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