Beispiel #1
0
    void CalcAnchor(out float offsetX, out float offsetY)
    {
        if (_font != null)
        {
            // calc string width
            float maxWidth = 0.0f;
            float width    = 0.0f;
            int   numLines = 1;

            for (int i = 0; i < _maxChars && i < _text.Length; ++i)
            {
                if (_text[i] == '\n')
                {
                    numLines++;
                    maxWidth = Mathf.Max(maxWidth, width);
                    width    = 0.0f;
                }
                else
                {
                    tk2dFontChar chr = _font.chars[_text[i]];
                    width += chr.advance * _scale.x;
                }
            }

            maxWidth = Mathf.Max(maxWidth, width);
            float lineHeight = _font.lineHeight * _scale.y;
            float height     = lineHeight * numLines;

            switch (_anchor)
            {
            case TextAnchor.LowerLeft: offsetX = 0.0f;  offsetY = height - lineHeight; break;

            case TextAnchor.MiddleLeft: offsetX = 0.0f; offsetY = height / 2.0f - lineHeight; break;

            case TextAnchor.UpperLeft: offsetX = 0.0f;  offsetY = -lineHeight; break;

            case TextAnchor.LowerCenter: offsetX = -maxWidth / 2.0f;    offsetY = height - lineHeight; break;

            case TextAnchor.MiddleCenter: offsetX = -maxWidth / 2.0f;   offsetY = height / 2.0f - lineHeight; break;

            case TextAnchor.UpperCenter: offsetX = -maxWidth / 2.0f;    offsetY = -lineHeight; break;

            case TextAnchor.LowerRight: offsetX = -maxWidth;    offsetY = height - lineHeight; break;

            case TextAnchor.MiddleRight: offsetX = -maxWidth;   offsetY = height / 2.0f - lineHeight; break;

            case TextAnchor.UpperRight: offsetX = -maxWidth;    offsetY = -lineHeight; break;

            default:
                offsetX = 0.0f;
                offsetY = 0.0f;
                break;
            }
        }
        else
        {
            offsetX = 0.0f;
            offsetY = 0.0f;
        }
    }
Beispiel #2
0
    /// <summary>
    /// Calculates the mesh dimensions for the given string
    /// and returns a width and height.
    /// </summary>
    public static Vector2 GetMeshDimensionsForString(this tk2dTextMeshData geomData, tk2dColoredText inputText, int startIdx, int count)
    {
        tk2dTextMeshData data      = geomData;
        tk2dFontData     _fontInst = data.FontInst;

        float maxWidth = 0.0f;

        float cursorX = 0.0f;
        float cursorY = 0.0f;

        for (int i = startIdx; (i < inputText.Length) && (i < (startIdx + count)); ++i)
        {
            int idx = inputText[i];
            if (idx == '\n')
            {
                maxWidth = Mathf.Max(cursorX, maxWidth);
                cursorX  = 0.0f;
                cursorY -= data.ActualLineSpaceHeight;
            }
            else
            {
                // Get the character from dictionary / array
                tk2dFontChar chr = _fontInst.GetCharForIndex(idx, 0);

                cursorX += (chr.advance + data.Spacing) * data.TotalScale.x;
                if (data.kerning && i < inputText.Length - 1)
                {
                    foreach (var k in _fontInst.kerning)
                    {
                        if (k.c0 == inputText[i] && k.c1 == inputText[i + 1])
                        {
                            cursorX += k.amount * data.TotalScale.x;
                            break;
                        }
                    }
                }
            }
        }

        maxWidth = Mathf.Max(cursorX, maxWidth);
        cursorY -= data.ActualLineHeight;

        return(new Vector2(maxWidth, cursorY));
    }
Beispiel #3
0
        public static bool BuildFont(Info fontInfo, tk2dFontData target, float scale, int charPadX, bool dupeCaps, bool flipTextureY, Texture2D gradientTexture, int gradientCount)
        {
            float texWidth = fontInfo.scaleW;
            float texHeight = fontInfo.scaleH;
            float lineHeight = fontInfo.lineHeight;

            target.lineHeight = lineHeight * scale;

            // Get number of characters (lastindex + 1)
            int maxCharId = 0;
            int maxUnicodeChar = 100000;
            foreach (var theChar in fontInfo.chars)
            {
                if (theChar.id > maxUnicodeChar)
                {
                    // in most cases the font contains unwanted characters!
                    Debug.LogError("Unicode character id exceeds allowed limit: " + theChar.id.ToString() + ". Skipping.");
                    continue;
                }

                if (theChar.id > maxCharId) maxCharId = theChar.id;
            }

            // decide to use dictionary if necessary
            // 2048 is a conservative lower floor
            bool useDictionary = maxCharId > 2048;

            Dictionary<int, tk2dFontChar> charDict = (useDictionary)?new Dictionary<int, tk2dFontChar>():null;
            tk2dFontChar[] chars = (useDictionary)?null:new tk2dFontChar[maxCharId + 1];
            int minChar = 0x7fffffff;
            int maxCharWithinBounds = 0;
            int numLocalChars = 0;
            float largestWidth = 0.0f;
            foreach (var theChar in fontInfo.chars)
            {
                tk2dFontChar thisChar = new tk2dFontChar();
                int id = theChar.id;
                int x = theChar.x;
                int y = theChar.y;
                int width = theChar.width;
                int height = theChar.height;
                int xoffset = theChar.xoffset;
                int yoffset = theChar.yoffset;
                int xadvance = theChar.xadvance + charPadX;

                // special case, if the width and height are zero, the origin doesn't need to be offset
                // handles problematic case highlighted here:
                // http://2dtoolkit.com/forum/index.php/topic,89.msg220.html
                if (width == 0 && height == 0)
                {
                    xoffset = 0;
                    yoffset = 0;
                }

                // precompute required data
                float px = xoffset * scale;
                float py = (lineHeight - yoffset) * scale;

                if (theChar.texOverride)
                {
                    int w = theChar.texW;
                    int h = theChar.texH;
                    if (theChar.texFlipped)
                    {
                        h = theChar.texW;
                        w = theChar.texH;
                    }

                    thisChar.p0 = new Vector3(px + theChar.texOffsetX * scale, py - theChar.texOffsetY * scale, 0);
                    thisChar.p1 = new Vector3(px + (theChar.texOffsetX + w) * scale, py - (theChar.texOffsetY + h) * scale, 0);

                    thisChar.uv0 = new Vector2((theChar.texX) / texWidth, (theChar.texY + theChar.texH) / texHeight);
                    thisChar.uv1 = new Vector2((theChar.texX + theChar.texW) / texWidth, (theChar.texY) / texHeight);

                    thisChar.flipped = theChar.texFlipped;
                }
                else
                {
                    thisChar.p0 = new Vector3(px, py, 0);
                    thisChar.p1 = new Vector3(px + width * scale, py - height * scale, 0);
                    if (flipTextureY)
                    {
                        thisChar.uv0 = new Vector2(x / texWidth, y / texHeight);
                        thisChar.uv1 = new Vector2(thisChar.uv0.x + width / texWidth, thisChar.uv0.y + height / texHeight);
                    }
                    else
                    {
                        thisChar.uv0 = new Vector2(x / texWidth, 1.0f - y / texHeight);
                        thisChar.uv1 = new Vector2(thisChar.uv0.x + width / texWidth, thisChar.uv0.y - height / texHeight);
                    }

                    thisChar.flipped = false;
                }
                thisChar.advance = xadvance * scale;
                largestWidth = Mathf.Max(thisChar.advance, largestWidth);

                // Needs gradient data
                if (gradientTexture != null)
                {
                    // build it up assuming the first gradient
                    float x0 = (float)(0.0f / gradientCount);
                    float x1 = (float)(1.0f / gradientCount);
                    float y0 = 1.0f;
                    float y1 = 0.0f;

                    // align to glyph if necessary

                    thisChar.gradientUv = new Vector2[4];
                    thisChar.gradientUv[0] = new Vector2(x0, y0);
                    thisChar.gradientUv[1] = new Vector2(x1, y0);
                    thisChar.gradientUv[2] = new Vector2(x0, y1);
                    thisChar.gradientUv[3] = new Vector2(x1, y1);
                }

                if (id <= maxCharId)
                {
                    maxCharWithinBounds = (id > maxCharWithinBounds) ? id : maxCharWithinBounds;
                    minChar = (id < minChar) ? id : minChar;

                    if (useDictionary)
                        charDict[id] = thisChar;
                    else
                        chars[id] = thisChar;

                    ++numLocalChars;
                }
            }

            // duplicate capitals to lower case, or vice versa depending on which ones exist
            if (dupeCaps)
            {
                for (int uc = 'A'; uc <= 'Z'; ++uc)
                {
                    int lc = uc + ('a' - 'A');

                    if (useDictionary)
                    {
                        if (charDict.ContainsKey(uc))
                            charDict[lc] = charDict[uc];
                        else if (charDict.ContainsKey(lc))
                            charDict[uc] = charDict[lc];
                    }
                    else
                    {
                        if (chars[lc] == null) chars[lc] = chars[uc];
                        else if (chars[uc] == null) chars[uc] = chars[lc];
                    }
                }
            }

            // share null char, same pointer
            var nullChar = new tk2dFontChar();
            nullChar.gradientUv = new Vector2[4]; // this would be null otherwise

            target.largestWidth = largestWidth;
            if (useDictionary)
            {
                // guarantee at least the first 256 characters
                for (int i = 0; i < 256; ++i)
                {
                    if (!charDict.ContainsKey(i))
                        charDict[i] = nullChar;
                }

                target.chars = null;
                target.SetDictionary(charDict);
                target.useDictionary = true;
            }
            else
            {
                target.chars = new tk2dFontChar[maxCharId + 1];
                for (int i = 0; i <= maxCharId; ++i)
                {
                    target.chars[i] = chars[i];
                    if (target.chars[i] == null)
                    {
                        target.chars[i] = nullChar; // zero everything, null char
                    }
                }

                target.charDict = null;
                target.useDictionary = false;
            }

            // kerning
            target.kerning = new tk2dFontKerning[fontInfo.kernings.Count];
            for (int i = 0; i < target.kerning.Length; ++i)
            {
                tk2dFontKerning kerning = new tk2dFontKerning();
                kerning.c0 = fontInfo.kernings[i].first;
                kerning.c1 = fontInfo.kernings[i].second;
                kerning.amount = fontInfo.kernings[i].amount * scale;
                target.kerning[i] = kerning;
            }

            return true;
        }
Beispiel #4
0
        public static bool BuildFont(Info fontInfo, tk2dFontData target, float scale, int charPadX, bool dupeCaps, bool flipTextureY, Texture2D gradientTexture, int gradientCount)
        {
            float texWidth   = fontInfo.scaleW;
            float texHeight  = fontInfo.scaleH;
            float lineHeight = fontInfo.lineHeight;

            target.lineHeight = lineHeight * scale;

            // Get number of characters (lastindex + 1)
            int maxCharId      = 0;
            int maxUnicodeChar = 100000;

            foreach (var theChar in fontInfo.chars)
            {
                if (theChar.id > maxUnicodeChar)
                {
                    // in most cases the font contains unwanted characters!
                    Debug.LogError("Unicode character id exceeds allowed limit: " + theChar.id.ToString() + ". Skipping.");
                    continue;
                }

                if (theChar.id > maxCharId)
                {
                    maxCharId = theChar.id;
                }
            }

            // decide to use dictionary if necessary
            // 2048 is a conservative lower floor
            bool useDictionary = maxCharId > 2048;

            Dictionary <int, tk2dFontChar> charDict = (useDictionary)?new Dictionary <int, tk2dFontChar>():null;

            tk2dFontChar[] chars               = (useDictionary)?null:new tk2dFontChar[maxCharId + 1];
            int            minChar             = 0x7fffffff;
            int            maxCharWithinBounds = 0;
            int            numLocalChars       = 0;
            float          largestWidth        = 0.0f;

            foreach (var theChar in fontInfo.chars)
            {
                tk2dFontChar thisChar = new tk2dFontChar();
                int          id       = theChar.id;
                int          x        = theChar.x;
                int          y        = theChar.y;
                int          width    = theChar.width;
                int          height   = theChar.height;
                int          xoffset  = theChar.xoffset;
                int          yoffset  = theChar.yoffset;
                int          xadvance = theChar.xadvance + charPadX;

                // special case, if the width and height are zero, the origin doesn't need to be offset
                // handles problematic case highlighted here:
                // http://unikronsoftware.com/2dtoolkit/forum/index.php/topic,89.msg220.html
                if (width == 0 && height == 0)
                {
                    xoffset = 0;
                    yoffset = 0;
                }

                // precompute required data
                float px = xoffset * scale;
                float py = (lineHeight - yoffset) * scale;

                if (theChar.texOverride)
                {
                    int w = theChar.texW;
                    int h = theChar.texH;
                    if (theChar.texFlipped)
                    {
                        h = theChar.texW;
                        w = theChar.texH;
                    }

                    thisChar.p0 = new Vector3(px + theChar.texOffsetX * scale, py - theChar.texOffsetY * scale, 0);
                    thisChar.p1 = new Vector3(px + (theChar.texOffsetX + w) * scale, py - (theChar.texOffsetY + h) * scale, 0);

                    thisChar.uv0 = new Vector2((theChar.texX) / texWidth, (theChar.texY + theChar.texH) / texHeight);
                    thisChar.uv1 = new Vector2((theChar.texX + theChar.texW) / texWidth, (theChar.texY) / texHeight);

                    thisChar.flipped = theChar.texFlipped;
                }
                else
                {
                    thisChar.p0 = new Vector3(px, py, 0);
                    thisChar.p1 = new Vector3(px + width * scale, py - height * scale, 0);
                    if (flipTextureY)
                    {
                        thisChar.uv0 = new Vector2(x / texWidth, y / texHeight);
                        thisChar.uv1 = new Vector2(thisChar.uv0.x + width / texWidth, thisChar.uv0.y + height / texHeight);
                    }
                    else
                    {
                        thisChar.uv0 = new Vector2(x / texWidth, 1.0f - y / texHeight);
                        thisChar.uv1 = new Vector2(thisChar.uv0.x + width / texWidth, thisChar.uv0.y - height / texHeight);
                    }

                    thisChar.flipped = false;
                }
                thisChar.advance = xadvance * scale;
                largestWidth     = Mathf.Max(thisChar.advance, largestWidth);

                // Needs gradient data
                if (gradientTexture != null)
                {
                    // build it up assuming the first gradient
                    float x0 = (float)(0.0f / gradientCount);
                    float x1 = (float)(1.0f / gradientCount);
                    float y0 = 1.0f;
                    float y1 = 0.0f;

                    // align to glyph if necessary

                    thisChar.gradientUv    = new Vector2[4];
                    thisChar.gradientUv[0] = new Vector2(x0, y0);
                    thisChar.gradientUv[1] = new Vector2(x1, y0);
                    thisChar.gradientUv[2] = new Vector2(x0, y1);
                    thisChar.gradientUv[3] = new Vector2(x1, y1);
                }

                if (id <= maxCharId)
                {
                    maxCharWithinBounds = (id > maxCharWithinBounds) ? id : maxCharWithinBounds;
                    minChar             = (id < minChar) ? id : minChar;

                    if (useDictionary)
                    {
                        charDict[id] = thisChar;
                    }
                    else
                    {
                        chars[id] = thisChar;
                    }

                    ++numLocalChars;
                }
            }

            // duplicate capitals to lower case, or vice versa depending on which ones exist
            if (dupeCaps)
            {
                for (int uc = 'A'; uc <= 'Z'; ++uc)
                {
                    int lc = uc + ('a' - 'A');

                    if (useDictionary)
                    {
                        if (charDict.ContainsKey(uc))
                        {
                            charDict[lc] = charDict[uc];
                        }
                        else if (charDict.ContainsKey(lc))
                        {
                            charDict[uc] = charDict[lc];
                        }
                    }
                    else
                    {
                        if (chars[lc] == null)
                        {
                            chars[lc] = chars[uc];
                        }
                        else if (chars[uc] == null)
                        {
                            chars[uc] = chars[lc];
                        }
                    }
                }
            }

            // share null char, same pointer
            var nullChar = new tk2dFontChar();

            nullChar.gradientUv = new Vector2[4];             // this would be null otherwise

            target.largestWidth = largestWidth;
            if (useDictionary)
            {
                // guarantee at least the first 256 characters
                for (int i = 0; i < 256; ++i)
                {
                    if (!charDict.ContainsKey(i))
                    {
                        charDict[i] = nullChar;
                    }
                }

                target.chars = null;
                target.SetDictionary(charDict);
                target.useDictionary = true;
            }
            else
            {
                target.chars = new tk2dFontChar[maxCharId + 1];
                for (int i = 0; i <= maxCharId; ++i)
                {
                    target.chars[i] = chars[i];
                    if (target.chars[i] == null)
                    {
                        target.chars[i] = nullChar;                         // zero everything, null char
                    }
                }

                target.charDict      = null;
                target.useDictionary = false;
            }

            // kerning
            target.kerning = new tk2dFontKerning[fontInfo.kernings.Count];
            for (int i = 0; i < target.kerning.Length; ++i)
            {
                tk2dFontKerning kerning = new tk2dFontKerning();
                kerning.c0        = fontInfo.kernings[i].first;
                kerning.c1        = fontInfo.kernings[i].second;
                kerning.amount    = fontInfo.kernings[i].amount * scale;
                target.kerning[i] = kerning;
            }

            return(true);
        }
Beispiel #5
0
    int CalcAnchor(bool useInlineStyling, out float offsetX, out float offsetY)
    {
        int numChars = 0;

        if (_font != null)
        {
            // calc string width
            float maxWidth = 0.0f;
            float width    = 0.0f;
            int   numLines = 1;
            int   count    = 0;

            for (int i = 0; count < _maxChars && i < _text.Length; ++i)
            {
                int idx = _text[i];
                if (idx >= _font.chars.Length)
                {
                    idx = 0;                                // should be space
                }
                tk2dFontChar chr = _font.chars[idx];

                if (idx == '\n')
                {
                    numLines++;
                    maxWidth = Mathf.Max(maxWidth, width);
                    width    = 0.0f;
                    continue;
                }
                else if (useInlineStyling)
                {
                    if (idx == '^')
                    {
                        if (i + 1 < _text.Length)
                        {
                            i++;
                            if (_text[i] != '^')
                            {
                                continue;
                            }
                        }
                    }
                }

                width += chr.advance * _scale.x;
                numChars++;
                count++;
            }

            maxWidth = Mathf.Max(maxWidth, width);
            float lineHeight = _font.lineHeight * _scale.y;
            float height     = lineHeight * numLines;

            switch (_anchor)
            {
            case TextAnchor.LowerLeft: offsetX = 0.0f;  offsetY = height - lineHeight; break;

            case TextAnchor.MiddleLeft: offsetX = 0.0f; offsetY = height / 2.0f - lineHeight; break;

            case TextAnchor.UpperLeft: offsetX = 0.0f;  offsetY = -lineHeight; break;

            case TextAnchor.LowerCenter: offsetX = -maxWidth / 2.0f;    offsetY = height - lineHeight; break;

            case TextAnchor.MiddleCenter: offsetX = -maxWidth / 2.0f;   offsetY = height / 2.0f - lineHeight; break;

            case TextAnchor.UpperCenter: offsetX = -maxWidth / 2.0f;    offsetY = -lineHeight; break;

            case TextAnchor.LowerRight: offsetX = -maxWidth;    offsetY = height - lineHeight; break;

            case TextAnchor.MiddleRight: offsetX = -maxWidth;   offsetY = height / 2.0f - lineHeight; break;

            case TextAnchor.UpperRight: offsetX = -maxWidth;    offsetY = -lineHeight; break;

            default:
                offsetX = 0.0f;
                offsetY = 0.0f;
                break;
            }
        }
        else
        {
            offsetX = 0.0f;
            offsetY = 0.0f;
        }

        return(numChars);
    }
