pdf_writer/files.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
use super::*;
/// Writer for a _file specification dictionary_.
///
/// This struct is created by [`Annotation::file_spec`],
/// [`Reference::file_spec`], [`MediaClip::data`], and [`Action::file_spec`].
pub struct FileSpec<'a> {
dict: Dict<'a>,
}
writer!(FileSpec: |obj| {
let mut dict = obj.dict();
dict.pair(Name(b"Type"), Name(b"Filespec"));
Self { dict }
});
impl<'a> FileSpec<'a> {
/// Write the `/FS` attribute to set the file system this entry relates to.
/// If you set the `system` argument to `Name(b"URL")`, this becomes an URL
/// specification.
pub fn file_system(&mut self, system: Name) -> &mut Self {
self.pair(Name(b"FS"), system);
self
}
/// Write the `/F` attribute to set the file path. Directories are indicated
/// by `/`, independent of the platform.
pub fn path(&mut self, path: Str) -> &mut Self {
self.pair(Name(b"F"), path);
self
}
/// Write the `/UF` attribute to set a Unicode-compatible path. Directories
/// are indicated by `/`, independent of the platform. PDF 1.7+.
pub fn unic_file(&mut self, path: TextStr) -> &mut Self {
self.pair(Name(b"UF"), path);
self
}
/// Write the `/V` attribute to indicate whether _not_ to cache the file.
pub fn volatile(&mut self, dont_cache: bool) -> &mut Self {
self.pair(Name(b"V"), dont_cache);
self
}
/// Write the `/Desc` attribute to set a file description. PDF 1.6+.
pub fn description(&mut self, desc: TextStr) -> &mut Self {
self.pair(Name(b"Desc"), desc);
self
}
/// Write the `/EF` attribute to reference an [embedded file](EmbeddedFile).
/// PDF 1.3+.
///
/// This only sets an embedded file for the `F` attribute corresponding to
/// the [`path`](Self::path) method. If you want to set the same embedded
/// file for the `UF` attribute, also call [`Self::embedded_file_with_unicode`]
/// instead.
///
/// Note that this key is forbidden in PDF/A-1 and restricted in PDF/A-2 and
/// PDF/A-4.
pub fn embedded_file(&mut self, id: Ref) -> &mut Self {
self.insert(Name(b"EF")).dict().pair(Name(b"F"), id);
self
}
/// Write the `/EF` attribute to reference an [embedded file](EmbeddedFile)
/// for the legacy and Unicode-compatible file path. PDF 1.7+.
///
/// Note that this key is forbidden in PDF/A-1 and restricted in PDF/A-2 an
/// PDF/A-4.
pub fn embedded_file_with_unicode(&mut self, id: Ref) -> &mut Self {
self.insert(Name(b"EF"))
.dict()
.pair(Name(b"F"), id)
.pair(Name(b"UF"), id);
self
}
/// How this file relates to the PDF document it is embedded in.
/// PDF/A-3 and PDF/A-4f.
pub fn association_kind(&mut self, kind: AssociationKind) -> &mut Self {
self.pair(Name(b"AFRelationship"), kind.to_name());
self
}
}
deref!('a, FileSpec<'a> => Dict<'a>, dict);
/// Writer for an _embedded file stream_.
///
/// This struct is created by [`Chunk::embedded_file`].
pub struct EmbeddedFile<'a> {
stream: Stream<'a>,
}
impl<'a> EmbeddedFile<'a> {
/// Create a new embedded file writer.
pub(crate) fn start(mut stream: Stream<'a>) -> Self {
stream.pair(Name(b"Type"), Name(b"EmbeddedFile"));
Self { stream }
}
/// Write the `/Subtype` attribute to set the file type.
///
/// This can either be a MIME type or a name prefixed by a first class PDF
/// prefix. Note that special characters must be encoded as described in
/// section 7.3.5 of the PDF 1.7 specification, e.g. `image/svg+xml` would
/// become `Name(b"image#2Fsvg+xml")`.
pub fn subtype(&mut self, subtype: Name) -> &mut Self {
self.pair(Name(b"Subtype"), subtype);
self
}
/// Start writing the `/Params` dictionary.
pub fn params(&mut self) -> EmbeddingParams<'_> {
self.insert(Name(b"Params")).start()
}
}
deref!('a, EmbeddedFile<'a> => Stream<'a>, stream);
/// Writer for an _embedded file parameter dictionary_.
///
/// This struct is created by [`EmbeddedFile::params`].
pub struct EmbeddingParams<'a> {
dict: Dict<'a>,
}
writer!(EmbeddingParams: |obj| Self { dict: obj.dict() });
impl<'a> EmbeddingParams<'a> {
/// Write the `/Size` attribute to set the uncompressed file size in bytes.
pub fn size(&mut self, size: i32) -> &mut Self {
self.pair(Name(b"Size"), size);
self
}
/// Write the `/CreationDate` attribute to set the file creation date.
pub fn creation_date(&mut self, date: Date) -> &mut Self {
self.pair(Name(b"CreationDate"), date);
self
}
/// Write the `/ModDate` attribute to set the file modification date.
pub fn modification_date(&mut self, date: Date) -> &mut Self {
self.pair(Name(b"ModDate"), date);
self
}
/// Write the `/CheckSum` attribute to set the file checksum.
///
/// The checksum shall be a 16-byte MD5 string.
pub fn checksum(&mut self, checksum: Str) -> &mut Self {
self.pair(Name(b"CheckSum"), checksum);
self
}
}
deref!('a, EmbeddingParams<'a> => Dict<'a>, dict);
/// How an embedded file relates to the PDF document it is embedded in.
/// PDF/A-3 and PDF/A-4f.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum AssociationKind {
/// The PDF document was created from this source file.
Source,
/// This file was used to derive a visual presentation in the PDF.
Data,
/// An alternative representation of this document.
Alternative,
/// Additional resources for this document.
Supplement,
/// There is no clear relationship or it is not known.
Unspecified,
}
impl AssociationKind {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::Source => Name(b"Source"),
Self::Data => Name(b"Data"),
Self::Alternative => Name(b"Alternative"),
Self::Supplement => Name(b"Supplement"),
Self::Unspecified => Name(b"Unspecified"),
}
}
}