Esempio n. 1
0
        public uiMeshMesh transform(uiMatrix3?matrix)
        {
            var vertices = ObjectPool <uiList <Vector3> > .alloc();

            vertices.SetCapacity(this.vertices.Count);
            vertices.AddRange(this.vertices.data);

            var triangles = ObjectPool <uiList <int> > .alloc();

            triangles.SetCapacity(this.triangles.Count);
            triangles.AddRange(this.triangles.data);


            uiList <Vector2> uv = null;

            if (this.uv != null)
            {
                uv = ObjectPool <uiList <Vector2> > .alloc();

                uv.SetCapacity(this.uv.Count);
                uv.AddRange(this.uv.data);
            }


            var ret = create(matrix, vertices, triangles, uv, this.rawBounds);

            return(ret);
        }
Esempio n. 2
0
            public static CmdLayer create(RenderLayer layer)
            {
                CmdLayer newCmd = ObjectPool <CmdLayer> .alloc();

                newCmd.layer = layer;
                return(newCmd);
            }
Esempio n. 3
0
        public static ReducedClip create(ClipStack stack, uiRect layerBounds, uiRect queryBounds)
        {
            ReducedClip clip = ObjectPool <ReducedClip> .alloc();

            uiRect?stackBounds;
            bool   iior;

            stack.getBounds(out stackBounds, out iior);

            if (stackBounds == null)
            {
                clip.scissor = layerBounds;
                return(clip);
            }

            stackBounds = uiRectHelper.intersect(layerBounds, stackBounds.Value);
            if (iior)
            {
                clip.scissor = stackBounds;
                return(clip);
            }

            queryBounds = uiRectHelper.intersect(stackBounds.Value, queryBounds);
            if (queryBounds.isEmpty)
            {
                clip.scissor = uiRectHelper.zero;
                return(clip);
            }

            clip.scissor = queryBounds;
            clip._walkStack(stack, clip.scissor.Value);
            return(clip);
        }
Esempio n. 4
0
            public static CmdScissor create(uiRect?deviceScissor)
            {
                CmdScissor newCmd = ObjectPool <CmdScissor> .alloc();

                newCmd.deviceScissor = deviceScissor;
                return(newCmd);
            }
Esempio n. 5
0
        public static uiMeshMesh imageMesh(uiMatrix3?matrix, uiRect src, uiRect dst)
        {
            var vertices = ObjectPool <uiList <Vector3> > .alloc();

            vertices.SetCapacity(4);

            var uv = ObjectPool <uiList <Vector2> > .alloc();

            uv.SetCapacity(4);

            float uvx0 = src.left;
            float uvx1 = src.right;
            float uvy0 = 1.0f - src.top;
            float uvy1 = 1.0f - src.bottom;

            vertices.Add(new Vector2(dst.left, dst.top));
            uv.Add(new Vector2(uvx0, uvy0));
            vertices.Add(new Vector2(dst.left, dst.bottom));
            uv.Add(new Vector2(uvx0, uvy1));
            vertices.Add(new Vector2(dst.right, dst.bottom));
            uv.Add(new Vector2(uvx1, uvy1));
            vertices.Add(new Vector2(dst.right, dst.top));
            uv.Add(new Vector2(uvx1, uvy0));

            var _triangles = ObjectPool <uiList <int> > .alloc();

            _triangles.AddRange(_imageTriangles);

            return(uiMeshMesh.create(matrix, vertices, _triangles, uv));
        }
