hexapdf 0.46.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +83 -16
  3. data/lib/hexapdf/composer.rb +7 -0
  4. data/lib/hexapdf/configuration.rb +13 -0
  5. data/lib/hexapdf/content/parser.rb +3 -1
  6. data/lib/hexapdf/digital_signature/cms_handler.rb +13 -0
  7. data/lib/hexapdf/digital_signature/signature.rb +1 -1
  8. data/lib/hexapdf/digital_signature/signing/default_handler.rb +1 -0
  9. data/lib/hexapdf/document.rb +14 -3
  10. data/lib/hexapdf/encryption/standard_security_handler.rb +32 -26
  11. data/lib/hexapdf/font/cmap/writer.rb +58 -4
  12. data/lib/hexapdf/font/cmap.rb +7 -0
  13. data/lib/hexapdf/font/true_type_wrapper.rb +41 -16
  14. data/lib/hexapdf/importer.rb +1 -1
  15. data/lib/hexapdf/layout/table_box.rb +57 -10
  16. data/lib/hexapdf/layout/text_fragment.rb +2 -1
  17. data/lib/hexapdf/object.rb +1 -1
  18. data/lib/hexapdf/parser.rb +1 -1
  19. data/lib/hexapdf/reference.rb +1 -1
  20. data/lib/hexapdf/task/merge_acro_form.rb +164 -0
  21. data/lib/hexapdf/task/optimize.rb +4 -4
  22. data/lib/hexapdf/task.rb +1 -0
  23. data/lib/hexapdf/tokenizer.rb +2 -0
  24. data/lib/hexapdf/type/acro_form/appearance_generator.rb +8 -4
  25. data/lib/hexapdf/type/acro_form/form.rb +14 -24
  26. data/lib/hexapdf/type/acro_form/signature_field.rb +18 -7
  27. data/lib/hexapdf/type/acro_form/variable_text_field.rb +12 -4
  28. data/lib/hexapdf/type/actions/go_to.rb +1 -0
  29. data/lib/hexapdf/type/actions/go_to_r.rb +1 -0
  30. data/lib/hexapdf/type/actions/launch.rb +5 -1
  31. data/lib/hexapdf/type/annotation.rb +6 -1
  32. data/lib/hexapdf/type/annotations/markup_annotation.rb +14 -1
  33. data/lib/hexapdf/type/annotations/widget.rb +4 -2
  34. data/lib/hexapdf/type/catalog.rb +3 -0
  35. data/lib/hexapdf/type/cid_font.rb +4 -1
  36. data/lib/hexapdf/type/file_specification.rb +17 -14
  37. data/lib/hexapdf/type/font_descriptor.rb +4 -3
  38. data/lib/hexapdf/type/font_simple.rb +3 -1
  39. data/lib/hexapdf/type/font_true_type.rb +2 -0
  40. data/lib/hexapdf/type/font_type0.rb +1 -1
  41. data/lib/hexapdf/type/font_type1.rb +7 -0
  42. data/lib/hexapdf/type/font_type3.rb +0 -1
  43. data/lib/hexapdf/type/form.rb +5 -2
  44. data/lib/hexapdf/type/graphics_state_parameter.rb +7 -4
  45. data/lib/hexapdf/type/image.rb +8 -4
  46. data/lib/hexapdf/type/info.rb +2 -2
  47. data/lib/hexapdf/type/mark_information.rb +2 -2
  48. data/lib/hexapdf/type/optional_content_configuration.rb +1 -1
  49. data/lib/hexapdf/type/optional_content_membership.rb +1 -1
  50. data/lib/hexapdf/type/page.rb +5 -3
  51. data/lib/hexapdf/type/resources.rb +6 -6
  52. data/lib/hexapdf/type/viewer_preferences.rb +4 -3
  53. data/lib/hexapdf/version.rb +1 -1
  54. data/lib/hexapdf/writer.rb +1 -0
  55. data/test/data/standard-security-handler/bothpwd-aes-256bit-V5-R5.pdf +43 -0
  56. data/test/data/standard-security-handler/nopwd-aes-256bit-V5-R5.pdf +44 -0
  57. data/test/data/standard-security-handler/ownerpwd-aes-256bit-V5-R5.pdf +43 -0
  58. data/test/data/standard-security-handler/userpwd-aes-256bit-V5-R5.pdf +0 -0
  59. data/test/hexapdf/common_tokenizer_tests.rb +5 -0
  60. data/test/hexapdf/digital_signature/signing/test_default_handler.rb +6 -0
  61. data/test/hexapdf/digital_signature/test_cms_handler.rb +12 -7
  62. data/test/hexapdf/digital_signature/test_signature.rb +7 -0
  63. data/test/hexapdf/digital_signature/test_signatures.rb +12 -7
  64. data/test/hexapdf/encryption/test_standard_security_handler.rb +5 -2
  65. data/test/hexapdf/font/cmap/test_writer.rb +73 -16
  66. data/test/hexapdf/font/test_true_type_wrapper.rb +17 -3
  67. data/test/hexapdf/layout/test_list_box.rb +7 -7
  68. data/test/hexapdf/layout/test_table_box.rb +52 -0
  69. data/test/hexapdf/layout/test_text_fragment.rb +3 -3
  70. data/test/hexapdf/layout/test_text_layouter.rb +4 -2
  71. data/test/hexapdf/task/test_merge_acro_form.rb +104 -0
  72. data/test/hexapdf/task/test_optimize.rb +2 -0
  73. data/test/hexapdf/test_composer.rb +8 -0
  74. data/test/hexapdf/test_document.rb +12 -3
  75. data/test/hexapdf/test_importer.rb +7 -0
  76. data/test/hexapdf/test_parser.rb +7 -0
  77. data/test/hexapdf/test_writer.rb +19 -5
  78. data/test/hexapdf/type/acro_form/test_appearance_generator.rb +40 -23
  79. data/test/hexapdf/type/acro_form/test_form.rb +7 -8
  80. data/test/hexapdf/type/acro_form/test_signature_field.rb +3 -1
  81. data/test/hexapdf/type/acro_form/test_variable_text_field.rb +14 -1
  82. data/test/hexapdf/type/actions/test_launch.rb +6 -2
  83. data/test/hexapdf/type/annotations/test_widget.rb +4 -0
  84. data/test/hexapdf/type/test_font_type1.rb +5 -0
  85. data/test/hexapdf/type/test_form.rb +1 -1
  86. data/test/hexapdf/type/test_page.rb +7 -1
  87. metadata +8 -2
