fmalita | 6ceef3d | 2016-07-26 18:46:34 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2016 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | #ifndef SkSVGRenderContext_DEFINED |
| 9 | #define SkSVGRenderContext_DEFINED |
| 10 | |
| 11 | #include "SkPaint.h" |
Florin Malita | 7d52988 | 2016-12-08 16:04:24 -0500 | [diff] [blame] | 12 | #include "SkPath.h" |
fmalita | 397a517 | 2016-08-08 11:38:55 -0700 | [diff] [blame] | 13 | #include "SkRect.h" |
| 14 | #include "SkSize.h" |
fmalita | 2d961e0 | 2016-08-11 09:16:29 -0700 | [diff] [blame] | 15 | #include "SkSVGAttribute.h" |
fmalita | 28d5b72 | 2016-09-12 17:06:47 -0700 | [diff] [blame] | 16 | #include "SkSVGIDMapper.h" |
fmalita | 6ceef3d | 2016-07-26 18:46:34 -0700 | [diff] [blame] | 17 | #include "SkTLazy.h" |
fmalita | 397a517 | 2016-08-08 11:38:55 -0700 | [diff] [blame] | 18 | #include "SkTypes.h" |
fmalita | 6ceef3d | 2016-07-26 18:46:34 -0700 | [diff] [blame] | 19 | |
fmalita | 397a517 | 2016-08-08 11:38:55 -0700 | [diff] [blame] | 20 | class SkCanvas; |
fmalita | bffc256 | 2016-08-03 10:21:11 -0700 | [diff] [blame] | 21 | class SkSVGLength; |
| 22 | |
| 23 | class SkSVGLengthContext { |
| 24 | public: |
fmalita | 280e282 | 2016-08-17 14:51:03 -0700 | [diff] [blame] | 25 | SkSVGLengthContext(const SkSize& viewport, SkScalar dpi = 90) |
| 26 | : fViewport(viewport), fDPI(dpi) {} |
fmalita | bffc256 | 2016-08-03 10:21:11 -0700 | [diff] [blame] | 27 | |
| 28 | enum class LengthType { |
| 29 | kHorizontal, |
| 30 | kVertical, |
| 31 | kOther, |
| 32 | }; |
| 33 | |
fmalita | 397a517 | 2016-08-08 11:38:55 -0700 | [diff] [blame] | 34 | const SkSize& viewPort() const { return fViewport; } |
fmalita | bffc256 | 2016-08-03 10:21:11 -0700 | [diff] [blame] | 35 | void setViewPort(const SkSize& viewport) { fViewport = viewport; } |
| 36 | |
| 37 | SkScalar resolve(const SkSVGLength&, LengthType) const; |
fmalita | 397a517 | 2016-08-08 11:38:55 -0700 | [diff] [blame] | 38 | SkRect resolveRect(const SkSVGLength& x, const SkSVGLength& y, |
| 39 | const SkSVGLength& w, const SkSVGLength& h) const; |
fmalita | bffc256 | 2016-08-03 10:21:11 -0700 | [diff] [blame] | 40 | |
| 41 | private: |
fmalita | 280e282 | 2016-08-17 14:51:03 -0700 | [diff] [blame] | 42 | SkSize fViewport; |
| 43 | SkScalar fDPI; |
fmalita | bffc256 | 2016-08-03 10:21:11 -0700 | [diff] [blame] | 44 | }; |
fmalita | 6ceef3d | 2016-07-26 18:46:34 -0700 | [diff] [blame] | 45 | |
fmalita | 2d961e0 | 2016-08-11 09:16:29 -0700 | [diff] [blame] | 46 | struct SkSVGPresentationContext { |
fmalita | 397a517 | 2016-08-08 11:38:55 -0700 | [diff] [blame] | 47 | SkSVGPresentationContext(); |
fmalita | 2d961e0 | 2016-08-11 09:16:29 -0700 | [diff] [blame] | 48 | SkSVGPresentationContext(const SkSVGPresentationContext&) = default; |
| 49 | SkSVGPresentationContext& operator=(const SkSVGPresentationContext&) = default; |
fmalita | bffc256 | 2016-08-03 10:21:11 -0700 | [diff] [blame] | 50 | |
fmalita | 2d961e0 | 2016-08-11 09:16:29 -0700 | [diff] [blame] | 51 | // Inherited presentation attributes, computed for the current node. |
| 52 | SkSVGPresentationAttributes fInherited; |
fmalita | 6ceef3d | 2016-07-26 18:46:34 -0700 | [diff] [blame] | 53 | |
fmalita | 2d961e0 | 2016-08-11 09:16:29 -0700 | [diff] [blame] | 54 | // Cached paints, reflecting the current presentation attributes. |
| 55 | SkPaint fFillPaint; |
| 56 | SkPaint fStrokePaint; |
fmalita | 397a517 | 2016-08-08 11:38:55 -0700 | [diff] [blame] | 57 | }; |
| 58 | |
| 59 | class SkSVGRenderContext { |
| 60 | public: |
fmalita | 28d5b72 | 2016-09-12 17:06:47 -0700 | [diff] [blame] | 61 | SkSVGRenderContext(SkCanvas*, const SkSVGIDMapper&, const SkSVGLengthContext&, |
| 62 | const SkSVGPresentationContext&); |
fmalita | 397a517 | 2016-08-08 11:38:55 -0700 | [diff] [blame] | 63 | SkSVGRenderContext(const SkSVGRenderContext&); |
Florin Malita | 1aa1bb6 | 2017-10-11 14:34:33 -0400 | [diff] [blame] | 64 | SkSVGRenderContext(const SkSVGRenderContext&, SkCanvas*); |
fmalita | 397a517 | 2016-08-08 11:38:55 -0700 | [diff] [blame] | 65 | ~SkSVGRenderContext(); |
| 66 | |
| 67 | const SkSVGLengthContext& lengthContext() const { return *fLengthContext; } |
| 68 | SkSVGLengthContext* writableLengthContext() { return fLengthContext.writable(); } |
| 69 | |
Florin Malita | e932d4b | 2016-12-01 13:35:11 -0500 | [diff] [blame] | 70 | const SkSVGPresentationContext& presentationContext() const { return *fPresentationContext; } |
| 71 | |
fmalita | 397a517 | 2016-08-08 11:38:55 -0700 | [diff] [blame] | 72 | SkCanvas* canvas() const { return fCanvas; } |
Florin Malita | b36be14 | 2017-10-11 14:11:16 -0400 | [diff] [blame] | 73 | void saveOnce(); |
fmalita | 397a517 | 2016-08-08 11:38:55 -0700 | [diff] [blame] | 74 | |
fmalita | bef51c2 | 2016-09-20 15:45:57 -0700 | [diff] [blame] | 75 | enum ApplyFlags { |
| 76 | kLeaf = 1 << 0, // the target node doesn't have descendants |
| 77 | }; |
| 78 | void applyPresentationAttributes(const SkSVGPresentationAttributes&, uint32_t flags); |
fmalita | 2d961e0 | 2016-08-11 09:16:29 -0700 | [diff] [blame] | 79 | |
fmalita | 28d5b72 | 2016-09-12 17:06:47 -0700 | [diff] [blame] | 80 | const SkSVGNode* findNodeById(const SkString&) const; |
| 81 | |
fmalita | 2d961e0 | 2016-08-11 09:16:29 -0700 | [diff] [blame] | 82 | const SkPaint* fillPaint() const; |
| 83 | const SkPaint* strokePaint() const; |
| 84 | |
Florin Malita | 7d52988 | 2016-12-08 16:04:24 -0500 | [diff] [blame] | 85 | // The local computed clip path (not inherited). |
| 86 | const SkPath* clipPath() const { return fClipPath.getMaybeNull(); } |
| 87 | |
fmalita | 397a517 | 2016-08-08 11:38:55 -0700 | [diff] [blame] | 88 | private: |
| 89 | // Stack-only |
| 90 | void* operator new(size_t) = delete; |
| 91 | void* operator new(size_t, void*) = delete; |
| 92 | SkSVGRenderContext& operator=(const SkSVGRenderContext&) = delete; |
| 93 | |
fmalita | bef51c2 | 2016-09-20 15:45:57 -0700 | [diff] [blame] | 94 | void applyOpacity(SkScalar opacity, uint32_t flags); |
Florin Malita | ce8840e | 2016-12-08 09:26:47 -0500 | [diff] [blame] | 95 | void applyClip(const SkSVGClip&); |
fmalita | bef51c2 | 2016-09-20 15:45:57 -0700 | [diff] [blame] | 96 | |
fmalita | 28d5b72 | 2016-09-12 17:06:47 -0700 | [diff] [blame] | 97 | const SkSVGIDMapper& fIDMapper; |
fmalita | 397a517 | 2016-08-08 11:38:55 -0700 | [diff] [blame] | 98 | SkTCopyOnFirstWrite<SkSVGLengthContext> fLengthContext; |
| 99 | SkTCopyOnFirstWrite<SkSVGPresentationContext> fPresentationContext; |
| 100 | SkCanvas* fCanvas; |
| 101 | // The save count on 'fCanvas' at construction time. |
| 102 | // A restoreToCount() will be issued on destruction. |
| 103 | int fCanvasSaveCount; |
Florin Malita | 7d52988 | 2016-12-08 16:04:24 -0500 | [diff] [blame] | 104 | |
| 105 | // clipPath, if present for the current context (not inherited). |
| 106 | SkTLazy<SkPath> fClipPath; |
fmalita | 6ceef3d | 2016-07-26 18:46:34 -0700 | [diff] [blame] | 107 | }; |
| 108 | |
| 109 | #endif // SkSVGRenderContext_DEFINED |