Example #1
0
        private FontGlyph GetGlyphWithoutBitmap(Dictionary <int, FontGlyph> glyphs, int codepoint)
        {
            FontGlyph glyph = null;

            if (glyphs.TryGetValue(codepoint, out glyph))
            {
                return(glyph);
            }

            Font font;
            var  g = GetCodepointIndex(codepoint, out font);

            if (g == 0)
            {
                return(null);
            }

            int advance = 0, lsb = 0, x0 = 0, y0 = 0, x1 = 0, y1 = 0;

            font.BuildGlyphBitmap(g, FontSize, font.Scale, ref advance, ref lsb, ref x0, ref y0, ref x1, ref y1);

            var pad = FontGlyph.PadFromBlur(Blur);
            var gw  = x1 - x0 + pad * 2;
            var gh  = y1 - y0 + pad * 2;

            glyph = new FontGlyph
            {
                Font      = font,
                Codepoint = codepoint,
                Size      = FontSize,
                Blur      = Blur,
                Index     = g,
                Bounds    = new Rectangle(0, 0, gw, gh),
                XAdvance  = (int)(font.Scale * advance * 10.0f),
                XOffset   = x0 - pad,
                YOffset   = y0 - pad
            };

            glyphs[codepoint] = glyph;

            return(glyph);
        }
        private FontGlyph GetGlyphWithoutBitmap(int codepoint)
        {
            FontGlyph glyph = null;

            if (_glyphs.TryGetValue(codepoint, out glyph))
            {
                return(glyph);
            }

            IFontSource font;
            var         g = FontSystem.GetCodepointIndex(codepoint, out font);

            if (g == null)
            {
                return(null);
            }

            int advance = 0, x0 = 0, y0 = 0, x1 = 0, y1 = 0;

            font.GetGlyphMetrics(g.Value, FontSize, out advance, out x0, out y0, out x1, out y1);

            var pad    = Math.Max(FontGlyph.PadFromBlur(FontSystem.BlurAmount), FontGlyph.PadFromBlur(FontSystem.StrokeAmount));
            var gw     = x1 - x0 + pad * 2;
            var gh     = y1 - y0 + pad * 2;
            var offset = FontGlyph.PadFromBlur(FontSystem.BlurAmount);

            glyph = new FontGlyph
            {
                Codepoint = codepoint,
                Id        = g.Value,
                Size      = FontSize,
                Font      = font,
                Bounds    = new Rectangle(0, 0, gw, gh),
                XAdvance  = advance,
                XOffset   = x0 - offset,
                YOffset   = y0 - offset
            };

            _glyphs[codepoint] = glyph;

            return(glyph);
        }
Example #3
0
        FontGlyph GetGlyphWithoutBitmap(GlyphCollection collection, int codepoint)
        {
            FontGlyph glyph = null;

            if (collection.Glyphs.TryGetValue(codepoint, out glyph))
            {
                return(glyph);
            }

            Font font;
            var  g = GetCodepointIndex(codepoint, out font);

            if (g == 0)
            {
                return(null);
            }

            int advance = 0, lsb = 0, x0 = 0, y0 = 0, x1 = 0, y1 = 0;

            font.BuildGlyphBitmap(g, font.Scale, ref advance, ref lsb, ref x0, ref y0, ref x1, ref y1);

            var pad    = Math.Max(FontGlyph.PadFromBlur(BlurAmount), FontGlyph.PadFromBlur(StrokeAmount));
            var gw     = x1 - x0 + pad * 2;
            var gh     = y1 - y0 + pad * 2;
            var offset = FontGlyph.PadFromBlur(BlurAmount);

            glyph = new FontGlyph
            {
                Font      = font,
                Codepoint = codepoint,
                Size      = FontSize,
                Index     = g,
                Bounds    = new Rectangle(0, 0, gw, gh),
                XAdvance  = (int)(font.Scale * advance * 10.0f),
                XOffset   = x0 - offset,
                YOffset   = y0 - offset
            };

            collection.Glyphs[codepoint] = glyph;

            return(glyph);
        }
