Пример #1
0
        private void Dispose(bool disposing)
        {
            if (this.disposedValue == false)
            {
                if (disposing)
                {
                    // Dispose managed resources.
                }

                // Dispose unmanaged resources.
                FullDictionary <char, GlyphInfo> dict = this.GlyphInfoDictionary;
                this.GlyphInfoDictionary = null;
                if (dict != null)
                {
                    dict.Clear();
                }

                Font font = this.GlyphFont;
                this.GlyphFont = null;
                if (font != null)
                {
                    font.Dispose();
                }

                Texture texture = this.TextureObj;
                this.TextureObj = null;
                if (texture != null)
                {
                    texture.Dispose();
                }
            }

            this.disposedValue = true;
        }
Пример #2
0
        private static Bitmap PaintTexture(int textureWidth, int textureHeight, FullDictionary <char, GlyphInfo> fullDictionary, Font font)
        {
            var bitmap = new Bitmap(textureWidth, textureHeight);

            using (var graphics = Graphics.FromImage(bitmap))
            {
                graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
                foreach (var item in fullDictionary)
                {
                    Size oneSize = graphics.MeasureString(string.Format("{0}", item.Key), font).ToSize();

                    using (var oneBitmap = new Bitmap(oneSize.Width, oneSize.Height))
                    {
                        using (var oneGrphics = Graphics.FromImage(oneBitmap))
                        { oneGrphics.DrawString(string.Format("{0}", item.Key), font, Brushes.Red, 0, 0); }

                        graphics.DrawImage(oneBitmap,
                                           item.Value.ToRectangle(),
                                           new Rectangle((oneSize.Width - item.Value.width) / 2, 0, item.Value.width, item.Value.height),
                                           GraphicsUnit.Pixel);
                    }
                }
            }

            return(bitmap);
        }
Пример #3
0
        unsafe private void SetupGlyphTexCoord(string content, IFontTexture fontTexture)
        {
            FullDictionary <char, GlyphInfo> charInfoDict = fontTexture.GlyphInfoDictionary;
            IntPtr pointer = this.uvBuffer.MapBuffer(MapBufferAccess.WriteOnly);
            var    array   = (TextModel.GlyphTexCoord *)pointer.ToPointer();
            int    width   = fontTexture.TextureSize.Width;
            int    height  = fontTexture.TextureSize.Height;

            /*
             * 0     3  4     6 8     11 12   15
             * -------  ------- -------  -------
             * |     |  |     | |     |  |     |
             * |     |  |     | |     |  |     |
             * |     |  |     | |     |  |     |
             * -------  ------- -------  -------
             * 1     2  5     6 9     10 13   14
             */
            for (int i = 0; i < content.Length; i++)
            {
                char      ch     = content[i];
                GlyphInfo info   = fontTexture.GlyphInfoDictionary[ch];
                const int shrimp = 0;
                array[i] = new TextModel.GlyphTexCoord(
                    //new vec2(0, 0),
                    //new vec2(0, 1),
                    //new vec2(1, 1),
                    //new vec2(1, 0)
                    new vec2((float)(info.xoffset + shrimp) / (float)width, (float)(info.yoffset) / (float)height),
                    new vec2((float)(info.xoffset + shrimp) / (float)width, (float)(info.yoffset + info.height) / (float)height),
                    new vec2((float)(info.xoffset - shrimp + info.width) / (float)width, (float)(info.yoffset + info.height) / (float)height),
                    new vec2((float)(info.xoffset - shrimp + info.width) / (float)width, (float)(info.yoffset) / (float)height)
                    );
            }
            this.uvBuffer.UnmapBuffer();
        }
