Format gfx platform #21373

This commit is contained in:
kingdido999 2018-09-05 08:39:05 +08:00
parent 5063ac465b
commit c57c99d9f7
13 changed files with 496 additions and 372 deletions

View file

@ -27,10 +27,18 @@ use text::glyph::GlyphId;
use truetype;
// 1em = 12pt = 16px, assuming 72 points per inch and 96 px per inch
fn pt_to_px(pt: f64) -> f64 { pt / 72. * 96. }
fn em_to_px(em: f64) -> f64 { em * 16. }
fn au_from_em(em: f64) -> Au { Au::from_f64_px(em_to_px(em)) }
fn au_from_pt(pt: f64) -> Au { Au::from_f64_px(pt_to_px(pt)) }
fn pt_to_px(pt: f64) -> f64 {
pt / 72. * 96.
}
fn em_to_px(em: f64) -> f64 {
em * 16.
}
fn au_from_em(em: f64) -> Au {
Au::from_f64_px(em_to_px(em))
}
fn au_from_pt(pt: f64) -> Au {
Au::from_f64_px(pt_to_px(pt))
}
pub struct FontTable {
data: Vec<u8>,
@ -38,7 +46,9 @@ pub struct FontTable {
impl FontTable {
pub fn wrap(data: &[u8]) -> FontTable {
FontTable { data: data.to_vec() }
FontTable {
data: data.to_vec(),
}
}
}
@ -139,7 +149,7 @@ impl FontInfo {
} else {
return Err(());
}
}
},
};
let mut os2_table_cursor = Cursor::new(os2_table_bytes.as_ref().unwrap());
@ -163,18 +173,20 @@ impl FontInfo {
let weight = StyleFontWeight(weight_val as f32);
let stretch = StyleFontStretch(NonNegative(match min(9, max(1, width_val)) {
1 => FontStretchKeyword::UltraCondensed,
2 => FontStretchKeyword::ExtraCondensed,
3 => FontStretchKeyword::Condensed,
4 => FontStretchKeyword::SemiCondensed,
5 => FontStretchKeyword::Normal,
6 => FontStretchKeyword::SemiExpanded,
7 => FontStretchKeyword::Expanded,
8 => FontStretchKeyword::ExtraExpanded,
9 => FontStretchKeyword::UltraExpanded,
_ => return Err(()),
}.compute()));
let stretch = StyleFontStretch(NonNegative(
match min(9, max(1, width_val)) {
1 => FontStretchKeyword::UltraCondensed,
2 => FontStretchKeyword::ExtraCondensed,
3 => FontStretchKeyword::Condensed,
4 => FontStretchKeyword::SemiCondensed,
5 => FontStretchKeyword::Normal,
6 => FontStretchKeyword::SemiExpanded,
7 => FontStretchKeyword::Expanded,
8 => FontStretchKeyword::ExtraExpanded,
9 => FontStretchKeyword::UltraExpanded,
_ => return Err(()),
}.compute(),
));
let style = if italic_bool {
GenericFontStyle::Italic
@ -212,18 +224,20 @@ impl FontInfo {
// slightly blacker black
FontWeight::ExtraBlack => 1000.,
});
let stretch = StyleFontStretch(NonNegative(match font.stretch() {
FontStretch::Undefined => FontStretchKeyword::Normal,
FontStretch::UltraCondensed => FontStretchKeyword::UltraCondensed,
FontStretch::ExtraCondensed => FontStretchKeyword::ExtraCondensed,
FontStretch::Condensed => FontStretchKeyword::Condensed,
FontStretch::SemiCondensed => FontStretchKeyword::SemiCondensed,
FontStretch::Normal => FontStretchKeyword::Normal,
FontStretch::SemiExpanded => FontStretchKeyword::SemiExpanded,
FontStretch::Expanded => FontStretchKeyword::Expanded,
FontStretch::ExtraExpanded => FontStretchKeyword::ExtraExpanded,
FontStretch::UltraExpanded => FontStretchKeyword::UltraExpanded,
}.compute()));
let stretch = StyleFontStretch(NonNegative(
match font.stretch() {
FontStretch::Undefined => FontStretchKeyword::Normal,
FontStretch::UltraCondensed => FontStretchKeyword::UltraCondensed,
FontStretch::ExtraCondensed => FontStretchKeyword::ExtraCondensed,
FontStretch::Condensed => FontStretchKeyword::Condensed,
FontStretch::SemiCondensed => FontStretchKeyword::SemiCondensed,
FontStretch::Normal => FontStretchKeyword::Normal,
FontStretch::SemiExpanded => FontStretchKeyword::SemiExpanded,
FontStretch::Expanded => FontStretchKeyword::Expanded,
FontStretch::ExtraExpanded => FontStretchKeyword::ExtraExpanded,
FontStretch::UltraExpanded => FontStretchKeyword::UltraExpanded,
}.compute(),
));
Ok(FontInfo {
family_name: font.family_name(),
@ -246,13 +260,14 @@ pub struct FontHandle {
scaled_du_to_px: f32,
}
impl FontHandle {
}
impl FontHandle {}
impl FontHandleMethods for FontHandle {
fn new_from_template(_: &FontContextHandle, template: Arc<FontTemplateData>, pt_size: Option<Au>)
-> Result<Self, ()>
{
fn new_from_template(
_: &FontContextHandle,
template: Arc<FontTemplateData>,
pt_size: Option<Au>,
) -> Result<Self, ()> {
let (info, face) = if let Some(ref raw_font) = template.bytes {
let font_file = FontFile::new_from_data(&raw_font);
if font_file.is_none() {
@ -260,7 +275,9 @@ impl FontHandleMethods for FontHandle {
return Err(());
}
let face = font_file.unwrap().create_face(0, dwrote::DWRITE_FONT_SIMULATIONS_NONE);
let face = font_file
.unwrap()
.create_face(0, dwrote::DWRITE_FONT_SIMULATIONS_NONE);
let info = FontInfo::new_from_face(&face)?;
(info, face)
} else {
@ -350,32 +367,34 @@ impl FontHandleMethods for FontHandle {
let dm = self.face.metrics();
let au_from_du = |du| -> Au { Au::from_f32_px(du as f32 * self.du_to_px) };
let au_from_du_s = |du| -> Au { Au:: from_f32_px(du as f32 * self.scaled_du_to_px) };
let au_from_du_s = |du| -> Au { Au::from_f32_px(du as f32 * self.scaled_du_to_px) };
// anything that we calculate and don't just pull out of self.face.metrics
// is pulled out here for clarity
let leading = dm.ascent - dm.capHeight;
let metrics = FontMetrics {
underline_size: au_from_du(dm.underlineThickness as i32),
underline_size: au_from_du(dm.underlineThickness as i32),
underline_offset: au_from_du_s(dm.underlinePosition as i32),
strikeout_size: au_from_du(dm.strikethroughThickness as i32),
strikeout_size: au_from_du(dm.strikethroughThickness as i32),
strikeout_offset: au_from_du_s(dm.strikethroughPosition as i32),
leading: au_from_du_s(leading as i32),
x_height: au_from_du_s(dm.xHeight as i32),
em_size: au_from_em(self.em_size as f64),
ascent: au_from_du_s(dm.ascent as i32),
descent: au_from_du_s(dm.descent as i32),
max_advance: au_from_pt(0.0), // FIXME
average_advance: au_from_pt(0.0), // FIXME
line_gap: au_from_du_s((dm.ascent + dm.descent + dm.lineGap as u16) as i32),
leading: au_from_du_s(leading as i32),
x_height: au_from_du_s(dm.xHeight as i32),
em_size: au_from_em(self.em_size as f64),
ascent: au_from_du_s(dm.ascent as i32),
descent: au_from_du_s(dm.descent as i32),
max_advance: au_from_pt(0.0), // FIXME
average_advance: au_from_pt(0.0), // FIXME
line_gap: au_from_du_s((dm.ascent + dm.descent + dm.lineGap as u16) as i32),
};
debug!("Font metrics (@{} pt): {:?}", self.em_size * 12., metrics);
metrics
}
fn table_for_tag(&self, tag: FontTableTag) -> Option<FontTable> {
self.face.get_font_table(tag).map(|bytes| FontTable { data: bytes })
self.face
.get_font_table(tag)
.map(|bytes| FontTable { data: bytes })
}
fn identifier(&self) -> Atom {

View file

@ -21,7 +21,10 @@ pub fn system_default_family(_: &str) -> Option<String> {
Some("Verdana".to_owned())
}
pub fn for_each_available_family<F>(mut callback: F) where F: FnMut(String) {
pub fn for_each_available_family<F>(mut callback: F)
where
F: FnMut(String),
{
let system_fc = FontCollection::system();
for family in system_fc.families_iter() {
callback(family.name());
@ -37,7 +40,10 @@ pub fn for_each_available_family<F>(mut callback: F) where F: FnMut(String) {
// we'll stringify, and then put them all in a HashMap with
// the actual FontDescriptor there.
pub fn for_each_variation<F>(family_name: &str, mut callback: F) where F: FnMut(String) {
pub fn for_each_variation<F>(family_name: &str, mut callback: F)
where
F: FnMut(String),
{
let system_fc = FontCollection::system();
if let Some(family) = system_fc.get_font_family_by_name(family_name) {
let count = family.get_font_count();
@ -65,12 +71,14 @@ pub fn descriptor_from_atom(ident: &Atom) -> FontDescriptor {
pub fn font_from_atom(ident: &Atom) -> Font {
let fonts = FONT_ATOM_MAP.lock().unwrap();
FontCollection::system().get_font_from_descriptor(fonts.get(ident).unwrap()).unwrap()
FontCollection::system()
.get_font_from_descriptor(fonts.get(ident).unwrap())
.unwrap()
}
// Based on gfxWindowsPlatform::GetCommonFallbackFonts() in Gecko
pub fn fallback_font_families(codepoint: Option<char>) -> Vec<&'static str> {
let mut families = vec!("Arial");
let mut families = vec!["Arial"];
if let Some(codepoint) = codepoint {
match unicode_plane(codepoint) {
@ -83,31 +91,29 @@ pub fn fallback_font_families(codepoint: Option<char>) -> Vec<&'static str> {
UnicodeBlock::Hebrew => {
families.push("Estrangelo Edessa");
families.push("Cambria");
}
},
UnicodeBlock::Arabic |
UnicodeBlock::ArabicSupplement => {
UnicodeBlock::Arabic | UnicodeBlock::ArabicSupplement => {
families.push("Microsoft Uighur");
}
},
UnicodeBlock::Syriac => {
families.push("Estrangelo Edessa");
}
},
UnicodeBlock::Thaana => {
families.push("MV Boli");
}
},
UnicodeBlock::NKo => {
families.push("Ebrima");
}
},
UnicodeBlock::Devanagari |
UnicodeBlock::Bengali => {
UnicodeBlock::Devanagari | UnicodeBlock::Bengali => {
families.push("Nirmala UI");
families.push("Utsaah");
families.push("Aparajita");
}
},
UnicodeBlock::Gurmukhi |
UnicodeBlock::Gujarati |
@ -123,21 +129,21 @@ pub fn fallback_font_families(codepoint: Option<char>) -> Vec<&'static str> {
UnicodeBlock::SundaneseSupplement |
UnicodeBlock::VedicExtensions => {
families.push("Nirmala UI");
}
},
UnicodeBlock::Thai => {
families.push("Leelawadee UI");
}
},
UnicodeBlock::Lao => {
families.push("Lao UI");
}
},
UnicodeBlock::Myanmar |
UnicodeBlock::MyanmarExtendedA |
UnicodeBlock::MyanmarExtendedB => {
families.push("Myanmar Text");
}
},
UnicodeBlock::HangulJamo |
UnicodeBlock::HangulJamoExtendedA |
@ -145,48 +151,47 @@ pub fn fallback_font_families(codepoint: Option<char>) -> Vec<&'static str> {
UnicodeBlock::HangulJamoExtendedB |
UnicodeBlock::HangulCompatibilityJamo => {
families.push("Malgun Gothic");
}
},
UnicodeBlock::Ethiopic |
UnicodeBlock::EthiopicSupplement |
UnicodeBlock::EthiopicExtended |
UnicodeBlock::EthiopicExtendedA => {
families.push("Nyala");
}
},
UnicodeBlock::Cherokee => {
families.push("Plantagenet Cherokee");
}
},
UnicodeBlock::UnifiedCanadianAboriginalSyllabics |
UnicodeBlock::UnifiedCanadianAboriginalSyllabicsExtended => {
families.push("Euphemia");
families.push("Segoe UI");
}
},
UnicodeBlock::Khmer |
UnicodeBlock::KhmerSymbols => {
UnicodeBlock::Khmer | UnicodeBlock::KhmerSymbols => {
families.push("Khmer UI");
families.push("Leelawadee UI");
}
},
UnicodeBlock::Mongolian => {
families.push("Mongolian Baiti");
}
},
UnicodeBlock::TaiLe => {
families.push("Microsoft Tai Le");
}
},
UnicodeBlock::NewTaiLue => {
families.push("Microsoft New Tai Lue");
}
},
UnicodeBlock::Buginese |
UnicodeBlock::TaiTham |
UnicodeBlock::CombiningDiacriticalMarksExtended => {
families.push("Leelawadee UI");
}
},
UnicodeBlock::GeneralPunctuation |
UnicodeBlock::SuperscriptsandSubscripts |
@ -220,7 +225,7 @@ pub fn fallback_font_families(codepoint: Option<char>) -> Vec<&'static str> {
families.push("Meiryo");
families.push("Lucida Sans Unicode");
families.push("Ebrima");
}
},
UnicodeBlock::GeorgianSupplement |
UnicodeBlock::Tifinagh |
@ -232,11 +237,11 @@ pub fn fallback_font_families(codepoint: Option<char>) -> Vec<&'static str> {
families.push("Segoe UI");
families.push("Segoe UI Symbol");
families.push("Meiryo");
}
},
UnicodeBlock::BraillePatterns => {
families.push("Segoe UI Symbol");
}
},
UnicodeBlock::CJKSymbolsandPunctuation |
UnicodeBlock::Hiragana |
@ -249,21 +254,20 @@ pub fn fallback_font_families(codepoint: Option<char>) -> Vec<&'static str> {
UnicodeBlock::CJKUnifiedIdeographs => {
families.push("Microsoft YaHei");
families.push("Yu Gothic");
}
},
UnicodeBlock::EnclosedCJKLettersandMonths => {
families.push("Malgun Gothic");
}
},
UnicodeBlock::YijingHexagramSymbols => {
families.push("Segoe UI Symbol");
}
},
UnicodeBlock::YiSyllables |
UnicodeBlock::YiRadicals => {
UnicodeBlock::YiSyllables | UnicodeBlock::YiRadicals => {
families.push("Microsoft Yi Baiti");
families.push("Segoe UI");
}
},
UnicodeBlock::Vai |
UnicodeBlock::CyrillicExtendedB |
@ -273,36 +277,34 @@ pub fn fallback_font_families(codepoint: Option<char>) -> Vec<&'static str> {
families.push("Ebrima");
families.push("Segoe UI");
families.push("Cambria Math");
}
},
UnicodeBlock::SylotiNagri |
UnicodeBlock::CommonIndicNumberForms |
UnicodeBlock::Phagspa |
UnicodeBlock::Saurashtra |
UnicodeBlock::DevanagariExtended => {
families.push("Microsoft PhagsPa");
families.push("Nirmala UI");
}
families.push("Microsoft PhagsPa");
families.push("Nirmala UI");
},
UnicodeBlock::KayahLi |
UnicodeBlock::Rejang |
UnicodeBlock::Javanese => {
families.push("Malgun Gothic");
families.push("Javanese Text");
families.push("Leelawadee UI");
}
UnicodeBlock::KayahLi | UnicodeBlock::Rejang | UnicodeBlock::Javanese => {
families.push("Malgun Gothic");
families.push("Javanese Text");
families.push("Leelawadee UI");
},
UnicodeBlock::AlphabeticPresentationForms => {
families.push("Microsoft Uighur");
families.push("Gabriola");
families.push("Sylfaen");
}
},
UnicodeBlock::ArabicPresentationFormsA |
UnicodeBlock::ArabicPresentationFormsB => {
families.push("Traditional Arabic");
families.push("Arabic Typesetting");
}
},
UnicodeBlock::VariationSelectors |
UnicodeBlock::VerticalForms |
@ -312,12 +314,12 @@ pub fn fallback_font_families(codepoint: Option<char>) -> Vec<&'static str> {
UnicodeBlock::HalfwidthandFullwidthForms |
UnicodeBlock::Specials => {
families.push("Microsoft JhengHei");
}
},
_ => {}
_ => {},
}
}
}
},
// https://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane
1 => {
@ -325,9 +327,9 @@ pub fn fallback_font_families(codepoint: Option<char>) -> Vec<&'static str> {
families.push("Ebrima");
families.push("Nirmala UI");
families.push("Cambria Math");
}
},
_ => {}
_ => {},
}
}

View file

@ -11,7 +11,6 @@ use webrender_api::NativeFontHandle;
#[derive(Deserialize, Serialize)]
pub struct FontTemplateData {
// If you add members here, review the Debug impl below
pub bytes: Option<Vec<u8>>,
pub identifier: Atom,
}
@ -19,20 +18,22 @@ pub struct FontTemplateData {
impl fmt::Debug for FontTemplateData {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("FontTemplateData")
.field(
"bytes",
&self.bytes
.field(
"bytes",
&self
.bytes
.as_ref()
.map(|bytes| format!("[{} bytes]", bytes.len()))
)
.field("identifier", &self.identifier)
.finish()
.map(|bytes| format!("[{} bytes]", bytes.len())),
).field("identifier", &self.identifier)
.finish()
}
}
impl FontTemplateData {
pub fn new(identifier: Atom,
font_data: Option<Vec<u8>>) -> Result<FontTemplateData, io::Error> {
pub fn new(
identifier: Atom,
font_data: Option<Vec<u8>>,
) -> Result<FontTemplateData, io::Error> {
Ok(FontTemplateData {
bytes: font_data,
identifier: identifier,