diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 05d0782fb194..090ff1ad0a1d 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -2174,6 +2174,64 @@ DrawBorderSides(gfxContext *ctx, // The content to render to #endif } +/* + * Compute the float-pixel radii that should be used for drawing + * this border/outline, given the various input bits. + * + * If a side is skipped via skipSides, its corners are forced to 0, + * otherwise the resulting radius is the smaller of the specified + * radius and half of each adjacent side's length. + */ +static void +ComputePixelRadii(const nscoord *aTwipsRadii, + const nsRect& outerRect, + const nsMargin& borderMargin, + PRIntn skipSides, + nscoord twipsPerPixel, + gfxFloat *oBorderRadii) +{ + nscoord twipsRadii[4] = { aTwipsRadii[0], aTwipsRadii[1], aTwipsRadii[2], aTwipsRadii[3] }; + nsMargin border(borderMargin); + + if (skipSides & SIDE_BIT_TOP) { + border.top = 0; + twipsRadii[C_TL] = 0; + twipsRadii[C_TR] = 0; + } + + if (skipSides & SIDE_BIT_RIGHT) { + border.right = 0; + twipsRadii[C_TR] = 0; + twipsRadii[C_BR] = 0; + } + + if (skipSides & SIDE_BIT_BOTTOM) { + border.bottom = 0; + twipsRadii[C_BR] = 0; + twipsRadii[C_BL] = 0; + } + + if (skipSides & SIDE_BIT_LEFT) { + border.left = 0; + twipsRadii[C_BL] = 0; + twipsRadii[C_TL] = 0; + } + + nsRect innerRect(outerRect); + innerRect.Deflate(border); + + // make sure the corner radii don't get too big + nsMargin maxRadiusSize(innerRect.width/2 + border.left, + innerRect.height/2 + border.top, + innerRect.width/2 + border.right, + innerRect.height/2 + border.bottom); + + oBorderRadii[C_TL] = gfxFloat(PR_MIN(twipsRadii[C_TL], PR_MIN(maxRadiusSize.top, maxRadiusSize.left))) / twipsPerPixel; + oBorderRadii[C_TR] = gfxFloat(PR_MIN(twipsRadii[C_TR], PR_MIN(maxRadiusSize.top, maxRadiusSize.right))) / twipsPerPixel; + oBorderRadii[C_BL] = gfxFloat(PR_MIN(twipsRadii[C_BL], PR_MIN(maxRadiusSize.bottom, maxRadiusSize.left))) / twipsPerPixel; + oBorderRadii[C_BR] = gfxFloat(PR_MIN(twipsRadii[C_BR], PR_MIN(maxRadiusSize.bottom, maxRadiusSize.right))) / twipsPerPixel; +} + static void DrawDashedSide(gfxContext *ctx, PRUint8 side, @@ -2620,34 +2678,10 @@ nsCSSRendering::PaintBorder(nsPresContext* aPresContext, } // Turn off rendering for all of the zero sized sides - if (border.top == 0) aSkipSides |= SIDE_BIT_TOP; - if (border.right == 0) aSkipSides |= SIDE_BIT_RIGHT; - if (border.bottom == 0) aSkipSides |= SIDE_BIT_BOTTOM; - if (border.left == 0) aSkipSides |= SIDE_BIT_LEFT; - - if (aSkipSides & SIDE_BIT_TOP) { - border.top = 0; - twipsRadii[C_TL] = 0; - twipsRadii[C_TR] = 0; - } - - if (aSkipSides & SIDE_BIT_RIGHT) { - border.right = 0; - twipsRadii[C_TR] = 0; - twipsRadii[C_BR] = 0; - } - - if (aSkipSides & SIDE_BIT_BOTTOM) { - border.bottom = 0; - twipsRadii[C_BR] = 0; - twipsRadii[C_BL] = 0; - } - - if (aSkipSides & SIDE_BIT_LEFT) { - border.left = 0; - twipsRadii[C_BL] = 0; - twipsRadii[C_TL] = 0; - } + if (aSkipSides & SIDE_BIT_TOP) border.top = 0; + if (aSkipSides & SIDE_BIT_RIGHT) border.right = 0; + if (aSkipSides & SIDE_BIT_BOTTOM) border.bottom = 0; + if (aSkipSides & SIDE_BIT_LEFT) border.left = 0; // get the inside and outside parts of the border nsRect outerRect(aBorderArea), innerRect(aBorderArea); @@ -2678,19 +2712,6 @@ nsCSSRendering::PaintBorder(nsPresContext* aPresContext, return; } - // make sure the corner radii don't get too big - nsMargin maxRadiusSize(innerRect.width/2 + border.left, - innerRect.height/2 + border.top, - innerRect.width/2 + border.right, - innerRect.height/2 + border.bottom); - - twipsRadii[C_TL] = PR_MIN(twipsRadii[C_TL], PR_MIN(maxRadiusSize.top, maxRadiusSize.left)); - twipsRadii[C_TR] = PR_MIN(twipsRadii[C_TR], PR_MIN(maxRadiusSize.top, maxRadiusSize.right)); - twipsRadii[C_BL] = PR_MIN(twipsRadii[C_BL], PR_MIN(maxRadiusSize.bottom, maxRadiusSize.left)); - twipsRadii[C_BR] = PR_MIN(twipsRadii[C_BR], PR_MIN(maxRadiusSize.bottom, maxRadiusSize.right)); - - SF(" borderRadii: %d %d %d %d\n", twipsRadii[0], twipsRadii[1], twipsRadii[2], twipsRadii[3]); - // we can assume that we're already clipped to aDirtyRect -- I think? (!?) // Get our conversion values @@ -2707,10 +2728,8 @@ nsCSSRendering::PaintBorder(nsPresContext* aPresContext, border.left / twipsPerPixel }; // convert the radii - gfxFloat borderRadii[4] = { gfxFloat(twipsRadii[0]) / twipsPerPixel, - gfxFloat(twipsRadii[1]) / twipsPerPixel, - gfxFloat(twipsRadii[2]) / twipsPerPixel, - gfxFloat(twipsRadii[3]) / twipsPerPixel }; + gfxFloat borderRadii[4]; + ComputePixelRadii(twipsRadii, outerRect, border, aSkipSides, twipsPerPixel, borderRadii); PRUint8 borderStyles[4]; nscolor borderColors[4]; @@ -2823,9 +2842,6 @@ nsCSSRendering::PaintOutline(nsPresContext* aPresContext, default: break; } - - if (twipsRadii[i]) - twipsRadii[i] = PR_MIN(twipsRadii[i], PR_MIN(aBorderArea.width / 2, aBorderArea.height / 2)); } nsRect overflowArea = aForFrame->GetOverflowRect(); @@ -2865,10 +2881,9 @@ nsCSSRendering::PaintOutline(nsPresContext* aPresContext, gfxRect iRect(RectToGfxRect(innerRect, twipsPerPixel)); // convert the radii - gfxFloat outlineRadii[4] = { gfxFloat(twipsRadii[0]) / twipsPerPixel, - gfxFloat(twipsRadii[1]) / twipsPerPixel, - gfxFloat(twipsRadii[2]) / twipsPerPixel, - gfxFloat(twipsRadii[3]) / twipsPerPixel }; + nsMargin outlineMargin(width, width, width, width); + gfxFloat outlineRadii[4]; + ComputePixelRadii(twipsRadii, outerRect, outlineMargin, 0, twipsPerPixel, outlineRadii); PRUint8 outlineStyle = aOutlineStyle.GetOutlineStyle(); PRUint8 outlineStyles[4] = { outlineStyle, @@ -3817,7 +3832,7 @@ nsCSSRendering::PaintBackgroundColor(nsPresContext* aPresContext, } nsStyleCoord bordStyleRadius[4]; - PRInt16 borderRadii[4]; + nscoord borderRadii[4]; nsRect bgClipArea(aBgClipArea); // get the radius for our border @@ -3887,7 +3902,7 @@ nsCSSRendering::PaintRoundedBackground(nsPresContext* aPresContext, const nsRect& aBgClipArea, const nsStyleBackground& aColor, const nsStyleBorder& aBorder, - PRInt16 aTheRadius[4], + nscoord aTheRadius[4], PRBool aCanPaintNonWhite) { nsRefPtr ctx = (gfxContext*) @@ -3921,10 +3936,13 @@ nsCSSRendering::PaintRoundedBackground(nsPresContext* aPresContext, if (oRect.IsEmpty()) return; - gfxFloat radii[4] = { gfxFloat(aTheRadius[0]) / appUnitsPerPixel, - gfxFloat(aTheRadius[1]) / appUnitsPerPixel, - gfxFloat(aTheRadius[2]) / appUnitsPerPixel, - gfxFloat(aTheRadius[3]) / appUnitsPerPixel }; + // convert the radii + gfxFloat radii[4]; + nsMargin border = aBorder.GetBorder(); + + ComputePixelRadii(aTheRadius, aBgClipArea, border, + aForFrame ? aForFrame->GetSkipSides() : 0, + appUnitsPerPixel, radii); // Add 1.0 to any border radii; if we don't, the border and background // curves will combine to have fringing at the rounded corners. Since diff --git a/layout/base/nsCSSRendering.h b/layout/base/nsCSSRendering.h index 424e8a80e0e9..336b620fdbe2 100644 --- a/layout/base/nsCSSRendering.h +++ b/layout/base/nsCSSRendering.h @@ -215,7 +215,7 @@ protected: const nsRect& aBorderArea, const nsStyleBackground& aColor, const nsStyleBorder& aBorder, - PRInt16 aTheRadius[4], + nscoord aTheRadius[4], PRBool aCanPaintNonWhite); static nscolor MakeBevelColor(PRIntn whichSide, PRUint8 style, @@ -234,98 +234,4 @@ protected: }; - -/** --------------------------------------------------- - * Class QBCurve, a quadratic bezier curve, used to implement the rounded rectangles - * @update 3/26/99 dwc - */ -class QBCurve -{ - -public: - nsFloatPoint mAnc1; - nsFloatPoint mCon; - nsFloatPoint mAnc2; - - QBCurve() {mAnc1.x=0;mAnc1.y=0;mCon=mAnc2=mAnc1;} - void SetControls(nsFloatPoint &aAnc1,nsFloatPoint &aCon,nsFloatPoint &aAnc2) { mAnc1 = aAnc1; mCon = aCon; mAnc2 = aAnc2;} - void SetPoints(float a1x,float a1y,float acx,float acy,float a2x,float a2y) {mAnc1.MoveTo(a1x,a1y),mCon.MoveTo(acx,acy),mAnc2.MoveTo(a2x,a2y);} - -/** --------------------------------------------------- - * Divide a Quadratic curve into line segments if it is not smaller than a certain size - * else it is so small that it can be approximated by 2 lineto calls - * @param aRenderingContext -- The RenderingContext to use to draw with - * @param aPointArray[] -- A list of points we can put line calls into instead of drawing. If null, lines are drawn - * @param aCurInex -- a pointer to an Integer that tells were to put the points into the array, incremented when finished - * @update 3/26/99 dwc - */ - void SubDivide(nsIRenderingContext *aRenderingContext,nsPoint aPointArray[],PRInt32 *aCurIndex); - -/** --------------------------------------------------- - * Divide a Quadratic Bezier curve at the mid-point - * @update 3/26/99 dwc - * @param aCurve1 -- Curve 1 as a result of the division - * @param aCurve2 -- Curve 2 as a result of the division - */ - void MidPointDivide(QBCurve *A,QBCurve *B); -}; - - -/** --------------------------------------------------- - * Class RoundedRect, A class to encapsulate all the rounded rect functionality, - * which are based on the QBCurve - * @update 4/13/99 dwc - */ -class RoundedRect -{ - -public: - PRInt32 mRoundness[4]; - - PRBool mDoRound; - - PRInt32 mLeft; - PRInt32 mRight; - PRInt32 mTop; - PRInt32 mBottom; - - /** - * Construct a rounded rectangle object - * @update 4/19/99 - */ - void RoundRect() {mRoundness[0]=0;} - - /** - * Set the curves boundaries and then break it up into the curve pieces for rendering - * @update 4/13/99 dwc - * @param aLeft -- Left side of bounding box - * @param aTop -- Top side of bounding box - * @param aWidth -- Width of bounding box - * @param aHeight -- Height of bounding box - * @param aRadius -- radius for the rounding - */ - void Set(nscoord aLeft,nscoord aTop,PRInt32 aWidth,PRInt32 aHeight,PRInt16 aRadius[4],PRInt16 aNumTwipPerPix); - - - /** - * Calculate the inset of a curve based on a border - * @update 4/13/99 dwc - * @param aLeft -- Left side of bounding box - * @param aTop -- Top side of bounding box - */ - void CalcInsetCurves(QBCurve &aULCurve,QBCurve &aURCurve,QBCurve &aLLCurve,QBCurve &aLRCurve,nsMargin &aBorder); - - /** --------------------------------------------------- - * set the passed in curves to the rounded borders of the rectangle - * @update 4/13/99 dwc - * @param aULCurve -- upperleft curve - * @param aURCurve -- upperright curve - * @param aLRCurve -- lowerright curve - * @param aLLCurve -- lowerleft curve - */ - void GetRoundedBorders(QBCurve &aULCurve,QBCurve &aURCurve,QBCurve &aLLCurve,QBCurve &aLRCurve); - -}; - - #endif /* nsCSSRendering_h___ */