diff options
author | Brian J. Burg <burg@cs.washington.edu> | 2012-10-18 11:53:25 -0700 |
---|---|---|
committer | Brian J. Burg <burg@cs.washington.edu> | 2012-10-18 11:53:25 -0700 |
commit | 0f050e783525225b8897db575abc7d0da53510cc (patch) | |
tree | 92b095ded3b2e15dd7953619e6ef49cd90695faf /src/servo | |
parent | efca6fedfc901e0954609dec8f6a6e22beaff043 (diff) | |
download | servo-0f050e783525225b8897db575abc7d0da53510cc.tar.gz servo-0f050e783525225b8897db575abc7d0da53510cc.zip |
More TextRange refactoring.
Diffstat (limited to 'src/servo')
-rw-r--r-- | src/servo/layout/box.rs | 46 | ||||
-rw-r--r-- | src/servo/layout/inline.rs | 8 | ||||
-rw-r--r-- | src/servo/layout/text.rs | 76 | ||||
-rw-r--r-- | src/servo/text/font.rs | 15 | ||||
-rw-r--r-- | src/servo/text/text_run.rs | 4 |
5 files changed, 44 insertions, 105 deletions
diff --git a/src/servo/layout/box.rs b/src/servo/layout/box.rs index d32729105b7..89255b83c0c 100644 --- a/src/servo/layout/box.rs +++ b/src/servo/layout/box.rs @@ -187,47 +187,47 @@ impl RenderBox : RenderBoxMethods { let mut i : uint = 0; let mut remaining_width : au = max_width; - let mut left_offset : uint = data.offset; + let mut left_offset : uint = data.range.begin(); let mut left_length : uint = 0; let mut right_offset : Option<uint> = None; let mut right_length : Option<uint> = None; debug!("split_to_width: splitting text box (strlen=%u, off=%u, len=%u, avail_width=%?)", - data.run.text.len(), data.offset, data.length, max_width); - do data.run.iter_indivisible_pieces_for_range(TextRange(data.offset, data.length)) |subrange| { + data.run.text.len(), data.range.begin(), data.range.length(), max_width); + do data.run.iter_indivisible_pieces_for_range(data.range) |piece_range| { debug!("split_to_width: considering range (off=%u, len=%u, remain_width=%?)", - subrange.begin(), subrange.length(), remaining_width); - let metrics = data.run.metrics_for_range(subrange); + piece_range.begin(), piece_range.length(), remaining_width); + let metrics = data.run.metrics_for_range(piece_range); let advance = metrics.advance_width; let should_continue : bool; if advance <= remaining_width { should_continue = true; - if starts_line && i == 0 && data.run.range_is_trimmable_whitespace(subrange) { + if starts_line && i == 0 && data.run.range_is_trimmable_whitespace(piece_range) { debug!("split_to_width: case=skipping leading trimmable whitespace"); - left_offset += subrange.length(); + left_offset += piece_range.length(); } else { debug!("split_to_width: case=enlarging span"); remaining_width -= advance; - left_length += subrange.length(); + left_length += piece_range.length(); } } else { /* advance > remaining_width */ should_continue = false; - if data.run.range_is_trimmable_whitespace(subrange) { + if data.run.range_is_trimmable_whitespace(piece_range) { // if there are still things after the trimmable whitespace, create right chunk - if subrange.end() < data.offset + data.length { + if piece_range.end() < data.range.end() { debug!("split_to_width: case=skipping trimmable trailing whitespace, then split remainder"); - right_offset = Some(subrange.end()); - right_length = Some((data.offset + data.length) - subrange.end()); + right_offset = Some(piece_range.end()); + right_length = Some(data.range.end() - piece_range.end()); } else { debug!("split_to_width: case=skipping trimmable trailing whitespace"); } - } else if subrange.begin() < data.length + data.offset { + } else if piece_range.begin() < data.range.end() { // still things left, create right chunk - right_offset = Some(subrange.begin()); - right_length = Some((data.offset + data.length) - subrange.begin()); + right_offset = Some(piece_range.begin()); + right_length = Some(data.range.end() - piece_range.begin()); debug!("split_to_width: case=splitting remainder with right span: (off=%u, len=%u)", - subrange.begin(), (data.offset + data.length) - subrange.begin()); + piece_range.begin(), data.range.end() - piece_range.begin()); } } i += 1; @@ -235,14 +235,14 @@ impl RenderBox : RenderBoxMethods { } let left_box = if left_length > 0 { - Some(layout::text::adapt_textbox_with_range(self.d(), data.run, - left_offset, left_length)) + Some(layout::text::adapt_textbox_with_range(self.d(), data.run, + TextRange(left_offset, left_length))) } else { None }; match (right_offset, right_length) { (Some(right_off), Some(right_len)) => { let right_box = layout::text::adapt_textbox_with_range(self.d(), data.run, - right_off, right_len); + TextRange(right_off, right_len)); return if i == 1 || left_box.is_none() { SplitDidNotFit(left_box, Some(right_box)) } else { @@ -270,7 +270,7 @@ impl RenderBox : RenderBoxMethods { // TODO: consult CSS 'width', margin, border. // TODO: If image isn't available, consult 'width'. ImageBox(_,i) => au::from_px(i.get_size().get_default(Size2D(0,0)).width), - TextBox(_,d) => d.run.min_width_for_range(TextRange(d.offset, d.length)), + TextBox(_,d) => d.run.min_width_for_range(d.range), UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here." } } @@ -293,7 +293,7 @@ impl RenderBox : RenderBoxMethods { // factor in min/pref widths of any text runs that it owns. TextBox(_,d) => { let mut max_line_width: au = au(0); - for d.run.iter_natural_lines_for_range(TextRange(d.offset, d.length)) |line_range| { + for d.run.iter_natural_lines_for_range(d.range) |line_range| { // if the line is a single newline, then len will be zero if line_range.length() == 0 { loop } @@ -442,7 +442,7 @@ impl RenderBox : RenderBoxMethods { UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here.", TextBox(_,d) => { list.append_item(~dl::Text(copy abs_box_bounds, text_run::serialize(builder.ctx.font_cache, d.run), - d.offset, d.length)) + d.range.begin(), d.range.length())) }, // TODO: items for background, border, outline GenericBox(_) => { @@ -519,7 +519,7 @@ impl RenderBox : BoxedDebugMethods { let repr = match self { @GenericBox(*) => ~"GenericBox", @ImageBox(*) => ~"ImageBox", - @TextBox(_,d) => fmt!("TextBox(text=%s)", str::substr(d.run.text, d.offset, d.length)), + @TextBox(_,d) => fmt!("TextBox(text=%s)", str::substr(d.run.text, d.range.begin(), d.range.length())), @UnscannedTextBox(_,s) => fmt!("UnscannedTextBox(%s)", s) }; diff --git a/src/servo/layout/inline.rs b/src/servo/layout/inline.rs index 97acba4c6cc..2c86e15527c 100644 --- a/src/servo/layout/inline.rs +++ b/src/servo/layout/inline.rs @@ -168,7 +168,8 @@ impl TextRunScanner { let run = @TextRun(ctx.font_cache.get_test_font(), move transformed_text); debug!("TextRunScanner: pushing single text box when start=%u,end=%u", self.clump_start, self.clump_end); - let new_box = layout::text::adapt_textbox_with_range(in_boxes[self.clump_start].d(), run, 0, run.text.len()); + let new_box = layout::text::adapt_textbox_with_range(in_boxes[self.clump_start].d(), run, + TextRange(0, run.text.len())); out_boxes.push(new_box); }, (false, true) => { @@ -221,7 +222,8 @@ impl TextRunScanner { let run = @TextRun(ctx.font_cache.get_test_font(), move run_str); debug!("TextRunScanner: pushing box(es) when start=%u,end=%u", self.clump_start, self.clump_end); - let new_box = layout::text::adapt_textbox_with_range(in_boxes[self.clump_start].d(), run, 0, run.text.len()); + let new_box = layout::text::adapt_textbox_with_range(in_boxes[self.clump_start].d(), run, + TextRange(0, run.text.len())); out_boxes.push(new_box); } } /* /match */ @@ -586,7 +588,7 @@ impl FlowContext : InlineLayout { // adjust bounding box metric to box's horizontal offset // TODO: can we trust the leading provided by font metrics? @TextBox(_, data) => { - let text_bounds = data.run.metrics_for_range(TextRange(data.offset, data.length)).bounding_box; + let text_bounds = data.run.metrics_for_range(data.range).bounding_box; text_bounds.translate(&Point2D(cur_box.d().position.origin.x, au(0))) }, _ => fail fmt!("Tried to compute bounding box of unknown Box variant: %s", cur_box.debug_str()) diff --git a/src/servo/layout/text.rs b/src/servo/layout/text.rs index b218f4b191e..49f8682f4ec 100644 --- a/src/servo/layout/text.rs +++ b/src/servo/layout/text.rs @@ -1,34 +1,27 @@ /** Text layout. */ -use au = gfx::geometry; -use au::au; -use geom::size::Size2D; use servo_text::text_run::{TextRange, TextRun}; -use servo_text::font_cache::FontCache; use layout::box::{TextBox, RenderBox, RenderBoxData, UnscannedTextBox}; -use layout::context::LayoutContext; pub struct TextBoxData { run: @TextRun, - offset: uint, - length: uint + range: TextRange, } -pub fn TextBoxData(run: @TextRun, offset: uint, length: uint) -> TextBoxData { +pub fn TextBoxData(run: @TextRun, range: TextRange) -> TextBoxData { TextBoxData { run: run, - offset: offset, - length: length + range: range, } } pub fn adapt_textbox_with_range(box_data: &RenderBoxData, run: @TextRun, - offset: uint, length: uint) -> @RenderBox { + range: TextRange) -> @RenderBox { debug!("Creating textbox with span: (strlen=%u, off=%u, len=%u) of textrun: %s", - run.text.len(), offset, length, run.text); + run.text.len(), range.begin(), range.length(), run.text); let new_box_data = copy *box_data; - let new_text_data = TextBoxData(run, offset, length); - let metrics = run.metrics_for_range(TextRange(offset, length)); + let new_text_data = TextBoxData(run, range); + let metrics = run.metrics_for_range(range); new_box_data.position.size = metrics.bounding_box.size; @TextBox(move new_box_data, move new_text_data) } @@ -45,58 +38,3 @@ impl RenderBox : UnscannedMethods { } } } - -/* The main reflow routine for text layout. -impl @RenderBox : TextLayout { - fn reflow_text(ctx: &LayoutContext) { - let d = match self { - @TextBox(_,d) => { d } - _ => { fail ~"expected text box in reflow_text!" } - }; - - // TODO: get font from textrun's TextStyle - let font = ctx.font_cache.get_test_font(); - - // Do line breaking. - let mut current = TextRun(font, d.text); - let mut lines = dvec::DVec(); - let mut width_left = au::from_px(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.d().position.size = Size2D(max_width, total_height); - d.runs = move dvec::unwrap(lines); - } -}*/ diff --git a/src/servo/text/font.rs b/src/servo/text/font.rs index 675a06ac837..ca4a6cf81a2 100644 --- a/src/servo/text/font.rs +++ b/src/servo/text/font.rs @@ -9,7 +9,7 @@ use glyph::GlyphIndex; use libc::{ c_int, c_double, c_ulong }; use native_font::NativeFont; use ptr::{null, addr_of}; -use text::text_run::TextRun; +use text::text_run::{TextRun, TextRange}; use vec_to_ptr = vec::raw::to_ptr; // Used to abstract over the shaper's choice of fixed int representation. @@ -41,7 +41,7 @@ struct RunMetrics { // Public API pub trait FontMethods { - fn measure_text(run: &TextRun, offset: uint, length: uint) -> RunMetrics; + fn measure_text(&TextRun, TextRange) -> RunMetrics; fn buf(&self) -> @~[u8]; // these are used to get glyphs and advances in the case that the @@ -51,15 +51,14 @@ pub trait FontMethods { } pub impl Font : FontMethods { - fn measure_text(run: &TextRun, offset: uint, length: uint) -> RunMetrics { - assert offset < run.text.len(); - assert offset + length <= run.text.len(); + fn measure_text(run: &TextRun, range: TextRange) -> RunMetrics { + assert range.is_valid_for_string(run.text); // TODO: alter advance direction for RTL // TODO(Issue #98): using inter-char and inter-word spacing settings when measuring text let mut advance = au(0); - if length > 0 { - do run.glyphs.iter_glyphs_for_range(offset, length) |_i, glyph| { + if range.length() > 0 { + do run.glyphs.iter_glyphs_for_range(range.begin(), range.length()) |_i, glyph| { advance += glyph.advance(); } } @@ -75,7 +74,7 @@ pub impl Font : FontMethods { ascent: self.metrics.ascent, descent: self.metrics.descent, }; - debug!("Measured text range '%s' with metrics:", run.text.substr(offset, length)); + debug!("Measured text range '%s' with metrics:", run.text.substr(range.begin(), range.length())); debug!("%?", metrics); return metrics; diff --git a/src/servo/text/text_run.rs b/src/servo/text/text_run.rs index 5fc3d4df0a5..300cb6bdd7a 100644 --- a/src/servo/text/text_run.rs +++ b/src/servo/text/text_run.rs @@ -167,7 +167,7 @@ impl TextRun : TextRunMethods { } fn metrics_for_range(&self, range: TextRange) -> RunMetrics { - self.font.measure_text(self, range.begin(), range.length()) + self.font.measure_text(self, range) } fn min_width_for_range(&self, range: TextRange) -> au { @@ -175,7 +175,7 @@ impl TextRun : TextRunMethods { let mut max_piece_width = au(0); for self.iter_indivisible_pieces_for_range(range) |piece_range| { - let metrics = self.font.measure_text(self, piece_range.begin(), piece_range.length()); + let metrics = self.font.measure_text(self, piece_range); max_piece_width = au::max(max_piece_width, metrics.advance_width); } return max_piece_width; |