@@ -62,8 +62,10 @@ module HexaPDF
62
62
 
63
63
  define_field :Type, type: Symbol, default: type
64
64
  define_field :Action, type: Symbol, required: true,
65
- allowed_values: [:All, :Include, :Exclude]
65
+ allowed_values: [:All, :Include, :Exclude]
66
66
  define_field :Fields, type: PDFArray
67
+ define_field :P, type: Numeric, version: '2.0',
68
+ allowed_values: [1, 2, 3]
67
69
 
68
70
  private
69
71
 
@@ -83,8 +85,8 @@ module HexaPDF
83
85
  # If a flag is set it means that the associated entry is a required constraint. Otherwise it
84
86
  # is optional.
85
87
  #
86
- # The available flags are: filter, sub_filter, v, reasons, legal_attestation, add_rev_info
87
- # and digest_method.
88
+ # The available flags are: filter, sub_filter, v, reasons, legal_attestation, add_rev_info,
89
+ # digest_method, lock_document and appearance_filter.
88
90
  #
89
91
  # See: PDF2.0 s12.7.5.5
90
92
  class SeedValueDictionary < Dictionary
@@ -98,13 +100,16 @@ module HexaPDF
98
100
  define_field :Filter, type: Symbol
99
101
  define_field :SubFilter, type: PDFArray
100
102
  define_field :DigestMethod, type: PDFArray, version: '1.7'
101
- define_field :V, type: Float
103
+ define_field :V, type: Integer
102
104
  define_field :Cert, type: :SVCert
103
105
  define_field :Reasons, type: PDFArray
104
106
  define_field :MDP, type: Dictionary, version: '1.6'
105
107
  define_field :TimeStamp, type: Dictionary, version: '1.6'
106
108
  define_field :LegalAttestation, type: PDFArray, version: '1.6'
107
109
  define_field :AddRevInfo, type: Boolean, version: '1.7'
110
+ define_field :LockDocument, type: Symbol, version: '2.0',
111
+ allowed_values: [:true, :false, :auto]
112
+ define_field :AppearanceFilter, type: String, version: '2.0'
108
113
 
109
114
  ##
110
115
  # :method: flags
@@ -130,7 +135,8 @@ module HexaPDF
130
135
  # all prior flags will be cleared.
131
136
  #
132
137
  bit_field(:flags, {filter: 0, sub_filter: 1, v: 2, reasons: 3, legal_attestation: 4,
133
- add_rev_info: 5, digest_method: 6},
138
+ add_rev_info: 5, digest_method: 6, lock_document: 7,
139
+ appearance_filter: 8},
134
140
  lister: "flags", getter: "flagged?", setter: "flag", unsetter: "unflag",
135
141
  value_getter: "self[:Ff]", value_setter: "self[:Ff]")
136
142
 
@@ -155,12 +161,16 @@ module HexaPDF
155
161
  define_field :Type, type: Symbol, default: type
156
162
  define_field :Ff, type: Integer, default: 0
157
163
  define_field :Subject, type: PDFArray
164
+ define_field :SignaturePolicyOID, type: String, version: '2.0'
165
+ define_field :SignaturePolicyHashValue, type: String, version: '2.0'
166
+ define_field :SignaturePolicyHashAlgorithm, type: Symbol, version: '2.0'
167
+ define_field :SignaturePolicyCommitmentType, type: PDFArray, version: '2.0'
158
168
  define_field :SubjectDN, type: PDFArray, version: '1.7'
