Пример #1
0
        void _drawImageRect(Image image, uiRect?src, uiRect dst, uiPaint paint)
        {
            D.assert(image != null && image.valid);

            if (image == null || !image.valid)
            {
                return;
            }

            if (src == null)
            {
                src = uiRectHelper.one;
            }
            else
            {
                src = uiRectHelper.scale(src.Value, 1f / image.width, 1f / image.height);
            }

            var layer = this._currentLayer;
            var state = layer.currentState;
            var mesh  = ImageMeshGenerator.imageMesh(state.matrix, src.Value, dst);

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

                return;
            }

            layer.draws.Add(CanvasShader.tex(layer, paint, mesh, image));
        }
Пример #2
0
        void _drawPathDrawMeshCallback(uiPaint p, uiMeshMesh fillMesh, uiMeshMesh strokeMesh, bool convex, float alpha,
                                       float strokeMult, Texture tex,
                                       uiRect textBlobBounds, TextBlobMesh textMesh, bool notEmoji)
        {
            if (!this._applyClip(fillMesh.bounds))
            {
                ObjectPool <uiMeshMesh> .release(fillMesh);

                ObjectPool <uiMeshMesh> .release(strokeMesh);

                return;
            }

            var layer = this._currentLayer;

            if (convex)
            {
                layer.draws.Add(CanvasShader.convexFill(layer, p, fillMesh));
            }
            else
            {
                layer.draws.Add(CanvasShader.fill0(layer, fillMesh));
                layer.draws.Add(CanvasShader.fill1(layer, p, fillMesh.boundsMesh));
            }

            if (strokeMesh != null)
            {
                layer.draws.Add(CanvasShader.strokeAlpha(layer, p, alpha, strokeMult, strokeMesh));
                layer.draws.Add(CanvasShader.stroke1(layer, strokeMesh.duplicate()));
            }
        }
Пример #3
0
        void _drawImageNine(Image image, uiRect?src, uiRect center, uiRect dst, uiPaint paint)
        {
            D.assert(image != null);

            var scaleX = 1f / image.width;
            var scaleY = 1f / image.height;

            if (src == null)
            {
                src = uiRectHelper.one;
            }
            else
            {
                src = uiRectHelper.scale(src.Value, scaleX, scaleY);
            }

            center = uiRectHelper.scale(center, scaleX, scaleY);

            var layer = this._currentLayer;
            var state = layer.currentState;

            var mesh = ImageMeshGenerator.imageNineMesh(state.matrix, src.Value, center, image.width, image.height,
                                                        dst);

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

                return;
            }

            layer.draws.Add(CanvasShader.tex(layer, paint, mesh, image));
        }
Пример #4
0
        void _drawWithMaskFilter(uiRect meshBounds, uiPaint paint, uiMaskFilter maskFilter,
                                 uiMeshMesh fillMesh, uiMeshMesh strokeMesh, bool convex, float alpha, float strokeMult, Texture tex,
                                 uiRect texBound, TextBlobMesh textMesh, bool notEmoji,
                                 _drawPathDrawMeshCallbackDelegate drawCallback)
        {
            var layer      = this._currentLayer;
            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)
            {
                this._drawPathDrawMeshQuit(fillMesh, strokeMesh, textMesh);
                return;
            }

            var   state = layer.currentState;
            float sigma = state.scale * maskFilter.sigma;

            if (sigma <= 0)
            {
                this._drawPathDrawMeshQuit(fillMesh, strokeMesh, textMesh);
                return;
            }

            float sigma3     = 3 * sigma;
            var   maskBounds = uiRectHelper.inflate(meshBounds, sigma3);

            maskBounds = uiRectHelper.intersect(maskBounds, uiRectHelper.inflate(clipBounds, sigma3));
            if (maskBounds.isEmpty)
            {
                this._drawPathDrawMeshQuit(fillMesh, strokeMesh, textMesh);
                return;
            }

            var maskLayer = this._createMaskLayer(layer, maskBounds, drawCallback, paint, convex, alpha, strokeMult,
                                                  tex, texBound,
                                                  textMesh, fillMesh, strokeMesh, notEmoji);

            var blurLayer = this._createBlurLayer(maskLayer, sigma, sigma, layer);

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

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

                return;
            }

            layer.draws.Add(CanvasShader.texRT(layer, paint, blurMesh, blurLayer));
        }
