hexapdf 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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