const SkColor colors[], SkXfermode* xmode,
const uint16_t indices[], int indexCount,
const SkPaint& paint);
-
+
/**
Draw a cubic coons patch
-
+
@param cubic specifies the 4 bounding cubic bezier curves of a patch with clockwise order
starting at the top left corner.
@param colors specifies the colors for the corners which will be bilerp across the patch,
their order is clockwise starting at the top left corner.
- @param texCoords specifies the texture coordinates that will be bilerp across the patch,
+ @param texCoords specifies the texture coordinates that will be bilerp across the patch,
their order is the same as the colors.
- @param xmode specifies how are the colors and the textures combined if both of them are
+ @param xmode specifies how are the colors and the textures combined if both of them are
present.
@param paint Specifies the shader/texture if present.
*/
return kFullLayer_SaveLayerStrategy;
}
virtual void willRestore() {}
+ virtual void didRestore() {}
virtual void didConcat(const SkMatrix&) {}
virtual void didSetMatrix(const SkMatrix&) {}
virtual void onDrawTextOnPath(const void* text, size_t byteLength,
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint);
-
+
virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
if (fMCStack.count() > 1) {
this->willRestore();
this->internalRestore();
+ this->didRestore();
}
}
if (NULL == cubics) {
return;
}
-
+
// Since a patch is always within the convex hull of the control points, we discard it when its
// bounding rectangle is completely outside the current clip.
SkRect bounds;
if (this->quickReject(bounds)) {
return;
}
-
+
this->onDrawPatch(cubics, colors, texCoords, xmode, paint);
}
const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) {
LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL)
-
+
while (iter.next()) {
iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint);
}
-
+
LOOPER_END
}
} else if (NULL != matrix) {
canvas->save();
}
-
+
if (NULL != matrix) {
canvas->concat(*matrix);
}
FillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) : fBounds(record.count()) {
// Calculate bounds for all ops. This won't go quite in order, so we'll need
// to store the bounds separately then feed them in to the BBH later in order.
+ fCTM.setIdentity();
for (fCurrentOp = 0; fCurrentOp < record.count(); fCurrentOp++) {
record.visit<void>(fCurrentOp, *this);
}
}
template <typename T> void operator()(const T& r) {
+ this->updateCTM(r);
this->trackBounds(r);
}
SkIRect bounds; // Bounds of everything in the block.
};
+ template <typename T> void updateCTM(const T&) { /* most ops don't change the CTM */ }
+ void updateCTM(const Restore& r) { fCTM = r.matrix; }
+ void updateCTM(const SetMatrix& r) { fCTM = r.matrix; }
+ void updateCTM(const Concat& r) { fCTM.preConcat(r.matrix); }
+
// The bounds of these ops must be calculated when we hit the Restore
// from the bounds of the ops in the same Save block.
void trackBounds(const Save&) { this->pushSaveBlock(); }
SkIRect bounds(const NoOp&) { return SkIRect::MakeEmpty(); } // NoOps don't draw anywhere.
SkAutoTMalloc<SkIRect> fBounds; // One for each op in the record.
+ SkMatrix fCTM;
unsigned fCurrentOp;
SkTDArray<SaveBounds> fSaveStack;
SkTDArray<unsigned> fControlIndices;
return SkCanvas::kNoLayer_SaveLayerStrategy;
}
-void SkRecorder::willRestore() {
- APPEND(Restore);
- INHERITED(willRestore);
+void SkRecorder::didRestore() {
+ APPEND(Restore, this->getTotalMatrix());
+ INHERITED(didRestore);
}
void SkRecorder::onPushCull(const SkRect& rect) {
}
void SkRecorder::didSetMatrix(const SkMatrix& matrix) {
+ SkASSERT(matrix == this->getTotalMatrix());
APPEND(SetMatrix, matrix);
INHERITED(didSetMatrix, matrix);
}
void willSave() SK_OVERRIDE;
SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SkCanvas::SaveFlags) SK_OVERRIDE;
- void willRestore() SK_OVERRIDE;
+ void didRestore() SK_OVERRIDE;
void didConcat(const SkMatrix&) SK_OVERRIDE;
void didSetMatrix(const SkMatrix&) SK_OVERRIDE;
void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkXfermode* xmode,
const SkPaint& paint) SK_OVERRIDE;
-
+
void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) SK_OVERRIDE;
void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) SK_OVERRIDE;
void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) SK_OVERRIDE;
RECORD0(NoOp);
-RECORD0(Restore);
+RECORD1(Restore, SkMatrix, matrix);
RECORD0(Save);
RECORD3(SaveLayer, Optional<SkRect>, bounds, Optional<SkPaint>, paint, SkCanvas::SaveFlags, flags);
PODArray<uint16_t> indices;
int indexCount;
};
-
+
struct DrawPatch {
static const Type kType = DrawPatch_Type;
-
+
DrawPatch(const SkPaint& paint, SkPoint cubics[12], SkColor colors[4],
SkPoint texCoords[4], SkXfermode* xmode)
: paint(paint)
, colors(colors)
, texCoords(texCoords)
, xmode(SkSafeRef(xmode)) { }
-
+
SkPaint paint;
PODArray<SkPoint> cubics;
PODArray<SkColor> colors;