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