Esempio n. 6
0
        public static ClipElement create(int saveCount, uiPath uiPath, uiMatrix3 matrix, float scale)
        {
            ClipElement newElement = ObjectPool <ClipElement> .alloc();

            newElement.saveCount = saveCount;

            var pathCache = uiPath.flatten(scale);
            var fillMesh  = pathCache.getFillMesh(out newElement.convex);

            newElement.mesh = fillMesh.transform(matrix);

            var vertices = newElement.mesh.vertices;

            if (newElement.convex && vertices.Count == 4 && matrix.rectStaysRect() &&
                (Mathf.Abs(vertices[0].x - vertices[1].x) < 1e-6 && Mathf.Abs(vertices[1].y - vertices[2].y) < 1e-6 &&
                 Mathf.Abs(vertices[2].x - vertices[3].x) < 1e-6 && Mathf.Abs(vertices[3].y - vertices[0].y) < 1e-6 ||
                 Mathf.Abs(vertices[0].y - vertices[1].y) < 1e-6 && Mathf.Abs(vertices[1].x - vertices[2].x) < 1e-6 &&
                 Mathf.Abs(vertices[2].y - vertices[3].y) < 1e-6 && Mathf.Abs(vertices[3].x - vertices[0].x) < 1e-6))
            {
                newElement.isRect = true;
                newElement.rect   = newElement.mesh.bounds;
            }
            else
            {
                newElement.isRect = false;
                newElement.rect   = null;
            }

            return(newElement);
        }
Esempio n. 7
0
        public static uiMeshMesh imageMesh(uiMatrix3?matrix,
                                           uiOffset srcTL, uiOffset srcBL, uiOffset srcBR, uiOffset srcTR,
                                           uiRect dst)
        {
            var vertices = ObjectPool <uiList <Vector3> > .alloc();

            vertices.SetCapacity(4);

            var uv = ObjectPool <uiList <Vector2> > .alloc();

            uv.SetCapacity(4);

            vertices.Add(new Vector2(dst.left, dst.top));
            uv.Add(new Vector2(srcTL.dx, 1.0f - srcTL.dy));
            vertices.Add(new Vector2(dst.left, dst.bottom));
            uv.Add(new Vector2(srcBL.dx, 1.0f - srcBL.dy));
            vertices.Add(new Vector2(dst.right, dst.bottom));
            uv.Add(new Vector2(srcBR.dx, 1.0f - srcBR.dy));
            vertices.Add(new Vector2(dst.right, dst.top));
            uv.Add(new Vector2(srcTR.dx, 1.0f - srcTR.dy));

            var _triangles = ObjectPool <uiList <int> > .alloc();

            _triangles.AddRange(_imageTriangles);

            return(uiMeshMesh.create(matrix, vertices, _triangles, uv));
        }
Esempio n. 8
0
        public static PictureFlusher.CmdDraw fastShadow(PictureFlusher.RenderLayer layer, uiMeshMesh mesh, float sigma,
                                                        bool isRect, bool isCircle, float corner, Vector4 bound, uiColor color)
        {
            Vector4 viewport = layer.viewport;
            var     mat      = _shadowBox;

            if (!isRect)
            {
                mat = _shadowRBox;
            }

            var props = ObjectPool <MaterialPropertyBlockWrapper> .alloc();

            props.SetVector(_viewportId, viewport);
            props.SetFloat(_shadowSigmaId, sigma);
            props.SetVector(_shadowBoxId, bound);
            props.SetVector(_shadowColorId, _colorToVector4(color));
            if (!isRect)
            {
                props.SetFloat(_shadowCornerId, corner);
            }

            return(PictureFlusher.CmdDraw.create(
                       mesh: mesh,
                       pass: 0,
                       material: mat,
                       properties: props
                       ));
        }
Esempio n. 9
0
        public static uiPath create(int capacity = 128)
        {
            uiPath newPath = ObjectPool <uiPath> .alloc();

            newPath._reset();
            return(newPath);
        }
        public static MeshKey create(long textBlobId, float scale)
        {
            var newKey = ObjectPool <MeshKey> .alloc();

            newKey.textBlobId = textBlobId;
            newKey.scale      = scale;
            return(newKey);
        }
Esempio n. 11
0
        public static uiPicture create(List <uiDrawCmd> drawCmds, uiRect paintBounds)
        {
            var picture = ObjectPool <uiPicture> .alloc();

            picture.drawCmds    = drawCmds;
            picture.paintBounds = paintBounds;
            return(picture);
        }
