diff options
author | 2016-01-29 07:15:08 -0800 | |
---|---|---|
committer | 2016-01-29 07:15:08 -0800 | |
commit | 78fc22af41a5118963a8f7253758111b05b9700e (patch) | |
tree | c984f0cc74aa6498680598a76404bb5e9f2247bd | |
parent | 6b2c3461b0c109897b4699bda0f7bfdb9c37e744 (diff) |
added support for more features in JSON (blurs, dashing, different path fill types, etc.)
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1644903003
Review URL: https://codereview.chromium.org/1644903003
-rw-r--r-- | gyp/json.gyp | 2 | ||||
-rw-r--r-- | tools/json/SkJSONCanvas.cpp | 163 | ||||
-rw-r--r-- | tools/json/SkJSONCanvas.h | 32 | ||||
-rw-r--r-- | tools/json/SkJSONRenderer.cpp | 246 |
4 files changed, 373 insertions, 70 deletions
diff --git a/gyp/json.gyp b/gyp/json.gyp index 6c12b7ce09..5b20b2961c 100644 --- a/gyp/json.gyp +++ b/gyp/json.gyp @@ -14,6 +14,8 @@ 'jsoncpp.gyp:jsoncpp', ], 'include_dirs': [ + '../include/core', + '../include/effects', '../include/utils', '../src/core', ], diff --git a/tools/json/SkJSONCanvas.cpp b/tools/json/SkJSONCanvas.cpp index 4bd23db4fd..106b59ff56 100644 --- a/tools/json/SkJSONCanvas.cpp +++ b/tools/json/SkJSONCanvas.cpp @@ -6,7 +6,10 @@ */ #include "SkJSONCanvas.h" +#include "SkMaskFilter.h" +#include "SkPaintDefaults.h" #include "SkPath.h" +#include "SkPathEffect.h" #include "SkRRect.h" SkJSONCanvas::SkJSONCanvas(int width, int height, SkWStream& out) @@ -50,13 +53,28 @@ Json::Value SkJSONCanvas::makeRRect(const SkRRect& rrect) { result.append(this->makeRect(rrect.rect())); result.append(this->makePoint(rrect.radii(SkRRect::kUpperLeft_Corner))); result.append(this->makePoint(rrect.radii(SkRRect::kUpperRight_Corner))); - result.append(this->makePoint(rrect.radii(SkRRect::kLowerLeft_Corner))); result.append(this->makePoint(rrect.radii(SkRRect::kLowerRight_Corner))); + result.append(this->makePoint(rrect.radii(SkRRect::kLowerLeft_Corner))); return result; } Json::Value SkJSONCanvas::makePath(const SkPath& path) { - Json::Value result(Json::arrayValue); + Json::Value result(Json::objectValue); + switch (path.getFillType()) { + case SkPath::kWinding_FillType: + result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_WINDING; + break; + case SkPath::kEvenOdd_FillType: + result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_EVENODD; + break; + case SkPath::kInverseWinding_FillType: + result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_INVERSEWINDING; + break; + case SkPath::kInverseEvenOdd_FillType: + result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_INVERSEEVENODD; + break; + } + Json::Value verbs(Json::arrayValue); SkPath::Iter iter(path, false); SkPoint pts[4]; SkPath::Verb verb; @@ -65,7 +83,7 @@ Json::Value SkJSONCanvas::makePath(const SkPath& path) { case SkPath::kLine_Verb: { Json::Value line(Json::objectValue); line[SKJSONCANVAS_VERB_LINE] = this->makePoint(pts[1]); - result.append(line); + verbs.append(line); break; } case SkPath::kQuad_Verb: { @@ -74,7 +92,7 @@ Json::Value SkJSONCanvas::makePath(const SkPath& path) { coords.append(this->makePoint(pts[1])); coords.append(this->makePoint(pts[2])); quad[SKJSONCANVAS_VERB_QUAD] = coords; - result.append(quad); + verbs.append(quad); break; } case SkPath::kCubic_Verb: { @@ -84,7 +102,7 @@ Json::Value SkJSONCanvas::makePath(const SkPath& path) { coords.append(this->makePoint(pts[2])); coords.append(this->makePoint(pts[3])); cubic[SKJSONCANVAS_VERB_CUBIC] = coords; - result.append(cubic); + verbs.append(cubic); break; } case SkPath::kConic_Verb: { @@ -94,22 +112,23 @@ Json::Value SkJSONCanvas::makePath(const SkPath& path) { coords.append(this->makePoint(pts[2])); coords.append(Json::Value(iter.conicWeight())); conic[SKJSONCANVAS_VERB_CONIC] = coords; - result.append(conic); + verbs.append(conic); break; } case SkPath::kMove_Verb: { Json::Value move(Json::objectValue); move[SKJSONCANVAS_VERB_MOVE] = this->makePoint(pts[0]); - result.append(move); + verbs.append(move); break; } case SkPath::kClose_Verb: - result.append(Json::Value(SKJSONCANVAS_VERB_CLOSE)); + verbs.append(Json::Value(SKJSONCANVAS_VERB_CLOSE)); break; case SkPath::kDone_Verb: break; } } + result[SKJSONCANVAS_ATTRIBUTE_VERBS] = verbs; return result; } @@ -117,6 +136,18 @@ Json::Value SkJSONCanvas::makeRegion(const SkRegion& region) { return Json::Value("<unimplemented>"); } +void store_scalar(Json::Value* target, const char* key, SkScalar value, SkScalar defaultValue) { + if (value != defaultValue) { + (*target)[key] = Json::Value(value); + } +} + +void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) { + if (value != defaultValue) { + (*target)[key] = Json::Value(value); + } +} + Json::Value SkJSONCanvas::makePaint(const SkPaint& paint) { Json::Value result(Json::objectValue); SkColor color = paint.getColor(); @@ -144,12 +175,86 @@ Json::Value SkJSONCanvas::makePaint(const SkPaint& paint) { default: SkASSERT(false); } } - SkScalar strokeWidth = paint.getStrokeWidth(); - if (strokeWidth != 0.0f) { - result[SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH] = Json::Value(strokeWidth); + store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f); + store_bool(&result, SKJSONCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false); + SkMaskFilter* maskFilter = paint.getMaskFilter(); + if (maskFilter != nullptr) { + SkMaskFilter::BlurRec blurRec; + if (maskFilter->asABlur(&blurRec)) { + Json::Value blur(Json::objectValue); + blur[SKJSONCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma); + switch (blurRec.fStyle) { + case SkBlurStyle::kNormal_SkBlurStyle: + blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_NORMAL); + break; + case SkBlurStyle::kSolid_SkBlurStyle: + blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_SOLID); + break; + case SkBlurStyle::kOuter_SkBlurStyle: + blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_OUTER); + break; + case SkBlurStyle::kInner_SkBlurStyle: + blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_INNER); + break; + default: + SkASSERT(false); + } + switch (blurRec.fQuality) { + case SkBlurQuality::kLow_SkBlurQuality: + blur[SKJSONCANVAS_ATTRIBUTE_QUALITY] = Json::Value(SKJSONCANVAS_BLURQUALITY_LOW); + break; + case SkBlurQuality::kHigh_SkBlurQuality: + blur[SKJSONCANVAS_ATTRIBUTE_QUALITY] = Json::Value(SKJSONCANVAS_BLURQUALITY_HIGH); + break; + default: + SkASSERT(false); + } + result[SKJSONCANVAS_ATTRIBUTE_BLUR] = blur; + } + else { + SkDebugf("unimplemented: non-blur maskfilter"); + SkASSERT(false); + } } - if (paint.isAntiAlias()) { - result[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(true); + SkPathEffect* pathEffect = paint.getPathEffect(); + if (pathEffect != nullptr) { + SkPathEffect::DashInfo dashInfo; + SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo); + if (dashType == SkPathEffect::kDash_DashType) { + dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar)); + pathEffect->asADash(&dashInfo); + Json::Value dashing(Json::objectValue); + Json::Value intervals(Json::arrayValue); + for (int32_t i = 0; i < dashInfo.fCount; i++) { + intervals.append(Json::Value(dashInfo.fIntervals[i])); + } + free(dashInfo.fIntervals); + dashing[SKJSONCANVAS_ATTRIBUTE_INTERVALS] = intervals; + dashing[SKJSONCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase; + result[SKJSONCANVAS_ATTRIBUTE_DASHING] = dashing; + } + else { + SkDebugf("unimplemented: non-dash patheffect"); + SkASSERT(false); + } + } + store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(), + SkPaintDefaults_TextSize); + store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1); + store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f); + SkPaint::Align textAlign = paint.getTextAlign(); + if (textAlign != SkPaint::kLeft_Align) { + switch (textAlign) { + case SkPaint::kCenter_Align: { + result[SKJSONCANVAS_ATTRIBUTE_TEXTALIGN] = SKJSONCANVAS_ALIGN_CENTER; + break; + } + case SkPaint::kRight_Align: { + result[SKJSONCANVAS_ATTRIBUTE_TEXTALIGN] = SKJSONCANVAS_ALIGN_RIGHT; + break; + } + default: SkASSERT(false); + } } return result; } @@ -194,18 +299,6 @@ Json::Value SkJSONCanvas::makeRegionOp(SkRegion::Op op) { }; } -Json::Value SkJSONCanvas::makeEdgeStyle(SkCanvas::ClipEdgeStyle edgeStyle) { - switch (edgeStyle) { - case SkCanvas::kHard_ClipEdgeStyle: - return Json::Value(SKJSONCANVAS_EDGESTYLE_HARD); - case SkCanvas::kSoft_ClipEdgeStyle: - return Json::Value(SKJSONCANVAS_EDGESTYLE_SOFT); - default: - SkASSERT(false); - return Json::Value("<invalid edge style>"); - }; -} - Json::Value SkJSONCanvas::makePointMode(SkCanvas::PointMode mode) { switch (mode) { case SkCanvas::kPoints_PointMode: @@ -352,7 +445,18 @@ void SkJSONCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, void SkJSONCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint) { - SkDebugf("unsupported: drawPosText\n"); + this->updateMatrix(); + Json::Value command(Json::objectValue); + command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_POSTEXT); + command[SKJSONCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) text, + ((const char*) text) + byteLength); + Json::Value coords(Json::arrayValue); + for (size_t i = 0; i < byteLength; i++) { + coords.append(this->makePoint(pos[i])); + } + command[SKJSONCANVAS_ATTRIBUTE_COORDS] = coords; + command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint); + fCommands.append(command); } void SkJSONCanvas::onDrawPosTextH(const void* text, size_t byteLength, @@ -388,7 +492,7 @@ void SkJSONCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPRECT); command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRect(rect); command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op); - command[SKJSONCANVAS_ATTRIBUTE_EDGESTYLE] = this->makeEdgeStyle(edgeStyle); + command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS] = (edgeStyle == SkCanvas::kSoft_ClipEdgeStyle); fCommands.append(command); } @@ -398,7 +502,7 @@ void SkJSONCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeSt command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPRRECT); command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRRect(rrect); command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op); - command[SKJSONCANVAS_ATTRIBUTE_EDGESTYLE] = this->makeEdgeStyle(edgeStyle); + command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS] = (edgeStyle == SkCanvas::kSoft_ClipEdgeStyle); fCommands.append(command); } @@ -408,7 +512,7 @@ void SkJSONCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPPATH); command[SKJSONCANVAS_ATTRIBUTE_PATH] = this->makePath(path); command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op); - command[SKJSONCANVAS_ATTRIBUTE_EDGESTYLE] = this->makeEdgeStyle(edgeStyle); + command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS] = (edgeStyle == SkCanvas::kSoft_ClipEdgeStyle); fCommands.append(command); } @@ -422,6 +526,7 @@ void SkJSONCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { } void SkJSONCanvas::willSave() { + this->updateMatrix(); Json::Value command(Json::objectValue); command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_SAVE); fCommands.append(command); diff --git a/tools/json/SkJSONCanvas.h b/tools/json/SkJSONCanvas.h index 66b413ebbe..27cb398a36 100644 --- a/tools/json/SkJSONCanvas.h +++ b/tools/json/SkJSONCanvas.h @@ -63,6 +63,18 @@ #define SKJSONCANVAS_ATTRIBUTE_REGIONOP "op" #define SKJSONCANVAS_ATTRIBUTE_EDGESTYLE "edgeStyle" #define SKJSONCANVAS_ATTRIBUTE_DEVICEREGION "deviceRegion" +#define SKJSONCANVAS_ATTRIBUTE_BLUR "blur" +#define SKJSONCANVAS_ATTRIBUTE_SIGMA "sigma" +#define SKJSONCANVAS_ATTRIBUTE_QUALITY "quality" +#define SKJSONCANVAS_ATTRIBUTE_TEXTALIGN "textAlign" +#define SKJSONCANVAS_ATTRIBUTE_TEXTSIZE "textSize" +#define SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX "textScaleX" +#define SKJSONCANVAS_ATTRIBUTE_TEXTSKEWX "textSkewX" +#define SKJSONCANVAS_ATTRIBUTE_DASHING "dashing" +#define SKJSONCANVAS_ATTRIBUTE_INTERVALS "intervals" +#define SKJSONCANVAS_ATTRIBUTE_PHASE "phase" +#define SKJSONCANVAS_ATTRIBUTE_FILLTYPE "fillType" +#define SKJSONCANVAS_ATTRIBUTE_VERBS "verbs" #define SKJSONCANVAS_VERB_MOVE "move" #define SKJSONCANVAS_VERB_LINE "line" @@ -75,9 +87,6 @@ #define SKJSONCANVAS_STYLE_STROKE "stroke" #define SKJSONCANVAS_STYLE_STROKEANDFILL "strokeAndFill" -#define SKJSONCANVAS_EDGESTYLE_HARD "hard" -#define SKJSONCANVAS_EDGESTYLE_SOFT "soft" - #define SKJSONCANVAS_POINTMODE_POINTS "points" #define SKJSONCANVAS_POINTMODE_LINES "lines" #define SKJSONCANVAS_POINTMODE_POLYGON "polygon" @@ -89,6 +98,23 @@ #define SKJSONCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference" #define SKJSONCANVAS_REGIONOP_REPLACE "replace" +#define SKJSONCANVAS_BLURSTYLE_NORMAL "normal" +#define SKJSONCANVAS_BLURSTYLE_SOLID "solid" +#define SKJSONCANVAS_BLURSTYLE_OUTER "outer" +#define SKJSONCANVAS_BLURSTYLE_INNER "inner" + +#define SKJSONCANVAS_BLURQUALITY_LOW "low" +#define SKJSONCANVAS_BLURQUALITY_HIGH "high" + +#define SKJSONCANVAS_ALIGN_LEFT "left" +#define SKJSONCANVAS_ALIGN_CENTER "center" +#define SKJSONCANVAS_ALIGN_RIGHT "right" + +#define SKJSONCANVAS_FILLTYPE_WINDING "winding" +#define SKJSONCANVAS_FILLTYPE_EVENODD "evenOdd" +#define SKJSONCANVAS_FILLTYPE_INVERSEWINDING "inverseWinding" +#define SKJSONCANVAS_FILLTYPE_INVERSEEVENODD "inverseEvenOdd" + /* * Implementation of SkCanvas which writes JSON when drawn to. The JSON describes all of the draw * commands issued to the canvas, and can later be turned back into draw commands using diff --git a/tools/json/SkJSONRenderer.cpp b/tools/json/SkJSONRenderer.cpp index f9bb6ee40e..e84a1ed692 100644 --- a/tools/json/SkJSONRenderer.cpp +++ b/tools/json/SkJSONRenderer.cpp @@ -6,6 +6,9 @@ */ #include "SkJSONRenderer.h" + +#include "SkBlurMaskFilter.h" +#include "SkDashPathEffect.h" #include "SkJSONCanvas.h" #include "SkJSONCPP.h" #include "SkPath.h" @@ -20,6 +23,10 @@ public: void getRRect(Json::Value& command, const char* name, SkRRect* rrect); + void getPath(Json::Value& command, SkPath* path); + + SkRegion::Op getRegionOp(Json::Value& command); + void processCommand(Json::Value& command, SkCanvas* target); void processMatrix(Json::Value& command, SkCanvas* target); @@ -40,9 +47,15 @@ public: void processText(Json::Value& command, SkCanvas* target); + void processPosText(Json::Value& command, SkCanvas* target); + void processPoints(Json::Value& command, SkCanvas* target); void processClipRect(Json::Value& command, SkCanvas* target); + + void processClipRRect(Json::Value& command, SkCanvas* target); + + void processClipPath(Json::Value& command, SkCanvas* target); }; void Renderer::processCommand(Json::Value& command, SkCanvas* target) { @@ -75,12 +88,21 @@ void Renderer::processCommand(Json::Value& command, SkCanvas* target) { else if (!strcmp(name, SKJSONCANVAS_COMMAND_TEXT)) { this->processText(command, target); } + else if (!strcmp(name, SKJSONCANVAS_COMMAND_POSTEXT)) { + this->processPosText(command, target); + } else if (!strcmp(name, SKJSONCANVAS_COMMAND_POINTS)) { this->processPoints(command, target); } else if (!strcmp(name, SKJSONCANVAS_COMMAND_CLIPRECT)) { this->processClipRect(command, target); } + else if (!strcmp(name, SKJSONCANVAS_COMMAND_CLIPRRECT)) { + this->processClipRRect(command, target); + } + else if (!strcmp(name, SKJSONCANVAS_COMMAND_CLIPPATH)) { + this->processClipPath(command, target); + } else { SkDebugf("unsupported JSON command: %s\n", name); } @@ -112,6 +134,82 @@ void Renderer::getPaint(Json::Value& command, SkPaint* result) { if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_ANTIALIAS)) { result->setAntiAlias(jsonPaint[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS].asBool()); } + if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_BLUR)) { + Json::Value blur = jsonPaint[SKJSONCANVAS_ATTRIBUTE_BLUR]; + SkScalar sigma = blur[SKJSONCANVAS_ATTRIBUTE_SIGMA].asFloat(); + SkBlurStyle style; + const char* jsonStyle = blur[SKJSONCANVAS_ATTRIBUTE_STYLE].asCString(); + if (!strcmp(jsonStyle, SKJSONCANVAS_BLURSTYLE_NORMAL)) { + style = SkBlurStyle::kNormal_SkBlurStyle; + } + else if (!strcmp(jsonStyle, SKJSONCANVAS_BLURSTYLE_SOLID)) { + style = SkBlurStyle::kSolid_SkBlurStyle; + } + else if (!strcmp(jsonStyle, SKJSONCANVAS_BLURSTYLE_OUTER)) { + style = SkBlurStyle::kOuter_SkBlurStyle; + } + else if (!strcmp(jsonStyle, SKJSONCANVAS_BLURSTYLE_INNER)) { + style = SkBlurStyle::kInner_SkBlurStyle; + } + else { + SkASSERT(false); + style = SkBlurStyle::kNormal_SkBlurStyle; + } + SkBlurMaskFilter::BlurFlags flags; + const char* jsonQuality = blur[SKJSONCANVAS_ATTRIBUTE_QUALITY].asCString(); + if (!strcmp(jsonQuality, SKJSONCANVAS_BLURQUALITY_LOW)) { + flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag; + } + else if (!strcmp(jsonQuality, SKJSONCANVAS_BLURQUALITY_HIGH)) { + flags = SkBlurMaskFilter::BlurFlags::kHighQuality_BlurFlag; + } + else { + SkASSERT(false); + flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag; + } + result->setMaskFilter(SkBlurMaskFilter::Create(style, sigma, flags)); + } + if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_DASHING)) { + Json::Value dash = jsonPaint[SKJSONCANVAS_ATTRIBUTE_DASHING]; + Json::Value jsonIntervals = dash[SKJSONCANVAS_ATTRIBUTE_INTERVALS]; + Json::ArrayIndex count = jsonIntervals.size(); + SkScalar* intervals = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar)); + for (Json::ArrayIndex i = 0; i < count; i++) { + intervals[i] = jsonIntervals[i].asFloat(); + } + SkScalar phase = dash[SKJSONCANVAS_ATTRIBUTE_PHASE].asFloat(); + result->setPathEffect(SkDashPathEffect::Create(intervals, count, phase)); + free(intervals); + } + if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_TEXTALIGN)) { + SkPaint::Align textAlign; + const char* jsonAlign = jsonPaint[SKJSONCANVAS_ATTRIBUTE_TEXTALIGN].asCString(); + if (!strcmp(jsonAlign, SKJSONCANVAS_ALIGN_LEFT)) { + textAlign = SkPaint::kLeft_Align; + } + else if (!strcmp(jsonAlign, SKJSONCANVAS_ALIGN_CENTER)) { + textAlign = SkPaint::kCenter_Align; + } + else if (!strcmp(jsonAlign, SKJSONCANVAS_ALIGN_RIGHT)) { + textAlign = SkPaint::kRight_Align; + } + else { + SkASSERT(false); + textAlign = SkPaint::kLeft_Align; + } + } + if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_TEXTSIZE)) { + float textSize = jsonPaint[SKJSONCANVAS_ATTRIBUTE_TEXTSIZE].asFloat(); + result->setTextSize(textSize); + } + if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX)) { + float textScaleX = jsonPaint[SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat(); + result->setTextScaleX(textScaleX); + } + if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_TEXTSKEWX)) { + float textSkewX = jsonPaint[SKJSONCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat(); + result->setTextSkewX(textSkewX); + } } void Renderer::getRect(Json::Value& command, const char* name, SkRect* result) { @@ -132,6 +230,85 @@ void Renderer::getRRect(Json::Value& command, const char* name, SkRRect* result) radii); } +void Renderer::getPath(Json::Value& command, SkPath* result) { + Json::Value path = command[SKJSONCANVAS_ATTRIBUTE_PATH]; + const char* fillType = path[SKJSONCANVAS_ATTRIBUTE_FILLTYPE].asCString(); + if (!strcmp(fillType, SKJSONCANVAS_FILLTYPE_WINDING)) { + result->setFillType(SkPath::kWinding_FillType); + } + else if (!strcmp(fillType, SKJSONCANVAS_FILLTYPE_EVENODD)) { + result->setFillType(SkPath::kEvenOdd_FillType); + } + else if (!strcmp(fillType, SKJSONCANVAS_FILLTYPE_INVERSEWINDING)) { + result->setFillType(SkPath::kInverseWinding_FillType); + } + else if (!strcmp(fillType, SKJSONCANVAS_FILLTYPE_INVERSEEVENODD)) { + result->setFillType(SkPath::kInverseEvenOdd_FillType); + } + Json::Value verbs = path[SKJSONCANVAS_ATTRIBUTE_VERBS]; + for (Json::ArrayIndex i = 0; i < verbs.size(); i++) { + Json::Value verb = verbs[i]; + if (verb.isString()) { + SkASSERT(!strcmp(verb.asCString(), SKJSONCANVAS_VERB_CLOSE)); + result->close(); + } + else { + if (verb.isMember(SKJSONCANVAS_VERB_MOVE)) { + Json::Value move = verb[SKJSONCANVAS_VERB_MOVE]; + result->moveTo(move[0].asFloat(), move[1].asFloat()); + } + else if (verb.isMember(SKJSONCANVAS_VERB_LINE)) { + Json::Value line = verb[SKJSONCANVAS_VERB_LINE]; + result->lineTo(line[0].asFloat(), line[1].asFloat()); + } + else if (verb.isMember(SKJSONCANVAS_VERB_QUAD)) { + Json::Value quad = verb[SKJSONCANVAS_VERB_QUAD]; + result->quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(), + quad[1][0].asFloat(), quad[1][1].asFloat()); + } + else if (verb.isMember(SKJSONCANVAS_VERB_CUBIC)) { + Json::Value cubic = verb[SKJSONCANVAS_VERB_CUBIC]; + result->cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(), + cubic[1][0].asFloat(), cubic[1][1].asFloat(), + cubic[2][0].asFloat(), cubic[2][1].asFloat()); + } + else if (verb.isMember(SKJSONCANVAS_VERB_CONIC)) { + Json::Value conic = verb[SKJSONCANVAS_VERB_CONIC]; + result->conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(), + conic[1][0].asFloat(), conic[1][1].asFloat(), + conic[2].asFloat()); + } + else { + SkASSERT(false); + } + } + } +} + +SkRegion::Op Renderer::getRegionOp(Json::Value& command) { + const char* op = command[SKJSONCANVAS_ATTRIBUTE_REGIONOP].asCString(); + if (!strcmp(op, SKJSONCANVAS_REGIONOP_DIFFERENCE)) { + return SkRegion::kDifference_Op; + } + else if (!strcmp(op, SKJSONCANVAS_REGIONOP_INTERSECT)) { + return SkRegion::kIntersect_Op; + } + else if (!strcmp(op, SKJSONCANVAS_REGIONOP_UNION)) { + return SkRegion::kUnion_Op; + } + else if (!strcmp(op, SKJSONCANVAS_REGIONOP_XOR)) { + return SkRegion::kXOR_Op; + } + else if (!strcmp(op, SKJSONCANVAS_REGIONOP_REVERSE_DIFFERENCE)) { + return SkRegion::kReverseDifference_Op; + } + else if (!strcmp(op, SKJSONCANVAS_REGIONOP_REPLACE)) { + return SkRegion::kReplace_Op; + } + SkASSERT(false); + return SkRegion::kIntersect_Op; +} + void Renderer::processMatrix(Json::Value& command, SkCanvas* target) { Json::Value jsonMatrix = command[SKJSONCANVAS_ATTRIBUTE_MATRIX]; SkMatrix matrix; @@ -185,43 +362,7 @@ void Renderer::processOval(Json::Value& command, SkCanvas* target) { void Renderer::processPath(Json::Value& command, SkCanvas* target) { Json::Value jsonPath = command[SKJSONCANVAS_ATTRIBUTE_PATH]; SkPath path; - for (Json::ArrayIndex i = 0; i < jsonPath.size(); i++) { - Json::Value verb = jsonPath[i]; - if (verb.isString()) { - SkASSERT(!strcmp(verb.asCString(), SKJSONCANVAS_VERB_CLOSE)); - path.close(); - } - else { - if (verb.isMember(SKJSONCANVAS_VERB_MOVE)) { - Json::Value move = verb[SKJSONCANVAS_VERB_MOVE]; - path.moveTo(move[0].asFloat(), move[1].asFloat()); - } - else if (verb.isMember(SKJSONCANVAS_VERB_LINE)) { - Json::Value line = verb[SKJSONCANVAS_VERB_LINE]; - path.lineTo(line[0].asFloat(), line[1].asFloat()); - } - else if (verb.isMember(SKJSONCANVAS_VERB_QUAD)) { - Json::Value quad = verb[SKJSONCANVAS_VERB_QUAD]; - path.quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(), - quad[1][0].asFloat(), quad[1][1].asFloat()); - } - else if (verb.isMember(SKJSONCANVAS_VERB_CUBIC)) { - Json::Value cubic = verb[SKJSONCANVAS_VERB_CUBIC]; - path.cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(), - cubic[1][0].asFloat(), cubic[1][1].asFloat(), - cubic[2][0].asFloat(), cubic[2][1].asFloat()); - } - else if (verb.isMember(SKJSONCANVAS_VERB_CONIC)) { - Json::Value conic = verb[SKJSONCANVAS_VERB_CONIC]; - path.conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(), - conic[1][0].asFloat(), conic[1][1].asFloat(), - conic[2].asFloat()); - } - else { - SkASSERT(false); - } - } - } + this->getPath(command, &path); SkPaint paint; this->getPaint(command, &paint); target->drawPath(path, paint); @@ -235,6 +376,20 @@ void Renderer::processText(Json::Value& command, SkCanvas* target) { target->drawText(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(), paint); } +void Renderer::processPosText(Json::Value& command, SkCanvas* target) { + const char* text = command[SKJSONCANVAS_ATTRIBUTE_TEXT].asCString(); + SkPaint paint; + this->getPaint(command, &paint); + Json::Value coords = command[SKJSONCANVAS_ATTRIBUTE_COORDS]; + int count = (int) coords.size(); + SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint)); + for (int i = 0; i < count; i++) { + points[i] = SkPoint::Make(coords[i][0].asFloat(), coords[i][1].asFloat()); + } + target->drawPosText(text, strlen(text), points, paint); + free(points); +} + void Renderer::processPoints(Json::Value& command, SkCanvas* target) { SkCanvas::PointMode mode; const char* jsonMode = command[SKJSONCANVAS_ATTRIBUTE_MODE].asCString(); @@ -266,7 +421,22 @@ void Renderer::processPoints(Json::Value& command, SkCanvas* target) { void Renderer::processClipRect(Json::Value& command, SkCanvas* target) { SkRect rect; this->getRect(command, SKJSONCANVAS_ATTRIBUTE_COORDS, &rect); - target->clipRect(rect); + target->clipRect(rect, this->getRegionOp(command), + command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS].asBool()); +} + +void Renderer::processClipRRect(Json::Value& command, SkCanvas* target) { + SkRRect rrect; + this->getRRect(command, SKJSONCANVAS_ATTRIBUTE_COORDS, &rrect); + target->clipRRect(rrect, this->getRegionOp(command), + command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS].asBool()); +} + +void Renderer::processClipPath(Json::Value& command, SkCanvas* target) { + SkPath path; + this->getPath(command, &path); + target->clipPath(path, this->getRegionOp(command), + command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS].asBool()); } void render(const char* json, SkCanvas* target) { |