// this function is static to ensure that no fields are changed during this call
    private static void ConvertString(tk2dColoredText formattedText,
                                      tk2dTextMeshData meshData)
    {
        const char NonBreakableSpace = (char)17;


        if (meshData.UseShortNumbers)
        {
            formattedText.ApplyShortNumber();
        }

        if (!meshData.DisableNumberGrouping)
        {
            int currentNumberCount = 0;

            for (int i = formattedText.Length - 1; i >= 0; i--)
            {
                var curChar = formattedText[i];
                if (curChar >= '0' && curChar <= '9')
                {
                    currentNumberCount += 1;
                }
                else
                {
                    currentNumberCount = 0;
                }

                if (currentNumberCount == 4)
                {
                    // add device control char -> if you add normal space ->
                    // code lower will make new lines
                    formattedText.Insert(i + 1, new string(NonBreakableSpace, 1));
                    currentNumberCount = 1;
                }
            }
        }


        // reset line break scale before calculate the dimentions
        meshData.lineBreakScale = Vector3.one;
        Vector2 dims = meshData.GetMeshDimensionsForString(formattedText);

        if (dims.x > meshData.maxTextLength)
        {
            if (meshData.maxTextLength > 0.0f)
            {
                switch (meshData.BreakMode)
                {
                case LineBreakMode.ScaleDown:
                {
                    float curScale = meshData.maxTextLength / dims.x;
                    meshData.lineBreakScale.Set(curScale,
                                                curScale,
                                                curScale);
                }
                break;


                case LineBreakMode.ThreeDots:
                {
                    formattedText.Append("...");
                    for (int i = formattedText.Length - 4; i >= 0 && meshData.GetMeshDimensionsForString(formattedText).x > meshData.MaxTextLength; i--)
                    {
                        formattedText.Remove(i);
                    }
                }
                break;


                case LineBreakMode.LineBreak:
                {
                    int curStartIndex  = 0;
                    int curFinishIndex = 0;
                    while (curFinishIndex < (formattedText.Length - 1))
                    {
                        int curNextSpace = formattedText.IndexOf(' ', curFinishIndex + 1);
                        int curLastIndex = (curNextSpace != -1) ? curNextSpace : (formattedText.Length - 1);
                        if (meshData.GetMeshDimensionsForString(formattedText, curStartIndex, (curLastIndex - curStartIndex + 1)).x > meshData.maxTextLength)
                        {
                            int actualFinishIndex = (curFinishIndex > curStartIndex) ? curFinishIndex : curLastIndex;

                            formattedText[actualFinishIndex] = '\n';

                            curFinishIndex = curStartIndex = actualFinishIndex + 1;
                        }
                        else
                        {
                            curFinishIndex = curLastIndex;
                        }
                    }
                }
                break;
                }
            }
        }

        float dimsY = Mathf.Abs(meshData.GetMeshDimensionsForString(formattedText).y);

        if (dimsY > meshData.maxTextHeight)
        {
            if (meshData.maxTextHeight > 0.0f)
            {
                float curScale = meshData.lineBreakScale.x;
                float newScale = meshData.maxTextHeight / dimsY;
                curScale = Math.Min(curScale, newScale);
                meshData.lineBreakScale.Set(curScale,
                                            curScale,
                                            curScale);
            }
        }

        if (meshData.ShouldScaleInCellSize)
        {
            float newScale = Mathf.Min(meshData.maxTextLength / dims.x, meshData.MaxTextHeight / Mathf.Abs(dims.y));
            meshData.lineBreakScale.Set(newScale, newScale, newScale);
        }

        formattedText.Replace(NonBreakableSpace, ' ');
    }
예제 #2
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;
        }
    }