diff --git a/components/gfx/font.rs b/components/gfx/font.rs index 76beb89eb5a..489b2a3ef30 100644 --- a/components/gfx/font.rs +++ b/components/gfx/font.rs @@ -8,7 +8,7 @@ use std::string; use std::rc::Rc; use std::cell::RefCell; use servo_util::cache::{Cache, HashCache}; -use servo_util::smallvec::{SmallVec, SmallVec1}; +use servo_util::smallvec::{SmallVec, SmallVec8}; use style::computed_values::{font_variant, font_weight}; use style::style_structs::Font as FontStyle; use sync::Arc; @@ -165,11 +165,11 @@ impl Font { } pub struct FontGroup { - pub fonts: SmallVec1>>, + pub fonts: SmallVec8>>, } impl FontGroup { - pub fn new(fonts: SmallVec1>>) -> FontGroup { + pub fn new(fonts: SmallVec8>>) -> FontGroup { FontGroup { fonts: fonts, } diff --git a/components/gfx/font_context.rs b/components/gfx/font_context.rs index 5ad81019d3a..3c701e164e4 100644 --- a/components/gfx/font_context.rs +++ b/components/gfx/font_context.rs @@ -13,8 +13,9 @@ use platform::font_template::FontTemplateData; use font::FontHandleMethods; use platform::font::FontHandle; use servo_util::cache::HashCache; -use servo_util::smallvec::{SmallVec, SmallVec1}; +use servo_util::smallvec::{SmallVec, SmallVec8}; use servo_util::geometry::Au; +use servo_util::arc_ptr_eq; use std::rc::Rc; use std::cell::RefCell; @@ -74,6 +75,9 @@ pub struct FontContext { /// Strong reference as the render FontContext is (for now) recycled /// per frame. TODO: Make this weak when incremental redraw is done. render_font_cache: Vec, + + last_style: Option>, + last_fontgroup: Option>, } impl FontContext { @@ -85,6 +89,8 @@ impl FontContext { layout_font_cache: vec!(), fallback_font_cache: vec!(), render_font_cache: vec!(), + last_style: None, + last_fontgroup: None, } } @@ -120,13 +126,22 @@ impl FontContext { /// Create a group of fonts for use in layout calculations. May return /// a cached font if this font instance has already been used by /// this context. - pub fn get_layout_font_group_for_style(&mut self, style: &SpecifiedFontStyle) -> FontGroup { + pub fn get_layout_font_group_for_style(&mut self, style: Arc) + -> Rc { + let matches = match self.last_style { + Some(ref last_style) => arc_ptr_eq(&style, last_style), + None => false, + }; + if matches { + return self.last_fontgroup.as_ref().unwrap().clone(); + } + // TODO: The font context holds a strong ref to the cached fonts // so they will never be released. Find out a good time to drop them. let desc = FontTemplateDescriptor::new(style.font_weight, style.font_style == font_style::italic); - let mut fonts: SmallVec1>> = SmallVec1::new(); + let mut fonts = SmallVec8::new(); for family in style.font_family.iter() { // GWTODO: Check on real pages if this is faster as Vec() or HashMap(). @@ -208,7 +223,10 @@ impl FontContext { } } - FontGroup::new(fonts) + let font_group = Rc::new(FontGroup::new(fonts)); + self.last_style = Some(style); + self.last_fontgroup = Some(font_group.clone()); + font_group } /// Create a render font for use with azure. May return a cached diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 23fd1b41dff..965f2a990c0 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -724,7 +724,7 @@ impl Fragment { } pub fn calculate_line_height(&self, layout_context: &LayoutContext) -> Au { - let font_style = self.style.get_font(); + let font_style = self.style.get_font_arc(); let font_metrics = text::font_metrics_for_style(layout_context.font_context(), font_style); text::line_height_from_style(&*self.style, &font_metrics) } @@ -1394,7 +1394,7 @@ impl Fragment { InlineBlockFragment(ref info) => { // See CSS 2.1 ยง 10.8.1. let block_flow = info.flow_ref.deref().as_immutable_block(); - let font_style = self.style.get_font(); + let font_style = self.style.get_font_arc(); let font_metrics = text::font_metrics_for_style(layout_context.font_context(), font_style); InlineMetrics::from_block_height(&font_metrics, diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 3a186920399..994695a5cc8 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -859,7 +859,7 @@ impl InlineFlow { return (Au(0), Au(0)) } - let font_style = style.get_font(); + let font_style = style.get_font_arc(); let font_metrics = text::font_metrics_for_style(font_context, font_style); let line_height = text::line_height_from_style(style, &font_metrics); let inline_metrics = InlineMetrics::from_font_metrics(&font_metrics, line_height); @@ -873,7 +873,7 @@ impl InlineFlow { match frag.inline_context { Some(ref inline_context) => { for style in inline_context.styles.iter() { - let font_style = style.get_font(); + let font_style = style.get_font_arc(); let font_metrics = text::font_metrics_for_style(font_context, font_style); let line_height = text::line_height_from_style(&**style, &font_metrics); let inline_metrics = InlineMetrics::from_font_metrics(&font_metrics, diff --git a/components/layout/text.rs b/components/layout/text.rs index db0380615df..bcea931fab6 100644 --- a/components/layout/text.rs +++ b/components/layout/text.rs @@ -106,7 +106,7 @@ impl TextRunScanner { let compression; { let in_fragment = self.clump.front().unwrap(); - let font_style = in_fragment.style().get_font(); + let font_style = in_fragment.style().get_font_arc(); fontgroup = font_context.get_layout_font_group_for_style(font_style); compression = match in_fragment.white_space() { white_space::normal | white_space::nowrap => CompressWhitespaceNewline, @@ -209,7 +209,7 @@ fn bounding_box_for_run_metrics(metrics: &RunMetrics, writing_mode: WritingMode) /// /// `#[inline]` because often the caller only needs a few fields from the font metrics. #[inline] -pub fn font_metrics_for_style(font_context: &mut FontContext, font_style: &FontStyle) +pub fn font_metrics_for_style(font_context: &mut FontContext, font_style: Arc) -> FontMetrics { let fontgroup = font_context.get_layout_font_group_for_style(font_style); fontgroup.fonts.get(0).borrow().metrics.clone() diff --git a/components/style/properties/mod.rs.mako b/components/style/properties/mod.rs.mako index e2c2bdcb7f3..f036003f237 100644 --- a/components/style/properties/mod.rs.mako +++ b/components/style/properties/mod.rs.mako @@ -1809,6 +1809,11 @@ impl ComputedValues { )) } + #[inline] + pub fn get_font_arc(&self) -> Arc { + self.font.clone() + } + % for style_struct in STYLE_STRUCTS: #[inline] pub fn get_${style_struct.name.lower()}