diff --git a/src/components/servo-gfx/font.rs b/src/components/servo-gfx/font.rs index 9178d69351f..fd200050de4 100644 --- a/src/components/servo-gfx/font.rs +++ b/src/components/servo-gfx/font.rs @@ -177,6 +177,10 @@ pub impl FontGroup { } } + fn teardown(&mut self) { + self.fonts = ~[]; + } + fn create_textrun(&self, text: ~str) -> TextRun { assert!(self.fonts.len() > 0); @@ -283,6 +287,11 @@ pub impl Font { return result; } + fn teardown(&mut self) { + self.shaper = None; + self.azure_font = None; + } + // TODO: this should return a borrowed pointer, but I can't figure // out why borrowck doesn't like my implementation. diff --git a/src/components/servo-gfx/text/text_run.rs b/src/components/servo-gfx/text/text_run.rs index e94dd4a15df..d49c5ddd858 100644 --- a/src/components/servo-gfx/text/text_run.rs +++ b/src/components/servo-gfx/text/text_run.rs @@ -51,6 +51,10 @@ pub impl<'self> TextRun { return run; } + fn teardown(&self) { + self.font.teardown(); + } + fn compute_potential_breaks(text: &str, glyphs: &mut GlyphStore) { // TODO(Issue #230): do a better job. See Gecko's LineBreaker. diff --git a/src/components/servo/layout/aux.rs b/src/components/servo/layout/aux.rs index f56f204e0d1..8a311098d13 100644 --- a/src/components/servo/layout/aux.rs +++ b/src/components/servo/layout/aux.rs @@ -18,6 +18,14 @@ impl LayoutAuxMethods for AbstractNode { /// box in the COW model) and populates it with an empty style object. fn initialize_layout_data(self) -> Option<@mut LayoutData> { if self.has_layout_data() { + { + let layout_data = &mut self.layout_data().flow; + match *layout_data { + Some(ref flow) => flow.teardown(), + None => () + } + } + self.layout_data().flow = None; None } else { let data = @mut LayoutData::new(); diff --git a/src/components/servo/layout/block.rs b/src/components/servo/layout/block.rs index d5479984f8d..1d0ec0f9d86 100644 --- a/src/components/servo/layout/block.rs +++ b/src/components/servo/layout/block.rs @@ -45,6 +45,14 @@ impl BlockFlowData { is_root: true } } + + pub fn teardown(&mut self) { + self.common.teardown(); + for self.box.each |box| { + box.teardown(); + } + self.box = None; + } } pub trait BlockLayout { diff --git a/src/components/servo/layout/box.rs b/src/components/servo/layout/box.rs index da4cbc882db..129b79d1834 100644 --- a/src/components/servo/layout/box.rs +++ b/src/components/servo/layout/box.rs @@ -59,6 +59,15 @@ pub enum RenderBox { UnscannedTextRenderBoxClass(@mut UnscannedTextRenderBox), } +impl RenderBox { + pub fn teardown(&self) { + match *self { + TextRenderBoxClass(box) => box.teardown(), + _ => () + } + } +} + /// A box that represents a (replaced content) image and its accompanying borders, shadows, etc. pub struct ImageRenderBox { base: RenderBoxBase, @@ -88,6 +97,12 @@ pub struct TextRenderBox { text_data: TextBoxData, } +impl TextRenderBox { + fn teardown(&self) { + self.text_data.teardown(); + } +} + /// The data for an unscanned text box. pub struct UnscannedTextRenderBox { base: RenderBoxBase, diff --git a/src/components/servo/layout/flow.rs b/src/components/servo/layout/flow.rs index 3a1c7b3bb86..b28f11867f6 100644 --- a/src/components/servo/layout/flow.rs +++ b/src/components/servo/layout/flow.rs @@ -67,6 +67,43 @@ impl Clone for FlowContext { } } +impl FlowContext { + pub fn teardown(&self) { + match *self { + AbsoluteFlow(data) | + FloatFlow(data) | + InlineBlockFlow(data) | + TableFlow(data) => data.teardown(), + BlockFlow(data) => data.teardown(), + InlineFlow(data) => data.teardown() + } + } +} + +impl FlowData { + pub fn teardown(&mut self) { + // Under the assumption that all flows exist in a tree, + // we must restrict ourselves to finalizing flows that + // are descendents and subsequent siblings to ourselves, + // or we risk dynamic borrow failures. + self.parent = None; + + for self.first_child.each |flow| { + flow.teardown(); + } + self.first_child = None; + + self.last_child = None; + + for self.next_sibling.each |flow| { + flow.teardown(); + } + self.next_sibling = None; + + self.prev_sibling = None; + } +} + impl TreeNodeRef for FlowContext { fn with_base(&self, callback: &fn(&FlowData) -> R) -> R { match *self { diff --git a/src/components/servo/layout/inline.rs b/src/components/servo/layout/inline.rs index 2bc621625f0..2798361131a 100644 --- a/src/components/servo/layout/inline.rs +++ b/src/components/servo/layout/inline.rs @@ -638,6 +638,14 @@ impl InlineFlowData { elems: ElementMapping::new(), } } + + pub fn teardown(&mut self) { + self.common.teardown(); + for self.boxes.each |box| { + box.teardown(); + } + self.boxes = ~[]; + } } pub trait InlineLayout { diff --git a/src/components/servo/layout/text.rs b/src/components/servo/layout/text.rs index 2bf2d49f0ac..7904c8d084b 100644 --- a/src/components/servo/layout/text.rs +++ b/src/components/servo/layout/text.rs @@ -21,6 +21,10 @@ impl TextBoxData { range: range, } } + + pub fn teardown(&self) { + self.run.teardown(); + } } pub fn adapt_textbox_with_range(mut base: RenderBoxBase, run: @TextRun, range: Range)