From 2b665ac7e3e4ede7c32ce89e608f5163ea4d2756 Mon Sep 17 00:00:00 2001 From: angusj Date: Thu, 10 Oct 2024 08:41:44 +1000 Subject: [PATCH] Reversed LINQ dependency in C# code --- CSharp/Clipper2Lib/Clipper.Core.cs | 21 +++- CSharp/Clipper2Lib/Clipper.Engine.cs | 40 +++++-- CSharp/Clipper2Lib/Clipper.Minkowski.cs | 11 +- CSharp/Clipper2Lib/Clipper.Offset.cs | 27 +++-- CSharp/Clipper2Lib/Clipper.RectClip.cs | 28 +++-- CSharp/Clipper2Lib/Clipper.cs | 130 ++++++++++++++-------- CSharp/Utils/ClipFileIO/Clipper.FileIO.cs | 4 +- CSharp/Utils/SVG/Clipper.SVG.cs | 29 ++--- 8 files changed, 192 insertions(+), 98 deletions(-) diff --git a/CSharp/Clipper2Lib/Clipper.Core.cs b/CSharp/Clipper2Lib/Clipper.Core.cs index 3b8e18b1..dd422ed7 100644 --- a/CSharp/Clipper2Lib/Clipper.Core.cs +++ b/CSharp/Clipper2Lib/Clipper.Core.cs @@ -1,6 +1,6 @@ /******************************************************************************* * Author : Angus Johnson * -* Date : 17 September 2024 * +* Date : 10 October 2024 * * Website : http://www.angusj.com * * Copyright : Angus Johnson 2010-2024 * * Purpose : Core structures and functions for the Clipper Library * @@ -10,7 +10,6 @@ #nullable enable using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; namespace Clipper2Lib @@ -479,7 +478,9 @@ public Path64(int capacity = 0) : base(capacity) { } public Path64(IEnumerable path) : base(path) { } public override string ToString() { - string s = this.Aggregate("", (current, p) => current + p.ToString() + ", "); + string s = ""; + foreach (Point64 p in this) + s = s + p.ToString() + ", "; if (s != "") s = s.Remove(s.Length - 2); return s; } @@ -492,7 +493,10 @@ public Paths64(int capacity = 0) : base(capacity) { } public Paths64(IEnumerable paths) : base(paths) { } public override string ToString() { - return this.Aggregate("", (current, p) => current + p + "\n"); + string s = ""; + foreach (Path64 p in this) + s = s + p + "\n"; + return s; } } @@ -503,7 +507,9 @@ public PathD(int capacity = 0) : base(capacity) { } public PathD(IEnumerable path) : base(path) { } public string ToString(int precision = 2) { - string s = this.Aggregate("", (current, p) => current + p.ToString(precision) + ", "); + string s = ""; + foreach (PointD p in this) + s = s + p.ToString(precision) + ", "; if (s != "") s = s.Remove(s.Length - 2); return s; } @@ -516,7 +522,10 @@ public PathsD(int capacity = 0) : base(capacity) { } public PathsD(IEnumerable paths) : base(paths) { } public string ToString(int precision = 2) { - return this.Aggregate("", (current, p) => current + p.ToString(precision) + "\n"); + string s = ""; + foreach (PathD p in this) + s = s + p.ToString(precision) + "\n"; + return s; } } diff --git a/CSharp/Clipper2Lib/Clipper.Engine.cs b/CSharp/Clipper2Lib/Clipper.Engine.cs index c1dc41df..7cfc0b5f 100644 --- a/CSharp/Clipper2Lib/Clipper.Engine.cs +++ b/CSharp/Clipper2Lib/Clipper.Engine.cs @@ -1,6 +1,6 @@ /******************************************************************************* * Author : Angus Johnson * -* Date : 17 September 2024 * +* Date : 10 October 2024 * * Website : http://www.angusj.com * * Copyright : Angus Johnson 2010-2024 * * Purpose : This is the main polygon clipping module * @@ -13,7 +13,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; namespace Clipper2Lib @@ -236,7 +235,8 @@ internal static void EnsureCapacity(this List list, int minCapacity) internal static void AddPathsToVertexList(Paths64 paths, PathType polytype, bool isOpen, List minimaList, List vertexList) { - int totalVertCnt = paths.Sum(path => path.Count); + int totalVertCnt = 0; + foreach (Path64 path in paths) totalVertCnt += path.Count; vertexList.EnsureCapacity(vertexList.Count + totalVertCnt); foreach (Path64 path in paths) @@ -2528,7 +2528,9 @@ private static int HorzSegSort(HorzSegment? hs1, HorzSegment? hs2) private void ConvertHorzSegsToJoins() { - int k = _horzSegList.Count(UpdateHorzSegment); + int k = 0; + foreach (HorzSegment hs in _horzSegList) + if (UpdateHorzSegment(hs)) k++; if (k < 2) return; _horzSegList.Sort(HorzSegSort); @@ -3032,8 +3034,10 @@ private bool CheckBounds(OutRec outrec) private bool CheckSplitOwner(OutRec outrec, List? splits) { - foreach (OutRec? split in splits!.Select(i => GetRealOutRec(_outrecList[i])).OfType().Where(split => split != outrec && split.recursiveSplit != outrec)) + foreach (int i in splits!) { + OutRec? split = GetRealOutRec(_outrecList[i]); + if (split == null || split == outrec || split.recursiveSplit == outrec) continue; split.recursiveSplit = outrec; //#599 if (split.splits != null && CheckSplitOwner(outrec, split.splits)) return true; if (!IsValidOwner(outrec, split) || @@ -3043,7 +3047,6 @@ private bool CheckSplitOwner(OutRec outrec, List? splits) outrec.owner = split; //found in split return true; } - return false; } private void RecursiveCheckOwners(OutRec outrec, PolyPathBase polypath) @@ -3343,9 +3346,11 @@ public bool Execute(ClipType clipType, FillRule fillRule, if (!success) return false; solutionClosed.EnsureCapacity(solClosed64.Count); - solutionClosed.AddRange(solClosed64.Select(path => Clipper.ScalePathD(path, _invScale))); + foreach (Path64 path in solClosed64) + solutionClosed.Add(Clipper.ScalePathD(path, _invScale)); solutionOpen.EnsureCapacity(solOpen64.Count); - solutionOpen.AddRange(solOpen64.Select(path => Clipper.ScalePathD(path, _invScale))); + foreach (Path64 path in solOpen64) + solutionOpen.Add(Clipper.ScalePathD(path, _invScale)); return true; } @@ -3380,7 +3385,8 @@ public bool Execute(ClipType clipType, FillRule fillRule, PolyTreeD polytree, Pa if (!success) return false; if (oPaths.Count <= 0) return true; openPaths.EnsureCapacity(oPaths.Count); - openPaths.AddRange(oPaths.Select(path => Clipper.ScalePathD(path, _invScale))); + foreach (Path64 path in oPaths) + openPaths.Add(Clipper.ScalePathD(path, _invScale)); return true; } @@ -3534,7 +3540,13 @@ public PolyPath64 Child(int index) [MethodImpl(MethodImplOptions.AggressiveInlining)] public double Area() { - return (Polygon == null ? 0 : Clipper.Area(Polygon)) + _childs.Cast().Sum(child => child.Area()); + double result = Polygon == null ? 0 : Clipper.Area(Polygon); + foreach (PolyPathBase polyPathBase in _childs) + { + PolyPath64 child = (PolyPath64) polyPathBase; + result += child.Area(); + } + return result; } } public class PolyPathD : PolyPathBase @@ -3577,7 +3589,13 @@ public PolyPathD this[int index] [MethodImpl(MethodImplOptions.AggressiveInlining)] public double Area() { - return (Polygon == null ? 0 : Clipper.Area(Polygon)) + _childs.Cast().Sum(child => child.Area()); + double result = Polygon == null ? 0 : Clipper.Area(Polygon); + foreach (PolyPathBase polyPathBase in _childs) + { + PolyPathD child = (PolyPathD) polyPathBase; + result += child.Area(); + } + return result; } } diff --git a/CSharp/Clipper2Lib/Clipper.Minkowski.cs b/CSharp/Clipper2Lib/Clipper.Minkowski.cs index 91412b14..afad586f 100644 --- a/CSharp/Clipper2Lib/Clipper.Minkowski.cs +++ b/CSharp/Clipper2Lib/Clipper.Minkowski.cs @@ -1,15 +1,14 @@ /******************************************************************************* * Author : Angus Johnson * -* Date : 15 October 2022 * +* Date : 10 October 2024 * * Website : http://www.angusj.com * -* Copyright : Angus Johnson 2010-2022 * +* Copyright : Angus Johnson 2010-2024 * * Purpose : Minkowski Sum and Difference * * License : http://www.boost.org/LICENSE_1_0.txt * *******************************************************************************/ #nullable enable using System; -using System.Linq; namespace Clipper2Lib { @@ -26,11 +25,13 @@ private static Paths64 MinkowskiInternal(Path64 pattern, Path64 path, bool isSum Path64 path2 = new Path64(patLen); if (isSum) { - path2.AddRange(pattern.Select(basePt => pathPt + basePt)); + foreach (Point64 basePt in pattern) + path2.Add(pathPt + basePt); } else { - path2.AddRange(pattern.Select(basePt => pathPt - basePt)); + foreach (Point64 basePt in pattern) + path2.Add(pathPt - basePt); } tmp.Add(path2); } diff --git a/CSharp/Clipper2Lib/Clipper.Offset.cs b/CSharp/Clipper2Lib/Clipper.Offset.cs index 11d6dc01..8741322a 100644 --- a/CSharp/Clipper2Lib/Clipper.Offset.cs +++ b/CSharp/Clipper2Lib/Clipper.Offset.cs @@ -9,7 +9,6 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; namespace Clipper2Lib @@ -141,12 +140,22 @@ public void AddPaths(Paths64 paths, JoinType joinType, EndType endType) private int CalcSolutionCapacity() { - return _groupList.Sum(g => (g.endType == EndType.Joined) ? g.inPaths.Count * 2 : g.inPaths.Count); + int result = 0; + foreach (Group g in _groupList) + result += (g.endType == EndType.Joined) ? g.inPaths.Count * 2 : g.inPaths.Count; + return result; } internal bool CheckPathsReversed() { - return (from g in _groupList where g.endType == EndType.Polygon select g.pathsReversed).FirstOrDefault(); + bool result = false; + foreach (Group g in _groupList) + if (g.endType == EndType.Polygon) + { + result = g.pathsReversed; + break; + } + return result; } private void ExecuteInternal(double delta) @@ -157,8 +166,9 @@ private void ExecuteInternal(double delta) // make sure the offset delta is significant if (Math.Abs(delta) < 0.5) { - foreach (Path64 path in _groupList.SelectMany(group => group.inPaths)) - _solution.Add(path); + foreach (Group group in _groupList) + foreach (Path64 path in group.inPaths) + _solution.Add(path); return; } @@ -230,9 +240,10 @@ internal static int GetLowestPathIdx(Paths64 paths) Point64 botPt = new Point64(long.MaxValue, long.MinValue); for (int i = 0; i < paths.Count; ++i) { - foreach (Point64 pt in paths[i].Where(pt => (pt.Y >= botPt.Y) && - ((pt.Y != botPt.Y) || (pt.X < botPt.X)))) - { + foreach (Point64 pt in paths[i]) + { + if ((pt.Y < botPt.Y) || + ((pt.Y == botPt.Y) && (pt.X >= botPt.X))) continue; result = i; botPt.X = pt.X; botPt.Y = pt.Y; diff --git a/CSharp/Clipper2Lib/Clipper.RectClip.cs b/CSharp/Clipper2Lib/Clipper.RectClip.cs index ff10c0b1..02e637f1 100644 --- a/CSharp/Clipper2Lib/Clipper.RectClip.cs +++ b/CSharp/Clipper2Lib/Clipper.RectClip.cs @@ -1,6 +1,6 @@ /******************************************************************************* * Author : Angus Johnson * -* Date : 5 July 2024 * +* Date : 10 October 2024 * * Website : http://www.angusj.com * * Copyright : Angus Johnson 2010-2024 * * Purpose : FAST rectangular clipping * @@ -10,7 +10,6 @@ #nullable enable using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; namespace Clipper2Lib @@ -92,8 +91,10 @@ private static bool Path1ContainsPath2(Path64 path1, Path64 path2) // nb: occasionally, due to rounding, path1 may // appear (momentarily) inside or outside path2. int ioCount = 0; - foreach (PointInPolygonResult pip in path2.Select(pt => InternalClipper.PointInPolygon(pt, path1))) + foreach (Point64 pt in path2) { + PointInPolygonResult pip = + InternalClipper.PointInPolygon(pt, path1); switch(pip) { case PointInPolygonResult.IsInside: @@ -636,8 +637,9 @@ private void ExecuteInternal(Path64 path) if (startLocs.Count > 0) { prev = loc; - foreach (Location loc2 in startLocs.Where(loc2 => prev != loc2)) + foreach (Location loc2 in startLocs) { + if (prev == loc2) continue; AddCorner(ref prev, HeadingClockwise(prev, loc2)); prev = loc2; } @@ -652,8 +654,9 @@ public Paths64 Execute(Paths64 paths) { Paths64 result = new Paths64(); if (rect_.IsEmpty()) return result; - foreach (Path64 path in paths.Where(path => path.Count >= 3)) + foreach (Path64 path in paths) { + if (path.Count < 3) continue; pathBounds_ = Clipper.GetBounds(path); if (!rect_.Intersects(pathBounds_)) continue; // the path must be completely outside fRect @@ -668,7 +671,11 @@ public Paths64 Execute(Paths64 paths) for (int i = 0; i < 4; ++i) TidyEdgePair(i, edges_[i * 2], edges_[i * 2 + 1]); - result.AddRange(results_.Select(GetPath).Where(tmp => tmp.Count > 0)); + foreach (OutPt2? op in results_) + { + Path64 tmp = GetPath(op); + if (tmp.Count > 0) result.Add(tmp); + } //clean up after every loop results_.Clear(); @@ -955,8 +962,9 @@ internal RectClipLines64(Rect64 rect) : base(rect) { } { Paths64 result = new Paths64(); if (rect_.IsEmpty()) return result; - foreach (Path64 path in paths.Where(path => path.Count >= 2)) + foreach (Path64 path in paths) { + if (path.Count < 2) continue; pathBounds_ = Clipper.GetBounds(path); if (!rect_.Intersects(pathBounds_)) continue; // the path must be completely outside fRect @@ -965,7 +973,11 @@ internal RectClipLines64(Rect64 rect) : base(rect) { } // fRect, simply by comparing path bounds with fRect. ExecuteInternal(path); - result.AddRange(results_.Select(GetPath).Where(tmp => tmp.Count > 0)); + foreach (OutPt2? op in results_) + { + Path64 tmp = GetPath(op); + if (tmp.Count > 0) result.Add(tmp); + } //clean up after every loop results_.Clear(); diff --git a/CSharp/Clipper2Lib/Clipper.cs b/CSharp/Clipper2Lib/Clipper.cs index b72f4bb1..90efb98f 100644 --- a/CSharp/Clipper2Lib/Clipper.cs +++ b/CSharp/Clipper2Lib/Clipper.cs @@ -1,6 +1,6 @@ /******************************************************************************* * Author : Angus Johnson * -* Date : 10 May 2024 * +* Date : 10 October 2024 * * Website : http://www.angusj.com * * Copyright : Angus Johnson 2010-2024 * * Purpose : This module contains simple functions that will likely cover * @@ -14,7 +14,6 @@ #nullable enable using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; namespace Clipper2Lib @@ -261,7 +260,10 @@ public static double Area(Path64 path) public static double Area(Paths64 paths) { - return paths.Sum(Area); + double a = 0.0; + foreach (Path64 path in paths) + a += Area(path); + return a; } public static double Area(PathD path) @@ -280,7 +282,10 @@ public static double Area(PathD path) public static double Area(PathsD paths) { - return paths.Sum(Area); + double a = 0.0; + foreach (PathD path in paths) + a += Area(path); + return a; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -297,26 +302,37 @@ public static bool IsPositive(PathD poly) public static string Path64ToString(Path64 path) { - string result = path.Aggregate("", (current, pt) => current + pt.ToString()); + string result = ""; + foreach (Point64 pt in path) + result += pt.ToString(); return result + '\n'; } public static string Paths64ToString(Paths64 paths) { - return paths.Aggregate("", (current, path) => current + Path64ToString(path)); + string result = ""; + foreach (Path64 path in paths) + result += Path64ToString(path); + return result; } public static string PathDToString(PathD path) { - string result = path.Aggregate("", (current, pt) => current + pt.ToString()); + string result = ""; + foreach (PointD pt in path) + result += pt.ToString(); return result + '\n'; } public static string PathsDToString(PathsD paths) { - return paths.Aggregate("", (current, path) => current + PathDToString(path)); + string result = ""; + foreach (PathD path in paths) + result += PathDToString(path); + return result; } public static Path64 OffsetPath(Path64 path, long dx, long dy) { Path64 result = new Path64(path.Count); - result.AddRange(path.Select(pt => new Point64(pt.X + dx, pt.Y + dy))); + foreach (Point64 pt in path) + result.Add(new Point64(pt.X + dx, pt.Y + dy)); return result; } @@ -366,11 +382,12 @@ public static Path64 ScalePath(Path64 path, double scale) { if (InternalClipper.IsAlmostZero(scale - 1)) return path; Path64 result = new Path64(path.Count); - result.AddRange(path.Select(pt => new Point64(pt.X * scale, pt.Y * scale))); #if USINGZ foreach (Point64 pt in path) result.Add(new Point64(pt.X * scale, pt.Y * scale, pt.Z)); #else + foreach (Point64 pt in path) + result.Add(new Point64(pt.X * scale, pt.Y * scale)); #endif return result; } @@ -379,7 +396,8 @@ public static Paths64 ScalePaths(Paths64 paths, double scale) { if (InternalClipper.IsAlmostZero(scale - 1)) return paths; Paths64 result = new Paths64(paths.Count); - result.AddRange(paths.Select(path => ScalePath(path, scale))); + foreach (Path64 path in paths) + result.Add(ScalePath(path, scale)); return result; } @@ -387,7 +405,8 @@ public static PathD ScalePath(PathD path, double scale) { if (InternalClipper.IsAlmostZero(scale - 1)) return path; PathD result = new PathD(path.Count); - result.AddRange(path.Select(pt => new PointD(pt, scale))); + foreach (PointD pt in path) + result.Add(new PointD(pt, scale)); return result; } @@ -395,7 +414,8 @@ public static PathsD ScalePaths(PathsD paths, double scale) { if (InternalClipper.IsAlmostZero(scale - 1)) return paths; PathsD result = new PathsD(paths.Count); - result.AddRange(paths.Select(path => ScalePath(path, scale))); + foreach (PathD path in paths) + result.Add(ScalePath(path, scale)); return result; } @@ -404,7 +424,8 @@ public static Path64 ScalePath64(PathD path, double scale) { int cnt = path.Count; Path64 res = new Path64(cnt); - res.AddRange(path.Select(pt => new Point64(pt, scale))); + foreach (PointD pt in path) + res.Add(new Point64(pt, scale)); return res; } @@ -412,7 +433,8 @@ public static Paths64 ScalePaths64(PathsD paths, double scale) { int cnt = paths.Count; Paths64 res = new Paths64(cnt); - res.AddRange(paths.Select(path => ScalePath64(path, scale))); + foreach (PathD path in paths) + res.Add(ScalePath64(path, scale)); return res; } @@ -420,7 +442,8 @@ public static PathD ScalePathD(Path64 path, double scale) { int cnt = path.Count; PathD res = new PathD(cnt); - res.AddRange(path.Select(pt => new PointD(pt, scale))); + foreach (Point64 pt in path) + res.Add(new PointD(pt, scale)); return res; } @@ -428,7 +451,8 @@ public static PathsD ScalePathsD(Paths64 paths, double scale) { int cnt = paths.Count; PathsD res = new PathsD(cnt); - res.AddRange(paths.Select(path => ScalePathD(path, scale))); + foreach (Path64 path in paths) + res.Add(ScalePathD(path, scale)); return res; } @@ -436,56 +460,64 @@ public static PathsD ScalePathsD(Paths64 paths, double scale) public static Path64 Path64(PathD path) { Path64 result = new Path64(path.Count); - result.AddRange(path.Select(pt => new Point64(pt))); + foreach (PointD pt in path) + result.Add(new Point64(pt)); return result; } public static Paths64 Paths64(PathsD paths) { Paths64 result = new Paths64(paths.Count); - result.AddRange(paths.Select(Path64)); + foreach (PathD path in paths) + result.Add(Path64(path)); return result; } public static PathsD PathsD(Paths64 paths) { PathsD result = new PathsD(paths.Count); - result.AddRange(paths.Select(PathD)); + foreach (Path64 path in paths) + result.Add(PathD(path)); return result; } public static PathD PathD(Path64 path) { PathD result = new PathD(path.Count); - result.AddRange(path.Select(pt => new PointD(pt))); + foreach (Point64 pt in path) + result.Add(new PointD(pt)); return result; } public static Path64 TranslatePath(Path64 path, long dx, long dy) { Path64 result = new Path64(path.Count); - result.AddRange(path.Select(pt => new Point64(pt.X + dx, pt.Y + dy))); + foreach (Point64 pt in path) + result.Add(new Point64(pt.X + dx, pt.Y + dy)); return result; } public static Paths64 TranslatePaths(Paths64 paths, long dx, long dy) { Paths64 result = new Paths64(paths.Count); - result.AddRange(paths.Select(path => OffsetPath(path, dx, dy))); + foreach (Path64 path in paths) + result.Add(OffsetPath(path, dx, dy)); return result; } public static PathD TranslatePath(PathD path, double dx, double dy) { PathD result = new PathD(path.Count); - result.AddRange(path.Select(pt => new PointD(pt.x + dx, pt.y + dy))); + foreach (PointD pt in path) + result.Add(new PointD(pt.x + dx, pt.y + dy)); return result; } public static PathsD TranslatePaths(PathsD paths, double dx, double dy) { PathsD result = new PathsD(paths.Count); - result.AddRange(paths.Select(path => TranslatePath(path, dx, dy))); + foreach (PathD path in paths) + result.Add(TranslatePath(path, dx, dy)); return result; } @@ -506,7 +538,8 @@ public static PathD ReversePath(PathD path) public static Paths64 ReversePaths(Paths64 paths) { Paths64 result = new Paths64(paths.Count); - result.AddRange(paths.Select(ReversePath)); + foreach (Path64 t in paths) + result.Add(ReversePath(t)); return result; } @@ -514,7 +547,8 @@ public static Paths64 ReversePaths(Paths64 paths) public static PathsD ReversePaths(PathsD paths) { PathsD result = new PathsD(paths.Count); - result.AddRange(paths.Select(ReversePath)); + foreach (PathD path in paths) + result.Add(ReversePath(path)); return result; } @@ -534,13 +568,14 @@ public static Rect64 GetBounds(Path64 path) public static Rect64 GetBounds(Paths64 paths) { Rect64 result = InvalidRect64; - foreach (Point64 pt in paths.SelectMany(path => path)) - { - if (pt.X < result.left) result.left = pt.X; - if (pt.X > result.right) result.right = pt.X; - if (pt.Y < result.top) result.top = pt.Y; - if (pt.Y > result.bottom) result.bottom = pt.Y; - } + foreach (Path64 path in paths) + foreach (Point64 pt in path) + { + if (pt.X < result.left) result.left = pt.X; + if (pt.X > result.right) result.right = pt.X; + if (pt.Y < result.top) result.top = pt.Y; + if (pt.Y > result.bottom) result.bottom = pt.Y; + } return result.left == long.MaxValue ? new Rect64() : result; } @@ -560,13 +595,14 @@ public static RectD GetBounds(PathD path) public static RectD GetBounds(PathsD paths) { RectD result = InvalidRectD; - foreach (PointD pt in paths.SelectMany(path => path)) - { - if (pt.x < result.left) result.left = pt.x; - if (pt.x > result.right) result.right = pt.x; - if (pt.y < result.top) result.top = pt.y; - if (pt.y > result.bottom) result.bottom = pt.y; - } + foreach (PathD path in paths) + foreach (PointD pt in path) + { + if (pt.x < result.left) result.left = pt.x; + if (pt.x > result.right) result.right = pt.x; + if (pt.y < result.top) result.top = pt.y; + if (pt.y > result.bottom) result.bottom = pt.y; + } return Math.Abs(result.left - double.MaxValue) < InternalClipper.floatingPointTolerance ? new RectD() : result; } @@ -819,7 +855,8 @@ public static Path64 RamerDouglasPeucker(Path64 path, double epsilon) public static Paths64 RamerDouglasPeucker(Paths64 paths, double epsilon) { Paths64 result = new Paths64(paths.Count); - result.AddRange(paths.Select(path => RamerDouglasPeucker(path, epsilon))); + foreach (Path64 path in paths) + result.Add(RamerDouglasPeucker(path, epsilon)); return result; } @@ -867,7 +904,8 @@ public static PathD RamerDouglasPeucker(PathD path, double epsilon) public static PathsD RamerDouglasPeucker(PathsD paths, double epsilon) { PathsD result = new PathsD(paths.Count); - result.AddRange(paths.Select(path => RamerDouglasPeucker(path, epsilon))); + foreach (PathD path in paths) + result.Add(RamerDouglasPeucker(path, epsilon)); return result; } @@ -964,7 +1002,8 @@ public static Paths64 SimplifyPaths(Paths64 paths, double epsilon, bool isClosedPaths = true) { Paths64 result = new Paths64(paths.Count); - result.AddRange(paths.Select(path => SimplifyPath(path, epsilon, isClosedPaths))); + foreach (Path64 path in paths) + result.Add(SimplifyPath(path, epsilon, isClosedPaths)); return result; } @@ -1036,7 +1075,8 @@ public static PathsD SimplifyPaths(PathsD paths, double epsilon, bool isClosedPath = true) { PathsD result = new PathsD(paths.Count); - result.AddRange(paths.Select(path => SimplifyPath(path, epsilon, isClosedPath))); + foreach (PathD path in paths) + result.Add(SimplifyPath(path, epsilon, isClosedPath)); return result; } diff --git a/CSharp/Utils/ClipFileIO/Clipper.FileIO.cs b/CSharp/Utils/ClipFileIO/Clipper.FileIO.cs index 5fef3ad9..f5cdc471 100644 --- a/CSharp/Utils/ClipFileIO/Clipper.FileIO.cs +++ b/CSharp/Utils/ClipFileIO/Clipper.FileIO.cs @@ -9,7 +9,6 @@ using System; using System.IO; using System.Diagnostics; -using System.Linq; namespace Clipper2Lib { @@ -265,7 +264,8 @@ public static Paths64 AffineTranslatePaths(Paths64 paths, long dx, long dy) foreach (Path64 path in paths) { Path64 p = new Path64(path.Count); - p.AddRange(path.Select(pt => new Point64(pt.X + dx, pt.Y + dy))); + foreach (Point64 pt in path) + p.Add(new Point64(pt.X + dx, pt.Y + dy)); result.Add(p); } return result; diff --git a/CSharp/Utils/SVG/Clipper.SVG.cs b/CSharp/Utils/SVG/Clipper.SVG.cs index 188dc2ed..4d101ba2 100644 --- a/CSharp/Utils/SVG/Clipper.SVG.cs +++ b/CSharp/Utils/SVG/Clipper.SVG.cs @@ -10,7 +10,6 @@ using System.Collections.Generic; using System.Globalization; using System.IO; -using System.Linq; namespace Clipper2Lib { @@ -199,13 +198,15 @@ public void AddText(string cap, double posX, double posY, int fontSize, uint fon private RectD GetBounds() { RectD bounds = new RectD(RectMax); - foreach (PointD pt in from pi in PolyInfoList from path in pi.paths from pt in path select pt) - { - if (pt.x < bounds.left) bounds.left = pt.x; - if (pt.x > bounds.right) bounds.right = pt.x; - if (pt.y < bounds.top) bounds.top = pt.y; - if (pt.y > bounds.bottom) bounds.bottom = pt.y; - } + foreach (PolyInfo pi in PolyInfoList) + foreach (PathD path in pi.paths) + foreach (PointD pt in path) + { + if (pt.x < bounds.left) bounds.left = pt.x; + if (pt.x > bounds.right) bounds.right = pt.x; + if (pt.y < bounds.top) bounds.top = pt.y; + if (pt.y > bounds.bottom) bounds.bottom = pt.y; + } return !IsValidRect(bounds) ? RectEmpty : bounds; } @@ -253,16 +254,18 @@ public bool SaveToFile(string filename, int maxWidth = 0, int maxHeight = 0, int foreach (PolyInfo pi in PolyInfoList) { writer.Write(" path.Count >= 2).Where(path => pi.IsOpen || path.Count >= 3)) + foreach (PathD path in pi.paths) { + if (path.Count < 2) continue; + if (!pi.IsOpen && path.Count < 3) continue; writer.Write(string.Format(NumberFormatInfo.InvariantInfo, " M {0:f2} {1:f2}", - (path[0].x * scale + offsetX), - (path[0].y * scale + offsetY))); + (path[0].x * scale + offsetX), + (path[0].y * scale + offsetY))); for (int j = 1; j < path.Count; j++) { writer.Write(string.Format(NumberFormatInfo.InvariantInfo, " L {0:f2} {1:f2}", - (path[j].x * scale + offsetX), - (path[j].y * scale + offsetY))); + (path[j].x * scale + offsetX), + (path[j].y * scale + offsetY))); } if (!pi.IsOpen) writer.Write(" z"); }