Пример #4
0
        private static FullDictionary <char, GlyphInfo> GetGlyphDict(Font font, string charSet)
        {
            var dict = new FullDictionary <char, GlyphInfo>(GlyphInfo.Default);

            using (var bmp = new Bitmap(1, 1))
            {
                using (var graphics = Graphics.FromImage(bmp))
                {
                    foreach (var c in charSet)
                    {
                        Size oneSize    = graphics.MeasureString(string.Format("{0}", c), font).ToSize();
                        Size doubleSize = graphics.MeasureString(string.Format("{0}{0}", c), font).ToSize();

                        // TODO: Log this.
                        if (oneSize.Height != doubleSize.Height)
                        {
                            continue;
                        }
                        if (oneSize.Width >= doubleSize.Width)
                        {
                            continue;
                        }

                        Size charSize = new Size(doubleSize.Width - oneSize.Width, oneSize.Height);
                        var  info     = new GlyphInfo(0, 0, charSize.Width, charSize.Height);
                        dict.Add(c, info);
                    }
                }
            }

            return(dict);
        }
Пример #5
0
        unsafe private void SetupGlyphPositions(string content, FontResource fontResource)
        {
            FullDictionary <char, CharacterInfo> charInfoDict = fontResource.CharInfoDict;

            OpenGL.BindBuffer(BufferTarget.ArrayBuffer, this.model.positionBufferPtr.BufferId);
            IntPtr pointer = OpenGL.MapBuffer(BufferTarget.ArrayBuffer, MapBufferAccess.ReadWrite);
            var    array = (GlyphPosition *)pointer.ToPointer();
            int    currentWidth = 0; int currentHeight = 0;

            /*
             * 0     3  4     7 8     11 12   15
             * -------  ------- -------  -------
             * |     |  |     | |     |  |     |
             * |     |  |     | |     |  |     |
             * |     |  |     | |     |  |     |
             * -------  ------- -------  -------
             * 1     2  5     6 9     10 13   14
             */
            for (int i = 0; i < content.Length; i++)
            {
                char          ch   = content[i];
                CharacterInfo info = charInfoDict[ch];
                array[i] = new GlyphPosition(
                    new vec2(currentWidth, currentHeight + fontResource.FontHeight),
                    new vec2(currentWidth, currentHeight),
                    new vec2(currentWidth + info.width, currentHeight),
                    new vec2(currentWidth + info.width, currentHeight + fontResource.FontHeight));
                currentWidth += info.width + fontResource.FontHeight / 10;
            }
            // move to center
            for (int i = 0; i < content.Length; i++)
            {
                GlyphPosition position = array[i];

                position.leftUp.x -= currentWidth / 2.0f;
                //position.leftUp.x /= currentWidth / factor;
                position.leftDown.x -= currentWidth / 2.0f;
                //position.leftDown.x /= currentWidth / factor;
                position.rightUp.x -= currentWidth / 2.0f;
                //position.rightUp.x /= currentWidth / factor;
                position.rightDown.x -= currentWidth / 2.0f;
                //position.rightDown.x /= currentWidth / factor;
                position.leftUp.y    -= (currentHeight + fontResource.FontHeight) / 2.0f;
                position.leftDown.y  -= (currentHeight + fontResource.FontHeight) / 2.0f;
                position.rightUp.y   -= (currentHeight + fontResource.FontHeight) / 2.0f;
                position.rightDown.y -= (currentHeight + fontResource.FontHeight) / 2.0f;

                position.leftUp.x    /= (currentHeight + fontResource.FontHeight);
                position.leftDown.x  /= (currentHeight + fontResource.FontHeight);
                position.rightUp.x   /= (currentHeight + fontResource.FontHeight);
                position.rightDown.x /= (currentHeight + fontResource.FontHeight);
                position.leftUp.y    /= (currentHeight + fontResource.FontHeight);
                position.leftDown.y  /= (currentHeight + fontResource.FontHeight);
                position.rightUp.y   /= (currentHeight + fontResource.FontHeight);
                position.rightDown.y /= (currentHeight + fontResource.FontHeight);
                array[i]              = position;
            }
            OpenGL.UnmapBuffer(BufferTarget.ArrayBuffer);
            OpenGL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }
