aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental/svg/model/SkSVGRenderContext.cpp
diff options
context:
space:
mode:
authorGravatar fmalita <fmalita@chromium.org>2016-09-12 17:06:47 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-09-12 17:06:47 -0700
commit28d5b72d86fdfae20dc47ba548748f119c7273e3 (patch)
tree579d10ae07a10a882ca68d00c2da6fa407c0c658 /experimental/svg/model/SkSVGRenderContext.cpp
parent8c24f4fae3389b9937eb73128e76226cffebdd72 (diff)
[SVGDom] Initial linear gradient support
Kind of a big change, to connect several new bits into something useful: * ID tracking & lookup * new asPaint() node virtual to support shader (and in the future filter) based paint servers * <defs>, <linearGradient> and <stop> element support * 'href', 'offset', 'stop-color', 'stop-opacity' attribute support * IRI/FuncIRI and rgb(...) parsing BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2327233003 Review-Url: https://codereview.chromium.org/2327233003
Diffstat (limited to 'experimental/svg/model/SkSVGRenderContext.cpp')
-rw-r--r--experimental/svg/model/SkSVGRenderContext.cpp51
1 files changed, 35 insertions, 16 deletions
diff --git a/experimental/svg/model/SkSVGRenderContext.cpp b/experimental/svg/model/SkSVGRenderContext.cpp
index d8f762142f..46ed5a28c4 100644
--- a/experimental/svg/model/SkSVGRenderContext.cpp
+++ b/experimental/svg/model/SkSVGRenderContext.cpp
@@ -7,6 +7,7 @@
#include "SkCanvas.h"
#include "SkSVGAttribute.h"
+#include "SkSVGNode.h"
#include "SkSVGRenderContext.h"
#include "SkSVGTypes.h"
@@ -98,11 +99,18 @@ SkPaint::Join toSkJoin(const SkSVGLineJoin& join) {
}
}
-void applySvgPaint(const SkSVGPaint& svgPaint, SkPaint* p) {
+void applySvgPaint(const SkSVGRenderContext& ctx, const SkSVGPaint& svgPaint, SkPaint* p) {
switch (svgPaint.type()) {
case SkSVGPaint::Type::kColor:
p->setColor(SkColorSetA(svgPaint.color(), p->getAlpha()));
break;
+ case SkSVGPaint::Type::kIRI: {
+ const auto* node = ctx.findNodeById(svgPaint.iri());
+ if (!node || !node->asPaint(ctx, p)) {
+ p->setColor(SK_ColorTRANSPARENT);
+ }
+ break;
+ }
case SkSVGPaint::Type::kCurrentColor:
SkDebugf("unimplemented 'currentColor' paint type");
// Fall through.
@@ -120,33 +128,33 @@ inline uint8_t opacity_to_alpha(SkScalar o) {
// Commit the selected attribute to the paint cache.
template <SkSVGAttribute>
void commitToPaint(const SkSVGPresentationAttributes&,
- const SkSVGLengthContext&,
+ const SkSVGRenderContext&,
SkSVGPresentationContext*);
template <>
void commitToPaint<SkSVGAttribute::kFill>(const SkSVGPresentationAttributes& attrs,
- const SkSVGLengthContext&,
+ const SkSVGRenderContext& ctx,
SkSVGPresentationContext* pctx) {
- applySvgPaint(*attrs.fFill.get(), &pctx->fFillPaint);
+ applySvgPaint(ctx, *attrs.fFill.get(), &pctx->fFillPaint);
}
template <>
void commitToPaint<SkSVGAttribute::kStroke>(const SkSVGPresentationAttributes& attrs,
- const SkSVGLengthContext&,
+ const SkSVGRenderContext& ctx,
SkSVGPresentationContext* pctx) {
- applySvgPaint(*attrs.fStroke.get(), &pctx->fStrokePaint);
+ applySvgPaint(ctx, *attrs.fStroke.get(), &pctx->fStrokePaint);
}
template <>
void commitToPaint<SkSVGAttribute::kFillOpacity>(const SkSVGPresentationAttributes& attrs,
- const SkSVGLengthContext&,
+ const SkSVGRenderContext&,
SkSVGPresentationContext* pctx) {
pctx->fFillPaint.setAlpha(opacity_to_alpha(*attrs.fFillOpacity.get()));
}
template <>
void commitToPaint<SkSVGAttribute::kStrokeLineCap>(const SkSVGPresentationAttributes& attrs,
- const SkSVGLengthContext&,
+ const SkSVGRenderContext&,
SkSVGPresentationContext* pctx) {
const auto& cap = *attrs.fStrokeLineCap.get();
if (cap.type() != SkSVGLineCap::Type::kInherit) {
@@ -156,7 +164,7 @@ void commitToPaint<SkSVGAttribute::kStrokeLineCap>(const SkSVGPresentationAttrib
template <>
void commitToPaint<SkSVGAttribute::kStrokeLineJoin>(const SkSVGPresentationAttributes& attrs,
- const SkSVGLengthContext&,
+ const SkSVGRenderContext&,
SkSVGPresentationContext* pctx) {
const auto& join = *attrs.fStrokeLineJoin.get();
if (join.type() != SkSVGLineJoin::Type::kInherit) {
@@ -166,17 +174,17 @@ void commitToPaint<SkSVGAttribute::kStrokeLineJoin>(const SkSVGPresentationAttri
template <>
void commitToPaint<SkSVGAttribute::kStrokeOpacity>(const SkSVGPresentationAttributes& attrs,
- const SkSVGLengthContext&,
+ const SkSVGRenderContext&,
SkSVGPresentationContext* pctx) {
pctx->fStrokePaint.setAlpha(opacity_to_alpha(*attrs.fStrokeOpacity.get()));
}
template <>
void commitToPaint<SkSVGAttribute::kStrokeWidth>(const SkSVGPresentationAttributes& attrs,
- const SkSVGLengthContext& lctx,
+ const SkSVGRenderContext& ctx,
SkSVGPresentationContext* pctx) {
- auto strokeWidth = lctx.resolve(*attrs.fStrokeWidth.get(),
- SkSVGLengthContext::LengthType::kOther);
+ auto strokeWidth = ctx.lengthContext().resolve(*attrs.fStrokeWidth.get(),
+ SkSVGLengthContext::LengthType::kOther);
pctx->fStrokePaint.setStrokeWidth(strokeWidth);
}
@@ -193,7 +201,10 @@ SkSVGPresentationContext::SkSVGPresentationContext()
fStrokePaint.setAntiAlias(true);
// Commit initial values to the paint cache.
- SkSVGLengthContext dummy(SkSize::Make(0, 0));
+ SkCanvas dummyCanvas(0, 0);
+ SkSVGRenderContext dummy(&dummyCanvas, SkSVGIDMapper(), SkSVGLengthContext(SkSize::Make(0, 0)),
+ *this);
+
commitToPaint<SkSVGAttribute::kFill>(fInherited, dummy, this);
commitToPaint<SkSVGAttribute::kFillOpacity>(fInherited, dummy, this);
commitToPaint<SkSVGAttribute::kStroke>(fInherited, dummy, this);
@@ -204,15 +215,18 @@ SkSVGPresentationContext::SkSVGPresentationContext()
}
SkSVGRenderContext::SkSVGRenderContext(SkCanvas* canvas,
+ const SkSVGIDMapper& mapper,
const SkSVGLengthContext& lctx,
const SkSVGPresentationContext& pctx)
- : fLengthContext(lctx)
+ : fIDMapper(mapper)
+ , fLengthContext(lctx)
, fPresentationContext(pctx)
, fCanvas(canvas)
, fCanvasSaveCount(canvas->getSaveCount()) {}
SkSVGRenderContext::SkSVGRenderContext(const SkSVGRenderContext& other)
: SkSVGRenderContext(other.fCanvas,
+ other.fIDMapper,
*other.fLengthContext,
*other.fPresentationContext) {}
@@ -220,6 +234,11 @@ SkSVGRenderContext::~SkSVGRenderContext() {
fCanvas->restoreToCount(fCanvasSaveCount);
}
+const SkSVGNode* SkSVGRenderContext::findNodeById(const SkString& id) const {
+ const auto* v = fIDMapper.find(id);
+ return v ? v->get() : nullptr;
+}
+
void SkSVGRenderContext::applyPresentationAttributes(const SkSVGPresentationAttributes& attrs) {
#define ApplyLazyInheritedAttribute(ATTR) \
@@ -231,7 +250,7 @@ void SkSVGRenderContext::applyPresentationAttributes(const SkSVGPresentationAttr
/* Update the local attribute value */ \
fPresentationContext.writable()->fInherited.f ## ATTR.set(*value); \
/* Update the cached paints */ \
- commitToPaint<SkSVGAttribute::k ## ATTR>(attrs, *fLengthContext, \
+ commitToPaint<SkSVGAttribute::k ## ATTR>(attrs, *this, \
fPresentationContext.writable()); \
} \
} while (false)