mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 626536. Part 1. Refactor the background clip code so that it stores its state in a struct we can pass around. r=roc a=roc
This commit is contained in:
parent
ba5c94807f
commit
9e965d401c
@ -1541,19 +1541,30 @@ SetupDirtyRects(const nsRect& aBGClipArea, const nsRect& aCallerDirtyRect,
|
||||
"second should be empty if first is");
|
||||
}
|
||||
|
||||
struct BackgroundClipState {
|
||||
nsRect mBGClipArea;
|
||||
nsRect mDirtyRect;
|
||||
gfxRect mDirtyRectGfx;
|
||||
|
||||
gfxCornerSizes mClippedRadii;
|
||||
PRPackedBool mRadiiAreOuter;
|
||||
|
||||
// Whether we are being asked to draw with a caller provided background
|
||||
// clipping area. If this is true we also disable rounded corners.
|
||||
PRPackedBool mCustomClip;
|
||||
};
|
||||
|
||||
static void
|
||||
SetupBackgroundClip(gfxContext *aCtx, PRUint8 aBackgroundClip,
|
||||
nsIFrame* aForFrame, const nsRect& aBorderArea,
|
||||
const nsRect& aCallerDirtyRect, PRBool aHaveRoundedCorners,
|
||||
const gfxCornerSizes& aBGRadii, nscoord aAppUnitsPerPixel,
|
||||
gfxContextAutoSaveRestore* aAutoSR,
|
||||
/* OUT: */
|
||||
nsRect* aBGClipArea, nsRect* aDirtyRect,
|
||||
gfxRect* aDirtyRectGfx)
|
||||
GetBackgroundClip(gfxContext *aCtx, PRUint8 aBackgroundClip,
|
||||
nsIFrame* aForFrame, const nsRect& aBorderArea,
|
||||
const nsRect& aCallerDirtyRect, PRBool aHaveRoundedCorners,
|
||||
const gfxCornerSizes& aBGRadii, nscoord aAppUnitsPerPixel,
|
||||
/* out */ BackgroundClipState* aClipState)
|
||||
{
|
||||
*aBGClipArea = aBorderArea;
|
||||
PRBool radiiAreOuter = PR_TRUE;
|
||||
gfxCornerSizes clippedRadii = aBGRadii;
|
||||
aClipState->mBGClipArea = aBorderArea;
|
||||
aClipState->mCustomClip = PR_FALSE;
|
||||
aClipState->mRadiiAreOuter = PR_TRUE;
|
||||
aClipState->mClippedRadii = aBGRadii;
|
||||
if (aBackgroundClip != NS_STYLE_BG_CLIP_BORDER) {
|
||||
nsMargin border = aForFrame->GetUsedBorder();
|
||||
if (aBackgroundClip != NS_STYLE_BG_CLIP_PADDING) {
|
||||
@ -1562,7 +1573,7 @@ SetupBackgroundClip(gfxContext *aCtx, PRUint8 aBackgroundClip,
|
||||
border += aForFrame->GetUsedPadding();
|
||||
}
|
||||
aForFrame->ApplySkipSides(border);
|
||||
aBGClipArea->Deflate(border);
|
||||
aClipState->mBGClipArea.Deflate(border);
|
||||
|
||||
if (aHaveRoundedCorners) {
|
||||
gfxFloat borderSizes[4] = {
|
||||
@ -1572,20 +1583,32 @@ SetupBackgroundClip(gfxContext *aCtx, PRUint8 aBackgroundClip,
|
||||
gfxFloat(border.left / aAppUnitsPerPixel)
|
||||
};
|
||||
nsCSSBorderRenderer::ComputeInnerRadii(aBGRadii, borderSizes,
|
||||
&clippedRadii);
|
||||
radiiAreOuter = PR_FALSE;
|
||||
&aClipState->mClippedRadii);
|
||||
aClipState->mRadiiAreOuter = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
SetupDirtyRects(*aBGClipArea, aCallerDirtyRect, aAppUnitsPerPixel,
|
||||
aDirtyRect, aDirtyRectGfx);
|
||||
SetupDirtyRects(aClipState->mBGClipArea, aCallerDirtyRect, aAppUnitsPerPixel,
|
||||
&aClipState->mDirtyRect, &aClipState->mDirtyRectGfx);
|
||||
}
|
||||
|
||||
if (aDirtyRectGfx->IsEmpty()) {
|
||||
static void
|
||||
SetupBackgroundClip(BackgroundClipState& aClipState, gfxContext *aCtx,
|
||||
PRBool aHaveRoundedCorners, nscoord aAppUnitsPerPixel,
|
||||
gfxContextAutoSaveRestore* aAutoSR)
|
||||
{
|
||||
if (aClipState.mDirtyRectGfx.IsEmpty()) {
|
||||
// Our caller won't draw anything under this condition, so no need
|
||||
// to set more up.
|
||||
return;
|
||||
}
|
||||
|
||||
if (aClipState.mCustomClip) {
|
||||
// We don't support custom clips and rounded corners, arguably a bug, but
|
||||
// table painting seems to depend on it.
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have rounded corners, clip all subsequent drawing to the
|
||||
// rounded rectangle defined by bgArea and bgRadii (we don't know
|
||||
// whether the rounded corners intrude on the dirtyRect or not).
|
||||
@ -1595,7 +1618,7 @@ SetupBackgroundClip(gfxContext *aCtx, PRUint8 aBackgroundClip,
|
||||
|
||||
if (aHaveRoundedCorners) {
|
||||
gfxRect bgAreaGfx =
|
||||
nsLayoutUtils::RectToGfxRect(*aBGClipArea, aAppUnitsPerPixel);
|
||||
nsLayoutUtils::RectToGfxRect(aClipState.mBGClipArea, aAppUnitsPerPixel);
|
||||
bgAreaGfx.Round();
|
||||
bgAreaGfx.Condition();
|
||||
|
||||
@ -1604,13 +1627,13 @@ SetupBackgroundClip(gfxContext *aCtx, PRUint8 aBackgroundClip,
|
||||
// http://hg.mozilla.org/mozilla-central/rev/50e934e4979b landed.
|
||||
NS_WARNING("converted background area should not be empty");
|
||||
// Make our caller not do anything.
|
||||
aDirtyRectGfx->size.SizeTo(0.0, 0.0);
|
||||
aClipState.mDirtyRectGfx.size.SizeTo(0.0, 0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
aAutoSR->Reset(aCtx);
|
||||
aCtx->NewPath();
|
||||
aCtx->RoundedRectangle(bgAreaGfx, clippedRadii, radiiAreOuter);
|
||||
aCtx->RoundedRectangle(bgAreaGfx, aClipState.mClippedRadii, aClipState.mRadiiAreOuter);
|
||||
aCtx->Clip();
|
||||
}
|
||||
}
|
||||
@ -2267,15 +2290,14 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||
// intersection, but that breaks the table painter -- in particular,
|
||||
// taking the intersection breaks reftests/bugs/403249-1[ab].)
|
||||
const nsStyleBackground *bg = aBackgroundSC->GetStyleBackground();
|
||||
nsRect bgClipArea, dirtyRect;
|
||||
gfxRect dirtyRectGfx;
|
||||
BackgroundClipState clipState;
|
||||
PRUint8 currentBackgroundClip;
|
||||
PRBool isSolidBorder;
|
||||
gfxContextAutoSaveRestore autoSR;
|
||||
if (aBGClipRect) {
|
||||
bgClipArea = *aBGClipRect;
|
||||
SetupDirtyRects(bgClipArea, aDirtyRect, appUnitsPerPixel,
|
||||
&dirtyRect, &dirtyRectGfx);
|
||||
clipState.mBGClipArea = *aBGClipRect;
|
||||
clipState.mCustomClip = PR_TRUE;
|
||||
SetupDirtyRects(clipState.mBGClipArea, aDirtyRect, appUnitsPerPixel,
|
||||
&clipState.mDirtyRect, &clipState.mDirtyRectGfx);
|
||||
} else {
|
||||
// The background is rendered over the 'background-clip' area,
|
||||
// which is normally equal to the border area but may be reduced
|
||||
@ -2290,23 +2312,27 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||
(aFlags & PAINTBG_WILL_PAINT_BORDER) && IsOpaqueBorder(aBorder);
|
||||
if (isSolidBorder && currentBackgroundClip == NS_STYLE_BG_CLIP_BORDER)
|
||||
currentBackgroundClip = NS_STYLE_BG_CLIP_PADDING;
|
||||
SetupBackgroundClip(ctx, currentBackgroundClip, aForFrame,
|
||||
aBorderArea, aDirtyRect, haveRoundedCorners,
|
||||
bgRadii, appUnitsPerPixel, &autoSR,
|
||||
&bgClipArea, &dirtyRect, &dirtyRectGfx);
|
||||
|
||||
GetBackgroundClip(ctx, currentBackgroundClip, aForFrame, aBorderArea,
|
||||
aDirtyRect, haveRoundedCorners, bgRadii, appUnitsPerPixel,
|
||||
&clipState);
|
||||
}
|
||||
|
||||
// If we might be using a background color, go ahead and set it now.
|
||||
if (drawBackgroundColor && !isCanvasFrame)
|
||||
ctx->SetColor(gfxRGBA(bgColor));
|
||||
|
||||
gfxContextAutoSaveRestore autoSR;
|
||||
|
||||
// If there is no background image, draw a color. (If there is
|
||||
// neither a background image nor a color, we wouldn't have gotten
|
||||
// this far.)
|
||||
if (!drawBackgroundImage) {
|
||||
if (!dirtyRectGfx.IsEmpty() && !isCanvasFrame) {
|
||||
if (!clipState.mDirtyRectGfx.IsEmpty() && !isCanvasFrame) {
|
||||
SetupBackgroundClip(clipState, ctx, haveRoundedCorners, appUnitsPerPixel,
|
||||
&autoSR);
|
||||
ctx->NewPath();
|
||||
ctx->Rectangle(dirtyRectGfx, PR_TRUE);
|
||||
ctx->Rectangle(clipState.mDirtyRectGfx, PR_TRUE);
|
||||
ctx->Fill();
|
||||
}
|
||||
return;
|
||||
@ -2326,9 +2352,11 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||
// The background color is rendered over the entire dirty area,
|
||||
// even if the image isn't.
|
||||
if (drawBackgroundColor && !isCanvasFrame) {
|
||||
if (!dirtyRectGfx.IsEmpty()) {
|
||||
if (!clipState.mDirtyRectGfx.IsEmpty()) {
|
||||
SetupBackgroundClip(clipState, ctx, haveRoundedCorners, appUnitsPerPixel,
|
||||
&autoSR);
|
||||
ctx->NewPath();
|
||||
ctx->Rectangle(dirtyRectGfx, PR_TRUE);
|
||||
ctx->Rectangle(clipState.mDirtyRectGfx, PR_TRUE);
|
||||
ctx->Fill();
|
||||
}
|
||||
}
|
||||
@ -2342,19 +2370,21 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||
newBackgroundClip = NS_STYLE_BG_CLIP_PADDING;
|
||||
if (currentBackgroundClip != newBackgroundClip) {
|
||||
currentBackgroundClip = newBackgroundClip;
|
||||
SetupBackgroundClip(ctx, currentBackgroundClip, aForFrame,
|
||||
aBorderArea, aDirtyRect, haveRoundedCorners,
|
||||
bgRadii, appUnitsPerPixel, &autoSR,
|
||||
&bgClipArea, &dirtyRect, &dirtyRectGfx);
|
||||
GetBackgroundClip(ctx, currentBackgroundClip, aForFrame, aBorderArea,
|
||||
aDirtyRect, haveRoundedCorners, bgRadii,
|
||||
appUnitsPerPixel, &clipState);
|
||||
SetupBackgroundClip(clipState, ctx, haveRoundedCorners,
|
||||
appUnitsPerPixel, &autoSR);
|
||||
}
|
||||
}
|
||||
if (!dirtyRectGfx.IsEmpty()) {
|
||||
if (!clipState.mDirtyRectGfx.IsEmpty()) {
|
||||
BackgroundLayerState state = PrepareBackgroundLayer(aPresContext, aForFrame,
|
||||
aFlags, aBorderArea, bgClipArea, *bg, layer);
|
||||
aFlags, aBorderArea, clipState.mBGClipArea, *bg, layer);
|
||||
if (!state.mFillArea.IsEmpty()) {
|
||||
state.mImageRenderer.Draw(aPresContext, aRenderingContext,
|
||||
state.mDestArea, state.mFillArea,
|
||||
state.mAnchor + aBorderArea.TopLeft(), dirtyRect);
|
||||
state.mAnchor + aBorderArea.TopLeft(),
|
||||
clipState.mDirtyRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user