diff options
author | Patrick Walton <pcwalton@mimiga.net> | 2015-01-01 10:55:25 -0500 |
---|---|---|
committer | Patrick Walton <pcwalton@mimiga.net> | 2015-01-08 12:32:58 -0800 |
commit | 53b74ae853194940ed1a19f9255a70869520d0af (patch) | |
tree | 88ee23cb0e56ad83d919a169729195f083518ab1 | |
parent | 112ab49706a525ab0b93ca37bd41e9d929218736 (diff) | |
download | servo-53b74ae853194940ed1a19f9255a70869520d0af.tar.gz servo-53b74ae853194940ed1a19f9255a70869520d0af.zip |
layout: Implement `text-rendering` per SVG 1.1 § 11.7.4.
Like Gecko, we treat `geometricprecision` the same as
`optimizelegibility` for now.
-rw-r--r-- | components/gfx/font.rs | 4 | ||||
-rw-r--r-- | components/gfx/text/shaping/harfbuzz.rs | 14 | ||||
-rw-r--r-- | components/layout/text.rs | 23 | ||||
-rw-r--r-- | components/style/properties/mod.rs.mako | 2 | ||||
-rw-r--r-- | tests/html/text_rendering.html | 27 |
5 files changed, 60 insertions, 10 deletions
diff --git a/components/gfx/font.rs b/components/gfx/font.rs index 270e0447ed1..3c6379988bc 100644 --- a/components/gfx/font.rs +++ b/components/gfx/font.rs @@ -105,7 +105,9 @@ bitflags! { #[doc="Set if the text is entirely whitespace."] const IS_WHITESPACE_SHAPING_FLAG = 0x01, #[doc="Set if we are to ignore ligatures."] - const IGNORE_LIGATURES_SHAPING_FLAG = 0x02 + const IGNORE_LIGATURES_SHAPING_FLAG = 0x02, + #[doc="Set if we are to disable kerning."] + const DISABLE_KERNING_SHAPING_FLAG = 0x04 } } diff --git a/components/gfx/text/shaping/harfbuzz.rs b/components/gfx/text/shaping/harfbuzz.rs index 11c01a65948..813e4aa33f7 100644 --- a/components/gfx/text/shaping/harfbuzz.rs +++ b/components/gfx/text/shaping/harfbuzz.rs @@ -4,8 +4,8 @@ extern crate harfbuzz; -use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag, IGNORE_LIGATURES_SHAPING_FLAG}; -use font::{ShapingOptions}; +use font::{DISABLE_KERNING_SHAPING_FLAG, Font, FontHandleMethods, FontTableMethods, FontTableTag}; +use font::{IGNORE_LIGATURES_SHAPING_FLAG, ShapingOptions}; use platform::font::FontTable; use text::glyph::{CharIndex, GlyphStore, GlyphId, GlyphData}; use text::shaping::ShaperMethods; @@ -50,6 +50,8 @@ use std::ptr; static NO_GLYPH: i32 = -1; static CONTINUATION_BYTE: i32 = -2; +static KERN: u32 = ((b'k' as u32) << 24) | ((b'e' as u32) << 16) | ((b'r' as u32) << 8) | + (b'n' as u32); static LIGA: u32 = ((b'l' as u32) << 24) | ((b'i' as u32) << 16) | ((b'g' as u32) << 8) | (b'a' as u32); @@ -242,6 +244,14 @@ impl ShaperMethods for Shaper { _end: hb_buffer_get_length(hb_buffer), }) } + if options.flags.contains(DISABLE_KERNING_SHAPING_FLAG) { + features.push(hb_feature_t { + _tag: KERN, + _value: 0, + _start: 0, + _end: hb_buffer_get_length(hb_buffer), + }) + } hb_shape(self.hb_font, hb_buffer, features.as_mut_ptr(), features.len() as u32); self.save_glyph_results(text, options, glyphs, hb_buffer); diff --git a/components/layout/text.rs b/components/layout/text.rs index e92197b7257..ae4ad5ec0de 100644 --- a/components/layout/text.rs +++ b/components/layout/text.rs @@ -9,8 +9,8 @@ use fragment::{Fragment, SpecificFragmentInfo, ScannedTextFragmentInfo}; use inline::InlineFragments; -use gfx::font::{FontMetrics, IGNORE_LIGATURES_SHAPING_FLAG, RunMetrics, ShapingFlags}; -use gfx::font::{ShapingOptions}; +use gfx::font::{DISABLE_KERNING_SHAPING_FLAG, FontMetrics, IGNORE_LIGATURES_SHAPING_FLAG}; +use gfx::font::{RunMetrics, ShapingFlags, ShapingOptions}; use gfx::font_context::FontContext; use gfx::text::glyph::CharIndex; use gfx::text::text_run::TextRun; @@ -23,7 +23,8 @@ use servo_util::smallvec::{SmallVec, SmallVec1}; use std::collections::DList; use std::mem; use style::ComputedValues; -use style::computed_values::{line_height, text_orientation, text_transform, white_space}; +use style::computed_values::{line_height, text_orientation, text_rendering, text_transform}; +use style::computed_values::{white_space}; use style::style_structs::Font as FontStyle; use std::sync::Arc; @@ -108,6 +109,7 @@ impl TextRunScanner { let text_transform; let letter_spacing; let word_spacing; + let text_rendering; { let in_fragment = self.clump.front().unwrap(); let font_style = in_fragment.style().get_font_arc(); @@ -120,6 +122,7 @@ impl TextRunScanner { text_transform = inherited_text_style.text_transform; letter_spacing = inherited_text_style.letter_spacing; word_spacing = inherited_text_style.word_spacing.unwrap_or(Au(0)); + text_rendering = inherited_text_style.text_rendering; } // First, transform/compress text of all the nodes. @@ -161,13 +164,19 @@ impl TextRunScanner { // as the default space, user agents should not use ligatures." This ensures that, for // example, `finally` with a wide `letter-spacing` renders as `f i n a l l y` and not // `fi n a l l y`. + let mut flags = ShapingFlags::empty(); + match letter_spacing { + Some(Au(0)) | None => {} + Some(_) => flags.insert(IGNORE_LIGATURES_SHAPING_FLAG), + } + if text_rendering == text_rendering::T::optimizespeed { + flags.insert(IGNORE_LIGATURES_SHAPING_FLAG); + flags.insert(DISABLE_KERNING_SHAPING_FLAG) + } let options = ShapingOptions { letter_spacing: letter_spacing, word_spacing: word_spacing, - flags: match letter_spacing { - Some(Au(0)) | None => ShapingFlags::empty(), - Some(_) => IGNORE_LIGATURES_SHAPING_FLAG, - }, + flags: flags, }; Arc::new(box TextRun::new(&mut *fontgroup.fonts.get(0).borrow_mut(), diff --git a/components/style/properties/mod.rs.mako b/components/style/properties/mod.rs.mako index 3726152f026..fc4a49d1848 100644 --- a/components/style/properties/mod.rs.mako +++ b/components/style/properties/mod.rs.mako @@ -1483,6 +1483,8 @@ pub mod longhands { // TODO(pcwalton): `full-width` ${single_keyword("text-transform", "none capitalize uppercase lowercase")} + ${single_keyword("text-rendering", "auto optimizespeed optimizelegibility geometricprecision")} + // CSS 2.1, Section 17 - Tables ${new_style_struct("Table", is_inherited=False)} diff --git a/tests/html/text_rendering.html b/tests/html/text_rendering.html new file mode 100644 index 00000000000..13e69236f4f --- /dev/null +++ b/tests/html/text_rendering.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> +<head> +<style> +body { + font-size: 24pt; + font-family: "PT Sans"; + font-weight: bold; +} +#a { + text-rendering: optimizelegibility; +} +#b { + text-rendering: geometricprecision; +} +#c { + text-rendering: optimizespeed; +} +</style> +</head> +<body> +<div id=a>Harry finally caught the Snitch.</div> +<div id=b>Harry finally caught the Snitch.</div> +<div id=c>Harry finally caught the Snitch.</div> +</body> +</html> + |