예제 #1
0
        public static uiPath create(int capacity = 128)
        {
            uiPath newPath = ObjectPool <uiPath> .alloc();

            newPath._reset();
            return(newPath);
        }
예제 #2
0
        void _clipPath(uiPath path)
        {
            var layer = this._currentLayer;
            var state = layer.currentState;

            layer.clipStack.clipPath(path, state.matrix.Value, state.scale * this._devicePixelRatio);
        }
예제 #3
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);
        }
예제 #4
0
 public static void putToCache(uiPath uipath)
 {
     if (!uipath.needCache)
     {
         ObjectPool <uiPath> .release(uipath);
     }
 }
예제 #5
0
        public static bool tryGetUiPath(uint pathKey, out uiPath outpath)
        {
            if (cache.ContainsKey(pathKey))
            {
                touched[pathKey] = true;
                outpath          = cache[pathKey];
                return(true);
            }

            var uipath = uiPath.create();

            cache[pathKey]   = uipath;
            touched[pathKey] = true;

            uipath.needCache = true;
            uipath.pathKey   = pathKey;

            outpath = uipath;
            return(false);
        }
예제 #6
0
        void _drawPath(uiPath path, uiPaint paint)
        {
            D.assert(path != null);

            //draw fast shadow
            if (paint.maskFilter != null && paint.maskFilter.Value.style == BlurStyle.fast_shadow)
            {
                this._drawRRectShadow(path, paint);
                return;
            }

            if (paint.style == PaintingStyle.fill)
            {
                var state = this._currentLayer.currentState;
                var cache = path.flatten(state.scale * this._devicePixelRatio);

                bool convex;
                cache.computeFillMesh(this._fringeWidth, out convex);
                var   fillMesh   = cache.fillMesh;
                var   strokeMesh = cache.strokeMesh;
                var   fmesh      = fillMesh.transform(state.matrix);
                var   smesh      = strokeMesh?.transform(state.matrix);
                float strokeMult = 1.0f;

                if (paint.maskFilter != null && paint.maskFilter.Value.sigma != 0)
                {
                    this._drawWithMaskFilter(fmesh.bounds, paint, paint.maskFilter.Value, fmesh, smesh, convex, 0,
                                             strokeMult, null,
                                             uiRectHelper.zero, null, false, this.___drawPathDrawMeshCallback);
                    return;
                }

                this._drawPathDrawMeshCallback(paint, fmesh, smesh, convex, 1.0f, strokeMult, null, uiRectHelper.zero,
                                               null, false);
            }
            else
            {
                var   state       = this._currentLayer.currentState;
                float strokeWidth = (paint.strokeWidth * state.scale).clamp(0, 200.0f);
                float alpha       = 1.0f;

                if (strokeWidth == 0)
                {
                    strokeWidth = this._fringeWidth;
                }
                else if (strokeWidth < this._fringeWidth)
                {
                    // If the stroke width is less than pixel size, use alpha to emulate coverage.
                    // Since coverage is area, scale by alpha*alpha.
                    alpha       = (strokeWidth / this._fringeWidth).clamp(0.0f, 1.0f);
                    alpha      *= alpha;
                    strokeWidth = this._fringeWidth;
                }

                strokeWidth = strokeWidth / state.scale * 0.5f;
                float strokeMult = (this._fringeWidth * 0.5f + strokeWidth * 0.5f) / this._fringeWidth;

                var cache = path.flatten(state.scale * this._devicePixelRatio);

                cache.computeStrokeMesh(
                    strokeWidth,
                    this._fringeWidth,
                    paint.strokeCap,
                    paint.strokeJoin,
                    paint.strokeMiterLimit);
                var strokeMesh = cache.strokeMesh;

                var mesh = strokeMesh.transform(state.matrix);

                if (paint.maskFilter != null && paint.maskFilter.Value.sigma != 0)
                {
                    this._drawWithMaskFilter(mesh.bounds, paint, paint.maskFilter.Value, null, mesh, false, alpha,
                                             strokeMult, null,
                                             uiRectHelper.zero, null, false, this.___drawPathDrawMeshCallback2);
                    return;
                }

                this._drawPathDrawMeshCallback2(paint, null, mesh, false, alpha, strokeMult, null, uiRectHelper.zero,
                                                null, false);
            }
        }
        void _drawRRectShadow(uiPath path, uiPaint paint)
        {
            D.assert(path.isNaiveRRect, () => "Cannot draw fast Shadow for non-NaiveRRect shapes");
            D.assert(paint.style == PaintingStyle.fill, () => "Cannot draw fast Shadow for stroke lines");
            var layer = this._currentLayer;
            var state = layer.currentState;

            var  cache = path.flatten(state.scale * this._devicePixelRatio);
            bool convex;

            cache.computeFillMesh(this._fringeWidth, out convex);
            var fillMesh   = cache.fillMesh;
            var meshBounds = fillMesh.transform(state.matrix);
            var clipBounds = layer.layerBounds;

            uiRect?stackBounds;
            bool   iior;

            layer.clipStack.getBounds(out stackBounds, out iior);

            if (stackBounds != null)
            {
                clipBounds = uiRectHelper.intersect(clipBounds, stackBounds.Value);
            }

            if (clipBounds.isEmpty)
            {
                ObjectPool <uiMeshMesh> .release(meshBounds);

                return;
            }

            var maskBounds = meshBounds.bounds;

            maskBounds = uiRectHelper.intersect(maskBounds, clipBounds);
            if (maskBounds.isEmpty)
            {
                ObjectPool <uiMeshMesh> .release(meshBounds);

                return;
            }

            var blurMesh = ImageMeshGenerator.imageMesh(null, uiRectHelper.one, maskBounds);

            if (!this._applyClip(blurMesh.bounds))
            {
                ObjectPool <uiMeshMesh> .release(meshBounds);

                ObjectPool <uiMeshMesh> .release(blurMesh);

                return;
            }

            var bound = path.getBounds();
            var sigma = state.scale * paint.maskFilter.Value.sigma / 3f;

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

            vertices.SetCapacity(4);
            vertices.Add(new Vector2(0, 0));
            vertices.Add(new Vector2(1, 0));
            vertices.Add(new Vector2(0, 1));
            vertices.Add(new Vector2(1, 1));

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

            _triangles.SetCapacity(6);
            _triangles.Add(0);
            _triangles.Add(1);
            _triangles.Add(2);
            _triangles.Add(2);
            _triangles.Add(1);
            _triangles.Add(3);

            ObjectPool <uiMeshMesh> .release(meshBounds);

            ObjectPool <uiMeshMesh> .release(blurMesh);

            var mesh        = uiMeshMesh.create(state.matrix, vertices, _triangles);
            var shadowColor = paint.color.withAlpha(128);

            layer.draws.Add(CanvasShader.fastShadow(layer, mesh, sigma, path.isRect, path.isCircle, path.rRectCorner, new Vector4(bound.left, bound.top, bound.right, bound.bottom), shadowColor));
        }
예제 #8
0
        public void clipPath(uiPath uiPath, uiMatrix3 matrix, float scale)
        {
            var element = ClipElement.create(this._saveCount, uiPath, matrix, scale);

            this._pushElement(element);
        }