예제 #1
0
 private static Vector2 ToVector2(this ContourPoint p, float scale)
 {
     return(new Vector2(p.X * scale, p.Y * scale));
 }
예제 #2
0
        private static GlyphContourInfoV2 FromTtfGlyph(GlyphContourInfo g, FontModel model, FontSource source)
        {
            var advancedWidth   = g.BaseInfo.AdvancedWidth * model.BaseScale;
            var leftSideBearing = g.BaseInfo.LeftSideBearing * model.BaseScale;

            if (g.Header.NumberOfContours > 0)
            {
                var con = new List <List <ContourPoint> >();

                var points = g.Header.GetGlyphPoints(source);
                if (points == null || points.Length == 0)
                {
                    throw new FontException("Cannot get points");
                }

                var list = new List <ContourPoint>();
                con.Add(list);
                for (var i = 0; i < points.Length; i++)
                {
                    var point        = points[i];
                    var contourPoint = new ContourPoint(point.X, point.Y, point.OnCurve);
                    list.Add(contourPoint);

                    if (point.IsEndPoint && i != points.Length - 1)
                    {
                        list = new List <ContourPoint>();
                        con.Add(list);
                    }
                }

                return(new GlyphContourInfoV2(advancedWidth, leftSideBearing, ContourToVector(con, model.BaseScale, true)));
            }
            else
            {
                // Composite Glyph
                var components = g.Header.GetGlyphComponents(source);

                var con = new List <List <ContourPoint> >();

                foreach (var component in components)
                {
                    var cg = model.GetGlyphFromGid(component.GlyphId, source);
                    if (cg.Header.NumberOfContours > 0)
                    {
                        var points = cg.Header.GetGlyphPoints(source);
                        if (points == null || points.Length == 0)
                        {
                            throw new FontException("Cannot get points");
                        }

                        if (component.MatchedPoints == null)
                        {
                            GlyphTable.GlyphHeader.GlyphComponent.TransformPoints(points, component);
                        }
                        else
                        {
                            // MatchedPoints are not supported.
                            break;
                        }

                        var list = new List <ContourPoint>();
                        con.Add(list);
                        for (var i = 0; i < points.Length; i++)
                        {
                            var point = points[i];

                            var contourPoint = new ContourPoint(point.X, point.Y, point.OnCurve);
                            list.Add(contourPoint);

                            if (point.IsEndPoint && i != points.Length - 1)
                            {
                                list = new List <ContourPoint>();
                                con.Add(list);
                            }
                        }
                    }
                }
                return(new GlyphContourInfoV2(advancedWidth, leftSideBearing, ContourToVector(con, model.BaseScale, true)));
            }
        }
예제 #3
0
 private static Vector2 ToVector2(this ContourPoint p)
 {
     return(new Vector2(p.X, p.Y));
 }
예제 #4
0
        private static Vector2[] ContourToVector(IReadOnlyList <ContourPoint> contour, float baseScale, bool splitContour)
        {
            if (!contour[0].OnCurve)
            {
                var c2 = new List <ContourPoint>(contour.Count + 1);
                var c0 = new ContourPoint(
                    (short)((contour[0].X + contour[contour.Count - 1].X) / 2),
                    (short)((contour[0].Y + contour[contour.Count - 1].Y) / 2), true);
                c2.Add(c0);
                c2.AddRange(contour);
                contour = c2;
            }

            var points  = new List <Vector2>();
            var segment = new List <Vector2> {
                contour[0].ToVector2(baseScale)
            };

            for (var i = 1; i < contour.Count; i++)
            {
                var p = contour[i];
                var v = p.ToVector2(baseScale);
                if (p.OnCurve)
                {
                    if (segment.Count == 0)
                    {
                        segment.Add(v);
                    }
                    else
                    {
                        segment.Add(v);

                        AddBezierCurve(segment, points);

                        if (i == contour.Count - 1)
                        {
                            points.Add(v);
                        }
                        else
                        {
                            segment.Clear();
                            segment.Add(v);
                        }
                    }
                }
                else
                {
                    if (segment.Count == 2)
                    {
                        if (splitContour)
                        {
                            var mp = new Vector2((segment[1].x + v.x) * 0.5f, (segment[1].y + v.y) * 0.5f);
                            segment.Add(mp);

                            AddBezierCurve(segment, points);

                            segment.Clear();
                            segment.Add(mp);
                            segment.Add(v);
                        }
                        else
                        {
                            segment.Add(v);
                        }
                    }
                    else if (segment.Count == 1)
                    {
                        segment.Add(v);
                    }
                    else
                    {
                        throw new FontException("Font parse error.");
                    }

                    if (i == contour.Count - 1)
                    {
                        segment.Add(contour[0].ToVector2(baseScale));

                        AddBezierCurve(segment, points);
                    }
                }
            }
            return(points.ToArray());
        }