diff --git a/dom/svg/SVGContentUtils.cpp b/dom/svg/SVGContentUtils.cpp index 7f372c9b42..21b98daba8 100644 --- a/dom/svg/SVGContentUtils.cpp +++ b/dom/svg/SVGContentUtils.cpp @@ -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; } diff --git a/layout/reftests/css-calc/reftest.list b/layout/reftests/css-calc/reftest.list index 86fc61801e..5e04db1b38 100644 --- a/layout/reftests/css-calc/reftest.list +++ b/layout/reftests/css-calc/reftest.list @@ -1,2 +1,3 @@ == background-image-gradient-1.html background-image-gradient-1-ref.html == line-height-1.html line-height-1-ref.html +== stroke-dashoffset-1.html stroke-dashoffset-1-ref.html diff --git a/layout/reftests/css-calc/stroke-dashoffset-1-ref.html b/layout/reftests/css-calc/stroke-dashoffset-1-ref.html new file mode 100644 index 0000000000..037bb9263b --- /dev/null +++ b/layout/reftests/css-calc/stroke-dashoffset-1-ref.html @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/css-calc/stroke-dashoffset-1.html b/layout/reftests/css-calc/stroke-dashoffset-1.html new file mode 100644 index 0000000000..4cee290041 --- /dev/null +++ b/layout/reftests/css-calc/stroke-dashoffset-1.html @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp index ff67835536..2332de6a6a 100644 --- a/layout/style/StyleAnimationValue.cpp +++ b/layout/style/StyleAnimationValue.cpp @@ -63,11 +63,15 @@ GetCommonUnit(nsCSSPropertyID aProperty, StyleAnimationValue::Unit aSecondUnit) { if (aFirstUnit != aSecondUnit) { + bool numberAsPixel = + nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_NUMBERS_ARE_PIXELS); if (nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_STORES_CALC) && - (aFirstUnit == StyleAnimationValue::eUnit_Coord || + ((aFirstUnit == StyleAnimationValue::eUnit_Float && numberAsPixel) || + aFirstUnit == StyleAnimationValue::eUnit_Coord || aFirstUnit == StyleAnimationValue::eUnit_Percent || aFirstUnit == StyleAnimationValue::eUnit_Calc) && - (aSecondUnit == StyleAnimationValue::eUnit_Coord || + ((aSecondUnit == StyleAnimationValue::eUnit_Float && numberAsPixel) || + aSecondUnit == StyleAnimationValue::eUnit_Coord || aSecondUnit == StyleAnimationValue::eUnit_Percent || aSecondUnit == StyleAnimationValue::eUnit_Calc)) { // We can use calc() as the common unit. @@ -354,6 +358,12 @@ ExtractCalcValue(const StyleAnimationValue& aValue) result.mHasPercent = true; return result; } + if (aValue.GetUnit() == StyleAnimationValue::eUnit_Float) { + result.mLength = aValue.GetFloatValue(); + result.mPercent = 0.0f; + result.mHasPercent = false; + return result; + } MOZ_ASSERT(aValue.GetUnit() == StyleAnimationValue::eUnit_Calc, "unexpected unit"); nsCSSValue *val = aValue.GetCSSValueValue(); diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index e78dafcc5c..45e919d4f8 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -3814,9 +3814,10 @@ CSS_PROP_SVG( stroke_dashoffset, StrokeDashoffset, CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_NUMBERS_ARE_PIXELS, + CSS_PROPERTY_NUMBERS_ARE_PIXELS | + CSS_PROPERTY_STORES_CALC, "", - VARIANT_HLPN | VARIANT_OPENTYPE_SVG_KEYWORD, + VARIANT_HLPN | VARIANT_OPENTYPE_SVG_KEYWORD | VARIANT_CALC, kStrokeContextValueKTable, offsetof(nsStyleSVG, mStrokeDashoffset), eStyleAnimType_Coord) diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 04715aa99a..74ba732885 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -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, diff --git a/toolkit/themes/windows/global/toolbar.css b/toolkit/themes/windows/global/toolbar.css index 38c8a617a5..97310e1aeb 100644 --- a/toolkit/themes/windows/global/toolbar.css +++ b/toolkit/themes/windows/global/toolbar.css @@ -17,6 +17,15 @@ toolbox { -moz-border-top-colors: ThreeDShadow ThreeDHighlight; } +@media (-moz-os-version: windows-win10) and (-moz-windows-theme: aero) { + toolbox { + /* Windows 10's "aero" msstyle sourced toolbox background is pure white + so don't use the widget toolbox styling and fallback to -moz-Dialog's + color which by default should be a non-blinding rgb(240, 240, 240) */ + -moz-appearance: none; + } +} + /* ::::: toolbar & menubar ::::: */ toolbar, menubar {