Пример #6
0
        public static XElement ToXElement(this FullDictionary <char, CharacterInfo> dict)
        {
            XElement result = new XElement(strCharacterInfoDict,
                                           from item in dict
                                           select KeyValuePairHelper.ToXElement(item));

            return(result);
        }
Пример #7
0
        unsafe private void SetupGlyphPositions(string content, IFontTexture fontTexture)
        {
            FullDictionary <char, GlyphInfo> charInfoDict = fontTexture.GlyphInfoDictionary;
            IntPtr pointer = this.positionBuffer.MapBuffer(MapBufferAccess.ReadWrite);
            var    array = (TextModel.GlyphPosition *)pointer.ToPointer();
            float  currentWidth = 0; int currentHeight = 0;

            /*
             * 0     3  4     7 8     11 12   15
             * -------  ------- -------  -------
             * |     |  |     | |     |  |     |
             * |     |  |     | |     |  |     |
             * |     |  |     | |     |  |     |
             * -------  ------- -------  -------
             * 1     2  5     6 9     10 13   14
             */
            for (int i = 0; i < content.Length; i++)
            {
                char      ch   = content[i];
                GlyphInfo info = charInfoDict[ch];
                array[i] = new TextModel.GlyphPosition(
                    new vec2(currentWidth, currentHeight + fontTexture.GlyphHeight),
                    new vec2(currentWidth, currentHeight),
                    new vec2(currentWidth + info.width, currentHeight),
                    new vec2(currentWidth + info.width, currentHeight + fontTexture.GlyphHeight));
                currentWidth += info.width + fontTexture.GlyphHeight / 10;
            }
            // move to center
            for (int i = 0; i < content.Length; i++)
            {
                TextModel.GlyphPosition position = array[i];

                position.leftUp.x -= currentWidth / 2.0f;
                //position.leftUp.x /= currentWidth / factor;
                position.leftDown.x -= currentWidth / 2.0f;
                //position.leftDown.x /= currentWidth / factor;
                position.rightUp.x -= currentWidth / 2.0f;
                //position.rightUp.x /= currentWidth / factor;
                position.rightDown.x -= currentWidth / 2.0f;
                //position.rightDown.x /= currentWidth / factor;
                position.leftUp.y    -= (currentHeight + fontTexture.GlyphHeight) / 2.0f;
                position.leftDown.y  -= (currentHeight + fontTexture.GlyphHeight) / 2.0f;
                position.rightUp.y   -= (currentHeight + fontTexture.GlyphHeight) / 2.0f;
                position.rightDown.y -= (currentHeight + fontTexture.GlyphHeight) / 2.0f;

                position.leftUp.x    /= (currentHeight + fontTexture.GlyphHeight);
                position.leftDown.x  /= (currentHeight + fontTexture.GlyphHeight);
                position.rightUp.x   /= (currentHeight + fontTexture.GlyphHeight);
                position.rightDown.x /= (currentHeight + fontTexture.GlyphHeight);
                position.leftUp.y    /= (currentHeight + fontTexture.GlyphHeight);
                position.leftDown.y  /= (currentHeight + fontTexture.GlyphHeight);
                position.rightUp.y   /= (currentHeight + fontTexture.GlyphHeight);
                position.rightDown.y /= (currentHeight + fontTexture.GlyphHeight);
                array[i]              = position;
            }
            this.positionBuffer.UnmapBuffer();
        }
