mirror of
https://github.com/servo/servo.git
synced 2025-09-20 11:50:09 +01:00
fonts: Use skrifa to get raw font table data on Linux (#38690)
Use skrifa instead of freetype for extracting raw table data. Allows us to replace unsafe Freetype code with safe Skrifa code. Also allows us to avoid copying the table data. Instead we return Arc'd data. --------- Signed-off-by: Nico Burns <nico@nicoburns.com>
This commit is contained in:
parent
a4fdbe8be3
commit
046dbd86a1
4 changed files with 27 additions and 35 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2648,6 +2648,7 @@ dependencies = [
|
||||||
"servo_config",
|
"servo_config",
|
||||||
"servo_malloc_size_of",
|
"servo_malloc_size_of",
|
||||||
"servo_url",
|
"servo_url",
|
||||||
|
"skrifa",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"stylo",
|
"stylo",
|
||||||
"stylo_atoms",
|
"stylo_atoms",
|
||||||
|
|
|
@ -138,6 +138,7 @@ servo-media-dummy = { git = "https://github.com/servo/media" }
|
||||||
servo-media-gstreamer = { git = "https://github.com/servo/media" }
|
servo-media-gstreamer = { git = "https://github.com/servo/media" }
|
||||||
servo-tracing = { path = "components/servo_tracing" }
|
servo-tracing = { path = "components/servo_tracing" }
|
||||||
servo_arc = { git = "https://github.com/servo/stylo", branch = "2025-08-01" }
|
servo_arc = { git = "https://github.com/servo/stylo", branch = "2025-08-01" }
|
||||||
|
skrifa = "0.31.3"
|
||||||
smallbitvec = "2.6.0"
|
smallbitvec = "2.6.0"
|
||||||
smallvec = { version = "1.15", features = ["serde", "union"] }
|
smallvec = { version = "1.15", features = ["serde", "union"] }
|
||||||
string_cache = "0.8"
|
string_cache = "0.8"
|
||||||
|
|
|
@ -45,6 +45,7 @@ serde = { workspace = true }
|
||||||
servo_arc = { workspace = true }
|
servo_arc = { workspace = true }
|
||||||
servo_config = { path = "../config" }
|
servo_config = { path = "../config" }
|
||||||
servo_url = { path = "../url" }
|
servo_url = { path = "../url" }
|
||||||
|
skrifa = { workspace = true }
|
||||||
smallvec = { workspace = true }
|
smallvec = { workspace = true }
|
||||||
stylo = { workspace = true }
|
stylo = { workspace = true }
|
||||||
stylo_atoms = { workspace = true }
|
stylo_atoms = { workspace = true }
|
||||||
|
|
|
@ -10,17 +10,19 @@ use std::{mem, ptr};
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use euclid::default::{Point2D, Rect, Size2D};
|
use euclid::default::{Point2D, Rect, Size2D};
|
||||||
use freetype_sys::{
|
use freetype_sys::{
|
||||||
FT_Byte, FT_Done_Face, FT_Error, FT_F26Dot6, FT_FACE_FLAG_COLOR, FT_FACE_FLAG_FIXED_SIZES,
|
FT_Done_Face, FT_F26Dot6, FT_FACE_FLAG_COLOR, FT_FACE_FLAG_FIXED_SIZES, FT_FACE_FLAG_SCALABLE,
|
||||||
FT_FACE_FLAG_SCALABLE, FT_Face, FT_Get_Char_Index, FT_Get_Kerning, FT_GlyphSlot, FT_Int32,
|
FT_Face, FT_Get_Char_Index, FT_Get_Kerning, FT_GlyphSlot, FT_Int32, FT_KERNING_DEFAULT,
|
||||||
FT_KERNING_DEFAULT, FT_LOAD_COLOR, FT_LOAD_DEFAULT, FT_LOAD_NO_HINTING, FT_Load_Glyph, FT_Long,
|
FT_LOAD_COLOR, FT_LOAD_DEFAULT, FT_LOAD_NO_HINTING, FT_Load_Glyph, FT_Long, FT_New_Face,
|
||||||
FT_New_Face, FT_New_Memory_Face, FT_Pos, FT_Select_Size, FT_Set_Char_Size, FT_Size_Metrics,
|
FT_New_Memory_Face, FT_Pos, FT_Select_Size, FT_Set_Char_Size, FT_Size_Metrics, FT_SizeRec,
|
||||||
FT_SizeRec, FT_UInt, FT_ULong, FT_Vector,
|
FT_UInt, FT_ULong, FT_Vector,
|
||||||
};
|
};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use memmap2::Mmap;
|
use memmap2::Mmap;
|
||||||
use parking_lot::ReentrantMutex;
|
use parking_lot::ReentrantMutex;
|
||||||
use read_fonts::tables::os2::SelectionFlags;
|
use read_fonts::tables::os2::SelectionFlags;
|
||||||
|
use read_fonts::types::Tag;
|
||||||
use read_fonts::{FontRef, ReadError, TableProvider};
|
use read_fonts::{FontRef, ReadError, TableProvider};
|
||||||
|
use servo_arc::Arc;
|
||||||
use style::Zero;
|
use style::Zero;
|
||||||
use style::computed_values::font_stretch::T as FontStretch;
|
use style::computed_values::font_stretch::T as FontStretch;
|
||||||
use style::computed_values::font_weight::T as FontWeight;
|
use style::computed_values::font_weight::T as FontWeight;
|
||||||
|
@ -49,12 +51,17 @@ fn fixed_26_dot_6_to_float(fixed: FT_F26Dot6) -> f64 {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FontTable {
|
pub struct FontTable {
|
||||||
buffer: Vec<u8>,
|
data: FreeTypeFaceTableProviderData,
|
||||||
|
tag: Tag,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontTableMethods for FontTable {
|
impl FontTableMethods for FontTable {
|
||||||
fn buffer(&self) -> &[u8] {
|
fn buffer(&self) -> &[u8] {
|
||||||
&self.buffer
|
let font_ref = self.data.font_ref().expect("Font checked before creating");
|
||||||
|
let table_data = font_ref
|
||||||
|
.table_data(self.tag)
|
||||||
|
.expect("Table existence checked before creating");
|
||||||
|
table_data.as_bytes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +171,7 @@ impl PlatformFontMethods for PlatformFont {
|
||||||
requested_face_size,
|
requested_face_size,
|
||||||
actual_face_size,
|
actual_face_size,
|
||||||
table_provider_data: FreeTypeFaceTableProviderData::Local(
|
table_provider_data: FreeTypeFaceTableProviderData::Local(
|
||||||
memory_mapped_font_data,
|
Arc::new(memory_mapped_font_data),
|
||||||
font_identifier.index(),
|
font_identifier.index(),
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
|
@ -393,22 +400,13 @@ impl PlatformFontMethods for PlatformFont {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn table_for_tag(&self, tag: FontTableTag) -> Option<FontTable> {
|
fn table_for_tag(&self, tag: FontTableTag) -> Option<FontTable> {
|
||||||
let face = self.face.lock();
|
let tag = Tag::from_u32(tag);
|
||||||
let tag = tag as FT_ULong;
|
let font_ref = self.table_provider_data.font_ref().ok()?;
|
||||||
|
let _table_data = font_ref.table_data(tag)?;
|
||||||
unsafe {
|
Some(FontTable {
|
||||||
// Get the length
|
data: self.table_provider_data.clone(),
|
||||||
let mut len = 0;
|
tag,
|
||||||
if 0 != FT_Load_Sfnt_Table(*face, tag, 0, ptr::null_mut(), &mut len) {
|
})
|
||||||
return None;
|
|
||||||
}
|
|
||||||
// Get the bytes
|
|
||||||
let mut buf = vec![0u8; len as usize];
|
|
||||||
if 0 != FT_Load_Sfnt_Table(*face, tag, 0, buf.as_mut_ptr(), &mut len) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Some(FontTable { buffer: buf })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn typographic_bounds(&self, glyph_id: GlyphId) -> Rect<f32> {
|
fn typographic_bounds(&self, glyph_id: GlyphId) -> Rect<f32> {
|
||||||
|
@ -529,19 +527,10 @@ impl FreeTypeFaceHelpers for FT_Face {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" {
|
#[derive(Clone)]
|
||||||
fn FT_Load_Sfnt_Table(
|
|
||||||
face: FT_Face,
|
|
||||||
tag: FT_ULong,
|
|
||||||
offset: FT_Long,
|
|
||||||
buffer: *mut FT_Byte,
|
|
||||||
length: *mut FT_ULong,
|
|
||||||
) -> FT_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum FreeTypeFaceTableProviderData {
|
enum FreeTypeFaceTableProviderData {
|
||||||
Web(FontData),
|
Web(FontData),
|
||||||
Local(Mmap, u32),
|
Local(Arc<Mmap>, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FreeTypeFaceTableProviderData {
|
impl FreeTypeFaceTableProviderData {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue