OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 #include "sky/engine/config.h" | |
32 #include "sky/engine/platform/graphics/LoggingCanvas.h" | |
33 | |
34 #include "platform/image-encoders/skia/PNGImageEncoder.h" | |
35 #include "sky/engine/wtf/HexNumber.h" | |
36 #include "sky/engine/wtf/text/Base64.h" | |
37 #include "sky/engine/wtf/text/TextEncoding.h" | |
38 #include "third_party/skia/include/core/SkPicture.h" | |
39 | |
40 namespace blink { | |
41 | |
42 class AutoLogger { | |
43 public: | |
44 explicit AutoLogger(LoggingCanvas*); | |
45 PassRefPtr<JSONObject> logItem(const String& name); | |
46 PassRefPtr<JSONObject> logItemWithParams(const String& name); | |
47 ~AutoLogger(); | |
48 | |
49 private: | |
50 LoggingCanvas* m_canvas; | |
51 RefPtr<JSONObject> m_logItem; | |
52 }; | |
53 | |
54 AutoLogger::AutoLogger(LoggingCanvas* loggingCanvas) : m_canvas(loggingCanvas) | |
55 { | |
56 loggingCanvas->m_depthCount++; | |
57 } | |
58 | |
59 PassRefPtr<JSONObject> AutoLogger::logItem(const String& name) | |
60 { | |
61 RefPtr<JSONObject> item = JSONObject::create(); | |
62 item->setString("method", name); | |
63 m_logItem = item; | |
64 return item.release(); | |
65 } | |
66 | |
67 PassRefPtr<JSONObject> AutoLogger::logItemWithParams(const String& name) | |
68 { | |
69 RefPtr<JSONObject> item = logItem(name); | |
70 RefPtr<JSONObject> params = JSONObject::create(); | |
71 item->setObject("params", params); | |
72 return params.release(); | |
73 } | |
74 | |
75 AutoLogger::~AutoLogger() | |
76 { | |
77 m_canvas->m_depthCount--; | |
78 if (!m_canvas->m_depthCount) | |
79 m_canvas->m_log->pushObject(m_logItem); | |
80 } | |
81 | |
82 LoggingCanvas::LoggingCanvas(int width, int height) : InterceptingCanvas(width,
height) | |
83 { | |
84 m_log = JSONArray::create(); | |
85 } | |
86 | |
87 void LoggingCanvas::drawPaint(const SkPaint& paint) | |
88 { | |
89 AutoLogger logger(this); | |
90 logger.logItemWithParams("drawPaint")->setObject("paint", objectForSkPaint(p
aint)); | |
91 this->SkCanvas::drawPaint(paint); | |
92 } | |
93 | |
94 void LoggingCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[]
, const SkPaint& paint) | |
95 { | |
96 AutoLogger logger(this); | |
97 RefPtr<JSONObject> params = logger.logItemWithParams("drawPoints"); | |
98 params->setString("pointMode", pointModeName(mode)); | |
99 params->setArray("points", arrayForSkPoints(count, pts)); | |
100 params->setObject("paint", objectForSkPaint(paint)); | |
101 this->SkCanvas::drawPoints(mode, count, pts, paint); | |
102 } | |
103 | |
104 void LoggingCanvas::drawRect(const SkRect& rect, const SkPaint& paint) | |
105 { | |
106 AutoLogger logger(this); | |
107 RefPtr<JSONObject> params = logger.logItemWithParams("drawRect"); | |
108 params->setObject("rect", objectForSkRect(rect)); | |
109 params->setObject("paint", objectForSkPaint(paint)); | |
110 this->SkCanvas::drawRect(rect, paint); | |
111 } | |
112 | |
113 void LoggingCanvas::drawOval(const SkRect& oval, const SkPaint& paint) | |
114 { | |
115 AutoLogger logger(this); | |
116 RefPtr<JSONObject> params = logger.logItemWithParams("drawOval"); | |
117 params->setObject("oval", objectForSkRect(oval)); | |
118 params->setObject("paint", objectForSkPaint(paint)); | |
119 this->SkCanvas::drawOval(oval, paint); | |
120 } | |
121 | |
122 void LoggingCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) | |
123 { | |
124 AutoLogger logger(this); | |
125 RefPtr<JSONObject> params = logger.logItemWithParams("drawRRect"); | |
126 params->setObject("rrect", objectForSkRRect(rrect)); | |
127 params->setObject("paint", objectForSkPaint(paint)); | |
128 this->SkCanvas::drawRRect(rrect, paint); | |
129 } | |
130 | |
131 void LoggingCanvas::drawPath(const SkPath& path, const SkPaint& paint) | |
132 { | |
133 AutoLogger logger(this); | |
134 RefPtr<JSONObject> params = logger.logItemWithParams("drawPath"); | |
135 params->setObject("path", objectForSkPath(path)); | |
136 params->setObject("paint", objectForSkPaint(paint)); | |
137 this->SkCanvas::drawPath(path, paint); | |
138 } | |
139 | |
140 void LoggingCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar t
op, const SkPaint* paint) | |
141 { | |
142 AutoLogger logger(this); | |
143 RefPtr<JSONObject> params = logger.logItemWithParams("drawBitmap"); | |
144 params->setNumber("left", left); | |
145 params->setNumber("top", top); | |
146 params->setObject("bitmap", objectForSkBitmap(bitmap)); | |
147 params->setObject("paint", objectForSkPaint(*paint)); | |
148 this->SkCanvas::drawBitmap(bitmap, left, top, paint); | |
149 } | |
150 | |
151 void LoggingCanvas::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* s
rc, const SkRect& dst, const SkPaint* paint, DrawBitmapRectFlags flags) | |
152 { | |
153 AutoLogger logger(this); | |
154 RefPtr<JSONObject> params = logger.logItemWithParams("drawBitmapRectToRect")
; | |
155 params->setObject("bitmap", objectForSkBitmap(bitmap)); | |
156 params->setObject("src", objectForSkRect(*src)); | |
157 params->setObject("dst", objectForSkRect(dst)); | |
158 params->setObject("paint", objectForSkPaint(*paint)); | |
159 params->setNumber("flags", flags); | |
160 this->SkCanvas::drawBitmapRectToRect(bitmap, src, dst, paint, flags); | |
161 } | |
162 | |
163 void LoggingCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center
, const SkRect& dst, const SkPaint* paint) | |
164 { | |
165 AutoLogger logger(this); | |
166 RefPtr<JSONObject> params = logger.logItemWithParams("drawBitmapNine"); | |
167 params->setObject("bitmap", objectForSkBitmap(bitmap)); | |
168 params->setObject("center", objectForSkIRect(center)); | |
169 params->setObject("dst", objectForSkRect(dst)); | |
170 params->setObject("paint", objectForSkPaint(*paint)); | |
171 this->SkCanvas::drawBitmapNine(bitmap, center, dst, paint); | |
172 } | |
173 | |
174 void LoggingCanvas::drawSprite(const SkBitmap& bitmap, int left, int top, const
SkPaint* paint) | |
175 { | |
176 AutoLogger logger(this); | |
177 RefPtr<JSONObject> params = logger.logItemWithParams("drawSprite"); | |
178 params->setObject("bitmap", objectForSkBitmap(bitmap)); | |
179 params->setNumber("left", left); | |
180 params->setNumber("top", top); | |
181 params->setObject("paint", objectForSkPaint(*paint)); | |
182 this->SkCanvas::drawSprite(bitmap, left, top, paint); | |
183 } | |
184 | |
185 void LoggingCanvas::drawVertices(VertexMode vmode, int vertexCount, const SkPoin
t vertices[], const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, | |
186 const uint16_t indices[], int indexCount, const SkPaint& paint) | |
187 { | |
188 AutoLogger logger(this); | |
189 RefPtr<JSONObject> params = logger.logItemWithParams("drawVertices"); | |
190 params->setObject("paint", objectForSkPaint(paint)); | |
191 this->SkCanvas::drawVertices(vmode, vertexCount, vertices, texs, colors, xmo
de, indices, indexCount, paint); | |
192 } | |
193 | |
194 void LoggingCanvas::drawData(const void* data, size_t length) | |
195 { | |
196 AutoLogger logger(this); | |
197 RefPtr<JSONObject> params = logger.logItemWithParams("drawData"); | |
198 params->setNumber("length", length); | |
199 this->SkCanvas::drawData(data, length); | |
200 } | |
201 | |
202 void LoggingCanvas::beginCommentGroup(const char* description) | |
203 { | |
204 AutoLogger logger(this); | |
205 RefPtr<JSONObject> params = logger.logItemWithParams("beginCommentGroup"); | |
206 params->setString("description", description); | |
207 this->SkCanvas::beginCommentGroup(description); | |
208 } | |
209 | |
210 void LoggingCanvas::addComment(const char* keyword, const char* value) | |
211 { | |
212 AutoLogger logger(this); | |
213 RefPtr<JSONObject> params = logger.logItemWithParams("addComment"); | |
214 params->setString("key", keyword); | |
215 params->setString("value", value); | |
216 this->SkCanvas::addComment(keyword, value); | |
217 } | |
218 | |
219 void LoggingCanvas::endCommentGroup() | |
220 { | |
221 AutoLogger logger(this); | |
222 logger.logItem("endCommentGroup"); | |
223 this->SkCanvas::endCommentGroup(); | |
224 } | |
225 | |
226 void LoggingCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, con
st SkPaint& paint) | |
227 { | |
228 AutoLogger logger(this); | |
229 RefPtr<JSONObject> params = logger.logItemWithParams("drawDRRect"); | |
230 params->setObject("outer", objectForSkRRect(outer)); | |
231 params->setObject("inner", objectForSkRRect(inner)); | |
232 params->setObject("paint", objectForSkPaint(paint)); | |
233 this->SkCanvas::onDrawDRRect(outer, inner, paint); | |
234 } | |
235 | |
236 void LoggingCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x,
SkScalar y, const SkPaint& paint) | |
237 { | |
238 AutoLogger logger(this); | |
239 RefPtr<JSONObject> params = logger.logItemWithParams("drawText"); | |
240 params->setString("text", stringForText(text, byteLength, paint)); | |
241 params->setNumber("x", x); | |
242 params->setNumber("y", y); | |
243 params->setObject("paint", objectForSkPaint(paint)); | |
244 this->SkCanvas::onDrawText(text, byteLength, x, y, paint); | |
245 } | |
246 | |
247 void LoggingCanvas::onDrawPosText(const void* text, size_t byteLength, const SkP
oint pos[], const SkPaint& paint) | |
248 { | |
249 AutoLogger logger(this); | |
250 RefPtr<JSONObject> params = logger.logItemWithParams("drawPosText"); | |
251 params->setString("text", stringForText(text, byteLength, paint)); | |
252 size_t pointsCount = paint.countText(text, byteLength); | |
253 params->setArray("pos", arrayForSkPoints(pointsCount, pos)); | |
254 params->setObject("paint", objectForSkPaint(paint)); | |
255 this->SkCanvas::onDrawPosText(text, byteLength, pos, paint); | |
256 } | |
257 | |
258 void LoggingCanvas::onDrawPosTextH(const void* text, size_t byteLength, const Sk
Scalar xpos[], SkScalar constY, const SkPaint& paint) | |
259 { | |
260 AutoLogger logger(this); | |
261 RefPtr<JSONObject> params = logger.logItemWithParams("drawPosTextH"); | |
262 params->setString("text", stringForText(text, byteLength, paint)); | |
263 size_t pointsCount = paint.countText(text, byteLength); | |
264 params->setArray("xpos", arrayForSkScalars(pointsCount, xpos)); | |
265 params->setNumber("constY", constY); | |
266 params->setObject("paint", objectForSkPaint(paint)); | |
267 this->SkCanvas::onDrawPosTextH(text, byteLength, xpos, constY, paint); | |
268 } | |
269 | |
270 void LoggingCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const
SkPath& path, const SkMatrix* matrix, const SkPaint& paint) | |
271 { | |
272 AutoLogger logger(this); | |
273 RefPtr<JSONObject> params = logger.logItemWithParams("drawTextOnPath"); | |
274 params->setString("text", stringForText(text, byteLength, paint)); | |
275 params->setObject("path", objectForSkPath(path)); | |
276 params->setArray("matrix", arrayForSkMatrix(*matrix)); | |
277 params->setObject("paint", objectForSkPaint(paint)); | |
278 this->SkCanvas::onDrawTextOnPath(text, byteLength, path, matrix, paint); | |
279 } | |
280 | |
281 void LoggingCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyl
e style) | |
282 { | |
283 AutoLogger logger(this); | |
284 RefPtr<JSONObject> params = logger.logItemWithParams("clipRect"); | |
285 params->setObject("rect", objectForSkRect(rect)); | |
286 params->setString("SkRegion::Op", regionOpName(op)); | |
287 params->setBoolean("softClipEdgeStyle", kSoft_ClipEdgeStyle == style); | |
288 this->SkCanvas::onClipRect(rect, op, style); | |
289 } | |
290 | |
291 void LoggingCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeS
tyle style) | |
292 { | |
293 AutoLogger logger(this); | |
294 RefPtr<JSONObject> params = logger.logItemWithParams("clipRRect"); | |
295 params->setObject("rrect", objectForSkRRect(rrect)); | |
296 params->setString("SkRegion::Op", regionOpName(op)); | |
297 params->setBoolean("softClipEdgeStyle", kSoft_ClipEdgeStyle == style); | |
298 this->SkCanvas::onClipRRect(rrect, op, style); | |
299 } | |
300 | |
301 void LoggingCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyl
e style) | |
302 { | |
303 AutoLogger logger(this); | |
304 RefPtr<JSONObject> params = logger.logItemWithParams("clipPath"); | |
305 params->setObject("path", objectForSkPath(path)); | |
306 params->setString("SkRegion::Op", regionOpName(op)); | |
307 params->setBoolean("softClipEdgeStyle", kSoft_ClipEdgeStyle == style); | |
308 this->SkCanvas::onClipPath(path, op, style); | |
309 } | |
310 | |
311 void LoggingCanvas::onClipRegion(const SkRegion& region, SkRegion::Op op) | |
312 { | |
313 AutoLogger logger(this); | |
314 RefPtr<JSONObject> params = logger.logItemWithParams("clipRegion"); | |
315 params->setString("op", regionOpName(op)); | |
316 this->SkCanvas::onClipRegion(region, op); | |
317 } | |
318 | |
319 void LoggingCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matr
ix, const SkPaint* paint) | |
320 { | |
321 AutoLogger logger(this); | |
322 logger.logItemWithParams("drawPicture")->setObject("picture", objectForSkPic
ture(*picture)); | |
323 this->SkCanvas::onDrawPicture(picture, matrix, paint); | |
324 } | |
325 | |
326 void LoggingCanvas::didSetMatrix(const SkMatrix& matrix) | |
327 { | |
328 AutoLogger logger(this); | |
329 RefPtr<JSONObject> params = logger.logItemWithParams("setMatrix"); | |
330 params->setArray("matrix", arrayForSkMatrix(matrix)); | |
331 this->SkCanvas::didSetMatrix(matrix); | |
332 } | |
333 | |
334 void LoggingCanvas::didConcat(const SkMatrix& matrix) | |
335 { | |
336 AutoLogger logger(this); | |
337 RefPtr<JSONObject> params; | |
338 | |
339 switch (matrix.getType()) { | |
340 case SkMatrix::kTranslate_Mask: | |
341 params = logger.logItemWithParams("translate"); | |
342 params->setNumber("dx", matrix.getTranslateX()); | |
343 params->setNumber("dy", matrix.getTranslateY()); | |
344 break; | |
345 | |
346 case SkMatrix::kScale_Mask: | |
347 params = logger.logItemWithParams("scale"); | |
348 params->setNumber("scaleX", matrix.getScaleX()); | |
349 params->setNumber("scaleY", matrix.getScaleY()); | |
350 break; | |
351 | |
352 default: | |
353 params = logger.logItemWithParams("concat"); | |
354 params->setArray("matrix", arrayForSkMatrix(matrix)); | |
355 } | |
356 this->SkCanvas::didConcat(matrix); | |
357 } | |
358 | |
359 void LoggingCanvas::willSave() | |
360 { | |
361 AutoLogger logger(this); | |
362 RefPtr<JSONObject> params = logger.logItem("save"); | |
363 this->SkCanvas::willSave(); | |
364 } | |
365 | |
366 SkCanvas::SaveLayerStrategy LoggingCanvas::willSaveLayer(const SkRect* bounds, c
onst SkPaint* paint, SaveFlags flags) | |
367 { | |
368 AutoLogger logger(this); | |
369 RefPtr<JSONObject> params = logger.logItemWithParams("saveLayer"); | |
370 if (bounds) | |
371 params->setObject("bounds", objectForSkRect(*bounds)); | |
372 params->setObject("paint", objectForSkPaint(*paint)); | |
373 params->setString("saveFlags", saveFlagsToString(flags)); | |
374 return this->SkCanvas::willSaveLayer(bounds, paint, flags); | |
375 } | |
376 | |
377 void LoggingCanvas::willRestore() | |
378 { | |
379 AutoLogger logger(this); | |
380 logger.logItem("restore"); | |
381 this->SkCanvas::willRestore(); | |
382 } | |
383 | |
384 PassRefPtr<JSONArray> LoggingCanvas::log() | |
385 { | |
386 return m_log; | |
387 } | |
388 | |
389 PassRefPtr<JSONObject> LoggingCanvas::objectForSkRect(const SkRect& rect) | |
390 { | |
391 RefPtr<JSONObject> rectItem = JSONObject::create(); | |
392 rectItem->setNumber("left", rect.left()); | |
393 rectItem->setNumber("top", rect.top()); | |
394 rectItem->setNumber("right", rect.right()); | |
395 rectItem->setNumber("bottom", rect.bottom()); | |
396 return rectItem.release(); | |
397 } | |
398 | |
399 PassRefPtr<JSONObject> LoggingCanvas::objectForSkIRect(const SkIRect& rect) | |
400 { | |
401 RefPtr<JSONObject> rectItem = JSONObject::create(); | |
402 rectItem->setNumber("left", rect.left()); | |
403 rectItem->setNumber("top", rect.top()); | |
404 rectItem->setNumber("right", rect.right()); | |
405 rectItem->setNumber("bottom", rect.bottom()); | |
406 return rectItem.release(); | |
407 } | |
408 | |
409 String LoggingCanvas::pointModeName(PointMode mode) | |
410 { | |
411 switch (mode) { | |
412 case SkCanvas::kPoints_PointMode: return "Points"; | |
413 case SkCanvas::kLines_PointMode: return "Lines"; | |
414 case SkCanvas::kPolygon_PointMode: return "Polygon"; | |
415 default: | |
416 ASSERT_NOT_REACHED(); | |
417 return "?"; | |
418 }; | |
419 } | |
420 | |
421 PassRefPtr<JSONObject> LoggingCanvas::objectForSkPoint(const SkPoint& point) | |
422 { | |
423 RefPtr<JSONObject> pointItem = JSONObject::create(); | |
424 pointItem->setNumber("x", point.x()); | |
425 pointItem->setNumber("y", point.y()); | |
426 return pointItem.release(); | |
427 } | |
428 | |
429 PassRefPtr<JSONArray> LoggingCanvas::arrayForSkPoints(size_t count, const SkPoin
t points[]) | |
430 { | |
431 RefPtr<JSONArray> pointsArrayItem = JSONArray::create(); | |
432 for (size_t i = 0; i < count; ++i) | |
433 pointsArrayItem->pushObject(objectForSkPoint(points[i])); | |
434 return pointsArrayItem.release(); | |
435 } | |
436 | |
437 PassRefPtr<JSONObject> LoggingCanvas::objectForSkPicture(const SkPicture& pictur
e) | |
438 { | |
439 const SkIRect bounds = picture.cullRect().roundOut(); | |
440 RefPtr<JSONObject> pictureItem = JSONObject::create(); | |
441 pictureItem->setNumber("width", bounds.width()); | |
442 pictureItem->setNumber("height", bounds.height()); | |
443 return pictureItem.release(); | |
444 } | |
445 | |
446 PassRefPtr<JSONObject> LoggingCanvas::objectForRadius(const SkRRect& rrect, SkRR
ect::Corner corner) | |
447 { | |
448 RefPtr<JSONObject> radiusItem = JSONObject::create(); | |
449 SkVector radius = rrect.radii(corner); | |
450 radiusItem->setNumber("xRadius", radius.x()); | |
451 radiusItem->setNumber("yRadius", radius.y()); | |
452 return radiusItem.release(); | |
453 } | |
454 | |
455 String LoggingCanvas::rrectTypeName(SkRRect::Type type) | |
456 { | |
457 switch (type) { | |
458 case SkRRect::kEmpty_Type: return "Empty"; | |
459 case SkRRect::kRect_Type: return "Rect"; | |
460 case SkRRect::kOval_Type: return "Oval"; | |
461 case SkRRect::kSimple_Type: return "Simple"; | |
462 case SkRRect::kNinePatch_Type: return "Nine-patch"; | |
463 case SkRRect::kComplex_Type: return "Complex"; | |
464 default: | |
465 ASSERT_NOT_REACHED(); | |
466 return "?"; | |
467 }; | |
468 } | |
469 | |
470 String LoggingCanvas::radiusName(SkRRect::Corner corner) | |
471 { | |
472 switch (corner) { | |
473 case SkRRect::kUpperLeft_Corner: return "upperLeftRadius"; | |
474 case SkRRect::kUpperRight_Corner: return "upperRightRadius"; | |
475 case SkRRect::kLowerRight_Corner: return "lowerRightRadius"; | |
476 case SkRRect::kLowerLeft_Corner: return "lowerLeftRadius"; | |
477 default: | |
478 ASSERT_NOT_REACHED(); | |
479 return "?"; | |
480 } | |
481 } | |
482 | |
483 PassRefPtr<JSONObject> LoggingCanvas::objectForSkRRect(const SkRRect& rrect) | |
484 { | |
485 RefPtr<JSONObject> rrectItem = JSONObject::create(); | |
486 rrectItem->setString("type", rrectTypeName(rrect.type())); | |
487 rrectItem->setNumber("left", rrect.rect().left()); | |
488 rrectItem->setNumber("top", rrect.rect().top()); | |
489 rrectItem->setNumber("right", rrect.rect().right()); | |
490 rrectItem->setNumber("bottom", rrect.rect().bottom()); | |
491 for (int i = 0; i < 4; ++i) | |
492 rrectItem->setObject(radiusName((SkRRect::Corner) i), objectForRadius(rr
ect, (SkRRect::Corner) i)); | |
493 return rrectItem.release(); | |
494 } | |
495 | |
496 String LoggingCanvas::fillTypeName(SkPath::FillType type) | |
497 { | |
498 switch (type) { | |
499 case SkPath::kWinding_FillType: return "Winding"; | |
500 case SkPath::kEvenOdd_FillType: return "EvenOdd"; | |
501 case SkPath::kInverseWinding_FillType: return "InverseWinding"; | |
502 case SkPath::kInverseEvenOdd_FillType: return "InverseEvenOdd"; | |
503 default: | |
504 ASSERT_NOT_REACHED(); | |
505 return "?"; | |
506 }; | |
507 } | |
508 | |
509 String LoggingCanvas::convexityName(SkPath::Convexity convexity) | |
510 { | |
511 switch (convexity) { | |
512 case SkPath::kUnknown_Convexity: return "Unknown"; | |
513 case SkPath::kConvex_Convexity: return "Convex"; | |
514 case SkPath::kConcave_Convexity: return "Concave"; | |
515 default: | |
516 ASSERT_NOT_REACHED(); | |
517 return "?"; | |
518 }; | |
519 } | |
520 | |
521 String LoggingCanvas::verbName(SkPath::Verb verb) | |
522 { | |
523 switch (verb) { | |
524 case SkPath::kMove_Verb: return "Move"; | |
525 case SkPath::kLine_Verb: return "Line"; | |
526 case SkPath::kQuad_Verb: return "Quad"; | |
527 case SkPath::kConic_Verb: return "Conic"; | |
528 case SkPath::kCubic_Verb: return "Cubic"; | |
529 case SkPath::kClose_Verb: return "Close"; | |
530 case SkPath::kDone_Verb: return "Done"; | |
531 default: | |
532 ASSERT_NOT_REACHED(); | |
533 return "?"; | |
534 }; | |
535 } | |
536 | |
537 LoggingCanvas::VerbParams LoggingCanvas::segmentParams(SkPath::Verb verb) | |
538 { | |
539 switch (verb) { | |
540 case SkPath::kMove_Verb: return VerbParams("Move", 1, 0); | |
541 case SkPath::kLine_Verb: return VerbParams("Line", 1, 1); | |
542 case SkPath::kQuad_Verb: return VerbParams("Quad", 2, 1); | |
543 case SkPath::kConic_Verb: return VerbParams("Conic", 2, 1); | |
544 case SkPath::kCubic_Verb: return VerbParams("Cubic", 3, 1); | |
545 case SkPath::kClose_Verb: return VerbParams("Close", 0, 0); | |
546 case SkPath::kDone_Verb: return VerbParams("Done", 0, 0); | |
547 default: | |
548 ASSERT_NOT_REACHED(); | |
549 return VerbParams("?", 0, 0); | |
550 }; | |
551 } | |
552 | |
553 PassRefPtr<JSONObject> LoggingCanvas::objectForSkPath(const SkPath& path) | |
554 { | |
555 RefPtr<JSONObject> pathItem = JSONObject::create(); | |
556 pathItem->setString("fillType", fillTypeName(path.getFillType())); | |
557 pathItem->setString("convexity", convexityName(path.getConvexity())); | |
558 pathItem->setBoolean("isRect", path.isRect(0)); | |
559 SkPath::Iter iter(path, false); | |
560 SkPoint points[4]; | |
561 RefPtr<JSONArray> pathPointsArray = JSONArray::create(); | |
562 for (SkPath::Verb verb = iter.next(points, false); verb != SkPath::kDone_Ver
b; verb = iter.next(points, false)) { | |
563 VerbParams verbParams = segmentParams(verb); | |
564 RefPtr<JSONObject> pathPointItem = JSONObject::create(); | |
565 pathPointItem->setString("verb", verbParams.name); | |
566 ASSERT(verbParams.pointCount + verbParams.pointOffset <= WTF_ARRAY_LENGT
H(points)); | |
567 pathPointItem->setArray("points", arrayForSkPoints(verbParams.pointCount
, points + verbParams.pointOffset)); | |
568 if (SkPath::kConic_Verb == verb) | |
569 pathPointItem->setNumber("conicWeight", iter.conicWeight()); | |
570 pathPointsArray->pushObject(pathPointItem); | |
571 } | |
572 pathItem->setArray("pathPoints", pathPointsArray); | |
573 pathItem->setObject("bounds", objectForSkRect(path.getBounds())); | |
574 return pathItem.release(); | |
575 } | |
576 | |
577 String LoggingCanvas::colorTypeName(SkColorType colorType) | |
578 { | |
579 switch (colorType) { | |
580 case kUnknown_SkColorType: return "None"; | |
581 case kAlpha_8_SkColorType: return "A8"; | |
582 case kIndex_8_SkColorType: return "Index8"; | |
583 case kRGB_565_SkColorType: return "RGB565"; | |
584 case kARGB_4444_SkColorType: return "ARGB4444"; | |
585 case kN32_SkColorType: return "ARGB8888"; | |
586 default: | |
587 ASSERT_NOT_REACHED(); | |
588 return "?"; | |
589 }; | |
590 } | |
591 | |
592 PassRefPtr<JSONObject> LoggingCanvas::objectForBitmapData(const SkBitmap& bitmap
) | |
593 { | |
594 RefPtr<JSONObject> dataItem = JSONObject::create(); | |
595 Vector<unsigned char> output; | |
596 PNGImageEncoder::encode(bitmap, &output); | |
597 dataItem->setString("base64", WTF::base64Encode(reinterpret_cast<char*>(outp
ut.data()), output.size())); | |
598 dataItem->setString("mimeType", "image/png"); | |
599 return dataItem.release(); | |
600 } | |
601 | |
602 PassRefPtr<JSONObject> LoggingCanvas::objectForSkBitmap(const SkBitmap& bitmap) | |
603 { | |
604 RefPtr<JSONObject> bitmapItem = JSONObject::create(); | |
605 bitmapItem->setNumber("width", bitmap.width()); | |
606 bitmapItem->setNumber("height", bitmap.height()); | |
607 bitmapItem->setString("config", colorTypeName(bitmap.colorType())); | |
608 bitmapItem->setBoolean("opaque", bitmap.isOpaque()); | |
609 bitmapItem->setBoolean("immutable", bitmap.isImmutable()); | |
610 bitmapItem->setBoolean("volatile", bitmap.isVolatile()); | |
611 bitmapItem->setNumber("genID", bitmap.getGenerationID()); | |
612 bitmapItem->setObject("data", objectForBitmapData(bitmap)); | |
613 return bitmapItem.release(); | |
614 } | |
615 | |
616 PassRefPtr<JSONObject> LoggingCanvas::objectForSkShader(const SkShader& shader) | |
617 { | |
618 RefPtr<JSONObject> shaderItem = JSONObject::create(); | |
619 const SkMatrix localMatrix = shader.getLocalMatrix(); | |
620 if (!localMatrix.isIdentity()) | |
621 shaderItem->setArray("localMatrix", arrayForSkMatrix(localMatrix)); | |
622 return shaderItem.release(); | |
623 } | |
624 | |
625 String LoggingCanvas::stringForSkColor(const SkColor& color) | |
626 { | |
627 String colorString = "#"; | |
628 appendUnsignedAsHex(color, colorString); | |
629 return colorString; | |
630 } | |
631 | |
632 void LoggingCanvas::appendFlagToString(String* flagsString, bool isSet, const St
ring& name) | |
633 { | |
634 if (!isSet) | |
635 return; | |
636 if (flagsString->length()) | |
637 flagsString->append("|"); | |
638 flagsString->append(name); | |
639 } | |
640 | |
641 String LoggingCanvas::stringForSkPaintFlags(const SkPaint& paint) | |
642 { | |
643 if (!paint.getFlags()) | |
644 return "none"; | |
645 String flagsString = ""; | |
646 appendFlagToString(&flagsString, paint.isAntiAlias(), "AntiAlias"); | |
647 appendFlagToString(&flagsString, paint.isDither(), "Dither"); | |
648 appendFlagToString(&flagsString, paint.isUnderlineText(), "UnderlinText"); | |
649 appendFlagToString(&flagsString, paint.isStrikeThruText(), "StrikeThruText")
; | |
650 appendFlagToString(&flagsString, paint.isFakeBoldText(), "FakeBoldText"); | |
651 appendFlagToString(&flagsString, paint.isLinearText(), "LinearText"); | |
652 appendFlagToString(&flagsString, paint.isSubpixelText(), "SubpixelText"); | |
653 appendFlagToString(&flagsString, paint.isDevKernText(), "DevKernText"); | |
654 appendFlagToString(&flagsString, paint.isLCDRenderText(), "LCDRenderText"); | |
655 appendFlagToString(&flagsString, paint.isEmbeddedBitmapText(), "EmbeddedBitm
apText"); | |
656 appendFlagToString(&flagsString, paint.isAutohinted(), "Autohinted"); | |
657 appendFlagToString(&flagsString, paint.isVerticalText(), "VerticalText"); | |
658 appendFlagToString(&flagsString, paint.getFlags() & SkPaint::kGenA8FromLCD_F
lag, "GenA8FromLCD"); | |
659 return flagsString; | |
660 } | |
661 | |
662 String LoggingCanvas::filterLevelName(SkPaint::FilterLevel filterLevel) | |
663 { | |
664 switch (filterLevel) { | |
665 case SkPaint::kNone_FilterLevel: return "None"; | |
666 case SkPaint::kLow_FilterLevel: return "Low"; | |
667 case SkPaint::kMedium_FilterLevel: return "Medium"; | |
668 case SkPaint::kHigh_FilterLevel: return "High"; | |
669 default: | |
670 ASSERT_NOT_REACHED(); | |
671 return "?"; | |
672 }; | |
673 } | |
674 | |
675 String LoggingCanvas::textAlignName(SkPaint::Align align) | |
676 { | |
677 switch (align) { | |
678 case SkPaint::kLeft_Align: return "Left"; | |
679 case SkPaint::kCenter_Align: return "Center"; | |
680 case SkPaint::kRight_Align: return "Right"; | |
681 default: | |
682 ASSERT_NOT_REACHED(); | |
683 return "?"; | |
684 }; | |
685 } | |
686 | |
687 String LoggingCanvas::strokeCapName(SkPaint::Cap cap) | |
688 { | |
689 switch (cap) { | |
690 case SkPaint::kButt_Cap: return "Butt"; | |
691 case SkPaint::kRound_Cap: return "Round"; | |
692 case SkPaint::kSquare_Cap: return "Square"; | |
693 default: | |
694 ASSERT_NOT_REACHED(); | |
695 return "?"; | |
696 }; | |
697 } | |
698 | |
699 String LoggingCanvas::strokeJoinName(SkPaint::Join join) | |
700 { | |
701 switch (join) { | |
702 case SkPaint::kMiter_Join: return "Miter"; | |
703 case SkPaint::kRound_Join: return "Round"; | |
704 case SkPaint::kBevel_Join: return "Bevel"; | |
705 default: | |
706 ASSERT_NOT_REACHED(); | |
707 return "?"; | |
708 }; | |
709 } | |
710 | |
711 String LoggingCanvas::styleName(SkPaint::Style style) | |
712 { | |
713 switch (style) { | |
714 case SkPaint::kFill_Style: return "Fill"; | |
715 case SkPaint::kStroke_Style: return "Stroke"; | |
716 case SkPaint::kStrokeAndFill_Style: return "StrokeAndFill"; | |
717 default: | |
718 ASSERT_NOT_REACHED(); | |
719 return "?"; | |
720 }; | |
721 } | |
722 | |
723 String LoggingCanvas::textEncodingName(SkPaint::TextEncoding encoding) | |
724 { | |
725 switch (encoding) { | |
726 case SkPaint::kUTF8_TextEncoding: return "UTF-8"; | |
727 case SkPaint::kUTF16_TextEncoding: return "UTF-16"; | |
728 case SkPaint::kUTF32_TextEncoding: return "UTF-32"; | |
729 case SkPaint::kGlyphID_TextEncoding: return "GlyphID"; | |
730 default: | |
731 ASSERT_NOT_REACHED(); | |
732 return "?"; | |
733 }; | |
734 } | |
735 | |
736 String LoggingCanvas::hintingName(SkPaint::Hinting hinting) | |
737 { | |
738 switch (hinting) { | |
739 case SkPaint::kNo_Hinting: return "None"; | |
740 case SkPaint::kSlight_Hinting: return "Slight"; | |
741 case SkPaint::kNormal_Hinting: return "Normal"; | |
742 case SkPaint::kFull_Hinting: return "Full"; | |
743 default: | |
744 ASSERT_NOT_REACHED(); | |
745 return "?"; | |
746 }; | |
747 } | |
748 | |
749 PassRefPtr<JSONObject> LoggingCanvas::objectForSkPaint(const SkPaint& paint) | |
750 { | |
751 RefPtr<JSONObject> paintItem = JSONObject::create(); | |
752 paintItem->setNumber("textSize", paint.getTextSize()); | |
753 paintItem->setNumber("textScaleX", paint.getTextScaleX()); | |
754 paintItem->setNumber("textSkewX", paint.getTextSkewX()); | |
755 if (SkShader* shader = paint.getShader()) | |
756 paintItem->setObject("shader", objectForSkShader(*shader)); | |
757 paintItem->setString("color", stringForSkColor(paint.getColor())); | |
758 paintItem->setNumber("strokeWidth", paint.getStrokeWidth()); | |
759 paintItem->setNumber("strokeMiter", paint.getStrokeMiter()); | |
760 paintItem->setString("flags", stringForSkPaintFlags(paint)); | |
761 paintItem->setString("filterLevel", filterLevelName(paint.getFilterLevel()))
; | |
762 paintItem->setString("textAlign", textAlignName(paint.getTextAlign())); | |
763 paintItem->setString("strokeCap", strokeCapName(paint.getStrokeCap())); | |
764 paintItem->setString("strokeJoin", strokeJoinName(paint.getStrokeJoin())); | |
765 paintItem->setString("styleName", styleName(paint.getStyle())); | |
766 paintItem->setString("textEncoding", textEncodingName(paint.getTextEncoding(
))); | |
767 paintItem->setString("hinting", hintingName(paint.getHinting())); | |
768 return paintItem.release(); | |
769 } | |
770 | |
771 PassRefPtr<JSONArray> LoggingCanvas::arrayForSkMatrix(const SkMatrix& matrix) | |
772 { | |
773 RefPtr<JSONArray> matrixArray = JSONArray::create(); | |
774 for (int i = 0; i < 9; ++i) | |
775 matrixArray->pushNumber(matrix[i]); | |
776 return matrixArray.release(); | |
777 } | |
778 | |
779 PassRefPtr<JSONArray> LoggingCanvas::arrayForSkScalars(size_t n, const SkScalar
scalars[]) | |
780 { | |
781 RefPtr<JSONArray> scalarsArray = JSONArray::create(); | |
782 for (size_t i = 0; i < n; ++i) | |
783 scalarsArray->pushNumber(scalars[i]); | |
784 return scalarsArray.release(); | |
785 } | |
786 | |
787 String LoggingCanvas::regionOpName(SkRegion::Op op) | |
788 { | |
789 switch (op) { | |
790 case SkRegion::kDifference_Op: return "kDifference_Op"; | |
791 case SkRegion::kIntersect_Op: return "kIntersect_Op"; | |
792 case SkRegion::kUnion_Op: return "kUnion_Op"; | |
793 case SkRegion::kXOR_Op: return "kXOR_Op"; | |
794 case SkRegion::kReverseDifference_Op: return "kReverseDifference_Op"; | |
795 case SkRegion::kReplace_Op: return "kReplace_Op"; | |
796 default: return "Unknown type"; | |
797 }; | |
798 } | |
799 | |
800 String LoggingCanvas::saveFlagsToString(SkCanvas::SaveFlags flags) | |
801 { | |
802 String flagsString = ""; | |
803 if (flags & SkCanvas::kHasAlphaLayer_SaveFlag) | |
804 flagsString.append("kHasAlphaLayer_SaveFlag "); | |
805 if (flags & SkCanvas::kFullColorLayer_SaveFlag) | |
806 flagsString.append("kFullColorLayer_SaveFlag "); | |
807 if (flags & SkCanvas::kClipToLayer_SaveFlag) | |
808 flagsString.append("kClipToLayer_SaveFlag "); | |
809 return flagsString; | |
810 } | |
811 | |
812 String LoggingCanvas::textEncodingCanonicalName(SkPaint::TextEncoding encoding) | |
813 { | |
814 String name = textEncodingName(encoding); | |
815 if (encoding == SkPaint::kUTF16_TextEncoding || encoding == SkPaint::kUTF32_
TextEncoding) | |
816 name.append("LE"); | |
817 return name; | |
818 } | |
819 | |
820 String LoggingCanvas::stringForUTFText(const void* text, size_t length, SkPaint:
:TextEncoding encoding) | |
821 { | |
822 return WTF::TextEncoding(textEncodingCanonicalName(encoding)).decode((const
char*)text, length); | |
823 } | |
824 | |
825 String LoggingCanvas::stringForText(const void* text, size_t byteLength, const S
kPaint& paint) | |
826 { | |
827 SkPaint::TextEncoding encoding = paint.getTextEncoding(); | |
828 switch (encoding) { | |
829 case SkPaint::kUTF8_TextEncoding: | |
830 case SkPaint::kUTF16_TextEncoding: | |
831 case SkPaint::kUTF32_TextEncoding: | |
832 return stringForUTFText(text, byteLength, encoding); | |
833 case SkPaint::kGlyphID_TextEncoding: { | |
834 WTF::Vector<SkUnichar> dataVector(byteLength / 2); | |
835 SkUnichar* textData = dataVector.data(); | |
836 paint.glyphsToUnichars(static_cast<const uint16_t*>(text), byteLength /
2, textData); | |
837 return WTF::UTF32LittleEndianEncoding().decode(reinterpret_cast<const ch
ar*>(textData), byteLength * 2); | |
838 } | |
839 default: | |
840 ASSERT_NOT_REACHED(); | |
841 return "?"; | |
842 } | |
843 } | |
844 | |
845 } // namespace blink | |
OLD | NEW |