Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/layout/base/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 140 kB image not shown  

Quelle  nsLayoutUtils.h   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#ifndef nsLayoutUtils_h__
#define nsLayoutUtils_h__

#include <limits>
#include <algorithm>

#include "gfxPoint.h"
#include "LayoutConstants.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/ScrollableLayerGuid.h"
#include "mozilla/LayoutStructs.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/Maybe.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/RelativeTo.h"
#include "mozilla/Span.h"
#include "mozilla/StaticPrefs_nglayout.h"
#include "mozilla/SurfaceFromElementResult.h"
#include "mozilla/SVGImageContext.h"
#include "mozilla/ToString.h"
#include "mozilla/TypedEnumBits.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/WritingModes.h"
#include "nsBoundingMetrics.h"
#include "nsCSSPropertyIDSet.h"
#include "nsFrameList.h"
#include "nsPoint.h"
#include "nsThreadUtils.h"
#include "Units.h"
// If you're thinking of adding a new include here, please try hard to not.
// This header file gets included just about everywhere and adding headers here
// can dramatically increase avoidable build activity. Try instead:
// - using a forward declaration
// - putting the include in the .cpp file, if it is only needed by the body
// - putting your new functions in some other less-widely-used header

class gfxContext;
class gfxFontEntry;
class imgIContainer;
class nsFrameList;
class nsPresContext;
class nsIContent;
class nsIPrincipal;
class nsIWidget;
class nsAtom;
class nsRegion;
enum nsChangeHint : uint32_t;
class nsFontMetrics;
class nsFontFaceList;
class nsIImageLoadingContent;
class nsBlockFrame;
class nsContainerFrame;
class nsView;
class nsIFrame;
class nsPIDOMWindowOuter;
class imgIRequest;
struct nsStyleFont;

namespace mozilla {
class nsDisplayItem;
class nsDisplayList;
class nsDisplayListBuilder;
enum class nsDisplayListBuilderMode : uint8_t;
class RetainedDisplayListBuilder;
struct AspectRatio;
class ComputedStyle;
class DisplayPortUtils;
class PresShell;
enum class PseudoStyleType : uint8_t;
class EventListenerManager;
enum class LayoutFrameType : uint8_t;
struct IntrinsicSize;
class ReflowOutput;
class WritingMode;
class DisplayItemClip;
class EffectSet;
struct ActiveScrolledRoot;
class ScrollContainerFrame;
enum class ScrollOrigin : uint8_t;
enum class StyleImageOrientation : uint8_t;
enum class StyleSystemFont : uint8_t;
enum class StyleScrollbarWidth : uint8_t;
struct OverflowAreas;
namespace dom {
class CanvasRenderingContext2D;
class DOMRectList;
class Document;
class Element;
class Event;
class HTMLImageElement;
class HTMLCanvasElement;
class HTMLVideoElement;
class ImageBitmap;
class InspectorFontFace;
class OffscreenCanvas;
class Selection;
class VideoFrame;
}  // namespace dom
namespace gfx {
struct RectCornerRadii;
enum class ShapedTextFlags : uint16_t;
}  // namespace gfx
namespace image {
class ImageIntRegion;
struct Resolution;
}  // namespace image
namespace layers {
struct FrameMetrics;
struct ScrollMetadata;
class Image;
class StackingContextHelper;
class Layer;
class WebRenderLayerManager;
}  // namespace layers
namespace widget {
enum class TransparencyMode : uint8_t;
}
}  // namespace mozilla

// Flags to customize the behavior of nsLayoutUtils::DrawString.
enum class DrawStringFlags {
  Default = 0x0,
  ForceHorizontal = 0x1  // Forces the text to be drawn horizontally.
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DrawStringFlags)

namespace mozilla {

class RectCallback {
 public:
  virtual void AddRect(const nsRect& aRect) = 0;
};

}  // namespace mozilla

/**
 * nsLayoutUtils is a namespace class used for various helper
 * functions that are useful in multiple places in layout.  The goal
 * is not to define multiple copies of the same static helper.
 */

class nsLayoutUtils {
  typedef mozilla::AspectRatio AspectRatio;
  typedef mozilla::ComputedStyle ComputedStyle;
  typedef mozilla::LengthPercentage LengthPercentage;
  typedef mozilla::LengthPercentageOrAuto LengthPercentageOrAuto;
  typedef mozilla::dom::DOMRectList DOMRectList;
  typedef mozilla::layers::StackingContextHelper StackingContextHelper;
  typedef mozilla::IntrinsicSize IntrinsicSize;
  typedef mozilla::RelativeTo RelativeTo;
  typedef mozilla::ScrollOrigin ScrollOrigin;
  typedef mozilla::ViewportType ViewportType;
  typedef mozilla::gfx::SourceSurface SourceSurface;
  typedef mozilla::gfx::sRGBColor sRGBColor;
  typedef mozilla::gfx::DrawTarget DrawTarget;
  typedef mozilla::gfx::ExtendMode ExtendMode;
  typedef mozilla::gfx::SamplingFilter SamplingFilter;
  typedef mozilla::gfx::Float Float;
  typedef mozilla::gfx::Point Point;
  typedef mozilla::gfx::Rect Rect;
  typedef mozilla::gfx::RectDouble RectDouble;
  typedef mozilla::gfx::Size Size;
  typedef mozilla::gfx::Matrix4x4 Matrix4x4;
  typedef mozilla::gfx::Matrix4x4Flagged Matrix4x4Flagged;
  typedef mozilla::gfx::MatrixScales MatrixScales;
  typedef mozilla::gfx::MatrixScalesDouble MatrixScalesDouble;
  typedef mozilla::gfx::RectCornerRadii RectCornerRadii;
  typedef mozilla::gfx::StrokeOptions StrokeOptions;
  typedef mozilla::image::ImgDrawResult ImgDrawResult;

  using nsDisplayItem = mozilla::nsDisplayItem;
  using nsDisplayList = mozilla::nsDisplayList;
  using nsDisplayListBuilder = mozilla::nsDisplayListBuilder;
  using nsDisplayListBuilderMode = mozilla::nsDisplayListBuilderMode;
  using RetainedDisplayListBuilder = mozilla::RetainedDisplayListBuilder;

 public:
  typedef mozilla::layers::FrameMetrics FrameMetrics;
  typedef mozilla::layers::ScrollMetadata ScrollMetadata;
  typedef mozilla::layers::ScrollableLayerGuid::ViewID ViewID;
  typedef mozilla::CSSPoint CSSPoint;
  typedef mozilla::CSSSize CSSSize;
  typedef mozilla::CSSIntSize CSSIntSize;
  typedef mozilla::CSSRect CSSRect;
  typedef mozilla::ScreenMargin ScreenMargin;
  typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize;
  typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
  typedef mozilla::PresShell PresShell;
  typedef mozilla::StyleGeometryBox StyleGeometryBox;
  typedef mozilla::SVGImageContext SVGImageContext;
  typedef mozilla::LogicalSize LogicalSize;

  /**
   * Finds previously assigned ViewID for the given content element, if any.
   * Returns whether a ViewID was previously assigned.
   */

  static bool FindIDFor(const nsIContent* aContent, ViewID* aOutViewId);

  /**
   * Finds previously assigned or generates a unique ViewID for the given
   * content element.
   */

  static ViewID FindOrCreateIDFor(nsIContent* aContent);

  /**
   * Find content for given ID.
   */

  static nsIContent* FindContentFor(ViewID aId);

  /**
   * Find the scroll container frame for a given content element.
   */

  static mozilla::ScrollContainerFrame* FindScrollContainerFrameFor(
      nsIContent* aContent);

  /**
   * Find the scroll container frame for a given ID.
   */

  static mozilla::ScrollContainerFrame* FindScrollContainerFrameFor(ViewID aId);

  /**
   * Helper for FindScrollContainerFrameFor(), also used in DisplayPortUtils.
   * Most clients should use FindScrollContainerFrameFor().
   */

  static nsIFrame* GetScrollContainerFrameFromContent(nsIContent* aContent);

  /**
   * Find the ID for a given scroll container frame.
   */

