diff --git a/src/pdf/font.rs b/src/pdf/font.rs index 23d479e..bfc52b7 100644 --- a/src/pdf/font.rs +++ b/src/pdf/font.rs @@ -1,7 +1,10 @@ use std::{borrow::Cow, sync::Arc}; use crate::pdf::{ - object::{IsPdfNull, PdfDictionary, PdfName, PdfObject, PdfObjectDirect, PdfStream}, + object::{ + IsPdfNull, PdfDictionary, PdfName, PdfObject, PdfObjectDirect, PdfRectangle, PdfStream, + PdfString, + }, parse::{PdfParse, PdfParseError}, pdf_parse, }; @@ -17,12 +20,90 @@ pdf_parse! { } pdf_parse! { - #[pdf(transparent)] + #[pdf(name)] + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug)] + pub enum PdfFontDescriptorType { + #[pdf(name = "FontDescriptor")] + #[default] + FontDescriptor, + } +} + +pdf_parse! { + #[pdf(name)] + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] + pub enum PdfFontStretch { + #[pdf(name = "UltraCondensed")] + UltraCondensed, + #[pdf(name = "ExtraCondensed")] + ExtraCondensed, + #[pdf(name = "Condensed")] + Condensed, + #[pdf(name = "SemiCondensed")] + SemiCondensed, + #[pdf(name = "Normal")] + Normal, + #[pdf(name = "SemiExpanded")] + SemiExpanded, + #[pdf(name = "Expanded")] + Expanded, + #[pdf(name = "ExtraExpanded")] + ExtraExpanded, + #[pdf(name = "UltraExpanded")] + UltraExpanded, + } +} + +pdf_parse! { + #[pdf] #[derive(Clone, Debug)] - // TODO: actually parse the dictionary pub struct PdfFontDescriptor { - #[pdf] - dictionary: PdfDictionary, + #[pdf(name = "Type")] + pub ty: PdfFontDescriptorType, + #[pdf(name = "FontName")] + pub font_name: PdfName, + #[pdf(name = "FontFamily")] + pub font_family: Option, + #[pdf(name = "FontStretch")] + pub font_stretch: Option, + #[pdf(name = "FontWeight")] + pub font_weight: Option, + #[pdf(name = "Flags")] + pub flags: u32, + #[pdf(name = "FontBBox")] + pub font_bounding_box: Option, + #[pdf(name = "ItalicAngle")] + pub italic_angle: f32, + #[pdf(name = "Ascent")] + pub ascent: Option, + #[pdf(name = "Descent")] + pub descent: Option, + #[pdf(name = "Leading")] + pub leading: Option, + #[pdf(name = "CapHeight")] + pub cap_height: Option, + #[pdf(name = "XHeight")] + pub x_height: Option, + #[pdf(name = "StemV")] + pub stem_v: Option, + #[pdf(name = "StemH")] + pub stem_h: Option, + #[pdf(name = "AvgWidth")] + pub avg_width: Option, + #[pdf(name = "MaxWidth")] + pub max_width: Option, + #[pdf(name = "MissingWidth")] + pub missing_width: Option, + #[pdf(name = "FontFile")] + pub font_file: Option, + #[pdf(name = "FontFile2")] + pub font_file2: Option, + #[pdf(name = "FontFile3")] + pub font_file3: Option, + #[pdf(name = "CharSet")] + pub char_set: Option, + #[pdf(flatten)] + pub rest: PdfDictionary, } } @@ -152,6 +233,69 @@ pub enum PdfFontType1 { Other(PdfFontType1Other), } +impl PdfFontType1 { + pub fn common(&self) -> PdfFontType1Common { + match self { + PdfFontType1::Standard(v) => v.common(), + PdfFontType1::Other(v) => v.common(), + } + } + pub fn name(&self) -> &Option { + match self { + Self::Standard(v) => &v.name, + Self::Other(v) => &v.name, + } + } + pub fn base_font(&self) -> PdfName { + match self { + Self::Standard(v) => v.base_font.into(), + Self::Other(v) => v.base_font.clone(), + } + } + pub fn first_char(&self) -> Option { + match self { + Self::Standard(v) => v.first_char, + Self::Other(v) => Some(v.first_char), + } + } + pub fn last_char(&self) -> Option { + match self { + Self::Standard(v) => v.last_char, + Self::Other(v) => Some(v.last_char), + } + } + pub fn widths(&self) -> Option<&Arc<[f32]>> { + match self { + Self::Standard(v) => v.widths.as_ref(), + Self::Other(v) => Some(&v.widths), + } + } + pub fn font_descriptor(&self) -> Option<&PdfFontDescriptor> { + match self { + Self::Standard(v) => v.font_descriptor.as_ref(), + Self::Other(v) => Some(&v.font_descriptor), + } + } + pub fn encoding(&self) -> &PdfObjectDirect { + match self { + Self::Standard(v) => &v.encoding, + Self::Other(v) => &v.encoding, + } + } + pub fn to_unicode(&self) -> &Option { + match self { + Self::Standard(v) => &v.to_unicode, + Self::Other(v) => &v.to_unicode, + } + } + pub fn rest(&self) -> &PdfDictionary { + match self { + Self::Standard(v) => &v.rest, + Self::Other(v) => &v.rest, + } + } +} + impl IsPdfNull for PdfFontType1 { fn is_pdf_null(&self) -> bool { false @@ -175,6 +319,21 @@ impl PdfParse for PdfFontType1 { } } +#[derive(Clone, Debug)] +pub struct PdfFontType1Common { + pub ty: PdfFontType, + pub subtype: PdfFontType1Subtype, + pub name: Option, + pub base_font: PdfName, + pub first_char: Option, + pub last_char: Option, + pub widths: Option>, + pub font_descriptor: Option, + pub encoding: PdfObjectDirect, + pub to_unicode: Option, + pub rest: PdfDictionary, +} + pdf_parse! { #[pdf] #[derive(Clone, Debug)] @@ -205,6 +364,37 @@ pdf_parse! { } } +impl PdfFontType1Standard { + pub fn common(&self) -> PdfFontType1Common { + let Self { + ty, + subtype, + ref name, + base_font, + first_char, + last_char, + ref widths, + ref font_descriptor, + ref encoding, + ref to_unicode, + ref rest, + } = *self; + PdfFontType1Common { + ty, + subtype, + name: name.clone(), + base_font: base_font.into(), + first_char, + last_char, + widths: widths.clone(), + font_descriptor: font_descriptor.clone(), + encoding: encoding.clone(), + to_unicode: to_unicode.clone(), + rest: rest.clone(), + } + } +} + pdf_parse! { #[pdf] #[derive(Clone, Debug)] @@ -234,3 +424,34 @@ pdf_parse! { pub rest: PdfDictionary, } } + +impl PdfFontType1Other { + pub fn common(&self) -> PdfFontType1Common { + let Self { + ty, + subtype, + ref name, + ref base_font, + first_char, + last_char, + ref widths, + ref font_descriptor, + ref encoding, + ref to_unicode, + ref rest, + } = *self; + PdfFontType1Common { + ty, + subtype, + name: name.clone(), + base_font: base_font.clone(), + first_char: Some(first_char), + last_char: Some(last_char), + widths: Some(widths.clone()), + font_descriptor: Some(font_descriptor.clone()), + encoding: encoding.clone(), + to_unicode: to_unicode.clone(), + rest: rest.clone(), + } + } +}