hexapdf 0.21.1 → 0.24.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 +137 -0
- data/LICENSE +1 -1
- data/Rakefile +1 -1
- data/examples/016-frame_automatic_box_placement.rb +7 -2
- data/examples/017-frame_text_flow.rb +10 -18
- data/examples/020-column_box.rb +20 -37
- data/examples/021-list_box.rb +26 -0
- data/lib/hexapdf/cli/batch.rb +1 -1
- data/lib/hexapdf/cli/command.rb +1 -1
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/fonts.rb +1 -1
- data/lib/hexapdf/cli/form.rb +31 -4
- data/lib/hexapdf/cli/image2pdf.rb +1 -1
- data/lib/hexapdf/cli/images.rb +1 -1
- data/lib/hexapdf/cli/info.rb +2 -2
- data/lib/hexapdf/cli/inspect.rb +19 -6
- data/lib/hexapdf/cli/merge.rb +1 -1
- data/lib/hexapdf/cli/modify.rb +24 -4
- data/lib/hexapdf/cli/optimize.rb +1 -1
- data/lib/hexapdf/cli/split.rb +1 -1
- data/lib/hexapdf/cli/watermark.rb +1 -1
- data/lib/hexapdf/cli.rb +1 -1
- data/lib/hexapdf/composer.rb +66 -125
- data/lib/hexapdf/configuration.rb +17 -1
- data/lib/hexapdf/content/canvas.rb +1 -1
- data/lib/hexapdf/content/color_space.rb +1 -1
- data/lib/hexapdf/content/graphic_object/arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object/geom2d.rb +2 -1
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object.rb +1 -1
- data/lib/hexapdf/content/graphics_state.rb +1 -1
- data/lib/hexapdf/content/operator.rb +1 -1
- data/lib/hexapdf/content/parser.rb +1 -1
- data/lib/hexapdf/content/processor.rb +1 -1
- data/lib/hexapdf/content/transformation_matrix.rb +1 -1
- data/lib/hexapdf/content.rb +1 -1
- data/lib/hexapdf/data_dir.rb +1 -1
- data/lib/hexapdf/dictionary.rb +1 -1
- data/lib/hexapdf/dictionary_fields.rb +2 -2
- data/lib/hexapdf/document/destinations.rb +396 -0
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/images.rb +1 -1
- data/lib/hexapdf/document/layout.rb +397 -0
- data/lib/hexapdf/document/pages.rb +17 -1
- data/lib/hexapdf/document/signatures.rb +5 -4
- data/lib/hexapdf/document.rb +46 -90
- data/lib/hexapdf/encryption/aes.rb +1 -1
- data/lib/hexapdf/encryption/arc4.rb +1 -1
- data/lib/hexapdf/encryption/fast_aes.rb +1 -1
- data/lib/hexapdf/encryption/fast_arc4.rb +30 -21
- data/lib/hexapdf/encryption/identity.rb +1 -1
- data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
- data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
- data/lib/hexapdf/encryption/security_handler.rb +1 -1
- data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
- data/lib/hexapdf/encryption.rb +1 -1
- data/lib/hexapdf/error.rb +1 -1
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
- data/lib/hexapdf/filter/crypt.rb +1 -1
- data/lib/hexapdf/filter/encryption.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 +1 -1
- data/lib/hexapdf/font/cmap/parser.rb +1 -1
- data/lib/hexapdf/font/cmap/writer.rb +1 -1
- data/lib/hexapdf/font/cmap.rb +1 -1
- data/lib/hexapdf/font/encoding/base.rb +1 -1
- data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/glyph_list.rb +2 -2
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
- 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 +1 -1
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding.rb +1 -1
- data/lib/hexapdf/font/invalid_glyph.rb +1 -1
- data/lib/hexapdf/font/true_type/builder.rb +1 -1
- data/lib/hexapdf/font/true_type/font.rb +1 -1
- data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
- data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
- data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
- data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
- data/lib/hexapdf/font/true_type/table/head.rb +1 -1
- data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
- data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
- data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
- data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
- data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
- data/lib/hexapdf/font/true_type/table/name.rb +1 -1
- data/lib/hexapdf/font/true_type/table/os2.rb +1 -1
- data/lib/hexapdf/font/true_type/table/post.rb +1 -1
- data/lib/hexapdf/font/true_type/table.rb +1 -1
- data/lib/hexapdf/font/true_type.rb +1 -1
- data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
- data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
- data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/font.rb +1 -1
- data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
- data/lib/hexapdf/font/type1.rb +1 -1
- data/lib/hexapdf/font/type1_wrapper.rb +1 -1
- data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
- data/lib/hexapdf/font_loader/from_file.rb +1 -1
- data/lib/hexapdf/font_loader/standard14.rb +1 -1
- data/lib/hexapdf/font_loader.rb +1 -1
- data/lib/hexapdf/image_loader/jpeg.rb +1 -1
- data/lib/hexapdf/image_loader/pdf.rb +1 -1
- data/lib/hexapdf/image_loader/png.rb +1 -1
- data/lib/hexapdf/image_loader.rb +1 -1
- data/lib/hexapdf/importer.rb +1 -1
- data/lib/hexapdf/layout/box.rb +121 -22
- data/lib/hexapdf/layout/box_fitter.rb +136 -0
- data/lib/hexapdf/layout/column_box.rb +168 -89
- data/lib/hexapdf/layout/frame.rb +155 -140
- data/lib/hexapdf/layout/image_box.rb +19 -4
- data/lib/hexapdf/layout/inline_box.rb +1 -1
- data/lib/hexapdf/layout/line.rb +1 -1
- data/lib/hexapdf/layout/list_box.rb +355 -0
- data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
- data/lib/hexapdf/layout/style.rb +285 -8
- data/lib/hexapdf/layout/text_box.rb +30 -11
- data/lib/hexapdf/layout/text_fragment.rb +3 -2
- data/lib/hexapdf/layout/text_layouter.rb +23 -3
- data/lib/hexapdf/layout/text_shaper.rb +1 -1
- data/lib/hexapdf/layout/width_from_polygon.rb +12 -7
- data/lib/hexapdf/layout.rb +4 -1
- data/lib/hexapdf/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +1 -1
- data/lib/hexapdf/parser.rb +1 -8
- 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 +9 -2
- data/lib/hexapdf/revisions.rb +152 -51
- data/lib/hexapdf/serializer.rb +1 -1
- data/lib/hexapdf/stream.rb +1 -1
- data/lib/hexapdf/task/dereference.rb +1 -1
- data/lib/hexapdf/task/optimize.rb +22 -12
- data/lib/hexapdf/task.rb +1 -1
- data/lib/hexapdf/tokenizer.rb +1 -1
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +1 -1
- 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 +1 -1
- data/lib/hexapdf/type/acro_form/form.rb +12 -6
- data/lib/hexapdf/type/acro_form/signature_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/text_field.rb +9 -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/uri.rb +1 -1
- data/lib/hexapdf/type/actions.rb +1 -1
- data/lib/hexapdf/type/annotation.rb +1 -1
- 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 +1 -1
- data/lib/hexapdf/type/annotations/widget.rb +1 -1
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/catalog.rb +10 -2
- data/lib/hexapdf/type/cid_font.rb +1 -1
- data/lib/hexapdf/type/embedded_file.rb +1 -1
- data/lib/hexapdf/type/file_specification.rb +1 -1
- data/lib/hexapdf/type/font.rb +1 -1
- data/lib/hexapdf/type/font_descriptor.rb +1 -1
- data/lib/hexapdf/type/font_simple.rb +1 -1
- data/lib/hexapdf/type/font_true_type.rb +1 -1
- data/lib/hexapdf/type/font_type0.rb +1 -1
- data/lib/hexapdf/type/font_type1.rb +1 -1
- data/lib/hexapdf/type/font_type3.rb +1 -1
- data/lib/hexapdf/type/form.rb +1 -1
- 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 +48 -4
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/names.rb +14 -1
- data/lib/hexapdf/type/object_stream.rb +1 -1
- data/lib/hexapdf/type/page.rb +1 -1
- data/lib/hexapdf/type/page_tree_node.rb +19 -2
- data/lib/hexapdf/type/resources.rb +1 -1
- data/lib/hexapdf/type/signature/adbe_pkcs7_detached.rb +1 -1
- data/lib/hexapdf/type/signature/adbe_x509_rsa_sha1.rb +1 -1
- data/lib/hexapdf/type/signature/handler.rb +1 -1
- data/lib/hexapdf/type/signature/verification_result.rb +1 -1
- data/lib/hexapdf/type/signature.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 +3 -2
- data/lib/hexapdf/type.rb +1 -1
- data/lib/hexapdf/utils/bit_field.rb +1 -1
- data/lib/hexapdf/utils/bit_stream.rb +1 -1
- data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
- data/lib/hexapdf/utils/lru_cache.rb +1 -1
- data/lib/hexapdf/utils/math_helpers.rb +1 -1
- data/lib/hexapdf/utils/object_hash.rb +1 -1
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
- data/lib/hexapdf/utils/sorted_tree_node.rb +4 -2
- data/lib/hexapdf/version.rb +2 -2
- data/lib/hexapdf/writer.rb +23 -8
- data/lib/hexapdf/xref_section.rb +1 -1
- data/lib/hexapdf.rb +1 -1
- data/test/hexapdf/content/graphic_object/test_geom2d.rb +1 -1
- data/test/hexapdf/document/test_destinations.rb +338 -0
- data/test/hexapdf/document/test_images.rb +1 -1
- data/test/hexapdf/document/test_layout.rb +264 -0
- data/test/hexapdf/document/test_pages.rb +9 -0
- data/test/hexapdf/document/test_signatures.rb +10 -3
- data/test/hexapdf/encryption/test_security_handler.rb +3 -3
- data/test/hexapdf/font/encoding/test_glyph_list.rb +4 -0
- data/test/hexapdf/layout/test_box.rb +53 -3
- data/test/hexapdf/layout/test_box_fitter.rb +62 -0
- data/test/hexapdf/layout/test_column_box.rb +159 -0
- data/test/hexapdf/layout/test_frame.rb +114 -39
- data/test/hexapdf/layout/test_image_box.rb +1 -1
- data/test/hexapdf/layout/test_list_box.rb +249 -0
- data/test/hexapdf/layout/test_text_box.rb +33 -2
- data/test/hexapdf/layout/test_text_fragment.rb +1 -1
- data/test/hexapdf/layout/test_text_layouter.rb +49 -17
- data/test/hexapdf/layout/test_width_from_polygon.rb +13 -0
- data/test/hexapdf/task/test_optimize.rb +17 -4
- data/test/hexapdf/test_composer.rb +35 -1
- data/test/hexapdf/test_dictionary_fields.rb +10 -10
- data/test/hexapdf/test_document.rb +33 -136
- data/test/hexapdf/test_filter.rb +1 -1
- data/test/hexapdf/test_parser.rb +1 -3
- data/test/hexapdf/test_revision.rb +14 -0
- data/test/hexapdf/test_revisions.rb +137 -29
- data/test/hexapdf/test_serializer.rb +1 -5
- data/test/hexapdf/test_writer.rb +99 -15
- data/test/hexapdf/type/acro_form/test_form.rb +2 -1
- data/test/hexapdf/type/acro_form/test_text_field.rb +17 -0
- data/test/hexapdf/type/test_catalog.rb +8 -0
- data/test/hexapdf/type/test_image.rb +45 -9
- data/test/hexapdf/type/test_names.rb +20 -0
- data/test/hexapdf/type/test_page_tree_node.rb +21 -1
- data/test/hexapdf/type/test_trailer.rb +3 -3
- data/test/hexapdf/type/test_xref_stream.rb +2 -1
- data/test/hexapdf/utils/test_sorted_tree_node.rb +11 -1
- data/test/test_helper.rb +5 -1
- metadata +29 -3
@@ -0,0 +1,249 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require_relative '../content/common'
|
5
|
+
require 'hexapdf/document'
|
6
|
+
require 'hexapdf/layout/list_box'
|
7
|
+
|
8
|
+
describe HexaPDF::Layout::ListBox do
|
9
|
+
before do
|
10
|
+
@frame = HexaPDF::Layout::Frame.new(0, 0, 100, 100)
|
11
|
+
inline_box = HexaPDF::Layout::InlineBox.create(width: 10, height: 10) {}
|
12
|
+
@text_boxes = 5.times.map do
|
13
|
+
HexaPDF::Layout::TextBox.new(items: [inline_box] * 15, style: {position: :default})
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_box(**kwargs)
|
18
|
+
HexaPDF::Layout::ListBox.new(content_indentation: 10, **kwargs)
|
19
|
+
end
|
20
|
+
|
21
|
+
def check_box(box, width, height, fit_pos = nil)
|
22
|
+
assert(box.fit(@frame.available_width, @frame.available_height, @frame), "box fit?")
|
23
|
+
assert_equal(width, box.width, "box width")
|
24
|
+
assert_equal(height, box.height, "box height")
|
25
|
+
if fit_pos
|
26
|
+
results = box.instance_variable_get(:@results)
|
27
|
+
results.each_with_index do |box_fitter, item_index|
|
28
|
+
box_fitter.fit_results.each_with_index do |fit_result, result_index|
|
29
|
+
x, y = fit_pos.shift
|
30
|
+
assert_equal(x, fit_result.x, "item #{item_index}, result #{result_index}, x")
|
31
|
+
assert_equal(y, fit_result.y, "item #{item_index}, result #{result_index}, y")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
assert(fit_pos.empty?)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "initialize" do
|
39
|
+
it "creates a new instance with the given arguments" do
|
40
|
+
box = create_box(children: [:a], item_type: :circle, content_indentation: 15,
|
41
|
+
start_number: 4, item_spacing: 20)
|
42
|
+
assert_equal([:a], box.children)
|
43
|
+
assert_equal(:circle, box.item_type)
|
44
|
+
assert_equal(15, box.content_indentation)
|
45
|
+
assert_equal(4, box.start_number)
|
46
|
+
assert_equal(20, box.item_spacing)
|
47
|
+
assert(box.supports_position_flow?)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "fit" do
|
52
|
+
[:default, :flow].each do |position|
|
53
|
+
it "respects the set initial width, position #{position}" do
|
54
|
+
box = create_box(children: @text_boxes[0, 2], width: 50, style: {position: position})
|
55
|
+
check_box(box, 50, 80)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "respects the set initial height, position #{position}" do
|
59
|
+
box = create_box(children: @text_boxes[0, 2], height: 50, style: {position: position})
|
60
|
+
check_box(box, 100, 40)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "respects the border and padding around all list items, position #{position}" do
|
64
|
+
box = create_box(children: @text_boxes[0, 2],
|
65
|
+
style: {border: {width: [5, 4, 3, 2]}, padding: [5, 4, 3, 2], position: position})
|
66
|
+
check_box(box, 100, 76, [[14, 60], [14, 30]])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it "uses the frame's current cursor position and available width/height when position=:default" do
|
71
|
+
@frame.remove_area(Geom2D::Polygon([0, 0], [10, 0], [10, 90], [100, 90], [100, 100], [0, 100]))
|
72
|
+
box = create_box(children: @text_boxes[0, 2])
|
73
|
+
check_box(box, 90, 40, [[20, 70], [20, 50]])
|
74
|
+
end
|
75
|
+
|
76
|
+
it "respects the frame's shape when style position=:flow" do
|
77
|
+
@frame.remove_area(Geom2D::Polygon([0, 0], [0, 40], [40, 40], [40, 0]))
|
78
|
+
box = create_box(children: @text_boxes[0, 4], style: {position: :flow})
|
79
|
+
check_box(box, 100, 90, [[10, 80], [10, 60], [10, 40], [50, 10]])
|
80
|
+
end
|
81
|
+
|
82
|
+
it "respects the content indentation" do
|
83
|
+
box = create_box(children: @text_boxes[0, 1], content_indentation: 30)
|
84
|
+
check_box(box, 100, 30, [[30, 70]])
|
85
|
+
end
|
86
|
+
|
87
|
+
it "respects the spacing between list items" do
|
88
|
+
box = create_box(children: @text_boxes[0, 2], item_spacing: 30)
|
89
|
+
check_box(box, 100, 70, [[10, 80], [10, 30]])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "split" do
|
94
|
+
it "splits before a list item if no part of it will fit" do
|
95
|
+
box = create_box(children: @text_boxes[0, 2], height: 20)
|
96
|
+
box.fit(100, 100, @frame)
|
97
|
+
box_a, box_b = box.split(100, 100, @frame)
|
98
|
+
assert_same(box, box_a)
|
99
|
+
assert_equal(:show_first_marker, box_b.split_box?)
|
100
|
+
assert_equal(1, box_a.instance_variable_get(:@results)[0].fit_results.size)
|
101
|
+
assert_equal(1, box_b.children.size)
|
102
|
+
assert_equal(2, box_b.start_number)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "splits a list item if some part of it will fit" do
|
106
|
+
box = create_box(children: @text_boxes[0, 2], height: 10)
|
107
|
+
box.fit(100, 100, @frame)
|
108
|
+
box_a, box_b = box.split(100, 100, @frame)
|
109
|
+
assert_same(box, box_a)
|
110
|
+
assert_equal(:hide_first_marker, box_b.split_box?)
|
111
|
+
assert_equal(1, box_a.instance_variable_get(:@results)[0].fit_results.size)
|
112
|
+
assert_equal(2, box_b.children.size)
|
113
|
+
assert_equal(1, box_b.start_number)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "draw" do
|
118
|
+
before do
|
119
|
+
@canvas = HexaPDF::Document.new.pages.add.canvas
|
120
|
+
draw_block = lambda {|canvas, box| }
|
121
|
+
@fixed_size_boxes = 5.times.map { HexaPDF::Layout::Box.new(width: 20, height: 10, &draw_block) }
|
122
|
+
end
|
123
|
+
|
124
|
+
it "draws the result" do
|
125
|
+
box = create_box(children: @fixed_size_boxes[0, 2])
|
126
|
+
box.fit(100, 100, @frame)
|
127
|
+
box.draw(@canvas, 0, 0)
|
128
|
+
operators = [
|
129
|
+
[:save_graphics_state],
|
130
|
+
[:set_font_and_size, [:F1, 10]],
|
131
|
+
[:begin_text],
|
132
|
+
[:set_text_matrix, [1, 0, 0, 1, 1.5, 93.17]],
|
133
|
+
[:show_text, ["\x95".b]],
|
134
|
+
[:end_text],
|
135
|
+
[:restore_graphics_state],
|
136
|
+
[:save_graphics_state],
|
137
|
+
[:concatenate_matrix, [1, 0, 0, 1, 10, 90]],
|
138
|
+
[:restore_graphics_state],
|
139
|
+
|
140
|
+
[:save_graphics_state],
|
141
|
+
[:set_font_and_size, [:F1, 10]],
|
142
|
+
[:begin_text],
|
143
|
+
[:set_text_matrix, [1, 0, 0, 1, 1.5, 83.17]],
|
144
|
+
[:show_text, ["\x95".b]],
|
145
|
+
[:end_text],
|
146
|
+
[:restore_graphics_state],
|
147
|
+
[:save_graphics_state],
|
148
|
+
[:concatenate_matrix, [1, 0, 0, 1, 10, 80]],
|
149
|
+
[:restore_graphics_state],
|
150
|
+
]
|
151
|
+
assert_operators(@canvas.contents, operators)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "draws a cicle as marker" do
|
155
|
+
box = create_box(children: @fixed_size_boxes[0, 1], item_type: :circle)
|
156
|
+
box.fit(100, 100, @frame)
|
157
|
+
box.draw(@canvas, 0, 0)
|
158
|
+
operators = [
|
159
|
+
[:save_graphics_state],
|
160
|
+
[:set_font_and_size, [:F1, 5]],
|
161
|
+
[:set_text_rise, [-5.555556]],
|
162
|
+
[:begin_text],
|
163
|
+
[:set_text_matrix, [1, 0, 0, 1, 0.635, 100]],
|
164
|
+
[:show_text, ["m".b]],
|
165
|
+
[:end_text],
|
166
|
+
[:restore_graphics_state],
|
167
|
+
[:save_graphics_state],
|
168
|
+
[:concatenate_matrix, [1, 0, 0, 1, 10, 90]],
|
169
|
+
[:restore_graphics_state],
|
170
|
+
]
|
171
|
+
assert_operators(@canvas.contents, operators)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "draws a square as marker" do
|
175
|
+
box = create_box(children: @fixed_size_boxes[0, 1], item_type: :square)
|
176
|
+
box.fit(100, 100, @frame)
|
177
|
+
box.draw(@canvas, 0, 0)
|
178
|
+
operators = [
|
179
|
+
[:save_graphics_state],
|
180
|
+
[:set_font_and_size, [:F1, 5]],
|
181
|
+
[:set_text_rise, [-5.555556]],
|
182
|
+
[:begin_text],
|
183
|
+
[:set_text_matrix, [1, 0, 0, 1, 1.195, 100]],
|
184
|
+
[:show_text, ["n".b]],
|
185
|
+
[:end_text],
|
186
|
+
[:restore_graphics_state],
|
187
|
+
[:save_graphics_state],
|
188
|
+
[:concatenate_matrix, [1, 0, 0, 1, 10, 90]],
|
189
|
+
[:restore_graphics_state],
|
190
|
+
]
|
191
|
+
assert_operators(@canvas.contents, operators)
|
192
|
+
end
|
193
|
+
|
194
|
+
it "draws decimal numbers as marker" do
|
195
|
+
box = create_box(children: @fixed_size_boxes[0, 2], item_type: :decimal,
|
196
|
+
content_indentation: 20)
|
197
|
+
box.fit(100, 100, @frame)
|
198
|
+
box.draw(@canvas, 0, 0)
|
199
|
+
operators = [
|
200
|
+
[:save_graphics_state],
|
201
|
+
[:set_font_and_size, [:F1, 10]],
|
202
|
+
[:begin_text],
|
203
|
+
[:set_text_matrix, [1, 0, 0, 1, 7.5, 93.17]],
|
204
|
+
[:show_text, ["1.".b]],
|
205
|
+
[:end_text],
|
206
|
+
[:restore_graphics_state],
|
207
|
+
[:save_graphics_state],
|
208
|
+
[:concatenate_matrix, [1, 0, 0, 1, 20, 90]],
|
209
|
+
[:restore_graphics_state],
|
210
|
+
|
211
|
+
[:save_graphics_state],
|
212
|
+
[:set_font_and_size, [:F1, 10]],
|
213
|
+
[:begin_text],
|
214
|
+
[:set_text_matrix, [1, 0, 0, 1, 7.5, 83.17]],
|
215
|
+
[:show_text, ["2.".b]],
|
216
|
+
[:end_text],
|
217
|
+
[:restore_graphics_state],
|
218
|
+
[:save_graphics_state],
|
219
|
+
[:concatenate_matrix, [1, 0, 0, 1, 20, 80]],
|
220
|
+
[:restore_graphics_state],
|
221
|
+
]
|
222
|
+
assert_operators(@canvas.contents, operators)
|
223
|
+
end
|
224
|
+
|
225
|
+
it "allows drawing custom markers" do
|
226
|
+
marker = lambda do |doc, list_box, index|
|
227
|
+
HexaPDF::Layout::Box.create(width: 10, height: 10) {}
|
228
|
+
end
|
229
|
+
box = create_box(children: @fixed_size_boxes[0, 1], item_type: marker)
|
230
|
+
box.fit(100, 100, @frame)
|
231
|
+
box.draw(@canvas, 0, 0)
|
232
|
+
operators = [
|
233
|
+
[:save_graphics_state],
|
234
|
+
[:concatenate_matrix, [1, 0, 0, 1, 0, 90]],
|
235
|
+
[:restore_graphics_state],
|
236
|
+
[:save_graphics_state],
|
237
|
+
[:concatenate_matrix, [1, 0, 0, 1, 10, 90]],
|
238
|
+
[:restore_graphics_state],
|
239
|
+
]
|
240
|
+
assert_operators(@canvas.contents, operators)
|
241
|
+
end
|
242
|
+
|
243
|
+
it "fails for unknown item types" do
|
244
|
+
box = create_box(children: @fixed_size_boxes[0, 1], item_type: :unknown)
|
245
|
+
box.fit(100, 100, @frame)
|
246
|
+
assert_raises(HexaPDF::Error) { box.draw(@canvas, 0, 0) }
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
@@ -12,7 +12,7 @@ describe HexaPDF::Layout::TextBox do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def create_box(items, **kwargs)
|
15
|
-
HexaPDF::Layout::TextBox.new(items, **kwargs)
|
15
|
+
HexaPDF::Layout::TextBox.new(items: items, **kwargs)
|
16
16
|
end
|
17
17
|
|
18
18
|
describe "initialize" do
|
@@ -20,6 +20,10 @@ describe HexaPDF::Layout::TextBox do
|
|
20
20
|
box = create_box([], width: 100)
|
21
21
|
assert_equal(100, box.width)
|
22
22
|
end
|
23
|
+
|
24
|
+
it "supports flowing text around other content" do
|
25
|
+
assert(create_box([]).supports_position_flow?)
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
29
|
describe "fit" do
|
@@ -53,6 +57,22 @@ describe HexaPDF::Layout::TextBox do
|
|
53
57
|
assert_equal(20, box.height)
|
54
58
|
end
|
55
59
|
|
60
|
+
it "uses the whole available width when aligning to the center or right" do
|
61
|
+
[:center, :right].each do |align|
|
62
|
+
box = create_box([@inline_box], style: {align: align})
|
63
|
+
assert(box.fit(100, 100, @frame))
|
64
|
+
assert_equal(100, box.width)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "uses the whole available height when vertically aligning to the center or bottom" do
|
69
|
+
[:center, :bottom].each do |valign|
|
70
|
+
box = create_box([@inline_box], style: {valign: valign})
|
71
|
+
assert(box.fit(100, 100, @frame))
|
72
|
+
assert_equal(100, box.height)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
56
76
|
it "can't fit the text box if the set width is bigger than the available width" do
|
57
77
|
box = create_box([@inline_box], width: 101)
|
58
78
|
refute(box.fit(100, 100, @frame))
|
@@ -88,11 +108,22 @@ describe HexaPDF::Layout::TextBox do
|
|
88
108
|
assert_equal([nil, box], box.split(100, 100, @frame))
|
89
109
|
end
|
90
110
|
|
91
|
-
it "splits the box if necessary" do
|
111
|
+
it "splits the box if necessary when using non-flowing text" do
|
92
112
|
box = create_box([@inline_box] * 10)
|
93
113
|
boxes = box.split(50, 10, @frame)
|
94
114
|
assert_equal(2, boxes.length)
|
95
115
|
assert_equal(box, boxes[0])
|
116
|
+
refute(boxes[0].split_box?)
|
117
|
+
assert(boxes[1].split_box?)
|
118
|
+
assert_equal(5, boxes[1].instance_variable_get(:@items).length)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "splits the box if necessary when using flowing text that results in a wider box" do
|
122
|
+
@frame.remove_area(Geom2D::Polygon.new([[0, 100], [50, 100], [50, 10], [0, 10]]))
|
123
|
+
box = create_box([@inline_box] * 60, style: {position: :flow})
|
124
|
+
boxes = box.split(50, 100, @frame)
|
125
|
+
assert_equal(2, boxes.length)
|
126
|
+
assert_equal(box, boxes[0])
|
96
127
|
assert_equal(5, boxes[1].instance_variable_get(:@items).length)
|
97
128
|
end
|
98
129
|
end
|
@@ -57,6 +57,24 @@ module TestTextLayouterHelpers
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
describe HexaPDF::Layout::TextLayouter::Box do
|
61
|
+
it "can describe itself" do
|
62
|
+
assert_equal('Box["test"]', HexaPDF::Layout::TextLayouter::Box.new("test").inspect)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe HexaPDF::Layout::TextLayouter::Glue do
|
67
|
+
it "can describe itself" do
|
68
|
+
assert_equal('Glue["test"]', HexaPDF::Layout::TextLayouter::Glue.new("test", 5, 5).inspect)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe HexaPDF::Layout::TextLayouter::Penalty do
|
73
|
+
it "can describe itself" do
|
74
|
+
assert_equal('Penalty[100 10 nil]', HexaPDF::Layout::TextLayouter::Penalty.new(100, 10).inspect)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
60
78
|
describe HexaPDF::Layout::TextLayouter::SimpleTextSegmentation do
|
61
79
|
include TestTextLayouterHelpers
|
62
80
|
|
@@ -556,36 +574,43 @@ describe HexaPDF::Layout::TextLayouter do
|
|
556
574
|
end
|
557
575
|
end
|
558
576
|
|
559
|
-
describe "
|
577
|
+
describe "breaking into parts of a too wide text fragment" do
|
560
578
|
before do
|
561
|
-
@str = "
|
579
|
+
@str = " Thisisaverylongstring"
|
562
580
|
@frag = HexaPDF::Layout::TextFragment.create(@str, font: @font)
|
563
581
|
end
|
564
582
|
|
565
|
-
it "
|
583
|
+
it "arranges the parts if single parts fit into the available space" do
|
566
584
|
result = @layouter.fit([@frag], 20, 100)
|
567
585
|
assert(result.remaining_items.empty?)
|
568
586
|
assert_equal(:success, result.status)
|
569
|
-
assert_equal(@str.
|
570
|
-
assert_equal(
|
587
|
+
assert_equal(@str.strip.length, result.lines.sum {|l| l.items.sum {|i| i.items.count } })
|
588
|
+
assert_equal(45, result.height)
|
589
|
+
end
|
571
590
|
|
591
|
+
it "works even if a single part doesn't fit" do
|
572
592
|
result = @layouter.fit([@frag], 1, 100)
|
573
|
-
assert_equal(
|
593
|
+
assert_equal(@str.strip.length, result.remaining_items.count)
|
574
594
|
assert_equal(:box_too_wide, result.status)
|
575
595
|
end
|
576
596
|
|
577
|
-
it "works
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
else
|
583
|
-
10
|
584
|
-
end
|
585
|
-
end
|
586
|
-
result = @layouter.fit([@frag], width_block, 30)
|
597
|
+
it "works if the parts of the broken fragment are used in another .fit call" do
|
598
|
+
text = "This is a long string to test"
|
599
|
+
frag = HexaPDF::Layout::TextFragment.create(text, font: @font)
|
600
|
+
result = @layouter.fit([frag], lambda {|h, _| h > 17 ? 0 : 25 }, 20)
|
601
|
+
refute(result.remaining_items.empty?)
|
587
602
|
assert_equal(:height, result.status)
|
588
|
-
assert_equal([
|
603
|
+
assert_equal(["This", "is a"],
|
604
|
+
result.lines.map {|l| l.items.map {|tf| tf.items.map(&:str).join }.join })
|
605
|
+
|
606
|
+
# Simulating a split text box where the second part is tried to fit into same remaining
|
607
|
+
# space
|
608
|
+
result = @layouter.fit(result.remaining_items, 25, 1)
|
609
|
+
|
610
|
+
# Now fit into next available space
|
611
|
+
result = @layouter.fit(result.remaining_items, 25, 100)
|
612
|
+
assert_equal(["long", "string", "to test"],
|
613
|
+
result.lines.map {|l| l.items.map {|tf| tf.items.map(&:str).join }.join })
|
589
614
|
end
|
590
615
|
end
|
591
616
|
|
@@ -646,6 +671,13 @@ describe HexaPDF::Layout::TextLayouter do
|
|
646
671
|
assert_equal(100 - 20 * 2 + 20, result.lines[0].y_offset)
|
647
672
|
assert_equal(100, result.height)
|
648
673
|
end
|
674
|
+
|
675
|
+
it "doesn't vertically align when layouting in variable-width mode" do
|
676
|
+
@style.valign = :bottom
|
677
|
+
result = @layouter.fit(@items, proc { 40 }, 100)
|
678
|
+
assert_equal(result.lines[0].y_max, result.lines[0].y_offset)
|
679
|
+
assert_equal(40, result.height)
|
680
|
+
end
|
649
681
|
end
|
650
682
|
|
651
683
|
it "post-processes lines for justification if needed" do
|
@@ -32,6 +32,13 @@ describe HexaPDF::Layout::WidthFromPolygon do
|
|
32
32
|
assert_equal([2.5, 7.5], ws.call(5, 1))
|
33
33
|
end
|
34
34
|
|
35
|
+
it "works for polygons in counterclockwise order with some segments crossing only top or bottom" do
|
36
|
+
ws = create_width_spec(Geom2D::PolygonSet(Geom2D::Polygon([55.0, 65.0], [70, 65], [70.0, 50.0],
|
37
|
+
[100.0, 50.0], [100.0, 63.0], [120, 63],
|
38
|
+
[120, 70], [55, 70])))
|
39
|
+
assert_equal([70, 30], ws.call(0, 10))
|
40
|
+
end
|
41
|
+
|
35
42
|
it "works if some segments only cross the top line" do
|
36
43
|
ws = create_width_spec(Geom2D::Polygon([0, 0], [0, 10], [2, 11], [4, 9], [6, 11], [10, 10],
|
37
44
|
[10, 0]))
|
@@ -60,6 +67,12 @@ describe HexaPDF::Layout::WidthFromPolygon do
|
|
60
67
|
assert_equal([5, 5], ws.call(4, 2))
|
61
68
|
end
|
62
69
|
|
70
|
+
it "works in case of small floating point differences" do
|
71
|
+
ws = create_width_spec(Geom2D::Polygon([0, 0], [10, 0], [10, 5.99999999999994], [8, 6], [8, 10],
|
72
|
+
[6, 10], [6, 5], [0, 5]))
|
73
|
+
assert_equal([6, 4], ws.call(4.0, 3.0))
|
74
|
+
end
|
75
|
+
|
63
76
|
describe "multiple polygons" do
|
64
77
|
it "rectangle in rectangle" do
|
65
78
|
ws = create_width_spec(Geom2D::PolygonSet(Geom2D::Polygon([0, 0], [0, 10], [10, 10], [10, 0]),
|
@@ -52,7 +52,7 @@ describe HexaPDF::Task::Optimize do
|
|
52
52
|
describe "compact" do
|
53
53
|
it "compacts the document" do
|
54
54
|
@doc.task(:optimize, compact: true)
|
55
|
-
assert_equal(1, @doc.revisions.
|
55
|
+
assert_equal(1, @doc.revisions.count)
|
56
56
|
assert_equal(2, @doc.each(only_current: false).to_a.size)
|
57
57
|
refute_equal(@obj2, @doc.object(@obj2))
|
58
58
|
refute_equal(@obj3, @doc.object(@obj3))
|
@@ -81,8 +81,8 @@ describe HexaPDF::Task::Optimize do
|
|
81
81
|
end
|
82
82
|
|
83
83
|
it "compacts and deletes xref streams" do
|
84
|
-
@doc.add({Type: :XRef},
|
85
|
-
@doc.add({Type: :XRef},
|
84
|
+
@doc.revisions.all[0].add(@doc.wrap({Type: :XRef}, oid: @doc.revisions.next_oid))
|
85
|
+
@doc.revisions.all[1].add(@doc.wrap({Type: :XRef}, oid: @doc.revisions.next_oid))
|
86
86
|
@doc.task(:optimize, compact: true, xref_streams: :delete)
|
87
87
|
assert_no_xrefstms
|
88
88
|
assert_default_deleted
|
@@ -108,7 +108,9 @@ describe HexaPDF::Task::Optimize do
|
|
108
108
|
assert_objstms_generated
|
109
109
|
assert_default_deleted
|
110
110
|
assert_nil(@doc.object(objstm).value)
|
111
|
-
|
111
|
+
objstms = @doc.revisions.current.find_all {|obj| obj.type == :ObjStm }
|
112
|
+
assert_equal(2, objstms.size)
|
113
|
+
assert_equal(400, objstms[0].instance_variable_get(:@objects).size)
|
112
114
|
end
|
113
115
|
|
114
116
|
it "deletes object and xref streams" do
|
@@ -158,6 +160,17 @@ describe HexaPDF::Task::Optimize do
|
|
158
160
|
@doc.task(:optimize, compress_pages: true)
|
159
161
|
assert_equal("10 10 m\nq\nQ\nBI\n/Name 5 ID\ndataEI\n", page.contents)
|
160
162
|
end
|
163
|
+
|
164
|
+
it "uses parser.on_correctable_error to defer a decision regarding invalid operations" do
|
165
|
+
page = @doc.pages.add
|
166
|
+
page.contents = "10 20-30 m"
|
167
|
+
@doc.task(:optimize, compress_pages: true)
|
168
|
+
assert_equal("", page.contents)
|
169
|
+
|
170
|
+
@doc.config['parser.on_correctable_error'] = proc { true }
|
171
|
+
page.contents = "10 20-30 m"
|
172
|
+
assert_raises(HexaPDF::Error) { @doc.task(:optimize, compress_pages: true) }
|
173
|
+
end
|
161
174
|
end
|
162
175
|
|
163
176
|
describe "prune_page_resources" do
|
@@ -90,7 +90,7 @@ describe HexaPDF::Composer do
|
|
90
90
|
it "creates a new style if it does not exist based on the base argument" do
|
91
91
|
@composer.style(:base, font_size: 20)
|
92
92
|
assert_equal(20, @composer.style(:newstyle, subscript: true).font_size)
|
93
|
-
refute(
|
93
|
+
refute(@composer.style(:base).subscript)
|
94
94
|
assert_equal(10, @composer.style(:another_new, base: nil).font_size)
|
95
95
|
assert(@composer.style(:yet_another_new, base: :newstyle).subscript)
|
96
96
|
end
|
@@ -240,6 +240,24 @@ describe HexaPDF::Composer do
|
|
240
240
|
assert(box.style.subscript)
|
241
241
|
assert_same(@composer.document.images.add(image_path), box.image)
|
242
242
|
end
|
243
|
+
|
244
|
+
it "allows using a form XObject" do
|
245
|
+
form = @composer.document.add({Type: :XObject, Subtype: :Form, BBox: [0, 0, 10, 10]})
|
246
|
+
@composer.image(form, width: 10)
|
247
|
+
assert_equal(796, @composer.y)
|
248
|
+
assert_equal(36, @composer.x)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe "box" do
|
253
|
+
it "creates the named box and draws it on the canvas" do
|
254
|
+
box = nil
|
255
|
+
@composer.define_singleton_method(:draw_box) {|arg| box = arg }
|
256
|
+
image = @composer.document.images.add(File.join(TEST_DATA_DIR, 'images', 'gray.jpg'))
|
257
|
+
@composer.box(:list, width: 20) {|list| list.image(image) }
|
258
|
+
assert_equal(20, box.width)
|
259
|
+
assert_same(image, box.children[0].image)
|
260
|
+
end
|
243
261
|
end
|
244
262
|
|
245
263
|
describe "draw_box" do
|
@@ -318,4 +336,20 @@ describe HexaPDF::Composer do
|
|
318
336
|
end
|
319
337
|
end
|
320
338
|
end
|
339
|
+
|
340
|
+
describe "create_stamp" do
|
341
|
+
it "creates and returns a form XObject" do
|
342
|
+
stamp = @composer.create_stamp(10, 5)
|
343
|
+
assert_kind_of(HexaPDF::Type::Form, stamp)
|
344
|
+
assert_equal(10, stamp.width)
|
345
|
+
assert_equal(5, stamp.height)
|
346
|
+
end
|
347
|
+
|
348
|
+
it "allows using a block to draw on the canvas of the form XObject" do
|
349
|
+
stamp = @composer.create_stamp(10, 10) do |canvas|
|
350
|
+
canvas.line_width(5)
|
351
|
+
end
|
352
|
+
assert_equal("5 w\n", stamp.canvas.contents)
|
353
|
+
end
|
354
|
+
end
|
321
355
|
end
|
@@ -37,7 +37,7 @@ describe HexaPDF::DictionaryFields do
|
|
37
37
|
describe "convert" do
|
38
38
|
it "returns the converted object, using the first usable converter" do
|
39
39
|
doc = Minitest::Mock.new
|
40
|
-
doc.expect(:wrap, :data, [Hash,
|
40
|
+
doc.expect(:wrap, :data, [Hash], type: Integer)
|
41
41
|
@field.convert({}, doc)
|
42
42
|
doc.verify
|
43
43
|
|
@@ -67,20 +67,20 @@ describe HexaPDF::DictionaryFields do
|
|
67
67
|
end
|
68
68
|
|
69
69
|
it "allows conversion from a hash" do
|
70
|
-
@doc.expect(:wrap, :data, [Hash,
|
70
|
+
@doc.expect(:wrap, :data, [Hash], type: Class)
|
71
71
|
@field.convert({Test: :value}, @doc)
|
72
72
|
@doc.verify
|
73
73
|
end
|
74
74
|
|
75
75
|
it "allows conversion from a Dictionary" do
|
76
|
-
@doc.expect(:wrap, :data, [HexaPDF::Dictionary,
|
76
|
+
@doc.expect(:wrap, :data, [HexaPDF::Dictionary], type: Class)
|
77
77
|
@field.convert(HexaPDF::Dictionary.new({Test: :value}), @doc)
|
78
78
|
@doc.verify
|
79
79
|
end
|
80
80
|
|
81
81
|
it "allows conversion from an HexaPDF::Dictionary to a Stream if stream data is set" do
|
82
82
|
@field = self.class::Field.new(HexaPDF::Stream)
|
83
|
-
@doc.expect(:wrap, :data, [HexaPDF::Dictionary,
|
83
|
+
@doc.expect(:wrap, :data, [HexaPDF::Dictionary], type: Class)
|
84
84
|
data = HexaPDF::PDFData.new({}, 0, 0, "")
|
85
85
|
@field.convert(HexaPDF::Dictionary.new(data), @doc)
|
86
86
|
@doc.verify
|
@@ -108,7 +108,7 @@ describe HexaPDF::DictionaryFields do
|
|
108
108
|
end
|
109
109
|
|
110
110
|
it "allows conversion from an array" do
|
111
|
-
@doc.expect(:wrap, :data, [[1, 2],
|
111
|
+
@doc.expect(:wrap, :data, [[1, 2]], type: HexaPDF::PDFArray)
|
112
112
|
@field.convert([1, 2], @doc)
|
113
113
|
@doc.verify
|
114
114
|
end
|
@@ -134,7 +134,7 @@ describe HexaPDF::DictionaryFields do
|
|
134
134
|
assert_equal(Encoding::UTF_8, str.encoding)
|
135
135
|
end
|
136
136
|
|
137
|
-
def
|
137
|
+
def config
|
138
138
|
HexaPDF::Configuration.with_defaults
|
139
139
|
end
|
140
140
|
|
@@ -208,14 +208,14 @@ describe HexaPDF::DictionaryFields do
|
|
208
208
|
|
209
209
|
it "allows conversion from a string" do
|
210
210
|
@doc = Minitest::Mock.new
|
211
|
-
@doc.expect(:wrap, :data, [{F: 'test'},
|
211
|
+
@doc.expect(:wrap, :data, [{F: 'test'}], type: HexaPDF::Type::FileSpecification)
|
212
212
|
@field.convert('test', @doc)
|
213
213
|
@doc.verify
|
214
214
|
end
|
215
215
|
|
216
216
|
it "allows conversion from a hash/dictionary" do
|
217
217
|
@doc = Minitest::Mock.new
|
218
|
-
@doc.expect(:wrap, :data, [{F: 'test'},
|
218
|
+
@doc.expect(:wrap, :data, [{F: 'test'}], type: HexaPDF::Type::FileSpecification)
|
219
219
|
@field.convert({F: 'test'}, @doc)
|
220
220
|
@doc.verify
|
221
221
|
end
|
@@ -232,7 +232,7 @@ describe HexaPDF::DictionaryFields do
|
|
232
232
|
|
233
233
|
it "allows conversion to a Rectangle from an Array" do
|
234
234
|
doc = Minitest::Mock.new
|
235
|
-
doc.expect(:wrap, :data, [[0, 1, 2, 3],
|
235
|
+
doc.expect(:wrap, :data, [[0, 1, 2, 3]], type: HexaPDF::Rectangle)
|
236
236
|
@field.convert([0, 1, 2, 3], doc)
|
237
237
|
doc.verify
|
238
238
|
end
|
@@ -240,7 +240,7 @@ describe HexaPDF::DictionaryFields do
|
|
240
240
|
it "allows conversion to a Rectangle from a HexaPDF::PDFArray" do
|
241
241
|
data = HexaPDF::PDFArray.new([0, 1, 2, 3])
|
242
242
|
doc = Minitest::Mock.new
|
243
|
-
doc.expect(:wrap, :data, [data,
|
243
|
+
doc.expect(:wrap, :data, [data], type: HexaPDF::Rectangle)
|
244
244
|
@field.convert(data, doc)
|
245
245
|
doc.verify
|
246
246
|
end
|