Bug 1358688 - Part 2: stylo: Handle text-zoom for font-size ; r?emilio
MozReview-Commit-ID: JoVdOF3MoYI
--- a/servo/components/style/gecko/media_queries.rs
+++ b/servo/components/style/gecko/media_queries.rs
@@ -181,16 +181,21 @@ impl Device {
pub fn use_document_colors(&self) -> bool {
self.pres_context().mUseDocumentColors() != 0
}
/// Returns the default background color.
pub fn default_background_color(&self) -> RGBA {
convert_nscolor_to_rgba(self.pres_context().mBackgroundColor)
}
+
+ /// Applies text zoom to a font-size or line-height value (see nsStyleFont::ZoomText).
+ pub fn zoom_text(&self, size: Au) -> Au {
+ size.scale_by(self.pres_context().mEffectiveTextZoom)
+ }
}
/// A expression for gecko contains a reference to the media feature, the value
/// the media query contained, and the range to evaluate.
#[derive(Debug, Clone)]
pub struct Expression {
feature: &'static nsMediaFeature,
value: Option<MediaExpressionValue>,
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -2226,19 +2226,16 @@ fn static_assert() {
quoted: true
}),
x => panic!("Found unexpected font FontFamilyType: {:?}", x),
}
}).collect()
)
}
- // FIXME(bholley): Gecko has two different sizes, one of which (mSize) is the
- // actual computed size, and the other of which (mFont.size) is the 'display
- // size' which takes font zooming into account. We don't handle font zooming yet.
pub fn set_font_size(&mut self, v: longhands::font_size::computed_value::T) {
self.gecko.mSize = v.0;
self.gecko.mScriptUnconstrainedSize = v.0;
}
/// Set font size, taking into account scriptminsize and scriptlevel
/// 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,
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -825,27 +825,27 @@ macro_rules! impl_gecko_keyword_conversi
NoCalcLength::FontRelative(value))) => {
value.to_computed_value(context, base_size)
}
SpecifiedValue::Length(LengthOrPercentage::Length(
NoCalcLength::ServoCharacterWidth(value))) => {
value.to_computed_value(base_size.resolve(context))
}
SpecifiedValue::Length(LengthOrPercentage::Length(ref l)) => {
- l.to_computed_value(context)
+ context.maybe_zoom_text(l.to_computed_value(context))
}
SpecifiedValue::Length(LengthOrPercentage::Percentage(pc)) => {
base_size.resolve(context).scale_by(pc.0)
}
SpecifiedValue::Length(LengthOrPercentage::Calc(ref calc)) => {
- let calc = calc.to_computed_value(context);
+ let calc = calc.to_computed_value_zoomed(context);
calc.to_used_value(Some(base_size.resolve(context))).unwrap()
}
SpecifiedValue::Keyword(ref key, fraction) => {
- key.to_computed_value(context).scale_by(fraction)
+ context.maybe_zoom_text(key.to_computed_value(context).scale_by(fraction))
}
SpecifiedValue::Smaller => {
FontRelativeLength::Em(1. / LARGER_FONT_SIZE_RATIO)
.to_computed_value(context, base_size)
}
SpecifiedValue::Larger => {
FontRelativeLength::Em(LARGER_FONT_SIZE_RATIO)
.to_computed_value(context, base_size)
@@ -955,17 +955,17 @@ macro_rules! impl_gecko_keyword_conversi
use gecko_bindings::structs::nsIAtom;
// 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.raw::<nsIAtom>() !=
context.builder.get_parent_font().gecko().mLanguage.raw::<nsIAtom>() ||
context.builder.get_font().gecko().mGenericID !=
context.builder.get_parent_font().gecko().mGenericID {
if let Some((kw, ratio)) = context.builder.font_size_keyword {
- computed = kw.to_computed_value(context).scale_by(ratio);
+ computed = context.maybe_zoom_text(kw.to_computed_value(context).scale_by(ratio));
}
}
% endif
let device = context.builder.device;
let mut font = context.builder.take_font();
let parent_unconstrained = {
let parent_font = context.builder.get_parent_font();
@@ -985,17 +985,17 @@ macro_rules! impl_gecko_keyword_conversi
/// 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.font_size_keyword.map(|(kw, ratio)| {
- SpecifiedValue::Keyword(kw, ratio).to_computed_value(context)
+ context.maybe_zoom_text(SpecifiedValue::Keyword(kw, ratio).to_computed_value(context))
});
let parent_kw;
let device = context.builder.device;
let mut font = context.builder.take_font();
let used_kw = {
let parent_font = context.builder.get_parent_font();
parent_kw = context.builder.inherited_font_computation_data().font_size_keyword;
@@ -1010,18 +1010,20 @@ macro_rules! impl_gecko_keyword_conversi
///
/// 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);
+ let computed = context.maybe_zoom_text(
+ 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
context.builder.font_size_keyword = Some((Default::default(), 1.));
}
</%helpers:longhand>
--- a/servo/components/style/values/computed/length.rs
+++ b/servo/components/style/values/computed/length.rs
@@ -223,24 +223,24 @@ impl ToCss for CalcLengthOrPercentage {
match (self.length, self.percentage) {
(l, Some(p)) if l == Au(0) => p.to_css(dest),
(l, Some(p)) => write!(dest, "calc({}px + {}%)", Au::to_px(l), p.0 * 100.),
(l, None) => write!(dest, "{}px", Au::to_px(l)),
}
}
}
-impl ToComputedValue for specified::CalcLengthOrPercentage {
- type ComputedValue = CalcLengthOrPercentage;
-
- fn to_computed_value(&self, context: &Context) -> CalcLengthOrPercentage {
+impl specified::CalcLengthOrPercentage {
+ /// Compute the value, zooming any absolute units by the zoom function.
+ fn to_computed_value_with_zoom<F>(&self, context: &Context, zoom_fn: F) -> CalcLengthOrPercentage
+ where F: Fn(Au) -> Au {
let mut length = Au(0);
if let Some(absolute) = self.absolute {
- length += absolute;
+ length += zoom_fn(absolute);
}
for val in &[self.vw.map(ViewportPercentageLength::Vw),
self.vh.map(ViewportPercentageLength::Vh),
self.vmin.map(ViewportPercentageLength::Vmin),
self.vmax.map(ViewportPercentageLength::Vmax)] {
if let Some(val) = *val {
length += val.to_computed_value(context.viewport_size());
@@ -258,16 +258,29 @@ impl ToComputedValue for specified::Calc
CalcLengthOrPercentage {
clamping_mode: self.clamping_mode,
length: length,
percentage: self.percentage,
}
}
+ /// Compute font-size or line-height taking into account text-zoom if necessary.
+ pub fn to_computed_value_zoomed(&self, context: &Context) -> CalcLengthOrPercentage {
+ self.to_computed_value_with_zoom(context, |abs| context.maybe_zoom_text(abs))
+ }
+}
+
+impl ToComputedValue for specified::CalcLengthOrPercentage {
+ type ComputedValue = CalcLengthOrPercentage;
+
+ fn to_computed_value(&self, context: &Context) -> CalcLengthOrPercentage {
+ self.to_computed_value_with_zoom(context, |abs| abs)
+ }
+
#[inline]
fn from_computed_value(computed: &CalcLengthOrPercentage) -> Self {
specified::CalcLengthOrPercentage {
clamping_mode: computed.clamping_mode,
absolute: Some(computed.length),
percentage: computed.percentage,
..Default::default()
}
--- a/servo/components/style/values/computed/mod.rs
+++ b/servo/components/style/values/computed/mod.rs
@@ -127,16 +127,36 @@ impl<'a> Context<'a> {
pub fn default_style(&self) -> &ComputedValues {
self.builder.default_style()
}
/// The current style.
pub fn style(&self) -> &StyleBuilder {
&self.builder
}
+
+
+ /// Apply text-zoom if enabled
+ #[cfg(feature = "gecko")]
+ pub fn maybe_zoom_text(&self, size: Au) -> Au {
+ // We disable zoom for <svg:text> by unsetting the
+ // -x-text-zoom property, which leads to a false value
+ // in mAllowZoom
+ if self.style().get_font().gecko.mAllowZoom {
+ self.device().zoom_text(size)
+ } else {
+ size
+ }
+ }
+
+ /// (Servo doesn't do text-zoom)
+ #[cfg(feature = "servo")]
+ pub fn maybe_zoom_text(&self, size: Au) -> Au {
+ size
+ }
}
/// An iterator over a slice of computed values
#[derive(Clone)]
pub struct ComputedVecIter<'a, 'cx, 'cx_a: 'cx, S: ToComputedValue + 'a> {
cx: &'cx Context<'cx_a>,
values: &'a [S],
}