Esempio n. 1
0
        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);
        }