Img32.Clipper2.pas 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. unit Img32.Clipper2;
  2. (*******************************************************************************
  3. * Author : Angus Johnson *
  4. * Version : 4.7 *
  5. * Date : 6 January 2025 *
  6. * Website : http://www.angusj.com *
  7. * Copyright : Angus Johnson 2019-2025 *
  8. * Purpose : Wrapper module for the Clipper library *
  9. * License : http://www.boost.org/LICENSE_1_0.txt *
  10. *******************************************************************************)
  11. interface
  12. uses
  13. Img32, Img32.Draw, Img32.Vector, Clipper.Offset;
  14. //nb: InflatePath assumes that there's consistent winding where
  15. //outer paths wind in one direction and inner paths in the other
  16. type
  17. TClipperEndType = Clipper.Offset.TEndType;
  18. function ClipperEndType(endStyle: TEndStyle): TClipperEndType;
  19. function InflatePath(const path: TPathD; delta: Double;
  20. joinStyle: TJoinStyle = jsAuto; endType: TClipperEndType = etPolygon;
  21. miterLimit: double = 2.0; arcTolerance: double = 0.0;
  22. minEdgeLength: double = 0.25): TPathsD;
  23. function InflatePaths(const paths: TPathsD; delta: Double;
  24. joinStyle: TJoinStyle = jsAuto; endType: TClipperEndType = etPolygon;
  25. miterLimit: double = 2.0; arcTolerance: double = 0.0;
  26. minEdgeLength: double = 0): TPathsD;
  27. //UnionPolygon: removes self-intersections
  28. function UnionPolygon(const polygon: TPathD;
  29. fillRule: TFillRule): TPathsD;
  30. function UnionPolygons(const polygons: TPathsD;
  31. fillRule: TFillRule): TPathsD; overload;
  32. function UnionPolygons(const polygon1, polygon2: TPathD;
  33. fillRule: TFillRule): TPathsD; overload;
  34. function UnionPolygons(const polygons1, polygons2: TPathsD;
  35. fillRule: TFillRule): TPathsD; overload;
  36. function IntersectPolygons(const polygons1, polygons2: TPathsD;
  37. fillRule: TFillRule): TPathsD;
  38. function DifferencePolygons(const polygons1, polygons2: TPathsD;
  39. fillRule: TFillRule): TPathsD;
  40. const
  41. etPolygon = Clipper.Offset.etPolygon;
  42. etJoined = Clipper.Offset.etJoined;
  43. etButt = Clipper.Offset.etButt;
  44. etSquare = Clipper.Offset.etSquare;
  45. etRound = Clipper.Offset.etRound;
  46. implementation
  47. uses Clipper, Clipper.Core, Clipper.Engine;
  48. //------------------------------------------------------------------------------
  49. //------------------------------------------------------------------------------
  50. function ClipperEndType(endStyle: TEndStyle): TClipperEndType;
  51. begin
  52. case endStyle of
  53. esPolygon: Result := etJoined;
  54. esButt: Result := etButt;
  55. esSquare: Result := etSquare;
  56. else Result := etRound;
  57. end;
  58. end;
  59. //------------------------------------------------------------------------------
  60. function InflatePath(const path: Img32.TPathD;
  61. delta: Double; joinStyle: TJoinStyle; endType: TClipperEndType;
  62. miterLimit: double; arcTolerance: double; minEdgeLength: double): Img32.TPathsD;
  63. var
  64. paths: Img32.TPathsD;
  65. begin
  66. setLength(paths, 1);
  67. paths[0] := path;
  68. Result := InflatePaths(paths, delta, joinStyle, endType,
  69. miterLimit, arcTolerance, minEdgeLength);
  70. end;
  71. //------------------------------------------------------------------------------
  72. function InflatePaths(const paths: Img32.TPathsD;
  73. delta: Double; joinStyle: TJoinStyle; endType: TClipperEndType;
  74. miterLimit: double; arcTolerance: double; minEdgeLength: double): Img32.TPathsD;
  75. var
  76. jt: Clipper.Offset.TJoinType;
  77. begin
  78. case joinStyle of
  79. jsSquare : jt := jtSquare;
  80. jsButt : jt := jtBevel;
  81. jsMiter : jt := jtMiter;
  82. jsRound : jt := jtRound;
  83. else if endType = etRound then jt := jtRound
  84. else jt := jtSquare;
  85. end;
  86. Result := Img32.TPathsD(Clipper.InflatePaths(
  87. Clipper.Core.TPathsD(paths), delta, jt, endType));
  88. end;
  89. //------------------------------------------------------------------------------
  90. function UnionPolygon(const polygon: Img32.TPathD;
  91. fillRule: Img32.Vector.TFillRule): Img32.TPathsD;
  92. begin
  93. with TClipperD.Create do
  94. try
  95. AddSubject(Clipper.Core.TPathD(polygon));
  96. Execute(ctUnion,
  97. Clipper.Core.TFillRule(fillRule), Clipper.Core.TPathsD(result));
  98. finally
  99. Free;
  100. end;
  101. end;
  102. //------------------------------------------------------------------------------
  103. function UnionPolygons(const polygons: Img32.TPathsD;
  104. fillRule: Img32.Vector.TFillRule): Img32.TPathsD;
  105. begin
  106. with TClipperD.Create do
  107. try
  108. AddSubject(Clipper.Core.TPathsD(polygons));
  109. Execute(ctUnion,
  110. Clipper.Core.TFillRule(fillRule), Clipper.Core.TPathsD(result));
  111. finally
  112. Free;
  113. end;
  114. end;
  115. //------------------------------------------------------------------------------
  116. function UnionPolygons(const polygon1, polygon2: Img32.TPathD;
  117. fillRule: Img32.Vector.TFillRule): Img32.TPathsD;
  118. begin
  119. with TClipperD.Create do
  120. try
  121. AddSubject(Clipper.Core.TPathD(polygon1));
  122. AddClip(Clipper.Core.TPathD(polygon2));
  123. Execute(ctUnion,
  124. Clipper.Core.TFillRule(fillRule), Clipper.Core.TPathsD(result));
  125. finally
  126. Free;
  127. end;
  128. end;
  129. //------------------------------------------------------------------------------
  130. function UnionPolygons(const polygons1, polygons2: Img32.TPathsD;
  131. fillRule: Img32.Vector.TFillRule): Img32.TPathsD;
  132. begin
  133. with TClipperD.Create do
  134. try
  135. AddSubject(Clipper.Core.TPathsD(polygons1));
  136. AddClip(Clipper.Core.TPathsD(polygons2));
  137. Execute(ctUnion,
  138. Clipper.Core.TFillRule(fillRule), Clipper.Core.TPathsD(result));
  139. finally
  140. Free;
  141. end;
  142. end;
  143. //------------------------------------------------------------------------------
  144. function IntersectPolygons(const polygons1, polygons2: Img32.TPathsD;
  145. fillRule: Img32.Vector.TFillRule): Img32.TPathsD;
  146. begin
  147. with TClipperD.Create do
  148. try
  149. AddSubject(Clipper.Core.TPathsD(polygons1));
  150. AddClip(Clipper.Core.TPathsD(polygons2));
  151. Execute(ctIntersection,
  152. Clipper.Core.TFillRule(fillRule), Clipper.Core.TPathsD(result));
  153. finally
  154. Free;
  155. end;
  156. end;
  157. //------------------------------------------------------------------------------
  158. function DifferencePolygons(const polygons1, polygons2: Img32.TPathsD;
  159. fillRule: Img32.Vector.TFillRule): Img32.TPathsD;
  160. begin
  161. with TClipperD.Create do
  162. try
  163. AddSubject(Clipper.Core.TPathsD(polygons1));
  164. AddClip(Clipper.Core.TPathsD(polygons2));
  165. Execute(ctDifference,
  166. Clipper.Core.TFillRule(fillRule), Clipper.Core.TPathsD(result));
  167. finally
  168. Free;
  169. end;
  170. end;
  171. //------------------------------------------------------------------------------
  172. end.