Finish collecting and storing FontList data.

This commit is contained in:
Brian J. Burg 2012-11-09 17:43:48 -08:00
parent b1c59aba61
commit c5161f1823
7 changed files with 98 additions and 33 deletions

@ -1 +1 @@
Subproject commit 0b37b31edb11c94916b1255221d522c170dce739 Subproject commit 9c398db2b0627b150eba88edc0eb861dfb4a28ac

@ -1 +1 @@
Subproject commit ce1f192686d0d4acebdcdc8280c9054826c81bf1 Subproject commit eb86bb090d6bbf5f543c75756b52ba42d1ec3ddf

View file

@ -171,7 +171,16 @@ pub impl FontSelector : cmp::Eq {
// 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: ~[@FontEntry], entries: DVec<@FontEntry>,
}
pub impl FontFamily {
static fn new(family_name: &str) -> FontFamily {
FontFamily {
family_name: str::from_slice(family_name).to_managed(),
entries: DVec(),
}
}
} }
// This struct is the result of mapping a specified FontStyle into the // This struct is the result of mapping a specified FontStyle into the

View file

@ -3,6 +3,7 @@ use gfx::{
}; };
use dvec::DVec; use dvec::DVec;
use send_map::{linear, SendMap};
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
type FontListHandle/& = quartz::font_list::QuartzFontListHandle; type FontListHandle/& = quartz::font_list::QuartzFontListHandle;
@ -22,9 +23,11 @@ pub impl FontListHandle {
} }
} }
type FontFamilyMap = linear::LinearMap<~str, @FontFamily>;
pub struct FontList { pub struct FontList {
families: DVec<@FontFamily>, mut family_map: FontFamilyMap,
handle: FontListHandle, mut handle: FontListHandle,
} }
pub impl FontList { pub impl FontList {
@ -32,18 +35,17 @@ pub impl FontList {
let handle = result::unwrap(FontListHandle::new(fctx)); let handle = result::unwrap(FontListHandle::new(fctx));
let list = FontList { let list = FontList {
handle: move handle, handle: move handle,
families: DVec(), family_map: linear::LinearMap(),
}; };
list.refresh(fctx); list.refresh(fctx);
return move list; return move list;
} }
priv fn refresh(fctx: &native::FontContextHandle) { priv fn refresh(fctx: &native::FontContextHandle) {
// TODO: don't refresh unless something actually changed. // TODO(Issue #186): don't refresh unless something actually
// Does OSX have a notification for this event? // changed. Does OSX have a notification for this event?
// It would be better to do piecemeal. do util::time::time("gfx::font_list: regenerating available font families and faces") {
do self.families.swap |_old_families: ~[@FontFamily]| { self.family_map = self.handle.get_available_families(fctx);
self.handle.get_available_families(fctx)
} }
} }
} }

View file

