mirror of
https://github.com/servo/servo.git
synced 2025-08-13 09:25: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;
|
type FontContextHandle/& = freetype::font_context::FreeTypeFontContextHandle;
|
||||||
|
|
||||||
trait FontContextHandleMethods {
|
trait FontContextHandleMethods {
|
||||||
|
pure fn clone(&const self) -> FontContextHandle;
|
||||||
fn create_font_from_identifier(~str, UsedFontStyle) -> Result<FontHandle, ()>;
|
fn create_font_from_identifier(~str, UsedFontStyle) -> Result<FontHandle, ()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,14 @@ pub impl FontListHandle {
|
||||||
|
|
||||||
type FontFamilyMap = linear::LinearMap<~str, @FontFamily>;
|
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 {
|
pub struct FontList {
|
||||||
mut family_map: FontFamilyMap,
|
mut family_map: FontFamilyMap,
|
||||||
mut handle: FontListHandle,
|
handle: FontListHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl FontList {
|
pub impl FontList {
|
||||||
|
@ -40,11 +45,13 @@ pub impl FontList {
|
||||||
return move list;
|
return move list;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv fn refresh(fctx: &native::FontContextHandle) {
|
priv fn refresh(_fctx: &native::FontContextHandle) {
|
||||||
// TODO(Issue #186): don't refresh unless something actually
|
// TODO(Issue #186): don't refresh unless something actually
|
||||||
// changed. Does OSX have a notification for this event?
|
// 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") {
|
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
|
// if such family exists, try to match style to a font
|
||||||
do family.iter |fam| {
|
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" };
|
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
|
// Holds a specific font family, and the various
|
||||||
pub struct FontFamily {
|
pub struct FontFamily {
|
||||||
family_name: @str,
|
family_name: ~str,
|
||||||
entries: DVec<@FontEntry>,
|
entries: DVec<@FontEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl FontFamily {
|
pub impl FontFamily {
|
||||||
static fn new(family_name: &str) -> FontFamily {
|
static fn new(family_name: &str) -> FontFamily {
|
||||||
FontFamily {
|
FontFamily {
|
||||||
family_name: str::from_slice(family_name).to_managed(),
|
family_name: str::from_slice(family_name),
|
||||||
entries: DVec(),
|
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;
|
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
|
// TODO(Issue #189): optimize lookup for
|
||||||
// regular/bold/italic/bolditalic with fixed offsets and a
|
// regular/bold/italic/bolditalic with fixed offsets and a
|
||||||
|
|
|
@ -23,6 +23,10 @@ pub impl QuartzFontContextHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl QuartzFontContextHandle : FontContextHandleMethods {
|
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, ()> {
|
fn create_font_from_identifier(name: ~str, style: UsedFontStyle) -> Result<FontHandle, ()> {
|
||||||
let ctfont_result = CTFont::new_from_name(move name, style.pt_size);
|
let ctfont_result = CTFont::new_from_name(move name, style.pt_size);
|
||||||
do result::chain(move ctfont_result) |ctfont| {
|
do result::chain(move ctfont_result) |ctfont| {
|
||||||
|
|
|
@ -1,56 +1,57 @@
|
||||||
extern mod core_foundation;
|
extern mod core_foundation;
|
||||||
extern mod core_text;
|
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 = core_foundation;
|
||||||
use cf::array::CFArray;
|
use cf::array::CFArray;
|
||||||
use core::dvec::DVec;
|
use cf::string::CFString;
|
||||||
use core::send_map::{linear, SendMap};
|
|
||||||
use ct = core_text;
|
use ct = core_text;
|
||||||
use ct::font::{CTFont, debug_font_names, debug_font_traits};
|
use ct::font::{CTFont, debug_font_names, debug_font_traits};
|
||||||
use ct::font_collection::CTFontCollection;
|
use ct::font_collection::CTFontCollection;
|
||||||
use ct::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef, debug_descriptor};
|
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 {
|
pub struct QuartzFontListHandle {
|
||||||
collection: CTFontCollection,
|
fctx: QuartzFontContextHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl QuartzFontListHandle {
|
pub impl QuartzFontListHandle {
|
||||||
static pub fn new(_fctx: &native::FontContextHandle) -> QuartzFontListHandle {
|
static fn new(fctx: &native::FontContextHandle) -> QuartzFontListHandle {
|
||||||
QuartzFontListHandle { collection: CTFontCollection::new() }
|
QuartzFontListHandle { fctx: fctx.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_available_families(&const self,
|
fn get_available_families() -> FontFamilyMap {
|
||||||
fctx: &native::FontContextHandle)
|
let family_names = CTFontCollection::get_family_names();
|
||||||
-> linear::LinearMap<~str, @FontFamily> {
|
let mut family_map : FontFamilyMap = linear::LinearMap();
|
||||||
// since we mutate it repeatedly, must be mut variable.
|
for family_names.each |family_name_cfstr: &CFString| {
|
||||||
let mut family_map : linear::LinearMap<~str, @FontFamily> = linear::LinearMap();
|
let family_name = family_name_cfstr.to_str();
|
||||||
let descriptors : CFArray<CTFontDescriptorRef, CTFontDescriptor>;
|
debug!("Creating new FontFamily for family: %s", family_name);
|
||||||
descriptors = self.collection.get_descriptors();
|
|
||||||
for descriptors.each |desc: &CTFontDescriptor| {
|
let new_family = @FontFamily::new(family_name);
|
||||||
// TODO: for each descriptor, make a FontEntry.
|
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 font = CTFont::new_from_descriptor(desc, 0.0);
|
||||||
let handle = result::unwrap(QuartzFontHandle::new_from_CTFont(fctx, move font));
|
let handle = result::unwrap(QuartzFontHandle::new_from_CTFont(&self.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
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
debug!("Creating new FontEntry for face: %s", handle.face_name());
|
debug!("Creating new FontEntry for face: %s", handle.face_name());
|
||||||
let entry = @FontEntry::new(family, move handle);
|
let entry = @FontEntry::new(family, move handle);
|
||||||
family.entries.push(entry);
|
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