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); }
bool _applyClip(uiRect?queryBounds) { if (queryBounds == null || queryBounds.Value.isEmpty) { return(false); } var layer = this._currentLayer; var layerBounds = layer.layerBounds; ReducedClip reducedClip = ReducedClip.create(layer.clipStack, layerBounds, queryBounds.Value); if (reducedClip.isEmpty()) { ObjectPool <ReducedClip> .release(reducedClip); return(false); } var scissor = reducedClip.scissor; var physicalRect = uiRectHelper.fromLTRB(0, 0, layer.width, layer.height); if (uiRectHelper.equals(scissor, layerBounds)) { this._tryAddScissor(layer, null); } else { var deviceScissor = uiRectHelper.fromLTRB( scissor.Value.left - layerBounds.left, layerBounds.bottom - scissor.Value.bottom, scissor.Value.right - layerBounds.left, layerBounds.bottom - scissor.Value.top ); deviceScissor = uiRectHelper.scale(deviceScissor, layer.width / layerBounds.width, layer.height / layerBounds.height); deviceScissor = uiRectHelper.roundOut(deviceScissor); deviceScissor = uiRectHelper.intersect(deviceScissor, physicalRect); if (deviceScissor.isEmpty) { ObjectPool <ReducedClip> .release(reducedClip); return(false); } this._tryAddScissor(layer, deviceScissor); } var maskGenID = reducedClip.maskGenID(); if (this._mustRenderClip(maskGenID, reducedClip.scissor.Value)) { if (maskGenID == ClipStack.wideOpenGenID) { layer.ignoreClip = true; } else { layer.ignoreClip = false; // need to inflate a bit to make sure all area is cleared. var inflatedScissor = uiRectHelper.inflate(reducedClip.scissor.Value, this._fringeWidth); var boundsMesh = uiMeshMesh.create(inflatedScissor); layer.draws.Add(CanvasShader.stencilClear(layer, boundsMesh)); foreach (var maskElement in reducedClip.maskElements) { layer.draws.Add(CanvasShader.stencil0(layer, maskElement.mesh.duplicate())); layer.draws.Add(CanvasShader.stencil1(layer, boundsMesh.duplicate())); } } this._setLastClipGenId(maskGenID, reducedClip.scissor.Value); } ObjectPool <ReducedClip> .release(reducedClip); return(true); }
bool _applyClip(Rect queryBounds) { var layer = this._currentLayer; var layerBounds = layer.layerBounds; ReducedClip reducedClip = new ReducedClip(layer.clipStack, layerBounds, queryBounds); if (reducedClip.isEmpty()) { return(false); } var scissor = reducedClip.scissor; var physicalRect = Rect.fromLTRB(0, 0, layer.width, layer.height); if (scissor == layerBounds) { this._tryAddScissor(layer, null); } else { var deviceScissor = Rect.fromLTRB( scissor.left - layerBounds.left, layerBounds.bottom - scissor.bottom, scissor.right - layerBounds.left, layerBounds.bottom - scissor.top ).scale(layer.width / layerBounds.width, layer.height / layerBounds.height); deviceScissor = deviceScissor.roundOut(); deviceScissor = deviceScissor.intersect(physicalRect); if (deviceScissor.isEmpty) { return(false); } this._tryAddScissor(layer, deviceScissor); } var maskGenID = reducedClip.maskGenID(); if (this._mustRenderClip(maskGenID, reducedClip.scissor)) { if (maskGenID == ClipStack.wideOpenGenID) { layer.ignoreClip = true; } else { layer.ignoreClip = false; var boundsMesh = new MeshMesh(reducedClip.scissor); layer.draws.Add(CanvasShader.stencilClear(layer, boundsMesh)); foreach (var maskElement in reducedClip.maskElements) { layer.draws.Add(CanvasShader.stencil0(layer, maskElement.mesh)); layer.draws.Add(CanvasShader.stencil1(layer, boundsMesh)); } } this._setLastClipGenId(maskGenID, reducedClip.scissor); } return(true); }