layout/base/nsDisplayList.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/base/nsDisplayList.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,3413 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 + * vim: set ts=2 sw=2 et tw=78:
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.9 + */
    1.10 +
    1.11 +/*
    1.12 + * structures that represent things to be painted (ordered in z-order),
    1.13 + * used during painting and hit testing
    1.14 + */
    1.15 +
    1.16 +#ifndef NSDISPLAYLIST_H_
    1.17 +#define NSDISPLAYLIST_H_
    1.18 +
    1.19 +#include "mozilla/Attributes.h"
    1.20 +#include "nsCOMPtr.h"
    1.21 +#include "nsIFrame.h"
    1.22 +#include "nsPoint.h"
    1.23 +#include "nsRect.h"
    1.24 +#include "nsCaret.h"
    1.25 +#include "plarena.h"
    1.26 +#include "nsRegion.h"
    1.27 +#include "FrameLayerBuilder.h"
    1.28 +#include "nsLayoutUtils.h"
    1.29 +#include "nsDisplayListInvalidation.h"
    1.30 +#include "DisplayListClipState.h"
    1.31 +
    1.32 +#include <stdint.h>
    1.33 +
    1.34 +#include <stdlib.h>
    1.35 +#include <algorithm>
    1.36 +
    1.37 +class nsIContent;
    1.38 +class nsRenderingContext;
    1.39 +class nsDisplayTableItem;
    1.40 +class nsISelection;
    1.41 +class nsDisplayLayerEventRegions;
    1.42 +
    1.43 +namespace mozilla {
    1.44 +namespace layers {
    1.45 +class Layer;
    1.46 +class ImageLayer;
    1.47 +class ImageContainer;
    1.48 +} //namepsace
    1.49 +} //namepsace
    1.50 +
    1.51 +/*
    1.52 + * An nsIFrame can have many different visual parts. For example an image frame
    1.53 + * can have a background, border, and outline, the image itself, and a
    1.54 + * translucent selection overlay. In general these parts can be drawn at
    1.55 + * discontiguous z-levels; see CSS2.1 appendix E:
    1.56 + * http://www.w3.org/TR/CSS21/zindex.html
    1.57 + * 
    1.58 + * We construct a display list for a frame tree that contains one item
    1.59 + * for each visual part. The display list is itself a tree since some items
    1.60 + * are containers for other items; however, its structure does not match
    1.61 + * the structure of its source frame tree. The display list items are sorted
    1.62 + * by z-order. A display list can be used to paint the frames, to determine
    1.63 + * which frame is the target of a mouse event, and to determine what areas
    1.64 + * need to be repainted when scrolling. The display lists built for each task
    1.65 + * may be different for efficiency; in particular some frames need special
    1.66 + * display list items only for event handling, and do not create these items
    1.67 + * when the display list will be used for painting (the common case). For
    1.68 + * example, when painting we avoid creating nsDisplayBackground items for
    1.69 + * frames that don't display a visible background, but for event handling
    1.70 + * we need those backgrounds because they are not transparent to events.
    1.71 + * 
    1.72 + * We could avoid constructing an explicit display list by traversing the
    1.73 + * frame tree multiple times in clever ways. However, reifying the display list
    1.74 + * reduces code complexity and reduces the number of times each frame must be
    1.75 + * traversed to one, which seems to be good for performance. It also means
    1.76 + * we can share code for painting, event handling and scroll analysis.
    1.77 + * 
    1.78 + * Display lists are short-lived; content and frame trees cannot change
    1.79 + * between a display list being created and destroyed. Display lists should
    1.80 + * not be created during reflow because the frame tree may be in an
    1.81 + * inconsistent state (e.g., a frame's stored overflow-area may not include
    1.82 + * the bounds of all its children). However, it should be fine to create
    1.83 + * a display list while a reflow is pending, before it starts.
    1.84 + * 
    1.85 + * A display list covers the "extended" frame tree; the display list for a frame
    1.86 + * tree containing FRAME/IFRAME elements can include frames from the subdocuments.
    1.87 + *
    1.88 + * Display item's coordinates are relative to their nearest reference frame ancestor.
    1.89 + * Both the display root and any frame with a transform act as a reference frame
    1.90 + * for their frame subtrees.
    1.91 + */
    1.92 +
    1.93 +// All types are defined in nsDisplayItemTypes.h
    1.94 +#ifdef MOZ_DUMP_PAINTING
    1.95 +#define NS_DISPLAY_DECL_NAME(n, e) \
    1.96 +  virtual const char* Name() { return n; } \
    1.97 +  virtual Type GetType() { return e; }
    1.98 +#else
    1.99 +#define NS_DISPLAY_DECL_NAME(n, e) \
   1.100 +  virtual Type GetType() { return e; }
   1.101 +#endif
   1.102 +
   1.103 +/**
   1.104 + * This manages a display list and is passed as a parameter to
   1.105 + * nsIFrame::BuildDisplayList.
   1.106 + * It contains the parameters that don't change from frame to frame and manages
   1.107 + * the display list memory using a PLArena. It also establishes the reference
   1.108 + * coordinate system for all display list items. Some of the parameters are
   1.109 + * available from the prescontext/presshell, but we copy them into the builder
   1.110 + * for faster/more convenient access.
   1.111 + */
   1.112 +class nsDisplayListBuilder {
   1.113 +public:
   1.114 +  typedef mozilla::FramePropertyDescriptor FramePropertyDescriptor;
   1.115 +  typedef mozilla::FrameLayerBuilder FrameLayerBuilder;
   1.116 +  typedef mozilla::DisplayItemClip DisplayItemClip;
   1.117 +  typedef mozilla::DisplayListClipState DisplayListClipState;
   1.118 +  typedef nsIWidget::ThemeGeometry ThemeGeometry;
   1.119 +  typedef mozilla::layers::Layer Layer;
   1.120 +  typedef mozilla::layers::FrameMetrics::ViewID ViewID;
   1.121 +
   1.122 +  /**
   1.123 +   * @param aReferenceFrame the frame at the root of the subtree; its origin
   1.124 +   * is the origin of the reference coordinate system for this display list
   1.125 +   * @param aIsForEvents true if we're creating this list in order to
   1.126 +   * determine which frame is under the mouse position
   1.127 +   * @param aBuildCaret whether or not we should include the caret in any
   1.128 +   * display lists that we make.
   1.129 +   */
   1.130 +  enum Mode {
   1.131 +    PAINTING,
   1.132 +    EVENT_DELIVERY,
   1.133 +    PLUGIN_GEOMETRY,
   1.134 +    IMAGE_VISIBILITY,
   1.135 +    OTHER
   1.136 +  };
   1.137 +  nsDisplayListBuilder(nsIFrame* aReferenceFrame, Mode aMode, bool aBuildCaret);
   1.138 +  ~nsDisplayListBuilder();
   1.139 +
   1.140 +  void SetWillComputePluginGeometry(bool aWillComputePluginGeometry)
   1.141 +  {
   1.142 +    mWillComputePluginGeometry = aWillComputePluginGeometry;
   1.143 +  }
   1.144 +  void SetForPluginGeometry()
   1.145 +  {
   1.146 +    NS_ASSERTION(mMode == PAINTING, "Can only switch from PAINTING to PLUGIN_GEOMETRY");
   1.147 +    NS_ASSERTION(mWillComputePluginGeometry, "Should have signalled this in advance");
   1.148 +    mMode = PLUGIN_GEOMETRY;
   1.149 +  }
   1.150 +
   1.151 +  /**
   1.152 +   * @return true if the display is being built in order to determine which
   1.153 +   * frame is under the mouse position.
   1.154 +   */
   1.155 +  bool IsForEventDelivery() { return mMode == EVENT_DELIVERY; }
   1.156 +  /**
   1.157 +   * Be careful with this. The display list will be built in PAINTING mode
   1.158 +   * first and then switched to PLUGIN_GEOMETRY before a second call to
   1.159 +   * ComputeVisibility.
   1.160 +   * @return true if the display list is being built to compute geometry
   1.161 +   * for plugins.
   1.162 +   */
   1.163 +  bool IsForPluginGeometry() { return mMode == PLUGIN_GEOMETRY; }
   1.164 +  /**
   1.165 +   * @return true if the display list is being built for painting.
   1.166 +   */
   1.167 +  bool IsForPainting() { return mMode == PAINTING; }
   1.168 +  /**
   1.169 +   * @return true if the display list is being built for determining image
   1.170 +   * visibility.
   1.171 +   */
   1.172 +  bool IsForImageVisibility() { return mMode == IMAGE_VISIBILITY; }
   1.173 +  bool WillComputePluginGeometry() { return mWillComputePluginGeometry; }
   1.174 +  /**
   1.175 +   * @return true if "painting is suppressed" during page load and we
   1.176 +   * should paint only the background of the document.
   1.177 +   */
   1.178 +  bool IsBackgroundOnly() {
   1.179 +    NS_ASSERTION(mPresShellStates.Length() > 0,
   1.180 +                 "don't call this if we're not in a presshell");
   1.181 +    return CurrentPresShellState()->mIsBackgroundOnly;
   1.182 +  }
   1.183 +  /**
   1.184 +   * @return true if the currently active BuildDisplayList call is being
   1.185 +   * applied to a frame at the root of a pseudo stacking context. A pseudo
   1.186 +   * stacking context is either a real stacking context or basically what
   1.187 +   * CSS2.1 appendix E refers to with "treat the element as if it created
   1.188 +   * a new stacking context
   1.189 +   */
   1.190 +  bool IsAtRootOfPseudoStackingContext() { return mIsAtRootOfPseudoStackingContext; }
   1.191 +
   1.192 +  /**
   1.193 +   * @return the selection that painting should be restricted to (or nullptr
   1.194 +   * in the normal unrestricted case)
   1.195 +   */
   1.196 +  nsISelection* GetBoundingSelection() { return mBoundingSelection; }
   1.197 +
   1.198 +  /**
   1.199 +   * @return the root of given frame's (sub)tree, whose origin
   1.200 +   * establishes the coordinate system for the child display items.
   1.201 +   */
   1.202 +  const nsIFrame* FindReferenceFrameFor(const nsIFrame *aFrame)
   1.203 +  {
   1.204 +    if (aFrame == mCachedOffsetFrame) {
   1.205 +      return mCachedReferenceFrame;
   1.206 +    }
   1.207 +    for (const nsIFrame* f = aFrame; f; f = nsLayoutUtils::GetCrossDocParentFrame(f))
   1.208 +    {
   1.209 +      if (f == mReferenceFrame || f->IsTransformed()) {
   1.210 +        mCachedOffsetFrame = aFrame;
   1.211 +        mCachedReferenceFrame = f;
   1.212 +        mCachedOffset = aFrame->GetOffsetToCrossDoc(f);
   1.213 +        return f;
   1.214 +      }
   1.215 +    }
   1.216 +    mCachedOffsetFrame = aFrame;
   1.217 +    mCachedReferenceFrame = mReferenceFrame;
   1.218 +    mCachedOffset = aFrame->GetOffsetToCrossDoc(mReferenceFrame);
   1.219 +    return mReferenceFrame;
   1.220 +  }
   1.221 +  
   1.222 +  /**
   1.223 +   * @return the root of the display list's frame (sub)tree, whose origin
   1.224 +   * establishes the coordinate system for the display list
   1.225 +   */
   1.226 +  nsIFrame* RootReferenceFrame() 
   1.227 +  {
   1.228 +    return mReferenceFrame;
   1.229 +  }
   1.230 +
   1.231 +  /**
   1.232 +   * @return a point pt such that adding pt to a coordinate relative to aFrame
   1.233 +   * makes it relative to ReferenceFrame(), i.e., returns 
   1.234 +   * aFrame->GetOffsetToCrossDoc(ReferenceFrame()). The returned point is in
   1.235 +   * the appunits of aFrame. It may be optimized to be faster than
   1.236 +   * aFrame->GetOffsetToCrossDoc(ReferenceFrame()) (but currently isn't).
   1.237 +   */
   1.238 +  const nsPoint& ToReferenceFrame(const nsIFrame* aFrame) {
   1.239 +    if (aFrame != mCachedOffsetFrame) {
   1.240 +      FindReferenceFrameFor(aFrame);
   1.241 +    }
   1.242 +    return mCachedOffset;
   1.243 +  }
   1.244 +  /**
   1.245 +   * When building the display list, the scrollframe aFrame will be "ignored"
   1.246 +   * for the purposes of clipping, and its scrollbars will be hidden. We use
   1.247 +   * this to allow RenderOffscreen to render a whole document without beign
   1.248 +   * clipped by the viewport or drawing the viewport scrollbars.
   1.249 +   */
   1.250 +  void SetIgnoreScrollFrame(nsIFrame* aFrame) { mIgnoreScrollFrame = aFrame; }
   1.251 +  /**
   1.252 +   * Get the scrollframe to ignore, if any.
   1.253 +   */
   1.254 +  nsIFrame* GetIgnoreScrollFrame() { return mIgnoreScrollFrame; }
   1.255 +  /**
   1.256 +   * Get the ViewID of the nearest scrolling ancestor frame.
   1.257 +   */
   1.258 +  ViewID GetCurrentScrollParentId() const { return mCurrentScrollParentId; }
   1.259 +  /**
   1.260 +   * Calling this setter makes us include all out-of-flow descendant
   1.261 +   * frames in the display list, wherever they may be positioned (even
   1.262 +   * outside the dirty rects).
   1.263 +   */
   1.264 +  void SetIncludeAllOutOfFlows() { mIncludeAllOutOfFlows = true; }
   1.265 +  bool GetIncludeAllOutOfFlows() const { return mIncludeAllOutOfFlows; }
   1.266 +  /**
   1.267 +   * Calling this setter makes us exclude all leaf frames that aren't
   1.268 +   * selected.
   1.269 +   */
   1.270 +  void SetSelectedFramesOnly() { mSelectedFramesOnly = true; }
   1.271 +  bool GetSelectedFramesOnly() { return mSelectedFramesOnly; }
   1.272 +  /**
   1.273 +   * Calling this setter makes us compute accurate visible regions at the cost
   1.274 +   * of performance if regions get very complex.
   1.275 +   */
   1.276 +  void SetAccurateVisibleRegions() { mAccurateVisibleRegions = true; }
   1.277 +  bool GetAccurateVisibleRegions() { return mAccurateVisibleRegions; }
   1.278 +  /**
   1.279 +   * Allows callers to selectively override the regular paint suppression checks,
   1.280 +   * so that methods like GetFrameForPoint work when painting is suppressed.
   1.281 +   */
   1.282 +  void IgnorePaintSuppression() { mIgnoreSuppression = true; }
   1.283 +  /**
   1.284 +   * @return Returns if this builder will ignore paint suppression.
   1.285 +   */
   1.286 +  bool IsIgnoringPaintSuppression() { return mIgnoreSuppression; }
   1.287 +  /**
   1.288 +   * @return Returns if this builder had to ignore painting suppression on some
   1.289 +   * document when building the display list.
   1.290 +   */
   1.291 +  bool GetHadToIgnorePaintSuppression() { return mHadToIgnoreSuppression; }
   1.292 +  /**
   1.293 +   * Call this if we're doing normal painting to the window.
   1.294 +   */
   1.295 +  void SetPaintingToWindow(bool aToWindow) { mIsPaintingToWindow = aToWindow; }
   1.296 +  bool IsPaintingToWindow() const { return mIsPaintingToWindow; }
   1.297 +  /**
   1.298 +   * Call this to prevent descending into subdocuments.
   1.299 +   */
   1.300 +  void SetDescendIntoSubdocuments(bool aDescend) { mDescendIntoSubdocuments = aDescend; }
   1.301 +  bool GetDescendIntoSubdocuments() { return mDescendIntoSubdocuments; }
   1.302 +
   1.303 +  /**
   1.304 +   * Returns true if merging and flattening of display lists should be
   1.305 +   * performed while computing visibility.
   1.306 +   */
   1.307 +  bool AllowMergingAndFlattening() { return mAllowMergingAndFlattening; }
   1.308 +  void SetAllowMergingAndFlattening(bool aAllow) { mAllowMergingAndFlattening = aAllow; }
   1.309 +
   1.310 +  nsDisplayLayerEventRegions* GetLayerEventRegions() { return mLayerEventRegions; }
   1.311 +  void SetLayerEventRegions(nsDisplayLayerEventRegions* aItem)
   1.312 +  {
   1.313 +    mLayerEventRegions = aItem;
   1.314 +  }
   1.315 +  bool IsBuildingLayerEventRegions()
   1.316 +  {
   1.317 +    // Disable for now.
   1.318 +    return false;
   1.319 +    // return mMode == PAINTING;
   1.320 +  }
   1.321 +
   1.322 +  bool GetAncestorHasTouchEventHandler() { return mAncestorHasTouchEventHandler; }
   1.323 +  void SetAncestorHasTouchEventHandler(bool aValue)
   1.324 +  {
   1.325 +    mAncestorHasTouchEventHandler = aValue;
   1.326 +  }
   1.327 +
   1.328 +  bool HaveScrollableDisplayPort() const { return mHaveScrollableDisplayPort; }
   1.329 +  void SetHaveScrollableDisplayPort() { mHaveScrollableDisplayPort = true; }
   1.330 +
   1.331 +  bool SetIsCompositingCheap(bool aCompositingCheap) { 
   1.332 +    bool temp = mIsCompositingCheap; 
   1.333 +    mIsCompositingCheap = aCompositingCheap;
   1.334 +    return temp;
   1.335 +  }
   1.336 +  bool IsCompositingCheap() const { return mIsCompositingCheap; }
   1.337 +  /**
   1.338 +   * Display the caret if needed.
   1.339 +   */
   1.340 +  void DisplayCaret(nsIFrame* aFrame, const nsRect& aDirtyRect,
   1.341 +                    nsDisplayList* aList) {
   1.342 +    nsIFrame* frame = GetCaretFrame();
   1.343 +    if (aFrame == frame) {
   1.344 +      frame->DisplayCaret(this, aDirtyRect, aList);
   1.345 +    }
   1.346 +  }
   1.347 +  /**
   1.348 +   * Get the frame that the caret is supposed to draw in.
   1.349 +   * If the caret is currently invisible, this will be null.
   1.350 +   */
   1.351 +  nsIFrame* GetCaretFrame() {
   1.352 +    return CurrentPresShellState()->mCaretFrame;
   1.353 +  }
   1.354 +  /**
   1.355 +   * Get the caret associated with the current presshell.
   1.356 +   */
   1.357 +  nsCaret* GetCaret();
   1.358 +  /**
   1.359 +   * Notify the display list builder that we're entering a presshell.
   1.360 +   * aReferenceFrame should be a frame in the new presshell and aDirtyRect
   1.361 +   * should be the current dirty rect in aReferenceFrame's coordinate space.
   1.362 +   */
   1.363 +  void EnterPresShell(nsIFrame* aReferenceFrame, const nsRect& aDirtyRect);
   1.364 +  /**
   1.365 +   * For print-preview documents, we sometimes need to build display items for
   1.366 +   * the same frames multiple times in the same presentation, with different
   1.367 +   * clipping. Between each such batch of items, call
   1.368 +   * ResetMarkedFramesForDisplayList to make sure that the results of
   1.369 +   * MarkFramesForDisplayList do not carry over between batches.
   1.370 +   */
   1.371 +  void ResetMarkedFramesForDisplayList();
   1.372 +  /**
   1.373 +   * Notify the display list builder that we're leaving a presshell.
   1.374 +   */
   1.375 +  void LeavePresShell(nsIFrame* aReferenceFrame, const nsRect& aDirtyRect);
   1.376 +
   1.377 +  /**
   1.378 +   * Returns true if we're currently building a display list that's
   1.379 +   * directly or indirectly under an nsDisplayTransform.
   1.380 +   */
   1.381 +  bool IsInTransform() const { return mInTransform; }
   1.382 +  /**
   1.383 +   * Indicate whether or not we're directly or indirectly under and
   1.384 +   * nsDisplayTransform or SVG foreignObject.
   1.385 +   */
   1.386 +  void SetInTransform(bool aInTransform) { mInTransform = aInTransform; }
   1.387 +
   1.388 +  /**
   1.389 +   * Returns true if we're currently building display items that are in
   1.390 +   * true fixed position subtree.
   1.391 +   */
   1.392 +  bool IsInFixedPos() const { return mInFixedPos; }
   1.393 +
   1.394 +  /**
   1.395 +   * @return true if images have been set to decode synchronously.
   1.396 +   */
   1.397 +  bool ShouldSyncDecodeImages() { return mSyncDecodeImages; }
   1.398 +
   1.399 +  /**
   1.400 +   * Indicates whether we should synchronously decode images. If true, we decode
   1.401 +   * and draw whatever image data has been loaded. If false, we just draw
   1.402 +   * whatever has already been decoded.
   1.403 +   */
   1.404 +  void SetSyncDecodeImages(bool aSyncDecodeImages) {
   1.405 +    mSyncDecodeImages = aSyncDecodeImages;
   1.406 +  }
   1.407 +
   1.408 +  /**
   1.409 +   * Helper method to generate background painting flags based on the
   1.410 +   * information available in the display list builder. Currently only
   1.411 +   * accounts for mSyncDecodeImages.
   1.412 +   */
   1.413 +  uint32_t GetBackgroundPaintFlags();
   1.414 +
   1.415 +  /**
   1.416 +   * Subtracts aRegion from *aVisibleRegion. We avoid letting
   1.417 +   * aVisibleRegion become overcomplex by simplifying it if necessary ---
   1.418 +   * unless mAccurateVisibleRegions is set, in which case we let it
   1.419 +   * get arbitrarily complex.
   1.420 +   */
   1.421 +  void SubtractFromVisibleRegion(nsRegion* aVisibleRegion,
   1.422 +                                 const nsRegion& aRegion);
   1.423 +
   1.424 +  /**
   1.425 +   * Mark the frames in aFrames to be displayed if they intersect aDirtyRect
   1.426 +   * (which is relative to aDirtyFrame). If the frames have placeholders
   1.427 +   * that might not be displayed, we mark the placeholders and their ancestors
   1.428 +   * to ensure that display list construction descends into them
   1.429 +   * anyway. nsDisplayListBuilder will take care of unmarking them when it is
   1.430 +   * destroyed.
   1.431 +   */
   1.432 +  void MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
   1.433 +                                const nsFrameList& aFrames,
   1.434 +                                const nsRect& aDirtyRect);
   1.435 +  /**
   1.436 +   * Mark all child frames that Preserve3D() as needing display.
   1.437 +   * Because these frames include transforms set on their parent, dirty rects
   1.438 +   * for intermediate frames may be empty, yet child frames could still be visible.
   1.439 +   */
   1.440 +  void MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect);
   1.441 +
   1.442 +  /**
   1.443 +   * Get the area of the final transparent region.
   1.444 +   */
   1.445 +  const nsRegion* GetFinalTransparentRegion() { return mFinalTransparentRegion; }
   1.446 +  /**
   1.447 +   * Record the area of the final transparent region after all visibility
   1.448 +   * calculations were performed.
   1.449 +   */
   1.450 +  void SetFinalTransparentRegion(const nsRegion& aFinalTransparentRegion)
   1.451 +  {
   1.452 +    mFinalTransparentRegion = &aFinalTransparentRegion;
   1.453 +  }
   1.454 +
   1.455 +  const nsTArray<ThemeGeometry>& GetThemeGeometries() { return mThemeGeometries; }
   1.456 +
   1.457 +  /**
   1.458 +   * Returns true if we need to descend into this frame when building
   1.459 +   * the display list, even though it doesn't intersect the dirty
   1.460 +   * rect, because it may have out-of-flows that do so.
   1.461 +   */
   1.462 +  bool ShouldDescendIntoFrame(nsIFrame* aFrame) const {
   1.463 +    return
   1.464 +      (aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) ||
   1.465 +      GetIncludeAllOutOfFlows();
   1.466 +  }
   1.467 +
   1.468 +  /**
   1.469 +   * Notifies the builder that a particular themed widget exists
   1.470 +   * at the given rectangle within the currently built display list.
   1.471 +   * For certain appearance values (currently only
   1.472 +   * NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR, NS_THEME_TOOLBAR and
   1.473 +   * NS_THEME_WINDOW_TITLEBAR) this gets called during every display list
   1.474 +   * construction, for every themed widget of the right type within the
   1.475 +   * display list, except for themed widgets which are transformed or have
   1.476 +   * effects applied to them (e.g. CSS opacity or filters).
   1.477 +   *
   1.478 +   * @param aWidgetType the -moz-appearance value for the themed widget
   1.479 +   * @param aRect the device-pixel rect relative to the widget's displayRoot
   1.480 +   * for the themed widget
   1.481 +   */
   1.482 +  void RegisterThemeGeometry(uint8_t aWidgetType,
   1.483 +                             const nsIntRect& aRect) {
   1.484 +    if (mIsPaintingToWindow && mPresShellStates.Length() == 1) {
   1.485 +      ThemeGeometry geometry(aWidgetType, aRect);
   1.486 +      mThemeGeometries.AppendElement(geometry);
   1.487 +    }
   1.488 +  }
   1.489 +
   1.490 +  /**
   1.491 +   * Allocate memory in our arena. It will only be freed when this display list
   1.492 +   * builder is destroyed. This memory holds nsDisplayItems. nsDisplayItem
   1.493 +   * destructors are called as soon as the item is no longer used.
   1.494 +   */
   1.495 +  void* Allocate(size_t aSize);
   1.496 +
   1.497 +  /**
   1.498 +   * Allocate a new DisplayListClip in the arena. Will be cleaned up
   1.499 +   * automatically when the arena goes away.
   1.500 +   */
   1.501 +  const DisplayItemClip* AllocateDisplayItemClip(const DisplayItemClip& aOriginal);
   1.502 +
   1.503 +  /**
   1.504 +   * Transfer off main thread animations to the layer.  May be called
   1.505 +   * with aBuilder and aItem both null, but only if the caller has
   1.506 +   * already checked that off main thread animations should be sent to
   1.507 +   * the layer.  When they are both null, the animations are added to
   1.508 +   * the layer as pending animations.
   1.509 +   */
   1.510 +  static void AddAnimationsAndTransitionsToLayer(Layer* aLayer,
   1.511 +                                                 nsDisplayListBuilder* aBuilder,
   1.512 +                                                 nsDisplayItem* aItem,
   1.513 +                                                 nsIFrame* aFrame,
   1.514 +                                                 nsCSSProperty aProperty);
   1.515 +  /**
   1.516 +   * A helper class to temporarily set the value of
   1.517 +   * mIsAtRootOfPseudoStackingContext, and temporarily
   1.518 +   * update mCachedOffsetFrame/mCachedOffset from a frame to its child.
   1.519 +   * Also saves and restores mClipState.
   1.520 +   */
   1.521 +  class AutoBuildingDisplayList;
   1.522 +  friend class AutoBuildingDisplayList;
   1.523 +  class AutoBuildingDisplayList {
   1.524 +  public:
   1.525 +    AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, bool aIsRoot)
   1.526 +      : mBuilder(aBuilder),
   1.527 +        mPrevCachedOffsetFrame(aBuilder->mCachedOffsetFrame),
   1.528 +        mPrevCachedReferenceFrame(aBuilder->mCachedReferenceFrame),
   1.529 +        mPrevLayerEventRegions(aBuilder->mLayerEventRegions),
   1.530 +        mPrevCachedOffset(aBuilder->mCachedOffset),
   1.531 +        mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext),
   1.532 +        mPrevAncestorHasTouchEventHandler(aBuilder->mAncestorHasTouchEventHandler)
   1.533 +    {
   1.534 +      aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
   1.535 +    }
   1.536 +    AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder,
   1.537 +                            nsIFrame* aForChild, bool aIsRoot)
   1.538 +      : mBuilder(aBuilder),
   1.539 +        mPrevCachedOffsetFrame(aBuilder->mCachedOffsetFrame),
   1.540 +        mPrevCachedReferenceFrame(aBuilder->mCachedReferenceFrame),
   1.541 +        mPrevLayerEventRegions(aBuilder->mLayerEventRegions),
   1.542 +        mPrevCachedOffset(aBuilder->mCachedOffset),
   1.543 +        mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext),
   1.544 +        mPrevAncestorHasTouchEventHandler(aBuilder->mAncestorHasTouchEventHandler)
   1.545 +    {
   1.546 +      if (aForChild->IsTransformed()) {
   1.547 +        aBuilder->mCachedOffset = nsPoint();
   1.548 +        aBuilder->mCachedReferenceFrame = aForChild;
   1.549 +      } else if (mPrevCachedOffsetFrame == aForChild->GetParent()) {
   1.550 +        aBuilder->mCachedOffset += aForChild->GetPosition();
   1.551 +      } else {
   1.552 +        aBuilder->mCachedOffset = aBuilder->ToReferenceFrame(aForChild);
   1.553 +      }
   1.554 +      aBuilder->mCachedOffsetFrame = aForChild;
   1.555 +      aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
   1.556 +    }
   1.557 +    ~AutoBuildingDisplayList() {
   1.558 +      mBuilder->mCachedOffsetFrame = mPrevCachedOffsetFrame;
   1.559 +      mBuilder->mCachedReferenceFrame = mPrevCachedReferenceFrame;
   1.560 +      mBuilder->mLayerEventRegions = mPrevLayerEventRegions;
   1.561 +      mBuilder->mCachedOffset = mPrevCachedOffset;
   1.562 +      mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext;
   1.563 +      mBuilder->mAncestorHasTouchEventHandler = mPrevAncestorHasTouchEventHandler;
   1.564 +    }
   1.565 +  private:
   1.566 +    nsDisplayListBuilder* mBuilder;
   1.567 +    const nsIFrame*       mPrevCachedOffsetFrame;
   1.568 +    const nsIFrame*       mPrevCachedReferenceFrame;
   1.569 +    nsDisplayLayerEventRegions* mPrevLayerEventRegions;
   1.570 +    nsPoint               mPrevCachedOffset;
   1.571 +    bool                  mPrevIsAtRootOfPseudoStackingContext;
   1.572 +    bool                  mPrevAncestorHasTouchEventHandler;
   1.573 +  };
   1.574 +
   1.575 +  /**
   1.576 +   * A helper class to temporarily set the value of mInTransform.
   1.577 +   */
   1.578 +  class AutoInTransformSetter;
   1.579 +  friend class AutoInTransformSetter;
   1.580 +  class AutoInTransformSetter {
   1.581 +  public:
   1.582 +    AutoInTransformSetter(nsDisplayListBuilder* aBuilder, bool aInTransform)
   1.583 +      : mBuilder(aBuilder), mOldValue(aBuilder->mInTransform) {
   1.584 +      aBuilder->mInTransform = aInTransform;
   1.585 +    }
   1.586 +    ~AutoInTransformSetter() {
   1.587 +      mBuilder->mInTransform = mOldValue;
   1.588 +    }
   1.589 +  private:
   1.590 +    nsDisplayListBuilder* mBuilder;
   1.591 +    bool                  mOldValue;
   1.592 +  };
   1.593 +
   1.594 +  /**
   1.595 +   * A helper class to temporarily set the value of mInFixedPos.
   1.596 +   */
   1.597 +  class AutoInFixedPosSetter;
   1.598 +  friend class AutoInFixedPosSetter;
   1.599 +  class AutoInFixedPosSetter {
   1.600 +  public:
   1.601 +    AutoInFixedPosSetter(nsDisplayListBuilder* aBuilder, bool aInFixedPos)
   1.602 +      : mBuilder(aBuilder), mOldValue(aBuilder->mInFixedPos) {
   1.603 +      aBuilder->mInFixedPos = aInFixedPos;
   1.604 +    }
   1.605 +    ~AutoInFixedPosSetter() {
   1.606 +      mBuilder->mInFixedPos = mOldValue;
   1.607 +    }
   1.608 +  private:
   1.609 +    nsDisplayListBuilder* mBuilder;
   1.610 +    bool                  mOldValue;
   1.611 +  };
   1.612 +
   1.613 +  /**
   1.614 +   * A helper class to temporarily set the value of mCurrentScrollParentId.
   1.615 +   */
   1.616 +  class AutoCurrentScrollParentIdSetter;
   1.617 +  friend class AutoCurrentScrollParentIdSetter;
   1.618 +  class AutoCurrentScrollParentIdSetter {
   1.619 +  public:
   1.620 +    AutoCurrentScrollParentIdSetter(nsDisplayListBuilder* aBuilder, ViewID aScrollId)
   1.621 +      : mBuilder(aBuilder), mOldValue(aBuilder->mCurrentScrollParentId) {
   1.622 +      aBuilder->mCurrentScrollParentId = aScrollId;
   1.623 +    }
   1.624 +    ~AutoCurrentScrollParentIdSetter() {
   1.625 +      mBuilder->mCurrentScrollParentId = mOldValue;
   1.626 +    }
   1.627 +  private:
   1.628 +    nsDisplayListBuilder* mBuilder;
   1.629 +    ViewID                mOldValue;
   1.630 +  };
   1.631 +
   1.632 +  // Helpers for tables
   1.633 +  nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; }
   1.634 +  void SetCurrentTableItem(nsDisplayTableItem* aTableItem) { mCurrentTableItem = aTableItem; }
   1.635 +
   1.636 +  struct OutOfFlowDisplayData {
   1.637 +    OutOfFlowDisplayData(const DisplayItemClip& aContainingBlockClip,
   1.638 +                         const nsRect &aDirtyRect)
   1.639 +      : mContainingBlockClip(aContainingBlockClip)
   1.640 +      , mDirtyRect(aDirtyRect)
   1.641 +    {}
   1.642 +    OutOfFlowDisplayData(const nsRect &aDirtyRect)
   1.643 +      : mDirtyRect(aDirtyRect)
   1.644 +    {}
   1.645 +    DisplayItemClip mContainingBlockClip;
   1.646 +    nsRect mDirtyRect;
   1.647 +  };
   1.648 +  static void DestroyOutOfFlowDisplayData(void* aPropertyValue)
   1.649 +  {
   1.650 +    delete static_cast<OutOfFlowDisplayData*>(aPropertyValue);
   1.651 +  }
   1.652 +
   1.653 +  NS_DECLARE_FRAME_PROPERTY(OutOfFlowDisplayDataProperty, DestroyOutOfFlowDisplayData)
   1.654 +  NS_DECLARE_FRAME_PROPERTY(Preserve3DDirtyRectProperty, nsIFrame::DestroyRect)
   1.655 +
   1.656 +  nsPresContext* CurrentPresContext() {
   1.657 +    return CurrentPresShellState()->mPresShell->GetPresContext();
   1.658 +  }
   1.659 +
   1.660 +  /**
   1.661 +   * Accumulates the bounds of box frames that have moz-appearance
   1.662 +   * -moz-win-exclude-glass style. Used in setting glass margins on
   1.663 +   * Windows.
   1.664 +   */  
   1.665 +  void AddExcludedGlassRegion(nsRect &bounds) {
   1.666 +    mExcludedGlassRegion.Or(mExcludedGlassRegion, bounds);
   1.667 +  }
   1.668 +  const nsRegion& GetExcludedGlassRegion() {
   1.669 +    return mExcludedGlassRegion;
   1.670 +  }
   1.671 +  void SetGlassDisplayItem(nsDisplayItem* aItem) {
   1.672 +    if (mGlassDisplayItem) {
   1.673 +      // Web pages or extensions could trigger this by using
   1.674 +      // -moz-appearance:win-borderless-glass etc on their own elements.
   1.675 +      // Keep the first one, since that will be the background of the root
   1.676 +      // window
   1.677 +      NS_WARNING("Multiple glass backgrounds found?");
   1.678 +    } else {
   1.679 +      mGlassDisplayItem = aItem;
   1.680 +    }
   1.681 +  }
   1.682 +  bool NeedToForceTransparentSurfaceForItem(nsDisplayItem* aItem) {
   1.683 +    return aItem == mGlassDisplayItem;
   1.684 +  }
   1.685 +
   1.686 +  void SetContainsPluginItem() { mContainsPluginItem = true; }
   1.687 +  bool ContainsPluginItem() { return mContainsPluginItem; }
   1.688 +
   1.689 +  /**
   1.690 +   * mContainsBlendMode is true if we processed a display item that
   1.691 +   * has a blend mode attached. We do this so we can insert a 
   1.692 +   * nsDisplayBlendContainer in the parent stacking context.
   1.693 +   */
   1.694 +  void SetContainsBlendMode(bool aContainsBlendMode) { mContainsBlendMode = aContainsBlendMode; }
   1.695 +  bool ContainsBlendMode() const { return mContainsBlendMode; }
   1.696 +
   1.697 +  DisplayListClipState& ClipState() { return mClipState; }
   1.698 +
   1.699 +private:
   1.700 +  void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame,
   1.701 +                                    const nsRect& aDirtyRect);
   1.702 +
   1.703 +  struct PresShellState {
   1.704 +    nsIPresShell* mPresShell;
   1.705 +    nsIFrame*     mCaretFrame;
   1.706 +    uint32_t      mFirstFrameMarkedForDisplay;
   1.707 +    bool          mIsBackgroundOnly;
   1.708 +  };
   1.709 +  PresShellState* CurrentPresShellState() {
   1.710 +    NS_ASSERTION(mPresShellStates.Length() > 0,
   1.711 +                 "Someone forgot to enter a presshell");
   1.712 +    return &mPresShellStates[mPresShellStates.Length() - 1];
   1.713 +  }
   1.714 +
   1.715 +  nsIFrame*                      mReferenceFrame;
   1.716 +  nsIFrame*                      mIgnoreScrollFrame;
   1.717 +  nsDisplayLayerEventRegions*    mLayerEventRegions;
   1.718 +  PLArenaPool                    mPool;
   1.719 +  nsCOMPtr<nsISelection>         mBoundingSelection;
   1.720 +  nsAutoTArray<PresShellState,8> mPresShellStates;
   1.721 +  nsAutoTArray<nsIFrame*,100>    mFramesMarkedForDisplay;
   1.722 +  nsAutoTArray<ThemeGeometry,2>  mThemeGeometries;
   1.723 +  nsDisplayTableItem*            mCurrentTableItem;
   1.724 +  DisplayListClipState           mClipState;
   1.725 +  const nsRegion*                mFinalTransparentRegion;
   1.726 +  // When mCachedOffsetFrame is non-null, mCachedOffset is the offset from
   1.727 +  // mCachedOffsetFrame to mReferenceFrame.
   1.728 +  const nsIFrame*                mCachedOffsetFrame;
   1.729 +  const nsIFrame*                mCachedReferenceFrame;
   1.730 +  nsPoint                        mCachedOffset;
   1.731 +  nsRegion                       mExcludedGlassRegion;
   1.732 +  // The display item for the Windows window glass background, if any
   1.733 +  nsDisplayItem*                 mGlassDisplayItem;
   1.734 +  nsTArray<DisplayItemClip*>     mDisplayItemClipsToDestroy;
   1.735 +  Mode                           mMode;
   1.736 +  ViewID                         mCurrentScrollParentId;
   1.737 +  bool                           mBuildCaret;
   1.738 +  bool                           mIgnoreSuppression;
   1.739 +  bool                           mHadToIgnoreSuppression;
   1.740 +  bool                           mIsAtRootOfPseudoStackingContext;
   1.741 +  bool                           mIncludeAllOutOfFlows;
   1.742 +  bool                           mDescendIntoSubdocuments;
   1.743 +  bool                           mSelectedFramesOnly;
   1.744 +  bool                           mAccurateVisibleRegions;
   1.745 +  bool                           mAllowMergingAndFlattening;
   1.746 +  bool                           mWillComputePluginGeometry;
   1.747 +  // True when we're building a display list that's directly or indirectly
   1.748 +  // under an nsDisplayTransform
   1.749 +  bool                           mInTransform;
   1.750 +  bool                           mInFixedPos;
   1.751 +  bool                           mSyncDecodeImages;
   1.752 +  bool                           mIsPaintingToWindow;
   1.753 +  bool                           mIsCompositingCheap;
   1.754 +  bool                           mContainsPluginItem;
   1.755 +  bool                           mContainsBlendMode;
   1.756 +  bool                           mAncestorHasTouchEventHandler;
   1.757 +  // True when the first async-scrollable scroll frame for which we build a
   1.758 +  // display list has a display port. An async-scrollable scroll frame is one
   1.759 +  // which WantsAsyncScroll().
   1.760 +  bool                           mHaveScrollableDisplayPort;
   1.761 +};
   1.762 +
   1.763 +class nsDisplayItem;
   1.764 +class nsDisplayList;
   1.765 +/**
   1.766 + * nsDisplayItems are put in singly-linked lists rooted in an nsDisplayList.
   1.767 + * nsDisplayItemLink holds the link. The lists are linked from lowest to
   1.768 + * highest in z-order.
   1.769 + */
   1.770 +class nsDisplayItemLink {
   1.771 +  // This is never instantiated directly, so no need to count constructors and
   1.772 +  // destructors.
   1.773 +protected:
   1.774 +  nsDisplayItemLink() : mAbove(nullptr) {}
   1.775 +  nsDisplayItem* mAbove;  
   1.776 +  
   1.777 +  friend class nsDisplayList;
   1.778 +};
   1.779 +
   1.780 +/**
   1.781 + * This is the unit of rendering and event testing. Each instance of this
   1.782 + * class represents an entity that can be drawn on the screen, e.g., a
   1.783 + * frame's CSS background, or a frame's text string.
   1.784 + * 
   1.785 + * nsDisplayListItems can be containers --- i.e., they can perform hit testing
   1.786 + * and painting by recursively traversing a list of child items.
   1.787 + * 
   1.788 + * These are arena-allocated during display list construction. A typical
   1.789 + * subclass would just have a frame pointer, so its object would be just three
   1.790 + * pointers (vtable, next-item, frame).
   1.791 + * 
   1.792 + * Display items belong to a list at all times (except temporarily as they
   1.793 + * move from one list to another).
   1.794 + */
   1.795 +class nsDisplayItem : public nsDisplayItemLink {
   1.796 +public:
   1.797 +  typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
   1.798 +  typedef mozilla::DisplayItemClip DisplayItemClip;
   1.799 +  typedef mozilla::layers::FrameMetrics::ViewID ViewID;
   1.800 +  typedef mozilla::layers::Layer Layer;
   1.801 +  typedef mozilla::layers::LayerManager LayerManager;
   1.802 +  typedef mozilla::LayerState LayerState;
   1.803 +
   1.804 +  // This is never instantiated directly (it has pure virtual methods), so no
   1.805 +  // need to count constructors and destructors.
   1.806 +  nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
   1.807 +    : mFrame(aFrame)
   1.808 +    , mClip(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder))
   1.809 +    , mInFixedPos(aBuilder->IsInFixedPos())
   1.810 +#ifdef MOZ_DUMP_PAINTING
   1.811 +    , mPainted(false)
   1.812 +#endif
   1.813 +  {
   1.814 +    mReferenceFrame = aBuilder->FindReferenceFrameFor(aFrame);
   1.815 +    mToReferenceFrame = aBuilder->ToReferenceFrame(aFrame);
   1.816 +  }
   1.817 +  nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
   1.818 +                const nsIFrame* aReferenceFrame,
   1.819 +                const nsPoint& aToReferenceFrame)
   1.820 +    : mFrame(aFrame)
   1.821 +    , mClip(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder))
   1.822 +    , mReferenceFrame(aReferenceFrame)
   1.823 +    , mToReferenceFrame(aToReferenceFrame)
   1.824 +    , mInFixedPos(aBuilder->IsInFixedPos())
   1.825 +#ifdef MOZ_DUMP_PAINTING
   1.826 +    , mPainted(false)
   1.827 +#endif
   1.828 +  {
   1.829 +  }
   1.830 +  /**
   1.831 +   * This constructor is only used in rare cases when we need to construct
   1.832 +   * temporary items.
   1.833 +   */
   1.834 +  nsDisplayItem(nsIFrame* aFrame)
   1.835 +    : mFrame(aFrame)
   1.836 +    , mClip(nullptr)
   1.837 +    , mReferenceFrame(nullptr)
   1.838 +    , mInFixedPos(false)
   1.839 +#ifdef MOZ_DUMP_PAINTING
   1.840 +    , mPainted(false)
   1.841 +#endif
   1.842 +  {
   1.843 +  }
   1.844 +  virtual ~nsDisplayItem() {}
   1.845 +  
   1.846 +  void* operator new(size_t aSize,
   1.847 +                     nsDisplayListBuilder* aBuilder) CPP_THROW_NEW {
   1.848 +    return aBuilder->Allocate(aSize);
   1.849 +  }
   1.850 +
   1.851 +// Contains all the type integers for each display list item type
   1.852 +#include "nsDisplayItemTypes.h"
   1.853 +
   1.854 +  struct HitTestState {
   1.855 +    typedef nsTArray<ViewID> ShadowArray;
   1.856 +
   1.857 +    HitTestState(ShadowArray* aShadows = nullptr)
   1.858 +      : mShadows(aShadows) {
   1.859 +    }
   1.860 +
   1.861 +    ~HitTestState() {
   1.862 +      NS_ASSERTION(mItemBuffer.Length() == 0,
   1.863 +                   "mItemBuffer should have been cleared");
   1.864 +    }
   1.865 +
   1.866 +    nsAutoTArray<nsDisplayItem*, 100> mItemBuffer;
   1.867 +
   1.868 +    // It is sometimes useful to hit test for frames that are not in this
   1.869 +    // process. Display items may append IDs into this array if it is
   1.870 +    // non-null.
   1.871 +    ShadowArray* mShadows;
   1.872 +  };
   1.873 +
   1.874 +  /**
   1.875 +   * Some consecutive items should be rendered together as a unit, e.g.,
   1.876 +   * outlines for the same element. For this, we need a way for items to
   1.877 +   * identify their type. We use the type for other purposes too.
   1.878 +   */
   1.879 +  virtual Type GetType() = 0;
   1.880 +  /**
   1.881 +   * Pairing this with the GetUnderlyingFrame() pointer gives a key that
   1.882 +   * uniquely identifies this display item in the display item tree.
   1.883 +   * XXX check ScrollLayerWrapper/nsOptionEventGrabberWrapper/nsXULEventRedirectorWrapper
   1.884 +   */
   1.885 +  virtual uint32_t GetPerFrameKey() { return uint32_t(GetType()); }
   1.886 +  /**
   1.887 +   * This is called after we've constructed a display list for event handling.
   1.888 +   * When this is called, we've already ensured that aRect intersects the
   1.889 +   * item's bounds and that clipping has been taking into account.
   1.890 +   *
   1.891 +   * @param aRect the point or rect being tested, relative to the reference
   1.892 +   * frame. If the width and height are both 1 app unit, it indicates we're
   1.893 +   * hit testing a point, not a rect.
   1.894 +   * @param aState must point to a HitTestState. If you don't have one,
   1.895 +   * just create one with the default constructor and pass it in.
   1.896 +   * @param aOutFrames each item appends the frame(s) in this display item that
   1.897 +   * the rect is considered over (if any) to aOutFrames.
   1.898 +   */
   1.899 +  virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
   1.900 +                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {}
   1.901 +  /**
   1.902 +   * @return the frame that this display item is based on. This is used to sort
   1.903 +   * items by z-index and content order and for some other uses. Never
   1.904 +   * returns null.
   1.905 +   */
   1.906 +  inline nsIFrame* Frame() const { return mFrame; }
   1.907 +  /**
   1.908 +   * Compute the used z-index of our frame; returns zero for elements to which
   1.909 +   * z-index does not apply, and for z-index:auto.
   1.910 +   * @note This can be overridden, @see nsDisplayWrapList::SetOverrideZIndex.
   1.911 +   */
   1.912 +  virtual int32_t ZIndex() const;
   1.913 +  /**
   1.914 +   * The default bounds is the frame border rect.
   1.915 +   * @param aSnap *aSnap is set to true if the returned rect will be
   1.916 +   * snapped to nearest device pixel edges during actual drawing.
   1.917 +   * It might be set to false and snap anyway, so code computing the set of
   1.918 +   * pixels affected by this display item needs to round outwards to pixel
   1.919 +   * boundaries when *aSnap is set to false.
   1.920 +   * This does not take the item's clipping into account.
   1.921 +   * @return a rectangle relative to aBuilder->ReferenceFrame() that
   1.922 +   * contains the area drawn by this display item
   1.923 +   */
   1.924 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
   1.925 +  {
   1.926 +    *aSnap = false;
   1.927 +    return nsRect(ToReferenceFrame(), Frame()->GetSize());
   1.928 +  }
   1.929 +  /**
   1.930 +   * Returns the result of GetBounds intersected with the item's clip.
   1.931 +   * The intersection is approximate since rounded corners are not taking into
   1.932 +   * account.
   1.933 +   */
   1.934 +  nsRect GetClippedBounds(nsDisplayListBuilder* aBuilder);
   1.935 +  nsRect GetBorderRect() {
   1.936 +    return nsRect(ToReferenceFrame(), Frame()->GetSize());
   1.937 +  }
   1.938 +  nsRect GetPaddingRect() {
   1.939 +    return Frame()->GetPaddingRectRelativeToSelf() + ToReferenceFrame();
   1.940 +  }
   1.941 +  nsRect GetContentRect() {
   1.942 +    return Frame()->GetContentRectRelativeToSelf() + ToReferenceFrame();
   1.943 +  }
   1.944 +
   1.945 +  /**
   1.946 +   * Checks if the frame(s) owning this display item have been marked as invalid,
   1.947 +   * and needing repainting.
   1.948 +   */
   1.949 +  virtual bool IsInvalid(nsRect& aRect) { 
   1.950 +    bool result = mFrame ? mFrame->IsInvalid(aRect) : false;
   1.951 +    aRect += ToReferenceFrame();
   1.952 +    return result;
   1.953 +  }
   1.954 +
   1.955 +  /**
   1.956 +   * Creates and initializes an nsDisplayItemGeometry object that retains the current
   1.957 +   * areas covered by this display item. These need to retain enough information
   1.958 +   * such that they can be compared against a future nsDisplayItem of the same type, 
   1.959 +   * and determine if repainting needs to happen.
   1.960 +   *
   1.961 +   * Subclasses wishing to store more information need to override both this
   1.962 +   * and ComputeInvalidationRegion, as well as implementing an nsDisplayItemGeometry
   1.963 +   * subclass.
   1.964 +   *
   1.965 +   * The default implementation tracks both the display item bounds, and the frame's
   1.966 +   * border rect.
   1.967 +   */
   1.968 +  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
   1.969 +  {
   1.970 +    return new nsDisplayItemGenericGeometry(this, aBuilder);
   1.971 +  }
   1.972 +
   1.973 +  /**
   1.974 +   * Compares an nsDisplayItemGeometry object from a previous paint against the 
   1.975 +   * current item. Computes if the geometry of the item has changed, and the 
   1.976 +   * invalidation area required for correct repainting.
   1.977 +   *
   1.978 +   * The existing geometry will have been created from a display item with a 
   1.979 +   * matching GetPerFrameKey()/mFrame pair to the current item.
   1.980 +   *
   1.981 +   * The default implementation compares the display item bounds, and the frame's
   1.982 +   * border rect, and invalidates the entire bounds if either rect changes.
   1.983 +   *
   1.984 +   * @param aGeometry The geometry of the matching display item from the 
   1.985 +   * previous paint.
   1.986 +   * @param aInvalidRegion Output param, the region to invalidate, or
   1.987 +   * unchanged if none.
   1.988 +   */
   1.989 +  virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
   1.990 +                                         const nsDisplayItemGeometry* aGeometry,
   1.991 +                                         nsRegion* aInvalidRegion)
   1.992 +  {
   1.993 +    const nsDisplayItemGenericGeometry* geometry = static_cast<const nsDisplayItemGenericGeometry*>(aGeometry);
   1.994 +    bool snap;
   1.995 +    if (!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder, &snap)) ||
   1.996 +        !geometry->mBorderRect.IsEqualInterior(GetBorderRect())) {
   1.997 +      aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds);
   1.998 +    }
   1.999 +  }
  1.1000 +
  1.1001 +  /**
  1.1002 +   * An alternative default implementation of ComputeInvalidationRegion,
  1.1003 +   * that instead invalidates only the changed area between the two items.
  1.1004 +   */
  1.1005 +  void ComputeInvalidationRegionDifference(nsDisplayListBuilder* aBuilder,
  1.1006 +                                           const nsDisplayItemBoundsGeometry* aGeometry,
  1.1007 +                                           nsRegion* aInvalidRegion)
  1.1008 +  {
  1.1009 +    bool snap;
  1.1010 +    nsRect bounds = GetBounds(aBuilder, &snap);
  1.1011 +
  1.1012 +    if (!aGeometry->mBounds.IsEqualInterior(bounds)) {
  1.1013 +      nscoord radii[8];
  1.1014 +      if (aGeometry->mHasRoundedCorners ||
  1.1015 +          Frame()->GetBorderRadii(radii)) {
  1.1016 +        aInvalidRegion->Or(aGeometry->mBounds, bounds);
  1.1017 +      } else {
  1.1018 +        aInvalidRegion->Xor(aGeometry->mBounds, bounds);
  1.1019 +      }
  1.1020 +    }
  1.1021 +  }
  1.1022 +
  1.1023 +  /**
  1.1024 +   * For display items types that just draw a background we use this function
  1.1025 +   * to do any invalidation that might be needed if we are asked to sync decode
  1.1026 +   * images.
  1.1027 +   */
  1.1028 +  void AddInvalidRegionForSyncDecodeBackgroundImages(
  1.1029 +    nsDisplayListBuilder* aBuilder,
  1.1030 +    const nsDisplayItemGeometry* aGeometry,
  1.1031 +    nsRegion* aInvalidRegion);
  1.1032 +
  1.1033 +  /**
  1.1034 +   * Called when the area rendered by this display item has changed (been
  1.1035 +   * invalidated or changed geometry) since the last paint. This includes
  1.1036 +   * when the display item was not rendered at all in the last paint.
  1.1037 +   * It does NOT get called when a display item was being rendered and no
  1.1038 +   * longer is, because generally that means there is no display item to
  1.1039 +   * call this method on.
  1.1040 +   */
  1.1041 +  virtual void NotifyRenderingChanged() {}
  1.1042 +
  1.1043 +  /**
  1.1044 +   * @param aSnap set to true if the edges of the rectangles of the opaque
  1.1045 +   * region would be snapped to device pixels when drawing
  1.1046 +   * @return a region of the item that is opaque --- that is, every pixel
  1.1047 +   * that is visible (according to ComputeVisibility) is painted with an opaque
  1.1048 +   * color. This is useful for determining when one piece
  1.1049 +   * of content completely obscures another so that we can do occlusion
  1.1050 +   * culling.
  1.1051 +   * This does not take clipping into account.
  1.1052 +   */
  1.1053 +  virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
  1.1054 +                                   bool* aSnap)
  1.1055 +  {
  1.1056 +    *aSnap = false;
  1.1057 +    return nsRegion();
  1.1058 +  }
  1.1059 +  /**
  1.1060 +   * If this returns true, then aColor is set to the uniform color
  1.1061 +   * @return true if the item is guaranteed to paint every pixel in its
  1.1062 +   * bounds with the same (possibly translucent) color
  1.1063 +   */
  1.1064 +  virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { return false; }
  1.1065 +  /**
  1.1066 +   * @return false if the painting performed by the item is invariant
  1.1067 +   * when the item's underlying frame is moved relative to aFrame.
  1.1068 +   * In other words, if you render the item at locations P and P', the rendering
  1.1069 +   * only differs by the translation.
  1.1070 +   * It return true for all wrapped lists.
  1.1071 +   */
  1.1072 +  virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
  1.1073 +                                                nsIFrame* aFrame)
  1.1074 +  { return false; }
  1.1075 +  /**
  1.1076 +   * @return true if the contents of this item are rendered fixed relative
  1.1077 +   * to the nearest viewport.
  1.1078 +   */
  1.1079 +  virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder)
  1.1080 +  { return false; }
  1.1081 +
  1.1082 +  /**
  1.1083 +   * Returns true if all layers that can be active should be forced to be
  1.1084 +   * active. Requires setting the pref layers.force-active=true.
  1.1085 +   */
  1.1086 +  static bool ForceActiveLayers();
  1.1087 +
  1.1088 +  /**
  1.1089 +   * Returns the maximum number of layers that should be created
  1.1090 +   * or -1 for no limit. Requires setting the pref layers.max-acitve.
  1.1091 +   */
  1.1092 +  static int32_t MaxActiveLayers();
  1.1093 +
  1.1094 +  /**
  1.1095 +   * @return LAYER_NONE if BuildLayer will return null. In this case
  1.1096 +   * there is no layer for the item, and Paint should be called instead
  1.1097 +   * to paint the content using Thebes.
  1.1098 +   * Return LAYER_INACTIVE if there is a layer --- BuildLayer will
  1.1099 +   * not return null (unless there's an error) --- but the layer contents
  1.1100 +   * are not changing frequently. In this case it makes sense to composite
  1.1101 +   * the layer into a ThebesLayer with other content, so we don't have to
  1.1102 +   * recomposite it every time we paint.
  1.1103 +   * Note: GetLayerState is only allowed to return LAYER_INACTIVE if all
  1.1104 +   * descendant display items returned LAYER_INACTIVE or LAYER_NONE. Also,
  1.1105 +   * all descendant display item frames must have an active scrolled root
  1.1106 +   * that's either the same as this item's frame's active scrolled root, or
  1.1107 +   * a descendant of this item's frame. This ensures that the entire
  1.1108 +   * set of display items can be collapsed onto a single ThebesLayer.
  1.1109 +   * Return LAYER_ACTIVE if the layer is active, that is, its contents are
  1.1110 +   * changing frequently. In this case it makes sense to keep the layer
  1.1111 +   * as a separate buffer in VRAM and composite it into the destination
  1.1112 +   * every time we paint.
  1.1113 +   *
  1.1114 +   * Users of GetLayerState should check ForceActiveLayers() and if it returns
  1.1115 +   * true, change a returned value of LAYER_INACTIVE to LAYER_ACTIVE.
  1.1116 +   */
  1.1117 +  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
  1.1118 +                                   LayerManager* aManager,
  1.1119 +                                   const ContainerLayerParameters& aParameters)
  1.1120 +  { return mozilla::LAYER_NONE; }
  1.1121 +  /**
  1.1122 +   * Return true to indicate the layer should be constructed even if it's
  1.1123 +   * completely invisible.
  1.1124 +   */
  1.1125 +  virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder)
  1.1126 +  { return false; }
  1.1127 +  /**
  1.1128 +   * Actually paint this item to some rendering context.
  1.1129 +   * Content outside mVisibleRect need not be painted.
  1.1130 +   * aCtx must be set up as for nsDisplayList::Paint.
  1.1131 +   */
  1.1132 +  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) {}
  1.1133 +
  1.1134 +#ifdef MOZ_DUMP_PAINTING
  1.1135 +  /**
  1.1136 +   * Mark this display item as being painted via FrameLayerBuilder::DrawThebesLayer.
  1.1137 +   */
  1.1138 +  bool Painted() { return mPainted; }
  1.1139 +
  1.1140 +  /**
  1.1141 +   * Check if this display item has been painted.
  1.1142 +   */
  1.1143 +  void SetPainted() { mPainted = true; }
  1.1144 +#endif
  1.1145 +
  1.1146 +  /**
  1.1147 +   * Get the layer drawn by this display item. Call this only if
  1.1148 +   * GetLayerState() returns something other than LAYER_NONE.
  1.1149 +   * If GetLayerState returned LAYER_NONE then Paint will be called
  1.1150 +   * instead.
  1.1151 +   * This is called while aManager is in the construction phase.
  1.1152 +   * 
  1.1153 +   * The caller (nsDisplayList) is responsible for setting the visible
  1.1154 +   * region of the layer.
  1.1155 +   *
  1.1156 +   * @param aContainerParameters should be passed to
  1.1157 +   * FrameLayerBuilder::BuildContainerLayerFor if a ContainerLayer is
  1.1158 +   * constructed.
  1.1159 +   */
  1.1160 +  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
  1.1161 +                                             LayerManager* aManager,
  1.1162 +                                             const ContainerLayerParameters& aContainerParameters)
  1.1163 +  { return nullptr; }
  1.1164 +
  1.1165 +  /**
  1.1166 +   * On entry, aVisibleRegion contains the region (relative to ReferenceFrame())
  1.1167 +   * which may be visible. If the display item opaquely covers an area, it
  1.1168 +   * can remove that area from aVisibleRegion before returning.
  1.1169 +   * nsDisplayList::ComputeVisibility automatically subtracts the region
  1.1170 +   * returned by GetOpaqueRegion, and automatically removes items whose bounds
  1.1171 +   * do not intersect the visible area, so implementations of
  1.1172 +   * nsDisplayItem::ComputeVisibility do not need to do these things.
  1.1173 +   * nsDisplayList::ComputeVisibility will already have set mVisibleRect on
  1.1174 +   * this item to the intersection of *aVisibleRegion and this item's bounds.
  1.1175 +   * We rely on that, so this should only be called by
  1.1176 +   * nsDisplayList::ComputeVisibility or nsDisplayItem::RecomputeVisibility.
  1.1177 +   * aAllowVisibleRegionExpansion is a rect where we are allowed to
  1.1178 +   * expand the visible region and is only used for making sure the
  1.1179 +   * background behind a plugin is visible.
  1.1180 +   * This method needs to be idempotent.
  1.1181 +   *
  1.1182 +   * @return true if the item is visible, false if no part of the item
  1.1183 +   * is visible.
  1.1184 +   */
  1.1185 +  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
  1.1186 +                                   nsRegion* aVisibleRegion,
  1.1187 +                                   const nsRect& aAllowVisibleRegionExpansion)
  1.1188 +  { return !mVisibleRect.IsEmpty(); }
  1.1189 +
  1.1190 +  /**
  1.1191 +   * Try to merge with the other item (which is below us in the display
  1.1192 +   * list). This gets used by nsDisplayClip to coalesce clipping operations
  1.1193 +   * (optimization), by nsDisplayOpacity to merge rendering for the same
  1.1194 +   * content element into a single opacity group (correctness), and will be
  1.1195 +   * used by nsDisplayOutline to merge multiple outlines for the same element
  1.1196 +   * (also for correctness).
  1.1197 +   * @return true if the merge was successful and the other item should be deleted
  1.1198 +   */
  1.1199 +  virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) {
  1.1200 +    return false;
  1.1201 +  }
  1.1202 +
  1.1203 +  /**
  1.1204 +   * Appends the underlying frames of all display items that have been
  1.1205 +   * merged into this one (excluding  this item's own underlying frame)
  1.1206 +   * to aFrames.
  1.1207 +   */
  1.1208 +  virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) {}
  1.1209 +
  1.1210 +  /**
  1.1211 +   * During the visibility computation and after TryMerge, display lists may
  1.1212 +   * return true here to flatten themselves away, removing them. This
  1.1213 +   * flattening is distinctly different from FlattenTo, which occurs before
  1.1214 +   * items are merged together.
  1.1215 +   */
  1.1216 +  virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) {
  1.1217 +    return false;
  1.1218 +  }
  1.1219 +
  1.1220 +  /**
  1.1221 +   * If this has a child list where the children are in the same coordinate
  1.1222 +   * system as this item (i.e., they have the same reference frame),
  1.1223 +   * return the list.
  1.1224 +   */
  1.1225 +  virtual nsDisplayList* GetSameCoordinateSystemChildren() { return nullptr; }
  1.1226 +  virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) {}
  1.1227 +
  1.1228 +  /**
  1.1229 +   * If this has a child list, return it, even if the children are in
  1.1230 +   * a different coordinate system to this item.
  1.1231 +   */
  1.1232 +  virtual nsDisplayList* GetChildren() { return nullptr; }
  1.1233 +
  1.1234 +  /**
  1.1235 +   * Returns the visible rect. Should only be called after ComputeVisibility
  1.1236 +   * has happened.
  1.1237 +   */
  1.1238 +  const nsRect& GetVisibleRect() { return mVisibleRect; }
  1.1239 +
  1.1240 +  /**
  1.1241 +   * Stores the given opacity value to be applied when drawing. Returns
  1.1242 +   * false if this isn't supported for this display item.
  1.1243 +   */
  1.1244 +  virtual bool ApplyOpacity(nsDisplayListBuilder* aBuilder,
  1.1245 +                            float aOpacity,
  1.1246 +                            const DisplayItemClip* aClip) {
  1.1247 +    return false;
  1.1248 +  }
  1.1249 +  
  1.1250 +#ifdef MOZ_DUMP_PAINTING
  1.1251 +  /**
  1.1252 +   * For debugging and stuff
  1.1253 +   */
  1.1254 +  virtual const char* Name() = 0;
  1.1255 +
  1.1256 +  virtual void WriteDebugInfo(nsACString& aTo) {}
  1.1257 +#endif
  1.1258 +
  1.1259 +  nsDisplayItem* GetAbove() { return mAbove; }
  1.1260 +
  1.1261 +  /**
  1.1262 +   * Like ComputeVisibility, but does the work that nsDisplayList
  1.1263 +   * does per-item:
  1.1264 +   * -- Intersects GetBounds with aVisibleRegion and puts the result
  1.1265 +   * in mVisibleRect
  1.1266 +   * -- Subtracts bounds from aVisibleRegion if the item is opaque
  1.1267 +   */
  1.1268 +  bool RecomputeVisibility(nsDisplayListBuilder* aBuilder,
  1.1269 +                             nsRegion* aVisibleRegion);
  1.1270 +
  1.1271 +  /**
  1.1272 +   * Returns the result of aBuilder->ToReferenceFrame(GetUnderlyingFrame())
  1.1273 +   */
  1.1274 +  const nsPoint& ToReferenceFrame() const {
  1.1275 +    NS_ASSERTION(mFrame, "No frame?");
  1.1276 +    return mToReferenceFrame;
  1.1277 +  }
  1.1278 +  /**
  1.1279 +   * @return the root of the display list's frame (sub)tree, whose origin
  1.1280 +   * establishes the coordinate system for the display list
  1.1281 +   */
  1.1282 +  const nsIFrame* ReferenceFrame() const { return mReferenceFrame; }
  1.1283 +
  1.1284 +  /**
  1.1285 +   * Returns the reference frame for display item children of this item.
  1.1286 +   */
  1.1287 +  virtual const nsIFrame* ReferenceFrameForChildren() const { return mReferenceFrame; }
  1.1288 +
  1.1289 +  /**
  1.1290 +   * Checks if this display item (or any children) contains content that might
  1.1291 +   * be rendered with component alpha (e.g. subpixel antialiasing). Returns the
  1.1292 +   * bounds of the area that needs component alpha, or an empty rect if nothing
  1.1293 +   * in the item does.
  1.1294 +   */
  1.1295 +  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) { return nsRect(); }
  1.1296 +
  1.1297 +  /**
  1.1298 +   * Disable usage of component alpha. Currently only relevant for items that have text.
  1.1299 +   */
  1.1300 +  virtual void DisableComponentAlpha() {}
  1.1301 +
  1.1302 +  /**
  1.1303 +   * Check if we can add async animations to the layer for this display item.
  1.1304 +   */
  1.1305 +  virtual bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) {
  1.1306 +    return false;
  1.1307 +  }
  1.1308 +  
  1.1309 +  virtual bool SupportsOptimizingToImage() { return false; }
  1.1310 +
  1.1311 +  const DisplayItemClip& GetClip()
  1.1312 +  {
  1.1313 +    return mClip ? *mClip : DisplayItemClip::NoClip();
  1.1314 +  }
  1.1315 +  void SetClip(nsDisplayListBuilder* aBuilder, const DisplayItemClip& aClip)
  1.1316 +  {
  1.1317 +    if (!aClip.HasClip()) {
  1.1318 +      mClip = nullptr;
  1.1319 +      return;
  1.1320 +    }
  1.1321 +    mClip = aBuilder->AllocateDisplayItemClip(aClip);
  1.1322 +  }
  1.1323 +
  1.1324 +  void IntersectClip(nsDisplayListBuilder* aBuilder, const DisplayItemClip& aClip)
  1.1325 +  {
  1.1326 +    if (mClip) {
  1.1327 +      DisplayItemClip temp = *mClip;
  1.1328 +      temp.IntersectWith(aClip);
  1.1329 +      SetClip(aBuilder, temp);
  1.1330 +    } else {
  1.1331 +      SetClip(aBuilder, aClip);
  1.1332 +    }
  1.1333 +  }
  1.1334 +
  1.1335 +  // If we return false here it means that if this item creates a layer then
  1.1336 +  // ProcessDisplayItems will not set the visible region on the layer. The item
  1.1337 +  // should set the visible region, usually in BuildContainerLayer.
  1.1338 +  virtual bool SetVisibleRegionOnLayer() { return true; }
  1.1339 +
  1.1340 +  bool IsInFixedPos() { return mInFixedPos; }
  1.1341 +
  1.1342 +protected:
  1.1343 +  friend class nsDisplayList;
  1.1344 +
  1.1345 +  nsDisplayItem() { mAbove = nullptr; }
  1.1346 +
  1.1347 +  nsIFrame* mFrame;
  1.1348 +  const DisplayItemClip* mClip;
  1.1349 +  // Result of FindReferenceFrameFor(mFrame), if mFrame is non-null
  1.1350 +  const nsIFrame* mReferenceFrame;
  1.1351 +  // Result of ToReferenceFrame(mFrame), if mFrame is non-null
  1.1352 +  nsPoint   mToReferenceFrame;
  1.1353 +  // This is the rectangle that needs to be painted.
  1.1354 +  // nsDisplayList::ComputeVisibility sets this to the visible region
  1.1355 +  // of the item by intersecting the current visible region with the bounds
  1.1356 +  // of the item. Paint implementations can use this to limit their drawing.
  1.1357 +  // Guaranteed to be contained in GetBounds().
  1.1358 +  nsRect    mVisibleRect;
  1.1359 +  bool      mInFixedPos;
  1.1360 +#ifdef MOZ_DUMP_PAINTING
  1.1361 +  // True if this frame has been painted.
  1.1362 +  bool      mPainted;
  1.1363 +#endif
  1.1364 +};
  1.1365 +
  1.1366 +/**
  1.1367 + * Manages a singly-linked list of display list items.
  1.1368 + * 
  1.1369 + * mSentinel is the sentinel list value, the first value in the null-terminated
  1.1370 + * linked list of items. mTop is the last item in the list (whose 'above'
  1.1371 + * pointer is null). This class has no virtual methods. So list objects are just
  1.1372 + * two pointers.
  1.1373 + * 
  1.1374 + * Stepping upward through this list is very fast. Stepping downward is very
  1.1375 + * slow so we don't support it. The methods that need to step downward
  1.1376 + * (HitTest(), ComputeVisibility()) internally build a temporary array of all
  1.1377 + * the items while they do the downward traversal, so overall they're still
  1.1378 + * linear time. We have optimized for efficient AppendToTop() of both
  1.1379 + * items and lists, with minimal codesize. AppendToBottom() is efficient too.
  1.1380 + */
  1.1381 +class nsDisplayList {
  1.1382 +public:
  1.1383 +  typedef mozilla::layers::Layer Layer;
  1.1384 +  typedef mozilla::layers::LayerManager LayerManager;
  1.1385 +  typedef mozilla::layers::ThebesLayer ThebesLayer;
  1.1386 +
  1.1387 +  /**
  1.1388 +   * Create an empty list.
  1.1389 +   */
  1.1390 +  nsDisplayList() :
  1.1391 +    mIsOpaque(false)
  1.1392 +  {
  1.1393 +    mTop = &mSentinel;
  1.1394 +    mSentinel.mAbove = nullptr;
  1.1395 +#if defined(DEBUG) || defined(MOZ_DUMP_PAINTING)
  1.1396 +    mDidComputeVisibility = false;
  1.1397 +#endif
  1.1398 +  }
  1.1399 +  ~nsDisplayList() {
  1.1400 +    if (mSentinel.mAbove) {
  1.1401 +      NS_WARNING("Nonempty list left over?");
  1.1402 +    }
  1.1403 +    DeleteAll();
  1.1404 +  }
  1.1405 +
  1.1406 +  /**
  1.1407 +   * Append an item to the top of the list. The item must not currently
  1.1408 +   * be in a list and cannot be null.
  1.1409 +   */
  1.1410 +  void AppendToTop(nsDisplayItem* aItem) {
  1.1411 +    NS_ASSERTION(aItem, "No item to append!");
  1.1412 +    NS_ASSERTION(!aItem->mAbove, "Already in a list!");
  1.1413 +    mTop->mAbove = aItem;
  1.1414 +    mTop = aItem;
  1.1415 +  }
  1.1416 +  
  1.1417 +  /**
  1.1418 +   * Append a new item to the top of the list. If the item is null we return
  1.1419 +   * NS_ERROR_OUT_OF_MEMORY. The intended usage is AppendNewToTop(new ...);
  1.1420 +   */
  1.1421 +  void AppendNewToTop(nsDisplayItem* aItem) {
  1.1422 +    if (aItem) {
  1.1423 +      AppendToTop(aItem);
  1.1424 +    }
  1.1425 +  }
  1.1426 +  
  1.1427 +  /**
  1.1428 +   * Append a new item to the bottom of the list. If the item is null we return
  1.1429 +   * NS_ERROR_OUT_OF_MEMORY. The intended usage is AppendNewToBottom(new ...);
  1.1430 +   */
  1.1431 +  void AppendNewToBottom(nsDisplayItem* aItem) {
  1.1432 +    if (aItem) {
  1.1433 +      AppendToBottom(aItem);
  1.1434 +    }
  1.1435 +  }
  1.1436 +  
  1.1437 +  /**
  1.1438 +   * Append a new item to the bottom of the list. The item must be non-null
  1.1439 +   * and not already in a list.
  1.1440 +   */
  1.1441 +  void AppendToBottom(nsDisplayItem* aItem) {
  1.1442 +    NS_ASSERTION(aItem, "No item to append!");
  1.1443 +    NS_ASSERTION(!aItem->mAbove, "Already in a list!");
  1.1444 +    aItem->mAbove = mSentinel.mAbove;
  1.1445 +    mSentinel.mAbove = aItem;
  1.1446 +    if (mTop == &mSentinel) {
  1.1447 +      mTop = aItem;
  1.1448 +    }
  1.1449 +  }
  1.1450 +  
  1.1451 +  /**
  1.1452 +   * Removes all items from aList and appends them to the top of this list
  1.1453 +   */
  1.1454 +  void AppendToTop(nsDisplayList* aList) {
  1.1455 +    if (aList->mSentinel.mAbove) {
  1.1456 +      mTop->mAbove = aList->mSentinel.mAbove;
  1.1457 +      mTop = aList->mTop;
  1.1458 +      aList->mTop = &aList->mSentinel;
  1.1459 +      aList->mSentinel.mAbove = nullptr;
  1.1460 +    }
  1.1461 +  }
  1.1462 +  
  1.1463 +  /**
  1.1464 +   * Removes all items from aList and prepends them to the bottom of this list
  1.1465 +   */
  1.1466 +  void AppendToBottom(nsDisplayList* aList) {
  1.1467 +    if (aList->mSentinel.mAbove) {
  1.1468 +      aList->mTop->mAbove = mSentinel.mAbove;
  1.1469 +      mSentinel.mAbove = aList->mSentinel.mAbove;
  1.1470 +      if (mTop == &mSentinel) {
  1.1471 +        mTop = aList->mTop;
  1.1472 +      }
  1.1473 +           
  1.1474 +      aList->mTop = &aList->mSentinel;
  1.1475 +      aList->mSentinel.mAbove = nullptr;
  1.1476 +    }
  1.1477 +  }
  1.1478 +  
  1.1479 +  /**
  1.1480 +   * Remove an item from the bottom of the list and return it.
  1.1481 +   */
  1.1482 +  nsDisplayItem* RemoveBottom();
  1.1483 +  
  1.1484 +  /**
  1.1485 +   * Remove all items from the list and call their destructors.
  1.1486 +   */
  1.1487 +  void DeleteAll();
  1.1488 +  
  1.1489 +  /**
  1.1490 +   * @return the item at the top of the list, or null if the list is empty
  1.1491 +   */
  1.1492 +  nsDisplayItem* GetTop() const {
  1.1493 +    return mTop != &mSentinel ? static_cast<nsDisplayItem*>(mTop) : nullptr;
  1.1494 +  }
  1.1495 +  /**
  1.1496 +   * @return the item at the bottom of the list, or null if the list is empty
  1.1497 +   */
  1.1498 +  nsDisplayItem* GetBottom() const { return mSentinel.mAbove; }
  1.1499 +  bool IsEmpty() const { return mTop == &mSentinel; }
  1.1500 +  
  1.1501 +  /**
  1.1502 +   * This is *linear time*!
  1.1503 +   * @return the number of items in the list
  1.1504 +   */
  1.1505 +  uint32_t Count() const;
  1.1506 +  /**
  1.1507 +   * Stable sort the list by the z-order of GetUnderlyingFrame() on
  1.1508 +   * each item. 'auto' is counted as zero. Content order is used as the
  1.1509 +   * secondary order.
  1.1510 +   * @param aCommonAncestor a common ancestor of all the content elements
  1.1511 +   * associated with the display items, for speeding up tree order
  1.1512 +   * checks, or nullptr if not known; it's only a hint, if it is not an
  1.1513 +   * ancestor of some elements, then we lose performance but not correctness
  1.1514 +   */
  1.1515 +  void SortByZOrder(nsDisplayListBuilder* aBuilder, nsIContent* aCommonAncestor);
  1.1516 +  /**
  1.1517 +   * Stable sort the list by the tree order of the content of
  1.1518 +   * GetUnderlyingFrame() on each item. z-index is ignored.
  1.1519 +   * @param aCommonAncestor a common ancestor of all the content elements
  1.1520 +   * associated with the display items, for speeding up tree order
  1.1521 +   * checks, or nullptr if not known; it's only a hint, if it is not an
  1.1522 +   * ancestor of some elements, then we lose performance but not correctness
  1.1523 +   */
  1.1524 +  void SortByContentOrder(nsDisplayListBuilder* aBuilder, nsIContent* aCommonAncestor);
  1.1525 +
  1.1526 +  /**
  1.1527 +   * Generic stable sort. Take care, because some of the items might be nsDisplayLists
  1.1528 +   * themselves.
  1.1529 +   * aCmp(item1, item2) should return true if item1 <= item2. We sort the items
  1.1530 +   * into increasing order.
  1.1531 +   */
  1.1532 +  typedef bool (* SortLEQ)(nsDisplayItem* aItem1, nsDisplayItem* aItem2,
  1.1533 +                             void* aClosure);
  1.1534 +  void Sort(nsDisplayListBuilder* aBuilder, SortLEQ aCmp, void* aClosure);
  1.1535 +
  1.1536 +  /**
  1.1537 +   * Compute visiblity for the items in the list.
  1.1538 +   * We put this logic here so it can be shared by top-level
  1.1539 +   * painting and also display items that maintain child lists.
  1.1540 +   * This is also a good place to put ComputeVisibility-related logic
  1.1541 +   * that must be applied to every display item. In particular, this
  1.1542 +   * sets mVisibleRect on each display item.
  1.1543 +   * This sets mIsOpaque if the entire visible area of this list has
  1.1544 +   * been removed from aVisibleRegion when we return.
  1.1545 +   * This does not remove any items from the list, so we can recompute
  1.1546 +   * visiblity with different regions later (see
  1.1547 +   * FrameLayerBuilder::DrawThebesLayer).
  1.1548 +   * This method needs to be idempotent.
  1.1549 +   * 
  1.1550 +   * @param aVisibleRegion the area that is visible, relative to the
  1.1551 +   * reference frame; on return, this contains the area visible under the list.
  1.1552 +   * I.e., opaque contents of this list are subtracted from aVisibleRegion.
  1.1553 +   * @param aListVisibleBounds must be equal to the bounds of the intersection
  1.1554 +   * of aVisibleRegion and GetBounds() for this list.
  1.1555 +   * @param aDisplayPortFrame If the item for which this list corresponds is
  1.1556 +   * within a displayport, the scroll frame for which that display port
  1.1557 +   * applies. For root scroll frames, you can pass the the root frame instead.
  1.1558 +   * @return true if any item in the list is visible.
  1.1559 +   */
  1.1560 +  bool ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
  1.1561 +                                   nsRegion* aVisibleRegion,
  1.1562 +                                   const nsRect& aListVisibleBounds,
  1.1563 +                                   const nsRect& aAllowVisibleRegionExpansion,
  1.1564 +                                   nsIFrame* aDisplayPortFrame = nullptr);
  1.1565 +
  1.1566 +  /**
  1.1567 +   * As ComputeVisibilityForSublist, but computes visibility for a root
  1.1568 +   * list (a list that does not belong to an nsDisplayItem).
  1.1569 +   * This method needs to be idempotent.
  1.1570 +   *
  1.1571 +   * @param aVisibleRegion the area that is visible
  1.1572 +   * @param aDisplayPortFrame The root scroll frame, if a displayport is set
  1.1573 +   */
  1.1574 +  bool ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
  1.1575 +                                nsRegion* aVisibleRegion,
  1.1576 +                                nsIFrame* aDisplayPortFrame = nullptr);
  1.1577 +
  1.1578 +  /**
  1.1579 +   * Returns true if the visible region output from ComputeVisiblity was
  1.1580 +   * empty, i.e. everything visible in this list is opaque.
  1.1581 +   */
  1.1582 +  bool IsOpaque() const {
  1.1583 +    NS_ASSERTION(mDidComputeVisibility, "Need to have called ComputeVisibility");
  1.1584 +    return mIsOpaque;
  1.1585 +  }
  1.1586 +
  1.1587 +  /**
  1.1588 +   * Returns true if during ComputeVisibility any display item
  1.1589 +   * set the surface to be transparent.
  1.1590 +   */
  1.1591 +  bool NeedsTransparentSurface() const {
  1.1592 +    NS_ASSERTION(mDidComputeVisibility, "Need to have called ComputeVisibility");
  1.1593 +    return mForceTransparentSurface;
  1.1594 +  }
  1.1595 +  /**
  1.1596 +   * Paint the list to the rendering context. We assume that (0,0) in aCtx
  1.1597 +   * corresponds to the origin of the reference frame. For best results,
  1.1598 +   * aCtx's current transform should make (0,0) pixel-aligned. The
  1.1599 +   * rectangle in aDirtyRect is painted, which *must* be contained in the
  1.1600 +   * dirty rect used to construct the display list.
  1.1601 +   * 
  1.1602 +   * If aFlags contains PAINT_USE_WIDGET_LAYERS and
  1.1603 +   * ShouldUseWidgetLayerManager() is set, then we will paint using
  1.1604 +   * the reference frame's widget's layer manager (and ctx may be null),
  1.1605 +   * otherwise we will use a temporary BasicLayerManager and ctx must
  1.1606 +   * not be null.
  1.1607 +   * 
  1.1608 +   * If PAINT_FLUSH_LAYERS is set, we'll force a completely new layer
  1.1609 +   * tree to be created for this paint *and* the next paint.
  1.1610 +   * 
  1.1611 +   * If PAINT_EXISTING_TRANSACTION is set, the reference frame's widget's
  1.1612 +   * layer manager has already had BeginTransaction() called on it and
  1.1613 +   * we should not call it again.
  1.1614 +   *
  1.1615 +   * If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to compressed mode
  1.1616 +   * to avoid short cut optimizations.
  1.1617 +   *
  1.1618 +   * ComputeVisibility must be called before Paint.
  1.1619 +   * 
  1.1620 +   * This must only be called on the root display list of the display list
  1.1621 +   * tree.
  1.1622 +   */
  1.1623 +  enum {
  1.1624 +    PAINT_DEFAULT = 0,
  1.1625 +    PAINT_USE_WIDGET_LAYERS = 0x01,
  1.1626 +    PAINT_FLUSH_LAYERS = 0x02,
  1.1627 +    PAINT_EXISTING_TRANSACTION = 0x04,
  1.1628 +    PAINT_NO_COMPOSITE = 0x08,
  1.1629 +    PAINT_COMPRESSED = 0x10
  1.1630 +  };
  1.1631 +  void PaintRoot(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
  1.1632 +                 uint32_t aFlags) const;
  1.1633 +  /**
  1.1634 +   * Like PaintRoot, but used for internal display sublists.
  1.1635 +   * aForFrame is the frame that the list is associated with.
  1.1636 +   */
  1.1637 +  void PaintForFrame(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
  1.1638 +                     nsIFrame* aForFrame, uint32_t aFlags) const;
  1.1639 +  /**
  1.1640 +   * Get the bounds. Takes the union of the bounds of all children.
  1.1641 +   */
  1.1642 +  nsRect GetBounds(nsDisplayListBuilder* aBuilder) const;
  1.1643 +  /**
  1.1644 +   * Find the topmost display item that returns a non-null frame, and return
  1.1645 +   * the frame.
  1.1646 +   */
  1.1647 +  void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
  1.1648 +               nsDisplayItem::HitTestState* aState,
  1.1649 +               nsTArray<nsIFrame*> *aOutFrames) const;
  1.1650 +
  1.1651 +#if defined(DEBUG) || defined(MOZ_DUMP_PAINTING)
  1.1652 +  bool DidComputeVisibility() const { return mDidComputeVisibility; }
  1.1653 +#endif
  1.1654 +
  1.1655 +  nsRect GetVisibleRect() const { return mVisibleRect; }
  1.1656 +
  1.1657 +private:
  1.1658 +  // This class is only used on stack, so we don't have to worry about leaking
  1.1659 +  // it.  Don't let us be heap-allocated!
  1.1660 +  void* operator new(size_t sz) CPP_THROW_NEW;
  1.1661 +  
  1.1662 +  // Utility function used to massage the list during ComputeVisibility.
  1.1663 +  void FlattenTo(nsTArray<nsDisplayItem*>* aElements);
  1.1664 +  
  1.1665 +  nsDisplayItemLink  mSentinel;
  1.1666 +  nsDisplayItemLink* mTop;
  1.1667 +
  1.1668 +  // This is set by ComputeVisibility
  1.1669 +  nsRect mVisibleRect;
  1.1670 +  // This is set to true by ComputeVisibility if the final visible region
  1.1671 +  // is empty (i.e. everything that was visible is covered by some
  1.1672 +  // opaque content in this list).
  1.1673 +  bool mIsOpaque;
  1.1674 +  // This is set to true by ComputeVisibility if any display item in this
  1.1675 +  // list needs to force the surface containing this list to be transparent.
  1.1676 +  bool mForceTransparentSurface;
  1.1677 +#if defined(DEBUG) || defined(MOZ_DUMP_PAINTING)
  1.1678 +  bool mDidComputeVisibility;
  1.1679 +#endif
  1.1680 +};
  1.1681 +
  1.1682 +/**
  1.1683 + * This is passed as a parameter to nsIFrame::BuildDisplayList. That method
  1.1684 + * will put any generated items onto the appropriate list given here. It's
  1.1685 + * basically just a collection with one list for each separate stacking layer.
  1.1686 + * The lists themselves are external to this object and thus can be shared
  1.1687 + * with others. Some of the list pointers may even refer to the same list.
  1.1688 + */
  1.1689 +class nsDisplayListSet {
  1.1690 +public:
  1.1691 +  /**
  1.1692 +   * @return a list where one should place the border and/or background for
  1.1693 +   * this frame (everything from steps 1 and 2 of CSS 2.1 appendix E)
  1.1694 +   */
  1.1695 +  nsDisplayList* BorderBackground() const { return mBorderBackground; }
  1.1696 +  /**
  1.1697 +   * @return a list where one should place the borders and/or backgrounds for
  1.1698 +   * block-level in-flow descendants (step 4 of CSS 2.1 appendix E)
  1.1699 +   */
  1.1700 +  nsDisplayList* BlockBorderBackgrounds() const { return mBlockBorderBackgrounds; }
  1.1701 +  /**
  1.1702 +   * @return a list where one should place descendant floats (step 5 of
  1.1703 +   * CSS 2.1 appendix E)
  1.1704 +   */
  1.1705 +  nsDisplayList* Floats() const { return mFloats; }
  1.1706 +  /**
  1.1707 +   * @return a list where one should place the (pseudo) stacking contexts 
  1.1708 +   * for descendants of this frame (everything from steps 3, 7 and 8
  1.1709 +   * of CSS 2.1 appendix E)
  1.1710 +   */
  1.1711 +  nsDisplayList* PositionedDescendants() const { return mPositioned; }
  1.1712 +  /**
  1.1713 +   * @return a list where one should place the outlines
  1.1714 +   * for this frame and its descendants (step 9 of CSS 2.1 appendix E)
  1.1715 +   */
  1.1716 +  nsDisplayList* Outlines() const { return mOutlines; }
  1.1717 +  /**
  1.1718 +   * @return a list where one should place all other content
  1.1719 +   */
  1.1720 +  nsDisplayList* Content() const { return mContent; }
  1.1721 +  
  1.1722 +  nsDisplayListSet(nsDisplayList* aBorderBackground,
  1.1723 +                   nsDisplayList* aBlockBorderBackgrounds,
  1.1724 +                   nsDisplayList* aFloats,
  1.1725 +                   nsDisplayList* aContent,
  1.1726 +                   nsDisplayList* aPositionedDescendants,
  1.1727 +                   nsDisplayList* aOutlines) :
  1.1728 +     mBorderBackground(aBorderBackground),
  1.1729 +     mBlockBorderBackgrounds(aBlockBorderBackgrounds),
  1.1730 +     mFloats(aFloats),
  1.1731 +     mContent(aContent),
  1.1732 +     mPositioned(aPositionedDescendants),
  1.1733 +     mOutlines(aOutlines) {
  1.1734 +  }
  1.1735 +
  1.1736 +  /**
  1.1737 +   * A copy constructor that lets the caller override the BorderBackground
  1.1738 +   * list.
  1.1739 +   */  
  1.1740 +  nsDisplayListSet(const nsDisplayListSet& aLists,
  1.1741 +                   nsDisplayList* aBorderBackground) :
  1.1742 +     mBorderBackground(aBorderBackground),
  1.1743 +     mBlockBorderBackgrounds(aLists.BlockBorderBackgrounds()),
  1.1744 +     mFloats(aLists.Floats()),
  1.1745 +     mContent(aLists.Content()),
  1.1746 +     mPositioned(aLists.PositionedDescendants()),
  1.1747 +     mOutlines(aLists.Outlines()) {
  1.1748 +  }
  1.1749 +  
  1.1750 +  /**
  1.1751 +   * Move all display items in our lists to top of the corresponding lists in the
  1.1752 +   * destination.
  1.1753 +   */
  1.1754 +  void MoveTo(const nsDisplayListSet& aDestination) const;
  1.1755 +
  1.1756 +private:
  1.1757 +  // This class is only used on stack, so we don't have to worry about leaking
  1.1758 +  // it.  Don't let us be heap-allocated!
  1.1759 +  void* operator new(size_t sz) CPP_THROW_NEW;
  1.1760 +
  1.1761 +protected:
  1.1762 +  nsDisplayList* mBorderBackground;
  1.1763 +  nsDisplayList* mBlockBorderBackgrounds;
  1.1764 +  nsDisplayList* mFloats;
  1.1765 +  nsDisplayList* mContent;
  1.1766 +  nsDisplayList* mPositioned;
  1.1767 +  nsDisplayList* mOutlines;
  1.1768 +};
  1.1769 +
  1.1770 +/**
  1.1771 + * A specialization of nsDisplayListSet where the lists are actually internal
  1.1772 + * to the object, and all distinct.
  1.1773 + */
  1.1774 +struct nsDisplayListCollection : public nsDisplayListSet {
  1.1775 +  nsDisplayListCollection() :
  1.1776 +    nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4],
  1.1777 +                     &mLists[5]) {}
  1.1778 +  nsDisplayListCollection(nsDisplayList* aBorderBackground) :
  1.1779 +    nsDisplayListSet(aBorderBackground, &mLists[1], &mLists[2], &mLists[3], &mLists[4],
  1.1780 +                     &mLists[5]) {}
  1.1781 +
  1.1782 +  /**
  1.1783 +   * Sort all lists by content order.
  1.1784 +   */                     
  1.1785 +  void SortAllByContentOrder(nsDisplayListBuilder* aBuilder, nsIContent* aCommonAncestor) {
  1.1786 +    for (int32_t i = 0; i < 6; ++i) {
  1.1787 +      mLists[i].SortByContentOrder(aBuilder, aCommonAncestor);
  1.1788 +    }
  1.1789 +  }
  1.1790 +
  1.1791 +private:
  1.1792 +  // This class is only used on stack, so we don't have to worry about leaking
  1.1793 +  // it.  Don't let us be heap-allocated!
  1.1794 +  void* operator new(size_t sz) CPP_THROW_NEW;
  1.1795 +
  1.1796 +  nsDisplayList mLists[6];
  1.1797 +};
  1.1798 +
  1.1799 +
  1.1800 +class nsDisplayImageContainer : public nsDisplayItem {
  1.1801 +public:
  1.1802 +  typedef mozilla::layers::ImageContainer ImageContainer;
  1.1803 +  typedef mozilla::layers::ImageLayer ImageLayer;
  1.1804 +
  1.1805 +  nsDisplayImageContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
  1.1806 +    : nsDisplayItem(aBuilder, aFrame)
  1.1807 +  {}
  1.1808 +
  1.1809 +  virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
  1.1810 +                                                        nsDisplayListBuilder* aBuilder) = 0;
  1.1811 +  virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) = 0;
  1.1812 +
  1.1813 +  virtual bool SupportsOptimizingToImage() MOZ_OVERRIDE { return true; }
  1.1814 +};
  1.1815 +
  1.1816 +/**
  1.1817 + * Use this class to implement not-very-frequently-used display items
  1.1818 + * that are not opaque, do not receive events, and are bounded by a frame's
  1.1819 + * border-rect.
  1.1820 + * 
  1.1821 + * This should not be used for display items which are created frequently,
  1.1822 + * because each item is one or two pointers bigger than an item from a
  1.1823 + * custom display item class could be, and fractionally slower. However it does
  1.1824 + * save code size. We use this for infrequently-used item types.
  1.1825 + */
  1.1826 +class nsDisplayGeneric : public nsDisplayItem {
  1.1827 +public:
  1.1828 +  typedef void (* PaintCallback)(nsIFrame* aFrame, nsRenderingContext* aCtx,
  1.1829 +                                 const nsRect& aDirtyRect, nsPoint aFramePt);
  1.1830 +
  1.1831 +  nsDisplayGeneric(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.1832 +                   PaintCallback aPaint, const char* aName, Type aType)
  1.1833 +    : nsDisplayItem(aBuilder, aFrame), mPaint(aPaint)
  1.1834 +#ifdef MOZ_DUMP_PAINTING
  1.1835 +      , mName(aName)
  1.1836 +#endif
  1.1837 +      , mType(aType)
  1.1838 +  {
  1.1839 +    MOZ_COUNT_CTOR(nsDisplayGeneric);
  1.1840 +  }
  1.1841 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.1842 +  virtual ~nsDisplayGeneric() {
  1.1843 +    MOZ_COUNT_DTOR(nsDisplayGeneric);
  1.1844 +  }
  1.1845 +#endif
  1.1846 +  
  1.1847 +  virtual void Paint(nsDisplayListBuilder* aBuilder,
  1.1848 +                     nsRenderingContext* aCtx) MOZ_OVERRIDE {
  1.1849 +    mPaint(mFrame, aCtx, mVisibleRect, ToReferenceFrame());
  1.1850 +  }
  1.1851 +  NS_DISPLAY_DECL_NAME(mName, mType)
  1.1852 +
  1.1853 +  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE {
  1.1854 +    if (mType == nsDisplayItem::TYPE_HEADER_FOOTER) {
  1.1855 +      bool snap;
  1.1856 +      return GetBounds(aBuilder, &snap);
  1.1857 +    }
  1.1858 +    return nsRect();
  1.1859 +  }
  1.1860 +
  1.1861 +protected:
  1.1862 +  PaintCallback mPaint;
  1.1863 +#ifdef MOZ_DUMP_PAINTING
  1.1864 +  const char*   mName;
  1.1865 +#endif
  1.1866 +  Type mType;
  1.1867 +};
  1.1868 +
  1.1869 +/**
  1.1870 + * Generic display item that can contain overflow. Use this in lieu of
  1.1871 + * nsDisplayGeneric if you have a frame that should use the visual overflow
  1.1872 + * rect of its frame when drawing items, instead of the frame's bounds.
  1.1873 + */
  1.1874 +class nsDisplayGenericOverflow : public nsDisplayGeneric {
  1.1875 +  public:
  1.1876 +    nsDisplayGenericOverflow(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.1877 +                             PaintCallback aPaint, const char* aName, Type aType)
  1.1878 +      : nsDisplayGeneric(aBuilder, aFrame, aPaint, aName, aType)
  1.1879 +    {
  1.1880 +      MOZ_COUNT_CTOR(nsDisplayGenericOverflow);
  1.1881 +    }
  1.1882 +  #ifdef NS_BUILD_REFCNT_LOGGING
  1.1883 +    virtual ~nsDisplayGenericOverflow() {
  1.1884 +      MOZ_COUNT_DTOR(nsDisplayGenericOverflow);
  1.1885 +    }
  1.1886 +  #endif
  1.1887 +
  1.1888 +    /**
  1.1889 +     * Returns the frame's visual overflow rect instead of the frame's bounds.
  1.1890 +     */
  1.1891 +    virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
  1.1892 +                             bool* aSnap) MOZ_OVERRIDE
  1.1893 +    {
  1.1894 +      *aSnap = false;
  1.1895 +      return Frame()->GetVisualOverflowRect() + ToReferenceFrame();
  1.1896 +    }
  1.1897 +};
  1.1898 +
  1.1899 +#if defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF)
  1.1900 +/**
  1.1901 + * This class implements painting of reflow counts.  Ideally, we would simply
  1.1902 + * make all the frame names be those returned by nsFrame::GetFrameName
  1.1903 + * (except that tosses in the content tag name!)  and support only one color
  1.1904 + * and eliminate this class altogether in favor of nsDisplayGeneric, but for
  1.1905 + * the time being we can't pass args to a PaintCallback, so just have a
  1.1906 + * separate class to do the right thing.  Sadly, this alsmo means we need to
  1.1907 + * hack all leaf frame classes to handle this.
  1.1908 + *
  1.1909 + * XXXbz the color thing is a bit of a mess, but 0 basically means "not set"
  1.1910 + * here...  I could switch it all to nscolor, but why bother?
  1.1911 + */
  1.1912 +class nsDisplayReflowCount : public nsDisplayItem {
  1.1913 +public:
  1.1914 +  nsDisplayReflowCount(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.1915 +                       const char* aFrameName,
  1.1916 +                       uint32_t aColor = 0)
  1.1917 +    : nsDisplayItem(aBuilder, aFrame),
  1.1918 +      mFrameName(aFrameName),
  1.1919 +      mColor(aColor)
  1.1920 +  {
  1.1921 +    MOZ_COUNT_CTOR(nsDisplayReflowCount);
  1.1922 +  }
  1.1923 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.1924 +  virtual ~nsDisplayReflowCount() {
  1.1925 +    MOZ_COUNT_DTOR(nsDisplayReflowCount);
  1.1926 +  }
  1.1927 +#endif
  1.1928 +
  1.1929 +  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE {
  1.1930 +    mFrame->PresContext()->PresShell()->PaintCount(mFrameName, aCtx,
  1.1931 +                                                   mFrame->PresContext(),
  1.1932 +                                                   mFrame, ToReferenceFrame(),
  1.1933 +                                                   mColor);
  1.1934 +  }
  1.1935 +  NS_DISPLAY_DECL_NAME("nsDisplayReflowCount", TYPE_REFLOW_COUNT)
  1.1936 +protected:
  1.1937 +  const char* mFrameName;
  1.1938 +  nscolor mColor;
  1.1939 +};
  1.1940 +
  1.1941 +#define DO_GLOBAL_REFLOW_COUNT_DSP(_name)                                     \
  1.1942 +  PR_BEGIN_MACRO                                                              \
  1.1943 +    if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() &&   \
  1.1944 +        PresContext()->PresShell()->IsPaintingFrameCounts()) {                \
  1.1945 +        aLists.Outlines()->AppendNewToTop(                                    \
  1.1946 +            new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name));      \
  1.1947 +    }                                                                         \
  1.1948 +  PR_END_MACRO
  1.1949 +
  1.1950 +#define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color)                       \
  1.1951 +  PR_BEGIN_MACRO                                                              \
  1.1952 +    if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() &&   \
  1.1953 +        PresContext()->PresShell()->IsPaintingFrameCounts()) {                \
  1.1954 +        aLists.Outlines()->AppendNewToTop(                                    \
  1.1955 +             new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name, _color)); \
  1.1956 +    }                                                                         \
  1.1957 +  PR_END_MACRO
  1.1958 +
  1.1959 +/*
  1.1960 +  Macro to be used for classes that don't actually implement BuildDisplayList
  1.1961 + */
  1.1962 +#define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super)                   \
  1.1963 +  void BuildDisplayList(nsDisplayListBuilder*   aBuilder,                 \
  1.1964 +                        const nsRect&           aDirtyRect,               \
  1.1965 +                        const nsDisplayListSet& aLists) {                 \
  1.1966 +    DO_GLOBAL_REFLOW_COUNT_DSP(#_class);                                  \
  1.1967 +    _super::BuildDisplayList(aBuilder, aDirtyRect, aLists);               \
  1.1968 +  }
  1.1969 +
  1.1970 +#else // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF
  1.1971 +
  1.1972 +#define DO_GLOBAL_REFLOW_COUNT_DSP(_name)
  1.1973 +#define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color)
  1.1974 +#define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super)
  1.1975 +
  1.1976 +#endif // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF
  1.1977 +
  1.1978 +class nsDisplayCaret : public nsDisplayItem {
  1.1979 +public:
  1.1980 +  nsDisplayCaret(nsDisplayListBuilder* aBuilder, nsIFrame* aCaretFrame,
  1.1981 +                 nsCaret *aCaret)
  1.1982 +    : nsDisplayItem(aBuilder, aCaretFrame), mCaret(aCaret) {
  1.1983 +    MOZ_COUNT_CTOR(nsDisplayCaret);
  1.1984 +  }
  1.1985 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.1986 +  virtual ~nsDisplayCaret() {
  1.1987 +    MOZ_COUNT_DTOR(nsDisplayCaret);
  1.1988 +  }
  1.1989 +#endif
  1.1990 +
  1.1991 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE {
  1.1992 +    *aSnap = false;
  1.1993 +    // The caret returns a rect in the coordinates of mFrame.
  1.1994 +    return mCaret->GetCaretRect() + ToReferenceFrame();
  1.1995 +  }
  1.1996 +  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
  1.1997 +  NS_DISPLAY_DECL_NAME("Caret", TYPE_CARET)
  1.1998 +protected:
  1.1999 +  nsRefPtr<nsCaret> mCaret;
  1.2000 +};
  1.2001 +
  1.2002 +/**
  1.2003 + * The standard display item to paint the CSS borders of a frame.
  1.2004 + */
  1.2005 +class nsDisplayBorder : public nsDisplayItem {
  1.2006 +public:
  1.2007 +  nsDisplayBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) :
  1.2008 +    nsDisplayItem(aBuilder, aFrame)
  1.2009 +  {
  1.2010 +    MOZ_COUNT_CTOR(nsDisplayBorder);
  1.2011 +  }
  1.2012 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2013 +  virtual ~nsDisplayBorder() {
  1.2014 +    MOZ_COUNT_DTOR(nsDisplayBorder);
  1.2015 +  }
  1.2016 +#endif
  1.2017 +
  1.2018 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
  1.2019 +  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
  1.2020 +  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
  1.2021 +                                   nsRegion* aVisibleRegion,
  1.2022 +                                   const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
  1.2023 +  NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
  1.2024 +  
  1.2025 +  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
  1.2026 +
  1.2027 +  virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
  1.2028 +                                         const nsDisplayItemGeometry* aGeometry,
  1.2029 +                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE;
  1.2030 +
  1.2031 +protected:
  1.2032 +  nsRect CalculateBounds(const nsStyleBorder& aStyleBorder);
  1.2033 +};
  1.2034 +
  1.2035 +/**
  1.2036 + * A simple display item that just renders a solid color across the
  1.2037 + * specified bounds. For canvas frames (in the CSS sense) we split off the
  1.2038 + * drawing of the background color into this class (from nsDisplayBackground
  1.2039 + * via nsDisplayCanvasBackground). This is done so that we can always draw a
  1.2040 + * background color to avoid ugly flashes of white when we can't draw a full
  1.2041 + * frame tree (ie when a page is loading). The bounds can differ from the
  1.2042 + * frame's bounds -- this is needed when a frame/iframe is loading and there
  1.2043 + * is not yet a frame tree to go in the frame/iframe so we use the subdoc
  1.2044 + * frame of the parent document as a standin.
  1.2045 + */
  1.2046 +class nsDisplaySolidColor : public nsDisplayItem {
  1.2047 +public:
  1.2048 +  nsDisplaySolidColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2049 +                      const nsRect& aBounds, nscolor aColor)
  1.2050 +    : nsDisplayItem(aBuilder, aFrame), mBounds(aBounds), mColor(aColor)
  1.2051 +  {
  1.2052 +    NS_ASSERTION(NS_GET_A(aColor) > 0, "Don't create invisible nsDisplaySolidColors!");
  1.2053 +    MOZ_COUNT_CTOR(nsDisplaySolidColor);
  1.2054 +  }
  1.2055 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2056 +  virtual ~nsDisplaySolidColor() {
  1.2057 +    MOZ_COUNT_DTOR(nsDisplaySolidColor);
  1.2058 +  }
  1.2059 +#endif
  1.2060 +
  1.2061 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
  1.2062 +
  1.2063 +  virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
  1.2064 +                                   bool* aSnap) MOZ_OVERRIDE {
  1.2065 +    *aSnap = false;
  1.2066 +    nsRegion result;
  1.2067 +    if (NS_GET_A(mColor) == 255) {
  1.2068 +      result = GetBounds(aBuilder, aSnap);
  1.2069 +    }
  1.2070 +    return result;
  1.2071 +  }
  1.2072 +
  1.2073 +  virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE
  1.2074 +  {
  1.2075 +    *aColor = mColor;
  1.2076 +    return true;
  1.2077 +  }
  1.2078 +
  1.2079 +  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
  1.2080 +
  1.2081 +  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
  1.2082 +  {
  1.2083 +    return new nsDisplaySolidColorGeometry(this, aBuilder, mColor);
  1.2084 +  }
  1.2085 +
  1.2086 +  virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
  1.2087 +                                         const nsDisplayItemGeometry* aGeometry,
  1.2088 +                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE
  1.2089 +  {
  1.2090 +    const nsDisplaySolidColorGeometry* geometry =
  1.2091 +      static_cast<const nsDisplaySolidColorGeometry*>(aGeometry);
  1.2092 +    if (mColor != geometry->mColor) {
  1.2093 +      bool dummy;
  1.2094 +      aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &dummy));
  1.2095 +      return;
  1.2096 +    }
  1.2097 +    ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
  1.2098 +  }
  1.2099 +
  1.2100 +#ifdef MOZ_DUMP_PAINTING
  1.2101 +  virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
  1.2102 +#endif
  1.2103 +
  1.2104 +  NS_DISPLAY_DECL_NAME("SolidColor", TYPE_SOLID_COLOR)
  1.2105 +
  1.2106 +private:
  1.2107 +  nsRect  mBounds;
  1.2108 +  nscolor mColor;
  1.2109 +};
  1.2110 +
  1.2111 +/**
  1.2112 + * A display item to paint one background-image for a frame. Each background
  1.2113 + * image layer gets its own nsDisplayBackgroundImage.
  1.2114 + */
  1.2115 +class nsDisplayBackgroundImage : public nsDisplayImageContainer {
  1.2116 +public:
  1.2117 +  /**
  1.2118 +   * aLayer signifies which background layer this item represents.
  1.2119 +   * aIsThemed should be the value of aFrame->IsThemed.
  1.2120 +   * aBackgroundStyle should be the result of
  1.2121 +   * nsCSSRendering::FindBackground, or null if FindBackground returned false.
  1.2122 +   */
  1.2123 +  nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2124 +                           uint32_t aLayer,
  1.2125 +                           const nsStyleBackground* aBackgroundStyle);
  1.2126 +  virtual ~nsDisplayBackgroundImage();
  1.2127 +
  1.2128 +  // This will create and append new items for all the layers of the
  1.2129 +  // background. Returns whether we appended a themed background.
  1.2130 +  static bool AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuilder,
  1.2131 +                                         nsIFrame* aFrame,
  1.2132 +                                         nsDisplayList* aList);
  1.2133 +
  1.2134 +  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
  1.2135 +                                   LayerManager* aManager,
  1.2136 +                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
  1.2137 +
  1.2138 +  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
  1.2139 +                                             LayerManager* aManager,
  1.2140 +                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
  1.2141 +
  1.2142 +  virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
  1.2143 +                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
  1.2144 +  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
  1.2145 +                                   nsRegion* aVisibleRegion,
  1.2146 +                                   const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
  1.2147 +  virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
  1.2148 +                                   bool* aSnap) MOZ_OVERRIDE;
  1.2149 +  virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
  1.2150 +                                                nsIFrame* aFrame) MOZ_OVERRIDE;
  1.2151 +  virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE;
  1.2152 +  /**
  1.2153 +   * GetBounds() returns the background painting area.
  1.2154 +   */
  1.2155 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
  1.2156 +  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
  1.2157 +  virtual uint32_t GetPerFrameKey() MOZ_OVERRIDE;
  1.2158 +  NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
  1.2159 +
  1.2160 +  /**
  1.2161 +   * Return the background positioning area.
  1.2162 +   * (GetBounds() returns the background painting area.)
  1.2163 +   * Can be called only when mBackgroundStyle is non-null.
  1.2164 +   */
  1.2165 +  nsRect GetPositioningArea();
  1.2166 +
  1.2167 +  /**
  1.2168 +   * Returns true if existing rendered pixels of this display item may need
  1.2169 +   * to be redrawn if the positioning area size changes but its position does
  1.2170 +   * not.
  1.2171 +   * If false, only the changed painting area needs to be redrawn when the
  1.2172 +   * positioning area size changes but its position does not.
  1.2173 +   */
  1.2174 +  bool RenderingMightDependOnPositioningAreaSizeChange();
  1.2175 +
  1.2176 +  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
  1.2177 +  {
  1.2178 +    return new nsDisplayBackgroundGeometry(this, aBuilder);
  1.2179 +  }
  1.2180 +
  1.2181 +  virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
  1.2182 +                                         const nsDisplayItemGeometry* aGeometry,
  1.2183 +                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE;
  1.2184 +  
  1.2185 +  virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
  1.2186 +                                                        nsDisplayListBuilder *aBuilder) MOZ_OVERRIDE;
  1.2187 +  virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) MOZ_OVERRIDE;
  1.2188 +
  1.2189 +  static nsRegion GetInsideClipRegion(nsDisplayItem* aItem, nsPresContext* aPresContext, uint8_t aClip,
  1.2190 +                                      const nsRect& aRect, bool* aSnap);
  1.2191 +
  1.2192 +protected:
  1.2193 +  typedef class mozilla::layers::ImageContainer ImageContainer;
  1.2194 +  typedef class mozilla::layers::ImageLayer ImageLayer;
  1.2195 +
  1.2196 +  bool TryOptimizeToImageLayer(LayerManager* aManager, nsDisplayListBuilder* aBuilder);
  1.2197 +  bool IsSingleFixedPositionImage(nsDisplayListBuilder* aBuilder,
  1.2198 +                                  const nsRect& aClipRect,
  1.2199 +                                  gfxRect* aDestRect);
  1.2200 +  nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder);
  1.2201 +
  1.2202 +  void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
  1.2203 +                     const nsRect& aBounds, nsRect* aClipRect);
  1.2204 +
  1.2205 +  // Cache the result of nsCSSRendering::FindBackground. Always null if
  1.2206 +  // mIsThemed is true or if FindBackground returned false.
  1.2207 +  const nsStyleBackground* mBackgroundStyle;
  1.2208 +  /* If this background can be a simple image layer, we store the format here. */
  1.2209 +  nsRefPtr<ImageContainer> mImageContainer;
  1.2210 +  gfxRect mDestRect;
  1.2211 +  /* Bounds of this display item */
  1.2212 +  nsRect mBounds;
  1.2213 +  uint32_t mLayer;
  1.2214 +};
  1.2215 +
  1.2216 +
  1.2217 +/**
  1.2218 + * A display item to paint the native theme background for a frame.
  1.2219 + */
  1.2220 +class nsDisplayThemedBackground : public nsDisplayItem {
  1.2221 +public:
  1.2222 +  nsDisplayThemedBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
  1.2223 +  virtual ~nsDisplayThemedBackground();
  1.2224 +
  1.2225 +  virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
  1.2226 +                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
  1.2227 +  virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
  1.2228 +                                   bool* aSnap) MOZ_OVERRIDE;
  1.2229 +  virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE;
  1.2230 +  /**
  1.2231 +   * GetBounds() returns the background painting area.
  1.2232 +   */
  1.2233 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
  1.2234 +  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
  1.2235 +  NS_DISPLAY_DECL_NAME("ThemedBackground", TYPE_THEMED_BACKGROUND)
  1.2236 +
  1.2237 +  /**
  1.2238 +   * Return the background positioning area.
  1.2239 +   * (GetBounds() returns the background painting area.)
  1.2240 +   * Can be called only when mBackgroundStyle is non-null.
  1.2241 +   */
  1.2242 +  nsRect GetPositioningArea();
  1.2243 +
  1.2244 +  /**
  1.2245 +   * Return whether our frame's document does not have the state
  1.2246 +   * NS_DOCUMENT_STATE_WINDOW_INACTIVE.
  1.2247 +   */
  1.2248 +  bool IsWindowActive();
  1.2249 +
  1.2250 +  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
  1.2251 +  {
  1.2252 +    return new nsDisplayThemedBackgroundGeometry(this, aBuilder);
  1.2253 +  }
  1.2254 +
  1.2255 +  virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
  1.2256 +                                         const nsDisplayItemGeometry* aGeometry,
  1.2257 +                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE;
  1.2258 +
  1.2259 +#ifdef MOZ_DUMP_PAINTING
  1.2260 +  virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
  1.2261 +#endif
  1.2262 +protected:
  1.2263 +  nsRect GetBoundsInternal();
  1.2264 +
  1.2265 +  void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
  1.2266 +                     const nsRect& aBounds, nsRect* aClipRect);
  1.2267 +
  1.2268 +  nsRect mBounds;
  1.2269 +  nsITheme::Transparency mThemeTransparency;
  1.2270 +  uint8_t mAppearance;
  1.2271 +};
  1.2272 +
  1.2273 +class nsDisplayBackgroundColor : public nsDisplayItem
  1.2274 +{
  1.2275 +public:
  1.2276 +  nsDisplayBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2277 +                           const nsStyleBackground* aBackgroundStyle,
  1.2278 +                           nscolor aColor)
  1.2279 +    : nsDisplayItem(aBuilder, aFrame)
  1.2280 +    , mBackgroundStyle(aBackgroundStyle)
  1.2281 +    , mColor(aColor)
  1.2282 +  { }
  1.2283 +
  1.2284 +  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
  1.2285 +  
  1.2286 +  virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
  1.2287 +                                   bool* aSnap) MOZ_OVERRIDE;
  1.2288 +  virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE;
  1.2289 +  virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
  1.2290 +                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
  1.2291 +
  1.2292 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE
  1.2293 +  {
  1.2294 +    *aSnap = true;
  1.2295 +    return nsRect(ToReferenceFrame(), Frame()->GetSize());
  1.2296 +  }
  1.2297 +
  1.2298 +  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
  1.2299 +  {
  1.2300 +    return new nsDisplayItemBoundsGeometry(this, aBuilder);
  1.2301 +  }
  1.2302 +
  1.2303 +  virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
  1.2304 +                                         const nsDisplayItemGeometry* aGeometry,
  1.2305 +                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE
  1.2306 +  {
  1.2307 +    const nsDisplayItemBoundsGeometry* geometry = static_cast<const nsDisplayItemBoundsGeometry*>(aGeometry);
  1.2308 +    ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
  1.2309 +  }
  1.2310 +
  1.2311 +  NS_DISPLAY_DECL_NAME("BackgroundColor", TYPE_BACKGROUND_COLOR)
  1.2312 +#ifdef MOZ_DUMP_PAINTING
  1.2313 +  virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
  1.2314 +#endif
  1.2315 +
  1.2316 +protected:
  1.2317 +  const nsStyleBackground* mBackgroundStyle;
  1.2318 +  nscolor mColor;
  1.2319 +};
  1.2320 +
  1.2321 +/**
  1.2322 + * The standard display item to paint the outer CSS box-shadows of a frame.
  1.2323 + */
  1.2324 +class nsDisplayBoxShadowOuter : public nsDisplayItem {
  1.2325 +public:
  1.2326 +  nsDisplayBoxShadowOuter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
  1.2327 +    : nsDisplayItem(aBuilder, aFrame)
  1.2328 +    , mOpacity(1.0) {
  1.2329 +    MOZ_COUNT_CTOR(nsDisplayBoxShadowOuter);
  1.2330 +    mBounds = GetBoundsInternal();
  1.2331 +  }
  1.2332 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2333 +  virtual ~nsDisplayBoxShadowOuter() {
  1.2334 +    MOZ_COUNT_DTOR(nsDisplayBoxShadowOuter);
  1.2335 +  }
  1.2336 +#endif
  1.2337 +
  1.2338 +  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
  1.2339 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
  1.2340 +  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
  1.2341 +                                   nsRegion* aVisibleRegion,
  1.2342 +                                   const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
  1.2343 +  NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER)
  1.2344 +  
  1.2345 +  virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
  1.2346 +                                         const nsDisplayItemGeometry* aGeometry,
  1.2347 +                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE;
  1.2348 +  
  1.2349 +  virtual bool ApplyOpacity(nsDisplayListBuilder* aBuilder,
  1.2350 +                            float aOpacity,
  1.2351 +                            const DisplayItemClip* aClip) MOZ_OVERRIDE
  1.2352 +  {
  1.2353 +    mOpacity = aOpacity;
  1.2354 +    if (aClip) {
  1.2355 +      IntersectClip(aBuilder, *aClip);
  1.2356 +    }
  1.2357 +    return true;
  1.2358 +  }
  1.2359 +
  1.2360 +  nsRect GetBoundsInternal();
  1.2361 +
  1.2362 +private:
  1.2363 +  nsRegion mVisibleRegion;
  1.2364 +  nsRect mBounds;
  1.2365 +  float mOpacity;
  1.2366 +};
  1.2367 +
  1.2368 +/**
  1.2369 + * The standard display item to paint the inner CSS box-shadows of a frame.
  1.2370 + */
  1.2371 +class nsDisplayBoxShadowInner : public nsDisplayItem {
  1.2372 +public:
  1.2373 +  nsDisplayBoxShadowInner(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
  1.2374 +    : nsDisplayItem(aBuilder, aFrame) {
  1.2375 +    MOZ_COUNT_CTOR(nsDisplayBoxShadowInner);
  1.2376 +  }
  1.2377 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2378 +  virtual ~nsDisplayBoxShadowInner() {
  1.2379 +    MOZ_COUNT_DTOR(nsDisplayBoxShadowInner);
  1.2380 +  }
  1.2381 +#endif
  1.2382 +
  1.2383 +  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
  1.2384 +  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
  1.2385 +                                   nsRegion* aVisibleRegion,
  1.2386 +                                   const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
  1.2387 +  NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER)
  1.2388 +  
  1.2389 +  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
  1.2390 +  {
  1.2391 +    return new nsDisplayBoxShadowInnerGeometry(this, aBuilder);
  1.2392 +  }
  1.2393 +
  1.2394 +  virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
  1.2395 +                                         const nsDisplayItemGeometry* aGeometry,
  1.2396 +                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE
  1.2397 +  {
  1.2398 +    const nsDisplayBoxShadowInnerGeometry* geometry = static_cast<const nsDisplayBoxShadowInnerGeometry*>(aGeometry);
  1.2399 +    if (!geometry->mPaddingRect.IsEqualInterior(GetPaddingRect())) {
  1.2400 +      // nsDisplayBoxShadowInner is based around the padding rect, but it can
  1.2401 +      // touch pixels outside of this. We should invalidate the entire bounds.
  1.2402 +      bool snap;
  1.2403 +      aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &snap));
  1.2404 +    }
  1.2405 +  }
  1.2406 +
  1.2407 +private:
  1.2408 +  nsRegion mVisibleRegion;
  1.2409 +};
  1.2410 +
  1.2411 +/**
  1.2412 + * The standard display item to paint the CSS outline of a frame.
  1.2413 + */
  1.2414 +class nsDisplayOutline : public nsDisplayItem {
  1.2415 +public:
  1.2416 +  nsDisplayOutline(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) :
  1.2417 +    nsDisplayItem(aBuilder, aFrame) {
  1.2418 +    MOZ_COUNT_CTOR(nsDisplayOutline);
  1.2419 +  }
  1.2420 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2421 +  virtual ~nsDisplayOutline() {
  1.2422 +    MOZ_COUNT_DTOR(nsDisplayOutline);
  1.2423 +  }
  1.2424 +#endif
  1.2425 +
  1.2426 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
  1.2427 +  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
  1.2428 +  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
  1.2429 +                                   nsRegion* aVisibleRegion,
  1.2430 +                                   const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
  1.2431 +  NS_DISPLAY_DECL_NAME("Outline", TYPE_OUTLINE)
  1.2432 +};
  1.2433 +
  1.2434 +/**
  1.2435 + * A class that lets you receive events within the frame bounds but never paints.
  1.2436 + */
  1.2437 +class nsDisplayEventReceiver : public nsDisplayItem {
  1.2438 +public:
  1.2439 +  nsDisplayEventReceiver(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
  1.2440 +    : nsDisplayItem(aBuilder, aFrame) {
  1.2441 +    MOZ_COUNT_CTOR(nsDisplayEventReceiver);
  1.2442 +  }
  1.2443 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2444 +  virtual ~nsDisplayEventReceiver() {
  1.2445 +    MOZ_COUNT_DTOR(nsDisplayEventReceiver);
  1.2446 +  }
  1.2447 +#endif
  1.2448 +
  1.2449 +  virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
  1.2450 +                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
  1.2451 +  NS_DISPLAY_DECL_NAME("EventReceiver", TYPE_EVENT_RECEIVER)
  1.2452 +};
  1.2453 +
  1.2454 +/**
  1.2455 + * A display item that tracks event-sensitive regions which will be set
  1.2456 + * on the ContainerLayer that eventually contains this item.
  1.2457 + *
  1.2458 + * One of these is created for each stacking context and pseudo-stacking-context.
  1.2459 + * It accumulates regions for event targets contributed by the border-boxes of
  1.2460 + * frames in its (pseudo) stacking context. A nsDisplayLayerEventRegions
  1.2461 + * eventually contributes its regions to the ThebesLayer it is placed in by
  1.2462 + * FrameLayerBuilder. (We don't create a display item for every frame that
  1.2463 + * could be an event target (i.e. almost all frames), because that would be
  1.2464 + * high overhead.)
  1.2465 + *
  1.2466 + * We always make leaf layers other than ThebesLayers transparent to events.
  1.2467 + * For example, an event targeting a canvas or video will actually target the
  1.2468 + * background of that element, which is logically in the ThebesLayer behind the
  1.2469 + * CanvasFrame or ImageFrame. We only need to create a
  1.2470 + * nsDisplayLayerEventRegions when an element's background could be in front
  1.2471 + * of a lower z-order element with its own layer.
  1.2472 + */
  1.2473 +class nsDisplayLayerEventRegions MOZ_FINAL : public nsDisplayItem {
  1.2474 +public:
  1.2475 +  nsDisplayLayerEventRegions(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
  1.2476 +    : nsDisplayItem(aBuilder, aFrame)
  1.2477 +  {
  1.2478 +    MOZ_COUNT_CTOR(nsDisplayEventReceiver);
  1.2479 +    AddFrame(aBuilder, aFrame);
  1.2480 +  }
  1.2481 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2482 +  virtual ~nsDisplayLayerEventRegions() {
  1.2483 +    MOZ_COUNT_DTOR(nsDisplayEventReceiver);
  1.2484 +  }
  1.2485 +#endif
  1.2486 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE
  1.2487 +  {
  1.2488 +    *aSnap = false;
  1.2489 +    return mHitRegion.GetBounds().Union(mMaybeHitRegion.GetBounds());
  1.2490 +  }
  1.2491 +
  1.2492 +  NS_DISPLAY_DECL_NAME("LayerEventRegions", TYPE_LAYER_EVENT_REGIONS)
  1.2493 +
  1.2494 +  // Indicate that aFrame's border-box contributes to the event regions for
  1.2495 +  // this layer. aFrame must have the same reference frame as mFrame.
  1.2496 +  void AddFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
  1.2497 +
  1.2498 +  const nsRegion& HitRegion() { return mHitRegion; }
  1.2499 +  const nsRegion& MaybeHitRegion() { return mMaybeHitRegion; }
  1.2500 +  const nsRegion& DispatchToContentHitRegion() { return mDispatchToContentHitRegion; }
  1.2501 +
  1.2502 +private:
  1.2503 +  // Relative to aFrame's reference frame.
  1.2504 +  // These are the points that are definitely in the hit region.
  1.2505 +  nsRegion mHitRegion;
  1.2506 +  // These are points that may or may not be in the hit region. Only main-thread
  1.2507 +  // event handling can tell for sure (e.g. because complex shapes are present).
  1.2508 +  nsRegion mMaybeHitRegion;
  1.2509 +  // These are points that need to be dispatched to the content thread for
  1.2510 +  // resolution. Always contained in the union of mHitRegion and mMaybeHitRegion.
  1.2511 +  nsRegion mDispatchToContentHitRegion;
  1.2512 +};
  1.2513 +
  1.2514 +/**
  1.2515 + * A class that lets you wrap a display list as a display item.
  1.2516 + * 
  1.2517 + * GetUnderlyingFrame() is troublesome for wrapped lists because if the wrapped
  1.2518 + * list has many items, it's not clear which one has the 'underlying frame'.
  1.2519 + * Thus we force the creator to specify what the underlying frame is. The
  1.2520 + * underlying frame should be the root of a stacking context, because sorting
  1.2521 + * a list containing this item will not get at the children.
  1.2522 + * 
  1.2523 + * In some cases (e.g., clipping) we want to wrap a list but we don't have a
  1.2524 + * particular underlying frame that is a stacking context root. In that case
  1.2525 + * we allow the frame to be nullptr. Callers to GetUnderlyingFrame must
  1.2526 + * detect and handle this case.
  1.2527 + */
  1.2528 +class nsDisplayWrapList : public nsDisplayItem {
  1.2529 +  // This is never instantiated directly, so no need to count constructors and
  1.2530 +  // destructors.
  1.2531 +
  1.2532 +public:
  1.2533 +  /**
  1.2534 +   * Takes all the items from aList and puts them in our list.
  1.2535 +   */
  1.2536 +  nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2537 +                    nsDisplayList* aList);
  1.2538 +  nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2539 +                    nsDisplayItem* aItem);
  1.2540 +  nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2541 +                    nsDisplayItem* aItem, const nsIFrame* aReferenceFrame, const nsPoint& aToReferenceFrame);
  1.2542 +  nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
  1.2543 +    : nsDisplayItem(aBuilder, aFrame), mOverrideZIndex(0) {}
  1.2544 +  virtual ~nsDisplayWrapList();
  1.2545 +  /**
  1.2546 +   * Call this if the wrapped list is changed.
  1.2547 +   */
  1.2548 +  virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
  1.2549 +  {
  1.2550 +    mBounds = mList.GetBounds(aBuilder);
  1.2551 +  }
  1.2552 +  virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
  1.2553 +                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
  1.2554 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
  1.2555 +  virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
  1.2556 +                                   bool* aSnap) MOZ_OVERRIDE;
  1.2557 +  virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE;
  1.2558 +  virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
  1.2559 +                                                nsIFrame* aFrame) MOZ_OVERRIDE;
  1.2560 +  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
  1.2561 +  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
  1.2562 +                                 nsRegion* aVisibleRegion,
  1.2563 +                                 const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
  1.2564 +  virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE {
  1.2565 +    NS_WARNING("This list should already have been flattened!!!");
  1.2566 +    return false;
  1.2567 +  }
  1.2568 +  virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) MOZ_OVERRIDE
  1.2569 +  {
  1.2570 +    aFrames->AppendElements(mMergedFrames);
  1.2571 +  }
  1.2572 +  virtual bool IsInvalid(nsRect& aRect) MOZ_OVERRIDE
  1.2573 +  {
  1.2574 +    if (mFrame->IsInvalid(aRect) && aRect.IsEmpty()) {
  1.2575 +      return true;
  1.2576 +    }
  1.2577 +    nsRect temp;
  1.2578 +    for (uint32_t i = 0; i < mMergedFrames.Length(); i++) {
  1.2579 +      if (mMergedFrames[i]->IsInvalid(temp) && temp.IsEmpty()) {
  1.2580 +        aRect.SetEmpty();
  1.2581 +        return true;
  1.2582 +      }
  1.2583 +      aRect = aRect.Union(temp);
  1.2584 +    }
  1.2585 +    aRect += ToReferenceFrame();
  1.2586 +    return !aRect.IsEmpty();
  1.2587 +  }
  1.2588 +  NS_DISPLAY_DECL_NAME("WrapList", TYPE_WRAP_LIST)
  1.2589 +
  1.2590 +  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
  1.2591 +                                    
  1.2592 +  virtual nsDisplayList* GetSameCoordinateSystemChildren() MOZ_OVERRIDE
  1.2593 +  {
  1.2594 +    NS_ASSERTION(mList.IsEmpty() || !ReferenceFrame() ||
  1.2595 +                 !mList.GetBottom()->ReferenceFrame() ||
  1.2596 +                 mList.GetBottom()->ReferenceFrame() == ReferenceFrame(),
  1.2597 +                 "Children must have same reference frame");
  1.2598 +    return &mList;
  1.2599 +  }
  1.2600 +  virtual nsDisplayList* GetChildren() MOZ_OVERRIDE { return &mList; }
  1.2601 +
  1.2602 +  virtual int32_t ZIndex() const MOZ_OVERRIDE
  1.2603 +  {
  1.2604 +    return (mOverrideZIndex > 0) ? mOverrideZIndex : nsDisplayItem::ZIndex();
  1.2605 +  }
  1.2606 +
  1.2607 +  void SetOverrideZIndex(int32_t aZIndex)
  1.2608 +  {
  1.2609 +    mOverrideZIndex = aZIndex;
  1.2610 +  }
  1.2611 +
  1.2612 +  /**
  1.2613 +   * This creates a copy of this item, but wrapping aItem instead of
  1.2614 +   * our existing list. Only gets called if this item returned nullptr
  1.2615 +   * for GetUnderlyingFrame(). aItem is guaranteed to return non-null from
  1.2616 +   * GetUnderlyingFrame().
  1.2617 +   */
  1.2618 +  virtual nsDisplayWrapList* WrapWithClone(nsDisplayListBuilder* aBuilder,
  1.2619 +                                           nsDisplayItem* aItem) {
  1.2620 +    NS_NOTREACHED("We never returned nullptr for GetUnderlyingFrame!");
  1.2621 +    return nullptr;
  1.2622 +  }
  1.2623 +
  1.2624 +protected:
  1.2625 +  nsDisplayWrapList() {}
  1.2626 +
  1.2627 +  void MergeFrom(nsDisplayWrapList* aOther)
  1.2628 +  {
  1.2629 +    mList.AppendToBottom(&aOther->mList);
  1.2630 +    mBounds.UnionRect(mBounds, aOther->mBounds);
  1.2631 +  }
  1.2632 +  void MergeFromTrackingMergedFrames(nsDisplayWrapList* aOther)
  1.2633 +  {
  1.2634 +    MergeFrom(aOther);
  1.2635 +    mMergedFrames.AppendElement(aOther->mFrame);
  1.2636 +    mMergedFrames.MoveElementsFrom(aOther->mMergedFrames);
  1.2637 +  }
  1.2638 +
  1.2639 +  nsDisplayList mList;
  1.2640 +  // The frames from items that have been merged into this item, excluding
  1.2641 +  // this item's own frame.
  1.2642 +  nsTArray<nsIFrame*> mMergedFrames;
  1.2643 +  nsRect mBounds;
  1.2644 +  // Overrides the ZIndex of our frame if > 0.
  1.2645 +  int32_t mOverrideZIndex;
  1.2646 +};
  1.2647 +
  1.2648 +/**
  1.2649 + * We call WrapDisplayList on the in-flow lists: BorderBackground(),
  1.2650 + * BlockBorderBackgrounds() and Content().
  1.2651 + * We call WrapDisplayItem on each item of Outlines(), PositionedDescendants(),
  1.2652 + * and Floats(). This is done to support special wrapping processing for frames
  1.2653 + * that may not be in-flow descendants of the current frame.
  1.2654 + */
  1.2655 +class nsDisplayWrapper {
  1.2656 +public:
  1.2657 +  // This is never instantiated directly (it has pure virtual methods), so no
  1.2658 +  // need to count constructors and destructors.
  1.2659 +
  1.2660 +  virtual bool WrapBorderBackground() { return true; }
  1.2661 +  virtual nsDisplayItem* WrapList(nsDisplayListBuilder* aBuilder,
  1.2662 +                                  nsIFrame* aFrame, nsDisplayList* aList) = 0;
  1.2663 +  virtual nsDisplayItem* WrapItem(nsDisplayListBuilder* aBuilder,
  1.2664 +                                  nsDisplayItem* aItem) = 0;
  1.2665 +
  1.2666 +  nsresult WrapLists(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2667 +                     const nsDisplayListSet& aIn, const nsDisplayListSet& aOut);
  1.2668 +  nsresult WrapListsInPlace(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2669 +                            const nsDisplayListSet& aLists);
  1.2670 +protected:
  1.2671 +  nsDisplayWrapper() {}
  1.2672 +};
  1.2673 +
  1.2674 +/**
  1.2675 + * The standard display item to paint a stacking context with translucency
  1.2676 + * set by the stacking context root frame's 'opacity' style.
  1.2677 + */
  1.2678 +class nsDisplayOpacity : public nsDisplayWrapList {
  1.2679 +public:
  1.2680 +  nsDisplayOpacity(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2681 +                   nsDisplayList* aList);
  1.2682 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2683 +  virtual ~nsDisplayOpacity();
  1.2684 +#endif
  1.2685 +
  1.2686 +  virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
  1.2687 +                                   bool* aSnap) MOZ_OVERRIDE;
  1.2688 +  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
  1.2689 +                                             LayerManager* aManager,
  1.2690 +                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
  1.2691 +  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
  1.2692 +                                   LayerManager* aManager,
  1.2693 +                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
  1.2694 +  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
  1.2695 +                                   nsRegion* aVisibleRegion,
  1.2696 +                                   const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;  
  1.2697 +  virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
  1.2698 +  virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
  1.2699 +                                         const nsDisplayItemGeometry* aGeometry,
  1.2700 +                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE
  1.2701 +  {
  1.2702 +    // We don't need to compute an invalidation region since we have LayerTreeInvalidation
  1.2703 +  }
  1.2704 +  virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
  1.2705 +  bool NeedsActiveLayer();
  1.2706 +  NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
  1.2707 +#ifdef MOZ_DUMP_PAINTING
  1.2708 +  virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
  1.2709 +#endif
  1.2710 +
  1.2711 +  bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
  1.2712 +};
  1.2713 +
  1.2714 +class nsDisplayMixBlendMode : public nsDisplayWrapList {
  1.2715 +public:
  1.2716 +  nsDisplayMixBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2717 +                        nsDisplayList* aList, uint32_t aFlags = 0);
  1.2718 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2719 +  virtual ~nsDisplayMixBlendMode();
  1.2720 +#endif
  1.2721 +
  1.2722 +  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
  1.2723 +                           bool* aSnap) MOZ_OVERRIDE;
  1.2724 +
  1.2725 +  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
  1.2726 +                                             LayerManager* aManager,
  1.2727 +                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
  1.2728 +  virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
  1.2729 +                                         const nsDisplayItemGeometry* aGeometry,
  1.2730 +                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE
  1.2731 +  {
  1.2732 +    // We don't need to compute an invalidation region since we have LayerTreeInvalidation
  1.2733 +  }
  1.2734 +  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
  1.2735 +                                   LayerManager* aManager,
  1.2736 +                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
  1.2737 +  {
  1.2738 +    return mozilla::LAYER_INACTIVE;
  1.2739 +  }
  1.2740 +  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
  1.2741 +                                 nsRegion* aVisibleRegion,
  1.2742 +                                 const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
  1.2743 +  virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
  1.2744 +  NS_DISPLAY_DECL_NAME("MixBlendMode", TYPE_MIX_BLEND_MODE)
  1.2745 +};
  1.2746 +
  1.2747 +class nsDisplayBlendContainer : public nsDisplayWrapList {
  1.2748 +public:
  1.2749 +    nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2750 +                          nsDisplayList* aList, uint32_t aFlags = 0);
  1.2751 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2752 +    virtual ~nsDisplayBlendContainer();
  1.2753 +#endif
  1.2754 +    
  1.2755 +    virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
  1.2756 +                                               LayerManager* aManager,
  1.2757 +                                               const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
  1.2758 +    virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
  1.2759 +                                     LayerManager* aManager,
  1.2760 +                                     const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
  1.2761 +    {
  1.2762 +        return mozilla::LAYER_INACTIVE;
  1.2763 +    }
  1.2764 +    virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
  1.2765 +    NS_DISPLAY_DECL_NAME("BlendContainer", TYPE_BLEND_CONTAINER)
  1.2766 +};
  1.2767 +
  1.2768 +/**
  1.2769 + * A display item that has no purpose but to ensure its contents get
  1.2770 + * their own layer.
  1.2771 + */
  1.2772 +class nsDisplayOwnLayer : public nsDisplayWrapList {
  1.2773 +public:
  1.2774 +
  1.2775 +  /**
  1.2776 +   * nsDisplayOwnLayer constructor flags
  1.2777 +   */
  1.2778 +  enum {
  1.2779 +    GENERATE_SUBDOC_INVALIDATIONS = 0x01,
  1.2780 +    VERTICAL_SCROLLBAR = 0x02,
  1.2781 +    HORIZONTAL_SCROLLBAR = 0x04,
  1.2782 +    GENERATE_SCROLLABLE_LAYER = 0x08
  1.2783 +  };
  1.2784 +
  1.2785 +  /**
  1.2786 +   * @param aFlags GENERATE_SUBDOC_INVALIDATIONS :
  1.2787 +   * Add UserData to the created ContainerLayer, so that invalidations
  1.2788 +   * for this layer are send to our nsPresContext.
  1.2789 +   * GENERATE_SCROLLABLE_LAYER : only valid on nsDisplaySubDocument (and
  1.2790 +   * subclasses), indicates this layer is to be a scrollable layer, so call
  1.2791 +   * RecordFrameMetrics, etc.
  1.2792 +   * @param aScrollTarget when VERTICAL_SCROLLBAR or HORIZONTAL_SCROLLBAR
  1.2793 +   * is set in the flags, this parameter should be the ViewID of the
  1.2794 +   * scrollable content this scrollbar is for.
  1.2795 +   */
  1.2796 +  nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2797 +                    nsDisplayList* aList, uint32_t aFlags = 0,
  1.2798 +                    ViewID aScrollTarget = mozilla::layers::FrameMetrics::NULL_SCROLL_ID);
  1.2799 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2800 +  virtual ~nsDisplayOwnLayer();
  1.2801 +#endif
  1.2802 +  
  1.2803 +  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
  1.2804 +                                             LayerManager* aManager,
  1.2805 +                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
  1.2806 +  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
  1.2807 +                                   LayerManager* aManager,
  1.2808 +                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
  1.2809 +  {
  1.2810 +    return mozilla::LAYER_ACTIVE_FORCE;
  1.2811 +  }
  1.2812 +  virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE
  1.2813 +  {
  1.2814 +    // Don't allow merging, each sublist must have its own layer
  1.2815 +    return false;
  1.2816 +  }
  1.2817 +  uint32_t GetFlags() { return mFlags; }
  1.2818 +  NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
  1.2819 +protected:
  1.2820 +  uint32_t mFlags;
  1.2821 +  ViewID mScrollTarget;
  1.2822 +};
  1.2823 +
  1.2824 +/**
  1.2825 + * A display item for subdocuments. This is more or less the same as nsDisplayOwnLayer,
  1.2826 + * except that it always populates the FrameMetrics instance on the ContainerLayer it
  1.2827 + * builds.
  1.2828 + */
  1.2829 +class nsDisplaySubDocument : public nsDisplayOwnLayer {
  1.2830 +public:
  1.2831 +  nsDisplaySubDocument(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2832 +                       nsDisplayList* aList, uint32_t aFlags);
  1.2833 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2834 +  virtual ~nsDisplaySubDocument();
  1.2835 +#endif
  1.2836 +
  1.2837 +  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
  1.2838 +                                             LayerManager* aManager,
  1.2839 +                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
  1.2840 +
  1.2841 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
  1.2842 +
  1.2843 +  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
  1.2844 +                                 nsRegion* aVisibleRegion,
  1.2845 +                                 const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
  1.2846 +
  1.2847 +  virtual bool SetVisibleRegionOnLayer() MOZ_OVERRIDE { return !(mFlags & GENERATE_SCROLLABLE_LAYER); }
  1.2848 +
  1.2849 +  virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
  1.2850 +
  1.2851 +  virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
  1.2852 +
  1.2853 +  NS_DISPLAY_DECL_NAME("SubDocument", TYPE_SUBDOCUMENT)
  1.2854 +protected:
  1.2855 +  ViewID mScrollParentId;
  1.2856 +};
  1.2857 +
  1.2858 +/**
  1.2859 + * A display item for subdocuments to capture the resolution from the presShell
  1.2860 + * and ensure that it gets applied to all the right elements. This item creates
  1.2861 + * a container layer.
  1.2862 + */
  1.2863 +class nsDisplayResolution : public nsDisplaySubDocument {
  1.2864 +public:
  1.2865 +  nsDisplayResolution(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2866 +                      nsDisplayList* aList, uint32_t aFlags);
  1.2867 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2868 +  virtual ~nsDisplayResolution();
  1.2869 +#endif
  1.2870 +
  1.2871 +  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
  1.2872 +                                             LayerManager* aManager,
  1.2873 +                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
  1.2874 +  NS_DISPLAY_DECL_NAME("Resolution", TYPE_RESOLUTION)
  1.2875 +};
  1.2876 +
  1.2877 +/**
  1.2878 + * A display item used to represent sticky position elements. The contents
  1.2879 + * gets its own layer and creates a stacking context, and the layer will have
  1.2880 + * position-related metadata set on it.
  1.2881 + */
  1.2882 +class nsDisplayStickyPosition : public nsDisplayOwnLayer {
  1.2883 +public:
  1.2884 +  nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.2885 +                          nsDisplayList* aList);
  1.2886 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2887 +  virtual ~nsDisplayStickyPosition();
  1.2888 +#endif
  1.2889 +
  1.2890 +  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
  1.2891 +                                             LayerManager* aManager,
  1.2892 +                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
  1.2893 +  NS_DISPLAY_DECL_NAME("StickyPosition", TYPE_STICKY_POSITION)
  1.2894 +  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
  1.2895 +                                   LayerManager* aManager,
  1.2896 +                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
  1.2897 +  {
  1.2898 +    return mozilla::LAYER_ACTIVE;
  1.2899 +  }
  1.2900 +  virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
  1.2901 +};
  1.2902 +
  1.2903 +/**
  1.2904 + * This potentially creates a layer for the given list of items, whose
  1.2905 + * visibility is determined by the displayport for the given frame instead of
  1.2906 + * what is passed in to ComputeVisibility.
  1.2907 + *
  1.2908 + * Here in content, we can use this to render more content than is actually
  1.2909 + * visible. Then, the compositing process can manipulate the generated layer
  1.2910 + * through transformations so that asynchronous scrolling can be implemented.
  1.2911 + *
  1.2912 + * Note that setting the displayport will not change any hit testing! The
  1.2913 + * content process will know nothing about what the user is actually seeing,
  1.2914 + * so it can only do hit testing for what is supposed to be the visible region.
  1.2915 + *
  1.2916 + * It is possible for scroll boxes to have content that can be both above and
  1.2917 + * below content outside of the scroll box. We cannot create layers for these
  1.2918 + * cases. This is accomplished by wrapping display items with
  1.2919 + * nsDisplayScrollLayers. nsDisplayScrollLayers with the same scroll frame will
  1.2920 + * be merged together. If more than one nsDisplayScrollLayer exists after
  1.2921 + * merging, all nsDisplayScrollLayers will be flattened out so that no new
  1.2922 + * layer is created at all.
  1.2923 + */
  1.2924 +class nsDisplayScrollLayer : public nsDisplayWrapList
  1.2925 +{
  1.2926 +public:
  1.2927 +  /**
  1.2928 +   * @param aScrolledFrame This will determine what the displayport is. It should be
  1.2929 +   *                       the root content frame of the scrolled area. Note
  1.2930 +   *                       that nsDisplayScrollLayer will expect for
  1.2931 +   *                       ScrollLayerCount to be defined on aScrolledFrame.
  1.2932 +   * @param aScrollFrame The viewport frame you see this content through.
  1.2933 +   */
  1.2934 +  nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
  1.2935 +                       nsIFrame* aForFrame, nsIFrame* aScrolledFrame,
  1.2936 +                       nsIFrame* aScrollFrame);
  1.2937 +  nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
  1.2938 +                       nsIFrame* aForFrame, nsIFrame* aScrolledFrame,
  1.2939 +                       nsIFrame* aScrollFrame);
  1.2940 +  nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
  1.2941 +                       nsIFrame* aForFrame, nsIFrame* aScrolledFrame,
  1.2942 +                       nsIFrame* aScrollFrame);
  1.2943 +  NS_DISPLAY_DECL_NAME("ScrollLayer", TYPE_SCROLL_LAYER)
  1.2944 +
  1.2945 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.2946 +  virtual ~nsDisplayScrollLayer();
  1.2947 +#endif
  1.2948 +
  1.2949 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
  1.2950 +
  1.2951 +  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
  1.2952 +                                             LayerManager* aManager,
  1.2953 +                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
  1.2954 +
  1.2955 +  virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
  1.2956 +
  1.2957 +  virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
  1.2958 +                                   bool* aSnap) MOZ_OVERRIDE {
  1.2959 +    *aSnap = false;
  1.2960 +    return nsRegion();
  1.2961 +  }
  1.2962 +
  1.2963 +  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
  1.2964 +                                   nsRegion* aVisibleRegion,
  1.2965 +                                   const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
  1.2966 +
  1.2967 +  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
  1.2968 +                                   LayerManager* aManager,
  1.2969 +                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
  1.2970 +
  1.2971 +  virtual bool TryMerge(nsDisplayListBuilder* aBuilder,
  1.2972 +                          nsDisplayItem* aItem) MOZ_OVERRIDE;
  1.2973 +
  1.2974 +  virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
  1.2975 +
  1.2976 +  // Get the number of nsDisplayScrollLayers for a scroll frame. Note that this
  1.2977 +  // number does not include nsDisplayScrollInfoLayers. If this number is not 1
  1.2978 +  // after merging, all the nsDisplayScrollLayers should flatten away.
  1.2979 +  intptr_t GetScrollLayerCount();
  1.2980 +
  1.2981 +  virtual nsIFrame* GetScrollFrame() { return mScrollFrame; }
  1.2982 +  virtual nsIFrame* GetScrolledFrame() { return mScrolledFrame; }
  1.2983 +
  1.2984 +  virtual bool SetVisibleRegionOnLayer() MOZ_OVERRIDE { return false; }
  1.2985 +
  1.2986 +#ifdef MOZ_DUMP_PAINTING
  1.2987 +  virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
  1.2988 +#endif
  1.2989 +
  1.2990 +protected:
  1.2991 +  nsIFrame* mScrollFrame;
  1.2992 +  nsIFrame* mScrolledFrame;
  1.2993 +  ViewID mScrollParentId;
  1.2994 +};
  1.2995 +
  1.2996 +/**
  1.2997 + * Like nsDisplayScrollLayer, but only has metadata on the scroll frame. This
  1.2998 + * creates a layer that has no Thebes child layer, but still allows the
  1.2999 + * compositor process to know of the scroll frame's existence.
  1.3000 + *
  1.3001 + * After visibility computation, nsDisplayScrollInfoLayers should only exist if
  1.3002 + * nsDisplayScrollLayers were all flattened away.
  1.3003 + *
  1.3004 + * Important!! Add info layers to the bottom of the list so they are only
  1.3005 + * considered after the others have flattened out!
  1.3006 + */
  1.3007 +class nsDisplayScrollInfoLayer : public nsDisplayScrollLayer
  1.3008 +{
  1.3009 +public:
  1.3010 +  nsDisplayScrollInfoLayer(nsDisplayListBuilder* aBuilder,
  1.3011 +                           nsIFrame* aScrolledFrame, nsIFrame* aScrollFrame);
  1.3012 +  NS_DISPLAY_DECL_NAME("ScrollInfoLayer", TYPE_SCROLL_INFO_LAYER)
  1.3013 +
  1.3014 +  virtual ~nsDisplayScrollInfoLayer();
  1.3015 +
  1.3016 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
  1.3017 +
  1.3018 +  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
  1.3019 +                                   LayerManager* aManager,
  1.3020 +                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
  1.3021 +  virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
  1.3022 +  { return true; }
  1.3023 +  virtual bool TryMerge(nsDisplayListBuilder* aBuilder,
  1.3024 +                          nsDisplayItem* aItem) MOZ_OVERRIDE;
  1.3025 +
  1.3026 +  virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
  1.3027 +};
  1.3028 +
  1.3029 +/**
  1.3030 + * nsDisplayZoom is used for subdocuments that have a different full zoom than
  1.3031 + * their parent documents. This item creates a container layer.
  1.3032 + */
  1.3033 +class nsDisplayZoom : public nsDisplaySubDocument {
  1.3034 +public:
  1.3035 +  /**
  1.3036 +   * @param aFrame is the root frame of the subdocument.
  1.3037 +   * @param aList contains the display items for the subdocument.
  1.3038 +   * @param aAPD is the app units per dev pixel ratio of the subdocument.
  1.3039 +   * @param aParentAPD is the app units per dev pixel ratio of the parent
  1.3040 +   * document.
  1.3041 +   * @param aFlags GENERATE_SUBDOC_INVALIDATIONS :
  1.3042 +   * Add UserData to the created ContainerLayer, so that invalidations
  1.3043 +   * for this layer are send to our nsPresContext.
  1.3044 +   */
  1.3045 +  nsDisplayZoom(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.3046 +                nsDisplayList* aList,
  1.3047 +                int32_t aAPD, int32_t aParentAPD,
  1.3048 +                uint32_t aFlags = 0);
  1.3049 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.3050 +  virtual ~nsDisplayZoom();
  1.3051 +#endif
  1.3052 +  
  1.3053 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
  1.3054 +  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
  1.3055 +  virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
  1.3056 +                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
  1.3057 +  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
  1.3058 +                                   nsRegion* aVisibleRegion,
  1.3059 +                                   const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
  1.3060 +  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
  1.3061 +                                   LayerManager* aManager,
  1.3062 +                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
  1.3063 +  {
  1.3064 +    return mozilla::LAYER_ACTIVE;
  1.3065 +  }
  1.3066 +  NS_DISPLAY_DECL_NAME("Zoom", TYPE_ZOOM)
  1.3067 +
  1.3068 +  // Get the app units per dev pixel ratio of the child document.
  1.3069 +  int32_t GetChildAppUnitsPerDevPixel() { return mAPD; }
  1.3070 +  // Get the app units per dev pixel ratio of the parent document.
  1.3071 +  int32_t GetParentAppUnitsPerDevPixel() { return mParentAPD; }
  1.3072 +
  1.3073 +private:
  1.3074 +  int32_t mAPD, mParentAPD;
  1.3075 +};
  1.3076 +
  1.3077 +/**
  1.3078 + * A display item to paint a stacking context with effects
  1.3079 + * set by the stacking context root frame's style.
  1.3080 + */
  1.3081 +class nsDisplaySVGEffects : public nsDisplayWrapList {
  1.3082 +public:
  1.3083 +  nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
  1.3084 +                      nsDisplayList* aList);
  1.3085 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.3086 +  virtual ~nsDisplaySVGEffects();
  1.3087 +#endif
  1.3088 +  
  1.3089 +  virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
  1.3090 +                                   bool* aSnap) MOZ_OVERRIDE;
  1.3091 +  virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
  1.3092 +                       HitTestState* aState,
  1.3093 +                       nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
  1.3094 +  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
  1.3095 +                           bool* aSnap) MOZ_OVERRIDE {
  1.3096 +    *aSnap = false;
  1.3097 +    return mEffectsBounds + ToReferenceFrame();
  1.3098 +  }
  1.3099 +  virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
  1.3100 +                                   nsRegion* aVisibleRegion,
  1.3101 +                                   const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;  
  1.3102 +  virtual bool TryMerge(nsDisplayListBuilder* aBuilder,
  1.3103 +                        nsDisplayItem* aItem) MOZ_OVERRIDE;
  1.3104 +  NS_DISPLAY_DECL_NAME("SVGEffects", TYPE_SVG_EFFECTS)
  1.3105 +
  1.3106 +  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
  1.3107 +                                   LayerManager* aManager,
  1.3108 +                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
  1.3109 + 
  1.3110 +  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
  1.3111 +                                             LayerManager* aManager,
  1.3112 +                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
  1.3113 +  
  1.3114 +  virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
  1.3115 +                                         const nsDisplayItemGeometry* aGeometry,
  1.3116 +                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE
  1.3117 +  {
  1.3118 +    // We don't need to compute an invalidation region since we have LayerTreeInvalidation
  1.3119 +  }
  1.3120 +
  1.3121 +  void PaintAsLayer(nsDisplayListBuilder* aBuilder,
  1.3122 +                    nsRenderingContext* aCtx,
  1.3123 +                    LayerManager* aManager);
  1.3124 +
  1.3125 +#ifdef MOZ_DUMP_PAINTING
  1.3126 +  void PrintEffects(nsACString& aTo);
  1.3127 +#endif
  1.3128 +
  1.3129 +private:
  1.3130 +  // relative to mFrame
  1.3131 +  nsRect mEffectsBounds;
  1.3132 +};
  1.3133 +
  1.3134 +/* A display item that applies a transformation to all of its descendant
  1.3135 + * elements.  This wrapper should only be used if there is a transform applied
  1.3136 + * to the root element.
  1.3137 + *
  1.3138 + * The reason that a "bounds" rect is involved in transform calculations is
  1.3139 + * because CSS-transforms allow percentage values for the x and y components
  1.3140 + * of <translation-value>s, where percentages are percentages of the element's
  1.3141 + * border box.
  1.3142 + *
  1.3143 + * INVARIANT: The wrapped frame is transformed or we supplied a transform getter
  1.3144 + * function.
  1.3145 + * INVARIANT: The wrapped frame is non-null.
  1.3146 + */ 
  1.3147 +class nsDisplayTransform: public nsDisplayItem
  1.3148 +{
  1.3149 +public:
  1.3150 +  /**
  1.3151 +   * Returns a matrix (in pixels) for the current frame. The matrix should be relative to
  1.3152 +   * the current frame's coordinate space.
  1.3153 +   *
  1.3154 +   * @param aFrame The frame to compute the transform for.
  1.3155 +   * @param aAppUnitsPerPixel The number of app units per graphics unit.
  1.3156 +   */
  1.3157 +  typedef gfx3DMatrix (* ComputeTransformFunction)(nsIFrame* aFrame, float aAppUnitsPerPixel);
  1.3158 +
  1.3159 +  /* Constructor accepts a display list, empties it, and wraps it up.  It also
  1.3160 +   * ferries the underlying frame to the nsDisplayItem constructor.
  1.3161 +   */
  1.3162 +  nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
  1.3163 +                     nsDisplayList *aList, uint32_t aIndex = 0);
  1.3164 +  nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
  1.3165 +                     nsDisplayItem *aItem, uint32_t aIndex = 0);
  1.3166 +  nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
  1.3167 +                     nsDisplayList *aList, ComputeTransformFunction aTransformGetter, uint32_t aIndex = 0);
  1.3168 +
  1.3169 +#ifdef NS_BUILD_REFCNT_LOGGING
  1.3170 +  virtual ~nsDisplayTransform()
  1.3171 +  {
  1.3172 +    MOZ_COUNT_DTOR(nsDisplayTransform);
  1.3173 +  }
  1.3174 +#endif
  1.3175 +
  1.3176 +  NS_DISPLAY_DECL_NAME("nsDisplayTransform", TYPE_TRANSFORM)
  1.3177 +
  1.3178 +  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
  1.3179 +  {
  1.3180 +    if (mStoredList.GetComponentAlphaBounds(aBuilder).IsEmpty())
  1.3181 +      return nsRect();
  1.3182 +    bool snap;
  1.3183 +    return GetBounds(aBuilder, &snap);
  1.3184 +  }
  1.3185 +
  1.3186 +  virtual nsDisplayList* GetChildren() MOZ_OVERRIDE { return mStoredList.GetChildren(); }
  1.3187 +
  1.3188 +  virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect,
  1.3189 +                       HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
  1.3190 +  virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap) MOZ_OVERRIDE;
  1.3191 +  virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
  1.3192 +                                   bool* aSnap) MOZ_OVERRIDE;
  1.3193 +  virtual bool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor) MOZ_OVERRIDE;
  1.3194 +  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
  1.3195 +                                   LayerManager* aManager,
  1.3196 +                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
  1.3197 +  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
  1.3198 +                                             LayerManager* aManager,
  1.3199 +                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
  1.3200 +  virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
  1.3201 +  virtual bool ComputeVisibility(nsDisplayListBuilder *aBuilder,
  1.3202 +                                   nsRegion *aVisibleRegion,
  1.3203 +                                   const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
  1.3204 +  virtual bool TryMerge(nsDisplayListBuilder *aBuilder, nsDisplayItem *aItem) MOZ_OVERRIDE;
  1.3205 +  
  1.3206 +  virtual uint32_t GetPerFrameKey() MOZ_OVERRIDE { return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); }
  1.3207 +  
  1.3208 +  virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
  1.3209 +                                         const nsDisplayItemGeometry* aGeometry,
  1.3210 +                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE
  1.3211 +  {
  1.3212 +    // We don't need to compute an invalidation region since we have LayerTreeInvalidation
  1.3213 +  }
  1.3214 +
  1.3215 +  virtual const nsIFrame* ReferenceFrameForChildren() const MOZ_OVERRIDE {
  1.3216 +    // If we were created using a transform-getter, then we don't
  1.3217 +    // belong to a transformed frame, and aren't a reference frame
  1.3218 +    // for our children.
  1.3219 +    if (!mTransformGetter) {
  1.3220 +      return mFrame;
  1.3221 +    }
  1.3222 +    return nsDisplayItem::ReferenceFrameForChildren(); 
  1.3223 +  }
  1.3224 +
  1.3225 +  enum {
  1.3226 +    INDEX_MAX = UINT32_MAX >> nsDisplayItem::TYPE_BITS
  1.3227 +  };
  1.3228 +
  1.3229 +  const gfx3DMatrix& GetTransform();
  1.3230 +
  1.3231 +  float GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsPoint& aPoint);
  1.3232 +
  1.3233 +  /**
  1.3234 +   * TransformRect takes in as parameters a rectangle (in aFrame's coordinate
  1.3235 +   * space) and returns the smallest rectangle (in aFrame's coordinate space)
  1.3236 +   * containing the transformed image of that rectangle.  That is, it takes
  1.3237 +   * the four corners of the rectangle, transforms them according to the
  1.3238 +   * matrix associated with the specified frame, then returns the smallest
  1.3239 +   * rectangle containing the four transformed points.
  1.3240 +   *
  1.3241 +   * @param untransformedBounds The rectangle (in app units) to transform.
  1.3242 +   * @param aFrame The frame whose transformation should be applied.  This
  1.3243 +   *        function raises an assertion if aFrame is null or doesn't have a
  1.3244 +   *        transform applied to it.
  1.3245 +   * @param aOrigin The origin of the transform relative to aFrame's local
  1.3246 +   *        coordinate space.
  1.3247 +   * @param aBoundsOverride (optional) Rather than using the frame's computed
  1.3248 +   *        bounding rect as frame bounds, use this rectangle instead.  Pass
  1.3249 +   *        nullptr (or nothing at all) to use the default.
  1.3250 +   */
  1.3251 +  static nsRect TransformRect(const nsRect &aUntransformedBounds, 
  1.3252 +                              const nsIFrame* aFrame,
  1.3253 +                              const nsPoint &aOrigin,
  1.3254 +                              const nsRect* aBoundsOverride = nullptr);
  1.3255 +
  1.3256 +  static nsRect TransformRectOut(const nsRect &aUntransformedBounds, 
  1.3257 +                                 const nsIFrame* aFrame,
  1.3258 +                                 const nsPoint &aOrigin,
  1.3259 +                                 const nsRect* aBoundsOverride = nullptr);
  1.3260 +
  1.3261 +  /* UntransformRect is like TransformRect, except that it inverts the
  1.3262 +   * transform.
  1.3263 +   */
  1.3264 +  static bool UntransformRect(const nsRect &aTransformedBounds,
  1.3265 +                              const nsRect &aChildBounds,
  1.3266 +                              const nsIFrame* aFrame,
  1.3267 +                              const nsPoint &aOrigin,
  1.3268 +                              nsRect *aOutRect);
  1.3269 +
  1.3270 +  bool UntransformVisibleRect(nsDisplayListBuilder* aBuilder,
  1.3271 +                              nsRect* aOutRect);
  1.3272 +
  1.3273 +  static gfxPoint3D GetDeltaToTransformOrigin(const nsIFrame* aFrame,
  1.3274 +                                              float aAppUnitsPerPixel,
  1.3275 +                                              const nsRect* aBoundsOverride);
  1.3276 +
  1.3277 +  static gfxPoint3D GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame,
  1.3278 +                                                float aAppUnitsPerPixel);
  1.3279 +
  1.3280 +  /**
  1.3281 +   * Returns the bounds of a frame as defined for resolving percentage
  1.3282 +   * <translation-value>s in CSS transforms.  If
  1.3283 +   * UNIFIED_CONTINUATIONS is not defined, this is simply the frame's bounding
  1.3284 +   * rectangle, translated to the origin.  Otherwise, returns the smallest
  1.3285 +   * rectangle containing a frame and all of its continuations.  For example,
  1.3286 +   * if there is a <span> element with several continuations split over
  1.3287 +   * several lines, this function will return the rectangle containing all of
  1.3288 +   * those continuations.  This rectangle is relative to the origin of the
  1.3289 +   * frame's local coordinate space.
  1.3290 +   *
  1.3291 +   * @param aFrame The frame to get the bounding rect for.
  1.3292 +   * @return The frame's bounding rect, as described above.
  1.3293 +   */
  1.3294 +  static nsRect GetFrameBoundsForTransform(const nsIFrame* aFrame);
  1.3295 +
  1.3296 +  struct FrameTransformProperties
  1.3297 +  {
  1.3298 +    FrameTransformProperties(const nsIFrame* aFrame,
  1.3299 +                             float aAppUnitsPerPixel,
  1.3300 +                             const nsRect* aBoundsOverride);
  1.3301 +    FrameTransformProperties(nsCSSValueSharedList* aTransformList,
  1.3302 +                             const gfxPoint3D& aToTransformOrigin,
  1.3303 +                             const gfxPoint3D& aToPerspectiveOrigin,
  1.3304 +                             nscoord aChildPerspective)
  1.3305 +      : mFrame(nullptr)
  1.3306 +      , mTransformList(aTransformList)
  1.3307 +      , mToTransformOrigin(aToTransformOrigin)
  1.3308 +      , mToPerspectiveOrigin(aToPerspectiveOrigin)
  1.3309 +      , mChildPerspective(aChildPerspective)
  1.3310 +    {}
  1.3311 +
  1.3312 +    const nsIFrame* mFrame;
  1.3313 +    nsRefPtr<nsCSSValueSharedList> mTransformList;
  1.3314 +    const gfxPoint3D mToTransformOrigin;
  1.3315 +    const gfxPoint3D mToPerspectiveOrigin;
  1.3316 +    nscoord mChildPerspective;
  1.3317 +  };
  1.3318 +
  1.3319 +  /**
  1.3320 +   * Given a frame with the -moz-transform property or an SVG transform,
  1.3321 +   * returns the transformation matrix for that frame.
  1.3322 +   *
  1.3323 +   * @param aFrame The frame to get the matrix from.
  1.3324 +   * @param aOrigin Relative to which point this transform should be applied.
  1.3325 +   * @param aAppUnitsPerPixel The number of app units per graphics unit.
  1.3326 +   * @param aBoundsOverride [optional] If this is nullptr (the default), the
  1.3327 +   *        computation will use the value of GetFrameBoundsForTransform(aFrame)
  1.3328 +   *        for the frame's bounding rectangle. Otherwise, it will use the
  1.3329 +   *        value of aBoundsOverride.  This is mostly for internal use and in
  1.3330 +   *        most cases you will not need to specify a value.
  1.3331 +   */
  1.3332 +  static gfx3DMatrix GetResultingTransformMatrix(const nsIFrame* aFrame,
  1.3333 +                                                 const nsPoint& aOrigin,
  1.3334 +                                                 float aAppUnitsPerPixel,
  1.3335 +                                                 const nsRect* aBoundsOverride = nullptr,
  1.3336 +                                                 nsIFrame** aOutAncestor = nullptr);
  1.3337 +  static gfx3DMatrix GetResultingTransformMatrix(const FrameTransformProperties& aProperties,
  1.3338 +                                                 const nsPoint& aOrigin,
  1.3339 +                                                 float aAppUnitsPerPixel,
  1.3340 +                                                 const nsRect* aBoundsOverride = nullptr,
  1.3341 +                                                 nsIFrame** aOutAncestor = nullptr);
  1.3342 +  /**
  1.3343 +   * Return true when we should try to prerender the entire contents of the
  1.3344 +   * transformed frame even when it's not completely visible (yet).
  1.3345 +   */
  1.3346 +  static bool ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
  1.3347 +                                                nsIFrame* aFrame,
  1.3348 +                                                bool aLogAnimations = false);
  1.3349 +  bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
  1.3350 +
  1.3351 +  virtual bool SetVisibleRegionOnLayer() MOZ_OVERRIDE { return false; }
  1.3352 +
  1.3353 +private:
  1.3354 +  static gfx3DMatrix GetResultingTransformMatrixInternal(const FrameTransformProperties& aProperties,
  1.3355 +                                                         const nsPoint& aOrigin,
  1.3356 +                                                         float aAppUnitsPerPixel,
  1.3357 +                                                         const nsRect* aBoundsOverride,
  1.3358 +                                                         nsIFrame** aOutAncestor);
  1.3359 +
  1.3360 +  nsDisplayWrapList mStoredList;
  1.3361 +  gfx3DMatrix mTransform;
  1.3362 +  ComputeTransformFunction mTransformGetter;
  1.3363 +  uint32_t mIndex;
  1.3364 +};
  1.3365 +
  1.3366 +/**
  1.3367 + * This class adds basic support for limiting the rendering to the part inside
  1.3368 + * the specified edges.  It's a base class for the display item classes that
  1.3369 + * does the actual work.  The two members, mLeftEdge and mRightEdge, are
  1.3370 + * relative to the edges of the frame's scrollable overflow rectangle and is
  1.3371 + * the amount to suppress on each side.
  1.3372 + *
  1.3373 + * Setting none, both or only one edge is allowed.
  1.3374 + * The values must be non-negative.
  1.3375 + * The default value for both edges is zero, which means everything is painted.
  1.3376 + */
  1.3377 +class nsCharClipDisplayItem : public nsDisplayItem {
  1.3378 +public:
  1.3379 +  nsCharClipDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
  1.3380 +    : nsDisplayItem(aBuilder, aFrame), mLeftEdge(0), mRightEdge(0) {}
  1.3381 +
  1.3382 +  nsCharClipDisplayItem(nsIFrame* aFrame)
  1.3383 +    : nsDisplayItem(aFrame) {}
  1.3384 +
  1.3385 +  struct ClipEdges {
  1.3386 +    ClipEdges(const nsDisplayItem& aItem,
  1.3387 +              nscoord aLeftEdge, nscoord aRightEdge) {
  1.3388 +      nsRect r = aItem.Frame()->GetScrollableOverflowRect() +
  1.3389 +                 aItem.ToReferenceFrame();
  1.3390 +      mX = aLeftEdge > 0 ? r.x + aLeftEdge : nscoord_MIN;
  1.3391 +      mXMost = aRightEdge > 0 ? std::max(r.XMost() - aRightEdge, mX) : nscoord_MAX;
  1.3392 +    }
  1.3393 +    void Intersect(nscoord* aX, nscoord* aWidth) const {
  1.3394 +      nscoord xmost1 = *aX + *aWidth;
  1.3395 +      *aX = std::max(*aX, mX);
  1.3396 +      *aWidth = std::max(std::min(xmost1, mXMost) - *aX, 0);
  1.3397 +    }
  1.3398 +    nscoord mX;
  1.3399 +    nscoord mXMost;
  1.3400 +  };
  1.3401 +
  1.3402 +  ClipEdges Edges() const { return ClipEdges(*this, mLeftEdge, mRightEdge); }
  1.3403 +
  1.3404 +  static nsCharClipDisplayItem* CheckCast(nsDisplayItem* aItem) {
  1.3405 +    nsDisplayItem::Type t = aItem->GetType();
  1.3406 +    return (t == nsDisplayItem::TYPE_TEXT ||
  1.3407 +            t == nsDisplayItem::TYPE_TEXT_DECORATION ||
  1.3408 +            t == nsDisplayItem::TYPE_TEXT_SHADOW)
  1.3409 +      ? static_cast<nsCharClipDisplayItem*>(aItem) : nullptr;
  1.3410 +  }
  1.3411 +
  1.3412 +  nscoord mLeftEdge;  // length from the left side
  1.3413 +  nscoord mRightEdge; // length from the right side
  1.3414 +};
  1.3415 +
  1.3416 +#endif /*NSDISPLAYLIST_H_*/

mercurial