remove @ fontcontext

This commit is contained in:
patrick kim 2013-12-06 14:29:42 +09:00
parent 964b5e9d9a
commit 1b8f9c09d3
6 changed files with 79 additions and 99 deletions

View file

@ -144,20 +144,24 @@ impl<E> DisplayItem<E> {
// FIXME(pcwalton): Allocating? Why?
let font = render_context.font_ctx.get_font_by_descriptor(&text.text_run.font_descriptor).unwrap();
let font_metrics = font.with_borrow( |font| {
font.metrics.clone()
});
let origin = text.base.bounds.origin;
let baseline_origin = Point2D(origin.x, origin.y + font.metrics.ascent);
font.draw_text_into_context(render_context,
&text.text_run,
&text.range,
baseline_origin,
text.color);
let baseline_origin = Point2D(origin.x, origin.y +
font.with_borrow( |font| {font.metrics.ascent} ));
font.with_mut_borrow( |font| {
font.draw_text_into_context(render_context,
&text.text_run,
&text.range,
baseline_origin,
text.color);
});
let width = text.base.bounds.size.width;
let underline_size = font.metrics.underline_size;
let underline_offset = font.metrics.underline_offset;
let strikeout_size = font.metrics.strikeout_size;
let strikeout_offset = font.metrics.strikeout_offset;
let underline_size = font_metrics.underline_size;
let underline_offset = font_metrics.underline_offset;
let strikeout_size = font_metrics.strikeout_size;
let strikeout_offset = font_metrics.strikeout_offset;
if text.text_run.decoration.underline {
let underline_y = baseline_origin.y - underline_offset;

View file

@ -11,6 +11,7 @@ use std::cast;
use std::ptr;
use std::str;
use std::vec;
use std::rc::RcMut;
use servo_util::cache::{Cache, HashCache};
use servo_util::range::Range;
use servo_util::time::ProfilerChan;
@ -172,15 +173,15 @@ pub enum FontSelector {
// The ordering of font instances is mainly decided by the CSS
// 'font-family' property. The last font is a system fallback font.
pub struct FontGroup {
families: @str,
families: ~str,
// style of the first western font in group, which is
// used for purposes of calculating text run metrics.
style: UsedFontStyle,
fonts: ~[@mut Font],
fonts: ~[RcMut<Font>]
}
impl FontGroup {
pub fn new(families: @str, style: &UsedFontStyle, fonts: ~[@mut Font]) -> FontGroup {
pub fn new(families: ~str, style: &UsedFontStyle, fonts: ~[RcMut<Font>]) -> FontGroup {
FontGroup {
families: families,
style: (*style).clone(),
@ -194,9 +195,12 @@ impl FontGroup {
pub fn create_textrun(&self, text: ~str, decoration: text_decoration::T) -> TextRun {
assert!(self.fonts.len() > 0);
// TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable.
return TextRun::new(self.fonts[0], text, decoration);
let lr = self.fonts[0].with_mut_borrow(|font| {
TextRun::new(font, text.clone(), decoration)
});
lr
}
}
@ -250,7 +254,7 @@ impl<'self> Font {
style: &SpecifiedFontStyle,
backend: BackendType,
profiler_chan: ProfilerChan)
-> Result<@mut Font, ()> {
-> Result<RcMut<Font>, ()> {
let handle = FontHandleMethods::new_from_buffer(&ctx.handle, buffer, style);
let handle: FontHandle = if handle.is_ok() {
handle.unwrap()
@ -261,7 +265,7 @@ impl<'self> Font {
let metrics = handle.get_metrics();
// TODO(Issue #179): convert between specified and used font style here?
return Ok(@mut Font {
return Ok(RcMut::new(Font {
handle: handle,
azure_font: None,
shaper: None,
@ -271,15 +275,15 @@ impl<'self> Font {
profiler_chan: profiler_chan,
shape_cache: HashCache::new(),
glyph_advance_cache: HashCache::new(),
});
}));
}
pub fn new_from_adopted_handle(_fctx: &FontContext, handle: FontHandle,
style: &SpecifiedFontStyle, backend: BackendType,
profiler_chan: ProfilerChan) -> @mut Font {
profiler_chan: ProfilerChan) -> Font {
let metrics = handle.get_metrics();
@mut Font {
Font {
handle: handle,
azure_font: None,
shaper: None,
@ -294,7 +298,7 @@ impl<'self> Font {
pub fn new_from_existing_handle(fctx: &FontContext, handle: &FontHandle,
style: &SpecifiedFontStyle, backend: BackendType,
profiler_chan: ProfilerChan) -> Result<@mut Font,()> {
profiler_chan: ProfilerChan) -> Result<RcMut<Font>,()> {
// TODO(Issue #179): convert between specified and used font style here?
let styled_handle = match handle.clone_with_style(&fctx.handle, style) {
@ -302,7 +306,7 @@ impl<'self> Font {
Err(()) => return Err(())
};
return Ok(Font::new_from_adopted_handle(fctx, styled_handle, style, backend, profiler_chan));
return Ok(RcMut::new(Font::new_from_adopted_handle(fctx, styled_handle, style, backend, profiler_chan)));
}
fn make_shaper(&'self mut self) -> &'self Shaper {

View file

@ -15,6 +15,8 @@ use platform::font_context::FontContextHandle;
use azure::azure_hl::BackendType;
use std::hashmap::HashMap;
use std::rc::RcMut;
// TODO(Rust #3934): creating lots of new dummy styles is a workaround
// for not being able to store symbolic enums in top-level constants.
pub fn dummy_style() -> FontStyle {
@ -34,9 +36,9 @@ pub trait FontContextHandleMethods {
}
pub struct FontContext {
instance_cache: LRUCache<FontDescriptor, @mut Font>,
instance_cache: LRUCache<FontDescriptor, RcMut<Font>>,
font_list: Option<FontList>, // only needed by layout
group_cache: LRUCache<SpecifiedFontStyle, @FontGroup>,
group_cache: LRUCache<SpecifiedFontStyle, RcMut<FontGroup>>,
handle: FontContextHandle,
backend: BackendType,
generic_fonts: HashMap<~str,~str>,
@ -76,7 +78,7 @@ impl<'self> FontContext {
self.font_list.get_ref()
}
pub fn get_resolved_font_for_style(&mut self, style: &SpecifiedFontStyle) -> @FontGroup {
pub fn get_resolved_font_for_style(&mut self, style: &SpecifiedFontStyle) -> RcMut<FontGroup> {
match self.group_cache.find(style) {
Some(fg) => {
debug!("font group cache hit");
@ -85,13 +87,13 @@ impl<'self> FontContext {
None => {
debug!("font group cache miss");
let fg = self.create_font_group(style);
self.group_cache.insert(style.clone(), fg);
self.group_cache.insert(style.clone(), fg.clone());
fg
}
}
}
pub fn get_font_by_descriptor(&mut self, desc: &FontDescriptor) -> Result<@mut Font, ()> {
pub fn get_font_by_descriptor(&mut self, desc: &FontDescriptor) -> Result<RcMut<Font>, ()> {
match self.instance_cache.find(desc) {
Some(f) => {
debug!("font cache hit");
@ -100,9 +102,9 @@ impl<'self> FontContext {
None => {
debug!("font cache miss");
let result = self.create_font_instance(desc);
match result {
match result.clone() {
Ok(font) => {
self.instance_cache.insert(desc.clone(), font);
self.instance_cache.insert(desc.clone(), font.clone());
}, _ => {}
};
result
@ -120,7 +122,7 @@ impl<'self> FontContext {
}
}
fn create_font_group(&mut self, style: &SpecifiedFontStyle) -> @FontGroup {
fn create_font_group(&mut self, style: &SpecifiedFontStyle) -> RcMut<FontGroup> {
let mut fonts = ~[];
debug!("(create font group) --- starting ---");
@ -152,7 +154,7 @@ impl<'self> FontContext {
found = true;
let instance = self.get_font_by_descriptor(&result.unwrap());
for font in instance.iter() { fonts.push(*font); }
for font in instance.iter() { fonts.push(font.clone()); }
}
@ -169,14 +171,30 @@ impl<'self> FontContext {
None => None,
};
for font_entry in result.iter() {
let font_id =
SelectorPlatformIdentifier(font_entry.handle.face_identifier());
let font_desc = FontDescriptor::new((*style).clone(), font_id);
let instance = self.get_font_by_descriptor(&font_desc);
for family in last_resort.iter() {
if self.font_list.is_some() {
let font_desc = {
let font_list = self.font_list.get_mut_ref();
let font_entry = font_list.find_font_in_family(family, style);
match font_entry {
Some(v) => {
let font_id =
SelectorPlatformIdentifier(v.handle.face_identifier());
Some(FontDescriptor::new((*style).clone(), font_id))
}, None => {
None
}
}
};
for font in instance.iter() {
fonts.push(*font);
match font_desc {
Some(ref fd) => {
let instance = self.get_font_by_descriptor(fd);
for font in instance.iter() {
fonts.push(font.clone());
}
}, None => {
}
}
}
@ -188,21 +206,21 @@ impl<'self> FontContext {
debug!("(create font group) --- finished ---");
FontGroup::new(style.families.to_owned(), &used_style, fonts)
unsafe { RcMut::new_unchecked(FontGroup::new(style.families.to_owned(), &used_style, fonts)) }
}
fn create_font_instance(&self, desc: &FontDescriptor) -> Result<@mut Font, ()> {
fn create_font_instance(&self, desc: &FontDescriptor) -> Result<RcMut<Font>, ()> {
return match &desc.selector {
// TODO(Issue #174): implement by-platform-name font selectors.
&SelectorPlatformIdentifier(ref identifier) => {
let result_handle = self.handle.create_font_from_identifier((*identifier).clone(),
desc.style.clone());
do result_handle.and_then |handle| {
Ok(Font::new_from_adopted_handle(self,
Ok(RcMut::new(Font::new_from_adopted_handle(self,
handle,
&desc.style,
self.backend,
self.profiler_chan.clone()))
self.profiler_chan.clone())))
}
}
};

View file

@ -75,23 +75,7 @@ impl<'self> FontList {
None
}
}
/*
fn find_family(&'self mut self, family_name: &~str) -> Option<&'self mut FontFamily> {
// TODO(Issue #188): look up localized font family names if canonical name not found
// look up canonical name
if self.family_map.contains_key(family_name) {
//FIXME call twice!(ksh8281)
debug!("FontList: {:s} font family with name={:s}", "Found", family_name.to_str());
let s: &'self mut FontFamily = self.family_map.get_mut(family_name);
Some(s)
}
else {
debug!("FontList: {:s} font family with name={:s}", "Couldn't find", family_name.to_str());
None
}
}
*/
pub fn get_last_resort_font_families() -> ~[~str] {
let last_resort = FontListHandle::get_last_resort_font_families();
last_resort

View file

@ -4,7 +4,6 @@
use std::vec::VecIterator;
use font_context::FontContext;
use servo_util::geometry::Au;
use text::glyph::GlyphStore;
use font::{Font, FontDescriptor, RunMetrics, FontStyle, FontMetrics};
@ -23,31 +22,6 @@ pub struct TextRun {
glyphs: Arc<~[Arc<GlyphStore>]>,
}
/// The same as a text run, but with a font descriptor instead of a font. This makes them thread
/// safe.
/*pub struct SendableTextRun {
text: Arc<~str>,
font: FontDescriptor,
decoration: text_decoration::T,
priv glyphs: Arc<~[Arc<GlyphStore>]>,
}
impl SendableTextRun {
pub fn deserialize(&self, fctx: @mut FontContext) -> TextRun {
let font = match fctx.get_font_by_descriptor(&self.font) {
Ok(f) => f,
Err(_) => fail!("Font descriptor deserialization failed! desc={:?}", self.font)
};
TextRun {
text: self.text.clone(),
font: font,
decoration: self.decoration,
glyphs: self.glyphs.clone(),
}
}
}
*/
pub struct SliceIterator<'self> {
priv glyph_iter: VecIterator<'self, Arc<GlyphStore>>,
priv range: Range,
@ -194,16 +168,7 @@ impl<'self> TextRun {
glyphs
}
/*
pub fn serialize(&self) -> SendableTextRun {
SendableTextRun {
text: self.text.clone(),
font: self.font.get_descriptor(),
decoration: self.decoration,
glyphs: self.glyphs.clone(),
}
}
*/
pub fn char_len(&self) -> uint {
do self.glyphs.get().iter().fold(0u) |len, slice_glyphs| {
len + slice_glyphs.get().char_len()
@ -243,7 +208,7 @@ impl<'self> TextRun {
pub fn min_width_for_range(&self, range: &Range) -> Au {
let mut max_piece_width = Au(0);
debug!("iterating outer range {:?}", range);
for (glyphs, offset, slice_range) in self.iter_slices_for_range(range) {
for (_, offset, slice_range) in self.iter_slices_for_range(range) {
debug!("iterated on {:?}[{:?}]", offset, slice_range);
let metrics = self.metrics_for_range(&slice_range);
max_piece_width = Au::max(max_piece_width, metrics.advance_width);