1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-10 06:34:17 +03:00

fonts: parse weight and italic into ParsedFont

This commit is contained in:
Wez Furlong 2021-04-07 20:00:41 -07:00
parent 5c7e07bb60
commit 80aa86fa0c
4 changed files with 245 additions and 1 deletions

View File

@ -18,6 +18,6 @@ bindgen bindings.h -o src/lib.rs \
--default-enum-style rust \
--generate=functions,types,vars \
--whitelist-function="FT_.*" \
--whitelist-type="FT_.*" \
--whitelist-type="[FT]T_.*" \
--whitelist-var="FT_.*" \
-- -Ifreetype2/include

View File

@ -1195,6 +1195,168 @@ pub type FT_LcdFiveTapFilter = [FT_Byte; 5usize];
extern "C" {
pub fn FT_Library_SetLcdGeometry(library: FT_Library, sub: *mut FT_Vector) -> FT_Error;
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct TT_Header_ {
pub Table_Version: FT_Fixed,
pub Font_Revision: FT_Fixed,
pub CheckSum_Adjust: FT_Long,
pub Magic_Number: FT_Long,
pub Flags: FT_UShort,
pub Units_Per_EM: FT_UShort,
pub Created: [FT_ULong; 2usize],
pub Modified: [FT_ULong; 2usize],
pub xMin: FT_Short,
pub yMin: FT_Short,
pub xMax: FT_Short,
pub yMax: FT_Short,
pub Mac_Style: FT_UShort,
pub Lowest_Rec_PPEM: FT_UShort,
pub Font_Direction: FT_Short,
pub Index_To_Loc_Format: FT_Short,
pub Glyph_Data_Format: FT_Short,
}
pub type TT_Header = TT_Header_;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct TT_HoriHeader_ {
pub Version: FT_Fixed,
pub Ascender: FT_Short,
pub Descender: FT_Short,
pub Line_Gap: FT_Short,
pub advance_Width_Max: FT_UShort,
pub min_Left_Side_Bearing: FT_Short,
pub min_Right_Side_Bearing: FT_Short,
pub xMax_Extent: FT_Short,
pub caret_Slope_Rise: FT_Short,
pub caret_Slope_Run: FT_Short,
pub caret_Offset: FT_Short,
pub Reserved: [FT_Short; 4usize],
pub metric_Data_Format: FT_Short,
pub number_Of_HMetrics: FT_UShort,
pub long_metrics: *mut ::std::os::raw::c_void,
pub short_metrics: *mut ::std::os::raw::c_void,
}
pub type TT_HoriHeader = TT_HoriHeader_;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct TT_VertHeader_ {
pub Version: FT_Fixed,
pub Ascender: FT_Short,
pub Descender: FT_Short,
pub Line_Gap: FT_Short,
pub advance_Height_Max: FT_UShort,
pub min_Top_Side_Bearing: FT_Short,
pub min_Bottom_Side_Bearing: FT_Short,
pub yMax_Extent: FT_Short,
pub caret_Slope_Rise: FT_Short,
pub caret_Slope_Run: FT_Short,
pub caret_Offset: FT_Short,
pub Reserved: [FT_Short; 4usize],
pub metric_Data_Format: FT_Short,
pub number_Of_VMetrics: FT_UShort,
pub long_metrics: *mut ::std::os::raw::c_void,
pub short_metrics: *mut ::std::os::raw::c_void,
}
pub type TT_VertHeader = TT_VertHeader_;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct TT_OS2_ {
pub version: FT_UShort,
pub xAvgCharWidth: FT_Short,
pub usWeightClass: FT_UShort,
pub usWidthClass: FT_UShort,
pub fsType: FT_UShort,
pub ySubscriptXSize: FT_Short,
pub ySubscriptYSize: FT_Short,
pub ySubscriptXOffset: FT_Short,
pub ySubscriptYOffset: FT_Short,
pub ySuperscriptXSize: FT_Short,
pub ySuperscriptYSize: FT_Short,
pub ySuperscriptXOffset: FT_Short,
pub ySuperscriptYOffset: FT_Short,
pub yStrikeoutSize: FT_Short,
pub yStrikeoutPosition: FT_Short,
pub sFamilyClass: FT_Short,
pub panose: [FT_Byte; 10usize],
pub ulUnicodeRange1: FT_ULong,
pub ulUnicodeRange2: FT_ULong,
pub ulUnicodeRange3: FT_ULong,
pub ulUnicodeRange4: FT_ULong,
pub achVendID: [FT_Char; 4usize],
pub fsSelection: FT_UShort,
pub usFirstCharIndex: FT_UShort,
pub usLastCharIndex: FT_UShort,
pub sTypoAscender: FT_Short,
pub sTypoDescender: FT_Short,
pub sTypoLineGap: FT_Short,
pub usWinAscent: FT_UShort,
pub usWinDescent: FT_UShort,
pub ulCodePageRange1: FT_ULong,
pub ulCodePageRange2: FT_ULong,
pub sxHeight: FT_Short,
pub sCapHeight: FT_Short,
pub usDefaultChar: FT_UShort,
pub usBreakChar: FT_UShort,
pub usMaxContext: FT_UShort,
pub usLowerOpticalPointSize: FT_UShort,
pub usUpperOpticalPointSize: FT_UShort,
}
pub type TT_OS2 = TT_OS2_;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct TT_Postscript_ {
pub FormatType: FT_Fixed,
pub italicAngle: FT_Fixed,
pub underlinePosition: FT_Short,
pub underlineThickness: FT_Short,
pub isFixedPitch: FT_ULong,
pub minMemType42: FT_ULong,
pub maxMemType42: FT_ULong,
pub minMemType1: FT_ULong,
pub maxMemType1: FT_ULong,
}
pub type TT_Postscript = TT_Postscript_;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct TT_PCLT_ {
pub Version: FT_Fixed,
pub FontNumber: FT_ULong,
pub Pitch: FT_UShort,
pub xHeight: FT_UShort,
pub Style: FT_UShort,
pub TypeFamily: FT_UShort,
pub CapHeight: FT_UShort,
pub SymbolSet: FT_UShort,
pub TypeFace: [FT_Char; 16usize],
pub CharacterComplement: [FT_Char; 8usize],
pub FileName: [FT_Char; 6usize],
pub StrokeWeight: FT_Char,
pub WidthType: FT_Char,
pub SerifStyle: FT_Byte,
pub Reserved: FT_Byte,
}
pub type TT_PCLT = TT_PCLT_;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct TT_MaxProfile_ {
pub version: FT_Fixed,
pub numGlyphs: FT_UShort,
pub maxPoints: FT_UShort,
pub maxContours: FT_UShort,
pub maxCompositePoints: FT_UShort,
pub maxCompositeContours: FT_UShort,
pub maxZones: FT_UShort,
pub maxTwilightPoints: FT_UShort,
pub maxStorage: FT_UShort,
pub maxFunctionDefs: FT_UShort,
pub maxInstructionDefs: FT_UShort,
pub maxStackElements: FT_UShort,
pub maxSizeOfInstructions: FT_UShort,
pub maxComponentElements: FT_UShort,
pub maxComponentDepth: FT_UShort,
}
pub type TT_MaxProfile = TT_MaxProfile_;
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum FT_Sfnt_Tag_ {

View File

@ -152,6 +152,21 @@ impl Face {
}
}
pub fn get_os2_table(&self) -> Option<&TT_OS2> {
unsafe {
let os2: *const TT_OS2 = FT_Get_Sfnt_Table(self.face, FT_Sfnt_Tag::FT_SFNT_OS2) as _;
if os2.is_null() {
None
} else {
Some(&*os2)
}
}
}
pub fn italic(&self) -> bool {
unsafe { ((*self.face).style_flags & FT_STYLE_FLAG_ITALIC as FT_Long) != 0 }
}
/// This is a wrapper around set_char_size and select_size
/// that accounts for some weirdness with eg: color emoji
pub fn set_font_size(&mut self, point_size: f64, dpi: u32) -> anyhow::Result<(f64, f64)> {

View File

@ -11,10 +11,58 @@ pub enum MaybeShaped {
Unresolved { raw: String, slice_start: usize },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FontWeight {
Thin,
ExtraLight,
Light,
DemiLight,
Book,
Regular,
Medium,
DemiBold,
Bold,
ExtraBold,
Black,
ExtraBlack,
}
impl FontWeight {
pub fn from_opentype_weight(w: u16) -> Self {
if w >= 1000 {
Self::ExtraBlack
} else if w >= 900 {
Self::Black
} else if w >= 800 {
Self::ExtraBold
} else if w >= 700 {
Self::Bold
} else if w >= 600 {
Self::DemiBold
} else if w >= 500 {
Self::Medium
} else if w >= 400 {
Self::Regular
} else if w >= 380 {
Self::Book
} else if w >= 350 {
Self::DemiLight
} else if w >= 300 {
Self::Light
} else if w >= 200 {
Self::ExtraLight
} else {
Self::Thin
}
}
}
/// Represents a parsed font
#[derive(Debug)]
pub struct ParsedFont {
names: Names,
weight: FontWeight,
italic: bool,
}
#[derive(Debug)]
@ -50,14 +98,33 @@ impl ParsedFont {
pub fn from_locator(handle: &FontDataHandle) -> anyhow::Result<Self> {
let lib = crate::ftwrap::Library::new()?;
let face = lib.face_from_locator(handle)?;
let italic = face.italic();
let weight;
if let Some(os2) = face.get_os2_table() {
weight = FontWeight::from_opentype_weight(os2.usWeightClass);
} else {
weight = FontWeight::Regular;
}
Ok(Self {
names: Names::from_ft_face(&face),
weight,
italic,
})
}
pub fn names(&self) -> &Names {
&self.names
}
pub fn weight(&self) -> FontWeight {
self.weight
}
pub fn italic(&self) -> bool {
self.italic
}
}
pub fn font_info_matches(attr: &FontAttributes, names: &Names) -> bool {