hayro_syntax/object/
dict.rs

1//! Dictionaries.
2
3use crate::object::Name;
4use crate::object::Null;
5use crate::object::macros::object;
6use crate::object::r#ref::{MaybeRef, ObjRef};
7use crate::object::{Object, ObjectLike};
8use crate::reader::{Readable, Reader, ReaderContext, Skippable};
9use crate::xref::XRef;
10use std::collections::HashMap;
11use std::fmt::{Debug, Formatter};
12use std::ops::Deref;
13use std::sync::Arc;
14
15/// A dictionary, which is a key-value map, keys being names, and values being any PDF object or
16/// objetc reference.
17#[derive(Clone)]
18pub struct Dict<'a>(Arc<Repr<'a>>);
19
20impl Default for Dict<'_> {
21    fn default() -> Self {
22        Self::empty()
23    }
24}
25
26// Note that this is not structural equality, i.e. two dictionaries with the same
27// items are still considered different if they have different whitespaces.
28impl PartialEq for Dict<'_> {
29    fn eq(&self, other: &Self) -> bool {
30        self.0.data == other.0.data
31    }
32}
33
34impl<'a> Dict<'a> {
35    /// Create a new empty dictionary.
36    pub fn empty() -> Dict<'a> {
37        let repr = Repr {
38            data: &[],
39            offsets: Default::default(),
40            ctx: ReaderContext::new(XRef::dummy(), false),
41        };
42
43        Self(Arc::new(repr))
44    }
45
46    pub(crate) fn data(&self) -> &'a [u8] {
47        self.0.data
48    }
49
50    /// Returns the number of entries in the dictionary.
51    pub fn len(&self) -> usize {
52        self.0.offsets.len()
53    }
54
55    /// Return whether the dictionary is empty.
56    pub fn is_empty(&self) -> bool {
57        self.0.offsets.is_empty()
58    }
59
60    /// Checks whether the dictionary contains an entry with a specific key.
61    pub fn contains_key(&self, key: impl Deref<Target = [u8]>) -> bool {
62        self.0
63            .offsets
64            .contains_key(&Name::from_unescaped(key.deref()))
65    }
66
67    /// Returns the entry of a key as a specific object, or try to resolve it in case it's
68    /// an object reference.
69    #[allow(
70        private_bounds,
71        reason = "users shouldn't be able to implement `ObjectLike` for custom objects."
72    )]
73    pub fn get<'b, T>(&self, key: impl Deref<Target = [u8]>) -> Option<T>
74    where
75        T: ObjectLike<'a>,
76    {
77        self.get_raw::<T>(key.as_ref())?.resolve(self.0.ctx)
78    }
79
80    /// Get the object reference linked to a key.
81    pub fn get_ref(&self, key: impl Deref<Target = [u8]>) -> Option<ObjRef> {
82        let offset = *self.0.offsets.get(&Name::from_unescaped(key.as_ref()))?;
83
84        Reader::new(&self.0.data[offset..]).read_with_context::<ObjRef>(self.0.ctx)
85    }
86
87    /// Returns an iterator over all keys in the dictionary.
88    pub fn keys(&self) -> impl Iterator<Item = Name<'a>> {
89        self.0.offsets.keys().cloned()
90    }
91
92    /// An iterator over all entries in the dictionary, sorted by key.
93    pub fn entries(&self) -> impl Iterator<Item = (Name<'a>, MaybeRef<Object<'a>>)> {
94        let mut sorted_keys = self.keys().collect::<Vec<_>>();
95        sorted_keys.sort_by(|n1, n2| n1.as_ref().cmp(n2.as_ref()));
96        sorted_keys.into_iter().map(|k| {
97            let obj = self.get_raw(k.deref()).unwrap();
98            (k, obj)
99        })
100    }
101
102    /// Return the raw entry for a specific key.
103    #[allow(private_bounds)]
104    pub fn get_raw<T>(&self, key: impl Deref<Target = [u8]>) -> Option<MaybeRef<T>>
105    where
106        T: Readable<'a>,
107    {
108        let offset = *self.0.offsets.get(&Name::from_unescaped(key.as_ref()))?;
109
110        Reader::new(&self.0.data[offset..]).read_with_context::<MaybeRef<T>>(self.0.ctx)
111    }
112}
113
114impl Debug for Dict<'_> {
115    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
116        let mut r = Reader::new(self.0.data);
117        let mut debug_struct = f.debug_struct("Dict");
118
119        for (key, val) in &self.0.offsets {
120            r.jump(*val);
121            debug_struct.field(
122                &format!("{:?}", key.as_str()),
123                &r.read_with_context::<MaybeRef<Object>>(ReaderContext::dummy())
124                    .unwrap(),
125            );
126        }
127        Ok(())
128    }
129}
130
131impl Skippable for Dict<'_> {
132    fn skip(r: &mut Reader<'_>, is_content_stream: bool) -> Option<()> {
133        r.forward_tag(b"<<")?;
134
135        loop {
136            r.skip_white_spaces_and_comments();
137
138            if let Some(()) = r.forward_tag(b">>") {
139                break Some(());
140            } else {
141                r.skip::<Name>(is_content_stream)?;
142                r.skip_white_spaces_and_comments();
143
144                if is_content_stream {
145                    r.skip::<Object>(is_content_stream)?;
146                } else {
147                    r.skip::<MaybeRef<Object>>(is_content_stream)?;
148                }
149            }
150        }
151    }
152}
153
154impl<'a> Readable<'a> for Dict<'a> {
155    fn read(r: &mut Reader<'a>, ctx: ReaderContext<'a>) -> Option<Self> {
156        read_inner(r, ctx, Some(b"<<"), b">>")
157    }
158}
159
160fn read_inner<'a>(
161    r: &mut Reader<'a>,
162    ctx: ReaderContext<'a>,
163    start_tag: Option<&[u8]>,
164    end_tag: &[u8],
165) -> Option<Dict<'a>> {
166    let mut offsets = HashMap::new();
167
168    let data = {
169        let dict_data = r.tail()?;
170        let start_offset = r.offset();
171
172        // Inline image dictionaries don't start with '<<'.
173        if let Some(start_tag) = start_tag {
174            r.forward_tag(start_tag)?;
175        }
176
177        loop {
178            r.skip_white_spaces_and_comments();
179
180            // Normal dictionaries end with '>>', inline image dictionaries end with BD.
181            if let Some(()) = r.peek_tag(end_tag) {
182                r.forward_tag(end_tag)?;
183                let end_offset = r.offset() - start_offset;
184
185                break &dict_data[..end_offset];
186            } else {
187                let name = r.read_without_context::<Name>()?;
188                r.skip_white_spaces_and_comments();
189
190                // Keys with null objects should be treated as non-existing.
191                let is_null = {
192                    let mut nr = Reader::new(r.tail()?);
193
194                    if ctx.in_content_stream {
195                        nr.read_with_context::<Null>(ctx)
196                    } else {
197                        nr.read_with_context::<MaybeRef<Null>>(ctx)
198                            .and_then(|n| n.resolve(ctx))
199                    }
200                    .is_some()
201                };
202
203                if !is_null {
204                    let offset = r.offset() - start_offset;
205                    offsets.insert(name, offset);
206                }
207
208                if ctx.in_content_stream {
209                    r.skip::<Object>(ctx.in_content_stream)?;
210                } else {
211                    r.skip::<MaybeRef<Object>>(ctx.in_content_stream)?;
212                }
213            }
214        }
215    };
216
217    Some(Dict(Arc::new(Repr { data, offsets, ctx })))
218}
219
220object!(Dict<'a>, Dict);
221
222struct Repr<'a> {
223    data: &'a [u8],
224    offsets: HashMap<Name<'a>, usize>,
225    ctx: ReaderContext<'a>,
226}
227
228pub(crate) struct InlineImageDict<'a>(Dict<'a>);
229
230impl<'a> InlineImageDict<'a> {
231    pub(crate) fn get_dict(&self) -> &Dict<'a> {
232        &self.0
233    }
234}
235
236impl<'a> Readable<'a> for InlineImageDict<'a> {
237    fn read(r: &mut Reader<'a>, ctx: ReaderContext<'a>) -> Option<Self> {
238        Some(Self(read_inner(r, ctx, None, b"ID")?))
239    }
240}
241
242/// A collection of possible keys in a PDF dictionary. Copied and adapted from PDFBox.
243#[allow(missing_docs)]
244pub mod keys {
245    macro_rules! key {
246        ($i:ident, $e:expr) => {
247            pub const $i: &'static [u8] = $e;
248        };
249    }
250
251    // A
252    key!(A, b"A");
253    key!(AA, b"AA");
254    key!(ABSOLUTE_COLORIMETRIC, b"AbsoluteColorimetric");
255    key!(AC, b"AC");
256    key!(ACRO_FORM, b"AcroForm");
257    key!(ACTUAL_TEXT, b"ActualText");
258    key!(ADBE, b"ADBE");
259    key!(ADBE_PKCS7_DETACHED, b"adbe.pkcs7.detached");
260    key!(ADBE_PKCS7_SHA1, b"adbe.pkcs7.sha1");
261    key!(ADBE_X509_RSA_SHA1, b"adbe.x509.rsa_sha1");
262    key!(ADOBE_PPKLITE, b"Adobe.PPKLite");
263    key!(AESV2, b"AESV2");
264    key!(AESV3, b"AESV3");
265    key!(AF, b"AF");
266    key!(AF_RELATIONSHIP, b"AFRelationship");
267    key!(AFTER, b"After");
268    key!(AI_META_DATA, b"AIMetaData");
269    key!(AIS, b"AIS");
270    key!(ALL_OFF, b"AllOff");
271    key!(ALL_ON, b"AllOn");
272    key!(ALT, b"Alt");
273    key!(ALPHA, b"Alpha");
274    key!(ALTERNATE, b"Alternate");
275    key!(ANNOT, b"Annot");
276    key!(ANNOTS, b"Annots");
277    key!(ANTI_ALIAS, b"AntiAlias");
278    key!(ANY_OFF, b"AnyOff");
279    key!(ANY_ON, b"AnyOn");
280    key!(AP, b"AP");
281    key!(AP_REF, b"APRef");
282    key!(APP, b"App");
283    key!(ART_BOX, b"ArtBox");
284    key!(ARTIFACT, b"Artifact");
285    key!(AS, b"AS");
286    key!(ASCENT, b"Ascent");
287    key!(ASCII_HEX_DECODE, b"ASCIIHexDecode");
288    key!(ASCII_HEX_DECODE_ABBREVIATION, b"AHx");
289    key!(ASCII85_DECODE, b"ASCII85Decode");
290    key!(ASCII85_DECODE_ABBREVIATION, b"A85");
291    key!(ATTACHED, b"Attached");
292    key!(AUTHOR, b"Author");
293    key!(AVG_WIDTH, b"AvgWidth");
294
295    // B
296    key!(B, b"B");
297    key!(BACKGROUND, b"Background");
298    key!(BASE_ENCODING, b"BaseEncoding");
299    key!(BASE_FONT, b"BaseFont");
300    key!(BASE_STATE, b"BaseState");
301    key!(BASE_VERSION, b"BaseVersion");
302    key!(BBOX, b"BBox");
303    key!(BC, b"BC");
304    key!(BE, b"BE");
305    key!(BEAD, b"BEAD");
306    key!(BEFORE, b"Before");
307    key!(BG, b"BG");
308    key!(BITS_PER_COMPONENT, b"BitsPerComponent");
309    key!(BITS_PER_COORDINATE, b"BitsPerCoordinate");
310    key!(BITS_PER_FLAG, b"BitsPerFlag");
311    key!(BITS_PER_SAMPLE, b"BitsPerSample");
312    key!(BL, b"Bl");
313    key!(BLACK_IS_1, b"BlackIs1");
314    key!(BLACK_POINT, b"BlackPoint");
315    key!(BLEED_BOX, b"BleedBox");
316    key!(BM, b"BM");
317    key!(BORDER, b"Border");
318    key!(BOUNDS, b"Bounds");
319    key!(BPC, b"BPC");
320    key!(BS, b"BS");
321    key!(BTN, b"Btn");
322    key!(BYTERANGE, b"ByteRange");
323
324    // C
325    key!(C, b"C");
326    key!(C0, b"C0");
327    key!(C1, b"C1");
328    key!(CA, b"CA");
329    key!(CA_NS, b"ca");
330    key!(CALGRAY, b"CalGray");
331    key!(CALRGB, b"CalRGB");
332    key!(CALCMYK, b"CalCMYK");
333    key!(CAP, b"Cap");
334    key!(CAP_HEIGHT, b"CapHeight");
335    key!(CATALOG, b"Catalog");
336    key!(CCITTFAX_DECODE, b"CCITTFaxDecode");
337    key!(CCITTFAX_DECODE_ABBREVIATION, b"CCF");
338    key!(CENTER_WINDOW, b"CenterWindow");
339    key!(CERT, b"Cert");
340    key!(CERTS, b"Certs");
341    key!(CF, b"CF");
342    key!(CFM, b"CFM");
343    key!(CH, b"Ch");
344    key!(CHAR_PROCS, b"CharProcs");
345    key!(CHAR_SET, b"CharSet");
346    key!(CHECK_SUM, b"CheckSum");
347    key!(CI, b"CI");
348    key!(CICI_SIGNIT, b"CICI.SignIt");
349    key!(CID_FONT_TYPE0, b"CIDFontType0");
350    key!(CID_FONT_TYPE0C, b"CIDFontType0C");
351    key!(CID_FONT_TYPE2, b"CIDFontType2");
352    key!(CID_TO_GID_MAP, b"CIDToGIDMap");
353    key!(CID_SET, b"CIDSet");
354    key!(CIDSYSTEMINFO, b"CIDSystemInfo");
355    key!(CL, b"CL");
356    key!(CLASS_MAP, b"ClassMap");
357    key!(CLR_F, b"ClrF");
358    key!(CLR_FF, b"ClrFf");
359    key!(CMAP, b"CMap");
360    key!(CMAPNAME, b"CMapName");
361    key!(CMYK, b"CMYK");
362    key!(CO, b"CO");
363    key!(COLOR, b"Color");
364    key!(COLLECTION, b"Collection");
365    key!(COLLECTION_ITEM, b"CollectionItem");
366    key!(COLLECTION_FIELD, b"CollectionField");
367    key!(COLLECTION_SCHEMA, b"CollectionSchema");
368    key!(COLLECTION_SORT, b"CollectionSort");
369    key!(COLLECTION_SUBITEM, b"CollectionSubitem");
370    key!(COLOR_BURN, b"ColorBurn");
371    key!(COLOR_DODGE, b"ColorDodge");
372    key!(COLORANTS, b"Colorants");
373    key!(COLORS, b"Colors");
374    key!(COLORSPACE, b"ColorSpace");
375    key!(COLUMNS, b"Columns");
376    key!(COMPATIBLE, b"Compatible");
377    key!(COMPONENTS, b"Components");
378    key!(CONTACT_INFO, b"ContactInfo");
379    key!(CONTENTS, b"Contents");
380    key!(COORDS, b"Coords");
381    key!(COUNT, b"Count");
382    key!(CP, b"CP");
383    key!(CREATION_DATE, b"CreationDate");
384    key!(CREATOR, b"Creator");
385    key!(CRL, b"CRL");
386    key!(CRLS, b"CRLS");
387    key!(CROP_BOX, b"CropBox");
388    key!(CRYPT, b"Crypt");
389    key!(CS, b"CS");
390    key!(CYX, b"CYX");
391
392    // D
393    key!(D, b"D");
394    key!(DA, b"DA");
395    key!(DARKEN, b"Darken");
396    key!(DATE, b"Date");
397    key!(DCT_DECODE, b"DCTDecode");
398    key!(DCT_DECODE_ABBREVIATION, b"DCT");
399    key!(DECODE, b"Decode");
400    key!(DECODE_PARMS, b"DecodeParms");
401    key!(DEFAULT, b"default");
402    key!(DEFAULT_CMYK, b"DefaultCMYK");
403    key!(DEFAULT_CRYPT_FILTER, b"DefaultCryptFilter");
404    key!(DEFAULT_GRAY, b"DefaultGray");
405    key!(DEFAULT_RGB, b"DefaultRGB");
406    key!(DESC, b"Desc");
407    key!(DESCENDANT_FONTS, b"DescendantFonts");
408    key!(DESCENT, b"Descent");
409    key!(DEST, b"Dest");
410    key!(DEST_OUTPUT_PROFILE, b"DestOutputProfile");
411    key!(DESTS, b"Dests");
412    key!(DEVICE_CMYK, b"DeviceCMYK");
413    key!(DEVICE_GRAY, b"DeviceGray");
414    key!(DEVICE_N, b"DeviceN");
415    key!(DEVICE_RGB, b"DeviceRGB");
416    key!(DI, b"Di");
417    key!(DIFFERENCE, b"Difference");
418    key!(DIFFERENCES, b"Differences");
419    key!(DIGEST_METHOD, b"DigestMethod");
420    key!(DIGEST_RIPEMD160, b"RIPEMD160");
421    key!(DIGEST_SHA1, b"SHA1");
422    key!(DIGEST_SHA256, b"SHA256");
423    key!(DIGEST_SHA384, b"SHA384");
424    key!(DIGEST_SHA512, b"SHA512");
425    key!(DIRECTION, b"Direction");
426    key!(DISPLAY_DOC_TITLE, b"DisplayDocTitle");
427    key!(DL, b"DL");
428    key!(DM, b"Dm");
429    key!(DOC, b"Doc");
430    key!(DOC_CHECKSUM, b"DocChecksum");
431    key!(DOC_TIME_STAMP, b"DocTimeStamp");
432    key!(DOCMDP, b"DocMDP");
433    key!(DOCUMENT, b"Document");
434    key!(DOMAIN, b"Domain");
435    key!(DOS, b"DOS");
436    key!(DP, b"DP");
437    key!(DR, b"DR");
438    key!(DS, b"DS");
439    key!(DSS, b"DSS");
440    key!(DUPLEX, b"Duplex");
441    key!(DUR, b"Dur");
442    key!(DV, b"DV");
443    key!(DW, b"DW");
444    key!(DW2, b"DW2");
445
446    // E
447    key!(E, b"E");
448    key!(EARLY_CHANGE, b"EarlyChange");
449    key!(EF, b"EF");
450    key!(EMBEDDED_FDFS, b"EmbeddedFDFs");
451    key!(EMBEDDED_FILE, b"EmbeddedFile");
452    key!(EMBEDDED_FILES, b"EmbeddedFiles");
453    key!(EMPTY, b"");
454    key!(ENCODE, b"Encode");
455    key!(ENCODED_BYTE_ALIGN, b"EncodedByteAlign");
456    key!(ENCODING, b"Encoding");
457    key!(ENCODING_90MS_RKSJ_H, b"90ms-RKSJ-H");
458    key!(ENCODING_90MS_RKSJ_V, b"90ms-RKSJ-V");
459    key!(ENCODING_ETEN_B5_H, b"ETen-B5-H");
460    key!(ENCODING_ETEN_B5_V, b"ETen-B5-V");
461    key!(ENCRYPT, b"Encrypt");
462    key!(ENCRYPT_META_DATA, b"EncryptMetadata");
463    key!(ENCRYPTED_PAYLOAD, b"EncryptedPayload");
464    key!(END_OF_BLOCK, b"EndOfBlock");
465    key!(END_OF_LINE, b"EndOfLine");
466    key!(ENTRUST_PPKEF, b"Entrust.PPKEF");
467    key!(EXCLUSION, b"Exclusion");
468    key!(EXTENSIONS, b"Extensions");
469    key!(EXTENSION_LEVEL, b"ExtensionLevel");
470    key!(EX_DATA, b"ExData");
471    key!(EXPORT, b"Export");
472    key!(EXPORT_STATE, b"ExportState");
473    key!(EXT_G_STATE, b"ExtGState");
474    key!(EXTEND, b"Extend");
475    key!(EXTENDS, b"Extends");
476
477    // F
478    key!(F, b"F");
479    key!(F_DECODE_PARMS, b"FDecodeParms");
480    key!(F_FILTER, b"FFilter");
481    key!(FB, b"FB");
482    key!(FDF, b"FDF");
483    key!(FF, b"Ff");
484    key!(FIELDS, b"Fields");
485    key!(FILESPEC, b"Filespec");
486    key!(FILTER, b"Filter");
487    key!(FIRST, b"First");
488    key!(FIRST_CHAR, b"FirstChar");
489    key!(FIT_WINDOW, b"FitWindow");
490    key!(FL, b"FL");
491    key!(FLAGS, b"Flags");
492    key!(FLATE_DECODE, b"FlateDecode");
493    key!(FLATE_DECODE_ABBREVIATION, b"Fl");
494    key!(FO, b"Fo");
495    key!(FOLDERS, b"Folders");
496    key!(FONT, b"Font");
497    key!(FONT_BBOX, b"FontBBox");
498    key!(FONT_DESC, b"FontDescriptor");
499    key!(FONT_FAMILY, b"FontFamily");
500    key!(FONT_FILE, b"FontFile");
501    key!(FONT_FILE2, b"FontFile2");
502    key!(FONT_FILE3, b"FontFile3");
503    key!(FONT_MATRIX, b"FontMatrix");
504    key!(FONT_NAME, b"FontName");
505    key!(FONT_STRETCH, b"FontStretch");
506    key!(FONT_WEIGHT, b"FontWeight");
507    key!(FORM, b"Form");
508    key!(FORMTYPE, b"FormType");
509    key!(FRM, b"FRM");
510    key!(FS, b"FS");
511    key!(FT, b"FT");
512    key!(FUNCTION, b"Function");
513    key!(FUNCTION_TYPE, b"FunctionType");
514    key!(FUNCTIONS, b"Functions");
515
516    // G
517    key!(G, b"G");
518    key!(GAMMA, b"Gamma");
519    key!(GROUP, b"Group");
520    key!(GTS_PDFA1, b"GTS_PDFA1");
521
522    // H
523    key!(H, b"H");
524    key!(HARD_LIGHT, b"HardLight");
525    key!(HEIGHT, b"Height");
526    key!(HELV, b"Helv");
527    key!(HIDE_MENUBAR, b"HideMenubar");
528    key!(HIDE_TOOLBAR, b"HideToolbar");
529    key!(HIDE_WINDOWUI, b"HideWindowUI");
530    key!(HUE, b"Hue");
531
532    // I
533    key!(I, b"I");
534    key!(IC, b"IC");
535    key!(ICC_BASED, b"ICCBased");
536    key!(ID, b"ID");
537    key!(ID_TREE, b"IDTree");
538    key!(IDENTITY, b"Identity");
539    key!(IDENTITY_H, b"Identity-H");
540    key!(IDENTITY_V, b"Identity-V");
541    key!(IF, b"IF");
542    key!(ILLUSTRATOR, b"Illustrator");
543    key!(IM, b"IM");
544    key!(IMAGE, b"Image");
545    key!(IMAGE_MASK, b"ImageMask");
546    key!(INDEX, b"Index");
547    key!(INDEXED, b"Indexed");
548    key!(INFO, b"Info");
549    key!(INKLIST, b"InkList");
550    key!(INTENT, b"Intent");
551    key!(INTERPOLATE, b"Interpolate");
552    key!(IRT, b"IRT");
553    key!(IT, b"IT");
554    key!(ITALIC_ANGLE, b"ItalicAngle");
555    key!(ISSUER, b"Issuer");
556    key!(IX, b"IX");
557
558    // J
559    key!(JAVA_SCRIPT, b"JavaScript");
560    key!(JBIG2_DECODE, b"JBIG2Decode");
561    key!(JBIG2_GLOBALS, b"JBIG2Globals");
562    key!(JPX_DECODE, b"JPXDecode");
563    key!(JS, b"JS");
564
565    // K
566    key!(K, b"K");
567    key!(KEYWORDS, b"Keywords");
568    key!(KEY_USAGE, b"KeyUsage");
569    key!(KIDS, b"Kids");
570
571    // L
572    key!(L, b"L");
573    key!(LAB, b"Lab");
574    key!(LANG, b"Lang");
575    key!(LAST, b"Last");
576    key!(LAST_CHAR, b"LastChar");
577    key!(LAST_MODIFIED, b"LastModified");
578    key!(LC, b"LC");
579    key!(LE, b"LE");
580    key!(LEADING, b"Leading");
581    key!(LEGAL_ATTESTATION, b"LegalAttestation");
582    key!(LENGTH, b"Length");
583    key!(LENGTH1, b"Length1");
584    key!(LENGTH2, b"Length2");
585    key!(LENGTH3, b"Length3");
586    key!(LIGHTEN, b"Lighten");
587    key!(LIMITS, b"Limits");
588    key!(LINEARIZED, b"Linearized");
589    key!(LJ, b"LJ");
590    key!(LL, b"LL");
591    key!(LLE, b"LLE");
592    key!(LLO, b"LLO");
593    key!(LOCATION, b"Location");
594    key!(LUMINOSITY, b"Luminosity");
595    key!(LW, b"LW");
596    key!(LZW_DECODE, b"LZWDecode");
597    key!(LZW_DECODE_ABBREVIATION, b"LZW");
598
599    // M
600    key!(M, b"M");
601    key!(MAC, b"Mac");
602    key!(MAC_EXPERT_ENCODING, b"MacExpertEncoding");
603    key!(MAC_ROMAN_ENCODING, b"MacRomanEncoding");
604    key!(MARK_INFO, b"MarkInfo");
605    key!(MASK, b"Mask");
606    key!(MATRIX, b"Matrix");
607    key!(MATTE, b"Matte");
608    key!(MAX_LEN, b"MaxLen");
609    key!(MAX_WIDTH, b"MaxWidth");
610    key!(MCID, b"MCID");
611    key!(MDP, b"MDP");
612    key!(MEDIA_BOX, b"MediaBox");
613    key!(MEASURE, b"Measure");
614    key!(METADATA, b"Metadata");
615    key!(MISSING_WIDTH, b"MissingWidth");
616    key!(MIX, b"Mix");
617    key!(MK, b"MK");
618    key!(ML, b"ML");
619    key!(MM_TYPE1, b"MMType1");
620    key!(MOD_DATE, b"ModDate");
621    key!(MULTIPLY, b"Multiply");
622
623    // N
624    key!(N, b"N");
625    key!(NAME, b"Name");
626    key!(NAMES, b"Names");
627    key!(NAVIGATOR, b"Navigator");
628    key!(NEED_APPEARANCES, b"NeedAppearances");
629    key!(NEW_WINDOW, b"NewWindow");
630    key!(NEXT, b"Next");
631    key!(NM, b"NM");
632    key!(NON_EFONT_NO_WARN, b"NonEFontNoWarn");
633    key!(NON_FULL_SCREEN_PAGE_MODE, b"NonFullScreenPageMode");
634    key!(NONE, b"None");
635    key!(NORMAL, b"Normal");
636    key!(NUMS, b"Nums");
637
638    // O
639    key!(O, b"O");
640    key!(OBJ, b"Obj");
641    key!(OBJR, b"OBJR");
642    key!(OBJ_STM, b"ObjStm");
643    key!(OC, b"OC");
644    key!(OCG, b"OCG");
645    key!(OCGS, b"OCGs");
646    key!(OCMD, b"OCMD");
647    key!(OCPROPERTIES, b"OCProperties");
648    key!(OCSP, b"OCSP");
649    key!(OCSPS, b"OCSPs");
650    key!(OE, b"OE");
651    key!(OID, b"OID");
652    key!(OFF, b"OFF");
653    key!(ON, b"ON");
654    key!(OP, b"OP");
655    key!(OP_NS, b"op");
656    key!(OPEN_ACTION, b"OpenAction");
657    key!(OPEN_TYPE, b"OpenType");
658    key!(OPI, b"OPI");
659    key!(OPM, b"OPM");
660    key!(OPT, b"Opt");
661    key!(ORDER, b"Order");
662    key!(ORDERING, b"Ordering");
663    key!(OS, b"OS");
664    key!(OUTLINES, b"Outlines");
665    key!(OUTPUT_CONDITION, b"OutputCondition");
666    key!(OUTPUT_CONDITION_IDENTIFIER, b"OutputConditionIdentifier");
667    key!(OUTPUT_INTENT, b"OutputIntent");
668    key!(OUTPUT_INTENTS, b"OutputIntents");
669    key!(OVERLAY, b"Overlay");
670
671    // P
672    key!(P, b"P");
673    key!(PA, b"PA");
674    key!(PAGE, b"Page");
675    key!(PAGE_LABELS, b"PageLabels");
676    key!(PAGE_LAYOUT, b"PageLayout");
677    key!(PAGE_MODE, b"PageMode");
678    key!(PAGES, b"Pages");
679    key!(PAINT_TYPE, b"PaintType");
680    key!(PANOSE, b"Panose");
681    key!(PARAMS, b"Params");
682    key!(PARENT, b"Parent");
683    key!(PARENT_TREE, b"ParentTree");
684    key!(PARENT_TREE_NEXT_KEY, b"ParentTreeNextKey");
685    key!(PART, b"Part");
686    key!(PATH, b"Path");
687    key!(PATTERN, b"Pattern");
688    key!(PATTERN_TYPE, b"PatternType");
689    key!(PC, b"PC");
690    key!(PDF_DOC_ENCODING, b"PDFDocEncoding");
691    key!(PERMS, b"Perms");
692    key!(PERCEPTUAL, b"Perceptual");
693    key!(PIECE_INFO, b"PieceInfo");
694    key!(PG, b"Pg");
695    key!(PI, b"PI");
696    key!(PO, b"PO");
697    key!(POPUP, b"Popup");
698    key!(PRE_RELEASE, b"PreRelease");
699    key!(PREDICTOR, b"Predictor");
700    key!(PREV, b"Prev");
701    key!(PRINT, b"Print");
702    key!(PRINT_AREA, b"PrintArea");
703    key!(PRINT_CLIP, b"PrintClip");
704    key!(PRINT_SCALING, b"PrintScaling");
705    key!(PRINT_STATE, b"PrintState");
706    key!(PRIVATE, b"Private");
707    key!(PROC_SET, b"ProcSet");
708    key!(PROCESS, b"Process");
709    key!(PRODUCER, b"Producer");
710    key!(PROP_BUILD, b"Prop_Build");
711    key!(PROPERTIES, b"Properties");
712    key!(PS, b"PS");
713    key!(PT_DATA, b"PtData");
714    key!(PUB_SEC, b"PubSec");
715    key!(PV, b"PV");
716
717    // Q
718    key!(Q, b"Q");
719    key!(QUADPOINTS, b"QuadPoints");
720
721    // R
722    key!(R, b"R");
723    key!(RANGE, b"Range");
724    key!(RC, b"RC");
725    key!(RD, b"RD");
726    key!(REASON, b"Reason");
727    key!(REASONS, b"Reasons");
728    key!(RECIPIENTS, b"Recipients");
729    key!(RECT, b"Rect");
730    key!(REF, b"Ref");
731    key!(REFERENCE, b"Reference");
732    key!(REGISTRY, b"Registry");
733    key!(REGISTRY_NAME, b"RegistryName");
734    key!(RELATIVE_COLORIMETRIC, b"RelativeColorimetric");
735    key!(RENAME, b"Rename");
736    key!(REPEAT, b"Repeat");
737    key!(RES_FORK, b"ResFork");
738    key!(RESOURCES, b"Resources");
739    key!(RGB, b"RGB");
740    key!(RI, b"RI");
741    key!(ROLE_MAP, b"RoleMap");
742    key!(ROOT, b"Root");
743    key!(ROTATE, b"Rotate");
744    key!(ROWS, b"Rows");
745    key!(RT, b"RT");
746    key!(RUN_LENGTH_DECODE, b"RunLengthDecode");
747    key!(RUN_LENGTH_DECODE_ABBREVIATION, b"RL");
748    key!(RV, b"RV");
749
750    // S
751    key!(S, b"S");
752    key!(SA, b"SA");
753    key!(SATURATION, b"Saturation");
754    key!(SCHEMA, b"Schema");
755    key!(SCREEN, b"Screen");
756    key!(SE, b"SE");
757    key!(SEPARATION, b"Separation");
758    key!(SET_F, b"SetF");
759    key!(SET_FF, b"SetFf");
760    key!(SHADING, b"Shading");
761    key!(SHADING_TYPE, b"ShadingType");
762    key!(SIG, b"Sig");
763    key!(SIG_FLAGS, b"SigFlags");
764    key!(SIG_REF, b"SigRef");
765    key!(SIZE, b"Size");
766    key!(SM, b"SM");
767    key!(SMASK, b"SMask");
768    key!(SMASK_IN_DATA, b"SMaskInData");
769    key!(SOFT_LIGHT, b"SoftLight");
770    key!(SORT, b"Sort");
771    key!(SOUND, b"Sound");
772    key!(SPLIT, b"Split");
773    key!(SS, b"SS");
774    key!(ST, b"St");
775    key!(STANDARD_ENCODING, b"StandardEncoding");
776    key!(STATE, b"State");
777    key!(STATE_MODEL, b"StateModel");
778    key!(STATUS, b"Status");
779    key!(STD_CF, b"StdCF");
780    key!(STEM_H, b"StemH");
781    key!(STEM_V, b"StemV");
782    key!(STM_F, b"StmF");
783    key!(STR_F, b"StrF");
784    key!(STRUCT_ELEM, b"StructElem");
785    key!(STRUCT_PARENT, b"StructParent");
786    key!(STRUCT_PARENTS, b"StructParents");
787    key!(STRUCT_TREE_ROOT, b"StructTreeRoot");
788    key!(STYLE, b"Style");
789    key!(SUB_FILTER, b"SubFilter");
790    key!(SUBJ, b"Subj");
791    key!(SUBJECT, b"Subject");
792    key!(SUBJECT_DN, b"SubjectDN");
793    key!(SUBTYPE, b"Subtype");
794    key!(SUPPLEMENT, b"Supplement");
795    key!(SV, b"SV");
796    key!(SV_CERT, b"SVCert");
797    key!(SW, b"SW");
798    key!(SY, b"Sy");
799    key!(SYNCHRONOUS, b"Synchronous");
800    key!(T, b"T");
801    key!(TARGET, b"Target");
802    key!(TEMPLATES, b"Templates");
803    key!(THREAD, b"Thread");
804    key!(THREADS, b"Threads");
805    key!(THREE_DD, b"3DD");
806    key!(THUMB, b"Thumb");
807    key!(TI, b"TI");
808    key!(TILING_TYPE, b"TilingType");
809    key!(TIME_STAMP, b"TimeStamp");
810    key!(TITLE, b"Title");
811    key!(TK, b"TK");
812    key!(TM, b"TM");
813    key!(TO_UNICODE, b"ToUnicode");
814    key!(TR, b"TR");
815    key!(TR2, b"TR2");
816    key!(TRAPPED, b"Trapped");
817    key!(TRANS, b"Trans");
818    key!(TRANSFORM_METHOD, b"TransformMethod");
819    key!(TRANSFORM_PARAMS, b"TransformParams");
820    key!(TRANSPARENCY, b"Transparency");
821    key!(TREF, b"TRef");
822    key!(TRIM_BOX, b"TrimBox");
823    key!(TRUE_TYPE, b"TrueType");
824    key!(TRUSTED_MODE, b"TrustedMode");
825    key!(TU, b"TU");
826    key!(TX, b"Tx");
827    key!(TYPE, b"Type");
828    key!(TYPE0, b"Type0");
829    key!(TYPE1, b"Type1");
830    key!(TYPE3, b"Type3");
831
832    // U
833    key!(U, b"U");
834    key!(UE, b"UE");
835    key!(UF, b"UF");
836    key!(UNCHANGED, b"Unchanged");
837    key!(UNIX, b"Unix");
838    key!(URI, b"URI");
839    key!(URL, b"URL");
840    key!(URL_TYPE, b"URLType");
841    key!(USAGE, b"Usage");
842    key!(USE_CMAP, b"UseCMap");
843    key!(USER_UNIT, b"UserUnit");
844
845    // V
846    key!(V, b"V");
847    key!(VE, b"VE");
848    key!(VERISIGN_PPKVS, b"VeriSign.PPKVS");
849    key!(VERSION, b"Version");
850    key!(VERTICES, b"Vertices");
851    key!(VERTICES_PER_ROW, b"VerticesPerRow");
852    key!(VIEW, b"View");
853    key!(VIEW_AREA, b"ViewArea");
854    key!(VIEW_CLIP, b"ViewClip");
855    key!(VIEW_STATE, b"ViewState");
856    key!(VIEWER_PREFERENCES, b"ViewerPreferences");
857    key!(VOLUME, b"Volume");
858    key!(VP, b"VP");
859    key!(VRI, b"VRI");
860
861    // W
862    key!(W, b"W");
863    key!(W2, b"W2");
864    key!(WC, b"WC");
865    key!(WHITE_POINT, b"WhitePoint");
866    key!(WIDGET, b"Widget");
867    key!(WIDTH, b"Width");
868    key!(WIDTHS, b"Widths");
869    key!(WIN, b"Win");
870    key!(WIN_ANSI_ENCODING, b"WinAnsiEncoding");
871    key!(WMODE, b"WMode");
872    key!(WP, b"WP");
873    key!(WS, b"WS");
874
875    // X
876    key!(X, b"X");
877    key!(XFA, b"XFA");
878    key!(X_STEP, b"XStep");
879    key!(XHEIGHT, b"XHeight");
880    key!(XOBJECT, b"XObject");
881    key!(XREF, b"XRef");
882    key!(XREF_STM, b"XRefStm");
883
884    // Y
885    key!(Y, b"Y");
886    key!(Y_STEP, b"YStep");
887    key!(YES, b"Yes");
888
889    // Z
890    key!(ZA_DB, b"ZaDb");
891}
892
893#[cfg(test)]
894mod tests {
895    use crate::object::Name;
896    use crate::object::Number;
897    use crate::object::dict::{Dict, InlineImageDict};
898    use crate::object::string;
899    use crate::reader::{Reader, ReaderContext};
900
901    fn dict_impl(data: &[u8]) -> Option<Dict> {
902        Reader::new(data).read_with_context::<Dict>(ReaderContext::dummy())
903    }
904
905    #[test]
906    fn empty_dict_1() {
907        let dict_data = b"<<>>";
908        let dict = dict_impl(dict_data).unwrap();
909
910        assert_eq!(dict.len(), 0);
911    }
912
913    #[test]
914    fn empty_dict_2() {
915        let dict_data = b"<<   \n >>";
916        let dict = dict_impl(dict_data).unwrap();
917
918        assert_eq!(dict.len(), 0);
919    }
920
921    #[test]
922    fn dict_1() {
923        let dict_data = b"<<  /Hi 34.0 >>";
924        let dict = dict_impl(dict_data).unwrap();
925
926        assert_eq!(dict.len(), 1);
927        assert!(dict.get::<Number>(Name::new(b"Hi")).is_some());
928    }
929
930    #[test]
931    fn dict_2() {
932        let dict_data = b"<<  /Hi \n 34.0 /Second true >>";
933        let dict = dict_impl(dict_data).unwrap();
934
935        assert_eq!(dict.len(), 2);
936        assert!(dict.get::<Number>(Name::new(b"Hi")).is_some());
937        assert!(dict.get::<bool>(Name::new(b"Second")).is_some());
938    }
939
940    #[test]
941    fn dict_with_null() {
942        let dict_data = b"<<  /Entry null /Second (Hi) >>";
943        let dict = dict_impl(dict_data).unwrap();
944
945        assert_eq!(dict.len(), 1);
946    }
947
948    #[test]
949    fn dict_complex() {
950        let data = "<< /Type /Example
951/Subtype /DictionaryExample
952/Version 0.01
953/IntegerItem 12
954/StringItem ( a string )
955/Subdictionary << /Item1 0.4
956                /Item2 true
957                /LastItem ( not ! )
958                /VeryLastItem ( OK )
959                >>
960>>";
961
962        let dict = Reader::new(data.as_bytes())
963            .read_with_context::<Dict>(ReaderContext::dummy())
964            .unwrap();
965        assert_eq!(dict.len(), 6);
966        assert!(dict.get::<Name>(Name::new(b"Type")).is_some());
967        assert!(dict.get::<Name>(Name::new(b"Subtype")).is_some());
968        assert!(dict.get::<Number>(Name::new(b"Version")).is_some());
969        assert!(dict.get::<i32>(Name::new(b"IntegerItem")).is_some());
970        assert!(
971            dict.get::<string::String>(Name::new(b"StringItem"))
972                .is_some()
973        );
974        assert!(dict.get::<Dict>(Name::new(b"Subdictionary")).is_some());
975    }
976
977    #[test]
978    fn dict_with_trailing() {
979        let dict_data = b"<<  /Hi 67.0  >>trailing data";
980        let dict = dict_impl(dict_data).unwrap();
981
982        assert_eq!(dict.len(), 1);
983    }
984
985    #[test]
986    fn dict_with_comment() {
987        let dict_data = b"<<  /Hi % A comment \n 67.0 % Another comment \n >>";
988        let dict = dict_impl(dict_data).unwrap();
989
990        assert_eq!(dict.len(), 1);
991    }
992
993    #[test]
994    fn inline_dict() {
995        let dict_data = b"/W 17 /H 17 /CS /RGB /BPC 8 /F [ /A85 /LZW ] ID ";
996
997        let dict = Reader::new(&dict_data[..])
998            .read_with_context::<InlineImageDict>(ReaderContext::dummy())
999            .unwrap();
1000
1001        assert_eq!(dict.get_dict().len(), 5);
1002    }
1003
1004    #[test]
1005    fn dict_with_escaped_name() {
1006        let dict_data = b"<< /PANTONE#20104#20C 234 >>";
1007        let dict = dict_impl(dict_data).unwrap();
1008
1009        assert!(dict.contains_key(b"PANTONE 104 C".as_ref()));
1010    }
1011}