Bug 1128769 (Part 1) - Propagate the imgIContainer::Draw result through the nsLayoutUtils::PaintBackground* functions. r=tn

This commit is contained in:
Seth Fowler 2015-02-09 23:27:39 -08:00
parent fa11992be6
commit dcf10374b4
2 changed files with 86 additions and 69 deletions

View File

@ -63,7 +63,7 @@
using namespace mozilla;
using namespace mozilla::css;
using namespace mozilla::gfx;
using mozilla::image::ImageOps;
using namespace mozilla::image;
using mozilla::CSSSizeOrRatio;
static int gFrameTreeLockCount = 0;
@ -1619,7 +1619,7 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext,
}
}
void
DrawResult
nsCSSRendering::PaintBackground(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
@ -1643,21 +1643,21 @@ nsCSSRendering::PaintBackground(nsPresContext* aPresContext,
// draw the background. The canvas really should be drawing the
// bg, but there's no way to hook that up via css.
if (!aForFrame->StyleDisplay()->mAppearance) {
return;
return DrawResult::SUCCESS;
}
nsIContent* content = aForFrame->GetContent();
if (!content || content->GetParent()) {
return;
return DrawResult::SUCCESS;
}
sc = aForFrame->StyleContext();
}
PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame,
aDirtyRect, aBorderArea, sc,
*aForFrame->StyleBorder(), aFlags,
aBGClipRect, aLayer);
return PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame,
aDirtyRect, aBorderArea, sc,
*aForFrame->StyleBorder(), aFlags,
aBGClipRect, aLayer);
}
static bool
@ -2818,7 +2818,7 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
}
}
void
DrawResult
nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
@ -2833,6 +2833,11 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
NS_PRECONDITION(aForFrame,
"Frame is expected to be provided to PaintBackground");
// Initialize our result to success. We update it only if its value is
// currently DrawResult::SUCCESS, which means that as soon as we hit our first
// non-successful draw, we stop updating and will return that value.
DrawResult result = DrawResult::SUCCESS;
// Check to see if we have an appearance defined. If so, we let the theme
// renderer draw the background and bail out.
// XXXzw this ignores aBGClipRect.
@ -2848,7 +2853,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
theme->DrawWidgetBackground(&aRenderingContext, aForFrame,
displayData->mAppearance, aBorderArea,
drawing);
return;
return DrawResult::SUCCESS;
}
}
@ -2883,7 +2888,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
// true if and only if we are actually supposed to paint an image or
// color into aDirtyRect, respectively.
if (!drawBackgroundImage && !drawBackgroundColor)
return;
return DrawResult::SUCCESS;
// Compute the outermost boundary of the area that might be painted.
// Same coordinate space as aBorderArea & aBGClipRect.
@ -2930,13 +2935,13 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
if (!isCanvasFrame) {
DrawBackgroundColor(clipState, ctx, appUnitsPerPixel);
}
return;
return DrawResult::SUCCESS;
}
if (bg->mImageCount < 1) {
// Return if there are no background layers, all work from this point
// onwards happens iteratively on these.
return;
return DrawResult::SUCCESS;
}
// Validate the layer range before we start iterating.
@ -3005,10 +3010,17 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
"It is assumed the initial operator is OPERATOR_OVER, when it is restored later");
ctx->SetOperator(state.mCompositingOp);
}
state.mImageRenderer.DrawBackground(aPresContext, aRenderingContext,
state.mDestArea, state.mFillArea,
state.mAnchor + paintBorderArea.TopLeft(),
clipState.mDirtyRect);
DrawResult resultForLayer =
state.mImageRenderer.DrawBackground(aPresContext, aRenderingContext,
state.mDestArea, state.mFillArea,
state.mAnchor + paintBorderArea.TopLeft(),
clipState.mDirtyRect);
if (result == DrawResult::SUCCESS) {
result = resultForLayer;
}
if (state.mCompositingOp != gfxContext::OPERATOR_OVER) {
ctx->SetOperator(gfxContext::OPERATOR_OVER);
}
@ -3016,6 +3028,8 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
}
}
}
return result;
}
static inline bool
@ -4910,7 +4924,7 @@ ConvertImageRendererToDrawFlags(uint32_t aImageRendererFlags)
return drawFlags;
}
void
DrawResult
nsImageRenderer::Draw(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
@ -4921,11 +4935,11 @@ nsImageRenderer::Draw(nsPresContext* aPresContext,
{
if (!mIsReady) {
NS_NOTREACHED("Ensure PrepareImage() has returned true before calling me");
return;
return DrawResult::TEMPORARY_ERROR;
}
if (aDest.IsEmpty() || aFill.IsEmpty() ||
mSize.width <= 0 || mSize.height <= 0) {
return;
return DrawResult::SUCCESS;
}
GraphicsFilter filter = nsLayoutUtils::GetGraphicsFilterForFrame(mForFrame);
@ -4935,19 +4949,19 @@ nsImageRenderer::Draw(nsPresContext* aPresContext,
{
nsIntSize imageSize(nsPresContext::AppUnitsToIntCSSPixels(mSize.width),
nsPresContext::AppUnitsToIntCSSPixels(mSize.height));
nsLayoutUtils::DrawBackgroundImage(*aRenderingContext.ThebesContext(),
aPresContext,
mImageContainer, imageSize, filter,
aDest, aFill, aAnchor, aDirtyRect,
ConvertImageRendererToDrawFlags(mFlags));
return;
return
nsLayoutUtils::DrawBackgroundImage(*aRenderingContext.ThebesContext(),
aPresContext,
mImageContainer, imageSize, filter,
aDest, aFill, aAnchor, aDirtyRect,
ConvertImageRendererToDrawFlags(mFlags));
}
case eStyleImageType_Gradient:
{
nsCSSRendering::PaintGradient(aPresContext, aRenderingContext,
mGradientData, aDirtyRect,
aDest, aFill, aSrc, mSize);
return;
return DrawResult::SUCCESS;
}
case eStyleImageType_Element:
{
@ -4955,7 +4969,7 @@ nsImageRenderer::Draw(nsPresContext* aPresContext,
aRenderingContext);
if (!drawable) {
NS_WARNING("Could not create drawable for element");
return;
return DrawResult::TEMPORARY_ERROR;
}
gfxContext* ctx = aRenderingContext.ThebesContext();
@ -4976,11 +4990,11 @@ nsImageRenderer::Draw(nsPresContext* aPresContext,
ctx->Paint();
}
return;
return DrawResult::SUCCESS;
}
case eStyleImageType_Null:
default:
return;
return DrawResult::SUCCESS;
}
}
@ -5013,7 +5027,7 @@ nsImageRenderer::DrawableForElement(const nsRect& aImageRect,
return drawable.forget();
}
void
DrawResult
nsImageRenderer::DrawBackground(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDest,
@ -5023,18 +5037,18 @@ nsImageRenderer::DrawBackground(nsPresContext* aPresContext,
{
if (!mIsReady) {
NS_NOTREACHED("Ensure PrepareImage() has returned true before calling me");
return;
return DrawResult::TEMPORARY_ERROR;
}
if (aDest.IsEmpty() || aFill.IsEmpty() ||
mSize.width <= 0 || mSize.height <= 0) {
return;
return DrawResult::SUCCESS;
}
Draw(aPresContext, aRenderingContext,
aDirty, aDest, aFill, aAnchor,
CSSIntRect(0, 0,
nsPresContext::AppUnitsToIntCSSPixels(mSize.width),
nsPresContext::AppUnitsToIntCSSPixels(mSize.height)));
return Draw(aPresContext, aRenderingContext,
aDirty, aDest, aFill, aAnchor,
CSSIntRect(0, 0,
nsPresContext::AppUnitsToIntCSSPixels(mSize.width),
nsPresContext::AppUnitsToIntCSSPixels(mSize.height)));
}
/**

View File

@ -10,6 +10,7 @@
#include "gfxBlur.h"
#include "gfxContext.h"
#include "imgIContainer.h"
#include "mozilla/gfx/PathHelpers.h"
#include "mozilla/gfx/Rect.h"
#include "nsLayoutUtils.h"
@ -109,6 +110,7 @@ struct CSSSizeOrRatio
*/
class nsImageRenderer {
public:
typedef mozilla::image::DrawResult DrawResult;
typedef mozilla::layers::LayerManager LayerManager;
typedef mozilla::layers::ImageContainer ImageContainer;
@ -202,12 +204,12 @@ public:
* arguments.
* @see nsLayoutUtils::DrawImage() for parameters.
*/
void DrawBackground(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDest,
const nsRect& aFill,
const nsPoint& aAnchor,
const nsRect& aDirty);
DrawResult DrawBackground(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDest,
const nsRect& aFill,
const nsPoint& aAnchor,
const nsRect& aDirty);
/**
* Draw the image to a single component of a border-image style rendering.
@ -247,13 +249,13 @@ private:
*
* @see nsLayoutUtils::DrawImage() for other parameters.
*/
void Draw(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
const nsRect& aDest,
const nsRect& aFill,
const nsPoint& aAnchor,
const mozilla::CSSIntRect& aSrc);
DrawResult Draw(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
const nsRect& aDest,
const nsRect& aFill,
const nsPoint& aAnchor,
const mozilla::CSSIntRect& aSrc);
/**
* Helper method for creating a gfxDrawable from mPaintServerFrame or
@ -321,6 +323,7 @@ struct nsCSSRendering {
typedef mozilla::gfx::Float Float;
typedef mozilla::gfx::Rect Rect;
typedef mozilla::gfx::RectCornerRadii RectCornerRadii;
typedef mozilla::image::DrawResult DrawResult;
typedef nsIFrame::Sides Sides;
/**
@ -554,14 +557,14 @@ struct nsCSSRendering {
*/
PAINTBG_TO_WINDOW = 0x04
};
static void PaintBackground(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
uint32_t aFlags,
nsRect* aBGClipRect = nullptr,
int32_t aLayer = -1);
static DrawResult PaintBackground(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
uint32_t aFlags,
nsRect* aBGClipRect = nullptr,
int32_t aLayer = -1);
/**
* Same as |PaintBackground|, except using the provided style structs.
@ -572,16 +575,16 @@ struct nsCSSRendering {
* The background color will only be painted if the back-most layer is also
* being painted.
*/
static void PaintBackgroundWithSC(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
nsStyleContext *aStyleContext,
const nsStyleBorder& aBorder,
uint32_t aFlags,
nsRect* aBGClipRect = nullptr,
int32_t aLayer = -1);
static DrawResult PaintBackgroundWithSC(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
nsStyleContext *aStyleContext,
const nsStyleBorder& aBorder,
uint32_t aFlags,
nsRect* aBGClipRect = nullptr,
int32_t aLayer = -1);
/**
* Returns the rectangle covered by the given background layer image, taking