mirror of
https://github.com/servo/servo.git
synced 2025-07-03 13:33:39 +01:00
Auto merge of #19119 - CYBAI:font-size-out-of-mako, r=emilio
style: Move font-size outside of mako This is a sub-PR of #19015 r? emilio --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #19111 (github issue number if applicable). - [x] These changes do not require tests <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/19119) <!-- Reviewable:end -->
This commit is contained in:
commit
fd8b4b59c2
10 changed files with 170 additions and 159 deletions
|
@ -20,7 +20,6 @@ use gecko_bindings::structs::{nsPresContext, RawGeckoPresContextOwned};
|
||||||
use media_queries::MediaType;
|
use media_queries::MediaType;
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
use properties::ComputedValues;
|
use properties::ComputedValues;
|
||||||
use properties::longhands::font_size;
|
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering};
|
||||||
|
@ -32,6 +31,7 @@ use style_traits::viewport::ViewportConstraints;
|
||||||
use stylesheets::Origin;
|
use stylesheets::Origin;
|
||||||
use values::{CSSFloat, CustomIdent, serialize_dimension};
|
use values::{CSSFloat, CustomIdent, serialize_dimension};
|
||||||
use values::computed::{self, ToComputedValue};
|
use values::computed::{self, ToComputedValue};
|
||||||
|
use values::computed::font::FontSize;
|
||||||
use values::specified::Length;
|
use values::specified::Length;
|
||||||
|
|
||||||
/// The `Device` in Gecko wraps a pres context, has a default values computed,
|
/// The `Device` in Gecko wraps a pres context, has a default values computed,
|
||||||
|
@ -75,7 +75,7 @@ impl Device {
|
||||||
pres_context: pres_context,
|
pres_context: pres_context,
|
||||||
default_values: ComputedValues::default_values(unsafe { &*pres_context }),
|
default_values: ComputedValues::default_values(unsafe { &*pres_context }),
|
||||||
// FIXME(bz): Seems dubious?
|
// FIXME(bz): Seems dubious?
|
||||||
root_font_size: AtomicIsize::new(font_size::get_initial_value().size().0 as isize),
|
root_font_size: AtomicIsize::new(FontSize::medium().size().0 as isize),
|
||||||
body_text_color: AtomicUsize::new(unsafe { &*pres_context }.mDefaultColor as usize),
|
body_text_color: AtomicUsize::new(unsafe { &*pres_context }.mDefaultColor as usize),
|
||||||
used_root_font_size: AtomicBool::new(false),
|
used_root_font_size: AtomicBool::new(false),
|
||||||
used_viewport_size: AtomicBool::new(false),
|
used_viewport_size: AtomicBool::new(false),
|
||||||
|
|
|
@ -59,6 +59,7 @@ use std::mem::{forget, uninitialized, transmute, zeroed};
|
||||||
use std::{cmp, ops, ptr};
|
use std::{cmp, ops, ptr};
|
||||||
use values::{self, Auto, CustomIdent, Either, KeyframesName, None_};
|
use values::{self, Auto, CustomIdent, Either, KeyframesName, None_};
|
||||||
use values::computed::{NonNegativeLength, ToComputedValue, Percentage};
|
use values::computed::{NonNegativeLength, ToComputedValue, Percentage};
|
||||||
|
use values::computed::font::FontSize;
|
||||||
use values::computed::effects::{BoxShadow, Filter, SimpleShadow};
|
use values::computed::effects::{BoxShadow, Filter, SimpleShadow};
|
||||||
use computed_values::border_style;
|
use computed_values::border_style;
|
||||||
|
|
||||||
|
@ -2088,7 +2089,7 @@ fn static_assert() {
|
||||||
self.gecko.mFont.size = device.unzoom_text(Au(self.gecko.mFont.size)).0;
|
self.gecko.mFont.size = device.unzoom_text(Au(self.gecko.mFont.size)).0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_font_size(&mut self, v: longhands::font_size::computed_value::T) {
|
pub fn set_font_size(&mut self, v: FontSize) {
|
||||||
use values::specified::font::KeywordSize;
|
use values::specified::font::KeywordSize;
|
||||||
self.gecko.mSize = v.size().0;
|
self.gecko.mSize = v.size().0;
|
||||||
self.gecko.mScriptUnconstrainedSize = v.size().0;
|
self.gecko.mScriptUnconstrainedSize = v.size().0;
|
||||||
|
@ -2114,7 +2115,7 @@ fn static_assert() {
|
||||||
|
|
||||||
/// Set font size, taking into account scriptminsize and scriptlevel
|
/// Set font size, taking into account scriptminsize and scriptlevel
|
||||||
/// Returns Some(size) if we have to recompute the script unconstrained size
|
/// Returns Some(size) if we have to recompute the script unconstrained size
|
||||||
pub fn apply_font_size(&mut self, v: longhands::font_size::computed_value::T,
|
pub fn apply_font_size(&mut self, v: FontSize,
|
||||||
parent: &Self,
|
parent: &Self,
|
||||||
device: &Device) -> Option<NonNegativeLength> {
|
device: &Device) -> Option<NonNegativeLength> {
|
||||||
let (adjusted_size, adjusted_unconstrained_size) =
|
let (adjusted_size, adjusted_unconstrained_size) =
|
||||||
|
@ -2297,7 +2298,7 @@ fn static_assert() {
|
||||||
self.fixup_font_min_size(device);
|
self.fixup_font_min_size(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_font_size(&self) -> longhands::font_size::computed_value::T {
|
pub fn clone_font_size(&self) -> FontSize {
|
||||||
use values::computed::font::KeywordInfo;
|
use values::computed::font::KeywordInfo;
|
||||||
use values::specified::font::KeywordSize;
|
use values::specified::font::KeywordSize;
|
||||||
let size = Au(self.gecko.mSize).into();
|
let size = Au(self.gecko.mSize).into();
|
||||||
|
@ -2311,14 +2312,14 @@ fn static_assert() {
|
||||||
structs::NS_STYLE_FONT_SIZE_XXLARGE => KeywordSize::XXLarge,
|
structs::NS_STYLE_FONT_SIZE_XXLARGE => KeywordSize::XXLarge,
|
||||||
structs::NS_STYLE_FONT_SIZE_XXXLARGE => KeywordSize::XXXLarge,
|
structs::NS_STYLE_FONT_SIZE_XXXLARGE => KeywordSize::XXXLarge,
|
||||||
structs::NS_STYLE_FONT_SIZE_NO_KEYWORD => {
|
structs::NS_STYLE_FONT_SIZE_NO_KEYWORD => {
|
||||||
return longhands::font_size::computed_value::T {
|
return FontSize {
|
||||||
size: size,
|
size: size,
|
||||||
keyword_info: None,
|
keyword_info: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unreachable!("mFontSizeKeyword should be an absolute keyword or NO_KEYWORD")
|
_ => unreachable!("mFontSizeKeyword should be an absolute keyword or NO_KEYWORD")
|
||||||
};
|
};
|
||||||
longhands::font_size::computed_value::T {
|
FontSize {
|
||||||
size: size,
|
size: size,
|
||||||
keyword_info: Some(KeywordInfo {
|
keyword_info: Some(KeywordInfo {
|
||||||
kw: kw,
|
kw: kw,
|
||||||
|
|
|
@ -356,7 +356,7 @@
|
||||||
let computed = specified_value.to_computed_value(context);
|
let computed = specified_value.to_computed_value(context);
|
||||||
% endif
|
% endif
|
||||||
% if property.ident == "font_size":
|
% if property.ident == "font_size":
|
||||||
longhands::font_size::cascade_specified_font_size(
|
specified::FontSize::cascade_specified_font_size(
|
||||||
context,
|
context,
|
||||||
&specified_value,
|
&specified_value,
|
||||||
computed,
|
computed,
|
||||||
|
@ -373,7 +373,7 @@
|
||||||
% endif
|
% endif
|
||||||
CSSWideKeyword::Initial => {
|
CSSWideKeyword::Initial => {
|
||||||
% if property.ident == "font_size":
|
% if property.ident == "font_size":
|
||||||
longhands::font_size::cascade_initial_font_size(context);
|
computed::FontSize::cascade_initial_font_size(context);
|
||||||
% else:
|
% else:
|
||||||
context.builder.reset_${property.ident}();
|
context.builder.reset_${property.ident}();
|
||||||
% endif
|
% endif
|
||||||
|
@ -386,7 +386,7 @@
|
||||||
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
||||||
% endif
|
% endif
|
||||||
% if property.ident == "font_size":
|
% if property.ident == "font_size":
|
||||||
longhands::font_size::cascade_inherit_font_size(context);
|
computed::FontSize::cascade_inherit_font_size(context);
|
||||||
% else:
|
% else:
|
||||||
context.builder.inherit_${property.ident}();
|
context.builder.inherit_${property.ident}();
|
||||||
% endif
|
% endif
|
||||||
|
|
|
@ -624,137 +624,14 @@ ${helpers.predefined_type("font-weight",
|
||||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight")}
|
spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight")}
|
||||||
|
|
||||||
<%helpers:longhand name="font-size" animation_value_type="NonNegativeLength"
|
${helpers.predefined_type("font-size",
|
||||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER"
|
"FontSize",
|
||||||
allow_quirks="True" spec="https://drafts.csswg.org/css-fonts/#propdef-font-size">
|
initial_value="computed::FontSize::medium()",
|
||||||
use app_units::Au;
|
initial_specified_value="specified::FontSize::medium()",
|
||||||
use values::specified::AllowQuirks;
|
animation_value_type="NonNegativeLength",
|
||||||
use values::specified::length::FontBaseSize;
|
allow_quirks=True,
|
||||||
use values::specified::font::{FONT_MEDIUM_PX, KeywordSize};
|
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||||
use values::computed::font::{KeywordInfo};
|
spec="https://drafts.csswg.org/css-fonts/#propdef-font-size")}
|
||||||
|
|
||||||
pub mod computed_value {
|
|
||||||
use values::computed::font;
|
|
||||||
pub type T = font::FontSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use values::specified::font::FontSize as SpecifiedValue;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
#[allow(missing_docs)]
|
|
||||||
pub fn get_initial_value() -> computed_value::T {
|
|
||||||
computed_value::T {
|
|
||||||
size: Au::from_px(FONT_MEDIUM_PX).into(),
|
|
||||||
keyword_info: Some(KeywordInfo::medium())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get_initial_specified_value() -> SpecifiedValue {
|
|
||||||
SpecifiedValue::Keyword(KeywordInfo::medium())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <length> | <percentage> | <absolute-size> | <relative-size>
|
|
||||||
pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
|
||||||
-> Result<SpecifiedValue, ParseError<'i>> {
|
|
||||||
parse_quirky(context, input, AllowQuirks::No)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parses a font-size, with quirks.
|
|
||||||
pub fn parse_quirky<'i, 't>(context: &ParserContext,
|
|
||||||
input: &mut Parser<'i, 't>,
|
|
||||||
allow_quirks: AllowQuirks)
|
|
||||||
-> Result<SpecifiedValue, ParseError<'i>> {
|
|
||||||
use self::specified::LengthOrPercentage;
|
|
||||||
if let Ok(lop) = input.try(|i| LengthOrPercentage::parse_non_negative_quirky(context, i, allow_quirks)) {
|
|
||||||
return Ok(SpecifiedValue::Length(lop))
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(kw) = input.try(KeywordSize::parse) {
|
|
||||||
return Ok(SpecifiedValue::Keyword(kw.into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
try_match_ident_ignore_ascii_case! { input,
|
|
||||||
"smaller" => Ok(SpecifiedValue::Smaller),
|
|
||||||
"larger" => Ok(SpecifiedValue::Larger),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused_mut)]
|
|
||||||
pub fn cascade_specified_font_size(context: &mut Context,
|
|
||||||
specified_value: &SpecifiedValue,
|
|
||||||
mut computed: computed_value::T) {
|
|
||||||
// we could use clone_language and clone_font_family() here but that's
|
|
||||||
// expensive. Do it only in gecko mode for now.
|
|
||||||
% if product == "gecko":
|
|
||||||
// if the language or generic changed, we need to recalculate
|
|
||||||
// the font size from the stored font-size origin information.
|
|
||||||
if context.builder.get_font().gecko().mLanguage.mRawPtr !=
|
|
||||||
context.builder.get_parent_font().gecko().mLanguage.mRawPtr ||
|
|
||||||
context.builder.get_font().gecko().mGenericID !=
|
|
||||||
context.builder.get_parent_font().gecko().mGenericID {
|
|
||||||
if let Some(info) = computed.keyword_info {
|
|
||||||
computed.size = info.to_computed_value(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
% endif
|
|
||||||
|
|
||||||
let device = context.builder.device;
|
|
||||||
let mut font = context.builder.take_font();
|
|
||||||
let parent_unconstrained = {
|
|
||||||
let parent_font = context.builder.get_parent_font();
|
|
||||||
font.apply_font_size(computed, parent_font, device)
|
|
||||||
};
|
|
||||||
context.builder.put_font(font);
|
|
||||||
|
|
||||||
if let Some(parent) = parent_unconstrained {
|
|
||||||
let new_unconstrained =
|
|
||||||
specified_value
|
|
||||||
.to_computed_value_against(context, FontBaseSize::Custom(Au::from(parent)));
|
|
||||||
context.builder
|
|
||||||
.mutate_font()
|
|
||||||
.apply_unconstrained_font_size(new_unconstrained.size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// FIXME(emilio): This is very complex. Also, it should move to
|
|
||||||
/// StyleBuilder.
|
|
||||||
pub fn cascade_inherit_font_size(context: &mut Context) {
|
|
||||||
// If inheriting, we must recompute font-size in case of language
|
|
||||||
// changes using the font_size_keyword. We also need to do this to
|
|
||||||
// handle mathml scriptlevel changes
|
|
||||||
let kw_inherited_size = context.builder.get_parent_font()
|
|
||||||
.clone_font_size()
|
|
||||||
.keyword_info.map(|info| {
|
|
||||||
SpecifiedValue::Keyword(info).to_computed_value(context).size
|
|
||||||
});
|
|
||||||
let mut font = context.builder.take_font();
|
|
||||||
font.inherit_font_size_from(context.builder.get_parent_font(),
|
|
||||||
kw_inherited_size,
|
|
||||||
context.builder.device);
|
|
||||||
context.builder.put_font(font);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Cascade the initial value for the `font-size` property.
|
|
||||||
///
|
|
||||||
/// FIXME(emilio): This is the only function that is outside of the
|
|
||||||
/// `StyleBuilder`, and should really move inside!
|
|
||||||
///
|
|
||||||
/// Can we move the font stuff there?
|
|
||||||
pub fn cascade_initial_font_size(context: &mut Context) {
|
|
||||||
// font-size's default ("medium") does not always
|
|
||||||
// compute to the same value and depends on the font
|
|
||||||
let computed =
|
|
||||||
longhands::font_size::get_initial_specified_value()
|
|
||||||
.to_computed_value(context);
|
|
||||||
context.builder.mutate_font().set_font_size(computed);
|
|
||||||
% if product == "gecko":
|
|
||||||
let device = context.builder.device;
|
|
||||||
context.builder.mutate_font().fixup_font_min_size(device);
|
|
||||||
% endif
|
|
||||||
}
|
|
||||||
</%helpers:longhand>
|
|
||||||
|
|
||||||
<%helpers:longhand products="gecko" name="font-size-adjust"
|
<%helpers:longhand products="gecko" name="font-size-adjust"
|
||||||
animation_value_type="longhands::font_size_adjust::computed_value::T"
|
animation_value_type="longhands::font_size_adjust::computed_value::T"
|
||||||
|
@ -2051,6 +1928,7 @@ ${helpers.predefined_type("-x-text-zoom",
|
||||||
use gecko_bindings::bindings;
|
use gecko_bindings::bindings;
|
||||||
use gecko_bindings::structs::{LookAndFeel_FontID, nsFont};
|
use gecko_bindings::structs::{LookAndFeel_FontID, nsFont};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use values::computed::font::FontSize;
|
||||||
|
|
||||||
let id = match *self {
|
let id = match *self {
|
||||||
% for font in system_fonts:
|
% for font in system_fonts:
|
||||||
|
@ -2076,7 +1954,7 @@ ${helpers.predefined_type("-x-text-zoom",
|
||||||
unsafe { system.fontlist.mFontlist.mBasePtr.to_safe() }
|
unsafe { system.fontlist.mFontlist.mBasePtr.to_safe() }
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
font_size: longhands::font_size::computed_value::T {
|
font_size: FontSize {
|
||||||
size: Au(system.size).into(),
|
size: Au(system.size).into(),
|
||||||
keyword_info: None
|
keyword_info: None
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,10 +20,11 @@
|
||||||
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font">
|
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font">
|
||||||
use parser::Parse;
|
use parser::Parse;
|
||||||
use properties::longhands::{font_family, font_style, font_weight, font_stretch};
|
use properties::longhands::{font_family, font_style, font_weight, font_stretch};
|
||||||
use properties::longhands::{font_size, font_variant_caps};
|
use properties::longhands::font_variant_caps;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use properties::longhands::system_font::SystemFont;
|
use properties::longhands::system_font::SystemFont;
|
||||||
use values::specified::text::LineHeight;
|
use values::specified::text::LineHeight;
|
||||||
|
use values::specified::FontSize;
|
||||||
|
|
||||||
<%
|
<%
|
||||||
gecko_sub_properties = "kerning language_override size_adjust \
|
gecko_sub_properties = "kerning language_override size_adjust \
|
||||||
|
@ -50,7 +51,11 @@
|
||||||
if let Ok(sys) = input.try(SystemFont::parse) {
|
if let Ok(sys) = input.try(SystemFont::parse) {
|
||||||
return Ok(expanded! {
|
return Ok(expanded! {
|
||||||
% for name in SYSTEM_FONT_LONGHANDS:
|
% for name in SYSTEM_FONT_LONGHANDS:
|
||||||
${name}: ${name}::SpecifiedValue::system_font(sys),
|
% if name == "font_size":
|
||||||
|
${name}: FontSize::system_font(sys),
|
||||||
|
% else:
|
||||||
|
${name}: ${name}::SpecifiedValue::system_font(sys),
|
||||||
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
// line-height is just reset to initial
|
// line-height is just reset to initial
|
||||||
line_height: LineHeight::normal(),
|
line_height: LineHeight::normal(),
|
||||||
|
@ -89,27 +94,38 @@
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size = Some(font_size::parse(context, input)?);
|
size = Some(FontSize::parse(context, input)?);
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
#[inline]
|
|
||||||
fn count<T>(opt: &Option<T>) -> u8 {
|
let size = match size {
|
||||||
if opt.is_some() { 1 } else { 0 }
|
Some(s) => s,
|
||||||
}
|
None => {
|
||||||
if size.is_none() ||
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
(count(&style) + count(&weight) + count(&variant_caps) + count(&stretch) + nb_normals) > 4 {
|
}
|
||||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
};
|
||||||
}
|
|
||||||
let line_height = if input.try(|input| input.expect_delim('/')).is_ok() {
|
let line_height = if input.try(|input| input.expect_delim('/')).is_ok() {
|
||||||
Some(LineHeight::parse(context, input)?)
|
Some(LineHeight::parse(context, input)?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn count<T>(opt: &Option<T>) -> u8 {
|
||||||
|
if opt.is_some() { 1 } else { 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count(&style) + count(&weight) + count(&variant_caps) + count(&stretch) + nb_normals) > 4 {
|
||||||
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
|
}
|
||||||
|
|
||||||
let family = FontFamily::parse(input)?;
|
let family = FontFamily::parse(input)?;
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
% for name in "style weight stretch size variant_caps".split():
|
% for name in "style weight stretch variant_caps".split():
|
||||||
font_${name}: unwrap_or_initial!(font_${name}, ${name}),
|
font_${name}: unwrap_or_initial!(font_${name}, ${name}),
|
||||||
% endfor
|
% endfor
|
||||||
|
font_size: size,
|
||||||
line_height: line_height.unwrap_or(LineHeight::normal()),
|
line_height: line_height.unwrap_or(LineHeight::normal()),
|
||||||
font_family: family,
|
font_family: family,
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
|
|
|
@ -11,13 +11,13 @@ use euclid::{ScaleFactor, Size2D, TypedSize2D};
|
||||||
use media_queries::MediaType;
|
use media_queries::MediaType;
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
use properties::ComputedValues;
|
use properties::ComputedValues;
|
||||||
use properties::longhands::font_size;
|
|
||||||
use selectors::parser::SelectorParseErrorKind;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering};
|
||||||
use style_traits::{CSSPixel, DevicePixel, ToCss, ParseError};
|
use style_traits::{CSSPixel, DevicePixel, ToCss, ParseError};
|
||||||
use style_traits::viewport::ViewportConstraints;
|
use style_traits::viewport::ViewportConstraints;
|
||||||
use values::computed::{self, ToComputedValue};
|
use values::computed::{self, ToComputedValue};
|
||||||
|
use values::computed::font::FontSize;
|
||||||
use values::specified;
|
use values::specified;
|
||||||
|
|
||||||
/// A device is a structure that represents the current media a given document
|
/// A device is a structure that represents the current media a given document
|
||||||
|
@ -64,7 +64,7 @@ impl Device {
|
||||||
viewport_size,
|
viewport_size,
|
||||||
device_pixel_ratio,
|
device_pixel_ratio,
|
||||||
// FIXME(bz): Seems dubious?
|
// FIXME(bz): Seems dubious?
|
||||||
root_font_size: AtomicIsize::new(font_size::get_initial_value().size().0 as isize),
|
root_font_size: AtomicIsize::new(FontSize::medium().size().0 as isize),
|
||||||
used_root_font_size: AtomicBool::new(false),
|
used_root_font_size: AtomicBool::new(false),
|
||||||
used_viewport_units: AtomicBool::new(false),
|
used_viewport_units: AtomicBool::new(false),
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,50 @@ impl FontSize {
|
||||||
pub fn size(self) -> Au {
|
pub fn size(self) -> Au {
|
||||||
self.size.into()
|
self.size.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Get default value of font size.
|
||||||
|
pub fn medium() -> Self {
|
||||||
|
Self {
|
||||||
|
size: Au::from_px(specified::FONT_MEDIUM_PX).into(),
|
||||||
|
keyword_info: Some(KeywordInfo::medium())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// FIXME(emilio): This is very complex. Also, it should move to
|
||||||
|
/// StyleBuilder.
|
||||||
|
pub fn cascade_inherit_font_size(context: &mut Context) {
|
||||||
|
// If inheriting, we must recompute font-size in case of language
|
||||||
|
// changes using the font_size_keyword. We also need to do this to
|
||||||
|
// handle mathml scriptlevel changes
|
||||||
|
let kw_inherited_size = context.builder.get_parent_font()
|
||||||
|
.clone_font_size()
|
||||||
|
.keyword_info.map(|info| {
|
||||||
|
specified::FontSize::Keyword(info).to_computed_value(context).size
|
||||||
|
});
|
||||||
|
let mut font = context.builder.take_font();
|
||||||
|
font.inherit_font_size_from(context.builder.get_parent_font(),
|
||||||
|
kw_inherited_size,
|
||||||
|
context.builder.device);
|
||||||
|
context.builder.put_font(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cascade the initial value for the `font-size` property.
|
||||||
|
///
|
||||||
|
/// FIXME(emilio): This is the only function that is outside of the
|
||||||
|
/// `StyleBuilder`, and should really move inside!
|
||||||
|
///
|
||||||
|
/// Can we move the font stuff there?
|
||||||
|
pub fn cascade_initial_font_size(context: &mut Context) {
|
||||||
|
// font-size's default ("medium") does not always
|
||||||
|
// compute to the same value and depends on the font
|
||||||
|
let computed = specified::FontSize::medium().to_computed_value(context);
|
||||||
|
context.builder.mutate_font().set_font_size(computed);
|
||||||
|
#[cfg(feature = "gecko")] {
|
||||||
|
let device = context.builder.device;
|
||||||
|
context.builder.mutate_font().fixup_font_min_size(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCss for FontSize {
|
impl ToCss for FontSize {
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub use self::angle::Angle;
|
||||||
pub use self::background::{BackgroundSize, BackgroundRepeat};
|
pub use self::background::{BackgroundSize, BackgroundRepeat};
|
||||||
pub use self::border::{BorderImageSlice, BorderImageWidth, BorderImageSideWidth};
|
pub use self::border::{BorderImageSlice, BorderImageWidth, BorderImageSideWidth};
|
||||||
pub use self::border::{BorderRadius, BorderCornerRadius, BorderSpacing};
|
pub use self::border::{BorderRadius, BorderCornerRadius, BorderSpacing};
|
||||||
pub use self::font::{FontWeight, MozScriptLevel, MozScriptMinSize, XTextZoom};
|
pub use self::font::{FontSize, FontWeight, MozScriptLevel, MozScriptMinSize, XTextZoom};
|
||||||
pub use self::box_::{AnimationIterationCount, AnimationName, ScrollSnapType, VerticalAlign};
|
pub use self::box_::{AnimationIterationCount, AnimationName, ScrollSnapType, VerticalAlign};
|
||||||
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
|
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
|
||||||
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
|
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
|
||||||
|
|
|
@ -13,7 +13,7 @@ use properties::longhands::system_font::SystemFont;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{ToCss, StyleParseErrorKind, ParseError};
|
use style_traits::{ToCss, StyleParseErrorKind, ParseError};
|
||||||
use values::computed::{font as computed, Context, Length, NonNegativeLength, ToComputedValue};
|
use values::computed::{font as computed, Context, Length, NonNegativeLength, ToComputedValue};
|
||||||
use values::specified::{LengthOrPercentage, NoCalcLength};
|
use values::specified::{AllowQuirks, LengthOrPercentage, NoCalcLength};
|
||||||
use values::specified::length::{AU_PER_PT, AU_PER_PX, FontBaseSize};
|
use values::specified::length::{AU_PER_PT, AU_PER_PX, FontBaseSize};
|
||||||
|
|
||||||
const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8;
|
const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8;
|
||||||
|
@ -466,6 +466,78 @@ impl FontSize {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
/// Get initial value for specified font size.
|
||||||
|
pub fn medium() -> Self {
|
||||||
|
FontSize::Keyword(computed::KeywordInfo::medium())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parses a font-size, with quirks.
|
||||||
|
pub fn parse_quirky<'i, 't>(
|
||||||
|
context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
allow_quirks: AllowQuirks
|
||||||
|
) -> Result<FontSize, ParseError<'i>> {
|
||||||
|
if let Ok(lop) = input.try(|i| LengthOrPercentage::parse_non_negative_quirky(context, i, allow_quirks)) {
|
||||||
|
return Ok(FontSize::Length(lop))
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(kw) = input.try(KeywordSize::parse) {
|
||||||
|
return Ok(FontSize::Keyword(kw.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
|
"smaller" => Ok(FontSize::Smaller),
|
||||||
|
"larger" => Ok(FontSize::Larger),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
/// Cascade `font-size` with specified value
|
||||||
|
pub fn cascade_specified_font_size(
|
||||||
|
context: &mut Context,
|
||||||
|
specified_value: &FontSize,
|
||||||
|
mut computed: computed::FontSize
|
||||||
|
) {
|
||||||
|
// we could use clone_language and clone_font_family() here but that's
|
||||||
|
// expensive. Do it only in gecko mode for now.
|
||||||
|
#[cfg(feature = "gecko")] {
|
||||||
|
// if the language or generic changed, we need to recalculate
|
||||||
|
// the font size from the stored font-size origin information.
|
||||||
|
if context.builder.get_font().gecko().mLanguage.mRawPtr !=
|
||||||
|
context.builder.get_parent_font().gecko().mLanguage.mRawPtr ||
|
||||||
|
context.builder.get_font().gecko().mGenericID !=
|
||||||
|
context.builder.get_parent_font().gecko().mGenericID {
|
||||||
|
if let Some(info) = computed.keyword_info {
|
||||||
|
computed.size = info.to_computed_value(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let device = context.builder.device;
|
||||||
|
let mut font = context.builder.take_font();
|
||||||
|
let parent_unconstrained = {
|
||||||
|
let parent_font = context.builder.get_parent_font();
|
||||||
|
font.apply_font_size(computed, parent_font, device)
|
||||||
|
};
|
||||||
|
context.builder.put_font(font);
|
||||||
|
|
||||||
|
if let Some(parent) = parent_unconstrained {
|
||||||
|
let new_unconstrained =
|
||||||
|
specified_value.to_computed_value_against(context, FontBaseSize::Custom(Au::from(parent)));
|
||||||
|
context.builder
|
||||||
|
.mutate_font()
|
||||||
|
.apply_unconstrained_font_size(new_unconstrained.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parse for FontSize {
|
||||||
|
/// <length> | <percentage> | <absolute-size> | <relative-size>
|
||||||
|
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<FontSize, ParseError<'i>> {
|
||||||
|
FontSize::parse_quirky(context, input, AllowQuirks::No)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
|
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, Justify
|
||||||
pub use self::background::{BackgroundRepeat, BackgroundSize};
|
pub use self::background::{BackgroundRepeat, BackgroundSize};
|
||||||
pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth};
|
pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth};
|
||||||
pub use self::border::{BorderImageSideWidth, BorderRadius, BorderSideWidth, BorderSpacing};
|
pub use self::border::{BorderImageSideWidth, BorderRadius, BorderSideWidth, BorderSpacing};
|
||||||
pub use self::font::{FontWeight, MozScriptLevel, MozScriptMinSize, XTextZoom};
|
pub use self::font::{FontSize, FontWeight, MozScriptLevel, MozScriptMinSize, XTextZoom};
|
||||||
pub use self::box_::{AnimationIterationCount, AnimationName, ScrollSnapType, VerticalAlign};
|
pub use self::box_::{AnimationIterationCount, AnimationName, ScrollSnapType, VerticalAlign};
|
||||||
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
|
pub use self::color::{Color, ColorPropertyValue, RGBAColor};
|
||||||
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
|
pub use self::effects::{BoxShadow, Filter, SimpleShadow};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue