diff options
author | Patrick Walton <pcwalton@mimiga.net> | 2013-10-24 16:57:42 -0700 |
---|---|---|
committer | Patrick Walton <pcwalton@mimiga.net> | 2013-10-28 13:22:26 -0700 |
commit | 42092921c17a779eb8c0db3b056204dfaaa9dab7 (patch) | |
tree | c12417ad6538e0ba55328c4f3d254295055e133a /src/components/main/layout/text.rs | |
parent | 81f5ba7d059805e1c879bff1b7380c1d90ba9fd8 (diff) | |
download | servo-42092921c17a779eb8c0db3b056204dfaaa9dab7.tar.gz servo-42092921c17a779eb8c0db3b056204dfaaa9dab7.zip |
Optimize reflow by changing enums to traits and inlining more
Diffstat (limited to 'src/components/main/layout/text.rs')
-rw-r--r-- | src/components/main/layout/text.rs | 101 |
1 files changed, 31 insertions, 70 deletions
diff --git a/src/components/main/layout/text.rs b/src/components/main/layout/text.rs index a14dd2bf74a..77a8831d137 100644 --- a/src/components/main/layout/text.rs +++ b/src/components/main/layout/text.rs @@ -8,51 +8,11 @@ use std::vec; use gfx::text::text_run::TextRun; use gfx::text::util::{CompressWhitespaceNewline, transform_text}; -use layout::box::{RenderBox, RenderBoxBase, TextRenderBox}; -use layout::box::{TextRenderBoxClass, UnscannedTextRenderBoxClass}; +use layout::box::{RenderBox, RenderBoxUtils, TextRenderBox, UnscannedTextRenderBoxClass}; use layout::context::LayoutContext; use layout::flow::FlowContext; use servo_util::range::Range; - -/// Creates a TextRenderBox from a range and a text run. -pub fn adapt_textbox_with_range(mut base: RenderBoxBase, run: @TextRun, range: Range) - -> TextRenderBox { - debug!("Creating textbox with span: (strlen=%u, off=%u, len=%u) of textrun (%s) (len=%u)", - run.char_len(), - range.begin(), - range.length(), - run.text, - run.char_len()); - - assert!(range.begin() < run.char_len()); - assert!(range.end() <= run.char_len()); - assert!(range.length() > 0); - - let metrics = run.metrics_for_range(&range); - base.position.size = metrics.bounding_box.size; - - TextRenderBox { - base: base, - run: run, - range: range, - } -} - -pub trait UnscannedMethods { - /// Copies out the text from an unscanned text box. Fails if this is not an unscanned text box. - fn raw_text(&self) -> ~str; -} - -impl UnscannedMethods for RenderBox { - fn raw_text(&self) -> ~str { - match *self { - UnscannedTextRenderBoxClass(text_box) => text_box.text.clone(), - _ => fail!(~"unsupported operation: box.raw_text() on non-unscanned text box."), - } - } -} - /// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextBox`es. struct TextRunScanner { clump: Range, @@ -67,7 +27,7 @@ impl TextRunScanner { pub fn scan_for_runs(&mut self, ctx: &LayoutContext, flow: &mut FlowContext) { { - let inline = flow.imm_inline(); + let inline = flow.as_immutable_inline(); // FIXME: this assertion fails on wikipedia, but doesn't seem // to cause problems. // assert!(inline.boxes.len() > 0); @@ -76,9 +36,11 @@ impl TextRunScanner { let mut last_whitespace = true; let mut out_boxes = ~[]; - for box_i in range(0, flow.imm_inline().boxes.len()) { - debug!("TextRunScanner: considering box: %?", flow.imm_inline().boxes[box_i].debug_str()); - if box_i > 0 && !can_coalesce_text_nodes(flow.imm_inline().boxes, box_i-1, box_i) { + for box_i in range(0, flow.as_immutable_inline().boxes.len()) { + debug!("TextRunScanner: considering box: %u", box_i); + if box_i > 0 && !can_coalesce_text_nodes(flow.as_immutable_inline().boxes, + box_i - 1, + box_i) { last_whitespace = self.flush_clump_to_list(ctx, flow, last_whitespace, &mut out_boxes); } self.clump.extend_by(1); @@ -91,17 +53,17 @@ impl TextRunScanner { debug!("TextRunScanner: swapping out boxes."); // Swap out the old and new box list of the flow. - flow.inline().boxes = out_boxes; + flow.as_inline().boxes = out_boxes; // A helper function. - fn can_coalesce_text_nodes(boxes: &[RenderBox], left_i: uint, right_i: uint) -> bool { + fn can_coalesce_text_nodes(boxes: &[@RenderBox], left_i: uint, right_i: uint) -> bool { assert!(left_i < boxes.len()); assert!(right_i > 0 && right_i < boxes.len()); assert!(left_i != right_i); let (left, right) = (boxes[left_i], boxes[right_i]); - match (left, right) { - (UnscannedTextRenderBoxClass(*), UnscannedTextRenderBoxClass(*)) => { + match (left.class(), right.class()) { + (UnscannedTextRenderBoxClass, UnscannedTextRenderBoxClass) => { left.can_merge_with_box(right) } (_, _) => false @@ -123,18 +85,17 @@ impl TextRunScanner { ctx: &LayoutContext, flow: &mut FlowContext, last_whitespace: bool, - out_boxes: &mut ~[RenderBox]) -> bool { - let inline = flow.inline(); + out_boxes: &mut ~[@RenderBox]) + -> bool { + let inline = flow.as_inline(); let in_boxes = &inline.boxes; assert!(self.clump.length() > 0); debug!("TextRunScanner: flushing boxes in range=%?", self.clump); let is_singleton = self.clump.length() == 1; - let is_text_clump = match in_boxes[self.clump.begin()] { - UnscannedTextRenderBoxClass(*) => true, - _ => false - }; + let possible_text_clump = in_boxes[self.clump.begin()]; // FIXME(pcwalton): Rust bug + let is_text_clump = possible_text_clump.class() == UnscannedTextRenderBoxClass; let mut new_whitespace = last_whitespace; @@ -148,9 +109,9 @@ impl TextRunScanner { }, (true, true) => { let old_box = in_boxes[self.clump.begin()]; - let text = old_box.raw_text(); - let font_style = old_box.font_style(); - let decoration = old_box.text_decoration(); + let text = old_box.as_unscanned_text_render_box().raw_text(); + let font_style = old_box.base().font_style(); + let decoration = old_box.base().text_decoration(); // TODO(#115): Use the actual CSS `white-space` property of the relevant style. let compression = CompressWhitespaceNewline; @@ -166,12 +127,10 @@ impl TextRunScanner { let run = @fontgroup.create_textrun(transformed_text, decoration); debug!("TextRunScanner: pushing single text box in range: %? (%?)", self.clump, text); - let new_box = do old_box.with_base |old_box_base| { - let range = Range::new(0, run.char_len()); - @mut adapt_textbox_with_range(*old_box_base, run, range) - }; + let range = Range::new(0, run.char_len()); + let new_box = @TextRenderBox::new((*old_box.base()).clone(), run, range); - out_boxes.push(TextRenderBoxClass(new_box)); + out_boxes.push(new_box as @RenderBox); } }, (false, true) => { @@ -185,7 +144,8 @@ impl TextRunScanner { // `transform_text`, so that boxes starting and/or ending with whitespace can // be compressed correctly with respect to the text run. let idx = i + self.clump.begin(); - let (new_str, new_whitespace) = transform_text(in_boxes[idx].raw_text(), + let in_box = in_boxes[idx].as_unscanned_text_render_box().raw_text(); + let (new_str, new_whitespace) = transform_text(in_box, compression, last_whitespace_in_clump); last_whitespace_in_clump = new_whitespace; @@ -210,9 +170,10 @@ impl TextRunScanner { // TODO(#177): Text run creation must account for the renderability of text by // font group fonts. This is probably achieved by creating the font group above // and then letting `FontGroup` decide which `Font` to stick into the text run. - let font_style = in_boxes[self.clump.begin()].font_style(); + let in_box = in_boxes[self.clump.begin()]; + let font_style = in_box.base().font_style(); let fontgroup = ctx.font_ctx.get_resolved_font_for_style(&font_style); - let decoration = in_boxes[self.clump.begin()].text_decoration(); + let decoration = in_box.base().text_decoration(); // TextRuns contain a cycle which is usually resolved by the teardown // sequence. If no clump takes ownership, however, it will leak. @@ -234,10 +195,10 @@ impl TextRunScanner { continue } - do in_boxes[i].with_base |base| { - let new_box = @mut adapt_textbox_with_range(*base, run.unwrap(), range); - out_boxes.push(TextRenderBoxClass(new_box)); - } + let new_box = @TextRenderBox::new((*in_boxes[i].base()).clone(), + run.unwrap(), + range); + out_boxes.push(new_box as @RenderBox); } } } // End of match. |