Exemple #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 = StbTrueType.CreateFont(ttf, 0);

            if (fontInfo == null)
            {
                throw new Exception("Failed to init font.");
            }

            var scaleFactor = StbTrueType.stbtt_ScaleForPixelHeight(fontInfo, fontPixelHeight);

            int ascent, descent, lineGap;

            StbTrueType.stbtt_GetFontVMetrics(fontInfo, &ascent, &descent, &lineGap);

            foreach (var range in characterRanges)
            {
                if (range.Start > range.End)
                {
                    continue;
                }

                var cd = new StbTrueType.stbtt_packedchar[range.End - range.Start + 1];
                fixed(StbTrueType.stbtt_packedchar *chardataPtr = cd)
                {
                    StbTrueType.stbtt_PackFontRange(_context, fontInfo.data, 0, fontPixelHeight,
                                                    range.Start,
                                                    range.End - range.Start + 1,
                                                    chardataPtr);
                }

                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;
                }
            }
        }