Пример #8
0
        private static void BlitCharacter(int pixelSize, int maxWidth, FullDictionary <char, CharacterInfo> dict, ref int currentX, ref int currentY, Graphics g, FontFace typeface, char c)
        {
            if (c == ' ')
            {
                int width = pixelSize / 3;
                if (currentX + xInterval + width >= maxWidth)
                {
                    currentX  = 0;
                    currentY += yInterval + pixelSize;
                    if (currentY + yInterval + pixelSize >= maxWidth)
                    {
                        throw new Exception("Texture Size not big enough for reuqired characters.");
                    }
                }
                Bitmap glyphBitmap = new Bitmap(width + xInterval, pixelSize + yInterval);
                //float yoffset = pixelSize * 3 / 4 - glyph.HorizontalMetrics.Bearing.Y;
                g.DrawImage(glyphBitmap, currentX + xInterval, currentY + yInterval);
                CharacterInfo info = new CharacterInfo(currentX, currentY, width + xInterval, pixelSize + yInterval);
                dict.Add(c, info);
                glyphBitmap.Dispose();
                currentX += width;
            }
            else
            {
                Surface surface; Glyph glyph;
                if (RenderGlyph(typeface, c, pixelSize, out surface, out glyph))
                {
                    if (currentX + xInterval + surface.Width >= maxWidth)
                    {
                        currentX  = 0;
                        currentY += yInterval + pixelSize;
                        if (currentY + yInterval + pixelSize >= maxWidth)
                        {
                            throw new Exception("Texture Size not big enough for reuqired characters.");
                        }
                    }
                    Bitmap    glyphBitmap = GetGlyphBitmap(surface);
                    const int a           = 5;
                    const int b           = 8;
                    //float yoffset = pixelSize * a / b - glyph.HorizontalMetrics.Bearing.Y;
#if DEBUG
                    g.DrawRectangle(redPen, currentX + xInterval, currentY + yInterval + pixelSize * a / b - glyph.HorizontalMetrics.Bearing.Y, glyphBitmap.Width, glyphBitmap.Height);
                    g.DrawRectangle(greenPen, currentX, currentY, glyphBitmap.Width + xInterval, yInterval + pixelSize - 1);
#endif
                    g.DrawImage(glyphBitmap, currentX + xInterval, currentY + yInterval + pixelSize * a / b - glyph.HorizontalMetrics.Bearing.Y, glyphBitmap.Width, glyphBitmap.Height);
                    CharacterInfo info = new CharacterInfo(currentX, currentY, glyphBitmap.Width + xInterval, yInterval + pixelSize - 1);
                    dict.Add(c, info);
                    glyphBitmap.Dispose();
                    currentX += xInterval + surface.Width;
                }

                surface.Dispose();
            }
        }
Пример #9
0
        private static int GetTextureWidth(FullDictionary <char, GlyphInfo> fullDictionary)
        {
            int totalAera = 0;

            foreach (var item in fullDictionary)
            {
                int area = item.Value.width * item.Value.height;
                totalAera += area;
            }

            return((int)Math.Sqrt(totalAera));
        }
Пример #10
0
        public static FullDictionary <char, CharacterInfo> Parse(XElement xElement)
        {
            FullDictionary <char, CharacterInfo> result = new FullDictionary <char, CharacterInfo>(
                CharacterInfo.Default);

            foreach (var item in xElement.Elements(KeyValuePairHelper.strKeyValuePair))
            {
                KeyValuePair <char, CharacterInfo> pair = KeyValuePairHelper.Parse(item);
                result.Add(pair.Key, pair.Value);
            }

            return(result);
        }
Пример #11
0
        private static int GetGlyphHeight(FullDictionary <char, GlyphInfo> fullDictionary, int textureWidth)
        {
            int glyphHeight = 0;

            foreach (var item in fullDictionary)
            {
                int height = item.Value.height;
                if (glyphHeight < height)
                {
                    glyphHeight = height;
                }
            }

            return(glyphHeight);
        }
