Add some primitive text line breaking

This commit is contained in:
Patrick Walton 2012-09-14 19:57:10 -07:00
parent b7c241a091
commit 632bffd8f4
3 changed files with 58 additions and 13 deletions

View file

@ -84,14 +84,20 @@ fn box_to_display_items(list: dl::DisplayList, box: @Box, origin: Point2D<au>) {
match box.kind {
TextBoxKind(subbox) => {
let run = copy subbox.run;
assert run.is_some();
let runs = &mut subbox.runs;
list.push(~dl::SolidColor(bounds, 255u8, 255u8, 255u8));
let glyph_run = text_run_to_dl_glyph_run(run.get_ref());
list.push(~dl::Glyphs(bounds, glyph_run));
let mut bounds = bounds;
for uint::range(0, runs.len()) |i| {
bounds.size.height = runs[i].size().height;
let glyph_run = text_run_to_dl_glyph_run(&mut runs[i]);
list.push(~dl::Glyphs(bounds, glyph_run));
bounds.origin.y += bounds.size.height;
}
return;
fn text_run_to_dl_glyph_run(text_run: &TextRun) -> dl::GlyphRun {
pure fn text_run_to_dl_glyph_run(text_run: &mut TextRun) ->
dl::GlyphRun {
dl::GlyphRun {
glyphs: copy text_run.glyphs
}

View file

@ -1,20 +1,20 @@
#[doc="Text layout."]
use geom::size::Size2D;
use gfx::geometry::au;
use gfx::geometry::{au, px_to_au};
use servo_text::text_run::TextRun;
use servo_text::font_library::FontLibrary;
use base::{Box, TextBoxKind};
struct TextBox {
text: ~str,
mut run: Option<TextRun>,
mut runs: ~[TextRun],
}
fn TextBox(text: ~str) -> TextBox {
TextBox {
text: text,
run: None,
runs: ~[],
}
}
@ -33,9 +33,48 @@ impl @Box : TextLayout {
// FIXME: The font library should not be initialized here
let flib = FontLibrary();
let font = flib.get_test_font();
let run = TextRun(font, subbox.text);
self.bounds.size = run.size();
subbox.run = Some(run);
// Do line breaking.
let mut current = TextRun(font, subbox.text);
let mut lines = dvec::DVec();
let mut width_left = px_to_au(800);
let mut max_width = au(0);
while current.size().width > width_left {
let min_width = current.min_break_width();
debug!("line %d, current width %d, width left %d, min width %d",
lines.len() as int,
*current.size().width as int,
*width_left as int,
*min_width as int);
if min_width > width_left {
// Too bad, we couldn't break. Overflow.
break;
}
let (prev_line, next_line) = current.split(font, width_left);
let prev_width = prev_line.size().width;
if max_width < prev_width {
max_width = prev_width;
}
lines.push(move prev_line);
current = next_line;
}
let remaining_width = current.size().width;
if max_width < remaining_width {
max_width = remaining_width;
}
let line_count = 1 + (lines.len() as i32);
let total_height = au(*current.size().height * line_count);
lines.push(move current);
self.bounds.size = Size2D(max_width, total_height);
subbox.runs = dvec::unwrap(lines);
}
}

View file

@ -17,8 +17,8 @@ struct TextRun {
impl TextRun {
/// The size of the entire TextRun
fn size() -> Size2D<au> { self.size_ }
fn min_break_width() -> au { self.min_break_width_ }
pure fn size() -> Size2D<au> { self.size_ }
pure fn min_break_width() -> au { self.min_break_width_ }
/// Split a run of text in two
// FIXME: Should be storing a reference to the Font inside