Beispiel #6
0
    // returns number of characters written
    int FillTextData()
    {
        Vector2 gradientOffset = new Vector2((float)_textureGradient / font.gradientCount, 0);

        bool  useInlineStyling = inlineStyling && _font.textureGradients;
        float offsetX, offsetY;

        CalcAnchor(useInlineStyling, out offsetX, out offsetY);

        float cursorX = 0.0f;
        float cursorY = 0.0f;

        int target = 0;

        for (int i = 0; i < _text.Length && target < _maxChars; ++i)
        {
            int idx = _text[i];
            if (idx >= _font.chars.Length)
            {
                idx = 0;                            // should be space
            }
            tk2dFontChar chr = _font.chars[idx];

            if (idx == '\n')
            {
                cursorX  = 0.0f;
                cursorY -= _font.lineHeight * _scale.y;
                continue;
            }
            else if (useInlineStyling)
            {
                if (idx == '^')
                {
                    if (i + 1 < _text.Length)
                    {
                        i++;
                        if (_text[i] != '^')
                        {
                            int data = _text[i] - '0';
                            gradientOffset = new Vector2((float)data / font.gradientCount, 0);
                            continue;
                        }
                    }
                }
            }

            vertices[target * 4 + 0] = new Vector3(offsetX + cursorX + chr.p0.x * _scale.x, offsetY + cursorY + chr.p0.y * _scale.y, 0);
            vertices[target * 4 + 1] = new Vector3(offsetX + cursorX + chr.p1.x * _scale.x, offsetY + cursorY + chr.p0.y * _scale.y, 0);
            vertices[target * 4 + 2] = new Vector3(offsetX + cursorX + chr.p0.x * _scale.x, offsetY + cursorY + chr.p1.y * _scale.y, 0);
            vertices[target * 4 + 3] = new Vector3(offsetX + cursorX + chr.p1.x * _scale.x, offsetY + cursorY + chr.p1.y * _scale.y, 0);

            uvs[target * 4 + 0] = new Vector2(chr.uv0.x, chr.uv0.y);
            uvs[target * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
            uvs[target * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
            uvs[target * 4 + 3] = new Vector2(chr.uv1.x, chr.uv1.y);

            if (_font.textureGradients)
            {
                uv2[target * 4 + 0] = gradientOffset + chr.gradientUv[0];
                uv2[target * 4 + 1] = gradientOffset + chr.gradientUv[1];
                uv2[target * 4 + 2] = gradientOffset + chr.gradientUv[2];
                uv2[target * 4 + 3] = gradientOffset + chr.gradientUv[3];
            }

            cursorX += chr.advance * _scale.x;

            if (_kerning && i < _text.Length - 1)
            {
                foreach (var k in _font.kerning)
                {
                    if (k.c0 == _text[i] && k.c1 == _text[i + 1])
                    {
                        cursorX += k.amount * _scale.x;
                        break;
                    }
                }
            }

            ++target;
        }

        return(target);
    }
Beispiel #7
0
    bool ParseBMFont(string path, tk2dFontData bmFont, tk2dFont source)
    {
        IntFontInfo fontInfo = null;

        try
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(path);
            fontInfo = ParseBMFontXml(doc);
        }
        catch
        {
            fontInfo = ParseBMFontText(path);
        }

        if (fontInfo == null || fontInfo.chars.Count == 0)
        {
            return(false);
        }

        float texWidth   = fontInfo.scaleW;
        float texHeight  = fontInfo.scaleH;
        float lineHeight = fontInfo.lineHeight;

        float scale = 2.0f * source.targetOrthoSize / source.targetHeight;

        bmFont.lineHeight = lineHeight * scale;

        tk2dFontChar[] chars               = new tk2dFontChar[source.numCharacters];
        int            minChar             = 65536;
        int            maxCharWithinBounds = 0;
        int            numLocalChars       = 0;
        float          largestWidth        = 0.0f;

        foreach (var theChar in fontInfo.chars)
        {
            tk2dFontChar thisChar = new tk2dFontChar();
            int          id       = theChar.id;
            int          x        = theChar.x;
            int          y        = theChar.y;
            int          width    = theChar.width;
            int          height   = theChar.height;
            int          xoffset  = theChar.xoffset;
            int          yoffset  = theChar.yoffset;
            int          xadvance = theChar.xadvance;

            // precompute required data
            float px = xoffset * scale;
            float py = (lineHeight - yoffset) * scale;

            thisChar.p0 = new Vector3(px, py, 0);
            thisChar.p1 = new Vector3(px + width * scale, py - height * scale, 0);

            if (source.flipTextureY)
            {
                thisChar.uv0 = new Vector2(x / texWidth, y / texHeight);
                thisChar.uv1 = new Vector2(thisChar.uv0.x + width / texWidth, thisChar.uv0.y + height / texHeight);
            }
            else
            {
                thisChar.uv0 = new Vector2(x / texWidth, 1.0f - y / texHeight);
                thisChar.uv1 = new Vector2(thisChar.uv0.x + width / texWidth, thisChar.uv0.y - height / texHeight);
            }
            thisChar.advance = xadvance * scale;
            largestWidth     = Mathf.Max(thisChar.advance, largestWidth);

            // Needs gradient data
            if (source.gradientTexture != null)
            {
                // build it up assuming the first gradient
                float x0 = (float)(0.0f / source.gradientCount);
                float x1 = (float)(1.0f / source.gradientCount);
                float y0 = 1.0f;
                float y1 = 0.0f;

                // align to glyph if necessary

                thisChar.gradientUv    = new Vector2[4];
                thisChar.gradientUv[0] = new Vector2(x0, y0);
                thisChar.gradientUv[1] = new Vector2(x1, y0);
                thisChar.gradientUv[2] = new Vector2(x0, y1);
                thisChar.gradientUv[3] = new Vector2(x1, y1);
            }

            if (id < source.numCharacters)
            {
                maxCharWithinBounds = (id > maxCharWithinBounds) ? id : maxCharWithinBounds;
                minChar             = (id < minChar) ? id : minChar;
                chars[id]           = thisChar;
                ++numLocalChars;
            }
        }

        if (source.dupeCaps)
        {
            for (int uc = 'A'; uc <= 'Z'; ++uc)
            {
                int lc = uc + ('a' - 'A');
                if (chars[lc] == null)
                {
                    chars[lc] = chars[uc];
                }
                else if (chars[uc] == null)
                {
                    chars[uc] = chars[lc];
                }
            }
        }

        bmFont.largestWidth = largestWidth;
        bmFont.chars        = new tk2dFontChar[source.numCharacters];
        for (int i = 0; i < source.numCharacters; ++i)
        {
            bmFont.chars[i] = chars[i];
            if (bmFont.chars[i] == null)
            {
                bmFont.chars[i] = new tk2dFontChar();                 // zero everything, null char
            }
        }

        // kerning
        bmFont.kerning = new tk2dFontKerning[fontInfo.kernings.Count];
        for (int i = 0; i < bmFont.kerning.Length; ++i)
        {
            tk2dFontKerning kerning = new tk2dFontKerning();
            kerning.c0        = fontInfo.kernings[i].first;
            kerning.c1        = fontInfo.kernings[i].second;
            kerning.amount    = fontInfo.kernings[i].amount * scale;
            bmFont.kerning[i] = kerning;
        }

        return(true);
    }
Beispiel #8
0
    Vector2 GetMeshDimensionsForString(string str)
    {
        bool  _useInlineStyling = useInlineStyling;
        float maxWidth          = 0.0f;

        float cursorX = 0.0f;
        float cursorY = 0.0f;

        int target = 0;

        for (int i = 0; i < _text.Length && target < _maxChars; ++i)
        {
            int idx = _text[i];
            if (idx >= _font.chars.Length)
            {
                idx = 0;                            // should be space
            }
            tk2dFontChar chr = _font.chars[idx];

            if (idx == '\n')
            {
                maxWidth = Mathf.Max(cursorX, maxWidth);
                cursorX  = 0.0f;
                cursorY -= (_font.lineHeight + lineSpacing) * _scale.y;
                continue;
            }
            else if (_useInlineStyling)
            {
                if (idx == '^')
                {
                    if (i + 1 < _text.Length)
                    {
                        i++;
                        if (_text[i] != '^')
                        {
                            continue;
                        }
                    }
                }
            }

            cursorX += (chr.advance + spacing) * _scale.x;
            if (_kerning && i < _text.Length - 1)
            {
                foreach (var k in _font.kerning)
                {
                    if (k.c0 == _text[i] && k.c1 == _text[i + 1])
                    {
                        cursorX += k.amount * _scale.x;
                        break;
                    }
                }
            }

            ++target;
        }

        maxWidth = Mathf.Max(cursorX, maxWidth);
        cursorY -= (_font.lineHeight + lineSpacing) * _scale.y;

        return(new Vector2(maxWidth, cursorY));
    }
Beispiel #9
0
    int FillTextData()
    {
        Vector2 gradientOffset = new Vector2((float)_textureGradient / font.gradientCount, 0);

        Vector2 dims    = GetMeshDimensionsForString(_text);
        float   offsetY = GetYAnchorForHeight(dims.y);

        bool  _useInlineStyling = useInlineStyling;
        float cursorX           = 0.0f;
        float cursorY           = 0.0f;
        int   target            = 0;
        int   alignStartTarget  = 0;

        for (int i = 0; i < _text.Length && target < _maxChars; ++i)
        {
            int idx = _text[i];
            if (idx >= _font.chars.Length)
            {
                idx = 0;                            // should be space
            }
            tk2dFontChar chr = _font.chars[idx];

            if (idx == '\n')
            {
                float lineWidth      = cursorX;
                int   alignEndTarget = target;               // this is one after the last filled character
                if (alignStartTarget != target)
                {
                    float xOffset = GetXAnchorForWidth(lineWidth);
                    PostAlignTextData(alignStartTarget, alignEndTarget, xOffset);
                }


                alignStartTarget = target;
                cursorX          = 0.0f;
                cursorY         -= (_font.lineHeight + lineSpacing) * _scale.y;
                continue;
            }
            else if (_useInlineStyling)
            {
                if (idx == '^')
                {
                    if (i + 1 < _text.Length)
                    {
                        i++;
                        if (_text[i] != '^')
                        {
                            int data = _text[i] - '0';
                            gradientOffset = new Vector2((float)data / font.gradientCount, 0);
                            continue;
                        }
                    }
                }
            }

            vertices[target * 4 + 0] = new Vector3(cursorX + chr.p0.x * _scale.x, offsetY + cursorY + chr.p0.y * _scale.y, 0);
            vertices[target * 4 + 1] = new Vector3(cursorX + chr.p1.x * _scale.x, offsetY + cursorY + chr.p0.y * _scale.y, 0);
            vertices[target * 4 + 2] = new Vector3(cursorX + chr.p0.x * _scale.x, offsetY + cursorY + chr.p1.y * _scale.y, 0);
            vertices[target * 4 + 3] = new Vector3(cursorX + chr.p1.x * _scale.x, offsetY + cursorY + chr.p1.y * _scale.y, 0);

            uvs[target * 4 + 0] = new Vector2(chr.uv0.x, chr.uv0.y);
            uvs[target * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
            uvs[target * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
            uvs[target * 4 + 3] = new Vector2(chr.uv1.x, chr.uv1.y);

            if (_font.textureGradients)
            {
                uv2[target * 4 + 0] = gradientOffset + chr.gradientUv[0];
                uv2[target * 4 + 1] = gradientOffset + chr.gradientUv[1];
                uv2[target * 4 + 2] = gradientOffset + chr.gradientUv[2];
                uv2[target * 4 + 3] = gradientOffset + chr.gradientUv[3];
            }

            cursorX += (chr.advance + spacing) * _scale.x;

            if (_kerning && i < _text.Length - 1)
            {
                foreach (var k in _font.kerning)
                {
                    if (k.c0 == _text[i] && k.c1 == _text[i + 1])
                    {
                        cursorX += k.amount * _scale.x;
                        break;
                    }
                }
            }

            ++target;
        }

        if (alignStartTarget != target)
        {
            float lineWidth      = cursorX;
            int   alignEndTarget = target;
            float xOffset        = GetXAnchorForWidth(lineWidth);
            PostAlignTextData(alignStartTarget, alignEndTarget, xOffset);
        }

        return(target);
    }
Beispiel #10
0
    int FillTextData()
    {
        Vector2 gradientOffset = new Vector2((float)_textureGradient / font.gradientCount, 0);

        Vector2 dims    = GetMeshDimensionsForString(_text);
        float   offsetY = GetYAnchorForHeight(dims.y);

        bool  _useInlineStyling = useInlineStyling;
        float cursorX           = 0.0f;
        float cursorY           = 0.0f;
        int   target            = 0;
        int   alignStartTarget  = 0;

        Color topColor    = _color;
        Color bottomColor = _useGradient?_color2:_color;

        for (int i = 0; i < _text.Length && target < _maxChars; ++i)
        {
            int          idx = _text[i];
            tk2dFontChar chr = null;

            if (idx == '[' && _text[i + 1] == 'c' && _text.IndexOf(']', i) == (i + 11))
            {
                int iFrom = i + 3;
                int iTo   = _text.IndexOf(']', i);
                i = iTo;
                string color_str  = _text.Substring(iFrom, iTo - iFrom);
                uint   color_code = System.UInt32.Parse(color_str, System.Globalization.NumberStyles.HexNumber);

                uint r = (color_code & 0xff000000) >> 24;
                uint g = (color_code & 0x00ff0000) >> 16;
                uint b = (color_code & 0x0000ff00) >> 8;
                uint a = (color_code & 0x000000ff) >> 0;

                float rf = (float)r / 255.0f;
                float gf = (float)g / 255.0f;
                float bf = (float)b / 255.0f;
                float af = (float)a / 255.0f;

                topColor    = new Color(rf, gf, bf, af);
                bottomColor = topColor;
                continue;
            }
            else if (_font.useDictionary)
            {
                if (!_font.charDict.ContainsKey(idx))
                {
                    idx = 0;
                }
                chr = _font.charDict[idx];
            }
            else
            {
                if (idx >= _font.chars.Length)
                {
                    idx = 0;                                // should be space
                }
                chr = _font.chars[idx];
            }

            if (idx == '\n')
            {
                float lineWidth      = cursorX;
                int   alignEndTarget = target;               // this is one after the last filled character
                if (alignStartTarget != target)
                {
                    float xOffset = GetXAnchorForWidth(lineWidth);
                    PostAlignTextData(alignStartTarget, alignEndTarget, xOffset);
                }


                alignStartTarget = target;
                cursorX          = 0.0f;
                cursorY         -= (_font.lineHeight + lineSpacing) * _scale.y;
                continue;
            }
            else if (_useInlineStyling)
            {
                if (idx == '^')
                {
                    if (i + 1 < _text.Length)
                    {
                        i++;
                        if (_text[i] != '^')
                        {
                            int data = _text[i] - '0';
                            gradientOffset = new Vector2((float)data / font.gradientCount, 0);
                            continue;
                        }
                    }
                }
            }

            vertices[target * 4 + 0] = new Vector3(cursorX + chr.p0.x * _scale.x, offsetY + cursorY + chr.p0.y * _scale.y, 0);
            vertices[target * 4 + 1] = new Vector3(cursorX + chr.p1.x * _scale.x, offsetY + cursorY + chr.p0.y * _scale.y, 0);
            vertices[target * 4 + 2] = new Vector3(cursorX + chr.p0.x * _scale.x, offsetY + cursorY + chr.p1.y * _scale.y, 0);
            vertices[target * 4 + 3] = new Vector3(cursorX + chr.p1.x * _scale.x, offsetY + cursorY + chr.p1.y * _scale.y, 0);

            colors[target * 4 + 0] = colors[target * 4 + 1] = topColor;
            colors[target * 4 + 2] = colors[target * 4 + 3] = bottomColor;

            if (chr.flipped)
            {
                uvs[target * 4 + 0] = new Vector2(chr.uv1.x, chr.uv1.y);
                uvs[target * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
                uvs[target * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
                uvs[target * 4 + 3] = new Vector2(chr.uv0.x, chr.uv0.y);
            }
            else
            {
                uvs[target * 4 + 0] = new Vector2(chr.uv0.x, chr.uv0.y);
                uvs[target * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
                uvs[target * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
                uvs[target * 4 + 3] = new Vector2(chr.uv1.x, chr.uv1.y);
            }

            if (_font.textureGradients)
            {
                uv2[target * 4 + 0] = gradientOffset + chr.gradientUv[0];
                uv2[target * 4 + 1] = gradientOffset + chr.gradientUv[1];
                uv2[target * 4 + 2] = gradientOffset + chr.gradientUv[2];
                uv2[target * 4 + 3] = gradientOffset + chr.gradientUv[3];
            }

            cursorX += (chr.advance + spacing) * _scale.x;

            if (_kerning && i < _text.Length - 1)
            {
                foreach (var k in _font.kerning)
                {
                    if (k.c0 == _text[i] && k.c1 == _text[i + 1])
                    {
                        cursorX += k.amount * _scale.x;
                        break;
                    }
                }
            }

            ++target;
        }

        if (alignStartTarget != target)
        {
            float lineWidth      = cursorX;
            int   alignEndTarget = target;
            float xOffset        = GetXAnchorForWidth(lineWidth);
            PostAlignTextData(alignStartTarget, alignEndTarget, xOffset);
        }

        return(target);
    }
Beispiel #11
0
    public static void SetTextMeshGeom(this GeomData geomData, Vector3[] pos, Vector2[] uv, Vector2[] uv2, Color32[] color, int offset)
    {
        tk2dTextMeshData data          = geomData.TextMeshData;
        tk2dFontData     fontInst      = data.FontInst;
        tk2dColoredText  formattedText = data.FormattedText;

        InlineStyler curStyler = new InlineStyler();

        curStyler.meshTopColor     = new Color32(255, 255, 255, 255);
        curStyler.meshBottomColor  = new Color32(255, 255, 255, 255);
        curStyler.meshGradientTexU = (float)data.textureGradient / (float)((fontInst.gradientCount > 0) ? fontInst.gradientCount : 1);
        curStyler.curGradientCount = fontInst.gradientCount;

        Vector2 dims    = data.GetMeshDimensionsForString(formattedText);
        float   offsetY = data.GetYAnchorForHeight(dims.y);

        float cursorX = 0.0f;
        float cursorY = 0.0f;

        // target is required due to invisible '\n' character
        int target           = 0;
        int alignStartTarget = 0;

        for (int i = 0; i < formattedText.Length && target < geomData.CurrentAllocatedCharacters; ++i)
        {
            formattedText.ApplyColorCommand(curStyler, i);

            int          idx = formattedText[i];
            tk2dFontChar chr = fontInst.GetCharForIndex(idx, 0);

            if (idx == '\n')
            {
                float lineWidth      = cursorX;
                int   alignEndTarget = target;               // this is one after the last filled character
                if (alignStartTarget != target)
                {
                    float xOffset = data.GetXAnchorForWidth(lineWidth);
                    PostAlignTextData(pos, offset, alignStartTarget, alignEndTarget, xOffset);
                }


                alignStartTarget = target;
                cursorX          = 0.0f;
                cursorY         -= data.ActualLineSpaceHeight;
            }
            else
            {
                pos[offset + target * 4 + 0] = new Vector3(cursorX + chr.p0.x * data.TotalScale.x, offsetY + cursorY + chr.p0.y * data.TotalScale.y, 0);
                pos[offset + target * 4 + 1] = new Vector3(cursorX + chr.p1.x * data.TotalScale.x, offsetY + cursorY + chr.p0.y * data.TotalScale.y, 0);
                pos[offset + target * 4 + 2] = new Vector3(cursorX + chr.p0.x * data.TotalScale.x, offsetY + cursorY + chr.p1.y * data.TotalScale.y, 0);
                pos[offset + target * 4 + 3] = new Vector3(cursorX + chr.p1.x * data.TotalScale.x, offsetY + cursorY + chr.p1.y * data.TotalScale.y, 0);

                if (chr.flipped)
                {
                    uv[offset + target * 4 + 0] = new Vector2(chr.uv1.x, chr.uv1.y);
                    uv[offset + target * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
                    uv[offset + target * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
                    uv[offset + target * 4 + 3] = new Vector2(chr.uv0.x, chr.uv0.y);
                }
                else
                {
                    uv[offset + target * 4 + 0] = new Vector2(chr.uv0.x, chr.uv0.y);
                    uv[offset + target * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
                    uv[offset + target * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
                    uv[offset + target * 4 + 3] = new Vector2(chr.uv1.x, chr.uv1.y);
                }

                if (fontInst.textureGradients)
                {
                    uv2[offset + target * 4 + 0] = chr.gradientUv[0] + new Vector2(curStyler.meshGradientTexU, 0);
                    uv2[offset + target * 4 + 1] = chr.gradientUv[1] + new Vector2(curStyler.meshGradientTexU, 0);
                    uv2[offset + target * 4 + 2] = chr.gradientUv[2] + new Vector2(curStyler.meshGradientTexU, 0);
                    uv2[offset + target * 4 + 3] = chr.gradientUv[3] + new Vector2(curStyler.meshGradientTexU, 0);
                }

                if (fontInst.isPacked)
                {
                    Color32 c = channelSelectColors[chr.channel];
                    color[offset + target * 4 + 0] = c;
                    color[offset + target * 4 + 1] = c;
                    color[offset + target * 4 + 2] = c;
                    color[offset + target * 4 + 3] = c;
                }
                else
                {
                    color[offset + target * 4 + 0] = curStyler.meshTopColor;
                    color[offset + target * 4 + 1] = curStyler.meshTopColor;
                    color[offset + target * 4 + 2] = curStyler.meshBottomColor;
                    color[offset + target * 4 + 3] = curStyler.meshBottomColor;
                }

                cursorX += (chr.advance + data.Spacing) * data.TotalScale.x;

                if (data.kerning && i < formattedText.Length - 1)
                {
                    foreach (var k in fontInst.kerning)
                    {
                        if (k.c0 == formattedText[i] && k.c1 == formattedText[i + 1])
                        {
                            cursorX += k.amount * data.TotalScale.x;
                            break;
                        }
                    }
                }

                target++;
            }
        }

        if (alignStartTarget != target)
        {
            float lineWidth      = cursorX;
            int   alignEndTarget = target;
            float xOffset        = data.GetXAnchorForWidth(lineWidth);
            PostAlignTextData(pos, offset, alignStartTarget, alignEndTarget, xOffset);
        }

        for (int i = target; i < geomData.CurrentAllocatedCharacters; ++i)
        {
            pos[offset + i * 4 + 0] = pos[offset + i * 4 + 1] = pos[offset + i * 4 + 2] = pos[offset + i * 4 + 3] = Vector3.zero;
            uv[offset + i * 4 + 0]  = uv[offset + i * 4 + 1] = uv[offset + i * 4 + 2] = uv[offset + i * 4 + 3] = Vector2.zero;

            if (fontInst.textureGradients)
            {
                uv2[offset + i * 4 + 0] = uv2[offset + i * 4 + 1] = uv2[offset + i * 4 + 2] = uv2[offset + i * 4 + 3] = Vector2.zero;
            }

            color[offset + i * 4 + 0] = color[offset + i * 4 + 1] = color[offset + i * 4 + 2] = color[offset + i * 4 + 3] = Color.clear;
        }
    }
    bool ParseBMFont(string path, tk2dFontData bmFont, tk2dFont source)
    {
        IntFontInfo fontInfo = null;

        try
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(path);
            fontInfo = ParseBMFontXml(doc);
        }
        catch
        {
            fontInfo = ParseBMFontText(path);
        }

        if (fontInfo == null || fontInfo.chars.Count == 0)
            return false;

        float texWidth = fontInfo.scaleW;
        float texHeight = fontInfo.scaleH;
        float lineHeight = fontInfo.lineHeight;

        float scale = 2.0f * source.targetOrthoSize / source.targetHeight;

        bmFont.lineHeight = lineHeight * scale;

        // Get largest index
        int numCharacters = 0;
        foreach (var theChar in fontInfo.chars)
        {
            if (theChar.id > numCharacters) numCharacters = theChar.id;
        }

        tk2dFontChar[] chars = new tk2dFontChar[numCharacters];
        int minChar = 65536;
        int maxCharWithinBounds = 0;
        int numLocalChars = 0;
        float largestWidth = 0.0f;
        foreach (var theChar in fontInfo.chars)
        {
            tk2dFontChar thisChar = new tk2dFontChar();
            int id = theChar.id;
            int x = theChar.x;
            int y = theChar.y;
            int width = theChar.width;
            int height = theChar.height;
            int xoffset = theChar.xoffset;
            int yoffset = theChar.yoffset;
            int xadvance = theChar.xadvance + source.charPadX;

            // precompute required data
            float px = xoffset * scale;
            float py = (lineHeight - yoffset) * scale;

            thisChar.p0 = new Vector3(px, py, 0);
            thisChar.p1 = new Vector3(px + width * scale, py - height * scale, 0);

            if (source.flipTextureY)
            {
                thisChar.uv0 = new Vector2(x / texWidth, y / texHeight);
                thisChar.uv1 = new Vector2(thisChar.uv0.x + width / texWidth, thisChar.uv0.y + height / texHeight);
            }
            else
            {
                thisChar.uv0 = new Vector2(x / texWidth, 1.0f - y / texHeight);
                thisChar.uv1 = new Vector2(thisChar.uv0.x + width / texWidth, thisChar.uv0.y - height / texHeight);
            }
            thisChar.advance = xadvance * scale;
            largestWidth = Mathf.Max(thisChar.advance, largestWidth);

            // Needs gradient data
            if (source.gradientTexture != null)
            {
                // build it up assuming the first gradient
                float x0 = (float)(0.0f / source.gradientCount);
                float x1 = (float)(1.0f / source.gradientCount);
                float y0 = 1.0f;
                float y1 = 0.0f;

                // align to glyph if necessary

                thisChar.gradientUv = new Vector2[4];
                thisChar.gradientUv[0] = new Vector2(x0, y0);
                thisChar.gradientUv[1] = new Vector2(x1, y0);
                thisChar.gradientUv[2] = new Vector2(x0, y1);
                thisChar.gradientUv[3] = new Vector2(x1, y1);
            }

            if (id < numCharacters)
            {
                maxCharWithinBounds = (id > maxCharWithinBounds) ? id : maxCharWithinBounds;
                minChar = (id < minChar) ? id : minChar;
                chars[id] = thisChar;
                ++numLocalChars;
            }
        }

        if (source.dupeCaps)
        {
            for (int uc = 'A'; uc <= 'Z'; ++uc)
            {
                int lc = uc + ('a' - 'A');
                if (chars[lc] == null) chars[lc] = chars[uc];
                else if (chars[uc] == null) chars[uc] = chars[lc];
            }
        }

        // share null char, same pointer
        var nullChar = new tk2dFontChar();
        bmFont.largestWidth = largestWidth;
        bmFont.chars = new tk2dFontChar[numCharacters];
        for (int i = 0; i < numCharacters; ++i)
        {
            bmFont.chars[i] = chars[i];
            if (bmFont.chars[i] == null)
            {
                bmFont.chars[i] = nullChar; // zero everything, null char
            }
        }

        // kerning
        bmFont.kerning = new tk2dFontKerning[fontInfo.kernings.Count];
        for (int i = 0; i < bmFont.kerning.Length; ++i)
        {
            tk2dFontKerning kerning = new tk2dFontKerning();
            kerning.c0 = fontInfo.kernings[i].first;
            kerning.c1 = fontInfo.kernings[i].second;
            kerning.amount = fontInfo.kernings[i].amount * scale;
            bmFont.kerning[i] = kerning;
        }

        return true;
    }
Beispiel #13
0
    public void Init()
    {
        if (_font && (updateFlags & UpdateFlags.UpdateBuffers) != 0)
        {
            MeshFilter meshFilter = GetComponent <MeshFilter>();
            Mesh       newMesh    = new Mesh();

            Color topColor    = _color;
            Color bottomColor = _useGradient?_color2:_color;

            // volatile data
            vertices = new Vector3[_maxChars * 4];
            uvs      = new Vector2[_maxChars * 4];
            colors   = new Color[_maxChars * 4];
            int[] triangles = new int[_maxChars * 6];

            float offsetX, offsetY;
            CalcAnchor(out offsetX, out offsetY);

            float cursorX = 0.0f;
            float cursorY = 0.0f;
            for (int i = 0; i < _maxChars; ++i)
            {
                if (i < _text.Length)
                {
                    int idx = _text[i];
                    if (idx >= _font.chars.Length)
                    {
                        idx = 0;                            // should be space
                    }
                    tk2dFontChar chr = _font.chars[idx];

                    if (idx == '\n')
                    {
                        cursorX  = 0.0f;
                        cursorY -= _font.lineHeight * _scale.y;
                        continue;
                    }

                    vertices[i * 4 + 0] = new Vector3(offsetX + cursorX + chr.p0.x * _scale.x, offsetY + cursorY + chr.p0.y * _scale.y, 0);
                    vertices[i * 4 + 1] = new Vector3(offsetX + cursorX + chr.p1.x * _scale.x, offsetY + cursorY + chr.p0.y * _scale.y, 0);
                    vertices[i * 4 + 2] = new Vector3(offsetX + cursorX + chr.p0.x * _scale.x, offsetY + cursorY + chr.p1.y * _scale.y, 0);
                    vertices[i * 4 + 3] = new Vector3(offsetX + cursorX + chr.p1.x * _scale.x, offsetY + cursorY + chr.p1.y * _scale.y, 0);

                    uvs[i * 4 + 0] = new Vector2(chr.uv0.x, chr.uv0.y);
                    uvs[i * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
                    uvs[i * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
                    uvs[i * 4 + 3] = new Vector2(chr.uv1.x, chr.uv1.y);

                    cursorX += chr.advance * _scale.x;
                }
                else
                {
                    vertices[i * 4 + 0] = vertices[i * 4 + 1] = vertices[i * 4 + 2] = vertices[i * 4 + 3] = Vector3.zero;
                    uvs[i * 4 + 0]      = uvs[i * 4 + 1] = uvs[i * 4 + 2] = uvs[i * 4 + 3] = Vector2.zero;
                }

                colors[i * 4 + 0] = colors[i * 4 + 1] = topColor;
                colors[i * 4 + 2] = colors[i * 4 + 3] = bottomColor;

                triangles[i * 6 + 0] = i * 4 + 0;
                triangles[i * 6 + 1] = i * 4 + 1;
                triangles[i * 6 + 2] = i * 4 + 3;
                triangles[i * 6 + 3] = i * 4 + 2;
                triangles[i * 6 + 4] = i * 4 + 0;
                triangles[i * 6 + 5] = i * 4 + 3;

                if (_kerning && i < _text.Length - 1)
                {
                    foreach (var k in _font.kerning)
                    {
                        if (k.c0 == _text[i] && k.c1 == _text[i + 1])
                        {
                            cursorX += k.amount * _scale.x;
                            break;
                        }
                    }
                }
            }


            newMesh.vertices  = vertices;
            newMesh.uv        = uvs;
            newMesh.triangles = triangles;
            newMesh.colors    = colors;

            newMesh.RecalculateBounds();
            meshFilter.mesh = newMesh;
            mesh            = meshFilter.sharedMesh;

            updateFlags = UpdateFlags.UpdateNone;
        }
    }
Beispiel #14
0
    public void Commit()
    {
        // Can come in here without anything initalized when
        // instantiated in code
        if ((updateFlags & UpdateFlags.UpdateBuffers) != 0)
        {
            Init();
        }
        else
        {
            if ((updateFlags & UpdateFlags.UpdateText) != 0)
            {
                float cursorX = 0.0f;
                float cursorY = 0.0f;

                float offsetX, offsetY;
                CalcAnchor(out offsetX, out offsetY);

                for (int i = 0; i < _maxChars; ++i)
                {
                    if (i < _text.Length)
                    {
                        int idx = _text[i];
                        if (idx >= _font.chars.Length)
                        {
                            idx = 0;                                // should be space
                        }
                        tk2dFontChar chr = _font.chars[idx];

                        if (idx == '\n')
                        {
                            cursorX  = 0.0f;
                            cursorY -= _font.lineHeight * _scale.y;
                            continue;
                        }

                        vertices[i * 4 + 0] = new Vector3(offsetX + cursorX + chr.p0.x * _scale.x, offsetY + cursorY + chr.p0.y * _scale.y, 0);
                        vertices[i * 4 + 1] = new Vector3(offsetX + cursorX + chr.p1.x * _scale.x, offsetY + cursorY + chr.p0.y * _scale.y, 0);
                        vertices[i * 4 + 2] = new Vector3(offsetX + cursorX + chr.p0.x * _scale.x, offsetY + cursorY + chr.p1.y * _scale.y, 0);
                        vertices[i * 4 + 3] = new Vector3(offsetX + cursorX + chr.p1.x * _scale.x, offsetY + cursorY + chr.p1.y * _scale.y, 0);

                        uvs[i * 4 + 0] = new Vector2(chr.uv0.x, chr.uv0.y);
                        uvs[i * 4 + 1] = new Vector2(chr.uv1.x, chr.uv0.y);
                        uvs[i * 4 + 2] = new Vector2(chr.uv0.x, chr.uv1.y);
                        uvs[i * 4 + 3] = new Vector2(chr.uv1.x, chr.uv1.y);

                        cursorX += chr.advance * _scale.x;

                        if (_kerning && i < _text.Length - 1)
                        {
                            foreach (var k in _font.kerning)
                            {
                                if (k.c0 == _text[i] && k.c1 == _text[i + 1])
                                {
                                    cursorX += k.amount * _scale.x;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        vertices[i * 4 + 0] = vertices[i * 4 + 1] = vertices[i * 4 + 2] = vertices[i * 4 + 3] = Vector3.zero;
                        uvs[i * 4 + 0]      = uvs[i * 4 + 1] = uvs[i * 4 + 2] = uvs[i * 4 + 3] = Vector2.zero;
                    }
                }

                mesh.vertices = vertices;
                mesh.uv       = uvs;

                // comment this in for game if it becomes a problem
        #if UNITY_EDITOR
                mesh.RecalculateBounds();
        #endif
            }

            if ((updateFlags & UpdateFlags.UpdateColors) != 0)
            {
                Color topColor    = _color;
                Color bottomColor = _useGradient ? _color2 : _color;

                for (int i = 0; i < colors.Length; i += 4)
                {
                    colors[i + 0] = colors[i + 1] = topColor;
                    colors[i + 2] = colors[i + 3] = bottomColor;
                }
                mesh.colors = colors;
            }
        }

        updateFlags = UpdateFlags.UpdateNone;
    }