void DrawGlyphContour(GlyphContour cnt, AggCanvasPainter p) { //for debug List <GlyphPart> parts = cnt.parts; int j = parts.Count; for (int i = 0; i < j; ++i) { GlyphPart part = parts[i]; switch (part.Kind) { default: throw new NotSupportedException(); case GlyphPartKind.Line: { GlyphLine line = (GlyphLine)part; p.FillColor = PixelFarm.Drawing.Color.Red; p.FillRectLBWH(line.x0, line.y0, 2, 2); p.FillRectLBWH(line.x1, line.y1, 2, 2); } break; case GlyphPartKind.Curve3: { GlyphCurve3 c = (GlyphCurve3)part; p.FillColor = PixelFarm.Drawing.Color.Red; p.FillRectLBWH(c.x0, c.y0, 2, 2); p.FillColor = PixelFarm.Drawing.Color.Blue; p.FillRectLBWH(c.p2x, c.p2y, 2, 2); p.FillColor = PixelFarm.Drawing.Color.Red; p.FillRectLBWH(c.x, c.y, 2, 2); } break; case GlyphPartKind.Curve4: { GlyphCurve4 c = (GlyphCurve4)part; p.FillColor = PixelFarm.Drawing.Color.Red; p.FillRectLBWH(c.x0, c.y0, 2, 2); p.FillColor = PixelFarm.Drawing.Color.Blue; p.FillRectLBWH(c.p2x, c.p2y, 2, 2); p.FillRectLBWH(c.p3x, c.p3y, 2, 2); p.FillColor = PixelFarm.Drawing.Color.Red; p.FillRectLBWH(c.x, c.y, 2, 2); } break; } } }
static List <GlyphContour> CreateGlyphContours(float[] polygon1, int[] contourEndIndices) { List <GlyphContour> contours = new List <GlyphContour>(); int contourCount = contourEndIndices.Length; int index = 0; for (int c = 0; c < contourCount; ++c) { GlyphContour contour = new GlyphContour(); List <GlyphPointF> list = new List <GlyphPointF>(); contour.flattenPoints = list; int endAt = contourEndIndices[c]; for (; index < endAt;) { list.Add(new GlyphPointF(polygon1[index], polygon1[index + 1], true));//the point is already flatten so=>false index += 2; } //-- //temp hack here! //ensure=> duplicated points, //most common => first point and last point GlyphPointF p0 = list[0]; GlyphPointF lastPoint = list[list.Count - 1]; if (p0.X == lastPoint.X && p0.Y == lastPoint.Y) { list.RemoveAt(list.Count - 1); } //-- contours.Add(contour); } return(contours); }
public static Poly2Tri.Polygon Triangulate(float[] polygon1, int[] contourEndIndices) { //create List <GlyphContour> flattenContours = CreateGlyphContours(polygon1, contourEndIndices); //-------------------------- //TODO: review here, add hole or not // more than 1 contours, no hole => eg. i, j, ;, etc // more than 1 contours, with hole => eg. a,e , etc //clockwise => not hole _waitingHoles.Clear(); int cntCount = flattenContours.Count; Poly2Tri.Polygon mainPolygon = null; // //this version if it is a hole=> we add it to main polygon //TODO: add to more proper polygon *** //eg i //-------------------------- List <Poly2Tri.Polygon> otherPolygons = null; for (int n = 0; n < cntCount; ++n) { GlyphContour cnt = flattenContours[n]; if (cnt.IsClockwise()) { //not a hole if (mainPolygon == null) { //if we don't have mainPolygon before //this is main polygon mainPolygon = CreatePolygon(cnt.flattenPoints); if (_waitingHoles.Count > 0) { //flush all waiting holes to the main polygon int j = _waitingHoles.Count; for (int i = 0; i < j; ++i) { mainPolygon.AddHole(_waitingHoles[i]); } _waitingHoles.Clear(); } } else { //if we already have a main polygon //then this is another sub polygon //IsHole is correct after we Analyze() the glyph contour Poly2Tri.Polygon subPolygon = CreatePolygon(cnt.flattenPoints); if (otherPolygons == null) { otherPolygons = new List <Poly2Tri.Polygon>(); } otherPolygons.Add(subPolygon); } } else { //this is a hole Poly2Tri.Polygon subPolygon = CreatePolygon(cnt.flattenPoints); if (mainPolygon == null) { //add to waiting polygon _waitingHoles.Add(subPolygon); } else { //add to mainPolygon mainPolygon.AddHole(subPolygon); } } } if (_waitingHoles.Count > 0) { throw new NotSupportedException(); } //------------------------------------------ //2. tri angulate Poly2Tri.P2T.Triangulate(mainPolygon); //that poly is triangulated Poly2Tri.Polygon[] subPolygons = (otherPolygons != null) ? otherPolygons.ToArray() : null; if (subPolygons != null) { for (int i = subPolygons.Length - 1; i >= 0; --i) { Poly2Tri.P2T.Triangulate(subPolygons[i]); } } if (mainPolygon == null) { } return(mainPolygon); }