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