tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsPresContext.h (51313B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /* a presentation of a document, part 1 */
      8 
      9 #ifndef nsPresContext_h___
     10 #define nsPresContext_h___
     11 
     12 #include "FontVisibilityProvider.h"
     13 #include "Units.h"
     14 #include "gfxRect.h"
     15 #include "gfxTypes.h"
     16 #include "mozilla/AppUnits.h"
     17 #include "mozilla/Attributes.h"
     18 #include "mozilla/DepthOrderedFrameList.h"
     19 #include "mozilla/EnumeratedArray.h"
     20 #include "mozilla/MediaEmulationData.h"
     21 #include "mozilla/MemoryReporting.h"
     22 #include "mozilla/NotNull.h"
     23 #include "mozilla/PreferenceSheet.h"
     24 #include "mozilla/PresShellForwards.h"
     25 #include "mozilla/ScrollStyles.h"
     26 #include "mozilla/TimeStamp.h"
     27 #include "mozilla/UniquePtr.h"
     28 #include "mozilla/WeakPtr.h"
     29 #include "mozilla/intl/Bidi.h"
     30 #include "mozilla/widget/ThemeChangeKind.h"
     31 #include "nsAtom.h"
     32 #include "nsCOMPtr.h"
     33 #include "nsChangeHint.h"
     34 #include "nsColor.h"
     35 #include "nsCompatibility.h"
     36 #include "nsCoord.h"
     37 #include "nsCycleCollectionParticipant.h"
     38 #include "nsFontMetrics.h"
     39 #include "nsGkAtoms.h"
     40 #include "nsHashKeys.h"
     41 #include "nsIWidgetListener.h"  // for nsSizeMode
     42 #include "nsRect.h"
     43 #include "nsStringFwd.h"
     44 #include "nsTArray.h"
     45 #include "nsTHashSet.h"
     46 #include "nsTHashtable.h"
     47 #include "nsThreadUtils.h"
     48 
     49 class nsIPrintSettings;
     50 class nsDocShell;
     51 class nsIDocShell;
     52 class nsITheme;
     53 class nsITimer;
     54 class nsIContent;
     55 class nsIFrame;
     56 class nsFrameManager;
     57 class nsAtom;
     58 class nsIRunnable;
     59 class gfxFontFamily;
     60 class gfxFontFeatureValueSet;
     61 class gfxUserFontEntry;
     62 class gfxUserFontSet;
     63 class gfxTextPerfMetrics;
     64 class nsCSSFontFeatureValuesRule;
     65 class nsCSSFrameConstructor;
     66 class nsFontCache;
     67 class nsTransitionManager;
     68 class nsAnimationManager;
     69 class nsRefreshDriver;
     70 class nsIWidget;
     71 class nsDeviceContext;
     72 class gfxMissingFontRecorder;
     73 
     74 namespace mozilla {
     75 class AnimationEventDispatcher;
     76 class EffectCompositor;
     77 class Encoding;
     78 class EventStateManager;
     79 class CounterStyleManager;
     80 class ManagedPostRefreshObserver;
     81 class PresShell;
     82 class RestyleManager;
     83 class ServoStyleSet;
     84 class StaticPresData;
     85 class TimelineManager;
     86 struct MediaFeatureChange;
     87 enum class MediaFeatureChangePropagation : uint8_t;
     88 enum class ColorScheme : uint8_t;
     89 enum class StyleForcedColors : uint8_t;
     90 namespace layers {
     91 class ContainerLayer;
     92 class LayerManager;
     93 }  // namespace layers
     94 namespace dom {
     95 class Document;
     96 class Element;
     97 class PerformanceMainThread;
     98 enum class PrefersColorSchemeOverride : uint8_t;
     99 }  // namespace dom
    100 namespace gfx {
    101 class FontPaletteValueSet;
    102 class PaletteCache;
    103 }  // namespace gfx
    104 }  // namespace mozilla
    105 
    106 // IDs for the default variable and fixed fonts (not to be changed, see
    107 // nsFont.h) To be used for Get/SetDefaultFont(). The other IDs in nsFont.h are
    108 // also supported.
    109 //
    110 // kGenericFont_moz_variable
    111 const uint8_t kPresContext_DefaultVariableFont_ID = 0x00;
    112 // kGenericFont_moz_fixed
    113 const uint8_t kPresContext_DefaultFixedFont_ID = 0x01;
    114 
    115 #ifdef DEBUG
    116 struct nsAutoLayoutPhase;
    117 
    118 enum class nsLayoutPhase : uint8_t {
    119  Paint,
    120  DisplayListBuilding,  // sometimes a subset of the paint phase
    121  Reflow,
    122  FrameC,
    123  COUNT
    124 };
    125 #endif
    126 
    127 class nsRootPresContext;
    128 
    129 // An interface for presentation contexts. Presentation contexts are
    130 // objects that provide an outer context for a presentation shell.
    131 
    132 class nsPresContext : public nsISupports,
    133                      public mozilla::SupportsWeakPtr,
    134                      public FontVisibilityProvider {
    135 public:
    136  using Encoding = mozilla::Encoding;
    137  template <typename T>
    138  using NotNull = mozilla::NotNull<T>;
    139  template <typename T>
    140  using Maybe = mozilla::Maybe<T>;
    141  using MediaEmulationData = mozilla::MediaEmulationData;
    142 
    143  typedef mozilla::ScrollStyles ScrollStyles;
    144  using TransactionId = mozilla::layers::TransactionId;
    145 
    146  NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINAL
    147  NS_DECL_CYCLE_COLLECTION_CLASS(nsPresContext)
    148 
    149  FONT_VISIBILITY_PROVIDER_IMPL
    150 
    151  enum nsPresContextType : uint8_t {
    152    eContext_Galley,        // unpaginated screen presentation
    153    eContext_PrintPreview,  // paginated screen presentation
    154    eContext_Print,         // paginated printer presentation
    155    eContext_PageLayout     // paginated & editable.
    156  };
    157 
    158  nsPresContext(mozilla::dom::Document* aDocument, nsPresContextType aType);
    159 
    160  /**
    161   * Initialize the presentation context from a particular device.
    162   */
    163  nsresult Init(nsDeviceContext* aDeviceContext);
    164 
    165  /**
    166   * Initialize the font cache if it hasn't been initialized yet.
    167   * (Needed for stylo)
    168   */
    169  void InitFontCache();
    170 
    171  void UpdateFontCacheUserFonts(gfxUserFontSet* aUserFontSet);
    172 
    173  /**
    174   * Get the nsFontMetrics that describe the properties of
    175   * an nsFont.
    176   * @param aFont font description to obtain metrics for
    177   */
    178  already_AddRefed<nsFontMetrics> GetMetricsFor(
    179      const nsFont& aFont, const nsFontMetrics::Params& aParams);
    180 
    181  /**
    182   * Notification when a font metrics instance created for this context is
    183   * about to be deleted
    184   */
    185  nsresult FontMetricsDeleted(const nsFontMetrics* aFontMetrics);
    186 
    187  /**
    188   * Attempt to free up resources by flushing out any fonts no longer
    189   * referenced by anything other than the font cache itself.
    190   * @return error status
    191   */
    192  nsresult FlushFontCache();
    193 
    194  /**
    195   * Set and detach presentation shell that this context is bound to.
    196   * A presentation context may only be bound to a single shell.
    197   */
    198  void AttachPresShell(mozilla::PresShell* aPresShell);
    199  void DetachPresShell();
    200 
    201  nsPresContextType Type() const { return mType; }
    202 
    203  /**
    204   * Get the PresentationShell that this context is bound to.
    205   */
    206  mozilla::PresShell* PresShell() const {
    207    NS_ASSERTION(mPresShell, "Null pres shell");
    208    return mPresShell;
    209  }
    210 
    211  mozilla::PresShell* GetPresShell() const { return mPresShell; }
    212 
    213  void DocumentCharSetChanged(NotNull<const Encoding*> aCharSet);
    214 
    215  mozilla::dom::PerformanceMainThread* GetPerformanceMainThread() const;
    216  /**
    217   * Returns the parent prescontext for this one. Returns null if this is a
    218   * root.
    219   */
    220  nsPresContext* GetParentPresContext() const;
    221 
    222  /**
    223   * Returns the prescontext of the root content document in the same process
    224   * that contains this presentation, or null if there isn't one.
    225   */
    226  nsPresContext* GetInProcessRootContentDocumentPresContext();
    227 
    228  /**
    229   * Returns the nearest widget for the root frame or view of this.
    230   */
    231  nsIWidget* GetNearestWidget() const;
    232 
    233  /**
    234   * Returns the root widget for this.
    235   */
    236  nsIWidget* GetRootWidget() const;
    237 
    238  /**
    239   * Returns the widget which may have native focus and handles text input
    240   * like keyboard input, IME, etc.
    241   */
    242  nsIWidget* GetTextInputHandlingWidget() const {
    243    // Currently, root widget for each PresContext handles text input.
    244    return GetRootWidget();
    245  }
    246 
    247  /**
    248   * Return the presentation context for the root of the view manager
    249   * hierarchy that contains this presentation context, or nullptr if it can't
    250   * be found (e.g. it's detached).
    251   */
    252  nsRootPresContext* GetRootPresContext() const;
    253 
    254  virtual bool IsRoot() const { return false; }
    255 
    256  mozilla::dom::Document* Document() const {
    257 #ifdef DEBUG
    258    ValidatePresShellAndDocumentReleation();
    259 #endif  // #ifdef DEBUG
    260    return mDocument;
    261  }
    262 
    263  inline mozilla::ServoStyleSet* StyleSet() const;
    264 
    265  bool HasPendingMediaQueryUpdates() const {
    266    return !!mPendingMediaFeatureValuesChange;
    267  }
    268 
    269  inline nsCSSFrameConstructor* FrameConstructor() const;
    270 
    271  mozilla::AnimationEventDispatcher* AnimationEventDispatcher() {
    272    return mAnimationEventDispatcher;
    273  }
    274 
    275  mozilla::EffectCompositor* EffectCompositor() { return mEffectCompositor; }
    276  nsTransitionManager* TransitionManager() { return mTransitionManager.get(); }
    277  nsAnimationManager* AnimationManager() { return mAnimationManager.get(); }
    278  const nsAnimationManager* AnimationManager() const {
    279    return mAnimationManager.get();
    280  }
    281  mozilla::TimelineManager* TimelineManager() { return mTimelineManager.get(); }
    282 
    283  nsRefreshDriver* RefreshDriver() { return mRefreshDriver; }
    284 
    285  mozilla::RestyleManager* RestyleManager() {
    286    MOZ_ASSERT(mRestyleManager);
    287    return mRestyleManager.get();
    288  }
    289 
    290  mozilla::CounterStyleManager* CounterStyleManager() const {
    291    return mCounterStyleManager;
    292  }
    293 
    294  /**
    295   * Rebuilds all style data by throwing out the old rule tree and
    296   * building a new one, and additionally applying a change hint (which must not
    297   * contain nsChangeHint_ReconstructFrame) to the root frame.
    298   *
    299   * For the restyle hint argument, see RestyleManager::RebuildAllStyleData.
    300   * Also rebuild the user font set and counter style manager.
    301   *
    302   * FIXME(emilio): The name of this is an utter lie. We should probably call
    303   * this PostGlobalStyleChange or something, as it doesn't really rebuild
    304   * anything unless you tell it to via the change hint / restyle hint
    305   * machinery.
    306   */
    307  void RebuildAllStyleData(nsChangeHint, const mozilla::RestyleHint&);
    308  /**
    309   * Just like RebuildAllStyleData, except (1) asynchronous and (2) it
    310   * doesn't rebuild the user font set / counter-style manager / etc.
    311   */
    312  void PostRebuildAllStyleDataEvent(nsChangeHint, const mozilla::RestyleHint&);
    313 
    314  void ContentLanguageChanged();
    315 
    316  /** Returns whether any media query changed. */
    317  bool FlushPendingMediaFeatureValuesChanged();
    318 
    319  /**
    320   * Schedule a media feature change for this document, and potentially for
    321   * other subdocuments and images (depending on the arguments).
    322   */
    323  void MediaFeatureValuesChanged(const mozilla::MediaFeatureChange&,
    324                                 mozilla::MediaFeatureChangePropagation);
    325 
    326  /**
    327   * Updates the size mode on all remote children and recursively notifies this
    328   * document and all subdocuments (including remote children) that a media
    329   * feature value has changed.
    330   */
    331  void SizeModeChanged(nsSizeMode aSizeMode);
    332 
    333  /**
    334   * Access compatibility mode for this context.  This is the same as
    335   * our document's compatibility mode.
    336   */
    337  nsCompatibility CompatibilityMode() const;
    338 
    339  /**
    340   * Access the image animation mode for this context
    341   */
    342  uint16_t ImageAnimationMode() const { return mImageAnimationMode; }
    343  void SetImageAnimationMode(uint16_t aMode);
    344 
    345  /**
    346   * Get medium of presentation
    347   */
    348  const nsAtom* Medium() const {
    349    MOZ_ASSERT(mMedium);
    350    return mMediaEmulationData.mMedium ? mMediaEmulationData.mMedium.get()
    351                                       : mMedium;
    352  }
    353 
    354  /*
    355   * Render the document as if being viewed on a device with the specified
    356   * media type.
    357   *
    358   * If passed null, it stops emulating.
    359   */
    360  void EmulateMedium(nsAtom* aMediaType);
    361 
    362  const mozilla::PreferenceSheet::Prefs& PrefSheetPrefs() const {
    363    return mozilla::PreferenceSheet::PrefsFor(*mDocument);
    364  }
    365 
    366  mozilla::StyleForcedColors ForcedColors() const { return mForcedColors; }
    367  bool ForcingColors() const;
    368 
    369  mozilla::ColorScheme DefaultBackgroundColorScheme() const;
    370  nscolor DefaultBackgroundColor() const;
    371 
    372  nsISupports* GetContainerWeak() const;
    373 
    374  nsDocShell* GetDocShell() const;
    375 
    376  /**
    377   * Get the visible area associated with this presentation context.
    378   * This is the size of the visible area that is used for
    379   * presenting the document. The returned value is in the standard
    380   * nscoord units (as scaled by the device context).
    381   */
    382  nsRect GetVisibleArea() const { return mVisibleArea; }
    383 
    384  /**
    385   * Set the currently visible area. The units for r are standard
    386   * nscoord units (as scaled by the device context).
    387   */
    388  void SetVisibleArea(const nsRect& aRect);
    389 
    390  /**
    391   * Set the initial visible area. This should be called only from
    392   * nsDocumentViewer when initializing this pres context visible area with
    393   * the document viewer bounds.
    394   */
    395  void SetInitialVisibleArea(const nsRect& aRect);
    396 
    397  nsSize GetSizeForViewportUnits() const { return mSizeForViewportUnits; }
    398 
    399  /**
    400   * Set the maximum height of the dynamic toolbar in nscoord units.
    401   */
    402  MOZ_CAN_RUN_SCRIPT
    403  void SetDynamicToolbarMaxHeight(mozilla::ScreenIntCoord aHeight);
    404 
    405  /**
    406   * Returns true if we are using the dynamic toolbar.
    407   */
    408  bool HasDynamicToolbar() const { return GetDynamicToolbarMaxHeight() > 0; }
    409 
    410  /*
    411   * |aOffset| must be offset from the bottom edge of the ICB and it's negative.
    412   */
    413  void UpdateDynamicToolbarOffset(mozilla::ScreenIntCoord aOffset);
    414 
    415  mozilla::ScreenIntCoord GetDynamicToolbarMaxHeight() const {
    416    MOZ_ASSERT_IF(mDynamicToolbarMaxHeight > 0,
    417                  IsRootContentDocumentCrossProcess());
    418    return mDynamicToolbarMaxHeight;
    419  }
    420 
    421  nscoord GetDynamicToolbarMaxHeightInAppUnits() const;
    422 
    423  mozilla::ScreenIntCoord GetDynamicToolbarHeight() const {
    424    MOZ_ASSERT_IF(mDynamicToolbarHeight > 0,
    425                  IsRootContentDocumentCrossProcess());
    426    return mDynamicToolbarHeight;
    427  }
    428 
    429  void UpdateKeyboardHeight(mozilla::ScreenIntCoord aHeight);
    430 
    431  mozilla::ScreenIntCoord GetKeyboardHeight() const;
    432 
    433  /**
    434   * Returns true if the software keyboard is hidden or
    435   * the document is `interactive-widget=resizes-content` mode.
    436   */
    437  bool IsKeyboardHiddenOrResizesContentMode() const;
    438 
    439  /**
    440   * Returns the maximum height of the dynamic toolbar if the toolbar state is
    441   * `DynamicToolbarState::Collapsed`, otherwise returns zero.
    442   */
    443  nscoord GetBimodalDynamicToolbarHeightInAppUnits() const;
    444 
    445  /**
    446   * Returns the state of the dynamic toolbar.
    447   */
    448  mozilla::DynamicToolbarState GetDynamicToolbarState() const;
    449 
    450  /**
    451   * Return true if this presentation context is a paginated
    452   * context.
    453   */
    454  bool IsPaginated() const { return mPaginated; }
    455 
    456  /**
    457   * Sets whether the presentation context can scroll for a paginated
    458   * context.
    459   */
    460  void SetPaginatedScrolling(bool aResult);
    461 
    462  /**
    463   * Return true if this presentation context can scroll for paginated
    464   * context.
    465   */
    466  bool HasPaginatedScrolling() const { return mCanPaginatedScroll; }
    467 
    468  uint32_t LastScrollGeneration() { return mLastScrollGeneration; }
    469  void UpdateLastScrollGeneration() { mLastScrollGeneration += 1; }
    470  bool HasBeenScrolledSince(const uint32_t& mPreviousScrollGeneration) const {
    471    return mPreviousScrollGeneration < mLastScrollGeneration;
    472  }
    473 
    474  /**
    475   * Get/set the size of a page
    476   */
    477  const nsSize& GetPageSize() const { return mPageSize; }
    478  const nsMargin& GetDefaultPageMargin() const { return mDefaultPageMargin; }
    479  void SetPageSize(nsSize aSize) { mPageSize = aSize; }
    480 
    481  /**
    482   * Get/set whether this document should be treated as having real pages
    483   * XXX This raises the obvious question of why a document that isn't a page
    484   *     is paginated; there isn't a good reason except history
    485   */
    486  bool IsRootPaginatedDocument() { return mIsRootPaginatedDocument; }
    487  void SetIsRootPaginatedDocument(bool aIsRootPaginatedDocument) {
    488    mIsRootPaginatedDocument = aIsRootPaginatedDocument;
    489  }
    490 
    491  /**
    492   * Get/set the print scaling level; used by nsPageFrame to scale up
    493   * pages.  Set safe to call before reflow, get guaranteed to be set
    494   * properly after reflow.
    495   */
    496 
    497  float GetPageScale() { return mPageScale; }
    498  void SetPageScale(float aScale) { mPageScale = aScale; }
    499 
    500  /**
    501   * Get/set the scaling factor to use when rendering the pages for print
    502   * preview. Only safe to get after print preview set up; safe to set anytime.
    503   * This is a scaling factor for the display of the print preview.  It
    504   * does not affect layout.  It only affects the size of the onscreen pages
    505   * in print preview.
    506   *
    507   * The getter should only be used by the page sequence frame, which is the
    508   * frame responsible for applying the scaling. Other callers should use
    509   * nsPageSequenceFrame::GetPrintPreviewScale() if needed, instead of this API.
    510   *
    511   * XXX Temporary: see http://wiki.mozilla.org/Gecko:PrintPreview
    512   */
    513  float GetPrintPreviewScaleForSequenceFrameOrScrollbars() const {
    514    return mPPScale;
    515  }
    516  void SetPrintPreviewScale(float aScale) { mPPScale = aScale; }
    517 
    518  nsDeviceContext* DeviceContext() const { return mDeviceContext; }
    519  mozilla::EventStateManager* EventStateManager() { return mEventManager; }
    520 
    521  bool UserInputEventsAllowed();
    522 
    523  void MaybeIncreaseMeasuredTicksSinceLoading();
    524 
    525  bool NeedsMoreTicksForUserInput() const;
    526 
    527  void ResetUserInputEventsAllowed() {
    528    MOZ_ASSERT(IsRoot());
    529    mMeasuredTicksSinceLoading = 0;
    530    mUserInputEventsAllowed = false;
    531  }
    532 
    533  // Get the text zoom factor in use.
    534  float TextZoom() const { return mTextZoom; }
    535 
    536  /**
    537   * Notify the pres context that the safe area insets have changed.
    538   */
    539  void SetSafeAreaInsets(const mozilla::LayoutDeviceIntMargin& aInsets);
    540 
    541  const mozilla::LayoutDeviceIntMargin& GetSafeAreaInsets() const {
    542    return mSafeAreaInsets;
    543  }
    544 
    545  void RegisterManagedPostRefreshObserver(mozilla::ManagedPostRefreshObserver*);
    546  void UnregisterManagedPostRefreshObserver(
    547      mozilla::ManagedPostRefreshObserver*);
    548 
    549 protected:
    550  void CancelManagedPostRefreshObservers();
    551 
    552 #ifdef DEBUG
    553  void ValidatePresShellAndDocumentReleation() const;
    554 #endif  // #ifdef DEBUG
    555 
    556  void SetTextZoom(float aZoom);
    557  void SetFullZoom(float aZoom);
    558  void SetOverrideDPPX(float);
    559  void SetInRDMPane(bool aInRDMPane);
    560  void UpdateTopInnerSizeForRFP();
    561  void UpdateForcedColors(bool aNotify = true);
    562 
    563 public:
    564  float GetFullZoom() { return mFullZoom; }
    565  /**
    566   * Device full zoom differs from full zoom because it gets the zoom from
    567   * the device context, which may be using a different zoom due to rounding
    568   * of app units to device pixels.
    569   */
    570  float GetDeviceFullZoom();
    571 
    572  float GetOverrideDPPX() const { return mMediaEmulationData.mDPPX; }
    573 
    574  // Gets the forced color-scheme if any via either our embedder, or DevTools
    575  // emulation, or printing.
    576  //
    577  // NOTE(emilio): This might be called from an stylo thread.
    578  Maybe<mozilla::ColorScheme> GetOverriddenOrEmbedderColorScheme() const;
    579 
    580  /**
    581   * Recomputes the data dependent on the browsing context, like zoom and text
    582   * zoom.
    583   */
    584  void RecomputeBrowsingContextDependentData();
    585 
    586  /**
    587   * Sets the effective color scheme override, and invalidate stuff as needed.
    588   */
    589  void SetColorSchemeOverride(mozilla::dom::PrefersColorSchemeOverride);
    590 
    591  /**
    592   * Return the device's screen size in inches, for font size
    593   * inflation.
    594   *
    595   * If |aChanged| is non-null, then aChanged is filled in with whether
    596   * the screen size value has changed since either:
    597   *  a. the last time the function was called with non-null aChanged, or
    598   *  b. the first time the function was called.
    599   */
    600  gfxSize ScreenSizeInchesForFontInflation(bool* aChanged = nullptr);
    601 
    602  int32_t AppUnitsPerDevPixel() const { return mCurAppUnitsPerDevPixel; }
    603 
    604  static nscoord CSSPixelsToAppUnits(int32_t aPixels) {
    605    return NSToCoordRoundWithClamp(float(aPixels) *
    606                                   float(mozilla::AppUnitsPerCSSPixel()));
    607  }
    608 
    609  static nscoord CSSPixelsToAppUnits(float aPixels) {
    610    return NSToCoordRoundWithClamp(aPixels *
    611                                   float(mozilla::AppUnitsPerCSSPixel()));
    612  }
    613 
    614  static int32_t AppUnitsToIntCSSPixels(nscoord aAppUnits) {
    615    return NSAppUnitsToIntPixels(aAppUnits,
    616                                 float(mozilla::AppUnitsPerCSSPixel()));
    617  }
    618 
    619  static float AppUnitsToFloatCSSPixels(nscoord aAppUnits) {
    620    return NSAppUnitsToFloatPixels(aAppUnits,
    621                                   float(mozilla::AppUnitsPerCSSPixel()));
    622  }
    623 
    624  static double AppUnitsToDoubleCSSPixels(nscoord aAppUnits) {
    625    return NSAppUnitsToDoublePixels(aAppUnits,
    626                                    double(mozilla::AppUnitsPerCSSPixel()));
    627  }
    628 
    629  nscoord DevPixelsToAppUnits(int32_t aPixels) const {
    630    return NSIntPixelsToAppUnits(aPixels, AppUnitsPerDevPixel());
    631  }
    632 
    633  int32_t AppUnitsToDevPixels(nscoord aAppUnits) const {
    634    return NSAppUnitsToIntPixels(aAppUnits, float(AppUnitsPerDevPixel()));
    635  }
    636 
    637  float AppUnitsToFloatDevPixels(nscoord aAppUnits) const {
    638    return aAppUnits / float(AppUnitsPerDevPixel());
    639  }
    640 
    641  int32_t CSSPixelsToDevPixels(int32_t aPixels) const {
    642    return AppUnitsToDevPixels(CSSPixelsToAppUnits(aPixels));
    643  }
    644 
    645  float CSSPixelsToDevPixels(float aPixels) const {
    646    return NSAppUnitsToFloatPixels(CSSPixelsToAppUnits(aPixels),
    647                                   float(AppUnitsPerDevPixel()));
    648  }
    649 
    650  int32_t DevPixelsToIntCSSPixels(int32_t aPixels) const {
    651    return AppUnitsToIntCSSPixels(DevPixelsToAppUnits(aPixels));
    652  }
    653 
    654  static nscoord RoundDownAppUnitsToCSSPixel(nscoord aAppUnits) {
    655    return mozilla::RoundDownToMultiple(aAppUnits,
    656                                        mozilla::AppUnitsPerCSSPixel());
    657  }
    658  static nscoord RoundUpAppUnitsToCSSPixel(nscoord aAppUnits) {
    659    return mozilla::RoundUpToMultiple(aAppUnits,
    660                                      mozilla::AppUnitsPerCSSPixel());
    661  }
    662  static nscoord RoundAppUnitsToCSSPixel(nscoord aAppUnits) {
    663    return mozilla::RoundToMultiple(aAppUnits, mozilla::AppUnitsPerCSSPixel());
    664  }
    665 
    666  nscoord RoundDownAppUnitsToDevPixel(nscoord aAppUnits) const {
    667    return mozilla::RoundDownToMultiple(aAppUnits, AppUnitsPerDevPixel());
    668  }
    669  nscoord RoundUpAppUnitsToDevPixel(nscoord aAppUnits) const {
    670    return mozilla::RoundUpToMultiple(aAppUnits, AppUnitsPerDevPixel());
    671  }
    672  nscoord RoundAppUnitsToDevPixel(nscoord aAppUnits) const {
    673    return mozilla::RoundToMultiple(aAppUnits, AppUnitsPerDevPixel());
    674  }
    675 
    676  mozilla::CSSIntPoint DevPixelsToIntCSSPixels(
    677      const mozilla::LayoutDeviceIntPoint& aPoint) {
    678    return mozilla::CSSIntPoint(
    679        AppUnitsToIntCSSPixels(DevPixelsToAppUnits(aPoint.x)),
    680        AppUnitsToIntCSSPixels(DevPixelsToAppUnits(aPoint.y)));
    681  }
    682 
    683  float DevPixelsToFloatCSSPixels(int32_t aPixels) const {
    684    return AppUnitsToFloatCSSPixels(DevPixelsToAppUnits(aPixels));
    685  }
    686 
    687  mozilla::CSSToLayoutDeviceScale CSSToDevPixelScale() const {
    688    return mozilla::CSSToLayoutDeviceScale(
    689        float(mozilla::AppUnitsPerCSSPixel()) / float(AppUnitsPerDevPixel()));
    690  }
    691 
    692  // If there is a remainder, it is rounded to nearest app units.
    693  nscoord GfxUnitsToAppUnits(gfxFloat aGfxUnits) const;
    694 
    695  gfxFloat AppUnitsToGfxUnits(nscoord aAppUnits) const;
    696 
    697  gfxRect AppUnitsToGfxUnits(const nsRect& aAppRect) const {
    698    return gfxRect(AppUnitsToGfxUnits(aAppRect.x),
    699                   AppUnitsToGfxUnits(aAppRect.y),
    700                   AppUnitsToGfxUnits(aAppRect.Width()),
    701                   AppUnitsToGfxUnits(aAppRect.Height()));
    702  }
    703 
    704  static nscoord CSSTwipsToAppUnits(float aTwips) {
    705    return NSToCoordRoundWithClamp(mozilla::AppUnitsPerCSSInch() *
    706                                   NS_TWIPS_TO_INCHES(aTwips));
    707  }
    708 
    709  // Margin-specific version, since they often need TwipsToAppUnits
    710  static nsMargin CSSTwipsToAppUnits(const nsIntMargin& marginInTwips) {
    711    return nsMargin(CSSTwipsToAppUnits(float(marginInTwips.top)),
    712                    CSSTwipsToAppUnits(float(marginInTwips.right)),
    713                    CSSTwipsToAppUnits(float(marginInTwips.bottom)),
    714                    CSSTwipsToAppUnits(float(marginInTwips.left)));
    715  }
    716 
    717  static nscoord CSSPointsToAppUnits(float aPoints) {
    718    return NSToCoordRound(aPoints * mozilla::AppUnitsPerCSSInch() /
    719                          POINTS_PER_INCH_FLOAT);
    720  }
    721 
    722  nscoord PhysicalMillimetersToAppUnits(float aMM) const;
    723 
    724  nscoord RoundAppUnitsToNearestDevPixels(nscoord aAppUnits) const {
    725    return DevPixelsToAppUnits(AppUnitsToDevPixels(aAppUnits));
    726  }
    727 
    728  /**
    729   * This checks the root element and the HTML BODY, if any, for an "overflow"
    730   * property that should be applied to the viewport. If one is found then we
    731   * return the element that we took the overflow from (which should then be
    732   * treated as "overflow: visible"), and we store the overflow style here.
    733   * If the document is in fullscreen, and the fullscreen element is not the
    734   * root, the scrollbar of viewport will be suppressed.
    735   * @param aRemovedChild the element we're about to remove from the DOM, which
    736   *                      we can't make the new override element.
    737   * @return if scroll was propagated from some content node, the content node
    738   *         it was propagated from.
    739   */
    740  mozilla::dom::Element* UpdateViewportScrollStylesOverride(
    741      const mozilla::dom::Element* aRemovedChild = nullptr);
    742 
    743  /**
    744   * Returns the cached result from the last call to
    745   * UpdateViewportScrollStylesOverride() -- i.e. return the node
    746   * whose scrollbar styles we have propagated to the viewport (or nullptr if
    747   * there is no such node).
    748   */
    749  mozilla::dom::Element* GetViewportScrollStylesOverrideElement() const {
    750    return mViewportScrollOverrideElement;
    751  }
    752 
    753  const ScrollStyles& GetViewportScrollStylesOverride() const {
    754    return mViewportScrollStyles;
    755  }
    756 
    757  /**
    758   * Check whether the given element would propagate its scrollbar styles to the
    759   * viewport in non-paginated mode.
    760   */
    761  bool ElementWouldPropagateScrollStyles(const mozilla::dom::Element&);
    762 
    763  /**
    764   * Methods for controlling the background drawing.
    765   */
    766  bool GetBackgroundImageDraw() const { return mDrawImageBackground; }
    767  bool GetBackgroundColorDraw() const { return mDrawColorBackground; }
    768 
    769  /**
    770   *  Check if bidi enabled (set depending on the presence of RTL
    771   *  characters or when default directionality is RTL).
    772   *  If enabled, we should apply the Unicode Bidi Algorithm
    773   *
    774   *  @lina 07/12/2000
    775   */
    776  bool BidiEnabled() const;
    777 
    778  /**
    779   *  Set bidi enabled. This means we should apply the Unicode Bidi Algorithm
    780   *
    781   *  @lina 07/12/2000
    782   */
    783  void SetBidiEnabled() const;
    784 
    785  /**
    786   *  Set visual or implicit mode into the pres context.
    787   *
    788   *  Visual directionality is a presentation method that displays text
    789   *  as if it were a uni-directional, according to the primary display
    790   *  direction only.
    791   *
    792   *  Implicit directionality is a presentation method in which the
    793   *  direction is determined by the Bidi algorithm according to the
    794   *  category of the characters and the category of the adjacent
    795   *  characters, and according to their primary direction.
    796   *
    797   *  @lina 05/02/2000
    798   */
    799  void SetVisualMode(bool aIsVisual) { mIsVisual = aIsVisual; }
    800 
    801  /**
    802   *  Check whether the content should be treated as visual.
    803   *
    804   *  @lina 05/02/2000
    805   */
    806  bool IsVisualMode() const { return mIsVisual; }
    807 
    808  enum class InteractionType : uint32_t {
    809    ClickInteraction,
    810    KeyInteraction,
    811    MouseMoveInteraction,
    812    ScrollInteraction
    813  };
    814 
    815  void RecordInteractionTime(InteractionType aType,
    816                             const mozilla::TimeStamp& aTimeStamp);
    817 
    818  void DisableInteractionTimeRecording() { mInteractionTimeEnabled = false; }
    819 
    820  // Mohamed
    821 
    822  /**
    823   * Set the Bidi options for the presentation context
    824   */
    825  void SetBidi(uint32_t aBidiOptions);
    826 
    827  /**
    828   * Get the Bidi options for the presentation context
    829   * Not inline so consumers of nsPresContext are not forced to
    830   * include Document.
    831   */
    832  uint32_t GetBidi() const;
    833 
    834  nsITheme* Theme() const MOZ_NONNULL_RETURN;
    835 
    836  void RecomputeTheme();
    837 
    838  bool UseOverlayScrollbars() const;
    839 
    840  /*
    841   * Notify the pres context that the theme has changed.  An internal switch
    842   * means it's one of our Mozilla themes that changed (e.g., Modern to
    843   * Classic). Otherwise, the OS is telling us that the native theme for the
    844   * platform has changed.
    845   */
    846  void ThemeChanged(mozilla::widget::ThemeChangeKind);
    847 
    848  /*
    849   * Notify the pres context that the resolution of the user interface has
    850   * changed. This happens if a window is moved between HiDPI and non-HiDPI
    851   * displays, so that the ratio of points to device pixels changes.
    852   * The notification happens asynchronously.
    853   */
    854  void UIResolutionChanged();
    855 
    856  /*
    857   * Like UIResolutionChanged() but invalidates values immediately.
    858   */
    859  void UIResolutionChangedSync();
    860 
    861  /** Printing methods below should only be used for Medium() == print **/
    862  void SetPrintSettings(nsIPrintSettings* aPrintSettings);
    863 
    864  nsIPrintSettings* GetPrintSettings() { return mPrintSettings; }
    865 
    866  /* Helper function that ensures that this prescontext is shown in its
    867     docshell if it's the most recent prescontext for the docshell.  Returns
    868     whether the prescontext is now being shown.
    869  */
    870  bool EnsureVisible();
    871 
    872 #ifdef MOZ_REFLOW_PERF
    873  void CountReflows(const char* aName, nsIFrame* aFrame);
    874 #endif
    875 
    876  void ConstructedFrame() { ++mFramesConstructed; }
    877  void ReflowedFrame() { ++mFramesReflowed; }
    878  void TriggeredAnimationRestyle() { ++mAnimationTriggeredRestyles; }
    879 
    880  uint64_t FramesConstructedCount() const { return mFramesConstructed; }
    881  uint64_t FramesReflowedCount() const { return mFramesReflowed; }
    882  uint64_t AnimationTriggeredRestylesCount() const {
    883    return mAnimationTriggeredRestyles;
    884  }
    885 
    886  static nscoord GetBorderWidthForKeyword(unsigned int aBorderWidthKeyword) {
    887    // This table maps border-width enums 'thin', 'medium', 'thick'
    888    // to actual nscoord values.
    889    static const nscoord kBorderWidths[] = {
    890        CSSPixelsToAppUnits(1), CSSPixelsToAppUnits(3), CSSPixelsToAppUnits(5)};
    891    MOZ_ASSERT(size_t(aBorderWidthKeyword) < std::size(kBorderWidths));
    892 
    893    return kBorderWidths[aBorderWidthKeyword];
    894  }
    895 
    896  gfxTextPerfMetrics* GetTextPerfMetrics() { return mTextPerf.get(); }
    897 
    898  bool IsDynamic() const {
    899    return mType == eContext_PageLayout || mType == eContext_Galley;
    900  }
    901  bool IsScreen() const {
    902    return mMedium == nsGkAtoms::screen || mType == eContext_PageLayout ||
    903           mType == eContext_PrintPreview;
    904  }
    905  bool IsPrintingOrPrintPreview() const {
    906    return mType == eContext_Print || mType == eContext_PrintPreview;
    907  }
    908 
    909  bool IsPrintPreview() const { return mType == eContext_PrintPreview; }
    910 
    911  gfxUserFontSet* GetUserFontSet();
    912 
    913  gfxMissingFontRecorder* MissingFontRecorder() { return mMissingFonts.get(); }
    914 
    915  void NotifyMissingFonts();
    916 
    917  void FlushCounterStyles();
    918  void MarkCounterStylesDirty();
    919 
    920  void FlushFontFeatureValues();
    921  void MarkFontFeatureValuesDirty() { mFontFeatureValuesDirty = true; }
    922 
    923  void FlushFontPaletteValues();
    924  void MarkFontPaletteValuesDirty() { mFontPaletteValuesDirty = true; }
    925 
    926  mozilla::gfx::PaletteCache& FontPaletteCache();
    927 
    928  // Ensure that it is safe to hand out CSS rules outside the layout
    929  // engine by ensuring that all CSS style sheets have unique inners
    930  // and, if necessary, synchronously rebuilding all style data.
    931  void EnsureSafeToHandOutCSSRules();
    932 
    933  // Mark an area as invalidated, associated with a given transaction id
    934  // (allocated by nsRefreshDriver::GetTransactionId). Invalidated regions will
    935  // be dispatched to MozAfterPaint events when NotifyDidPaintForSubtree is
    936  // called for the transaction id (or any higher id).
    937  void NotifyInvalidation(TransactionId aTransactionId, const nsRect& aRect);
    938  void NotifyDidPaintForSubtree(
    939      TransactionId aTransactionId = TransactionId{0},
    940      const mozilla::TimeStamp& aTimeStamp = mozilla::TimeStamp());
    941  void NotifyRevokingDidPaint(TransactionId aTransactionId);
    942  // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
    943  MOZ_CAN_RUN_SCRIPT_BOUNDARY void FireDOMPaintEvent(
    944      nsTArray<nsRect>* aList, TransactionId aTransactionId,
    945      mozilla::TimeStamp aTimeStamp = mozilla::TimeStamp());
    946 
    947  bool IsDOMPaintEventPending();
    948 
    949  /**
    950   * Returns the RestyleManager's restyle generation counter.
    951   */
    952  uint64_t GetRestyleGeneration() const;
    953  uint64_t GetUndisplayedRestyleGeneration() const;
    954 
    955  /**
    956   * Notify the prescontext that the presshell is about to reflow a reflow root.
    957   * The single argument indicates whether this reflow should be interruptible.
    958   * If aInterruptible is false then CheckForInterrupt and HasPendingInterrupt
    959   * will always return false. If aInterruptible is true then CheckForInterrupt
    960   * will return true when a pending event is detected.  This is for use by the
    961   * presshell only.  Reflow code wanting to prevent interrupts should use
    962   * InterruptPreventer.
    963   */
    964  void ReflowStarted(bool aInterruptible);
    965 
    966  /**
    967   * A class that can be used to temporarily disable reflow interruption.
    968   */
    969  class InterruptPreventer;
    970  friend class InterruptPreventer;
    971  class MOZ_STACK_CLASS InterruptPreventer {
    972   public:
    973    explicit InterruptPreventer(nsPresContext* aCtx)
    974        : mCtx(aCtx),
    975          mInterruptsEnabled(aCtx->mInterruptsEnabled),
    976          mHasPendingInterrupt(aCtx->mHasPendingInterrupt) {
    977      mCtx->mInterruptsEnabled = false;
    978      mCtx->mHasPendingInterrupt = false;
    979    }
    980    ~InterruptPreventer() {
    981      mCtx->mInterruptsEnabled = mInterruptsEnabled;
    982      mCtx->mHasPendingInterrupt = mHasPendingInterrupt;
    983    }
    984 
    985   private:
    986    nsPresContext* mCtx;
    987    bool mInterruptsEnabled;
    988    bool mHasPendingInterrupt;
    989  };
    990 
    991  /**
    992   * Check for interrupts. This may return true if a pending event is
    993   * detected. Once it has returned true, it will keep returning true
    994   * until ReflowStarted is called. In all cases where this returns true,
    995   * the passed-in frame (which should be the frame whose reflow will be
    996   * interrupted if true is returned) will be passed to
    997   * PresShell::FrameNeedsToContinueReflow.
    998   */
    999  bool CheckForInterrupt(nsIFrame* aFrame);
   1000  /**
   1001   * Returns true if CheckForInterrupt has returned true since the last
   1002   * ReflowStarted call. Cannot itself trigger an interrupt check.
   1003   */
   1004  bool HasPendingInterrupt() const { return mHasPendingInterrupt; }
   1005  /**
   1006   * Sets a flag that will trip a reflow interrupt. This only bypasses the
   1007   * interrupt timeout and the pending event check; other checks such as whether
   1008   * interrupts are enabled and the interrupt check skipping still take effect.
   1009   */
   1010  void SetPendingInterruptFromTest() { mPendingInterruptFromTest = true; }
   1011 
   1012  /**
   1013   * If we have a presshell, and if the given content's current
   1014   * document is the same as our presshell's document, return the
   1015   * content's primary frame.  Otherwise, return null.  Only use this
   1016   * if you care about which presshell the primary frame is in.
   1017   */
   1018  nsIFrame* GetPrimaryFrameFor(nsIContent* aContent);
   1019 
   1020  virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   1021  virtual size_t SizeOfIncludingThis(
   1022      mozilla::MallocSizeOf aMallocSizeOf) const {
   1023    return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   1024  }
   1025 
   1026  /**
   1027   * We are a root content document in process if: we are not a resource doc, we
   1028   * are not chrome, and we either have no parent in the current process or our
   1029   * parent is chrome.
   1030   */
   1031  bool IsRootContentDocumentInProcess() const;
   1032 
   1033  /**
   1034   * We are a root content document cross process if: we are not a resource doc,
   1035   * we are not chrome, and we either have no parent in any process or our
   1036   * parent is chrome.
   1037   */
   1038  bool IsRootContentDocumentCrossProcess() const;
   1039 
   1040  bool HadNonBlankPaint() const { return mHadNonBlankPaint; }
   1041  bool HadFirstContentfulPaint() const { return mHadFirstContentfulPaint; }
   1042  bool HasStoppedGeneratingLCP() const;
   1043  void NotifyNonBlankPaint();
   1044  void NotifyContentfulPaint();
   1045  void NotifyPaintStatusReset();
   1046 
   1047  bool HasEverBuiltInvisibleText() const { return mHasEverBuiltInvisibleText; }
   1048  void SetBuiltInvisibleText() { mHasEverBuiltInvisibleText = true; }
   1049 
   1050  bool HasWarnedAboutTooLargeDashedOrDottedRadius() const {
   1051    return mHasWarnedAboutTooLargeDashedOrDottedRadius;
   1052  }
   1053 
   1054  void SetHasWarnedAboutTooLargeDashedOrDottedRadius() {
   1055    mHasWarnedAboutTooLargeDashedOrDottedRadius = true;
   1056  }
   1057 
   1058  void RegisterContainerQueryFrame(nsIFrame* aFrame);
   1059  void UnregisterContainerQueryFrame(nsIFrame* aFrame);
   1060  bool HasContainerQueryFrames() const {
   1061    return !mContainerQueryFrames.IsEmpty();
   1062  }
   1063 
   1064  void FinishedContainerQueryUpdate();
   1065 
   1066  void UpdateContainerQueryStylesAndAnchorPosLayout();
   1067 
   1068  mozilla::intl::Bidi& BidiEngine();
   1069 
   1070  gfxFontFeatureValueSet* GetFontFeatureValuesLookup() const {
   1071    return mFontFeatureValuesLookup;
   1072  }
   1073 
   1074  mozilla::gfx::FontPaletteValueSet* GetFontPaletteValueSet() const {
   1075    return mFontPaletteValueSet;
   1076  }
   1077 
   1078  bool NeedsToUpdateHiddenByContentVisibilityForAnimations() const {
   1079    return mNeedsToUpdateHiddenByContentVisibilityForAnimations;
   1080  }
   1081  void SetNeedsToUpdateHiddenByContentVisibilityForAnimations() {
   1082    mNeedsToUpdateHiddenByContentVisibilityForAnimations = true;
   1083  }
   1084  void UpdateHiddenByContentVisibilityForAnimationsIfNeeded() {
   1085    if (mNeedsToUpdateHiddenByContentVisibilityForAnimations) {
   1086      DoUpdateHiddenByContentVisibilityForAnimations();
   1087    }
   1088  }
   1089 
   1090  // Return the cached value of the about:config pref
   1091  // 'layout.abspos.fragmentainer-aware-positioning.enabled'.
   1092  //
   1093  // Note: Layout code should use this helper rather than the actual "live" pref
   1094  // value. This ensures a given frame tree handles abspos fragmentation
   1095  // consistently even if the actual pref value changes.
   1096  bool FragmentainerAwarePositioningEnabled() const {
   1097    return mFragmentainerAwarePositioningEnabled;
   1098  }
   1099 
   1100 protected:
   1101  void DoUpdateHiddenByContentVisibilityForAnimations();
   1102  friend class nsRunnableMethod<nsPresContext>;
   1103  void ThemeChangedInternal();
   1104  void RefreshSystemMetrics();
   1105 
   1106  // Update device context's resolution from the widget
   1107  void UIResolutionChangedInternal();
   1108 
   1109  void SetImgAnimations(nsIContent* aParent, uint16_t aMode);
   1110  void SetSMILAnimations(mozilla::dom::Document* aDoc, uint16_t aNewMode,
   1111                         uint16_t aOldMode);
   1112 
   1113  static void PreferenceChanged(const char* aPrefName, void* aSelf);
   1114  void PreferenceChanged(const char* aPrefName);
   1115 
   1116  void GetUserPreferences();
   1117 
   1118  void UpdateCharSet(NotNull<const Encoding*> aCharSet);
   1119 
   1120  void DoForceReflowForFontInfoUpdateFromStyle();
   1121 
   1122 public:
   1123  // Used by the PresShell to force a reflow when some aspect of font info
   1124  // has been updated, potentially affecting font selection and layout.
   1125  void ForceReflowForFontInfoUpdate(bool aNeedsReframe);
   1126  void ForceReflowForFontInfoUpdateFromStyle();
   1127 
   1128  void InvalidatePaintedLayers();
   1129 
   1130  uint32_t GetNextFrameRateMultiplier() const {
   1131    return mNextFrameRateMultiplier;
   1132  }
   1133 
   1134  void DidUseFrameRateMultiplier() {
   1135    // This heuristic is used to reduce frame rate between fcp and the end of
   1136    // the page load.
   1137    if (mNextFrameRateMultiplier < 8) {
   1138      ++mNextFrameRateMultiplier;
   1139    }
   1140  }
   1141 
   1142  mozilla::TimeStamp GetMarkPaintTimingStart() const {
   1143    return mMarkPaintTimingStart;
   1144  }
   1145 
   1146  // Are we using normalized ruby-positioning metrics? This will fetch and
   1147  // cache the pref if not already initialized.
   1148  bool NormalizeRubyMetrics();
   1149 
   1150  // Get the scaling factor to apply to em-normalized font ascent/descent. This
   1151  // should only be used if NormalizeRubyMetrics() has returned true, otherwise
   1152  // its return value may be meaningless.
   1153  float RubyPositioningFactor() const {
   1154    MOZ_ASSERT(mRubyPositioningFactor > 0.0f);
   1155    return mRubyPositioningFactor;
   1156  }
   1157 
   1158 protected:
   1159  // May be called multiple times (unlink, destructor)
   1160  void Destroy();
   1161 
   1162  void AppUnitsPerDevPixelChanged();
   1163 
   1164  bool HavePendingInputEvent();
   1165 
   1166  // Creates a one-shot timer with the given aCallback & aDelay.
   1167  // Returns a refcounted pointer to the timer (or nullptr on failure).
   1168  already_AddRefed<nsITimer> CreateTimer(nsTimerCallbackFunc aCallback,
   1169                                         const nsACString& aName,
   1170                                         uint32_t aDelay);
   1171 
   1172  struct TransactionInvalidations {
   1173    TransactionId mTransactionId;
   1174    nsTArray<nsRect> mInvalidations;
   1175    bool mIsWaitingForPreviousTransaction = false;
   1176  };
   1177  TransactionInvalidations* GetInvalidations(TransactionId aTransactionId);
   1178 
   1179  // This should be called only when we update mVisibleArea or
   1180  // mDynamicToolbarMaxHeight or `app units per device pixels` changes.
   1181  void AdjustSizeForViewportUnits();
   1182 
   1183  // Call in response to prefs changes that might affect what fonts should be
   1184  // visibile to CSS. Returns whether the current visibility value actually
   1185  // changed (in which case content should be reflowed).
   1186  bool UpdateFontVisibility();
   1187 
   1188  // IMPORTANT: The ownership implicit in the following member variables
   1189  // has been explicitly checked.  If you add any members to this class,
   1190  // please make the ownership explicit (pinkerton, scc).
   1191 
   1192  // the PresShell owns a strong reference to the nsPresContext, and is
   1193  // responsible for nulling this pointer before it is destroyed
   1194  mozilla::PresShell* MOZ_NON_OWNING_REF mPresShell;  // [WEAK]
   1195  RefPtr<mozilla::dom::Document> mDocument;
   1196  RefPtr<nsDeviceContext> mDeviceContext;  // [STRONG] could be weak, but
   1197                                           // better safe than sorry.
   1198                                           // Cannot reintroduce cycles
   1199                                           // since there is no dependency
   1200                                           // from gfx back to layout.
   1201  RefPtr<nsFontCache> mFontCache;
   1202  RefPtr<mozilla::EventStateManager> mEventManager;
   1203  RefPtr<nsRefreshDriver> mRefreshDriver;
   1204  RefPtr<mozilla::AnimationEventDispatcher> mAnimationEventDispatcher;
   1205  RefPtr<mozilla::EffectCompositor> mEffectCompositor;
   1206  mozilla::UniquePtr<nsTransitionManager> mTransitionManager;
   1207  mozilla::UniquePtr<nsAnimationManager> mAnimationManager;
   1208  mozilla::UniquePtr<mozilla::TimelineManager> mTimelineManager;
   1209  mozilla::UniquePtr<mozilla::RestyleManager> mRestyleManager;
   1210  RefPtr<mozilla::CounterStyleManager> mCounterStyleManager;
   1211  const nsStaticAtom* mMedium;
   1212  RefPtr<gfxFontFeatureValueSet> mFontFeatureValuesLookup;
   1213  RefPtr<mozilla::gfx::FontPaletteValueSet> mFontPaletteValueSet;
   1214 
   1215  mozilla::UniquePtr<mozilla::gfx::PaletteCache> mFontPaletteCache;
   1216 
   1217  // TODO(emilio): Maybe lazily create and put under a UniquePtr if this grows a
   1218  // lot?
   1219  MediaEmulationData mMediaEmulationData;
   1220 
   1221  float mTextZoom;  // Text zoom, defaults to 1.0
   1222  float mFullZoom;  // Page zoom, defaults to 1.0
   1223 
   1224  gfxSize mLastFontInflationScreenSize;
   1225 
   1226  int32_t mCurAppUnitsPerDevPixel;
   1227  int32_t mAutoQualityMinFontSizePixelsPref;
   1228 
   1229  float mRubyPositioningFactor = -1.0f;  // negative indicates uninitialized
   1230 
   1231  nsCOMPtr<nsITheme> mTheme;
   1232  nsCOMPtr<nsIPrintSettings> mPrintSettings;
   1233 
   1234  mozilla::UniquePtr<mozilla::intl::Bidi> mBidiEngine;
   1235 
   1236  AutoTArray<TransactionInvalidations, 4> mTransactions;
   1237 
   1238  // text performance metrics
   1239  mozilla::UniquePtr<gfxTextPerfMetrics> mTextPerf;
   1240 
   1241  mozilla::UniquePtr<gfxMissingFontRecorder> mMissingFonts;
   1242 
   1243  nsRect mVisibleArea;
   1244  // This value is used to resolve viewport units.
   1245  // On mobile this size is including the dynamic toolbar maximum height below.
   1246  // On desktops this size is pretty much the same as |mVisibleArea|.
   1247  nsSize mSizeForViewportUnits;
   1248  // The maximum height of the dynamic toolbar on mobile.
   1249  mozilla::ScreenIntCoord mDynamicToolbarMaxHeight;
   1250  mozilla::ScreenIntCoord mDynamicToolbarHeight;
   1251  // Safe area insets support
   1252  mozilla::LayoutDeviceIntMargin mSafeAreaInsets;
   1253  nsSize mPageSize;
   1254 
   1255  // The computed page margins from the print settings.
   1256  //
   1257  // This margin will be used for each page in the current print operation, by
   1258  // default (i.e. unless overridden by @page rules).
   1259  //
   1260  // FIXME(emilio): Maybe we could let a global @page rule do that, though it's
   1261  // sketchy at best, see https://github.com/w3c/csswg-drafts/issues/5437 for
   1262  // discussion.
   1263  nsMargin mDefaultPageMargin;
   1264  float mPageScale;
   1265  float mPPScale;
   1266 
   1267  // This is a non-owning pointer. May be null. If non-null, it's guaranteed to
   1268  // be pointing to an element that's still alive, because we'll reset it in
   1269  // UpdateViewportScrollStylesOverride() as part of the cleanup code when
   1270  // this element is removed from the document. (For <body> and the root
   1271  // element, this call happens in nsCSSFrameConstructor::ContentRemoved(). For
   1272  // fullscreen elements, it happens in the fullscreen-specific cleanup invoked
   1273  // by Element::UnbindFromTree().)
   1274  mozilla::dom::Element* MOZ_NON_OWNING_REF mViewportScrollOverrideElement;
   1275 
   1276  // Counters for tests and tools that want to detect frame construction
   1277  // or reflow.
   1278  uint64_t mElementsRestyled;
   1279  uint64_t mFramesConstructed;
   1280  uint64_t mFramesReflowed;
   1281  uint64_t mAnimationTriggeredRestyles;
   1282 
   1283  mozilla::TimeStamp mReflowStartTime;
   1284 
   1285  // Defined in https://w3c.github.io/paint-timing/#mark-paint-timing step 2.
   1286  mozilla::TimeStamp mMarkPaintTimingStart;
   1287 
   1288  Maybe<TransactionId> mFirstContentfulPaintTransactionId;
   1289 
   1290  mozilla::UniquePtr<mozilla::MediaFeatureChange>
   1291      mPendingMediaFeatureValuesChange;
   1292 
   1293  // Time of various first interaction types, used to report time from
   1294  // first paint of the top level content pres shell to first interaction.
   1295  mozilla::TimeStamp mFirstNonBlankPaintTime;
   1296  mozilla::TimeStamp mFirstClickTime;
   1297  mozilla::TimeStamp mFirstKeyTime;
   1298  mozilla::TimeStamp mFirstMouseMoveTime;
   1299  mozilla::TimeStamp mFirstScrollTime;
   1300 
   1301  // incremented each time the root scroller scrolls, helpful to determine if
   1302  // it has scrolled between the start and end of some deferred work (such as a
   1303  // navigation intercept).
   1304  uint32_t mLastScrollGeneration;
   1305 
   1306  // last time we did a full style flush
   1307  mozilla::TimeStamp mLastStyleUpdateForAllAnimations;
   1308 
   1309  uint32_t mInterruptChecksToSkip;
   1310 
   1311  // During page load we use slower frame rate.
   1312  uint32_t mNextFrameRateMultiplier;
   1313 
   1314  uint32_t mMeasuredTicksSinceLoading;
   1315 
   1316  nsTArray<RefPtr<mozilla::ManagedPostRefreshObserver>>
   1317      mManagedPostRefreshObservers;
   1318 
   1319  // If we block the use of a font-family that is explicitly requested,
   1320  // due to font visibility settings, we log a message to the web console;
   1321  // this hash-set keeps track of names we've logged for this context, so
   1322  // that we can avoid repeatedly reporting the same font.
   1323  nsTHashSet<nsCString> mBlockedFonts;
   1324 
   1325  // The set of container query boxes currently in the document, sorted by
   1326  // depth.
   1327  mozilla::DepthOrderedFrameList mContainerQueryFrames;
   1328  // The set of container query elements currently in the document that have
   1329  // been updated so far. This is necessary to avoid reentering on container
   1330  // query style changes which cause us to do frame reconstruction.
   1331  nsTHashSet<nsIContent*> mUpdatedContainerQueryContents;
   1332 
   1333  ScrollStyles mViewportScrollStyles;
   1334 
   1335  uint16_t mImageAnimationMode;
   1336  uint16_t mImageAnimationModePref;
   1337 
   1338  nsPresContextType mType;
   1339 
   1340 public:
   1341  // The following are public member variables so that we can use them
   1342  // with mozilla::AutoToggle or mozilla::AutoRestore.
   1343 
   1344  // Should we disable font size inflation because we're inside of
   1345  // shrink-wrapping calculations on an inflation container?
   1346  bool mInflationDisabledForShrinkWrap;
   1347 
   1348 protected:
   1349  static constexpr size_t kThemeChangeKindBits = 2;
   1350  static_assert(unsigned(mozilla::widget::ThemeChangeKind::AllBits) <=
   1351                    (1u << kThemeChangeKindBits) - 1,
   1352                "theme change kind doesn't fit");
   1353 
   1354  unsigned mInteractionTimeEnabled : 1;
   1355  unsigned mHasPendingInterrupt : 1;
   1356  unsigned mHasEverBuiltInvisibleText : 1;
   1357  unsigned mPendingInterruptFromTest : 1;
   1358  unsigned mInterruptsEnabled : 1;
   1359  unsigned mDrawImageBackground : 1;
   1360  unsigned mDrawColorBackground : 1;
   1361  unsigned mNeverAnimate : 1;
   1362  unsigned mPaginated : 1;
   1363  unsigned mCanPaginatedScroll : 1;
   1364  unsigned mDoScaledTwips : 1;
   1365  unsigned mIsRootPaginatedDocument : 1;
   1366  unsigned mPendingThemeChanged : 1;
   1367  // widget::ThemeChangeKind
   1368  unsigned mPendingThemeChangeKind : kThemeChangeKindBits;
   1369  unsigned mPendingUIResolutionChanged : 1;
   1370  unsigned mPendingFontInfoUpdateReflowFromStyle : 1;
   1371 
   1372  // Are we currently drawing an SVG glyph?
   1373  unsigned mIsGlyph : 1;
   1374 
   1375  // Is the current mCounterStyleManager valid?
   1376  unsigned mCounterStylesDirty : 1;
   1377 
   1378  // Is the current mFontFeatureValuesLookup valid?
   1379  unsigned mFontFeatureValuesDirty : 1;
   1380 
   1381  // Is the current mFontFeatureValueSet valid?
   1382  unsigned mFontPaletteValuesDirty : 1;
   1383 
   1384  unsigned mIsVisual : 1;
   1385 
   1386  // Are we in the RDM pane?
   1387  unsigned mInRDMPane : 1;
   1388 
   1389  unsigned mHasWarnedAboutTooLargeDashedOrDottedRadius : 1;
   1390 
   1391  // Have we added quirk.css to the style set?
   1392  unsigned mQuirkSheetAdded : 1;
   1393 
   1394  // Has NotifyNonBlankPaint been called on this PresContext?
   1395  unsigned mHadNonBlankPaint : 1;
   1396  // Has NotifyContentfulPaint been called on this PresContext?
   1397  unsigned mHadFirstContentfulPaint : 1;
   1398  // True when a contentful paint has happened and this paint doesn't
   1399  // come from the regular tick process. Usually this means a
   1400  // contentful paint was triggered manually.
   1401  unsigned mHadNonTickContentfulPaint : 1;
   1402 
   1403  // Has NotifyDidPaintForSubtree been called for a contentful paint?
   1404  unsigned mHadContentfulPaintComposite : 1;
   1405 
   1406  // Whether we might need to update c-v state for animations.
   1407  unsigned mNeedsToUpdateHiddenByContentVisibilityForAnimations : 1;
   1408 
   1409  unsigned mUserInputEventsAllowed : 1;
   1410 
   1411  // Cached value of the about:config pref
   1412  // 'layout.abspos.fragmentainer-aware-positioning.enabled'
   1413  // from when this nsPresContext was initialized.
   1414  bool mFragmentainerAwarePositioningEnabled : 1 = false;
   1415 
   1416 #ifdef DEBUG
   1417  unsigned mInitialized : 1;
   1418 #endif
   1419 
   1420  // FIXME(emilio): These would be better packed on top of the bitfields, but
   1421  // that breaks bindgen in win32.
   1422  FontVisibility mFontVisibility = FontVisibility::Unknown;
   1423  mozilla::dom::PrefersColorSchemeOverride mOverriddenOrEmbedderColorScheme;
   1424  mozilla::StyleForcedColors mForcedColors;
   1425 
   1426 protected:
   1427  virtual ~nsPresContext();
   1428 
   1429  void LastRelease();
   1430 
   1431  void EnsureTheme();
   1432 
   1433 #ifdef DEBUG
   1434 private:
   1435  friend struct nsAutoLayoutPhase;
   1436  mozilla::EnumeratedArray<nsLayoutPhase, uint32_t,
   1437                           size_t(nsLayoutPhase::COUNT)>
   1438      mLayoutPhaseCount;
   1439 
   1440 public:
   1441  uint32_t LayoutPhaseCount(nsLayoutPhase aPhase) {
   1442    return mLayoutPhaseCount[aPhase];
   1443  }
   1444 #endif
   1445 };
   1446 
   1447 class nsRootPresContext final : public nsPresContext {
   1448 public:
   1449  nsRootPresContext(mozilla::dom::Document* aDocument, nsPresContextType aType);
   1450  virtual bool IsRoot() const override { return true; }
   1451 
   1452  /**
   1453   * Add a runnable that will get called before the next paint. They will get
   1454   * run eventually even if painting doesn't happen. They might run well before
   1455   * painting happens.
   1456   */
   1457  void AddWillPaintObserver(nsIRunnable* aRunnable);
   1458 
   1459  /**
   1460   * Run all runnables that need to get called before the next paint.
   1461   */
   1462  void FlushWillPaintObservers();
   1463 
   1464  virtual size_t SizeOfExcludingThis(
   1465      mozilla::MallocSizeOf aMallocSizeOf) const override;
   1466 
   1467 protected:
   1468  class RunWillPaintObservers : public mozilla::Runnable {
   1469   public:
   1470    explicit RunWillPaintObservers(nsRootPresContext* aPresContext)
   1471        : Runnable("nsPresContextType::RunWillPaintObservers"),
   1472          mPresContext(aPresContext) {}
   1473    void Revoke() { mPresContext = nullptr; }
   1474    NS_IMETHOD Run() override {
   1475      if (mPresContext) {
   1476        mPresContext->FlushWillPaintObservers();
   1477      }
   1478      return NS_OK;
   1479    }
   1480    // The lifetime of this reference is handled by an nsRevocableEventPtr
   1481    nsRootPresContext* MOZ_NON_OWNING_REF mPresContext;
   1482  };
   1483 
   1484  friend class nsPresContext;
   1485 
   1486  nsTArray<nsCOMPtr<nsIRunnable>> mWillPaintObservers;
   1487  nsRevocableEventPtr<RunWillPaintObservers> mWillPaintFallbackEvent;
   1488 };
   1489 
   1490 #ifdef MOZ_REFLOW_PERF
   1491 
   1492 #  define DO_GLOBAL_REFLOW_COUNT(_name) \
   1493    aPresContext->CountReflows((_name), (nsIFrame*)this);
   1494 #else
   1495 #  define DO_GLOBAL_REFLOW_COUNT(_name)
   1496 #endif  // MOZ_REFLOW_PERF
   1497 
   1498 #endif /* nsPresContext_h___ */