diff --git a/CPP/Clipper2Lib/include/clipper2/clipper.export.h b/CPP/Clipper2Lib/include/clipper2/clipper.export.h index 3f41fad9..8dd17283 100644 --- a/CPP/Clipper2Lib/include/clipper2/clipper.export.h +++ b/CPP/Clipper2Lib/include/clipper2/clipper.export.h @@ -1,6 +1,6 @@ /******************************************************************************* * Author : Angus Johnson * -* Date : 25 October 2023 * +* Date : 26 October 2023 * * Website : http://www.angusj.com * * Copyright : Angus Johnson 2010-2023 * * Purpose : This module exports the Clipper2 Library (ie DLL/so) * @@ -31,15 +31,24 @@ // These structures are very similar to their respecitve path structures. These // structures not only contain any number of consecutive CPath64 or CPathD // structures but, preceeding these paths, there is an extra x,y pair of values -// that contains the path count. However, in this case the x value = 0, and -// the y value contains the count (ie the number of following paths). +// that contains the path count. However, in this case the x value = array length, +// and the y value contains the count (ie the number of following paths). // _______________________________ // |counter|path1|path2|...|pathN| -// |0, N | | |...|pathN| +// |len, N | | |...|pathN| // _______________________________ // // -// The CPolytree64 & CPolytreeD structures are defined lower down. +// CPolytree64 and CPolytreeD: +// These are both simple arrays (of int64_t or double respectively). Otherwise +// their structures are identical, and consist of series of CPolyPath structures. +// The CPolyPath structure is as follows: +// Usually polygon length (N) except for the very first CPolyPath entry that +// contains the array size. (The top-most CPolyPath never contains a polygon.) +// ChildCount (C) +// N * x,y coordinates in Polygon +// C * Nested child CPolyPath structures + #ifndef CLIPPER2_EXPORT_H #define CLIPPER2_EXPORT_H @@ -59,9 +68,6 @@ typedef int64_t* CPaths64; typedef double* CPathD; typedef double* CPathsD; -static const int64_t magic_64 = 64; -static const double magic_D = 68; - typedef int64_t* CPolyPath64; typedef int64_t* CPolyTree64; // magic, hole, child_count, poly_len (4 total) + polygon + nested childs @@ -205,8 +211,9 @@ size_t& cnt, size_t& array_len) static size_t GetPolyPath64ArrayLen(const PolyPath64& pp) { - size_t result = 4; // magic + is_hole + child_count + poly_length + size_t result = 2; // poly_length + child_count result += pp.Polygon().size() * 2; + //plus nested children :) for (size_t i = 0; i < pp.Count(); ++i) result += GetPolyPath64ArrayLen(*pp[i]); return result; @@ -223,7 +230,7 @@ static CPaths64 CreateCPaths64(const Paths64& paths) size_t cnt, array_len; GetPathCountAndCPathsArrayLen(paths, cnt, array_len); int64_t* result = new int64_t[array_len], * v = result; - *v++ = 0; + *v++ = array_len; *v++ = cnt; for (const Path64& path : paths) { @@ -244,7 +251,7 @@ static CPathsD CreateCPathsD(const PathsD& paths) size_t cnt, array_len; GetPathCountAndCPathsArrayLen(paths, cnt, array_len); double* result = new double[array_len], * v = result; - *v++ = 0; + *v++ = array_len; *v++ = (double)cnt; for (const PathD& path : paths) { @@ -266,7 +273,7 @@ CPathsD CreateCPathsDFromPaths64(const Paths64& paths, double scale) size_t cnt, array_len; GetPathCountAndCPathsArrayLen(paths, cnt, array_len); CPathsD result = new double[array_len], v = result; - *v++ = 0; + *v++ = array_len; *v++ = (double)cnt; for (const Path64& path : paths) { @@ -355,10 +362,8 @@ static Paths64 ConvertCPathsDToPaths64(const CPathsD paths, double scale) static void CreateCPolyPath64(const PolyPath64* pp, CPolyPath64& v) { - *v++ = magic_64; - *v++ = pp->IsHole() ? 1 : 0; - *v++ = pp->Count(); *v++ = pp->Polygon().size(); + *v++ = pp->Count(); for (const Point64& pt : pp->Polygon()) { *v++ = pt.x; @@ -377,10 +382,8 @@ static CPolyTree64 CreateCPolyTree64(const PolyTree64& tree) int64_t* result = new int64_t[array_len]; int64_t* v = &result[0]; - *v++ = magic_64; - *v++ = 0; + *v++ = array_len; *v++ = tree.Count(); - *v++ = 0; for (size_t i = 0; i < tree.Count(); ++i) CreateCPolyPath64(tree.Child(i), v); return result; @@ -388,10 +391,8 @@ static CPolyTree64 CreateCPolyTree64(const PolyTree64& tree) static void CreateCPolyPathD(const PolyPath64* pp, CPolyPathD& v, double scale) { - *v++ = magic_64; - *v++ = pp->IsHole() ? 1 : 0; - *v++ = (double)pp->Count(); *v++ = (double)pp->Polygon().size(); + *v++ = (double)pp->Count(); for (const Point64& pt : pp->Polygon()) { *v++ = pt.x * scale; @@ -409,12 +410,10 @@ static CPolyTreeD CreateCPolyTreeD(const PolyTree64& tree, double scale) if (!cnt) return nullptr; // allocate storage double* result = new double[array_len]; - double* v = &result[0]; + double* v = result; - *v++ = magic_64; - *v++ = 0; + *v++ = array_len; *v++ = (double)tree.Count(); - *v++ = 0; for (size_t i = 0; i < tree.Count(); ++i) CreateCPolyPathD(tree.Child(i), v, scale); return result; diff --git a/CPP/Tests/TestExportHeaders.cpp b/CPP/Tests/TestExportHeaders.cpp index af761573..01557700 100644 --- a/CPP/Tests/TestExportHeaders.cpp +++ b/CPP/Tests/TestExportHeaders.cpp @@ -8,8 +8,8 @@ using namespace Clipper2Lib; static bool CreatePolyPath64FromCPolyPath(CPolyPath64& v, PolyPath64& owner) { - int64_t magic = *v++, hole = *v++, child_count = *v++, poly_len = *v++; - if (magic != magic_64 || !poly_len) return false; + int64_t poly_len = *v++, child_count = *v++; + if (!poly_len) return false; Path64 path; path.reserve(poly_len); for (size_t i = 0; i < poly_len; ++i) @@ -28,8 +28,7 @@ static bool BuildPolyTree64FromCPolyTree(CPolyTree64 tree, PolyTree64& result) { result.Clear(); int64_t* v = tree; - int64_t magic = *v++, hole = *v++, child_count = *v++, poly_len = *v++; - if (magic != magic_64 || poly_len) return false; + int64_t array_len = *v++, child_count = *v++; for (size_t i = 0; i < child_count; ++i) if (!CreatePolyPath64FromCPolyPath(v, result)) return false; return true; @@ -37,8 +36,8 @@ static bool BuildPolyTree64FromCPolyTree(CPolyTree64 tree, PolyTree64& result) static bool CreatePolyPathDFromCPolyPath(CPolyPathD& v, PolyPathD& owner) { - int64_t magic = *v++, hole = *v++, child_count = *v++, poly_len = *v++; - if (magic != magic_64 || !poly_len) return false; + int64_t poly_len = *v++, child_count = *v++; + if (!poly_len) return false; PathD path; path.reserve(poly_len); for (size_t i = 0; i < poly_len; ++i) @@ -56,8 +55,7 @@ static bool BuildPolyTreeDFromCPolyTree(CPolyTreeD tree, PolyTreeD& result) { result.Clear(); double* v = tree; - int64_t magic = *v++, hole = *v++, child_count = *v++, poly_len = *v++; - if (magic != magic_64 || poly_len) return false; + int64_t array_len = *v++, child_count = *v++; for (size_t i = 0; i < child_count; ++i) if (!CreatePolyPathDFromCPolyPath(v, result)) return false; return true; diff --git a/DLL/Delphi_TestApp/Test_DLL.dpr b/DLL/Delphi_TestApp/Test_DLL.dpr index 39e56683..775dbc36 100644 --- a/DLL/Delphi_TestApp/Test_DLL.dpr +++ b/DLL/Delphi_TestApp/Test_DLL.dpr @@ -111,7 +111,6 @@ function RectClipLinesD(const rect: TRectD; const Intersection = 1; Union = 2; Difference =3; Xor_ = 4; EvenOdd = 0; NonZero = 1; Positive = 2; Negative = 3; - magic_64 = 64; magic_D = 68; //////////////////////////////////////////////////////// // functions related to Clipper2 DLL structures @@ -142,7 +141,7 @@ begin if Length(pp[i]) > 0 then inc(len2, Length(pp[i]) *2 + 2); GetMem(Result, len2 * sizeof(Int64)); - Result[0] := 0; + Result[0] := len2; Result[1] := len; v := @Result[2]; for i := 0 to len -1 do @@ -170,7 +169,7 @@ begin if Length(pp[i]) > 0 then inc(len2, Length(pp[i]) *2 + 2); GetMem(Result, len2 * sizeof(double)); - Result[0] := 0; + Result[0] := len2; Result[1] := len; v := @Result[2]; for i := 0 to len -1 do @@ -194,7 +193,7 @@ var begin Result := nil; v := PInt64(cp); - if v^ <> 0 then Exit; inc(v); + inc(v); // ignore array length len := v^; inc(v); SetLength(Result, len); for i := 0 to len -1 do @@ -215,10 +214,10 @@ var v: PDouble; begin Result := nil; - if cp[0] <> 0 then Exit; - len := Round(cp[1]); + v := PDouble(cp); + inc(v); // ignore array length + len := Round(cp[1]); inc(v); SetLength(Result, len); - v := @cp[2]; for i := 0 to len -1 do begin len2 := Round(v^); inc(v, 2); @@ -235,7 +234,7 @@ function GetPolyPath64ArrayLen(const pp: TPolyPath64): integer; var i: integer; begin - Result := 4; // magic + is_hole + child_count + poly_length + Result := 2; // poly_length + child_count inc(Result, Length(pp.Polygon) * 2); for i := 0 to pp.Count -1 do Inc(Result, GetPolyPath64ArrayLen(pp.Child[i])); @@ -253,14 +252,9 @@ procedure CreateCPolyPathD(const pp: TPolyPath64; var i, len: integer; begin - v^ := magic_64; inc(v); - if pp.IsHole then - v^ := 1 else - v^ := 0; - inc(v); - v^ := pp.Count; inc(v); len := Length(pp.Polygon); v^ := len; inc(v); + v^ := pp.Count; inc(v); for i := 0 to len -1 do begin v^ := pp.Polygon[i].x * scale; @@ -283,10 +277,8 @@ begin GetMem(Result, arrayLen * SizeOf(double)); v := PDouble(Result); - v^ := magic_64; inc(v); - v^ := 0; inc(v); + v^ := arrayLen; inc(v); v^ := tree.Count; inc(v); - v^ := 0; inc(v); for i := 0 to tree.Count - 1 do CreateCPolyPathD(tree.Child[i], v, scale); end; @@ -298,10 +290,9 @@ var newOwner: TPolyPath64; begin Result := false; - magic := v^; inc(v, 2); + len := v^; inc(v); //polygon length childCount := v^; inc(v); - len := v^; inc(v); - if (magic <> magic_64) or (len = 0) then Exit; + if (len = 0) then Exit; SetLength(path, len); for i := 0 to len -1 do begin @@ -322,10 +313,8 @@ begin Result := false; outTree.Clear(); v := PInt64(tree); - magic := v^; inc(v, 2); + inc(v); //skip array size childCount := v^; inc(v); - len := v^; inc(v); - if (magic <> magic_64) or (len > 0) then Exit; for i := 0 to childCount -1 do if not CreatePolyPath64FromCPolyPath(v, outTree) then Exit; Result := true; @@ -338,10 +327,9 @@ var newOwner: TPolyPathD; begin Result := false; - magic := Round(v^); inc(v, 2); - childCount := Round(v^); inc(v); len := Round(v^); inc(v); - if (magic <> magic_64) or (len = 0) then Exit; + childCount := Round(v^); inc(v); + if (len = 0) then Exit; SetLength(path, len); for i := 0 to len -1 do begin @@ -362,10 +350,8 @@ begin Result := false; outTree.Clear(); v := PDouble(tree); - magic := Round(v^); inc(v, 2); + inc(v); // ignore array size childCount := Round(v^); inc(v); - len := Round(v^); inc(v); - if (magic <> magic_64) or (len > 0) then Exit; for i := 0 to childCount -1 do if not CreatePolyPathDFromCPolyPath(v, outTree) then Exit; Result := true;