Beispiel #1
0
 public MeshInfo(MeshKey key, MeshMesh mesh, long textureVersion, int timeToLive = 5)
 {
     this.mesh           = mesh;
     this.key            = key;
     this.textureVersion = textureVersion;
     this.touch(timeToLive);
 }
        public static MeshInfo create(MeshKey key, uiMeshMesh mesh, long textureVersion, int timeToLive = 5)
        {
            var meshInfo = ObjectPool <MeshInfo> .alloc();

            meshInfo.mesh           = mesh;
            meshInfo.key            = key;
            meshInfo.textureVersion = textureVersion;
            meshInfo.touch(timeToLive);
            return(meshInfo);
        }
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }