michael@0: michael@0: /* michael@0: * Copyright 2012 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #include "SkColorPriv.h" michael@0: #include "SkDebugCanvas.h" michael@0: #include "SkDrawCommand.h" michael@0: #include "SkDrawFilter.h" michael@0: #include "SkDevice.h" michael@0: #include "SkXfermode.h" michael@0: michael@0: SkDebugCanvas::SkDebugCanvas(int width, int height) michael@0: : INHERITED(width, height) michael@0: , fWidth(width) michael@0: , fHeight(height) michael@0: , fFilter(false) michael@0: , fMegaVizMode(false) michael@0: , fIndex(0) michael@0: , fOverdrawViz(false) michael@0: , fOverdrawFilter(NULL) michael@0: , fOverrideTexFiltering(false) michael@0: , fTexOverrideFilter(NULL) michael@0: , fOutstandingSaveCount(0) { michael@0: fUserMatrix.reset(); michael@0: michael@0: // SkPicturePlayback uses the base-class' quickReject calls to cull clipped michael@0: // operations. This can lead to problems in the debugger which expects all michael@0: // the operations in the captured skp to appear in the debug canvas. To michael@0: // circumvent this we create a wide open clip here (an empty clip rect michael@0: // is not sufficient). michael@0: // Internally, the SkRect passed to clipRect is converted to an SkIRect and michael@0: // rounded out. The following code creates a nearly maximal rect that will michael@0: // not get collapsed by the coming conversions (Due to precision loss the michael@0: // inset has to be surprisingly large). michael@0: SkIRect largeIRect = SkIRect::MakeLargest(); michael@0: largeIRect.inset(1024, 1024); michael@0: SkRect large = SkRect::Make(largeIRect); michael@0: #ifdef SK_DEBUG michael@0: large.roundOut(&largeIRect); michael@0: SkASSERT(!largeIRect.isEmpty()); michael@0: #endif michael@0: // call the base class' version to avoid adding a draw command michael@0: this->INHERITED::onClipRect(large, SkRegion::kReplace_Op, kHard_ClipEdgeStyle); michael@0: } michael@0: michael@0: SkDebugCanvas::~SkDebugCanvas() { michael@0: fCommandVector.deleteAll(); michael@0: SkSafeUnref(fOverdrawFilter); michael@0: SkSafeUnref(fTexOverrideFilter); michael@0: } michael@0: michael@0: void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) { michael@0: fCommandVector.push(command); michael@0: } michael@0: michael@0: void SkDebugCanvas::draw(SkCanvas* canvas) { michael@0: if (!fCommandVector.isEmpty()) { michael@0: drawTo(canvas, fCommandVector.count() - 1); michael@0: } michael@0: } michael@0: michael@0: void SkDebugCanvas::applyUserTransform(SkCanvas* canvas) { michael@0: canvas->concat(fUserMatrix); michael@0: } michael@0: michael@0: int SkDebugCanvas::getCommandAtPoint(int x, int y, int index) { michael@0: SkBitmap bitmap; michael@0: bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1)); michael@0: michael@0: SkCanvas canvas(bitmap); michael@0: canvas.translate(SkIntToScalar(-x), SkIntToScalar(-y)); michael@0: applyUserTransform(&canvas); michael@0: michael@0: int layer = 0; michael@0: SkColor prev = bitmap.getColor(0,0); michael@0: for (int i = 0; i < index; i++) { michael@0: if (fCommandVector[i]->isVisible()) { michael@0: fCommandVector[i]->execute(&canvas); michael@0: } michael@0: if (prev != bitmap.getColor(0,0)) { michael@0: layer = i; michael@0: } michael@0: prev = bitmap.getColor(0,0); michael@0: } michael@0: return layer; michael@0: } michael@0: michael@0: static SkPMColor OverdrawXferModeProc(SkPMColor src, SkPMColor dst) { michael@0: // This table encodes the color progression of the overdraw visualization michael@0: static const SkPMColor gTable[] = { michael@0: SkPackARGB32(0x00, 0x00, 0x00, 0x00), michael@0: SkPackARGB32(0xFF, 128, 158, 255), michael@0: SkPackARGB32(0xFF, 170, 185, 212), michael@0: SkPackARGB32(0xFF, 213, 195, 170), michael@0: SkPackARGB32(0xFF, 255, 192, 127), michael@0: SkPackARGB32(0xFF, 255, 185, 85), michael@0: SkPackARGB32(0xFF, 255, 165, 42), michael@0: SkPackARGB32(0xFF, 255, 135, 0), michael@0: SkPackARGB32(0xFF, 255, 95, 0), michael@0: SkPackARGB32(0xFF, 255, 50, 0), michael@0: SkPackARGB32(0xFF, 255, 0, 0) michael@0: }; michael@0: michael@0: for (size_t i = 0; i < SK_ARRAY_COUNT(gTable)-1; ++i) { michael@0: if (gTable[i] == dst) { michael@0: return gTable[i+1]; michael@0: } michael@0: } michael@0: michael@0: return gTable[SK_ARRAY_COUNT(gTable)-1]; michael@0: } michael@0: michael@0: // The OverdrawFilter modifies every paint to use an SkProcXfermode which michael@0: // in turn invokes OverdrawXferModeProc michael@0: class SkOverdrawFilter : public SkDrawFilter { michael@0: public: michael@0: SkOverdrawFilter() { michael@0: fXferMode = SkProcXfermode::Create(OverdrawXferModeProc); michael@0: } michael@0: michael@0: virtual ~SkOverdrawFilter() { michael@0: delete fXferMode; michael@0: } michael@0: michael@0: virtual bool filter(SkPaint* p, Type) SK_OVERRIDE { michael@0: p->setXfermode(fXferMode); michael@0: return true; michael@0: } michael@0: michael@0: protected: michael@0: SkXfermode* fXferMode; michael@0: michael@0: private: michael@0: typedef SkDrawFilter INHERITED; michael@0: }; michael@0: michael@0: // SkTexOverrideFilter modifies every paint to use the specified michael@0: // texture filtering mode michael@0: class SkTexOverrideFilter : public SkDrawFilter { michael@0: public: michael@0: SkTexOverrideFilter() : fFilterLevel(SkPaint::kNone_FilterLevel) { michael@0: } michael@0: michael@0: void setFilterLevel(SkPaint::FilterLevel filterLevel) { michael@0: fFilterLevel = filterLevel; michael@0: } michael@0: michael@0: virtual bool filter(SkPaint* p, Type) SK_OVERRIDE { michael@0: p->setFilterLevel(fFilterLevel); michael@0: return true; michael@0: } michael@0: michael@0: protected: michael@0: SkPaint::FilterLevel fFilterLevel; michael@0: michael@0: private: michael@0: typedef SkDrawFilter INHERITED; michael@0: }; michael@0: michael@0: class SkDebugClipVisitor : public SkCanvas::ClipVisitor { michael@0: public: michael@0: SkDebugClipVisitor(SkCanvas* canvas) : fCanvas(canvas) {} michael@0: michael@0: virtual void clipRect(const SkRect& r, SkRegion::Op, bool doAA) SK_OVERRIDE { michael@0: SkPaint p; michael@0: p.setColor(SK_ColorRED); michael@0: p.setStyle(SkPaint::kStroke_Style); michael@0: p.setAntiAlias(doAA); michael@0: fCanvas->drawRect(r, p); michael@0: } michael@0: virtual void clipRRect(const SkRRect& rr, SkRegion::Op, bool doAA) SK_OVERRIDE { michael@0: SkPaint p; michael@0: p.setColor(SK_ColorGREEN); michael@0: p.setStyle(SkPaint::kStroke_Style); michael@0: p.setAntiAlias(doAA); michael@0: fCanvas->drawRRect(rr, p); michael@0: } michael@0: virtual void clipPath(const SkPath& path, SkRegion::Op, bool doAA) SK_OVERRIDE { michael@0: SkPaint p; michael@0: p.setColor(SK_ColorBLUE); michael@0: p.setStyle(SkPaint::kStroke_Style); michael@0: p.setAntiAlias(doAA); michael@0: fCanvas->drawPath(path, p); michael@0: } michael@0: michael@0: protected: michael@0: SkCanvas* fCanvas; michael@0: michael@0: private: michael@0: typedef SkCanvas::ClipVisitor INHERITED; michael@0: }; michael@0: michael@0: // set up the saveLayer commands so that the active ones michael@0: // return true in their 'active' method michael@0: void SkDebugCanvas::markActiveCommands(int index) { michael@0: fActiveLayers.rewind(); michael@0: fActiveCulls.rewind(); michael@0: michael@0: for (int i = 0; i < fCommandVector.count(); ++i) { michael@0: fCommandVector[i]->setActive(false); michael@0: } michael@0: michael@0: for (int i = 0; i < index; ++i) { michael@0: SkDrawCommand::Action result = fCommandVector[i]->action(); michael@0: if (SkDrawCommand::kPushLayer_Action == result) { michael@0: fActiveLayers.push(fCommandVector[i]); michael@0: } else if (SkDrawCommand::kPopLayer_Action == result) { michael@0: fActiveLayers.pop(); michael@0: } else if (SkDrawCommand::kPushCull_Action == result) { michael@0: fActiveCulls.push(fCommandVector[i]); michael@0: } else if (SkDrawCommand::kPopCull_Action == result) { michael@0: fActiveCulls.pop(); michael@0: } michael@0: } michael@0: michael@0: for (int i = 0; i < fActiveLayers.count(); ++i) { michael@0: fActiveLayers[i]->setActive(true); michael@0: } michael@0: michael@0: for (int i = 0; i < fActiveCulls.count(); ++i) { michael@0: fActiveCulls[i]->setActive(true); michael@0: } michael@0: } michael@0: michael@0: void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) { michael@0: SkASSERT(!fCommandVector.isEmpty()); michael@0: SkASSERT(index < fCommandVector.count()); michael@0: int i = 0; michael@0: michael@0: // This only works assuming the canvas and device are the same ones that michael@0: // were previously drawn into because they need to preserve all saves michael@0: // and restores. michael@0: // The visibility filter also requires a full re-draw - otherwise we can michael@0: // end up drawing the filter repeatedly. michael@0: if (fIndex < index && !fFilter && !fMegaVizMode) { michael@0: i = fIndex + 1; michael@0: } else { michael@0: for (int j = 0; j < fOutstandingSaveCount; j++) { michael@0: canvas->restore(); michael@0: } michael@0: canvas->clear(SK_ColorTRANSPARENT); michael@0: canvas->resetMatrix(); michael@0: SkRect rect = SkRect::MakeWH(SkIntToScalar(fWidth), michael@0: SkIntToScalar(fHeight)); michael@0: canvas->clipRect(rect, SkRegion::kReplace_Op ); michael@0: applyUserTransform(canvas); michael@0: fOutstandingSaveCount = 0; michael@0: } michael@0: michael@0: // The setting of the draw filter has to go here (rather than in michael@0: // SkRasterWidget) due to the canvas restores this class performs. michael@0: // Since the draw filter is stored in the layer stack if we michael@0: // call setDrawFilter on anything but the root layer odd things happen. michael@0: if (fOverdrawViz) { michael@0: if (NULL == fOverdrawFilter) { michael@0: fOverdrawFilter = new SkOverdrawFilter; michael@0: } michael@0: michael@0: if (fOverdrawFilter != canvas->getDrawFilter()) { michael@0: canvas->setDrawFilter(fOverdrawFilter); michael@0: } michael@0: } else if (fOverrideTexFiltering) { michael@0: if (NULL == fTexOverrideFilter) { michael@0: fTexOverrideFilter = new SkTexOverrideFilter; michael@0: } michael@0: michael@0: if (fTexOverrideFilter != canvas->getDrawFilter()) { michael@0: canvas->setDrawFilter(fTexOverrideFilter); michael@0: } michael@0: } else { michael@0: canvas->setDrawFilter(NULL); michael@0: } michael@0: michael@0: if (fMegaVizMode) { michael@0: this->markActiveCommands(index); michael@0: } michael@0: michael@0: for (; i <= index; i++) { michael@0: if (i == index && fFilter) { michael@0: SkPaint p; michael@0: p.setColor(0xAAFFFFFF); michael@0: canvas->save(); michael@0: canvas->resetMatrix(); michael@0: SkRect mask; michael@0: mask.set(SkIntToScalar(0), SkIntToScalar(0), michael@0: SkIntToScalar(fWidth), SkIntToScalar(fHeight)); michael@0: canvas->clipRect(mask, SkRegion::kReplace_Op, false); michael@0: canvas->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0), michael@0: SkIntToScalar(fWidth), SkIntToScalar(fHeight), p); michael@0: canvas->restore(); michael@0: } michael@0: michael@0: if (fCommandVector[i]->isVisible()) { michael@0: if (fMegaVizMode && fCommandVector[i]->active()) { michael@0: // "active" commands execute their visualization behaviors: michael@0: // All active saveLayers get replaced with saves so all draws go to the michael@0: // visible canvas. michael@0: // All active culls draw their cull box michael@0: fCommandVector[i]->vizExecute(canvas); michael@0: } else { michael@0: fCommandVector[i]->execute(canvas); michael@0: } michael@0: michael@0: fCommandVector[i]->trackSaveState(&fOutstandingSaveCount); michael@0: } michael@0: } michael@0: michael@0: if (fMegaVizMode) { michael@0: SkRect r = SkRect::MakeWH(SkIntToScalar(fWidth), SkIntToScalar(fHeight)); michael@0: r.outset(SK_Scalar1, SK_Scalar1); michael@0: michael@0: canvas->save(); michael@0: // nuke the CTM michael@0: canvas->setMatrix(SkMatrix::I()); michael@0: // turn off clipping michael@0: canvas->clipRect(r, SkRegion::kReplace_Op); michael@0: michael@0: // visualize existing clips michael@0: SkDebugClipVisitor visitor(canvas); michael@0: michael@0: canvas->replayClips(&visitor); michael@0: michael@0: canvas->restore(); michael@0: } michael@0: fMatrix = canvas->getTotalMatrix(); michael@0: if (!canvas->getClipDeviceBounds(&fClip)) { michael@0: fClip.setEmpty(); michael@0: } michael@0: fIndex = index; michael@0: } michael@0: michael@0: void SkDebugCanvas::deleteDrawCommandAt(int index) { michael@0: SkASSERT(index < fCommandVector.count()); michael@0: delete fCommandVector[index]; michael@0: fCommandVector.remove(index); michael@0: } michael@0: michael@0: SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) { michael@0: SkASSERT(index < fCommandVector.count()); michael@0: return fCommandVector[index]; michael@0: } michael@0: michael@0: void SkDebugCanvas::setDrawCommandAt(int index, SkDrawCommand* command) { michael@0: SkASSERT(index < fCommandVector.count()); michael@0: delete fCommandVector[index]; michael@0: fCommandVector[index] = command; michael@0: } michael@0: michael@0: SkTDArray* SkDebugCanvas::getCommandInfo(int index) { michael@0: SkASSERT(index < fCommandVector.count()); michael@0: return fCommandVector[index]->Info(); michael@0: } michael@0: michael@0: bool SkDebugCanvas::getDrawCommandVisibilityAt(int index) { michael@0: SkASSERT(index < fCommandVector.count()); michael@0: return fCommandVector[index]->isVisible(); michael@0: } michael@0: michael@0: const SkTDArray & SkDebugCanvas::getDrawCommands() const { michael@0: return fCommandVector; michael@0: } michael@0: michael@0: SkTDArray & SkDebugCanvas::getDrawCommands() { michael@0: return fCommandVector; michael@0: } michael@0: michael@0: // TODO(chudy): Free command string memory. michael@0: SkTArray* SkDebugCanvas::getDrawCommandsAsStrings() const { michael@0: SkTArray* commandString = new SkTArray(fCommandVector.count()); michael@0: if (!fCommandVector.isEmpty()) { michael@0: for (int i = 0; i < fCommandVector.count(); i ++) { michael@0: commandString->push_back() = fCommandVector[i]->toString(); michael@0: } michael@0: } michael@0: return commandString; michael@0: } michael@0: michael@0: void SkDebugCanvas::overrideTexFiltering(bool overrideTexFiltering, SkPaint::FilterLevel level) { michael@0: if (NULL == fTexOverrideFilter) { michael@0: fTexOverrideFilter = new SkTexOverrideFilter; michael@0: } michael@0: michael@0: fOverrideTexFiltering = overrideTexFiltering; michael@0: fTexOverrideFilter->setFilterLevel(level); michael@0: } michael@0: michael@0: void SkDebugCanvas::clear(SkColor color) { michael@0: addDrawCommand(new SkClearCommand(color)); michael@0: } michael@0: michael@0: void SkDebugCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { michael@0: this->addDrawCommand(new SkClipPathCommand(path, op, kSoft_ClipEdgeStyle == edgeStyle)); michael@0: } michael@0: michael@0: void SkDebugCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { michael@0: this->addDrawCommand(new SkClipRectCommand(rect, op, kSoft_ClipEdgeStyle == edgeStyle)); michael@0: } michael@0: michael@0: void SkDebugCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { michael@0: this->addDrawCommand(new SkClipRRectCommand(rrect, op, kSoft_ClipEdgeStyle == edgeStyle)); michael@0: } michael@0: michael@0: void SkDebugCanvas::onClipRegion(const SkRegion& region, SkRegion::Op op) { michael@0: this->addDrawCommand(new SkClipRegionCommand(region, op)); michael@0: } michael@0: michael@0: void SkDebugCanvas::didConcat(const SkMatrix& matrix) { michael@0: addDrawCommand(new SkConcatCommand(matrix)); michael@0: this->INHERITED::didConcat(matrix); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left, michael@0: SkScalar top, const SkPaint* paint = NULL) { michael@0: addDrawCommand(new SkDrawBitmapCommand(bitmap, left, top, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawBitmapRectToRect(const SkBitmap& bitmap, michael@0: const SkRect* src, const SkRect& dst, michael@0: const SkPaint* paint, michael@0: SkCanvas::DrawBitmapRectFlags flags) { michael@0: addDrawCommand(new SkDrawBitmapRectCommand(bitmap, src, dst, paint, flags)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawBitmapMatrix(const SkBitmap& bitmap, michael@0: const SkMatrix& matrix, const SkPaint* paint) { michael@0: addDrawCommand(new SkDrawBitmapMatrixCommand(bitmap, matrix, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawBitmapNine(const SkBitmap& bitmap, michael@0: const SkIRect& center, const SkRect& dst, const SkPaint* paint) { michael@0: addDrawCommand(new SkDrawBitmapNineCommand(bitmap, center, dst, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawData(const void* data, size_t length) { michael@0: addDrawCommand(new SkDrawDataCommand(data, length)); michael@0: } michael@0: michael@0: void SkDebugCanvas::beginCommentGroup(const char* description) { michael@0: addDrawCommand(new SkBeginCommentGroupCommand(description)); michael@0: } michael@0: michael@0: void SkDebugCanvas::addComment(const char* kywd, const char* value) { michael@0: addDrawCommand(new SkCommentCommand(kywd, value)); michael@0: } michael@0: michael@0: void SkDebugCanvas::endCommentGroup() { michael@0: addDrawCommand(new SkEndCommentGroupCommand()); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawOval(const SkRect& oval, const SkPaint& paint) { michael@0: addDrawCommand(new SkDrawOvalCommand(oval, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawPaint(const SkPaint& paint) { michael@0: addDrawCommand(new SkDrawPaintCommand(paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawPath(const SkPath& path, const SkPaint& paint) { michael@0: addDrawCommand(new SkDrawPathCommand(path, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawPicture(SkPicture& picture) { michael@0: addDrawCommand(new SkDrawPictureCommand(picture)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawPoints(PointMode mode, size_t count, michael@0: const SkPoint pts[], const SkPaint& paint) { michael@0: addDrawCommand(new SkDrawPointsCommand(mode, count, pts, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawPosText(const void* text, size_t byteLength, michael@0: const SkPoint pos[], const SkPaint& paint) { michael@0: addDrawCommand(new SkDrawPosTextCommand(text, byteLength, pos, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawPosTextH(const void* text, size_t byteLength, michael@0: const SkScalar xpos[], SkScalar constY, const SkPaint& paint) { michael@0: addDrawCommand( michael@0: new SkDrawPosTextHCommand(text, byteLength, xpos, constY, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawRect(const SkRect& rect, const SkPaint& paint) { michael@0: // NOTE(chudy): Messing up when renamed to DrawRect... Why? michael@0: addDrawCommand(new SkDrawRectCommand(rect, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { michael@0: addDrawCommand(new SkDrawRRectCommand(rrect, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, michael@0: const SkPaint& paint) { michael@0: this->addDrawCommand(new SkDrawDRRectCommand(outer, inner, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawSprite(const SkBitmap& bitmap, int left, int top, michael@0: const SkPaint* paint = NULL) { michael@0: addDrawCommand(new SkDrawSpriteCommand(bitmap, left, top, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawText(const void* text, size_t byteLength, SkScalar x, michael@0: SkScalar y, const SkPaint& paint) { michael@0: addDrawCommand(new SkDrawTextCommand(text, byteLength, x, y, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawTextOnPath(const void* text, size_t byteLength, michael@0: const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) { michael@0: addDrawCommand( michael@0: new SkDrawTextOnPathCommand(text, byteLength, path, matrix, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::drawVertices(VertexMode vmode, int vertexCount, michael@0: const SkPoint vertices[], const SkPoint texs[], const SkColor colors[], michael@0: SkXfermode*, const uint16_t indices[], int indexCount, michael@0: const SkPaint& paint) { michael@0: addDrawCommand(new SkDrawVerticesCommand(vmode, vertexCount, vertices, michael@0: texs, colors, NULL, indices, indexCount, paint)); michael@0: } michael@0: michael@0: void SkDebugCanvas::onPushCull(const SkRect& cullRect) { michael@0: this->addDrawCommand(new SkPushCullCommand(cullRect)); michael@0: } michael@0: michael@0: void SkDebugCanvas::onPopCull() { michael@0: this->addDrawCommand(new SkPopCullCommand()); michael@0: } michael@0: michael@0: void SkDebugCanvas::willRestore() { michael@0: this->addDrawCommand(new SkRestoreCommand()); michael@0: this->INHERITED::willRestore(); michael@0: } michael@0: michael@0: void SkDebugCanvas::didRotate(SkScalar degrees) { michael@0: addDrawCommand(new SkRotateCommand(degrees)); michael@0: this->INHERITED::didRotate(degrees); michael@0: } michael@0: michael@0: void SkDebugCanvas::willSave(SaveFlags flags) { michael@0: this->addDrawCommand(new SkSaveCommand(flags)); michael@0: this->INHERITED::willSave(flags); michael@0: } michael@0: michael@0: SkCanvas::SaveLayerStrategy SkDebugCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint, michael@0: SaveFlags flags) { michael@0: this->addDrawCommand(new SkSaveLayerCommand(bounds, paint, flags)); michael@0: this->INHERITED::willSaveLayer(bounds, paint, flags); michael@0: // No need for a full layer. michael@0: return kNoLayer_SaveLayerStrategy; michael@0: } michael@0: michael@0: void SkDebugCanvas::didScale(SkScalar sx, SkScalar sy) { michael@0: addDrawCommand(new SkScaleCommand(sx, sy)); michael@0: this->INHERITED::didScale(sx, sy); michael@0: } michael@0: michael@0: void SkDebugCanvas::didSetMatrix(const SkMatrix& matrix) { michael@0: addDrawCommand(new SkSetMatrixCommand(matrix)); michael@0: this->INHERITED::didSetMatrix(matrix); michael@0: } michael@0: michael@0: void SkDebugCanvas::didSkew(SkScalar sx, SkScalar sy) { michael@0: addDrawCommand(new SkSkewCommand(sx, sy)); michael@0: this->INHERITED::didSkew(sx, sy); michael@0: } michael@0: michael@0: void SkDebugCanvas::didTranslate(SkScalar dx, SkScalar dy) { michael@0: addDrawCommand(new SkTranslateCommand(dx, dy)); michael@0: this->INHERITED::didTranslate(dx, dy); michael@0: } michael@0: michael@0: void SkDebugCanvas::toggleCommand(int index, bool toggle) { michael@0: SkASSERT(index < fCommandVector.count()); michael@0: fCommandVector[index]->setVisible(toggle); michael@0: }