| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright 2016 Google Inc. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license that can be | |
| 5 * found in the LICENSE file. | |
| 6 */ | |
| 7 | |
| 8 #include "SkJSONRenderer.h" | |
| 9 #include "SkJSONCanvas.h" | |
| 10 #include "SkJSONCPP.h" | |
| 11 #include "SkPath.h" | |
| 12 | |
| 13 namespace SkJSONRenderer { | |
| 14 | |
| 15 class Renderer { | |
| 16 public: | |
| 17 void getPaint(Json::Value& command, SkPaint* paint); | |
| 18 | |
| 19 void getRect(Json::Value& command, const char* name, SkRect* rect); | |
| 20 | |
| 21 void getRRect(Json::Value& command, const char* name, SkRRect* rrect); | |
| 22 | |
| 23 void processCommand(Json::Value& command, SkCanvas* target); | |
| 24 | |
| 25 void processMatrix(Json::Value& command, SkCanvas* target); | |
| 26 | |
| 27 void processSave(Json::Value& command, SkCanvas* target); | |
| 28 | |
| 29 void processRestore(Json::Value& command, SkCanvas* target); | |
| 30 | |
| 31 void processPaint(Json::Value& command, SkCanvas* target); | |
| 32 | |
| 33 void processRect(Json::Value& command, SkCanvas* target); | |
| 34 | |
| 35 void processRRect(Json::Value& command, SkCanvas* target); | |
| 36 | |
| 37 void processOval(Json::Value& command, SkCanvas* target); | |
| 38 | |
| 39 void processPath(Json::Value& command, SkCanvas* target); | |
| 40 | |
| 41 void processText(Json::Value& command, SkCanvas* target); | |
| 42 | |
| 43 void processPoints(Json::Value& command, SkCanvas* target); | |
| 44 | |
| 45 void processClipRect(Json::Value& command, SkCanvas* target); | |
| 46 }; | |
| 47 | |
| 48 void Renderer::processCommand(Json::Value& command, SkCanvas* target) { | |
| 49 const char* name = command[SKJSONCANVAS_COMMAND].asCString(); | |
| 50 // TODO speed this up with a hash | |
| 51 if (!strcmp(name, SKJSONCANVAS_COMMAND_MATRIX)) { | |
| 52 this->processMatrix(command, target); | |
| 53 } | |
| 54 else if (!strcmp(name, SKJSONCANVAS_COMMAND_SAVE)) { | |
| 55 this->processSave(command, target); | |
| 56 } | |
| 57 else if (!strcmp(name, SKJSONCANVAS_COMMAND_RESTORE)) { | |
| 58 this->processRestore(command, target); | |
| 59 } | |
| 60 else if (!strcmp(name, SKJSONCANVAS_COMMAND_PAINT)) { | |
| 61 this->processPaint(command, target); | |
| 62 } | |
| 63 else if (!strcmp(name, SKJSONCANVAS_COMMAND_RECT)) { | |
| 64 this->processRect(command, target); | |
| 65 } | |
| 66 else if (!strcmp(name, SKJSONCANVAS_COMMAND_RRECT)) { | |
| 67 this->processRRect(command, target); | |
| 68 } | |
| 69 else if (!strcmp(name, SKJSONCANVAS_COMMAND_OVAL)) { | |
| 70 this->processOval(command, target); | |
| 71 } | |
| 72 else if (!strcmp(name, SKJSONCANVAS_COMMAND_PATH)) { | |
| 73 this->processPath(command, target); | |
| 74 } | |
| 75 else if (!strcmp(name, SKJSONCANVAS_COMMAND_TEXT)) { | |
| 76 this->processText(command, target); | |
| 77 } | |
| 78 else if (!strcmp(name, SKJSONCANVAS_COMMAND_POINTS)) { | |
| 79 this->processPoints(command, target); | |
| 80 } | |
| 81 else if (!strcmp(name, SKJSONCANVAS_COMMAND_CLIPRECT)) { | |
| 82 this->processClipRect(command, target); | |
| 83 } | |
| 84 else { | |
| 85 SkDebugf("unsupported JSON command: %s\n", name); | |
| 86 } | |
| 87 } | |
| 88 | |
| 89 void Renderer::getPaint(Json::Value& command, SkPaint* result) { | |
| 90 Json::Value jsonPaint = command[SKJSONCANVAS_ATTRIBUTE_PAINT]; | |
| 91 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_COLOR)) { | |
| 92 Json::Value color = jsonPaint[SKJSONCANVAS_ATTRIBUTE_COLOR]; | |
| 93 result->setColor(SkColorSetARGB(color[0].asInt(), color[1].asInt(), colo
r[2].asInt(), | |
| 94 color[3].asInt())); | |
| 95 } | |
| 96 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_STYLE)) { | |
| 97 const char* style = jsonPaint[SKJSONCANVAS_ATTRIBUTE_STYLE].asCString(); | |
| 98 if (!strcmp(style, SKJSONCANVAS_STYLE_FILL)) { | |
| 99 result->setStyle(SkPaint::kFill_Style); | |
| 100 } | |
| 101 else if (!strcmp(style, SKJSONCANVAS_STYLE_STROKE)) { | |
| 102 result->setStyle(SkPaint::kStroke_Style); | |
| 103 } | |
| 104 else if (!strcmp(style, SKJSONCANVAS_STYLE_STROKEANDFILL)) { | |
| 105 result->setStyle(SkPaint::kStrokeAndFill_Style); | |
| 106 } | |
| 107 } | |
| 108 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH)) { | |
| 109 float strokeWidth = jsonPaint[SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH].asFloa
t(); | |
| 110 result->setStrokeWidth(strokeWidth); | |
| 111 } | |
| 112 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_ANTIALIAS)) { | |
| 113 result->setAntiAlias(jsonPaint[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS].asBool(
)); | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 void Renderer::getRect(Json::Value& command, const char* name, SkRect* result) { | |
| 118 Json::Value rect = command[name]; | |
| 119 result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3]
.asFloat()); | |
| 120 } | |
| 121 | |
| 122 void Renderer::getRRect(Json::Value& command, const char* name, SkRRect* result)
{ | |
| 123 Json::Value rrect = command[name]; | |
| 124 SkVector radii[4] = { | |
| 125 { rrect[1][0].asFloat(), rrect[1][1].asFloat() }, | |
| 126 { rrect[2][0].asFloat(), rrect[2][1].asFloat() }, | |
| 127 { rrect[3][0].asFloat(), rrect[3][1].asFloat() }, | |
| 128 { rrect[4][0].asFloat(), rrect[4][1].asFloat() } | |
| 129 }; | |
| 130 result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asF
loat(), | |
| 131 rrect[0][2].asFloat(), rrect[0][3].asF
loat()), | |
| 132 radii); | |
| 133 } | |
| 134 | |
| 135 void Renderer::processMatrix(Json::Value& command, SkCanvas* target) { | |
| 136 Json::Value jsonMatrix = command[SKJSONCANVAS_ATTRIBUTE_MATRIX]; | |
| 137 SkMatrix matrix; | |
| 138 SkScalar values[] = { | |
| 139 jsonMatrix[0][0].asFloat(), jsonMatrix[0][1].asFloat(), jsonMatrix[0][2]
.asFloat(), | |
| 140 jsonMatrix[1][0].asFloat(), jsonMatrix[1][1].asFloat(), jsonMatrix[1][2]
.asFloat(), | |
| 141 jsonMatrix[2][0].asFloat(), jsonMatrix[2][1].asFloat(), jsonMatrix[2][2]
.asFloat() | |
| 142 }; | |
| 143 matrix.set9(values); | |
| 144 target->setMatrix(matrix); | |
| 145 } | |
| 146 | |
| 147 void Renderer::processSave(Json::Value& command, SkCanvas* target) { | |
| 148 target->save(); | |
| 149 } | |
| 150 | |
| 151 void Renderer::processRestore(Json::Value& command, SkCanvas* target) { | |
| 152 target->restore(); | |
| 153 } | |
| 154 | |
| 155 void Renderer::processPaint(Json::Value& command, SkCanvas* target) { | |
| 156 SkPaint paint; | |
| 157 this->getPaint(command, &paint); | |
| 158 target->drawPaint(paint); | |
| 159 } | |
| 160 | |
| 161 void Renderer::processRect(Json::Value& command, SkCanvas* target) { | |
| 162 SkRect rect; | |
| 163 this->getRect(command, SKJSONCANVAS_ATTRIBUTE_COORDS, &rect); | |
| 164 SkPaint paint; | |
| 165 this->getPaint(command, &paint); | |
| 166 target->drawRect(rect, paint); | |
| 167 } | |
| 168 | |
| 169 void Renderer::processRRect(Json::Value& command, SkCanvas* target) { | |
| 170 SkRRect rrect; | |
| 171 this->getRRect(command, SKJSONCANVAS_ATTRIBUTE_COORDS, &rrect); | |
| 172 SkPaint paint; | |
| 173 this->getPaint(command, &paint); | |
| 174 target->drawRRect(rrect, paint); | |
| 175 } | |
| 176 | |
| 177 void Renderer::processOval(Json::Value& command, SkCanvas* target) { | |
| 178 SkRect rect; | |
| 179 this->getRect(command, SKJSONCANVAS_ATTRIBUTE_COORDS, &rect); | |
| 180 SkPaint paint; | |
| 181 this->getPaint(command, &paint); | |
| 182 target->drawOval(rect, paint); | |
| 183 } | |
| 184 | |
| 185 void Renderer::processPath(Json::Value& command, SkCanvas* target) { | |
| 186 Json::Value jsonPath = command[SKJSONCANVAS_ATTRIBUTE_PATH]; | |
| 187 SkPath path; | |
| 188 for (Json::ArrayIndex i = 0; i < jsonPath.size(); i++) { | |
| 189 Json::Value verb = jsonPath[i]; | |
| 190 if (verb.isString()) { | |
| 191 SkASSERT(!strcmp(verb.asCString(), SKJSONCANVAS_VERB_CLOSE)); | |
| 192 path.close(); | |
| 193 } | |
| 194 else { | |
| 195 if (verb.isMember(SKJSONCANVAS_VERB_MOVE)) { | |
| 196 Json::Value move = verb[SKJSONCANVAS_VERB_MOVE]; | |
| 197 path.moveTo(move[0].asFloat(), move[1].asFloat()); | |
| 198 } | |
| 199 else if (verb.isMember(SKJSONCANVAS_VERB_LINE)) { | |
| 200 Json::Value line = verb[SKJSONCANVAS_VERB_LINE]; | |
| 201 path.lineTo(line[0].asFloat(), line[1].asFloat()); | |
| 202 } | |
| 203 else if (verb.isMember(SKJSONCANVAS_VERB_QUAD)) { | |
| 204 Json::Value quad = verb[SKJSONCANVAS_VERB_QUAD]; | |
| 205 path.quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(), | |
| 206 quad[1][0].asFloat(), quad[1][1].asFloat()); | |
| 207 } | |
| 208 else if (verb.isMember(SKJSONCANVAS_VERB_CUBIC)) { | |
| 209 Json::Value cubic = verb[SKJSONCANVAS_VERB_CUBIC]; | |
| 210 path.cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(), | |
| 211 cubic[1][0].asFloat(), cubic[1][1].asFloat(), | |
| 212 cubic[2][0].asFloat(), cubic[2][1].asFloat()); | |
| 213 } | |
| 214 else if (verb.isMember(SKJSONCANVAS_VERB_CONIC)) { | |
| 215 Json::Value conic = verb[SKJSONCANVAS_VERB_CONIC]; | |
| 216 path.conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(), | |
| 217 conic[1][0].asFloat(), conic[1][1].asFloat(), | |
| 218 conic[2].asFloat()); | |
| 219 } | |
| 220 else { | |
| 221 SkASSERT(false); | |
| 222 } | |
| 223 } | |
| 224 } | |
| 225 SkPaint paint; | |
| 226 this->getPaint(command, &paint); | |
| 227 target->drawPath(path, paint); | |
| 228 } | |
| 229 | |
| 230 void Renderer::processText(Json::Value& command, SkCanvas* target) { | |
| 231 const char* text = command[SKJSONCANVAS_ATTRIBUTE_TEXT].asCString(); | |
| 232 SkPaint paint; | |
| 233 this->getPaint(command, &paint); | |
| 234 Json::Value coords = command[SKJSONCANVAS_ATTRIBUTE_COORDS]; | |
| 235 target->drawText(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(
), paint); | |
| 236 } | |
| 237 | |
| 238 void Renderer::processPoints(Json::Value& command, SkCanvas* target) { | |
| 239 SkCanvas::PointMode mode; | |
| 240 const char* jsonMode = command[SKJSONCANVAS_ATTRIBUTE_MODE].asCString(); | |
| 241 if (!strcmp(jsonMode, SKJSONCANVAS_POINTMODE_POINTS)) { | |
| 242 mode = SkCanvas::kPoints_PointMode; | |
| 243 } | |
| 244 else if (!strcmp(jsonMode, SKJSONCANVAS_POINTMODE_LINES)) { | |
| 245 mode = SkCanvas::kLines_PointMode; | |
| 246 } | |
| 247 else if (!strcmp(jsonMode, SKJSONCANVAS_POINTMODE_POLYGON)) { | |
| 248 mode = SkCanvas::kPolygon_PointMode; | |
| 249 } | |
| 250 else { | |
| 251 SkASSERT(false); | |
| 252 return; | |
| 253 } | |
| 254 Json::Value jsonPoints = command[SKJSONCANVAS_ATTRIBUTE_POINTS]; | |
| 255 int count = (int) jsonPoints.size(); | |
| 256 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint)); | |
| 257 for (int i = 0; i < count; i++) { | |
| 258 points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].a
sFloat()); | |
| 259 } | |
| 260 SkPaint paint; | |
| 261 this->getPaint(command, &paint); | |
| 262 target->drawPoints(mode, count, points, paint); | |
| 263 free(points); | |
| 264 } | |
| 265 | |
| 266 void Renderer::processClipRect(Json::Value& command, SkCanvas* target) { | |
| 267 SkRect rect; | |
| 268 this->getRect(command, SKJSONCANVAS_ATTRIBUTE_COORDS, &rect); | |
| 269 target->clipRect(rect); | |
| 270 } | |
| 271 | |
| 272 void render(const char* json, SkCanvas* target) { | |
| 273 Renderer renderer; | |
| 274 Json::Reader reader; | |
| 275 Json::Value root; | |
| 276 if (reader.parse(std::string(json), root)) { | |
| 277 SkASSERT(root[SKJSONCANVAS_VERSION].asInt() == 1); | |
| 278 Json::Value commands = root[SKJSONCANVAS_COMMANDS]; | |
| 279 for (Json::ArrayIndex i = 0; i < commands.size(); i++) { | |
| 280 renderer.processCommand(commands[i], target); | |
| 281 } | |
| 282 } | |
| 283 else { | |
| 284 SkDebugf(json); | |
| 285 SkFAIL("json parse failure"); | |
| 286 } | |
| 287 } | |
| 288 | |
| 289 } // namespace | |
| OLD | NEW |