Exemplo n.º 1
0
 protected override void OnCurveToQuadratic(float x1, float y1, float x, float y, bool isRelative)
 {
     if (isRelative)
     {
         _writer.Curve3Rel(x1, y1, x, y);
     }
     else
     {
         _writer.Curve3(x1, y1, x, y);
     }
 }
Exemplo n.º 2
0
        FontGlyph CreateGlyphFromSVGGlyphData(string svgGlyphData)
        {
            FontGlyph newGlyph = new FontGlyph();

            if (!GetIntValue(svgGlyphData, "horiz-adv-x", out newGlyph.horiz_adv_x))
            {
                newGlyph.horiz_adv_x = horiz_adv_x;
            }

            newGlyph.glyphName = GetStringValue(svgGlyphData, "glyph-name");
            String unicodeString = GetStringValue(svgGlyphData, "unicode");

            if (unicodeString != null)
            {
                if (unicodeString.Length == 1)
                {
                    newGlyph.unicode = (int)unicodeString[0];
                }
                else
                {
                    if (unicodeString.Split(';').Length > 1 && unicodeString.Split(';')[1].Length > 0)
                    {
                        throw new NotImplementedException("We do not currently support glyphs longer than one character.  You need to wirite the seach so that it will find them if you want to support this");
                    }

                    if (int.TryParse(unicodeString, NumberStyles.Number, null, out newGlyph.unicode) == false)
                    {
                        // see if it is a unicode
                        String hexNumber = GetSubString(unicodeString, "&#x", ";");
                        int.TryParse(hexNumber, NumberStyles.HexNumber, null, out newGlyph.unicode);
                    }
                }
            }

            String dString = GetStringValue(svgGlyphData, "d");

            int        parseIndex = 0;
            int        polyStartVertexSourceIndex = 0;
            Vector2    lastXY   = new Vector2(0, 0);
            double     px       = 0;
            double     py       = 0;
            PathWriter gyphPath = new PathWriter();

            newGlyph.originalVxs = gyphPath.Vxs;
            if (dString == null || dString.Length == 0)
            {
                return(newGlyph);
            }

            while (parseIndex < dString.Length)
            {
                char command = dString[parseIndex];
                switch (command)
                {
                case 'M':
                {
                    parseIndex++;
                    // svg fonts are stored cw and agg expects its shapes to be ccw.  cw shapes are holes.
                    // so we store the position of the start of this polygon so we can flip it when we colse it.
                    polyStartVertexSourceIndex = gyphPath.Count;
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.MoveTo(px, py);
                }
                break;

                case 'v':
                {
                    parseIndex++;
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.VerticalLineToRel(py);
                }
                break;

                case 'V':
                {
                    parseIndex++;
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.VerticalLineTo(py);
                }
                break;

                case 'h':
                {
                    parseIndex++;
                    px = GetNextNumber(dString, ref parseIndex);
                    gyphPath.HorizontalLineToRel(px);
                }
                break;

                case 'H':
                {
                    parseIndex++;
                    px = GetNextNumber(dString, ref parseIndex);
                    gyphPath.HorizontalLineTo(px);
                }
                break;

                case 'l':
                {
                    parseIndex++;
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.LineToRel(px, py);
                }
                break;

                case 'L':
                {
                    parseIndex++;
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.LineTo(px, py);
                }
                break;

                case 'q':
                {
                    //Curve3
                    parseIndex++;
                    double p2x = GetNextNumber(dString, ref parseIndex);
                    double p2y = GetNextNumber(dString, ref parseIndex);
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.Curve3Rel(p2x, p2y, px, py);
                }
                break;

                case 'Q':
                {           //Curve3
                    parseIndex++;
                    double p2x = GetNextNumber(dString, ref parseIndex);
                    double p2y = GetNextNumber(dString, ref parseIndex);
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.Curve3(p2x, p2y, px, py);
                }
                break;

                case 't':
                {
                    //svg smooth curve3
                    parseIndex++;
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.SmoothCurve3Rel(px, py);
                }
                break;

                case 'T':
                {
                    parseIndex++;
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.SmoothCurve3(px, py);
                }
                break;

                case 'z':
                case 'Z':
                {
                    parseIndex++;
                    //curXY = lastXY; // value not used this is to remove an error.
                    //newGlyph.glyphData.ClosePathStorage();
                    gyphPath.CloseFigure();
                    // svg fonts are stored cw and agg expects its shapes to be ccw.  cw shapes are holes.
                    // We stored the position of the start of this polygon, no we flip it as we close it.
                    //newGlyph.glyphData.InvertPolygon(polyStartVertexSourceIndex);
                    // VertexHelper.InvertPolygon(gyphPath.Vxs, polyStartVertexSourceIndex);
                }
                break;

                case ' ':
                case '\n':     // some white space we need to skip
                case '\r':
                {
                    parseIndex++;
                }
                break;

                default:
                    throw new NotImplementedException("unrecognized d command '" + command + "'.");
                }
            }

            return(newGlyph);
        }