hexapdf 0.11.9 → 0.12.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 +82 -0
- data/LICENSE +1 -1
- data/examples/001-hello_world.rb +1 -1
- data/examples/002-graphics.rb +1 -1
- data/examples/003-arcs.rb +1 -1
- data/examples/004-optimizing.rb +1 -1
- data/examples/005-merging.rb +1 -1
- data/examples/006-standard_pdf_fonts.rb +1 -1
- data/examples/007-truetype.rb +1 -1
- data/examples/008-show_char_bboxes.rb +1 -1
- data/examples/009-text_layouter_alignment.rb +1 -1
- data/examples/010-text_layouter_inline_boxes.rb +1 -1
- data/examples/011-text_layouter_line_wrapping.rb +1 -1
- data/examples/012-text_layouter_styling.rb +1 -1
- data/examples/013-text_layouter_shapes.rb +1 -1
- data/examples/014-text_in_polygon.rb +1 -1
- data/examples/015-boxes.rb +1 -1
- data/examples/016-frame_automatic_box_placement.rb +1 -1
- data/examples/017-frame_text_flow.rb +1 -1
- data/examples/018-composer.rb +1 -1
- data/examples/019-acro_form.rb +51 -0
- data/lib/hexapdf.rb +1 -1
- data/lib/hexapdf/cli.rb +3 -1
- data/lib/hexapdf/cli/batch.rb +1 -1
- data/lib/hexapdf/cli/command.rb +18 -9
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/form.rb +240 -0
- data/lib/hexapdf/cli/image2pdf.rb +1 -1
- data/lib/hexapdf/cli/images.rb +1 -1
- data/lib/hexapdf/cli/info.rb +1 -1
- data/lib/hexapdf/cli/inspect.rb +1 -1
- data/lib/hexapdf/cli/merge.rb +1 -1
- data/lib/hexapdf/cli/modify.rb +1 -1
- 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/composer.rb +2 -2
- data/lib/hexapdf/configuration.rb +66 -11
- data/lib/hexapdf/content.rb +3 -1
- data/lib/hexapdf/content/canvas.rb +5 -18
- data/lib/hexapdf/content/color_space.rb +111 -32
- data/lib/hexapdf/content/graphic_object.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 +1 -1
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
- data/lib/hexapdf/content/graphics_state.rb +1 -1
- data/lib/hexapdf/content/operator.rb +9 -9
- data/lib/hexapdf/content/parser.rb +18 -5
- data/lib/hexapdf/content/processor.rb +1 -1
- data/lib/hexapdf/content/transformation_matrix.rb +1 -1
- data/lib/hexapdf/data_dir.rb +1 -1
- data/lib/hexapdf/dictionary.rb +1 -1
- data/lib/hexapdf/dictionary_fields.rb +1 -1
- data/lib/hexapdf/document.rb +14 -5
- 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/pages.rb +3 -14
- data/lib/hexapdf/encryption.rb +1 -1
- 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 +1 -1
- 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/error.rb +1 -1
- data/lib/hexapdf/filter.rb +3 -3
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.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/{jpx_decode.rb → pass_through.rb} +5 -5
- data/lib/hexapdf/filter/predictor.rb +1 -1
- data/lib/hexapdf/filter/run_length_decode.rb +1 -1
- data/lib/hexapdf/font/cmap.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/encoding.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 +1 -1
- 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/invalid_glyph.rb +1 -1
- data/lib/hexapdf/font/true_type.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.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_wrapper.rb +54 -51
- data/lib/hexapdf/font/type1.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_wrapper.rb +67 -51
- data/lib/hexapdf/font_loader.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/image_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/importer.rb +2 -4
- data/lib/hexapdf/layout.rb +1 -1
- data/lib/hexapdf/layout/box.rb +1 -1
- data/lib/hexapdf/layout/frame.rb +1 -1
- data/lib/hexapdf/layout/image_box.rb +1 -1
- data/lib/hexapdf/layout/inline_box.rb +1 -1
- data/lib/hexapdf/layout/line.rb +1 -1
- data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
- data/lib/hexapdf/layout/style.rb +1 -1
- data/lib/hexapdf/layout/text_box.rb +1 -1
- data/lib/hexapdf/layout/text_fragment.rb +1 -1
- data/lib/hexapdf/layout/text_layouter.rb +1 -1
- data/lib/hexapdf/layout/text_shaper.rb +1 -1
- data/lib/hexapdf/layout/width_from_polygon.rb +1 -1
- data/lib/hexapdf/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +2 -2
- data/lib/hexapdf/parser.rb +4 -3
- data/lib/hexapdf/pdf_array.rb +1 -1
- data/lib/hexapdf/rectangle.rb +31 -1
- data/lib/hexapdf/reference.rb +1 -1
- data/lib/hexapdf/revision.rb +2 -1
- data/lib/hexapdf/revisions.rb +1 -1
- data/lib/hexapdf/serializer.rb +1 -1
- data/lib/hexapdf/stream.rb +1 -1
- data/lib/hexapdf/task.rb +1 -1
- data/lib/hexapdf/task/dereference.rb +1 -1
- data/lib/hexapdf/task/optimize.rb +1 -1
- data/lib/hexapdf/tokenizer.rb +1 -1
- data/lib/hexapdf/type.rb +1 -1
- data/lib/hexapdf/type/acro_form.rb +7 -1
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +401 -0
- data/lib/hexapdf/type/acro_form/button_field.rb +300 -0
- data/lib/hexapdf/type/acro_form/choice_field.rb +220 -0
- data/lib/hexapdf/type/acro_form/field.rb +220 -17
- data/lib/hexapdf/type/acro_form/form.rb +157 -7
- data/lib/hexapdf/type/acro_form/text_field.rb +186 -0
- data/lib/hexapdf/type/acro_form/variable_text_field.rb +122 -0
- data/lib/hexapdf/type/action.rb +1 -1
- data/lib/hexapdf/type/actions.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/annotation.rb +73 -3
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/annotations/link.rb +2 -2
- 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 +239 -2
- data/lib/hexapdf/type/catalog.rb +21 -1
- 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 +18 -1
- data/lib/hexapdf/type/font_descriptor.rb +2 -2
- 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 +16 -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 +3 -1
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/names.rb +1 -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 +8 -11
- data/lib/hexapdf/type/resources.rb +16 -3
- data/lib/hexapdf/type/trailer.rb +2 -3
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +1 -1
- data/lib/hexapdf/utils/bit_field.rb +38 -24
- 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 +1 -1
- data/lib/hexapdf/version.rb +2 -2
- data/lib/hexapdf/writer.rb +1 -1
- data/lib/hexapdf/xref_section.rb +1 -1
- data/test/hexapdf/content/common.rb +2 -2
- data/test/hexapdf/content/test_color_space.rb +71 -8
- data/test/hexapdf/content/test_operator.rb +22 -22
- data/test/hexapdf/content/test_parser.rb +14 -0
- data/test/hexapdf/document/test_fonts.rb +1 -1
- data/test/hexapdf/document/test_pages.rb +6 -6
- data/test/hexapdf/font/test_true_type_wrapper.rb +10 -7
- data/test/hexapdf/font/test_type1_wrapper.rb +32 -8
- data/test/hexapdf/test_document.rb +12 -0
- data/test/hexapdf/test_parser.rb +10 -0
- data/test/hexapdf/test_rectangle.rb +14 -0
- data/test/hexapdf/test_revision.rb +3 -0
- data/test/hexapdf/test_writer.rb +2 -2
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +515 -0
- data/test/hexapdf/type/acro_form/test_button_field.rb +276 -0
- data/test/hexapdf/type/acro_form/test_choice_field.rb +137 -0
- data/test/hexapdf/type/acro_form/test_field.rb +124 -6
- data/test/hexapdf/type/acro_form/test_form.rb +189 -22
- data/test/hexapdf/type/acro_form/test_text_field.rb +119 -0
- data/test/hexapdf/type/acro_form/test_variable_text_field.rb +77 -0
- data/test/hexapdf/type/annotations/test_text.rb +1 -1
- data/test/hexapdf/type/annotations/test_widget.rb +199 -0
- data/test/hexapdf/type/test_annotation.rb +45 -0
- data/test/hexapdf/type/test_catalog.rb +18 -0
- data/test/hexapdf/type/test_font.rb +5 -0
- data/test/hexapdf/type/test_font_type1.rb +8 -0
- data/test/hexapdf/type/test_image.rb +7 -0
- data/test/hexapdf/type/test_page_tree_node.rb +20 -12
- data/test/hexapdf/type/test_resources.rb +20 -0
- data/test/hexapdf/type/test_trailer.rb +4 -0
- data/test/hexapdf/utils/test_bit_field.rb +13 -1
- data/test/test_helper.rb +1 -1
- metadata +37 -18
- data/lib/hexapdf/filter/dct_decode.rb +0 -60
|
@@ -8,7 +8,7 @@ describe HexaPDF::Type::Annotations::Text do
|
|
|
8
8
|
before do
|
|
9
9
|
@doc = HexaPDF::Document.new
|
|
10
10
|
@doc.version = '1.5'
|
|
11
|
-
@annot = HexaPDF::Type::Annotations::Text.new({Rect: [0, 0, 1, 1]}, document: @doc)
|
|
11
|
+
@annot = HexaPDF::Type::Annotations::Text.new({Rect: [0, 0, 1, 1]}, document: @doc, oid: 1)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
describe "validation" do
|
|
@@ -22,3 +22,202 @@ describe HexaPDF::Type::Annotations::Widget::AppearanceCharacteristics do
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
|
+
|
|
26
|
+
describe HexaPDF::Type::Annotations::Widget do
|
|
27
|
+
before do
|
|
28
|
+
@doc = HexaPDF::Document.new
|
|
29
|
+
@widget = @doc.wrap({Type: :Annot, Subtype: :Widget})
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "form_field" do
|
|
33
|
+
it "works for the field and widget being the same object" do
|
|
34
|
+
@widget[:FT] = :Tx
|
|
35
|
+
@widget[:T] = 'field'
|
|
36
|
+
result = @widget.form_field
|
|
37
|
+
assert_kind_of(HexaPDF::Type::AcroForm::TextField, result)
|
|
38
|
+
assert_same(@widget.data, result.data)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "works for a field with a parent field and the widget being the same object" do
|
|
42
|
+
@widget[:Parent] = {FT: :Tx, T: 'parent', Kids: [@widget]}
|
|
43
|
+
@widget[:T] = 'field'
|
|
44
|
+
result = @widget.form_field
|
|
45
|
+
assert_kind_of(HexaPDF::Type::AcroForm::TextField, result)
|
|
46
|
+
assert_same(@widget.data, result.data)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "works for the widget being in the /Kids array of the field" do
|
|
50
|
+
@widget[:Parent] = {FT: :Tx, T: 'parent', Kids: [@widget]}
|
|
51
|
+
result = @widget.form_field
|
|
52
|
+
assert_kind_of(HexaPDF::Type::AcroForm::TextField, result)
|
|
53
|
+
refute_same(@widget.data, result.data)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe "background_color" do
|
|
58
|
+
it "returns the current background color" do
|
|
59
|
+
assert_nil(@widget.background_color)
|
|
60
|
+
@widget[:MK] = {BG: [1]}
|
|
61
|
+
assert_equal([1], @widget.background_color.components)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "sets the color and returns self" do
|
|
65
|
+
assert_same(@widget, @widget.background_color(51))
|
|
66
|
+
assert_equal([0.2], @widget.background_color.components)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe "border_style" do
|
|
71
|
+
before do
|
|
72
|
+
@widget[:MK] = {BC: [1, 0, 1]}
|
|
73
|
+
@color = HexaPDF::Content::ColorSpace.prenormalized_device_color([1, 0, 1])
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe "getter" do
|
|
77
|
+
it "no /Border, /BS or /MK set" do
|
|
78
|
+
@widget.delete(:MK)
|
|
79
|
+
assert_equal([1, nil, :solid, 0, 0], @widget.border_style.to_a)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "no /Border, /BS but with /MK empty" do
|
|
83
|
+
@widget[:MK].delete(:BC)
|
|
84
|
+
assert_equal([1, nil, :solid, 0, 0], @widget.border_style.to_a)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "uses the color from /MK" do
|
|
88
|
+
assert_equal([1, @color, :solid, 0, 0], @widget.border_style.to_a)
|
|
89
|
+
@widget[:MK][:BC] = []
|
|
90
|
+
assert_equal([1, nil, :solid, 0, 0], @widget.border_style.to_a)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "uses the data from /Border" do
|
|
94
|
+
@widget[:Border] = [1, 2, 3, [1, 2]]
|
|
95
|
+
assert_equal([3, @color, [1, 2], 1, 2], @widget.border_style.to_a)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "uses the data from /BS, overriding /Border values" do
|
|
99
|
+
@widget[:Border] = [1, 2, 3, [1, 2]]
|
|
100
|
+
@widget[:BS] = {W: 5, S: :D, D: [5, 6]}
|
|
101
|
+
assert_equal([5, @color, [5, 6], 0, 0], @widget.border_style.to_a)
|
|
102
|
+
|
|
103
|
+
[[:S, :solid], [:D, [5, 6]], [:B, :beveled], [:I, :inset],
|
|
104
|
+
[:U, :underlined], [:Unknown, :solid]].each do |val, result|
|
|
105
|
+
@widget[:BS] = {S: val, D: [5, 6]}
|
|
106
|
+
assert_equal([1, @color, result, 0, 0], @widget.border_style.to_a)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
describe "setter" do
|
|
112
|
+
it "returns self" do
|
|
113
|
+
assert_equal(@widget, @widget.border_style(width: 1))
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "sets the color" do
|
|
117
|
+
@widget.border_style(color: [1.0, 51, 1.0])
|
|
118
|
+
assert_equal([1, 0.2, 1], @widget[:MK][:BC].value)
|
|
119
|
+
|
|
120
|
+
@widget.border_style(color: :transparent)
|
|
121
|
+
assert_equal([], @widget[:MK][:BC].value)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "sets the width" do
|
|
125
|
+
@widget.border_style(width: 2)
|
|
126
|
+
assert_equal(2, @widget[:BS][:W])
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "sets the style" do
|
|
130
|
+
[[:solid, :S], [[5, 6], :D], [:beveled, :B], [:inset, :I], [:underlined, :U]].each do |val, r|
|
|
131
|
+
@widget.border_style(style: val)
|
|
132
|
+
assert_equal(r, @widget[:BS][:S])
|
|
133
|
+
assert_equal(val, @widget[:BS][:D].value) if r == :D
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "overrides all priorly set values" do
|
|
138
|
+
@widget.border_style(width: 3, style: :inset, color: [1])
|
|
139
|
+
@widget.border_style(width: 5)
|
|
140
|
+
border_style = @widget.border_style
|
|
141
|
+
assert_equal(:solid, border_style.style)
|
|
142
|
+
assert_equal([0], border_style.color.components)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "raises an error for an unknown style" do
|
|
146
|
+
assert_raises(ArgumentError) { @widget.border_style(style: :unknown) }
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
describe "marker_style" do
|
|
152
|
+
before do
|
|
153
|
+
@chars = %w[4 l 8 u n H S]
|
|
154
|
+
@values = [:check, :circle, :cross, :diamond, :square, :star, 'S']
|
|
155
|
+
@widget[:Parent] = {FT: :Btn}
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
describe "style" do
|
|
159
|
+
it "returns the style" do
|
|
160
|
+
@chars.zip(@values) do |char, result|
|
|
161
|
+
@widget[:MK] = {CA: char}
|
|
162
|
+
assert_equal(result, @widget.marker_style.style)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "returns the correct default button style depending on the field" do
|
|
167
|
+
@widget.form_field.initialize_as_check_box
|
|
168
|
+
assert_equal(:check, @widget.marker_style.style)
|
|
169
|
+
@widget.form_field.initialize_as_radio_button
|
|
170
|
+
assert_equal(:circle, @widget.marker_style.style)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it "sets the button style" do
|
|
174
|
+
@values.zip(@chars) do |argument, char|
|
|
175
|
+
@widget.marker_style(style: argument)
|
|
176
|
+
assert_equal(char, @widget[:MK][:CA])
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "fails if an invalid argument is provided" do
|
|
181
|
+
assert_raises(ArgumentError) { @widget.marker_style(style: 5) }
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
describe "size" do
|
|
186
|
+
it "returns the size" do
|
|
187
|
+
@widget.form_field[:DA] = "/F 15 Tf"
|
|
188
|
+
assert_equal(15, @widget.marker_style.size)
|
|
189
|
+
@widget[:DA] = "/F 10 Tf"
|
|
190
|
+
assert_equal(10, @widget.marker_style.size)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "returns the default size if none is set" do
|
|
194
|
+
assert_equal(0, @widget.marker_style.size)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
it "sets the given size" do
|
|
198
|
+
@widget.marker_style(size: 10)
|
|
199
|
+
assert_equal('/ZaDb 10 Tf 0.0 g', @widget[:DA])
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
describe "color" do
|
|
204
|
+
it "returns the color" do
|
|
205
|
+
@widget.form_field[:DA] = "0 1 0 rg"
|
|
206
|
+
assert_equal([0, 1, 0], @widget.marker_style.color.components)
|
|
207
|
+
@widget[:DA] = "0 0 1 rg"
|
|
208
|
+
assert_equal([0, 0, 1], @widget.marker_style.color.components)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it "returns the default color if none is set" do
|
|
212
|
+
assert_equal([0], @widget.marker_style.color.components)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
it "sets the given color" do
|
|
216
|
+
@widget.marker_style(color: [1.0, 51, 1.0])
|
|
217
|
+
assert_equal([1, 0.2, 1], @widget.marker_style.color.components)
|
|
218
|
+
@widget.marker_style(color: [1.0, 20, 1.0, 1.0])
|
|
219
|
+
assert_equal([1, 0.2, 1, 1], @widget.marker_style.color.components)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
@@ -4,12 +4,57 @@ require 'test_helper'
|
|
|
4
4
|
require 'hexapdf/document'
|
|
5
5
|
require 'hexapdf/type/annotation'
|
|
6
6
|
|
|
7
|
+
describe HexaPDF::Type::Annotation::AppearanceDictionary do
|
|
8
|
+
before do
|
|
9
|
+
@doc = HexaPDF::Document.new
|
|
10
|
+
@ap = @doc.add({N: :n, D: :d, R: :r}, type: :XXAppearanceDictionary)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "resolves the normal appearance" do
|
|
14
|
+
assert_equal(:n, @ap.normal_appearance)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "resolves the rollover appearance" do
|
|
18
|
+
assert_equal(:r, @ap.rollover_appearance)
|
|
19
|
+
@ap.delete(:R)
|
|
20
|
+
assert_equal(:n, @ap.rollover_appearance)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "resolves the down appearance" do
|
|
24
|
+
assert_equal(:d, @ap.down_appearance)
|
|
25
|
+
@ap.delete(:D)
|
|
26
|
+
assert_equal(:n, @ap.down_appearance)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
7
30
|
describe HexaPDF::Type::Annotation do
|
|
8
31
|
before do
|
|
9
32
|
@doc = HexaPDF::Document.new
|
|
10
33
|
@annot = @doc.add({Type: :Annot, F: 0b100011})
|
|
11
34
|
end
|
|
12
35
|
|
|
36
|
+
it "must always be indirect" do
|
|
37
|
+
@annot.must_be_indirect = false
|
|
38
|
+
assert(@annot.must_be_indirect?)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "returns the appearance dictionary" do
|
|
42
|
+
@annot[:AP] = :yes
|
|
43
|
+
assert_equal(:yes, @annot.appearance)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "checks whether an appearance exists" do
|
|
47
|
+
refute(@annot.appearance?)
|
|
48
|
+
@annot[:AP] = {N: {}}
|
|
49
|
+
refute(@annot.appearance?)
|
|
50
|
+
@annot[:AP][:N] = @doc.wrap({}, stream: '')
|
|
51
|
+
assert(@annot.appearance?)
|
|
52
|
+
@annot[:AP][:N] = {okay: @doc.wrap({}, stream: '')}
|
|
53
|
+
assert(@annot.appearance?)
|
|
54
|
+
@annot[:AP][:N][:Off] = :other
|
|
55
|
+
refute(@annot.appearance?)
|
|
56
|
+
end
|
|
57
|
+
|
|
13
58
|
describe "flags" do
|
|
14
59
|
it "returns all flags" do
|
|
15
60
|
assert_equal([:invisible, :hidden, :no_view], @annot.flags)
|
|
@@ -21,6 +21,24 @@ describe HexaPDF::Type::Catalog do
|
|
|
21
21
|
assert_equal(:Pages, pages.type)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
describe "acro_form" do
|
|
25
|
+
it "returns an existing form object" do
|
|
26
|
+
@catalog[:AcroForm] = :test
|
|
27
|
+
assert_equal(:test, @catalog.acro_form)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "returns an existing form object even if create: true" do
|
|
31
|
+
@catalog[:AcroForm] = :test
|
|
32
|
+
assert_equal(:test, @catalog.acro_form(create: true))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "creates a new AcroForm object with defaults if create: true" do
|
|
36
|
+
form = @catalog.acro_form(create: true)
|
|
37
|
+
assert_kind_of(HexaPDF::Type::AcroForm::Form, form)
|
|
38
|
+
assert(form[:DA])
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
24
42
|
describe "validation" do
|
|
25
43
|
it "creates the page tree if necessary" do
|
|
26
44
|
refute(@catalog.validate(auto_correct: false))
|
|
@@ -17,6 +17,11 @@ describe HexaPDF::Type::Font do
|
|
|
17
17
|
@font = @doc.add({Type: :Font, BaseFont: :TestFont, FontDescriptor: fd, ToUnicode: cmap})
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
it "allows setting and returning a font wrapper object" do
|
|
21
|
+
@font.font_wrapper = :fake_wrapper
|
|
22
|
+
assert_equal(:fake_wrapper, @font.font_wrapper)
|
|
23
|
+
end
|
|
24
|
+
|
|
20
25
|
it "must always be an indirect" do
|
|
21
26
|
assert(@font.must_be_indirect?)
|
|
22
27
|
end
|
|
@@ -57,6 +57,14 @@ describe HexaPDF::Type::FontType1 do
|
|
|
57
57
|
FirstChar: 32, LastChar: 34, Widths: [600, 0, 700]})
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
+
it "can create a usable font wrapper for the standard fonts" do
|
|
61
|
+
wrapper = @font.font_wrapper
|
|
62
|
+
assert(wrapper)
|
|
63
|
+
assert_same(@font, wrapper.pdf_object)
|
|
64
|
+
assert_equal(@font[:BaseFont], wrapper.wrapped_font.font_name.intern)
|
|
65
|
+
assert_same(wrapper, @font.font_wrapper)
|
|
66
|
+
end
|
|
67
|
+
|
|
60
68
|
describe "encoding" do
|
|
61
69
|
it "returns the the standard font's encoding" do
|
|
62
70
|
@font.delete(:Encoding)
|
|
@@ -120,6 +120,12 @@ describe HexaPDF::Type::Image do
|
|
|
120
120
|
assert_equal(:other, info.color_space)
|
|
121
121
|
assert_equal(-1, info.components)
|
|
122
122
|
end
|
|
123
|
+
|
|
124
|
+
it "processes the SMask entry" do
|
|
125
|
+
@image[:SMask] = :something
|
|
126
|
+
info = @image.info
|
|
127
|
+
refute(info.writable)
|
|
128
|
+
end
|
|
123
129
|
end
|
|
124
130
|
|
|
125
131
|
describe "write" do
|
|
@@ -182,6 +188,7 @@ describe HexaPDF::Type::Image do
|
|
|
182
188
|
end
|
|
183
189
|
|
|
184
190
|
Dir.glob(File.join(TEST_DATA_DIR, 'images', '*.png')).each do |png_file|
|
|
191
|
+
next if png_file =~ /alpha/
|
|
185
192
|
it "writes #{File.basename(png_file)} correctly as PNG file" do
|
|
186
193
|
image = @doc.images.add(png_file)
|
|
187
194
|
if png_file =~ /greyscale-1bit.png/ # force use of arrays for one image
|
|
@@ -155,36 +155,44 @@ describe HexaPDF::Type::PageTreeNode do
|
|
|
155
155
|
end
|
|
156
156
|
|
|
157
157
|
it "deletes the correct page by index" do
|
|
158
|
-
|
|
158
|
+
@root.delete_page(2)
|
|
159
159
|
assert_equal(2, @kid12.page_count)
|
|
160
160
|
assert_equal(4, @kid1.page_count)
|
|
161
161
|
assert_equal(7, @root.page_count)
|
|
162
|
-
|
|
162
|
+
assert(@pages[2].null?)
|
|
163
163
|
|
|
164
|
-
|
|
164
|
+
@root.delete_page(4)
|
|
165
165
|
assert_equal(6, @root.page_count)
|
|
166
|
-
|
|
166
|
+
assert(@pages[5].null?)
|
|
167
167
|
end
|
|
168
168
|
|
|
169
169
|
it "deletes the given page" do
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
@root.delete_page(@pages[2])
|
|
171
|
+
assert(@pages[2].null?)
|
|
172
|
+
@root.delete_page(@pages[5])
|
|
173
|
+
assert(@pages[5].null?)
|
|
172
174
|
end
|
|
173
175
|
|
|
174
176
|
it "allows deleting a page from an intermediary node" do
|
|
175
|
-
|
|
177
|
+
@kid1.delete_page(@pages[2])
|
|
176
178
|
assert_equal(7, @root.page_count)
|
|
177
179
|
end
|
|
178
180
|
|
|
179
181
|
it "does nothing if the page index is not valid" do
|
|
180
|
-
|
|
181
|
-
|
|
182
|
+
@root.delete_page(20)
|
|
183
|
+
@root.delete_page(-20)
|
|
182
184
|
assert_equal(8, @root.page_count)
|
|
183
185
|
end
|
|
184
186
|
|
|
185
|
-
it "does nothing if the page
|
|
187
|
+
it "does nothing if the page has already been deleted" do
|
|
188
|
+
@root.delete_page(@pages[2])
|
|
189
|
+
@root.delete_page(@pages[2])
|
|
190
|
+
assert_equal(7, @root.page_count)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "fails if the page is not in its parent's /Kids array" do
|
|
186
194
|
@kid12[:Kids].delete_at(0)
|
|
187
|
-
|
|
195
|
+
assert_raises(HexaPDF::Error) { @root.delete_page(@pages[2]) }
|
|
188
196
|
assert_equal(8, @root.page_count)
|
|
189
197
|
end
|
|
190
198
|
|
|
@@ -193,7 +201,7 @@ describe HexaPDF::Type::PageTreeNode do
|
|
|
193
201
|
page = @doc.add({Type: :Page, Parent: pages})
|
|
194
202
|
pages[:Kids] << page
|
|
195
203
|
|
|
196
|
-
|
|
204
|
+
@root.delete_page(page)
|
|
197
205
|
assert_equal(8, @root.page_count)
|
|
198
206
|
end
|
|
199
207
|
end
|
|
@@ -25,6 +25,10 @@ describe HexaPDF::Type::Resources do
|
|
|
25
25
|
assert_kind_of(HexaPDF::Content::ColorSpace::Universal, @res.color_space(:CSName))
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
it "works for the Pattern color space" do
|
|
29
|
+
assert_kind_of(HexaPDF::Content::ColorSpace::Universal, @res.color_space(:Pattern))
|
|
30
|
+
end
|
|
31
|
+
|
|
28
32
|
it "returns the universal color space for unknown color spaces, with resolved references" do
|
|
29
33
|
data = @doc.add({Some: :data})
|
|
30
34
|
@res[:ColorSpace] = {CSName: [:SomeUnknownColorSpace,
|
|
@@ -168,6 +172,22 @@ describe HexaPDF::Type::Resources do
|
|
|
168
172
|
end
|
|
169
173
|
end
|
|
170
174
|
|
|
175
|
+
describe "pattern" do
|
|
176
|
+
it "invokes the object_getter method" do
|
|
177
|
+
assert_method_invoked(@res, :object_getter, [:Pattern, :test]) do
|
|
178
|
+
@res.pattern(:test)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
describe "add_pattern" do
|
|
184
|
+
it "invokes the object_setter method" do
|
|
185
|
+
assert_method_invoked(@res, :object_setter, [:Pattern, 'P', :test]) do
|
|
186
|
+
@res.add_pattern(:test)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
171
191
|
describe "validation" do
|
|
172
192
|
it "assigns the default value if ProcSet is not set" do
|
|
173
193
|
@res.validate
|
|
@@ -9,12 +9,16 @@ describe HexaPDF::Type::Trailer do
|
|
|
9
9
|
before do
|
|
10
10
|
@doc = Object.new
|
|
11
11
|
@doc.instance_variable_set(:@version, '1.2')
|
|
12
|
+
|
|
12
13
|
def (@doc).version=(v); @version = v; end
|
|
14
|
+
|
|
13
15
|
def (@doc).deref(obj); obj; end
|
|
16
|
+
|
|
14
17
|
def (@doc).wrap(obj, *)
|
|
15
18
|
(obj.kind_of?(Array) ? HexaPDF::PDFArray : HexaPDF::Dictionary).
|
|
16
19
|
new(obj, oid: (obj.oid rescue 0))
|
|
17
20
|
end
|
|
21
|
+
|
|
18
22
|
root = HexaPDF::Dictionary.new({}, oid: 3)
|
|
19
23
|
@obj = HexaPDF::Type::Trailer.new({Size: 10, Root: root}, document: @doc)
|
|
20
24
|
end
|