Esempio n. 12
0
        public static uiPathCache create(float scale)
        {
            uiPathCache newPathCache = ObjectPool <uiPathCache> .alloc();

            newPathCache._distTol = 0.01f / scale;
            newPathCache._tessTol = 0.25f / scale;
            newPathCache._scale   = scale;
            return(newPathCache);
        }
        public static TextBlobMesh create(TextBlob textBlob, float scale, uiMatrix3 matrix)
        {
            TextBlobMesh newMesh = ObjectPool <TextBlobMesh> .alloc();

            newMesh.textBlob = textBlob;
            newMesh.scale    = scale;
            newMesh.matrix   = matrix;
            return(newMesh);
        }
        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);
        }
Esempio n. 15
0
        public static uiTessellationInfo create(uiTessellationKey key, uiList <Vector2> points, int timeToLive = 5)
        {
            var newInfo = ObjectPool <uiTessellationInfo> .alloc();

            newInfo.points = points;
            newInfo.key    = key;
            newInfo.touch(timeToLive);

            return(newInfo);
        }
Esempio n. 16
0
            public static State create(uiMatrix3?matrix = null, float?scale = null, uiMatrix3?invMatrix = null)
            {
                State newState = ObjectPool <State> .alloc();

                newState._matrix    = matrix ?? _id;
                newState._scale     = scale;
                newState._invMatrix = invMatrix;

                return(newState);
            }
Esempio n. 17
0
        public static uiPicture create(List <uiDrawCmd> drawCmds,
                                       uiRect paintBounds,
                                       BBoxHierarchy <IndexedRect> bbh = null,
                                       uiList <int> stateUpdateIndices = null)
        {
            var picture = ObjectPool <uiPicture> .alloc();

            picture.drawCmds            = drawCmds;
            picture.paintBounds         = paintBounds;
            picture.bbh                 = bbh;
            picture.stateUpdatesIndices = stateUpdateIndices;
            return(picture);
        }
Esempio n. 18
0
        void _reset()
        {
            this._commands = ObjectPool <uiList <float> > .alloc();

            this._commandx = 0;
            this._commandy = 0;
            this._minX     = float.MaxValue;
            this._minY     = float.MaxValue;
            this._maxX     = float.MinValue;
            this._maxY     = float.MinValue;
            ObjectPool <uiPathCache> .release(this._cache);

            this._cache = null;
        }
Esempio n. 19
0
        public static uiTessellationKey create(float x1, float y1, float x2, float y2, float x3, float y3, float x4,
                                               float y4,
                                               float tessTol)
        {
            var newKey = ObjectPool <uiTessellationKey> .alloc();

            newKey.x2      = x2 - x1;
            newKey.y2      = y2 - y1;
            newKey.x3      = x3 - x1;
            newKey.y3      = y3 - y1;
            newKey.x4      = x4 - x1;
            newKey.y4      = y4 - y1;
            newKey.tessTol = tessTol;

            return(newKey);
        }
Esempio n. 20
0
        public static PictureFlusher.CmdDraw stencil1(PictureFlusher.RenderLayer layer, uiMeshMesh mesh)
        {
            Vector4 viewport = layer.viewport;
            var     mat      = _stencilMat;

            var pass  = 2;
            var props = ObjectPool <MaterialPropertyBlockWrapper> .alloc();

            props.SetVector(_viewportId, viewport);

            return(PictureFlusher.CmdDraw.create(
                       mesh: mesh,
                       pass: pass,
                       material: mat,
                       properties: props
                       ));
        }
Esempio n. 21
0
        public static PictureFlusher.CmdDraw fill0(PictureFlusher.RenderLayer layer, uiMeshMesh mesh)
        {
            Vector4 viewport = layer.viewport;
            var     mat      = _fill0Mat.getMaterial(layer.ignoreClip);

            var pass  = 0;
            var props = ObjectPool <MaterialPropertyBlockWrapper> .alloc();

            props.SetVector(_viewportId, viewport);

            return(PictureFlusher.CmdDraw.create(
                       mesh: mesh,
                       pass: pass,
                       material: mat,
                       properties: props
                       ));
        }
