Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Unified Diff: tools/json/SkJSONRenderer.cpp

Issue 1662503003: support for more features when rendering to/from JSON (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/json/SkJSONCanvas.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/json/SkJSONRenderer.cpp
diff --git a/tools/json/SkJSONRenderer.cpp b/tools/json/SkJSONRenderer.cpp
index a830fe0fb5f84cb79cc91c975e8bca9e9b57d59b..734ce116b44f46a102be248f78642d503de7740b 100644
--- a/tools/json/SkJSONRenderer.cpp
+++ b/tools/json/SkJSONRenderer.cpp
@@ -12,6 +12,7 @@
#include "SkJSONCanvas.h"
#include "SkJSONCPP.h"
#include "SkPath.h"
+#include "SkValidatingReadBuffer.h"
namespace SkJSONRenderer {
@@ -35,6 +36,8 @@ public:
void processRestore(Json::Value& command, SkCanvas* target);
+ void processSaveLayer(Json::Value& command, SkCanvas* target);
+
void processPaint(Json::Value& command, SkCanvas* target);
void processRect(Json::Value& command, SkCanvas* target);
@@ -51,6 +54,14 @@ public:
void processPoints(Json::Value& command, SkCanvas* target);
+ void processImage(Json::Value& command, SkCanvas* target);
+
+ void processImageRect(Json::Value& command, SkCanvas* target);
+
+ void processBitmap(Json::Value& command, SkCanvas* target);
+
+ void processBitmapRect(Json::Value& command, SkCanvas* target);
+
void processClipRect(Json::Value& command, SkCanvas* target);
void processClipRRect(Json::Value& command, SkCanvas* target);
@@ -70,6 +81,9 @@ void Renderer::processCommand(Json::Value& command, SkCanvas* target) {
else if (!strcmp(name, SKJSONCANVAS_COMMAND_RESTORE)) {
this->processRestore(command, target);
}
+ else if (!strcmp(name, SKJSONCANVAS_COMMAND_SAVELAYER)) {
+ this->processSaveLayer(command, target);
+ }
else if (!strcmp(name, SKJSONCANVAS_COMMAND_PAINT)) {
this->processPaint(command, target);
}
@@ -94,6 +108,18 @@ void Renderer::processCommand(Json::Value& command, SkCanvas* target) {
else if (!strcmp(name, SKJSONCANVAS_COMMAND_POINTS)) {
this->processPoints(command, target);
}
+ else if (!strcmp(name, SKJSONCANVAS_COMMAND_IMAGE)) {
+ this->processImage(command, target);
+ }
+ else if (!strcmp(name, SKJSONCANVAS_COMMAND_IMAGERECT)) {
+ this->processImageRect(command, target);
+ }
+ else if (!strcmp(name, SKJSONCANVAS_COMMAND_BITMAP)) {
+ this->processBitmap(command, target);
+ }
+ else if (!strcmp(name, SKJSONCANVAS_COMMAND_BITMAPRECT)) {
+ this->processBitmapRect(command, target);
+ }
else if (!strcmp(name, SKJSONCANVAS_COMMAND_CLIPRECT)) {
this->processClipRect(command, target);
}
@@ -108,32 +134,171 @@ void Renderer::processCommand(Json::Value& command, SkCanvas* target) {
}
}
-void Renderer::getPaint(Json::Value& command, SkPaint* result) {
- Json::Value jsonPaint = command[SKJSONCANVAS_ATTRIBUTE_PAINT];
+static void apply_paint_color(Json::Value& jsonPaint, SkPaint* target) {
if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_COLOR)) {
Json::Value color = jsonPaint[SKJSONCANVAS_ATTRIBUTE_COLOR];
- result->setColor(SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(),
+ target->setColor(SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(),
color[3].asInt()));
}
+}
+
+// note that the caller is responsible for freeing the pointer
+static Json::ArrayIndex decode_data(Json::Value bytes, void** target) {
+ Json::ArrayIndex size = bytes.size();
+ *target = sk_malloc_throw(size);
+ for (Json::ArrayIndex i = 0; i < size; i++) {
+ ((uint8_t*) *target)[i] = bytes[i].asInt();
+ }
+ return size;
+}
+
+static SkFlattenable* load_flattenable(Json::Value jsonFlattenable) {
+ if (!jsonFlattenable.isMember(SKJSONCANVAS_ATTRIBUTE_NAME)) {
+ return nullptr;
+ }
+ const char* name = jsonFlattenable[SKJSONCANVAS_ATTRIBUTE_NAME].asCString();
+ SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
+ if (factory == nullptr) {
+ return nullptr;
+ }
+ void* data;
+ int size = decode_data(jsonFlattenable[SKJSONCANVAS_ATTRIBUTE_BYTES], &data);
+ SkValidatingReadBuffer buffer(data, size);
+ SkFlattenable* result = factory(buffer);
+ free(data);
+ if (!buffer.isValid()) {
+ return nullptr;
+ }
+ return result;
+}
+
+// caller is responsible for freeing return value
+static SkBitmap* load_bitmap(Json::Value jsonBitmap) {
+ if (!jsonBitmap.isMember(SKJSONCANVAS_ATTRIBUTE_BYTES)) {
+ return nullptr;
+ }
+ void* data;
+ int size = decode_data(jsonBitmap[SKJSONCANVAS_ATTRIBUTE_BYTES], &data);
+ SkMemoryStream stream(data, size);
+ SkImageDecoder* decoder = SkImageDecoder::Factory(&stream);
+ SkBitmap* bitmap = new SkBitmap();
+ SkImageDecoder::Result result = decoder->decode(&stream, bitmap,
+ SkImageDecoder::kDecodePixels_Mode);
+ free(decoder);
+ if (result != SkImageDecoder::kFailure) {
+ free(data);
+ return bitmap;
+ }
+ SkDebugf("image decode failed");
+ free(data);
+ return nullptr;
+}
+
+static SkImage* load_image(Json::Value jsonImage) {
+ SkBitmap* bitmap = load_bitmap(jsonImage);
+ if (bitmap == nullptr) {
+ return nullptr;
+ }
+ SkImage* result = SkImage::NewFromBitmap(*bitmap);
+ free(bitmap);
+ return result;
+}
+
+static void apply_paint_shader(Json::Value& jsonPaint, SkPaint* target) {
+ if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_SHADER)) {
+ Json::Value jsonShader = jsonPaint[SKJSONCANVAS_ATTRIBUTE_SHADER];
+ SkShader* shader = (SkShader*) load_flattenable(jsonShader);
+ if (shader != nullptr) {
+ target->setShader(shader);
+ shader->unref();
+ }
+ }
+}
+
+static void apply_paint_patheffect(Json::Value& jsonPaint, SkPaint* target) {
+ if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_PATHEFFECT)) {
+ Json::Value jsonPathEffect = jsonPaint[SKJSONCANVAS_ATTRIBUTE_PATHEFFECT];
+ SkPathEffect* pathEffect = (SkPathEffect*) load_flattenable(jsonPathEffect);
+ if (pathEffect != nullptr) {
+ target->setPathEffect(pathEffect);
+ pathEffect->unref();
+ }
+ }
+}
+
+static void apply_paint_maskfilter(Json::Value& jsonPaint, SkPaint* target) {
+ if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_MASKFILTER)) {
+ Json::Value jsonMaskFilter = jsonPaint[SKJSONCANVAS_ATTRIBUTE_MASKFILTER];
+ SkMaskFilter* maskFilter = (SkMaskFilter*) load_flattenable(jsonMaskFilter);
+ if (maskFilter != nullptr) {
+ target->setMaskFilter(maskFilter);
+ maskFilter->unref();
+ }
+ }
+}
+
+static void apply_paint_xfermode(Json::Value& jsonPaint, SkPaint* target) {
+ if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_XFERMODE)) {
+ Json::Value jsonXfermode = jsonPaint[SKJSONCANVAS_ATTRIBUTE_XFERMODE];
+ SkXfermode* xfermode = (SkXfermode*) load_flattenable(jsonXfermode);
+ if (xfermode != nullptr) {
+ target->setXfermode(xfermode);
+ xfermode->unref();
+ }
+ }
+}
+
+static void apply_paint_style(Json::Value& jsonPaint, SkPaint* target) {
if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_STYLE)) {
const char* style = jsonPaint[SKJSONCANVAS_ATTRIBUTE_STYLE].asCString();
if (!strcmp(style, SKJSONCANVAS_STYLE_FILL)) {
- result->setStyle(SkPaint::kFill_Style);
+ target->setStyle(SkPaint::kFill_Style);
}
else if (!strcmp(style, SKJSONCANVAS_STYLE_STROKE)) {
- result->setStyle(SkPaint::kStroke_Style);
+ target->setStyle(SkPaint::kStroke_Style);
}
else if (!strcmp(style, SKJSONCANVAS_STYLE_STROKEANDFILL)) {
- result->setStyle(SkPaint::kStrokeAndFill_Style);
+ target->setStyle(SkPaint::kStrokeAndFill_Style);
}
}
+}
+
+static void apply_paint_strokewidth(Json::Value& jsonPaint, SkPaint* target) {
if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH)) {
float strokeWidth = jsonPaint[SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH].asFloat();
- result->setStrokeWidth(strokeWidth);
+ target->setStrokeWidth(strokeWidth);
+ }
+}
+
+static void apply_paint_strokemiter(Json::Value& jsonPaint, SkPaint* target) {
+ if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_STROKEMITER)) {
+ float strokeMiter = jsonPaint[SKJSONCANVAS_ATTRIBUTE_STROKEMITER].asFloat();
+ target->setStrokeMiter(strokeMiter);
+ }
+}
+
+static void apply_paint_cap(Json::Value& jsonPaint, SkPaint* target) {
+ if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_CAP)) {
+ const char* cap = jsonPaint[SKJSONCANVAS_ATTRIBUTE_CAP].asCString();
+ if (!strcmp(cap, SKJSONCANVAS_CAP_BUTT)) {
+ target->setStrokeCap(SkPaint::kButt_Cap);
+ }
+ else if (!strcmp(cap, SKJSONCANVAS_CAP_ROUND)) {
+ target->setStrokeCap(SkPaint::kRound_Cap);
+ }
+ else if (!strcmp(cap, SKJSONCANVAS_CAP_SQUARE)) {
+ target->setStrokeCap(SkPaint::kSquare_Cap);
+ }
}
+}
+
+static void apply_paint_antialias(Json::Value& jsonPaint, SkPaint* target) {
if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_ANTIALIAS)) {
- result->setAntiAlias(jsonPaint[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
+ target->setAntiAlias(jsonPaint[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
}
+}
+
+static void apply_paint_blur(Json::Value& jsonPaint, SkPaint* target) {
if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_BLUR)) {
Json::Value blur = jsonPaint[SKJSONCANVAS_ATTRIBUTE_BLUR];
SkScalar sigma = blur[SKJSONCANVAS_ATTRIBUTE_SIGMA].asFloat();
@@ -167,8 +332,11 @@ void Renderer::getPaint(Json::Value& command, SkPaint* result) {
SkASSERT(false);
flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag;
}
- result->setMaskFilter(SkBlurMaskFilter::Create(style, sigma, flags));
+ target->setMaskFilter(SkBlurMaskFilter::Create(style, sigma, flags));
}
+}
+
+static void apply_paint_dashing(Json::Value& jsonPaint, SkPaint* target) {
if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_DASHING)) {
Json::Value dash = jsonPaint[SKJSONCANVAS_ATTRIBUTE_DASHING];
Json::Value jsonIntervals = dash[SKJSONCANVAS_ATTRIBUTE_INTERVALS];
@@ -178,9 +346,12 @@ void Renderer::getPaint(Json::Value& command, SkPaint* result) {
intervals[i] = jsonIntervals[i].asFloat();
}
SkScalar phase = dash[SKJSONCANVAS_ATTRIBUTE_PHASE].asFloat();
- result->setPathEffect(SkDashPathEffect::Create(intervals, count, phase));
+ target->setPathEffect(SkDashPathEffect::Create(intervals, count, phase));
free(intervals);
}
+}
+
+static void apply_paint_textalign(Json::Value& jsonPaint, SkPaint* target) {
if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_TEXTALIGN)) {
SkPaint::Align textAlign;
const char* jsonAlign = jsonPaint[SKJSONCANVAS_ATTRIBUTE_TEXTALIGN].asCString();
@@ -197,22 +368,51 @@ void Renderer::getPaint(Json::Value& command, SkPaint* result) {
SkASSERT(false);
textAlign = SkPaint::kLeft_Align;
}
- result->setTextAlign(textAlign);
+ target->setTextAlign(textAlign);
}
+}
+
+static void apply_paint_textsize(Json::Value& jsonPaint, SkPaint* target) {
if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_TEXTSIZE)) {
float textSize = jsonPaint[SKJSONCANVAS_ATTRIBUTE_TEXTSIZE].asFloat();
- result->setTextSize(textSize);
+ target->setTextSize(textSize);
}
+}
+
+static void apply_paint_textscalex(Json::Value& jsonPaint, SkPaint* target) {
if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX)) {
float textScaleX = jsonPaint[SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat();
- result->setTextScaleX(textScaleX);
+ target->setTextScaleX(textScaleX);
}
+}
+
+static void apply_paint_textskewx(Json::Value& jsonPaint, SkPaint* target) {
if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_TEXTSKEWX)) {
float textSkewX = jsonPaint[SKJSONCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat();
- result->setTextSkewX(textSkewX);
+ target->setTextSkewX(textSkewX);
}
}
+void Renderer::getPaint(Json::Value& command, SkPaint* result) {
+ Json::Value jsonPaint = command[SKJSONCANVAS_ATTRIBUTE_PAINT];
+ apply_paint_color(jsonPaint, result);
+ apply_paint_shader(jsonPaint, result);
+ apply_paint_patheffect(jsonPaint, result);
+ apply_paint_maskfilter(jsonPaint, result);
+ apply_paint_xfermode(jsonPaint, result);
+ apply_paint_style(jsonPaint, result);
+ apply_paint_strokewidth(jsonPaint, result);
+ apply_paint_strokemiter(jsonPaint, result);
+ apply_paint_cap(jsonPaint, result);
+ apply_paint_antialias(jsonPaint, result);
+ apply_paint_blur(jsonPaint, result);
+ apply_paint_dashing(jsonPaint, result);
+ apply_paint_textalign(jsonPaint, result);
+ apply_paint_textsize(jsonPaint, result);
+ apply_paint_textscalex(jsonPaint, result);
+ apply_paint_textskewx(jsonPaint, result);
+}
+
void Renderer::getRect(Json::Value& command, const char* name, SkRect* result) {
Json::Value rect = command[name];
result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3].asFloat());
@@ -330,6 +530,27 @@ void Renderer::processRestore(Json::Value& command, SkCanvas* target) {
target->restore();
}
+void Renderer::processSaveLayer(Json::Value& command, SkCanvas* target) {
+ SkCanvas::SaveLayerRec rec;
+ SkRect bounds;
+ if (command.isMember(SKJSONCANVAS_ATTRIBUTE_BOUNDS)) {
+ this->getRect(command, SKJSONCANVAS_ATTRIBUTE_BOUNDS, &bounds);
+ rec.fBounds = &bounds;
+ }
+ SkPaint paint;
+ if (command.isMember(SKJSONCANVAS_ATTRIBUTE_PAINT)) {
+ this->getPaint(command, &paint);
+ rec.fPaint = &paint;
+ }
+ if (command.isMember(SKJSONCANVAS_ATTRIBUTE_BACKDROP)) {
+ rec.fBackdrop = (SkImageFilter*) load_flattenable(command[SKJSONCANVAS_ATTRIBUTE_BACKDROP]);
+ }
+ target->saveLayer(rec);
+ if (rec.fBackdrop != nullptr) {
+ rec.fBackdrop->unref();
+ }
+}
+
void Renderer::processPaint(Json::Value& command, SkCanvas* target) {
SkPaint paint;
this->getPaint(command, &paint);
@@ -440,6 +661,114 @@ void Renderer::processClipPath(Json::Value& command, SkCanvas* target) {
command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
}
+void Renderer::processImage(Json::Value& command, SkCanvas* target) {
+ SkImage* image = load_image(command[SKJSONCANVAS_ATTRIBUTE_IMAGE]);
+ if (image == nullptr) {
+ return;
+ }
+ Json::Value point = command[SKJSONCANVAS_ATTRIBUTE_COORDS];
+ SkPaint* paintPtr;
+ SkPaint paint;
+ if (command.isMember(SKJSONCANVAS_ATTRIBUTE_PAINT)) {
+ this->getPaint(command, &paint);
+ paintPtr = &paint;
+ }
+ else {
+ paintPtr = nullptr;
+ }
+ target->drawImage(image, point[0].asFloat(), point[1].asFloat(), paintPtr);
+ image->unref();
+}
+
+void Renderer::processImageRect(Json::Value& command, SkCanvas* target) {
+ SkImage* image = load_image(command[SKJSONCANVAS_ATTRIBUTE_IMAGE]);
+ if (image == nullptr) {
+ return;
+ }
+ SkRect dst;
+ this->getRect(command, SKJSONCANVAS_ATTRIBUTE_DST, &dst);
+ SkPaint* paintPtr;
+ SkPaint paint;
+ if (command.isMember(SKJSONCANVAS_ATTRIBUTE_PAINT)) {
+ this->getPaint(command, &paint);
+ paintPtr = &paint;
+ }
+ else {
+ paintPtr = nullptr;
+ }
+ SkCanvas::SrcRectConstraint constraint;
+ if (command.isMember(SKJSONCANVAS_ATTRIBUTE_STRICT) &&
+ command[SKJSONCANVAS_ATTRIBUTE_STRICT].asBool()) {
+ constraint = SkCanvas::kStrict_SrcRectConstraint;
+ }
+ else {
+ constraint = SkCanvas::kFast_SrcRectConstraint;
+ }
+ if (command.isMember(SKJSONCANVAS_ATTRIBUTE_SRC)) {
+ SkRect src;
+ this->getRect(command, SKJSONCANVAS_ATTRIBUTE_SRC, &src);
+ target->drawImageRect(image, src, dst, paintPtr, constraint);
+ }
+ else {
+ target->drawImageRect(image, dst, paintPtr, constraint);
+ }
+ image->unref();
+}
+
+void Renderer::processBitmap(Json::Value& command, SkCanvas* target) {
+ SkImage* image = load_image(command[SKJSONCANVAS_ATTRIBUTE_BITMAP]);
+ if (image == nullptr) {
+ return;
+ }
+ Json::Value point = command[SKJSONCANVAS_ATTRIBUTE_COORDS];
+ SkPaint* paintPtr;
+ SkPaint paint;
+ if (command.isMember(SKJSONCANVAS_ATTRIBUTE_PAINT)) {
+ this->getPaint(command, &paint);
+ paintPtr = &paint;
+ }
+ else {
+ paintPtr = nullptr;
+ }
+ target->drawImage(image, point[0].asFloat(), point[1].asFloat(), paintPtr);
+ image->unref();
+}
+
+void Renderer::processBitmapRect(Json::Value& command, SkCanvas* target) {
+ SkBitmap* bitmap = load_bitmap(command[SKJSONCANVAS_ATTRIBUTE_BITMAP]);
+ if (bitmap == nullptr) {
+ return;
+ }
+ SkRect dst;
+ this->getRect(command, SKJSONCANVAS_ATTRIBUTE_DST, &dst);
+ SkPaint* paintPtr;
+ SkPaint paint;
+ if (command.isMember(SKJSONCANVAS_ATTRIBUTE_PAINT)) {
+ this->getPaint(command, &paint);
+ paintPtr = &paint;
+ }
+ else {
+ paintPtr = nullptr;
+ }
+ SkCanvas::SrcRectConstraint constraint;
+ if (command.isMember(SKJSONCANVAS_ATTRIBUTE_STRICT) &&
+ command[SKJSONCANVAS_ATTRIBUTE_STRICT].asBool()) {
+ constraint = SkCanvas::kStrict_SrcRectConstraint;
+ }
+ else {
+ constraint = SkCanvas::kFast_SrcRectConstraint;
+ }
+ if (command.isMember(SKJSONCANVAS_ATTRIBUTE_SRC)) {
+ SkRect src;
+ this->getRect(command, SKJSONCANVAS_ATTRIBUTE_SRC, &src);
+ target->drawBitmapRect(*bitmap, src, dst, paintPtr, constraint);
+ }
+ else {
+ target->drawBitmapRect(*bitmap, dst, paintPtr, constraint);
+ }
+ free(bitmap);
+}
+
void render(const char* json, SkCanvas* target) {
Renderer renderer;
Json::Reader reader;
« no previous file with comments | « tools/json/SkJSONCanvas.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698