font_metrics.rs (4728B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 5 //! Access to font metrics from the style system. 6 7 #![deny(missing_docs)] 8 9 use crate::values::computed::Length; 10 11 /// Represents the font metrics that style needs from a font to compute the 12 /// value of certain CSS units like `ex`. 13 #[derive(Clone, Debug, PartialEq)] 14 pub struct FontMetrics { 15 /// The x-height of the font. 16 pub x_height: Option<Length>, 17 /// The zero advance. This is usually writing mode dependent 18 pub zero_advance_measure: Option<Length>, 19 /// The cap-height of the font. 20 pub cap_height: Option<Length>, 21 /// The ideographic-width of the font. 22 pub ic_width: Option<Length>, 23 /// The ascent of the font (a value is always available for this). 24 pub ascent: Length, 25 /// Script scale down factor for math-depth 1. 26 /// https://w3c.github.io/mathml-core/#dfn-scriptpercentscaledown 27 pub script_percent_scale_down: Option<f32>, 28 /// Script scale down factor for math-depth 2. 29 /// https://w3c.github.io/mathml-core/#dfn-scriptscriptpercentscaledown 30 pub script_script_percent_scale_down: Option<f32>, 31 } 32 33 impl Default for FontMetrics { 34 fn default() -> Self { 35 FontMetrics { 36 x_height: None, 37 zero_advance_measure: None, 38 cap_height: None, 39 ic_width: None, 40 ascent: Length::new(0.0), 41 script_percent_scale_down: None, 42 script_script_percent_scale_down: None, 43 } 44 } 45 } 46 47 impl FontMetrics { 48 /// Returns the x-height, computing a fallback value if not present 49 pub fn x_height_or_default(&self, reference_font_size: Length) -> Length { 50 // https://drafts.csswg.org/css-values/#ex 51 // 52 // In the cases where it is impossible or impractical to 53 // determine the x-height, a value of 0.5em must be 54 // assumed. 55 // 56 // (But note we use 0.5em of the used, not computed 57 // font-size) 58 self.x_height.unwrap_or_else(|| reference_font_size * 0.5) 59 } 60 61 /// Returns the zero advance measure, computing a fallback value if not present 62 pub fn zero_advance_measure_or_default( 63 &self, 64 reference_font_size: Length, 65 upright: bool, 66 ) -> Length { 67 // https://drafts.csswg.org/css-values/#ch 68 // 69 // In the cases where it is impossible or impractical to 70 // determine the measure of the “0” glyph, it must be 71 // assumed to be 0.5em wide by 1em tall. Thus, the ch 72 // unit falls back to 0.5em in the general case, and to 73 // 1em when it would be typeset upright (i.e. 74 // writing-mode is vertical-rl or vertical-lr and 75 // text-orientation is upright). 76 // 77 // Same caveat about computed vs. used font-size applies 78 // above. 79 self.zero_advance_measure.unwrap_or_else(|| { 80 if upright { 81 reference_font_size 82 } else { 83 reference_font_size * 0.5 84 } 85 }) 86 } 87 88 /// Returns the cap-height, computing a fallback value if not present 89 pub fn cap_height_or_default(&self) -> Length { 90 // https://drafts.csswg.org/css-values/#cap 91 // 92 // In the cases where it is impossible or impractical to 93 // determine the cap-height, the font’s ascent must be 94 // used. 95 // 96 self.cap_height.unwrap_or_else(|| self.ascent) 97 } 98 99 /// Returns the ideographic advance measure, computing a fallback value if not present 100 pub fn ic_width_or_default(&self, reference_font_size: Length) -> Length { 101 // https://drafts.csswg.org/css-values/#ic 102 // 103 // In the cases where it is impossible or impractical to 104 // determine the ideographic advance measure, it must be 105 // assumed to be 1em. 106 // 107 // Same caveat about computed vs. used as for other 108 // metric-dependent units. 109 self.ic_width.unwrap_or_else(|| reference_font_size) 110 } 111 } 112 113 /// Type of font metrics to retrieve. 114 #[derive(Clone, Debug, PartialEq)] 115 pub enum FontMetricsOrientation { 116 /// Get metrics for horizontal or vertical according to the Context's 117 /// writing mode, using horizontal metrics for vertical/mixed 118 MatchContextPreferHorizontal, 119 /// Get metrics for horizontal or vertical according to the Context's 120 /// writing mode, using vertical metrics for vertical/mixed 121 MatchContextPreferVertical, 122 /// Force getting horizontal metrics. 123 Horizontal, 124 }