blob: 59f982a9f507e53752c2e1ed01f40b810e59b46e [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() {
chudy@google.com97cee972012-08-07 20:41:37 +000027 commandVector.deleteAll();
chudy@google.com9cda6f72012-08-07 15:08:33 +000028}
chudy@google.com902ebe52012-06-29 14:21:22 +000029
30void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) {
chudy@google.com97cee972012-08-07 20:41:37 +000031 commandVector.push(command);
chudy@google.com902ebe52012-06-29 14:21:22 +000032}
33
34void SkDebugCanvas::draw(SkCanvas* canvas) {
chudy@google.com97cee972012-08-07 20:41:37 +000035 if(!commandVector.isEmpty()) {
36 for (int i = 0; i < commandVector.count(); i++) {
37 if (commandVector[i]->isVisible()) {
38 commandVector[i]->execute(canvas);
chudy@google.com0ab03392012-07-28 20:16:11 +000039 }
chudy@google.com902ebe52012-06-29 14:21:22 +000040 }
41 }
chudy@google.com97cee972012-08-07 20:41:37 +000042 fIndex = commandVector.count() - 1;
chudy@google.com902ebe52012-06-29 14:21:22 +000043}
44
chudy@google.com830b8792012-08-01 15:57:52 +000045void SkDebugCanvas::applyUserTransform(SkCanvas* canvas) {
46 canvas->translate(fUserOffset.fX, fUserOffset.fY);
47 if (fUserScale < 0) {
48 canvas->scale((1.0 / -fUserScale), (1.0 / -fUserScale));
49 } else if (fUserScale > 0) {
50 canvas->scale(fUserScale, fUserScale);
51 }
52}
53
54int SkDebugCanvas::getCommandAtPoint(int x, int y, int index) {
chudy@google.com0b5bbb02012-07-31 19:55:32 +000055 SkBitmap bitmap;
56 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
57 bitmap.allocPixels();
chudy@google.com902ebe52012-06-29 14:21:22 +000058
chudy@google.com0b5bbb02012-07-31 19:55:32 +000059 SkCanvas canvas(bitmap);
chudy@google.com830b8792012-08-01 15:57:52 +000060 canvas.translate(-x, -y);
61 applyUserTransform(&canvas);
chudy@google.com0b5bbb02012-07-31 19:55:32 +000062
63 int layer = 0;
chudy@google.com751961d2012-07-31 20:07:42 +000064 SkColor prev = bitmap.getColor(0,0);
chudy@google.com0b5bbb02012-07-31 19:55:32 +000065 for (int i = 0; i < index; i++) {
66 if (commandVector[i]->isVisible()) {
67 commandVector[i]->execute(&canvas);
68 }
69 if (prev != bitmap.getColor(0,0)) {
70 layer = i;
71 }
72 prev = bitmap.getColor(0,0);
73 }
74 return layer;
75}
76
77void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
78 int counter = 0;
chudy@google.com97cee972012-08-07 20:41:37 +000079 SkASSERT(!commandVector.isEmpty());
80 SkASSERT(index < commandVector.count());
chudy@google.com830b8792012-08-01 15:57:52 +000081 int i;
82
83 // This only works assuming the canvas and device are the same ones that
84 // were previously drawn into because they need to preserve all saves
85 // and restores.
86 if (fIndex < index) {
87 i = fIndex + 1;
88 } else {
89 i = 0;
90 canvas->clear(0);
91 canvas->resetMatrix();
92 applyUserTransform(canvas);
93 }
94
95 for (; i <= index; i++) {
chudy@google.com0b5bbb02012-07-31 19:55:32 +000096 if (i == index && fFilter) {
97 SkPaint p;
98 p.setColor(0xAAFFFFFF);
99 canvas->save();
100 canvas->resetMatrix();
101 SkRect mask;
102 mask.set(SkIntToScalar(0), SkIntToScalar(0),
103 SkIntToScalar(fWidth), SkIntToScalar(fHeight));
104 canvas->clipRect(mask, SkRegion::kReplace_Op, false);
105 canvas->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0),
106 SkIntToScalar(fWidth), SkIntToScalar(fHeight), p);
107 canvas->restore();
108 }
109
110 if (commandVector[i]->isVisible()) {
111 commandVector[i]->execute(canvas);
chudy@google.com902ebe52012-06-29 14:21:22 +0000112 }
113 }
chudy@google.coma9e937c2012-08-03 17:32:05 +0000114 fMatrix = canvas->getTotalMatrix();
115 fClip = canvas->getTotalClip().getBounds();
chudy@google.com830b8792012-08-01 15:57:52 +0000116 fIndex = index;
chudy@google.com902ebe52012-06-29 14:21:22 +0000117}
118
119SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) {
chudy@google.com97cee972012-08-07 20:41:37 +0000120 SkASSERT(index < commandVector.count());
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000121 return commandVector[index];
chudy@google.com902ebe52012-06-29 14:21:22 +0000122}
123
chudy@google.com97cee972012-08-07 20:41:37 +0000124SkTDArray<SkString*>* SkDebugCanvas::getCommandInfo(int index) {
125 SkASSERT(index < commandVector.count());
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000126 return commandVector[index]->Info();
127}
chudy@google.com902ebe52012-06-29 14:21:22 +0000128
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000129bool SkDebugCanvas::getDrawCommandVisibilityAt(int index) {
chudy@google.com97cee972012-08-07 20:41:37 +0000130 SkASSERT(index < commandVector.count());
chudy@google.com0b5bbb02012-07-31 19:55:32 +0000131 return commandVector[index]->isVisible();
chudy@google.com902ebe52012-06-29 14:21:22 +0000132}
133
chudy@google.com97cee972012-08-07 20:41:37 +0000134SkTDArray <SkDrawCommand*> SkDebugCanvas::getDrawCommands() {
chudy@google.com902ebe52012-06-29 14:21:22 +0000135 return commandVector;
136}
137
138// TODO(chudy): Free command string memory.
chudy@google.com97cee972012-08-07 20:41:37 +0000139SkTDArray<SkString*>* SkDebugCanvas::getDrawCommandsAsStrings() {
140 SkTDArray<SkString*>* commandString = new SkTDArray<SkString*>();
141 if (!commandVector.isEmpty()) {
142 for (int i = 0; i < commandVector.count(); i ++) {
143 commandString->push(new SkString(commandVector[i]->toString()));
chudy@google.com902ebe52012-06-29 14:21:22 +0000144 }
145 }
146 return commandString;
147}
148
149void SkDebugCanvas::toggleFilter(bool toggle) {
150 fFilter = toggle;
151}
152
153void SkDebugCanvas::clear(SkColor color) {
154 addDrawCommand(new Clear(color));
155}
156
157bool SkDebugCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
158 addDrawCommand(new ClipPath(path, op, doAA));
159 return true;
160}
161
162bool SkDebugCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
163 addDrawCommand(new ClipRect(rect, op, doAA));
164 return true;
165}
166
167bool SkDebugCanvas::clipRegion(const SkRegion& region, SkRegion::Op op) {
168 addDrawCommand(new ClipRegion(region, op));
169 return true;
170}
171
172bool SkDebugCanvas::concat(const SkMatrix& matrix) {
173 addDrawCommand(new Concat(matrix));
174 return true;
175}
176
177void SkDebugCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left,
178 SkScalar top, const SkPaint* paint = NULL) {
179 addDrawCommand(new DrawBitmap(bitmap, left, top, paint));
180}
181
182void SkDebugCanvas::drawBitmapRect(const SkBitmap& bitmap,
183 const SkIRect* src, const SkRect& dst, const SkPaint* paint) {
184 addDrawCommand(new DrawBitmapRect(bitmap, src, dst, paint));
185}
186
187void SkDebugCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
188 const SkMatrix& matrix, const SkPaint* paint) {
189 addDrawCommand(new DrawBitmapMatrix(bitmap, matrix, paint));
190}
191
192void SkDebugCanvas::drawBitmapNine(const SkBitmap& bitmap,
193 const SkIRect& center, const SkRect& dst, const SkPaint* paint) {
194 addDrawCommand(new DrawBitmapNine(bitmap, center, dst, paint));
195}
196
197void SkDebugCanvas::drawData(const void* data, size_t length) {
198 addDrawCommand(new DrawData(data, length));
199}
200
201void SkDebugCanvas::drawPaint(const SkPaint& paint) {
202 addDrawCommand(new DrawPaint(paint));
203}
204
205void SkDebugCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
206 addDrawCommand(new DrawPath(path, paint));
207}
208
209void SkDebugCanvas::drawPicture(SkPicture& picture) {
210 addDrawCommand(new DrawPicture(picture));
211}
212
213void SkDebugCanvas::drawPoints(PointMode mode, size_t count,
214 const SkPoint pts[], const SkPaint& paint) {
215 addDrawCommand(new DrawPoints(mode, count, pts, paint));
216}
217
218void SkDebugCanvas::drawPosText(const void* text, size_t byteLength,
219 const SkPoint pos[], const SkPaint& paint) {
220 addDrawCommand(new DrawPosText(text, byteLength, pos, paint));
221}
222
223void SkDebugCanvas::drawPosTextH(const void* text, size_t byteLength,
224 const SkScalar xpos[], SkScalar constY, const SkPaint& paint) {
225 addDrawCommand(new DrawPosTextH(text, byteLength, xpos, constY, paint));
226}
227
228void SkDebugCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
229 // NOTE(chudy): Messing up when renamed to DrawRect... Why?
230 addDrawCommand(new DrawRectC(rect, paint));
231}
232
233void SkDebugCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
234 const SkPaint* paint = NULL) {
235 addDrawCommand(new DrawSprite(bitmap, left, top, paint));
236}
237
238void SkDebugCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
239 SkScalar y, const SkPaint& paint) {
240 addDrawCommand(new DrawTextC(text, byteLength, x, y, paint));
241}
242
243void SkDebugCanvas::drawTextOnPath(const void* text, size_t byteLength,
244 const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) {
245 addDrawCommand(new DrawTextOnPath(text, byteLength, path, matrix, paint));
246}
247
248void SkDebugCanvas::drawVertices(VertexMode vmode, int vertexCount,
249 const SkPoint vertices[], const SkPoint texs[], const SkColor colors[],
250 SkXfermode*, const uint16_t indices[], int indexCount,
251 const SkPaint& paint) {
252 addDrawCommand(new DrawVertices(vmode, vertexCount, vertices, texs, colors,
253 NULL, indices, indexCount, paint));
254}
255
256void SkDebugCanvas::restore() {
257 addDrawCommand(new Restore());
258}
259
260bool SkDebugCanvas::rotate(SkScalar degrees) {
261 addDrawCommand(new Rotate(degrees));
262 return true;
263}
264
265int SkDebugCanvas::save(SaveFlags flags) {
266 addDrawCommand(new Save(flags));
267 return true;
268}
269
270int SkDebugCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
271 SaveFlags flags) {
272 addDrawCommand(new SaveLayer(bounds, paint, flags));
273 return true;
274}
275
276bool SkDebugCanvas::scale(SkScalar sx, SkScalar sy) {
277 addDrawCommand(new Scale(sx, sy));
278 return true;
279}
280
281void SkDebugCanvas::setMatrix(const SkMatrix& matrix) {
282 addDrawCommand(new SetMatrix(matrix));
283}
284
285bool SkDebugCanvas::skew(SkScalar sx, SkScalar sy) {
286 addDrawCommand(new Skew(sx, sy));
287 return true;
288}
289
290bool SkDebugCanvas::translate(SkScalar dx, SkScalar dy) {
291 addDrawCommand(new Translate(dx, dy));
292 return true;
293}
294
chudy@google.com902ebe52012-06-29 14:21:22 +0000295void SkDebugCanvas::toggleCommand(int index, bool toggle) {
chudy@google.com97cee972012-08-07 20:41:37 +0000296 SkASSERT(index < commandVector.count());
chudy@google.com0b5bbb02012-07-31 19:55:32 +0000297 commandVector[index]->setVisible(toggle);
chudy@google.com902ebe52012-06-29 14:21:22 +0000298}