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/ReflowOutput.h"
16 #include "mozilla/RelativeTo.h"
17 #include "mozilla/StaticPrefs_nglayout.h"
18 #include "mozilla/SVGImageContext.h"
19 #include "mozilla/ToString.h"
20 #include "mozilla/TypedEnumBits.h"
21 #include "mozilla/UniquePtr.h"
22 #include "mozilla/layout/FrameChildList.h"
23 #include "mozilla/layers/ScrollableLayerGuid.h"
24 #include "mozilla/gfx/2D.h"
25 #include "gfx2DGlue.h"
27 #include "nsBoundingMetrics.h"
28 #include "nsCSSPropertyIDSet.h"
29 #include "nsClassHashtable.h"
30 #include "nsGkAtoms.h"
31 #include "nsThreadUtils.h"
32 #include "ImageContainer.h" // for layers::Image
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 class nsDisplayListBuilder
;
55 enum class nsDisplayListBuilderMode
: uint8_t;
56 enum nsChangeHint
: uint32_t;
60 class nsIImageLoadingContent
;
62 class nsContainerFrame
;
65 class nsPIDOMWindowOuter
;
68 struct nsOverflowAreas
;
74 enum class PseudoStyleType
: uint8_t;
75 class EventListenerManager
;
76 enum class LayoutFrameType
: uint8_t;
78 struct ContainerLayerParameters
;
80 class DisplayItemClip
;
82 struct ActiveScrolledRoot
;
83 enum class ScrollOrigin
: uint8_t;
84 enum class StyleImageOrientation
: uint8_t;
86 class CanvasRenderingContext2D
;
91 class HTMLImageElement
;
92 class HTMLCanvasElement
;
93 class HTMLVideoElement
;
94 class InspectorFontFace
;
95 class OffscreenCanvas
;
99 struct RectCornerRadii
;
100 enum class ShapedTextFlags
: uint16_t;
104 struct ScrollMetadata
;
106 class StackingContextHelper
;
108 } // namespace layers
109 } // namespace mozilla
113 struct DisplayPortPropertyData
{
114 DisplayPortPropertyData(const nsRect
& aRect
, uint32_t aPriority
,
116 : mRect(aRect
), mPriority(aPriority
), mPainted(aPainted
) {}
122 struct DisplayPortMarginsPropertyData
{
123 DisplayPortMarginsPropertyData(const ScreenMargin
& aMargins
,
124 uint32_t aPriority
, bool aPainted
)
125 : mMargins(aMargins
), mPriority(aPriority
), mPainted(aPainted
) {}
126 ScreenMargin mMargins
;
131 } // namespace mozilla
133 // For GetDisplayPort
134 enum class DisplayportRelativeTo
{ ScrollPort
, ScrollFrame
};
136 // Flags to customize the behavior of nsLayoutUtils::DrawString.
137 enum class DrawStringFlags
{
139 ForceHorizontal
= 0x1 // Forces the text to be drawn horizontally.
141 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DrawStringFlags
)
144 * nsLayoutUtils is a namespace class used for various helper
145 * functions that are useful in multiple places in layout. The goal
146 * is not to define multiple copies of the same static helper.
148 class nsLayoutUtils
{
149 typedef mozilla::AspectRatio AspectRatio
;
150 typedef mozilla::ComputedStyle ComputedStyle
;
151 typedef mozilla::LengthPercentage LengthPercentage
;
152 typedef mozilla::LengthPercentageOrAuto LengthPercentageOrAuto
;
153 typedef mozilla::dom::DOMRectList DOMRectList
;
154 typedef mozilla::layers::Layer Layer
;
155 typedef mozilla::layers::StackingContextHelper StackingContextHelper
;
156 typedef mozilla::ContainerLayerParameters ContainerLayerParameters
;
157 typedef mozilla::IntrinsicSize IntrinsicSize
;
158 typedef mozilla::RelativeTo RelativeTo
;
159 typedef mozilla::ScrollOrigin ScrollOrigin
;
160 typedef mozilla::ViewportType ViewportType
;
161 typedef mozilla::gfx::SourceSurface SourceSurface
;
162 typedef mozilla::gfx::sRGBColor sRGBColor
;
163 typedef mozilla::gfx::DrawTarget DrawTarget
;
164 typedef mozilla::gfx::ExtendMode ExtendMode
;
165 typedef mozilla::gfx::SamplingFilter SamplingFilter
;
166 typedef mozilla::gfx::Float Float
;
167 typedef mozilla::gfx::Point Point
;
168 typedef mozilla::gfx::Rect Rect
;
169 typedef mozilla::gfx::RectDouble RectDouble
;
170 typedef mozilla::gfx::Size Size
;
171 typedef mozilla::gfx::Matrix4x4 Matrix4x4
;
172 typedef mozilla::gfx::Matrix4x4Flagged Matrix4x4Flagged
;
173 typedef mozilla::gfx::RectCornerRadii RectCornerRadii
;
174 typedef mozilla::gfx::StrokeOptions StrokeOptions
;
175 typedef mozilla::image::ImgDrawResult ImgDrawResult
;
178 typedef mozilla::layers::FrameMetrics FrameMetrics
;
179 typedef mozilla::layers::ScrollMetadata ScrollMetadata
;
180 typedef mozilla::layers::ScrollableLayerGuid::ViewID ViewID
;
181 typedef mozilla::CSSPoint CSSPoint
;
182 typedef mozilla::CSSSize CSSSize
;
183 typedef mozilla::CSSIntSize CSSIntSize
;
184 typedef mozilla::CSSRect CSSRect
;
185 typedef mozilla::ScreenMargin ScreenMargin
;
186 typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize
;
187 typedef mozilla::LayoutDeviceRect LayoutDeviceRect
;
188 typedef mozilla::PresShell PresShell
;
189 typedef mozilla::StyleGeometryBox StyleGeometryBox
;
190 typedef mozilla::SVGImageContext SVGImageContext
;
191 typedef mozilla::LogicalSize LogicalSize
;
194 * Finds previously assigned ViewID for the given content element, if any.
195 * Returns whether a ViewID was previously assigned.
197 static bool FindIDFor(const nsIContent
* aContent
, ViewID
* aOutViewId
);
200 * Finds previously assigned or generates a unique ViewID for the given
203 static ViewID
FindOrCreateIDFor(nsIContent
* aContent
);
206 * Find content for given ID.
208 static nsIContent
* FindContentFor(ViewID aId
);
211 * Find the scrollable frame for a given content element.
213 static nsIScrollableFrame
* FindScrollableFrameFor(nsIContent
* aContent
);
216 * Find the scrollable frame for a given ID.
218 static nsIScrollableFrame
* FindScrollableFrameFor(ViewID aId
);
221 * Find the ID for a given scrollable frame.
223 static ViewID
FindIDForScrollableFrame(nsIScrollableFrame
* aScrollable
);
226 * Get display port for the given element, relative to the specified entity,
227 * defaulting to the scrollport.
229 static bool GetDisplayPort(
230 nsIContent
* aContent
, nsRect
* aResult
,
231 DisplayportRelativeTo aRelativeTo
= DisplayportRelativeTo::ScrollPort
,
232 bool* aOutPainted
= nullptr);
235 * Check whether the given element has a displayport.
237 static bool HasDisplayPort(nsIContent
* aContent
);
240 * Check whether the given element has a displayport that has already
241 * been sent to the compositor via a layers or WR transaction.
243 static bool HasPaintedDisplayPort(nsIContent
* aContent
);
246 * Mark the displayport of a given element as having been sent to
247 * the compositor via a layers or WR transaction.
249 static void MarkDisplayPortAsPainted(nsIContent
* aContent
);
252 * Check whether the given frame has a displayport. It returns false
253 * for scrolled frames and true for the corresponding scroll frame.
254 * Optionally pass the child, and it only returns true if the child is the
255 * scrolled frame for the displayport.
257 static bool FrameHasDisplayPort(nsIFrame
* aFrame
,
258 const nsIFrame
* aScrolledFrame
= nullptr);
261 * Check if the given element has a margins based displayport but is missing a
262 * displayport base rect that it needs to properly compute a displayport rect.
264 static bool IsMissingDisplayPortBaseRect(nsIContent
* aContent
);
267 * Go through the IPC Channel and update displayport margins for content
268 * elements based on UpdateFrame messages. The messages are left in the
269 * queue and will be fully processed when dequeued. The aim is to paint
270 * the most up-to-date displayport without waiting for these message to
271 * go through the message queue.
273 static void UpdateDisplayPortMarginsFromPendingMessages();
276 * @return the display port for the given element which should be used for
277 * visibility testing purposes.
279 * If low-precision buffers are enabled, this is the critical display port;
280 * otherwise, it's the same display port returned by GetDisplayPort().
282 static bool GetDisplayPortForVisibilityTesting(
283 nsIContent
* aContent
, nsRect
* aResult
,
284 DisplayportRelativeTo aRelativeTo
= DisplayportRelativeTo::ScrollPort
);
286 enum class RepaintMode
: uint8_t { Repaint
, DoNotRepaint
};
289 * Invalidate for displayport change.
291 static void InvalidateForDisplayPortChange(
292 nsIContent
* aContent
, bool aHadDisplayPort
, const nsRect
& aOldDisplayPort
,
293 const nsRect
& aNewDisplayPort
,
294 RepaintMode aRepaintMode
= RepaintMode::Repaint
);
297 * Set the display port margins for a content element to be used with a
298 * display port base (see SetDisplayPortBase()).
299 * See also nsIDOMWindowUtils.setDisplayPortMargins.
300 * @param aContent the content element for which to set the margins
301 * @param aPresShell the pres shell for the document containing the element
302 * @param aMargins the margins to set
303 * @param aAlignmentX, alignmentY the amount of pixels to which to align the
304 * displayport built by combining the base
305 * rect with the margins, in either direction
306 * @param aPriority a priority value to determine which margins take effect
307 * when multiple callers specify margins
308 * @param aRepaintMode whether to schedule a paint after setting the margins
309 * @return true if the new margins were applied.
311 static bool SetDisplayPortMargins(
312 nsIContent
* aContent
, PresShell
* aPresShell
, const ScreenMargin
& aMargins
,
313 uint32_t aPriority
= 0, RepaintMode aRepaintMode
= RepaintMode::Repaint
);
316 * Set the display port base rect for given element to be used with display
318 * SetDisplayPortBaseIfNotSet is like SetDisplayPortBase except it only sets
319 * the display port base to aBase if no display port base is currently set.
321 static void SetDisplayPortBase(nsIContent
* aContent
, const nsRect
& aBase
);
322 static void SetDisplayPortBaseIfNotSet(nsIContent
* aContent
,
323 const nsRect
& aBase
);
326 * Get the critical display port for the given element.
328 static bool GetCriticalDisplayPort(nsIContent
* aContent
, nsRect
* aResult
,
329 bool* aOutPainted
= nullptr);
332 * Check whether the given element has a critical display port.
334 static bool HasCriticalDisplayPort(nsIContent
* aContent
);
337 * If low-precision painting is turned on, delegates to
338 * GetCriticalDisplayPort. Otherwise, delegates to GetDisplayPort.
340 static bool GetHighResolutionDisplayPort(nsIContent
* aContent
,
342 bool* aOutPainted
= nullptr);
345 * Remove the displayport for the given element.
347 static void RemoveDisplayPort(nsIContent
* aContent
);
350 * Notify the scroll frame with the given scroll id that its scroll offset
351 * is being sent to APZ as part of a paint-skip transaction.
353 * Normally, this notification happens during painting, after calls to
354 * ComputeScrollMetadata(). During paint-skipping that code is skipped,
355 * but it's still important for the scroll frame to be notified for
356 * correctness of relative scroll updates, so the code that sends the
357 * empty paint-skip transaction needs to call this.
359 static void NotifyPaintSkipTransaction(ViewID aScrollId
);
362 * Use heuristics to figure out the child list that
363 * aChildFrame is currently in.
365 static mozilla::layout::FrameChildListID
GetChildListNameFor(
366 nsIFrame
* aChildFrame
);
369 * Returns the ::before pseudo-element for aContent, if any.
371 static mozilla::dom::Element
* GetBeforePseudo(const nsIContent
* aContent
);
374 * Returns the frame corresponding to the ::before pseudo-element for
377 static nsIFrame
* GetBeforeFrame(const nsIContent
* aContent
);
380 * Returns the ::after pseudo-element for aContent, if any.
382 static mozilla::dom::Element
* GetAfterPseudo(const nsIContent
* aContent
);
385 * Returns the frame corresponding to the ::after pseudo-element for aContent,
388 static nsIFrame
* GetAfterFrame(const nsIContent
* aContent
);
391 * Returns the ::marker pseudo-element for aContent, if any.
393 static mozilla::dom::Element
* GetMarkerPseudo(const nsIContent
* aContent
);
396 * Returns the frame corresponding to the ::marker pseudo-element for
399 static nsIFrame
* GetMarkerFrame(const nsIContent
* aContent
);
402 * Given a frame, search up the frame tree until we find an
403 * ancestor that (or the frame itself) is of type aFrameType, if any.
405 * @param aFrame the frame to start at
406 * @param aFrameType the frame type to look for
407 * @param aStopAt a frame to stop at after we checked it
408 * @return a frame of the given type or nullptr if no
409 * such ancestor exists
411 static nsIFrame
* GetClosestFrameOfType(nsIFrame
* aFrame
,
412 mozilla::LayoutFrameType aFrameType
,
413 nsIFrame
* aStopAt
= nullptr);
416 * Given a frame, search up the frame tree until we find an
417 * ancestor that (or the frame itself) is a "Page" frame, if any.
419 * @param aFrame the frame to start at
420 * @return a frame of type mozilla::LayoutFrameType::Page or nullptr if no
421 * such ancestor exists
423 static nsIFrame
* GetPageFrame(nsIFrame
* aFrame
);
426 * Given a frame which is the primary frame for an element,
427 * return the frame that has the non-pseudoelement ComputedStyle for
429 * This is aPrimaryFrame itself except for tableWrapper frames.
431 * Given a non-null input, this will return null if and only if its
432 * argument is a table wrapper frame that is mid-destruction (and its
433 * table frame has been destroyed).
435 static nsIFrame
* GetStyleFrame(nsIFrame
* aPrimaryFrame
);
436 static const nsIFrame
* GetStyleFrame(const nsIFrame
* aPrimaryFrame
);
439 * Given a content node,
440 * return the frame that has the non-pseudoelement ComputedStyle for
441 * the content. May return null.
442 * This is aContent->GetPrimaryFrame() except for tableWrapper frames.
444 static nsIFrame
* GetStyleFrame(const nsIContent
* aContent
);
447 * The inverse of GetStyleFrame. Returns |aStyleFrame| unless it is an inner
448 * table frame, in which case the table wrapper frame is returned.
450 static nsIFrame
* GetPrimaryFrameFromStyleFrame(nsIFrame
* aStyleFrame
);
451 static const nsIFrame
* GetPrimaryFrameFromStyleFrame(
452 const nsIFrame
* aStyleFrame
);
455 * Similar to nsIFrame::IsPrimaryFrame except that this will return true
456 * for the inner table frame rather than for its wrapper frame.
458 static bool IsPrimaryStyleFrame(const nsIFrame
* aFrame
);
461 // TODO: remove, see bug 598468.
462 static bool gPreventAssertInCompareTreePosition
;
466 * CompareTreePosition determines whether aContent1 comes before or
467 * after aContent2 in a preorder traversal of the content tree.
469 * @param aCommonAncestor either null, or a common ancestor of
470 * aContent1 and aContent2. Actually this is
471 * only a hint; if it's not an ancestor of
472 * aContent1 or aContent2, this function will
473 * still work, but it will be slower than
475 * @return < 0 if aContent1 is before aContent2
476 * > 0 if aContent1 is after aContent2,
477 * 0 otherwise (meaning they're the same, or they're in
478 * different documents)
480 static int32_t CompareTreePosition(
481 nsIContent
* aContent1
, nsIContent
* aContent2
,
482 const nsIContent
* aCommonAncestor
= nullptr) {
483 return DoCompareTreePosition(aContent1
, aContent2
, -1, 1, aCommonAncestor
);
487 * More generic version of |CompareTreePosition|. |aIf1Ancestor|
488 * gives the value to return when 1 is an ancestor of 2, and likewise
489 * for |aIf2Ancestor|. Passing (-1, 1) gives preorder traversal
490 * order, and (1, -1) gives postorder traversal order.
492 static int32_t DoCompareTreePosition(
493 nsIContent
* aContent1
, nsIContent
* aContent2
, int32_t aIf1Ancestor
,
494 int32_t aIf2Ancestor
, const nsIContent
* aCommonAncestor
= nullptr);
497 * CompareTreePosition determines whether aFrame1 comes before or
498 * after aFrame2 in a preorder traversal of the frame tree, where out
499 * of flow frames are treated as children of their placeholders. This is
500 * basically the same ordering as DoCompareTreePosition(nsIContent*) except
501 * that it handles anonymous content properly and there are subtleties with
504 * @param aCommonAncestor either null, or a common ancestor of
505 * aContent1 and aContent2. Actually this is
506 * only a hint; if it's not an ancestor of
507 * aContent1 or aContent2, this function will
508 * still work, but it will be slower than
510 * @return < 0 if aContent1 is before aContent2
511 * > 0 if aContent1 is after aContent2,
512 * 0 otherwise (meaning they're the same, or they're in
513 * different frame trees)
515 static int32_t CompareTreePosition(nsIFrame
* aFrame1
, nsIFrame
* aFrame2
,
516 nsIFrame
* aCommonAncestor
= nullptr) {
517 return DoCompareTreePosition(aFrame1
, aFrame2
, -1, 1, aCommonAncestor
);
520 static int32_t CompareTreePosition(nsIFrame
* aFrame1
, nsIFrame
* aFrame2
,
521 nsTArray
<nsIFrame
*>& aFrame2Ancestors
,
522 nsIFrame
* aCommonAncestor
= nullptr) {
523 return DoCompareTreePosition(aFrame1
, aFrame2
, aFrame2Ancestors
, -1, 1,
528 * More generic version of |CompareTreePosition|. |aIf1Ancestor|
529 * gives the value to return when 1 is an ancestor of 2, and likewise
530 * for |aIf2Ancestor|. Passing (-1, 1) gives preorder traversal
531 * order, and (1, -1) gives postorder traversal order.
533 static int32_t DoCompareTreePosition(nsIFrame
* aFrame1
, nsIFrame
* aFrame2
,
534 int32_t aIf1Ancestor
,
535 int32_t aIf2Ancestor
,
536 nsIFrame
* aCommonAncestor
= nullptr);
538 static nsIFrame
* FillAncestors(nsIFrame
* aFrame
, nsIFrame
* aStopAtAncestor
,
539 nsTArray
<nsIFrame
*>* aAncestors
);
541 static int32_t DoCompareTreePosition(nsIFrame
* aFrame1
, nsIFrame
* aFrame2
,
542 nsTArray
<nsIFrame
*>& aFrame2Ancestors
,
543 int32_t aIf1Ancestor
,
544 int32_t aIf2Ancestor
,
545 nsIFrame
* aCommonAncestor
);
548 * LastContinuationWithChild gets the last continuation in aFrame's chain
549 * that has a child, or the first continuation if the frame has no children.
551 static nsContainerFrame
* LastContinuationWithChild(nsContainerFrame
* aFrame
);
554 * GetLastSibling simply finds the last sibling of aFrame, or returns nullptr
557 static nsIFrame
* GetLastSibling(nsIFrame
* aFrame
);
560 * FindSiblingViewFor locates the child of aParentView that aFrame's
561 * view should be inserted 'above' (i.e., before in sibling view
562 * order). This is the first child view of aParentView whose
563 * corresponding content is before aFrame's content (view siblings
564 * are in reverse content order).
566 static nsView
* FindSiblingViewFor(nsView
* aParentView
, nsIFrame
* aFrame
);
569 * Get the parent of aFrame. If aFrame is the root frame for a document,
570 * and the document has a parent document in the same view hierarchy, then
571 * we try to return the subdocumentframe in the parent document.
572 * @param aExtraOffset [in/out] if non-null, then as we cross documents
573 * an extra offset may be required and it will be added to aCrossDocOffset.
574 * Be careful dealing with this extra offset as it is in app units of the
575 * parent document, which may have a different app units per dev pixel ratio
576 * than the child document.
578 static nsIFrame
* GetCrossDocParentFrame(const nsIFrame
* aFrame
,
579 nsPoint
* aCrossDocOffset
= nullptr);
582 * IsProperAncestorFrame checks whether aAncestorFrame is an ancestor
583 * of aFrame and not equal to aFrame.
584 * @param aCommonAncestor nullptr, or a common ancestor of aFrame and
585 * aAncestorFrame. If non-null, this can bound the search and speed up
588 static bool IsProperAncestorFrame(const nsIFrame
* aAncestorFrame
,
589 const nsIFrame
* aFrame
,
590 const nsIFrame
* aCommonAncestor
= nullptr);
593 * Like IsProperAncestorFrame, but looks across document boundaries.
595 * Just like IsAncestorFrameCrossDoc, except that it returns false when
596 * aFrame == aAncestorFrame.
598 static bool IsProperAncestorFrameCrossDoc(
599 const nsIFrame
* aAncestorFrame
, const nsIFrame
* aFrame
,
600 const nsIFrame
* aCommonAncestor
= nullptr);
603 * IsAncestorFrameCrossDoc checks whether aAncestorFrame is an ancestor
604 * of aFrame or equal to aFrame, looking across document boundaries.
605 * @param aCommonAncestor nullptr, or a common ancestor of aFrame and
606 * aAncestorFrame. If non-null, this can bound the search and speed up
609 * Just like IsProperAncestorFrameCrossDoc, except that it returns true when
610 * aFrame == aAncestorFrame.
612 static bool IsAncestorFrameCrossDoc(
613 const nsIFrame
* aAncestorFrame
, const nsIFrame
* aFrame
,
614 const nsIFrame
* aCommonAncestor
= nullptr);
617 * Sets the fixed-pos metadata properties on aLayer.
618 * aAnchorRect is the basic anchor rectangle. If aFixedPosFrame is not a
619 * viewport frame, then we pick a corner of aAnchorRect to as the anchor point
620 * for the fixed-pos layer (i.e. the point to remain stable during zooming),
621 * based on which of the fixed-pos frame's CSS absolute positioning offset
622 * properties (top, left, right, bottom) are auto. aAnchorRect is in the
623 * coordinate space of aLayer's container layer (i.e. relative to the
624 * reference frame of the display item which is building aLayer's container
627 static void SetFixedPositionLayerData(
628 Layer
* aLayer
, const nsIFrame
* aViewportFrame
, const nsRect
& aAnchorRect
,
629 const nsIFrame
* aFixedPosFrame
, nsPresContext
* aPresContext
,
630 const ContainerLayerParameters
& aContainerParameters
);
632 static mozilla::SideBits
GetSideBitsAndAdjustAnchorForFixedPositionContent(
633 const nsIFrame
* aViewportFrame
, const nsIFrame
* aFixedPosFrame
,
634 mozilla::LayerPoint
* aAnchor
, const Rect
* aAnchorRect
);
635 static mozilla::SideBits
GetSideBitsForFixedPositionContent(
636 const nsIFrame
* aFixedPosFrame
);
639 * Get the scroll id for the root scrollframe of the presshell of the given
640 * prescontext. Returns NULL_SCROLL_ID if it couldn't be found.
642 static ViewID
ScrollIdForRootScrollFrame(nsPresContext
* aPresContext
);
645 * Return true if aPresContext's viewport has a displayport.
647 static bool ViewportHasDisplayPort(nsPresContext
* aPresContext
);
650 * Return true if aFrame is a fixed-pos frame and is a child of a viewport
651 * which has a displayport. These frames get special treatment from the
652 * compositor. aDisplayPort, if non-null, is set to the display port rectangle
653 * (relative to the viewport).
655 static bool IsFixedPosFrameInDisplayPort(const nsIFrame
* aFrame
);
658 * GetScrollableFrameFor returns the scrollable frame for a scrolled frame
660 static nsIScrollableFrame
* GetScrollableFrameFor(
661 const nsIFrame
* aScrolledFrame
);
664 * GetNearestScrollableFrameForDirection locates the first ancestor of
665 * aFrame (or aFrame itself) that is scrollable with overflow:scroll or
666 * overflow:auto in the given direction and where either the scrollbar for
667 * that direction is visible or the frame can be scrolled by some
668 * positive amount in that direction.
669 * The search extends across document boundaries.
671 * @param aFrame the frame to start with
672 * @param aDirection Whether it's for horizontal or vertical scrolling.
673 * @return the nearest scrollable frame or nullptr if not found
675 enum Direction
{ eHorizontal
, eVertical
};
676 static nsIScrollableFrame
* GetNearestScrollableFrameForDirection(
677 nsIFrame
* aFrame
, Direction aDirection
);
681 * If the SCROLLABLE_SAME_DOC flag is set, then we only walk the frame tree
682 * up to the root frame in the current document.
684 SCROLLABLE_SAME_DOC
= 0x01,
686 * If the SCROLLABLE_INCLUDE_HIDDEN flag is set then we allow
687 * overflow:hidden scrollframes to be returned as scrollable frames.
689 SCROLLABLE_INCLUDE_HIDDEN
= 0x02,
691 * If the SCROLLABLE_ONLY_ASYNC_SCROLLABLE flag is set, then we only
692 * want to match scrollable frames for which WantAsyncScroll() returns
695 SCROLLABLE_ONLY_ASYNC_SCROLLABLE
= 0x04,
697 * If the SCROLLABLE_ALWAYS_MATCH_ROOT flag is set, then we will always
698 * return the root scrollable frame for the root document (in the current
699 * process) if we encounter it, whether or not it is async scrollable or
702 SCROLLABLE_ALWAYS_MATCH_ROOT
= 0x08,
704 * If the SCROLLABLE_FIXEDPOS_FINDS_ROOT flag is set, then for fixed-pos
705 * frames return the root scrollable frame for that document.
707 SCROLLABLE_FIXEDPOS_FINDS_ROOT
= 0x10,
709 * If the SCROLLABLE_STOP_AT_PAGE flag is set, then we stop searching
710 * for scrollable ancestors when seeing a nsPageFrame. This can be used
711 * to avoid finding the viewport scroll frame in Print Preview (which
712 * would be undesirable as a 'position:sticky' container for content).
714 SCROLLABLE_STOP_AT_PAGE
= 0x20,
717 * GetNearestScrollableFrame locates the first ancestor of aFrame
718 * (or aFrame itself) that is scrollable with overflow:scroll or
719 * overflow:auto in some direction.
721 * @param aFrame the frame to start with
722 * @param aFlags if SCROLLABLE_SAME_DOC is set, do not search across
723 * document boundaries. If SCROLLABLE_INCLUDE_HIDDEN is set, include
724 * frames scrollable with overflow:hidden.
725 * @return the nearest scrollable frame or nullptr if not found
727 static nsIScrollableFrame
* GetNearestScrollableFrame(nsIFrame
* aFrame
,
728 uint32_t aFlags
= 0);
731 * GetScrolledRect returns the range of allowable scroll offsets
732 * for aScrolledFrame, assuming the scrollable overflow area is
733 * aScrolledFrameOverflowArea and the scrollport size is aScrollPortSize.
735 static nsRect
GetScrolledRect(nsIFrame
* aScrolledFrame
,
736 const nsRect
& aScrolledFrameOverflowArea
,
737 const nsSize
& aScrollPortSize
,
738 mozilla::StyleDirection
);
741 * HasPseudoStyle returns true if aContent (whose primary style
742 * context is aComputedStyle) has the aPseudoElement pseudo-style
743 * attached to it; returns false otherwise.
745 * @param aContent the content node we're looking at
746 * @param aComputedStyle aContent's ComputedStyle
747 * @param aPseudoElement the id of the pseudo style we care about
748 * @param aPresContext the presentation context
749 * @return whether aContent has aPseudoElement style attached to it
751 static bool HasPseudoStyle(nsIContent
* aContent
,
752 ComputedStyle
* aComputedStyle
,
753 mozilla::PseudoStyleType aPseudoElement
,
754 nsPresContext
* aPresContext
);
757 * If this frame is a placeholder for a float, then return the float,
758 * otherwise return nullptr. aPlaceholder must be a placeholder frame.
760 static nsIFrame
* GetFloatFromPlaceholder(nsIFrame
* aPlaceholder
);
762 // Combine aNewBreakType with aOrigBreakType, but limit the break types
763 // to StyleClear::Left, Right, Both.
764 static mozilla::StyleClear
CombineBreakType(
765 mozilla::StyleClear aOrigBreakType
, mozilla::StyleClear aNewBreakType
);
768 * Get the coordinates of a given DOM mouse event, relative to a given
769 * frame. Works only for DOM events generated by WidgetGUIEvents.
770 * @param aDOMEvent the event
771 * @param aFrame the frame to make coordinates relative to
772 * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
773 * for some reason the coordinates for the mouse are not known (e.g.,
774 * the event is not a GUI event).
776 static nsPoint
GetDOMEventCoordinatesRelativeTo(
777 mozilla::dom::Event
* aDOMEvent
, nsIFrame
* aFrame
);
780 * Get the coordinates of a given native mouse event, relative to a given
782 * @param aEvent the event
783 * @param aFrame the frame to make coordinates relative to
784 * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
785 * for some reason the coordinates for the mouse are not known (e.g.,
786 * the event is not a GUI event).
788 static nsPoint
GetEventCoordinatesRelativeTo(
789 const mozilla::WidgetEvent
* aEvent
, RelativeTo aFrame
);
792 * Get the coordinates of a given point relative to an event and a
794 * @param aEvent the event
795 * @param aPoint the point to get the coordinates relative to
796 * @param aFrame the frame to make coordinates relative to
797 * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
798 * for some reason the coordinates for the mouse are not known (e.g.,
799 * the event is not a GUI event).
801 static nsPoint
GetEventCoordinatesRelativeTo(
802 const mozilla::WidgetEvent
* aEvent
,
803 const mozilla::LayoutDeviceIntPoint
& aPoint
, RelativeTo aFrame
);
806 * Get the coordinates of a given point relative to a widget and a
808 * @param aWidget the event src widget
809 * @param aPoint the point to get the coordinates relative to
810 * @param aFrame the frame to make coordinates relative to
811 * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
812 * for some reason the coordinates for the mouse are not known (e.g.,
813 * the event is not a GUI event).
815 static nsPoint
GetEventCoordinatesRelativeTo(
816 nsIWidget
* aWidget
, const mozilla::LayoutDeviceIntPoint
& aPoint
,
820 * Get the popup frame of a given native mouse event.
821 * @param aPresContext only check popups within aPresContext or a descendant
822 * @param aEvent the event.
823 * @return Null, if there is no popup frame at the point, otherwise,
824 * returns top-most popup frame at the point.
826 static nsIFrame
* GetPopupFrameForEventCoordinates(
827 nsPresContext
* aPresContext
, const mozilla::WidgetEvent
* aEvent
);
830 * Get container and offset if aEvent collapses Selection.
831 * @param aPresShell The PresShell handling aEvent.
832 * @param aEvent The event having coordinates where you want to
833 * collapse Selection.
834 * @param aContainer Returns the container node at the point.
835 * Set nullptr if you don't need this.
836 * @param aOffset Returns offset in the container node at the point.
837 * Set nullptr if you don't need this.
840 static void GetContainerAndOffsetAtEvent(PresShell
* aPresShell
,
841 const mozilla::WidgetEvent
* aEvent
,
842 nsIContent
** aContainer
,
846 * Translate from widget coordinates to the view's coordinates
847 * @param aPresContext the PresContext for the view
848 * @param aWidget the widget
849 * @param aPt the point relative to the widget
850 * @param aView view to which returned coordinates are relative
851 * @return the point in the view's coordinates
853 static nsPoint
TranslateWidgetToView(nsPresContext
* aPresContext
,
855 const mozilla::LayoutDeviceIntPoint
& aPt
,
859 * Translate from view coordinates to the widget's coordinates.
860 * @param aPresContext the PresContext for the view
861 * @param aView the view
862 * @param aPt the point relative to the view
863 * @param aViewportType whether the point is in visual or layout coordinates
864 * @param aWidget the widget to which returned coordinates are relative
865 * @return the point in the view's coordinates
867 static mozilla::LayoutDeviceIntPoint
TranslateViewToWidget(
868 nsPresContext
* aPresContext
, nsView
* aView
, nsPoint aPt
,
869 ViewportType aViewportType
, nsIWidget
* aWidget
);
871 static mozilla::LayoutDeviceIntPoint
WidgetToWidgetOffset(
872 nsIWidget
* aFromWidget
, nsIWidget
* aToWidget
);
874 enum class FrameForPointOption
{
876 * When set, paint suppression is ignored, so we'll return non-root page
877 * elements even if paint suppression is stopping them from painting.
879 IgnorePaintSuppression
= 1,
881 * When set, clipping due to the root scroll frame (and any other viewport-
882 * related clipping) is ignored.
884 IgnoreRootScrollFrame
,
886 * When set, return only content in the same document as aFrame.
890 * When set, return only content that is actually visible.
896 * Given aFrame, the root frame of a stacking context, find its descendant
897 * frame under the point aPt that receives a mouse event at that location,
898 * or nullptr if there is no such frame.
899 * @param aPt the point, relative to the frame origin, in either visual
900 * or layout coordinates depending on aRelativeTo.mViewportType
901 * @param aFlags some combination of FrameForPointOption.
903 static nsIFrame
* GetFrameForPoint(RelativeTo aRelativeTo
, nsPoint aPt
,
904 mozilla::EnumSet
<FrameForPointOption
> = {});
907 * Given aFrame, the root frame of a stacking context, find all descendant
908 * frames under the area of a rectangle that receives a mouse event,
909 * or nullptr if there is no such frame.
910 * @param aRect the rect, relative to the frame origin, in either visual
911 * or layout coordinates depending on aRelativeTo.mViewportType
912 * @param aOutFrames an array to add all the frames found
913 * @param aFlags some combination of FrameForPointOption.
915 static nsresult
GetFramesForArea(RelativeTo aRelativeTo
, const nsRect
& aRect
,
916 nsTArray
<nsIFrame
*>& aOutFrames
,
917 mozilla::EnumSet
<FrameForPointOption
> = {});
920 * Transform aRect relative to aFrame up to the coordinate system of
921 * aAncestor. Computes the bounding-box of the true quadrilateral.
922 * Pass non-null aPreservesAxisAlignedRectangles and it will be set to true if
923 * we only need to use a 2d transform that PreservesAxisAlignedRectangles().
924 * The corner positions of aRect are treated as meaningful even if aRect is
927 * |aMatrixCache| allows for optimizations in recomputing the same matrix over
928 * and over. The argument can be one of the following values:
930 * nullptr (the default) - No optimization; the transform matrix is computed
931 * on every call to this function.
933 * non-null pointer to an empty Maybe<Matrix4x4> - Upon return, the Maybe is
934 * filled with the transform matrix that was computed. This can then be passed
935 * in to subsequent calls with the same source and destination frames to avoid
936 * recomputing the matrix.
938 * non-null pointer to a non-empty Matrix4x4 - The provided matrix will be
939 * used as the transform matrix and applied to the rect.
941 static nsRect
TransformFrameRectToAncestor(
942 const nsIFrame
* aFrame
, const nsRect
& aRect
, const nsIFrame
* aAncestor
,
943 bool* aPreservesAxisAlignedRectangles
= nullptr,
944 mozilla::Maybe
<Matrix4x4Flagged
>* aMatrixCache
= nullptr,
945 bool aStopAtStackingContextAndDisplayPortAndOOFFrame
= false,
946 nsIFrame
** aOutAncestor
= nullptr) {
947 return TransformFrameRectToAncestor(
948 aFrame
, aRect
, RelativeTo
{aAncestor
}, aPreservesAxisAlignedRectangles
,
949 aMatrixCache
, aStopAtStackingContextAndDisplayPortAndOOFFrame
,
952 static nsRect
TransformFrameRectToAncestor(
953 const nsIFrame
* aFrame
, const nsRect
& aRect
, RelativeTo aAncestor
,
954 bool* aPreservesAxisAlignedRectangles
= nullptr,
955 mozilla::Maybe
<Matrix4x4Flagged
>* aMatrixCache
= nullptr,
956 bool aStopAtStackingContextAndDisplayPortAndOOFFrame
= false,
957 nsIFrame
** aOutAncestor
= nullptr);
960 * Gets the transform for aFrame relative to aAncestor. Pass null for
961 * aAncestor to go up to the root frame. Including nsIFrame::IN_CSS_UNITS
962 * flag in aFlags will return CSS pixels, by default it returns device
964 * More info can be found in nsIFrame::GetTransformMatrix.
966 * Some notes on the possible combinations of |aFrame.mViewportType| and
967 * |aAncestor.mViewportType|:
969 * | aFrame. | aAncestor. | Notes
970 * | mViewportType | mViewportType |
971 * ==========================================================================
972 * | Layout | Layout | Commonplace, when both source and target
973 * | | | are inside zoom boundary.
975 * | | | Could also happen in non-e10s setups
976 * | | | when both source and target are outside
977 * | | | the zoom boundary and the code is
978 * | | | oblivious to the existence of a zoom
980 * ==========================================================================
981 * | Layout | Visual | Commonplace, used when hit testing visual
982 * | | | coordinates (e.g. coming from user input
983 * | | | events). We expected to encounter a
984 * | | | zoomed content root during traversal and
985 * | | | apply a layout-to-visual transform.
986 * ==========================================================================
987 * | Visual | Layout | Should never happen, will assert.
988 * ==========================================================================
989 * | Visual | Visual | In e10s setups, should only happen if
990 * | | | aFrame and aAncestor are both the
991 * | | | RCD viewport frame.
993 * | | | In non-e10s setups, could happen with
994 * | | | different frames if they are both
995 * | | | outside the zoom boundary.
996 * ==========================================================================
998 static Matrix4x4Flagged
GetTransformToAncestor(
999 RelativeTo aFrame
, RelativeTo aAncestor
, uint32_t aFlags
= 0,
1000 nsIFrame
** aOutAncestor
= nullptr);
1003 * Gets the scale factors of the transform for aFrame relative to the root
1004 * frame if this transform is 2D, or the identity scale factors otherwise.
1006 static gfxSize
GetTransformToAncestorScale(nsIFrame
* aFrame
);
1009 * Gets the scale factors of the transform for aFrame relative to the root
1010 * frame if this transform is 2D, or the identity scale factors otherwise.
1011 * If some frame on the path from aFrame to the display root frame may have an
1012 * animated scale, returns the identity scale factors.
1014 static gfxSize
GetTransformToAncestorScaleExcludingAnimated(nsIFrame
* aFrame
);
1017 * Find the nearest common ancestor frame for aFrame1 and aFrame2. The
1018 * ancestor frame could be cross-doc.
1020 static const nsIFrame
* FindNearestCommonAncestorFrame(
1021 const nsIFrame
* aFrame1
, const nsIFrame
* aFrame2
);
1024 * Find the nearest common ancestor frame for aFrame1 and aFrame2, assuming
1025 * that they are within the same block.
1027 * Returns null if they are not within the same block.
1029 static const nsIFrame
* FindNearestCommonAncestorFrameWithinBlock(
1030 const nsTextFrame
* aFrame1
, const nsTextFrame
* aFrame2
);
1033 * Transforms a list of CSSPoints from aFromFrame to aToFrame, taking into
1034 * account all relevant transformations on the frames up to (but excluding)
1035 * their nearest common ancestor.
1036 * If we encounter a transform that we need to invert but which is
1037 * non-invertible, we return NONINVERTIBLE_TRANSFORM. If the frames have
1038 * no common ancestor, we return NO_COMMON_ANCESTOR.
1039 * If this returns TRANSFORM_SUCCEEDED, the points in aPoints are transformed
1040 * in-place, otherwise they are untouched.
1042 enum TransformResult
{
1043 TRANSFORM_SUCCEEDED
,
1045 NONINVERTIBLE_TRANSFORM
1047 static TransformResult
TransformPoints(nsIFrame
* aFromFrame
,
1049 uint32_t aPointCount
,
1053 * Same as above function, but transform points in app units and
1054 * handle 1 point per call.
1056 static TransformResult
TransformPoint(RelativeTo aFromFrame
,
1057 RelativeTo aToFrame
, nsPoint
& aPoint
);
1060 * Transforms a rect from aFromFrame to aToFrame. In app units.
1061 * Returns the bounds of the actual rect if the transform requires rotation
1062 * or anything complex like that.
1064 static TransformResult
TransformRect(const nsIFrame
* aFromFrame
,
1065 const nsIFrame
* aToFrame
, nsRect
& aRect
);
1068 * Converts app units to pixels (with optional snapping) and appends as a
1069 * translation to aTransform.
1071 static void PostTranslate(Matrix4x4
& aTransform
, const nsPoint
& aOrigin
,
1072 float aAppUnitsPerPixel
, bool aRounded
);
1075 * Whether the frame should snap to grid. This will end up being passed
1076 * as the aRounded parameter in PostTranslate above. SVG frames should
1077 * not have their translation rounded.
1079 static bool ShouldSnapToGrid(const nsIFrame
* aFrame
);
1082 * Get the border-box of aElement's primary frame, transformed it to be
1083 * relative to aFrame.
1085 static nsRect
GetRectRelativeToFrame(mozilla::dom::Element
* aElement
,
1089 * Returns true if aRect with border inflation of size aInflateSize contains
1092 static bool ContainsPoint(const nsRect
& aRect
, const nsPoint
& aPoint
,
1093 nscoord aInflateSize
);
1096 * Clamp aRect relative to aFrame to the scroll frames boundary searching from
1099 static nsRect
ClampRectToScrollFrames(nsIFrame
* aFrame
, const nsRect
& aRect
);
1102 * Return true if a "layer transform" could be computed for aFrame,
1103 * and optionally return the computed transform. The returned
1104 * transform is what would be set on the layer currently if a layers
1105 * transaction were opened at the time this helper is called.
1107 static bool GetLayerTransformForFrame(nsIFrame
* aFrame
,
1108 Matrix4x4Flagged
* aTransform
);
1111 * Given a point in the global coordinate space, returns that point expressed
1112 * in the coordinate system of aFrame. This effectively inverts all
1113 * transforms between this point and the root frame.
1115 * @param aFromType Specifies whether |aPoint| is in layout or visual
1117 * @param aFrame The frame that acts as the coordinate space container.
1118 * @param aPoint The point, in global layout or visual coordinates (as per
1119 * |aFromType|, to get in the frame-local space.
1120 * @return aPoint, expressed in aFrame's canonical coordinate space.
1122 static nsPoint
TransformRootPointToFrame(ViewportType aFromType
,
1124 const nsPoint
& aPoint
) {
1125 return TransformAncestorPointToFrame(aFrame
, aPoint
,
1126 RelativeTo
{nullptr, aFromType
});
1130 * Transform aPoint relative to aAncestor down to the coordinate system of
1133 static nsPoint
TransformAncestorPointToFrame(RelativeTo aFrame
,
1134 const nsPoint
& aPoint
,
1135 RelativeTo aAncestor
);
1138 * Helper function that, given a rectangle and a matrix, returns the smallest
1139 * rectangle containing the image of the source rectangle.
1141 * @param aBounds The rectangle to transform.
1142 * @param aMatrix The matrix to transform it with.
1143 * @param aFactor The number of app units per graphics unit.
1144 * @return The smallest rect that contains the image of aBounds.
1146 static nsRect
MatrixTransformRect(const nsRect
& aBounds
,
1147 const Matrix4x4
& aMatrix
, float aFactor
);
1148 static nsRect
MatrixTransformRect(const nsRect
& aBounds
,
1149 const Matrix4x4Flagged
& aMatrix
,
1153 * Helper function that, given a point and a matrix, returns the image
1154 * of that point under the matrix transform.
1156 * @param aPoint The point to transform.
1157 * @param aMatrix The matrix to transform it with.
1158 * @param aFactor The number of app units per graphics unit.
1159 * @return The image of the point under the transform.
1161 static nsPoint
MatrixTransformPoint(const nsPoint
& aPoint
,
1162 const Matrix4x4
& aMatrix
, float aFactor
);
1165 * Given a graphics rectangle in graphics space, return a rectangle in
1166 * app space that contains the graphics rectangle, rounding out as necessary.
1168 * @param aRect The graphics rect to round outward.
1169 * @param aFactor The number of app units per graphics unit.
1170 * @return The smallest rectangle in app space that contains aRect.
1172 template <typename T
>
1173 static nsRect
RoundGfxRectToAppRect(const T
& aRect
, const float aFactor
);
1176 * Returns a subrectangle of aContainedRect that is entirely inside the
1177 * rounded rect. Complex cases are handled conservatively by returning a
1178 * smaller rect than necessary.
1180 static nsRegion
RoundedRectIntersectRect(const nsRect
& aRoundedRect
,
1181 const nscoord aRadii
[8],
1182 const nsRect
& aContainedRect
);
1183 static nsIntRegion
RoundedRectIntersectIntRect(
1184 const nsIntRect
& aRoundedRect
, const RectCornerRadii
& aCornerRadii
,
1185 const nsIntRect
& aContainedRect
);
1188 * Return whether any part of aTestRect is inside of the rounded
1189 * rectangle formed by aBounds and aRadii (which are indexed by the
1190 * enum HalfCorner constants in gfx/2d/Types.h). This is precise.
1192 static bool RoundedRectIntersectsRect(const nsRect
& aRoundedRect
,
1193 const nscoord aRadii
[8],
1194 const nsRect
& aTestRect
);
1196 static bool MaybeCreateDisplayPortInFirstScrollFrameEncountered(
1197 nsIFrame
* aFrame
, nsDisplayListBuilder
* aBuilder
);
1199 enum class PaintFrameFlags
: uint32_t {
1201 SyncDecodeImages
= 0x02,
1202 WidgetLayers
= 0x04,
1203 IgnoreSuppression
= 0x08,
1204 DocumentRelative
= 0x10,
1207 ExistingTransaction
= 0x80,
1208 NoComposite
= 0x100,
1210 ForWebRender
= 0x400,
1211 UseHighQualityScaling
= 0x800,
1215 * Given aFrame, the root frame of a stacking context, paint it and its
1216 * descendants to aRenderingContext.
1217 * @param aRenderingContext a rendering context translated so that (0,0)
1218 * is the origin of aFrame; for best results, (0,0) should transform
1219 * to pixel-aligned coordinates. This can be null, in which case
1220 * aFrame must be a "display root" (root frame for a root document,
1221 * or the root of a popup) with an associated widget and we draw using
1222 * the layer manager for the frame's widget.
1223 * @param aDirtyRegion the region that must be painted, in the coordinates
1225 * @param aBackstop paint the dirty area with this color before drawing
1226 * the actual content; pass NS_RGBA(0,0,0,0) to draw no background.
1227 * @param aBuilderMode Passed through to the display-list builder.
1228 * @param aFlags if PAINT_IN_TRANSFORM is set, then we assume
1229 * this is inside a transform or SVG foreignObject. If
1230 * PAINT_SYNC_DECODE_IMAGES is set, we force synchronous decode on all
1231 * images. If PAINT_WIDGET_LAYERS is set, aFrame must be a display root,
1232 * and we will use the frame's widget's layer manager to paint
1233 * even if aRenderingContext is non-null. This is useful if you want
1234 * to force rendering to use the widget's layer manager for testing
1235 * or speed. PAINT_WIDGET_LAYERS must be set if aRenderingContext is null.
1236 * If PAINT_DOCUMENT_RELATIVE is used, the visible region is interpreted
1237 * as being relative to the document (normally it's relative to the CSS
1238 * viewport) and the document is painted as if no scrolling has occured.
1239 * Only considered if PresShell::IgnoringViewportScrolling is true.
1240 * PAINT_TO_WINDOW sets painting to window to true on the display list
1241 * builder even if we can't tell that we are painting to the window.
1242 * If PAINT_EXISTING_TRANSACTION is set, then BeginTransaction() has already
1243 * been called on aFrame's widget's layer manager and should not be
1245 * If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to
1246 * compressed mode to avoid short cut optimizations.
1248 * So there are three possible behaviours:
1249 * 1) PAINT_WIDGET_LAYERS is set and aRenderingContext is null; we paint
1250 * by calling BeginTransaction on the widget's layer manager.
1251 * 2) PAINT_WIDGET_LAYERS is set and aRenderingContext is non-null; we
1252 * paint by calling BeginTransactionWithTarget on the widget's layer
1254 * 3) PAINT_WIDGET_LAYERS is not set and aRenderingContext is non-null;
1255 * we paint by construct a BasicLayerManager and calling
1256 * BeginTransactionWithTarget on it. This is desirable if we're doing
1257 * something like drawWindow in a mode where what gets rendered doesn't
1258 * necessarily correspond to what's visible in the window; we don't
1259 * want to mess up the widget's layer tree.
1261 static nsresult
PaintFrame(gfxContext
* aRenderingContext
, nsIFrame
* aFrame
,
1262 const nsRegion
& aDirtyRegion
, nscolor aBackstop
,
1263 nsDisplayListBuilderMode aBuilderMode
,
1264 PaintFrameFlags aFlags
= PaintFrameFlags(0));
1267 * Uses a binary search for find where the cursor falls in the line of text
1268 * It also keeps track of the part of the string that has already been
1269 * measured so it doesn't have to keep measuring the same text over and over.
1271 * @param "aBaseWidth" contains the width in twips of the portion
1272 * of the text that has already been measured, and aBaseInx contains
1273 * the index of the text that has already been measured.
1275 * @param aTextWidth returns (in twips) the length of the text that falls
1276 * before the cursor aIndex contains the index of the text where the cursor
1279 static bool BinarySearchForPosition(DrawTarget
* aDrawTarget
,
1280 nsFontMetrics
& aFontMetrics
,
1281 const char16_t
* aText
, int32_t aBaseWidth
,
1282 int32_t aBaseInx
, int32_t aStartInx
,
1283 int32_t aEndInx
, int32_t aCursorPos
,
1284 int32_t& aIndex
, int32_t& aTextWidth
);
1288 BoxCallback() : mIncludeCaptionBoxForTable(true) {}
1289 virtual void AddBox(nsIFrame
* aFrame
) = 0;
1290 bool mIncludeCaptionBoxForTable
;
1293 * Collect all CSS boxes associated with aFrame and its
1294 * continuations, "drilling down" through table wrapper frames and
1295 * some anonymous blocks since they're not real CSS boxes.
1296 * If aFrame is null, no boxes are returned.
1297 * SVG frames return a single box, themselves.
1299 static void GetAllInFlowBoxes(nsIFrame
* aFrame
, BoxCallback
* aCallback
);
1302 * Like GetAllInFlowBoxes, but doesn't include continuations.
1304 static void AddBoxesForFrame(nsIFrame
* aFrame
, BoxCallback
* aCallback
);
1307 * Find the first frame descendant of aFrame (including aFrame) which is
1308 * not an anonymous frame that getBoxQuads/getClientRects should ignore.
1310 static nsIFrame
* GetFirstNonAnonymousFrame(nsIFrame
* aFrame
);
1312 class RectCallback
{
1314 virtual void AddRect(const nsRect
& aRect
) = 0;
1317 struct RectAccumulator
: public RectCallback
{
1320 bool mSeenFirstRect
;
1324 virtual void AddRect(const nsRect
& aRect
) override
;
1327 struct RectListBuilder
: public RectCallback
{
1328 DOMRectList
* mRectList
;
1330 explicit RectListBuilder(DOMRectList
* aList
);
1331 virtual void AddRect(const nsRect
& aRect
) override
;
1334 static nsIFrame
* GetContainingBlockForClientRect(nsIFrame
* aFrame
);
1337 RECTS_ACCOUNT_FOR_TRANSFORMS
= 0x01,
1338 // Two bits for specifying which box type to use.
1339 // With neither bit set (default), use the border box.
1340 RECTS_USE_CONTENT_BOX
= 0x02,
1341 RECTS_USE_PADDING_BOX
= 0x04,
1342 RECTS_USE_MARGIN_BOX
= 0x06, // both bits set
1343 RECTS_WHICH_BOX_MASK
= 0x06 // bitmask for these two bits
1346 * Collect all CSS boxes (content, padding, border, or margin) associated
1347 * with aFrame and its continuations, "drilling down" through table wrapper
1348 * frames and some anonymous blocks since they're not real CSS boxes.
1349 * The boxes are positioned relative to aRelativeTo (taking scrolling
1350 * into account) and passed to the callback in frame-tree order.
1351 * If aFrame is null, no boxes are returned.
1352 * For SVG frames, returns one rectangle, the bounding box.
1353 * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting
1354 * the boxes into aRelativeTo coordinates, transforms (including CSS
1355 * and SVG transforms) are taken into account.
1356 * If aFlags includes one of RECTS_USE_CONTENT_BOX, RECTS_USE_PADDING_BOX,
1357 * or RECTS_USE_MARGIN_BOX, the corresponding type of box is used.
1358 * Otherwise (by default), the border box is used.
1360 static void GetAllInFlowRects(nsIFrame
* aFrame
, const nsIFrame
* aRelativeTo
,
1361 RectCallback
* aCallback
, uint32_t aFlags
= 0);
1363 static void GetAllInFlowRectsAndTexts(
1364 nsIFrame
* aFrame
, const nsIFrame
* aRelativeTo
, RectCallback
* aCallback
,
1365 mozilla::dom::Sequence
<nsString
>* aTextList
, uint32_t aFlags
= 0);
1368 * Computes the union of all rects returned by GetAllInFlowRects. If
1369 * the union is empty, returns the first rect.
1370 * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting
1371 * the boxes into aRelativeTo coordinates, transforms (including CSS
1372 * and SVG transforms) are taken into account.
1373 * If aFlags includes one of RECTS_USE_CONTENT_BOX, RECTS_USE_PADDING_BOX,
1374 * or RECTS_USE_MARGIN_BOX, the corresponding type of box is used.
1375 * Otherwise (by default), the border box is used.
1377 static nsRect
GetAllInFlowRectsUnion(nsIFrame
* aFrame
,
1378 const nsIFrame
* aRelativeTo
,
1379 uint32_t aFlags
= 0);
1381 enum { EXCLUDE_BLUR_SHADOWS
= 0x01 };
1383 * Takes a text-shadow array from the style properties of a given nsIFrame and
1384 * computes the union of those shadows along with the given initial rect.
1385 * If there are no shadows, the initial rect is returned.
1387 static nsRect
GetTextShadowRectsUnion(const nsRect
& aTextAndDecorationsRect
,
1388 nsIFrame
* aFrame
, uint32_t aFlags
= 0);
1391 * Computes the destination rect that a given replaced element should render
1392 * into, based on its CSS 'object-fit' and 'object-position' properties.
1394 * @param aConstraintRect The constraint rect that we have at our disposal,
1395 * which would e.g. be exactly filled by the image
1396 * if we had "object-fit: fill".
1397 * @param aIntrinsicSize The replaced content's intrinsic size, as reported
1398 * by nsIFrame::GetIntrinsicSize().
1399 * @param aIntrinsicRatio The replaced content's intrinsic ratio, as reported
1400 * by nsIFrame::GetIntrinsicRatio().
1401 * @param aStylePos The nsStylePosition struct that contains the 'object-fit'
1402 * and 'object-position' values that we should rely on.
1403 * (This should usually be the nsStylePosition for the
1404 * replaced element in question, but not always. For
1405 * example, a <video>'s poster-image has a dedicated
1406 * anonymous element & child-frame, but we should still use
1407 * the <video>'s 'object-fit' and 'object-position' values.)
1408 * @param aAnchorPoint [out] A point that should be pixel-aligned by functions
1409 * like nsLayoutUtils::DrawImage. See documentation
1410 * in nsCSSRendering.h for ComputeObjectAnchorPoint.
1411 * @return The nsRect into which we should render the replaced content (using
1412 * the same coordinate space as the passed-in aConstraintRect).
1414 static nsRect
ComputeObjectDestRect(const nsRect
& aConstraintRect
,
1415 const IntrinsicSize
& aIntrinsicSize
,
1416 const AspectRatio
& aIntrinsicRatio
,
1417 const nsStylePosition
* aStylePos
,
1418 nsPoint
* aAnchorPoint
= nullptr);
1421 * Get the font metrics corresponding to the frame's style data.
1422 * @param aFrame the frame
1423 * @param aSizeInflation number to multiply font size by
1425 static already_AddRefed
<nsFontMetrics
> GetFontMetricsForFrame(
1426 const nsIFrame
* aFrame
, float aSizeInflation
);
1428 static already_AddRefed
<nsFontMetrics
> GetInflatedFontMetricsForFrame(
1429 const nsIFrame
* aFrame
) {
1430 return GetFontMetricsForFrame(aFrame
, FontSizeInflationFor(aFrame
));
1434 * Get the font metrics corresponding to the given style data.
1435 * @param aComputedStyle the style data
1436 * @param aSizeInflation number to multiply font size by
1438 static already_AddRefed
<nsFontMetrics
> GetFontMetricsForComputedStyle(
1439 ComputedStyle
* aComputedStyle
, nsPresContext
* aPresContext
,
1440 float aSizeInflation
= 1.0f
,
1441 uint8_t aVariantWidth
= NS_FONT_VARIANT_WIDTH_NORMAL
);
1444 * Get the font metrics of emphasis marks corresponding to the given
1445 * style data. The result is same as GetFontMetricsForComputedStyle
1446 * except that the font size is scaled down to 50%.
1447 * @param aComputedStyle the style data
1448 * @param aInflation number to multiple font size by
1450 static already_AddRefed
<nsFontMetrics
> GetFontMetricsOfEmphasisMarks(
1451 ComputedStyle
* aComputedStyle
, nsPresContext
* aPresContext
,
1453 return GetFontMetricsForComputedStyle(aComputedStyle
, aPresContext
,
1458 * Find the immediate child of aParent whose frame subtree contains
1459 * aDescendantFrame. Returns null if aDescendantFrame is not a descendant
1462 static nsIFrame
* FindChildContainingDescendant(nsIFrame
* aParent
,
1463 nsIFrame
* aDescendantFrame
);
1466 * Find the nearest ancestor that's a block
1468 static nsBlockFrame
* FindNearestBlockAncestor(nsIFrame
* aFrame
);
1471 * Find the nearest ancestor that's not for generated content. Will return
1472 * aFrame if aFrame is not for generated content.
1474 static nsIFrame
* GetNonGeneratedAncestor(nsIFrame
* aFrame
);
1477 * Whether the frame is an nsBlockFrame which is not a wrapper block.
1479 static bool IsNonWrapperBlock(nsIFrame
* aFrame
);
1482 * If aFrame is an out of flow frame, return its placeholder, otherwise
1483 * return its parent.
1485 static nsIFrame
* GetParentOrPlaceholderFor(const nsIFrame
* aFrame
);
1488 * If aFrame is an out of flow frame, return its placeholder, otherwise
1489 * return its (possibly cross-doc) parent.
1491 static nsIFrame
* GetParentOrPlaceholderForCrossDoc(nsIFrame
* aFrame
);
1494 * Returns the frame that would act as the parent of aFrame when
1495 * descending through the frame tree in display list building.
1496 * Usually the same as GetParentOrPlaceholderForCrossDoc, except
1497 * that pushed floats are treated as children of their containing
1500 static nsIFrame
* GetDisplayListParent(nsIFrame
* aFrame
);
1503 * Get a frame's previous continuation, or, if it doesn't have one, its
1504 * previous block-in-inline-split sibling.
1506 static nsIFrame
* GetPrevContinuationOrIBSplitSibling(const nsIFrame
* aFrame
);
1509 * Get a frame's next continuation, or, if it doesn't have one, its
1510 * block-in-inline-split sibling.
1512 static nsIFrame
* GetNextContinuationOrIBSplitSibling(const nsIFrame
* aFrame
);
1515 * Get the first frame in the continuation-plus-ib-split-sibling chain
1516 * containing aFrame.
1518 static nsIFrame
* FirstContinuationOrIBSplitSibling(const nsIFrame
* aFrame
);
1521 * Get the last frame in the continuation-plus-ib-split-sibling chain
1522 * containing aFrame.
1524 static nsIFrame
* LastContinuationOrIBSplitSibling(const nsIFrame
* aFrame
);
1527 * Is FirstContinuationOrIBSplitSibling(aFrame) going to return
1530 static bool IsFirstContinuationOrIBSplitSibling(const nsIFrame
* aFrame
);
1533 * Check whether aFrame is a part of the scrollbar or scrollcorner of
1535 * @param aFrame the checking frame.
1536 * @return true if the frame is a part of the scrollbar or scrollcorner of
1539 static bool IsViewportScrollbarFrame(nsIFrame
* aFrame
);
1542 * Get the contribution of aFrame to its containing block's intrinsic
1543 * size for the given physical axis. This considers the child's intrinsic
1544 * width, its 'width', 'min-width', and 'max-width' properties (or 'height'
1545 * variations if that's what matches aAxis) and its padding, border and margin
1546 * in the corresponding dimension.
1547 * @param aPercentageBasis an optional percentage basis (in aFrame's WM).
1548 * If the basis is indefinite in a given axis, pass a size with
1549 * NS_UNCONSTRAINEDSIZE in that component.
1550 * If you pass Nothing() a percentage basis will be calculated from aFrame's
1551 * ancestors' computed size in the relevant axis, if needed.
1552 * @param aMarginBoxMinSizeClamp make the result fit within this margin-box
1553 * size by reducing the *content size* (flooring at zero). This is used for:
1554 * https://drafts.csswg.org/css-grid/#min-size-auto
1556 enum class IntrinsicISizeType
{ MinISize
, PrefISize
};
1557 static const auto MIN_ISIZE
= IntrinsicISizeType::MinISize
;
1558 static const auto PREF_ISIZE
= IntrinsicISizeType::PrefISize
;
1560 IGNORE_PADDING
= 0x01,
1561 BAIL_IF_REFLOW_NEEDED
= 0x02, // returns NS_INTRINSIC_ISIZE_UNKNOWN if so
1562 MIN_INTRINSIC_ISIZE
= 0x04, // use min-width/height instead of width/height
1564 static nscoord
IntrinsicForAxis(
1565 mozilla::PhysicalAxis aAxis
, gfxContext
* aRenderingContext
,
1566 nsIFrame
* aFrame
, IntrinsicISizeType aType
,
1567 const mozilla::Maybe
<LogicalSize
>& aPercentageBasis
= mozilla::Nothing(),
1568 uint32_t aFlags
= 0, nscoord aMarginBoxMinSizeClamp
= NS_MAXSIZE
);
1570 * Calls IntrinsicForAxis with aFrame's parent's inline physical axis.
1572 static nscoord
IntrinsicForContainer(gfxContext
* aRenderingContext
,
1574 IntrinsicISizeType aType
,
1575 uint32_t aFlags
= 0);
1578 * Get the definite size contribution of aFrame for the given physical axis.
1579 * This considers the child's 'min-width' property (or 'min-height' if the
1580 * given axis is vertical), and its padding, border, and margin in the
1581 * corresponding dimension. If the 'min-' property is 'auto' (and 'overflow'
1582 * is 'visible') and the corresponding 'width'/'height' is definite it returns
1583 * the "specified size" for:
1584 * https://drafts.csswg.org/css-grid/#min-size-auto
1585 * Note that the "transferred size" is not handled here; use IntrinsicForAxis.
1586 * Note that any percentage in 'width'/'height' makes it count as indefinite.
1587 * If the 'min-' property is 'auto' and 'overflow' is not 'visible', then it
1588 * calculates the result as if the 'min-' computed value is zero.
1589 * Otherwise, return NS_UNCONSTRAINEDSIZE.
1591 * @param aPercentageBasis the percentage basis (in aFrame's WM).
1592 * Pass NS_UNCONSTRAINEDSIZE if the basis is indefinite in either/both axes.
1593 * @note this behavior is specific to Grid/Flexbox (currently) so aFrame
1594 * should be a grid/flex item.
1596 static nscoord
MinSizeContributionForAxis(mozilla::PhysicalAxis aAxis
,
1597 gfxContext
* aRC
, nsIFrame
* aFrame
,
1598 IntrinsicISizeType aType
,
1599 const LogicalSize
& aPercentageBasis
,
1600 uint32_t aFlags
= 0);
1603 * Convert LengthPercentage to nscoord when percentages depend on the
1604 * containing block size.
1605 * @param aPercentBasis The width or height of the containing block
1606 * (whichever the client wants to use for resolving percentages).
1608 static nscoord
ComputeCBDependentValue(nscoord aPercentBasis
,
1609 const LengthPercentage
& aCoord
) {
1610 NS_WARNING_ASSERTION(
1611 aPercentBasis
!= NS_UNCONSTRAINEDSIZE
,
1612 "have unconstrained width or height; this should only result from very "
1613 "large sizes, not attempts at intrinsic size calculation");
1614 return aCoord
.Resolve(aPercentBasis
);
1616 static nscoord
ComputeCBDependentValue(nscoord aPercentBasis
,
1617 const LengthPercentageOrAuto
& aCoord
) {
1618 if (aCoord
.IsAuto()) {
1621 return ComputeCBDependentValue(aPercentBasis
, aCoord
.AsLengthPercentage());
1624 static nscoord
ComputeBSizeDependentValue(nscoord aContainingBlockBSize
,
1625 const LengthPercentageOrAuto
&);
1627 static nscoord
ComputeBSizeValue(nscoord aContainingBlockBSize
,
1628 nscoord aContentEdgeToBoxSizingBoxEdge
,
1629 const LengthPercentage
& aCoord
) {
1630 MOZ_ASSERT(aContainingBlockBSize
!= nscoord_MAX
|| !aCoord
.HasPercent(),
1631 "caller must deal with %% of unconstrained block-size");
1633 nscoord result
= aCoord
.Resolve(aContainingBlockBSize
);
1634 // Clamp calc(), and the subtraction for box-sizing.
1635 return std::max(0, result
- aContentEdgeToBoxSizingBoxEdge
);
1639 * The "extremum length" values (see ExtremumLength) were originally aimed at
1640 * inline-size (or width, as it was before logicalization). For now, we return
1641 * true for those here, so that we don't call ComputeBSizeValue with value
1642 * types that it doesn't understand. (See bug 1113216.)
1644 * FIXME (bug 567039, bug 527285)
1645 * This isn't correct for the 'fill' value or for the 'min-*' or 'max-*'
1646 * properties, which need to be handled differently by the callers of
1649 template <typename SizeOrMaxSize
>
1650 static bool IsAutoBSize(const SizeOrMaxSize
& aCoord
, nscoord aCBBSize
) {
1651 return aCoord
.BehavesLikeInitialValueOnBlockAxis() ||
1652 (aCBBSize
== nscoord_MAX
&& aCoord
.HasPercent());
1655 static bool IsPaddingZero(const LengthPercentage
& aLength
) {
1656 // clamp negative calc() to 0
1657 return aLength
.Resolve(nscoord_MAX
) <= 0 && aLength
.Resolve(0) <= 0;
1660 static bool IsMarginZero(const LengthPercentage
& aLength
) {
1661 return aLength
.Resolve(nscoord_MAX
) == 0 && aLength
.Resolve(0) == 0;
1664 static void MarkDescendantsDirty(nsIFrame
* aSubtreeRoot
);
1666 static void MarkIntrinsicISizesDirtyIfDependentOnBSize(nsIFrame
* aFrame
);
1669 * Calculate the used values for 'width' and 'height' when width
1670 * and height are 'auto'. The tentWidth and tentHeight arguments should be
1671 * the result of applying the rules for computing intrinsic sizes and ratios.
1672 * as specified by CSS 2.1 sections 10.3.2 and 10.6.2
1674 static nsSize
ComputeAutoSizeWithIntrinsicDimensions(
1675 nscoord minWidth
, nscoord minHeight
, nscoord maxWidth
, nscoord maxHeight
,
1676 nscoord tentWidth
, nscoord tentHeight
);
1678 // Implement nsIFrame::GetPrefISize in terms of nsIFrame::AddInlinePrefISize
1679 static nscoord
PrefISizeFromInline(nsIFrame
* aFrame
,
1680 gfxContext
* aRenderingContext
);
1682 // Implement nsIFrame::GetMinISize in terms of nsIFrame::AddInlineMinISize
1683 static nscoord
MinISizeFromInline(nsIFrame
* aFrame
,
1684 gfxContext
* aRenderingContext
);
1686 // Get a suitable foreground color for painting aColor for aFrame.
1687 static nscolor
DarkenColorIfNeeded(nsIFrame
* aFrame
, nscolor aColor
);
1689 // Get a suitable foreground color for painting aField for aFrame.
1690 // Type of aFrame is made a template parameter because nsIFrame is not
1691 // a complete type in the header. Type-safety is not harmed given that
1692 // DarkenColorIfNeeded requires an nsIFrame pointer.
1693 template <typename Frame
, typename T
, typename S
>
1694 static nscolor
GetColor(Frame
* aFrame
, T
S::*aField
) {
1695 nscolor color
= aFrame
->GetVisitedDependentColor(aField
);
1696 return DarkenColorIfNeeded(aFrame
, color
);
1699 // Get a baseline y position in app units that is snapped to device pixels.
1700 static gfxFloat
GetSnappedBaselineY(nsIFrame
* aFrame
, gfxContext
* aContext
,
1701 nscoord aY
, nscoord aAscent
);
1702 // Ditto for an x position (for vertical text). Note that for vertical-rl
1703 // writing mode, the ascent value should be negated by the caller.
1704 static gfxFloat
GetSnappedBaselineX(nsIFrame
* aFrame
, gfxContext
* aContext
,
1705 nscoord aX
, nscoord aAscent
);
1707 static nscoord
AppUnitWidthOfString(char16_t aC
, nsFontMetrics
& aFontMetrics
,
1708 DrawTarget
* aDrawTarget
) {
1709 return AppUnitWidthOfString(&aC
, 1, aFontMetrics
, aDrawTarget
);
1711 static nscoord
AppUnitWidthOfString(const nsString
& aString
,
1712 nsFontMetrics
& aFontMetrics
,
1713 DrawTarget
* aDrawTarget
) {
1714 return nsLayoutUtils::AppUnitWidthOfString(aString
.get(), aString
.Length(),
1715 aFontMetrics
, aDrawTarget
);
1717 static nscoord
AppUnitWidthOfString(const char16_t
* aString
, uint32_t aLength
,
1718 nsFontMetrics
& aFontMetrics
,
1719 DrawTarget
* aDrawTarget
);
1720 static nscoord
AppUnitWidthOfStringBidi(const nsString
& aString
,
1721 const nsIFrame
* aFrame
,
1722 nsFontMetrics
& aFontMetrics
,
1723 gfxContext
& aContext
) {
1724 return nsLayoutUtils::AppUnitWidthOfStringBidi(
1725 aString
.get(), aString
.Length(), aFrame
, aFontMetrics
, aContext
);
1727 static nscoord
AppUnitWidthOfStringBidi(const char16_t
* aString
,
1729 const nsIFrame
* aFrame
,
1730 nsFontMetrics
& aFontMetrics
,
1731 gfxContext
& aContext
);
1733 static bool StringWidthIsGreaterThan(const nsString
& aString
,
1734 nsFontMetrics
& aFontMetrics
,
1735 DrawTarget
* aDrawTarget
, nscoord aWidth
);
1737 static nsBoundingMetrics
AppUnitBoundsOfString(const char16_t
* aString
,
1739 nsFontMetrics
& aFontMetrics
,
1740 DrawTarget
* aDrawTarget
);
1742 static void DrawString(const nsIFrame
* aFrame
, nsFontMetrics
& aFontMetrics
,
1743 gfxContext
* aContext
, const char16_t
* aString
,
1744 int32_t aLength
, nsPoint aPoint
,
1745 ComputedStyle
* aComputedStyle
= nullptr,
1746 DrawStringFlags aFlags
= DrawStringFlags::Default
);
1748 static nsPoint
GetBackgroundFirstTilePos(const nsPoint
& aDest
,
1749 const nsPoint
& aFill
,
1750 const nsSize
& aRepeatSize
);
1753 * Supports only LTR or RTL. Bidi (mixed direction) is not supported.
1755 static void DrawUniDirString(const char16_t
* aString
, uint32_t aLength
,
1756 const nsPoint
& aPoint
,
1757 nsFontMetrics
& aFontMetrics
,
1758 gfxContext
& aContext
);
1761 * Helper function for drawing text-shadow. The callback's job
1762 * is to draw whatever needs to be blurred onto the given context.
1764 typedef void (*TextShadowCallback
)(gfxContext
* aCtx
, nsPoint aShadowOffset
,
1765 const nscolor
& aShadowColor
, void* aData
);
1767 static void PaintTextShadow(const nsIFrame
* aFrame
, gfxContext
* aContext
,
1768 const nsRect
& aTextRect
, const nsRect
& aDirtyRect
,
1769 const nscolor
& aForegroundColor
,
1770 TextShadowCallback aCallback
,
1771 void* aCallbackData
);
1774 * Gets the baseline to vertically center text from a font within a
1775 * line of specified height.
1776 * aIsInverted: true if the text is inverted relative to the block
1777 * direction, so that the block-dir "ascent" corresponds to font
1778 * descent. (Applies to sideways text in vertical-lr mode.)
1780 * Returns the baseline position relative to the top of the line.
1782 static nscoord
GetCenteredFontBaseline(nsFontMetrics
* aFontMetrics
,
1783 nscoord aLineHeight
, bool aIsInverted
);
1786 * Derive a baseline of |aFrame| (measured from its top border edge)
1787 * from its first in-flow line box (not descending into anything with
1788 * 'overflow' not 'visible', potentially including aFrame itself).
1790 * Returns true if a baseline was found (and fills in aResult).
1791 * Otherwise returns false.
1793 static bool GetFirstLineBaseline(mozilla::WritingMode aWritingMode
,
1794 const nsIFrame
* aFrame
, nscoord
* aResult
);
1797 * Just like GetFirstLineBaseline, except also returns the top and
1798 * bottom of the line with the baseline.
1800 * Returns true if a line was found (and fills in aResult).
1801 * Otherwise returns false.
1803 struct LinePosition
{
1804 nscoord mBStart
, mBaseline
, mBEnd
;
1806 LinePosition
operator+(nscoord aOffset
) const {
1807 LinePosition result
;
1808 result
.mBStart
= mBStart
+ aOffset
;
1809 result
.mBaseline
= mBaseline
+ aOffset
;
1810 result
.mBEnd
= mBEnd
+ aOffset
;
1814 static bool GetFirstLinePosition(mozilla::WritingMode aWritingMode
,
1815 const nsIFrame
* aFrame
,
1816 LinePosition
* aResult
);
1819 * Derive a baseline of |aFrame| (measured from its top border edge)
1820 * from its last in-flow line box (not descending into anything with
1821 * 'overflow' not 'visible', potentially including aFrame itself).
1823 * Returns true if a baseline was found (and fills in aResult).
1824 * Otherwise returns false.
1826 static bool GetLastLineBaseline(mozilla::WritingMode aWritingMode
,
1827 const nsIFrame
* aFrame
, nscoord
* aResult
);
1830 * Returns a block-dir coordinate relative to this frame's origin that
1831 * represents the logical block-end of the frame or its visible content,
1832 * whichever is further from the origin.
1833 * Relative positioning is ignored and margins and glyph bounds are not
1835 * This value will be >= mRect.BSize() and <= overflowRect.BEnd() unless
1836 * relative positioning is applied.
1838 static nscoord
CalculateContentBEnd(mozilla::WritingMode aWritingMode
,
1842 * Gets the closest frame (the frame passed in or one of its parents) that
1843 * qualifies as a "layer"; used in DOM0 methods that depends upon that
1844 * definition. This is the nearest frame that is either positioned or scrolled
1845 * (the child of a scroll frame).
1847 static nsIFrame
* GetClosestLayer(nsIFrame
* aFrame
);
1850 * Gets the graphics sampling filter for the frame
1852 static SamplingFilter
GetSamplingFilterForFrame(nsIFrame
* aFrame
);
1854 static inline void InitDashPattern(StrokeOptions
& aStrokeOptions
,
1855 mozilla::StyleBorderStyle aBorderStyle
) {
1856 if (aBorderStyle
== mozilla::StyleBorderStyle::Dotted
) {
1857 static Float dot
[] = {1.f
, 1.f
};
1858 aStrokeOptions
.mDashLength
= MOZ_ARRAY_LENGTH(dot
);
1859 aStrokeOptions
.mDashPattern
= dot
;
1860 } else if (aBorderStyle
== mozilla::StyleBorderStyle::Dashed
) {
1861 static Float dash
[] = {5.f
, 5.f
};
1862 aStrokeOptions
.mDashLength
= MOZ_ARRAY_LENGTH(dash
);
1863 aStrokeOptions
.mDashPattern
= dash
;
1865 aStrokeOptions
.mDashLength
= 0;
1866 aStrokeOptions
.mDashPattern
= nullptr;
1871 * Convert an nsRect to a gfxRect.
1873 static gfxRect
RectToGfxRect(const nsRect
& aRect
,
1874 int32_t aAppUnitsPerDevPixel
);
1876 static gfxPoint
PointToGfxPoint(const nsPoint
& aPoint
,
1877 int32_t aAppUnitsPerPixel
) {
1878 return gfxPoint(gfxFloat(aPoint
.x
) / aAppUnitsPerPixel
,
1879 gfxFloat(aPoint
.y
) / aAppUnitsPerPixel
);
1882 /* N.B. The only difference between variants of the Draw*Image
1883 * functions below is the type of the aImage argument.
1887 * Draw a background image. The image's dimensions are as specified in aDest;
1888 * the image itself is not consulted to determine a size.
1889 * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering
1892 * The context to draw to, already set up with an appropriate scale and
1893 * transform for drawing in app units.
1895 * The nsIFrame that we're drawing this image for.
1899 * The position and scaled area where one copy of the image should be drawn.
1900 * This area represents the image itself in its correct position as defined
1901 * with the background-position css property.
1903 * The area to be filled with copies of the image.
1904 * @param aRepeatSize
1905 * The distance between the positions of two subsequent repeats of the image.
1906 * Sizes larger than aDest.Size() create gaps between the images.
1908 * A point in aFill which we will ensure is pixel-aligned in the output.
1910 * Pixels outside this area may be skipped.
1911 * @param aImageFlags
1912 * Image flags of the imgIContainer::FLAG_* variety.
1913 * @param aExtendMode
1914 * How to extend the image over the dest rect.
1916 static ImgDrawResult
DrawBackgroundImage(
1917 gfxContext
& aContext
, nsIFrame
* aForFrame
, nsPresContext
* aPresContext
,
1918 imgIContainer
* aImage
, SamplingFilter aSamplingFilter
,
1919 const nsRect
& aDest
, const nsRect
& aFill
, const nsSize
& aRepeatSize
,
1920 const nsPoint
& aAnchor
, const nsRect
& aDirty
, uint32_t aImageFlags
,
1921 ExtendMode aExtendMode
, float aOpacity
);
1925 * See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering
1926 * @param aRenderingContext Where to draw the image, set up with an
1927 * appropriate scale and transform for drawing in
1929 * @param aComputedStyle The ComputedStyle of the nsIFrame (or
1930 * pseudo-element) for which this image is being
1932 * @param aImage The image.
1933 * @param aDest Where one copy of the image should mapped to.
1934 * @param aFill The area to be filled with copies of the
1936 * @param aAnchor A point in aFill which we will ensure is
1937 * pixel-aligned in the output.
1938 * @param aDirty Pixels outside this area may be skipped.
1939 * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety
1941 static ImgDrawResult
DrawImage(gfxContext
& aContext
,
1942 ComputedStyle
* aComputedStyle
,
1943 nsPresContext
* aPresContext
,
1944 imgIContainer
* aImage
,
1945 const SamplingFilter aSamplingFilter
,
1946 const nsRect
& aDest
, const nsRect
& aFill
,
1947 const nsPoint
& aAnchor
, const nsRect
& aDirty
,
1948 uint32_t aImageFlags
, float aOpacity
= 1.0);
1951 * Draw a whole image without scaling or tiling.
1953 * @param aRenderingContext Where to draw the image, set up with an
1954 * appropriate scale and transform for drawing in
1956 * @param aImage The image.
1957 * @param aDest The top-left where the image should be drawn.
1958 * @param aDirty If non-null, then pixels outside this area may
1960 * @param aSVGContext Optionally provides an SVGImageContext.
1961 * Callers should pass an SVGImageContext with at
1962 * least the viewport size set if aImage may be of
1963 * type imgIContainer::TYPE_VECTOR, or pass
1964 * Nothing() if it is of type
1965 * imgIContainer::TYPE_RASTER (to save cycles
1966 * constructing an SVGImageContext, since this
1967 * argument will be ignored for raster images).
1968 * @param aImageFlags Image flags of the imgIContainer::FLAG_* variety
1969 * @param aSourceArea If non-null, this area is extracted from
1970 * the image and drawn at aDest. It's
1971 * in appunits. For best results it should
1972 * be aligned with image pixels.
1974 static ImgDrawResult
DrawSingleUnscaledImage(
1975 gfxContext
& aContext
, nsPresContext
* aPresContext
, imgIContainer
* aImage
,
1976 const SamplingFilter aSamplingFilter
, const nsPoint
& aDest
,
1977 const nsRect
* aDirty
, const mozilla::Maybe
<SVGImageContext
>& aSVGContext
,
1978 uint32_t aImageFlags
, const nsRect
* aSourceArea
= nullptr);
1981 * Draw a whole image without tiling.
1983 * @param aRenderingContext Where to draw the image, set up with an
1984 * appropriate scale and transform for drawing in
1986 * @param aImage The image.
1987 * @param aDest The area that the image should fill.
1988 * @param aDirty Pixels outside this area may be skipped.
1989 * @param aSVGContext Optionally provides an SVGImageContext.
1990 * Callers should pass an SVGImageContext with at
1991 * least the viewport size set if aImage may be of
1992 * type imgIContainer::TYPE_VECTOR, or pass
1993 * Nothing() if it is of type
1994 * imgIContainer::TYPE_RASTER (to save cycles
1995 * constructing an SVGImageContext, since this
1996 * argument will be ignored for raster images).
1997 * @param aImageFlags Image flags of the imgIContainer::FLAG_*
1999 * @param aAnchor If non-null, a point which we will ensure
2000 * is pixel-aligned in the output.
2001 * @param aSourceArea If non-null, this area is extracted from
2002 * the image and drawn in aDest. It's
2003 * in appunits. For best results it should
2004 * be aligned with image pixels.
2006 static ImgDrawResult
DrawSingleImage(
2007 gfxContext
& aContext
, nsPresContext
* aPresContext
, imgIContainer
* aImage
,
2008 const SamplingFilter aSamplingFilter
, const nsRect
& aDest
,
2009 const nsRect
& aDirty
, const mozilla::Maybe
<SVGImageContext
>& aSVGContext
,
2010 uint32_t aImageFlags
, const nsPoint
* aAnchorPoint
= nullptr,
2011 const nsRect
* aSourceArea
= nullptr);
2014 * Given an imgIContainer, this method attempts to obtain an intrinsic
2015 * px-valued height & width for it. If the imgIContainer has a non-pixel
2016 * value for either height or width, this method tries to generate a pixel
2017 * value for that dimension using the intrinsic ratio (if available). The
2018 * intrinsic ratio will be assigned to aIntrinsicRatio; if there's no
2019 * intrinsic ratio then (0, 0) will be assigned.
2021 * This method will always set aGotWidth and aGotHeight to indicate whether
2022 * we were able to successfully obtain (or compute) a value for each
2025 * NOTE: This method is similar to ComputeSizeWithIntrinsicDimensions. The
2026 * difference is that this one is simpler and is suited to places where we
2027 * have less information about the frame tree.
2029 static void ComputeSizeForDrawing(imgIContainer
* aImage
,
2030 CSSIntSize
& aImageSize
,
2031 AspectRatio
& aIntrinsicRatio
,
2032 bool& aGotWidth
, bool& aGotHeight
);
2035 * Given an imgIContainer, this method attempts to obtain an intrinsic
2036 * px-valued height & width for it. If the imgIContainer has a non-pixel
2037 * value for either height or width, this method tries to generate a pixel
2038 * value for that dimension using the intrinsic ratio (if available). If,
2039 * after trying all these methods, no value is available for one or both
2040 * dimensions, the corresponding dimension of aFallbackSize is used instead.
2042 static CSSIntSize
ComputeSizeForDrawingWithFallback(
2043 imgIContainer
* aImage
, const nsSize
& aFallbackSize
);
2046 * Given the image container, frame, and dest rect, determine the best fitting
2047 * size to decode the image at, and calculate any necessary SVG parameters.
2049 static mozilla::gfx::IntSize
ComputeImageContainerDrawingParameters(
2050 imgIContainer
* aImage
, nsIFrame
* aForFrame
,
2051 const LayoutDeviceRect
& aDestRect
, const StackingContextHelper
& aSc
,
2052 uint32_t aFlags
, mozilla::Maybe
<SVGImageContext
>& aSVGContext
);
2055 * Given a source area of an image (in appunits) and a destination area
2056 * that we want to map that source area too, computes the area that
2057 * would be covered by the whole image. This is useful for passing to
2058 * the aDest parameter of DrawImage, when we want to draw a subimage
2059 * of an overall image.
2061 static nsRect
GetWholeImageDestination(const nsSize
& aWholeImageSize
,
2062 const nsRect
& aImageSourceArea
,
2063 const nsRect
& aDestArea
);
2066 * Given an image container and an orientation, returns an image container
2067 * that contains the same image, reoriented appropriately. May return the
2068 * original image container if no changes are needed.
2070 * @param aContainer The image container to apply the orientation to.
2071 * @param aOrientation The desired orientation.
2073 static already_AddRefed
<imgIContainer
> OrientImage(
2074 imgIContainer
* aContainer
,
2075 const mozilla::StyleImageOrientation
& aOrientation
);
2078 * Determine if any corner radius is of nonzero size
2079 * @param aCorners the |BorderRadius| object to check
2080 * @return true unless all the coordinates are 0%, 0 or null.
2082 * A corner radius with one dimension zero and one nonzero is
2083 * treated as a nonzero-radius corner, even though it will end up
2084 * being rendered like a zero-radius corner. This is because such
2085 * corners are not expected to appear outside of test cases, and it's
2086 * simpler to implement the test this way.
2088 static bool HasNonZeroCorner(const mozilla::BorderRadius
& aCorners
);
2091 * Determine if there is any corner radius on corners adjacent to the
2094 static bool HasNonZeroCornerOnSide(const mozilla::BorderRadius
& aCorners
,
2095 mozilla::Side aSide
);
2098 * Determine if a widget is likely to require transparency or translucency.
2099 * @param aBackgroundFrame The frame that the background is set on. For
2100 * <window>s, this will be the canvas frame.
2101 * @param aCSSRootFrame The frame that holds CSS properties affecting
2102 * the widget's transparency. For menupopups,
2103 * aBackgroundFrame and aCSSRootFrame will be the
2105 * @return a value suitable for passing to SetWindowTranslucency.
2107 static nsTransparencyMode
GetFrameTransparency(nsIFrame
* aBackgroundFrame
,
2108 nsIFrame
* aCSSRootFrame
);
2111 * A frame is a popup if it has its own floating window. Menus, panels
2112 * and combobox dropdowns are popups.
2114 static bool IsPopup(const nsIFrame
* aFrame
);
2117 * Find the nearest "display root". This is the nearest enclosing
2118 * popup frame or the root prescontext's root frame.
2120 static nsIFrame
* GetDisplayRootFrame(nsIFrame
* aFrame
);
2123 * Get the reference frame that would be used when constructing a
2124 * display item for this frame. Rather than using their own frame
2125 * as a reference frame.)
2127 * This duplicates some of the logic of GetDisplayRootFrame above and
2128 * of nsDisplayListBuilder::FindReferenceFrameFor.
2130 * If you have an nsDisplayListBuilder, you should get the reference
2131 * frame from it instead of calling this.
2133 static nsIFrame
* GetReferenceFrame(nsIFrame
* aFrame
);
2136 * Get textrun construction flags determined by a given style; in particular
2137 * some combination of:
2138 * -- TEXT_DISABLE_OPTIONAL_LIGATURES if letter-spacing is in use
2139 * -- TEXT_OPTIMIZE_SPEED if the text-rendering CSS property and font size
2140 * and prefs indicate we should be optimizing for speed over quality
2142 static mozilla::gfx::ShapedTextFlags
GetTextRunFlagsForStyle(
2143 ComputedStyle
* aComputedStyle
, nsPresContext
* aPresContext
,
2144 const nsStyleFont
* aStyleFont
, const nsStyleText
* aStyleText
,
2145 nscoord aLetterSpacing
);
2148 * Get orientation flags for textrun construction.
2150 static mozilla::gfx::ShapedTextFlags
GetTextRunOrientFlagsForStyle(
2151 ComputedStyle
* aComputedStyle
);
2154 * Takes two rectangles whose origins must be the same, and computes
2155 * the difference between their union and their intersection as two
2156 * rectangles. (This difference is a superset of the difference
2157 * between the two rectangles.)
2159 static void GetRectDifferenceStrips(const nsRect
& aR1
, const nsRect
& aR2
,
2160 nsRect
* aHStrip
, nsRect
* aVStrip
);
2163 * Get a device context that can be used to get up-to-date device
2164 * dimensions for the given window. For some reason, this is more
2165 * complicated than it ought to be in multi-monitor situations.
2167 static nsDeviceContext
* GetDeviceContextForScreenInfo(
2168 nsPIDOMWindowOuter
* aWindow
);
2171 * Some frames with 'position: fixed' (nsStyleDisplay::mPosition ==
2172 * StylePositionProperty::Fixed) are not really fixed positioned, since
2173 * they're inside an element with -moz-transform. This function says
2174 * whether such an element is a real fixed-pos element.
2176 static bool IsReallyFixedPos(const nsIFrame
* aFrame
);
2179 * This function says whether `aFrame` would really be a fixed positioned
2180 * frame if the frame was created with StylePositionProperty::Fixed.
2182 * It is effectively the same as IsReallyFixedPos, but without asserting the
2183 * position value. Use it only when you know what you're doing, like when
2184 * tearing down the frame tree (where styles may have changed due to
2185 * ::first-line reparenting and rule changes at the same time).
2187 static bool MayBeReallyFixedPos(const nsIFrame
* aFrame
);
2190 * Returns true if |aFrame| is inside position:fixed subtree.
2192 static bool IsInPositionFixedSubtree(const nsIFrame
* aFrame
);
2195 * Obtain a SourceSurface from the given DOM element, if possible.
2196 * This obtains the most natural surface from the element; that
2197 * is, the one that can be obtained with the fewest conversions.
2199 * The flags below can modify the behaviour of this function. The
2200 * result is returned as a SurfaceFromElementResult struct, also
2203 * Currently, this will do:
2204 * - HTML Canvas elements: will return the underlying canvas surface
2205 * - HTML Video elements: will return the current video frame
2206 * - Image elements: will return the image
2208 * The above results are modified by the below flags (copying,
2209 * forcing image surface, etc.).
2213 /* When creating a new surface, create an image surface */
2214 SFE_WANT_IMAGE_SURFACE
= 1 << 0,
2215 /* Whether to extract the first frame (as opposed to the
2216 current frame) in the case that the element is an image. */
2217 SFE_WANT_FIRST_FRAME_IF_IMAGE
= 1 << 1,
2218 /* Whether we should skip colorspace/gamma conversion */
2219 SFE_NO_COLORSPACE_CONVERSION
= 1 << 2,
2220 /* Caller handles SFER::mAlphaType = NonPremult */
2221 SFE_ALLOW_NON_PREMULT
= 1 << 3,
2222 /* Whether we should skip getting a surface for vector images and
2223 return a DirectDrawInfo containing an imgIContainer instead. */
2224 SFE_NO_RASTERIZING_VECTORS
= 1 << 4,
2225 /* If image type is vector, the return surface size will same as
2226 element size, not image's intrinsic size. */
2227 SFE_USE_ELEMENT_SIZE_IF_VECTOR
= 1 << 5
2230 struct DirectDrawInfo
{
2231 /* imgIContainer to directly draw to a context */
2232 nsCOMPtr
<imgIContainer
> mImgContainer
;
2233 /* which frame to draw */
2234 uint32_t mWhichFrame
;
2235 /* imgIContainer flags to use when drawing */
2236 uint32_t mDrawingFlags
;
2239 struct SurfaceFromElementResult
{
2240 friend class mozilla::dom::CanvasRenderingContext2D
;
2241 friend class nsLayoutUtils
;
2243 /* If SFEResult contains a valid surface, it either mLayersImage or
2244 * mSourceSurface will be non-null, and GetSourceSurface() will not be null.
2246 * For valid surfaces, mSourceSurface may be null if mLayersImage is
2247 * non-null, but GetSourceSurface() will create mSourceSurface from
2248 * mLayersImage when called.
2251 /* Video elements (at least) often are already decoded as layers::Images. */
2252 RefPtr
<mozilla::layers::Image
> mLayersImage
;
2255 /* GetSourceSurface() fills this and returns its non-null value if this
2256 * SFEResult was successful. */
2257 RefPtr
<mozilla::gfx::SourceSurface
> mSourceSurface
;
2260 /* Contains info for drawing when there is no mSourceSurface. */
2261 DirectDrawInfo mDrawInfo
;
2263 /* The size of the surface */
2264 mozilla::gfx::IntSize mSize
;
2265 /* The size the surface is intended to be rendered at */
2266 mozilla::gfx::IntSize mIntrinsicSize
;
2267 /* The principal associated with the element whose surface was returned.
2268 If there is a surface, this will never be null. */
2269 nsCOMPtr
<nsIPrincipal
> mPrincipal
;
2270 /* The image request, if the element is an nsIImageLoadingContent */
2271 nsCOMPtr
<imgIRequest
> mImageRequest
;
2272 /* True if cross-origins redirects have been done in order to load this
2274 bool mHadCrossOriginRedirects
;
2275 /* Whether the element was "write only", that is, the bits should not be
2276 * exposed to content */
2278 /* Whether the element was still loading. Some consumers need to handle
2279 this case specially. */
2280 bool mIsStillLoading
;
2281 /* Whether the element has a valid size. */
2283 /* Whether the element used CORS when loading. */
2286 gfxAlphaType mAlphaType
;
2290 SurfaceFromElementResult();
2292 // Gets mSourceSurface, or makes a SourceSurface from mLayersImage.
2293 const RefPtr
<mozilla::gfx::SourceSurface
>& GetSourceSurface();
2296 // This function can be called on any thread.
2297 static SurfaceFromElementResult
SurfaceFromOffscreenCanvas(
2298 mozilla::dom::OffscreenCanvas
* aOffscreenCanvas
, uint32_t aSurfaceFlags
,
2299 RefPtr
<DrawTarget
>& aTarget
);
2300 static SurfaceFromElementResult
SurfaceFromOffscreenCanvas(
2301 mozilla::dom::OffscreenCanvas
* aOffscreenCanvas
,
2302 uint32_t aSurfaceFlags
= 0) {
2303 RefPtr
<DrawTarget
> target
= nullptr;
2304 return SurfaceFromOffscreenCanvas(aOffscreenCanvas
, aSurfaceFlags
, target
);
2307 static SurfaceFromElementResult
SurfaceFromElement(
2308 mozilla::dom::Element
* aElement
, uint32_t aSurfaceFlags
,
2309 RefPtr
<DrawTarget
>& aTarget
);
2310 static SurfaceFromElementResult
SurfaceFromElement(
2311 mozilla::dom::Element
* aElement
, uint32_t aSurfaceFlags
= 0) {
2312 RefPtr
<DrawTarget
> target
= nullptr;
2313 return SurfaceFromElement(aElement
, aSurfaceFlags
, target
);
2316 // There are a bunch of callers of SurfaceFromElement. Just mark it as
2317 MOZ_CAN_RUN_SCRIPT_BOUNDARY
2318 static SurfaceFromElementResult
SurfaceFromElement(
2319 nsIImageLoadingContent
* aElement
, uint32_t aSurfaceFlags
,
2320 RefPtr
<DrawTarget
>& aTarget
);
2321 // Need an HTMLImageElement overload, because otherwise the
2322 // nsIImageLoadingContent and mozilla::dom::Element overloads are ambiguous
2323 // for HTMLImageElement.
2324 static SurfaceFromElementResult
SurfaceFromElement(
2325 mozilla::dom::HTMLImageElement
* aElement
, uint32_t aSurfaceFlags
,
2326 RefPtr
<DrawTarget
>& aTarget
);
2327 static SurfaceFromElementResult
SurfaceFromElement(
2328 mozilla::dom::HTMLCanvasElement
* aElement
, uint32_t aSurfaceFlags
,
2329 RefPtr
<DrawTarget
>& aTarget
);
2330 static SurfaceFromElementResult
SurfaceFromElement(
2331 mozilla::dom::HTMLVideoElement
* aElement
, uint32_t aSurfaceFlags
,
2332 RefPtr
<DrawTarget
>& aTarget
);
2335 * When the document is editable by contenteditable attribute of its root
2336 * content or body content.
2338 * Be aware, this returns nullptr if it's in designMode.
2342 * <html contenteditable="true"><body></body></html>
2343 * returns the <html>.
2345 * <html><body contenteditable="true"></body></html>
2346 * <body contenteditable="true"></body>
2347 * With these cases, this returns the <body>.
2348 * NOTE: The latter case isn't created normally, however, it can be
2349 * created by script with XHTML.
2351 * <body><p contenteditable="true"></p></body>
2352 * returns nullptr because <body> isn't editable.
2354 static mozilla::dom::Element
* GetEditableRootContentByContentEditable(
2355 mozilla::dom::Document
* aDocument
);
2357 static void AddExtraBackgroundItems(nsDisplayListBuilder
* aBuilder
,
2358 nsDisplayList
* aList
, nsIFrame
* aFrame
,
2359 const nsRect
& aCanvasArea
,
2360 const nsRegion
& aVisibleRegion
,
2364 * Returns true if the passed in prescontext needs the dark grey background
2365 * that goes behind the page of a print preview presentation.
2367 static bool NeedsPrintPreviewBackground(nsPresContext
* aPresContext
);
2370 * Types used by the helpers for InspectorUtils.getUsedFontFaces.
2371 * The API returns an array (UsedFontFaceList) that owns the
2372 * InspectorFontFace instances, but during range traversal we also
2373 * want to maintain a mapping from gfxFontEntry to InspectorFontFace
2374 * records, so use a temporary hashtable for that.
2376 typedef nsTArray
<mozilla::UniquePtr
<mozilla::dom::InspectorFontFace
>>
2378 typedef nsDataHashtable
<nsPtrHashKey
<gfxFontEntry
>,
2379 mozilla::dom::InspectorFontFace
*>
2383 * Adds all font faces used in the frame tree starting from aFrame
2384 * to the list aFontFaceList.
2385 * aMaxRanges: maximum number of text ranges to record for each face.
2387 static nsresult
GetFontFacesForFrames(nsIFrame
* aFrame
,
2388 UsedFontFaceList
& aResult
,
2389 UsedFontFaceTable
& aFontFaces
,
2390 uint32_t aMaxRanges
,
2391 bool aSkipCollapsedWhitespace
);
2394 * Adds all font faces used within the specified range of text in aFrame,
2395 * and optionally its continuations, to the list in aFontFaceList.
2396 * Pass 0 and INT32_MAX for aStartOffset and aEndOffset to specify the
2397 * entire text is to be considered.
2398 * aMaxRanges: maximum number of text ranges to record for each face.
2400 static void GetFontFacesForText(nsIFrame
* aFrame
, int32_t aStartOffset
,
2401 int32_t aEndOffset
, bool aFollowContinuations
,
2402 UsedFontFaceList
& aResult
,
2403 UsedFontFaceTable
& aFontFaces
,
2404 uint32_t aMaxRanges
,
2405 bool aSkipCollapsedWhitespace
);
2408 * Walks the frame tree starting at aFrame looking for textRuns.
2409 * If |clear| is true, just clears the TEXT_RUN_MEMORY_ACCOUNTED flag
2410 * on each textRun found (and |aMallocSizeOf| is not used).
2411 * If |clear| is false, adds the storage used for each textRun to the
2412 * total, and sets the TEXT_RUN_MEMORY_ACCOUNTED flag to avoid double-
2413 * accounting. (Runs with this flag already set will be skipped.)
2414 * Expected usage pattern is therefore to call twice:
2415 * (void)SizeOfTextRunsForFrames(rootFrame, nullptr, true);
2416 * total = SizeOfTextRunsForFrames(rootFrame, mallocSizeOf, false);
2418 static size_t SizeOfTextRunsForFrames(nsIFrame
* aFrame
,
2419 mozilla::MallocSizeOf aMallocSizeOf
,
2423 * Returns true if |aFrame| has an animation of a property in |aPropertySet|
2424 * regardless of whether any property in the set is overridden by an
2427 static bool HasAnimationOfPropertySet(const nsIFrame
* aFrame
,
2428 const nsCSSPropertyIDSet
& aPropertySet
);
2431 * A variant of the above HasAnimationOfPropertySet that takes an optional
2432 * EffectSet parameter as an optimization to save redundant lookups of the
2435 static bool HasAnimationOfPropertySet(const nsIFrame
* aFrame
,
2436 const nsCSSPropertyIDSet
& aPropertySet
,
2437 mozilla::EffectSet
* aEffectSet
);
2440 * A variant of the above HasAnimationOfPropertySet. This is especially for
2441 * tranform-like properties with motion-path.
2442 * For transform-like properties with motion-path, we need to check if
2443 * offset-path has effect. If we don't have any animation on offset-path and
2444 * offset-path is none, there is no effective motion-path, and so we don't
2445 * care other offset-* properties. In this case, this function only checks the
2446 * rest of transform-like properties (i.e. transform/translate/rotate/scale).
2448 static bool HasAnimationOfTransformAndMotionPath(const nsIFrame
* aFrame
);
2451 * Returns true if |aFrame| has an animation of |aProperty| which is
2452 * not overridden by !important rules.
2454 static bool HasEffectiveAnimation(const nsIFrame
* aFrame
,
2455 nsCSSPropertyID aProperty
);
2458 * Returns true if |aFrame| has an animation where at least one of the
2459 * properties in |aPropertySet| is not overridden by !important rules.
2461 * If |aPropertySet| includes transform-like properties (transform, rotate,
2462 * etc.) however, this will return false if any of the transform-like
2463 * properties is overriden by an !important rule since these properties should
2464 * be combined on the compositor.
2466 static bool HasEffectiveAnimation(const nsIFrame
* aFrame
,
2467 const nsCSSPropertyIDSet
& aPropertySet
);
2470 * Returns all effective animated CSS properties on |aStyleFrame| and its
2471 * corresponding primary frame (for content that makes this distinction,
2472 * notable display:table content) that can be animated on the compositor.
2474 * Properties that can be animated on the compositor but which are overridden
2475 * by !important rules are not returned.
2477 * Unlike HasEffectiveAnimation, however, this does not check the set of
2478 * transform-like properties to ensure that if any such properties are
2479 * overridden by !important rules, the other transform-like properties are
2480 * not run on the compositor (see bug 1534884).
2482 static nsCSSPropertyIDSet
GetAnimationPropertiesForCompositor(
2483 const nsIFrame
* aStyleFrame
);
2486 * Checks if off-main-thread animations are enabled.
2488 static bool AreAsyncAnimationsEnabled();
2491 * Checks if retained display lists are enabled.
2493 static bool AreRetainedDisplayListsEnabled();
2495 static bool DisplayRootHasRetainedDisplayListBuilder(nsIFrame
* aFrame
);
2498 * Find a suitable scale for a element (aFrame's content) over the course of
2499 * any animations and transitions of the CSS transform property on the element
2500 * that run on the compositor thread. It will check the maximum and minimum
2501 * scale during the animations and transitions and return a suitable value for
2502 * performance and quality. Will return scale(1,1) if there are no such
2503 * animations. Always returns a positive value.
2504 * @param aVisibleSize is the size of the area we want to paint
2505 * @param aDisplaySize is the size of the display area of the pres context
2507 static Size
ComputeSuitableScaleForAnimation(const nsIFrame
* aFrame
,
2508 const nsSize
& aVisibleSize
,
2509 const nsSize
& aDisplaySize
);
2512 * Checks whether we want to use the GPU to scale images when
2515 static bool GPUImageScalingEnabled();
2518 * Unions the overflow areas of the children of aFrame with aOverflowAreas.
2519 * aSkipChildLists specifies any child lists that should be skipped.
2520 * kSelectPopupList and kPopupList are always skipped.
2522 static void UnionChildOverflow(
2523 nsIFrame
* aFrame
, nsOverflowAreas
& aOverflowAreas
,
2524 mozilla::layout::FrameChildListIDs aSkipChildLists
=
2525 mozilla::layout::FrameChildListIDs());
2528 * Return the font size inflation *ratio* for a given frame. This is
2529 * the factor by which font sizes should be inflated; it is never
2532 static float FontSizeInflationFor(const nsIFrame
* aFrame
);
2535 * Perform the first half of the computation of FontSizeInflationFor
2537 * This includes determining whether inflation should be performed
2538 * within this container and returning 0 if it should not be.
2540 * The result is guaranteed not to vary between line participants
2541 * (inlines, text frames) within a line.
2543 * The result should not be used directly since font sizes slightly
2544 * above the minimum should always be adjusted as done by
2545 * FontSizeInflationInner.
2547 static nscoord
InflationMinFontSizeFor(const nsIFrame
* aFrame
);
2550 * Perform the second half of the computation done by
2551 * FontSizeInflationFor (see above).
2553 * aMinFontSize must be the result of one of the
2554 * InflationMinFontSizeFor methods above.
2556 static float FontSizeInflationInner(const nsIFrame
* aFrame
,
2557 nscoord aMinFontSize
);
2559 static bool FontSizeInflationEnabled(nsPresContext
* aPresContext
);
2562 * Returns true if the nglayout.debug.invalidation pref is set to true.
2564 static bool InvalidationDebuggingIsEnabled() {
2565 return mozilla::StaticPrefs::nglayout_debug_invalidation() ||
2566 getenv("MOZ_DUMP_INVALIDATION") != 0;
2569 static void Initialize();
2570 static void Shutdown();
2573 * Register an imgIRequest object with a refresh driver.
2575 * @param aPresContext The nsPresContext whose refresh driver we want to
2577 * @param aRequest A pointer to the imgIRequest object which the client wants
2578 * to register with the refresh driver.
2579 * @param aRequestRegistered A pointer to a boolean value which indicates
2580 * whether the given image request is registered. If
2581 * *aRequestRegistered is true, then this request will not be
2582 * registered again. If the request is registered by this function,
2583 * then *aRequestRegistered will be set to true upon the completion of
2587 static void RegisterImageRequest(nsPresContext
* aPresContext
,
2588 imgIRequest
* aRequest
,
2589 bool* aRequestRegistered
);
2592 * Register an imgIRequest object with a refresh driver, but only if the
2593 * request is for an image that is animated.
2595 * @param aPresContext The nsPresContext whose refresh driver we want to
2597 * @param aRequest A pointer to the imgIRequest object which the client wants
2598 * to register with the refresh driver.
2599 * @param aRequestRegistered A pointer to a boolean value which indicates
2600 * whether the given image request is registered. If
2601 * *aRequestRegistered is true, then this request will not be
2602 * registered again. If the request is registered by this function,
2603 * then *aRequestRegistered will be set to true upon the completion of
2607 static void RegisterImageRequestIfAnimated(nsPresContext
* aPresContext
,
2608 imgIRequest
* aRequest
,
2609 bool* aRequestRegistered
);
2612 * Deregister an imgIRequest object from a refresh driver.
2614 * @param aPresContext The nsPresContext whose refresh driver we want to
2616 * @param aRequest A pointer to the imgIRequest object with which the client
2617 * previously registered and now wants to deregister from the refresh
2619 * @param aRequestRegistered A pointer to a boolean value which indicates
2620 * whether the given image request is registered. If
2621 * *aRequestRegistered is false, then this request will not be
2622 * deregistered. If the request is deregistered by this function,
2623 * then *aRequestRegistered will be set to false upon the completion of
2626 static void DeregisterImageRequest(nsPresContext
* aPresContext
,
2627 imgIRequest
* aRequest
,
2628 bool* aRequestRegistered
);
2631 * Shim to nsCSSFrameConstructor::PostRestyleEvent. Exists so that we
2632 * can avoid including nsCSSFrameConstructor.h and all its dependencies
2635 static void PostRestyleEvent(mozilla::dom::Element
*, mozilla::RestyleHint
,
2636 nsChangeHint aMinChangeHint
);
2639 * Updates a pair of x and y distances if a given point is closer to a given
2640 * rectangle than the original distance values. If aPoint is closer to
2641 * aRect than aClosestXDistance and aClosestYDistance indicate, then those
2642 * two variables are updated with the distance between aPoint and aRect,
2643 * and true is returned. If aPoint is not closer, then aClosestXDistance
2644 * and aClosestYDistance are left unchanged, and false is returned.
2646 * Distances are measured in the two dimensions separately; a closer x
2647 * distance beats a closer y distance.
2649 template <typename PointType
, typename RectType
, typename CoordType
>
2650 static bool PointIsCloserToRect(PointType aPoint
, const RectType
& aRect
,
2651 CoordType
& aClosestXDistance
,
2652 CoordType
& aClosestYDistance
);
2654 * Computes the box shadow rect for the frame, or returns an empty rect if
2655 * there are no shadows.
2657 * @param aFrame Frame to compute shadows for.
2658 * @param aFrameSize Size of aFrame (in case it hasn't been set yet).
2660 static nsRect
GetBoxShadowRectForFrame(nsIFrame
* aFrame
,
2661 const nsSize
& aFrameSize
);
2665 * Assert that there are no duplicate continuations of the same frame
2666 * within aFrameList. Optimize the tests by assuming that all frames
2667 * in aFrameList have parent aContainer.
2669 static void AssertNoDuplicateContinuations(nsIFrame
* aContainer
,
2670 const nsFrameList
& aFrameList
);
2673 * Assert that the frame tree rooted at |aSubtreeRoot| is empty, i.e.,
2674 * that it contains no first-in-flows.
2676 static void AssertTreeOnlyEmptyNextInFlows(nsIFrame
* aSubtreeRoot
);
2680 * Helper method to get touch action behaviour from the frame
2682 static mozilla::StyleTouchAction
GetTouchActionFromFrame(nsIFrame
* aFrame
);
2685 * Helper method to transform |aBounds| from aFrame to aAncestorFrame,
2686 * and combine it with |aPreciseTargetDest| if it is axis-aligned, or
2687 * combine it with |aImpreciseTargetDest| if not. The transformed rect is
2688 * clipped to |aClip|; if |aClip| has rounded corners, that also causes
2689 * the imprecise target to be used.
2691 static void TransformToAncestorAndCombineRegions(
2692 const nsRegion
& aRegion
, nsIFrame
* aFrame
, const nsIFrame
* aAncestorFrame
,
2693 nsRegion
* aPreciseTargetDest
, nsRegion
* aImpreciseTargetDest
,
2694 mozilla::Maybe
<Matrix4x4Flagged
>* aMatrixCache
,
2695 const mozilla::DisplayItemClip
* aClip
);
2698 * Populate aOutSize with the size of the content viewer corresponding
2699 * to the given prescontext. Return true if the size was set, false
2702 enum class SubtractDynamicToolbar
{ No
, Yes
};
2703 static bool GetContentViewerSize(
2704 nsPresContext
* aPresContext
, LayoutDeviceIntSize
& aOutSize
,
2705 SubtractDynamicToolbar
= SubtractDynamicToolbar::Yes
);
2708 static bool UpdateCompositionBoundsForRCDRSF(
2709 mozilla::ParentLayerRect
& aCompBounds
, nsPresContext
* aPresContext
);
2713 * Calculate the compostion size for a frame. See FrameMetrics.h for
2714 * defintion of composition size (or bounds).
2715 * Note that for the root content document's root scroll frame (RCD-RSF),
2716 * the returned size does not change as the document's resolution changes,
2717 * but for all other frames it does. This means that callers that pass in
2718 * a frame that may or may not be the RCD-RSF (which is most callers),
2719 * are likely to need special-case handling of the RCD-RSF.
2721 static nsSize
CalculateCompositionSizeForFrame(
2722 nsIFrame
* aFrame
, bool aSubtractScrollbars
= true,
2723 const nsSize
* aOverrideScrollPortSize
= nullptr);
2726 * Calculate the composition size for the root scroll frame of the root
2728 * @param aFrame A frame in the root content document (or a descendant of it).
2729 * @param aIsRootContentDocRootScrollFrame Whether aFrame is already the root
2730 * scroll frame of the root content document. In this case we just
2731 * use aFrame's own composition size.
2732 * @param aMetrics A partially populated FrameMetrics for aFrame. Must have at
2733 * least mCompositionBounds, mCumulativeResolution, and
2734 * mDevPixelsPerCSSPixel set.
2736 static CSSSize
CalculateRootCompositionSize(
2737 nsIFrame
* aFrame
, bool aIsRootContentDocRootScrollFrame
,
2738 const FrameMetrics
& aMetrics
);
2741 * Calculate the scrollable rect for a frame. See FrameMetrics.h for
2742 * defintion of scrollable rect. aScrollableFrame is the scroll frame to
2743 * calculate the scrollable rect for. If it's null then we calculate the
2744 * scrollable rect as the rect of the root frame.
2746 static nsRect
CalculateScrollableRectForFrame(
2747 nsIScrollableFrame
* aScrollableFrame
, nsIFrame
* aRootFrame
);
2750 * Calculate the expanded scrollable rect for a frame. See FrameMetrics.h for
2751 * defintion of expanded scrollable rect.
2753 static nsRect
CalculateExpandedScrollableRect(nsIFrame
* aFrame
);
2756 * Returns true if the widget owning the given frame uses asynchronous
2759 static bool UsesAsyncScrolling(nsIFrame
* aFrame
);
2762 * Returns true if the widget owning the given frame has builtin APZ support
2765 static bool AsyncPanZoomEnabled(nsIFrame
* aFrame
);
2768 * Returns the current APZ Resolution Scale. When Java Pan/Zoom is
2769 * enabled in Fennec it will always return 1.0.
2771 static float GetCurrentAPZResolutionScale(PresShell
* aPresShell
);
2774 * Returns true if aDocument should be allowed to use resolution
2777 static bool AllowZoomingForDocument(const mozilla::dom::Document
* aDocument
);
2780 * Returns true if we need to disable async scrolling for this particular
2781 * element. Note that this does a partial disabling - the displayport still
2782 * exists but uses a very small margin, and the compositor doesn't apply the
2783 * async transform. However, the content may still be layerized.
2785 static bool ShouldDisableApzForElement(nsIContent
* aContent
);
2788 * Log a key/value pair as "additional data" (not associated with a paint)
2790 * While the data is not associated with a paint, the APZTestData object
2791 * is still owned by {Client,WebRender}LayerManager, so we need to be passed
2792 * something from which we can derive the layer manager.
2793 * This function takes a display list builder as the object to derive the
2794 * layer manager from, to facilitate logging test data during display list
2795 * building, but other overloads that take other objects could be added if
2798 static void LogAdditionalTestData(nsDisplayListBuilder
* aBuilder
,
2799 const std::string
& aKey
,
2800 const std::string
& aValue
);
2803 * Log a key/value pair for APZ testing during a paint.
2804 * @param aManager The data will be written to the APZTestData associated
2805 * with this layer manager.
2806 * @param aScrollId Identifies the scroll frame to which the data pertains.
2807 * @param aKey The key under which to log the data.
2808 * @param aValue The value of the data to be logged.
2810 static void LogTestDataForPaint(mozilla::layers::LayerManager
* aManager
,
2811 ViewID aScrollId
, const std::string
& aKey
,
2812 const std::string
& aValue
) {
2813 DoLogTestDataForPaint(aManager
, aScrollId
, aKey
, aValue
);
2817 * A convenience overload of LogTestDataForPaint() that accepts any type
2818 * as the value, and passes it through mozilla::ToString() to obtain a string
2819 * value. The type passed must support streaming to an std::ostream.
2821 template <typename Value
>
2822 static void LogTestDataForPaint(mozilla::layers::LayerManager
* aManager
,
2823 ViewID aScrollId
, const std::string
& aKey
,
2824 const Value
& aValue
) {
2825 DoLogTestDataForPaint(aManager
, aScrollId
, aKey
, mozilla::ToString(aValue
));
2829 * Calculate a basic FrameMetrics with enough fields set to perform some
2830 * layout calculations. The fields set are dev-to-css ratio, pres shell
2831 * resolution, cumulative resolution, zoom, composition size, root
2832 * composition size, scroll offset and scrollable rect.
2834 * Note that for the RCD-RSF, the scroll offset returned is the layout
2835 * viewport offset; if you need the visual viewport offset, that needs to
2836 * be queried independently via PresShell::GetVisualViewportOffset().
2838 * By contrast, ComputeFrameMetrics() computes all the fields, but requires
2839 * extra inputs and can only be called during frame layer building.
2841 static FrameMetrics
CalculateBasicFrameMetrics(
2842 nsIScrollableFrame
* aScrollFrame
);
2845 * Calculate a default set of displayport margins for the given scrollframe
2846 * and set them on the scrollframe's content element. The margins are set with
2847 * the default priority, which may clobber previously set margins. The repaint
2848 * mode provided is passed through to the call to SetDisplayPortMargins.
2849 * The |aScrollFrame| parameter must be non-null and queryable to an nsIFrame.
2850 * @return true iff the call to SetDisplayPortMargins returned true.
2852 static bool CalculateAndSetDisplayPortMargins(
2853 nsIScrollableFrame
* aScrollFrame
, RepaintMode aRepaintMode
);
2856 * If |aScrollFrame| WantsAsyncScroll() and we don't have a scrollable
2857 * displayport yet (as tracked by |aBuilder|), calculate and set a
2860 * If this is called during display list building pass DoNotRepaint in
2863 * Returns true if there is a displayport on an async scrollable scrollframe
2864 * after this call, either because one was just added or it already existed.
2866 static bool MaybeCreateDisplayPort(nsDisplayListBuilder
* aBuilder
,
2867 nsIFrame
* aScrollFrame
,
2868 RepaintMode aRepaintMode
);
2870 static nsIScrollableFrame
* GetAsyncScrollableAncestorFrame(nsIFrame
* aTarget
);
2873 * Sets a zero margin display port on all proper ancestors of aFrame that
2874 * are async scrollable.
2876 static void SetZeroMarginDisplayPortOnAsyncScrollableAncestors(
2879 * Finds the closest ancestor async scrollable frame from aFrame that has a
2880 * displayport and attempts to trigger the displayport expiry on that
2883 static void ExpireDisplayPortOnAsyncScrollableAncestor(nsIFrame
* aFrame
);
2885 static void SetBSizeFromFontMetrics(
2886 const nsIFrame
* aFrame
, mozilla::ReflowOutput
& aMetrics
,
2887 const mozilla::LogicalMargin
& aFramePadding
, mozilla::WritingMode aLineWM
,
2888 mozilla::WritingMode aFrameWM
);
2890 static bool HasDocumentLevelListenersForApzAwareEvents(PresShell
* aPresShell
);
2893 * Returns true if the given scroll origin is "higher priority" than APZ.
2894 * In general any content programmatic scrolls (e.g. scrollTo calls) are
2895 * higher priority, and take precedence over APZ scrolling. This function
2896 * returns true for those, and returns false for other origins like APZ
2897 * itself, or scroll position updates from the history restore code.
2899 static bool CanScrollOriginClobberApz(ScrollOrigin aScrollOrigin
);
2901 static ScrollMetadata
ComputeScrollMetadata(
2902 nsIFrame
* aForFrame
, nsIFrame
* aScrollFrame
, nsIContent
* aContent
,
2903 const nsIFrame
* aReferenceFrame
,
2904 mozilla::layers::LayerManager
* aLayerManager
, ViewID aScrollParentId
,
2905 const nsRect
& aViewport
, const mozilla::Maybe
<nsRect
>& aClipRect
,
2907 const mozilla::Maybe
<ContainerLayerParameters
>& aContainerParameters
);
2910 * Returns the metadata to put onto the root layer of a layer tree, if one is
2911 * needed. The last argument is a callback function to check if the caller
2912 * already has a metadata for a given scroll id.
2914 static mozilla::Maybe
<ScrollMetadata
> GetRootMetadata(
2915 nsDisplayListBuilder
* aBuilder
,
2916 mozilla::layers::LayerManager
* aLayerManager
,
2917 const ContainerLayerParameters
& aContainerParameters
,
2918 const std::function
<bool(ViewID
& aScrollId
)>& aCallback
);
2921 * If the given scroll frame needs an area excluded from its composition
2922 * bounds due to scrollbars, return that area, otherwise return an empty
2924 * There is no need to exclude scrollbars in the following cases:
2925 * - If the scroll frame is not the RCD-RSF; in that case, the composition
2926 * bounds is calculated based on the scroll port which already excludes
2927 * the scrollbar area.
2928 * - If the scrollbars are overlay, since then they are drawn on top of the
2929 * scrollable content.
2931 static nsMargin
ScrollbarAreaToExcludeFromCompositionBoundsFor(
2932 nsIFrame
* aScrollFrame
);
2935 * Looks in the layer subtree rooted at aLayer for a metrics with scroll id
2936 * aScrollId. Returns true if such is found.
2938 static bool ContainsMetricsWithId(const Layer
* aLayer
,
2939 const ViewID
& aScrollId
);
2941 static bool ShouldUseNoScriptSheet(mozilla::dom::Document
*);
2942 static bool ShouldUseNoFramesSheet(mozilla::dom::Document
*);
2945 * Get the text content inside the frame. This methods traverse the
2946 * frame tree and collect the content from text frames. Note that this
2947 * method is similiar to nsContentUtils::GetNodeTextContent, but it at
2948 * least differs from that method in the following things:
2949 * 1. it skips text content inside nodes like style, script, textarea
2950 * which don't generate an in-tree text frame for the text;
2951 * 2. it skips elements with display property set to none;
2952 * 3. it skips out-of-flow elements;
2953 * 4. it includes content inside pseudo elements;
2954 * 5. it may include part of text content of a node if a text frame
2955 * inside is split to different continuations.
2957 static void GetFrameTextContent(nsIFrame
* aFrame
, nsAString
& aResult
);
2960 * Same as GetFrameTextContent but appends the result rather than sets it.
2962 static void AppendFrameTextContent(nsIFrame
* aFrame
, nsAString
& aResult
);
2965 * Takes a selection, and returns selection's bounding rect which is relative
2966 * to its root frame.
2968 * @param aSel Selection to check
2970 static nsRect
GetSelectionBoundingRect(mozilla::dom::Selection
* aSel
);
2973 * Calculate the bounding rect of |aContent|, relative to the origin
2974 * of the scrolled content of |aRootScrollFrame|.
2975 * Where the element is contained inside a scrollable subframe, the
2976 * bounding rect is clipped to the bounds of the subframe.
2978 static CSSRect
GetBoundingContentRect(
2979 const nsIContent
* aContent
, const nsIScrollableFrame
* aRootScrollFrame
);
2982 * Returns the first ancestor who is a float containing block.
2984 static nsBlockFrame
* GetFloatContainingBlock(nsIFrame
* aFrame
);
2987 * Walks up the frame tree from |aForFrame| up to |aTopFrame|, or to the
2988 * root of the frame tree if |aTopFrame| is nullptr, and returns true if
2989 * a transformed frame is encountered.
2991 static bool IsTransformed(nsIFrame
* aForFrame
, nsIFrame
* aTopFrame
= nullptr);
2994 * Walk up from aFrame to the cross-doc root, accumulating all the APZ
2995 * callback transforms on the content elements encountered along the way.
2996 * Return the accumulated value.
2997 * XXX: Note that this does not take into account CSS transforms, nor
2998 * differences in structure between the frame tree and the layer tree (which
2999 * is probably what we *want* to be computing).
3001 static CSSPoint
GetCumulativeApzCallbackTransform(nsIFrame
* aFrame
);
3004 * Compute a rect to pre-render in cases where we want to render more of
3005 * something than what is visible (usually to support async transformation).
3006 * @param aFrame the target frame to be pre-rendered
3007 * @param aDirtyRect the area that's visible in the coordinate system of
3009 * @param aOverflow the total size of the thing we're rendering in the
3010 * coordinate system of |aFrame|.
3011 * @param aPrerenderSize how large of an area we're willing to render in the
3012 * coordinate system of the root frame.
3013 * @return A rectangle that includes |aDirtyRect|, is clamped to |aOverflow|,
3014 * and is no larger than |aPrerenderSize| (unless |aPrerenderSize| is
3015 * smaller than |aDirtyRect|, in which case the returned rect will
3016 * still include |aDirtyRect| and thus be larger than
3017 * |aPrerenderSize|).
3019 static nsRect
ComputePartialPrerenderArea(nsIFrame
* aFrame
,
3020 const nsRect
& aDirtyRect
,
3021 const nsRect
& aOverflow
,
3022 const nsSize
& aPrerenderSize
);
3025 * Checks whether a node is an invisible break.
3026 * If not, returns the first frame on the next line if such a next line
3030 * true if the node is an invisible break. aNextLineFrame is returned null
3033 * false if the node causes a visible break or if the node is no break.
3035 * @param aNextLineFrame
3036 * assigned to first frame on the next line if such a next line exists, null
3039 static bool IsInvisibleBreak(nsINode
* aNode
,
3040 nsIFrame
** aNextLineFrame
= nullptr);
3042 static nsRect
ComputeGeometryBox(nsIFrame
*, StyleGeometryBox
);
3044 static nsRect
ComputeGeometryBox(nsIFrame
*,
3045 const mozilla::StyleShapeGeometryBox
&);
3047 static nsRect
ComputeGeometryBox(nsIFrame
*, const mozilla::StyleShapeBox
&);
3049 static nsPoint
ComputeOffsetToUserSpace(nsDisplayListBuilder
* aBuilder
,
3052 // Return the default value to be used for -moz-control-character-visibility,
3053 // from preferences.
3054 static mozilla::StyleControlCharacterVisibility
3055 ControlCharVisibilityDefault();
3057 // Callers are responsible to ensure the user-font-set is up-to-date if
3058 // aUseUserFontSet is true.
3059 static already_AddRefed
<nsFontMetrics
> GetMetricsFor(
3060 nsPresContext
* aPresContext
, bool aIsVertical
,
3061 const nsStyleFont
* aStyleFont
, mozilla::Length aFontSize
,
3062 bool aUseUserFontSet
);
3064 static void ComputeSystemFont(nsFont
* aSystemFont
,
3065 mozilla::LookAndFeel::FontID aFontID
,
3066 const nsFont
* aDefaultVariableFont
);
3068 static uint32_t ParseFontLanguageOverride(const nsAString
& aLangTag
);
3071 * Returns true if there are any preferences or overrides that indicate a
3072 * need to handle <meta name="viewport"> tags.
3074 static bool ShouldHandleMetaViewport(const mozilla::dom::Document
*);
3077 * Resolve a CSS <length-percentage> value to a definite size.
3079 template <bool clampNegativeResultToZero
>
3080 static nscoord
ResolveToLength(const LengthPercentage
& aLengthPercentage
,
3081 nscoord aPercentageBasis
) {
3082 nscoord value
= (aPercentageBasis
== NS_UNCONSTRAINEDSIZE
)
3083 ? aLengthPercentage
.Resolve(0)
3084 : aLengthPercentage
.Resolve(aPercentageBasis
);
3085 return clampNegativeResultToZero
? std::max(0, value
) : value
;
3089 * Resolve a column-gap/row-gap to a definite size.
3090 * @note This method resolves 'normal' to zero.
3091 * Callers who want different behavior should handle 'normal' on their own.
3093 static nscoord
ResolveGapToLength(
3094 const mozilla::NonNegativeLengthPercentageOrNormal
& aGap
,
3095 nscoord aPercentageBasis
) {
3096 if (aGap
.IsNormal()) {
3099 return ResolveToLength
<true>(aGap
.AsLengthPercentage(), aPercentageBasis
);
3103 * Get the computed style from which the scrollbar style should be
3104 * used for the given scrollbar part frame.
3106 static ComputedStyle
* StyleForScrollbar(nsIFrame
* aScrollbarPart
);
3109 * Returns true if |aFrame| is scrolled out of view by a scrollable element in
3110 * a cross-process ancestor document.
3111 * Note this function only works for frames in out-of-process iframes.
3113 static bool FrameIsScrolledOutOfViewInCrossProcess(const nsIFrame
* aFrame
);
3116 * Similar to above FrameIsScrolledOutViewInCrossProcess but returns true even
3117 * if |aFrame| is not fully scrolled out of view and its visible area width or
3118 * height is smaller than |aMargin|.
3120 static bool FrameIsMostlyScrolledOutOfViewInCrossProcess(
3121 const nsIFrame
* aFrame
, nscoord aMargin
);
3124 * Expand the height of |aSize| to the size of `vh` units.
3126 * With dynamic toolbar(s) the height for `vh` units is greater than the
3127 * ICB height, we need to expand it in some places.
3129 static nsSize
ExpandHeightForViewportUnits(nsPresContext
* aPresContext
,
3130 const nsSize
& aSize
);
3132 static CSSSize
ExpandHeightForDynamicToolbar(nsPresContext
* aPresContext
,
3133 const CSSSize
& aSize
);
3134 static nsSize
ExpandHeightForDynamicToolbar(nsPresContext
* aPresContext
,
3135 const nsSize
& aSize
);
3139 * Helper function for LogTestDataForPaint().
3141 static void DoLogTestDataForPaint(mozilla::layers::LayerManager
* aManager
,
3142 ViewID aScrollId
, const std::string
& aKey
,
3143 const std::string
& aValue
);
3145 static bool IsAPZTestLoggingEnabled();
3147 static void ConstrainToCoordValues(gfxFloat
& aStart
, gfxFloat
& aSize
);
3148 static void ConstrainToCoordValues(float& aStart
, float& aSize
);
3151 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsLayoutUtils::PaintFrameFlags
)
3153 template <typename PointType
, typename RectType
, typename CoordType
>
3154 /* static */ bool nsLayoutUtils::PointIsCloserToRect(
3155 PointType aPoint
, const RectType
& aRect
, CoordType
& aClosestXDistance
,
3156 CoordType
& aClosestYDistance
) {
3157 CoordType fromLeft
= aPoint
.x
- aRect
.x
;
3158 CoordType fromRight
= aPoint
.x
- aRect
.XMost();
3160 CoordType xDistance
;
3161 if (fromLeft
>= 0 && fromRight
<= 0) {
3164 xDistance
= std::min(abs(fromLeft
), abs(fromRight
));
3167 if (xDistance
<= aClosestXDistance
) {
3168 if (xDistance
< aClosestXDistance
) {
3169 aClosestYDistance
= std::numeric_limits
<CoordType
>::max();
3172 CoordType fromTop
= aPoint
.y
- aRect
.y
;
3173 CoordType fromBottom
= aPoint
.y
- aRect
.YMost();
3175 CoordType yDistance
;
3176 if (fromTop
>= 0 && fromBottom
<= 0) {
3179 yDistance
= std::min(abs(fromTop
), abs(fromBottom
));
3182 if (yDistance
< aClosestYDistance
) {
3183 aClosestXDistance
= xDistance
;
3184 aClosestYDistance
= yDistance
;
3192 template <typename T
>
3193 nsRect
nsLayoutUtils::RoundGfxRectToAppRect(const T
& aRect
,
3194 const float aFactor
) {
3195 // Get a new Rect whose units are app units by scaling by the specified
3197 T scaledRect
= aRect
;
3198 scaledRect
.ScaleRoundOut(aFactor
);
3200 // We now need to constrain our results to the max and min values for coords.
3201 ConstrainToCoordValues(scaledRect
.x
, scaledRect
.width
);
3202 ConstrainToCoordValues(scaledRect
.y
, scaledRect
.height
);
3204 if (!aRect
.Width()) {
3205 scaledRect
.SetWidth(0);
3208 if (!aRect
.Height()) {
3209 scaledRect
.SetHeight(0);
3212 // Now typecast everything back. This is guaranteed to be safe.
3213 return nsRect(nscoord(scaledRect
.X()), nscoord(scaledRect
.Y()),
3214 nscoord(scaledRect
.Width()), nscoord(scaledRect
.Height()));
3220 * Converts an nsPoint in app units to a Moz2D Point in pixels (whether those
3221 * are device pixels or CSS px depends on what the caller chooses to pass as
3222 * aAppUnitsPerPixel).
3224 inline gfx::Point
NSPointToPoint(const nsPoint
& aPoint
,
3225 int32_t aAppUnitsPerPixel
) {
3226 return gfx::Point(gfx::Float(aPoint
.x
) / aAppUnitsPerPixel
,
3227 gfx::Float(aPoint
.y
) / aAppUnitsPerPixel
);
3231 * Converts an nsRect in app units to a Moz2D Rect in pixels (whether those
3232 * are device pixels or CSS px depends on what the caller chooses to pass as
3233 * aAppUnitsPerPixel).
3235 gfx::Rect
NSRectToRect(const nsRect
& aRect
, double aAppUnitsPerPixel
);
3238 * Converts an nsRect in app units to a Moz2D Rect in pixels (whether those
3239 * are device pixels or CSS px depends on what the caller chooses to pass as
3240 * aAppUnitsPerPixel).
3242 * The passed DrawTarget is used to additionally snap the returned Rect to
3243 * device pixels, if appropriate (as decided and carried out by Moz2D's
3244 * MaybeSnapToDevicePixels helper, which this function calls to do any
3247 gfx::Rect
NSRectToSnappedRect(const nsRect
& aRect
, double aAppUnitsPerPixel
,
3248 const gfx::DrawTarget
& aSnapDT
);
3251 * Converts, where possible, an nsRect in app units to a Moz2D Rect in pixels
3252 * (whether those are device pixels or CSS px depends on what the caller
3253 * chooses to pass as aAppUnitsPerPixel).
3255 * If snapping results in a rectangle with zero width or height, the affected
3256 * coordinates are left unsnapped
3258 gfx::Rect
NSRectToNonEmptySnappedRect(const nsRect
& aRect
,
3259 double aAppUnitsPerPixel
,
3260 const gfx::DrawTarget
& aSnapDT
);
3262 void StrokeLineWithSnapping(
3263 const nsPoint
& aP1
, const nsPoint
& aP2
, int32_t aAppUnitsPerDevPixel
,
3264 gfx::DrawTarget
& aDrawTarget
, const gfx::Pattern
& aPattern
,
3265 const gfx::StrokeOptions
& aStrokeOptions
= gfx::StrokeOptions(),
3266 const gfx::DrawOptions
& aDrawOptions
= gfx::DrawOptions());
3271 * An RAII class which will, for the duration of its lifetime,
3272 * **if** the frame given is a container for font size inflation,
3273 * set the current inflation container on the pres context to null
3274 * (and then, in its destructor, restore the old value).
3276 class AutoMaybeDisableFontInflation
{
3278 explicit AutoMaybeDisableFontInflation(nsIFrame
* aFrame
);
3280 ~AutoMaybeDisableFontInflation();
3283 nsPresContext
* mPresContext
;
3287 void MaybeSetupTransactionIdAllocator(layers::LayerManager
* aManager
,
3288 nsPresContext
* aPresContext
);
3290 } // namespace layout
3291 } // namespace mozilla
3293 class nsSetAttrRunnable
: public mozilla::Runnable
{
3295 nsSetAttrRunnable(mozilla::dom::Element
* aElement
, nsAtom
* aAttrName
,
3296 const nsAString
& aValue
);
3297 nsSetAttrRunnable(mozilla::dom::Element
* aElement
, nsAtom
* aAttrName
,
3302 RefPtr
<mozilla::dom::Element
> mElement
;
3303 RefPtr
<nsAtom
> mAttrName
;
3304 nsAutoString mValue
;
3307 class nsUnsetAttrRunnable
: public mozilla::Runnable
{
3309 nsUnsetAttrRunnable(mozilla::dom::Element
* aElement
, nsAtom
* aAttrName
);
3313 RefPtr
<mozilla::dom::Element
> mElement
;
3314 RefPtr
<nsAtom
> mAttrName
;
3317 // This class allows you to easily set any pointer variable and ensure it's
3318 // set to nullptr when leaving its scope.
3319 template <typename T
>
3320 class MOZ_RAII SetAndNullOnExit
{
3322 SetAndNullOnExit(T
*& aVariable
, T
* aValue
) {
3324 mVariable
= &aVariable
;
3326 ~SetAndNullOnExit() { *mVariable
= nullptr; }
3332 #endif // nsLayoutUtils_h__