Ignore:
Timestamp:
Apr 17, 2019, 12:58:41 AM (5 years ago)
Author:
chronos
Message:
  • Modified: Propagate project build mode options to used packages.
  • Added: Check memory leaks using heaptrc.
  • Modified: Update BGRABitmap package.
Location:
GraphicTest
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • GraphicTest

    • Property svn:ignore
      •  

        old new  
        88GraphicTest.lps
        99GraphicTest.dbg
         10heaptrclog.trc
  • GraphicTest/Packages/bgrabitmap/bgrafillinfo.pas

    r494 r521  
    111111  public
    112112    WindingFactor: integer;
    113     constructor Create(x1, y1, x2, y2, rx, ry: single; options: TRoundRectangleOptions);
     113    constructor Create(x1, y1, x2, y2, rx, ry: single; options: TRoundRectangleOptions; APixelCenteredCoordinates: boolean = true);
    114114    function SegmentsCurved: boolean; override;
    115115    function GetBounds: TRect; override;
     
    129129      var inter: ArrayOfTIntersectionInfo; var nbInter: integer); override;
    130130  public
    131     constructor Create(x1, y1, x2, y2, rx, ry, w: single; options: TRoundRectangleOptions);
     131    constructor Create(x1, y1, x2, y2, rx, ry, w: single; options: TRoundRectangleOptions; APixelCenteredCoordinates: boolean = true);
    132132    function GetBounds: TRect; override;
    133133    function SegmentsCurved: boolean; override;
     
    161161    function NbMaxIntersection: integer; override;
    162162    procedure SetIntersectionValues(AInter: TIntersectionInfo; AInterX: Single; AWinding, ANumSegment: integer; {%H-}dy: single; {%H-}AData: pointer); virtual;
     163    procedure InitPoints(const points: array of TPointF);
    163164  public
    164     constructor Create(const points: array of TPointF);
     165    constructor Create(const points: array of TPointF; APixelCenteredCoordinates: boolean = true);
    165166    function CreateSegmentData(numPt,nextPt: integer; x,y: single): pointer; virtual;
    166167    procedure FreeSegmentData(data: pointer); virtual;
     
    180181      var inter: ArrayOfTIntersectionInfo; var nbInter: integer); override;
    181182  public
    182     constructor Create(const points: array of TPointF);
     183    constructor Create(const points: array of TPointF; APixelCenteredCoordinates: boolean = true);
    183184    destructor Destroy; override;
    184185    function GetSliceIndex: integer; override;
     
    216217      var inter: ArrayOfTIntersectionInfo; var nbInter: integer); override;
    217218  public
    218     constructor Create(const points: array of TPointF);
     219    constructor Create(const points: array of TPointF; APixelCenteredCoordinates: boolean = true);
    219220    function CreateIntersectionArray: ArrayOfTIntersectionInfo; override;
    220221    function GetSliceIndex: integer; override;
     
    454455procedure TFillShapeInfo.SortIntersection(var inter: ArrayOfTIntersectionInfo; nbInter: integer);
    455456var
    456   i,j: Integer;
     457  i,j,k: Integer;
    457458  tempInter: TIntersectionInfo;
    458459begin
     
    460461  begin
    461462    j := i;
    462     while (j > 0) and (inter[j - 1].interX > inter[j].interX) do
    463     begin
    464       tempInter    := inter[j - 1];
    465       inter[j - 1] := inter[j];
    466       inter[j]     := tempInter;
    467       Dec(j);
     463    while (j > 0) and (inter[i].interX < inter[j-1].interX) do dec(j);
     464    if j <> i then
     465    begin
     466      tempInter := inter[i];
     467      for k := i-1 downto j do
     468        inter[k+1] := inter[k];
     469      inter[j]  := tempInter;
    468470    end;
    469471  end;
     
    482484    if (windingSum = 0) xor (prevSum = 0) then
    483485    begin
    484       tempInfo := inter[nbAlternate];
    485       inter[nbAlternate] := inter[i];
    486       inter[i] := tempInfo;
     486      if nbAlternate<>i then
     487      begin
     488        tempInfo := inter[nbAlternate];
     489        inter[nbAlternate] := inter[i];
     490        inter[i] := tempInfo;
     491      end;
    487492      inc(nbAlternate);
    488493    end;
     
    628633{ TCustomFillPolyInfo }
    629634
    630 constructor TCustomFillPolyInfo.Create(const points: array of TPointF);
     635constructor TCustomFillPolyInfo.Create(const points: array of TPointF; APixelCenteredCoordinates: boolean);
    631636var
    632   i, j: integer;
    633   First, cur, nbP: integer;
    634 begin
    635   setlength(FPoints, length(points));
    636   nbP := 0;
    637   first := -1;
    638   for i := 0 to high(points) do
    639   if isEmptyPointF(points[i]) then
    640   begin
    641     if first<>-1 then
    642     begin
    643       if nbP = first+1 then //is there only one point?
    644       begin
    645         dec(nbP);
    646         first := -1; //remove subpolygon
    647       end else
    648       if (FPoints[nbP-1] = FPoints[first]) then
    649         dec(nbP); //remove just last looping point
    650     end;
    651     if first<>-1 then
    652     begin
    653       FPoints[nbP] := points[i];
    654       inc(nbP);
    655       first := -1;
    656     end;
    657   end else
    658   if (first=-1) or (points[i]<>points[i-1]) then
    659   begin
    660     if first = -1 then first := nbP;
    661     FPoints[nbP] := points[i];
    662     inc(nbP);
    663   end;
    664   setlength(FPoints, nbP);
     637  cur, first, i, j: integer;
     638
     639begin
     640  InitPoints(points);
    665641
    666642  //look for empty points, correct coordinate and successors
     
    669645
    670646  cur   := -1;
    671   First := -1;
     647  first := -1;
    672648  for i := 0 to high(FPoints) do
    673649    if not isEmptyPointF(FPoints[i]) then
    674650    begin
    675651      FEmptyPt[i]  := False;
    676       FPoints[i].x += 0.5;
    677       FPoints[i].y += 0.5;
     652      if APixelCenteredCoordinates then
     653      begin
     654        FPoints[i].x += 0.5;
     655        FPoints[i].y += 0.5;
     656      end;
    678657      if cur <> -1 then
    679658        FNext[cur] := i;
    680       if First = -1 then
    681         First := i;
     659      if first = -1 then
     660        first := i;
    682661      cur     := i;
    683662    end
    684663    else
    685664    begin
    686       if (First <> -1) and (cur <> First) then
    687         FNext[cur] := First;
     665      if (first <> -1) and (cur <> first) then
     666        FNext[cur] := first;
    688667
    689668      FEmptyPt[i] := True;
    690669      FNext[i] := -1;
    691670      cur   := -1;
    692       First := -1;
    693     end;
    694   if (First <> -1) and (cur <> First) then
    695     FNext[cur] := First;
     671      first := -1;
     672    end;
     673  if (first <> -1) and (cur <> first) then
     674    FNext[cur] := first;
    696675
    697676  setlength(FPrev, length(FPoints));
     
    779758end;
    780759
     760procedure TCustomFillPolyInfo.InitPoints(const points: array of TPointF);
     761const
     762  minDist = 0.00390625; //1 over 256
     763
     764var
     765  i, first, nbP: integer;
     766
     767  function PointAlmostEqual(const p1,p2: TPointF): boolean;
     768  begin
     769    result := (abs(p1.x-p2.x) < minDist) and (abs(p1.y-p2.y) < minDist);
     770  end;
     771
     772  procedure EndOfSubPolygon;
     773  begin
     774    //if there is a subpolygon
     775    if first<>-1 then
     776    begin
     777      //last point is the same as first point?
     778      if (nbP >= first+2) and PointAlmostEqual(FPoints[nbP-1],FPoints[first]) then
     779        dec(nbP); //remove superfluous looping point
     780
     781      if (nbP <= first+2) then //are there only one or two points?
     782      begin
     783        //remove subpolygon because we need at least a triangle
     784        nbP := first;
     785        first := -1;
     786      end;
     787
     788    end;
     789  end;
     790
     791begin
     792  setlength(FPoints, length(points));
     793  nbP := 0;
     794  first := -1;
     795  for i := 0 to high(points) do
     796  if isEmptyPointF(points[i]) then
     797  begin
     798    EndOfSubPolygon;
     799    if first<>-1 then
     800    begin
     801      FPoints[nbP] := EmptyPointF;
     802      inc(nbP);
     803      first := -1;
     804    end;
     805  end else
     806  if (first=-1) or not PointAlmostEqual(FPoints[nbP-1],points[i]) then
     807  begin
     808    if first = -1 then first := nbP;
     809    FPoints[nbP] := points[i];
     810    inc(nbP);
     811  end;
     812  EndOfSubPolygon;
     813  //if last point was a subpolygon delimiter (EmptyPointF) then removes it
     814  if (nbP > 0) and isEmptyPointF(FPoints[nbP-1]) then dec(nbP);
     815
     816  setlength(FPoints, nbP);
     817end;
     818
    781819{ TFillPolyInfo }
    782820
     
    807845end;
    808846
    809 constructor TFillPolyInfo.Create(const points: array of TPointF);
     847constructor TFillPolyInfo.Create(const points: array of TPointF; APixelCenteredCoordinates: boolean);
    810848  function AddSeg(numSlice: integer): integer;
    811849  begin
     
    824862
    825863begin
    826   inherited Create(points);
     864  inherited Create(points, APixelCenteredCoordinates);
    827865
    828866  //slice
     
    10421080end;
    10431081
    1044 constructor TOnePassFillPolyInfo.Create(const points: array of TPointF);
     1082constructor TOnePassFillPolyInfo.Create(const points: array of TPointF; APixelCenteredCoordinates: boolean);
    10451083var i,j: integer;
    10461084  p: POnePassRecord;
    10471085  temp: single;
    10481086begin
    1049   inherited create(points);
     1087  inherited create(points, APixelCenteredCoordinates);
    10501088
    10511089  FShouldInitializeDrawing := true;
     
    12931331{ TFillRoundRectangleInfo }
    12941332
    1295 constructor TFillRoundRectangleInfo.Create(x1, y1, x2, y2, rx, ry: single; options: TRoundRectangleOptions);
     1333constructor TFillRoundRectangleInfo.Create(x1, y1, x2, y2, rx, ry: single; options: TRoundRectangleOptions; APixelCenteredCoordinates: boolean);
    12961334var
    12971335  temp: Single;
     
    13091347    x2 := temp;
    13101348  end;
    1311   FX1  := x1 + 0.5;
    1312   FY1  := y1 + 0.5;
    1313   FX2  := x2 + 0.5;
    1314   FY2  := y2 + 0.5;
     1349  if APixelCenteredCoordinates then
     1350  begin
     1351    FX1  := x1 + 0.5;
     1352    FY1  := y1 + 0.5;
     1353    FX2  := x2 + 0.5;
     1354    FY2  := y2 + 0.5;
     1355  end else
     1356  begin
     1357    FX1 := x1;
     1358    FY1 := y1;
     1359    FX2 := x2;
     1360    FY2 := y2;
     1361  end;
    13151362  FRX := abs(rx);
    13161363  FRY := abs(ry);
     
    14221469{ TFillBorderRoundRectInfo }
    14231470
    1424 constructor TFillBorderRoundRectInfo.Create(x1, y1, x2, y2, rx, ry, w: single; options: TRoundRectangleOptions);
     1471constructor TFillBorderRoundRectInfo.Create(x1, y1, x2, y2, rx, ry, w: single; options: TRoundRectangleOptions; APixelCenteredCoordinates: boolean);
    14251472var rdiff: single;
    14261473  temp: Single;
     
    14461493  if 2*ry > y2-y1 then ry := (y2-y1)/2;
    14471494  rdiff := w*(sqrt(2)-1);
    1448   FOuterBorder := TFillRoundRectangleInfo.Create(x1-w/2,y1-w/2,x2+w/2,y2+w/2, rx+rdiff, ry+rdiff, options);
     1495  FOuterBorder := TFillRoundRectangleInfo.Create(x1-w/2,y1-w/2,x2+w/2,y2+w/2, rx+rdiff, ry+rdiff, options, APixelCenteredCoordinates);
    14491496  if (abs(x2-x1) > w) and (abs(y2-y1) > w) then
    14501497  begin
    14511498    if (rx-rdiff <= 0) or (ry-rdiff <= 0) then
    1452       FInnerBorder := TFillRoundRectangleInfo.Create(x1+w/2, y1+w/2, x2-w/2, y2-w/2, 0,0, options)
     1499      FInnerBorder := TFillRoundRectangleInfo.Create(x1+w/2, y1+w/2, x2-w/2, y2-w/2, 0,0, options, APixelCenteredCoordinates)
    14531500    else
    1454       FInnerBorder := TFillRoundRectangleInfo.Create(x1+w/2, y1+w/2, x2-w/2, y2-w/2, rx-rdiff, ry-rdiff, options);
     1501      FInnerBorder := TFillRoundRectangleInfo.Create(x1+w/2, y1+w/2, x2-w/2, y2-w/2, rx-rdiff, ry-rdiff, options, APixelCenteredCoordinates);
    14551502    FInnerBorder.WindingFactor := -1;
    14561503  end
Note: See TracChangeset for help on using the changeset viewer.