diff --git a/src/servo/layout/display_list_builder.rs b/src/servo/layout/display_list_builder.rs index 25eeaf18e5e..6ab83900dea 100644 --- a/src/servo/layout/display_list_builder.rs +++ b/src/servo/layout/display_list_builder.rs @@ -84,14 +84,20 @@ fn box_to_display_items(list: dl::DisplayList, box: @Box, origin: Point2D) { 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 } diff --git a/src/servo/layout/text.rs b/src/servo/layout/text.rs index 8f4a956a96a..5c7417cf38a 100644 --- a/src/servo/layout/text.rs +++ b/src/servo/layout/text.rs @@ -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, + 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); } } diff --git a/src/servo/text/text_run.rs b/src/servo/text/text_run.rs index 26bd981ba16..5333501fa7a 100644 --- a/src/servo/text/text_run.rs +++ b/src/servo/text/text_run.rs @@ -17,8 +17,8 @@ struct TextRun { impl TextRun { /// The size of the entire TextRun - fn size() -> Size2D { self.size_ } - fn min_break_width() -> au { self.min_break_width_ } + pure fn size() -> Size2D { 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