hexapdf 0.46.0 → 1.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.
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