Ejemplo n.º 1
0
        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;
                }
            }
        }