aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2015-01-01 10:55:25 -0500
committerPatrick Walton <pcwalton@mimiga.net>2015-01-08 12:32:58 -0800
commit53b74ae853194940ed1a19f9255a70869520d0af (patch)
tree88ee23cb0e56ad83d919a169729195f083518ab1
parent112ab49706a525ab0b93ca37bd41e9d929218736 (diff)
downloadservo-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.rs4
-rw-r--r--components/gfx/text/shaping/harfbuzz.rs14
-rw-r--r--components/layout/text.rs23
-rw-r--r--components/style/properties/mod.rs.mako2
-rw-r--r--tests/html/text_rendering.html27
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>
+