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

Unified Diff: src/svg/SkSVGDevice.cpp

Issue 959883003: [SkSVGDevice] drawBitmap* support (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: win warning fix Created 5 years, 10 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 | « src/svg/SkSVGDevice.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/svg/SkSVGDevice.cpp
diff --git a/src/svg/SkSVGDevice.cpp b/src/svg/SkSVGDevice.cpp
index a56a6314464fa46c00d2e26cdca758cb4ae79031..45e616b3f618b2717fb4fadb31690da12bcbf49c 100644
--- a/src/svg/SkSVGDevice.cpp
+++ b/src/svg/SkSVGDevice.cpp
@@ -7,12 +7,14 @@
#include "SkSVGDevice.h"
+#include "SkBase64.h"
#include "SkBitmap.h"
#include "SkChecksum.h"
+#include "SkData.h"
#include "SkDraw.h"
+#include "SkImageEncoder.h"
#include "SkPaint.h"
#include "SkParsePath.h"
-#include "SkPathOps.h"
#include "SkShader.h"
#include "SkStream.h"
#include "SkTHash.h"
@@ -251,7 +253,7 @@ private:
// and deduplicate resources.
class SkSVGDevice::ResourceBucket : ::SkNoncopyable {
public:
- ResourceBucket() : fGradientCount(0), fClipCount(0), fPathCount(0) {}
+ ResourceBucket() : fGradientCount(0), fClipCount(0), fPathCount(0), fImageCount(0) {}
SkString addLinearGradient() {
return SkStringPrintf("gradient_%d", fGradientCount++);
@@ -265,10 +267,15 @@ public:
return SkStringPrintf("path_%d", fPathCount++);
}
+ SkString addImage() {
+ return SkStringPrintf("img_%d", fImageCount++);
+ }
+
private:
uint32_t fGradientCount;
uint32_t fClipCount;
uint32_t fPathCount;
+ uint32_t fImageCount;
};
class SkSVGDevice::AutoElement : ::SkNoncopyable {
@@ -285,6 +292,12 @@ public:
, fResourceBucket(bucket) {
Resources res = this->addResources(draw, paint);
+ if (!res.fClip.isEmpty()) {
+ // The clip is in device space. Apply it via a <g> wrapper to avoid local transform
+ // interference.
+ fClipGroup.reset(SkNEW_ARGS(AutoElement, ("g", fWriter)));
+ fClipGroup->addAttribute("clip-path",res.fClip);
+ }
fWriter->startElement(name);
@@ -332,8 +345,9 @@ private:
SkString addLinearGradientDef(const SkShader::GradientInfo& info, const SkShader* shader);
- SkXMLWriter* fWriter;
- ResourceBucket* fResourceBucket;
+ SkXMLWriter* fWriter;
+ ResourceBucket* fResourceBucket;
+ SkAutoTDelete<AutoElement> fClipGroup;
};
void SkSVGDevice::AutoElement::addPaint(const SkPaint& paint, const Resources& resources) {
@@ -379,10 +393,6 @@ void SkSVGDevice::AutoElement::addPaint(const SkPaint& paint, const Resources& r
SkASSERT(style == SkPaint::kFill_Style);
this->addAttribute("stroke", "none");
}
-
- if (!resources.fClip.isEmpty()) {
- this->addAttribute("clip-path", resources.fClip);
- }
}
Resources SkSVGDevice::AutoElement::addResources(const SkDraw& draw, const SkPaint& paint) {
@@ -629,23 +639,82 @@ void SkSVGDevice::drawPath(const SkDraw& draw, const SkPath& path, const SkPaint
elem.addPathAttributes(path);
}
-void SkSVGDevice::drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+void SkSVGDevice::drawBitmapCommon(const SkDraw& draw, const SkBitmap& bm,
+ const SkPaint& paint) {
+ SkAutoTUnref<const SkData> pngData(
+ SkImageEncoder::EncodeData(bm, SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality));
+ if (!pngData) {
+ return;
+ }
+
+ size_t b64Size = SkBase64::Encode(pngData->data(), pngData->size(), NULL);
+ SkAutoTMalloc<char> b64Data(b64Size);
+ SkBase64::Encode(pngData->data(), pngData->size(), b64Data.get());
+
+ SkString svgImageData("data:image/png;base64,");
+ svgImageData.append(b64Data.get(), b64Size);
+
+ SkString imageID = fResourceBucket->addImage();
+ {
+ AutoElement defs("defs", fWriter);
+ {
+ AutoElement image("image", fWriter);
+ image.addAttribute("id", imageID);
+ image.addAttribute("width", bm.width());
+ image.addAttribute("height", bm.height());
+ image.addAttribute("xlink:href", svgImageData);
+ }
+ }
+
+ {
+ AutoElement imageUse("use", fWriter, fResourceBucket, draw, paint);
+ imageUse.addAttribute("xlink:href", SkStringPrintf("#%s", imageID.c_str()));
+ }
+}
+
+void SkSVGDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
const SkMatrix& matrix, const SkPaint& paint) {
- // todo
- SkDebugf("unsupported operation: drawBitmap()\n");
+ SkMatrix adjustedMatrix = *draw.fMatrix;
+ adjustedMatrix.preConcat(matrix);
+ SkDraw adjustedDraw(draw);
+ adjustedDraw.fMatrix = &adjustedMatrix;
+
+ drawBitmapCommon(adjustedDraw, bitmap, paint);
}
-void SkSVGDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap,
+void SkSVGDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
int x, int y, const SkPaint& paint) {
- // todo
- SkDebugf("unsupported operation: drawSprite()\n");
+ SkMatrix adjustedMatrix = *draw.fMatrix;
+ adjustedMatrix.preTranslate(SkIntToScalar(x), SkIntToScalar(y));
+ SkDraw adjustedDraw(draw);
+ adjustedDraw.fMatrix = &adjustedMatrix;
+
+ drawBitmapCommon(adjustedDraw, bitmap, paint);
}
-void SkSVGDevice::drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect* srcOrNull,
+void SkSVGDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bm, const SkRect* srcOrNull,
const SkRect& dst, const SkPaint& paint,
- SkCanvas::DrawBitmapRectFlags flags) {
- // todo
- SkDebugf("unsupported operation: drawBitmapRect()\n");
+ SkCanvas::DrawBitmapRectFlags) {
+ SkMatrix adjustedMatrix;
+ adjustedMatrix.setRectToRect(srcOrNull ? *srcOrNull : SkRect::Make(bm.bounds()),
+ dst,
+ SkMatrix::kFill_ScaleToFit);
+ adjustedMatrix.postConcat(*draw.fMatrix);
+
+ SkDraw adjustedDraw(draw);
+ adjustedDraw.fMatrix = &adjustedMatrix;
+
+ SkClipStack adjustedClipStack;
+ if (srcOrNull && *srcOrNull != SkRect::Make(bm.bounds())) {
+ SkRect devClipRect;
+ draw.fMatrix->mapRect(&devClipRect, dst);
+
+ adjustedClipStack = *draw.fClipStack;
+ adjustedClipStack.clipDevRect(devClipRect, SkRegion::kIntersect_Op, paint.isAntiAlias());
+ adjustedDraw.fClipStack = &adjustedClipStack;
+ }
+
+ drawBitmapCommon(adjustedDraw, bm, paint);
}
void SkSVGDevice::drawText(const SkDraw& draw, const void* text, size_t len,
« no previous file with comments | « src/svg/SkSVGDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698