Break at word boundaries

This commit is contained in:
Patrick Walton 2017-02-07 14:40:03 -08:00
parent e9fd5d6b1b
commit 66d239cf2f
2 changed files with 29 additions and 21 deletions

View File

@ -94,31 +94,40 @@ fn main() {
let codepoint_ranges = CodepointRanges::from_sorted_chars(&chars);
let file = Mmap::open_path(font_path, Protection::Read).unwrap();
let (font, shaped_glyph_positions, glyph_ranges);
let (font, glyph_ranges);
unsafe {
font = Font::new(file.as_slice()).unwrap();
glyph_ranges = font.glyph_ranges_for_codepoint_ranges(&codepoint_ranges.ranges).unwrap();
shaped_glyph_positions = shaper::shape_text(&font, &glyph_ranges, &text)
}
let paragraph_width = (device_pixel_size.width as f32 * font.units_per_em() as f32 /
INITIAL_POINT_SIZE) as u32;
// Do some basic line breaking.
let mut glyph_positions = vec![];
let paragraph_width = (device_pixel_size.width as f32 * font.units_per_em() as f32 /
INITIAL_POINT_SIZE) as u32;
let space_advance = font.metrics_for_glyph(glyph_ranges.glyph_for(' ' as u32).unwrap())
.unwrap()
.advance_width as u32;
let line_spacing = font.units_per_em() as u32;
let (mut current_x, mut current_y) = (0, line_spacing);
for glyph_position in &shaped_glyph_positions {
current_x += glyph_position.advance as u32;
if current_x > paragraph_width {
for word in text.split_whitespace() {
let shaped_glyph_positions = shaper::shape_text(&font, &glyph_ranges, word);
let total_advance: u32 = shaped_glyph_positions.iter().map(|p| p.advance as u32).sum();
if current_x + total_advance > paragraph_width {
current_x = 0;
current_y += line_spacing;
}
glyph_positions.push(GlyphPos {
x: current_x,
y: current_y,
glyph_id: glyph_position.glyph_id,
});
for glyph_position in &shaped_glyph_positions {
glyph_positions.push(GlyphPos {
x: current_x,
y: current_y,
glyph_id: glyph_position.glyph_id,
});
current_x += glyph_position.advance as u32;
}
current_x += space_advance
}
let renderer = Renderer::new();
@ -640,12 +649,12 @@ impl Renderer {
let mut fps_glyphs = vec![];
let mut current_x = 0;
for glyph_pos in &shaper::shape_text(&font, &glyph_ranges, &fps_text) {
current_x += glyph_pos.advance as u32;
fps_glyphs.push(GlyphPos {
x: current_x,
y: 0,
glyph_id: glyph_pos.glyph_id,
});
current_x += glyph_pos.advance as u32;
}
self.draw_glyphs(font,

View File

@ -19,20 +19,19 @@ use otf::Font;
use std::cmp;
pub fn shape_text(font: &Font, glyph_ranges: &GlyphRanges, string: &str) -> Vec<GlyphPos> {
let mut advance = 0;
string.chars().map(|ch| {
let glyph_id = glyph_ranges.glyph_for(ch as u32).unwrap_or(0);
let metrics = font.metrics_for_glyph(glyph_id);
let pos = GlyphPos {
glyph_id: glyph_id,
advance: cmp::max(0, advance) as u16,
let advance = match metrics {
Err(_) => 0,
Ok(metrics) => metrics.advance_width,
};
if let Ok(ref metrics) = metrics {
advance = metrics.advance_width as i32
GlyphPos {
glyph_id: glyph_id,
advance: advance,
}
pos
}).collect()
}