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); }
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)); }