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