  static ViewID FindIDForScrollContainerFrame(
      mozilla::ScrollContainerFrame* aScrollContainerFrame);

  /**
   * Notify the scroll frame with the given scroll id that its scroll offset
   * is being sent to APZ as part of a paint-skip transaction.
   *
   * Normally, this notification happens during painting, after calls to
   * ComputeScrollMetadata(). During paint-skipping that code is skipped,
   * but it's still important for the scroll frame to be notified for
   * correctness of relative scroll updates, so the code that sends the
   * empty paint-skip transaction needs to call this.
   */

  static void NotifyPaintSkipTransaction(ViewID aScrollId);

  /**
   * Use heuristics to figure out the child list that
   * aChildFrame is currently in.
   */

  static mozilla::FrameChildListID GetChildListNameFor(nsIFrame* aChildFrame);

  /**
   * Returns the ::before pseudo-element for aContent, if any.
   */

  static mozilla::dom::Element* GetBeforePseudo(const nsIContent* aContent);

  /**
   * Returns the frame corresponding to the ::before pseudo-element for
   * aContent, if any.
   */

  static nsIFrame* GetBeforeFrame(const nsIContent* aContent);

  /**
   * Returns the ::after pseudo-element for aContent, if any.
   */

  static mozilla::dom::Element* GetAfterPseudo(const nsIContent* aContent);

  /**
   * Returns the frame corresponding to the ::after pseudo-element for aContent,
   * if any.
   */

  static nsIFrame* GetAfterFrame(const nsIContent* aContent);

  /**
   * Returns the ::marker pseudo-element for aContent, if any.
   */

  static mozilla::dom::Element* GetMarkerPseudo(const nsIContent* aContent);

  /**
   * Returns the frame corresponding to the ::marker pseudo-element for
   * aContent, if any.
   */

  static nsIFrame* GetMarkerFrame(const nsIContent* aContent);

#ifdef ACCESSIBILITY
  /**
   * Set aText to the spoken text for the given ::marker content (aContent)
   * if it has a frame, or the empty string otherwise.
   */

  static void GetMarkerSpokenText(const nsIContent* aContent, nsAString& aText);
#endif

  /**
   * Given a frame, search up the frame tree until we find an
   * ancestor that (or the frame itself) is of type aFrameType, if any.
   *
   * @param aFrame the frame to start at
   * @param aFrameType the frame type to look for
   * @param aStopAt a frame to stop at after we checked it
   * @return a frame of the given type or nullptr if no
   *         such ancestor exists
   */

  static nsIFrame* GetClosestFrameOfType(nsIFrame* aFrame,
                                         mozilla::LayoutFrameType aFrameType,
                                         nsIFrame* aStopAt = nullptr);

  /**
   * Given a frame, search up the frame tree until we find an
   * ancestor that (or the frame itself) is a "Page" frame, if any.
   *
   * @param aFrame the frame to start at
   * @return a frame of type mozilla::LayoutFrameType::Page or nullptr if no
   *         such ancestor exists
   */

  static nsIFrame* GetPageFrame(nsIFrame* aFrame);

  /**
   * Given a frame which is the primary frame for an element,
   * return the frame that has the non-pseudoelement ComputedStyle for
   * the content.
   * This is aPrimaryFrame itself except for tableWrapper frames.
   *
   * Given a non-null input, this will return null if and only if its
   * argument is a table wrapper frame that is mid-destruction (and its
   * table frame has been destroyed).
   */

  static nsIFrame* GetStyleFrame(nsIFrame* aPrimaryFrame);
  static const nsIFrame* GetStyleFrame(const nsIFrame* aPrimaryFrame);

  /**
   * Given a content node,
   * return the frame that has the non-pseudoelement ComputedStyle for
   * the content.  May return null.
   * This is aContent->GetPrimaryFrame() except for tableWrapper frames.
   */

  static nsIFrame* GetStyleFrame(const nsIContent* aContent);

  /**
   * Returns the placeholder size for when the scrollbar is unthemed.
   */

  static mozilla::CSSIntCoord UnthemedScrollbarSize(
      mozilla::StyleScrollbarWidth);

  /**
   * The inverse of GetStyleFrame. Returns |aStyleFrame| unless it is an inner
   * table frame, in which case the table wrapper frame is returned.
   */

  static nsIFrame* GetPrimaryFrameFromStyleFrame(nsIFrame* aStyleFrame);
  static const nsIFrame* GetPrimaryFrameFromStyleFrame(
      const nsIFrame* aStyleFrame);

  /**
   * Similar to nsIFrame::IsPrimaryFrame except that this will return true
   * for the inner table frame rather than for its wrapper frame.
   */

  static bool IsPrimaryStyleFrame(const nsIFrame* aFrame);

  /**
   * CompareTreePosition determines whether aFrame1 comes before or
   * after aFrame2 in a preorder traversal of the frame tree, where out
   * of flow frames are treated as children of their placeholders. This is
   * basically the same ordering as DoCompareTreePosition(nsIContent*) except
   * that it handles anonymous content properly and there are subtleties with
   * continuations.
   *
   * @param aCommonAncestor either null, or a common ancestor of
   *                        aContent1 and aContent2.  Actually this is
   *                        only a hint; if it's not an ancestor of
   *                        aContent1 or aContent2, this function will
   *                        still work, but it will be slower than
   *                        normal.
   * @return < 0 if aContent1 is before aContent2
   *         > 0 if aContent1 is after aContent2,
   *         0 otherwise (meaning they're the same, or they're in
   *           different frame trees)
   */

  static int32_t CompareTreePosition(nsIFrame* aFrame1, nsIFrame* aFrame2,
                                     nsIFrame* aCommonAncestor = nullptr) {
    return DoCompareTreePosition(aFrame1, aFrame2, aCommonAncestor);
  }

  static int32_t CompareTreePosition(nsIFrame* aFrame1, nsIFrame* aFrame2,
                                     nsTArray<nsIFrame*>& aFrame2Ancestors,
                                     nsIFrame* aCommonAncestor = nullptr) {
    return DoCompareTreePosition(aFrame1, aFrame2, aFrame2Ancestors,
                                 aCommonAncestor);
  }

  static nsIFrame* FillAncestors(nsIFrame* aFrame, nsIFrame* aStopAtAncestor,
                                 nsTArray<nsIFrame*>* aAncestors);

  static int32_t DoCompareTreePosition(nsIFrame* aFrame1, nsIFrame* aFrame2,
                                       nsIFrame* aCommonAncestor);
  static int32_t DoCompareTreePosition(nsIFrame* aFrame1, nsIFrame* aFrame2,
                                       nsTArray<nsIFrame*>& aFrame2Ancestors,
                                       nsIFrame* aCommonAncestor);

  /**
   * LastContinuationWithChild gets the last continuation in aFrame's chain
   * that has a child, or the first continuation if the frame has no children.
   */

  static nsContainerFrame* LastContinuationWithChild(nsContainerFrame* aFrame);

  /**
   * GetLastSibling simply finds the last sibling of aFrame, or returns nullptr
   * if aFrame is null.
   */

  static nsIFrame* GetLastSibling(nsIFrame* aFrame);

  /**
   * FindSiblingViewFor locates the child of aParentView that aFrame's
   * view should be inserted 'above' (i.e., before in sibling view
   * order).  This is the first child view of aParentView whose
   * corresponding content is before aFrame's content (view siblings
   * are in reverse content order).
   */

  static nsView* FindSiblingViewFor(nsView* aParentView, nsIFrame* aFrame);

  /**
   * Get the parent of aFrame. If aFrame is the root frame for a document,
   * and the document has a parent document in the same view hierarchy, then
   * we try to return the subdocumentframe in the parent document.
   * @param aCrossDocOffset [in/out] if non-null, then as we cross documents
   * an extra offset may be required and it will be added to aCrossDocOffset.
   * Be careful dealing with this extra offset as it is in app units of the
   * parent document, which may have a different app units per dev pixel ratio
   * than the child document.
   * Note that, while this function crosses document boundaries, it (naturally)
   * cannot cross process boundaries.
   */

