hexapdf 0.5.0 → 0.6.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 (122) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +76 -2
  3. data/CONTRIBUTERS +1 -1
  4. data/Rakefile +1 -1
  5. data/VERSION +1 -1
  6. data/examples/boxes.rb +68 -0
  7. data/examples/graphics.rb +12 -12
  8. data/examples/{text_box_alignment.rb → text_layouter_alignment.rb} +14 -14
  9. data/examples/text_layouter_inline_boxes.rb +66 -0
  10. data/examples/{text_box_line_wrapping.rb → text_layouter_line_wrapping.rb} +9 -10
  11. data/examples/{text_box_shapes.rb → text_layouter_shapes.rb} +58 -54
  12. data/examples/text_layouter_styling.rb +125 -0
  13. data/examples/truetype.rb +5 -7
  14. data/lib/hexapdf/cli/command.rb +1 -0
  15. data/lib/hexapdf/configuration.rb +170 -106
  16. data/lib/hexapdf/content/canvas.rb +41 -36
  17. data/lib/hexapdf/content/graphics_state.rb +15 -0
  18. data/lib/hexapdf/content/operator.rb +1 -1
  19. data/lib/hexapdf/dictionary.rb +20 -8
  20. data/lib/hexapdf/dictionary_fields.rb +8 -6
  21. data/lib/hexapdf/document.rb +25 -26
  22. data/lib/hexapdf/document/fonts.rb +4 -4
  23. data/lib/hexapdf/document/images.rb +2 -2
  24. data/lib/hexapdf/document/pages.rb +16 -16
  25. data/lib/hexapdf/encryption/security_handler.rb +41 -9
  26. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  27. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  28. data/lib/hexapdf/filter/predictor.rb +7 -1
  29. data/lib/hexapdf/font/true_type/font.rb +20 -0
  30. data/lib/hexapdf/font/type1/font.rb +23 -0
  31. data/lib/hexapdf/font_loader.rb +1 -0
  32. data/lib/hexapdf/font_loader/from_configuration.rb +2 -3
  33. data/lib/hexapdf/font_loader/from_file.rb +65 -0
  34. data/lib/hexapdf/image_loader/png.rb +2 -2
  35. data/lib/hexapdf/layout.rb +3 -2
  36. data/lib/hexapdf/layout/box.rb +146 -0
  37. data/lib/hexapdf/layout/inline_box.rb +40 -31
  38. data/lib/hexapdf/layout/{line_fragment.rb → line.rb} +12 -13
  39. data/lib/hexapdf/layout/style.rb +630 -41
  40. data/lib/hexapdf/layout/text_fragment.rb +80 -12
  41. data/lib/hexapdf/layout/{text_box.rb → text_layouter.rb} +164 -109
  42. data/lib/hexapdf/number_tree_node.rb +1 -1
  43. data/lib/hexapdf/parser.rb +4 -1
  44. data/lib/hexapdf/revisions.rb +11 -4
  45. data/lib/hexapdf/stream.rb +8 -9
  46. data/lib/hexapdf/tokenizer.rb +5 -3
  47. data/lib/hexapdf/type.rb +3 -0
  48. data/lib/hexapdf/type/action.rb +56 -0
  49. data/lib/hexapdf/type/actions.rb +52 -0
  50. data/lib/hexapdf/type/actions/go_to.rb +52 -0
  51. data/lib/hexapdf/type/actions/go_to_r.rb +54 -0
  52. data/lib/hexapdf/type/actions/launch.rb +73 -0
  53. data/lib/hexapdf/type/actions/uri.rb +65 -0
  54. data/lib/hexapdf/type/annotation.rb +85 -0
  55. data/lib/hexapdf/type/annotations.rb +51 -0
  56. data/lib/hexapdf/type/annotations/link.rb +70 -0
  57. data/lib/hexapdf/type/annotations/markup_annotation.rb +70 -0
  58. data/lib/hexapdf/type/annotations/text.rb +81 -0
  59. data/lib/hexapdf/type/catalog.rb +3 -1
  60. data/lib/hexapdf/type/embedded_file.rb +6 -11
  61. data/lib/hexapdf/type/file_specification.rb +4 -6
  62. data/lib/hexapdf/type/font.rb +3 -1
  63. data/lib/hexapdf/type/font_descriptor.rb +18 -16
  64. data/lib/hexapdf/type/form.rb +3 -1
  65. data/lib/hexapdf/type/graphics_state_parameter.rb +3 -1
  66. data/lib/hexapdf/type/image.rb +4 -2
  67. data/lib/hexapdf/type/info.rb +2 -5
  68. data/lib/hexapdf/type/names.rb +2 -5
  69. data/lib/hexapdf/type/object_stream.rb +2 -1
  70. data/lib/hexapdf/type/page.rb +14 -1
  71. data/lib/hexapdf/type/page_tree_node.rb +9 -6
  72. data/lib/hexapdf/type/resources.rb +2 -5
  73. data/lib/hexapdf/type/trailer.rb +2 -5
  74. data/lib/hexapdf/type/viewer_preferences.rb +2 -5
  75. data/lib/hexapdf/type/xref_stream.rb +3 -1
  76. data/lib/hexapdf/version.rb +1 -1
  77. data/test/hexapdf/common_tokenizer_tests.rb +3 -1
  78. data/test/hexapdf/content/test_canvas.rb +29 -3
  79. data/test/hexapdf/content/test_graphics_state.rb +11 -0
  80. data/test/hexapdf/content/test_operator.rb +3 -2
  81. data/test/hexapdf/document/test_fonts.rb +8 -8
  82. data/test/hexapdf/document/test_images.rb +4 -12
  83. data/test/hexapdf/document/test_pages.rb +7 -7
  84. data/test/hexapdf/encryption/test_security_handler.rb +1 -5
  85. data/test/hexapdf/filter/test_predictor.rb +40 -12
  86. data/test/hexapdf/font/true_type/test_font.rb +16 -0
  87. data/test/hexapdf/font/type1/test_font.rb +30 -0
  88. data/test/hexapdf/font_loader/test_from_file.rb +29 -0
  89. data/test/hexapdf/font_loader/test_standard14.rb +4 -3
  90. data/test/hexapdf/layout/test_box.rb +104 -0
  91. data/test/hexapdf/layout/test_inline_box.rb +24 -10
  92. data/test/hexapdf/layout/{test_line_fragment.rb → test_line.rb} +9 -9
  93. data/test/hexapdf/layout/test_style.rb +519 -31
  94. data/test/hexapdf/layout/test_text_fragment.rb +136 -15
  95. data/test/hexapdf/layout/{test_text_box.rb → test_text_layouter.rb} +224 -144
  96. data/test/hexapdf/layout/test_text_shaper.rb +1 -1
  97. data/test/hexapdf/test_configuration.rb +12 -6
  98. data/test/hexapdf/test_dictionary.rb +27 -2
  99. data/test/hexapdf/test_dictionary_fields.rb +10 -1
  100. data/test/hexapdf/test_document.rb +14 -13
  101. data/test/hexapdf/test_parser.rb +12 -0
  102. data/test/hexapdf/test_revisions.rb +34 -0
  103. data/test/hexapdf/test_stream.rb +1 -1
  104. data/test/hexapdf/test_type.rb +18 -0
  105. data/test/hexapdf/test_writer.rb +2 -2
  106. data/test/hexapdf/type/actions/test_launch.rb +24 -0
  107. data/test/hexapdf/type/actions/test_uri.rb +23 -0
  108. data/test/hexapdf/type/annotations/test_link.rb +19 -0
  109. data/test/hexapdf/type/annotations/test_markup_annotation.rb +22 -0
  110. data/test/hexapdf/type/annotations/test_text.rb +38 -0
  111. data/test/hexapdf/type/test_annotation.rb +38 -0
  112. data/test/hexapdf/type/test_file_specification.rb +0 -7
  113. data/test/hexapdf/type/test_info.rb +0 -5
  114. data/test/hexapdf/type/test_page.rb +14 -0
  115. data/test/hexapdf/type/test_page_tree_node.rb +4 -1
  116. data/test/hexapdf/type/test_trailer.rb +0 -4
  117. data/test/test_helper.rb +6 -3
  118. metadata +36 -15
  119. data/examples/text_box_inline_boxes.rb +0 -56
  120. data/examples/text_box_styling.rb +0 -72
  121. data/test/hexapdf/type/test_embedded_file.rb +0 -16
  122. data/test/hexapdf/type/test_names.rb +0 -9
