blob: 225435a4bc7fad710b4d2e50b2ae7e2cf7a97611 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 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 */
yangsu@google.coma8a42e22011-06-16 20:49:55 +00008#include "SkDebugDumper.h"
9#include "SkString.h"
10#include "SkPaint.h"
11#include "SkShader.h"
12#include "SkPathEffect.h"
13#include "SkXfermode.h"
14#include "SkColorFilter.h"
15#include "SkPathEffect.h"
16#include "SkMaskFilter.h"
17#include "SkGradientShader.h"
18#include "SkDebuggerViews.h"
19
20bool gNeverSetToTrueJustNeedToFoolLinker;
21static void init_effects() {
22 if (gNeverSetToTrueJustNeedToFoolLinker) {
23 SkPoint p = SkPoint::Make(0,0);
24 SkPoint q = SkPoint::Make(100,100);
25 SkPoint pts[] = {p, q};
26 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN };
27 SkScalar pos[] = { 0, 1.0};
28 SkGradientShader::CreateLinear(pts, colors, pos, 2,
29 SkShader::kMirror_TileMode);
30 }
31}
32
33SkDebugDumper::SkDebugDumper(SkEventSinkID cID, SkEventSinkID clID,
34 SkEventSinkID ipID) {
35 fContentID = cID;
36 fCommandListID = clID;
37 fInfoPanelID = ipID;
38 fInit = false;
39 fDisabled = false;
40 fCount = 0;
41 init_effects();
42}
43
44static void appendPtr(SkString* str, const void* ptr, const char name[]) {
45 if (ptr) {
46 str->appendf("$s: %p\t", name, ptr);
47 }
48}
49
50static void appendFlattenable(SkString* str, const SkFlattenable* ptr,
51 const char name[]) {
52 if (ptr) {
53 SkString info;
54 if (ptr->toDumpString(&info)) {
55 str->appendf("%s", info.c_str());
56 } else {
57 str->appendf("%s: %p", name, ptr);
58 }
59 }
60}
61
62static SkString dumpMatrix(SkDumpCanvasM* canvas) {
63 SkString str;
64 SkMatrix m = canvas->getTotalMatrix();
65 str.appendf("Matrix:");
66 str.appendf("Translate (%0.4g, %0.4g) ",
67 SkScalarToFloat(m.get(SkMatrix::kMTransX)),
68 SkScalarToFloat(m.get(SkMatrix::kMTransY)));
69 str.appendf("Scale (%0.4g, %0.4g) ",
70 SkScalarToFloat(m.get(SkMatrix::kMScaleX)),
71 SkScalarToFloat(m.get(SkMatrix::kMScaleY)));
72 str.appendf("Skew (%0.4g, %0.4g) ",
73 SkScalarToFloat(m.get(SkMatrix::kMSkewX)),
74 SkScalarToFloat(m.get(SkMatrix::kMSkewY)));
75 str.appendf("Perspective (%0.4g, %0.4g, %0.4g) ",
76 SkScalarToFloat(m.get(SkMatrix::kMPersp0)),
77 SkScalarToFloat(m.get(SkMatrix::kMPersp1)),
78 SkScalarToFloat(m.get(SkMatrix::kMPersp2)));
79 return str;
80}
81
82static SkString dumpClip(SkDumpCanvasM* canvas) {
83 SkString str;
84 SkPath p;
85 int maxPts = 50;
86 if (canvas->getTotalClip().getBoundaryPath(&p)) {
87 SkPoint pts[maxPts];
88 int numPts = p.getPoints(pts, maxPts);
89
90 str.appendf("Clip: [ ");
91 for (int i = 0; i < numPts; ++i) {
92 str.appendf("(%0.4g, %0.4g)", pts[i].x(), pts[i].y());
93 if (i < numPts-1)
94 str.appendf(" , ");
95 }
96 str.appendf(" ]");
97 }
98 return str;
99}
100
101static const char* gPaintFlags[] = {
102 "AntiAliasing",
103 "Bitmap Filtering",
104 "Dithering",
105 "Underline Text",
106 "Strike-Through Text",
107 "Fake Bold Text",
108 "Linear Text",
109 "Subpixel Positioned Text",
110 "Device Kerning Text",
111 "LCD/Subpixel Glyph Rendering",
112 "Embedded Bitmap Text",
113 "Freetype Autohinting",
114
115 "ALL"
116};
117
118
119static SkString dumpPaint(SkDumpCanvasM* canvas, const SkPaint* p,
120 SkDumpCanvasM::Verb verb) {
121 SkString str;
122 str.appendf("Color: #%08X\n", p->getColor());
123 str.appendf("Flags: %s\n", gPaintFlags[p->getFlags()]);
124 appendFlattenable(&str, p->getShader(), "shader");
125 appendFlattenable(&str, p->getXfermode(), "xfermode");
126 appendFlattenable(&str, p->getPathEffect(), "pathEffect");
127 appendFlattenable(&str, p->getMaskFilter(), "maskFilter");
128 appendFlattenable(&str, p->getPathEffect(), "pathEffect");
129 appendFlattenable(&str, p->getColorFilter(), "filter");
130
131 if (SkDumpCanvasM::kDrawText_Verb == verb) {
132 str.appendf("Text Size:%0.4g\n", SkScalarToFloat(p->getTextSize()));
133 appendPtr(&str, p->getTypeface(), "typeface");
134 }
135
136 return str;
137}
138
139void SkDebugDumper::dump(SkDumpCanvasM* canvas, SkDumpCanvasM::Verb verb,
140 const char str[], const SkPaint* p) {
141 if (!fDisabled) {
142 SkString msg, tab;
143
144 const int level = canvas->getNestLevel() + canvas->getSaveCount() - 1;
145 SkASSERT(level >= 0);
146 for (int i = 0; i < level; i++) {
147 tab.append("| ");
148 }
149
150 msg.appendf("%03d: %s%s\n", fCount, tab.c_str(), str);
151 ++fCount;
152 if (!fInit) {
153 SkEvent* cmd = new SkEvent(SkDebugger_CommandType);
154 cmd->setString(SkDebugger_Atom, msg);
155 cmd->post(fCommandListID, 100);
156 }
157 else {
158 SkEvent* state = new SkEvent(SkDebugger_StateType);
159 state->setString(SkDebugger_Matrix, dumpMatrix(canvas));
160 state->setString(SkDebugger_Clip, dumpClip(canvas));
161 if (p) {
162 state->setString(SkDebugger_PaintInfo, dumpPaint(canvas, p, verb));
163 state->getMetaData().setPtr(SkDebugger_Paint, (void*)p, PaintProc);
164 }
165 state->post(fInfoPanelID);
166 }
167 }
168}