public override ICanvasImage GetRender(ICanvasResourceCreator resourceCreator, IList <Layerage> children) { Transformer transformer = base.Transform.Transformer; CanvasGeometry geometry = transformer.ToRectangle(resourceCreator); CanvasCommandList command = new CanvasCommandList(resourceCreator); using (CanvasDrawingSession drawingSession = command.CreateDrawingSession()) { if (this.Transform.IsCrop) { CanvasGeometry geometryCrop = this.Transform.CropTransformer.ToRectangle(resourceCreator); CanvasGeometryRelation relation = geometry.CompareWith(geometryCrop); switch (relation) { case CanvasGeometryRelation.Disjoint: return(null); case CanvasGeometryRelation.Contained: this._patternRender(resourceCreator, drawingSession, geometry); break; case CanvasGeometryRelation.Contains: this._patternRender(resourceCreator, drawingSession, geometryCrop); break; case CanvasGeometryRelation.Overlap: Matrix3x2 zero = Matrix3x2.CreateTranslation(0.0f, 0.0f); CanvasGeometry combine = geometry.CombineWith(geometryCrop, zero, CanvasGeometryCombine.Intersect); this._patternRender(resourceCreator, drawingSession, combine); break; default: return(null); } } else { this._patternRender(resourceCreator, drawingSession, geometry); } } return(command); }
List <Rect> SplitGeometryIntoRectangles(CanvasGeometry geometry, float rectangleHeight, CanvasControl sender) { List <Rect> result = new List <Rect>(); var geometryBounds = geometry.ComputeBounds(); double left = geometryBounds.X; double top = geometryBounds.Y; double y = top; while (y < geometryBounds.Bottom) { var lineRegion = new Rect(left, y, geometryBounds.Width, rectangleHeight); var lineRegionGeometry = CanvasGeometry.CreateRectangle(sender, lineRegion); var compareResult = geometry.CompareWith(lineRegionGeometry); if (compareResult == CanvasGeometryRelation.Contains) { // The whole line fits. result.Add(lineRegion); } else if (compareResult == CanvasGeometryRelation.Disjoint) { // The line doesn't fit, so skip it. } else if (compareResult == CanvasGeometryRelation.Overlap) { var intersection = geometry.CombineWith(lineRegionGeometry, Matrix3x2.Identity, CanvasGeometryCombine.Intersect); PathReader pathReader = new PathReader(lineRegion); intersection.Simplify(CanvasGeometrySimplification.Lines).SendPathTo(pathReader); var rectangles = pathReader.GetRectangles(); rectangles.Sort(new RectangleComparer(CurrentTextDirection == TextDirection.RightToLeft)); result.AddRange(rectangles); } y += rectangleHeight; } return(result); }
public static bool HasOverlaps(IEnumerable <Data.Path> paths, IEnumerable <Data.Path> otherPaths = null) { if (otherPaths != null) { using CanvasGeometry geom1 = MakeGeometry(paths), geom2 = MakeGeometry(otherPaths); return(geom1.CompareWith(geom2) != CanvasGeometryRelation.Disjoint); } else { var pathsList = paths.ToList(); for (int ix = 0; ix < pathsList.Count; ++ix) { var path = new[] { pathsList[ix] }; using var geom = MakeGeometry(path); // Check for self-intersections using (var evenOddGeom = MakeGeometry(path, CanvasFilledRegionDetermination.Alternate)) { var selfIntersectingGeom = geom.CombineWith( evenOddGeom, Matrix3x2.Identity, CanvasGeometryCombine.Exclude, float.Epsilon); if (Math.Abs(selfIntersectingGeom.ComputeArea()) > float.Epsilon) { return(true); } } // Check for overlaps with remaining paths if (ix < pathsList.Count - 1) { using var other = MakeGeometry(pathsList.GetRange(ix + 1, pathsList.Count - (ix + 1))); if (geom.CompareWith(other, Matrix3x2.Identity, float.Epsilon) != CanvasGeometryRelation.Disjoint) { return(true); } } } return(false); } }