hexapdf 0.32.2 → 0.34.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +104 -1
- data/README.md +9 -0
- data/examples/002-graphics.rb +15 -17
- data/examples/003-arcs.rb +9 -9
- data/examples/009-text_layouter_alignment.rb +1 -1
- data/examples/010-text_layouter_inline_boxes.rb +2 -2
- data/examples/011-text_layouter_line_wrapping.rb +1 -1
- data/examples/012-text_layouter_styling.rb +7 -7
- data/examples/013-text_layouter_shapes.rb +1 -1
- data/examples/014-text_in_polygon.rb +1 -1
- data/examples/015-boxes.rb +8 -7
- data/examples/016-frame_automatic_box_placement.rb +2 -2
- data/examples/017-frame_text_flow.rb +2 -1
- data/examples/018-composer.rb +1 -1
- data/examples/020-column_box.rb +2 -1
- data/examples/025-table_box.rb +46 -0
- data/examples/026-optional_content.rb +55 -0
- data/examples/027-composer_optional_content.rb +83 -0
- data/lib/hexapdf/cli/command.rb +12 -3
- data/lib/hexapdf/cli/fonts.rb +1 -1
- data/lib/hexapdf/cli/form.rb +5 -5
- data/lib/hexapdf/cli/inspect.rb +5 -7
- data/lib/hexapdf/composer.rb +106 -53
- data/lib/hexapdf/configuration.rb +65 -40
- data/lib/hexapdf/content/canvas.rb +445 -267
- data/lib/hexapdf/content/color_space.rb +72 -25
- data/lib/hexapdf/content/graphic_object/arc.rb +57 -24
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +66 -23
- data/lib/hexapdf/content/graphic_object/geom2d.rb +47 -6
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +58 -36
- data/lib/hexapdf/content/graphic_object.rb +6 -7
- data/lib/hexapdf/content/graphics_state.rb +54 -45
- data/lib/hexapdf/content/operator.rb +54 -54
- data/lib/hexapdf/content/parser.rb +2 -2
- data/lib/hexapdf/content/processor.rb +15 -15
- data/lib/hexapdf/content/transformation_matrix.rb +1 -1
- data/lib/hexapdf/content.rb +5 -0
- data/lib/hexapdf/dictionary.rb +7 -5
- data/lib/hexapdf/dictionary_fields.rb +43 -16
- data/lib/hexapdf/digital_signature/cms_handler.rb +2 -2
- data/lib/hexapdf/digital_signature/handler.rb +1 -1
- data/lib/hexapdf/digital_signature/pkcs1_handler.rb +2 -3
- data/lib/hexapdf/digital_signature/signature.rb +6 -6
- data/lib/hexapdf/digital_signature/signatures.rb +13 -12
- data/lib/hexapdf/digital_signature/signing/default_handler.rb +14 -5
- data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +2 -4
- data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +4 -4
- data/lib/hexapdf/digital_signature/signing.rb +4 -0
- data/lib/hexapdf/digital_signature/verification_result.rb +3 -4
- data/lib/hexapdf/digital_signature.rb +7 -2
- data/lib/hexapdf/document/destinations.rb +12 -11
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/layout.rb +170 -39
- data/lib/hexapdf/document/pages.rb +4 -3
- data/lib/hexapdf/document.rb +96 -55
- data/lib/hexapdf/encryption/aes.rb +5 -5
- data/lib/hexapdf/encryption/arc4.rb +1 -1
- data/lib/hexapdf/encryption/fast_aes.rb +2 -2
- data/lib/hexapdf/encryption/fast_arc4.rb +1 -1
- data/lib/hexapdf/encryption/identity.rb +1 -1
- data/lib/hexapdf/encryption/ruby_aes.rb +11 -21
- data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
- data/lib/hexapdf/encryption/security_handler.rb +31 -24
- data/lib/hexapdf/encryption/standard_security_handler.rb +45 -36
- data/lib/hexapdf/encryption.rb +7 -2
- data/lib/hexapdf/error.rb +18 -0
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
- data/lib/hexapdf/filter/flate_decode.rb +1 -1
- data/lib/hexapdf/filter/lzw_decode.rb +1 -1
- data/lib/hexapdf/filter/pass_through.rb +1 -1
- data/lib/hexapdf/filter/predictor.rb +1 -1
- data/lib/hexapdf/filter/run_length_decode.rb +1 -1
- data/lib/hexapdf/filter.rb +55 -6
- data/lib/hexapdf/font/cmap/parser.rb +2 -2
- data/lib/hexapdf/font/cmap.rb +1 -1
- data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +3 -3
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
- data/lib/hexapdf/font/invalid_glyph.rb +3 -0
- data/lib/hexapdf/font/true_type_wrapper.rb +17 -4
- data/lib/hexapdf/font/type1_wrapper.rb +19 -4
- data/lib/hexapdf/font_loader/from_configuration.rb +5 -2
- data/lib/hexapdf/font_loader/from_file.rb +5 -5
- data/lib/hexapdf/font_loader/standard14.rb +3 -3
- data/lib/hexapdf/font_loader.rb +3 -0
- data/lib/hexapdf/image_loader/jpeg.rb +2 -2
- data/lib/hexapdf/image_loader/pdf.rb +1 -1
- data/lib/hexapdf/image_loader/png.rb +2 -2
- data/lib/hexapdf/image_loader.rb +1 -1
- data/lib/hexapdf/importer.rb +13 -0
- data/lib/hexapdf/layout/box.rb +32 -5
- data/lib/hexapdf/layout/box_fitter.rb +2 -2
- data/lib/hexapdf/layout/column_box.rb +20 -5
- data/lib/hexapdf/layout/frame.rb +53 -18
- data/lib/hexapdf/layout/image_box.rb +5 -0
- data/lib/hexapdf/layout/inline_box.rb +21 -9
- data/lib/hexapdf/layout/list_box.rb +50 -20
- data/lib/hexapdf/layout/page_style.rb +6 -5
- data/lib/hexapdf/layout/style.rb +64 -9
- data/lib/hexapdf/layout/table_box.rb +684 -0
- data/lib/hexapdf/layout/text_box.rb +12 -3
- data/lib/hexapdf/layout/text_fragment.rb +29 -3
- data/lib/hexapdf/layout/text_layouter.rb +32 -8
- data/lib/hexapdf/layout.rb +1 -0
- data/lib/hexapdf/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +18 -7
- data/lib/hexapdf/parser.rb +7 -7
- data/lib/hexapdf/pdf_array.rb +1 -1
- data/lib/hexapdf/rectangle.rb +1 -1
- data/lib/hexapdf/reference.rb +1 -1
- data/lib/hexapdf/revision.rb +1 -1
- data/lib/hexapdf/revisions.rb +3 -3
- data/lib/hexapdf/serializer.rb +15 -15
- data/lib/hexapdf/stream.rb +5 -4
- data/lib/hexapdf/tokenizer.rb +14 -14
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +22 -22
- data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/field.rb +2 -2
- data/lib/hexapdf/type/acro_form/form.rb +1 -1
- data/lib/hexapdf/type/acro_form/signature_field.rb +4 -4
- data/lib/hexapdf/type/acro_form/text_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/variable_text_field.rb +1 -1
- data/lib/hexapdf/type/acro_form.rb +1 -1
- data/lib/hexapdf/type/action.rb +1 -1
- data/lib/hexapdf/type/actions/go_to.rb +1 -1
- data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
- data/lib/hexapdf/type/actions/launch.rb +1 -1
- data/lib/hexapdf/type/actions/set_ocg_state.rb +86 -0
- data/lib/hexapdf/type/actions/uri.rb +1 -1
- data/lib/hexapdf/type/actions.rb +2 -1
- data/lib/hexapdf/type/annotation.rb +3 -3
- data/lib/hexapdf/type/annotations/link.rb +1 -1
- data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
- data/lib/hexapdf/type/annotations/text.rb +2 -3
- data/lib/hexapdf/type/annotations/widget.rb +2 -2
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/catalog.rb +11 -2
- data/lib/hexapdf/type/cid_font.rb +18 -4
- data/lib/hexapdf/type/embedded_file.rb +1 -1
- data/lib/hexapdf/type/file_specification.rb +2 -2
- data/lib/hexapdf/type/font_descriptor.rb +1 -1
- data/lib/hexapdf/type/font_simple.rb +2 -2
- data/lib/hexapdf/type/font_type0.rb +3 -3
- data/lib/hexapdf/type/font_type3.rb +1 -1
- data/lib/hexapdf/type/form.rb +76 -6
- data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
- data/lib/hexapdf/type/icon_fit.rb +1 -1
- data/lib/hexapdf/type/image.rb +1 -1
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/mark_information.rb +1 -1
- data/lib/hexapdf/type/names.rb +2 -2
- data/lib/hexapdf/type/object_stream.rb +2 -1
- data/lib/hexapdf/type/optional_content_configuration.rb +170 -0
- data/lib/hexapdf/type/optional_content_group.rb +370 -0
- data/lib/hexapdf/type/optional_content_membership.rb +63 -0
- data/lib/hexapdf/type/optional_content_properties.rb +158 -0
- data/lib/hexapdf/type/outline.rb +1 -1
- data/lib/hexapdf/type/outline_item.rb +1 -1
- data/lib/hexapdf/type/page.rb +46 -21
- data/lib/hexapdf/type/page_label.rb +5 -9
- data/lib/hexapdf/type/page_tree_node.rb +1 -1
- data/lib/hexapdf/type/resources.rb +1 -1
- data/lib/hexapdf/type/trailer.rb +2 -2
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +2 -2
- data/lib/hexapdf/type.rb +4 -0
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -2
- data/lib/hexapdf/version.rb +1 -1
- data/lib/hexapdf/writer.rb +4 -4
- data/lib/hexapdf/xref_section.rb +2 -2
- data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +11 -1
- data/test/hexapdf/content/graphic_object/test_geom2d.rb +7 -0
- data/test/hexapdf/content/test_canvas.rb +49 -1
- data/test/hexapdf/digital_signature/test_signatures.rb +22 -0
- data/test/hexapdf/document/test_files.rb +2 -2
- data/test/hexapdf/document/test_layout.rb +105 -2
- data/test/hexapdf/document/test_pages.rb +6 -6
- data/test/hexapdf/encryption/test_security_handler.rb +12 -11
- data/test/hexapdf/encryption/test_standard_security_handler.rb +35 -23
- data/test/hexapdf/font/test_true_type_wrapper.rb +18 -1
- data/test/hexapdf/font/test_type1_wrapper.rb +15 -1
- data/test/hexapdf/layout/test_box.rb +14 -5
- data/test/hexapdf/layout/test_column_box.rb +65 -21
- data/test/hexapdf/layout/test_frame.rb +27 -15
- data/test/hexapdf/layout/test_image_box.rb +4 -0
- data/test/hexapdf/layout/test_inline_box.rb +17 -3
- data/test/hexapdf/layout/test_list_box.rb +84 -33
- data/test/hexapdf/layout/test_page_style.rb +3 -2
- data/test/hexapdf/layout/test_style.rb +60 -0
- data/test/hexapdf/layout/test_table_box.rb +728 -0
- data/test/hexapdf/layout/test_text_box.rb +26 -0
- data/test/hexapdf/layout/test_text_fragment.rb +33 -0
- data/test/hexapdf/layout/test_text_layouter.rb +36 -5
- data/test/hexapdf/test_composer.rb +10 -0
- data/test/hexapdf/test_dictionary.rb +10 -0
- data/test/hexapdf/test_dictionary_fields.rb +4 -1
- data/test/hexapdf/test_document.rb +5 -0
- data/test/hexapdf/test_filter.rb +8 -0
- data/test/hexapdf/test_importer.rb +9 -0
- data/test/hexapdf/test_object.rb +16 -5
- data/test/hexapdf/test_stream.rb +7 -0
- data/test/hexapdf/test_writer.rb +3 -3
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +13 -5
- data/test/hexapdf/type/acro_form/test_form.rb +4 -3
- data/test/hexapdf/type/actions/test_set_ocg_state.rb +40 -0
- data/test/hexapdf/type/test_catalog.rb +11 -0
- data/test/hexapdf/type/test_form.rb +119 -0
- data/test/hexapdf/type/test_optional_content_configuration.rb +112 -0
- data/test/hexapdf/type/test_optional_content_group.rb +158 -0
- data/test/hexapdf/type/test_optional_content_properties.rb +109 -0
- data/test/hexapdf/type/test_page.rb +20 -6
- metadata +28 -8
@@ -6,7 +6,9 @@ require 'hexapdf/layout/list_box'
|
|
6
6
|
|
7
7
|
describe HexaPDF::Layout::ListBox do
|
8
8
|
before do
|
9
|
-
@
|
9
|
+
@doc = HexaPDF::Document.new
|
10
|
+
@page = @doc.pages.add
|
11
|
+
@frame = HexaPDF::Layout::Frame.new(0, 0, 100, 100, context: @page)
|
10
12
|
inline_box = HexaPDF::Layout::InlineBox.create(width: 10, height: 10) {}
|
11
13
|
@text_boxes = 5.times.map do
|
12
14
|
HexaPDF::Layout::TextBox.new(items: [inline_box] * 15, style: {position: :default})
|
@@ -18,13 +20,13 @@ describe HexaPDF::Layout::ListBox do
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def check_box(box, width, height, fit_pos = nil)
|
21
|
-
assert(box.fit(@frame.available_width, @frame.available_height, @frame), "box fit
|
23
|
+
assert(box.fit(@frame.available_width, @frame.available_height, @frame), "box didn't fit")
|
22
24
|
assert_equal(width, box.width, "box width")
|
23
25
|
assert_equal(height, box.height, "box height")
|
24
26
|
if fit_pos
|
25
27
|
results = box.instance_variable_get(:@results)
|
26
|
-
results.each_with_index do |
|
27
|
-
box_fitter.fit_results.each_with_index do |fit_result, result_index|
|
28
|
+
results.each_with_index do |item_result, item_index|
|
29
|
+
item_result.box_fitter.fit_results.each_with_index do |fit_result, result_index|
|
28
30
|
x, y = fit_pos.shift
|
29
31
|
assert_equal(x, fit_result.x, "item #{item_index}, result #{result_index}, x")
|
30
32
|
assert_equal(y, fit_result.y, "item #{item_index}, result #{result_index}, y")
|
@@ -47,6 +49,18 @@ describe HexaPDF::Layout::ListBox do
|
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
52
|
+
describe "empty?" do
|
53
|
+
it "is empty if nothing was fit yet" do
|
54
|
+
assert(create_box.empty?)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "is empty if nothing could be fit" do
|
58
|
+
box = create_box(children: [@text_boxes[0]], width: 5)
|
59
|
+
box.fit(@frame.available_width, @frame.available_height, @frame)
|
60
|
+
assert(box.empty?)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
50
64
|
describe "fit" do
|
51
65
|
[:default, :flow].each do |position|
|
52
66
|
it "respects the set initial width, position #{position}" do
|
@@ -78,6 +92,12 @@ describe HexaPDF::Layout::ListBox do
|
|
78
92
|
check_box(box, 100, 90, [[10, 80], [10, 60], [10, 40], [50, 10]])
|
79
93
|
end
|
80
94
|
|
95
|
+
it "calculates the correct height if the marker is higher than the content" do
|
96
|
+
box = create_box(children: @text_boxes[0, 1], content_indentation: 20,
|
97
|
+
style: {font_size: 30})
|
98
|
+
check_box(box, 100, 27, [[20, 80]])
|
99
|
+
end
|
100
|
+
|
81
101
|
it "respects the content indentation" do
|
82
102
|
box = create_box(children: @text_boxes[0, 1], content_indentation: 30)
|
83
103
|
check_box(box, 100, 30, [[30, 70]])
|
@@ -87,6 +107,11 @@ describe HexaPDF::Layout::ListBox do
|
|
87
107
|
box = create_box(children: @text_boxes[0, 2], item_spacing: 30)
|
88
108
|
check_box(box, 100, 70, [[10, 80], [10, 30]])
|
89
109
|
end
|
110
|
+
|
111
|
+
it "fails for unknown item types" do
|
112
|
+
box = create_box(children: @text_boxes[0, 1], item_type: :unknown)
|
113
|
+
assert_raises(HexaPDF::Error) { box.fit(100, 100, @frame) }
|
114
|
+
end
|
90
115
|
end
|
91
116
|
|
92
117
|
describe "split" do
|
@@ -96,7 +121,7 @@ describe HexaPDF::Layout::ListBox do
|
|
96
121
|
box_a, box_b = box.split(100, 100, @frame)
|
97
122
|
assert_same(box, box_a)
|
98
123
|
assert_equal(:show_first_marker, box_b.split_box?)
|
99
|
-
assert_equal(1, box_a.instance_variable_get(:@results)[0].fit_results.size)
|
124
|
+
assert_equal(1, box_a.instance_variable_get(:@results)[0].box_fitter.fit_results.size)
|
100
125
|
assert_equal(1, box_b.children.size)
|
101
126
|
assert_equal(2, box_b.start_number)
|
102
127
|
end
|
@@ -107,7 +132,7 @@ describe HexaPDF::Layout::ListBox do
|
|
107
132
|
box_a, box_b = box.split(100, 100, @frame)
|
108
133
|
assert_same(box, box_a)
|
109
134
|
assert_equal(:hide_first_marker, box_b.split_box?)
|
110
|
-
assert_equal(1, box_a.instance_variable_get(:@results)[0].fit_results.size)
|
135
|
+
assert_equal(1, box_a.instance_variable_get(:@results)[0].box_fitter.fit_results.size)
|
111
136
|
assert_equal(2, box_b.children.size)
|
112
137
|
assert_equal(1, box_b.start_number)
|
113
138
|
end
|
@@ -115,20 +140,22 @@ describe HexaPDF::Layout::ListBox do
|
|
115
140
|
|
116
141
|
describe "draw" do
|
117
142
|
before do
|
118
|
-
@canvas =
|
143
|
+
@canvas = @page.canvas
|
119
144
|
draw_block = lambda {|canvas, box| }
|
120
145
|
@fixed_size_boxes = 5.times.map { HexaPDF::Layout::Box.new(width: 20, height: 10, &draw_block) }
|
121
146
|
end
|
122
147
|
|
123
148
|
it "draws the result" do
|
124
|
-
box = create_box(children: @fixed_size_boxes[0, 2]
|
149
|
+
box = create_box(children: @fixed_size_boxes[0, 2],
|
150
|
+
style: {font_size: 11, fill_color: 0.5})
|
125
151
|
box.fit(100, 100, @frame)
|
126
|
-
box.draw(@canvas, 0,
|
152
|
+
box.draw(@canvas, 0, 100 - box.height)
|
127
153
|
operators = [
|
128
154
|
[:save_graphics_state],
|
129
|
-
[:set_font_and_size, [:F1,
|
155
|
+
[:set_font_and_size, [:F1, 11]],
|
156
|
+
[:set_device_gray_non_stroking_color, [0.5]],
|
130
157
|
[:begin_text],
|
131
|
-
[:set_text_matrix, [1, 0, 0, 1, 1.
|
158
|
+
[:set_text_matrix, [1, 0, 0, 1, 1.15, 92.487]],
|
132
159
|
[:show_text, ["\x95".b]],
|
133
160
|
[:end_text],
|
134
161
|
[:restore_graphics_state],
|
@@ -137,9 +164,10 @@ describe HexaPDF::Layout::ListBox do
|
|
137
164
|
[:restore_graphics_state],
|
138
165
|
|
139
166
|
[:save_graphics_state],
|
140
|
-
[:set_font_and_size, [:F1,
|
167
|
+
[:set_font_and_size, [:F1, 11]],
|
168
|
+
[:set_device_gray_non_stroking_color, [0.5]],
|
141
169
|
[:begin_text],
|
142
|
-
[:set_text_matrix, [1, 0, 0, 1, 1.
|
170
|
+
[:set_text_matrix, [1, 0, 0, 1, 1.15, 82.487]],
|
143
171
|
[:show_text, ["\x95".b]],
|
144
172
|
[:end_text],
|
145
173
|
[:restore_graphics_state],
|
@@ -150,16 +178,18 @@ describe HexaPDF::Layout::ListBox do
|
|
150
178
|
assert_operators(@canvas.contents, operators)
|
151
179
|
end
|
152
180
|
|
153
|
-
it "draws a
|
154
|
-
box = create_box(children: @fixed_size_boxes[0, 1], item_type: :circle
|
181
|
+
it "draws a circle as marker" do
|
182
|
+
box = create_box(children: @fixed_size_boxes[0, 1], item_type: :circle,
|
183
|
+
style: {font_size: 11, fill_color: 0.5})
|
155
184
|
box.fit(100, 100, @frame)
|
156
|
-
box.draw(@canvas, 0,
|
185
|
+
box.draw(@canvas, 0, 100 - box.height)
|
157
186
|
operators = [
|
158
187
|
[:save_graphics_state],
|
159
|
-
[:set_font_and_size, [:F1, 5]],
|
160
|
-
[:set_text_rise, [-
|
188
|
+
[:set_font_and_size, [:F1, 5.5]],
|
189
|
+
[:set_text_rise, [-6.111111]],
|
190
|
+
[:set_device_gray_non_stroking_color, [0.5]],
|
161
191
|
[:begin_text],
|
162
|
-
[:set_text_matrix, [1, 0, 0, 1, 0.
|
192
|
+
[:set_text_matrix, [1, 0, 0, 1, 0.1985, 100]],
|
163
193
|
[:show_text, ["m".b]],
|
164
194
|
[:end_text],
|
165
195
|
[:restore_graphics_state],
|
@@ -171,15 +201,17 @@ describe HexaPDF::Layout::ListBox do
|
|
171
201
|
end
|
172
202
|
|
173
203
|
it "draws a square as marker" do
|
174
|
-
box = create_box(children: @fixed_size_boxes[0, 1], item_type: :square
|
204
|
+
box = create_box(children: @fixed_size_boxes[0, 1], item_type: :square,
|
205
|
+
style: {font_size: 11, fill_color: 0.5})
|
175
206
|
box.fit(100, 100, @frame)
|
176
|
-
box.draw(@canvas, 0,
|
207
|
+
box.draw(@canvas, 0, 100 - box.height)
|
177
208
|
operators = [
|
178
209
|
[:save_graphics_state],
|
179
|
-
[:set_font_and_size, [:F1, 5]],
|
180
|
-
[:set_text_rise, [-
|
210
|
+
[:set_font_and_size, [:F1, 5.5]],
|
211
|
+
[:set_text_rise, [-6.111111]],
|
212
|
+
[:set_device_gray_non_stroking_color, [0.5]],
|
181
213
|
[:begin_text],
|
182
|
-
[:set_text_matrix, [1, 0, 0, 1,
|
214
|
+
[:set_text_matrix, [1, 0, 0, 1, 0.8145, 100]],
|
183
215
|
[:show_text, ["n".b]],
|
184
216
|
[:end_text],
|
185
217
|
[:restore_graphics_state],
|
@@ -192,14 +224,16 @@ describe HexaPDF::Layout::ListBox do
|
|
192
224
|
|
193
225
|
it "draws decimal numbers as marker" do
|
194
226
|
box = create_box(children: @fixed_size_boxes[0, 2], item_type: :decimal,
|
227
|
+
style: {font_size: 11, fill_color: 0.5},
|
195
228
|
content_indentation: 20)
|
196
229
|
box.fit(100, 100, @frame)
|
197
|
-
box.draw(@canvas, 0,
|
230
|
+
box.draw(@canvas, 0, 100 - box.height)
|
198
231
|
operators = [
|
199
232
|
[:save_graphics_state],
|
200
|
-
[:set_font_and_size, [:F1,
|
233
|
+
[:set_font_and_size, [:F1, 11]],
|
234
|
+
[:set_device_gray_non_stroking_color, [0.5]],
|
201
235
|
[:begin_text],
|
202
|
-
[:set_text_matrix, [1, 0, 0, 1,
|
236
|
+
[:set_text_matrix, [1, 0, 0, 1, 6.75, 92.487]],
|
203
237
|
[:show_text, ["1.".b]],
|
204
238
|
[:end_text],
|
205
239
|
[:restore_graphics_state],
|
@@ -208,9 +242,10 @@ describe HexaPDF::Layout::ListBox do
|
|
208
242
|
[:restore_graphics_state],
|
209
243
|
|
210
244
|
[:save_graphics_state],
|
211
|
-
[:set_font_and_size, [:F1,
|
245
|
+
[:set_font_and_size, [:F1, 11]],
|
246
|
+
[:set_device_gray_non_stroking_color, [0.5]],
|
212
247
|
[:begin_text],
|
213
|
-
[:set_text_matrix, [1, 0, 0, 1,
|
248
|
+
[:set_text_matrix, [1, 0, 0, 1, 6.75, 82.487]],
|
214
249
|
[:show_text, ["2.".b]],
|
215
250
|
[:end_text],
|
216
251
|
[:restore_graphics_state],
|
@@ -227,7 +262,7 @@ describe HexaPDF::Layout::ListBox do
|
|
227
262
|
end
|
228
263
|
box = create_box(children: @fixed_size_boxes[0, 1], item_type: marker)
|
229
264
|
box.fit(100, 100, @frame)
|
230
|
-
box.draw(@canvas, 0,
|
265
|
+
box.draw(@canvas, 0, 100 - box.height)
|
231
266
|
operators = [
|
232
267
|
[:save_graphics_state],
|
233
268
|
[:concatenate_matrix, [1, 0, 0, 1, 0, 90]],
|
@@ -239,10 +274,26 @@ describe HexaPDF::Layout::ListBox do
|
|
239
274
|
assert_operators(@canvas.contents, operators)
|
240
275
|
end
|
241
276
|
|
242
|
-
it "
|
243
|
-
box = create_box(children: @fixed_size_boxes[0, 1]
|
277
|
+
it "takes a different final location into account" do
|
278
|
+
box = create_box(children: @fixed_size_boxes[0, 1])
|
244
279
|
box.fit(100, 100, @frame)
|
245
|
-
|
280
|
+
box.draw(@canvas, 20, 10)
|
281
|
+
operators = [
|
282
|
+
[:save_graphics_state],
|
283
|
+
[:concatenate_matrix, [1, 0, 0, 1, 20, -80]],
|
284
|
+
[:save_graphics_state],
|
285
|
+
[:set_font_and_size, [:F1, 10]],
|
286
|
+
[:begin_text],
|
287
|
+
[:set_text_matrix, [1, 0, 0, 1, 1.5, 93.17]],
|
288
|
+
[:show_text, ["\x95".b]],
|
289
|
+
[:end_text],
|
290
|
+
[:restore_graphics_state],
|
291
|
+
[:save_graphics_state],
|
292
|
+
[:concatenate_matrix, [1, 0, 0, 1, 10, 90]],
|
293
|
+
[:restore_graphics_state],
|
294
|
+
[:restore_graphics_state],
|
295
|
+
]
|
296
|
+
assert_operators(@canvas.contents, operators)
|
246
297
|
end
|
247
298
|
end
|
248
299
|
end
|
@@ -5,11 +5,12 @@ require 'hexapdf/layout/page_style'
|
|
5
5
|
require 'hexapdf/document'
|
6
6
|
|
7
7
|
describe HexaPDF::Layout::PageStyle do
|
8
|
-
it "allows assigning the page size, orientation and template on initialization" do
|
8
|
+
it "allows assigning the page size, orientation, next style and template on initialization" do
|
9
9
|
block = lambda {}
|
10
|
-
style = HexaPDF::Layout::PageStyle.new(page_size: :A3, orientation: :landscape, &block)
|
10
|
+
style = HexaPDF::Layout::PageStyle.new(page_size: :A3, orientation: :landscape, next_style: :a, &block)
|
11
11
|
assert_equal(:A3, style.page_size)
|
12
12
|
assert_equal(:landscape, style.orientation)
|
13
|
+
assert_equal(:a, style.next_style)
|
13
14
|
assert_same(block, style.template)
|
14
15
|
end
|
15
16
|
|
@@ -156,15 +156,24 @@ describe HexaPDF::Layout::Style::Border do
|
|
156
156
|
assert_kind_of(HexaPDF::Layout::Style::Quad, border.style)
|
157
157
|
end
|
158
158
|
|
159
|
+
it "has an accessor for the draw-on-bounds option" do
|
160
|
+
border = create_border
|
161
|
+
refute(border.draw_on_bounds)
|
162
|
+
border.draw_on_bounds = true
|
163
|
+
assert(border.draw_on_bounds)
|
164
|
+
end
|
165
|
+
|
159
166
|
it "can be duplicated" do
|
160
167
|
border = create_border
|
161
168
|
copy = border.dup
|
162
169
|
border.width.top = 10
|
163
170
|
border.color.top = :red
|
164
171
|
border.style.top = :dotted
|
172
|
+
border.draw_on_bounds = true
|
165
173
|
assert_equal(0, copy.width.top)
|
166
174
|
assert_equal(0, copy.color.top)
|
167
175
|
assert_equal(:solid, copy.style.top)
|
176
|
+
refute(copy.draw_on_bounds)
|
168
177
|
end
|
169
178
|
|
170
179
|
it "can be asked whether a border is defined" do
|
@@ -259,6 +268,19 @@ describe HexaPDF::Layout::Style::Border do
|
|
259
268
|
[:restore_graphics_state]]
|
260
269
|
assert_operators(@canvas.contents, ops)
|
261
270
|
end
|
271
|
+
|
272
|
+
it "works if the border is drawn on the bounds" do
|
273
|
+
border = create_border(width: 10, color: 0.5, style: :solid, draw_on_bounds: true)
|
274
|
+
border.draw(@canvas, 0, 0, 100, 100)
|
275
|
+
assert_operators(@canvas.contents, [[:save_graphics_state],
|
276
|
+
[:set_device_gray_stroking_color, [0.5]],
|
277
|
+
[:set_line_width, [10]],
|
278
|
+
[:append_rectangle, [-5, -5, 110, 110]],
|
279
|
+
[:clip_path_non_zero], [:end_path],
|
280
|
+
[:append_rectangle, [0, 0, 100, 100]],
|
281
|
+
[:stroke_path],
|
282
|
+
[:restore_graphics_state]])
|
283
|
+
end
|
262
284
|
end
|
263
285
|
|
264
286
|
describe "complex borders where edges have different width/color/style values" do
|
@@ -369,6 +391,34 @@ describe HexaPDF::Layout::Style::Border do
|
|
369
391
|
[:restore_graphics_state], [:restore_graphics_state]]
|
370
392
|
assert_operators(@canvas.contents, ops)
|
371
393
|
end
|
394
|
+
|
395
|
+
it "works if the border is drawn on the bounds" do
|
396
|
+
border = create_border(width: [20, 10, 40, 30], draw_on_bounds: true)
|
397
|
+
border.draw(@canvas, 0, 0, 100, 200)
|
398
|
+
ops = [[:save_graphics_state],
|
399
|
+
[:save_graphics_state],
|
400
|
+
[:move_to, [-15, 210]], [:line_to, [105, 210]],
|
401
|
+
[:line_to, [95, 190]], [:line_to, [15, 190]], [:clip_path_non_zero], [:end_path],
|
402
|
+
[:set_line_width, [20]],
|
403
|
+
[:move_to, [-15, 200]], [:line_to, [105, 200]], [:stroke_path],
|
404
|
+
[:restore_graphics_state], [:save_graphics_state],
|
405
|
+
[:move_to, [105, 210]], [:line_to, [105, -20]],
|
406
|
+
[:line_to, [95, 20]], [:line_to, [95, 190]], [:clip_path_non_zero], [:end_path],
|
407
|
+
[:set_line_width, [10]],
|
408
|
+
[:move_to, [100, 210]], [:line_to, [100, -20]], [:stroke_path],
|
409
|
+
[:restore_graphics_state], [:save_graphics_state],
|
410
|
+
[:move_to, [105, -20]], [:line_to, [-15, -20]],
|
411
|
+
[:line_to, [15, 20]], [:line_to, [95, 20]], [:clip_path_non_zero], [:end_path],
|
412
|
+
[:set_line_width, [40]],
|
413
|
+
[:move_to, [105, 0]], [:line_to, [-15, 0]], [:stroke_path],
|
414
|
+
[:restore_graphics_state], [:save_graphics_state],
|
415
|
+
[:move_to, [-15, -20]], [:line_to, [-15, 210]],
|
416
|
+
[:line_to, [15, 190]], [:line_to, [15, 20]], [:clip_path_non_zero], [:end_path],
|
417
|
+
[:set_line_width, [30]],
|
418
|
+
[:move_to, [0, -20]], [:line_to, [0, 210]], [:stroke_path],
|
419
|
+
[:restore_graphics_state], [:restore_graphics_state]]
|
420
|
+
assert_operators(@canvas.contents, ops)
|
421
|
+
end
|
372
422
|
end
|
373
423
|
|
374
424
|
describe "border width greater than edge length" do
|
@@ -530,7 +580,10 @@ describe HexaPDF::Layout::Style::LinkLayer do
|
|
530
580
|
it "fails if more than one possible target is chosen" do
|
531
581
|
assert_raises(ArgumentError) { HexaPDF::Layout::Style::LinkLayer.new(dest: true, uri: true) }
|
532
582
|
assert_raises(ArgumentError) { HexaPDF::Layout::Style::LinkLayer.new(dest: true, file: true) }
|
583
|
+
assert_raises(ArgumentError) { HexaPDF::Layout::Style::LinkLayer.new(dest: true, action: true) }
|
533
584
|
assert_raises(ArgumentError) { HexaPDF::Layout::Style::LinkLayer.new(uri: true, file: true) }
|
585
|
+
assert_raises(ArgumentError) { HexaPDF::Layout::Style::LinkLayer.new(uri: true, action: true) }
|
586
|
+
assert_raises(ArgumentError) { HexaPDF::Layout::Style::LinkLayer.new(file: true, action: true) }
|
534
587
|
end
|
535
588
|
|
536
589
|
it "fails if an invalid border is provided" do
|
@@ -606,6 +659,12 @@ describe HexaPDF::Layout::Style::LinkLayer do
|
|
606
659
|
assert_nil(annot[:Dest])
|
607
660
|
end
|
608
661
|
|
662
|
+
it "works for actions" do
|
663
|
+
annot = call_link(action: {Type: :Action, S: :SetOCGState})
|
664
|
+
assert_equal({Type: :Action, S: :SetOCGState}, annot[:A].value)
|
665
|
+
assert_nil(annot[:Dest])
|
666
|
+
end
|
667
|
+
|
609
668
|
it "works for destinations set via the 'link' custom box property" do
|
610
669
|
@box.properties['link'] = [@canvas.context, :FitH]
|
611
670
|
annot = call_link({})
|
@@ -723,6 +782,7 @@ describe HexaPDF::Layout::Style do
|
|
723
782
|
refute(@style.subscript)
|
724
783
|
refute(@style.superscript)
|
725
784
|
refute(@style.last_line_gap)
|
785
|
+
refute(@style.fill_horizontal)
|
726
786
|
assert_kind_of(HexaPDF::Layout::Style::Layers, @style.underlays)
|
727
787
|
assert_kind_of(HexaPDF::Layout::Style::Layers, @style.overlays)
|
728
788
|
end
|