mirror of
https://github.com/roytam1/UXP.git
synced 2026-05-26 14:54:25 +00:00
Issue #1781 - Part 1: support calc() in stroke-dashoffset CSS
This adds basic calc() support to stroke-dashoffset. It does not provide CSS animation (yet, todo for part 2)
This commit is contained in:
@@ -833,6 +833,14 @@ SVGContentUtils::CoordToFloat(nsSVGElement *aContent,
|
||||
SVGSVGElement* ctx = aContent->GetCtx();
|
||||
return ctx ? aCoord.GetPercentValue() * ctx->GetLength(SVGContentUtils::XY) : 0.0f;
|
||||
}
|
||||
case eStyleUnit_Calc: {
|
||||
MOZ_ASSERT(aCoord.GetCalcValue(), "Invalid calc value");
|
||||
nsStyleCoord::Calc* calc = aCoord.GetCalcValue();
|
||||
SVGSVGElement* ctx = aContent->GetCtx();
|
||||
float len = nsPresContext::AppUnitsToFloatCSSPixels(calc->mLength);
|
||||
return ctx ? len + calc->mPercent * ctx->GetLength(SVGContentUtils::XY)
|
||||
: len;
|
||||
}
|
||||
default:
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
@@ -3816,7 +3816,7 @@ CSS_PROP_SVG(
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_NUMBERS_ARE_PIXELS,
|
||||
"",
|
||||
VARIANT_HLPN | VARIANT_OPENTYPE_SVG_KEYWORD,
|
||||
VARIANT_HLPN | VARIANT_OPENTYPE_SVG_KEYWORD | VARIANT_CALC,
|
||||
kStrokeContextValueKTable,
|
||||
offsetof(nsStyleSVG, mStrokeDashoffset),
|
||||
eStyleAnimType_Coord)
|
||||
|
||||
@@ -4492,6 +4492,15 @@ struct LengthNumberCalcObj
|
||||
bool mIsNumber;
|
||||
};
|
||||
|
||||
struct RealNumberComputedCalc
|
||||
{
|
||||
// We use float for mLength, so it can support real numbers.
|
||||
float mLength = 0.0f;
|
||||
float mPercent = 0.0f;
|
||||
bool mIsNumber = false;
|
||||
};
|
||||
|
||||
|
||||
struct LengthNumberCalcOps : public css::NumbersAlreadyNormalizedOps
|
||||
{
|
||||
typedef LengthNumberCalcObj result_type;
|
||||
@@ -4574,6 +4583,96 @@ struct LengthNumberCalcOps : public css::NumbersAlreadyNormalizedOps
|
||||
}
|
||||
};
|
||||
|
||||
// This is like LengthNumberCalcOps, but then for real/float.
|
||||
struct LengthPercentNumberCalcOps : public css::NumbersAlreadyNormalizedOps
|
||||
{
|
||||
typedef RealNumberComputedCalc result_type;
|
||||
|
||||
nsStyleContext* const mContext;
|
||||
nsPresContext* const mPresContext;
|
||||
RuleNodeCacheConditions& mConditions;
|
||||
bool mHasPercent = false;
|
||||
|
||||
LengthPercentNumberCalcOps(nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
RuleNodeCacheConditions& aConditions)
|
||||
: mContext(aContext),
|
||||
mPresContext(aPresContext),
|
||||
mConditions(aConditions) { }
|
||||
|
||||
result_type
|
||||
MergeAdditive(nsCSSUnit aCalcFunction,
|
||||
result_type aValue1, result_type aValue2)
|
||||
{
|
||||
MOZ_ASSERT(aValue1.mIsNumber == aValue2.mIsNumber);
|
||||
MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Plus ||
|
||||
aCalcFunction == eCSSUnit_Calc_Minus,
|
||||
"unexpected unit");
|
||||
|
||||
result_type result;
|
||||
result.mIsNumber = aValue1.mIsNumber;
|
||||
if (aCalcFunction == eCSSUnit_Calc_Plus) {
|
||||
result.mLength = aValue1.mLength + aValue2.mLength;
|
||||
result.mPercent = aValue1.mPercent + aValue2.mPercent;
|
||||
} else {
|
||||
result.mLength = aValue2.mLength == NS_IEEEPositiveInfinity() ?
|
||||
0.0f :
|
||||
aValue1.mLength - aValue2.mLength;
|
||||
result.mPercent = aValue1.mPercent - aValue2.mPercent;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeMultiplicativeL(nsCSSUnit aCalcFunction,
|
||||
float aValue1, result_type aValue2)
|
||||
{
|
||||
MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Times_L,
|
||||
"unexpected unit");
|
||||
result_type result;
|
||||
result.mLength = aValue1 * aValue2.mLength;
|
||||
result.mPercent = aValue1 * aValue2.mPercent;
|
||||
result.mIsNumber = aValue2.mIsNumber;
|
||||
return result;
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeMultiplicativeR(nsCSSUnit aCalcFunction,
|
||||
result_type aValue1, float aValue2)
|
||||
{
|
||||
MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_TimesR ||
|
||||
aCalcFunction == eCSSUnit_Divided,
|
||||
"unexpected unit");
|
||||
result_type result;
|
||||
if (aCalcFunction == eCSSUnit_Calc_Divided) {
|
||||
aValue2 = 1.0f / aValue2;
|
||||
}
|
||||
result.mLength = aValue1.mLength * aValue2;
|
||||
result.mPercent = aValue1.mPercent * aValue2;
|
||||
result.mIsNumber = aValue1.mIsNumber;
|
||||
return result;
|
||||
}
|
||||
|
||||
result_type
|
||||
ComputeLeafValue(const nsCSSValue& aValue)
|
||||
{
|
||||
result_type result;
|
||||
if (aValue.IsLengthUnit()) {
|
||||
result.mLength = CalcLength(aValue, mContext, mPresContext, mConditions);
|
||||
} else if (aValue.GetUnit() == eCSSUnit_Percent) {
|
||||
result.mPercent = aValue.GetPercentValue();
|
||||
mHasPercent = true;
|
||||
} else if (aValue.GetUnit() == eCSSUnit_Number) {
|
||||
result.mLength = aValue.GetFloatValue();
|
||||
result.mIsNumber = true;
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected unit");
|
||||
result.mLength = CalcLength(aValue, mContext, mPresContext, mConditions);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
struct SetLineHeightCalcOps : public LengthNumberCalcOps
|
||||
{
|
||||
SetLineHeightCalcOps(nsStyleContext* aStyleContext,
|
||||
@@ -9626,6 +9725,18 @@ nsRuleNode::ComputeSVGData(void* aStartStruct,
|
||||
strokeDashoffsetValue->GetIntValue() == NS_STYLE_STROKE_PROP_CONTEXT_VALUE);
|
||||
if (svg->StrokeDashoffsetFromObject()) {
|
||||
svg->mStrokeDashoffset.SetCoordValue(0);
|
||||
} else if (strokeDashoffsetValue->IsCalcUnit()) {
|
||||
LengthPercentNumberCalcOps ops(aContext, mPresContext, conditions);
|
||||
RealNumberComputedCalc obj = css::ComputeCalc(*strokeDashoffsetValue, ops);
|
||||
if (obj.mIsNumber) {
|
||||
svg->mStrokeDashoffset.SetFactorValue(obj.mLength);
|
||||
} else {
|
||||
nsStyleCoord::Calc* calcObj = new nsStyleCoord::Calc;
|
||||
calcObj->mLength = NSToCoordRoundWithClamp(obj.mLength);
|
||||
calcObj->mPercent = obj.mPercent;
|
||||
calcObj->mHasPercent = ops.mHasPercent;
|
||||
svg->mStrokeDashoffset.SetCalcValue(calcObj);
|
||||
}
|
||||
} else {
|
||||
SetCoord(*aRuleData->ValueForStrokeDashoffset(),
|
||||
svg->mStrokeDashoffset, parentSVG->mStrokeDashoffset,
|
||||
|
||||
Reference in New Issue
Block a user