public void Add(byte[] ttf, float fontPixelHeight, IEnumerable <CharacterRange> characterRanges) { if (ttf == null || ttf.Length == 0) { throw new ArgumentNullException(nameof(ttf)); } if (fontPixelHeight <= 0) { throw new ArgumentOutOfRangeException(nameof(fontPixelHeight)); } if (characterRanges == null) { throw new ArgumentNullException(nameof(characterRanges)); } if (!characterRanges.Any()) { throw new ArgumentException("characterRanges must have a least one value."); } var fontInfo = new FontInfo(); if (fontInfo.stbtt_InitFont(ttf, 0) == 0) { throw new Exception("Failed to init font."); } var scaleFactor = fontInfo.stbtt_ScaleForPixelHeight(fontPixelHeight); int ascent, descent, lineGap; fontInfo.stbtt_GetFontVMetrics(out ascent, out descent, out lineGap); foreach (var range in characterRanges) { if (range.Start > range.End) { continue; } var cd = new stbtt_packedchar[range.End - range.Start + 1]; for (var i = 0; i < cd.Length; ++i) { cd[i] = new stbtt_packedchar(); } _context.stbtt_PackFontRange(ttf, 0, fontPixelHeight, range.Start, range.End - range.Start + 1, cd); for (var i = 0; i < cd.Length; ++i) { var yOff = cd[i].yoff; yOff += ascent * scaleFactor; var glyphInfo = new GlyphInfo { X = cd[i].x0, Y = cd[i].y0, Width = cd[i].x1 - cd[i].x0, Height = cd[i].y1 - cd[i].y0, XOffset = (int)cd[i].xoff, YOffset = (int)Math.Round(yOff), XAdvance = (int)Math.Round(cd[i].xadvance) }; _glyphs[i + range.Start] = glyphInfo; } } }
public void Add( ReadOnlyMemory <byte> fontData, int fontIndex, float pixelHeight, ReadOnlySpan <CharacterRange> ranges) { if (fontData.IsEmpty) { throw new ArgumentException(nameof(fontData)); } if (pixelHeight <= 0) { throw new ArgumentOutOfRangeException(nameof(pixelHeight)); } if (ranges.IsEmpty) { throw new ArgumentException(); } var fontInfo = new TrueType.FontInfo(); if (!TrueType.InitFont(fontInfo, fontData, fontIndex)) { throw new Exception("Failed to init font."); } var scale = TrueType.ScaleForPixelHeight(fontInfo, pixelHeight); TrueType.GetFontVMetrics(fontInfo, out int ascent, out _, out _); foreach (var range in ranges) { if (range.Start > range.End) { continue; } var charData = new TrueType.PackedChar[range.Size]; TrueType.PackFontRange( _context, _bitmap, fontData, pixelHeight, range.Start, charData); for (int i = 0; i < charData.Length; ++i) { var yOff = charData[i].offset0.Y; yOff += ascent * scale.X; var glyphInfo = new GlyphInfo( x: charData[i].x0, y: charData[i].y0, width: charData[i].x1 - charData[i].x0, height: charData[i].y1 - charData[i].y0, xOffset: (int)charData[i].offset0.X, yOffset: (int)Math.Round(yOff), xAdvance: (int)Math.Round(charData[i].xadvance)); _glyphs[i + range.Start] = glyphInfo; } } }