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

Unified Diff: experimental/svg/model/SkSVGRenderContext.cpp

Issue 2234153002: [SVGDom] Add more presentation attributes. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: review Created 4 years, 4 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 | « experimental/svg/model/SkSVGRenderContext.h ('k') | experimental/svg/model/SkSVGShape.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: experimental/svg/model/SkSVGRenderContext.cpp
diff --git a/experimental/svg/model/SkSVGRenderContext.cpp b/experimental/svg/model/SkSVGRenderContext.cpp
index e902d4ecf3d389018535e941299ef989c1e7bd42..ee92c47d542ea39744f4487e4007f8a5ed916a7c 100644
--- a/experimental/svg/model/SkSVGRenderContext.cpp
+++ b/experimental/svg/model/SkSVGRenderContext.cpp
@@ -6,6 +6,7 @@
*/
#include "SkCanvas.h"
+#include "SkSVGAttribute.h"
#include "SkSVGRenderContext.h"
#include "SkSVGTypes.h"
@@ -30,17 +31,15 @@ SkScalar length_size_for_type(const SkSize& viewport, SkSVGLengthContext::Length
SkScalar SkSVGLengthContext::resolve(const SkSVGLength& l, LengthType t) const {
switch (l.unit()) {
case SkSVGLength::Unit::kNumber:
+ // Fall through.
+ case SkSVGLength::Unit::kPX:
return l.value();
- break;
case SkSVGLength::Unit::kPercentage:
return l.value() * length_size_for_type(fViewport, t) / 100;
- break;
default:
SkDebugf("unsupported unit type: <%d>\n", l.unit());
- break;
+ return 0;
}
-
- return 0;
}
SkRect SkSVGLengthContext::resolveRect(const SkSVGLength& x, const SkSVGLength& y,
@@ -52,55 +51,135 @@ SkRect SkSVGLengthContext::resolveRect(const SkSVGLength& x, const SkSVGLength&
this->resolve(h, SkSVGLengthContext::LengthType::kVertical));
}
-SkSVGPresentationContext::SkSVGPresentationContext() {}
+namespace {
-SkSVGPresentationContext::SkSVGPresentationContext(const SkSVGPresentationContext& o) {
- this->initFrom(o);
+SkPaint::Cap toSkCap(const SkSVGLineCap& cap) {
+ switch (cap.type()) {
+ case SkSVGLineCap::Type::kButt:
+ return SkPaint::kButt_Cap;
+ case SkSVGLineCap::Type::kRound:
+ return SkPaint::kRound_Cap;
+ case SkSVGLineCap::Type::kSquare:
+ return SkPaint::kSquare_Cap;
+ default:
+ SkASSERT(false);
+ return SkPaint::kButt_Cap;
+ }
}
-SkSVGPresentationContext& SkSVGPresentationContext::operator=(const SkSVGPresentationContext& o) {
- this->initFrom(o);
- return *this;
+SkPaint::Join toSkJoin(const SkSVGLineJoin& join) {
+ switch (join.type()) {
+ case SkSVGLineJoin::Type::kMiter:
+ return SkPaint::kMiter_Join;
+ case SkSVGLineJoin::Type::kRound:
+ return SkPaint::kRound_Join;
+ case SkSVGLineJoin::Type::kBevel:
+ return SkPaint::kBevel_Join;
+ default:
+ SkASSERT(false);
+ return SkPaint::kMiter_Join;
+ }
}
-void SkSVGPresentationContext::initFrom(const SkSVGPresentationContext& other) {
- if (other.fFill.isValid()) {
- fFill.set(*other.fFill.get());
- } else {
- fFill.reset();
+void applySvgPaint(const SkSVGPaint& svgPaint, SkPaint* p) {
+ switch (svgPaint.type()) {
+ case SkSVGPaint::Type::kColor:
+ p->setColor(SkColorSetA(svgPaint.color(), p->getAlpha()));
+ break;
+ case SkSVGPaint::Type::kCurrentColor:
+ SkDebugf("unimplemented 'currentColor' paint type");
+ // Fall through.
+ case SkSVGPaint::Type::kNone:
+ // Fall through.
+ case SkSVGPaint::Type::kInherit:
+ break;
}
+}
- if (other.fStroke.isValid()) {
- fStroke.set(*other.fStroke.get());
- } else {
- fStroke.reset();
- }
+// Commit the selected attribute to the paint cache.
+template <SkSVGAttribute>
+void commitToPaint(const SkSVGPresentationAttributes&,
+ const SkSVGLengthContext&,
+ SkSVGPresentationContext*);
+
+template <>
+void commitToPaint<SkSVGAttribute::kFill>(const SkSVGPresentationAttributes& attrs,
+ const SkSVGLengthContext&,
+ SkSVGPresentationContext* pctx) {
+ applySvgPaint(*attrs.fFill.get(), &pctx->fFillPaint);
}
-SkPaint& SkSVGPresentationContext::ensureFill() {
- if (!fFill.isValid()) {
- fFill.init();
- fFill.get()->setStyle(SkPaint::kFill_Style);
- fFill.get()->setAntiAlias(true);
+template <>
+void commitToPaint<SkSVGAttribute::kStroke>(const SkSVGPresentationAttributes& attrs,
+ const SkSVGLengthContext&,
+ SkSVGPresentationContext* pctx) {
+ applySvgPaint(*attrs.fStroke.get(), &pctx->fStrokePaint);
+}
+
+template <>
+void commitToPaint<SkSVGAttribute::kFillOpacity>(const SkSVGPresentationAttributes& attrs,
+ const SkSVGLengthContext&,
+ SkSVGPresentationContext* pctx) {
+ pctx->fFillPaint.setAlpha(static_cast<uint8_t>(*attrs.fFillOpacity.get() * 255));
+}
+
+template <>
+void commitToPaint<SkSVGAttribute::kStrokeLineCap>(const SkSVGPresentationAttributes& attrs,
+ const SkSVGLengthContext&,
+ SkSVGPresentationContext* pctx) {
+ const auto& cap = *attrs.fStrokeLineCap.get();
+ if (cap.type() != SkSVGLineCap::Type::kInherit) {
+ pctx->fStrokePaint.setStrokeCap(toSkCap(cap));
}
- return *fFill.get();
}
-SkPaint& SkSVGPresentationContext::ensureStroke() {
- if (!fStroke.isValid()) {
- fStroke.init();
- fStroke.get()->setStyle(SkPaint::kStroke_Style);
- fStroke.get()->setAntiAlias(true);
+template <>
+void commitToPaint<SkSVGAttribute::kStrokeLineJoin>(const SkSVGPresentationAttributes& attrs,
+ const SkSVGLengthContext&,
+ SkSVGPresentationContext* pctx) {
+ const auto& join = *attrs.fStrokeLineJoin.get();
+ if (join.type() != SkSVGLineJoin::Type::kInherit) {
+ pctx->fStrokePaint.setStrokeJoin(toSkJoin(join));
}
- return *fStroke.get();
}
-void SkSVGPresentationContext::setFillColor(SkColor color) {
- this->ensureFill().setColor(color);
+template <>
+void commitToPaint<SkSVGAttribute::kStrokeOpacity>(const SkSVGPresentationAttributes& attrs,
+ const SkSVGLengthContext&,
+ SkSVGPresentationContext* pctx) {
+ pctx->fStrokePaint.setAlpha(static_cast<uint8_t>(*attrs.fStrokeOpacity.get() * 255));
}
-void SkSVGPresentationContext::setStrokeColor(SkColor color) {
- this->ensureStroke().setColor(color);
+template <>
+void commitToPaint<SkSVGAttribute::kStrokeWidth>(const SkSVGPresentationAttributes& attrs,
+ const SkSVGLengthContext& lctx,
+ SkSVGPresentationContext* pctx) {
+ auto strokeWidth = lctx.resolve(*attrs.fStrokeWidth.get(),
+ SkSVGLengthContext::LengthType::kOther);
+ pctx->fStrokePaint.setStrokeWidth(strokeWidth);
+}
+
+} // anonymous ns
+
+SkSVGPresentationContext::SkSVGPresentationContext()
+ : fInherited(SkSVGPresentationAttributes::MakeInitial()) {
+
+ fFillPaint.setStyle(SkPaint::kFill_Style);
+ fStrokePaint.setStyle(SkPaint::kStroke_Style);
+
+ // TODO: drive AA off presentation attrs also (shape-rendering?)
+ fFillPaint.setAntiAlias(true);
+ fStrokePaint.setAntiAlias(true);
+
+ // Commit initial values to the paint cache.
+ SkSVGLengthContext dummy(SkSize::Make(0, 0));
+ commitToPaint<SkSVGAttribute::kFill>(fInherited, dummy, this);
+ commitToPaint<SkSVGAttribute::kFillOpacity>(fInherited, dummy, this);
+ commitToPaint<SkSVGAttribute::kStroke>(fInherited, dummy, this);
+ commitToPaint<SkSVGAttribute::kStrokeLineCap>(fInherited, dummy, this);
+ commitToPaint<SkSVGAttribute::kStrokeLineJoin>(fInherited, dummy, this);
+ commitToPaint<SkSVGAttribute::kStrokeOpacity>(fInherited, dummy, this);
+ commitToPaint<SkSVGAttribute::kStrokeWidth>(fInherited, dummy, this);
}
SkSVGRenderContext::SkSVGRenderContext(SkCanvas* canvas,
@@ -112,10 +191,47 @@ SkSVGRenderContext::SkSVGRenderContext(SkCanvas* canvas,
, fCanvasSaveCount(canvas->getSaveCount()) {}
SkSVGRenderContext::SkSVGRenderContext(const SkSVGRenderContext& other)
- : SkSVGRenderContext(other.canvas(),
- other.lengthContext(),
- other.presentationContext()) {}
+ : SkSVGRenderContext(other.fCanvas,
+ *other.fLengthContext,
+ *other.fPresentationContext) {}
SkSVGRenderContext::~SkSVGRenderContext() {
fCanvas->restoreToCount(fCanvasSaveCount);
}
+
+void SkSVGRenderContext::applyPresentationAttributes(const SkSVGPresentationAttributes& attrs) {
+
+#define ApplyLazyInheritedAttribute(ATTR) \
+ do { \
+ /* All attributes should be defined on the inherited context. */ \
+ SkASSERT(fPresentationContext->fInherited.f ## ATTR.isValid()); \
+ const auto* value = attrs.f ## ATTR.getMaybeNull(); \
+ if (value && *value != *fPresentationContext->fInherited.f ## ATTR.get()) { \
+ /* Update the local attribute value */ \
+ fPresentationContext.writable()->fInherited.f ## ATTR.set(*value); \
+ /* Update the cached paints */ \
+ commitToPaint<SkSVGAttribute::k ## ATTR>(attrs, *fLengthContext, \
+ fPresentationContext.writable()); \
+ } \
+ } while (false)
+
+ ApplyLazyInheritedAttribute(Fill);
+ ApplyLazyInheritedAttribute(FillOpacity);
+ ApplyLazyInheritedAttribute(Stroke);
+ ApplyLazyInheritedAttribute(StrokeLineCap);
+ ApplyLazyInheritedAttribute(StrokeLineJoin);
+ ApplyLazyInheritedAttribute(StrokeOpacity);
+ ApplyLazyInheritedAttribute(StrokeWidth);
+
+#undef ApplyLazyInheritedAttribute
+}
+
+const SkPaint* SkSVGRenderContext::fillPaint() const {
+ const SkSVGPaint::Type paintType = fPresentationContext->fInherited.fFill.get()->type();
+ return paintType != SkSVGPaint::Type::kNone ? &fPresentationContext->fFillPaint : nullptr;
+}
+
+const SkPaint* SkSVGRenderContext::strokePaint() const {
+ const SkSVGPaint::Type paintType = fPresentationContext->fInherited.fStroke.get()->type();
+ return paintType != SkSVGPaint::Type::kNone ? &fPresentationContext->fStrokePaint : nullptr;
+}
« no previous file with comments | « experimental/svg/model/SkSVGRenderContext.h ('k') | experimental/svg/model/SkSVGShape.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698