/// <summary> /// Loads the glyphs from a font. /// </summary> /// <param name="font">The font.</param> /// <returns>The <see cref="Task" /> that represents the asynchronous operation.</returns> private async Task Load(Font font) { using (font) { var size = (int)Math.Ceiling(font.GetHeight()); var rows = (int)Math.Ceiling(Math.Sqrt(characters.Length)); var columns = (int)Math.Ceiling(characters.Length / (double)rows); using (var drawing = new Drawing(size * columns, size * rows)) { await Task.Run(delegate { drawing.Draw(g => { var format = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center, FormatFlags = StringFormatFlags.MeasureTrailingSpaces, }; g.CompositingMode = CompositingMode.SourceCopy; g.Clear(Color.FromArgb(1, 255, 255, 255)); g.CompositingMode = CompositingMode.SourceOver; g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; for (var i = 0; i < characters.Length; i++) { var row = i / columns; var col = i % columns; g.DrawString(characters[i].ToString(), font, Brushes.White, new RectangleF(col * size, row * size, size, size), format); } var kerningInfo = font.GetKerningInfo(); for (var i = 0; i < this.glyphs.Length; i++) { var kerning = new float[this.characters.Length]; var spacing = Math.Max(1, size * SpacingFactor); for (var c = 0; c < this.characters.Length; c++) { var info = kerningInfo.GetValueOrDefault(this.characters[i]); if (info != null) { kerning[c] = spacing + info.GetValueOrDefault(this.characters[c]); } else { kerning[c] = spacing; } } this.glyphs[i] = new BitmapGlyph(this.Texture, this.characters, kerning); } this.whitespace.Width = Math.Max(8, size * EscapementFactor); this.whitespace.Height = size; }); drawing.Scan(this.glyphs, columns, SpriteScanOptions.ScanHorizontally); }); drawing.CopyTo(this.Texture.Image); } } }