private static void AddPadding(RenderGlyph renderGlyph, int padding) { if (padding == 0) { return; } int width = Math.Max(0, renderGlyph.Bitmap.Width + padding * 2); int height = Math.Max(0, renderGlyph.Bitmap.Height + padding * 2); BBitmap result = new BBitmap(width, height); result.Draw(renderGlyph.Bitmap, padding, padding); renderGlyph.Info.XOffset += padding; renderGlyph.Info.YOffset = height; renderGlyph.Bitmap = result; }
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 }); }