public static Bitmap RenderChar(char c, PixelRenderingOptions options) { FontFace fallback = FontManager.FontMap.GetFont(0); if (c == ' ') { throw new Exception("A space cannot be rendered in the TextEngine."); } FontSheet sheet = options.Font.Search(c, options.FontType, out (int i, int x, int y)index) ?? fallback.Search(c, options.FontType, out index); Rectangle crop = new Rectangle( options.Font.Ppu.Width * index.x, options.Font.Ppu.Height * index.y, options.Font.Ppu.Width, options.Font.Ppu.Height); using (Bitmap b = new Bitmap(sheet.Path)) { using (Bitmap tmp = b.Clone(crop, b.PixelFormat)) { if (!options.Font.AutoCrop.HasValue) { crop.Width = TextConfiguration.GetWidth(tmp, tmp.Width); } else { if (options.Font.AutoCrop.Value) { crop.Width = TextConfiguration.GetWidth(tmp, tmp.Width); } } crop.Debug(); return(b.Clone(crop, b.PixelFormat)); } } }
public static Size GetRenderBox(this string s, FontFace font) { int letterwidth = font.Ppu.Width + font.Padding; int letterspace = font.Spacing; int letterheight = font.Ppu.Height + font.Padding; List <int> width = new List <int>(); char[] map = s.ToCharArray(); if (map.Any(u => u.Overhangs())) { //letterheight += font.Overhang; } int b = 0; // overhang extender. int x = 0; // font width int y = 1; // font height foreach (char c in map) { if (font.HasFallback.HasValue) { if (!font.HasFallback.Value) { if (!font.Search(font.GetDefault(), c, out (int i, int x, int y)index).Exists()) { continue; } } } if (c.Overhangs()) { b += 1; } if (c == '\n') { c.Debug("Line Break"); width.Add(x); x = 0; y += 1; continue; } if (c == ' ') { c.Debug("Space"); x += letterspace; continue; } if (c == '⠀') { c.Debug("Braille Clear Block"); x += 4; // Default Braille Length. continue; } c.Debug("normal letter"); x += letterwidth; } width.Add(x); letterheight.Debug($"* {y}"); letterheight *= y; letterheight += (font.Overhang * b); letterwidth = width.GetLargest(); return(new Size(letterwidth, letterheight)); }
public static Bitmap RenderString(string str, PixelRenderingOptions options, ulong?fontId = null, int padding = 0) { char[] map = str.ToCharArray(); FontFace oldFont = options.Font; options.Font = fontId.HasValue ? FontManager.FontMap.GetFont(fontId.Value) : options.Font; FontFace font = options.Font; Point pointer = new Point(padding, padding); // This is where the top left letter bitmap will start from. Size s = str.GetRenderBox(font); // Correct render box built. s.Width += padding * 2; s.Height += padding * 2; s.Debug(); Rectangle area = new Rectangle(pointer, s); Bitmap render = new Bitmap(s.Width, s.Height); using (Graphics g = Graphics.FromImage(render)) { Bitmap[] renders = RenderChars(map, options); bool overhung = false; int x = 0; for (int i = 0; i < map.Length; i++) { if (map[i] == '\n') { if (overhung) { pointer.Y += font.Overhang; overhung = false; } pointer.Y += font.Ppu.Height + font.Padding; pointer.X = padding; continue; } if (map[i] == ' ') { pointer.X += font.Spacing; continue; } if (map[i] == '⠀') // Invisible Braille Block { pointer.X += 4; // The width of all braille. continue; } if (font.HasFallback.HasValue) { if (!font.HasFallback.Value) { if (!font.Search(map[i], options.FontType, out (int i, int x, int y)index).Exists()) { continue; } } } if (map[i].Overhangs()) { overhung = true; pointer.Y += font.Overhang; } // if there is no fallback, if the letter doesnt exist, skip it. using (Bitmap b = renders[x]) { Rectangle rct = new Rectangle(pointer, b.Size); g.SetClip(rct); g.DrawImage(b, rct); g.ResetClip(); pointer.X += rct.Width + font.Padding; } if (map[i].Overhangs()) { pointer.Y -= font.Overhang; } x++; } } options.Font = oldFont; return(render.Color(options.Palette)); }