|
|
|
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
var matrix = Matrix3.makeTrans(-bounds.left, -bounds.top); |
|
|
|
matrix.postConcat(filter.transform); |
|
|
|
var matrix = uiMatrix3.makeTrans(-bounds.left, -bounds.top); |
|
|
|
matrix.postConcat(uiMatrix3.fromMatrix3(filter.transform)); |
|
|
|
matrix.postTranslate(bounds.left, bounds.top); |
|
|
|
|
|
|
|
var mesh = ImageMeshGenerator.imageMesh( |
|
|
|
|
|
|
|
|
|
|
void _translate(float dx, float dy) { |
|
|
|
var state = this._currentLayer.currentState; |
|
|
|
var matrix = Matrix3.makeTrans(dx, dy); |
|
|
|
var matrix = uiMatrix3.makeTrans(dx, dy); |
|
|
|
matrix.postConcat(state.matrix); |
|
|
|
state.matrix = matrix; |
|
|
|
} |
|
|
|
|
|
|
var matrix = Matrix3.makeScale(sx, (sy ?? sx)); |
|
|
|
var matrix = uiMatrix3.makeScale(sx, (sy ?? sx)); |
|
|
|
matrix.postConcat(state.matrix); |
|
|
|
state.matrix = matrix; |
|
|
|
} |
|
|
|
|
|
|
if (offset == null) { |
|
|
|
var matrix = Matrix3.makeRotate(radians); |
|
|
|
var matrix = uiMatrix3.makeRotate(radians); |
|
|
|
var matrix = Matrix3.makeRotate(radians, offset.dx, offset.dy); |
|
|
|
var matrix = uiMatrix3.makeRotate(radians, offset.dx, offset.dy); |
|
|
|
matrix.postConcat(state.matrix); |
|
|
|
state.matrix = matrix; |
|
|
|
} |
|
|
|
|
|
|
var state = this._currentLayer.currentState; |
|
|
|
var matrix = Matrix3.makeSkew( sx, sy); |
|
|
|
var matrix = uiMatrix3.makeSkew( sx, sy); |
|
|
|
void _concat(Matrix3 matrix) { |
|
|
|
void _concat(uiMatrix3 matrix) { |
|
|
|
matrix = new Matrix3(matrix); |
|
|
|
matrix = new uiMatrix3(matrix); |
|
|
|
matrix.postConcat(state.matrix); |
|
|
|
state.matrix = matrix; |
|
|
|
} |
|
|
|
|
|
|
state.matrix = Matrix3.I(); |
|
|
|
state.matrix = uiMatrix3.I(); |
|
|
|
void _setMatrix(Matrix3 matrix) { |
|
|
|
void _setMatrix(uiMatrix3 matrix) { |
|
|
|
state.matrix = new Matrix3(matrix); |
|
|
|
state.matrix = new uiMatrix3(matrix); |
|
|
|
var path = new Path(); |
|
|
|
var path = new uiPath(); |
|
|
|
var path = new Path(); |
|
|
|
var path = new uiPath(); |
|
|
|
void _clipPath(Path path) { |
|
|
|
void _clipPath(uiPath path) { |
|
|
|
var layer = this._currentLayer; |
|
|
|
var state = layer.currentState; |
|
|
|
layer.clipStack.clipPath(path, state.matrix, state.scale * this._devicePixelRatio); |
|
|
|
|
|
|
|
|
|
|
// need to inflate a bit to make sure all area is cleared.
|
|
|
|
var inflatedScissor = reducedClip.scissor.inflate(this._fringeWidth); |
|
|
|
var boundsMesh = new MeshMesh(inflatedScissor); |
|
|
|
var boundsMesh = new uiMeshMesh(inflatedScissor); |
|
|
|
layer.draws.Add(CanvasShader.stencilClear(layer, boundsMesh)); |
|
|
|
|
|
|
|
foreach (var maskElement in reducedClip.maskElements) { |
|
|
|
|
|
|
layer.draws.Add(CanvasShader.texRT(layer, paint, blurMesh, blurLayer)); |
|
|
|
} |
|
|
|
|
|
|
|
void _drawPath(Path path, Paint paint) { |
|
|
|
void _drawPath(uiPath path, Paint paint) { |
|
|
|
D.assert(path != null); |
|
|
|
D.assert(paint != null); |
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
case DrawConcat cmd: { |
|
|
|
this._concat(cmd.matrix); |
|
|
|
this._concat(uiMatrix3.fromMatrix3(cmd.matrix)); |
|
|
|
break; |
|
|
|
} |
|
|
|
case DrawResetMatrix _: |
|
|
|
|
|
|
this._setMatrix(cmd.matrix); |
|
|
|
this._setMatrix(uiMatrix3.fromMatrix3(cmd.matrix)); |
|
|
|
break; |
|
|
|
} |
|
|
|
case DrawClipRect cmd: { |
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
case DrawClipPath cmd: { |
|
|
|
this._clipPath(cmd.path); |
|
|
|
this._clipPath(uiPath.fromPath(cmd.path)); |
|
|
|
this._drawPath(cmd.path, cmd.paint); |
|
|
|
this._drawPath(uiPath.fromPath(cmd.path), cmd.paint); |
|
|
|
break; |
|
|
|
} |
|
|
|
case DrawImage cmd: { |
|
|
|
|
|
|
var state = this._currentLayer.currentState; |
|
|
|
var scale = state.scale * this._devicePixelRatio; |
|
|
|
|
|
|
|
var matrix = new Matrix3(state.matrix); |
|
|
|
var matrix = new uiMatrix3(state.matrix); |
|
|
|
matrix.preTranslate(offset.dx, offset.dy); |
|
|
|
|
|
|
|
var mesh = new TextBlobMesh(textBlob, scale, matrix); |
|
|
|
|
|
|
// clear triangles first in order to bypass validation in SetVertices.
|
|
|
|
cmd.meshObj.SetTriangles((int[]) null, 0, false); |
|
|
|
|
|
|
|
MeshMesh mesh = cmd.mesh; |
|
|
|
uiMeshMesh mesh = cmd.mesh; |
|
|
|
if (cmd.textMesh != null) { |
|
|
|
mesh = cmd.textMesh.resovleMesh(); |
|
|
|
} |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
internal class State { |
|
|
|
static readonly Matrix3 _id = Matrix3.I(); |
|
|
|
static readonly uiMatrix3 _id = uiMatrix3.I(); |
|
|
|
Matrix3 _matrix; |
|
|
|
uiMatrix3 _matrix; |
|
|
|
Matrix3 _invMatrix; |
|
|
|
uiMatrix3 _invMatrix; |
|
|
|
public State(Matrix3 matrix = null, float? scale = null, Matrix3 invMatrix = null) { |
|
|
|
public State(uiMatrix3 matrix = null, float? scale = null, uiMatrix3 invMatrix = null) { |
|
|
|
public Matrix3 matrix { |
|
|
|
public uiMatrix3 matrix { |
|
|
|
get { return this._matrix; } |
|
|
|
set { |
|
|
|
this._matrix = value ?? _id; |
|
|
|
|
|
|
public float scale { |
|
|
|
get { |
|
|
|
if (this._scale == null) { |
|
|
|
this._scale = XformUtils.getScale(this._matrix); |
|
|
|
this._scale = uiXformUtils.getScale(this._matrix); |
|
|
|
public Matrix3 invMatrix { |
|
|
|
public uiMatrix3 invMatrix { |
|
|
|
this._invMatrix = Matrix3.I(); |
|
|
|
this._invMatrix = uiMatrix3.I(); |
|
|
|
this._matrix.invert(this._invMatrix); |
|
|
|
} |
|
|
|
return this._invMatrix; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
internal class CmdDraw { |
|
|
|
public MeshMesh mesh; |
|
|
|
public uiMeshMesh mesh; |
|
|
|
public TextBlobMesh textMesh; |
|
|
|
public int pass; |
|
|
|
public MaterialPropertyBlock properties; |
|
|
|
|
|
|
this._recorder.reset(); |
|
|
|
this._flusher.flush(picture); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static class uiXformUtils { |
|
|
|
public static float getAverageScale(uiMatrix3 matrix) { |
|
|
|
return (getScaleX(matrix) + getScaleY(matrix)) * 0.5f; |
|
|
|
} |
|
|
|
|
|
|
|
public static float getMaxScale(uiMatrix3 matrix) { |
|
|
|
return Mathf.Max(getScaleX(matrix), getScaleY(matrix)); |
|
|
|
} |
|
|
|
|
|
|
|
public static float getScaleX(uiMatrix3 matrix) { |
|
|
|
// ignore perspective parameters for now.
|
|
|
|
if (matrix.isIdentity()) { |
|
|
|
return 1.0f; |
|
|
|
} |
|
|
|
|
|
|
|
if (matrix.getSkewY() == 0) { |
|
|
|
return matrix.getScaleX(); |
|
|
|
} |
|
|
|
|
|
|
|
var x = matrix.getScaleX(); |
|
|
|
var y = matrix.getSkewY(); |
|
|
|
|
|
|
|
return Mathf.Sqrt(x * x + y * y); |
|
|
|
} |
|
|
|
|
|
|
|
public static float getScaleY(uiMatrix3 matrix) { |
|
|
|
// ignore perspective parameters for now.
|
|
|
|
if (matrix.isIdentity()) { |
|
|
|
return 1.0f; |
|
|
|
} |
|
|
|
|
|
|
|
if (matrix.getSkewX() == 0) { |
|
|
|
return matrix.getScaleY(); |
|
|
|
} |
|
|
|
|
|
|
|
var x = matrix.getSkewX(); |
|
|
|
var y = matrix.getScaleY(); |
|
|
|
|
|
|
|
return Mathf.Sqrt(x * x + y * y); |
|
|
|
} |
|
|
|
|
|
|
|
public static float getScale(uiMatrix3 matrix) { |
|
|
|
var scaleX = getScaleX(matrix); |
|
|
|
var scaleY = getScaleY(matrix); |
|
|
|
|
|
|
|
if (scaleX == 1.0) { |
|
|
|
return scaleY; |
|
|
|
} |
|
|
|
|
|
|
|
if (scaleY == 1.0) { |
|
|
|
return scaleX; |
|
|
|
} |
|
|
|
|
|
|
|
// geometric mean of len0 and len1.
|
|
|
|
return Mathf.Sqrt(scaleX * scaleY); |
|
|
|
} |
|
|
|
|
|
|
|
public static float mapRadius(uiMatrix3 matrix, float radius) { |
|
|
|
return getScale(matrix) * radius; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static class XformUtils { |
|
|
|
public static float getAverageScale(Matrix3 matrix) { |
|
|
|
|
|
|
10, 11, 14, 11, 15, 14, |
|
|
|
}; |
|
|
|
|
|
|
|
public static MeshMesh imageMesh(Matrix3 matrix, |
|
|
|
public static uiMeshMesh imageMesh(uiMatrix3 matrix, |
|
|
|
Offset srcTL, Offset srcBL, Offset srcBR, Offset srcTR, |
|
|
|
Rect dst) { |
|
|
|
var vertices = new List<Vector3>(4); |
|
|
|
|
|
|
vertices.Add(new Vector2(dst.right, dst.top)); |
|
|
|
uv.Add(new Vector2(srcTR.dx, 1.0f - srcTR.dy)); |
|
|
|
|
|
|
|
return new MeshMesh(matrix, vertices, _imageTriangles, uv); |
|
|
|
return new uiMeshMesh(matrix, vertices, _imageTriangles, uv); |
|
|
|
public static MeshMesh imageMesh(Matrix3 matrix, Rect src, Rect dst) { |
|
|
|
public static uiMeshMesh imageMesh(uiMatrix3 matrix, Rect src, Rect dst) { |
|
|
|
var vertices = new List<Vector3>(4); |
|
|
|
var uv = new List<Vector2>(4); |
|
|
|
|
|
|
|
|
|
|
vertices.Add(new Vector2(dst.right, dst.top)); |
|
|
|
uv.Add(new Vector2(uvx1, uvy0)); |
|
|
|
|
|
|
|
return new MeshMesh(matrix, vertices, _imageTriangles, uv); |
|
|
|
return new uiMeshMesh(matrix, vertices, _imageTriangles, uv); |
|
|
|
public static MeshMesh imageNineMesh(Matrix3 matrix, Rect src, Rect center, int srcWidth, int srcHeight, Rect dst) { |
|
|
|
public static uiMeshMesh imageNineMesh(uiMatrix3 matrix, Rect src, Rect center, int srcWidth, int srcHeight, Rect dst) { |
|
|
|
float x0 = dst.left; |
|
|
|
float x3 = dst.right; |
|
|
|
float x1 = x0 + ((center.left - src.left) * srcWidth); |
|
|
|
|
|
|
vertices.Add(new Vector2(x3, y3)); |
|
|
|
uv.Add(new Vector2(tx3, ty3)); |
|
|
|
|
|
|
|
return new MeshMesh(matrix, vertices, _imageNineTriangles, uv); |
|
|
|
return new uiMeshMesh(matrix, vertices, _imageNineTriangles, uv); |
|
|
|
} |
|
|
|
} |
|
|
|
} |