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