Example #4
0
        private FontGlyph GetGlyph(Font font, int codepoint, int isize, int iblur, bool isBitmapRequired)
        {
            var       g       = 0;
            var       advance = 0;
            var       lsb     = 0;
            var       x0      = 0;
            var       y0      = 0;
            var       x1      = 0;
            var       y1      = 0;
            var       gw      = 0;
            var       gh      = 0;
            var       gx      = 0;
            var       gy      = 0;
            float     scale   = 0;
            FontGlyph glyph   = null;
            var       size    = isize / 10.0f;

            if (isize < 2)
            {
                return(null);
            }
            if (iblur > 20)
            {
                iblur = 20;
            }

            if (font.TryGetGlyph(codepoint, isize, iblur, out glyph))
            {
                if (!isBitmapRequired || glyph.X0 >= 0 && glyph.Y0 >= 0)
                {
                    return(glyph);
                }
            }
            g = font._font.fons__tt_getGlyphIndex(codepoint);
            if (g == 0)
            {
                throw new Exception(string.Format("Could not find glyph for codepoint {0}", codepoint));
            }

            scale = font._font.fons__tt_getPixelHeightScale(size);
            font._font.fons__tt_buildGlyphBitmap(g, size, scale, &advance, &lsb, &x0, &y0, &x1, &y1);

            var pad = FontGlyph.PadFromBlur(iblur);

            gw = x1 - x0 + pad * 2;
            gh = y1 - y0 + pad * 2;

            var currentAtlas = CurrentAtlas;

            if (isBitmapRequired)
            {
                if (!currentAtlas.AddRect(gw, gh, ref gx, ref gy))
                {
                    var ev = CurrentAtlasFull;
                    if (ev != null)
                    {
                        ev(this, EventArgs.Empty);
                    }

                    // This code will force creation of new atlas
                    _currentAtlas = null;
                    currentAtlas  = CurrentAtlas;

                    // Try to add again
                    if (!currentAtlas.AddRect(gw, gh, ref gx, ref gy))
                    {
                        throw new Exception(string.Format("Could not add rect to the newly created atlas. gw={0}, gh={1}", gw, gh));
                    }
                }
            }
            else
            {
                gx = -1;
                gy = -1;
            }

            if (glyph == null)
            {
                glyph = new FontGlyph
                {
                    Codepoint = codepoint,
                    Size      = isize,
                    Blur      = iblur
                };

                font.SetGlyph(codepoint, isize, iblur, glyph);
            }

            glyph.Index      = g;
            glyph.AtlasIndex = currentAtlas.Index;
            glyph.X0         = gx;
            glyph.Y0         = gy;
            glyph.X1         = glyph.X0 + gw;
            glyph.Y1         = glyph.Y0 + gh;
            glyph.XAdvance   = (int)(scale * advance * 10.0f);
            glyph.XOffset    = x0 - pad;
            glyph.YOffset    = y0 - pad;
            if (!isBitmapRequired)
            {
                return(glyph);
            }

            currentAtlas.RenderGlyph(font, glyph, gw, gh, scale);

            return(glyph);
        }
Example #5
0
        public void RenderGlyph(GraphicsDevice device, FontGlyph glyph, int blurAmount, int strokeAmount)
        {
            var pad = Math.Max(FontGlyph.PadFromBlur(blurAmount), FontGlyph.PadFromBlur(strokeAmount));

            // Render glyph to byte buffer
            var bufferSize = glyph.Bounds.Width * glyph.Bounds.Height;
            var buffer     = _byteBuffer;

            if ((buffer == null) || (buffer.Length < bufferSize))
            {
                buffer      = new byte[bufferSize];
                _byteBuffer = buffer;
            }
            Array.Clear(buffer, 0, bufferSize);

            var g           = glyph.Index;
            var colorSize   = glyph.Bounds.Width * glyph.Bounds.Height;
            var colorBuffer = _colorBuffer;

            if ((colorBuffer == null) || (colorBuffer.Length < colorSize))
            {
                colorBuffer  = new Color[colorSize];
                _colorBuffer = colorBuffer;
            }

            fixed(byte *dst = &buffer[pad + pad *glyph.Bounds.Width])
            {
                glyph.Font.RenderGlyphBitmap(dst,
                                             glyph.Bounds.Width - pad * 2,
                                             glyph.Bounds.Height - pad * 2,
                                             glyph.Bounds.Width,
                                             g);
            }

            if (strokeAmount > 0)
            {
                var width  = glyph.Bounds.Width;
                var top    = width * strokeAmount;
                var bottom = (glyph.Bounds.Height - strokeAmount) * glyph.Bounds.Width;
                var right  = glyph.Bounds.Width - strokeAmount;
                var left   = strokeAmount;

                byte d;
                for (var i = 0; i < colorSize; ++i)
                {
                    var col   = buffer[i];
                    var black = 0;
                    if (col == 255)
                    {
                        colorBuffer[i].R = colorBuffer[i].G = colorBuffer[i].B = colorBuffer[i].A = 255;
                        continue;
                    }

                    if (i >= top)
                    {
                        black = buffer[i - top];
                    }
                    if (i < bottom)
                    {
                        d     = buffer[i + top];
                        black = ((255 - d) * black + 255 * d) / 255;
                    }
                    if (i % width >= left)
                    {
                        d     = buffer[i - strokeAmount];
                        black = ((255 - d) * black + 255 * d) / 255;
                    }
                    if (i % width < right)
                    {
                        d     = buffer[i + strokeAmount];
                        black = ((255 - d) * black + 255 * d) / 255;
                    }

                    if (black == 0)
                    {
                        if (col == 0)
                        {
                            colorBuffer[i].R = colorBuffer[i].G = colorBuffer[i].B = colorBuffer[i].A = 0;                             //black transparency to suit stroke
                            continue;
                        }
#if PREMULTIPLIEDALPHA
                        colorBuffer[i].R = colorBuffer[i].G = colorBuffer[i].B = colorBuffer[i].A = col;
#else
                        colorBuffer[i].R = colorBuffer[i].G = colorBuffer[i].B = 255;
                        colorBuffer[i].A = col;
#endif
                    }
                    else
                    {
                        if (col == 0)
                        {
                            colorBuffer[i].R = colorBuffer[i].G = colorBuffer[i].B = 0;
                            colorBuffer[i].A = (byte)black;
                            continue;
                        }

#if PREMULTIPLIEDALPHA
                        var alpha = ((255 - col) * black + 255 * col) / 255;
                        colorBuffer[i].R = colorBuffer[i].G = colorBuffer[i].B = (byte)((alpha * col) / 255);
                        colorBuffer[i].A = (byte)alpha;
#else
                        colorBuffer[i].R = colorBuffer[i].G = colorBuffer[i].B = col;
                        colorBuffer[i].A = (byte)(((255 - col) * black + 255 * col) / 255);
#endif
                    }
                }
            }
            else
            {
                if (blurAmount > 0)
                {
                    fixed(byte *bdst = &buffer[0])
                    {
                        Blur(bdst, glyph.Bounds.Width, glyph.Bounds.Height, glyph.Bounds.Width, blurAmount);
                    }
                }

                for (var i = 0; i < colorSize; ++i)
                {
                    var c = buffer[i];
#if PREMULTIPLIEDALPHA
                    colorBuffer[i].R = colorBuffer[i].G = colorBuffer[i].B = colorBuffer[i].A = c;
#else
                    colorBuffer[i].R = colorBuffer[i].G = colorBuffer[i].B = 255;
                    colorBuffer[i].A = c;
#endif
                }
            }

            // Write to texture
            if (Texture == null)
            {
                Texture = new Texture2D(device, Width, Height);
            }
#if TEXTURESETDATAEXT
            fixed(Color *p = colorBuffer)
#if FNA
            Texture.SetDataPointerEXT(0, glyph.Bounds, (IntPtr)p, colorSize * sizeof(Color));
#else
            Texture.SetDataEXT(0, 0, glyph.Bounds, (IntPtr)p, colorSize * sizeof(Color));
#endif
#else
            Texture.SetData(0, 0, glyph.Bounds, colorBuffer, 0, colorSize);
#endif
        }
