auto merge of #978 : ryanhc/servo/renderbox-cache, r=metajack

This commit is contained in:
bors-servo 2013-09-25 20:06:42 -07:00
commit a3bad43e8a
2 changed files with 92 additions and 38 deletions

View file

@ -114,6 +114,11 @@ impl TextRenderBox {
pub struct UnscannedTextRenderBox { pub struct UnscannedTextRenderBox {
base: RenderBoxBase, base: RenderBoxBase,
text: ~str, text: ~str,
// Cache font-style and text-decoration to check whether
// this box can merge with another render box.
font_style: Option<FontStyle>,
text_decoration: Option<CSSTextDecoration>,
} }
impl UnscannedTextRenderBox { impl UnscannedTextRenderBox {
@ -128,6 +133,8 @@ impl UnscannedTextRenderBox {
UnscannedTextRenderBox { UnscannedTextRenderBox {
base: base, base: base,
text: text_node.element.data.to_str(), text: text_node.element.data.to_str(),
font_style: None,
text_decoration: None,
} }
} }
} }
@ -407,7 +414,7 @@ impl RenderBox {
let border_right = base.model.compute_border_width(style.border_right_width(), let border_right = base.model.compute_border_width(style.border_right_width(),
font_size); font_size);
width + margin_left + margin_right + padding_left + padding_right + width + margin_left + margin_right + padding_left + padding_right +
border_left + border_right border_left + border_right
} }
} }
@ -563,7 +570,7 @@ impl RenderBox {
base.model.border.left + base.model.border.left +
base.model.padding.left, base.model.padding.left,
base.position.origin.y); base.position.origin.y);
let size = Size2D(base.position.size.width - self.get_noncontent_width(), let size = Size2D(base.position.size.width - self.get_noncontent_width(),
base.position.size.height); base.position.size.height);
Rect(origin, size) Rect(origin, size)
} }
@ -677,7 +684,7 @@ impl RenderBox {
// //
// FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We // FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We
// should have a real `SERVO_DEBUG` system. // should have a real `SERVO_DEBUG` system.
debug!("%?", { debug!("%?", {
// Compute the text box bounds and draw a border surrounding them. // Compute the text box bounds and draw a border surrounding them.
let debug_border = SideOffsets2D::new_all_same(Au::from_px(1)); let debug_border = SideOffsets2D::new_all_same(Au::from_px(1));
@ -743,7 +750,7 @@ impl RenderBox {
}; };
list.append_item(BorderDisplayItemClass(border_display_item)) list.append_item(BorderDisplayItemClass(border_display_item))
} }
() ()
}); });
@ -824,44 +831,69 @@ impl RenderBox {
/// Converts this node's computed style to a font style used for rendering. /// Converts this node's computed style to a font style used for rendering.
pub fn font_style(&self) -> FontStyle { pub fn font_style(&self) -> FontStyle {
let my_style = self.nearest_ancestor_element().style(); fn get_font_style(element: AbstractNode<LayoutView>) -> FontStyle {
let my_style = element.style();
debug!("(font style) start: %?", self.nearest_ancestor_element().type_id()); debug!("(font style) start: %?", element.type_id());
// FIXME: Too much allocation here. // FIXME: Too much allocation here.
let font_families = do my_style.font_family().map |family| { let font_families = do my_style.font_family().map |family| {
match *family { match *family {
CSSFontFamilyFamilyName(ref family_str) => (*family_str).clone(), CSSFontFamilyFamilyName(ref family_str) => (*family_str).clone(),
CSSFontFamilyGenericFamily(Serif) => ~"serif", CSSFontFamilyGenericFamily(Serif) => ~"serif",
CSSFontFamilyGenericFamily(SansSerif) => ~"sans-serif", CSSFontFamilyGenericFamily(SansSerif) => ~"sans-serif",
CSSFontFamilyGenericFamily(Cursive) => ~"cursive", CSSFontFamilyGenericFamily(Cursive) => ~"cursive",
CSSFontFamilyGenericFamily(Fantasy) => ~"fantasy", CSSFontFamilyGenericFamily(Fantasy) => ~"fantasy",
CSSFontFamilyGenericFamily(Monospace) => ~"monospace", CSSFontFamilyGenericFamily(Monospace) => ~"monospace",
}
};
let font_families = font_families.connect(", ");
debug!("(font style) font families: `%s`", font_families);
let font_size = match my_style.font_size() {
CSSFontSizeLength(Px(length)) => length,
// todo: this is based on a hard coded font size, should be the parent element's font size
CSSFontSizeLength(Em(length)) => length * 16f,
_ => 16f // px units
};
debug!("(font style) font size: `%fpx`", font_size);
let (italic, oblique) = match my_style.font_style() {
CSSFontStyleNormal => (false, false),
CSSFontStyleItalic => (true, false),
CSSFontStyleOblique => (false, true),
};
FontStyle {
pt_size: font_size,
weight: FontWeight300,
italic: italic,
oblique: oblique,
families: font_families,
} }
}; }
let font_families = font_families.connect(", ");
debug!("(font style) font families: `%s`", font_families);
let font_size = match my_style.font_size() { let font_style_cached = match *self {
CSSFontSizeLength(Px(length)) => length, UnscannedTextRenderBoxClass(ref box) => {
// todo: this is based on a hard coded font size, should be the parent element's font size match box.font_style {
CSSFontSizeLength(Em(length)) => length * 16f, Some(ref style) => Some(style.clone()),
_ => 16f // px units None => None
}; }
debug!("(font style) font size: `%fpx`", font_size); }
_ => None
let (italic, oblique) = match my_style.font_style() {
CSSFontStyleNormal => (false, false),
CSSFontStyleItalic => (true, false),
CSSFontStyleOblique => (false, true),
}; };
FontStyle { if font_style_cached.is_some() {
pt_size: font_size, return font_style_cached.unwrap();
weight: FontWeight300, } else {
italic: italic, let font_style = get_font_style(self.nearest_ancestor_element());
oblique: oblique, match *self {
families: font_families, UnscannedTextRenderBoxClass(ref box) => {
box.font_style = Some(font_style.clone());
}
_ => ()
}
return font_style;
} }
} }
@ -916,7 +948,29 @@ impl RenderBox {
text_decoration text_decoration
} }
} }
get_propagated_text_decoration(self.nearest_ancestor_element())
let text_decoration_cached = match *self {
UnscannedTextRenderBoxClass(ref box) => {
match box.text_decoration {
Some(ref decoration) => Some(decoration.clone()),
None => None
}
}
_ => None
};
if text_decoration_cached.is_some() {
return text_decoration_cached.unwrap();
} else {
let text_decoration = get_propagated_text_decoration(self.nearest_ancestor_element());
match *self {
UnscannedTextRenderBoxClass(ref box) => {
box.text_decoration = Some(text_decoration.clone());
}
_ => ()
}
return text_decoration;
}
} }
/// Dumps this node, for debugging. /// Dumps this node, for debugging.

@ -1 +1 @@
Subproject commit 33df32548180b55cc96a22d1ff84aafe8e38503b Subproject commit 6d44ce5cc97ccb3bfa9c06833b852921025d9b14