aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/svg/SkSVGDevice.cpp
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2017-02-17 14:38:11 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-17 21:03:43 +0000
commitc5e641cc9947b8b2d3c63f908c7b98fa5b3d0f07 (patch)
treeb17cc0ae0a104ec61876ea932fc3bc4be96b73be /src/svg/SkSVGDevice.cpp
parent9c58306f87ff342bf30ed645be3332aa6f2b2fee (diff)
use common intermediate device class for clipstack management
BUG=skia:6214 Change-Id: I64b849ad7c8dafe423e24e6fccfb3f0c1d096ab0 Reviewed-on: https://skia-review.googlesource.com/8669 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'src/svg/SkSVGDevice.cpp')
-rw-r--r--src/svg/SkSVGDevice.cpp102
1 files changed, 58 insertions, 44 deletions
diff --git a/src/svg/SkSVGDevice.cpp b/src/svg/SkSVGDevice.cpp
index 06679daf9e..261ad22d6d 100644
--- a/src/svg/SkSVGDevice.cpp
+++ b/src/svg/SkSVGDevice.cpp
@@ -274,6 +274,21 @@ private:
uint32_t fImageCount;
};
+struct SkSVGDevice::MxCp {
+ const SkMatrix* fMatrix;
+ const SkClipStack* fClipStack;
+
+ MxCp(SkSVGDevice* device, const SkDraw& draw) {
+#ifdef SK_USE_DEVICE_CLIPPING
+ fMatrix = &device->ctm();
+ fClipStack = &device->cs();
+#else
+ fMatrix = draw.fMatrix;
+ fClipStack = draw.fClipStack;
+#endif
+ }
+};
+
class SkSVGDevice::AutoElement : ::SkNoncopyable {
public:
AutoElement(const char name[], SkXMLWriter* writer)
@@ -283,11 +298,11 @@ public:
}
AutoElement(const char name[], SkXMLWriter* writer, ResourceBucket* bucket,
- const SkDraw& draw, const SkPaint& paint)
+ const MxCp& mc, const SkPaint& paint)
: fWriter(writer)
, fResourceBucket(bucket) {
- Resources res = this->addResources(draw, paint);
+ Resources res = this->addResources(mc, paint);
if (!res.fClip.isEmpty()) {
// The clip is in device space. Apply it via a <g> wrapper to avoid local transform
// interference.
@@ -299,8 +314,8 @@ public:
this->addPaint(paint, res);
- if (!draw.fMatrix->isIdentity()) {
- this->addAttribute("transform", svg_transform(*draw.fMatrix));
+ if (!mc.fMatrix->isIdentity()) {
+ this->addAttribute("transform", svg_transform(*mc.fMatrix));
}
}
@@ -333,8 +348,8 @@ public:
void addTextAttributes(const SkPaint&);
private:
- Resources addResources(const SkDraw& draw, const SkPaint& paint);
- void addClipResources(const SkDraw& draw, Resources* resources);
+ Resources addResources(const MxCp&, const SkPaint& paint);
+ void addClipResources(const MxCp&, Resources* resources);
void addShaderResources(const SkPaint& paint, Resources* resources);
void addPaint(const SkPaint& paint, const Resources& resources);
@@ -391,18 +406,18 @@ void SkSVGDevice::AutoElement::addPaint(const SkPaint& paint, const Resources& r
}
}
-Resources SkSVGDevice::AutoElement::addResources(const SkDraw& draw, const SkPaint& paint) {
+Resources SkSVGDevice::AutoElement::addResources(const MxCp& mc, const SkPaint& paint) {
Resources resources(paint);
// FIXME: this is a weak heuristic and we end up with LOTS of redundant clips.
- bool hasClip = !draw.fClipStack->isWideOpen();
+ bool hasClip = !mc.fClipStack->isWideOpen();
bool hasShader = SkToBool(paint.getShader());
if (hasClip || hasShader) {
AutoElement defs("defs", fWriter);
if (hasClip) {
- this->addClipResources(draw, &resources);
+ this->addClipResources(mc, &resources);
}
if (hasShader) {
@@ -438,11 +453,11 @@ void SkSVGDevice::AutoElement::addShaderResources(const SkPaint& paint, Resource
resources->fPaintServer.printf("url(#%s)", addLinearGradientDef(grInfo, shader).c_str());
}
-void SkSVGDevice::AutoElement::addClipResources(const SkDraw& draw, Resources* resources) {
- SkASSERT(!draw.fClipStack->isWideOpen());
+void SkSVGDevice::AutoElement::addClipResources(const MxCp& mc, Resources* resources) {
+ SkASSERT(!mc.fClipStack->isWideOpen());
SkPath clipPath;
- (void) draw.fClipStack->asPath(&clipPath);
+ (void) mc.fClipStack->asPath(&clipPath);
SkString clipID = fResourceBucket->addClip();
const char* clipRule = clipPath.getFillType() == SkPath::kEvenOdd_FillType ?
@@ -592,7 +607,7 @@ SkSVGDevice::~SkSVGDevice() {
}
void SkSVGDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
- AutoElement rect("rect", fWriter, fResourceBucket.get(), draw, paint);
+ AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
rect.addRectAttributes(SkRect::MakeWH(SkIntToScalar(this->width()),
SkIntToScalar(this->height())));
}
@@ -612,7 +627,7 @@ void SkSVGDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_
path.rewind();
path.moveTo(pts[i]);
path.lineTo(pts[i+1]);
- AutoElement elem("path", fWriter, fResourceBucket.get(), draw, paint);
+ AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
elem.addPathAttributes(path);
}
break;
@@ -620,7 +635,7 @@ void SkSVGDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_
if (count > 1) {
path.addPoly(pts, SkToInt(count), false);
path.moveTo(pts[0]);
- AutoElement elem("path", fWriter, fResourceBucket.get(), draw, paint);
+ AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
elem.addPathAttributes(path);
}
break;
@@ -628,12 +643,12 @@ void SkSVGDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_
}
void SkSVGDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
- AutoElement rect("rect", fWriter, fResourceBucket.get(), draw, paint);
+ AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
rect.addRectAttributes(r);
}
void SkSVGDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
- AutoElement ellipse("ellipse", fWriter, fResourceBucket.get(), draw, paint);
+ AutoElement ellipse("ellipse", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
ellipse.addAttribute("cx", oval.centerX());
ellipse.addAttribute("cy", oval.centerY());
ellipse.addAttribute("rx", oval.width() / 2);
@@ -644,13 +659,13 @@ void SkSVGDevice::drawRRect(const SkDraw& draw, const SkRRect& rr, const SkPaint
SkPath path;
path.addRRect(rr);
- AutoElement elem("path", fWriter, fResourceBucket.get(), draw, paint);
+ AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
elem.addPathAttributes(path);
}
void SkSVGDevice::drawPath(const SkDraw& draw, const SkPath& path, const SkPaint& paint,
const SkMatrix* prePathMatrix, bool pathIsMutable) {
- AutoElement elem("path", fWriter, fResourceBucket.get(), draw, paint);
+ AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
elem.addPathAttributes(path);
// TODO: inverse fill types?
@@ -664,8 +679,7 @@ static sk_sp<SkData> encode(const SkBitmap& src) {
return SkEncodeImage(&buf, src, SkEncodedImageFormat::kPNG, 80) ? buf.detachAsData() : nullptr;
}
-void SkSVGDevice::drawBitmapCommon(const SkDraw& draw, const SkBitmap& bm,
- const SkPaint& paint) {
+void SkSVGDevice::drawBitmapCommon(const MxCp& mc, const SkBitmap& bm, const SkPaint& paint) {
sk_sp<SkData> pngData = encode(bm);
if (!pngData) {
return;
@@ -691,57 +705,57 @@ void SkSVGDevice::drawBitmapCommon(const SkDraw& draw, const SkBitmap& bm,
}
{
- AutoElement imageUse("use", fWriter, fResourceBucket.get(), draw, paint);
+ AutoElement imageUse("use", fWriter, fResourceBucket.get(), mc, 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) {
- SkMatrix adjustedMatrix = *draw.fMatrix;
+ MxCp mc(this, draw);
+ SkMatrix adjustedMatrix = *mc.fMatrix;
adjustedMatrix.preConcat(matrix);
- SkDraw adjustedDraw(draw);
- adjustedDraw.fMatrix = &adjustedMatrix;
+ mc.fMatrix = &adjustedMatrix;
- drawBitmapCommon(adjustedDraw, bitmap, paint);
+ drawBitmapCommon(mc, bitmap, paint);
}
void SkSVGDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
int x, int y, const SkPaint& paint) {
- SkMatrix adjustedMatrix = *draw.fMatrix;
+ MxCp mc(this, draw);
+ SkMatrix adjustedMatrix = *mc.fMatrix;
adjustedMatrix.preTranslate(SkIntToScalar(x), SkIntToScalar(y));
- SkDraw adjustedDraw(draw);
- adjustedDraw.fMatrix = &adjustedMatrix;
+ mc.fMatrix = &adjustedMatrix;
- drawBitmapCommon(adjustedDraw, bitmap, paint);
+ drawBitmapCommon(mc, bitmap, paint);
}
void SkSVGDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bm, const SkRect* srcOrNull,
const SkRect& dst, const SkPaint& paint,
SkCanvas::SrcRectConstraint) {
- SkMatrix adjustedMatrix;
- adjustedMatrix.setRectToRect(srcOrNull ? *srcOrNull : SkRect::Make(bm.bounds()),
- dst,
- SkMatrix::kFill_ScaleToFit);
- adjustedMatrix.postConcat(*draw.fMatrix);
-
- SkDraw adjustedDraw(draw);
- adjustedDraw.fMatrix = &adjustedMatrix;
+ MxCp mc(this, draw);
SkClipStack adjustedClipStack;
if (srcOrNull && *srcOrNull != SkRect::Make(bm.bounds())) {
- adjustedClipStack = *draw.fClipStack;
- adjustedClipStack.clipRect(dst, *draw.fMatrix, kIntersect_SkClipOp,
+ adjustedClipStack = *mc.fClipStack;
+ adjustedClipStack.clipRect(dst, *mc.fMatrix, kIntersect_SkClipOp,
paint.isAntiAlias());
- adjustedDraw.fClipStack = &adjustedClipStack;
+ mc.fClipStack = &adjustedClipStack;
}
- drawBitmapCommon(adjustedDraw, bm, paint);
+ SkMatrix adjustedMatrix;
+ adjustedMatrix.setRectToRect(srcOrNull ? *srcOrNull : SkRect::Make(bm.bounds()),
+ dst,
+ SkMatrix::kFill_ScaleToFit);
+ adjustedMatrix.postConcat(*mc.fMatrix);
+ mc.fMatrix = &adjustedMatrix;
+
+ drawBitmapCommon(mc, bm, paint);
}
void SkSVGDevice::drawText(const SkDraw& draw, const void* text, size_t len,
SkScalar x, SkScalar y, const SkPaint& paint) {
- AutoElement elem("text", fWriter, fResourceBucket.get(), draw, paint);
+ AutoElement elem("text", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
elem.addTextAttributes(paint);
SVGTextBuilder builder(text, len, paint, SkPoint::Make(x, y), 0);
@@ -755,7 +769,7 @@ void SkSVGDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
const SkPaint& paint) {
SkASSERT(scalarsPerPos == 1 || scalarsPerPos == 2);
- AutoElement elem("text", fWriter, fResourceBucket.get(), draw, paint);
+ AutoElement elem("text", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
elem.addTextAttributes(paint);
SVGTextBuilder builder(text, len, paint, offset, scalarsPerPos, pos);