mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +00:00
Bug 310124 Double border is incorrectly compressed when rendered; regression. original idea by Takeshi Ichimaru <ayakawa.m@gmail.com> r+sr=roc
This commit is contained in:
parent
856897abff
commit
a3cbff90e5
@ -22,6 +22,8 @@
|
|||||||
*
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Mats Palmgren <mats.palmgren@bredband.net>
|
* Mats Palmgren <mats.palmgren@bredband.net>
|
||||||
|
* Takeshi Ichimaru <ayakawa.m@gmail.com>
|
||||||
|
* Masayuki Nakano <masayuki@d-toybox.com>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
@ -341,6 +343,9 @@ nscolor nsCSSRendering::MakeBevelColor(PRIntn whichSide, PRUint8 style,
|
|||||||
// Maximum poly points in any of the polygons we generate below
|
// Maximum poly points in any of the polygons we generate below
|
||||||
#define MAX_POLY_POINTS 4
|
#define MAX_POLY_POINTS 4
|
||||||
|
|
||||||
|
#define ACTUAL_THICKNESS(outside, inside, frac, tpp) \
|
||||||
|
(NSToCoordRound(((outside) - (inside)) * (frac) / (tpp)) * (tpp))
|
||||||
|
|
||||||
// a nifty helper function to create a polygon representing a
|
// a nifty helper function to create a polygon representing a
|
||||||
// particular side of a border. This helps localize code for figuring
|
// particular side of a border. This helps localize code for figuring
|
||||||
// mitered edges. It is mainly used by the solid, inset, and outset
|
// mitered edges. It is mainly used by the solid, inset, and outset
|
||||||
@ -350,17 +355,13 @@ nscolor nsCSSRendering::MakeBevelColor(PRIntn whichSide, PRUint8 style,
|
|||||||
// is one pixel), then a line with two endpoints is returned
|
// is one pixel), then a line with two endpoints is returned
|
||||||
PRIntn nsCSSRendering::MakeSide(nsPoint aPoints[],
|
PRIntn nsCSSRendering::MakeSide(nsPoint aPoints[],
|
||||||
nsIRenderingContext& aContext,
|
nsIRenderingContext& aContext,
|
||||||
PRIntn whichSide,
|
PRIntn aWhichSide,
|
||||||
const nsRect& outside, const nsRect& inside,
|
const nsRect& aOutside, const nsRect& aInside,
|
||||||
PRIntn aSkipSides,
|
PRIntn aSkipSides,
|
||||||
PRIntn borderPart, float borderFrac,
|
PRIntn aBorderPart, float aBorderFrac,
|
||||||
nscoord twipsPerPixel)
|
nscoord aTwipsPerPixel)
|
||||||
{
|
{
|
||||||
float borderRest = 1.0f - borderFrac;
|
nscoord outsideEdge, insideEdge, outsideTL, insideTL, outsideBR, insideBR;
|
||||||
|
|
||||||
PRIntn np = 0;
|
|
||||||
nscoord thickness, outsideEdge, insideEdge, outsideTL, insideTL, outsideBR,
|
|
||||||
insideBR;
|
|
||||||
|
|
||||||
// Initialize the following six nscoord's:
|
// Initialize the following six nscoord's:
|
||||||
// outsideEdge, insideEdge, outsideTL, insideTL, outsideBR, insideBR
|
// outsideEdge, insideEdge, outsideTL, insideTL, outsideBR, insideBR
|
||||||
@ -378,52 +379,52 @@ PRIntn nsCSSRendering::MakeSide(nsPoint aPoints[],
|
|||||||
// if we don't want the bevel, we'll get rid of it later by setting
|
// if we don't want the bevel, we'll get rid of it later by setting
|
||||||
// outsideXX to insideXX
|
// outsideXX to insideXX
|
||||||
|
|
||||||
switch (whichSide) {
|
switch (aWhichSide) {
|
||||||
case NS_SIDE_TOP:
|
case NS_SIDE_TOP:
|
||||||
// the TL points are the left end; the BR points are the right end
|
// the TL points are the left end; the BR points are the right end
|
||||||
outsideEdge = outside.y;
|
outsideEdge = aOutside.y;
|
||||||
insideEdge = inside.y;
|
insideEdge = aInside.y;
|
||||||
outsideTL = outside.x;
|
outsideTL = aOutside.x;
|
||||||
insideTL = inside.x;
|
insideTL = aInside.x;
|
||||||
insideBR = inside.XMost();
|
insideBR = aInside.XMost();
|
||||||
outsideBR = outside.XMost();
|
outsideBR = aOutside.XMost();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NS_SIDE_BOTTOM:
|
case NS_SIDE_BOTTOM:
|
||||||
// the TL points are the left end; the BR points are the right end
|
// the TL points are the left end; the BR points are the right end
|
||||||
outsideEdge = outside.YMost();
|
outsideEdge = aOutside.YMost();
|
||||||
insideEdge = inside.YMost();
|
insideEdge = aInside.YMost();
|
||||||
outsideTL = outside.x;
|
outsideTL = aOutside.x;
|
||||||
insideTL = inside.x;
|
insideTL = aInside.x;
|
||||||
insideBR = inside.XMost();
|
insideBR = aInside.XMost();
|
||||||
outsideBR = outside.XMost();
|
outsideBR = aOutside.XMost();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NS_SIDE_LEFT:
|
case NS_SIDE_LEFT:
|
||||||
// the TL points are the top end; the BR points are the bottom end
|
// the TL points are the top end; the BR points are the bottom end
|
||||||
outsideEdge = outside.x;
|
outsideEdge = aOutside.x;
|
||||||
insideEdge = inside.x;
|
insideEdge = aInside.x;
|
||||||
outsideTL = outside.y;
|
outsideTL = aOutside.y;
|
||||||
insideTL = inside.y;
|
insideTL = aInside.y;
|
||||||
insideBR = inside.YMost();
|
insideBR = aInside.YMost();
|
||||||
outsideBR = outside.YMost();
|
outsideBR = aOutside.YMost();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NS_ASSERTION(whichSide == NS_SIDE_RIGHT, "whichSide is not a valid side");
|
NS_ASSERTION(aWhichSide == NS_SIDE_RIGHT, "aWhichSide is not a valid side");
|
||||||
// the TL points are the top end; the BR points are the bottom end
|
// the TL points are the top end; the BR points are the bottom end
|
||||||
outsideEdge = outside.XMost();
|
outsideEdge = aOutside.XMost();
|
||||||
insideEdge = inside.XMost();
|
insideEdge = aInside.XMost();
|
||||||
outsideTL = outside.y;
|
outsideTL = aOutside.y;
|
||||||
insideTL = inside.y;
|
insideTL = aInside.y;
|
||||||
insideBR = inside.YMost();
|
insideBR = aInside.YMost();
|
||||||
outsideBR = outside.YMost();
|
outsideBR = aOutside.YMost();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't draw the bevels if an adjacent side is skipped
|
// Don't draw the bevels if an adjacent side is skipped
|
||||||
|
|
||||||
if ( (whichSide == NS_SIDE_TOP) || (whichSide == NS_SIDE_BOTTOM) ) {
|
if ( (aWhichSide == NS_SIDE_TOP) || (aWhichSide == NS_SIDE_BOTTOM) ) {
|
||||||
// a top or bottom side
|
// a top or bottom side
|
||||||
if ((1<<NS_SIDE_LEFT) & aSkipSides) {
|
if ((1<<NS_SIDE_LEFT) & aSkipSides) {
|
||||||
insideTL = outsideTL;
|
insideTL = outsideTL;
|
||||||
@ -441,55 +442,75 @@ PRIntn nsCSSRendering::MakeSide(nsPoint aPoints[],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// move things around when only drawing part of the border
|
nscoord fullThickness;
|
||||||
|
if (aWhichSide == NS_SIDE_TOP || aWhichSide == NS_SIDE_LEFT)
|
||||||
|
fullThickness = insideEdge - outsideEdge;
|
||||||
|
else
|
||||||
|
fullThickness = outsideEdge - insideEdge;
|
||||||
|
if (fullThickness != 0)
|
||||||
|
fullThickness = NS_MAX(fullThickness, aTwipsPerPixel);
|
||||||
|
|
||||||
if (borderPart == BORDER_INSIDE) {
|
nscoord thickness = fullThickness;
|
||||||
outsideEdge = nscoord(outsideEdge * borderFrac + insideEdge * borderRest);
|
if (aBorderFrac != 1.0f && fullThickness != 0) {
|
||||||
outsideTL = nscoord(outsideTL * borderFrac + insideTL * borderRest);
|
thickness = aTwipsPerPixel *
|
||||||
outsideBR = nscoord(outsideBR * borderFrac + insideBR * borderRest);
|
NS_MAX(NSToCoordRound(fullThickness * aBorderFrac / aTwipsPerPixel), 1);
|
||||||
} else if (borderPart == BORDER_OUTSIDE ) {
|
if ((aWhichSide == NS_SIDE_TOP) || (aWhichSide == NS_SIDE_LEFT)) {
|
||||||
insideEdge = nscoord(insideEdge * borderFrac + outsideEdge * borderRest);
|
if (aBorderPart == BORDER_INSIDE)
|
||||||
insideTL = nscoord(insideTL * borderFrac + outsideTL * borderRest);
|
outsideEdge = insideEdge - thickness;
|
||||||
insideBR = nscoord(insideBR * borderFrac + outsideBR * borderRest);
|
else if (aBorderPart == BORDER_OUTSIDE)
|
||||||
|
insideEdge = outsideEdge + thickness;
|
||||||
|
} else {
|
||||||
|
if (aBorderPart == BORDER_INSIDE)
|
||||||
|
outsideEdge = insideEdge + thickness;
|
||||||
|
else if (aBorderPart == BORDER_OUTSIDE)
|
||||||
|
insideEdge = outsideEdge - thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
float actualFrac = (float)thickness / (float)fullThickness;
|
||||||
|
if (aBorderPart == BORDER_INSIDE) {
|
||||||
|
outsideTL = insideTL +
|
||||||
|
ACTUAL_THICKNESS(outsideTL, insideTL, actualFrac, aTwipsPerPixel);
|
||||||
|
outsideBR = insideBR +
|
||||||
|
ACTUAL_THICKNESS(outsideBR, insideBR, actualFrac, aTwipsPerPixel);
|
||||||
|
} else if (aBorderPart == BORDER_OUTSIDE) {
|
||||||
|
insideTL = outsideTL -
|
||||||
|
ACTUAL_THICKNESS(outsideTL, insideTL, actualFrac, aTwipsPerPixel);
|
||||||
|
insideBR = outsideBR -
|
||||||
|
ACTUAL_THICKNESS(outsideBR, insideBR, actualFrac, aTwipsPerPixel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base our thickness check on the segment being less than a pixel and 1/2
|
// Base our thickness check on the segment being less than a pixel and 1/2
|
||||||
twipsPerPixel += twipsPerPixel >> 2;
|
aTwipsPerPixel += aTwipsPerPixel >> 2;
|
||||||
|
|
||||||
// find the thickness of the piece being drawn
|
|
||||||
if ((whichSide == NS_SIDE_TOP) || (whichSide == NS_SIDE_LEFT)) {
|
|
||||||
thickness = insideEdge - outsideEdge;
|
|
||||||
} else {
|
|
||||||
thickness = outsideEdge - insideEdge;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if returning a line, do it along inside edge for bottom or right borders
|
// if returning a line, do it along inside edge for bottom or right borders
|
||||||
// so that it's in the same place as it would be with polygons (why?)
|
// so that it's in the same place as it would be with polygons (why?)
|
||||||
// XXX The previous version of the code shortened the right border too.
|
// XXX The previous version of the code shortened the right border too.
|
||||||
if ( !((thickness >= twipsPerPixel) || (borderPart != BORDER_FULL)) &&
|
if ( !((thickness >= aTwipsPerPixel) || (aBorderPart != BORDER_FULL)) &&
|
||||||
((whichSide == NS_SIDE_BOTTOM) || (whichSide == NS_SIDE_RIGHT))) {
|
((aWhichSide == NS_SIDE_BOTTOM) || (aWhichSide == NS_SIDE_RIGHT))) {
|
||||||
outsideEdge = insideEdge;
|
outsideEdge = insideEdge;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the appropriate line or trapezoid
|
// return the appropriate line or trapezoid
|
||||||
if ((whichSide == NS_SIDE_TOP) || (whichSide == NS_SIDE_BOTTOM)) {
|
PRIntn np = 0;
|
||||||
|
if ((aWhichSide == NS_SIDE_TOP) || (aWhichSide == NS_SIDE_BOTTOM)) {
|
||||||
// top and bottom borders
|
// top and bottom borders
|
||||||
aPoints[np++].MoveTo(outsideTL,outsideEdge);
|
aPoints[np++].MoveTo(outsideTL,outsideEdge);
|
||||||
aPoints[np++].MoveTo(outsideBR,outsideEdge);
|
aPoints[np++].MoveTo(outsideBR,outsideEdge);
|
||||||
// XXX Making this condition only (thickness >= twipsPerPixel) will
|
// XXX Making this condition only (thickness >= aTwipsPerPixel) will
|
||||||
// improve double borders and some cases of groove/ridge,
|
// improve double borders and some cases of groove/ridge,
|
||||||
// but will cause problems with table borders. See last and third
|
// but will cause problems with table borders. See last and third
|
||||||
// from last tests in test4.htm
|
// from last tests in test4.htm
|
||||||
// Doing it this way emulates the old behavior. It might be worth
|
// Doing it this way emulates the old behavior. It might be worth
|
||||||
// fixing.
|
// fixing.
|
||||||
if ((thickness >= twipsPerPixel) || (borderPart != BORDER_FULL) ) {
|
if ((thickness >= aTwipsPerPixel) || (aBorderPart != BORDER_FULL)) {
|
||||||
aPoints[np++].MoveTo(insideBR,insideEdge);
|
aPoints[np++].MoveTo(insideBR,insideEdge);
|
||||||
aPoints[np++].MoveTo(insideTL,insideEdge);
|
aPoints[np++].MoveTo(insideTL,insideEdge);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// right and left borders
|
// right and left borders
|
||||||
// XXX Ditto above
|
// XXX Ditto above
|
||||||
if ((thickness >= twipsPerPixel) || (borderPart != BORDER_FULL) ) {
|
if ((thickness >= aTwipsPerPixel) || (aBorderPart != BORDER_FULL)) {
|
||||||
aPoints[np++].MoveTo(insideEdge,insideBR);
|
aPoints[np++].MoveTo(insideEdge,insideBR);
|
||||||
aPoints[np++].MoveTo(insideEdge,insideTL);
|
aPoints[np++].MoveTo(insideEdge,insideTL);
|
||||||
}
|
}
|
||||||
@ -1803,10 +1824,11 @@ void nsCSSRendering::PaintBorder(nsPresContext* aPresContext,
|
|||||||
for (cnt = 0; cnt < 4; cnt++) {
|
for (cnt = 0; cnt < 4; cnt++) {
|
||||||
PRUint8 side = sideOrder[cnt];
|
PRUint8 side = sideOrder[cnt];
|
||||||
|
|
||||||
|
// If a side needs a double/groove/ridge border but will be less than two
|
||||||
// If a side needs a double border but will be less than two pixels,
|
// pixels, force it to be solid (see bug 1781 and bug 310124).
|
||||||
// force it to be solid (see bug 1781).
|
if (aBorderStyle.GetBorderStyle(side) == NS_STYLE_BORDER_STYLE_DOUBLE ||
|
||||||
if (aBorderStyle.GetBorderStyle(side) == NS_STYLE_BORDER_STYLE_DOUBLE) {
|
aBorderStyle.GetBorderStyle(side) == NS_STYLE_BORDER_STYLE_GROOVE ||
|
||||||
|
aBorderStyle.GetBorderStyle(side) == NS_STYLE_BORDER_STYLE_RIDGE) {
|
||||||
nscoord widths[] = { border.top, border.right, border.bottom, border.left };
|
nscoord widths[] = { border.top, border.right, border.bottom, border.left };
|
||||||
forceSolid = (widths[side]/twipsPerPixel < 2);
|
forceSolid = (widths[side]/twipsPerPixel < 2);
|
||||||
} else
|
} else
|
||||||
|
Loading…
Reference in New Issue
Block a user