Break at word boundaries
This commit is contained in:
parent
e9fd5d6b1b
commit
66d239cf2f
|
@ -94,31 +94,40 @@ fn main() {
|
||||||
let codepoint_ranges = CodepointRanges::from_sorted_chars(&chars);
|
let codepoint_ranges = CodepointRanges::from_sorted_chars(&chars);
|
||||||
|
|
||||||
let file = Mmap::open_path(font_path, Protection::Read).unwrap();
|
let file = Mmap::open_path(font_path, Protection::Read).unwrap();
|
||||||
let (font, shaped_glyph_positions, glyph_ranges);
|
let (font, glyph_ranges);
|
||||||
unsafe {
|
unsafe {
|
||||||
font = Font::new(file.as_slice()).unwrap();
|
font = Font::new(file.as_slice()).unwrap();
|
||||||
glyph_ranges = font.glyph_ranges_for_codepoint_ranges(&codepoint_ranges.ranges).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.
|
// Do some basic line breaking.
|
||||||
let mut glyph_positions = vec![];
|
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 line_spacing = font.units_per_em() as u32;
|
||||||
|
|
||||||
let (mut current_x, mut current_y) = (0, line_spacing);
|
let (mut current_x, mut current_y) = (0, line_spacing);
|
||||||
for glyph_position in &shaped_glyph_positions {
|
for word in text.split_whitespace() {
|
||||||
current_x += glyph_position.advance as u32;
|
let shaped_glyph_positions = shaper::shape_text(&font, &glyph_ranges, word);
|
||||||
if current_x > paragraph_width {
|
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_x = 0;
|
||||||
current_y += line_spacing;
|
current_y += line_spacing;
|
||||||
}
|
}
|
||||||
glyph_positions.push(GlyphPos {
|
|
||||||
x: current_x,
|
for glyph_position in &shaped_glyph_positions {
|
||||||
y: current_y,
|
glyph_positions.push(GlyphPos {
|
||||||
glyph_id: glyph_position.glyph_id,
|
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();
|
let renderer = Renderer::new();
|
||||||
|
@ -640,12 +649,12 @@ impl Renderer {
|
||||||
let mut fps_glyphs = vec![];
|
let mut fps_glyphs = vec![];
|
||||||
let mut current_x = 0;
|
let mut current_x = 0;
|
||||||
for glyph_pos in &shaper::shape_text(&font, &glyph_ranges, &fps_text) {
|
for glyph_pos in &shaper::shape_text(&font, &glyph_ranges, &fps_text) {
|
||||||
current_x += glyph_pos.advance as u32;
|
|
||||||
fps_glyphs.push(GlyphPos {
|
fps_glyphs.push(GlyphPos {
|
||||||
x: current_x,
|
x: current_x,
|
||||||
y: 0,
|
y: 0,
|
||||||
glyph_id: glyph_pos.glyph_id,
|
glyph_id: glyph_pos.glyph_id,
|
||||||
});
|
});
|
||||||
|
current_x += glyph_pos.advance as u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.draw_glyphs(font,
|
self.draw_glyphs(font,
|
||||||
|
|
|
@ -19,20 +19,19 @@ use otf::Font;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
|
||||||
pub fn shape_text(font: &Font, glyph_ranges: &GlyphRanges, string: &str) -> Vec<GlyphPos> {
|
pub fn shape_text(font: &Font, glyph_ranges: &GlyphRanges, string: &str) -> Vec<GlyphPos> {
|
||||||
let mut advance = 0;
|
|
||||||
string.chars().map(|ch| {
|
string.chars().map(|ch| {
|
||||||
let glyph_id = glyph_ranges.glyph_for(ch as u32).unwrap_or(0);
|
let glyph_id = glyph_ranges.glyph_for(ch as u32).unwrap_or(0);
|
||||||
let metrics = font.metrics_for_glyph(glyph_id);
|
let metrics = font.metrics_for_glyph(glyph_id);
|
||||||
|
|
||||||
let pos = GlyphPos {
|
let advance = match metrics {
|
||||||
glyph_id: glyph_id,
|
Err(_) => 0,
|
||||||
advance: cmp::max(0, advance) as u16,
|
Ok(metrics) => metrics.advance_width,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(ref metrics) = metrics {
|
GlyphPos {
|
||||||
advance = metrics.advance_width as i32
|
glyph_id: glyph_id,
|
||||||
|
advance: advance,
|
||||||
}
|
}
|
||||||
pos
|
|
||||||
}).collect()
|
}).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue