diff --git a/src/rust-core-foundation b/src/rust-core-foundation index 7fcbf5112ec..1f0bc6db0d2 160000 --- a/src/rust-core-foundation +++ b/src/rust-core-foundation @@ -1 +1 @@ -Subproject commit 7fcbf5112ec163bdc14f096ddd9a45ef744ca6a6 +Subproject commit 1f0bc6db0d23a9f1edd1918b3cb68e0ffba2cb9d diff --git a/src/rust-core-text b/src/rust-core-text index 4c38ba65d49..4914947bb56 160000 --- a/src/rust-core-text +++ b/src/rust-core-text @@ -1 +1 @@ -Subproject commit 4c38ba65d4929ba418317c9fd9d16a0aa83945c9 +Subproject commit 4914947bb5663f1b3f83757edc5be38f8f6f6d0d diff --git a/src/servo-gfx/font_context.rs b/src/servo-gfx/font_context.rs index ee0e85d1d8c..0460c186720 100644 --- a/src/servo-gfx/font_context.rs +++ b/src/servo-gfx/font_context.rs @@ -34,6 +34,7 @@ type FontContextHandle/& = quartz::font_context::QuartzFontContextHandle; type FontContextHandle/& = freetype::font_context::FreeTypeFontContextHandle; trait FontContextHandleMethods { + pure fn clone(&const self) -> FontContextHandle; fn create_font_from_identifier(~str, UsedFontStyle) -> Result; } diff --git a/src/servo-gfx/font_list.rs b/src/servo-gfx/font_list.rs index 27c1b576b76..ad8f1aafcb6 100644 --- a/src/servo-gfx/font_list.rs +++ b/src/servo-gfx/font_list.rs @@ -24,9 +24,14 @@ pub impl FontListHandle { type FontFamilyMap = linear::LinearMap<~str, @FontFamily>; +trait FontListHandleMethods { + fn get_available_families(&const self, fctx: &native::FontContextHandle) -> FontFamilyMap; + fn load_variations_for_family(&const self, family: @FontFamily); +} + pub struct FontList { mut family_map: FontFamilyMap, - mut handle: FontListHandle, + handle: FontListHandle, } pub impl FontList { @@ -40,11 +45,13 @@ pub impl FontList { return move list; } - priv fn refresh(fctx: &native::FontContextHandle) { + priv fn refresh(_fctx: &native::FontContextHandle) { // TODO(Issue #186): don't refresh unless something actually // changed. Does OSX have a notification for this event? + // + // Should font families with entries be invalidated/refreshed too? do util::time::time("gfx::font_list: regenerating available font families and faces") { - self.family_map = self.handle.get_available_families(fctx); + self.family_map = self.handle.get_available_families(); } } @@ -57,7 +64,7 @@ pub impl FontList { // if such family exists, try to match style to a font do family.iter |fam| { - result = fam.find_font_for_style(style); + result = fam.find_font_for_style(&self.handle, style); } let decision = if result.is_some() { "Found" } else { "Couldn't find" }; @@ -80,20 +87,27 @@ pub impl FontList { // Holds a specific font family, and the various pub struct FontFamily { - family_name: @str, + family_name: ~str, entries: DVec<@FontEntry>, } pub impl FontFamily { static fn new(family_name: &str) -> FontFamily { FontFamily { - family_name: str::from_slice(family_name).to_managed(), + family_name: str::from_slice(family_name), entries: DVec(), } } - pure fn find_font_for_style(style: &SpecifiedFontStyle) -> Option<@FontEntry> { + priv fn load_family_variations(@self, list: &native::FontListHandle) { + if self.entries.len() > 0 { return; } + list.load_variations_for_family(self); assert self.entries.len() > 0; + } + + fn find_font_for_style(@self, list: &native::FontListHandle, style: &SpecifiedFontStyle) -> Option<@FontEntry> { + + self.load_family_variations(list); // TODO(Issue #189): optimize lookup for // regular/bold/italic/bolditalic with fixed offsets and a diff --git a/src/servo-gfx/quartz/font_context.rs b/src/servo-gfx/quartz/font_context.rs index d02fade7781..ffe730a2ad2 100644 --- a/src/servo-gfx/quartz/font_context.rs +++ b/src/servo-gfx/quartz/font_context.rs @@ -23,6 +23,10 @@ pub impl QuartzFontContextHandle { } pub impl QuartzFontContextHandle : FontContextHandleMethods { + pure fn clone(&const self) -> QuartzFontContextHandle { + QuartzFontContextHandle { ctx: self.ctx } + } + fn create_font_from_identifier(name: ~str, style: UsedFontStyle) -> Result { let ctfont_result = CTFont::new_from_name(move name, style.pt_size); do result::chain(move ctfont_result) |ctfont| { diff --git a/src/servo-gfx/quartz/font_list.rs b/src/servo-gfx/quartz/font_list.rs index 39357884403..91a3cc7dd09 100644 --- a/src/servo-gfx/quartz/font_list.rs +++ b/src/servo-gfx/quartz/font_list.rs @@ -1,56 +1,57 @@ extern mod core_foundation; extern mod core_text; -use quartz::font::{QuartzFontHandle}; -use servo_gfx_font::FontHandle; -use servo_gfx_font_list::{FontEntry, FontFamily}; - use cf = core_foundation; use cf::array::CFArray; -use core::dvec::DVec; -use core::send_map::{linear, SendMap}; +use cf::string::CFString; + use ct = core_text; use ct::font::{CTFont, debug_font_names, debug_font_traits}; use ct::font_collection::CTFontCollection; use ct::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef, debug_descriptor}; +use quartz::font::QuartzFontHandle; +use quartz::font_context::QuartzFontContextHandle; +use gfx_font::FontHandle; +use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap}; + +use core::dvec::DVec; +use core::send_map::{linear, SendMap}; + pub struct QuartzFontListHandle { - collection: CTFontCollection, + fctx: QuartzFontContextHandle, } pub impl QuartzFontListHandle { - static pub fn new(_fctx: &native::FontContextHandle) -> QuartzFontListHandle { - QuartzFontListHandle { collection: CTFontCollection::new() } + static fn new(fctx: &native::FontContextHandle) -> QuartzFontListHandle { + QuartzFontListHandle { fctx: fctx.clone() } } - fn get_available_families(&const self, - fctx: &native::FontContextHandle) - -> linear::LinearMap<~str, @FontFamily> { - // since we mutate it repeatedly, must be mut variable. - let mut family_map : linear::LinearMap<~str, @FontFamily> = linear::LinearMap(); - let descriptors : CFArray; - descriptors = self.collection.get_descriptors(); - for descriptors.each |desc: &CTFontDescriptor| { - // TODO: for each descriptor, make a FontEntry. + fn get_available_families() -> FontFamilyMap { + let family_names = CTFontCollection::get_family_names(); + let mut family_map : FontFamilyMap = linear::LinearMap(); + for family_names.each |family_name_cfstr: &CFString| { + let family_name = family_name_cfstr.to_str(); + debug!("Creating new FontFamily for family: %s", family_name); + + let new_family = @FontFamily::new(family_name); + family_map.insert(move family_name, new_family); + } + return move family_map; + } + + fn load_variations_for_family(family: @FontFamily) { + let family_name = &family.family_name; + debug!("Looking for faces of family: %s", *family_name); + + let family_collection = CTFontCollection::create_for_family(*family_name); + for family_collection.get_descriptors().each |desc: &CTFontDescriptor| { let font = CTFont::new_from_descriptor(desc, 0.0); - let handle = result::unwrap(QuartzFontHandle::new_from_CTFont(fctx, move font)); - let family_name = handle.family_name(); - debug!("Looking for family name: %s", family_name); - let family = match family_map.find(&family_name) { - Some(fam) => fam, - None => { - debug!("Creating new FontFamily for family: %s", family_name); - let new_family = @FontFamily::new(family_name); - family_map.insert(move family_name, new_family); - new_family - } - }; + let handle = result::unwrap(QuartzFontHandle::new_from_CTFont(&self.fctx, move font)); debug!("Creating new FontEntry for face: %s", handle.face_name()); let entry = @FontEntry::new(family, move handle); family.entries.push(entry); - // TODO: append FontEntry to hashtable value } - return move family_map; } }