Пример #5
0
        void _drawTextDrawMeshCallback(uiPaint p, uiMeshMesh fillMesh, uiMeshMesh strokeMesh, bool convex, float alpha,
                                       float strokeMult, Texture tex,
                                       uiRect textBlobBounds, TextBlobMesh textMesh, bool notEmoji)
        {
            if (!this._applyClip(textBlobBounds))
            {
                ObjectPool <TextBlobMesh> .release(textMesh);

                return;
            }

            var layer = this._currentLayer;

            if (notEmoji)
            {
                layer.draws.Add(CanvasShader.texAlpha(layer, p, textMesh, tex));
            }
            else
            {
                uiPaint paintWithWhite = new uiPaint(p);
                paintWithWhite.color = uiColor.white;
                if (EmojiUtils.image == null)
                {
                    ObjectPool <TextBlobMesh> .release(textMesh);

                    return;
                }

                var raw_mesh = textMesh.resolveMesh();
                var meshmesh = raw_mesh.duplicate();
                ObjectPool <TextBlobMesh> .release(textMesh);

                layer.draws.Add(CanvasShader.tex(layer, paintWithWhite, meshmesh, EmojiUtils.image));
            }
        }
Пример #6
0
 public static uiPaint shapeOnly(uiPaint paint)
 {
     return(new uiPaint(
                style: paint.style,
                strokeWidth: paint.strokeWidth,
                strokeCap: paint.strokeCap,
                strokeJoin: paint.strokeJoin,
                strokeMiterLimit: paint.strokeMiterLimit
                ));
 }
Пример #7
0
        void _drawImage(Image image, uiOffset offset, uiPaint paint)
        {
            D.assert(image != null);

            this._drawImageRect(image,
                                null,
                                uiRectHelper.fromLTWH(
                                    offset.dx, offset.dy,
                                    image.width / this._devicePixelRatio,
                                    image.height / this._devicePixelRatio),
                                paint);
        }
Пример #8
0
        void _drawPathDrawMeshCallback2(uiPaint p, uiMeshMesh mesh, bool convex, float alpha, Texture tex,
                                        uiRect textBlobBounds, TextBlobMesh textMesh, bool notEmoji)
        {
            if (!this._applyClip(mesh.bounds))
            {
                ObjectPool <uiMeshMesh> .release(mesh);

                return;
            }

            var layer = this._currentLayer;

            layer.draws.Add(CanvasShader.stroke0(layer, p, alpha, mesh));
            layer.draws.Add(CanvasShader.stroke1(layer, mesh.duplicate()));
        }
Пример #9
0
        RenderLayer _createMaskLayer(RenderLayer parentLayer, uiRect maskBounds,
                                     _drawPathDrawMeshCallbackDelegate drawCallback,
                                     uiPaint paint, bool convex, float alpha, float strokeMult, Texture tex, uiRect texBound,
                                     TextBlobMesh textMesh,
                                     uiMeshMesh fillMesh, uiMeshMesh strokeMesh, bool notEmoji)
        {
            var textureWidth = Mathf.CeilToInt(maskBounds.width * this._devicePixelRatio);

            if (textureWidth < 1)
            {
                textureWidth = 1;
            }

            var textureHeight = Mathf.CeilToInt(maskBounds.height * this._devicePixelRatio);

            if (textureHeight < 1)
            {
                textureHeight = 1;
            }

            var maskLayer = RenderLayer.create(
                rtID: Shader.PropertyToID(this._getNewRenderTextureKey()),
                width: textureWidth,
                height: textureHeight,
                layerBounds: maskBounds,
                filterMode: FilterMode.Bilinear,
                noMSAA: true
                );

            parentLayer.addLayer(maskLayer);
            this._layers.Add(maskLayer);
            this._currentLayer = maskLayer;

            var parentState = parentLayer.states[parentLayer.states.Count - 1];
            var maskState   = maskLayer.states[maskLayer.states.Count - 1];

            maskState.matrix = parentState.matrix;

            drawCallback.Invoke(uiPaint.shapeOnly(paint), fillMesh, strokeMesh, convex, alpha, strokeMult, tex,
                                texBound, textMesh, notEmoji);

            var removed = this._layers.removeLast();

            D.assert(removed == maskLayer);
            this._currentLayer = this._layers[this._layers.Count - 1];

            return(maskLayer);
        }