@ -8,7 +8,15 @@ use gfx::font::{
CSSFontWeight, CSSFontWeight,
FontHandleMethods, FontHandleMethods,
FontMetrics, FontMetrics,
FontWeight100,
FontWeight200,
FontWeight300,
FontWeight400,
FontWeight500, FontWeight500,
FontWeight600,
FontWeight700,
FontWeight800,
FontWeight900,
FractionalPixel FractionalPixel
}; };
use text::glyph::GlyphIndex; use text::glyph::GlyphIndex;
@ -40,15 +48,20 @@ use ct = core_text;
use ct::font::CTFont; use ct::font::CTFont;
use ct::font_descriptor::{ use ct::font_descriptor::{
kCTFontDefaultOrientation, kCTFontDefaultOrientation,
CTFontSymbolicTraits,
SymbolicTraitAccessors,
}; };
pub struct QuartzFontHandle { pub struct QuartzFontHandle {
cgfont: CGFontRef, priv mut cgfont: Option<CGFontRef>,
ctfont: CTFont, ctfont: CTFont,
drop { drop {
assert self.cgfont.is_not_null(); // TODO(Issue #152): use a wrapped CGFont.
CGFontRelease(self.cgfont); do (copy self.cgfont).iter |cgfont| {
assert cgfont.is_not_null();
CGFontRelease(*cgfont);
}
} }
} }
@ -64,7 +77,7 @@ pub impl QuartzFontHandle {
let ctfont = CTFont::new_from_CGFont(cgfont, pt_size); let ctfont = CTFont::new_from_CGFont(cgfont, pt_size);
let result = Ok(QuartzFontHandle { let result = Ok(QuartzFontHandle {
cgfont : cgfont, cgfont : Some(cgfont),
ctfont : move ctfont, ctfont : move ctfont,
}); });
@ -72,28 +85,53 @@ pub impl QuartzFontHandle {
} }
static fn new_from_CTFont(_fctx: &QuartzFontContextHandle, ctfont: CTFont) -> Result<QuartzFontHandle, ()> { static fn new_from_CTFont(_fctx: &QuartzFontContextHandle, ctfont: CTFont) -> Result<QuartzFontHandle, ()> {
let cgfont = ctfont.copy_to_CGFont();
let result = Ok(QuartzFontHandle { let result = Ok(QuartzFontHandle {
cgfont: cgfont, mut cgfont: None,
ctfont: move ctfont, ctfont: move ctfont,
}); });
return move result; return move result;
} }
fn get_CGFont() -> CGFontRef {
match self.cgfont {
Some(cg) => cg,
None => {
let cgfont = self.ctfont.copy_to_CGFont();
self.cgfont = Some(cgfont);
cgfont
}
}
}
} }
pub impl QuartzFontHandle : FontHandleMethods { pub impl QuartzFontHandle : FontHandleMethods {
pure fn family_name() -> ~str {
self.ctfont.family_name()
}
pure fn face_name() -> ~str { pure fn face_name() -> ~str {
self.ctfont.face_name() self.ctfont.face_name()
} }
pure fn is_italic() -> bool { pure fn is_italic() -> bool {
false // FIXME self.ctfont.symbolic_traits().is_italic()
} }
pure fn boldness() -> CSSFontWeight { pure fn boldness() -> CSSFontWeight {
FontWeight500 // FIXME // -1.0 to 1.0
let normalized = unsafe { self.ctfont.all_traits().normalized_weight() };
// 0.0 to 9.0
let normalized = (normalized + 1.0) / 2.0 * 9.0;
if normalized < 1.0 { return FontWeight100; }
if normalized < 2.0 { return FontWeight200; }
if normalized < 3.0 { return FontWeight300; }
if normalized < 4.0 { return FontWeight400; }
if normalized < 5.0 { return FontWeight500; }
if normalized < 6.0 { return FontWeight600; }
if normalized < 7.0 { return FontWeight700; }
if normalized < 8.0 { return FontWeight800; }
else { return FontWeight900; }
} }

View file

@ -16,9 +16,16 @@ use ct::font_descriptor::{
debug_descriptor, debug_descriptor,
}; };
use gfx::font::FontFamily; use gfx::font::{
FontEntry,
FontFamily,
FontHandle,
};
use font::{QuartzFontHandle};
use dvec::DVec; use dvec::DVec;
use send_map::{linear, SendMap};
pub struct QuartzFontListHandle { pub struct QuartzFontListHandle {
collection: CTFontCollection, collection: CTFontCollection,
@ -29,23 +36,32 @@ pub impl QuartzFontListHandle {
QuartzFontListHandle { collection: CTFontCollection::new() } QuartzFontListHandle { collection: CTFontCollection::new() }
} }
fn get_available_families(fctx: &native::FontContextHandle) -> ~[@FontFamily] { fn get_available_families(&const self,fctx: &native::FontContextHandle) -> linear::LinearMap<~str, @FontFamily> {
// TODO: make a hashtable from family name to DVec<FontEntry> // since we mutate it repeatedly, must be mut variable.
let mut family_map : linear::LinearMap<~str, @FontFamily> = linear::LinearMap();
let descriptors : CFArray<CTFontDescriptorRef, CTFontDescriptor>; let descriptors : CFArray<CTFontDescriptorRef, CTFontDescriptor>;
descriptors = self.collection.get_descriptors(); descriptors = self.collection.get_descriptors();
for descriptors.each |desc: &CTFontDescriptor| { for descriptors.each |desc: &CTFontDescriptor| {
//debug!("%?", { debug_descriptor(desc); () });
// TODO: for each descriptor, make a FontEntry. // TODO: for each descriptor, make a FontEntry.
let font = CTFont::new_from_descriptor(desc, 0.0); let font = CTFont::new_from_descriptor(desc, 0.0);
debug!("family: %s", font.family_name()); let handle = result::unwrap(QuartzFontHandle::new_from_CTFont(fctx, move font));
debug!("face: %s", font.face_name()); let family_name = handle.family_name();
debug!("%s", { debug_font_traits(&font); ~"--- DEBUG CTFONT TRAITS ---" }); 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());
let entry = @FontEntry::new(family, move handle);
family.entries.push(entry);
// TODO: append FontEntry to hashtable value // TODO: append FontEntry to hashtable value
} }
return move family_map;
let families: DVec<@FontFamily> = DVec();
// TODO: iterate over (key,val) pairs and create FontFamily instances
return move dvec::unwrap(move families);
} }
} }

View file

@ -390,7 +390,7 @@ impl RenderBox : RenderBoxMethods {
* `origin` - Total offset from display list root flow to this box's owning flow * `origin` - Total offset from display list root flow to this box's owning flow
* `list` - List to which items should be appended * `list` - List to which items should be appended
*/ */
fn build_display_list(@self, builder: &DisplayListBuilder, dirty: &Rect<Au>, fn build_display_list(@self, _builder: &DisplayListBuilder, dirty: &Rect<Au>,
offset: &Point2D<Au>, list: &mut DisplayList) { offset: &Point2D<Au>, list: &mut DisplayList) {
let box_bounds = self.d().position; let box_bounds = self.d().position;