@@ -0,0 +1,125 @@
1
+ # ## Text Layouter - Styling
2
+ #
3
+ # The text used as part of a [HexaPDF::Layout::TextLayouter] class can be styled
4
+ # using [HexaPDF::Layout::Style]. To do this [HexaPDF::Layout::TextFragment]
5
+ # objects have to be created with the needed styling and then added to a text
6
+ # layout object. In addition the style objects can be used for customizing the
7
+ # text layouts themselves.
8
+ #
9
+ # This example shows how to do this and shows off the various styling option,
10
+ # including using callbacks to further customize the appearance.
11
+ #
12
+ # Usage:
13
+ # : `ruby text_layouter_styling.rb [FONT_FILE]`
14
+ #
15
+
16
+ require 'hexapdf'
17
+
18
+ include HexaPDF::Layout
19
+
20
+ sample_text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit,
21
+ sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
22
+ enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
23
+ aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit
24
+ in voluptate velit esse cillum dolore eu fugiat nulla pariatur.".tr("\n", ' ')
25
+
26
+ # Wraps the text in a TextFragment using the given style.
27
+ def fragment(text, style)
28
+ style = Style.new(style)
29
+ TextFragment.new(items: style.font.decode_utf8(text), style: style)
30
+ end
31
+
32
+ # Draws the text at the given [x, y] position onto the canvas and returns the
33
+ # new y position.
34
+ def draw_text(layouter, canvas, x, y)
35
+ rest, = layouter.fit
36
+ raise "Error" unless rest.empty?
37
+ layouter.draw(canvas, x, y)
38
+ y - layouter.actual_height
39
+ end
40
+
41
+ doc = HexaPDF::Document.new
42
+ canvas = doc.pages.add.canvas
43
+
44
+ base_font = doc.fonts.add(ARGV[0] || "Times")
45
+ base_style = {font: base_font, font_size: 12, text_indent: 20}
46
+ styles = {
47
+ "Fonts | Font Sizes | Colors" => [
48
+ {font: doc.fonts.add("Times", variant: :italic),
49
+ font_size: 12, fill_color: [0, 0, 255]},
50
+ {font: doc.fonts.add("Courier"), font_size: 14,
51
+ fill_color: [0, 255, 0]},
52
+ {font: doc.fonts.add("Helvetica", variant: :bold),
53
+ font_size: 20, fill_alpha: 0.5},
54
+ ],
55
+ "Character Spacing | Word Spacing | Horizontal Scaling" => [
56
+ {**base_style, character_spacing: 3},
57
+ {**base_style, horizontal_scaling: 150},
58
+ {**base_style, word_spacing: 15},
59
+ ],
60
+ "Text Rise" => [
61
+ {**base_style, text_rise: 5},
62
+ {**base_style, text_rise: -3},
63
+ ],
64
+ "Subscript | Superscript" => [
65
+ {**base_style, font_size: 15, subscript: true},
66
+ {**base_style, font_size: 15, superscript: true},
67
+ ],
68
+ "Underline | Strikeout" => [
69
+ {**base_style, underline: true, strikeout: true},
70
+ {**base_style, underline: true, strikeout: true, text_rise: 5},
71
+ {**base_style, underline: true, strikeout: true, subscript: true},
72
+ ],
73
+ "Text Rendering Mode" => [
74
+ {**base_style, text_rendering_mode: :stroke,
75
+ stroke_width: 0.1},
76
+ {**base_style, font_size: 20, text_rendering_mode: :fill_stroke,
77
+ stroke_color: [0, 255, 0], stroke_width: 0.7,
78
+ stroke_dash_pattern: [0.5, 1, 1.5], stroke_cap_style: :round},
79
+ ],
80
+ "Underlays | Overlays" => [
81
+ {**base_style, underlays: [lambda do |canv, box|
82
+ canv.fill_color(240, 240, 0).opacity(fill_alpha: 0.5).
83
+ rectangle(0, 0, box.width, box.height).fill
84
+ end]},
85
+ {**base_style, overlays: [lambda do |canv, box|
86
+ canv.line_width(1).stroke_color([0, 255, 0]).
87
+ line(0, -box.y_min, box.width, box.y_max - box.y_min).stroke
88
+ end]},
89
+ ],
90
+ "Links" => [
91
+ {**base_style, overlays: [
92
+ [:link, dest: [canvas.context, :FitR, 100, 300, 200, 400]],
93
+ ]},
94
+ {**base_style, overlays: [
95
+ [:link, uri: "https://hexapdf.gettalong.org",
96
+ border: [0, 0, 2, [3, 3]], border_color: [89, 150, 220]],
97
+ ]},
98
+ {**base_style, overlays: [
99
+ [:link, file: "text_layouter_styling.pdf", border: true],
100
+ ]},
101
+ ],
102
+ }
103
+
104
+ y = 800
105
+ left = 50
106
+ width = 500
107
+
108
+ styles.each do |desc, variations|
109
+ items = sample_text.split(/(Lorem ipsum dolor|\b\w{2,5}\b)/).map do |str|
110
+ if str.length >= 3 && str.length <= 5
111
+ fragment(str, variations[str.length % variations.length])
112
+ elsif str.length == 2
113
+ fragment(str, variations.first)
114
+ elsif str =~ /Lorem/
115
+ fragment(str, variations.last)
116
+ else
117
+ fragment(str, base_style)
118
+ end
119
+ end
120
+ items.unshift(fragment(desc + ": ", fill_color: [255, 0, 0], **base_style))
121
+ layouter = TextLayouter.new(items: items, width: width, style: base_style)
122
+ y = draw_text(layouter, canvas, left, y) - 20
123
+ end
124
+
125
+ doc.write("text_layouter_styling.pdf", optimize: true)
@@ -5,7 +5,8 @@
5
5
  # fonts.
