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