From f372c9c5c3274e530dba458afad04fb99a6aabbf Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 5 Apr 2013 15:49:11 -0700 Subject: [PATCH 01/11] gfx: Refactor the Mac platform goop into platform/ --- src/servo-gfx/font.rs | 15 ++++--- src/servo-gfx/font_context.rs | 7 ++- src/servo-gfx/font_list.rs | 13 +++--- .../{quartz => platform/macos}/font.rs | 45 ++++++++++--------- .../macos}/font_context.rs | 16 ++++--- .../{quartz => platform/macos}/font_list.rs | 29 ++++++------ src/servo-gfx/servo_gfx.rc | 8 +--- 7 files changed, 69 insertions(+), 64 deletions(-) rename src/servo-gfx/{quartz => platform/macos}/font.rs (79%) rename src/servo-gfx/{quartz => platform/macos}/font_context.rs (64%) rename src/servo-gfx/{quartz => platform/macos}/font_list.rs (65%) diff --git a/src/servo-gfx/font.rs b/src/servo-gfx/font.rs index bf8cdfb3620..ec7f98a9462 100644 --- a/src/servo-gfx/font.rs +++ b/src/servo-gfx/font.rs @@ -1,20 +1,21 @@ +//! Fonts. + use color::Color; use font_context::FontContext; use geometry::Au; +use platform; use render_context::RenderContext; -use util::range::Range; use text::glyph::{GlyphStore, GlyphIndex}; use text::shaper::ShaperMethods; -use text::{Shaper, TextRun}; use text::shaper::ShaperMethods; +use text::{Shaper, TextRun}; +use util::range::Range; use azure::{AzFloat, AzScaledFontRef}; use azure::scaled_font::ScaledFont; use azure::azure_hl::{BackendType, ColorPattern}; use geom::{Point2D, Rect, Size2D}; -#[cfg(target_os = "macos")] -use quartz; #[cfg(target_os = "linux")] use freetype_impl; use native; @@ -25,7 +26,7 @@ use native; // resources needed by the graphics layer to draw glyphs. #[cfg(target_os = "macos")] -pub type FontHandle = quartz::font::QuartzFontHandle; +pub type FontHandle = platform::font::QuartzFontHandle; #[cfg(target_os = "linux")] pub type FontHandle = freetype_impl::font::FreeTypeFontHandle; @@ -56,7 +57,7 @@ pub impl FontHandle { buf: ~[u8], style: &SpecifiedFontStyle) -> Result { - quartz::font::QuartzFontHandle::new_from_buffer(fctx, buf, style) + platform::font::QuartzFontHandle::new_from_buffer(fctx, buf, style) } #[cfg(target_os = "linux")] @@ -90,7 +91,7 @@ impl FontTableTagConversions for FontTableTag { } #[cfg(target_os = "macos")] -pub type FontTable = quartz::font::QuartzFontTable; +pub type FontTable = platform::font::QuartzFontTable; #[cfg(target_os = "linux")] pub type FontTable = freetype_impl::font::FreeTypeFontTable; diff --git a/src/servo-gfx/font_context.rs b/src/servo-gfx/font_context.rs index 884e142f5e5..733af2ebe1b 100644 --- a/src/servo-gfx/font_context.rs +++ b/src/servo-gfx/font_context.rs @@ -2,14 +2,13 @@ use font::{Font, FontDescriptor, FontGroup, FontStyle, SelectorPlatformIdentifie use font::{SelectorStubDummy, SpecifiedFontStyle, UsedFontStyle}; use font_list::FontList; use native::FontHandle; +use platform; use util::cache::Cache; use util::cache::MonoCache; use azure::azure_hl::BackendType; use core::hashmap::HashMap; -#[cfg(target_os = "macos")] -use quartz; #[cfg(target_os = "linux")] use freetype_impl; use font_context; @@ -35,7 +34,7 @@ pub fn dummy_style() -> FontStyle { } #[cfg(target_os = "macos")] -type FontContextHandle = quartz::font_context::QuartzFontContextHandle; +type FontContextHandle = platform::font_context::QuartzFontContextHandle; #[cfg(target_os = "linux")] type FontContextHandle = freetype_impl::font_context::FreeTypeFontContextHandle; @@ -50,7 +49,7 @@ pub trait FontContextHandleMethods { pub impl FontContextHandle { #[cfg(target_os = "macos")] pub fn new() -> FontContextHandle { - quartz::font_context::QuartzFontContextHandle::new() + platform::font_context::QuartzFontContextHandle::new() } #[cfg(target_os = "linux")] diff --git a/src/servo-gfx/font_list.rs b/src/servo-gfx/font_list.rs index 7b299c9b9ab..218d57741ad 100644 --- a/src/servo-gfx/font_list.rs +++ b/src/servo-gfx/font_list.rs @@ -1,19 +1,20 @@ +//! Implementation of the list of fonts. + use font::{CSSFontWeight, SpecifiedFontStyle}; use gfx_font::FontHandleMethods; -use native::FontHandle; use gfx_font::FontHandleMethods; +use native::FontHandle; +use platform; +use util::time::time; use core::hashmap::HashMap; #[cfg(target_os = "linux")] use fontconfig; -#[cfg(target_os = "macos")] -use quartz; use native; -use util::time::time; #[cfg(target_os = "macos")] -type FontListHandle = quartz::font_list::QuartzFontListHandle; +type FontListHandle = platform::font_list::QuartzFontListHandle; #[cfg(target_os = "linux")] type FontListHandle = fontconfig::font_list::FontconfigFontListHandle; @@ -21,7 +22,7 @@ type FontListHandle = fontconfig::font_list::FontconfigFontListHandle; pub impl FontListHandle { #[cfg(target_os = "macos")] pub fn new(fctx: &native::FontContextHandle) -> Result { - Ok(quartz::font_list::QuartzFontListHandle::new(fctx)) + Ok(platform::font_list::QuartzFontListHandle::new(fctx)) } #[cfg(target_os = "linux")] diff --git a/src/servo-gfx/quartz/font.rs b/src/servo-gfx/platform/macos/font.rs similarity index 79% rename from src/servo-gfx/quartz/font.rs rename to src/servo-gfx/platform/macos/font.rs index 5dc5cbf6326..15280f6c6e2 100644 --- a/src/servo-gfx/quartz/font.rs +++ b/src/servo-gfx/platform/macos/font.rs @@ -1,4 +1,4 @@ -/// Implementation of Quartz (CoreGraphics) fonts. +//! Implementation of Quartz (CoreGraphics) fonts. extern mod core_foundation; extern mod core_graphics; @@ -9,17 +9,18 @@ use gfx_font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTable, FontTab use gfx_font::{FontTableTag, FontWeight100, FontWeight200, FontWeight300, FontWeight400}; use gfx_font::{FontWeight500, FontWeight600, FontWeight700, FontWeight800, FontWeight900}; use gfx_font::{FractionalPixel, SpecifiedFontStyle}; -use quartz::font::core_foundation::base::{CFIndex, CFWrapper}; -use quartz::font::core_foundation::data::CFData; -use quartz::font::core_foundation::string::UniChar; -use quartz::font::core_graphics::data_provider::CGDataProvider; -use quartz::font::core_graphics::font::{CGFont, CGGlyph}; -use quartz::font::core_graphics::geometry::CGRect; -use quartz::font::core_text::font::{CTFont, CTFontMethods, CTFontMethodsPrivate}; -use quartz::font::core_text::font_descriptor::{SymbolicTraitAccessors, TraitAccessors}; -use quartz::font::core_text::font_descriptor::kCTFontDefaultOrientation; -use quartz::font_context::QuartzFontContextHandle; -use quartz; +use platform::macos::font::core_foundation::base::{CFIndex, CFWrapper}; +use platform::macos::font::core_foundation::data::CFData; +use platform::macos::font::core_foundation::string::UniChar; +use platform::macos::font::core_graphics::data_provider::CGDataProvider; +use platform::macos::font::core_graphics::font::{CGFont, CGGlyph}; +use platform::macos::font::core_graphics::geometry::CGRect; +use platform::macos::font::core_text::font::{CTFont, CTFontMethods, CTFontMethodsPrivate}; +use platform::macos::font::core_text::font_descriptor::{SymbolicTraitAccessors}; +use platform::macos::font::core_text::font_descriptor::{TraitAccessors}; +use platform::macos::font::core_text::font_descriptor::{kCTFontDefaultOrientation}; +use platform::macos::font_context::QuartzFontContextHandle; +use platform; use text::glyph::GlyphIndex; struct QuartzFontTable { @@ -51,11 +52,13 @@ pub impl QuartzFontHandle { fn new_from_buffer(_fctx: &QuartzFontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result { let fontprov : CGDataProvider = vec::as_imm_buf(buf, |cbuf, len| { - quartz::font::core_graphics::data_provider::new_from_buffer(cbuf, len) + platform::macos::font::core_graphics::data_provider::new_from_buffer(cbuf, len) }); - let cgfont = quartz::font::core_graphics::font::create_with_data_provider(&fontprov); - let ctfont = quartz::font::core_text::font::new_from_CGFont(&cgfont, style.pt_size); + let cgfont = platform::macos::font::core_graphics::font::create_with_data_provider( + &fontprov); + let ctfont = platform::macos::font::core_text::font::new_from_CGFont(&cgfont, + style.pt_size); let result = Ok(QuartzFontHandle { cgfont: Some(cgfont), @@ -65,13 +68,13 @@ pub impl QuartzFontHandle { return result; } - fn new_from_CTFont(_fctx: &QuartzFontContextHandle, ctfont: CTFont) -> Result { - let result = Ok(QuartzFontHandle { + fn new_from_CTFont(_: &QuartzFontContextHandle, + ctfont: CTFont) + -> Result { + Ok(QuartzFontHandle { mut cgfont: None, ctfont: ctfont, - }); - - return result; + }) } fn get_CGFont(&mut self) -> CGFont { @@ -177,7 +180,7 @@ impl FontHandleMethods for QuartzFontHandle { } fn get_table_for_tag(&self, tag: FontTableTag) -> Option { - let result : Option = self.ctfont.get_font_table(tag); + let result: Option = self.ctfont.get_font_table(tag); result.chain(|data| { Some(QuartzFontTable::wrap(data)) }) diff --git a/src/servo-gfx/quartz/font_context.rs b/src/servo-gfx/platform/macos/font_context.rs similarity index 64% rename from src/servo-gfx/quartz/font_context.rs rename to src/servo-gfx/platform/macos/font_context.rs index b610bdb576c..fcd1c71914d 100644 --- a/src/servo-gfx/quartz/font_context.rs +++ b/src/servo-gfx/platform/macos/font_context.rs @@ -2,12 +2,12 @@ extern mod core_foundation; extern mod core_graphics; extern mod core_text; -use quartz; -use quartz::font::QuartzFontHandle; - use gfx_font::{FontHandle, UsedFontStyle}; use gfx_font_context::FontContextHandleMethods; +use platform::macos::font::QuartzFontHandle; +use platform; + pub struct QuartzFontContextHandle { ctx: () } @@ -24,9 +24,13 @@ impl FontContextHandleMethods for QuartzFontContextHandle { QuartzFontContextHandle { ctx: self.ctx } } - fn create_font_from_identifier(&self, name: ~str, style: UsedFontStyle) -> Result { - let ctfont_result = quartz::font_context::core_text::font::new_from_name(name, - style.pt_size); + fn create_font_from_identifier(&self, + name: ~str, + style: UsedFontStyle) + -> Result { + let ctfont_result = platform::macos::font_context::core_text::font::new_from_name( + name, + style.pt_size); do result::chain(ctfont_result) |ctfont| { QuartzFontHandle::new_from_CTFont(self, ctfont) } diff --git a/src/servo-gfx/quartz/font_list.rs b/src/servo-gfx/platform/macos/font_list.rs similarity index 65% rename from src/servo-gfx/quartz/font_list.rs rename to src/servo-gfx/platform/macos/font_list.rs index 10eaca28d0b..7adeb5f5cb6 100644 --- a/src/servo-gfx/quartz/font_list.rs +++ b/src/servo-gfx/platform/macos/font_list.rs @@ -1,21 +1,20 @@ extern mod core_foundation; extern mod core_text; -use native; -use quartz; -use quartz::font_list::core_foundation::array::CFArray; -use quartz::font_list::core_foundation::base::CFWrapper; -use quartz::font_list::core_foundation::string::{CFString, CFStringRef}; - -use quartz::font_list::core_text::font_descriptor::CTFontDescriptorRef; -use quartz::font_list::core_text::font_collection::CTFontCollectionMethods; - -use quartz::font::QuartzFontHandle; -use quartz::font_context::QuartzFontContextHandle; use gfx_font::FontHandleMethods; use gfx_font_context::FontContextHandleMethods; use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap}; +use native; +use platform::macos::font::QuartzFontHandle; +use platform::macos::font_context::QuartzFontContextHandle; +use platform::macos::font_list::core_foundation::array::CFArray; +use platform::macos::font_list::core_foundation::base::CFWrapper; +use platform::macos::font_list::core_foundation::string::{CFString, CFStringRef}; +use platform::macos::font_list::core_text::font_collection::CTFontCollectionMethods; +use platform::macos::font_list::core_text::font_descriptor::CTFontDescriptorRef; +use platform; + use core::hashmap::HashMap; pub struct QuartzFontListHandle { @@ -29,7 +28,7 @@ pub impl QuartzFontListHandle { fn get_available_families(&self) -> FontFamilyMap { let family_names: CFArray = - quartz::font_list::core_text::font_collection::get_family_names(); + platform::macos::font_list::core_text::font_collection::get_family_names(); let mut family_map : FontFamilyMap = HashMap::new(); for family_names.each |&strref: &CFStringRef| { let family_name = CFString::wrap_extern(strref).to_str(); @@ -47,10 +46,12 @@ pub impl QuartzFontListHandle { debug!("Looking for faces of family: %s", *family_name); let family_collection = - quartz::font_list::core_text::font_collection::create_for_family(*family_name); + platform::macos::font_list::core_text::font_collection::create_for_family( + *family_name); for family_collection.get_descriptors().each |descref: &CTFontDescriptorRef| { let desc = CFWrapper::wrap_shared(*descref); - let font = quartz::font_list::core_text::font::new_from_descriptor(&desc, 0.0); + let font = platform::macos::font_list::core_text::font::new_from_descriptor(&desc, + 0.0); let handle = result::unwrap(QuartzFontHandle::new_from_CTFont(&self.fctx, font)); debug!("Creating new FontEntry for face: %s", handle.face_name()); diff --git a/src/servo-gfx/servo_gfx.rc b/src/servo-gfx/servo_gfx.rc index 31f0977da06..29ab186f97d 100644 --- a/src/servo-gfx/servo_gfx.rc +++ b/src/servo-gfx/servo_gfx.rc @@ -41,12 +41,8 @@ pub mod opts; // font.rs, font_list.rs, font_context.rs pub mod native; -#[cfg(target_os = "macos")] -pub mod quartz { - pub mod font; - pub mod font_context; - pub mod font_list; -} +#[path="platform/mod.rs"] +pub mod platform; #[cfg(target_os = "linux")] pub mod freetype_impl { From 9822f5d96b4dc24d78553a3883f084f0cb9887c5 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 5 Apr 2013 16:12:24 -0700 Subject: [PATCH 02/11] Refactor the Linux font stuff --- src/servo-gfx/font.rs | 8 +-- src/servo-gfx/font_context.rs | 11 ++- src/servo-gfx/font_list.rs | 9 +-- .../{freetype_impl => platform/linux}/font.rs | 69 +++++-------------- .../linux}/font_context.rs | 24 +++---- .../linux}/font_list.rs | 38 ++++++---- src/servo-gfx/servo_gfx.rc | 11 --- 7 files changed, 62 insertions(+), 108 deletions(-) rename src/servo-gfx/{freetype_impl => platform/linux}/font.rs (88%) rename src/servo-gfx/{freetype_impl => platform/linux}/font_context.rs (73%) rename src/servo-gfx/{fontconfig => platform/linux}/font_list.rs (78%) diff --git a/src/servo-gfx/font.rs b/src/servo-gfx/font.rs index ec7f98a9462..354239bfd82 100644 --- a/src/servo-gfx/font.rs +++ b/src/servo-gfx/font.rs @@ -16,8 +16,6 @@ use azure::scaled_font::ScaledFont; use azure::azure_hl::{BackendType, ColorPattern}; use geom::{Point2D, Rect, Size2D}; -#[cfg(target_os = "linux")] -use freetype_impl; use native; // FontHandle encapsulates access to the platform's font API, @@ -29,7 +27,7 @@ use native; pub type FontHandle = platform::font::QuartzFontHandle; #[cfg(target_os = "linux")] -pub type FontHandle = freetype_impl::font::FreeTypeFontHandle; +pub type FontHandle = platform::font::FreeTypeFontHandle; pub trait FontHandleMethods { // an identifier usable by FontContextHandle to recreate this FontHandle. @@ -65,7 +63,7 @@ pub impl FontHandle { buf: ~[u8], style: &SpecifiedFontStyle) -> Result { - freetype_impl::font::FreeTypeFontHandle::new_from_buffer(fctx, @buf, style) + platform::font::FreeTypeFontHandle::new_from_buffer(fctx, @buf, style) } } @@ -94,7 +92,7 @@ impl FontTableTagConversions for FontTableTag { pub type FontTable = platform::font::QuartzFontTable; #[cfg(target_os = "linux")] -pub type FontTable = freetype_impl::font::FreeTypeFontTable; +pub type FontTable = platform::font::FreeTypeFontTable; pub trait FontTableMethods { fn with_buffer(&self, &fn(*u8, uint)); diff --git a/src/servo-gfx/font_context.rs b/src/servo-gfx/font_context.rs index 733af2ebe1b..bfc96f37a4d 100644 --- a/src/servo-gfx/font_context.rs +++ b/src/servo-gfx/font_context.rs @@ -1,5 +1,8 @@ +//! The font context. + use font::{Font, FontDescriptor, FontGroup, FontStyle, SelectorPlatformIdentifier}; use font::{SelectorStubDummy, SpecifiedFontStyle, UsedFontStyle}; +use font_context; use font_list::FontList; use native::FontHandle; use platform; @@ -9,10 +12,6 @@ use util::cache::MonoCache; use azure::azure_hl::BackendType; use core::hashmap::HashMap; -#[cfg(target_os = "linux")] -use freetype_impl; -use font_context; - // TODO(Issue #164): delete, and get default font from font list static TEST_FONT: [u8, ..33004] = include_bin!("JosefinSans-SemiBold.ttf"); @@ -37,7 +36,7 @@ pub fn dummy_style() -> FontStyle { type FontContextHandle = platform::font_context::QuartzFontContextHandle; #[cfg(target_os = "linux")] -type FontContextHandle = freetype_impl::font_context::FreeTypeFontContextHandle; +type FontContextHandle = platform::font_context::FreeTypeFontContextHandle; pub trait FontContextHandleMethods { fn clone(&self) -> FontContextHandle; @@ -54,7 +53,7 @@ pub impl FontContextHandle { #[cfg(target_os = "linux")] pub fn new() -> FontContextHandle { - freetype_impl::font_context::FreeTypeFontContextHandle::new() + platform::font_context::FreeTypeFontContextHandle::new() } } diff --git a/src/servo-gfx/font_list.rs b/src/servo-gfx/font_list.rs index 218d57741ad..32413043db1 100644 --- a/src/servo-gfx/font_list.rs +++ b/src/servo-gfx/font_list.rs @@ -4,20 +4,17 @@ use font::{CSSFontWeight, SpecifiedFontStyle}; use gfx_font::FontHandleMethods; use gfx_font::FontHandleMethods; use native::FontHandle; +use native; use platform; use util::time::time; use core::hashmap::HashMap; -#[cfg(target_os = "linux")] -use fontconfig; -use native; - #[cfg(target_os = "macos")] type FontListHandle = platform::font_list::QuartzFontListHandle; #[cfg(target_os = "linux")] -type FontListHandle = fontconfig::font_list::FontconfigFontListHandle; +type FontListHandle = platform::font_list::FontconfigFontListHandle; pub impl FontListHandle { #[cfg(target_os = "macos")] @@ -27,7 +24,7 @@ pub impl FontListHandle { #[cfg(target_os = "linux")] pub fn new(fctx: &native::FontContextHandle) -> Result { - Ok(fontconfig::font_list::FontconfigFontListHandle::new(fctx)) + Ok(platform::font_list::FontconfigFontListHandle::new(fctx)) } } diff --git a/src/servo-gfx/freetype_impl/font.rs b/src/servo-gfx/platform/linux/font.rs similarity index 88% rename from src/servo-gfx/freetype_impl/font.rs rename to src/servo-gfx/platform/linux/font.rs index 234ffaeb00e..f09034cf4a0 100644 --- a/src/servo-gfx/freetype_impl/font.rs +++ b/src/servo-gfx/platform/linux/font.rs @@ -1,59 +1,28 @@ +//! Linux (FreeType) representation of fonts. + extern mod freetype; -use native; -use freetype_impl::font_context::FreeTypeFontContextHandle; -use gfx_font::{ - CSSFontWeight, - FontHandleMethods, - FontMetrics, - FontTable, - FontTableMethods, - FontTableTag, - FractionalPixel, - SpecifiedFontStyle, - UsedFontStyle, - FontWeight100, - FontWeight200, - FontWeight300, - FontWeight400, - FontWeight500, - FontWeight600, - FontWeight700, - FontWeight800, - FontWeight900, -}; -use geometry; use geometry::Au; +use geometry; +use gfx_font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTable, FontTableMethods}; +use gfx_font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle, FontWeight100}; +use gfx_font::{FontWeight200, FontWeight300, FontWeight400, FontWeight500, FontWeight600}; +use gfx_font::{FontWeight700, FontWeight800, FontWeight900}; +use native; +use platform::font_context::FreeTypeFontContextHandle; use text::glyph::GlyphIndex; use text::util::{float_to_fixed, fixed_to_float}; -use self::freetype::freetype::{ - FTErrorMethods, - FT_F26Dot6, - FT_Face, - FT_FaceRec, - FT_GlyphSlot, - FT_Library, - FT_Long, - FT_ULong, - FT_SizeRec, - FT_UInt, - FT_Size_Metrics, - FT_STYLE_FLAG_ITALIC, - FT_STYLE_FLAG_BOLD, - ft_sfnt_os2 -}; -use self::freetype::freetype::bindgen::{ - FT_New_Memory_Face, - FT_Done_Face, - FT_Get_Char_Index, - FT_Get_Postscript_Name, - FT_Load_Glyph, - FT_Set_Char_Size, - FT_New_Face, - FT_Get_Sfnt_Table -}; -use self::freetype::tt_os2::TT_OS2; +use platform::font::freetype::freetype::bindgen::{FT_Get_Char_Index, FT_Get_Postscript_Name}; +use platform::font::freetype::freetype::bindgen::{FT_Load_Glyph, FT_Set_Char_Size}; +use platform::font::freetype::freetype::bindgen::{FT_New_Face, FT_Get_Sfnt_Table}; +use platform::font::freetype::freetype::bindgen::{FT_New_Memory_Face, FT_Done_Face}; +use platform::font::freetype::freetype::{FTErrorMethods, FT_F26Dot6, FT_Face, FT_FaceRec}; +use platform::font::freetype::freetype::{FT_GlyphSlot, FT_Library, FT_Long, FT_ULong}; +use platform::font::freetype::freetype::{FT_STYLE_FLAG_ITALIC, FT_STYLE_FLAG_BOLD}; +use platform::font::freetype::freetype::{FT_SizeRec, FT_UInt, FT_Size_Metrics}; +use platform::font::freetype::freetype::{ft_sfnt_os2}; +use platform::font::freetype::tt_os2::TT_OS2; fn float_to_fixed_ft(f: float) -> i32 { float_to_fixed(6, f) diff --git a/src/servo-gfx/freetype_impl/font_context.rs b/src/servo-gfx/platform/linux/font_context.rs similarity index 73% rename from src/servo-gfx/freetype_impl/font_context.rs rename to src/servo-gfx/platform/linux/font_context.rs index 98b5615bbaf..b81278b53e7 100644 --- a/src/servo-gfx/freetype_impl/font_context.rs +++ b/src/servo-gfx/platform/linux/font_context.rs @@ -1,22 +1,13 @@ extern mod freetype; extern mod fontconfig; -use self::freetype::freetype::{ - FTErrorMethods, - FT_Library, -}; -use self::freetype::freetype::bindgen::{ - FT_Init_FreeType, - FT_Done_FreeType -}; -use fontconfig::font_list::path_from_identifier; +use gfx_font::{FontHandle, UsedFontStyle}; +use platform::font::FreeTypeFontHandle; +use platform::font_context::FontContextHandleMethods; +use platform::font_list::path_from_identifier; -use gfx_font::{ - FontHandle, - UsedFontStyle, -}; -use font_context::FontContextHandleMethods; -use freetype_impl::font::FreeTypeFontHandle; +use platform::font_context::freetype::freetype::{FTErrorMethods, FT_Library}; +use platform::font_context::freetype::freetype::bindgen::{FT_Done_FreeType, FT_Init_FreeType}; struct FreeTypeLibraryHandle { ctx: FT_Library, @@ -50,7 +41,8 @@ impl FontContextHandleMethods for FreeTypeFontContextHandle { FreeTypeFontContextHandle { ctx: self.ctx } } - fn create_font_from_identifier(&self, name: ~str, style: UsedFontStyle) -> Result { + fn create_font_from_identifier(&self, name: ~str, style: UsedFontStyle) + -> Result { debug!("Creating font handle for %s", name); do path_from_identifier(name).chain |file_name| { debug!("Opening font face %s", file_name); diff --git a/src/servo-gfx/fontconfig/font_list.rs b/src/servo-gfx/platform/linux/font_list.rs similarity index 78% rename from src/servo-gfx/fontconfig/font_list.rs rename to src/servo-gfx/platform/linux/font_list.rs index 6ab2668b1f6..79027fb8d84 100644 --- a/src/servo-gfx/fontconfig/font_list.rs +++ b/src/servo-gfx/platform/linux/font_list.rs @@ -1,25 +1,34 @@ +//! Font list implementation for Linux (fontconfig). + extern mod freetype; extern mod fontconfig; use gfx_font::FontHandleMethods; -use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap}; use gfx_font_context::FontContextHandleMethods; -use freetype_impl::font_context::FreeTypeFontContextHandle; -use freetype_impl::font::FreeTypeFontHandle; -use self::fontconfig::fontconfig::{FcChar8, FcResultMatch, FcSetSystem, - FcResultNoMatch, FcMatchPattern}; -use self::fontconfig::fontconfig::bindgen::{ - FcConfigGetCurrent, FcConfigGetFonts, FcPatternGetString, - FcPatternDestroy, FcFontSetDestroy, FcConfigSubstitute, - FcDefaultSubstitute, FcPatternCreate, FcPatternAddString, - FcFontMatch, FcFontSetList, FcObjectSetCreate, FcObjectSetDestroy, - FcObjectSetAdd, FcPatternGetInteger -}; +use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap}; +use native; +use platform::font::FreeTypeFontHandle; +use platform::font_context::FreeTypeFontContextHandle; use core::hashmap::HashMap; use core::libc::c_int; use core::ptr::Ptr; -use native; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcConfigGetCurrent}; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcConfigGetFonts}; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcDefaultSubstitute}; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcPatternCreate}; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcFontSetDestroy}; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcConfigSubstitute}; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcFontSetList}; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcObjectSetCreate}; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcObjectSetDestroy}; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcObjectSetAdd}; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcPatternAddString, FcFontMatch}; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcPatternGetInteger}; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcPatternGetString}; +use platform::font_context::fontconfig::fontconfig::bindgen::{FcPatternDestroy}; +use platform::font_context::fontconfig::fontconfig::{FcChar8, FcResultMatch, FcSetSystem}; +use platform::font_context::fontconfig::fontconfig::{FcMatchPattern, FcResultNoMatch}; pub struct FontconfigFontListHandle { fctx: FreeTypeFontContextHandle, @@ -99,7 +108,8 @@ pub impl FontconfigFontListHandle { debug!("variation file: %?", file); debug!("variation index: %?", index); - let font_handle = FreeTypeFontHandle::new_from_file_unstyled(&self.fctx, file); + let font_handle = FreeTypeFontHandle::new_from_file_unstyled(&self.fctx, + file); let font_handle = font_handle.unwrap(); debug!("Creating new FontEntry for face: %s", font_handle.face_name()); diff --git a/src/servo-gfx/servo_gfx.rc b/src/servo-gfx/servo_gfx.rc index 29ab186f97d..66d697aa465 100644 --- a/src/servo-gfx/servo_gfx.rc +++ b/src/servo-gfx/servo_gfx.rc @@ -44,17 +44,6 @@ pub mod native; #[path="platform/mod.rs"] pub mod platform; -#[cfg(target_os = "linux")] -pub mod freetype_impl { - pub mod font; - pub mod font_context; -} - -#[cfg(target_os = "linux")] -pub mod fontconfig { - pub mod font_list; -} - // Images pub mod image { pub mod base; From b2f5ccfd5f680491b9621926132a5deb43b1dab0 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 5 Apr 2013 16:57:24 -0700 Subject: [PATCH 03/11] Remove native.rs. It's no longer needed; just use platform::* directly. --- src/servo-gfx/font.rs | 51 +++---------- src/servo-gfx/font_context.rs | 24 +----- src/servo-gfx/font_list.rs | 44 ++++------- src/servo-gfx/native.rs | 9 --- src/servo-gfx/platform/linux/font.rs | 18 +++-- src/servo-gfx/platform/linux/font_context.rs | 2 + src/servo-gfx/platform/linux/font_list.rs | 5 +- src/servo-gfx/platform/macos/font.rs | 78 ++++++++++---------- src/servo-gfx/platform/macos/font_context.rs | 22 +++--- src/servo-gfx/platform/macos/font_list.rs | 19 ++--- src/servo-gfx/servo_gfx.rc | 5 +- src/servo-gfx/text/harfbuzz/shaper.rs | 3 +- 12 files changed, 104 insertions(+), 176 deletions(-) delete mode 100644 src/servo-gfx/native.rs diff --git a/src/servo-gfx/font.rs b/src/servo-gfx/font.rs index 354239bfd82..4ad4ad0a0a7 100644 --- a/src/servo-gfx/font.rs +++ b/src/servo-gfx/font.rs @@ -3,11 +3,11 @@ use color::Color; use font_context::FontContext; use geometry::Au; -use platform; +use platform::font_context::FontContextHandle; +use platform::font::{FontHandle, FontTable}; use render_context::RenderContext; use text::glyph::{GlyphStore, GlyphIndex}; use text::shaper::ShaperMethods; -use text::shaper::ShaperMethods; use text::{Shaper, TextRun}; use util::range::Range; @@ -16,20 +16,15 @@ use azure::scaled_font::ScaledFont; use azure::azure_hl::{BackendType, ColorPattern}; use geom::{Point2D, Rect, Size2D}; -use native; - // FontHandle encapsulates access to the platform's font API, // e.g. quartz, FreeType. It provides access to metrics and tables // needed by the text shaper as well as access to the underlying font // resources needed by the graphics layer to draw glyphs. -#[cfg(target_os = "macos")] -pub type FontHandle = platform::font::QuartzFontHandle; - -#[cfg(target_os = "linux")] -pub type FontHandle = platform::font::FreeTypeFontHandle; - pub trait FontHandleMethods { + fn new_from_buffer(fctx: &FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) + -> Result; + // an identifier usable by FontContextHandle to recreate this FontHandle. fn face_identifier(&self) -> ~str; fn family_name(&self) -> ~str; @@ -37,36 +32,14 @@ pub trait FontHandleMethods { fn is_italic(&self) -> bool; fn boldness(&self) -> CSSFontWeight; - fn clone_with_style(&self, fctx: &native::FontContextHandle, style: &UsedFontStyle) -> Result; + fn clone_with_style(&self, fctx: &FontContextHandle, style: &UsedFontStyle) + -> Result; fn glyph_index(&self, codepoint: char) -> Option; fn glyph_h_advance(&self, GlyphIndex) -> Option; fn get_metrics(&self) -> FontMetrics; fn get_table_for_tag(&self, FontTableTag) -> Option; } -// TODO(Issue #163): this is a workaround for static methods and -// typedefs not working well together. It should be removed. -// -// `new` should be part of trait FontHandleMethods. - -pub impl FontHandle { - #[cfg(target_os = "macos")] - pub fn new_from_buffer(fctx: &native::FontContextHandle, - buf: ~[u8], - style: &SpecifiedFontStyle) - -> Result { - platform::font::QuartzFontHandle::new_from_buffer(fctx, buf, style) - } - - #[cfg(target_os = "linux")] - pub fn new_from_buffer(fctx: &native::FontContextHandle, - buf: ~[u8], - style: &SpecifiedFontStyle) - -> Result { - platform::font::FreeTypeFontHandle::new_from_buffer(fctx, @buf, style) - } -} - // Used to abstract over the shaper's choice of fixed int representation. pub type FractionalPixel = float; @@ -88,12 +61,6 @@ impl FontTableTagConversions for FontTableTag { } } -#[cfg(target_os = "macos")] -pub type FontTable = platform::font::QuartzFontTable; - -#[cfg(target_os = "linux")] -pub type FontTable = platform::font::FreeTypeFontTable; - pub trait FontTableMethods { fn with_buffer(&self, &fn(*u8, uint)); } @@ -246,8 +213,8 @@ pub impl Font { style: &SpecifiedFontStyle, backend: BackendType) -> Result<@mut Font, ()> { - let handle = FontHandle::new_from_buffer(&ctx.handle, buffer, style); - let handle = if handle.is_ok() { + let handle = FontHandleMethods::new_from_buffer(&ctx.handle, buffer, style); + let handle: FontHandle = if handle.is_ok() { result::unwrap(handle) } else { return Err(handle.get_err()); diff --git a/src/servo-gfx/font_context.rs b/src/servo-gfx/font_context.rs index bfc96f37a4d..4a3835de6ae 100644 --- a/src/servo-gfx/font_context.rs +++ b/src/servo-gfx/font_context.rs @@ -4,8 +4,8 @@ use font::{Font, FontDescriptor, FontGroup, FontStyle, SelectorPlatformIdentifie use font::{SelectorStubDummy, SpecifiedFontStyle, UsedFontStyle}; use font_context; use font_list::FontList; -use native::FontHandle; -use platform; +use platform::font::FontHandle; +use platform::font_context::FontContextHandle; use util::cache::Cache; use util::cache::MonoCache; @@ -32,31 +32,11 @@ pub fn dummy_style() -> FontStyle { } } -#[cfg(target_os = "macos")] -type FontContextHandle = platform::font_context::QuartzFontContextHandle; - -#[cfg(target_os = "linux")] -type FontContextHandle = platform::font_context::FreeTypeFontContextHandle; - pub trait FontContextHandleMethods { fn clone(&self) -> FontContextHandle; fn create_font_from_identifier(&self, ~str, UsedFontStyle) -> Result; } -// TODO(Issue #163): this is a workaround for static methods, traits, -// and typedefs not working well together. It should be removed. -pub impl FontContextHandle { - #[cfg(target_os = "macos")] - pub fn new() -> FontContextHandle { - platform::font_context::QuartzFontContextHandle::new() - } - - #[cfg(target_os = "linux")] - pub fn new() -> FontContextHandle { - platform::font_context::FreeTypeFontContextHandle::new() - } -} - #[allow(non_implicitly_copyable_typarams)] pub struct FontContext { instance_cache: MonoCache, diff --git a/src/servo-gfx/font_list.rs b/src/servo-gfx/font_list.rs index 32413043db1..7a6ddae6570 100644 --- a/src/servo-gfx/font_list.rs +++ b/src/servo-gfx/font_list.rs @@ -2,36 +2,17 @@ use font::{CSSFontWeight, SpecifiedFontStyle}; use gfx_font::FontHandleMethods; -use gfx_font::FontHandleMethods; -use native::FontHandle; -use native; -use platform; +use platform::font::FontHandle; +use platform::font_context::FontContextHandle; +use platform::font_list::FontListHandle; use util::time::time; use core::hashmap::HashMap; -#[cfg(target_os = "macos")] -type FontListHandle = platform::font_list::QuartzFontListHandle; - -#[cfg(target_os = "linux")] -type FontListHandle = platform::font_list::FontconfigFontListHandle; - -pub impl FontListHandle { - #[cfg(target_os = "macos")] - pub fn new(fctx: &native::FontContextHandle) -> Result { - Ok(platform::font_list::QuartzFontListHandle::new(fctx)) - } - - #[cfg(target_os = "linux")] - pub fn new(fctx: &native::FontContextHandle) -> Result { - Ok(platform::font_list::FontconfigFontListHandle::new(fctx)) - } -} - pub type FontFamilyMap = HashMap<~str, @mut FontFamily>; trait FontListHandleMethods { - fn get_available_families(&self, fctx: &native::FontContextHandle) -> FontFamilyMap; + fn get_available_families(&self, fctx: &FontContextHandle) -> FontFamilyMap; fn load_variations_for_family(&self, family: @mut FontFamily); } @@ -41,8 +22,8 @@ pub struct FontList { } pub impl FontList { - fn new(fctx: &native::FontContextHandle) -> FontList { - let handle = result::unwrap(FontListHandle::new(fctx)); + fn new(fctx: &FontContextHandle) -> FontList { + let handle = FontListHandle::new(fctx); let mut list = FontList { handle: handle, family_map: HashMap::new(), @@ -51,7 +32,7 @@ pub impl FontList { return list; } - priv fn refresh(&mut self, _fctx: &native::FontContextHandle) { + priv fn refresh(&mut self, _: &FontContextHandle) { // TODO(Issue #186): don't refresh unless something actually // changed. Does OSX have a notification for this event? // @@ -106,15 +87,15 @@ pub impl FontFamily { } } - priv fn load_family_variations(@mut self, list: &native::FontListHandle) { + priv fn load_family_variations(@mut self, list: &FontListHandle) { let this : &mut FontFamily = self; // FIXME: borrow checker workaround if this.entries.len() > 0 { return; } list.load_variations_for_family(self); assert!(this.entries.len() > 0); } - fn find_font_for_style(@mut self, list: &native::FontListHandle, style: &SpecifiedFontStyle) -> Option<@FontEntry> { - + fn find_font_for_style(@mut self, list: &FontListHandle, style: &SpecifiedFontStyle) + -> Option<@FontEntry> { self.load_family_variations(list); // TODO(Issue #189): optimize lookup for @@ -165,5 +146,8 @@ pub impl FontEntry { self.weight.is_bold() } - fn is_italic(&self) -> bool { self.italic } + fn is_italic(&self) -> bool { + self.italic + } } + diff --git a/src/servo-gfx/native.rs b/src/servo-gfx/native.rs deleted file mode 100644 index 9ae03bdc06b..00000000000 --- a/src/servo-gfx/native.rs +++ /dev/null @@ -1,9 +0,0 @@ -/* This file exists just to make it easier to import platform-specific - implementations. - -Note that you still must define each of the files as a module in -servo_gfx.rc. This is not ideal and may be changed in the future. */ - -pub use font::FontHandle; -pub use font_context::FontContextHandle; -pub use font_list::FontListHandle; diff --git a/src/servo-gfx/platform/linux/font.rs b/src/servo-gfx/platform/linux/font.rs index f09034cf4a0..6fa22fad275 100644 --- a/src/servo-gfx/platform/linux/font.rs +++ b/src/servo-gfx/platform/linux/font.rs @@ -8,8 +8,7 @@ use gfx_font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTable, FontTab use gfx_font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle, FontWeight100}; use gfx_font::{FontWeight200, FontWeight300, FontWeight400, FontWeight500, FontWeight600}; use gfx_font::{FontWeight700, FontWeight800, FontWeight900}; -use native; -use platform::font_context::FreeTypeFontContextHandle; +use platform::font_context::{FreeTypeFontContextHandle, FontContextHandle}; use text::glyph::GlyphIndex; use text::util::{float_to_fixed, fixed_to_float}; @@ -24,6 +23,9 @@ use platform::font::freetype::freetype::{FT_SizeRec, FT_UInt, FT_Size_Metrics}; use platform::font::freetype::freetype::{ft_sfnt_os2}; use platform::font::freetype::tt_os2::TT_OS2; +pub use FontHandle = platform::linux::font::FreeTypeFontHandle; +pub use FontTable = platform::linux::font::FreeTypeFontTable; + fn float_to_fixed_ft(f: float) -> i32 { float_to_fixed(6, f) } @@ -113,9 +115,15 @@ pub impl FreeTypeFontHandle { Ok(FreeTypeFontHandle { source: FontSourceFile(file), face: face }) } +} +impl FontHandleMethods for FreeTypeFontHandle { pub fn new_from_buffer(fctx: &FreeTypeFontContextHandle, - buf: @~[u8], style: &SpecifiedFontStyle) -> Result { + buf: ~[u8], + style: &SpecifiedFontStyle) + -> Result { + let buf = @buf; + let ft_ctx: FT_Library = fctx.ctx.ctx; if ft_ctx.is_null() { return Err(()); } @@ -150,9 +158,7 @@ pub impl FreeTypeFontHandle { } } } -} -impl FontHandleMethods for FreeTypeFontHandle { // an identifier usable by FontContextHandle to recreate this FontHandle. fn face_identifier(&self) -> ~str { /* FT_Get_Postscript_Name seems like a better choice here, but it @@ -196,7 +202,7 @@ impl FontHandleMethods for FreeTypeFontHandle { } fn clone_with_style(&self, - fctx: &native::FontContextHandle, + fctx: &FontContextHandle, style: &UsedFontStyle) -> Result { match self.source { FontSourceMem(buf) => { diff --git a/src/servo-gfx/platform/linux/font_context.rs b/src/servo-gfx/platform/linux/font_context.rs index b81278b53e7..c809f89d225 100644 --- a/src/servo-gfx/platform/linux/font_context.rs +++ b/src/servo-gfx/platform/linux/font_context.rs @@ -9,6 +9,8 @@ use platform::font_list::path_from_identifier; use platform::font_context::freetype::freetype::{FTErrorMethods, FT_Library}; use platform::font_context::freetype::freetype::bindgen::{FT_Done_FreeType, FT_Init_FreeType}; +pub use FontContextHandle = platform::linux::FreeTypeFontContextHandle; + struct FreeTypeLibraryHandle { ctx: FT_Library, } diff --git a/src/servo-gfx/platform/linux/font_list.rs b/src/servo-gfx/platform/linux/font_list.rs index 79027fb8d84..d7dcc80d1df 100644 --- a/src/servo-gfx/platform/linux/font_list.rs +++ b/src/servo-gfx/platform/linux/font_list.rs @@ -6,9 +6,8 @@ extern mod fontconfig; use gfx_font::FontHandleMethods; use gfx_font_context::FontContextHandleMethods; use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap}; -use native; use platform::font::FreeTypeFontHandle; -use platform::font_context::FreeTypeFontContextHandle; +use platform::font_context::{FontContextHandle, FreeTypeFontContextHandle}; use core::hashmap::HashMap; use core::libc::c_int; @@ -35,7 +34,7 @@ pub struct FontconfigFontListHandle { } pub impl FontconfigFontListHandle { - pub fn new(fctx: &native::FontContextHandle) -> FontconfigFontListHandle { + pub fn new(fctx: &FontContextHandle) -> FontconfigFontListHandle { FontconfigFontListHandle { fctx: fctx.clone() } } diff --git a/src/servo-gfx/platform/macos/font.rs b/src/servo-gfx/platform/macos/font.rs index 15280f6c6e2..9706aa110ae 100644 --- a/src/servo-gfx/platform/macos/font.rs +++ b/src/servo-gfx/platform/macos/font.rs @@ -5,7 +5,7 @@ extern mod core_graphics; extern mod core_text; use geometry::Au; -use gfx_font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTable, FontTableMethods}; +use gfx_font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTableMethods}; use gfx_font::{FontTableTag, FontWeight100, FontWeight200, FontWeight300, FontWeight400}; use gfx_font::{FontWeight500, FontWeight600, FontWeight700, FontWeight800, FontWeight900}; use gfx_font::{FractionalPixel, SpecifiedFontStyle}; @@ -19,59 +19,39 @@ use platform::macos::font::core_text::font::{CTFont, CTFontMethods, CTFontMethod use platform::macos::font::core_text::font_descriptor::{SymbolicTraitAccessors}; use platform::macos::font::core_text::font_descriptor::{TraitAccessors}; use platform::macos::font::core_text::font_descriptor::{kCTFontDefaultOrientation}; -use platform::macos::font_context::QuartzFontContextHandle; +use platform::macos::font_context::FontContextHandle; use platform; use text::glyph::GlyphIndex; -struct QuartzFontTable { +pub struct FontTable { data: CFData, } - // Noncopyable. -impl Drop for QuartzFontTable { fn finalize(&self) {} } +impl Drop for FontTable { + fn finalize(&self) {} +} -pub impl QuartzFontTable { - fn wrap(data: CFData) -> QuartzFontTable { - QuartzFontTable { data: data } +pub impl FontTable { + fn wrap(data: CFData) -> FontTable { + FontTable { data: data } } } -impl FontTableMethods for QuartzFontTable { +impl FontTableMethods for FontTable { fn with_buffer(&self, blk: &fn(*u8, uint)) { blk(self.data.bytes(), self.data.len()); } } -pub struct QuartzFontHandle { +pub struct FontHandle { priv cgfont: Option, ctfont: CTFont, } -pub impl QuartzFontHandle { - fn new_from_buffer(_fctx: &QuartzFontContextHandle, buf: ~[u8], - style: &SpecifiedFontStyle) -> Result { - let fontprov : CGDataProvider = vec::as_imm_buf(buf, |cbuf, len| { - platform::macos::font::core_graphics::data_provider::new_from_buffer(cbuf, len) - }); - - let cgfont = platform::macos::font::core_graphics::font::create_with_data_provider( - &fontprov); - let ctfont = platform::macos::font::core_text::font::new_from_CGFont(&cgfont, - style.pt_size); - - let result = Ok(QuartzFontHandle { - cgfont: Some(cgfont), - ctfont: ctfont, - }); - - return result; - } - - fn new_from_CTFont(_: &QuartzFontContextHandle, - ctfont: CTFont) - -> Result { - Ok(QuartzFontHandle { +pub impl FontHandle { + fn new_from_CTFont(_: &FontContextHandle, ctfont: CTFont) -> Result { + Ok(FontHandle { mut cgfont: None, ctfont: ctfont, }) @@ -89,7 +69,26 @@ pub impl QuartzFontHandle { } } -impl FontHandleMethods for QuartzFontHandle { +impl FontHandleMethods for FontHandle { + fn new_from_buffer(_: &FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) + -> Result { + let fontprov : CGDataProvider = vec::as_imm_buf(buf, |cbuf, len| { + platform::macos::font::core_graphics::data_provider::new_from_buffer(cbuf, len) + }); + + let cgfont = platform::macos::font::core_graphics::font::create_with_data_provider( + &fontprov); + let ctfont = platform::macos::font::core_text::font::new_from_CGFont(&cgfont, + style.pt_size); + + let result = Ok(FontHandle { + cgfont: Some(cgfont), + ctfont: ctfont, + }); + + return result; + } + fn family_name(&self) -> ~str { self.ctfont.family_name() } @@ -118,11 +117,10 @@ impl FontHandleMethods for QuartzFontHandle { return FontWeight900; } - fn clone_with_style(&self, fctx: &QuartzFontContextHandle, - style: &SpecifiedFontStyle) - -> Result { + fn clone_with_style(&self, fctx: &FontContextHandle, style: &SpecifiedFontStyle) + -> Result { let new_font = self.ctfont.clone_with_font_size(style.pt_size); - return QuartzFontHandle::new_from_CTFont(fctx, new_font); + return FontHandle::new_from_CTFont(fctx, new_font); } fn glyph_index(&self, codepoint: char) -> Option { @@ -182,7 +180,7 @@ impl FontHandleMethods for QuartzFontHandle { fn get_table_for_tag(&self, tag: FontTableTag) -> Option { let result: Option = self.ctfont.get_font_table(tag); result.chain(|data| { - Some(QuartzFontTable::wrap(data)) + Some(FontTable::wrap(data)) }) } diff --git a/src/servo-gfx/platform/macos/font_context.rs b/src/servo-gfx/platform/macos/font_context.rs index fcd1c71914d..aacd51cdcb9 100644 --- a/src/servo-gfx/platform/macos/font_context.rs +++ b/src/servo-gfx/platform/macos/font_context.rs @@ -2,26 +2,28 @@ extern mod core_foundation; extern mod core_graphics; extern mod core_text; -use gfx_font::{FontHandle, UsedFontStyle}; +use gfx_font::UsedFontStyle; use gfx_font_context::FontContextHandleMethods; -use platform::macos::font::QuartzFontHandle; +use platform::macos::font::FontHandle; use platform; -pub struct QuartzFontContextHandle { +pub struct FontContextHandle { ctx: () } -pub impl QuartzFontContextHandle { +pub impl FontContextHandle { // this is a placeholder until NSFontManager or whatever is bound in here. - pub fn new() -> QuartzFontContextHandle { - QuartzFontContextHandle { ctx: () } + pub fn new() -> FontContextHandle { + FontContextHandle { ctx: () } } } -impl FontContextHandleMethods for QuartzFontContextHandle { - fn clone(&self) -> QuartzFontContextHandle { - QuartzFontContextHandle { ctx: self.ctx } +impl FontContextHandleMethods for FontContextHandle { + fn clone(&self) -> FontContextHandle { + FontContextHandle { + ctx: self.ctx + } } fn create_font_from_identifier(&self, @@ -32,7 +34,7 @@ impl FontContextHandleMethods for QuartzFontContextHandle { name, style.pt_size); do result::chain(ctfont_result) |ctfont| { - QuartzFontHandle::new_from_CTFont(self, ctfont) + FontHandle::new_from_CTFont(self, ctfont) } } } diff --git a/src/servo-gfx/platform/macos/font_list.rs b/src/servo-gfx/platform/macos/font_list.rs index 7adeb5f5cb6..0c7bbfe4f37 100644 --- a/src/servo-gfx/platform/macos/font_list.rs +++ b/src/servo-gfx/platform/macos/font_list.rs @@ -5,9 +5,8 @@ use gfx_font::FontHandleMethods; use gfx_font_context::FontContextHandleMethods; use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap}; -use native; -use platform::macos::font::QuartzFontHandle; -use platform::macos::font_context::QuartzFontContextHandle; +use platform::macos::font::FontHandle; +use platform::macos::font_context::FontContextHandle; use platform::macos::font_list::core_foundation::array::CFArray; use platform::macos::font_list::core_foundation::base::CFWrapper; use platform::macos::font_list::core_foundation::string::{CFString, CFStringRef}; @@ -17,13 +16,15 @@ use platform; use core::hashmap::HashMap; -pub struct QuartzFontListHandle { - fctx: QuartzFontContextHandle, +pub struct FontListHandle { + fctx: FontContextHandle, } -pub impl QuartzFontListHandle { - fn new(fctx: &native::FontContextHandle) -> QuartzFontListHandle { - QuartzFontListHandle { fctx: fctx.clone() } +pub impl FontListHandle { + fn new(fctx: &FontContextHandle) -> FontListHandle { + FontListHandle { + fctx: fctx.clone() + } } fn get_available_families(&self) -> FontFamilyMap { @@ -52,7 +53,7 @@ pub impl QuartzFontListHandle { let desc = CFWrapper::wrap_shared(*descref); let font = platform::macos::font_list::core_text::font::new_from_descriptor(&desc, 0.0); - let handle = result::unwrap(QuartzFontHandle::new_from_CTFont(&self.fctx, font)); + let handle = result::unwrap(FontHandle::new_from_CTFont(&self.fctx, font)); debug!("Creating new FontEntry for face: %s", handle.face_name()); let entry = @FontEntry::new(family, handle); diff --git a/src/servo-gfx/servo_gfx.rc b/src/servo-gfx/servo_gfx.rc index 66d697aa465..caeef9d9cdd 100644 --- a/src/servo-gfx/servo_gfx.rc +++ b/src/servo-gfx/servo_gfx.rc @@ -37,10 +37,7 @@ pub mod font_list; // Misc. pub mod opts; -// Pub-uses for multiple implementations. Platform selection happens in -// font.rs, font_list.rs, font_context.rs -pub mod native; - +// Platform-specific implementations. #[path="platform/mod.rs"] pub mod platform; diff --git a/src/servo-gfx/text/harfbuzz/shaper.rs b/src/servo-gfx/text/harfbuzz/shaper.rs index a0f8cda7f0a..52424bb430e 100644 --- a/src/servo-gfx/text/harfbuzz/shaper.rs +++ b/src/servo-gfx/text/harfbuzz/shaper.rs @@ -4,7 +4,8 @@ use geom::Point2D; use geometry::Au; -use font::{Font, FontTable, FontTableMethods, FontTableTag}; +use font::{Font, FontTableMethods, FontTableTag}; +use platform::font::FontTable; use text::glyph::{GlyphStore, GlyphIndex, GlyphData}; use text::shaper::ShaperMethods; From bd15317eae4ae211cec8396923996075db3864f0 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 5 Apr 2013 17:16:30 -0700 Subject: [PATCH 04/11] Remove some module aliases. These aliases were there for old versions of resolve, and are no longer needed. --- src/servo-gfx/font_list.rs | 49 +++++++++++--------- src/servo-gfx/platform/linux/font.rs | 14 +++--- src/servo-gfx/platform/linux/font_context.rs | 2 +- src/servo-gfx/platform/linux/font_list.rs | 6 +-- src/servo-gfx/platform/macos/font.rs | 15 +++--- src/servo-gfx/platform/macos/font_context.rs | 5 +- src/servo-gfx/platform/macos/font_list.rs | 6 +-- src/servo-gfx/servo_gfx.rc | 11 ++--- src/servo-gfx/text/glyph.rs | 33 ++++++------- src/servo-gfx/text/harfbuzz/shaper.rs | 3 +- src/servo-gfx/text/shaper.rs | 11 ++--- src/servo-gfx/text/text_run.rs | 11 +++-- 12 files changed, 84 insertions(+), 82 deletions(-) diff --git a/src/servo-gfx/font_list.rs b/src/servo-gfx/font_list.rs index 7a6ddae6570..cb3da78155f 100644 --- a/src/servo-gfx/font_list.rs +++ b/src/servo-gfx/font_list.rs @@ -1,7 +1,6 @@ //! Implementation of the list of fonts. -use font::{CSSFontWeight, SpecifiedFontStyle}; -use gfx_font::FontHandleMethods; +use font::{CSSFontWeight, FontHandleMethods, SpecifiedFontStyle}; use platform::font::FontHandle; use platform::font_context::FontContextHandle; use platform::font_list::FontListHandle; @@ -16,6 +15,7 @@ trait FontListHandleMethods { fn load_variations_for_family(&self, family: @mut FontFamily); } +/// The platform-independent font list abstraction. pub struct FontList { family_map: FontFamilyMap, handle: FontListHandle, @@ -29,7 +29,7 @@ pub impl FontList { family_map: HashMap::new(), }; list.refresh(fctx); - return list; + list } priv fn refresh(&mut self, _: &FontContextHandle) { @@ -46,19 +46,24 @@ pub impl FontList { family_name: &str, style: &SpecifiedFontStyle) -> Option<@FontEntry> { let family = self.find_family(family_name); - let mut result : Option<@FontEntry> = None; // 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 family.each |fam| { result = fam.find_font_for_style(&self.handle, style); } - let decision = if result.is_some() { "Found" } else { "Couldn't find" }; + let decision = if result.is_some() { + "Found" + } else { + "Couldn't find" + }; + debug!("FontList: %s font face in family[%s] matching style", decision, family_name); - return result; + result } priv fn find_family(&self, family_name: &str) -> Option<@mut FontFamily> { @@ -79,23 +84,23 @@ pub struct FontFamily { entries: ~[@FontEntry], } -pub impl FontFamily { - fn new(family_name: &str) -> FontFamily { +impl FontFamily { + pub fn new(family_name: &str) -> FontFamily { FontFamily { family_name: str::from_slice(family_name), entries: ~[], } } - priv fn load_family_variations(@mut self, list: &FontListHandle) { + fn load_family_variations(@mut self, list: &FontListHandle) { let this : &mut FontFamily = self; // FIXME: borrow checker workaround if this.entries.len() > 0 { return; } list.load_variations_for_family(self); assert!(this.entries.len() > 0); } - fn find_font_for_style(@mut self, list: &FontListHandle, style: &SpecifiedFontStyle) - -> Option<@FontEntry> { + pub fn find_font_for_style(@mut self, list: &FontListHandle, style: &SpecifiedFontStyle) + -> Option<@FontEntry> { self.load_family_variations(list); // TODO(Issue #189): optimize lookup for @@ -104,7 +109,7 @@ pub impl FontFamily { // TODO(Issue #190): if not in the fast path above, do // expensive matching of weights, etc. - let this : &mut FontFamily = self; // FIXME: borrow checker workaround + let this: &mut FontFamily = self; // FIXME: borrow checker workaround for this.entries.each |entry| { if (style.weight.is_bold() == entry.is_bold()) && (style.italic == entry.is_italic()) { @@ -113,15 +118,15 @@ pub impl FontFamily { } } - return None; + None } } -// This struct summarizes an available font's features. In the future, -// this will include fiddly settings such as special font table handling. - -// In the common case, each FontFamily will have a singleton FontEntry, or -// it will have the standard four faces: Normal, Bold, Italic, BoldItalic. +/// This struct summarizes an available font's features. In the future, this will include fiddly +/// settings such as special font table handling. +/// +/// In the common case, each FontFamily will have a singleton FontEntry, or it will have the +/// standard four faces: Normal, Bold, Italic, BoldItalic. pub struct FontEntry { family: @mut FontFamily, face_name: ~str, @@ -131,8 +136,8 @@ pub struct FontEntry { // TODO: array of OpenType features, etc. } -pub impl FontEntry { - fn new(family: @mut FontFamily, handle: FontHandle) -> FontEntry { +impl FontEntry { + pub fn new(family: @mut FontFamily, handle: FontHandle) -> FontEntry { FontEntry { family: family, face_name: handle.face_name(), @@ -142,11 +147,11 @@ pub impl FontEntry { } } - fn is_bold(&self) -> bool { + pub fn is_bold(&self) -> bool { self.weight.is_bold() } - fn is_italic(&self) -> bool { + pub fn is_italic(&self) -> bool { self.italic } } diff --git a/src/servo-gfx/platform/linux/font.rs b/src/servo-gfx/platform/linux/font.rs index 6fa22fad275..9a4a1e3e360 100644 --- a/src/servo-gfx/platform/linux/font.rs +++ b/src/servo-gfx/platform/linux/font.rs @@ -2,12 +2,12 @@ extern mod freetype; +use font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTable, FontTableMethods}; +use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle, FontWeight100}; +use font::{FontWeight200, FontWeight300, FontWeight400, FontWeight500, FontWeight600}; +use font::{FontWeight700, FontWeight800, FontWeight900}; use geometry::Au; use geometry; -use gfx_font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTable, FontTableMethods}; -use gfx_font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle, FontWeight100}; -use gfx_font::{FontWeight200, FontWeight300, FontWeight400, FontWeight500, FontWeight600}; -use gfx_font::{FontWeight700, FontWeight800, FontWeight900}; use platform::font_context::{FreeTypeFontContextHandle, FontContextHandle}; use text::glyph::GlyphIndex; use text::util::{float_to_fixed, fixed_to_float}; @@ -99,7 +99,7 @@ pub impl FreeTypeFontHandle { } pub fn new_from_file_unstyled(fctx: &FreeTypeFontContextHandle, file: ~str) - -> Result { + -> Result { let ft_ctx: FT_Library = fctx.ctx.ctx; if ft_ctx.is_null() { return Err(()); } @@ -270,7 +270,7 @@ impl FontHandleMethods for FreeTypeFontHandle { } } - fn get_table_for_tag(&self, _tag: FontTableTag) -> Option { + fn get_table_for_tag(&self, _: FontTableTag) -> Option { None } } @@ -283,7 +283,6 @@ pub impl FreeTypeFontHandle { } priv fn font_units_to_au(&self, value: float) -> Au { - let face = self.get_face_rec(); // face.size is a *c_void in the bindings, presumably to avoid @@ -300,3 +299,4 @@ pub impl FreeTypeFontHandle { return geometry::from_frac_px(value * x_scale); } } + diff --git a/src/servo-gfx/platform/linux/font_context.rs b/src/servo-gfx/platform/linux/font_context.rs index c809f89d225..24456530d1a 100644 --- a/src/servo-gfx/platform/linux/font_context.rs +++ b/src/servo-gfx/platform/linux/font_context.rs @@ -1,7 +1,7 @@ extern mod freetype; extern mod fontconfig; -use gfx_font::{FontHandle, UsedFontStyle}; +use font::{FontHandle, UsedFontStyle}; use platform::font::FreeTypeFontHandle; use platform::font_context::FontContextHandleMethods; use platform::font_list::path_from_identifier; diff --git a/src/servo-gfx/platform/linux/font_list.rs b/src/servo-gfx/platform/linux/font_list.rs index d7dcc80d1df..809d6ed62fc 100644 --- a/src/servo-gfx/platform/linux/font_list.rs +++ b/src/servo-gfx/platform/linux/font_list.rs @@ -3,9 +3,9 @@ extern mod freetype; extern mod fontconfig; -use gfx_font::FontHandleMethods; -use gfx_font_context::FontContextHandleMethods; -use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap}; +use font::FontHandleMethods; +use font_context::FontContextHandleMethods; +use font_list::{FontEntry, FontFamily, FontFamilyMap}; use platform::font::FreeTypeFontHandle; use platform::font_context::{FontContextHandle, FreeTypeFontContextHandle}; diff --git a/src/servo-gfx/platform/macos/font.rs b/src/servo-gfx/platform/macos/font.rs index 9706aa110ae..d735a637f58 100644 --- a/src/servo-gfx/platform/macos/font.rs +++ b/src/servo-gfx/platform/macos/font.rs @@ -4,11 +4,15 @@ extern mod core_foundation; extern mod core_graphics; extern mod core_text; +use font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTableMethods}; +use font::{FontTableTag, FontWeight100, FontWeight200, FontWeight300, FontWeight400}; +use font::{FontWeight500, FontWeight600, FontWeight700, FontWeight800, FontWeight900}; +use font::{FractionalPixel, SpecifiedFontStyle}; use geometry::Au; -use gfx_font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTableMethods}; -use gfx_font::{FontTableTag, FontWeight100, FontWeight200, FontWeight300, FontWeight400}; -use gfx_font::{FontWeight500, FontWeight600, FontWeight700, FontWeight800, FontWeight900}; -use gfx_font::{FractionalPixel, SpecifiedFontStyle}; +use platform::macos::font_context::FontContextHandle; +use platform; +use text::glyph::GlyphIndex; + use platform::macos::font::core_foundation::base::{CFIndex, CFWrapper}; use platform::macos::font::core_foundation::data::CFData; use platform::macos::font::core_foundation::string::UniChar; @@ -19,9 +23,6 @@ use platform::macos::font::core_text::font::{CTFont, CTFontMethods, CTFontMethod use platform::macos::font::core_text::font_descriptor::{SymbolicTraitAccessors}; use platform::macos::font::core_text::font_descriptor::{TraitAccessors}; use platform::macos::font::core_text::font_descriptor::{kCTFontDefaultOrientation}; -use platform::macos::font_context::FontContextHandle; -use platform; -use text::glyph::GlyphIndex; pub struct FontTable { data: CFData, diff --git a/src/servo-gfx/platform/macos/font_context.rs b/src/servo-gfx/platform/macos/font_context.rs index aacd51cdcb9..a8558fd4bb4 100644 --- a/src/servo-gfx/platform/macos/font_context.rs +++ b/src/servo-gfx/platform/macos/font_context.rs @@ -2,9 +2,8 @@ extern mod core_foundation; extern mod core_graphics; extern mod core_text; -use gfx_font::UsedFontStyle; -use gfx_font_context::FontContextHandleMethods; - +use font::UsedFontStyle; +use font_context::FontContextHandleMethods; use platform::macos::font::FontHandle; use platform; diff --git a/src/servo-gfx/platform/macos/font_list.rs b/src/servo-gfx/platform/macos/font_list.rs index 0c7bbfe4f37..a56f5a5f86c 100644 --- a/src/servo-gfx/platform/macos/font_list.rs +++ b/src/servo-gfx/platform/macos/font_list.rs @@ -1,9 +1,9 @@ extern mod core_foundation; extern mod core_text; -use gfx_font::FontHandleMethods; -use gfx_font_context::FontContextHandleMethods; -use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap}; +use font::FontHandleMethods; +use font_context::FontContextHandleMethods; +use font_list::{FontEntry, FontFamily, FontFamilyMap}; use platform::macos::font::FontHandle; use platform::macos::font_context::FontContextHandle; diff --git a/src/servo-gfx/servo_gfx.rc b/src/servo-gfx/servo_gfx.rc index caeef9d9cdd..614ce9134b3 100644 --- a/src/servo-gfx/servo_gfx.rc +++ b/src/servo-gfx/servo_gfx.rc @@ -1,3 +1,5 @@ +//! Graphics and resource loading module for Servo. + #[link(name = "servo_gfx", vers = "0.1", uuid = "0106bb54-6ea9-45bf-a39e-a738621f15e5", @@ -10,14 +12,6 @@ extern mod http_client; extern mod stb_image; extern mod std; -pub use servo_util = util; -pub use gfx_font = font; -pub use gfx_font_context = font_context; -pub use gfx_font_list = font_list; -pub use servo_gfx_font = font; -pub use servo_gfx_font_list = font_list; -pub use servo_gfx_util = util; - priv mod render_context; // Rendering @@ -71,3 +65,4 @@ pub mod util { pub mod url; pub mod vec; } + diff --git a/src/servo-gfx/text/glyph.rs b/src/servo-gfx/text/glyph.rs index 7a91c5e128d..21005dda13b 100644 --- a/src/servo-gfx/text/glyph.rs +++ b/src/servo-gfx/text/glyph.rs @@ -1,8 +1,10 @@ -use geometry::Au; -use servo_gfx_util::range::Range; -use servo_gfx_util::vec::*; +//! A platform-independent representation of a glyph. +use geometry::Au; use geometry; +use util::range::Range; +use util::vec::*; + use core; use core::cmp::{Ord, Eq}; use core::num::NumCast; @@ -10,20 +12,19 @@ use core::u16; use geom::point::Point2D; use std::sort; - -// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing -// glyph data compactly. -// -// In the common case (reasonable glyph advances, no offsets from the -// font em-box, and one glyph per character), we pack glyph advance, -// glyph id, and some flags into a single u32. -// -// In the uncommon case (multiple glyphs per unicode character, large -// glyph index/advance, or glyph offsets), we pack the glyph count -// into GlyphEntry, and store the other glyph information in -// DetailedGlyphStore. +/// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing +/// glyph data compactly. +/// +/// In the common case (reasonable glyph advances, no offsets from the +/// font em-box, and one glyph per character), we pack glyph advance, +/// glyph id, and some flags into a single u32. +/// +/// In the uncommon case (multiple glyphs per unicode character, large +/// glyph index/advance, or glyph offsets), we pack the glyph count +/// into GlyphEntry, and store the other glyph information in +/// DetailedGlyphStore. struct GlyphEntry { - value : u32 + value: u32 } fn GlyphEntry(value: u32) -> GlyphEntry { GlyphEntry { value: value } } diff --git a/src/servo-gfx/text/harfbuzz/shaper.rs b/src/servo-gfx/text/harfbuzz/shaper.rs index 52424bb430e..8c250b5a038 100644 --- a/src/servo-gfx/text/harfbuzz/shaper.rs +++ b/src/servo-gfx/text/harfbuzz/shaper.rs @@ -4,12 +4,11 @@ use geom::Point2D; use geometry::Au; -use font::{Font, FontTableMethods, FontTableTag}; +use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag}; use platform::font::FontTable; use text::glyph::{GlyphStore, GlyphIndex, GlyphData}; use text::shaper::ShaperMethods; -use gfx_font::{FontHandleMethods, FontTableMethods}; use util::range::Range; diff --git a/src/servo-gfx/text/shaper.rs b/src/servo-gfx/text/shaper.rs index b5f3d322931..429f6b1d9c0 100644 --- a/src/servo-gfx/text/shaper.rs +++ b/src/servo-gfx/text/shaper.rs @@ -1,10 +1,9 @@ -/** -Shaper encapsulates a specific shaper, such as Harfbuzz, -Uniscribe, Pango, or Coretext. +//! Shaper encapsulates a specific shaper, such as Harfbuzz, +/// Uniscribe, Pango, or Coretext. +/// +/// Currently, only harfbuzz bindings are implemented. -Currently, only harfbuzz bindings are implemented. -*/ -use gfx_font::Font; +use font::Font; use text::glyph::GlyphStore; use text::harfbuzz; diff --git a/src/servo-gfx/text/text_run.rs b/src/servo-gfx/text/text_run.rs index 694d8236e77..00a48b892cf 100644 --- a/src/servo-gfx/text/text_run.rs +++ b/src/servo-gfx/text/text_run.rs @@ -1,17 +1,20 @@ +//! The text run abstraction. A text run is a word-wrapped line of text of the same font family, +/// style, and size. + +use font::{Font, FontDescriptor, RunMetrics}; use font_context::FontContext; use geometry::Au; use text::glyph::{BreakTypeNormal, GlyphStore}; -use servo_gfx_font::{Font, FontDescriptor, RunMetrics}; -use servo_gfx_util::range::Range; +use util::range::Range; +/// A text run. pub struct TextRun { text: ~str, font: @mut Font, glyphs: GlyphStore, } -// This is a hack until TextRuns are normally sendable, or -// we instead use ARC everywhere. +/// This is a hack until TextRuns are normally sendable, or we instead use ARC everywhere. pub struct SendableTextRun { text: ~str, font: FontDescriptor, From 9cadf19d1595aea2ccc9bcd0f36c7279cabe1296 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 5 Apr 2013 17:40:04 -0700 Subject: [PATCH 05/11] Refactor glyph.rs to modern Rust coding style --- src/servo-gfx/text/glyph.rs | 318 ++++++++++++++------------ src/servo-gfx/text/harfbuzz/shaper.rs | 20 +- 2 files changed, 180 insertions(+), 158 deletions(-) diff --git a/src/servo-gfx/text/glyph.rs b/src/servo-gfx/text/glyph.rs index 21005dda13b..f5ced97fbdb 100644 --- a/src/servo-gfx/text/glyph.rs +++ b/src/servo-gfx/text/glyph.rs @@ -5,29 +5,79 @@ use geometry; use util::range::Range; use util::vec::*; -use core; use core::cmp::{Ord, Eq}; use core::num::NumCast; use core::u16; +use core; use geom::point::Point2D; use std::sort; -/// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing -/// glyph data compactly. +/// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing glyph data compactly. /// -/// In the common case (reasonable glyph advances, no offsets from the -/// font em-box, and one glyph per character), we pack glyph advance, -/// glyph id, and some flags into a single u32. +/// In the common case (reasonable glyph advances, no offsets from the font em-box, and one glyph +/// per character), we pack glyph advance, glyph id, and some flags into a single u32. /// -/// In the uncommon case (multiple glyphs per unicode character, large -/// glyph index/advance, or glyph offsets), we pack the glyph count -/// into GlyphEntry, and store the other glyph information in -/// DetailedGlyphStore. +/// In the uncommon case (multiple glyphs per unicode character, large glyph index/advance, or +/// glyph offsets), we pack the glyph count into GlyphEntry, and store the other glyph information +/// in DetailedGlyphStore. struct GlyphEntry { value: u32 } -fn GlyphEntry(value: u32) -> GlyphEntry { GlyphEntry { value: value } } +impl GlyphEntry { + fn new(value: u32) -> GlyphEntry { + GlyphEntry { + value: value + } + } + + fn initial() -> GlyphEntry { + GlyphEntry::new(0) + } + + // Creates a GlyphEntry for the common case + fn simple(index: GlyphIndex, advance: Au) -> GlyphEntry { + assert!(is_simple_glyph_id(index)); + assert!(is_simple_advance(advance)); + + let index_mask = index as u32; + let advance_mask = (*advance as u32) << GLYPH_ADVANCE_SHIFT; + + GlyphEntry::new(index_mask | advance_mask | FLAG_IS_SIMPLE_GLYPH) + } + + // Create a GlyphEntry for uncommon case; should be accompanied by + // initialization of the actual DetailedGlyph data in DetailedGlyphStore + fn complex(starts_cluster: bool, starts_ligature: bool, glyph_count: uint) -> GlyphEntry { + assert!(glyph_count <= u16::max_value as uint); + + debug!("creating complex glyph entry: starts_cluster=%?, starts_ligature=%?, \ + glyph_count=%?", + starts_cluster, + starts_ligature, + glyph_count); + + let mut val = FLAG_NOT_MISSING; + + if !starts_cluster { + val |= FLAG_NOT_CLUSTER_START; + } + if !starts_ligature { + val |= FLAG_NOT_LIGATURE_GROUP_START; + } + val |= (glyph_count as u32) << GLYPH_COUNT_SHIFT; + + GlyphEntry::new(val) + } + + /// Create a GlyphEntry for the case where glyphs couldn't be found for the specified + /// character. + fn missing(glyph_count: uint) -> GlyphEntry { + assert!(glyph_count <= u16::max_value as uint); + + GlyphEntry::new((glyph_count as u32) << GLYPH_COUNT_SHIFT) + } +} /// The index of a particular glyph within a font pub type GlyphIndex = u32; @@ -40,19 +90,23 @@ pub enum BreakType { BreakTypeHyphen } -static BREAK_TYPE_NONE : u8 = 0x0u8; -static BREAK_TYPE_NORMAL : u8 = 0x1u8; -static BREAK_TYPE_HYPHEN : u8 = 0x2u8; +static BREAK_TYPE_NONE: u8 = 0x0; +static BREAK_TYPE_NORMAL: u8 = 0x1; +static BREAK_TYPE_HYPHEN: u8 = 0x2; fn break_flag_to_enum(flag: u8) -> BreakType { - if (flag & BREAK_TYPE_NORMAL) != 0 { return BreakTypeNormal; } - if (flag & BREAK_TYPE_HYPHEN) != 0 { return BreakTypeHyphen; } + if (flag & BREAK_TYPE_NORMAL) != 0 { + return BreakTypeNormal; + } + if (flag & BREAK_TYPE_HYPHEN) != 0 { + return BreakTypeHyphen; + } BreakTypeNone } fn break_enum_to_flag(e: BreakType) -> u8 { match e { - BreakTypeNone => BREAK_TYPE_NONE, + BreakTypeNone => BREAK_TYPE_NONE, BreakTypeNormal => BREAK_TYPE_NORMAL, BreakTypeHyphen => BREAK_TYPE_HYPHEN, } @@ -60,16 +114,16 @@ fn break_enum_to_flag(e: BreakType) -> u8 { // TODO: make this more type-safe. -static FLAG_CHAR_IS_SPACE : u32 = 0x10000000u32; +static FLAG_CHAR_IS_SPACE: u32 = 0x10000000; // These two bits store some BREAK_TYPE_* flags -static FLAG_CAN_BREAK_MASK : u32 = 0x60000000u32; -static FLAG_CAN_BREAK_SHIFT : u32 = 29; -static FLAG_IS_SIMPLE_GLYPH : u32 = 0x80000000u32; +static FLAG_CAN_BREAK_MASK: u32 = 0x60000000; +static FLAG_CAN_BREAK_SHIFT: u32 = 29; +static FLAG_IS_SIMPLE_GLYPH: u32 = 0x80000000; // glyph advance; in Au's. -static GLYPH_ADVANCE_MASK : u32 = 0x0FFF0000u32; -static GLYPH_ADVANCE_SHIFT : u32 = 16; -static GLYPH_ID_MASK : u32 = 0x0000FFFFu32; +static GLYPH_ADVANCE_MASK: u32 = 0x0FFF0000; +static GLYPH_ADVANCE_SHIFT: u32 = 16; +static GLYPH_ID_MASK: u32 = 0x0000FFFF; // Non-simple glyphs (more than one glyph per char; missing glyph, // newline, tab, large advance, or nonzero x/y offsets) may have one @@ -80,18 +134,18 @@ static GLYPH_ID_MASK : u32 = 0x0000FFFFu32; // The number of detailed glyphs for this char. If the char couldn't // be mapped to a glyph (!FLAG_NOT_MISSING), then this actually holds // the UTF8 code point instead. -static GLYPH_COUNT_MASK : u32 = 0x00FFFF00u32; -static GLYPH_COUNT_SHIFT : u32 = 8; +static GLYPH_COUNT_MASK: u32 = 0x00FFFF00; +static GLYPH_COUNT_SHIFT: u32 = 8; // N.B. following Gecko, these are all inverted so that a lot of // missing chars can be memset with zeros in one fell swoop. -static FLAG_NOT_MISSING : u32 = 0x00000001u32; -static FLAG_NOT_CLUSTER_START : u32 = 0x00000002u32; -static FLAG_NOT_LIGATURE_GROUP_START : u32 = 0x00000004u32; +static FLAG_NOT_MISSING: u32 = 0x00000001; +static FLAG_NOT_CLUSTER_START: u32 = 0x00000002; +static FLAG_NOT_LIGATURE_GROUP_START: u32 = 0x00000004; -static FLAG_CHAR_IS_TAB : u32 = 0x00000008u32; -static FLAG_CHAR_IS_NEWLINE : u32 = 0x00000010u32; -static FLAG_CHAR_IS_LOW_SURROGATE : u32 = 0x00000020u32; -static CHAR_IDENTITY_FLAGS_MASK : u32 = 0x00000038u32; +static FLAG_CHAR_IS_TAB: u32 = 0x00000008; +static FLAG_CHAR_IS_NEWLINE: u32 = 0x00000010; +static FLAG_CHAR_IS_LOW_SURROGATE: u32 = 0x00000020; +static CHAR_IDENTITY_FLAGS_MASK: u32 = 0x00000038; fn is_simple_glyph_id(glyphId: GlyphIndex) -> bool { ((glyphId as u32) & GLYPH_ID_MASK) == glyphId @@ -104,73 +158,20 @@ fn is_simple_advance(advance: Au) -> bool { type DetailedGlyphCount = u16; -fn InitialGlyphEntry() -> GlyphEntry { - GlyphEntry { value: 0 } -} - -// Creates a GlyphEntry for the common case -fn SimpleGlyphEntry(index: GlyphIndex, advance: Au) -> GlyphEntry { - assert!(is_simple_glyph_id(index)); - assert!(is_simple_advance(advance)); - - let index_mask = index as u32; - let advance_mask = (*advance as u32) << GLYPH_ADVANCE_SHIFT; - - GlyphEntry { - value: index_mask | advance_mask | FLAG_IS_SIMPLE_GLYPH - } -} - -// Create a GlyphEntry for uncommon case; should be accompanied by -// initialization of the actual DetailedGlyph data in DetailedGlyphStore -fn ComplexGlyphEntry(startsCluster: bool, startsLigature: bool, glyphCount: uint) -> GlyphEntry { - assert!(glyphCount <= u16::max_value as uint); - - debug!("Creating complex glyph entry: startsCluster=%?, startsLigature=%?, glyphCount=%?", - startsCluster, startsLigature, glyphCount); - - let mut val = FLAG_NOT_MISSING; - - if !startsCluster { - val |= FLAG_NOT_CLUSTER_START; - } - if !startsLigature { - val |= FLAG_NOT_LIGATURE_GROUP_START; - } - val |= (glyphCount as u32) << GLYPH_COUNT_SHIFT; - - GlyphEntry { - value: val - } -} - -// Create a GlyphEntry for the case where glyphs couldn't be found -// for the specified character. -fn MissingGlyphsEntry(glyphCount: uint) -> GlyphEntry { - assert!(glyphCount <= u16::max_value as uint); - - GlyphEntry { - value: (glyphCount as u32) << GLYPH_COUNT_SHIFT - } -} - // Getters and setters for GlyphEntry. Setter methods are functional, // because GlyphEntry is immutable and only a u32 in size. impl GlyphEntry { // getter methods #[inline(always)] fn advance(&self) -> Au { - //assert!(self.is_simple()); NumCast::from((self.value & GLYPH_ADVANCE_MASK) >> GLYPH_ADVANCE_SHIFT) } fn index(&self) -> GlyphIndex { - //assert!(self.is_simple()); self.value & GLYPH_ID_MASK } fn offset(&self) -> Point2D { - //assert!(self.is_simple()); Point2D(Au(0), Au(0)) } @@ -204,30 +205,30 @@ impl GlyphEntry { // setter methods #[inline(always)] fn set_char_is_space(&self) -> GlyphEntry { - GlyphEntry(self.value | FLAG_CHAR_IS_SPACE) + GlyphEntry::new(self.value | FLAG_CHAR_IS_SPACE) } #[inline(always)] fn set_char_is_tab(&self) -> GlyphEntry { assert!(!self.is_simple()); - GlyphEntry(self.value | FLAG_CHAR_IS_TAB) + GlyphEntry::new(self.value | FLAG_CHAR_IS_TAB) } #[inline(always)] fn set_char_is_newline(&self) -> GlyphEntry { assert!(!self.is_simple()); - GlyphEntry(self.value | FLAG_CHAR_IS_NEWLINE) + GlyphEntry::new(self.value | FLAG_CHAR_IS_NEWLINE) } #[inline(always)] fn set_can_break_before(&self, e: BreakType) -> GlyphEntry { let flag = (break_enum_to_flag(e) as u32) << FLAG_CAN_BREAK_SHIFT; - GlyphEntry(self.value | flag) + GlyphEntry::new(self.value | flag) } // helper methods - /*priv*/ fn glyph_count(&self) -> u16 { + fn glyph_count(&self) -> u16 { assert!(!self.is_simple()); ((self.value & GLYPH_COUNT_MASK) >> GLYPH_COUNT_SHIFT) as u16 } @@ -238,7 +239,7 @@ impl GlyphEntry { } #[inline(always)] - /*priv*/ fn has_flag(&self, flag: u32) -> bool { + fn has_flag(&self, flag: u32) -> bool { (self.value & flag) != 0 } @@ -258,13 +259,13 @@ struct DetailedGlyph { offset: Point2D } - -fn DetailedGlyph(index: GlyphIndex, - advance: Au, offset: Point2D) -> DetailedGlyph { - DetailedGlyph { - index: index, - advance: advance, - offset: offset +impl DetailedGlyph { + fn new(index: GlyphIndex, advance: Au, offset: Point2D) -> DetailedGlyph { + DetailedGlyph { + index: index, + advance: advance, + offset: offset + } } } @@ -301,15 +302,15 @@ struct DetailedGlyphStore { lookup_is_sorted: bool, } -fn DetailedGlyphStore() -> DetailedGlyphStore { - DetailedGlyphStore { - detail_buffer: ~[], // TODO: default size? - detail_lookup: ~[], - lookup_is_sorted: false - } -} - impl DetailedGlyphStore { + fn new() -> DetailedGlyphStore { + DetailedGlyphStore { + detail_buffer: ~[], // TODO: default size? + detail_lookup: ~[], + lookup_is_sorted: false + } + } + fn add_detailed_glyphs_for_entry(&mut self, entry_offset: uint, glyphs: &[DetailedGlyph]) { let entry = DetailedGlyphRecord { entry_offset: entry_offset, @@ -334,7 +335,8 @@ impl DetailedGlyphStore { self.lookup_is_sorted = false; } - fn get_detailed_glyphs_for_entry(&self, entry_offset: uint, count: u16) -> &'self [DetailedGlyph] { + fn get_detailed_glyphs_for_entry(&self, entry_offset: uint, count: u16) + -> &'self [DetailedGlyph] { debug!("Requesting detailed glyphs[n=%u] for entry[off=%u]", count as uint, entry_offset); // FIXME: Is this right? --pcwalton @@ -376,7 +378,7 @@ impl DetailedGlyphStore { }; // FIXME: This is a workaround for borrow of self.detail_lookup not getting inferred. - let records : &[DetailedGlyphRecord] = self.detail_lookup; + let records: &[DetailedGlyphRecord] = self.detail_lookup; match records.binary_search_index(&key) { None => fail!(~"Invalid index not found in detailed glyph lookup table!"), Some(i) => { @@ -396,7 +398,7 @@ impl DetailedGlyphStore { // immutable locations thus don't play well with freezing. // Thar be dragons here. You have been warned. (Tips accepted.) - let mut unsorted_records : ~[DetailedGlyphRecord] = ~[]; + let mut unsorted_records: ~[DetailedGlyphRecord] = ~[]; core::util::swap(&mut self.detail_lookup, &mut unsorted_records); let mut mut_records : ~[DetailedGlyphRecord] = unsorted_records; sort::quick_sort3(mut_records); @@ -418,24 +420,27 @@ pub struct GlyphData { ligature_start: bool, } -pub fn GlyphData(index: GlyphIndex, - advance: Au, - offset: Option>, - is_missing: bool, - cluster_start: bool, - ligature_start: bool) -> GlyphData { - let _offset = match offset { - None => geometry::zero_point(), - Some(o) => o - }; +impl GlyphData { + pub fn new(index: GlyphIndex, + advance: Au, + offset: Option>, + is_missing: bool, + cluster_start: bool, + ligature_start: bool) + -> GlyphData { + let offset = match offset { + None => geometry::zero_point(), + Some(o) => o + }; - GlyphData { - index: index, - advance: advance, - offset: _offset, - is_missing: is_missing, - cluster_start: cluster_start, - ligature_start: ligature_start, + GlyphData { + index: index, + advance: advance, + offset: offset, + is_missing: is_missing, + cluster_start: cluster_start, + ligature_start: ligature_start, + } } } @@ -452,7 +457,9 @@ impl<'self> GlyphInfo<'self> { fn index(self) -> GlyphIndex { match self { SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].index(), - DetailGlyphInfo(store, entry_i, detail_j) => store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).index + DetailGlyphInfo(store, entry_i, detail_j) => { + store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).index + } } } @@ -460,14 +467,18 @@ impl<'self> GlyphInfo<'self> { fn advance(self) -> Au { match self { SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].advance(), - DetailGlyphInfo(store, entry_i, detail_j) => store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).advance + DetailGlyphInfo(store, entry_i, detail_j) => { + store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).advance + } } } fn offset(self) -> Option> { match self { SimpleGlyphInfo(_, _) => None, - DetailGlyphInfo(store, entry_i, detail_j) => Some(store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).offset) + DetailGlyphInfo(store, entry_i, detail_j) => { + Some(store.detail_store.get_detailed_glyph_with_index(entry_i, detail_j).offset) + } } } @@ -488,7 +499,6 @@ impl<'self> GlyphInfo<'self> { // Public data structure and API for storing and retrieving glyph data pub struct GlyphStore { - // we use a DVec here instead of a mut vec, since this is much safer. entry_buffer: ~[GlyphEntry], detail_store: DetailedGlyphStore, } @@ -500,8 +510,8 @@ pub impl GlyphStore { assert!(length > 0); GlyphStore { - entry_buffer: vec::from_elem(length, InitialGlyphEntry()), - detail_store: DetailedGlyphStore(), + entry_buffer: vec::from_elem(length, GlyphEntry::initial()), + detail_store: DetailedGlyphStore::new(), } } @@ -510,7 +520,6 @@ pub impl GlyphStore { } fn add_glyph_for_char_index(&mut self, i: uint, data: &GlyphData) { - fn glyph_is_compressible(data: &GlyphData) -> bool { is_simple_glyph_id(data.index) && is_simple_advance(data.advance) @@ -522,12 +531,12 @@ pub impl GlyphStore { assert!(i < self.entry_buffer.len()); let entry = match (data.is_missing, glyph_is_compressible(data)) { - (true, _) => MissingGlyphsEntry(1), - (false, true) => { SimpleGlyphEntry(data.index, data.advance) }, + (true, _) => GlyphEntry::missing(1), + (false, true) => GlyphEntry::simple(data.index, data.advance), (false, false) => { - let glyph = [DetailedGlyph(data.index, data.advance, data.offset)]; + let glyph = [DetailedGlyph::new(data.index, data.advance, data.offset)]; self.detail_store.add_detailed_glyphs_for_entry(i, glyph); - ComplexGlyphEntry(data.cluster_start, data.ligature_start, 1) + GlyphEntry::complex(data.cluster_start, data.ligature_start, 1) } }.adapt_character_flags_of_entry(self.entry_buffer[i]); @@ -542,18 +551,18 @@ pub impl GlyphStore { let first_glyph_data = data_for_glyphs[0]; let entry = match first_glyph_data.is_missing { - true => MissingGlyphsEntry(glyph_count), + true => GlyphEntry::missing(glyph_count), false => { let glyphs_vec = vec::from_fn(glyph_count, |i| { - DetailedGlyph(data_for_glyphs[i].index, - data_for_glyphs[i].advance, - data_for_glyphs[i].offset) + DetailedGlyph::new(data_for_glyphs[i].index, + data_for_glyphs[i].advance, + data_for_glyphs[i].offset) }); self.detail_store.add_detailed_glyphs_for_entry(i, glyphs_vec); - ComplexGlyphEntry(first_glyph_data.cluster_start, - first_glyph_data.ligature_start, - glyph_count) + GlyphEntry::complex(first_glyph_data.cluster_start, + first_glyph_data.ligature_start, + glyph_count) } }.adapt_character_flags_of_entry(self.entry_buffer[i]); @@ -566,13 +575,16 @@ pub impl GlyphStore { fn add_nonglyph_for_char_index(&mut self, i: uint, cluster_start: bool, ligature_start: bool) { assert!(i < self.entry_buffer.len()); - let entry = ComplexGlyphEntry(cluster_start, ligature_start, 0); + let entry = GlyphEntry::complex(cluster_start, ligature_start, 0); debug!("adding spacer for chracter without associated glyph[idx=%u]", i); self.entry_buffer[i] = entry; } - fn iter_glyphs_for_char_index(&self, i: uint, cb: &fn(uint, &GlyphInfo<'self>) -> bool) -> bool { + fn iter_glyphs_for_char_index(&self, + i: uint, + cb: &fn(uint, &GlyphInfo<'self>) -> bool) + -> bool { assert!(i < self.entry_buffer.len()); let entry = &self.entry_buffer[i]; @@ -590,7 +602,7 @@ pub impl GlyphStore { } } } - return true; + true } fn iter_glyphs_for_char_range(&self, range: &Range, cb: &fn(uint, &GlyphInfo<'self>) -> bool) { @@ -604,13 +616,17 @@ pub impl GlyphStore { } for range.eachi |i| { - if !self.iter_glyphs_for_char_index(i, cb) { break; } - } + if !self.iter_glyphs_for_char_index(i, cb) { + break; + } + } } fn iter_all_glyphs(&self, cb: &fn(uint, &GlyphInfo<'self>) -> bool) { for uint::range(0, self.entry_buffer.len()) |i| { - if !self.iter_glyphs_for_char_index(i, cb) { break; } + if !self.iter_glyphs_for_char_index(i, cb) { + break; + } } } diff --git a/src/servo-gfx/text/harfbuzz/shaper.rs b/src/servo-gfx/text/harfbuzz/shaper.rs index 8c250b5a038..1f26fc76436 100644 --- a/src/servo-gfx/text/harfbuzz/shaper.rs +++ b/src/servo-gfx/text/harfbuzz/shaper.rs @@ -400,7 +400,12 @@ pub impl HarfbuzzShaper { // (i.e., pretend there are no combining character sequences). // 1-to-1 mapping of character to glyph also treated as ligature start. let shape = glyph_data.get_entry_for_glyph(glyph_span.begin(), &mut y_pos); - let data = GlyphData(shape.codepoint, shape.advance, shape.offset, false, true, true); + let data = GlyphData::new(shape.codepoint, + shape.advance, + shape.offset, + false, + true, + true); glyphs.add_glyph_for_char_index(char_idx, &data); } else { // collect all glyphs to be assigned to the first character. @@ -408,12 +413,13 @@ pub impl HarfbuzzShaper { for glyph_span.eachi |glyph_i| { let shape = glyph_data.get_entry_for_glyph(glyph_i, &mut y_pos); - datas.push(GlyphData(shape.codepoint, - shape.advance, - shape.offset, - false, // not missing - true, // treat as cluster start - glyph_i > glyph_span.begin())); // all but first are ligature continuations + datas.push(GlyphData::new(shape.codepoint, + shape.advance, + shape.offset, + false, // not missing + true, // treat as cluster start + glyph_i > glyph_span.begin())); + // all but first are ligature continuations } // now add the detailed glyph entry. From bbf1582f8e0fa671e2f680a1a87ff9ba1b2d9821 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 5 Apr 2013 18:03:33 -0700 Subject: [PATCH 06/11] Refactor the HarfBuzz shaper to be in line with modern Rust style --- src/servo-gfx/text/harfbuzz/shaper.rs | 310 ++++++++++++++------------ 1 file changed, 168 insertions(+), 142 deletions(-) diff --git a/src/servo-gfx/text/harfbuzz/shaper.rs b/src/servo-gfx/text/harfbuzz/shaper.rs index 1f26fc76436..c581263e43e 100644 --- a/src/servo-gfx/text/harfbuzz/shaper.rs +++ b/src/servo-gfx/text/harfbuzz/shaper.rs @@ -1,62 +1,59 @@ +//! Performs shaping with HarfBuzz. + extern mod harfbuzz; -use geom::Point2D; - -use geometry::Au; - use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag}; +use geometry::Au; use platform::font::FontTable; - use text::glyph::{GlyphStore, GlyphIndex, GlyphData}; use text::shaper::ShaperMethods; - +use text::util::{float_to_fixed, fixed_to_float, fixed_to_rounded_int}; use util::range::Range; +use core::cast::transmute; use core::libc::{c_uint, c_int, c_void, c_char}; +use core::ptr::null; use core::util::ignore; - -use text::harfbuzz::shaper::harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR, hb_blob_t}; -use text::harfbuzz::shaper::harfbuzz::{hb_face_t, hb_font_t}; -use text::harfbuzz::shaper::harfbuzz::{hb_font_funcs_t, hb_buffer_t, hb_codepoint_t, hb_bool_t}; -use text::harfbuzz::shaper::harfbuzz::{hb_glyph_position_t}; -use text::harfbuzz::shaper::harfbuzz::{hb_glyph_info_t, hb_position_t}; -use text::harfbuzz::shaper::harfbuzz::bindgen::hb_blob_create; -use text::harfbuzz::shaper::harfbuzz::bindgen::hb_face_destroy; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_create, hb_font_destroy}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_create}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_destroy}; +use geom::Point2D; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_blob_create, hb_face_create_for_tables}; use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_add_utf8, hb_shape}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_create}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_destroy, hb_buffer_add_utf8}; use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_get_glyph_infos}; use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_get_glyph_positions}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_ppem}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_scale}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_get_glyph_positions}; use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_set_direction}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_set_direction}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_face_destroy, hb_font_create}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_face_destroy}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_create, hb_font_destroy}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_destroy, hb_buffer_create}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_create, hb_font_funcs_destroy}; use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_create}; use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_destroy}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_funcs}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func}; use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_set_glyph_func}; - +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_set_glyph_func}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_funcs}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_funcs}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_ppem, hb_font_set_scale}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_ppem}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_scale}; +use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_shape, hb_buffer_get_glyph_infos}; +use text::harfbuzz::shaper::harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR, hb_blob_t}; use text::harfbuzz::shaper::harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR}; use text::harfbuzz::shaper::harfbuzz::{hb_blob_t, hb_face_t, hb_font_t, hb_font_funcs_t}; use text::harfbuzz::shaper::harfbuzz::{hb_buffer_t, hb_codepoint_t, hb_bool_t}; +use text::harfbuzz::shaper::harfbuzz::{hb_face_t, hb_font_t}; +use text::harfbuzz::shaper::harfbuzz::{hb_font_funcs_t, hb_buffer_t, hb_codepoint_t, hb_bool_t}; +use text::harfbuzz::shaper::harfbuzz::{hb_glyph_info_t, hb_position_t}; use text::harfbuzz::shaper::harfbuzz::{hb_glyph_position_t, hb_glyph_info_t}; +use text::harfbuzz::shaper::harfbuzz::{hb_glyph_position_t}; use text::harfbuzz::shaper::harfbuzz::{hb_position_t, hb_tag_t}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_blob_create, - hb_face_create_for_tables, hb_face_destroy, - hb_font_create, hb_font_destroy, - hb_buffer_create, hb_buffer_destroy, - hb_buffer_add_utf8, hb_shape, - hb_buffer_get_glyph_infos, - hb_buffer_get_glyph_positions, - hb_font_set_ppem, hb_font_set_scale, - hb_buffer_set_direction, - hb_font_funcs_create, hb_font_funcs_destroy, - hb_font_set_funcs, - hb_font_funcs_set_glyph_h_advance_func, - hb_font_funcs_set_glyph_func}; -use text::util::{float_to_fixed, fixed_to_float, fixed_to_rounded_int}; +static NO_GLYPH: i32 = -1; +static CONTINUATION_BYTE: i32 = -2; pub struct ShapedGlyphData { count: uint, @@ -71,15 +68,15 @@ pub struct ShapedGlyphEntry { offset: Option>, } -pub impl ShapedGlyphData { - fn new(buffer: *hb_buffer_t) -> ShapedGlyphData { +impl ShapedGlyphData { + pub fn new(buffer: *hb_buffer_t) -> ShapedGlyphData { unsafe { - let glyph_count = 0 as c_uint; - let glyph_infos = hb_buffer_get_glyph_infos(buffer, ptr::to_unsafe_ptr(&glyph_count)); + let glyph_count = 0; + let glyph_infos = hb_buffer_get_glyph_infos(buffer, &glyph_count); let glyph_count = glyph_count as uint; assert!(glyph_infos.is_not_null()); - let pos_count = 0 as c_uint; - let pos_infos = hb_buffer_get_glyph_positions(buffer, ptr::to_unsafe_ptr(&pos_count)); + let pos_count = 0; + let pos_infos = hb_buffer_get_glyph_positions(buffer, &pos_count); assert!(pos_infos.is_not_null()); assert!(glyph_count == pos_count as uint); @@ -92,7 +89,7 @@ pub impl ShapedGlyphData { } #[inline(always)] - priv fn byte_offset_of_glyph(&self, i: uint) -> uint { + fn byte_offset_of_glyph(&self, i: uint) -> uint { assert!(i < self.count); let glyph_info_i = ptr::offset(self.glyph_infos, i); @@ -101,31 +98,38 @@ pub impl ShapedGlyphData { } } - fn len(&self) -> uint { self.count } + pub fn len(&self) -> uint { + self.count + } - // Returns shaped glyph data for one glyph, and updates the y-position of the pen. - fn get_entry_for_glyph(&self, i: uint, y_pos: &mut Au) -> ShapedGlyphEntry { + /// Returns shaped glyph data for one glyph, and updates the y-position of the pen. + pub fn get_entry_for_glyph(&self, i: uint, y_pos: &mut Au) -> ShapedGlyphEntry { assert!(i < self.count); - let glyph_info_i = ptr::offset(self.glyph_infos, i); - let pos_info_i = ptr::offset(self.pos_infos, i); - let x_offset = unsafe { Au::from_frac_px(HarfbuzzShaper::fixed_to_float((*pos_info_i).x_offset)) }; - let y_offset = unsafe { Au::from_frac_px(HarfbuzzShaper::fixed_to_float((*pos_info_i).y_offset)) }; - let x_advance = unsafe { Au::from_frac_px(HarfbuzzShaper::fixed_to_float((*pos_info_i).x_advance)) }; - let y_advance = unsafe { Au::from_frac_px(HarfbuzzShaper::fixed_to_float((*pos_info_i).y_advance)) }; - let offset = if x_offset == Au(0) - && y_offset == Au(0) - && y_advance == Au(0) { None } - else { - // adjust the pen.. - if y_advance > Au(0) { - *y_pos -= y_advance; - } - - Some(Point2D(x_offset, *y_pos - y_offset)) - }; - unsafe { + let glyph_info_i = ptr::offset(self.glyph_infos, i); + let pos_info_i = ptr::offset(self.pos_infos, i); + let x_offset = HarfbuzzShaper::fixed_to_float((*pos_info_i).x_offset); + let y_offset = HarfbuzzShaper::fixed_to_float((*pos_info_i).y_offset); + let x_advance = HarfbuzzShaper::fixed_to_float((*pos_info_i).x_advance); + let y_advance = HarfbuzzShaper::fixed_to_float((*pos_info_i).y_advance); + + let x_offset = Au::from_frac_px(x_offset); + let y_offset = Au::from_frac_px(y_offset); + let x_advance = Au::from_frac_px(x_advance); + let y_advance = Au::from_frac_px(y_advance); + + let offset = if x_offset == Au(0) && y_offset == Au(0) && y_advance == Au(0) { + None + } else { + // adjust the pen.. + if y_advance > Au(0) { + *y_pos -= y_advance; + } + + Some(Point2D(x_offset, *y_pos - y_offset)) + }; + ShapedGlyphEntry { cluster: (*glyph_info_i).cluster as uint, codepoint: (*glyph_info_i).codepoint as GlyphIndex, @@ -157,102 +161,106 @@ impl Drop for HarfbuzzShaper { } } -pub impl HarfbuzzShaper { +impl HarfbuzzShaper { pub fn new(font: @mut Font) -> HarfbuzzShaper { - let hb_face: *hb_face_t = hb_face_create_for_tables(get_font_table_func, ptr::to_unsafe_ptr(font) as *c_void, ptr::null()); - let hb_font: *hb_font_t = hb_font_create(hb_face); - // Set points-per-em. if zero, performs no hinting in that direction. - let pt_size = font.style.pt_size; - hb_font_set_ppem(hb_font, pt_size as c_uint, pt_size as c_uint); - // Set scaling. Note that this takes 16.16 fixed point. - hb_font_set_scale(hb_font, - HarfbuzzShaper::float_to_fixed(pt_size) as c_int, - HarfbuzzShaper::float_to_fixed(pt_size) as c_int); - - // configure static function callbacks. - // NB. This funcs structure could be reused globally, as it never changes. - let hb_funcs: *hb_font_funcs_t = hb_font_funcs_create(); - hb_font_funcs_set_glyph_func(hb_funcs, glyph_func, ptr::null(), ptr::null()); - hb_font_funcs_set_glyph_h_advance_func(hb_funcs, glyph_h_advance_func, ptr::null(), ptr::null()); unsafe { - let font_data: *c_void = ptr::addr_of(font) as *c_void; - hb_font_set_funcs(hb_font, hb_funcs, font_data, ptr::null()); - }; + let font_ptr: *mut Font = &mut *font; + let hb_face: *hb_face_t = hb_face_create_for_tables(get_font_table_func, + font_ptr as *c_void, + null()); + let hb_font: *hb_font_t = hb_font_create(hb_face); - HarfbuzzShaper { - font: font, - hb_face: hb_face, - hb_font: hb_font, - hb_funcs: hb_funcs, + // Set points-per-em. if zero, performs no hinting in that direction. + let pt_size = font.style.pt_size; + hb_font_set_ppem(hb_font, pt_size as c_uint, pt_size as c_uint); + + // Set scaling. Note that this takes 16.16 fixed point. + hb_font_set_scale(hb_font, + HarfbuzzShaper::float_to_fixed(pt_size) as c_int, + HarfbuzzShaper::float_to_fixed(pt_size) as c_int); + + // configure static function callbacks. + // NB. This funcs structure could be reused globally, as it never changes. + let hb_funcs: *hb_font_funcs_t = hb_font_funcs_create(); + hb_font_funcs_set_glyph_func(hb_funcs, glyph_func, null(), null()); + hb_font_funcs_set_glyph_h_advance_func(hb_funcs, glyph_h_advance_func, null(), null()); + hb_font_set_funcs(hb_font, hb_funcs, font_ptr as *c_void, null()); + + HarfbuzzShaper { + font: font, + hb_face: hb_face, + hb_font: hb_font, + hb_funcs: hb_funcs, + } } } - priv fn float_to_fixed(f: float) -> i32 { + fn float_to_fixed(f: float) -> i32 { float_to_fixed(16, f) } - priv fn fixed_to_float(i: hb_position_t) -> float { + fn fixed_to_float(i: hb_position_t) -> float { fixed_to_float(16, i) } - priv fn fixed_to_rounded_int(f: hb_position_t) -> int { + fn fixed_to_rounded_int(f: hb_position_t) -> int { fixed_to_rounded_int(16, f) } } impl ShaperMethods for HarfbuzzShaper { - /** - Calculate the layout metrics associated with a some given text - when rendered in a specific font. - */ + /// Calculate the layout metrics associated with the given text when rendered in a specific + /// font. fn shape_text(&self, text: &str, glyphs: &mut GlyphStore) { let hb_buffer: *hb_buffer_t = hb_buffer_create(); hb_buffer_set_direction(hb_buffer, HB_DIRECTION_LTR); // Using as_buf because it never does a copy - we don't need the trailing null - str::as_buf(text, |ctext: *u8, _l: uint| { + do str::as_buf(text) |ctext: *u8, _: uint| { hb_buffer_add_utf8(hb_buffer, ctext as *c_char, text.len() as c_int, - 0 as c_uint, + 0, text.len() as c_int); - }); + } - hb_shape(self.hb_font, hb_buffer, ptr::null(), 0 as c_uint); + hb_shape(self.hb_font, hb_buffer, null(), 0); self.save_glyph_results(text, glyphs, hb_buffer); hb_buffer_destroy(hb_buffer); } } -pub impl HarfbuzzShaper { - - priv fn save_glyph_results(&self, text: &str, glyphs: &mut GlyphStore, buffer: *hb_buffer_t) { +impl HarfbuzzShaper { + fn save_glyph_results(&self, text: &str, glyphs: &mut GlyphStore, buffer: *hb_buffer_t) { let glyph_data = ShapedGlyphData::new(buffer); let glyph_count = glyph_data.len(); let byte_max = text.len(); let char_max = str::char_len(text); + // GlyphStore records are indexed by character, not byte offset. // so, we must be careful to increment this when saving glyph entries. let mut char_idx = 0; assert!(glyph_count <= char_max); - debug!("Shaped text[char count=%u], got back %u glyph info records.", char_max, glyph_count); + debug!("Shaped text[char count=%u], got back %u glyph info records.", + char_max, + glyph_count); + if char_max != glyph_count { - debug!("NOTE: Since these are not equal, we probably have been given some complex glyphs."); + debug!("NOTE: Since these are not equal, we probably have been given some complex \ + glyphs."); } // make map of what chars have glyphs - static NO_GLYPH : i32 = -1; - static CONTINUATION_BYTE : i32 = -2; - let mut byteToGlyph : ~[i32]; + let mut byteToGlyph: ~[i32]; // fast path: all chars are single-byte. if byte_max == char_max { byteToGlyph = vec::from_elem(byte_max, NO_GLYPH); } else { byteToGlyph = vec::from_elem(byte_max, CONTINUATION_BYTE); - let mut i = 0u; + let mut i = 0; while i < byte_max { byteToGlyph[i] = NO_GLYPH; let range = str::char_range_at(text, i); @@ -268,8 +276,11 @@ pub impl HarfbuzzShaper { if loc < byte_max { assert!(byteToGlyph[loc] != CONTINUATION_BYTE); byteToGlyph[loc] = i as i32; + } else { + debug!("ERROR: tried to set out of range byteToGlyph: idx=%u, glyph idx=%u", + loc, + i); } - else { debug!("ERROR: tried to set out of range byteToGlyph: idx=%u, glyph idx=%u", loc, i); } debug!("%u -> %u", i, loc); } @@ -283,14 +294,15 @@ pub impl HarfbuzzShaper { } // some helpers - let mut glyph_span : Range = Range::empty(); + let mut glyph_span: Range = Range::empty(); // this span contains first byte of first char, to last byte of last char in range. // so, end() points to first byte of last+1 char, if it's less than byte_max. - let mut char_byte_span : Range = Range::empty(); + let mut char_byte_span: Range = Range::empty(); let mut y_pos = Au(0); // main loop over each glyph. each iteration usually processes 1 glyph and 1+ chars. - // in cases with complex glyph-character assocations, 2+ glyphs and 1+ chars can be processed. + // in cases with complex glyph-character assocations, 2+ glyphs and 1+ chars can be + // processed. while glyph_span.begin() < glyph_count { // start by looking at just one glyph. glyph_span.extend_by(1); @@ -309,8 +321,10 @@ pub impl HarfbuzzShaper { debug!("Processing char byte span: off=%u, len=%u for glyph idx=%u", char_byte_span.begin(), char_byte_span.length(), glyph_span.begin()); - while char_byte_span.end() != byte_max && byteToGlyph[char_byte_span.end()] == NO_GLYPH { - debug!("Extending char byte span to include byte offset=%u with no associated glyph", char_byte_span.end()); + while char_byte_span.end() != byte_max && + byteToGlyph[char_byte_span.end()] == NO_GLYPH { + debug!("Extending char byte span to include byte offset=%u with no associated \ + glyph", char_byte_span.end()); let range = str::char_range_at(text, char_byte_span.end()); ignore(range.ch); char_byte_span.extend_to(range.next); @@ -327,7 +341,8 @@ pub impl HarfbuzzShaper { if max_glyph_idx > glyph_span.end() { glyph_span.extend_to(max_glyph_idx); - debug!("Extended glyph span (off=%u, len=%u) to cover char byte span's max glyph index", + debug!("Extended glyph span (off=%u, len=%u) to cover char byte span's max \ + glyph index", glyph_span.begin(), glyph_span.length()); } @@ -338,7 +353,8 @@ pub impl HarfbuzzShaper { // if no glyphs were found yet, extend the char byte range more. if glyph_span.length() == 0 { loop; } - debug!("Complex (multi-glyph to multi-char) association found. This case probably doesn't work."); + debug!("Complex (multi-glyph to multi-char) association found. This case \ + probably doesn't work."); let mut all_glyphs_are_within_cluster: bool = true; do glyph_span.eachi |j| { @@ -349,7 +365,8 @@ pub impl HarfbuzzShaper { all_glyphs_are_within_cluster // if true, keep checking. else, stop. } - debug!("All glyphs within char_byte_span cluster?: %?", all_glyphs_are_within_cluster); + debug!("All glyphs within char_byte_span cluster?: %?", + all_glyphs_are_within_cluster); // found a valid range; stop extending char_span. if all_glyphs_are_within_cluster { break; } @@ -371,10 +388,11 @@ pub impl HarfbuzzShaper { // gspan: [-] // cspan: [-] // covsp: [---------------] + let mut covered_byte_span = copy char_byte_span; // extend, clipping at end of text range. while covered_byte_span.end() < byte_max - && byteToGlyph[covered_byte_span.end()] == NO_GLYPH { + && byteToGlyph[covered_byte_span.end()] == NO_GLYPH { let range = str::char_range_at(text, covered_byte_span.end()); ignore(range.ch); covered_byte_span.extend_to(range.next); @@ -413,8 +431,8 @@ pub impl HarfbuzzShaper { for glyph_span.eachi |glyph_i| { let shape = glyph_data.get_entry_for_glyph(glyph_i, &mut y_pos); - datas.push(GlyphData::new(shape.codepoint, - shape.advance, + datas.push(GlyphData::new(shape.codepoint, + shape.advance, shape.offset, false, // not missing true, // treat as cluster start @@ -452,26 +470,32 @@ pub impl HarfbuzzShaper { } /// Callbacks from Harfbuzz when font map and glyph advance lookup needed. -extern fn glyph_func(_font: *hb_font_t, +extern fn glyph_func(_: *hb_font_t, font_data: *c_void, unicode: hb_codepoint_t, - _variant_selector: hb_codepoint_t, + _: hb_codepoint_t, glyph: *mut hb_codepoint_t, - _user_data: *c_void) -> hb_bool_t { + _: *c_void) + -> hb_bool_t { let font: *Font = font_data as *Font; assert!(font.is_not_null()); + unsafe { - return match (*font).glyph_index(unicode as char) { - Some(g) => { *glyph = g as hb_codepoint_t; true }, - None => false - } as hb_bool_t; + match (*font).glyph_index(unicode as char) { + Some(g) => { + *glyph = g as hb_codepoint_t; + true as hb_bool_t + } + None => false as hb_bool_t + } } } -extern fn glyph_h_advance_func(_font: *hb_font_t, +extern fn glyph_h_advance_func(_: *hb_font_t, font_data: *c_void, glyph: hb_codepoint_t, - _user_data: *c_void) -> hb_position_t { + _: *c_void) + -> hb_position_t { let font: *Font = font_data as *Font; assert!(font.is_not_null()); @@ -482,27 +506,29 @@ extern fn glyph_h_advance_func(_font: *hb_font_t, } // Callback to get a font table out of a font. -extern fn get_font_table_func(_face: *hb_face_t, tag: hb_tag_t, user_data: *c_void) -> *hb_blob_t { +extern fn get_font_table_func(_: *hb_face_t, tag: hb_tag_t, user_data: *c_void) -> *hb_blob_t { unsafe { let font: *Font = user_data as *Font; assert!(font.is_not_null()); // TODO(Issue #197): reuse font table data, which will change the unsound trickery here. match (*font).get_table_for_tag(tag as FontTableTag) { - None => return ptr::null(), + None => null(), Some(ref font_table) => { - let skinny_font_table = ~font_table; - let skinny_font_table_ptr = ptr::to_unsafe_ptr(skinny_font_table); - let mut blob: *hb_blob_t = ptr::null(); - (*skinny_font_table_ptr).with_buffer(|buf: *u8, len: uint| { + let skinny_font_table_ptr: *FontTable = font_table; // private context + + let mut blob: *hb_blob_t = null(); + do (*skinny_font_table_ptr).with_buffer |buf: *u8, len: uint| { + // HarfBuzz calls `destroy_blob_func` when the buffer is no longer needed. blob = hb_blob_create(buf as *c_char, len as c_uint, HB_MEMORY_MODE_READONLY, - cast::transmute(skinny_font_table_ptr), // private context for below. - destroy_blob_func); // HarfBuzz calls this when blob not needed. - }); + transmute(skinny_font_table_ptr), + destroy_blob_func); + } + assert!(blob.is_not_null()); - return blob; + blob } } } @@ -512,7 +538,7 @@ extern fn get_font_table_func(_face: *hb_face_t, tag: hb_tag_t, user_data: *c_vo // In particular, we'll need to cast to a boxed, rather than owned, FontTable. // even better, should cache the harfbuzz blobs directly instead of recreating a lot. -extern fn destroy_blob_func(user_data: *c_void) { - // this will cause drop to run. - let _wrapper : &~FontTable = unsafe { cast::transmute(user_data) }; +extern fn destroy_blob_func(_: *c_void) { + // TODO: Previous code here was broken. Rewrite. } + From a535f221469940d9549550953b845010a353d3bc Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 5 Apr 2013 18:24:46 -0700 Subject: [PATCH 07/11] Rename one of the two modules called "shaper" --- src/servo-gfx/font.rs | 2 +- src/servo-gfx/text/mod.rs | 17 +-- src/servo-gfx/text/shaper.rs | 22 ---- .../shaper.rs => shaping/harfbuzz.rs} | 102 +++++++++--------- src/servo-gfx/text/shaping/mod.rs | 15 +++ 5 files changed, 72 insertions(+), 86 deletions(-) delete mode 100644 src/servo-gfx/text/shaper.rs rename src/servo-gfx/text/{harfbuzz/shaper.rs => shaping/harfbuzz.rs} (84%) create mode 100644 src/servo-gfx/text/shaping/mod.rs diff --git a/src/servo-gfx/font.rs b/src/servo-gfx/font.rs index 4ad4ad0a0a7..ff97fc6f423 100644 --- a/src/servo-gfx/font.rs +++ b/src/servo-gfx/font.rs @@ -7,7 +7,7 @@ use platform::font_context::FontContextHandle; use platform::font::{FontHandle, FontTable}; use render_context::RenderContext; use text::glyph::{GlyphStore, GlyphIndex}; -use text::shaper::ShaperMethods; +use text::shaping::ShaperMethods; use text::{Shaper, TextRun}; use util::range::Range; diff --git a/src/servo-gfx/text/mod.rs b/src/servo-gfx/text/mod.rs index 992dc50283e..bfa52ea42e5 100644 --- a/src/servo-gfx/text/mod.rs +++ b/src/servo-gfx/text/mod.rs @@ -1,19 +1,12 @@ -/* This file exists just to make it easier to import things inside of - ./text/ without specifying the file they came out of imports. - -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. */ +//! This file exists just to make it easier to import things inside of +/// ./text/ without specifying the file they came out of imports. -pub use text::shaper::Shaper; -pub use text::text_run::TextRun; +pub use text::shaping::Shaper; pub use text::text_run::SendableTextRun; +pub use text::text_run::TextRun; pub mod glyph; +#[path="shaping/mod.rs"] pub mod shaping; pub mod text_run; pub mod util; -pub mod shaper; -// Below are the actual platform-specific parts. -pub mod harfbuzz { - pub mod shaper; -} diff --git a/src/servo-gfx/text/shaper.rs b/src/servo-gfx/text/shaper.rs deleted file mode 100644 index 429f6b1d9c0..00000000000 --- a/src/servo-gfx/text/shaper.rs +++ /dev/null @@ -1,22 +0,0 @@ -//! Shaper encapsulates a specific shaper, such as Harfbuzz, -/// Uniscribe, Pango, or Coretext. -/// -/// Currently, only harfbuzz bindings are implemented. - -use font::Font; -use text::glyph::GlyphStore; -use text::harfbuzz; - -pub type Shaper = harfbuzz::shaper::HarfbuzzShaper; - -pub trait ShaperMethods { - fn shape_text(&self, text: &str, glyphs: &mut GlyphStore); -} - -// 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 { - harfbuzz::shaper::HarfbuzzShaper::new(font) - } -} diff --git a/src/servo-gfx/text/harfbuzz/shaper.rs b/src/servo-gfx/text/shaping/harfbuzz.rs similarity index 84% rename from src/servo-gfx/text/harfbuzz/shaper.rs rename to src/servo-gfx/text/shaping/harfbuzz.rs index c581263e43e..88129f216d7 100644 --- a/src/servo-gfx/text/harfbuzz/shaper.rs +++ b/src/servo-gfx/text/shaping/harfbuzz.rs @@ -6,7 +6,7 @@ use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag}; use geometry::Au; use platform::font::FontTable; use text::glyph::{GlyphStore, GlyphIndex, GlyphData}; -use text::shaper::ShaperMethods; +use text::shaping::ShaperMethods; use text::util::{float_to_fixed, fixed_to_float, fixed_to_rounded_int}; use util::range::Range; @@ -15,42 +15,42 @@ use core::libc::{c_uint, c_int, c_void, c_char}; use core::ptr::null; use core::util::ignore; use geom::Point2D; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_blob_create, hb_face_create_for_tables}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_add_utf8, hb_shape}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_create}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_destroy, hb_buffer_add_utf8}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_get_glyph_infos}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_get_glyph_positions}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_get_glyph_positions}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_set_direction}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_buffer_set_direction}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_face_destroy, hb_font_create}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_face_destroy}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_create, hb_font_destroy}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_destroy, hb_buffer_create}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_create, hb_font_funcs_destroy}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_create}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_destroy}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_set_glyph_func}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_set_glyph_func}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_funcs}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_funcs}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_ppem, hb_font_set_scale}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_ppem}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_font_set_scale}; -use text::harfbuzz::shaper::harfbuzz::bindgen::{hb_shape, hb_buffer_get_glyph_infos}; -use text::harfbuzz::shaper::harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR, hb_blob_t}; -use text::harfbuzz::shaper::harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR}; -use text::harfbuzz::shaper::harfbuzz::{hb_blob_t, hb_face_t, hb_font_t, hb_font_funcs_t}; -use text::harfbuzz::shaper::harfbuzz::{hb_buffer_t, hb_codepoint_t, hb_bool_t}; -use text::harfbuzz::shaper::harfbuzz::{hb_face_t, hb_font_t}; -use text::harfbuzz::shaper::harfbuzz::{hb_font_funcs_t, hb_buffer_t, hb_codepoint_t, hb_bool_t}; -use text::harfbuzz::shaper::harfbuzz::{hb_glyph_info_t, hb_position_t}; -use text::harfbuzz::shaper::harfbuzz::{hb_glyph_position_t, hb_glyph_info_t}; -use text::harfbuzz::shaper::harfbuzz::{hb_glyph_position_t}; -use text::harfbuzz::shaper::harfbuzz::{hb_position_t, hb_tag_t}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_blob_create, hb_face_create_for_tables}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_add_utf8, hb_shape}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_create}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_destroy, hb_buffer_add_utf8}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_get_glyph_infos}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_get_glyph_positions}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_get_glyph_positions}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_set_direction}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_set_direction}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_face_destroy, hb_font_create}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_face_destroy}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_create, hb_font_destroy}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_destroy, hb_buffer_create}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_create, hb_font_funcs_destroy}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_create}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_destroy}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_set_glyph_func}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_set_glyph_func}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_set_funcs}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_set_funcs}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_set_ppem, hb_font_set_scale}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_set_ppem}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_set_scale}; +use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_shape, hb_buffer_get_glyph_infos}; +use text::shaping::harfbuzz::harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR, hb_blob_t}; +use text::shaping::harfbuzz::harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR}; +use text::shaping::harfbuzz::harfbuzz::{hb_blob_t, hb_face_t, hb_font_t, hb_font_funcs_t}; +use text::shaping::harfbuzz::harfbuzz::{hb_buffer_t, hb_codepoint_t, hb_bool_t}; +use text::shaping::harfbuzz::harfbuzz::{hb_face_t, hb_font_t}; +use text::shaping::harfbuzz::harfbuzz::{hb_font_funcs_t, hb_buffer_t, hb_codepoint_t}; +use text::shaping::harfbuzz::harfbuzz::{hb_glyph_info_t, hb_position_t}; +use text::shaping::harfbuzz::harfbuzz::{hb_glyph_position_t, hb_glyph_info_t}; +use text::shaping::harfbuzz::harfbuzz::{hb_glyph_position_t}; +use text::shaping::harfbuzz::harfbuzz::{hb_position_t, hb_tag_t}; static NO_GLYPH: i32 = -1; static CONTINUATION_BYTE: i32 = -2; @@ -109,10 +109,10 @@ impl ShapedGlyphData { unsafe { let glyph_info_i = ptr::offset(self.glyph_infos, i); let pos_info_i = ptr::offset(self.pos_infos, i); - let x_offset = HarfbuzzShaper::fixed_to_float((*pos_info_i).x_offset); - let y_offset = HarfbuzzShaper::fixed_to_float((*pos_info_i).y_offset); - let x_advance = HarfbuzzShaper::fixed_to_float((*pos_info_i).x_advance); - let y_advance = HarfbuzzShaper::fixed_to_float((*pos_info_i).y_advance); + let x_offset = Shaper::fixed_to_float((*pos_info_i).x_offset); + let y_offset = Shaper::fixed_to_float((*pos_info_i).y_offset); + let x_advance = Shaper::fixed_to_float((*pos_info_i).x_advance); + let y_advance = Shaper::fixed_to_float((*pos_info_i).y_advance); let x_offset = Au::from_frac_px(x_offset); let y_offset = Au::from_frac_px(y_offset); @@ -140,7 +140,7 @@ impl ShapedGlyphData { } } -pub struct HarfbuzzShaper { +pub struct Shaper { font: @mut Font, priv hb_face: *hb_face_t, priv hb_font: *hb_font_t, @@ -148,7 +148,7 @@ pub struct HarfbuzzShaper { } #[unsafe_destructor] -impl Drop for HarfbuzzShaper { +impl Drop for Shaper { fn finalize(&self) { assert!(self.hb_face.is_not_null()); hb_face_destroy(self.hb_face); @@ -161,8 +161,8 @@ impl Drop for HarfbuzzShaper { } } -impl HarfbuzzShaper { - pub fn new(font: @mut Font) -> HarfbuzzShaper { +impl Shaper { + pub fn new(font: @mut Font) -> Shaper { unsafe { let font_ptr: *mut Font = &mut *font; let hb_face: *hb_face_t = hb_face_create_for_tables(get_font_table_func, @@ -176,8 +176,8 @@ impl HarfbuzzShaper { // Set scaling. Note that this takes 16.16 fixed point. hb_font_set_scale(hb_font, - HarfbuzzShaper::float_to_fixed(pt_size) as c_int, - HarfbuzzShaper::float_to_fixed(pt_size) as c_int); + Shaper::float_to_fixed(pt_size) as c_int, + Shaper::float_to_fixed(pt_size) as c_int); // configure static function callbacks. // NB. This funcs structure could be reused globally, as it never changes. @@ -186,7 +186,7 @@ impl HarfbuzzShaper { hb_font_funcs_set_glyph_h_advance_func(hb_funcs, glyph_h_advance_func, null(), null()); hb_font_set_funcs(hb_font, hb_funcs, font_ptr as *c_void, null()); - HarfbuzzShaper { + Shaper { font: font, hb_face: hb_face, hb_font: hb_font, @@ -208,7 +208,7 @@ impl HarfbuzzShaper { } } -impl ShaperMethods for HarfbuzzShaper { +impl ShaperMethods for Shaper { /// Calculate the layout metrics associated with the given text when rendered in a specific /// font. fn shape_text(&self, text: &str, glyphs: &mut GlyphStore) { @@ -230,7 +230,7 @@ impl ShaperMethods for HarfbuzzShaper { } } -impl HarfbuzzShaper { +impl Shaper { fn save_glyph_results(&self, text: &str, glyphs: &mut GlyphStore, buffer: *hb_buffer_t) { let glyph_data = ShapedGlyphData::new(buffer); let glyph_count = glyph_data.len(); @@ -501,7 +501,7 @@ extern fn glyph_h_advance_func(_: *hb_font_t, unsafe { let advance = (*font).glyph_h_advance(glyph as GlyphIndex); - HarfbuzzShaper::float_to_fixed(advance) + Shaper::float_to_fixed(advance) } } diff --git a/src/servo-gfx/text/shaping/mod.rs b/src/servo-gfx/text/shaping/mod.rs new file mode 100644 index 00000000000..2b2673c9c04 --- /dev/null +++ b/src/servo-gfx/text/shaping/mod.rs @@ -0,0 +1,15 @@ +//! Shaper encapsulates a specific shaper, such as Harfbuzz, +/// Uniscribe, Pango, or Coretext. +/// +/// Currently, only harfbuzz bindings are implemented. + +use text::glyph::GlyphStore; + +pub use Shaper = text::shaping::harfbuzz::Shaper; + +pub mod harfbuzz; + +pub trait ShaperMethods { + fn shape_text(&self, text: &str, glyphs: &mut GlyphStore); +} + From 8972f52b2bb0b5845fa503afede34771349809aa Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 5 Apr 2013 18:38:17 -0700 Subject: [PATCH 08/11] Hoist all `extern mod` directives to the top level This improves compile time and makes `use` directives look cleaner. --- src/servo-gfx/platform/linux/font.rs | 22 +++--- src/servo-gfx/platform/linux/font_context.rs | 7 +- src/servo-gfx/platform/linux/font_list.rs | 34 +++++---- src/servo-gfx/platform/macos/font.rs | 34 ++++----- src/servo-gfx/platform/macos/font_context.rs | 11 +-- src/servo-gfx/platform/macos/font_list.rs | 27 +++---- src/servo-gfx/servo_gfx.rc | 13 ++++ src/servo-gfx/text/shaping/harfbuzz.rs | 74 ++++++++++---------- 8 files changed, 105 insertions(+), 117 deletions(-) diff --git a/src/servo-gfx/platform/linux/font.rs b/src/servo-gfx/platform/linux/font.rs index 9a4a1e3e360..94278c4e72b 100644 --- a/src/servo-gfx/platform/linux/font.rs +++ b/src/servo-gfx/platform/linux/font.rs @@ -1,7 +1,5 @@ //! Linux (FreeType) representation of fonts. -extern mod freetype; - use font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTable, FontTableMethods}; use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle, FontWeight100}; use font::{FontWeight200, FontWeight300, FontWeight400, FontWeight500, FontWeight600}; @@ -12,16 +10,16 @@ use platform::font_context::{FreeTypeFontContextHandle, FontContextHandle}; use text::glyph::GlyphIndex; use text::util::{float_to_fixed, fixed_to_float}; -use platform::font::freetype::freetype::bindgen::{FT_Get_Char_Index, FT_Get_Postscript_Name}; -use platform::font::freetype::freetype::bindgen::{FT_Load_Glyph, FT_Set_Char_Size}; -use platform::font::freetype::freetype::bindgen::{FT_New_Face, FT_Get_Sfnt_Table}; -use platform::font::freetype::freetype::bindgen::{FT_New_Memory_Face, FT_Done_Face}; -use platform::font::freetype::freetype::{FTErrorMethods, FT_F26Dot6, FT_Face, FT_FaceRec}; -use platform::font::freetype::freetype::{FT_GlyphSlot, FT_Library, FT_Long, FT_ULong}; -use platform::font::freetype::freetype::{FT_STYLE_FLAG_ITALIC, FT_STYLE_FLAG_BOLD}; -use platform::font::freetype::freetype::{FT_SizeRec, FT_UInt, FT_Size_Metrics}; -use platform::font::freetype::freetype::{ft_sfnt_os2}; -use platform::font::freetype::tt_os2::TT_OS2; +use freetype::freetype::bindgen::{FT_Get_Char_Index, FT_Get_Postscript_Name}; +use freetype::freetype::bindgen::{FT_Load_Glyph, FT_Set_Char_Size}; +use freetype::freetype::bindgen::{FT_New_Face, FT_Get_Sfnt_Table}; +use freetype::freetype::bindgen::{FT_New_Memory_Face, FT_Done_Face}; +use freetype::freetype::{FTErrorMethods, FT_F26Dot6, FT_Face, FT_FaceRec}; +use freetype::freetype::{FT_GlyphSlot, FT_Library, FT_Long, FT_ULong}; +use freetype::freetype::{FT_STYLE_FLAG_ITALIC, FT_STYLE_FLAG_BOLD}; +use freetype::freetype::{FT_SizeRec, FT_UInt, FT_Size_Metrics}; +use freetype::freetype::{ft_sfnt_os2}; +use freetype::tt_os2::TT_OS2; pub use FontHandle = platform::linux::font::FreeTypeFontHandle; pub use FontTable = platform::linux::font::FreeTypeFontTable; diff --git a/src/servo-gfx/platform/linux/font_context.rs b/src/servo-gfx/platform/linux/font_context.rs index 24456530d1a..d40df90ec05 100644 --- a/src/servo-gfx/platform/linux/font_context.rs +++ b/src/servo-gfx/platform/linux/font_context.rs @@ -1,13 +1,10 @@ -extern mod freetype; -extern mod fontconfig; - use font::{FontHandle, UsedFontStyle}; use platform::font::FreeTypeFontHandle; use platform::font_context::FontContextHandleMethods; use platform::font_list::path_from_identifier; -use platform::font_context::freetype::freetype::{FTErrorMethods, FT_Library}; -use platform::font_context::freetype::freetype::bindgen::{FT_Done_FreeType, FT_Init_FreeType}; +use freetype::freetype::{FTErrorMethods, FT_Library}; +use freetype::freetype::bindgen::{FT_Done_FreeType, FT_Init_FreeType}; pub use FontContextHandle = platform::linux::FreeTypeFontContextHandle; diff --git a/src/servo-gfx/platform/linux/font_list.rs b/src/servo-gfx/platform/linux/font_list.rs index 809d6ed62fc..2e00c8f355b 100644 --- a/src/servo-gfx/platform/linux/font_list.rs +++ b/src/servo-gfx/platform/linux/font_list.rs @@ -1,7 +1,5 @@ //! Font list implementation for Linux (fontconfig). -extern mod freetype; -extern mod fontconfig; use font::FontHandleMethods; use font_context::FontContextHandleMethods; @@ -12,22 +10,22 @@ use platform::font_context::{FontContextHandle, FreeTypeFontContextHandle}; use core::hashmap::HashMap; use core::libc::c_int; use core::ptr::Ptr; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcConfigGetCurrent}; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcConfigGetFonts}; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcDefaultSubstitute}; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcPatternCreate}; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcFontSetDestroy}; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcConfigSubstitute}; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcFontSetList}; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcObjectSetCreate}; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcObjectSetDestroy}; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcObjectSetAdd}; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcPatternAddString, FcFontMatch}; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcPatternGetInteger}; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcPatternGetString}; -use platform::font_context::fontconfig::fontconfig::bindgen::{FcPatternDestroy}; -use platform::font_context::fontconfig::fontconfig::{FcChar8, FcResultMatch, FcSetSystem}; -use platform::font_context::fontconfig::fontconfig::{FcMatchPattern, FcResultNoMatch}; +use fontconfig::fontconfig::bindgen::{FcConfigGetCurrent}; +use fontconfig::fontconfig::bindgen::{FcConfigGetFonts}; +use fontconfig::fontconfig::bindgen::{FcDefaultSubstitute}; +use fontconfig::fontconfig::bindgen::{FcPatternCreate}; +use fontconfig::fontconfig::bindgen::{FcFontSetDestroy}; +use fontconfig::fontconfig::bindgen::{FcConfigSubstitute}; +use fontconfig::fontconfig::bindgen::{FcFontSetList}; +use fontconfig::fontconfig::bindgen::{FcObjectSetCreate}; +use fontconfig::fontconfig::bindgen::{FcObjectSetDestroy}; +use fontconfig::fontconfig::bindgen::{FcObjectSetAdd}; +use fontconfig::fontconfig::bindgen::{FcPatternAddString, FcFontMatch}; +use fontconfig::fontconfig::bindgen::{FcPatternGetInteger}; +use fontconfig::fontconfig::bindgen::{FcPatternGetString}; +use fontconfig::fontconfig::bindgen::{FcPatternDestroy}; +use fontconfig::fontconfig::{FcChar8, FcResultMatch, FcSetSystem}; +use fontconfig::fontconfig::{FcMatchPattern, FcResultNoMatch}; pub struct FontconfigFontListHandle { fctx: FreeTypeFontContextHandle, diff --git a/src/servo-gfx/platform/macos/font.rs b/src/servo-gfx/platform/macos/font.rs index d735a637f58..8281d0c444f 100644 --- a/src/servo-gfx/platform/macos/font.rs +++ b/src/servo-gfx/platform/macos/font.rs @@ -1,28 +1,24 @@ //! Implementation of Quartz (CoreGraphics) fonts. -extern mod core_foundation; -extern mod core_graphics; -extern mod core_text; - use font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTableMethods}; use font::{FontTableTag, FontWeight100, FontWeight200, FontWeight300, FontWeight400}; use font::{FontWeight500, FontWeight600, FontWeight700, FontWeight800, FontWeight900}; use font::{FractionalPixel, SpecifiedFontStyle}; use geometry::Au; use platform::macos::font_context::FontContextHandle; -use platform; use text::glyph::GlyphIndex; -use platform::macos::font::core_foundation::base::{CFIndex, CFWrapper}; -use platform::macos::font::core_foundation::data::CFData; -use platform::macos::font::core_foundation::string::UniChar; -use platform::macos::font::core_graphics::data_provider::CGDataProvider; -use platform::macos::font::core_graphics::font::{CGFont, CGGlyph}; -use platform::macos::font::core_graphics::geometry::CGRect; -use platform::macos::font::core_text::font::{CTFont, CTFontMethods, CTFontMethodsPrivate}; -use platform::macos::font::core_text::font_descriptor::{SymbolicTraitAccessors}; -use platform::macos::font::core_text::font_descriptor::{TraitAccessors}; -use platform::macos::font::core_text::font_descriptor::{kCTFontDefaultOrientation}; +use core_foundation::base::{CFIndex, CFWrapper}; +use core_foundation::data::CFData; +use core_foundation::string::UniChar; +use core_graphics::data_provider::CGDataProvider; +use core_graphics::font::{CGFont, CGGlyph}; +use core_graphics::geometry::CGRect; +use core_graphics; +use core_text::font::{CTFont, CTFontMethods, CTFontMethodsPrivate}; +use core_text::font_descriptor::{SymbolicTraitAccessors, TraitAccessors}; +use core_text::font_descriptor::{kCTFontDefaultOrientation}; +use core_text; pub struct FontTable { data: CFData, @@ -74,13 +70,11 @@ impl FontHandleMethods for FontHandle { fn new_from_buffer(_: &FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result { let fontprov : CGDataProvider = vec::as_imm_buf(buf, |cbuf, len| { - platform::macos::font::core_graphics::data_provider::new_from_buffer(cbuf, len) + core_graphics::data_provider::new_from_buffer(cbuf, len) }); - let cgfont = platform::macos::font::core_graphics::font::create_with_data_provider( - &fontprov); - let ctfont = platform::macos::font::core_text::font::new_from_CGFont(&cgfont, - style.pt_size); + let cgfont = core_graphics::font::create_with_data_provider(&fontprov); + let ctfont = core_text::font::new_from_CGFont(&cgfont, style.pt_size); let result = Ok(FontHandle { cgfont: Some(cgfont), diff --git a/src/servo-gfx/platform/macos/font_context.rs b/src/servo-gfx/platform/macos/font_context.rs index a8558fd4bb4..9626f977a7c 100644 --- a/src/servo-gfx/platform/macos/font_context.rs +++ b/src/servo-gfx/platform/macos/font_context.rs @@ -1,11 +1,8 @@ -extern mod core_foundation; -extern mod core_graphics; -extern mod core_text; - use font::UsedFontStyle; use font_context::FontContextHandleMethods; use platform::macos::font::FontHandle; -use platform; + +use core_text; pub struct FontContextHandle { ctx: () @@ -29,9 +26,7 @@ impl FontContextHandleMethods for FontContextHandle { name: ~str, style: UsedFontStyle) -> Result { - let ctfont_result = platform::macos::font_context::core_text::font::new_from_name( - name, - style.pt_size); + let ctfont_result = core_text::font::new_from_name(name, style.pt_size); do result::chain(ctfont_result) |ctfont| { FontHandle::new_from_CTFont(self, ctfont) } diff --git a/src/servo-gfx/platform/macos/font_list.rs b/src/servo-gfx/platform/macos/font_list.rs index a56f5a5f86c..6dd71a6953b 100644 --- a/src/servo-gfx/platform/macos/font_list.rs +++ b/src/servo-gfx/platform/macos/font_list.rs @@ -1,18 +1,17 @@ -extern mod core_foundation; -extern mod core_text; +//! Mac OS-specific bindings to the native font list (called a "font collection" in Core Text). use font::FontHandleMethods; use font_context::FontContextHandleMethods; use font_list::{FontEntry, FontFamily, FontFamilyMap}; - use platform::macos::font::FontHandle; use platform::macos::font_context::FontContextHandle; -use platform::macos::font_list::core_foundation::array::CFArray; -use platform::macos::font_list::core_foundation::base::CFWrapper; -use platform::macos::font_list::core_foundation::string::{CFString, CFStringRef}; -use platform::macos::font_list::core_text::font_collection::CTFontCollectionMethods; -use platform::macos::font_list::core_text::font_descriptor::CTFontDescriptorRef; -use platform; + +use core_foundation::array::CFArray; +use core_foundation::base::CFWrapper; +use core_foundation::string::{CFString, CFStringRef}; +use core_text::font_collection::CTFontCollectionMethods; +use core_text::font_descriptor::CTFontDescriptorRef; +use core_text; use core::hashmap::HashMap; @@ -28,8 +27,7 @@ pub impl FontListHandle { } fn get_available_families(&self) -> FontFamilyMap { - let family_names: CFArray = - platform::macos::font_list::core_text::font_collection::get_family_names(); + let family_names: CFArray = core_text::font_collection::get_family_names(); let mut family_map : FontFamilyMap = HashMap::new(); for family_names.each |&strref: &CFStringRef| { let family_name = CFString::wrap_extern(strref).to_str(); @@ -46,13 +44,10 @@ pub impl FontListHandle { let family_name = &fam.family_name; debug!("Looking for faces of family: %s", *family_name); - let family_collection = - platform::macos::font_list::core_text::font_collection::create_for_family( - *family_name); + let family_collection = core_text::font_collection::create_for_family(*family_name); for family_collection.get_descriptors().each |descref: &CTFontDescriptorRef| { let desc = CFWrapper::wrap_shared(*descref); - let font = platform::macos::font_list::core_text::font::new_from_descriptor(&desc, - 0.0); + let font = core_text::font::new_from_descriptor(&desc, 0.0); let handle = result::unwrap(FontHandle::new_from_CTFont(&self.fctx, font)); debug!("Creating new FontEntry for face: %s", handle.face_name()); diff --git a/src/servo-gfx/servo_gfx.rc b/src/servo-gfx/servo_gfx.rc index 614ce9134b3..d1010b6dab4 100644 --- a/src/servo-gfx/servo_gfx.rc +++ b/src/servo-gfx/servo_gfx.rc @@ -12,6 +12,19 @@ extern mod http_client; extern mod stb_image; extern mod std; +// Eventually we would like the shaper to be pluggable, as many operating systems have their own +// shapers. For now, however, this is a hard dependency. +extern mod harfbuzz; + +// Linux-specific library dependencies +#[cfg(target_os="linux")] extern mod fontconfig; +#[cfg(target_os="linux")] extern mod freetype; + +// Mac OS-specific library dependencies +#[cfg(target_os="macos")] extern mod core_foundation; +#[cfg(target_os="macos")] extern mod core_graphics; +#[cfg(target_os="macos")] extern mod core_text; + priv mod render_context; // Rendering diff --git a/src/servo-gfx/text/shaping/harfbuzz.rs b/src/servo-gfx/text/shaping/harfbuzz.rs index 88129f216d7..54d1f05d862 100644 --- a/src/servo-gfx/text/shaping/harfbuzz.rs +++ b/src/servo-gfx/text/shaping/harfbuzz.rs @@ -1,7 +1,5 @@ //! Performs shaping with HarfBuzz. -extern mod harfbuzz; - use font::{Font, FontHandleMethods, FontTableMethods, FontTableTag}; use geometry::Au; use platform::font::FontTable; @@ -15,42 +13,42 @@ use core::libc::{c_uint, c_int, c_void, c_char}; use core::ptr::null; use core::util::ignore; use geom::Point2D; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_blob_create, hb_face_create_for_tables}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_add_utf8, hb_shape}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_create}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_destroy, hb_buffer_add_utf8}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_get_glyph_infos}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_get_glyph_positions}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_get_glyph_positions}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_set_direction}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_buffer_set_direction}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_face_destroy, hb_font_create}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_face_destroy}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_create, hb_font_destroy}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_destroy, hb_buffer_create}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_create, hb_font_funcs_destroy}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_create}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_destroy}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_set_glyph_func}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_set_glyph_func}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_set_funcs}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_set_funcs}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_set_ppem, hb_font_set_scale}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_set_ppem}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_font_set_scale}; -use text::shaping::harfbuzz::harfbuzz::bindgen::{hb_shape, hb_buffer_get_glyph_infos}; -use text::shaping::harfbuzz::harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR, hb_blob_t}; -use text::shaping::harfbuzz::harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR}; -use text::shaping::harfbuzz::harfbuzz::{hb_blob_t, hb_face_t, hb_font_t, hb_font_funcs_t}; -use text::shaping::harfbuzz::harfbuzz::{hb_buffer_t, hb_codepoint_t, hb_bool_t}; -use text::shaping::harfbuzz::harfbuzz::{hb_face_t, hb_font_t}; -use text::shaping::harfbuzz::harfbuzz::{hb_font_funcs_t, hb_buffer_t, hb_codepoint_t}; -use text::shaping::harfbuzz::harfbuzz::{hb_glyph_info_t, hb_position_t}; -use text::shaping::harfbuzz::harfbuzz::{hb_glyph_position_t, hb_glyph_info_t}; -use text::shaping::harfbuzz::harfbuzz::{hb_glyph_position_t}; -use text::shaping::harfbuzz::harfbuzz::{hb_position_t, hb_tag_t}; +use harfbuzz::bindgen::{hb_blob_create, hb_face_create_for_tables}; +use harfbuzz::bindgen::{hb_buffer_add_utf8, hb_shape}; +use harfbuzz::bindgen::{hb_buffer_create}; +use harfbuzz::bindgen::{hb_buffer_destroy, hb_buffer_add_utf8}; +use harfbuzz::bindgen::{hb_buffer_get_glyph_infos}; +use harfbuzz::bindgen::{hb_buffer_get_glyph_positions}; +use harfbuzz::bindgen::{hb_buffer_get_glyph_positions}; +use harfbuzz::bindgen::{hb_buffer_set_direction}; +use harfbuzz::bindgen::{hb_buffer_set_direction}; +use harfbuzz::bindgen::{hb_face_destroy, hb_font_create}; +use harfbuzz::bindgen::{hb_face_destroy}; +use harfbuzz::bindgen::{hb_font_create, hb_font_destroy}; +use harfbuzz::bindgen::{hb_font_destroy, hb_buffer_create}; +use harfbuzz::bindgen::{hb_font_funcs_create, hb_font_funcs_destroy}; +use harfbuzz::bindgen::{hb_font_funcs_create}; +use harfbuzz::bindgen::{hb_font_funcs_destroy}; +use harfbuzz::bindgen::{hb_font_funcs_set_glyph_func}; +use harfbuzz::bindgen::{hb_font_funcs_set_glyph_func}; +use harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func}; +use harfbuzz::bindgen::{hb_font_funcs_set_glyph_h_advance_func}; +use harfbuzz::bindgen::{hb_font_set_funcs}; +use harfbuzz::bindgen::{hb_font_set_funcs}; +use harfbuzz::bindgen::{hb_font_set_ppem, hb_font_set_scale}; +use harfbuzz::bindgen::{hb_font_set_ppem}; +use harfbuzz::bindgen::{hb_font_set_scale}; +use harfbuzz::bindgen::{hb_shape, hb_buffer_get_glyph_infos}; +use harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR, hb_blob_t}; +use harfbuzz::{HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR}; +use harfbuzz::{hb_blob_t, hb_face_t, hb_font_t, hb_font_funcs_t}; +use harfbuzz::{hb_buffer_t, hb_codepoint_t, hb_bool_t}; +use harfbuzz::{hb_face_t, hb_font_t}; +use harfbuzz::{hb_font_funcs_t, hb_buffer_t, hb_codepoint_t}; +use harfbuzz::{hb_glyph_info_t, hb_position_t}; +use harfbuzz::{hb_glyph_position_t, hb_glyph_info_t}; +use harfbuzz::{hb_glyph_position_t}; +use harfbuzz::{hb_position_t, hb_tag_t}; static NO_GLYPH: i32 = -1; static CONTINUATION_BYTE: i32 = -2; From 5274f11a4cb15305e5c43e9e5a21af040c741e2f Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 5 Apr 2013 18:42:16 -0700 Subject: [PATCH 09/11] Nuke the TGA encoder --- src/servo-gfx/image/encode/tga.rs | 24 ------------------------ src/servo-gfx/servo_gfx.rc | 3 --- 2 files changed, 27 deletions(-) delete mode 100644 src/servo-gfx/image/encode/tga.rs diff --git a/src/servo-gfx/image/encode/tga.rs b/src/servo-gfx/image/encode/tga.rs deleted file mode 100644 index 60bada116ee..00000000000 --- a/src/servo-gfx/image/encode/tga.rs +++ /dev/null @@ -1,24 +0,0 @@ -use core::io::WriterUtil; -use surface; - -fn encode(writer: @io::Writer, surface: &surface::ImageSurface) { - assert!(surface.format == surface::fo_rgba_8888); - - writer.write_u8(0u8); // identsize - writer.write_u8(0u8); // colourmaptype - writer.write_u8(2u8); // imagetype - - writer.write_le_u16(0u16); // colourmapstart - writer.write_le_u16(0u16); // colourmaplength - writer.write_u8(16u8); // colourmapbits - - writer.write_le_u16(0u16); // xstart - writer.write_le_u16(0u16); // ystart - writer.write_le_u16(surface.size.width as u16); // width - writer.write_le_u16(surface.size.height as u16); // height - writer.write_u8(32u8); // bits - writer.write_u8(0x30u8); // descriptor - - writer.write(surface.buffer); -} - diff --git a/src/servo-gfx/servo_gfx.rc b/src/servo-gfx/servo_gfx.rc index d1010b6dab4..93d9ba67454 100644 --- a/src/servo-gfx/servo_gfx.rc +++ b/src/servo-gfx/servo_gfx.rc @@ -51,9 +51,6 @@ pub mod platform; // Images pub mod image { pub mod base; - pub mod encode { - pub mod tga; - } pub mod holder; } From cf9e02e3a02a7d12d818ed92c384e6a7444c93f1 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 9 Apr 2013 10:04:43 -0700 Subject: [PATCH 10/11] Add missing platform/mod.rs --- src/servo-gfx/platform/mod.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/servo-gfx/platform/mod.rs diff --git a/src/servo-gfx/platform/mod.rs b/src/servo-gfx/platform/mod.rs new file mode 100644 index 00000000000..126e7449476 --- /dev/null +++ b/src/servo-gfx/platform/mod.rs @@ -0,0 +1,19 @@ +//! Platform-specific modules. + +#[cfg(target_os="linux")] pub use platform::linux::{font, font_context, font_list}; +#[cfg(target_os="macos")] pub use platform::macos::{font, font_context, font_list}; + +#[cfg(target_os="linux")] +pub mod linux { + pub mod font; + pub mod font_context; + pub mod font_list; +} + +#[cfg(target_os="macos")] +pub mod macos { + pub mod font; + pub mod font_context; + pub mod font_list; +} + From c3f3e71c1c4ddc68c6bc0b9543bec871ebd2dd04 Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Thu, 18 Apr 2013 10:34:47 -0600 Subject: [PATCH 11/11] Fix refactored code on linux. --- src/servo-gfx/platform/linux/font.rs | 141 +++++++++---------- src/servo-gfx/platform/linux/font_context.rs | 23 ++- src/servo-gfx/platform/linux/font_list.rs | 18 +-- 3 files changed, 87 insertions(+), 95 deletions(-) diff --git a/src/servo-gfx/platform/linux/font.rs b/src/servo-gfx/platform/linux/font.rs index 94278c4e72b..0796960ab3c 100644 --- a/src/servo-gfx/platform/linux/font.rs +++ b/src/servo-gfx/platform/linux/font.rs @@ -1,12 +1,12 @@ //! Linux (FreeType) representation of fonts. -use font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTable, FontTableMethods}; +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 geometry::Au; use geometry; -use platform::font_context::{FreeTypeFontContextHandle, FontContextHandle}; +use platform::font_context::FontContextHandle; use text::glyph::GlyphIndex; use text::util::{float_to_fixed, fixed_to_float}; @@ -21,9 +21,6 @@ use freetype::freetype::{FT_SizeRec, FT_UInt, FT_Size_Metrics}; use freetype::freetype::{ft_sfnt_os2}; use freetype::tt_os2::TT_OS2; -pub use FontHandle = platform::linux::font::FreeTypeFontHandle; -pub use FontTable = platform::linux::font::FreeTypeFontTable; - fn float_to_fixed_ft(f: float) -> i32 { float_to_fixed(6, f) } @@ -32,22 +29,22 @@ fn fixed_to_float_ft(f: i32) -> float { fixed_to_float(6, f) } -pub struct FreeTypeFontTable { +pub struct FontTable { bogus: () } -impl FontTableMethods for FreeTypeFontTable { +impl FontTableMethods for FontTable { fn with_buffer(&self, _blk: &fn(*u8, uint)) { fail!() } } enum FontSource { - FontSourceMem(@~[u8]), + FontSourceMem(~[u8]), FontSourceFile(~str) } -pub struct FreeTypeFontHandle { +pub struct FontHandle { // The font binary. This must stay valid for the lifetime of the font, // if the font is created using FT_Memory_Face. source: FontSource, @@ -55,7 +52,7 @@ pub struct FreeTypeFontHandle { } #[unsafe_destructor] -impl Drop for FreeTypeFontHandle { +impl Drop for FontHandle { fn finalize(&self) { assert!(self.face.is_not_null()); if !FT_Done_Face(self.face).succeeded() { @@ -64,68 +61,15 @@ impl Drop for FreeTypeFontHandle { } } -pub impl FreeTypeFontHandle { - priv fn set_char_size(face: FT_Face, pt_size: float) -> Result<(), ()>{ - let char_width = float_to_fixed_ft(pt_size) as FT_F26Dot6; - let char_height = float_to_fixed_ft(pt_size) as FT_F26Dot6; - let h_dpi = 72; - let v_dpi = 72; - - let result = FT_Set_Char_Size(face, char_width, char_height, h_dpi, v_dpi); - if result.succeeded() { Ok(()) } else { Err(()) } - } - - pub fn new_from_file(fctx: &FreeTypeFontContextHandle, file: ~str, - style: &SpecifiedFontStyle) -> Result { - let ft_ctx: FT_Library = fctx.ctx.ctx; - if ft_ctx.is_null() { return Err(()); } - - let mut face: FT_Face = ptr::null(); - let face_index = 0 as FT_Long; - do str::as_c_str(file) |file_str| { - FT_New_Face(ft_ctx, file_str, - face_index, ptr::to_unsafe_ptr(&face)); - } - if face.is_null() { - return Err(()); - } - if FreeTypeFontHandle::set_char_size(face, style.pt_size).is_ok() { - Ok(FreeTypeFontHandle { source: FontSourceFile(file), face: face }) - } else { - Err(()) - } - } - - pub fn new_from_file_unstyled(fctx: &FreeTypeFontContextHandle, file: ~str) - -> Result { - let ft_ctx: FT_Library = fctx.ctx.ctx; - if ft_ctx.is_null() { return Err(()); } - - let mut face: FT_Face = ptr::null(); - let face_index = 0 as FT_Long; - do str::as_c_str(file) |file_str| { - FT_New_Face(ft_ctx, file_str, - face_index, ptr::to_unsafe_ptr(&face)); - } - if face.is_null() { - return Err(()); - } - - Ok(FreeTypeFontHandle { source: FontSourceFile(file), face: face }) - } -} - -impl FontHandleMethods for FreeTypeFontHandle { - pub fn new_from_buffer(fctx: &FreeTypeFontContextHandle, +impl FontHandleMethods for FontHandle { + pub fn new_from_buffer(fctx: &FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) - -> Result { - let buf = @buf; - + -> Result { let ft_ctx: FT_Library = fctx.ctx.ctx; if ft_ctx.is_null() { return Err(()); } - let face_result = do vec::as_imm_buf(*buf) |bytes: *u8, len: uint| { + let face_result = do vec::as_imm_buf(buf) |bytes: *u8, len: uint| { create_face_from_buffer(ft_ctx, bytes, len, style.pt_size) }; @@ -133,7 +77,7 @@ impl FontHandleMethods for FreeTypeFontHandle { // and moving buf into the struct ctor, but cant' move out of // captured binding. return match face_result { - Ok(face) => Ok(FreeTypeFontHandle { face: face, source: FontSourceMem(buf) }), + Ok(face) => Ok(FontHandle { face: face, source: FontSourceMem(buf) }), Err(()) => Err(()) }; @@ -149,7 +93,7 @@ impl FontHandleMethods for FreeTypeFontHandle { if !result.succeeded() || face.is_null() { return Err(()); } - if FreeTypeFontHandle::set_char_size(face, pt_size).is_ok() { + if FontHandle::set_char_size(face, pt_size).is_ok() { Ok(face) } else { Err(()) @@ -201,13 +145,13 @@ impl FontHandleMethods for FreeTypeFontHandle { fn clone_with_style(&self, fctx: &FontContextHandle, - style: &UsedFontStyle) -> Result { + style: &UsedFontStyle) -> Result { match self.source { - FontSourceMem(buf) => { - FreeTypeFontHandle::new_from_buffer(fctx, buf, style) + FontSourceMem(ref buf) => { + FontHandleMethods::new_from_buffer(fctx, buf.clone(), style) } FontSourceFile(copy file) => { - FreeTypeFontHandle::new_from_file(fctx, file, style) + FontHandle::new_from_file(fctx, file, style) } } } @@ -273,7 +217,56 @@ impl FontHandleMethods for FreeTypeFontHandle { } } -pub impl FreeTypeFontHandle { +pub impl FontHandle { + priv fn set_char_size(face: FT_Face, pt_size: float) -> Result<(), ()>{ + let char_width = float_to_fixed_ft(pt_size) as FT_F26Dot6; + let char_height = float_to_fixed_ft(pt_size) as FT_F26Dot6; + let h_dpi = 72; + let v_dpi = 72; + + let result = FT_Set_Char_Size(face, char_width, char_height, h_dpi, v_dpi); + if result.succeeded() { Ok(()) } else { Err(()) } + } + + pub fn new_from_file(fctx: &FontContextHandle, file: ~str, + style: &SpecifiedFontStyle) -> Result { + let ft_ctx: FT_Library = fctx.ctx.ctx; + if ft_ctx.is_null() { return Err(()); } + + let mut face: FT_Face = ptr::null(); + let face_index = 0 as FT_Long; + do str::as_c_str(file) |file_str| { + FT_New_Face(ft_ctx, file_str, + face_index, ptr::to_unsafe_ptr(&face)); + } + if face.is_null() { + return Err(()); + } + if FontHandle::set_char_size(face, style.pt_size).is_ok() { + Ok(FontHandle { source: FontSourceFile(file), face: face }) + } else { + Err(()) + } + } + + pub fn new_from_file_unstyled(fctx: &FontContextHandle, file: ~str) + -> Result { + let ft_ctx: FT_Library = fctx.ctx.ctx; + if ft_ctx.is_null() { return Err(()); } + + let mut face: FT_Face = ptr::null(); + let face_index = 0 as FT_Long; + do str::as_c_str(file) |file_str| { + FT_New_Face(ft_ctx, file_str, + face_index, ptr::to_unsafe_ptr(&face)); + } + if face.is_null() { + return Err(()); + } + + Ok(FontHandle { source: FontSourceFile(file), face: face }) + } + priv fn get_face_rec(&self) -> &'self FT_FaceRec { unsafe { &(*self.face) diff --git a/src/servo-gfx/platform/linux/font_context.rs b/src/servo-gfx/platform/linux/font_context.rs index d40df90ec05..7b5dee4ae34 100644 --- a/src/servo-gfx/platform/linux/font_context.rs +++ b/src/servo-gfx/platform/linux/font_context.rs @@ -1,12 +1,11 @@ -use font::{FontHandle, UsedFontStyle}; -use platform::font::FreeTypeFontHandle; -use platform::font_context::FontContextHandleMethods; +use font::UsedFontStyle; +use platform::font::FontHandle; +use font_context::FontContextHandleMethods; use platform::font_list::path_from_identifier; use freetype::freetype::{FTErrorMethods, FT_Library}; use freetype::freetype::bindgen::{FT_Done_FreeType, FT_Init_FreeType}; -pub use FontContextHandle = platform::linux::FreeTypeFontContextHandle; struct FreeTypeLibraryHandle { ctx: FT_Library, @@ -19,25 +18,25 @@ impl Drop for FreeTypeLibraryHandle { } } -pub struct FreeTypeFontContextHandle { +pub struct FontContextHandle { ctx: @FreeTypeLibraryHandle, } -pub impl FreeTypeFontContextHandle { - pub fn new() -> FreeTypeFontContextHandle { +pub impl FontContextHandle { + pub fn new() -> FontContextHandle { let ctx: FT_Library = ptr::null(); let result = FT_Init_FreeType(ptr::to_unsafe_ptr(&ctx)); if !result.succeeded() { fail!(); } - FreeTypeFontContextHandle { + FontContextHandle { ctx: @FreeTypeLibraryHandle { ctx: ctx }, } } } -impl FontContextHandleMethods for FreeTypeFontContextHandle { - fn clone(&self) -> FreeTypeFontContextHandle { - FreeTypeFontContextHandle { ctx: self.ctx } +impl FontContextHandleMethods for FontContextHandle { + fn clone(&self) -> FontContextHandle { + FontContextHandle { ctx: self.ctx } } fn create_font_from_identifier(&self, name: ~str, style: UsedFontStyle) @@ -45,7 +44,7 @@ impl FontContextHandleMethods for FreeTypeFontContextHandle { debug!("Creating font handle for %s", name); do path_from_identifier(name).chain |file_name| { debug!("Opening font face %s", file_name); - FreeTypeFontHandle::new_from_file(self, file_name, &style) + FontHandle::new_from_file(self, file_name, &style) } } } diff --git a/src/servo-gfx/platform/linux/font_list.rs b/src/servo-gfx/platform/linux/font_list.rs index 2e00c8f355b..76bfa534747 100644 --- a/src/servo-gfx/platform/linux/font_list.rs +++ b/src/servo-gfx/platform/linux/font_list.rs @@ -4,8 +4,8 @@ use font::FontHandleMethods; use font_context::FontContextHandleMethods; use font_list::{FontEntry, FontFamily, FontFamilyMap}; -use platform::font::FreeTypeFontHandle; -use platform::font_context::{FontContextHandle, FreeTypeFontContextHandle}; +use platform::font::FontHandle; +use platform::font_context::FontContextHandle; use core::hashmap::HashMap; use core::libc::c_int; @@ -27,13 +27,13 @@ use fontconfig::fontconfig::bindgen::{FcPatternDestroy}; use fontconfig::fontconfig::{FcChar8, FcResultMatch, FcSetSystem}; use fontconfig::fontconfig::{FcMatchPattern, FcResultNoMatch}; -pub struct FontconfigFontListHandle { - fctx: FreeTypeFontContextHandle, +pub struct FontListHandle { + fctx: FontContextHandle, } -pub impl FontconfigFontListHandle { - pub fn new(fctx: &FontContextHandle) -> FontconfigFontListHandle { - FontconfigFontListHandle { fctx: fctx.clone() } +pub impl FontListHandle { + pub fn new(fctx: &FontContextHandle) -> FontListHandle { + FontListHandle { fctx: fctx.clone() } } fn get_available_families(&self) -> FontFamilyMap { @@ -105,8 +105,8 @@ pub impl FontconfigFontListHandle { debug!("variation file: %?", file); debug!("variation index: %?", index); - let font_handle = FreeTypeFontHandle::new_from_file_unstyled(&self.fctx, - file); + let font_handle = FontHandle::new_from_file_unstyled(&self.fctx, + file); let font_handle = font_handle.unwrap(); debug!("Creating new FontEntry for face: %s", font_handle.face_name());