import { AbstractMaskSystem } from './AbstractMaskSystem';
/**
* System plugin to the renderer to manage scissor rects (used for masks).
*
* @class
* @extends PIXI.System
* @memberof PIXI.systems
*/
export class ScissorSystem extends AbstractMaskSystem {
/**
* @param {PIXI.Renderer} renderer - The renderer this System works for.
*/
constructor(renderer) {
super(renderer);
this.glConst = WebGLRenderingContext.SCISSOR_TEST;
}
getStackLength() {
const maskData = this.maskStack[this.maskStack.length - 1];
if (maskData) {
return maskData._scissorCounter;
}
return 0;
}
/**
* Applies the Mask and adds it to the current stencil stack. @alvin
*
* @param {PIXI.MaskData} maskData - The mask data
*/
push(maskData) {
const maskObject = maskData.maskObject;
maskObject.renderable = true;
const prevData = maskData._scissorRect;
const bounds = maskObject.getBounds(true);
const { gl } = this.renderer;
maskObject.renderable = false;
if (prevData) {
bounds.fit(prevData);
}
else {
gl.enable(gl.SCISSOR_TEST);
}
maskData._scissorCounter++;
maskData._scissorRect = bounds;
this._useCurrent();
}
/**
* Pops scissor mask. MaskData is already removed from stack
*/
pop() {
const { gl } = this.renderer;
if (this.getStackLength() > 0) {
this._useCurrent();
}
else {
gl.disable(gl.SCISSOR_TEST);
}
}
/**
* Setup renderer to use the current scissor data.
* @private
*/
_useCurrent() {
const rect = this.maskStack[this.maskStack.length - 1]._scissorRect;
const rt = this.renderer.renderTexture.current;
const { transform, sourceFrame, destinationFrame } = this.renderer.projection;
const resolution = rt ? rt.resolution : this.renderer.resolution;
let x = ((rect.x - sourceFrame.x) * resolution) + destinationFrame.x;
let y = ((rect.y - sourceFrame.y) * resolution) + destinationFrame.y;
const width = rect.width * resolution;
const height = rect.height * resolution;
if (transform) {
x += transform.tx * resolution;
y += transform.ty * resolution;
}
if (!rt) {
// flipY. In future we'll have it over renderTextures as an option
y = this.renderer.height - height - y;
}
this.renderer.gl.scissor(x, y, width, height);
}
}