From 5b3009c210f03dbeb0309de9c83fb294579f2df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Fri, 4 Sep 2009 15:32:17 +0200 Subject: [PATCH] Backed out changeset 1e6d52401dd2 --- layout/base/nsCSSRendering.cpp | 80 ++++++++++++------- layout/base/nsCSSRendering.h | 4 +- layout/generic/nsHTMLContainerFrame.cpp | 16 ++-- layout/generic/nsTextFrame.h | 2 +- layout/generic/nsTextFrameThebes.cpp | 13 ++- .../text-shadow/padding-decoration-ref.html | 1 - .../text-shadow/padding-decoration.html | 1 - layout/reftests/text-shadow/reftest.list | 1 - layout/xul/base/src/nsTextBoxFrame.cpp | 11 ++- 9 files changed, 74 insertions(+), 55 deletions(-) delete mode 100644 layout/reftests/text-shadow/padding-decoration-ref.html delete mode 100644 layout/reftests/text-shadow/padding-decoration.html diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 92db50ed85e..0043a9608f4 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -1162,30 +1162,35 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext, gfxRect frameGfxRect = RectToGfxRect(aFrameArea, twipsPerPixel); frameGfxRect.Round(); + gfxRect dirtyGfxRect = RectToGfxRect(aDirtyRect, twipsPerPixel); for (PRUint32 i = shadows->Length(); i > 0; --i) { nsCSSShadowItem* shadowItem = shadows->ShadowAt(i - 1); if (shadowItem->mInset) continue; - nsRect shadowRect = aFrameArea; - shadowRect.MoveBy(shadowItem->mXOffset, shadowItem->mYOffset); - shadowRect.Inflate(shadowItem->mSpread, shadowItem->mSpread); + gfxRect shadowRect(aFrameArea.x, aFrameArea.y, aFrameArea.width, aFrameArea.height); + shadowRect.MoveBy(gfxPoint(shadowItem->mXOffset, shadowItem->mYOffset)); + shadowRect.Outset(shadowItem->mSpread); + + gfxRect shadowRectPlusBlur = shadowRect; + shadowRect.ScaleInverse(twipsPerPixel); + shadowRect.Round(); // shadowRect won't include the blur, so make an extra rect here that includes the blur // for use in the even-odd rule below. - nsRect shadowRectPlusBlur = shadowRect; nscoord blurRadius = shadowItem->mRadius; - shadowRectPlusBlur.Inflate(blurRadius, blurRadius); - - gfxRect shadowGfxRect = RectToGfxRect(shadowRect, twipsPerPixel); - gfxRect shadowGfxRectPlusBlur = RectToGfxRect(shadowRectPlusBlur, twipsPerPixel); + shadowRectPlusBlur.Outset(blurRadius); + shadowRectPlusBlur.ScaleInverse(twipsPerPixel); + shadowRectPlusBlur.RoundOut(); gfxContext* renderContext = aRenderingContext.ThebesContext(); nsRefPtr shadowContext; nsContextBoxBlur blurringArea; - shadowContext = blurringArea.Init(shadowRect, blurRadius, twipsPerPixel, renderContext, aDirtyRect); + // shadowRect is already in device pixels, pass 1 as the appunits/pixel value + blurRadius /= twipsPerPixel; + shadowContext = blurringArea.Init(shadowRect, blurRadius, 1, renderContext, dirtyGfxRect); if (!shadowContext) continue; @@ -1202,7 +1207,7 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext, // Clip out the area of the actual frame so the shadow is not shown within // the frame renderContext->NewPath(); - renderContext->Rectangle(shadowGfxRectPlusBlur); + renderContext->Rectangle(shadowRectPlusBlur); if (hasBorderRadius) renderContext->RoundedRectangle(frameGfxRect, borderRadii); else @@ -1225,9 +1230,9 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext, }; nsCSSBorderRenderer::ComputeInnerRadii(borderRadii, borderSizes, &clipRectRadii); - shadowContext->RoundedRectangle(shadowGfxRect, clipRectRadii); + shadowContext->RoundedRectangle(shadowRect, clipRectRadii); } else { - shadowContext->Rectangle(shadowGfxRect); + shadowContext->Rectangle(shadowRect); } shadowContext->Fill(); @@ -1274,6 +1279,7 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, &innerRadii); } + gfxRect dirtyGfxRect = RectToGfxRect(aDirtyRect, twipsPerPixel); for (PRUint32 i = shadows->Length(); i > 0; --i) { nsCSSShadowItem* shadowItem = shadows->ShadowAt(i - 1); if (!shadowItem->mInset) @@ -1287,18 +1293,28 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, * that we will NOT paint in */ nscoord blurRadius = shadowItem->mRadius; - nsRect shadowPaintRect = paddingRect; - shadowPaintRect.Inflate(blurRadius, blurRadius); + gfxRect shadowRect(paddingRect.x, paddingRect.y, paddingRect.width, paddingRect.height); + gfxRect shadowPaintRect = shadowRect; + shadowPaintRect.Outset(blurRadius); - nsRect shadowClipRect = paddingRect; - shadowClipRect.MoveBy(shadowItem->mXOffset, shadowItem->mYOffset); - shadowClipRect.Deflate(shadowItem->mSpread, shadowItem->mSpread); + gfxRect shadowClipRect = shadowRect; + shadowClipRect.MoveBy(gfxPoint(shadowItem->mXOffset, shadowItem->mYOffset)); + shadowClipRect.Inset(shadowItem->mSpread); + + shadowRect.ScaleInverse(twipsPerPixel); + shadowRect.Round(); + shadowPaintRect.ScaleInverse(twipsPerPixel); + shadowPaintRect.RoundOut(); + shadowClipRect.ScaleInverse(twipsPerPixel); + shadowClipRect.Round(); gfxContext* renderContext = aRenderingContext.ThebesContext(); nsRefPtr shadowContext; nsContextBoxBlur blurringArea; - shadowContext = blurringArea.Init(shadowPaintRect, blurRadius, twipsPerPixel, renderContext, aDirtyRect); + // shadowPaintRect is already in device pixels, pass 1 as the appunits/pixel value + blurRadius /= twipsPerPixel; + shadowContext = blurringArea.Init(shadowPaintRect, blurRadius, 1, renderContext, dirtyGfxRect); if (!shadowContext) continue; @@ -1314,20 +1330,17 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, // Clip the context to the area of the frame's padding rect, so no part of the // shadow is painted outside - gfxRect shadowGfxRect = RectToGfxRect(paddingRect, twipsPerPixel); renderContext->NewPath(); if (hasBorderRadius) - renderContext->RoundedRectangle(shadowGfxRect, innerRadii, PR_FALSE); + renderContext->RoundedRectangle(shadowRect, innerRadii, PR_FALSE); else - renderContext->Rectangle(shadowGfxRect); + renderContext->Rectangle(shadowRect); renderContext->Clip(); // Fill the temporary surface minus the area within the frame that we should // not paint in, and blur and apply it - gfxRect shadowPaintGfxRect = RectToGfxRect(shadowPaintRect, twipsPerPixel); - gfxRect shadowClipGfxRect = RectToGfxRect(shadowClipRect, twipsPerPixel); shadowContext->NewPath(); - shadowContext->Rectangle(shadowPaintGfxRect); + shadowContext->Rectangle(shadowPaintRect); if (hasBorderRadius) { // Calculate the radii the inner clipping rect will have gfxCornerSizes clipRectRadii; @@ -1338,9 +1351,9 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, }; nsCSSBorderRenderer::ComputeInnerRadii(innerRadii, borderSizes, &clipRectRadii); - shadowContext->RoundedRectangle(shadowClipGfxRect, clipRectRadii, PR_FALSE); + shadowContext->RoundedRectangle(shadowClipRect, clipRectRadii, PR_FALSE); } else { - shadowContext->Rectangle(shadowClipGfxRect); + shadowContext->Rectangle(shadowClipRect); } shadowContext->SetFillRule(gfxContext::FILL_RULE_EVEN_ODD); shadowContext->Fill(); @@ -3193,14 +3206,15 @@ ImageRenderer::Draw(nsPresContext* aPresContext, // nsContextBoxBlur // ----- gfxContext* -nsContextBoxBlur::Init(const nsRect& aRect, nscoord aBlurRadius, +nsContextBoxBlur::Init(const gfxRect& aRect, nscoord aBlurRadius, PRInt32 aAppUnitsPerDevPixel, gfxContext* aDestinationCtx, - const nsRect& aDirtyRect) + const gfxRect& aDirtyRect) { - PRInt32 blurRadius = static_cast(aBlurRadius / aAppUnitsPerDevPixel); mDestinationCtx = aDestinationCtx; + PRInt32 blurRadius = static_cast(aBlurRadius / aAppUnitsPerDevPixel); + // if not blurring, draw directly onto the destination device if (blurRadius <= 0) { mContext = aDestinationCtx; @@ -3208,14 +3222,18 @@ nsContextBoxBlur::Init(const nsRect& aRect, nscoord aBlurRadius, } // Convert from app units to device pixels - gfxRect rect = RectToGfxRect(aRect, aAppUnitsPerDevPixel); + gfxRect rect = aRect; + rect.ScaleInverse(aAppUnitsPerDevPixel); if (rect.IsEmpty()) { mContext = aDestinationCtx; return mContext; } - gfxRect dirtyRect = RectToGfxRect(aDirtyRect, aAppUnitsPerDevPixel); + gfxRect dirtyRect = aDirtyRect; + dirtyRect.ScaleInverse(aAppUnitsPerDevPixel); + + mDestinationCtx = aDestinationCtx; // Create the temporary surface for blurring mContext = blur.Init(rect, gfxIntSize(blurRadius, blurRadius), &dirtyRect); diff --git a/layout/base/nsCSSRendering.h b/layout/base/nsCSSRendering.h index 618212aeb34..ac3e9e1c885 100644 --- a/layout/base/nsCSSRendering.h +++ b/layout/base/nsCSSRendering.h @@ -400,9 +400,9 @@ public: * should prepare the destination context as if you were going to draw * directly on it instead of any temporary surface created in this class. */ - gfxContext* Init(const nsRect& aRect, nscoord aBlurRadius, + gfxContext* Init(const gfxRect& aRect, nscoord aBlurRadius, PRInt32 aAppUnitsPerDevPixel, gfxContext* aDestinationCtx, - const nsRect& aDirtyRect); + const gfxRect& aDirtyRect); /** * Does the actual blurring and mask applying. Users of this object *must* diff --git a/layout/generic/nsHTMLContainerFrame.cpp b/layout/generic/nsHTMLContainerFrame.cpp index 2cfd814c250..7cf435e91ba 100644 --- a/layout/generic/nsHTMLContainerFrame.cpp +++ b/layout/generic/nsHTMLContainerFrame.cpp @@ -155,7 +155,7 @@ class nsDisplayTextShadow : public nsDisplayItem { public: nsDisplayTextShadow(nsHTMLContainerFrame* aFrame, const PRUint8 aDecoration, const nscolor& aColor, nsLineBox* aLine, - const nscoord& aBlurRadius, const nsPoint& aOffset) + const nscoord& aBlurRadius, const gfxPoint& aOffset) : nsDisplayItem(aFrame), mLine(aLine), mColor(aColor), mDecorationFlags(aDecoration), mBlurRadius(aBlurRadius), mOffset(aOffset) { @@ -174,7 +174,7 @@ private: nscolor mColor; PRUint8 mDecorationFlags; nscoord mBlurRadius; // App units - nsPoint mOffset; // App units + gfxPoint mOffset; // App units }; void @@ -192,17 +192,21 @@ nsDisplayTextShadow::Paint(nsDisplayListBuilder* aBuilder, if (!firstFont) return; // OOM const gfxFont::Metrics& metrics = firstFont->GetMetrics(); + nsPoint pt = aBuilder->ToReferenceFrame(mFrame) + nsPoint(mOffset.x, mOffset.y); nsHTMLContainerFrame* f = static_cast(mFrame); - nsPoint pt = aBuilder->ToReferenceFrame(mFrame) + mOffset; + nsMargin bp = f->GetUsedBorderAndPadding(); + nscoord innerWidthInAppUnits = (mFrame->GetSize().width - bp.LeftRight()); - nsRect shadowRect = mFrame->GetContentRect() - mFrame->GetPosition() + pt; + gfxRect shadowRect = gfxRect(pt.x, pt.y, innerWidthInAppUnits, mFrame->GetSize().height); gfxContext* thebesCtx = aCtx->ThebesContext(); + gfxRect dirtyRect(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); + nsContextBoxBlur contextBoxBlur; gfxContext* shadowCtx = contextBoxBlur.Init(shadowRect, mBlurRadius, mFrame->PresContext()->AppUnitsPerDevPixel(), - thebesCtx, aDirtyRect); + thebesCtx, dirtyRect); if (!shadowCtx) return; @@ -275,7 +279,7 @@ nsHTMLContainerFrame::DisplayTextDecorations(nsDisplayListBuilder* aBuilder, else shadowColor = GetStyleColor()->mColor; - nsPoint offset(shadow->mXOffset, shadow->mYOffset); + gfxPoint offset = gfxPoint(shadow->mXOffset, shadow->mYOffset); // Add it to the display list so it is painted underneath the text and all decorations nsresult rv = aBelowTextDecorations->AppendNewToTop(new (aBuilder) diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h index 12714f67d45..6179ce51c30 100644 --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -418,7 +418,7 @@ protected: PRUint32 aLength, nsCSSShadowItem* aShadowDetails, PropertyProvider* aProvider, - const nsRect& aDirtyRect, + const gfxRect& aDirtyRect, const gfxPoint& aFramePt, const gfxPoint& aTextBaselinePt, gfxContext* aCtx, diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp index 1ae42fc32f9..2b8dcd45640 100644 --- a/layout/generic/nsTextFrameThebes.cpp +++ b/layout/generic/nsTextFrameThebes.cpp @@ -4422,7 +4422,7 @@ AddHyphenToMetrics(nsTextFrame* aTextFrame, gfxTextRun* aBaseTextRun, void nsTextFrame::PaintOneShadow(PRUint32 aOffset, PRUint32 aLength, nsCSSShadowItem* aShadowDetails, - PropertyProvider* aProvider, const nsRect& aDirtyRect, + PropertyProvider* aProvider, const gfxRect& aDirtyRect, const gfxPoint& aFramePt, const gfxPoint& aTextBaselinePt, gfxContext* aCtx, const nscolor& aForegroundColor) { @@ -4439,10 +4439,8 @@ nsTextFrame::PaintOneShadow(PRUint32 aOffset, PRUint32 aLength, // This rect is the box which is equivalent to where the shadow will be painted. // The origin of mBoundingBox is the text baseline left, so we must translate it by // that much in order to make the origin the top-left corner of the text bounding box. - gfxRect shadowGfxRect = shadowMetrics.mBoundingBox + + gfxRect shadowRect = shadowMetrics.mBoundingBox + gfxPoint(aFramePt.x, aTextBaselinePt.y) + shadowOffset; - nsRect shadowRect(shadowGfxRect.X(), shadowGfxRect.Y(), - shadowGfxRect.Width(), shadowGfxRect.Height()); nsContextBoxBlur contextBoxBlur; gfxContext* shadowContext = contextBoxBlur.Init(shadowRect, blurRadius, @@ -4464,18 +4462,17 @@ nsTextFrame::PaintOneShadow(PRUint32 aOffset, PRUint32 aLength, // Draw the text onto our alpha-only surface to capture the alpha values. // Remember that the box blur context has a device offset on it, so we don't need to // translate any coordinates to fit on the surface. - gfxRect dirtyGfxRect(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); gfxFloat advanceWidth; DrawText(shadowContext, aTextBaselinePt + shadowOffset, - aOffset, aLength, &dirtyGfxRect, aProvider, advanceWidth, + aOffset, aLength, &aDirtyRect, aProvider, advanceWidth, (GetStateBits() & TEXT_HYPHEN_BREAK) != 0); // This will only have an effect in quirks mode. Standards mode text-decoration shadow painting // is handled in nsHTMLContainerFrame.cpp, so you must remember to consider that if you change // any code behaviour here. nsTextPaintStyle textPaintStyle(this); - PaintTextDecorations(shadowContext, dirtyGfxRect, aFramePt + shadowOffset, + PaintTextDecorations(shadowContext, aDirtyRect, aFramePt + shadowOffset, aTextBaselinePt + shadowOffset, textPaintStyle, *aProvider, &shadowColor); @@ -4741,7 +4738,7 @@ nsTextFrame::PaintText(nsIRenderingContext* aRenderingContext, nsPoint aPt, PaintOneShadow(provider.GetStart().GetSkippedOffset(), ComputeTransformedLength(provider), textStyle->mTextShadow->ShadowAt(i - 1), &provider, - aDirtyRect, framePt, textBaselinePt, ctx, + dirtyRect, framePt, textBaselinePt, ctx, textPaintStyle.GetTextColor()); } } diff --git a/layout/reftests/text-shadow/padding-decoration-ref.html b/layout/reftests/text-shadow/padding-decoration-ref.html deleted file mode 100644 index bb54e6d67e7..00000000000 --- a/layout/reftests/text-shadow/padding-decoration-ref.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/layout/reftests/text-shadow/padding-decoration.html b/layout/reftests/text-shadow/padding-decoration.html deleted file mode 100644 index 0e60ed9b2c1..00000000000 --- a/layout/reftests/text-shadow/padding-decoration.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/layout/reftests/text-shadow/reftest.list b/layout/reftests/text-shadow/reftest.list index 9bdc57cb654..dbaa93766ec 100644 --- a/layout/reftests/text-shadow/reftest.list +++ b/layout/reftests/text-shadow/reftest.list @@ -13,5 +13,4 @@ == multiple-noblur.html multiple-noblur-ref.html == quirks-decor-noblur.html quirks-decor-noblur-ref.html == standards-decor-noblur.html standards-decor-noblur-ref.html -== padding-decoration.html padding-decoration-ref.html diff --git a/layout/xul/base/src/nsTextBoxFrame.cpp b/layout/xul/base/src/nsTextBoxFrame.cpp index 73a1dd248bd..1c6f84e7569 100644 --- a/layout/xul/base/src/nsTextBoxFrame.cpp +++ b/layout/xul/base/src/nsTextBoxFrame.cpp @@ -574,10 +574,14 @@ void nsTextBoxFrame::PaintOneShadow(gfxContext* aCtx, nsRect shadowRect(aTextRect); shadowRect.MoveBy(shadowOffset); + gfxRect shadowRectGFX(shadowRect.x, shadowRect.y, shadowRect.width, shadowRect.height); + gfxRect dirtyRectGFX(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); + nsContextBoxBlur contextBoxBlur; - gfxContext* shadowContext = contextBoxBlur.Init(shadowRect, blurRadius, + gfxContext* shadowContext = contextBoxBlur.Init(shadowRectGFX, blurRadius, PresContext()->AppUnitsPerDevPixel(), - aCtx, aDirtyRect); + aCtx, dirtyRectGFX); + if (!shadowContext) return; @@ -591,8 +595,7 @@ void nsTextBoxFrame::PaintOneShadow(gfxContext* aCtx, nsCOMPtr renderingContext = nsnull; nsIDeviceContext* devCtx = PresContext()->DeviceContext(); devCtx->CreateRenderingContextInstance(*getter_AddRefs(renderingContext)); - if (!renderingContext) - return; + if (!renderingContext) return; renderingContext->Init(devCtx, shadowContext); aCtx->Save();