mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 12:55:46 +00:00
Change storage of background-size and background-position to allow percentages and lengths. (Bug 594934) r=bzbarsky a=blocking2.0:betaN
This commit is contained in:
parent
c5db5e47e4
commit
04ad76518f
@ -881,23 +881,17 @@ ComputeBackgroundAnchorPoint(const nsStyleBackground::Layer& aLayer,
|
||||
nsPoint* aTopLeft,
|
||||
nsPoint* aAnchorPoint)
|
||||
{
|
||||
if (!aLayer.mPosition.mXIsPercent) {
|
||||
aTopLeft->x = aAnchorPoint->x = aLayer.mPosition.mXPosition.mCoord;
|
||||
}
|
||||
else {
|
||||
double percent = aLayer.mPosition.mXPosition.mFloat;
|
||||
aAnchorPoint->x = NSToCoordRound(percent*aOriginBounds.width);
|
||||
aTopLeft->x = NSToCoordRound(percent*(aOriginBounds.width - aImageSize.width));
|
||||
}
|
||||
double percentX = aLayer.mPosition.mXPosition.mPercent;
|
||||
nscoord lengthX = aLayer.mPosition.mXPosition.mLength;
|
||||
aAnchorPoint->x = lengthX + NSToCoordRound(percentX*aOriginBounds.width);
|
||||
aTopLeft->x = lengthX +
|
||||
NSToCoordRound(percentX*(aOriginBounds.width - aImageSize.width));
|
||||
|
||||
if (!aLayer.mPosition.mYIsPercent) {
|
||||
aTopLeft->y = aAnchorPoint->y = aLayer.mPosition.mYPosition.mCoord;
|
||||
}
|
||||
else {
|
||||
double percent = aLayer.mPosition.mYPosition.mFloat;
|
||||
aAnchorPoint->y = NSToCoordRound(percent*aOriginBounds.height);
|
||||
aTopLeft->y = NSToCoordRound(percent*(aOriginBounds.height - aImageSize.height));
|
||||
}
|
||||
double percentY = aLayer.mPosition.mYPosition.mPercent;
|
||||
nscoord lengthY = aLayer.mPosition.mYPosition.mLength;
|
||||
aAnchorPoint->y = lengthY + NSToCoordRound(percentY*aOriginBounds.height);
|
||||
aTopLeft->y = lengthY +
|
||||
NSToCoordRound(percentY*(aOriginBounds.height - aImageSize.height));
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
@ -2303,15 +2297,15 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
static inline float
|
||||
ScaleDimension(nsStyleBackground::Size::Dimension aDimension,
|
||||
ScaleDimension(const nsStyleBackground::Size::Dimension& aDimension,
|
||||
PRUint8 aType,
|
||||
nscoord aLength, nscoord aAvailLength)
|
||||
{
|
||||
switch (aType) {
|
||||
case nsStyleBackground::Size::ePercentage:
|
||||
return double(aDimension.mFloat) * (double(aAvailLength) / double(aLength));
|
||||
case nsStyleBackground::Size::eLength:
|
||||
return double(aDimension.mCoord) / double(aLength);
|
||||
case nsStyleBackground::Size::eLengthPercentage:
|
||||
return (double(aDimension.mPercent) * double(aAvailLength) +
|
||||
double(aDimension.mLength)) /
|
||||
double(aLength);
|
||||
default:
|
||||
NS_ABORT_IF_FALSE(PR_FALSE, "bad aDimension.mType");
|
||||
return 1.0f;
|
||||
|
@ -1719,16 +1719,20 @@ nsComputedDOMStyle::DoGetBackgroundPosition(nsIDOMCSSValue** aValue)
|
||||
|
||||
const nsStyleBackground::Position &pos = bg->mLayers[i].mPosition;
|
||||
|
||||
if (pos.mXIsPercent) {
|
||||
valX->SetPercent(pos.mXPosition.mFloat);
|
||||
if (pos.mXPosition.mLength != 0) {
|
||||
NS_ABORT_IF_FALSE(pos.mXPosition.mPercent == 0.0f,
|
||||
"can't have both until calc() implemented");
|
||||
valX->SetAppUnits(pos.mXPosition.mLength);
|
||||
} else {
|
||||
valX->SetAppUnits(pos.mXPosition.mCoord);
|
||||
valX->SetPercent(pos.mXPosition.mPercent);
|
||||
}
|
||||
|
||||
if (pos.mYIsPercent) {
|
||||
valY->SetPercent(pos.mYPosition.mFloat);
|
||||
if (pos.mYPosition.mLength != 0) {
|
||||
NS_ABORT_IF_FALSE(pos.mYPosition.mPercent == 0.0f,
|
||||
"can't have both until calc() implemented");
|
||||
valY->SetAppUnits(pos.mYPosition.mLength);
|
||||
} else {
|
||||
valY->SetAppUnits(pos.mYPosition.mCoord);
|
||||
valY->SetPercent(pos.mYPosition.mPercent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1796,22 +1800,32 @@ nsComputedDOMStyle::DoGetMozBackgroundSize(nsIDOMCSSValue** aValue)
|
||||
|
||||
if (size.mWidthType == nsStyleBackground::Size::eAuto) {
|
||||
valX->SetIdent(eCSSKeyword_auto);
|
||||
} else if (size.mWidthType == nsStyleBackground::Size::ePercentage) {
|
||||
valX->SetPercent(size.mWidth.mFloat);
|
||||
} else {
|
||||
NS_ABORT_IF_FALSE(size.mWidthType == nsStyleBackground::Size::eLength,
|
||||
NS_ABORT_IF_FALSE(size.mWidthType ==
|
||||
nsStyleBackground::Size::eLengthPercentage,
|
||||
"bad mWidthType");
|
||||
valX->SetAppUnits(size.mWidth.mCoord);
|
||||
if (size.mWidth.mLength != 0) {
|
||||
NS_ABORT_IF_FALSE(size.mWidth.mPercent == 0.0f,
|
||||
"can't have both until calc() implemented");
|
||||
valX->SetAppUnits(size.mWidth.mLength);
|
||||
} else {
|
||||
valX->SetPercent(size.mWidth.mPercent);
|
||||
}
|
||||
}
|
||||
|
||||
if (size.mHeightType == nsStyleBackground::Size::eAuto) {
|
||||
valY->SetIdent(eCSSKeyword_auto);
|
||||
} else if (size.mHeightType == nsStyleBackground::Size::ePercentage) {
|
||||
valY->SetPercent(size.mHeight.mFloat);
|
||||
} else {
|
||||
NS_ABORT_IF_FALSE(size.mHeightType == nsStyleBackground::Size::eLength,
|
||||
NS_ABORT_IF_FALSE(size.mHeightType ==
|
||||
nsStyleBackground::Size::eLengthPercentage,
|
||||
"bad mHeightType");
|
||||
valY->SetAppUnits(size.mHeight.mCoord);
|
||||
if (size.mHeight.mLength != 0) {
|
||||
NS_ABORT_IF_FALSE(size.mHeight.mPercent == 0.0f,
|
||||
"can't have both until calc() implemented");
|
||||
valY->SetAppUnits(size.mHeight.mLength);
|
||||
} else {
|
||||
valY->SetPercent(size.mHeight.mPercent);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -4461,16 +4461,13 @@ struct BackgroundPositionAxis {
|
||||
nsCSSValue nsCSSValuePairList::*specified;
|
||||
nsStyleBackground::Position::PositionCoord
|
||||
nsStyleBackground::Position::*result;
|
||||
PRPackedBool nsStyleBackground::Position::*isPercent;
|
||||
};
|
||||
|
||||
static const BackgroundPositionAxis gBGPosAxes[] = {
|
||||
{ &nsCSSValuePairList::mXValue,
|
||||
&nsStyleBackground::Position::mXPosition,
|
||||
&nsStyleBackground::Position::mXIsPercent },
|
||||
&nsStyleBackground::Position::mXPosition },
|
||||
{ &nsCSSValuePairList::mYValue,
|
||||
&nsStyleBackground::Position::mYPosition,
|
||||
&nsStyleBackground::Position::mYIsPercent }
|
||||
&nsStyleBackground::Position::mYPosition }
|
||||
};
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
@ -4487,19 +4484,19 @@ struct BackgroundItemComputer<nsCSSValuePairList, nsStyleBackground::Position>
|
||||
axis != axis_end; ++axis) {
|
||||
const nsCSSValue &specified = aSpecifiedValue->*(axis->specified);
|
||||
if (eCSSUnit_Percent == specified.GetUnit()) {
|
||||
(position.*(axis->result)).mFloat = specified.GetPercentValue();
|
||||
position.*(axis->isPercent) = PR_TRUE;
|
||||
(position.*(axis->result)).mLength = 0;
|
||||
(position.*(axis->result)).mPercent = specified.GetPercentValue();
|
||||
}
|
||||
else if (specified.IsLengthUnit()) {
|
||||
(position.*(axis->result)).mCoord =
|
||||
(position.*(axis->result)).mLength =
|
||||
CalcLength(specified, aStyleContext, aStyleContext->PresContext(),
|
||||
aCanStoreInRuleTree);
|
||||
position.*(axis->isPercent) = PR_FALSE;
|
||||
(position.*(axis->result)).mPercent = 0.0f;
|
||||
}
|
||||
else if (eCSSUnit_Enumerated == specified.GetUnit()) {
|
||||
(position.*(axis->result)).mFloat =
|
||||
(position.*(axis->result)).mLength = 0;
|
||||
(position.*(axis->result)).mPercent =
|
||||
GetFloatFromBoxPosition(specified.GetIntValue());
|
||||
position.*(axis->isPercent) = PR_TRUE;
|
||||
} else {
|
||||
NS_NOTREACHED("unexpected unit");
|
||||
}
|
||||
@ -4569,15 +4566,17 @@ struct BackgroundItemComputer<nsCSSValuePairList, nsStyleBackground::Size>
|
||||
size.*(axis->type) = size.mWidthType;
|
||||
}
|
||||
else if (eCSSUnit_Percent == specified.GetUnit()) {
|
||||
(size.*(axis->result)).mFloat = specified.GetPercentValue();
|
||||
size.*(axis->type) = nsStyleBackground::Size::ePercentage;
|
||||
(size.*(axis->result)).mLength = 0;
|
||||
(size.*(axis->result)).mPercent = specified.GetPercentValue();
|
||||
size.*(axis->type) = nsStyleBackground::Size::eLengthPercentage;
|
||||
}
|
||||
else {
|
||||
NS_ABORT_IF_FALSE(specified.IsLengthUnit(), "unexpected unit");
|
||||
(size.*(axis->result)).mCoord =
|
||||
(size.*(axis->result)).mLength =
|
||||
CalcLength(specified, aStyleContext, aStyleContext->PresContext(),
|
||||
aCanStoreInRuleTree);
|
||||
size.*(axis->type) = nsStyleBackground::Size::eLength;
|
||||
(size.*(axis->result)).mPercent = 0.0f;
|
||||
size.*(axis->type) = nsStyleBackground::Size::eLengthPercentage;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2182,15 +2182,19 @@ nsStyleAnimation::ExtractComputedValue(nsCSSProperty aProperty,
|
||||
resultTail = &item->mNext;
|
||||
|
||||
const nsStyleBackground::Position &pos = bg->mLayers[i].mPosition;
|
||||
if (pos.mXIsPercent) {
|
||||
item->mXValue.SetPercentValue(pos.mXPosition.mFloat);
|
||||
if (pos.mXPosition.mLength == 0) {
|
||||
item->mXValue.SetPercentValue(pos.mXPosition.mPercent);
|
||||
} else {
|
||||
nscoordToCSSValue(pos.mXPosition.mCoord, item->mXValue);
|
||||
NS_ABORT_IF_FALSE(pos.mXPosition.mPercent == 0.0f,
|
||||
"calc() isn't supported yet");
|
||||
nscoordToCSSValue(pos.mXPosition.mLength, item->mXValue);
|
||||
}
|
||||
if (pos.mYIsPercent) {
|
||||
item->mYValue.SetPercentValue(pos.mYPosition.mFloat);
|
||||
if (pos.mYPosition.mLength == 0) {
|
||||
item->mYValue.SetPercentValue(pos.mYPosition.mPercent);
|
||||
} else {
|
||||
nscoordToCSSValue(pos.mYPosition.mCoord, item->mYValue);
|
||||
NS_ABORT_IF_FALSE(pos.mYPosition.mPercent == 0.0f,
|
||||
"calc() isn't supported yet");
|
||||
nscoordToCSSValue(pos.mYPosition.mLength, item->mYValue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2216,14 +2220,17 @@ nsStyleAnimation::ExtractComputedValue(nsCSSProperty aProperty,
|
||||
item->mXValue.SetIntValue(size.mWidthType,
|
||||
eCSSUnit_Enumerated);
|
||||
break;
|
||||
case nsStyleBackground::Size::ePercentage:
|
||||
item->mXValue.SetPercentValue(size.mWidth.mFloat);
|
||||
break;
|
||||
case nsStyleBackground::Size::eAuto:
|
||||
item->mXValue.SetAutoValue();
|
||||
break;
|
||||
case nsStyleBackground::Size::eLength:
|
||||
nscoordToCSSValue(size.mWidth.mCoord, item->mXValue);
|
||||
case nsStyleBackground::Size::eLengthPercentage:
|
||||
if (size.mWidth.mLength == 0) {
|
||||
item->mXValue.SetPercentValue(size.mWidth.mPercent);
|
||||
} else {
|
||||
NS_ABORT_IF_FALSE(size.mWidth.mPercent == 0.0f,
|
||||
"calc() isn't supported yet");
|
||||
nscoordToCSSValue(size.mWidth.mLength, item->mXValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2232,14 +2239,17 @@ nsStyleAnimation::ExtractComputedValue(nsCSSProperty aProperty,
|
||||
case nsStyleBackground::Size::eCover:
|
||||
// leave it null
|
||||
break;
|
||||
case nsStyleBackground::Size::ePercentage:
|
||||
item->mYValue.SetPercentValue(size.mHeight.mFloat);
|
||||
break;
|
||||
case nsStyleBackground::Size::eAuto:
|
||||
item->mYValue.SetAutoValue();
|
||||
break;
|
||||
case nsStyleBackground::Size::eLength:
|
||||
nscoordToCSSValue(size.mHeight.mCoord, item->mYValue);
|
||||
case nsStyleBackground::Size::eLengthPercentage:
|
||||
if (size.mHeight.mLength == 0) {
|
||||
item->mYValue.SetPercentValue(size.mHeight.mPercent);
|
||||
} else {
|
||||
NS_ABORT_IF_FALSE(size.mHeight.mPercent == 0.0f,
|
||||
"calc() isn't supported yet");
|
||||
nscoordToCSSValue(size.mHeight.mLength, item->mYValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1815,10 +1815,10 @@ PRBool nsStyleBackground::IsTransparent() const
|
||||
void
|
||||
nsStyleBackground::Position::SetInitialValues()
|
||||
{
|
||||
mXPosition.mFloat = 0.0f;
|
||||
mYPosition.mFloat = 0.0f;
|
||||
mXIsPercent = PR_TRUE;
|
||||
mYIsPercent = PR_TRUE;
|
||||
mXPosition.mPercent = 0.0f;
|
||||
mXPosition.mLength = 0;
|
||||
mYPosition.mPercent = 0.0f;
|
||||
mYPosition.mLength = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1827,7 +1827,7 @@ nsStyleBackground::Size::SetInitialValues()
|
||||
mWidthType = mHeightType = eAuto;
|
||||
}
|
||||
|
||||
PRBool
|
||||
bool
|
||||
nsStyleBackground::Size::operator==(const Size& aOther) const
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mWidthType < eDimensionType_COUNT,
|
||||
@ -1839,26 +1839,10 @@ nsStyleBackground::Size::operator==(const Size& aOther) const
|
||||
NS_ABORT_IF_FALSE(aOther.mHeightType < eDimensionType_COUNT,
|
||||
"bad mHeightType for aOther");
|
||||
|
||||
if (mWidthType != aOther.mWidthType || mHeightType != aOther.mHeightType)
|
||||
return PR_FALSE;
|
||||
|
||||
if (mWidthType == ePercentage) {
|
||||
if (mWidth.mFloat != aOther.mWidth.mFloat)
|
||||
return PR_FALSE;
|
||||
} else if (mWidthType == eLength) {
|
||||
if (mWidth.mCoord != aOther.mWidth.mCoord)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (mHeightType == ePercentage) {
|
||||
if (mHeight.mFloat != aOther.mHeight.mFloat)
|
||||
return PR_FALSE;
|
||||
} else if (mHeightType == eLength) {
|
||||
if (mHeight.mCoord != aOther.mHeight.mCoord)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
return mWidthType == aOther.mWidthType &&
|
||||
mHeightType == aOther.mHeightType &&
|
||||
(mWidthType != eLengthPercentage || mWidth == aOther.mWidth) &&
|
||||
(mHeightType != eLengthPercentage || mHeight == aOther.mHeight);
|
||||
}
|
||||
|
||||
nsStyleBackground::Layer::Layer()
|
||||
|
@ -349,12 +349,18 @@ struct nsStyleBackground {
|
||||
struct Position;
|
||||
friend struct Position;
|
||||
struct Position {
|
||||
typedef union {
|
||||
nscoord mCoord; // for lengths
|
||||
float mFloat; // for percents
|
||||
} PositionCoord;
|
||||
struct PositionCoord {
|
||||
// A 'background-position' can be a linear combination of length
|
||||
// and percent (thanks to calc(), which can combine them).
|
||||
nscoord mLength;
|
||||
float mPercent;
|
||||
|
||||
bool operator==(const PositionCoord& aOther) const
|
||||
{ return mLength == aOther.mLength && mPercent == aOther.mPercent; }
|
||||
bool operator!=(const PositionCoord& aOther) const
|
||||
{ return !(*this == aOther); }
|
||||
};
|
||||
PositionCoord mXPosition, mYPosition;
|
||||
PRPackedBool mXIsPercent, mYIsPercent;
|
||||
|
||||
// Initialize nothing
|
||||
Position() {}
|
||||
@ -365,19 +371,14 @@ struct nsStyleBackground {
|
||||
// True if the effective background image position described by this depends
|
||||
// on the size of the corresponding frame.
|
||||
PRBool DependsOnFrameSize() const {
|
||||
return (mXIsPercent && mXPosition.mFloat != 0.0f) ||
|
||||
(mYIsPercent && mYPosition.mFloat != 0.0f);
|
||||
return mXPosition.mPercent != 0.0f || mYPosition.mPercent != 0.0f;
|
||||
}
|
||||
|
||||
PRBool operator==(const Position& aOther) const {
|
||||
return mXIsPercent == aOther.mXIsPercent &&
|
||||
(mXIsPercent ? (mXPosition.mFloat == aOther.mXPosition.mFloat)
|
||||
: (mXPosition.mCoord == aOther.mXPosition.mCoord)) &&
|
||||
mYIsPercent == aOther.mYIsPercent &&
|
||||
(mYIsPercent ? (mYPosition.mFloat == aOther.mYPosition.mFloat)
|
||||
: (mYPosition.mCoord == aOther.mYPosition.mCoord));
|
||||
bool operator==(const Position& aOther) const {
|
||||
return mXPosition == aOther.mXPosition &&
|
||||
mYPosition == aOther.mYPosition;
|
||||
}
|
||||
PRBool operator!=(const Position& aOther) const {
|
||||
bool operator!=(const Position& aOther) const {
|
||||
return !(*this == aOther);
|
||||
}
|
||||
};
|
||||
@ -385,25 +386,31 @@ struct nsStyleBackground {
|
||||
struct Size;
|
||||
friend struct Size;
|
||||
struct Size {
|
||||
typedef union {
|
||||
nscoord mCoord; // for lengths
|
||||
float mFloat; // for percents
|
||||
} Dimension;
|
||||
struct Dimension {
|
||||
// A 'background-size' can be a linear combination of length
|
||||
// and percent (thanks to calc(), which can combine them).
|
||||
nscoord mLength;
|
||||
float mPercent;
|
||||
|
||||
bool operator==(const Dimension& aOther) const
|
||||
{ return mLength == aOther.mLength && mPercent == aOther.mPercent; }
|
||||
bool operator!=(const Dimension& aOther) const
|
||||
{ return !(*this == aOther); }
|
||||
};
|
||||
Dimension mWidth, mHeight;
|
||||
|
||||
// Dimension types which might change how a layer is painted when the
|
||||
// corresponding frame's dimensions change *must* precede all dimension
|
||||
// types which are agnostic to frame size; see DependsOnFrameSize below.
|
||||
// Except for eLengthPercentage, Dimension types which might change
|
||||
// how a layer is painted when the corresponding frame's dimensions
|
||||
// change *must* precede all dimension types which are agnostic to
|
||||
// frame size; see DependsOnFrameSize below.
|
||||
enum DimensionType {
|
||||
// If one of mWidth and mHeight is eContain or eCover, then both are.
|
||||
// Also, these two values must equal the corresponding values in
|
||||
// kBackgroundSizeKTable.
|
||||
eContain, eCover,
|
||||
|
||||
ePercentage,
|
||||
|
||||
eAuto,
|
||||
eLength,
|
||||
eLengthPercentage,
|
||||
eDimensionType_COUNT
|
||||
};
|
||||
PRUint8 mWidthType, mHeightType;
|
||||
@ -416,9 +423,13 @@ struct nsStyleBackground {
|
||||
// -moz-element also depends on the frame size when the dimensions
|
||||
// are 'auto' since it could be an SVG gradient or pattern which
|
||||
// behaves exactly like a CSS gradient.
|
||||
PRBool DependsOnFrameSize(nsStyleImageType aType) const {
|
||||
bool DependsOnFrameSize(nsStyleImageType aType) const {
|
||||
if ((mWidthType == eLengthPercentage && mWidth.mPercent != 0.0f) ||
|
||||
(mHeightType == eLengthPercentage && mHeight.mPercent != 0.0f)) {
|
||||
return true;
|
||||
}
|
||||
if (aType == eStyleImageType_Image) {
|
||||
return mWidthType <= ePercentage || mHeightType <= ePercentage;
|
||||
return mWidthType <= eCover || mHeightType <= eCover;
|
||||
} else {
|
||||
NS_ABORT_IF_FALSE(aType == eStyleImageType_Gradient ||
|
||||
aType == eStyleImageType_Element,
|
||||
@ -433,8 +444,8 @@ struct nsStyleBackground {
|
||||
// Initialize to initial values
|
||||
void SetInitialValues();
|
||||
|
||||
PRBool operator==(const Size& aOther) const;
|
||||
PRBool operator!=(const Size& aOther) const {
|
||||
bool operator==(const Size& aOther) const;
|
||||
bool operator!=(const Size& aOther) const {
|
||||
return !(*this == aOther);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user