6
6
  #
7
7
  # Before a TrueType font can be used, HexaPDF needs to be made aware of it. This
8
- # is done by setting the configuration option 'font.map'.
8
+ # is done by setting the configuration option 'font.map'. For one-off usage of a
9
+ # font file, the file name itself can also be used.
9
10
  #
10
11
  # Once that is done the [HexaPDF::Content::Canvas#font] method can be used as
11
12
  # usual.
@@ -17,11 +18,8 @@
17
18
  require 'hexapdf'
18
19
 
19
20
  doc = HexaPDF::Document.new
20
- doc.config['font.map'] = {
21
- 'myfont' => {none: ARGV.shift || File.join(__dir__, '../test/data/fonts/Ubuntu-Title.ttf')},
22
- }
23
-
24
- wrapper = doc.fonts.load('myfont')
21
+ font_file = ARGV.shift || File.join(__dir__, '../test/data/fonts/Ubuntu-Title.ttf')
22
+ wrapper = doc.fonts.add(font_file)
25
23
  max_gid = wrapper.wrapped_font[:maxp].num_glyphs
26
24
 
27
25
  255.times do |page|
@@ -30,7 +28,7 @@ max_gid = wrapper.wrapped_font[:maxp].num_glyphs
30
28
  canvas.font("Helvetica", size: 10)
