From 99549860f7158101e19bdbb222cf44412d79a39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 19 Feb 2019 20:28:47 +0000 Subject: [PATCH] Bug 1529058 - Use Rust types from transform-origin / perspective-origin. r=mattwoodrow Depends on D20381 Differential Revision: https://phabricator.services.mozilla.com/D20382 --HG-- extra : moz-landing-system : lando --- layout/base/nsLayoutUtils.cpp | 29 +------ layout/generic/nsFrame.cpp | 3 +- layout/painting/nsDisplayList.cpp | 55 ++++--------- layout/style/ServoBindings.toml | 1 + layout/style/ServoCSSPropList.mako.py | 1 + layout/style/nsComputedDOMStyle.cpp | 70 +++++----------- layout/style/nsComputedDOMStyle.h | 2 - layout/style/nsStyleCoord.h | 10 +-- layout/style/nsStyleStruct.cpp | 59 ++++--------- layout/style/nsStyleStruct.h | 7 +- layout/style/nsStyleTransformMatrix.cpp | 45 ++++------ layout/style/nsStyleTransformMatrix.h | 15 +++- servo/components/style/cbindgen.toml | 2 + .../components/style/properties/gecko.mako.rs | 82 +------------------ .../style/values/computed/transform.rs | 2 +- .../style/values/generics/transform.rs | 11 ++- 16 files changed, 108 insertions(+), 286 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 0f1a9d3b58ef..eff868890771 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -9718,26 +9718,6 @@ already_AddRefed nsLayoutUtils::GetMetricsFor( return style.get(); } -static float ResolveTransformOrigin( - const nsStyleCoord& aCoord, TransformReferenceBox& aRefBox, - TransformReferenceBox::DimensionGetter aGetter) { - float result = 0.0; - const float scale = mozilla::AppUnitsPerCSSPixel(); - if (aCoord.GetUnit() == eStyleUnit_Calc) { - const nsStyleCoord::Calc* calc = aCoord.GetCalcValue(); - result = - NSAppUnitsToFloatPixels((aRefBox.*aGetter)(), scale) * calc->mPercent + - NSAppUnitsToFloatPixels(calc->mLength, scale); - } else if (aCoord.GetUnit() == eStyleUnit_Percent) { - result = NSAppUnitsToFloatPixels((aRefBox.*aGetter)(), scale) * - aCoord.GetPercentValue(); - } else { - MOZ_ASSERT(aCoord.GetUnit() == eStyleUnit_Coord, "unexpected unit"); - result = NSAppUnitsToFloatPixels(aCoord.GetCoordValue(), scale); - } - return result; -} - /* static */ Maybe nsLayoutUtils::ResolveMotionPath( const nsIFrame* aFrame) { MOZ_ASSERT(aFrame); @@ -9791,11 +9771,10 @@ static float ResolveTransformOrigin( // We need to resolve transform-origin here to calculate the correct path // translate. (i.e. Center transform-origin on the path.) TransformReferenceBox refBox(aFrame); - Point origin(ResolveTransformOrigin(display->mTransformOrigin[0], refBox, - &TransformReferenceBox::Width), - ResolveTransformOrigin(display->mTransformOrigin[1], refBox, - &TransformReferenceBox::Height)); + auto& transformOrigin = display->mTransformOrigin; + CSSPoint origin = nsStyleTransformMatrix::Convert2DPosition( + transformOrigin.horizontal, transformOrigin.vertical, refBox); // Bug 1186329: the translate parameters will be adjusted more after we // implement offset-position and offset-anchor. - return Some(MotionPathData{point - origin, angle}); + return Some(MotionPathData{point - origin.ToUnknownPoint(), angle}); } diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 8af139b2509f..1e8f30d4a573 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -10527,8 +10527,9 @@ gfx::Matrix nsIFrame::ComputeWidgetTransform() { float(appUnitsPerDevPixel)); // Apply the -moz-window-transform-origin translation to the matrix. + const StyleTransformOrigin& origin = uiReset->mWindowTransformOrigin; Point transformOrigin = nsStyleTransformMatrix::Convert2DPosition( - uiReset->mWindowTransformOrigin, refBox, appUnitsPerDevPixel); + origin.horizontal, origin.vertical, refBox, appUnitsPerDevPixel); matrix.ChangeBasis(Point3D(transformOrigin.x, transformOrigin.y, 0)); gfx::Matrix result2d; diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 54f4b5cde51f..4666ff45d4f6 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -7376,49 +7376,21 @@ bool nsDisplayTransform::ShouldFlattenAway(nsDisplayListBuilder* aBuilder) { refBox.Init(aFrame); } - /* Allows us to access dimension getters by index. */ - float transformOrigin[2]; - TransformReferenceBox::DimensionGetter dimensionGetter[] = { - &TransformReferenceBox::Width, &TransformReferenceBox::Height}; - TransformReferenceBox::DimensionGetter offsetGetter[] = { - &TransformReferenceBox::X, &TransformReferenceBox::Y}; + const StyleTransformOrigin& transformOrigin = display->mTransformOrigin; + CSSPoint origin = nsStyleTransformMatrix::Convert2DPosition( + transformOrigin.horizontal, transformOrigin.vertical, refBox); - for (uint8_t index = 0; index < 2; ++index) { - /* If the transform-origin specifies a percentage, take the percentage - * of the size of the box. - */ - const nsStyleCoord& originValue = display->mTransformOrigin[index]; - if (originValue.GetUnit() == eStyleUnit_Calc) { - const nsStyleCoord::Calc* calc = originValue.GetCalcValue(); - transformOrigin[index] = - NSAppUnitsToFloatPixels((refBox.*dimensionGetter[index])(), - aAppUnitsPerPixel) * - calc->mPercent + - NSAppUnitsToFloatPixels(calc->mLength, aAppUnitsPerPixel); - } else if (originValue.GetUnit() == eStyleUnit_Percent) { - transformOrigin[index] = - NSAppUnitsToFloatPixels((refBox.*dimensionGetter[index])(), - aAppUnitsPerPixel) * - originValue.GetPercentValue(); - } else { - MOZ_ASSERT(originValue.GetUnit() == eStyleUnit_Coord, "unexpected unit"); - transformOrigin[index] = NSAppUnitsToFloatPixels( - originValue.GetCoordValue(), aAppUnitsPerPixel); - } - - if (aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) { - // SVG frames (unlike other frames) have a reference box that can be (and - // typically is) offset from the TopLeft() of the frame. We need to - // account for that here. - transformOrigin[index] += NSAppUnitsToFloatPixels( - (refBox.*offsetGetter[index])(), aAppUnitsPerPixel); - } + if (aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) { + // SVG frames (unlike other frames) have a reference box that can be (and + // typically is) offset from the TopLeft() of the frame. We need to account + // for that here. + origin.x += CSSPixel::FromAppUnits(refBox.X()); + origin.y += CSSPixel::FromAppUnits(refBox.Y()); } - return Point3D( - transformOrigin[0], transformOrigin[1], - NSAppUnitsToFloatPixels(display->mTransformOrigin[2].GetCoordValue(), - aAppUnitsPerPixel)); + float scale = mozilla::AppUnitsPerCSSPixel() / float(aAppUnitsPerPixel); + float z = transformOrigin.depth._0; + return Point3D(origin.x * scale, origin.y * scale, z * scale); } /* static */ bool nsDisplayTransform::ComputePerspectiveMatrix( @@ -7462,7 +7434,8 @@ bool nsDisplayTransform::ShouldFlattenAway(nsDisplayListBuilder* aBuilder) { TransformReferenceBox refBox(cbFrame); Point perspectiveOrigin = nsStyleTransformMatrix::Convert2DPosition( - cbDisplay->mPerspectiveOrigin, refBox, aAppUnitsPerPixel); + cbDisplay->mPerspectiveOrigin.horizontal, + cbDisplay->mPerspectiveOrigin.vertical, refBox, aAppUnitsPerPixel); /* GetOffsetTo computes the offset required to move from 0,0 in cbFrame to 0,0 * in aFrame. Although we actually want the inverse of this, it's faster to diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml index 98cf001fa107..1566cf5f8be1 100644 --- a/layout/style/ServoBindings.toml +++ b/layout/style/ServoBindings.toml @@ -441,6 +441,7 @@ cbindgen-types = [ { gecko = "StylePercentage", servo = "values::computed::Percentage" }, { gecko = "StylePerspective", servo = "values::computed::Perspective" }, { gecko = "StyleZIndex", servo = "values::computed::ZIndex" }, + { gecko = "StyleTransformOrigin", servo = "values::computed::TransformOrigin" }, ] mapped-generic-types = [ diff --git a/layout/style/ServoCSSPropList.mako.py b/layout/style/ServoCSSPropList.mako.py index 64577ad859da..af963039bf79 100644 --- a/layout/style/ServoCSSPropList.mako.py +++ b/layout/style/ServoCSSPropList.mako.py @@ -123,6 +123,7 @@ SERIALIZED_PREDEFINED_TYPES = [ "TextAlign", "Translate", "TimingFunction", + "TransformOrigin", "TransformStyle", "UserSelect", "background::BackgroundSize", diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 34080cab5bcb..2df84ca3391e 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -1065,6 +1065,17 @@ already_AddRefed nsComputedDOMStyle::DoGetColumnRuleWidth() { return val.forget(); } +static Position MaybeResolvePositionForTransform(const LengthPercentage& aX, + const LengthPercentage& aY, + nsIFrame* aInnerFrame) { + if (!aInnerFrame) { + return {aX, aY}; + } + nsStyleTransformMatrix::TransformReferenceBox refBox(aInnerFrame); + CSSPoint p = nsStyleTransformMatrix::Convert2DPosition(aX, aY, refBox); + return {LengthPercentage::FromPixels(p.x), LengthPercentage::FromPixels(p.y)}; +} + /* Convert the stored representation into a list of two values and then hand * it back. */ @@ -1077,25 +1088,17 @@ already_AddRefed nsComputedDOMStyle::DoGetTransformOrigin() { RefPtr valueList = GetROCSSValueList(false); /* Now, get the values. */ - const nsStyleDisplay* display = StyleDisplay(); + const auto& origin = StyleDisplay()->mTransformOrigin; RefPtr width = new nsROCSSPrimitiveValue; - SetValueToCoord(width, display->mTransformOrigin[0], false, - &nsComputedDOMStyle::GetFrameBoundsWidthForTransform); - valueList->AppendCSSValue(width.forget()); - - RefPtr height = new nsROCSSPrimitiveValue; - SetValueToCoord(height, display->mTransformOrigin[1], false, - &nsComputedDOMStyle::GetFrameBoundsHeightForTransform); - valueList->AppendCSSValue(height.forget()); - - if (display->mTransformOrigin[2].GetUnit() != eStyleUnit_Coord || - display->mTransformOrigin[2].GetCoordValue() != 0) { + auto position = MaybeResolvePositionForTransform( + origin.horizontal, origin.vertical, mInnerFrame); + SetValueToPosition(position, valueList); + if (origin.depth._0 != 0.0f) { RefPtr depth = new nsROCSSPrimitiveValue; - SetValueToCoord(depth, display->mTransformOrigin[2], false, nullptr); + depth->SetAppUnits(origin.depth.ToAppUnits()); valueList->AppendCSSValue(depth.forget()); } - return valueList.forget(); } @@ -1111,18 +1114,11 @@ already_AddRefed nsComputedDOMStyle::DoGetPerspectiveOrigin() { RefPtr valueList = GetROCSSValueList(false); /* Now, get the values. */ - const nsStyleDisplay* display = StyleDisplay(); - - RefPtr width = new nsROCSSPrimitiveValue; - SetValueToCoord(width, display->mPerspectiveOrigin[0], false, - &nsComputedDOMStyle::GetFrameBoundsWidthForTransform); - valueList->AppendCSSValue(width.forget()); - - RefPtr height = new nsROCSSPrimitiveValue; - SetValueToCoord(height, display->mPerspectiveOrigin[1], false, - &nsComputedDOMStyle::GetFrameBoundsHeightForTransform); - valueList->AppendCSSValue(height.forget()); + const auto& origin = StyleDisplay()->mPerspectiveOrigin; + auto position = MaybeResolvePositionForTransform( + origin.horizontal, origin.vertical, mInnerFrame); + SetValueToPosition(position, valueList); return valueList.forget(); } @@ -3073,30 +3069,6 @@ bool nsComputedDOMStyle::GetFrameBorderRectHeight(nscoord& aHeight) { return true; } -bool nsComputedDOMStyle::GetFrameBoundsWidthForTransform(nscoord& aWidth) { - // We need a frame to work with. - if (!mInnerFrame) { - return false; - } - - AssertFlushedPendingReflows(); - - aWidth = nsStyleTransformMatrix::TransformReferenceBox(mInnerFrame).Width(); - return true; -} - -bool nsComputedDOMStyle::GetFrameBoundsHeightForTransform(nscoord& aHeight) { - // We need a frame to work with. - if (!mInnerFrame) { - return false; - } - - AssertFlushedPendingReflows(); - - aHeight = nsStyleTransformMatrix::TransformReferenceBox(mInnerFrame).Height(); - return true; -} - already_AddRefed nsComputedDOMStyle::GetFallbackValue( const nsStyleSVGPaint* aPaint) { RefPtr fallback = new nsROCSSPrimitiveValue; diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index a4acd18cbea9..4f9ad434acb3 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -475,8 +475,6 @@ class nsComputedDOMStyle final : public nsDOMCSSDeclaration, bool GetCBPaddingRectHeight(nscoord& aHeight); bool GetScrollFrameContentWidth(nscoord& aWidth); bool GetScrollFrameContentHeight(nscoord& aHeight); - bool GetFrameBoundsWidthForTransform(nscoord& aWidth); - bool GetFrameBoundsHeightForTransform(nscoord& aHeight); bool GetFrameBorderRectWidth(nscoord& aWidth); bool GetFrameBorderRectHeight(nscoord& aHeight); diff --git a/layout/style/nsStyleCoord.h b/layout/style/nsStyleCoord.h index 91df5bac87b5..baf34008442f 100644 --- a/layout/style/nsStyleCoord.h +++ b/layout/style/nsStyleCoord.h @@ -68,12 +68,12 @@ constexpr LengthPercentage LengthPercentage::Zero() { return {{0.}, {0.}, StyleAllowedNumericType::All, false, false}; } +LengthPercentage LengthPercentage::FromPixels(CSSCoord aCoord) { + return {{aCoord}, {0.}, StyleAllowedNumericType::All, false, false}; +} + LengthPercentage LengthPercentage::FromAppUnits(nscoord aCoord) { - return {{CSSPixel::FromAppUnits(aCoord)}, - {0.}, - StyleAllowedNumericType::All, - false, - false}; + return LengthPercentage::FromPixels(CSSPixel::FromAppUnits(aCoord)); } LengthPercentage LengthPercentage::FromPercentage(float aPercentage) { diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index d95797bdceb2..7b3dc98e8ff2 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -2933,13 +2933,11 @@ nsStyleDisplay::nsStyleDisplay(const Document& aDocument) mBackfaceVisibility(NS_STYLE_BACKFACE_VISIBILITY_VISIBLE), mTransformStyle(NS_STYLE_TRANSFORM_STYLE_FLAT), mTransformBox(StyleGeometryBox::BorderBox), - mTransformOrigin{ - {0.5f, eStyleUnit_Percent}, // Transform is centered on origin - {0.5f, eStyleUnit_Percent}, - {0, nsStyleCoord::CoordConstructor}}, + mTransformOrigin{LengthPercentage::FromPercentage(0.5), + LengthPercentage::FromPercentage(0.5), + {0.}}, mChildPerspective(StylePerspective::None()), - mPerspectiveOrigin{{0.5f, eStyleUnit_Percent}, - {0.5f, eStyleUnit_Percent}}, + mPerspectiveOrigin(Position::FromPercentage(0.5f)), mVerticalAlign(NS_STYLE_VERTICAL_ALIGN_BASELINE, eStyleUnit_Enumerated), mTransitions( nsStyleAutoArray::WITH_SINGLE_INITIAL_ELEMENT), @@ -3009,11 +3007,9 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource) // appropriate. mMotion(aSource.mMotion ? MakeUnique(*aSource.mMotion) : nullptr), - mTransformOrigin{aSource.mTransformOrigin[0], aSource.mTransformOrigin[1], - aSource.mTransformOrigin[2]}, + mTransformOrigin(aSource.mTransformOrigin), mChildPerspective(aSource.mChildPerspective), - mPerspectiveOrigin{aSource.mPerspectiveOrigin[0], - aSource.mPerspectiveOrigin[1]}, + mPerspectiveOrigin(aSource.mPerspectiveOrigin), mVerticalAlign(aSource.mVerticalAlign), mTransitions(aSource.mTransitions), mTransitionTimingFunctionCount(aSource.mTransitionTimingFunctionCount), @@ -3246,26 +3242,15 @@ nsChangeHint nsStyleDisplay::CalcDifference( CompareTransformValues(mSpecifiedScale, aNewData.mSpecifiedScale); transformHint |= CompareMotionValues(mMotion.get(), aNewData.mMotion.get()); - const nsChangeHint kUpdateOverflowAndRepaintHint = - nsChangeHint_UpdateOverflow | nsChangeHint_RepaintFrame; - for (uint8_t index = 0; index < 3; ++index) { - if (mTransformOrigin[index] != aNewData.mTransformOrigin[index]) { - transformHint |= nsChangeHint_UpdateTransformLayer | - nsChangeHint_UpdatePostTransformOverflow; - break; - } + if (mTransformOrigin != aNewData.mTransformOrigin) { + transformHint |= nsChangeHint_UpdateTransformLayer | + nsChangeHint_UpdatePostTransformOverflow; } - for (uint8_t index = 0; index < 2; ++index) { - if (mPerspectiveOrigin[index] != aNewData.mPerspectiveOrigin[index]) { - transformHint |= kUpdateOverflowAndRepaintHint; - break; - } - } - - if (mTransformStyle != aNewData.mTransformStyle || + if (mPerspectiveOrigin != aNewData.mPerspectiveOrigin || + mTransformStyle != aNewData.mTransformStyle || mTransformBox != aNewData.mTransformBox) { - transformHint |= kUpdateOverflowAndRepaintHint; + transformHint |= nsChangeHint_UpdateOverflow | nsChangeHint_RepaintFrame; } if (mBackfaceVisibility != aNewData.mBackfaceVisibility) { @@ -4003,9 +3988,9 @@ nsStyleUIReset::nsStyleUIReset(const Document& aDocument) mWindowShadow(NS_STYLE_WINDOW_SHADOW_DEFAULT), mWindowOpacity(1.0), mSpecifiedWindowTransform(nullptr), - mWindowTransformOrigin{ - {0.5f, eStyleUnit_Percent}, // Transform is centered on origin - {0.5f, eStyleUnit_Percent}} { + mWindowTransformOrigin{LengthPercentage::FromPercentage(0.5), + LengthPercentage::FromPercentage(0.5), + {0.}} { MOZ_COUNT_CTOR(nsStyleUIReset); } @@ -4018,8 +4003,7 @@ nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset& aSource) mWindowShadow(aSource.mWindowShadow), mWindowOpacity(aSource.mWindowOpacity), mSpecifiedWindowTransform(aSource.mSpecifiedWindowTransform), - mWindowTransformOrigin{aSource.mWindowTransformOrigin[0], - aSource.mWindowTransformOrigin[1]} { + mWindowTransformOrigin(aSource.mWindowTransformOrigin) { MOZ_COUNT_CTOR(nsStyleUIReset); } @@ -4060,16 +4044,9 @@ nsChangeHint nsStyleUIReset::CalcDifference( if (mWindowOpacity != aNewData.mWindowOpacity || !mSpecifiedWindowTransform != !aNewData.mSpecifiedWindowTransform || (mSpecifiedWindowTransform && - *mSpecifiedWindowTransform != *aNewData.mSpecifiedWindowTransform)) { + *mSpecifiedWindowTransform != *aNewData.mSpecifiedWindowTransform) || + mWindowTransformOrigin != aNewData.mWindowTransformOrigin) { hint |= nsChangeHint_UpdateWidgetProperties; - } else { - for (uint8_t index = 0; index < 2; ++index) { - if (mWindowTransformOrigin[index] != - aNewData.mWindowTransformOrigin[index]) { - hint |= nsChangeHint_UpdateWidgetProperties; - break; - } - } } if (!hint && mIMEMode != aNewData.mIMEMode) { diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 053faa0dd762..3d236c9e1580 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1901,10 +1901,9 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay { RefPtr mIndividualTransform; mozilla::UniquePtr mMotion; - nsStyleCoord mTransformOrigin[3]; // percent, coord, calc, 3rd param is - // coord, calc only + mozilla::StyleTransformOrigin mTransformOrigin; mozilla::StylePerspective mChildPerspective; - nsStyleCoord mPerspectiveOrigin[2]; // percent, coord, calc + mozilla::Position mPerspectiveOrigin; nsStyleCoord mVerticalAlign; // coord, percent, calc, enum // (NS_STYLE_VERTICAL_ALIGN_*) @@ -2484,7 +2483,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset { uint8_t mWindowShadow; float mWindowOpacity; RefPtr mSpecifiedWindowTransform; - nsStyleCoord mWindowTransformOrigin[2]; // percent, coord, calc + mozilla::StyleTransformOrigin mWindowTransformOrigin; }; struct nsCursorImage { diff --git a/layout/style/nsStyleTransformMatrix.cpp b/layout/style/nsStyleTransformMatrix.cpp index 1990718c28e9..d6ef9a2234d0 100644 --- a/layout/style/nsStyleTransformMatrix.cpp +++ b/layout/style/nsStyleTransformMatrix.cpp @@ -842,36 +842,23 @@ Matrix4x4 ReadTransforms(const nsCSSValueList* aIndividualTransforms, return result; } -Point Convert2DPosition(nsStyleCoord const (&aValue)[2], - TransformReferenceBox& aRefBox, - int32_t aAppUnitsPerDevPixel) { - float position[2]; - nsStyleTransformMatrix::TransformReferenceBox::DimensionGetter - dimensionGetter[] = { - &nsStyleTransformMatrix::TransformReferenceBox::Width, - &nsStyleTransformMatrix::TransformReferenceBox::Height}; - for (uint8_t index = 0; index < 2; ++index) { - const nsStyleCoord& value = aValue[index]; - if (value.GetUnit() == eStyleUnit_Calc) { - const nsStyleCoord::Calc* calc = value.GetCalcValue(); - position[index] = - NSAppUnitsToFloatPixels((aRefBox.*dimensionGetter[index])(), - aAppUnitsPerDevPixel) * - calc->mPercent + - NSAppUnitsToFloatPixels(calc->mLength, aAppUnitsPerDevPixel); - } else if (value.GetUnit() == eStyleUnit_Percent) { - position[index] = - NSAppUnitsToFloatPixels((aRefBox.*dimensionGetter[index])(), - aAppUnitsPerDevPixel) * - value.GetPercentValue(); - } else { - MOZ_ASSERT(value.GetUnit() == eStyleUnit_Coord, "unexpected unit"); - position[index] = - NSAppUnitsToFloatPixels(value.GetCoordValue(), aAppUnitsPerDevPixel); - } - } +CSSPoint Convert2DPosition(const LengthPercentage& aX, + const LengthPercentage& aY, + TransformReferenceBox& aRefBox) { + return { + aX.ResolveToCSSPixelsWith( + [&] { return CSSPixel::FromAppUnits(aRefBox.Width()); }), + aY.ResolveToCSSPixelsWith( + [&] { return CSSPixel::FromAppUnits(aRefBox.Height()); }), + }; +} - return Point(position[0], position[1]); +Point Convert2DPosition(const LengthPercentage& aX, const LengthPercentage& aY, + TransformReferenceBox& aRefBox, + int32_t aAppUnitsPerPixel) { + float scale = mozilla::AppUnitsPerCSSPixel() / float(aAppUnitsPerPixel); + CSSPoint p = Convert2DPosition(aX, aY, aRefBox); + return {p.x * scale, p.y * scale}; } /* diff --git a/layout/style/nsStyleTransformMatrix.h b/layout/style/nsStyleTransformMatrix.h index d1e3f06d8dcf..0a56d9caab6a 100644 --- a/layout/style/nsStyleTransformMatrix.h +++ b/layout/style/nsStyleTransformMatrix.h @@ -187,10 +187,19 @@ mozilla::gfx::Matrix4x4 ReadTransforms( float aAppUnitsPerMatrixUnit); /** - * Given two nsStyleCoord values, compute the 2d position with respect to the - * given TransformReferenceBox that these values describe, in device pixels. + * Given the x and y values, compute the 2d position with respect to the given + * TransformReferenceBox that these values describe, in CSS pixels. */ -mozilla::gfx::Point Convert2DPosition(nsStyleCoord const (&aValue)[2], +mozilla::CSSPoint Convert2DPosition(const mozilla::LengthPercentage& aX, + const mozilla::LengthPercentage& aY, + TransformReferenceBox& aRefBox); + +/** + * Given the x and y values, compute the 2d position with respect to the given + * TransformReferenceBox that these values describe, in device pixels. + */ +mozilla::gfx::Point Convert2DPosition(const mozilla::LengthPercentage& aX, + const mozilla::LengthPercentage& aY, TransformReferenceBox& aRefBox, int32_t aAppUnitsPerDevPixel); diff --git a/servo/components/style/cbindgen.toml b/servo/components/style/cbindgen.toml index 104893701c56..0b8719c4dbfd 100644 --- a/servo/components/style/cbindgen.toml +++ b/servo/components/style/cbindgen.toml @@ -91,6 +91,7 @@ include = [ "NonNegativeLengthOrNumberRect", "Perspective", "ZIndex", + "TransformOrigin", ] item_types = ["enums", "structs", "typedefs"] @@ -103,6 +104,7 @@ item_types = ["enums", "structs", "typedefs"] // Defined in nsStyleCoord.h static constexpr inline StyleLengthPercentage Zero(); static inline StyleLengthPercentage FromAppUnits(nscoord); + static inline StyleLengthPercentage FromPixels(CSSCoord); static inline StyleLengthPercentage FromPercentage(float); inline CSSCoord LengthInCSSPixels() const; inline float Percentage() const; diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs index ca1a75df3219..b1be315e7a02 100644 --- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -1188,55 +1188,6 @@ pub fn clone_transform_from_list( } -<%def name="impl_transform_origin(ident, gecko_ffi_name)"> - #[allow(non_snake_case)] - pub fn set_${ident}(&mut self, v: values::computed::TransformOrigin) { - self.gecko.${gecko_ffi_name}[0].set(v.horizontal); - self.gecko.${gecko_ffi_name}[1].set(v.vertical); - // transform-origin supports the third value for depth, while - // -moz-window-transform-origin doesn't. The following code is - // for handling this difference. If we can have more knowledge - // about the type here, we may want to check that the length is - // exactly either 2 or 3 in compile time. - if let Some(third) = self.gecko.${gecko_ffi_name}.get_mut(2) { - third.set(v.depth); - } - } - - #[allow(non_snake_case)] - pub fn copy_${ident}_from(&mut self, other: &Self) { - self.gecko.${gecko_ffi_name}[0].copy_from(&other.gecko.${gecko_ffi_name}[0]); - self.gecko.${gecko_ffi_name}[1].copy_from(&other.gecko.${gecko_ffi_name}[1]); - if let (Some(self_third), Some(other_third)) = - (self.gecko.${gecko_ffi_name}.get_mut(2), other.gecko.${gecko_ffi_name}.get(2)) - { - self_third.copy_from(other_third) - } - } - - #[allow(non_snake_case)] - pub fn reset_${ident}(&mut self, other: &Self) { - self.copy_${ident}_from(other) - } - - #[allow(non_snake_case)] - pub fn clone_${ident}(&self) -> values::computed::TransformOrigin { - use crate::values::computed::{Length, LengthPercentage, TransformOrigin}; - TransformOrigin { - horizontal: LengthPercentage::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}[0]) - .expect("clone for LengthPercentage failed"), - vertical: LengthPercentage::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}[1]) - .expect("clone for LengthPercentage failed"), - depth: if let Some(third) = self.gecko.${gecko_ffi_name}.get(2) { - Length::from_gecko_style_coord(third) - .expect("clone for Length failed") - } else { - Length::new(0.) - }, - } - } - - <%def name="impl_logical(name, **kwargs)"> ${helpers.logical_setter(name)} @@ -1385,7 +1336,7 @@ impl Clone for ${style_struct.gecko_struct_name} { "SVGPaint": impl_svg_paint, "SVGWidth": impl_svg_length, "Transform": impl_transform, - "TransformOrigin": impl_transform_origin, + "TransformOrigin": impl_simple, "UserSelect": impl_simple, "url::UrlOrNone": impl_css_url, "ZIndex": impl_simple, @@ -2913,10 +2864,8 @@ fn static_assert() { clear transition-duration transition-delay transition-timing-function transition-property rotate scroll-snap-points-x scroll-snap-points-y - scroll-snap-coordinate - perspective-origin -moz-binding will-change - offset-path perspective-origin -moz-binding - will-change shape-outside contain touch-action + scroll-snap-coordinate -moz-binding will-change + offset-path shape-outside contain touch-action translate scale""" %> <%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}"> #[inline] @@ -3268,31 +3217,6 @@ fn static_assert() { ${impl_animation_timing_function()} - pub fn set_perspective_origin(&mut self, v: longhands::perspective_origin::computed_value::T) { - self.gecko.mPerspectiveOrigin[0].set(v.horizontal); - self.gecko.mPerspectiveOrigin[1].set(v.vertical); - } - - pub fn copy_perspective_origin_from(&mut self, other: &Self) { - self.gecko.mPerspectiveOrigin[0].copy_from(&other.gecko.mPerspectiveOrigin[0]); - self.gecko.mPerspectiveOrigin[1].copy_from(&other.gecko.mPerspectiveOrigin[1]); - } - - pub fn reset_perspective_origin(&mut self, other: &Self) { - self.copy_perspective_origin_from(other) - } - - pub fn clone_perspective_origin(&self) -> longhands::perspective_origin::computed_value::T { - use crate::properties::longhands::perspective_origin::computed_value::T; - use crate::values::computed::LengthPercentage; - T { - horizontal: LengthPercentage::from_gecko_style_coord(&self.gecko.mPerspectiveOrigin[0]) - .expect("Expected length or percentage for horizontal value of perspective-origin"), - vertical: LengthPercentage::from_gecko_style_coord(&self.gecko.mPerspectiveOrigin[1]) - .expect("Expected length or percentage for vertical value of perspective-origin"), - } - } - ${impl_individual_transform('rotate', 'Rotate', 'mSpecifiedRotate')} ${impl_individual_transform('translate', 'Translate', 'mSpecifiedTranslate')} ${impl_individual_transform('scale', 'Scale', 'mSpecifiedScale')} diff --git a/servo/components/style/values/computed/transform.rs b/servo/components/style/values/computed/transform.rs index 979886aa9967..a78cda03ec07 100644 --- a/servo/components/style/values/computed/transform.rs +++ b/servo/components/style/values/computed/transform.rs @@ -21,7 +21,7 @@ pub type TransformOperation = pub type Transform = generic::Transform; /// The computed value of a CSS `` -pub type TransformOrigin = generic::TransformOrigin; +pub type TransformOrigin = generic::GenericTransformOrigin; /// A vector to represent the direction vector (rotate axis) for Rotate3D. pub type DirectionVector = Vector3D; diff --git a/servo/components/style/values/generics/transform.rs b/servo/components/style/values/generics/transform.rs index 4591f3addd28..6c98a45dd6c5 100644 --- a/servo/components/style/values/generics/transform.rs +++ b/servo/components/style/values/generics/transform.rs @@ -83,7 +83,8 @@ impl> From> for Transform3D { ToComputedValue, ToCss, )] -pub struct TransformOrigin { +#[repr(C)] +pub struct GenericTransformOrigin { /// The horizontal origin. pub horizontal: H, /// The vertical origin. @@ -92,14 +93,12 @@ pub struct TransformOrigin { pub depth: Depth, } +pub use self::GenericTransformOrigin as TransformOrigin; + impl TransformOrigin { /// Returns a new transform origin. pub fn new(horizontal: H, vertical: V, depth: D) -> Self { - Self { - horizontal: horizontal, - vertical: vertical, - depth: depth, - } + Self { horizontal, vertical, depth } } }