FairyGUI.TextField.BuildMesh C# (CSharp) Method

BuildMesh() private method

private BuildMesh ( ) : void
return void
        void BuildMesh()
        {
            _requireUpdateMesh = false;

            if (_textWidth == 0 && _lines.Count == 1)
            {
                graphics.ClearMesh();

                if (_charPositions != null && _charPositions.Count == 0)
                    _charPositions.Add(new CharPosition());

                if (_richTextField != null)
                    _richTextField.RefreshObjects();

                return;
            }

            int letterSpacing = _textFormat.letterSpacing;
            float rectWidth = _contentRect.width - GUTTER_X * 2;
            TextFormat format = _textFormat;
            _font.SetFormat(format, _fontSizeScale);
            Color32 color = format.color;
            Color32[] gradientColor = format.gradientColor;
            bool boldVertice = format.bold && (_font.customBold || (format.italic && _font.customBoldAndItalic));
            if (_input)
                letterSpacing++;
            if (_charPositions != null)
                _charPositions.Clear();

            if (_fontSizeScale != 1) //不为1,表示在Shrink的作用下,字体变小了,所以要重新请求
                RequestText();

            Vector3 v0 = Vector3.zero, v1 = Vector3.zero;
            Vector2 u0, u1, u2, u3;
            float specFlag;

            List<Vector3> vertList = sCachedVerts;
            List<Vector2> uvList = sCachedUVs;
            List<Color32> colList = sCachedCols;
            vertList.Clear();
            uvList.Clear();
            colList.Clear();

            HtmlLink currentLink = null;
            float linkStartX = 0;
            int linkStartLine = 0;

            float charX = 0;
            float xIndent;
            float yIndent = 0;
            bool clipped = !_input && _autoSize == AutoSizeType.None;
            bool lineClipped;

            int lineCount = _lines.Count;
            for (int i = 0; i < lineCount; ++i)
            {
                LineInfo line = _lines[i];
                lineClipped = clipped && i != 0 && line.y + line.height > _contentRect.height; //超出区域,剪裁

                if (_align == AlignType.Center)
                    xIndent = (int)((rectWidth - line.width) / 2);
                else if (_align == AlignType.Right)
                    xIndent = rectWidth - line.width;
                else
                    xIndent = 0;
                if (_input && xIndent < 0)
                    xIndent = 0;

                charX = GUTTER_X + xIndent;

                int textLength = line.text.Length;
                for (int j = 0; j < textLength; j++)
                {
                    char ch = line.text[j];
                    if (ch == E_TAG)
                    {
                        int elementIndex = (int)line.text[++j] - 33;
                        HtmlElement element = _elements[elementIndex];
                        if (element.type == HtmlElementType.Text)
                        {
                            format = element.format;
                            _font.SetFormat(format, _fontSizeScale);
                            color = format.color;
                            gradientColor = format.gradientColor;
                            boldVertice = format.bold && (_font.customBold || (format.italic && _font.customBoldAndItalic));
                        }
                        else if (element.type == HtmlElementType.Link)
                        {
                            currentLink = (HtmlLink)element.htmlObject;
                            if (currentLink != null)
                            {
                                element.position = Vector2.zero;
                                currentLink.SetPosition(0, 0);
                                linkStartX = charX;
                                linkStartLine = i;
                            }
                        }
                        else if (element.type == HtmlElementType.LinkEnd)
                        {
                            if (currentLink != null)
                            {
                                currentLink.SetArea(linkStartLine, linkStartX, i, charX);
                                currentLink = null;
                            }
                        }
                        else
                        {
                            IHtmlObject htmlObj = element.htmlObject;
                            if (htmlObj != null)
                            {
                                if (_charPositions != null)
                                {
                                    CharPosition cp = new CharPosition();
                                    cp.lineIndex = (short)i;
                                    cp.charIndex = (short)j;
                                    cp.caretIndex = _charPositions.Count;
                                    cp.vertCount = -1 - elementIndex; //借用
                                    cp.offsetX = (int)charX;
                                    _charPositions.Add(cp);
                                }
                                element.position = new Vector2(charX + 1, line.y + (int)((line.height - htmlObj.height) / 2));
                                htmlObj.SetPosition(element.position.x, element.position.y);
                                if (lineClipped || clipped && charX + htmlObj.width > _contentRect.width - GUTTER_X)
                                    element.status |= 1;
                                else
                                    element.status &= 254;
                                charX += htmlObj.width + letterSpacing + 2;
                            }
                        }
                        continue;
                    }

                    if (_font.GetGlyph(ch, glyph))
                    {
                        if (lineClipped || clipped && charX != 0 && charX + glyph.width > _contentRect.width - GUTTER_X) //超出区域,剪裁
                        {
                            charX += letterSpacing + glyph.width;
                            continue;
                        }

                        yIndent = (int)((line.height + line.textHeight) / 2) - glyph.height;
                        v0.x = charX + glyph.vert.xMin;
                        v0.y = -line.y - yIndent + glyph.vert.yMin;
                        v1.x = charX + glyph.vert.xMax;
                        v1.y = -line.y - yIndent + glyph.vert.yMax;
                        u0 = glyph.uvBottomLeft;
                        u1 = glyph.uvTopLeft;
                        u2 = glyph.uvTopRight;
                        u3 = glyph.uvBottomRight;
                        specFlag = 0;

                        if (_font.hasChannel)
                        {
                            //对于由BMFont生成的字体,使用这个特殊的设置告诉着色器告诉用的是哪个通道
                            if (glyph.channel != 0)
                            {
                                specFlag = 10 * (glyph.channel - 1);
                                u0.x += specFlag;
                                u1.x += specFlag;
                                u2.x += specFlag;
                                u3.x += specFlag;
                            }
                        }
                        else if (_font.canLight && format.bold)
                        {
                            //对于动态字体,使用这个特殊的设置告诉着色器这个文字不需要点亮(粗体亮度足够,不需要)
                            specFlag = 10;
                            u0.x += specFlag;
                            u1.x += specFlag;
                            u2.x += specFlag;
                            u3.x += specFlag;
                        }

                        if (!boldVertice)
                        {
                            uvList.Add(u0);
                            uvList.Add(u1);
                            uvList.Add(u2);
                            uvList.Add(u3);

                            vertList.Add(v0);
                            vertList.Add(new Vector3(v0.x, v1.y));
                            vertList.Add(new Vector3(v1.x, v1.y));
                            vertList.Add(new Vector3(v1.x, v0.y));

                            if (gradientColor != null)
                            {
                                colList.Add(gradientColor[1]);
                                colList.Add(gradientColor[0]);
                                colList.Add(gradientColor[2]);
                                colList.Add(gradientColor[3]);
                            }
                            else
                            {
                                colList.Add(color);
                                colList.Add(color);
                                colList.Add(color);
                                colList.Add(color);
                            }
                        }
                        else
                        {
                            for (int b = 0; b < 4; b++)
                            {
                                uvList.Add(u0);
                                uvList.Add(u1);
                                uvList.Add(u2);
                                uvList.Add(u3);

                                float fx = BOLD_OFFSET[b * 2];
                                float fy = BOLD_OFFSET[b * 2 + 1];

                                vertList.Add(new Vector3(v0.x + fx, v0.y + fy));
                                vertList.Add(new Vector3(v0.x + fx, v1.y + fy));
                                vertList.Add(new Vector3(v1.x + fx, v1.y + fy));
                                vertList.Add(new Vector3(v1.x + fx, v0.y + fy));

                                if (gradientColor != null)
                                {
                                    colList.Add(gradientColor[1]);
                                    colList.Add(gradientColor[0]);
                                    colList.Add(gradientColor[2]);
                                    colList.Add(gradientColor[3]);
                                }
                                else
                                {
                                    colList.Add(color);
                                    colList.Add(color);
                                    colList.Add(color);
                                    colList.Add(color);
                                }
                            }
                        }

                        if (format.underline)
                        {
                            if (_font.GetGlyph('_', glyph2))
                            {
                                //取中点的UV
                                if (glyph2.uvBottomLeft.x != glyph2.uvBottomRight.x)
                                    u0.x = (glyph2.uvBottomLeft.x + glyph2.uvBottomRight.x) * 0.5f;
                                else
                                    u0.x = (glyph2.uvBottomLeft.x + glyph2.uvTopLeft.x) * 0.5f;
                                u0.x += specFlag;

                                if (glyph2.uvBottomLeft.y != glyph2.uvTopLeft.y)
                                    u0.y = (glyph2.uvBottomLeft.y + glyph2.uvTopLeft.y) * 0.5f;
                                else
                                    u0.y = (glyph2.uvBottomLeft.y + glyph2.uvBottomRight.y) * 0.5f;

                                uvList.Add(u0);
                                uvList.Add(u0);
                                uvList.Add(u0);
                                uvList.Add(u0);

                                v0.y = -line.y - yIndent + glyph2.vert.yMin - 1;
                                v1.y = -line.y - yIndent + glyph2.vert.yMax - 1;

                                float tmpX = charX + letterSpacing + glyph.width;

                                vertList.Add(new Vector3(charX, v0.y));
                                vertList.Add(new Vector3(charX, v1.y));
                                vertList.Add(new Vector3(tmpX, v1.y));
                                vertList.Add(new Vector3(tmpX, v0.y));

                                colList.Add(color);
                                colList.Add(color);
                                colList.Add(color);
                                colList.Add(color);
                            }
                            else
                                format.underline = false;
                        }

                        if (_charPositions != null)
                        {
                            CharPosition cp = new CharPosition();
                            cp.lineIndex = (short)i;
                            cp.charIndex = (short)j;
                            cp.caretIndex = _charPositions.Count;
                            cp.vertCount = ((boldVertice ? 4 : 1) + (format.underline ? 1 : 0)) * 4;
                            cp.offsetX = (int)charX;
                            _charPositions.Add(cp);
                        }

                        charX += letterSpacing + glyph.width;
                    }
                    else //if GetGlyph failed
                    {
                        if (_charPositions != null)
                        {
                            CharPosition cp = new CharPosition();
                            cp.lineIndex = (short)i;
                            cp.charIndex = (short)j;
                            cp.caretIndex = _charPositions.Count;
                            cp.vertCount = 0;
                            cp.offsetX = (int)charX;
                            _charPositions.Add(cp);
                        }

                        charX += letterSpacing;
                    }
                }//text loop
            }//line loop

            if (_charPositions != null)
            {
                CharPosition cp = new CharPosition();
                cp.lineIndex = (short)(lineCount - 1);
                cp.caretIndex = _charPositions.Count;
                cp.offsetX = (int)charX;
                _charPositions.Add(cp);
            }

            bool hasShadow = _shadowOffset.x != 0 || _shadowOffset.y != 0;
            if ((_stroke != 0 || hasShadow) && _font.canOutline)
            {
                int count = vertList.Count;
                int allocCount = count;
                if (_stroke != 0)
                    allocCount += count * 4;
                if (hasShadow)
                    allocCount += count;
                graphics.Alloc(allocCount);

                Vector3[] vertBuf = graphics.vertices;
                Vector2[] uvBuf = graphics.uv;
                Color32[] colBuf = graphics.colors;

                int start = allocCount - count;
                vertList.CopyTo(0, vertBuf, start, count);
                uvList.CopyTo(0, uvBuf, start, count);
                if (_font.canTint)
                {
                    for (int i = 0; i < count; i++)
                        colBuf[start + i] = colList[i];
                }
                else
                {
                    for (int i = 0; i < count; i++)
                        colBuf[start + i] = Color.white;
                }

                Color32 strokeColor = _strokeColor;
                if (_stroke != 0)
                {
                    start = allocCount - count * 5;
                    for (int j = 0; j < 4; j++)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            Vector3 vert = vertList[i];
                            Vector2 u = uvList[i];

                            //使用这个特殊的设置告诉着色器这个是描边
                            if (_font.canOutline)
                                u.y = 10 + u.y;
                            uvBuf[start] = u;
                            vertBuf[start] = new Vector3(vert.x + STROKE_OFFSET[j * 2] * _stroke, vert.y + STROKE_OFFSET[j * 2 + 1] * _stroke, 0);
                            colBuf[start] = strokeColor;
                            start++;
                        }
                    }
                }

                if (hasShadow)
                {
                    for (int i = 0; i < count; i++)
                    {
                        Vector3 vert = vertList[i];
                        Vector2 u = uvList[i];

                        //使用这个特殊的设置告诉着色器这个是描边
                        if (_font.canOutline)
                            u.y = 10 + u.y;
                        uvBuf[i] = u;
                        vertBuf[i] = new Vector3(vert.x + _shadowOffset.x, vert.y - _shadowOffset.y, 0);
                        colBuf[i] = strokeColor;
                    }
                }
            }
            else
            {
                int count = vertList.Count;
                graphics.Alloc(count);
                vertList.CopyTo(0, graphics.vertices, 0, count);
                uvList.CopyTo(0, graphics.uv, 0, count);
                Color32[] colors = graphics.colors;
                if (_font.canTint)
                {
                    for (int i = 0; i < count; i++)
                        colors[i] = colList[i];
                }
                else
                {
                    for (int i = 0; i < count; i++)
                        colors[i] = Color.white;
                }
            }

            graphics.FillTriangles();
            graphics.UpdateMesh();

            if (_richTextField != null)
                _richTextField.RefreshObjects();
        }