Ejemplo n.º 1
0
        public static Shape LoadGlyph(Face face, int unicode)
        {
            if (face == null)
            {
                throw new ArgumentNullException(nameof(face));
            }

            face.LoadChar((uint)unicode, LoadFlags.NoScale, LoadTarget.Normal);

            Shape output = new Shape();

            Context context = new Context {
                shape = output
            };

            OutlineFuncs funcs = new OutlineFuncs();

            funcs.MoveFunction  = MoveTo;
            funcs.LineFunction  = LineTo;
            funcs.ConicFunction = ConicTo;
            funcs.CubicFunction = CubicTo;
            unsafe
            {
                face.Glyph.Outline.Decompose(funcs, (IntPtr)Unsafe.AsPointer(ref context));
            }
            return(output);
        }
Ejemplo n.º 2
0
        public static Shape LoadGlyph(Face font, uint unicode, ref double advance)
        {
            var result = new Shape();

            font.LoadChar(unicode, LoadFlags.NoScale, LoadTarget.Normal);
            result.InverseYAxis = false;
            advance             = font.Glyph.Advance.X.Value / 64.0;
            var context     = new FtContext(result);
            var ftFunctions = new OutlineFuncs
            {
                MoveFunction  = context.FtMoveTo,
                LineFunction  = context.FtLineTo,
                ConicFunction = context.FtConicTo,
                CubicFunction = context.FtCubicTo,
                Shift         = 0
            };

            font.Glyph.Outline.Decompose(ftFunctions, IntPtr.Zero);
            return(result);
        }
Ejemplo n.º 3
0
        public static void CreateFromString([NotNull] Font font, [CanBeNull] string str, [NotNull] GeometrySink sink)
        {
            if (string.IsNullOrEmpty(str))
            {
                return;
            }

            Guard.ArgumentNotNull(font, nameof(font));

            var       fontFace = font.FontFace;
            const int noError  = 0;
            const int factorX  = 1 << 10;
            const int factorY  = -factorX;

            var currentOrigin = Vector2.Zero;
            var outlineFuncs  = new OutlineFuncs(MoveTo, LineTo, QuadraticBezierTo, CubicBezierTo, factorX, 0);

            foreach (var ch in str)
            {
                if (ch == '\r')
                {
                    continue;
                }

                if (ch == ' ')
                {
                    // TODO: hack!
                    currentOrigin.X += FontHelper.PointsToPixels(font.Size) / 2;
                    continue;
                }

                if (ch == '\n')
                {
                    currentOrigin.Y += FontHelper.PointsToPixels(font.Size);

                    continue;
                }

                var glyphIndex = fontFace.GetCharIndex(ch);
                fontFace.LoadGlyph(glyphIndex, LoadFlags.Render, LoadTarget.Normal);

                var outline = fontFace.Glyph.Outline;

                sink.BeginFigure(currentOrigin);
                outline.Decompose(outlineFuncs, IntPtr.Zero);
                sink.EndFigure(FigureEnd.Closed);

                var metrics  = fontFace.Glyph.Metrics;
                var charSize = fontFace.GetCharSize(glyphIndex, metrics, null, 1, 1);
                currentOrigin.X += charSize.X;
            }

            int MoveTo(ref FTVector p2, IntPtr user)
            {
                sink.EndFigure(FigureEnd.Closed);

                sink.BeginFigure(currentOrigin + new Vector2(factorX * p2.X.ToSingle(), factorY * p2.Y.ToSingle()));

                return(noError);
            }

            int LineTo(ref FTVector p2, IntPtr user)
            {
                sink.AddLine(currentOrigin + new Vector2(factorX * p2.X.ToSingle(), factorY * p2.Y.ToSingle()));

                return(noError);
            }

            int QuadraticBezierTo(ref FTVector cp, ref FTVector p2, IntPtr user)
            {
                var bezier = new QuadraticBezierSegment {
                    Point1 = currentOrigin + new Vector2(factorX * cp.X.ToSingle(), factorY * cp.Y.ToSingle()),
                    Point2 = currentOrigin + new Vector2(factorX * p2.X.ToSingle(), factorY * p2.Y.ToSingle())
                };

                sink.AddQuadraticBezier(bezier);

                return(noError);
            }

            int CubicBezierTo(ref FTVector cp1, ref FTVector cp2, ref FTVector p2, IntPtr user)
            {
                var bezier = new BezierSegment {
                    Point1 = currentOrigin + new Vector2(factorX * cp1.X.ToSingle(), factorY * cp1.Y.ToSingle()),
                    Point2 = currentOrigin + new Vector2(factorX * cp2.X.ToSingle(), factorY * cp2.Y.ToSingle()),
                    Point3 = currentOrigin + new Vector2(factorX * p2.X.ToSingle(), factorY * p2.Y.ToSingle())
                };

                sink.AddBezier(bezier);

                return(noError);
            }
        }