public MeshMesh resovleMesh() { if (this._resolved) { return(this._mesh); } this._resolved = true; var style = this._textBlob.style; var fontInfo = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle); var key = new MeshKey(this._textBlob.instanceId, this._scale); _meshes.TryGetValue(key, out var meshInfo); if (meshInfo != null && meshInfo.textureVersion == fontInfo.textureVersion) { meshInfo.touch(); this._mesh = meshInfo.mesh.transform(this._transform); return(this._mesh); } var font = fontInfo.font; var length = this._textBlob.textSize; var text = this._textBlob.text; var fontSizeToLoad = Mathf.CeilToInt(style.UnityFontSize * this._scale); var vertices = new List <Vector3>(length * 4); var triangles = new List <int>(length * 6); var uv = new List <Vector2>(length * 4); for (int charIndex = 0; charIndex < length; ++charIndex) { var ch = text[charIndex + this._textBlob.textOffset]; // first char as origin for mesh position var position = this._textBlob.positions[charIndex]; if (LayoutUtils.isWordSpace(ch) || LayoutUtils.isLineEndSpace(ch) || ch == '\t') { continue; } CharacterInfo charInfo = font.getCharacterInfo(ch, fontSizeToLoad, style.UnityFontStyle); var minX = charInfo.minX / this._scale; var maxX = charInfo.maxX / this._scale; var minY = charInfo.minY / this._scale; var maxY = charInfo.maxY / this._scale; var baseIndex = vertices.Count; vertices.Add(new Vector3((position.x + minX), (position.y - maxY), 0)); vertices.Add(new Vector3((position.x + maxX), (position.y - maxY), 0)); vertices.Add(new Vector3((position.x + maxX), (position.y - minY), 0)); vertices.Add(new Vector3((position.x + minX), (position.y - minY), 0)); triangles.Add(baseIndex); triangles.Add(baseIndex + 1); triangles.Add(baseIndex + 2); triangles.Add(baseIndex); triangles.Add(baseIndex + 2); triangles.Add(baseIndex + 3); uv.Add(charInfo.uvTopLeft); uv.Add(charInfo.uvTopRight); uv.Add(charInfo.uvBottomRight); uv.Add(charInfo.uvBottomLeft); } if (vertices.Count == 0) { this._mesh = null; return(null); } MeshMesh mesh = vertices.Count > 0 ? new MeshMesh(null, vertices, triangles, uv) : null; _meshes[key] = new MeshInfo(key, mesh, fontInfo.textureVersion); this._mesh = mesh.transform(this._transform); return(this._mesh); }
public uiMeshMesh resolveMesh() { if (this._resolved) { return(this._mesh); } this._resolved = true; var style = this.textBlob.Value.style; var text = this.textBlob.Value.text; var key = MeshKey.create(this.textBlob.Value.instanceId, this.scale); var fontInfo = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle); var font = fontInfo.font; _meshes.TryGetValue(key, out var meshInfo); if (meshInfo != null && meshInfo.textureVersion == fontInfo.textureVersion) { ObjectPool <MeshKey> .release(key); meshInfo.touch(); this._mesh = meshInfo.mesh.transform(this.matrix); return(this._mesh); } // Handling Emoji char startingChar = text[this.textBlob.Value.textOffset]; if (char.IsHighSurrogate(startingChar) || EmojiUtils.isSingleCharEmoji(startingChar)) { var vert = ObjectPool <uiList <Vector3> > .alloc(); var tri = ObjectPool <uiList <int> > .alloc(); var uvCoord = ObjectPool <uiList <Vector2> > .alloc(); var metrics = FontMetrics.fromFont(font, style.UnityFontSize); var minMaxRect = EmojiUtils.getMinMaxRect(style.fontSize, metrics.ascent, metrics.descent); var minX = minMaxRect.left; var maxX = minMaxRect.right; var minY = minMaxRect.top; var maxY = minMaxRect.bottom; for (int i = 0; i < this.textBlob.Value.textSize; i++) { char a = text[this.textBlob.Value.textOffset + i]; int code = a; if (char.IsHighSurrogate(a)) { D.assert(i + 1 < this.textBlob.Value.textSize); D.assert(this.textBlob.Value.textOffset + i + 1 < this.textBlob.Value.text.Length); char b = text[this.textBlob.Value.textOffset + i + 1]; D.assert(char.IsLowSurrogate(b)); code = char.ConvertToUtf32(a, b); } else if (char.IsLowSurrogate(a) || EmojiUtils.isEmptyEmoji(a)) { continue; } var uvRect = EmojiUtils.getUVRect(code); var positionX = this.textBlob.Value.getPositionX(i); int baseIndex = vert.Count; vert.Add(new Vector3(positionX + minX, minY, 0)); vert.Add(new Vector3(positionX + maxX, minY, 0)); vert.Add(new Vector3(positionX + maxX, maxY, 0)); vert.Add(new Vector3(positionX + minX, maxY, 0)); tri.Add(baseIndex); tri.Add(baseIndex + 1); tri.Add(baseIndex + 2); tri.Add(baseIndex); tri.Add(baseIndex + 2); tri.Add(baseIndex + 3); uvCoord.Add(uvRect.bottomLeft.toVector()); uvCoord.Add(uvRect.bottomRight.toVector()); uvCoord.Add(uvRect.topRight.toVector()); uvCoord.Add(uvRect.topLeft.toVector()); if (char.IsHighSurrogate(a)) { i++; } } uiMeshMesh meshMesh = uiMeshMesh.create(null, vert, tri, uvCoord); if (_meshes.ContainsKey(key)) { ObjectPool <MeshInfo> .release(_meshes[key]); _meshes.Remove(key); } _meshes[key] = MeshInfo.create(key, meshMesh, 0); this._mesh = meshMesh.transform(this.matrix); return(this._mesh); } var length = this.textBlob.Value.textSize; var fontSizeToLoad = Mathf.CeilToInt(style.UnityFontSize * this.scale); var vertices = ObjectPool <uiList <Vector3> > .alloc(); vertices.SetCapacity(length * 4); var triangles = ObjectPool <uiList <int> > .alloc(); triangles.SetCapacity(length * 6); var uv = ObjectPool <uiList <Vector2> > .alloc(); uv.SetCapacity(length * 4); for (int charIndex = 0; charIndex < length; ++charIndex) { var ch = text[charIndex + this.textBlob.Value.textOffset]; // first char as origin for mesh position var positionX = this.textBlob.Value.getPositionX(charIndex); if (LayoutUtils.isWordSpace(ch) || LayoutUtils.isLineEndSpace(ch) || ch == '\t') { continue; } if (fontSizeToLoad == 0) { continue; } font.getGlyphInfo(ch, out var glyphInfo, fontSizeToLoad, style.UnityFontStyle); var minX = glyphInfo.minX / this.scale; var maxX = glyphInfo.maxX / this.scale; var minY = -glyphInfo.maxY / this.scale; var maxY = -glyphInfo.minY / this.scale; var baseIndex = vertices.Count; vertices.Add(new Vector3(positionX + minX, minY, 0)); vertices.Add(new Vector3(positionX + maxX, minY, 0)); vertices.Add(new Vector3(positionX + maxX, maxY, 0)); vertices.Add(new Vector3(positionX + minX, maxY, 0)); triangles.Add(baseIndex); triangles.Add(baseIndex + 1); triangles.Add(baseIndex + 2); triangles.Add(baseIndex); triangles.Add(baseIndex + 2); triangles.Add(baseIndex + 3); uv.Add(glyphInfo.uvTopLeft); uv.Add(glyphInfo.uvTopRight); uv.Add(glyphInfo.uvBottomRight); uv.Add(glyphInfo.uvBottomLeft); } if (vertices.Count == 0) { this._mesh = null; ObjectPool <uiList <Vector3> > .release(vertices); ObjectPool <uiList <Vector2> > .release(uv); ObjectPool <uiList <int> > .release(triangles); ObjectPool <MeshKey> .release(key); return(null); } uiMeshMesh mesh = vertices.Count > 0 ? uiMeshMesh.create(null, vertices, triangles, uv) : null; if (_meshes.ContainsKey(key)) { ObjectPool <MeshInfo> .release(_meshes[key]); _meshes.Remove(key); } _meshes[key] = MeshInfo.create(key, mesh, fontInfo.textureVersion); this._mesh = mesh.transform(this.matrix); return(this._mesh); }
public static MeshMesh generateMesh(TextBlob textBlob, float scale) { var style = textBlob.style; var fontInfo = FontManager.instance.getOrCreate(style.fontFamily); var key = new MeshKey(textBlob.instanceId, scale); _meshes.TryGetValue(key, out var meshInfo); if (meshInfo != null && meshInfo.textureVersion == fontInfo.textureVersion) { meshInfo.touch(); return(meshInfo.mesh); } var font = fontInfo.font; var length = textBlob.textSize; var text = textBlob.text; var fontSizeToLoad = Mathf.CeilToInt(style.UnityFontSize * scale); var subText = textBlob.text.Substring(textBlob.textOffset, textBlob.textSize); font.RequestCharactersInTexture(subText, fontSizeToLoad, style.UnityFontStyle); var vertices = new List <Vector3>(length * 4); var triangles = new List <int>(length * 6); var uv = new List <Vector2>(length * 4); for (int charIndex = 0; charIndex < length; ++charIndex) { var ch = text[charIndex + textBlob.textOffset]; // first char as origin for mesh position var position = textBlob.positions[charIndex]; if (LayoutUtils.isWordSpace(ch) || LayoutUtils.isLineEndSpace(ch) || ch == '\t') { continue; } CharacterInfo charInfo; font.GetCharacterInfo(ch, out charInfo, fontSizeToLoad, style.UnityFontStyle); var minX = charInfo.minX / scale; var maxX = charInfo.maxX / scale; var minY = charInfo.minY / scale; var maxY = charInfo.maxY / scale; var baseIndex = vertices.Count; vertices.Add(new Vector3((float)(position.x + minX), (float)(position.y - maxY), 0)); vertices.Add(new Vector3((float)(position.x + maxX), (float)(position.y - maxY), 0)); vertices.Add(new Vector3((float)(position.x + maxX), (float)(position.y - minY), 0)); vertices.Add(new Vector3((float)(position.x + minX), (float)(position.y - minY), 0)); triangles.Add(baseIndex); triangles.Add(baseIndex + 1); triangles.Add(baseIndex + 2); triangles.Add(baseIndex); triangles.Add(baseIndex + 2); triangles.Add(baseIndex + 3); uv.Add(charInfo.uvTopLeft); uv.Add(charInfo.uvTopRight); uv.Add(charInfo.uvBottomRight); uv.Add(charInfo.uvBottomLeft); } if (vertices.Count == 0) { return(null); } MeshMesh mesh = vertices.Count > 0 ? new MeshMesh(null, vertices, triangles, uv) : null; _meshes[key] = new MeshInfo(key, mesh, fontInfo.textureVersion); return(mesh); }