Пример #10
0
 public uiPaint(uiPaint paint)
 {
     this.color            = paint.color;
     this.blendMode        = paint.blendMode;
     this.style            = paint.style;
     this.strokeWidth      = paint.strokeWidth;
     this.strokeCap        = paint.strokeCap;
     this.strokeJoin       = paint.strokeJoin;
     this.strokeMiterLimit = paint.strokeMiterLimit;
     this.filterMode       = paint.filterMode;
     this.colorFilter      = paint.colorFilter;
     this.maskFilter       = paint.maskFilter;
     this.backdrop         = paint.backdrop;
     this.shader           = paint.shader;
     this.invertColors     = paint.invertColors;
 }
Пример #11
0
        public static PictureFlusher.CmdDraw texRT(PictureFlusher.RenderLayer layer, uiPaint paint,
                                                   uiMeshMesh mesh, PictureFlusher.RenderLayer renderLayer)
        {
            var mat = _texMat.getMaterial(paint.blendMode, layer.ignoreClip);

            _getShaderPassAndProps(layer, paint, mesh.matrix, 1.0f, 0.0f, out var pass, out var props);
            props.SetInt(_texModeId, 1); // pre alpha

            return(PictureFlusher.CmdDraw.create(
                       mesh: mesh,
                       pass: pass,
                       material: mat,
                       properties: props,
                       layerId: renderLayer.rtID
                       ));
        }
Пример #12
0
        void _drawImage(Image image, uiOffset offset, uiPaint paint)
        {
            D.assert(image != null && image.valid);

            if (image == null || !image.valid)
            {
                return;
            }

            this._drawImageRect(image,
                                null,
                                uiRectHelper.fromLTWH(
                                    offset.dx, offset.dy,
                                    image.width / this._devicePixelRatio,
                                    image.height / this._devicePixelRatio),
                                paint);
        }
Пример #13
0
        public static PictureFlusher.CmdDraw fill1(PictureFlusher.RenderLayer layer, uiPaint paint,
                                                   uiMeshMesh mesh)
        {
            var mat = _fill1Mat.getMaterial(paint.blendMode);

            _getShaderPassAndProps(layer, paint, mesh.matrix, 1.0f, 0.0f, out var pass, out var props);

            var ret = PictureFlusher.CmdDraw.create(
                mesh: mesh.boundsMesh,
                pass: pass,
                material: mat,
                properties: props
                );

            ObjectPool <uiMeshMesh> .release(mesh);

            return(ret);
        }
Пример #14
0
        public static PictureFlusher.CmdDraw tex(PictureFlusher.RenderLayer layer, uiPaint paint,
                                                 uiMeshMesh mesh, Image image)
        {
            var mat = _texMat.getMaterial(paint.blendMode, layer.ignoreClip);

            _getShaderPassAndProps(layer, paint, mesh.matrix, 1.0f, 0.0f, out var pass, out var props);

            image.texture.filterMode = paint.filterMode;
            props.SetTexture(_texId, image.texture);
            props.SetInt(_texModeId, image.texture is RenderTexture || image.isDynamic ? 1 : 0); // pre alpha if RT else post alpha

            return(PictureFlusher.CmdDraw.create(
                       mesh: mesh,
                       pass: pass,
                       material: mat,
                       properties: props,
                       image: image // keep a reference to avoid GC.
                       ));
        }
Пример #15
0
        void _drawPathDrawMeshCallback(uiPaint p, uiMeshMesh mesh, bool convex, float alpha, Texture tex,
                                       uiRect textBlobBounds, TextBlobMesh textMesh, bool notEmoji)
        {
            if (!this._applyClip(mesh.bounds))
            {
                ObjectPool <uiMeshMesh> .release(mesh);

                return;
            }

            var layer = this._currentLayer;

            if (convex)
            {
                layer.draws.Add(CanvasShader.convexFill(layer, p, mesh));
            }
            else
            {
                layer.draws.Add(CanvasShader.fill0(layer, mesh));
                layer.draws.Add(CanvasShader.fill1(layer, p, mesh.boundsMesh));
            }
        }
