servo: Move FontFamily/FontEntry to font_list.rs; implement strawman family/face matching.

Source-Repo: https://github.com/servo/servo
Source-Revision: 0034e2d6be11c30c37b0005b5a98ad1e6d025af6
This commit is contained in:
Brian J. Burg 2012-11-09 18:53:23 -08:00
parent 7bd95ccc60
commit 02d5e01517
4 changed files with 104 additions and 60 deletions

View File

@ -12,12 +12,12 @@ pub use display_list::DisplayItem;
pub use display_list::DisplayList;
pub use font::Font;
pub use font::FontDescriptor;
pub use font::FontFamily;
pub use font::FontGroup;
pub use font::FontSelector;
pub use font::FontStyle;
pub use font::RunMetrics;
pub use font_context::FontContext;
pub use font_list::FontFamily;
pub use font_list::FontList;
pub use geometry::Au;

View File

@ -82,6 +82,15 @@ enum CSSFontWeight {
}
pub impl CSSFontWeight : cmp::Eq;
pub impl CSSFontWeight {
pub pure fn is_bold() -> bool {
match self {
FontWeight900 | FontWeight800 | FontWeight700 | FontWeight600 => true,
_ => false
}
}
}
// TODO: eventually this will be split into the specified and used
// font styles. specified contains uninterpreted CSS font property
// values, while 'used' is attached to gfx::Font to descript the
@ -168,21 +177,6 @@ pub impl FontSelector : cmp::Eq {
pure fn ne(other: &FontSelector) -> bool { !self.eq(other) }
}
// Holds a specific font family, and the various
pub struct FontFamily {
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(),
entries: DVec(),
}
}
}
// This struct is the result of mapping a specified FontStyle into the
// available fonts on the system. It contains an ordered list of font
// instances to be used in case the prior font cannot be used for
@ -208,42 +202,6 @@ pub impl FontGroup {
}
}
// This struct summarizes an available font's features. In the future,
// this will include fiddly settings such as special font table handling.
// In the common case, each FontFamily will have a singleton FontEntry, or
// it will have the standard four faces: Normal, Bold, Italic, BoldItalic.
struct FontEntry {
family: @FontFamily,
face_name: ~str,
priv weight: CSSFontWeight,
priv italic: bool,
handle: FontHandle,
// TODO: array of OpenType features, etc.
}
impl FontEntry {
static fn new(family: @FontFamily, handle: FontHandle) -> FontEntry {
FontEntry {
family: family,
face_name: handle.face_name(),
weight: handle.boldness(),
italic: handle.is_italic(),
handle: move handle
}
}
pure fn is_bold() -> bool {
match self.weight {
FontWeight900 | FontWeight800 | FontWeight700 | FontWeight600 => true,
_ => false
}
}
pure fn is_italic() -> bool { self.italic }
}
struct RunMetrics {
// may be negative due to negative width (i.e., kerning of '.' in 'P.T.')
advance_width: Au,

View File

@ -1,6 +1,8 @@
use gfx::{
FontFamily,
use gfx::font::{
CSSFontWeight,
SpecifiedFontStyle,
};
use gfx::native::FontHandle;
use dvec::DVec;
use send_map::{linear, SendMap};
@ -48,4 +50,91 @@ pub impl FontList {
self.family_map = self.handle.get_available_families(fctx);
}
}
}
fn find_font_in_family(family_name: &str,
style: &SpecifiedFontStyle) -> Option<@FontEntry> {
let family = self.find_family(family_name);
let mut result : Option<@FontEntry> = None;
// if such family exists, try to match style to a font
do family.iter |fam| {
result = fam.find_font_for_style(style);
}
return result;
}
priv fn find_family(family_name: &str) -> Option<@FontFamily> {
// look up canonical name
let family = self.family_map.find(&str::from_slice(family_name));
// TODO(Issue #188): look up localized font family names if canonical name not found
return family;
}
}
// Holds a specific font family, and the various
pub struct FontFamily {
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(),
entries: DVec(),
}
}
pure fn find_font_for_style(style: &SpecifiedFontStyle) -> Option<@FontEntry> {
assert self.entries.len() > 0;
// TODO(Issue #189): optimize lookup for
// regular/bold/italic/bolditalic with fixed offsets and a
// static decision table for fallback between these values.
// TODO(Issue #190): if not in the fast path above, do
// expensive matching of weights, etc.
for self.entries.each |entry| {
if (style.weight.is_bold() == entry.is_bold()) &&
(style.italic == entry.is_italic()) {
return Some(*entry);
}
}
return None;
}
}
// This struct summarizes an available font's features. In the future,
// this will include fiddly settings such as special font table handling.
// In the common case, each FontFamily will have a singleton FontEntry, or
// it will have the standard four faces: Normal, Bold, Italic, BoldItalic.
struct FontEntry {
family: @FontFamily,
face_name: ~str,
priv weight: CSSFontWeight,
priv italic: bool,
handle: FontHandle,
// TODO: array of OpenType features, etc.
}
impl FontEntry {
static fn new(family: @FontFamily, handle: FontHandle) -> FontEntry {
FontEntry {
family: family,
face_name: handle.face_name(),
weight: handle.boldness(),
italic: handle.is_italic(),
handle: move handle
}
}
pure fn is_bold() -> bool {
self.weight.is_bold()
}
pure fn is_italic() -> bool { self.italic }
}

View File

@ -16,11 +16,8 @@ use ct::font_descriptor::{
debug_descriptor,
};
use gfx::font::{
FontEntry,
FontFamily,
FontHandle,
};
use gfx::font::FontHandle;
use gfx::font_list::FontEntry;
use font::{QuartzFontHandle};