Index: tools/json/SkJSONCanvas.cpp |
diff --git a/tools/json/SkJSONCanvas.cpp b/tools/json/SkJSONCanvas.cpp |
index efc4acd1a319013a84a8611a65e4b962d3ee9faa..4cd2218948cde9bfa9d44a5822d1d5f6af5d37c1 100644 |
--- a/tools/json/SkJSONCanvas.cpp |
+++ b/tools/json/SkJSONCanvas.cpp |
@@ -181,15 +181,31 @@ static void flatten(const SkFlattenable* flattenable, Json::Value* target, bool |
static bool SK_WARN_UNUSED_RESULT flatten(const SkImage& image, Json::Value* target, |
bool sendBinaries) { |
if (sendBinaries) { |
- SkData* png = image.encode(SkImageEncoder::kPNG_Type, 100); |
- if (png == nullptr) { |
- SkDebugf("could not encode image\n"); |
- return false; |
+ SkData* encoded = image.encode(SkImageEncoder::kPNG_Type, 100); |
+ if (encoded == nullptr) { |
+ // PNG encode doesn't necessarily support all color formats, convert to a different |
+ // format |
+ size_t rowBytes = 4 * image.width(); |
+ void* buffer = sk_malloc_throw(rowBytes * image.height()); |
+ SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(), |
+ kN32_SkColorType, kPremul_SkAlphaType); |
+ if (!image.readPixels(dstInfo, buffer, rowBytes, 0, 0)) { |
+ SkDebugf("readPixels failed\n"); |
+ return false; |
+ } |
+ SkImage* converted = SkImage::NewRasterCopy(dstInfo, buffer, rowBytes); |
+ encoded = converted->encode(SkImageEncoder::kPNG_Type, 100); |
+ if (encoded == nullptr) { |
+ SkDebugf("image encode failed\n"); |
+ return false; |
+ } |
+ free(converted); |
+ free(buffer); |
} |
Json::Value bytes; |
- encode_data(png->data(), png->size(), &bytes); |
+ encode_data(encoded->data(), encoded->size(), &bytes); |
(*target)[SKJSONCANVAS_ATTRIBUTE_BYTES] = bytes; |
- png->unref(); |
+ encoded->unref(); |
} |
else { |
SkString description = SkStringPrintf("%dx%d pixel image", image.width(), image.height()); |
@@ -198,11 +214,50 @@ static bool SK_WARN_UNUSED_RESULT flatten(const SkImage& image, Json::Value* tar |
return true; |
} |
+static const char* color_type_name(SkColorType colorType) { |
+ switch (colorType) { |
+ case kARGB_4444_SkColorType: |
+ return SKJSONCANVAS_COLORTYPE_ARGB4444; |
+ case kRGBA_8888_SkColorType: |
+ return SKJSONCANVAS_COLORTYPE_RGBA8888; |
+ case kBGRA_8888_SkColorType: |
+ return SKJSONCANVAS_COLORTYPE_BGRA8888; |
+ case kRGB_565_SkColorType: |
+ return SKJSONCANVAS_COLORTYPE_565; |
+ case kGray_8_SkColorType: |
+ return SKJSONCANVAS_COLORTYPE_GRAY8; |
+ case kIndex_8_SkColorType: |
+ return SKJSONCANVAS_COLORTYPE_INDEX8; |
+ case kAlpha_8_SkColorType: |
+ return SKJSONCANVAS_COLORTYPE_ALPHA8; |
+ default: |
+ SkASSERT(false); |
+ return SKJSONCANVAS_COLORTYPE_RGBA8888; |
+ } |
+} |
+ |
+static const char* alpha_type_name(SkAlphaType alphaType) { |
+ switch (alphaType) { |
+ case kOpaque_SkAlphaType: |
+ return SKJSONCANVAS_ALPHATYPE_OPAQUE; |
+ case kPremul_SkAlphaType: |
+ return SKJSONCANVAS_ALPHATYPE_PREMUL; |
+ case kUnpremul_SkAlphaType: |
+ return SKJSONCANVAS_ALPHATYPE_UNPREMUL; |
+ default: |
+ SkASSERT(false); |
+ return SKJSONCANVAS_ALPHATYPE_OPAQUE; |
+ } |
+} |
+ |
static bool SK_WARN_UNUSED_RESULT flatten(const SkBitmap& bitmap, Json::Value* target, |
bool sendBinaries) { |
- SkImage* image = SkImage::NewFromBitmap(bitmap); |
+ bitmap.lockPixels(); |
+ SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(bitmap)); |
+ bitmap.unlockPixels(); |
+ (*target)[SKJSONCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType())); |
+ (*target)[SKJSONCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType())); |
bool success = flatten(*image, target, sendBinaries); |
- image->unref(); |
return success; |
} |
@@ -361,6 +416,15 @@ static void apply_paint_xfermode(const SkPaint& paint, Json::Value* target, bool |
} |
} |
+static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) { |
+ SkFlattenable* imageFilter = paint.getImageFilter(); |
+ if (imageFilter != nullptr) { |
+ Json::Value jsonImageFilter; |
+ flatten(imageFilter, &jsonImageFilter, sendBinaries); |
+ (*target)[SKJSONCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter; |
+ } |
+} |
+ |
Json::Value SkJSONCanvas::makePaint(const SkPaint& paint) { |
Json::Value result(Json::objectValue); |
store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f); |
@@ -379,6 +443,7 @@ Json::Value SkJSONCanvas::makePaint(const SkPaint& paint) { |
apply_paint_maskfilter(paint, &result, fSendBinaries); |
apply_paint_shader(paint, &result, fSendBinaries); |
apply_paint_xfermode(paint, &result, fSendBinaries); |
+ apply_paint_imagefilter(paint, &result, fSendBinaries); |
return result; |
} |
@@ -592,7 +657,7 @@ void SkJSONCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, c |
this->updateMatrix(); |
Json::Value command(Json::objectValue); |
command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_BITMAPRECT); |
- command[SKJSONCANVAS_ATTRIBUTE_IMAGE] = encoded; |
+ command[SKJSONCANVAS_ATTRIBUTE_BITMAP] = encoded; |
if (src != nullptr) { |
command[SKJSONCANVAS_ATTRIBUTE_SRC] = this->makeRect(*src); |
} |
@@ -720,6 +785,7 @@ void SkJSONCanvas::willRestore() { |
} |
SkCanvas::SaveLayerStrategy SkJSONCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) { |
+ this->updateMatrix(); |
Json::Value command(Json::objectValue); |
command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_SAVELAYER); |
if (rec.fBounds != nullptr) { |