blob: 6371f111e01ff980f3ae347333c41b551a8bdc86 [file] [log] [blame]
chudy@google.com902ebe52012-06-29 14:21:22 +00001
2/*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#include <iostream>
11#include "SkDebugCanvas.h"
12#include "SkDrawCommand.h"
13
chudy@google.com80a4a602012-07-30 18:54:07 +000014SkDebugCanvas::SkDebugCanvas(int width, int height) {
chudy@google.com902ebe52012-06-29 14:21:22 +000015 // TODO(chudy): Free up memory from all draw commands in destructor.
chudy@google.com80a4a602012-07-30 18:54:07 +000016 fWidth = width;
17 fHeight = height;
chudy@google.comb9ddd4e2012-07-10 14:14:50 +000018 fBm.setConfig(SkBitmap::kNo_Config, fWidth, fHeight);
chudy@google.com902ebe52012-06-29 14:21:22 +000019 this->setBitmapDevice(fBm);
20 fFilter = false;
chudy@google.com830b8792012-08-01 15:57:52 +000021 fIndex = 0;
22 fUserOffset.set(0,0);
23 fUserScale = 1.0;
chudy@google.com902ebe52012-06-29 14:21:22 +000024}
25
chudy@google.com9cda6f72012-08-07 15:08:33 +000026SkDebugCanvas::~SkDebugCanvas() {
27 for (int i = 0; i < commandVector.size(); i++) {
28 delete(commandVector[i]);
29 }
30 commandVector.clear();
31}
chudy@google.com902ebe52012-06-29 14:21:22 +000032
33void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) {
34 commandVector.push_back(command);
35}
36
37void SkDebugCanvas::draw(SkCanvas* canvas) {
38 if(!commandVector.empty()) {
39 for(it = commandVector.begin(); it != commandVector.end(); ++it) {
chudy@google.com0b5bbb02012-07-31 19:55:32 +000040 if ((*it)->isVisible()) {
chudy@google.com0ab03392012-07-28 20:16:11 +000041 (*it)->execute(canvas);
42 }
chudy@google.com902ebe52012-06-29 14:21:22 +000043 }
44 }
chudy@google.com830b8792012-08-01 15:57:52 +000045 fIndex = commandVector.size() - 1;
chudy@google.com902ebe52012-06-29 14:21:22 +000046}
47
chudy@google.com830b8792012-08-01 15:57:52 +000048void SkDebugCanvas::applyUserTransform(SkCanvas* canvas) {
49 canvas->translate(fUserOffset.fX, fUserOffset.fY);
50 if (fUserScale < 0) {
51 canvas->scale((1.0 / -fUserScale), (1.0 / -fUserScale));
52 } else if (fUserScale > 0) {
53 canvas->scale(fUserScale, fUserScale);
54 }
55}
56
57int SkDebugCanvas::getCommandAtPoint(int x, int y, int index) {
chudy@google.com0b5bbb02012-07-31 19:55:32 +000058 SkBitmap bitmap;
59 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
60 bitmap.allocPixels();
chudy@google.com902ebe52012-06-29 14:21:22 +000061
chudy@google.com0b5bbb02012-07-31 19:55:32 +000062 SkCanvas canvas(bitmap);
chudy@google.com830b8792012-08-01 15:57:52 +000063 canvas.translate(-x, -y);
64 applyUserTransform(&canvas);
chudy@google.com0b5bbb02012-07-31 19:55:32 +000065
66 int layer = 0;
chudy@google.com751961d2012-07-31 20:07:42 +000067 SkColor prev = bitmap.getColor(0,0);
chudy@google.com0b5bbb02012-07-31 19:55:32 +000068 for (int i = 0; i < index; i++) {
69 if (commandVector[i]->isVisible()) {
70 commandVector[i]->execute(&canvas);
71 }
72 if (prev != bitmap.getColor(0,0)) {
73 layer = i;
74 }
75 prev = bitmap.getColor(0,0);
76 }
77 return layer;
78}
79
80void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
81 int counter = 0;
82 SkASSERT(!commandVector.empty());
chudy@google.com751961d2012-07-31 20:07:42 +000083 SkASSERT(index < (int)commandVector.size());
chudy@google.com830b8792012-08-01 15:57:52 +000084 int i;
85
86 // This only works assuming the canvas and device are the same ones that
87 // were previously drawn into because they need to preserve all saves
88 // and restores.
89 if (fIndex < index) {
90 i = fIndex + 1;
91 } else {
92 i = 0;
93 canvas->clear(0);
94 canvas->resetMatrix();
95 applyUserTransform(canvas);
96 }
97
98 for (; i <= index; i++) {
chudy@google.com0b5bbb02012-07-31 19:55:32 +000099 if (i == index && fFilter) {
100 SkPaint p;
101 p.setColor(0xAAFFFFFF);
102 canvas->save();
103 canvas->resetMatrix();
104 SkRect mask;
105 mask.set(SkIntToScalar(0), SkIntToScalar(0),
106 SkIntToScalar(fWidth), SkIntToScalar(fHeight));
107 canvas->clipRect(mask, SkRegion::kReplace_Op, false);
108 canvas->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0),
109 SkIntToScalar(fWidth), SkIntToScalar(fHeight), p);
110 canvas->restore();
111 }
112
113 if (commandVector[i]->isVisible()) {
114 commandVector[i]->execute(canvas);
chudy@google.com902ebe52012-06-29 14:21:22 +0000115 }
116 }
chudy@google.coma9e937c2012-08-03 17:32:05 +0000117 fMatrix = canvas->getTotalMatrix();
118 fClip = canvas->getTotalClip().getBounds();
chudy@google.com830b8792012-08-01 15:57:52 +0000119 fIndex = index;
chudy@google.com902ebe52012-06-29 14:21:22 +0000120}
121
122SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) {
chudy@google.com751961d2012-07-31 20:07:42 +0000123 SkASSERT(index < (int)commandVector.size());
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000124 return commandVector[index];
chudy@google.com902ebe52012-06-29 14:21:22 +0000125}
126
127std::vector<std::string>* SkDebugCanvas::getCommandInfoAt(int index) {
chudy@google.com751961d2012-07-31 20:07:42 +0000128 SkASSERT(index < (int)commandVector.size());
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000129 return commandVector[index]->Info();
130}
chudy@google.com902ebe52012-06-29 14:21:22 +0000131
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000132bool SkDebugCanvas::getDrawCommandVisibilityAt(int index) {
chudy@google.com751961d2012-07-31 20:07:42 +0000133 SkASSERT(index < (int)commandVector.size());
chudy@google.com0b5bbb02012-07-31 19:55:32 +0000134 return commandVector[index]->isVisible();
chudy@google.com902ebe52012-06-29 14:21:22 +0000135}
136
137std::vector<SkDrawCommand*> SkDebugCanvas::getDrawCommands() {
138 return commandVector;
139}
140
141// TODO(chudy): Free command string memory.
142std::vector<std::string>* SkDebugCanvas::getDrawCommandsAsStrings() {
143 std::vector<std::string>* commandString = new std::vector<std::string>();
144 if (!commandVector.empty()) {
145 for(it = commandVector.begin(); it != commandVector.end(); ++it) {
146 commandString->push_back((*it)->toString());
147 }
148 }
149 return commandString;
150}
151
152void SkDebugCanvas::toggleFilter(bool toggle) {
153 fFilter = toggle;
154}
155
156void SkDebugCanvas::clear(SkColor color) {
157 addDrawCommand(new Clear(color));
158}
159
160bool SkDebugCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
161 addDrawCommand(new ClipPath(path, op, doAA));
162 return true;
163}
164
165bool SkDebugCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
166 addDrawCommand(new ClipRect(rect, op, doAA));
167 return true;
168}
169
170bool SkDebugCanvas::clipRegion(const SkRegion& region, SkRegion::Op op) {
171 addDrawCommand(new ClipRegion(region, op));
172 return true;
173}
174
175bool SkDebugCanvas::concat(const SkMatrix& matrix) {
176 addDrawCommand(new Concat(matrix));
177 return true;
178}
179
180void SkDebugCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left,
181 SkScalar top, const SkPaint* paint = NULL) {
182 addDrawCommand(new DrawBitmap(bitmap, left, top, paint));
183}
184
185void SkDebugCanvas::drawBitmapRect(const SkBitmap& bitmap,
186 const SkIRect* src, const SkRect& dst, const SkPaint* paint) {
187 addDrawCommand(new DrawBitmapRect(bitmap, src, dst, paint));
188}
189
190void SkDebugCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
191 const SkMatrix& matrix, const SkPaint* paint) {
192 addDrawCommand(new DrawBitmapMatrix(bitmap, matrix, paint));
193}
194
195void SkDebugCanvas::drawBitmapNine(const SkBitmap& bitmap,
196 const SkIRect& center, const SkRect& dst, const SkPaint* paint) {
197 addDrawCommand(new DrawBitmapNine(bitmap, center, dst, paint));
198}
199
200void SkDebugCanvas::drawData(const void* data, size_t length) {
201 addDrawCommand(new DrawData(data, length));
202}
203
204void SkDebugCanvas::drawPaint(const SkPaint& paint) {
205 addDrawCommand(new DrawPaint(paint));
206}
207
208void SkDebugCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
209 addDrawCommand(new DrawPath(path, paint));
210}
211
212void SkDebugCanvas::drawPicture(SkPicture& picture) {
213 addDrawCommand(new DrawPicture(picture));
214}
215
216void SkDebugCanvas::drawPoints(PointMode mode, size_t count,
217 const SkPoint pts[], const SkPaint& paint) {
218 addDrawCommand(new DrawPoints(mode, count, pts, paint));
219}
220
221void SkDebugCanvas::drawPosText(const void* text, size_t byteLength,
222 const SkPoint pos[], const SkPaint& paint) {
223 addDrawCommand(new DrawPosText(text, byteLength, pos, paint));
224}
225
226void SkDebugCanvas::drawPosTextH(const void* text, size_t byteLength,
227 const SkScalar xpos[], SkScalar constY, const SkPaint& paint) {
228 addDrawCommand(new DrawPosTextH(text, byteLength, xpos, constY, paint));
229}
230
231void SkDebugCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
232 // NOTE(chudy): Messing up when renamed to DrawRect... Why?
233 addDrawCommand(new DrawRectC(rect, paint));
234}
235
236void SkDebugCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
237 const SkPaint* paint = NULL) {
238 addDrawCommand(new DrawSprite(bitmap, left, top, paint));
239}
240
241void SkDebugCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
242 SkScalar y, const SkPaint& paint) {
243 addDrawCommand(new DrawTextC(text, byteLength, x, y, paint));
244}
245
246void SkDebugCanvas::drawTextOnPath(const void* text, size_t byteLength,
247 const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) {
248 addDrawCommand(new DrawTextOnPath(text, byteLength, path, matrix, paint));
249}
250
251void SkDebugCanvas::drawVertices(VertexMode vmode, int vertexCount,
252 const SkPoint vertices[], const SkPoint texs[], const SkColor colors[],
253 SkXfermode*, const uint16_t indices[], int indexCount,
254 const SkPaint& paint) {
255 addDrawCommand(new DrawVertices(vmode, vertexCount, vertices, texs, colors,
256 NULL, indices, indexCount, paint));
257}
258
259void SkDebugCanvas::restore() {
260 addDrawCommand(new Restore());
261}
262
263bool SkDebugCanvas::rotate(SkScalar degrees) {
264 addDrawCommand(new Rotate(degrees));
265 return true;
266}
267
268int SkDebugCanvas::save(SaveFlags flags) {
269 addDrawCommand(new Save(flags));
270 return true;
271}
272
273int SkDebugCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
274 SaveFlags flags) {
275 addDrawCommand(new SaveLayer(bounds, paint, flags));
276 return true;
277}
278
279bool SkDebugCanvas::scale(SkScalar sx, SkScalar sy) {
280 addDrawCommand(new Scale(sx, sy));
281 return true;
282}
283
284void SkDebugCanvas::setMatrix(const SkMatrix& matrix) {
285 addDrawCommand(new SetMatrix(matrix));
286}
287
288bool SkDebugCanvas::skew(SkScalar sx, SkScalar sy) {
289 addDrawCommand(new Skew(sx, sy));
290 return true;
291}
292
293bool SkDebugCanvas::translate(SkScalar dx, SkScalar dy) {
294 addDrawCommand(new Translate(dx, dy));
295 return true;
296}
297
chudy@google.com902ebe52012-06-29 14:21:22 +0000298void SkDebugCanvas::toggleCommand(int index, bool toggle) {
chudy@google.com751961d2012-07-31 20:07:42 +0000299 SkASSERT(index < (int)commandVector.size());
chudy@google.com0b5bbb02012-07-31 19:55:32 +0000300 commandVector[index]->setVisible(toggle);
chudy@google.com902ebe52012-06-29 14:21:22 +0000301}