GR32_Clipper.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. unit GR32_Clipper;
  2. (* ***** BEGIN LICENSE BLOCK *****
  3. * Version: MPL 1.1 or LGPL 2.1 with linking exception
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. * http://www.mozilla.org/MPL/
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. *
  15. * Alternatively, the contents of this file may be used under the terms of the
  16. * Free Pascal modified version of the GNU Lesser General Public License
  17. * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
  18. * of this license are applicable instead of those above.
  19. * Please see the file LICENSE.txt for additional information concerning this
  20. * license.
  21. *
  22. * The Original Code is GR32_Clipper
  23. *
  24. * The Initial Developer of the Original Code is
  25. * Angus Johnson
  26. *
  27. * Portions created by the Initial Developer are Copyright (C) 2012-2022
  28. * the Initial Developer. All Rights Reserved.
  29. *
  30. * Contributor(s):
  31. *
  32. * ***** END LICENSE BLOCK ***** *)
  33. interface
  34. {$include GR32.inc}
  35. uses
  36. Classes,
  37. SysUtils,
  38. Math,
  39. GR32_Clipper2,
  40. GR32_Polygons,
  41. Clipper.Core,
  42. Clipper.Engine,
  43. Clipper.Offset,
  44. GR32;
  45. const
  46. // TPathType
  47. ptSubject = Clipper.Engine.ptSubject;
  48. ptClip = Clipper.Engine.ptClip;
  49. const
  50. // TClipType
  51. ctNone = Clipper.Core.ctNone;
  52. ctIntersection= Clipper.Core.ctIntersection;
  53. ctUnion = Clipper.Core.ctUnion;
  54. ctDifference = Clipper.Core.ctDifference;
  55. ctXor = Clipper.Core.ctXor;
  56. const
  57. // TFillRule
  58. frEvenOdd = Clipper.Core.frEvenOdd;
  59. frNonZero = Clipper.Core.frNonZero;
  60. frPositive = Clipper.Core.frPositive;
  61. frNegative = Clipper.Core.frNegative;
  62. type
  63. TPathType = Clipper.Engine.TPathType;
  64. TClipType = Clipper.Core.TClipType;
  65. TFillRule = Clipper.Core.TFillRule;
  66. type
  67. TClipper = class(TClipper64)
  68. private
  69. protected
  70. public
  71. function GetBounds: TFloatRect;
  72. // ADDPATH & ADDPATHS METHODS ...
  73. procedure AddPath(const Path: TArrayOfFloatPoint; PolyType: TPathType = ptSubject; IsOpen: Boolean = False); overload;
  74. procedure AddPath(const Path: TArrayOfFixedPoint; PolyType: TPathType = ptSubject; IsOpen: Boolean = False); overload;
  75. procedure AddPaths(const Paths: TArrayOfArrayOfFloatPoint; PolyType: TPathType = ptSubject; IsOpen: Boolean = False); overload;
  76. procedure AddPaths(const Paths: TArrayOfArrayOfFixedPoint; PolyType: TPathType = ptSubject; IsOpen: Boolean = False); overload;
  77. // EXECUTE METHODS ...
  78. function Execute(ClipType: TClipType; FillRule: TFillRule; out ClosedPaths: TArrayOfArrayOfFloatPoint): Boolean; overload;
  79. function Execute(ClipType: TClipType; FillRule: TFillRule; out ClosedPaths: TArrayOfArrayOfFixedPoint): Boolean; overload;
  80. function Execute(ClipType: TClipType; FillRule: TFillRule; out ClosedPaths, OpenPaths: TArrayOfArrayOfFloatPoint): Boolean; overload;
  81. function Execute(ClipType: TClipType; FillRule: TFillRule; out ClosedPaths, OpenPaths: TArrayOfArrayOfFixedPoint): Boolean; overload;
  82. end;
  83. TClipper32 = TClipper; // Can be used to avoid ambiguity with Clipper's own TClipper class.
  84. const
  85. // TJoinType
  86. jtBevel = Clipper.Offset.jtBevel;
  87. jtSquare = Clipper.Offset.jtSquare;
  88. jtRound = Clipper.Offset.jtRound;
  89. jtRoundEx = Clipper.Offset.jtRound; // Not implemented in Clipper2
  90. jtMiter = Clipper.Offset.jtMiter;
  91. const
  92. // TEndType
  93. etPolygon = Clipper.Offset.etPolygon;
  94. etOpenJoined = Clipper.Offset.etJoined;
  95. etOpenButt = Clipper.Offset.etButt;
  96. etOpenSquare = Clipper.Offset.etSquare;
  97. etOpenRound = Clipper.Offset.etRound;
  98. type
  99. TJoinType = Clipper.Offset.TJoinType;
  100. TEndType = Clipper.Offset.TEndType;
  101. type
  102. TClipperOffset = class(Clipper.Offset.TClipperOffset)
  103. private
  104. public
  105. procedure AddPath(const Path: TArrayOfFloatPoint); overload; deprecated 'Use AddPath(path, joinType, endType)';
  106. procedure AddPath(const Path: TArrayOfFloatPoint; JoinType: TJoinType; EndType: TEndType); overload;
  107. procedure AddPaths(const Paths: TArrayOfArrayOfFloatPoint); overload; deprecated 'Use AddPaths(paths, joinType, endType)';
  108. procedure AddPaths(const Paths: TArrayOfArrayOfFloatPoint; JoinType: TJoinType; EndType: TEndType); overload;
  109. procedure Execute(Delta: Double; jt: TJoinType; et: TEndType; out Solution: TArrayOfArrayOfFloatPoint); overload; deprecated 'Use Execute(delta)';
  110. function Execute(Delta: Double): TArrayOfArrayOfFloatPoint; overload;
  111. end;
  112. function InflatePaths(const Paths: GR32.TArrayOfArrayOfFixedPoint;
  113. Delta: double; jointType: TJoinType; EndType: TEndType;
  114. MiterLimit: double = 2): GR32.TArrayOfArrayOfFixedPoint; overload;
  115. function InflatePaths(const Paths: GR32.TArrayOfArrayOfFloatPoint;
  116. Delta: double; jointType: TJoinType; EndType: TEndType;
  117. MiterLimit: double = 2): GR32.TArrayOfArrayOfFloatPoint; overload;
  118. implementation
  119. uses
  120. Clipper;
  121. //------------------------------------------------------------------------------
  122. function InflatePaths(const Paths: GR32.TArrayOfArrayOfFixedPoint;
  123. Delta: double; jointType: TJoinType; EndType: TEndType;
  124. MiterLimit: double): GR32.TArrayOfArrayOfFixedPoint;
  125. var
  126. sub, sol: TPaths64;
  127. begin
  128. sub := GR32_Clipper2.FixedPointsToPaths64(Paths);
  129. sol := Clipper.InflatePaths(sub, Delta * ClipperFloat.FixedGrowScale, jointType, EndType, MiterLimit);
  130. sol := Clipper.Core.RamerDouglasPeucker(sol, 10);
  131. Result := GR32_Clipper2.Paths64ToFixedPoints(sol);
  132. end;
  133. function InflatePaths(const Paths: GR32.TArrayOfArrayOfFloatPoint;
  134. Delta: double; jointType: TJoinType; EndType: TEndType;
  135. MiterLimit: double): GR32.TArrayOfArrayOfFloatPoint;
  136. var
  137. sub, sol: TPaths64;
  138. begin
  139. sub := GR32_Clipper2.FloatPointsToPaths64(Paths);
  140. sol := Clipper.InflatePaths(sub, Delta * ClipperFloat.GrowScale, jointType, EndType, MiterLimit);
  141. sol := Clipper.Core.RamerDouglasPeucker(sol, 10);
  142. Result := GR32_Clipper2.Paths64ToFloatPoints(sol);
  143. end;
  144. //------------------------------------------------------------------------------
  145. // TClipper methods ...
  146. //------------------------------------------------------------------------------
  147. procedure TClipper.AddPath(const Path: TArrayOfFloatPoint; PolyType: TPathType; IsOpen: Boolean);
  148. var
  149. Path64: TPath64;
  150. begin
  151. Path64 := GR32_Clipper2.FloatPointsToPath64(Path);
  152. inherited AddPath(Path64, PolyType, IsOpen);
  153. end;
  154. //------------------------------------------------------------------------------
  155. procedure TClipper.AddPath(const Path: TArrayOfFixedPoint; PolyType: TPathType; IsOpen: Boolean);
  156. var
  157. Path64: TPath64;
  158. begin
  159. Path64 := GR32_Clipper2.FixedPointsToPath64(Path);
  160. inherited AddPath(Path64, PolyType, IsOpen);
  161. end;
  162. //------------------------------------------------------------------------------
  163. procedure TClipper.AddPaths(const Paths: TArrayOfArrayOfFloatPoint; PolyType: TPathType; IsOpen: Boolean);
  164. var
  165. Paths64: TPaths64;
  166. begin
  167. Paths64 := GR32_Clipper2.FloatPointsToPaths64(Paths);
  168. inherited AddPaths(Paths64, PolyType, IsOpen);
  169. end;
  170. //------------------------------------------------------------------------------
  171. procedure TClipper.AddPaths(const Paths: TArrayOfArrayOfFixedPoint; PolyType: TPathType; IsOpen: Boolean);
  172. var
  173. Paths64: TPaths64;
  174. begin
  175. Paths64 := GR32_Clipper2.FixedPointsToPaths64(Paths);
  176. inherited AddPaths(Paths64, PolyType, IsOpen);
  177. end;
  178. //------------------------------------------------------------------------------
  179. function TClipper.Execute(ClipType: TClipType; FillRule: TFillRule; out ClosedPaths: TArrayOfArrayOfFloatPoint): Boolean;
  180. var
  181. ClosedSolutions: TPaths64;
  182. begin
  183. Result := inherited Execute(ClipType, FillRule, ClosedSolutions);
  184. if (Result) then
  185. ClosedPaths := GR32_Clipper2.Paths64ToFloatPoints(ClosedSolutions)
  186. else
  187. SetLength(ClosedPaths, 0);
  188. end;
  189. //------------------------------------------------------------------------------
  190. function TClipper.Execute(ClipType: TClipType; FillRule: TFillRule; out ClosedPaths: TArrayOfArrayOfFixedPoint): Boolean;
  191. var
  192. ClosedSolutions: TPaths64;
  193. begin
  194. Result := inherited Execute(ClipType, FillRule, ClosedSolutions);
  195. if (Result) then
  196. ClosedPaths := GR32_Clipper2.Paths64ToFixedPoints(ClosedSolutions)
  197. else
  198. SetLength(ClosedPaths, 0);
  199. end;
  200. //------------------------------------------------------------------------------
  201. function TClipper.Execute(ClipType: TClipType; FillRule: TFillRule; out ClosedPaths, OpenPaths: TArrayOfArrayOfFloatPoint): Boolean;
  202. var
  203. ClosedSolutions, OpenSolutions: TPaths64;
  204. begin
  205. Result := inherited Execute(ClipType, FillRule, ClosedSolutions, OpenSolutions);
  206. if (Result) then
  207. begin
  208. ClosedPaths := GR32_Clipper2.Paths64ToFloatPoints(ClosedSolutions);
  209. OpenPaths := GR32_Clipper2.Paths64ToFloatPoints(OpenSolutions);
  210. end else
  211. begin
  212. SetLength(ClosedPaths, 0);
  213. SetLength(OpenPaths, 0);
  214. end;
  215. end;
  216. //------------------------------------------------------------------------------
  217. function TClipper.Execute(ClipType: TClipType; FillRule: TFillRule; out ClosedPaths, OpenPaths: TArrayOfArrayOfFixedPoint): Boolean;
  218. var
  219. ClosedSolutions, OpenSolutions: TPaths64;
  220. begin
  221. Result := inherited Execute(ClipType, FillRule, ClosedSolutions, OpenSolutions);
  222. if (Result) then
  223. begin
  224. ClosedPaths := GR32_Clipper2.Paths64ToFixedPoints(ClosedSolutions);
  225. OpenPaths := GR32_Clipper2.Paths64ToFixedPoints(OpenSolutions);
  226. end else
  227. begin
  228. SetLength(ClosedPaths, 0);
  229. SetLength(OpenPaths, 0);
  230. end;
  231. end;
  232. //------------------------------------------------------------------------------
  233. function TClipper.GetBounds: TFloatRect;
  234. begin
  235. Result := GR32_Clipper2.FloatRect(inherited GetBounds);
  236. end;
  237. //------------------------------------------------------------------------------
  238. // TClipperOffset methods ...
  239. //------------------------------------------------------------------------------
  240. procedure TClipperOffset.AddPath(const Path: TArrayOfFloatPoint; JoinType: TJoinType; EndType: TEndType);
  241. var
  242. Path64: TPath64;
  243. begin
  244. Path64 := GR32_Clipper2.FloatPointsToPath64(Path);
  245. inherited AddPath(Path64, JoinType, EndType);
  246. end;
  247. procedure TClipperOffset.AddPath(const Path: TArrayOfFloatPoint);
  248. begin
  249. AddPath(Path, jtRound, etPolygon);
  250. end;
  251. //------------------------------------------------------------------------------
  252. procedure TClipperOffset.AddPaths(const Paths: TArrayOfArrayOfFloatPoint; JoinType: TJoinType; EndType: TEndType);
  253. var
  254. Paths64: TPaths64;
  255. begin
  256. Paths64 := GR32_Clipper2.FloatPointsToPaths64(Paths);
  257. inherited AddPaths(Paths64, JoinType, EndType);
  258. end;
  259. procedure TClipperOffset.AddPaths(const Paths: TArrayOfArrayOfFloatPoint);
  260. begin
  261. AddPaths(Paths, jtRound, etPolygon);
  262. end;
  263. //------------------------------------------------------------------------------
  264. function TClipperOffset.Execute(Delta: Double): TArrayOfArrayOfFloatPoint;
  265. var
  266. Paths64: TPaths64;
  267. begin
  268. inherited Execute(Delta, Paths64);
  269. Result := GR32_Clipper2.Paths64ToFloatPoints(Paths64);
  270. end;
  271. procedure TClipperOffset.Execute(Delta: Double; jt: TJoinType; et: TEndType; out Solution: TArrayOfArrayOfFloatPoint);
  272. begin
  273. Solution := Execute(Delta);
  274. end;
  275. //------------------------------------------------------------------------------
  276. end.