diff --git a/src/servo/gfx.rs b/src/servo/gfx.rs index dde9fe83a45..331d12ae507 100644 --- a/src/servo/gfx.rs +++ b/src/servo/gfx.rs @@ -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; diff --git a/src/servo/gfx/font.rs b/src/servo/gfx/font.rs index 37d27a40760..664d6330832 100644 --- a/src/servo/gfx/font.rs +++ b/src/servo/gfx/font.rs @@ -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, diff --git a/src/servo/gfx/font_list.rs b/src/servo/gfx/font_list.rs index 575b90ab630..6d100efe1fa 100644 --- a/src/servo/gfx/font_list.rs +++ b/src/servo/gfx/font_list.rs @@ -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); } } -} \ No newline at end of file + + 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 } +} diff --git a/src/servo/gfx/quartz/font_list.rs b/src/servo/gfx/quartz/font_list.rs index df774906215..dabd4db0a56 100644 --- a/src/servo/gfx/quartz/font_list.rs +++ b/src/servo/gfx/quartz/font_list.rs @@ -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};