mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Implement downloadable fonts on Windows
This commit is contained in:
parent
68fa988bf3
commit
a9611c31a7
5 changed files with 245 additions and 57 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -955,6 +955,7 @@ dependencies = [
|
||||||
"style 0.0.1",
|
"style 0.0.1",
|
||||||
"style_traits 0.0.1",
|
"style_traits 0.0.1",
|
||||||
"time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"truetype 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"webrender_traits 0.11.0 (git+https://github.com/servo/webrender)",
|
"webrender_traits 0.11.0 (git+https://github.com/servo/webrender)",
|
||||||
"xi-unicode 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"xi-unicode 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -3022,6 +3023,11 @@ name = "traitobject"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "truetype"
|
||||||
|
version = "0.24.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typeable"
|
name = "typeable"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
@ -3607,6 +3613,7 @@ dependencies = [
|
||||||
"checksum tinyfiledialogs 2.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d401358cd71aca93d5f4fccd3db5b87d970ae70fe457911929d99f4a87f7531"
|
"checksum tinyfiledialogs 2.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d401358cd71aca93d5f4fccd3db5b87d970ae70fe457911929d99f4a87f7531"
|
||||||
"checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796"
|
"checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796"
|
||||||
"checksum traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "07eaeb7689bb7fca7ce15628319635758eda769fed481ecfe6686ddef2600616"
|
"checksum traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "07eaeb7689bb7fca7ce15628319635758eda769fed481ecfe6686ddef2600616"
|
||||||
|
"checksum truetype 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)" = "87167c7d6d14725f614d16761de2bb71c01ee374989936b49797d3db1a02bcdd"
|
||||||
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
|
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
|
||||||
"checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764"
|
"checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764"
|
||||||
"checksum unicode-bidi 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b61814f3e7fd0e0f15370f767c7c943e08bc2e3214233ae8f88522b334ceb778"
|
"checksum unicode-bidi 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b61814f3e7fd0e0f15370f767c7c943e08bc2e3214233ae8f88522b334ceb778"
|
||||||
|
|
|
@ -60,4 +60,5 @@ servo-fontconfig = "0.2.1"
|
||||||
simd = {git = "https://github.com/huonw/simd"}
|
simd = {git = "https://github.com/huonw/simd"}
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
dwrote = "0.1.1"
|
dwrote = "0.1.5"
|
||||||
|
truetype = "0.24"
|
||||||
|
|
|
@ -29,6 +29,7 @@ extern crate bitflags;
|
||||||
|
|
||||||
// Windows-specific library dependencies
|
// Windows-specific library dependencies
|
||||||
#[cfg(target_os = "windows")] extern crate dwrote;
|
#[cfg(target_os = "windows")] extern crate dwrote;
|
||||||
|
#[cfg(target_os = "windows")] extern crate truetype;
|
||||||
|
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
extern crate fnv;
|
extern crate fnv;
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
// renderer moves to a sandboxed process.
|
// renderer moves to a sandboxed process.
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use dwrote::{Font, FontFace};
|
use dwrote;
|
||||||
|
use dwrote::{Font, FontFace, FontFile};
|
||||||
use dwrote::{FontWeight, FontStretch, FontStyle};
|
use dwrote::{FontWeight, FontStretch, FontStyle};
|
||||||
use font::{FontHandleMethods, FontMetrics, FontTableMethods};
|
use font::{FontHandleMethods, FontMetrics, FontTableMethods};
|
||||||
use font::{FontTableTag, FractionalPixel};
|
use font::{FontTableTag, FractionalPixel};
|
||||||
|
@ -17,6 +18,7 @@ use platform::windows::font_list::font_from_atom;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style::computed_values::{font_stretch, font_weight};
|
use style::computed_values::{font_stretch, font_weight};
|
||||||
use text::glyph::GlyphId;
|
use text::glyph::GlyphId;
|
||||||
|
use truetype;
|
||||||
|
|
||||||
// 1em = 12pt = 16px, assuming 72 points per inch and 96 px per inch
|
// 1em = 12pt = 16px, assuming 72 points per inch and 96 px per inch
|
||||||
fn pt_to_px(pt: f64) -> f64 { pt / 72. * 96. }
|
fn pt_to_px(pt: f64) -> f64 { pt / 72. * 96. }
|
||||||
|
@ -40,11 +42,205 @@ impl FontTableMethods for FontTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_tag(tag_bytes: &[u8]) -> FontTableTag {
|
||||||
|
assert_eq!(tag_bytes.len(), 4);
|
||||||
|
unsafe { *(tag_bytes.as_ptr() as *const FontTableTag) }
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! try_lossy(($result:expr) => (try!($result.map_err(|_| (())))));
|
||||||
|
|
||||||
|
// Given a set of records, figure out the string indices for the family and face
|
||||||
|
// names. We want name_id 1 and 2, and we need to use platform_id == 1 and
|
||||||
|
// language_id == 0 to avoid limitations in the truetype crate. We *could* just
|
||||||
|
// do our own parsing here, and use the offset/length data and pull the values out
|
||||||
|
// ourselves.
|
||||||
|
fn get_family_face_indices(records: &[truetype::naming_table::Record]) -> Option<(usize, usize)> {
|
||||||
|
let mut family_name_index = None;
|
||||||
|
let mut face_name_index = None;
|
||||||
|
|
||||||
|
for i in 0..records.len() {
|
||||||
|
// the truetype crate can only decode mac platform format names
|
||||||
|
if records[i].platform_id != 1 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if records[i].language_id != 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if records[i].name_id == 1 {
|
||||||
|
family_name_index = Some(i);
|
||||||
|
} else if records[i].name_id == 2 {
|
||||||
|
face_name_index = Some(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if family_name_index.is_some() && face_name_index.is_some() {
|
||||||
|
Some((family_name_index.unwrap(), face_name_index.unwrap()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need the font (DWriteFont) in order to be able to query things like
|
||||||
|
// the family name, face name, weight, etc. On Windows 10, the
|
||||||
|
// DWriteFontFace3 interface provides this on the FontFace, but that's only
|
||||||
|
// available on Win10+.
|
||||||
|
//
|
||||||
|
// Instead, we do the parsing work using the truetype crate for raw fonts.
|
||||||
|
// We're just extracting basic info, so this is sufficient for now.
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct FontInfo {
|
||||||
|
family_name: String,
|
||||||
|
face_name: String,
|
||||||
|
weight: font_weight::T,
|
||||||
|
stretch: font_stretch::T,
|
||||||
|
style: FontStyle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FontInfo {
|
||||||
|
fn new_from_face(face: &FontFace) -> Result<FontInfo, ()> {
|
||||||
|
use std::cmp::{min, max};
|
||||||
|
use std::io::Cursor;
|
||||||
|
use truetype::{NamingTable, Value, WindowsMetrics};
|
||||||
|
|
||||||
|
let name_table_bytes = face.get_font_table(make_tag(b"name"));
|
||||||
|
let os2_table_bytes = face.get_font_table(make_tag(b"OS/2"));
|
||||||
|
if name_table_bytes.is_none() || os2_table_bytes.is_none() {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut name_table_cursor = Cursor::new(name_table_bytes.as_ref().unwrap());
|
||||||
|
let names = try_lossy!(NamingTable::read(&mut name_table_cursor));
|
||||||
|
let (family, face) = match names {
|
||||||
|
NamingTable::Format0(ref table) => {
|
||||||
|
if let Some((family_index, face_index)) = get_family_face_indices(&table.records) {
|
||||||
|
let strings = table.strings().unwrap();
|
||||||
|
let family = strings[family_index].clone();
|
||||||
|
let face = strings[face_index].clone();
|
||||||
|
((family, face))
|
||||||
|
} else {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
NamingTable::Format1(ref table) => {
|
||||||
|
if let Some((family_index, face_index)) = get_family_face_indices(&table.records) {
|
||||||
|
let strings = table.strings().unwrap();
|
||||||
|
let family = strings[family_index].clone();
|
||||||
|
let face = strings[face_index].clone();
|
||||||
|
((family, face))
|
||||||
|
} else {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut os2_table_cursor = Cursor::new(os2_table_bytes.as_ref().unwrap());
|
||||||
|
let metrics = try_lossy!(WindowsMetrics::read(&mut os2_table_cursor));
|
||||||
|
let (weight_val, width_val, italic_bool) = match metrics {
|
||||||
|
WindowsMetrics::Version0(ref m) => {
|
||||||
|
(m.weight_class, m.width_class, m.selection_flags.0 & 1 == 1)
|
||||||
|
},
|
||||||
|
WindowsMetrics::Version1(ref m) => {
|
||||||
|
(m.weight_class, m.width_class, m.selection_flags.0 & 1 == 1)
|
||||||
|
},
|
||||||
|
WindowsMetrics::Version2(ref m) |
|
||||||
|
WindowsMetrics::Version3(ref m) |
|
||||||
|
WindowsMetrics::Version4(ref m) => {
|
||||||
|
(m.weight_class, m.width_class, m.selection_flags.0 & 1 == 1)
|
||||||
|
},
|
||||||
|
WindowsMetrics::Version5(ref m) => {
|
||||||
|
(m.weight_class, m.width_class, m.selection_flags.0 & 1 == 1)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let weight = match min(9, max(1, weight_val / 100)) {
|
||||||
|
1 => font_weight::T::Weight100,
|
||||||
|
2 => font_weight::T::Weight200,
|
||||||
|
3 => font_weight::T::Weight300,
|
||||||
|
4 => font_weight::T::Weight400,
|
||||||
|
5 => font_weight::T::Weight500,
|
||||||
|
6 => font_weight::T::Weight600,
|
||||||
|
7 => font_weight::T::Weight700,
|
||||||
|
8 => font_weight::T::Weight800,
|
||||||
|
9 => font_weight::T::Weight900,
|
||||||
|
_ => return Err(()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let stretch = match min(9, max(1, width_val)) {
|
||||||
|
1 => font_stretch::T::ultra_condensed,
|
||||||
|
2 => font_stretch::T::extra_condensed,
|
||||||
|
3 => font_stretch::T::condensed,
|
||||||
|
4 => font_stretch::T::semi_condensed,
|
||||||
|
5 => font_stretch::T::normal,
|
||||||
|
6 => font_stretch::T::semi_expanded,
|
||||||
|
7 => font_stretch::T::expanded,
|
||||||
|
8 => font_stretch::T::extra_expanded,
|
||||||
|
9 => font_stretch::T::ultra_expanded,
|
||||||
|
_ => return Err(()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let style = if italic_bool {
|
||||||
|
FontStyle::Italic
|
||||||
|
} else {
|
||||||
|
FontStyle::Normal
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(FontInfo {
|
||||||
|
family_name: family,
|
||||||
|
face_name: face,
|
||||||
|
weight: weight,
|
||||||
|
stretch: stretch,
|
||||||
|
style: style,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_from_font(font: &Font) -> Result<FontInfo, ()> {
|
||||||
|
let style = font.style();
|
||||||
|
let weight = match font.weight() {
|
||||||
|
FontWeight::Thin => font_weight::T::Weight100,
|
||||||
|
FontWeight::ExtraLight => font_weight::T::Weight200,
|
||||||
|
FontWeight::Light => font_weight::T::Weight300,
|
||||||
|
// slightly grayer gray
|
||||||
|
FontWeight::SemiLight => font_weight::T::Weight300,
|
||||||
|
FontWeight::Regular => font_weight::T::Weight400,
|
||||||
|
FontWeight::Medium => font_weight::T::Weight500,
|
||||||
|
FontWeight::SemiBold => font_weight::T::Weight600,
|
||||||
|
FontWeight::Bold => font_weight::T::Weight700,
|
||||||
|
FontWeight::ExtraBold => font_weight::T::Weight800,
|
||||||
|
FontWeight::Black => font_weight::T::Weight900,
|
||||||
|
// slightly blacker black
|
||||||
|
FontWeight::ExtraBlack => font_weight::T::Weight900,
|
||||||
|
};
|
||||||
|
let stretch = match font.stretch() {
|
||||||
|
FontStretch::Undefined => font_stretch::T::normal,
|
||||||
|
FontStretch::UltraCondensed => font_stretch::T::ultra_condensed,
|
||||||
|
FontStretch::ExtraCondensed => font_stretch::T::extra_condensed,
|
||||||
|
FontStretch::Condensed => font_stretch::T::condensed,
|
||||||
|
FontStretch::SemiCondensed => font_stretch::T::semi_condensed,
|
||||||
|
FontStretch::Normal => font_stretch::T::normal,
|
||||||
|
FontStretch::SemiExpanded => font_stretch::T::semi_expanded,
|
||||||
|
FontStretch::Expanded => font_stretch::T::expanded,
|
||||||
|
FontStretch::ExtraExpanded => font_stretch::T::extra_expanded,
|
||||||
|
FontStretch::UltraExpanded => font_stretch::T::ultra_expanded,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(FontInfo {
|
||||||
|
family_name: font.family_name(),
|
||||||
|
face_name: font.face_name(),
|
||||||
|
style: style,
|
||||||
|
weight: weight,
|
||||||
|
stretch: stretch,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FontHandle {
|
pub struct FontHandle {
|
||||||
font_data: Arc<FontTemplateData>,
|
font_data: Arc<FontTemplateData>,
|
||||||
font: Font,
|
|
||||||
face: FontFace,
|
face: FontFace,
|
||||||
|
info: FontInfo,
|
||||||
em_size: f32,
|
em_size: f32,
|
||||||
du_per_em: f32,
|
du_per_em: f32,
|
||||||
du_to_px: f32,
|
du_to_px: f32,
|
||||||
|
@ -58,32 +254,41 @@ impl FontHandleMethods for FontHandle {
|
||||||
fn new_from_template(_: &FontContextHandle, template: Arc<FontTemplateData>, pt_size: Option<Au>)
|
fn new_from_template(_: &FontContextHandle, template: Arc<FontTemplateData>, pt_size: Option<Au>)
|
||||||
-> Result<Self, ()>
|
-> Result<Self, ()>
|
||||||
{
|
{
|
||||||
if let Some(_) = template.bytes {
|
let (info, face) = if let Some(ref raw_font) = template.bytes {
|
||||||
// FIXME we should load from template.bytes
|
let font_file = FontFile::new_from_data(&raw_font);
|
||||||
Err(())
|
if font_file.is_none() {
|
||||||
|
// failed to load raw font
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let face = font_file.unwrap().create_face(0, dwrote::DWRITE_FONT_SIMULATIONS_NONE);
|
||||||
|
let info = try!(FontInfo::new_from_face(&face));
|
||||||
|
(info, face)
|
||||||
} else {
|
} else {
|
||||||
let font = font_from_atom(&template.identifier);
|
let font = font_from_atom(&template.identifier);
|
||||||
let face = font.create_font_face();
|
let face = font.create_font_face();
|
||||||
|
let info = try!(FontInfo::new_from_font(&font));
|
||||||
|
(info, face)
|
||||||
|
};
|
||||||
|
|
||||||
let pt_size = pt_size.unwrap_or(au_from_pt(12.));
|
let pt_size = pt_size.unwrap_or(au_from_pt(12.));
|
||||||
let du_per_em = face.metrics().designUnitsPerEm as f32;
|
let du_per_em = face.metrics().designUnitsPerEm as f32;
|
||||||
|
|
||||||
let em_size = pt_size.to_f32_px() / 16.;
|
let em_size = pt_size.to_f32_px() / 16.;
|
||||||
let design_units_per_pixel = du_per_em / 16.;
|
let design_units_per_pixel = du_per_em / 16.;
|
||||||
|
|
||||||
let design_units_to_pixels = 1. / design_units_per_pixel;
|
let design_units_to_pixels = 1. / design_units_per_pixel;
|
||||||
let scaled_design_units_to_pixels = em_size / design_units_per_pixel;
|
let scaled_design_units_to_pixels = em_size / design_units_per_pixel;
|
||||||
|
|
||||||
Ok(FontHandle {
|
Ok(FontHandle {
|
||||||
font_data: template.clone(),
|
font_data: template.clone(),
|
||||||
font: font,
|
face: face,
|
||||||
face: face,
|
info: info,
|
||||||
em_size: em_size,
|
em_size: em_size,
|
||||||
du_per_em: du_per_em,
|
du_per_em: du_per_em,
|
||||||
du_to_px: design_units_to_pixels,
|
du_to_px: design_units_to_pixels,
|
||||||
scaled_du_to_px: scaled_design_units_to_pixels,
|
scaled_du_to_px: scaled_design_units_to_pixels,
|
||||||
})
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn template(&self) -> Arc<FontTemplateData> {
|
fn template(&self) -> Arc<FontTemplateData> {
|
||||||
|
@ -91,51 +296,26 @@ impl FontHandleMethods for FontHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn family_name(&self) -> String {
|
fn family_name(&self) -> String {
|
||||||
self.font.family_name()
|
self.info.family_name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn face_name(&self) -> String {
|
fn face_name(&self) -> String {
|
||||||
self.font.face_name()
|
self.info.face_name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_italic(&self) -> bool {
|
fn is_italic(&self) -> bool {
|
||||||
match self.font.style() {
|
match self.info.style {
|
||||||
FontStyle::Normal => false,
|
FontStyle::Normal => false,
|
||||||
FontStyle::Oblique | FontStyle::Italic => true,
|
FontStyle::Oblique | FontStyle::Italic => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn boldness(&self) -> font_weight::T {
|
fn boldness(&self) -> font_weight::T {
|
||||||
match self.font.weight() {
|
self.info.weight
|
||||||
FontWeight::Thin => font_weight::T::Weight100,
|
|
||||||
FontWeight::ExtraLight => font_weight::T::Weight200,
|
|
||||||
FontWeight::Light => font_weight::T::Weight300,
|
|
||||||
// slightly lighter gray
|
|
||||||
FontWeight::SemiLight => font_weight::T::Weight300,
|
|
||||||
FontWeight::Regular => font_weight::T::Weight400,
|
|
||||||
FontWeight::Medium => font_weight::T::Weight500,
|
|
||||||
FontWeight::SemiBold => font_weight::T::Weight600,
|
|
||||||
FontWeight::Bold => font_weight::T::Weight700,
|
|
||||||
FontWeight::ExtraBold => font_weight::T::Weight800,
|
|
||||||
FontWeight::Black => font_weight::T::Weight900,
|
|
||||||
// slightly blacker black
|
|
||||||
FontWeight::ExtraBlack => font_weight::T::Weight900,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stretchiness(&self) -> font_stretch::T {
|
fn stretchiness(&self) -> font_stretch::T {
|
||||||
match self.font.stretch() {
|
self.info.stretch
|
||||||
FontStretch::Undefined => font_stretch::T::normal,
|
|
||||||
FontStretch::UltraCondensed => font_stretch::T::ultra_condensed,
|
|
||||||
FontStretch::ExtraCondensed => font_stretch::T::extra_condensed,
|
|
||||||
FontStretch::Condensed => font_stretch::T::condensed,
|
|
||||||
FontStretch::SemiCondensed => font_stretch::T::semi_condensed,
|
|
||||||
FontStretch::Normal => font_stretch::T::normal,
|
|
||||||
FontStretch::SemiExpanded => font_stretch::T::semi_expanded,
|
|
||||||
FontStretch::Expanded => font_stretch::T::expanded,
|
|
||||||
FontStretch::ExtraExpanded => font_stretch::T::extra_expanded,
|
|
||||||
FontStretch::UltraExpanded => font_stretch::T::ultra_expanded,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glyph_index(&self, codepoint: char) -> Option<GlyphId> {
|
fn glyph_index(&self, codepoint: char) -> Option<GlyphId> {
|
||||||
|
|
|
@ -40,11 +40,10 @@ impl FontTemplateData {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn native_font(&self) -> Option<NativeFontHandle> {
|
pub fn native_font(&self) -> Option<NativeFontHandle> {
|
||||||
if self.bytes.is_some() {
|
if self.bytes.is_none() {
|
||||||
panic!("Can't create fonts yet");
|
Some(descriptor_from_atom(&self.identifier))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
let descriptor = descriptor_from_atom(&self.identifier);
|
|
||||||
Some(descriptor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue