示例#1
0
        internal void RenderGlyphOnAtlas(FontGlyph glyph)
        {
            var currentAtlas = CurrentAtlas;
            int gx = 0, gy = 0;
            var gw = glyph.Bounds.Width;
            var gh = glyph.Bounds.Height;

            if (!currentAtlas.AddRect(gw, gh, ref gx, ref gy))
            {
                CurrentAtlasFull?.Invoke(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));
                }
            }

            glyph.Bounds.X = gx;
            glyph.Bounds.Y = gy;

            currentAtlas.RenderGlyph(_textureCreator, glyph, BlurAmount, StrokeAmount, PremultiplyAlpha);

            glyph.Atlas = currentAtlas;
        }
示例#2
0
        private FontAtlas GetCurrentAtlas(ITexture2DManager device, int textureWidth, int textureHeight)
#endif
        {
            if (_currentAtlas == null)
            {
                Texture2D existingTexture = null;
                if (ExistingTexture != null && Atlases.Count == 0)
                {
                    existingTexture = ExistingTexture;
                }

                _currentAtlas = new FontAtlas(textureWidth, textureHeight, 256, existingTexture);

                // If existing texture is used, mark existing used rect as used
                if (existingTexture != null && !ExistingTextureUsedSpace.IsEmpty)
                {
                    if (!_currentAtlas.AddSkylineLevel(0, ExistingTextureUsedSpace.X, ExistingTextureUsedSpace.Y, ExistingTextureUsedSpace.Width, ExistingTextureUsedSpace.Height))
                    {
                        throw new Exception(string.Format("Unable to specify existing texture used space: {0}", ExistingTextureUsedSpace));
                    }

                    // TODO: Clear remaining space
                }

                Atlases.Add(_currentAtlas);
            }

            return(_currentAtlas);
        }
示例#3
0
 public void Dispose()
 {
     if (_fonts != null)
     {
         foreach (var font in _fonts)
         {
             font.Dispose();
         }
         _fonts.Clear();
     }
     Atlases?.Clear();
     _currentAtlas = null;
     _glyphs?.Clear();
 }
示例#4
0
        public FontSystem(FontSystemParams p)
        {
            _params_ = p;

            atlas        = new FontAtlas(_params_.Width, _params_.Height, 256);
            _fonts       = new Font[4];
            _fontsNumber = 0;
            _itw         = 1.0f / _params_.Width;
            _ith         = 1.0f / _params_.Height;
            _texData     = new byte[_params_.Width * _params_.Height];
            Array.Clear(_texData, 0, _texData.Length);
            _dirtyRect[0] = _params_.Width;
            _dirtyRect[1] = _params_.Height;
            _dirtyRect[2] = 0;
            _dirtyRect[3] = 0;
            AddWhiteRect(2, 2);
            ClearState();
        }
示例#5
0
        private FontGlyph GetGlyphInternal(GraphicsDevice graphicsDevice, Dictionary <int, FontGlyph> glyphs, int codepoint)
        {
            var glyph = GetGlyphWithoutBitmap(glyphs, codepoint);

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

            if (graphicsDevice == null || glyph.Atlas != null || glyph.IsEmpty)
            {
                return(glyph);
            }

            var currentAtlas = CurrentAtlas;
            int gx = 0, gy = 0;
            var gw = glyph.Bounds.Width;
            var gh = glyph.Bounds.Height;

            if (!currentAtlas.AddRect(gw, gh, ref gx, ref gy))
            {
                CurrentAtlasFull?.Invoke(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));
                }
            }

            glyph.Bounds.X = gx;
            glyph.Bounds.Y = gy;

            currentAtlas.RenderGlyph(graphicsDevice, glyph);

            glyph.Atlas = currentAtlas;

            return(glyph);
        }
示例#6
0
        public FontSystem(FontSystemParams p)
        {
            _params_ = p;

            AtlasFull = () => ResetAtlas();

            _atlas     = new FontAtlas(_params_.Width, _params_.Height, 256);
            _itw       = 1.0f / _params_.Width;
            _ith       = 1.0f / _params_.Height;
            _texData   = new byte[_params_.Width * _params_.Height];
            _colorData = new Color[_params_.Width * _params_.Height];
            Array.Clear(_texData, 0, _texData.Length);
            _dirtyRect[0] = _params_.Width;
            _dirtyRect[1] = _params_.Height;
            _dirtyRect[2] = 0;
            _dirtyRect[3] = 0;
            AddWhiteRect(2, 2);
            ClearState();
        }
示例#7
0
        internal void RenderGlyphOnAtlas(ITexture2DManager device, DynamicFontGlyph glyph)
#endif
        {
            var textureSize = new Point(TextureWidth, TextureHeight);

            if (ExistingTexture != null)
            {
#if MONOGAME || FNA || STRIDE
                textureSize = new Point(ExistingTexture.Width, ExistingTexture.Height);
#else
                textureSize = device.GetTextureSize(ExistingTexture);
#endif
            }

            int gx = 0, gy = 0;
            var gw = glyph.Bounds.Width;
            var gh = glyph.Bounds.Height;

            var currentAtlas = GetCurrentAtlas(device, textureSize.X, textureSize.Y);
            if (!currentAtlas.AddRect(gw, gh, ref gx, ref gy))
            {
                CurrentAtlasFull?.Invoke(this, EventArgs.Empty);

                // This code will force creation of new atlas
                _currentAtlas = null;
                currentAtlas  = GetCurrentAtlas(device, textureSize.X, textureSize.Y);

                // 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));
                }
            }

            glyph.Bounds.X = gx;
            glyph.Bounds.Y = gy;

            currentAtlas.RenderGlyph(device, glyph, FontSources[glyph.FontSourceIndex], BlurAmount, StrokeAmount, PremultiplyAlpha, KernelWidth, KernelHeight);

            glyph.Texture = currentAtlas.Texture;
        }
示例#8
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);
        }