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___ */