зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #16155 - stylo: Implement gecko glue for font-language-override (from chenpighead:gecko-glue-for-font-language-override); r=emilio
To be aligned with the implementation from Gecko side, we parse font-language-override as Normal keyword or String. Then, we compute and store it as a u32. So, as to the stylo glue, we can just pass the u32 to Gecko. The extra crate, byteorder, is used to simplify the computing and serialization. Since we now implement font-language-override for Gecko, we can remove the additional branches for font-language-override in font shorthand. ref: Gecko [Bug 1347821](https://bugzilla.mozilla.org/show_bug.cgi?id=1347821) <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: af243d5decde5663e2f6558eaa78c9022536c289 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : a8af7077c4c7d662923ae8ccc854e06b53c590ea
This commit is contained in:
Родитель
b1aecb3f20
Коммит
1a65c22c50
|
@ -2746,6 +2746,7 @@ dependencies = [
|
|||
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bindgen 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cssparser 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -25,6 +25,7 @@ testing = []
|
|||
app_units = "0.4"
|
||||
atomic_refcell = "0.1"
|
||||
bitflags = "0.7"
|
||||
byteorder = "1.0"
|
||||
cfg-if = "0.1.0"
|
||||
cssparser = "0.12"
|
||||
encoding = {version = "0.2", optional = true}
|
||||
|
|
|
@ -41,6 +41,7 @@ extern crate app_units;
|
|||
extern crate atomic_refcell;
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
#[allow(unused_extern_crates)] extern crate byteorder;
|
||||
#[cfg(feature = "gecko")] #[macro_use] #[no_link] extern crate cfg_if;
|
||||
#[macro_use] extern crate cssparser;
|
||||
extern crate euclid;
|
||||
|
|
|
@ -1177,7 +1177,7 @@ fn static_assert() {
|
|||
</%self:impl_trait>
|
||||
|
||||
<%self:impl_trait style_struct_name="Font"
|
||||
skip_longhands="font-family font-size font-size-adjust font-weight font-synthesis -x-lang"
|
||||
skip_longhands="font-family font-size font-size-adjust font-weight font-synthesis -x-lang font-language-override"
|
||||
skip_additionals="*">
|
||||
|
||||
pub fn set_font_family(&mut self, v: longhands::font_family::computed_value::T) {
|
||||
|
@ -1315,6 +1315,11 @@ fn static_assert() {
|
|||
Gecko_nsStyleFont_CopyLangFrom(&mut self.gecko, &other.gecko);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_font_language_override(&mut self, v: longhands::font_language_override::computed_value::T) {
|
||||
self.gecko.mFont.languageOverride = v.0;
|
||||
}
|
||||
${impl_simple_copy('font_language_override', 'mFont.languageOverride')}
|
||||
</%self:impl_trait>
|
||||
|
||||
<%def name="impl_copy_animation_or_transition_value(type, ident, gecko_ffi_name)">
|
||||
|
|
|
@ -954,40 +954,67 @@ ${helpers.single_keyword("font-variant-position",
|
|||
}
|
||||
</%helpers:longhand>
|
||||
|
||||
// https://www.w3.org/TR/css-fonts-3/#propdef-font-language-override
|
||||
<%helpers:longhand name="font-language-override" products="none" animatable="False" extra_prefixes="moz"
|
||||
<%helpers:longhand name="font-language-override" products="gecko" animatable="False" extra_prefixes="moz"
|
||||
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font-language-override">
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
use values::HasViewportPercentage;
|
||||
use values::computed::ComputedValueAsSpecified;
|
||||
pub use self::computed_value::T as SpecifiedValue;
|
||||
|
||||
impl ComputedValueAsSpecified for SpecifiedValue {}
|
||||
no_viewport_percentage!(SpecifiedValue);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum SpecifiedValue {
|
||||
Normal,
|
||||
Override(String),
|
||||
}
|
||||
|
||||
impl ToCss for SpecifiedValue {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
use cssparser;
|
||||
match *self {
|
||||
SpecifiedValue::Normal => dest.write_str("normal"),
|
||||
SpecifiedValue::Override(ref lang) =>
|
||||
cssparser::serialize_string(lang, dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod computed_value {
|
||||
use std::fmt;
|
||||
use std::{fmt, str};
|
||||
use style_traits::ToCss;
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
use cssparser;
|
||||
|
||||
impl ToCss for T {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
T::Normal => dest.write_str("normal"),
|
||||
T::Override(ref lang) => write!(dest, "\"{}\"", lang),
|
||||
if self.0 == 0 {
|
||||
return dest.write_str("normal")
|
||||
}
|
||||
let mut buf = [0; 4];
|
||||
BigEndian::write_u32(&mut buf, self.0);
|
||||
// Safe because we ensure it's ASCII during computing
|
||||
let slice = if cfg!(debug_assertions) {
|
||||
str::from_utf8(&buf).unwrap()
|
||||
} else {
|
||||
unsafe { str::from_utf8_unchecked(&buf) }
|
||||
};
|
||||
cssparser::serialize_string(slice.trim_right(), dest)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
// font-language-override can only have a single three-letter
|
||||
// OpenType "language system" tag, so we should be able to compute
|
||||
// it and store it as a 32-bit integer
|
||||
// (see http://www.microsoft.com/typography/otspec/languagetags.htm).
|
||||
#[derive(PartialEq, Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum T {
|
||||
Normal,
|
||||
Override(String),
|
||||
}
|
||||
pub struct T(pub u32);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_initial_value() -> computed_value::T {
|
||||
computed_value::T::Normal
|
||||
computed_value::T(0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -995,6 +1022,45 @@ ${helpers.single_keyword("font-variant-position",
|
|||
SpecifiedValue::Normal
|
||||
}
|
||||
|
||||
impl ToComputedValue for SpecifiedValue {
|
||||
type ComputedValue = computed_value::T;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, _: &Context) -> computed_value::T {
|
||||
use std::ascii::AsciiExt;
|
||||
match *self {
|
||||
SpecifiedValue::Normal => computed_value::T(0),
|
||||
SpecifiedValue::Override(ref lang) => {
|
||||
if lang.is_empty() || lang.len() > 4 || !lang.is_ascii() {
|
||||
return computed_value::T(0)
|
||||
}
|
||||
let mut computed_lang = lang.clone();
|
||||
while computed_lang.len() < 4 {
|
||||
computed_lang.push(' ');
|
||||
}
|
||||
let bytes = computed_lang.into_bytes();
|
||||
computed_value::T(BigEndian::read_u32(&bytes))
|
||||
}
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &computed_value::T) -> Self {
|
||||
if computed.0 == 0 {
|
||||
return SpecifiedValue::Normal
|
||||
}
|
||||
let mut buf = [0; 4];
|
||||
BigEndian::write_u32(&mut buf, computed.0);
|
||||
SpecifiedValue::Override(
|
||||
if cfg!(debug_assertions) {
|
||||
String::from_utf8(buf.to_vec()).unwrap()
|
||||
} else {
|
||||
unsafe { String::from_utf8_unchecked(buf.to_vec()) }
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// normal | <string>
|
||||
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
|
||||
Ok(SpecifiedValue::Normal)
|
||||
|
|
|
@ -4,21 +4,20 @@
|
|||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
<%helpers:shorthand name="font" sub_properties="font-style font-variant font-weight font-stretch
|
||||
font-size line-height font-family
|
||||
${'font-size-adjust' if product == 'gecko' or data.testing else ''}
|
||||
${'font-kerning' if product == 'gecko' or data.testing else ''}
|
||||
${'font-variant-caps' if product == 'gecko' or data.testing else ''}
|
||||
${'font-variant-position' if product == 'gecko' or data.testing else ''}
|
||||
${'font-language-override' if data.testing else ''}"
|
||||
<%helpers:shorthand name="font"
|
||||
sub_properties="font-style font-variant font-weight font-stretch
|
||||
font-size line-height font-family
|
||||
${'font-size-adjust' if product == 'gecko' or data.testing else ''}
|
||||
${'font-kerning' if product == 'gecko' or data.testing else ''}
|
||||
${'font-variant-caps' if product == 'gecko' or data.testing else ''}
|
||||
${'font-variant-position' if product == 'gecko' or data.testing else ''}
|
||||
${'font-language-override' if product == 'gecko' or data.testing else ''}"
|
||||
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font">
|
||||
use properties::longhands::{font_style, font_variant, font_weight, font_stretch};
|
||||
use properties::longhands::{font_size, line_height};
|
||||
% if product == "gecko" or data.testing:
|
||||
use properties::longhands::{font_size_adjust, font_kerning, font_variant_caps, font_variant_position};
|
||||
% endif
|
||||
% if data.testing:
|
||||
use properties::longhands::font_language_override;
|
||||
use properties::longhands::{font_size_adjust, font_kerning, font_variant_caps, font_variant_position,
|
||||
font_language_override};
|
||||
% endif
|
||||
use properties::longhands::font_family::SpecifiedValue as FontFamily;
|
||||
|
||||
|
@ -84,13 +83,10 @@
|
|||
line_height: unwrap_or_initial!(line_height),
|
||||
font_family: family,
|
||||
% if product == "gecko" or data.testing:
|
||||
% for name in "size_adjust kerning variant_caps variant_position".split():
|
||||
% for name in "size_adjust kerning variant_caps variant_position language_override".split():
|
||||
font_${name}: font_${name}::get_initial_specified_value(),
|
||||
% endfor
|
||||
% endif
|
||||
% if data.testing:
|
||||
font_language_override: font_language_override::get_initial_specified_value(),
|
||||
% endif
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -99,19 +95,13 @@
|
|||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
|
||||
% if product == "gecko" or data.testing:
|
||||
% for name in "size_adjust kerning variant_caps variant_position".split():
|
||||
% for name in "size_adjust kerning variant_caps variant_position language_override".split():
|
||||
if self.font_${name} != &font_${name}::get_initial_specified_value() {
|
||||
return Ok(());
|
||||
}
|
||||
% endfor
|
||||
% endif
|
||||
|
||||
% if data.testing:
|
||||
if self.font_language_override != &font_language_override::get_initial_specified_value() {
|
||||
return Ok(());
|
||||
}
|
||||
% endif
|
||||
|
||||
% for name in "style variant weight stretch".split():
|
||||
self.font_${name}.to_css(dest)?;
|
||||
dest.write_str(" ")?;
|
||||
|
|
Загрузка…
Ссылка в новой задаче