mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
style: Expose line-height resolution to style, and use it from ToResolvedValue
For ToResolvedValue implementation purposes we wouldn't need to split out the vertical / font / line-height arguments and we could just pass around the ComputedStyle, but the lh unit would need that distinction, (because computing lh on font properties should use the parent style). Differential Revision: https://phabricator.services.mozilla.com/D168705
This commit is contained in:
parent
aa810f77ec
commit
8997888c6f
4 changed files with 62 additions and 28 deletions
|
@ -14,7 +14,7 @@ use crate::media_queries::MediaType;
|
|||
use crate::properties::ComputedValues;
|
||||
use crate::string_cache::Atom;
|
||||
use crate::values::computed::font::GenericFontFamily;
|
||||
use crate::values::computed::{ColorScheme, Length};
|
||||
use crate::values::computed::{ColorScheme, Length, NonNegativeLength};
|
||||
use crate::values::specified::color::SystemColor;
|
||||
use crate::values::specified::font::FONT_MEDIUM_PX;
|
||||
use crate::values::specified::ViewportVariant;
|
||||
|
@ -115,6 +115,30 @@ impl Device {
|
|||
&self.environment
|
||||
}
|
||||
|
||||
/// Returns the computed line-height for the font in a given computed values instance.
|
||||
///
|
||||
/// If you pass down an element, then the used line-height is returned.
|
||||
pub fn calc_line_height(
|
||||
&self,
|
||||
line_height: &crate::values::computed::LineHeight,
|
||||
vertical: bool,
|
||||
font: &crate::properties::style_structs::Font,
|
||||
element: Option<super::wrapper::GeckoElement>,
|
||||
) -> NonNegativeLength {
|
||||
let pres_context = self.pres_context();
|
||||
let au = Au(unsafe {
|
||||
bindings::Gecko_CalcLineHeight(
|
||||
line_height,
|
||||
pres_context.map_or(std::ptr::null(), |pc| pc),
|
||||
vertical,
|
||||
font.gecko(),
|
||||
element.map_or(std::ptr::null(), |e| e.0)
|
||||
)
|
||||
});
|
||||
NonNegativeLength::new(au.to_f32_px())
|
||||
}
|
||||
|
||||
|
||||
/// Tells the device that a new viewport rule has been found, and stores the
|
||||
/// relevant viewport constraints.
|
||||
pub fn account_for_viewport_rule(&mut self, _constraints: &ViewportConstraints) {
|
||||
|
|
|
@ -3145,24 +3145,18 @@ impl ComputedValues {
|
|||
}
|
||||
% endfor
|
||||
|
||||
/// Writes the value of the given longhand as a string in `dest`.
|
||||
///
|
||||
/// Note that the value will usually be the computed value, except for
|
||||
/// colors, where it's resolved.
|
||||
/// Writes the (resolved or computed) value of the given longhand as a string in `dest`.
|
||||
///
|
||||
/// TODO(emilio): We should move all the special resolution from
|
||||
/// nsComputedDOMStyle to ToResolvedValue instead.
|
||||
pub fn get_resolved_value(
|
||||
pub fn computed_or_resolved_value(
|
||||
&self,
|
||||
property_id: LonghandId,
|
||||
context: Option<<&resolved::Context>,
|
||||
dest: &mut CssStringWriter,
|
||||
) -> fmt::Result {
|
||||
use crate::values::resolved::ToResolvedValue;
|
||||
|
||||
let mut dest = CssWriter::new(dest);
|
||||
let context = resolved::Context {
|
||||
style: self,
|
||||
};
|
||||
match property_id {
|
||||
% for specified_type, props in groupby(data.longhands, key=lambda x: x.specified_type()):
|
||||
<% props = list(props) %>
|
||||
|
@ -3173,34 +3167,39 @@ impl ComputedValues {
|
|||
% endfor
|
||||
_ => unsafe { debug_unreachable!() },
|
||||
};
|
||||
value.to_resolved_value(&context).to_css(&mut dest)
|
||||
if let Some(c) = context {
|
||||
value.to_resolved_value(c).to_css(&mut dest)
|
||||
} else {
|
||||
value.to_css(&mut dest)
|
||||
}
|
||||
}
|
||||
% endfor
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the given longhand's resolved value as a property declaration.
|
||||
pub fn resolved_declaration(&self, property_id: LonghandId) -> PropertyDeclaration {
|
||||
pub fn computed_or_resolved_declaration(
|
||||
&self,
|
||||
property_id: LonghandId,
|
||||
context: Option<<&resolved::Context>,
|
||||
) -> PropertyDeclaration {
|
||||
use crate::values::resolved::ToResolvedValue;
|
||||
use crate::values::computed::ToComputedValue;
|
||||
|
||||
let context = resolved::Context {
|
||||
style: self,
|
||||
};
|
||||
|
||||
match property_id {
|
||||
% for specified_type, props in groupby(data.longhands, key=lambda x: x.specified_type()):
|
||||
<% props = list(props) %>
|
||||
${" |\n".join("LonghandId::{}".format(p.camel_case) for p in props)} => {
|
||||
let value = match property_id {
|
||||
let mut computed_value = match property_id {
|
||||
% for prop in props:
|
||||
LonghandId::${prop.camel_case} => self.clone_${prop.ident}(),
|
||||
% endfor
|
||||
_ => unsafe { debug_unreachable!() },
|
||||
};
|
||||
let resolved = value.to_resolved_value(&context);
|
||||
let computed = ToResolvedValue::from_resolved_value(resolved);
|
||||
let specified = ToComputedValue::from_computed_value(&computed);
|
||||
if let Some(c) = context {
|
||||
let resolved = computed_value.to_resolved_value(c);
|
||||
computed_value = ToResolvedValue::from_resolved_value(resolved);
|
||||
}
|
||||
let specified = ToComputedValue::from_computed_value(&computed_value);
|
||||
% if props[0].boxed:
|
||||
let specified = Box::new(specified);
|
||||
% endif
|
||||
|
|
|
@ -119,12 +119,12 @@ impl ToResolvedValue for LineHeight {
|
|||
|
||||
fn to_resolved_value(self, context: &ResolvedContext) -> Self::ResolvedValue {
|
||||
// Resolve <number> to an absolute <length> based on font size.
|
||||
if let LineHeight::Number(num) = &self {
|
||||
let size = context.style.get_font().clone_font_size().computed_size();
|
||||
LineHeight::Length(NonNegativeLength::new(size.px() * num.0))
|
||||
} else {
|
||||
self
|
||||
if matches!(self, Self::Normal | Self::MozBlockHeight) {
|
||||
return self;
|
||||
}
|
||||
let wm = context.style.writing_mode;
|
||||
let vertical = wm.is_vertical() && !wm.is_sideways();
|
||||
Self::Length(context.device.calc_line_height(&self, vertical, context.style.get_font(), Some(context.element_info.element)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
//! Resolved values. These are almost always computed values, but in some cases
|
||||
//! there are used values.
|
||||
|
||||
use crate::media_queries::Device;
|
||||
use crate::properties::ComputedValues;
|
||||
use crate::ArcSlice;
|
||||
use cssparser;
|
||||
|
@ -16,12 +17,22 @@ mod counters;
|
|||
|
||||
use crate::values::computed;
|
||||
|
||||
/// Element-specific information needed to resolve property values.
|
||||
pub struct ResolvedElementInfo<'a> {
|
||||
/// Element we're resolving line-height against.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub element: crate::gecko::wrapper::GeckoElement<'a>,
|
||||
}
|
||||
|
||||
/// Information needed to resolve a given value.
|
||||
pub struct Context<'a> {
|
||||
/// The style we're resolving for. This is useful to resolve currentColor.
|
||||
pub style: &'a ComputedValues,
|
||||
// TODO(emilio): Add layout box information, and maybe property-specific
|
||||
// information?
|
||||
/// The device / document we're resolving style for. Useful to do font metrics stuff needed for
|
||||
/// line-height.
|
||||
pub device: &'a Device,
|
||||
/// The element-specific information to resolve the value.
|
||||
pub element_info: ResolvedElementInfo<'a>,
|
||||
}
|
||||
|
||||
/// A trait to represent the conversion between resolved and resolved values.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue