示例#1
0
    public Vector2 GetTextSize(string inText)
    {
        // TODO ::  computing height is not correct there can be fonts with glyphs which has
        //          different height and y offset. So for example [ _ , ~ ] can have same height
        //			but lie on different base line.

        Vector2 size = Vector2.zero;

        if (Initialize() == true)
        {
            foreach (char ch in inText)
            {
                BitmapCharacter bc = GetCharacterInfo(ch);
                if (bc == null)
                {
                    continue;
                }

                size.x += (bc.XAdvance * m_CorrectionFontSizeScale);
                size.y  = Mathf.Max(size.y, bc.Height * m_CorrectionFontSizeScale);
            }
        }

        return(size);
    }
示例#2
0
    protected float GetPhaseByPosition(BitmapCharacter _Character, float _Size, float _Phase)
    {
        if (_Character == null)
        {
            return(_Phase);
        }

        Rect rect = Rect;

        return(_Phase - (_Character.Rect.center.x - rect.x) / (_Size * CharSize));
    }
示例#3
0
    protected float GetPhaseBySeed(BitmapCharacter _Character, int _Seed, float _Phase)
    {
        if (_Character == null)
        {
            return(_Phase);
        }

        Random.InitState(_Character.Index + _Seed);

        return(_Phase - Random.value);
    }
示例#4
0
    public float GetCharWidth(int inCharacter)
    {
        if (Initialize() == false)
        {
            return(0.0f);
        }

        BitmapCharacter c = GetCharacterInfo(inCharacter);

        if (c == null)
        {
            return(0.0f);
        }

        float xAdvance = c.XAdvance * m_CorrectionFontSizeScale;

        return(xAdvance);
    }
示例#5
0
        public override object Read(ContentReader reader)
        {
            Texture2D  texture = reader.ReadObjectRaw <Texture2D>();
            BitmapFont font    = new BitmapFont(_shader);

            font.Texture = texture;
            font.CharacterSet.LineHeight   = reader.ReadInt32();
            font.CharacterSet.Base         = reader.ReadInt32();
            font.CharacterSet.RenderedSize = reader.ReadInt32();
            font.CharacterSet.PaddingUp    = reader.ReadInt32();
            font.CharacterSet.PaddingRight = reader.ReadInt32();
            font.CharacterSet.PaddingDown  = reader.ReadInt32();
            font.CharacterSet.PaddingLeft  = reader.ReadInt32();
            font.CharacterSet.Width        = texture.Width;
            font.CharacterSet.Height       = texture.Height;
            int characterCount = reader.ReadInt32();

            for (int i = 0; i < characterCount; i++)
            {
                BitmapCharacter character = new BitmapCharacter();
                character.ID       = reader.ReadInt32();
                character.X        = reader.ReadInt32();
                character.Y        = reader.ReadInt32();
                character.Width    = reader.ReadInt32();
                character.Height   = reader.ReadInt32();
                character.XOffset  = reader.ReadInt32();
                character.YOffset  = reader.ReadInt32();
                character.XAdvance = reader.ReadInt32();
                int kerningCount = reader.ReadInt32();
                for (int j = 0; j < kerningCount; j++)
                {
                    int key   = reader.ReadInt32();
                    int value = reader.ReadInt32();
                    character.Kerning[key] = value;
                }
                font.CharacterSet.Characters.Add(character);
            }

            font.Ascent  = font.CharacterSet.Characters.Where(c => c.ID > 33 && c.ID < 127).Max(c => c.YOffset);
            font.Descent = font.CharacterSet.Characters.Where(c => c.ID > 33 && c.ID < 127).Max(c => c.Height - c.YOffset);

            return(font);
        }
示例#6
0
        /// <summary>
        ///     Create new empty bitmap font
        /// </summary>
        /// <param name="getPixel">Given i,j in the source image, return the pixel in ARGB format</param>
        public BitmapFont(string name, int lineHeight, int base1, int renderedSize, int[] charDefs,
                          Func <int, int, uint> getPixel, int width = -1)
        {
            Name         = name;
            LineHeight   = lineHeight;
            Base         = base1;
            RenderedSize = renderedSize;
            Width        = width;

            Characters  = new BitmapCharacter[256];
            KerningList = new List <Kerning>();

            for (var i = 0; i < charDefs.Length; i += 10)
            {
                var id       = charDefs[i + 0];
                var x        = charDefs[i + 1];
                var y        = charDefs[i + 2];
                var w        = charDefs[i + 3];
                var h        = charDefs[i + 4];
                var xoffset  = charDefs[i + 5];
                var yoffset  = charDefs[i + 6];
                var xadvance = charDefs[i + 7];
                var page     = charDefs[i + 8];
                var chnl     = charDefs[i + 9];
                var c        = new BitmapCharacter(id, x, y, w, h, xoffset, yoffset, xadvance, page, chnl, getPixel);
                Characters[id] = c;
            }
            // fill rest
            for (var i = 0; i < 256; i++)
            {
                if (Characters[i] == null)
                {
                    Characters[i] = new BitmapCharacter();
                }
            }
        }
示例#7
0
    /*void OnGUI()
     * {
     *      if(Event.current.type.Equals(EventType.Repaint))
     *      {
     *              //Rect screenRect = new Rect(0, 0, 500, 500);
     *              //Rect sourceRect = new Rect(0, 0, 1, 1);
     *              //Graphics.DrawTexture(screenRect, m_Texture, sourceRect, 0, 0, 0, 0);// mat);
     *
     *              //string testString = "This . is test\\ //,# string ygpd W";
     *              string testString = "John: Damn it... that didn't go well.";
     *
     *              float x = Screen.width*0.4f;
     *              float y = 120;
     *
     *              Rect screenRect, sourceRect;
     *              float width;
     *              for(int i = 0; i < testString.Length; i++)
     *              {
     *                      if(GetCharDescription(testString[i], out width, out screenRect, out sourceRect))
     *                      {
     *                              screenRect.x += x;
     *                              screenRect.y += y;
     *
     *                              Graphics.DrawTexture(screenRect, m_Texture, sourceRect, 0, 0, 0, 0, m_Material);
     *
     *                              x += width;
     *                      }
     *              }
     *      }
     * }*/

    public bool GetCharDescription(int inCharacter,
                                   out float outWidth,
                                   out Rect outSprite,
                                   out Rect outTexUV,
                                   bool inNormalizeTextCoord = true,
                                   bool inFliped             = true,
                                   bool inFixHeightForGUI    = true)
    {
        outWidth  = 0;
        outSprite = new Rect();
        outTexUV  = new Rect();

        if (Initialize() == false)
        {
            return(false);
        }

        BitmapCharacter c = GetCharacterInfo(inCharacter);

        if (c == null)
        {
            return(false);
        }

        float xOffset  = c.XOffset * m_CorrectionFontSizeScale;
        float yOffset  = c.YOffset * m_CorrectionFontSizeScale;
        float xAdvance = c.XAdvance * m_CorrectionFontSizeScale;
        float width    = c.Width * m_CorrectionFontSizeScale;
        float height   = c.Height * m_CorrectionFontSizeScale;

        if (inFixHeightForGUI)
        {
            yOffset /= (float)m_CharSet.Height;
            height  /= (float)m_CharSet.Height * texHeightFixupCoef;
        }

        outWidth  = xAdvance;
        outSprite = new Rect(xOffset, yOffset, width, height);

        float texU = (float)c.X;
        float texV = (float)c.Y;
        float texW = (float)c.Width;
        float texH = (float)c.Height;

        if (inFliped == true)
        {
            outTexUV = new Rect(texU, m_CharSet.Height - (texV + texH), texW, texH);
        }
        else
        {
            outTexUV = new Rect(texU, texV, texW, texH);
        }

        if (inNormalizeTextCoord == true)
        {
            outTexUV.x      /= (float)m_CharSet.Width;
            outTexUV.y      /= (float)m_CharSet.Height;
            outTexUV.width  /= (float)m_CharSet.Width;
            outTexUV.height /= (float)m_CharSet.Height;
        }
        else
        {
            outTexUV.x      *= (float)texWidthFixupCoef;
            outTexUV.y      *= (float)texHeightFixupCoef;
            outTexUV.width  *= (float)texWidthFixupCoef;
            outTexUV.height *= (float)texHeightFixupCoef;
        }

        return(true);
    }
示例#8
0
    void ProcessCharacters()
    {
        Scale = 1;

        if (m_TagText == null)
        {
            m_TagText = new TagText();
        }

        m_TagText.Load(Text);

        if (m_Lines == null)
        {
            m_Lines = new List <BitmapLine>();
        }
        else
        {
            m_Lines.Clear();
        }

        if (m_Characters == null)
        {
            m_Characters = new List <BitmapCharacter>();
        }

        int delta = m_TagText.Text.Length - m_Characters.Count;

        for (int i = 0; i < delta; i++)
        {
            m_Characters.Add(new BitmapCharacter());
        }

        for (int i = 0; i < m_Characters.Count; i++)
        {
            if (m_Characters[i] == null)
            {
                m_Characters[i] = new BitmapCharacter();
            }

            BitmapCharacter character = m_Characters[i];

            character.Index   = -1;
            character.Enabled = false;
            character.Visible = false;
            character.Tint    = Color.white;
            character.Offset  = Vector2.zero;
        }

        List <BitmapCharacter> line = new List <BitmapCharacter>();
        int index = 0;

        for (int i = 0; i < m_TagText.Text.Length; i++)
        {
            if (m_TagText.Text[i] == '\n')
            {
                m_Lines.Add(new BitmapLine(line));
                line.Clear();

                index++;
                continue;
            }

            BitmapCharacter character = m_Characters[index];

            character.Index     = i;
            character.Enabled   = true;
            character.Character = m_TagText.Text[i];

            BitmapGlyph glyph = Font.GetGlyph(character.Character);
            if (glyph != null)
            {
                Rect glyphRect = glyph.Rect;
                character.Visible        = true;
                character.Rect           = glyphRect.Scale(CharSize);
                character.BaselineOffset = glyph.Offset * CharSize;
                character.LineHeight     = Font.Ascender * CharSize;
                character.UV             = glyph.UV;
                character.Color          = color;
            }
            else if (character.Character == ' ')
            {
                Rect glyphRect = new Rect(0, 0, Font.SpaceWidth, 0);

                character.Visible = false;
                character.Rect    = glyphRect.Scale(CharSize);
            }

            line.Add(character);

            index++;
        }
        m_Lines.Add(new BitmapLine(line));
        line.Clear();
    }
示例#9
0
        protected void DrawString(int x, int y, string s, BitmapFont font, int size)
        {
            float curX = x;
            float curY = y;

            List <VertexPositionTexture> vertexData = new List <VertexPositionTexture>();
            List <int> indexData = new List <int>();

            float scale = size / (float)font.CharacterSet.RenderedSize;

            int  i = 0;
            bool firstCharacter = true;

            foreach (char c in s)
            {
                BitmapCharacter bc = font.CharacterSet.GetCharacterByID((int)c);

                float xOffset  = bc.XOffset * scale;
                float yOffset  = bc.YOffset * scale;
                float xAdvance = bc.XAdvance * scale;
                float width    = bc.Width * scale;
                float height   = bc.Height * scale;

                // create the quads triangles for this character
                // uper left
                //vertexData.Add(new VertexPositionTexture(curX + (bc.XOffset + font.CharacterSet.PaddingLeft )* scale, curY + (font.Ascent - bc.YOffset - font.CharacterSet.PaddingUp) * scale, 0, (float)bc.X / (float)font.CharacterSet.Width, (float)bc.Y / (float)font.CharacterSet.Height));
                vertexData.Add(new VertexPositionTexture(curX + xOffset, curY + yOffset, 0, (float)bc.X / (float)font.CharacterSet.Width, (float)bc.Y / (float)font.CharacterSet.Height));
                // upper right
                //vertexData.Add(new VertexPositionTexture(curX + width, curY + (font.Ascent - bc.YOffset - font.CharacterSet.PaddingUp) * scale, 0, (float)(bc.X + bc.Width) / (float)font.CharacterSet.Width, (float)bc.Y / (float)font.CharacterSet.Height));
                vertexData.Add(new VertexPositionTexture(curX + xOffset + width, curY + yOffset, 0, (float)(bc.X + bc.Width) / (float)font.CharacterSet.Width, (float)bc.Y / (float)font.CharacterSet.Height));
                // lower right
                //vertexData.Add(new VertexPositionTexture(curX + bc.Width * scale + bc.XOffset * scale, curY + (font.Ascent - bc.YOffset + bc.Height) * scale, 0, (float)(bc.X + bc.Width) / (float)font.CharacterSet.Width, (float)(bc.Y + bc.Height) / (float)font.CharacterSet.Height));
                vertexData.Add(new VertexPositionTexture(curX + xOffset + width, curY + yOffset + height, 0, (float)(bc.X + bc.Width) / (float)font.CharacterSet.Width, (float)(bc.Y + bc.Height) / (float)font.CharacterSet.Height));
                // lower left
                //vertexData.Add(new VertexPositionTexture(curX + bc.XOffset * scale, curY + (font.Ascent - bc.YOffset + bc.Height) * scale, 0, (float)bc.X / (float)font.CharacterSet.Width, (float)(bc.Y + bc.Height) / (float)font.CharacterSet.Height));
                vertexData.Add(new VertexPositionTexture(curX + xOffset, curY + yOffset + height, 0, (float)bc.X / (float)font.CharacterSet.Width, (float)(bc.Y + bc.Height) / (float)font.CharacterSet.Height));
                indexData.Add(i);
                indexData.Add(i + 1);
                indexData.Add(i + 2);
                indexData.Add(i + 2);
                indexData.Add(i + 3);
                indexData.Add(i);
                i += 4;



                curX += bc.XAdvance * scale;
            }

            VertexBuffer positionVbo = VertexBuffer.Create(VertexFormat.PositionTexture, vertexData.ToArray());
            IndexBuffer  indexVbo    = IndexBuffer.Create(indexData.ToArray());
            VertexArray  vao         = new VertexArray(positionVbo, indexVbo);

            vao.AddBinding(shader.VertexAttribute("vert").Slot, VertexUsage.Position);
            vao.AddBinding(shader.VertexAttribute("vertTexCoord").Slot, VertexUsage.TextureCoordinate);
            vao.Bind();

            font.Shader.Bind();
            font.Shader.Uniform1("tex", 0);
            GL.ActiveTexture(TextureUnit.Texture0);
            font.Texture.Bind();
            indexVbo.Bind();
            GL.DrawElements(BeginMode.Triangles, indexVbo.Length,
                            DrawElementsType.UnsignedInt, IntPtr.Zero);
        }
示例#10
0
        /// <summary>
        /// Create a font from a file.
        /// Return null if an error.
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public static BitmapFont ReadFile(string filename)
        {
            var font  = new BitmapFont();
            var bytes = File.ReadAllBytes(filename);

            // start with ASCII "BMF"
            if (bytes.Length < 3 || bytes[0] != 66 || bytes[1] != 77 || bytes[2] != 70)
            {
                return(null); // wrong header
            }
            var version = bytes[3];

            if (version > 3)
            {
                return(null); // unsupported version
            }
            var index = 4;    // start here

            Func <int, int> Read = n =>
            {
                var val = 0;
                for (var i = 0; i < n; ++i)
                {
                    val = bytes[index++];
                }
                return(val);
            };
            Func <int, uint> ReadU = n => (uint)Read(n);
            int pages = 0;

            while (index < bytes.Length)
            {
                var type = bytes[index++];
                var size = Read(4);      // block size, not including type and 4 byte size field
                var next = size + index; // should end here
                switch (type)
                {
                case 1:                     // general info - how font was generated
                {
                    var fontSize = Read(2); // size of TT font
                    var bits     = Read(1);
                    // bit 0: smooth, bit 1: unicode, bit 2: italic, bit 3: bold, bit 4: fixedHeight, bits 5-7: reserved
                    var smooth      = (bits & 1) != 0;     // smoothing was on
                    var unicode     = (bits & 2) != 0;     // a unicode charset
                    var italic      = (bits & 4) != 0;     // font is italic
                    var bold        = (bits & 8) != 0;     // font is bold
                    var fixedHeight = (bits & 16) != 0;

                    var charSet      = Read(1); // name of OEM charset, when not Unicode
                    var stretchH     = Read(2); // 100% means no stretch
                    var aa           = Read(1); // supersampling level used
                    var paddingUp    = Read(1);
                    var paddingRight = Read(1);
                    var paddingDown  = Read(1);
                    var paddingLeft  = Read(1);
                    var spacingH     = Read(1);
                    var spacingV     = Read(1);    // character spacing
                    var outline      = Read(1);    // outline thickness
                    var sb           = new StringBuilder();
                    while (bytes[index] != 0)
                    {
                        sb.Append((char)bytes[index++]);
                    }
                    var name = sb.ToString(); // name of true type font used
                    index++;                  // skip 0
                }

                break;

                case 2:                                   // common
                {
                    font.LineHeight = Read(2);            // uint 0
                    font.Base       = Read(2);            // uint 2
                    var scaleW = Read(2);                 // uint 4
                    var scaleH = Read(2);                 // uint 6
                    pages = Read(2);                      // uint 8 number of texture pages
                    var bitField = Read(1);               // bits 10 bits 0-6: reserved, bit 7: packed
                    var packed   = (bitField & 128) != 0; // if packed, each color channel has monochrome characters and alpha channel describes what's in channels

                    // each channel: Set to 0 if the channel holds the glyph data, 1 if it holds the outline, 2 if it holds the glyph and the outline, 3 if its set to zero, and 4 if its set to one.
                    var alphaChnl = Read(1);       // uint 11
                    var redChnl   = Read(1);       //uint 12
                    var greenChnl = Read(1);       //uint 13
                    var blueChnl  = Read(1);       //uint 14
                }

                break;

                case 3:     // page names for textures
                {
                    for (var i = 0; i < pages; ++i)
                    {
                        var sb = new StringBuilder();
                        while (bytes[index] != 0)
                        {
                            sb.Append((char)bytes[index++]);
                        }
                        var name = sb.ToString();
                        index++;         // skip 0
                    }
                }
                break;

                case 4:     // chars
                {
                    // The number of characters in the file can be computed by taking the size of
                    // the block and dividing with the size of the charInfo structure, i.e.: numChars = charsBlock.blockSize/20.
                    if ((size % 20) != 0)
                    {
                        return(null);        // wrong size
                    }
                    var num = size / 20;
                    for (var i = 0; i < num; ++i)
                    {
                        var c  = new BitmapCharacter();
                        var id = Read(4);      // character ID (unicode?)
                        //uint 0+c*20 These fields are repeated until all characters have been described
                        c.X        = Read(2);  // uint 4+c*20   texture X position
                        c.Y        = Read(2);  //uint 6+c*20    texture Y position
                        c.Width    = Read(2);  //uint 8+c*20  texture width
                        c.Height   = Read(2);  //uint 10+c*20  texture height
                        c.XOffset  = Read(2);  // int 12+c*20  offset when copying to screen
                        c.YOffset  = Read(2);  // int 14+c*20
                        c.XAdvance = Read(2);  //int 16+c*20  advance after drawing character
                        var page = Read(1);    // uint 18+c*20   // texture page where character is found
                        var chnl = Read(1);    // uint 19+c*20 // texture where found (1=blue,2-green,4-red,8=alpha,15=all channels)
                        font.Characters[id] = c;
                    }
                }
                break;

                case 5:     // kerning pairs
                {
                    if ((size % 10) != 0)
                    {
                        return(null);        // wrong size
                    }
                    var num = size / 10;
                    for (var i = 0; i < num; ++i)
                    {
                        // This block is only in the file if there are any kerning pairs with amount differing from 0.
                        var k = new Kerning();
                        // uint 0+c*10 These fields are repeated until all kerning pairs have been described
                        k.First  = Read(4);        // first character id
                        k.Second = Read(4);        // uint 4+c*10  second character id
                        k.Amount = Read(2);        // int 8+c*6 amount to adjust x position
                        font.KerningList.Add(k);
                    }
                }
                break;

                default:
                    return(null);    // unknown block type
                }
                if (next != index)
                {
                    return(null); // wrong block size
                }
            }

            return(font);
        }
示例#11
0
 /// <summary>Clones the BitmapCharacter</summary>
 /// <returns>Cloned BitmapCharacter</returns>
 public object Clone()
 {
     BitmapCharacter result = new BitmapCharacter();
     result.X = X;
     result.Y = Y;
     result.Width = Width;
     result.Height = Height;
     result.XOffset = XOffset;
     result.YOffset = YOffset;
     result.XAdvance = XAdvance;
     result.KerningList.AddRange( KerningList );
     return result;
 }