From c60ab361a5a74b91c6a236674df2a1f82d9aa2ea Mon Sep 17 00:00:00 2001 From: patrick kim Date: Tue, 3 Dec 2013 20:02:22 +0900 Subject: [PATCH 1/5] remove @ from FontContextHandle in linux --- src/components/gfx/platform/linux/font.rs | 7 ++- .../gfx/platform/linux/font_context.rs | 58 +++++++++++++------ 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/components/gfx/platform/linux/font.rs b/src/components/gfx/platform/linux/font.rs index 29e81ddaaee..04b288ee8c9 100644 --- a/src/components/gfx/platform/linux/font.rs +++ b/src/components/gfx/platform/linux/font.rs @@ -8,6 +8,7 @@ use font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTableMethods}; use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle, FontWeight100}; use font::{FontWeight200, FontWeight300, FontWeight400, FontWeight500, FontWeight600}; use font::{FontWeight700, FontWeight800, FontWeight900}; +use font_context::FontContextHandleMethods; use servo_util::geometry::Au; use servo_util::geometry; use platform::font_context::FontContextHandle; @@ -93,7 +94,7 @@ impl FontHandleMethods for FontHandle { let handle = FontHandle { face: face, source: FontSourceMem(buf), - handle: *fctx + handle: fctx.clone() }; Ok(handle) } @@ -295,7 +296,7 @@ impl<'self> FontHandle { Ok(FontHandle { source: FontSourceFile(file.to_str()), face: face, - handle: *fctx + handle: fctx.clone() }) } else { Err(()) @@ -323,7 +324,7 @@ impl<'self> FontHandle { Ok(FontHandle { source: FontSourceFile(file), face: face, - handle: *fctx + handle: fctx.clone() }) } } diff --git a/src/components/gfx/platform/linux/font_context.rs b/src/components/gfx/platform/linux/font_context.rs index 313082309d5..eee240cfc78 100644 --- a/src/components/gfx/platform/linux/font_context.rs +++ b/src/components/gfx/platform/linux/font_context.rs @@ -12,34 +12,53 @@ use freetype::freetype::{FT_Done_FreeType, FT_Init_FreeType}; use std::ptr; +#[deriving(Clone)] struct FreeTypeLibraryHandle { ctx: FT_Library, } -impl Drop for FreeTypeLibraryHandle { - #[fixed_stack_segment] - fn drop(&mut self) { - assert!(self.ctx.is_not_null()); - unsafe { - FT_Done_FreeType(self.ctx); - } - } +// FIXME(ksh8281) this value have to use atomic operation for counting ref +static mut font_context_ref_count: uint = 0; +static mut ft_pointer: Option = None; +pub struct FontContextHandle { + ctx: FreeTypeLibraryHandle, } -pub struct FontContextHandle { - ctx: @FreeTypeLibraryHandle, +impl Drop for FontContextHandle { + #[fixed_stack_segment] + fn drop(&mut self) { + assert!(self.ctx.ctx.is_not_null()); + unsafe { + assert!(font_context_ref_count >= 1); + font_context_ref_count = font_context_ref_count - 1; + if font_context_ref_count == 0 { + FT_Done_FreeType(self.ctx.ctx); + } + } + } } impl FontContextHandle { #[fixed_stack_segment] pub fn new() -> FontContextHandle { unsafe { - let ctx: FT_Library = ptr::null(); - let result = FT_Init_FreeType(ptr::to_unsafe_ptr(&ctx)); - if !result.succeeded() { fail!(); } - - FontContextHandle { - ctx: @FreeTypeLibraryHandle { ctx: ctx }, + match ft_pointer { + Some(ref ctx) => { + font_context_ref_count = font_context_ref_count + 1; + FontContextHandle { + ctx: FreeTypeLibraryHandle { ctx: ctx.clone() }, + } + }, + None => { + let ctx: FT_Library = ptr::null(); + let result = FT_Init_FreeType(ptr::to_unsafe_ptr(&ctx)); + if !result.succeeded() { fail!(); } + ft_pointer = Some(ctx); + font_context_ref_count = font_context_ref_count + 1; + FontContextHandle { + ctx: FreeTypeLibraryHandle { ctx: ctx }, + } + } } } } @@ -47,7 +66,12 @@ impl FontContextHandle { impl FontContextHandleMethods for FontContextHandle { fn clone(&self) -> FontContextHandle { - FontContextHandle { ctx: self.ctx } + unsafe { + font_context_ref_count = font_context_ref_count + 1; + FontContextHandle{ + ctx: self.ctx.clone() + } + } } fn create_font_from_identifier(&self, name: ~str, style: UsedFontStyle) From 964b5e9d9a94739f14095507250e6878cf02084d Mon Sep 17 00:00:00 2001 From: patrick kim Date: Thu, 5 Dec 2013 21:14:58 +0900 Subject: [PATCH 2/5] remove SendableTextRun & remove @mut Font From TextRun&Shaper(Font),Font.shaper, fontfamily,fontgroup,render_context.font_ctx --- src/components/gfx/display_list.rs | 19 ++-- src/components/gfx/font.rs | 29 +++--- src/components/gfx/font_context.rs | 31 ++++--- src/components/gfx/font_list.rs | 91 ++++++++++--------- .../gfx/platform/linux/font_list.rs | 6 +- src/components/gfx/render_context.rs | 2 +- src/components/gfx/render_task.rs | 10 +- src/components/gfx/text/mod.rs | 1 - src/components/gfx/text/shaper.rs | 2 +- src/components/gfx/text/shaping/harfbuzz.rs | 9 +- src/components/gfx/text/text_run.rs | 43 ++++++--- src/components/main/layout/box.rs | 14 ++- src/components/main/layout/inline.rs | 2 +- 13 files changed, 146 insertions(+), 113 deletions(-) diff --git a/src/components/gfx/display_list.rs b/src/components/gfx/display_list.rs index 46b7525100a..2ff86d8d605 100644 --- a/src/components/gfx/display_list.rs +++ b/src/components/gfx/display_list.rs @@ -18,7 +18,7 @@ use color::Color; use servo_util::geometry::Au; use style::computed_values::border_style; use render_context::RenderContext; -use text::SendableTextRun; +use text::TextRun; use std::cast::transmute_region; use geom::{Point2D, Rect, Size2D, SideOffsets2D}; @@ -47,7 +47,7 @@ impl DisplayList { } /// Draws the display list into the given render context. - pub fn draw_into_context(&self, render_context: &RenderContext) { + pub fn draw_into_context(&self, render_context: &mut RenderContext) { debug!("Beginning display list."); for item in self.list.iter() { // FIXME(Issue #150): crashes @@ -87,7 +87,7 @@ pub struct SolidColorDisplayItem { /// Renders text. pub struct TextDisplayItem { base: BaseDisplayItem, - text_run: ~SendableTextRun, + text_run: ~TextRun, range: Range, color: Color, } @@ -120,7 +120,7 @@ pub struct ClipDisplayItem { impl DisplayItem { /// Renders this display item into the given render context. - fn draw_into_context(&self, render_context: &RenderContext) { + fn draw_into_context(&self, render_context: &mut RenderContext) { match *self { SolidColorDisplayItemClass(ref solid_color) => { render_context.draw_solid_color(&solid_color.base.bounds, solid_color.color) @@ -142,14 +142,13 @@ impl DisplayItem { debug!("Drawing text at {:?}.", text.base.bounds); // FIXME(pcwalton): Allocating? Why? - let new_run = @text.text_run.deserialize(render_context.font_ctx); + let font = render_context.font_ctx.get_font_by_descriptor(&text.text_run.font_descriptor).unwrap(); - let font = new_run.font; let origin = text.base.bounds.origin; let baseline_origin = Point2D(origin.x, origin.y + font.metrics.ascent); font.draw_text_into_context(render_context, - new_run, + &text.text_run, &text.range, baseline_origin, text.color); @@ -160,18 +159,18 @@ impl DisplayItem { let strikeout_size = font.metrics.strikeout_size; let strikeout_offset = font.metrics.strikeout_offset; - if new_run.decoration.underline { + if text.text_run.decoration.underline { let underline_y = baseline_origin.y - underline_offset; let underline_bounds = Rect(Point2D(baseline_origin.x, underline_y), Size2D(width, underline_size)); render_context.draw_solid_color(&underline_bounds, text.color); } - if new_run.decoration.overline { + if text.text_run.decoration.overline { let overline_bounds = Rect(Point2D(baseline_origin.x, origin.y), Size2D(width, underline_size)); render_context.draw_solid_color(&overline_bounds, text.color); } - if new_run.decoration.line_through { + if text.text_run.decoration.line_through { let strikeout_y = baseline_origin.y - strikeout_offset; let strikeout_bounds = Rect(Point2D(baseline_origin.x, strikeout_y), Size2D(width, strikeout_size)); diff --git a/src/components/gfx/font.rs b/src/components/gfx/font.rs index 589d9dd363d..bdcf089c4f9 100644 --- a/src/components/gfx/font.rs +++ b/src/components/gfx/font.rs @@ -75,6 +75,7 @@ pub trait FontTableMethods { fn with_buffer(&self, &fn(*u8, uint)); } +#[deriving(Clone)] pub struct FontMetrics { underline_size: Au, underline_offset: Au, @@ -234,7 +235,7 @@ and the renderer can use it to render text. pub struct Font { priv handle: FontHandle, priv azure_font: Option, - priv shaper: Option<@Shaper>, + priv shaper: Option, style: UsedFontStyle, metrics: FontMetrics, backend: BackendType, @@ -243,7 +244,7 @@ pub struct Font { glyph_advance_cache: HashCache, } -impl Font { +impl<'self> Font { pub fn new_from_buffer(ctx: &FontContext, buffer: ~[u8], style: &SpecifiedFontStyle, @@ -256,7 +257,7 @@ impl Font { } else { return Err(handle.unwrap_err()); }; - + let metrics = handle.get_metrics(); // TODO(Issue #179): convert between specified and used font style here? @@ -304,16 +305,20 @@ impl Font { return Ok(Font::new_from_adopted_handle(fctx, styled_handle, style, backend, profiler_chan)); } - fn get_shaper(@mut self) -> @Shaper { + fn make_shaper(&'self mut self) -> &'self Shaper { // fast path: already created a shaper match self.shaper { - Some(shaper) => { return shaper; }, + Some(ref shaper) => { + let s: &'self Shaper = shaper; + return s; + }, None => {} } - let shaper = @Shaper::new(self); + let shaper = Shaper::new(self); self.shaper = Some(shaper); - shaper + let s:&'self Shaper = self.shaper.get_ref(); + s } pub fn get_table_for_tag(&self, tag: FontTableTag) -> Option { @@ -369,7 +374,7 @@ impl Font { #[fixed_stack_segment] pub fn draw_text_into_context(&mut self, rctx: &RenderContext, - run: &TextRun, + run: &~TextRun, range: &Range, baseline_origin: Point2D, color: Color) { @@ -454,11 +459,13 @@ impl Font { RunMetrics::new(advance, self.metrics.ascent, self.metrics.descent) } - pub fn shape_text(@mut self, text: ~str, is_whitespace: bool) -> Arc { - let shaper = self.get_shaper(); + pub fn shape_text(&mut self, text: ~str, is_whitespace: bool) -> Arc { + + //FIXME (ksh8281) + self.make_shaper(); do self.shape_cache.find_or_create(&text) |txt| { let mut glyphs = GlyphStore::new(text.char_len(), is_whitespace); - shaper.shape_text(*txt, &mut glyphs); + self.shaper.get_ref().shape_text(*txt, &mut glyphs); Arc::new(glyphs) } } diff --git a/src/components/gfx/font_context.rs b/src/components/gfx/font_context.rs index 5d662a348ed..61666f6efb4 100644 --- a/src/components/gfx/font_context.rs +++ b/src/components/gfx/font_context.rs @@ -130,24 +130,31 @@ impl<'self> FontContext { let family_name = family.trim(); let transformed_family_name = self.transform_family(family_name); debug!("(create font group) transformed family is `{:s}`", transformed_family_name); + let mut found = false; let result = match self.font_list { - Some(ref fl) => fl.find_font_in_family(transformed_family_name, style), + Some(ref mut fl) => { + let font_in_family = fl.find_font_in_family(&transformed_family_name, style); + if font_in_family.is_some() { + let font_entry = font_in_family.unwrap(); + let font_id = + SelectorPlatformIdentifier(font_entry.handle.face_identifier()); + let font_desc = FontDescriptor::new((*style).clone(), font_id); + Some(font_desc) + } else { + None + } + } None => None, }; - let mut found = false; - for font_entry in result.iter() { + if result.is_some() { found = true; - - 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); + let instance = self.get_font_by_descriptor(&result.unwrap()); for font in instance.iter() { fonts.push(*font); } - }; + } + if !found { debug!("(create font group) didn't find `{:s}`", transformed_family_name); @@ -156,7 +163,6 @@ impl<'self> FontContext { if fonts.len() == 0 { let last_resort = FontList::get_last_resort_font_families(); - for family in last_resort.iter() { let result = match self.font_list { Some(ref fl) => fl.find_font_in_family(*family, style), @@ -167,7 +173,6 @@ impl<'self> FontContext { 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 font in instance.iter() { @@ -183,7 +188,7 @@ impl<'self> FontContext { debug!("(create font group) --- finished ---"); - @FontGroup::new(style.families.to_managed(), &used_style, fonts) + FontGroup::new(style.families.to_owned(), &used_style, fonts) } fn create_font_instance(&self, desc: &FontDescriptor) -> Result<@mut Font, ()> { diff --git a/src/components/gfx/font_list.rs b/src/components/gfx/font_list.rs index 4c6c02710ec..dc24f689332 100644 --- a/src/components/gfx/font_list.rs +++ b/src/components/gfx/font_list.rs @@ -13,11 +13,11 @@ use servo_util::time::ProfilerChan; use std::hashmap::HashMap; -pub type FontFamilyMap = HashMap<~str, @mut FontFamily>; +pub type FontFamilyMap = HashMap<~str, FontFamily>; trait FontListHandleMethods { fn get_available_families(&self, fctx: &FontContextHandle) -> FontFamilyMap; - fn load_variations_for_family(&self, family: @mut FontFamily); + fn load_variations_for_family(&self, family: &mut FontFamily); fn get_last_resort_font_families() -> ~[~str]; } @@ -28,7 +28,7 @@ pub struct FontList { prof_chan: ProfilerChan, } -impl FontList { +impl<'self> FontList { pub fn new(fctx: &FontContextHandle, prof_chan: ProfilerChan) -> FontList { @@ -52,41 +52,46 @@ impl FontList { } } - pub fn find_font_in_family(&self, - family_name: &str, - style: &SpecifiedFontStyle) -> Option<@FontEntry> { - let family = self.find_family(family_name); - - // TODO(Issue #192: handle generic font families, like 'serif' and 'sans-serif'. - - // if such family exists, try to match style to a font - let mut result: Option<@FontEntry> = None; - for fam in family.iter() { - result = fam.find_font_for_style(&self.handle, style); - } - - let decision = if result.is_some() { - "Found" - } else { - "Couldn't find" - }; - - debug!("FontList: {:s} font face in family[{:s}] matching style", decision, family_name); - - result - } - - fn find_family(&self, family_name: &str) -> Option<@mut FontFamily> { - // look up canonical name - let family = self.family_map.find_equiv(&family_name); - - let decision = if family.is_some() { "Found" } else { "Couldn't find" }; - debug!("FontList: {:s} font family with name={:s}", decision, family_name); - + pub fn find_font_in_family(&'self mut self, + family_name: &~str, + style: &SpecifiedFontStyle) -> Option<&'self FontEntry> { // TODO(Issue #188): look up localized font family names if canonical name not found - family.map(|f| *f) - } + // 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); + // TODO(Issue #192: handle generic font families, like 'serif' and 'sans-serif'. + // if such family exists, try to match style to a font + let result = s.find_font_for_style(&mut self.handle, style); + if result.is_some() { + return result; + } + None + } + else { + debug!("FontList: {:s} font family with name={:s}", "Couldn't find", family_name.to_str()); + 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 @@ -94,12 +99,12 @@ impl FontList { } // Holds a specific font family, and the various -pub struct FontFamily { +pub struct FontFamily<'self> { family_name: ~str, - entries: ~[@FontEntry], + entries: ~[FontEntry], } -impl FontFamily { +impl<'self> FontFamily { pub fn new(family_name: &str) -> FontFamily { FontFamily { family_name: family_name.to_str(), @@ -107,7 +112,7 @@ impl FontFamily { } } - fn load_family_variations(@mut self, list: &FontListHandle) { + fn load_family_variations(&mut self, list: &FontListHandle) { if self.entries.len() > 0 { return } @@ -115,8 +120,8 @@ impl FontFamily { assert!(self.entries.len() > 0) } - pub fn find_font_for_style(@mut self, list: &FontListHandle, style: &SpecifiedFontStyle) - -> Option<@FontEntry> { + pub fn find_font_for_style(&'self mut self, list: &FontListHandle, style: &SpecifiedFontStyle) + -> Option<&'self FontEntry> { self.load_family_variations(list); // TODO(Issue #189): optimize lookup for @@ -129,7 +134,7 @@ impl FontFamily { if (style.weight.is_bold() == entry.is_bold()) && (style.italic == entry.is_italic()) { - return Some(*entry); + return Some(entry); } } diff --git a/src/components/gfx/platform/linux/font_list.rs b/src/components/gfx/platform/linux/font_list.rs index 4d0c721c272..74fe4449445 100644 --- a/src/components/gfx/platform/linux/font_list.rs +++ b/src/components/gfx/platform/linux/font_list.rs @@ -53,7 +53,7 @@ impl FontListHandle { while FcPatternGetString(*font, FC_FAMILY, v, &family) == FcResultMatch { let family_name = str::raw::from_c_str(family as *c_char); debug!("Creating new FontFamily for family: {:s}", family_name); - let new_family = @mut FontFamily::new(family_name); + let new_family = FontFamily::new(family_name); family_map.insert(family_name, new_family); v += 1; } @@ -64,7 +64,7 @@ impl FontListHandle { } #[fixed_stack_segment] - pub fn load_variations_for_family(&self, family: @mut FontFamily) { + pub fn load_variations_for_family(&self, family: &mut FontFamily) { debug!("getting variations for {:?}", family); unsafe { let config = FcConfigGetCurrent(); @@ -120,7 +120,7 @@ impl FontListHandle { let font_handle = font_handle.unwrap(); debug!("Creating new FontEntry for face: {:s}", font_handle.face_name()); - let entry = @FontEntry::new(font_handle); + let entry = FontEntry::new(font_handle); family.entries.push(entry); } diff --git a/src/components/gfx/render_context.rs b/src/components/gfx/render_context.rs index aecf6938f60..d13d709acce 100755 --- a/src/components/gfx/render_context.rs +++ b/src/components/gfx/render_context.rs @@ -24,7 +24,7 @@ use std::libc::size_t; pub struct RenderContext<'self> { draw_target: &'self DrawTarget, - font_ctx: @mut FontContext, + font_ctx: &'self mut ~FontContext, opts: &'self Opts, /// The rectangle that this context encompasses in page coordinates. page_rect: Rect, diff --git a/src/components/gfx/render_task.rs b/src/components/gfx/render_task.rs index 34ff27cfcb5..e25c1354bba 100644 --- a/src/components/gfx/render_task.rs +++ b/src/components/gfx/render_task.rs @@ -97,7 +97,7 @@ pub struct RenderTask { port: Port>, compositor: C, constellation_chan: ConstellationChan, - font_ctx: @mut FontContext, + font_ctx: ~FontContext, opts: Opts, /// A channel to the profiler. @@ -150,7 +150,7 @@ impl RenderTask { port: port, compositor: compositor, constellation_chan: constellation_chan, - font_ctx: @mut FontContext::new(opts.render_backend.clone(), + font_ctx: ~FontContext::new(opts.render_backend.clone(), false, profiler_chan.clone()), opts: opts, @@ -266,9 +266,9 @@ impl RenderTask { { // Build the render context. - let ctx = RenderContext { + let mut ctx = RenderContext { draw_target: &draw_target, - font_ctx: self.font_ctx, + font_ctx: &mut self.font_ctx, opts: &self.opts, page_rect: tile.page_rect, screen_rect: tile.screen_rect, @@ -287,7 +287,7 @@ impl RenderTask { // Draw the display list. do profile(time::RenderingDrawingCategory, self.profiler_chan.clone()) { - render_layer.display_list.get().draw_into_context(&ctx); + render_layer.display_list.get().draw_into_context(&mut ctx); ctx.draw_target.flush(); } } diff --git a/src/components/gfx/text/mod.rs b/src/components/gfx/text/mod.rs index edadaae760d..13a07fa9dba 100644 --- a/src/components/gfx/text/mod.rs +++ b/src/components/gfx/text/mod.rs @@ -9,7 +9,6 @@ Note that you still must define each of the files as a module in servo.rc. This is not ideal and may be changed in the future. */ pub use text::shaping::Shaper; -pub use text::text_run::SendableTextRun; pub use text::text_run::TextRun; pub mod glyph; diff --git a/src/components/gfx/text/shaper.rs b/src/components/gfx/text/shaper.rs index 217d2496a9e..a79eab945c1 100644 --- a/src/components/gfx/text/shaper.rs +++ b/src/components/gfx/text/shaper.rs @@ -21,7 +21,7 @@ pub trait ShaperMethods { // TODO(Issue #163): this is a workaround for static methods and // typedefs not working well together. It should be removed. pub impl Shaper { - pub fn new(font: @mut Font) -> Shaper { + pub fn new(font: &mut Font) -> Shaper { harfbuzz::shaper::HarfbuzzShaper::new(font) } } diff --git a/src/components/gfx/text/shaping/harfbuzz.rs b/src/components/gfx/text/shaping/harfbuzz.rs index 7ed2fb93f47..d8dc5fd14ae 100644 --- a/src/components/gfx/text/shaping/harfbuzz.rs +++ b/src/components/gfx/text/shaping/harfbuzz.rs @@ -136,7 +136,6 @@ impl ShapedGlyphData { } pub struct Shaper { - font: @mut Font, priv hb_face: *hb_face_t, priv hb_font: *hb_font_t, priv hb_funcs: *hb_font_funcs_t, @@ -161,13 +160,10 @@ impl Drop for Shaper { impl Shaper { #[fixed_stack_segment] - pub fn new(font: @mut Font) -> Shaper { + pub fn new(font: &mut Font) -> Shaper { unsafe { // Indirection for Rust Issue #6248, dynamic freeze scope artifically extended - let font_ptr = { - let borrowed_font= &mut *font; - borrowed_font as *mut Font - }; + let font_ptr = font as *mut Font; let hb_face: *hb_face_t = hb_face_create_for_tables(get_font_table_func, font_ptr as *c_void, None); @@ -190,7 +186,6 @@ impl Shaper { hb_font_set_funcs(hb_font, hb_funcs, font_ptr as *c_void, None); Shaper { - font: font, hb_face: hb_face, hb_font: hb_font, hb_funcs: hb_funcs, diff --git a/src/components/gfx/text/text_run.rs b/src/components/gfx/text/text_run.rs index e7193b7ee57..e64cbb7a56e 100644 --- a/src/components/gfx/text/text_run.rs +++ b/src/components/gfx/text/text_run.rs @@ -7,22 +7,25 @@ use std::vec::VecIterator; use font_context::FontContext; use servo_util::geometry::Au; use text::glyph::GlyphStore; -use font::{Font, FontDescriptor, RunMetrics}; +use font::{Font, FontDescriptor, RunMetrics, FontStyle, FontMetrics}; use servo_util::range::Range; use extra::arc::Arc; use style::computed_values::text_decoration; /// A text run. +#[deriving(Clone)] pub struct TextRun { text: Arc<~str>, - font: @mut Font, + font_descriptor: FontDescriptor, + font_metrics: FontMetrics, + font_style: FontStyle, decoration: text_decoration::T, glyphs: Arc<~[Arc]>, } /// The same as a text run, but with a font descriptor instead of a font. This makes them thread /// safe. -pub struct SendableTextRun { +/*pub struct SendableTextRun { text: Arc<~str>, font: FontDescriptor, decoration: text_decoration::T, @@ -44,7 +47,7 @@ impl SendableTextRun { } } } - +*/ pub struct SliceIterator<'self> { priv glyph_iter: VecIterator<'self, Arc>, priv range: Range, @@ -120,12 +123,14 @@ impl<'self> Iterator for LineIterator<'self> { } impl<'self> TextRun { - pub fn new(font: @mut Font, text: ~str, decoration: text_decoration::T) -> TextRun { + pub fn new(font: &mut Font, text: ~str, decoration: text_decoration::T) -> TextRun { let glyphs = TextRun::break_and_shape(font, text); let run = TextRun { text: Arc::new(text), - font: font, + font_style: font.style.clone(), + font_metrics: font.metrics.clone(), + font_descriptor: font.get_descriptor(), decoration: decoration, glyphs: Arc::new(glyphs), }; @@ -133,10 +138,9 @@ impl<'self> TextRun { } pub fn teardown(&self) { - self.font.teardown(); } - pub fn break_and_shape(font: @mut Font, text: &str) -> ~[Arc] { + pub fn break_and_shape(font: &mut Font, text: &str) -> ~[Arc] { // TODO(Issue #230): do a better job. See Gecko's LineBreaker. let mut glyphs = ~[]; @@ -190,7 +194,7 @@ impl<'self> TextRun { glyphs } - +/* pub fn serialize(&self) -> SendableTextRun { SendableTextRun { text: self.text.clone(), @@ -199,7 +203,7 @@ impl<'self> TextRun { 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() @@ -218,19 +222,30 @@ impl<'self> TextRun { } pub fn metrics_for_range(&self, range: &Range) -> RunMetrics { - self.font.measure_text(self, range) + // TODO(Issue #199): alter advance direction for RTL + // TODO(Issue #98): using inter-char and inter-word spacing settings when measuring text + let mut advance = Au(0); + for (glyphs, _offset, slice_range) in self.iter_slices_for_range(range) { + for (_i, glyph) in glyphs.iter_glyphs_for_char_range(&slice_range) { + advance = advance + glyph.advance(); + } + } + RunMetrics::new(advance, self.font_metrics.ascent, self.font_metrics.descent) } pub fn metrics_for_slice(&self, glyphs: &GlyphStore, slice_range: &Range) -> RunMetrics { - self.font.measure_text_for_slice(glyphs, slice_range) + let mut advance = Au(0); + for (_i, glyph) in glyphs.iter_glyphs_for_char_range(slice_range) { + advance = advance + glyph.advance(); + } + RunMetrics::new(advance, self.font_metrics.ascent, self.font_metrics.descent) } - 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) { debug!("iterated on {:?}[{:?}]", offset, slice_range); - let metrics = self.font.measure_text_for_slice(glyphs, &slice_range); + let metrics = self.metrics_for_range(&slice_range); max_piece_width = Au::max(max_piece_width, metrics.advance_width); } max_piece_width diff --git a/src/components/main/layout/box.rs b/src/components/main/layout/box.rs index 2b5eec154b0..7feac56d621 100644 --- a/src/components/main/layout/box.rs +++ b/src/components/main/layout/box.rs @@ -630,13 +630,21 @@ impl Box { // Create the text box. do list.with_mut_ref |list| { + // FIXME(pcwalton): Allocation? Why?! + let run = ~TextRun { + text: text_box.run.text.clone(), + font_descriptor: text_box.run.font_descriptor.clone(), + font_metrics: text_box.run.font_metrics.clone(), + font_style: text_box.run.font_style.clone(), + decoration: text_box.run.decoration.clone(), + glyphs: text_box.run.glyphs.clone() + }; let text_display_item = ~TextDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, extra: ExtraDisplayListData::new(&self), }, - // FIXME(pcwalton): Allocation? Why?! - text_run: ~text_box.run.serialize(), + text_run: run, range: text_box.range, color: color, }; @@ -947,7 +955,7 @@ impl Box { self.position.mutate().ptr.size.width = image_width } ScannedTextBox(_) => { - // Scanned text boxes will have already had their widths assigned by this point. + } UnscannedTextBox(_) => fail!("Unscanned text boxes should have been scanned by now!"), } diff --git a/src/components/main/layout/inline.rs b/src/components/main/layout/inline.rs index 69cfb2901bf..11852060d6f 100644 --- a/src/components/main/layout/inline.rs +++ b/src/components/main/layout/inline.rs @@ -711,7 +711,7 @@ impl Flow for InlineFlow { // Find the top and bottom of the content area. // Those are used in text-top and text-bottom value of 'vertical-align' - let text_ascent = text_box.run.font.metrics.ascent; + let text_ascent = text_box.run.font_metrics.ascent; // Offset from the top of the box is 1/2 of the leading + ascent let text_offset = text_ascent + (line_height - em_size).scale_by(0.5); From 1b8f9c09d3bbbd128270053040392cc357b65905 Mon Sep 17 00:00:00 2001 From: patrick kim Date: Fri, 6 Dec 2013 14:29:42 +0900 Subject: [PATCH 3/5] remove @ fontcontext --- src/components/gfx/display_list.rs | 28 ++++++++------ src/components/gfx/font.rs | 28 ++++++++------ src/components/gfx/font_context.rs | 58 +++++++++++++++++++---------- src/components/gfx/font_list.rs | 16 -------- src/components/gfx/text/text_run.rs | 39 +------------------ src/components/main/layout/text.rs | 9 ++++- 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 DisplayItem { // 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] } impl FontGroup { - pub fn new(families: @str, style: &UsedFontStyle, fonts: ~[@mut Font]) -> FontGroup { + pub fn new(families: ~str, style: &UsedFontStyle, fonts: ~[RcMut]) -> 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, ()> { 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,()> { // 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, + instance_cache: LRUCache>, font_list: Option, // only needed by layout - group_cache: LRUCache, + group_cache: LRUCache>, 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 { 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, ()> { 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 { 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, ()> { 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]>, } -/// 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]>, -} - -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>, 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 }; From ab1291f34a300f2e8605ac85ab4e66160eedbebf Mon Sep 17 00:00:00 2001 From: Junyoung Cho Date: Fri, 6 Dec 2013 17:16:11 +0900 Subject: [PATCH 4/5] Patch for macos --- src/components/gfx/platform/macos/font_list.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/gfx/platform/macos/font_list.rs b/src/components/gfx/platform/macos/font_list.rs index d1533aca166..00e4b163b06 100644 --- a/src/components/gfx/platform/macos/font_list.rs +++ b/src/components/gfx/platform/macos/font_list.rs @@ -36,13 +36,13 @@ impl FontListHandle { let family_name = family_name_cf.to_str(); debug!("Creating new FontFamily for family: {:s}", family_name); - let new_family = @mut FontFamily::new(family_name); + let new_family = FontFamily::new(family_name); family_map.insert(family_name, new_family); } family_map } - pub fn load_variations_for_family(&self, family: @mut FontFamily) { + pub fn load_variations_for_family(&self, family: &mut FontFamily) { debug!("Looking for faces of family: {:s}", family.family_name); let family_collection = core_text::font_collection::create_for_family(family.family_name); @@ -54,7 +54,7 @@ impl FontListHandle { let handle = FontHandle::new_from_CTFont(&self.fctx, font).unwrap(); debug!("Creating new FontEntry for face: {:s}", handle.face_name()); - let entry = @FontEntry::new(handle); + let entry = FontEntry::new(handle); family.entries.push(entry) } } From 86e2cac8e853f37e4e5848f2ad2737592d6c7903 Mon Sep 17 00:00:00 2001 From: patrick kim Date: Fri, 6 Dec 2013 19:04:00 +0900 Subject: [PATCH 5/5] fix indent & some code --- src/components/gfx/display_list.rs | 3 +- src/components/gfx/font.rs | 10 ++- src/components/gfx/font_context.rs | 72 ++++++++++--------- src/components/gfx/font_list.rs | 7 +- .../gfx/platform/linux/font_context.rs | 4 +- src/components/main/layout/box.rs | 2 +- src/components/main/layout/text.rs | 9 ++- 7 files changed, 53 insertions(+), 54 deletions(-) diff --git a/src/components/gfx/display_list.rs b/src/components/gfx/display_list.rs index 1816bfd279d..bd972e54bbe 100644 --- a/src/components/gfx/display_list.rs +++ b/src/components/gfx/display_list.rs @@ -148,8 +148,7 @@ impl DisplayItem { font.metrics.clone() }); let origin = text.base.bounds.origin; - let baseline_origin = Point2D(origin.x, origin.y + - font.with_borrow( |font| {font.metrics.ascent} )); + let baseline_origin = Point2D(origin.x, origin.y + font_metrics.ascent); font.with_mut_borrow( |font| { font.draw_text_into_context(render_context, &text.text_run, diff --git a/src/components/gfx/font.rs b/src/components/gfx/font.rs index 6d1a4630f38..6ec769bb64e 100644 --- a/src/components/gfx/font.rs +++ b/src/components/gfx/font.rs @@ -195,12 +195,11 @@ 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. - let lr = self.fonts[0].with_mut_borrow(|font| { + self.fonts[0].with_mut_borrow(|font| { TextRun::new(font, text.clone(), decoration) - }); - lr + }) } } @@ -321,8 +320,7 @@ impl<'self> Font { let shaper = Shaper::new(self); self.shaper = Some(shaper); - let s:&'self Shaper = self.shaper.get_ref(); - s + self.shaper.get_ref() } pub fn get_table_for_tag(&self, tag: FontTableTag) -> Option { diff --git a/src/components/gfx/font_context.rs b/src/components/gfx/font_context.rs index c8191a93a57..72b37de0d25 100644 --- a/src/components/gfx/font_context.rs +++ b/src/components/gfx/font_context.rs @@ -103,7 +103,7 @@ impl<'self> FontContext { debug!("font cache miss"); let result = self.create_font_instance(desc); match result.clone() { - Ok(font) => { + Ok(ref font) => { self.instance_cache.insert(desc.clone(), font.clone()); }, _ => {} }; @@ -137,27 +137,31 @@ impl<'self> FontContext { let result = match self.font_list { Some(ref mut fl) => { let font_in_family = fl.find_font_in_family(&transformed_family_name, style); - if font_in_family.is_some() { - let font_entry = font_in_family.unwrap(); - let font_id = - SelectorPlatformIdentifier(font_entry.handle.face_identifier()); + match font_in_family { + Some(font_entry) => { + let font_id = + SelectorPlatformIdentifier(font_entry.handle.face_identifier()); let font_desc = FontDescriptor::new((*style).clone(), font_id); Some(font_desc) - } else { - None + }, + None => { + None + } } } None => None, }; - if result.is_some() { - found = true; - let instance = self.get_font_by_descriptor(&result.unwrap()); + match result { + Some(ref result) => { + found = true; + let instance = self.get_font_by_descriptor(result); - for font in instance.iter() { fonts.push(font.clone()); } + for font in instance.iter() { fonts.push(font.clone()); } + }, + _ => {} } - if !found { debug!("(create font group) didn't find `{:s}`", transformed_family_name); } @@ -166,24 +170,25 @@ impl<'self> FontContext { if fonts.len() == 0 { let last_resort = FontList::get_last_resort_font_families(); for family in last_resort.iter() { - let result = match self.font_list { - Some(ref fl) => fl.find_font_in_family(*family, style), - None => None, - }; - - 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 - } + let font_desc = match self.font_list { + Some(ref mut font_list) => { + let font_desc = { + 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 + } + } + }; + font_desc + }, + None => { + None } }; @@ -194,12 +199,11 @@ impl<'self> FontContext { for font in instance.iter() { fonts.push(font.clone()); } - }, None => { - } - } + }, + None => { } + }; } } - assert!(fonts.len() > 0); // TODO(Issue #179): Split FontStyle into specified and used styles let used_style = (*style).clone(); diff --git a/src/components/gfx/font_list.rs b/src/components/gfx/font_list.rs index c4db0475d73..4c6056ad67c 100644 --- a/src/components/gfx/font_list.rs +++ b/src/components/gfx/font_list.rs @@ -59,7 +59,7 @@ impl<'self> FontList { // 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()); + debug!("FontList: Found font family with name={:s}", family_name.to_str()); let s: &'self mut FontFamily = self.family_map.get_mut(family_name); // TODO(Issue #192: handle generic font families, like 'serif' and 'sans-serif'. // if such family exists, try to match style to a font @@ -69,9 +69,8 @@ impl<'self> FontList { } None - } - else { - debug!("FontList: {:s} font family with name={:s}", "Couldn't find", family_name.to_str()); + } else { + debug!("FontList: Couldn't find font family with name={:s}", family_name.to_str()); None } } diff --git a/src/components/gfx/platform/linux/font_context.rs b/src/components/gfx/platform/linux/font_context.rs index eee240cfc78..4619454d10d 100644 --- a/src/components/gfx/platform/linux/font_context.rs +++ b/src/components/gfx/platform/linux/font_context.rs @@ -52,7 +52,7 @@ impl FontContextHandle { None => { let ctx: FT_Library = ptr::null(); let result = FT_Init_FreeType(ptr::to_unsafe_ptr(&ctx)); - if !result.succeeded() { fail!(); } + if !result.succeeded() { fail!("Unable to initialize FreeType library"); } ft_pointer = Some(ctx); font_context_ref_count = font_context_ref_count + 1; FontContextHandle { @@ -68,7 +68,7 @@ impl FontContextHandleMethods for FontContextHandle { fn clone(&self) -> FontContextHandle { unsafe { font_context_ref_count = font_context_ref_count + 1; - FontContextHandle{ + FontContextHandle { ctx: self.ctx.clone() } } diff --git a/src/components/main/layout/box.rs b/src/components/main/layout/box.rs index 7feac56d621..6328328459e 100644 --- a/src/components/main/layout/box.rs +++ b/src/components/main/layout/box.rs @@ -955,7 +955,7 @@ impl Box { self.position.mutate().ptr.size.width = image_width } ScannedTextBox(_) => { - + // Scanned text boxes will have already had their widths assigned by this point. } UnscannedTextBox(_) => fail!("Unscanned text boxes should have been scanned by now!"), } diff --git a/src/components/main/layout/text.rs b/src/components/main/layout/text.rs index 7cb692baec4..e42ede37b56 100644 --- a/src/components/main/layout/text.rs +++ b/src/components/main/layout/text.rs @@ -188,11 +188,10 @@ 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 { - let font = { - fontgroup.with_borrow( |fg| fg.fonts[0].clone()) - }; - font.with_mut_borrow( |font| { - Some(@TextRun::new(font, run_str.clone(), decoration)) + fontgroup.with_borrow( |fg| { + fg.fonts[0].with_mut_borrow( |font| { + Some(@TextRun::new(font, run_str.clone(), decoration)) + }) }) } else { None