hexapdf 0.9.3 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -0
  3. data/CONTRIBUTERS +2 -1
  4. data/VERSION +1 -1
  5. data/lib/hexapdf/cli/command.rb +9 -5
  6. data/lib/hexapdf/cli/images.rb +68 -13
  7. data/lib/hexapdf/cli/inspect.rb +201 -71
  8. data/lib/hexapdf/content/canvas.rb +1 -1
  9. data/lib/hexapdf/dictionary.rb +15 -1
  10. data/lib/hexapdf/dictionary_fields.rb +5 -4
  11. data/lib/hexapdf/document.rb +15 -6
  12. data/lib/hexapdf/encryption/security_handler.rb +3 -2
  13. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +165 -165
  14. data/lib/hexapdf/font/true_type_wrapper.rb +2 -2
  15. data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
  16. data/lib/hexapdf/image_loader/jpeg.rb +13 -11
  17. data/lib/hexapdf/reference.rb +5 -0
  18. data/lib/hexapdf/revision.rb +14 -0
  19. data/lib/hexapdf/serializer.rb +6 -6
  20. data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
  21. data/lib/hexapdf/type/image.rb +3 -1
  22. data/lib/hexapdf/version.rb +1 -1
  23. data/lib/hexapdf/xref_section.rb +8 -0
  24. data/man/man1/hexapdf.1 +88 -20
  25. data/test/data/images/truecolour-alpha-8bit.png +0 -0
  26. data/test/data/images/ycck.jpg +0 -0
  27. data/test/hexapdf/content/test_canvas.rb +2 -2
  28. data/test/hexapdf/document/test_images.rb +7 -5
  29. data/test/hexapdf/encryption/test_security_handler.rb +13 -0
  30. data/test/hexapdf/image_loader/test_jpeg.rb +10 -0
  31. data/test/hexapdf/image_loader/test_png.rb +3 -2
  32. data/test/hexapdf/test_dictionary.rb +9 -0
  33. data/test/hexapdf/test_dictionary_fields.rb +15 -0
  34. data/test/hexapdf/test_document.rb +5 -2
  35. data/test/hexapdf/test_reference.rb +4 -0
  36. data/test/hexapdf/test_revision.rb +12 -0
  37. data/test/hexapdf/test_writer.rb +5 -5
  38. data/test/hexapdf/test_xref_section.rb +11 -0
  39. data/test/hexapdf/type/test_form.rb +1 -1
  40. data/test/hexapdf/type/test_image.rb +28 -19
  41. 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, heigth: 300)
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)
@@ -284,7 +284,16 @@ module HexaPDF
284
284
 
285
285
  # Check the type of the field
286
286
  unless field.valid_object?(obj)
287
- yield("Type of field #{name} is invalid: #{obj.class}", false)
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
- @type_mapped = true
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) || !(data.kind_of?(Hash) ||
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
 
@@ -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
- # of the +type+ and +subtype+ options as well as on the 'object.type_map' and
282
- # 'object.subtype_map' global configuration options:
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 already a Class object, it is
285
- # used, otherwise the type is looked up in 'object.type_map'.
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
- klass = GlobalConfiguration.constantize('object.subtype_map', type, subtype) { klass }
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 => :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,
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