зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1773493 - Use Rust's `ComputedTimingFunction` for IPDL. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D149663
This commit is contained in:
Родитель
7f2dc4ffd4
Коммит
aca7c3d4df
|
@ -13,9 +13,8 @@
|
|||
namespace mozilla {
|
||||
|
||||
ComputedTimingFunction::Function ComputedTimingFunction::ConstructFunction(
|
||||
const nsTimingFunction& aFunction) {
|
||||
const StyleComputedTimingFunction& timing = aFunction.mTiming;
|
||||
switch (timing.tag) {
|
||||
const StyleComputedTimingFunction& aFunction) {
|
||||
switch (aFunction.tag) {
|
||||
case StyleComputedTimingFunction::Tag::Keyword: {
|
||||
static_assert(
|
||||
static_cast<uint8_t>(StyleTimingKeyword::Linear) == 0 &&
|
||||
|
@ -32,33 +31,39 @@ ComputedTimingFunction::Function ComputedTimingFunction::ConstructFunction(
|
|||
{0.42f, 0.00f, 0.58f, 1.00f} // ease-in-out
|
||||
};
|
||||
const float(&values)[4] =
|
||||
timingFunctionValues[uint8_t(timing.keyword._0)];
|
||||
timingFunctionValues[uint8_t(aFunction.keyword._0)];
|
||||
return AsVariant(KeywordFunction{
|
||||
timing.keyword._0,
|
||||
aFunction.keyword._0,
|
||||
SMILKeySpline{values[0], values[1], values[2], values[3]}});
|
||||
}
|
||||
case StyleComputedTimingFunction::Tag::CubicBezier:
|
||||
return AsVariant(
|
||||
SMILKeySpline{timing.cubic_bezier.x1, timing.cubic_bezier.y1,
|
||||
timing.cubic_bezier.x2, timing.cubic_bezier.y2});
|
||||
SMILKeySpline{aFunction.cubic_bezier.x1, aFunction.cubic_bezier.y1,
|
||||
aFunction.cubic_bezier.x2, aFunction.cubic_bezier.y2});
|
||||
case StyleComputedTimingFunction::Tag::Steps:
|
||||
return AsVariant(
|
||||
StepFunc{static_cast<uint32_t>(timing.steps._0), timing.steps._1});
|
||||
return AsVariant(StepFunc{static_cast<uint32_t>(aFunction.steps._0),
|
||||
aFunction.steps._1});
|
||||
case StyleComputedTimingFunction::Tag::LinearFunction: {
|
||||
StylePiecewiseLinearFunction result;
|
||||
Servo_CreatePiecewiseLinearFunction(&timing.linear_function._0, &result);
|
||||
Servo_CreatePiecewiseLinearFunction(&aFunction.linear_function._0,
|
||||
&result);
|
||||
return AsVariant(result);
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown timing function.");
|
||||
return ConstructFunction(nsTimingFunction{StyleTimingKeyword::Linear});
|
||||
return ConstructFunction(mozilla::StyleComputedTimingFunction::Keyword(
|
||||
StyleTimingKeyword::Linear));
|
||||
}
|
||||
|
||||
ComputedTimingFunction::ComputedTimingFunction(
|
||||
const nsTimingFunction& aFunction)
|
||||
const StyleComputedTimingFunction& aFunction)
|
||||
: mFunction{ConstructFunction(aFunction)} {}
|
||||
|
||||
static inline double StepTiming(
|
||||
ComputedTimingFunction::ComputedTimingFunction(
|
||||
const nsTimingFunction& aFunction)
|
||||
: ComputedTimingFunction{aFunction.mTiming} {}
|
||||
|
||||
double ComputedTimingFunction::StepTiming(
|
||||
const ComputedTimingFunction::StepFunc& aStepFunc, double aPortion,
|
||||
ComputedTimingFunction::BeforeFlag aBeforeFlag) {
|
||||
// Use the algorithm defined in the spec:
|
||||
|
@ -185,7 +190,16 @@ double ComputedTimingFunction::GetValue(
|
|||
|
||||
void ComputedTimingFunction::AppendToString(nsACString& aResult) const {
|
||||
nsTimingFunction timing;
|
||||
timing.mTiming = {mFunction.match(
|
||||
// This does not preserve the original input either - that is,
|
||||
// linear(0 0% 50%, 1 50% 100%) -> linear(0 0%, 0 50%, 1 50%, 1 100%)
|
||||
timing.mTiming = {ToStyleComputedTimingFunction(*this)};
|
||||
Servo_SerializeEasing(&timing, &aResult);
|
||||
}
|
||||
|
||||
StyleComputedTimingFunction
|
||||
ComputedTimingFunction::ToStyleComputedTimingFunction(
|
||||
const ComputedTimingFunction& aComputedTimingFunction) {
|
||||
return aComputedTimingFunction.mFunction.match(
|
||||
[](const KeywordFunction& aFunction) {
|
||||
return StyleComputedTimingFunction::Keyword(aFunction.mKeyword);
|
||||
},
|
||||
|
@ -201,7 +215,6 @@ void ComputedTimingFunction::AppendToString(nsACString& aResult) const {
|
|||
static_cast<int>(aFunction.mSteps), aFunction.mPos);
|
||||
},
|
||||
[](const StylePiecewiseLinearFunction& aFunction) {
|
||||
// TODO(dshin, bug 1773493): Having to go back and forth isn't ideal.
|
||||
Vector<StyleComputedLinearStop> stops;
|
||||
bool reserved = stops.initCapacity(aFunction.entries.Length());
|
||||
MOZ_RELEASE_ASSERT(reserved, "Failed to reserve memory");
|
||||
|
@ -212,75 +225,6 @@ void ComputedTimingFunction::AppendToString(nsACString& aResult) const {
|
|||
}
|
||||
return StyleComputedTimingFunction::LinearFunction(
|
||||
StyleOwnedSlice<StyleComputedLinearStop>{std::move(stops)});
|
||||
})};
|
||||
Servo_SerializeEasing(&timing, &aResult);
|
||||
}
|
||||
|
||||
Maybe<ComputedTimingFunction> ComputedTimingFunction::FromLayersTimingFunction(
|
||||
const layers::TimingFunction& aTimingFunction) {
|
||||
switch (aTimingFunction.type()) {
|
||||
case layers::TimingFunction::Tnull_t:
|
||||
return Nothing();
|
||||
case layers::TimingFunction::TCubicBezierFunction: {
|
||||
auto cbf = aTimingFunction.get_CubicBezierFunction();
|
||||
return Some(ComputedTimingFunction::CubicBezier(cbf.x1(), cbf.y1(),
|
||||
cbf.x2(), cbf.y2()));
|
||||
}
|
||||
case layers::TimingFunction::TStepFunction: {
|
||||
auto sf = aTimingFunction.get_StepFunction();
|
||||
StyleStepPosition pos = static_cast<StyleStepPosition>(sf.type());
|
||||
return Some(ComputedTimingFunction::Steps(sf.steps(), pos));
|
||||
}
|
||||
case layers::TimingFunction::TLinearFunction: {
|
||||
auto lf = aTimingFunction.get_LinearFunction();
|
||||
Vector<StylePiecewiseLinearFunctionEntry> stops;
|
||||
bool reserved = stops.initCapacity(lf.stops().Length());
|
||||
MOZ_RELEASE_ASSERT(reserved, "Failed to reserve memory");
|
||||
for (const auto& e : lf.stops()) {
|
||||
stops.infallibleAppend(
|
||||
StylePiecewiseLinearFunctionEntry{e.input(), e.output()});
|
||||
}
|
||||
StylePiecewiseLinearFunction result;
|
||||
return Some(ComputedTimingFunction{result});
|
||||
}
|
||||
case layers::TimingFunction::T__None:
|
||||
break;
|
||||
}
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected timing function type.");
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
layers::TimingFunction ComputedTimingFunction::ToLayersTimingFunction(
|
||||
const Maybe<ComputedTimingFunction>& aComputedTimingFunction) {
|
||||
if (aComputedTimingFunction.isNothing()) {
|
||||
return {null_t{}};
|
||||
}
|
||||
return aComputedTimingFunction->mFunction.match(
|
||||
[](const KeywordFunction& aFunction) {
|
||||
return layers::TimingFunction{layers::CubicBezierFunction{
|
||||
static_cast<float>(aFunction.mFunction.X1()),
|
||||
static_cast<float>(aFunction.mFunction.Y1()),
|
||||
static_cast<float>(aFunction.mFunction.X2()),
|
||||
static_cast<float>(aFunction.mFunction.Y2())}};
|
||||
},
|
||||
[](const SMILKeySpline& aFunction) {
|
||||
return layers::TimingFunction{
|
||||
layers::CubicBezierFunction{static_cast<float>(aFunction.X1()),
|
||||
static_cast<float>(aFunction.Y1()),
|
||||
static_cast<float>(aFunction.X2()),
|
||||
static_cast<float>(aFunction.Y2())}};
|
||||
},
|
||||
[](const StepFunc& aFunction) {
|
||||
return layers::TimingFunction{
|
||||
layers::StepFunction{static_cast<int>(aFunction.mSteps),
|
||||
static_cast<uint8_t>(aFunction.mPos)}};
|
||||
},
|
||||
[](const StylePiecewiseLinearFunction& aFunction) {
|
||||
nsTArray<layers::LinearStop> stops{aFunction.entries.Length()};
|
||||
for (const auto& e : aFunction.entries.AsSpan()) {
|
||||
stops.AppendElement(layers::LinearStop{e.x, e.y});
|
||||
}
|
||||
return layers::TimingFunction{layers::LinearFunction{stops}};
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -18,38 +18,13 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
namespace layers {
|
||||
class TimingFunction;
|
||||
}
|
||||
|
||||
class ComputedTimingFunction {
|
||||
public:
|
||||
struct StepFunc {
|
||||
uint32_t mSteps = 1;
|
||||
StyleStepPosition mPos = StyleStepPosition::End;
|
||||
constexpr StepFunc() = default;
|
||||
constexpr StepFunc(uint32_t aSteps, StyleStepPosition aPos)
|
||||
: mSteps(aSteps), mPos(aPos){};
|
||||
bool operator==(const StepFunc& aOther) const {
|
||||
return mSteps == aOther.mSteps && mPos == aOther.mPos;
|
||||
}
|
||||
};
|
||||
|
||||
static ComputedTimingFunction CubicBezier(double x1, double y1, double x2,
|
||||
double y2) {
|
||||
return ComputedTimingFunction(x1, y1, x2, y2);
|
||||
}
|
||||
static ComputedTimingFunction Steps(uint32_t aSteps, StyleStepPosition aPos) {
|
||||
MOZ_ASSERT(aSteps > 0, "The number of steps should be 1 or more");
|
||||
return ComputedTimingFunction(aSteps, aPos);
|
||||
}
|
||||
|
||||
static Maybe<ComputedTimingFunction> FromLayersTimingFunction(
|
||||
const layers::TimingFunction& aTimingFunction);
|
||||
static layers::TimingFunction ToLayersTimingFunction(
|
||||
const Maybe<ComputedTimingFunction>& aComputedTimingFunction);
|
||||
|
||||
explicit ComputedTimingFunction(const nsTimingFunction& aFunction);
|
||||
explicit ComputedTimingFunction(const StyleComputedTimingFunction& aFunction);
|
||||
|
||||
static StyleComputedTimingFunction ToStyleComputedTimingFunction(
|
||||
const ComputedTimingFunction& aComputedTimingFunction);
|
||||
|
||||
// BeforeFlag is used in step timing function.
|
||||
// https://drafts.csswg.org/css-easing/#before-flag
|
||||
|
@ -62,37 +37,7 @@ class ComputedTimingFunction {
|
|||
return !(*this == aOther);
|
||||
}
|
||||
bool operator==(const nsTimingFunction& aOther) const {
|
||||
return mFunction.match(
|
||||
[&aOther](const KeywordFunction& aFunction) {
|
||||
return aOther.mTiming.tag ==
|
||||
StyleComputedTimingFunction::Tag::Keyword &&
|
||||
aFunction.mKeyword == aOther.mTiming.keyword._0;
|
||||
},
|
||||
[&aOther](const SMILKeySpline& aFunction) {
|
||||
return aOther.mTiming.tag ==
|
||||
StyleComputedTimingFunction::Tag::CubicBezier &&
|
||||
aFunction.X1() == aOther.mTiming.cubic_bezier.x1 &&
|
||||
aFunction.Y1() == aOther.mTiming.cubic_bezier.y1 &&
|
||||
aFunction.X2() == aOther.mTiming.cubic_bezier.x2 &&
|
||||
aFunction.Y2() == aOther.mTiming.cubic_bezier.y2;
|
||||
},
|
||||
[&aOther](const StepFunc& aFunction) {
|
||||
return aOther.mTiming.tag ==
|
||||
StyleComputedTimingFunction::Tag::Steps &&
|
||||
aFunction.mSteps == uint32_t(aOther.mTiming.steps._0) &&
|
||||
aFunction.mPos == aOther.mTiming.steps._1;
|
||||
},
|
||||
[&aOther](const StylePiecewiseLinearFunction& aFunction) {
|
||||
if (aOther.mTiming.tag !=
|
||||
StyleComputedTimingFunction::Tag::LinearFunction) {
|
||||
return false;
|
||||
}
|
||||
StylePiecewiseLinearFunction other;
|
||||
// TODO(dshin, bug 1773493): Having to go back and forth isn't ideal.
|
||||
Servo_CreatePiecewiseLinearFunction(
|
||||
&aOther.mTiming.linear_function._0, &other);
|
||||
return aFunction.entries == other.entries;
|
||||
});
|
||||
return ToStyleComputedTimingFunction(*this) == aOther.mTiming;
|
||||
}
|
||||
bool operator!=(const nsTimingFunction& aOther) const {
|
||||
return !(*this == aOther);
|
||||
|
@ -105,6 +50,17 @@ class ComputedTimingFunction {
|
|||
}
|
||||
|
||||
private:
|
||||
struct StepFunc {
|
||||
uint32_t mSteps = 1;
|
||||
StyleStepPosition mPos = StyleStepPosition::End;
|
||||
constexpr StepFunc() = default;
|
||||
constexpr StepFunc(uint32_t aSteps, StyleStepPosition aPos)
|
||||
: mSteps(aSteps), mPos(aPos){};
|
||||
bool operator==(const StepFunc& aOther) const {
|
||||
return mSteps == aOther.mSteps && mPos == aOther.mPos;
|
||||
}
|
||||
};
|
||||
|
||||
struct KeywordFunction {
|
||||
KeywordFunction(mozilla::StyleTimingKeyword aKeyword,
|
||||
SMILKeySpline aFunction)
|
||||
|
@ -120,14 +76,16 @@ class ComputedTimingFunction {
|
|||
using Function = mozilla::Variant<KeywordFunction, SMILKeySpline, StepFunc,
|
||||
StylePiecewiseLinearFunction>;
|
||||
|
||||
static Function ConstructFunction(const nsTimingFunction& aFunction);
|
||||
static Function ConstructFunction(
|
||||
const StyleComputedTimingFunction& aFunction);
|
||||
ComputedTimingFunction(double x1, double y1, double x2, double y2)
|
||||
: mFunction{AsVariant(SMILKeySpline{x1, y1, x2, y2})} {}
|
||||
ComputedTimingFunction(uint32_t aSteps, StyleStepPosition aPos)
|
||||
: mFunction{AsVariant(StepFunc{aSteps, aPos})} {}
|
||||
explicit ComputedTimingFunction(StylePiecewiseLinearFunction aFunction)
|
||||
: mFunction{AsVariant(std::move(aFunction))} {}
|
||||
|
||||
static double StepTiming(const StepFunc& aStepFunc, double aPortion,
|
||||
BeforeFlag aBeforeFlag);
|
||||
Function mFunction;
|
||||
};
|
||||
|
||||
|
|
|
@ -460,6 +460,10 @@ AnimationStorageData AnimationHelper::ExtractAnimations(
|
|||
|
||||
PropertyAnimation* propertyAnimation =
|
||||
currData->mAnimations.AppendElement();
|
||||
Maybe<mozilla::ComputedTimingFunction> easingFunction;
|
||||
if (animation.easingFunction().isSome()) {
|
||||
easingFunction.emplace(*animation.easingFunction());
|
||||
}
|
||||
|
||||
propertyAnimation->mOriginTime = animation.originTime();
|
||||
propertyAnimation->mStartTime = animation.startTime();
|
||||
|
@ -477,21 +481,23 @@ AnimationStorageData AnimationHelper::ExtractAnimations(
|
|||
animation.iterationStart(),
|
||||
static_cast<dom::PlaybackDirection>(animation.direction()),
|
||||
GetAdjustedFillMode(animation),
|
||||
ComputedTimingFunction::FromLayersTimingFunction(
|
||||
animation.easingFunction())};
|
||||
std::move(easingFunction)};
|
||||
propertyAnimation->mScrollTimelineOptions =
|
||||
animation.scrollTimelineOptions();
|
||||
|
||||
nsTArray<PropertyAnimation::SegmentData>& segmentData =
|
||||
propertyAnimation->mSegments;
|
||||
for (const AnimationSegment& segment : animation.segments()) {
|
||||
Maybe<mozilla::ComputedTimingFunction> sampleFn;
|
||||
if (segment.sampleFn().isSome()) {
|
||||
sampleFn.emplace(*segment.sampleFn());
|
||||
}
|
||||
segmentData.AppendElement(PropertyAnimation::SegmentData{
|
||||
AnimationValue::FromAnimatable(animation.property(),
|
||||
segment.startState()),
|
||||
AnimationValue::FromAnimatable(animation.property(),
|
||||
segment.endState()),
|
||||
ComputedTimingFunction::FromLayersTimingFunction(segment.sampleFn()),
|
||||
segment.startPortion(), segment.endPortion(),
|
||||
std::move(sampleFn), segment.startPortion(), segment.endPortion(),
|
||||
static_cast<dom::CompositeOperation>(segment.startComposite()),
|
||||
static_cast<dom::CompositeOperation>(segment.endComposite())});
|
||||
}
|
||||
|
|
|
@ -480,8 +480,12 @@ void AnimationInfo::AddAnimationForProperty(
|
|||
? static_cast<float>(aAnimation->PlaybackRate())
|
||||
: std::numeric_limits<float>::quiet_NaN();
|
||||
animation->transformData() = aTransformData;
|
||||
animation->easingFunction() =
|
||||
ComputedTimingFunction::ToLayersTimingFunction(timing.TimingFunction());
|
||||
animation->easingFunction() = Nothing();
|
||||
if (timing.TimingFunction().isSome()) {
|
||||
animation->easingFunction().emplace(
|
||||
ComputedTimingFunction::ToStyleComputedTimingFunction(
|
||||
*timing.TimingFunction()));
|
||||
}
|
||||
animation->iterationComposite() = static_cast<uint8_t>(
|
||||
aAnimation->GetEffect()->AsKeyframeEffect()->IterationComposite());
|
||||
animation->isNotPlaying() = !aAnimation->IsPlaying();
|
||||
|
@ -518,8 +522,12 @@ void AnimationInfo::AddAnimationForProperty(
|
|||
animSegment->startComposite() =
|
||||
static_cast<uint8_t>(segment.mFromComposite);
|
||||
animSegment->endComposite() = static_cast<uint8_t>(segment.mToComposite);
|
||||
animSegment->sampleFn() =
|
||||
ComputedTimingFunction::ToLayersTimingFunction(segment.mTimingFunction);
|
||||
animSegment->sampleFn() = Nothing();
|
||||
if (segment.mTimingFunction.isSome()) {
|
||||
animSegment->sampleFn().emplace(
|
||||
ComputedTimingFunction::ToStyleComputedTimingFunction(
|
||||
*segment.mTimingFunction));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -834,7 +842,7 @@ void AnimationInfo::AddNonAnimatingTransformLikePropertiesStyles(
|
|||
: AddAnimation();
|
||||
animation->property() = aProperty;
|
||||
animation->baseStyle() = std::move(aBaseStyle);
|
||||
animation->easingFunction() = null_t();
|
||||
animation->easingFunction() = Nothing();
|
||||
animation->isNotAnimating() = true;
|
||||
};
|
||||
|
||||
|
|
|
@ -1009,6 +1009,7 @@ IMPL_PARAMTRAITS_BY_SERDE(StyleRotate)
|
|||
IMPL_PARAMTRAITS_BY_SERDE(StyleScale)
|
||||
IMPL_PARAMTRAITS_BY_SERDE(StyleTranslate)
|
||||
IMPL_PARAMTRAITS_BY_SERDE(StyleTransform)
|
||||
IMPL_PARAMTRAITS_BY_SERDE(StyleComputedTimingFunction)
|
||||
|
||||
} /* namespace IPC */
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ using mozilla::StyleRotate from "mozilla/ServoStyleConsts.h";
|
|||
using mozilla::StyleScale from "mozilla/ServoStyleConsts.h";
|
||||
using mozilla::StyleTranslate from "mozilla/ServoStyleConsts.h";
|
||||
using mozilla::StyleTransform from "mozilla/ServoStyleConsts.h";
|
||||
using mozilla::StyleComputedTimingFunction from "mozilla/ServoStyleConsts.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -88,35 +89,6 @@ struct OpAttachAsyncCompositable {
|
|||
LayerHandle layer;
|
||||
CompositableHandle compositable;
|
||||
};
|
||||
|
||||
struct CubicBezierFunction {
|
||||
float x1;
|
||||
float y1;
|
||||
float x2;
|
||||
float y2;
|
||||
};
|
||||
|
||||
struct StepFunction {
|
||||
int steps;
|
||||
uint8_t type; // Converted from StyleStepPosition.
|
||||
};
|
||||
|
||||
struct LinearStop {
|
||||
float input;
|
||||
float output;
|
||||
};
|
||||
|
||||
struct LinearFunction {
|
||||
LinearStop[] stops;
|
||||
};
|
||||
|
||||
union TimingFunction {
|
||||
null_t;
|
||||
CubicBezierFunction;
|
||||
StepFunction;
|
||||
LinearFunction;
|
||||
};
|
||||
|
||||
struct LayerColor { DeviceColor value; };
|
||||
|
||||
[Comparable] union Animatable {
|
||||
|
@ -140,7 +112,7 @@ struct AnimationSegment {
|
|||
float endPortion;
|
||||
uint8_t startComposite;
|
||||
uint8_t endComposite;
|
||||
TimingFunction sampleFn;
|
||||
StyleComputedTimingFunction? sampleFn;
|
||||
};
|
||||
|
||||
[Comparable] struct MotionPathData {
|
||||
|
@ -234,7 +206,7 @@ struct Animation {
|
|||
// to the playbackRate is being performed.
|
||||
float previousPlaybackRate;
|
||||
// This is used in the transformed progress calculation.
|
||||
TimingFunction easingFunction;
|
||||
StyleComputedTimingFunction? easingFunction;
|
||||
uint8_t iterationComposite;
|
||||
// True if the animation has a fixed current time (e.g. paused and
|
||||
// forward-filling animations).
|
||||
|
|
|
@ -86,6 +86,7 @@ BASIC_SERDE_FUNCS(StyleTransform)
|
|||
BASIC_SERDE_FUNCS(StyleOffsetPath)
|
||||
BASIC_SERDE_FUNCS(StyleOffsetRotate)
|
||||
BASIC_SERDE_FUNCS(StylePositionOrAuto)
|
||||
BASIC_SERDE_FUNCS(StyleComputedTimingFunction)
|
||||
|
||||
#undef BASIC_SERDE_FUNCS
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ use crate::values::generics::Optional;
|
|||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
)]
|
||||
#[repr(C)]
|
||||
pub struct LinearStop<Number, Percentage> {
|
||||
|
@ -44,9 +46,12 @@ pub struct LinearStop<Number, Percentage> {
|
|||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
)]
|
||||
#[value_info(ty = "TIMING_FUNCTION")]
|
||||
#[repr(u8, C)]
|
||||
/// cbindgen:private-default-tagged-enum-constructor=false
|
||||
pub enum TimingFunction<Integer, Number, Percentage> {
|
||||
/// `linear | ease | ease-in | ease-out | ease-in-out`
|
||||
Keyword(TimingKeyword),
|
||||
|
@ -86,6 +91,8 @@ pub enum TimingFunction<Integer, Number, Percentage> {
|
|||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
)]
|
||||
#[repr(u8)]
|
||||
pub enum TimingKeyword {
|
||||
|
@ -120,6 +127,8 @@ fn step_position_jump_enabled(_context: &ParserContext) -> bool {
|
|||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
)]
|
||||
#[repr(u8)]
|
||||
pub enum StepPosition {
|
||||
|
|
|
@ -336,6 +336,8 @@ pub use page::PageSize;
|
|||
ToCss,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
)]
|
||||
#[repr(C, u8)]
|
||||
pub enum Optional<T> {
|
||||
|
|
|
@ -103,7 +103,6 @@ include = [
|
|||
"FontFamily",
|
||||
"FontFamilyNameSyntax",
|
||||
"OverflowWrap",
|
||||
"TimingFunction",
|
||||
"OffsetPath",
|
||||
"OffsetRotate",
|
||||
"UnicodeRange",
|
||||
|
@ -810,6 +809,12 @@ renaming_overrides_prefixing = true
|
|||
StyleGenericPositionOrAuto(): tag(Tag::Auto) {}
|
||||
"""
|
||||
|
||||
"TimingFunction" = """
|
||||
public:
|
||||
// The implementation of IPC LayersMessages needs this to be public.
|
||||
StyleTimingFunction() : tag(Tag::Keyword) { ::new (&keyword._0) (StyleTimingKeyword) (StyleTimingKeyword::Linear); }
|
||||
"""
|
||||
|
||||
"GenericImage" = """
|
||||
public:
|
||||
// Returns the intrinsic resolution of the image.
|
||||
|
|
|
@ -1087,6 +1087,12 @@ impl_basic_serde_funcs!(
|
|||
computed::position::PositionOrAuto
|
||||
);
|
||||
|
||||
impl_basic_serde_funcs!(
|
||||
Servo_StyleComputedTimingFunction_Serialize,
|
||||
Servo_StyleComputedTimingFunction_Deserialize,
|
||||
computed::easing::ComputedTimingFunction
|
||||
);
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_SVGPathData_Normalize(
|
||||
input: &specified::SVGPathData,
|
||||
|
|
Загрузка…
Ссылка в новой задаче