From da17edee9230c8c5cadb2bde322c552f8ddf104a Mon Sep 17 00:00:00 2001 From: "Brian J. Burg" Date: Sun, 18 Nov 2012 18:49:46 -0800 Subject: [PATCH] Move away from using non-freezable Range. --- src/servo-gfx/display_list.rs | 10 +++++----- src/servo-gfx/font.rs | 10 +++++----- src/servo-gfx/text/glyph.rs | 4 ++-- src/servo-gfx/text/text_run.rs | 22 +++++++++++----------- src/servo-gfx/util/range.rs | 4 ---- src/servo/layout/box.rs | 22 +++++++++++----------- src/servo/layout/box_builder.rs | 2 +- src/servo/layout/inline.rs | 28 ++++++++++++++-------------- src/servo/layout/text.rs | 10 +++++----- 9 files changed, 54 insertions(+), 58 deletions(-) diff --git a/src/servo-gfx/display_list.rs b/src/servo-gfx/display_list.rs index bb0d17685e05..fb07756df57b 100644 --- a/src/servo-gfx/display_list.rs +++ b/src/servo-gfx/display_list.rs @@ -3,7 +3,7 @@ use geometry::Au; use image::base::Image; use render_context::RenderContext; use text::SendableTextRun; -use util::range::Range; +use util::range::MutableRange; use azure::azure_hl::DrawTarget; use core::dvec::DVec; @@ -27,7 +27,7 @@ pub enum DisplayItem { // TODO: need to provide spacing data for text run. // (i.e, to support rendering of CSS 'word-spacing' and 'letter-spacing') // TODO: don't copy text runs, ever. - Text(DisplayItemData, ~SendableTextRun, Range, Color), + Text(DisplayItemData, ~SendableTextRun, MutableRange, Color), Image(DisplayItemData, ARC<~image::base::Image>), Border(DisplayItemData, Au, Color) } @@ -45,7 +45,7 @@ impl DisplayItem { fn draw_into_context(&self, ctx: &RenderContext) { match *self { SolidColor(_, color) => ctx.draw_solid_color(&self.d().bounds, color), - Text(_, run, range, color) => { + Text(_, run, ref range, color) => { let new_run = @run.deserialize(ctx.font_ctx); let font = new_run.font; let origin = self.d().bounds.origin; @@ -71,9 +71,9 @@ impl DisplayItem { static pure fn new_Text(bounds: &Rect, run: ~SendableTextRun, - range: Range, + range: MutableRange, color: Color) -> DisplayItem { - Text(DisplayItemData::new(bounds), move run, range, color) + Text(DisplayItemData::new(bounds), move run, move range, color) } // ARC should be cloned into ImageData, but Images are not sendable diff --git a/src/servo-gfx/font.rs b/src/servo-gfx/font.rs index 627520d9275f..2a7a52e99464 100644 --- a/src/servo-gfx/font.rs +++ b/src/servo-gfx/font.rs @@ -2,7 +2,7 @@ use color::Color; use font_context::FontContext; use geometry::Au; use render_context::RenderContext; -use util::range::Range; +use util::range::{Range, MutableRange}; use text::glyph::{GlyphStore, GlyphIndex}; use text::{Shaper, TextRun}; @@ -372,10 +372,10 @@ impl Font { pub trait FontMethods { fn draw_text_into_context(rctx: &RenderContext, run: &TextRun, - range: Range, + range: &MutableRange, baseline_origin: Point2D, color: Color); - fn measure_text(&TextRun, Range) -> RunMetrics; + fn measure_text(&TextRun, &const MutableRange) -> RunMetrics; fn shape_text(@self, &str) -> GlyphStore; fn get_descriptor() -> FontDescriptor; @@ -388,7 +388,7 @@ pub trait FontMethods { pub impl Font : FontMethods { fn draw_text_into_context(rctx: &RenderContext, run: &TextRun, - range: Range, + range: &const MutableRange, baseline_origin: Point2D, color: Color) { use libc::types::common::c99::{uint16_t, uint32_t}; @@ -445,7 +445,7 @@ pub impl Font : FontMethods { ptr::null()); } - fn measure_text(run: &TextRun, range: Range) -> RunMetrics { + fn measure_text(run: &TextRun, range: &const MutableRange) -> RunMetrics { assert range.is_valid_for_string(run.text); // TODO(Issue #199): alter advance direction for RTL diff --git a/src/servo-gfx/text/glyph.rs b/src/servo-gfx/text/glyph.rs index d58ce74c0af3..9dba4ed225ee 100644 --- a/src/servo-gfx/text/glyph.rs +++ b/src/servo-gfx/text/glyph.rs @@ -1,6 +1,6 @@ use au = geometry; use au::Au; -use servo_gfx_util::range::Range; +use servo_gfx_util::range::MutableRange; use servo_gfx_util::vec::*; use core::cmp::{Ord, Eq}; @@ -582,7 +582,7 @@ impl GlyphStore { return true; } - fn iter_glyphs_for_range(&self, range: Range, cb: fn&(uint, GlyphInfo/&) -> bool) { + fn iter_glyphs_for_range(&self, range: &const MutableRange, cb: fn&(uint, GlyphInfo/&) -> bool) { assert range.begin() < self.entry_buffer.len(); assert range.end() <= self.entry_buffer.len(); diff --git a/src/servo-gfx/text/text_run.rs b/src/servo-gfx/text/text_run.rs index eb3a8b6d32f6..1a7348424d7c 100644 --- a/src/servo-gfx/text/text_run.rs +++ b/src/servo-gfx/text/text_run.rs @@ -60,7 +60,7 @@ impl TextRun { pure fn glyphs(&self) -> &self/GlyphStore { &self.glyphs } - pure fn range_is_trimmable_whitespace(&self, range: Range) -> bool { + pure fn range_is_trimmable_whitespace(&self, range: &const MutableRange) -> bool { let mut i = range.begin(); while i < range.end() { // jump i to each new char @@ -74,11 +74,11 @@ impl TextRun { return true; } - fn metrics_for_range(&self, range: Range) -> RunMetrics { + fn metrics_for_range(&self, range: &const MutableRange) -> RunMetrics { self.font.measure_text(self, range) } - fn min_width_for_range(&self, range: Range) -> Au { + fn min_width_for_range(&self, range: &const MutableRange) -> Au { assert range.is_valid_for_string(self.text); let mut max_piece_width = Au(0); @@ -89,7 +89,7 @@ impl TextRun { return max_piece_width; } - fn iter_natural_lines_for_range(&self, range: Range, f: fn(Range) -> bool) { + fn iter_natural_lines_for_range(&self, range: &const MutableRange, f: fn(&const MutableRange) -> bool) { assert range.is_valid_for_string(self.text); let mut clump = MutableRange::new(range.begin(), 0); @@ -105,7 +105,7 @@ impl TextRun { in_clump = false; // don't include the linebreak 'glyph' // (we assume there's one GlyphEntry for a newline, and no actual glyphs) - if !f(clump.as_immutable()) { break } + if !f(&const clump) { break } } } } @@ -113,11 +113,11 @@ impl TextRun { // flush any remaining chars as a line if in_clump { clump.extend_to(range.end()); - f(clump.as_immutable()); + f(&const clump); } } - fn iter_indivisible_pieces_for_range(&self, range: Range, f: fn(Range) -> bool) { + fn iter_indivisible_pieces_for_range(&self, range: &const MutableRange, f: fn(&const MutableRange) -> bool) { assert range.is_valid_for_string(self.text); let mut clump = MutableRange::new(range.begin(), 0); @@ -126,14 +126,14 @@ impl TextRun { match str::find_between(self.text, clump.begin(), range.end(), |c| !char::is_whitespace(c)) { Some(nonws_char_offset) => { clump.extend_to(nonws_char_offset); - if !f(clump.as_immutable()) { break } + if !f(&const clump) { break } clump.reset(clump.end(), 0); }, None => { // nothing left, flush last piece containing only whitespace if clump.end() < range.end() { clump.extend_to(range.end()); - f(clump.as_immutable()); + f(&const clump); break; } } @@ -143,14 +143,14 @@ impl TextRun { match str::find_between(self.text, clump.begin(), range.end(), |c| char::is_whitespace(c)) { Some(ws_char_offset) => { clump.extend_to(ws_char_offset); - if !f(clump.as_immutable()) { break } + if !f(&const clump) { break } clump.reset(clump.end(), 0); } None => { // nothing left, flush last piece containing only non-whitespaces if clump.end() < range.end() { clump.extend_to(range.end()); - f(clump.as_immutable()); + f(&const clump); break; } } diff --git a/src/servo-gfx/util/range.rs b/src/servo-gfx/util/range.rs index 68111c461fbe..d9243584be16 100644 --- a/src/servo-gfx/util/range.rs +++ b/src/servo-gfx/util/range.rs @@ -83,10 +83,6 @@ pub impl MutableRange { i >= self.begin() && i < self.end() } - pure fn as_immutable(&const self) -> Range { - Range(self.begin(), self.length()) - } - pure fn is_valid_for_string(&const self, s: &str) -> bool { self.begin() < s.len() && self.end() <= s.len() && self.length() <= s.len() } diff --git a/src/servo/layout/box.rs b/src/servo/layout/box.rs index 919b78e1150a..276caae3e940 100644 --- a/src/servo/layout/box.rs +++ b/src/servo/layout/box.rs @@ -190,10 +190,10 @@ impl RenderBox : RenderBoxMethods { let mut pieces_processed_count : uint = 0; let mut remaining_width : Au = max_width; let mut left_range = MutableRange::new(data.range.begin(), 0); - let mut right_range : Option = None; + let mut right_range : Option = None; debug!("split_to_width: splitting text box (strlen=%u, range=%?, avail_width=%?)", data.run.text.len(), data.range, max_width); - do data.run.iter_indivisible_pieces_for_range(data.range) |piece_range| { + do data.run.iter_indivisible_pieces_for_range(&const data.range) |piece_range| { debug!("split_to_width: considering piece (range=%?, remain_width=%?)", piece_range, remaining_width); let metrics = data.run.metrics_for_range(piece_range); @@ -218,15 +218,15 @@ impl RenderBox : RenderBoxMethods { // if there are still things after the trimmable whitespace, create right chunk if piece_range.end() < data.range.end() { debug!("split_to_width: case=skipping trimmable trailing whitespace, then split remainder"); - right_range = Some(Range(piece_range.end(), - data.range.end() - piece_range.end())); + right_range = Some(MutableRange::new(piece_range.end(), + data.range.end() - piece_range.end())); } else { debug!("split_to_width: case=skipping trimmable trailing whitespace"); } } else if piece_range.begin() < data.range.end() { // still things left, create right chunk - right_range = Some(Range(piece_range.begin(), - data.range.end() - piece_range.begin())); + right_range = Some(MutableRange::new(piece_range.begin(), + data.range.end() - piece_range.begin())); debug!("split_to_width: case=splitting remainder with right range=%?", right_range); } @@ -236,11 +236,11 @@ impl RenderBox : RenderBoxMethods { } let left_box = if left_range.length() > 0 { - Some(layout::text::adapt_textbox_with_range(self.d(), data.run, left_range.as_immutable())) + Some(layout::text::adapt_textbox_with_range(self.d(), data.run, &const left_range)) } else { None }; - let right_box = option::map_default(&right_range, None, |range: &Range| { - Some(layout::text::adapt_textbox_with_range(self.d(), data.run, *range)) + let right_box = option::map_default(&right_range, None, |range: &const MutableRange| { + Some(layout::text::adapt_textbox_with_range(self.d(), data.run, range)) }); return if pieces_processed_count == 1 || left_box.is_none() { @@ -267,7 +267,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(d.range), + TextBox(_,d) => d.run.min_width_for_range(&const d.range), UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here." } } @@ -290,7 +290,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(d.range) |line_range| { + for d.run.iter_natural_lines_for_range(&const d.range) |line_range| { let mut line_width: Au = Au(0); for d.run.glyphs.iter_glyphs_for_range(line_range) |_char_i, glyph| { line_width += glyph.advance() diff --git a/src/servo/layout/box_builder.rs b/src/servo/layout/box_builder.rs index 94e3e6ea19d0..cbd9b8a218d8 100644 --- a/src/servo/layout/box_builder.rs +++ b/src/servo/layout/box_builder.rs @@ -156,7 +156,7 @@ impl BoxGenerator { assert node_range.length() > 0; debug!("BoxGenerator: adding element range=%?", node_range); - self.flow.inline().elems.add_mapping(node, node_range.as_immutable()); + self.flow.inline().elems.add_mapping(node, &const node_range); }, @BlockFlow(*) | @RootFlow(*) => { assert self.range_stack.len() == 0; diff --git a/src/servo/layout/inline.rs b/src/servo/layout/inline.rs index e1e869fbc3d7..2f5245228c0a 100644 --- a/src/servo/layout/inline.rs +++ b/src/servo/layout/inline.rs @@ -41,12 +41,12 @@ hard to try out that alternative. struct NodeRange { node: Node, - mut range: Range, + range: MutableRange, } impl NodeRange { - static pure fn new(node: Node, range: Range) -> NodeRange { - NodeRange { node: node, range: range } + static pure fn new(node: Node, range: &const MutableRange) -> NodeRange { + NodeRange { node: node, range: copy *range } } } @@ -59,7 +59,7 @@ impl ElementMapping { ElementMapping { entries: DVec() } } - fn add_mapping(node: Node, range: Range) { + fn add_mapping(node: Node, range: &const MutableRange) { self.entries.push(NodeRange::new(node, range)) } @@ -103,7 +103,7 @@ impl ElementMapping { }; let repair_stack : DVec = DVec(); - do self.entries.borrow |entries: &[NodeRange]| { + do self.entries.borrow_mut |entries: &[mut NodeRange]| { // index into entries let mut entries_k = 0; @@ -133,7 +133,7 @@ impl ElementMapping { let item = repair_stack.pop(); debug!("repair_for_box_changes: Set range for %u to %?", item.entry_idx, Range(item.begin_idx, new_j - item.begin_idx)); - entries[item.entry_idx].range = Range(item.begin_idx, new_j - item.begin_idx); + entries[item.entry_idx].range = MutableRange::new(item.begin_idx, new_j - item.begin_idx); } } } @@ -249,7 +249,7 @@ priv impl TextRunScanner { debug!("TextRunScanner: pushing single text box in range: %?", self.clump); let new_box = layout::text::adapt_textbox_with_range(old_box.d(), run, - Range(0, run.text.len())); + &const MutableRange::new(0, run.text.len())); out_boxes.push(new_box); }, (false, true) => { @@ -270,9 +270,9 @@ priv impl TextRunScanner { // TODO(Issue #118): use a rope, simply give ownership of nonzero strs to rope let mut run_str : ~str = ~""; - let new_ranges : DVec = DVec(); + let new_ranges : DVec = DVec(); for uint::range(0, transformed_strs.len()) |i| { - new_ranges.push(Range(run_str.len(), transformed_strs[i].len())); + new_ranges.push(MutableRange::new(run_str.len(), transformed_strs[i].len())); str::push_str(&mut run_str, transformed_strs[i]); } @@ -289,7 +289,7 @@ priv impl TextRunScanner { debug!("TextRunScanner: pushing box(es) in range: %?", self.clump); let clump = self.clump; for clump.eachi |i| { - let range = new_ranges[i - self.clump.begin()]; + let range = &const new_ranges[i - self.clump.begin()]; if range.length() == 0 { error!("Elided an UnscannedTextbox because it was zero-length after compression; %s", in_boxes[i].debug_str()); @@ -328,7 +328,7 @@ struct LineboxScanner { new_boxes: DVec<@RenderBox>, work_list: DList<@RenderBox>, pending_line: {mut range: MutableRange, mut width: Au}, - line_spans: DVec, + line_spans: DVec, } fn LineboxScanner(inline: @FlowContext) -> LineboxScanner { @@ -415,7 +415,7 @@ impl LineboxScanner { debug!("LineboxScanner: Flushing line %u: %?", self.line_spans.len(), self.pending_line); // set box horizontal offsets - let line_range = self.pending_line.range.as_immutable(); + let line_range = self.pending_line.range; let mut offset_x = Au(0); // TODO(Issue #199): interpretation of CSS 'direction' will change how boxes are positioned. debug!("LineboxScanner: Setting horizontal offsets for boxes in line %u range: %?", @@ -566,7 +566,7 @@ struct InlineFlowData { boxes: DVec<@RenderBox>, // vec of ranges into boxes that represents line positions. // these ranges are disjoint, and are the result of inline layout. - lines: DVec, + lines: DVec, // vec of ranges into boxes that represent elements. These ranges // must be well-nested, and are only related to the content of // boxes (not lines). Ranges are only kept for non-leaf elements. @@ -681,7 +681,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(data.range).bounding_box; + let text_bounds = data.run.metrics_for_range(&const 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 4ffdee41c1b0..f932b654d4d4 100644 --- a/src/servo/layout/text.rs +++ b/src/servo/layout/text.rs @@ -3,22 +3,22 @@ use layout::box::{TextBox, RenderBox, RenderBoxData, UnscannedTextBox}; use gfx::text::text_run::TextRun; -use gfx::util::range::Range; +use gfx::util::range::MutableRange; pub struct TextBoxData { run: @TextRun, - range: Range, + range: MutableRange, } -pub fn TextBoxData(run: @TextRun, range: Range) -> TextBoxData { +pub fn TextBoxData(run: @TextRun, range: &const MutableRange) -> TextBoxData { TextBoxData { run: run, - range: range, + range: copy *range, } } pub fn adapt_textbox_with_range(box_data: &RenderBoxData, run: @TextRun, - range: Range) -> @RenderBox { + range: &const MutableRange) -> @RenderBox { debug!("Creating textbox with span: (strlen=%u, off=%u, len=%u) of textrun: %s", run.text.len(), range.begin(), range.length(), run.text); let new_box_data = copy *box_data;