Пример #16
0
        void _drawTextBlob(TextBlob?textBlob, uiOffset offset, uiPaint paint)
        {
            D.assert(textBlob != null);

            var state = this._currentLayer.currentState;
            var scale = state.scale * this._devicePixelRatio;

            var matrix = new uiMatrix3(state.matrix.Value);

            matrix.preTranslate(offset.dx, offset.dy);

            var mesh           = TextBlobMesh.create(textBlob.Value, scale, matrix);
            var textBlobBounds = matrix.mapRect(uiRectHelper.fromRect(textBlob.Value.boundsInText));

            // request font texture so text mesh could be generated correctly
            var     style          = textBlob.Value.style;
            var     font           = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle).font;
            var     fontSizeToLoad = Mathf.CeilToInt(style.UnityFontSize * scale);
            var     subText        = textBlob.Value.text.Substring(textBlob.Value.textOffset, textBlob.Value.textSize);
            Texture tex            = null;
            bool    notEmoji       = !char.IsHighSurrogate(subText[0]) && !EmojiUtils.isSingleCharEmoji(subText[0]);

            if (notEmoji)
            {
                font.RequestCharactersInTextureSafe(subText, fontSizeToLoad, style.UnityFontStyle);
                tex = font.material.mainTexture;
            }

            if (paint.maskFilter != null && paint.maskFilter.Value.sigma != 0)
            {
                this._drawWithMaskFilter(textBlobBounds, paint, paint.maskFilter.Value, null, null, false, 0, 0, tex,
                                         textBlobBounds, mesh, notEmoji, this.___drawTextDrawMeshCallback);
                return;
            }

            this._drawTextDrawMeshCallback(paint, null, null, false, 0, 0, tex, textBlobBounds, mesh, notEmoji);
        }
Пример #17
0
        public static PictureFlusher.CmdDraw texAlpha(PictureFlusher.RenderLayer layer, uiPaint paint,
                                                      uiMeshMesh mesh, TextBlobMesh textMesh, Texture tex)
        {
            var mat        = _texMat.getMaterial(paint.blendMode, layer.ignoreClip);
            var meshMatrix = mesh != null ? mesh.matrix : textMesh.matrix;

            _getShaderPassAndProps(layer, paint, meshMatrix, 1.0f, 0.0f, out var pass, out var props);
            tex.filterMode = paint.filterMode;
            props.SetTexture(_texId, tex);
            props.SetInt(_texModeId, 2); // alpha only

            return(PictureFlusher.CmdDraw.create(
                       mesh: mesh,
                       textMesh: textMesh,
                       pass: pass,
                       material: mat,
                       properties: props
                       ));
        }
Пример #18
0
 public static PictureFlusher.CmdDraw texAlpha(PictureFlusher.RenderLayer layer, uiPaint paint,
                                               TextBlobMesh textMesh, Texture tex)
 {
     return(texAlpha(layer, paint, null, textMesh, tex));
 }
Пример #19
0
        public static PictureFlusher.CmdDraw strokeAlpha(PictureFlusher.RenderLayer layer, uiPaint paint, float alpha, float strokeMult, uiMeshMesh mesh)
        {
            var mat = _strokeAlphaMat.getMaterial(paint.blendMode, layer.ignoreClip);

            _getShaderPassAndProps(layer, paint, mesh.matrix, alpha, strokeMult, out var pass, out var props);

            return(PictureFlusher.CmdDraw.create(
                       mesh: mesh,
                       pass: pass,
                       material: mat,
                       properties: props
                       ));
        }
Пример #20
0
        public static PictureFlusher.CmdDraw convexFill(PictureFlusher.RenderLayer layer, uiPaint paint,
                                                        uiMeshMesh mesh)
        {
            var mat = _convexFillMat.getMaterial(paint.blendMode, layer.ignoreClip);

            _getShaderPassAndProps(layer, paint, mesh.matrix, 1.0f, 0.0f, out var pass, out var props);

            return(PictureFlusher.CmdDraw.create(
                       mesh: mesh,
                       pass: pass,
                       material: mat,
                       properties: props
                       ));
        }
Пример #21
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);
            }
        }
        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));
        }
