// Combine all of the given geometries into a single geometry. static CanvasGeometry CombineGeometries( TranslationContext context, CanvasGeometry[] geometries, MergePaths.MergeMode mergeMode) { switch (geometries.Length) { case 0: return(null); case 1: return(geometries[0]); } // If MergeMode.Merge and they're all paths with the same FilledRegionDetermination, // combine into a single path. if (mergeMode == MergePaths.MergeMode.Merge && geometries.All(g => g.Type == CanvasGeometry.GeometryType.Path) && geometries.Select(g => ((CanvasGeometry.Path)g).FilledRegionDetermination).Distinct().Count() == 1) { return(Paths.MergePaths(geometries.Cast <CanvasGeometry.Path>().ToArray())); } else { if (geometries.Length > 50) { // There will be stack overflows if the CanvasGeometry.Combine is too large. // Usually not a problem, but handle degenerate cases. context.Issues.MergingALargeNumberOfShapesIsNotSupported(); geometries = geometries.Take(50).ToArray(); } var combineMode = ConvertTo.GeometryCombine(mergeMode); #if PreCombineGeometries return(CanvasGeometryCombiner.CombineGeometries(geometries, combineMode)); #else var accumulator = geometries[0]; for (var i = 1; i < geometries.Length; i++) { accumulator = accumulator.CombineWith(geometries[i], Sn.Matrix3x2.Identity, combineMode); } return(accumulator); #endif } }
public static CanvasGeometryCombine GeometryCombine(MergePaths.MergeMode mergeMode) { switch (mergeMode) { case MergePaths.MergeMode.Add: return(CanvasGeometryCombine.Union); case MergePaths.MergeMode.Subtract: return(CanvasGeometryCombine.Exclude); case MergePaths.MergeMode.Intersect: return(CanvasGeometryCombine.Intersect); // TODO - find out what merge should be - maybe should be a Union. case MergePaths.MergeMode.Merge: case MergePaths.MergeMode.ExcludeIntersections: return(CanvasGeometryCombine.Xor); default: throw new InvalidOperationException(); } }
static CanvasGeometry MergeShapeLayerContent(ShapeContext context, Stack <ShapeLayerContent> stack, MergePaths.MergeMode mergeMode) { var pathFillType = context.Fill is null ? ShapeFill.PathFillType.EvenOdd : context.Fill.FillType; var geometries = CreateCanvasGeometries(context, stack, pathFillType).ToArray(); switch (geometries.Length) { case 0: return(null); case 1: return(geometries[0]); default: return(CombineGeometries(context, geometries, mergeMode)); } }
// Merge the stack into a single shape. Merging is done recursively - the top geometry on the // stack is merged with the merge of the remainder of the stack. static CompositionShape TranslateMergePathsContent(ShapeContext context, Stack <ShapeLayerContent> stack, MergePaths.MergeMode mergeMode) { var mergedGeometry = MergeShapeLayerContent(context, stack, mergeMode); if (mergedGeometry != null) { var result = context.ObjectFactory.CreateSpriteShape(); result.Geometry = context.ObjectFactory.CreatePathGeometry(new CompositionPath(mergedGeometry)); TranslateAndApplyShapeContext( context, result, reverseDirection: false, trimOffsetDegrees: 0); return(result); } else { return(null); } }
static CanvasGeometry?MergeShapeLayerContent(ShapeContext context, Stack <ShapeLayerContent> stack, MergePaths.MergeMode mergeMode) { var pathFillType = context.Fill is null ? ShapeFill.PathFillType.EvenOdd : context.Fill.FillType; var geometries = CreateCanvasGeometries(context, stack, pathFillType).ToArray(); return(geometries.Length switch { 0 => null, 1 => geometries[0], _ => CombineGeometries(context, geometries, mergeMode), });