commit 2d447f0895de5b8d2b927957048b2bc1e2ba34df
parent 27635743073f28e912bdb12a61b00d7c0931e5d5
Author: Sajid Anwar <sajidanwar94@gmail.com>
Date: Wed, 3 Dec 2025 17:12:10 +0000
Bug 1740584 - Implement relative root font lengths for SVG. r=emilio,firefox-style-system-reviewers,jwatt
Differential Revision: https://phabricator.services.mozilla.com/D274528
Diffstat:
6 files changed, 61 insertions(+), 29 deletions(-)
diff --git a/dom/svg/SVGLength.cpp b/dom/svg/SVGLength.cpp
@@ -28,10 +28,14 @@ const unsigned short SVG_LENGTHTYPE_IC = 14;
const unsigned short SVG_LENGTHTYPE_CAP = 15;
const unsigned short SVG_LENGTHTYPE_LH = 16;
const unsigned short SVG_LENGTHTYPE_RLH = 17;
-const unsigned short SVG_LENGTHTYPE_VW = 18;
-const unsigned short SVG_LENGTHTYPE_VH = 19;
-const unsigned short SVG_LENGTHTYPE_VMIN = 20;
-const unsigned short SVG_LENGTHTYPE_VMAX = 21;
+const unsigned short SVG_LENGTHTYPE_REX = 18;
+const unsigned short SVG_LENGTHTYPE_RCH = 19;
+const unsigned short SVG_LENGTHTYPE_RIC = 20;
+const unsigned short SVG_LENGTHTYPE_RCAP = 21;
+const unsigned short SVG_LENGTHTYPE_VW = 22;
+const unsigned short SVG_LENGTHTYPE_VH = 23;
+const unsigned short SVG_LENGTHTYPE_VMIN = 24;
+const unsigned short SVG_LENGTHTYPE_VMAX = 25;
void SVGLength::GetValueAsString(nsAString& aValue) const {
nsTextFormatter::ssprintf(aValue, u"%g", (double)mValue);
@@ -78,7 +82,7 @@ bool SVGLength::IsAbsoluteUnit(uint8_t aUnit) {
/*static*/
bool SVGLength::IsFontRelativeUnit(uint8_t aUnit) {
return aUnit == SVG_LENGTHTYPE_EMS || aUnit == SVG_LENGTHTYPE_EXS ||
- (aUnit >= SVG_LENGTHTYPE_CH && aUnit <= SVG_LENGTHTYPE_RLH);
+ (aUnit >= SVG_LENGTHTYPE_CH && aUnit <= SVG_LENGTHTYPE_RCAP);
}
/**
@@ -214,6 +218,18 @@ float SVGLength::GetPixelsPerUnit(const UserSpaceMetrics& aMetrics,
case SVG_LENGTHTYPE_RLH:
zoomType = ZoomType::SelfFromRoot;
return aMetrics.GetLineHeight(UserSpaceMetrics::Type::Root);
+ case SVG_LENGTHTYPE_REX:
+ zoomType = ZoomType::SelfFromRoot;
+ return aMetrics.GetExLength(UserSpaceMetrics::Type::Root);
+ case SVG_LENGTHTYPE_RCH:
+ zoomType = ZoomType::SelfFromRoot;
+ return aMetrics.GetChSize(UserSpaceMetrics::Type::Root);
+ case SVG_LENGTHTYPE_RIC:
+ zoomType = ZoomType::SelfFromRoot;
+ return aMetrics.GetIcWidth(UserSpaceMetrics::Type::Root);
+ case SVG_LENGTHTYPE_RCAP:
+ zoomType = ZoomType::SelfFromRoot;
+ return aMetrics.GetCapHeight(UserSpaceMetrics::Type::Root);
default:
MOZ_ASSERT(IsAbsoluteUnit(aUnitType));
return GetAbsUnitsPerAbsUnit(SVG_LENGTHTYPE_PX, aUnitType);
diff --git a/dom/svg/SVGLengthUnits.h b/dom/svg/SVGLengthUnits.h
@@ -30,3 +30,7 @@ SVG_LENGTH_UNIT(SVG_LENGTHTYPE_VMIN, "vmin", nsCSSUnit::eCSSUnit_VMin)
SVG_LENGTH_UNIT(SVG_LENGTHTYPE_VMAX, "vmax", nsCSSUnit::eCSSUnit_VMax)
SVG_LENGTH_UNIT(SVG_LENGTHTYPE_LH, "lh", nsCSSUnit::eCSSUnit_LineHeight)
SVG_LENGTH_UNIT(SVG_LENGTHTYPE_RLH, "rlh", nsCSSUnit::eCSSUnit_RootLineHeight)
+SVG_LENGTH_UNIT(SVG_LENGTHTYPE_REX, "rex", nsCSSUnit::eCSSUnit_RootXHeight)
+SVG_LENGTH_UNIT(SVG_LENGTHTYPE_RCH, "rch", nsCSSUnit::eCSSUnit_RootChar)
+SVG_LENGTH_UNIT(SVG_LENGTHTYPE_RIC, "ric", nsCSSUnit::eCSSUnit_RootIdeographic)
+SVG_LENGTH_UNIT(SVG_LENGTHTYPE_RCAP, "rcap", nsCSSUnit::eCSSUnit_RootCapHeight)
diff --git a/layout/style/nsCSSValue.h b/layout/style/nsCSSValue.h
@@ -33,16 +33,20 @@ enum nsCSSUnit : uint32_t {
// different behavior than percent)
// Font relative measure
- eCSSUnit_EM = 800, // == current font size
- eCSSUnit_XHeight = 801, // distance from top of lower case x to
- // baseline
- eCSSUnit_Char = 802, // number of characters, used for width with
- // monospace font
- eCSSUnit_RootEM = 803, // == root element font size
- eCSSUnit_Ideographic = 804, // == CJK water ideograph width
- eCSSUnit_CapHeight = 805, // == Capital letter height
- eCSSUnit_LineHeight = 806, // == Line height
- eCSSUnit_RootLineHeight = 807, // == Root line height
+ eCSSUnit_EM = 800, // == current font size (em)
+ eCSSUnit_XHeight = 801, // distance from top of lower case x to
+ // baseline (ex)
+ eCSSUnit_Char = 802, // number of characters, used for width with
+ // monospace font (ch)
+ eCSSUnit_RootEM = 803, // == root element font size (rem)
+ eCSSUnit_Ideographic = 804, // == CJK water ideograph width (ic)
+ eCSSUnit_CapHeight = 805, // == Capital letter height (cap)
+ eCSSUnit_LineHeight = 806, // == Line height (lh)
+ eCSSUnit_RootLineHeight = 807, // == Root line height (rlh)
+ eCSSUnit_RootXHeight = 808, // == Root x-height (rex)
+ eCSSUnit_RootChar = 809, // == Root advance measure (rch)
+ eCSSUnit_RootIdeographic = 810, // == Root ideographic advance measure (ric)
+ eCSSUnit_RootCapHeight = 811, // == Root capital letter height (rch)
// Screen relative measure
eCSSUnit_Point = 900, // 4/3 of a CSS pixel
diff --git a/testing/web-platform/meta/css/css-viewport/zoom/svg-font-relative-units.html.ini b/testing/web-platform/meta/css/css-viewport/zoom/svg-font-relative-units.html.ini
@@ -1,2 +0,0 @@
-[svg-font-relative-units.html]
- expected: FAIL
diff --git a/testing/web-platform/tests/css/css-viewport/zoom/svg-font-relative-units-ref.html b/testing/web-platform/tests/css/css-viewport/zoom/svg-font-relative-units-ref.html
@@ -18,13 +18,18 @@
</style>
<div class="container">
<svg width=400 height=400>
- <line y1=40 y2=40 x1=0 x2=80 />
- <line y1=120 y2=120 x1=0 x2=80 />
- <line y1=140 y2=140 x1=0 x2=80 />
+ <line y1=40 y2=40 x1=0 x2=80 /> <!-- em -->
+ <line y1=60 y2=60 x1=0 x2=64 /> <!-- ex -->
+ <line y1=80 y2=80 x1=0 x2=64 /> <!-- cap -->
+ <line y1=100 y2=100 x1=0 x2=80 /> <!-- ch -->
+ <line y1=120 y2=120 x1=0 x2=80 /> <!-- ic -->
+ <line y1=140 y2=140 x1=0 x2=80 /> <!-- lh -->
- <line y1=220 y2=220 x1=0 x2=40 />
- <line y1=240 y2=240 x1=0 x2=40 />
- <line y1=280 y2=280 x1=0 x2=40 />
- <line y1=300 y2=300 x1=0 x2=40 />
+ <line y1=240 y2=240 x1=0 x2=40 /> <!-- em -->
+ <line y1=260 y2=260 x1=0 x2=32 /> <!-- ex -->
+ <line y1=280 y2=280 x1=0 x2=32 /> <!-- cap -->
+ <line y1=300 y2=300 x1=0 x2=40 /> <!-- ch -->
+ <line y1=320 y2=320 x1=0 x2=40 /> <!-- ic -->
+ <line y1=340 y2=340 x1=0 x2=40 /> <!-- lh -->
</svg>
</div>
diff --git a/testing/web-platform/tests/css/css-viewport/zoom/svg-font-relative-units.html b/testing/web-platform/tests/css/css-viewport/zoom/svg-font-relative-units.html
@@ -28,14 +28,19 @@
<svg width=100 height=100>
<!-- Font-relative units -->
<line y1=10 y2=10 x1=0 x2=1em />
- <line y1=30 y2=30 x1=0 x2=1ch />
- <line y1=35 y2=35 x1=0 x2=1ic />
+ <line y1=15 y2=15 x1=0 x2=1ex />
+ <line y1=20 y2=20 x1=0 x2=1cap />
+ <line y1=25 y2=25 x1=0 x2=1ch />
+ <line y1=30 y2=30 x1=0 x2=1ic />
+ <line y1=35 y2=35 x1=0 x2=1lh />
<!-- Root font-relative units -->
- <line y1=55 y2=55 x1=0 x2=1rch />
<line y1=60 y2=60 x1=0 x2=1rem />
- <line y1=70 y2=70 x1=0 x2=1ric />
- <line y1=75 y2=75 x1=0 x2=1rlh />
+ <line y1=65 y2=65 x1=0 x2=1rex />
+ <line y1=70 y2=70 x1=0 x2=1rcap />
+ <line y1=75 y2=75 x1=0 x2=1rch />
+ <line y1=80 y2=80 x1=0 x2=1ric />
+ <line y1=85 y2=85 x1=0 x2=1rlh />
</svg>
</div>
</div>