hexapdf 0.9.3 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -0
- data/CONTRIBUTERS +2 -1
- data/VERSION +1 -1
- data/lib/hexapdf/cli/command.rb +9 -5
- data/lib/hexapdf/cli/images.rb +68 -13
- data/lib/hexapdf/cli/inspect.rb +201 -71
- data/lib/hexapdf/content/canvas.rb +1 -1
- data/lib/hexapdf/dictionary.rb +15 -1
- data/lib/hexapdf/dictionary_fields.rb +5 -4
- data/lib/hexapdf/document.rb +15 -6
- data/lib/hexapdf/encryption/security_handler.rb +3 -2
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +165 -165
- data/lib/hexapdf/font/true_type_wrapper.rb +2 -2
- data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
- data/lib/hexapdf/image_loader/jpeg.rb +13 -11
- data/lib/hexapdf/reference.rb +5 -0
- data/lib/hexapdf/revision.rb +14 -0
- data/lib/hexapdf/serializer.rb +6 -6
- data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
- data/lib/hexapdf/type/image.rb +3 -1
- data/lib/hexapdf/version.rb +1 -1
- data/lib/hexapdf/xref_section.rb +8 -0
- data/man/man1/hexapdf.1 +88 -20
- data/test/data/images/truecolour-alpha-8bit.png +0 -0
- data/test/data/images/ycck.jpg +0 -0
- data/test/hexapdf/content/test_canvas.rb +2 -2
- data/test/hexapdf/document/test_images.rb +7 -5
- data/test/hexapdf/encryption/test_security_handler.rb +13 -0
- data/test/hexapdf/image_loader/test_jpeg.rb +10 -0
- data/test/hexapdf/image_loader/test_png.rb +3 -2
- data/test/hexapdf/test_dictionary.rb +9 -0
- data/test/hexapdf/test_dictionary_fields.rb +15 -0
- data/test/hexapdf/test_document.rb +5 -2
- data/test/hexapdf/test_reference.rb +4 -0
- data/test/hexapdf/test_revision.rb +12 -0
- data/test/hexapdf/test_writer.rb +5 -5
- data/test/hexapdf/test_xref_section.rb +11 -0
- data/test/hexapdf/type/test_form.rb +1 -1
- data/test/hexapdf/type/test_image.rb +28 -19
- metadata +3 -2
@@ -1253,7 +1253,7 @@ module HexaPDF
|
|
1253
1253
|
# end
|
1254
1254
|
#
|
1255
1255
|
# image = document.object(5) # Object with oid=5 is an image XObject in this example
|
1256
|
-
# canvas.xobject(image, at: [100, 200], width: 200,
|
1256
|
+
# canvas.xobject(image, at: [100, 200], width: 200, height: 300)
|
1257
1257
|
#
|
1258
1258
|
# See: PDF1.7 s8.8, s.8.10.1
|
1259
1259
|
def xobject(obj, at:, width: nil, height: nil)
|
data/lib/hexapdf/dictionary.rb
CHANGED
@@ -284,7 +284,16 @@ module HexaPDF
|
|
284
284
|
|
285
285
|
# Check the type of the field
|
286
286
|
unless field.valid_object?(obj)
|
287
|
-
|
287
|
+
msg = "Type of field #{name} is invalid: #{obj.class}"
|
288
|
+
if field.type.include?(String) && obj.kind_of?(Symbol)
|
289
|
+
yield(msg, true)
|
290
|
+
self[name] = obj.to_s
|
291
|
+
elsif field.type.include?(Symbol) && obj.kind_of?(String)
|
292
|
+
yield(msg, true)
|
293
|
+
self[name] = obj.intern
|
294
|
+
else
|
295
|
+
yield(msg, false)
|
296
|
+
end
|
288
297
|
end
|
289
298
|
|
290
299
|
# Check if field value needs to be (in)direct
|
@@ -304,4 +313,9 @@ module HexaPDF
|
|
304
313
|
|
305
314
|
end
|
306
315
|
|
316
|
+
# :nodoc:
|
317
|
+
# Forward declaration of Stream to circumvent circular require problem
|
318
|
+
class Stream < Dictionary
|
319
|
+
end
|
320
|
+
|
307
321
|
end
|
@@ -118,8 +118,7 @@ module HexaPDF
|
|
118
118
|
# Returns the array with valid types for this field.
|
119
119
|
def type
|
120
120
|
return @type if @type_mapped
|
121
|
-
@
|
122
|
-
@type.concat(@converters.map(&:additional_types).compact.flatten)
|
121
|
+
@type.concat(@converters.flat_map(&:additional_types).compact)
|
123
122
|
@type.map! do |type|
|
124
123
|
if type.kind_of?(Symbol)
|
125
124
|
HexaPDF::GlobalConfiguration.constantize('object.type_map', type)
|
@@ -128,6 +127,7 @@ module HexaPDF
|
|
128
127
|
end
|
129
128
|
end
|
130
129
|
@type.uniq!
|
130
|
+
@type_mapped = true
|
131
131
|
@type
|
132
132
|
end
|
133
133
|
|
@@ -191,8 +191,9 @@ module HexaPDF
|
|
191
191
|
# Wraps the given data value in the PDF specific type class if it can be converted. Otherwise
|
192
192
|
# returns +nil+.
|
193
193
|
def self.convert(data, type, document)
|
194
|
-
return if data.kind_of?(type.first) ||
|
195
|
-
data.kind_of?(HexaPDF::Dictionary))
|
194
|
+
return if data.kind_of?(type.first) ||
|
195
|
+
!(data.kind_of?(Hash) || data.kind_of?(HexaPDF::Dictionary)) ||
|
196
|
+
(type.first <= HexaPDF::Stream && (data.kind_of?(Hash) || data.data.stream.nil?))
|
196
197
|
document.wrap(data, type: type.first)
|
197
198
|
end
|
198
199
|
|
data/lib/hexapdf/document.rb
CHANGED
@@ -277,17 +277,22 @@ module HexaPDF
|
|
277
277
|
# needed.
|
278
278
|
#
|
279
279
|
# The class of the returned object is always a subclass of HexaPDF::Object (or of
|
280
|
-
# HexaPDF::Stream if a +stream+ is given). Which subclass is used, depends on the values
|
281
|
-
#
|
282
|
-
#
|
280
|
+
# HexaPDF::Stream if a +stream+ is given). Which subclass is used, depends on the values of the
|
281
|
+
# +type+ and +subtype+ options as well as on the 'object.type_map' and 'object.subtype_map'
|
282
|
+
# global configuration options:
|
283
283
|
#
|
284
|
-
# * First +type+ is used to try to determine the class. If it is
|
285
|
-
#
|
284
|
+
# * First +type+ is used to try to determine the class. If it is not provided and if +obj+ is a
|
285
|
+
# hash with a :Type field, the value of this field is used instead. If the resulting object is
|
286
|
+
# already a Class object, it is used, otherwise the type is looked up in 'object.type_map'.
|
286
287
|
#
|
287
288
|
# * If +subtype+ is provided or can be determined because +obj+ is a hash with a :Subtype or :S
|
288
289
|
# field, the type and subtype together are used to look up a special subtype class in
|
289
290
|
# 'object.subtype_map'.
|
290
291
|
#
|
292
|
+
# Additionally, if there is no +type+ but a +subtype+, all required fields of the subtype
|
293
|
+
# class need to have values; otherwise the subtype class is not used. This is done to better
|
294
|
+
# prevent invalid mappings when only partial knowledge (:Type key is missing) is available.
|
295
|
+
#
|
291
296
|
# * If there is no valid class after the above steps, HexaPDF::Stream is used if a stream is
|
292
297
|
# given, HexaPDF::Dictionary if the given objecct is a hash or else HexaPDF::Object is used.
|
293
298
|
#
|
@@ -330,7 +335,11 @@ module HexaPDF
|
|
330
335
|
subtype ||= deref(data.value[:Subtype]) || deref(data.value[:S])
|
331
336
|
end
|
332
337
|
if subtype
|
333
|
-
|
338
|
+
sub_klass = GlobalConfiguration.constantize('object.subtype_map', type, subtype) { klass }
|
339
|
+
if type ||
|
340
|
+
sub_klass&.each_field&.none? {|name, field| field.required? && !data.value.key?(name) }
|
341
|
+
klass = sub_klass
|
342
|
+
end
|
334
343
|
end
|
335
344
|
|
336
345
|
klass ||= if data.stream
|
@@ -257,7 +257,7 @@ module HexaPDF
|
|
257
257
|
|
258
258
|
key = object_key(obj.oid, obj.gen, string_algorithm)
|
259
259
|
each_string_in_object(obj.value) do |str|
|
260
|
-
next if str.empty?
|
260
|
+
next if str.empty? || (obj.type == :Sig && obj[:Contents].equal?(str))
|
261
261
|
str.replace(string_algorithm.decrypt(key, str))
|
262
262
|
end
|
263
263
|
|
@@ -275,7 +275,8 @@ module HexaPDF
|
|
275
275
|
#
|
276
276
|
# See: PDF1.7 s7.6.2
|
277
277
|
def encrypt_string(str, obj)
|
278
|
-
return str if str.empty? || obj == document.trailer[:Encrypt] || obj.type == :XRef
|
278
|
+
return str if str.empty? || obj == document.trailer[:Encrypt] || obj.type == :XRef ||
|
279
|
+
(obj.type == :Sig && obj[:Contents].equal?(str))
|
279
280
|
|
280
281
|
key = object_key(obj.oid, obj.gen, string_algorithm)
|
281
282
|
string_algorithm.encrypt(key, str)
|
@@ -49,171 +49,171 @@ module HexaPDF
|
|
49
49
|
super
|
50
50
|
@encoding_name = :MacExpertEncoding
|
51
51
|
@code_to_name = {
|
52
|
-
0276
|
53
|
-
0207
|
54
|
-
0211
|
55
|
-
0047
|
56
|
-
0212
|
57
|
-
0210
|
58
|
-
0214
|
59
|
-
0141
|
60
|
-
0213
|
61
|
-
0363
|
62
|
-
0142
|
63
|
-
0256
|
64
|
-
0215
|
65
|
-
0311
|
66
|
-
0136
|
67
|
-
0143
|
68
|
-
0254
|
69
|
-
0372
|
70
|
-
0144
|
71
|
-
0216
|
72
|
-
0220
|
73
|
-
0221
|
74
|
-
0217
|
75
|
-
0145
|
76
|
-
0104
|
77
|
-
0146
|
78
|
-
0140
|
79
|
-
0147
|
80
|
-
0150
|
81
|
-
0042
|
82
|
-
0222
|
83
|
-
0224
|
84
|
-
0225
|
85
|
-
0223
|
86
|
-
0151
|
87
|
-
0152
|
88
|
-
0153
|
89
|
-
0302
|
90
|
-
0154
|
91
|
-
0364
|
92
|
-
0155
|
93
|
-
0156
|
94
|
-
0226
|
95
|
-
0317
|
96
|
-
0227
|
97
|
-
0231
|
98
|
-
0232
|
99
|
-
0362
|
100
|
-
0230
|
101
|
-
0277
|
102
|
-
0157
|
103
|
-
0233
|
104
|
-
0160
|
105
|
-
0161
|
106
|
-
0373
|
107
|
-
0162
|
108
|
-
0247
|
109
|
-
0163
|
110
|
-
0271
|
111
|
-
0176
|
112
|
-
0164
|
113
|
-
0234
|
114
|
-
0236
|
115
|
-
0237
|
116
|
-
0235
|
117
|
-
0165
|
118
|
-
0166
|
119
|
-
0167
|
120
|
-
0170
|
121
|
-
0264
|
122
|
-
0330
|
123
|
-
0171
|
124
|
-
0275
|
125
|
-
0172
|
126
|
-
0046
|
127
|
-
0201
|
128
|
-
0365
|
129
|
-
0251
|
130
|
-
0043
|
131
|
-
0202
|
132
|
-
0072
|
133
|
-
0173
|
134
|
-
0054
|
135
|
-
0262
|
136
|
-
0370
|
137
|
-
0266
|
138
|
-
0044
|
139
|
-
0045
|
140
|
-
0353
|
141
|
-
0245
|
142
|
-
0070
|
143
|
-
0241
|
144
|
-
0344
|
145
|
-
0326
|
146
|
-
0041
|
147
|
-
0126
|
148
|
-
0131
|
149
|
-
0132
|
150
|
-
0127
|
151
|
-
0320
|
152
|
-
0114
|
153
|
-
0260
|
154
|
-
0065
|
155
|
-
0336
|
156
|
-
0130
|
157
|
-
0242
|
158
|
-
0064
|
159
|
-
0335
|
160
|
-
0057
|
161
|
-
0055
|
162
|
-
0137
|
163
|
-
0321
|
164
|
-
0351
|
165
|
-
0361
|
166
|
-
0367
|
167
|
-
0273
|
168
|
-
0071
|
169
|
-
0341
|
170
|
-
0366
|
171
|
-
0053
|
172
|
-
0112
|
173
|
-
0174
|
174
|
-
0110
|
175
|
-
0301
|
176
|
-
0061
|
177
|
-
0107
|
178
|
-
0332
|
179
|
-
0116
|
180
|
-
0257
|
181
|
-
0133
|
182
|
-
0050
|
183
|
-
0135
|
184
|
-
0051
|
185
|
-
0056
|
186
|
-
0263
|
187
|
-
0371
|
188
|
-
0300
|
189
|
-
0077
|
190
|
-
0345
|
191
|
-
0175
|
192
|
-
0073
|
193
|
-
0115
|
194
|
-
0246
|
195
|
-
0067
|
196
|
-
0340
|
197
|
-
0244
|
198
|
-
0066
|
199
|
-
0337
|
200
|
-
0040
|
201
|
-
0352
|
202
|
-
0113
|
203
|
-
0243
|
204
|
-
0063
|
205
|
-
0111
|
206
|
-
0075
|
207
|
-
0334
|
208
|
-
0346
|
209
|
-
0052
|
210
|
-
0252
|
211
|
-
0062
|
212
|
-
0333
|
213
|
-
0117
|
214
|
-
0274
|
215
|
-
0060
|
216
|
-
0342
|
52
|
+
0276 => :AEsmall,
|
53
|
+
0207 => :Aacutesmall,
|
54
|
+
0211 => :Acircumflexsmall,
|
55
|
+
0047 => :Acutesmall,
|
56
|
+
0212 => :Adieresissmall,
|
57
|
+
0210 => :Agravesmall,
|
58
|
+
0214 => :Aringsmall,
|
59
|
+
0141 => :Asmall,
|
60
|
+
0213 => :Atildesmall,
|
61
|
+
0363 => :Brevesmall,
|
62
|
+
0142 => :Bsmall,
|
63
|
+
0256 => :Caronsmall,
|
64
|
+
0215 => :Ccedillasmall,
|
65
|
+
0311 => :Cedillasmall,
|
66
|
+
0136 => :Circumflexsmall,
|
67
|
+
0143 => :Csmall,
|
68
|
+
0254 => :Dieresissmall,
|
69
|
+
0372 => :Dotaccentsmall,
|
70
|
+
0144 => :Dsmall,
|
71
|
+
0216 => :Eacutesmall,
|
72
|
+
0220 => :Ecircumflexsmall,
|
73
|
+
0221 => :Edieresissmall,
|
74
|
+
0217 => :Egravesmall,
|
75
|
+
0145 => :Esmall,
|
76
|
+
0104 => :Ethsmall,
|
77
|
+
0146 => :Fsmall,
|
78
|
+
0140 => :Gravesmall,
|
79
|
+
0147 => :Gsmall,
|
80
|
+
0150 => :Hsmall,
|
81
|
+
0042 => :Hungarumlautsmall,
|
82
|
+
0222 => :Iacutesmall,
|
83
|
+
0224 => :Icircumflexsmall,
|
84
|
+
0225 => :Idieresissmall,
|
85
|
+
0223 => :Igravesmall,
|
86
|
+
0151 => :Ismall,
|
87
|
+
0152 => :Jsmall,
|
88
|
+
0153 => :Ksmall,
|
89
|
+
0302 => :Lslashsmall,
|
90
|
+
0154 => :Lsmall,
|
91
|
+
0364 => :Macronsmall,
|
92
|
+
0155 => :Msmall,
|
93
|
+
0156 => :Nsmall,
|
94
|
+
0226 => :Ntildesmall,
|
95
|
+
0317 => :OEsmall,
|
96
|
+
0227 => :Oacutesmall,
|
97
|
+
0231 => :Ocircumflexsmall,
|
98
|
+
0232 => :Odieresissmall,
|
99
|
+
0362 => :Ogoneksmall,
|
100
|
+
0230 => :Ogravesmall,
|
101
|
+
0277 => :Oslashsmall,
|
102
|
+
0157 => :Osmall,
|
103
|
+
0233 => :Otildesmall,
|
104
|
+
0160 => :Psmall,
|
105
|
+
0161 => :Qsmall,
|
106
|
+
0373 => :Ringsmall,
|
107
|
+
0162 => :Rsmall,
|
108
|
+
0247 => :Scaronsmall,
|
109
|
+
0163 => :Ssmall,
|
110
|
+
0271 => :Thornsmall,
|
111
|
+
0176 => :Tildesmall,
|
112
|
+
0164 => :Tsmall,
|
113
|
+
0234 => :Uacutesmall,
|
114
|
+
0236 => :Ucircumflexsmall,
|
115
|
+
0237 => :Udieresissmall,
|
116
|
+
0235 => :Ugravesmall,
|
117
|
+
0165 => :Usmall,
|
118
|
+
0166 => :Vsmall,
|
119
|
+
0167 => :Wsmall,
|
120
|
+
0170 => :Xsmall,
|
121
|
+
0264 => :Yacutesmall,
|
122
|
+
0330 => :Ydieresissmall,
|
123
|
+
0171 => :Ysmall,
|
124
|
+
0275 => :Zcaronsmall,
|
125
|
+
0172 => :Zsmall,
|
126
|
+
0046 => :ampersandsmall,
|
127
|
+
0201 => :asuperior,
|
128
|
+
0365 => :bsuperior,
|
129
|
+
0251 => :centinferior,
|
130
|
+
0043 => :centoldstyle,
|
131
|
+
0202 => :centsuperior,
|
132
|
+
0072 => :colon,
|
133
|
+
0173 => :colonmonetary,
|
134
|
+
0054 => :comma,
|
135
|
+
0262 => :commainferior,
|
136
|
+
0370 => :commasuperior,
|
137
|
+
0266 => :dollarinferior,
|
138
|
+
0044 => :dollaroldstyle,
|
139
|
+
0045 => :dollarsuperior,
|
140
|
+
0353 => :dsuperior,
|
141
|
+
0245 => :eightinferior,
|
142
|
+
0070 => :eightoldstyle,
|
143
|
+
0241 => :eightsuperior,
|
144
|
+
0344 => :esuperior,
|
145
|
+
0326 => :exclamdownsmall,
|
146
|
+
0041 => :exclamsmall,
|
147
|
+
0126 => :ff,
|
148
|
+
0131 => :ffi,
|
149
|
+
0132 => :ffl,
|
150
|
+
0127 => :fi,
|
151
|
+
0320 => :figuredash,
|
152
|
+
0114 => :fiveeighths,
|
153
|
+
0260 => :fiveinferior,
|
154
|
+
0065 => :fiveoldstyle,
|
155
|
+
0336 => :fivesuperior,
|
156
|
+
0130 => :fl,
|
157
|
+
0242 => :fourinferior,
|
158
|
+
0064 => :fouroldstyle,
|
159
|
+
0335 => :foursuperior,
|
160
|
+
0057 => :fraction,
|
161
|
+
0055 => :hyphen,
|
162
|
+
0137 => :hypheninferior,
|
163
|
+
0321 => :hyphensuperior,
|
164
|
+
0351 => :isuperior,
|
165
|
+
0361 => :lsuperior,
|
166
|
+
0367 => :msuperior,
|
167
|
+
0273 => :nineinferior,
|
168
|
+
0071 => :nineoldstyle,
|
169
|
+
0341 => :ninesuperior,
|
170
|
+
0366 => :nsuperior,
|
171
|
+
0053 => :onedotenleader,
|
172
|
+
0112 => :oneeighth,
|
173
|
+
0174 => :onefitted,
|
174
|
+
0110 => :onehalf,
|
175
|
+
0301 => :oneinferior,
|
176
|
+
0061 => :oneoldstyle,
|
177
|
+
0107 => :onequarter,
|
178
|
+
0332 => :onesuperior,
|
179
|
+
0116 => :onethird,
|
180
|
+
0257 => :osuperior,
|
181
|
+
0133 => :parenleftinferior,
|
182
|
+
0050 => :parenleftsuperior,
|
183
|
+
0135 => :parenrightinferior,
|
184
|
+
0051 => :parenrightsuperior,
|
185
|
+
0056 => :period,
|
186
|
+
0263 => :periodinferior,
|
187
|
+
0371 => :periodsuperior,
|
188
|
+
0300 => :questiondownsmall,
|
189
|
+
0077 => :questionsmall,
|
190
|
+
0345 => :rsuperior,
|
191
|
+
0175 => :rupiah,
|
192
|
+
0073 => :semicolon,
|
193
|
+
0115 => :seveneighths,
|
194
|
+
0246 => :seveninferior,
|
195
|
+
0067 => :sevenoldstyle,
|
196
|
+
0340 => :sevensuperior,
|
197
|
+
0244 => :sixinferior,
|
198
|
+
0066 => :sixoldstyle,
|
199
|
+
0337 => :sixsuperior,
|
200
|
+
0040 => :space,
|
201
|
+
0352 => :ssuperior,
|
202
|
+
0113 => :threeeighths,
|
203
|
+
0243 => :threeinferior,
|
204
|
+
0063 => :threeoldstyle,
|
205
|
+
0111 => :threequarters,
|
206
|
+
0075 => :threequartersemdash,
|
207
|
+
0334 => :threesuperior,
|
208
|
+
0346 => :tsuperior,
|
209
|
+
0052 => :twodotenleader,
|
210
|
+
0252 => :twoinferior,
|
211
|
+
0062 => :twooldstyle,
|
212
|
+
0333 => :twosuperior,
|
213
|
+
0117 => :twothirds,
|
214
|
+
0274 => :zeroinferior,
|
215
|
+
0060 => :zerooldstyle,
|
216
|
+
0342 => :zerosuperior,
|
217
217
|
}
|
218
218
|
end
|
219
219
|
|