Skip to content

Commit

Permalink
stylo: Disable text-zoom for <svg:text>
Browse files Browse the repository at this point in the history
  • Loading branch information
Manishearth committed Aug 2, 2017
1 parent fb107d8 commit 0e3f7d7
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 1 deletion.
4 changes: 4 additions & 0 deletions components/style/gecko/media_queries.rs
Expand Up @@ -191,6 +191,10 @@ impl Device {
pub fn zoom_text(&self, size: Au) -> Au {
size.scale_by(self.pres_context().mEffectiveTextZoom)
}
/// Un-apply text zoom (see nsStyleFont::UnzoomText).
pub fn unzoom_text(&self, size: Au) -> Au {
size.scale_by(1. / self.pres_context().mEffectiveTextZoom)
}
}

/// A expression for gecko contains a reference to the media feature, the value
Expand Down
15 changes: 15 additions & 0 deletions components/style/gecko/wrapper.rs
Expand Up @@ -1402,6 +1402,7 @@ impl<'le> PresentationalHintsSynthesizer for GeckoElement<'le> {
where V: Push<ApplicableDeclarationBlock>,
{
use properties::longhands::_x_lang::SpecifiedValue as SpecifiedLang;
use properties::longhands::_x_text_zoom::SpecifiedValue as SpecifiedZoom;
use properties::longhands::color::SpecifiedValue as SpecifiedColor;
use properties::longhands::text_align::SpecifiedValue as SpecifiedTextAlign;
use values::specified::color::Color;
Expand Down Expand Up @@ -1433,6 +1434,15 @@ impl<'le> PresentationalHintsSynthesizer for GeckoElement<'le> {
let arc = Arc::new(global_style_data.shared_lock.wrap(pdb));
ApplicableDeclarationBlock::from_declarations(arc, ServoCascadeLevel::PresHints)
};
static ref SVG_TEXT_DISABLE_ZOOM_RULE: ApplicableDeclarationBlock = {
let global_style_data = &*GLOBAL_STYLE_DATA;
let pdb = PropertyDeclarationBlock::with_one(
PropertyDeclaration::XTextZoom(SpecifiedZoom(false)),
Importance::Normal
);
let arc = Arc::new(global_style_data.shared_lock.wrap(pdb));
ApplicableDeclarationBlock::from_declarations(arc, ServoCascadeLevel::PresHints)
};
};

let ns = self.get_namespace();
Expand All @@ -1445,6 +1455,11 @@ impl<'le> PresentationalHintsSynthesizer for GeckoElement<'le> {
hints.push(TABLE_COLOR_RULE.clone());
}
}
if ns == &*Namespace(atom!("http://www.w3.org/2000/svg")) {
if self.get_local_name().as_ptr() == atom!("text").as_ptr() {
hints.push(SVG_TEXT_DISABLE_ZOOM_RULE.clone());
}
}
let declarations = unsafe { Gecko_GetHTMLPresentationAttrDeclarationBlock(self.0) };
let declarations: Option<&RawOffsetArc<Locked<PropertyDeclarationBlock>>> =
declarations.and_then(|s| s.as_arc_opt());
Expand Down
23 changes: 22 additions & 1 deletion components/style/properties/gecko.mako.rs
Expand Up @@ -2057,7 +2057,7 @@ fn static_assert() {
font-variant-east-asian font-variant-ligatures
font-variant-numeric font-language-override
font-feature-settings font-variation-settings
-moz-min-font-size-ratio"""
-moz-min-font-size-ratio -x-text-zoom"""
%>
<%self:impl_trait style_struct_name="Font"
skip_longhands="${skip_font_longhands}"
Expand Down Expand Up @@ -2231,6 +2231,12 @@ fn static_assert() {
)
}

pub fn unzoom_fonts(&mut self, device: &Device) {
self.gecko.mSize = device.unzoom_text(Au(self.gecko.mSize)).0;
self.gecko.mScriptUnconstrainedSize = device.unzoom_text(Au(self.gecko.mScriptUnconstrainedSize)).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) {
self.gecko.mSize = v.0;
self.gecko.mScriptUnconstrainedSize = v.0;
Expand Down Expand Up @@ -2465,6 +2471,21 @@ fn static_assert() {
}
}

#[allow(non_snake_case)]
pub fn set__x_text_zoom(&mut self, v: longhands::_x_text_zoom::computed_value::T) {
self.gecko.mAllowZoom = v.0;
}

#[allow(non_snake_case)]
pub fn copy__x_text_zoom_from(&mut self, other: &Self) {
self.gecko.mAllowZoom = other.gecko.mAllowZoom;
}

#[allow(non_snake_case)]
pub fn reset__x_text_zoom(&mut self, other: &Self) {
self.copy__x_text_zoom_from(other)
}

#[allow(non_snake_case)]
pub fn reset__x_lang(&mut self, other: &Self) {
self.copy__x_lang_from(other)
Expand Down
35 changes: 35 additions & 0 deletions components/style/properties/longhand/font.mako.rs
Expand Up @@ -2383,6 +2383,41 @@ ${helpers.single_keyword("-moz-math-variant",
}
</%helpers:longhand>

<%helpers:longhand name="-x-text-zoom" products="gecko" animation_value_type="none" internal="True"
spec="Internal (not web-exposed)">
use values::computed::ComputedValueAsSpecified;
pub use self::computed_value::T as SpecifiedValue;

impl ComputedValueAsSpecified for SpecifiedValue {}
no_viewport_percentage!(SpecifiedValue);

pub mod computed_value {
use std::fmt;
use style_traits::ToCss;

impl ToCss for T {
fn to_css<W>(&self, _: &mut W) -> fmt::Result where W: fmt::Write {
Ok(())
}
}

#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
/// text-zoom. Enable if true, disable if false
pub struct T(pub bool);
}

#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T(true)
}

pub fn parse<'i, 't>(_context: &ParserContext, _input: &mut Parser<'i, 't>)
-> Result<SpecifiedValue, ParseError<'i>> {
debug_assert!(false, "Should be set directly by presentation attributes only.");
Err(StyleParseError::UnspecifiedError.into())
}
</%helpers:longhand>

% if product == "gecko":
pub mod system_font {
Expand Down
18 changes: 18 additions & 0 deletions components/style/properties/properties.mako.rs
Expand Up @@ -608,6 +608,7 @@ impl LonghandId {
LonghandId::AnimationName |
LonghandId::TransitionProperty |
LonghandId::XLang |
LonghandId::XTextZoom |
LonghandId::MozScriptLevel |
LonghandId::MozMinFontSizeRatio |
% endif
Expand Down Expand Up @@ -3207,6 +3208,23 @@ where
let mut _skip_font_family = false;

% if product == "gecko":

// <svg:text> is not affected by text zoom, and it uses a preshint to
// disable it. We fix up the struct when this happens by unzooming
// its contained font values, which will have been zoomed in the parent
if seen.contains(LonghandId::XTextZoom) {
let zoom = context.builder.get_font().gecko().mAllowZoom;
let parent_zoom = context.style().get_parent_font().gecko().mAllowZoom;
if zoom != parent_zoom {
debug_assert!(!zoom,
"We only ever disable text zoom (in svg:text), never enable it");
// can't borrow both device and font, use the take/put machinery
let mut font = context.builder.take_font();
font.unzoom_fonts(context.device());
context.builder.put_font(font);
}
}

// Whenever a single generic value is specified, gecko will do a bunch of
// recalculation walking up the rule tree, including handling the font-size stuff.
// It basically repopulates the font struct with the default font for a given
Expand Down

0 comments on commit 0e3f7d7

Please sign in to comment.