Exemple #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));
        }
Exemple #2
0
        void _restore()
        {
            var layer = this._currentLayer;

            D.assert(layer.states.Count > 0);
            if (layer.states.Count > 1)
            {
                ObjectPool <State> .release(layer.states[layer.states.Count - 1]);

                layer.states.RemoveAt(layer.states.Count - 1);
                layer.currentState = layer.states[layer.states.Count - 1];
                layer.clipStack.restore();
                return;
            }

            this._layers.RemoveAt(this._layers.Count - 1);
            var currentLayer = this._currentLayer = this._layers[this._layers.Count - 1];
            var state        = currentLayer.currentState;

            var mesh = ImageMeshGenerator.imageMesh(state.matrix, uiRectHelper.one, layer.layerBounds);

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

                return;
            }

            var renderDraw = CanvasShader.texRT(currentLayer, layer.layerPaint.Value, mesh, layer);

            currentLayer.draws.Add(renderDraw);
        }
Exemple #3
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));
        }
Exemple #4
0
        void _drawImageRect(Image image, Rect src, Rect dst, Paint paint)
        {
            D.assert(image != null);
            D.assert(dst != null);
            D.assert(paint != null);

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

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

            if (!this._applyClip(mesh.bounds))
            {
                return;
            }

            layer.draws.Add(CanvasShader.tex(layer, paint, mesh, image));
        }
Exemple #5
0
        public void restore()
        {
            this._saveCount--;

            var layer = this._getLayer();

            D.assert(layer.states.Count > 0);
            if (layer.states.Count > 1)
            {
                layer.states.RemoveAt(layer.states.Count - 1);
                layer.clipStack.restore();
                return;
            }

            this._layers.RemoveAt(this._layers.Count - 1);
            var state = this._getState();

            var mesh = ImageMeshGenerator.imageMesh(state.matrix, Rect.one, layer.layerBounds);

            if (!this._applyClip(mesh.bounds))
            {
                return;
            }

            var renderDraw = CanvasShader.texRT(this._getLayer(), layer.layerPaint, mesh, layer);

            this._getLayer().draws.Add(renderDraw);
        }
Exemple #6
0
        RenderLayer _createBlurLayer(RenderLayer maskLayer, float sigmaX, float sigmaY, RenderLayer parentLayer)
        {
            sigmaX = BlurUtils.adjustSigma(sigmaX, out var scaleFactorX, out var radiusX);
            sigmaY = BlurUtils.adjustSigma(sigmaY, out var scaleFactorY, out var radiusY);

            var textureWidth = Mathf.CeilToInt((float)maskLayer.width / scaleFactorX);

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

            var textureHeight = Mathf.CeilToInt((float)maskLayer.height / scaleFactorY);

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

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

            parentLayer.addLayer(blurXLayer);

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

            parentLayer.addLayer(blurYLayer);

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

            var kernelX = BlurUtils.get1DGaussianKernel(sigmaX, radiusX);
            var kernelY = BlurUtils.get1DGaussianKernel(sigmaY, radiusY);

            blurXLayer.draws.Add(CanvasShader.maskFilter(
                                     blurXLayer, blurMesh, maskLayer,
                                     radiusX, new Vector2(1f / textureWidth, 0), kernelX));

            blurYLayer.draws.Add(CanvasShader.maskFilter(
                                     blurYLayer, blurMesh.duplicate(), blurXLayer,
                                     radiusY, new Vector2(0, -1f / textureHeight), kernelY));

            return(blurYLayer);
        }
Exemple #7
0
        RenderLayer _createBlurLayer(RenderLayer maskLayer, float sigma, RenderLayer parentLayer)
        {
            sigma = BlurUtils.adjustSigma(sigma, out var scaleFactor, out var radius);

            var textureWidth = Mathf.CeilToInt((float)maskLayer.width / scaleFactor);

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

            var textureHeight = Mathf.CeilToInt((float)maskLayer.height / scaleFactor);

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

            var blurXLayer = new RenderLayer {
                rtID        = Shader.PropertyToID("_rtID_" + this._layers.Count + "_" + parentLayer.layers.Count),
                width       = textureWidth,
                height      = textureHeight,
                layerBounds = maskLayer.layerBounds,
                filterMode  = FilterMode.Bilinear,
            };

            parentLayer.layers.Add(blurXLayer);

            var blurYLayer = new RenderLayer {
                rtID        = Shader.PropertyToID("_rtID_" + this._layers.Count + "_" + parentLayer.layers.Count),
                width       = textureWidth,
                height      = textureHeight,
                layerBounds = maskLayer.layerBounds,
                filterMode  = FilterMode.Bilinear,
            };

            parentLayer.layers.Add(blurYLayer);

            var blurMesh = ImageMeshGenerator.imageMesh(null, Rect.one, maskLayer.layerBounds);

            var kernel = BlurUtils.get1DGaussianKernel(sigma, radius);

            blurXLayer.draws.Add(CanvasShader.maskFilter(
                                     blurXLayer, blurMesh, maskLayer,
                                     radius, new Vector2(1f / textureWidth, 0), kernel));

            blurYLayer.draws.Add(CanvasShader.maskFilter(
                                     blurYLayer, blurMesh, blurXLayer,
                                     radius, new Vector2(0, -1f / textureHeight), kernel));

            return(blurYLayer);
        }
Exemple #8
0
        void _drawWithMaskFilter(Rect meshBounds, Action <Paint> drawAction, Paint paint, MaskFilter maskFilter)
        {
            var layer      = this._currentLayer;
            var clipBounds = layer.layerBounds;

            Rect stackBounds;
            bool iior;

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

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

            if (clipBounds.isEmpty)
            {
                return;
            }

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

            if (sigma <= 0)
            {
                return;
            }

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

            maskBounds = maskBounds.intersect(clipBounds.inflate(sigma3));
            if (maskBounds.isEmpty)
            {
                return;
            }

            var maskLayer = this._createMaskLayer(layer, maskBounds, drawAction, paint);

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

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

            if (!this._applyClip(blurMesh.bounds))
            {
                return;
            }

            layer.draws.Add(CanvasShader.texRT(layer, paint, blurMesh, blurLayer));
        }
Exemple #9
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);
                    }
                }
            }
        }
        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));
        }