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