31
29
  canvas.text("Font: #{wrapper.wrapped_font.full_name}", at: [50, 825])
32
30
 
33
- canvas.font("myfont", size: 15)
31
+ canvas.font(font_file, size: 15)
34
32
  16.times do |y|
35
33
  canvas.move_text_cursor(offset: [50, 800 - y * 50], absolute: true)
36
34
  canvas.show_glyphs((0..15).map do |i|
@@ -96,6 +96,7 @@ module HexaPDF
96
96
  # switches.
97
97
  def pdf_options(password)
98
98
  hash = {decryption_opts: {password: password}, config: {}}
99
+ HexaPDF::GlobalConfiguration['filter.predictor.strict'] = command_parser.strict
99
100
  hash[:config]['parser.on_correctable_error'] =
100
101
  if command_parser.strict
101
102
  proc { true }
@@ -84,35 +84,46 @@ module HexaPDF
84
84
  # object (or hash) and this configuration object.
85
85
  #
86
86
  # If a key already has a value in this object, its value is overwritten by the one from
87
- # +config+. However, hash values are merged instead of being overwritten.
87
+ # +config+. However, hash values are merged instead of being overwritten. Array values are
88
+ # duplicated.
88
89
  def merge(config)
89
90
  config = (config.kind_of?(self.class) ? config.options : config)
90
- self.class.new(options.merge(config) do |_key, old, new|
91
- old.kind_of?(Hash) && new.kind_of?(Hash) ? old.merge(new) : new
92
- end)
91
+ merged_config = options.each_with_object({}) do |(key, old), conf|
92
+ new = config[key]
93
+ conf[key] = if old.kind_of?(Hash) && new.kind_of?(Hash)
94
+ old.merge(new)
95
+ elsif new.kind_of?(Array) || old.kind_of?(Array)
96
+ (new || old).dup
97
+ elsif config.key?(key)
98
+ new
99
+ else
100
+ old
101
+ end
102
+ end
103
+ self.class.new(merged_config)
93
104
  end
94
105
 
95
106
  # :call-seq:
96
- # config.constantize(name, key = nil) -> constant
97
- # config.constantize(name, key = nil) {|name| block} -> obj
107
+ # config.constantize(name, *keys) -> constant
108
+ # config.constantize(name, *keys) {|name| block} -> obj
98
109
  #
99
- # Returns the constant the option +name+ is referring to. If +key+ is provided and the value
100
- # of the option +name+ responds to \#[], the constant to which +key+ refers is returned.
110
+ # Returns the constant the option +name+ is referring to. If +keys+ are provided and the value
111
+ # of the option +name+ responds to \#dig, the constant to which the keys refer is returned.
101
112
  #
102
113
  # If no constant can be found and no block is provided, an error is raised. If a block is
103
114
  # provided it is called with the option name and its result will be returned.
104
115
  #
105
116
  # config.constantize('encryption.aes') #=> HexaPDF::Encryption::FastAES
106
117
  # config.constantize('filter.map', :Fl) #=> HexaPDF::Filter::FlateDecode
107
- def constantize(name, key = :__unset)
118
+ def constantize(name, *keys)
108
119
  data = self[name]
109
- data = data[key] if key != :__unset && data.respond_to?(:[])
120
+ data = data.dig(*keys) if data.respond_to?(:dig)
110
121
  (data = ::Object.const_get(data) rescue nil) if data.kind_of?(String)
111
122
  if data.nil? && block_given?
112
123
  data = yield(name)
113
124
  elsif data.nil?
114
125
  raise HexaPDF::Error, "Error getting constant for configuration option '#{name}'" <<
115
- (key == :__unset ? "" : " and key '#{key}'")
126
+ (keys.empty? ? "" : " and keys '#{keys.join(', ')}'")
116
127
  end
117
128
  data
118
129
  end
@@ -141,6 +152,44 @@ module HexaPDF
141
152
  #
142
153
  # In nearly all cases this option should not be changed from its default setting!
143
154
  #
155
+ # encryption.aes::
156
+ # The class that should be used for AES encryption. If the value is a String, it should
157
+ # contain the name of a constant to such a class.
158
+ #
159
+ # See HexaPDF::Encryption::AES for the general interface such a class must conform to and
160
+ # HexaPDF::Encryption::RubyAES as well as HexaPDF::Encryption::FastAES for implementations.
161
+ #
162
+ # encryption.arc4::
163
+ # The class that should be used for ARC4 encryption. If the value is a String, it should
164
+ # contain the name of a constant to such a class.
165
+ #
166
+ # See HexaPDF::Encryption::ARC4 for the general interface such a class must conform to and
167
+ # HexaPDF::Encryption::RubyARC4 as well as HexaPDF::Encryption::FastARC4 for implementations.
168
+ #
169
+ # encryption.filter_map::
170
+ # A mapping from a PDF name (a Symbol) to a security handler class (see
171
+ # Encryption::SecurityHandler). If the value is a String, it should contain the name of a
172
+ # constant to such a class.
173
+ #
174
+ # PDF defines a standard security handler that is implemented
175
+ # (HexaPDF::Encryption::StandardSecurityHandler) and assigned the :Standard name.
176
+ #
177
+ # encryption.sub_filter_map::
178
+ # A mapping from a PDF name (a Symbol) to a security handler class (see
179
+ # HexaPDF::Encryption::SecurityHandler). If the value is a String, it should contain the name
180
+ # of a constant to such a class.
181
+ #
182
+ # The sub filter map is used when the security handler defined by the encryption dictionary
183
+ # is not available, but a compatible implementation is.
184
+ #
185
+ # filter.map::
186
+ # A mapping from a PDF name (a Symbol) to a filter object (see Filter). If the value is a
187
+ # String, it should contain the name of a constant that contains a filter object.
188
+ #
189
+ # The most often used filters are implemented and readily available.
190
+ #
191
+ # See PDF1.7 s7.4.1, ADB sH.3 3.3
192
+ #
144
193
  # font.map::
145
194
  # Defines a mapping from font names and variants to font files.
146
195
  #
@@ -197,6 +246,16 @@ module HexaPDF
197
246
  # to compute. It should not be set to values lower than 4, otherwise the approximation of a
198
247
  # complete ellipse is visibly false.
199
248
  #
249
+ # image_loader::
250
+ # An array with image loader implementations. When an image should be loaded, the array is
251
+ # iterated in sequence to find a suitable image loader.
252
+ #
253
+ # If a value is a String, it should contain the name of a constant that is an image loader
254
+ # object.
255
+ #
256
+ # See the HexaPDF::ImageLoader module for information on how to implement an image loader
257
+ # object.
258
+ #
200
259
  # image_loader.pdf.use_stringio::
201
260
  # A boolean determining whether images specified via file names should be read into memory
202
261
  # all at once using a StringIO object.
@@ -224,6 +283,11 @@ module HexaPDF
224
283
  # The value can either be a rectangle defining the paper size or a Symbol referencing one of
225
284
  # the predefined paper sizes.
226
285
  #
286
+ # page.default_media_orientation::
287
+ # The page orientation that is used for new pages that don't define a media box. It is only
288
+ # used if 'page.default_media_box' references a predefined paper size. Default value is
289
+ # :portrait. The other possible value is :landscape.
290
+ #
227
291
  # parser.on_correctable_error::
228
292
  # Callback hook when the parser encounters an error that can be corrected.
229
293
  #
@@ -232,8 +296,43 @@ module HexaPDF
232
296
  #
233
297
  # sorted_tree.max_leaf_node_size::
234
298
  # The maximum number of nodes that should be in a leaf node of a node tree.
299
+ #
300
+ # style.layers_map::
301
+ # A mapping from style layer names to layer objects.
302
+ #
303
+ # See HexaPDF::Layout::Style::Layers for more information.
304
+ #
305
+ # task.map::
306
+ # A mapping from task names to callable task objects. See HexaPDF::Task for more information.
235
307
  DefaultDocumentConfiguration =
236
308
  Configuration.new('document.auto_decrypt' => true,
309
+ 'encryption.aes' => 'HexaPDF::Encryption::FastAES',
310
+ 'encryption.arc4' => 'HexaPDF::Encryption::FastARC4',
311
+ 'encryption.filter_map' => {
312
+ Standard: 'HexaPDF::Encryption::StandardSecurityHandler',
313
+ },
314
+ 'encryption.sub_filter_map' => {
315
+ },
316
+ 'filter.map' => {
317
+ ASCIIHexDecode: 'HexaPDF::Filter::ASCIIHexDecode',
318
+ AHx: 'HexaPDF::Filter::ASCIIHexDecode',
319
+ ASCII85Decode: 'HexaPDF::Filter::ASCII85Decode',
320
+ A85: 'HexaPDF::Filter::ASCII85Decode',
321
+ LZWDecode: 'HexaPDF::Filter::LZWDecode',
322
+ LZW: 'HexaPDF::Filter::LZWDecode',
323
+ FlateDecode: 'HexaPDF::Filter::FlateDecode',
324
+ Fl: 'HexaPDF::Filter::FlateDecode',
325
+ RunLengthDecode: 'HexaPDF::Filter::RunLengthDecode',
326
+ RL: 'HexaPDF::Filter::RunLengthDecode',
327
+ CCITTFaxDecode: nil,
328
+ CCF: nil,
329
+ JBIG2Decode: nil,
330
+ DCTDecode: 'HexaPDF::Filter::DCTDecode',
331
+ DCT: 'HexaPDF::Filter::DCTDecode',
332
+ JPXDecode: 'HexaPDF::Filter::JPXDecode',
333
+ Crypt: nil,
334
+ Encryption: 'HexaPDF::Filter::Encryption',
335
+ },
237
336
  'font.map' => {},
238
337
  'font.on_missing_glyph' => proc do |char, _type, font|
239
338
  HexaPDF::Font::InvalidGlyph.new(font, char)
@@ -245,6 +344,7 @@ module HexaPDF
245
344
  'font_loader' => [
246
345
  'HexaPDF::FontLoader::Standard14',
247
346
  'HexaPDF::FontLoader::FromConfiguration',
347
+ 'HexaPDF::FontLoader::FromFile',
248
348
  ],
249
349
  'graphic_object.map' => {
250
350
  arc: 'HexaPDF::Content::GraphicObject::Arc',
@@ -252,11 +352,24 @@ module HexaPDF
252
352
  solid_arc: 'HexaPDF::Content::GraphicObject::SolidArc',
253
353
  },
254
354
  'graphic_object.arc.max_curves' => 6,
355
+ 'image_loader' => [
356
+ 'HexaPDF::ImageLoader::JPEG',
357
+ 'HexaPDF::ImageLoader::PNG',
358
+ 'HexaPDF::ImageLoader::PDF',
359
+ ],
255
360
  'image_loader.pdf.use_stringio' => true,
256
361
  'io.chunk_size' => 2**16,
257
362
  'page.default_media_box' => :A4,
363
+ 'page.default_media_orientation' => :portrait,
258
364
  'parser.on_correctable_error' => proc { false },
259
- 'sorted_tree.max_leaf_node_size' => 64)
365
+ 'sorted_tree.max_leaf_node_size' => 64,
366
+ 'style.layers_map' => {
367
+ link: 'HexaPDF::Layout::Style::LinkLayer',
368
+ },
369
+ 'task.map' => {
370
+ optimize: 'HexaPDF::Task::Optimize',
371
+ dereference: 'HexaPDF::Task::Dereference',
372
+ })
260
373
 
