|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef nsLayoutUtils_h__ |
|
7 #define nsLayoutUtils_h__ |
|
8 |
|
9 #include "mozilla/MemoryReporting.h" |
|
10 #include "nsChangeHint.h" |
|
11 #include "nsAutoPtr.h" |
|
12 #include "nsFrameList.h" |
|
13 #include "mozilla/layout/FrameChildList.h" |
|
14 #include "nsThreadUtils.h" |
|
15 #include "nsIPrincipal.h" |
|
16 #include "GraphicsFilter.h" |
|
17 #include "nsCSSPseudoElements.h" |
|
18 #include "FrameMetrics.h" |
|
19 #include "gfx3DMatrix.h" |
|
20 #include "nsIWidget.h" |
|
21 #include "nsCSSProperty.h" |
|
22 #include "nsStyleCoord.h" |
|
23 #include "nsStyleConsts.h" |
|
24 #include "nsGkAtoms.h" |
|
25 #include "nsRuleNode.h" |
|
26 #include "imgIContainer.h" |
|
27 #include "mozilla/gfx/2D.h" |
|
28 #include "Units.h" |
|
29 |
|
30 #include <limits> |
|
31 #include <algorithm> |
|
32 |
|
33 class nsIFormControlFrame; |
|
34 class nsPresContext; |
|
35 class nsIContent; |
|
36 class nsIAtom; |
|
37 class nsIScrollableFrame; |
|
38 class nsIDOMEvent; |
|
39 class nsRegion; |
|
40 class nsDisplayListBuilder; |
|
41 class nsDisplayItem; |
|
42 class nsFontMetrics; |
|
43 class nsFontFaceList; |
|
44 class nsIImageLoadingContent; |
|
45 class nsStyleContext; |
|
46 class nsBlockFrame; |
|
47 class gfxASurface; |
|
48 class gfxDrawable; |
|
49 class nsView; |
|
50 class nsIFrame; |
|
51 class nsStyleCoord; |
|
52 class nsStyleCorners; |
|
53 class gfxContext; |
|
54 class nsPIDOMWindow; |
|
55 class imgIRequest; |
|
56 class nsIDocument; |
|
57 class gfxPoint; |
|
58 struct nsStyleFont; |
|
59 struct nsStyleImageOrientation; |
|
60 struct nsOverflowAreas; |
|
61 |
|
62 namespace mozilla { |
|
63 class SVGImageContext; |
|
64 struct IntrinsicSize; |
|
65 struct ContainerLayerParameters; |
|
66 namespace dom { |
|
67 class DOMRectList; |
|
68 class Element; |
|
69 class HTMLImageElement; |
|
70 class HTMLCanvasElement; |
|
71 class HTMLVideoElement; |
|
72 } // namespace dom |
|
73 namespace layers { |
|
74 class Layer; |
|
75 } |
|
76 } |
|
77 |
|
78 namespace mozilla { |
|
79 |
|
80 struct DisplayPortPropertyData { |
|
81 DisplayPortPropertyData(const nsRect& aRect, uint32_t aPriority) |
|
82 : mRect(aRect) |
|
83 , mPriority(aPriority) |
|
84 {} |
|
85 nsRect mRect; |
|
86 uint32_t mPriority; |
|
87 }; |
|
88 |
|
89 struct DisplayPortMarginsPropertyData { |
|
90 DisplayPortMarginsPropertyData(const LayerMargin& aMargins, |
|
91 uint32_t aAlignmentX, uint32_t aAlignmentY, |
|
92 uint32_t aPriority) |
|
93 : mMargins(aMargins) |
|
94 , mAlignmentX(aAlignmentX) |
|
95 , mAlignmentY(aAlignmentY) |
|
96 , mPriority(aPriority) |
|
97 {} |
|
98 LayerMargin mMargins; |
|
99 uint32_t mAlignmentX; |
|
100 uint32_t mAlignmentY; |
|
101 uint32_t mPriority; |
|
102 }; |
|
103 |
|
104 template <class AnimationsOrTransitions> |
|
105 extern AnimationsOrTransitions* HasAnimationOrTransition(nsIContent* aContent, |
|
106 nsIAtom* aAnimationProperty, |
|
107 nsCSSProperty aProperty); |
|
108 |
|
109 } // namespace mozilla |
|
110 |
|
111 /** |
|
112 * nsLayoutUtils is a namespace class used for various helper |
|
113 * functions that are useful in multiple places in layout. The goal |
|
114 * is not to define multiple copies of the same static helper. |
|
115 */ |
|
116 class nsLayoutUtils |
|
117 { |
|
118 typedef ::GraphicsFilter GraphicsFilter; |
|
119 typedef mozilla::dom::DOMRectList DOMRectList; |
|
120 typedef mozilla::layers::Layer Layer; |
|
121 typedef mozilla::ContainerLayerParameters ContainerLayerParameters; |
|
122 typedef mozilla::gfx::SourceSurface SourceSurface; |
|
123 typedef mozilla::gfx::DrawTarget DrawTarget; |
|
124 typedef mozilla::gfx::Rect Rect; |
|
125 |
|
126 public: |
|
127 typedef mozilla::layers::FrameMetrics FrameMetrics; |
|
128 typedef FrameMetrics::ViewID ViewID; |
|
129 typedef mozilla::CSSPoint CSSPoint; |
|
130 typedef mozilla::CSSSize CSSSize; |
|
131 typedef mozilla::LayerMargin LayerMargin; |
|
132 |
|
133 /** |
|
134 * Finds previously assigned ViewID for the given content element, if any. |
|
135 * Returns whether a ViewID was previously assigned. |
|
136 */ |
|
137 static bool FindIDFor(const nsIContent* aContent, ViewID* aOutViewId); |
|
138 |
|
139 /** |
|
140 * Finds previously assigned or generates a unique ViewID for the given |
|
141 * content element. |
|
142 */ |
|
143 static ViewID FindOrCreateIDFor(nsIContent* aContent); |
|
144 |
|
145 /** |
|
146 * Find content for given ID. |
|
147 */ |
|
148 static nsIContent* FindContentFor(ViewID aId); |
|
149 |
|
150 /** |
|
151 * Find the scrollable frame for a given ID. |
|
152 */ |
|
153 static nsIScrollableFrame* FindScrollableFrameFor(ViewID aId); |
|
154 |
|
155 /** |
|
156 * Get display port for the given element. |
|
157 */ |
|
158 static bool GetDisplayPort(nsIContent* aContent, nsRect *aResult = nullptr); |
|
159 |
|
160 MOZ_BEGIN_NESTED_ENUM_CLASS(RepaintMode, uint8_t) |
|
161 Repaint, |
|
162 DoNotRepaint |
|
163 MOZ_END_NESTED_ENUM_CLASS(RepaintMode) |
|
164 |
|
165 /** |
|
166 * Set the display port margins for a content element to be used with a |
|
167 * display port base (see SetDisplayPortBase()). |
|
168 * See also nsIDOMWindowUtils.setDisplayPortMargins. |
|
169 * @param aContent the content element for which to set the margins |
|
170 * @param aPresShell the pres shell for the document containing the element |
|
171 * @param aMargins the margins to set |
|
172 * @param aAlignmentX, alignmentY the amount of pixels to which to align the |
|
173 * displayport built by combining the base |
|
174 * rect with the margins, in either direction |
|
175 * @param aPriority a priority value to determine which margins take effect |
|
176 * when multiple callers specify margins |
|
177 * @param aRepaintMode whether to schedule a paint after setting the margins |
|
178 */ |
|
179 static void SetDisplayPortMargins(nsIContent* aContent, |
|
180 nsIPresShell* aPresShell, |
|
181 const LayerMargin& aMargins, |
|
182 uint32_t aAlignmentX, |
|
183 uint32_t aAlignmentY, |
|
184 uint32_t aPriority = 0, |
|
185 RepaintMode aRepaintMode = RepaintMode::Repaint); |
|
186 |
|
187 /** |
|
188 * Set the display port base rect for given element to be used with display |
|
189 * port margins. |
|
190 * SetDisplayPortBaseIfNotSet is like SetDisplayPortBase except it only sets |
|
191 * the display port base to aBase if no display port base is currently set. |
|
192 */ |
|
193 static void SetDisplayPortBase(nsIContent* aContent, const nsRect& aBase); |
|
194 static void SetDisplayPortBaseIfNotSet(nsIContent* aContent, const nsRect& aBase); |
|
195 |
|
196 /** |
|
197 * Get the critical display port for the given element. |
|
198 */ |
|
199 static bool GetCriticalDisplayPort(nsIContent* aContent, nsRect* aResult = nullptr); |
|
200 |
|
201 /** |
|
202 * Use heuristics to figure out the child list that |
|
203 * aChildFrame is currently in. |
|
204 */ |
|
205 static mozilla::layout::FrameChildListID GetChildListNameFor(nsIFrame* aChildFrame); |
|
206 |
|
207 /** |
|
208 * GetBeforeFrame returns the outermost :before frame of the given frame, if |
|
209 * one exists. This is typically O(1). The frame passed in must be |
|
210 * the first-in-flow. |
|
211 * |
|
212 * @param aFrame the frame whose :before is wanted |
|
213 * @return the :before frame or nullptr if there isn't one |
|
214 */ |
|
215 static nsIFrame* GetBeforeFrame(nsIFrame* aFrame); |
|
216 |
|
217 /** |
|
218 * GetAfterFrame returns the outermost :after frame of the given frame, if one |
|
219 * exists. This will walk the in-flow chain to the last-in-flow if |
|
220 * needed. This function is typically O(N) in the number of child |
|
221 * frames, following in-flows, etc. |
|
222 * |
|
223 * @param aFrame the frame whose :after is wanted |
|
224 * @return the :after frame or nullptr if there isn't one |
|
225 */ |
|
226 static nsIFrame* GetAfterFrame(nsIFrame* aFrame); |
|
227 |
|
228 /** |
|
229 * Given a frame, search up the frame tree until we find an |
|
230 * ancestor that (or the frame itself) is of type aFrameType, if any. |
|
231 * |
|
232 * @param aFrame the frame to start at |
|
233 * @param aFrameType the frame type to look for |
|
234 * @return a frame of the given type or nullptr if no |
|
235 * such ancestor exists |
|
236 */ |
|
237 static nsIFrame* GetClosestFrameOfType(nsIFrame* aFrame, nsIAtom* aFrameType); |
|
238 |
|
239 /** |
|
240 * Given a frame, search up the frame tree until we find an |
|
241 * ancestor that (or the frame itself) is a "Page" frame, if any. |
|
242 * |
|
243 * @param aFrame the frame to start at |
|
244 * @return a frame of type nsGkAtoms::pageFrame or nullptr if no |
|
245 * such ancestor exists |
|
246 */ |
|
247 static nsIFrame* GetPageFrame(nsIFrame* aFrame) |
|
248 { |
|
249 return GetClosestFrameOfType(aFrame, nsGkAtoms::pageFrame); |
|
250 } |
|
251 |
|
252 /** |
|
253 * Given a frame which is the primary frame for an element, |
|
254 * return the frame that has the non-psuedoelement style context for |
|
255 * the content. |
|
256 * This is aPrimaryFrame itself except for tableOuter frames. |
|
257 */ |
|
258 static nsIFrame* GetStyleFrame(nsIFrame* aPrimaryFrame); |
|
259 |
|
260 /** |
|
261 * Given a content node, |
|
262 * return the frame that has the non-psuedoelement style context for |
|
263 * the content. May return null. |
|
264 * This is aContent->GetPrimaryFrame() except for tableOuter frames. |
|
265 */ |
|
266 static nsIFrame* GetStyleFrame(const nsIContent* aContent); |
|
267 |
|
268 /** |
|
269 * IsGeneratedContentFor returns true if aFrame is the outermost |
|
270 * frame for generated content of type aPseudoElement for aContent. |
|
271 * aFrame *might not* have the aPseudoElement pseudo-style! For example |
|
272 * it might be a table outer frame and the inner table frame might |
|
273 * have the pseudo-style. |
|
274 * |
|
275 * @param aContent the content node we're looking at. If this is |
|
276 * null, then we just assume that aFrame has the right content |
|
277 * pointer. |
|
278 * @param aFrame the frame we're looking at |
|
279 * @param aPseudoElement the pseudo type we're interested in |
|
280 * @return whether aFrame is the generated aPseudoElement frame for aContent |
|
281 */ |
|
282 static bool IsGeneratedContentFor(nsIContent* aContent, nsIFrame* aFrame, |
|
283 nsIAtom* aPseudoElement); |
|
284 |
|
285 #ifdef DEBUG |
|
286 // TODO: remove, see bug 598468. |
|
287 static bool gPreventAssertInCompareTreePosition; |
|
288 #endif // DEBUG |
|
289 |
|
290 /** |
|
291 * CompareTreePosition determines whether aContent1 comes before or |
|
292 * after aContent2 in a preorder traversal of the content tree. |
|
293 * |
|
294 * @param aCommonAncestor either null, or a common ancestor of |
|
295 * aContent1 and aContent2. Actually this is |
|
296 * only a hint; if it's not an ancestor of |
|
297 * aContent1 or aContent2, this function will |
|
298 * still work, but it will be slower than |
|
299 * normal. |
|
300 * @return < 0 if aContent1 is before aContent2 |
|
301 * > 0 if aContent1 is after aContent2, |
|
302 * 0 otherwise (meaning they're the same, or they're in |
|
303 * different documents) |
|
304 */ |
|
305 static int32_t CompareTreePosition(nsIContent* aContent1, |
|
306 nsIContent* aContent2, |
|
307 const nsIContent* aCommonAncestor = nullptr) |
|
308 { |
|
309 return DoCompareTreePosition(aContent1, aContent2, -1, 1, aCommonAncestor); |
|
310 } |
|
311 |
|
312 /* |
|
313 * More generic version of |CompareTreePosition|. |aIf1Ancestor| |
|
314 * gives the value to return when 1 is an ancestor of 2, and likewise |
|
315 * for |aIf2Ancestor|. Passing (-1, 1) gives preorder traversal |
|
316 * order, and (1, -1) gives postorder traversal order. |
|
317 */ |
|
318 static int32_t DoCompareTreePosition(nsIContent* aContent1, |
|
319 nsIContent* aContent2, |
|
320 int32_t aIf1Ancestor, |
|
321 int32_t aIf2Ancestor, |
|
322 const nsIContent* aCommonAncestor = nullptr); |
|
323 |
|
324 /** |
|
325 * CompareTreePosition determines whether aFrame1 comes before or |
|
326 * after aFrame2 in a preorder traversal of the frame tree, where out |
|
327 * of flow frames are treated as children of their placeholders. This is |
|
328 * basically the same ordering as DoCompareTreePosition(nsIContent*) except |
|
329 * that it handles anonymous content properly and there are subtleties with |
|
330 * continuations. |
|
331 * |
|
332 * @param aCommonAncestor either null, or a common ancestor of |
|
333 * aContent1 and aContent2. Actually this is |
|
334 * only a hint; if it's not an ancestor of |
|
335 * aContent1 or aContent2, this function will |
|
336 * still work, but it will be slower than |
|
337 * normal. |
|
338 * @return < 0 if aContent1 is before aContent2 |
|
339 * > 0 if aContent1 is after aContent2, |
|
340 * 0 otherwise (meaning they're the same, or they're in |
|
341 * different frame trees) |
|
342 */ |
|
343 static int32_t CompareTreePosition(nsIFrame* aFrame1, |
|
344 nsIFrame* aFrame2, |
|
345 nsIFrame* aCommonAncestor = nullptr) |
|
346 { |
|
347 return DoCompareTreePosition(aFrame1, aFrame2, -1, 1, aCommonAncestor); |
|
348 } |
|
349 |
|
350 static int32_t CompareTreePosition(nsIFrame* aFrame1, |
|
351 nsIFrame* aFrame2, |
|
352 nsTArray<nsIFrame*>& aFrame2Ancestors, |
|
353 nsIFrame* aCommonAncestor = nullptr) |
|
354 { |
|
355 return DoCompareTreePosition(aFrame1, aFrame2, aFrame2Ancestors, |
|
356 -1, 1, aCommonAncestor); |
|
357 } |
|
358 |
|
359 /* |
|
360 * More generic version of |CompareTreePosition|. |aIf1Ancestor| |
|
361 * gives the value to return when 1 is an ancestor of 2, and likewise |
|
362 * for |aIf2Ancestor|. Passing (-1, 1) gives preorder traversal |
|
363 * order, and (1, -1) gives postorder traversal order. |
|
364 */ |
|
365 static int32_t DoCompareTreePosition(nsIFrame* aFrame1, |
|
366 nsIFrame* aFrame2, |
|
367 int32_t aIf1Ancestor, |
|
368 int32_t aIf2Ancestor, |
|
369 nsIFrame* aCommonAncestor = nullptr); |
|
370 |
|
371 static nsIFrame* FillAncestors(nsIFrame* aFrame, |
|
372 nsIFrame* aStopAtAncestor, |
|
373 nsTArray<nsIFrame*>* aAncestors); |
|
374 |
|
375 static int32_t DoCompareTreePosition(nsIFrame* aFrame1, |
|
376 nsIFrame* aFrame2, |
|
377 nsTArray<nsIFrame*>& aFrame2Ancestors, |
|
378 int32_t aIf1Ancestor, |
|
379 int32_t aIf2Ancestor, |
|
380 nsIFrame* aCommonAncestor); |
|
381 |
|
382 /** |
|
383 * LastContinuationWithChild gets the last continuation in aFrame's chain |
|
384 * that has a child, or the first continuation if the frame has no children. |
|
385 */ |
|
386 static nsIFrame* LastContinuationWithChild(nsIFrame* aFrame); |
|
387 |
|
388 /** |
|
389 * GetLastSibling simply finds the last sibling of aFrame, or returns nullptr if |
|
390 * aFrame is null. |
|
391 */ |
|
392 static nsIFrame* GetLastSibling(nsIFrame* aFrame); |
|
393 |
|
394 /** |
|
395 * FindSiblingViewFor locates the child of aParentView that aFrame's |
|
396 * view should be inserted 'above' (i.e., before in sibling view |
|
397 * order). This is the first child view of aParentView whose |
|
398 * corresponding content is before aFrame's content (view siblings |
|
399 * are in reverse content order). |
|
400 */ |
|
401 static nsView* FindSiblingViewFor(nsView* aParentView, nsIFrame* aFrame); |
|
402 |
|
403 /** |
|
404 * Get the parent of aFrame. If aFrame is the root frame for a document, |
|
405 * and the document has a parent document in the same view hierarchy, then |
|
406 * we try to return the subdocumentframe in the parent document. |
|
407 * @param aExtraOffset [in/out] if non-null, then as we cross documents |
|
408 * an extra offset may be required and it will be added to aCrossDocOffset. |
|
409 * Be careful dealing with this extra offset as it is in app units of the |
|
410 * parent document, which may have a different app units per dev pixel ratio |
|
411 * than the child document. |
|
412 */ |
|
413 static nsIFrame* GetCrossDocParentFrame(const nsIFrame* aFrame, |
|
414 nsPoint* aCrossDocOffset = nullptr); |
|
415 |
|
416 /** |
|
417 * IsProperAncestorFrame checks whether aAncestorFrame is an ancestor |
|
418 * of aFrame and not equal to aFrame. |
|
419 * @param aCommonAncestor nullptr, or a common ancestor of aFrame and |
|
420 * aAncestorFrame. If non-null, this can bound the search and speed up |
|
421 * the function |
|
422 */ |
|
423 static bool IsProperAncestorFrame(nsIFrame* aAncestorFrame, nsIFrame* aFrame, |
|
424 nsIFrame* aCommonAncestor = nullptr); |
|
425 |
|
426 /** |
|
427 * Like IsProperAncestorFrame, but looks across document boundaries. |
|
428 * |
|
429 * Just like IsAncestorFrameCrossDoc, except that it returns false when |
|
430 * aFrame == aAncestorFrame. |
|
431 */ |
|
432 static bool IsProperAncestorFrameCrossDoc(nsIFrame* aAncestorFrame, nsIFrame* aFrame, |
|
433 nsIFrame* aCommonAncestor = nullptr); |
|
434 |
|
435 /** |
|
436 * IsAncestorFrameCrossDoc checks whether aAncestorFrame is an ancestor |
|
437 * of aFrame or equal to aFrame, looking across document boundaries. |
|
438 * @param aCommonAncestor nullptr, or a common ancestor of aFrame and |
|
439 * aAncestorFrame. If non-null, this can bound the search and speed up |
|
440 * the function. |
|
441 * |
|
442 * Just like IsProperAncestorFrameCrossDoc, except that it returns true when |
|
443 * aFrame == aAncestorFrame. |
|
444 */ |
|
445 static bool IsAncestorFrameCrossDoc(const nsIFrame* aAncestorFrame, const nsIFrame* aFrame, |
|
446 const nsIFrame* aCommonAncestor = nullptr); |
|
447 |
|
448 /** |
|
449 * Sets the fixed-pos metadata properties on aLayer. |
|
450 * aAnchorRect is the basic anchor rectangle. If aFixedPosFrame is not a viewport |
|
451 * frame, then we pick a corner of aAnchorRect to as the anchor point for the |
|
452 * fixed-pos layer (i.e. the point to remain stable during zooming), based |
|
453 * on which of the fixed-pos frame's CSS absolute positioning offset |
|
454 * properties (top, left, right, bottom) are auto. aAnchorRect is in the |
|
455 * coordinate space of aLayer's container layer (i.e. relative to the reference |
|
456 * frame of the display item which is building aLayer's container layer). |
|
457 */ |
|
458 static void SetFixedPositionLayerData(Layer* aLayer, const nsIFrame* aViewportFrame, |
|
459 const nsRect& aAnchorRect, |
|
460 const nsIFrame* aFixedPosFrame, |
|
461 nsPresContext* aPresContext, |
|
462 const ContainerLayerParameters& aContainerParameters); |
|
463 |
|
464 /** |
|
465 * Return true if aPresContext's viewport has a displayport. |
|
466 * Fills in aDisplayPort with the displayport rectangle if non-null. |
|
467 */ |
|
468 static bool ViewportHasDisplayPort(nsPresContext* aPresContext, |
|
469 nsRect* aDisplayPort = nullptr); |
|
470 |
|
471 /** |
|
472 * Return true if aFrame is a fixed-pos frame and is a child of a viewport |
|
473 * which has a displayport. These frames get special treatment from the compositor. |
|
474 * aDisplayPort, if non-null, is set to the display port rectangle (relative to |
|
475 * the viewport). |
|
476 */ |
|
477 static bool IsFixedPosFrameInDisplayPort(const nsIFrame* aFrame, |
|
478 nsRect* aDisplayPort = nullptr); |
|
479 |
|
480 /** |
|
481 * Finds the nearest ancestor frame to aItem that is considered to have (or |
|
482 * will have) "animated geometry". For example the scrolled frames of |
|
483 * scrollframes which are actively being scrolled fall into this category. |
|
484 * Frames with certain CSS properties that are being animated (e.g. |
|
485 * 'left'/'top' etc) are also placed in this category. |
|
486 * Frames with different active geometry roots are in different ThebesLayers, |
|
487 * so that we can animate the geometry root by changing its transform (either |
|
488 * on the main thread or in the compositor). |
|
489 * The animated geometry root is required to be a descendant (or equal to) |
|
490 * aItem's ReferenceFrame(), which means that we will fall back to |
|
491 * returning aItem->ReferenceFrame() when we can't find another animated |
|
492 * geometry root. |
|
493 */ |
|
494 static nsIFrame* GetAnimatedGeometryRootFor(nsDisplayItem* aItem, |
|
495 nsDisplayListBuilder* aBuilder); |
|
496 |
|
497 /** |
|
498 * GetScrollableFrameFor returns the scrollable frame for a scrolled frame |
|
499 */ |
|
500 static nsIScrollableFrame* GetScrollableFrameFor(const nsIFrame *aScrolledFrame); |
|
501 |
|
502 /** |
|
503 * GetNearestScrollableFrameForDirection locates the first ancestor of |
|
504 * aFrame (or aFrame itself) that is scrollable with overflow:scroll or |
|
505 * overflow:auto in the given direction and where either the scrollbar for |
|
506 * that direction is visible or the frame can be scrolled by some |
|
507 * positive amount in that direction. |
|
508 * The search extends across document boundaries. |
|
509 * |
|
510 * @param aFrame the frame to start with |
|
511 * @param aDirection Whether it's for horizontal or vertical scrolling. |
|
512 * @return the nearest scrollable frame or nullptr if not found |
|
513 */ |
|
514 enum Direction { eHorizontal, eVertical }; |
|
515 static nsIScrollableFrame* GetNearestScrollableFrameForDirection(nsIFrame* aFrame, |
|
516 Direction aDirection); |
|
517 |
|
518 enum { |
|
519 SCROLLABLE_SAME_DOC = 0x01, |
|
520 SCROLLABLE_INCLUDE_HIDDEN = 0x02 |
|
521 }; |
|
522 /** |
|
523 * GetNearestScrollableFrame locates the first ancestor of aFrame |
|
524 * (or aFrame itself) that is scrollable with overflow:scroll or |
|
525 * overflow:auto in some direction. |
|
526 * |
|
527 * @param aFrame the frame to start with |
|
528 * @param aFlags if SCROLLABLE_SAME_DOC is set, do not search across |
|
529 * document boundaries. If SCROLLABLE_INCLUDE_HIDDEN is set, include |
|
530 * frames scrollable with overflow:hidden. |
|
531 * @return the nearest scrollable frame or nullptr if not found |
|
532 */ |
|
533 static nsIScrollableFrame* GetNearestScrollableFrame(nsIFrame* aFrame, |
|
534 uint32_t aFlags = 0); |
|
535 |
|
536 /** |
|
537 * GetScrolledRect returns the range of allowable scroll offsets |
|
538 * for aScrolledFrame, assuming the scrollable overflow area is |
|
539 * aScrolledFrameOverflowArea and the scrollport size is aScrollPortSize. |
|
540 * aDirection is either NS_STYLE_DIRECTION_LTR or NS_STYLE_DIRECTION_RTL. |
|
541 */ |
|
542 static nsRect GetScrolledRect(nsIFrame* aScrolledFrame, |
|
543 const nsRect& aScrolledFrameOverflowArea, |
|
544 const nsSize& aScrollPortSize, |
|
545 uint8_t aDirection); |
|
546 |
|
547 /** |
|
548 * HasPseudoStyle returns true if aContent (whose primary style |
|
549 * context is aStyleContext) has the aPseudoElement pseudo-style |
|
550 * attached to it; returns false otherwise. |
|
551 * |
|
552 * @param aContent the content node we're looking at |
|
553 * @param aStyleContext aContent's style context |
|
554 * @param aPseudoElement the id of the pseudo style we care about |
|
555 * @param aPresContext the presentation context |
|
556 * @return whether aContent has aPseudoElement style attached to it |
|
557 */ |
|
558 static bool HasPseudoStyle(nsIContent* aContent, |
|
559 nsStyleContext* aStyleContext, |
|
560 nsCSSPseudoElements::Type aPseudoElement, |
|
561 nsPresContext* aPresContext); |
|
562 |
|
563 /** |
|
564 * If this frame is a placeholder for a float, then return the float, |
|
565 * otherwise return nullptr. aPlaceholder must be a placeholder frame. |
|
566 */ |
|
567 static nsIFrame* GetFloatFromPlaceholder(nsIFrame* aPlaceholder); |
|
568 |
|
569 // Combine aNewBreakType with aOrigBreakType, but limit the break types |
|
570 // to NS_STYLE_CLEAR_LEFT, RIGHT, LEFT_AND_RIGHT. |
|
571 static uint8_t CombineBreakType(uint8_t aOrigBreakType, uint8_t aNewBreakType); |
|
572 |
|
573 /** |
|
574 * Get the coordinates of a given DOM mouse event, relative to a given |
|
575 * frame. Works only for DOM events generated by WidgetGUIEvents. |
|
576 * @param aDOMEvent the event |
|
577 * @param aFrame the frame to make coordinates relative to |
|
578 * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if |
|
579 * for some reason the coordinates for the mouse are not known (e.g., |
|
580 * the event is not a GUI event). |
|
581 */ |
|
582 static nsPoint GetDOMEventCoordinatesRelativeTo(nsIDOMEvent* aDOMEvent, |
|
583 nsIFrame* aFrame); |
|
584 |
|
585 /** |
|
586 * Get the coordinates of a given native mouse event, relative to a given |
|
587 * frame. |
|
588 * @param aEvent the event |
|
589 * @param aFrame the frame to make coordinates relative to |
|
590 * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if |
|
591 * for some reason the coordinates for the mouse are not known (e.g., |
|
592 * the event is not a GUI event). |
|
593 */ |
|
594 static nsPoint GetEventCoordinatesRelativeTo( |
|
595 const mozilla::WidgetEvent* aEvent, |
|
596 nsIFrame* aFrame); |
|
597 |
|
598 /** |
|
599 * Get the coordinates of a given point relative to an event and a |
|
600 * given frame. |
|
601 * @param aEvent the event |
|
602 * @param aPoint the point to get the coordinates relative to |
|
603 * @param aFrame the frame to make coordinates relative to |
|
604 * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if |
|
605 * for some reason the coordinates for the mouse are not known (e.g., |
|
606 * the event is not a GUI event). |
|
607 */ |
|
608 static nsPoint GetEventCoordinatesRelativeTo( |
|
609 const mozilla::WidgetEvent* aEvent, |
|
610 const nsIntPoint aPoint, |
|
611 nsIFrame* aFrame); |
|
612 |
|
613 /** |
|
614 * Get the coordinates of a given point relative to a widget and a |
|
615 * given frame. |
|
616 * @param aWidget the event src widget |
|
617 * @param aPoint the point to get the coordinates relative to |
|
618 * @param aFrame the frame to make coordinates relative to |
|
619 * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if |
|
620 * for some reason the coordinates for the mouse are not known (e.g., |
|
621 * the event is not a GUI event). |
|
622 */ |
|
623 static nsPoint GetEventCoordinatesRelativeTo(nsIWidget* aWidget, |
|
624 const nsIntPoint aPoint, |
|
625 nsIFrame* aFrame); |
|
626 |
|
627 /** |
|
628 * Get the popup frame of a given native mouse event. |
|
629 * @param aPresContext only check popups within aPresContext or a descendant |
|
630 * @param aEvent the event. |
|
631 * @return Null, if there is no popup frame at the point, otherwise, |
|
632 * returns top-most popup frame at the point. |
|
633 */ |
|
634 static nsIFrame* GetPopupFrameForEventCoordinates( |
|
635 nsPresContext* aPresContext, |
|
636 const mozilla::WidgetEvent* aEvent); |
|
637 |
|
638 /** |
|
639 * Translate from widget coordinates to the view's coordinates |
|
640 * @param aPresContext the PresContext for the view |
|
641 * @param aWidget the widget |
|
642 * @param aPt the point relative to the widget |
|
643 * @param aView view to which returned coordinates are relative |
|
644 * @return the point in the view's coordinates |
|
645 */ |
|
646 static nsPoint TranslateWidgetToView(nsPresContext* aPresContext, |
|
647 nsIWidget* aWidget, nsIntPoint aPt, |
|
648 nsView* aView); |
|
649 |
|
650 /** |
|
651 * Given a matrix and a point, let T be the transformation matrix translating points |
|
652 * in the coordinate space with origin aOrigin to the coordinate space used by the |
|
653 * matrix. If M is the stored matrix, this function returns (T-1)MT, the matrix |
|
654 * that's equivalent to aMatrix but in the coordinate space that treats aOrigin |
|
655 * as the origin. |
|
656 * |
|
657 * @param aOrigin The origin to translate to. |
|
658 * @param aMatrix The matrix to change the basis of. |
|
659 * @return A matrix equivalent to aMatrix, but operating in the coordinate system with |
|
660 * origin aOrigin. |
|
661 */ |
|
662 static gfx3DMatrix ChangeMatrixBasis(const gfxPoint3D &aOrigin, const gfx3DMatrix &aMatrix); |
|
663 |
|
664 /** |
|
665 * Find IDs corresponding to a scrollable content element in the child process. |
|
666 * In correspondence with the shadow layer tree, you can use this to perform a |
|
667 * hit test that corresponds to a specific shadow layer that you can then perform |
|
668 * transformations on to do parent-side scrolling. |
|
669 * |
|
670 * @param aFrame The root frame of a stack context |
|
671 * @param aTarget The rect to hit test relative to the frame origin |
|
672 * @param aOutIDs All found IDs are added here |
|
673 * @param aIgnoreRootScrollFrame a boolean to control if the display list |
|
674 * builder should ignore the root scroll frame |
|
675 */ |
|
676 static nsresult GetRemoteContentIds(nsIFrame* aFrame, |
|
677 const nsRect& aTarget, |
|
678 nsTArray<ViewID> &aOutIDs, |
|
679 bool aIgnoreRootScrollFrame); |
|
680 |
|
681 enum FrameForPointFlags { |
|
682 /** |
|
683 * When set, paint suppression is ignored, so we'll return non-root page |
|
684 * elements even if paint suppression is stopping them from painting. |
|
685 */ |
|
686 IGNORE_PAINT_SUPPRESSION = 0x01, |
|
687 /** |
|
688 * When set, clipping due to the root scroll frame (and any other viewport- |
|
689 * related clipping) is ignored. |
|
690 */ |
|
691 IGNORE_ROOT_SCROLL_FRAME = 0x02, |
|
692 /** |
|
693 * When set, return only content in the same document as aFrame. |
|
694 */ |
|
695 IGNORE_CROSS_DOC = 0x04 |
|
696 }; |
|
697 |
|
698 /** |
|
699 * Given aFrame, the root frame of a stacking context, find its descendant |
|
700 * frame under the point aPt that receives a mouse event at that location, |
|
701 * or nullptr if there is no such frame. |
|
702 * @param aPt the point, relative to the frame origin |
|
703 * @param aFlags some combination of FrameForPointFlags |
|
704 */ |
|
705 static nsIFrame* GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt, |
|
706 uint32_t aFlags = 0); |
|
707 |
|
708 /** |
|
709 * Given aFrame, the root frame of a stacking context, find all descendant |
|
710 * frames under the area of a rectangle that receives a mouse event, |
|
711 * or nullptr if there is no such frame. |
|
712 * @param aRect the rect, relative to the frame origin |
|
713 * @param aOutFrames an array to add all the frames found |
|
714 * @param aFlags some combination of FrameForPointFlags |
|
715 */ |
|
716 static nsresult GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect, |
|
717 nsTArray<nsIFrame*> &aOutFrames, |
|
718 uint32_t aFlags = 0); |
|
719 |
|
720 /** |
|
721 * Transform aRect relative to aFrame up to the coordinate system of |
|
722 * aAncestor. Computes the bounding-box of the true quadrilateral. |
|
723 * Pass non-null aPreservesAxisAlignedRectangles and it will be set to true if |
|
724 * we only need to use a 2d transform that PreservesAxisAlignedRectangles(). |
|
725 */ |
|
726 static nsRect TransformFrameRectToAncestor(nsIFrame* aFrame, |
|
727 const nsRect& aRect, |
|
728 const nsIFrame* aAncestor, |
|
729 bool* aPreservesAxisAlignedRectangles = nullptr); |
|
730 |
|
731 |
|
732 /** |
|
733 * Gets the transform for aFrame relative to aAncestor. Pass null for aAncestor |
|
734 * to go up to the root frame. |
|
735 */ |
|
736 static gfx3DMatrix GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncestor); |
|
737 |
|
738 /** |
|
739 * Transforms a list of CSSPoints from aFromFrame to aToFrame, taking into |
|
740 * account all relevant transformations on the frames up to (but excluding) |
|
741 * their nearest common ancestor. |
|
742 * If we encounter a transform that we need to invert but which is |
|
743 * non-invertible, we return NONINVERTIBLE_TRANSFORM. If the frames have |
|
744 * no common ancestor, we return NO_COMMON_ANCESTOR. |
|
745 * If this returns TRANSFORM_SUCCEEDED, the points in aPoints are transformed |
|
746 * in-place, otherwise they are untouched. |
|
747 */ |
|
748 enum TransformResult { |
|
749 TRANSFORM_SUCCEEDED, |
|
750 NO_COMMON_ANCESTOR, |
|
751 NONINVERTIBLE_TRANSFORM |
|
752 }; |
|
753 static TransformResult TransformPoints(nsIFrame* aFromFrame, nsIFrame* aToFrame, |
|
754 uint32_t aPointCount, CSSPoint* aPoints); |
|
755 |
|
756 /** |
|
757 * Return true if a "layer transform" could be computed for aFrame, |
|
758 * and optionally return the computed transform. The returned |
|
759 * transform is what would be set on the layer currently if a layers |
|
760 * transaction were opened at the time this helper is called. |
|
761 */ |
|
762 static bool GetLayerTransformForFrame(nsIFrame* aFrame, |
|
763 gfx3DMatrix* aTransform); |
|
764 |
|
765 /** |
|
766 * Given a point in the global coordinate space, returns that point expressed |
|
767 * in the coordinate system of aFrame. This effectively inverts all transforms |
|
768 * between this point and the root frame. |
|
769 * |
|
770 * @param aFrame The frame that acts as the coordinate space container. |
|
771 * @param aPoint The point, in the global space, to get in the frame-local space. |
|
772 * @return aPoint, expressed in aFrame's canonical coordinate space. |
|
773 */ |
|
774 static nsPoint TransformRootPointToFrame(nsIFrame* aFrame, |
|
775 const nsPoint &aPoint) |
|
776 { |
|
777 return TransformAncestorPointToFrame(aFrame, aPoint, nullptr); |
|
778 } |
|
779 |
|
780 /** |
|
781 * Transform aPoint relative to aAncestor down to the coordinate system of |
|
782 * aFrame. |
|
783 */ |
|
784 static nsPoint TransformAncestorPointToFrame(nsIFrame* aFrame, |
|
785 const nsPoint& aPoint, |
|
786 nsIFrame* aAncestor); |
|
787 |
|
788 /** |
|
789 * Helper function that, given a rectangle and a matrix, returns the smallest |
|
790 * rectangle containing the image of the source rectangle. |
|
791 * |
|
792 * @param aBounds The rectangle to transform. |
|
793 * @param aMatrix The matrix to transform it with. |
|
794 * @param aFactor The number of app units per graphics unit. |
|
795 * @return The smallest rect that contains the image of aBounds. |
|
796 */ |
|
797 static nsRect MatrixTransformRect(const nsRect &aBounds, |
|
798 const gfx3DMatrix &aMatrix, float aFactor); |
|
799 |
|
800 /** |
|
801 * Helper function that, given a rectangle and a matrix, returns the smallest |
|
802 * rectangle containing the image of the source rectangle rounded out to the nearest |
|
803 * pixel value. |
|
804 * |
|
805 * @param aBounds The rectangle to transform. |
|
806 * @param aMatrix The matrix to transform it with. |
|
807 * @param aFactor The number of app units per graphics unit. |
|
808 * @return The smallest rect that contains the image of aBounds. |
|
809 */ |
|
810 static nsRect MatrixTransformRectOut(const nsRect &aBounds, |
|
811 const gfx3DMatrix &aMatrix, float aFactor); |
|
812 /** |
|
813 * Helper function that, given a point and a matrix, returns the image |
|
814 * of that point under the matrix transform. |
|
815 * |
|
816 * @param aPoint The point to transform. |
|
817 * @param aMatrix The matrix to transform it with. |
|
818 * @param aFactor The number of app units per graphics unit. |
|
819 * @return The image of the point under the transform. |
|
820 */ |
|
821 static nsPoint MatrixTransformPoint(const nsPoint &aPoint, |
|
822 const gfx3DMatrix &aMatrix, float aFactor); |
|
823 |
|
824 /** |
|
825 * Given a graphics rectangle in graphics space, return a rectangle in |
|
826 * app space that contains the graphics rectangle, rounding out as necessary. |
|
827 * |
|
828 * @param aRect The graphics rect to round outward. |
|
829 * @param aFactor The number of app units per graphics unit. |
|
830 * @return The smallest rectangle in app space that contains aRect. |
|
831 */ |
|
832 static nsRect RoundGfxRectToAppRect(const Rect &aRect, float aFactor); |
|
833 |
|
834 /** |
|
835 * Given a graphics rectangle in graphics space, return a rectangle in |
|
836 * app space that contains the graphics rectangle, rounding out as necessary. |
|
837 * |
|
838 * @param aRect The graphics rect to round outward. |
|
839 * @param aFactor The number of app units per graphics unit. |
|
840 * @return The smallest rectangle in app space that contains aRect. |
|
841 */ |
|
842 static nsRect RoundGfxRectToAppRect(const gfxRect &aRect, float aFactor); |
|
843 |
|
844 /** |
|
845 * Returns a subrectangle of aContainedRect that is entirely inside the rounded |
|
846 * rect. Complex cases are handled conservatively by returning a smaller |
|
847 * rect than necessary. |
|
848 */ |
|
849 static nsRegion RoundedRectIntersectRect(const nsRect& aRoundedRect, |
|
850 const nscoord aRadii[8], |
|
851 const nsRect& aContainedRect); |
|
852 |
|
853 /** |
|
854 * Return whether any part of aTestRect is inside of the rounded |
|
855 * rectangle formed by aBounds and aRadii (which are indexed by the |
|
856 * NS_CORNER_* constants in nsStyleConsts.h). This is precise. |
|
857 */ |
|
858 static bool RoundedRectIntersectsRect(const nsRect& aRoundedRect, |
|
859 const nscoord aRadii[8], |
|
860 const nsRect& aTestRect); |
|
861 |
|
862 enum { |
|
863 PAINT_IN_TRANSFORM = 0x01, |
|
864 PAINT_SYNC_DECODE_IMAGES = 0x02, |
|
865 PAINT_WIDGET_LAYERS = 0x04, |
|
866 PAINT_IGNORE_SUPPRESSION = 0x08, |
|
867 PAINT_DOCUMENT_RELATIVE = 0x10, |
|
868 PAINT_HIDE_CARET = 0x20, |
|
869 PAINT_ALL_CONTINUATIONS = 0x40, |
|
870 PAINT_TO_WINDOW = 0x80, |
|
871 PAINT_EXISTING_TRANSACTION = 0x100, |
|
872 PAINT_NO_COMPOSITE = 0x200, |
|
873 PAINT_COMPRESSED = 0x400 |
|
874 }; |
|
875 |
|
876 /** |
|
877 * Given aFrame, the root frame of a stacking context, paint it and its |
|
878 * descendants to aRenderingContext. |
|
879 * @param aRenderingContext a rendering context translated so that (0,0) |
|
880 * is the origin of aFrame; for best results, (0,0) should transform |
|
881 * to pixel-aligned coordinates. This can be null, in which case |
|
882 * aFrame must be a "display root" (root frame for a root document, |
|
883 * or the root of a popup) with an associated widget and we draw using |
|
884 * the layer manager for the frame's widget. |
|
885 * @param aDirtyRegion the region that must be painted, in the coordinates |
|
886 * of aFrame |
|
887 * @param aBackstop paint the dirty area with this color before drawing |
|
888 * the actual content; pass NS_RGBA(0,0,0,0) to draw no background |
|
889 * @param aFlags if PAINT_IN_TRANSFORM is set, then we assume |
|
890 * this is inside a transform or SVG foreignObject. If |
|
891 * PAINT_SYNC_DECODE_IMAGES is set, we force synchronous decode on all |
|
892 * images. If PAINT_WIDGET_LAYERS is set, aFrame must be a display root, |
|
893 * and we will use the frame's widget's layer manager to paint |
|
894 * even if aRenderingContext is non-null. This is useful if you want |
|
895 * to force rendering to use the widget's layer manager for testing |
|
896 * or speed. PAINT_WIDGET_LAYERS must be set if aRenderingContext is null. |
|
897 * If PAINT_DOCUMENT_RELATIVE is used, the visible region is interpreted |
|
898 * as being relative to the document. (Normally it's relative to the CSS |
|
899 * viewport.) PAINT_TO_WINDOW sets painting to window to true on the display |
|
900 * list builder even if we can't tell that we are painting to the window. |
|
901 * If PAINT_EXISTING_TRANSACTION is set, then BeginTransaction() has already |
|
902 * been called on aFrame's widget's layer manager and should not be |
|
903 * called again. |
|
904 * If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to compressed mode |
|
905 * to avoid short cut optimizations. |
|
906 * |
|
907 * So there are three possible behaviours: |
|
908 * 1) PAINT_WIDGET_LAYERS is set and aRenderingContext is null; we paint |
|
909 * by calling BeginTransaction on the widget's layer manager |
|
910 * 2) PAINT_WIDGET_LAYERS is set and aRenderingContext is non-null; we |
|
911 * paint by calling BeginTransactionWithTarget on the widget's layer |
|
912 * maanger |
|
913 * 3) PAINT_WIDGET_LAYERS is not set and aRenderingContext is non-null; |
|
914 * we paint by construct a BasicLayerManager and calling |
|
915 * BeginTransactionWithTarget on it. This is desirable if we're doing |
|
916 * something like drawWindow in a mode where what gets rendered doesn't |
|
917 * necessarily correspond to what's visible in the window; we don't |
|
918 * want to mess up the widget's layer tree. |
|
919 */ |
|
920 static nsresult PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFrame, |
|
921 const nsRegion& aDirtyRegion, nscolor aBackstop, |
|
922 uint32_t aFlags = 0); |
|
923 |
|
924 /** |
|
925 * Uses a binary search for find where the cursor falls in the line of text |
|
926 * It also keeps track of the part of the string that has already been measured |
|
927 * so it doesn't have to keep measuring the same text over and over |
|
928 * |
|
929 * @param "aBaseWidth" contains the width in twips of the portion |
|
930 * of the text that has already been measured, and aBaseInx contains |
|
931 * the index of the text that has already been measured. |
|
932 * |
|
933 * @param aTextWidth returns the (in twips) the length of the text that falls |
|
934 * before the cursor aIndex contains the index of the text where the cursor falls |
|
935 */ |
|
936 static bool |
|
937 BinarySearchForPosition(nsRenderingContext* acx, |
|
938 const char16_t* aText, |
|
939 int32_t aBaseWidth, |
|
940 int32_t aBaseInx, |
|
941 int32_t aStartInx, |
|
942 int32_t aEndInx, |
|
943 int32_t aCursorPos, |
|
944 int32_t& aIndex, |
|
945 int32_t& aTextWidth); |
|
946 |
|
947 class BoxCallback { |
|
948 public: |
|
949 virtual void AddBox(nsIFrame* aFrame) = 0; |
|
950 }; |
|
951 /** |
|
952 * Collect all CSS boxes associated with aFrame and its |
|
953 * continuations, "drilling down" through outer table frames and |
|
954 * some anonymous blocks since they're not real CSS boxes. |
|
955 * If aFrame is null, no boxes are returned. |
|
956 * SVG frames return a single box, themselves. |
|
957 */ |
|
958 static void GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback); |
|
959 |
|
960 /** |
|
961 * Find the first frame descendant of aFrame (including aFrame) which is |
|
962 * not an anonymous frame that getBoxQuads/getClientRects should ignore. |
|
963 */ |
|
964 static nsIFrame* GetFirstNonAnonymousFrame(nsIFrame* aFrame); |
|
965 |
|
966 class RectCallback { |
|
967 public: |
|
968 virtual void AddRect(const nsRect& aRect) = 0; |
|
969 }; |
|
970 |
|
971 struct RectAccumulator : public RectCallback { |
|
972 nsRect mResultRect; |
|
973 nsRect mFirstRect; |
|
974 bool mSeenFirstRect; |
|
975 |
|
976 RectAccumulator(); |
|
977 |
|
978 virtual void AddRect(const nsRect& aRect); |
|
979 }; |
|
980 |
|
981 struct RectListBuilder : public RectCallback { |
|
982 DOMRectList* mRectList; |
|
983 |
|
984 RectListBuilder(DOMRectList* aList); |
|
985 virtual void AddRect(const nsRect& aRect); |
|
986 }; |
|
987 |
|
988 static nsIFrame* GetContainingBlockForClientRect(nsIFrame* aFrame); |
|
989 |
|
990 enum { |
|
991 RECTS_ACCOUNT_FOR_TRANSFORMS = 0x01, |
|
992 // Two bits for specifying which box type to use. |
|
993 // With neither bit set (default), use the border box. |
|
994 RECTS_USE_CONTENT_BOX = 0x02, |
|
995 RECTS_USE_PADDING_BOX = 0x04, |
|
996 RECTS_USE_MARGIN_BOX = 0x06, // both bits set |
|
997 RECTS_WHICH_BOX_MASK = 0x06 // bitmask for these two bits |
|
998 }; |
|
999 /** |
|
1000 * Collect all CSS boxes (content, padding, border, or margin) associated |
|
1001 * with aFrame and its continuations, "drilling down" through outer table |
|
1002 * frames and some anonymous blocks since they're not real CSS boxes. |
|
1003 * The boxes are positioned relative to aRelativeTo (taking scrolling |
|
1004 * into account) and passed to the callback in frame-tree order. |
|
1005 * If aFrame is null, no boxes are returned. |
|
1006 * For SVG frames, returns one rectangle, the bounding box. |
|
1007 * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting |
|
1008 * the boxes into aRelativeTo coordinates, transforms (including CSS |
|
1009 * and SVG transforms) are taken into account. |
|
1010 * If aFlags includes one of RECTS_USE_CONTENT_BOX, RECTS_USE_PADDING_BOX, |
|
1011 * or RECTS_USE_MARGIN_BOX, the corresponding type of box is used. |
|
1012 * Otherwise (by default), the border box is used. |
|
1013 */ |
|
1014 static void GetAllInFlowRects(nsIFrame* aFrame, nsIFrame* aRelativeTo, |
|
1015 RectCallback* aCallback, uint32_t aFlags = 0); |
|
1016 |
|
1017 /** |
|
1018 * Computes the union of all rects returned by GetAllInFlowRects. If |
|
1019 * the union is empty, returns the first rect. |
|
1020 * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting |
|
1021 * the boxes into aRelativeTo coordinates, transforms (including CSS |
|
1022 * and SVG transforms) are taken into account. |
|
1023 * If aFlags includes one of RECTS_USE_CONTENT_BOX, RECTS_USE_PADDING_BOX, |
|
1024 * or RECTS_USE_MARGIN_BOX, the corresponding type of box is used. |
|
1025 * Otherwise (by default), the border box is used. |
|
1026 */ |
|
1027 static nsRect GetAllInFlowRectsUnion(nsIFrame* aFrame, nsIFrame* aRelativeTo, |
|
1028 uint32_t aFlags = 0); |
|
1029 |
|
1030 enum { |
|
1031 EXCLUDE_BLUR_SHADOWS = 0x01 |
|
1032 }; |
|
1033 /** |
|
1034 * Takes a text-shadow array from the style properties of a given nsIFrame and |
|
1035 * computes the union of those shadows along with the given initial rect. |
|
1036 * If there are no shadows, the initial rect is returned. |
|
1037 */ |
|
1038 static nsRect GetTextShadowRectsUnion(const nsRect& aTextAndDecorationsRect, |
|
1039 nsIFrame* aFrame, |
|
1040 uint32_t aFlags = 0); |
|
1041 |
|
1042 /** |
|
1043 * Get the font metrics corresponding to the frame's style data. |
|
1044 * @param aFrame the frame |
|
1045 * @param aFontMetrics the font metrics result |
|
1046 * @param aSizeInflation number to multiply font size by |
|
1047 * @return success or failure code |
|
1048 */ |
|
1049 static nsresult GetFontMetricsForFrame(const nsIFrame* aFrame, |
|
1050 nsFontMetrics** aFontMetrics, |
|
1051 float aSizeInflation = 1.0f); |
|
1052 |
|
1053 /** |
|
1054 * Get the font metrics corresponding to the given style data. |
|
1055 * @param aStyleContext the style data |
|
1056 * @param aFontMetrics the font metrics result |
|
1057 * @param aSizeInflation number to multiply font size by |
|
1058 * @return success or failure code |
|
1059 */ |
|
1060 static nsresult GetFontMetricsForStyleContext(nsStyleContext* aStyleContext, |
|
1061 nsFontMetrics** aFontMetrics, |
|
1062 float aSizeInflation = 1.0f); |
|
1063 |
|
1064 /** |
|
1065 * Find the immediate child of aParent whose frame subtree contains |
|
1066 * aDescendantFrame. Returns null if aDescendantFrame is not a descendant |
|
1067 * of aParent. |
|
1068 */ |
|
1069 static nsIFrame* FindChildContainingDescendant(nsIFrame* aParent, nsIFrame* aDescendantFrame); |
|
1070 |
|
1071 /** |
|
1072 * Find the nearest ancestor that's a block |
|
1073 */ |
|
1074 static nsBlockFrame* FindNearestBlockAncestor(nsIFrame* aFrame); |
|
1075 |
|
1076 /** |
|
1077 * Find the nearest ancestor that's not for generated content. Will return |
|
1078 * aFrame if aFrame is not for generated content. |
|
1079 */ |
|
1080 static nsIFrame* GetNonGeneratedAncestor(nsIFrame* aFrame); |
|
1081 |
|
1082 /** |
|
1083 * Cast aFrame to an nsBlockFrame* or return null if it's not |
|
1084 * an nsBlockFrame. |
|
1085 */ |
|
1086 static nsBlockFrame* GetAsBlock(nsIFrame* aFrame); |
|
1087 |
|
1088 /* |
|
1089 * Whether the frame is an nsBlockFrame which is not a wrapper block. |
|
1090 */ |
|
1091 static bool IsNonWrapperBlock(nsIFrame* aFrame); |
|
1092 |
|
1093 /** |
|
1094 * If aFrame is an out of flow frame, return its placeholder, otherwise |
|
1095 * return its parent. |
|
1096 */ |
|
1097 static nsIFrame* GetParentOrPlaceholderFor(nsIFrame* aFrame); |
|
1098 |
|
1099 /** |
|
1100 * If aFrame is an out of flow frame, return its placeholder, otherwise |
|
1101 * return its (possibly cross-doc) parent. |
|
1102 */ |
|
1103 static nsIFrame* GetParentOrPlaceholderForCrossDoc(nsIFrame* aFrame); |
|
1104 |
|
1105 /** |
|
1106 * Get a frame's next-in-flow, or, if it doesn't have one, its |
|
1107 * block-in-inline-split sibling. |
|
1108 */ |
|
1109 static nsIFrame* |
|
1110 GetNextContinuationOrIBSplitSibling(nsIFrame *aFrame); |
|
1111 |
|
1112 /** |
|
1113 * Get the first frame in the continuation-plus-ib-split-sibling chain |
|
1114 * containing aFrame. |
|
1115 */ |
|
1116 static nsIFrame* |
|
1117 FirstContinuationOrIBSplitSibling(nsIFrame *aFrame); |
|
1118 |
|
1119 /** |
|
1120 * Is FirstContinuationOrIBSplitSibling(aFrame) going to return |
|
1121 * aFrame? |
|
1122 */ |
|
1123 static bool |
|
1124 IsFirstContinuationOrIBSplitSibling(nsIFrame *aFrame); |
|
1125 |
|
1126 /** |
|
1127 * Check whether aFrame is a part of the scrollbar or scrollcorner of |
|
1128 * the root content. |
|
1129 * @param aFrame the checking frame |
|
1130 * @return if TRUE, the frame is a part of the scrollbar or scrollcorner of |
|
1131 * the root content. |
|
1132 */ |
|
1133 static bool IsViewportScrollbarFrame(nsIFrame* aFrame); |
|
1134 |
|
1135 /** |
|
1136 * Get the contribution of aFrame to its containing block's intrinsic |
|
1137 * width. This considers the child's intrinsic width, its 'width', |
|
1138 * 'min-width', and 'max-width' properties, and its padding, border, |
|
1139 * and margin. |
|
1140 */ |
|
1141 enum IntrinsicWidthType { MIN_WIDTH, PREF_WIDTH }; |
|
1142 enum { |
|
1143 IGNORE_PADDING = 0x01 |
|
1144 }; |
|
1145 static nscoord IntrinsicForContainer(nsRenderingContext* aRenderingContext, |
|
1146 nsIFrame* aFrame, |
|
1147 IntrinsicWidthType aType, |
|
1148 uint32_t aFlags = 0); |
|
1149 |
|
1150 /* |
|
1151 * Convert nsStyleCoord to nscoord when percentages depend on the |
|
1152 * containing block size. |
|
1153 * @param aPercentBasis The width or height of the containing block |
|
1154 * (whichever the client wants to use for resolving percentages). |
|
1155 */ |
|
1156 static nscoord ComputeCBDependentValue(nscoord aPercentBasis, |
|
1157 const nsStyleCoord& aCoord); |
|
1158 |
|
1159 /* |
|
1160 * Convert nsStyleCoord to nscoord when percentages depend on the |
|
1161 * containing block width, and enumerated values are for width, |
|
1162 * min-width, or max-width. Returns the content-box width value based |
|
1163 * on aContentEdgeToBoxSizing and aBoxSizingToMarginEdge (which are |
|
1164 * also used for the enumerated values for width. This function does |
|
1165 * not handle 'auto'. It ensures that the result is nonnegative. |
|
1166 * |
|
1167 * @param aRenderingContext Rendering context for font measurement/metrics. |
|
1168 * @param aFrame Frame whose (min-/max-/)width is being computed |
|
1169 * @param aContainingBlockWidth Width of aFrame's containing block. |
|
1170 * @param aContentEdgeToBoxSizing The sum of any left/right padding and |
|
1171 * border that goes inside the rect chosen by box-sizing. |
|
1172 * @param aBoxSizingToMarginEdge The sum of any left/right padding, border, |
|
1173 * and margin that goes outside the rect chosen by box-sizing. |
|
1174 * @param aCoord The width value to compute. |
|
1175 */ |
|
1176 static nscoord ComputeWidthValue( |
|
1177 nsRenderingContext* aRenderingContext, |
|
1178 nsIFrame* aFrame, |
|
1179 nscoord aContainingBlockWidth, |
|
1180 nscoord aContentEdgeToBoxSizing, |
|
1181 nscoord aBoxSizingToMarginEdge, |
|
1182 const nsStyleCoord& aCoord); |
|
1183 |
|
1184 /* |
|
1185 * Convert nsStyleCoord to nscoord when percentages depend on the |
|
1186 * containing block height. |
|
1187 */ |
|
1188 static nscoord ComputeHeightDependentValue( |
|
1189 nscoord aContainingBlockHeight, |
|
1190 const nsStyleCoord& aCoord); |
|
1191 |
|
1192 /* |
|
1193 * Likewise, but for 'height', 'min-height', or 'max-height'. |
|
1194 */ |
|
1195 static nscoord ComputeHeightValue(nscoord aContainingBlockHeight, |
|
1196 nscoord aContentEdgeToBoxSizingBoxEdge, |
|
1197 const nsStyleCoord& aCoord) |
|
1198 { |
|
1199 MOZ_ASSERT(aContainingBlockHeight != nscoord_MAX || !aCoord.HasPercent(), |
|
1200 "caller must deal with %% of unconstrained height"); |
|
1201 MOZ_ASSERT(aCoord.IsCoordPercentCalcUnit()); |
|
1202 |
|
1203 nscoord result = |
|
1204 nsRuleNode::ComputeCoordPercentCalc(aCoord, aContainingBlockHeight); |
|
1205 // Clamp calc(), and the subtraction for box-sizing. |
|
1206 return std::max(0, result - aContentEdgeToBoxSizingBoxEdge); |
|
1207 } |
|
1208 |
|
1209 static bool IsAutoHeight(const nsStyleCoord &aCoord, nscoord aCBHeight) |
|
1210 { |
|
1211 nsStyleUnit unit = aCoord.GetUnit(); |
|
1212 return unit == eStyleUnit_Auto || // only for 'height' |
|
1213 unit == eStyleUnit_None || // only for 'max-height' |
|
1214 (aCBHeight == nscoord_MAX && aCoord.HasPercent()); |
|
1215 } |
|
1216 |
|
1217 static bool IsPaddingZero(const nsStyleCoord &aCoord) |
|
1218 { |
|
1219 return (aCoord.GetUnit() == eStyleUnit_Coord && |
|
1220 aCoord.GetCoordValue() == 0) || |
|
1221 (aCoord.GetUnit() == eStyleUnit_Percent && |
|
1222 aCoord.GetPercentValue() == 0.0f) || |
|
1223 (aCoord.IsCalcUnit() && |
|
1224 // clamp negative calc() to 0 |
|
1225 nsRuleNode::ComputeCoordPercentCalc(aCoord, nscoord_MAX) <= 0 && |
|
1226 nsRuleNode::ComputeCoordPercentCalc(aCoord, 0) <= 0); |
|
1227 } |
|
1228 |
|
1229 static bool IsMarginZero(const nsStyleCoord &aCoord) |
|
1230 { |
|
1231 return (aCoord.GetUnit() == eStyleUnit_Coord && |
|
1232 aCoord.GetCoordValue() == 0) || |
|
1233 (aCoord.GetUnit() == eStyleUnit_Percent && |
|
1234 aCoord.GetPercentValue() == 0.0f) || |
|
1235 (aCoord.IsCalcUnit() && |
|
1236 nsRuleNode::ComputeCoordPercentCalc(aCoord, nscoord_MAX) == 0 && |
|
1237 nsRuleNode::ComputeCoordPercentCalc(aCoord, 0) == 0); |
|
1238 } |
|
1239 |
|
1240 static void MarkDescendantsDirty(nsIFrame *aSubtreeRoot); |
|
1241 |
|
1242 /* |
|
1243 * Calculate the used values for 'width' and 'height' for a replaced element. |
|
1244 * |
|
1245 * http://www.w3.org/TR/CSS21/visudet.html#min-max-widths |
|
1246 */ |
|
1247 static nsSize ComputeSizeWithIntrinsicDimensions( |
|
1248 nsRenderingContext* aRenderingContext, nsIFrame* aFrame, |
|
1249 const mozilla::IntrinsicSize& aIntrinsicSize, |
|
1250 nsSize aIntrinsicRatio, nsSize aCBSize, |
|
1251 nsSize aMargin, nsSize aBorder, nsSize aPadding); |
|
1252 |
|
1253 /* |
|
1254 * Calculate the used values for 'width' and 'height' when width |
|
1255 * and height are 'auto'. The tentWidth and tentHeight arguments should be |
|
1256 * the result of applying the rules for computing intrinsic sizes and ratios. |
|
1257 * as specified by CSS 2.1 sections 10.3.2 and 10.6.2 |
|
1258 */ |
|
1259 static nsSize ComputeAutoSizeWithIntrinsicDimensions(nscoord minWidth, nscoord minHeight, |
|
1260 nscoord maxWidth, nscoord maxHeight, |
|
1261 nscoord tentWidth, nscoord tentHeight); |
|
1262 |
|
1263 // Implement nsIFrame::GetPrefWidth in terms of nsIFrame::AddInlinePrefWidth |
|
1264 static nscoord PrefWidthFromInline(nsIFrame* aFrame, |
|
1265 nsRenderingContext* aRenderingContext); |
|
1266 |
|
1267 // Implement nsIFrame::GetMinWidth in terms of nsIFrame::AddInlineMinWidth |
|
1268 static nscoord MinWidthFromInline(nsIFrame* aFrame, |
|
1269 nsRenderingContext* aRenderingContext); |
|
1270 |
|
1271 // Get a suitable foreground color for painting aProperty for aFrame. |
|
1272 static nscolor GetColor(nsIFrame* aFrame, nsCSSProperty aProperty); |
|
1273 |
|
1274 // Get the native text color if appropriate. If false is returned, callers |
|
1275 // should fallback to the CSS color. |
|
1276 static bool GetNativeTextColor(nsIFrame* aFrame, nscolor& aColor); |
|
1277 |
|
1278 // Get a baseline y position in app units that is snapped to device pixels. |
|
1279 static gfxFloat GetSnappedBaselineY(nsIFrame* aFrame, gfxContext* aContext, |
|
1280 nscoord aY, nscoord aAscent); |
|
1281 |
|
1282 static void DrawString(const nsIFrame* aFrame, |
|
1283 nsRenderingContext* aContext, |
|
1284 const char16_t* aString, |
|
1285 int32_t aLength, |
|
1286 nsPoint aPoint, |
|
1287 nsStyleContext* aStyleContext = nullptr); |
|
1288 |
|
1289 static nscoord GetStringWidth(const nsIFrame* aFrame, |
|
1290 nsRenderingContext* aContext, |
|
1291 const char16_t* aString, |
|
1292 int32_t aLength); |
|
1293 |
|
1294 /** |
|
1295 * Helper function for drawing text-shadow. The callback's job |
|
1296 * is to draw whatever needs to be blurred onto the given context. |
|
1297 */ |
|
1298 typedef void (* TextShadowCallback)(nsRenderingContext* aCtx, |
|
1299 nsPoint aShadowOffset, |
|
1300 const nscolor& aShadowColor, |
|
1301 void* aData); |
|
1302 |
|
1303 static void PaintTextShadow(const nsIFrame* aFrame, |
|
1304 nsRenderingContext* aContext, |
|
1305 const nsRect& aTextRect, |
|
1306 const nsRect& aDirtyRect, |
|
1307 const nscolor& aForegroundColor, |
|
1308 TextShadowCallback aCallback, |
|
1309 void* aCallbackData); |
|
1310 |
|
1311 /** |
|
1312 * Gets the baseline to vertically center text from a font within a |
|
1313 * line of specified height. |
|
1314 * |
|
1315 * Returns the baseline position relative to the top of the line. |
|
1316 */ |
|
1317 static nscoord GetCenteredFontBaseline(nsFontMetrics* aFontMetrics, |
|
1318 nscoord aLineHeight); |
|
1319 |
|
1320 /** |
|
1321 * Derive a baseline of |aFrame| (measured from its top border edge) |
|
1322 * from its first in-flow line box (not descending into anything with |
|
1323 * 'overflow' not 'visible', potentially including aFrame itself). |
|
1324 * |
|
1325 * Returns true if a baseline was found (and fills in aResult). |
|
1326 * Otherwise returns false. |
|
1327 */ |
|
1328 static bool GetFirstLineBaseline(const nsIFrame* aFrame, nscoord* aResult); |
|
1329 |
|
1330 /** |
|
1331 * Just like GetFirstLineBaseline, except also returns the top and |
|
1332 * bottom of the line with the baseline. |
|
1333 * |
|
1334 * Returns true if a line was found (and fills in aResult). |
|
1335 * Otherwise returns false. |
|
1336 */ |
|
1337 struct LinePosition { |
|
1338 nscoord mTop, mBaseline, mBottom; |
|
1339 |
|
1340 LinePosition operator+(nscoord aOffset) const { |
|
1341 LinePosition result; |
|
1342 result.mTop = mTop + aOffset; |
|
1343 result.mBaseline = mBaseline + aOffset; |
|
1344 result.mBottom = mBottom + aOffset; |
|
1345 return result; |
|
1346 } |
|
1347 }; |
|
1348 static bool GetFirstLinePosition(const nsIFrame* aFrame, |
|
1349 LinePosition* aResult); |
|
1350 |
|
1351 |
|
1352 /** |
|
1353 * Derive a baseline of |aFrame| (measured from its top border edge) |
|
1354 * from its last in-flow line box (not descending into anything with |
|
1355 * 'overflow' not 'visible', potentially including aFrame itself). |
|
1356 * |
|
1357 * Returns true if a baseline was found (and fills in aResult). |
|
1358 * Otherwise returns false. |
|
1359 */ |
|
1360 static bool GetLastLineBaseline(const nsIFrame* aFrame, nscoord* aResult); |
|
1361 |
|
1362 /** |
|
1363 * Returns a y coordinate relative to this frame's origin that represents |
|
1364 * the logical bottom of the frame or its visible content, whichever is lower. |
|
1365 * Relative positioning is ignored and margins and glyph bounds are not |
|
1366 * considered. |
|
1367 * This value will be >= mRect.height() and <= overflowRect.YMost() unless |
|
1368 * relative positioning is applied. |
|
1369 */ |
|
1370 static nscoord CalculateContentBottom(nsIFrame* aFrame); |
|
1371 |
|
1372 /** |
|
1373 * Gets the closest frame (the frame passed in or one of its parents) that |
|
1374 * qualifies as a "layer"; used in DOM0 methods that depends upon that |
|
1375 * definition. This is the nearest frame that is either positioned or scrolled |
|
1376 * (the child of a scroll frame). |
|
1377 */ |
|
1378 static nsIFrame* GetClosestLayer(nsIFrame* aFrame); |
|
1379 |
|
1380 /** |
|
1381 * Gets the graphics filter for the frame |
|
1382 */ |
|
1383 static GraphicsFilter GetGraphicsFilterForFrame(nsIFrame* aFrame); |
|
1384 |
|
1385 /* N.B. The only difference between variants of the Draw*Image |
|
1386 * functions below is the type of the aImage argument. |
|
1387 */ |
|
1388 |
|
1389 /** |
|
1390 * Draw a background image. The image's dimensions are as specified in aDest; |
|
1391 * the image itself is not consulted to determine a size. |
|
1392 * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering |
|
1393 * @param aRenderingContext Where to draw the image, set up with an |
|
1394 * appropriate scale and transform for drawing in |
|
1395 * app units. |
|
1396 * @param aImage The image. |
|
1397 * @param aImageSize The unscaled size of the image being drawn. |
|
1398 * (This might be the image's size if no scaling |
|
1399 * occurs, or it might be the image's size if |
|
1400 * the image is a vector image being rendered at |
|
1401 * that size.) |
|
1402 * @param aDest The position and scaled area where one copy of |
|
1403 * the image should be drawn. |
|
1404 * @param aFill The area to be filled with copies of the |
|
1405 * image. |
|
1406 * @param aAnchor A point in aFill which we will ensure is |
|
1407 * pixel-aligned in the output. |
|
1408 * @param aDirty Pixels outside this area may be skipped. |
|
1409 * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety |
|
1410 */ |
|
1411 static nsresult DrawBackgroundImage(nsRenderingContext* aRenderingContext, |
|
1412 imgIContainer* aImage, |
|
1413 const nsIntSize& aImageSize, |
|
1414 GraphicsFilter aGraphicsFilter, |
|
1415 const nsRect& aDest, |
|
1416 const nsRect& aFill, |
|
1417 const nsPoint& aAnchor, |
|
1418 const nsRect& aDirty, |
|
1419 uint32_t aImageFlags); |
|
1420 |
|
1421 /** |
|
1422 * Draw an image. |
|
1423 * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering |
|
1424 * @param aRenderingContext Where to draw the image, set up with an |
|
1425 * appropriate scale and transform for drawing in |
|
1426 * app units. |
|
1427 * @param aImage The image. |
|
1428 * @param aDest Where one copy of the image should mapped to. |
|
1429 * @param aFill The area to be filled with copies of the |
|
1430 * image. |
|
1431 * @param aAnchor A point in aFill which we will ensure is |
|
1432 * pixel-aligned in the output. |
|
1433 * @param aDirty Pixels outside this area may be skipped. |
|
1434 * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety |
|
1435 */ |
|
1436 static nsresult DrawImage(nsRenderingContext* aRenderingContext, |
|
1437 imgIContainer* aImage, |
|
1438 GraphicsFilter aGraphicsFilter, |
|
1439 const nsRect& aDest, |
|
1440 const nsRect& aFill, |
|
1441 const nsPoint& aAnchor, |
|
1442 const nsRect& aDirty, |
|
1443 uint32_t aImageFlags); |
|
1444 |
|
1445 /** |
|
1446 * Convert an nsRect to a gfxRect. |
|
1447 */ |
|
1448 static gfxRect RectToGfxRect(const nsRect& aRect, |
|
1449 int32_t aAppUnitsPerDevPixel); |
|
1450 |
|
1451 /** |
|
1452 * Draw a drawable using the pixel snapping algorithm. |
|
1453 * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering |
|
1454 * @param aRenderingContext Where to draw the image, set up with an |
|
1455 * appropriate scale and transform for drawing in |
|
1456 * app units. |
|
1457 * @param aDrawable The drawable we want to draw. |
|
1458 * @param aFilter The graphics filter we should draw with. |
|
1459 * @param aDest Where one copy of the image should mapped to. |
|
1460 * @param aFill The area to be filled with copies of the |
|
1461 * image. |
|
1462 * @param aAnchor A point in aFill which we will ensure is |
|
1463 * pixel-aligned in the output. |
|
1464 * @param aDirty Pixels outside this area may be skipped. |
|
1465 */ |
|
1466 static void DrawPixelSnapped(nsRenderingContext* aRenderingContext, |
|
1467 gfxDrawable* aDrawable, |
|
1468 GraphicsFilter aFilter, |
|
1469 const nsRect& aDest, |
|
1470 const nsRect& aFill, |
|
1471 const nsPoint& aAnchor, |
|
1472 const nsRect& aDirty); |
|
1473 |
|
1474 /** |
|
1475 * Draw a whole image without scaling or tiling. |
|
1476 * |
|
1477 * @param aRenderingContext Where to draw the image, set up with an |
|
1478 * appropriate scale and transform for drawing in |
|
1479 * app units. |
|
1480 * @param aImage The image. |
|
1481 * @param aDest The top-left where the image should be drawn |
|
1482 * @param aDirty If non-null, then pixels outside this area may |
|
1483 * be skipped. |
|
1484 * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety |
|
1485 * @param aSourceArea If non-null, this area is extracted from |
|
1486 * the image and drawn at aDest. It's |
|
1487 * in appunits. For best results it should |
|
1488 * be aligned with image pixels. |
|
1489 */ |
|
1490 static nsresult DrawSingleUnscaledImage(nsRenderingContext* aRenderingContext, |
|
1491 imgIContainer* aImage, |
|
1492 GraphicsFilter aGraphicsFilter, |
|
1493 const nsPoint& aDest, |
|
1494 const nsRect* aDirty, |
|
1495 uint32_t aImageFlags, |
|
1496 const nsRect* aSourceArea = nullptr); |
|
1497 |
|
1498 /** |
|
1499 * Draw a whole image without tiling. |
|
1500 * |
|
1501 * @param aRenderingContext Where to draw the image, set up with an |
|
1502 * appropriate scale and transform for drawing in |
|
1503 * app units. |
|
1504 * @param aImage The image. |
|
1505 * @param aDest The area that the image should fill |
|
1506 * @param aDirty Pixels outside this area may be skipped. |
|
1507 * @param aSVGContext If non-null, SVG-related rendering context |
|
1508 * such as overridden attributes on the image |
|
1509 * document's root <svg> node. Ignored for |
|
1510 * raster images. |
|
1511 * @param aImageFlags Image flags of the imgIContainer::FLAG_* |
|
1512 * variety. |
|
1513 * @param aSourceArea If non-null, this area is extracted from |
|
1514 * the image and drawn in aDest. It's |
|
1515 * in appunits. For best results it should |
|
1516 * be aligned with image pixels. |
|
1517 */ |
|
1518 static nsresult DrawSingleImage(nsRenderingContext* aRenderingContext, |
|
1519 imgIContainer* aImage, |
|
1520 GraphicsFilter aGraphicsFilter, |
|
1521 const nsRect& aDest, |
|
1522 const nsRect& aDirty, |
|
1523 const mozilla::SVGImageContext* aSVGContext, |
|
1524 uint32_t aImageFlags, |
|
1525 const nsRect* aSourceArea = nullptr); |
|
1526 |
|
1527 /** |
|
1528 * Given an imgIContainer, this method attempts to obtain an intrinsic |
|
1529 * px-valued height & width for it. If the imgIContainer has a non-pixel |
|
1530 * value for either height or width, this method tries to generate a pixel |
|
1531 * value for that dimension using the intrinsic ratio (if available). The |
|
1532 * intrinsic ratio will be assigned to aIntrinsicRatio; if there's no |
|
1533 * intrinsic ratio then (0, 0) will be assigned. |
|
1534 * |
|
1535 * This method will always set aGotWidth and aGotHeight to indicate whether |
|
1536 * we were able to successfully obtain (or compute) a value for each |
|
1537 * dimension. |
|
1538 * |
|
1539 * NOTE: This method is similar to ComputeSizeWithIntrinsicDimensions. The |
|
1540 * difference is that this one is simpler and is suited to places where we |
|
1541 * have less information about the frame tree. |
|
1542 */ |
|
1543 static void ComputeSizeForDrawing(imgIContainer* aImage, |
|
1544 nsIntSize& aImageSize, |
|
1545 nsSize& aIntrinsicRatio, |
|
1546 bool& aGotWidth, |
|
1547 bool& aGotHeight); |
|
1548 |
|
1549 /** |
|
1550 * Given a source area of an image (in appunits) and a destination area |
|
1551 * that we want to map that source area too, computes the area that |
|
1552 * would be covered by the whole image. This is useful for passing to |
|
1553 * the aDest parameter of DrawImage, when we want to draw a subimage |
|
1554 * of an overall image. |
|
1555 */ |
|
1556 static nsRect GetWholeImageDestination(const nsIntSize& aWholeImageSize, |
|
1557 const nsRect& aImageSourceArea, |
|
1558 const nsRect& aDestArea); |
|
1559 |
|
1560 /** |
|
1561 * Given an image container and an orientation, returns an image container |
|
1562 * that contains the same image, reoriented appropriately. May return the |
|
1563 * original image container if no changes are needed. |
|
1564 * |
|
1565 * @param aContainer The image container to apply the orientation to. |
|
1566 * @param aOrientation The desired orientation. |
|
1567 */ |
|
1568 static already_AddRefed<imgIContainer> |
|
1569 OrientImage(imgIContainer* aContainer, |
|
1570 const nsStyleImageOrientation& aOrientation); |
|
1571 |
|
1572 /** |
|
1573 * Determine if any corner radius is of nonzero size |
|
1574 * @param aCorners the |nsStyleCorners| object to check |
|
1575 * @return true unless all the coordinates are 0%, 0 or null. |
|
1576 * |
|
1577 * A corner radius with one dimension zero and one nonzero is |
|
1578 * treated as a nonzero-radius corner, even though it will end up |
|
1579 * being rendered like a zero-radius corner. This is because such |
|
1580 * corners are not expected to appear outside of test cases, and it's |
|
1581 * simpler to implement the test this way. |
|
1582 */ |
|
1583 static bool HasNonZeroCorner(const nsStyleCorners& aCorners); |
|
1584 |
|
1585 /** |
|
1586 * Determine if there is any corner radius on corners adjacent to the |
|
1587 * given side. |
|
1588 */ |
|
1589 static bool HasNonZeroCornerOnSide(const nsStyleCorners& aCorners, |
|
1590 mozilla::css::Side aSide); |
|
1591 |
|
1592 /** |
|
1593 * Determine if a widget is likely to require transparency or translucency. |
|
1594 * @param aBackgroundFrame The frame that the background is set on. For |
|
1595 * <window>s, this will be the canvas frame. |
|
1596 * @param aCSSRootFrame The frame that holds CSS properties affecting |
|
1597 * the widget's transparency. For menupopups, |
|
1598 * aBackgroundFrame and aCSSRootFrame will be the |
|
1599 * same. |
|
1600 * @return a value suitable for passing to SetWindowTranslucency |
|
1601 */ |
|
1602 static nsTransparencyMode GetFrameTransparency(nsIFrame* aBackgroundFrame, |
|
1603 nsIFrame* aCSSRootFrame); |
|
1604 |
|
1605 /** |
|
1606 * A frame is a popup if it has its own floating window. Menus, panels |
|
1607 * and combobox dropdowns are popups. |
|
1608 */ |
|
1609 static bool IsPopup(nsIFrame* aFrame); |
|
1610 |
|
1611 /** |
|
1612 * Find the nearest "display root". This is the nearest enclosing |
|
1613 * popup frame or the root prescontext's root frame. |
|
1614 */ |
|
1615 static nsIFrame* GetDisplayRootFrame(nsIFrame* aFrame); |
|
1616 |
|
1617 /** |
|
1618 * Get the reference frame that would be used when constructing a |
|
1619 * display item for this frame. (Note, however, that |
|
1620 * nsDisplayTransform use the reference frame appropriate for their |
|
1621 * GetTransformRootFrame(), rather than using their own frame as a |
|
1622 * reference frame.) |
|
1623 * |
|
1624 * This duplicates some of the logic of GetDisplayRootFrame above and |
|
1625 * of nsDisplayListBuilder::FindReferenceFrameFor. |
|
1626 * |
|
1627 * If you have an nsDisplayListBuilder, you should get the reference |
|
1628 * frame from it instead of calling this. |
|
1629 */ |
|
1630 static nsIFrame* GetReferenceFrame(nsIFrame* aFrame); |
|
1631 |
|
1632 /** |
|
1633 * Get the parent of this frame, except if that parent is part of a |
|
1634 * preserve-3d hierarchy, get the parent of the root of the |
|
1635 * preserve-3d hierarchy. |
|
1636 * |
|
1637 * (This is used as the starting point for reference frame computation |
|
1638 * for nsDisplayTransform display items.) |
|
1639 */ |
|
1640 static nsIFrame* GetTransformRootFrame(nsIFrame* aFrame); |
|
1641 |
|
1642 /** |
|
1643 * Get textrun construction flags determined by a given style; in particular |
|
1644 * some combination of: |
|
1645 * -- TEXT_DISABLE_OPTIONAL_LIGATURES if letter-spacing is in use |
|
1646 * -- TEXT_OPTIMIZE_SPEED if the text-rendering CSS property and font size |
|
1647 * and prefs indicate we should be optimizing for speed over quality |
|
1648 */ |
|
1649 static uint32_t GetTextRunFlagsForStyle(nsStyleContext* aStyleContext, |
|
1650 const nsStyleFont* aStyleFont, |
|
1651 const nsStyleText* aStyleText, |
|
1652 nscoord aLetterSpacing); |
|
1653 |
|
1654 /** |
|
1655 * Takes two rectangles whose origins must be the same, and computes |
|
1656 * the difference between their union and their intersection as two |
|
1657 * rectangles. (This difference is a superset of the difference |
|
1658 * between the two rectangles.) |
|
1659 */ |
|
1660 static void GetRectDifferenceStrips(const nsRect& aR1, const nsRect& aR2, |
|
1661 nsRect* aHStrip, nsRect* aVStrip); |
|
1662 |
|
1663 /** |
|
1664 * Get a device context that can be used to get up-to-date device |
|
1665 * dimensions for the given window. For some reason, this is more |
|
1666 * complicated than it ought to be in multi-monitor situations. |
|
1667 */ |
|
1668 static nsDeviceContext* |
|
1669 GetDeviceContextForScreenInfo(nsPIDOMWindow* aWindow); |
|
1670 |
|
1671 /** |
|
1672 * Some frames with 'position: fixed' (nsStylePosition::mDisplay == |
|
1673 * NS_STYLE_POSITION_FIXED) are not really fixed positioned, since |
|
1674 * they're inside an element with -moz-transform. This function says |
|
1675 * whether such an element is a real fixed-pos element. |
|
1676 */ |
|
1677 static bool IsReallyFixedPos(nsIFrame* aFrame); |
|
1678 |
|
1679 /** |
|
1680 * Obtain a gfxASurface from the given DOM element, if possible. |
|
1681 * This obtains the most natural surface from the element; that |
|
1682 * is, the one that can be obtained with the fewest conversions. |
|
1683 * |
|
1684 * The flags below can modify the behaviour of this function. The |
|
1685 * result is returned as a SurfaceFromElementResult struct, also |
|
1686 * defined below. |
|
1687 * |
|
1688 * Currently, this will do: |
|
1689 * - HTML Canvas elements: will return the underlying canvas surface |
|
1690 * - HTML Video elements: will return the current video frame |
|
1691 * - Image elements: will return the image |
|
1692 * |
|
1693 * The above results are modified by the below flags (copying, |
|
1694 * forcing image surface, etc.). |
|
1695 */ |
|
1696 |
|
1697 enum { |
|
1698 /* When creating a new surface, create an image surface */ |
|
1699 SFE_WANT_IMAGE_SURFACE = 1 << 0, |
|
1700 /* Whether to extract the first frame (as opposed to the |
|
1701 current frame) in the case that the element is an image. */ |
|
1702 SFE_WANT_FIRST_FRAME = 1 << 1, |
|
1703 /* Whether we should skip colorspace/gamma conversion */ |
|
1704 SFE_NO_COLORSPACE_CONVERSION = 1 << 2, |
|
1705 /* Specifies that the caller wants unpremultiplied pixel data. |
|
1706 If this is can be done efficiently, the result will be a |
|
1707 DataSourceSurface and mIsPremultiplied with be set to false. */ |
|
1708 SFE_PREFER_NO_PREMULTIPLY_ALPHA = 1 << 3, |
|
1709 /* Whether we should skip getting a surface for vector images and |
|
1710 return a DirectDrawInfo containing an imgIContainer instead. */ |
|
1711 SFE_NO_RASTERIZING_VECTORS = 1 << 4 |
|
1712 }; |
|
1713 |
|
1714 struct DirectDrawInfo { |
|
1715 /* imgIContainer to directly draw to a context */ |
|
1716 nsCOMPtr<imgIContainer> mImgContainer; |
|
1717 /* which frame to draw */ |
|
1718 uint32_t mWhichFrame; |
|
1719 /* imgIContainer flags to use when drawing */ |
|
1720 uint32_t mDrawingFlags; |
|
1721 }; |
|
1722 |
|
1723 struct SurfaceFromElementResult { |
|
1724 SurfaceFromElementResult(); |
|
1725 |
|
1726 /* mSurface will contain the resulting surface, or will be nullptr on error */ |
|
1727 nsRefPtr<gfxASurface> mSurface; |
|
1728 mozilla::RefPtr<SourceSurface> mSourceSurface; |
|
1729 /* Contains info for drawing when there is no mSourceSurface. */ |
|
1730 DirectDrawInfo mDrawInfo; |
|
1731 |
|
1732 /* The size of the surface */ |
|
1733 gfxIntSize mSize; |
|
1734 /* The principal associated with the element whose surface was returned. |
|
1735 If there is a surface, this will never be null. */ |
|
1736 nsCOMPtr<nsIPrincipal> mPrincipal; |
|
1737 /* The image request, if the element is an nsIImageLoadingContent */ |
|
1738 nsCOMPtr<imgIRequest> mImageRequest; |
|
1739 /* Whether the element was "write only", that is, the bits should not be exposed to content */ |
|
1740 bool mIsWriteOnly; |
|
1741 /* Whether the element was still loading. Some consumers need to handle |
|
1742 this case specially. */ |
|
1743 bool mIsStillLoading; |
|
1744 /* Whether the element used CORS when loading. */ |
|
1745 bool mCORSUsed; |
|
1746 /* Whether the returned image contains premultiplied pixel data */ |
|
1747 bool mIsPremultiplied; |
|
1748 }; |
|
1749 |
|
1750 static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::Element *aElement, |
|
1751 uint32_t aSurfaceFlags = 0, |
|
1752 DrawTarget *aTarget = nullptr); |
|
1753 static SurfaceFromElementResult SurfaceFromElement(nsIImageLoadingContent *aElement, |
|
1754 uint32_t aSurfaceFlags = 0, |
|
1755 DrawTarget *aTarget = nullptr); |
|
1756 // Need an HTMLImageElement overload, because otherwise the |
|
1757 // nsIImageLoadingContent and mozilla::dom::Element overloads are ambiguous |
|
1758 // for HTMLImageElement. |
|
1759 static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::HTMLImageElement *aElement, |
|
1760 uint32_t aSurfaceFlags = 0, |
|
1761 DrawTarget *aTarget = nullptr); |
|
1762 static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::HTMLCanvasElement *aElement, |
|
1763 uint32_t aSurfaceFlags = 0, |
|
1764 DrawTarget *aTarget = nullptr); |
|
1765 static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::HTMLVideoElement *aElement, |
|
1766 uint32_t aSurfaceFlags = 0, |
|
1767 DrawTarget *aTarget = nullptr); |
|
1768 |
|
1769 /** |
|
1770 * When the document is editable by contenteditable attribute of its root |
|
1771 * content or body content. |
|
1772 * |
|
1773 * Be aware, this returns nullptr if it's in designMode. |
|
1774 * |
|
1775 * For example: |
|
1776 * |
|
1777 * <html contenteditable="true"><body></body></html> |
|
1778 * returns the <html>. |
|
1779 * |
|
1780 * <html><body contenteditable="true"></body></html> |
|
1781 * <body contenteditable="true"></body> |
|
1782 * With these cases, this returns the <body>. |
|
1783 * NOTE: The latter case isn't created normally, however, it can be |
|
1784 * created by script with XHTML. |
|
1785 * |
|
1786 * <body><p contenteditable="true"></p></body> |
|
1787 * returns nullptr because <body> isn't editable. |
|
1788 */ |
|
1789 static nsIContent* |
|
1790 GetEditableRootContentByContentEditable(nsIDocument* aDocument); |
|
1791 |
|
1792 /** |
|
1793 * Returns true if the passed in prescontext needs the dark grey background |
|
1794 * that goes behind the page of a print preview presentation. |
|
1795 */ |
|
1796 static bool NeedsPrintPreviewBackground(nsPresContext* aPresContext); |
|
1797 |
|
1798 /** |
|
1799 * Adds all font faces used in the frame tree starting from aFrame |
|
1800 * to the list aFontFaceList. |
|
1801 */ |
|
1802 static nsresult GetFontFacesForFrames(nsIFrame* aFrame, |
|
1803 nsFontFaceList* aFontFaceList); |
|
1804 |
|
1805 /** |
|
1806 * Adds all font faces used within the specified range of text in aFrame, |
|
1807 * and optionally its continuations, to the list in aFontFaceList. |
|
1808 * Pass 0 and INT32_MAX for aStartOffset and aEndOffset to specify the |
|
1809 * entire text is to be considered. |
|
1810 */ |
|
1811 static nsresult GetFontFacesForText(nsIFrame* aFrame, |
|
1812 int32_t aStartOffset, |
|
1813 int32_t aEndOffset, |
|
1814 bool aFollowContinuations, |
|
1815 nsFontFaceList* aFontFaceList); |
|
1816 |
|
1817 /** |
|
1818 * Walks the frame tree starting at aFrame looking for textRuns. |
|
1819 * If |clear| is true, just clears the TEXT_RUN_MEMORY_ACCOUNTED flag |
|
1820 * on each textRun found (and |aMallocSizeOf| is not used). |
|
1821 * If |clear| is false, adds the storage used for each textRun to the |
|
1822 * total, and sets the TEXT_RUN_MEMORY_ACCOUNTED flag to avoid double- |
|
1823 * accounting. (Runs with this flag already set will be skipped.) |
|
1824 * Expected usage pattern is therefore to call twice: |
|
1825 * (void)SizeOfTextRunsForFrames(rootFrame, nullptr, true); |
|
1826 * total = SizeOfTextRunsForFrames(rootFrame, mallocSizeOf, false); |
|
1827 */ |
|
1828 static size_t SizeOfTextRunsForFrames(nsIFrame* aFrame, |
|
1829 mozilla::MallocSizeOf aMallocSizeOf, |
|
1830 bool clear); |
|
1831 |
|
1832 /** |
|
1833 * Returns true if the content node has animations or transitions that can be |
|
1834 * performed on the compositor. |
|
1835 */ |
|
1836 static bool HasAnimationsForCompositor(nsIContent* aContent, |
|
1837 nsCSSProperty aProperty); |
|
1838 |
|
1839 /** |
|
1840 * Returns true if the content node has animations or transitions for the |
|
1841 * property. |
|
1842 */ |
|
1843 static bool HasAnimations(nsIContent* aContent, nsCSSProperty aProperty); |
|
1844 |
|
1845 /** |
|
1846 * Checks if off-main-thread animations are enabled. |
|
1847 */ |
|
1848 static bool AreAsyncAnimationsEnabled(); |
|
1849 |
|
1850 /** |
|
1851 * Checks if we should warn about animations that can't be async |
|
1852 */ |
|
1853 static bool IsAnimationLoggingEnabled(); |
|
1854 |
|
1855 /** |
|
1856 * Find a suitable scale for an element (aContent) over the course of any |
|
1857 * animations and transitions on the element. |
|
1858 * It will check the maximum and minimum scale during the animations and |
|
1859 * transitions and return a suitable value for performance and quality. |
|
1860 * Will return scale(1,1) if there is no animated scaling. |
|
1861 * Always return positive value. |
|
1862 */ |
|
1863 static gfxSize ComputeSuitableScaleForAnimation(nsIContent* aContent); |
|
1864 |
|
1865 /** |
|
1866 * Checks if we should forcibly use nearest pixel filtering for the |
|
1867 * background. |
|
1868 */ |
|
1869 static bool UseBackgroundNearestFiltering(); |
|
1870 |
|
1871 /** |
|
1872 * Checks whether we want to use the GPU to scale images when |
|
1873 * possible. |
|
1874 */ |
|
1875 static bool GPUImageScalingEnabled(); |
|
1876 |
|
1877 /** |
|
1878 * Checks whether we want to layerize animated images whenever possible. |
|
1879 */ |
|
1880 static bool AnimatedImageLayersEnabled(); |
|
1881 |
|
1882 /** |
|
1883 * Checks if we should enable parsing for CSS Filters. |
|
1884 */ |
|
1885 static bool CSSFiltersEnabled(); |
|
1886 |
|
1887 /** |
|
1888 * Checks whether support for the CSS-wide "unset" value is enabled. |
|
1889 */ |
|
1890 static bool UnsetValueEnabled(); |
|
1891 |
|
1892 /** |
|
1893 * Checks whether support for the CSS text-align (and -moz-text-align-last) |
|
1894 * 'true' value is enabled. |
|
1895 */ |
|
1896 static bool IsTextAlignTrueValueEnabled(); |
|
1897 |
|
1898 /** |
|
1899 * Checks if CSS variables are currently enabled. |
|
1900 */ |
|
1901 static bool CSSVariablesEnabled() |
|
1902 { |
|
1903 return sCSSVariablesEnabled; |
|
1904 } |
|
1905 |
|
1906 static bool InterruptibleReflowEnabled() |
|
1907 { |
|
1908 return sInterruptibleReflowEnabled; |
|
1909 } |
|
1910 |
|
1911 /** |
|
1912 * Unions the overflow areas of the children of aFrame with aOverflowAreas. |
|
1913 * aSkipChildLists specifies any child lists that should be skipped. |
|
1914 * kSelectPopupList and kPopupList are always skipped. |
|
1915 */ |
|
1916 static void UnionChildOverflow(nsIFrame* aFrame, |
|
1917 nsOverflowAreas& aOverflowAreas, |
|
1918 mozilla::layout::FrameChildListIDs aSkipChildLists = |
|
1919 mozilla::layout::FrameChildListIDs()); |
|
1920 |
|
1921 /** |
|
1922 * Return the font size inflation *ratio* for a given frame. This is |
|
1923 * the factor by which font sizes should be inflated; it is never |
|
1924 * smaller than 1. |
|
1925 */ |
|
1926 static float FontSizeInflationFor(const nsIFrame *aFrame); |
|
1927 |
|
1928 /** |
|
1929 * Perform the first half of the computation of FontSizeInflationFor |
|
1930 * (see above). |
|
1931 * This includes determining whether inflation should be performed |
|
1932 * within this container and returning 0 if it should not be. |
|
1933 * |
|
1934 * The result is guaranteed not to vary between line participants |
|
1935 * (inlines, text frames) within a line. |
|
1936 * |
|
1937 * The result should not be used directly since font sizes slightly |
|
1938 * above the minimum should always be adjusted as done by |
|
1939 * FontSizeInflationInner. |
|
1940 */ |
|
1941 static nscoord InflationMinFontSizeFor(const nsIFrame *aFrame); |
|
1942 |
|
1943 /** |
|
1944 * Perform the second half of the computation done by |
|
1945 * FontSizeInflationFor (see above). |
|
1946 * |
|
1947 * aMinFontSize must be the result of one of the |
|
1948 * InflationMinFontSizeFor methods above. |
|
1949 */ |
|
1950 static float FontSizeInflationInner(const nsIFrame *aFrame, |
|
1951 nscoord aMinFontSize); |
|
1952 |
|
1953 static bool FontSizeInflationEnabled(nsPresContext *aPresContext); |
|
1954 |
|
1955 /** |
|
1956 * See comment above "font.size.inflation.maxRatio" in |
|
1957 * modules/libpref/src/init/all.js . |
|
1958 */ |
|
1959 static uint32_t FontSizeInflationMaxRatio() { |
|
1960 return sFontSizeInflationMaxRatio; |
|
1961 } |
|
1962 |
|
1963 /** |
|
1964 * See comment above "font.size.inflation.emPerLine" in |
|
1965 * modules/libpref/src/init/all.js . |
|
1966 */ |
|
1967 static uint32_t FontSizeInflationEmPerLine() { |
|
1968 return sFontSizeInflationEmPerLine; |
|
1969 } |
|
1970 |
|
1971 /** |
|
1972 * See comment above "font.size.inflation.minTwips" in |
|
1973 * modules/libpref/src/init/all.js . |
|
1974 */ |
|
1975 static uint32_t FontSizeInflationMinTwips() { |
|
1976 return sFontSizeInflationMinTwips; |
|
1977 } |
|
1978 |
|
1979 /** |
|
1980 * See comment above "font.size.inflation.lineThreshold" in |
|
1981 * modules/libpref/src/init/all.js . |
|
1982 */ |
|
1983 static uint32_t FontSizeInflationLineThreshold() { |
|
1984 return sFontSizeInflationLineThreshold; |
|
1985 } |
|
1986 |
|
1987 static bool FontSizeInflationForceEnabled() { |
|
1988 return sFontSizeInflationForceEnabled; |
|
1989 } |
|
1990 |
|
1991 static bool FontSizeInflationDisabledInMasterProcess() { |
|
1992 return sFontSizeInflationDisabledInMasterProcess; |
|
1993 } |
|
1994 |
|
1995 /** |
|
1996 * See comment above "font.size.inflation.mappingIntercept" in |
|
1997 * modules/libpref/src/init/all.js . |
|
1998 */ |
|
1999 static int32_t FontSizeInflationMappingIntercept() { |
|
2000 return sFontSizeInflationMappingIntercept; |
|
2001 } |
|
2002 |
|
2003 /** |
|
2004 * Returns true if the nglayout.debug.invalidation pref is set to true. |
|
2005 * Note that sInvalidationDebuggingIsEnabled is declared outside this function to |
|
2006 * allow it to be accessed an manipulated from breakpoint conditions. |
|
2007 */ |
|
2008 static bool InvalidationDebuggingIsEnabled() { |
|
2009 return sInvalidationDebuggingIsEnabled || getenv("MOZ_DUMP_INVALIDATION") != 0; |
|
2010 } |
|
2011 |
|
2012 static void Initialize(); |
|
2013 static void Shutdown(); |
|
2014 |
|
2015 /** |
|
2016 * Register an imgIRequest object with a refresh driver. |
|
2017 * |
|
2018 * @param aPresContext The nsPresContext whose refresh driver we want to |
|
2019 * register with. |
|
2020 * @param aRequest A pointer to the imgIRequest object which the client wants |
|
2021 * to register with the refresh driver. |
|
2022 * @param aRequestRegistered A pointer to a boolean value which indicates |
|
2023 * whether the given image request is registered. If |
|
2024 * *aRequestRegistered is true, then this request will not be |
|
2025 * registered again. If the request is registered by this function, |
|
2026 * then *aRequestRegistered will be set to true upon the completion of |
|
2027 * this function. |
|
2028 * |
|
2029 */ |
|
2030 static void RegisterImageRequest(nsPresContext* aPresContext, |
|
2031 imgIRequest* aRequest, |
|
2032 bool* aRequestRegistered); |
|
2033 |
|
2034 /** |
|
2035 * Register an imgIRequest object with a refresh driver, but only if the |
|
2036 * request is for an image that is animated. |
|
2037 * |
|
2038 * @param aPresContext The nsPresContext whose refresh driver we want to |
|
2039 * register with. |
|
2040 * @param aRequest A pointer to the imgIRequest object which the client wants |
|
2041 * to register with the refresh driver. |
|
2042 * @param aRequestRegistered A pointer to a boolean value which indicates |
|
2043 * whether the given image request is registered. If |
|
2044 * *aRequestRegistered is true, then this request will not be |
|
2045 * registered again. If the request is registered by this function, |
|
2046 * then *aRequestRegistered will be set to true upon the completion of |
|
2047 * this function. |
|
2048 * |
|
2049 */ |
|
2050 static void RegisterImageRequestIfAnimated(nsPresContext* aPresContext, |
|
2051 imgIRequest* aRequest, |
|
2052 bool* aRequestRegistered); |
|
2053 |
|
2054 /** |
|
2055 * Deregister an imgIRequest object from a refresh driver. |
|
2056 * |
|
2057 * @param aPresContext The nsPresContext whose refresh driver we want to |
|
2058 * deregister from. |
|
2059 * @param aRequest A pointer to the imgIRequest object with which the client |
|
2060 * previously registered and now wants to deregister from the refresh |
|
2061 * driver. |
|
2062 * @param aRequestRegistered A pointer to a boolean value which indicates |
|
2063 * whether the given image request is registered. If |
|
2064 * *aRequestRegistered is false, then this request will not be |
|
2065 * deregistered. If the request is deregistered by this function, |
|
2066 * then *aRequestRegistered will be set to false upon the completion of |
|
2067 * this function. |
|
2068 */ |
|
2069 static void DeregisterImageRequest(nsPresContext* aPresContext, |
|
2070 imgIRequest* aRequest, |
|
2071 bool* aRequestRegistered); |
|
2072 |
|
2073 /** |
|
2074 * Shim to nsCSSFrameConstructor::PostRestyleEvent. Exists so that we |
|
2075 * can avoid including nsCSSFrameConstructor.h and all its dependencies |
|
2076 * in content files. |
|
2077 */ |
|
2078 static void PostRestyleEvent(mozilla::dom::Element* aElement, |
|
2079 nsRestyleHint aRestyleHint, |
|
2080 nsChangeHint aMinChangeHint); |
|
2081 |
|
2082 /** |
|
2083 * Updates a pair of x and y distances if a given point is closer to a given |
|
2084 * rectangle than the original distance values. If aPoint is closer to |
|
2085 * aRect than aClosestXDistance and aClosestYDistance indicate, then those |
|
2086 * two variables are updated with the distance between aPoint and aRect, |
|
2087 * and true is returned. If aPoint is not closer, then aClosestXDistance |
|
2088 * and aClosestYDistance are left unchanged, and false is returned. |
|
2089 * |
|
2090 * Distances are measured in the two dimensions separately; a closer x |
|
2091 * distance beats a closer y distance. |
|
2092 */ |
|
2093 template<typename PointType, typename RectType, typename CoordType> |
|
2094 static bool PointIsCloserToRect(PointType aPoint, const RectType& aRect, |
|
2095 CoordType& aClosestXDistance, |
|
2096 CoordType& aClosestYDistance); |
|
2097 /** |
|
2098 * Computes the box shadow rect for the frame, or returns an empty rect if |
|
2099 * there are no shadows. |
|
2100 * |
|
2101 * @param aFrame Frame to compute shadows for. |
|
2102 * @param aFrameSize Size of aFrame (in case it hasn't been set yet). |
|
2103 */ |
|
2104 static nsRect GetBoxShadowRectForFrame(nsIFrame* aFrame, const nsSize& aFrameSize); |
|
2105 |
|
2106 #ifdef DEBUG |
|
2107 /** |
|
2108 * Assert that there are no duplicate continuations of the same frame |
|
2109 * within aFrameList. Optimize the tests by assuming that all frames |
|
2110 * in aFrameList have parent aContainer. |
|
2111 */ |
|
2112 static void |
|
2113 AssertNoDuplicateContinuations(nsIFrame* aContainer, |
|
2114 const nsFrameList& aFrameList); |
|
2115 |
|
2116 /** |
|
2117 * Assert that the frame tree rooted at |aSubtreeRoot| is empty, i.e., |
|
2118 * that it contains no first-in-flows. |
|
2119 */ |
|
2120 static void |
|
2121 AssertTreeOnlyEmptyNextInFlows(nsIFrame *aSubtreeRoot); |
|
2122 #endif |
|
2123 |
|
2124 /** |
|
2125 * Determine if aImageFrame (which is an nsImageFrame, nsImageControlFrame, or |
|
2126 * nsSVGImageFrame) is visible or close to being visible via scrolling and |
|
2127 * update the presshell with this knowledge. |
|
2128 */ |
|
2129 static void |
|
2130 UpdateImageVisibilityForFrame(nsIFrame* aImageFrame); |
|
2131 |
|
2132 /** |
|
2133 * Calculate the compostion size for a frame. See FrameMetrics.h for |
|
2134 * defintion of composition size (or bounds). |
|
2135 */ |
|
2136 static nsSize |
|
2137 CalculateCompositionSizeForFrame(nsIFrame* aFrame); |
|
2138 |
|
2139 /** |
|
2140 * Calculate the composition size for the root scroll frame of the root |
|
2141 * content document. |
|
2142 * @param aFrame A frame in the root content document (or a descendant of it). |
|
2143 * @param aIsRootContentDocRootScrollFrame Whether aFrame is already the root |
|
2144 * scroll frame of the root content document. In this case we just |
|
2145 * use aFrame's own composition size. |
|
2146 * @param aMetrics A partially populated FrameMetrics for aFrame. Must have at |
|
2147 * least mCompositionBounds, mCumulativeResolution, and |
|
2148 * mDevPixelsPerCSSPixel set. |
|
2149 */ |
|
2150 static CSSSize |
|
2151 CalculateRootCompositionSize(nsIFrame* aFrame, |
|
2152 bool aIsRootContentDocRootScrollFrame, |
|
2153 const FrameMetrics& aMetrics); |
|
2154 |
|
2155 /** |
|
2156 * Calculate the scrollable rect for a frame. See FrameMetrics.h for |
|
2157 * defintion of scrollable rect. aScrollableFrame is the scroll frame to calculate |
|
2158 * the scrollable rect for. If it's null then we calculate the scrollable rect |
|
2159 * as the rect of the root frame. |
|
2160 */ |
|
2161 static nsRect |
|
2162 CalculateScrollableRectForFrame(nsIScrollableFrame* aScrollableFrame, nsIFrame* aRootFrame); |
|
2163 |
|
2164 /** |
|
2165 * Calculate the expanded scrollable rect for a frame. See FrameMetrics.h for |
|
2166 * defintion of expanded scrollable rect. |
|
2167 */ |
|
2168 static nsRect |
|
2169 CalculateExpandedScrollableRect(nsIFrame* aFrame); |
|
2170 |
|
2171 /** |
|
2172 * Return whether we want to use APZ for subframes in this process. |
|
2173 * Currently we don't support APZ for the parent process on B2G. |
|
2174 */ |
|
2175 static bool WantSubAPZC(); |
|
2176 |
|
2177 /** |
|
2178 * Get the display port for |aScrollFrame|'s content. If |aScrollFrame| |
|
2179 * WantsAsyncScroll() and we don't have a scrollable displayport yet (as |
|
2180 * tracked by |aBuilder|), calculate and set a display port. Returns true if |
|
2181 * there is (now) a displayport, and if so the displayport is returned in |
|
2182 * |aOutDisplayport|. |
|
2183 * |
|
2184 * Note that a displayport can either be stored as a rect, or as a base |
|
2185 * rect + margins. If it is stored as a base rect + margins, the base rect |
|
2186 * is updated to |aDisplayPortBase|, and the rect assembled from the |
|
2187 * base rect and margins is returned. If this function creates a displayport, |
|
2188 * it computes margins and stores |aDisplayPortBase| as the base rect. |
|
2189 * |
|
2190 * This is intended to be called during display list building. |
|
2191 */ |
|
2192 static bool GetOrMaybeCreateDisplayPort(nsDisplayListBuilder& aBuilder, |
|
2193 nsIFrame* aScrollFrame, |
|
2194 nsRect aDisplayPortBase, |
|
2195 nsRect* aOutDisplayport); |
|
2196 |
|
2197 private: |
|
2198 static uint32_t sFontSizeInflationEmPerLine; |
|
2199 static uint32_t sFontSizeInflationMinTwips; |
|
2200 static uint32_t sFontSizeInflationLineThreshold; |
|
2201 static int32_t sFontSizeInflationMappingIntercept; |
|
2202 static uint32_t sFontSizeInflationMaxRatio; |
|
2203 static bool sFontSizeInflationForceEnabled; |
|
2204 static bool sFontSizeInflationDisabledInMasterProcess; |
|
2205 static bool sInvalidationDebuggingIsEnabled; |
|
2206 static bool sCSSVariablesEnabled; |
|
2207 static bool sInterruptibleReflowEnabled; |
|
2208 }; |
|
2209 |
|
2210 MOZ_FINISH_NESTED_ENUM_CLASS(nsLayoutUtils::RepaintMode) |
|
2211 |
|
2212 template<typename PointType, typename RectType, typename CoordType> |
|
2213 /* static */ bool |
|
2214 nsLayoutUtils::PointIsCloserToRect(PointType aPoint, const RectType& aRect, |
|
2215 CoordType& aClosestXDistance, |
|
2216 CoordType& aClosestYDistance) |
|
2217 { |
|
2218 CoordType fromLeft = aPoint.x - aRect.x; |
|
2219 CoordType fromRight = aPoint.x - aRect.XMost(); |
|
2220 |
|
2221 CoordType xDistance; |
|
2222 if (fromLeft >= 0 && fromRight <= 0) { |
|
2223 xDistance = 0; |
|
2224 } else { |
|
2225 xDistance = std::min(abs(fromLeft), abs(fromRight)); |
|
2226 } |
|
2227 |
|
2228 if (xDistance <= aClosestXDistance) { |
|
2229 if (xDistance < aClosestXDistance) { |
|
2230 aClosestYDistance = std::numeric_limits<CoordType>::max(); |
|
2231 } |
|
2232 |
|
2233 CoordType fromTop = aPoint.y - aRect.y; |
|
2234 CoordType fromBottom = aPoint.y - aRect.YMost(); |
|
2235 |
|
2236 CoordType yDistance; |
|
2237 if (fromTop >= 0 && fromBottom <= 0) { |
|
2238 yDistance = 0; |
|
2239 } else { |
|
2240 yDistance = std::min(abs(fromTop), abs(fromBottom)); |
|
2241 } |
|
2242 |
|
2243 if (yDistance < aClosestYDistance) { |
|
2244 aClosestXDistance = xDistance; |
|
2245 aClosestYDistance = yDistance; |
|
2246 return true; |
|
2247 } |
|
2248 } |
|
2249 |
|
2250 return false; |
|
2251 } |
|
2252 |
|
2253 namespace mozilla { |
|
2254 namespace layout { |
|
2255 |
|
2256 /** |
|
2257 * An RAII class which will, for the duration of its lifetime, |
|
2258 * **if** the frame given is a container for font size inflation, |
|
2259 * set the current inflation container on the pres context to null |
|
2260 * (and then, in its destructor, restore the old value). |
|
2261 */ |
|
2262 class AutoMaybeDisableFontInflation { |
|
2263 public: |
|
2264 AutoMaybeDisableFontInflation(nsIFrame *aFrame); |
|
2265 |
|
2266 ~AutoMaybeDisableFontInflation(); |
|
2267 private: |
|
2268 nsPresContext *mPresContext; |
|
2269 bool mOldValue; |
|
2270 }; |
|
2271 |
|
2272 } |
|
2273 } |
|
2274 |
|
2275 class nsSetAttrRunnable : public nsRunnable |
|
2276 { |
|
2277 public: |
|
2278 nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName, |
|
2279 const nsAString& aValue); |
|
2280 nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName, |
|
2281 int32_t aValue); |
|
2282 |
|
2283 NS_DECL_NSIRUNNABLE |
|
2284 |
|
2285 nsCOMPtr<nsIContent> mContent; |
|
2286 nsCOMPtr<nsIAtom> mAttrName; |
|
2287 nsAutoString mValue; |
|
2288 }; |
|
2289 |
|
2290 class nsUnsetAttrRunnable : public nsRunnable |
|
2291 { |
|
2292 public: |
|
2293 nsUnsetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName); |
|
2294 |
|
2295 NS_DECL_NSIRUNNABLE |
|
2296 |
|
2297 nsCOMPtr<nsIContent> mContent; |
|
2298 nsCOMPtr<nsIAtom> mAttrName; |
|
2299 }; |
|
2300 |
|
2301 #endif // nsLayoutUtils_h__ |