159
169
  define_field :KeyUsage, type: PDFArray, version: '1.7'
160
170
  define_field :Issuer, type: PDFArray
161
171
  define_field :OID, type: PDFArray
162
172
  define_field :URL, type: String
163
- define_field :URLType, type: Symbol, default: :Browser
173
+ define_field :URLType, type: Symbol, default: :Browser, version: '1.7'
164
174
 
165
175
  ##
166
176
  # :method: flags
@@ -199,7 +209,8 @@ module HexaPDF
199
209
 
200
210
  # Returns the associated signature dictionary or +nil+ if the signature is not filled in.
201
211
  def field_value
202
- self[:V]
212
+ val = self[:V]
213
+ val.instance_of?(Dictionary) ? document.wrap(val, type: :Sig) : val
203
214
  end
204
215
 
205
216
  # Sets the signature dictionary as value of this signature field.
@@ -51,7 +51,7 @@ module HexaPDF
51
51
  # See: PDF2.0 s12.7.4.3
52
52
  class VariableTextField < Field
53
53
 
54
- define_field :DA, type: String
54
+ define_field :DA, type: PDFByteString
55
55
  define_field :Q, type: Integer, default: 0, allowed_values: [0, 1, 2]
56
56
  define_field :DS, type: String, version: '1.5'
57
57
  define_field :RV, type: [String, Stream], version: '1.5'
@@ -106,7 +106,7 @@ module HexaPDF
106
106
  font_params[2] = HexaPDF::Content::ColorSpace.prenormalized_device_color(params)
107
107
  end
108
108
  end
