font.mako.rs (17399B)
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 <%namespace name="helpers" file="/helpers.mako.rs" /> 6 <% from data import SYSTEM_FONT_LONGHANDS %> 7 8 ${helpers.predefined_type( 9 "font-family", 10 "FontFamily", 11 engines="gecko servo", 12 initial_value="computed::FontFamily::serif()", 13 animation_type="discrete", 14 spec="https://drafts.csswg.org/css-fonts/#propdef-font-family", 15 gecko_ffi_name="mFont.family", 16 servo_restyle_damage="rebuild_box", 17 affects="layout", 18 )} 19 20 ${helpers.predefined_type( 21 "font-style", 22 "FontStyle", 23 engines="gecko servo", 24 initial_value="computed::FontStyle::normal()", 25 initial_specified_value="specified::FontStyle::normal()", 26 spec="https://drafts.csswg.org/css-fonts/#propdef-font-style", 27 gecko_ffi_name="mFont.style", 28 servo_restyle_damage="rebuild_box", 29 affects="layout", 30 )} 31 32 <% font_variant_caps_custom_consts= { "small-caps": "SMALLCAPS", 33 "all-small-caps": "ALLSMALL", 34 "petite-caps": "PETITECAPS", 35 "all-petite-caps": "ALLPETITE", 36 "titling-caps": "TITLING" } %> 37 38 ${helpers.single_keyword( 39 "font-variant-caps", 40 "normal small-caps", 41 engines="gecko servo", 42 extra_gecko_values="all-small-caps petite-caps all-petite-caps unicase titling-caps", 43 gecko_constant_prefix="NS_FONT_VARIANT_CAPS", 44 gecko_ffi_name="mFont.variantCaps", 45 spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps", 46 custom_consts=font_variant_caps_custom_consts, 47 animation_type="discrete", 48 servo_restyle_damage="rebuild_box", 49 affects="layout", 50 )} 51 52 ${helpers.predefined_type( 53 "font-weight", 54 "FontWeight", 55 engines="gecko servo", 56 initial_value="computed::FontWeight::normal()", 57 initial_specified_value="specified::FontWeight::normal()", 58 gecko_ffi_name="mFont.weight", 59 spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight", 60 servo_restyle_damage="rebuild_box", 61 affects="layout", 62 )} 63 64 ${helpers.predefined_type( 65 "font-size", 66 "FontSize", 67 engines="gecko servo", 68 initial_value="computed::FontSize::medium()", 69 initial_specified_value="specified::FontSize::medium()", 70 allow_quirks="Yes", 71 spec="https://drafts.csswg.org/css-fonts/#propdef-font-size", 72 servo_restyle_damage="rebuild_box", 73 affects="layout", 74 )} 75 76 ${helpers.predefined_type( 77 "font-size-adjust", 78 "FontSizeAdjust", 79 engines="gecko", 80 initial_value="computed::FontSizeAdjust::None", 81 initial_specified_value="specified::FontSizeAdjust::None", 82 spec="https://drafts.csswg.org/css-fonts/#propdef-font-size-adjust", 83 gecko_ffi_name="mFont.sizeAdjust", 84 affects="layout", 85 )} 86 87 ${helpers.predefined_type( 88 "font-synthesis-weight", 89 "FontSynthesis", 90 engines="gecko servo", 91 initial_value="computed::FontSynthesis::Auto", 92 initial_specified_value="specified::FontSynthesis::Auto", 93 gecko_ffi_name="mFont.synthesisWeight", 94 animation_type="discrete", 95 spec="https://drafts.csswg.org/css-fonts-4/#font-synthesis-weight", 96 affects="layout", 97 )} 98 99 ${helpers.predefined_type( 100 "font-synthesis-style", 101 "FontSynthesisStyle", 102 engines="gecko", 103 initial_value="computed::FontSynthesisStyle::Auto", 104 initial_specified_value="specified::FontSynthesisStyle::Auto", 105 gecko_ffi_name="mFont.synthesisStyle", 106 animation_type="discrete", 107 spec="https://drafts.csswg.org/css-fonts-4/#font-synthesis-style", 108 affects="layout", 109 )} 110 111 ${helpers.predefined_type( 112 "font-synthesis-small-caps", 113 "FontSynthesis", 114 engines="gecko", 115 initial_value="computed::FontSynthesis::Auto", 116 initial_specified_value="specified::FontSynthesis::Auto", 117 gecko_ffi_name="mFont.synthesisSmallCaps", 118 animation_type="discrete", 119 spec="https://drafts.csswg.org/css-fonts-4/#font-synthesis-small-caps", 120 affects="layout", 121 )} 122 123 ${helpers.predefined_type( 124 "font-synthesis-position", 125 "FontSynthesis", 126 engines="gecko", 127 initial_value="computed::FontSynthesis::Auto", 128 initial_specified_value="specified::FontSynthesis::Auto", 129 gecko_ffi_name="mFont.synthesisPosition", 130 animation_type="discrete", 131 spec="https://drafts.csswg.org/css-fonts-4/#font-synthesis-position", 132 affects="layout", 133 )} 134 135 ${helpers.predefined_type( 136 "font-stretch", 137 "FontStretch", 138 engines="gecko servo", 139 initial_value="computed::FontStretch::hundred()", 140 initial_specified_value="specified::FontStretch::normal()", 141 gecko_ffi_name="mFont.stretch", 142 spec="https://drafts.csswg.org/css-fonts/#propdef-font-stretch", 143 servo_restyle_damage="rebuild_box", 144 affects="layout", 145 )} 146 147 ${helpers.single_keyword( 148 "font-kerning", 149 "auto none normal", 150 engines="gecko", 151 gecko_ffi_name="mFont.kerning", 152 gecko_constant_prefix="NS_FONT_KERNING", 153 spec="https://drafts.csswg.org/css-fonts/#propdef-font-kerning", 154 animation_type="discrete", 155 affects="layout", 156 )} 157 158 ${helpers.predefined_type( 159 "font-variant-alternates", 160 "FontVariantAlternates", 161 engines="gecko", 162 initial_value="computed::FontVariantAlternates::default()", 163 initial_specified_value="specified::FontVariantAlternates::default()", 164 animation_type="discrete", 165 spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-alternates", 166 gecko_ffi_name="mFont.variantAlternates", 167 affects="layout", 168 )} 169 170 ${helpers.predefined_type( 171 "font-variant-east-asian", 172 "FontVariantEastAsian", 173 engines="gecko", 174 initial_value="computed::FontVariantEastAsian::empty()", 175 initial_specified_value="specified::FontVariantEastAsian::empty()", 176 animation_type="discrete", 177 gecko_ffi_name="mFont.variantEastAsian", 178 spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-east-asian", 179 affects="layout", 180 )} 181 182 ${helpers.single_keyword( 183 "font-variant-emoji", 184 "normal text emoji unicode", 185 engines="gecko", 186 gecko_pref="layout.css.font-variant-emoji.enabled", 187 has_effect_on_gecko_scrollbars=False, 188 gecko_enum_prefix="StyleFontVariantEmoji", 189 gecko_ffi_name="mFont.variantEmoji", 190 spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-emoji", 191 animation_type="discrete", 192 affects="layout", 193 )} 194 195 ${helpers.predefined_type( 196 "font-variant-ligatures", 197 "FontVariantLigatures", 198 engines="gecko", 199 initial_value="computed::FontVariantLigatures::empty()", 200 initial_specified_value="specified::FontVariantLigatures::empty()", 201 animation_type="discrete", 202 gecko_ffi_name="mFont.variantLigatures", 203 spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-ligatures", 204 affects="layout", 205 )} 206 207 ${helpers.predefined_type( 208 "font-variant-numeric", 209 "FontVariantNumeric", 210 engines="gecko", 211 initial_value="computed::FontVariantNumeric::empty()", 212 initial_specified_value="specified::FontVariantNumeric::empty()", 213 animation_type="discrete", 214 gecko_ffi_name="mFont.variantNumeric", 215 spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-numeric", 216 affects="layout", 217 )} 218 219 ${helpers.single_keyword( 220 "font-variant-position", 221 "normal sub super", 222 engines="gecko", 223 gecko_ffi_name="mFont.variantPosition", 224 gecko_constant_prefix="NS_FONT_VARIANT_POSITION", 225 spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-position", 226 animation_type="discrete", 227 affects="layout", 228 )} 229 230 ${helpers.predefined_type( 231 "font-feature-settings", 232 "FontFeatureSettings", 233 engines="gecko", 234 initial_value="computed::FontFeatureSettings::normal()", 235 initial_specified_value="specified::FontFeatureSettings::normal()", 236 extra_prefixes="moz:layout.css.prefixes.font-features webkit", 237 animation_type="discrete", 238 spec="https://drafts.csswg.org/css-fonts/#propdef-font-feature-settings", 239 affects="layout", 240 )} 241 242 ${helpers.predefined_type( 243 "font-variation-settings", 244 "FontVariationSettings", 245 engines="gecko servo", 246 servo_pref="layout.variable_fonts.enabled", 247 gecko_pref="layout.css.font-variations.enabled", 248 has_effect_on_gecko_scrollbars=False, 249 initial_value="computed::FontVariationSettings::normal()", 250 initial_specified_value="specified::FontVariationSettings::normal()", 251 spec="https://drafts.csswg.org/css-fonts-4/#propdef-font-variation-settings", 252 affects="layout", 253 )} 254 255 ${helpers.predefined_type( 256 "font-language-override", 257 "FontLanguageOverride", 258 engines="gecko servo", 259 initial_value="computed::FontLanguageOverride::normal()", 260 initial_specified_value="specified::FontLanguageOverride::normal()", 261 animation_type="discrete", 262 gecko_ffi_name="mFont.languageOverride", 263 extra_prefixes="moz:layout.css.prefixes.font-features", 264 spec="https://drafts.csswg.org/css-fonts-3/#propdef-font-language-override", 265 affects="layout", 266 )} 267 268 ${helpers.single_keyword( 269 "font-optical-sizing", 270 "auto none", 271 engines="gecko", 272 gecko_pref="layout.css.font-variations.enabled", 273 has_effect_on_gecko_scrollbars=False, 274 gecko_ffi_name="mFont.opticalSizing", 275 gecko_constant_prefix="NS_FONT_OPTICAL_SIZING", 276 animation_type="discrete", 277 spec="https://www.w3.org/TR/css-fonts-4/#font-optical-sizing-def", 278 affects="layout", 279 )} 280 281 ${helpers.predefined_type( 282 "font-palette", 283 "FontPalette", 284 engines="gecko", 285 initial_value="computed::FontPalette::normal()", 286 initial_specified_value="specified::FontPalette::normal()", 287 animation_type="discrete", 288 gecko_pref="layout.css.font-palette.enabled", 289 has_effect_on_gecko_scrollbars=False, 290 spec="https://drafts.csswg.org/css-fonts/#font-palette-prop", 291 affects="layout", 292 )} 293 294 ${helpers.predefined_type( 295 "-x-lang", 296 "XLang", 297 engines="gecko servo", 298 initial_value="computed::XLang::get_initial_value()", 299 animation_type="none", 300 enabled_in="", 301 has_effect_on_gecko_scrollbars=False, 302 spec="Internal (not web-exposed)", 303 affects="layout", 304 )} 305 306 ${helpers.predefined_type( 307 "math-depth", 308 "MathDepth", 309 "0", 310 engines="gecko", 311 spec="https://mathml-refresh.github.io/mathml-core/#the-math-script-level-property", 312 affects="", 313 )} 314 315 ${helpers.single_keyword( 316 "math-style", 317 "normal compact", 318 engines="gecko", 319 gecko_enum_prefix="StyleMathStyle", 320 spec="https://mathml-refresh.github.io/mathml-core/#the-math-style-property", 321 animation_type="discrete", 322 needs_conversion=True, 323 affects="layout", 324 )} 325 326 ${helpers.single_keyword( 327 "math-shift", 328 "normal compact", 329 engines="gecko", 330 gecko_enum_prefix="StyleMathShift", 331 spec="https://w3c.github.io/mathml-core/#the-math-shift", 332 animation_type="discrete", 333 gecko_pref="mathml.math_shift.enabled", 334 has_effect_on_gecko_scrollbars=False, 335 enabled_in="ua", 336 needs_conversion=True, 337 affects="layout", 338 )} 339 340 ${helpers.single_keyword( 341 "-moz-math-variant", 342 """none normal bold italic bold-italic script bold-script 343 fraktur double-struck bold-fraktur sans-serif 344 bold-sans-serif sans-serif-italic sans-serif-bold-italic 345 monospace initial tailed looped stretched""", 346 engines="gecko", 347 gecko_enum_prefix="StyleMathVariant", 348 gecko_ffi_name="mMathVariant", 349 spec="Internal (not web-exposed)", 350 animation_type="none", 351 enabled_in="", 352 has_effect_on_gecko_scrollbars=False, 353 needs_conversion=True, 354 affects="layout", 355 )} 356 357 ${helpers.predefined_type( 358 "-x-text-scale", 359 "XTextScale", 360 "computed::XTextScale::All", 361 engines="gecko", 362 animation_type="none", 363 enabled_in="", 364 has_effect_on_gecko_scrollbars=False, 365 spec="Internal (not web-exposed)", 366 affects="layout", 367 )} 368 369 ${helpers.predefined_type( 370 "line-height", 371 "LineHeight", 372 "computed::LineHeight::normal()", 373 engines="gecko servo", 374 spec="https://drafts.csswg.org/css2/visudet.html#propdef-line-height", 375 servo_restyle_damage="rebuild_box", 376 affects="layout", 377 )} 378 379 % if engine == "gecko": 380 pub mod system_font { 381 //! We deal with system fonts here 382 //! 383 //! System fonts can only be set as a group via the font shorthand. 384 //! They resolve at compute time (not parse time -- this lets the 385 //! browser respond to changes to the OS font settings). 386 //! 387 //! While Gecko handles these as a separate property and keyword 388 //! values on each property indicating that the font should be picked 389 //! from the -x-system-font property, we avoid this. Instead, 390 //! each font longhand has a special SystemFont variant which contains 391 //! the specified system font. When the cascade function (in helpers) 392 //! detects that a value has a system font, it will resolve it, and 393 //! cache it on the ComputedValues. After this, it can be just fetched 394 //! whenever a font longhand on the same element needs the system font. 395 //! 396 //! When a longhand property is holding a SystemFont, it's serialized 397 //! to an empty string as if its value comes from a shorthand with 398 //! variable reference. We may want to improve this behavior at some 399 //! point. See also https://github.com/w3c/csswg-drafts/issues/1586. 400 401 use crate::properties::longhands; 402 use std::hash::{Hash, Hasher}; 403 use crate::values::computed::{ToComputedValue, Context}; 404 use crate::values::specified::font::SystemFont; 405 // ComputedValues are compared at times 406 // so we need these impls. We don't want to 407 // add Eq to Number (which contains a float) 408 // so instead we have an eq impl which skips the 409 // cached values 410 impl PartialEq for ComputedSystemFont { 411 fn eq(&self, other: &Self) -> bool { 412 self.system_font == other.system_font 413 } 414 } 415 impl Eq for ComputedSystemFont {} 416 417 impl Hash for ComputedSystemFont { 418 fn hash<H: Hasher>(&self, hasher: &mut H) { 419 self.system_font.hash(hasher) 420 } 421 } 422 423 impl ToComputedValue for SystemFont { 424 type ComputedValue = ComputedSystemFont; 425 426 fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue { 427 use crate::gecko_bindings::bindings; 428 use crate::gecko_bindings::structs::nsFont; 429 use crate::values::computed::font::FontSize; 430 use crate::values::specified::font::KeywordInfo; 431 use crate::values::generics::NonNegative; 432 use std::mem; 433 434 let mut system = mem::MaybeUninit::<nsFont>::uninit(); 435 let system = unsafe { 436 bindings::Gecko_nsFont_InitSystem( 437 system.as_mut_ptr(), 438 *self, 439 &**cx.style().get_font(), 440 cx.device().document() 441 ); 442 &mut *system.as_mut_ptr() 443 }; 444 let size = NonNegative(cx.maybe_zoom_text(system.size.0)); 445 let ret = ComputedSystemFont { 446 font_family: system.family.clone(), 447 font_size: FontSize { 448 computed_size: size, 449 used_size: size, 450 keyword_info: KeywordInfo::none() 451 }, 452 font_weight: system.weight, 453 font_stretch: system.stretch, 454 font_style: system.style, 455 system_font: *self, 456 }; 457 unsafe { bindings::Gecko_nsFont_Destroy(system); } 458 ret 459 } 460 461 fn from_computed_value(_: &ComputedSystemFont) -> Self { 462 unreachable!() 463 } 464 } 465 466 #[inline] 467 /// Compute and cache a system font 468 /// 469 /// Must be called before attempting to compute a system font 470 /// specified value 471 pub fn resolve_system_font(system: SystemFont, context: &mut Context) { 472 // Checking if context.cached_system_font.is_none() isn't enough, 473 // if animating from one system font to another the cached system font 474 // may change 475 if context.cached_system_font.as_ref().is_none_or(|x| x.system_font != system) { 476 let computed = system.to_computed_value(context); 477 context.cached_system_font = Some(computed); 478 } 479 } 480 481 #[derive(Clone, Debug)] 482 pub struct ComputedSystemFont { 483 % for name in SYSTEM_FONT_LONGHANDS: 484 pub ${name}: longhands::${name}::computed_value::T, 485 % endfor 486 pub system_font: SystemFont, 487 } 488 489 } 490 % endif 491 492 ${helpers.single_keyword( 493 "-moz-osx-font-smoothing", 494 "auto grayscale subpixel-antialiased", 495 engines="gecko", 496 gecko_constant_prefix="NS_FONT_SMOOTHING", 497 gecko_ffi_name="mFont.smoothing", 498 gecko_pref="layout.css.osx-font-smoothing.enabled", 499 aliases="-webkit-font-smoothing:layout.css.osx-font-smoothing.enabled", 500 gecko_aliases="antialiased=grayscale", 501 has_effect_on_gecko_scrollbars=False, 502 spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth)", 503 animation_type="discrete", 504 affects="paint", 505 )} 506 507 ${helpers.predefined_type( 508 "-moz-min-font-size-ratio", 509 "Percentage", 510 "computed::Percentage::hundred()", 511 engines="gecko", 512 animation_type="none", 513 gecko_ffi_name="mMinFontSizeRatio", 514 enabled_in="ua", 515 spec="Nonstandard (Internal-only)", 516 affects="layout", 517 )}