mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
Format gfx platform #21373
This commit is contained in:
parent
5063ac465b
commit
c57c99d9f7
13 changed files with 496 additions and 372 deletions
|
@ -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 {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue