use super::*;
pub struct Type1Font<'a> {
dict: Dict<'a>,
}
writer!(Type1Font: |obj| {
let mut dict = obj.dict();
dict.pair(Name(b"Type"), Name(b"Font"));
dict.pair(Name(b"Subtype"), Name(b"Type1"));
Self { dict }
});
impl<'a> Type1Font<'a> {
pub fn name(&mut self, name: Name) -> &mut Self {
self.pair(Name(b"Name"), name);
self
}
pub fn base_font(&mut self, name: Name) -> &mut Self {
self.pair(Name(b"BaseFont"), name);
self
}
pub fn first_char(&mut self, first: u8) -> &mut Self {
self.pair(Name(b"FirstChar"), i32::from(first));
self
}
pub fn last_char(&mut self, last: u8) -> &mut Self {
self.pair(Name(b"LastChar"), i32::from(last));
self
}
pub fn widths(&mut self, widths: impl IntoIterator<Item = f32>) -> &mut Self {
self.insert(Name(b"Widths")).array().items(widths);
self
}
pub fn font_descriptor(&mut self, id: Ref) -> &mut Self {
self.pair(Name(b"FontDescriptor"), id);
self
}
pub fn encoding_predefined(&mut self, encoding: Name) -> &mut Self {
self.pair(Name(b"Encoding"), encoding);
self
}
pub fn encoding_custom(&mut self) -> Encoding<'_> {
self.insert(Name(b"Encoding")).start()
}
pub fn to_unicode(&mut self, id: Ref) -> &mut Self {
self.pair(Name(b"ToUnicode"), id);
self
}
}
deref!('a, Type1Font<'a> => Dict<'a>, dict);
pub struct Type3Font<'a> {
dict: Dict<'a>,
}
writer!(Type3Font: |obj| {
let mut dict = obj.dict();
dict.pair(Name(b"Type"), Name(b"Font"));
dict.pair(Name(b"Subtype"), Name(b"Type3"));
Self { dict }
});
impl<'a> Type3Font<'a> {
pub fn name(&mut self, name: Name) -> &mut Self {
self.pair(Name(b"Name"), name);
self
}
pub fn bbox(&mut self, bbox: Rect) -> &mut Self {
self.pair(Name(b"FontBBox"), bbox);
self
}
pub fn matrix(&mut self, matrix: [f32; 6]) -> &mut Self {
self.insert(Name(b"FontMatrix")).array().items(matrix);
self
}
pub fn char_procs(&mut self) -> TypedDict<'_, Ref> {
self.insert(Name(b"CharProcs")).dict().typed()
}
pub fn encoding_predefined(&mut self, encoding: Name) -> &mut Self {
self.pair(Name(b"Encoding"), encoding);
self
}
pub fn encoding_custom(&mut self) -> Encoding<'_> {
self.insert(Name(b"Encoding")).start()
}
pub fn first_char(&mut self, first: u8) -> &mut Self {
self.pair(Name(b"FirstChar"), i32::from(first));
self
}
pub fn last_char(&mut self, last: u8) -> &mut Self {
self.pair(Name(b"LastChar"), i32::from(last));
self
}
pub fn widths(&mut self, widths: impl IntoIterator<Item = f32>) -> &mut Self {
self.insert(Name(b"Widths")).array().items(widths);
self
}
pub fn font_descriptor(&mut self, id: Ref) -> &mut Self {
self.pair(Name(b"FontDescriptor"), id);
self
}
pub fn resources(&mut self) -> Resources<'_> {
self.insert(Name(b"Resources")).start()
}
pub fn to_unicode(&mut self, id: Ref) -> &mut Self {
self.pair(Name(b"ToUnicode"), id);
self
}
}
deref!('a, Type3Font<'a> => Dict<'a>, dict);
pub struct Encoding<'a> {
dict: Dict<'a>,
}
writer!(Encoding: |obj| {
let mut dict = obj.dict();
dict.pair(Name(b"Type"), Name(b"Encoding"));
Self { dict }
});
impl<'a> Encoding<'a> {
pub fn base_encoding(&mut self, name: Name) -> &mut Self {
self.pair(Name(b"BaseEncoding"), name);
self
}
pub fn differences(&mut self) -> Differences<'_> {
self.insert(Name(b"Differences")).start()
}
}
deref!('a, Encoding<'a> => Dict<'a>, dict);
pub struct Differences<'a> {
array: Array<'a>,
}
writer!(Differences: |obj| Self { array: obj.array() });
impl<'a> Differences<'a> {
pub fn consecutive<'n>(
&mut self,
start: u8,
names: impl IntoIterator<Item = Name<'n>>,
) -> &mut Self {
self.item(i32::from(start));
for name in names {
self.item(name);
}
self
}
}
deref!('a, Differences<'a> => Array<'a>, array);
pub struct Type0Font<'a> {
dict: Dict<'a>,
}
writer!(Type0Font: |obj| {
let mut dict = obj.dict();
dict.pair(Name(b"Type"), Name(b"Font"));
dict.pair(Name(b"Subtype"), Name(b"Type0"));
Self { dict }
});
impl<'a> Type0Font<'a> {
pub fn base_font(&mut self, name: Name) -> &mut Self {
self.pair(Name(b"BaseFont"), name);
self
}
pub fn encoding_predefined(&mut self, encoding: Name) -> &mut Self {
self.pair(Name(b"Encoding"), encoding);
self
}
pub fn encoding_cmap(&mut self, cmap: Ref) -> &mut Self {
self.pair(Name(b"Encoding"), cmap);
self
}
pub fn descendant_font(&mut self, cid_font: Ref) -> &mut Self {
self.insert(Name(b"DescendantFonts")).array().item(cid_font);
self
}
pub fn to_unicode(&mut self, cmap: Ref) -> &mut Self {
self.pair(Name(b"ToUnicode"), cmap);
self
}
}
deref!('a, Type0Font<'a> => Dict<'a>, dict);
pub struct CidFont<'a> {
dict: Dict<'a>,
}
writer!(CidFont: |obj| {
let mut dict = obj.dict();
dict.pair(Name(b"Type"), Name(b"Font"));
Self { dict }
});
impl<'a> CidFont<'a> {
pub fn subtype(&mut self, subtype: CidFontType) -> &mut Self {
self.pair(Name(b"Subtype"), subtype.to_name());
self
}
pub fn base_font(&mut self, name: Name) -> &mut Self {
self.pair(Name(b"BaseFont"), name);
self
}
pub fn system_info(&mut self, info: SystemInfo) -> &mut Self {
info.write(self.insert(Name(b"CIDSystemInfo")));
self
}
pub fn font_descriptor(&mut self, id: Ref) -> &mut Self {
self.pair(Name(b"FontDescriptor"), id);
self
}
pub fn default_width(&mut self, width: f32) -> &mut Self {
self.pair(Name(b"DW"), width);
self
}
pub fn widths(&mut self) -> Widths<'_> {
self.insert(Name(b"W")).start()
}
pub fn cid_to_gid_map_predefined(&mut self, name: Name) -> &mut Self {
self.pair(Name(b"CIDToGIDMap"), name);
self
}
pub fn cid_to_gid_map_stream(&mut self, stream: Ref) -> &mut Self {
self.pair(Name(b"CIDToGIDMap"), stream);
self
}
}
deref!('a, CidFont<'a> => Dict<'a>, dict);
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum CidFontType {
Type0,
Type2,
}
impl CidFontType {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::Type0 => Name(b"CIDFontType0"),
Self::Type2 => Name(b"CIDFontType2"),
}
}
}
pub struct Widths<'a> {
array: Array<'a>,
}
writer!(Widths: |obj| Self { array: obj.array() });
impl<'a> Widths<'a> {
pub fn consecutive(
&mut self,
start: u16,
widths: impl IntoIterator<Item = f32>,
) -> &mut Self {
self.item(i32::from(start));
self.push().array().items(widths);
self
}
pub fn same(&mut self, first: u16, last: u16, width: f32) -> &mut Self {
self.item(i32::from(first));
self.item(i32::from(last));
self.item(width);
self
}
}
deref!('a, Widths<'a> => Array<'a>, array);
pub struct FontDescriptor<'a> {
dict: Dict<'a>,
}
writer!(FontDescriptor: |obj| {
let mut dict = obj.dict();
dict.pair(Name(b"Type"), Name(b"FontDescriptor"));
Self { dict }
});
impl<'a> FontDescriptor<'a> {
pub fn name(&mut self, name: Name) -> &mut Self {
self.pair(Name(b"FontName"), name);
self
}
pub fn family(&mut self, family: Str) -> &mut Self {
self.pair(Name(b"FontFamily"), family);
self
}
pub fn stretch(&mut self, stretch: FontStretch) -> &mut Self {
self.pair(Name(b"FontStretch"), stretch.to_name());
self
}
pub fn weight(&mut self, weight: u16) -> &mut Self {
self.pair(Name(b"FontWeight"), i32::from(weight));
self
}
pub fn flags(&mut self, flags: FontFlags) -> &mut Self {
self.pair(Name(b"Flags"), flags.bits() as i32);
self
}
pub fn bbox(&mut self, bbox: Rect) -> &mut Self {
self.pair(Name(b"FontBBox"), bbox);
self
}
pub fn italic_angle(&mut self, angle: f32) -> &mut Self {
self.pair(Name(b"ItalicAngle"), angle);
self
}
pub fn ascent(&mut self, ascent: f32) -> &mut Self {
self.pair(Name(b"Ascent"), ascent);
self
}
pub fn descent(&mut self, descent: f32) -> &mut Self {
self.pair(Name(b"Descent"), descent);
self
}
pub fn leading(&mut self, leading: f32) -> &mut Self {
self.pair(Name(b"Leading"), leading);
self
}
pub fn cap_height(&mut self, cap_height: f32) -> &mut Self {
self.pair(Name(b"CapHeight"), cap_height);
self
}
pub fn x_height(&mut self, x_height: f32) -> &mut Self {
self.pair(Name(b"XHeight"), x_height);
self
}
pub fn stem_v(&mut self, stem_v: f32) -> &mut Self {
self.pair(Name(b"StemV"), stem_v);
self
}
pub fn stem_h(&mut self, stem_h: f32) -> &mut Self {
self.pair(Name(b"StemH"), stem_h);
self
}
pub fn avg_width(&mut self, avg_width: f32) -> &mut Self {
self.pair(Name(b"AvgWidth"), avg_width);
self
}
pub fn max_width(&mut self, max_width: f32) -> &mut Self {
self.pair(Name(b"MaxWidth"), max_width);
self
}
pub fn missing_width(&mut self, missing_width: f32) -> &mut Self {
self.pair(Name(b"MissingWidth"), missing_width);
self
}
pub fn font_file(&mut self, id: Ref) -> &mut Self {
self.pair(Name(b"FontFile"), id);
self
}
pub fn font_file2(&mut self, id: Ref) -> &mut Self {
self.pair(Name(b"FontFile2"), id);
self
}
pub fn font_file3(&mut self, id: Ref) -> &mut Self {
self.pair(Name(b"FontFile3"), id);
self
}
pub fn char_set(&mut self, names: Str) -> &mut Self {
self.pair(Name(b"CharSet"), names);
self
}
}
deref!('a, FontDescriptor<'a> => Dict<'a>, dict);
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[allow(missing_docs)]
pub enum FontStretch {
UltraCondensed,
ExtraCondensed,
Condensed,
SemiCondensed,
Normal,
SemiExpanded,
Expanded,
ExtraExpanded,
UltraExpanded,
}
impl FontStretch {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::UltraCondensed => Name(b"UltraCondensed"),
Self::ExtraCondensed => Name(b"ExtraCondensed"),
Self::Condensed => Name(b"Condensed"),
Self::SemiCondensed => Name(b"SemiCondensed"),
Self::Normal => Name(b"Normal"),
Self::SemiExpanded => Name(b"SemiExpanded"),
Self::Expanded => Name(b"Expanded"),
Self::ExtraExpanded => Name(b"ExtraExpanded"),
Self::UltraExpanded => Name(b"UltraExpanded"),
}
}
}
bitflags::bitflags! {
pub struct FontFlags: u32 {
const FIXED_PITCH = 1 << 0;
const SERIF = 1 << 1;
const SYMBOLIC = 1 << 2;
const SCRIPT = 1 << 3;
const NON_SYMBOLIC = 1 << 5;
const ITALIC = 1 << 6;
const ALL_CAP = 1 << 16;
const SMALL_CAP = 1 << 17;
const FORCE_BOLD = 1 << 18;
}
}
pub struct Cmap<'a> {
stream: Stream<'a>,
}
impl<'a> Cmap<'a> {
pub(crate) fn start(mut stream: Stream<'a>) -> Self {
stream.pair(Name(b"Type"), Name(b"CMap"));
Self { stream }
}
pub fn name(&mut self, name: Name) -> &mut Self {
self.pair(Name(b"CMapName"), name);
self
}
pub fn system_info(&mut self, info: SystemInfo) -> &mut Self {
info.write(self.insert(Name(b"CIDSystemInfo")));
self
}
}
deref!('a, Cmap<'a> => Stream<'a>, stream);
pub struct UnicodeCmap {
buf: Vec<u8>,
mappings: Vec<u8>,
count: i32,
}
impl UnicodeCmap {
pub fn new(name: Name, info: SystemInfo) -> Self {
let mut buf = Vec::new();
buf.extend(b"%!PS-Adobe-3.0 Resource-CMap\n");
buf.extend(b"%%DocumentNeededResources: procset CIDInit\n");
buf.extend(b"%%IncludeResource: procset CIDInit\n");
buf.extend(b"%%BeginResource: CMap ");
buf.extend(name.0);
buf.push(b'\n');
buf.extend(b"%%Title: (");
buf.extend(name.0);
buf.push(b' ');
buf.extend(info.registry.0);
buf.push(b' ');
buf.extend(info.ordering.0);
buf.push(b' ');
buf.push_int(info.supplement);
buf.extend(b")\n");
buf.extend(b"%%Version: 1\n");
buf.extend(b"%%EndComments\n");
buf.extend(b"/CIDInit /ProcSet findresource begin\n");
buf.extend(b"12 dict begin\n");
buf.extend(b"begincmap\n");
buf.extend(b"/CIDSystemInfo 3 dict dup begin\n");
buf.extend(b" /Registry ");
buf.push_val(info.registry);
buf.extend(b" def\n");
buf.extend(b" /Ordering ");
buf.push_val(info.ordering);
buf.extend(b" def\n");
buf.extend(b" /Supplement ");
buf.push_val(info.supplement);
buf.extend(b" def\n");
buf.extend(b"end def\n");
buf.extend(b"/CMapName ");
buf.push_val(name);
buf.extend(b" def\n");
buf.extend(b"/CMapVersion 1 def\n");
buf.extend(b"/CMapType 0 def\n");
buf.extend(b"1 begincodespacerange\n");
buf.extend(b"<0000> <ffff>\n");
buf.extend(b"endcodespacerange\n");
Self { buf, mappings: vec![], count: 0 }
}
pub fn pair(&mut self, glyph: u16, codepoint: char) {
self.pair_with_multiple(glyph, [codepoint]);
}
pub fn pair_with_multiple(
&mut self,
glyph: u16,
codepoints: impl IntoIterator<Item = char>,
) {
self.mappings.push(b'<');
self.mappings.push_hex_u16(glyph);
self.mappings.extend(b"> <");
for c in codepoints {
for &mut part in c.encode_utf16(&mut [0; 2]) {
self.mappings.push_hex_u16(part);
}
}
self.mappings.extend(b">\n");
self.count += 1;
if self.count >= 100 {
self.flush_range();
}
}
pub fn finish(mut self) -> Vec<u8> {
self.flush_range();
self.buf.extend(b"endcmap\n");
self.buf.extend(b"CMapName currentdict /CMap defineresource pop\n");
self.buf.extend(b"end\n");
self.buf.extend(b"end\n");
self.buf.extend(b"%%EndResource\n");
self.buf.extend(b"%%EOF");
self.buf
}
fn flush_range(&mut self) {
if self.count > 0 {
self.buf.push_int(self.count);
self.buf.extend(b" beginbfchar\n");
self.buf.extend(&self.mappings);
self.buf.extend(b"endbfchar\n");
}
self.count = 0;
self.mappings.clear();
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct SystemInfo<'a> {
pub registry: Str<'a>,
pub ordering: Str<'a>,
pub supplement: i32,
}
impl SystemInfo<'_> {
fn write(&self, obj: Obj<'_>) {
obj.dict()
.pair(Name(b"Registry"), self.registry)
.pair(Name(b"Ordering"), self.ordering)
.pair(Name(b"Supplement"), self.supplement);
}
}