예제 #1
0
        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));
                }
            }
        }
예제 #2
0
        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));
        }
예제 #3
0
        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));
        }