mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
fonts: Fix loading SFNT tables on Windows (#32499)
DirectWrite APIs expect the bytes of table tags to be reversed when reading them. Servo was doing this when loading font tables, but not all of them. This led to shaping being broken on Windows. This fixes that issue in a more comprehensive way and adds a comment to avoid this failing in the future.
This commit is contained in:
parent
e902d63732
commit
2c0d0d57b1
1 changed files with 11 additions and 12 deletions
|
@ -27,6 +27,7 @@ use crate::font::{
|
|||
};
|
||||
use crate::font_cache_thread::FontIdentifier;
|
||||
use crate::font_template::FontTemplateDescriptor;
|
||||
use crate::ot_tag;
|
||||
use crate::text::glyph::GlyphId;
|
||||
|
||||
// 1em = 12pt = 16px, assuming 72 points per inch and 96 px per inch
|
||||
|
@ -61,16 +62,6 @@ impl FontTableMethods for FontTable {
|
|||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
/// Packs the components of a font tag name into 32 bytes, while respecting the
|
||||
/// necessary Rust 4-byte alignment for pointers. This is similar to
|
||||
/// [`crate::ot_tag`], but the bytes are reversed.
|
||||
macro_rules! font_tag {
|
||||
($t1:expr, $t2:expr, $t3:expr, $t4:expr) => {
|
||||
(($t4 as u32) << 24) | (($t3 as u32) << 16) | (($t2 as u32) << 8) | ($t1 as u32)
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PlatformFont {
|
||||
face: Nondebug<FontFace>,
|
||||
|
@ -142,7 +133,12 @@ impl PlatformFontMethods for PlatformFont {
|
|||
//
|
||||
// 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.
|
||||
let windows_metrics_bytes = self.face.get_font_table(font_tag!('O', 'S', '/', '2'));
|
||||
//
|
||||
// The `dwrote` APIs take SFNT table tags in a reversed byte order, which
|
||||
// is why `u32::swap_bytes()` is called here.
|
||||
let windows_metrics_bytes = self
|
||||
.face
|
||||
.get_font_table(u32::swap_bytes(ot_tag!('O', 'S', '/', '2')));
|
||||
if windows_metrics_bytes.is_none() {
|
||||
warn!("Could not find OS/2 table in font.");
|
||||
return FontTemplateDescriptor::default();
|
||||
|
@ -269,8 +265,11 @@ impl PlatformFontMethods for PlatformFont {
|
|||
}
|
||||
|
||||
fn table_for_tag(&self, tag: FontTableTag) -> Option<FontTable> {
|
||||
// dwrote (and presumably the Windows APIs) accept a reversed version of the table
|
||||
// tag bytes, which means that `u32::swap_bytes` must be called here in order to
|
||||
// use a byte order compatible with the rest of Servo.
|
||||
self.face
|
||||
.get_font_table(tag)
|
||||
.get_font_table(u32::swap_bytes(tag))
|
||||
.map(|bytes| FontTable { data: bytes })
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue