diff options
author | Mike Reed <reed@google.com> | 2017-02-17 14:38:11 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-02-17 21:03:43 +0000 |
commit | c5e641cc9947b8b2d3c63f908c7b98fa5b3d0f07 (patch) | |
tree | b17cc0ae0a104ec61876ea932fc3bc4be96b73be /src/svg/SkSVGDevice.cpp | |
parent | 9c58306f87ff342bf30ed645be3332aa6f2b2fee (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.cpp | 102 |
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); |