Esempio n. 22
0
        public uiPicture endRecording()
        {
            if (this._states.Count > 1)
            {
                throw new Exception("unmatched save/restore commands");
            }

            uiList <int> stateUpdateIndices = ObjectPool <uiList <int> > .alloc();

            stateUpdateIndices.AddRange(this._stateUpdateIndices);
            var state = this._getState();

            return(uiPicture.create(
                       this._drawCmds,
                       state.paintBounds,
                       bbh: this._bbh,
                       stateUpdateIndices: stateUpdateIndices));
        }
Esempio n. 23
0
            public static CmdDraw create(uiMeshMesh mesh = null, TextBlobMesh textMesh = null, int pass = 0,
                                         MaterialPropertyBlockWrapper properties = null, int?layerId = null, Material material = null,
                                         Image image         = null, Mesh meshObj = null,
                                         bool meshObjCreated = false)
            {
                CmdDraw newCmd = ObjectPool <CmdDraw> .alloc();

                newCmd.mesh           = mesh;
                newCmd.textMesh       = textMesh;
                newCmd.pass           = pass;
                newCmd.properties     = properties;
                newCmd.layerId        = layerId;
                newCmd.material       = material;
                newCmd.image          = image;
                newCmd.meshObj        = meshObj;
                newCmd.meshObjCreated = meshObjCreated;

                return(newCmd);
            }
Esempio n. 24
0
            public static RenderLayer create(int rtID = 0, int width = 0, int height = 0,
                                             FilterMode filterMode = FilterMode.Bilinear,
                                             uiRect?layerBounds    = null, uiPaint?layerPaint = null, bool ignoreClip = true)
            {
                D.assert(layerBounds != null);
                var newLayer = ObjectPool <RenderLayer> .alloc();

                newLayer.rtID         = rtID;
                newLayer.width        = width;
                newLayer.height       = height;
                newLayer.filterMode   = filterMode;
                newLayer.layerBounds  = layerBounds.Value;
                newLayer.layerPaint   = layerPaint;
                newLayer.ignoreClip   = ignoreClip;
                newLayer.currentState = State.create();
                newLayer.states.Add(newLayer.currentState);
                newLayer.clipStack = ClipStack.create();

                return(newLayer);
            }
Esempio n. 25
0
        public static uiMeshMesh create(uiRect rect)
        {
            uiMeshMesh newMesh = ObjectPool <uiMeshMesh> .alloc();

            newMesh.vertices = ObjectPool <uiList <Vector3> > .alloc();

            newMesh.vertices.Add(new Vector3(rect.right, rect.bottom));
            newMesh.vertices.Add(new Vector3(rect.right, rect.top));
            newMesh.vertices.Add(new Vector3(rect.left, rect.bottom));
            newMesh.vertices.Add(new Vector3(rect.left, rect.top));

            newMesh.triangles = ObjectPool <uiList <int> > .alloc();

            newMesh.triangles.AddRange(_boundsTriangles);
            newMesh.rawBounds = rect;

            newMesh._bounds = newMesh.rawBounds;

            return(newMesh);
        }
Esempio n. 26
0
        public static PictureFlusher.CmdDraw maskFilter(PictureFlusher.RenderLayer layer, uiMeshMesh mesh,
                                                        PictureFlusher.RenderLayer renderLayer, float radius, Vector2 imgInc, float[] kernel)
        {
            Vector4 viewport = layer.viewport;
            var     mat      = _filterMat;

            var pass  = 0;
            var props = ObjectPool <MaterialPropertyBlockWrapper> .alloc();

            props.SetVector(_viewportId, viewport);

            props.SetFloat(_mfRadiusId, radius);
            props.SetVector(_mfImgIncId, imgInc);
            props.SetFloatArray(_mfKernelId, kernel);

            return(PictureFlusher.CmdDraw.create(
                       mesh: mesh,
                       pass: pass,
                       material: mat,
                       properties: props,
                       layerId: renderLayer.rtID
                       ));
        }
