aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/components/gfx/display_list.rs28
-rw-r--r--src/components/gfx/font.rs28
-rw-r--r--src/components/gfx/font_context.rs58
-rw-r--r--src/components/gfx/font_list.rs16
-rw-r--r--src/components/gfx/text/text_run.rs39
-rw-r--r--src/components/main/layout/text.rs9
6 files changed, 79 insertions, 99 deletions
diff --git a/src/components/gfx/display_list.rs b/src/components/gfx/display_list.rs
index 2ff86d8d605..1816bfd279d 100644
--- a/src/components/gfx/display_list.rs
+++ b/src/components/gfx/display_list.rs
@@ -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;
diff --git a/src/components/gfx/font.rs b/src/components/gfx/font.rs
index bdcf089c4f9..6d1a4630f38 100644
--- a/src/components/gfx/font.rs
+++ b/src/components/gfx/font.rs
@@ -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 {
diff --git a/src/components/gfx/font_context.rs b/src/components/gfx/font_context.rs
index 61666f6efb4..c8191a93a57 100644
--- a/src/components/gfx/font_context.rs
+++ b/src/components/gfx/font_context.rs
@@ -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
+ }
+ }
+ };
+
+ match font_desc {
+ Some(ref fd) => {
+ let instance = self.get_font_by_descriptor(fd);
- for font in instance.iter() {
- fonts.push(*font);
+ 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())))
}
}
};
diff --git a/src/components/gfx/font_list.rs b/src/components/gfx/font_list.rs
index dc24f689332..c4db0475d73 100644
--- a/src/components/gfx/font_list.rs
+++ b/src/components/gfx/font_list.rs
@@ -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
diff --git a/src/components/gfx/text/text_run.rs b/src/components/gfx/text/text_run.rs
index e64cbb7a56e..2e5a06e5079 100644
--- a/src/components/gfx/text/text_run.rs
+++ b/src/components/gfx/text/text_run.rs
@@ -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);
diff --git a/src/components/main/layout/text.rs b/src/components/main/layout/text.rs
index 00459f42b7f..7cb692baec4 100644
--- a/src/components/main/layout/text.rs
+++ b/src/components/main/layout/text.rs
@@ -125,7 +125,7 @@ impl TextRunScanner {
// font group fonts. This is probably achieved by creating the font group above
// and then letting `FontGroup` decide which `Font` to stick into the text run.
let fontgroup = ctx.font_ctx.get_resolved_font_for_style(&font_style);
- let run = @fontgroup.create_textrun(transformed_text, decoration);
+ let run = @fontgroup.with_borrow(|fg| fg.create_textrun(transformed_text.clone(), decoration));
debug!("TextRunScanner: pushing single text box in range: {} ({})",
self.clump,
@@ -188,7 +188,12 @@ impl TextRunScanner {
// sequence. If no clump takes ownership, however, it will leak.
let clump = self.clump;
let run = if clump.length() != 0 && run_str.len() > 0 {
- Some(@TextRun::new(fontgroup.fonts[0], run_str, decoration))
+ let font = {
+ fontgroup.with_borrow( |fg| fg.fonts[0].clone())
+ };
+ font.with_mut_borrow( |font| {
+ Some(@TextRun::new(font, run_str.clone(), decoration))
+ })
} else {
None
};