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
pub struct FontFamily {
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

View file

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

View file

@ -8,7 +8,15 @@ use gfx::font::{
CSSFontWeight,
FontHandleMethods,
FontMetrics,
FontWeight100,
FontWeight200,
FontWeight300,
FontWeight400,
FontWeight500,
FontWeight600,
FontWeight700,
FontWeight800,
FontWeight900,
FractionalPixel
};
use text::glyph::GlyphIndex;
@ -40,15 +48,20 @@ use ct = core_text;
use ct::font::CTFont;
use ct::font_descriptor::{
kCTFontDefaultOrientation,
CTFontSymbolicTraits,
SymbolicTraitAccessors,
};
pub struct QuartzFontHandle {
cgfont: CGFontRef,
priv mut cgfont: Option<CGFontRef>,
ctfont: CTFont,
drop {
assert self.cgfont.is_not_null();
CGFontRelease(self.cgfont);
// TODO(Issue #152): use a wrapped 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 result = Ok(QuartzFontHandle {
cgfont : cgfont,
cgfont : Some(cgfont),
ctfont : move ctfont,
});
@ -72,28 +85,53 @@ pub impl QuartzFontHandle {
}
static fn new_from_CTFont(_fctx: &QuartzFontContextHandle, ctfont: CTFont) -> Result<QuartzFontHandle, ()> {
let cgfont = ctfont.copy_to_CGFont();
let result = Ok(QuartzFontHandle {
cgfont: cgfont,
mut cgfont: None,
ctfont: move ctfont,
});
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 {
pure fn family_name() -> ~str {
self.ctfont.family_name()
}
pure fn face_name() -> ~str {
self.ctfont.face_name()
}
pure fn is_italic() -> bool {
false // FIXME
self.ctfont.symbolic_traits().is_italic()
}
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,
};
use gfx::font::FontFamily;
use gfx::font::{
FontEntry,
FontFamily,
FontHandle,
};
use font::{QuartzFontHandle};
use dvec::DVec;
use send_map::{linear, SendMap};
pub struct QuartzFontListHandle {
collection: CTFontCollection,
@ -29,23 +36,32 @@ pub impl QuartzFontListHandle {
QuartzFontListHandle { collection: CTFontCollection::new() }
}
fn get_available_families(fctx: &native::FontContextHandle) -> ~[@FontFamily] {
// TODO: make a hashtable from family name to DVec<FontEntry>
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| {
//debug!("%?", { debug_descriptor(desc); () });
// TODO: for each descriptor, make a FontEntry.
let font = CTFont::new_from_descriptor(desc, 0.0);
debug!("family: %s", font.family_name());
debug!("face: %s", font.face_name());
debug!("%s", { debug_font_traits(&font); ~"--- DEBUG CTFONT TRAITS ---" });
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
}
};
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
}
let families: DVec<@FontFamily> = DVec();
// TODO: iterate over (key,val) pairs and create FontFamily instances
return move dvec::unwrap(move families);
return move family_map;
}
}
}

View file

@ -390,7 +390,7 @@ impl RenderBox : RenderBoxMethods {
* `origin` - Total offset from display list root flow to this box's owning flow
* `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) {
let box_bounds = self.d().position;