auto merge of #3794 : glennw/servo/font-content-opt, r=pcwalton

This commit is contained in:
bors-servo 2014-10-23 21:09:29 -06:00
commit 3910bc942f
6 changed files with 36 additions and 13 deletions

View file

@ -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<Rc<RefCell<Font>>>,
pub fonts: SmallVec8<Rc<RefCell<Font>>>,
}
impl FontGroup {
pub fn new(fonts: SmallVec1<Rc<RefCell<Font>>>) -> FontGroup {
pub fn new(fonts: SmallVec8<Rc<RefCell<Font>>>) -> FontGroup {
FontGroup {
fonts: fonts,
}

View file

@ -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<RenderFontCacheEntry>,
last_style: Option<Arc<SpecifiedFontStyle>>,
last_fontgroup: Option<Rc<FontGroup>>,
}
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<SpecifiedFontStyle>)
-> Rc<FontGroup> {
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<Rc<RefCell<Font>>> = 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

View file

@ -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,

View file

@ -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,

View file

@ -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<FontStyle>)
-> FontMetrics {
let fontgroup = font_context.get_layout_font_group_for_style(font_style);
fontgroup.fonts.get(0).borrow().metrics.clone()

View file

@ -1809,6 +1809,11 @@ impl ComputedValues {
))
}
#[inline]
pub fn get_font_arc(&self) -> Arc<style_structs::Font> {
self.font.clone()
}
% for style_struct in STYLE_STRUCTS:
#[inline]
pub fn get_${style_struct.name.lower()}