Esempio n. 27
0
        static void _getShaderPassAndProps(
            PictureFlusher.RenderLayer layer, uiPaint paint, uiMatrix3?meshMatrix, float alpha, float strokeMult,
            out int pass, out MaterialPropertyBlockWrapper props)
        {
            Vector4 viewport = layer.viewport;

            props = ObjectPool <MaterialPropertyBlockWrapper> .alloc();

            props.SetVector(_viewportId, viewport);
            props.SetFloat(_alphaId, alpha);
            props.SetFloat(_strokeMultId, strokeMult);

            switch (paint.shader)
            {
            case null:
                pass = 0;
                props.SetVector(_colorId, _colorToVector4(paint.color));
                return;

            case _LinearGradient linear:
                pass = 1;
                props.SetMatrix(_shaderMatId, linear.getGradientMat(
                                    _getShaderMatBase(layer.currentState, meshMatrix)).toMatrix4x4());
                props.SetTexture(_shaderTexId, linear.gradientTex.texture);
                props.SetVector(_leftColorId, _colorToVector4(linear.leftColor));
                props.SetVector(_rightColorId, _colorToVector4(linear.rightColor));
                props.SetInt(_tileModeId, (int)linear.tileMode);
                return;

            case _RadialGradient radial:
                pass = 2;
                props.SetMatrix(_shaderMatId, radial.getGradientMat(
                                    _getShaderMatBase(layer.currentState, meshMatrix)).toMatrix4x4());
                props.SetTexture(_shaderTexId, radial.gradientTex.texture);
                props.SetVector(_leftColorId, _colorToVector4(radial.leftColor));
                props.SetVector(_rightColorId, _colorToVector4(radial.rightColor));
                props.SetInt(_tileModeId, (int)radial.tileMode);
                return;

            case _SweepGradient sweep:
                pass = 3;
                props.SetMatrix(_shaderMatId, sweep.getGradientMat(
                                    _getShaderMatBase(layer.currentState, meshMatrix)).toMatrix4x4());
                props.SetTexture(_shaderTexId, sweep.gradientTex.texture);
                props.SetVector(_leftColorId, _colorToVector4(sweep.leftColor));
                props.SetVector(_rightColorId, _colorToVector4(sweep.rightColor));
                props.SetInt(_tileModeId, (int)sweep.tileMode);
                props.SetFloat(_biasId, sweep.bias);
                props.SetFloat(_scaleId, sweep.scale);
                return;

            case ImageShader image:
                pass = 4;
                props.SetMatrix(_shaderMatId, image.getShaderMat(
                                    _getShaderMatBase(layer.currentState, meshMatrix)).toMatrix4x4());
                props.SetTexture(_shaderTexId, image.image.texture);
                props.SetInt(_tileModeId, (int)image.tileMode);
                return;

            default:
                throw new Exception("Unknown paint.shader: " + paint.shader);
            }
        }
