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