Пример #1
0
        public static BFont FromFile(string path, BFontOptions options)
        {
            using (Face face = new Face(library, path))
            {
                return(FromFace(face, options, renderGlyph =>
                {
                    int padding = options.Padding + options.DistanceField;

                    AddPadding(renderGlyph, padding);

                    GenerateSignedDistanceField(renderGlyph, options.DistanceField);
                }));
            }
        }
Пример #2
0
        private static BFont FromFace(Face face, BFontOptions options, Action <RenderGlyph> action = null)
        {
            char[]             singleCharacters = options.Characters.GroupBy(c => c).Select(g => g.First()).Where(c => !char.IsControl(c)).ToArray();
            List <RenderGlyph> renderGlyphs     = new List <RenderGlyph>();

            face.SetCharSize(0, options.Size, 72, 72);

            foreach (var character in singleCharacters)
            {
                face.LoadGlyph(face.GetCharIndex(character), LoadFlags.Default, options.DistanceField > 0 ? LoadTarget.Mono : LoadTarget.Normal);
                face.Glyph.RenderGlyph(options.DistanceField > 0 ? RenderMode.Mono : RenderMode.Normal);

                BBitmap glyphBitmap = face.Glyph.Metrics.Height != 0 ? BBitmap.FromFTBitmap(face.Glyph.Bitmap) : new BBitmap((int)face.Glyph.Advance.X, 0);

                renderGlyphs.Add(new RenderGlyph
                {
                    Bitmap = glyphBitmap,
                    Info   = new BGlyph
                    {
                        Character = character,
                        XOffset   = face.Glyph.BitmapLeft,
                        YOffset   = face.Glyph.BitmapTop,
                        Width     = (int)face.Glyph.Metrics.Width,
                        Height    = (int)face.Glyph.Metrics.Height,
                        XAdvance  = (int)face.Glyph.Advance.X,
                        YAdvance  = (int)face.Glyph.Advance.Y
                    }
                });
            }

            renderGlyphs = renderGlyphs.OrderByDescending(g => g.Info.Height)
                           .ThenBy(g => g.Info.Character).ToList();

            List <BBitmap> pages     = new List <BBitmap>();
            List <BGlyph>  glyphs    = new List <BGlyph>();
            Point          cursor    = new Point(0, 0);
            int            maxHeight = 0;

            BBitmap page;

            void CreateNewPage()
            {
                page = new BBitmap(options.PageSize, options.PageSize);

                pages.Add(page);
            }

            CreateNewPage();

            foreach (var renderGlyph in renderGlyphs)
            {
                action?.Invoke(renderGlyph);

                if (cursor.X + renderGlyph.Bitmap.Width > options.PageSize)
                {
                    cursor.X  = 0;
                    cursor.Y += maxHeight;
                    maxHeight = 0;

                    if (cursor.Y + renderGlyph.Bitmap.Height > options.PageSize)
                    {
                        cursor.Y = 0;
                        CreateNewPage();
                    }
                }

                renderGlyph.Info.Page = pages.Count - 1;
                renderGlyph.Info.X    = cursor.X;
                renderGlyph.Info.Y    = cursor.Y;

                glyphs.Add(renderGlyph.Info);

                page.Draw(renderGlyph.Bitmap, cursor.X, cursor.Y);

                maxHeight = Math.Max(maxHeight, renderGlyph.Bitmap.Height);
                cursor.X += renderGlyph.Bitmap.Width;
            }

            return(new BFont
            {
                Glyphs = glyphs.ToArray(),
                LineHeight = face.Height,
                Pages = pages.ToArray(),
                Name = face.FamilyName
            });
        }