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/Attributes.h"
13 #include "mozilla/MediaFeatureChange.h"
14 #include "mozilla/NotNull.h"
15 #include "mozilla/UniquePtr.h"
16 #include "mozilla/WeakPtr.h"
17 #include "nsColor.h"
18 #include "nsCoord.h"
19 #include "nsCOMPtr.h"
20 #include "nsIPresShell.h"
21 #include "nsIPresShellInlines.h"
22 #include "nsRect.h"
23 #include "nsStringFwd.h"
24 #include "nsFont.h"
25 #include "gfxFontConstants.h"
26 #include "nsAtom.h"
27 #include "nsITimer.h"
28 #include "nsCRT.h"
29 #include "nsIWidgetListener.h"
30 #include "nsLanguageAtomService.h"
31 #include "nsGkAtoms.h"
32 #include "nsCycleCollectionParticipant.h"
33 #include "nsChangeHint.h"
34 #include <algorithm>
35 #include "gfxTypes.h"
36 #include "gfxRect.h"
37 #include "nsTArray.h"
38 #include "nsAutoPtr.h"
39 #include "mozilla/MemoryReporting.h"
40 #include "mozilla/TimeStamp.h"
41 #include "mozilla/AppUnits.h"
42 #include "prclist.h"
43 #include "nsThreadUtils.h"
44 #include "ScrollbarStyles.h"
45 #include "nsIMessageManager.h"
46 #include "mozilla/RestyleLogging.h"
47 #include "Units.h"
48 #include "prenv.h"
49 #include "mozilla/StaticPresData.h"
50 #include "mozilla/StyleBackendType.h"
51 
52 class nsBidi;
53 class nsIPrintSettings;
54 class nsDocShell;
55 class nsIDocShell;
56 class nsIDocument;
57 class nsITheme;
58 class nsIContent;
59 class nsIFrame;
60 class nsFrameManager;
61 class nsILinkHandler;
62 class nsAtom;
63 class nsIRunnable;
64 class gfxFontFeatureValueSet;
65 class gfxUserFontEntry;
66 class gfxUserFontSet;
67 class gfxTextPerfMetrics;
68 class nsCSSFontFeatureValuesRule;
69 class nsPluginFrame;
70 class nsTransitionManager;
71 class nsAnimationManager;
72 class nsRefreshDriver;
73 class nsIWidget;
74 class nsDeviceContext;
75 class gfxMissingFontRecorder;
76 
77 namespace mozilla {
78 class AnimationEventDispatcher;
79 class EffectCompositor;
80 class Encoding;
81 class EventStateManager;
82 class CounterStyleManager;
83 class RestyleManager;
84 namespace layers {
85 class ContainerLayer;
86 class LayerManager;
87 }  // namespace layers
88 namespace dom {
89 class Element;
90 }  // namespace dom
91 }  // namespace mozilla
92 
93 // supported values for cached bool types
94 enum nsPresContext_CachedBoolPrefType {
95   kPresContext_UseDocumentFonts = 1,
96   kPresContext_UnderlineLinks
97 };
98 
99 // supported values for cached integer pref types
100 enum nsPresContext_CachedIntPrefType {
101   kPresContext_ScrollbarSide = 1,
102   kPresContext_BidiDirection
103 };
104 
105 // IDs for the default variable and fixed fonts (not to be changed, see
106 // nsFont.h) To be used for Get/SetDefaultFont(). The other IDs in nsFont.h are
107 // also supported.
108 const uint8_t kPresContext_DefaultVariableFont_ID =
109     0x00;  // kGenericFont_moz_variable
110 const uint8_t kPresContext_DefaultFixedFont_ID =
111     0x01;  // kGenericFont_moz_fixed
112 
113 #ifdef DEBUG
114 struct nsAutoLayoutPhase;
115 
116 enum nsLayoutPhase {
117   eLayoutPhase_Paint,
118   eLayoutPhase_DisplayListBuilding,  // sometimes a subset of the paint phase
119   eLayoutPhase_Reflow,
120   eLayoutPhase_FrameC,
121   eLayoutPhase_COUNT
122 };
123 #endif
124 
125 /* Used by nsPresContext::HasAuthorSpecifiedRules */
126 #define NS_AUTHOR_SPECIFIED_BACKGROUND (1 << 0)
127 #define NS_AUTHOR_SPECIFIED_BORDER (1 << 1)
128 #define NS_AUTHOR_SPECIFIED_PADDING (1 << 2)
129 
130 class nsRootPresContext;
131 
132 // An interface for presentation contexts. Presentation contexts are
133 // objects that provide an outer context for a presentation shell.
134 
135 class nsPresContext : public nsISupports,
136                       public mozilla::SupportsWeakPtr<nsPresContext> {
137  public:
138   using Encoding = mozilla::Encoding;
139   template <typename T>
140   using NotNull = mozilla::NotNull<T>;
141   typedef mozilla::LangGroupFontPrefs LangGroupFontPrefs;
142   typedef mozilla::ScrollbarStyles ScrollbarStyles;
143   typedef mozilla::StaticPresData StaticPresData;
144 
145   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
146   NS_DECL_CYCLE_COLLECTION_CLASS(nsPresContext)
147   MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsPresContext)
148 
149   enum nsPresContextType {
150     eContext_Galley,        // unpaginated screen presentation
151     eContext_PrintPreview,  // paginated screen presentation
152     eContext_Print,         // paginated printer presentation
153     eContext_PageLayout     // paginated & editable.
154   };
155 
156   nsPresContext(nsIDocument* aDocument, nsPresContextType aType);
157 
158   /**
159    * Initialize the presentation context from a particular device.
160    */
161   nsresult Init(nsDeviceContext* aDeviceContext);
162 
163   /**
164    * Set and detach presentation shell that this context is bound to.
165    * A presentation context may only be bound to a single shell.
166    */
167   void AttachShell(nsIPresShell* aShell,
168                    mozilla::StyleBackendType aBackendType);
169   void DetachShell();
170 
Type()171   nsPresContextType Type() const { return mType; }
172 
173   /**
174    * Get the PresentationShell that this context is bound to.
175    */
PresShell()176   nsIPresShell* PresShell() const {
177     NS_ASSERTION(mShell, "Null pres shell");
178     return mShell;
179   }
180 
GetPresShell()181   nsIPresShell* GetPresShell() const { return mShell; }
182 
183   void DispatchCharSetChange(NotNull<const Encoding*> aCharSet);
184 
185   /**
186    * Returns the parent prescontext for this one. Returns null if this is a
187    * root.
188    */
189   nsPresContext* GetParentPresContext();
190 
191   /**
192    * Returns the prescontext of the toplevel content document that contains
193    * this presentation, or null if there isn't one.
194    */
195   nsPresContext* GetToplevelContentDocumentPresContext();
196 
197   /**
198    * Returns the nearest widget for the root frame of this.
199    *
200    * @param aOffset     If non-null the offset from the origin of the root
201    *                    frame's view to the widget's origin (usually positive)
202    *                    expressed in appunits of this will be returned in
203    *                    aOffset.
204    */
205   nsIWidget* GetNearestWidget(nsPoint* aOffset = nullptr);
206 
207   /**
208    * Returns the root widget for this.
209    * Note that the widget is a mediater with IME.
210    */
211   nsIWidget* GetRootWidget();
212 
213   /**
214    * Return the presentation context for the root of the view manager
215    * hierarchy that contains this presentation context, or nullptr if it can't
216    * be found (e.g. it's detached).
217    */
218   nsRootPresContext* GetRootPresContext();
219 
IsRoot()220   virtual bool IsRoot() { return false; }
221 
Document()222   nsIDocument* Document() const {
223     NS_ASSERTION(
224         !mShell || !mShell->GetDocument() || mShell->GetDocument() == mDocument,
225         "nsPresContext doesn't have the same document as nsPresShell!");
226     return mDocument;
227   }
228 
StyleSet()229   mozilla::StyleSetHandle StyleSet() const {
230     return GetPresShell()->StyleSet();
231   }
232 
HasPendingMediaQueryUpdates()233   bool HasPendingMediaQueryUpdates() const {
234     return !!mPendingMediaFeatureValuesChange;
235   }
236 
FrameConstructor()237   nsCSSFrameConstructor* FrameConstructor() {
238     return PresShell()->FrameConstructor();
239   }
240 
AnimationEventDispatcher()241   mozilla::AnimationEventDispatcher* AnimationEventDispatcher() {
242     return mAnimationEventDispatcher;
243   }
244 
EffectCompositor()245   mozilla::EffectCompositor* EffectCompositor() { return mEffectCompositor; }
TransitionManager()246   nsTransitionManager* TransitionManager() { return mTransitionManager; }
AnimationManager()247   nsAnimationManager* AnimationManager() { return mAnimationManager; }
AnimationManager()248   const nsAnimationManager* AnimationManager() const {
249     return mAnimationManager;
250   }
251 
RefreshDriver()252   nsRefreshDriver* RefreshDriver() { return mRefreshDriver; }
253 
RestyleManager()254   mozilla::RestyleManager* RestyleManager() {
255     MOZ_ASSERT(mRestyleManager);
256     return mRestyleManager;
257   }
258 
CounterStyleManager()259   mozilla::CounterStyleManager* CounterStyleManager() const {
260     return mCounterStyleManager;
261   }
262 
263   /**
264    * Rebuilds all style data by throwing out the old rule tree and
265    * building a new one, and additionally applying aExtraHint (which
266    * must not contain nsChangeHint_ReconstructFrame) to the root frame.
267    * For aRestyleHint, see RestyleManager::RebuildAllStyleData.
268    * Also rebuild the user font set and counter style manager.
269    */
270   void RebuildAllStyleData(nsChangeHint aExtraHint, nsRestyleHint aRestyleHint);
271   /**
272    * Just like RebuildAllStyleData, except (1) asynchronous and (2) it
273    * doesn't rebuild the user font set.
274    */
275   void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint,
276                                     nsRestyleHint aRestyleHint);
277 
278   /**
279    * Handle changes in the values of media features (used in media
280    * queries).
281    *
282    * There are three sensible values to use for aRestyleHint:
283    *  * nsRestyleHint(0) to rebuild style data, with rerunning of
284    *    selector matching, only if media features have changed
285    *  * eRestyle_ForceDescendants to force rebuilding of style data (but
286    *    still only rerun selector matching if media query results have
287    *    changed).  (RebuildAllStyleData always adds
288    *    eRestyle_ForceDescendants internally, so here we're only using
289    *    it to distinguish from nsRestyleHint(0) whether we need to call
290    *    RebuildAllStyleData at all.)
291    *  * eRestyle_Subtree to force rebuilding of style data with
292    *    rerunning of selector matching
293    *
294    * For aChangeHint, see RestyleManager::RebuildAllStyleData.  (Passing
295    * a nonzero aChangeHint forces rebuilding style data even if
296    * nsRestyleHint(0) is passed.)
297    */
MediaFeatureValuesChanged(const mozilla::MediaFeatureChange & aChange)298   void MediaFeatureValuesChanged(const mozilla::MediaFeatureChange& aChange) {
299     if (mShell) {
300       mShell->EnsureStyleFlush();
301     }
302 
303     if (!mPendingMediaFeatureValuesChange) {
304       mPendingMediaFeatureValuesChange.emplace(aChange);
305       return;
306     }
307 
308     *mPendingMediaFeatureValuesChange |= aChange;
309   }
310 
311   void FlushPendingMediaFeatureValuesChanged();
312 
313   /**
314    * Calls MediaFeatureValuesChanged for this pres context and all descendant
315    * subdocuments that have a pres context. This should be used for media
316    * features that must be updated in all subdocuments e.g. display-mode.
317    */
318   void MediaFeatureValuesChangedAllDocuments(
319       const mozilla::MediaFeatureChange&);
320 
321   /**
322    * Updates the size mode on all remote children and recursively notifies this
323    * document and all subdocuments (including remote children) that a media
324    * feature value has changed.
325    */
326   void SizeModeChanged(nsSizeMode aSizeMode);
327 
328   /**
329    * Access compatibility mode for this context.  This is the same as
330    * our document's compatibility mode.
331    */
332   nsCompatibility CompatibilityMode() const;
333 
334   /**
335    * Notify the context that the document's compatibility mode has changed
336    */
337   void CompatibilityModeChanged();
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   nsAtom* Medium() {
349     if (!mIsEmulatingMedia) return mMedium;
350     return mMediaEmulated;
351   }
352 
353   /*
354    * Render the document as if being viewed on a device with the specified
355    * media type.
356    */
357   void EmulateMedium(const nsAString& aMediaType);
358 
359   /*
360    * Restore the viewer's natural medium
361    */
362   void StopEmulatingMedium();
363 
364   /**
365    * Get the default font for the given language and generic font ID.
366    * If aLanguage is nullptr, the document's language is used.
367    *
368    * See the comment in StaticPresData::GetDefaultFont.
369    */
370   const nsFont* GetDefaultFont(uint8_t aFontID, nsAtom* aLanguage,
371                                bool* aNeedsToCache = nullptr) const {
372     nsAtom* lang = aLanguage ? aLanguage : mLanguage.get();
373     const LangGroupFontPrefs* prefs = GetFontPrefsForLang(lang, aNeedsToCache);
374     if (aNeedsToCache && *aNeedsToCache) {
375       return nullptr;
376     }
377     return StaticPresData::Get()->GetDefaultFontHelper(aFontID, lang, prefs);
378   }
379 
380   void ForceCacheLang(nsAtom* aLanguage);
381   void CacheAllLangs();
382 
383   /** Get a cached boolean pref, by its type */
384   // *  - initially created for bugs 31816, 20760, 22963
GetCachedBoolPref(nsPresContext_CachedBoolPrefType aPrefType)385   bool GetCachedBoolPref(nsPresContext_CachedBoolPrefType aPrefType) const {
386     // If called with a constant parameter, the compiler should optimize
387     // this switch statement away.
388     switch (aPrefType) {
389       case kPresContext_UseDocumentFonts:
390         return mUseDocumentFonts;
391       case kPresContext_UnderlineLinks:
392         return mUnderlineLinks;
393       default:
394         NS_ERROR("Invalid arg passed to GetCachedBoolPref");
395     }
396 
397     return false;
398   }
399 
400   /** Get a cached integer pref, by its type */
401   // *  - initially created for bugs 30910, 61883, 74186, 84398
GetCachedIntPref(nsPresContext_CachedIntPrefType aPrefType)402   int32_t GetCachedIntPref(nsPresContext_CachedIntPrefType aPrefType) const {
403     // If called with a constant parameter, the compiler should optimize
404     // this switch statement away.
405     switch (aPrefType) {
406       case kPresContext_ScrollbarSide:
407         return mPrefScrollbarSide;
408       case kPresContext_BidiDirection:
409         return mPrefBidiDirection;
410       default:
411         NS_ERROR("invalid arg passed to GetCachedIntPref");
412     }
413 
414     return false;
415   }
416 
417   /**
418    * Get the default colors
419    */
DefaultColor()420   nscolor DefaultColor() const { return mDefaultColor; }
DefaultBackgroundColor()421   nscolor DefaultBackgroundColor() const { return mBackgroundColor; }
DefaultLinkColor()422   nscolor DefaultLinkColor() const { return mLinkColor; }
DefaultActiveLinkColor()423   nscolor DefaultActiveLinkColor() const { return mActiveLinkColor; }
DefaultVisitedLinkColor()424   nscolor DefaultVisitedLinkColor() const { return mVisitedLinkColor; }
FocusBackgroundColor()425   nscolor FocusBackgroundColor() const { return mFocusBackgroundColor; }
FocusTextColor()426   nscolor FocusTextColor() const { return mFocusTextColor; }
427 
428   /**
429    * Body text color, for use in quirks mode only.
430    */
BodyTextColor()431   nscolor BodyTextColor() const { return mBodyTextColor; }
SetBodyTextColor(nscolor aColor)432   void SetBodyTextColor(nscolor aColor) { mBodyTextColor = aColor; }
433 
GetUseFocusColors()434   bool GetUseFocusColors() const { return mUseFocusColors; }
FocusRingWidth()435   uint8_t FocusRingWidth() const { return mFocusRingWidth; }
GetFocusRingOnAnything()436   bool GetFocusRingOnAnything() const { return mFocusRingOnAnything; }
GetFocusRingStyle()437   uint8_t GetFocusRingStyle() const { return mFocusRingStyle; }
438 
439   void SetContainer(nsIDocShell* aContainer);
440 
441   nsISupports* GetContainerWeak() const;
442 
443   nsIDocShell* GetDocShell() const;
444 
445   // XXX this are going to be replaced with set/get container
SetLinkHandler(nsILinkHandler * aHandler)446   void SetLinkHandler(nsILinkHandler* aHandler) { mLinkHandler = aHandler; }
GetLinkHandler()447   nsILinkHandler* GetLinkHandler() { return mLinkHandler; }
448 
449   /**
450    * Detach this pres context - i.e. cancel relevant timers,
451    * SetLinkHandler(null), SetContainer(null) etc.
452    * Only to be used by the DocumentViewer.
453    */
454   virtual void Detach();
455 
456   /**
457    * Get the visible area associated with this presentation context.
458    * This is the size of the visible area that is used for
459    * presenting the document. The returned value is in the standard
460    * nscoord units (as scaled by the device context).
461    */
GetVisibleArea()462   nsRect GetVisibleArea() const { return mVisibleArea; }
463 
464   /**
465    * Set the currently visible area. The units for r are standard
466    * nscoord units (as scaled by the device context).
467    */
SetVisibleArea(const nsRect & r)468   void SetVisibleArea(const nsRect& r) {
469     if (!r.IsEqualEdges(mVisibleArea)) {
470       mVisibleArea = r;
471       // Visible area does not affect media queries when paginated.
472       if (!IsPaginated()) {
473         MediaFeatureValuesChanged(
474             {mozilla::MediaFeatureChangeReason::ViewportChange});
475       }
476     }
477   }
478 
ShouldFireResizeEvent()479   bool ShouldFireResizeEvent() const {
480     return !mLastResizeEventVisibleArea.IsEqualEdges(mVisibleArea);
481   }
482 
WillFireResizeEvent()483   void WillFireResizeEvent() { mLastResizeEventVisibleArea = mVisibleArea; }
484 
485   /**
486    * Return true if this presentation context is a paginated
487    * context.
488    */
IsPaginated()489   bool IsPaginated() const { return mPaginated; }
490 
491   /**
492    * Sets whether the presentation context can scroll for a paginated
493    * context.
494    */
495   void SetPaginatedScrolling(bool aResult);
496 
497   /**
498    * Return true if this presentation context can scroll for paginated
499    * context.
500    */
HasPaginatedScrolling()501   bool HasPaginatedScrolling() const { return mCanPaginatedScroll; }
502 
503   /**
504    * Get/set the size of a page
505    */
GetPageSize()506   nsSize GetPageSize() { return mPageSize; }
SetPageSize(nsSize aSize)507   void SetPageSize(nsSize aSize) { mPageSize = aSize; }
508 
509   /**
510    * Get/set whether this document should be treated as having real pages
511    * XXX This raises the obvious question of why a document that isn't a page
512    *     is paginated; there isn't a good reason except history
513    */
IsRootPaginatedDocument()514   bool IsRootPaginatedDocument() { return mIsRootPaginatedDocument; }
SetIsRootPaginatedDocument(bool aIsRootPaginatedDocument)515   void SetIsRootPaginatedDocument(bool aIsRootPaginatedDocument) {
516     mIsRootPaginatedDocument = aIsRootPaginatedDocument;
517   }
518 
519   /**
520    * Get/set the print scaling level; used by nsPageFrame to scale up
521    * pages.  Set safe to call before reflow, get guaranteed to be set
522    * properly after reflow.
523    */
524 
GetPageScale()525   float GetPageScale() { return mPageScale; }
SetPageScale(float aScale)526   void SetPageScale(float aScale) { mPageScale = aScale; }
527 
528   /**
529    * Get/set the scaling facor to use when rendering the pages for print
530    * preview. Only safe to get after print preview set up; safe to set anytime.
531    * This is a scaling factor for the display of the print preview.  It
532    * does not affect layout.  It only affects the size of the onscreen pages
533    * in print preview.
534    * XXX Temporary: see http://wiki.mozilla.org/Gecko:PrintPreview
535    */
GetPrintPreviewScale()536   float GetPrintPreviewScale() { return mPPScale; }
SetPrintPreviewScale(float aScale)537   void SetPrintPreviewScale(float aScale) { mPPScale = aScale; }
538 
DeviceContext()539   nsDeviceContext* DeviceContext() const { return mDeviceContext; }
EventStateManager()540   mozilla::EventStateManager* EventStateManager() { return mEventManager; }
GetLanguageFromCharset()541   nsAtom* GetLanguageFromCharset() const { return mLanguage; }
542   already_AddRefed<nsAtom> GetContentLanguage() const;
543 
544   /**
545    * Get/set a text zoom factor that is applied on top of the normal text zoom
546    * set by the front-end/user.
547    */
GetSystemFontScale()548   float GetSystemFontScale() const { return mSystemFontScale; }
SetSystemFontScale(float aFontScale)549   void SetSystemFontScale(float aFontScale) {
550     MOZ_ASSERT(aFontScale > 0.0f, "invalid font scale");
551     if (aFontScale == mSystemFontScale || IsPrintingOrPrintPreview()) {
552       return;
553     }
554 
555     mSystemFontScale = aFontScale;
556     UpdateEffectiveTextZoom();
557   }
558 
559   /**
560    * Get/set the text zoom factor in use.
561    * This value should be used if you're interested in the pure text zoom value
562    * controlled by the front-end, e.g. when transferring zoom levels to a new
563    * document.
564    * Code that wants to use this value for layouting and rendering purposes
565    * should consider using EffectiveTextZoom() instead, so as to take the system
566    * font scale into account as well.
567    */
TextZoom()568   float TextZoom() const { return mTextZoom; }
SetTextZoom(float aZoom)569   void SetTextZoom(float aZoom) {
570     MOZ_ASSERT(aZoom > 0.0f, "invalid zoom factor");
571     if (aZoom == mTextZoom) return;
572 
573     mTextZoom = aZoom;
574     UpdateEffectiveTextZoom();
575   }
576 
577  protected:
578   void UpdateEffectiveTextZoom();
579 
580  public:
581   /**
582    * Corresponds to the product of text zoom and system font scale, limited
583    * by zoom.maxPercent and minPercent.
584    * As the system font scale is automatically set by the PresShell, code that
585    * e.g. wants to transfer zoom levels to a new document should use TextZoom()
586    * instead, which corresponds to the text zoom level that was actually set by
587    * the front-end/user.
588    */
EffectiveTextZoom()589   float EffectiveTextZoom() const { return mEffectiveTextZoom; }
590 
591   /**
592    * Get the minimum font size for the specified language. If aLanguage
593    * is nullptr, then the document's language is used.  This combines
594    * the language-specific global preference with the per-presentation
595    * base minimum font size.
596    */
597   int32_t MinFontSize(nsAtom* aLanguage, bool* aNeedsToCache = nullptr) const {
598     const LangGroupFontPrefs* prefs =
599         GetFontPrefsForLang(aLanguage, aNeedsToCache);
600     if (aNeedsToCache && *aNeedsToCache) {
601       return 0;
602     }
603     return std::max(mBaseMinFontSize, prefs->mMinimumFontSize);
604   }
605 
606   /**
607    * Get the per-presentation base minimum font size.  This size is
608    * independent of the language-specific global preference.
609    */
BaseMinFontSize()610   int32_t BaseMinFontSize() const { return mBaseMinFontSize; }
611 
612   /**
613    * Set the per-presentation base minimum font size.  This size is
614    * independent of the language-specific global preference.
615    */
SetBaseMinFontSize(int32_t aMinFontSize)616   void SetBaseMinFontSize(int32_t aMinFontSize) {
617     if (aMinFontSize == mBaseMinFontSize) {
618       return;
619     }
620 
621     mBaseMinFontSize = aMinFontSize;
622 
623     // Media queries could have changed, since we changed the meaning
624     // of 'em' units in them.
625     MediaFeatureValuesChanged(
626         {eRestyle_ForceDescendants, NS_STYLE_HINT_REFLOW,
627          mozilla::MediaFeatureChangeReason::MinFontSizeChange});
628   }
629 
GetFullZoom()630   float GetFullZoom() { return mFullZoom; }
631   /**
632    * Device full zoom differs from full zoom because it gets the zoom from
633    * the device context, which may be using a different zoom due to rounding
634    * of app units to device pixels.
635    */
636   float GetDeviceFullZoom();
637   void SetFullZoom(float aZoom);
638 
GetOverrideDPPX()639   float GetOverrideDPPX() { return mOverrideDPPX; }
640   void SetOverrideDPPX(float aDPPX);
641 
GetAutoQualityMinFontSize()642   nscoord GetAutoQualityMinFontSize() {
643     return DevPixelsToAppUnits(mAutoQualityMinFontSizePixelsPref);
644   }
645 
646   /**
647    * Return the device's screen size in inches, for font size
648    * inflation.
649    *
650    * If |aChanged| is non-null, then aChanged is filled in with whether
651    * the screen size value has changed since either:
652    *  a. the last time the function was called with non-null aChanged, or
653    *  b. the first time the function was called.
654    */
655   gfxSize ScreenSizeInchesForFontInflation(bool* aChanged = nullptr);
656 
AppUnitsPerCSSPixel()657   static int32_t AppUnitsPerCSSPixel() {
658     return mozilla::AppUnitsPerCSSPixel();
659   }
660   int32_t AppUnitsPerDevPixel() const;
AppUnitsPerCSSInch()661   static int32_t AppUnitsPerCSSInch() { return mozilla::AppUnitsPerCSSInch(); }
662 
CSSPixelsToAppUnits(int32_t aPixels)663   static nscoord CSSPixelsToAppUnits(int32_t aPixels) {
664     return NSToCoordRoundWithClamp(float(aPixels) *
665                                    float(AppUnitsPerCSSPixel()));
666   }
667 
CSSPixelsToAppUnits(float aPixels)668   static nscoord CSSPixelsToAppUnits(float aPixels) {
669     return NSToCoordRoundWithClamp(aPixels * float(AppUnitsPerCSSPixel()));
670   }
671 
AppUnitsToIntCSSPixels(nscoord aAppUnits)672   static int32_t AppUnitsToIntCSSPixels(nscoord aAppUnits) {
673     return NSAppUnitsToIntPixels(aAppUnits, float(AppUnitsPerCSSPixel()));
674   }
675 
AppUnitsToFloatCSSPixels(nscoord aAppUnits)676   static float AppUnitsToFloatCSSPixels(nscoord aAppUnits) {
677     return NSAppUnitsToFloatPixels(aAppUnits, float(AppUnitsPerCSSPixel()));
678   }
679 
AppUnitsToDoubleCSSPixels(nscoord aAppUnits)680   static double AppUnitsToDoubleCSSPixels(nscoord aAppUnits) {
681     return NSAppUnitsToDoublePixels(aAppUnits, double(AppUnitsPerCSSPixel()));
682   }
683 
DevPixelsToAppUnits(int32_t aPixels)684   nscoord DevPixelsToAppUnits(int32_t aPixels) const {
685     return NSIntPixelsToAppUnits(aPixels, AppUnitsPerDevPixel());
686   }
687 
AppUnitsToDevPixels(nscoord aAppUnits)688   int32_t AppUnitsToDevPixels(nscoord aAppUnits) const {
689     return NSAppUnitsToIntPixels(aAppUnits, float(AppUnitsPerDevPixel()));
690   }
691 
AppUnitsToFloatDevPixels(nscoord aAppUnits)692   float AppUnitsToFloatDevPixels(nscoord aAppUnits) {
693     return aAppUnits / float(AppUnitsPerDevPixel());
694   }
695 
CSSPixelsToDevPixels(int32_t aPixels)696   int32_t CSSPixelsToDevPixels(int32_t aPixels) {
697     return AppUnitsToDevPixels(CSSPixelsToAppUnits(aPixels));
698   }
699 
CSSPixelsToDevPixels(float aPixels)700   float CSSPixelsToDevPixels(float aPixels) {
701     return NSAppUnitsToFloatPixels(CSSPixelsToAppUnits(aPixels),
702                                    float(AppUnitsPerDevPixel()));
703   }
704 
DevPixelsToIntCSSPixels(int32_t aPixels)705   int32_t DevPixelsToIntCSSPixels(int32_t aPixels) {
706     return AppUnitsToIntCSSPixels(DevPixelsToAppUnits(aPixels));
707   }
708 
DevPixelsToFloatCSSPixels(int32_t aPixels)709   float DevPixelsToFloatCSSPixels(int32_t aPixels) {
710     return AppUnitsToFloatCSSPixels(DevPixelsToAppUnits(aPixels));
711   }
712 
CSSToDevPixelScale()713   mozilla::CSSToLayoutDeviceScale CSSToDevPixelScale() const {
714     return mozilla::CSSToLayoutDeviceScale(float(AppUnitsPerCSSPixel()) /
715                                            float(AppUnitsPerDevPixel()));
716   }
717 
718   // If there is a remainder, it is rounded to nearest app units.
719   nscoord GfxUnitsToAppUnits(gfxFloat aGfxUnits) const;
720 
721   gfxFloat AppUnitsToGfxUnits(nscoord aAppUnits) const;
722 
AppUnitsToGfxUnits(const nsRect & aAppRect)723   gfxRect AppUnitsToGfxUnits(const nsRect& aAppRect) const {
724     return gfxRect(AppUnitsToGfxUnits(aAppRect.x),
725                    AppUnitsToGfxUnits(aAppRect.y),
726                    AppUnitsToGfxUnits(aAppRect.Width()),
727                    AppUnitsToGfxUnits(aAppRect.Height()));
728   }
729 
CSSTwipsToAppUnits(float aTwips)730   static nscoord CSSTwipsToAppUnits(float aTwips) {
731     return NSToCoordRoundWithClamp(mozilla::AppUnitsPerCSSInch() *
732                                    NS_TWIPS_TO_INCHES(aTwips));
733   }
734 
735   // Margin-specific version, since they often need TwipsToAppUnits
CSSTwipsToAppUnits(const nsIntMargin & marginInTwips)736   static nsMargin CSSTwipsToAppUnits(const nsIntMargin& marginInTwips) {
737     return nsMargin(CSSTwipsToAppUnits(float(marginInTwips.top)),
738                     CSSTwipsToAppUnits(float(marginInTwips.right)),
739                     CSSTwipsToAppUnits(float(marginInTwips.bottom)),
740                     CSSTwipsToAppUnits(float(marginInTwips.left)));
741   }
742 
CSSPointsToAppUnits(float aPoints)743   static nscoord CSSPointsToAppUnits(float aPoints) {
744     return NSToCoordRound(aPoints * mozilla::AppUnitsPerCSSInch() /
745                           POINTS_PER_INCH_FLOAT);
746   }
747 
748   nscoord PhysicalMillimetersToAppUnits(float aMM) const;
749 
RoundAppUnitsToNearestDevPixels(nscoord aAppUnits)750   nscoord RoundAppUnitsToNearestDevPixels(nscoord aAppUnits) const {
751     return DevPixelsToAppUnits(AppUnitsToDevPixels(aAppUnits));
752   }
753 
754   /**
755    * This checks the root element and the HTML BODY, if any, for an "overflow"
756    * property that should be applied to the viewport. If one is found then we
757    * return the element that we took the overflow from (which should then be
758    * treated as "overflow: visible"), and we store the overflow style here.
759    * If the document is in fullscreen, and the fullscreen element is not the
760    * root, the scrollbar of viewport will be suppressed.
761    * @return if scroll was propagated from some content node, the content node
762    *         it was propagated from.
763    */
764   mozilla::dom::Element* UpdateViewportScrollbarStylesOverride();
765 
766   /**
767    * Returns the cached result from the last call to
768    * UpdateViewportScrollbarStylesOverride() -- i.e. return the node
769    * whose scrollbar styles we have propagated to the viewport (or nullptr if
770    * there is no such node).
771    */
GetViewportScrollbarStylesOverrideElement()772   mozilla::dom::Element* GetViewportScrollbarStylesOverrideElement() const {
773     return mViewportScrollbarOverrideElement;
774   }
775 
GetViewportScrollbarStylesOverride()776   const ScrollbarStyles& GetViewportScrollbarStylesOverride() const {
777     return mViewportStyleScrollbar;
778   }
779 
780   /**
781    * Check whether the given element would propagate its scrollbar styles to the
782    * viewport in non-paginated mode.  Must only be called if IsPaginated().
783    */
784   bool ElementWouldPropagateScrollbarStyles(mozilla::dom::Element* aElement);
785 
786   /**
787    * Set and get methods for controlling the background drawing
788    */
GetBackgroundImageDraw()789   bool GetBackgroundImageDraw() const { return mDrawImageBackground; }
SetBackgroundImageDraw(bool aCanDraw)790   void SetBackgroundImageDraw(bool aCanDraw) {
791     mDrawImageBackground = aCanDraw;
792   }
793 
GetBackgroundColorDraw()794   bool GetBackgroundColorDraw() const { return mDrawColorBackground; }
SetBackgroundColorDraw(bool aCanDraw)795   void SetBackgroundColorDraw(bool aCanDraw) {
796     mDrawColorBackground = aCanDraw;
797   }
798 
799   /**
800    *  Check if bidi enabled (set depending on the presence of RTL
801    *  characters or when default directionality is RTL).
802    *  If enabled, we should apply the Unicode Bidi Algorithm
803    *
804    *  @lina 07/12/2000
805    */
806   bool BidiEnabled() const;
807 
808   /**
809    *  Set bidi enabled. This means we should apply the Unicode Bidi Algorithm
810    *
811    *  @lina 07/12/2000
812    */
813   void SetBidiEnabled() const;
814 
815   /**
816    *  Set visual or implicit mode into the pres context.
817    *
818    *  Visual directionality is a presentation method that displays text
819    *  as if it were a uni-directional, according to the primary display
820    *  direction only.
821    *
822    *  Implicit directionality is a presentation method in which the
823    *  direction is determined by the Bidi algorithm according to the
824    *  category of the characters and the category of the adjacent
825    *  characters, and according to their primary direction.
826    *
827    *  @lina 05/02/2000
828    */
SetVisualMode(bool aIsVisual)829   void SetVisualMode(bool aIsVisual) { mIsVisual = aIsVisual; }
830 
831   /**
832    *  Check whether the content should be treated as visual.
833    *
834    *  @lina 05/02/2000
835    */
IsVisualMode()836   bool IsVisualMode() const { return mIsVisual; }
837 
838   enum class InteractionType : uint32_t {
839     eClickInteraction,
840     eKeyInteraction,
841     eMouseMoveInteraction,
842     eScrollInteraction
843   };
844 
845   void RecordInteractionTime(InteractionType aType,
846                              const mozilla::TimeStamp& aTimeStamp);
847 
DisableInteractionTimeRecording()848   void DisableInteractionTimeRecording() { mInteractionTimeEnabled = false; }
849 
850   // Mohamed
851 
852   /**
853    * Set the Bidi options for the presentation context
854    */
855   void SetBidi(uint32_t aBidiOptions);
856 
857   /**
858    * Get the Bidi options for the presentation context
859    * Not inline so consumers of nsPresContext are not forced to
860    * include nsIDocument.
861    */
862   uint32_t GetBidi() const;
863 
864   /**
865    * Render only Selection
866    */
SetIsRenderingOnlySelection(bool aResult)867   void SetIsRenderingOnlySelection(bool aResult) {
868     mIsRenderingOnlySelection = aResult;
869   }
870 
IsRenderingOnlySelection()871   bool IsRenderingOnlySelection() const { return mIsRenderingOnlySelection; }
872 
873   bool IsTopLevelWindowInactive();
874 
875   /*
876    * Obtain a native them for rendering our widgets (both form controls and
877    * html)
878    */
879   nsITheme* GetTheme();
880 
881   /*
882    * Notify the pres context that the theme has changed.  An internal switch
883    * means it's one of our Mozilla themes that changed (e.g., Modern to
884    * Classic). Otherwise, the OS is telling us that the native theme for the
885    * platform has changed.
886    */
887   void ThemeChanged();
888 
889   /*
890    * Notify the pres context that the resolution of the user interface has
891    * changed. This happens if a window is moved between HiDPI and non-HiDPI
892    * displays, so that the ratio of points to device pixels changes.
893    * The notification happens asynchronously.
894    */
895   void UIResolutionChanged();
896 
897   /*
898    * Like UIResolutionChanged() but invalidates values immediately.
899    */
900   void UIResolutionChangedSync();
901 
902   /*
903    * Notify the pres context that a system color has changed
904    */
905   void SysColorChanged();
906 
907   /** Printing methods below should only be used for Medium() == print **/
908   void SetPrintSettings(nsIPrintSettings* aPrintSettings);
909 
GetPrintSettings()910   nsIPrintSettings* GetPrintSettings() { return mPrintSettings; }
911 
912   /* Helper function that ensures that this prescontext is shown in its
913      docshell if it's the most recent prescontext for the docshell.  Returns
914      whether the prescontext is now being shown.
915   */
916   bool EnsureVisible();
917 
918 #ifdef MOZ_REFLOW_PERF
919   void CountReflows(const char* aName, nsIFrame* aFrame);
920 #endif
921 
ConstructedFrame()922   void ConstructedFrame() { ++mFramesConstructed; }
ReflowedFrame()923   void ReflowedFrame() { ++mFramesReflowed; }
924 
FramesConstructedCount()925   uint64_t FramesConstructedCount() { return mFramesConstructed; }
FramesReflowedCount()926   uint64_t FramesReflowedCount() { return mFramesReflowed; }
927 
928   /*
929    * Helper functions for a telemetry scroll probe
930    * for more information see bug 1340904
931    */
SetTelemetryScrollY(nscoord aScrollY)932   void SetTelemetryScrollY(nscoord aScrollY) {
933     nscoord delta = abs(aScrollY - mTelemetryScrollLastY);
934     mTelemetryScrollLastY = aScrollY;
935 
936     mTelemetryScrollTotalY += delta;
937     if (aScrollY > mTelemetryScrollMaxY) {
938       mTelemetryScrollMaxY = aScrollY;
939     }
940   }
TelemetryScrollMaxY()941   nscoord TelemetryScrollMaxY() const { return mTelemetryScrollMaxY; }
TelemetryScrollTotalY()942   nscoord TelemetryScrollTotalY() const { return mTelemetryScrollTotalY; }
943 
GetBorderWidthForKeyword(unsigned int aBorderWidthKeyword)944   static nscoord GetBorderWidthForKeyword(unsigned int aBorderWidthKeyword) {
945     // This table maps border-width enums 'thin', 'medium', 'thick'
946     // to actual nscoord values.
947     static const nscoord kBorderWidths[] = {
948         CSSPixelsToAppUnits(1), CSSPixelsToAppUnits(3), CSSPixelsToAppUnits(5)};
949     MOZ_ASSERT(size_t(aBorderWidthKeyword) <
950                mozilla::ArrayLength(kBorderWidths));
951 
952     return kBorderWidths[aBorderWidthKeyword];
953   }
954 
GetTextPerfMetrics()955   gfxTextPerfMetrics* GetTextPerfMetrics() { return mTextPerf; }
956 
IsDynamic()957   bool IsDynamic() {
958     return (mType == eContext_PageLayout || mType == eContext_Galley);
959   }
IsScreen()960   bool IsScreen() {
961     return (mMedium == nsGkAtoms::screen || mType == eContext_PageLayout ||
962             mType == eContext_PrintPreview);
963   }
IsPrintingOrPrintPreview()964   bool IsPrintingOrPrintPreview() {
965     return (mType == eContext_Print || mType == eContext_PrintPreview);
966   }
967 
968   // Is this presentation in a chrome docshell?
IsChrome()969   bool IsChrome() const { return mIsChrome; }
IsChromeOriginImage()970   bool IsChromeOriginImage() const { return mIsChromeOriginImage; }
971   void UpdateIsChrome();
972 
973   // Public API for native theme code to get style internals.
974   bool HasAuthorSpecifiedRules(const nsIFrame* aFrame,
975                                uint32_t ruleTypeMask) const;
976 
977   // Is it OK to let the page specify colors and backgrounds?
UseDocumentColors()978   bool UseDocumentColors() const {
979     MOZ_ASSERT(mUseDocumentColors || !(IsChrome() || IsChromeOriginImage()),
980                "We should never have a chrome doc or image that can't use its "
981                "colors.");
982     return mUseDocumentColors;
983   }
984 
985   // Explicitly enable and disable paint flashing.
SetPaintFlashing(bool aPaintFlashing)986   void SetPaintFlashing(bool aPaintFlashing) {
987     mPaintFlashing = aPaintFlashing;
988     mPaintFlashingInitialized = true;
989   }
990 
991   // This method should be used instead of directly accessing mPaintFlashing,
992   // as that value may be out of date when mPaintFlashingInitialized is false.
993   bool GetPaintFlashing() const;
994 
SuppressingResizeReflow()995   bool SuppressingResizeReflow() const { return mSuppressResizeReflow; }
996 
997   gfxUserFontSet* GetUserFontSet(bool aFlushUserFontSet = true);
998 
999   // Should be called whenever the set of fonts available in the user
1000   // font set changes (e.g., because a new font loads, or because the
1001   // user font set is changed and fonts become unavailable).
1002   void UserFontSetUpdated(gfxUserFontEntry* aUpdatedFont = nullptr);
1003 
MissingFontRecorder()1004   gfxMissingFontRecorder* MissingFontRecorder() { return mMissingFonts; }
1005   void NotifyMissingFonts();
1006 
1007   void FlushCounterStyles();
1008   void MarkCounterStylesDirty();
1009 
1010   void FlushFontFeatureValues();
MarkFontFeatureValuesDirty()1011   void MarkFontFeatureValuesDirty() { mFontFeatureValuesDirty = true; }
1012 
1013   // Ensure that it is safe to hand out CSS rules outside the layout
1014   // engine by ensuring that all CSS style sheets have unique inners
1015   // and, if necessary, synchronously rebuilding all style data.
1016   void EnsureSafeToHandOutCSSRules();
1017 
1018   // Mark an area as invalidated, associated with a given transaction id
1019   // (allocated by nsRefreshDriver::GetTransactionId). Invalidated regions will
1020   // be dispatched to MozAfterPaint events when NotifyDidPaintForSubtree is
1021   // called for the transaction id (or any higher id).
1022   void NotifyInvalidation(uint64_t aTransactionId, const nsRect& aRect);
1023   // aRect is in device pixels
1024   void NotifyInvalidation(uint64_t aTransactionId, const nsIntRect& aRect);
1025   void NotifyDidPaintForSubtree(
1026       uint64_t aTransactionId = 0,
1027       const mozilla::TimeStamp& aTimeStamp = mozilla::TimeStamp());
1028   void FireDOMPaintEvent(nsTArray<nsRect>* aList, uint64_t aTransactionId,
1029                          mozilla::TimeStamp aTimeStamp = mozilla::TimeStamp());
1030 
1031   // Callback for catching invalidations in ContainerLayers
1032   // Passed to LayerProperties::ComputeDifference
1033   static void NotifySubDocInvalidation(
1034       mozilla::layers::ContainerLayer* aContainer, const nsIntRegion* aRegion);
1035   void SetNotifySubDocInvalidationData(
1036       mozilla::layers::ContainerLayer* aContainer);
1037   static void ClearNotifySubDocInvalidationData(
1038       mozilla::layers::ContainerLayer* aContainer);
1039   bool IsDOMPaintEventPending();
1040 
1041   /**
1042    * Returns the RestyleManager's restyle generation counter.
1043    */
1044   uint64_t GetRestyleGeneration() const;
1045   uint64_t GetUndisplayedRestyleGeneration() const;
1046 
1047   /**
1048    * Returns whether there are any pending restyles or reflows.
1049    */
1050   bool HasPendingRestyleOrReflow();
1051 
1052   /**
1053    * Informs the document's FontFaceSet that the refresh driver ticked,
1054    * flushing style and layout.
1055    */
1056   void NotifyFontFaceSetOnRefresh();
1057 
1058   /**
1059    * Notify the prescontext that the presshell is about to reflow a reflow root.
1060    * The single argument indicates whether this reflow should be interruptible.
1061    * If aInterruptible is false then CheckForInterrupt and HasPendingInterrupt
1062    * will always return false. If aInterruptible is true then CheckForInterrupt
1063    * will return true when a pending event is detected.  This is for use by the
1064    * presshell only.  Reflow code wanting to prevent interrupts should use
1065    * InterruptPreventer.
1066    */
1067   void ReflowStarted(bool aInterruptible);
1068 
1069   /**
1070    * A class that can be used to temporarily disable reflow interruption.
1071    */
1072   class InterruptPreventer;
1073   friend class InterruptPreventer;
1074   class MOZ_STACK_CLASS InterruptPreventer {
1075    public:
InterruptPreventer(nsPresContext * aCtx)1076     explicit InterruptPreventer(nsPresContext* aCtx)
1077         : mCtx(aCtx),
1078           mInterruptsEnabled(aCtx->mInterruptsEnabled),
1079           mHasPendingInterrupt(aCtx->mHasPendingInterrupt) {
1080       mCtx->mInterruptsEnabled = false;
1081       mCtx->mHasPendingInterrupt = false;
1082     }
~InterruptPreventer()1083     ~InterruptPreventer() {
1084       mCtx->mInterruptsEnabled = mInterruptsEnabled;
1085       mCtx->mHasPendingInterrupt = mHasPendingInterrupt;
1086     }
1087 
1088    private:
1089     nsPresContext* mCtx;
1090     bool mInterruptsEnabled;
1091     bool mHasPendingInterrupt;
1092   };
1093 
1094   /**
1095    * Check for interrupts. This may return true if a pending event is
1096    * detected. Once it has returned true, it will keep returning true
1097    * until ReflowStarted is called. In all cases where this returns true,
1098    * the passed-in frame (which should be the frame whose reflow will be
1099    * interrupted if true is returned) will be passed to
1100    * nsIPresShell::FrameNeedsToContinueReflow.
1101    */
1102   bool CheckForInterrupt(nsIFrame* aFrame);
1103   /**
1104    * Returns true if CheckForInterrupt has returned true since the last
1105    * ReflowStarted call. Cannot itself trigger an interrupt check.
1106    */
HasPendingInterrupt()1107   bool HasPendingInterrupt() { return mHasPendingInterrupt; }
1108   /**
1109    * Sets a flag that will trip a reflow interrupt. This only bypasses the
1110    * interrupt timeout and the pending event check; other checks such as whether
1111    * interrupts are enabled and the interrupt check skipping still take effect.
1112    */
SetPendingInterruptFromTest()1113   void SetPendingInterruptFromTest() { mPendingInterruptFromTest = true; }
1114 
1115   /**
1116    * If we have a presshell, and if the given content's current
1117    * document is the same as our presshell's document, return the
1118    * content's primary frame.  Otherwise, return null.  Only use this
1119    * if you care about which presshell the primary frame is in.
1120    */
1121   nsIFrame* GetPrimaryFrameFor(nsIContent* aContent);
1122 
1123   virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)1124   virtual size_t SizeOfIncludingThis(
1125       mozilla::MallocSizeOf aMallocSizeOf) const {
1126     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
1127   }
1128 
1129   bool IsRootContentDocument() const;
1130 
HadNonBlankPaint()1131   bool HadNonBlankPaint() const { return mHadNonBlankPaint; }
1132 
1133   void NotifyNonBlankPaint();
1134 
UsesRootEMUnits()1135   bool UsesRootEMUnits() const { return mUsesRootEMUnits; }
1136 
SetUsesRootEMUnits(bool aValue)1137   void SetUsesRootEMUnits(bool aValue) { mUsesRootEMUnits = aValue; }
1138 
UsesExChUnits()1139   bool UsesExChUnits() const { return mUsesExChUnits; }
1140 
SetUsesExChUnits(bool aValue)1141   void SetUsesExChUnits(bool aValue) { mUsesExChUnits = aValue; }
1142 
1143   // true if there are OMTA transition updates for the current document which
1144   // have been throttled, and therefore some style information may not be up
1145   // to date
ExistThrottledUpdates()1146   bool ExistThrottledUpdates() const { return mExistThrottledUpdates; }
1147 
SetExistThrottledUpdates(bool aExistThrottledUpdates)1148   void SetExistThrottledUpdates(bool aExistThrottledUpdates) {
1149     mExistThrottledUpdates = aExistThrottledUpdates;
1150   }
1151 
1152   bool IsDeviceSizePageSize();
1153 
HasWarnedAboutPositionedTableParts()1154   bool HasWarnedAboutPositionedTableParts() const {
1155     return mHasWarnedAboutPositionedTableParts;
1156   }
1157 
SetHasWarnedAboutPositionedTableParts()1158   void SetHasWarnedAboutPositionedTableParts() {
1159     mHasWarnedAboutPositionedTableParts = true;
1160   }
1161 
HasWarnedAboutTooLargeDashedOrDottedRadius()1162   bool HasWarnedAboutTooLargeDashedOrDottedRadius() const {
1163     return mHasWarnedAboutTooLargeDashedOrDottedRadius;
1164   }
1165 
SetHasWarnedAboutTooLargeDashedOrDottedRadius()1166   void SetHasWarnedAboutTooLargeDashedOrDottedRadius() {
1167     mHasWarnedAboutTooLargeDashedOrDottedRadius = true;
1168   }
1169 
1170   nsBidi& GetBidiEngine();
1171 
GetFontFeatureValuesLookup()1172   gfxFontFeatureValueSet* GetFontFeatureValuesLookup() const {
1173     return mFontFeatureValuesLookup;
1174   }
1175 
1176  protected:
1177   friend class nsRunnableMethod<nsPresContext>;
1178   void ThemeChangedInternal();
1179   void SysColorChangedInternal();
1180   void RefreshSystemMetrics();
1181 
1182   // update device context's resolution from the widget
1183   void UIResolutionChangedInternal();
1184 
1185   // if aScale > 0.0, use it as resolution scale factor to the device context
1186   // (otherwise get it from the widget)
1187   void UIResolutionChangedInternalScale(double aScale);
1188 
1189   // aData here is a pointer to a double that holds the CSS to device-pixel
1190   // scale factor from the parent, which will be applied to the subdocument's
1191   // device context instead of retrieving a scale from the widget.
1192   static bool UIResolutionChangedSubdocumentCallback(nsIDocument* aDocument,
1193                                                      void* aData);
1194 
1195   void SetImgAnimations(nsIContent* aParent, uint16_t aMode);
1196   void SetSMILAnimations(nsIDocument* aDoc, uint16_t aNewMode,
1197                          uint16_t aOldMode);
1198   void GetDocumentColorPreferences();
1199 
1200   void PreferenceChanged(const char* aPrefName);
1201   static void PrefChangedCallback(const char*, void*);
1202 
1203   void UpdateAfterPreferencesChanged();
1204   void DispatchPrefChangedRunnableIfNeeded();
1205 
1206   void GetUserPreferences();
1207 
1208   /**
1209    * Fetch the user's font preferences for the given aLanguage's
1210    * langugage group.
1211    */
1212   const LangGroupFontPrefs* GetFontPrefsForLang(
1213       nsAtom* aLanguage, bool* aNeedsToCache = nullptr) const {
1214     nsAtom* lang = aLanguage ? aLanguage : mLanguage.get();
1215     return StaticPresData::Get()->GetFontPrefsForLangHelper(
1216         lang, &mLangGroupFontPrefs, aNeedsToCache);
1217   }
1218 
1219   void UpdateCharSet(NotNull<const Encoding*> aCharSet);
1220 
1221   static bool NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument,
1222                                                 void* aData);
1223 
1224  public:
1225   // Used by the PresShell to force a reflow when some aspect of font info
1226   // has been updated, potentially affecting font selection and layout.
1227   void ForceReflowForFontInfoUpdate();
1228 
1229   void DoChangeCharSet(NotNull<const Encoding*> aCharSet);
1230 
1231   /**
1232    * Checks for MozAfterPaint listeners on the document
1233    */
1234   bool MayHavePaintEventListener();
1235 
1236   /**
1237    * Checks for MozAfterPaint listeners on the document and
1238    * any subdocuments, except for subdocuments that are non-top-level
1239    * content documents.
1240    */
1241   bool MayHavePaintEventListenerInSubDocument();
1242 
1243 #ifdef RESTYLE_LOGGING
1244   // Controls for whether debug information about restyling in this
1245   // document should be output.
RestyleLoggingEnabled()1246   bool RestyleLoggingEnabled() const { return mRestyleLoggingEnabled; }
StartRestyleLogging()1247   void StartRestyleLogging() { mRestyleLoggingEnabled = true; }
StopRestyleLogging()1248   void StopRestyleLogging() { mRestyleLoggingEnabled = false; }
1249 #endif
1250 
1251   void InvalidatePaintedLayers();
1252 
1253  protected:
1254   // May be called multiple times (unlink, destructor)
1255   void Destroy();
1256 
1257   void AppUnitsPerDevPixelChanged();
1258 
1259   bool HavePendingInputEvent();
1260 
1261   // Creates a one-shot timer with the given aCallback & aDelay.
1262   // Returns a refcounted pointer to the timer (or nullptr on failure).
1263   already_AddRefed<nsITimer> CreateTimer(nsTimerCallbackFunc aCallback,
1264                                          const char* aName, uint32_t aDelay);
1265 
1266   struct TransactionInvalidations {
1267     uint64_t mTransactionId;
1268     nsTArray<nsRect> mInvalidations;
1269   };
1270   TransactionInvalidations* GetInvalidations(uint64_t aTransactionId);
1271 
1272   // IMPORTANT: The ownership implicit in the following member variables
1273   // has been explicitly checked.  If you add any members to this class,
1274   // please make the ownership explicit (pinkerton, scc).
1275 
1276   nsPresContextType mType;
1277   // the nsPresShell owns a strong reference to the nsPresContext, and is
1278   // responsible for nulling this pointer before it is destroyed
1279   nsIPresShell* MOZ_NON_OWNING_REF mShell;  // [WEAK]
1280   nsCOMPtr<nsIDocument> mDocument;
1281   RefPtr<nsDeviceContext> mDeviceContext;  // [STRONG] could be weak, but
1282                                            // better safe than sorry.
1283                                            // Cannot reintroduce cycles
1284                                            // since there is no dependency
1285                                            // from gfx back to layout.
1286   RefPtr<mozilla::EventStateManager> mEventManager;
1287   RefPtr<nsRefreshDriver> mRefreshDriver;
1288   RefPtr<mozilla::AnimationEventDispatcher> mAnimationEventDispatcher;
1289   RefPtr<mozilla::EffectCompositor> mEffectCompositor;
1290   RefPtr<nsTransitionManager> mTransitionManager;
1291   RefPtr<nsAnimationManager> mAnimationManager;
1292   RefPtr<mozilla::RestyleManager> mRestyleManager;
1293   RefPtr<mozilla::CounterStyleManager> mCounterStyleManager;
1294   nsAtom* MOZ_UNSAFE_REF(
1295       "always a static atom") mMedium;  // initialized by subclass ctors
1296   RefPtr<nsAtom> mMediaEmulated;
1297   RefPtr<gfxFontFeatureValueSet> mFontFeatureValuesLookup;
1298 
1299   // This pointer is nulled out through SetLinkHandler() in the destructors of
1300   // the classes which set it. (using SetLinkHandler() again).
1301   nsILinkHandler* MOZ_NON_OWNING_REF mLinkHandler;
1302 
1303   // Formerly mLangGroup; moving from charset-oriented langGroup to
1304   // maintaining actual language settings everywhere (see bug 524107).
1305   // This may in fact hold a langGroup such as x-western rather than
1306   // a specific language, however (e.g, if it is inferred from the
1307   // charset rather than explicitly specified as a lang attribute).
1308   RefPtr<nsAtom> mLanguage;
1309 
1310  public:
1311   // The following are public member variables so that we can use them
1312   // with mozilla::AutoToggle or mozilla::AutoRestore.
1313 
1314   // Should we disable font size inflation because we're inside of
1315   // shrink-wrapping calculations on an inflation container?
1316   bool mInflationDisabledForShrinkWrap;
1317 
1318  protected:
1319   mozilla::WeakPtr<nsDocShell> mContainer;
1320 
1321   // Base minimum font size, independent of the language-specific global
1322   // preference. Defaults to 0
1323   int32_t mBaseMinFontSize;
1324   float mSystemFontScale;    // Internal text zoom factor, defaults to 1.0
1325   float mTextZoom;           // Text zoom, defaults to 1.0
1326   float mEffectiveTextZoom;  // Text zoom * system font scale
1327   float mFullZoom;           // Page zoom, defaults to 1.0
1328   float mOverrideDPPX;       // DPPX overrided, defaults to 0.0
1329   gfxSize mLastFontInflationScreenSize;
1330 
1331   int32_t mCurAppUnitsPerDevPixel;
1332   int32_t mAutoQualityMinFontSizePixelsPref;
1333 
1334   nsCOMPtr<nsITheme> mTheme;
1335   nsLanguageAtomService* mLangService;
1336   nsCOMPtr<nsIPrintSettings> mPrintSettings;
1337 
1338   mozilla::UniquePtr<nsBidi> mBidiEngine;
1339 
1340   AutoTArray<TransactionInvalidations, 4> mTransactions;
1341 
1342   // text performance metrics
1343   nsAutoPtr<gfxTextPerfMetrics> mTextPerf;
1344 
1345   nsAutoPtr<gfxMissingFontRecorder> mMissingFonts;
1346 
1347   nsRect mVisibleArea;
1348   nsRect mLastResizeEventVisibleArea;
1349   nsSize mPageSize;
1350   float mPageScale;
1351   float mPPScale;
1352 
1353   nscolor mDefaultColor;
1354   nscolor mBackgroundColor;
1355 
1356   nscolor mLinkColor;
1357   nscolor mActiveLinkColor;
1358   nscolor mVisitedLinkColor;
1359 
1360   nscolor mFocusBackgroundColor;
1361   nscolor mFocusTextColor;
1362 
1363   nscolor mBodyTextColor;
1364 
1365   // This is a non-owning pointer. May be null. If non-null, it's guaranteed to
1366   // be pointing to an element that's still alive, because we'll reset it in
1367   // UpdateViewportScrollbarStylesOverride() as part of the cleanup code when
1368   // this element is removed from the document. (For <body> and the root
1369   // element, this call happens in nsCSSFrameConstructor::ContentRemoved(). For
1370   // fullscreen elements, it happens in the fullscreen-specific cleanup invoked
1371   // by Element::UnbindFromTree().)
1372   mozilla::dom::Element* MOZ_NON_OWNING_REF mViewportScrollbarOverrideElement;
1373   ScrollbarStyles mViewportStyleScrollbar;
1374 
1375   uint8_t mFocusRingWidth;
1376 
1377   bool mExistThrottledUpdates;
1378 
1379   uint16_t mImageAnimationMode;
1380   uint16_t mImageAnimationModePref;
1381 
1382   // Most documents will only use one (or very few) language groups. Rather
1383   // than have the overhead of a hash lookup, we simply look along what will
1384   // typically be a very short (usually of length 1) linked list. There are 31
1385   // language groups, so in the worst case scenario we'll need to traverse 31
1386   // link items.
1387   LangGroupFontPrefs mLangGroupFontPrefs;
1388 
1389   bool mFontGroupCacheDirty;
1390   nsTHashtable<nsRefPtrHashKey<nsAtom>> mLanguagesUsed;
1391 
1392   nscoord mBorderWidthTable[3];
1393 
1394   uint32_t mInterruptChecksToSkip;
1395 
1396   // Counters for tests and tools that want to detect frame construction
1397   // or reflow.
1398   uint64_t mElementsRestyled;
1399   uint64_t mFramesConstructed;
1400   uint64_t mFramesReflowed;
1401 
1402   mozilla::TimeStamp mReflowStartTime;
1403 
1404   // Time of various first interaction types, used to report time from
1405   // first paint of the top level content pres shell to first interaction.
1406   mozilla::TimeStamp mFirstNonBlankPaintTime;
1407   mozilla::TimeStamp mFirstClickTime;
1408   mozilla::TimeStamp mFirstKeyTime;
1409   mozilla::TimeStamp mFirstMouseMoveTime;
1410   mozilla::TimeStamp mFirstScrollTime;
1411   bool mInteractionTimeEnabled;
1412 
1413   // last time we did a full style flush
1414   mozilla::TimeStamp mLastStyleUpdateForAllAnimations;
1415 
1416   nscoord mTelemetryScrollLastY;
1417   nscoord mTelemetryScrollMaxY;
1418   nscoord mTelemetryScrollTotalY;
1419 
1420   unsigned mHasPendingInterrupt : 1;
1421   unsigned mPendingInterruptFromTest : 1;
1422   unsigned mInterruptsEnabled : 1;
1423   unsigned mUseDocumentFonts : 1;
1424   unsigned mUseDocumentColors : 1;
1425   unsigned mUnderlineLinks : 1;
1426   unsigned mSendAfterPaintToContent : 1;
1427   unsigned mUseFocusColors : 1;
1428   unsigned mFocusRingOnAnything : 1;
1429   unsigned mFocusRingStyle : 1;
1430   unsigned mDrawImageBackground : 1;
1431   unsigned mDrawColorBackground : 1;
1432   unsigned mNeverAnimate : 1;
1433   unsigned mIsRenderingOnlySelection : 1;
1434   unsigned mPaginated : 1;
1435   unsigned mCanPaginatedScroll : 1;
1436   unsigned mDoScaledTwips : 1;
1437   unsigned mIsRootPaginatedDocument : 1;
1438   unsigned mPrefBidiDirection : 1;
1439   unsigned mPrefScrollbarSide : 2;
1440   unsigned mPendingSysColorChanged : 1;
1441   unsigned mPendingThemeChanged : 1;
1442   unsigned mPendingUIResolutionChanged : 1;
1443   unsigned mPrefChangePendingNeedsReflow : 1;
1444   unsigned mPostedPrefChangedRunnable : 1;
1445   unsigned mIsEmulatingMedia : 1;
1446 
1447   // Are we currently drawing an SVG glyph?
1448   unsigned mIsGlyph : 1;
1449 
1450   // Does the associated document use root-em (rem) units?
1451   unsigned mUsesRootEMUnits : 1;
1452   // Does the associated document use ex or ch units?
1453   unsigned mUsesExChUnits : 1;
1454 
1455   // Is the current mCounterStyleManager valid?
1456   unsigned mCounterStylesDirty : 1;
1457 
1458   // Is the current mFontFeatureValuesLookup valid?
1459   unsigned mFontFeatureValuesDirty : 1;
1460 
1461   // resize reflow is suppressed when the only change has been to zoom
1462   // the document rather than to change the document's dimensions
1463   unsigned mSuppressResizeReflow : 1;
1464 
1465   unsigned mIsVisual : 1;
1466 
1467   unsigned mIsChrome : 1;
1468   unsigned mIsChromeOriginImage : 1;
1469 
1470   // Should we paint flash in this context? Do not use this variable directly.
1471   // Use GetPaintFlashing() method instead.
1472   mutable unsigned mPaintFlashing : 1;
1473   mutable unsigned mPaintFlashingInitialized : 1;
1474 
1475   unsigned mHasWarnedAboutPositionedTableParts : 1;
1476 
1477   unsigned mHasWarnedAboutTooLargeDashedOrDottedRadius : 1;
1478 
1479   // Have we added quirk.css to the style set?
1480   unsigned mQuirkSheetAdded : 1;
1481 
1482   // Is there a pref update to process once we have a container?
1483   unsigned mNeedsPrefUpdate : 1;
1484 
1485   // Has NotifyNonBlankPaint been called on this PresContext?
1486   unsigned mHadNonBlankPaint : 1;
1487 
1488 #ifdef RESTYLE_LOGGING
1489   // Should we output debug information about restyling for this document?
1490   unsigned mRestyleLoggingEnabled : 1;
1491 #endif
1492 
1493 #ifdef DEBUG
1494   unsigned mInitialized : 1;
1495 #endif
1496 
1497   mozilla::Maybe<mozilla::MediaFeatureChange> mPendingMediaFeatureValuesChange;
1498 
1499  protected:
1500   virtual ~nsPresContext();
1501 
1502   nscolor MakeColorPref(const nsString& aColor);
1503 
1504   void LastRelease();
1505 
1506 #ifdef DEBUG
1507  private:
1508   friend struct nsAutoLayoutPhase;
1509   uint32_t mLayoutPhaseCount[eLayoutPhase_COUNT];
1510 
1511  public:
LayoutPhaseCount(nsLayoutPhase aPhase)1512   uint32_t LayoutPhaseCount(nsLayoutPhase aPhase) {
1513     return mLayoutPhaseCount[aPhase];
1514   }
1515 #endif
1516 };
1517 
1518 class nsRootPresContext final : public nsPresContext {
1519  public:
1520   nsRootPresContext(nsIDocument* aDocument, nsPresContextType aType);
1521   virtual ~nsRootPresContext();
1522   virtual void Detach() override;
1523 
1524   /**
1525    * Ensure that NotifyDidPaintForSubtree is eventually called on this
1526    * object after a timeout.
1527    */
1528   void EnsureEventualDidPaintEvent(uint64_t aTransactionId);
1529 
1530   /**
1531    * Cancels any pending eventual did paint timer for transaction
1532    * ids up to and including aTransactionId.
1533    */
1534   void CancelDidPaintTimers(uint64_t aTransactionId);
1535 
1536   /**
1537    * Cancel all pending eventual did paint timers.
1538    */
1539   void CancelAllDidPaintTimers();
1540 
1541   /**
1542    * Registers a plugin to receive geometry updates (position and clip
1543    * region) so it can update its widget.
1544    * Callers must call UnregisterPluginForGeometryUpdates before
1545    * the aPlugin frame is destroyed.
1546    */
1547   void RegisterPluginForGeometryUpdates(nsIContent* aPlugin);
1548   /**
1549    * Stops a plugin receiving geometry updates (position and clip
1550    * region). If the plugin was not already registered, this does
1551    * nothing.
1552    */
1553   void UnregisterPluginForGeometryUpdates(nsIContent* aPlugin);
1554 
NeedToComputePluginGeometryUpdates()1555   bool NeedToComputePluginGeometryUpdates() {
1556     return mRegisteredPlugins.Count() > 0;
1557   }
1558   /**
1559    * Compute geometry updates for each plugin given that aList is the display
1560    * list for aFrame. The updates are not yet applied;
1561    * ApplyPluginGeometryUpdates is responsible for that. In the meantime they
1562    * are stored on each nsPluginFrame.
1563    * This needs to be called even when aFrame is a popup, since although
1564    * windowed plugins aren't allowed in popups, windowless plugins are
1565    * and ComputePluginGeometryUpdates needs to be called for them.
1566    * aBuilder and aList can be null. This indicates that all plugins are
1567    * hidden because we're in a background tab.
1568    */
1569   void ComputePluginGeometryUpdates(nsIFrame* aFrame,
1570                                     nsDisplayListBuilder* aBuilder,
1571                                     nsDisplayList* aList);
1572 
1573   /**
1574    * Apply the stored plugin geometry updates. This should normally be called
1575    * in DidPaint so the plugins are moved/clipped immediately after we've
1576    * updated our window, so they look in sync with our window.
1577    */
1578   void ApplyPluginGeometryUpdates();
1579 
1580   /**
1581    * Transfer stored plugin geometry updates to the compositor. Called during
1582    * reflow, data is shipped over with layer updates. e10s specific.
1583    */
1584   void CollectPluginGeometryUpdates(
1585       mozilla::layers::LayerManager* aLayerManager);
1586 
IsRoot()1587   virtual bool IsRoot() override { return true; }
1588 
1589   /**
1590    * Add a runnable that will get called before the next paint. They will get
1591    * run eventually even if painting doesn't happen. They might run well before
1592    * painting happens.
1593    */
1594   void AddWillPaintObserver(nsIRunnable* aRunnable);
1595 
1596   /**
1597    * Run all runnables that need to get called before the next paint.
1598    */
1599   void FlushWillPaintObservers();
1600 
1601   virtual size_t SizeOfExcludingThis(
1602       mozilla::MallocSizeOf aMallocSizeOf) const override;
1603 
1604  protected:
1605   /**
1606    * Start a timer to ensure we eventually run ApplyPluginGeometryUpdates.
1607    */
1608   void InitApplyPluginGeometryTimer();
1609   /**
1610    * Cancel the timer that ensures we eventually run ApplyPluginGeometryUpdates.
1611    */
1612   void CancelApplyPluginGeometryTimer();
1613 
1614   class RunWillPaintObservers : public mozilla::Runnable {
1615    public:
RunWillPaintObservers(nsRootPresContext * aPresContext)1616     explicit RunWillPaintObservers(nsRootPresContext* aPresContext)
1617         : Runnable("nsPresContextType::RunWillPaintObservers"),
1618           mPresContext(aPresContext) {}
Revoke()1619     void Revoke() { mPresContext = nullptr; }
Run()1620     NS_IMETHOD Run() override {
1621       if (mPresContext) {
1622         mPresContext->FlushWillPaintObservers();
1623       }
1624       return NS_OK;
1625     }
1626     // The lifetime of this reference is handled by an nsRevocableEventPtr
1627     nsRootPresContext* MOZ_NON_OWNING_REF mPresContext;
1628   };
1629 
1630   friend class nsPresContext;
1631 
1632   struct NotifyDidPaintTimer {
1633     uint64_t mTransactionId;
1634     nsCOMPtr<nsITimer> mTimer;
1635   };
1636   AutoTArray<NotifyDidPaintTimer, 4> mNotifyDidPaintTimers;
1637 
1638   nsCOMPtr<nsITimer> mApplyPluginGeometryTimer;
1639   nsTHashtable<nsRefPtrHashKey<nsIContent>> mRegisteredPlugins;
1640   nsTArray<nsCOMPtr<nsIRunnable>> mWillPaintObservers;
1641   nsRevocableEventPtr<RunWillPaintObservers> mWillPaintFallbackEvent;
1642 };
1643 
1644 #ifdef MOZ_REFLOW_PERF
1645 
1646 #define DO_GLOBAL_REFLOW_COUNT(_name) \
1647   aPresContext->CountReflows((_name), (nsIFrame*)this);
1648 #else
1649 #define DO_GLOBAL_REFLOW_COUNT(_name)
1650 #endif  // MOZ_REFLOW_PERF
1651 
1652 #endif /* nsPresContext_h___ */
1653