add more font structures

This commit is contained in:
Jacob Lifshay 2025-12-26 01:42:18 -08:00
parent e0993fdb4a
commit 13dcea1dab
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ

View file

@ -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<PdfString>,
#[pdf(name = "FontStretch")]
pub font_stretch: Option<PdfFontStretch>,
#[pdf(name = "FontWeight")]
pub font_weight: Option<u32>,
#[pdf(name = "Flags")]
pub flags: u32,
#[pdf(name = "FontBBox")]
pub font_bounding_box: Option<PdfRectangle>,
#[pdf(name = "ItalicAngle")]
pub italic_angle: f32,
#[pdf(name = "Ascent")]
pub ascent: Option<f32>,
#[pdf(name = "Descent")]
pub descent: Option<f32>,
#[pdf(name = "Leading")]
pub leading: Option<f32>,
#[pdf(name = "CapHeight")]
pub cap_height: Option<f32>,
#[pdf(name = "XHeight")]
pub x_height: Option<f32>,
#[pdf(name = "StemV")]
pub stem_v: Option<f32>,
#[pdf(name = "StemH")]
pub stem_h: Option<f32>,
#[pdf(name = "AvgWidth")]
pub avg_width: Option<f32>,
#[pdf(name = "MaxWidth")]
pub max_width: Option<f32>,
#[pdf(name = "MissingWidth")]
pub missing_width: Option<f32>,
#[pdf(name = "FontFile")]
pub font_file: Option<PdfStream>,
#[pdf(name = "FontFile2")]
pub font_file2: Option<PdfStream>,
#[pdf(name = "FontFile3")]
pub font_file3: Option<PdfStream>,
#[pdf(name = "CharSet")]
pub char_set: Option<PdfString>,
#[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<PdfName> {
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<u32> {
match self {
Self::Standard(v) => v.first_char,
Self::Other(v) => Some(v.first_char),
}
}
pub fn last_char(&self) -> Option<u32> {
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<PdfFontToUnicode> {
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<PdfName>,
pub base_font: PdfName,
pub first_char: Option<u32>,
pub last_char: Option<u32>,
pub widths: Option<Arc<[f32]>>,
pub font_descriptor: Option<PdfFontDescriptor>,
pub encoding: PdfObjectDirect,
pub to_unicode: Option<PdfFontToUnicode>,
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(),
}
}
}