/// <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)); }
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; } }