Exemple #1
0
        public int LoadFont(StbTrueType.stbtt_fontinfo font, byte *data, int dataSize)
        {
            var stbError = 0;

            font.userdata = this;
            stbError      = StbTrueType.stbtt_InitFont(font, data, 0);
            return(stbError);
        }
Exemple #2
0
        public static StbTrueType.stbtt_fontinfo LoadFontStb(byte[] bytes)
        {
            var font = new StbTrueType.stbtt_fontinfo();

            unsafe
            {
                fixed(byte *fontDataPtr = &bytes[0])
                {
                    StbTrueType.stbtt_InitFont(font, fontDataPtr, 0);
                }
            }

            return(font);
        }
Exemple #3
0
        public static unsafe DrawableFontAtlas RenderFontStbPacked(byte[] ttf, float fontSize, Vector2 atlasSize, int numChars, Font f, out StbTrueType.stbtt_fontinfo fontInfo)
        {
            var atlasObj = new DrawableFontAtlas(f, fontSize);

            fontSize = atlasObj.FontSize;

            fontInfo = new StbTrueType.stbtt_fontinfo();
            fixed(byte *ttPtr = &ttf[0])
            {
                StbTrueType.stbtt_InitFont(fontInfo, ttPtr, 0);

                float scaleFactor = StbTrueType.stbtt_ScaleForMappingEmToPixels(fontInfo, fontSize);
                int   ascent, descent, lineGap;

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

                atlasSize *= 3; // Needs to be big as the packing sucks, and glyphs getting cut out messes with the tests.
                var pixels = new byte[(int)atlasSize.X * (int)atlasSize.Y];

                var pc = new StbTrueType.stbtt_pack_context();

                fixed(byte *pixelsPtr = pixels)
                {
                    StbTrueType.stbtt_PackBegin(pc, pixelsPtr, (int)atlasSize.X, (int)atlasSize.Y, (int)atlasSize.X, 1, null);
                }

                var cd = new StbTrueType.stbtt_packedchar[numChars];

                fixed(StbTrueType.stbtt_packedchar *charPtr = cd)
                {
                    StbTrueType.stbtt_PackFontRange(pc, ttPtr, 0, -fontSize, 0, numChars, charPtr);
                }

                StbTrueType.stbtt_PackEnd(pc);
                for (var i = 0; i < cd.Length; ++i)
                {
                    var atlasGlyph = DrawableGlyph.CreateForTest(cd[i].xadvance, cd[i].xoff, cd[i].x1 - cd[i].x0, cd[i].y1 - cd[i].y0);
                    atlasGlyph.GlyphUV       = new Rectangle(cd[i].x0, cd[i].y0, atlasGlyph.Width, atlasGlyph.Height);
                    atlasObj.Glyphs[(char)i] = atlasGlyph;
                }
            }

            return(atlasObj);
        }
Exemple #4
0
        /// <summary>
        /// Loads a Font from the byte array. The Font will use this buffer until it is disposed.
        /// </summary>
        public unsafe Font(byte[] buffer)
        {
            fontBuffer = buffer;
            fontHandle = GCHandle.Alloc(fontBuffer, GCHandleType.Pinned);
            fontInfo   = new StbTrueType.stbtt_fontinfo();

            StbTrueType.stbtt_InitFont(fontInfo, (byte *)(fontHandle.AddrOfPinnedObject().ToPointer()), 0);

            FamilyName = GetName(fontInfo, 1);
            StyleName  = GetName(fontInfo, 2);

            // properties
            int ascent, descent, linegap;

            StbTrueType.stbtt_GetFontVMetrics(fontInfo, &ascent, &descent, &linegap);
            Ascent     = ascent;
            Descent    = descent;
            LineGap    = linegap;
            Height     = Ascent - Descent;
            LineHeight = Height + LineGap;
        public static TtfFontBakerResult Bake(byte[] ttf, float fontPixelHeight,
                                              int bitmapWidth, int bitmapHeight,
                                              IEnumerable <CharacterRange> characterRanges)
        {
            if (ttf == null || ttf.Length == 0)
            {
                throw new ArgumentNullException(nameof(ttf));
            }

            if (fontPixelHeight <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(fontPixelHeight));
            }

            if (bitmapWidth <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(bitmapWidth));
            }

            if (bitmapHeight <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(bitmapHeight));
            }

            if (characterRanges == null)
            {
                throw new ArgumentNullException(nameof(characterRanges));
            }

            if (!characterRanges.Any())
            {
                throw new ArgumentException("characterRanges must have a least one value.");
            }

            byte[] pixels;
            var    glyphs = new Dictionary <int, GlyphInfo>();

            fixed(byte *ttfPtr = ttf)
            {
                StbTrueType.stbtt_fontinfo fontInfo = new StbTrueType.stbtt_fontinfo();
                if (StbTrueType.stbtt_InitFont(fontInfo, ttfPtr, 0) == 0)
                {
                    throw new Exception("Failed to init font.");
                }

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

                int ascent, descent, lineGap;

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

                pixels = new byte[bitmapWidth * bitmapHeight];
                StbTrueType.stbtt_pack_context pc = new StbTrueType.stbtt_pack_context();
                fixed(byte *pixelsPtr = pixels)
                {
                    StbTrueType.stbtt_PackBegin(pc, pixelsPtr, bitmapWidth,
                                                bitmapHeight, bitmapWidth, 1, null);
                }

                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(pc, ttfPtr, 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[(char)(i + range.Start)] = glyphInfo;
                    }
                }
            }

            return(new TtfFontBakerResult(glyphs, fontPixelHeight, pixels, bitmapWidth, bitmapHeight));
        }
Exemple #6
0
        public void Add(byte[] ttf, float fontPixelHeight,
                        List <CharRange> charRanges)
        {
            if (ttf == null || ttf.Length == 0)
            {
                throw new ArgumentNullException(nameof(ttf));
            }

            if (fontPixelHeight <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(fontPixelHeight));
            }

            if (charRanges == null)
            {
                throw new ArgumentNullException(nameof(charRanges));
            }

            if (!charRanges.Any())
                throw new ArgumentException("charRanges must have a least one value.");

            fixed(byte *ttfPtr = ttf)
            {
                var fontInfo = new StbTrueType.stbtt_fontinfo();

                if (StbTrueType.stbtt_InitFont(fontInfo, ttfPtr, 0) == 0)
                {
                    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 charRanges)
                {
                    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, ttfPtr, 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;
                    }
                }
            }
        }