109
- HexaPDF::Content::Parser.parse(appearance_string.sub(/\/\//, '/'), &block)
109
+ HexaPDF::Content::Parser.parse(appearance_string.to_s.sub(/\/\//, '/'), &block)
110
110
  block_given? ? nil : font_params
111
111
  end
112
112
 
@@ -154,13 +154,21 @@ module HexaPDF
154
154
  # font_size, font_color].
155
155
  #
156
156
  # The default appearance string is taken from the given +widget+ of the field, falls back to
157
- # the field itself or, if still not available, the default appearance string of the form.
157
+ # the field itself and then the default appearance string of the form. If it still not
158
+ # available, a standard default appearance string is set (see
159
+ # #set_default_appearance_string) and used.
158
160
  #
159
161
  # The reason why a specific widget of the field can be specified is because the widgets of a
160
162
  # field might differ in their visual representation.
161
163
  def parse_default_appearance_string(widget = self)
162
164
  da = widget[:DA] || self[:DA] || (document.acro_form && document.acro_form[:DA])
163
- raise HexaPDF::Error, "No default appearance string set" unless da
165
+ unless da
166
+ if (args = document.config['acro_form.fallback_default_appearance'])
167
+ da = set_default_appearance_string(**args)
168
+ else
169
+ raise HexaPDF::Error, "No default appearance string set"
170
+ end
171
+ end
164
172
  self.class.parse_appearance_string(da)
165
173
  end
166
174
 
@@ -47,6 +47,7 @@ module HexaPDF
47
47
 
48
48
  define_field :S, type: Symbol, required: true, default: :GoTo
49
49
  define_field :D, type: [Symbol, PDFByteString, PDFArray], required: true
50
+ define_field :SD, type: PDFArray, version: '2.0'
50
51
 
51
52
  end
52
53
 
@@ -48,6 +48,7 @@ module HexaPDF
48
48
  define_field :S, type: Symbol, required: true, default: :GoToR
49
49
  define_field :F, type: :Filespec, required: true
50
50
  define_field :D, type: [Symbol, PDFByteString, PDFArray], required: true
51
+ define_field :SD, type: PDFArray, version: '2.0'
51
52
  define_field :NewWindow, type: Boolean, version: '1.2'
52
53
 
53
54
  end
@@ -60,13 +60,17 @@ module HexaPDF
60
60
  define_field :S, type: Symbol, required: true, default: :Launch
61
61
  define_field :F, type: :Filespec
62
62
  define_field :Win, type: :XXLaunchActionWinParameters
63
+ define_field :Mac, type: ::Object, version: '2.0'
64
+ define_field :Unix, type: ::Object, version: '2.0'
63
65
  define_field :NewWindow, type: Boolean, version: '1.2'
64
66
 
65
67
  private
66
68
 
67
69
  def perform_validation #:nodoc:
68
70
  super
69
- yield("A Launch action needs a target") unless key?(:F) || key?(:Win)
71
+ unless key?(:Win) || key?(:Mac) || key?(:Unix) || key?(:F)
72
+ yield("Launch action key /F required if /Win, /Mac and /Unix are absent")
73
+ end
70
74
  end
71
75
 
72
76
  end
@@ -123,7 +123,7 @@ module HexaPDF
123
123
  define_field :Contents, type: String
124
124
  define_field :P, type: Dictionary, version: '1.3'
125
125
  define_field :NM, type: String, version: '1.4'
126
- define_field :M, type: PDFDate, version: '1.1'
126
+ define_field :M, type: [PDFDate, String], version: '1.1'
127
127
  define_field :F, type: Integer, default: 0, version: '1.1'
128
128
  define_field :AP, type: :XXAppearanceDictionary, version: '1.2'
129
129
  define_field :AS, type: Symbol, version: '1.2'
@@ -131,6 +131,11 @@ module HexaPDF
131
131
  define_field :C, type: PDFArray, version: '1.1'
132
132
  define_field :StructParent, type: Integer, version: '1.3'
133
133
  define_field :OC, type: Dictionary, version: '1.5'
134
+ define_field :AF, type: PDFArray, version: '2.0'
135
+ define_field :ca, type: Numeric, default: 1.0, version: '2.0'
136
+ define_field :CA, type: Numeric, default: 1.0, version: '2.0'
137
+ define_field :BM, type: Symbol, version: '2.0'
138
+ define_field :Lang, type: String, version: '2.0'
134
139
 
135
140
  ##
136
141
  # :method: flags
@@ -46,6 +46,19 @@ module HexaPDF
46
46
  # See: PDF2.0 s12.5.6.2, HexaPDF::Type::Annotation
47
47
  class MarkupAnnotation < Annotation
48
48
 
49
+ # External data dictionary used by some markup annotation types.
50
+ #
51
+ # See: PDF2.0 s12.5.6.2
52
+ class ExData < Dictionary
53
+
54
+ define_type :ExData
55
+
56
+ define_field :Type, type: Symbol, required: true, default: type
57
+ define_field :Subtype, type: Symbol, required: true,
58
+ allowed_values: [:Markup3D, :'3DM', :MarkupGeo]
59
+
60
+ end
61
+
49
62
  define_field :T, type: String, version: '1.1'
50
63
  define_field :Popup, type: :Annot, version: '1.3'
51
64
  define_field :CA, type: Numeric, default: 1.0, version: '1.4'
@@ -56,7 +69,7 @@ module HexaPDF
56
69
  define_field :RT, type: Symbol, default: :R, allowed_values: [:R, :Group],
57
70
  version: '1.6'
58
71
  define_field :IT, type: Symbol, version: '1.6'
59
- define_field :ExData, type: Dictionary, version: '1.7'
72
+ define_field :ExData, type: :ExData, version: '1.7'
60
73
 
61
74
  private
62
75
 
@@ -259,7 +259,7 @@ module HexaPDF
259
259
  # auto-sized checkmark (i.e. :check for for check boxes) or circle (:circle for radio
260
260
  # buttons). This also means that multiple invocations will reset *all* prior values.
261
261
  #
262
- # Note: The marker is called "normal caption" in the PDF 1.7 spec and the /CA entry of the
262
+ # Note: The marker is called "normal caption" in the PDF 2.0 spec and the /CA entry of the
263
263
  # associated appearance characteristics dictionary. The marker size and color are set using
264
264
  # the /DA key on the widget (although /DA is not defined for widget, this is how Acrobat
265
265
  # does it).
@@ -305,7 +305,9 @@ module HexaPDF
305
305
  size = 0
306
306
  color = HexaPDF::Content::ColorSpace.prenormalized_device_color([0])
307
307
  if (da = self[:DA] || field[:DA])
308
- _, size, color = HexaPDF::Type::AcroForm::VariableTextField.parse_appearance_string(da)
308
+ _, da_size, da_color = AcroForm::VariableTextField.parse_appearance_string(da)
309
+ size = da_size || size
310
+ color = da_color || color
309
311
  end
310
312
 
311
313
  MarkerStyle.new(style, size, color)
@@ -84,6 +84,9 @@ module HexaPDF
84
84
  define_field :Requirements, type: PDFArray, version: '1.7'
85
85
  define_field :Collection, type: Dictionary, version: '1.7'
86
86
  define_field :NeedsRendering, type: Boolean, version: '1.7'
87
+ define_field :DSS, type: Dictionary, version: '2.0'
88
+ define_field :AF, type: PDFArray, version: '2.0'
89
+ define_field :DPartRoot, type: Dictionary, version: '2.0'
87
90
 
88
91
  # Returns +true+ since catalog objects must always be indirect.
89
92
  def must_be_indirect?
@@ -61,13 +61,16 @@ module HexaPDF
61
61
 
62
62
  DEFAULT_WIDTH = 1000 # :nodoc:
63
63
 
64
+ define_field :Subtype, type: Symbol, required: true,
65
+ allowed_values: [:CIDFontType0, :CIDFontType2]
64
66
  define_field :BaseFont, type: Symbol, required: true
65
67
  define_field :CIDSystemInfo, type: :XXCIDSystemInfo, required: true
66
- define_field :FontDescriptor, type: :FontDescriptor, indirect: true, required: true
68
+ define_field :FontDescriptor, type: :FontDescriptor, required: true
67
69
  define_field :DW, type: Integer, default: DEFAULT_WIDTH
68
70
  define_field :W, type: PDFArray
69
71
  define_field :DW2, type: PDFArray, default: [880, -1100]
70
72
  define_field :W2, type: PDFArray
73
+ define_field :CIDToGIDMap, type: [Symbol, Stream]
71
74
 
72
75
  # Returns the unscaled width of the given CID in glyph units, or 0 if the width for the CID is
73
76
  # missing.
@@ -78,19 +78,22 @@ module HexaPDF
78
78
 
79
79
  define_type :Filespec
80
80
 
81
- define_field :Type, type: Symbol, default: type, required: true
82
- define_field :FS, type: Symbol
83
- define_field :F, type: PDFByteString
84
- define_field :UF, type: String, version: '1.7'
85
- define_field :DOS, type: PDFByteString
86
- define_field :Mac, type: PDFByteString
87
- define_field :Unix, type: PDFByteString
88
- define_field :ID, type: PDFArray
89
- define_field :V, type: Boolean, version: '1.2'
90
- define_field :EF, type: :XXFilespecEFDictionary, version: '1.7'
91
- define_field :RF, type: Dictionary, version: '1.3'
92
- define_field :Desc, type: String, version: '1.6'
93
- define_field :CI, type: Dictionary, version: '1.7'
81
+ define_field :Type, type: Symbol, default: type, required: true
82
+ define_field :FS, type: Symbol
83
+ define_field :F, type: PDFByteString
84
+ define_field :UF, type: String, version: '1.7'
85
+ define_field :DOS, type: PDFByteString
86
+ define_field :Mac, type: PDFByteString
87
+ define_field :Unix, type: PDFByteString
88
+ define_field :ID, type: PDFArray
89
+ define_field :V, type: Boolean, version: '1.2'
90
+ define_field :EF, type: :XXFilespecEFDictionary, version: '1.7'
91
+ define_field :RF, type: Dictionary, version: '1.3'
92
+ define_field :Desc, type: String, version: '1.6'
93
+ define_field :CI, type: Dictionary, version: '1.7'
94
+ define_field :Thumb, type: Stream, version: '2.0'
95
+ define_field :EP, type: Dictionary, version: '2.0'
96
+ define_field :AF, type: Symbol, version: '2.0', default: :Unspecified
94
97
 
95
98
  # Returns +true+ if this file specification references an URL and not a file.
96
99
  def url?
@@ -114,7 +117,7 @@ module HexaPDF
114
117
 
115
118
  # Sets the file specification string to the given filename.
116
119
  #
117
- # Since the /Unix, /Mac and /DOS fields are obsolescent, only the /F and /UF fields are set.
120
+ # Since the /Unix, /Mac and /DOS fields are deprecated, only the /F and /UF fields are set.
118
121
  def path=(filename)
119
122
  self[:UF] = filename
120
123
  self[:F] = filename.b
@@ -57,7 +57,7 @@ module HexaPDF
57
57
  define_field :FontStretch, type: Symbol, version: '1.5',
58
58
  allowed_values: [:UltraCondensed, :ExtraCondensed, :Condensed, :SemiCondensed,
59
59
  :Normal, :SemiExpanded, :Expanded, :ExtraExpanded, :UltraExpanded]
60
- define_field :FontWeight, type: Numeric, version: '1.5'
60
+ define_field :FontWeight, type: Integer, version: '1.5' # also see validation
61
61
  define_field :Flags, type: Integer, required: true
62
62
  define_field :FontBBox, type: Rectangle
63
63
  define_field :ItalicAngle, type: Numeric, required: true
@@ -76,6 +76,7 @@ module HexaPDF
76
76
  define_field :FontFile3, type: Stream, version: '1.2'
77
77
  define_field :CharSet, type: [PDFByteString, String], version: '1.1'
78
78
 
79
+ # From PDF2.0 s9.8.3.1
79
80
  define_field :Style, type: Dictionary
80
81
  define_field :Lang, type: Symbol, version: '1.5'
81
82
  define_field :FD, type: Dictionary
@@ -98,13 +99,13 @@ module HexaPDF
98
99
 
99
100
  font_weight = self[:FontWeight]
100
101
  if font_weight && !ALLOWED_FONT_WEIGHTS.include?(font_weight)
101
- yield("Field FontWeight does not contain an allowed value", true)
102
+ yield("Field FontWeight contains the disallowed value #{font_weight}", true)
102
103
  delete(:FontWeight)
103
104
  end
104
105
 
105
106
  descent = self[:Descent]
106
107
  if descent && descent > 0
107
- yield("The /Descent value needs to be a negative number", true)
108
+ yield("The /Descent value needs to be zero or negative", true)
108
109
  self[:Descent] = -descent
109
110
  end
110
111
  end
@@ -47,10 +47,12 @@ module HexaPDF
47
47
  # See: PDF2.0 s9.6
48
48
  class FontSimple < Font
49
49
 
50
+ # Only the common fields are defined here, the rest in FontType1, FontType3, FontTrueType
51
+ define_field :Name, type: Symbol
50
52
  define_field :FirstChar, type: Integer
51
53
  define_field :LastChar, type: Integer
52
54
  define_field :Widths, type: PDFArray
53
- define_field :FontDescriptor, type: :FontDescriptor, indirect: true
55
+ define_field :FontDescriptor, type: :FontDescriptor
54
56
  define_field :Encoding, type: [Dictionary, Symbol]
55
57
 
56
58
  # Returns the font descriptor. May be +nil+ for a standard 14 font.
@@ -41,6 +41,8 @@ module HexaPDF
41
41
  module Type
42
42
 
43
43
  # Represents a TrueType font.
44
+ #
45
+ # See: PDF2.0 s9.6.3
44
46
  class FontTrueType < FontSimple
45
47
 
46
48
  define_field :Subtype, type: Symbol, required: true, default: :TrueType
@@ -48,7 +48,7 @@ module HexaPDF
48
48
  # Composite fonts also allow for vertical writing mode and support TrueType as well as OpenType
49
49
  # fonts.
50
50
  #
51
- # See: PDF2.0 s9.7
51
+ # See: PDF2.0 s9.7, s9.7.6.1
52
52
  class FontType0 < Font
53
53
 
54
54
  define_field :Subtype, type: Symbol, required: true, default: :Type0
@@ -170,6 +170,8 @@ module HexaPDF
170
170
  end
171
171
  end
172
172
 
173
+ PREDEFINED_ENCODING = [:MacRomanEncoding, :MacExpertEncoding, :WinAnsiEncoding] #:nodoc:
174
+
173
175
  # Validates the Type1 font dictionary.
174
176
  def perform_validation
175
177
  std_font = StandardFonts.standard_font?(self[:BaseFont])
@@ -178,6 +180,11 @@ module HexaPDF
178
180
  if !std_font && self[:FontDescriptor].nil?
179
181
  yield("Required field FontDescriptor is not set", false)
180
182
  end
183
+
184
+ encoding = self[:Encoding]
185
+ if encoding.kind_of?(Symbol) && !PREDEFINED_ENCODING.include?(encoding)
186
+ yield("The /Encoding value '#{encoding}' is invalid", false)
187
+ end
181
188
  end
182
189
 
183
190
  end
@@ -49,7 +49,6 @@ module HexaPDF
49
49
  class FontType3 < FontSimple
50
50
 
51
51
  define_field :Subtype, type: Symbol, required: true, default: :Type3
52
- define_field :Name, type: Symbol
53
52
  define_field :FontBBox, type: Rectangle, required: true
54
53
  define_field :FontMatrix, type: PDFArray, required: true
55
54
  define_field :CharProcs, type: Dictionary, required: true
@@ -89,6 +89,10 @@ module HexaPDF
89
89
  define_field :StructParents, type: Integer, version: '1.3'
90
90
  define_field :OPI, type: Dictionary, version: '1.2'
91
91
  define_field :OC, type: Dictionary, version: '1.5'
92
+ define_field :Name, type: Symbol
93
+ define_field :AF, type: PDFArray, version: '2.0'
94
+ define_field :Measure, type: Dictionary, version: '2.0'
95
+ define_field :PtData, type: Dictionary, version: '2.0'
92
96
 
93
97
  # Returns the path to the PDF file that was used when creating the form object.
94
98
  #
@@ -131,8 +135,7 @@ module HexaPDF
131
135
 
132
136
  # Returns the resource dictionary which is automatically created if it doesn't exist.
133
137
  def resources
134
- self[:Resources] ||= document.wrap({ProcSet: [:PDF, :Text, :ImageB, :ImageC, :ImageI]},
135
- type: :XXResources)
138
+ self[:Resources] ||= document.wrap({}, type: :XXResources)
136
139
  end
137
140
 
138
141
  # Processes the content stream of the form XObject with the given processor object.
@@ -58,10 +58,10 @@ module HexaPDF
58
58
  define_field :ML, type: Numeric, version: "1.3"
59
59
  define_field :D, type: PDFArray, version: "1.3"
60
60
  define_field :RI, type: Symbol, version: "1.3",
61
- allowed_values: [HexaPDF::Content::RenderingIntent::ABSOLUTE_COLORIMETRIC,
62
- HexaPDF::Content::RenderingIntent::RELATIVE_COLORIMETRIC,
63
- HexaPDF::Content::RenderingIntent::SATURATION,
64
- HexaPDF::Content::RenderingIntent::PERCEPTUAL]
61
+ allowed_values: [HexaPDF::Content::RenderingIntent::ABSOLUTE_COLORIMETRIC,
62
+ HexaPDF::Content::RenderingIntent::RELATIVE_COLORIMETRIC,
63
+ HexaPDF::Content::RenderingIntent::SATURATION,
64
+ HexaPDF::Content::RenderingIntent::PERCEPTUAL]
65
65
  define_field :OP, type: Boolean
66
66
  define_field :op, type: Boolean, version: "1.3"
67
67
  define_field :OPM, type: Integer, version: "1.3"
@@ -82,6 +82,9 @@ module HexaPDF
82
82
  define_field :ca, type: Numeric, version: "1.4"
83
83
  define_field :AIS, type: Boolean, version: "1.4"
84
84
  define_field :TK, type: Boolean, version: "1.4"
85
+ define_field :UseBlackPtComp, type: Symbol, version: "2.0",
86
+ allowed_values: [:OFF, :ON, :Default]
87
+ define_field :HTO, type: PDFArray, version: "2.0"
85
88
 
86
89
  end
87
90
 
@@ -61,10 +61,10 @@ module HexaPDF
61
61
  define_field :ColorSpace, type: [Symbol, PDFArray]
62
62
  define_field :BitsPerComponent, type: Integer
63
63
  define_field :Intent, type: Symbol, version: '1.1',
64
- allowed_values: [HexaPDF::Content::RenderingIntent::ABSOLUTE_COLORIMETRIC,
65
- HexaPDF::Content::RenderingIntent::RELATIVE_COLORIMETRIC,
66
- HexaPDF::Content::RenderingIntent::SATURATION,
67
- HexaPDF::Content::RenderingIntent::PERCEPTUAL]
64
+ allowed_values: [HexaPDF::Content::RenderingIntent::ABSOLUTE_COLORIMETRIC,
65
+ HexaPDF::Content::RenderingIntent::RELATIVE_COLORIMETRIC,
66
+ HexaPDF::Content::RenderingIntent::SATURATION,
67
+ HexaPDF::Content::RenderingIntent::PERCEPTUAL]
68
68
  define_field :ImageMask, type: Boolean, default: false
69
69
  define_field :Mask, type: [Stream, PDFArray], version: '1.3'
70
70
  define_field :Decode, type: PDFArray
@@ -72,11 +72,15 @@ module HexaPDF
72
72
  define_field :Alternates, type: PDFArray, version: '1.3'
73
73
  define_field :SMask, type: Stream, version: '1.4'
74
74
  define_field :SMaskInData, type: Integer, version: '1.5', allowed_values: [0, 1, 2]
75
+ define_field :Name, type: Symbol
75
76
  define_field :StructParent, type: Integer, version: '1.3'
76
77
  define_field :ID, type: PDFByteString, version: '1.3'
77
78
  define_field :OPI, type: Dictionary, version: '1.2'
78
79
  define_field :Metadata, type: Stream, version: '1.4'
79
80
  define_field :OC, type: Dictionary, version: '1.5'
81
+ define_field :AF, type: PDFArray, version: '2.0'
82
+ define_field :Measure, type: Dictionary, version: '2.0'
83
+ define_field :PtData, type: Dictionary, version: '2.0'
80
84
 
81
85
  # Returns the source path that was used when creating the image object.
82
86
  #
@@ -57,8 +57,8 @@ module HexaPDF
57
57
  define_field :Producer, type: String
58
58
  define_field :CreationDate, type: PDFDate
59
59
  define_field :ModDate, type: PDFDate
60
- define_field :Trapped, type: Symbol, version: '1.3',
61
- allowed_values: [:True, :False, :Unknown]
60
+ define_field :Trapped, type: Symbol, version: '1.3', default: :Unknown,
61
+ allowed_values: [:True, :False, :Unknown]
62
62
 
63
63
  # Info dictionaries must always be indirect.
64
64
  def must_be_indirect?
@@ -48,8 +48,8 @@ module HexaPDF
48
48
  define_type :XXMarkInformation
49
49
 
50
50
  define_field :Marked, type: Boolean, default: false
51
- define_field :UserProperties, type: Boolean, default: false
52
- define_field :Suspects, type: Boolean, default: false
51
+ define_field :UserProperties, type: Boolean, default: false, version: '1.6'
52
+ define_field :Suspects, type: Boolean, default: false, version: '1.6'
53
53
 
54
54
  end
55
55
 
@@ -76,7 +76,7 @@ module HexaPDF
76
76
  define_field :AS, type: PDFArray
77
77
  define_field :Order, type: PDFArray
78
78
  define_field :ListMode, type: Symbol, default: :AllPages,
79
- allowed_values: [:AllPages, :VisiblePages]
79
+ allowed_values: [:AllPages, :VisiblePages]
80
80
  define_field :RBGroups, type: PDFArray
81
81
  define_field :Locked, type: PDFArray, default: []
82
82
 
@@ -54,7 +54,7 @@ module HexaPDF
54
54
  define_field :Type, type: Symbol, required: true, default: type
55
55
  define_field :OCGs, type: [:OCG, PDFArray]
56
56
  define_field :P, type: Symbol, default: :AnyOn,
57
- allowed_values: [:AllOn, :AnyOn, :AnyOff, :AllOff]
57
+ allowed_values: [:AllOn, :AnyOn, :AnyOff, :AllOff]
58
58
  define_field :VE, type: PDFArray
59
59
 
60
60
  end
@@ -159,6 +159,9 @@ module HexaPDF
159
159
  define_field :PresSteps, type: Dictionary, version: '1.5'
160
160
  define_field :UserUnit, type: Numeric, version: '1.6'
161
161
  define_field :VP, type: PDFArray, version: '1.6'
162
+ define_field :AF, type: PDFArray, version: '2.0'
163
+ define_field :OutputIntents, type: PDFArray, version: '2.0'
164
+ define_field :DPart, type: Dictionary, version: '2.0'
162
165
 
163
166
  # Returns +true+ since page objects must always be indirect.
164
167
  def must_be_indirect?
@@ -358,7 +361,7 @@ module HexaPDF
358
361
  def contents
359
362
  Array(self[:Contents]).each_with_object("".b) do |content_stream, content|
360
363
  content << " " unless content.empty?
361
- content << content_stream.stream
364
+ content << content_stream.stream if content_stream.kind_of?(Stream)
362
365
  end
363
366
  end
364
367
 
@@ -380,8 +383,7 @@ module HexaPDF
380
383
  # Returns the, possibly inherited, resource dictionary which is automatically created if it
381
384
  # doesn't exist.
382
385
  def resources
383
- self[:Resources] ||= document.wrap({ProcSet: [:PDF, :Text, :ImageB, :ImageC, :ImageI]},
384
- type: :XXResources)
386
+ self[:Resources] ||= document.wrap({}, type: :XXResources)
385
387
  end
386
388
 
387
389
  # Processes the content streams associated with the page with the given processor object.
@@ -49,13 +49,13 @@ module HexaPDF
49
49
 
50
50
  define_type :XXResources
51
51
 
52
- define_field :ExtGState, type: Dictionary
52
+ define_field :ExtGState, type: Dictionary
53
53
  define_field :ColorSpace, type: Dictionary
54
- define_field :Pattern, type: Dictionary
55
- define_field :Shading, type: Dictionary, version: '1.3'
56
- define_field :XObject, type: Dictionary
57
- define_field :Font, type: Dictionary
58
- define_field :ProcSet, type: PDFArray
54
+ define_field :Pattern, type: Dictionary
55
+ define_field :Shading, type: Dictionary, version: '1.3'
56
+ define_field :XObject, type: Dictionary
57
+ define_field :Font, type: Dictionary
58
+ define_field :ProcSet, type: PDFArray
59
59
  define_field :Properties, type: Dictionary, version: '1.2'
60
60
 
61
61
  # Returns the color space stored under the given name.
@@ -56,19 +56,20 @@ module HexaPDF
56
56
  define_field :CenterWindow, type: Boolean, default: false
57
57
  define_field :DisplayDocTitle, type: Boolean, default: false, version: '1.4'
58
58
  define_field :NonFullScreenPageMode, type: Symbol, default: :UseNone,
59
- allowed_values: [:UseNone, :UseOutlines, :UseThumbs, :UseOC]
59
+ allowed_values: [:UseNone, :UseOutlines, :UseThumbs, :UseOC]
60
60
  define_field :Direction, type: Symbol, default: :L2R, version: '1.3',
61
- allowed_values: [:L2R, :R2L]
61
+ allowed_values: [:L2R, :R2L]
62
62
  define_field :ViewArea, type: Symbol, default: :CropBox, version: '1.4'
63
63
  define_field :ViewClip, type: Symbol, default: :CropBox, version: '1.4'
64
64
  define_field :PrintArea, type: Symbol, default: :CropBox, version: '1.4'
65
65
  define_field :PrintClip, type: Symbol, default: :CropBox, version: '1.4'
66
66
  define_field :PrintScaling, type: Symbol, default: :AppDefault, version: '1.6'
67
67
  define_field :Duplex, type: Symbol, version: '1.7',
68
- allowed_values: [:Simplex, :DuplexFlipShortEdge, :DuplexFlipLongEdge]
68
+ allowed_values: [:Simplex, :DuplexFlipShortEdge, :DuplexFlipLongEdge]
69
69
  define_field :PickTrayByPDFSize, type: Boolean, version: '1.7'
70
70
  define_field :PrintPageRange, type: PDFArray, version: '1.7'
71
71
  define_field :NumCopies, type: Integer, version: '1.7'
72
+ define_field :Enforce, type: PDFArray, version: '2.0'
72
73
 
73
74
  end
74
75
 
@@ -37,6 +37,6 @@
37
37
  module HexaPDF
38
38
 
39
39
  # The version of HexaPDF.
40
- VERSION = '0.46.0'
40
+ VERSION = '1.0.0'
41
41
 
42
42
  end
@@ -163,6 +163,7 @@ module HexaPDF
163
163
 
164
164
  trailer = rev.trailer.value.dup
165
165
  trailer.delete(:XRefStm)
166
+ trailer.delete(:Type)
166
167
  if previous_xref_pos
167
168
  trailer[:Prev] = previous_xref_pos
168
169
  else