Changeset 521 for GraphicTest/Packages/bgrabitmap/bgrafillinfo.pas
- Timestamp:
- Apr 17, 2019, 12:58:41 AM (5 years ago)
- Location:
- GraphicTest
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
GraphicTest
- Property svn:ignore
-
old new 8 8 GraphicTest.lps 9 9 GraphicTest.dbg 10 heaptrclog.trc
-
- Property svn:ignore
-
GraphicTest/Packages/bgrabitmap/bgrafillinfo.pas
r494 r521 111 111 public 112 112 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); 114 114 function SegmentsCurved: boolean; override; 115 115 function GetBounds: TRect; override; … … 129 129 var inter: ArrayOfTIntersectionInfo; var nbInter: integer); override; 130 130 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); 132 132 function GetBounds: TRect; override; 133 133 function SegmentsCurved: boolean; override; … … 161 161 function NbMaxIntersection: integer; override; 162 162 procedure SetIntersectionValues(AInter: TIntersectionInfo; AInterX: Single; AWinding, ANumSegment: integer; {%H-}dy: single; {%H-}AData: pointer); virtual; 163 procedure InitPoints(const points: array of TPointF); 163 164 public 164 constructor Create(const points: array of TPointF );165 constructor Create(const points: array of TPointF; APixelCenteredCoordinates: boolean = true); 165 166 function CreateSegmentData(numPt,nextPt: integer; x,y: single): pointer; virtual; 166 167 procedure FreeSegmentData(data: pointer); virtual; … … 180 181 var inter: ArrayOfTIntersectionInfo; var nbInter: integer); override; 181 182 public 182 constructor Create(const points: array of TPointF );183 constructor Create(const points: array of TPointF; APixelCenteredCoordinates: boolean = true); 183 184 destructor Destroy; override; 184 185 function GetSliceIndex: integer; override; … … 216 217 var inter: ArrayOfTIntersectionInfo; var nbInter: integer); override; 217 218 public 218 constructor Create(const points: array of TPointF );219 constructor Create(const points: array of TPointF; APixelCenteredCoordinates: boolean = true); 219 220 function CreateIntersectionArray: ArrayOfTIntersectionInfo; override; 220 221 function GetSliceIndex: integer; override; … … 454 455 procedure TFillShapeInfo.SortIntersection(var inter: ArrayOfTIntersectionInfo; nbInter: integer); 455 456 var 456 i,j : Integer;457 i,j,k: Integer; 457 458 tempInter: TIntersectionInfo; 458 459 begin … … 460 461 begin 461 462 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; 468 470 end; 469 471 end; … … 482 484 if (windingSum = 0) xor (prevSum = 0) then 483 485 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; 487 492 inc(nbAlternate); 488 493 end; … … 628 633 { TCustomFillPolyInfo } 629 634 630 constructor TCustomFillPolyInfo.Create(const points: array of TPointF );635 constructor TCustomFillPolyInfo.Create(const points: array of TPointF; APixelCenteredCoordinates: boolean); 631 636 var 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 639 begin 640 InitPoints(points); 665 641 666 642 //look for empty points, correct coordinate and successors … … 669 645 670 646 cur := -1; 671 First := -1;647 first := -1; 672 648 for i := 0 to high(FPoints) do 673 649 if not isEmptyPointF(FPoints[i]) then 674 650 begin 675 651 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; 678 657 if cur <> -1 then 679 658 FNext[cur] := i; 680 if First = -1 then681 First := i;659 if first = -1 then 660 first := i; 682 661 cur := i; 683 662 end 684 663 else 685 664 begin 686 if ( First <> -1) and (cur <> First) then687 FNext[cur] := First;665 if (first <> -1) and (cur <> first) then 666 FNext[cur] := first; 688 667 689 668 FEmptyPt[i] := True; 690 669 FNext[i] := -1; 691 670 cur := -1; 692 First := -1;693 end; 694 if ( First <> -1) and (cur <> First) then695 FNext[cur] := First;671 first := -1; 672 end; 673 if (first <> -1) and (cur <> first) then 674 FNext[cur] := first; 696 675 697 676 setlength(FPrev, length(FPoints)); … … 779 758 end; 780 759 760 procedure TCustomFillPolyInfo.InitPoints(const points: array of TPointF); 761 const 762 minDist = 0.00390625; //1 over 256 763 764 var 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 791 begin 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); 817 end; 818 781 819 { TFillPolyInfo } 782 820 … … 807 845 end; 808 846 809 constructor TFillPolyInfo.Create(const points: array of TPointF );847 constructor TFillPolyInfo.Create(const points: array of TPointF; APixelCenteredCoordinates: boolean); 810 848 function AddSeg(numSlice: integer): integer; 811 849 begin … … 824 862 825 863 begin 826 inherited Create(points );864 inherited Create(points, APixelCenteredCoordinates); 827 865 828 866 //slice … … 1042 1080 end; 1043 1081 1044 constructor TOnePassFillPolyInfo.Create(const points: array of TPointF );1082 constructor TOnePassFillPolyInfo.Create(const points: array of TPointF; APixelCenteredCoordinates: boolean); 1045 1083 var i,j: integer; 1046 1084 p: POnePassRecord; 1047 1085 temp: single; 1048 1086 begin 1049 inherited create(points );1087 inherited create(points, APixelCenteredCoordinates); 1050 1088 1051 1089 FShouldInitializeDrawing := true; … … 1293 1331 { TFillRoundRectangleInfo } 1294 1332 1295 constructor TFillRoundRectangleInfo.Create(x1, y1, x2, y2, rx, ry: single; options: TRoundRectangleOptions );1333 constructor TFillRoundRectangleInfo.Create(x1, y1, x2, y2, rx, ry: single; options: TRoundRectangleOptions; APixelCenteredCoordinates: boolean); 1296 1334 var 1297 1335 temp: Single; … … 1309 1347 x2 := temp; 1310 1348 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; 1315 1362 FRX := abs(rx); 1316 1363 FRY := abs(ry); … … 1422 1469 { TFillBorderRoundRectInfo } 1423 1470 1424 constructor TFillBorderRoundRectInfo.Create(x1, y1, x2, y2, rx, ry, w: single; options: TRoundRectangleOptions );1471 constructor TFillBorderRoundRectInfo.Create(x1, y1, x2, y2, rx, ry, w: single; options: TRoundRectangleOptions; APixelCenteredCoordinates: boolean); 1425 1472 var rdiff: single; 1426 1473 temp: Single; … … 1446 1493 if 2*ry > y2-y1 then ry := (y2-y1)/2; 1447 1494 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); 1449 1496 if (abs(x2-x1) > w) and (abs(y2-y1) > w) then 1450 1497 begin 1451 1498 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) 1453 1500 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); 1455 1502 FInnerBorder.WindingFactor := -1; 1456 1503 end
Note:
See TracChangeset
for help on using the changeset viewer.