  static nsIFrame* GetCrossDocParentFrameInProcess(
      const nsIFrame* aFrame, nsPoint* aCrossDocOffset = nullptr);

  /**
   * Does the same thing as GetCrossDocParentFrameInProcess().
   * The purpose of having two functions is to more easily track which call
   * sites have been audited to consider out-of-process iframes (bug 1599913).
   * Once all call sites have been audited, this function can be removed.
   */

  static nsIFrame* GetCrossDocParentFrame(const nsIFrame* aFrame,
                                          nsPoint* aCrossDocOffset = nullptr);

  /**
   * IsProperAncestorFrame checks whether aAncestorFrame is an ancestor
   * of aFrame and not equal to aFrame.
   * @param aCommonAncestor nullptr, or a common ancestor of aFrame and
   * aAncestorFrame. If non-null, this can bound the search and speed up
   * the function
   */

  static bool IsProperAncestorFrame(const nsIFrame* aAncestorFrame,
                                    const nsIFrame* aFrame,
                                    const nsIFrame* aCommonAncestor = nullptr);

  /**
   * Like IsProperAncestorFrame, but looks across document boundaries.
   *
   * Just like IsAncestorFrameCrossDoc, except that it returns false when
   * aFrame == aAncestorFrame.
   * TODO: Once after we fixed bug 1715932, this function should be removed.
   */

  static bool IsProperAncestorFrameCrossDoc(
      const nsIFrame* aAncestorFrame, const nsIFrame* aFrame,
      const nsIFrame* aCommonAncestor = nullptr);

  /**
   * Like IsProperAncestorFrame, but looks across document boundaries.
   *
   * Just like IsAncestorFrameCrossDoc, except that it returns false when
   * aFrame == aAncestorFrame.
   */

  static bool IsProperAncestorFrameCrossDocInProcess(
      const nsIFrame* aAncestorFrame, const nsIFrame* aFrame,
      const nsIFrame* aCommonAncestor = nullptr);

  /**
   * IsAncestorFrameCrossDoc checks whether aAncestorFrame is an ancestor
   * of aFrame or equal to aFrame, looking across document boundaries.
   * @param aCommonAncestor nullptr, or a common ancestor of aFrame and
   * aAncestorFrame. If non-null, this can bound the search and speed up
   * the function.
   *
   * Just like IsProperAncestorFrameCrossDoc, except that it returns true when
   * aFrame == aAncestorFrame.
   *
   * TODO: Bug 1700245, all call sites of this function will be eventually
   * replaced by IsAncestorFrameCrossDocInProcess.
   */

  static bool IsAncestorFrameCrossDoc(
      const nsIFrame* aAncestorFrame, const nsIFrame* aFrame,
      const nsIFrame* aCommonAncestor = nullptr);

  /**
   * IsAncestorFrameCrossDocInProcess checks whether aAncestorFrame is an
   * ancestor of aFrame or equal to aFrame, looking across document boundaries
   * in the same process.
   * @param aCommonAncestor nullptr, or a common ancestor of aFrame and
   * aAncestorFrame. If non-null, this can bound the search and speed up
   * the function.
   *
   * Just like IsProperAncestorFrameCrossDoc, except that it returns true when
   * aFrame == aAncestorFrame.
   *
   * NOTE: This function doesn't return true even if |aAncestorFrame| and
   * |aFrame| is in the same process but they are not directly connected, e.g.
   * both |aAncestorFrame| and |aFrame| in A domain documents, but there's
   * another an iframe document domain B, such as A1 -> B1 ->A2 document tree.
   */

  static bool IsAncestorFrameCrossDocInProcess(
      const nsIFrame* aAncestorFrame, const nsIFrame* aFrame,
      const nsIFrame* aCommonAncestor = nullptr);

  static mozilla::SideBits GetSideBitsForFixedPositionContent(
      const nsIFrame* aFixedPosFrame);

  /**
   * Get the scroll id for the root scrollframe of the presshell of the given
   * prescontext. Returns NULL_SCROLL_ID if it couldn't be found.
   */

  static ViewID ScrollIdForRootScrollFrame(nsPresContext* aPresContext);

  /**
   * GetScrollContainerFrameFor returns the scroll container frame for a
   * scrolled frame.
   */

  static mozilla::ScrollContainerFrame* GetScrollContainerFrameFor(
      const nsIFrame* aScrolledFrame);

  /**
   * GetNearestScrollableFrameForDirection locates the first ancestor of
   * aFrame (or aFrame itself) that is scrollable with overflow:scroll or
   * overflow:auto in the given direction and where either the scrollbar for
   * that direction is visible or the frame can be scrolled by some
   * positive amount in that direction.
   * The search extends across document boundaries.
   *
   * @param  aFrame the frame to start with
   * @param  aDirection Whether it's for horizontal or vertical scrolling.
   * @return the nearest scroll container frame or nullptr if not found
   */

  static mozilla::ScrollContainerFrame* GetNearestScrollableFrameForDirection(
      nsIFrame* aFrame, mozilla::layers::ScrollDirections aDirections);

  enum {
    /**
     * If the SCROLLABLE_SAME_DOC flag is set, then we only walk the frame tree
     * up to the root frame in the current document.
     */

    SCROLLABLE_SAME_DOC = 0x01,
    /**
     * If the SCROLLABLE_INCLUDE_HIDDEN flag is set then we allow
     * overflow:hidden scrollframes to be returned as scrollable frames.
     */

    SCROLLABLE_INCLUDE_HIDDEN = 0x02,
    /**
     * If the SCROLLABLE_ONLY_ASYNC_SCROLLABLE flag is set, then we only
     * want to match scrollable frames for which WantAsyncScroll() returns
     * true.
     */

    SCROLLABLE_ONLY_ASYNC_SCROLLABLE = 0x04,
    /**
     * If the SCROLLABLE_ALWAYS_MATCH_ROOT flag is set, then we will always
     * return the root scrollable frame for the root document (in the current
     * process) if we encounter it, whether or not it is async scrollable or
     * overflow: hidden.
     */

    SCROLLABLE_ALWAYS_MATCH_ROOT = 0x08,
    /**
     * If the SCROLLABLE_FIXEDPOS_FINDS_ROOT flag is set, then for fixed-pos
     * frames return the root scrollable frame for that document.
     */

    SCROLLABLE_FIXEDPOS_FINDS_ROOT = 0x10,
    /**
     * If the SCROLLABLE_STOP_AT_PAGE flag is set, then we stop searching
     * for scrollable ancestors when seeing a nsPageFrame.  This can be used
     * to avoid finding the viewport scroll frame in Print Preview (which
     * would be undesirable as a 'position:sticky' container for content).
     */

    SCROLLABLE_STOP_AT_PAGE = 0x20,
  };
  /**
   * GetNearestScrollContainerFrame locates the first ancestor of aFrame
   * (or aFrame itself) that is scrollable with overflow:scroll or
   * overflow:auto in some direction.
   *
   * @param  aFrame the frame to start with
   * @param  aFlags if SCROLLABLE_SAME_DOC is set, do not search across
   * document boundaries. If SCROLLABLE_INCLUDE_HIDDEN is set, include
   * frames scrollable with overflow:hidden.
   * @return the nearest scroll container frame or nullptr if not found
   */

  static mozilla::ScrollContainerFrame* GetNearestScrollContainerFrame(
      nsIFrame* aFrame, uint32_t aFlags = 0);

  /**
   * GetScrolledRect returns the range of allowable scroll offsets
   * for aScrolledFrame, assuming the scrollable overflow area is
   * aScrolledFrameOverflowArea and the scrollport size is aScrollPortSize.
   */

  static nsRect GetScrolledRect(nsIFrame* aScrolledFrame,
                                const nsRect& aScrolledFrameOverflowArea,
                                const nsSize& aScrollPortSize,
                                mozilla::StyleDirection);

  /**
   * HasPseudoStyle returns true if aContent (whose primary style
   * context is aComputedStyle) has the aPseudoElement pseudo-style
   * attached to it; returns false otherwise.
   *
   * @param aContent the content node we're looking at
   * @param aComputedStyle aContent's ComputedStyle
   * @param aPseudoElement the id of the pseudo style we care about
   * @param aPresContext the presentation context
   * @return whether aContent has aPseudoElement style attached to it
   */

