1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef nsLayoutUtils_h__
8 #define nsLayoutUtils_h__
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/RelativeTo.h"
16 #include "mozilla/StaticPrefs_nglayout.h"
17 #include "mozilla/SurfaceFromElementResult.h"
18 #include "mozilla/SVGImageContext.h"
19 #include "mozilla/ToString.h"
20 #include "mozilla/TypedEnumBits.h"
21 #include "mozilla/Span.h"
22 #include "mozilla/UniquePtr.h"
23 #include "mozilla/WritingModes.h"
24 #include "mozilla/layers/ScrollableLayerGuid.h"
25 #include "mozilla/gfx/2D.h"
28 #include "nsBoundingMetrics.h"
29 #include "nsCSSPropertyIDSet.h"
30 #include "nsFrameList.h"
31 #include "nsThreadUtils.h"
33 #include "mozilla/layers/LayersTypes.h"
36 // If you're thinking of adding a new include here, please try hard to not.
37 // This header file gets included just about everywhere and adding headers here
38 // can dramatically increase avoidable build activity. Try instead:
39 // - using a forward declaration
40 // - putting the include in the .cpp file, if it is only needed by the body
41 // - putting your new functions in some other less-widely-used header
52 class nsIScrollableFrame
;
54 enum nsChangeHint
: uint32_t;
57 class nsIImageLoadingContent
;
59 class nsContainerFrame
;
62 class nsPIDOMWindowOuter
;
69 class nsDisplayListBuilder
;
70 enum class nsDisplayListBuilderMode
: uint8_t;
71 class RetainedDisplayListBuilder
;
74 class DisplayPortUtils
;
76 enum class PseudoStyleType
: uint8_t;
77 class EventListenerManager
;
78 enum class LayoutFrameType
: uint8_t;
82 class DisplayItemClip
;
84 struct ActiveScrolledRoot
;
85 enum class ScrollOrigin
: uint8_t;
86 enum class StyleImageOrientation
: uint8_t;
87 enum class StyleSystemFont
: uint8_t;
88 enum class StyleScrollbarWidth
: uint8_t;
91 class CanvasRenderingContext2D
;
96 class HTMLImageElement
;
97 class HTMLCanvasElement
;
98 class HTMLVideoElement
;
100 class InspectorFontFace
;
101 class OffscreenCanvas
;
106 struct RectCornerRadii
;
107 enum class ShapedTextFlags
: uint16_t;
110 class ImageIntRegion
;
115 struct ScrollMetadata
;
117 class StackingContextHelper
;
119 class WebRenderLayerManager
;
120 } // namespace layers
122 enum class TransparencyMode
: uint8_t;
124 } // namespace mozilla
126 // Flags to customize the behavior of nsLayoutUtils::DrawString.
127 enum class DrawStringFlags
{
129 ForceHorizontal
= 0x1 // Forces the text to be drawn horizontally.
131 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DrawStringFlags
)
137 virtual void AddRect(const nsRect
& aRect
) = 0;
140 } // namespace mozilla
143 * nsLayoutUtils is a namespace class used for various helper
144 * functions that are useful in multiple places in layout. The goal
145 * is not to define multiple copies of the same static helper.
147 class nsLayoutUtils
{
148 typedef mozilla::AspectRatio AspectRatio
;
149 typedef mozilla::ComputedStyle ComputedStyle
;
150 typedef mozilla::LengthPercentage LengthPercentage
;
151 typedef mozilla::LengthPercentageOrAuto LengthPercentageOrAuto
;
152 typedef mozilla::dom::DOMRectList DOMRectList
;
153 typedef mozilla::layers::StackingContextHelper StackingContextHelper
;
154 typedef mozilla::IntrinsicSize IntrinsicSize
;
155 typedef mozilla::RelativeTo RelativeTo
;
156 typedef mozilla::ScrollOrigin ScrollOrigin
;
157 typedef mozilla::ViewportType ViewportType
;
158 typedef mozilla::gfx::SourceSurface SourceSurface
;
159 typedef mozilla::gfx::sRGBColor sRGBColor
;
160 typedef mozilla::gfx::DrawTarget DrawTarget
;
161 typedef mozilla::gfx::ExtendMode ExtendMode
;
162 typedef mozilla::gfx::SamplingFilter SamplingFilter
;
163 typedef mozilla::gfx::Float Float
;
164 typedef mozilla::gfx::Point Point
;
165 typedef mozilla::gfx::Rect Rect
;
166 typedef mozilla::gfx::RectDouble RectDouble
;
167 typedef mozilla::gfx::Size Size
;
168 typedef mozilla::gfx::Matrix4x4 Matrix4x4
;
169 typedef mozilla::gfx::Matrix4x4Flagged Matrix4x4Flagged
;
170 typedef mozilla::gfx::MatrixScales MatrixScales
;
171 typedef mozilla::gfx::MatrixScalesDouble MatrixScalesDouble
;
172 typedef mozilla::gfx::RectCornerRadii RectCornerRadii
;
173 typedef mozilla::gfx::StrokeOptions StrokeOptions
;
174 typedef mozilla::image::ImgDrawResult ImgDrawResult
;
176 using nsDisplayItem
= mozilla::nsDisplayItem
;
177 using nsDisplayList
= mozilla::nsDisplayList
;
178 using nsDisplayListBuilder
= mozilla::nsDisplayListBuilder
;
179 using nsDisplayListBuilderMode
= mozilla::nsDisplayListBuilderMode
;
180 using RetainedDisplayListBuilder
= mozilla::RetainedDisplayListBuilder
;
183 typedef mozilla::layers::FrameMetrics FrameMetrics
;
184 typedef mozilla::layers::ScrollMetadata ScrollMetadata
;
185 typedef mozilla::layers::ScrollableLayerGuid::ViewID ViewID
;
186 typedef mozilla::CSSPoint CSSPoint
;
187 typedef mozilla::CSSSize CSSSize
;
188 typedef mozilla::CSSIntSize CSSIntSize
;
189 typedef mozilla::CSSRect CSSRect
;
190 typedef mozilla::ScreenMargin ScreenMargin
;
191 typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize
;
192 typedef mozilla::LayoutDeviceRect LayoutDeviceRect
;
193 typedef mozilla::PresShell PresShell
;
194 typedef mozilla::StyleGeometryBox StyleGeometryBox
;
195 typedef mozilla::SVGImageContext SVGImageContext
;
196 typedef mozilla::LogicalSize LogicalSize
;
199 * Finds previously assigned ViewID for the given content element, if any.
200 * Returns whether a ViewID was previously assigned.
202 static bool FindIDFor(const nsIContent
* aContent
, ViewID
* aOutViewId
);
205 * Finds previously assigned or generates a unique ViewID for the given
208 static ViewID
FindOrCreateIDFor(nsIContent
* aContent
);
211 * Find content for given ID.
213 static nsIContent
* FindContentFor(ViewID aId
);
216 * Find the scrollable frame for a given content element.
218 static nsIScrollableFrame
* FindScrollableFrameFor(nsIContent
* aContent
);
221 * Find the scrollable frame for a given ID.
223 static nsIScrollableFrame
* FindScrollableFrameFor(ViewID aId
);
226 * Helper for FindScrollableFrameFor(), also used in DisplayPortUtils.
227 * Most clients should use FindScrollableFrameFor().
229 static nsIFrame
* GetScrollFrameFromContent(nsIContent
* aContent
);
232 * Find the ID for a given scrollable frame.
234 static ViewID
FindIDForScrollableFrame(nsIScrollableFrame
* aScrollable
);
237 * Notify the scroll frame with the given scroll id that its scroll offset
238 * is being sent to APZ as part of a paint-skip transaction.
240 * Normally, this notification happens during painting, after calls to
241 * ComputeScrollMetadata(). During paint-skipping that code is skipped,
242 * but it's still important for the scroll frame to be notified for
243 * correctness of relative scroll updates, so the code that sends the
244 * empty paint-skip transaction needs to call this.
246 static void NotifyPaintSkipTransaction(ViewID aScrollId
);
249 * Use heuristics to figure out the child list that
250 * aChildFrame is currently in.
252 static mozilla::FrameChildListID
GetChildListNameFor(nsIFrame
* aChildFrame
);
255 * Returns the ::before pseudo-element for aContent, if any.
257 static mozilla::dom::Element
* GetBeforePseudo(const nsIContent
* aContent
);
260 * Returns the frame corresponding to the ::before pseudo-element for
263 static nsIFrame
* GetBeforeFrame(const nsIContent
* aContent
);
266 * Returns the ::after pseudo-element for aContent, if any.
268 static mozilla::dom::Element
* GetAfterPseudo(const nsIContent
* aContent
);
271 * Returns the frame corresponding to the ::after pseudo-element for aContent,
274 static nsIFrame
* GetAfterFrame(const nsIContent
* aContent
);
277 * Returns the ::marker pseudo-element for aContent, if any.
279 static mozilla::dom::Element
* GetMarkerPseudo(const nsIContent
* aContent
);
282 * Returns the frame corresponding to the ::marker pseudo-element for
285 static nsIFrame
* GetMarkerFrame(const nsIContent
* aContent
);
289 * Set aText to the spoken text for the given ::marker content (aContent)
290 * if it has a frame, or the empty string otherwise.
292 static void GetMarkerSpokenText(const nsIContent
* aContent
, nsAString
& aText
);
296 * Given a frame, search up the frame tree until we find an
297 * ancestor that (or the frame itself) is of type aFrameType, if any.
299 * @param aFrame the frame to start at
300 * @param aFrameType the frame type to look for
301 * @param aStopAt a frame to stop at after we checked it
302 * @return a frame of the given type or nullptr if no
303 * such ancestor exists
305 static nsIFrame
* GetClosestFrameOfType(nsIFrame
* aFrame
,
306 mozilla::LayoutFrameType aFrameType
,
307 nsIFrame
* aStopAt
= nullptr);
310 * Given a frame, search up the frame tree until we find an
311 * ancestor that (or the frame itself) is a "Page" frame, if any.
313 * @param aFrame the frame to start at
314 * @return a frame of type mozilla::LayoutFrameType::Page or nullptr if no
315 * such ancestor exists
317 static nsIFrame
* GetPageFrame(nsIFrame
* aFrame
);
320 * Given a frame which is the primary frame for an element,
321 * return the frame that has the non-pseudoelement ComputedStyle for
323 * This is aPrimaryFrame itself except for tableWrapper frames.
325 * Given a non-null input, this will return null if and only if its
326 * argument is a table wrapper frame that is mid-destruction (and its
327 * table frame has been destroyed).
329 static nsIFrame
* GetStyleFrame(nsIFrame
* aPrimaryFrame
);
330 static const nsIFrame
* GetStyleFrame(const nsIFrame
* aPrimaryFrame
);
333 * Given a content node,
334 * return the frame that has the non-pseudoelement ComputedStyle for
335 * the content. May return null.
336 * This is aContent->GetPrimaryFrame() except for tableWrapper frames.
338 static nsIFrame
* GetStyleFrame(const nsIContent
* aContent
);
341 * Returns the placeholder size for when the scrollbar is unthemed.
343 static mozilla::CSSIntCoord
UnthemedScrollbarSize(
344 mozilla::StyleScrollbarWidth
);
347 * The inverse of GetStyleFrame. Returns |aStyleFrame| unless it is an inner
348 * table frame, in which case the table wrapper frame is returned.
350 static nsIFrame
* GetPrimaryFrameFromStyleFrame(nsIFrame
* aStyleFrame
);
351 static const nsIFrame
* GetPrimaryFrameFromStyleFrame(
352 const nsIFrame
* aStyleFrame
);
355 * Similar to nsIFrame::IsPrimaryFrame except that this will return true
356 * for the inner table frame rather than for its wrapper frame.
358 static bool IsPrimaryStyleFrame(const nsIFrame
* aFrame
);
361 * CompareTreePosition determines whether aFrame1 comes before or
362 * after aFrame2 in a preorder traversal of the frame tree, where out
363 * of flow frames are treated as children of their placeholders. This is
364 * basically the same ordering as DoCompareTreePosition(nsIContent*) except
365 * that it handles anonymous content properly and there are subtleties with
368 * @param aCommonAncestor either null, or a common ancestor of
369 * aContent1 and aContent2. Actually this is
370 * only a hint; if it's not an ancestor of
371 * aContent1 or aContent2, this function will
372 * still work, but it will be slower than
374 * @return < 0 if aContent1 is before aContent2
375 * > 0 if aContent1 is after aContent2,
376 * 0 otherwise (meaning they're the same, or they're in
377 * different frame trees)
379 static int32_t CompareTreePosition(nsIFrame
* aFrame1
, nsIFrame
* aFrame2
,
380 nsIFrame
* aCommonAncestor
= nullptr) {
381 return DoCompareTreePosition(aFrame1
, aFrame2
, aCommonAncestor
);
384 static int32_t CompareTreePosition(nsIFrame
* aFrame1
, nsIFrame
* aFrame2
,
385 nsTArray
<nsIFrame
*>& aFrame2Ancestors
,
386 nsIFrame
* aCommonAncestor
= nullptr) {
387 return DoCompareTreePosition(aFrame1
, aFrame2
, aFrame2Ancestors
,
391 static nsIFrame
* FillAncestors(nsIFrame
* aFrame
, nsIFrame
* aStopAtAncestor
,
392 nsTArray
<nsIFrame
*>* aAncestors
);
394 static int32_t DoCompareTreePosition(nsIFrame
* aFrame1
, nsIFrame
* aFrame2
,
395 nsIFrame
* aCommonAncestor
);
396 static int32_t DoCompareTreePosition(nsIFrame
* aFrame1
, nsIFrame
* aFrame2
,
397 nsTArray
<nsIFrame
*>& aFrame2Ancestors
,
398 nsIFrame
* aCommonAncestor
);
401 * LastContinuationWithChild gets the last continuation in aFrame's chain
402 * that has a child, or the first continuation if the frame has no children.
404 static nsContainerFrame
* LastContinuationWithChild(nsContainerFrame
* aFrame
);
407 * GetLastSibling simply finds the last sibling of aFrame, or returns nullptr
410 static nsIFrame
* GetLastSibling(nsIFrame
* aFrame
);
413 * FindSiblingViewFor locates the child of aParentView that aFrame's
414 * view should be inserted 'above' (i.e., before in sibling view
415 * order). This is the first child view of aParentView whose
416 * corresponding content is before aFrame's content (view siblings
417 * are in reverse content order).
419 static nsView
* FindSiblingViewFor(nsView
* aParentView
, nsIFrame
* aFrame
);
422 * Get the parent of aFrame. If aFrame is the root frame for a document,
423 * and the document has a parent document in the same view hierarchy, then
424 * we try to return the subdocumentframe in the parent document.
425 * @param aCrossDocOffset [in/out] if non-null, then as we cross documents
426 * an extra offset may be required and it will be added to aCrossDocOffset.
427 * Be careful dealing with this extra offset as it is in app units of the
428 * parent document, which may have a different app units per dev pixel ratio
429 * than the child document.
430 * Note that, while this function crosses document boundaries, it (naturally)
431 * cannot cross process boundaries.
433 static nsIFrame
* GetCrossDocParentFrameInProcess(
434 const nsIFrame
* aFrame
, nsPoint
* aCrossDocOffset
= nullptr);
437 * Does the same thing as GetCrossDocParentFrameInProcess().
438 * The purpose of having two functions is to more easily track which call
439 * sites have been audited to consider out-of-process iframes (bug 1599913).
440 * Once all call sites have been audited, this function can be removed.
442 static nsIFrame
* GetCrossDocParentFrame(const nsIFrame
* aFrame
,
443 nsPoint
* aCrossDocOffset
= nullptr);
446 * IsProperAncestorFrame checks whether aAncestorFrame is an ancestor
447 * of aFrame and not equal to aFrame.
448 * @param aCommonAncestor nullptr, or a common ancestor of aFrame and
449 * aAncestorFrame. If non-null, this can bound the search and speed up
452 static bool IsProperAncestorFrame(const nsIFrame
* aAncestorFrame
,
453 const nsIFrame
* aFrame
,
454 const nsIFrame
* aCommonAncestor
= nullptr);
457 * Like IsProperAncestorFrame, but looks across document boundaries.
459 * Just like IsAncestorFrameCrossDoc, except that it returns false when
460 * aFrame == aAncestorFrame.
461 * TODO: Once after we fixed bug 1715932, this function should be removed.
463 static bool IsProperAncestorFrameCrossDoc(
464 const nsIFrame
* aAncestorFrame
, const nsIFrame
* aFrame
,
465 const nsIFrame
* aCommonAncestor
= nullptr);
468 * Like IsProperAncestorFrame, but looks across document boundaries.
470 * Just like IsAncestorFrameCrossDoc, except that it returns false when
471 * aFrame == aAncestorFrame.
473 static bool IsProperAncestorFrameCrossDocInProcess(
474 const nsIFrame
* aAncestorFrame
, const nsIFrame
* aFrame
,
475 const nsIFrame
* aCommonAncestor
= nullptr);
478 * IsAncestorFrameCrossDoc checks whether aAncestorFrame is an ancestor
479 * of aFrame or equal to aFrame, looking across document boundaries.
480 * @param aCommonAncestor nullptr, or a common ancestor of aFrame and
481 * aAncestorFrame. If non-null, this can bound the search and speed up
484 * Just like IsProperAncestorFrameCrossDoc, except that it returns true when
485 * aFrame == aAncestorFrame.
487 * TODO: Bug 1700245, all call sites of this function will be eventually
488 * replaced by IsAncestorFrameCrossDocInProcess.
490 static bool IsAncestorFrameCrossDoc(
491 const nsIFrame
* aAncestorFrame
, const nsIFrame
* aFrame
,
492 const nsIFrame
* aCommonAncestor
= nullptr);
495 * IsAncestorFrameCrossDocInProcess checks whether aAncestorFrame is an
496 * ancestor of aFrame or equal to aFrame, looking across document boundaries
497 * in the same process.
498 * @param aCommonAncestor nullptr, or a common ancestor of aFrame and
499 * aAncestorFrame. If non-null, this can bound the search and speed up
502 * Just like IsProperAncestorFrameCrossDoc, except that it returns true when
503 * aFrame == aAncestorFrame.
505 * NOTE: This function doesn't return true even if |aAncestorFrame| and
506 * |aFrame| is in the same process but they are not directly connected, e.g.
507 * both |aAncestorFrame| and |aFrame| in A domain documents, but there's
508 * another an iframe document domain B, such as A1 -> B1 ->A2 document tree.
510 static bool IsAncestorFrameCrossDocInProcess(
511 const nsIFrame
* aAncestorFrame
, const nsIFrame
* aFrame
,
512 const nsIFrame
* aCommonAncestor
= nullptr);
514 static mozilla::SideBits
GetSideBitsForFixedPositionContent(
515 const nsIFrame
* aFixedPosFrame
);
518 * Get the scroll id for the root scrollframe of the presshell of the given
519 * prescontext. Returns NULL_SCROLL_ID if it couldn't be found.
521 static ViewID
ScrollIdForRootScrollFrame(nsPresContext
* aPresContext
);
524 * GetScrollableFrameFor returns the scrollable frame for a scrolled frame
526 static nsIScrollableFrame
* GetScrollableFrameFor(
527 const nsIFrame
* aScrolledFrame
);
530 * GetNearestScrollableFrameForDirection locates the first ancestor of
531 * aFrame (or aFrame itself) that is scrollable with overflow:scroll or
532 * overflow:auto in the given direction and where either the scrollbar for
533 * that direction is visible or the frame can be scrolled by some
534 * positive amount in that direction.
535 * The search extends across document boundaries.
537 * @param aFrame the frame to start with
538 * @param aDirection Whether it's for horizontal or vertical scrolling.
539 * @return the nearest scrollable frame or nullptr if not found
541 static nsIScrollableFrame
* GetNearestScrollableFrameForDirection(
542 nsIFrame
* aFrame
, mozilla::layers::ScrollDirections aDirections
);
546 * If the SCROLLABLE_SAME_DOC flag is set, then we only walk the frame tree
547 * up to the root frame in the current document.
549 SCROLLABLE_SAME_DOC
= 0x01,
551 * If the SCROLLABLE_INCLUDE_HIDDEN flag is set then we allow
552 * overflow:hidden scrollframes to be returned as scrollable frames.
554 SCROLLABLE_INCLUDE_HIDDEN
= 0x02,
556 * If the SCROLLABLE_ONLY_ASYNC_SCROLLABLE flag is set, then we only
557 * want to match scrollable frames for which WantAsyncScroll() returns
560 SCROLLABLE_ONLY_ASYNC_SCROLLABLE
= 0x04,
562 * If the SCROLLABLE_ALWAYS_MATCH_ROOT flag is set, then we will always
563 * return the root scrollable frame for the root document (in the current
564 * process) if we encounter it, whether or not it is async scrollable or
567 SCROLLABLE_ALWAYS_MATCH_ROOT
= 0x08,
569 * If the SCROLLABLE_FIXEDPOS_FINDS_ROOT flag is set, then for fixed-pos
570 * frames return the root scrollable frame for that document.
572 SCROLLABLE_FIXEDPOS_FINDS_ROOT
= 0x10,
574 * If the SCROLLABLE_STOP_AT_PAGE flag is set, then we stop searching
575 * for scrollable ancestors when seeing a nsPageFrame. This can be used
576 * to avoid finding the viewport scroll frame in Print Preview (which
577 * would be undesirable as a 'position:sticky' container for content).
579 SCROLLABLE_STOP_AT_PAGE
= 0x20,
582 * GetNearestScrollableFrame locates the first ancestor of aFrame
583 * (or aFrame itself) that is scrollable with overflow:scroll or
584 * overflow:auto in some direction.
586 * @param aFrame the frame to start with
587 * @param aFlags if SCROLLABLE_SAME_DOC is set, do not search across
588 * document boundaries. If SCROLLABLE_INCLUDE_HIDDEN is set, include
589 * frames scrollable with overflow:hidden.
590 * @return the nearest scrollable frame or nullptr if not found
592 static nsIScrollableFrame
* GetNearestScrollableFrame(nsIFrame
* aFrame
,
593 uint32_t aFlags
= 0);
596 * GetScrolledRect returns the range of allowable scroll offsets
597 * for aScrolledFrame, assuming the scrollable overflow area is
598 * aScrolledFrameOverflowArea and the scrollport size is aScrollPortSize.
600 static nsRect
GetScrolledRect(nsIFrame
* aScrolledFrame
,
601 const nsRect
& aScrolledFrameOverflowArea
,
602 const nsSize
& aScrollPortSize
,
603 mozilla::StyleDirection
);
606 * HasPseudoStyle returns true if aContent (whose primary style
607 * context is aComputedStyle) has the aPseudoElement pseudo-style
608 * attached to it; returns false otherwise.
610 * @param aContent the content node we're looking at
611 * @param aComputedStyle aContent's ComputedStyle
612 * @param aPseudoElement the id of the pseudo style we care about
613 * @param aPresContext the presentation context
614 * @return whether aContent has aPseudoElement style attached to it
616 static bool HasPseudoStyle(nsIContent
* aContent
,
617 ComputedStyle
* aComputedStyle
,
618 mozilla::PseudoStyleType aPseudoElement
,
619 nsPresContext
* aPresContext
);
622 * If this frame is a placeholder for a float, then return the float,
623 * otherwise return nullptr. aPlaceholder must be a placeholder frame.
625 static nsIFrame
* GetFloatFromPlaceholder(nsIFrame
* aPlaceholder
);
627 // Combine aOrigClearType with aNewClearType, but limit the clear types
628 // to StyleClear::Left, Right, Both.
629 static mozilla::StyleClear
CombineClearType(
630 mozilla::StyleClear aOrigClearType
, mozilla::StyleClear aNewClearType
);
633 * Get the coordinates of a given DOM mouse event, relative to a given
634 * frame. Works only for DOM events generated by WidgetGUIEvents.
635 * @param aDOMEvent the event
636 * @param aFrame the frame to make coordinates relative to
637 * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
638 * for some reason the coordinates for the mouse are not known (e.g.,
639 * the event is not a GUI event).
641 static nsPoint
GetDOMEventCoordinatesRelativeTo(
642 mozilla::dom::Event
* aDOMEvent
, nsIFrame
* aFrame
);
645 * Get the coordinates of a given native mouse event, relative to a given
647 * @param aEvent the event
648 * @param aFrame the frame to make coordinates relative to
649 * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
650 * for some reason the coordinates for the mouse are not known (e.g.,
651 * the event is not a GUI event).
653 static nsPoint
GetEventCoordinatesRelativeTo(
654 const mozilla::WidgetEvent
* aEvent
, RelativeTo aFrame
);
657 * Get the coordinates of a given point relative to an event and a
659 * @param aEvent the event
660 * @param aPoint the point to get the coordinates relative to
661 * @param aFrame the frame to make coordinates relative to
662 * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
663 * for some reason the coordinates for the mouse are not known (e.g.,
664 * the event is not a GUI event).
666 static nsPoint
GetEventCoordinatesRelativeTo(
667 const mozilla::WidgetEvent
* aEvent
,
668 const mozilla::LayoutDeviceIntPoint
& aPoint
, RelativeTo aFrame
);
671 * Get the coordinates of a given point relative to a widget and a
673 * @param aWidget the event src widget
674 * @param aPoint the point to get the coordinates relative to
675 * @param aFrame the frame to make coordinates relative to
676 * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
677 * for some reason the coordinates for the mouse are not known (e.g.,
678 * the event is not a GUI event).
680 static nsPoint
GetEventCoordinatesRelativeTo(
681 nsIWidget
* aWidget
, const mozilla::LayoutDeviceIntPoint
& aPoint
,
685 * Get the popup frame of a given native mouse event.
686 * @param aRootPresContext only check popups within aRootPresContext or a
688 * @param aEvent the event.
689 * @return Null, if there is no popup frame at the point, otherwise,
690 * returns top-most popup frame at the point.
692 static nsIFrame
* GetPopupFrameForEventCoordinates(
693 nsPresContext
* aRootPresContext
, const mozilla::WidgetEvent
* aEvent
);
696 * Get the popup frame of a given point relative to a widget.
697 * @param aRootPresContext only check popups within aRootPresContext or a
699 * @param aEvent the event.
700 * @return Null, if there is no popup frame at the point, otherwise,
701 * returns top-most popup frame at the point.
703 enum class GetPopupFrameForPointFlags
: uint8_t {
704 OnlyReturnFramesWithWidgets
= 0x1,
706 static nsIFrame
* GetPopupFrameForPoint(
707 nsPresContext
* aRootPresContext
, nsIWidget
* aWidget
,
708 const mozilla::LayoutDeviceIntPoint
& aPoint
,
709 GetPopupFrameForPointFlags aFlags
= GetPopupFrameForPointFlags(0));
712 * Get container and offset if aEvent collapses Selection.
713 * @param aPresShell The PresShell handling aEvent.
714 * @param aEvent The event having coordinates where you want to
715 * collapse Selection.
716 * @param aContainer Returns the container node at the point.
717 * Set nullptr if you don't need this.
718 * @param aOffset Returns offset in the container node at the point.
719 * Set nullptr if you don't need this.
722 static void GetContainerAndOffsetAtEvent(PresShell
* aPresShell
,
723 const mozilla::WidgetEvent
* aEvent
,
724 nsIContent
** aContainer
,
728 * Translate from widget coordinates to the view's coordinates
729 * @param aPresContext the PresContext for the view
730 * @param aWidget the widget
731 * @param aPt the point relative to the widget
732 * @param aView view to which returned coordinates are relative
733 * @return the point in the view's coordinates
735 static nsPoint
TranslateWidgetToView(nsPresContext
* aPresContext
,
737 const mozilla::LayoutDeviceIntPoint
& aPt
,
741 * Translate from view coordinates to the widget's coordinates.
742 * @param aPresContext the PresContext for the view
743 * @param aView the view
744 * @param aPt the point relative to the view
745 * @param aViewportType whether the point is in visual or layout coordinates
746 * @param aWidget the widget to which returned coordinates are relative
747 * @return the point in the view's coordinates
749 static mozilla::LayoutDeviceIntPoint
TranslateViewToWidget(
750 nsPresContext
* aPresContext
, nsView
* aView
, nsPoint aPt
,
751 ViewportType aViewportType
, nsIWidget
* aWidget
);
753 static mozilla::LayoutDeviceIntPoint
WidgetToWidgetOffset(
754 nsIWidget
* aFromWidget
, nsIWidget
* aToWidget
);
756 enum class FrameForPointOption
{
758 * When set, paint suppression is ignored, so we'll return non-root page
759 * elements even if paint suppression is stopping them from painting.
761 IgnorePaintSuppression
= 1,
763 * When set, clipping due to the root scroll frame (and any other viewport-
764 * related clipping) is ignored.
766 IgnoreRootScrollFrame
,
768 * When set, return only content in the same document as aFrame.
772 * When set, return only content that is actually visible.
777 struct FrameForPointOptions
{
778 using Bits
= mozilla::EnumSet
<FrameForPointOption
>;
781 // If mBits contains OnlyVisible, what is the opacity threshold which we
782 // consider "opaque enough" to clobber stuff underneath.
783 float mVisibleThreshold
;
785 FrameForPointOptions(Bits aBits
, float aVisibleThreshold
)
786 : mBits(aBits
), mVisibleThreshold(aVisibleThreshold
){};
788 MOZ_IMPLICIT
FrameForPointOptions(Bits aBits
)
789 : FrameForPointOptions(aBits
, 1.0f
) {}
791 FrameForPointOptions() : FrameForPointOptions(Bits()){};
795 * Given aFrame, the root frame of a stacking context, find its descendant
796 * frame under the point aPt that receives a mouse event at that location,
797 * or nullptr if there is no such frame.
798 * @param aPt the point, relative to the frame origin, in either visual
799 * or layout coordinates depending on aRelativeTo.mViewportType
801 static nsIFrame
* GetFrameForPoint(RelativeTo aRelativeTo
, nsPoint aPt
,
802 const FrameForPointOptions
& = {});
805 * Given aFrame, the root frame of a stacking context, find all descendant
806 * frames under the area of a rectangle that receives a mouse event,
807 * or nullptr if there is no such frame.
808 * @param aRect the rect, relative to the frame origin, in either visual
809 * or layout coordinates depending on aRelativeTo.mViewportType
810 * @param aOutFrames an array to add all the frames found
812 static nsresult
GetFramesForArea(RelativeTo aRelativeTo
, const nsRect
& aRect
,
813 nsTArray
<nsIFrame
*>& aOutFrames
,
814 const FrameForPointOptions
& = {});
817 * Transform aRect relative to aFrame up to the coordinate system of
818 * aAncestor. Computes the bounding-box of the true quadrilateral.
819 * Pass non-null aPreservesAxisAlignedRectangles and it will be set to true if
820 * we only need to use a 2d transform that PreservesAxisAlignedRectangles().
821 * The corner positions of aRect are treated as meaningful even if aRect is
824 * |aMatrixCache| allows for optimizations in recomputing the same matrix over
825 * and over. The argument can be one of the following values:
827 * nullptr (the default) - No optimization; the transform matrix is computed
828 * on every call to this function.
830 * non-null pointer to an empty Maybe<Matrix4x4> - Upon return, the Maybe is
831 * filled with the transform matrix that was computed. This can then be passed
832 * in to subsequent calls with the same source and destination frames to avoid
833 * recomputing the matrix.
835 * non-null pointer to a non-empty Matrix4x4 - The provided matrix will be
836 * used as the transform matrix and applied to the rect.
838 static nsRect
TransformFrameRectToAncestor(
839 const nsIFrame
* aFrame
, const nsRect
& aRect
, const nsIFrame
* aAncestor
,
840 bool* aPreservesAxisAlignedRectangles
= nullptr,
841 mozilla::Maybe
<Matrix4x4Flagged
>* aMatrixCache
= nullptr,
842 bool aStopAtStackingContextAndDisplayPortAndOOFFrame
= false,
843 nsIFrame
** aOutAncestor
= nullptr) {
844 return TransformFrameRectToAncestor(
845 aFrame
, aRect
, RelativeTo
{aAncestor
}, aPreservesAxisAlignedRectangles
,
846 aMatrixCache
, aStopAtStackingContextAndDisplayPortAndOOFFrame
,
849 static nsRect
TransformFrameRectToAncestor(
850 const nsIFrame
* aFrame
, const nsRect
& aRect
, RelativeTo aAncestor
,
851 bool* aPreservesAxisAlignedRectangles
= nullptr,
852 mozilla::Maybe
<Matrix4x4Flagged
>* aMatrixCache
= nullptr,
853 bool aStopAtStackingContextAndDisplayPortAndOOFFrame
= false,
854 nsIFrame
** aOutAncestor
= nullptr);
857 * Gets the transform for aFrame relative to aAncestor. Pass null for
858 * aAncestor to go up to the root frame. Including nsIFrame::IN_CSS_UNITS
859 * flag in aFlags will return CSS pixels, by default it returns device
861 * More info can be found in nsIFrame::GetTransformMatrix.
863 * Some notes on the possible combinations of |aFrame.mViewportType| and
864 * |aAncestor.mViewportType|:
866 * | aFrame. | aAncestor. | Notes
867 * | mViewportType | mViewportType |
868 * ==========================================================================
869 * | Layout | Layout | Commonplace, when both source and target
870 * | | | are inside zoom boundary.
872 * | | | Could also happen in non-e10s setups
873 * | | | when both source and target are outside
874 * | | | the zoom boundary and the code is
875 * | | | oblivious to the existence of a zoom
877 * ==========================================================================
878 * | Layout | Visual | Commonplace, used when hit testing visual
879 * | | | coordinates (e.g. coming from user input
880 * | | | events). We expected to encounter a
881 * | | | zoomed content root during traversal and
882 * | | | apply a layout-to-visual transform.
883 * ==========================================================================
884 * | Visual | Layout | Should never happen, will assert.
885 * ==========================================================================
886 * | Visual | Visual | In e10s setups, should only happen if
887 * | | | aFrame and aAncestor are both the
888 * | | | RCD viewport frame.
890 * | | | In non-e10s setups, could happen with
891 * | | | different frames if they are both
892 * | | | outside the zoom boundary.
893 * ==========================================================================
895 static Matrix4x4Flagged
GetTransformToAncestor(
896 RelativeTo aFrame
, RelativeTo aAncestor
, uint32_t aFlags
= 0,
897 nsIFrame
** aOutAncestor
= nullptr);
900 * Gets the scale factors of the transform for aFrame relative to the root
901 * frame if this transform can be drawn 2D, or the identity scale factors
904 static MatrixScales
GetTransformToAncestorScale(const nsIFrame
* aFrame
);
907 * Gets the scale factors of the transform for aFrame relative to the root
908 * frame if this transform is 2D, or the identity scale factors otherwise.
909 * If some frame on the path from aFrame to the display root frame may have an
910 * animated scale, returns the identity scale factors.
912 static MatrixScales
GetTransformToAncestorScaleExcludingAnimated(
916 * Gets a scale that includes CSS transforms in this process as well as the
917 * transform to ancestor scale passed down from our direct ancestor process
918 * (which includes any enclosing CSS transforms and resolution). Note: this
919 * does not include any resolution in the current process (this is on purpose
920 * because that is what the transform to ancestor field on FrameMetrics needs,
921 * see its definition for explanation as to why). This is the transform to
922 * ancestor scale to set on FrameMetrics.
924 static mozilla::ParentLayerToScreenScale2D
925 GetTransformToAncestorScaleCrossProcessForFrameMetrics(
926 const nsIFrame
* aFrame
);
929 * Find the nearest common ancestor frame for aFrame1 and aFrame2. The
930 * ancestor frame could be cross-doc.
932 static const nsIFrame
* FindNearestCommonAncestorFrame(
933 const nsIFrame
* aFrame1
, const nsIFrame
* aFrame2
);
936 * Find the nearest common ancestor frame for aFrame1 and aFrame2, assuming
937 * that they are within the same block.
939 * Returns null if they are not within the same block.
941 static const nsIFrame
* FindNearestCommonAncestorFrameWithinBlock(
942 const nsTextFrame
* aFrame1
, const nsTextFrame
* aFrame2
);
945 * Whether author-specified borders / backgrounds disable theming for a given
948 static bool AuthorSpecifiedBorderBackgroundDisablesTheming(
949 mozilla::StyleAppearance
);
952 * Transforms a list of CSSPoints from aFromFrame to aToFrame, taking into
953 * account all relevant transformations on the frames up to (but excluding)
954 * their nearest common ancestor.
955 * If we encounter a transform that we need to invert but which is
956 * non-invertible, we return NONINVERTIBLE_TRANSFORM. If the frames have
957 * no common ancestor, we return NO_COMMON_ANCESTOR.
958 * If this returns TRANSFORM_SUCCEEDED, the points in aPoints are transformed
959 * in-place, otherwise they are untouched.
961 enum TransformResult
{
964 NONINVERTIBLE_TRANSFORM
966 static TransformResult
TransformPoints(RelativeTo aFromFrame
,
968 uint32_t aPointCount
,
972 * Same as above function, but transform points in app units and
973 * handle 1 point per call.
975 static TransformResult
TransformPoint(RelativeTo aFromFrame
,
976 RelativeTo aToFrame
, nsPoint
& aPoint
);
979 * Transforms a rect from aFromFrame to aToFrame. In app units.
980 * Returns the bounds of the actual rect if the transform requires rotation
981 * or anything complex like that.
983 static TransformResult
TransformRect(const nsIFrame
* aFromFrame
,
984 const nsIFrame
* aToFrame
, nsRect
& aRect
);
987 * Converts app units to pixels (with optional snapping) and appends as a
988 * translation to aTransform.
990 static void PostTranslate(Matrix4x4
& aTransform
, const nsPoint
& aOrigin
,
991 float aAppUnitsPerPixel
, bool aRounded
);
994 * Whether the frame should snap to grid. This will end up being passed
995 * as the aRounded parameter in PostTranslate above. SVG frames should
996 * not have their translation rounded.
998 static bool ShouldSnapToGrid(const nsIFrame
* aFrame
);
1001 * Get the border-box of aElement's primary frame, transformed it to be
1002 * relative to aFrame.
1004 static nsRect
GetRectRelativeToFrame(mozilla::dom::Element
* aElement
,
1008 * Returns true if aRect with border inflation of size aInflateSize contains
1011 static bool ContainsPoint(const nsRect
& aRect
, const nsPoint
& aPoint
,
1012 nscoord aInflateSize
);
1015 * Clamp aRect relative to aFrame to the scroll frames boundary searching from
1018 static nsRect
ClampRectToScrollFrames(nsIFrame
* aFrame
, const nsRect
& aRect
);
1021 * Given a point in the global coordinate space, returns that point expressed
1022 * in the coordinate system of aFrame. This effectively inverts all
1023 * transforms between this point and the root frame.
1025 * @param aFromType Specifies whether |aPoint| is in layout or visual
1027 * @param aFrame The frame that acts as the coordinate space container.
1028 * @param aPoint The point, in global layout or visual coordinates (as per
1029 * |aFromType|, to get in the frame-local space.
1030 * @return aPoint, expressed in aFrame's canonical coordinate space.
1032 static nsPoint
TransformRootPointToFrame(ViewportType aFromType
,
1034 const nsPoint
& aPoint
) {
1035 return TransformAncestorPointToFrame(aFrame
, aPoint
,
1036 RelativeTo
{nullptr, aFromType
});
1040 * Transform aPoint relative to aAncestor down to the coordinate system of
1043 static nsPoint
TransformAncestorPointToFrame(RelativeTo aFrame
,
1044 const nsPoint
& aPoint
,
1045 RelativeTo aAncestor
);
1048 * Helper function that, given a rectangle and a matrix, returns the smallest
1049 * rectangle containing the image of the source rectangle.
1051 * @param aBounds The rectangle to transform.
1052 * @param aMatrix The matrix to transform it with.
1053 * @param aFactor The number of app units per graphics unit.
1054 * @return The smallest rect that contains the image of aBounds.
1056 static nsRect
MatrixTransformRect(const nsRect
& aBounds
,
1057 const Matrix4x4
& aMatrix
, float aFactor
);
1058 static nsRect
MatrixTransformRect(const nsRect
& aBounds
,
1059 const Matrix4x4Flagged
& aMatrix
,
1063 * Helper function that, given a point and a matrix, returns the image
1064 * of that point under the matrix transform.
1066 * @param aPoint The point to transform.
1067 * @param aMatrix The matrix to transform it with.
1068 * @param aFactor The number of app units per graphics unit.
1069 * @return The image of the point under the transform.
1071 static nsPoint
MatrixTransformPoint(const nsPoint
& aPoint
,
1072 const Matrix4x4
& aMatrix
, float aFactor
);
1075 * Given a graphics rectangle in graphics space, return a rectangle in
1076 * app space that contains the graphics rectangle, rounding out as necessary.
1078 * @param aRect The graphics rect to round outward.
1079 * @param aFactor The number of app units per graphics unit.
1080 * @return The smallest rectangle in app space that contains aRect.
1082 template <typename T
>
1083 static nsRect
RoundGfxRectToAppRect(const T
& aRect
, const float aFactor
);
1086 * Returns a subrectangle of aContainedRect that is entirely inside the
1087 * rounded rect. Complex cases are handled conservatively by returning a
1088 * smaller rect than necessary.
1090 static nsRegion
RoundedRectIntersectRect(const nsRect
& aRoundedRect
,
1091 const nscoord aRadii
[8],
1092 const nsRect
& aContainedRect
);
1093 static nsIntRegion
RoundedRectIntersectIntRect(
1094 const nsIntRect
& aRoundedRect
, const RectCornerRadii
& aCornerRadii
,
1095 const nsIntRect
& aContainedRect
);
1098 * Return whether any part of aTestRect is inside of the rounded
1099 * rectangle formed by aBounds and aRadii (which are indexed by the
1100 * enum HalfCorner constants in gfx/2d/Types.h). This is precise.
1102 static bool RoundedRectIntersectsRect(const nsRect
& aRoundedRect
,
1103 const nscoord aRadii
[8],
1104 const nsRect
& aTestRect
);
1106 enum class PaintFrameFlags
: uint32_t {
1108 SyncDecodeImages
= 0x02,
1109 WidgetLayers
= 0x04,
1110 IgnoreSuppression
= 0x08,
1111 DocumentRelative
= 0x10,
1114 ExistingTransaction
= 0x80,
1115 ForWebRender
= 0x100,
1116 UseHighQualityScaling
= 0x200,
1117 ResetViewportScrolling
= 0x400,
1121 * Given aFrame, the root frame of a stacking context, paint it and its
1122 * descendants to aRenderingContext.
1123 * @param aRenderingContext a rendering context translated so that (0,0)
1124 * is the origin of aFrame; for best results, (0,0) should transform
1125 * to pixel-aligned coordinates. This can be null, in which case
1126 * aFrame must be a "display root" (root frame for a root document,
1127 * or the root of a popup) with an associated widget and we draw using
1128 * the layer manager for the frame's widget.
1129 * @param aDirtyRegion the region that must be painted, in the coordinates
1131 * @param aBackstop paint the dirty area with this color before drawing
1132 * the actual content; pass NS_RGBA(0,0,0,0) to draw no background.
1133 * @param aBuilderMode Passed through to the display-list builder.
1134 * @param aFlags if PAINT_IN_TRANSFORM is set, then we assume
1135 * this is inside a transform or SVG foreignObject. If
1136 * PAINT_SYNC_DECODE_IMAGES is set, we force synchronous decode on all
1137 * images. If PAINT_WIDGET_LAYERS is set, aFrame must be a display root,
1138 * and we will use the frame's widget's layer manager to paint
1139 * even if aRenderingContext is non-null. This is useful if you want
1140 * to force rendering to use the widget's layer manager for testing
1141 * or speed. PAINT_WIDGET_LAYERS must be set if aRenderingContext is null.
1142 * If PAINT_DOCUMENT_RELATIVE is used, the visible region is interpreted
1143 * as being relative to the document (normally it's relative to the CSS
1144 * viewport) and the document is painted as if no scrolling has occured.
1145 * Only considered if PresShell::IgnoringViewportScrolling is true.
1146 * If ResetViewportScrolling is used, then the root scroll frame's scroll
1147 * position is set to 0 during painting, so that position:fixed elements
1148 * are drawn in their initial position.
1149 * PAINT_TO_WINDOW sets painting to window to true on the display list
1150 * builder even if we can't tell that we are painting to the window.
1151 * If PAINT_EXISTING_TRANSACTION is set, then BeginTransaction() has already
1152 * been called on aFrame's widget's layer manager and should not be
1154 * If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to
1155 * compressed mode to avoid short cut optimizations.
1157 * So there are three possible behaviours:
1158 * 1) PAINT_WIDGET_LAYERS is set and aRenderingContext is null; we paint
1159 * by calling BeginTransaction on the widget's layer manager.
1160 * 2) PAINT_WIDGET_LAYERS is set and aRenderingContext is non-null; we
1161 * paint by calling BeginTransactionWithTarget on the widget's layer
1163 * 3) PAINT_WIDGET_LAYERS is not set and aRenderingContext is non-null;
1164 * we paint by construct a BasicLayerManager and calling
1165 * BeginTransactionWithTarget on it. This is desirable if we're doing
1166 * something like drawWindow in a mode where what gets rendered doesn't
1167 * necessarily correspond to what's visible in the window; we don't
1168 * want to mess up the widget's layer tree.
1170 static void PaintFrame(gfxContext
* aRenderingContext
, nsIFrame
* aFrame
,
1171 const nsRegion
& aDirtyRegion
, nscolor aBackstop
,
1172 nsDisplayListBuilderMode aBuilderMode
,
1173 PaintFrameFlags aFlags
= PaintFrameFlags(0));
1176 * Uses a binary search for find where the cursor falls in the line of text
1177 * It also keeps track of the part of the string that has already been
1178 * measured so it doesn't have to keep measuring the same text over and over.
1180 * @param "aBaseWidth" contains the width in twips of the portion
1181 * of the text that has already been measured, and aBaseInx contains
1182 * the index of the text that has already been measured.
1184 * @param aTextWidth returns (in twips) the length of the text that falls
1185 * before the cursor aIndex contains the index of the text where the cursor
1188 static bool BinarySearchForPosition(DrawTarget
* aDrawTarget
,
1189 nsFontMetrics
& aFontMetrics
,
1190 const char16_t
* aText
, int32_t aBaseWidth
,
1191 int32_t aBaseInx
, int32_t aStartInx
,
1192 int32_t aEndInx
, int32_t aCursorPos
,
1193 int32_t& aIndex
, int32_t& aTextWidth
);
1197 BoxCallback() = default;
1198 virtual void AddBox(nsIFrame
* aFrame
) = 0;
1199 bool mIncludeCaptionBoxForTable
= true;
1200 // Whether we are in a continuation or ib-split-sibling of the target we're
1201 // measuring. This is useful because if we know we're in the target subtree
1202 // and measuring against it we can avoid finding the common ancestor.
1203 bool mInTargetContinuation
= false;
1206 * Collect all CSS boxes associated with aFrame and its
1207 * continuations, "drilling down" through table wrapper frames and
1208 * some anonymous blocks since they're not real CSS boxes.
1209 * If aFrame is null, no boxes are returned.
1210 * SVG frames return a single box, themselves.
1212 static void GetAllInFlowBoxes(nsIFrame
* aFrame
, BoxCallback
* aCallback
);
1215 * Like GetAllInFlowBoxes, but doesn't include continuations.
1217 static void AddBoxesForFrame(nsIFrame
* aFrame
, BoxCallback
* aCallback
);
1220 * Find the first frame descendant of aFrame (including aFrame) which is
1221 * not an anonymous frame that getBoxQuads/getClientRects should ignore.
1223 static nsIFrame
* GetFirstNonAnonymousFrame(nsIFrame
* aFrame
);
1225 struct RectAccumulator
: public mozilla::RectCallback
{
1228 bool mSeenFirstRect
;
1232 virtual void AddRect(const nsRect
& aRect
) override
;
1235 struct RectListBuilder
: public mozilla::RectCallback
{
1236 DOMRectList
* mRectList
;
1238 explicit RectListBuilder(DOMRectList
* aList
);
1239 virtual void AddRect(const nsRect
& aRect
) override
;
1242 static nsIFrame
* GetContainingBlockForClientRect(nsIFrame
* aFrame
);
1245 RECTS_ACCOUNT_FOR_TRANSFORMS
= 0x01,
1246 // Two bits for specifying which box type to use.
1247 // With neither bit set (default), use the border box.
1248 RECTS_USE_CONTENT_BOX
= 0x02,
1249 RECTS_USE_PADDING_BOX
= 0x04,
1250 RECTS_USE_MARGIN_BOX
= 0x06, // both bits set
1251 RECTS_WHICH_BOX_MASK
= 0x06 // bitmask for these two bits
1254 * Collect all CSS boxes (content, padding, border, or margin) associated
1255 * with aFrame and its continuations, "drilling down" through table wrapper
1256 * frames and some anonymous blocks since they're not real CSS boxes.
1257 * The boxes are positioned relative to aRelativeTo (taking scrolling
1258 * into account) and passed to the callback in frame-tree order.
1259 * If aFrame is null, no boxes are returned.
1260 * For SVG frames, returns one rectangle, the bounding box.
1261 * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting
1262 * the boxes into aRelativeTo coordinates, transforms (including CSS
1263 * and SVG transforms) are taken into account.
1264 * If aFlags includes one of RECTS_USE_CONTENT_BOX, RECTS_USE_PADDING_BOX,
1265 * or RECTS_USE_MARGIN_BOX, the corresponding type of box is used.
1266 * Otherwise (by default), the border box is used.
1268 static void GetAllInFlowRects(nsIFrame
* aFrame
, const nsIFrame
* aRelativeTo
,
1269 mozilla::RectCallback
* aCallback
,
1270 uint32_t aFlags
= 0);
1272 static void GetAllInFlowRectsAndTexts(
1273 nsIFrame
* aFrame
, const nsIFrame
* aRelativeTo
,
1274 mozilla::RectCallback
* aCallback
,
1275 mozilla::dom::Sequence
<nsString
>* aTextList
, uint32_t aFlags
= 0);
1278 * Computes the union of all rects returned by GetAllInFlowRects. If
1279 * the union is empty, returns the first rect.
1280 * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting
1281 * the boxes into aRelativeTo coordinates, transforms (including CSS
1282 * and SVG transforms) are taken into account.
1283 * If aFlags includes one of RECTS_USE_CONTENT_BOX, RECTS_USE_PADDING_BOX,
1284 * or RECTS_USE_MARGIN_BOX, the corresponding type of box is used.
1285 * Otherwise (by default), the border box is used.
1287 static nsRect
GetAllInFlowRectsUnion(nsIFrame
* aFrame
,
1288 const nsIFrame
* aRelativeTo
,
1289 uint32_t aFlags
= 0);
1291 enum { EXCLUDE_BLUR_SHADOWS
= 0x01 };
1293 * Takes a text-shadow array from the style properties of a given nsIFrame and
1294 * computes the union of those shadows along with the given initial rect.
1295 * If there are no shadows, the initial rect is returned.
1297 static nsRect
GetTextShadowRectsUnion(const nsRect
& aTextAndDecorationsRect
,
1298 nsIFrame
* aFrame
, uint32_t aFlags
= 0);
1301 * Computes the destination rect that a given replaced element should render
1302 * into, based on its CSS 'object-fit' and 'object-position' properties.
1304 * @param aConstraintRect The constraint rect that we have at our disposal,
1305 * which would e.g. be exactly filled by the image
1306 * if we had "object-fit: fill".
1307 * @param aIntrinsicSize The replaced content's intrinsic size, as reported
1308 * by nsIFrame::GetIntrinsicSize().
1309 * @param aIntrinsicRatio The replaced content's intrinsic ratio, as reported
1310 * by nsIFrame::GetIntrinsicRatio().
1311 * @param aStylePos The nsStylePosition struct that contains the 'object-fit'
1312 * and 'object-position' values that we should rely on.
1313 * (This should usually be the nsStylePosition for the
1314 * replaced element in question, but not always. For
1315 * example, a <video>'s poster-image has a dedicated
1316 * anonymous element & child-frame, but we should still use
1317 * the <video>'s 'object-fit' and 'object-position' values.)
1318 * @param aAnchorPoint [out] A point that should be pixel-aligned by functions
1319 * like nsLayoutUtils::DrawImage. See documentation
1320 * in nsCSSRendering.h for ComputeObjectAnchorPoint.
1321 * @return The nsRect into which we should render the replaced content (using
1322 * the same coordinate space as the passed-in aConstraintRect).
1324 static nsRect
ComputeObjectDestRect(const nsRect
& aConstraintRect
,
1325 const IntrinsicSize
& aIntrinsicSize
,
1326 const AspectRatio
& aIntrinsicRatio
,
1327 const nsStylePosition
* aStylePos
,
1328 nsPoint
* aAnchorPoint
= nullptr);
1331 * Get the font metrics corresponding to the frame's style data.
1332 * @param aFrame the frame
1333 * @param aSizeInflation number to multiply font size by
1335 static already_AddRefed
<nsFontMetrics
> GetFontMetricsForFrame(
1336 const nsIFrame
* aFrame
, float aSizeInflation
);
1338 static already_AddRefed
<nsFontMetrics
> GetInflatedFontMetricsForFrame(
1339 const nsIFrame
* aFrame
) {
1340 return GetFontMetricsForFrame(aFrame
, FontSizeInflationFor(aFrame
));
1344 * Get the font metrics corresponding to the given style data.
1345 * @param aComputedStyle the style data
1346 * @param aSizeInflation number to multiply font size by
1348 static already_AddRefed
<nsFontMetrics
> GetFontMetricsForComputedStyle(
1349 const ComputedStyle
* aComputedStyle
, nsPresContext
* aPresContext
,
1350 float aSizeInflation
= 1.0f
,
1351 uint8_t aVariantWidth
= NS_FONT_VARIANT_WIDTH_NORMAL
);
1354 * Get the font metrics of emphasis marks corresponding to the given
1355 * style data. The result is same as GetFontMetricsForComputedStyle
1356 * except that the font size is scaled down to 50%.
1357 * @param aComputedStyle the style data
1358 * @param aInflation number to multiple font size by
1360 static already_AddRefed
<nsFontMetrics
> GetFontMetricsOfEmphasisMarks(
1361 ComputedStyle
* aComputedStyle
, nsPresContext
* aPresContext
,
1363 return GetFontMetricsForComputedStyle(aComputedStyle
, aPresContext
,
1368 * Find the immediate child of aParent whose frame subtree contains
1369 * aDescendantFrame. Returns null if aDescendantFrame is not a descendant
1372 static nsIFrame
* FindChildContainingDescendant(nsIFrame
* aParent
,
1373 nsIFrame
* aDescendantFrame
);
1376 * Find the nearest ancestor that's a block
1378 static nsBlockFrame
* FindNearestBlockAncestor(nsIFrame
* aFrame
);
1381 * Find the nearest ancestor that's not for generated content. Will return
1382 * aFrame if aFrame is not for generated content.
1384 static nsIFrame
* GetNonGeneratedAncestor(nsIFrame
* aFrame
);
1387 * Whether the frame is an nsBlockFrame which is not a wrapper block.
1389 static bool IsNonWrapperBlock(nsIFrame
* aFrame
);
1392 * If aFrame is an out of flow frame, return its placeholder, otherwise
1393 * return its parent.
1395 static nsIFrame
* GetParentOrPlaceholderFor(const nsIFrame
* aFrame
);
1398 * If aFrame is an out of flow frame, return its placeholder, otherwise
1399 * return its (possibly cross-doc) parent.
1401 static nsIFrame
* GetParentOrPlaceholderForCrossDoc(const nsIFrame
* aFrame
);
1404 * Returns the frame that would act as the parent of aFrame when
1405 * descending through the frame tree in display list building.
1406 * Usually the same as GetParentOrPlaceholderForCrossDoc, except
1407 * that pushed floats are treated as children of their containing
1410 static nsIFrame
* GetDisplayListParent(nsIFrame
* aFrame
);
1413 * Get a frame's previous continuation, or, if it doesn't have one, its
1414 * previous block-in-inline-split sibling.
1416 static nsIFrame
* GetPrevContinuationOrIBSplitSibling(const nsIFrame
* aFrame
);
1419 * Get a frame's next continuation, or, if it doesn't have one, its
1420 * block-in-inline-split sibling.
1422 static nsIFrame
* GetNextContinuationOrIBSplitSibling(const nsIFrame
* aFrame
);
1425 * Get the first frame in the continuation-plus-ib-split-sibling chain
1426 * containing aFrame.
1428 static nsIFrame
* FirstContinuationOrIBSplitSibling(const nsIFrame
* aFrame
);
1431 * Get the last frame in the continuation-plus-ib-split-sibling chain
1432 * containing aFrame.
1434 static nsIFrame
* LastContinuationOrIBSplitSibling(const nsIFrame
* aFrame
);
1437 * Is FirstContinuationOrIBSplitSibling(aFrame) going to return
1440 static bool IsFirstContinuationOrIBSplitSibling(const nsIFrame
* aFrame
);
1443 * Check whether aFrame is a part of the scrollbar or scrollcorner of
1445 * @param aFrame the checking frame.
1446 * @return true if the frame is a part of the scrollbar or scrollcorner of
1449 static bool IsViewportScrollbarFrame(nsIFrame
* aFrame
);
1452 * Get the contribution of aFrame to its containing block's intrinsic
1453 * size for the given physical axis. This considers the child's intrinsic
1454 * width, its 'width', 'min-width', and 'max-width' properties (or 'height'
1455 * variations if that's what matches aAxis) and its padding, border and margin
1456 * in the corresponding dimension.
1457 * @param aPercentageBasis an optional percentage basis (in aFrame's WM).
1458 * If the basis is indefinite in a given axis, pass a size with
1459 * NS_UNCONSTRAINEDSIZE in that component.
1460 * If you pass Nothing() a percentage basis will be calculated from aFrame's
1461 * ancestors' computed size in the relevant axis, if needed.
1462 * @param aMarginBoxMinSizeClamp make the result fit within this margin-box
1463 * size by reducing the *content size* (flooring at zero). This is used for:
1464 * https://drafts.csswg.org/css-grid/#min-size-auto
1467 IGNORE_PADDING
= 0x01,
1468 BAIL_IF_REFLOW_NEEDED
= 0x02, // returns NS_INTRINSIC_ISIZE_UNKNOWN if so
1469 MIN_INTRINSIC_ISIZE
= 0x04, // use min-width/height instead of width/height
1471 static nscoord
IntrinsicForAxis(
1472 mozilla::PhysicalAxis aAxis
, gfxContext
* aRenderingContext
,
1473 nsIFrame
* aFrame
, mozilla::IntrinsicISizeType aType
,
1474 const mozilla::Maybe
<LogicalSize
>& aPercentageBasis
= mozilla::Nothing(),
1475 uint32_t aFlags
= 0, nscoord aMarginBoxMinSizeClamp
= NS_MAXSIZE
);
1477 * Calls IntrinsicForAxis with aFrame's parent's inline physical axis.
1479 static nscoord
IntrinsicForContainer(gfxContext
* aRenderingContext
,
1481 mozilla::IntrinsicISizeType aType
,
1482 uint32_t aFlags
= 0);
1485 * Get the definite size contribution of aFrame for the given physical axis.
1486 * This considers the child's 'min-width' property (or 'min-height' if the
1487 * given axis is vertical), and its padding, border, and margin in the
1488 * corresponding dimension. If the 'min-' property is 'auto' (and 'overflow'
1489 * is 'visible') and the corresponding 'width'/'height' is definite it returns
1490 * the "specified size" for:
1491 * https://drafts.csswg.org/css-grid/#min-size-auto
1492 * Note that the "transferred size" is not handled here; use IntrinsicForAxis.
1493 * Note that any percentage in 'width'/'height' makes it count as indefinite.
1494 * If the 'min-' property is 'auto' and 'overflow' is not 'visible', then it
1495 * calculates the result as if the 'min-' computed value is zero.
1496 * Otherwise, return NS_UNCONSTRAINEDSIZE.
1498 * @param aPercentageBasis the percentage basis (in aFrame's WM).
1499 * Pass NS_UNCONSTRAINEDSIZE if the basis is indefinite in either/both axes.
1500 * @note this behavior is specific to Grid/Flexbox (currently) so aFrame
1501 * should be a grid/flex item.
1503 static nscoord
MinSizeContributionForAxis(mozilla::PhysicalAxis aAxis
,
1504 gfxContext
* aRC
, nsIFrame
* aFrame
,
1505 mozilla::IntrinsicISizeType aType
,
1506 const LogicalSize
& aPercentageBasis
,
1507 uint32_t aFlags
= 0);
1510 * Convert LengthPercentage to nscoord when percentages depend on the
1511 * containing block size.
1512 * @param aPercentBasis The width or height of the containing block
1513 * (whichever the client wants to use for resolving percentages).
1515 static nscoord
ComputeCBDependentValue(nscoord aPercentBasis
,
1516 const LengthPercentage
& aCoord
) {
1518 aPercentBasis
!= NS_UNCONSTRAINEDSIZE
,
1519 "have unconstrained width or height; this should only result from very "
1520 "large sizes, not attempts at intrinsic size calculation");
1521 return aCoord
.Resolve(aPercentBasis
);
1523 static nscoord
ComputeCBDependentValue(nscoord aPercentBasis
,
1524 const LengthPercentageOrAuto
& aCoord
) {
1525 if (aCoord
.IsAuto()) {
1528 return ComputeCBDependentValue(aPercentBasis
, aCoord
.AsLengthPercentage());
1531 static nscoord
ComputeBSizeDependentValue(nscoord aContainingBlockBSize
,
1532 const LengthPercentageOrAuto
&);
1534 static nscoord
ComputeBSizeValue(nscoord aContainingBlockBSize
,
1535 nscoord aContentEdgeToBoxSizingBoxEdge
,
1536 const LengthPercentage
& aCoord
) {
1537 MOZ_ASSERT(aContainingBlockBSize
!= nscoord_MAX
|| !aCoord
.HasPercent(),
1538 "caller must deal with %% of unconstrained block-size");
1540 nscoord result
= aCoord
.Resolve(aContainingBlockBSize
);
1541 // Clamp calc(), and the subtraction for box-sizing.
1542 return std::max(0, result
- aContentEdgeToBoxSizingBoxEdge
);
1546 * The "extremum length" values (see ExtremumLength) were originally aimed at
1547 * inline-size (or width, as it was before logicalization). For now, we return
1548 * true for those here, so that we don't call ComputeBSizeValue with value
1549 * types that it doesn't understand. (See bug 1113216.)
1551 * FIXME (bug 567039, bug 527285)
1552 * This isn't correct for the 'fill' value or for the 'min-*' or 'max-*'
1553 * properties, which need to be handled differently by the callers of
1556 template <typename SizeOrMaxSize
>
1557 static bool IsAutoBSize(const SizeOrMaxSize
& aCoord
, nscoord aCBBSize
) {
1558 return aCoord
.BehavesLikeInitialValueOnBlockAxis() ||
1559 (aCBBSize
== nscoord_MAX
&& aCoord
.HasPercent());
1562 static bool IsPaddingZero(const LengthPercentage
& aLength
) {
1563 // clamp negative calc() to 0
1564 return aLength
.Resolve(nscoord_MAX
) <= 0 && aLength
.Resolve(0) <= 0;
1567 static bool IsMarginZero(const LengthPercentage
& aLength
) {
1568 return aLength
.Resolve(nscoord_MAX
) == 0 && aLength
.Resolve(0) == 0;
1571 static void MarkDescendantsDirty(nsIFrame
* aSubtreeRoot
);
1573 static void MarkIntrinsicISizesDirtyIfDependentOnBSize(nsIFrame
* aFrame
);
1576 * Calculate the used values for 'width' and 'height' when width
1577 * and height are 'auto'. The tentWidth and tentHeight arguments should be
1578 * the result of applying the rules for computing intrinsic sizes and ratios.
1579 * as specified by CSS 2.1 sections 10.3.2 and 10.6.2
1581 static nsSize
ComputeAutoSizeWithIntrinsicDimensions(
1582 nscoord minWidth
, nscoord minHeight
, nscoord maxWidth
, nscoord maxHeight
,
1583 nscoord tentWidth
, nscoord tentHeight
);
1585 // Implement nsIFrame::GetPrefISize in terms of nsIFrame::AddInlinePrefISize
1586 static nscoord
PrefISizeFromInline(nsIFrame
* aFrame
,
1587 gfxContext
* aRenderingContext
);
1589 // Implement nsIFrame::GetMinISize in terms of nsIFrame::AddInlineMinISize
1590 static nscoord
MinISizeFromInline(nsIFrame
* aFrame
,
1591 gfxContext
* aRenderingContext
);
1593 // Get a suitable foreground color for painting aColor for aFrame.
1594 static nscolor
DarkenColorIfNeeded(nsIFrame
* aFrame
, nscolor aColor
);
1596 // Get a suitable foreground color for painting aField for aFrame.
1597 // Type of aFrame is made a template parameter because nsIFrame is not
1598 // a complete type in the header. Type-safety is not harmed given that
1599 // DarkenColorIfNeeded requires an nsIFrame pointer.
1600 template <typename Frame
, typename T
, typename S
>
1601 static nscolor
GetColor(Frame
* aFrame
, T
S::*aField
) {
1602 nscolor color
= aFrame
->GetVisitedDependentColor(aField
);
1603 return DarkenColorIfNeeded(aFrame
, color
);
1606 // Get a baseline y position in app units that is snapped to device pixels.
1607 static gfxFloat
GetSnappedBaselineY(nsIFrame
* aFrame
, gfxContext
* aContext
,
1608 nscoord aY
, nscoord aAscent
);
1609 // Ditto for an x position (for vertical text). Note that for vertical-rl
1610 // writing mode, the ascent value should be negated by the caller.
1611 static gfxFloat
GetSnappedBaselineX(nsIFrame
* aFrame
, gfxContext
* aContext
,
1612 nscoord aX
, nscoord aAscent
);
1614 static nscoord
AppUnitWidthOfString(char16_t aC
, nsFontMetrics
& aFontMetrics
,
1615 DrawTarget
* aDrawTarget
) {
1616 return AppUnitWidthOfString(&aC
, 1, aFontMetrics
, aDrawTarget
);
1618 static nscoord
AppUnitWidthOfString(mozilla::Span
<const char16_t
> aString
,
1619 nsFontMetrics
& aFontMetrics
,
1620 DrawTarget
* aDrawTarget
) {
1621 return nsLayoutUtils::AppUnitWidthOfString(
1622 aString
.Elements(), aString
.Length(), aFontMetrics
, aDrawTarget
);
1624 static nscoord
AppUnitWidthOfString(const char16_t
* aString
, uint32_t aLength
,
1625 nsFontMetrics
& aFontMetrics
,
1626 DrawTarget
* aDrawTarget
);
1627 static nscoord
AppUnitWidthOfStringBidi(const nsString
& aString
,
1628 const nsIFrame
* aFrame
,
1629 nsFontMetrics
& aFontMetrics
,
1630 gfxContext
& aContext
) {
1631 return nsLayoutUtils::AppUnitWidthOfStringBidi(
1632 aString
.get(), aString
.Length(), aFrame
, aFontMetrics
, aContext
);
1634 static nscoord
AppUnitWidthOfStringBidi(const char16_t
* aString
,
1636 const nsIFrame
* aFrame
,
1637 nsFontMetrics
& aFontMetrics
,
1638 gfxContext
& aContext
);
1640 static bool StringWidthIsGreaterThan(const nsString
& aString
,
1641 nsFontMetrics
& aFontMetrics
,
1642 DrawTarget
* aDrawTarget
, nscoord aWidth
);
1644 static nsBoundingMetrics
AppUnitBoundsOfString(const char16_t
* aString
,
1646 nsFontMetrics
& aFontMetrics
,
1647 DrawTarget
* aDrawTarget
);
1649 static void DrawString(const nsIFrame
* aFrame
, nsFontMetrics
& aFontMetrics
,
1650 gfxContext
* aContext
, const char16_t
* aString
,
1651 int32_t aLength
, nsPoint aPoint
,
1652 ComputedStyle
* aComputedStyle
= nullptr,
1653 DrawStringFlags aFlags
= DrawStringFlags::Default
);
1655 static nsPoint
GetBackgroundFirstTilePos(const nsPoint
& aDest
,
1656 const nsPoint
& aFill
,
1657 const nsSize
& aRepeatSize
);
1660 * Supports only LTR or RTL. Bidi (mixed direction) is not supported.
1662 static void DrawUniDirString(const char16_t
* aString
, uint32_t aLength
,
1663 const nsPoint
& aPoint
,
1664 nsFontMetrics
& aFontMetrics
,
1665 gfxContext
& aContext
);
1668 * Helper function for drawing text-shadow. The callback's job
1669 * is to draw whatever needs to be blurred onto the given context.
1671 typedef void (*TextShadowCallback
)(gfxContext
* aCtx
, nsPoint aShadowOffset
,
1672 const nscolor
& aShadowColor
, void* aData
);
1674 static void PaintTextShadow(const nsIFrame
* aFrame
, gfxContext
* aContext
,
1675 const nsRect
& aTextRect
, const nsRect
& aDirtyRect
,
1676 const nscolor
& aForegroundColor
,
1677 TextShadowCallback aCallback
,
1678 void* aCallbackData
);
1681 * Gets the baseline to vertically center text from a font within a
1682 * line of specified height.
1683 * aIsInverted: true if the text is inverted relative to the block
1684 * direction, so that the block-dir "ascent" corresponds to font
1685 * descent. (Applies to sideways text in vertical-lr mode.)
1687 * Returns the baseline position relative to the top of the line.
1689 static nscoord
GetCenteredFontBaseline(nsFontMetrics
* aFontMetrics
,
1690 nscoord aLineHeight
, bool aIsInverted
);
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).
1697 * Returns true if a baseline was found (and fills in aResult).
1698 * Otherwise returns false.
1700 static bool GetFirstLineBaseline(mozilla::WritingMode aWritingMode
,
1701 const nsIFrame
* aFrame
, nscoord
* aResult
);
1704 * Just like GetFirstLineBaseline, except also returns the top and
1705 * bottom of the line with the baseline.
1707 * Returns true if a line was found (and fills in aResult).
1708 * Otherwise returns false.
1710 struct LinePosition
{
1711 nscoord mBStart
{nscoord_MAX
};
1712 nscoord mBaseline
{nscoord_MAX
};
1713 nscoord mBEnd
{nscoord_MAX
};
1715 LinePosition
operator+(nscoord aOffset
) const {
1716 LinePosition result
;
1717 result
.mBStart
= mBStart
+ aOffset
;
1718 result
.mBaseline
= mBaseline
+ aOffset
;
1719 result
.mBEnd
= mBEnd
+ aOffset
;
1723 static bool GetFirstLinePosition(mozilla::WritingMode aWritingMode
,
1724 const nsIFrame
* aFrame
,
1725 LinePosition
* aResult
);
1728 * Derive a baseline of |aFrame| (measured from its top border edge)
1729 * from its last in-flow line box (not descending into anything with
1730 * 'overflow' not 'visible', potentially including aFrame itself).
1732 * Returns true if a baseline was found (and fills in aResult).
1733 * Otherwise returns false.
1735 static bool GetLastLineBaseline(mozilla::WritingMode aWritingMode
,
1736 const nsIFrame
* aFrame
, nscoord
* aResult
);
1739 * Returns a block-dir coordinate relative to this frame's origin that
1740 * represents the logical block-end of the frame or its visible content,
1741 * whichever is further from the origin.
1742 * Relative positioning is ignored and margins and glyph bounds are not
1744 * This value will be >= mRect.BSize() and <= overflowRect.BEnd() unless
1745 * relative positioning is applied.
1747 static nscoord
CalculateContentBEnd(mozilla::WritingMode aWritingMode
,
1751 * Gets the closest frame (the frame passed in or one of its parents) that
1752 * qualifies as a "layer"; used in DOM0 methods that depends upon that
1753 * definition. This is the nearest frame that is either positioned or scrolled
1754 * (the child of a scroll frame).
1756 static nsIFrame
* GetClosestLayer(nsIFrame
* aFrame
);
1759 * Gets the graphics sampling filter for the frame
1761 static SamplingFilter
GetSamplingFilterForFrame(nsIFrame
* aFrame
);
1763 static inline void InitDashPattern(StrokeOptions
& aStrokeOptions
,
1764 mozilla::StyleBorderStyle aBorderStyle
) {
1765 if (aBorderStyle
== mozilla::StyleBorderStyle::Dotted
) {
1766 static Float dot
[] = {1.f
, 1.f
};
1767 aStrokeOptions
.mDashLength
= MOZ_ARRAY_LENGTH(dot
);
1768 aStrokeOptions
.mDashPattern
= dot
;
1769 } else if (aBorderStyle
== mozilla::StyleBorderStyle::Dashed
) {
1770 static Float dash
[] = {5.f
, 5.f
};
1771 aStrokeOptions
.mDashLength
= MOZ_ARRAY_LENGTH(dash
);
1772 aStrokeOptions
.mDashPattern
= dash
;
1774 aStrokeOptions
.mDashLength
= 0;
1775 aStrokeOptions
.mDashPattern
= nullptr;
1780 * Convert an nsRect to a gfxRect.
1782 static gfxRect
RectToGfxRect(const nsRect
& aRect
,
1783 int32_t aAppUnitsPerDevPixel
);
1785 static gfxPoint
PointToGfxPoint(const nsPoint
& aPoint
,
1786 int32_t aAppUnitsPerPixel
) {
1787 return gfxPoint(gfxFloat(aPoint
.x
) / aAppUnitsPerPixel
,
1788 gfxFloat(aPoint
.y
) / aAppUnitsPerPixel
);
1791 /* N.B. The only difference between variants of the Draw*Image
1792 * functions below is the type of the aImage argument.
1796 * Draw a background image. The image's dimensions are as specified in aDest;
1797 * the image itself is not consulted to determine a size.
1798 * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering
1801 * The context to draw to, already set up with an appropriate scale and
1802 * transform for drawing in app units.
1804 * The nsIFrame that we're drawing this image for.
1808 * The position and scaled area where one copy of the image should be drawn.
1809 * This area represents the image itself in its correct position as defined
1810 * with the background-position css property.
1812 * The area to be filled with copies of the image.
1813 * @param aRepeatSize
1814 * The distance between the positions of two subsequent repeats of the image.
1815 * Sizes larger than aDest.Size() create gaps between the images.
1817 * A point in aFill which we will ensure is pixel-aligned in the output.
1819 * Pixels outside this area may be skipped.
1820 * @param aImageFlags
1821 * Image flags of the imgIContainer::FLAG_* variety.
1822 * @param aExtendMode
1823 * How to extend the image over the dest rect.
1825 static ImgDrawResult
DrawBackgroundImage(
1826 gfxContext
& aContext
, nsIFrame
* aForFrame
, nsPresContext
* aPresContext
,
1827 imgIContainer
* aImage
, SamplingFilter aSamplingFilter
,
1828 const nsRect
& aDest
, const nsRect
& aFill
, const nsSize
& aRepeatSize
,
1829 const nsPoint
& aAnchor
, const nsRect
& aDirty
, uint32_t aImageFlags
,
1830 ExtendMode aExtendMode
, float aOpacity
);
1834 * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering
1835 * @param aRenderingContext Where to draw the image, set up with an
1836 * appropriate scale and transform for drawing in
1838 * @param aComputedStyle The ComputedStyle of the nsIFrame (or
1839 * pseudo-element) for which this image is being
1841 * @param aImage The image.
1842 * @param aDest Where one copy of the image should mapped to.
1843 * @param aFill The area to be filled with copies of the
1845 * @param aAnchor A point in aFill which we will ensure is
1846 * pixel-aligned in the output.
1847 * @param aDirty Pixels outside this area may be skipped.
1848 * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety
1850 static ImgDrawResult
DrawImage(gfxContext
& aContext
,
1851 ComputedStyle
* aComputedStyle
,
1852 nsPresContext
* aPresContext
,
1853 imgIContainer
* aImage
,
1854 const SamplingFilter aSamplingFilter
,
1855 const nsRect
& aDest
, const nsRect
& aFill
,
1856 const nsPoint
& aAnchor
, const nsRect
& aDirty
,
1857 uint32_t aImageFlags
, float aOpacity
= 1.0);
1860 * Draw a whole image without scaling or tiling.
1862 * @param aRenderingContext Where to draw the image, set up with an
1863 * appropriate scale and transform for drawing in
1865 * @param aImage The image.
1866 * @param aDest The top-left where the image should be drawn.
1867 * @param aDirty If non-null, then pixels outside this area may
1869 * @param aSVGContext Optionally provides an SVGImageContext.
1870 * Callers should pass an SVGImageContext with at
1871 * least the viewport size set if aImage may be of
1872 * type imgIContainer::TYPE_VECTOR, or pass
1873 * Nothing() if it is of type
1874 * imgIContainer::TYPE_RASTER (to save cycles
1875 * constructing an SVGImageContext, since this
1876 * argument will be ignored for raster images).
1877 * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety
1878 * @param aSourceArea If non-null, this area is extracted from
1879 * the image and drawn at aDest. It's
1880 * in appunits. For best results it should
1881 * be aligned with image pixels.
1883 static ImgDrawResult
DrawSingleUnscaledImage(
1884 gfxContext
& aContext
, nsPresContext
* aPresContext
, imgIContainer
* aImage
,
1885 const SamplingFilter aSamplingFilter
, const nsPoint
& aDest
,
1886 const nsRect
* aDirty
, const mozilla::SVGImageContext
& aSVGContext
,
1887 uint32_t aImageFlags
, const nsRect
* aSourceArea
= nullptr);
1890 * Draw a whole image without tiling.
1892 * @param aRenderingContext Where to draw the image, set up with an
1893 * appropriate scale and transform for drawing in
1895 * @param aImage The image.
1896 * @param aDest The area that the image should fill.
1897 * @param aDirty Pixels outside this area may be skipped.
1898 * @param aSVGContext Optionally provides an SVGImageContext.
1899 * Callers should pass an SVGImageContext with at
1900 * least the viewport size set if aImage may be of
1901 * type imgIContainer::TYPE_VECTOR, or pass
1902 * Nothing() if it is of type
1903 * imgIContainer::TYPE_RASTER (to save cycles
1904 * constructing an SVGImageContext, since this
1905 * argument will be ignored for raster images).
1906 * @param aImageFlags Image flags of the imgIContainer::FLAG_*
1908 * @param aAnchor If non-null, a point which we will ensure
1909 * is pixel-aligned in the output.
1911 static ImgDrawResult
DrawSingleImage(
1912 gfxContext
& aContext
, nsPresContext
* aPresContext
, imgIContainer
* aImage
,
1913 SamplingFilter aSamplingFilter
, const nsRect
& aDest
, const nsRect
& aDirty
,
1914 const mozilla::SVGImageContext
& aSVGContext
, uint32_t aImageFlags
,
1915 const nsPoint
* aAnchorPoint
= nullptr);
1918 * Given an imgIContainer, this method attempts to obtain an intrinsic
1919 * px-valued height & width for it. If the imgIContainer has a non-pixel
1920 * value for either height or width, this method tries to generate a pixel
1921 * value for that dimension using the intrinsic ratio (if available). The
1922 * intrinsic ratio will be assigned to aIntrinsicRatio; if there's no
1923 * intrinsic ratio then (0, 0) will be assigned.
1925 * This method will always set aGotWidth and aGotHeight to indicate whether
1926 * we were able to successfully obtain (or compute) a value for each
1929 * NOTE: This method is similar to ComputeSizeWithIntrinsicDimensions. The
1930 * difference is that this one is simpler and is suited to places where we
1931 * have less information about the frame tree.
1933 * @param aResolution The resolution specified by the author for the image, or
1934 * its intrinsic resolution.
1936 * This will affect the intrinsic size size of the image
1937 * (so e.g., if resolution is 2, and the image is 100x100,
1938 * the intrinsic size of the image will be 50x50).
1940 static void ComputeSizeForDrawing(imgIContainer
* aImage
,
1941 const mozilla::image::Resolution
&,
1942 CSSIntSize
& aImageSize
,
1943 AspectRatio
& aIntrinsicRatio
,
1944 bool& aGotWidth
, bool& aGotHeight
);
1947 * Given an imgIContainer, this method attempts to obtain an intrinsic
1948 * px-valued height & width for it. If the imgIContainer has a non-pixel
1949 * value for either height or width, this method tries to generate a pixel
1950 * value for that dimension using the intrinsic ratio (if available). If,
1951 * after trying all these methods, no value is available for one or both
1952 * dimensions, the corresponding dimension of aFallbackSize is used instead.
1954 static CSSIntSize
ComputeSizeForDrawingWithFallback(
1955 imgIContainer
* aImage
, const mozilla::image::Resolution
&,
1956 const nsSize
& aFallbackSize
);
1959 * Given the image container, frame, and dest rect, determine the best fitting
1960 * size to decode the image at, and calculate any necessary SVG parameters.
1962 static mozilla::gfx::IntSize
ComputeImageContainerDrawingParameters(
1963 imgIContainer
* aImage
, nsIFrame
* aForFrame
,
1964 const LayoutDeviceRect
& aDestRect
, const LayoutDeviceRect
& aFillRect
,
1965 const StackingContextHelper
& aSc
, uint32_t aFlags
,
1966 mozilla::SVGImageContext
& aSVGContext
,
1967 mozilla::Maybe
<mozilla::image::ImageIntRegion
>& aRegion
);
1970 * Given a source area of an image (in appunits) and a destination area
1971 * that we want to map that source area too, computes the area that
1972 * would be covered by the whole image. This is useful for passing to
1973 * the aDest parameter of DrawImage, when we want to draw a subimage
1974 * of an overall image.
1976 static nsRect
GetWholeImageDestination(const nsSize
& aWholeImageSize
,
1977 const nsRect
& aImageSourceArea
,
1978 const nsRect
& aDestArea
);
1981 * Given an image container and an orientation, returns an image container
1982 * that contains the same image, reoriented appropriately. May return the
1983 * original image container if no changes are needed.
1985 * @param aContainer The image container to apply the orientation to.
1986 * @param aOrientation The desired orientation.
1988 static already_AddRefed
<imgIContainer
> OrientImage(
1989 imgIContainer
* aContainer
,
1990 const mozilla::StyleImageOrientation
& aOrientation
);
1993 * Given an image request, determine if the request uses CORS.
1995 static bool ImageRequestUsesCORS(imgIRequest
* aRequest
);
1998 * Determine if any corner radius is of nonzero size
1999 * @param aCorners the |BorderRadius| object to check
2000 * @return true unless all the coordinates are 0%, 0 or null.
2002 * A corner radius with one dimension zero and one nonzero is
2003 * treated as a nonzero-radius corner, even though it will end up
2004 * being rendered like a zero-radius corner. This is because such
2005 * corners are not expected to appear outside of test cases, and it's
2006 * simpler to implement the test this way.
2008 static bool HasNonZeroCorner(const mozilla::BorderRadius
& aCorners
);
2011 * Determine if there is any corner radius on corners adjacent to the
2014 static bool HasNonZeroCornerOnSide(const mozilla::BorderRadius
& aCorners
,
2015 mozilla::Side aSide
);
2018 * Determine if a widget is likely to require transparency or translucency.
2019 * @param aBackgroundFrame The frame that the background is set on. For
2020 * <window>s, this will be the canvas frame.
2021 * @param aCSSRootFrame The frame that holds CSS properties affecting
2022 * the widget's transparency. For menupopups,
2023 * aBackgroundFrame and aCSSRootFrame will be the
2025 * @return a value suitable for passing to SetWindowTranslucency.
2027 using TransparencyMode
= mozilla::widget::TransparencyMode
;
2028 static TransparencyMode
GetFrameTransparency(nsIFrame
* aBackgroundFrame
,
2029 nsIFrame
* aCSSRootFrame
);
2032 * A frame is a popup if it has its own floating window. Menus, panels
2033 * and combobox dropdowns are popups.
2035 static bool IsPopup(const nsIFrame
* aFrame
);
2038 * Find the nearest "display root". This is the nearest enclosing
2039 * popup frame or the root prescontext's root frame.
2041 static nsIFrame
* GetDisplayRootFrame(nsIFrame
* aFrame
);
2042 static const nsIFrame
* GetDisplayRootFrame(const nsIFrame
* aFrame
);
2045 * Get the reference frame that would be used when constructing a
2046 * display item for this frame. Rather than using their own frame
2047 * as a reference frame.)
2049 * This duplicates some of the logic of GetDisplayRootFrame above and
2050 * of nsDisplayListBuilder::FindReferenceFrameFor.
2052 * If you have an nsDisplayListBuilder, you should get the reference
2053 * frame from it instead of calling this.
2055 static nsIFrame
* GetReferenceFrame(nsIFrame
* aFrame
);
2058 * Get textrun construction flags determined by a given style; in particular
2059 * some combination of:
2060 * -- TEXT_DISABLE_OPTIONAL_LIGATURES if letter-spacing is in use
2061 * -- TEXT_OPTIMIZE_SPEED if the text-rendering CSS property and font size
2062 * and prefs indicate we should be optimizing for speed over quality
2064 static mozilla::gfx::ShapedTextFlags
GetTextRunFlagsForStyle(
2065 const ComputedStyle
*, nsPresContext
*, const nsStyleFont
*,
2066 const nsStyleText
*, nscoord aLetterSpacing
);
2069 * Get orientation flags for textrun construction.
2071 static mozilla::gfx::ShapedTextFlags
GetTextRunOrientFlagsForStyle(
2072 const ComputedStyle
*);
2075 * Takes two rectangles whose origins must be the same, and computes
2076 * the difference between their union and their intersection as two
2077 * rectangles. (This difference is a superset of the difference
2078 * between the two rectangles.)
2080 static void GetRectDifferenceStrips(const nsRect
& aR1
, const nsRect
& aR2
,
2081 nsRect
* aHStrip
, nsRect
* aVStrip
);
2084 * Get a device context that can be used to get up-to-date device
2085 * dimensions for the given window. For some reason, this is more
2086 * complicated than it ought to be in multi-monitor situations.
2088 static nsDeviceContext
* GetDeviceContextForScreenInfo(
2089 nsPIDOMWindowOuter
* aWindow
);
2092 * Some frames with 'position: fixed' (nsStyleDisplay::mPosition ==
2093 * StylePositionProperty::Fixed) are not really fixed positioned, since
2094 * they're inside a transformed element or other element that establishes a
2095 * fixed-pos containing block). This function says whether such an element is
2096 * a real fixed-pos element.
2098 static bool IsReallyFixedPos(const nsIFrame
* aFrame
);
2101 * This function says whether `aFrame` would really be a fixed positioned
2102 * frame if the frame was created with StylePositionProperty::Fixed.
2104 * It is effectively the same as IsReallyFixedPos, but without asserting the
2105 * position value. Use it only when you know what you're doing, like when
2106 * tearing down the frame tree (where styles may have changed due to
2107 * ::first-line reparenting and rule changes at the same time).
2109 static bool MayBeReallyFixedPos(const nsIFrame
* aFrame
);
2112 * Returns true if |aFrame| is inside position:fixed subtree.
2114 static bool IsInPositionFixedSubtree(const nsIFrame
* aFrame
);
2117 * Obtain a SourceSurface from the given DOM element, if possible.
2118 * This obtains the most natural surface from the element; that
2119 * is, the one that can be obtained with the fewest conversions.
2121 * The flags below can modify the behaviour of this function. The
2122 * result is returned as a SurfaceFromElementResult struct, also
2125 * Currently, this will do:
2126 * - HTML Canvas elements: will return the underlying canvas surface
2127 * - HTML Video elements: will return the current video frame
2128 * - Image elements: will return the image
2130 * The above results are modified by the below flags (copying,
2131 * forcing image surface, etc.).
2135 /* Whether to extract the first frame (as opposed to the
2136 current frame) in the case that the element is an image. */
2137 SFE_WANT_FIRST_FRAME_IF_IMAGE
= 1 << 0,
2138 /* Whether we should skip colorspace/gamma conversion */
2139 SFE_NO_COLORSPACE_CONVERSION
= 1 << 1,
2140 /* Caller handles SFER::mAlphaType = NonPremult */
2141 SFE_ALLOW_NON_PREMULT
= 1 << 2,
2142 /* Whether we should skip getting a surface for vector images and
2143 return a DirectDrawInfo containing an imgIContainer instead. */
2144 SFE_NO_RASTERIZING_VECTORS
= 1 << 3,
2145 /* If image type is vector, the return surface size will same as
2146 element size, not image's intrinsic size. */
2147 SFE_USE_ELEMENT_SIZE_IF_VECTOR
= 1 << 4,
2148 /* Ensure that the returned surface has a size that matches the
2149 * SurfaceFromElementResult::mSize. This is mostly a convenience thing so
2150 * that callers who want this don't have to deal with it themselves.
2151 * The surface might be different for, e.g., a EXIF-scaled raster image, if
2152 * we don't rescale during decode. */
2153 SFE_EXACT_SIZE_SURFACE
= 1 << 6,
2154 /* Use orientation from image */
2155 SFE_ORIENTATION_FROM_IMAGE
= 1 << 7,
2156 /* Caller handles SFER::mCropRect.isSome() */
2157 SFE_ALLOW_UNCROPPED_UNSCALED
= 1 << 8,
2160 // This function can be called on any thread.
2161 static mozilla::SurfaceFromElementResult
SurfaceFromOffscreenCanvas(
2162 mozilla::dom::OffscreenCanvas
* aOffscreenCanvas
, uint32_t aSurfaceFlags
,
2163 RefPtr
<DrawTarget
>& aTarget
);
2164 static mozilla::SurfaceFromElementResult
SurfaceFromOffscreenCanvas(
2165 mozilla::dom::OffscreenCanvas
* aOffscreenCanvas
,
2166 uint32_t aSurfaceFlags
= 0) {
2167 RefPtr
<DrawTarget
> target
= nullptr;
2168 return SurfaceFromOffscreenCanvas(aOffscreenCanvas
, aSurfaceFlags
, target
);
2170 // This function can be called on any thread.
2171 static mozilla::SurfaceFromElementResult
SurfaceFromVideoFrame(
2172 mozilla::dom::VideoFrame
* aVideoFrame
, uint32_t aSurfaceFlags
,
2173 RefPtr
<DrawTarget
>& aTarget
);
2174 static mozilla::SurfaceFromElementResult
SurfaceFromVideoFrame(
2175 mozilla::dom::VideoFrame
* aVideoFrame
, uint32_t aSurfaceFlags
= 0) {
2176 RefPtr
<DrawTarget
> target
= nullptr;
2177 return SurfaceFromVideoFrame(aVideoFrame
, aSurfaceFlags
, target
);
2179 // This function can be called on any thread.
2180 static mozilla::SurfaceFromElementResult
SurfaceFromImageBitmap(
2181 mozilla::dom::ImageBitmap
* aImageBitmap
, uint32_t aSurfaceFlags
);
2183 static mozilla::SurfaceFromElementResult
SurfaceFromElement(
2184 mozilla::dom::Element
* aElement
,
2185 const mozilla::Maybe
<int32_t>& aResizeWidth
,
2186 const mozilla::Maybe
<int32_t>& aResizeHeight
, uint32_t aSurfaceFlags
,
2187 RefPtr
<DrawTarget
>& aTarget
);
2188 static mozilla::SurfaceFromElementResult
SurfaceFromElement(
2189 mozilla::dom::Element
* aElement
, uint32_t aSurfaceFlags
= 0) {
2190 RefPtr
<DrawTarget
> target
= nullptr;
2191 return SurfaceFromElement(aElement
, mozilla::Nothing(), mozilla::Nothing(),
2192 aSurfaceFlags
, target
);
2194 static mozilla::SurfaceFromElementResult
SurfaceFromElement(
2195 mozilla::dom::Element
* aElement
, uint32_t aSurfaceFlags
,
2196 RefPtr
<DrawTarget
>& aTarget
) {
2197 return SurfaceFromElement(aElement
, mozilla::Nothing(), mozilla::Nothing(),
2198 aSurfaceFlags
, aTarget
);
2200 static mozilla::SurfaceFromElementResult
SurfaceFromElement(
2201 mozilla::dom::Element
* aElement
,
2202 const mozilla::Maybe
<int32_t>& aResizeWidth
,
2203 const mozilla::Maybe
<int32_t>& aResizeHeight
,
2204 uint32_t aSurfaceFlags
= 0) {
2205 RefPtr
<DrawTarget
> target
= nullptr;
2206 return SurfaceFromElement(aElement
, aResizeWidth
, aResizeHeight
,
2207 aSurfaceFlags
, target
);
2210 // There are a bunch of callers of SurfaceFromElement. Just mark it as
2211 MOZ_CAN_RUN_SCRIPT_BOUNDARY
2212 static mozilla::SurfaceFromElementResult
SurfaceFromElement(
2213 nsIImageLoadingContent
* aElement
,
2214 const mozilla::Maybe
<int32_t>& aResizeWidth
,
2215 const mozilla::Maybe
<int32_t>& aResizeHeight
, uint32_t aSurfaceFlags
,
2216 RefPtr
<DrawTarget
>& aTarget
);
2217 // Need an HTMLImageElement overload, because otherwise the
2218 // nsIImageLoadingContent and mozilla::dom::Element overloads are ambiguous
2219 // for HTMLImageElement.
2220 static mozilla::SurfaceFromElementResult
SurfaceFromElement(
2221 mozilla::dom::HTMLImageElement
* aElement
, uint32_t aSurfaceFlags
,
2222 RefPtr
<DrawTarget
>& aTarget
);
2223 static mozilla::SurfaceFromElementResult
SurfaceFromElement(
2224 mozilla::dom::HTMLCanvasElement
* aElement
, uint32_t aSurfaceFlags
,
2225 RefPtr
<DrawTarget
>& aTarget
);
2226 static mozilla::SurfaceFromElementResult
SurfaceFromElement(
2227 mozilla::dom::HTMLCanvasElement
* aElement
, uint32_t aSurfaceFlags
) {
2228 RefPtr
<DrawTarget
> target
= nullptr;
2229 return SurfaceFromElement(aElement
, aSurfaceFlags
, target
);
2231 static mozilla::SurfaceFromElementResult
SurfaceFromElement(
2232 mozilla::dom::HTMLVideoElement
* aElement
, uint32_t aSurfaceFlags
,
2233 RefPtr
<DrawTarget
>& aTarget
);
2236 * When the document is editable by contenteditable attribute of its root
2237 * content or body content.
2239 * Be aware, this returns nullptr if it's in designMode.
2243 * <html contenteditable="true"><body></body></html>
2244 * returns the <html>.
2246 * <html><body contenteditable="true"></body></html>
2247 * <body contenteditable="true"></body>
2248 * With these cases, this returns the <body>.
2249 * NOTE: The latter case isn't created normally, however, it can be
2250 * created by script with XHTML.
2252 * <body><p contenteditable="true"></p></body>
2253 * returns nullptr because <body> isn't editable.
2255 static mozilla::dom::Element
* GetEditableRootContentByContentEditable(
2256 mozilla::dom::Document
* aDocument
);
2258 static void AddExtraBackgroundItems(nsDisplayListBuilder
* aBuilder
,
2259 nsDisplayList
* aList
, nsIFrame
* aFrame
,
2260 const nsRect
& aCanvasArea
,
2261 const nsRegion
& aVisibleRegion
,
2265 * Returns true if the passed in prescontext needs the dark grey background
2266 * that goes behind the page of a print preview presentation.
2268 static bool NeedsPrintPreviewBackground(nsPresContext
* aPresContext
);
2271 * Types used by the helpers for InspectorUtils.getUsedFontFaces.
2272 * The API returns an array (UsedFontFaceList) that owns the
2273 * InspectorFontFace instances, but during range traversal we also
2274 * want to maintain a mapping from gfxFontEntry to InspectorFontFace
2275 * records, so use a temporary hashtable for that.
2277 typedef nsTArray
<mozilla::UniquePtr
<mozilla::dom::InspectorFontFace
>>
2279 typedef nsTHashMap
<nsPtrHashKey
<gfxFontEntry
>,
2280 mozilla::dom::InspectorFontFace
*>
2284 * Adds all font faces used in the frame tree starting from aFrame
2285 * to the list aFontFaceList.
2286 * aMaxRanges: maximum number of text ranges to record for each face.
2288 static nsresult
GetFontFacesForFrames(nsIFrame
* aFrame
,
2289 UsedFontFaceList
& aResult
,
2290 UsedFontFaceTable
& aFontFaces
,
2291 uint32_t aMaxRanges
,
2292 bool aSkipCollapsedWhitespace
);
2295 * Adds all font faces used within the specified range of text in aFrame,
2296 * and optionally its continuations, to the list in aFontFaceList.
2297 * Pass 0 and INT32_MAX for aStartOffset and aEndOffset to specify the
2298 * entire text is to be considered.
2299 * aMaxRanges: maximum number of text ranges to record for each face.
2301 static void GetFontFacesForText(nsIFrame
* aFrame
, int32_t aStartOffset
,
2302 int32_t aEndOffset
, bool aFollowContinuations
,
2303 UsedFontFaceList
& aResult
,
2304 UsedFontFaceTable
& aFontFaces
,
2305 uint32_t aMaxRanges
,
2306 bool aSkipCollapsedWhitespace
);
2309 * Walks the frame tree starting at aFrame looking for textRuns.
2310 * If |clear| is true, just clears the TEXT_RUN_MEMORY_ACCOUNTED flag
2311 * on each textRun found (and |aMallocSizeOf| is not used).
2312 * If |clear| is false, adds the storage used for each textRun to the
2313 * total, and sets the TEXT_RUN_MEMORY_ACCOUNTED flag to avoid double-
2314 * accounting. (Runs with this flag already set will be skipped.)
2315 * Expected usage pattern is therefore to call twice:
2316 * (void)SizeOfTextRunsForFrames(rootFrame, nullptr, true);
2317 * total = SizeOfTextRunsForFrames(rootFrame, mallocSizeOf, false);
2319 static size_t SizeOfTextRunsForFrames(nsIFrame
* aFrame
,
2320 mozilla::MallocSizeOf aMallocSizeOf
,
2324 * Returns true if |aFrame| has an animation of a property in |aPropertySet|
2325 * regardless of whether any property in the set is overridden by an
2328 static bool HasAnimationOfPropertySet(const nsIFrame
* aFrame
,
2329 const nsCSSPropertyIDSet
& aPropertySet
);
2332 * A variant of the above HasAnimationOfPropertySet that takes an optional
2333 * EffectSet parameter as an optimization to save redundant lookups of the
2336 static bool HasAnimationOfPropertySet(const nsIFrame
* aFrame
,
2337 const nsCSSPropertyIDSet
& aPropertySet
,
2338 mozilla::EffectSet
* aEffectSet
);
2341 * A variant of the above HasAnimationOfPropertySet. This is especially for
2342 * tranform-like properties with motion-path.
2343 * For transform-like properties with motion-path, we need to check if
2344 * offset-path has effect. If we don't have any animation on offset-path and
2345 * offset-path is none, there is no effective motion-path, and so we don't
2346 * care other offset-* properties. In this case, this function only checks the
2347 * rest of transform-like properties (i.e. transform/translate/rotate/scale).
2349 static bool HasAnimationOfTransformAndMotionPath(const nsIFrame
* aFrame
);
2352 * Returns true if |aFrame| has an animation of |aProperty| which is
2353 * not overridden by !important rules.
2355 static bool HasEffectiveAnimation(const nsIFrame
* aFrame
,
2356 nsCSSPropertyID aProperty
);
2359 * Returns true if |aFrame| has an animation where at least one of the
2360 * properties in |aPropertySet| is not overridden by !important rules.
2362 * If |aPropertySet| includes transform-like properties (transform, rotate,
2363 * etc.) however, this will return false if any of the transform-like
2364 * properties is overriden by an !important rule since these properties should
2365 * be combined on the compositor.
2367 static bool HasEffectiveAnimation(const nsIFrame
* aFrame
,
2368 const nsCSSPropertyIDSet
& aPropertySet
);
2371 * Returns all effective animated CSS properties on |aStyleFrame| and its
2372 * corresponding primary frame (for content that makes this distinction,
2373 * notable display:table content) that can be animated on the compositor.
2375 * Properties that can be animated on the compositor but which are overridden
2376 * by !important rules are not returned.
2378 * Unlike HasEffectiveAnimation, however, this does not check the set of
2379 * transform-like properties to ensure that if any such properties are
2380 * overridden by !important rules, the other transform-like properties are
2381 * not run on the compositor (see bug 1534884).
2383 static nsCSSPropertyIDSet
GetAnimationPropertiesForCompositor(
2384 const nsIFrame
* aStyleFrame
);
2387 * Checks if off-main-thread animations are enabled.
2389 static bool AreAsyncAnimationsEnabled();
2392 * Checks if retained display lists are enabled.
2394 static bool AreRetainedDisplayListsEnabled();
2396 static bool DisplayRootHasRetainedDisplayListBuilder(nsIFrame
* aFrame
);
2398 static RetainedDisplayListBuilder
* GetRetainedDisplayListBuilder(
2402 * Find a suitable scale for a element (aFrame's content) over the course of
2403 * any animations and transitions of the CSS transform property on the element
2404 * that run on the compositor thread. It will check the maximum and minimum
2405 * scale during the animations and transitions and return a suitable value for
2406 * performance and quality. Will return scale(1,1) if there are no such
2407 * animations. Always returns a positive value.
2408 * @param aVisibleSize is the size of the area we want to paint
2409 * @param aDisplaySize is the size of the display area of the pres context
2411 static MatrixScales
ComputeSuitableScaleForAnimation(
2412 const nsIFrame
* aFrame
, const nsSize
& aVisibleSize
,
2413 const nsSize
& aDisplaySize
);
2416 * Checks whether we want to use the GPU to scale images when
2419 static bool GPUImageScalingEnabled();
2422 * Unions the overflow areas of the children of aFrame with aOverflowAreas.
2423 * aSkipChildLists specifies any child lists that should be skipped.
2424 * FrameChildListID::Popup is always skipped.
2426 static void UnionChildOverflow(
2427 nsIFrame
* aFrame
, mozilla::OverflowAreas
& aOverflowAreas
,
2428 mozilla::FrameChildListIDs aSkipChildLists
= {});
2431 * Return the font size inflation *ratio* for a given frame. This is
2432 * the factor by which font sizes should be inflated; it is never
2435 static float FontSizeInflationFor(const nsIFrame
* aFrame
);
2438 * Perform the first half of the computation of FontSizeInflationFor
2440 * This includes determining whether inflation should be performed
2441 * within this container and returning 0 if it should not be.
2443 * The result is guaranteed not to vary between line participants
2444 * (inlines, text frames) within a line.
2446 * The result should not be used directly since font sizes slightly
2447 * above the minimum should always be adjusted as done by
2448 * FontSizeInflationInner.
2450 static nscoord
InflationMinFontSizeFor(const nsIFrame
* aFrame
);
2453 * Perform the second half of the computation done by
2454 * FontSizeInflationFor (see above).
2456 * aMinFontSize must be the result of one of the
2457 * InflationMinFontSizeFor methods above.
2459 static float FontSizeInflationInner(const nsIFrame
* aFrame
,
2460 nscoord aMinFontSize
);
2462 static bool FontSizeInflationEnabled(nsPresContext
* aPresContext
);
2465 * Returns true if the nglayout.debug.invalidation pref is set to true.
2467 static bool InvalidationDebuggingIsEnabled() {
2468 return mozilla::StaticPrefs::nglayout_debug_invalidation() ||
2469 getenv("MOZ_DUMP_INVALIDATION") != 0;
2472 static void Initialize();
2473 static void Shutdown();
2476 * Register an imgIRequest object with a refresh driver.
2478 * @param aPresContext The nsPresContext whose refresh driver we want to
2480 * @param aRequest A pointer to the imgIRequest object which the client wants
2481 * to register with the refresh driver.
2482 * @param aRequestRegistered A pointer to a boolean value which indicates
2483 * whether the given image request is registered. If
2484 * *aRequestRegistered is true, then this request will not be
2485 * registered again. If the request is registered by this function,
2486 * then *aRequestRegistered will be set to true upon the completion of
2490 static void RegisterImageRequest(nsPresContext
* aPresContext
,
2491 imgIRequest
* aRequest
,
2492 bool* aRequestRegistered
);
2495 * Register an imgIRequest object with a refresh driver, but only if the
2496 * request is for an image that is animated.
2498 * @param aPresContext The nsPresContext whose refresh driver we want to
2500 * @param aRequest A pointer to the imgIRequest object which the client wants
2501 * to register with the refresh driver.
2502 * @param aRequestRegistered A pointer to a boolean value which indicates
2503 * whether the given image request is registered. If
2504 * *aRequestRegistered is true, then this request will not be
2505 * registered again. If the request is registered by this function,
2506 * then *aRequestRegistered will be set to true upon the completion of
2510 static void RegisterImageRequestIfAnimated(nsPresContext
* aPresContext
,
2511 imgIRequest
* aRequest
,
2512 bool* aRequestRegistered
);
2515 * Deregister an imgIRequest object from a refresh driver.
2517 * @param aPresContext The nsPresContext whose refresh driver we want to
2519 * @param aRequest A pointer to the imgIRequest object with which the client
2520 * previously registered and now wants to deregister from the refresh
2522 * @param aRequestRegistered A pointer to a boolean value which indicates
2523 * whether the given image request is registered. If
2524 * *aRequestRegistered is false, then this request will not be
2525 * deregistered. If the request is deregistered by this function,
2526 * then *aRequestRegistered will be set to false upon the completion of
2529 static void DeregisterImageRequest(nsPresContext
* aPresContext
,
2530 imgIRequest
* aRequest
,
2531 bool* aRequestRegistered
);
2534 * Shim to nsCSSFrameConstructor::PostRestyleEvent. Exists so that we
2535 * can avoid including nsCSSFrameConstructor.h and all its dependencies
2538 static void PostRestyleEvent(mozilla::dom::Element
*, mozilla::RestyleHint
,
2539 nsChangeHint aMinChangeHint
);
2542 * Updates a pair of x and y distances if a given point is closer to a given
2543 * rectangle than the original distance values. If aPoint is closer to
2544 * aRect than aClosestXDistance and aClosestYDistance indicate, then those
2545 * two variables are updated with the distance between aPoint and aRect,
2546 * and true is returned. If aPoint is not closer, then aClosestXDistance
2547 * and aClosestYDistance are left unchanged, and false is returned.
2549 * Distances are measured in the two dimensions separately; a closer x
2550 * distance beats a closer y distance.
2552 template <typename PointType
, typename RectType
, typename CoordType
>
2553 static bool PointIsCloserToRect(PointType aPoint
, const RectType
& aRect
,
2554 CoordType
& aClosestXDistance
,
2555 CoordType
& aClosestYDistance
);
2557 * Computes the box shadow rect for the frame, or returns an empty rect if
2558 * there are no shadows.
2560 * @param aFrame Frame to compute shadows for.
2561 * @param aFrameSize Size of aFrame (in case it hasn't been set yet).
2563 static nsRect
GetBoxShadowRectForFrame(nsIFrame
* aFrame
,
2564 const nsSize
& aFrameSize
);
2568 * Assert that there are no duplicate continuations of the same frame
2569 * within aFrameList. Optimize the tests by assuming that all frames
2570 * in aFrameList have parent aContainer.
2572 static void AssertNoDuplicateContinuations(nsIFrame
* aContainer
,
2573 const nsFrameList
& aFrameList
);
2576 * Assert that the frame tree rooted at |aSubtreeRoot| is empty, i.e.,
2577 * that it contains no first-in-flows.
2579 static void AssertTreeOnlyEmptyNextInFlows(nsIFrame
* aSubtreeRoot
);
2583 * Helper method to transform |aBounds| from aFrame to aAncestorFrame,
2584 * and combine it with |aPreciseTargetDest| if it is axis-aligned, or
2585 * combine it with |aImpreciseTargetDest| if not. The transformed rect is
2586 * clipped to |aClip|; if |aClip| has rounded corners, that also causes
2587 * the imprecise target to be used.
2589 static void TransformToAncestorAndCombineRegions(
2590 const nsRegion
& aRegion
, nsIFrame
* aFrame
, const nsIFrame
* aAncestorFrame
,
2591 nsRegion
* aPreciseTargetDest
, nsRegion
* aImpreciseTargetDest
,
2592 mozilla::Maybe
<Matrix4x4Flagged
>* aMatrixCache
,
2593 const mozilla::DisplayItemClip
* aClip
);
2596 * Populate aOutSize with the size of the content viewer corresponding
2597 * to the given prescontext. Return true if the size was set, false
2600 enum class SubtractDynamicToolbar
{ No
, Yes
};
2601 static bool GetDocumentViewerSize(
2602 const nsPresContext
* aPresContext
, LayoutDeviceIntSize
& aOutSize
,
2603 SubtractDynamicToolbar
= SubtractDynamicToolbar::Yes
);
2606 * Whether to include the dynamic toolbar area automatically (depending
2607 * whether the root container is scrollable or not) or forcibly in below
2608 * UpdateCompositionBoundsForRCDRSF and CalculateCompositionSizeForFrame
2611 enum class IncludeDynamicToolbar
{ Auto
, Force
};
2614 static bool UpdateCompositionBoundsForRCDRSF(
2615 mozilla::ParentLayerRect
& aCompBounds
, const nsPresContext
* aPresContext
,
2616 IncludeDynamicToolbar aIncludeDynamicToolbar
=
2617 IncludeDynamicToolbar::Auto
);
2621 * Calculate the compostion size for a frame. See FrameMetrics.h for
2622 * defintion of composition size (or bounds).
2623 * Note that for the root content document's root scroll frame (RCD-RSF),
2624 * the returned size does not change as the document's resolution changes,
2625 * but for all other frames it does. This means that callers that pass in
2626 * a frame that may or may not be the RCD-RSF (which is most callers),
2627 * are likely to need special-case handling of the RCD-RSF.
2629 static nsSize
CalculateCompositionSizeForFrame(
2630 nsIFrame
* aFrame
, bool aSubtractScrollbars
= true,
2631 const nsSize
* aOverrideScrollPortSize
= nullptr,
2632 IncludeDynamicToolbar aIncludeDynamicToolbar
=
2633 IncludeDynamicToolbar::Auto
);
2636 * Calculate a size suitable for bounding the size of the composition bounds
2637 * of scroll frames in the current process. This should be at most the
2638 * composition size of the cross-process RCD-RSF, but it may be a tighter
2640 * @param aFrame A frame in the (in-process) root content document (or a
2641 * descendant of it).
2642 * @param aIsRootContentDocRootScrollFrame Whether aFrame is the root
2643 * scroll frame of the *cross-process* root content document.
2644 * In this case we just use aFrame's own composition size.
2645 * @param aMetrics A partially populated FrameMetrics for aFrame. Must have at
2646 * least mCompositionBounds, mCumulativeResolution, and
2647 * mDevPixelsPerCSSPixel set.
2649 static CSSSize
CalculateBoundingCompositionSize(
2650 const nsIFrame
* aFrame
, bool aIsRootContentDocRootScrollFrame
,
2651 const FrameMetrics
& aMetrics
);
2654 * Calculate the scrollable rect for a frame. See FrameMetrics.h for
2655 * defintion of scrollable rect. aScrollableFrame is the scroll frame to
2656 * calculate the scrollable rect for. If it's null then we calculate the
2657 * scrollable rect as the rect of the root frame.
2659 static nsRect
CalculateScrollableRectForFrame(
2660 const nsIScrollableFrame
* aScrollableFrame
, const nsIFrame
* aRootFrame
);
2663 * Calculate the expanded scrollable rect for a frame. See FrameMetrics.h for
2664 * defintion of expanded scrollable rect.
2666 static nsRect
CalculateExpandedScrollableRect(nsIFrame
* aFrame
);
2669 * Returns true if the widget owning the given frame uses asynchronous
2672 static bool UsesAsyncScrolling(nsIFrame
* aFrame
);
2675 * Returns true if the widget owning the given frame has builtin APZ support
2678 static bool AsyncPanZoomEnabled(const nsIFrame
* aFrame
);
2681 * Returns true if aDocument should be allowed to use resolution
2684 static bool AllowZoomingForDocument(const mozilla::dom::Document
* aDocument
);
2687 * Returns true if we need to disable async scrolling for this particular
2688 * element. Note that this does a partial disabling - the displayport still
2689 * exists but uses a very small margin, and the compositor doesn't apply the
2690 * async transform. However, the content may still be layerized.
2692 static bool ShouldDisableApzForElement(nsIContent
* aContent
);
2695 * Log a key/value pair as "additional data" (not associated with a paint)
2697 * While the data is not associated with a paint, the APZTestData object
2698 * is still owned by {Client,WebRender}LayerManager, so we need to be passed
2699 * something from which we can derive the layer manager.
2700 * This function takes a display list builder as the object to derive the
2701 * layer manager from, to facilitate logging test data during display list
2702 * building, but other overloads that take other objects could be added if
2705 static void LogAdditionalTestData(nsDisplayListBuilder
* aBuilder
,
2706 const std::string
& aKey
,
2707 const std::string
& aValue
);
2710 * Log a key/value pair for APZ testing during a paint.
2711 * @param aManager The data will be written to the APZTestData associated
2712 * with this layer manager.
2713 * @param aScrollId Identifies the scroll frame to which the data pertains.
2714 * @param aKey The key under which to log the data.
2715 * @param aValue The value of the data to be logged.
2717 static void LogTestDataForPaint(
2718 mozilla::layers::WebRenderLayerManager
* aManager
, ViewID aScrollId
,
2719 const std::string
& aKey
, const std::string
& aValue
) {
2720 DoLogTestDataForPaint(aManager
, aScrollId
, aKey
, aValue
);
2724 * A convenience overload of LogTestDataForPaint() that accepts any type
2725 * as the value, and passes it through mozilla::ToString() to obtain a string
2726 * value. The type passed must support streaming to an std::ostream.
2728 template <typename Value
>
2729 static void LogTestDataForPaint(
2730 mozilla::layers::WebRenderLayerManager
* aManager
, ViewID aScrollId
,
2731 const std::string
& aKey
, const Value
& aValue
) {
2732 DoLogTestDataForPaint(aManager
, aScrollId
, aKey
, mozilla::ToString(aValue
));
2736 * Calculate a basic FrameMetrics with enough fields set to perform some
2737 * layout calculations. The fields set are dev-to-css ratio, pres shell
2738 * resolution, cumulative resolution, zoom, composition size, root
2739 * composition size, scroll offset and scrollable rect.
2741 * Note that for the RCD-RSF, the scroll offset returned is the layout
2742 * viewport offset; if you need the visual viewport offset, that needs to
2743 * be queried independently via PresShell::GetVisualViewportOffset().
2745 * By contrast, ComputeFrameMetrics() computes all the fields, but requires
2746 * extra inputs and can only be called during frame layer building.
2748 static FrameMetrics
CalculateBasicFrameMetrics(
2749 nsIScrollableFrame
* aScrollFrame
);
2751 static nsIScrollableFrame
* GetAsyncScrollableAncestorFrame(nsIFrame
* aTarget
);
2753 static void SetBSizeFromFontMetrics(
2754 const nsIFrame
* aFrame
, mozilla::ReflowOutput
& aMetrics
,
2755 const mozilla::LogicalMargin
& aFramePadding
, mozilla::WritingMode aLineWM
,
2756 mozilla::WritingMode aFrameWM
);
2758 static bool HasDocumentLevelListenersForApzAwareEvents(PresShell
* aPresShell
);
2761 * Returns true if the given scroll origin is "higher priority" than APZ.
2762 * In general any content programmatic scrolls (e.g. scrollTo calls) are
2763 * higher priority, and take precedence over APZ scrolling. This function
2764 * returns true for those, and returns false for other origins like APZ
2765 * itself, or scroll position updates from the history restore code.
2767 static bool CanScrollOriginClobberApz(ScrollOrigin aScrollOrigin
);
2769 static ScrollMetadata
ComputeScrollMetadata(
2770 const nsIFrame
* aForFrame
, const nsIFrame
* aScrollFrame
,
2771 nsIContent
* aContent
, const nsIFrame
* aItemFrame
,
2772 const nsPoint
& aOffsetToReferenceFrame
,
2773 mozilla::layers::WebRenderLayerManager
* aLayerManager
,
2774 ViewID aScrollParentId
, const nsSize
& aScrollPortSize
, bool aIsRoot
);
2777 * Returns the metadata to put onto the root layer of a layer tree, if one is
2778 * needed. The last argument is a callback function to check if the caller
2779 * already has a metadata for a given scroll id.
2781 static mozilla::Maybe
<ScrollMetadata
> GetRootMetadata(
2782 nsDisplayListBuilder
* aBuilder
,
2783 mozilla::layers::WebRenderLayerManager
* aLayerManager
,
2784 const std::function
<bool(ViewID
& aScrollId
)>& aCallback
);
2787 * If the given scroll frame needs an area excluded from its composition
2788 * bounds due to scrollbars, return that area, otherwise return an empty
2790 * There is no need to exclude scrollbars in the following cases:
2791 * - If the scroll frame is not the RCD-RSF; in that case, the composition
2792 * bounds is calculated based on the scroll port which already excludes
2793 * the scrollbar area.
2794 * - If the scrollbars are overlay, since then they are drawn on top of the
2795 * scrollable content.
2797 static nsMargin
ScrollbarAreaToExcludeFromCompositionBoundsFor(
2798 const nsIFrame
* aScrollFrame
);
2800 static bool ShouldUseNoFramesSheet(mozilla::dom::Document
*);
2803 * Get the text content inside the frame. This methods traverse the
2804 * frame tree and collect the content from text frames. Note that this
2805 * method is similiar to nsContentUtils::GetNodeTextContent, but it at
2806 * least differs from that method in the following things:
2807 * 1. it skips text content inside nodes like style, script, textarea
2808 * which don't generate an in-tree text frame for the text;
2809 * 2. it skips elements with display property set to none;
2810 * 3. it skips out-of-flow elements;
2811 * 4. it includes content inside pseudo elements;
2812 * 5. it may include part of text content of a node if a text frame
2813 * inside is split to different continuations.
2815 static void GetFrameTextContent(nsIFrame
* aFrame
, nsAString
& aResult
);
2818 * Same as GetFrameTextContent but appends the result rather than sets it.
2820 static void AppendFrameTextContent(nsIFrame
* aFrame
, nsAString
& aResult
);
2823 * Takes a selection, and returns selection's bounding rect which is relative
2824 * to its root frame.
2826 * @param aSel Selection to check
2828 static nsRect
GetSelectionBoundingRect(const mozilla::dom::Selection
* aSel
);
2831 * Calculate the bounding rect of |aContent|, relative to the origin
2832 * of the scrolled content of |aRootScrollFrame|.
2833 * Where the element is contained inside a scrollable subframe, the
2834 * bounding rect is clipped to the bounds of the subframe.
2835 * If non-null aOutNearestScrollClip will be filled in with the rect of the
2836 * nearest scroll frame (excluding aRootScrollFrame) that is an ancestor of
2837 * the frame of aContent, if such exists, in the same coords are the returned
2838 * rect. This rect is used to clip the result.
2840 static CSSRect
GetBoundingContentRect(
2841 const nsIContent
* aContent
, const nsIScrollableFrame
* aRootScrollFrame
,
2842 mozilla::Maybe
<CSSRect
>* aOutNearestScrollClip
= nullptr);
2845 * Similar to GetBoundingContentRect for nsIFrame.
2847 static CSSRect
GetBoundingFrameRect(
2848 nsIFrame
* aFrame
, const nsIScrollableFrame
* aRootScrollFrame
,
2849 mozilla::Maybe
<CSSRect
>* aOutNearestScrollClip
= nullptr);
2852 * Returns the first ancestor who is a float containing block.
2854 static nsBlockFrame
* GetFloatContainingBlock(nsIFrame
* aFrame
);
2857 * Walks up the frame tree from |aForFrame| up to |aTopFrame|, or to the
2858 * root of the frame tree if |aTopFrame| is nullptr, and returns true if
2859 * a transformed frame is encountered.
2861 static bool IsTransformed(nsIFrame
* aForFrame
, nsIFrame
* aTopFrame
= nullptr);
2864 * Walk up from aFrame to the cross-doc root, accumulating all the APZ
2865 * callback transforms on the content elements encountered along the way.
2866 * Return the accumulated value.
2867 * XXX: Note that this does not take into account CSS transforms, nor
2868 * differences in structure between the frame tree and the layer tree (which
2869 * is probably what we *want* to be computing).
2871 static CSSPoint
GetCumulativeApzCallbackTransform(nsIFrame
* aFrame
);
2874 * Compute a rect to pre-render in cases where we want to render more of
2875 * something than what is visible (usually to support async transformation).
2876 * @param aFrame the target frame to be pre-rendered
2877 * @param aDirtyRect the area that's visible in the coordinate system of
2879 * @param aOverflow the total size of the thing we're rendering in the
2880 * coordinate system of |aFrame|.
2881 * @param aPrerenderSize how large of an area we're willing to render in the
2882 * coordinate system of the root frame.
2883 * @return A rectangle that includes |aDirtyRect|, is clamped to |aOverflow|,
2884 * and is no larger than |aPrerenderSize| (unless |aPrerenderSize| is
2885 * smaller than |aDirtyRect|, in which case the returned rect will
2886 * still include |aDirtyRect| and thus be larger than
2887 * |aPrerenderSize|).
2889 static nsRect
ComputePartialPrerenderArea(nsIFrame
* aFrame
,
2890 const nsRect
& aDirtyRect
,
2891 const nsRect
& aOverflow
,
2892 const nsSize
& aPrerenderSize
);
2895 * Checks whether a node is an invisible break.
2896 * If not, returns the first frame on the next line if such a next line
2900 * true if the node is an invisible break. aNextLineFrame is returned null
2903 * false if the node causes a visible break or if the node is no break.
2905 * @param aNextLineFrame
2906 * assigned to first frame on the next line if such a next line exists, null
2909 static bool IsInvisibleBreak(nsINode
* aNode
,
2910 nsIFrame
** aNextLineFrame
= nullptr);
2912 static nsRect
ComputeSVGOriginBox(mozilla::dom::SVGViewportElement
*);
2914 // Compute the geometry box for SVG layout. The caller should map the CSS box
2915 // into the proper SVG box.
2916 // |aMayHaveCyclicDependency| is used for stroke-box to avoid the cyclic
2917 // dependency if any of its descendants uses non-scaling-stroke.
2918 enum class MayHaveNonScalingStrokeCyclicDependency
: bool { No
, Yes
};
2919 static nsRect
ComputeSVGReferenceRect(
2920 nsIFrame
*, StyleGeometryBox
,
2921 MayHaveNonScalingStrokeCyclicDependency
=
2922 MayHaveNonScalingStrokeCyclicDependency::No
);
2924 // Compute the geometry box for CSS layout. The caller should map the SVG box
2925 // into the proper CSS box.
2926 static nsRect
ComputeHTMLReferenceRect(const nsIFrame
*, StyleGeometryBox
);
2928 static nsRect
ComputeClipPathGeometryBox(
2929 nsIFrame
*, const mozilla::StyleShapeGeometryBox
&);
2931 static nsPoint
ComputeOffsetToUserSpace(nsDisplayListBuilder
* aBuilder
,
2934 // Callers are responsible to ensure the user-font-set is up-to-date if
2935 // aUseUserFontSet is true.
2936 static already_AddRefed
<nsFontMetrics
> GetMetricsFor(
2937 nsPresContext
* aPresContext
, bool aIsVertical
,
2938 const nsStyleFont
* aStyleFont
, mozilla::Length aFontSize
,
2939 bool aUseUserFontSet
);
2941 static void ComputeSystemFont(nsFont
* aSystemFont
,
2942 mozilla::StyleSystemFont aFontID
,
2943 const nsFont
& aDefaultVariableFont
,
2944 const mozilla::dom::Document
* aDocument
);
2946 static uint32_t ParseFontLanguageOverride(const nsAString
& aLangTag
);
2949 * Returns true if there are any preferences or overrides that indicate a
2950 * need to handle <meta name="viewport"> tags.
2952 static bool ShouldHandleMetaViewport(const mozilla::dom::Document
*);
2955 * Resolve a CSS <length-percentage> value to a definite size.
2957 template <bool clampNegativeResultToZero
>
2958 static nscoord
ResolveToLength(const LengthPercentage
& aLengthPercentage
,
2959 nscoord aPercentageBasis
) {
2960 nscoord value
= (aPercentageBasis
== NS_UNCONSTRAINEDSIZE
)
2961 ? aLengthPercentage
.Resolve(0)
2962 : aLengthPercentage
.Resolve(aPercentageBasis
);
2963 return clampNegativeResultToZero
? std::max(0, value
) : value
;
2967 * Resolve a column-gap/row-gap to a definite size.
2968 * @note This method resolves 'normal' to zero.
2969 * Callers who want different behavior should handle 'normal' on their own.
2971 static nscoord
ResolveGapToLength(
2972 const mozilla::NonNegativeLengthPercentageOrNormal
& aGap
,
2973 nscoord aPercentageBasis
) {
2974 if (aGap
.IsNormal()) {
2977 return ResolveToLength
<true>(aGap
.AsLengthPercentage(), aPercentageBasis
);
2981 * Get the computed style from which the scrollbar style should be
2982 * used for the given scrollbar part frame.
2984 static ComputedStyle
* StyleForScrollbar(const nsIFrame
* aScrollbarPart
);
2987 * Returns true if |aFrame| is scrolled out of view by a scrollable element in
2988 * a cross-process ancestor document.
2989 * Note this function only works for frames in out-of-process iframes.
2991 static bool FrameIsScrolledOutOfViewInCrossProcess(const nsIFrame
* aFrame
);
2994 * Similar to above FrameIsScrolledOutViewInCrossProcess but returns true even
2995 * if |aFrame| is not fully scrolled out of view and its visible area width or
2996 * height is smaller than |aMargin|.
2998 static bool FrameIsMostlyScrolledOutOfViewInCrossProcess(
2999 const nsIFrame
* aFrame
, nscoord aMargin
);
3002 * Expand the height of |aSize| to the size of `vh` units.
3004 * With dynamic toolbar(s) the height for `vh` units is greater than the
3005 * ICB height, we need to expand it in some places.
3007 static nsSize
ExpandHeightForViewportUnits(nsPresContext
* aPresContext
,
3008 const nsSize
& aSize
);
3010 static CSSSize
ExpandHeightForDynamicToolbar(
3011 const nsPresContext
* aPresContext
, const CSSSize
& aSize
);
3012 static nsSize
ExpandHeightForDynamicToolbar(const nsPresContext
* aPresContext
,
3013 const nsSize
& aSize
);
3016 * Returns the nsIFrame which clips overflow regions of the given |aFrame|.
3017 * Note CSS clip or clip-path isn't accounted for.
3019 static nsIFrame
* GetNearestOverflowClipFrame(nsIFrame
* aFrame
);
3022 * Returns true if the user's preferences allow for smooth scrolling.
3024 static bool IsSmoothScrollingEnabled();
3027 * Recompute the default value of general.smoothScroll based on
3028 * the system settings for prefers-reduced-motion.
3030 * Note: Must only be called from the main thread.
3032 static void RecomputeSmoothScrollDefault();
3036 * Helper function for LogTestDataForPaint().
3038 static void DoLogTestDataForPaint(
3039 mozilla::layers::WebRenderLayerManager
* aManager
, ViewID aScrollId
,
3040 const std::string
& aKey
, const std::string
& aValue
);
3042 static bool IsAPZTestLoggingEnabled();
3044 static void ConstrainToCoordValues(gfxFloat
& aStart
, gfxFloat
& aSize
);
3045 static void ConstrainToCoordValues(float& aStart
, float& aSize
);
3048 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsLayoutUtils::PaintFrameFlags
)
3049 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsLayoutUtils::GetPopupFrameForPointFlags
)
3051 template <typename PointType
, typename RectType
, typename CoordType
>
3052 /* static */ bool nsLayoutUtils::PointIsCloserToRect(
3053 PointType aPoint
, const RectType
& aRect
, CoordType
& aClosestXDistance
,
3054 CoordType
& aClosestYDistance
) {
3055 CoordType fromLeft
= aPoint
.x
- aRect
.x
;
3056 CoordType fromRight
= aPoint
.x
- aRect
.XMost();
3058 CoordType xDistance
;
3059 if (fromLeft
>= 0 && fromRight
<= 0) {
3062 xDistance
= std::min(abs(fromLeft
), abs(fromRight
));
3065 if (xDistance
<= aClosestXDistance
) {
3066 if (xDistance
< aClosestXDistance
) {
3067 aClosestYDistance
= std::numeric_limits
<CoordType
>::max();
3070 CoordType fromTop
= aPoint
.y
- aRect
.y
;
3071 CoordType fromBottom
= aPoint
.y
- aRect
.YMost();
3073 CoordType yDistance
;
3074 if (fromTop
>= 0 && fromBottom
<= 0) {
3077 yDistance
= std::min(abs(fromTop
), abs(fromBottom
));
3080 if (yDistance
< aClosestYDistance
) {
3081 aClosestXDistance
= xDistance
;
3082 aClosestYDistance
= yDistance
;
3090 template <typename T
>
3091 nsRect
nsLayoutUtils::RoundGfxRectToAppRect(const T
& aRect
,
3092 const float aFactor
) {
3093 // Get a new Rect whose units are app units by scaling by the specified
3095 T scaledRect
= aRect
;
3096 scaledRect
.ScaleRoundOut(aFactor
);
3098 // We now need to constrain our results to the max and min values for coords.
3099 ConstrainToCoordValues(scaledRect
.x
, scaledRect
.width
);
3100 ConstrainToCoordValues(scaledRect
.y
, scaledRect
.height
);
3102 if (!aRect
.Width()) {
3103 scaledRect
.SetWidth(0);
3106 if (!aRect
.Height()) {
3107 scaledRect
.SetHeight(0);
3110 // Now typecast everything back. This is guaranteed to be safe.
3111 return nsRect(nscoord(scaledRect
.X()), nscoord(scaledRect
.Y()),
3112 nscoord(scaledRect
.Width()), nscoord(scaledRect
.Height()));
3118 * Converts an nsPoint in app units to a Moz2D Point in pixels (whether those
3119 * are device pixels or CSS px depends on what the caller chooses to pass as
3120 * aAppUnitsPerPixel).
3122 inline gfx::Point
NSPointToPoint(const nsPoint
& aPoint
,
3123 int32_t aAppUnitsPerPixel
) {
3124 return gfx::Point(gfx::Float(aPoint
.x
) / aAppUnitsPerPixel
,
3125 gfx::Float(aPoint
.y
) / aAppUnitsPerPixel
);
3129 * Converts an nsRect in app units to a Moz2D Rect in pixels (whether those
3130 * are device pixels or CSS px depends on what the caller chooses to pass as
3131 * aAppUnitsPerPixel).
3133 gfx::Rect
NSRectToRect(const nsRect
& aRect
, double aAppUnitsPerPixel
);
3136 * Converts an nsRect in app units to a Moz2D Rect in pixels (whether those
3137 * are device pixels or CSS px depends on what the caller chooses to pass as
3138 * aAppUnitsPerPixel).
3140 * The passed DrawTarget is used to additionally snap the returned Rect to
3141 * device pixels, if appropriate (as decided and carried out by Moz2D's
3142 * MaybeSnapToDevicePixels helper, which this function calls to do any
3145 gfx::Rect
NSRectToSnappedRect(const nsRect
& aRect
, double aAppUnitsPerPixel
,
3146 const gfx::DrawTarget
& aSnapDT
);
3149 * Converts, where possible, an nsRect in app units to a Moz2D Rect in pixels
3150 * (whether those are device pixels or CSS px depends on what the caller
3151 * chooses to pass as aAppUnitsPerPixel).
3153 * If snapping results in a rectangle with zero width or height, the affected
3154 * coordinates are left unsnapped
3156 gfx::Rect
NSRectToNonEmptySnappedRect(const nsRect
& aRect
,
3157 double aAppUnitsPerPixel
,
3158 const gfx::DrawTarget
& aSnapDT
);
3160 void StrokeLineWithSnapping(
3161 const nsPoint
& aP1
, const nsPoint
& aP2
, int32_t aAppUnitsPerDevPixel
,
3162 gfx::DrawTarget
& aDrawTarget
, const gfx::Pattern
& aPattern
,
3163 const gfx::StrokeOptions
& aStrokeOptions
= gfx::StrokeOptions(),
3164 const gfx::DrawOptions
& aDrawOptions
= gfx::DrawOptions());
3169 * An RAII class which will, for the duration of its lifetime,
3170 * **if** the frame given is a container for font size inflation,
3171 * set the current inflation container on the pres context to null
3172 * (and then, in its destructor, restore the old value).
3174 class AutoMaybeDisableFontInflation
{
3176 explicit AutoMaybeDisableFontInflation(nsIFrame
* aFrame
);
3178 ~AutoMaybeDisableFontInflation();
3181 nsPresContext
* mPresContext
;
3185 } // namespace layout
3186 } // namespace mozilla
3188 class nsSetAttrRunnable
: public mozilla::Runnable
{
3190 nsSetAttrRunnable(mozilla::dom::Element
* aElement
, nsAtom
* aAttrName
,
3191 const nsAString
& aValue
);
3192 nsSetAttrRunnable(mozilla::dom::Element
* aElement
, nsAtom
* aAttrName
,
3197 RefPtr
<mozilla::dom::Element
> mElement
;
3198 RefPtr
<nsAtom
> mAttrName
;
3199 nsAutoString mValue
;
3202 class nsUnsetAttrRunnable
: public mozilla::Runnable
{
3204 nsUnsetAttrRunnable(mozilla::dom::Element
* aElement
, nsAtom
* aAttrName
);
3208 RefPtr
<mozilla::dom::Element
> mElement
;
3209 RefPtr
<nsAtom
> mAttrName
;
3212 // This class allows you to easily set any pointer variable and ensure it's
3213 // set to nullptr when leaving its scope.
3214 template <typename T
>
3215 class MOZ_RAII SetAndNullOnExit
{
3217 SetAndNullOnExit(T
*& aVariable
, T
* aValue
) {
3219 mVariable
= &aVariable
;
3221 ~SetAndNullOnExit() { *mVariable
= nullptr; }
3227 #endif // nsLayoutUtils_h__