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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +76 -2
- data/CONTRIBUTERS +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/examples/boxes.rb +68 -0
- data/examples/graphics.rb +12 -12
- data/examples/{text_box_alignment.rb → text_layouter_alignment.rb} +14 -14
- data/examples/text_layouter_inline_boxes.rb +66 -0
- data/examples/{text_box_line_wrapping.rb → text_layouter_line_wrapping.rb} +9 -10
- data/examples/{text_box_shapes.rb → text_layouter_shapes.rb} +58 -54
- data/examples/text_layouter_styling.rb +125 -0
- data/examples/truetype.rb +5 -7
- data/lib/hexapdf/cli/command.rb +1 -0
- data/lib/hexapdf/configuration.rb +170 -106
- data/lib/hexapdf/content/canvas.rb +41 -36
- data/lib/hexapdf/content/graphics_state.rb +15 -0
- data/lib/hexapdf/content/operator.rb +1 -1
- data/lib/hexapdf/dictionary.rb +20 -8
- data/lib/hexapdf/dictionary_fields.rb +8 -6
- data/lib/hexapdf/document.rb +25 -26
- data/lib/hexapdf/document/fonts.rb +4 -4
- data/lib/hexapdf/document/images.rb +2 -2
- data/lib/hexapdf/document/pages.rb +16 -16
- data/lib/hexapdf/encryption/security_handler.rb +41 -9
- data/lib/hexapdf/filter/flate_decode.rb +1 -1
- data/lib/hexapdf/filter/lzw_decode.rb +1 -1
- data/lib/hexapdf/filter/predictor.rb +7 -1
- data/lib/hexapdf/font/true_type/font.rb +20 -0
- data/lib/hexapdf/font/type1/font.rb +23 -0
- data/lib/hexapdf/font_loader.rb +1 -0
- data/lib/hexapdf/font_loader/from_configuration.rb +2 -3
- data/lib/hexapdf/font_loader/from_file.rb +65 -0
- data/lib/hexapdf/image_loader/png.rb +2 -2
- data/lib/hexapdf/layout.rb +3 -2
- data/lib/hexapdf/layout/box.rb +146 -0
- data/lib/hexapdf/layout/inline_box.rb +40 -31
- data/lib/hexapdf/layout/{line_fragment.rb → line.rb} +12 -13
- data/lib/hexapdf/layout/style.rb +630 -41
- data/lib/hexapdf/layout/text_fragment.rb +80 -12
- data/lib/hexapdf/layout/{text_box.rb → text_layouter.rb} +164 -109
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/parser.rb +4 -1
- data/lib/hexapdf/revisions.rb +11 -4
- data/lib/hexapdf/stream.rb +8 -9
- data/lib/hexapdf/tokenizer.rb +5 -3
- data/lib/hexapdf/type.rb +3 -0
- data/lib/hexapdf/type/action.rb +56 -0
- data/lib/hexapdf/type/actions.rb +52 -0
- data/lib/hexapdf/type/actions/go_to.rb +52 -0
- data/lib/hexapdf/type/actions/go_to_r.rb +54 -0
- data/lib/hexapdf/type/actions/launch.rb +73 -0
- data/lib/hexapdf/type/actions/uri.rb +65 -0
- data/lib/hexapdf/type/annotation.rb +85 -0
- data/lib/hexapdf/type/annotations.rb +51 -0
- data/lib/hexapdf/type/annotations/link.rb +70 -0
- data/lib/hexapdf/type/annotations/markup_annotation.rb +70 -0
- data/lib/hexapdf/type/annotations/text.rb +81 -0
- data/lib/hexapdf/type/catalog.rb +3 -1
- data/lib/hexapdf/type/embedded_file.rb +6 -11
- data/lib/hexapdf/type/file_specification.rb +4 -6
- data/lib/hexapdf/type/font.rb +3 -1
- data/lib/hexapdf/type/font_descriptor.rb +18 -16
- data/lib/hexapdf/type/form.rb +3 -1
- data/lib/hexapdf/type/graphics_state_parameter.rb +3 -1
- data/lib/hexapdf/type/image.rb +4 -2
- data/lib/hexapdf/type/info.rb +2 -5
- data/lib/hexapdf/type/names.rb +2 -5
- data/lib/hexapdf/type/object_stream.rb +2 -1
- data/lib/hexapdf/type/page.rb +14 -1
- data/lib/hexapdf/type/page_tree_node.rb +9 -6
- data/lib/hexapdf/type/resources.rb +2 -5
- data/lib/hexapdf/type/trailer.rb +2 -5
- data/lib/hexapdf/type/viewer_preferences.rb +2 -5
- data/lib/hexapdf/type/xref_stream.rb +3 -1
- data/lib/hexapdf/version.rb +1 -1
- data/test/hexapdf/common_tokenizer_tests.rb +3 -1
- data/test/hexapdf/content/test_canvas.rb +29 -3
- data/test/hexapdf/content/test_graphics_state.rb +11 -0
- data/test/hexapdf/content/test_operator.rb +3 -2
- data/test/hexapdf/document/test_fonts.rb +8 -8
- data/test/hexapdf/document/test_images.rb +4 -12
- data/test/hexapdf/document/test_pages.rb +7 -7
- data/test/hexapdf/encryption/test_security_handler.rb +1 -5
- data/test/hexapdf/filter/test_predictor.rb +40 -12
- data/test/hexapdf/font/true_type/test_font.rb +16 -0
- data/test/hexapdf/font/type1/test_font.rb +30 -0
- data/test/hexapdf/font_loader/test_from_file.rb +29 -0
- data/test/hexapdf/font_loader/test_standard14.rb +4 -3
- data/test/hexapdf/layout/test_box.rb +104 -0
- data/test/hexapdf/layout/test_inline_box.rb +24 -10
- data/test/hexapdf/layout/{test_line_fragment.rb → test_line.rb} +9 -9
- data/test/hexapdf/layout/test_style.rb +519 -31
- data/test/hexapdf/layout/test_text_fragment.rb +136 -15
- data/test/hexapdf/layout/{test_text_box.rb → test_text_layouter.rb} +224 -144
- data/test/hexapdf/layout/test_text_shaper.rb +1 -1
- data/test/hexapdf/test_configuration.rb +12 -6
- data/test/hexapdf/test_dictionary.rb +27 -2
- data/test/hexapdf/test_dictionary_fields.rb +10 -1
- data/test/hexapdf/test_document.rb +14 -13
- data/test/hexapdf/test_parser.rb +12 -0
- data/test/hexapdf/test_revisions.rb +34 -0
- data/test/hexapdf/test_stream.rb +1 -1
- data/test/hexapdf/test_type.rb +18 -0
- data/test/hexapdf/test_writer.rb +2 -2
- data/test/hexapdf/type/actions/test_launch.rb +24 -0
- data/test/hexapdf/type/actions/test_uri.rb +23 -0
- data/test/hexapdf/type/annotations/test_link.rb +19 -0
- data/test/hexapdf/type/annotations/test_markup_annotation.rb +22 -0
- data/test/hexapdf/type/annotations/test_text.rb +38 -0
- data/test/hexapdf/type/test_annotation.rb +38 -0
- data/test/hexapdf/type/test_file_specification.rb +0 -7
- data/test/hexapdf/type/test_info.rb +0 -5
- data/test/hexapdf/type/test_page.rb +14 -0
- data/test/hexapdf/type/test_page_tree_node.rb +4 -1
- data/test/hexapdf/type/test_trailer.rb +0 -4
- data/test/test_helper.rb +6 -3
- metadata +36 -15
- data/examples/text_box_inline_boxes.rb +0 -56
- data/examples/text_box_styling.rb +0 -72
- data/test/hexapdf/type/test_embedded_file.rb +0 -16
- 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)
|
data/examples/truetype.rb
CHANGED
|
@@ -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
|
-
|
|
21
|
-
|
|
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(
|
|
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|
|
data/lib/hexapdf/cli/command.rb
CHANGED
|
@@ -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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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,
|
|
97
|
-
# config.constantize(name,
|
|
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 +
|
|
100
|
-
# of the option +name+ responds to \#
|
|
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,
|
|
118
|
+
def constantize(name, *keys)
|
|
108
119
|
data = self[name]
|
|
109
|
-
data = data
|
|
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
|
-
(
|
|
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.
|
|
314
|
-
#
|
|
315
|
-
#
|
|
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('
|
|
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.
|
|
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
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
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
|