GR32_Clipper.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  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. uses
  35. Classes,
  36. SysUtils,
  37. Math,
  38. GR32_Clipper2,
  39. Clipper.Core,
  40. Clipper.Engine,
  41. Clipper.Offset,
  42. GR32;
  43. const
  44. // TPathType
  45. ptSubject = Clipper.Engine.ptSubject;
  46. ptClip = Clipper.Engine.ptClip;
  47. const
  48. // TClipType
  49. ctNone = Clipper.Core.ctNone;
  50. ctIntersection= Clipper.Core.ctIntersection;
  51. ctUnion = Clipper.Core.ctUnion;
  52. ctDifference = Clipper.Core.ctDifference;
  53. ctXor = Clipper.Core.ctXor;
  54. const
  55. // TFillRule
  56. frEvenOdd = Clipper.Core.frEvenOdd;
  57. frNonZero = Clipper.Core.frNonZero;
  58. frPositive = Clipper.Core.frPositive;
  59. frNegative = Clipper.Core.frNegative;
  60. type
  61. TPathType = Clipper.Engine.TPathType;
  62. TClipType = Clipper.Core.TClipType;
  63. TFillRule = Clipper.Core.TFillRule;
  64. type
  65. TClipper = class(TClipper64)
  66. private
  67. protected
  68. public
  69. function GetBounds: TFloatRect;
  70. // ADDPATH & ADDPATHS METHODS ...
  71. procedure AddPath(const path: TArrayOfFloatPoint; polyType: TPathType = ptSubject; isOpen: Boolean = false); overload;
  72. procedure AddPath(const path: TArrayOfFixedPoint; polyType: TPathType = ptSubject; isOpen: Boolean = false); overload;
  73. procedure AddPaths(const paths: TArrayOfArrayOfFloatPoint; polyType: TPathType = ptSubject; isOpen: Boolean = false); overload;
  74. procedure AddPaths(const paths: TArrayOfArrayOfFixedPoint; polyType: TPathType = ptSubject; isOpen: Boolean = false); overload;
  75. // EXECUTE METHODS ...
  76. function Execute(clipType: TClipType; fillRule: TFillRule; out closedPaths: TArrayOfArrayOfFloatPoint): Boolean; overload;
  77. function Execute(clipType: TClipType; fillRule: TFillRule; out closedPaths: TArrayOfArrayOfFixedPoint): Boolean; overload;
  78. function Execute(clipType: TClipType; fillRule: TFillRule; out closedPaths, openPaths: TArrayOfArrayOfFloatPoint): Boolean; overload;
  79. function Execute(clipType: TClipType; fillRule: TFillRule; out closedPaths, openPaths: TArrayOfArrayOfFixedPoint): Boolean; overload;
  80. end;
  81. const
  82. // TJoinType
  83. jtSquare = Clipper.Offset.jtSquare;
  84. jtRound = Clipper.Offset.jtRound;
  85. jtRoundEx = Clipper.Offset.jtRound; // Not implemented in Clipper2
  86. jtMiter = Clipper.Offset.jtMiter;
  87. const
  88. // TEndType
  89. etPolygon = Clipper.Offset.etPolygon;
  90. etOpenJoined = Clipper.Offset.etJoined;
  91. etOpenButt = Clipper.Offset.etButt;
  92. etOpenSquare = Clipper.Offset.etSquare;
  93. etOpenRound = Clipper.Offset.etRound;
  94. type
  95. TJoinType = Clipper.Offset.TJoinType;
  96. TEndType = Clipper.Offset.TEndType;
  97. type
  98. TClipperOffset = class(Clipper.Offset.TClipperOffset)
  99. private
  100. public
  101. procedure AddPath(const path: TArrayOfFloatPoint); overload; deprecated 'Use AddPath(path, joinType, endType)';
  102. procedure AddPath(const path: TArrayOfFloatPoint; joinType: TJoinType; endType: TEndType); overload;
  103. procedure AddPaths(const paths: TArrayOfArrayOfFloatPoint); overload; deprecated 'Use AddPaths(paths, joinType, endType)';
  104. procedure AddPaths(const paths: TArrayOfArrayOfFloatPoint; joinType: TJoinType; endType: TEndType); overload;
  105. procedure Execute(delta: Double; jt: TJoinType; et: TEndType; out solution: TArrayOfArrayOfFloatPoint); overload; deprecated 'Use Execute(delta)';
  106. function Execute(delta: Double): TArrayOfArrayOfFloatPoint; overload;
  107. end;
  108. function InflatePaths(const paths: Gr32.TArrayOfArrayOfFixedPoint;
  109. delta: double; jointType: TJoinType; endType: TEndType;
  110. miterLimit: double = 2): Gr32.TArrayOfArrayOfFixedPoint; overload;
  111. function InflatePaths(const paths: Gr32.TArrayOfArrayOfFloatPoint;
  112. delta: double; jointType: TJoinType; endType: TEndType;
  113. miterLimit: double = 2): Gr32.TArrayOfArrayOfFloatPoint; overload;
  114. implementation
  115. uses
  116. Clipper;
  117. //------------------------------------------------------------------------------
  118. function InflatePaths(const paths: Gr32.TArrayOfArrayOfFixedPoint;
  119. delta: double; jointType: TJoinType; endType: TEndType;
  120. miterLimit: double): Gr32.TArrayOfArrayOfFixedPoint;
  121. var
  122. sub, sol: TPaths64;
  123. begin
  124. sub := GR32_Clipper2.FixedPointsToPaths64(paths);
  125. sol := Clipper.InflatePaths(sub, delta * FixedOne, jointType, endType, miterLimit);
  126. sol := Clipper.Core.RamerDouglasPeucker(sol, 10);
  127. Result := GR32_Clipper2.Paths64ToFixedPoints(sol);
  128. end;
  129. function InflatePaths(const paths: Gr32.TArrayOfArrayOfFloatPoint;
  130. delta: double; jointType: TJoinType; endType: TEndType;
  131. miterLimit: double): Gr32.TArrayOfArrayOfFloatPoint;
  132. var
  133. sub, sol: TPaths64;
  134. begin
  135. sub := GR32_Clipper2.FloatPointsToPaths64(paths);
  136. sol := Clipper.InflatePaths(sub, delta * ClipperFloatScale, jointType, endType, miterLimit);
  137. sol := Clipper.Core.RamerDouglasPeucker(sol, 10);
  138. Result := GR32_Clipper2.Paths64ToFloatPoints(sol);
  139. end;
  140. //------------------------------------------------------------------------------
  141. // TClipper methods ...
  142. //------------------------------------------------------------------------------
  143. procedure TClipper.AddPath(const path: TArrayOfFloatPoint; polyType: TPathType; isOpen: Boolean);
  144. var
  145. path64: TPath64;
  146. begin
  147. path64 := GR32_Clipper2.FloatPointsToPath64(path);
  148. inherited AddPath(path64, polyType, isOpen);
  149. end;
  150. //------------------------------------------------------------------------------
  151. procedure TClipper.AddPath(const path: TArrayOfFixedPoint; polyType: TPathType; isOpen: Boolean);
  152. var
  153. path64: TPath64;
  154. begin
  155. path64 := GR32_Clipper2.FixedPointsToPath64(path);
  156. inherited AddPath(path64, polyType, isOpen);
  157. end;
  158. //------------------------------------------------------------------------------
  159. procedure TClipper.AddPaths(const paths: TArrayOfArrayOfFloatPoint; polyType: TPathType; isOpen: Boolean);
  160. var
  161. paths64: TPaths64;
  162. begin
  163. paths64 := GR32_Clipper2.FloatPointsToPaths64(paths);
  164. inherited AddPaths(paths64, polyType, isOpen);
  165. end;
  166. //------------------------------------------------------------------------------
  167. procedure TClipper.AddPaths(const paths: TArrayOfArrayOfFixedPoint; polyType: TPathType; isOpen: Boolean);
  168. var
  169. paths64: TPaths64;
  170. begin
  171. paths64 := GR32_Clipper2.FixedPointsToPaths64(paths);
  172. inherited AddPaths(paths64, polyType, isOpen);
  173. end;
  174. //------------------------------------------------------------------------------
  175. function TClipper.Execute(clipType: TClipType; fillRule: TFillRule; out closedPaths: TArrayOfArrayOfFloatPoint): Boolean;
  176. var
  177. closedSolutions: TPaths64;
  178. begin
  179. Result := inherited Execute(clipType, fillRule, closedSolutions);
  180. if (Result) then
  181. closedPaths := GR32_Clipper2.Paths64ToFloatPoints(closedSolutions)
  182. else
  183. SetLength(closedPaths, 0);
  184. end;
  185. //------------------------------------------------------------------------------
  186. function TClipper.Execute(clipType: TClipType; fillRule: TFillRule; out closedPaths: TArrayOfArrayOfFixedPoint): Boolean;
  187. var
  188. closedSolutions: TPaths64;
  189. begin
  190. Result := inherited Execute(clipType, fillRule, closedSolutions);
  191. if (Result) then
  192. closedPaths := GR32_Clipper2.Paths64ToFixedPoints(closedSolutions)
  193. else
  194. SetLength(closedPaths, 0);
  195. end;
  196. //------------------------------------------------------------------------------
  197. function TClipper.Execute(clipType: TClipType; fillRule: TFillRule; out closedPaths, openPaths: TArrayOfArrayOfFloatPoint): Boolean;
  198. var
  199. closedSolutions, openSolutions: TPaths64;
  200. begin
  201. Result := inherited Execute(clipType, fillRule, closedSolutions, openSolutions);
  202. if (Result) then
  203. begin
  204. closedPaths := GR32_Clipper2.Paths64ToFloatPoints(closedSolutions);
  205. openPaths := GR32_Clipper2.Paths64ToFloatPoints(openSolutions);
  206. end else
  207. begin
  208. SetLength(closedPaths, 0);
  209. SetLength(openPaths, 0);
  210. end;
  211. end;
  212. //------------------------------------------------------------------------------
  213. function TClipper.Execute(clipType: TClipType; fillRule: TFillRule; out closedPaths, openPaths: TArrayOfArrayOfFixedPoint): Boolean;
  214. var
  215. closedSolutions, openSolutions: TPaths64;
  216. begin
  217. Result := inherited Execute(clipType, fillRule, closedSolutions, openSolutions);
  218. if (Result) then
  219. begin
  220. closedPaths := GR32_Clipper2.Paths64ToFixedPoints(closedSolutions);
  221. openPaths := GR32_Clipper2.Paths64ToFixedPoints(openSolutions);
  222. end else
  223. begin
  224. SetLength(closedPaths, 0);
  225. SetLength(openPaths, 0);
  226. end;
  227. end;
  228. //------------------------------------------------------------------------------
  229. function TClipper.GetBounds: TFloatRect;
  230. begin
  231. Result := GR32_Clipper2.FloatRect(inherited GetBounds);
  232. end;
  233. //------------------------------------------------------------------------------
  234. // TClipperOffset methods ...
  235. //------------------------------------------------------------------------------
  236. procedure TClipperOffset.AddPath(const path: TArrayOfFloatPoint; joinType: TJoinType; endType: TEndType);
  237. var
  238. path64: TPath64;
  239. begin
  240. path64 := GR32_Clipper2.FloatPointsToPath64(path);
  241. inherited AddPath(path64, joinType, endType);
  242. end;
  243. procedure TClipperOffset.AddPath(const path: TArrayOfFloatPoint);
  244. begin
  245. AddPath(path, jtRound, etPolygon);
  246. end;
  247. //------------------------------------------------------------------------------
  248. procedure TClipperOffset.AddPaths(const paths: TArrayOfArrayOfFloatPoint; joinType: TJoinType; endType: TEndType);
  249. var
  250. paths64: TPaths64;
  251. begin
  252. paths64 := GR32_Clipper2.FloatPointsToPaths64(paths);
  253. inherited AddPaths(paths64, joinType, endType);
  254. end;
  255. procedure TClipperOffset.AddPaths(const paths: TArrayOfArrayOfFloatPoint);
  256. begin
  257. AddPaths(paths, jtRound, etPolygon);
  258. end;
  259. //------------------------------------------------------------------------------
  260. function TClipperOffset.Execute(delta: Double): TArrayOfArrayOfFloatPoint;
  261. var
  262. paths64: TPaths64;
  263. begin
  264. paths64 := inherited Execute(delta);
  265. Result := GR32_Clipper2.Paths64ToFloatPoints(paths64);
  266. end;
  267. procedure TClipperOffset.Execute(delta: Double; jt: TJoinType; et: TEndType; out solution: TArrayOfArrayOfFloatPoint);
  268. begin
  269. solution := Execute(delta);
  270. end;
  271. //------------------------------------------------------------------------------
  272. end.