private void ExtractPath(Shape shape, int from, int to) { double factor = 2000.0; var winding = 0.0; int length = to - from; Point pa, pb; int a, b; var path = new Path(); int i = 0; while (i <= length) { a = i; int j = i + 1; while (j <= length && (Flags[from + j] & GlyphFlag.OnCurve) != GlyphFlag.OnCurve) j++; b = (j) % (length + 1); int padding = j - i; pa = new Point(Points[from + a].X / factor, Points[from + a].Y / factor); pb = new Point(Points[from + b].X / factor, Points[from + b].Y / factor); if(padding > 3) { //TODO var pc = new Point(Points[from + a + 1].X / factor, Points[from + a + 1].Y / factor); path.AddPathSegment(new QuadraticCurveSegment(pa, pc, pb) { Convex = true }); } else if(padding == 3) { //TODO var pc = new Point(Points[from + a + 1].X / factor, Points[from + a + 1].Y / factor); path.AddPathSegment(new QuadraticCurveSegment(pa, pc, pb) { Convex = true }); } else if(padding == 2) { var pc = new Point(Points[from + a + 1].X / factor, Points[from + a + 1].Y / factor); path.AddPathSegment(new QuadraticCurveSegment(pa, pc, pb) { Convex = true }); } else { path.AddPathSegment(new LineSegment(pa, pb)); } winding += (pb.X - pa.X) * (pb.Y + pa.Y); i = j; } if (winding >= 0.0) path.CompositMode = CompositMode.Add; else path.CompositMode = CompositMode.Subtract; foreach(var segment in path.Segments) { if(segment is QuadraticCurveSegment) { var qcs = segment as QuadraticCurveSegment; var sign = Math.Sign(((qcs.End.X - qcs.Start.X) * (qcs.ControlPoint.Y - qcs.Start.Y)) - ((qcs.End.Y - qcs.Start.Y) * (qcs.ControlPoint.X - qcs.Start.X))); if(path.CompositMode == CompositMode.Subtract) qcs.Convex = sign >= 0.0 ? false : true; else qcs.Convex = sign >= 0.0 ? true : false; } } shape.AddPath(path); }
public void AddPath(Path path) { paths.Add(path); }
public void RemovePath(Path path) { paths.Remove(path); }
private static void AddPathToBuffers(Path path, BufferGenerator vertexBufferGenerator, BufferGenerator indexBufferGenerator, ref int indexCount) { List<PolygonPoint> points = new List<PolygonPoint>(); float r; float g; float b; if (path.CompositMode == CompositMode.Subtract) { r = 1f; g = 0f; b = 0f; } else { r = 1f; g = 1f; b = 1f; } foreach (var segment in path.Segments) { if (segment is QuadraticCurveSegment) { var quadraticCurveSegment = segment as QuadraticCurveSegment; AddQuadraticCurveSegment(quadraticCurveSegment, points, vertexBufferGenerator, indexBufferGenerator, ref indexCount, r, g, b); } else if(segment is LineSegment) { var lineSegment = segment as LineSegment; points.Add(new PolygonPoint(lineSegment.End.X, lineSegment.End.Y)); var ext = 0.01; var normal = path.CompositMode == CompositMode.Subtract ? lineSegment.RightNormal : lineSegment.LeftNormal; var p1 = (normal * ext) + lineSegment.Start; var p2 = (normal * ext) + lineSegment.End; AddVertex(vertexBufferGenerator, (float)lineSegment.Start.X, (float)lineSegment.Start.Y, 0f, 1f, r, g, b, 1f); AddVertex(vertexBufferGenerator, (float)lineSegment.End.X, (float)lineSegment.End.Y, 0f, 1f, r, g, b, 1f); AddVertex(vertexBufferGenerator, (float)p1.X, (float)p1.Y, 1f, 1f, r, g, b, 1f); indexBufferGenerator.WriteUInt((uint)indexCount++, (uint)indexCount++, (uint)indexCount++); AddVertex(vertexBufferGenerator, (float)lineSegment.Start.X, (float)lineSegment.Start.Y, 0f, 1f, r, g, b, 1f); AddVertex(vertexBufferGenerator, (float)p1.X, (float)p1.Y, 0f, 0f, r, g, b, 1f); AddVertex(vertexBufferGenerator, (float)p2.X, (float)p2.Y, 1f, 1f, r, g, b, 1f); indexBufferGenerator.WriteUInt((uint)indexCount++, (uint)indexCount++, (uint)indexCount++); } else { throw new NotImplementedException(); } } Polygon polygon; try { polygon = new Polygon(points); P2T.Triangulate(polygon); } catch(Exception e) { System.Diagnostics.Debug.WriteLine(e.Message); return; } foreach (var triangle in polygon.Triangles) { AddVertex(vertexBufferGenerator, (float)triangle.Points[0].X, (float)triangle.Points[0].Y, 0f, 1f, r, g, b, 1f); AddVertex(vertexBufferGenerator, (float)triangle.Points[1].X, (float)triangle.Points[1].Y, 0f, 1f, r, g, b, 1f); AddVertex(vertexBufferGenerator, (float)triangle.Points[2].X, (float)triangle.Points[2].Y, 0f, 1f, r, g, b, 1f); indexBufferGenerator.WriteUInt((uint)indexCount++, (uint)indexCount++, (uint)indexCount++); } }