mirror of
https://github.com/servo/servo.git
synced 2025-08-29 17:18:23 +01:00
fonts: Add more types to fonts_traits
(#38898)
This is necessary so that `constellation_traits` can get these types via a dependency on `fonts_traits`. This will allow sending IPC channels to shared workers so that they can have access to a shared `FontContext` from `script`. Testing: This just moves code between crates, so is covered by existing tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
0b5bcfbf17
commit
3a97d4eed2
22 changed files with 495 additions and 446 deletions
9
Cargo.lock
generated
9
Cargo.lock
generated
|
@ -2669,7 +2669,6 @@ name = "fonts"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units",
|
"app_units",
|
||||||
"atomic_refcell",
|
|
||||||
"base",
|
"base",
|
||||||
"bitflags 2.9.3",
|
"bitflags 2.9.3",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
@ -2721,11 +2720,19 @@ dependencies = [
|
||||||
name = "fonts_traits"
|
name = "fonts_traits"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"atomic_refcell",
|
||||||
|
"dwrote",
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
|
"log",
|
||||||
"malloc_size_of_derive",
|
"malloc_size_of_derive",
|
||||||
|
"memmap2",
|
||||||
"range",
|
"range",
|
||||||
|
"read-fonts",
|
||||||
"serde",
|
"serde",
|
||||||
"servo_malloc_size_of",
|
"servo_malloc_size_of",
|
||||||
|
"servo_url",
|
||||||
|
"stylo",
|
||||||
|
"webrender_api",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -55,6 +55,7 @@ ctr = "0.9.2"
|
||||||
data-url = "0.3"
|
data-url = "0.3"
|
||||||
devtools_traits = { path = "components/shared/devtools" }
|
devtools_traits = { path = "components/shared/devtools" }
|
||||||
dpi = "0.1"
|
dpi = "0.1"
|
||||||
|
dwrote = "0.11.4"
|
||||||
embedder_traits = { path = "components/shared/embedder" }
|
embedder_traits = { path = "components/shared/embedder" }
|
||||||
encoding_rs = "0.8"
|
encoding_rs = "0.8"
|
||||||
env_logger = "0.11"
|
env_logger = "0.11"
|
||||||
|
|
|
@ -18,7 +18,6 @@ tracing = ["dep:tracing"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
app_units = { workspace = true }
|
app_units = { workspace = true }
|
||||||
atomic_refcell = { workspace = true }
|
|
||||||
base = { workspace = true }
|
base = { workspace = true }
|
||||||
bitflags = { workspace = true }
|
bitflags = { workspace = true }
|
||||||
compositing_traits = { workspace = true }
|
compositing_traits = { workspace = true }
|
||||||
|
@ -73,7 +72,7 @@ fontconfig_sys = { package = "yeslogic-fontconfig-sys", version = "6" }
|
||||||
xml-rs = "0.8"
|
xml-rs = "0.8"
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
dwrote = "0.11.4"
|
dwrote = { workspace = true }
|
||||||
winapi = { workspace = true }
|
winapi = { workspace = true }
|
||||||
|
|
||||||
[lints.rust]
|
[lints.rust]
|
||||||
|
|
|
@ -15,6 +15,7 @@ use app_units::Au;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use euclid::default::{Point2D, Rect, Size2D};
|
use euclid::default::{Point2D, Rect, Size2D};
|
||||||
use euclid::num::Zero;
|
use euclid::num::Zero;
|
||||||
|
use fonts_traits::FontDescriptor;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use malloc_size_of_derive::MallocSizeOf;
|
use malloc_size_of_derive::MallocSizeOf;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
@ -190,44 +191,6 @@ impl FontMetrics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `FontDescriptor` describes the parameters of a `Font`. It represents rendering a given font
|
|
||||||
/// template at a particular size, with a particular font-variant-caps applied, etc. This contrasts
|
|
||||||
/// with `FontTemplateDescriptor` in that the latter represents only the parameters inherent in the
|
|
||||||
/// font data (weight, stretch, etc.).
|
|
||||||
#[derive(Clone, Debug, Deserialize, Hash, MallocSizeOf, PartialEq, Serialize)]
|
|
||||||
pub struct FontDescriptor {
|
|
||||||
pub weight: FontWeight,
|
|
||||||
pub stretch: FontStretch,
|
|
||||||
pub style: FontStyle,
|
|
||||||
pub variant: font_variant_caps::T,
|
|
||||||
pub pt_size: Au,
|
|
||||||
pub variation_settings: Vec<FontVariation>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for FontDescriptor {}
|
|
||||||
|
|
||||||
impl<'a> From<&'a FontStyleStruct> for FontDescriptor {
|
|
||||||
fn from(style: &'a FontStyleStruct) -> Self {
|
|
||||||
let variation_settings = style
|
|
||||||
.clone_font_variation_settings()
|
|
||||||
.0
|
|
||||||
.into_iter()
|
|
||||||
.map(|setting| FontVariation {
|
|
||||||
tag: setting.tag.0,
|
|
||||||
value: setting.value,
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
FontDescriptor {
|
|
||||||
weight: style.font_weight,
|
|
||||||
stretch: style.font_stretch,
|
|
||||||
style: style.font_style,
|
|
||||||
variant: style.font_variant_caps,
|
|
||||||
pt_size: Au::from_f32_px(style.font_size.computed_size().px()),
|
|
||||||
variation_settings,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
struct CachedShapeData {
|
struct CachedShapeData {
|
||||||
glyph_advances: HashMap<GlyphId, FractionalPixel>,
|
glyph_advances: HashMap<GlyphId, FractionalPixel>,
|
||||||
|
|
|
@ -13,7 +13,10 @@ use app_units::Au;
|
||||||
use base::id::WebViewId;
|
use base::id::WebViewId;
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessCompositorApi;
|
||||||
use fnv::FnvHasher;
|
use fnv::FnvHasher;
|
||||||
use fonts_traits::StylesheetWebFontLoadFinishedCallback;
|
use fonts_traits::{
|
||||||
|
CSSFontFaceDescriptors, FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef,
|
||||||
|
FontTemplateRefMethods, StylesheetWebFontLoadFinishedCallback,
|
||||||
|
};
|
||||||
use log::{debug, trace};
|
use log::{debug, trace};
|
||||||
use malloc_size_of_derive::MallocSizeOf;
|
use malloc_size_of_derive::MallocSizeOf;
|
||||||
use net_traits::request::{Destination, Referrer, RequestBuilder};
|
use net_traits::request::{Destination, Referrer, RequestBuilder};
|
||||||
|
@ -35,13 +38,9 @@ use style::values::computed::font::{FamilyName, FontFamilyNameSyntax, SingleFont
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use webrender_api::{FontInstanceFlags, FontInstanceKey, FontKey, FontVariation};
|
use webrender_api::{FontInstanceFlags, FontInstanceKey, FontKey, FontVariation};
|
||||||
|
|
||||||
use crate::font::{
|
use crate::font::{Font, FontFamilyDescriptor, FontGroup, FontRef, FontSearchScope};
|
||||||
Font, FontDescriptor, FontFamilyDescriptor, FontGroup, FontRef, FontSearchScope,
|
|
||||||
};
|
|
||||||
use crate::font_store::CrossThreadFontStore;
|
use crate::font_store::CrossThreadFontStore;
|
||||||
use crate::font_template::{FontTemplate, FontTemplateRef, FontTemplateRefMethods};
|
|
||||||
use crate::platform::font::PlatformFont;
|
use crate::platform::font::PlatformFont;
|
||||||
use crate::system_font_service::{CSSFontFaceDescriptors, FontIdentifier};
|
|
||||||
use crate::{FontData, LowercaseFontFamilyName, PlatformFontMethods, SystemFontServiceProxy};
|
use crate::{FontData, LowercaseFontFamilyName, PlatformFontMethods, SystemFontServiceProxy};
|
||||||
|
|
||||||
static SMALL_CAPS_SCALE_FACTOR: f32 = 0.8; // Matches FireFox (see gfxFont.h)
|
static SMALL_CAPS_SCALE_FACTOR: f32 = 0.8; // Matches FireFox (see gfxFont.h)
|
||||||
|
|
|
@ -6,16 +6,16 @@ use std::collections::HashMap;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use fonts_traits::{
|
||||||
|
FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef, FontTemplateRefMethods,
|
||||||
|
IsOblique, LowercaseFontFamilyName,
|
||||||
|
};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use malloc_size_of_derive::MallocSizeOf;
|
use malloc_size_of_derive::MallocSizeOf;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use style::stylesheets::DocumentStyleSheet;
|
use style::stylesheets::DocumentStyleSheet;
|
||||||
use style::values::computed::{FontStyle, FontWeight};
|
use style::values::computed::{FontStyle, FontWeight};
|
||||||
|
|
||||||
use crate::font::FontDescriptor;
|
|
||||||
use crate::font_template::{FontTemplate, FontTemplateRef, FontTemplateRefMethods, IsOblique};
|
|
||||||
use crate::system_font_service::{FontIdentifier, LowercaseFontFamilyName};
|
|
||||||
|
|
||||||
#[derive(Default, MallocSizeOf)]
|
#[derive(Default, MallocSizeOf)]
|
||||||
pub struct FontStore {
|
pub struct FontStore {
|
||||||
pub(crate) families: HashMap<LowercaseFontFamilyName, FontTemplates>,
|
pub(crate) families: HashMap<LowercaseFontFamilyName, FontTemplates>,
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
mod font;
|
mod font;
|
||||||
mod font_context;
|
mod font_context;
|
||||||
mod font_store;
|
mod font_store;
|
||||||
mod font_template;
|
|
||||||
mod glyph;
|
mod glyph;
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub mod platform;
|
pub mod platform;
|
||||||
|
@ -17,10 +16,8 @@ mod system_font_service;
|
||||||
pub use font::*;
|
pub use font::*;
|
||||||
pub use font_context::*;
|
pub use font_context::*;
|
||||||
pub use font_store::*;
|
pub use font_store::*;
|
||||||
pub use font_template::*;
|
pub use fonts_traits::{LocalFontIdentifier, *};
|
||||||
pub use fonts_traits::*;
|
|
||||||
pub use glyph::*;
|
pub use glyph::*;
|
||||||
pub use platform::LocalFontIdentifier;
|
|
||||||
pub use shapers::*;
|
pub use shapers::*;
|
||||||
pub use system_font_service::*;
|
pub use system_font_service::*;
|
||||||
use unicode_properties::{EmojiStatus, UnicodeEmoji, emoji};
|
use unicode_properties::{EmojiStatus, UnicodeEmoji, emoji};
|
||||||
|
|
|
@ -7,6 +7,7 @@ use std::fs::File;
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use euclid::default::{Point2D, Rect, Size2D};
|
use euclid::default::{Point2D, Rect, Size2D};
|
||||||
|
use fonts_traits::{FontIdentifier, FontTemplateDescriptor, LocalFontIdentifier};
|
||||||
use freetype_sys::{
|
use freetype_sys::{
|
||||||
FT_F26Dot6, FT_Get_Char_Index, FT_Get_Kerning, FT_GlyphSlot, FT_KERNING_DEFAULT,
|
FT_F26Dot6, FT_Get_Char_Index, FT_Get_Kerning, FT_GlyphSlot, FT_KERNING_DEFAULT,
|
||||||
FT_LOAD_DEFAULT, FT_LOAD_NO_HINTING, FT_Load_Glyph, FT_Size_Metrics, FT_SizeRec, FT_UInt,
|
FT_LOAD_DEFAULT, FT_LOAD_NO_HINTING, FT_Load_Glyph, FT_Size_Metrics, FT_SizeRec, FT_UInt,
|
||||||
|
@ -21,14 +22,11 @@ use servo_arc::Arc;
|
||||||
use style::Zero;
|
use style::Zero;
|
||||||
use webrender_api::{FontInstanceFlags, FontVariation};
|
use webrender_api::{FontInstanceFlags, FontVariation};
|
||||||
|
|
||||||
use super::LocalFontIdentifier;
|
|
||||||
use super::library_handle::FreeTypeLibraryHandle;
|
use super::library_handle::FreeTypeLibraryHandle;
|
||||||
use crate::FontData;
|
use crate::FontData;
|
||||||
use crate::font::{FontMetrics, FontTableMethods, FractionalPixel, PlatformFontMethods};
|
use crate::font::{FontMetrics, FontTableMethods, FractionalPixel, PlatformFontMethods};
|
||||||
use crate::font_template::FontTemplateDescriptor;
|
|
||||||
use crate::glyph::GlyphId;
|
use crate::glyph::GlyphId;
|
||||||
use crate::platform::freetype::freetype_face::FreeTypeFace;
|
use crate::platform::freetype::freetype_face::FreeTypeFace;
|
||||||
use crate::system_font_service::FontIdentifier;
|
|
||||||
|
|
||||||
/// Convert FreeType-style 26.6 fixed point to an [`f64`].
|
/// Convert FreeType-style 26.6 fixed point to an [`f64`].
|
||||||
fn fixed_26_dot_6_to_float(fixed: FT_F26Dot6) -> f64 {
|
fn fixed_26_dot_6_to_float(fixed: FT_F26Dot6) -> f64 {
|
||||||
|
|
|
@ -19,6 +19,7 @@ use fontconfig_sys::{
|
||||||
FcObjectSetCreate, FcObjectSetDestroy, FcPattern, FcPatternAddString, FcPatternCreate,
|
FcObjectSetCreate, FcObjectSetDestroy, FcPattern, FcPatternAddString, FcPatternCreate,
|
||||||
FcPatternDestroy, FcPatternGetInteger, FcPatternGetString, FcResultMatch, FcSetSystem,
|
FcPatternDestroy, FcPatternGetInteger, FcPatternGetString, FcResultMatch, FcSetSystem,
|
||||||
};
|
};
|
||||||
|
use fonts_traits::{FontTemplate, FontTemplateDescriptor, LocalFontIdentifier};
|
||||||
use libc::{c_char, c_int};
|
use libc::{c_char, c_int};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use style::Atom;
|
use style::Atom;
|
||||||
|
@ -26,9 +27,7 @@ use style::values::computed::font::GenericFontFamily;
|
||||||
use style::values::computed::{FontStretch, FontStyle, FontWeight};
|
use style::values::computed::{FontStretch, FontStyle, FontWeight};
|
||||||
use unicode_script::Script;
|
use unicode_script::Script;
|
||||||
|
|
||||||
use super::LocalFontIdentifier;
|
|
||||||
use crate::font::map_platform_values_to_style_values;
|
use crate::font::map_platform_values_to_style_values;
|
||||||
use crate::font_template::{FontTemplate, FontTemplateDescriptor};
|
|
||||||
use crate::platform::add_noto_fallback_families;
|
use crate::platform::add_noto_fallback_families;
|
||||||
use crate::{
|
use crate::{
|
||||||
EmojiPresentationPreference, FallbackFontSelectionOptions, FontIdentifier,
|
EmojiPresentationPreference, FallbackFontSelectionOptions, FontIdentifier,
|
||||||
|
|
|
@ -2,19 +2,6 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::convert::TryInto;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::str;
|
|
||||||
|
|
||||||
use malloc_size_of_derive::MallocSizeOf;
|
|
||||||
use memmap2::Mmap;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use style::Atom;
|
|
||||||
use webrender_api::NativeFontHandle;
|
|
||||||
|
|
||||||
use crate::{FontData, FontDataAndIndex};
|
|
||||||
|
|
||||||
pub mod font;
|
pub mod font;
|
||||||
mod freetype_face;
|
mod freetype_face;
|
||||||
|
|
||||||
|
@ -37,36 +24,3 @@ mod ohos {
|
||||||
pub use self::ohos::font_list;
|
pub use self::ohos::font_list;
|
||||||
|
|
||||||
mod library_handle;
|
mod library_handle;
|
||||||
|
|
||||||
/// An identifier for a local font on systems using Freetype.
|
|
||||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
|
||||||
pub struct LocalFontIdentifier {
|
|
||||||
/// The path to the font.
|
|
||||||
pub path: Atom,
|
|
||||||
/// The variation index within the font.
|
|
||||||
pub variation_index: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LocalFontIdentifier {
|
|
||||||
pub(crate) fn index(&self) -> u32 {
|
|
||||||
self.variation_index.try_into().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn native_font_handle(&self) -> NativeFontHandle {
|
|
||||||
NativeFontHandle {
|
|
||||||
path: PathBuf::from(&*self.path),
|
|
||||||
index: self.variation_index as u32,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn font_data_and_index(&self) -> Option<FontDataAndIndex> {
|
|
||||||
let file = File::open(Path::new(&*self.path)).ok()?;
|
|
||||||
let mmap = unsafe { Mmap::map(&file).ok()? };
|
|
||||||
let data = FontData::from_bytes(&mmap);
|
|
||||||
|
|
||||||
Some(FontDataAndIndex {
|
|
||||||
data,
|
|
||||||
index: self.variation_index as u32,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,12 +13,12 @@ use core_foundation::string::{CFString, CFStringRef};
|
||||||
use core_foundation::url::{CFURL, kCFURLPOSIXPathStyle};
|
use core_foundation::url::{CFURL, kCFURLPOSIXPathStyle};
|
||||||
use core_graphics::display::CFDictionary;
|
use core_graphics::display::CFDictionary;
|
||||||
use core_text::font_descriptor::{kCTFontURLAttribute, kCTFontVariationAttribute};
|
use core_text::font_descriptor::{kCTFontURLAttribute, kCTFontVariationAttribute};
|
||||||
|
use fonts_traits::FontIdentifier;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use webrender_api::FontVariation;
|
use webrender_api::FontVariation;
|
||||||
|
|
||||||
use crate::FontData;
|
use crate::FontData;
|
||||||
use crate::platform::font::PlatformFont;
|
use crate::platform::font::PlatformFont;
|
||||||
use crate::system_font_service::FontIdentifier;
|
|
||||||
|
|
||||||
/// A cache of `CTFont` to avoid having to create `CTFont` instances over and over. It is
|
/// A cache of `CTFont` to avoid having to create `CTFont` instances over and over. It is
|
||||||
/// always possible to create a `CTFont` using a `FontTemplate` even if it isn't in this
|
/// always possible to create a `CTFont` using a `FontTemplate` even if it isn't in this
|
||||||
|
|
|
@ -17,16 +17,16 @@ use core_text::font_descriptor::{
|
||||||
CTFontTraits, SymbolicTraitAccessors, TraitAccessors, kCTFontDefaultOrientation,
|
CTFontTraits, SymbolicTraitAccessors, TraitAccessors, kCTFontDefaultOrientation,
|
||||||
};
|
};
|
||||||
use euclid::default::{Point2D, Rect, Size2D};
|
use euclid::default::{Point2D, Rect, Size2D};
|
||||||
|
use fonts_traits::{FontIdentifier, LocalFontIdentifier};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use skrifa::Tag;
|
use skrifa::Tag;
|
||||||
use style::values::computed::font::{FontStretch, FontStyle, FontWeight};
|
use style::values::computed::font::{FontStretch, FontStyle, FontWeight};
|
||||||
use webrender_api::{FontInstanceFlags, FontVariation};
|
use webrender_api::{FontInstanceFlags, FontVariation};
|
||||||
|
|
||||||
use super::core_text_font_cache::CoreTextFontCache;
|
use super::core_text_font_cache::CoreTextFontCache;
|
||||||
use super::font_list::LocalFontIdentifier;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
CBDT, COLR, FontData, FontIdentifier, FontMetrics, FontTableMethods, FontTemplateDescriptor,
|
CBDT, COLR, FontData, FontMetrics, FontTableMethods, FontTemplateDescriptor, FractionalPixel,
|
||||||
FractionalPixel, GlyphId, KERN, PlatformFontMethods, SBIX, map_platform_values_to_style_values,
|
GlyphId, KERN, PlatformFontMethods, SBIX, map_platform_values_to_style_values,
|
||||||
};
|
};
|
||||||
|
|
||||||
const KERN_PAIR_LEN: usize = 6;
|
const KERN_PAIR_LEN: usize = 6;
|
||||||
|
|
|
@ -2,107 +2,20 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::fs::File;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use base::text::{UnicodeBlock, UnicodeBlockMethod, unicode_plane};
|
use base::text::{UnicodeBlock, UnicodeBlockMethod, unicode_plane};
|
||||||
use log::{debug, warn};
|
use fonts_traits::LocalFontIdentifier;
|
||||||
use malloc_size_of_derive::MallocSizeOf;
|
use log::debug;
|
||||||
use memmap2::Mmap;
|
|
||||||
use read_fonts::types::NameId;
|
|
||||||
use read_fonts::{FileRef, TableProvider as _};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use style::Atom;
|
use style::Atom;
|
||||||
use style::values::computed::font::GenericFontFamily;
|
use style::values::computed::font::GenericFontFamily;
|
||||||
use unicode_script::Script;
|
use unicode_script::Script;
|
||||||
use webrender_api::NativeFontHandle;
|
|
||||||
|
|
||||||
use crate::platform::add_noto_fallback_families;
|
use crate::platform::add_noto_fallback_families;
|
||||||
use crate::platform::font::CoreTextFontTraitsMapping;
|
use crate::platform::font::CoreTextFontTraitsMapping;
|
||||||
use crate::{
|
use crate::{
|
||||||
EmojiPresentationPreference, FallbackFontSelectionOptions, FontData, FontDataAndIndex,
|
EmojiPresentationPreference, FallbackFontSelectionOptions, FontIdentifier, FontTemplate,
|
||||||
FontIdentifier, FontTemplate, FontTemplateDescriptor, LowercaseFontFamilyName,
|
FontTemplateDescriptor, LowercaseFontFamilyName,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An identifier for a local font on a MacOS system. These values comes from the CoreText
|
|
||||||
/// CTFontCollection. Note that `path` here is required. We do not load fonts that do not
|
|
||||||
/// have paths.
|
|
||||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
|
||||||
pub struct LocalFontIdentifier {
|
|
||||||
pub postscript_name: Atom,
|
|
||||||
pub path: Atom,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LocalFontIdentifier {
|
|
||||||
pub(crate) fn native_font_handle(&self) -> NativeFontHandle {
|
|
||||||
NativeFontHandle {
|
|
||||||
name: self.postscript_name.to_string(),
|
|
||||||
path: self.path.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn index(&self) -> u32 {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn font_data_and_index(&self) -> Option<FontDataAndIndex> {
|
|
||||||
let file = File::open(Path::new(&*self.path)).ok()?;
|
|
||||||
let mmap = unsafe { Mmap::map(&file).ok()? };
|
|
||||||
|
|
||||||
// Determine index
|
|
||||||
let file_ref = FileRef::new(mmap.as_ref()).ok()?;
|
|
||||||
let index = ttc_index_from_postscript_name(file_ref, &self.postscript_name);
|
|
||||||
|
|
||||||
Some(FontDataAndIndex {
|
|
||||||
data: FontData::from_bytes(&mmap),
|
|
||||||
index,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// CoreText font enumeration gives us a Postscript name rather than an index.
|
|
||||||
/// This functions maps from a Postscript name to an index.
|
|
||||||
///
|
|
||||||
/// This mapping works for single-font files and for simple TTC files, but may not work in all cases.
|
|
||||||
/// We are not 100% sure which cases (if any) will not work. But we suspect that variable fonts may cause
|
|
||||||
/// issues due to the Postscript names corresponding to instances not being straightforward, and the possibility
|
|
||||||
/// that CoreText may return a non-standard in that scenerio.
|
|
||||||
fn ttc_index_from_postscript_name(font_file: FileRef<'_>, postscript_name: &str) -> u32 {
|
|
||||||
match font_file {
|
|
||||||
// File only contains one font: simply return 0
|
|
||||||
FileRef::Font(_) => 0,
|
|
||||||
// File is a collection: iterate through each font in the collection and check
|
|
||||||
// whether the name matches
|
|
||||||
FileRef::Collection(collection) => {
|
|
||||||
for i in 0..collection.len() {
|
|
||||||
let font = collection.get(i).unwrap();
|
|
||||||
let name_table = font.name().unwrap();
|
|
||||||
if name_table
|
|
||||||
.name_record()
|
|
||||||
.iter()
|
|
||||||
.filter(|record| record.name_id() == NameId::POSTSCRIPT_NAME)
|
|
||||||
.any(|record| {
|
|
||||||
record
|
|
||||||
.string(name_table.string_data())
|
|
||||||
.unwrap()
|
|
||||||
.chars()
|
|
||||||
.eq(postscript_name.chars())
|
|
||||||
})
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we fail to find a font, just use the first font in the file.
|
|
||||||
warn!(
|
|
||||||
"Font with postscript_name {} not found in collection",
|
|
||||||
postscript_name
|
|
||||||
);
|
|
||||||
0
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn for_each_available_family<F>(mut callback: F)
|
pub fn for_each_available_family<F>(mut callback: F)
|
||||||
where
|
where
|
||||||
F: FnMut(String),
|
F: FnMut(String),
|
||||||
|
|
|
@ -22,13 +22,11 @@ use unicode_script::Script;
|
||||||
))]
|
))]
|
||||||
use crate::FallbackFontSelectionOptions;
|
use crate::FallbackFontSelectionOptions;
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
pub use crate::platform::freetype::{LocalFontIdentifier, font, font_list};
|
pub use crate::platform::freetype::{font, font_list};
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
pub use crate::platform::macos::{
|
pub use crate::platform::macos::{core_text_font_cache, font, font_list};
|
||||||
core_text_font_cache, font, font_list, font_list::LocalFontIdentifier,
|
|
||||||
};
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
pub use crate::platform::windows::{font, font_list, font_list::LocalFontIdentifier};
|
pub use crate::platform::windows::{font, font_list};
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
pub mod freetype;
|
pub mod freetype;
|
||||||
|
|
|
@ -17,6 +17,7 @@ use dwrote::{
|
||||||
DWRITE_FONT_AXIS_VALUE, DWRITE_FONT_SIMULATIONS_NONE, FontCollection, FontFace, FontFile,
|
DWRITE_FONT_AXIS_VALUE, DWRITE_FONT_SIMULATIONS_NONE, FontCollection, FontFace, FontFile,
|
||||||
};
|
};
|
||||||
use euclid::default::{Point2D, Rect, Size2D};
|
use euclid::default::{Point2D, Rect, Size2D};
|
||||||
|
use fonts_traits::LocalFontIdentifier;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use read_fonts::TableProvider;
|
use read_fonts::TableProvider;
|
||||||
use skrifa::Tag;
|
use skrifa::Tag;
|
||||||
|
@ -24,7 +25,6 @@ use style::Zero;
|
||||||
use webrender_api::{FontInstanceFlags, FontVariation};
|
use webrender_api::{FontInstanceFlags, FontVariation};
|
||||||
use winapi::shared::minwindef::{BOOL, FALSE};
|
use winapi::shared::minwindef::{BOOL, FALSE};
|
||||||
|
|
||||||
use super::font_list::LocalFontIdentifier;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
FontData, FontIdentifier, FontMetrics, FontTableMethods, FontTemplateDescriptor,
|
FontData, FontIdentifier, FontMetrics, FontTableMethods, FontTemplateDescriptor,
|
||||||
FractionalPixel, GlyphId, PlatformFontMethods,
|
FractionalPixel, GlyphId, PlatformFontMethods,
|
||||||
|
|
|
@ -2,21 +2,18 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::hash::Hash;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use base::text::{UnicodeBlock, UnicodeBlockMethod, unicode_plane};
|
use base::text::{UnicodeBlock, UnicodeBlockMethod, unicode_plane};
|
||||||
use dwrote::{Font, FontCollection, FontDescriptor, FontStretch, FontStyle};
|
use dwrote::{Font, FontCollection, FontStretch, FontStyle};
|
||||||
use malloc_size_of_derive::MallocSizeOf;
|
use fonts_traits::LocalFontIdentifier;
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use style::values::computed::font::GenericFontFamily;
|
use style::values::computed::font::GenericFontFamily;
|
||||||
use style::values::computed::{FontStyle as StyleFontStyle, FontWeight as StyleFontWeight};
|
use style::values::computed::{FontStyle as StyleFontStyle, FontWeight as StyleFontWeight};
|
||||||
use style::values::specified::font::FontStretchKeyword;
|
use style::values::specified::font::FontStretchKeyword;
|
||||||
use webrender_api::NativeFontHandle;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
EmojiPresentationPreference, FallbackFontSelectionOptions, FontData, FontDataAndIndex,
|
EmojiPresentationPreference, FallbackFontSelectionOptions, FontIdentifier, FontTemplate,
|
||||||
FontIdentifier, FontTemplate, FontTemplateDescriptor, LowercaseFontFamilyName,
|
FontTemplateDescriptor, LowercaseFontFamilyName,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn for_each_available_family<F>(mut callback: F)
|
pub fn for_each_available_family<F>(mut callback: F)
|
||||||
|
@ -31,71 +28,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An identifier for a local font on a Windows system.
|
|
||||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
|
|
||||||
pub struct LocalFontIdentifier {
|
|
||||||
/// The FontDescriptor of this font.
|
|
||||||
#[ignore_malloc_size_of = "dwrote does not support MallocSizeOf"]
|
|
||||||
pub font_descriptor: Arc<FontDescriptor>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LocalFontIdentifier {
|
|
||||||
pub fn index(&self) -> u32 {
|
|
||||||
FontCollection::system()
|
|
||||||
.font_from_descriptor(&self.font_descriptor)
|
|
||||||
.ok()
|
|
||||||
.flatten()
|
|
||||||
.map_or(0, |font| font.create_font_face().get_index())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn native_font_handle(&self) -> NativeFontHandle {
|
|
||||||
let face = FontCollection::system()
|
|
||||||
.font_from_descriptor(&self.font_descriptor)
|
|
||||||
.ok()
|
|
||||||
.flatten()
|
|
||||||
.expect("Could not create Font from FontDescriptor")
|
|
||||||
.create_font_face();
|
|
||||||
let path = face
|
|
||||||
.files()
|
|
||||||
.ok()
|
|
||||||
.and_then(|files| files.first().cloned())
|
|
||||||
.expect("Could not get FontFace files")
|
|
||||||
.font_file_path()
|
|
||||||
.ok()
|
|
||||||
.expect("Could not get FontFace files path");
|
|
||||||
NativeFontHandle {
|
|
||||||
path,
|
|
||||||
index: face.get_index(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn font_data_and_index(&self) -> Option<FontDataAndIndex> {
|
|
||||||
let font = FontCollection::system()
|
|
||||||
.font_from_descriptor(&self.font_descriptor)
|
|
||||||
.ok()??;
|
|
||||||
let face = font.create_font_face();
|
|
||||||
let index = face.get_index();
|
|
||||||
let files = face.files().ok()?;
|
|
||||||
assert!(!files.is_empty());
|
|
||||||
|
|
||||||
let data = files[0].font_file_bytes().ok()?;
|
|
||||||
let data = FontData::from_bytes(&data);
|
|
||||||
|
|
||||||
Some(FontDataAndIndex { data, index })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for LocalFontIdentifier {}
|
|
||||||
|
|
||||||
impl Hash for LocalFontIdentifier {
|
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
|
||||||
self.font_descriptor.family_name.hash(state);
|
|
||||||
self.font_descriptor.weight.to_u32().hash(state);
|
|
||||||
self.font_descriptor.stretch.to_u32().hash(state);
|
|
||||||
self.font_descriptor.style.to_u32().hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn for_each_variation<F>(family_name: &str, mut callback: F)
|
pub fn for_each_variation<F>(family_name: &str, mut callback: F)
|
||||||
where
|
where
|
||||||
F: FnMut(FontTemplate),
|
F: FnMut(FontTemplate),
|
||||||
|
@ -107,7 +39,7 @@ where
|
||||||
let Ok(font) = family.font(i) else {
|
let Ok(font) = family.font(i) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let template_descriptor = (&font).into();
|
let template_descriptor = font_template_descriptor_from_font(&font);
|
||||||
let local_font_identifier = LocalFontIdentifier {
|
let local_font_identifier = LocalFontIdentifier {
|
||||||
font_descriptor: Arc::new(font.to_descriptor()),
|
font_descriptor: Arc::new(font.to_descriptor()),
|
||||||
};
|
};
|
||||||
|
@ -383,29 +315,27 @@ pub fn fallback_font_families(options: FallbackFontSelectionOptions) -> Vec<&'st
|
||||||
families
|
families
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Font> for FontTemplateDescriptor {
|
fn font_template_descriptor_from_font(font: &Font) -> FontTemplateDescriptor {
|
||||||
fn from(font: &Font) -> Self {
|
let style = match font.style() {
|
||||||
let style = match font.style() {
|
FontStyle::Normal => StyleFontStyle::NORMAL,
|
||||||
FontStyle::Normal => StyleFontStyle::NORMAL,
|
FontStyle::Oblique => StyleFontStyle::OBLIQUE,
|
||||||
FontStyle::Oblique => StyleFontStyle::OBLIQUE,
|
FontStyle::Italic => StyleFontStyle::ITALIC,
|
||||||
FontStyle::Italic => StyleFontStyle::ITALIC,
|
};
|
||||||
};
|
let weight = StyleFontWeight::from_float(font.weight().to_u32() as f32);
|
||||||
let weight = StyleFontWeight::from_float(font.weight().to_u32() as f32);
|
let stretch = match font.stretch() {
|
||||||
let stretch = match font.stretch() {
|
FontStretch::Undefined => FontStretchKeyword::Normal,
|
||||||
FontStretch::Undefined => FontStretchKeyword::Normal,
|
FontStretch::UltraCondensed => FontStretchKeyword::UltraCondensed,
|
||||||
FontStretch::UltraCondensed => FontStretchKeyword::UltraCondensed,
|
FontStretch::ExtraCondensed => FontStretchKeyword::ExtraCondensed,
|
||||||
FontStretch::ExtraCondensed => FontStretchKeyword::ExtraCondensed,
|
FontStretch::Condensed => FontStretchKeyword::Condensed,
|
||||||
FontStretch::Condensed => FontStretchKeyword::Condensed,
|
FontStretch::SemiCondensed => FontStretchKeyword::SemiCondensed,
|
||||||
FontStretch::SemiCondensed => FontStretchKeyword::SemiCondensed,
|
FontStretch::Normal => FontStretchKeyword::Normal,
|
||||||
FontStretch::Normal => FontStretchKeyword::Normal,
|
FontStretch::SemiExpanded => FontStretchKeyword::SemiExpanded,
|
||||||
FontStretch::SemiExpanded => FontStretchKeyword::SemiExpanded,
|
FontStretch::Expanded => FontStretchKeyword::Expanded,
|
||||||
FontStretch::Expanded => FontStretchKeyword::Expanded,
|
FontStretch::ExtraExpanded => FontStretchKeyword::ExtraExpanded,
|
||||||
FontStretch::ExtraExpanded => FontStretchKeyword::ExtraExpanded,
|
FontStretch::UltraExpanded => FontStretchKeyword::UltraExpanded,
|
||||||
FontStretch::UltraExpanded => FontStretchKeyword::UltraExpanded,
|
|
||||||
}
|
|
||||||
.compute();
|
|
||||||
FontTemplateDescriptor::new(weight, stretch, style)
|
|
||||||
}
|
}
|
||||||
|
.compute();
|
||||||
|
FontTemplateDescriptor::new(weight, stretch, style)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default_system_generic_font_family(generic: GenericFontFamily) -> LowercaseFontFamilyName {
|
pub fn default_system_generic_font_family(generic: GenericFontFamily) -> LowercaseFontFamilyName {
|
||||||
|
|
|
@ -5,11 +5,13 @@
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::cell::OnceCell;
|
use std::cell::OnceCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ops::{Deref, RangeInclusive};
|
use std::thread;
|
||||||
use std::{fmt, thread};
|
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessCompositorApi;
|
||||||
|
use fonts_traits::{
|
||||||
|
FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef, LowercaseFontFamilyName,
|
||||||
|
};
|
||||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use malloc_size_of::MallocSizeOf as MallocSizeOfTrait;
|
use malloc_size_of::MallocSizeOf as MallocSizeOfTrait;
|
||||||
|
@ -21,38 +23,14 @@ use profile_traits::mem::{
|
||||||
use profile_traits::path;
|
use profile_traits::path;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use servo_config::pref;
|
use servo_config::pref;
|
||||||
use servo_url::ServoUrl;
|
use style::values::computed::font::{GenericFontFamily, SingleFontFamily};
|
||||||
use style::font_face::{FontFaceRuleData, FontStyle as FontFaceStyle};
|
|
||||||
use style::values::computed::font::{
|
|
||||||
FixedPoint, FontStyleFixedPoint, GenericFontFamily, SingleFontFamily,
|
|
||||||
};
|
|
||||||
use style::values::computed::{FontStretch, FontWeight};
|
|
||||||
use style::values::specified::FontStretch as SpecifiedFontStretch;
|
|
||||||
use webrender_api::{FontInstanceFlags, FontInstanceKey, FontKey, FontVariation};
|
use webrender_api::{FontInstanceFlags, FontInstanceKey, FontKey, FontVariation};
|
||||||
|
|
||||||
use crate::font::FontDescriptor;
|
|
||||||
use crate::font_store::FontStore;
|
use crate::font_store::FontStore;
|
||||||
use crate::font_template::{FontTemplate, FontTemplateRef};
|
|
||||||
use crate::platform::LocalFontIdentifier;
|
|
||||||
use crate::platform::font_list::{
|
use crate::platform::font_list::{
|
||||||
default_system_generic_font_family, for_each_available_family, for_each_variation,
|
default_system_generic_font_family, for_each_available_family, for_each_variation,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
|
||||||
pub enum FontIdentifier {
|
|
||||||
Local(LocalFontIdentifier),
|
|
||||||
Web(ServoUrl),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FontIdentifier {
|
|
||||||
pub fn index(&self) -> u32 {
|
|
||||||
match *self {
|
|
||||||
Self::Local(ref local_font_identifier) => local_font_identifier.index(),
|
|
||||||
Self::Web(_) => 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Commands that the `FontContext` sends to the `SystemFontService`.
|
/// Commands that the `FontContext` sends to the `SystemFontService`.
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub enum SystemFontServiceMessage {
|
pub enum SystemFontServiceMessage {
|
||||||
|
@ -379,89 +357,6 @@ pub struct SystemFontServiceProxy {
|
||||||
templates: RwLock<HashMap<FontTemplateCacheKey, Vec<FontTemplateRef>>>,
|
templates: RwLock<HashMap<FontTemplateCacheKey, Vec<FontTemplateRef>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A version of `FontStyle` from Stylo that is serializable. Normally this is not
|
|
||||||
/// because the specified version of `FontStyle` contains floats.
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
||||||
pub enum ComputedFontStyleDescriptor {
|
|
||||||
Italic,
|
|
||||||
Oblique(FontStyleFixedPoint, FontStyleFixedPoint),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This data structure represents the various optional descriptors that can be
|
|
||||||
/// applied to a `@font-face` rule in CSS. These are used to create a [`FontTemplate`]
|
|
||||||
/// from the given font data used as the source of the `@font-face` rule. If values
|
|
||||||
/// like weight, stretch, and style are not specified they are initialized based
|
|
||||||
/// on the contents of the font itself.
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
|
||||||
pub struct CSSFontFaceDescriptors {
|
|
||||||
pub family_name: LowercaseFontFamilyName,
|
|
||||||
pub weight: Option<(FontWeight, FontWeight)>,
|
|
||||||
pub stretch: Option<(FontStretch, FontStretch)>,
|
|
||||||
pub style: Option<ComputedFontStyleDescriptor>,
|
|
||||||
pub unicode_range: Option<Vec<RangeInclusive<u32>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CSSFontFaceDescriptors {
|
|
||||||
pub fn new(family_name: &str) -> Self {
|
|
||||||
CSSFontFaceDescriptors {
|
|
||||||
family_name: family_name.into(),
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&FontFaceRuleData> for CSSFontFaceDescriptors {
|
|
||||||
fn from(rule_data: &FontFaceRuleData) -> Self {
|
|
||||||
let family_name = rule_data
|
|
||||||
.family
|
|
||||||
.as_ref()
|
|
||||||
.expect("Expected rule to contain a font family.")
|
|
||||||
.name
|
|
||||||
.clone();
|
|
||||||
let weight = rule_data
|
|
||||||
.weight
|
|
||||||
.as_ref()
|
|
||||||
.map(|weight_range| (weight_range.0.compute(), weight_range.1.compute()));
|
|
||||||
|
|
||||||
let stretch_to_computed = |specified: SpecifiedFontStretch| match specified {
|
|
||||||
SpecifiedFontStretch::Stretch(percentage) => {
|
|
||||||
FontStretch::from_percentage(percentage.compute().0)
|
|
||||||
},
|
|
||||||
SpecifiedFontStretch::Keyword(keyword) => keyword.compute(),
|
|
||||||
SpecifiedFontStretch::System(_) => FontStretch::NORMAL,
|
|
||||||
};
|
|
||||||
let stretch = rule_data.stretch.as_ref().map(|stretch_range| {
|
|
||||||
(
|
|
||||||
stretch_to_computed(stretch_range.0),
|
|
||||||
stretch_to_computed(stretch_range.1),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
fn style_to_computed(specified: &FontFaceStyle) -> ComputedFontStyleDescriptor {
|
|
||||||
match specified {
|
|
||||||
FontFaceStyle::Italic => ComputedFontStyleDescriptor::Italic,
|
|
||||||
FontFaceStyle::Oblique(angle_a, angle_b) => ComputedFontStyleDescriptor::Oblique(
|
|
||||||
FixedPoint::from_float(angle_a.degrees()),
|
|
||||||
FixedPoint::from_float(angle_b.degrees()),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let style = rule_data.style.as_ref().map(style_to_computed);
|
|
||||||
let unicode_range = rule_data
|
|
||||||
.unicode_range
|
|
||||||
.as_ref()
|
|
||||||
.map(|ranges| ranges.iter().map(|range| range.start..=range.end).collect());
|
|
||||||
|
|
||||||
CSSFontFaceDescriptors {
|
|
||||||
family_name: family_name.into(),
|
|
||||||
weight,
|
|
||||||
stretch,
|
|
||||||
style,
|
|
||||||
unicode_range,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SystemFontServiceProxy {
|
impl SystemFontServiceProxy {
|
||||||
pub fn exit(&self) {
|
pub fn exit(&self) {
|
||||||
let (response_chan, response_port) = ipc::channel().unwrap();
|
let (response_chan, response_port) = ipc::channel().unwrap();
|
||||||
|
@ -584,31 +479,3 @@ impl SystemFontServiceProxy {
|
||||||
.expect("Failed to communicate with system font service.")
|
.expect("Failed to communicate with system font service.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
|
||||||
pub struct LowercaseFontFamilyName {
|
|
||||||
inner: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: AsRef<str>> From<T> for LowercaseFontFamilyName {
|
|
||||||
fn from(value: T) -> Self {
|
|
||||||
LowercaseFontFamilyName {
|
|
||||||
inner: value.as_ref().to_lowercase(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for LowercaseFontFamilyName {
|
|
||||||
type Target = str;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn deref(&self) -> &str {
|
|
||||||
&self.inner
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for LowercaseFontFamilyName {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
self.inner.fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,8 +12,18 @@ name = "fonts_traits"
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
atomic_refcell = { workspace = true }
|
||||||
ipc-channel = { workspace = true }
|
ipc-channel = { workspace = true }
|
||||||
|
log = { workspace = true }
|
||||||
malloc_size_of = { workspace = true }
|
malloc_size_of = { workspace = true }
|
||||||
malloc_size_of_derive = { workspace = true }
|
malloc_size_of_derive = { workspace = true }
|
||||||
|
memmap2 = { workspace = true }
|
||||||
range = { path = "../../range" }
|
range = { path = "../../range" }
|
||||||
|
read-fonts = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
|
servo_url = { path = "../../url" }
|
||||||
|
stylo = { workspace = true }
|
||||||
|
webrender_api = { workspace = true }
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
|
dwrote = { workspace = true }
|
||||||
|
|
164
components/shared/fonts/font_descriptor.rs
Normal file
164
components/shared/fonts/font_descriptor.rs
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use std::ops::{Deref, RangeInclusive};
|
||||||
|
|
||||||
|
use malloc_size_of_derive::MallocSizeOf;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use style::computed_values::font_variant_caps;
|
||||||
|
use style::font_face::{FontFaceRuleData, FontStyle as FontFaceStyle};
|
||||||
|
use style::properties::style_structs::Font as FontStyleStruct;
|
||||||
|
use style::values::computed::font::{FixedPoint, FontStyleFixedPoint};
|
||||||
|
use style::values::computed::{Au, FontStretch, FontStyle, FontWeight};
|
||||||
|
use style::values::specified::FontStretch as SpecifiedFontStretch;
|
||||||
|
use webrender_api::FontVariation;
|
||||||
|
|
||||||
|
/// `FontDescriptor` describes the parameters of a `Font`. It represents rendering a given font
|
||||||
|
/// template at a particular size, with a particular font-variant-caps applied, etc. This contrasts
|
||||||
|
/// with `FontTemplateDescriptor` in that the latter represents only the parameters inherent in the
|
||||||
|
/// font data (weight, stretch, etc.).
|
||||||
|
#[derive(Clone, Debug, Deserialize, Hash, MallocSizeOf, PartialEq, Serialize)]
|
||||||
|
pub struct FontDescriptor {
|
||||||
|
pub weight: FontWeight,
|
||||||
|
pub stretch: FontStretch,
|
||||||
|
pub style: FontStyle,
|
||||||
|
pub variant: font_variant_caps::T,
|
||||||
|
pub pt_size: Au,
|
||||||
|
pub variation_settings: Vec<FontVariation>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for FontDescriptor {}
|
||||||
|
|
||||||
|
impl<'a> From<&'a FontStyleStruct> for FontDescriptor {
|
||||||
|
fn from(style: &'a FontStyleStruct) -> Self {
|
||||||
|
let variation_settings = style
|
||||||
|
.clone_font_variation_settings()
|
||||||
|
.0
|
||||||
|
.into_iter()
|
||||||
|
.map(|setting| FontVariation {
|
||||||
|
tag: setting.tag.0,
|
||||||
|
value: setting.value,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
FontDescriptor {
|
||||||
|
weight: style.font_weight,
|
||||||
|
stretch: style.font_stretch,
|
||||||
|
style: style.font_style,
|
||||||
|
variant: style.font_variant_caps,
|
||||||
|
pt_size: Au::from_f32_px(style.font_size.computed_size().px()),
|
||||||
|
variation_settings,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A version of `FontStyle` from Stylo that is serializable. Normally this is not
|
||||||
|
/// because the specified version of `FontStyle` contains floats.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub enum ComputedFontStyleDescriptor {
|
||||||
|
Italic,
|
||||||
|
Oblique(FontStyleFixedPoint, FontStyleFixedPoint),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This data structure represents the various optional descriptors that can be
|
||||||
|
/// applied to a `@font-face` rule in CSS. These are used to create a [`FontTemplate`]
|
||||||
|
/// from the given font data used as the source of the `@font-face` rule. If values
|
||||||
|
/// like weight, stretch, and style are not specified they are initialized based
|
||||||
|
/// on the contents of the font itself.
|
||||||
|
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||||
|
pub struct CSSFontFaceDescriptors {
|
||||||
|
pub family_name: LowercaseFontFamilyName,
|
||||||
|
pub weight: Option<(FontWeight, FontWeight)>,
|
||||||
|
pub stretch: Option<(FontStretch, FontStretch)>,
|
||||||
|
pub style: Option<ComputedFontStyleDescriptor>,
|
||||||
|
pub unicode_range: Option<Vec<RangeInclusive<u32>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CSSFontFaceDescriptors {
|
||||||
|
pub fn new(family_name: &str) -> Self {
|
||||||
|
CSSFontFaceDescriptors {
|
||||||
|
family_name: family_name.into(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&FontFaceRuleData> for CSSFontFaceDescriptors {
|
||||||
|
fn from(rule_data: &FontFaceRuleData) -> Self {
|
||||||
|
let family_name = rule_data
|
||||||
|
.family
|
||||||
|
.as_ref()
|
||||||
|
.expect("Expected rule to contain a font family.")
|
||||||
|
.name
|
||||||
|
.clone();
|
||||||
|
let weight = rule_data
|
||||||
|
.weight
|
||||||
|
.as_ref()
|
||||||
|
.map(|weight_range| (weight_range.0.compute(), weight_range.1.compute()));
|
||||||
|
|
||||||
|
let stretch_to_computed = |specified: SpecifiedFontStretch| match specified {
|
||||||
|
SpecifiedFontStretch::Stretch(percentage) => {
|
||||||
|
FontStretch::from_percentage(percentage.compute().0)
|
||||||
|
},
|
||||||
|
SpecifiedFontStretch::Keyword(keyword) => keyword.compute(),
|
||||||
|
SpecifiedFontStretch::System(_) => FontStretch::NORMAL,
|
||||||
|
};
|
||||||
|
let stretch = rule_data.stretch.as_ref().map(|stretch_range| {
|
||||||
|
(
|
||||||
|
stretch_to_computed(stretch_range.0),
|
||||||
|
stretch_to_computed(stretch_range.1),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
fn style_to_computed(specified: &FontFaceStyle) -> ComputedFontStyleDescriptor {
|
||||||
|
match specified {
|
||||||
|
FontFaceStyle::Italic => ComputedFontStyleDescriptor::Italic,
|
||||||
|
FontFaceStyle::Oblique(angle_a, angle_b) => ComputedFontStyleDescriptor::Oblique(
|
||||||
|
FixedPoint::from_float(angle_a.degrees()),
|
||||||
|
FixedPoint::from_float(angle_b.degrees()),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let style = rule_data.style.as_ref().map(style_to_computed);
|
||||||
|
let unicode_range = rule_data
|
||||||
|
.unicode_range
|
||||||
|
.as_ref()
|
||||||
|
.map(|ranges| ranges.iter().map(|range| range.start..=range.end).collect());
|
||||||
|
|
||||||
|
CSSFontFaceDescriptors {
|
||||||
|
family_name: family_name.into(),
|
||||||
|
weight,
|
||||||
|
stretch,
|
||||||
|
style,
|
||||||
|
unicode_range,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
||||||
|
pub struct LowercaseFontFamilyName {
|
||||||
|
inner: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AsRef<str>> From<T> for LowercaseFontFamilyName {
|
||||||
|
fn from(value: T) -> Self {
|
||||||
|
LowercaseFontFamilyName {
|
||||||
|
inner: value.as_ref().to_lowercase(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for LowercaseFontFamilyName {
|
||||||
|
type Target = str;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn deref(&self) -> &str {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for LowercaseFontFamilyName {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
self.inner.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
246
components/shared/fonts/font_identifier.rs
Normal file
246
components/shared/fonts/font_identifier.rs
Normal file
|
@ -0,0 +1,246 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use malloc_size_of_derive::MallocSizeOf;
|
||||||
|
pub use platform::LocalFontIdentifier;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use servo_url::ServoUrl;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
||||||
|
pub enum FontIdentifier {
|
||||||
|
Local(LocalFontIdentifier),
|
||||||
|
Web(ServoUrl),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FontIdentifier {
|
||||||
|
pub fn index(&self) -> u32 {
|
||||||
|
match *self {
|
||||||
|
Self::Local(ref local_font_identifier) => local_font_identifier.index(),
|
||||||
|
Self::Web(_) => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
|
mod platform {
|
||||||
|
use std::fs::File;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use malloc_size_of_derive::MallocSizeOf;
|
||||||
|
use memmap2::Mmap;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use style::Atom;
|
||||||
|
use webrender_api::NativeFontHandle;
|
||||||
|
|
||||||
|
use crate::{FontData, FontDataAndIndex};
|
||||||
|
|
||||||
|
/// An identifier for a local font on systems using Freetype.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
||||||
|
pub struct LocalFontIdentifier {
|
||||||
|
/// The path to the font.
|
||||||
|
pub path: Atom,
|
||||||
|
/// The variation index within the font.
|
||||||
|
pub variation_index: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LocalFontIdentifier {
|
||||||
|
pub fn index(&self) -> u32 {
|
||||||
|
self.variation_index.try_into().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn native_font_handle(&self) -> NativeFontHandle {
|
||||||
|
NativeFontHandle {
|
||||||
|
path: PathBuf::from(&*self.path),
|
||||||
|
index: self.variation_index as u32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
pub fn font_data_and_index(&self) -> Option<FontDataAndIndex> {
|
||||||
|
let file = File::open(Path::new(&*self.path)).ok()?;
|
||||||
|
let mmap = unsafe { Mmap::map(&file).ok()? };
|
||||||
|
let data = FontData::from_bytes(&mmap);
|
||||||
|
|
||||||
|
Some(FontDataAndIndex {
|
||||||
|
data,
|
||||||
|
index: self.variation_index as u32,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
mod platform {
|
||||||
|
use std::fs::File;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use log::warn;
|
||||||
|
use malloc_size_of_derive::MallocSizeOf;
|
||||||
|
use memmap2::Mmap;
|
||||||
|
use read_fonts::types::NameId;
|
||||||
|
use read_fonts::{FileRef, TableProvider};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use style::Atom;
|
||||||
|
use webrender_api::NativeFontHandle;
|
||||||
|
|
||||||
|
use crate::{FontData, FontDataAndIndex};
|
||||||
|
|
||||||
|
/// An identifier for a local font on a MacOS system. These values comes from the CoreText
|
||||||
|
/// CTFontCollection. Note that `path` here is required. We do not load fonts that do not
|
||||||
|
/// have paths.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
||||||
|
pub struct LocalFontIdentifier {
|
||||||
|
pub postscript_name: Atom,
|
||||||
|
pub path: Atom,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LocalFontIdentifier {
|
||||||
|
pub fn native_font_handle(&self) -> NativeFontHandle {
|
||||||
|
NativeFontHandle {
|
||||||
|
name: self.postscript_name.to_string(),
|
||||||
|
path: self.path.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn index(&self) -> u32 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
pub fn font_data_and_index(&self) -> Option<FontDataAndIndex> {
|
||||||
|
let file = File::open(Path::new(&*self.path)).ok()?;
|
||||||
|
let mmap = unsafe { Mmap::map(&file).ok()? };
|
||||||
|
|
||||||
|
// Determine index
|
||||||
|
let file_ref = FileRef::new(mmap.as_ref()).ok()?;
|
||||||
|
let index = ttc_index_from_postscript_name(file_ref, &self.postscript_name);
|
||||||
|
|
||||||
|
Some(FontDataAndIndex {
|
||||||
|
data: FontData::from_bytes(&mmap),
|
||||||
|
index,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// CoreText font enumeration gives us a Postscript name rather than an index.
|
||||||
|
/// This functions maps from a Postscript name to an index.
|
||||||
|
///
|
||||||
|
/// This mapping works for single-font files and for simple TTC files, but may not work in all cases.
|
||||||
|
/// We are not 100% sure which cases (if any) will not work. But we suspect that variable fonts may cause
|
||||||
|
/// issues due to the Postscript names corresponding to instances not being straightforward, and the possibility
|
||||||
|
/// that CoreText may return a non-standard in that scenerio.
|
||||||
|
fn ttc_index_from_postscript_name(font_file: FileRef<'_>, postscript_name: &str) -> u32 {
|
||||||
|
match font_file {
|
||||||
|
// File only contains one font: simply return 0
|
||||||
|
FileRef::Font(_) => 0,
|
||||||
|
// File is a collection: iterate through each font in the collection and check
|
||||||
|
// whether the name matches
|
||||||
|
FileRef::Collection(collection) => {
|
||||||
|
for i in 0..collection.len() {
|
||||||
|
let font = collection.get(i).unwrap();
|
||||||
|
let name_table = font.name().unwrap();
|
||||||
|
if name_table
|
||||||
|
.name_record()
|
||||||
|
.iter()
|
||||||
|
.filter(|record| record.name_id() == NameId::POSTSCRIPT_NAME)
|
||||||
|
.any(|record| {
|
||||||
|
record
|
||||||
|
.string(name_table.string_data())
|
||||||
|
.unwrap()
|
||||||
|
.chars()
|
||||||
|
.eq(postscript_name.chars())
|
||||||
|
})
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we fail to find a font, just use the first font in the file.
|
||||||
|
warn!(
|
||||||
|
"Font with postscript_name {} not found in collection",
|
||||||
|
postscript_name
|
||||||
|
);
|
||||||
|
0
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
mod platform {
|
||||||
|
use std::hash::Hash;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use dwrote::{FontCollection, FontDescriptor};
|
||||||
|
use malloc_size_of_derive::MallocSizeOf;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use webrender_api::NativeFontHandle;
|
||||||
|
|
||||||
|
use crate::{FontData, FontDataAndIndex};
|
||||||
|
|
||||||
|
/// An identifier for a local font on a Windows system.
|
||||||
|
#[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
|
||||||
|
pub struct LocalFontIdentifier {
|
||||||
|
/// The FontDescriptor of this font.
|
||||||
|
#[ignore_malloc_size_of = "dwrote does not support MallocSizeOf"]
|
||||||
|
pub font_descriptor: Arc<FontDescriptor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LocalFontIdentifier {
|
||||||
|
pub fn index(&self) -> u32 {
|
||||||
|
FontCollection::system()
|
||||||
|
.font_from_descriptor(&self.font_descriptor)
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
.map_or(0, |font| font.create_font_face().get_index())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn native_font_handle(&self) -> NativeFontHandle {
|
||||||
|
let face = FontCollection::system()
|
||||||
|
.font_from_descriptor(&self.font_descriptor)
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
.expect("Could not create Font from FontDescriptor")
|
||||||
|
.create_font_face();
|
||||||
|
let path = face
|
||||||
|
.files()
|
||||||
|
.ok()
|
||||||
|
.and_then(|files| files.first().cloned())
|
||||||
|
.expect("Could not get FontFace files")
|
||||||
|
.font_file_path()
|
||||||
|
.ok()
|
||||||
|
.expect("Could not get FontFace files path");
|
||||||
|
NativeFontHandle {
|
||||||
|
path,
|
||||||
|
index: face.get_index(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn font_data_and_index(&self) -> Option<FontDataAndIndex> {
|
||||||
|
let font = FontCollection::system()
|
||||||
|
.font_from_descriptor(&self.font_descriptor)
|
||||||
|
.ok()??;
|
||||||
|
let face = font.create_font_face();
|
||||||
|
let index = face.get_index();
|
||||||
|
let files = face.files().ok()?;
|
||||||
|
assert!(!files.is_empty());
|
||||||
|
|
||||||
|
let data = files[0].font_file_bytes().ok()?;
|
||||||
|
let data = FontData::from_bytes(&data);
|
||||||
|
|
||||||
|
Some(FontDataAndIndex { data, index })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for LocalFontIdentifier {}
|
||||||
|
|
||||||
|
impl Hash for LocalFontIdentifier {
|
||||||
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
self.font_descriptor.family_name.hash(state);
|
||||||
|
self.font_descriptor.weight.to_u32().hash(state);
|
||||||
|
self.font_descriptor.stretch.to_u32().hash(state);
|
||||||
|
self.font_descriptor.style.to_u32().hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,10 +14,7 @@ use style::computed_values::font_style::T as FontStyle;
|
||||||
use style::stylesheets::DocumentStyleSheet;
|
use style::stylesheets::DocumentStyleSheet;
|
||||||
use style::values::computed::font::FontWeight;
|
use style::values::computed::font::FontWeight;
|
||||||
|
|
||||||
use crate::font::FontDescriptor;
|
use crate::{CSSFontFaceDescriptors, ComputedFontStyleDescriptor, FontDescriptor, FontIdentifier};
|
||||||
use crate::system_font_service::{
|
|
||||||
CSSFontFaceDescriptors, ComputedFontStyleDescriptor, FontIdentifier,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A reference to a [`FontTemplate`] with shared ownership and mutability.
|
/// A reference to a [`FontTemplate`] with shared ownership and mutability.
|
||||||
#[derive(Clone, Debug, MallocSizeOf)]
|
#[derive(Clone, Debug, MallocSizeOf)]
|
||||||
|
@ -120,7 +117,7 @@ impl FontTemplateDescriptor {
|
||||||
self.stretch.1 >= descriptor_to_match.stretch
|
self.stretch.1 >= descriptor_to_match.stretch
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn override_values_with_css_font_template_descriptors(
|
pub fn override_values_with_css_font_template_descriptors(
|
||||||
&mut self,
|
&mut self,
|
||||||
css_font_template_descriptors: &CSSFontFaceDescriptors,
|
css_font_template_descriptors: &CSSFontFaceDescriptors,
|
||||||
) {
|
) {
|
||||||
|
@ -512,7 +509,7 @@ impl FontMatchDistanceMethod for FontStyle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait IsOblique {
|
pub trait IsOblique {
|
||||||
fn is_oblique(&self) -> bool;
|
fn is_oblique(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,15 @@
|
||||||
|
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
|
|
||||||
|
mod font_descriptor;
|
||||||
|
mod font_identifier;
|
||||||
|
mod font_template;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub use font_descriptor::*;
|
||||||
|
pub use font_identifier::*;
|
||||||
|
pub use font_template::*;
|
||||||
use ipc_channel::ipc::IpcSharedMemory;
|
use ipc_channel::ipc::IpcSharedMemory;
|
||||||
use malloc_size_of_derive::MallocSizeOf;
|
use malloc_size_of_derive::MallocSizeOf;
|
||||||
use range::{RangeIndex, int_range_index};
|
use range::{RangeIndex, int_range_index};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue