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