1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/utils/debugger/SkDebugCanvas.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,579 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2012 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include "SkColorPriv.h" 1.14 +#include "SkDebugCanvas.h" 1.15 +#include "SkDrawCommand.h" 1.16 +#include "SkDrawFilter.h" 1.17 +#include "SkDevice.h" 1.18 +#include "SkXfermode.h" 1.19 + 1.20 +SkDebugCanvas::SkDebugCanvas(int width, int height) 1.21 + : INHERITED(width, height) 1.22 + , fWidth(width) 1.23 + , fHeight(height) 1.24 + , fFilter(false) 1.25 + , fMegaVizMode(false) 1.26 + , fIndex(0) 1.27 + , fOverdrawViz(false) 1.28 + , fOverdrawFilter(NULL) 1.29 + , fOverrideTexFiltering(false) 1.30 + , fTexOverrideFilter(NULL) 1.31 + , fOutstandingSaveCount(0) { 1.32 + fUserMatrix.reset(); 1.33 + 1.34 + // SkPicturePlayback uses the base-class' quickReject calls to cull clipped 1.35 + // operations. This can lead to problems in the debugger which expects all 1.36 + // the operations in the captured skp to appear in the debug canvas. To 1.37 + // circumvent this we create a wide open clip here (an empty clip rect 1.38 + // is not sufficient). 1.39 + // Internally, the SkRect passed to clipRect is converted to an SkIRect and 1.40 + // rounded out. The following code creates a nearly maximal rect that will 1.41 + // not get collapsed by the coming conversions (Due to precision loss the 1.42 + // inset has to be surprisingly large). 1.43 + SkIRect largeIRect = SkIRect::MakeLargest(); 1.44 + largeIRect.inset(1024, 1024); 1.45 + SkRect large = SkRect::Make(largeIRect); 1.46 +#ifdef SK_DEBUG 1.47 + large.roundOut(&largeIRect); 1.48 + SkASSERT(!largeIRect.isEmpty()); 1.49 +#endif 1.50 + // call the base class' version to avoid adding a draw command 1.51 + this->INHERITED::onClipRect(large, SkRegion::kReplace_Op, kHard_ClipEdgeStyle); 1.52 +} 1.53 + 1.54 +SkDebugCanvas::~SkDebugCanvas() { 1.55 + fCommandVector.deleteAll(); 1.56 + SkSafeUnref(fOverdrawFilter); 1.57 + SkSafeUnref(fTexOverrideFilter); 1.58 +} 1.59 + 1.60 +void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) { 1.61 + fCommandVector.push(command); 1.62 +} 1.63 + 1.64 +void SkDebugCanvas::draw(SkCanvas* canvas) { 1.65 + if (!fCommandVector.isEmpty()) { 1.66 + drawTo(canvas, fCommandVector.count() - 1); 1.67 + } 1.68 +} 1.69 + 1.70 +void SkDebugCanvas::applyUserTransform(SkCanvas* canvas) { 1.71 + canvas->concat(fUserMatrix); 1.72 +} 1.73 + 1.74 +int SkDebugCanvas::getCommandAtPoint(int x, int y, int index) { 1.75 + SkBitmap bitmap; 1.76 + bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1)); 1.77 + 1.78 + SkCanvas canvas(bitmap); 1.79 + canvas.translate(SkIntToScalar(-x), SkIntToScalar(-y)); 1.80 + applyUserTransform(&canvas); 1.81 + 1.82 + int layer = 0; 1.83 + SkColor prev = bitmap.getColor(0,0); 1.84 + for (int i = 0; i < index; i++) { 1.85 + if (fCommandVector[i]->isVisible()) { 1.86 + fCommandVector[i]->execute(&canvas); 1.87 + } 1.88 + if (prev != bitmap.getColor(0,0)) { 1.89 + layer = i; 1.90 + } 1.91 + prev = bitmap.getColor(0,0); 1.92 + } 1.93 + return layer; 1.94 +} 1.95 + 1.96 +static SkPMColor OverdrawXferModeProc(SkPMColor src, SkPMColor dst) { 1.97 + // This table encodes the color progression of the overdraw visualization 1.98 + static const SkPMColor gTable[] = { 1.99 + SkPackARGB32(0x00, 0x00, 0x00, 0x00), 1.100 + SkPackARGB32(0xFF, 128, 158, 255), 1.101 + SkPackARGB32(0xFF, 170, 185, 212), 1.102 + SkPackARGB32(0xFF, 213, 195, 170), 1.103 + SkPackARGB32(0xFF, 255, 192, 127), 1.104 + SkPackARGB32(0xFF, 255, 185, 85), 1.105 + SkPackARGB32(0xFF, 255, 165, 42), 1.106 + SkPackARGB32(0xFF, 255, 135, 0), 1.107 + SkPackARGB32(0xFF, 255, 95, 0), 1.108 + SkPackARGB32(0xFF, 255, 50, 0), 1.109 + SkPackARGB32(0xFF, 255, 0, 0) 1.110 + }; 1.111 + 1.112 + for (size_t i = 0; i < SK_ARRAY_COUNT(gTable)-1; ++i) { 1.113 + if (gTable[i] == dst) { 1.114 + return gTable[i+1]; 1.115 + } 1.116 + } 1.117 + 1.118 + return gTable[SK_ARRAY_COUNT(gTable)-1]; 1.119 +} 1.120 + 1.121 +// The OverdrawFilter modifies every paint to use an SkProcXfermode which 1.122 +// in turn invokes OverdrawXferModeProc 1.123 +class SkOverdrawFilter : public SkDrawFilter { 1.124 +public: 1.125 + SkOverdrawFilter() { 1.126 + fXferMode = SkProcXfermode::Create(OverdrawXferModeProc); 1.127 + } 1.128 + 1.129 + virtual ~SkOverdrawFilter() { 1.130 + delete fXferMode; 1.131 + } 1.132 + 1.133 + virtual bool filter(SkPaint* p, Type) SK_OVERRIDE { 1.134 + p->setXfermode(fXferMode); 1.135 + return true; 1.136 + } 1.137 + 1.138 +protected: 1.139 + SkXfermode* fXferMode; 1.140 + 1.141 +private: 1.142 + typedef SkDrawFilter INHERITED; 1.143 +}; 1.144 + 1.145 +// SkTexOverrideFilter modifies every paint to use the specified 1.146 +// texture filtering mode 1.147 +class SkTexOverrideFilter : public SkDrawFilter { 1.148 +public: 1.149 + SkTexOverrideFilter() : fFilterLevel(SkPaint::kNone_FilterLevel) { 1.150 + } 1.151 + 1.152 + void setFilterLevel(SkPaint::FilterLevel filterLevel) { 1.153 + fFilterLevel = filterLevel; 1.154 + } 1.155 + 1.156 + virtual bool filter(SkPaint* p, Type) SK_OVERRIDE { 1.157 + p->setFilterLevel(fFilterLevel); 1.158 + return true; 1.159 + } 1.160 + 1.161 +protected: 1.162 + SkPaint::FilterLevel fFilterLevel; 1.163 + 1.164 +private: 1.165 + typedef SkDrawFilter INHERITED; 1.166 +}; 1.167 + 1.168 +class SkDebugClipVisitor : public SkCanvas::ClipVisitor { 1.169 +public: 1.170 + SkDebugClipVisitor(SkCanvas* canvas) : fCanvas(canvas) {} 1.171 + 1.172 + virtual void clipRect(const SkRect& r, SkRegion::Op, bool doAA) SK_OVERRIDE { 1.173 + SkPaint p; 1.174 + p.setColor(SK_ColorRED); 1.175 + p.setStyle(SkPaint::kStroke_Style); 1.176 + p.setAntiAlias(doAA); 1.177 + fCanvas->drawRect(r, p); 1.178 + } 1.179 + virtual void clipRRect(const SkRRect& rr, SkRegion::Op, bool doAA) SK_OVERRIDE { 1.180 + SkPaint p; 1.181 + p.setColor(SK_ColorGREEN); 1.182 + p.setStyle(SkPaint::kStroke_Style); 1.183 + p.setAntiAlias(doAA); 1.184 + fCanvas->drawRRect(rr, p); 1.185 + } 1.186 + virtual void clipPath(const SkPath& path, SkRegion::Op, bool doAA) SK_OVERRIDE { 1.187 + SkPaint p; 1.188 + p.setColor(SK_ColorBLUE); 1.189 + p.setStyle(SkPaint::kStroke_Style); 1.190 + p.setAntiAlias(doAA); 1.191 + fCanvas->drawPath(path, p); 1.192 + } 1.193 + 1.194 +protected: 1.195 + SkCanvas* fCanvas; 1.196 + 1.197 +private: 1.198 + typedef SkCanvas::ClipVisitor INHERITED; 1.199 +}; 1.200 + 1.201 +// set up the saveLayer commands so that the active ones 1.202 +// return true in their 'active' method 1.203 +void SkDebugCanvas::markActiveCommands(int index) { 1.204 + fActiveLayers.rewind(); 1.205 + fActiveCulls.rewind(); 1.206 + 1.207 + for (int i = 0; i < fCommandVector.count(); ++i) { 1.208 + fCommandVector[i]->setActive(false); 1.209 + } 1.210 + 1.211 + for (int i = 0; i < index; ++i) { 1.212 + SkDrawCommand::Action result = fCommandVector[i]->action(); 1.213 + if (SkDrawCommand::kPushLayer_Action == result) { 1.214 + fActiveLayers.push(fCommandVector[i]); 1.215 + } else if (SkDrawCommand::kPopLayer_Action == result) { 1.216 + fActiveLayers.pop(); 1.217 + } else if (SkDrawCommand::kPushCull_Action == result) { 1.218 + fActiveCulls.push(fCommandVector[i]); 1.219 + } else if (SkDrawCommand::kPopCull_Action == result) { 1.220 + fActiveCulls.pop(); 1.221 + } 1.222 + } 1.223 + 1.224 + for (int i = 0; i < fActiveLayers.count(); ++i) { 1.225 + fActiveLayers[i]->setActive(true); 1.226 + } 1.227 + 1.228 + for (int i = 0; i < fActiveCulls.count(); ++i) { 1.229 + fActiveCulls[i]->setActive(true); 1.230 + } 1.231 +} 1.232 + 1.233 +void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) { 1.234 + SkASSERT(!fCommandVector.isEmpty()); 1.235 + SkASSERT(index < fCommandVector.count()); 1.236 + int i = 0; 1.237 + 1.238 + // This only works assuming the canvas and device are the same ones that 1.239 + // were previously drawn into because they need to preserve all saves 1.240 + // and restores. 1.241 + // The visibility filter also requires a full re-draw - otherwise we can 1.242 + // end up drawing the filter repeatedly. 1.243 + if (fIndex < index && !fFilter && !fMegaVizMode) { 1.244 + i = fIndex + 1; 1.245 + } else { 1.246 + for (int j = 0; j < fOutstandingSaveCount; j++) { 1.247 + canvas->restore(); 1.248 + } 1.249 + canvas->clear(SK_ColorTRANSPARENT); 1.250 + canvas->resetMatrix(); 1.251 + SkRect rect = SkRect::MakeWH(SkIntToScalar(fWidth), 1.252 + SkIntToScalar(fHeight)); 1.253 + canvas->clipRect(rect, SkRegion::kReplace_Op ); 1.254 + applyUserTransform(canvas); 1.255 + fOutstandingSaveCount = 0; 1.256 + } 1.257 + 1.258 + // The setting of the draw filter has to go here (rather than in 1.259 + // SkRasterWidget) due to the canvas restores this class performs. 1.260 + // Since the draw filter is stored in the layer stack if we 1.261 + // call setDrawFilter on anything but the root layer odd things happen. 1.262 + if (fOverdrawViz) { 1.263 + if (NULL == fOverdrawFilter) { 1.264 + fOverdrawFilter = new SkOverdrawFilter; 1.265 + } 1.266 + 1.267 + if (fOverdrawFilter != canvas->getDrawFilter()) { 1.268 + canvas->setDrawFilter(fOverdrawFilter); 1.269 + } 1.270 + } else if (fOverrideTexFiltering) { 1.271 + if (NULL == fTexOverrideFilter) { 1.272 + fTexOverrideFilter = new SkTexOverrideFilter; 1.273 + } 1.274 + 1.275 + if (fTexOverrideFilter != canvas->getDrawFilter()) { 1.276 + canvas->setDrawFilter(fTexOverrideFilter); 1.277 + } 1.278 + } else { 1.279 + canvas->setDrawFilter(NULL); 1.280 + } 1.281 + 1.282 + if (fMegaVizMode) { 1.283 + this->markActiveCommands(index); 1.284 + } 1.285 + 1.286 + for (; i <= index; i++) { 1.287 + if (i == index && fFilter) { 1.288 + SkPaint p; 1.289 + p.setColor(0xAAFFFFFF); 1.290 + canvas->save(); 1.291 + canvas->resetMatrix(); 1.292 + SkRect mask; 1.293 + mask.set(SkIntToScalar(0), SkIntToScalar(0), 1.294 + SkIntToScalar(fWidth), SkIntToScalar(fHeight)); 1.295 + canvas->clipRect(mask, SkRegion::kReplace_Op, false); 1.296 + canvas->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0), 1.297 + SkIntToScalar(fWidth), SkIntToScalar(fHeight), p); 1.298 + canvas->restore(); 1.299 + } 1.300 + 1.301 + if (fCommandVector[i]->isVisible()) { 1.302 + if (fMegaVizMode && fCommandVector[i]->active()) { 1.303 + // "active" commands execute their visualization behaviors: 1.304 + // All active saveLayers get replaced with saves so all draws go to the 1.305 + // visible canvas. 1.306 + // All active culls draw their cull box 1.307 + fCommandVector[i]->vizExecute(canvas); 1.308 + } else { 1.309 + fCommandVector[i]->execute(canvas); 1.310 + } 1.311 + 1.312 + fCommandVector[i]->trackSaveState(&fOutstandingSaveCount); 1.313 + } 1.314 + } 1.315 + 1.316 + if (fMegaVizMode) { 1.317 + SkRect r = SkRect::MakeWH(SkIntToScalar(fWidth), SkIntToScalar(fHeight)); 1.318 + r.outset(SK_Scalar1, SK_Scalar1); 1.319 + 1.320 + canvas->save(); 1.321 + // nuke the CTM 1.322 + canvas->setMatrix(SkMatrix::I()); 1.323 + // turn off clipping 1.324 + canvas->clipRect(r, SkRegion::kReplace_Op); 1.325 + 1.326 + // visualize existing clips 1.327 + SkDebugClipVisitor visitor(canvas); 1.328 + 1.329 + canvas->replayClips(&visitor); 1.330 + 1.331 + canvas->restore(); 1.332 + } 1.333 + fMatrix = canvas->getTotalMatrix(); 1.334 + if (!canvas->getClipDeviceBounds(&fClip)) { 1.335 + fClip.setEmpty(); 1.336 + } 1.337 + fIndex = index; 1.338 +} 1.339 + 1.340 +void SkDebugCanvas::deleteDrawCommandAt(int index) { 1.341 + SkASSERT(index < fCommandVector.count()); 1.342 + delete fCommandVector[index]; 1.343 + fCommandVector.remove(index); 1.344 +} 1.345 + 1.346 +SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) { 1.347 + SkASSERT(index < fCommandVector.count()); 1.348 + return fCommandVector[index]; 1.349 +} 1.350 + 1.351 +void SkDebugCanvas::setDrawCommandAt(int index, SkDrawCommand* command) { 1.352 + SkASSERT(index < fCommandVector.count()); 1.353 + delete fCommandVector[index]; 1.354 + fCommandVector[index] = command; 1.355 +} 1.356 + 1.357 +SkTDArray<SkString*>* SkDebugCanvas::getCommandInfo(int index) { 1.358 + SkASSERT(index < fCommandVector.count()); 1.359 + return fCommandVector[index]->Info(); 1.360 +} 1.361 + 1.362 +bool SkDebugCanvas::getDrawCommandVisibilityAt(int index) { 1.363 + SkASSERT(index < fCommandVector.count()); 1.364 + return fCommandVector[index]->isVisible(); 1.365 +} 1.366 + 1.367 +const SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() const { 1.368 + return fCommandVector; 1.369 +} 1.370 + 1.371 +SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() { 1.372 + return fCommandVector; 1.373 +} 1.374 + 1.375 +// TODO(chudy): Free command string memory. 1.376 +SkTArray<SkString>* SkDebugCanvas::getDrawCommandsAsStrings() const { 1.377 + SkTArray<SkString>* commandString = new SkTArray<SkString>(fCommandVector.count()); 1.378 + if (!fCommandVector.isEmpty()) { 1.379 + for (int i = 0; i < fCommandVector.count(); i ++) { 1.380 + commandString->push_back() = fCommandVector[i]->toString(); 1.381 + } 1.382 + } 1.383 + return commandString; 1.384 +} 1.385 + 1.386 +void SkDebugCanvas::overrideTexFiltering(bool overrideTexFiltering, SkPaint::FilterLevel level) { 1.387 + if (NULL == fTexOverrideFilter) { 1.388 + fTexOverrideFilter = new SkTexOverrideFilter; 1.389 + } 1.390 + 1.391 + fOverrideTexFiltering = overrideTexFiltering; 1.392 + fTexOverrideFilter->setFilterLevel(level); 1.393 +} 1.394 + 1.395 +void SkDebugCanvas::clear(SkColor color) { 1.396 + addDrawCommand(new SkClearCommand(color)); 1.397 +} 1.398 + 1.399 +void SkDebugCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1.400 + this->addDrawCommand(new SkClipPathCommand(path, op, kSoft_ClipEdgeStyle == edgeStyle)); 1.401 +} 1.402 + 1.403 +void SkDebugCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1.404 + this->addDrawCommand(new SkClipRectCommand(rect, op, kSoft_ClipEdgeStyle == edgeStyle)); 1.405 +} 1.406 + 1.407 +void SkDebugCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1.408 + this->addDrawCommand(new SkClipRRectCommand(rrect, op, kSoft_ClipEdgeStyle == edgeStyle)); 1.409 +} 1.410 + 1.411 +void SkDebugCanvas::onClipRegion(const SkRegion& region, SkRegion::Op op) { 1.412 + this->addDrawCommand(new SkClipRegionCommand(region, op)); 1.413 +} 1.414 + 1.415 +void SkDebugCanvas::didConcat(const SkMatrix& matrix) { 1.416 + addDrawCommand(new SkConcatCommand(matrix)); 1.417 + this->INHERITED::didConcat(matrix); 1.418 +} 1.419 + 1.420 +void SkDebugCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left, 1.421 + SkScalar top, const SkPaint* paint = NULL) { 1.422 + addDrawCommand(new SkDrawBitmapCommand(bitmap, left, top, paint)); 1.423 +} 1.424 + 1.425 +void SkDebugCanvas::drawBitmapRectToRect(const SkBitmap& bitmap, 1.426 + const SkRect* src, const SkRect& dst, 1.427 + const SkPaint* paint, 1.428 + SkCanvas::DrawBitmapRectFlags flags) { 1.429 + addDrawCommand(new SkDrawBitmapRectCommand(bitmap, src, dst, paint, flags)); 1.430 +} 1.431 + 1.432 +void SkDebugCanvas::drawBitmapMatrix(const SkBitmap& bitmap, 1.433 + const SkMatrix& matrix, const SkPaint* paint) { 1.434 + addDrawCommand(new SkDrawBitmapMatrixCommand(bitmap, matrix, paint)); 1.435 +} 1.436 + 1.437 +void SkDebugCanvas::drawBitmapNine(const SkBitmap& bitmap, 1.438 + const SkIRect& center, const SkRect& dst, const SkPaint* paint) { 1.439 + addDrawCommand(new SkDrawBitmapNineCommand(bitmap, center, dst, paint)); 1.440 +} 1.441 + 1.442 +void SkDebugCanvas::drawData(const void* data, size_t length) { 1.443 + addDrawCommand(new SkDrawDataCommand(data, length)); 1.444 +} 1.445 + 1.446 +void SkDebugCanvas::beginCommentGroup(const char* description) { 1.447 + addDrawCommand(new SkBeginCommentGroupCommand(description)); 1.448 +} 1.449 + 1.450 +void SkDebugCanvas::addComment(const char* kywd, const char* value) { 1.451 + addDrawCommand(new SkCommentCommand(kywd, value)); 1.452 +} 1.453 + 1.454 +void SkDebugCanvas::endCommentGroup() { 1.455 + addDrawCommand(new SkEndCommentGroupCommand()); 1.456 +} 1.457 + 1.458 +void SkDebugCanvas::drawOval(const SkRect& oval, const SkPaint& paint) { 1.459 + addDrawCommand(new SkDrawOvalCommand(oval, paint)); 1.460 +} 1.461 + 1.462 +void SkDebugCanvas::drawPaint(const SkPaint& paint) { 1.463 + addDrawCommand(new SkDrawPaintCommand(paint)); 1.464 +} 1.465 + 1.466 +void SkDebugCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 1.467 + addDrawCommand(new SkDrawPathCommand(path, paint)); 1.468 +} 1.469 + 1.470 +void SkDebugCanvas::drawPicture(SkPicture& picture) { 1.471 + addDrawCommand(new SkDrawPictureCommand(picture)); 1.472 +} 1.473 + 1.474 +void SkDebugCanvas::drawPoints(PointMode mode, size_t count, 1.475 + const SkPoint pts[], const SkPaint& paint) { 1.476 + addDrawCommand(new SkDrawPointsCommand(mode, count, pts, paint)); 1.477 +} 1.478 + 1.479 +void SkDebugCanvas::drawPosText(const void* text, size_t byteLength, 1.480 + const SkPoint pos[], const SkPaint& paint) { 1.481 + addDrawCommand(new SkDrawPosTextCommand(text, byteLength, pos, paint)); 1.482 +} 1.483 + 1.484 +void SkDebugCanvas::drawPosTextH(const void* text, size_t byteLength, 1.485 + const SkScalar xpos[], SkScalar constY, const SkPaint& paint) { 1.486 + addDrawCommand( 1.487 + new SkDrawPosTextHCommand(text, byteLength, xpos, constY, paint)); 1.488 +} 1.489 + 1.490 +void SkDebugCanvas::drawRect(const SkRect& rect, const SkPaint& paint) { 1.491 + // NOTE(chudy): Messing up when renamed to DrawRect... Why? 1.492 + addDrawCommand(new SkDrawRectCommand(rect, paint)); 1.493 +} 1.494 + 1.495 +void SkDebugCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 1.496 + addDrawCommand(new SkDrawRRectCommand(rrect, paint)); 1.497 +} 1.498 + 1.499 +void SkDebugCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 1.500 + const SkPaint& paint) { 1.501 + this->addDrawCommand(new SkDrawDRRectCommand(outer, inner, paint)); 1.502 +} 1.503 + 1.504 +void SkDebugCanvas::drawSprite(const SkBitmap& bitmap, int left, int top, 1.505 + const SkPaint* paint = NULL) { 1.506 + addDrawCommand(new SkDrawSpriteCommand(bitmap, left, top, paint)); 1.507 +} 1.508 + 1.509 +void SkDebugCanvas::drawText(const void* text, size_t byteLength, SkScalar x, 1.510 + SkScalar y, const SkPaint& paint) { 1.511 + addDrawCommand(new SkDrawTextCommand(text, byteLength, x, y, paint)); 1.512 +} 1.513 + 1.514 +void SkDebugCanvas::drawTextOnPath(const void* text, size_t byteLength, 1.515 + const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) { 1.516 + addDrawCommand( 1.517 + new SkDrawTextOnPathCommand(text, byteLength, path, matrix, paint)); 1.518 +} 1.519 + 1.520 +void SkDebugCanvas::drawVertices(VertexMode vmode, int vertexCount, 1.521 + const SkPoint vertices[], const SkPoint texs[], const SkColor colors[], 1.522 + SkXfermode*, const uint16_t indices[], int indexCount, 1.523 + const SkPaint& paint) { 1.524 + addDrawCommand(new SkDrawVerticesCommand(vmode, vertexCount, vertices, 1.525 + texs, colors, NULL, indices, indexCount, paint)); 1.526 +} 1.527 + 1.528 +void SkDebugCanvas::onPushCull(const SkRect& cullRect) { 1.529 + this->addDrawCommand(new SkPushCullCommand(cullRect)); 1.530 +} 1.531 + 1.532 +void SkDebugCanvas::onPopCull() { 1.533 + this->addDrawCommand(new SkPopCullCommand()); 1.534 +} 1.535 + 1.536 +void SkDebugCanvas::willRestore() { 1.537 + this->addDrawCommand(new SkRestoreCommand()); 1.538 + this->INHERITED::willRestore(); 1.539 +} 1.540 + 1.541 +void SkDebugCanvas::didRotate(SkScalar degrees) { 1.542 + addDrawCommand(new SkRotateCommand(degrees)); 1.543 + this->INHERITED::didRotate(degrees); 1.544 +} 1.545 + 1.546 +void SkDebugCanvas::willSave(SaveFlags flags) { 1.547 + this->addDrawCommand(new SkSaveCommand(flags)); 1.548 + this->INHERITED::willSave(flags); 1.549 +} 1.550 + 1.551 +SkCanvas::SaveLayerStrategy SkDebugCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint, 1.552 + SaveFlags flags) { 1.553 + this->addDrawCommand(new SkSaveLayerCommand(bounds, paint, flags)); 1.554 + this->INHERITED::willSaveLayer(bounds, paint, flags); 1.555 + // No need for a full layer. 1.556 + return kNoLayer_SaveLayerStrategy; 1.557 +} 1.558 + 1.559 +void SkDebugCanvas::didScale(SkScalar sx, SkScalar sy) { 1.560 + addDrawCommand(new SkScaleCommand(sx, sy)); 1.561 + this->INHERITED::didScale(sx, sy); 1.562 +} 1.563 + 1.564 +void SkDebugCanvas::didSetMatrix(const SkMatrix& matrix) { 1.565 + addDrawCommand(new SkSetMatrixCommand(matrix)); 1.566 + this->INHERITED::didSetMatrix(matrix); 1.567 +} 1.568 + 1.569 +void SkDebugCanvas::didSkew(SkScalar sx, SkScalar sy) { 1.570 + addDrawCommand(new SkSkewCommand(sx, sy)); 1.571 + this->INHERITED::didSkew(sx, sy); 1.572 +} 1.573 + 1.574 +void SkDebugCanvas::didTranslate(SkScalar dx, SkScalar dy) { 1.575 + addDrawCommand(new SkTranslateCommand(dx, dy)); 1.576 + this->INHERITED::didTranslate(dx, dy); 1.577 +} 1.578 + 1.579 +void SkDebugCanvas::toggleCommand(int index, bool toggle) { 1.580 + SkASSERT(index < fCommandVector.count()); 1.581 + fCommandVector[index]->setVisible(toggle); 1.582 +}