private void CalculateHyperlinkBound(TagData hyperlinkTagData, ref Vector4 buttonBound, ref bool buttonBoundInit, ref float lastCharMinY, float xOffset, float yOffset, int stringIndex) { if (IsTempVertexValid()) { Vector4 charBound = GetCharBound(); if (buttonBoundInit) { //判断换行 if ((lastCharMinY != float.MaxValue) && (lastCharMinY > charBound.w)) { buttonBound.x += xOffset; buttonBound.y += yOffset; buttonBound.z += xOffset; buttonBound.w += yOffset; hyperlinkTagData.AddBound(buttonBound); lastCharMinY = charBound.y; buttonBound = charBound; } else { lastCharMinY = charBound.y; if (charBound.x < buttonBound.x) { buttonBound.x = charBound.x; } if (charBound.y < buttonBound.y) { buttonBound.y = charBound.y; } if (charBound.z > buttonBound.z) { buttonBound.z = charBound.z; } if (charBound.w > buttonBound.w) { buttonBound.w = charBound.w; } } } else { buttonBound = charBound; lastCharMinY = charBound.y; buttonBoundInit = true; } } if ((hyperlinkTagData.GetEndIndex() - 1) == stringIndex) { if (buttonBoundInit) { buttonBound.x += xOffset; buttonBound.y += yOffset; buttonBound.z += xOffset; buttonBound.w += yOffset; hyperlinkTagData.AddBound(buttonBound);; } buttonBoundInit = false; hyperlinkTagData = null; } }
protected override void OnPopulateMesh(VertexHelper toFill) { if (font == null) { return; } // We don't care if we the font Texture changes while we are doing our Update. // The end result of cachedTextGenerator will be valid for this instance. // Otherwise we can get issues like Case 619238. m_DisableFontTextureRebuiltCallback = true; Vector2 extents = rectTransform.rect.size; var settings = GetGenerationSettings(extents); cachedTextGenerator.PopulateWithErrors(text, settings, gameObject); // Apply the offset to the vertices IList <UIVertex> verts = cachedTextGenerator.verts; float unitsPerPixel = 1 / pixelsPerUnit; //Last 4 verts are always a new line... (\n) int vertCount = verts.Count - 4; Vector2 roundingOffset = new Vector2(verts[0].position.x, verts[0].position.y) * unitsPerPixel; roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset; toFill.Clear(); if (_tagDict != null) { foreach (TagData tagData in _tagDict.Values) { tagData.SetValid(false); } } TagData hyperlinkTagData = null; Vector2 sizeDelta = rectTransform.sizeDelta; Vector2 pivot = rectTransform.pivot; float xOffset = sizeDelta.x * pivot.x; float yOffset = sizeDelta.y * pivot.y; Vector4 buttonBound = new Vector4(float.MaxValue, float.MaxValue, float.MinValue, float.MinValue); bool buttonBoundInit = false; float lastCharMinY = float.MaxValue; bool haveRoundingOffset = roundingOffset != Vector2.zero; for (int i = 0; i < vertCount; ++i) { int tempVertsIndex = i & 3; m_TempVerts[tempVertsIndex] = verts[i]; m_TempVerts[tempVertsIndex].position *= unitsPerPixel; if (haveRoundingOffset) { m_TempVerts[tempVertsIndex].position.x += roundingOffset.x; m_TempVerts[tempVertsIndex].position.y += roundingOffset.y; } if (tempVertsIndex == 3) { int stringIndex = Mathf.FloorToInt(i / 4); if (hyperlinkTagData != null) { CalculateHyperlinkBound(hyperlinkTagData, ref buttonBound, ref buttonBoundInit, ref lastCharMinY, xOffset, yOffset, stringIndex); } else if (_tagDict != null && _tagDict.ContainsKey(stringIndex)) { TagData tagData = _tagDict[stringIndex]; tagData.SetValid(true); if (tagData.UseQuad()) { float minX = float.MaxValue; float minY = float.MaxValue; for (int j = 0; j < 4; j++) { m_TempVerts[j].uv0 = _zero;//清除占位符显示 也可以用<color=#00000000><quad></color>来隐藏 if (m_TempVerts[j].position.x < minX) { minX = m_TempVerts[j].position.x; //获取占位符左下角坐标 } if (m_TempVerts[j].position.y < minY) { minY = m_TempVerts[j].position.y; //获取占位符左下角坐标 } } tagData.SetStartPosition(new Vector3(minX + xOffset, minY + yOffset, 0)); } else if (tagData.Type == TagType.hyperlink) { tagData.ClearBound(); hyperlinkTagData = tagData; if (IsTempVertexValid()) { Vector4 charBound = GetCharBound(); buttonBound = charBound; lastCharMinY = charBound.y; buttonBoundInit = true; } } } toFill.AddUIVertexQuad(m_TempVerts); } } m_DisableFontTextureRebuiltCallback = false; _dirty = true; }