origamindee 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +89 -0
- data/COPYING.LESSER +165 -0
- data/README.md +131 -0
- data/bin/config/pdfcop.conf.yml +236 -0
- data/bin/pdf2pdfa +87 -0
- data/bin/pdf2ruby +333 -0
- data/bin/pdfcop +476 -0
- data/bin/pdfdecompress +97 -0
- data/bin/pdfdecrypt +91 -0
- data/bin/pdfencrypt +113 -0
- data/bin/pdfexplode +223 -0
- data/bin/pdfextract +277 -0
- data/bin/pdfmetadata +143 -0
- data/bin/pdfsh +12 -0
- data/bin/shell/console.rb +128 -0
- data/bin/shell/hexdump.rb +59 -0
- data/bin/shell/irbrc +69 -0
- data/examples/README.md +34 -0
- data/examples/attachments/attachment.rb +38 -0
- data/examples/attachments/nested_document.rb +51 -0
- data/examples/encryption/encryption.rb +28 -0
- data/examples/events/events.rb +72 -0
- data/examples/flash/flash.rb +37 -0
- data/examples/flash/helloworld.swf +0 -0
- data/examples/forms/javascript.rb +54 -0
- data/examples/forms/xfa.rb +115 -0
- data/examples/javascript/hello_world.rb +22 -0
- data/examples/javascript/js_emulation.rb +54 -0
- data/examples/loop/goto.rb +32 -0
- data/examples/loop/named.rb +33 -0
- data/examples/signature/signature.rb +65 -0
- data/examples/uri/javascript.rb +56 -0
- data/examples/uri/open-uri.rb +21 -0
- data/examples/uri/submitform.rb +47 -0
- data/lib/origami/3d.rb +364 -0
- data/lib/origami/acroform.rb +321 -0
- data/lib/origami/actions.rb +318 -0
- data/lib/origami/annotations.rb +711 -0
- data/lib/origami/array.rb +242 -0
- data/lib/origami/boolean.rb +90 -0
- data/lib/origami/catalog.rb +418 -0
- data/lib/origami/collections.rb +144 -0
- data/lib/origami/compound.rb +161 -0
- data/lib/origami/destinations.rb +252 -0
- data/lib/origami/dictionary.rb +192 -0
- data/lib/origami/encryption.rb +1084 -0
- data/lib/origami/extensions/fdf.rb +347 -0
- data/lib/origami/extensions/ppklite.rb +422 -0
- data/lib/origami/filespec.rb +197 -0
- data/lib/origami/filters/ascii.rb +211 -0
- data/lib/origami/filters/ccitt/tables.rb +267 -0
- data/lib/origami/filters/ccitt.rb +357 -0
- data/lib/origami/filters/crypt.rb +38 -0
- data/lib/origami/filters/dct.rb +54 -0
- data/lib/origami/filters/flate.rb +69 -0
- data/lib/origami/filters/jbig2.rb +57 -0
- data/lib/origami/filters/jpx.rb +47 -0
- data/lib/origami/filters/lzw.rb +170 -0
- data/lib/origami/filters/predictors.rb +292 -0
- data/lib/origami/filters/runlength.rb +129 -0
- data/lib/origami/filters.rb +364 -0
- data/lib/origami/font.rb +196 -0
- data/lib/origami/functions.rb +79 -0
- data/lib/origami/graphics/colors.rb +230 -0
- data/lib/origami/graphics/instruction.rb +98 -0
- data/lib/origami/graphics/path.rb +182 -0
- data/lib/origami/graphics/patterns.rb +174 -0
- data/lib/origami/graphics/render.rb +62 -0
- data/lib/origami/graphics/state.rb +149 -0
- data/lib/origami/graphics/text.rb +225 -0
- data/lib/origami/graphics/xobject.rb +918 -0
- data/lib/origami/graphics.rb +38 -0
- data/lib/origami/header.rb +75 -0
- data/lib/origami/javascript.rb +713 -0
- data/lib/origami/linearization.rb +330 -0
- data/lib/origami/metadata.rb +172 -0
- data/lib/origami/name.rb +135 -0
- data/lib/origami/null.rb +65 -0
- data/lib/origami/numeric.rb +181 -0
- data/lib/origami/obfuscation.rb +245 -0
- data/lib/origami/object.rb +760 -0
- data/lib/origami/optionalcontent.rb +183 -0
- data/lib/origami/outline.rb +54 -0
- data/lib/origami/outputintents.rb +85 -0
- data/lib/origami/page.rb +722 -0
- data/lib/origami/parser.rb +269 -0
- data/lib/origami/parsers/fdf.rb +56 -0
- data/lib/origami/parsers/pdf/lazy.rb +176 -0
- data/lib/origami/parsers/pdf/linear.rb +122 -0
- data/lib/origami/parsers/pdf.rb +118 -0
- data/lib/origami/parsers/ppklite.rb +57 -0
- data/lib/origami/pdf.rb +1108 -0
- data/lib/origami/reference.rb +134 -0
- data/lib/origami/signature.rb +702 -0
- data/lib/origami/stream.rb +705 -0
- data/lib/origami/string.rb +444 -0
- data/lib/origami/template/patterns.rb +56 -0
- data/lib/origami/template/widgets.rb +151 -0
- data/lib/origami/trailer.rb +190 -0
- data/lib/origami/tree.rb +62 -0
- data/lib/origami/version.rb +23 -0
- data/lib/origami/webcapture.rb +100 -0
- data/lib/origami/xfa/config.rb +453 -0
- data/lib/origami/xfa/connectionset.rb +146 -0
- data/lib/origami/xfa/datasets.rb +49 -0
- data/lib/origami/xfa/localeset.rb +42 -0
- data/lib/origami/xfa/package.rb +59 -0
- data/lib/origami/xfa/pdf.rb +73 -0
- data/lib/origami/xfa/signature.rb +42 -0
- data/lib/origami/xfa/sourceset.rb +43 -0
- data/lib/origami/xfa/stylesheet.rb +44 -0
- data/lib/origami/xfa/template.rb +1691 -0
- data/lib/origami/xfa/xdc.rb +42 -0
- data/lib/origami/xfa/xfa.rb +146 -0
- data/lib/origami/xfa/xfdf.rb +43 -0
- data/lib/origami/xfa/xmpmeta.rb +43 -0
- data/lib/origami/xfa.rb +62 -0
- data/lib/origami/xreftable.rb +557 -0
- data/lib/origami.rb +47 -0
- data/test/dataset/calc.pdf +85 -0
- data/test/dataset/crypto.pdf +36 -0
- data/test/dataset/empty.pdf +49 -0
- data/test/test_actions.rb +27 -0
- data/test/test_annotations.rb +68 -0
- data/test/test_forms.rb +30 -0
- data/test/test_native_types.rb +83 -0
- data/test/test_object_tree.rb +33 -0
- data/test/test_pages.rb +60 -0
- data/test/test_pdf.rb +20 -0
- data/test/test_pdf_attachment.rb +34 -0
- data/test/test_pdf_create.rb +24 -0
- data/test/test_pdf_encrypt.rb +102 -0
- data/test/test_pdf_parse.rb +134 -0
- data/test/test_pdf_parse_lazy.rb +69 -0
- data/test/test_pdf_sign.rb +97 -0
- data/test/test_streams.rb +184 -0
- data/test/test_xrefs.rb +67 -0
- metadata +280 -0
@@ -0,0 +1,364 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
4
|
+
Copyright (C) 2016 Guillaume Delugré.
|
5
|
+
|
6
|
+
Origami is free software: you can redistribute it and/or modify
|
7
|
+
it under the terms of the GNU Lesser General Public License as published by
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
9
|
+
(at your option) any later version.
|
10
|
+
|
11
|
+
Origami is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
GNU Lesser General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the GNU Lesser General Public License
|
17
|
+
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
=end
|
20
|
+
|
21
|
+
module Origami
|
22
|
+
|
23
|
+
#
|
24
|
+
# Filters are algorithms used to encode data into a PDF Stream.
|
25
|
+
#
|
26
|
+
module Filter
|
27
|
+
|
28
|
+
autoload :ASCIIHex, "origami/filters/ascii"
|
29
|
+
autoload :AHx, "origami/filters/ascii"
|
30
|
+
autoload :ASCII85, "origami/filters/ascii"
|
31
|
+
autoload :A85, "origami/filters/ascii"
|
32
|
+
autoload :CCITTFax, "origami/filters/ccitt"
|
33
|
+
autoload :CCF, "origami/filters/ccitt"
|
34
|
+
autoload :Crypt, "origami/filters/crypt"
|
35
|
+
autoload :DCT, "origami/filters/dct"
|
36
|
+
autoload :Flate, "origami/filters/flate"
|
37
|
+
autoload :Fl, "origami/filters/flate"
|
38
|
+
autoload :JBIG2, "origami/filters/jbig2"
|
39
|
+
autoload :JPX, "origami/filters/jpx"
|
40
|
+
autoload :LZW, "origami/filters/lzw"
|
41
|
+
autoload :RunLength, "origami/filters/runlength"
|
42
|
+
autoload :RL, "origami/filters/runlength"
|
43
|
+
autoload :Predictor, "origami/filters/predictors"
|
44
|
+
|
45
|
+
|
46
|
+
#
|
47
|
+
# Base class for filter Exceptions.
|
48
|
+
#
|
49
|
+
class Error < Origami::Error
|
50
|
+
attr_accessor :input_data, :decoded_data
|
51
|
+
|
52
|
+
def initialize(message, input_data: nil, decoded_data: nil)
|
53
|
+
super(message)
|
54
|
+
|
55
|
+
@input_data, @decoded_data = input_data, decoded_data
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Exception class for unsupported filters or unsupported filter parameters.
|
61
|
+
#
|
62
|
+
class NotImplementedError < Error; end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Exception class for errors occuring during decode operations.
|
66
|
+
#
|
67
|
+
class DecodeError < Error; end
|
68
|
+
|
69
|
+
module Utils
|
70
|
+
|
71
|
+
class BitWriterError < Error #:nodoc:
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Class used to forge a String from a stream of bits.
|
76
|
+
# Internally used by some filters.
|
77
|
+
#
|
78
|
+
class BitWriter
|
79
|
+
def initialize
|
80
|
+
@data = ''.b
|
81
|
+
@last_byte = nil
|
82
|
+
@ptr_bit = 0
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# Writes _data_ represented as Fixnum to a _length_ number of bits.
|
87
|
+
#
|
88
|
+
def write(data, length)
|
89
|
+
return BitWriterError, "Invalid data length" unless length > 0 and length >= data.bit_length
|
90
|
+
|
91
|
+
# optimization for aligned byte writing
|
92
|
+
if length == 8 and @last_byte.nil? and @ptr_bit == 0
|
93
|
+
@data << data.chr
|
94
|
+
return self
|
95
|
+
end
|
96
|
+
|
97
|
+
write_bits(data, length)
|
98
|
+
|
99
|
+
self
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# Returns the data size in bits.
|
104
|
+
#
|
105
|
+
def size
|
106
|
+
(@data.size << 3) + @ptr_bit
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# Finalizes the stream.
|
111
|
+
#
|
112
|
+
def final
|
113
|
+
@data << @last_byte.chr if @last_byte
|
114
|
+
@last_byte = nil
|
115
|
+
@p = 0
|
116
|
+
|
117
|
+
self
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
# Outputs the stream as a String.
|
122
|
+
#
|
123
|
+
def to_s
|
124
|
+
@data.dup
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
#
|
130
|
+
# Write the bits into the internal data.
|
131
|
+
#
|
132
|
+
def write_bits(data, length)
|
133
|
+
|
134
|
+
while length > 0
|
135
|
+
if length >= 8 - @ptr_bit
|
136
|
+
length -= 8 - @ptr_bit
|
137
|
+
@last_byte ||= 0
|
138
|
+
@last_byte |= (data >> length) & ((1 << (8 - @ptr_bit)) - 1)
|
139
|
+
|
140
|
+
data &= (1 << length) - 1
|
141
|
+
@data << @last_byte.chr
|
142
|
+
@last_byte = nil
|
143
|
+
@ptr_bit = 0
|
144
|
+
else
|
145
|
+
@last_byte ||= 0
|
146
|
+
@last_byte |= (data & ((1 << length) - 1)) << (8 - @ptr_bit - length)
|
147
|
+
@ptr_bit += length
|
148
|
+
|
149
|
+
if @ptr_bit == 8
|
150
|
+
@data << @last_byte.chr
|
151
|
+
@last_byte = nil
|
152
|
+
@ptr_bit = 0
|
153
|
+
end
|
154
|
+
|
155
|
+
length = 0
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
class BitReaderError < Error #:nodoc:
|
162
|
+
end
|
163
|
+
|
164
|
+
#
|
165
|
+
# Class used to read a String as a stream of bits.
|
166
|
+
# Internally used by some filters.
|
167
|
+
#
|
168
|
+
class BitReader
|
169
|
+
BRUIJIN_TABLE = ::Array.new(32)
|
170
|
+
BRUIJIN_TABLE.size.times do |i|
|
171
|
+
BRUIJIN_TABLE[((0x77cb531 * (1 << i)) >> 27) & 31] = i
|
172
|
+
end
|
173
|
+
|
174
|
+
def initialize(data)
|
175
|
+
@data = data
|
176
|
+
reset
|
177
|
+
end
|
178
|
+
|
179
|
+
#
|
180
|
+
# Resets the read pointer.
|
181
|
+
#
|
182
|
+
def reset
|
183
|
+
@ptr_byte, @ptr_bit = 0, 0
|
184
|
+
self
|
185
|
+
end
|
186
|
+
|
187
|
+
#
|
188
|
+
# Returns true if end of data has been reached.
|
189
|
+
#
|
190
|
+
def eod?
|
191
|
+
@ptr_byte >= @data.size
|
192
|
+
end
|
193
|
+
|
194
|
+
#
|
195
|
+
# Returns the read pointer position in bits.
|
196
|
+
#
|
197
|
+
def pos
|
198
|
+
(@ptr_byte << 3) + @ptr_bit
|
199
|
+
end
|
200
|
+
|
201
|
+
#
|
202
|
+
# Returns the data size in bits.
|
203
|
+
#
|
204
|
+
def size
|
205
|
+
@data.size << 3
|
206
|
+
end
|
207
|
+
|
208
|
+
#
|
209
|
+
# Sets the read pointer position in bits.
|
210
|
+
#
|
211
|
+
def pos=(bits)
|
212
|
+
raise BitReaderError, "Pointer position out of data" if bits > self.size
|
213
|
+
|
214
|
+
pbyte = bits >> 3
|
215
|
+
pbit = bits - (pbyte << 3)
|
216
|
+
@ptr_byte, @ptr_bit = pbyte, pbit
|
217
|
+
end
|
218
|
+
|
219
|
+
#
|
220
|
+
# Reads _length_ bits as a Fixnum and advances read pointer.
|
221
|
+
#
|
222
|
+
def read(length)
|
223
|
+
n = self.peek(length)
|
224
|
+
self.pos += length
|
225
|
+
|
226
|
+
n
|
227
|
+
end
|
228
|
+
|
229
|
+
#
|
230
|
+
# Reads _length_ bits as a Fixnum. Does not advance read pointer.
|
231
|
+
#
|
232
|
+
def peek(length)
|
233
|
+
return BitReaderError, "Invalid read length" unless length > 0
|
234
|
+
return BitReaderError, "Insufficient data" if self.pos + length > self.size
|
235
|
+
|
236
|
+
n = 0
|
237
|
+
ptr_byte, ptr_bit = @ptr_byte, @ptr_bit
|
238
|
+
|
239
|
+
while length > 0
|
240
|
+
byte = @data[ptr_byte].ord
|
241
|
+
|
242
|
+
if length > 8 - ptr_bit
|
243
|
+
length -= 8 - ptr_bit
|
244
|
+
n |= ( byte & ((1 << (8 - ptr_bit)) - 1) ) << length
|
245
|
+
|
246
|
+
ptr_byte += 1
|
247
|
+
ptr_bit = 0
|
248
|
+
else
|
249
|
+
n |= (byte >> (8 - ptr_bit - length)) & ((1 << length) - 1)
|
250
|
+
length = 0
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
n
|
255
|
+
end
|
256
|
+
|
257
|
+
#
|
258
|
+
# Used for bit scanning.
|
259
|
+
# Counts leading zeros. Does not advance read pointer.
|
260
|
+
#
|
261
|
+
def clz
|
262
|
+
count = 0
|
263
|
+
if @ptr_bit != 0
|
264
|
+
bits = peek(8 - @ptr_bit)
|
265
|
+
count = clz32(bits << (32 - (8 - @ptr_bit)))
|
266
|
+
|
267
|
+
return count if count < (8 - @ptr_bit)
|
268
|
+
end
|
269
|
+
|
270
|
+
delta = 0
|
271
|
+
while @data.size > @ptr_byte + delta * 4
|
272
|
+
word = @data[@ptr_byte + delta * 4, 4] # next 32 bits
|
273
|
+
z = clz32((word << (4 - word.size)).unpack("N")[0])
|
274
|
+
|
275
|
+
count += z
|
276
|
+
delta += 1
|
277
|
+
|
278
|
+
return count if z < 32 - ((4 - word.size) << 3)
|
279
|
+
end
|
280
|
+
|
281
|
+
count
|
282
|
+
end
|
283
|
+
|
284
|
+
#
|
285
|
+
# Used for bit scanning.
|
286
|
+
# Count leading ones. Does not advance read pointer.
|
287
|
+
#
|
288
|
+
def clo
|
289
|
+
count = 0
|
290
|
+
if @ptr_bit != 0
|
291
|
+
bits = peek(8 - @ptr_bit)
|
292
|
+
count = clz32(~(bits << (32 - (8 - @ptr_bit))) & 0xff)
|
293
|
+
|
294
|
+
return count if count < (8 - @ptr_bit)
|
295
|
+
end
|
296
|
+
|
297
|
+
delta = 0
|
298
|
+
while @data.size > @ptr_byte + delta * 4
|
299
|
+
word = @data[@ptr_byte + delta * 4, 4] # next 32 bits
|
300
|
+
z = clz32(~((word << (4 - word.size)).unpack("N")[0]) & 0xffff_ffff)
|
301
|
+
|
302
|
+
count += z
|
303
|
+
delta += 1
|
304
|
+
|
305
|
+
return count if z < 32 - ((4 - word.size) << 3)
|
306
|
+
end
|
307
|
+
|
308
|
+
count
|
309
|
+
end
|
310
|
+
|
311
|
+
private
|
312
|
+
|
313
|
+
def bitswap8(i) #:nodoc
|
314
|
+
((i * 0x0202020202) & 0x010884422010) % 1023
|
315
|
+
end
|
316
|
+
|
317
|
+
def bitswap32(i) #:nodoc:
|
318
|
+
(bitswap8((i >> 0) & 0xff) << 24) |
|
319
|
+
(bitswap8((i >> 8) & 0xff) << 16) |
|
320
|
+
(bitswap8((i >> 16) & 0xff) << 8) |
|
321
|
+
(bitswap8((i >> 24) & 0xff) << 0)
|
322
|
+
end
|
323
|
+
|
324
|
+
def ctz32(i) #:nodoc:
|
325
|
+
if i == 0 then 32
|
326
|
+
else
|
327
|
+
BRUIJIN_TABLE[(((i & -i) * 0x77cb531) >> 27) & 31]
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
def clz32(i) #:nodoc:
|
332
|
+
ctz32 bitswap32 i
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
module ClassMethods
|
338
|
+
#
|
339
|
+
# Decodes the given data.
|
340
|
+
# _stream_:: The data to decode.
|
341
|
+
#
|
342
|
+
def decode(stream, params = {})
|
343
|
+
self.new(params).decode(stream)
|
344
|
+
end
|
345
|
+
|
346
|
+
#
|
347
|
+
# Encodes the given data.
|
348
|
+
# _stream_:: The data to encode.
|
349
|
+
#
|
350
|
+
def encode(stream, params = {})
|
351
|
+
self.new(params).encode(stream)
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
def initialize(parameters = {})
|
356
|
+
@params = parameters
|
357
|
+
end
|
358
|
+
|
359
|
+
def self.included(receiver)
|
360
|
+
receiver.extend(ClassMethods)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
end
|
data/lib/origami/font.rb
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
4
|
+
Copyright (C) 2016 Guillaume Delugré.
|
5
|
+
|
6
|
+
Origami is free software: you can redistribute it and/or modify
|
7
|
+
it under the terms of the GNU Lesser General Public License as published by
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
9
|
+
(at your option) any later version.
|
10
|
+
|
11
|
+
Origami is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
GNU Lesser General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the GNU Lesser General Public License
|
17
|
+
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
=end
|
20
|
+
|
21
|
+
module Origami
|
22
|
+
|
23
|
+
#
|
24
|
+
# Embedded font stream.
|
25
|
+
#
|
26
|
+
class FontStream < Stream
|
27
|
+
field :Subtype, :Type => Name
|
28
|
+
field :Length1, :Type => Integer
|
29
|
+
field :Length2, :Type => Integer
|
30
|
+
field :Length3, :Type => Integer
|
31
|
+
field :Metadata, :Type => MetadataStream
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Class representing a font details in a document.
|
36
|
+
#
|
37
|
+
class FontDescriptor < Dictionary
|
38
|
+
include StandardObject
|
39
|
+
|
40
|
+
FIXEDPITCH = 1 << 1
|
41
|
+
SERIF = 1 << 2
|
42
|
+
SYMBOLIC = 1 << 3
|
43
|
+
SCRIPT = 1 << 4
|
44
|
+
NONSYMBOLIC = 1 << 6
|
45
|
+
ITALIC = 1 << 7
|
46
|
+
ALLCAP = 1 << 17
|
47
|
+
SMALLCAP = 1 << 18
|
48
|
+
FORCEBOLD = 1 << 19
|
49
|
+
|
50
|
+
field :Type, :Type => Name, :Default => :FontDescriptor, :Required => true
|
51
|
+
field :FontName, :Type => Name, :Required => true
|
52
|
+
field :FontFamily, :Type => String, :Version => "1.5"
|
53
|
+
field :FontStretch, :Type => Name, :Default => :Normal, :Version => "1.5"
|
54
|
+
field :FontWeight, :Type => Integer, :Default => 400, :Version => "1.5"
|
55
|
+
field :Flags, :Type => Integer, :Required => true
|
56
|
+
field :FontBBox, :Type => Rectangle
|
57
|
+
field :ItalicAngle, :Type => Number, :Required => true
|
58
|
+
field :Ascent, :Type => Number
|
59
|
+
field :Descent, :Type => Number
|
60
|
+
field :Leading, :Type => Number, :Default => 0
|
61
|
+
field :CapHeight, :Type => Number
|
62
|
+
field :XHeight, :Type => Number, :Default => 0
|
63
|
+
field :StemV, :Type => Number
|
64
|
+
field :StemH, :Type => Number, :Default => 0
|
65
|
+
field :AvgWidth, :Type => Number, :Default => 0
|
66
|
+
field :MaxWidth, :Type => Number, :Default => 0
|
67
|
+
field :MissingWidth, :Type => Number, :Default => 0
|
68
|
+
field :FontFile, :Type => FontStream
|
69
|
+
field :FontFile2, :Type => FontStream, :Version => "1.1"
|
70
|
+
field :FontFile3, :Type => FontStream, :Version => "1.2"
|
71
|
+
field :CharSet, :Type => String, :Version => "1.1"
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Class representing a character encoding in a document.
|
76
|
+
#
|
77
|
+
class Encoding < Dictionary
|
78
|
+
include StandardObject
|
79
|
+
|
80
|
+
field :Type, :Type => Name, :Default => :Encoding
|
81
|
+
field :BaseEncoding, :Type => Name
|
82
|
+
field :Differences, :Type => Array
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# Class representing a rendering font in a document.
|
87
|
+
#
|
88
|
+
class Font < Dictionary
|
89
|
+
include StandardObject
|
90
|
+
|
91
|
+
field :Type, :Type => Name, :Default => :Font, :Required => true
|
92
|
+
field :Subtype, :Type => Name, :Required => true
|
93
|
+
field :Name, :Type => Name
|
94
|
+
field :FirstChar, :Type => Integer
|
95
|
+
field :LastChar, :Type => Integer
|
96
|
+
field :Widths, :Type => Array.of(Number)
|
97
|
+
field :FontDescriptor, :Type => FontDescriptor
|
98
|
+
field :Encoding, :Type => [ Name, Encoding ], :Default => :MacRomanEncoding
|
99
|
+
field :ToUnicode, :Type => Stream, :Version => "1.2"
|
100
|
+
|
101
|
+
# TODO: Type0 and CID Fonts
|
102
|
+
|
103
|
+
#
|
104
|
+
# Type1 Fonts.
|
105
|
+
#
|
106
|
+
class Type1 < Font
|
107
|
+
|
108
|
+
field :BaseFont, :Type => Name, :Required => true
|
109
|
+
field :Subtype, :Type => Name, :Default => :Type1, :Required => true
|
110
|
+
|
111
|
+
#
|
112
|
+
# 14 standard Type1 fonts.
|
113
|
+
#
|
114
|
+
module Standard
|
115
|
+
|
116
|
+
class TimesRoman < Type1
|
117
|
+
field :BaseFont, :Type => Name, :Default => :"Times-Roman", :Required => true
|
118
|
+
end
|
119
|
+
|
120
|
+
class Helvetica < Type1
|
121
|
+
field :BaseFont, :Type => Name, :Default => :Helvetica, :Required => true
|
122
|
+
end
|
123
|
+
|
124
|
+
class Courier < Type1
|
125
|
+
field :BaseFont, :Type => Name, :Default => :Courier, :Required => true
|
126
|
+
end
|
127
|
+
|
128
|
+
class Symbol < Type1
|
129
|
+
field :BaseFont, :Type => Name, :Default => :Symbol, :Required => true
|
130
|
+
end
|
131
|
+
|
132
|
+
class TimesBold < Type1
|
133
|
+
field :BaseFont, :Type => Name, :Default => :"Times-Bold", :Required => true
|
134
|
+
end
|
135
|
+
|
136
|
+
class HelveticaBold < Type1
|
137
|
+
field :BaseFont, :Type => Name, :Default => :"Helvetica-Bold", :Required => true
|
138
|
+
end
|
139
|
+
|
140
|
+
class CourierBold < Type1
|
141
|
+
field :BaseFont, :Type => Name, :Default => :"Courier-Bold", :Required => true
|
142
|
+
end
|
143
|
+
|
144
|
+
class ZapfDingbats < Type1
|
145
|
+
field :BaseFont, :Type => Name, :Default => :ZapfDingbats, :Required => true
|
146
|
+
end
|
147
|
+
|
148
|
+
class TimesItalic < Type1
|
149
|
+
field :BaseFont, :Type => Name, :Default => :"Times-Italic", :Required => true
|
150
|
+
end
|
151
|
+
|
152
|
+
class HelveticaOblique < Type1
|
153
|
+
field :BaseFont, :Type => Name, :Default => :"Helvetica-Oblique", :Required => true
|
154
|
+
end
|
155
|
+
|
156
|
+
class CourierOblique < Type1
|
157
|
+
field :BaseFont, :Type => Name, :Default => :"Courier-Oblique", :Required => true
|
158
|
+
end
|
159
|
+
|
160
|
+
class TimesBoldItalic < Type1
|
161
|
+
field :BaseFont, :Type => Name, :Default => :"Times-BoldItalic", :Required => true
|
162
|
+
end
|
163
|
+
|
164
|
+
class HelveticaBoldOblique < Type1
|
165
|
+
field :BaseFont, :Type => Name, :Default => :"Helvetica-BoldOblique", :Required => true
|
166
|
+
end
|
167
|
+
|
168
|
+
class CourierBoldOblique < Type1
|
169
|
+
field :BaseFont, :Type => Name, :Default => :"Courier-BoldOblique", :Required => true
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
#
|
175
|
+
# TrueType Fonts
|
176
|
+
#
|
177
|
+
class TrueType < Font
|
178
|
+
field :Subtype, :Type => Name, :Default => :TrueType, :Required => true
|
179
|
+
field :BaseFont, :Type => Name, :Required => true
|
180
|
+
end
|
181
|
+
|
182
|
+
#
|
183
|
+
# Type 3 Fonts
|
184
|
+
#
|
185
|
+
class Type3 < Font
|
186
|
+
include ResourcesHolder
|
187
|
+
|
188
|
+
field :Subtype, :Type => Name, :Default => :Type3, :Required => true
|
189
|
+
field :FontBBox, :Type => Rectangle, :Required => true
|
190
|
+
field :FontMatrix, :Type => Array.of(Number, length: 6), :Required => true
|
191
|
+
field :CharProcs, :Type => Dictionary, :Required => true
|
192
|
+
field :Resources, :Type => Resources, :Version => "1.2"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
4
|
+
Copyright (C) 2016 Guillaume Delugré.
|
5
|
+
|
6
|
+
Origami is free software: you can redistribute it and/or modify
|
7
|
+
it under the terms of the GNU Lesser General Public License as published by
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
9
|
+
(at your option) any later version.
|
10
|
+
|
11
|
+
Origami is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
GNU Lesser General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the GNU Lesser General Public License
|
17
|
+
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
=end
|
20
|
+
|
21
|
+
|
22
|
+
module Origami
|
23
|
+
|
24
|
+
module Function
|
25
|
+
|
26
|
+
module Type
|
27
|
+
SAMPLED = 0
|
28
|
+
EXPONENTIAL = 2
|
29
|
+
STITCHING = 3
|
30
|
+
POSTSCRIPT = 4
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.included(receiver)
|
34
|
+
receiver.field :FunctionType, :Type => Integer, :Required => true
|
35
|
+
receiver.field :Domain, :Type => Array.of(Number), :Required => true
|
36
|
+
receiver.field :Range, :Type => Array.of(Number)
|
37
|
+
end
|
38
|
+
|
39
|
+
class Sampled < Stream
|
40
|
+
include Function
|
41
|
+
|
42
|
+
field :FunctionType, :Type => Integer, :Default => Type::SAMPLED, :Version => "1.3", :Required => true
|
43
|
+
field :Range, :Type => Array.of(Number), :Required => true
|
44
|
+
field :Size, :Type => Array.of(Integer), :Required => true
|
45
|
+
field :BitsPerSample, :Type => Integer, :Required => true
|
46
|
+
field :Order, :Type => Integer, :Default => 1
|
47
|
+
field :Encode, :Type => Array.of(Number)
|
48
|
+
field :Decode, :Type => Array.of(Number)
|
49
|
+
end
|
50
|
+
|
51
|
+
class Exponential < Dictionary
|
52
|
+
include StandardObject
|
53
|
+
include Function
|
54
|
+
|
55
|
+
field :FunctionType, :Type => Integer, :Default => Type::EXPONENTIAL, :Version => "1.3", :Required => true
|
56
|
+
field :C0, :Type => Array.of(Number), :Default => [ 0.0 ]
|
57
|
+
field :C1, :Type => Array.of(Number), :Default => [ 1.0 ]
|
58
|
+
field :N, :Type => Number, :Required => true
|
59
|
+
end
|
60
|
+
|
61
|
+
class Stitching < Dictionary
|
62
|
+
include StandardObject
|
63
|
+
include Function
|
64
|
+
|
65
|
+
field :FunctionType, :Type => Integer, :Default => Type::STITCHING, :Version => "1.3", :Required => true
|
66
|
+
field :Functions, :Type => Array, :Required => true
|
67
|
+
field :Bounds, :Type => Array.of(Number), :Required => true
|
68
|
+
field :Encode, :Type => Array.of(Number), :Required => true
|
69
|
+
end
|
70
|
+
|
71
|
+
class PostScript < Stream
|
72
|
+
include Function
|
73
|
+
|
74
|
+
field :FunctionType, :Type => Integer, :Default => Type::POSTSCRIPT, :Version => "1.3", :Required => true
|
75
|
+
field :Range, :Type => Array.of(Number), :Required => true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|