aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrian J. Burg <burg@cs.washington.edu>2012-10-18 11:53:25 -0700
committerBrian J. Burg <burg@cs.washington.edu>2012-10-18 11:53:25 -0700
commit0f050e783525225b8897db575abc7d0da53510cc (patch)
tree92b095ded3b2e15dd7953619e6ef49cd90695faf /src
parentefca6fedfc901e0954609dec8f6a6e22beaff043 (diff)
downloadservo-0f050e783525225b8897db575abc7d0da53510cc.tar.gz
servo-0f050e783525225b8897db575abc7d0da53510cc.zip
More TextRange refactoring.
Diffstat (limited to 'src')
-rw-r--r--src/servo/layout/box.rs46
-rw-r--r--src/servo/layout/inline.rs8
-rw-r--r--src/servo/layout/text.rs76
-rw-r--r--src/servo/text/font.rs15
-rw-r--r--src/servo/text/text_run.rs4
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;