//! `head` — Font Header table. //! //! Contains global font metrics and flags. //! Reference: use crate::font::parse::Reader; use crate::font::FontError; /// Parsed `head` table. #[derive(Debug)] pub struct HeadTable { /// Major version (should be 1). pub major_version: u16, /// Minor version (should be 0). pub minor_version: u16, /// Font revision (fixed-point 16.16). pub font_revision: i32, /// Units per em (typically 1000 or 2048). pub units_per_em: u16, /// Bounding box: minimum x. pub x_min: i16, /// Bounding box: minimum y. pub y_min: i16, /// Bounding box: maximum x. pub x_max: i16, /// Bounding box: maximum y. pub y_max: i16, /// Mac style flags (bit 0 = bold, bit 1 = italic). pub mac_style: u16, /// Smallest readable size in pixels. pub lowest_rec_ppem: u16, /// 0 = short offsets in loca, 1 = long offsets. pub index_to_loc_format: i16, } impl HeadTable { /// Parse the `head` table from raw bytes. pub fn parse(data: &[u8]) -> Result { let r = Reader::new(data); // Minimum head table size is 54 bytes. if r.len() < 54 { return Err(FontError::MalformedTable("head")); } let major_version = r.u16(0)?; let minor_version = r.u16(2)?; let font_revision = r.i32(4)?; // skip checksumAdjustment(4) + magicNumber(4) + flags(2) let units_per_em = r.u16(18)?; // skip created(8) + modified(8) let x_min = r.i16(36)?; let y_min = r.i16(38)?; let x_max = r.i16(40)?; let y_max = r.i16(42)?; let mac_style = r.u16(44)?; let lowest_rec_ppem = r.u16(46)?; // skip fontDirectionHint(2) let index_to_loc_format = r.i16(50)?; Ok(HeadTable { major_version, minor_version, font_revision, units_per_em, x_min, y_min, x_max, y_max, mac_style, lowest_rec_ppem, index_to_loc_format, }) } }