261
374
  # The global configuration object, providing the following options:
262
375
  #
@@ -269,36 +382,6 @@ module HexaPDF
269
382
  #
270
383
  # See PDF1.7 s8.6
271
384
  #
272
- # encryption.aes::
273
- # The class that should be used for AES encryption. If the value is a String, it should
274
- # contain the name of a constant to such a class.
275
- #
276
- # See HexaPDF::Encryption::AES for the general interface such a class must conform to and
277
- # HexaPDF::Encryption::RubyAES as well as HexaPDF::Encryption::FastAES for implementations.
278
- #
279
- # encryption.arc4::
280
- # The class that should be used for ARC4 encryption. If the value is a String, it should
281
- # contain the name of a constant to such a class.
282
- #
283
- # See HexaPDF::Encryption::ARC4 for the general interface such a class must conform to and
284
- # HexaPDF::Encryption::RubyARC4 as well as HexaPDF::Encryption::FastARC4 for implementations.
285
- #
286
- # encryption.filter_map::
287
- # A mapping from a PDF name (a Symbol) to a security handler class (see
288
- # Encryption::SecurityHandler). If the value is a String, it should contain the name of a
289
- # constant to such a class.
290
- #
291
- # PDF defines a standard security handler that is implemented
292
- # (HexaPDF::Encryption::StandardSecurityHandler) and assigned the :Standard name.
293
- #
294
- # encryption.sub_filter_map::
295
- # A mapping from a PDF name (a Symbol) to a security handler class (see
296
- # HexaPDF::Encryption::SecurityHandler). If the value is a String, it should contain the name
297
- # of a constant to such a class.
298
- #
299
- # The sub filter map is used when the security handler defined by the encryption dictionary
300
- # is not available, but a compatible implementation is.
301
- #
302
385
  # filter.flate_compression::
