|
|
|
|
|
|
readonly List<DrawCmd> _drawCmds = new List<DrawCmd>(); |
|
|
|
|
|
|
|
readonly List<CanvasState> _states = new List<CanvasState>(); |
|
|
|
|
|
|
|
readonly BBoxHierarchy<IndexedRect> _bbh = new RTree<IndexedRect>(); |
|
|
|
|
|
|
|
readonly List<int> _stateUpdateIndices = new List<int>(); |
|
|
|
|
|
|
|
bool _isDynamic; |
|
|
|
|
|
|
|
|
|
|
layerOffset = null, |
|
|
|
paintBounds = Rect.zero, |
|
|
|
}); |
|
|
|
this._bbh.Clear(); |
|
|
|
this._stateUpdateIndices.Clear(); |
|
|
|
} |
|
|
|
|
|
|
|
public Picture endRecording() { |
|
|
|
|
|
|
|
|
|
|
int index = 0; |
|
|
|
RTree<IndexedRect> bbh = new RTree<IndexedRect>(); |
|
|
|
List<int> stateUpdateIndices = new List<int>(); |
|
|
|
foreach (var cmd in this._drawCmds) { |
|
|
|
if (cmd is StateUpdateDrawCmd) { |
|
|
|
stateUpdateIndices.Add(index); |
|
|
|
} |
|
|
|
else { |
|
|
|
bbh.Insert(new IndexedRect(cmd.bounds(5), index)); |
|
|
|
} |
|
|
|
index++; |
|
|
|
} |
|
|
|
|
|
|
|
bbh, |
|
|
|
stateUpdateIndices); |
|
|
|
this._bbh, |
|
|
|
this._stateUpdateIndices); |
|
|
|
} |
|
|
|
|
|
|
|
public void addDrawCmd(DrawCmd drawCmd) { |
|
|
|
|
|
|
case DrawSave _: |
|
|
|
this._states.Add(this._getState().copy()); |
|
|
|
this._stateUpdateIndices.Add(this._drawCmds.Count - 1); |
|
|
|
break; |
|
|
|
case DrawSaveLayer cmd: { |
|
|
|
this._states.Add(new CanvasState { |
|
|
|
|
|
|
layerOffset = cmd.rect.topLeft, |
|
|
|
paintBounds = Rect.zero, |
|
|
|
}); |
|
|
|
this._stateUpdateIndices.Add(this._drawCmds.Count - 1); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
paintBounds = state.xform.mapRect(paintBounds); |
|
|
|
this._addPaintBounds(paintBounds); |
|
|
|
} |
|
|
|
this._stateUpdateIndices.Add(this._drawCmds.Count - 1); |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
state.xform = new Matrix3(state.xform); |
|
|
|
state.xform.preTranslate(cmd.dx, cmd.dy); |
|
|
|
this._stateUpdateIndices.Add(this._drawCmds.Count - 1); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
state.xform.preScale(cmd.sx, (cmd.sy ?? cmd.sx)); |
|
|
|
this._stateUpdateIndices.Add(this._drawCmds.Count - 1); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
cmd.offset.dx, |
|
|
|
cmd.offset.dy); |
|
|
|
} |
|
|
|
this._stateUpdateIndices.Add(this._drawCmds.Count - 1); |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
state.xform = new Matrix3(state.xform); |
|
|
|
state.xform.preSkew(cmd.sx, cmd.sy); |
|
|
|
this._stateUpdateIndices.Add(this._drawCmds.Count - 1); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
state.xform.preConcat(cmd.matrix); |
|
|
|
this._stateUpdateIndices.Add(this._drawCmds.Count - 1); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
this._stateUpdateIndices.Add(this._drawCmds.Count - 1); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
this._stateUpdateIndices.Add(this._drawCmds.Count - 1); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
var rect = state.xform.mapRect(cmd.rect); |
|
|
|
state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect); |
|
|
|
this._stateUpdateIndices.Add(this._drawCmds.Count - 1); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
var rect = state.xform.mapRect(cmd.rrect.outerRect); |
|
|
|
state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect); |
|
|
|
this._stateUpdateIndices.Add(this._drawCmds.Count - 1); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
cache.computeFillMesh(0.0f, out _); |
|
|
|
var rect = cache.fillMesh.transform(state.xform).bounds; |
|
|
|
state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect); |
|
|
|
this._stateUpdateIndices.Add(this._drawCmds.Count - 1); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
float sigma = scale * paint.maskFilter.sigma; |
|
|
|
float sigma3 = 3 * sigma; |
|
|
|
this._addPaintBounds(mesh.bounds.inflate(sigma3)); |
|
|
|
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(mesh.bounds.inflate(sigma3 + 5)).Value, |
|
|
|
this._drawCmds.Count - 1)); |
|
|
|
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(mesh.bounds.inflate(5)).Value, |
|
|
|
this._drawCmds.Count - 1)); |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
cmd.image.width, cmd.image.height); |
|
|
|
rect = state.xform.mapRect(rect); |
|
|
|
this._addPaintBounds(rect); |
|
|
|
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value, |
|
|
|
this._drawCmds.Count - 1)); |
|
|
|
if (cmd.image.isDynamic) { |
|
|
|
this._isDynamic = true; |
|
|
|
} |
|
|
|
|
|
|
var state = this._getState(); |
|
|
|
var rect = state.xform.mapRect(cmd.dst); |
|
|
|
this._addPaintBounds(rect); |
|
|
|
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value, |
|
|
|
this._drawCmds.Count - 1)); |
|
|
|
if (cmd.image.isDynamic) { |
|
|
|
this._isDynamic = true; |
|
|
|
} |
|
|
|
|
|
|
var state = this._getState(); |
|
|
|
var rect = state.xform.mapRect(cmd.dst); |
|
|
|
this._addPaintBounds(rect); |
|
|
|
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value, |
|
|
|
this._drawCmds.Count - 1)); |
|
|
|
if (cmd.image.isDynamic) { |
|
|
|
this._isDynamic = true; |
|
|
|
} |
|
|
|
|
|
|
var state = this._getState(); |
|
|
|
var rect = state.xform.mapRect(cmd.picture.paintBounds); |
|
|
|
this._addPaintBounds(rect); |
|
|
|
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value, |
|
|
|
this._drawCmds.Count - 1)); |
|
|
|
if (cmd.picture.isDynamic) { |
|
|
|
this._isDynamic = true; |
|
|
|
} |
|
|
|
|
|
|
float sigma = scale * paint.maskFilter.sigma; |
|
|
|
float sigma3 = 3 * sigma; |
|
|
|
this._addPaintBounds(rect.inflate(sigma3)); |
|
|
|
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(sigma3 + 5)).Value, |
|
|
|
this._drawCmds.Count - 1)); |
|
|
|
this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value, |
|
|
|
this._drawCmds.Count - 1)); |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|