Esempio n. 28
0
        public void computeFillMesh(float fringe, out bool convex)
        {
            if (this._fillMesh != null && (fringe != 0.0f || this._strokeMesh != null) && this._fringe == fringe)
            {
                convex = this._fillConvex;
                return;
            }

            var verticesUV = this._expandFill(fringe);

            convex = this._fillConvex;

            var paths = this._paths;

            var cindices = 0;

            for (var i = 0; i < paths.Count; i++)
            {
                var path = paths[i];
                if (path.count <= 2)
                {
                    continue;
                }

                if (path.nfill > 0)
                {
                    D.assert(path.nfill >= 2);
                    cindices += (path.nfill - 2) * 3;
                }
            }

            var indices = ObjectPool <uiList <int> > .alloc();

            indices.SetCapacity(cindices);
            for (var i = 0; i < paths.Count; i++)
            {
                var path = paths[i];
                if (path.count <= 2)
                {
                    continue;
                }

                if (path.nfill > 0)
                {
                    for (var j = 2; j < path.nfill; j++)
                    {
                        indices.Add(path.ifill);
                        indices.Add(path.ifill + j);
                        indices.Add(path.ifill + j - 1);
                    }
                }
            }

            D.assert(indices.Count == cindices);

            if (verticesUV.strokeVertices != null)
            {
                cindices = 0;
                for (var i = 0; i < paths.Count; i++)
                {
                    var path = paths[i];
                    if (path.count <= 2)
                    {
                        continue;
                    }

                    if (path.nstroke > 0)
                    {
                        D.assert(path.nstroke >= 6);
                        cindices += path.nstroke * 3;
                    }
                }

                var strokeIndices = ObjectPool <uiList <int> > .alloc();

                strokeIndices.SetCapacity(cindices);
                for (var i = 0; i < paths.Count; i++)
                {
                    var path = paths[i];
                    if (path.count <= 2)
                    {
                        continue;
                    }

                    if (path.nstroke > 0)
                    {
                        strokeIndices.Add(path.istroke + path.nstroke - 1);
                        strokeIndices.Add(path.istroke + path.nstroke - 2);
                        strokeIndices.Add(path.istroke);
                        strokeIndices.Add(path.istroke + path.nstroke - 1);
                        strokeIndices.Add(path.istroke);
                        strokeIndices.Add(path.istroke + 1);
                        for (var j = 2; j < path.nstroke; j++)
                        {
                            if ((j & 1) == 0)
                            {
                                strokeIndices.Add(path.istroke + j - 1);
                                strokeIndices.Add(path.istroke + j - 2);
                                strokeIndices.Add(path.istroke + j);
                            }
                            else
                            {
                                strokeIndices.Add(path.istroke + j - 2);
                                strokeIndices.Add(path.istroke + j - 1);
                                strokeIndices.Add(path.istroke + j);
                            }
                        }
                    }
                }

                D.assert(strokeIndices.Count == cindices);

                ObjectPool <uiMeshMesh> .release(this._strokeMesh);

                this._strokeMesh = uiMeshMesh.create(null, verticesUV.strokeVertices, strokeIndices, verticesUV.strokeUV);
            }

            var mesh = uiMeshMesh.create(null, verticesUV.fillVertices, indices, verticesUV.fillUV);

            this._fillMesh = mesh;
            this._fringe   = fringe;
        }
Esempio n. 29
0
        public void computeStrokeMesh(float strokeWidth, float fringe, StrokeCap lineCap, StrokeJoin lineJoin, float miterLimit)
        {
            if (this._strokeMesh != null &&
                this._fillMesh == null && // Ensure that the cached stroke mesh was not calculated in computeFillMesh
                this._strokeWidth == strokeWidth &&
                this._fringe == fringe &&
                this._lineCap == lineCap &&
                this._lineJoin == lineJoin &&
                this._miterLimit == miterLimit)
            {
                return;
            }

            var verticesUV = this._expandStroke(strokeWidth, fringe, lineCap, lineJoin, miterLimit);

            var paths = this._paths;

            var cindices = 0;

            for (var i = 0; i < paths.Count; i++)
            {
                var path = paths[i];
                if (path.count <= 1)
                {
                    continue;
                }

                if (path.nstroke > 0)
                {
                    D.assert(path.nstroke >= 2);
                    cindices += (path.nstroke - 2) * 3;
                }
            }

            var indices = ObjectPool <uiList <int> > .alloc();

            indices.SetCapacity(cindices);
            for (var i = 0; i < paths.Count; i++)
            {
                var path = paths[i];
                if (path.count <= 1)
                {
                    continue;
                }

                if (path.nstroke > 0)
                {
                    for (var j = 2; j < path.nstroke; j++)
                    {
                        if ((j & 1) == 0)
                        {
                            indices.Add(path.istroke + j - 1);
                            indices.Add(path.istroke + j - 2);
                            indices.Add(path.istroke + j);
                        }
                        else
                        {
                            indices.Add(path.istroke + j - 2);
                            indices.Add(path.istroke + j - 1);
                            indices.Add(path.istroke + j);
                        }
                    }
                }
            }

            D.assert(indices.Count == cindices);

            ObjectPool <uiMeshMesh> .release(this._strokeMesh);

            this._strokeMesh = uiMeshMesh.create(null, verticesUV.strokeVertices, indices, verticesUV.strokeUV);
            ObjectPool <uiMeshMesh> .release(this._fillMesh);

            this._fillMesh    = null;
            this._strokeWidth = strokeWidth;
            this._fringe      = fringe;
            this._lineCap     = lineCap;
            this._lineJoin    = lineJoin;
            this._miterLimit  = miterLimit;
            return;
        }