303
386
  # Specifies the compression level that should be used with the FlateDecode filter. The level
304
387
  # can range from 0 (no compression), 1 (best speed) to 9 (best compression, default).
@@ -310,23 +393,10 @@ module HexaPDF
310
393
  # The HexaPDF default value of 6 has been found in tests to be nearly equivalent to the Zlib
311
394
  # default of 8 in terms of speed and compression level but uses less memory.
312
395
  #
313
- # filter.map::
314
- # A mapping from a PDF name (a Symbol) to a filter object (see Filter). If the value is a
315
- # String, it should contain the name of a constant that contains a filter object.
316
- #
317
- # The most often used filters are implemented and readily available.
318
- #
319
- # See PDF1.7 s7.4.1, ADB sH.3 3.3
320
- #
321
- # image_loader::
322
- # An array with image loader implementations. When an image should be loaded, the array is
323
- # iterated in sequence to find a suitable image loader.
324
- #
325
- # If a value is a String, it should contain the name of a constant that is an image loader
326
- # object.
327
- #
328
- # See the HexaPDF::ImageLoader module for information on how to implement an image loader
329
- # object.
396
+ # filter.predictor.strict::
397
+ # Specifies whether the predictor algorithm used by LZWDecode and FlateDecode should operate in
398
+ # strict mode, i.e. adhering to the PDF specification without correcting for common deficiences
399
+ # of PDF writer libraries.
330
400
  #
