| // THIS FILE IS AUTOGENERATED. |
| // Any changes to this file will be overwritten. |
| // For more information about how codegen works, see font-codegen/README.md |
| |
| #[allow(unused_imports)] |
| use crate::codegen_prelude::*; |
| |
| /// [post (PostScript)](https://docs.microsoft.com/en-us/typography/opentype/spec/post#header) table |
| #[derive(Debug, Clone, Copy)] |
| #[doc(hidden)] |
| pub struct PostMarker { |
| num_glyphs_byte_start: Option<usize>, |
| glyph_name_index_byte_start: Option<usize>, |
| glyph_name_index_byte_len: Option<usize>, |
| string_data_byte_start: Option<usize>, |
| string_data_byte_len: Option<usize>, |
| } |
| |
| impl PostMarker { |
| pub fn version_byte_range(&self) -> Range<usize> { |
| let start = 0; |
| start..start + Version16Dot16::RAW_BYTE_LEN |
| } |
| |
| pub fn italic_angle_byte_range(&self) -> Range<usize> { |
| let start = self.version_byte_range().end; |
| start..start + Fixed::RAW_BYTE_LEN |
| } |
| |
| pub fn underline_position_byte_range(&self) -> Range<usize> { |
| let start = self.italic_angle_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn underline_thickness_byte_range(&self) -> Range<usize> { |
| let start = self.underline_position_byte_range().end; |
| start..start + FWord::RAW_BYTE_LEN |
| } |
| |
| pub fn is_fixed_pitch_byte_range(&self) -> Range<usize> { |
| let start = self.underline_thickness_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| |
| pub fn min_mem_type42_byte_range(&self) -> Range<usize> { |
| let start = self.is_fixed_pitch_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| |
| pub fn max_mem_type42_byte_range(&self) -> Range<usize> { |
| let start = self.min_mem_type42_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| |
| pub fn min_mem_type1_byte_range(&self) -> Range<usize> { |
| let start = self.max_mem_type42_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| |
| pub fn max_mem_type1_byte_range(&self) -> Range<usize> { |
| let start = self.min_mem_type1_byte_range().end; |
| start..start + u32::RAW_BYTE_LEN |
| } |
| |
| pub fn num_glyphs_byte_range(&self) -> Option<Range<usize>> { |
| let start = self.num_glyphs_byte_start?; |
| Some(start..start + u16::RAW_BYTE_LEN) |
| } |
| |
| pub fn glyph_name_index_byte_range(&self) -> Option<Range<usize>> { |
| let start = self.glyph_name_index_byte_start?; |
| Some(start..start + self.glyph_name_index_byte_len?) |
| } |
| |
| pub fn string_data_byte_range(&self) -> Option<Range<usize>> { |
| let start = self.string_data_byte_start?; |
| Some(start..start + self.string_data_byte_len?) |
| } |
| } |
| |
| impl MinByteRange for PostMarker { |
| fn min_byte_range(&self) -> Range<usize> { |
| 0..self.max_mem_type1_byte_range().end |
| } |
| } |
| |
| impl TopLevelTable for Post<'_> { |
| /// `post` |
| const TAG: Tag = Tag::new(b"post"); |
| } |
| |
| impl<'a> FontRead<'a> for Post<'a> { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| let mut cursor = data.cursor(); |
| let version: Version16Dot16 = cursor.read()?; |
| cursor.advance::<Fixed>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<FWord>(); |
| cursor.advance::<u32>(); |
| cursor.advance::<u32>(); |
| cursor.advance::<u32>(); |
| cursor.advance::<u32>(); |
| cursor.advance::<u32>(); |
| let num_glyphs_byte_start = version |
| .compatible((2u16, 0u16)) |
| .then(|| cursor.position()) |
| .transpose()?; |
| let num_glyphs = version |
| .compatible((2u16, 0u16)) |
| .then(|| cursor.read::<u16>()) |
| .transpose()? |
| .unwrap_or_default(); |
| let glyph_name_index_byte_start = version |
| .compatible((2u16, 0u16)) |
| .then(|| cursor.position()) |
| .transpose()?; |
| let glyph_name_index_byte_len = version.compatible((2u16, 0u16)).then_some( |
| (num_glyphs as usize) |
| .checked_mul(u16::RAW_BYTE_LEN) |
| .ok_or(ReadError::OutOfBounds)?, |
| ); |
| if let Some(value) = glyph_name_index_byte_len { |
| cursor.advance_by(value); |
| } |
| let string_data_byte_start = version |
| .compatible((2u16, 0u16)) |
| .then(|| cursor.position()) |
| .transpose()?; |
| let string_data_byte_len = version |
| .compatible((2u16, 0u16)) |
| .then_some(cursor.remaining_bytes()); |
| if let Some(value) = string_data_byte_len { |
| cursor.advance_by(value); |
| } |
| cursor.finish(PostMarker { |
| num_glyphs_byte_start, |
| glyph_name_index_byte_start, |
| glyph_name_index_byte_len, |
| string_data_byte_start, |
| string_data_byte_len, |
| }) |
| } |
| } |
| |
| /// [post (PostScript)](https://docs.microsoft.com/en-us/typography/opentype/spec/post#header) table |
| pub type Post<'a> = TableRef<'a, PostMarker>; |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> Post<'a> { |
| /// 0x00010000 for version 1.0 0x00020000 for version 2.0 |
| /// 0x00025000 for version 2.5 (deprecated) 0x00030000 for version |
| /// 3.0 |
| pub fn version(&self) -> Version16Dot16 { |
| let range = self.shape.version_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Italic angle in counter-clockwise degrees from the vertical. |
| /// Zero for upright text, negative for text that leans to the |
| /// right (forward). |
| pub fn italic_angle(&self) -> Fixed { |
| let range = self.shape.italic_angle_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// This is the suggested distance of the top of the underline from |
| /// the baseline (negative values indicate below baseline). The |
| /// PostScript definition of this FontInfo dictionary key (the y |
| /// coordinate of the center of the stroke) is not used for |
| /// historical reasons. The value of the PostScript key may be |
| /// calculated by subtracting half the underlineThickness from the |
| /// value of this field. |
| pub fn underline_position(&self) -> FWord { |
| let range = self.shape.underline_position_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Suggested values for the underline thickness. In general, the |
| /// underline thickness should match the thickness of the |
| /// underscore character (U+005F LOW LINE), and should also match |
| /// the strikeout thickness, which is specified in the OS/2 table. |
| pub fn underline_thickness(&self) -> FWord { |
| let range = self.shape.underline_thickness_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Set to 0 if the font is proportionally spaced, non-zero if the |
| /// font is not proportionally spaced (i.e. monospaced). |
| pub fn is_fixed_pitch(&self) -> u32 { |
| let range = self.shape.is_fixed_pitch_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Minimum memory usage when an OpenType font is downloaded. |
| pub fn min_mem_type42(&self) -> u32 { |
| let range = self.shape.min_mem_type42_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Maximum memory usage when an OpenType font is downloaded. |
| pub fn max_mem_type42(&self) -> u32 { |
| let range = self.shape.max_mem_type42_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Minimum memory usage when an OpenType font is downloaded as a |
| /// Type 1 font. |
| pub fn min_mem_type1(&self) -> u32 { |
| let range = self.shape.min_mem_type1_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Maximum memory usage when an OpenType font is downloaded as a |
| /// Type 1 font. |
| pub fn max_mem_type1(&self) -> u32 { |
| let range = self.shape.max_mem_type1_byte_range(); |
| self.data.read_at(range.start).unwrap() |
| } |
| |
| /// Number of glyphs (this should be the same as numGlyphs in |
| /// 'maxp' table). |
| pub fn num_glyphs(&self) -> Option<u16> { |
| let range = self.shape.num_glyphs_byte_range()?; |
| Some(self.data.read_at(range.start).unwrap()) |
| } |
| |
| /// Array of indices into the string data. See below for details. |
| pub fn glyph_name_index(&self) -> Option<&'a [BigEndian<u16>]> { |
| let range = self.shape.glyph_name_index_byte_range()?; |
| Some(self.data.read_array(range).unwrap()) |
| } |
| |
| /// Storage for the string data. |
| pub fn string_data(&self) -> Option<VarLenArray<'a, PString<'a>>> { |
| let range = self.shape.string_data_byte_range()?; |
| Some(VarLenArray::read(self.data.split_off(range.start).unwrap()).unwrap()) |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| impl<'a> SomeTable<'a> for Post<'a> { |
| fn type_name(&self) -> &str { |
| "Post" |
| } |
| fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
| let version = self.version(); |
| match idx { |
| 0usize => Some(Field::new("version", self.version())), |
| 1usize => Some(Field::new("italic_angle", self.italic_angle())), |
| 2usize => Some(Field::new("underline_position", self.underline_position())), |
| 3usize => Some(Field::new( |
| "underline_thickness", |
| self.underline_thickness(), |
| )), |
| 4usize => Some(Field::new("is_fixed_pitch", self.is_fixed_pitch())), |
| 5usize => Some(Field::new("min_mem_type42", self.min_mem_type42())), |
| 6usize => Some(Field::new("max_mem_type42", self.max_mem_type42())), |
| 7usize => Some(Field::new("min_mem_type1", self.min_mem_type1())), |
| 8usize => Some(Field::new("max_mem_type1", self.max_mem_type1())), |
| 9usize if version.compatible((2u16, 0u16)) => { |
| Some(Field::new("num_glyphs", self.num_glyphs().unwrap())) |
| } |
| 10usize if version.compatible((2u16, 0u16)) => Some(Field::new( |
| "glyph_name_index", |
| self.glyph_name_index().unwrap(), |
| )), |
| 11usize if version.compatible((2u16, 0u16)) => { |
| Some(Field::new("string_data", self.traverse_string_data())) |
| } |
| _ => None, |
| } |
| } |
| } |
| |
| #[cfg(feature = "experimental_traverse")] |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> std::fmt::Debug for Post<'a> { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| (self as &dyn SomeTable<'a>).fmt(f) |
| } |
| } |