Esempio n. 30
0
        uiVertexUV _expandFill(float fringe)
        {
            float aa     = fringe;
            float woff   = aa * 0.5f;
            var   points = this._points;
            var   paths  = this._paths;

            this._calculateJoins(fringe, StrokeJoin.miter, 4.0f);

            var cvertices = 0;

            for (var i = 0; i < paths.Count; i++)
            {
                var path = paths[i];
                if (path.count <= 2)
                {
                    continue;
                }

                cvertices += path.count;
            }

            this._fillConvex = false;
            for (var i = 0; i < paths.Count; i++)
            {
                var path = paths[i];
                if (path.count <= 2)
                {
                    continue;
                }

                if (this._fillConvex)
                {
                    // if more than two paths, convex is false.
                    this._fillConvex = false;
                    break;
                }

                if (!path.convex)
                {
                    // if not convex, convex is false.
                    break;
                }

                this._fillConvex = true;
            }

            var _vertices = ObjectPool <uiList <Vector3> > .alloc();

            _vertices.SetCapacity(cvertices);
            var _uv = ObjectPool <uiList <Vector2> > .alloc();

            _uv.SetCapacity(cvertices);
            for (var i = 0; i < paths.Count; i++)
            {
                var path = paths[i];
                if (path.count <= 2)
                {
                    continue;
                }

                path.ifill = _vertices.Count;
                for (var j = 0; j < path.count; j++)
                {
                    var p = points[path.first + j];
                    if (aa > 0.0f)
                    {
                        _vertices.Add(new Vector2(p.x + p.dmx * woff, p.y + p.dmy * woff));
                    }
                    else
                    {
                        _vertices.Add(new Vector2(p.x, p.y));
                    }

                    _uv.Add(new Vector2(0.5f, 1.0f));
                }

                path.nfill = _vertices.Count - path.ifill;
                paths[i]   = path;
            }

            uiList <Vector3> _strokeVertices = null;
            uiList <Vector2> _strokeUV       = null;

            if (aa > 0.0f)
            {
                _strokeVertices = ObjectPool <uiList <Vector3> > .alloc();

                _strokeUV = ObjectPool <uiList <Vector2> > .alloc();

                cvertices = 0;
                for (var i = 0; i < paths.Count; i++)
                {
                    var path = paths[i];
                    if (path.count <= 2)
                    {
                        continue;
                    }

                    cvertices += path.count * 2;
                }
                _strokeVertices.SetCapacity(cvertices);
                _strokeUV.SetCapacity(cvertices);

                float lw = this._fillConvex ? woff : aa + woff;
                float rw = aa - woff;
                float lu = this._fillConvex ? 0.5f : 0.0f;
                float ru = 1.0f;

                for (var i = 0; i < paths.Count; i++)
                {
                    var path = paths[i];
                    if (path.count <= 2)
                    {
                        continue;
                    }

                    path.istroke = _strokeVertices.Count;
                    for (var j = 0; j < path.count; j++)
                    {
                        var p = points[path.first + j];
                        _strokeVertices.Add(new Vector2(p.x + p.dmx * lw, p.y + p.dmy * lw));
                        _strokeUV.Add(new Vector2(lu, 1.0f));
                        _strokeVertices.Add(new Vector2(p.x - p.dmx * rw, p.y - p.dmy * rw));
                        _strokeUV.Add(new Vector2(ru, 1.0f));
                    }

                    path.nstroke = _strokeVertices.Count - path.istroke;
                    paths[i]     = path;
                }
            }

            return(new uiVertexUV {
                fillVertices = _vertices,
                fillUV = _uv,
                strokeVertices = _strokeVertices,
                strokeUV = _strokeUV,
            });
        }