Compare commits
5
Commits
jsgc-refactor
...
3088
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5b2671f1e | ||
|
|
4249686af4 | ||
|
|
69ba22d624 | ||
|
|
4359582e67 | ||
|
|
fa06d2de31 |
No files matched your search
@@ -1737,7 +1737,9 @@ nsCSSRendering::PaintBackground(const PaintBGParams& aParams)
|
||||
}
|
||||
|
||||
static bool
|
||||
IsOpaqueBorderEdge(const nsStyleBorder& aBorder, mozilla::Side aSide)
|
||||
IsOpaqueBorderEdge(const nsStyleBorder& aBorder,
|
||||
const nsStyleColor& aColor,
|
||||
mozilla::Side aSide)
|
||||
{
|
||||
if (aBorder.GetComputedBorder().Side(aSide) == 0)
|
||||
return true;
|
||||
@@ -1759,25 +1761,20 @@ IsOpaqueBorderEdge(const nsStyleBorder& aBorder, mozilla::Side aSide)
|
||||
if (aBorder.mBorderImageSource.GetType() != eStyleImageType_Null)
|
||||
return false;
|
||||
|
||||
StyleComplexColor color = aBorder.mBorderColor[aSide];
|
||||
// We don't know the foreground color here, so if it's being used
|
||||
// we must assume it might be transparent.
|
||||
if (!color.IsNumericColor()) {
|
||||
return false;
|
||||
}
|
||||
return NS_GET_A(color.mColor) == 255;
|
||||
nscolor color = aColor.CalcComplexColor(aBorder.mBorderColor[aSide]);
|
||||
return NS_GET_A(color) == 255;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if all border edges are either missing or opaque.
|
||||
*/
|
||||
static bool
|
||||
IsOpaqueBorder(const nsStyleBorder& aBorder)
|
||||
IsOpaqueBorder(const nsStyleBorder& aBorder, const nsStyleColor& aColor)
|
||||
{
|
||||
if (aBorder.mBorderColors)
|
||||
return false;
|
||||
NS_FOR_CSS_SIDES(i) {
|
||||
if (!IsOpaqueBorderEdge(aBorder, i))
|
||||
if (!IsOpaqueBorderEdge(aBorder, aColor, i))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -1910,7 +1907,7 @@ nsCSSRendering::GetImageLayerClip(const nsStyleImageLayers::Layer& aLayer,
|
||||
}
|
||||
|
||||
bool isSolidBorder =
|
||||
aWillPaintBorder && IsOpaqueBorder(aBorder);
|
||||
aWillPaintBorder && IsOpaqueBorder(aBorder, *aForFrame->StyleColor());
|
||||
if (isSolidBorder && layerClip == StyleGeometryBox::Border) {
|
||||
// If we have rounded corners, we need to inflate the background
|
||||
// drawing area a bit to avoid seams between the border and
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
:root {
|
||||
--color: #fff;
|
||||
background: var(--color);
|
||||
color: var(--color);
|
||||
}
|
||||
div {
|
||||
display: block;
|
||||
width: 51px;
|
||||
height: 51px;
|
||||
border-radius: 50%;
|
||||
background-color: #323232;
|
||||
border: 10px solid var(--color);
|
||||
}
|
||||
</style>
|
||||
<div></div>
|
||||
@@ -0,0 +1,18 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
:root {
|
||||
--color: #fff;
|
||||
background: var(--color);
|
||||
color: var(--color);
|
||||
}
|
||||
div {
|
||||
display: block;
|
||||
width: 51px;
|
||||
height: 51px;
|
||||
border-radius: 50%;
|
||||
background-color: #323232;
|
||||
border: 10px solid currentcolor;
|
||||
}
|
||||
</style>
|
||||
<div></div>
|
||||
@@ -89,6 +89,8 @@ fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||/^Windows\x20NT\x206\.2/.te
|
||||
# Test for antialiasing gaps between background and border
|
||||
fuzzy-if(gtkWidget,1,9) fuzzy-if(winWidget&&!d2d,1,9) fuzzy-if(d2d,5,40) fuzzy-if(skiaContent,1,9) == curved-border-background-nogap.html curved-border-background-nogap-ref.html
|
||||
|
||||
== currentcolor-border-radius.html currentcolor-border-radius-ref.html
|
||||
|
||||
== color-layer-1a.html color-layer-1-ref.html
|
||||
|
||||
== corner-split.html corner-split-ref.svg # bug 1185636
|
||||
@@ -1273,7 +1273,8 @@ CSS_PROP_SHORTHAND(
|
||||
border_width,
|
||||
BorderWidth,
|
||||
CSS_PROPERTY_PARSE_FUNCTION |
|
||||
CSS_PROPERTY_UNITLESS_LENGTH_QUIRK,
|
||||
CSS_PROPERTY_UNITLESS_LENGTH_QUIRK |
|
||||
CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH,
|
||||
"")
|
||||
CSS_PROP_POSITION(
|
||||
bottom,
|
||||
|
||||
@@ -3193,6 +3193,66 @@ nsComputedDOMStyle::DoGetBorderRightWidth()
|
||||
return GetBorderWidthFor(eSideRight);
|
||||
}
|
||||
|
||||
already_AddRefed<CSSValue>
|
||||
nsComputedDOMStyle::DoGetBorderWidth()
|
||||
{
|
||||
nscoord widths[4];
|
||||
if (mInnerFrame) {
|
||||
AssertFlushedPendingReflows();
|
||||
const nsMargin& usedBorder = mInnerFrame->GetUsedBorder();
|
||||
NS_FOR_CSS_SIDES(side) {
|
||||
widths[side] = usedBorder.Side(side);
|
||||
}
|
||||
} else {
|
||||
const nsStyleBorder* border = StyleBorder();
|
||||
NS_FOR_CSS_SIDES(side) {
|
||||
widths[side] = border->GetComputedBorderWidth(side);
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
|
||||
|
||||
RefPtr<nsROCSSPrimitiveValue> top = new nsROCSSPrimitiveValue;
|
||||
top->SetAppUnits(widths[eSideTop]);
|
||||
valueList->AppendCSSValue(top.forget());
|
||||
|
||||
if (widths[eSideRight] == widths[eSideLeft]) {
|
||||
if (widths[eSideTop] == widths[eSideBottom]) {
|
||||
if (widths[eSideTop] == widths[eSideRight]) {
|
||||
return valueList.forget();
|
||||
}
|
||||
|
||||
RefPtr<nsROCSSPrimitiveValue> right = new nsROCSSPrimitiveValue;
|
||||
right->SetAppUnits(widths[eSideRight]);
|
||||
valueList->AppendCSSValue(right.forget());
|
||||
return valueList.forget();
|
||||
}
|
||||
|
||||
RefPtr<nsROCSSPrimitiveValue> right = new nsROCSSPrimitiveValue;
|
||||
right->SetAppUnits(widths[eSideRight]);
|
||||
valueList->AppendCSSValue(right.forget());
|
||||
|
||||
RefPtr<nsROCSSPrimitiveValue> bottom = new nsROCSSPrimitiveValue;
|
||||
bottom->SetAppUnits(widths[eSideBottom]);
|
||||
valueList->AppendCSSValue(bottom.forget());
|
||||
return valueList.forget();
|
||||
}
|
||||
|
||||
RefPtr<nsROCSSPrimitiveValue> right = new nsROCSSPrimitiveValue;
|
||||
right->SetAppUnits(widths[eSideRight]);
|
||||
valueList->AppendCSSValue(right.forget());
|
||||
|
||||
RefPtr<nsROCSSPrimitiveValue> bottom = new nsROCSSPrimitiveValue;
|
||||
bottom->SetAppUnits(widths[eSideBottom]);
|
||||
valueList->AppendCSSValue(bottom.forget());
|
||||
|
||||
RefPtr<nsROCSSPrimitiveValue> left = new nsROCSSPrimitiveValue;
|
||||
left->SetAppUnits(widths[eSideLeft]);
|
||||
valueList->AppendCSSValue(left.forget());
|
||||
|
||||
return valueList.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CSSValue>
|
||||
nsComputedDOMStyle::DoGetBorderTopColor()
|
||||
{
|
||||
@@ -6843,4 +6903,3 @@ nsComputedDOMStyle::DoGetOverflowBlockEnd()
|
||||
return DoGetOverflowBlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -344,6 +344,7 @@ private:
|
||||
already_AddRefed<CSSValue> DoGetBorderBottomWidth();
|
||||
already_AddRefed<CSSValue> DoGetBorderLeftWidth();
|
||||
already_AddRefed<CSSValue> DoGetBorderRightWidth();
|
||||
already_AddRefed<CSSValue> DoGetBorderWidth();
|
||||
already_AddRefed<CSSValue> DoGetBorderTopColor();
|
||||
already_AddRefed<CSSValue> DoGetBorderBottomColor();
|
||||
already_AddRefed<CSSValue> DoGetBorderLeftColor();
|
||||
|
||||
@@ -95,7 +95,7 @@ COMPUTED_STYLE_PROP(border_top_left_radius, BorderTopLeftRadius)
|
||||
COMPUTED_STYLE_PROP(border_top_right_radius, BorderTopRightRadius)
|
||||
COMPUTED_STYLE_PROP(border_top_style, BorderTopStyle)
|
||||
COMPUTED_STYLE_PROP(border_top_width, BorderTopWidth)
|
||||
//// COMPUTED_STYLE_PROP(border_width, BorderWidth)
|
||||
COMPUTED_STYLE_PROP(border_width, BorderWidth)
|
||||
COMPUTED_STYLE_PROP(bottom, Bottom)
|
||||
COMPUTED_STYLE_PROP(box_decoration_break, BoxDecorationBreak)
|
||||
COMPUTED_STYLE_PROP(box_shadow, BoxShadow)
|
||||
|
||||
+128
-22
@@ -319,6 +319,11 @@ nsRuleNode::EnsureInlineDisplay(StyleDisplay& display)
|
||||
}
|
||||
}
|
||||
|
||||
enum class AppUnitRounding {
|
||||
Default,
|
||||
TowardZero
|
||||
};
|
||||
|
||||
static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
||||
nscoord aFontSize,
|
||||
const nsStyleFont* aStyleFont,
|
||||
@@ -326,7 +331,9 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
||||
nsPresContext* aPresContext,
|
||||
bool aUseProvidedRootEmSize,
|
||||
bool aUseUserFontSet,
|
||||
RuleNodeCacheConditions& aConditions);
|
||||
RuleNodeCacheConditions& aConditions,
|
||||
AppUnitRounding aRounding =
|
||||
AppUnitRounding::Default);
|
||||
|
||||
struct CalcLengthCalcOps : public css::BasicCoordCalcOps,
|
||||
public css::NumbersAlreadyNormalizedOps
|
||||
@@ -339,18 +346,21 @@ struct CalcLengthCalcOps : public css::BasicCoordCalcOps,
|
||||
const bool mUseProvidedRootEmSize;
|
||||
const bool mUseUserFontSet;
|
||||
RuleNodeCacheConditions& mConditions;
|
||||
const AppUnitRounding mRounding;
|
||||
|
||||
CalcLengthCalcOps(nscoord aFontSize, const nsStyleFont* aStyleFont,
|
||||
nsStyleContext* aStyleContext, nsPresContext* aPresContext,
|
||||
bool aUseProvidedRootEmSize, bool aUseUserFontSet,
|
||||
RuleNodeCacheConditions& aConditions)
|
||||
RuleNodeCacheConditions& aConditions,
|
||||
AppUnitRounding aRounding)
|
||||
: mFontSize(aFontSize),
|
||||
mStyleFont(aStyleFont),
|
||||
mStyleContext(aStyleContext),
|
||||
mPresContext(aPresContext),
|
||||
mUseProvidedRootEmSize(aUseProvidedRootEmSize),
|
||||
mUseUserFontSet(aUseUserFontSet),
|
||||
mConditions(aConditions)
|
||||
mConditions(aConditions),
|
||||
mRounding(aRounding)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -358,15 +368,84 @@ struct CalcLengthCalcOps : public css::BasicCoordCalcOps,
|
||||
{
|
||||
return CalcLengthWith(aValue, mFontSize, mStyleFont,
|
||||
mStyleContext, mPresContext, mUseProvidedRootEmSize,
|
||||
mUseUserFontSet, mConditions);
|
||||
mUseUserFontSet, mConditions, mRounding);
|
||||
}
|
||||
};
|
||||
|
||||
static inline nscoord ScaleCoordRound(const nsCSSValue& aValue, float aFactor)
|
||||
static inline nscoord
|
||||
ScaleCoordWithRounding(const nsCSSValue& aValue, float aFactor,
|
||||
AppUnitRounding aRounding)
|
||||
{
|
||||
if (aRounding == AppUnitRounding::TowardZero) {
|
||||
return NSToCoordTruncClamped(aValue.GetFloatValue() * aFactor);
|
||||
}
|
||||
return NSToCoordRoundWithClamp(aValue.GetFloatValue() * aFactor);
|
||||
}
|
||||
|
||||
static inline nscoord
|
||||
CSSPixelsToAppUnitsWithRounding(float aPixels, AppUnitRounding aRounding)
|
||||
{
|
||||
if (aRounding == AppUnitRounding::TowardZero) {
|
||||
return NSToCoordTruncClamped(double(aPixels) *
|
||||
nsPresContext::AppUnitsPerCSSPixel());
|
||||
}
|
||||
return nsPresContext::CSSPixelsToAppUnits(aPixels);
|
||||
}
|
||||
|
||||
static nscoord
|
||||
GetFixedLengthWithRounding(const nsCSSValue& aValue,
|
||||
nsPresContext* aPresContext,
|
||||
AppUnitRounding aRounding)
|
||||
{
|
||||
if (aRounding == AppUnitRounding::Default) {
|
||||
return aValue.GetFixedLength(aPresContext);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_PhysicalMillimeter,
|
||||
"not a fixed length unit");
|
||||
double inches = double(aValue.GetFloatValue()) / MM_PER_INCH_FLOAT;
|
||||
return NSToCoordTruncClamped(
|
||||
inches * aPresContext->DeviceContext()->AppUnitsPerPhysicalInch());
|
||||
}
|
||||
|
||||
static nscoord
|
||||
GetPixelLengthWithRounding(const nsCSSValue& aValue,
|
||||
AppUnitRounding aRounding)
|
||||
{
|
||||
MOZ_ASSERT(aValue.IsPixelLengthUnit(), "not a pixel length unit");
|
||||
|
||||
double scaleFactor;
|
||||
switch (aValue.GetUnit()) {
|
||||
case eCSSUnit_Pixel:
|
||||
return CSSPixelsToAppUnitsWithRounding(aValue.GetFloatValue(),
|
||||
aRounding);
|
||||
case eCSSUnit_Pica:
|
||||
scaleFactor = 16.0;
|
||||
break;
|
||||
case eCSSUnit_Point:
|
||||
scaleFactor = 4.0 / 3.0;
|
||||
break;
|
||||
case eCSSUnit_Inch:
|
||||
scaleFactor = 96.0;
|
||||
break;
|
||||
case eCSSUnit_Millimeter:
|
||||
scaleFactor = 96.0 / 25.4;
|
||||
break;
|
||||
case eCSSUnit_Centimeter:
|
||||
scaleFactor = 96.0 / 2.54;
|
||||
break;
|
||||
case eCSSUnit_Quarter:
|
||||
scaleFactor = 96.0 / 101.6;
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("should never get here");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CSSPixelsToAppUnitsWithRounding(
|
||||
float(double(aValue.GetFloatValue()) * scaleFactor), aRounding);
|
||||
}
|
||||
|
||||
static inline nscoord ScaleViewportCoordTrunc(const nsCSSValue& aValue,
|
||||
nscoord aViewportSize)
|
||||
{
|
||||
@@ -465,7 +544,8 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
||||
// except when called from
|
||||
// CalcLengthWithInitialFont.
|
||||
bool aUseUserFontSet,
|
||||
RuleNodeCacheConditions& aConditions)
|
||||
RuleNodeCacheConditions& aConditions,
|
||||
AppUnitRounding aRounding)
|
||||
{
|
||||
NS_ASSERTION(aValue.IsLengthUnit() || aValue.IsCalcUnit(),
|
||||
"not a length or calc unit");
|
||||
@@ -476,10 +556,10 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
||||
NS_ASSERTION(aPresContext, "Must have prescontext");
|
||||
|
||||
if (aValue.IsFixedLengthUnit()) {
|
||||
return aValue.GetFixedLength(aPresContext);
|
||||
return GetFixedLengthWithRounding(aValue, aPresContext, aRounding);
|
||||
}
|
||||
if (aValue.IsPixelLengthUnit()) {
|
||||
return aValue.GetPixelLength();
|
||||
return GetPixelLengthWithRounding(aValue, aRounding);
|
||||
}
|
||||
if (aValue.IsCalcUnit()) {
|
||||
// For properties for which lengths are the *only* units accepted in
|
||||
@@ -490,7 +570,7 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
||||
CalcLengthCalcOps ops(aFontSize, aStyleFont,
|
||||
aStyleContext, aPresContext,
|
||||
aUseProvidedRootEmSize, aUseUserFontSet,
|
||||
aConditions);
|
||||
aConditions, aRounding);
|
||||
return css::ComputeCalc(aValue, ops);
|
||||
}
|
||||
switch (aValue.GetUnit()) {
|
||||
@@ -623,7 +703,7 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
||||
rootFontSize = rootStyleFont->mFont.size;
|
||||
}
|
||||
|
||||
return ScaleCoordRound(aValue, float(rootFontSize));
|
||||
return ScaleCoordWithRounding(aValue, float(rootFontSize), aRounding);
|
||||
}
|
||||
default:
|
||||
// Fall through to the code for units that can't be stored in the
|
||||
@@ -648,7 +728,7 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
||||
// CSS2.1 specifies that this unit scales to the computed font
|
||||
// size, not the em-width in the font metrics, despite the name.
|
||||
aConditions.SetFontSizeDependency(aFontSize);
|
||||
return ScaleCoordRound(aValue, float(aFontSize));
|
||||
return ScaleCoordWithRounding(aValue, float(aFontSize), aRounding);
|
||||
}
|
||||
case eCSSUnit_XHeight: {
|
||||
aPresContext->SetUsesExChUnits(true);
|
||||
@@ -656,7 +736,7 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
||||
GetMetricsFor(aPresContext, aStyleContext, styleFont,
|
||||
aFontSize, aUseUserFontSet);
|
||||
aConditions.SetUncacheable();
|
||||
return ScaleCoordRound(aValue, float(fm->XHeight()));
|
||||
return ScaleCoordWithRounding(aValue, float(fm->XHeight()), aRounding);
|
||||
}
|
||||
case eCSSUnit_Char: {
|
||||
aPresContext->SetUsesExChUnits(true);
|
||||
@@ -668,8 +748,9 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
||||
GetMetrics(fm->Orientation()).zeroOrAveCharWidth;
|
||||
|
||||
aConditions.SetUncacheable();
|
||||
return ScaleCoordRound(aValue, ceil(aPresContext->AppUnitsPerDevPixel() *
|
||||
zeroWidth));
|
||||
return ScaleCoordWithRounding(
|
||||
aValue, ceil(aPresContext->AppUnitsPerDevPixel() * zeroWidth),
|
||||
aRounding);
|
||||
}
|
||||
default:
|
||||
NS_NOTREACHED("unexpected unit");
|
||||
@@ -701,6 +782,20 @@ static inline nscoord CalcLength(const nsCSSValue& aValue,
|
||||
aPresContext, aConditions);
|
||||
}
|
||||
|
||||
static inline nscoord
|
||||
CalcLengthTowardZero(const nsCSSValue& aValue,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsPresContext* aPresContext,
|
||||
RuleNodeCacheConditions& aConditions)
|
||||
{
|
||||
NS_ASSERTION(aStyleContext, "Must have style data");
|
||||
|
||||
return CalcLengthWith(aValue, -1, nullptr,
|
||||
aStyleContext, aPresContext,
|
||||
false, true, aConditions,
|
||||
AppUnitRounding::TowardZero);
|
||||
}
|
||||
|
||||
/* static */ nscoord
|
||||
nsRuleNode::CalcLengthWithInitialFont(nsPresContext* aPresContext,
|
||||
const nsCSSValue& aValue)
|
||||
@@ -8018,13 +8113,11 @@ nsRuleNode::ComputeBorderData(void* aStartStruct,
|
||||
"Unexpected enum value");
|
||||
border->SetBorderWidth(side,
|
||||
(mPresContext->GetBorderWidthTable())[value.GetIntValue()]);
|
||||
// OK to pass bad aParentCoord since we're not passing SETCOORD_INHERIT
|
||||
} else if (SetCoord(value, coord, nsStyleCoord(),
|
||||
SETCOORD_LENGTH | SETCOORD_CALC_LENGTH_ONLY,
|
||||
aContext, mPresContext, conditions)) {
|
||||
NS_ASSERTION(coord.GetUnit() == eStyleUnit_Coord, "unexpected unit");
|
||||
} else if (value.IsLengthUnit() || value.IsCalcUnit()) {
|
||||
// clamp negative calc() to 0.
|
||||
border->SetBorderWidth(side, std::max(coord.GetCoordValue(), 0));
|
||||
border->SetBorderWidth(side,
|
||||
std::max(CalcLengthTowardZero(value, aContext, mPresContext,
|
||||
conditions), 0));
|
||||
} else if (eCSSUnit_Inherit == value.GetUnit()) {
|
||||
conditions.SetUncacheable();
|
||||
border->SetBorderWidth(side,
|
||||
@@ -8302,6 +8395,11 @@ nsRuleNode::ComputeOutlineData(void* aStartStruct,
|
||||
eCSSUnit_Revert == outlineWidthValue->GetUnit()) {
|
||||
outline->mOutlineWidth =
|
||||
nsStyleCoord(NS_STYLE_BORDER_WIDTH_MEDIUM, eStyleUnit_Enumerated);
|
||||
} else if (outlineWidthValue->IsLengthUnit() ||
|
||||
outlineWidthValue->IsCalcUnit()) {
|
||||
outline->mOutlineWidth.SetCoordValue(
|
||||
CalcLengthTowardZero(*outlineWidthValue, aContext, mPresContext,
|
||||
conditions));
|
||||
} else {
|
||||
SetCoord(*outlineWidthValue, outline->mOutlineWidth,
|
||||
parentOutline->mOutlineWidth,
|
||||
@@ -8312,13 +8410,21 @@ nsRuleNode::ComputeOutlineData(void* aStartStruct,
|
||||
// outline-offset: length, inherit
|
||||
nsStyleCoord tempCoord;
|
||||
const nsCSSValue* outlineOffsetValue = aRuleData->ValueForOutlineOffset();
|
||||
if (SetCoord(*outlineOffsetValue, tempCoord,
|
||||
if (outlineOffsetValue->IsLengthUnit() || outlineOffsetValue->IsCalcUnit()) {
|
||||
outline->mOutlineOffset =
|
||||
NS_ROUND_OFFSET_TO_PIXELS(
|
||||
CalcLengthTowardZero(*outlineOffsetValue, aContext, mPresContext,
|
||||
conditions),
|
||||
mPresContext->AppUnitsPerDevPixel());
|
||||
} else if (SetCoord(*outlineOffsetValue, tempCoord,
|
||||
nsStyleCoord(parentOutline->mOutlineOffset,
|
||||
nsStyleCoord::CoordConstructor),
|
||||
SETCOORD_LH | SETCOORD_INITIAL_ZERO | SETCOORD_CALC_LENGTH_ONLY |
|
||||
SETCOORD_UNSET_INITIAL,
|
||||
aContext, mPresContext, conditions)) {
|
||||
outline->mOutlineOffset = tempCoord.GetCoordValue();
|
||||
outline->mOutlineOffset =
|
||||
NS_ROUND_OFFSET_TO_PIXELS(tempCoord.GetCoordValue(),
|
||||
mPresContext->AppUnitsPerDevPixel());
|
||||
} else {
|
||||
NS_ASSERTION(outlineOffsetValue->GetUnit() == eCSSUnit_Null,
|
||||
"unexpected unit");
|
||||
|
||||
@@ -1145,21 +1145,19 @@ private:
|
||||
nsCSSShadowItem mArray[1]; // This MUST be the last item
|
||||
};
|
||||
|
||||
// Border widths are rounded to the nearest integer number of pixels, but values
|
||||
// between zero and one device pixels are always rounded up to one device pixel.
|
||||
// Border widths are rounded down to integer pixels, but values between zero and
|
||||
// one device pixel are always rounded up to one device pixel.
|
||||
#define NS_ROUND_BORDER_TO_PIXELS(l,tpp) \
|
||||
((l) == 0) ? 0 : std::max((tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp))
|
||||
(((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp)))
|
||||
// Caret widths are rounded to the nearest-below integer number of pixels, but values
|
||||
// between zero and one device pixels are always rounded up to one device pixel.
|
||||
#define NS_ROUND_CARET_TO_PIXELS(l,tpp) \
|
||||
((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp))
|
||||
// Outline offset is rounded to the nearest integer number of pixels, but values
|
||||
// between zero and one device pixels are always rounded up to one device pixel.
|
||||
// Note that the offset can be negative.
|
||||
NS_ROUND_BORDER_TO_PIXELS(l,tpp)
|
||||
// Outline offset is snapped like border widths, preserving the sign.
|
||||
#define NS_ROUND_OFFSET_TO_PIXELS(l,tpp) \
|
||||
(((l) == 0) ? 0 : \
|
||||
((l) > 0) ? std::max( (tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp)) : \
|
||||
std::min(-(tpp), ((l) - ((tpp) / 2)) / (tpp) * (tpp)))
|
||||
(((l) > 0) ? NS_ROUND_BORDER_TO_PIXELS((l), (tpp)) : \
|
||||
std::min(-(tpp), (l) / (tpp) * (tpp))))
|
||||
|
||||
// Returns if the given border style type is visible or not
|
||||
static bool IsVisibleBorderStyle(uint8_t aStyle)
|
||||
|
||||
@@ -75,6 +75,7 @@ support-files = file_animations_with_disabled_properties.html
|
||||
[test_nesting_flattening_parser_edges.html]
|
||||
[test_nesting_flattening_recovery.html]
|
||||
[test_box_size_keywords.html]
|
||||
[test_border_width_rounding.html]
|
||||
[test_bug73586.html]
|
||||
[test_bug74880.html]
|
||||
[test_bug98997.html]
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test fractional border and outline width rounding</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="display"></div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var display = document.getElementById("display");
|
||||
|
||||
var tests = [
|
||||
["0px", "0px"],
|
||||
["0.1px", "1px"],
|
||||
["0.25px", "1px"],
|
||||
["0.5px", "1px"],
|
||||
["0.9px", "1px"],
|
||||
["1px", "1px"],
|
||||
["1.25px", "1px"],
|
||||
["1.5px", "1px"],
|
||||
["2px", "2px"],
|
||||
["2.75px", "2px"],
|
||||
["2.999px", "2px"],
|
||||
["3px", "3px"],
|
||||
["3.001px", "3px"],
|
||||
];
|
||||
|
||||
function checkWidth(property, setupProperty, setupValue) {
|
||||
tests.forEach(function(test) {
|
||||
var specified = test[0];
|
||||
var expected = test[1];
|
||||
var div = document.createElement("div");
|
||||
div.style[setupProperty] = setupValue;
|
||||
div.style[property] = specified;
|
||||
display.appendChild(div);
|
||||
|
||||
is(document.defaultView.getComputedStyle(div, "")[property], expected,
|
||||
property + " computes " + specified + " as " + expected);
|
||||
|
||||
display.removeChild(div);
|
||||
});
|
||||
}
|
||||
|
||||
function checkOffset(property) {
|
||||
tests.forEach(function(test) {
|
||||
var specified = test[0];
|
||||
var expected = test[1];
|
||||
var div = document.createElement("div");
|
||||
div.style[property] = specified;
|
||||
display.appendChild(div);
|
||||
|
||||
is(document.defaultView.getComputedStyle(div, "")[property], expected,
|
||||
property + " computes " + specified + " as " + expected);
|
||||
|
||||
display.removeChild(div);
|
||||
});
|
||||
|
||||
tests.forEach(function(test) {
|
||||
var specified = test[0];
|
||||
var expected = test[0] == "0px" ? "0px" : "-" + test[1];
|
||||
var div = document.createElement("div");
|
||||
div.style[property] = "-" + specified;
|
||||
display.appendChild(div);
|
||||
|
||||
is(document.defaultView.getComputedStyle(div, "")[property], expected,
|
||||
property + " computes -" + specified + " as " + expected);
|
||||
|
||||
display.removeChild(div);
|
||||
});
|
||||
}
|
||||
|
||||
checkWidth("borderWidth", "borderStyle", "solid");
|
||||
checkWidth("outlineWidth", "outlineStyle", "solid");
|
||||
checkOffset("outlineOffset");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user