SVGImageContext.h (5549B)
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/. */ 6 7 #ifndef LAYOUT_SVG_SVGIMAGECONTEXT_H_ 8 #define LAYOUT_SVG_SVGIMAGECONTEXT_H_ 9 10 #include "Units.h" 11 #include "mozilla/Maybe.h" 12 #include "mozilla/SVGContextPaint.h" 13 #include "mozilla/SVGPreserveAspectRatio.h" 14 15 class nsIFrame; 16 class nsISVGPaintContext; 17 18 namespace mozilla { 19 20 enum class ColorScheme : uint8_t; 21 class ComputedStyle; 22 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 { 29 public: 30 SVGImageContext() = default; 31 32 /** 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. 47 */ 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) {} 55 56 static void MaybeStoreContextPaint(SVGImageContext& aContext, 57 nsIFrame* aFromFrame, 58 imgIContainer* aImgContainer); 59 60 static void MaybeStoreContextPaint(SVGImageContext& aContext, 61 const nsPresContext&, const ComputedStyle&, 62 imgIContainer*); 63 64 static void MaybeStoreContextPaint(SVGImageContext& aContext, 65 nsISVGPaintContext* aPaintContext, 66 imgIContainer* aImgContainer); 67 68 const Maybe<CSSIntSize>& GetViewportSize() const { return mViewportSize; } 69 70 void SetViewportSize(const Maybe<CSSIntSize>& aSize) { 71 mViewportSize = aSize; 72 } 73 74 const Maybe<ColorScheme>& GetColorScheme() const { return mColorScheme; } 75 76 void SetColorScheme(const Maybe<ColorScheme>& aScheme) { 77 mColorScheme = aScheme; 78 } 79 80 const Maybe<SVGPreserveAspectRatio>& GetPreserveAspectRatio() const { 81 return mPreserveAspectRatio; 82 } 83 84 void SetPreserveAspectRatio(const Maybe<SVGPreserveAspectRatio>& aPAR) { 85 mPreserveAspectRatio = aPAR; 86 } 87 88 const SVGEmbeddingContextPaint* GetContextPaint() const { 89 return mContextPaint.get(); 90 } 91 92 SVGEmbeddingContextPaint* GetOrCreateContextPaint() { 93 if (!mContextPaint) { 94 mContextPaint = MakeRefPtr<SVGEmbeddingContextPaint>(); 95 } 96 97 return mContextPaint.get(); 98 } 99 100 void ClearContextPaint() { mContextPaint = nullptr; } 101 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); 109 110 return contextPaintIsEqual && mViewportSize == aOther.mViewportSize && 111 mPreserveAspectRatio == aOther.mPreserveAspectRatio && 112 mColorScheme == aOther.mColorScheme; 113 } 114 115 bool operator!=(const SVGImageContext&) const = default; 116 117 PLDHashNumber Hash() const { 118 PLDHashNumber hash = 0; 119 if (mContextPaint) { 120 hash = HashGeneric(hash, mContextPaint->Hash()); 121 } 122 return HashGeneric(hash, mViewportSize.map(HashSize).valueOr(0), 123 mPreserveAspectRatio.map(HashPAR).valueOr(0), 124 mColorScheme.map(HashColorScheme).valueOr(0)); 125 } 126 127 private: 128 static PLDHashNumber HashSize(const CSSIntSize& aSize) { 129 return HashGeneric(aSize.width, aSize.height); 130 } 131 static PLDHashNumber HashPAR(const SVGPreserveAspectRatio& aPAR) { 132 return aPAR.Hash(); 133 } 134 static PLDHashNumber HashColorScheme(ColorScheme aScheme) { 135 return HashGeneric(uint8_t(aScheme)); 136 } 137 138 // NOTE: When adding new member-vars, remember to update Hash() & operator==. 139 RefPtr<SVGEmbeddingContextPaint> mContextPaint; 140 Maybe<CSSIntSize> mViewportSize; 141 Maybe<SVGPreserveAspectRatio> mPreserveAspectRatio; 142 Maybe<ColorScheme> mColorScheme; 143 }; 144 145 } // namespace mozilla 146 147 #endif // LAYOUT_SVG_SVGIMAGECONTEXT_H_