예제 #1
0
        static Bitmap GenerateOutput(string fontFileName, string phrase, int pixels, int SDF_scale)
        {
            var bytes = File.ReadAllBytes(fontFileName);

            var font = new LunarLabs.Fonts.Font(bytes);

            int height = pixels * SDF_scale;
            var scale  = font.ScaleInPixels(height);

            var glyphs  = new Dictionary <char, FontGlyph>();
            var bitmaps = new Dictionary <char, Bitmap>();

            foreach (var ch in phrase)
            {
                if (glyphs.ContainsKey(ch))
                {
                    continue;
                }

                var glyph = font.RenderGlyph(ch, scale);
                glyphs[ch]  = glyph;
                bitmaps[ch] = ConvertToBitmap(glyph.Image);
            }

            int ascent, descent, lineGap;

            font.GetFontVMetrics(out ascent, out descent, out lineGap);
            int baseLine = height - (int)(ascent * scale);


            int minX = int.MaxValue;
            int maxX = int.MinValue;
            int minY = int.MaxValue;
            int maxY = int.MinValue;

            var positions = new Point[phrase.Length];

            int x = 0;

            for (int i = 0; i < phrase.Length; i++)
            {
                var ch    = phrase[i];
                var glyph = glyphs[ch];

                var next = i < phrase.Length - 1 ? phrase[i + 1] : '\0';

                var kerning = font.GetKerning(ch, next, scale);

                int y0 = height - baseLine + glyph.yOfs;
                int y1 = y0 + glyph.Image.Height;

                int x0 = x + glyph.xOfs - kerning;
                int x1 = x0 + glyph.Image.Width;
                x += glyph.xAdvance;

                positions[i] = new Point(x0, y0);

                x1 = Math.Max(x, x1);

                minX = Math.Min(minX, x0);
                maxX = Math.Max(maxX, x1);

                minY = Math.Min(minY, y0);
                maxY = Math.Max(maxY, y1);
            }

            int realWidth  = (maxX - minX) + 1;
            int realHeight = (maxY - minY) + 1;

            for (int i = 0; i < phrase.Length; i++)
            {
                positions[i].X -= minX;
                positions[i].Y -= minY;
            }

            var tempBmp = new GlyphBitmap(realWidth, realHeight);

            {
                // draw the baseline height in blue color
                var ly = height - (baseLine + minY);
                //g.DrawLine(new Pen(Color.Blue), 0, ly, realWidth - 1, ly);

                // now draw each character
                x = 0;
                for (int i = 0; i < phrase.Length; i++)
                {
                    var ch    = phrase[i];
                    var glyph = glyphs[ch];
                    var bmp   = bitmaps[ch];
                    var pos   = positions[i];
                    tempBmp.Draw(glyph.Image, pos.X, pos.Y);
                }
            }

            if (SDF_scale > 1)
            {
                tempBmp = DistanceFieldUtils.CreateDistanceField(tempBmp, SDF_scale, 16 * SDF_scale);
            }

            return(ConvertToBitmap(tempBmp));
        }
예제 #2
0
        static void Main(string[] args)
        {
            var dlg = new OpenFileDialog {
                Filter = "Font Files (*.ttf)|*.ttf", InitialDirectory = Directory.GetCurrentDirectory()
            };

            if (dlg.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            var fontFileName = dlg.FileName;

            Console.WriteLine($"Loading {fontFileName}...");

            var bytes = File.ReadAllBytes(fontFileName);

            var font = new LunarLabs.Fonts.Font(bytes);

            // make this a number larger than 1 to enable SDF output
            int SDF_scale = 1;

            // here is the desired height in pixels of the output
            // the real value might not be exactly this depending on which characters are part of the input text
            int height = 64 * SDF_scale;
            var scale  = font.ScaleInPixels(height);

            var phrase  = "Hello world";
            var glyphs  = new Dictionary <char, FontGlyph>();
            var bitmaps = new Dictionary <char, Bitmap>();

            foreach (var ch in phrase)
            {
                if (glyphs.ContainsKey(ch))
                {
                    continue;
                }

                var glyph = font.RenderGlyph(ch, scale);
                glyphs[ch]  = glyph;
                bitmaps[ch] = ConvertToBitmap(glyph.Image);
            }

            int ascent, descent, lineGap;

            font.GetFontVMetrics(out ascent, out descent, out lineGap);
            int baseLine = height - (int)(ascent * scale);


            int minX = int.MaxValue;
            int maxX = int.MinValue;
            int minY = int.MaxValue;
            int maxY = int.MinValue;

            var positions = new Point[phrase.Length];

            int x = 0;

            for (int i = 0; i < phrase.Length; i++)
            {
                var ch    = phrase[i];
                var glyph = glyphs[ch];

                var next = i < phrase.Length - 1 ? phrase[i + 1] : '\0';

                var kerning = font.GetKerning(ch, next, scale);

                int y0 = height - baseLine + glyph.yOfs;
                int y1 = y0 + glyph.Image.Height;

                int x0 = x + glyph.xOfs - kerning;
                int x1 = x0 + glyph.Image.Width;
                x += glyph.xAdvance;

                positions[i] = new Point(x0, y0);

                x1 = Math.Max(x, x1);

                minX = Math.Min(minX, x0);
                maxX = Math.Max(maxX, x1);

                minY = Math.Min(minY, y0);
                maxY = Math.Max(maxY, y1);
            }

            int realWidth  = (maxX - minX) + 1;
            int realHeight = (maxY - minY) + 1;

            for (int i = 0; i < phrase.Length; i++)
            {
                positions[i].X -= minX;
                positions[i].Y -= minY;
            }

            var tempBmp = new GlyphBitmap(realWidth, realHeight);

            {
                // draw the baseline height in blue color
                var ly = height - (baseLine + minY);
                //g.DrawLine(new Pen(Color.Blue), 0, ly, realWidth - 1, ly);

                // now draw each character
                x = 0;
                for (int i = 0; i < phrase.Length; i++)
                {
                    var ch    = phrase[i];
                    var glyph = glyphs[ch];
                    var bmp   = bitmaps[ch];
                    var pos   = positions[i];
                    tempBmp.Draw(glyph.Image, pos.X, pos.Y);
                }
            }

            if (SDF_scale > 1)
            {
                tempBmp = DistanceFieldUtils.CreateDistanceField(tempBmp, SDF_scale, 32);
            }

            var outBmp         = ConvertToBitmap(tempBmp);
            var outputFileName = "output.png";

            Console.WriteLine($"Outputting {outputFileName}...");
            outBmp.Save(outputFileName);
        }