Bug 1675375 Part 7: Update expectations in helper_hittest_clippath.html. r=botond
[gecko.git] / layout / painting / nsImageRenderer.h
blob6d5843a73f8c279e0212638832d9bf461c371829
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 nsImageRenderer_h__
8 #define nsImageRenderer_h__
10 #include "nsStyleStruct.h"
11 #include "Units.h"
12 #include "mozilla/AspectRatio.h"
13 #include "mozilla/SurfaceFromElementResult.h"
15 class gfxDrawable;
16 class nsDisplayItem;
17 namespace mozilla {
19 namespace layers {
20 class StackingContextHelper;
21 class WebRenderParentCommand;
22 class RenderRootStateManager;
23 } // namespace layers
25 namespace wr {
26 class DisplayListBuilder;
27 class IpcResourceUpdateQueue;
28 } // namespace wr
30 // A CSSSizeOrRatio represents a (possibly partially specified) size for use
31 // in computing image sizes. Either or both of the width and height might be
32 // given. A ratio of width to height may also be given. If we at least two
33 // of these then we can compute a concrete size, that is a width and height.
34 struct CSSSizeOrRatio {
35 CSSSizeOrRatio()
36 : mWidth(0), mHeight(0), mHasWidth(false), mHasHeight(false) {}
38 bool CanComputeConcreteSize() const {
39 return mHasWidth + mHasHeight + HasRatio() >= 2;
41 bool IsConcrete() const { return mHasWidth && mHasHeight; }
42 bool HasRatio() const { return !!mRatio; }
43 bool IsEmpty() const {
44 return (mHasWidth && mWidth <= 0) || (mHasHeight && mHeight <= 0) ||
45 !mRatio;
48 // CanComputeConcreteSize must return true when ComputeConcreteSize is
49 // called.
50 nsSize ComputeConcreteSize() const;
52 void SetWidth(nscoord aWidth) {
53 mWidth = aWidth;
54 mHasWidth = true;
55 if (mHasHeight) {
56 mRatio = AspectRatio::FromSize(mWidth, mHeight);
59 void SetHeight(nscoord aHeight) {
60 mHeight = aHeight;
61 mHasHeight = true;
62 if (mHasWidth) {
63 mRatio = AspectRatio::FromSize(mWidth, mHeight);
66 void SetSize(const nsSize& aSize) {
67 mWidth = aSize.width;
68 mHeight = aSize.height;
69 mHasWidth = true;
70 mHasHeight = true;
71 mRatio = AspectRatio::FromSize(mWidth, mHeight);
73 void SetRatio(const AspectRatio& aRatio) {
74 MOZ_ASSERT(
75 !mHasWidth || !mHasHeight,
76 "Probably shouldn't be setting a ratio if we have a concrete size");
77 mRatio = aRatio;
80 AspectRatio mRatio;
81 nscoord mWidth;
82 nscoord mHeight;
83 bool mHasWidth;
84 bool mHasHeight;
87 /**
88 * This is a small wrapper class to encapsulate image drawing that can draw an
89 * StyleImage image, which may internally be a real image, a sub image, or a CSS
90 * gradient, etc...
92 * @note Always call the member functions in the order of PrepareImage(),
93 * SetSize(), and Draw*().
95 class nsImageRenderer {
96 public:
97 typedef mozilla::image::ImgDrawResult ImgDrawResult;
98 typedef mozilla::layers::LayerManager LayerManager;
99 typedef mozilla::layers::ImageContainer ImageContainer;
101 enum {
102 FLAG_SYNC_DECODE_IMAGES = 0x01,
103 FLAG_PAINTING_TO_WINDOW = 0x02,
104 FLAG_HIGH_QUALITY_SCALING = 0x04
106 enum FitType { CONTAIN, COVER };
108 nsImageRenderer(nsIFrame* aForFrame, const mozilla::StyleImage* aImage,
109 uint32_t aFlags);
110 ~nsImageRenderer() = default;
112 * Populates member variables to get ready for rendering.
113 * @return true iff the image is ready, and there is at least a pixel to
114 * draw.
116 bool PrepareImage();
119 * The three Compute*Size functions correspond to the sizing algorthms and
120 * definitions from the CSS Image Values and Replaced Content spec. See
121 * http://dev.w3.org/csswg/css-images-3/#sizing .
125 * Compute the intrinsic size of the image as defined in the CSS Image Values
126 * spec. The intrinsic size is the unscaled size which the image would ideally
127 * like to be in app units.
129 mozilla::CSSSizeOrRatio ComputeIntrinsicSize();
132 * Computes the placement for a background image, or for the image data
133 * inside of a replaced element.
135 * @param aPos The CSS <position> value that specifies the image's position.
136 * @param aOriginBounds The box to which the tiling position should be
137 * relative. For background images, this should correspond to
138 * 'background-origin' for the frame, except when painting on the
139 * canvas, in which case the origin bounds should be the bounds
140 * of the root element's frame. For a replaced element, this should
141 * be the element's content-box.
142 * @param aTopLeft [out] The top-left corner where an image tile should be
143 * drawn.
144 * @param aAnchorPoint [out] A point which should be pixel-aligned by
145 * nsLayoutUtils::DrawImage. This is the same as aTopLeft, unless
146 * CSS specifies a percentage (including 'right' or 'bottom'), in
147 * which case it's that percentage within of aOriginBounds. So
148 * 'right' would set aAnchorPoint.x to aOriginBounds.XMost().
150 * Points are returned relative to aOriginBounds.
152 static void ComputeObjectAnchorPoint(const mozilla::Position& aPos,
153 const nsSize& aOriginBounds,
154 const nsSize& aImageSize,
155 nsPoint* aTopLeft,
156 nsPoint* aAnchorPoint);
159 * Compute the size of the rendered image using either the 'cover' or
160 * 'contain' constraints (aFitType).
162 static nsSize ComputeConstrainedSize(
163 const nsSize& aConstrainingSize,
164 const mozilla::AspectRatio& aIntrinsicRatio, FitType aFitType);
166 * Compute the size of the rendered image (the concrete size) where no cover/
167 * contain constraints are given. The 'default algorithm' from the CSS Image
168 * Values spec.
170 static nsSize ComputeConcreteSize(
171 const mozilla::CSSSizeOrRatio& aSpecifiedSize,
172 const mozilla::CSSSizeOrRatio& aIntrinsicSize,
173 const nsSize& aDefaultSize);
176 * Set this image's preferred size. This will be its intrinsic size where
177 * specified and the default size where it is not. Used as the unscaled size
178 * when rendering the image.
180 void SetPreferredSize(const mozilla::CSSSizeOrRatio& aIntrinsicSize,
181 const nsSize& aDefaultSize);
184 * Draws the image to the target rendering context using
185 * {background|mask}-specific arguments.
186 * @see nsLayoutUtils::DrawImage() for parameters.
188 ImgDrawResult DrawLayer(nsPresContext* aPresContext,
189 gfxContext& aRenderingContext, const nsRect& aDest,
190 const nsRect& aFill, const nsPoint& aAnchor,
191 const nsRect& aDirty, const nsSize& aRepeatSize,
192 float aOpacity);
195 * Builds WebRender DisplayItems for an image using
196 * {background|mask}-specific arguments.
197 * @see nsLayoutUtils::DrawImage() for parameters.
199 ImgDrawResult BuildWebRenderDisplayItemsForLayer(
200 nsPresContext* aPresContext, mozilla::wr::DisplayListBuilder& aBuilder,
201 mozilla::wr::IpcResourceUpdateQueue& aResource,
202 const mozilla::layers::StackingContextHelper& aSc,
203 mozilla::layers::RenderRootStateManager* aManager, nsDisplayItem* aItem,
204 const nsRect& aDest, const nsRect& aFill, const nsPoint& aAnchor,
205 const nsRect& aDirty, const nsSize& aRepeatSize, float aOpacity);
208 * Draw the image to a single component of a border-image style rendering.
209 * aFill The destination rect to be drawn into
210 * aSrc is the part of the image to be rendered into a tile (aUnitSize in
211 * aFill), if aSrc and the dest tile are different sizes, the image will be
212 * scaled to map aSrc onto the dest tile.
213 * aHFill and aVFill are the repeat patterns for the component -
214 * NS_STYLE_BORDER_IMAGE_REPEAT_*
215 * aUnitSize The scaled size of a single source rect (in destination coords)
216 * aIndex identifies the component: 0 1 2
217 * 3 4 5
218 * 6 7 8
219 * aSVGViewportSize The image size evaluated by default sizing algorithm.
220 * Pass Nothing() if we can read a valid viewport size or aspect-ratio from
221 * the drawing image directly, otherwise, pass Some() with viewport size
222 * evaluated from default sizing algorithm.
223 * aHasIntrinsicRatio is used to record if the source image has fixed
224 * intrinsic ratio.
226 ImgDrawResult DrawBorderImageComponent(
227 nsPresContext* aPresContext, gfxContext& aRenderingContext,
228 const nsRect& aDirtyRect, const nsRect& aFill,
229 const mozilla::CSSIntRect& aSrc, mozilla::StyleBorderImageRepeat aHFill,
230 mozilla::StyleBorderImageRepeat aVFill, const nsSize& aUnitSize,
231 uint8_t aIndex, const mozilla::Maybe<nsSize>& aSVGViewportSize,
232 const bool aHasIntrinsicRatio);
235 * Draw the image to aRenderingContext which can be used to define the
236 * float area in the presence of "shape-outside: <image>".
238 ImgDrawResult DrawShapeImage(nsPresContext* aPresContext,
239 gfxContext& aRenderingContext);
241 bool IsRasterImage();
242 bool IsAnimatedImage();
244 /// Retrieves the image associated with this nsImageRenderer, if there is one.
245 already_AddRefed<imgIContainer> GetImage();
247 bool IsImageContainerAvailable(layers::LayerManager* aManager,
248 uint32_t aFlags);
249 bool IsReady() const { return mPrepareResult == ImgDrawResult::SUCCESS; }
250 ImgDrawResult PrepareResult() const { return mPrepareResult; }
251 void SetExtendMode(mozilla::gfx::ExtendMode aMode) { mExtendMode = aMode; }
252 void SetMaskOp(mozilla::StyleMaskMode aMaskOp) { mMaskOp = aMaskOp; }
253 void PurgeCacheForViewportChange(
254 const mozilla::Maybe<nsSize>& aSVGViewportSize, const bool aHasRatio);
255 const nsSize& GetSize() const { return mSize; }
256 mozilla::StyleImage::Tag GetType() const { return mType; }
257 const mozilla::StyleGradient* GetGradientData() const {
258 return mGradientData;
261 private:
263 * Draws the image to the target rendering context.
264 * aSrc is a rect on the source image which will be mapped to aDest; it's
265 * currently only used for gradients.
267 * @see nsLayoutUtils::DrawImage() for other parameters.
269 ImgDrawResult Draw(nsPresContext* aPresContext, gfxContext& aRenderingContext,
270 const nsRect& aDirtyRect, const nsRect& aDest,
271 const nsRect& aFill, const nsPoint& aAnchor,
272 const nsSize& aRepeatSize, const mozilla::CSSIntRect& aSrc,
273 float aOpacity = 1.0);
276 * Builds WebRender DisplayItems for the image.
277 * aSrc is a rect on the source image which will be mapped to aDest; it's
278 * currently only used for gradients.
280 * @see nsLayoutUtils::DrawImage() for other parameters.
282 ImgDrawResult BuildWebRenderDisplayItems(
283 nsPresContext* aPresContext, mozilla::wr::DisplayListBuilder& aBuilder,
284 mozilla::wr::IpcResourceUpdateQueue& aResources,
285 const mozilla::layers::StackingContextHelper& aSc,
286 mozilla::layers::RenderRootStateManager* aManager, nsDisplayItem* aItem,
287 const nsRect& aDirtyRect, const nsRect& aDest, const nsRect& aFill,
288 const nsPoint& aAnchor, const nsSize& aRepeatSize,
289 const mozilla::CSSIntRect& aSrc, float aOpacity = 1.0);
292 * Helper method for creating a gfxDrawable from mPaintServerFrame or
293 * mImageElementSurface.
294 * Requires mType to be Element.
295 * Returns null if we cannot create the drawable.
297 already_AddRefed<gfxDrawable> DrawableForElement(const nsRect& aImageRect,
298 gfxContext& aContext);
300 nsIFrame* mForFrame;
301 const mozilla::StyleImage* mImage;
302 mozilla::StyleImage::Tag mType;
303 nsCOMPtr<imgIContainer> mImageContainer;
304 const mozilla::StyleGradient* mGradientData;
305 nsIFrame* mPaintServerFrame;
306 SurfaceFromElementResult mImageElementSurface;
307 ImgDrawResult mPrepareResult;
308 nsSize mSize; // unscaled size of the image, in app units
309 uint32_t mFlags;
310 mozilla::gfx::ExtendMode mExtendMode;
311 mozilla::StyleMaskMode mMaskOp;
314 } // namespace mozilla
316 #endif /* nsImageRenderer_h__ */