layout/base/nsCSSRendering.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/base/nsCSSRendering.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,895 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/* utility functions for drawing borders and backgrounds */
    1.10 +
    1.11 +#ifndef nsCSSRendering_h___
    1.12 +#define nsCSSRendering_h___
    1.13 +
    1.14 +#include "gfxBlur.h"
    1.15 +#include "gfxContext.h"
    1.16 +#include "nsLayoutUtils.h"
    1.17 +#include "nsStyleStruct.h"
    1.18 +#include "nsIFrame.h"
    1.19 +
    1.20 +class nsStyleContext;
    1.21 +class nsPresContext;
    1.22 +class nsRenderingContext;
    1.23 +
    1.24 +namespace mozilla {
    1.25 +
    1.26 +namespace layers {
    1.27 +class ImageContainer;
    1.28 +}
    1.29 +
    1.30 +// A CSSSizeOrRatio represents a (possibly partially specified) size for use
    1.31 +// in computing image sizes. Either or both of the width and height might be
    1.32 +// given. A ratio of width to height may also be given. If we at least two
    1.33 +// of these then we can compute a concrete size, that is a width and height.
    1.34 +struct CSSSizeOrRatio
    1.35 +{
    1.36 +  CSSSizeOrRatio()
    1.37 +    : mRatio(0, 0)
    1.38 +    , mHasWidth(false)
    1.39 +    , mHasHeight(false) {}
    1.40 +
    1.41 +  bool CanComputeConcreteSize() const
    1.42 +  {
    1.43 +    return mHasWidth + mHasHeight + HasRatio() >= 2;
    1.44 +  }
    1.45 +  bool IsConcrete() const { return mHasWidth && mHasHeight; }
    1.46 +  bool HasRatio() const { return mRatio.width > 0 && mRatio.height > 0; }
    1.47 +  bool IsEmpty() const
    1.48 +  {
    1.49 +    return (mHasWidth && mWidth <= 0) ||
    1.50 +           (mHasHeight && mHeight <= 0) ||
    1.51 +           mRatio.width <= 0 || mRatio.height <= 0; 
    1.52 +  }
    1.53 +
    1.54 +  // CanComputeConcreteSize must return true when ComputeConcreteSize is
    1.55 +  // called.
    1.56 +  nsSize ComputeConcreteSize() const;
    1.57 +
    1.58 +  void SetWidth(nscoord aWidth)
    1.59 +  {
    1.60 +    mWidth = aWidth;
    1.61 +    mHasWidth = true;
    1.62 +    if (mHasHeight) {
    1.63 +      mRatio = nsSize(mWidth, mHeight);
    1.64 +    }
    1.65 +  }
    1.66 +  void SetHeight(nscoord aHeight)
    1.67 +  {
    1.68 +    mHeight = aHeight;
    1.69 +    mHasHeight = true;
    1.70 +    if (mHasWidth) {
    1.71 +      mRatio = nsSize(mWidth, mHeight);
    1.72 +    }
    1.73 +  }
    1.74 +  void SetSize(const nsSize& aSize)
    1.75 +  {
    1.76 +    mWidth = aSize.width;
    1.77 +    mHeight = aSize.height;
    1.78 +    mHasWidth = true;
    1.79 +    mHasHeight = true;
    1.80 +    mRatio = aSize;    
    1.81 +  }
    1.82 +  void SetRatio(const nsSize& aRatio)
    1.83 +  {
    1.84 +    MOZ_ASSERT(!mHasWidth || !mHasHeight,
    1.85 +               "Probably shouldn't be setting a ratio if we have a concrete size");
    1.86 +    mRatio = aRatio;
    1.87 +  }
    1.88 +
    1.89 +  nsSize mRatio;
    1.90 +  nscoord mWidth;
    1.91 +  nscoord mHeight;
    1.92 +  bool mHasWidth;
    1.93 +  bool mHasHeight;
    1.94 +};
    1.95 +
    1.96 +}
    1.97 +
    1.98 +/**
    1.99 + * This is a small wrapper class to encapsulate image drawing that can draw an
   1.100 + * nsStyleImage image, which may internally be a real image, a sub image, or a
   1.101 + * CSS gradient.
   1.102 + *
   1.103 + * @note Always call the member functions in the order of PrepareImage(),
   1.104 + * SetSize(), and Draw*().
   1.105 + */
   1.106 +class nsImageRenderer {
   1.107 +public:
   1.108 +  typedef mozilla::layers::LayerManager LayerManager;
   1.109 +  typedef mozilla::layers::ImageContainer ImageContainer;
   1.110 +
   1.111 +  enum {
   1.112 +    FLAG_SYNC_DECODE_IMAGES = 0x01,
   1.113 +    FLAG_PAINTING_TO_WINDOW = 0x02
   1.114 +  };
   1.115 +  enum FitType
   1.116 +  {
   1.117 +    CONTAIN,
   1.118 +    COVER
   1.119 +  };
   1.120 +
   1.121 +  nsImageRenderer(nsIFrame* aForFrame, const nsStyleImage* aImage, uint32_t aFlags);
   1.122 +  ~nsImageRenderer();
   1.123 +  /**
   1.124 +   * Populates member variables to get ready for rendering.
   1.125 +   * @return true iff the image is ready, and there is at least a pixel to
   1.126 +   * draw.
   1.127 +   */
   1.128 +  bool PrepareImage();
   1.129 +
   1.130 +  /**
   1.131 +   * The three Compute*Size functions correspond to the sizing algorthms and
   1.132 +   * definitions from the CSS Image Values and Replaced Content spec. See
   1.133 +   * http://dev.w3.org/csswg/css-images-3/#sizing .
   1.134 +   */
   1.135 +   
   1.136 +  /**
   1.137 +   * Compute the intrinsic size of the image as defined in the CSS Image Values
   1.138 +   * spec. The intrinsic size is the unscaled size which the image would ideally
   1.139 +   * like to be in app units.
   1.140 +   */
   1.141 +  mozilla::CSSSizeOrRatio ComputeIntrinsicSize();
   1.142 +
   1.143 +  /**
   1.144 +   * Compute the size of the rendered image using either the 'cover' or
   1.145 +   * 'contain' constraints (aFitType).
   1.146 +   * aIntrinsicRatio may be an invalid ratio, that is one or both of its
   1.147 +   * dimensions can be less than or equal to zero.
   1.148 +   */
   1.149 +  static nsSize ComputeConstrainedSize(const nsSize& aConstrainingSize,
   1.150 +                                       const nsSize& aIntrinsicRatio,
   1.151 +                                       FitType aFitType);
   1.152 +  /**
   1.153 +   * Compute the size of the rendered image (the concrete size) where no cover/
   1.154 +   * contain constraints are given. The 'default algorithm' from the CSS Image
   1.155 +   * Values spec.
   1.156 +   */
   1.157 +  static nsSize ComputeConcreteSize(const mozilla::CSSSizeOrRatio& aSpecifiedSize,
   1.158 +                                    const mozilla::CSSSizeOrRatio& aIntrinsicSize,
   1.159 +                                    const nsSize& aDefaultSize);
   1.160 +
   1.161 +  /**
   1.162 +   * Set this image's preferred size. This will be its intrinsic size where
   1.163 +   * specified and the default size where it is not. Used as the unscaled size
   1.164 +   * when rendering the image.
   1.165 +   */
   1.166 +  void SetPreferredSize(const mozilla::CSSSizeOrRatio& aIntrinsicSize,
   1.167 +                        const nsSize& aDefaultSize);
   1.168 +
   1.169 +  /**
   1.170 +   * Draws the image to the target rendering context.
   1.171 +   * aSrc is a rect on the source image which will be mapped to aDest.
   1.172 +   * @see nsLayoutUtils::DrawImage() for other parameters.
   1.173 +   */
   1.174 +  void Draw(nsPresContext*       aPresContext,
   1.175 +            nsRenderingContext&  aRenderingContext,
   1.176 +            const nsRect&        aDirtyRect,
   1.177 +            const nsRect&        aFill,
   1.178 +            const nsRect&        aDest,
   1.179 +            const mozilla::CSSIntRect& aSrc);
   1.180 +  /**
   1.181 +   * Draws the image to the target rendering context using background-specific
   1.182 +   * arguments.
   1.183 +   * @see nsLayoutUtils::DrawImage() for parameters.
   1.184 +   */
   1.185 +  void DrawBackground(nsPresContext*       aPresContext,
   1.186 +                      nsRenderingContext&  aRenderingContext,
   1.187 +                      const nsRect&        aDest,
   1.188 +                      const nsRect&        aFill,
   1.189 +                      const nsPoint&       aAnchor,
   1.190 +                      const nsRect&        aDirty);
   1.191 +
   1.192 +  /**
   1.193 +   * Draw the image to a single component of a border-image style rendering.
   1.194 +   * aFill The destination rect to be drawn into
   1.195 +   * aSrc is the part of the image to be rendered into a tile (aUnitSize in
   1.196 +   * aFill), if aSrc and the dest tile are different sizes, the image will be
   1.197 +   * scaled to map aSrc onto the dest tile.
   1.198 +   * aHFill and aVFill are the repeat patterns for the component -
   1.199 +   * NS_STYLE_BORDER_IMAGE_REPEAT_*
   1.200 +   * aUnitSize The scaled size of a single source rect (in destination coords)
   1.201 +   * aIndex identifies the component: 0 1 2
   1.202 +   *                                  3 4 5
   1.203 +   *                                  6 7 8
   1.204 +   */
   1.205 +  void
   1.206 +  DrawBorderImageComponent(nsPresContext*       aPresContext,
   1.207 +                           nsRenderingContext&  aRenderingContext,
   1.208 +                           const nsRect&        aDirtyRect,
   1.209 +                           const nsRect&        aFill,
   1.210 +                           const mozilla::CSSIntRect& aSrc,
   1.211 +                           uint8_t              aHFill,
   1.212 +                           uint8_t              aVFill,
   1.213 +                           const nsSize&        aUnitSize,
   1.214 +                           uint8_t              aIndex);
   1.215 +
   1.216 +  bool IsRasterImage();
   1.217 +  bool IsAnimatedImage();
   1.218 +  already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager);
   1.219 +
   1.220 +  bool IsReady() { return mIsReady; }
   1.221 +
   1.222 +private:
   1.223 +  /**
   1.224 +   * Helper method for creating a gfxDrawable from mPaintServerFrame or 
   1.225 +   * mImageElementSurface.
   1.226 +   * Requires mType is eStyleImageType_Element.
   1.227 +   * Returns null if we cannot create the drawable.
   1.228 +   */
   1.229 +  already_AddRefed<gfxDrawable> DrawableForElement(const nsRect& aImageRect,
   1.230 +                                                   nsRenderingContext&  aRenderingContext);
   1.231 +
   1.232 +  nsIFrame*                 mForFrame;
   1.233 +  const nsStyleImage*       mImage;
   1.234 +  nsStyleImageType          mType;
   1.235 +  nsCOMPtr<imgIContainer>   mImageContainer;
   1.236 +  nsRefPtr<nsStyleGradient> mGradientData;
   1.237 +  nsIFrame*                 mPaintServerFrame;
   1.238 +  nsLayoutUtils::SurfaceFromElementResult mImageElementSurface;
   1.239 +  bool                      mIsReady;
   1.240 +  nsSize                    mSize; // unscaled size of the image, in app units
   1.241 +  uint32_t                  mFlags;
   1.242 +};
   1.243 +
   1.244 +/**
   1.245 + * A struct representing all the information needed to paint a background
   1.246 + * image to some target, taking into account all CSS background-* properties.
   1.247 + * See PrepareBackgroundLayer.
   1.248 + */
   1.249 +struct nsBackgroundLayerState {
   1.250 +  /**
   1.251 +   * @param aFlags some combination of nsCSSRendering::PAINTBG_* flags
   1.252 +   */
   1.253 +  nsBackgroundLayerState(nsIFrame* aForFrame, const nsStyleImage* aImage, uint32_t aFlags)
   1.254 +    : mImageRenderer(aForFrame, aImage, aFlags), mCompositingOp(gfxContext::OPERATOR_OVER) {}
   1.255 +
   1.256 +  /**
   1.257 +   * The nsImageRenderer that will be used to draw the background.
   1.258 +   */
   1.259 +  nsImageRenderer mImageRenderer;
   1.260 +  /**
   1.261 +   * A rectangle that one copy of the image tile is mapped onto. Same
   1.262 +   * coordinate system as aBorderArea/aBGClipRect passed into
   1.263 +   * PrepareBackgroundLayer.
   1.264 +   */
   1.265 +  nsRect mDestArea;
   1.266 +  /**
   1.267 +   * The actual rectangle that should be filled with (complete or partial)
   1.268 +   * image tiles. Same coordinate system as aBorderArea/aBGClipRect passed into
   1.269 +   * PrepareBackgroundLayer.
   1.270 +   */
   1.271 +  nsRect mFillArea;
   1.272 +  /**
   1.273 +   * The anchor point that should be snapped to a pixel corner. Same
   1.274 +   * coordinate system as aBorderArea/aBGClipRect passed into
   1.275 +   * PrepareBackgroundLayer.
   1.276 +   */
   1.277 +  nsPoint mAnchor;
   1.278 +  /**
   1.279 +   * The compositing operation that the image should use
   1.280 +   */
   1.281 +  gfxContext::GraphicsOperator mCompositingOp;
   1.282 +};
   1.283 +
   1.284 +struct nsCSSRendering {
   1.285 +  /**
   1.286 +   * Initialize any static variables used by nsCSSRendering.
   1.287 +   */
   1.288 +  static void Init();
   1.289 +  
   1.290 +  /**
   1.291 +   * Clean up any static variables used by nsCSSRendering.
   1.292 +   */
   1.293 +  static void Shutdown();
   1.294 +  
   1.295 +  static void PaintBoxShadowInner(nsPresContext* aPresContext,
   1.296 +                                  nsRenderingContext& aRenderingContext,
   1.297 +                                  nsIFrame* aForFrame,
   1.298 +                                  const nsRect& aFrameArea,
   1.299 +                                  const nsRect& aDirtyRect);
   1.300 +
   1.301 +  static void PaintBoxShadowOuter(nsPresContext* aPresContext,
   1.302 +                                  nsRenderingContext& aRenderingContext,
   1.303 +                                  nsIFrame* aForFrame,
   1.304 +                                  const nsRect& aFrameArea,
   1.305 +                                  const nsRect& aDirtyRect,
   1.306 +                                  float aOpacity = 1.0);
   1.307 +
   1.308 +  static void ComputePixelRadii(const nscoord *aAppUnitsRadii,
   1.309 +                                nscoord aAppUnitsPerPixel,
   1.310 +                                gfxCornerSizes *oBorderRadii);
   1.311 +
   1.312 +  /**
   1.313 +   * Render the border for an element using css rendering rules
   1.314 +   * for borders. aSkipSides is a bitmask of the sides to skip
   1.315 +   * when rendering. If 0 then no sides are skipped.
   1.316 +   */
   1.317 +  static void PaintBorder(nsPresContext* aPresContext,
   1.318 +                          nsRenderingContext& aRenderingContext,
   1.319 +                          nsIFrame* aForFrame,
   1.320 +                          const nsRect& aDirtyRect,
   1.321 +                          const nsRect& aBorderArea,
   1.322 +                          nsStyleContext* aStyleContext,
   1.323 +                          int aSkipSides = 0);
   1.324 +
   1.325 +  /**
   1.326 +   * Like PaintBorder, but taking an nsStyleBorder argument instead of
   1.327 +   * getting it from aStyleContext.
   1.328 +   */
   1.329 +  static void PaintBorderWithStyleBorder(nsPresContext* aPresContext,
   1.330 +                                         nsRenderingContext& aRenderingContext,
   1.331 +                                         nsIFrame* aForFrame,
   1.332 +                                         const nsRect& aDirtyRect,
   1.333 +                                         const nsRect& aBorderArea,
   1.334 +                                         const nsStyleBorder& aBorderStyle,
   1.335 +                                         nsStyleContext* aStyleContext,
   1.336 +                                         int aSkipSides = 0);
   1.337 +
   1.338 +
   1.339 +  /**
   1.340 +   * Render the outline for an element using css rendering rules
   1.341 +   * for borders. aSkipSides is a bitmask of the sides to skip
   1.342 +   * when rendering. If 0 then no sides are skipped.
   1.343 +   */
   1.344 +  static void PaintOutline(nsPresContext* aPresContext,
   1.345 +                          nsRenderingContext& aRenderingContext,
   1.346 +                          nsIFrame* aForFrame,
   1.347 +                          const nsRect& aDirtyRect,
   1.348 +                          const nsRect& aBorderArea,
   1.349 +                          nsStyleContext* aStyleContext);
   1.350 +
   1.351 +  /**
   1.352 +   * Render keyboard focus on an element.
   1.353 +   * |aFocusRect| is the outer rectangle of the focused element.
   1.354 +   * Uses a fixed style equivalent to "1px dotted |aColor|".
   1.355 +   * Not used for controls, because the native theme may differ.
   1.356 +   */
   1.357 +  static void PaintFocus(nsPresContext* aPresContext,
   1.358 +                         nsRenderingContext& aRenderingContext,
   1.359 +                         const nsRect& aFocusRect,
   1.360 +                         nscolor aColor);
   1.361 +
   1.362 +  /**
   1.363 +   * Render a gradient for an element.
   1.364 +   * aDest is the rect for a single tile of the gradient on the destination.
   1.365 +   * aFill is the rect on the destination to be covered by repeated tiling of
   1.366 +   * the gradient.
   1.367 +   * aSrc is the part of the gradient to be rendered into a tile (aDest), if
   1.368 +   * aSrc and aDest are different sizes, the image will be scaled to map aSrc
   1.369 +   * onto aDest.
   1.370 +   * aIntrinsicSize is the size of the source gradient.
   1.371 +   */
   1.372 +  static void PaintGradient(nsPresContext* aPresContext,
   1.373 +                            nsRenderingContext& aRenderingContext,
   1.374 +                            nsStyleGradient* aGradient,
   1.375 +                            const nsRect& aDirtyRect,
   1.376 +                            const nsRect& aDest,
   1.377 +                            const nsRect& aFill,
   1.378 +                            const mozilla::CSSIntRect& aSrc,
   1.379 +                            const nsSize& aIntrinsiceSize);
   1.380 +
   1.381 +  /**
   1.382 +   * Find the frame whose background style should be used to draw the
   1.383 +   * canvas background. aForFrame must be the frame for the root element
   1.384 +   * whose background style should be used. This function will return
   1.385 +   * aForFrame unless the <body> background should be propagated, in
   1.386 +   * which case we return the frame associated with the <body>'s background.
   1.387 +   */
   1.388 +  static nsIFrame* FindBackgroundStyleFrame(nsIFrame* aForFrame);
   1.389 +
   1.390 +  /**
   1.391 +   * @return true if |aFrame| is a canvas frame, in the CSS sense.
   1.392 +   */
   1.393 +  static bool IsCanvasFrame(nsIFrame* aFrame);
   1.394 +
   1.395 +  /**
   1.396 +   * Fill in an aBackgroundSC to be used to paint the background
   1.397 +   * for an element.  This applies the rules for propagating
   1.398 +   * backgrounds between BODY, the root element, and the canvas.
   1.399 +   * @return true if there is some meaningful background.
   1.400 +   */
   1.401 +  static bool FindBackground(nsIFrame* aForFrame,
   1.402 +                             nsStyleContext** aBackgroundSC);
   1.403 +
   1.404 +  /**
   1.405 +   * As FindBackground, but the passed-in frame is known to be a root frame
   1.406 +   * (returned from nsCSSFrameConstructor::GetRootElementStyleFrame())
   1.407 +   * and there is always some meaningful background returned.
   1.408 +   */
   1.409 +  static nsStyleContext* FindRootFrameBackground(nsIFrame* aForFrame);
   1.410 +
   1.411 +  /**
   1.412 +   * Returns background style information for the canvas.
   1.413 +   *
   1.414 +   * @param aForFrame
   1.415 +   *   the frame used to represent the canvas, in the CSS sense (i.e.
   1.416 +   *   nsCSSRendering::IsCanvasFrame(aForFrame) must be true)
   1.417 +   * @param aRootElementFrame
   1.418 +   *   the frame representing the root element of the document
   1.419 +   * @param aBackground
   1.420 +   *   contains background style information for the canvas on return
   1.421 +   */
   1.422 +  static nsStyleContext*
   1.423 +  FindCanvasBackground(nsIFrame* aForFrame, nsIFrame* aRootElementFrame)
   1.424 +  {
   1.425 +    NS_ABORT_IF_FALSE(IsCanvasFrame(aForFrame), "not a canvas frame");
   1.426 +    if (aRootElementFrame)
   1.427 +      return FindRootFrameBackground(aRootElementFrame);
   1.428 +
   1.429 +    // This should always give transparent, so we'll fill it in with the
   1.430 +    // default color if needed.  This seems to happen a bit while a page is
   1.431 +    // being loaded.
   1.432 +    return aForFrame->StyleContext();
   1.433 +  }
   1.434 +
   1.435 +  /**
   1.436 +   * Find a frame which draws a non-transparent background,
   1.437 +   * for various table-related and HR-related backwards-compatibility hacks.
   1.438 +   * This function will also stop if it finds themed frame which might draw
   1.439 +   * background.
   1.440 +   *
   1.441 +   * Be very hesitant if you're considering calling this function -- it's
   1.442 +   * usually not what you want.
   1.443 +   */
   1.444 +  static nsIFrame*
   1.445 +  FindNonTransparentBackgroundFrame(nsIFrame* aFrame,
   1.446 +                                    bool aStartAtParent = false);
   1.447 +
   1.448 +  /**
   1.449 +   * Determine the background color to draw taking into account print settings.
   1.450 +   */
   1.451 +  static nscolor
   1.452 +  DetermineBackgroundColor(nsPresContext* aPresContext,
   1.453 +                           nsStyleContext* aStyleContext,
   1.454 +                           nsIFrame* aFrame,
   1.455 +                           bool& aDrawBackgroundImage,
   1.456 +                           bool& aDrawBackgroundColor);
   1.457 +
   1.458 +  static nsRect
   1.459 +  ComputeBackgroundPositioningArea(nsPresContext* aPresContext,
   1.460 +                                   nsIFrame* aForFrame,
   1.461 +                                   const nsRect& aBorderArea,
   1.462 +                                   const nsStyleBackground& aBackground,
   1.463 +                                   const nsStyleBackground::Layer& aLayer,
   1.464 +                                   nsIFrame** aAttachedToFrame);
   1.465 +
   1.466 +  static nsBackgroundLayerState
   1.467 +  PrepareBackgroundLayer(nsPresContext* aPresContext,
   1.468 +                         nsIFrame* aForFrame,
   1.469 +                         uint32_t aFlags,
   1.470 +                         const nsRect& aBorderArea,
   1.471 +                         const nsRect& aBGClipRect,
   1.472 +                         const nsStyleBackground& aBackground,
   1.473 +                         const nsStyleBackground::Layer& aLayer);
   1.474 +
   1.475 +  /**
   1.476 +   * Render the background for an element using css rendering rules
   1.477 +   * for backgrounds.
   1.478 +   */
   1.479 +  enum {
   1.480 +    /**
   1.481 +     * When this flag is passed, the element's nsDisplayBorder will be
   1.482 +     * painted immediately on top of this background.
   1.483 +     */
   1.484 +    PAINTBG_WILL_PAINT_BORDER = 0x01,
   1.485 +    /**
   1.486 +     * When this flag is passed, images are synchronously decoded.
   1.487 +     */
   1.488 +    PAINTBG_SYNC_DECODE_IMAGES = 0x02,
   1.489 +    /**
   1.490 +     * When this flag is passed, painting will go to the screen so we can
   1.491 +     * take advantage of the fact that it will be clipped to the viewport.
   1.492 +     */
   1.493 +    PAINTBG_TO_WINDOW = 0x04
   1.494 +  };
   1.495 +  static void PaintBackground(nsPresContext* aPresContext,
   1.496 +                              nsRenderingContext& aRenderingContext,
   1.497 +                              nsIFrame* aForFrame,
   1.498 +                              const nsRect& aDirtyRect,
   1.499 +                              const nsRect& aBorderArea,
   1.500 +                              uint32_t aFlags,
   1.501 +                              nsRect* aBGClipRect = nullptr,
   1.502 +                              int32_t aLayer = -1);
   1.503 + 
   1.504 +  static void PaintBackgroundColor(nsPresContext* aPresContext,
   1.505 +                                   nsRenderingContext& aRenderingContext,
   1.506 +                                   nsIFrame* aForFrame,
   1.507 +                                   const nsRect& aDirtyRect,
   1.508 +                                   const nsRect& aBorderArea,
   1.509 +                                   uint32_t aFlags);
   1.510 +
   1.511 +  /**
   1.512 +   * Same as |PaintBackground|, except using the provided style structs.
   1.513 +   * This short-circuits the code that ensures that the root element's
   1.514 +   * background is drawn on the canvas.
   1.515 +   * The aLayer parameter allows you to paint a single layer of the background.
   1.516 +   * The default value for aLayer, -1, means that all layers will be painted.
   1.517 +   * The background color will only be painted if the back-most layer is also
   1.518 +   * being painted.
   1.519 +   */
   1.520 +  static void PaintBackgroundWithSC(nsPresContext* aPresContext,
   1.521 +                                    nsRenderingContext& aRenderingContext,
   1.522 +                                    nsIFrame* aForFrame,
   1.523 +                                    const nsRect& aDirtyRect,
   1.524 +                                    const nsRect& aBorderArea,
   1.525 +                                    nsStyleContext *aStyleContext,
   1.526 +                                    const nsStyleBorder& aBorder,
   1.527 +                                    uint32_t aFlags,
   1.528 +                                    nsRect* aBGClipRect = nullptr,
   1.529 +                                    int32_t aLayer = -1);
   1.530 +
   1.531 +  static void PaintBackgroundColorWithSC(nsPresContext* aPresContext,
   1.532 +                                         nsRenderingContext& aRenderingContext,
   1.533 +                                         nsIFrame* aForFrame,
   1.534 +                                         const nsRect& aDirtyRect,
   1.535 +                                         const nsRect& aBorderArea,
   1.536 +                                         nsStyleContext *aStyleContext,
   1.537 +                                         const nsStyleBorder& aBorder,
   1.538 +                                         uint32_t aFlags);
   1.539 +  /**
   1.540 +   * Returns the rectangle covered by the given background layer image, taking
   1.541 +   * into account background positioning, sizing, and repetition, but not
   1.542 +   * clipping.
   1.543 +   */
   1.544 +  static nsRect GetBackgroundLayerRect(nsPresContext* aPresContext,
   1.545 +                                       nsIFrame* aForFrame,
   1.546 +                                       const nsRect& aBorderArea,
   1.547 +                                       const nsRect& aClipRect,
   1.548 +                                       const nsStyleBackground& aBackground,
   1.549 +                                       const nsStyleBackground::Layer& aLayer,
   1.550 +                                       uint32_t aFlags);
   1.551 +
   1.552 +  /**
   1.553 +   * Checks if image in layer aLayer of aBackground is currently decoded.
   1.554 +   */
   1.555 +  static bool IsBackgroundImageDecodedForStyleContextAndLayer(
   1.556 +    const nsStyleBackground *aBackground, uint32_t aLayer);
   1.557 +
   1.558 +  /**
   1.559 +   * Checks if all images that are part of the background for aFrame are
   1.560 +   * currently decoded.
   1.561 +   */
   1.562 +  static bool AreAllBackgroundImagesDecodedForFrame(nsIFrame* aFrame);
   1.563 +
   1.564 +  /**
   1.565 +   * Called when we start creating a display list. The frame tree will not
   1.566 +   * change until a matching EndFrameTreeLocked is called.
   1.567 +   */
   1.568 +  static void BeginFrameTreesLocked();
   1.569 +  /**
   1.570 +   * Called when we've finished using a display list. When all
   1.571 +   * BeginFrameTreeLocked calls have been balanced by an EndFrameTreeLocked,
   1.572 +   * the frame tree may start changing again.
   1.573 +   */
   1.574 +  static void EndFrameTreesLocked();
   1.575 +
   1.576 +  // Draw a border segment in the table collapsing border model without
   1.577 +  // beveling corners
   1.578 +  static void DrawTableBorderSegment(nsRenderingContext& aContext,
   1.579 +                                     uint8_t              aBorderStyle,  
   1.580 +                                     nscolor              aBorderColor,
   1.581 +                                     const nsStyleBackground* aBGColor,
   1.582 +                                     const nsRect&        aBorderRect,
   1.583 +                                     int32_t              aAppUnitsPerCSSPixel,
   1.584 +                                     uint8_t              aStartBevelSide = 0,
   1.585 +                                     nscoord              aStartBevelOffset = 0,
   1.586 +                                     uint8_t              aEndBevelSide = 0,
   1.587 +                                     nscoord              aEndBevelOffset = 0);
   1.588 +
   1.589 +  /**
   1.590 +   * Function for painting the decoration lines for the text.
   1.591 +   * NOTE: aPt, aLineSize, aAscent and aOffset are non-rounded device pixels,
   1.592 +   *       not app units.
   1.593 +   *   input:
   1.594 +   *     @param aFrame            the frame which needs the decoration line
   1.595 +   *     @param aGfxContext
   1.596 +   *     @param aDirtyRect        no need to paint outside this rect
   1.597 +   *     @param aColor            the color of the decoration line
   1.598 +   *     @param aPt               the top/left edge of the text
   1.599 +   *     @param aXInFrame         the distance between aPt.x and left edge of
   1.600 +   *                              aFrame.  If the decoration line is for shadow,
   1.601 +   *                              set the distance between the left edge of
   1.602 +   *                              the aFrame and the position of the text as
   1.603 +   *                              positioned without offset of the shadow.
   1.604 +   *     @param aLineSize         the width and the height of the decoration
   1.605 +   *                              line
   1.606 +   *     @param aAscent           the ascent of the text
   1.607 +   *     @param aOffset           the offset of the decoration line from
   1.608 +   *                              the baseline of the text (if the value is
   1.609 +   *                              positive, the line is lifted up)
   1.610 +   *     @param aDecoration       which line will be painted. The value can be
   1.611 +   *                              NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE or
   1.612 +   *                              NS_STYLE_TEXT_DECORATION_LINE_OVERLINE or
   1.613 +   *                              NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH.
   1.614 +   *     @param aStyle            the style of the decoration line such as
   1.615 +   *                              NS_STYLE_TEXT_DECORATION_STYLE_*.
   1.616 +   *     @param aDescentLimit     If aDescentLimit is zero or larger and the
   1.617 +   *                              underline overflows from the descent space,
   1.618 +   *                              the underline should be lifted up as far as
   1.619 +   *                              possible.  Note that this does not mean the
   1.620 +   *                              underline never overflows from this
   1.621 +   *                              limitation.  Because if the underline is
   1.622 +   *                              positioned to the baseline or upper, it causes
   1.623 +   *                              unreadability.  Note that if this is zero
   1.624 +   *                              or larger, the underline rect may be shrunken
   1.625 +   *                              if it's possible.  Therefore, this value is
   1.626 +   *                              used for strikeout line and overline too.
   1.627 +   */
   1.628 +  static void PaintDecorationLine(nsIFrame* aFrame,
   1.629 +                                  gfxContext* aGfxContext,
   1.630 +                                  const gfxRect& aDirtyRect,
   1.631 +                                  const nscolor aColor,
   1.632 +                                  const gfxPoint& aPt,
   1.633 +                                  const gfxFloat aXInFrame,
   1.634 +                                  const gfxSize& aLineSize,
   1.635 +                                  const gfxFloat aAscent,
   1.636 +                                  const gfxFloat aOffset,
   1.637 +                                  const uint8_t aDecoration,
   1.638 +                                  const uint8_t aStyle,
   1.639 +                                  const gfxFloat aDescentLimit = -1.0);
   1.640 +
   1.641 +  /**
   1.642 +   * Adds a path corresponding to the outline of the decoration line to
   1.643 +   * the specified context.  Arguments have the same meaning as for
   1.644 +   * PaintDecorationLine.  Currently this only works for solid
   1.645 +   * decorations; for other decoration styles, an empty path is added
   1.646 +   * to the context.
   1.647 +   */
   1.648 +  static void DecorationLineToPath(nsIFrame* aFrame,
   1.649 +                                   gfxContext* aGfxContext,
   1.650 +                                   const gfxRect& aDirtyRect,
   1.651 +                                   const nscolor aColor,
   1.652 +                                   const gfxPoint& aPt,
   1.653 +                                   const gfxFloat aXInFrame,
   1.654 +                                   const gfxSize& aLineSize,
   1.655 +                                   const gfxFloat aAscent,
   1.656 +                                   const gfxFloat aOffset,
   1.657 +                                   const uint8_t aDecoration,
   1.658 +                                   const uint8_t aStyle,
   1.659 +                                   const gfxFloat aDescentLimit = -1.0);
   1.660 +
   1.661 +  /**
   1.662 +   * Function for getting the decoration line rect for the text.
   1.663 +   * NOTE: aLineSize, aAscent and aOffset are non-rounded device pixels,
   1.664 +   *       not app units.
   1.665 +   *   input:
   1.666 +   *     @param aPresContext
   1.667 +   *     @param aLineSize         the width and the height of the decoration
   1.668 +   *                              line
   1.669 +   *     @param aAscent           the ascent of the text
   1.670 +   *     @param aOffset           the offset of the decoration line from
   1.671 +   *                              the baseline of the text (if the value is
   1.672 +   *                              positive, the line is lifted up)
   1.673 +   *     @param aDecoration       which line will be painted. The value can be
   1.674 +   *                              NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE or
   1.675 +   *                              NS_STYLE_TEXT_DECORATION_LINE_OVERLINE or
   1.676 +   *                              NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH.
   1.677 +   *     @param aStyle            the style of the decoration line such as
   1.678 +   *                              NS_STYLE_TEXT_DECORATION_STYLE_*.
   1.679 +   *     @param aDescentLimit     If aDescentLimit is zero or larger and the
   1.680 +   *                              underline overflows from the descent space,
   1.681 +   *                              the underline should be lifted up as far as
   1.682 +   *                              possible.  Note that this does not mean the
   1.683 +   *                              underline never overflows from this
   1.684 +   *                              limitation.  Because if the underline is
   1.685 +   *                              positioned to the baseline or upper, it causes
   1.686 +   *                              unreadability.  Note that if this is zero
   1.687 +   *                              or larger, the underline rect may be shrunken
   1.688 +   *                              if it's possible.  Therefore, this value is
   1.689 +   *                              used for strikeout line and overline too.
   1.690 +   *   output:
   1.691 +   *     @return                  the decoration line rect for the input,
   1.692 +   *                              the each values are app units.
   1.693 +   */
   1.694 +  static nsRect GetTextDecorationRect(nsPresContext* aPresContext,
   1.695 +                                      const gfxSize& aLineSize,
   1.696 +                                      const gfxFloat aAscent,
   1.697 +                                      const gfxFloat aOffset,
   1.698 +                                      const uint8_t aDecoration,
   1.699 +                                      const uint8_t aStyle,
   1.700 +                                      const gfxFloat aDescentLimit = -1.0);
   1.701 +
   1.702 +  static gfxContext::GraphicsOperator GetGFXBlendMode(uint8_t mBlendMode) {
   1.703 +    switch (mBlendMode) {
   1.704 +      case NS_STYLE_BLEND_NORMAL:      return gfxContext::OPERATOR_OVER;
   1.705 +      case NS_STYLE_BLEND_MULTIPLY:    return gfxContext::OPERATOR_MULTIPLY;
   1.706 +      case NS_STYLE_BLEND_SCREEN:      return gfxContext::OPERATOR_SCREEN;
   1.707 +      case NS_STYLE_BLEND_OVERLAY:     return gfxContext::OPERATOR_OVERLAY;
   1.708 +      case NS_STYLE_BLEND_DARKEN:      return gfxContext::OPERATOR_DARKEN;
   1.709 +      case NS_STYLE_BLEND_LIGHTEN:     return gfxContext::OPERATOR_LIGHTEN;
   1.710 +      case NS_STYLE_BLEND_COLOR_DODGE: return gfxContext::OPERATOR_COLOR_DODGE;
   1.711 +      case NS_STYLE_BLEND_COLOR_BURN:  return gfxContext::OPERATOR_COLOR_BURN;
   1.712 +      case NS_STYLE_BLEND_HARD_LIGHT:  return gfxContext::OPERATOR_HARD_LIGHT;
   1.713 +      case NS_STYLE_BLEND_SOFT_LIGHT:  return gfxContext::OPERATOR_SOFT_LIGHT;
   1.714 +      case NS_STYLE_BLEND_DIFFERENCE:  return gfxContext::OPERATOR_DIFFERENCE;
   1.715 +      case NS_STYLE_BLEND_EXCLUSION:   return gfxContext::OPERATOR_EXCLUSION;
   1.716 +      case NS_STYLE_BLEND_HUE:         return gfxContext::OPERATOR_HUE;
   1.717 +      case NS_STYLE_BLEND_SATURATION:  return gfxContext::OPERATOR_SATURATION;
   1.718 +      case NS_STYLE_BLEND_COLOR:       return gfxContext::OPERATOR_COLOR;
   1.719 +      case NS_STYLE_BLEND_LUMINOSITY:  return gfxContext::OPERATOR_LUMINOSITY;
   1.720 +      default:                         MOZ_ASSERT(false); return gfxContext::OPERATOR_OVER;
   1.721 +    }
   1.722 +
   1.723 +    return gfxContext::OPERATOR_OVER;
   1.724 +  }
   1.725 +
   1.726 +protected:
   1.727 +  static gfxRect GetTextDecorationRectInternal(const gfxPoint& aPt,
   1.728 +                                               const gfxSize& aLineSize,
   1.729 +                                               const gfxFloat aAscent,
   1.730 +                                               const gfxFloat aOffset,
   1.731 +                                               const uint8_t aDecoration,
   1.732 +                                               const uint8_t aStyle,
   1.733 +                                               const gfxFloat aDscentLimit);
   1.734 +
   1.735 +  /**
   1.736 +   * Returns inflated rect for painting a decoration line.
   1.737 +   * Complex style decoration lines should be painted from leftmost of nearest
   1.738 +   * ancestor block box because that makes better look of connection of lines
   1.739 +   * for different nodes.  ExpandPaintingRectForDecorationLine() returns
   1.740 +   * a rect for actual painting rect for the clipped rect.
   1.741 +   *
   1.742 +   * input:
   1.743 +   *     @param aFrame            the frame which needs the decoration line.
   1.744 +   *     @param aStyle            the style of the complex decoration line
   1.745 +   *                              NS_STYLE_TEXT_DECORATION_STYLE_DOTTED or
   1.746 +   *                              NS_STYLE_TEXT_DECORATION_STYLE_DASHED or
   1.747 +   *                              NS_STYLE_TEXT_DECORATION_STYLE_WAVY.
   1.748 +   *     @param aClippedRect      the clipped rect for the decoration line.
   1.749 +   *                              in other words, visible area of the line.
   1.750 +   *     @param aXInFrame         the distance between left edge of aFrame and
   1.751 +   *                              aClippedRect.pos.x.
   1.752 +   *     @param aCycleLength      the width of one cycle of the line style.
   1.753 +   */
   1.754 +  static gfxRect ExpandPaintingRectForDecorationLine(
   1.755 +                   nsIFrame* aFrame,
   1.756 +                   const uint8_t aStyle,
   1.757 +                   const gfxRect &aClippedRect,
   1.758 +                   const gfxFloat aXInFrame,
   1.759 +                   const gfxFloat aCycleLength);
   1.760 +};
   1.761 +
   1.762 +/*
   1.763 + * nsContextBoxBlur
   1.764 + * Creates an 8-bit alpha channel context for callers to draw in, blurs the
   1.765 + * contents of that context and applies it as a 1-color mask on a
   1.766 + * different existing context. Uses gfxAlphaBoxBlur as its back end.
   1.767 + *
   1.768 + * You must call Init() first to create a suitable temporary surface to draw
   1.769 + * on.  You must then draw any desired content onto the given context, then
   1.770 + * call DoPaint() to apply the blurred content as a single-color mask. You
   1.771 + * can only call Init() once, so objects cannot be reused.
   1.772 + *
   1.773 + * This is very useful for creating drop shadows or silhouettes.
   1.774 + */
   1.775 +class nsContextBoxBlur {
   1.776 +public:
   1.777 +  enum {
   1.778 +    FORCE_MASK = 0x01
   1.779 +  };
   1.780 +  /**
   1.781 +   * Prepares a gfxContext to draw on. Do not call this twice; if you want
   1.782 +   * to get the gfxContext again use GetContext().
   1.783 +   *
   1.784 +   * @param aRect                The coordinates of the surface to create.
   1.785 +   *                             All coordinates must be in app units.
   1.786 +   *                             This must not include the blur radius, pass
   1.787 +   *                             it as the second parameter and everything
   1.788 +   *                             is taken care of.
   1.789 +   *
   1.790 +   * @param aBlurRadius          The blur radius in app units.
   1.791 +   *
   1.792 +   * @param aAppUnitsPerDevPixel The number of app units in a device pixel,
   1.793 +   *                             for conversion.  Most of the time you'll
   1.794 +   *                             pass this from the current PresContext if
   1.795 +   *                             available.
   1.796 +   *
   1.797 +   * @param aDestinationCtx      The graphics context to apply the blurred
   1.798 +   *                             mask to when you call DoPaint(). Make sure
   1.799 +   *                             it is not destroyed before you call
   1.800 +   *                             DoPaint(). To set the color of the
   1.801 +   *                             resulting blurred graphic mask, you must
   1.802 +   *                             set the color on this context before
   1.803 +   *                             calling Init().
   1.804 +   *
   1.805 +   * @param aDirtyRect           The absolute dirty rect in app units. Used to
   1.806 +   *                             optimize the temporary surface size and speed up blur.
   1.807 +   *
   1.808 +   * @param aSkipRect            An area in device pixels (NOT app units!) to avoid
   1.809 +   *                             blurring over, to prevent unnecessary work.
   1.810 +   *                             
   1.811 +   * @param aFlags               FORCE_MASK to ensure that the content drawn to the
   1.812 +   *                             returned gfxContext is used as a mask, and not
   1.813 +   *                             drawn directly to aDestinationCtx.
   1.814 +   *
   1.815 +   * @return            A blank 8-bit alpha-channel-only graphics context to
   1.816 +   *                    draw on, or null on error. Must not be freed. The
   1.817 +   *                    context has a device offset applied to it given by
   1.818 +   *                    aRect. This means you can use coordinates as if it
   1.819 +   *                    were at the desired position at aRect and you don't
   1.820 +   *                    need to worry about translating any coordinates to
   1.821 +   *                    draw on this temporary surface.
   1.822 +   *
   1.823 +   * If aBlurRadius is 0, the returned context is aDestinationCtx and
   1.824 +   * DoPaint() does nothing, because no blurring is required. Therefore, you
   1.825 +   * should prepare the destination context as if you were going to draw
   1.826 +   * directly on it instead of any temporary surface created in this class.
   1.827 +   */
   1.828 +  gfxContext* Init(const nsRect& aRect, nscoord aSpreadRadius,
   1.829 +                   nscoord aBlurRadius,
   1.830 +                   int32_t aAppUnitsPerDevPixel, gfxContext* aDestinationCtx,
   1.831 +                   const nsRect& aDirtyRect, const gfxRect* aSkipRect,
   1.832 +                   uint32_t aFlags = 0);
   1.833 +
   1.834 +  /**
   1.835 +   * Does the actual blurring and mask applying. Users of this object *must*
   1.836 +   * have called Init() first, then have drawn whatever they want to be
   1.837 +   * blurred onto the internal gfxContext before calling this.
   1.838 +   */
   1.839 +  void DoPaint();
   1.840 +
   1.841 +  /**
   1.842 +   * Gets the internal gfxContext at any time. Must not be freed. Avoid
   1.843 +   * calling this before calling Init() since the context would not be
   1.844 +   * constructed at that point.
   1.845 +   */
   1.846 +  gfxContext* GetContext();
   1.847 +
   1.848 +
   1.849 +  /**
   1.850 +   * Get the margin associated with the given blur radius, i.e., the
   1.851 +   * additional area that might be painted as a result of it.  (The
   1.852 +   * margin for a spread radius is itself, on all sides.)
   1.853 +   */
   1.854 +  static nsMargin GetBlurRadiusMargin(nscoord aBlurRadius,
   1.855 +                                      int32_t aAppUnitsPerDevPixel);
   1.856 +
   1.857 +  /**
   1.858 +   * Blurs a coloured rectangle onto aDestinationCtx. This is equivalent
   1.859 +   * to calling Init(), drawing a rectangle onto the returned surface
   1.860 +   * and then calling DoPaint, but may let us optimize better in the
   1.861 +   * backend.
   1.862 +   *
   1.863 +   * @param aDestinationCtx      The destination to blur to.
   1.864 +   * @param aRect                The rectangle to blur in app units.
   1.865 +   * @param aAppUnitsPerDevPixel The number of app units in a device pixel,
   1.866 +   *                             for conversion.  Most of the time you'll
   1.867 +   *                             pass this from the current PresContext if
   1.868 +   *                             available.
   1.869 +   * @param aCornerRadii         Corner radii for aRect, if it is a rounded
   1.870 +   *                             rectangle.
   1.871 +   * @param aBlurRadius          The blur radius in app units.
   1.872 +   * @param aShadowColor         The color to draw the blurred shadow.
   1.873 +   * @param aDirtyRect           The absolute dirty rect in app units. Used to
   1.874 +   *                             optimize the temporary surface size and speed up blur.
   1.875 +   * @param aSkipRect            An area in device pixels (NOT app units!) to avoid
   1.876 +   *                             blurring over, to prevent unnecessary work.
   1.877 +   */
   1.878 +  static void BlurRectangle(gfxContext* aDestinationCtx,
   1.879 +                            const nsRect& aRect,
   1.880 +                            int32_t aAppUnitsPerDevPixel,
   1.881 +                            gfxCornerSizes* aCornerRadii,
   1.882 +                            nscoord aBlurRadius,
   1.883 +                            const gfxRGBA& aShadowColor,
   1.884 +                            const nsRect& aDirtyRect,
   1.885 +                            const gfxRect& aSkipRect);
   1.886 +
   1.887 +protected:
   1.888 +  gfxAlphaBoxBlur blur;
   1.889 +  nsRefPtr<gfxContext> mContext;
   1.890 +  gfxContext* mDestinationCtx;
   1.891 +
   1.892 +  /* This is true if the blur already has it's content transformed
   1.893 +   * by mDestinationCtx's transform */
   1.894 +  bool mPreTransformed;
   1.895 +
   1.896 +};
   1.897 +
   1.898 +#endif /* nsCSSRendering_h___ */

mercurial