1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef LAYOUT_SVG_SVGIMAGECONTEXT_H_
8 #define LAYOUT_SVG_SVGIMAGECONTEXT_H_
10 #include "mozilla/Maybe.h"
11 #include "mozilla/SVGContextPaint.h"
12 #include "mozilla/SVGPreserveAspectRatio.h"
16 class nsISVGPaintContext
;
20 enum class ColorScheme
: uint8_t;
23 // SVG image-specific rendering context. For imgIContainer::Draw.
24 // Used to pass information such as
25 // - viewport and color-scheme information from CSS, and
26 // - overridden attributes from an SVG <image> element
27 // to the image's internal SVG document when it's drawn.
28 class SVGImageContext
{
30 SVGImageContext() = default;
33 * Currently it seems that the aViewportSize parameter ends up being used
34 * for different things by different pieces of code, and probably in some
35 * cases being used incorrectly (specifically in the case of pixel snapping
36 * under the nsLayoutUtils::Draw*Image() methods). An unfortunate result of
37 * the messy code is that aViewportSize is currently a Maybe<T> since it
38 * is difficult to create a utility function that consumers can use up
39 * front to get the "correct" viewport size (i.e. which for compatibility
40 * with the current code (bugs and all) would mean the size including all
41 * the snapping and resizing magic that happens in various places under the
42 * nsLayoutUtils::Draw*Image() methods on the way to DrawImageInternal
43 * creating |fallbackContext|). Using Maybe<T> allows code to pass Nothing()
44 * in order to get the size that's created for |fallbackContext|. At some
45 * point we need to clean this code up, make our abstractions clear, create
46 * that utility and stop using Maybe for this parameter.
48 explicit SVGImageContext(
49 const Maybe
<CSSIntSize
>& aViewportSize
,
50 const Maybe
<SVGPreserveAspectRatio
>& aPreserveAspectRatio
= Nothing(),
51 const Maybe
<ColorScheme
>& aColorScheme
= Nothing())
52 : mViewportSize(aViewportSize
),
53 mPreserveAspectRatio(aPreserveAspectRatio
),
54 mColorScheme(aColorScheme
) {}
56 static void MaybeStoreContextPaint(SVGImageContext
& aContext
,
58 imgIContainer
* aImgContainer
);
60 static void MaybeStoreContextPaint(SVGImageContext
& aContext
,
61 const nsPresContext
&, const ComputedStyle
&,
64 static void MaybeStoreContextPaint(SVGImageContext
& aContext
,
65 nsISVGPaintContext
* aPaintContext
,
66 imgIContainer
* aImgContainer
);
68 const Maybe
<CSSIntSize
>& GetViewportSize() const { return mViewportSize
; }
70 void SetViewportSize(const Maybe
<CSSIntSize
>& aSize
) {
71 mViewportSize
= aSize
;
74 const Maybe
<ColorScheme
>& GetColorScheme() const { return mColorScheme
; }
76 void SetColorScheme(const Maybe
<ColorScheme
>& aScheme
) {
77 mColorScheme
= aScheme
;
80 const Maybe
<SVGPreserveAspectRatio
>& GetPreserveAspectRatio() const {
81 return mPreserveAspectRatio
;
84 void SetPreserveAspectRatio(const Maybe
<SVGPreserveAspectRatio
>& aPAR
) {
85 mPreserveAspectRatio
= aPAR
;
88 const SVGEmbeddingContextPaint
* GetContextPaint() const {
89 return mContextPaint
.get();
92 SVGEmbeddingContextPaint
* GetOrCreateContextPaint() {
94 mContextPaint
= MakeRefPtr
<SVGEmbeddingContextPaint
>();
97 return mContextPaint
.get();
100 void ClearContextPaint() { mContextPaint
= nullptr; }
102 bool operator==(const SVGImageContext
& aOther
) const {
103 bool contextPaintIsEqual
=
104 // neither have context paint, or they have the same object:
105 (mContextPaint
== aOther
.mContextPaint
) ||
106 // or both have context paint that are different but equivalent objects:
107 (mContextPaint
&& aOther
.mContextPaint
&&
108 *mContextPaint
== *aOther
.mContextPaint
);
110 return contextPaintIsEqual
&& mViewportSize
== aOther
.mViewportSize
&&
111 mPreserveAspectRatio
== aOther
.mPreserveAspectRatio
&&
112 mColorScheme
== aOther
.mColorScheme
;
115 bool operator!=(const SVGImageContext
& aOther
) const {
116 return !(*this == aOther
);
119 PLDHashNumber
Hash() const {
120 PLDHashNumber hash
= 0;
122 hash
= HashGeneric(hash
, mContextPaint
->Hash());
124 return HashGeneric(hash
, mViewportSize
.map(HashSize
).valueOr(0),
125 mPreserveAspectRatio
.map(HashPAR
).valueOr(0),
126 mColorScheme
.map(HashColorScheme
).valueOr(0));
130 static PLDHashNumber
HashSize(const CSSIntSize
& aSize
) {
131 return HashGeneric(aSize
.width
, aSize
.height
);
133 static PLDHashNumber
HashPAR(const SVGPreserveAspectRatio
& aPAR
) {
136 static PLDHashNumber
HashColorScheme(ColorScheme aScheme
) {
137 return HashGeneric(uint8_t(aScheme
));
140 // NOTE: When adding new member-vars, remember to update Hash() & operator==.
141 RefPtr
<SVGEmbeddingContextPaint
> mContextPaint
;
142 Maybe
<CSSIntSize
> mViewportSize
;
143 Maybe
<SVGPreserveAspectRatio
> mPreserveAspectRatio
;
144 Maybe
<ColorScheme
> mColorScheme
;
147 } // namespace mozilla
149 #endif // LAYOUT_SVG_SVGIMAGECONTEXT_H_