Example #6
0
        public void RenderGlyph(ITexture2DCreator textureCreator, FontGlyph glyph, int blurAmount, int strokeAmount, bool premultiplyAlpha)
        {
            var pad = Math.Max(FontGlyph.PadFromBlur(blurAmount), FontGlyph.PadFromBlur(strokeAmount));

            // Render glyph to byte buffer
            var bufferSize = glyph.Bounds.Width * glyph.Bounds.Height;
            var buffer     = _byteBuffer;

            if ((buffer == null) || (buffer.Length < bufferSize))
            {
                buffer      = new byte[bufferSize];
                _byteBuffer = buffer;
            }
            Array.Clear(buffer, 0, bufferSize);

            var colorBuffer = _colorBuffer;

            if ((colorBuffer == null) || (colorBuffer.Length < bufferSize * 4))
            {
                colorBuffer  = new byte[bufferSize * 4];
                _colorBuffer = colorBuffer;
            }

            glyph.Font.RasterizeGlyphBitmap(glyph.Id,
                                            glyph.Size,
                                            buffer,
                                            pad + pad * glyph.Bounds.Width,
                                            glyph.Bounds.Width - pad * 2,
                                            glyph.Bounds.Height - pad * 2,
                                            glyph.Bounds.Width);

            if (strokeAmount > 0)
            {
                var width  = glyph.Bounds.Width;
                var top    = width * strokeAmount;
                var bottom = (glyph.Bounds.Height - strokeAmount) * glyph.Bounds.Width;
                var right  = glyph.Bounds.Width - strokeAmount;
                var left   = strokeAmount;

                byte d;
                for (var i = 0; i < bufferSize; ++i)
                {
                    var ci    = i * 4;
                    var col   = buffer[i];
                    var black = 0;
                    if (col == 255)
                    {
                        colorBuffer[ci] = colorBuffer[ci + 1] = colorBuffer[ci + 2] = colorBuffer[ci + 3] = 255;
                        continue;
                    }

                    if (i >= top)
                    {
                        black = buffer[i - top];
                    }
                    if (i < bottom)
                    {
                        d     = buffer[i + top];
                        black = ((255 - d) * black + 255 * d) / 255;
                    }
                    if (i % width >= left)
                    {
                        d     = buffer[i - strokeAmount];
                        black = ((255 - d) * black + 255 * d) / 255;
                    }
                    if (i % width < right)
                    {
                        d     = buffer[i + strokeAmount];
                        black = ((255 - d) * black + 255 * d) / 255;
                    }

                    if (black == 0)
                    {
                        if (col == 0)
                        {
                            colorBuffer[ci] = colorBuffer[ci + 1] = colorBuffer[ci + 2] = colorBuffer[ci + 3] = 0;                             //black transparency to suit stroke
                            continue;
                        }

                        if (premultiplyAlpha)
                        {
                            colorBuffer[ci] = colorBuffer[ci + 1] = colorBuffer[ci + 2] = colorBuffer[ci + 3] = col;
                        }
                        else
                        {
                            colorBuffer[ci]     = colorBuffer[ci + 1] = colorBuffer[ci + 2] = 255;
                            colorBuffer[ci + 3] = col;
                        }
                    }
                    else
                    {
                        if (col == 0)
                        {
                            colorBuffer[ci]     = colorBuffer[ci + 1] = colorBuffer[ci + 2] = 0;
                            colorBuffer[ci + 3] = (byte)black;
                            continue;
                        }

                        if (premultiplyAlpha)
                        {
                            var alpha = ((255 - col) * black + 255 * col) / 255;
                            colorBuffer[ci]     = colorBuffer[ci + 1] = colorBuffer[ci + 2] = (byte)((alpha * col) / 255);
                            colorBuffer[ci + 3] = (byte)alpha;
                        }
                        else
                        {
                            colorBuffer[ci]     = colorBuffer[ci + 1] = colorBuffer[ci + 2] = col;
                            colorBuffer[ci + 3] = (byte)(((255 - col) * black + 255 * col) / 255);
                        }
                    }
                }
            }
            else
            {
                if (blurAmount > 0)
                {
                    fixed(byte *bdst = &buffer[0])
                    {
                        Blur(bdst, glyph.Bounds.Width, glyph.Bounds.Height, glyph.Bounds.Width, blurAmount);
                    }
                }

                for (var i = 0; i < bufferSize; ++i)
                {
                    var ci = i * 4;
                    var c  = buffer[i];

                    if (premultiplyAlpha)
                    {
                        colorBuffer[ci] = colorBuffer[ci + 1] = colorBuffer[ci + 2] = colorBuffer[ci + 3] = c;
                    }
                    else
                    {
                        colorBuffer[ci]     = colorBuffer[ci + 1] = colorBuffer[ci + 2] = 255;
                        colorBuffer[ci + 3] = c;
                    }
                }
            }

            // Write to texture
            if (Texture == null)
            {
                Texture = textureCreator.Create(Width, Height);
            }

            Texture.SetData(glyph.Bounds, colorBuffer);
        }