mirror of
https://github.com/servo/servo.git
synced 2025-08-12 08:55:32 +01:00
Load font family face variations on-demand, rather than all at startup. This breaks the linux build temporarily. Provides the Mac implementation for Issue #187.
This commit is contained in:
parent
fe29edb5f6
commit
b14505e44d
6 changed files with 61 additions and 41 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 7fcbf5112ec163bdc14f096ddd9a45ef744ca6a6
|
||||
Subproject commit 1f0bc6db0d23a9f1edd1918b3cb68e0ffba2cb9d
|
|
@ -1 +1 @@
|
|||
Subproject commit 4c38ba65d4929ba418317c9fd9d16a0aa83945c9
|
||||
Subproject commit 4914947bb5663f1b3f83757edc5be38f8f6f6d0d
|
|
@ -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<FontHandle, ()>;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<FontHandle, ()> {
|
||||
let ctfont_result = CTFont::new_from_name(move name, style.pt_size);
|
||||
do result::chain(move ctfont_result) |ctfont| {
|
||||
|
|
|
@ -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<CTFontDescriptorRef, CTFontDescriptor>;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue