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

Side by Side 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: Win build fix 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkCanvas.h" 8 #include "SkCanvas.h"
9 #include "SkSVGAttribute.h"
9 #include "SkSVGRenderContext.h" 10 #include "SkSVGRenderContext.h"
10 #include "SkSVGTypes.h" 11 #include "SkSVGTypes.h"
11 12
12 namespace { 13 namespace {
13 14
14 SkScalar length_size_for_type(const SkSize& viewport, SkSVGLengthContext::Length Type t) { 15 SkScalar length_size_for_type(const SkSize& viewport, SkSVGLengthContext::Length Type t) {
15 switch (t) { 16 switch (t) {
16 case SkSVGLengthContext::LengthType::kHorizontal: 17 case SkSVGLengthContext::LengthType::kHorizontal:
17 return viewport.width(); 18 return viewport.width();
18 case SkSVGLengthContext::LengthType::kVertical: 19 case SkSVGLengthContext::LengthType::kVertical:
19 return viewport.height(); 20 return viewport.height();
20 case SkSVGLengthContext::LengthType::kOther: 21 case SkSVGLengthContext::LengthType::kOther:
21 return SkScalarSqrt(viewport.width() * viewport.height()); 22 return SkScalarSqrt(viewport.width() * viewport.height());
22 } 23 }
23 24
24 SkASSERT(false); // Not reached. 25 SkASSERT(false); // Not reached.
25 return 0; 26 return 0;
26 } 27 }
27 28
28 } // anonymous ns 29 } // anonymous ns
29 30
30 SkScalar SkSVGLengthContext::resolve(const SkSVGLength& l, LengthType t) const { 31 SkScalar SkSVGLengthContext::resolve(const SkSVGLength& l, LengthType t) const {
31 switch (l.unit()) { 32 switch (l.unit()) {
robertphillips 2016/08/11 13:38:54 // fall through ?
f(malita) 2016/08/11 14:03:16 Done.
32 case SkSVGLength::Unit::kNumber: 33 case SkSVGLength::Unit::kNumber:
34 case SkSVGLength::Unit::kPX:
33 return l.value(); 35 return l.value();
34 break; 36 break;
35 case SkSVGLength::Unit::kPercentage: 37 case SkSVGLength::Unit::kPercentage:
36 return l.value() * length_size_for_type(fViewport, t) / 100; 38 return l.value() * length_size_for_type(fViewport, t) / 100;
37 break; 39 break;
38 default: 40 default:
39 SkDebugf("unsupported unit type: <%d>\n", l.unit()); 41 SkDebugf("unsupported unit type: <%d>\n", l.unit());
40 break; 42 break;
41 } 43 }
42 44
43 return 0; 45 return 0;
44 } 46 }
45 47
46 SkRect SkSVGLengthContext::resolveRect(const SkSVGLength& x, const SkSVGLength& y, 48 SkRect SkSVGLengthContext::resolveRect(const SkSVGLength& x, const SkSVGLength& y,
47 const SkSVGLength& w, const SkSVGLength& h) const { 49 const SkSVGLength& w, const SkSVGLength& h) const {
48 return SkRect::MakeXYWH( 50 return SkRect::MakeXYWH(
49 this->resolve(x, SkSVGLengthContext::LengthType::kHorizontal), 51 this->resolve(x, SkSVGLengthContext::LengthType::kHorizontal),
50 this->resolve(y, SkSVGLengthContext::LengthType::kVertical), 52 this->resolve(y, SkSVGLengthContext::LengthType::kVertical),
51 this->resolve(w, SkSVGLengthContext::LengthType::kHorizontal), 53 this->resolve(w, SkSVGLengthContext::LengthType::kHorizontal),
52 this->resolve(h, SkSVGLengthContext::LengthType::kVertical)); 54 this->resolve(h, SkSVGLengthContext::LengthType::kVertical));
53 } 55 }
54 56
55 SkSVGPresentationContext::SkSVGPresentationContext() {} 57 namespace {
56 58
57 SkSVGPresentationContext::SkSVGPresentationContext(const SkSVGPresentationContex t& o) { 59 SkPaint::Cap toSkCap(const SkSVGLineCap& cap) {
58 this->initFrom(o); 60 switch (cap.type()) {
59 } 61 case SkSVGLineCap::Type::kButt:
60 62 return SkPaint::kButt_Cap;
61 SkSVGPresentationContext& SkSVGPresentationContext::operator=(const SkSVGPresent ationContext& o) { 63 case SkSVGLineCap::Type::kRound:
62 this->initFrom(o); 64 return SkPaint::kRound_Cap;
63 return *this; 65 case SkSVGLineCap::Type::kSquare:
64 } 66 return SkPaint::kSquare_Cap;
65 67 default:
66 void SkSVGPresentationContext::initFrom(const SkSVGPresentationContext& other) { 68 SkASSERT(false);
67 if (other.fFill.isValid()) { 69 return SkPaint::kButt_Cap;
68 fFill.set(*other.fFill.get());
69 } else {
70 fFill.reset();
71 }
72
73 if (other.fStroke.isValid()) {
74 fStroke.set(*other.fStroke.get());
75 } else {
76 fStroke.reset();
77 } 70 }
78 } 71 }
79 72
80 SkPaint& SkSVGPresentationContext::ensureFill() { 73 SkPaint::Join toSkJoin(const SkSVGLineJoin& join) {
81 if (!fFill.isValid()) { 74 switch (join.type()) {
82 fFill.init(); 75 case SkSVGLineJoin::Type::kMiter:
83 fFill.get()->setStyle(SkPaint::kFill_Style); 76 return SkPaint::kMiter_Join;
84 fFill.get()->setAntiAlias(true); 77 case SkSVGLineJoin::Type::kRound:
78 return SkPaint::kRound_Join;
79 case SkSVGLineJoin::Type::kBevel:
80 return SkPaint::kBevel_Join;
81 default:
82 SkASSERT(false);
83 return SkPaint::kMiter_Join;
85 } 84 }
86 return *fFill.get();
87 } 85 }
88 86
89 SkPaint& SkSVGPresentationContext::ensureStroke() { 87 void applySvgPaint(const SkSVGPaint& svgPaint, SkPaint* p) {
90 if (!fStroke.isValid()) { 88 switch (svgPaint.type()) {
91 fStroke.init(); 89 case SkSVGPaint::Type::kColor:
92 fStroke.get()->setStyle(SkPaint::kStroke_Style); 90 p->setColor(SkColorSetA(svgPaint.color(), p->getAlpha()));
93 fStroke.get()->setAntiAlias(true); 91 break;
92 case SkSVGPaint::Type::kCurrentColor:
93 SkDebugf("unimplemented 'currentColor' paint type");
94 // Fall through.
95 case SkSVGPaint::Type::kNone:
96 // Fall through.
97 case SkSVGPaint::Type::kInherit:
98 break;
94 } 99 }
95 return *fStroke.get();
96 } 100 }
97 101
98 void SkSVGPresentationContext::setFillColor(SkColor color) { 102 // Commit the selected attribute to the paint cache.
99 this->ensureFill().setColor(color); 103 template <SkSVGAttribute>
104 void commitToPaint(const SkSVGPresentationAttributes&,
105 const SkSVGLengthContext&,
106 SkSVGPresentationContext*);
107
108 template <>
109 void commitToPaint<SkSVGAttribute::kFill>(const SkSVGPresentationAttributes& att rs,
110 const SkSVGLengthContext&,
111 SkSVGPresentationContext* pctx) {
112 applySvgPaint(*attrs.fFill.get(), &pctx->fFillPaint);
100 } 113 }
101 114
102 void SkSVGPresentationContext::setStrokeColor(SkColor color) { 115 template <>
103 this->ensureStroke().setColor(color); 116 void commitToPaint<SkSVGAttribute::kStroke>(const SkSVGPresentationAttributes& a ttrs,
117 const SkSVGLengthContext&,
118 SkSVGPresentationContext* pctx) {
119 applySvgPaint(*attrs.fStroke.get(), &pctx->fStrokePaint);
120 }
121
122 template <>
123 void commitToPaint<SkSVGAttribute::kFillOpacity>(const SkSVGPresentationAttribut es& attrs,
124 const SkSVGLengthContext&,
125 SkSVGPresentationContext* pctx) {
126 pctx->fFillPaint.setAlpha(static_cast<uint8_t>(*attrs.fFillOpacity.get() * 2 55));
127 }
128
129 template <>
130 void commitToPaint<SkSVGAttribute::kStrokeLineCap>(const SkSVGPresentationAttrib utes& attrs,
131 const SkSVGLengthContext&,
132 SkSVGPresentationContext* pct x) {
133 const auto& cap = *attrs.fStrokeLineCap.get();
134 if (cap.type() != SkSVGLineCap::Type::kInherit) {
135 pctx->fStrokePaint.setStrokeCap(toSkCap(cap));
136 }
137 }
138
139 template <>
140 void commitToPaint<SkSVGAttribute::kStrokeLineJoin>(const SkSVGPresentationAttri butes& attrs,
141 const SkSVGLengthContext&,
142 SkSVGPresentationContext* pc tx) {
143 const auto& join = *attrs.fStrokeLineJoin.get();
144 if (join.type() != SkSVGLineJoin::Type::kInherit) {
145 pctx->fStrokePaint.setStrokeJoin(toSkJoin(join));
146 }
147 }
148
149 template <>
150 void commitToPaint<SkSVGAttribute::kStrokeOpacity>(const SkSVGPresentationAttrib utes& attrs,
151 const SkSVGLengthContext&,
152 SkSVGPresentationContext* pct x) {
153 pctx->fStrokePaint.setAlpha(static_cast<uint8_t>(*attrs.fStrokeOpacity.get() * 255));
154 }
155
156 template <>
157 void commitToPaint<SkSVGAttribute::kStrokeWidth>(const SkSVGPresentationAttribut es& attrs,
158 const SkSVGLengthContext& lctx,
159 SkSVGPresentationContext* pctx) {
160 auto strokeWidth = lctx.resolve(*attrs.fStrokeWidth.get(),
161 SkSVGLengthContext::LengthType::kOther);
162 pctx->fStrokePaint.setStrokeWidth(strokeWidth);
163 }
164
165 } // anonymous ns
166
167 SkSVGPresentationContext::SkSVGPresentationContext()
168 : fInherited(SkSVGPresentationAttributes::MakeInitial()) {
169
170 fFillPaint.setStyle(SkPaint::kFill_Style);
171 fStrokePaint.setStyle(SkPaint::kStroke_Style);
172
173 // TODO: drive AA off presentation attrs also (shape-rendering?)
174 fFillPaint.setAntiAlias(true);
175 fStrokePaint.setAntiAlias(true);
176
177 // Commit initial values to the paint cache.
178 SkSVGLengthContext dummy(SkSize::Make(0, 0));
179 commitToPaint<SkSVGAttribute::kFill>(fInherited, dummy, this);
180 commitToPaint<SkSVGAttribute::kFillOpacity>(fInherited, dummy, this);
181 commitToPaint<SkSVGAttribute::kStroke>(fInherited, dummy, this);
182 commitToPaint<SkSVGAttribute::kStrokeLineCap>(fInherited, dummy, this);
183 commitToPaint<SkSVGAttribute::kStrokeLineJoin>(fInherited, dummy, this);
184 commitToPaint<SkSVGAttribute::kStrokeOpacity>(fInherited, dummy, this);
185 commitToPaint<SkSVGAttribute::kStrokeWidth>(fInherited, dummy, this);
104 } 186 }
105 187
106 SkSVGRenderContext::SkSVGRenderContext(SkCanvas* canvas, 188 SkSVGRenderContext::SkSVGRenderContext(SkCanvas* canvas,
107 const SkSVGLengthContext& lctx, 189 const SkSVGLengthContext& lctx,
108 const SkSVGPresentationContext& pctx) 190 const SkSVGPresentationContext& pctx)
109 : fLengthContext(lctx) 191 : fLengthContext(lctx)
110 , fPresentationContext(pctx) 192 , fPresentationContext(pctx)
111 , fCanvas(canvas) 193 , fCanvas(canvas)
112 , fCanvasSaveCount(canvas->getSaveCount()) {} 194 , fCanvasSaveCount(canvas->getSaveCount()) {}
113 195
114 SkSVGRenderContext::SkSVGRenderContext(const SkSVGRenderContext& other) 196 SkSVGRenderContext::SkSVGRenderContext(const SkSVGRenderContext& other)
115 : SkSVGRenderContext(other.canvas(), 197 : SkSVGRenderContext(other.fCanvas,
116 other.lengthContext(), 198 *other.fLengthContext,
117 other.presentationContext()) {} 199 *other.fPresentationContext) {}
118 200
119 SkSVGRenderContext::~SkSVGRenderContext() { 201 SkSVGRenderContext::~SkSVGRenderContext() {
120 fCanvas->restoreToCount(fCanvasSaveCount); 202 fCanvas->restoreToCount(fCanvasSaveCount);
121 } 203 }
204
205 void SkSVGRenderContext::applyPresentationAttributes(const SkSVGPresentationAttr ibutes& attrs) {
206
207 #define ApplyLazyInheritedAttribute(ATTR) \
208 do { \
209 /* All attributes should be defined on the inherited context. */ \
210 SkASSERT(fPresentationContext->fInherited.f ## ATTR.isValid()); \
211 const auto* value = attrs.f ## ATTR.getMaybeNull(); \
212 if (value && *value != *fPresentationContext->fInherited.f ## ATTR.get() ) { \
213 /* Update the local attribute value */ \
214 fPresentationContext.writable()->fInherited.f ## ATTR.set(*value); \
215 /* Update the cached paints */ \
216 commitToPaint<SkSVGAttribute::k ## ATTR>(attrs, *fLengthContext, \
217 fPresentationContext.writab le()); \
218 } \
219 } while (false)
220
221 ApplyLazyInheritedAttribute(Fill);
222 ApplyLazyInheritedAttribute(FillOpacity);
223 ApplyLazyInheritedAttribute(Stroke);
224 ApplyLazyInheritedAttribute(StrokeLineCap);
225 ApplyLazyInheritedAttribute(StrokeLineJoin);
226 ApplyLazyInheritedAttribute(StrokeOpacity);
227 ApplyLazyInheritedAttribute(StrokeWidth);
228
229 #undef ApplyLazyInheritedAttribute
230 }
231
232 const SkPaint* SkSVGRenderContext::fillPaint() const {
233 const SkSVGPaint::Type paintType = fPresentationContext->fInherited.fFill.ge t()->type();
234 return paintType != SkSVGPaint::Type::kNone ? &fPresentationContext->fFillPa int : nullptr;
235 }
236
237 const SkPaint* SkSVGRenderContext::strokePaint() const {
238 const SkSVGPaint::Type paintType = fPresentationContext->fInherited.fStroke. get()->type();
239 return paintType != SkSVGPaint::Type::kNone ? &fPresentationContext->fStroke Paint : nullptr;
240 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698