Skip to content

Commit 8257df9

Browse files
author
Swarup Ukil
committed
Bug 1993311 - Update hline and vline command parsing to support <position> values. r=boris,firefox-style-system-reviewers,firefox-svg-reviewers,layout-reviewers,longsonr
Differential Revision: https://phabricator.services.mozilla.com/D271463
1 parent bbbf187 commit 8257df9

File tree

16 files changed

+590
-311
lines changed

16 files changed

+590
-311
lines changed

dom/svg/SVGAnimatedPathSegList.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,19 @@ static StyleCurveControlPoint<float> MakeControlPoint(PositionType type,
4343
if (type == PositionType::Absolute) {
4444
return StyleCurveControlPoint<float>::Absolute({x, y});
4545
} else {
46-
return StyleCurveControlPoint<float>::Relative(
47-
StyleRelativeControlPoint<float>{{x, y}, StyleControlReference::None});
46+
const auto rcp =
47+
StyleRelativeControlPoint<float>{{x, y}, StyleControlReference::None};
48+
return StyleCurveControlPoint<float>::Relative(rcp);
49+
}
50+
}
51+
52+
static StyleAxisEndPoint<float> MakeAxisEndPoint(PositionType type,
53+
float end_point) {
54+
if (type == PositionType::Absolute) {
55+
const auto pos = StyleAxisPosition<float>::LengthPercent(end_point);
56+
return StyleAxisEndPoint<float>::ToPosition(pos);
57+
} else {
58+
return StyleAxisEndPoint<float>::ByCoordinate(end_point);
4859
}
4960
}
5061

