public GlyphInfo(char c, uint index, int bitmapLeft, GlyphMetrics metrics, FTBitmap bitmap) { BitmapLeft = bitmapLeft; Index = index; Character = c; Width = (int)metrics.Width; Height = (int)metrics.Height; Advance = (int)metrics.HorizontalAdvance; BearingX = (int)metrics.HorizontalBearingX; BearingY = (int)metrics.HorizontalBearingY; Bitmap = new GlyphBitmap(bitmap); }
static Bitmap ConvertToBitmap(GlyphBitmap image) { var bmp = new Bitmap(image.Width, image.Height); for (int j = 0; j < image.Height; j++) { for (int i = 0; i < image.Width; i++) { byte alpha = image.Pixels[i + j * image.Width]; bmp.SetPixel(i, j, Color.FromArgb(alpha, 0, 0, 0)); } } return(bmp); }
public void RenderGrayscaleGlyph(GlyphBitmap bitmap, int x, int y) { int height = bitmap.Rows; int width = bitmap.Width; int pitch = bitmap.Pitch; byte[] bufferData = bitmap.BufferData; for (int by = 0; by < height; by++) { for (int bx = 0; bx < width; bx++) { var src = by * pitch + bx; var dest = (by + y) * TextureSize + bx + x; colors[dest] = (uint)(0x00FFFFFF | (bufferData[src] << 24)); } } Texture.SetData(colors); }
public void RenderMonoGlyph(GlyphBitmap bitmap, int x, int y) { int height = bitmap.Rows; int width = bitmap.Width; int pitch = bitmap.Pitch; byte[] bufferData = bitmap.BufferData; for (int by = 0; by < height; by++) { for (int bx = 0; bx < width; bx++) { int src = by * pitch + bx / 8; int dest = (by + y) * TextureSize + bx + x; bool isOpaque = (bufferData[src] & (1 << (7 - bx % 8))) != 0; colors[dest] = isOpaque ? 0xFFFFFFFF : 0x00FFFFFF; } } Texture.SetData(colors); }
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)); }
public void GenerateFontSource(TextWriter writer, FontDescriptor fontDescriptor) { XmlWriterSettings settings = new XmlWriterSettings(); settings.CloseOutput = false; settings.Indent = true; settings.IndentChars = " "; XmlWriter wr = XmlWriter.Create(writer, settings); try { FontData fontData = new FontData(fontDescriptor.Font); wr.WriteStartDocument(); wr.WriteComment(" Creado con EosFontGenerator "); wr.WriteComment(" No modificar "); wr.WriteComment(String.Format(" Name : {0} ", fontData.Name)); wr.WriteComment(String.Format(" Size : {0}pt ", fontDescriptor.Font.SizeInPoints)); wr.WriteComment(String.Format(" Style : {0} ", fontDescriptor.Font.Style)); wr.WriteStartElement("resources"); wr.WriteStartElement("fontResource"); wr.WriteAttributeString("version", "2.0"); wr.WriteAttributeString("resourceId", fontData.Name.Replace(", ", "")); wr.WriteStartElement("font"); wr.WriteAttributeString("name", fontData.Name); wr.WriteAttributeString("height", fontData.Height.ToString()); wr.WriteAttributeString("ascent", fontData.Ascent.ToString()); wr.WriteAttributeString("descent", fontData.Descent.ToString()); foreach (CharacterDescriptor characterDescriptor in fontDescriptor.CharacterDescriptors) { char ch = characterDescriptor.Character; GlyphData glyphData = new GlyphData(characterDescriptor.Font, ch, GlyphFormat.L1); GlyphBitmap glyphBitmap = glyphData.Glyph; wr.WriteStartElement("char"); wr.WriteAttributeString("code", String.Format("0x{0:X2}", Convert.ToInt32(ch))); wr.WriteAttributeString("advance", glyphData.Advance.ToString()); if (glyphBitmap != null) { wr.WriteStartElement("bitmap"); wr.WriteAttributeString("format", "L1"); wr.WriteAttributeString("left", glyphBitmap.OffsetX.ToString()); wr.WriteAttributeString("top", glyphBitmap.OffsetY.ToString()); wr.WriteAttributeString("width", glyphBitmap.Width.ToString()); wr.WriteAttributeString("height", glyphBitmap.Height.ToString()); for (int y = 0; y < glyphBitmap.Height; y++) { wr.WriteStartElement("scanLine"); StringBuilder sb = new StringBuilder(); try { int black = Color.Black.ToArgb(); for (int x = 0; x < glyphBitmap.Width; x++) { if (glyphBitmap.Bitmap.GetPixel(x, y).ToArgb() == black) { sb.Append('1'); } else { sb.Append('.'); } } } catch { } wr.WriteString(sb.ToString()); wr.WriteEndElement(); } wr.WriteEndElement(); } wr.WriteEndElement(); } wr.WriteEndElement(); wr.WriteEndElement(); wr.WriteEndElement(); wr.WriteEndDocument(); } finally { wr.Close(); } }
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); }