@@ -19,7 +19,8 @@ use crate::values::computed::font::GenericFontFamily;
1919use crate :: values:: computed:: { ColorScheme , Length , NonNegativeLength } ;
2020use crate :: values:: specified:: color:: { ColorSchemeFlags , ForcedColors , SystemColor } ;
2121use crate :: values:: specified:: font:: {
22- QueryFontMetricsFlags , FONT_MEDIUM_LINE_HEIGHT_PX , FONT_MEDIUM_PX ,
22+ QueryFontMetricsFlags , FONT_MEDIUM_CAP_PX , FONT_MEDIUM_CH_PX , FONT_MEDIUM_EX_PX ,
23+ FONT_MEDIUM_IC_PX , FONT_MEDIUM_LINE_HEIGHT_PX , FONT_MEDIUM_PX ,
2324} ;
2425use crate :: values:: specified:: ViewportVariant ;
2526use crate :: values:: { CustomIdent , KeyframesName } ;
@@ -50,6 +51,14 @@ pub struct Device {
5051 root_font_size : AtomicU32 ,
5152 /// Line height of the root element, used for rlh units in other elements.
5253 root_line_height : AtomicU32 ,
54+ /// X-height of the root element, used for rex units in other elements.
55+ root_font_metrics_ex : AtomicU32 ,
56+ /// Cap-height of the root element, used for rcap units in other elements.
57+ root_font_metrics_cap : AtomicU32 ,
58+ /// Advance measure (ch) of the root element, used for rch units in other elements.
59+ root_font_metrics_ch : AtomicU32 ,
60+ /// Ideographic advance measure of the root element, used for ric units in other elements.
61+ root_font_metrics_ic : AtomicU32 ,
5362 /// The body text color, stored as an `nscolor`, used for the "tables
5463 /// inherit from body" quirk.
5564 ///
@@ -61,6 +70,9 @@ pub struct Device {
6170 /// Whether any styles computed in the document relied on the root line-height
6271 /// by using rlh units.
6372 used_root_line_height : AtomicBool ,
73+ /// Whether any styles computed in the document relied on the root font metrics
74+ /// by using rcap, rch, rex, or ric units.
75+ used_root_font_metrics : AtomicBool ,
6476 /// Whether any styles computed in the document relied on font metrics.
6577 used_font_metrics : AtomicBool ,
6678 /// Whether any styles computed in the document relied on the viewport size
@@ -103,11 +115,17 @@ impl Device {
103115 default_values : ComputedValues :: default_values ( doc) ,
104116 root_font_size : AtomicU32 :: new ( FONT_MEDIUM_PX . to_bits ( ) ) ,
105117 root_line_height : AtomicU32 :: new ( FONT_MEDIUM_LINE_HEIGHT_PX . to_bits ( ) ) ,
118+ root_font_metrics_ex : AtomicU32 :: new ( FONT_MEDIUM_EX_PX . to_bits ( ) ) ,
119+ root_font_metrics_cap : AtomicU32 :: new ( FONT_MEDIUM_CAP_PX . to_bits ( ) ) ,
120+ root_font_metrics_ch : AtomicU32 :: new ( FONT_MEDIUM_CH_PX . to_bits ( ) ) ,
121+ root_font_metrics_ic : AtomicU32 :: new ( FONT_MEDIUM_IC_PX . to_bits ( ) ) ,
122+
106123 // This gets updated when we see the <body>, so it doesn't really
107124 // matter which color-scheme we look at here.
108125 body_text_color : AtomicUsize :: new ( prefs. mLightColors . mDefault as usize ) ,
109126 used_root_font_size : AtomicBool :: new ( false ) ,
110127 used_root_line_height : AtomicBool :: new ( false ) ,
128+ used_root_font_metrics : AtomicBool :: new ( false ) ,
111129 used_font_metrics : AtomicBool :: new ( false ) ,
112130 used_viewport_size : AtomicBool :: new ( false ) ,
113131 used_dynamic_viewport_size : AtomicBool :: new ( false ) ,
@@ -193,6 +211,66 @@ impl Device {
193211 . store ( size. to_bits ( ) , Ordering :: Relaxed ) ;
194212 }
195213
214+ /// Get the x-height of the root element (for rex)
215+ pub fn root_font_metrics_ex ( & self ) -> Length {
216+ self . used_root_font_metrics . store ( true , Ordering :: Relaxed ) ;
217+ Length :: new ( f32:: from_bits (
218+ self . root_font_metrics_ex . load ( Ordering :: Relaxed ) ,
219+ ) )
220+ }
221+
222+ /// Set the x-height of the root element (for rex), in zoom-independent CSS pixels.
223+ pub fn set_root_font_metrics_ex ( & self , size : f32 ) -> bool {
224+ let size = size. to_bits ( ) ;
225+ let previous = self . root_font_metrics_ex . swap ( size, Ordering :: Relaxed ) ;
226+ previous != size
227+ }
228+
229+ /// Get the cap-height of the root element (for rcap)
230+ pub fn root_font_metrics_cap ( & self ) -> Length {
231+ self . used_root_font_metrics . store ( true , Ordering :: Relaxed ) ;
232+ Length :: new ( f32:: from_bits (
233+ self . root_font_metrics_cap . load ( Ordering :: Relaxed ) ,
234+ ) )
235+ }
236+
237+ /// Set the cap-height of the root element (for rcap), in zoom-independent CSS pixels.
238+ pub fn set_root_font_metrics_cap ( & self , size : f32 ) -> bool {
239+ let size = size. to_bits ( ) ;
240+ let previous = self . root_font_metrics_cap . swap ( size, Ordering :: Relaxed ) ;
241+ previous != size
242+ }
243+
244+ /// Get the advance measure of the root element (for rch)
245+ pub fn root_font_metrics_ch ( & self ) -> Length {
246+ self . used_root_font_metrics . store ( true , Ordering :: Relaxed ) ;
247+ Length :: new ( f32:: from_bits (
248+ self . root_font_metrics_ch . load ( Ordering :: Relaxed ) ,
249+ ) )
250+ }
251+
252+ /// Set the advance measure of the root element (for rch), in zoom-independent CSS pixels.
253+ pub fn set_root_font_metrics_ch ( & self , size : f32 ) -> bool {
254+ let size = size. to_bits ( ) ;
255+ let previous = self . root_font_metrics_ch . swap ( size, Ordering :: Relaxed ) ;
256+ previous != size
257+ }
258+
259+ /// Get the ideographic advance measure of the root element (for ric)
260+ pub fn root_font_metrics_ic ( & self ) -> Length {
261+ self . used_root_font_metrics . store ( true , Ordering :: Relaxed ) ;
262+ Length :: new ( f32:: from_bits (
263+ self . root_font_metrics_ic . load ( Ordering :: Relaxed ) ,
264+ ) )
265+ }
266+
267+ /// Set the ideographic advance measure of the root element (for ric), in zoom-independent CSS pixels.
268+ pub fn set_root_font_metrics_ic ( & self , size : f32 ) -> bool {
269+ let size = size. to_bits ( ) ;
270+ let previous = self . root_font_metrics_ic . swap ( size, Ordering :: Relaxed ) ;
271+ previous != size
272+ }
273+
196274 /// The quirks mode of the document.
197275 pub fn quirks_mode ( & self ) -> QuirksMode {
198276 self . document ( ) . mCompatMode . into ( )
@@ -230,8 +308,11 @@ impl Device {
230308 font : & crate :: properties:: style_structs:: Font ,
231309 base_size : Length ,
232310 flags : QueryFontMetricsFlags ,
311+ track_usage : bool ,
233312 ) -> FontMetrics {
234- self . used_font_metrics . store ( true , Ordering :: Relaxed ) ;
313+ if track_usage {
314+ self . used_font_metrics . store ( true , Ordering :: Relaxed ) ;
315+ }
235316 let pc = match self . pres_context ( ) {
236317 Some ( pc) => pc,
237318 None => return Default :: default ( ) ,
@@ -309,6 +390,7 @@ impl Device {
309390 self . reset_computed_values ( ) ;
310391 self . used_root_font_size . store ( false , Ordering :: Relaxed ) ;
311392 self . used_root_line_height . store ( false , Ordering :: Relaxed ) ;
393+ self . used_root_font_metrics . store ( false , Ordering :: Relaxed ) ;
312394 self . used_font_metrics . store ( false , Ordering :: Relaxed ) ;
313395 self . used_viewport_size . store ( false , Ordering :: Relaxed ) ;
314396 self . used_dynamic_viewport_size
@@ -325,6 +407,11 @@ impl Device {
325407 self . used_root_line_height . load ( Ordering :: Relaxed )
326408 }
327409
410+ /// Returns whether we ever looked up the root font metrics of the device.
411+ pub fn used_root_font_metrics ( & self ) -> bool {
412+ self . used_root_font_metrics . load ( Ordering :: Relaxed )
413+ }
414+
328415 /// Recreates all the temporary state that the `Device` stores.
329416 ///
330417 /// This includes the viewport override from `@viewport` rules, and also the
0 commit comments