/work/obj-fuzz/dist/include/nsLayoutUtils.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef nsLayoutUtils_h__ |
8 | | #define nsLayoutUtils_h__ |
9 | | |
10 | | #include "LayoutConstants.h" |
11 | | #include "mozilla/MemoryReporting.h" |
12 | | #include "mozilla/ArrayUtils.h" |
13 | | #include "mozilla/LookAndFeel.h" |
14 | | #include "mozilla/Maybe.h" |
15 | | #include "mozilla/TypedEnumBits.h" |
16 | | #include "nsBoundingMetrics.h" |
17 | | #include "nsChangeHint.h" |
18 | | #include "nsFrameList.h" |
19 | | #include "mozilla/layout/FrameChildList.h" |
20 | | #include "nsThreadUtils.h" |
21 | | #include "nsIPrincipal.h" |
22 | | #include "FrameMetrics.h" |
23 | | #include "nsIWidget.h" |
24 | | #include "nsCSSPropertyID.h" |
25 | | #include "nsStyleCoord.h" |
26 | | #include "nsStyleConsts.h" |
27 | | #include "nsGkAtoms.h" |
28 | | #include "imgIContainer.h" |
29 | | #include "mozilla/gfx/2D.h" |
30 | | #include "Units.h" |
31 | | #include "mozilla/ToString.h" |
32 | | #include "mozilla/ReflowOutput.h" |
33 | | #include "ImageContainer.h" |
34 | | #include "gfx2DGlue.h" |
35 | | #include "nsStyleConsts.h" |
36 | | #include "SVGImageContext.h" |
37 | | #include <limits> |
38 | | #include <algorithm> |
39 | | #include "gfxPoint.h" |
40 | | #include "nsClassHashtable.h" |
41 | | |
42 | | class gfxContext; |
43 | | class nsPresContext; |
44 | | class nsIContent; |
45 | | class nsAtom; |
46 | | class nsIScrollableFrame; |
47 | | class nsRegion; |
48 | | class nsDisplayListBuilder; |
49 | | enum class nsDisplayListBuilderMode : uint8_t; |
50 | | class nsDisplayItem; |
51 | | class nsFontMetrics; |
52 | | class nsFontFaceList; |
53 | | class nsIImageLoadingContent; |
54 | | class nsBlockFrame; |
55 | | class nsContainerFrame; |
56 | | class nsView; |
57 | | class nsIFrame; |
58 | | class nsStyleCoord; |
59 | | class nsStyleCorners; |
60 | | class nsPIDOMWindowOuter; |
61 | | class imgIRequest; |
62 | | class nsIDocument; |
63 | | struct nsStyleFont; |
64 | | struct nsOverflowAreas; |
65 | | |
66 | | namespace mozilla { |
67 | | class ComputedStyle; |
68 | | enum class CSSPseudoElementType : uint8_t; |
69 | | class EventListenerManager; |
70 | | enum class LayoutFrameType : uint8_t; |
71 | | struct IntrinsicSize; |
72 | | struct ContainerLayerParameters; |
73 | | class WritingMode; |
74 | | class DisplayItemClip; |
75 | | class EffectSet; |
76 | | struct ActiveScrolledRoot; |
77 | | enum class StyleImageOrientation : uint8_t; |
78 | | namespace dom { |
79 | | class CanvasRenderingContext2D; |
80 | | class DOMRectList; |
81 | | class Element; |
82 | | class Event; |
83 | | class HTMLImageElement; |
84 | | class HTMLCanvasElement; |
85 | | class HTMLVideoElement; |
86 | | class InspectorFontFace; |
87 | | class OffscreenCanvas; |
88 | | class Selection; |
89 | | } // namespace dom |
90 | | namespace gfx { |
91 | | struct RectCornerRadii; |
92 | | enum class ShapedTextFlags : uint16_t; |
93 | | } // namespace gfx |
94 | | namespace layers { |
95 | | class Image; |
96 | | class StackingContextHelper; |
97 | | class Layer; |
98 | | } // namespace layers |
99 | | } // namespace mozilla |
100 | | |
101 | | namespace mozilla { |
102 | | |
103 | | struct DisplayPortPropertyData { |
104 | | DisplayPortPropertyData(const nsRect& aRect, uint32_t aPriority) |
105 | | : mRect(aRect) |
106 | | , mPriority(aPriority) |
107 | 0 | {} |
108 | | nsRect mRect; |
109 | | uint32_t mPriority; |
110 | | }; |
111 | | |
112 | | struct DisplayPortMarginsPropertyData { |
113 | | DisplayPortMarginsPropertyData(const ScreenMargin& aMargins, |
114 | | uint32_t aPriority) |
115 | | : mMargins(aMargins) |
116 | | , mPriority(aPriority) |
117 | | {} |
118 | | ScreenMargin mMargins; |
119 | | uint32_t mPriority; |
120 | | }; |
121 | | |
122 | | struct MotionPathData { |
123 | | gfx::Point mTranslate; |
124 | | float mRotate; |
125 | | }; |
126 | | |
127 | | } // namespace mozilla |
128 | | |
129 | | // For GetDisplayPort |
130 | | enum class RelativeTo { |
131 | | ScrollPort, |
132 | | ScrollFrame |
133 | | }; |
134 | | |
135 | | // Flags to customize the behavior of nsLayoutUtils::DrawString. |
136 | | enum class DrawStringFlags { |
137 | | eDefault = 0x0, |
138 | | eForceHorizontal = 0x1 // Forces the text to be drawn horizontally. |
139 | | }; |
140 | | MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DrawStringFlags) |
141 | | |
142 | | enum class ReparentingDirection { |
143 | | Backwards, |
144 | | Forwards, |
145 | | Variable // Could be either of the above; take most pessimistic action. |
146 | | }; |
147 | | |
148 | | /** |
149 | | * nsLayoutUtils is a namespace class used for various helper |
150 | | * functions that are useful in multiple places in layout. The goal |
151 | | * is not to define multiple copies of the same static helper. |
152 | | */ |
153 | | class nsLayoutUtils |
154 | | { |
155 | | typedef mozilla::ComputedStyle ComputedStyle; |
156 | | typedef mozilla::dom::DOMRectList DOMRectList; |
157 | | typedef mozilla::layers::Layer Layer; |
158 | | typedef mozilla::layers::StackingContextHelper StackingContextHelper; |
159 | | typedef mozilla::ContainerLayerParameters ContainerLayerParameters; |
160 | | typedef mozilla::IntrinsicSize IntrinsicSize; |
161 | | typedef mozilla::gfx::SourceSurface SourceSurface; |
162 | | typedef mozilla::gfx::Color Color; |
163 | | typedef mozilla::gfx::DrawTarget DrawTarget; |
164 | | typedef mozilla::gfx::ExtendMode ExtendMode; |
165 | | typedef mozilla::gfx::SamplingFilter SamplingFilter; |
166 | | typedef mozilla::gfx::Float Float; |
167 | | typedef mozilla::gfx::Point Point; |
168 | | typedef mozilla::gfx::Rect Rect; |
169 | | typedef mozilla::gfx::RectDouble RectDouble; |
170 | | typedef mozilla::gfx::Size Size; |
171 | | typedef mozilla::gfx::Matrix4x4 Matrix4x4; |
172 | | typedef mozilla::gfx::Matrix4x4Flagged Matrix4x4Flagged; |
173 | | typedef mozilla::gfx::RectCornerRadii RectCornerRadii; |
174 | | typedef mozilla::gfx::StrokeOptions StrokeOptions; |
175 | | typedef mozilla::image::ImgDrawResult ImgDrawResult; |
176 | | |
177 | | public: |
178 | | typedef mozilla::layers::FrameMetrics FrameMetrics; |
179 | | typedef mozilla::layers::ScrollMetadata ScrollMetadata; |
180 | | typedef FrameMetrics::ViewID ViewID; |
181 | | typedef mozilla::CSSPoint CSSPoint; |
182 | | typedef mozilla::CSSSize CSSSize; |
183 | | typedef mozilla::CSSIntSize CSSIntSize; |
184 | | typedef mozilla::CSSRect CSSRect; |
185 | | typedef mozilla::ScreenMargin ScreenMargin; |
186 | | typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize; |
187 | | typedef mozilla::LayoutDeviceRect LayoutDeviceRect; |
188 | | typedef mozilla::StyleGeometryBox StyleGeometryBox; |
189 | | typedef mozilla::SVGImageContext SVGImageContext; |
190 | | typedef mozilla::LogicalSize LogicalSize; |
191 | | |
192 | | /** |
193 | | * Finds previously assigned ViewID for the given content element, if any. |
194 | | * Returns whether a ViewID was previously assigned. |
195 | | */ |
196 | | static bool FindIDFor(const nsIContent* aContent, ViewID* aOutViewId); |
197 | | |
198 | | /** |
199 | | * Finds previously assigned or generates a unique ViewID for the given |
200 | | * content element. |
201 | | */ |
202 | | static ViewID FindOrCreateIDFor(nsIContent* aContent); |
203 | | |
204 | | /** |
205 | | * Find content for given ID. |
206 | | */ |
207 | | static nsIContent* FindContentFor(ViewID aId); |
208 | | |
209 | | /** |
210 | | * Find the scrollable frame for a given ID. |
211 | | */ |
212 | | static nsIScrollableFrame* FindScrollableFrameFor(ViewID aId); |
213 | | |
214 | | /** |
215 | | * Find the ID for a given scrollable frame. |
216 | | */ |
217 | | static ViewID FindIDForScrollableFrame(nsIScrollableFrame* aScrollable); |
218 | | |
219 | | /** |
220 | | * Get display port for the given element, relative to the specified entity, |
221 | | * defaulting to the scrollport. |
222 | | */ |
223 | | static bool GetDisplayPort(nsIContent* aContent, nsRect *aResult, |
224 | | RelativeTo aRelativeTo = RelativeTo::ScrollPort); |
225 | | |
226 | | /** |
227 | | * Check whether the given element has a displayport. |
228 | | */ |
229 | | static bool HasDisplayPort(nsIContent* aContent); |
230 | | |
231 | | /** |
232 | | * Check whether the given frame has a displayport. It returns false |
233 | | * for scrolled frames and true for the corresponding scroll frame. |
234 | | * Optionally pass the child, and it only returns true if the child is the |
235 | | * scrolled frame for the displayport. |
236 | | */ |
237 | | static bool FrameHasDisplayPort(nsIFrame* aFrame, const nsIFrame* aScrolledFrame = nullptr); |
238 | | |
239 | | /** |
240 | | * Check if the given element has a margins based displayport but is missing a |
241 | | * displayport base rect that it needs to properly compute a displayport rect. |
242 | | */ |
243 | | static bool IsMissingDisplayPortBaseRect(nsIContent* aContent); |
244 | | |
245 | | /** |
246 | | * Go through the IPC Channel and update displayport margins for content |
247 | | * elements based on UpdateFrame messages. The messages are left in the |
248 | | * queue and will be fully processed when dequeued. The aim is to paint |
249 | | * the most up-to-date displayport without waiting for these message to |
250 | | * go through the message queue. |
251 | | */ |
252 | | static void UpdateDisplayPortMarginsFromPendingMessages(); |
253 | | |
254 | | /** |
255 | | * @return the display port for the given element which should be used for |
256 | | * visibility testing purposes. |
257 | | * |
258 | | * If low-precision buffers are enabled, this is the critical display port; |
259 | | * otherwise, it's the same display port returned by GetDisplayPort(). |
260 | | */ |
261 | | static bool GetDisplayPortForVisibilityTesting( |
262 | | nsIContent* aContent, |
263 | | nsRect* aResult, |
264 | | RelativeTo aRelativeTo = RelativeTo::ScrollPort); |
265 | | |
266 | | enum class RepaintMode : uint8_t { |
267 | | Repaint, |
268 | | DoNotRepaint |
269 | | }; |
270 | | |
271 | | /** |
272 | | * Invalidate for displayport change. |
273 | | */ |
274 | | static void InvalidateForDisplayPortChange(nsIContent* aContent, |
275 | | bool aHadDisplayPort, |
276 | | const nsRect& aOldDisplayPort, |
277 | | const nsRect& aNewDisplayPort, |
278 | | RepaintMode aRepaintMode = RepaintMode::Repaint); |
279 | | |
280 | | /** |
281 | | * Set the display port margins for a content element to be used with a |
282 | | * display port base (see SetDisplayPortBase()). |
283 | | * See also nsIDOMWindowUtils.setDisplayPortMargins. |
284 | | * @param aContent the content element for which to set the margins |
285 | | * @param aPresShell the pres shell for the document containing the element |
286 | | * @param aMargins the margins to set |
287 | | * @param aAlignmentX, alignmentY the amount of pixels to which to align the |
288 | | * displayport built by combining the base |
289 | | * rect with the margins, in either direction |
290 | | * @param aPriority a priority value to determine which margins take effect |
291 | | * when multiple callers specify margins |
292 | | * @param aRepaintMode whether to schedule a paint after setting the margins |
293 | | * @return true if the new margins were applied. |
294 | | */ |
295 | | static bool SetDisplayPortMargins(nsIContent* aContent, |
296 | | nsIPresShell* aPresShell, |
297 | | const ScreenMargin& aMargins, |
298 | | uint32_t aPriority = 0, |
299 | | RepaintMode aRepaintMode = RepaintMode::Repaint); |
300 | | |
301 | | /** |
302 | | * Set the display port base rect for given element to be used with display |
303 | | * port margins. |
304 | | * SetDisplayPortBaseIfNotSet is like SetDisplayPortBase except it only sets |
305 | | * the display port base to aBase if no display port base is currently set. |
306 | | */ |
307 | | static void SetDisplayPortBase(nsIContent* aContent, const nsRect& aBase); |
308 | | static void SetDisplayPortBaseIfNotSet(nsIContent* aContent, const nsRect& aBase); |
309 | | |
310 | | /** |
311 | | * Get the critical display port for the given element. |
312 | | */ |
313 | | static bool GetCriticalDisplayPort(nsIContent* aContent, nsRect* aResult); |
314 | | |
315 | | /** |
316 | | * Check whether the given element has a critical display port. |
317 | | */ |
318 | | static bool HasCriticalDisplayPort(nsIContent* aContent); |
319 | | |
320 | | /** |
321 | | * If low-precision painting is turned on, delegates to GetCriticalDisplayPort. |
322 | | * Otherwise, delegates to GetDisplayPort. |
323 | | */ |
324 | | static bool GetHighResolutionDisplayPort(nsIContent* aContent, nsRect* aResult); |
325 | | |
326 | | /** |
327 | | * Remove the displayport for the given element. |
328 | | */ |
329 | | static void RemoveDisplayPort(nsIContent* aContent); |
330 | | |
331 | | /** |
332 | | * Use heuristics to figure out the child list that |
333 | | * aChildFrame is currently in. |
334 | | */ |
335 | | static mozilla::layout::FrameChildListID GetChildListNameFor(nsIFrame* aChildFrame); |
336 | | |
337 | | /** |
338 | | * Returns the ::before pseudo-element for aContent, if any. |
339 | | */ |
340 | | static mozilla::dom::Element* GetBeforePseudo(const nsIContent* aContent); |
341 | | |
342 | | /** |
343 | | * Returns the frame corresponding to the ::before pseudo-element for |
344 | | * aContent, if any. |
345 | | */ |
346 | | static nsIFrame* GetBeforeFrame(const nsIContent* aContent); |
347 | | |
348 | | /** |
349 | | * Returns the ::after pseudo-element for aContent, if any. |
350 | | */ |
351 | | static mozilla::dom::Element* GetAfterPseudo(const nsIContent* aContent); |
352 | | |
353 | | /** |
354 | | * Returns the frame corresponding to the ::after pseudo-element for aContent, |
355 | | * if any. |
356 | | */ |
357 | | static nsIFrame* GetAfterFrame(const nsIContent* aContent); |
358 | | |
359 | | /** |
360 | | * Given a frame, search up the frame tree until we find an |
361 | | * ancestor that (or the frame itself) is of type aFrameType, if any. |
362 | | * |
363 | | * @param aFrame the frame to start at |
364 | | * @param aFrameType the frame type to look for |
365 | | * @param aStopAt a frame to stop at after we checked it |
366 | | * @return a frame of the given type or nullptr if no |
367 | | * such ancestor exists |
368 | | */ |
369 | | static nsIFrame* GetClosestFrameOfType(nsIFrame* aFrame, |
370 | | mozilla::LayoutFrameType aFrameType, |
371 | | nsIFrame* aStopAt = nullptr); |
372 | | |
373 | | /** |
374 | | * Given a frame, search up the frame tree until we find an |
375 | | * ancestor that (or the frame itself) is a "Page" frame, if any. |
376 | | * |
377 | | * @param aFrame the frame to start at |
378 | | * @return a frame of type mozilla::LayoutFrameType::Page or nullptr if no |
379 | | * such ancestor exists |
380 | | */ |
381 | | static nsIFrame* GetPageFrame(nsIFrame* aFrame); |
382 | | |
383 | | /** |
384 | | * Given a frame which is the primary frame for an element, |
385 | | * return the frame that has the non-pseudoelement ComputedStyle for |
386 | | * the content. |
387 | | * This is aPrimaryFrame itself except for tableWrapper frames. |
388 | | * |
389 | | * Given a non-null input, this will return null if and only if its |
390 | | * argument is a table wrapper frame that is mid-destruction (and its |
391 | | * table frame has been destroyed). |
392 | | */ |
393 | | static nsIFrame* GetStyleFrame(nsIFrame* aPrimaryFrame); |
394 | | |
395 | | /** |
396 | | * Given a content node, |
397 | | * return the frame that has the non-pseudoelement ComputedStyle for |
398 | | * the content. May return null. |
399 | | * This is aContent->GetPrimaryFrame() except for tableWrapper frames. |
400 | | */ |
401 | | static nsIFrame* GetStyleFrame(const nsIContent* aContent); |
402 | | |
403 | | /** |
404 | | * Gets the real primary frame associated with the content object. |
405 | | * |
406 | | * In the case of absolutely positioned elements and floated elements, |
407 | | * the real primary frame is the frame that is out of the flow and not the |
408 | | * placeholder frame. |
409 | | */ |
410 | | static nsIFrame* GetRealPrimaryFrameFor(const nsIContent* aContent); |
411 | | |
412 | | #ifdef DEBUG |
413 | | // TODO: remove, see bug 598468. |
414 | | static bool gPreventAssertInCompareTreePosition; |
415 | | #endif // DEBUG |
416 | | |
417 | | /** |
418 | | * CompareTreePosition determines whether aContent1 comes before or |
419 | | * after aContent2 in a preorder traversal of the content tree. |
420 | | * |
421 | | * @param aCommonAncestor either null, or a common ancestor of |
422 | | * aContent1 and aContent2. Actually this is |
423 | | * only a hint; if it's not an ancestor of |
424 | | * aContent1 or aContent2, this function will |
425 | | * still work, but it will be slower than |
426 | | * normal. |
427 | | * @return < 0 if aContent1 is before aContent2 |
428 | | * > 0 if aContent1 is after aContent2, |
429 | | * 0 otherwise (meaning they're the same, or they're in |
430 | | * different documents) |
431 | | */ |
432 | | static int32_t CompareTreePosition(nsIContent* aContent1, |
433 | | nsIContent* aContent2, |
434 | | const nsIContent* aCommonAncestor = nullptr) |
435 | 0 | { |
436 | 0 | return DoCompareTreePosition(aContent1, aContent2, -1, 1, aCommonAncestor); |
437 | 0 | } |
438 | | |
439 | | /* |
440 | | * More generic version of |CompareTreePosition|. |aIf1Ancestor| |
441 | | * gives the value to return when 1 is an ancestor of 2, and likewise |
442 | | * for |aIf2Ancestor|. Passing (-1, 1) gives preorder traversal |
443 | | * order, and (1, -1) gives postorder traversal order. |
444 | | */ |
445 | | static int32_t DoCompareTreePosition(nsIContent* aContent1, |
446 | | nsIContent* aContent2, |
447 | | int32_t aIf1Ancestor, |
448 | | int32_t aIf2Ancestor, |
449 | | const nsIContent* aCommonAncestor = nullptr); |
450 | | |
451 | | /** |
452 | | * CompareTreePosition determines whether aFrame1 comes before or |
453 | | * after aFrame2 in a preorder traversal of the frame tree, where out |
454 | | * of flow frames are treated as children of their placeholders. This is |
455 | | * basically the same ordering as DoCompareTreePosition(nsIContent*) except |
456 | | * that it handles anonymous content properly and there are subtleties with |
457 | | * continuations. |
458 | | * |
459 | | * @param aCommonAncestor either null, or a common ancestor of |
460 | | * aContent1 and aContent2. Actually this is |
461 | | * only a hint; if it's not an ancestor of |
462 | | * aContent1 or aContent2, this function will |
463 | | * still work, but it will be slower than |
464 | | * normal. |
465 | | * @return < 0 if aContent1 is before aContent2 |
466 | | * > 0 if aContent1 is after aContent2, |
467 | | * 0 otherwise (meaning they're the same, or they're in |
468 | | * different frame trees) |
469 | | */ |
470 | | static int32_t CompareTreePosition(nsIFrame* aFrame1, |
471 | | nsIFrame* aFrame2, |
472 | | nsIFrame* aCommonAncestor = nullptr) |
473 | | { |
474 | | return DoCompareTreePosition(aFrame1, aFrame2, -1, 1, aCommonAncestor); |
475 | | } |
476 | | |
477 | | static int32_t CompareTreePosition(nsIFrame* aFrame1, |
478 | | nsIFrame* aFrame2, |
479 | | nsTArray<nsIFrame*>& aFrame2Ancestors, |
480 | | nsIFrame* aCommonAncestor = nullptr) |
481 | | { |
482 | | return DoCompareTreePosition(aFrame1, aFrame2, aFrame2Ancestors, |
483 | | -1, 1, aCommonAncestor); |
484 | | } |
485 | | |
486 | | /* |
487 | | * More generic version of |CompareTreePosition|. |aIf1Ancestor| |
488 | | * gives the value to return when 1 is an ancestor of 2, and likewise |
489 | | * for |aIf2Ancestor|. Passing (-1, 1) gives preorder traversal |
490 | | * order, and (1, -1) gives postorder traversal order. |
491 | | */ |
492 | | static int32_t DoCompareTreePosition(nsIFrame* aFrame1, |
493 | | nsIFrame* aFrame2, |
494 | | int32_t aIf1Ancestor, |
495 | | int32_t aIf2Ancestor, |
496 | | nsIFrame* aCommonAncestor = nullptr); |
497 | | |
498 | | static nsIFrame* FillAncestors(nsIFrame* aFrame, |
499 | | nsIFrame* aStopAtAncestor, |
500 | | nsTArray<nsIFrame*>* aAncestors); |
501 | | |
502 | | static int32_t DoCompareTreePosition(nsIFrame* aFrame1, |
503 | | nsIFrame* aFrame2, |
504 | | nsTArray<nsIFrame*>& aFrame2Ancestors, |
505 | | int32_t aIf1Ancestor, |
506 | | int32_t aIf2Ancestor, |
507 | | nsIFrame* aCommonAncestor); |
508 | | |
509 | | /** |
510 | | * LastContinuationWithChild gets the last continuation in aFrame's chain |
511 | | * that has a child, or the first continuation if the frame has no children. |
512 | | */ |
513 | | static nsContainerFrame* LastContinuationWithChild(nsContainerFrame* aFrame); |
514 | | |
515 | | /** |
516 | | * GetLastSibling simply finds the last sibling of aFrame, or returns nullptr if |
517 | | * aFrame is null. |
518 | | */ |
519 | | static nsIFrame* GetLastSibling(nsIFrame* aFrame); |
520 | | |
521 | | /** |
522 | | * FindSiblingViewFor locates the child of aParentView that aFrame's |
523 | | * view should be inserted 'above' (i.e., before in sibling view |
524 | | * order). This is the first child view of aParentView whose |
525 | | * corresponding content is before aFrame's content (view siblings |
526 | | * are in reverse content order). |
527 | | */ |
528 | | static nsView* FindSiblingViewFor(nsView* aParentView, nsIFrame* aFrame); |
529 | | |
530 | | /** |
531 | | * Get the parent of aFrame. If aFrame is the root frame for a document, |
532 | | * and the document has a parent document in the same view hierarchy, then |
533 | | * we try to return the subdocumentframe in the parent document. |
534 | | * @param aExtraOffset [in/out] if non-null, then as we cross documents |
535 | | * an extra offset may be required and it will be added to aCrossDocOffset. |
536 | | * Be careful dealing with this extra offset as it is in app units of the |
537 | | * parent document, which may have a different app units per dev pixel ratio |
538 | | * than the child document. |
539 | | */ |
540 | | static nsIFrame* GetCrossDocParentFrame(const nsIFrame* aFrame, |
541 | | nsPoint* aCrossDocOffset = nullptr); |
542 | | |
543 | | /** |
544 | | * IsProperAncestorFrame checks whether aAncestorFrame is an ancestor |
545 | | * of aFrame and not equal to aFrame. |
546 | | * @param aCommonAncestor nullptr, or a common ancestor of aFrame and |
547 | | * aAncestorFrame. If non-null, this can bound the search and speed up |
548 | | * the function |
549 | | */ |
550 | | static bool IsProperAncestorFrame(nsIFrame* aAncestorFrame, nsIFrame* aFrame, |
551 | | nsIFrame* aCommonAncestor = nullptr); |
552 | | |
553 | | /** |
554 | | * Like IsProperAncestorFrame, but looks across document boundaries. |
555 | | * |
556 | | * Just like IsAncestorFrameCrossDoc, except that it returns false when |
557 | | * aFrame == aAncestorFrame. |
558 | | */ |
559 | | static bool IsProperAncestorFrameCrossDoc(nsIFrame* aAncestorFrame, nsIFrame* aFrame, |
560 | | nsIFrame* aCommonAncestor = nullptr); |
561 | | |
562 | | /** |
563 | | * IsAncestorFrameCrossDoc checks whether aAncestorFrame is an ancestor |
564 | | * of aFrame or equal to aFrame, looking across document boundaries. |
565 | | * @param aCommonAncestor nullptr, or a common ancestor of aFrame and |
566 | | * aAncestorFrame. If non-null, this can bound the search and speed up |
567 | | * the function. |
568 | | * |
569 | | * Just like IsProperAncestorFrameCrossDoc, except that it returns true when |
570 | | * aFrame == aAncestorFrame. |
571 | | */ |
572 | | static bool IsAncestorFrameCrossDoc(const nsIFrame* aAncestorFrame, const nsIFrame* aFrame, |
573 | | const nsIFrame* aCommonAncestor = nullptr); |
574 | | |
575 | | /** |
576 | | * Sets the fixed-pos metadata properties on aLayer. |
577 | | * aAnchorRect is the basic anchor rectangle. If aFixedPosFrame is not a viewport |
578 | | * frame, then we pick a corner of aAnchorRect to as the anchor point for the |
579 | | * fixed-pos layer (i.e. the point to remain stable during zooming), based |
580 | | * on which of the fixed-pos frame's CSS absolute positioning offset |
581 | | * properties (top, left, right, bottom) are auto. aAnchorRect is in the |
582 | | * coordinate space of aLayer's container layer (i.e. relative to the reference |
583 | | * frame of the display item which is building aLayer's container layer). |
584 | | */ |
585 | | static void SetFixedPositionLayerData(Layer* aLayer, const nsIFrame* aViewportFrame, |
586 | | const nsRect& aAnchorRect, |
587 | | const nsIFrame* aFixedPosFrame, |
588 | | nsPresContext* aPresContext, |
589 | | const ContainerLayerParameters& aContainerParameters); |
590 | | |
591 | | /** |
592 | | * Get the scroll id for the root scrollframe of the presshell of the given |
593 | | * prescontext. Returns NULL_SCROLL_ID if it couldn't be found. |
594 | | */ |
595 | | static FrameMetrics::ViewID ScrollIdForRootScrollFrame(nsPresContext* aPresContext); |
596 | | |
597 | | /** |
598 | | * Return true if aPresContext's viewport has a displayport. |
599 | | */ |
600 | | static bool ViewportHasDisplayPort(nsPresContext* aPresContext); |
601 | | |
602 | | /** |
603 | | * Return true if aFrame is a fixed-pos frame and is a child of a viewport |
604 | | * which has a displayport. These frames get special treatment from the compositor. |
605 | | * aDisplayPort, if non-null, is set to the display port rectangle (relative to |
606 | | * the viewport). |
607 | | */ |
608 | | static bool IsFixedPosFrameInDisplayPort(const nsIFrame* aFrame); |
609 | | |
610 | | /** |
611 | | * GetScrollableFrameFor returns the scrollable frame for a scrolled frame |
612 | | */ |
613 | | static nsIScrollableFrame* GetScrollableFrameFor(const nsIFrame *aScrolledFrame); |
614 | | |
615 | | /** |
616 | | * GetNearestScrollableFrameForDirection locates the first ancestor of |
617 | | * aFrame (or aFrame itself) that is scrollable with overflow:scroll or |
618 | | * overflow:auto in the given direction and where either the scrollbar for |
619 | | * that direction is visible or the frame can be scrolled by some |
620 | | * positive amount in that direction. |
621 | | * The search extends across document boundaries. |
622 | | * |
623 | | * @param aFrame the frame to start with |
624 | | * @param aDirection Whether it's for horizontal or vertical scrolling. |
625 | | * @return the nearest scrollable frame or nullptr if not found |
626 | | */ |
627 | | enum Direction { eHorizontal, eVertical }; |
628 | | static nsIScrollableFrame* GetNearestScrollableFrameForDirection(nsIFrame* aFrame, |
629 | | Direction aDirection); |
630 | | |
631 | | enum { |
632 | | /** |
633 | | * If the SCROLLABLE_SAME_DOC flag is set, then we only walk the frame tree |
634 | | * up to the root frame in the current document. |
635 | | */ |
636 | | SCROLLABLE_SAME_DOC = 0x01, |
637 | | /** |
638 | | * If the SCROLLABLE_INCLUDE_HIDDEN flag is set then we allow |
639 | | * overflow:hidden scrollframes to be returned as scrollable frames. |
640 | | */ |
641 | | SCROLLABLE_INCLUDE_HIDDEN = 0x02, |
642 | | /** |
643 | | * If the SCROLLABLE_ONLY_ASYNC_SCROLLABLE flag is set, then we only |
644 | | * want to match scrollable frames for which WantAsyncScroll() returns |
645 | | * true. |
646 | | */ |
647 | | SCROLLABLE_ONLY_ASYNC_SCROLLABLE = 0x04, |
648 | | /** |
649 | | * If the SCROLLABLE_ALWAYS_MATCH_ROOT flag is set, then we will always |
650 | | * return the root scrollable frame for the root document (in the current |
651 | | * process) if we encounter it, whether or not it is async scrollable or |
652 | | * overflow: hidden. |
653 | | */ |
654 | | SCROLLABLE_ALWAYS_MATCH_ROOT = 0x08, |
655 | | /** |
656 | | * If the SCROLLABLE_FIXEDPOS_FINDS_ROOT flag is set, then for fixed-pos |
657 | | * frames that are in the root document (in the current process) return the |
658 | | * root scrollable frame for that document. |
659 | | */ |
660 | | SCROLLABLE_FIXEDPOS_FINDS_ROOT = 0x10 |
661 | | }; |
662 | | /** |
663 | | * GetNearestScrollableFrame locates the first ancestor of aFrame |
664 | | * (or aFrame itself) that is scrollable with overflow:scroll or |
665 | | * overflow:auto in some direction. |
666 | | * |
667 | | * @param aFrame the frame to start with |
668 | | * @param aFlags if SCROLLABLE_SAME_DOC is set, do not search across |
669 | | * document boundaries. If SCROLLABLE_INCLUDE_HIDDEN is set, include |
670 | | * frames scrollable with overflow:hidden. |
671 | | * @return the nearest scrollable frame or nullptr if not found |
672 | | */ |
673 | | static nsIScrollableFrame* GetNearestScrollableFrame(nsIFrame* aFrame, |
674 | | uint32_t aFlags = 0); |
675 | | |
676 | | /** |
677 | | * GetScrolledRect returns the range of allowable scroll offsets |
678 | | * for aScrolledFrame, assuming the scrollable overflow area is |
679 | | * aScrolledFrameOverflowArea and the scrollport size is aScrollPortSize. |
680 | | * aDirection is either NS_STYLE_DIRECTION_LTR or NS_STYLE_DIRECTION_RTL. |
681 | | */ |
682 | | static nsRect GetScrolledRect(nsIFrame* aScrolledFrame, |
683 | | const nsRect& aScrolledFrameOverflowArea, |
684 | | const nsSize& aScrollPortSize, |
685 | | uint8_t aDirection); |
686 | | |
687 | | /** |
688 | | * HasPseudoStyle returns true if aContent (whose primary style |
689 | | * context is aComputedStyle) has the aPseudoElement pseudo-style |
690 | | * attached to it; returns false otherwise. |
691 | | * |
692 | | * @param aContent the content node we're looking at |
693 | | * @param aComputedStyle aContent's ComputedStyle |
694 | | * @param aPseudoElement the id of the pseudo style we care about |
695 | | * @param aPresContext the presentation context |
696 | | * @return whether aContent has aPseudoElement style attached to it |
697 | | */ |
698 | | static bool HasPseudoStyle(nsIContent* aContent, |
699 | | ComputedStyle* aComputedStyle, |
700 | | mozilla::CSSPseudoElementType aPseudoElement, |
701 | | nsPresContext* aPresContext); |
702 | | |
703 | | /** |
704 | | * If this frame is a placeholder for a float, then return the float, |
705 | | * otherwise return nullptr. aPlaceholder must be a placeholder frame. |
706 | | */ |
707 | | static nsIFrame* GetFloatFromPlaceholder(nsIFrame* aPlaceholder); |
708 | | |
709 | | // Combine aNewBreakType with aOrigBreakType, but limit the break types |
710 | | // to StyleClear::Left, Right, Both. |
711 | | static mozilla::StyleClear CombineBreakType(mozilla::StyleClear aOrigBreakType, |
712 | | mozilla::StyleClear aNewBreakType); |
713 | | |
714 | | /** |
715 | | * Get the coordinates of a given DOM mouse event, relative to a given |
716 | | * frame. Works only for DOM events generated by WidgetGUIEvents. |
717 | | * @param aDOMEvent the event |
718 | | * @param aFrame the frame to make coordinates relative to |
719 | | * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if |
720 | | * for some reason the coordinates for the mouse are not known (e.g., |
721 | | * the event is not a GUI event). |
722 | | */ |
723 | | static nsPoint GetDOMEventCoordinatesRelativeTo(mozilla::dom::Event* aDOMEvent, |
724 | | nsIFrame* aFrame); |
725 | | |
726 | | /** |
727 | | * Get the coordinates of a given native mouse event, relative to a given |
728 | | * frame. |
729 | | * @param aEvent the event |
730 | | * @param aFrame the frame to make coordinates relative to |
731 | | * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if |
732 | | * for some reason the coordinates for the mouse are not known (e.g., |
733 | | * the event is not a GUI event). |
734 | | */ |
735 | | static nsPoint GetEventCoordinatesRelativeTo( |
736 | | const mozilla::WidgetEvent* aEvent, |
737 | | nsIFrame* aFrame); |
738 | | |
739 | | /** |
740 | | * Get the coordinates of a given point relative to an event and a |
741 | | * given frame. |
742 | | * @param aEvent the event |
743 | | * @param aPoint the point to get the coordinates relative to |
744 | | * @param aFrame the frame to make coordinates relative to |
745 | | * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if |
746 | | * for some reason the coordinates for the mouse are not known (e.g., |
747 | | * the event is not a GUI event). |
748 | | */ |
749 | | static nsPoint GetEventCoordinatesRelativeTo( |
750 | | const mozilla::WidgetEvent* aEvent, |
751 | | const mozilla::LayoutDeviceIntPoint& aPoint, |
752 | | nsIFrame* aFrame); |
753 | | |
754 | | /** |
755 | | * Get the coordinates of a given point relative to a widget and a |
756 | | * given frame. |
757 | | * @param aWidget the event src widget |
758 | | * @param aPoint the point to get the coordinates relative to |
759 | | * @param aFrame the frame to make coordinates relative to |
760 | | * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if |
761 | | * for some reason the coordinates for the mouse are not known (e.g., |
762 | | * the event is not a GUI event). |
763 | | */ |
764 | | static nsPoint GetEventCoordinatesRelativeTo(nsIWidget* aWidget, |
765 | | const mozilla::LayoutDeviceIntPoint& aPoint, |
766 | | nsIFrame* aFrame); |
767 | | |
768 | | /** |
769 | | * Get the popup frame of a given native mouse event. |
770 | | * @param aPresContext only check popups within aPresContext or a descendant |
771 | | * @param aEvent the event. |
772 | | * @return Null, if there is no popup frame at the point, otherwise, |
773 | | * returns top-most popup frame at the point. |
774 | | */ |
775 | | static nsIFrame* GetPopupFrameForEventCoordinates( |
776 | | nsPresContext* aPresContext, |
777 | | const mozilla::WidgetEvent* aEvent); |
778 | | |
779 | | /** |
780 | | * Translate from widget coordinates to the view's coordinates |
781 | | * @param aPresContext the PresContext for the view |
782 | | * @param aWidget the widget |
783 | | * @param aPt the point relative to the widget |
784 | | * @param aView view to which returned coordinates are relative |
785 | | * @return the point in the view's coordinates |
786 | | */ |
787 | | static nsPoint TranslateWidgetToView(nsPresContext* aPresContext, |
788 | | nsIWidget* aWidget, |
789 | | const mozilla::LayoutDeviceIntPoint& aPt, |
790 | | nsView* aView); |
791 | | |
792 | | /** |
793 | | * Translate from view coordinates to the widget's coordinates. |
794 | | * @param aPresContext the PresContext for the view |
795 | | * @param aView the view |
796 | | * @param aPt the point relative to the view |
797 | | * @param aWidget the widget to which returned coordinates are relative |
798 | | * @return the point in the view's coordinates |
799 | | */ |
800 | | static mozilla::LayoutDeviceIntPoint |
801 | | TranslateViewToWidget(nsPresContext* aPresContext, |
802 | | nsView* aView, nsPoint aPt, |
803 | | nsIWidget* aWidget); |
804 | | |
805 | | static mozilla::LayoutDeviceIntPoint |
806 | | WidgetToWidgetOffset(nsIWidget* aFromWidget, nsIWidget* aToWidget); |
807 | | |
808 | | enum FrameForPointFlags { |
809 | | /** |
810 | | * When set, paint suppression is ignored, so we'll return non-root page |
811 | | * elements even if paint suppression is stopping them from painting. |
812 | | */ |
813 | | IGNORE_PAINT_SUPPRESSION = 0x01, |
814 | | /** |
815 | | * When set, clipping due to the root scroll frame (and any other viewport- |
816 | | * related clipping) is ignored. |
817 | | */ |
818 | | IGNORE_ROOT_SCROLL_FRAME = 0x02, |
819 | | /** |
820 | | * When set, return only content in the same document as aFrame. |
821 | | */ |
822 | | IGNORE_CROSS_DOC = 0x04, |
823 | | /** |
824 | | * When set, return only content that is actually visible. |
825 | | */ |
826 | | ONLY_VISIBLE = 0x08 |
827 | | }; |
828 | | |
829 | | /** |
830 | | * Given aFrame, the root frame of a stacking context, find its descendant |
831 | | * frame under the point aPt that receives a mouse event at that location, |
832 | | * or nullptr if there is no such frame. |
833 | | * @param aPt the point, relative to the frame origin |
834 | | * @param aFlags some combination of FrameForPointFlags |
835 | | */ |
836 | | static nsIFrame* GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt, |
837 | | uint32_t aFlags = 0); |
838 | | |
839 | | /** |
840 | | * Given aFrame, the root frame of a stacking context, find all descendant |
841 | | * frames under the area of a rectangle that receives a mouse event, |
842 | | * or nullptr if there is no such frame. |
843 | | * @param aRect the rect, relative to the frame origin |
844 | | * @param aOutFrames an array to add all the frames found |
845 | | * @param aFlags some combination of FrameForPointFlags |
846 | | */ |
847 | | static nsresult GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect, |
848 | | nsTArray<nsIFrame*> &aOutFrames, |
849 | | uint32_t aFlags = 0); |
850 | | |
851 | | /** |
852 | | * Transform aRect relative to aFrame up to the coordinate system of |
853 | | * aAncestor. Computes the bounding-box of the true quadrilateral. |
854 | | * Pass non-null aPreservesAxisAlignedRectangles and it will be set to true if |
855 | | * we only need to use a 2d transform that PreservesAxisAlignedRectangles(). |
856 | | * |
857 | | * |aMatrixCache| allows for optimizations in recomputing the same matrix over |
858 | | * and over. The argument can be one of the following values: |
859 | | * nullptr (the default) - No optimization; the transform matrix is computed on |
860 | | * every call to this function. |
861 | | * non-null pointer to an empty Maybe<Matrix4x4> - Upon return, the Maybe is |
862 | | * filled with the transform matrix that was computed. This can then be passed |
863 | | * in to subsequent calls with the same source and destination frames to avoid |
864 | | * recomputing the matrix. |
865 | | * non-null pointer to a non-empty Matrix4x4 - The provided matrix will be used |
866 | | * as the transform matrix and applied to the rect. |
867 | | */ |
868 | | static nsRect TransformFrameRectToAncestor(const nsIFrame* aFrame, |
869 | | const nsRect& aRect, |
870 | | const nsIFrame* aAncestor, |
871 | | bool* aPreservesAxisAlignedRectangles = nullptr, |
872 | | mozilla::Maybe<Matrix4x4Flagged>* aMatrixCache = nullptr, |
873 | | bool aStopAtStackingContextAndDisplayPortAndOOFFrame = false, |
874 | | nsIFrame** aOutAncestor = nullptr); |
875 | | |
876 | | |
877 | | /** |
878 | | * Gets the transform for aFrame relative to aAncestor. Pass null for |
879 | | * aAncestor to go up to the root frame. aInCSSUnits set to true will |
880 | | * return CSS units, set to false (the default) will return App units. |
881 | | */ |
882 | | static Matrix4x4Flagged GetTransformToAncestor(const nsIFrame *aFrame, |
883 | | const nsIFrame *aAncestor, |
884 | | uint32_t aFlags = 0, |
885 | | nsIFrame** aOutAncestor = nullptr); |
886 | | |
887 | | /** |
888 | | * Gets the scale factors of the transform for aFrame relative to the root |
889 | | * frame if this transform is 2D, or the identity scale factors otherwise. |
890 | | */ |
891 | | static gfxSize GetTransformToAncestorScale(nsIFrame* aFrame); |
892 | | |
893 | | /** |
894 | | * Gets the scale factors of the transform for aFrame relative to the root |
895 | | * frame if this transform is 2D, or the identity scale factors otherwise. |
896 | | * If some frame on the path from aFrame to the display root frame may have an |
897 | | * animated scale, returns the identity scale factors. |
898 | | */ |
899 | | static gfxSize GetTransformToAncestorScaleExcludingAnimated(nsIFrame* aFrame); |
900 | | |
901 | | /** |
902 | | * Find the nearest common ancestor frame for aFrame1 and aFrame2. The |
903 | | * ancestor frame could be cross-doc. |
904 | | */ |
905 | | static nsIFrame* FindNearestCommonAncestorFrame(nsIFrame* aFrame1, |
906 | | nsIFrame* aFrame2); |
907 | | |
908 | | /** |
909 | | * Transforms a list of CSSPoints from aFromFrame to aToFrame, taking into |
910 | | * account all relevant transformations on the frames up to (but excluding) |
911 | | * their nearest common ancestor. |
912 | | * If we encounter a transform that we need to invert but which is |
913 | | * non-invertible, we return NONINVERTIBLE_TRANSFORM. If the frames have |
914 | | * no common ancestor, we return NO_COMMON_ANCESTOR. |
915 | | * If this returns TRANSFORM_SUCCEEDED, the points in aPoints are transformed |
916 | | * in-place, otherwise they are untouched. |
917 | | */ |
918 | | enum TransformResult { |
919 | | TRANSFORM_SUCCEEDED, |
920 | | NO_COMMON_ANCESTOR, |
921 | | NONINVERTIBLE_TRANSFORM |
922 | | }; |
923 | | static TransformResult TransformPoints(nsIFrame* aFromFrame, nsIFrame* aToFrame, |
924 | | uint32_t aPointCount, CSSPoint* aPoints); |
925 | | |
926 | | /** |
927 | | * Same as above function, but transform points in app units and |
928 | | * handle 1 point per call. |
929 | | */ |
930 | | static TransformResult TransformPoint(nsIFrame* aFromFrame, nsIFrame* aToFrame, |
931 | | nsPoint& aPoint); |
932 | | |
933 | | /** |
934 | | * Transforms a rect from aFromFrame to aToFrame. In app units. |
935 | | * Returns the bounds of the actual rect if the transform requires rotation |
936 | | * or anything complex like that. |
937 | | */ |
938 | | static TransformResult TransformRect(nsIFrame* aFromFrame, nsIFrame* aToFrame, |
939 | | nsRect& aRect); |
940 | | |
941 | | /** |
942 | | * Converts app units to pixels (with optional snapping) and appends as a |
943 | | * translation to aTransform. |
944 | | */ |
945 | | static void PostTranslate(Matrix4x4& aTransform, const nsPoint& aOrigin, float aAppUnitsPerPixel, bool aRounded); |
946 | | |
947 | | /** |
948 | | * Get the border-box of aElement's primary frame, transformed it to be |
949 | | * relative to aFrame. |
950 | | */ |
951 | | static nsRect GetRectRelativeToFrame(mozilla::dom::Element* aElement, |
952 | | nsIFrame* aFrame); |
953 | | |
954 | | /** |
955 | | * Returns true if aRect with border inflation of size aInflateSize contains |
956 | | * aPoint. |
957 | | */ |
958 | | static bool ContainsPoint(const nsRect& aRect, const nsPoint& aPoint, |
959 | | nscoord aInflateSize); |
960 | | |
961 | | /** |
962 | | * Clamp aRect relative to aFrame to the scroll frames boundary searching from |
963 | | * aFrame. |
964 | | */ |
965 | | static nsRect ClampRectToScrollFrames(nsIFrame* aFrame, |
966 | | const nsRect& aRect); |
967 | | |
968 | | /** |
969 | | * Return true if a "layer transform" could be computed for aFrame, |
970 | | * and optionally return the computed transform. The returned |
971 | | * transform is what would be set on the layer currently if a layers |
972 | | * transaction were opened at the time this helper is called. |
973 | | */ |
974 | | static bool GetLayerTransformForFrame(nsIFrame* aFrame, |
975 | | Matrix4x4Flagged* aTransform); |
976 | | |
977 | | /** |
978 | | * Given a point in the global coordinate space, returns that point expressed |
979 | | * in the coordinate system of aFrame. This effectively inverts all |
980 | | * transforms between this point and the root frame. |
981 | | * |
982 | | * @param aFrame The frame that acts as the coordinate space container. |
983 | | * @param aPoint The point, in the global space, to get in the frame-local space. |
984 | | * @return aPoint, expressed in aFrame's canonical coordinate space. |
985 | | */ |
986 | | static nsPoint TransformRootPointToFrame(nsIFrame* aFrame, |
987 | | const nsPoint &aPoint) |
988 | | { |
989 | | return TransformAncestorPointToFrame(aFrame, aPoint, nullptr); |
990 | | } |
991 | | |
992 | | /** |
993 | | * Transform aPoint relative to aAncestor down to the coordinate system of |
994 | | * aFrame. |
995 | | */ |
996 | | static nsPoint TransformAncestorPointToFrame(nsIFrame* aFrame, |
997 | | const nsPoint& aPoint, |
998 | | nsIFrame* aAncestor); |
999 | | |
1000 | | /** |
1001 | | * Helper function that, given a rectangle and a matrix, returns the smallest |
1002 | | * rectangle containing the image of the source rectangle. |
1003 | | * |
1004 | | * @param aBounds The rectangle to transform. |
1005 | | * @param aMatrix The matrix to transform it with. |
1006 | | * @param aFactor The number of app units per graphics unit. |
1007 | | * @return The smallest rect that contains the image of aBounds. |
1008 | | */ |
1009 | | static nsRect MatrixTransformRect(const nsRect &aBounds, |
1010 | | const Matrix4x4 &aMatrix, float aFactor); |
1011 | | static nsRect MatrixTransformRect(const nsRect &aBounds, |
1012 | | const Matrix4x4Flagged &aMatrix, float aFactor); |
1013 | | |
1014 | | /** |
1015 | | * Helper function that, given a point and a matrix, returns the image |
1016 | | * of that point under the matrix transform. |
1017 | | * |
1018 | | * @param aPoint The point to transform. |
1019 | | * @param aMatrix The matrix to transform it with. |
1020 | | * @param aFactor The number of app units per graphics unit. |
1021 | | * @return The image of the point under the transform. |
1022 | | */ |
1023 | | static nsPoint MatrixTransformPoint(const nsPoint &aPoint, |
1024 | | const Matrix4x4 &aMatrix, float aFactor); |
1025 | | |
1026 | | /** |
1027 | | * Given a graphics rectangle in graphics space, return a rectangle in |
1028 | | * app space that contains the graphics rectangle, rounding out as necessary. |
1029 | | * |
1030 | | * @param aRect The graphics rect to round outward. |
1031 | | * @param aFactor The number of app units per graphics unit. |
1032 | | * @return The smallest rectangle in app space that contains aRect. |
1033 | | */ |
1034 | | static nsRect RoundGfxRectToAppRect(const Rect &aRect, float aFactor); |
1035 | | |
1036 | | /** |
1037 | | * Given a graphics rectangle in graphics space, return a rectangle in |
1038 | | * app space that contains the graphics rectangle, rounding out as necessary. |
1039 | | * |
1040 | | * @param aRect The graphics rect to round outward. |
1041 | | * @param aFactor The number of app units per graphics unit. |
1042 | | * @return The smallest rectangle in app space that contains aRect. |
1043 | | */ |
1044 | | static nsRect RoundGfxRectToAppRect(const gfxRect &aRect, float aFactor); |
1045 | | |
1046 | | /** |
1047 | | * Returns a subrectangle of aContainedRect that is entirely inside the rounded |
1048 | | * rect. Complex cases are handled conservatively by returning a smaller |
1049 | | * rect than necessary. |
1050 | | */ |
1051 | | static nsRegion RoundedRectIntersectRect(const nsRect& aRoundedRect, |
1052 | | const nscoord aRadii[8], |
1053 | | const nsRect& aContainedRect); |
1054 | | static nsIntRegion RoundedRectIntersectIntRect(const nsIntRect& aRoundedRect, |
1055 | | const RectCornerRadii& aCornerRadii, |
1056 | | const nsIntRect& aContainedRect); |
1057 | | |
1058 | | /** |
1059 | | * Return whether any part of aTestRect is inside of the rounded |
1060 | | * rectangle formed by aBounds and aRadii (which are indexed by the |
1061 | | * enum HalfCorner constants in gfx/2d/Types.h). This is precise. |
1062 | | */ |
1063 | | static bool RoundedRectIntersectsRect(const nsRect& aRoundedRect, |
1064 | | const nscoord aRadii[8], |
1065 | | const nsRect& aTestRect); |
1066 | | |
1067 | | static bool MaybeCreateDisplayPortInFirstScrollFrameEncountered( |
1068 | | nsIFrame* aFrame, nsDisplayListBuilder& aBuilder); |
1069 | | |
1070 | | |
1071 | | enum class PaintFrameFlags : uint32_t { |
1072 | | PAINT_IN_TRANSFORM = 0x01, |
1073 | | PAINT_SYNC_DECODE_IMAGES = 0x02, |
1074 | | PAINT_WIDGET_LAYERS = 0x04, |
1075 | | PAINT_IGNORE_SUPPRESSION = 0x08, |
1076 | | PAINT_DOCUMENT_RELATIVE = 0x10, |
1077 | | PAINT_HIDE_CARET = 0x20, |
1078 | | PAINT_TO_WINDOW = 0x40, |
1079 | | PAINT_EXISTING_TRANSACTION = 0x80, |
1080 | | PAINT_NO_COMPOSITE = 0x100, |
1081 | | PAINT_COMPRESSED = 0x200 |
1082 | | }; |
1083 | | |
1084 | | /** |
1085 | | * Given aFrame, the root frame of a stacking context, paint it and its |
1086 | | * descendants to aRenderingContext. |
1087 | | * @param aRenderingContext a rendering context translated so that (0,0) |
1088 | | * is the origin of aFrame; for best results, (0,0) should transform |
1089 | | * to pixel-aligned coordinates. This can be null, in which case |
1090 | | * aFrame must be a "display root" (root frame for a root document, |
1091 | | * or the root of a popup) with an associated widget and we draw using |
1092 | | * the layer manager for the frame's widget. |
1093 | | * @param aDirtyRegion the region that must be painted, in the coordinates |
1094 | | * of aFrame. |
1095 | | * @param aBackstop paint the dirty area with this color before drawing |
1096 | | * the actual content; pass NS_RGBA(0,0,0,0) to draw no background. |
1097 | | * @param aBuilderMode Passed through to the display-list builder. |
1098 | | * @param aFlags if PAINT_IN_TRANSFORM is set, then we assume |
1099 | | * this is inside a transform or SVG foreignObject. If |
1100 | | * PAINT_SYNC_DECODE_IMAGES is set, we force synchronous decode on all |
1101 | | * images. If PAINT_WIDGET_LAYERS is set, aFrame must be a display root, |
1102 | | * and we will use the frame's widget's layer manager to paint |
1103 | | * even if aRenderingContext is non-null. This is useful if you want |
1104 | | * to force rendering to use the widget's layer manager for testing |
1105 | | * or speed. PAINT_WIDGET_LAYERS must be set if aRenderingContext is null. |
1106 | | * If PAINT_DOCUMENT_RELATIVE is used, the visible region is interpreted |
1107 | | * as being relative to the document (normally it's relative to the CSS |
1108 | | * viewport) and the document is painted as if no scrolling has occured. |
1109 | | * Only considered if nsIPresShell::IgnoringViewportScrolling is true. |
1110 | | * PAINT_TO_WINDOW sets painting to window to true on the display list |
1111 | | * builder even if we can't tell that we are painting to the window. |
1112 | | * If PAINT_EXISTING_TRANSACTION is set, then BeginTransaction() has already |
1113 | | * been called on aFrame's widget's layer manager and should not be |
1114 | | * called again. |
1115 | | * If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to |
1116 | | * compressed mode to avoid short cut optimizations. |
1117 | | * |
1118 | | * So there are three possible behaviours: |
1119 | | * 1) PAINT_WIDGET_LAYERS is set and aRenderingContext is null; we paint |
1120 | | * by calling BeginTransaction on the widget's layer manager. |
1121 | | * 2) PAINT_WIDGET_LAYERS is set and aRenderingContext is non-null; we |
1122 | | * paint by calling BeginTransactionWithTarget on the widget's layer |
1123 | | * manager. |
1124 | | * 3) PAINT_WIDGET_LAYERS is not set and aRenderingContext is non-null; |
1125 | | * we paint by construct a BasicLayerManager and calling |
1126 | | * BeginTransactionWithTarget on it. This is desirable if we're doing |
1127 | | * something like drawWindow in a mode where what gets rendered doesn't |
1128 | | * necessarily correspond to what's visible in the window; we don't |
1129 | | * want to mess up the widget's layer tree. |
1130 | | */ |
1131 | | static nsresult PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame, |
1132 | | const nsRegion& aDirtyRegion, nscolor aBackstop, |
1133 | | nsDisplayListBuilderMode aBuilderMode, |
1134 | | PaintFrameFlags aFlags = PaintFrameFlags(0)); |
1135 | | |
1136 | | /** |
1137 | | * Uses a binary search for find where the cursor falls in the line of text |
1138 | | * It also keeps track of the part of the string that has already been |
1139 | | * measured so it doesn't have to keep measuring the same text over and over. |
1140 | | * |
1141 | | * @param "aBaseWidth" contains the width in twips of the portion |
1142 | | * of the text that has already been measured, and aBaseInx contains |
1143 | | * the index of the text that has already been measured. |
1144 | | * |
1145 | | * @param aTextWidth returns (in twips) the length of the text that falls |
1146 | | * before the cursor aIndex contains the index of the text where the cursor |
1147 | | * falls. |
1148 | | */ |
1149 | | static bool |
1150 | | BinarySearchForPosition(DrawTarget* aDrawTarget, |
1151 | | nsFontMetrics& aFontMetrics, |
1152 | | const char16_t* aText, |
1153 | | int32_t aBaseWidth, |
1154 | | int32_t aBaseInx, |
1155 | | int32_t aStartInx, |
1156 | | int32_t aEndInx, |
1157 | | int32_t aCursorPos, |
1158 | | int32_t& aIndex, |
1159 | | int32_t& aTextWidth); |
1160 | | |
1161 | | class BoxCallback { |
1162 | | public: |
1163 | | BoxCallback() : mIncludeCaptionBoxForTable(true) {} |
1164 | | virtual void AddBox(nsIFrame* aFrame) = 0; |
1165 | | bool mIncludeCaptionBoxForTable; |
1166 | | }; |
1167 | | /** |
1168 | | * Collect all CSS boxes associated with aFrame and its |
1169 | | * continuations, "drilling down" through table wrapper frames and |
1170 | | * some anonymous blocks since they're not real CSS boxes. |
1171 | | * If aFrame is null, no boxes are returned. |
1172 | | * SVG frames return a single box, themselves. |
1173 | | */ |
1174 | | static void GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback); |
1175 | | |
1176 | | /** |
1177 | | * Like GetAllInFlowBoxes, but doesn't include continuations. |
1178 | | */ |
1179 | | static void AddBoxesForFrame(nsIFrame* aFrame, BoxCallback* aCallback); |
1180 | | |
1181 | | /** |
1182 | | * Find the first frame descendant of aFrame (including aFrame) which is |
1183 | | * not an anonymous frame that getBoxQuads/getClientRects should ignore. |
1184 | | */ |
1185 | | static nsIFrame* GetFirstNonAnonymousFrame(nsIFrame* aFrame); |
1186 | | |
1187 | | class RectCallback { |
1188 | | public: |
1189 | | virtual void AddRect(const nsRect& aRect) = 0; |
1190 | | }; |
1191 | | |
1192 | | struct RectAccumulator : public RectCallback { |
1193 | | nsRect mResultRect; |
1194 | | nsRect mFirstRect; |
1195 | | bool mSeenFirstRect; |
1196 | | |
1197 | | RectAccumulator(); |
1198 | | |
1199 | | virtual void AddRect(const nsRect& aRect) override; |
1200 | | }; |
1201 | | |
1202 | | struct RectListBuilder : public RectCallback { |
1203 | | DOMRectList* mRectList; |
1204 | | |
1205 | | explicit RectListBuilder(DOMRectList* aList); |
1206 | | virtual void AddRect(const nsRect& aRect) override; |
1207 | | }; |
1208 | | |
1209 | | static nsIFrame* GetContainingBlockForClientRect(nsIFrame* aFrame); |
1210 | | |
1211 | | enum { |
1212 | | RECTS_ACCOUNT_FOR_TRANSFORMS = 0x01, |
1213 | | // Two bits for specifying which box type to use. |
1214 | | // With neither bit set (default), use the border box. |
1215 | | RECTS_USE_CONTENT_BOX = 0x02, |
1216 | | RECTS_USE_PADDING_BOX = 0x04, |
1217 | | RECTS_USE_MARGIN_BOX = 0x06, // both bits set |
1218 | | RECTS_WHICH_BOX_MASK = 0x06 // bitmask for these two bits |
1219 | | }; |
1220 | | /** |
1221 | | * Collect all CSS boxes (content, padding, border, or margin) associated |
1222 | | * with aFrame and its continuations, "drilling down" through table wrapper |
1223 | | * frames and some anonymous blocks since they're not real CSS boxes. |
1224 | | * The boxes are positioned relative to aRelativeTo (taking scrolling |
1225 | | * into account) and passed to the callback in frame-tree order. |
1226 | | * If aFrame is null, no boxes are returned. |
1227 | | * For SVG frames, returns one rectangle, the bounding box. |
1228 | | * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting |
1229 | | * the boxes into aRelativeTo coordinates, transforms (including CSS |
1230 | | * and SVG transforms) are taken into account. |
1231 | | * If aFlags includes one of RECTS_USE_CONTENT_BOX, RECTS_USE_PADDING_BOX, |
1232 | | * or RECTS_USE_MARGIN_BOX, the corresponding type of box is used. |
1233 | | * Otherwise (by default), the border box is used. |
1234 | | */ |
1235 | | static void GetAllInFlowRects(nsIFrame* aFrame, const nsIFrame* aRelativeTo, |
1236 | | RectCallback* aCallback, uint32_t aFlags = 0); |
1237 | | |
1238 | | static void GetAllInFlowRectsAndTexts(nsIFrame* aFrame, |
1239 | | const nsIFrame* aRelativeTo, |
1240 | | RectCallback* aCallback, |
1241 | | mozilla::dom::Sequence<nsString>* aTextList, |
1242 | | uint32_t aFlags = 0); |
1243 | | |
1244 | | /** |
1245 | | * Computes the union of all rects returned by GetAllInFlowRects. If |
1246 | | * the union is empty, returns the first rect. |
1247 | | * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting |
1248 | | * the boxes into aRelativeTo coordinates, transforms (including CSS |
1249 | | * and SVG transforms) are taken into account. |
1250 | | * If aFlags includes one of RECTS_USE_CONTENT_BOX, RECTS_USE_PADDING_BOX, |
1251 | | * or RECTS_USE_MARGIN_BOX, the corresponding type of box is used. |
1252 | | * Otherwise (by default), the border box is used. |
1253 | | */ |
1254 | | static nsRect GetAllInFlowRectsUnion(nsIFrame* aFrame, const nsIFrame* aRelativeTo, |
1255 | | uint32_t aFlags = 0); |
1256 | | |
1257 | | enum { |
1258 | | EXCLUDE_BLUR_SHADOWS = 0x01 |
1259 | | }; |
1260 | | /** |
1261 | | * Takes a text-shadow array from the style properties of a given nsIFrame and |
1262 | | * computes the union of those shadows along with the given initial rect. |
1263 | | * If there are no shadows, the initial rect is returned. |
1264 | | */ |
1265 | | static nsRect GetTextShadowRectsUnion(const nsRect& aTextAndDecorationsRect, |
1266 | | nsIFrame* aFrame, |
1267 | | uint32_t aFlags = 0); |
1268 | | |
1269 | | /** |
1270 | | * Computes the destination rect that a given replaced element should render |
1271 | | * into, based on its CSS 'object-fit' and 'object-position' properties. |
1272 | | * |
1273 | | * @param aConstraintRect The constraint rect that we have at our disposal, |
1274 | | * which would e.g. be exactly filled by the image |
1275 | | * if we had "object-fit: fill". |
1276 | | * @param aIntrinsicSize The replaced content's intrinsic size, as reported |
1277 | | * by nsIFrame::GetIntrinsicSize(). |
1278 | | * @param aIntrinsicRatio The replaced content's intrinsic ratio, as reported |
1279 | | * by nsIFrame::GetIntrinsicRatio(). |
1280 | | * @param aStylePos The nsStylePosition struct that contains the 'object-fit' |
1281 | | * and 'object-position' values that we should rely on. |
1282 | | * (This should usually be the nsStylePosition for the |
1283 | | * replaced element in question, but not always. For |
1284 | | * example, a <video>'s poster-image has a dedicated |
1285 | | * anonymous element & child-frame, but we should still use |
1286 | | * the <video>'s 'object-fit' and 'object-position' values.) |
1287 | | * @param aAnchorPoint [out] A point that should be pixel-aligned by functions |
1288 | | * like nsLayoutUtils::DrawImage. See documentation |
1289 | | * in nsCSSRendering.h for ComputeObjectAnchorPoint. |
1290 | | * @return The nsRect into which we should render the replaced content (using |
1291 | | * the same coordinate space as the passed-in aConstraintRect). |
1292 | | */ |
1293 | | static nsRect ComputeObjectDestRect(const nsRect& aConstraintRect, |
1294 | | const IntrinsicSize& aIntrinsicSize, |
1295 | | const nsSize& aIntrinsicRatio, |
1296 | | const nsStylePosition* aStylePos, |
1297 | | nsPoint* aAnchorPoint = nullptr); |
1298 | | |
1299 | | /** |
1300 | | * Get the font metrics corresponding to the frame's style data. |
1301 | | * @param aFrame the frame |
1302 | | * @param aSizeInflation number to multiply font size by |
1303 | | */ |
1304 | | static already_AddRefed<nsFontMetrics> GetFontMetricsForFrame( |
1305 | | const nsIFrame* aFrame, float aSizeInflation); |
1306 | | |
1307 | | static already_AddRefed<nsFontMetrics> |
1308 | | GetInflatedFontMetricsForFrame(const nsIFrame* aFrame) |
1309 | 0 | { |
1310 | 0 | return GetFontMetricsForFrame(aFrame, FontSizeInflationFor(aFrame)); |
1311 | 0 | } |
1312 | | |
1313 | | /** |
1314 | | * Get the font metrics corresponding to the given style data. |
1315 | | * @param aComputedStyle the style data |
1316 | | * @param aSizeInflation number to multiply font size by |
1317 | | */ |
1318 | | static already_AddRefed<nsFontMetrics> GetFontMetricsForComputedStyle( |
1319 | | ComputedStyle* aComputedStyle, |
1320 | | nsPresContext* aPresContext, |
1321 | | float aSizeInflation = 1.0f, |
1322 | | uint8_t aVariantWidth = NS_FONT_VARIANT_WIDTH_NORMAL); |
1323 | | |
1324 | | /** |
1325 | | * Get the font metrics of emphasis marks corresponding to the given |
1326 | | * style data. The result is same as GetFontMetricsForComputedStyle |
1327 | | * except that the font size is scaled down to 50%. |
1328 | | * @param aComputedStyle the style data |
1329 | | * @param aInflation number to multiple font size by |
1330 | | */ |
1331 | | static already_AddRefed<nsFontMetrics> GetFontMetricsOfEmphasisMarks( |
1332 | | ComputedStyle* aComputedStyle, |
1333 | | nsPresContext* aPresContext, |
1334 | | float aInflation) |
1335 | | { |
1336 | | return GetFontMetricsForComputedStyle(aComputedStyle, |
1337 | | aPresContext, |
1338 | | aInflation * 0.5f); |
1339 | | } |
1340 | | |
1341 | | /** |
1342 | | * Find the immediate child of aParent whose frame subtree contains |
1343 | | * aDescendantFrame. Returns null if aDescendantFrame is not a descendant |
1344 | | * of aParent. |
1345 | | */ |
1346 | | static nsIFrame* FindChildContainingDescendant(nsIFrame* aParent, nsIFrame* aDescendantFrame); |
1347 | | |
1348 | | /** |
1349 | | * Find the nearest ancestor that's a block |
1350 | | */ |
1351 | | static nsBlockFrame* FindNearestBlockAncestor(nsIFrame* aFrame); |
1352 | | |
1353 | | /** |
1354 | | * Find the nearest ancestor that's not for generated content. Will return |
1355 | | * aFrame if aFrame is not for generated content. |
1356 | | */ |
1357 | | static nsIFrame* GetNonGeneratedAncestor(nsIFrame* aFrame); |
1358 | | |
1359 | | /** |
1360 | | * Cast aFrame to an nsBlockFrame* or return null if it's not |
1361 | | * an nsBlockFrame. |
1362 | | */ |
1363 | | static nsBlockFrame* GetAsBlock(nsIFrame* aFrame); |
1364 | | |
1365 | | /* |
1366 | | * Whether the frame is an nsBlockFrame which is not a wrapper block. |
1367 | | */ |
1368 | | static bool IsNonWrapperBlock(nsIFrame* aFrame); |
1369 | | |
1370 | | /** |
1371 | | * If aFrame is an out of flow frame, return its placeholder, otherwise |
1372 | | * return its parent. |
1373 | | */ |
1374 | | static nsIFrame* GetParentOrPlaceholderFor(nsIFrame* aFrame); |
1375 | | |
1376 | | /** |
1377 | | * If aFrame is an out of flow frame, return its placeholder, otherwise |
1378 | | * return its (possibly cross-doc) parent. |
1379 | | */ |
1380 | | static nsIFrame* GetParentOrPlaceholderForCrossDoc(nsIFrame* aFrame); |
1381 | | |
1382 | | /** |
1383 | | * Get a frame's next-in-flow, or, if it doesn't have one, its |
1384 | | * block-in-inline-split sibling. |
1385 | | */ |
1386 | | static nsIFrame* |
1387 | | GetNextContinuationOrIBSplitSibling(nsIFrame *aFrame); |
1388 | | |
1389 | | /** |
1390 | | * Get the first frame in the continuation-plus-ib-split-sibling chain |
1391 | | * containing aFrame. |
1392 | | */ |
1393 | | static nsIFrame* |
1394 | | FirstContinuationOrIBSplitSibling(const nsIFrame *aFrame); |
1395 | | |
1396 | | /** |
1397 | | * Get the last frame in the continuation-plus-ib-split-sibling chain |
1398 | | * containing aFrame. |
1399 | | */ |
1400 | | static nsIFrame* |
1401 | | LastContinuationOrIBSplitSibling(const nsIFrame *aFrame); |
1402 | | |
1403 | | /** |
1404 | | * Is FirstContinuationOrIBSplitSibling(aFrame) going to return |
1405 | | * aFrame? |
1406 | | */ |
1407 | | static bool |
1408 | | IsFirstContinuationOrIBSplitSibling(nsIFrame *aFrame); |
1409 | | |
1410 | | /** |
1411 | | * Check whether aFrame is a part of the scrollbar or scrollcorner of |
1412 | | * the root content. |
1413 | | * @param aFrame the checking frame. |
1414 | | * @return true if the frame is a part of the scrollbar or scrollcorner of |
1415 | | * the root content. |
1416 | | */ |
1417 | | static bool IsViewportScrollbarFrame(nsIFrame* aFrame); |
1418 | | |
1419 | | /** |
1420 | | * Get the contribution of aFrame to its containing block's intrinsic |
1421 | | * size for the given physical axis. This considers the child's intrinsic |
1422 | | * width, its 'width', 'min-width', and 'max-width' properties (or 'height' |
1423 | | * variations if that's what matches aAxis) and its padding, border and margin |
1424 | | * in the corresponding dimension. |
1425 | | * @param aPercentageBasis an optional percentage basis (in aFrame's WM). |
1426 | | * If the basis is indefinite in a given axis, pass a size with |
1427 | | * NS_UNCONSTRAINEDSIZE in that component. |
1428 | | * If you pass Nothing() a percentage basis will be calculated from aFrame's |
1429 | | * ancestors' computed size in the relevant axis, if needed. |
1430 | | * @param aMarginBoxMinSizeClamp make the result fit within this margin-box |
1431 | | * size by reducing the *content size* (flooring at zero). This is used for: |
1432 | | * https://drafts.csswg.org/css-grid/#min-size-auto |
1433 | | */ |
1434 | | enum class IntrinsicISizeType { MIN_ISIZE, PREF_ISIZE }; |
1435 | | static const auto MIN_ISIZE = IntrinsicISizeType::MIN_ISIZE; |
1436 | | static const auto PREF_ISIZE = IntrinsicISizeType::PREF_ISIZE; |
1437 | | enum { |
1438 | | IGNORE_PADDING = 0x01, |
1439 | | BAIL_IF_REFLOW_NEEDED = 0x02, // returns NS_INTRINSIC_WIDTH_UNKNOWN if so |
1440 | | MIN_INTRINSIC_ISIZE = 0x04, // use min-width/height instead of width/height |
1441 | | }; |
1442 | | static nscoord |
1443 | | IntrinsicForAxis(mozilla::PhysicalAxis aAxis, |
1444 | | gfxContext* aRenderingContext, |
1445 | | nsIFrame* aFrame, |
1446 | | IntrinsicISizeType aType, |
1447 | | const mozilla::Maybe<LogicalSize>& aPercentageBasis = mozilla::Nothing(), |
1448 | | uint32_t aFlags = 0, |
1449 | | nscoord aMarginBoxMinSizeClamp = NS_MAXSIZE); |
1450 | | /** |
1451 | | * Calls IntrinsicForAxis with aFrame's parent's inline physical axis. |
1452 | | */ |
1453 | | static nscoord IntrinsicForContainer(gfxContext* aRenderingContext, |
1454 | | nsIFrame* aFrame, |
1455 | | IntrinsicISizeType aType, |
1456 | | uint32_t aFlags = 0); |
1457 | | |
1458 | | /** |
1459 | | * Get the definite size contribution of aFrame for the given physical axis. |
1460 | | * This considers the child's 'min-width' property (or 'min-height' if the |
1461 | | * given axis is vertical), and its padding, border, and margin in the |
1462 | | * corresponding dimension. If the 'min-' property is 'auto' (and 'overflow' |
1463 | | * is 'visible') and the corresponding 'width'/'height' is definite it returns |
1464 | | * the "specified size" for: |
1465 | | * https://drafts.csswg.org/css-grid/#min-size-auto |
1466 | | * Note that the "transferred size" is not handled here; use IntrinsicForAxis. |
1467 | | * Note that any percentage in 'width'/'height' makes it count as indefinite. |
1468 | | * If the 'min-' property is 'auto' and 'overflow' is not 'visible', then it |
1469 | | * calculates the result as if the 'min-' computed value is zero. |
1470 | | * Otherwise, return NS_UNCONSTRAINEDSIZE. |
1471 | | * |
1472 | | * @param aPercentageBasis the percentage basis (in aFrame's WM). |
1473 | | * Pass NS_UNCONSTRAINEDSIZE if the basis is indefinite in either/both axes. |
1474 | | * @note this behavior is specific to Grid/Flexbox (currently) so aFrame |
1475 | | * should be a grid/flex item. |
1476 | | */ |
1477 | | static nscoord |
1478 | | MinSizeContributionForAxis(mozilla::PhysicalAxis aAxis, |
1479 | | gfxContext* aRC, |
1480 | | nsIFrame* aFrame, |
1481 | | IntrinsicISizeType aType, |
1482 | | const LogicalSize& aPercentageBasis, |
1483 | | uint32_t aFlags = 0); |
1484 | | |
1485 | | /* |
1486 | | * Convert nsStyleCoord to nscoord when percentages depend on the |
1487 | | * containing block size. |
1488 | | * @param aPercentBasis The width or height of the containing block |
1489 | | * (whichever the client wants to use for resolving percentages). |
1490 | | */ |
1491 | | static nscoord ComputeCBDependentValue(nscoord aPercentBasis, |
1492 | | const nsStyleCoord& aCoord); |
1493 | | |
1494 | | static nscoord ComputeBSizeDependentValue( |
1495 | | nscoord aContainingBlockBSize, |
1496 | | const nsStyleCoord& aCoord); |
1497 | | |
1498 | | static nscoord ComputeBSizeValue(nscoord aContainingBlockBSize, |
1499 | | nscoord aContentEdgeToBoxSizingBoxEdge, |
1500 | | const nsStyleCoord& aCoord) |
1501 | | { |
1502 | | MOZ_ASSERT(aContainingBlockBSize != nscoord_MAX || !aCoord.HasPercent(), |
1503 | | "caller must deal with %% of unconstrained block-size"); |
1504 | | MOZ_ASSERT(aCoord.IsCoordPercentCalcUnit()); |
1505 | | |
1506 | | nscoord result = aCoord.ComputeCoordPercentCalc(aContainingBlockBSize); |
1507 | | // Clamp calc(), and the subtraction for box-sizing. |
1508 | | return std::max(0, result - aContentEdgeToBoxSizingBoxEdge); |
1509 | | } |
1510 | | |
1511 | | // XXX to be removed |
1512 | | static bool IsAutoHeight(const nsStyleCoord &aCoord, nscoord aCBHeight) |
1513 | 0 | { |
1514 | 0 | return IsAutoBSize(aCoord, aCBHeight); |
1515 | 0 | } |
1516 | | |
1517 | | static bool IsAutoBSize(const nsStyleCoord &aCoord, nscoord aCBBSize) |
1518 | | { |
1519 | | nsStyleUnit unit = aCoord.GetUnit(); |
1520 | | return unit == eStyleUnit_Auto || // only for 'height' |
1521 | | unit == eStyleUnit_None || // only for 'max-height' |
1522 | | // The enumerated values were originally aimed at inline-size |
1523 | | // (or width, as it was before logicalization). For now, let them |
1524 | | // return true here, so that we don't call ComputeBSizeValue with |
1525 | | // value types that it doesn't understand. (See bug 1113216.) |
1526 | | // |
1527 | | // FIXME (bug 567039, bug 527285) |
1528 | | // This isn't correct for the 'fill' value or for the 'min-*' or |
1529 | | // 'max-*' properties, which need to be handled differently by |
1530 | | // the callers of IsAutoBSize(). |
1531 | | unit == eStyleUnit_Enumerated || |
1532 | | (aCBBSize == nscoord_MAX && aCoord.HasPercent()); |
1533 | | } |
1534 | | |
1535 | | static bool IsPaddingZero(const nsStyleCoord &aCoord) |
1536 | | { |
1537 | | return (aCoord.GetUnit() == eStyleUnit_Coord && |
1538 | | aCoord.GetCoordValue() == 0) || |
1539 | | (aCoord.GetUnit() == eStyleUnit_Percent && |
1540 | | aCoord.GetPercentValue() == 0.0f) || |
1541 | | (aCoord.IsCalcUnit() && |
1542 | | // clamp negative calc() to 0 |
1543 | | aCoord.ComputeCoordPercentCalc(nscoord_MAX) <= 0 && |
1544 | | aCoord.ComputeCoordPercentCalc(0) <= 0); |
1545 | | } |
1546 | | |
1547 | | static bool IsMarginZero(const nsStyleCoord &aCoord) |
1548 | | { |
1549 | | return (aCoord.GetUnit() == eStyleUnit_Coord && |
1550 | | aCoord.GetCoordValue() == 0) || |
1551 | | (aCoord.GetUnit() == eStyleUnit_Percent && |
1552 | | aCoord.GetPercentValue() == 0.0f) || |
1553 | | (aCoord.IsCalcUnit() && |
1554 | | aCoord.ComputeCoordPercentCalc(nscoord_MAX) == 0 && |
1555 | | aCoord.ComputeCoordPercentCalc(0) == 0); |
1556 | | } |
1557 | | |
1558 | | static void MarkDescendantsDirty(nsIFrame *aSubtreeRoot); |
1559 | | |
1560 | | static void MarkIntrinsicISizesDirtyIfDependentOnBSize(nsIFrame* aFrame); |
1561 | | |
1562 | | /* |
1563 | | * Calculate the used values for 'width' and 'height' when width |
1564 | | * and height are 'auto'. The tentWidth and tentHeight arguments should be |
1565 | | * the result of applying the rules for computing intrinsic sizes and ratios. |
1566 | | * as specified by CSS 2.1 sections 10.3.2 and 10.6.2 |
1567 | | */ |
1568 | | static nsSize ComputeAutoSizeWithIntrinsicDimensions(nscoord minWidth, nscoord minHeight, |
1569 | | nscoord maxWidth, nscoord maxHeight, |
1570 | | nscoord tentWidth, nscoord tentHeight); |
1571 | | |
1572 | | // Implement nsIFrame::GetPrefISize in terms of nsIFrame::AddInlinePrefISize |
1573 | | static nscoord PrefISizeFromInline(nsIFrame* aFrame, |
1574 | | gfxContext* aRenderingContext); |
1575 | | |
1576 | | // Implement nsIFrame::GetMinISize in terms of nsIFrame::AddInlineMinISize |
1577 | | static nscoord MinISizeFromInline(nsIFrame* aFrame, |
1578 | | gfxContext* aRenderingContext); |
1579 | | |
1580 | | // Get a suitable foreground color for painting aColor for aFrame. |
1581 | | static nscolor DarkenColorIfNeeded(nsIFrame* aFrame, nscolor aColor); |
1582 | | |
1583 | | // Get a suitable foreground color for painting aField for aFrame. |
1584 | | // Type of aFrame is made a template parameter because nsIFrame is not |
1585 | | // a complete type in the header. Type-safety is not harmed given that |
1586 | | // DarkenColorIfNeeded requires an nsIFrame pointer. |
1587 | | template<typename Frame, typename T, typename S> |
1588 | | static nscolor GetColor(Frame* aFrame, T S::* aField) { |
1589 | | nscolor color = aFrame->GetVisitedDependentColor(aField); |
1590 | | return DarkenColorIfNeeded(aFrame, color); |
1591 | | } |
1592 | | |
1593 | | // Get a baseline y position in app units that is snapped to device pixels. |
1594 | | static gfxFloat GetSnappedBaselineY(nsIFrame* aFrame, gfxContext* aContext, |
1595 | | nscoord aY, nscoord aAscent); |
1596 | | // Ditto for an x position (for vertical text). Note that for vertical-rl |
1597 | | // writing mode, the ascent value should be negated by the caller. |
1598 | | static gfxFloat GetSnappedBaselineX(nsIFrame* aFrame, gfxContext* aContext, |
1599 | | nscoord aX, nscoord aAscent); |
1600 | | |
1601 | | static nscoord AppUnitWidthOfString(char16_t aC, |
1602 | | nsFontMetrics& aFontMetrics, |
1603 | | DrawTarget* aDrawTarget) { |
1604 | | return AppUnitWidthOfString(&aC, 1, aFontMetrics, aDrawTarget); |
1605 | | } |
1606 | | static nscoord AppUnitWidthOfString(const nsString& aString, |
1607 | | nsFontMetrics& aFontMetrics, |
1608 | | DrawTarget* aDrawTarget) { |
1609 | | return nsLayoutUtils::AppUnitWidthOfString(aString.get(), aString.Length(), |
1610 | | aFontMetrics, aDrawTarget); |
1611 | | } |
1612 | | static nscoord AppUnitWidthOfString(const char16_t *aString, |
1613 | | uint32_t aLength, |
1614 | | nsFontMetrics& aFontMetrics, |
1615 | | DrawTarget* aDrawTarget); |
1616 | | static nscoord AppUnitWidthOfStringBidi(const nsString& aString, |
1617 | | const nsIFrame* aFrame, |
1618 | | nsFontMetrics& aFontMetrics, |
1619 | | gfxContext& aContext) { |
1620 | | return nsLayoutUtils::AppUnitWidthOfStringBidi(aString.get(), |
1621 | | aString.Length(), aFrame, |
1622 | | aFontMetrics, aContext); |
1623 | | } |
1624 | | static nscoord AppUnitWidthOfStringBidi(const char16_t* aString, |
1625 | | uint32_t aLength, |
1626 | | const nsIFrame* aFrame, |
1627 | | nsFontMetrics& aFontMetrics, |
1628 | | gfxContext& aContext); |
1629 | | |
1630 | | static bool StringWidthIsGreaterThan(const nsString& aString, |
1631 | | nsFontMetrics& aFontMetrics, |
1632 | | DrawTarget* aDrawTarget, |
1633 | | nscoord aWidth); |
1634 | | |
1635 | | static nsBoundingMetrics AppUnitBoundsOfString(const char16_t* aString, |
1636 | | uint32_t aLength, |
1637 | | nsFontMetrics& aFontMetrics, |
1638 | | DrawTarget* aDrawTarget); |
1639 | | |
1640 | | static void DrawString(const nsIFrame* aFrame, |
1641 | | nsFontMetrics& aFontMetrics, |
1642 | | gfxContext* aContext, |
1643 | | const char16_t* aString, |
1644 | | int32_t aLength, |
1645 | | nsPoint aPoint, |
1646 | | ComputedStyle* aComputedStyle = nullptr, |
1647 | | DrawStringFlags aFlags = DrawStringFlags::eDefault); |
1648 | | |
1649 | | static nsPoint GetBackgroundFirstTilePos(const nsPoint& aDest, |
1650 | | const nsPoint& aFill, |
1651 | | const nsSize& aRepeatSize); |
1652 | | |
1653 | | /** |
1654 | | * Supports only LTR or RTL. Bidi (mixed direction) is not supported. |
1655 | | */ |
1656 | | static void DrawUniDirString(const char16_t* aString, |
1657 | | uint32_t aLength, |
1658 | | const nsPoint& aPoint, |
1659 | | nsFontMetrics& aFontMetrics, |
1660 | | gfxContext& aContext); |
1661 | | |
1662 | | /** |
1663 | | * Helper function for drawing text-shadow. The callback's job |
1664 | | * is to draw whatever needs to be blurred onto the given context. |
1665 | | */ |
1666 | | typedef void (* TextShadowCallback)(gfxContext* aCtx, |
1667 | | nsPoint aShadowOffset, |
1668 | | const nscolor& aShadowColor, |
1669 | | void* aData); |
1670 | | |
1671 | | static void PaintTextShadow(const nsIFrame* aFrame, |
1672 | | gfxContext* aContext, |
1673 | | const nsRect& aTextRect, |
1674 | | const nsRect& aDirtyRect, |
1675 | | const nscolor& aForegroundColor, |
1676 | | TextShadowCallback aCallback, |
1677 | | void* aCallbackData); |
1678 | | |
1679 | | /** |
1680 | | * Gets the baseline to vertically center text from a font within a |
1681 | | * line of specified height. |
1682 | | * aIsInverted: true if the text is inverted relative to the block |
1683 | | * direction, so that the block-dir "ascent" corresponds to font |
1684 | | * descent. (Applies to sideways text in vertical-lr mode.) |
1685 | | * |
1686 | | * Returns the baseline position relative to the top of the line. |
1687 | | */ |
1688 | | static nscoord GetCenteredFontBaseline(nsFontMetrics* aFontMetrics, |
1689 | | nscoord aLineHeight, |
1690 | | bool aIsInverted); |
1691 | | |
1692 | | /** |
1693 | | * Derive a baseline of |aFrame| (measured from its top border edge) |
1694 | | * from its first in-flow line box (not descending into anything with |
1695 | | * 'overflow' not 'visible', potentially including aFrame itself). |
1696 | | * |
1697 | | * Returns true if a baseline was found (and fills in aResult). |
1698 | | * Otherwise returns false. |
1699 | | */ |
1700 | | static bool GetFirstLineBaseline(mozilla::WritingMode aWritingMode, |
1701 | | const nsIFrame* aFrame, nscoord* aResult); |
1702 | | |
1703 | | /** |
1704 | | * Just like GetFirstLineBaseline, except also returns the top and |
1705 | | * bottom of the line with the baseline. |
1706 | | * |
1707 | | * Returns true if a line was found (and fills in aResult). |
1708 | | * Otherwise returns false. |
1709 | | */ |
1710 | | struct LinePosition { |
1711 | | nscoord mBStart, mBaseline, mBEnd; |
1712 | | |
1713 | | LinePosition operator+(nscoord aOffset) const { |
1714 | | LinePosition result; |
1715 | | result.mBStart = mBStart + aOffset; |
1716 | | result.mBaseline = mBaseline + aOffset; |
1717 | | result.mBEnd = mBEnd + aOffset; |
1718 | | return result; |
1719 | | } |
1720 | | }; |
1721 | | static bool GetFirstLinePosition(mozilla::WritingMode aWritingMode, |
1722 | | const nsIFrame* aFrame, |
1723 | | LinePosition* aResult); |
1724 | | |
1725 | | |
1726 | | /** |
1727 | | * Derive a baseline of |aFrame| (measured from its top border edge) |
1728 | | * from its last in-flow line box (not descending into anything with |
1729 | | * 'overflow' not 'visible', potentially including aFrame itself). |
1730 | | * |
1731 | | * Returns true if a baseline was found (and fills in aResult). |
1732 | | * Otherwise returns false. |
1733 | | */ |
1734 | | static bool GetLastLineBaseline(mozilla::WritingMode aWritingMode, |
1735 | | const nsIFrame* aFrame, nscoord* aResult); |
1736 | | |
1737 | | /** |
1738 | | * Returns a block-dir coordinate relative to this frame's origin that |
1739 | | * represents the logical block-end of the frame or its visible content, |
1740 | | * whichever is further from the origin. |
1741 | | * Relative positioning is ignored and margins and glyph bounds are not |
1742 | | * considered. |
1743 | | * This value will be >= mRect.BSize() and <= overflowRect.BEnd() unless |
1744 | | * relative positioning is applied. |
1745 | | */ |
1746 | | static nscoord CalculateContentBEnd(mozilla::WritingMode aWritingMode, |
1747 | | nsIFrame* aFrame); |
1748 | | |
1749 | | /** |
1750 | | * Gets the closest frame (the frame passed in or one of its parents) that |
1751 | | * qualifies as a "layer"; used in DOM0 methods that depends upon that |
1752 | | * definition. This is the nearest frame that is either positioned or scrolled |
1753 | | * (the child of a scroll frame). |
1754 | | */ |
1755 | | static nsIFrame* GetClosestLayer(nsIFrame* aFrame); |
1756 | | |
1757 | | /** |
1758 | | * Gets the graphics sampling filter for the frame |
1759 | | */ |
1760 | | static SamplingFilter GetSamplingFilterForFrame(nsIFrame* aFrame); |
1761 | | |
1762 | | static inline void InitDashPattern(StrokeOptions& aStrokeOptions, |
1763 | | uint8_t aBorderStyle) { |
1764 | | if (aBorderStyle == NS_STYLE_BORDER_STYLE_DOTTED) { |
1765 | | static Float dot[] = { 1.f, 1.f }; |
1766 | | aStrokeOptions.mDashLength = MOZ_ARRAY_LENGTH(dot); |
1767 | | aStrokeOptions.mDashPattern = dot; |
1768 | | } else if (aBorderStyle == NS_STYLE_BORDER_STYLE_DASHED) { |
1769 | | static Float dash[] = { 5.f, 5.f }; |
1770 | | aStrokeOptions.mDashLength = MOZ_ARRAY_LENGTH(dash); |
1771 | | aStrokeOptions.mDashPattern = dash; |
1772 | | } else { |
1773 | | aStrokeOptions.mDashLength = 0; |
1774 | | aStrokeOptions.mDashPattern = nullptr; |
1775 | | } |
1776 | | } |
1777 | | |
1778 | | /** |
1779 | | * Convert an nsRect to a gfxRect. |
1780 | | */ |
1781 | | static gfxRect RectToGfxRect(const nsRect& aRect, |
1782 | | int32_t aAppUnitsPerDevPixel); |
1783 | | |
1784 | | static gfxPoint PointToGfxPoint(const nsPoint& aPoint, |
1785 | | int32_t aAppUnitsPerPixel) { |
1786 | | return gfxPoint(gfxFloat(aPoint.x) / aAppUnitsPerPixel, |
1787 | | gfxFloat(aPoint.y) / aAppUnitsPerPixel); |
1788 | | } |
1789 | | |
1790 | | /* N.B. The only difference between variants of the Draw*Image |
1791 | | * functions below is the type of the aImage argument. |
1792 | | */ |
1793 | | |
1794 | | /** |
1795 | | * Draw a background image. The image's dimensions are as specified in aDest; |
1796 | | * the image itself is not consulted to determine a size. |
1797 | | * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering |
1798 | | * @param aContext The context to draw to, already set up with an |
1799 | | * appropriate scale and transform for drawing in |
1800 | | * app units. |
1801 | | * @param aForFrame The nsIFrame that we're drawing this image for. |
1802 | | * @param aImage The image. |
1803 | | * @param aImageSize The unscaled size of the image being drawn. |
1804 | | * (This might be the image's size if no scaling |
1805 | | * occurs, or it might be the image's size if |
1806 | | * the image is a vector image being rendered at |
1807 | | * that size.) |
1808 | | * @param aDest The position and scaled area where one copy of |
1809 | | * the image should be drawn. This area represents |
1810 | | * the image itself in its correct position as defined |
1811 | | * with the background-position css property. |
1812 | | * @param aFill The area to be filled with copies of the image. |
1813 | | * @param aRepeatSize The distance between the positions of two subsequent |
1814 | | * repeats of the image. Sizes larger than aDest.Size() |
1815 | | * create gaps between the images. |
1816 | | * @param aAnchor A point in aFill which we will ensure is |
1817 | | * pixel-aligned in the output. |
1818 | | * @param aDirty Pixels outside this area may be skipped. |
1819 | | * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety. |
1820 | | * @param aExtendMode How to extend the image over the dest rect. |
1821 | | */ |
1822 | | static ImgDrawResult DrawBackgroundImage(gfxContext& aContext, |
1823 | | nsIFrame* aForFrame, |
1824 | | nsPresContext* aPresContext, |
1825 | | imgIContainer* aImage, |
1826 | | const CSSIntSize& aImageSize, |
1827 | | SamplingFilter aSamplingFilter, |
1828 | | const nsRect& aDest, |
1829 | | const nsRect& aFill, |
1830 | | const nsSize& aRepeatSize, |
1831 | | const nsPoint& aAnchor, |
1832 | | const nsRect& aDirty, |
1833 | | uint32_t aImageFlags, |
1834 | | ExtendMode aExtendMode, |
1835 | | float aOpacity); |
1836 | | |
1837 | | /** |
1838 | | * Draw an image. |
1839 | | * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering |
1840 | | * @param aRenderingContext Where to draw the image, set up with an |
1841 | | * appropriate scale and transform for drawing in |
1842 | | * app units. |
1843 | | * @param aComputedStyle The ComputedStyle of the nsIFrame (or |
1844 | | * pseudo-element) for which this image is being |
1845 | | * drawn. |
1846 | | * @param aImage The image. |
1847 | | * @param aDest Where one copy of the image should mapped to. |
1848 | | * @param aFill The area to be filled with copies of the |
1849 | | * image. |
1850 | | * @param aAnchor A point in aFill which we will ensure is |
1851 | | * pixel-aligned in the output. |
1852 | | * @param aDirty Pixels outside this area may be skipped. |
1853 | | * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety |
1854 | | */ |
1855 | | static ImgDrawResult DrawImage(gfxContext& aContext, |
1856 | | ComputedStyle* aComputedStyle, |
1857 | | nsPresContext* aPresContext, |
1858 | | imgIContainer* aImage, |
1859 | | const SamplingFilter aSamplingFilter, |
1860 | | const nsRect& aDest, |
1861 | | const nsRect& aFill, |
1862 | | const nsPoint& aAnchor, |
1863 | | const nsRect& aDirty, |
1864 | | uint32_t aImageFlags, |
1865 | | float aOpacity = 1.0); |
1866 | | |
1867 | | /** |
1868 | | * Draw a whole image without scaling or tiling. |
1869 | | * |
1870 | | * @param aRenderingContext Where to draw the image, set up with an |
1871 | | * appropriate scale and transform for drawing in |
1872 | | * app units. |
1873 | | * @param aImage The image. |
1874 | | * @param aDest The top-left where the image should be drawn. |
1875 | | * @param aDirty If non-null, then pixels outside this area may |
1876 | | * be skipped. |
1877 | | * @param aSVGContext Optionally provides an SVGImageContext. |
1878 | | * Callers should pass an SVGImageContext with at |
1879 | | * least the viewport size set if aImage may be of |
1880 | | * type imgIContainer::TYPE_VECTOR, or pass |
1881 | | * Nothing() if it is of type |
1882 | | * imgIContainer::TYPE_RASTER (to save cycles |
1883 | | * constructing an SVGImageContext, since this |
1884 | | * argument will be ignored for raster images). |
1885 | | * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety |
1886 | | * @param aSourceArea If non-null, this area is extracted from |
1887 | | * the image and drawn at aDest. It's |
1888 | | * in appunits. For best results it should |
1889 | | * be aligned with image pixels. |
1890 | | */ |
1891 | | static ImgDrawResult DrawSingleUnscaledImage(gfxContext& aContext, |
1892 | | nsPresContext* aPresContext, |
1893 | | imgIContainer* aImage, |
1894 | | const SamplingFilter aSamplingFilter, |
1895 | | const nsPoint& aDest, |
1896 | | const nsRect* aDirty, |
1897 | | const mozilla::Maybe<SVGImageContext>& aSVGContext, |
1898 | | uint32_t aImageFlags, |
1899 | | const nsRect* aSourceArea = nullptr); |
1900 | | |
1901 | | /** |
1902 | | * Draw a whole image without tiling. |
1903 | | * |
1904 | | * @param aRenderingContext Where to draw the image, set up with an |
1905 | | * appropriate scale and transform for drawing in |
1906 | | * app units. |
1907 | | * @param aImage The image. |
1908 | | * @param aDest The area that the image should fill. |
1909 | | * @param aDirty Pixels outside this area may be skipped. |
1910 | | * @param aSVGContext Optionally provides an SVGImageContext. |
1911 | | * Callers should pass an SVGImageContext with at |
1912 | | * least the viewport size set if aImage may be of |
1913 | | * type imgIContainer::TYPE_VECTOR, or pass |
1914 | | * Nothing() if it is of type |
1915 | | * imgIContainer::TYPE_RASTER (to save cycles |
1916 | | * constructing an SVGImageContext, since this |
1917 | | * argument will be ignored for raster images). |
1918 | | * @param aImageFlags Image flags of the imgIContainer::FLAG_* |
1919 | | * variety. |
1920 | | * @param aAnchor If non-null, a point which we will ensure |
1921 | | * is pixel-aligned in the output. |
1922 | | * @param aSourceArea If non-null, this area is extracted from |
1923 | | * the image and drawn in aDest. It's |
1924 | | * in appunits. For best results it should |
1925 | | * be aligned with image pixels. |
1926 | | */ |
1927 | | static ImgDrawResult DrawSingleImage(gfxContext& aContext, |
1928 | | nsPresContext* aPresContext, |
1929 | | imgIContainer* aImage, |
1930 | | const SamplingFilter aSamplingFilter, |
1931 | | const nsRect& aDest, |
1932 | | const nsRect& aDirty, |
1933 | | const mozilla::Maybe<SVGImageContext>& aSVGContext, |
1934 | | uint32_t aImageFlags, |
1935 | | const nsPoint* aAnchorPoint = nullptr, |
1936 | | const nsRect* aSourceArea = nullptr); |
1937 | | |
1938 | | /** |
1939 | | * Given an imgIContainer, this method attempts to obtain an intrinsic |
1940 | | * px-valued height & width for it. If the imgIContainer has a non-pixel |
1941 | | * value for either height or width, this method tries to generate a pixel |
1942 | | * value for that dimension using the intrinsic ratio (if available). The |
1943 | | * intrinsic ratio will be assigned to aIntrinsicRatio; if there's no |
1944 | | * intrinsic ratio then (0, 0) will be assigned. |
1945 | | * |
1946 | | * This method will always set aGotWidth and aGotHeight to indicate whether |
1947 | | * we were able to successfully obtain (or compute) a value for each |
1948 | | * dimension. |
1949 | | * |
1950 | | * NOTE: This method is similar to ComputeSizeWithIntrinsicDimensions. The |
1951 | | * difference is that this one is simpler and is suited to places where we |
1952 | | * have less information about the frame tree. |
1953 | | */ |
1954 | | static void ComputeSizeForDrawing(imgIContainer* aImage, |
1955 | | CSSIntSize& aImageSize, |
1956 | | nsSize& aIntrinsicRatio, |
1957 | | bool& aGotWidth, |
1958 | | bool& aGotHeight); |
1959 | | |
1960 | | /** |
1961 | | * Given an imgIContainer, this method attempts to obtain an intrinsic |
1962 | | * px-valued height & width for it. If the imgIContainer has a non-pixel |
1963 | | * value for either height or width, this method tries to generate a pixel |
1964 | | * value for that dimension using the intrinsic ratio (if available). If, |
1965 | | * after trying all these methods, no value is available for one or both |
1966 | | * dimensions, the corresponding dimension of aFallbackSize is used instead. |
1967 | | */ |
1968 | | static CSSIntSize |
1969 | | ComputeSizeForDrawingWithFallback(imgIContainer* aImage, |
1970 | | const nsSize& aFallbackSize); |
1971 | | |
1972 | | /** |
1973 | | * Given the image container, frame, and dest rect, determine the best fitting |
1974 | | * size to decode the image at, and calculate any necessary SVG parameters. |
1975 | | */ |
1976 | | static mozilla::gfx::IntSize |
1977 | | ComputeImageContainerDrawingParameters(imgIContainer* aImage, |
1978 | | nsIFrame* aForFrame, |
1979 | | const LayoutDeviceRect& aDestRect, |
1980 | | const StackingContextHelper& aSc, |
1981 | | uint32_t aFlags, |
1982 | | mozilla::Maybe<SVGImageContext>& aSVGContext); |
1983 | | |
1984 | | /** |
1985 | | * Given a source area of an image (in appunits) and a destination area |
1986 | | * that we want to map that source area too, computes the area that |
1987 | | * would be covered by the whole image. This is useful for passing to |
1988 | | * the aDest parameter of DrawImage, when we want to draw a subimage |
1989 | | * of an overall image. |
1990 | | */ |
1991 | | static nsRect GetWholeImageDestination(const nsSize& aWholeImageSize, |
1992 | | const nsRect& aImageSourceArea, |
1993 | | const nsRect& aDestArea); |
1994 | | |
1995 | | /** |
1996 | | * Given an image container and an orientation, returns an image container |
1997 | | * that contains the same image, reoriented appropriately. May return the |
1998 | | * original image container if no changes are needed. |
1999 | | * |
2000 | | * @param aContainer The image container to apply the orientation to. |
2001 | | * @param aOrientation The desired orientation. |
2002 | | */ |
2003 | | static already_AddRefed<imgIContainer> |
2004 | | OrientImage(imgIContainer* aContainer, |
2005 | | const mozilla::StyleImageOrientation& aOrientation); |
2006 | | |
2007 | | /** |
2008 | | * Determine if any corner radius is of nonzero size |
2009 | | * @param aCorners the |nsStyleCorners| object to check |
2010 | | * @return true unless all the coordinates are 0%, 0 or null. |
2011 | | * |
2012 | | * A corner radius with one dimension zero and one nonzero is |
2013 | | * treated as a nonzero-radius corner, even though it will end up |
2014 | | * being rendered like a zero-radius corner. This is because such |
2015 | | * corners are not expected to appear outside of test cases, and it's |
2016 | | * simpler to implement the test this way. |
2017 | | */ |
2018 | | static bool HasNonZeroCorner(const nsStyleCorners& aCorners); |
2019 | | |
2020 | | /** |
2021 | | * Determine if there is any corner radius on corners adjacent to the |
2022 | | * given side. |
2023 | | */ |
2024 | | static bool HasNonZeroCornerOnSide(const nsStyleCorners& aCorners, |
2025 | | mozilla::Side aSide); |
2026 | | |
2027 | | /** |
2028 | | * Determine if a widget is likely to require transparency or translucency. |
2029 | | * @param aBackgroundFrame The frame that the background is set on. For |
2030 | | * <window>s, this will be the canvas frame. |
2031 | | * @param aCSSRootFrame The frame that holds CSS properties affecting |
2032 | | * the widget's transparency. For menupopups, |
2033 | | * aBackgroundFrame and aCSSRootFrame will be the |
2034 | | * same. |
2035 | | * @return a value suitable for passing to SetWindowTranslucency. |
2036 | | */ |
2037 | | static nsTransparencyMode GetFrameTransparency(nsIFrame* aBackgroundFrame, |
2038 | | nsIFrame* aCSSRootFrame); |
2039 | | |
2040 | | /** |
2041 | | * A frame is a popup if it has its own floating window. Menus, panels |
2042 | | * and combobox dropdowns are popups. |
2043 | | */ |
2044 | | static bool IsPopup(const nsIFrame* aFrame); |
2045 | | |
2046 | | /** |
2047 | | * Find the nearest "display root". This is the nearest enclosing |
2048 | | * popup frame or the root prescontext's root frame. |
2049 | | */ |
2050 | | static nsIFrame* GetDisplayRootFrame(nsIFrame* aFrame); |
2051 | | |
2052 | | /** |
2053 | | * Get the reference frame that would be used when constructing a |
2054 | | * display item for this frame. Rather than using their own frame |
2055 | | * as a reference frame.) |
2056 | | * |
2057 | | * This duplicates some of the logic of GetDisplayRootFrame above and |
2058 | | * of nsDisplayListBuilder::FindReferenceFrameFor. |
2059 | | * |
2060 | | * If you have an nsDisplayListBuilder, you should get the reference |
2061 | | * frame from it instead of calling this. |
2062 | | */ |
2063 | | static nsIFrame* GetReferenceFrame(nsIFrame* aFrame); |
2064 | | |
2065 | | /** |
2066 | | * Get textrun construction flags determined by a given style; in particular |
2067 | | * some combination of: |
2068 | | * -- TEXT_DISABLE_OPTIONAL_LIGATURES if letter-spacing is in use |
2069 | | * -- TEXT_OPTIMIZE_SPEED if the text-rendering CSS property and font size |
2070 | | * and prefs indicate we should be optimizing for speed over quality |
2071 | | */ |
2072 | | static mozilla::gfx::ShapedTextFlags |
2073 | | GetTextRunFlagsForStyle(ComputedStyle* aComputedStyle, |
2074 | | nsPresContext* aPresContext, |
2075 | | const nsStyleFont* aStyleFont, |
2076 | | const nsStyleText* aStyleText, |
2077 | | nscoord aLetterSpacing); |
2078 | | |
2079 | | /** |
2080 | | * Get orientation flags for textrun construction. |
2081 | | */ |
2082 | | static mozilla::gfx::ShapedTextFlags |
2083 | | GetTextRunOrientFlagsForStyle(ComputedStyle* aComputedStyle); |
2084 | | |
2085 | | /** |
2086 | | * Takes two rectangles whose origins must be the same, and computes |
2087 | | * the difference between their union and their intersection as two |
2088 | | * rectangles. (This difference is a superset of the difference |
2089 | | * between the two rectangles.) |
2090 | | */ |
2091 | | static void GetRectDifferenceStrips(const nsRect& aR1, const nsRect& aR2, |
2092 | | nsRect* aHStrip, nsRect* aVStrip); |
2093 | | |
2094 | | /** |
2095 | | * Get a device context that can be used to get up-to-date device |
2096 | | * dimensions for the given window. For some reason, this is more |
2097 | | * complicated than it ought to be in multi-monitor situations. |
2098 | | */ |
2099 | | static nsDeviceContext* |
2100 | | GetDeviceContextForScreenInfo(nsPIDOMWindowOuter* aWindow); |
2101 | | |
2102 | | /** |
2103 | | * Some frames with 'position: fixed' (nsStyleDisplay::mPosition == |
2104 | | * NS_STYLE_POSITION_FIXED) are not really fixed positioned, since |
2105 | | * they're inside an element with -moz-transform. This function says |
2106 | | * whether such an element is a real fixed-pos element. |
2107 | | */ |
2108 | | static bool IsReallyFixedPos(const nsIFrame* aFrame); |
2109 | | |
2110 | | /** |
2111 | | * This function says whether `aFrame` would really be a fixed positioned |
2112 | | * frame if the frame was created with NS_STYLE_POSITION_FIXED. |
2113 | | * |
2114 | | * It is effectively the same as IsReallyFixedPos, but without asserting the |
2115 | | * position value. Use it only when you know what you're doing, like when |
2116 | | * tearing down the frame tree (where styles may have changed due to |
2117 | | * ::first-line reparenting and rule changes at the same time). |
2118 | | */ |
2119 | | static bool MayBeReallyFixedPos(const nsIFrame* aFrame); |
2120 | | |
2121 | | /** |
2122 | | * Obtain a SourceSurface from the given DOM element, if possible. |
2123 | | * This obtains the most natural surface from the element; that |
2124 | | * is, the one that can be obtained with the fewest conversions. |
2125 | | * |
2126 | | * The flags below can modify the behaviour of this function. The |
2127 | | * result is returned as a SurfaceFromElementResult struct, also |
2128 | | * defined below. |
2129 | | * |
2130 | | * Currently, this will do: |
2131 | | * - HTML Canvas elements: will return the underlying canvas surface |
2132 | | * - HTML Video elements: will return the current video frame |
2133 | | * - Image elements: will return the image |
2134 | | * |
2135 | | * The above results are modified by the below flags (copying, |
2136 | | * forcing image surface, etc.). |
2137 | | */ |
2138 | | |
2139 | | enum { |
2140 | | /* When creating a new surface, create an image surface */ |
2141 | | SFE_WANT_IMAGE_SURFACE = 1 << 0, |
2142 | | /* Whether to extract the first frame (as opposed to the |
2143 | | current frame) in the case that the element is an image. */ |
2144 | | SFE_WANT_FIRST_FRAME_IF_IMAGE = 1 << 1, |
2145 | | /* Whether we should skip colorspace/gamma conversion */ |
2146 | | SFE_NO_COLORSPACE_CONVERSION = 1 << 2, |
2147 | | /* Specifies that the caller wants either OPAQUE or NON_PREMULT mAlphaType, |
2148 | | if this is can be done efficiently. */ |
2149 | | SFE_PREFER_NO_PREMULTIPLY_ALPHA = 1 << 3, |
2150 | | /* Whether we should skip getting a surface for vector images and |
2151 | | return a DirectDrawInfo containing an imgIContainer instead. */ |
2152 | | SFE_NO_RASTERIZING_VECTORS = 1 << 4, |
2153 | | /* If image type is vector, the return surface size will same as |
2154 | | element size, not image's intrinsic size. */ |
2155 | | SFE_USE_ELEMENT_SIZE_IF_VECTOR = 1 << 5 |
2156 | | }; |
2157 | | |
2158 | | struct DirectDrawInfo { |
2159 | | /* imgIContainer to directly draw to a context */ |
2160 | | nsCOMPtr<imgIContainer> mImgContainer; |
2161 | | /* which frame to draw */ |
2162 | | uint32_t mWhichFrame; |
2163 | | /* imgIContainer flags to use when drawing */ |
2164 | | uint32_t mDrawingFlags; |
2165 | | }; |
2166 | | |
2167 | | struct SurfaceFromElementResult { |
2168 | | friend class mozilla::dom::CanvasRenderingContext2D; |
2169 | | friend class nsLayoutUtils; |
2170 | | |
2171 | | /* If SFEResult contains a valid surface, it either mLayersImage or mSourceSurface |
2172 | | * will be non-null, and GetSourceSurface() will not be null. |
2173 | | * |
2174 | | * For valid surfaces, mSourceSurface may be null if mLayersImage is non-null, but |
2175 | | * GetSourceSurface() will create mSourceSurface from mLayersImage when called. |
2176 | | */ |
2177 | | |
2178 | | /* Video elements (at least) often are already decoded as layers::Images. */ |
2179 | | RefPtr<mozilla::layers::Image> mLayersImage; |
2180 | | |
2181 | | protected: |
2182 | | /* GetSourceSurface() fills this and returns its non-null value if this SFEResult |
2183 | | * was successful. */ |
2184 | | RefPtr<mozilla::gfx::SourceSurface> mSourceSurface; |
2185 | | |
2186 | | public: |
2187 | | /* Contains info for drawing when there is no mSourceSurface. */ |
2188 | | DirectDrawInfo mDrawInfo; |
2189 | | |
2190 | | /* The size of the surface */ |
2191 | | mozilla::gfx::IntSize mSize; |
2192 | | /* The principal associated with the element whose surface was returned. |
2193 | | If there is a surface, this will never be null. */ |
2194 | | nsCOMPtr<nsIPrincipal> mPrincipal; |
2195 | | /* The image request, if the element is an nsIImageLoadingContent */ |
2196 | | nsCOMPtr<imgIRequest> mImageRequest; |
2197 | | /* Whether the element was "write only", that is, the bits should not be exposed to content */ |
2198 | | bool mIsWriteOnly; |
2199 | | /* Whether the element was still loading. Some consumers need to handle |
2200 | | this case specially. */ |
2201 | | bool mIsStillLoading; |
2202 | | /* Whether the element has a valid size. */ |
2203 | | bool mHasSize; |
2204 | | /* Whether the element used CORS when loading. */ |
2205 | | bool mCORSUsed; |
2206 | | |
2207 | | gfxAlphaType mAlphaType; |
2208 | | |
2209 | | // Methods: |
2210 | | |
2211 | | SurfaceFromElementResult(); |
2212 | | |
2213 | | // Gets mSourceSurface, or makes a SourceSurface from mLayersImage. |
2214 | | const RefPtr<mozilla::gfx::SourceSurface>& GetSourceSurface(); |
2215 | | }; |
2216 | | |
2217 | | // This function can be called on any thread. |
2218 | | static SurfaceFromElementResult |
2219 | | SurfaceFromOffscreenCanvas(mozilla::dom::OffscreenCanvas *aOffscreenCanvas, |
2220 | | uint32_t aSurfaceFlags, |
2221 | | RefPtr<DrawTarget>& aTarget); |
2222 | | static SurfaceFromElementResult |
2223 | | SurfaceFromOffscreenCanvas(mozilla::dom::OffscreenCanvas *aOffscreenCanvas, |
2224 | 0 | uint32_t aSurfaceFlags = 0) { |
2225 | 0 | RefPtr<DrawTarget> target = nullptr; |
2226 | 0 | return SurfaceFromOffscreenCanvas(aOffscreenCanvas, aSurfaceFlags, target); |
2227 | 0 | } |
2228 | | |
2229 | | static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::Element *aElement, |
2230 | | uint32_t aSurfaceFlags, |
2231 | | RefPtr<DrawTarget>& aTarget); |
2232 | | static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::Element *aElement, |
2233 | 0 | uint32_t aSurfaceFlags = 0) { |
2234 | 0 | RefPtr<DrawTarget> target = nullptr; |
2235 | 0 | return SurfaceFromElement(aElement, aSurfaceFlags, target); |
2236 | 0 | } |
2237 | | |
2238 | | // There are a bunch of callers of SurfaceFromElement. Just mark it as |
2239 | | MOZ_CAN_RUN_SCRIPT_BOUNDARY |
2240 | | static SurfaceFromElementResult SurfaceFromElement(nsIImageLoadingContent *aElement, |
2241 | | uint32_t aSurfaceFlags, |
2242 | | RefPtr<DrawTarget>& aTarget); |
2243 | | // Need an HTMLImageElement overload, because otherwise the |
2244 | | // nsIImageLoadingContent and mozilla::dom::Element overloads are ambiguous |
2245 | | // for HTMLImageElement. |
2246 | | static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::HTMLImageElement *aElement, |
2247 | | uint32_t aSurfaceFlags, |
2248 | | RefPtr<DrawTarget>& aTarget); |
2249 | | static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::HTMLCanvasElement *aElement, |
2250 | | uint32_t aSurfaceFlags, |
2251 | | RefPtr<DrawTarget>& aTarget); |
2252 | | static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::HTMLVideoElement *aElement, |
2253 | | uint32_t aSurfaceFlags, |
2254 | | RefPtr<DrawTarget>& aTarget); |
2255 | | |
2256 | | /** |
2257 | | * When the document is editable by contenteditable attribute of its root |
2258 | | * content or body content. |
2259 | | * |
2260 | | * Be aware, this returns nullptr if it's in designMode. |
2261 | | * |
2262 | | * For example: |
2263 | | * |
2264 | | * <html contenteditable="true"><body></body></html> |
2265 | | * returns the <html>. |
2266 | | * |
2267 | | * <html><body contenteditable="true"></body></html> |
2268 | | * <body contenteditable="true"></body> |
2269 | | * With these cases, this returns the <body>. |
2270 | | * NOTE: The latter case isn't created normally, however, it can be |
2271 | | * created by script with XHTML. |
2272 | | * |
2273 | | * <body><p contenteditable="true"></p></body> |
2274 | | * returns nullptr because <body> isn't editable. |
2275 | | */ |
2276 | | static mozilla::dom::Element* |
2277 | | GetEditableRootContentByContentEditable(nsIDocument* aDocument); |
2278 | | |
2279 | | static void AddExtraBackgroundItems(nsDisplayListBuilder& aBuilder, |
2280 | | nsDisplayList& aList, |
2281 | | nsIFrame* aFrame, |
2282 | | const nsRect& aCanvasArea, |
2283 | | const nsRegion& aVisibleRegion, |
2284 | | nscolor aBackstop); |
2285 | | |
2286 | | /** |
2287 | | * Returns true if the passed in prescontext needs the dark grey background |
2288 | | * that goes behind the page of a print preview presentation. |
2289 | | */ |
2290 | | static bool NeedsPrintPreviewBackground(nsPresContext* aPresContext); |
2291 | | |
2292 | | typedef nsClassHashtable<nsPtrHashKey<gfxFontEntry>, |
2293 | | mozilla::dom::InspectorFontFace> UsedFontFaceTable; |
2294 | | |
2295 | | /** |
2296 | | * Adds all font faces used in the frame tree starting from aFrame |
2297 | | * to the list aFontFaceList. |
2298 | | * aMaxRanges: maximum number of text ranges to record for each face. |
2299 | | */ |
2300 | | static nsresult GetFontFacesForFrames(nsIFrame* aFrame, |
2301 | | UsedFontFaceTable& aResult, |
2302 | | uint32_t aMaxRanges, |
2303 | | bool aSkipCollapsedWhitespace); |
2304 | | |
2305 | | /** |
2306 | | * Adds all font faces used within the specified range of text in aFrame, |
2307 | | * and optionally its continuations, to the list in aFontFaceList. |
2308 | | * Pass 0 and INT32_MAX for aStartOffset and aEndOffset to specify the |
2309 | | * entire text is to be considered. |
2310 | | * aMaxRanges: maximum number of text ranges to record for each face. |
2311 | | */ |
2312 | | static void GetFontFacesForText(nsIFrame* aFrame, |
2313 | | int32_t aStartOffset, |
2314 | | int32_t aEndOffset, |
2315 | | bool aFollowContinuations, |
2316 | | UsedFontFaceTable& aResult, |
2317 | | uint32_t aMaxRanges, |
2318 | | bool aSkipCollapsedWhitespace); |
2319 | | |
2320 | | /** |
2321 | | * Walks the frame tree starting at aFrame looking for textRuns. |
2322 | | * If |clear| is true, just clears the TEXT_RUN_MEMORY_ACCOUNTED flag |
2323 | | * on each textRun found (and |aMallocSizeOf| is not used). |
2324 | | * If |clear| is false, adds the storage used for each textRun to the |
2325 | | * total, and sets the TEXT_RUN_MEMORY_ACCOUNTED flag to avoid double- |
2326 | | * accounting. (Runs with this flag already set will be skipped.) |
2327 | | * Expected usage pattern is therefore to call twice: |
2328 | | * (void)SizeOfTextRunsForFrames(rootFrame, nullptr, true); |
2329 | | * total = SizeOfTextRunsForFrames(rootFrame, mallocSizeOf, false); |
2330 | | */ |
2331 | | static size_t SizeOfTextRunsForFrames(nsIFrame* aFrame, |
2332 | | mozilla::MallocSizeOf aMallocSizeOf, |
2333 | | bool clear); |
2334 | | |
2335 | | /** |
2336 | | * Returns true if the frame has any current CSS transitions. |
2337 | | * A current transition is any transition that has not yet finished playing |
2338 | | * including paused transitions. |
2339 | | */ |
2340 | | static bool HasCurrentTransitions(const nsIFrame* aFrame); |
2341 | | |
2342 | | /** |
2343 | | * Returns true if |aFrame| has an animation of |aProperty| regardless of |
2344 | | * whether the property is overridden by !important rule. |
2345 | | */ |
2346 | | static bool HasAnimationOfProperty(const nsIFrame* aFrame, |
2347 | | nsCSSPropertyID aProperty); |
2348 | | |
2349 | | /** |
2350 | | * Returns true if |aEffectSet| has an animation of |aProperty| regardless of |
2351 | | * whether the property is overridden by !important rule. |
2352 | | */ |
2353 | | static bool HasAnimationOfProperty(mozilla::EffectSet* aEffectSet, |
2354 | | nsCSSPropertyID aProperty); |
2355 | | |
2356 | | /** |
2357 | | * Returns true if |aFrame| has an animation of |aProperty| which is |
2358 | | * not overridden by !important rules. |
2359 | | */ |
2360 | | static bool HasEffectiveAnimation(const nsIFrame* aFrame, |
2361 | | nsCSSPropertyID aProperty); |
2362 | | |
2363 | | /** |
2364 | | * Checks if off-main-thread animations are enabled. |
2365 | | */ |
2366 | | static bool AreAsyncAnimationsEnabled(); |
2367 | | |
2368 | | /** |
2369 | | * Checks if we should warn about animations that can't be async |
2370 | | */ |
2371 | | static bool IsAnimationLoggingEnabled(); |
2372 | | |
2373 | | /** |
2374 | | * Checks if retained display lists are enabled. |
2375 | | */ |
2376 | | static bool AreRetainedDisplayListsEnabled(); |
2377 | | |
2378 | | static bool DisplayRootHasRetainedDisplayListBuilder(nsIFrame* aFrame); |
2379 | | |
2380 | | /** |
2381 | | * Find a suitable scale for a element (aFrame's content) over the course of any |
2382 | | * animations and transitions of the CSS transform property on the |
2383 | | * element that run on the compositor thread. |
2384 | | * It will check the maximum and minimum scale during the animations and |
2385 | | * transitions and return a suitable value for performance and quality. |
2386 | | * Will return scale(1,1) if there are no such animations. |
2387 | | * Always returns a positive value. |
2388 | | * @param aVisibleSize is the size of the area we want to paint |
2389 | | * @param aDisplaySize is the size of the display area of the pres context |
2390 | | */ |
2391 | | static Size ComputeSuitableScaleForAnimation(const nsIFrame* aFrame, |
2392 | | const nsSize& aVisibleSize, |
2393 | | const nsSize& aDisplaySize); |
2394 | | |
2395 | | /** |
2396 | | * Checks whether we want to use the GPU to scale images when |
2397 | | * possible. |
2398 | | */ |
2399 | | static bool GPUImageScalingEnabled(); |
2400 | | |
2401 | | /** |
2402 | | * Checks whether we want to layerize animated images whenever possible. |
2403 | | */ |
2404 | | static bool AnimatedImageLayersEnabled(); |
2405 | | |
2406 | | /** |
2407 | | * Checks whether support for inter-character ruby is enabled. |
2408 | | */ |
2409 | | static bool IsInterCharacterRubyEnabled(); |
2410 | | |
2411 | | /** |
2412 | | * Checks whether content-select is enabled. |
2413 | | */ |
2414 | | static bool IsContentSelectEnabled(); |
2415 | | |
2416 | | static bool InterruptibleReflowEnabled() |
2417 | | { |
2418 | | return sInterruptibleReflowEnabled; |
2419 | | } |
2420 | | |
2421 | | /** |
2422 | | * Unions the overflow areas of the children of aFrame with aOverflowAreas. |
2423 | | * aSkipChildLists specifies any child lists that should be skipped. |
2424 | | * kSelectPopupList and kPopupList are always skipped. |
2425 | | */ |
2426 | | static void UnionChildOverflow(nsIFrame* aFrame, |
2427 | | nsOverflowAreas& aOverflowAreas, |
2428 | | mozilla::layout::FrameChildListIDs aSkipChildLists = |
2429 | | mozilla::layout::FrameChildListIDs()); |
2430 | | |
2431 | | /** |
2432 | | * Return the font size inflation *ratio* for a given frame. This is |
2433 | | * the factor by which font sizes should be inflated; it is never |
2434 | | * smaller than 1. |
2435 | | */ |
2436 | | static float FontSizeInflationFor(const nsIFrame *aFrame); |
2437 | | |
2438 | | /** |
2439 | | * Perform the first half of the computation of FontSizeInflationFor |
2440 | | * (see above). |
2441 | | * This includes determining whether inflation should be performed |
2442 | | * within this container and returning 0 if it should not be. |
2443 | | * |
2444 | | * The result is guaranteed not to vary between line participants |
2445 | | * (inlines, text frames) within a line. |
2446 | | * |
2447 | | * The result should not be used directly since font sizes slightly |
2448 | | * above the minimum should always be adjusted as done by |
2449 | | * FontSizeInflationInner. |
2450 | | */ |
2451 | | static nscoord InflationMinFontSizeFor(const nsIFrame *aFrame); |
2452 | | |
2453 | | /** |
2454 | | * Perform the second half of the computation done by |
2455 | | * FontSizeInflationFor (see above). |
2456 | | * |
2457 | | * aMinFontSize must be the result of one of the |
2458 | | * InflationMinFontSizeFor methods above. |
2459 | | */ |
2460 | | static float FontSizeInflationInner(const nsIFrame *aFrame, |
2461 | | nscoord aMinFontSize); |
2462 | | |
2463 | | static bool FontSizeInflationEnabled(nsPresContext *aPresContext); |
2464 | | |
2465 | | /** |
2466 | | * See comment above "font.size.inflation.maxRatio" in |
2467 | | * modules/libpref/src/init/all.js . |
2468 | | */ |
2469 | | static uint32_t FontSizeInflationMaxRatio() { |
2470 | | return sFontSizeInflationMaxRatio; |
2471 | | } |
2472 | | |
2473 | | /** |
2474 | | * See comment above "font.size.inflation.emPerLine" in |
2475 | | * modules/libpref/src/init/all.js . |
2476 | | */ |
2477 | | static uint32_t FontSizeInflationEmPerLine() { |
2478 | | return sFontSizeInflationEmPerLine; |
2479 | | } |
2480 | | |
2481 | | /** |
2482 | | * See comment above "font.size.inflation.minTwips" in |
2483 | | * modules/libpref/src/init/all.js . |
2484 | | */ |
2485 | | static uint32_t FontSizeInflationMinTwips() { |
2486 | | return sFontSizeInflationMinTwips; |
2487 | | } |
2488 | | |
2489 | | /** |
2490 | | * See comment above "font.size.inflation.lineThreshold" in |
2491 | | * modules/libpref/src/init/all.js . |
2492 | | */ |
2493 | | static uint32_t FontSizeInflationLineThreshold() { |
2494 | | return sFontSizeInflationLineThreshold; |
2495 | | } |
2496 | | |
2497 | | static bool FontSizeInflationForceEnabled() { |
2498 | | return sFontSizeInflationForceEnabled; |
2499 | | } |
2500 | | |
2501 | | static bool FontSizeInflationDisabledInMasterProcess() { |
2502 | | return sFontSizeInflationDisabledInMasterProcess; |
2503 | | } |
2504 | | |
2505 | | /** |
2506 | | * See comment above "font.size.systemFontScale" in |
2507 | | * modules/libpref/init/all.js. |
2508 | | */ |
2509 | | static float SystemFontScale() { |
2510 | | return sSystemFontScale / 100.0f; |
2511 | | } |
2512 | | |
2513 | | static float MaxZoom() { |
2514 | | return sZoomMaxPercent / 100.0f; |
2515 | | } |
2516 | | |
2517 | | static float MinZoom() { |
2518 | | return sZoomMinPercent / 100.0f; |
2519 | | } |
2520 | | |
2521 | 0 | static bool SVGTransformBoxEnabled() { |
2522 | 0 | return sSVGTransformBoxEnabled; |
2523 | 0 | } |
2524 | | |
2525 | | static uint32_t IdlePeriodDeadlineLimit() { |
2526 | | return sIdlePeriodDeadlineLimit; |
2527 | | } |
2528 | | |
2529 | | static uint32_t QuiescentFramesBeforeIdlePeriod() { |
2530 | | return sQuiescentFramesBeforeIdlePeriod; |
2531 | | } |
2532 | | |
2533 | | /** |
2534 | | * See comment above "font.size.inflation.mappingIntercept" in |
2535 | | * modules/libpref/src/init/all.js . |
2536 | | */ |
2537 | | static int32_t FontSizeInflationMappingIntercept() { |
2538 | | return sFontSizeInflationMappingIntercept; |
2539 | | } |
2540 | | |
2541 | | /** |
2542 | | * Returns true if the nglayout.debug.invalidation pref is set to true. |
2543 | | * Note that sInvalidationDebuggingIsEnabled is declared outside this function to |
2544 | | * allow it to be accessed an manipulated from breakpoint conditions. |
2545 | | */ |
2546 | 0 | static bool InvalidationDebuggingIsEnabled() { |
2547 | 0 | return sInvalidationDebuggingIsEnabled || getenv("MOZ_DUMP_INVALIDATION") != 0; |
2548 | 0 | } |
2549 | | |
2550 | | static void Initialize(); |
2551 | | static void Shutdown(); |
2552 | | |
2553 | | /** |
2554 | | * Register an imgIRequest object with a refresh driver. |
2555 | | * |
2556 | | * @param aPresContext The nsPresContext whose refresh driver we want to |
2557 | | * register with. |
2558 | | * @param aRequest A pointer to the imgIRequest object which the client wants |
2559 | | * to register with the refresh driver. |
2560 | | * @param aRequestRegistered A pointer to a boolean value which indicates |
2561 | | * whether the given image request is registered. If |
2562 | | * *aRequestRegistered is true, then this request will not be |
2563 | | * registered again. If the request is registered by this function, |
2564 | | * then *aRequestRegistered will be set to true upon the completion of |
2565 | | * this function. |
2566 | | * |
2567 | | */ |
2568 | | static void RegisterImageRequest(nsPresContext* aPresContext, |
2569 | | imgIRequest* aRequest, |
2570 | | bool* aRequestRegistered); |
2571 | | |
2572 | | /** |
2573 | | * Register an imgIRequest object with a refresh driver, but only if the |
2574 | | * request is for an image that is animated. |
2575 | | * |
2576 | | * @param aPresContext The nsPresContext whose refresh driver we want to |
2577 | | * register with. |
2578 | | * @param aRequest A pointer to the imgIRequest object which the client wants |
2579 | | * to register with the refresh driver. |
2580 | | * @param aRequestRegistered A pointer to a boolean value which indicates |
2581 | | * whether the given image request is registered. If |
2582 | | * *aRequestRegistered is true, then this request will not be |
2583 | | * registered again. If the request is registered by this function, |
2584 | | * then *aRequestRegistered will be set to true upon the completion of |
2585 | | * this function. |
2586 | | * |
2587 | | */ |
2588 | | static void RegisterImageRequestIfAnimated(nsPresContext* aPresContext, |
2589 | | imgIRequest* aRequest, |
2590 | | bool* aRequestRegistered); |
2591 | | |
2592 | | /** |
2593 | | * Deregister an imgIRequest object from a refresh driver. |
2594 | | * |
2595 | | * @param aPresContext The nsPresContext whose refresh driver we want to |
2596 | | * deregister from. |
2597 | | * @param aRequest A pointer to the imgIRequest object with which the client |
2598 | | * previously registered and now wants to deregister from the refresh |
2599 | | * driver. |
2600 | | * @param aRequestRegistered A pointer to a boolean value which indicates |
2601 | | * whether the given image request is registered. If |
2602 | | * *aRequestRegistered is false, then this request will not be |
2603 | | * deregistered. If the request is deregistered by this function, |
2604 | | * then *aRequestRegistered will be set to false upon the completion of |
2605 | | * this function. |
2606 | | */ |
2607 | | static void DeregisterImageRequest(nsPresContext* aPresContext, |
2608 | | imgIRequest* aRequest, |
2609 | | bool* aRequestRegistered); |
2610 | | |
2611 | | /** |
2612 | | * Shim to nsCSSFrameConstructor::PostRestyleEvent. Exists so that we |
2613 | | * can avoid including nsCSSFrameConstructor.h and all its dependencies |
2614 | | * in content files. |
2615 | | */ |
2616 | | static void PostRestyleEvent(mozilla::dom::Element* aElement, |
2617 | | nsRestyleHint aRestyleHint, |
2618 | | nsChangeHint aMinChangeHint); |
2619 | | |
2620 | | /** |
2621 | | * Updates a pair of x and y distances if a given point is closer to a given |
2622 | | * rectangle than the original distance values. If aPoint is closer to |
2623 | | * aRect than aClosestXDistance and aClosestYDistance indicate, then those |
2624 | | * two variables are updated with the distance between aPoint and aRect, |
2625 | | * and true is returned. If aPoint is not closer, then aClosestXDistance |
2626 | | * and aClosestYDistance are left unchanged, and false is returned. |
2627 | | * |
2628 | | * Distances are measured in the two dimensions separately; a closer x |
2629 | | * distance beats a closer y distance. |
2630 | | */ |
2631 | | template<typename PointType, typename RectType, typename CoordType> |
2632 | | static bool PointIsCloserToRect(PointType aPoint, const RectType& aRect, |
2633 | | CoordType& aClosestXDistance, |
2634 | | CoordType& aClosestYDistance); |
2635 | | /** |
2636 | | * Computes the box shadow rect for the frame, or returns an empty rect if |
2637 | | * there are no shadows. |
2638 | | * |
2639 | | * @param aFrame Frame to compute shadows for. |
2640 | | * @param aFrameSize Size of aFrame (in case it hasn't been set yet). |
2641 | | */ |
2642 | | static nsRect GetBoxShadowRectForFrame(nsIFrame* aFrame, const nsSize& aFrameSize); |
2643 | | |
2644 | | #ifdef DEBUG |
2645 | | /** |
2646 | | * Assert that there are no duplicate continuations of the same frame |
2647 | | * within aFrameList. Optimize the tests by assuming that all frames |
2648 | | * in aFrameList have parent aContainer. |
2649 | | */ |
2650 | | static void |
2651 | | AssertNoDuplicateContinuations(nsIFrame* aContainer, |
2652 | | const nsFrameList& aFrameList); |
2653 | | |
2654 | | /** |
2655 | | * Assert that the frame tree rooted at |aSubtreeRoot| is empty, i.e., |
2656 | | * that it contains no first-in-flows. |
2657 | | */ |
2658 | | static void |
2659 | | AssertTreeOnlyEmptyNextInFlows(nsIFrame *aSubtreeRoot); |
2660 | | #endif |
2661 | | |
2662 | | /** |
2663 | | * Helper method to get touch action behaviour from the frame |
2664 | | */ |
2665 | | static uint32_t |
2666 | | GetTouchActionFromFrame(nsIFrame* aFrame); |
2667 | | |
2668 | | /** |
2669 | | * Helper method to transform |aBounds| from aFrame to aAncestorFrame, |
2670 | | * and combine it with |aPreciseTargetDest| if it is axis-aligned, or |
2671 | | * combine it with |aImpreciseTargetDest| if not. The transformed rect is |
2672 | | * clipped to |aClip|; if |aClip| has rounded corners, that also causes |
2673 | | * the imprecise target to be used. |
2674 | | */ |
2675 | | static void |
2676 | | TransformToAncestorAndCombineRegions( |
2677 | | const nsRegion& aRegion, |
2678 | | nsIFrame* aFrame, |
2679 | | const nsIFrame* aAncestorFrame, |
2680 | | nsRegion* aPreciseTargetDest, |
2681 | | nsRegion* aImpreciseTargetDest, |
2682 | | mozilla::Maybe<Matrix4x4Flagged>* aMatrixCache, |
2683 | | const mozilla::DisplayItemClip* aClip); |
2684 | | |
2685 | | /** |
2686 | | * Populate aOutSize with the size of the content viewer corresponding |
2687 | | * to the given prescontext. Return true if the size was set, false |
2688 | | * otherwise. |
2689 | | */ |
2690 | | static bool |
2691 | | GetContentViewerSize(nsPresContext* aPresContext, |
2692 | | LayoutDeviceIntSize& aOutSize); |
2693 | | |
2694 | | /** |
2695 | | * Calculate the compostion size for a frame. See FrameMetrics.h for |
2696 | | * defintion of composition size (or bounds). |
2697 | | * Note that for the root content document's root scroll frame (RCD-RSF), |
2698 | | * the returned size does not change as the document's resolution changes, |
2699 | | * but for all other frames it does. This means that callers that pass in |
2700 | | * a frame that may or may not be the RCD-RSF (which is most callers), |
2701 | | * are likely to need special-case handling of the RCD-RSF. |
2702 | | */ |
2703 | | static nsSize |
2704 | | CalculateCompositionSizeForFrame(nsIFrame* aFrame, bool aSubtractScrollbars = true); |
2705 | | |
2706 | | /** |
2707 | | * Calculate the composition size for the root scroll frame of the root |
2708 | | * content document. |
2709 | | * @param aFrame A frame in the root content document (or a descendant of it). |
2710 | | * @param aIsRootContentDocRootScrollFrame Whether aFrame is already the root |
2711 | | * scroll frame of the root content document. In this case we just |
2712 | | * use aFrame's own composition size. |
2713 | | * @param aMetrics A partially populated FrameMetrics for aFrame. Must have at |
2714 | | * least mCompositionBounds, mCumulativeResolution, and |
2715 | | * mDevPixelsPerCSSPixel set. |
2716 | | */ |
2717 | | static CSSSize |
2718 | | CalculateRootCompositionSize(nsIFrame* aFrame, |
2719 | | bool aIsRootContentDocRootScrollFrame, |
2720 | | const FrameMetrics& aMetrics); |
2721 | | |
2722 | | /** |
2723 | | * Calculate the scrollable rect for a frame. See FrameMetrics.h for |
2724 | | * defintion of scrollable rect. aScrollableFrame is the scroll frame to calculate |
2725 | | * the scrollable rect for. If it's null then we calculate the scrollable rect |
2726 | | * as the rect of the root frame. |
2727 | | */ |
2728 | | static nsRect |
2729 | | CalculateScrollableRectForFrame(nsIScrollableFrame* aScrollableFrame, nsIFrame* aRootFrame); |
2730 | | |
2731 | | /** |
2732 | | * Calculate the expanded scrollable rect for a frame. See FrameMetrics.h for |
2733 | | * defintion of expanded scrollable rect. |
2734 | | */ |
2735 | | static nsRect |
2736 | | CalculateExpandedScrollableRect(nsIFrame* aFrame); |
2737 | | |
2738 | | /** |
2739 | | * Returns true if the widget owning the given frame uses asynchronous |
2740 | | * scrolling. |
2741 | | */ |
2742 | | static bool UsesAsyncScrolling(nsIFrame* aFrame); |
2743 | | |
2744 | | /** |
2745 | | * Returns true if the widget owning the given frame has builtin APZ support |
2746 | | * enabled. |
2747 | | */ |
2748 | | static bool AsyncPanZoomEnabled(nsIFrame* aFrame); |
2749 | | |
2750 | | /** |
2751 | | * Returns the current APZ Resolution Scale. When Java Pan/Zoom is |
2752 | | * enabled in Fennec it will always return 1.0. |
2753 | | */ |
2754 | | static float GetCurrentAPZResolutionScale(nsIPresShell* aShell); |
2755 | | |
2756 | | /** |
2757 | | * Returns true if we need to disable async scrolling for this particular |
2758 | | * element. Note that this does a partial disabling - the displayport still |
2759 | | * exists but uses a very small margin, and the compositor doesn't apply the |
2760 | | * async transform. However, the content may still be layerized. |
2761 | | */ |
2762 | | static bool ShouldDisableApzForElement(nsIContent* aContent); |
2763 | | |
2764 | | /** |
2765 | | * Log a key/value pair for APZ testing during a paint. |
2766 | | * @param aManager The data will be written to the APZTestData associated |
2767 | | * with this layer manager. |
2768 | | * @param aScrollId Identifies the scroll frame to which the data pertains. |
2769 | | * @param aKey The key under which to log the data. |
2770 | | * @param aValue The value of the data to be logged. |
2771 | | */ |
2772 | | static void LogTestDataForPaint(mozilla::layers::LayerManager* aManager, |
2773 | | ViewID aScrollId, |
2774 | | const std::string& aKey, |
2775 | 0 | const std::string& aValue) { |
2776 | 0 | DoLogTestDataForPaint(aManager, aScrollId, aKey, aValue); |
2777 | 0 | } |
2778 | | |
2779 | | /** |
2780 | | * A convenience overload of LogTestDataForPaint() that accepts any type |
2781 | | * as the value, and passes it through mozilla::ToString() to obtain a string |
2782 | | * value. The type passed must support streaming to an std::ostream. |
2783 | | */ |
2784 | | template <typename Value> |
2785 | | static void LogTestDataForPaint(mozilla::layers::LayerManager* aManager, |
2786 | | ViewID aScrollId, |
2787 | | const std::string& aKey, |
2788 | | const Value& aValue) { |
2789 | | DoLogTestDataForPaint(aManager, aScrollId, aKey, |
2790 | | mozilla::ToString(aValue)); |
2791 | | } |
2792 | | |
2793 | | /** |
2794 | | * Calculate a basic FrameMetrics with enough fields set to perform some |
2795 | | * layout calculations. The fields set are dev-to-css ratio, pres shell |
2796 | | * resolution, cumulative resolution, zoom, composition size, root |
2797 | | * composition size, scroll offset and scrollable rect. |
2798 | | * |
2799 | | * Note that for the RCD-RSF, the scroll offset returned is the layout |
2800 | | * viewport offset; if you need the visual viewport offset, that needs to |
2801 | | * be queried independently via nsIPresShell::GetVisualViewportOffset(). |
2802 | | * |
2803 | | * By contrast, ComputeFrameMetrics() computes all the fields, but requires |
2804 | | * extra inputs and can only be called during frame layer building. |
2805 | | */ |
2806 | | static FrameMetrics CalculateBasicFrameMetrics(nsIScrollableFrame* aScrollFrame); |
2807 | | |
2808 | | /** |
2809 | | * Calculate a default set of displayport margins for the given scrollframe |
2810 | | * and set them on the scrollframe's content element. The margins are set with |
2811 | | * the default priority, which may clobber previously set margins. The repaint |
2812 | | * mode provided is passed through to the call to SetDisplayPortMargins. |
2813 | | * The |aScrollFrame| parameter must be non-null and queryable to an nsIFrame. |
2814 | | * @return true iff the call to SetDisplayPortMargins returned true. |
2815 | | */ |
2816 | | static bool CalculateAndSetDisplayPortMargins(nsIScrollableFrame* aScrollFrame, |
2817 | | RepaintMode aRepaintMode); |
2818 | | |
2819 | | /** |
2820 | | * If |aScrollFrame| WantsAsyncScroll() and we don't have a scrollable |
2821 | | * displayport yet (as tracked by |aBuilder|), calculate and set a |
2822 | | * displayport. |
2823 | | * |
2824 | | * If this is called during display list building pass DoNotRepaint in |
2825 | | * aRepaintMode. |
2826 | | * |
2827 | | * Returns true if there is a displayport on an async scrollable scrollframe |
2828 | | * after this call, either because one was just added or it already existed. |
2829 | | */ |
2830 | | static bool MaybeCreateDisplayPort(nsDisplayListBuilder& aBuilder, |
2831 | | nsIFrame* aScrollFrame, |
2832 | | RepaintMode aRepaintMode); |
2833 | | |
2834 | | static nsIScrollableFrame* GetAsyncScrollableAncestorFrame(nsIFrame* aTarget); |
2835 | | |
2836 | | /** |
2837 | | * Sets a zero margin display port on all proper ancestors of aFrame that |
2838 | | * are async scrollable. |
2839 | | */ |
2840 | | static void SetZeroMarginDisplayPortOnAsyncScrollableAncestors(nsIFrame* aFrame, |
2841 | | RepaintMode aRepaintMode); |
2842 | | /** |
2843 | | * Finds the closest ancestor async scrollable frame from aFrame that has a |
2844 | | * displayport and attempts to trigger the displayport expiry on that |
2845 | | * ancestor. |
2846 | | */ |
2847 | | static void ExpireDisplayPortOnAsyncScrollableAncestor(nsIFrame* aFrame); |
2848 | | |
2849 | | static bool IsOutlineStyleAutoEnabled(); |
2850 | | |
2851 | | static void SetBSizeFromFontMetrics(const nsIFrame* aFrame, |
2852 | | mozilla::ReflowOutput& aMetrics, |
2853 | | const mozilla::LogicalMargin& aFramePadding, |
2854 | | mozilla::WritingMode aLineWM, |
2855 | | mozilla::WritingMode aFrameWM); |
2856 | | |
2857 | | static bool HasDocumentLevelListenersForApzAwareEvents(nsIPresShell* aShell); |
2858 | | |
2859 | | /** |
2860 | | * Set the viewport size for the purpose of clamping the scroll position |
2861 | | * for the root scroll frame of this document |
2862 | | * (see nsIDOMWindowUtils.setVisualViewportSize). |
2863 | | */ |
2864 | | static void SetVisualViewportSize(nsIPresShell* aPresShell, |
2865 | | CSSSize aSize); |
2866 | | |
2867 | | /** |
2868 | | * Returns true if the given scroll origin is "higher priority" than APZ. |
2869 | | * In general any content programmatic scrolls (e.g. scrollTo calls) are |
2870 | | * higher priority, and take precedence over APZ scrolling. This function |
2871 | | * returns true for those, and returns false for other origins like APZ |
2872 | | * itself, or scroll position updates from the history restore code. |
2873 | | */ |
2874 | | static bool CanScrollOriginClobberApz(nsAtom* aScrollOrigin); |
2875 | | |
2876 | | static ScrollMetadata ComputeScrollMetadata(nsIFrame* aForFrame, |
2877 | | nsIFrame* aScrollFrame, |
2878 | | nsIContent* aContent, |
2879 | | const nsIFrame* aReferenceFrame, |
2880 | | mozilla::layers::LayerManager* aLayerManager, |
2881 | | ViewID aScrollParentId, |
2882 | | const nsRect& aViewport, |
2883 | | const mozilla::Maybe<nsRect>& aClipRect, |
2884 | | bool aIsRoot, |
2885 | | const ContainerLayerParameters& aContainerParameters); |
2886 | | |
2887 | | /** |
2888 | | * Returns the metadata to put onto the root layer of a layer tree, if one is |
2889 | | * needed. The last argument is a callback function to check if the caller |
2890 | | * already has a metadata for a given scroll id. |
2891 | | */ |
2892 | | static mozilla::Maybe<ScrollMetadata> GetRootMetadata(nsDisplayListBuilder* aBuilder, |
2893 | | mozilla::layers::LayerManager* aLayerManager, |
2894 | | const ContainerLayerParameters& aContainerParameters, |
2895 | | const std::function<bool(ViewID& aScrollId)>& aCallback); |
2896 | | |
2897 | | /** |
2898 | | * If the given scroll frame needs an area excluded from its composition |
2899 | | * bounds due to scrollbars, return that area, otherwise return an empty |
2900 | | * margin. |
2901 | | * There is no need to exclude scrollbars in the following cases: |
2902 | | * - If the scroll frame is not the RCD-RSF; in that case, the composition |
2903 | | * bounds is calculated based on the scroll port which already excludes |
2904 | | * the scrollbar area. |
2905 | | * - If the scrollbars are overlay, since then they are drawn on top of the |
2906 | | * scrollable content. |
2907 | | */ |
2908 | | static nsMargin ScrollbarAreaToExcludeFromCompositionBoundsFor(nsIFrame* aScrollFrame); |
2909 | | |
2910 | | /** |
2911 | | * Looks in the layer subtree rooted at aLayer for a metrics with scroll id |
2912 | | * aScrollId. Returns true if such is found. |
2913 | | */ |
2914 | | static bool ContainsMetricsWithId(const Layer* aLayer, const ViewID& aScrollId); |
2915 | | |
2916 | | static bool ShouldUseNoScriptSheet(nsIDocument* aDocument); |
2917 | | static bool ShouldUseNoFramesSheet(nsIDocument* aDocument); |
2918 | | |
2919 | | /** |
2920 | | * Get the text content inside the frame. This methods traverse the |
2921 | | * frame tree and collect the content from text frames. Note that this |
2922 | | * method is similiar to nsContentUtils::GetNodeTextContent, but it at |
2923 | | * least differs from that method in the following things: |
2924 | | * 1. it skips text content inside nodes like style, script, textarea |
2925 | | * which don't generate an in-tree text frame for the text; |
2926 | | * 2. it skips elements with display property set to none; |
2927 | | * 3. it skips out-of-flow elements; |
2928 | | * 4. it includes content inside pseudo elements; |
2929 | | * 5. it may include part of text content of a node if a text frame |
2930 | | * inside is split to different continuations. |
2931 | | */ |
2932 | | static void GetFrameTextContent(nsIFrame* aFrame, nsAString& aResult); |
2933 | | |
2934 | | /** |
2935 | | * Same as GetFrameTextContent but appends the result rather than sets it. |
2936 | | */ |
2937 | | static void AppendFrameTextContent(nsIFrame* aFrame, nsAString& aResult); |
2938 | | |
2939 | | /** |
2940 | | * Takes a selection, and returns selection's bounding rect which is relative |
2941 | | * to its root frame. |
2942 | | * |
2943 | | * @param aSel Selection to check |
2944 | | */ |
2945 | | static nsRect GetSelectionBoundingRect(mozilla::dom::Selection* aSel); |
2946 | | |
2947 | | /** |
2948 | | * Calculate the bounding rect of |aContent|, relative to the origin |
2949 | | * of the scrolled content of |aRootScrollFrame|. |
2950 | | * Where the element is contained inside a scrollable subframe, the |
2951 | | * bounding rect is clipped to the bounds of the subframe. |
2952 | | */ |
2953 | | static CSSRect GetBoundingContentRect(const nsIContent* aContent, |
2954 | | const nsIScrollableFrame* aRootScrollFrame); |
2955 | | |
2956 | | /** |
2957 | | * Returns the first ancestor who is a float containing block. |
2958 | | */ |
2959 | | static nsBlockFrame* GetFloatContainingBlock(nsIFrame* aFrame); |
2960 | | |
2961 | | /** |
2962 | | * Walks up the frame tree from |aForFrame| up to |aTopFrame|, or to the |
2963 | | * root of the frame tree if |aTopFrame| is nullptr, and returns true if |
2964 | | * a transformed frame is encountered. |
2965 | | */ |
2966 | | static bool IsTransformed(nsIFrame* aForFrame, nsIFrame* aTopFrame = nullptr); |
2967 | | |
2968 | | /** |
2969 | | * Walk up from aFrame to the cross-doc root, accumulating all the APZ callback |
2970 | | * transforms on the content elements encountered along the way. Return the |
2971 | | * accumulated value. |
2972 | | * XXX: Note that this does not take into account CSS transforms, nor |
2973 | | * differences in structure between the frame tree and the layer tree (which |
2974 | | * is probably what we *want* to be computing). |
2975 | | */ |
2976 | | static CSSPoint GetCumulativeApzCallbackTransform(nsIFrame* aFrame); |
2977 | | |
2978 | | /** |
2979 | | * Compute a rect to pre-render in cases where we want to render more of |
2980 | | * something than what is visible (usually to support async transformation). |
2981 | | * @param aDirtyRect the area that's visible |
2982 | | * @param aOverflow the total size of the thing we're rendering |
2983 | | * @param aPrerenderSize how large of an area we're willing to render |
2984 | | * @return A rectangle that includes |aDirtyRect|, is clamped to |aOverflow|, |
2985 | | * and is no larger than |aPrerenderSize| (unless |aPrerenderSize| |
2986 | | * is smaller than |aDirtyRect|, in which case the returned rect |
2987 | | * will still include |aDirtyRect| and thus be larger than |
2988 | | * |aPrerenderSize|). |
2989 | | */ |
2990 | | static nsRect ComputePartialPrerenderArea(const nsRect& aDirtyRect, |
2991 | | const nsRect& aOverflow, |
2992 | | const nsSize& aPrerenderSize); |
2993 | | |
2994 | | /* |
2995 | | * Checks whether a node is an invisible break. |
2996 | | * If not, returns the first frame on the next line if such a next line exists. |
2997 | | * |
2998 | | * @return true if the node is an invisible break. |
2999 | | * aNextLineFrame is returned null in this case. |
3000 | | * false if the node causes a visible break or if the node is no break. |
3001 | | * |
3002 | | * @param aNextLineFrame assigned to first frame on the next line if such a |
3003 | | * next line exists, null otherwise. |
3004 | | */ |
3005 | | static bool IsInvisibleBreak(nsINode* aNode, nsIFrame** aNextLineFrame = nullptr); |
3006 | | |
3007 | | static nsRect ComputeGeometryBox(nsIFrame* aFrame, |
3008 | | StyleGeometryBox aGeometryBox); |
3009 | | |
3010 | | static nsPoint ComputeOffsetToUserSpace(nsDisplayListBuilder* aBuilder, |
3011 | | nsIFrame* aFrame); |
3012 | | |
3013 | | // Return the default value to be used for -moz-control-character-visibility, |
3014 | | // from preferences. |
3015 | | static uint8_t ControlCharVisibilityDefault(); |
3016 | | |
3017 | | enum class FlushUserFontSet { |
3018 | | Yes, |
3019 | | No, |
3020 | | }; |
3021 | | |
3022 | | static already_AddRefed<nsFontMetrics> GetMetricsFor(nsPresContext* aPresContext, |
3023 | | bool aIsVertical, |
3024 | | const nsStyleFont* aStyleFont, |
3025 | | nscoord aFontSize, |
3026 | | bool aUseUserFontSet, |
3027 | | FlushUserFontSet aFlushUserFontSet); |
3028 | | |
3029 | | /** |
3030 | | * Appropriately add the correct font if we are using DocumentFonts or |
3031 | | * overriding for XUL |
3032 | | */ |
3033 | | static void FixupNoneGeneric(nsFont* aFont, |
3034 | | const nsPresContext* aPresContext, |
3035 | | uint8_t aGenericFontID, |
3036 | | const nsFont* aDefaultVariableFont); |
3037 | | |
3038 | | /** |
3039 | | * For an nsStyleFont with mSize set, apply minimum font size constraints |
3040 | | * from preferences, as well as -moz-min-font-size-ratio. |
3041 | | */ |
3042 | | static void ApplyMinFontSize(nsStyleFont* aFont, |
3043 | | const nsPresContext* aPresContext, |
3044 | | nscoord aMinFontSize); |
3045 | | |
3046 | | static void ComputeSystemFont(nsFont* aSystemFont, |
3047 | | mozilla::LookAndFeel::FontID aFontID, |
3048 | | const nsPresContext* aPresContext, |
3049 | | const nsFont* aDefaultVariableFont); |
3050 | | |
3051 | | static void ComputeFontFeatures(const nsCSSValuePairList* aFeaturesList, |
3052 | | nsTArray<gfxFontFeature>& aFeatureSettings); |
3053 | | |
3054 | | static void ComputeFontVariations(const nsCSSValuePairList* aVariationsList, |
3055 | | nsTArray<gfxFontVariation>& aVariationSettings); |
3056 | | |
3057 | | static uint32_t ParseFontLanguageOverride(const nsAString& aLangTag); |
3058 | | |
3059 | | /** |
3060 | | * Resolve a CSS <length-percentage> value to a definite size. |
3061 | | */ |
3062 | | template<bool clampNegativeResultToZero> |
3063 | | static nscoord ResolveToLength(const nsStyleCoord& aCoord, |
3064 | | nscoord aPercentageBasis) |
3065 | | { |
3066 | | NS_WARNING_ASSERTION(aPercentageBasis >= nscoord(0), "nscoord overflow?"); |
3067 | | |
3068 | | switch (aCoord.GetUnit()) { |
3069 | | case eStyleUnit_Coord: |
3070 | | MOZ_ASSERT(!clampNegativeResultToZero || aCoord.GetCoordValue() >= 0, |
3071 | | "This value should have been rejected by the style system"); |
3072 | | return aCoord.GetCoordValue(); |
3073 | | case eStyleUnit_Percent: |
3074 | | if (aPercentageBasis == NS_UNCONSTRAINEDSIZE) { |
3075 | | return nscoord(0); |
3076 | | } |
3077 | | MOZ_ASSERT(!clampNegativeResultToZero || aCoord.GetPercentValue() >= 0, |
3078 | | "This value should have been rejected by the style system"); |
3079 | | return NSToCoordFloorClamped(aPercentageBasis * |
3080 | | aCoord.GetPercentValue()); |
3081 | | case eStyleUnit_Calc: { |
3082 | | nsStyleCoord::Calc* calc = aCoord.GetCalcValue(); |
3083 | | nscoord result; |
3084 | | if (aPercentageBasis == NS_UNCONSTRAINEDSIZE) { |
3085 | | result = calc->mLength; |
3086 | | } else { |
3087 | | result = calc->mLength + |
3088 | | NSToCoordFloorClamped(aPercentageBasis * calc->mPercent); |
3089 | | } |
3090 | | if (clampNegativeResultToZero && result < 0) { |
3091 | | return nscoord(0); |
3092 | | } |
3093 | | return result; |
3094 | | } |
3095 | | default: |
3096 | | MOZ_ASSERT_UNREACHABLE("Unexpected unit!"); |
3097 | | return nscoord(0); |
3098 | | } |
3099 | | } |
3100 | | |
3101 | | /** |
3102 | | * Resolve a column-gap/row-gap to a definite size. |
3103 | | * @note This method resolves 'normal' to zero. |
3104 | | * Callers who want different behavior should handle 'normal' on their own. |
3105 | | */ |
3106 | | static nscoord ResolveGapToLength(const nsStyleCoord& aGap, |
3107 | | nscoord aPercentageBasis) |
3108 | | { |
3109 | | if (aGap.GetUnit() == eStyleUnit_Normal) { |
3110 | | return nscoord(0); |
3111 | | } |
3112 | | return ResolveToLength<true>(aGap, aPercentageBasis); |
3113 | | } |
3114 | | |
3115 | | /** |
3116 | | * Get the computed style from which the scrollbar style should be |
3117 | | * used for the given scrollbar part frame. |
3118 | | */ |
3119 | | static ComputedStyle* StyleForScrollbar(nsIFrame* aScrollbarPart); |
3120 | | |
3121 | | /** |
3122 | | * Generate the motion path transform result. |
3123 | | **/ |
3124 | | static mozilla::Maybe<mozilla::MotionPathData> |
3125 | | ResolveMotionPath(const nsIFrame* aFrame); |
3126 | | |
3127 | | private: |
3128 | | static uint32_t sFontSizeInflationEmPerLine; |
3129 | | static uint32_t sFontSizeInflationMinTwips; |
3130 | | static uint32_t sFontSizeInflationLineThreshold; |
3131 | | static int32_t sFontSizeInflationMappingIntercept; |
3132 | | static uint32_t sFontSizeInflationMaxRatio; |
3133 | | static bool sFontSizeInflationForceEnabled; |
3134 | | static bool sFontSizeInflationDisabledInMasterProcess; |
3135 | | static uint32_t sSystemFontScale; |
3136 | | static uint32_t sZoomMaxPercent; |
3137 | | static uint32_t sZoomMinPercent; |
3138 | | static bool sInvalidationDebuggingIsEnabled; |
3139 | | static bool sInterruptibleReflowEnabled; |
3140 | | static bool sSVGTransformBoxEnabled; |
3141 | | static uint32_t sIdlePeriodDeadlineLimit; |
3142 | | static uint32_t sQuiescentFramesBeforeIdlePeriod; |
3143 | | |
3144 | | /** |
3145 | | * Helper function for LogTestDataForPaint(). |
3146 | | */ |
3147 | | static void DoLogTestDataForPaint(mozilla::layers::LayerManager* aManager, |
3148 | | ViewID aScrollId, |
3149 | | const std::string& aKey, |
3150 | | const std::string& aValue); |
3151 | | |
3152 | | static bool IsAPZTestLoggingEnabled(); |
3153 | | }; |
3154 | | |
3155 | | MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsLayoutUtils::PaintFrameFlags) |
3156 | | |
3157 | | template<typename PointType, typename RectType, typename CoordType> |
3158 | | /* static */ bool |
3159 | | nsLayoutUtils::PointIsCloserToRect(PointType aPoint, const RectType& aRect, |
3160 | | CoordType& aClosestXDistance, |
3161 | | CoordType& aClosestYDistance) |
3162 | | { |
3163 | | CoordType fromLeft = aPoint.x - aRect.x; |
3164 | | CoordType fromRight = aPoint.x - aRect.XMost(); |
3165 | | |
3166 | | CoordType xDistance; |
3167 | | if (fromLeft >= 0 && fromRight <= 0) { |
3168 | | xDistance = 0; |
3169 | | } else { |
3170 | | xDistance = std::min(abs(fromLeft), abs(fromRight)); |
3171 | | } |
3172 | | |
3173 | | if (xDistance <= aClosestXDistance) { |
3174 | | if (xDistance < aClosestXDistance) { |
3175 | | aClosestYDistance = std::numeric_limits<CoordType>::max(); |
3176 | | } |
3177 | | |
3178 | | CoordType fromTop = aPoint.y - aRect.y; |
3179 | | CoordType fromBottom = aPoint.y - aRect.YMost(); |
3180 | | |
3181 | | CoordType yDistance; |
3182 | | if (fromTop >= 0 && fromBottom <= 0) { |
3183 | | yDistance = 0; |
3184 | | } else { |
3185 | | yDistance = std::min(abs(fromTop), abs(fromBottom)); |
3186 | | } |
3187 | | |
3188 | | if (yDistance < aClosestYDistance) { |
3189 | | aClosestXDistance = xDistance; |
3190 | | aClosestYDistance = yDistance; |
3191 | | return true; |
3192 | | } |
3193 | | } |
3194 | | |
3195 | | return false; |
3196 | | } |
3197 | | |
3198 | | namespace mozilla { |
3199 | | |
3200 | | /** |
3201 | | * Converts an nsPoint in app units to a Moz2D Point in pixels (whether those |
3202 | | * are device pixels or CSS px depends on what the caller chooses to pass as |
3203 | | * aAppUnitsPerPixel). |
3204 | | */ |
3205 | | inline gfx::Point NSPointToPoint(const nsPoint& aPoint, |
3206 | | int32_t aAppUnitsPerPixel) { |
3207 | | return gfx::Point(gfx::Float(aPoint.x) / aAppUnitsPerPixel, |
3208 | | gfx::Float(aPoint.y) / aAppUnitsPerPixel); |
3209 | | } |
3210 | | |
3211 | | /** |
3212 | | * Converts an nsRect in app units to a Moz2D Rect in pixels (whether those |
3213 | | * are device pixels or CSS px depends on what the caller chooses to pass as |
3214 | | * aAppUnitsPerPixel). |
3215 | | */ |
3216 | | gfx::Rect NSRectToRect(const nsRect& aRect, double aAppUnitsPerPixel); |
3217 | | |
3218 | | /** |
3219 | | * Converts an nsRect in app units to a Moz2D Rect in pixels (whether those |
3220 | | * are device pixels or CSS px depends on what the caller chooses to pass as |
3221 | | * aAppUnitsPerPixel). |
3222 | | * |
3223 | | * The passed DrawTarget is used to additionally snap the returned Rect to |
3224 | | * device pixels, if appropriate (as decided and carried out by Moz2D's |
3225 | | * MaybeSnapToDevicePixels helper, which this function calls to do any |
3226 | | * snapping). |
3227 | | */ |
3228 | | gfx::Rect NSRectToSnappedRect(const nsRect& aRect, double aAppUnitsPerPixel, |
3229 | | const gfx::DrawTarget& aSnapDT); |
3230 | | |
3231 | | /** |
3232 | | * Converts, where possible, an nsRect in app units to a Moz2D Rect in pixels |
3233 | | * (whether those are device pixels or CSS px depends on what the caller |
3234 | | * chooses to pass as aAppUnitsPerPixel). |
3235 | | * |
3236 | | * If snapping results in a rectangle with zero width or height, the affected |
3237 | | * coordinates are left unsnapped |
3238 | | */ |
3239 | | gfx::Rect NSRectToNonEmptySnappedRect(const nsRect& aRect, double aAppUnitsPerPixel, |
3240 | | const gfx::DrawTarget& aSnapDT); |
3241 | | |
3242 | | void StrokeLineWithSnapping(const nsPoint& aP1, const nsPoint& aP2, |
3243 | | int32_t aAppUnitsPerDevPixel, |
3244 | | gfx::DrawTarget& aDrawTarget, |
3245 | | const gfx::Pattern& aPattern, |
3246 | | const gfx::StrokeOptions& aStrokeOptions = gfx::StrokeOptions(), |
3247 | | const gfx::DrawOptions& aDrawOptions = gfx::DrawOptions()); |
3248 | | |
3249 | | namespace layout { |
3250 | | |
3251 | | /** |
3252 | | * An RAII class which will, for the duration of its lifetime, |
3253 | | * **if** the frame given is a container for font size inflation, |
3254 | | * set the current inflation container on the pres context to null |
3255 | | * (and then, in its destructor, restore the old value). |
3256 | | */ |
3257 | | class AutoMaybeDisableFontInflation { |
3258 | | public: |
3259 | | explicit AutoMaybeDisableFontInflation(nsIFrame *aFrame); |
3260 | | |
3261 | | ~AutoMaybeDisableFontInflation(); |
3262 | | private: |
3263 | | nsPresContext *mPresContext; |
3264 | | bool mOldValue; |
3265 | | }; |
3266 | | |
3267 | | void MaybeSetupTransactionIdAllocator(layers::LayerManager* aManager, |
3268 | | nsPresContext* aPresContext); |
3269 | | |
3270 | | } // namespace layout |
3271 | | } // namespace mozilla |
3272 | | |
3273 | | class nsSetAttrRunnable : public mozilla::Runnable |
3274 | | { |
3275 | | public: |
3276 | | nsSetAttrRunnable(mozilla::dom::Element* aElement, nsAtom* aAttrName, |
3277 | | const nsAString& aValue); |
3278 | | nsSetAttrRunnable(mozilla::dom::Element* aElement, nsAtom* aAttrName, |
3279 | | int32_t aValue); |
3280 | | |
3281 | | NS_DECL_NSIRUNNABLE |
3282 | | |
3283 | | RefPtr<Element> mElement; |
3284 | | RefPtr<nsAtom> mAttrName; |
3285 | | nsAutoString mValue; |
3286 | | }; |
3287 | | |
3288 | | class nsUnsetAttrRunnable : public mozilla::Runnable |
3289 | | { |
3290 | | public: |
3291 | | nsUnsetAttrRunnable(mozilla::dom::Element* aElement, nsAtom* aAttrName); |
3292 | | |
3293 | | NS_DECL_NSIRUNNABLE |
3294 | | |
3295 | | RefPtr<Element> mElement; |
3296 | | RefPtr<nsAtom> mAttrName; |
3297 | | }; |
3298 | | |
3299 | | // This class allows you to easily set any pointer variable and ensure it's |
3300 | | // set to nullptr when leaving its scope. |
3301 | | template<typename T> |
3302 | | class MOZ_RAII SetAndNullOnExit |
3303 | | { |
3304 | | public: |
3305 | | SetAndNullOnExit(T* &aVariable, T* aValue) { |
3306 | | aVariable = aValue; |
3307 | | mVariable = &aVariable; |
3308 | | } |
3309 | | ~SetAndNullOnExit() { |
3310 | | *mVariable = nullptr; |
3311 | | } |
3312 | | private: |
3313 | | T** mVariable; |
3314 | | }; |
3315 | | |
3316 | | #endif // nsLayoutUtils_h__ |