  static bool HasPseudoStyle(nsIContent* aContent,
                             ComputedStyle* aComputedStyle,
                             mozilla::PseudoStyleType aPseudoElement,
                             nsPresContext* aPresContext);

  /**
   * If this frame is a placeholder for a float, then return the float,
   * otherwise return nullptr.  aPlaceholder must be a placeholder frame.
   */

  static nsIFrame* GetFloatFromPlaceholder(nsIFrame* aPlaceholder);

  // Combine aOrigClearType with aNewClearType, but limit the clear types
  // to UsedClear::Left, Right, Both.
  static mozilla::UsedClear CombineClearType(mozilla::UsedClear aOrigClearType,
                                             mozilla::UsedClear aNewClearType);

  /**
   * Get the coordinates of a given DOM mouse event, relative to a given
   * frame. Works only for DOM events generated by WidgetGUIEvents.
   * @param aDOMEvent the event
   * @param aFrame the frame to make coordinates relative to
   * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
   * for some reason the coordinates for the mouse are not known (e.g.,
   * the event is not a GUI event).
   */

  static nsPoint GetDOMEventCoordinatesRelativeTo(
      mozilla::dom::Event* aDOMEvent, nsIFrame* aFrame);

  /**
   * Get the coordinates of a given native mouse event, relative to a given
   * frame.
   * @param aEvent the event
   * @param aFrame the frame to make coordinates relative to
   * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
   * for some reason the coordinates for the mouse are not known (e.g.,
   * the event is not a GUI event).
   */

  static nsPoint GetEventCoordinatesRelativeTo(
      const mozilla::WidgetEvent* aEvent, RelativeTo aFrame);

  /**
   * Get the coordinates of a given point relative to an event and a
   * given frame.
   * @param aEvent the event
   * @param aPoint the point to get the coordinates relative to
   * @param aFrame the frame to make coordinates relative to
   * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
   * for some reason the coordinates for the mouse are not known (e.g.,
   * the event is not a GUI event).
   */

  static nsPoint GetEventCoordinatesRelativeTo(
      const mozilla::WidgetEvent* aEvent,
      const mozilla::LayoutDeviceIntPoint& aPoint, RelativeTo aFrame);

  /**
   * Get the coordinates of a given point relative to a widget and a
   * given frame.
   * @param aWidget the event src widget
   * @param aPoint the point to get the coordinates relative to
   * @param aFrame the frame to make coordinates relative to
   * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
   * for some reason the coordinates for the mouse are not known (e.g.,
   * the event is not a GUI event).
   */

  static nsPoint GetEventCoordinatesRelativeTo(
      nsIWidget* aWidget, const mozilla::LayoutDeviceIntPoint& aPoint,
      RelativeTo aFrame);

  /**
   * Get the popup frame of a given native mouse event.
   * @param aRootPresContext only check popups within aRootPresContext or a
   * descendant
   * @param aEvent  the event.
   * @return        Null, if there is no popup frame at the point, otherwise,
   *                returns top-most popup frame at the point.
   */

  static nsIFrame* GetPopupFrameForEventCoordinates(
      nsPresContext* aRootPresContext, const mozilla::WidgetEvent* aEvent);

  /**
   * Get the popup frame of a given point relative to a widget.
   * @param aRootPresContext only check popups within aRootPresContext or a
   * descendant
   * @param aEvent  the event.
   * @return        Null, if there is no popup frame at the point, otherwise,
   *                returns top-most popup frame at the point.
   */

  enum class GetPopupFrameForPointFlags : uint8_t {
    OnlyReturnFramesWithWidgets = 0x1,
  };
  static nsIFrame* GetPopupFrameForPoint(
      nsPresContext* aRootPresContext, nsIWidget* aWidget,
      const mozilla::LayoutDeviceIntPoint& aPoint,
      GetPopupFrameForPointFlags aFlags = GetPopupFrameForPointFlags(0));

  /**
   * Get container and offset if aEvent collapses Selection.
   * @param aPresShell      The PresShell handling aEvent.
   * @param aEvent          The event having coordinates where you want to
   *                        collapse Selection.
   * @param aContainer      Returns the container node at the point.
   *                        Set nullptr if you don't need this.
   * @param aOffset         Returns offset in the container node at the point.
   *                        Set nullptr if you don't need this.
   */

  MOZ_CAN_RUN_SCRIPT
  static void GetContainerAndOffsetAtEvent(PresShell* aPresShell,
                                           const mozilla::WidgetEvent* aEvent,
                                           nsIContent** aContainer,
                                           int32_t* aOffset);

  /**
   * Translate from widget coordinates to the view's coordinates
   * @param aPresContext the PresContext for the view
   * @param aWidget the widget
   * @param aPt the point relative to the widget
   * @param aView  view to which returned coordinates are relative
   * @return the point in the view's coordinates
   */

  static nsPoint TranslateWidgetToView(nsPresContext* aPresContext,
                                       nsIWidget* aWidget,
                                       const mozilla::LayoutDeviceIntPoint& aPt,
                                       nsView* aView);

  /**
   * Translate from view coordinates to the widget's coordinates.
   * @param aPresContext the PresContext for the view
   * @param aView the view
   * @param aPt the point relative to the view
   * @param aViewportType whether the point is in visual or layout coordinates
   * @param aWidget the widget to which returned coordinates are relative
   * @return the point in the view's coordinates
   */

  static mozilla::LayoutDeviceIntPoint TranslateViewToWidget(
      nsPresContext* aPresContext, nsView* aView, nsPoint aPt,
      ViewportType aViewportType, nsIWidget* aWidget);

  static mozilla::LayoutDeviceIntPoint WidgetToWidgetOffset(
      nsIWidget* aFromWidget, nsIWidget* aToWidget);

  enum class FrameForPointOption {
    /**
     * When set, paint suppression is ignored, so we'll return non-root page
     * elements even if paint suppression is stopping them from painting.
     */

    IgnorePaintSuppression = 1,
    /**
     * When set, clipping due to the root scroll frame (and any other viewport-
     * related clipping) is ignored.
     */

    IgnoreRootScrollFrame,
    /**
     * When set, return only content in the same document as aFrame.
     */

    IgnoreCrossDoc,
    /**
     * When set, return only content that is actually visible.
     */

    OnlyVisible,
  };

  struct FrameForPointOptions {
    using Bits = mozilla::EnumSet<FrameForPointOption>;

    Bits mBits;
    // If mBits contains OnlyVisible, what is the opacity threshold which we
    // consider "opaque enough" to clobber stuff underneath.
    float mVisibleThreshold;

    FrameForPointOptions(Bits aBits, float aVisibleThreshold)
        : mBits(aBits), mVisibleThreshold(aVisibleThreshold) {};

    MOZ_IMPLICIT FrameForPointOptions(Bits aBits)
        : FrameForPointOptions(aBits, 1.0f) {}

    FrameForPointOptions() : FrameForPointOptions(Bits()) {};
  };

  /**
   * Given aFrame, the root frame of a stacking context, find its descendant
   * frame under the point aPt that receives a mouse event at that location,
   * or nullptr if there is no such frame.
   * @param aPt the point, relative to the frame origin, in either visual
   *            or layout coordinates depending on aRelativeTo.mViewportType
   */

  static nsIFrame* GetFrameForPoint(RelativeTo aRelativeTo, nsPoint aPt,
                                    const FrameForPointOptions& = {});

  /**
   * Given aFrame, the root frame of a stacking context, find all descendant
   * frames under the area of a rectangle that receives a mouse event,
   * or nullptr if there is no such frame.
   * @param aRect the rect, relative to the frame origin, in either visual
   *              or layout coordinates depending on aRelativeTo.mViewportType
   * @param aOutFrames an array to add all the frames found
   */

  static nsresult GetFramesForArea(RelativeTo aRelativeTo, const nsRect& aRect,
                                   nsTArray<nsIFrame*>& aOutFrames,
                                   const FrameForPointOptions& = {});

