コード例 #1
0
ファイル: mesh_generator.cs プロジェクト: zjuwjf/UIWidgets
        public uiMeshMesh resolveMesh()
        {
            if (this._resolved)
            {
                return(this._mesh);
            }

            this._resolved = true;

            var style = this.textBlob.style;

            var text     = this.textBlob.text;
            var key      = MeshKey.create(this.textBlob.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.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.textSize; i++)
                {
                    char a    = text[this.textBlob.textOffset + i];
                    int  code = a;
                    if (char.IsHighSurrogate(a))
                    {
                        D.assert(i + 1 < this.textBlob.textSize);
                        D.assert(this.textBlob.textOffset + i + 1 < this.textBlob.text.Length);
                        char b = text[this.textBlob.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 pos = this.textBlob.positions[i];

                    int baseIndex = vert.Count;
                    vert.Add(new Vector3(pos.x + minX, pos.y + minY, 0));
                    vert.Add(new Vector3(pos.x + maxX, pos.y + minY, 0));
                    vert.Add(new Vector3(pos.x + maxX, pos.y + maxY, 0));
                    vert.Add(new Vector3(pos.x + minX, pos.y + 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.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.textOffset];
                // first char as origin for mesh position
                var position = this.textBlob.positions[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((position.x + minX), (position.y + minY), 0));
                vertices.Add(new Vector3((position.x + maxX), (position.y + minY), 0));
                vertices.Add(new Vector3((position.x + maxX), (position.y + maxY), 0));
                vertices.Add(new Vector3((position.x + minX), (position.y + 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);
        }
コード例 #2
0
ファイル: mesh_generator.cs プロジェクト: zjuwjf/UIWidgets
        public override void clear()
        {
            ObjectPool <MeshKey> .release(this.key);

            ObjectPool <uiMeshMesh> .release(this.mesh);
        }