mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
Bug 940845 - Part 2: Add a static BlurRectangle method to nsContextBoxBlur and use it when we're blurring a rectangle. r=roc
This commit is contained in:
parent
701b35213b
commit
20050256f7
@ -1085,12 +1085,8 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
|
|||||||
|
|
||||||
nsRect shadowRect = frameRect;
|
nsRect shadowRect = frameRect;
|
||||||
shadowRect.MoveBy(shadowItem->mXOffset, shadowItem->mYOffset);
|
shadowRect.MoveBy(shadowItem->mXOffset, shadowItem->mYOffset);
|
||||||
nscoord pixelSpreadRadius;
|
if (!nativeTheme) {
|
||||||
if (nativeTheme) {
|
|
||||||
pixelSpreadRadius = shadowItem->mSpread;
|
|
||||||
} else {
|
|
||||||
shadowRect.Inflate(shadowItem->mSpread, shadowItem->mSpread);
|
shadowRect.Inflate(shadowItem->mSpread, shadowItem->mSpread);
|
||||||
pixelSpreadRadius = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// shadowRect won't include the blur, so make an extra rect here that includes the blur
|
// shadowRect won't include the blur, so make an extra rect here that includes the blur
|
||||||
@ -1100,32 +1096,10 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
|
|||||||
shadowRectPlusBlur.Inflate(
|
shadowRectPlusBlur.Inflate(
|
||||||
nsContextBoxBlur::GetBlurRadiusMargin(blurRadius, twipsPerPixel));
|
nsContextBoxBlur::GetBlurRadiusMargin(blurRadius, twipsPerPixel));
|
||||||
|
|
||||||
gfxRect shadowGfxRect =
|
|
||||||
nsLayoutUtils::RectToGfxRect(shadowRect, twipsPerPixel);
|
|
||||||
gfxRect shadowGfxRectPlusBlur =
|
gfxRect shadowGfxRectPlusBlur =
|
||||||
nsLayoutUtils::RectToGfxRect(shadowRectPlusBlur, twipsPerPixel);
|
nsLayoutUtils::RectToGfxRect(shadowRectPlusBlur, twipsPerPixel);
|
||||||
shadowGfxRect.Round();
|
|
||||||
shadowGfxRectPlusBlur.RoundOut();
|
shadowGfxRectPlusBlur.RoundOut();
|
||||||
|
|
||||||
gfxContext* renderContext = aRenderingContext.ThebesContext();
|
|
||||||
nsContextBoxBlur blurringArea;
|
|
||||||
|
|
||||||
// When getting the widget shape from the native theme, we're going
|
|
||||||
// to draw the widget into the shadow surface to create a mask.
|
|
||||||
// We need to ensure that there actually *is* a shadow surface
|
|
||||||
// and that we're not going to draw directly into renderContext.
|
|
||||||
gfxContext* shadowContext =
|
|
||||||
blurringArea.Init(shadowRect, pixelSpreadRadius,
|
|
||||||
blurRadius, twipsPerPixel, renderContext, aDirtyRect,
|
|
||||||
useSkipGfxRect ? &skipGfxRect : nullptr,
|
|
||||||
nativeTheme ? nsContextBoxBlur::FORCE_MASK : 0);
|
|
||||||
if (!shadowContext)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// shadowContext is owned by either blurringArea or aRenderingContext.
|
|
||||||
MOZ_ASSERT(shadowContext == renderContext ||
|
|
||||||
shadowContext == blurringArea.GetContext());
|
|
||||||
|
|
||||||
// Set the shadow color; if not specified, use the foreground color
|
// Set the shadow color; if not specified, use the foreground color
|
||||||
nscolor shadowColor;
|
nscolor shadowColor;
|
||||||
if (shadowItem->mHasColor)
|
if (shadowItem->mHasColor)
|
||||||
@ -1136,15 +1110,34 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
|
|||||||
gfxRGBA gfxShadowColor(shadowColor);
|
gfxRGBA gfxShadowColor(shadowColor);
|
||||||
gfxShadowColor.a *= aOpacity;
|
gfxShadowColor.a *= aOpacity;
|
||||||
|
|
||||||
renderContext->Save();
|
gfxContext* renderContext = aRenderingContext.ThebesContext();
|
||||||
renderContext->SetColor(gfxShadowColor);
|
|
||||||
|
|
||||||
// Draw the shape of the frame so it can be blurred. Recall how nsContextBoxBlur
|
|
||||||
// doesn't make any temporary surfaces if blur is 0 and it just returns the original
|
|
||||||
// surface? If we have no blur, we're painting this fill on the actual content surface
|
|
||||||
// (renderContext == shadowContext) which is why we set up the color and clip
|
|
||||||
// before doing this.
|
|
||||||
if (nativeTheme) {
|
if (nativeTheme) {
|
||||||
|
nsContextBoxBlur blurringArea;
|
||||||
|
|
||||||
|
// When getting the widget shape from the native theme, we're going
|
||||||
|
// to draw the widget into the shadow surface to create a mask.
|
||||||
|
// We need to ensure that there actually *is* a shadow surface
|
||||||
|
// and that we're not going to draw directly into renderContext.
|
||||||
|
gfxContext* shadowContext =
|
||||||
|
blurringArea.Init(shadowRect, shadowItem->mSpread,
|
||||||
|
blurRadius, twipsPerPixel, renderContext, aDirtyRect,
|
||||||
|
useSkipGfxRect ? &skipGfxRect : nullptr,
|
||||||
|
nsContextBoxBlur::FORCE_MASK);
|
||||||
|
if (!shadowContext)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// shadowContext is owned by either blurringArea or aRenderingContext.
|
||||||
|
MOZ_ASSERT(shadowContext == blurringArea.GetContext());
|
||||||
|
|
||||||
|
renderContext->Save();
|
||||||
|
renderContext->SetColor(gfxShadowColor);
|
||||||
|
|
||||||
|
// Draw the shape of the frame so it can be blurred. Recall how nsContextBoxBlur
|
||||||
|
// doesn't make any temporary surfaces if blur is 0 and it just returns the original
|
||||||
|
// surface? If we have no blur, we're painting this fill on the actual content surface
|
||||||
|
// (renderContext == shadowContext) which is why we set up the color and clip
|
||||||
|
// before doing this.
|
||||||
|
|
||||||
// We don't clip the border-box from the shadow, nor any other box.
|
// We don't clip the border-box from the shadow, nor any other box.
|
||||||
// We assume that the native theme is going to paint over the shadow.
|
// We assume that the native theme is going to paint over the shadow.
|
||||||
|
|
||||||
@ -1159,7 +1152,11 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
|
|||||||
nativeRect.IntersectRect(frameRect, aDirtyRect);
|
nativeRect.IntersectRect(frameRect, aDirtyRect);
|
||||||
aPresContext->GetTheme()->DrawWidgetBackground(wrapperCtx, aForFrame,
|
aPresContext->GetTheme()->DrawWidgetBackground(wrapperCtx, aForFrame,
|
||||||
styleDisplay->mAppearance, aFrameArea, nativeRect);
|
styleDisplay->mAppearance, aFrameArea, nativeRect);
|
||||||
|
|
||||||
|
blurringArea.DoPaint();
|
||||||
|
renderContext->Restore();
|
||||||
} else {
|
} else {
|
||||||
|
renderContext->Save();
|
||||||
// Clip out the area of the actual frame so the shadow is not shown within
|
// Clip out the area of the actual frame so the shadow is not shown within
|
||||||
// the frame
|
// the frame
|
||||||
renderContext->NewPath();
|
renderContext->NewPath();
|
||||||
@ -1173,9 +1170,8 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
|
|||||||
renderContext->SetFillRule(gfxContext::FILL_RULE_EVEN_ODD);
|
renderContext->SetFillRule(gfxContext::FILL_RULE_EVEN_ODD);
|
||||||
renderContext->Clip();
|
renderContext->Clip();
|
||||||
|
|
||||||
shadowContext->NewPath();
|
gfxCornerSizes clipRectRadii;
|
||||||
if (hasBorderRadius) {
|
if (hasBorderRadius) {
|
||||||
gfxCornerSizes clipRectRadii;
|
|
||||||
gfxFloat spreadDistance = shadowItem->mSpread / twipsPerPixel;
|
gfxFloat spreadDistance = shadowItem->mSpread / twipsPerPixel;
|
||||||
|
|
||||||
gfxFloat borderSizes[4];
|
gfxFloat borderSizes[4];
|
||||||
@ -1187,15 +1183,19 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
|
|||||||
|
|
||||||
nsCSSBorderRenderer::ComputeOuterRadii(borderRadii, borderSizes,
|
nsCSSBorderRenderer::ComputeOuterRadii(borderRadii, borderSizes,
|
||||||
&clipRectRadii);
|
&clipRectRadii);
|
||||||
shadowContext->RoundedRectangle(shadowGfxRect, clipRectRadii);
|
|
||||||
} else {
|
|
||||||
shadowContext->Rectangle(shadowGfxRect);
|
|
||||||
}
|
}
|
||||||
shadowContext->Fill();
|
nsContextBoxBlur::BlurRectangle(renderContext,
|
||||||
|
shadowRect,
|
||||||
|
twipsPerPixel,
|
||||||
|
hasBorderRadius ? &clipRectRadii : nullptr,
|
||||||
|
blurRadius,
|
||||||
|
gfxShadowColor,
|
||||||
|
aDirtyRect,
|
||||||
|
skipGfxRect);
|
||||||
|
renderContext->Restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
blurringArea.DoPaint();
|
|
||||||
renderContext->Restore();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4807,3 +4807,38 @@ nsContextBoxBlur::GetBlurRadiusMargin(nscoord aBlurRadius,
|
|||||||
result.left = blurRadius.width * aAppUnitsPerDevPixel;
|
result.left = blurRadius.width * aAppUnitsPerDevPixel;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
nsContextBoxBlur::BlurRectangle(gfxContext* aDestinationCtx,
|
||||||
|
const nsRect& aRect,
|
||||||
|
int32_t aAppUnitsPerDevPixel,
|
||||||
|
gfxCornerSizes* aCornerRadii,
|
||||||
|
nscoord aBlurRadius,
|
||||||
|
const gfxRGBA& aShadowColor,
|
||||||
|
const nsRect& aDirtyRect,
|
||||||
|
const gfxRect& aSkipRect)
|
||||||
|
{
|
||||||
|
nsContextBoxBlur blur;
|
||||||
|
gfxContext *dest = blur.Init(aRect, 0, aBlurRadius, aAppUnitsPerDevPixel,
|
||||||
|
aDestinationCtx, aDirtyRect, &aSkipRect);
|
||||||
|
|
||||||
|
if (!dest) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxRect shadowGfxRect =
|
||||||
|
nsLayoutUtils::RectToGfxRect(aRect, aAppUnitsPerDevPixel);
|
||||||
|
shadowGfxRect.Round();
|
||||||
|
|
||||||
|
aDestinationCtx->SetColor(aShadowColor);
|
||||||
|
|
||||||
|
dest->NewPath();
|
||||||
|
if (aCornerRadii) {
|
||||||
|
dest->RoundedRectangle(shadowGfxRect, *aCornerRadii);
|
||||||
|
} else {
|
||||||
|
dest->Rectangle(shadowGfxRect);
|
||||||
|
}
|
||||||
|
dest->Fill();
|
||||||
|
|
||||||
|
blur.DoPaint();
|
||||||
|
}
|
||||||
|
@ -784,13 +784,6 @@ public:
|
|||||||
const nsRect& aDirtyRect, const gfxRect* aSkipRect,
|
const nsRect& aDirtyRect, const gfxRect* aSkipRect,
|
||||||
uint32_t aFlags = 0);
|
uint32_t aFlags = 0);
|
||||||
|
|
||||||
/**
|
|
||||||
* Does the actual blurring/spreading. Users of this object *must*
|
|
||||||
* have called Init() first, then have drawn whatever they want to be
|
|
||||||
* blurred onto the internal gfxContext before calling this.
|
|
||||||
*/
|
|
||||||
void DoEffects();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the actual blurring and mask applying. Users of this object *must*
|
* Does the actual blurring and mask applying. Users of this object *must*
|
||||||
* have called Init() first, then have drawn whatever they want to be
|
* have called Init() first, then have drawn whatever they want to be
|
||||||
@ -814,6 +807,15 @@ public:
|
|||||||
static nsMargin GetBlurRadiusMargin(nscoord aBlurRadius,
|
static nsMargin GetBlurRadiusMargin(nscoord aBlurRadius,
|
||||||
int32_t aAppUnitsPerDevPixel);
|
int32_t aAppUnitsPerDevPixel);
|
||||||
|
|
||||||
|
static void BlurRectangle(gfxContext* aDestinationCtx,
|
||||||
|
const nsRect& aRect,
|
||||||
|
int32_t aAppUnitsPerDevPixel,
|
||||||
|
gfxCornerSizes* aCornerRadii,
|
||||||
|
nscoord aBlurRadius,
|
||||||
|
const gfxRGBA& aShadowColor,
|
||||||
|
const nsRect& aDirtyRect,
|
||||||
|
const gfxRect& aSkipRect);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
gfxAlphaBoxBlur blur;
|
gfxAlphaBoxBlur blur;
|
||||||
nsRefPtr<gfxContext> mContext;
|
nsRefPtr<gfxContext> mContext;
|
||||||
|
Loading…
Reference in New Issue
Block a user