Пример #12
0
        unsafe private void SetupGlyphPositions(string content, IFontTexture fontTexture)
        {
            FullDictionary <char, GlyphInfo> charInfoDict = fontTexture.GlyphInfoDictionary;
            IntPtr pointer = this.positionBuffer.MapBuffer(MapBufferAccess.ReadWrite);
            var    array = (TextModel.GlyphPosition *)pointer.ToPointer();
            float  currentWidth = 0; int currentHeight = 0;

            /*
             * 0     3  4     7 8     11 12   15
             * -------  ------- -------  -------
             * |     |  |     | |     |  |     |
             * |     |  |     | |     |  |     |
             * |     |  |     | |     |  |     |
             * -------  ------- -------  -------
             * 1     2  5     6 9     10 13   14
             */
            for (int i = 0; i < content.Length; i++)
            {
                char      ch   = content[i];
                GlyphInfo info = charInfoDict[ch];
                array[i] = new TextModel.GlyphPosition(
                    new vec2(currentWidth, currentHeight + fontTexture.GlyphHeight),
                    new vec2(currentWidth, currentHeight),
                    new vec2(currentWidth + info.width, currentHeight),
                    new vec2(currentWidth + info.width, currentHeight + fontTexture.GlyphHeight));
                currentWidth += info.width + fontTexture.GlyphHeight / 10;
            }

            switch (this.Alignment)
            {
            case TextAlignment.Center:
                Move2Center(content, array, currentWidth, currentHeight, fontTexture);
                break;

            case TextAlignment.Left:
                Move2Left(content, array, currentWidth, currentHeight, fontTexture);
                break;

            case TextAlignment.Right:
                Move2Right(content, array, currentWidth, currentHeight, fontTexture);
                break;

            default:
                break;
            }

            this.positionBuffer.UnmapBuffer();
        }
Пример #13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stream">".ttf", or ".otf"</param>
        /// <param name="pixelSize">The desired size of the font, in pixels.</param>
        /// <returns></returns>
        private static FontResource Load(Stream stream,
                                         char firstChar, char lastChar, int pixelSize = 32)
        {
            InitStandardWidths();

            int count    = lastChar - firstChar + 1;
            int maxWidth = GetMaxWidth(pixelSize, count);

            var fontResource = new FontResource();

            fontResource.FontHeight = pixelSize + yInterval;
            var dict = new FullDictionary <char, CharacterInfo>(CharacterInfo.Default);

            fontResource.CharInfoDict = dict;
            var      bitmap = new Bitmap(maxWidth, maxWidth, PixelFormat.Format24bppRgb);
            int      currentX = 0, currentY = 0;
            Graphics g = Graphics.FromImage(bitmap);

            /*
             * this.FontHeight = int.Parse(config.Attribute(strFontHeight).Value);
             * this.CharInfoDict = CharacterInfoDictHelper.Parse(
             *  config.Element(CharacterInfoDictHelper.strCharacterInfoDict));
             */
            //using (var file = File.OpenRead(ttfFilename))
            {
                var typeface = new FontFace(stream);

                for (char c = firstChar; c <= lastChar; c++)
                {
                    BlitCharacter(pixelSize, maxWidth, dict, ref currentX, ref currentY, g, typeface, c);

                    if (c == char.MaxValue)
                    {
                        break;
                    }
                }
            }

            g.Dispose();
            Bitmap finalBitmap = ShortenBitmap(bitmap, maxWidth, currentY + yInterval + pixelSize + (pixelSize / 10 > 1 ? pixelSize / 10 : 1));

            bitmap.Dispose();
            fontResource.InitTexture(finalBitmap);
            finalBitmap.Dispose();

            return(fontResource);
        }
Пример #14
0
        private static int LayoutGlyphs(FullDictionary <char, GlyphInfo> fullDictionary, int textureWidth, int glyphHeight)
        {
            int cursorX = 0, cursorY = 0;

            foreach (var item in fullDictionary)
            {
                int width  = item.Value.width;
                int height = item.Value.height;
                if (cursorX + width > textureWidth)
                {
                    cursorX  = 0;
                    cursorY += glyphHeight;
                }

                item.Value.xoffset = cursorX;
                item.Value.yoffset = cursorY;

                cursorX += width;
            }

            return(cursorY + glyphHeight);
        }
