LCOV - code coverage report
Current view: directory - layout/base - nsDisplayList.h (source / functions) Found Hit Coverage
Test: app.info Lines: 383 0 0.0 %
Date: 2012-06-02 Functions: 204 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2                 :  * vim: set ts=2 sw=2 et tw=78:
       3                 :  * ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Novell code.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is Novell Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2006
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *     robert@ocallahan.org
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK *****
      38                 :  */
      39                 : 
      40                 : /*
      41                 :  * structures that represent things to be painted (ordered in z-order),
      42                 :  * used during painting and hit testing
      43                 :  */
      44                 : 
      45                 : #ifndef NSDISPLAYLIST_H_
      46                 : #define NSDISPLAYLIST_H_
      47                 : 
      48                 : #include "nsCOMPtr.h"
      49                 : #include "nsIFrame.h"
      50                 : #include "nsPoint.h"
      51                 : #include "nsRect.h"
      52                 : #include "nsISelection.h"
      53                 : #include "nsCaret.h"
      54                 : #include "plarena.h"
      55                 : #include "Layers.h"
      56                 : #include "nsRegion.h"
      57                 : #include "FrameLayerBuilder.h"
      58                 : #include "nsThemeConstants.h"
      59                 : 
      60                 : #include <stdlib.h>
      61                 : 
      62                 : class nsIPresShell;
      63                 : class nsIContent;
      64                 : class nsRenderingContext;
      65                 : class nsDeviceContext;
      66                 : class nsDisplayTableItem;
      67                 : class nsDisplayItem;
      68                 : 
      69                 : /*
      70                 :  * An nsIFrame can have many different visual parts. For example an image frame
      71                 :  * can have a background, border, and outline, the image itself, and a
      72                 :  * translucent selection overlay. In general these parts can be drawn at
      73                 :  * discontiguous z-levels; see CSS2.1 appendix E:
      74                 :  * http://www.w3.org/TR/CSS21/zindex.html
      75                 :  * 
      76                 :  * We construct a display list for a frame tree that contains one item
      77                 :  * for each visual part. The display list is itself a tree since some items
      78                 :  * are containers for other items; however, its structure does not match
      79                 :  * the structure of its source frame tree. The display list items are sorted
      80                 :  * by z-order. A display list can be used to paint the frames, to determine
      81                 :  * which frame is the target of a mouse event, and to determine what areas
      82                 :  * need to be repainted when scrolling. The display lists built for each task
      83                 :  * may be different for efficiency; in particular some frames need special
      84                 :  * display list items only for event handling, and do not create these items
      85                 :  * when the display list will be used for painting (the common case). For
      86                 :  * example, when painting we avoid creating nsDisplayBackground items for
      87                 :  * frames that don't display a visible background, but for event handling
      88                 :  * we need those backgrounds because they are not transparent to events.
      89                 :  * 
      90                 :  * We could avoid constructing an explicit display list by traversing the
      91                 :  * frame tree multiple times in clever ways. However, reifying the display list
      92                 :  * reduces code complexity and reduces the number of times each frame must be
      93                 :  * traversed to one, which seems to be good for performance. It also means
      94                 :  * we can share code for painting, event handling and scroll analysis.
      95                 :  * 
      96                 :  * Display lists are short-lived; content and frame trees cannot change
      97                 :  * between a display list being created and destroyed. Display lists should
      98                 :  * not be created during reflow because the frame tree may be in an
      99                 :  * inconsistent state (e.g., a frame's stored overflow-area may not include
     100                 :  * the bounds of all its children). However, it should be fine to create
     101                 :  * a display list while a reflow is pending, before it starts.
     102                 :  * 
     103                 :  * A display list covers the "extended" frame tree; the display list for a frame
     104                 :  * tree containing FRAME/IFRAME elements can include frames from the subdocuments.
     105                 :  */
     106                 : 
     107                 : // All types are defined in nsDisplayItemTypes.h
     108                 : #ifdef MOZ_DUMP_PAINTING
     109                 : #define NS_DISPLAY_DECL_NAME(n, e) \
     110                 :   virtual const char* Name() { return n; } \
     111                 :   virtual Type GetType() { return e; }
     112                 : #else
     113                 : #define NS_DISPLAY_DECL_NAME(n, e) \
     114                 :   virtual Type GetType() { return e; }
     115                 : #endif
     116                 : 
     117                 : /**
     118                 :  * This manages a display list and is passed as a parameter to
     119                 :  * nsIFrame::BuildDisplayList.
     120                 :  * It contains the parameters that don't change from frame to frame and manages
     121                 :  * the display list memory using a PLArena. It also establishes the reference
     122                 :  * coordinate system for all display list items. Some of the parameters are
     123                 :  * available from the prescontext/presshell, but we copy them into the builder
     124                 :  * for faster/more convenient access.
     125                 :  */
     126                 : class nsDisplayListBuilder {
     127                 : public:
     128                 :   typedef mozilla::FramePropertyDescriptor FramePropertyDescriptor;
     129                 :   typedef mozilla::FrameLayerBuilder FrameLayerBuilder;
     130                 :   typedef nsIWidget::ThemeGeometry ThemeGeometry;
     131                 : 
     132                 :   /**
     133                 :    * @param aReferenceFrame the frame at the root of the subtree; its origin
     134                 :    * is the origin of the reference coordinate system for this display list
     135                 :    * @param aIsForEvents true if we're creating this list in order to
     136                 :    * determine which frame is under the mouse position
     137                 :    * @param aBuildCaret whether or not we should include the caret in any
     138                 :    * display lists that we make.
     139                 :    */
     140                 :   enum Mode {
     141                 :         PAINTING,
     142                 :         EVENT_DELIVERY,
     143                 :         PLUGIN_GEOMETRY,
     144                 :         OTHER
     145                 :   };
     146                 :   nsDisplayListBuilder(nsIFrame* aReferenceFrame, Mode aMode, bool aBuildCaret);
     147                 :   ~nsDisplayListBuilder();
     148                 : 
     149                 :   /**
     150                 :    * @return true if the display is being built in order to determine which
     151                 :    * frame is under the mouse position.
     152                 :    */
     153               0 :   bool IsForEventDelivery() { return mMode == EVENT_DELIVERY; }
     154                 :   /**
     155                 :    * @return true if the display list is being built to compute geometry
     156                 :    * for plugins.
     157                 :    */
     158               0 :   bool IsForPluginGeometry() { return mMode == PLUGIN_GEOMETRY; }
     159                 :   /**
     160                 :    * @return true if the display list is being built for painting.
     161                 :    */
     162               0 :   bool IsForPainting() { return mMode == PAINTING; }
     163                 :   /**
     164                 :    * @return true if "painting is suppressed" during page load and we
     165                 :    * should paint only the background of the document.
     166                 :    */
     167               0 :   bool IsBackgroundOnly() {
     168               0 :     NS_ASSERTION(mPresShellStates.Length() > 0,
     169                 :                  "don't call this if we're not in a presshell");
     170               0 :     return CurrentPresShellState()->mIsBackgroundOnly;
     171                 :   }
     172                 :   /**
     173                 :    * @return true if the currently active BuildDisplayList call is being
     174                 :    * applied to a frame at the root of a pseudo stacking context. A pseudo
     175                 :    * stacking context is either a real stacking context or basically what
     176                 :    * CSS2.1 appendix E refers to with "treat the element as if it created
     177                 :    * a new stacking context
     178                 :    */
     179               0 :   bool IsAtRootOfPseudoStackingContext() { return mIsAtRootOfPseudoStackingContext; }
     180                 : 
     181                 :   /**
     182                 :    * @return the selection that painting should be restricted to (or nsnull
     183                 :    * in the normal unrestricted case)
     184                 :    */
     185               0 :   nsISelection* GetBoundingSelection() { return mBoundingSelection; }
     186                 :   /**
     187                 :    * @return the root of the display list's frame (sub)tree, whose origin
     188                 :    * establishes the coordinate system for the display list
     189                 :    */
     190               0 :   nsIFrame* ReferenceFrame() const { return mReferenceFrame; }
     191                 :   /**
     192                 :    * @return a point pt such that adding pt to a coordinate relative to aFrame
     193                 :    * makes it relative to ReferenceFrame(), i.e., returns 
     194                 :    * aFrame->GetOffsetToCrossDoc(ReferenceFrame()). The returned point is in
     195                 :    * the appunits of aFrame. It may be optimized to be faster than
     196                 :    * aFrame->GetOffsetToCrossDoc(ReferenceFrame()) (but currently isn't).
     197                 :    */
     198               0 :   nsPoint ToReferenceFrame(const nsIFrame* aFrame) const {
     199               0 :     return aFrame->GetOffsetToCrossDoc(ReferenceFrame());
     200                 :   }
     201                 :   /**
     202                 :    * When building the display list, the scrollframe aFrame will be "ignored"
     203                 :    * for the purposes of clipping, and its scrollbars will be hidden. We use
     204                 :    * this to allow RenderOffscreen to render a whole document without beign
     205                 :    * clipped by the viewport or drawing the viewport scrollbars.
     206                 :    */
     207               0 :   void SetIgnoreScrollFrame(nsIFrame* aFrame) { mIgnoreScrollFrame = aFrame; }
     208                 :   /**
     209                 :    * Get the scrollframe to ignore, if any.
     210                 :    */
     211               0 :   nsIFrame* GetIgnoreScrollFrame() { return mIgnoreScrollFrame; }
     212                 :   /**
     213                 :    * Calling this setter makes us include all out-of-flow descendant
     214                 :    * frames in the display list, wherever they may be positioned (even
     215                 :    * outside the dirty rects).
     216                 :    */
     217               0 :   void SetIncludeAllOutOfFlows() { mIncludeAllOutOfFlows = true; }
     218               0 :   bool GetIncludeAllOutOfFlows() const { return mIncludeAllOutOfFlows; }
     219                 :   /**
     220                 :    * Calling this setter makes us exclude all leaf frames that aren't
     221                 :    * selected.
     222                 :    */
     223               0 :   void SetSelectedFramesOnly() { mSelectedFramesOnly = true; }
     224               0 :   bool GetSelectedFramesOnly() { return mSelectedFramesOnly; }
     225                 :   /**
     226                 :    * Calling this setter makes us compute accurate visible regions at the cost
     227                 :    * of performance if regions get very complex.
     228                 :    */
     229               0 :   void SetAccurateVisibleRegions() { mAccurateVisibleRegions = true; }
     230               0 :   bool GetAccurateVisibleRegions() { return mAccurateVisibleRegions; }
     231                 :   /**
     232                 :    * Allows callers to selectively override the regular paint suppression checks,
     233                 :    * so that methods like GetFrameForPoint work when painting is suppressed.
     234                 :    */
     235               0 :   void IgnorePaintSuppression() { mIgnoreSuppression = true; }
     236                 :   /**
     237                 :    * @return Returns if this builder will ignore paint suppression.
     238                 :    */
     239               0 :   bool IsIgnoringPaintSuppression() { return mIgnoreSuppression; }
     240                 :   /**
     241                 :    * @return Returns if this builder had to ignore painting suppression on some
     242                 :    * document when building the display list.
     243                 :    */
     244               0 :   bool GetHadToIgnorePaintSuppression() { return mHadToIgnoreSuppression; }
     245                 :   /**
     246                 :    * Call this if we're doing normal painting to the window.
     247                 :    */
     248               0 :   void SetPaintingToWindow(bool aToWindow) { mIsPaintingToWindow = aToWindow; }
     249               0 :   bool IsPaintingToWindow() const { return mIsPaintingToWindow; }
     250                 :   /**
     251                 :    * Display the caret if needed.
     252                 :    */
     253               0 :   nsresult DisplayCaret(nsIFrame* aFrame, const nsRect& aDirtyRect,
     254                 :       nsDisplayList* aList) {
     255               0 :     nsIFrame* frame = GetCaretFrame();
     256               0 :     if (aFrame != frame) {
     257               0 :       return NS_OK;
     258                 :     }
     259               0 :     return frame->DisplayCaret(this, aDirtyRect, aList);
     260                 :   }
     261                 :   /**
     262                 :    * Get the frame that the caret is supposed to draw in.
     263                 :    * If the caret is currently invisible, this will be null.
     264                 :    */
     265               0 :   nsIFrame* GetCaretFrame() {
     266               0 :     return CurrentPresShellState()->mCaretFrame;
     267                 :   }
     268                 :   /**
     269                 :    * Get the caret associated with the current presshell.
     270                 :    */
     271                 :   nsCaret* GetCaret();
     272                 :   /**
     273                 :    * Notify the display list builder that we're entering a presshell.
     274                 :    * aReferenceFrame should be a frame in the new presshell and aDirtyRect
     275                 :    * should be the current dirty rect in aReferenceFrame's coordinate space.
     276                 :    */
     277                 :   void EnterPresShell(nsIFrame* aReferenceFrame, const nsRect& aDirtyRect);
     278                 :   /**
     279                 :    * Notify the display list builder that we're leaving a presshell.
     280                 :    */
     281                 :   void LeavePresShell(nsIFrame* aReferenceFrame, const nsRect& aDirtyRect);
     282                 : 
     283                 :   /**
     284                 :    * Returns true if we're currently building a display list that's
     285                 :    * directly or indirectly under an nsDisplayTransform or SVG
     286                 :    * foreignObject.
     287                 :    */
     288               0 :   bool IsInTransform() { return mInTransform; }
     289                 :   /**
     290                 :    * Indicate whether or not we're directly or indirectly under and
     291                 :    * nsDisplayTransform or SVG foreignObject.
     292                 :    */
     293               0 :   void SetInTransform(bool aInTransform) { mInTransform = aInTransform; }
     294                 : 
     295                 :   /**
     296                 :    * Call this if using display port for scrolling.
     297                 :    */
     298                 :   void SetDisplayPort(const nsRect& aDisplayPort);
     299               0 :   const nsRect* GetDisplayPort() { return mHasDisplayPort ? &mDisplayPort : nsnull; }
     300                 : 
     301                 :   /**
     302                 :    * Call this if ReferenceFrame() is a viewport frame with fixed-position
     303                 :    * children, or when we construct an item which will return true from
     304                 :    * ShouldFixToViewport()
     305                 :    */
     306               0 :   void SetHasFixedItems() { mHasFixedItems = true; }
     307               0 :   bool GetHasFixedItems() { return mHasFixedItems; }
     308                 : 
     309                 :   /**
     310                 :    * Returns true if snapping is enabled for the final drawing context.
     311                 :    * The default is true.
     312                 :    */
     313               0 :   bool IsSnappingEnabled() { return mSnappingEnabled; }
     314                 :   /**
     315                 :    * Set if snapping is enabled for the final drawing context.
     316                 :    */
     317               0 :   void SetSnappingEnabled(bool aSnappingEnabled) { mSnappingEnabled = aSnappingEnabled; }
     318                 : 
     319                 :   /**
     320                 :    * @return true if images have been set to decode synchronously.
     321                 :    */
     322               0 :   bool ShouldSyncDecodeImages() { return mSyncDecodeImages; }
     323                 : 
     324                 :   /**
     325                 :    * Indicates whether we should synchronously decode images. If true, we decode
     326                 :    * and draw whatever image data has been loaded. If false, we just draw
     327                 :    * whatever has already been decoded.
     328                 :    */
     329               0 :   void SetSyncDecodeImages(bool aSyncDecodeImages) {
     330               0 :     mSyncDecodeImages = aSyncDecodeImages;
     331               0 :   }
     332                 : 
     333                 :   /**
     334                 :    * Helper method to generate background painting flags based on the
     335                 :    * information available in the display list builder. Currently only
     336                 :    * accounts for mSyncDecodeImages.
     337                 :    */
     338                 :   PRUint32 GetBackgroundPaintFlags();
     339                 : 
     340                 :   /**
     341                 :    * Subtracts aRegion from *aVisibleRegion. We avoid letting
     342                 :    * aVisibleRegion become overcomplex by simplifying it if necessary ---
     343                 :    * unless mAccurateVisibleRegions is set, in which case we let it
     344                 :    * get arbitrarily complex.
     345                 :    */
     346                 :   void SubtractFromVisibleRegion(nsRegion* aVisibleRegion,
     347                 :                                  const nsRegion& aRegion);
     348                 : 
     349                 :   /**
     350                 :    * Mark the frames in aFrames to be displayed if they intersect aDirtyRect
     351                 :    * (which is relative to aDirtyFrame). If the frames have placeholders
     352                 :    * that might not be displayed, we mark the placeholders and their ancestors
     353                 :    * to ensure that display list construction descends into them
     354                 :    * anyway. nsDisplayListBuilder will take care of unmarking them when it is
     355                 :    * destroyed.
     356                 :    */
     357                 :   void MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
     358                 :                                 const nsFrameList& aFrames,
     359                 :                                 const nsRect& aDirtyRect);
     360                 : 
     361                 :   /**
     362                 :    * Return the FrameLayerBuilder.
     363                 :    */
     364               0 :   FrameLayerBuilder* LayerBuilder() { return &mLayerBuilder; }
     365                 : 
     366                 :   /**
     367                 :    * Get the area of the final transparent region.
     368                 :    */
     369               0 :   const nsRegion* GetFinalTransparentRegion() { return mFinalTransparentRegion; }
     370                 :   /**
     371                 :    * Record the area of the final transparent region after all visibility
     372                 :    * calculations were performed.
     373                 :    */
     374               0 :   void SetFinalTransparentRegion(const nsRegion& aFinalTransparentRegion)
     375                 :   {
     376               0 :     mFinalTransparentRegion = &aFinalTransparentRegion;
     377               0 :   }
     378                 : 
     379               0 :   const nsTArray<ThemeGeometry>& GetThemeGeometries() { return mThemeGeometries; }
     380                 : 
     381                 :   /**
     382                 :    * Returns true if we need to descend into this frame when building
     383                 :    * the display list, even though it doesn't intersect the dirty
     384                 :    * rect, because it may have out-of-flows that do so.
     385                 :    */
     386               0 :   bool ShouldDescendIntoFrame(nsIFrame* aFrame) const {
     387                 :     return
     388               0 :       (aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) ||
     389               0 :       GetIncludeAllOutOfFlows();
     390                 :   }
     391                 : 
     392                 :   /**
     393                 :    * Notifies the builder that a particular themed widget exists
     394                 :    * at the given rectangle within the currently built display list.
     395                 :    * For certain appearance values (currently only
     396                 :    * NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR and NS_THEME_TOOLBAR) this gets
     397                 :    * called during every display list construction, for every themed widget of
     398                 :    * the right type within the display list, except for themed widgets which
     399                 :    * are transformed or have effects applied to them (e.g. CSS opacity or
     400                 :    * filters).
     401                 :    *
     402                 :    * @param aWidgetType the -moz-appearance value for the themed widget
     403                 :    * @param aRect the device-pixel rect relative to the widget's displayRoot
     404                 :    * for the themed widget
     405                 :    */
     406               0 :   void RegisterThemeGeometry(PRUint8 aWidgetType,
     407                 :                              const nsIntRect& aRect) {
     408               0 :     if (mIsPaintingToWindow && mPresShellStates.Length() == 1) {
     409               0 :       ThemeGeometry geometry(aWidgetType, aRect);
     410               0 :       mThemeGeometries.AppendElement(geometry);
     411                 :     }
     412               0 :   }
     413                 : 
     414                 :   /**
     415                 :    * Allocate memory in our arena. It will only be freed when this display list
     416                 :    * builder is destroyed. This memory holds nsDisplayItems. nsDisplayItem
     417                 :    * destructors are called as soon as the item is no longer used.
     418                 :    */
     419                 :   void* Allocate(size_t aSize);
     420                 :   
     421                 :   /**
     422                 :    * A helper class to temporarily set the value of
     423                 :    * mIsAtRootOfPseudoStackingContext.
     424                 :    */
     425                 :   class AutoIsRootSetter;
     426                 :   friend class AutoIsRootSetter;
     427                 :   class AutoIsRootSetter {
     428                 :   public:
     429               0 :     AutoIsRootSetter(nsDisplayListBuilder* aBuilder, bool aIsRoot)
     430               0 :       : mBuilder(aBuilder), mOldValue(aBuilder->mIsAtRootOfPseudoStackingContext) { 
     431               0 :       aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
     432               0 :     }
     433               0 :     ~AutoIsRootSetter() {
     434               0 :       mBuilder->mIsAtRootOfPseudoStackingContext = mOldValue;
     435               0 :     }
     436                 :   private:
     437                 :     nsDisplayListBuilder* mBuilder;
     438                 :     bool                  mOldValue;
     439                 :   };
     440                 : 
     441                 :   /**
     442                 :    * A helper class to temporarily set the value of mInTransform.
     443                 :    */
     444                 :   class AutoInTransformSetter;
     445                 :   friend class AutoInTransformSetter;
     446                 :   class AutoInTransformSetter {
     447                 :   public:
     448               0 :     AutoInTransformSetter(nsDisplayListBuilder* aBuilder, bool aInTransform)
     449               0 :       : mBuilder(aBuilder), mOldValue(aBuilder->mInTransform) { 
     450               0 :       aBuilder->mInTransform = aInTransform;
     451               0 :     }
     452               0 :     ~AutoInTransformSetter() {
     453               0 :       mBuilder->mInTransform = mOldValue;
     454               0 :     }
     455                 :   private:
     456                 :     nsDisplayListBuilder* mBuilder;
     457                 :     bool                  mOldValue;
     458                 :   };  
     459                 :   
     460                 :   // Helpers for tables
     461               0 :   nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; }
     462               0 :   void SetCurrentTableItem(nsDisplayTableItem* aTableItem) { mCurrentTableItem = aTableItem; }
     463                 : 
     464               0 :   NS_DECLARE_FRAME_PROPERTY(OutOfFlowDirtyRectProperty, nsIFrame::DestroyRect)
     465                 : 
     466               0 :   nsPresContext* CurrentPresContext() {
     467               0 :     return CurrentPresShellState()->mPresShell->GetPresContext();
     468                 :   }
     469                 : 
     470                 :   /**
     471                 :    * Accumulates the bounds of box frames that have moz-appearance
     472                 :    * -moz-win-exclude-glass style. Used in setting glass margins on
     473                 :    * Windows.
     474                 :    */  
     475               0 :   void AddExcludedGlassRegion(nsRect &bounds) {
     476               0 :     mExcludedGlassRegion.Or(mExcludedGlassRegion, bounds);
     477               0 :   }
     478               0 :   const nsRegion& GetExcludedGlassRegion() {
     479               0 :     return mExcludedGlassRegion;
     480                 :   }
     481                 : 
     482                 : private:
     483                 :   void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame,
     484                 :                                     const nsRect& aDirtyRect);
     485                 : 
     486               0 :   struct PresShellState {
     487                 :     nsIPresShell* mPresShell;
     488                 :     nsIFrame*     mCaretFrame;
     489                 :     PRUint32      mFirstFrameMarkedForDisplay;
     490                 :     bool          mIsBackgroundOnly;
     491                 :   };
     492               0 :   PresShellState* CurrentPresShellState() {
     493               0 :     NS_ASSERTION(mPresShellStates.Length() > 0,
     494                 :                  "Someone forgot to enter a presshell");
     495               0 :     return &mPresShellStates[mPresShellStates.Length() - 1];
     496                 :   }
     497                 : 
     498                 :   FrameLayerBuilder              mLayerBuilder;
     499                 :   nsIFrame*                      mReferenceFrame;
     500                 :   nsIFrame*                      mIgnoreScrollFrame;
     501                 :   PLArenaPool                    mPool;
     502                 :   nsCOMPtr<nsISelection>         mBoundingSelection;
     503                 :   nsAutoTArray<PresShellState,8> mPresShellStates;
     504                 :   nsAutoTArray<nsIFrame*,100>    mFramesMarkedForDisplay;
     505                 :   nsAutoTArray<ThemeGeometry,2>  mThemeGeometries;
     506                 :   nsDisplayTableItem*            mCurrentTableItem;
     507                 :   const nsRegion*                mFinalTransparentRegion;
     508                 :   nsRect                         mDisplayPort;
     509                 :   nsRegion                       mExcludedGlassRegion;
     510                 :   Mode                           mMode;
     511                 :   bool                           mBuildCaret;
     512                 :   bool                           mIgnoreSuppression;
     513                 :   bool                           mHadToIgnoreSuppression;
     514                 :   bool                           mIsAtRootOfPseudoStackingContext;
     515                 :   bool                           mIncludeAllOutOfFlows;
     516                 :   bool                           mSelectedFramesOnly;
     517                 :   bool                           mAccurateVisibleRegions;
     518                 :   // True when we're building a display list that's directly or indirectly
     519                 :   // under an nsDisplayTransform
     520                 :   bool                           mInTransform;
     521                 :   bool                           mSyncDecodeImages;
     522                 :   bool                           mIsPaintingToWindow;
     523                 :   bool                           mSnappingEnabled;
     524                 :   bool                           mHasDisplayPort;
     525                 :   bool                           mHasFixedItems;
     526                 : };
     527                 : 
     528                 : class nsDisplayItem;
     529                 : class nsDisplayList;
     530                 : /**
     531                 :  * nsDisplayItems are put in singly-linked lists rooted in an nsDisplayList.
     532                 :  * nsDisplayItemLink holds the link. The lists are linked from lowest to
     533                 :  * highest in z-order.
     534                 :  */
     535                 : class nsDisplayItemLink {
     536                 :   // This is never instantiated directly, so no need to count constructors and
     537                 :   // destructors.
     538                 : protected:
     539               0 :   nsDisplayItemLink() : mAbove(nsnull) {}
     540                 :   nsDisplayItem* mAbove;  
     541                 :   
     542                 :   friend class nsDisplayList;
     543                 : };
     544                 : 
     545                 : /**
     546                 :  * This is the unit of rendering and event testing. Each instance of this
     547                 :  * class represents an entity that can be drawn on the screen, e.g., a
     548                 :  * frame's CSS background, or a frame's text string.
     549                 :  * 
     550                 :  * nsDisplayListItems can be containers --- i.e., they can perform hit testing
     551                 :  * and painting by recursively traversing a list of child items.
     552                 :  * 
     553                 :  * These are arena-allocated during display list construction. A typical
     554                 :  * subclass would just have a frame pointer, so its object would be just three
     555                 :  * pointers (vtable, next-item, frame).
     556                 :  * 
     557                 :  * Display items belong to a list at all times (except temporarily as they
     558                 :  * move from one list to another).
     559                 :  */
     560                 : class nsDisplayItem : public nsDisplayItemLink {
     561                 : public:
     562                 :   typedef mozilla::layers::FrameMetrics::ViewID ViewID;
     563                 :   typedef mozilla::layers::Layer Layer;
     564                 :   typedef mozilla::layers::LayerManager LayerManager;
     565                 :   typedef mozilla::LayerState LayerState;
     566                 : 
     567                 :   // This is never instantiated directly (it has pure virtual methods), so no
     568                 :   // need to count constructors and destructors.
     569               0 :   nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
     570                 :     : mFrame(aFrame)
     571                 : #ifdef MOZ_DUMP_PAINTING
     572               0 :     , mPainted(false)
     573                 : #endif
     574                 :   {
     575               0 :     if (aFrame) {
     576               0 :       mToReferenceFrame = aBuilder->ToReferenceFrame(aFrame);
     577                 :     }
     578               0 :   }
     579               0 :   virtual ~nsDisplayItem() {}
     580                 :   
     581               0 :   void* operator new(size_t aSize,
     582                 :                      nsDisplayListBuilder* aBuilder) CPP_THROW_NEW {
     583               0 :     return aBuilder->Allocate(aSize);
     584                 :   }
     585                 : 
     586                 : // Contains all the type integers for each display list item type
     587                 : #include "nsDisplayItemTypes.h"
     588                 : 
     589                 :   struct HitTestState {
     590                 :     typedef nsTArray<ViewID> ShadowArray;
     591                 : 
     592               0 :     HitTestState(ShadowArray* aShadows = NULL)
     593               0 :       : mShadows(aShadows) {
     594               0 :     }
     595                 : 
     596               0 :     ~HitTestState() {
     597               0 :       NS_ASSERTION(mItemBuffer.Length() == 0,
     598                 :                    "mItemBuffer should have been cleared");
     599               0 :     }
     600                 : 
     601                 :     nsAutoTArray<nsDisplayItem*, 100> mItemBuffer;
     602                 : 
     603                 :     // It is sometimes useful to hit test for frames that are not in this
     604                 :     // process. Display items may append IDs into this array if it is
     605                 :     // non-null.
     606                 :     ShadowArray* mShadows;
     607                 :   };
     608                 : 
     609                 :   /**
     610                 :    * Some consecutive items should be rendered together as a unit, e.g.,
     611                 :    * outlines for the same element. For this, we need a way for items to
     612                 :    * identify their type. We use the type for other purposes too.
     613                 :    */
     614                 :   virtual Type GetType() = 0;
     615                 :   /**
     616                 :    * If this returns a non-zero value, then pairing this with the
     617                 :    * GetUnderlyingFrame() pointer gives a key that uniquely identifies
     618                 :    * this display item in the display item tree.
     619                 :    * This will only return a zero value for items which wrap display lists
     620                 :    * and do not create a CSS stacking context, therefore requiring
     621                 :    * display items to be individually wrapped --- currently nsDisplayClip
     622                 :    * and nsDisplayClipRoundedRect only.
     623                 :    */
     624               0 :   virtual PRUint32 GetPerFrameKey() { return PRUint32(GetType()); }
     625                 :   /**
     626                 :    * This is called after we've constructed a display list for event handling.
     627                 :    * When this is called, we've already ensured that aRect intersects the
     628                 :    * item's bounds.
     629                 :    *
     630                 :    * @param aRect the point or rect being tested, relative to the reference
     631                 :    * frame. If the width and height are both 1 app unit, it indicates we're
     632                 :    * hit testing a point, not a rect.
     633                 :    * @param aState must point to a HitTestState. If you don't have one,
     634                 :    * just create one with the default constructor and pass it in.
     635                 :    * @param aOutFrames each item appends the frame(s) in this display item that
     636                 :    * the rect is considered over (if any) to aOutFrames.
     637                 :    */
     638               0 :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
     639               0 :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {}
     640                 :   /**
     641                 :    * @return the frame that this display item is based on. This is used to sort
     642                 :    * items by z-index and content order and for some other uses. For some items
     643                 :    * that wrap item lists, this could return nsnull because there is no single
     644                 :    * underlying frame; for leaf items it will never return nsnull.
     645                 :    */
     646               0 :   inline nsIFrame* GetUnderlyingFrame() const { return mFrame; }
     647                 :   /**
     648                 :    * The default bounds is the frame border rect.
     649                 :    * @return a rectangle relative to aBuilder->ReferenceFrame() that
     650                 :    * contains the area drawn by this display item
     651                 :    */
     652               0 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
     653               0 :     return nsRect(ToReferenceFrame(), GetUnderlyingFrame()->GetSize());
     654                 :   }
     655                 :   /**
     656                 :    * @return a region of the item that is opaque --- every pixel painted
     657                 :    * with an opaque color. This is useful for determining when one piece
     658                 :    * of content completely obscures another so that we can do occlusion
     659                 :    * culling.
     660                 :    */
     661               0 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
     662                 :                                    bool* aForceTransparentSurface = nsnull)
     663                 :   {
     664               0 :     if (aForceTransparentSurface) {
     665               0 :       *aForceTransparentSurface = false;
     666                 :     }
     667               0 :     return nsRegion();
     668                 :   }
     669                 :   /**
     670                 :    * If this returns true, then aColor is set to the uniform color
     671                 :    * @return true if the item is guaranteed to paint every pixel in its
     672                 :    * bounds with the same (possibly translucent) color
     673                 :    */
     674               0 :   virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { return false; }
     675                 :   /**
     676                 :    * @return false if the painting performed by the item is invariant
     677                 :    * when the item's underlying frame is moved relative to aFrame.
     678                 :    * In other words, if you render the item at locations P and P', the rendering
     679                 :    * only differs by the translation.
     680                 :    * It return true for all wrapped lists.
     681                 :    */
     682               0 :   virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
     683                 :                                                 nsIFrame* aFrame)
     684               0 :   { return false; }
     685                 :   /**
     686                 :    * @return true if the contents of this item are rendered fixed relative
     687                 :    * to the nearest viewport *and* they cover the viewport's scrollport.
     688                 :    * Only return true if the contents actually vary when scrolling in the viewport.
     689                 :    */
     690               0 :   virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder)
     691               0 :   { return false; }
     692                 : 
     693                 :   /**
     694                 :    * @return LAYER_NONE if BuildLayer will return null. In this case
     695                 :    * there is no layer for the item, and Paint should be called instead
     696                 :    * to paint the content using Thebes.
     697                 :    * Return LAYER_INACTIVE if there is a layer --- BuildLayer will
     698                 :    * not return null (unless there's an error) --- but the layer contents
     699                 :    * are not changing frequently. In this case it makes sense to composite
     700                 :    * the layer into a ThebesLayer with other content, so we don't have to
     701                 :    * recomposite it every time we paint.
     702                 :    * Note: GetLayerState is only allowed to return LAYER_INACTIVE if all
     703                 :    * descendant display items returned LAYER_INACTIVE or LAYER_NONE. Also,
     704                 :    * all descendant display item frames must have an active scrolled root
     705                 :    * that's either the same as this item's frame's active scrolled root, or
     706                 :    * a descendant of this item's frame. This ensures that the entire
     707                 :    * set of display items can be collapsed onto a single ThebesLayer.
     708                 :    * Return LAYER_ACTIVE if the layer is active, that is, its contents are
     709                 :    * changing frequently. In this case it makes sense to keep the layer
     710                 :    * as a separate buffer in VRAM and composite it into the destination
     711                 :    * every time we paint.
     712                 :    */
     713               0 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
     714                 :                                    LayerManager* aManager)
     715               0 :   { return mozilla::LAYER_NONE; }
     716                 :   /**
     717                 :    * Actually paint this item to some rendering context.
     718                 :    * Content outside mVisibleRect need not be painted.
     719                 :    * aCtx must be set up as for nsDisplayList::Paint.
     720                 :    */
     721               0 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) {}
     722                 : 
     723                 : #ifdef MOZ_DUMP_PAINTING
     724                 :   /**
     725                 :    * Mark this display item as being painted via FrameLayerBuilder::DrawThebesLayer.
     726                 :    */
     727               0 :   bool Painted() { return mPainted; }
     728                 : 
     729                 :   /**
     730                 :    * Check if this display item has been painted.
     731                 :    */
     732               0 :   void SetPainted() { mPainted = true; }
     733                 : #endif
     734                 : 
     735                 :   /**
     736                 :    * Get the layer drawn by this display item. Call this only if
     737                 :    * GetLayerState() returns something other than LAYER_NONE.
     738                 :    * If GetLayerState returned LAYER_NONE then Paint will be called
     739                 :    * instead.
     740                 :    * This is called while aManager is in the construction phase.
     741                 :    * 
     742                 :    * The caller (nsDisplayList) is responsible for setting the visible
     743                 :    * region of the layer.
     744                 :    *
     745                 :    * @param aContainerParameters should be passed to
     746                 :    * FrameLayerBuilder::BuildContainerLayerFor if a ContainerLayer is
     747                 :    * constructed.
     748                 :    */
     749                 :   typedef mozilla::FrameLayerBuilder::ContainerParameters ContainerParameters;
     750               0 :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
     751                 :                                              LayerManager* aManager,
     752                 :                                              const ContainerParameters& aContainerParameters)
     753               0 :   { return nsnull; }
     754                 : 
     755                 :   /**
     756                 :    * On entry, aVisibleRegion contains the region (relative to ReferenceFrame())
     757                 :    * which may be visible. If the display item opaquely covers an area, it
     758                 :    * can remove that area from aVisibleRegion before returning.
     759                 :    * nsDisplayList::ComputeVisibility automatically subtracts the region
     760                 :    * returned by GetOpaqueRegion, and automatically removes items whose bounds
     761                 :    * do not intersect the visible area, so implementations of
     762                 :    * nsDisplayItem::ComputeVisibility do not need to do these things.
     763                 :    * nsDisplayList::ComputeVisibility will already have set mVisibleRect on
     764                 :    * this item to the intersection of *aVisibleRegion and this item's bounds.
     765                 :    * We rely on that, so this should only be called by
     766                 :    * nsDisplayList::ComputeVisibility or nsDisplayItem::RecomputeVisibility.
     767                 :    * aAllowVisibleRegionExpansion is a rect where we are allowed to
     768                 :    * expand the visible region and is only used for making sure the
     769                 :    * background behind a plugin is visible.
     770                 :    *
     771                 :    * @return true if the item is visible, false if no part of the item
     772                 :    * is visible.
     773                 :    */
     774               0 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
     775                 :                                    nsRegion* aVisibleRegion,
     776                 :                                    const nsRect& aAllowVisibleRegionExpansion)
     777               0 :   { return !mVisibleRect.IsEmpty(); }
     778                 : 
     779                 :   /**
     780                 :    * Try to merge with the other item (which is below us in the display
     781                 :    * list). This gets used by nsDisplayClip to coalesce clipping operations
     782                 :    * (optimization), by nsDisplayOpacity to merge rendering for the same
     783                 :    * content element into a single opacity group (correctness), and will be
     784                 :    * used by nsDisplayOutline to merge multiple outlines for the same element
     785                 :    * (also for correctness).
     786                 :    * @return true if the merge was successful and the other item should be deleted
     787                 :    */
     788               0 :   virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) {
     789               0 :     return false;
     790                 :   }
     791                 : 
     792                 :   /**
     793                 :    * During the visibility computation and after TryMerge, display lists may
     794                 :    * return true here to flatten themselves away, removing them. This
     795                 :    * flattening is distinctly different from FlattenTo, which occurs before
     796                 :    * items are merged together.
     797                 :    */
     798               0 :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) {
     799               0 :     return false;
     800                 :   }
     801                 : 
     802                 :   /**
     803                 :    * If this is a leaf item we return null, otherwise we return the wrapped
     804                 :    * list.
     805                 :    */
     806               0 :   virtual nsDisplayList* GetList() { return nsnull; }
     807                 : 
     808                 :   /**
     809                 :    * Returns the visible rect. Should only be called after ComputeVisibility
     810                 :    * has happened.
     811                 :    */
     812               0 :   const nsRect& GetVisibleRect() { return mVisibleRect; }
     813                 :   
     814                 : #ifdef MOZ_DUMP_PAINTING
     815                 :   /**
     816                 :    * For debugging and stuff
     817                 :    */
     818                 :   virtual const char* Name() = 0;
     819                 : #endif
     820                 : 
     821               0 :   nsDisplayItem* GetAbove() { return mAbove; }
     822                 : 
     823                 :   /**
     824                 :    * Like ComputeVisibility, but does the work that nsDisplayList
     825                 :    * does per-item:
     826                 :    * -- Intersects GetBounds with aVisibleRegion and puts the result
     827                 :    * in mVisibleRect
     828                 :    * -- Subtracts bounds from aVisibleRegion if the item is opaque
     829                 :    */
     830                 :   bool RecomputeVisibility(nsDisplayListBuilder* aBuilder,
     831                 :                              nsRegion* aVisibleRegion);
     832                 : 
     833                 :   /**
     834                 :    * Returns the result of aBuilder->ToReferenceFrame(GetUnderlyingFrame())
     835                 :    */
     836               0 :   const nsPoint& ToReferenceFrame() const {
     837               0 :     NS_ASSERTION(mFrame, "No frame?");
     838               0 :     return mToReferenceFrame;
     839                 :   }
     840                 : 
     841                 :   /**
     842                 :    * Checks if this display item (or any children) contains content that might
     843                 :    * be rendered with component alpha (e.g. subpixel antialiasing). Returns the
     844                 :    * bounds of the area that needs component alpha, or an empty rect if nothing
     845                 :    * in the item does.
     846                 :    */
     847               0 :   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) { return nsRect(); }
     848                 : 
     849                 :   /**
     850                 :    * Disable usage of component alpha. Currently only relevant for items that have text.
     851                 :    */
     852               0 :   virtual void DisableComponentAlpha() {}
     853                 : 
     854                 : protected:
     855                 :   friend class nsDisplayList;
     856                 :   
     857                 :   nsDisplayItem() {
     858                 :     mAbove = nsnull;
     859                 :   }
     860                 :   
     861                 :   nsIFrame* mFrame;
     862                 :   // Result of ToReferenceFrame(mFrame), if mFrame is non-null
     863                 :   nsPoint   mToReferenceFrame;
     864                 :   // This is the rectangle that needs to be painted.
     865                 :   // nsDisplayList::ComputeVisibility sets this to the visible region
     866                 :   // of the item by intersecting the current visible region with the bounds
     867                 :   // of the item. Paint implementations can use this to limit their drawing.
     868                 :   // Guaranteed to be contained in GetBounds().
     869                 :   nsRect    mVisibleRect;
     870                 : #ifdef MOZ_DUMP_PAINTING
     871                 :   // True if this frame has been painted.
     872                 :   bool      mPainted;
     873                 : #endif
     874                 : };
     875                 : 
     876                 : /**
     877                 :  * Manages a singly-linked list of display list items.
     878                 :  * 
     879                 :  * mSentinel is the sentinel list value, the first value in the null-terminated
     880                 :  * linked list of items. mTop is the last item in the list (whose 'above'
     881                 :  * pointer is null). This class has no virtual methods. So list objects are just
     882                 :  * two pointers.
     883                 :  * 
     884                 :  * Stepping upward through this list is very fast. Stepping downward is very
     885                 :  * slow so we don't support it. The methods that need to step downward
     886                 :  * (HitTest(), ComputeVisibility()) internally build a temporary array of all
     887                 :  * the items while they do the downward traversal, so overall they're still
     888                 :  * linear time. We have optimized for efficient AppendToTop() of both
     889                 :  * items and lists, with minimal codesize. AppendToBottom() is efficient too.
     890                 :  */
     891                 : class nsDisplayList {
     892                 : public:
     893                 :   typedef mozilla::layers::Layer Layer;
     894                 :   typedef mozilla::layers::LayerManager LayerManager;
     895                 :   typedef mozilla::layers::ThebesLayer ThebesLayer;
     896                 : 
     897                 :   /**
     898                 :    * Create an empty list.
     899                 :    */
     900               0 :   nsDisplayList() :
     901               0 :     mIsOpaque(false)
     902                 :   {
     903               0 :     mTop = &mSentinel;
     904               0 :     mSentinel.mAbove = nsnull;
     905                 : #ifdef DEBUG
     906               0 :     mDidComputeVisibility = false;
     907                 : #endif
     908               0 :   }
     909               0 :   ~nsDisplayList() {
     910               0 :     if (mSentinel.mAbove) {
     911               0 :       NS_WARNING("Nonempty list left over?");
     912                 :     }
     913               0 :     DeleteAll();
     914               0 :   }
     915                 : 
     916                 :   /**
     917                 :    * Append an item to the top of the list. The item must not currently
     918                 :    * be in a list and cannot be null.
     919                 :    */
     920               0 :   void AppendToTop(nsDisplayItem* aItem) {
     921               0 :     NS_ASSERTION(aItem, "No item to append!");
     922               0 :     NS_ASSERTION(!aItem->mAbove, "Already in a list!");
     923               0 :     mTop->mAbove = aItem;
     924               0 :     mTop = aItem;
     925               0 :   }
     926                 :   
     927                 :   /**
     928                 :    * Append a new item to the top of the list. If the item is null we return
     929                 :    * NS_ERROR_OUT_OF_MEMORY. The intended usage is AppendNewToTop(new ...);
     930                 :    */
     931               0 :   nsresult AppendNewToTop(nsDisplayItem* aItem) {
     932               0 :     if (!aItem)
     933               0 :       return NS_ERROR_OUT_OF_MEMORY;
     934               0 :     AppendToTop(aItem);
     935               0 :     return NS_OK;
     936                 :   }
     937                 :   
     938                 :   /**
     939                 :    * Append a new item to the bottom of the list. If the item is null we return
     940                 :    * NS_ERROR_OUT_OF_MEMORY. The intended usage is AppendNewToBottom(new ...);
     941                 :    */
     942               0 :   nsresult AppendNewToBottom(nsDisplayItem* aItem) {
     943               0 :     if (!aItem)
     944               0 :       return NS_ERROR_OUT_OF_MEMORY;
     945               0 :     AppendToBottom(aItem);
     946               0 :     return NS_OK;
     947                 :   }
     948                 :   
     949                 :   /**
     950                 :    * Append a new item to the bottom of the list. The item must be non-null
     951                 :    * and not already in a list.
     952                 :    */
     953               0 :   void AppendToBottom(nsDisplayItem* aItem) {
     954               0 :     NS_ASSERTION(aItem, "No item to append!");
     955               0 :     NS_ASSERTION(!aItem->mAbove, "Already in a list!");
     956               0 :     aItem->mAbove = mSentinel.mAbove;
     957               0 :     mSentinel.mAbove = aItem;
     958               0 :     if (mTop == &mSentinel) {
     959               0 :       mTop = aItem;
     960                 :     }
     961               0 :   }
     962                 :   
     963                 :   /**
     964                 :    * Removes all items from aList and appends them to the top of this list
     965                 :    */
     966               0 :   void AppendToTop(nsDisplayList* aList) {
     967               0 :     if (aList->mSentinel.mAbove) {
     968               0 :       mTop->mAbove = aList->mSentinel.mAbove;
     969               0 :       mTop = aList->mTop;
     970               0 :       aList->mTop = &aList->mSentinel;
     971               0 :       aList->mSentinel.mAbove = nsnull;
     972                 :     }
     973               0 :   }
     974                 :   
     975                 :   /**
     976                 :    * Removes all items from aList and prepends them to the bottom of this list
     977                 :    */
     978               0 :   void AppendToBottom(nsDisplayList* aList) {
     979               0 :     if (aList->mSentinel.mAbove) {
     980               0 :       aList->mTop->mAbove = mSentinel.mAbove;
     981               0 :       mTop = aList->mTop;
     982               0 :       mSentinel.mAbove = aList->mSentinel.mAbove;
     983                 :            
     984               0 :       aList->mTop = &aList->mSentinel;
     985               0 :       aList->mSentinel.mAbove = nsnull;
     986                 :     }
     987               0 :   }
     988                 :   
     989                 :   /**
     990                 :    * Remove an item from the bottom of the list and return it.
     991                 :    */
     992                 :   nsDisplayItem* RemoveBottom();
     993                 :   
     994                 :   /**
     995                 :    * Remove all items from the list and call their destructors.
     996                 :    */
     997                 :   void DeleteAll();
     998                 :   
     999                 :   /**
    1000                 :    * @return the item at the top of the list, or null if the list is empty
    1001                 :    */
    1002               0 :   nsDisplayItem* GetTop() const {
    1003               0 :     return mTop != &mSentinel ? static_cast<nsDisplayItem*>(mTop) : nsnull;
    1004                 :   }
    1005                 :   /**
    1006                 :    * @return the item at the bottom of the list, or null if the list is empty
    1007                 :    */
    1008               0 :   nsDisplayItem* GetBottom() const { return mSentinel.mAbove; }
    1009               0 :   bool IsEmpty() const { return mTop == &mSentinel; }
    1010                 :   
    1011                 :   /**
    1012                 :    * This is *linear time*!
    1013                 :    * @return the number of items in the list
    1014                 :    */
    1015                 :   PRUint32 Count() const;
    1016                 :   /**
    1017                 :    * Stable sort the list by the z-order of GetUnderlyingFrame() on
    1018                 :    * each item. 'auto' is counted as zero. Content order is used as the
    1019                 :    * secondary order.
    1020                 :    * @param aCommonAncestor a common ancestor of all the content elements
    1021                 :    * associated with the display items, for speeding up tree order
    1022                 :    * checks, or nsnull if not known; it's only a hint, if it is not an
    1023                 :    * ancestor of some elements, then we lose performance but not correctness
    1024                 :    */
    1025                 :   void SortByZOrder(nsDisplayListBuilder* aBuilder, nsIContent* aCommonAncestor);
    1026                 :   /**
    1027                 :    * Stable sort the list by the tree order of the content of
    1028                 :    * GetUnderlyingFrame() on each item. z-index is ignored.
    1029                 :    * @param aCommonAncestor a common ancestor of all the content elements
    1030                 :    * associated with the display items, for speeding up tree order
    1031                 :    * checks, or nsnull if not known; it's only a hint, if it is not an
    1032                 :    * ancestor of some elements, then we lose performance but not correctness
    1033                 :    */
    1034                 :   void SortByContentOrder(nsDisplayListBuilder* aBuilder, nsIContent* aCommonAncestor);
    1035                 : 
    1036                 :   /**
    1037                 :    * Generic stable sort. Take care, because some of the items might be nsDisplayLists
    1038                 :    * themselves.
    1039                 :    * aCmp(item1, item2) should return true if item1 <= item2. We sort the items
    1040                 :    * into increasing order.
    1041                 :    */
    1042                 :   typedef bool (* SortLEQ)(nsDisplayItem* aItem1, nsDisplayItem* aItem2,
    1043                 :                              void* aClosure);
    1044                 :   void Sort(nsDisplayListBuilder* aBuilder, SortLEQ aCmp, void* aClosure);
    1045                 : 
    1046                 :   /**
    1047                 :    * Compute visiblity for the items in the list.
    1048                 :    * We put this logic here so it can be shared by top-level
    1049                 :    * painting and also display items that maintain child lists.
    1050                 :    * This is also a good place to put ComputeVisibility-related logic
    1051                 :    * that must be applied to every display item. In particular, this
    1052                 :    * sets mVisibleRect on each display item.
    1053                 :    * This sets mIsOpaque if the entire visible area of this list has
    1054                 :    * been removed from aVisibleRegion when we return.
    1055                 :    * This does not remove any items from the list, so we can recompute
    1056                 :    * visiblity with different regions later (see
    1057                 :    * FrameLayerBuilder::DrawThebesLayer).
    1058                 :    * 
    1059                 :    * @param aVisibleRegion the area that is visible, relative to the
    1060                 :    * reference frame; on return, this contains the area visible under the list.
    1061                 :    * I.e., opaque contents of this list are subtracted from aVisibleRegion.
    1062                 :    * @param aListVisibleBounds must be equal to the bounds of the intersection
    1063                 :    * of aVisibleRegion and GetBounds() for this list.
    1064                 :    * @return true if any item in the list is visible.
    1065                 :    */
    1066                 :   bool ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
    1067                 :                                      nsRegion* aVisibleRegion,
    1068                 :                                      const nsRect& aListVisibleBounds,
    1069                 :                                      const nsRect& aAllowVisibleRegionExpansion);
    1070                 : 
    1071                 :   /**
    1072                 :    * As ComputeVisibilityForSublist, but computes visibility for a root
    1073                 :    * list (a list that does not belong to an nsDisplayItem).
    1074                 :    *
    1075                 :    * @param aVisibleRegion the area that is visible
    1076                 :    */
    1077                 :   bool ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
    1078                 :                                   nsRegion* aVisibleRegion);
    1079                 : 
    1080                 :   /**
    1081                 :    * Returns true if the visible region output from ComputeVisiblity was
    1082                 :    * empty, i.e. everything visible in this list is opaque.
    1083                 :    */
    1084               0 :   bool IsOpaque() const {
    1085               0 :     NS_ASSERTION(mDidComputeVisibility, "Need to have called ComputeVisibility");
    1086               0 :     return mIsOpaque;
    1087                 :   }
    1088                 : 
    1089                 :   /**
    1090                 :    * Returns true if during ComputeVisibility any display item
    1091                 :    * set the surface to be transparent.
    1092                 :    */
    1093               0 :   bool NeedsTransparentSurface() const {
    1094               0 :     NS_ASSERTION(mDidComputeVisibility, "Need to have called ComputeVisibility");
    1095               0 :     return mForceTransparentSurface;
    1096                 :   }
    1097                 :   /**
    1098                 :    * Paint the list to the rendering context. We assume that (0,0) in aCtx
    1099                 :    * corresponds to the origin of the reference frame. For best results,
    1100                 :    * aCtx's current transform should make (0,0) pixel-aligned. The
    1101                 :    * rectangle in aDirtyRect is painted, which *must* be contained in the
    1102                 :    * dirty rect used to construct the display list.
    1103                 :    * 
    1104                 :    * If aFlags contains PAINT_USE_WIDGET_LAYERS and
    1105                 :    * ShouldUseWidgetLayerManager() is set, then we will paint using
    1106                 :    * the reference frame's widget's layer manager (and ctx may be null),
    1107                 :    * otherwise we will use a temporary BasicLayerManager and ctx must
    1108                 :    * not be null.
    1109                 :    * 
    1110                 :    * If PAINT_FLUSH_LAYERS is set, we'll force a completely new layer
    1111                 :    * tree to be created for this paint *and* the next paint.
    1112                 :    * 
    1113                 :    * If PAINT_EXISTING_TRANSACTION is set, the reference frame's widget's
    1114                 :    * layer manager has already had BeginTransaction() called on it and
    1115                 :    * we should not call it again.
    1116                 :    *
    1117                 :    * ComputeVisibility must be called before Paint.
    1118                 :    * 
    1119                 :    * This must only be called on the root display list of the display list
    1120                 :    * tree.
    1121                 :    */
    1122                 :   enum {
    1123                 :     PAINT_DEFAULT = 0,
    1124                 :     PAINT_USE_WIDGET_LAYERS = 0x01,
    1125                 :     PAINT_FLUSH_LAYERS = 0x02,
    1126                 :     PAINT_EXISTING_TRANSACTION = 0x04
    1127                 :   };
    1128                 :   void PaintRoot(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
    1129                 :                  PRUint32 aFlags) const;
    1130                 :   /**
    1131                 :    * Like PaintRoot, but used for internal display sublists.
    1132                 :    * aForFrame is the frame that the list is associated with.
    1133                 :    */
    1134                 :   void PaintForFrame(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
    1135                 :                      nsIFrame* aForFrame, PRUint32 aFlags) const;
    1136                 :   /**
    1137                 :    * Get the bounds. Takes the union of the bounds of all children.
    1138                 :    */
    1139                 :   nsRect GetBounds(nsDisplayListBuilder* aBuilder) const;
    1140                 :   /**
    1141                 :    * Find the topmost display item that returns a non-null frame, and return
    1142                 :    * the frame.
    1143                 :    */
    1144                 :   void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    1145                 :                nsDisplayItem::HitTestState* aState,
    1146                 :                nsTArray<nsIFrame*> *aOutFrames) const;
    1147                 : 
    1148                 : #ifdef DEBUG
    1149               0 :   bool DidComputeVisibility() const { return mDidComputeVisibility; }
    1150                 : #endif
    1151                 : 
    1152                 : private:
    1153                 :   // This class is only used on stack, so we don't have to worry about leaking
    1154                 :   // it.  Don't let us be heap-allocated!
    1155                 :   void* operator new(size_t sz) CPP_THROW_NEW;
    1156                 :   
    1157                 :   // Utility function used to massage the list during ComputeVisibility.
    1158                 :   void FlattenTo(nsTArray<nsDisplayItem*>* aElements);
    1159                 :   // Utility function used to massage the list during sorting, to rewrite
    1160                 :   // any wrapper items with null GetUnderlyingFrame
    1161                 :   void ExplodeAnonymousChildLists(nsDisplayListBuilder* aBuilder);
    1162                 :   
    1163                 :   nsDisplayItemLink  mSentinel;
    1164                 :   nsDisplayItemLink* mTop;
    1165                 : 
    1166                 :   // This is set by ComputeVisibility
    1167                 :   nsRect mVisibleRect;
    1168                 :   // This is set to true by ComputeVisibility if the final visible region
    1169                 :   // is empty (i.e. everything that was visible is covered by some
    1170                 :   // opaque content in this list).
    1171                 :   bool mIsOpaque;
    1172                 :   // This is set to true by ComputeVisibility if any display item in this
    1173                 :   // list needs to force the surface to be transparent (e.g. if the
    1174                 :   // item "punch holes" on the surface by clearing part of its area).
    1175                 :   bool mForceTransparentSurface;
    1176                 : #ifdef DEBUG
    1177                 :   bool mDidComputeVisibility;
    1178                 : #endif
    1179                 : };
    1180                 : 
    1181                 : /**
    1182                 :  * This is passed as a parameter to nsIFrame::BuildDisplayList. That method
    1183                 :  * will put any generated items onto the appropriate list given here. It's
    1184                 :  * basically just a collection with one list for each separate stacking layer.
    1185                 :  * The lists themselves are external to this object and thus can be shared
    1186                 :  * with others. Some of the list pointers may even refer to the same list.
    1187                 :  */
    1188                 : class nsDisplayListSet {
    1189                 : public:
    1190                 :   /**
    1191                 :    * @return a list where one should place the border and/or background for
    1192                 :    * this frame (everything from steps 1 and 2 of CSS 2.1 appendix E)
    1193                 :    */
    1194               0 :   nsDisplayList* BorderBackground() const { return mBorderBackground; }
    1195                 :   /**
    1196                 :    * @return a list where one should place the borders and/or backgrounds for
    1197                 :    * block-level in-flow descendants (step 4 of CSS 2.1 appendix E)
    1198                 :    */
    1199               0 :   nsDisplayList* BlockBorderBackgrounds() const { return mBlockBorderBackgrounds; }
    1200                 :   /**
    1201                 :    * @return a list where one should place descendant floats (step 5 of
    1202                 :    * CSS 2.1 appendix E)
    1203                 :    */
    1204               0 :   nsDisplayList* Floats() const { return mFloats; }
    1205                 :   /**
    1206                 :    * @return a list where one should place the (pseudo) stacking contexts 
    1207                 :    * for descendants of this frame (everything from steps 3, 7 and 8
    1208                 :    * of CSS 2.1 appendix E)
    1209                 :    */
    1210               0 :   nsDisplayList* PositionedDescendants() const { return mPositioned; }
    1211                 :   /**
    1212                 :    * @return a list where one should place the outlines
    1213                 :    * for this frame and its descendants (step 9 of CSS 2.1 appendix E)
    1214                 :    */
    1215               0 :   nsDisplayList* Outlines() const { return mOutlines; }
    1216                 :   /**
    1217                 :    * @return a list where one should place all other content
    1218                 :    */
    1219               0 :   nsDisplayList* Content() const { return mContent; }
    1220                 :   
    1221               0 :   nsDisplayListSet(nsDisplayList* aBorderBackground,
    1222                 :                    nsDisplayList* aBlockBorderBackgrounds,
    1223                 :                    nsDisplayList* aFloats,
    1224                 :                    nsDisplayList* aContent,
    1225                 :                    nsDisplayList* aPositionedDescendants,
    1226                 :                    nsDisplayList* aOutlines) :
    1227                 :      mBorderBackground(aBorderBackground),
    1228                 :      mBlockBorderBackgrounds(aBlockBorderBackgrounds),
    1229                 :      mFloats(aFloats),
    1230                 :      mContent(aContent),
    1231                 :      mPositioned(aPositionedDescendants),
    1232               0 :      mOutlines(aOutlines) {
    1233               0 :   }
    1234                 : 
    1235                 :   /**
    1236                 :    * A copy constructor that lets the caller override the BorderBackground
    1237                 :    * list.
    1238                 :    */  
    1239               0 :   nsDisplayListSet(const nsDisplayListSet& aLists,
    1240                 :                    nsDisplayList* aBorderBackground) :
    1241                 :      mBorderBackground(aBorderBackground),
    1242               0 :      mBlockBorderBackgrounds(aLists.BlockBorderBackgrounds()),
    1243               0 :      mFloats(aLists.Floats()),
    1244               0 :      mContent(aLists.Content()),
    1245               0 :      mPositioned(aLists.PositionedDescendants()),
    1246               0 :      mOutlines(aLists.Outlines()) {
    1247               0 :   }
    1248                 :   
    1249                 :   /**
    1250                 :    * Move all display items in our lists to top of the corresponding lists in the
    1251                 :    * destination.
    1252                 :    */
    1253                 :   void MoveTo(const nsDisplayListSet& aDestination) const;
    1254                 : 
    1255                 : private:
    1256                 :   // This class is only used on stack, so we don't have to worry about leaking
    1257                 :   // it.  Don't let us be heap-allocated!
    1258                 :   void* operator new(size_t sz) CPP_THROW_NEW;
    1259                 : 
    1260                 : protected:
    1261                 :   nsDisplayList* mBorderBackground;
    1262                 :   nsDisplayList* mBlockBorderBackgrounds;
    1263                 :   nsDisplayList* mFloats;
    1264                 :   nsDisplayList* mContent;
    1265                 :   nsDisplayList* mPositioned;
    1266                 :   nsDisplayList* mOutlines;
    1267                 : };
    1268                 : 
    1269                 : /**
    1270                 :  * A specialization of nsDisplayListSet where the lists are actually internal
    1271                 :  * to the object, and all distinct.
    1272                 :  */
    1273               0 : struct nsDisplayListCollection : public nsDisplayListSet {
    1274               0 :   nsDisplayListCollection() :
    1275                 :     nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4],
    1276               0 :                      &mLists[5]) {}
    1277                 :   nsDisplayListCollection(nsDisplayList* aBorderBackground) :
    1278                 :     nsDisplayListSet(aBorderBackground, &mLists[1], &mLists[2], &mLists[3], &mLists[4],
    1279                 :                      &mLists[5]) {}
    1280                 : 
    1281                 :   /**
    1282                 :    * Sort all lists by content order.
    1283                 :    */                     
    1284               0 :   void SortAllByContentOrder(nsDisplayListBuilder* aBuilder, nsIContent* aCommonAncestor) {
    1285               0 :     for (PRInt32 i = 0; i < 6; ++i) {
    1286               0 :       mLists[i].SortByContentOrder(aBuilder, aCommonAncestor);
    1287                 :     }
    1288               0 :   }
    1289                 : 
    1290                 : private:
    1291                 :   // This class is only used on stack, so we don't have to worry about leaking
    1292                 :   // it.  Don't let us be heap-allocated!
    1293                 :   void* operator new(size_t sz) CPP_THROW_NEW;
    1294                 : 
    1295                 :   nsDisplayList mLists[6];
    1296                 : };
    1297                 : 
    1298                 : /**
    1299                 :  * Use this class to implement not-very-frequently-used display items
    1300                 :  * that are not opaque, do not receive events, and are bounded by a frame's
    1301                 :  * border-rect.
    1302                 :  * 
    1303                 :  * This should not be used for display items which are created frequently,
    1304                 :  * because each item is one or two pointers bigger than an item from a
    1305                 :  * custom display item class could be, and fractionally slower. However it does
    1306                 :  * save code size. We use this for infrequently-used item types.
    1307                 :  */
    1308                 : class nsDisplayGeneric : public nsDisplayItem {
    1309                 : public:
    1310                 :   typedef void (* PaintCallback)(nsIFrame* aFrame, nsRenderingContext* aCtx,
    1311                 :                                  const nsRect& aDirtyRect, nsPoint aFramePt);
    1312                 : 
    1313               0 :   nsDisplayGeneric(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1314                 :                    PaintCallback aPaint, const char* aName, Type aType)
    1315                 :     : nsDisplayItem(aBuilder, aFrame), mPaint(aPaint)
    1316                 : #ifdef MOZ_DUMP_PAINTING
    1317                 :       , mName(aName)
    1318                 : #endif
    1319               0 :       , mType(aType)
    1320                 :   {
    1321               0 :     MOZ_COUNT_CTOR(nsDisplayGeneric);
    1322               0 :   }
    1323                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1324               0 :   virtual ~nsDisplayGeneric() {
    1325               0 :     MOZ_COUNT_DTOR(nsDisplayGeneric);
    1326               0 :   }
    1327                 : #endif
    1328                 :   
    1329               0 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) {
    1330               0 :     mPaint(mFrame, aCtx, mVisibleRect, ToReferenceFrame());
    1331               0 :   }
    1332               0 :   NS_DISPLAY_DECL_NAME(mName, mType)
    1333                 : 
    1334               0 :   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) {
    1335               0 :     if (mType == nsDisplayItem::TYPE_HEADER_FOOTER)
    1336               0 :       return GetBounds(aBuilder);
    1337               0 :     return nsRect();
    1338                 :   }
    1339                 : 
    1340                 : protected:
    1341                 :   PaintCallback mPaint;
    1342                 : #ifdef MOZ_DUMP_PAINTING
    1343                 :   const char*   mName;
    1344                 : #endif
    1345                 :   Type mType;
    1346                 : };
    1347                 : 
    1348                 : #if defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF)
    1349                 : /**
    1350                 :  * This class implements painting of reflow counts.  Ideally, we would simply
    1351                 :  * make all the frame names be those returned by nsFrame::GetFrameName
    1352                 :  * (except that tosses in the content tag name!)  and support only one color
    1353                 :  * and eliminate this class altogether in favor of nsDisplayGeneric, but for
    1354                 :  * the time being we can't pass args to a PaintCallback, so just have a
    1355                 :  * separate class to do the right thing.  Sadly, this alsmo means we need to
    1356                 :  * hack all leaf frame classes to handle this.
    1357                 :  *
    1358                 :  * XXXbz the color thing is a bit of a mess, but 0 basically means "not set"
    1359                 :  * here...  I could switch it all to nscolor, but why bother?
    1360                 :  */
    1361                 : class nsDisplayReflowCount : public nsDisplayItem {
    1362                 : public:
    1363               0 :   nsDisplayReflowCount(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1364                 :                        const char* aFrameName,
    1365                 :                        PRUint32 aColor = 0)
    1366                 :     : nsDisplayItem(aBuilder, aFrame),
    1367                 :       mFrameName(aFrameName),
    1368               0 :       mColor(aColor)
    1369                 :   {
    1370               0 :     MOZ_COUNT_CTOR(nsDisplayReflowCount);
    1371               0 :   }
    1372                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1373               0 :   virtual ~nsDisplayReflowCount() {
    1374               0 :     MOZ_COUNT_DTOR(nsDisplayReflowCount);
    1375               0 :   }
    1376                 : #endif
    1377                 : 
    1378               0 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) {
    1379               0 :     mFrame->PresContext()->PresShell()->PaintCount(mFrameName, aCtx,
    1380                 :                                                    mFrame->PresContext(),
    1381               0 :                                                    mFrame, ToReferenceFrame(),
    1382               0 :                                                    mColor);
    1383               0 :   }
    1384               0 :   NS_DISPLAY_DECL_NAME("nsDisplayReflowCount", TYPE_REFLOW_COUNT)
    1385                 : protected:
    1386                 :   const char* mFrameName;
    1387                 :   nscolor mColor;
    1388                 : };
    1389                 : 
    1390                 : #define DO_GLOBAL_REFLOW_COUNT_DSP(_name)                                     \
    1391                 :   PR_BEGIN_MACRO                                                              \
    1392                 :     if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() &&   \
    1393                 :         PresContext()->PresShell()->IsPaintingFrameCounts()) {                \
    1394                 :       nsresult _rv =                                                          \
    1395                 :         aLists.Outlines()->AppendNewToTop(                                    \
    1396                 :             new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name));      \
    1397                 :       NS_ENSURE_SUCCESS(_rv, _rv);                                            \
    1398                 :     }                                                                         \
    1399                 :   PR_END_MACRO
    1400                 : 
    1401                 : #define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color)                       \
    1402                 :   PR_BEGIN_MACRO                                                              \
    1403                 :     if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() &&   \
    1404                 :         PresContext()->PresShell()->IsPaintingFrameCounts()) {                \
    1405                 :       nsresult _rv =                                                          \
    1406                 :         aLists.Outlines()->AppendNewToTop(                                    \
    1407                 :              new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name, _color)); \
    1408                 :       NS_ENSURE_SUCCESS(_rv, _rv);                                            \
    1409                 :     }                                                                         \
    1410                 :   PR_END_MACRO
    1411                 : 
    1412                 : /*
    1413                 :   Macro to be used for classes that don't actually implement BuildDisplayList
    1414                 :  */
    1415                 : #define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super)                   \
    1416                 :   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,           \
    1417                 :                               const nsRect&           aDirtyRect,         \
    1418                 :                               const nsDisplayListSet& aLists) {           \
    1419                 :     DO_GLOBAL_REFLOW_COUNT_DSP(#_class);                                  \
    1420                 :     return _super::BuildDisplayList(aBuilder, aDirtyRect, aLists);        \
    1421                 :   }
    1422                 : 
    1423                 : #else // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF
    1424                 : 
    1425                 : #define DO_GLOBAL_REFLOW_COUNT_DSP(_name)
    1426                 : #define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color)
    1427                 : #define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super)
    1428                 : 
    1429                 : #endif // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF
    1430                 : 
    1431                 : class nsDisplayCaret : public nsDisplayItem {
    1432                 : public:
    1433               0 :   nsDisplayCaret(nsDisplayListBuilder* aBuilder, nsIFrame* aCaretFrame,
    1434                 :                  nsCaret *aCaret)
    1435               0 :     : nsDisplayItem(aBuilder, aCaretFrame), mCaret(aCaret) {
    1436               0 :     MOZ_COUNT_CTOR(nsDisplayCaret);
    1437               0 :   }
    1438                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1439               0 :   virtual ~nsDisplayCaret() {
    1440               0 :     MOZ_COUNT_DTOR(nsDisplayCaret);
    1441               0 :   }
    1442                 : #endif
    1443                 : 
    1444               0 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
    1445                 :     // The caret returns a rect in the coordinates of mFrame.
    1446               0 :     return mCaret->GetCaretRect() + ToReferenceFrame();
    1447                 :   }
    1448                 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
    1449               0 :   NS_DISPLAY_DECL_NAME("Caret", TYPE_CARET)
    1450                 : protected:
    1451                 :   nsRefPtr<nsCaret> mCaret;
    1452                 : };
    1453                 : 
    1454                 : /**
    1455                 :  * The standard display item to paint the CSS borders of a frame.
    1456                 :  */
    1457                 : class nsDisplayBorder : public nsDisplayItem {
    1458                 : public:
    1459               0 :   nsDisplayBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) :
    1460                 :     nsDisplayItem(aBuilder, aFrame),
    1461               0 :     mSnappingEnabled(aBuilder->IsSnappingEnabled() && !aBuilder->IsInTransform()) {
    1462               0 :     MOZ_COUNT_CTOR(nsDisplayBorder);
    1463               0 :   }
    1464                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1465               0 :   virtual ~nsDisplayBorder() {
    1466               0 :     MOZ_COUNT_DTOR(nsDisplayBorder);
    1467               0 :   }
    1468                 : #endif
    1469                 : 
    1470                 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
    1471                 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
    1472                 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    1473                 :                                    nsRegion* aVisibleRegion,
    1474                 :                                    const nsRect& aAllowVisibleRegionExpansion);
    1475               0 :   NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
    1476                 : 
    1477                 : protected:
    1478                 :   bool mSnappingEnabled;
    1479                 : };
    1480                 : 
    1481                 : /**
    1482                 :  * A simple display item that just renders a solid color across the
    1483                 :  * specified bounds. For canvas frames (in the CSS sense) we split off the
    1484                 :  * drawing of the background color into this class (from nsDisplayBackground
    1485                 :  * via nsDisplayCanvasBackground). This is done so that we can always draw a
    1486                 :  * background color to avoid ugly flashes of white when we can't draw a full
    1487                 :  * frame tree (ie when a page is loading). The bounds can differ from the
    1488                 :  * frame's bounds -- this is needed when a frame/iframe is loading and there
    1489                 :  * is not yet a frame tree to go in the frame/iframe so we use the subdoc
    1490                 :  * frame of the parent document as a standin.
    1491                 :  */
    1492                 : class nsDisplaySolidColor : public nsDisplayItem {
    1493                 : public:
    1494               0 :   nsDisplaySolidColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1495                 :                       const nsRect& aBounds, nscolor aColor)
    1496                 :     : nsDisplayItem(aBuilder, aFrame), mBounds(aBounds), mColor(aColor),
    1497               0 :       mSnappingEnabled(aBuilder->IsSnappingEnabled() && !aBuilder->IsInTransform()) {
    1498               0 :     NS_ASSERTION(NS_GET_A(aColor) > 0, "Don't create invisible nsDisplaySolidColors!");
    1499               0 :     MOZ_COUNT_CTOR(nsDisplaySolidColor);
    1500               0 :   }
    1501                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1502               0 :   virtual ~nsDisplaySolidColor() {
    1503               0 :     MOZ_COUNT_DTOR(nsDisplaySolidColor);
    1504               0 :   }
    1505                 : #endif
    1506                 : 
    1507                 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
    1508                 : 
    1509               0 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    1510                 :                                    bool* aOutTransparentBackground = nsnull) {
    1511               0 :     if (aOutTransparentBackground) {
    1512               0 :       *aOutTransparentBackground = false;
    1513                 :     }
    1514               0 :     nsRegion result;
    1515               0 :     if (NS_GET_A(mColor) == 255) {
    1516               0 :       result = GetBounds(aBuilder);
    1517                 :     }
    1518                 :     return result;
    1519                 :   }
    1520                 : 
    1521               0 :   virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor)
    1522                 :   {
    1523               0 :     *aColor = mColor;
    1524               0 :     return true;
    1525                 :   }
    1526                 : 
    1527                 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
    1528                 : 
    1529               0 :   NS_DISPLAY_DECL_NAME("SolidColor", TYPE_SOLID_COLOR)
    1530                 : 
    1531                 : private:
    1532                 :   nsRect  mBounds;
    1533                 :   nscolor mColor;
    1534                 :   bool mSnappingEnabled;
    1535                 : };
    1536                 : 
    1537                 : /**
    1538                 :  * The standard display item to paint the CSS background of a frame.
    1539                 :  */
    1540                 : class nsDisplayBackground : public nsDisplayItem {
    1541                 : public:
    1542                 :   nsDisplayBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
    1543                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1544               0 :   virtual ~nsDisplayBackground() {
    1545               0 :     MOZ_COUNT_DTOR(nsDisplayBackground);
    1546               0 :   }
    1547                 : #endif
    1548                 : 
    1549                 :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    1550                 :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
    1551                 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    1552                 :                                    nsRegion* aVisibleRegion,
    1553                 :                                    const nsRect& aAllowVisibleRegionExpansion);
    1554                 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    1555                 :                                    bool* aForceTransparentSurface = nsnull);
    1556                 :   virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
    1557                 :                                                 nsIFrame* aFrame);
    1558                 :   virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor);
    1559                 :   virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder);
    1560                 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
    1561                 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
    1562               0 :   NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
    1563                 : protected:
    1564                 :   nsRegion GetInsideClipRegion(nsPresContext* aPresContext, PRUint8 aClip,
    1565                 :                                const nsRect& aRect);
    1566                 : 
    1567                 :   /* Used to cache mFrame->IsThemed() since it isn't a cheap call */
    1568                 :   bool mIsThemed;
    1569                 :   bool mSnappingEnabled;
    1570                 :   nsITheme::Transparency mThemeTransparency;
    1571                 : };
    1572                 : 
    1573                 : /**
    1574                 :  * The standard display item to paint the outer CSS box-shadows of a frame.
    1575                 :  */
    1576                 : class nsDisplayBoxShadowOuter : public nsDisplayItem {
    1577                 : public:
    1578               0 :   nsDisplayBoxShadowOuter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    1579               0 :     : nsDisplayItem(aBuilder, aFrame) {
    1580               0 :     MOZ_COUNT_CTOR(nsDisplayBoxShadowOuter);
    1581               0 :   }
    1582                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1583               0 :   virtual ~nsDisplayBoxShadowOuter() {
    1584               0 :     MOZ_COUNT_DTOR(nsDisplayBoxShadowOuter);
    1585               0 :   }
    1586                 : #endif
    1587                 : 
    1588                 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
    1589                 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
    1590                 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    1591                 :                                    nsRegion* aVisibleRegion,
    1592                 :                                    const nsRect& aAllowVisibleRegionExpansion);
    1593               0 :   NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER)
    1594                 : 
    1595                 : private:
    1596                 :   nsRegion mVisibleRegion;
    1597                 : };
    1598                 : 
    1599                 : /**
    1600                 :  * The standard display item to paint the inner CSS box-shadows of a frame.
    1601                 :  */
    1602                 : class nsDisplayBoxShadowInner : public nsDisplayItem {
    1603                 : public:
    1604               0 :   nsDisplayBoxShadowInner(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    1605               0 :     : nsDisplayItem(aBuilder, aFrame) {
    1606               0 :     MOZ_COUNT_CTOR(nsDisplayBoxShadowInner);
    1607               0 :   }
    1608                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1609               0 :   virtual ~nsDisplayBoxShadowInner() {
    1610               0 :     MOZ_COUNT_DTOR(nsDisplayBoxShadowInner);
    1611               0 :   }
    1612                 : #endif
    1613                 : 
    1614                 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
    1615                 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    1616                 :                                    nsRegion* aVisibleRegion,
    1617                 :                                    const nsRect& aAllowVisibleRegionExpansion);
    1618               0 :   NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER)
    1619                 : 
    1620                 : private:
    1621                 :   nsRegion mVisibleRegion;
    1622                 : };
    1623                 : 
    1624                 : /**
    1625                 :  * The standard display item to paint the CSS outline of a frame.
    1626                 :  */
    1627                 : class nsDisplayOutline : public nsDisplayItem {
    1628                 : public:
    1629               0 :   nsDisplayOutline(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) :
    1630               0 :     nsDisplayItem(aBuilder, aFrame) {
    1631               0 :     MOZ_COUNT_CTOR(nsDisplayOutline);
    1632               0 :   }
    1633                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1634               0 :   virtual ~nsDisplayOutline() {
    1635               0 :     MOZ_COUNT_DTOR(nsDisplayOutline);
    1636               0 :   }
    1637                 : #endif
    1638                 : 
    1639                 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
    1640                 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
    1641                 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    1642                 :                                    nsRegion* aVisibleRegion,
    1643                 :                                    const nsRect& aAllowVisibleRegionExpansion);
    1644               0 :   NS_DISPLAY_DECL_NAME("Outline", TYPE_OUTLINE)
    1645                 : };
    1646                 : 
    1647                 : /**
    1648                 :  * A class that lets you receive events within the frame bounds but never paints.
    1649                 :  */
    1650                 : class nsDisplayEventReceiver : public nsDisplayItem {
    1651                 : public:
    1652               0 :   nsDisplayEventReceiver(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    1653               0 :     : nsDisplayItem(aBuilder, aFrame) {
    1654               0 :     MOZ_COUNT_CTOR(nsDisplayEventReceiver);
    1655               0 :   }
    1656                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1657               0 :   virtual ~nsDisplayEventReceiver() {
    1658               0 :     MOZ_COUNT_DTOR(nsDisplayEventReceiver);
    1659               0 :   }
    1660                 : #endif
    1661                 : 
    1662                 :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    1663                 :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
    1664               0 :   NS_DISPLAY_DECL_NAME("EventReceiver", TYPE_EVENT_RECEIVER)
    1665                 : };
    1666                 : 
    1667                 : /**
    1668                 :  * A class that lets you wrap a display list as a display item.
    1669                 :  * 
    1670                 :  * GetUnderlyingFrame() is troublesome for wrapped lists because if the wrapped
    1671                 :  * list has many items, it's not clear which one has the 'underlying frame'.
    1672                 :  * Thus we force the creator to specify what the underlying frame is. The
    1673                 :  * underlying frame should be the root of a stacking context, because sorting
    1674                 :  * a list containing this item will not get at the children.
    1675                 :  * 
    1676                 :  * In some cases (e.g., clipping) we want to wrap a list but we don't have a
    1677                 :  * particular underlying frame that is a stacking context root. In that case
    1678                 :  * we allow the frame to be nsnull. Callers to GetUnderlyingFrame must
    1679                 :  * detect and handle this case.
    1680                 :  */
    1681                 : class nsDisplayWrapList : public nsDisplayItem {
    1682                 :   // This is never instantiated directly, so no need to count constructors and
    1683                 :   // destructors.
    1684                 : 
    1685                 : public:
    1686                 :   /**
    1687                 :    * Takes all the items from aList and puts them in our list.
    1688                 :    */
    1689                 :   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1690                 :                     nsDisplayList* aList);
    1691                 :   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1692                 :                     nsDisplayItem* aItem);
    1693                 :   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
    1694                 :   virtual ~nsDisplayWrapList();
    1695                 :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    1696                 :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
    1697                 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
    1698                 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    1699                 :                                    bool* aForceTransparentSurface = nsnull);
    1700                 :   virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor);
    1701                 :   virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
    1702                 :                                                 nsIFrame* aFrame);
    1703                 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
    1704                 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    1705                 :                                    nsRegion* aVisibleRegion,
    1706                 :                                    const nsRect& aAllowVisibleRegionExpansion);
    1707               0 :   virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) {
    1708               0 :     NS_WARNING("This list should already have been flattened!!!");
    1709               0 :     return false;
    1710                 :   }
    1711               0 :   NS_DISPLAY_DECL_NAME("WrapList", TYPE_WRAP_LIST)
    1712                 : 
    1713                 :   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder);
    1714                 :                                     
    1715               0 :   virtual nsDisplayList* GetList() { return &mList; }
    1716                 :   
    1717                 :   /**
    1718                 :    * This creates a copy of this item, but wrapping aItem instead of
    1719                 :    * our existing list. Only gets called if this item returned nsnull
    1720                 :    * for GetUnderlyingFrame(). aItem is guaranteed to return non-null from
    1721                 :    * GetUnderlyingFrame().
    1722                 :    */
    1723               0 :   virtual nsDisplayWrapList* WrapWithClone(nsDisplayListBuilder* aBuilder,
    1724                 :                                            nsDisplayItem* aItem) {
    1725               0 :     NS_NOTREACHED("We never returned nsnull for GetUnderlyingFrame!");
    1726               0 :     return nsnull;
    1727                 :   }
    1728                 : 
    1729                 :   /**
    1730                 :    * Returns true if all descendant display items can be placed in the same
    1731                 :    * ThebesLayer --- GetLayerState returns LAYER_INACTIVE or LAYER_NONE,
    1732                 :    * and they all have the given aActiveScrolledRoot.
    1733                 :    */
    1734                 :   static bool ChildrenCanBeInactive(nsDisplayListBuilder* aBuilder,
    1735                 :                                       LayerManager* aManager,
    1736                 :                                       const nsDisplayList& aList,
    1737                 :                                       nsIFrame* aActiveScrolledRoot);
    1738                 : 
    1739                 : protected:
    1740                 :   nsDisplayWrapList() {}
    1741                 :   
    1742                 :   nsDisplayList mList;
    1743                 : };
    1744                 : 
    1745                 : /**
    1746                 :  * We call WrapDisplayList on the in-flow lists: BorderBackground(),
    1747                 :  * BlockBorderBackgrounds() and Content().
    1748                 :  * We call WrapDisplayItem on each item of Outlines(), PositionedDescendants(),
    1749                 :  * and Floats(). This is done to support special wrapping processing for frames
    1750                 :  * that may not be in-flow descendants of the current frame.
    1751                 :  */
    1752                 : class nsDisplayWrapper {
    1753                 : public:
    1754                 :   // This is never instantiated directly (it has pure virtual methods), so no
    1755                 :   // need to count constructors and destructors.
    1756                 : 
    1757               0 :   virtual bool WrapBorderBackground() { return true; }
    1758                 :   virtual nsDisplayItem* WrapList(nsDisplayListBuilder* aBuilder,
    1759                 :                                   nsIFrame* aFrame, nsDisplayList* aList) = 0;
    1760                 :   virtual nsDisplayItem* WrapItem(nsDisplayListBuilder* aBuilder,
    1761                 :                                   nsDisplayItem* aItem) = 0;
    1762                 : 
    1763                 :   nsresult WrapLists(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1764                 :                      const nsDisplayListSet& aIn, const nsDisplayListSet& aOut);
    1765                 :   nsresult WrapListsInPlace(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1766                 :                             const nsDisplayListSet& aLists);
    1767                 : protected:
    1768               0 :   nsDisplayWrapper() {}
    1769                 : };
    1770                 :                               
    1771                 : /**
    1772                 :  * The standard display item to paint a stacking context with translucency
    1773                 :  * set by the stacking context root frame's 'opacity' style.
    1774                 :  */
    1775                 : class nsDisplayOpacity : public nsDisplayWrapList {
    1776                 : public:
    1777                 :   nsDisplayOpacity(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1778                 :                    nsDisplayList* aList);
    1779                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1780                 :   virtual ~nsDisplayOpacity();
    1781                 : #endif
    1782                 :   
    1783                 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    1784                 :                                    bool* aForceTransparentSurface = nsnull);
    1785                 :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    1786                 :                                              LayerManager* aManager,
    1787                 :                                              const ContainerParameters& aContainerParameters);
    1788                 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    1789                 :                                    LayerManager* aManager);
    1790                 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    1791                 :                                    nsRegion* aVisibleRegion,
    1792                 :                                    const nsRect& aAllowVisibleRegionExpansion);  
    1793                 :   virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem);
    1794               0 :   NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
    1795                 : };
    1796                 : 
    1797                 : /**
    1798                 :  * A display item that has no purpose but to ensure its contents get
    1799                 :  * their own layer.
    1800                 :  */
    1801                 : class nsDisplayOwnLayer : public nsDisplayWrapList {
    1802                 : public:
    1803                 :   nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1804                 :                     nsDisplayList* aList);
    1805                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1806                 :   virtual ~nsDisplayOwnLayer();
    1807                 : #endif
    1808                 :   
    1809                 :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    1810                 :                                              LayerManager* aManager,
    1811                 :                                              const ContainerParameters& aContainerParameters);
    1812               0 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    1813                 :                                    LayerManager* aManager)
    1814                 :   {
    1815               0 :     return mozilla::LAYER_ACTIVE;
    1816                 :   }
    1817               0 :   virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem)
    1818                 :   {
    1819                 :     // Don't allow merging, each sublist must have its own layer
    1820               0 :     return false;
    1821                 :   }
    1822               0 :   NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
    1823                 : };
    1824                 : 
    1825                 : /**
    1826                 :  * This potentially creates a layer for the given list of items, whose
    1827                 :  * visibility is determined by the displayport for the given frame instead of
    1828                 :  * what is passed in to ComputeVisibility.
    1829                 :  *
    1830                 :  * Here in content, we can use this to render more content than is actually
    1831                 :  * visible. Then, the compositing process can manipulate the generated layer
    1832                 :  * through transformations so that asynchronous scrolling can be implemented.
    1833                 :  *
    1834                 :  * Note that setting the displayport will not change any hit testing! The
    1835                 :  * content process will know nothing about what the user is actually seeing,
    1836                 :  * so it can only do hit testing for what is supposed to be the visible region.
    1837                 :  *
    1838                 :  * It is possible for scroll boxes to have content that can be both above and
    1839                 :  * below content outside of the scroll box. We cannot create layers for these
    1840                 :  * cases. This is accomplished by wrapping display items with
    1841                 :  * nsDisplayScrollLayers. nsDisplayScrollLayers with the same scroll frame will
    1842                 :  * be merged together. If more than one nsDisplayScrollLayer exists after
    1843                 :  * merging, all nsDisplayScrollLayers will be flattened out so that no new
    1844                 :  * layer is created at all.
    1845                 :  */
    1846                 : class nsDisplayScrollLayer : public nsDisplayWrapList
    1847                 : {
    1848                 : public:
    1849                 :   /**
    1850                 :    * @param aScrolledFrame This will determine what the displayport is. It should be
    1851                 :    *                       the root content frame of the scrolled area. Note
    1852                 :    *                       that nsDisplayScrollLayer will expect for
    1853                 :    *                       ScrollLayerCount to be defined on aScrolledFrame.
    1854                 :    * @param aScrollFrame The viewport frame you see this content through.
    1855                 :    */
    1856                 :   nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
    1857                 :                        nsIFrame* aForFrame, nsIFrame* aScrolledFrame,
    1858                 :                        nsIFrame* aScrollFrame);
    1859                 :   nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
    1860                 :                        nsIFrame* aForFrame, nsIFrame* aScrolledFrame,
    1861                 :                        nsIFrame* aScrollFrame);
    1862                 :   nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
    1863                 :                        nsIFrame* aForFrame, nsIFrame* aScrolledFrame,
    1864                 :                        nsIFrame* aScrollFrame);
    1865               0 :   NS_DISPLAY_DECL_NAME("ScrollLayer", TYPE_SCROLL_LAYER)
    1866                 : 
    1867                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1868                 :   virtual ~nsDisplayScrollLayer();
    1869                 : #endif
    1870                 : 
    1871                 :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    1872                 :                                              LayerManager* aManager,
    1873                 :                                              const ContainerParameters& aContainerParameters);
    1874                 : 
    1875                 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    1876                 :                                    nsRegion* aVisibleRegion,
    1877                 :                                    const nsRect& aAllowVisibleRegionExpansion);
    1878                 : 
    1879                 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    1880                 :                                    LayerManager* aManager);
    1881                 : 
    1882                 :   virtual bool TryMerge(nsDisplayListBuilder* aBuilder,
    1883                 :                           nsDisplayItem* aItem);
    1884                 : 
    1885                 :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder);
    1886                 : 
    1887                 :   // Get the number of nsDisplayScrollLayers for a scroll frame. Note that this
    1888                 :   // number does not include nsDisplayScrollInfoLayers. If this number is not 1
    1889                 :   // after merging, all the nsDisplayScrollLayers should flatten away.
    1890                 :   PRWord GetScrollLayerCount();
    1891                 :   PRWord RemoveScrollLayerCount();
    1892                 : 
    1893                 : private:
    1894                 :   nsIFrame* mScrollFrame;
    1895                 :   nsIFrame* mScrolledFrame;
    1896                 : };
    1897                 : 
    1898                 : /**
    1899                 :  * Like nsDisplayScrollLayer, but only has metadata on the scroll frame. This
    1900                 :  * creates a layer that has no Thebes child layer, but still allows the
    1901                 :  * compositor process to know of the scroll frame's existence.
    1902                 :  *
    1903                 :  * After visibility computation, nsDisplayScrollInfoLayers should only exist if
    1904                 :  * nsDisplayScrollLayers were all flattened away.
    1905                 :  *
    1906                 :  * Important!! Add info layers to the bottom of the list so they are only
    1907                 :  * considered after the others have flattened out!
    1908                 :  */
    1909                 : class nsDisplayScrollInfoLayer : public nsDisplayScrollLayer
    1910                 : {
    1911                 : public:
    1912                 :   nsDisplayScrollInfoLayer(nsDisplayListBuilder* aBuilder,
    1913                 :                            nsIFrame* aScrolledFrame, nsIFrame* aScrollFrame);
    1914               0 :   NS_DISPLAY_DECL_NAME("ScrollInfoLayer", TYPE_SCROLL_INFO_LAYER)
    1915                 : 
    1916                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1917                 :   virtual ~nsDisplayScrollInfoLayer();
    1918                 : #endif
    1919                 : 
    1920                 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    1921                 :                                    LayerManager* aManager);
    1922                 : 
    1923                 :   virtual bool TryMerge(nsDisplayListBuilder* aBuilder,
    1924                 :                           nsDisplayItem* aItem);
    1925                 : 
    1926                 :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder);
    1927                 : };
    1928                 : 
    1929                 : /**
    1930                 :  * nsDisplayClip can clip a list of items, but we take a single item
    1931                 :  * initially and then later merge other items into it when we merge
    1932                 :  * adjacent matching nsDisplayClips
    1933                 :  */
    1934                 : class nsDisplayClip : public nsDisplayWrapList {
    1935                 : public:
    1936                 :   /**
    1937                 :    * @param aFrame the frame that should be considered the underlying
    1938                 :    * frame for this content, e.g. the frame whose z-index we have.  This
    1939                 :    * is *not* the frame that is inducing the clipping.
    1940                 :    */
    1941                 :   nsDisplayClip(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1942                 :                 nsDisplayItem* aItem, const nsRect& aRect);
    1943                 :   nsDisplayClip(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1944                 :                 nsDisplayList* aList, const nsRect& aRect);
    1945                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1946                 :   virtual ~nsDisplayClip();
    1947                 : #endif
    1948                 :   
    1949                 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
    1950                 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
    1951                 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    1952                 :                                    nsRegion* aVisibleRegion,
    1953                 :                                    const nsRect& aAllowVisibleRegionExpansion);
    1954                 :   virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem);
    1955               0 :   NS_DISPLAY_DECL_NAME("Clip", TYPE_CLIP)
    1956               0 :   virtual PRUint32 GetPerFrameKey() { return 0; }
    1957                 :   
    1958               0 :   const nsRect& GetClipRect() { return mClip; }
    1959               0 :   void SetClipRect(const nsRect& aRect) { mClip = aRect; }
    1960                 : 
    1961                 :   virtual nsDisplayWrapList* WrapWithClone(nsDisplayListBuilder* aBuilder,
    1962                 :                                            nsDisplayItem* aItem);
    1963                 : 
    1964                 : protected:
    1965                 :   nsRect    mClip;
    1966                 : };
    1967                 : 
    1968                 : /**
    1969                 :  * A display item to clip a list of items to the border-radius of a
    1970                 :  * frame.
    1971                 :  */
    1972                 : class nsDisplayClipRoundedRect : public nsDisplayClip {
    1973                 : public:
    1974                 :   /**
    1975                 :    * @param aFrame the frame that should be considered the underlying
    1976                 :    * frame for this content, e.g. the frame whose z-index we have.  This
    1977                 :    * is *not* the frame that is inducing the clipping.
    1978                 :    */
    1979                 :   nsDisplayClipRoundedRect(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1980                 :                            nsDisplayItem* aItem,
    1981                 :                            const nsRect& aRect, nscoord aRadii[8]);
    1982                 :   nsDisplayClipRoundedRect(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1983                 :                            nsDisplayList* aList,
    1984                 :                            const nsRect& aRect, nscoord aRadii[8]);
    1985                 : #ifdef NS_BUILD_REFCNT_LOGGING
    1986                 :   virtual ~nsDisplayClipRoundedRect();
    1987                 : #endif
    1988                 : 
    1989                 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    1990                 :                                    bool* aForceTransparentSurface = nsnull);
    1991                 :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    1992                 :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
    1993                 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    1994                 :                                    nsRegion* aVisibleRegion,
    1995                 :                                    const nsRect& aAllowVisibleRegionExpansion);
    1996                 :   virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem);
    1997               0 :   NS_DISPLAY_DECL_NAME("ClipRoundedRect", TYPE_CLIP_ROUNDED_RECT)
    1998                 : 
    1999                 :   virtual nsDisplayWrapList* WrapWithClone(nsDisplayListBuilder* aBuilder,
    2000                 :                                            nsDisplayItem* aItem);
    2001                 : 
    2002               0 :   void GetRadii(nscoord aRadii[8]) {
    2003               0 :     memcpy(aRadii, mRadii, sizeof(mRadii));
    2004               0 :   }
    2005                 : 
    2006                 : private:
    2007                 :   nscoord mRadii[8];
    2008                 : };
    2009                 : 
    2010                 : /**
    2011                 :  * nsDisplayZoom is used for subdocuments that have a different full zoom than
    2012                 :  * their parent documents. This item creates a container layer.
    2013                 :  */
    2014                 : class nsDisplayZoom : public nsDisplayOwnLayer {
    2015                 : public:
    2016                 :   /**
    2017                 :    * @param aFrame is the root frame of the subdocument.
    2018                 :    * @param aList contains the display items for the subdocument.
    2019                 :    * @param aAPD is the app units per dev pixel ratio of the subdocument.
    2020                 :    * @param aParentAPD is the app units per dev pixel ratio of the parent
    2021                 :    * document.
    2022                 :    */
    2023                 :   nsDisplayZoom(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    2024                 :                 nsDisplayList* aList,
    2025                 :                 PRInt32 aAPD, PRInt32 aParentAPD);
    2026                 : #ifdef NS_BUILD_REFCNT_LOGGING
    2027                 :   virtual ~nsDisplayZoom();
    2028                 : #endif
    2029                 :   
    2030                 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
    2031                 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
    2032                 :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    2033                 :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
    2034                 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    2035                 :                                    nsRegion* aVisibleRegion,
    2036                 :                                    const nsRect& aAllowVisibleRegionExpansion);
    2037               0 :   NS_DISPLAY_DECL_NAME("Zoom", TYPE_ZOOM)
    2038                 : 
    2039                 :   // Get the app units per dev pixel ratio of the child document.
    2040                 :   PRInt32 GetChildAppUnitsPerDevPixel() { return mAPD; }
    2041                 :   // Get the app units per dev pixel ratio of the parent document.
    2042               0 :   PRInt32 GetParentAppUnitsPerDevPixel() { return mParentAPD; }
    2043                 : 
    2044                 : private:
    2045                 :   PRInt32 mAPD, mParentAPD;
    2046                 : };
    2047                 : 
    2048                 : /**
    2049                 :  * A display item to paint a stacking context with effects
    2050                 :  * set by the stacking context root frame's style.
    2051                 :  */
    2052                 : class nsDisplaySVGEffects : public nsDisplayWrapList {
    2053                 : public:
    2054                 :   nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    2055                 :                       nsDisplayList* aList);
    2056                 : #ifdef NS_BUILD_REFCNT_LOGGING
    2057                 :   virtual ~nsDisplaySVGEffects();
    2058                 : #endif
    2059                 :   
    2060                 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    2061                 :                                    bool* aForceTransparentSurface = nsnull);
    2062                 :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    2063                 :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
    2064               0 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
    2065               0 :     return mBounds + aBuilder->ToReferenceFrame(mEffectsFrame);
    2066                 :   }
    2067                 :   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
    2068                 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    2069                 :                                    nsRegion* aVisibleRegion,
    2070                 :                                    const nsRect& aAllowVisibleRegionExpansion);  
    2071                 :   virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem);
    2072               0 :   NS_DISPLAY_DECL_NAME("SVGEffects", TYPE_SVG_EFFECTS)
    2073                 : 
    2074                 :   nsIFrame* GetEffectsFrame() { return mEffectsFrame; }
    2075                 : 
    2076                 : #ifdef MOZ_DUMP_PAINTING
    2077                 :   void PrintEffects(FILE* aOutput);
    2078                 : #endif
    2079                 : 
    2080                 : private:
    2081                 :   nsIFrame* mEffectsFrame;
    2082                 :   // relative to mEffectsFrame
    2083                 :   nsRect    mBounds;
    2084                 : };
    2085                 : 
    2086                 : /* A display item that applies a transformation to all of its descendant
    2087                 :  * elements.  This wrapper should only be used if there is a transform applied
    2088                 :  * to the root element.
    2089                 :  *
    2090                 :  * The reason that a "bounds" rect is involved in transform calculations is
    2091                 :  * because CSS-transforms allow percentage values for the x and y components
    2092                 :  * of <translation-value>s, where percentages are percentages of the element's
    2093                 :  * border box.
    2094                 :  *
    2095                 :  * INVARIANT: The wrapped frame is transformed.
    2096                 :  * INVARIANT: The wrapped frame is non-null.
    2097                 :  */ 
    2098                 : class nsDisplayTransform: public nsDisplayItem
    2099                 : {
    2100                 : public:
    2101                 :   /* Constructor accepts a display list, empties it, and wraps it up.  It also
    2102                 :    * ferries the underlying frame to the nsDisplayItem constructor.
    2103                 :    */
    2104               0 :   nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
    2105                 :                      nsDisplayList *aList, PRUint32 aIndex = 0) :
    2106               0 :     nsDisplayItem(aBuilder, aFrame), mStoredList(aBuilder, aFrame, aList), mIndex(aIndex)
    2107                 :   {
    2108               0 :     MOZ_COUNT_CTOR(nsDisplayTransform);
    2109               0 :     NS_ABORT_IF_FALSE(aFrame, "Must have a frame!");
    2110               0 :   }
    2111                 : 
    2112                 :   nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
    2113                 :                      nsDisplayItem *aItem, PRUint32 aIndex = 0) :
    2114                 :   nsDisplayItem(aBuilder, aFrame), mStoredList(aBuilder, aFrame, aItem), mIndex(aIndex)
    2115                 :   {
    2116                 :     MOZ_COUNT_CTOR(nsDisplayTransform);
    2117                 :     NS_ABORT_IF_FALSE(aFrame, "Must have a frame!");
    2118                 :   }
    2119                 : 
    2120                 : #ifdef NS_BUILD_REFCNT_LOGGING
    2121               0 :   virtual ~nsDisplayTransform()
    2122               0 :   {
    2123               0 :     MOZ_COUNT_DTOR(nsDisplayTransform);
    2124               0 :   }
    2125                 : #endif
    2126                 : 
    2127               0 :   NS_DISPLAY_DECL_NAME("nsDisplayTransform", TYPE_TRANSFORM);
    2128                 : 
    2129               0 :   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder)
    2130                 :   {
    2131               0 :     if (mStoredList.GetComponentAlphaBounds(aBuilder).IsEmpty())
    2132               0 :       return nsRect();
    2133               0 :     return GetBounds(aBuilder);
    2134                 :   }
    2135                 : 
    2136               0 :   nsDisplayWrapList* GetStoredList() { return &mStoredList; }
    2137                 : 
    2138                 :   virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect,
    2139                 :                        HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames);
    2140                 :   virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder);
    2141                 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
    2142                 :                                    bool* aForceTransparentSurface = nsnull);
    2143                 :   virtual bool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor);
    2144                 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    2145                 :                                    LayerManager* aManager);
    2146                 :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    2147                 :                                              LayerManager* aManager,
    2148                 :                                              const ContainerParameters& aContainerParameters);
    2149                 :   virtual bool ComputeVisibility(nsDisplayListBuilder *aBuilder,
    2150                 :                                    nsRegion *aVisibleRegion,
    2151                 :                                    const nsRect& aAllowVisibleRegionExpansion);
    2152                 :   virtual bool TryMerge(nsDisplayListBuilder *aBuilder, nsDisplayItem *aItem);
    2153                 :   
    2154               0 :   virtual PRUint32 GetPerFrameKey() { return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); }
    2155                 : 
    2156                 :   enum {
    2157                 :     INDEX_MAX = PR_UINT32_MAX >> nsDisplayItem::TYPE_BITS
    2158                 :   };
    2159                 : 
    2160                 :   const gfx3DMatrix& GetTransform(float aAppUnitsPerPixel);
    2161                 : 
    2162                 :   float GetHitDepthAtPoint(const nsPoint& aPoint);
    2163                 : 
    2164                 :   /**
    2165                 :    * TransformRect takes in as parameters a rectangle (in aFrame's coordinate
    2166                 :    * space) and returns the smallest rectangle (in aFrame's coordinate space)
    2167                 :    * containing the transformed image of that rectangle.  That is, it takes
    2168                 :    * the four corners of the rectangle, transforms them according to the
    2169                 :    * matrix associated with the specified frame, then returns the smallest
    2170                 :    * rectangle containing the four transformed points.
    2171                 :    *
    2172                 :    * @param untransformedBounds The rectangle (in app units) to transform.
    2173                 :    * @param aFrame The frame whose transformation should be applied.  This
    2174                 :    *        function raises an assertion if aFrame is null or doesn't have a
    2175                 :    *        transform applied to it.
    2176                 :    * @param aOrigin The origin of the transform relative to aFrame's local
    2177                 :    *        coordinate space.
    2178                 :    * @param aBoundsOverride (optional) Rather than using the frame's computed
    2179                 :    *        bounding rect as frame bounds, use this rectangle instead.  Pass
    2180                 :    *        nsnull (or nothing at all) to use the default.
    2181                 :    */
    2182                 :   static nsRect TransformRect(const nsRect &aUntransformedBounds, 
    2183                 :                               const nsIFrame* aFrame,
    2184                 :                               const nsPoint &aOrigin,
    2185                 :                               const nsRect* aBoundsOverride = nsnull);
    2186                 : 
    2187                 :   static nsRect TransformRectOut(const nsRect &aUntransformedBounds, 
    2188                 :                                  const nsIFrame* aFrame,
    2189                 :                                  const nsPoint &aOrigin,
    2190                 :                                  const nsRect* aBoundsOverride = nsnull);
    2191                 : 
    2192                 :   /* UntransformRect is like TransformRect, except that it inverts the
    2193                 :    * transform.
    2194                 :    */
    2195                 :   static bool UntransformRect(const nsRect &aUntransformedBounds, 
    2196                 :                                 const nsIFrame* aFrame,
    2197                 :                                 const nsPoint &aOrigin,
    2198                 :                                 nsRect* aOutRect);
    2199                 :   
    2200                 :   static bool UntransformRectMatrix(const nsRect &aUntransformedBounds, 
    2201                 :                                     const gfx3DMatrix& aMatrix,
    2202                 :                                     float aAppUnitsPerPixel,
    2203                 :                                     nsRect* aOutRect);
    2204                 : 
    2205                 :   /**
    2206                 :    * Returns the bounds of a frame as defined for resolving percentage
    2207                 :    * <translation-value>s in CSS transforms.  If
    2208                 :    * UNIFIED_CONTINUATIONS is not defined, this is simply the frame's bounding
    2209                 :    * rectangle, translated to the origin.  Otherwise, returns the smallest
    2210                 :    * rectangle containing a frame and all of its continuations.  For example,
    2211                 :    * if there is a <span> element with several continuations split over
    2212                 :    * several lines, this function will return the rectangle containing all of
    2213                 :    * those continuations.  This rectangle is relative to the origin of the
    2214                 :    * frame's local coordinate space.
    2215                 :    *
    2216                 :    * @param aFrame The frame to get the bounding rect for.
    2217                 :    * @return The frame's bounding rect, as described above.
    2218                 :    */
    2219                 :   static nsRect GetFrameBoundsForTransform(const nsIFrame* aFrame);
    2220                 : 
    2221                 :   /**
    2222                 :    * Given a frame with the -moz-transform property, returns the
    2223                 :    * transformation matrix for that frame.
    2224                 :    *
    2225                 :    * @param aFrame The frame to get the matrix from.
    2226                 :    * @param aOrigin Relative to which point this transform should be applied.
    2227                 :    * @param aAppUnitsPerPixel The number of app units per graphics unit.
    2228                 :    * @param aBoundsOverride [optional] If this is nsnull (the default), the
    2229                 :    *        computation will use the value of GetFrameBoundsForTransform(aFrame)
    2230                 :    *        for the frame's bounding rectangle. Otherwise, it will use the
    2231                 :    *        value of aBoundsOverride.  This is mostly for internal use and in
    2232                 :    *        most cases you will not need to specify a value.
    2233                 :    */
    2234                 :   static gfx3DMatrix GetResultingTransformMatrix(const nsIFrame* aFrame,
    2235                 :                                                  const nsPoint& aOrigin,
    2236                 :                                                  float aAppUnitsPerPixel,
    2237                 :                                                  const nsRect* aBoundsOverride = nsnull,
    2238                 :                                                  nsIFrame** aOutAncestor = nsnull);
    2239                 :   /**
    2240                 :    * Return true when we should try to prerender the entire contents of the
    2241                 :    * transformed frame even when it's not completely visible (yet).
    2242                 :    */
    2243                 :   static bool ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
    2244                 :                                                 nsIFrame* aFrame);
    2245                 : 
    2246                 : private:
    2247                 :   nsDisplayWrapList mStoredList;
    2248                 :   gfx3DMatrix mTransform;
    2249                 :   float mCachedAppUnitsPerPixel;
    2250                 :   PRUint32 mIndex;
    2251                 : };
    2252                 : 
    2253                 : /**
    2254                 :  * This class adds basic support for limiting the rendering to the part inside
    2255                 :  * the specified edges.  It's a base class for the display item classes that
    2256                 :  * does the actual work.  The two members, mLeftEdge and mRightEdge, are
    2257                 :  * relative to the edges of the frame's scrollable overflow rectangle and is
    2258                 :  * the amount to suppress on each side.
    2259                 :  *
    2260                 :  * Setting none, both or only one edge is allowed.
    2261                 :  * The values must be non-negative.
    2262                 :  * The default value for both edges is zero, which means everything is painted.
    2263                 :  */
    2264               0 : class nsCharClipDisplayItem : public nsDisplayItem {
    2265                 : public:
    2266               0 :   nsCharClipDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    2267               0 :     : nsDisplayItem(aBuilder, aFrame), mLeftEdge(0), mRightEdge(0) {}
    2268                 : 
    2269                 :   struct ClipEdges {
    2270               0 :     ClipEdges(const nsDisplayItem& aItem,
    2271                 :               nscoord aLeftEdge, nscoord aRightEdge) {
    2272               0 :       nsRect r = aItem.GetUnderlyingFrame()->GetScrollableOverflowRect() +
    2273               0 :                  aItem.ToReferenceFrame();
    2274               0 :       mX = aLeftEdge > 0 ? r.x + aLeftEdge : nscoord_MIN;
    2275               0 :       mXMost = aRightEdge > 0 ? NS_MAX(r.XMost() - aRightEdge, mX) : nscoord_MAX;
    2276               0 :     }
    2277               0 :     void Intersect(nscoord* aX, nscoord* aWidth) const {
    2278               0 :       nscoord xmost1 = *aX + *aWidth;
    2279               0 :       *aX = NS_MAX(*aX, mX);
    2280               0 :       *aWidth = NS_MAX(NS_MIN(xmost1, mXMost) - *aX, 0);
    2281               0 :     }
    2282                 :     nscoord mX;
    2283                 :     nscoord mXMost;
    2284                 :   };
    2285                 : 
    2286                 :   ClipEdges Edges() const { return ClipEdges(*this, mLeftEdge, mRightEdge); }
    2287                 : 
    2288               0 :   static nsCharClipDisplayItem* CheckCast(nsDisplayItem* aItem) {
    2289               0 :     nsDisplayItem::Type t = aItem->GetType();
    2290                 :     return (t == nsDisplayItem::TYPE_TEXT ||
    2291                 :             t == nsDisplayItem::TYPE_TEXT_DECORATION ||
    2292                 :             t == nsDisplayItem::TYPE_TEXT_SHADOW)
    2293               0 :       ? static_cast<nsCharClipDisplayItem*>(aItem) : nsnull;
    2294                 :   }
    2295                 : 
    2296                 :   nscoord mLeftEdge;  // length from the left side
    2297                 :   nscoord mRightEdge; // length from the right side
    2298                 : };
    2299                 : 
    2300                 : #endif /*NSDISPLAYLIST_H_*/

Generated by: LCOV version 1.7