331
401
  # object.type_map::
332
402
  # A mapping from a PDF name (a Symbol) to PDF object classes which is based on the /Type
@@ -343,49 +413,15 @@ module HexaPDF
343
413
  #
344
414
  # This mapping is used to provide automatic wrapping of objects in the HexaPDF::Document#wrap
345
415
  # method.
346
- #
347
- # task.map::
348
- # A mapping from task names to callable task objects. See HexaPDF::Task for more information.
349
416
  GlobalConfiguration =
350
- Configuration.new('encryption.aes' => 'HexaPDF::Encryption::FastAES',
351
- 'encryption.arc4' => 'HexaPDF::Encryption::FastARC4',
352
- 'encryption.filter_map' => {
353
- Standard: 'HexaPDF::Encryption::StandardSecurityHandler',
354
- },
355
- 'encryption.sub_filter_map' => {
356
- },
357
- 'filter.flate_compression' => 9,
417
+ Configuration.new('filter.flate_compression' => 9,
358
418
  'filter.flate_memory' => 6,
359
- 'filter.map' => {
360
- ASCIIHexDecode: 'HexaPDF::Filter::ASCIIHexDecode',
361
- AHx: 'HexaPDF::Filter::ASCIIHexDecode',
362
- ASCII85Decode: 'HexaPDF::Filter::ASCII85Decode',
363
- A85: 'HexaPDF::Filter::ASCII85Decode',
364
- LZWDecode: 'HexaPDF::Filter::LZWDecode',
365
- LZW: 'HexaPDF::Filter::LZWDecode',
366
- FlateDecode: 'HexaPDF::Filter::FlateDecode',
367
- Fl: 'HexaPDF::Filter::FlateDecode',
368
- RunLengthDecode: 'HexaPDF::Filter::RunLengthDecode',
369
- RL: 'HexaPDF::Filter::RunLengthDecode',
370
- CCITTFaxDecode: nil,
371
- CCF: nil,
372
- JBIG2Decode: nil,
373
- DCTDecode: 'HexaPDF::Filter::DCTDecode',
374
- DCT: 'HexaPDF::Filter::DCTDecode',
375
- JPXDecode: 'HexaPDF::Filter::JPXDecode',
376
- Crypt: nil,
377
- Encryption: 'HexaPDF::Filter::Encryption',
378
- },
419
+ 'filter.predictor.strict' => false,
379
420
  'color_space.map' => {
380
421
  DeviceRGB: 'HexaPDF::Content::ColorSpace::DeviceRGB',
381
422
  DeviceCMYK: 'HexaPDF::Content::ColorSpace::DeviceCMYK',
382
423
  DeviceGray: 'HexaPDF::Content::ColorSpace::DeviceGray',
383
424
  },
384
- 'image_loader' => [
385
- 'HexaPDF::ImageLoader::JPEG',
386
- 'HexaPDF::ImageLoader::PNG',
387
- 'HexaPDF::ImageLoader::PDF',
388
- ],
389
425
  'object.type_map' => {
390
426
  XRef: 'HexaPDF::Type::XRefStream',
391
427
  ObjStm: 'HexaPDF::Type::ObjectStream',
@@ -405,19 +441,47 @@ module HexaPDF
405
441
  XXResources: 'HexaPDF::Type::Resources',
406
442
  XXTrailer: 'HexaPDF::Type::Trailer',
407
443
  XXViewerPreferences: 'HexaPDF::Type::ViewerPreferences',
444
+ Action: 'HexaPDF::Type::Action',
445
+ XXLaunchActionWinParameters: 'HexaPDF::Type::Actions::Launch::WinParameters',
446
+ Annotation: 'HexaPDF::Type::Annotation',
408
447
  },
409
448
  'object.subtype_map' => {
410
- Image: 'HexaPDF::Type::Image',
411
- Form: 'HexaPDF::Type::Form',
412
- Type0: 'HexaPDF::Type::FontType0',
413
- Type1: 'HexaPDF::Type::FontType1',
414
- TrueType: 'HexaPDF::Type::FontTrueType',
415
- CIDFontType0: 'HexaPDF::Type::CIDFont',
416
- CIDFontType2: 'HexaPDF::Type::CIDFont',
417
- },
418
- 'task.map' => {
419
- optimize: 'HexaPDF::Task::Optimize',
420
- dereference: 'HexaPDF::Task::Dereference',
449
+ nil => {
450
+ Image: 'HexaPDF::Type::Image',
451
+ Form: 'HexaPDF::Type::Form',
452
+ Type0: 'HexaPDF::Type::FontType0',
453
+ Type1: 'HexaPDF::Type::FontType1',
454
+ TrueType: 'HexaPDF::Type::FontTrueType',
455
+ CIDFontType0: 'HexaPDF::Type::CIDFont',
456
+ CIDFontType2: 'HexaPDF::Type::CIDFont',
457
+ GoTo: 'HexaPDF::Type::Actions::GoTo',
458
+ GoToR: 'HexaPDF::Type::Actions::GoToR',
459
+ Launch: 'HexaPDF::Type::Actions::Launch',
460
+ URI: 'HexaPDF::Type::Actions::URI',
461
+ Text: 'HexaPDF::Type::Annotations::Text',
462
+ Link: 'HexaPDF::Type::Annotations::Link',
463
+ },
464
+ XObject: {
465
+ Image: 'HexaPDF::Type::Image',
466
+ Form: 'HexaPDF::Type::Form',
467
+ },
468
+ Font: {
469
+ Type0: 'HexaPDF::Type::FontType0',
470
+ Type1: 'HexaPDF::Type::FontType1',
471
+ TrueType: 'HexaPDF::Type::FontTrueType',
472
+ CIDFontType0: 'HexaPDF::Type::CIDFont',
473
+ CIDFontType2: 'HexaPDF::Type::CIDFont',
474
+ },
475
+ Action: {
476
+ GoTo: 'HexaPDF::Type::Actions::GoTo',
477
+ GoToR: 'HexaPDF::Type::Actions::GoToR',
478
+ Launch: 'HexaPDF::Type::Actions::Launch',
479
+ URI: 'HexaPDF::Type::Actions::URI',
480
+ },
481
+ Annotation: {
482
+ Text: 'HexaPDF::Type::Annotations::Text',
483
+ Link: 'HexaPDF::Type::Annotations::Link',
484
+ },
421
485
  })
422
486
 
423
487
  end