Пример #23
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);
            }
        }
Пример #24
0
        void _saveLayer(uiRect bounds, uiPaint paint)
        {
            D.assert(bounds.width > 0);
            D.assert(bounds.height > 0);

            var parentLayer  = this._currentLayer;
            var state        = parentLayer.currentState;
            var textureWidth = Mathf.CeilToInt(
                bounds.width * state.scale * this._devicePixelRatio);

            if (textureWidth < 1)
            {
                textureWidth = 1;
            }

            var textureHeight = Mathf.CeilToInt(
                bounds.height * state.scale * this._devicePixelRatio);

            if (textureHeight < 1)
            {
                textureHeight = 1;
            }

            var layer = RenderLayer.create(
                rtID: Shader.PropertyToID(this._getNewRenderTextureKey()),
                width: textureWidth,
                height: textureHeight,
                layerBounds: bounds,
                layerPaint: paint
                );

            parentLayer.addLayer(layer);
            this._layers.Add(layer);
            this._currentLayer = layer;

            if (paint.backdrop != null)
            {
                if (paint.backdrop is _uiBlurImageFilter)
                {
                    var filter = (_uiBlurImageFilter)paint.backdrop;
                    if (!(filter.sigmaX == 0 && filter.sigmaY == 0))
                    {
                        _cachedPoints[0] = bounds.topLeft;
                        _cachedPoints[1] = bounds.bottomLeft;
                        _cachedPoints[2] = bounds.bottomRight;
                        _cachedPoints[3] = bounds.topRight;

                        state.matrix.Value.mapPoints(ref _cachedPoints);

                        var parentBounds = parentLayer.layerBounds;
                        for (int i = 0; i < 4; i++)
                        {
                            _cachedPoints[i] = new uiOffset(
                                (_cachedPoints[i].dx - parentBounds.left) / parentBounds.width,
                                (_cachedPoints[i].dy - parentBounds.top) / parentBounds.height
                                );
                        }

                        var mesh = ImageMeshGenerator.imageMesh(
                            null,
                            _cachedPoints[0],
                            _cachedPoints[1],
                            _cachedPoints[2],
                            _cachedPoints[3],
                            bounds);
                        var renderDraw = CanvasShader.texRT(layer, layer.layerPaint.Value, mesh, parentLayer);
                        layer.draws.Add(renderDraw);

                        var blurLayer = this._createBlurLayer(layer, filter.sigmaX, filter.sigmaY, layer);
                        var blurMesh  = ImageMeshGenerator.imageMesh(null, uiRectHelper.one, bounds);
                        layer.draws.Add(CanvasShader.texRT(layer, paint, blurMesh, blurLayer));
                    }
                }
                else if (paint.backdrop is _uiMatrixImageFilter)
                {
                    var filter = (_uiMatrixImageFilter)paint.backdrop;
                    if (!filter.transform.isIdentity())
                    {
                        layer.filterMode = filter.filterMode;

                        _cachedPoints[0] = bounds.topLeft;
                        _cachedPoints[1] = bounds.bottomLeft;
                        _cachedPoints[2] = bounds.bottomRight;
                        _cachedPoints[3] = bounds.topRight;

                        state.matrix.Value.mapPoints(ref _cachedPoints);

                        var parentBounds = parentLayer.layerBounds;
                        for (int i = 0; i < 4; i++)
                        {
                            _cachedPoints[i] = new uiOffset(
                                (_cachedPoints[i].dx - parentBounds.left) / parentBounds.width,
                                (_cachedPoints[i].dy - parentBounds.top) / parentBounds.height
                                );
                        }

                        var matrix = uiMatrix3.makeTrans(-bounds.left, -bounds.top);
                        matrix.postConcat(filter.transform);
                        matrix.postTranslate(bounds.left, bounds.top);

                        var mesh = ImageMeshGenerator.imageMesh(
                            matrix,
                            _cachedPoints[0],
                            _cachedPoints[1],
                            _cachedPoints[2],
                            _cachedPoints[3],
                            bounds);
                        var renderDraw = CanvasShader.texRT(layer, layer.layerPaint.Value, mesh, parentLayer);
                        layer.draws.Add(renderDraw);
                    }
                }
            }
        }