  /**
   * Transform aRect relative to aFrame up to the coordinate system of
   * aAncestor. Computes the bounding-box of the true quadrilateral.
   * Pass non-null aPreservesAxisAlignedRectangles and it will be set to true if
   * we only need to use a 2d transform that PreservesAxisAlignedRectangles().
   * The corner positions of aRect are treated as meaningful even if aRect is
   * empty.
   *
   * |aMatrixCache| allows for optimizations in recomputing the same matrix over
   * and over. The argument can be one of the following values:
   *
   * nullptr (the default) - No optimization; the transform matrix is computed
   * on every call to this function.
   *
   * non-null pointer to an empty Maybe<Matrix4x4> - Upon return, the Maybe is
   * filled with the transform matrix that was computed. This can then be passed
   * in to subsequent calls with the same source and destination frames to avoid
   * recomputing the matrix.
   *
   * non-null pointer to a non-empty Matrix4x4 - The provided matrix will be
   * used as the transform matrix and applied to the rect.
   */

  static nsRect TransformFrameRectToAncestor(
      const nsIFrame* aFrame, const nsRect& aRect, const nsIFrame* aAncestor,
      bool* aPreservesAxisAlignedRectangles = nullptr,
      mozilla::Maybe<Matrix4x4Flagged>* aMatrixCache = nullptr,
      bool aStopAtStackingContextAndDisplayPortAndOOFFrame = false,
      nsIFrame** aOutAncestor = nullptr) {
    return TransformFrameRectToAncestor(
        aFrame, aRect, RelativeTo{aAncestor}, aPreservesAxisAlignedRectangles,
        aMatrixCache, aStopAtStackingContextAndDisplayPortAndOOFFrame,
        aOutAncestor);
  }
  static nsRect TransformFrameRectToAncestor(
      const nsIFrame* aFrame, const nsRect& aRect, RelativeTo aAncestor,
      bool* aPreservesAxisAlignedRectangles = nullptr,
      mozilla::Maybe<Matrix4x4Flagged>* aMatrixCache = nullptr,
      bool aStopAtStackingContextAndDisplayPortAndOOFFrame = false,
      nsIFrame** aOutAncestor = nullptr);

  /**
   * Gets the transform for aFrame relative to aAncestor. Pass null for
   * aAncestor to go up to the root frame. Including nsIFrame::IN_CSS_UNITS
   * flag in aFlags will return CSS pixels, by default it returns device
   * pixels.
   * More info can be found in nsIFrame::GetTransformMatrix.
   *
   * Some notes on the possible combinations of |aFrame.mViewportType| and
   * |aAncestor.mViewportType|:
   *
   * | aFrame.       | aAncestor.    | Notes
   * | mViewportType | mViewportType |
   * ==========================================================================
   * | Layout        | Layout        | Commonplace, when both source and target
   * |               |               | are inside zoom boundary.
   * |               |               |
   * |               |               | Could also happen in non-e10s setups
   * |               |               | when both source and target are outside
   * |               |               | the zoom boundary and the code is
   * |               |               | oblivious to the existence of a zoom
   * |               |               | boundary.
   * ==========================================================================
   * | Layout        | Visual        | Commonplace, used when hit testing visual
   * |               |               | coordinates (e.g. coming from user input
   * |               |               | events). We expected to encounter a
   * |               |               | zoomed content root during traversal and
   * |               |               | apply a layout-to-visual transform.
   * ==========================================================================
   * | Visual        | Layout        | Should never happen, will assert.
   * ==========================================================================
   * | Visual        | Visual        | In e10s setups, should only happen if
   * |               |               | aFrame and aAncestor are both the
   * |               |               | RCD viewport frame.
   * |               |               |
   * |               |               | In non-e10s setups, could happen with
   * |               |               | different frames if they are both
   * |               |               | outside the zoom boundary.
   * ==========================================================================
   */

  static Matrix4x4Flagged GetTransformToAncestor(
      RelativeTo aFrame, RelativeTo aAncestor, uint32_t aFlags = 0,
      nsIFrame** aOutAncestor = nullptr);

  /**
   * Gets the scale factors of the transform for aFrame relative to the root
   * frame if this transform can be drawn 2D, or the identity scale factors
   * otherwise.
   */

  static MatrixScales GetTransformToAncestorScale(const nsIFrame* aFrame);

  /**
   * Gets the scale factors of the transform for aFrame relative to the root
   * frame if this transform is 2D, or the identity scale factors otherwise.
   * If some frame on the path from aFrame to the display root frame may have an
   * animated scale, returns the identity scale factors.
   */

  static MatrixScales GetTransformToAncestorScaleExcludingAnimated(
      nsIFrame* aFrame);

  /**
   * Gets a scale that includes CSS transforms in this process as well as the
   * transform to ancestor scale passed down from our direct ancestor process
   * (which includes any enclosing CSS transforms and resolution). Note: this
   * does not include any resolution in the current process (this is on purpose
   * because that is what the transform to ancestor field on FrameMetrics needs,
   * see its definition for explanation as to why). This is the transform to
   * ancestor scale to set on FrameMetrics.
   */

  static mozilla::ParentLayerToScreenScale2D
  GetTransformToAncestorScaleCrossProcessForFrameMetrics(
      const nsIFrame* aFrame);

  /**
   * Find the nearest common ancestor frame for aFrame1 and aFrame2. The
   * ancestor frame could be cross-doc.
   */

  static const nsIFrame* FindNearestCommonAncestorFrame(
      const nsIFrame* aFrame1, const nsIFrame* aFrame2);

  /**
   * Find the nearest common ancestor frame for aFrame1 and aFrame2, assuming
   * that they are within the same block.
   *
   * Returns null if they are not within the same block.
   */

  static const nsIFrame* FindNearestCommonAncestorFrameWithinBlock(
      const nsTextFrame* aFrame1, const nsTextFrame* aFrame2);

  /**
   * Whether author-specified borders / backgrounds disable theming for a given
   * appearance value.
   */

  static bool AuthorSpecifiedBorderBackgroundDisablesTheming(
      mozilla::StyleAppearance);

  /**
   * Transforms a list of CSSPoints from aFromFrame to aToFrame, taking into
   * account all relevant transformations on the frames up to (but excluding)
   * their nearest common ancestor.
   * If we encounter a transform that we need to invert but which is
   * non-invertible, we return NONINVERTIBLE_TRANSFORM. If the frames have
   * no common ancestor, we return NO_COMMON_ANCESTOR.
   * If this returns TRANSFORM_SUCCEEDED, the points in aPoints are transformed
   * in-place, otherwise they are untouched.
   */

  enum TransformResult {
    TRANSFORM_SUCCEEDED,
    NO_COMMON_ANCESTOR,
    NONINVERTIBLE_TRANSFORM
  };
  static TransformResult TransformPoints(RelativeTo aFromFrame,
                                         RelativeTo aToFrame,
                                         uint32_t aPointCount,
                                         CSSPoint* aPoints);

  /**
   * Same as above function, but transform points in app units and
   * handle 1 point per call.
   */

  static TransformResult TransformPoint(RelativeTo aFromFrame,
                                        RelativeTo aToFrame, nsPoint& aPoint);

  /**
   * Transforms a rect from aFromFrame to aToFrame. In app units.
   * Returns the bounds of the actual rect if the transform requires rotation
   * or anything complex like that.
   */

  static TransformResult TransformRect(const nsIFrame* aFromFrame,
                                       const nsIFrame* aToFrame, nsRect& aRect);

  /**
   * Converts app units to pixels (with optional snapping) and appends as a
   * translation to aTransform.
   */

  static void PostTranslate(Matrix4x4& aTransform, const nsPoint& aOrigin,
                            float aAppUnitsPerPixel, bool aRounded);

  /*
   * Whether the frame should snap to grid. This will end up being passed
   * as the aRounded parameter in PostTranslate above. SVG frames should
   * not have their translation rounded.
   */

  static bool ShouldSnapToGrid(const nsIFrame* aFrame);

  /**
   * Get the border-box of aElement's primary frame, transformed it to be
   * relative to aFrame.
   */

  static nsRect GetRectRelativeToFrame(mozilla::dom::Element* aElement,
                                       nsIFrame* aFrame);

  /**
   * Returns true if aRect with border inflation of size aInflateSize contains
   * aPoint.
   */

  static bool ContainsPoint(const nsRect& aRect, const nsPoint& aPoint,
                            nscoord aInflateSize);

  /**
   * Clamp aRect relative to aFrame to the scroll frames boundary searching from
   * aFrame.
   */

  static nsRect ClampRectToScrollFrames(nsIFrame* aFrame, const nsRect& aRect);

  /**
   * Given a point in the global coordinate space, returns that point expressed
   * in the coordinate system of aFrame.  This effectively inverts all
   * transforms between this point and the root frame.
   *
   * @param aFromType Specifies whether |aPoint| is in layout or visual
   * coordinates.
   * @param aFrame The frame that acts as the coordinate space container.
   * @param aPoint The point, in global layout or visual coordinates (as per
   * |aFromType|, to get in the frame-local space.
   * @return aPoint, expressed in aFrame's canonical coordinate space.
   */

  static nsPoint TransformRootPointToFrame(ViewportType aFromType,
                                           RelativeTo aFrame,
                                           const nsPoint& aPoint) {
    return TransformAncestorPointToFrame(aFrame, aPoint,
                                         RelativeTo{nullptr, aFromType});
  }

  /**
   * Transform aPoint relative to aAncestor down to the coordinate system of
   * aFrame.
   */

  static nsPoint TransformAncestorPointToFrame(RelativeTo aFrame,
                                               const nsPoint& aPoint,
                                               RelativeTo aAncestor);

  static nsPoint TransformFramePointToRoot(ViewportType aToType,
                                           RelativeTo aFromFrame,
                                           const nsPoint& aPoint);

  /**
   * Helper function that, given a rectangle and a matrix, returns the smallest
   * rectangle containing the image of the source rectangle.
   *
   * @param aBounds The rectangle to transform.
   * @param aMatrix The matrix to transform it with.
   * @param aFactor The number of app units per graphics unit.
   * @return The smallest rect that contains the image of aBounds.
   */

  static nsRect MatrixTransformRect(const nsRect& aBounds,
                                    const Matrix4x4& aMatrix, float aFactor);
  static nsRect MatrixTransformRect(const nsRect& aBounds,
                                    const Matrix4x4Flagged& aMatrix,
                                    float aFactor);

  /**
   * Helper function that, given a point and a matrix, returns the image
   * of that point under the matrix transform.
   *
   * @param aPoint The point to transform.
   * @param aMatrix The matrix to transform it with.
   * @param aFactor The number of app units per graphics unit.
   * @return The image of the point under the transform.
   */

  static nsPoint MatrixTransformPoint(const nsPoint& aPoint,
                                      const Matrix4x4& aMatrix, float aFactor);

  /**
   * Given a graphics rectangle in graphics space, return a rectangle in
   * app space that contains the graphics rectangle, rounding out as necessary.
   *
   * @param aRect The graphics rect to round outward.
   * @param aFactor The number of app units per graphics unit.
   * @return The smallest rectangle in app space that contains aRect.
   */

  template <typename T>
  static nsRect RoundGfxRectToAppRect(const T& aRect, const float aFactor);

  /**
   * Returns a subrectangle of aContainedRect that is entirely inside the
   * rounded rect. Complex cases are handled conservatively by returning a
   * smaller rect than necessary.
   */

  static nsRegion RoundedRectIntersectRect(const nsRect& aRoundedRect,
                                           const nscoord aRadii[8],
                                           const nsRect& aContainedRect);
  static nsIntRegion RoundedRectIntersectIntRect(
      const nsIntRect& aRoundedRect, const RectCornerRadii& aCornerRadii,
      const nsIntRect& aContainedRect);

  /**
   * Return whether any part of aTestRect is inside of the rounded
   * rectangle formed by aBounds and aRadii (which are indexed by the
   * enum HalfCorner constants in gfx/2d/Types.h). This is precise.
   */

  static bool RoundedRectIntersectsRect(const nsRect& aRoundedRect,
                                        const nscoord aRadii[8],
                                        const nsRect& aTestRect);

  enum class PaintFrameFlags : uint32_t {
    InTransform = 0x01,
    SyncDecodeImages = 0x02,
    WidgetLayers = 0x04,
    IgnoreSuppression = 0x08,
    DocumentRelative = 0x10,
    HideCaret = 0x20,
    ToWindow = 0x40,
    ExistingTransaction = 0x80,
    ForWebRender = 0x100,
    UseHighQualityScaling = 0x200,
    ResetViewportScrolling = 0x400,
  };

  /**
   * Given aFrame, the root frame of a stacking context, paint it and its
   * descendants to aRenderingContext.
   * @param aRenderingContext a rendering context translated so that (0,0)
   * is the origin of aFrame; for best results, (0,0) should transform
   * to pixel-aligned coordinates. This can be null, in which case
   * aFrame must be a "display root" (root frame for a root document,
   * or the root of a popup) with an associated widget and we draw using
   * the layer manager for the frame's widget.
   * @param aDirtyRegion the region that must be painted, in the coordinates
   * of aFrame.
   * @param aBackstop paint the dirty area with this color before drawing
   * the actual content; pass NS_RGBA(0,0,0,0) to draw no background.
   * @param aBuilderMode Passed through to the display-list builder.
   * @param aFlags if PAINT_IN_TRANSFORM is set, then we assume
   * this is inside a transform or SVG foreignObject. If
   * PAINT_SYNC_DECODE_IMAGES is set, we force synchronous decode on all
   * images. If PAINT_WIDGET_LAYERS is set, aFrame must be a display root,
   * and we will use the frame's widget's layer manager to paint
   * even if aRenderingContext is non-null. This is useful if you want
   * to force rendering to use the widget's layer manager for testing
   * or speed. PAINT_WIDGET_LAYERS must be set if aRenderingContext is null.
   * If PAINT_DOCUMENT_RELATIVE is used, the visible region is interpreted
   * as being relative to the document (normally it's relative to the CSS
   * viewport) and the document is painted as if no scrolling has occured.
   * Only considered if PresShell::IgnoringViewportScrolling is true.
   * If ResetViewportScrolling is used, then the root scroll frame's scroll
   * position is set to 0 during painting, so that position:fixed elements
   * are drawn in their initial position.
   * PAINT_TO_WINDOW sets painting to window to true on the display list
   * builder even if we can't tell that we are painting to the window.
   * If PAINT_EXISTING_TRANSACTION is set, then BeginTransaction() has already
   * been called on aFrame's widget's layer manager and should not be
   * called again.
   * If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to
   * compressed mode to avoid short cut optimizations.
   *
   * So there are three possible behaviours:
   * 1) PAINT_WIDGET_LAYERS is set and aRenderingContext is null; we paint
   * by calling BeginTransaction on the widget's layer manager.
   * 2) PAINT_WIDGET_LAYERS is set and aRenderingContext is non-null; we
   * paint by calling BeginTransactionWithTarget on the widget's layer
   * manager.
   * 3) PAINT_WIDGET_LAYERS is not set and aRenderingContext is non-null;
   * we paint by construct a BasicLayerManager and calling
   * BeginTransactionWithTarget on it. This is desirable if we're doing
   * something like drawWindow in a mode where what gets rendered doesn't
   * necessarily correspond to what's visible in the window; we don't
   * want to mess up the widget's layer tree.
   */

  static void PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
                         const nsRegion& aDirtyRegion, nscolor aBackstop,
                         nsDisplayListBuilderMode aBuilderMode,
                         PaintFrameFlags aFlags = PaintFrameFlags(0));

  /**
   * Uses a binary search for find where the cursor falls in the line of text
   * It also keeps track of the part of the string that has already been
   * measured so it doesn't have to keep measuring the same text over and over.
   *
   * @param "aBaseWidth" contains the width in twips of the portion
   * of the text that has already been measured, and aBaseInx contains
   * the index of the text that has already been measured.
   *
   * @param aTextWidth returns (in twips) the length of the text that falls
   * before the cursor aIndex contains the index of the text where the cursor
   * falls.
   */

  static bool BinarySearchForPosition(DrawTarget* aDrawTarget,
                                      nsFontMetrics& aFontMetrics,
                                      const char16_t* aText, int32_t aBaseWidth,
                                      int32_t aBaseInx, int32_t aStartInx,
                                      int32_t aEndInx, int32_t aCursorPos,
                                      int32_t& aIndex, int32_t& aTextWidth);

  class BoxCallback {
   public:
    BoxCallback() = default;
    virtual void AddBox(nsIFrame* aFrame) = 0;
    bool mIncludeCaptionBoxForTable = true;
    // Whether we are in a continuation or ib-split-sibling of the target we're
    // measuring. This is useful because if we know we're in the target subtree
    // and measuring against it we can avoid finding the common ancestor.
    bool mInTargetContinuation = false;
  };
  /**
   * Collect all CSS boxes associated with aFrame and its
   * continuations, "drilling down" through table wrapper frames and
   * some anonymous blocks since they're not real CSS boxes.
   * If aFrame is null, no boxes are returned.
   * SVG frames return a single box, themselves.
   */

  static void GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback);

  /**
   * Like GetAllInFlowBoxes, but doesn't include continuations.
   */

  static void AddBoxesForFrame(nsIFrame* aFrame, BoxCallback* aCallback);

  /**
   * Find the first frame descendant of aFrame (including aFrame) which is
   * not an anonymous frame that getBoxQuads/getClientRects should ignore.
   */

  static nsIFrame* GetFirstNonAnonymousFrame(nsIFrame* aFrame);

  struct RectAccumulator : public mozilla::RectCallback {
    nsRect mResultRect;
    nsRect mFirstRect;
    bool mSeenFirstRect;

    RectAccumulator();

    virtual void AddRect(const nsRect& aRect) override;
  };

  struct RectListBuilder : public mozilla::RectCallback {
    DOMRectList* mRectList;

    explicit RectListBuilder(DOMRectList* aList);
    virtual void AddRect(const nsRect& aRect) override;
  };

  static nsIFrame* GetContainingBlockForClientRect(nsIFrame* aFrame);

  /**
   * Collect all CSS boxes (content, padding, border, or margin) associated
   * with aFrame and its continuations, "drilling down" through table wrapper
   * frames and some anonymous blocks since they're not real CSS boxes.
   *
   * The boxes are positioned relative to aRelativeTo (taking scrolling
   * into account) and passed to the callback in frame-tree order.
   * If aFrame is null, no boxes are returned.
   *
   * For SVG frames, returns one rectangle, the bounding box.
   *
   * If aFlags includes 'AccountForTransforms', then when converting the boxes
   * into aRelativeTo coordinates, transforms (including CSS and SVG transforms)
   * are taken into account.
   *
   * If aFlags includes one of 'UseContentBox', 'UsePaddingBox', 'UseMarginBox',
   * or 'UseMarginBoxWithAutoResolvedAsZero', the corresponding type of box is
   * used. Otherwise (by default), the border box is used. Note that these "Box"
   * flags are meant to be mutually exclusive, though we don't enforce that. If
   * multiple "Box" flags are used, we'll gracefully just use the first one in
   * the order of the enum.
   */

  enum class GetAllInFlowRectsFlag : uint8_t {
    AccountForTransforms,
    UseContentBox,
    UsePaddingBox,
    UseMarginBox,
    // Similar to UseMarginBox, but the 'auto' margins are resolved as zero.
    UseMarginBoxWithAutoResolvedAsZero,
  };
  using GetAllInFlowRectsFlags = mozilla::EnumSet<GetAllInFlowRectsFlag>;
  static void GetAllInFlowRects(nsIFrame* aFrame, const nsIFrame* aRelativeTo,
                                mozilla::RectCallback* aCallback,
                                GetAllInFlowRectsFlags aFlags = {});

  static void GetAllInFlowRectsAndTexts(
      nsIFrame* aFrame, const nsIFrame* aRelativeTo,
      mozilla::RectCallback* aCallback,
      mozilla::dom::Sequence<nsString>* aTextList,
      GetAllInFlowRectsFlags aFlags = {});

  /**
   * Computes the union of all rects returned by GetAllInFlowRects. If
   * the union is empty, returns the first rect.
   *
   * See GetAllInFlowRects() documentation for the meaning of aRelativeTo and
   * aFlags.
   */

  static nsRect GetAllInFlowRectsUnion(nsIFrame* aFrame,
                                       const nsIFrame* aRelativeTo,
                                       GetAllInFlowRectsFlags aFlags = {});

  enum { EXCLUDE_BLUR_SHADOWS = 0x01 };
  /**
   * Takes a text-shadow array from the style properties of a given nsIFrame and
   * computes the union of those shadows along with the given initial rect.
   * If there are no shadows, the initial rect is returned.
   */

  static nsRect GetTextShadowRectsUnion(const nsRect& aTextAndDecorationsRect,
                                        nsIFrame* aFrame, uint32_t aFlags = 0);

  /**
   * Computes the destination rect that a given replaced element should render
   * into, based on its CSS 'object-fit' and 'object-position' properties.
   *
   * @param aConstraintRect The constraint rect that we have at our disposal,
   *                        which would e.g. be exactly filled by the image
   *                        if we had "object-fit: fill".
   * @param aIntrinsicSize The replaced content's intrinsic size, as reported
   *                       by nsIFrame::GetIntrinsicSize().
   * @param aIntrinsicRatio The replaced content's intrinsic ratio, as reported
   *                        by nsIFrame::GetIntrinsicRatio().
   * @param aStylePos The nsStylePosition struct that contains the 'object-fit'
   *                  and 'object-position' values that we should rely on.
   *                  (This should usually be the nsStylePosition for the
   *                  replaced element in question, but not always. For
   *                  example, a <video>'s poster-image has a dedicated
   *                  anonymous element & child-frame, but we should still use
   *                  the <video>'s 'object-fit' and 'object-position' values.)
   * @param aAnchorPoint [out] A point that should be pixel-aligned by functions
   *                           like nsLayoutUtils::DrawImage. See documentation
   *                           in nsCSSRendering.h for ComputeObjectAnchorPoint.
   * @return The nsRect into which we should render the replaced content (using
   *         the same coordinate space as the passed-in aConstraintRect).
   */

  static nsRect ComputeObjectDestRect(const nsRect& aConstraintRect,
                                      const IntrinsicSize& aIntrinsicSize,
                                      const AspectRatio& aIntrinsicRatio,
                                      const nsStylePosition* aStylePos,
                                      nsPoint* aAnchorPoint = nullptr);

  /**
   * Get the font metrics corresponding to the frame's style data.
   * @param aFrame the frame
   * @param aSizeInflation number to multiply font size by
   */

  static already_AddRefed<nsFontMetrics> GetFontMetricsForFrame(
      const nsIFrame* aFrame, float aSizeInflation);

  static already_AddRefed<nsFontMetrics> GetInflatedFontMetricsForFrame(
      const nsIFrame* aFrame) {
    return GetFontMetricsForFrame(aFrame, FontSizeInflationFor(aFrame));
  }

  /**
   * Get the font metrics corresponding to the given style data.
   * @param aComputedStyle the style data
   * @param aSizeInflation number to multiply font size by
   */

  static already_AddRefed<nsFontMetrics> GetFontMetricsForComputedStyle(
      const ComputedStyle* aComputedStyle, nsPresContext* aPresContext,
      float aSizeInflation = 1.0f,
      uint8_t aVariantWidth = NS_FONT_VARIANT_WIDTH_NORMAL);

  /**
   * Get the font metrics of emphasis marks corresponding to the given
   * style data. The result is same as GetFontMetricsForComputedStyle
   * except that the font size is scaled down to 50%.
   * @param aComputedStyle the style data
   * @param aInflation number to multiple font size by
   */

  static already_AddRefed<nsFontMetrics> GetFontMetricsOfEmphasisMarks(
      ComputedStyle* aComputedStyle, nsPresContext* aPresContext,
      float aInflation) {
    return GetFontMetricsForComputedStyle(aComputedStyle, aPresContext,
                                          aInflation * 0.5f);
  }

  /**
   * Find the immediate child of aParent whose frame subtree contains
   * aDescendantFrame. Returns null if aDescendantFrame is not a descendant
   * of aParent.
   */

  static nsIFrame* FindChildContainingDescendant(nsIFrame* aParent,
                                                 nsIFrame* aDescendantFrame);

  /**
   * Find the nearest ancestor that's a block
   */

  static nsBlockFrame* FindNearestBlockAncestor(nsIFrame* aFrame);

  /**
   * Find the nearest ancestor that's not for generated content. Will return
   * aFrame if aFrame is not for generated content.
   */

  static nsIFrame* GetNonGeneratedAncestor(nsIFrame* aFrame);

  /*
   * Whether the frame is an nsBlockFrame which is not a wrapper block.
   */

  static bool IsNonWrapperBlock(nsIFrame* aFrame);

  /**
   * If aFrame is an out of flow frame, return its placeholder, otherwise
   * return its parent.
   */

  static nsIFrame* GetParentOrPlaceholderFor(const nsIFrame* aFrame);

  /**
   * If aFrame is an out of flow frame, return its placeholder, otherwise
   * return its (possibly cross-doc) parent.
   */

  static nsIFrame* GetParentOrPlaceholderForCrossDoc(const nsIFrame* aFrame);

  /**
   * Returns the frame that would act as the parent of aFrame when
   * descending through the frame tree in display list building.
   * Usually the same as GetParentOrPlaceholderForCrossDoc, except
   * that pushed floats are treated as children of their containing
   * block.
   */

  static nsIFrame* GetDisplayListParent(nsIFrame* aFrame);

  /**
   * Get a frame's previous continuation, or, if it doesn't have one, its
   * previous block-in-inline-split sibling.
   */

  static nsIFrame* GetPrevContinuationOrIBSplitSibling(const nsIFrame* aFrame);

  /**
   * Get a frame's next continuation, or, if it doesn't have one, its
   * block-in-inline-split sibling.
   */

  static nsIFrame* GetNextContinuationOrIBSplitSibling(const nsIFrame* aFrame);

  /**
   * Get the first frame in the continuation-plus-ib-split-sibling chain
   * containing aFrame.
   */

  static nsIFrame* FirstContinuationOrIBSplitSibling(const nsIFrame* aFrame);

  /**
   * Get the last frame in the continuation-plus-ib-split-sibling chain
   * containing aFrame.
   */

  static nsIFrame* LastContinuationOrIBSplitSibling(const nsIFrame* aFrame);

  /**
   * Is FirstContinuationOrIBSplitSibling(aFrame) going to return
   * aFrame?
   */

  static bool IsFirstContinuationOrIBSplitSibling(const nsIFrame* aFrame);

  /**
   * Check whether aFrame is a part of the scrollbar or scrollcorner of
   * the root content.
   * @param aFrame the checking frame.
   * @return true if the frame is a part of the scrollbar or scrollcorner of
   *         the root content.
   */

  static bool IsViewportScrollbarFrame(nsIFrame* aFrame);

  /**
   * Get the contribution of aFrame to its containing block's intrinsic
   * size for the given physical axis.  This considers the child's intrinsic
   * width, its 'width', 'min-width', and 'max-width' properties (or 'height'
   * variations if that's what matches aAxis) and its padding, border and margin
   * in the corresponding dimension.
   * @param aPercentageBasis an optional percentage basis (in aFrame's WM).
   *   If the basis is indefinite in a given axis, pass a size with
   *   NS_UNCONSTRAINEDSIZE in that component.
   *   If you pass Nothing() a percentage basis will be calculated from aFrame's
   *   ancestors' computed size in the relevant axis, if needed.
   * @param aMarginBoxMinSizeClamp make the result fit within this margin-box
   * size by reducing the *content size* (flooring at zero).  This is used for:
   * https://drafts.csswg.org/css-grid/#min-size-auto
   * @param aSizeOverrides optional override values for size properties, which
   * this function will use internally instead of the actual property values.
   */

  enum {
    IGNORE_PADDING = 0x01,
    BAIL_IF_REFLOW_NEEDED = 0x02,  // returns NS_INTRINSIC_ISIZE_UNKNOWN if so
    MIN_INTRINSIC_ISIZE = 0x04,  // use min-width/height instead of width/height
  };
  static nscoord IntrinsicForAxis(
      mozilla::PhysicalAxis aAxis, gfxContext* aRenderingContext,
      nsIFrame* aFrame, mozilla::IntrinsicISizeType aType,
      const mozilla::Maybe<LogicalSize>& aPercentageBasis = mozilla::Nothing(),
      uint32_t aFlags = 0, nscoord aMarginBoxMinSizeClamp = NS_MAXSIZE,
      const mozilla::StyleSizeOverrides& aSizeOverrides = {});
  /**
   * Calls IntrinsicForAxis with aFrame's parent's inline physical axis.
   */

  static nscoord IntrinsicForContainer(
      gfxContext* aRenderingContext, nsIFrame* aFrame,
      mozilla::IntrinsicISizeType aType,
      const mozilla::Maybe<LogicalSize>& aPercentageBasis = mozilla::Nothing(),
      uint32_t aFlags = 0,
      const mozilla::StyleSizeOverrides& aSizeOverrides = {});

  /**
   * Get the definite size contribution of aFrame for the given physical axis.
   * This considers the child's 'min-width' property (or 'min-height' if the
   * given axis is vertical), and its padding, border, and margin in the
   * corresponding dimension.  If the 'min-' property is 'auto' (and 'overflow'
   * is 'visible') and the corresponding 'width'/'height' is definite it returns
   * the "specified size" for:
   * https://drafts.csswg.org/css-grid/#min-size-auto
   * Note that the "transferred size" is not handled here; use IntrinsicForAxis.
   * Note that any percentage in 'width'/'height' makes it count as indefinite.
   * If the 'min-' property is 'auto' and 'overflow' is not 'visible', then it
   * calculates the result as if the 'min-' computed value is zero.
   * Otherwise, return NS_UNCONSTRAINEDSIZE.
   *
   * @param aPercentageBasis the percentage basis (in aFrame's WM).
   *   Pass NS_UNCONSTRAINEDSIZE if the basis is indefinite in either/both axes.
   * @note this behavior is specific to Grid/Flexbox (currently) so aFrame
   * should be a grid/flex item.
   */

  static nscoord MinSizeContributionForAxis(mozilla::PhysicalAxis aAxis,
                                            gfxContext* aRC, nsIFrame* aFrame,
                                            mozilla::IntrinsicISizeType aType,
                                            const LogicalSize& aPercentageBasis,
                                            uint32_t aFlags = 0);

  /*
   * Convert LengthPercentage to nscoord when percentages depend on the
   * containing block size.
   * @param aPercentBasis The width or height of the containing block
   * (whichever the client wants to use for resolving percentages).
   */

  static nscoord ComputeCBDependentValue(nscoord aPercentBasis,
                                         const LengthPercentage& aCoord) {
    NS_ASSERTION(aPercentBasis != NS_UNCONSTRAINEDSIZE || !aCoord.HasPercent(),
                 "Have unconstrained percentage basis when percentage "
                 "resolution needed; this should only result from very "
                 "large sizes, not attempts at intrinsic size calculation");
    return aCoord.Resolve(aPercentBasis);
  }
  static nscoord ComputeCBDependentValue(nscoord aPercentBasis,
                                         const LengthPercentageOrAuto& aCoord) {
    if (aCoord.IsAuto()) {
      return 0;
    }
    return ComputeCBDependentValue(aPercentBasis, aCoord.AsLengthPercentage());
  }

  static nscoord ComputeCBDependentValue(nscoord aPercentBasis,
                                         const mozilla::StyleInset& aInset) {
    if (!aInset.IsLengthPercentage()) {
--> --------------------

--> maximum size reached

--> --------------------

100%


¤ Dauer der Verarbeitung: 0.9 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.