@@ -139,13 +150,17 @@ class MOZ_STACK_CLASS SVGPathSegmentInitWrapper final {
139150
mInit.mValues[3] ? StyleArcSize::Large : StyleArcSize::Small,
140151
mInit.mValues[2]);
141152
case 'H':
142-
return StylePathCommand::HLine(StyleByTo::To, mInit.mValues[0]);
153+
return StylePathCommand::HLine(
154+
MakeAxisEndPoint(PositionType::Absolute, mInit.mValues[0]));
143155
case 'h':
144-
return StylePathCommand::HLine(StyleByTo::By, mInit.mValues[0]);
156+
return StylePathCommand::HLine(
157+
MakeAxisEndPoint(PositionType::Relative, mInit.mValues[0]));
145158
case 'V':
146-
return StylePathCommand::VLine(StyleByTo::To, mInit.mValues[0]);
159+
return StylePathCommand::VLine(
160+
MakeAxisEndPoint(PositionType::Absolute, mInit.mValues[0]));
147161
case 'v':
148-
return StylePathCommand::VLine(StyleByTo::By, mInit.mValues[0]);
162+
return StylePathCommand::VLine(
163+
MakeAxisEndPoint(PositionType::Relative, mInit.mValues[0]));
149164
case 'S':
150165
return StylePathCommand::SmoothCubic(
151166
MakeEndPoint(PositionType::Absolute, mInit.mValues[2],

dom/svg/SVGPathData.cpp

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -189,16 +189,6 @@ static inline StyleCSSFloat GetRotate(const StyleAngle& aAngle) {
189189
return aAngle.ToDegrees();
190190
}
191191

192-
static inline StyleCSSFloat Resolve(const StyleCSSFloat& aValue,
193-
CSSCoord aBasis) {
194-
return aValue;
195-
}
196-
197-
static inline StyleCSSFloat Resolve(const LengthPercentage& aValue,
198-
CSSCoord aBasis) {
199-
return aValue.ResolveToCSSPixels(aBasis);
200-
}
201-
202192
template <typename Angle, typename Position, typename LP>
203193
static already_AddRefed<Path> BuildPathInternal(
204194
Span<const StyleGenericShapeCommand<Angle, Position, LP>> aPath,
@@ -327,8 +317,8 @@ static already_AddRefed<Path> BuildPathInternal(
327317
break;
328318
}
329319
case Command::Tag::HLine: {
330-
const float x = Resolve(cmd.h_line.x, aPercentageBasis.width);
331-
if (cmd.h_line.by_to == StyleByTo::To) {
320+
const auto x = cmd.h_line.x.ToGfxCoord(aPercentageBasis.width);
321+
if (cmd.h_line.x.IsToPosition()) {
332322
segEnd = Point(x, segStart.y);
333323
} else {
334324
segEnd = segStart + Point(x, 0.0f);
@@ -341,8 +331,8 @@ static already_AddRefed<Path> BuildPathInternal(
341331
break;
342332
}
343333
case Command::Tag::VLine: {
344-
const float y = Resolve(cmd.v_line.y, aPercentageBasis.height);
345-
if (cmd.v_line.by_to == StyleByTo::To) {
334+
const auto y = cmd.v_line.y.ToGfxCoord(aPercentageBasis.height);
335+
if (cmd.v_line.y.IsToPosition()) {
346336
segEnd = Point(segStart.x, y);
347337
} else {
348338
segEnd = segStart + Point(0.0f, y);
@@ -640,19 +630,21 @@ void SVGPathData::GetMarkerPositioningData(Span<const StylePathCommand> aPath,
640630
break;
641631
}
642632
case StylePathCommand::Tag::HLine: {
643-
if (cmd.h_line.by_to == StyleByTo::To) {
644-
segEnd = Point(cmd.h_line.x, segStart.y) * aZoom;
633+
const auto x = cmd.h_line.x.ToGfxCoord();
634+
if (cmd.h_line.x.IsToPosition()) {
635+
segEnd = Point(x, segStart.y) * aZoom;
645636
} else {
646-
segEnd = segStart + Point(cmd.h_line.x, 0.0f) * aZoom;
637+
segEnd = segStart + Point(x, 0.0f) * aZoom;
647638
}
648639
segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
649640
break;
650641
}
651642
case StylePathCommand::Tag::VLine: {
652-
if (cmd.v_line.by_to == StyleByTo::To) {
653-
segEnd = Point(segStart.x, cmd.v_line.y) * aZoom;
643+
const auto y = cmd.v_line.y.ToGfxCoord();
644+
if (cmd.v_line.y.IsToPosition()) {
645+
segEnd = Point(segStart.x, y) * aZoom;
654646
} else {
655-
segEnd = segStart + Point(0.0f, cmd.v_line.y) * aZoom;
647+
segEnd = segStart + Point(0.0f, y) * aZoom;
656648
}
657649
segStartAngle = segEndAngle = AngleOfVector(segEnd, segStart);
658650
break;

dom/svg/SVGPathSegUtils.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,8 @@ void SVGPathSegUtils::TraversePathSegment(const StylePathCommand& aCommand,
188188
break;
189189
}
190190
case StylePathCommand::Tag::HLine: {
191-
Point to(aCommand.h_line.by_to == StyleByTo::To
192-
? aCommand.h_line.x
193-
: aState.pos.x + aCommand.h_line.x,
191+
const auto x = aCommand.h_line.x.ToGfxCoord();
192+
Point to(aCommand.h_line.x.IsToPosition() ? x : aState.pos.x + x,
194193
aState.pos.y);
195194
if (aState.ShouldUpdateLengthAndControlPoints()) {
196195
aState.length += std::fabs(to.x - aState.pos.x);
@@ -200,9 +199,9 @@ void SVGPathSegUtils::TraversePathSegment(const StylePathCommand& aCommand,
200199
break;
201200
}
202201
case StylePathCommand::Tag::VLine: {
203-
Point to(aState.pos.x, aCommand.v_line.by_to == StyleByTo::To
204-
? aCommand.v_line.y
205-
: aState.pos.y + aCommand.v_line.y);
202+
const auto y = aCommand.v_line.y.ToGfxCoord();
203+
Point to(aState.pos.x,
204+
aCommand.v_line.y.IsToPosition() ? y : aState.pos.y + y);
206205
if (aState.ShouldUpdateLengthAndControlPoints()) {
207206
aState.length += std::fabs(to.y - aState.pos.y);
208207
aState.cp1 = aState.cp2 = to;
@@ -434,8 +433,8 @@ Maybe<gfx::Rect> SVGPathToAxisAlignedRect(Span<const StylePathCommand> aPath) {
434433
break;
435434
}
436435
case StylePathCommand::Tag::HLine: {
437-
Point to = gfx::Point(cmd.h_line.x, segStart.y);
438-
if (cmd.h_line.by_to == StyleByTo::By) {
436+
Point to = gfx::Point(cmd.h_line.x.ToGfxCoord(), segStart.y);
437+
if (cmd.h_line.x.IsByCoordinate()) {
439438
to.x += segStart.x;
440439
}
441440

@@ -446,8 +445,8 @@ Maybe<gfx::Rect> SVGPathToAxisAlignedRect(Span<const StylePathCommand> aPath) {
446445
break;
447446
}
448447
case StylePathCommand::Tag::VLine: {
449-
Point to = gfx::Point(segStart.x, cmd.v_line.y);
450-
if (cmd.h_line.by_to == StyleByTo::By) {
448+
Point to = gfx::Point(segStart.x, cmd.v_line.y.ToGfxCoord());
449+
if (cmd.v_line.y.IsByCoordinate()) {
451450
to.y += segStart.y;
452451
}
453452

dom/svg/SVGPathSegment.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,12 @@ SVGPathSegment::SVGPathSegment(SVGPathElement* aSVGPathElement,
8585
break;
8686
}
8787
case StylePathCommand::Tag::HLine:
88-
mCommand.AssignLiteral(aCommand.h_line.by_to == StyleByTo::To ? "H"
89-
: "h");
90-
mValues.AppendElement(aCommand.h_line.x);
88+
mCommand.AssignLiteral(aCommand.h_line.x.IsToPosition() ? "H" : "h");
89+
mValues.AppendElement(aCommand.h_line.x.ToGfxCoord());
9190
break;
9291
case StylePathCommand::Tag::VLine:
93-
mCommand.AssignLiteral(aCommand.v_line.by_to == StyleByTo::To ? "V"
94-
: "v");
95-
mValues.AppendElement(aCommand.v_line.y);
92+
mCommand.AssignLiteral(aCommand.v_line.y.IsToPosition() ? "V" : "v");
93+
mValues.AppendElement(aCommand.v_line.y.ToGfxCoord());
9694
break;
9795
case StylePathCommand::Tag::SmoothCubic:
9896
mCommand.AssignLiteral(aCommand.smooth_cubic.point.IsToPosition() ? "S"

layout/inspector/tests/test_bug877690.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,9 @@
292292
ok(testValues(values, expected), "property box-shadow's values");
293293

294294
// Regression test for bug 1255379.
295-
var shapeFunction = [ "close", "evenodd", "nonzero", "by", "to", "cw", "ccw",
296-
"small", "large", "end", "origin", "start", "center",
297-
"left", "right", "top", "bottom"];
295+
var shapeFunction = [ "close", "evenodd", "nonzero", "cw", "ccw", "small", "large",
296+
"end", "origin", "start", "center", "left", "right", "top",
297+
"bottom", "x-end","x-start", "y-end","y-start" ];
298298
var expected = [ "inherit", "initial", "unset", "revert", "revert-layer",
299299
"none", "url", "polygon", "circle", "ellipse", "inset",
300300
"path", "rect", "xywh", "fill-box", "stroke-box",

layout/style/ServoStyleConstsInlines.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,29 @@ inline gfx::Point StyleCommandEndPoint<
13221322
}
13231323
}
13241324

1325+
template <>
1326+
inline gfx::Coord StyleAxisEndPoint<StyleCSSFloat>::ToGfxCoord(
1327+
const StyleCSSFloat* aBasis) const {
1328+
if (IsToPosition()) {
1329+
const auto pos = AsToPosition();
1330+
MOZ_ASSERT(pos.IsLengthPercent());
1331+
return gfx::Coord(pos.AsLengthPercent());
1332+
}
1333+
return gfx::Coord(AsByCoordinate());
1334+
}
1335+
1336+
template <>
1337+
inline gfx::Coord StyleAxisEndPoint<LengthPercentage>::ToGfxCoord(
1338+
const StyleCSSFloat* aBasis) const {
1339+
MOZ_ASSERT(aBasis);
1340+
if (IsToPosition()) {
1341+
const auto pos = AsToPosition();
1342+
MOZ_ASSERT(pos.IsLengthPercent());
1343+
return gfx::Coord(pos.AsLengthPercent().ResolveToCSSPixels(*aBasis));
1344+
}
1345+
return gfx::Coord(AsByCoordinate().ResolveToCSSPixels(*aBasis));
1346+
}
1347+
13251348
template <>
13261349
inline gfx::Point
13271350
StyleControlPoint<StyleShapePosition<StyleCSSFloat>, StyleCSSFloat>::ToGfxPoint(

servo/components/style/values/computed/basic_shape.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ pub type RelativeControlPoint = generic::RelativeControlPoint<LengthPercentage>;
6262
/// The computed value of 'CommandEndPoint'.
6363
pub type CommandEndPoint = generic::CommandEndPoint<Position, LengthPercentage>;
6464

65+
/// The computed value of hline and vline's endpoint.
66+
pub type AxisEndPoint = generic::AxisEndPoint<LengthPercentage>;
67+
6568
/// Animate from `Shape` to `Path`, and vice versa.
6669
macro_rules! animate_shape {
6770
(
@@ -144,7 +147,6 @@ impl Animate for PathOrShapeFunction {
144147
impl From<&PathCommand> for ShapeCommand {
145148
#[inline]
146149
fn from(path: &PathCommand) -> Self {
147-
use crate::values::computed::CSSPixelLength;
148150
match path {
149151
&PathCommand::Close => Self::Close,
150152
&PathCommand::Move { ref point } => Self::Move {
@@ -153,14 +155,8 @@ impl From<&PathCommand> for ShapeCommand {
153155
&PathCommand::Line { ref point } => Self::Move {
154156
point: point.into(),
155157
},
156-
&PathCommand::HLine { by_to, x } => Self::HLine {
157-
by_to,
158-
x: LengthPercentage::new_length(CSSPixelLength::new(x)),
159-
},
160-
&PathCommand::VLine { by_to, y } => Self::VLine {
161-
by_to,
162-
y: LengthPercentage::new_length(CSSPixelLength::new(y)),
163-
},
158+
&PathCommand::HLine { ref x } => Self::HLine { x: x.into() },
159+
&PathCommand::VLine { ref y } => Self::VLine { y: y.into() },
164160
&PathCommand::CubicCurve {
165161
ref point,
166162
ref control1,
@@ -236,6 +232,25 @@ impl From<&generic::CommandEndPoint<ShapePosition<CSSFloat>, CSSFloat>> for Comm
236232
}
237233
}
238234

235+
impl From<&generic::AxisEndPoint<CSSFloat>> for AxisEndPoint {
236+
#[inline]
237+
fn from(p: &generic::AxisEndPoint<CSSFloat>) -> Self {
238+
use crate::values::computed::CSSPixelLength;
239+
use generic::AxisPosition;
240+
match p {
241+
generic::AxisEndPoint::ToPosition(AxisPosition::LengthPercent(lp)) => Self::ToPosition(
242+
AxisPosition::LengthPercent(LengthPercentage::new_length(CSSPixelLength::new(*lp))),
243+
),
244+
generic::AxisEndPoint::ToPosition(AxisPosition::Keyword(_)) => {
245+
unreachable!("Invalid state: SVG path commands cannot contain a keyword.")
246+
},
247+
generic::AxisEndPoint::ByCoordinate(pos) => {
248+
Self::ByCoordinate(LengthPercentage::new_length(CSSPixelLength::new(*pos)))
249+
},
250+
}
251+
}
252+
}
253+
239254
impl From<&generic::ControlPoint<ShapePosition<CSSFloat>, CSSFloat>> for ControlPoint {
240255
#[inline]
241256
fn from(p: &generic::ControlPoint<ShapePosition<CSSFloat>, CSSFloat>) -> Self {

0 commit comments

Comments
 (0)