123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- unit GR32_Clipper2;
- (* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1 or LGPL 2.1 with linking exception
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * Alternatively, the contents of this file may be used under the terms of the
- * Free Pascal modified version of the GNU Lesser General Public License
- * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
- * of this license are applicable instead of those above.
- * Please see the file LICENSE.txt for additional information concerning this
- * license.
- *
- * The Original Code is GR32_Clipper
- *
- * The Initial Developer of the Original Code is
- * Angus Johnson
- *
- * Portions created by the Initial Developer are Copyright (C) 2012-2022
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** *)
- interface
- uses Gr32, Gr32_Polygons,
- Clipper, Clipper.Core, Clipper.Engine, Clipper.Offset;
- function Gr32BoolOp(clipType: TClipType; fillMode: TPolyFillMode;
- const subject, clip: Gr32.TArrayOfArrayOfFixedPoint):
- Gr32.TArrayOfArrayOfFixedPoint; overload;
- function Gr32_Intersect(const subject, clip: Gr32.TArrayOfArrayOfFixedPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFixedPoint; overload;
- function Gr32_Union(const subject, clip: Gr32.TArrayOfArrayOfFixedPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFixedPoint; overload;
- function Gr32_Difference(const subject, clip: Gr32.TArrayOfArrayOfFixedPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFixedPoint; overload;
- function Gr32_XOR(const subject, clip: Gr32.TArrayOfArrayOfFixedPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFixedPoint; overload;
- function Gr32_Inflate(const paths: Gr32.TArrayOfArrayOfFixedPoint;
- delta: double; jointType: TJoinType; endType: TEndType;
- miterLimit: double = 2): Gr32.TArrayOfArrayOfFixedPoint; overload;
- function Gr32BoolOp(clipType: TClipType; fillMode: TPolyFillMode;
- const subject, clip: Gr32.TArrayOfArrayOfFloatPoint):
- Gr32.TArrayOfArrayOfFloatPoint; overload;
- function Gr32_Intersect(const subject, clip: Gr32.TArrayOfArrayOfFloatPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFloatPoint; overload;
- function Gr32_Union(const subject, clip: Gr32.TArrayOfArrayOfFloatPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFloatPoint; overload;
- function Gr32_Difference(const subject, clip: Gr32.TArrayOfArrayOfFloatPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFloatPoint; overload;
- function Gr32_XOR(const subject, clip: Gr32.TArrayOfArrayOfFloatPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFloatPoint; overload;
- function Gr32_Inflate(const paths: Gr32.TArrayOfArrayOfFloatPoint;
- delta: double; jointType: TJoinType; endType: TEndType;
- miterLimit: double = 2): Gr32.TArrayOfArrayOfFloatPoint; overload;
- function FixedPointsToPath64(const pathFixed: Gr32.TArrayOfFixedPoint): Clipper.TPath64;
- function FloatPointsToPath64(const pathFloat: Gr32.TArrayOfFloatPoint): Clipper.TPath64;
- function FixedPointsToPaths64(const pathsFixed: Gr32.TArrayOfArrayOfFixedPoint): Clipper.TPaths64;
- function FloatPointsToPaths64(const pathsFloat: Gr32.TArrayOfArrayOfFloatPoint): Clipper.TPaths64;
- function Paths64ToFixedPoints(const paths: Clipper.TPaths64): Gr32.TArrayOfArrayOfFixedPoint;
- function Paths64ToFloatPoints(const paths: Clipper.TPaths64): Gr32.TArrayOfArrayOfFloatPoint;
- function FloatRect(const r: TRect64): GR32.TFloatRect;
- type
- TClipper = Clipper.Engine.TClipper64;
- TClipper64 = Clipper.Engine.TClipper64;
- TPoint64 = Clipper.Core.TPoint64;
- TRect64 = Clipper.Core.TRect64;
- TPath64 = Clipper.Core.TPath64;
- TPaths64 = Clipper.Core.TPaths64;
- TPointD = Clipper.Core.TPointD;
- TRectD = Clipper.Core.TRectD;
- TPathD = Clipper.Core.TPathD;
- TPathsD = Clipper.Core.TPathsD;
- TFillRule = Clipper.Core.TFillRule;
- TPolyTree64 = Clipper.Engine.TPolyTree64;
- TPolyTreeD = Clipper.Engine.TPolyTreeD;
- TJoinType = Clipper.Offset.TJoinType;
- TEndType = Clipper.Offset.TEndType;
- TClipType = Clipper.Core.TClipType;
- const
- frEvenOdd = Clipper.Core.frEvenOdd;
- frNonZero = Clipper.Core.frNonZero;
- frPositive = Clipper.Core.frPositive;
- frNegative = Clipper.Core.frNegative;
- jtSquare = Clipper.Offset.jtSquare;
- jtRound = Clipper.Offset.jtRound;
- jtMiter = Clipper.Offset.jtMiter;
- etPolygon = Clipper.Offset.etPolygon;
- etJoined = Clipper.Offset.etJoined;
- etButt = Clipper.Offset.etButt;
- etSquare = Clipper.Offset.etSquare;
- etRound = Clipper.Offset.etRound;
- ctNone = Clipper.Core.ctNone;
- ctIntersection = Clipper.Core.ctIntersection;
- ctUnion = Clipper.Core.ctUnion;
- ctDifference = Clipper.Core.ctDifference;
- ctXor = Clipper.Core.ctXor;
- function ClipperFloatScale: Double;
- function SetClipperFloatScale(Value: Double): Double;
- implementation
- var
- FClipperFloatScale: Double;
- FClipperInvFloatScale: Double;
- function ClipperFloatScale: Double;
- begin
- Result := FClipperFloatScale;
- end;
- function SetClipperFloatScale(Value: Double): Double;
- begin
- Result := FClipperFloatScale;
- if (Value <> 0) then
- begin
- FClipperFloatScale := Value;
- FClipperInvFloatScale := 1/FClipperFloatScale;
- end;
- end;
- function DblToInt64(val: double): Int64; {$IFDEF INLINE} inline; {$ENDIF}
- var
- exp: integer;
- i64: UInt64 absolute val;
- begin
- //https://en.wikipedia.org/wiki/Double-precision_floating-point_format
- Result := 0;
- if i64 = 0 then Exit;
- exp := Integer(Cardinal(i64 shr 52) and $7FF) - 1023;
- //nb: when exp == 1024 then val == INF or NAN.
- if exp < 0 then Exit;
- Result := ((i64 and $1FFFFFFFFFFFFF) shr (52 - exp)) or (UInt64(1) shl exp);
- if val < 0 then Result := -Result;
- end;
- function FloatRect(const r: TRect64): GR32.TFloatRect;
- begin
- Result.Left := DblToInt64(r.Left * FClipperFloatScale);
- Result.Top := DblToInt64(r.Top * FClipperFloatScale);
- Result.Right := DblToInt64(r.Right * FClipperFloatScale);
- Result.Bottom := DblToInt64(r.Bottom * FClipperFloatScale);
- end;
- function FixedPointsToPath64(const pathFixed: Gr32.TArrayOfFixedPoint): Clipper.TPath64;
- var
- i, len: integer;
- begin
- len := Length(pathFixed);
- SetLength(Result, len);
- for i := 0 to len -1 do
- begin
- Result[i].X := pathFixed[i].X;
- Result[i].Y := pathFixed[i].Y;
- end;
- end;
- function FloatPointsToPath64(const pathFloat: Gr32.TArrayOfFloatPoint): Clipper.TPath64;
- var
- i, len: integer;
- begin
- len := Length(pathFloat);
- SetLength(Result, len);
- for i := 0 to len -1 do
- begin
- Result[i].X := DblToInt64(pathFloat[i].X * FClipperFloatScale);
- Result[i].Y := DblToInt64(pathFloat[i].Y * FClipperFloatScale);
- end;
- end;
- function FixedPointsToPaths64(
- const pathsFixed: Gr32.TArrayOfArrayOfFixedPoint): Clipper.TPaths64;
- var
- i, len: integer;
- begin
- len := Length(pathsFixed);
- SetLength(Result, len);
- for i := 0 to len -1 do
- Result[i] := FixedPointsToPath64(pathsFixed[i]);
- end;
- function FloatPointsToPaths64(
- const pathsFloat: Gr32.TArrayOfArrayOfFloatPoint): Clipper.TPaths64;
- var
- i, len: integer;
- begin
- len := Length(pathsFloat);
- SetLength(Result, len);
- for i := 0 to len -1 do
- Result[i] := FloatPointsToPath64(pathsFloat[i]);
- end;
- function Path64ToFixedPoints(const path: Clipper.TPath64): Gr32.TArrayOfFixedPoint;
- var
- i, len: integer;
- begin
- len := Length(path);
- SetLength(Result, len);
- for i := 0 to len -1 do
- begin
- Result[i].X := TFixed(path[i].X);
- Result[i].Y := TFixed(path[i].Y);
- end;
- end;
- function Path64ToFloatPoints(const path: Clipper.TPath64): Gr32.TArrayOfFloatPoint;
- var
- i, len: integer;
- begin
- len := Length(path);
- SetLength(Result, len);
- for i := 0 to len -1 do
- begin
- Result[i].X := path[i].X * FClipperInvFloatScale;
- Result[i].Y := path[i].Y * FClipperInvFloatScale;
- end;
- end;
- function Paths64ToFixedPoints(const paths: Clipper.TPaths64): Gr32.TArrayOfArrayOfFixedPoint;
- var
- i, len: integer;
- begin
- len := Length(paths);
- SetLength(Result, len);
- for i := 0 to len -1 do
- Result[i] := Path64ToFixedPoints(paths[i]);
- end;
- function Paths64ToFloatPoints(const paths: Clipper.TPaths64): Gr32.TArrayOfArrayOfFloatPoint;
- var
- i, len: integer;
- begin
- len := Length(paths);
- SetLength(Result, len);
- for i := 0 to len -1 do
- Result[i] := Path64ToFloatPoints(paths[i]);
- end;
- function Gr32BoolOp(clipType: TClipType; fillMode: TPolyFillMode;
- const subject, clip: Gr32.TArrayOfArrayOfFixedPoint):
- Gr32.TArrayOfArrayOfFixedPoint;
- var
- sub, clp, sol: TPaths64;
- begin
- sub := FixedPointsToPaths64(subject);
- clp := FixedPointsToPaths64(clip);
- sol := Clipper.BooleanOp(clipType, sub, clp, TFillRule(fillMode));
- Result := Paths64ToFixedPoints(sol);
- end;
- function Gr32BoolOp(clipType: TClipType; fillMode: TPolyFillMode;
- const subject, clip: Gr32.TArrayOfArrayOfFloatPoint):
- Gr32.TArrayOfArrayOfFloatPoint;
- var
- sub, clp, sol: TPaths64;
- begin
- sub := FloatPointsToPaths64(subject);
- clp := FloatPointsToPaths64(clip);
- sol := Clipper.BooleanOp(clipType, sub, clp, TFillRule(fillMode));
- Result := Paths64ToFloatPoints(sol);
- end;
- function Gr32_Intersect(const subject, clip: Gr32.TArrayOfArrayOfFixedPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFixedPoint;
- begin
- Result := Gr32BoolOp(ctIntersection, fillMode, subject, clip);
- end;
- function Gr32_Union(const subject, clip: Gr32.TArrayOfArrayOfFixedPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFixedPoint;
- begin
- Result := Gr32BoolOp(ctUnion, fillMode, subject, clip);
- end;
- function Gr32_Difference(const subject, clip: Gr32.TArrayOfArrayOfFixedPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFixedPoint;
- begin
- Result := Gr32BoolOp(ctDifference, fillMode, subject, clip);
- end;
- function Gr32_XOR(const subject, clip: Gr32.TArrayOfArrayOfFixedPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFixedPoint;
- begin
- Result := Gr32BoolOp(ctXor, fillMode, subject, clip);
- end;
- function Gr32_Inflate(const paths: Gr32.TArrayOfArrayOfFixedPoint;
- delta: double; jointType: TJoinType; endType: TEndType;
- miterLimit: double = 2): Gr32.TArrayOfArrayOfFixedPoint;
- var
- sub, sol: TPaths64;
- begin
- sub := FixedPointsToPaths64(paths);
- sol := Clipper.InflatePaths(sub, delta * FixedOne,
- jointType, endType, miterLimit);
- sol := RamerDouglasPeucker(sol, 10);
- Result := Paths64ToFixedPoints(sol);
- end;
- function Gr32_Intersect(const subject, clip: Gr32.TArrayOfArrayOfFloatPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFloatPoint;
- begin
- Result := Gr32BoolOp(ctIntersection, fillMode, subject, clip);
- end;
- function Gr32_Union(const subject, clip: Gr32.TArrayOfArrayOfFloatPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFloatPoint;
- begin
- Result := Gr32BoolOp(ctUnion, fillMode, subject, clip);
- end;
- function Gr32_Difference(const subject, clip: Gr32.TArrayOfArrayOfFloatPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFloatPoint;
- begin
- Result := Gr32BoolOp(ctDifference, fillMode, subject, clip);
- end;
- function Gr32_XOR(const subject, clip: Gr32.TArrayOfArrayOfFloatPoint;
- fillMode: TPolyFillMode): Gr32.TArrayOfArrayOfFloatPoint;
- begin
- Result := Gr32BoolOp(ctXor, fillMode, subject, clip);
- end;
- function Gr32_Inflate(const paths: Gr32.TArrayOfArrayOfFloatPoint;
- delta: double; jointType: TJoinType; endType: TEndType;
- miterLimit: double = 2): Gr32.TArrayOfArrayOfFloatPoint;
- var
- sub, sol: TPaths64;
- begin
- sub := FloatPointsToPaths64(paths);
- sol := Clipper.InflatePaths(sub, delta * FClipperFloatScale,
- jointType, endType, miterLimit);
- sol := RamerDouglasPeucker(sol, 1);
- Result := Paths64ToFloatPoints(sol);
- end;
- initialization
- SetClipperFloatScale(100);
- end.
|