Пример #15
0
        private static FontResource LoadFromSomeChars(Stream stream, int pixelSize, IEnumerable <char> targets)
        {
            FontResource fontResource;

            int count    = targets.Count();
            int maxWidth = GetMaxWidth(pixelSize, count);

            fontResource            = new FontResource();
            fontResource.FontHeight = pixelSize + yInterval;
            var dict = new FullDictionary <char, CharacterInfo>(CharacterInfo.Default);

            fontResource.CharInfoDict = dict;
            var      bitmap = new Bitmap(maxWidth, maxWidth, PixelFormat.Format24bppRgb);
            int      currentX = 0, currentY = 0;
            Graphics g = Graphics.FromImage(bitmap);

            /*
             * this.FontHeight = int.Parse(config.Attribute(strFontHeight).Value);
             * this.CharInfoDict = CharacterInfoDictHelper.Parse(
             *  config.Element(CharacterInfoDictHelper.strCharacterInfoDict));
             */
            {
                var typeface = new FontFace(stream);

                foreach (char c in targets)
                {
                    BlitCharacter(pixelSize, maxWidth, dict, ref currentX, ref currentY, g, typeface, c);
                }
            }

            g.Dispose();
            Bitmap finalBitmap = ShortenBitmap(bitmap, maxWidth, currentY + yInterval + pixelSize + (pixelSize / 10 > 1 ? pixelSize / 10 : 1));

            bitmap.Dispose();
            fontResource.InitTexture(finalBitmap);
            finalBitmap.Dispose();
            return(fontResource);
        }
Пример #16
0
        unsafe private void SetupGlyphTexCoord(string content, FontResource fontResource)
        {
            FullDictionary <char, CharacterInfo> charInfoDict = fontResource.CharInfoDict;

            OpenGL.BindBuffer(BufferTarget.ArrayBuffer, this.model.uvBufferPtr.BufferId);
            IntPtr pointer = OpenGL.MapBuffer(BufferTarget.ArrayBuffer, MapBufferAccess.WriteOnly);
            var    array   = (GlyphTexCoord *)pointer.ToPointer();
            int    width   = fontResource.TextureSize.Width;
            int    height  = fontResource.TextureSize.Height;

            /*
             * 0     3  4     6 8     11 12   15
             * -------  ------- -------  -------
             * |     |  |     | |     |  |     |
             * |     |  |     | |     |  |     |
             * |     |  |     | |     |  |     |
             * -------  ------- -------  -------
             * 1     2  5     6 9     10 13   14
             */
            for (int i = 0; i < content.Length; i++)
            {
                char          ch     = content[i];
                CharacterInfo info   = fontResource.CharInfoDict[ch];
                const int     shrimp = 0;
                array[i] = new GlyphTexCoord(
                    //new vec2(0, 0),
                    //new vec2(0, 1),
                    //new vec2(1, 1),
                    //new vec2(1, 0)
                    new vec2((float)(info.xoffset + shrimp) / (float)width, (float)(info.yoffset) / (float)height),
                    new vec2((float)(info.xoffset + shrimp) / (float)width, (float)(info.yoffset + info.height) / (float)height),
                    new vec2((float)(info.xoffset - shrimp + info.width) / (float)width, (float)(info.yoffset + info.height) / (float)height),
                    new vec2((float)(info.xoffset - shrimp + info.width) / (float)width, (float)(info.yoffset) / (float)height)
                    );
            }
            OpenGL.UnmapBuffer(BufferTarget.ArrayBuffer);
            OpenGL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }
Пример #17
0
 internal FontBitmap()
 {
     this.GlyphInfoDictionary = new FullDictionary <char, GlyphInfo>(GlyphInfo.Default);
 }