mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
layout: Implement word-spacing
per CSS 2.1 § 16.4.
This assumes that there are no ligatures that span across multiple words. Since we have a per-word shape cache, this is a safe assumption as of now. I have left comments to ensure that, if and when this is revisted, we make sure to handle it properly.
This commit is contained in:
parent
ea39b878ac
commit
106fdb1d32
7 changed files with 94 additions and 7 deletions
|
@ -42,8 +42,8 @@ use harfbuzz::{hb_shape, hb_buffer_get_glyph_infos};
|
|||
use libc::{c_uint, c_int, c_void, c_char};
|
||||
use servo_util::geometry::Au;
|
||||
use servo_util::range::Range;
|
||||
use std::mem;
|
||||
use std::char;
|
||||
use std::mem;
|
||||
use std::cmp;
|
||||
use std::ptr;
|
||||
|
||||
|
@ -436,8 +436,12 @@ impl Shaper {
|
|||
// for now, just pretend that every character is a cluster start.
|
||||
// (i.e., pretend there are no combining character sequences).
|
||||
// 1-to-1 mapping of character to glyph also treated as ligature start.
|
||||
//
|
||||
// NB: When we acquire the ability to handle ligatures that cross word boundaries,
|
||||
// we'll need to do something special to handle `word-spacing` properly.
|
||||
let shape = glyph_data.get_entry_for_glyph(glyph_span.begin(), &mut y_pos);
|
||||
let advance = self.advance_for_shaped_glyph(shape.advance, options);
|
||||
let character = text.char_at(char_byte_span.begin() as uint);
|
||||
let advance = self.advance_for_shaped_glyph(shape.advance, character, options);
|
||||
let data = GlyphData::new(shape.codepoint,
|
||||
advance,
|
||||
shape.offset,
|
||||
|
@ -488,11 +492,22 @@ impl Shaper {
|
|||
glyphs.finalize_changes();
|
||||
}
|
||||
|
||||
fn advance_for_shaped_glyph(&self, advance: Au, options: &ShapingOptions) -> Au {
|
||||
fn advance_for_shaped_glyph(&self, mut advance: Au, character: char, options: &ShapingOptions)
|
||||
-> Au {
|
||||
match options.letter_spacing {
|
||||
None => advance,
|
||||
Some(spacing) => advance + spacing,
|
||||
None => {}
|
||||
Some(letter_spacing) => advance = advance + letter_spacing,
|
||||
};
|
||||
|
||||
// CSS 2.1 § 16.4 states that "word spacing affects each space (U+0020) and non-breaking
|
||||
// space (U+00A0) left in the text after the white space processing rules have been
|
||||
// applied. The effect of the property on other word-separator characters is undefined."
|
||||
// We elect to only space the two required code points.
|
||||
if character == ' ' || character == '\u00a0' {
|
||||
advance = advance + options.word_spacing
|
||||
}
|
||||
|
||||
advance
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue