hexapdf 0.34.1 → 0.35.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 +59 -0
- data/examples/009-text_layouter_alignment.rb +7 -7
- data/examples/010-text_layouter_inline_boxes.rb +1 -1
- data/examples/011-text_layouter_line_wrapping.rb +2 -4
- data/examples/013-text_layouter_shapes.rb +9 -11
- data/examples/014-text_in_polygon.rb +2 -2
- data/examples/016-frame_automatic_box_placement.rb +6 -7
- data/examples/017-frame_text_flow.rb +2 -2
- data/examples/018-composer.rb +5 -6
- data/examples/020-column_box.rb +2 -2
- data/examples/021-list_box.rb +1 -1
- data/examples/027-composer_optional_content.rb +5 -5
- data/examples/028-frame_mask_mode.rb +23 -0
- data/examples/029-composer_fallback_fonts.rb +22 -0
- data/lib/hexapdf/cli/info.rb +1 -0
- data/lib/hexapdf/cli/inspect.rb +55 -2
- data/lib/hexapdf/composer.rb +2 -2
- data/lib/hexapdf/configuration.rb +61 -1
- data/lib/hexapdf/content/canvas.rb +63 -0
- data/lib/hexapdf/content/canvas_composer.rb +142 -0
- data/lib/hexapdf/content.rb +1 -0
- data/lib/hexapdf/dictionary.rb +14 -3
- data/lib/hexapdf/document/layout.rb +35 -13
- data/lib/hexapdf/encryption/standard_security_handler.rb +15 -0
- data/lib/hexapdf/error.rb +2 -1
- data/lib/hexapdf/font/invalid_glyph.rb +22 -6
- data/lib/hexapdf/font/true_type_wrapper.rb +48 -20
- data/lib/hexapdf/font/type1_wrapper.rb +48 -24
- data/lib/hexapdf/layout/box.rb +11 -8
- data/lib/hexapdf/layout/column_box.rb +5 -3
- data/lib/hexapdf/layout/frame.rb +77 -39
- data/lib/hexapdf/layout/image_box.rb +3 -3
- data/lib/hexapdf/layout/list_box.rb +20 -19
- data/lib/hexapdf/layout/style.rb +173 -68
- data/lib/hexapdf/layout/table_box.rb +3 -3
- data/lib/hexapdf/layout/text_box.rb +5 -5
- data/lib/hexapdf/layout/text_fragment.rb +50 -0
- data/lib/hexapdf/layout/text_layouter.rb +7 -6
- data/lib/hexapdf/object.rb +5 -2
- data/lib/hexapdf/pdf_array.rb +5 -0
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +16 -11
- data/lib/hexapdf/utils/sorted_tree_node.rb +0 -10
- data/lib/hexapdf/version.rb +1 -1
- data/test/hexapdf/content/test_canvas.rb +37 -0
- data/test/hexapdf/content/test_canvas_composer.rb +112 -0
- data/test/hexapdf/document/test_layout.rb +40 -12
- data/test/hexapdf/encryption/test_standard_security_handler.rb +43 -0
- data/test/hexapdf/font/test_invalid_glyph.rb +13 -1
- data/test/hexapdf/font/test_true_type_wrapper.rb +15 -2
- data/test/hexapdf/font/test_type1_wrapper.rb +21 -2
- data/test/hexapdf/layout/test_column_box.rb +14 -0
- data/test/hexapdf/layout/test_frame.rb +181 -95
- data/test/hexapdf/layout/test_list_box.rb +7 -7
- data/test/hexapdf/layout/test_style.rb +14 -10
- data/test/hexapdf/layout/test_table_box.rb +3 -3
- data/test/hexapdf/layout/test_text_box.rb +2 -2
- data/test/hexapdf/layout/test_text_fragment.rb +37 -0
- data/test/hexapdf/layout/test_text_layouter.rb +10 -10
- data/test/hexapdf/test_configuration.rb +49 -0
- data/test/hexapdf/test_dictionary.rb +1 -1
- data/test/hexapdf/test_object.rb +13 -12
- data/test/hexapdf/test_pdf_array.rb +9 -0
- data/test/hexapdf/test_writer.rb +3 -3
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +41 -13
- data/test/hexapdf/utils/test_sorted_tree_node.rb +1 -1
- metadata +7 -3
|
@@ -651,7 +651,7 @@ describe HexaPDF::Layout::TextLayouter do
|
|
|
651
651
|
end
|
|
652
652
|
|
|
653
653
|
it "aligns the contents to the left" do
|
|
654
|
-
@style.
|
|
654
|
+
@style.text_align = :left
|
|
655
655
|
result = @layouter.fit(@items, 100, 100)
|
|
656
656
|
assert_equal(0, result.lines[0].x_offset)
|
|
657
657
|
assert_equal(80, result.lines[0].width)
|
|
@@ -661,7 +661,7 @@ describe HexaPDF::Layout::TextLayouter do
|
|
|
661
661
|
end
|
|
662
662
|
|
|
663
663
|
it "aligns the contents to the center" do
|
|
664
|
-
@style.
|
|
664
|
+
@style.text_align = :center
|
|
665
665
|
result = @layouter.fit(@items, 100, 100)
|
|
666
666
|
assert_equal(10, result.lines[0].x_offset)
|
|
667
667
|
result = @layouter.fit(@items, proc { 100 }, 100)
|
|
@@ -669,7 +669,7 @@ describe HexaPDF::Layout::TextLayouter do
|
|
|
669
669
|
end
|
|
670
670
|
|
|
671
671
|
it "aligns the contents to the right" do
|
|
672
|
-
@style.
|
|
672
|
+
@style.text_align = :right
|
|
673
673
|
result = @layouter.fit(@items, 100, 100)
|
|
674
674
|
assert_equal(20, result.lines[0].x_offset)
|
|
675
675
|
result = @layouter.fit(@items, proc { 100 }, 100)
|
|
@@ -683,28 +683,28 @@ describe HexaPDF::Layout::TextLayouter do
|
|
|
683
683
|
end
|
|
684
684
|
|
|
685
685
|
it "aligns the contents to the top" do
|
|
686
|
-
@style.
|
|
686
|
+
@style.text_valign = :top
|
|
687
687
|
result = @layouter.fit(@items, 40, 100)
|
|
688
688
|
assert_equal(result.lines[0].y_max, result.lines[0].y_offset)
|
|
689
689
|
assert_equal(40, result.height)
|
|
690
690
|
end
|
|
691
691
|
|
|
692
692
|
it "aligns the contents to the center" do
|
|
693
|
-
@style.
|
|
693
|
+
@style.text_valign = :center
|
|
694
694
|
result = @layouter.fit(@items, 40, 100)
|
|
695
695
|
assert_equal((100 - 40) / 2 + 20, result.lines[0].y_offset)
|
|
696
696
|
assert_equal(70, result.height)
|
|
697
697
|
end
|
|
698
698
|
|
|
699
699
|
it "aligns the contents to the bottom" do
|
|
700
|
-
@style.
|
|
700
|
+
@style.text_valign = :bottom
|
|
701
701
|
result = @layouter.fit(@items, 40, 100)
|
|
702
702
|
assert_equal(100 - 20 * 2 + 20, result.lines[0].y_offset)
|
|
703
703
|
assert_equal(100, result.height)
|
|
704
704
|
end
|
|
705
705
|
|
|
706
706
|
it "doesn't vertically align when layouting in variable-width mode" do
|
|
707
|
-
@style.
|
|
707
|
+
@style.text_valign = :bottom
|
|
708
708
|
result = @layouter.fit(@items, proc { 40 }, 100)
|
|
709
709
|
assert_equal(result.lines[0].y_max, result.lines[0].y_offset)
|
|
710
710
|
assert_equal(40, result.height)
|
|
@@ -723,7 +723,7 @@ describe HexaPDF::Layout::TextLayouter do
|
|
|
723
723
|
# Missing width: 100 - 90 = 10
|
|
724
724
|
# -> Each space must be doubled!
|
|
725
725
|
|
|
726
|
-
@style.
|
|
726
|
+
@style.text_align = :justify
|
|
727
727
|
result = @layouter.fit(items, 100, 100)
|
|
728
728
|
assert(result.remaining_items.empty?)
|
|
729
729
|
assert_equal(:success, result.status)
|
|
@@ -770,8 +770,8 @@ describe HexaPDF::Layout::TextLayouter do
|
|
|
770
770
|
|
|
771
771
|
it "respects the x- and y-offsets" do
|
|
772
772
|
top = 100
|
|
773
|
-
@layouter.style.
|
|
774
|
-
@layouter.style.
|
|
773
|
+
@layouter.style.text_valign = :center
|
|
774
|
+
@layouter.style.text_align = :center
|
|
775
775
|
|
|
776
776
|
result = @layouter.fit([@frag], @width, top)
|
|
777
777
|
result.draw(@canvas, 5, top)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'test_helper'
|
|
4
4
|
require 'hexapdf/configuration'
|
|
5
|
+
require 'hexapdf/document'
|
|
5
6
|
|
|
6
7
|
describe HexaPDF::Configuration do
|
|
7
8
|
before do
|
|
@@ -91,3 +92,51 @@ describe HexaPDF::Configuration do
|
|
|
91
92
|
end
|
|
92
93
|
end
|
|
93
94
|
end
|
|
95
|
+
|
|
96
|
+
describe "HexaPDF.font_on_invalid_glyph" do
|
|
97
|
+
before do
|
|
98
|
+
@doc = HexaPDF::Document.new
|
|
99
|
+
@font = @doc.fonts.add('Helvetica')
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def assert_glyph(font, codepoint, font_name, glyph_name)
|
|
103
|
+
invalid_glyph = HexaPDF::Font::InvalidGlyph.new(font, codepoint.chr("UTF-8"))
|
|
104
|
+
glyph = HexaPDF.font_on_invalid_glyph(codepoint, invalid_glyph)
|
|
105
|
+
|
|
106
|
+
assert_equal(1, glyph.size)
|
|
107
|
+
glyph = glyph.first
|
|
108
|
+
assert(glyph.valid?)
|
|
109
|
+
assert_equal(font_name, glyph.font_wrapper.wrapped_font.font_name)
|
|
110
|
+
assert_equal(glyph_name, glyph.name)
|
|
111
|
+
glyph
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "tries each fallback font and uses the first valid glyph" do
|
|
115
|
+
assert_glyph(@font, 10102, "ZapfDingbats", :a130)
|
|
116
|
+
assert_glyph(@font, 8855, "Symbol", :circlemultiply)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "takes the font variant into account" do
|
|
120
|
+
@doc.config['font.fallback'] = ['Times']
|
|
121
|
+
|
|
122
|
+
glyph = assert_glyph(@doc.fonts.add("Helvetica", variant: :bold), 65, "Times-Bold", :A)
|
|
123
|
+
assert(glyph.font_wrapper.bold?)
|
|
124
|
+
|
|
125
|
+
glyph = assert_glyph(@doc.fonts.add("Helvetica", variant: :italic), 65, "Times-Italic", :A)
|
|
126
|
+
assert(glyph.font_wrapper.italic?)
|
|
127
|
+
|
|
128
|
+
glyph = assert_glyph(@doc.fonts.add("Helvetica", variant: :bold_italic), 65, "Times-BoldItalic", :A)
|
|
129
|
+
assert(glyph.font_wrapper.bold?)
|
|
130
|
+
assert(glyph.font_wrapper.italic?)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "falls back to the :none variant of a fallback font if a more specific one doesn't exist" do
|
|
134
|
+
assert_glyph(@doc.fonts.add("Helvetica", variant: :bold), 9985, "ZapfDingbats", :a1)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "returns the given invalid glyph if no fallback glyph could be found" do
|
|
138
|
+
@doc.config['font.fallback'] = []
|
|
139
|
+
invalid_glyph = HexaPDF::Font::InvalidGlyph.new(@font, "A")
|
|
140
|
+
assert_equal([invalid_glyph], HexaPDF.font_on_invalid_glyph(65, invalid_glyph))
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -204,7 +204,7 @@ describe HexaPDF::Dictionary do
|
|
|
204
204
|
end
|
|
205
205
|
end
|
|
206
206
|
|
|
207
|
-
describe "
|
|
207
|
+
describe "perform_validation" do
|
|
208
208
|
before do
|
|
209
209
|
@test_class.define_field(:Inherited, type: [Array, Symbol], required: true, indirect: false)
|
|
210
210
|
@test_class.define_field(:AllowedValues, type: Integer, allowed_values: [1, 5])
|
data/test/hexapdf/test_object.rb
CHANGED
|
@@ -186,6 +186,19 @@ describe HexaPDF::Object do
|
|
|
186
186
|
refute(@obj.validate(auto_correct: false))
|
|
187
187
|
assert_equal([:before], invoked)
|
|
188
188
|
end
|
|
189
|
+
|
|
190
|
+
it "re-raises caught HexaPDF::Error exceptions" do
|
|
191
|
+
@obj.define_singleton_method(:perform_validation) { raise HexaPDF::Error, "Unknown" }
|
|
192
|
+
invoked = []
|
|
193
|
+
assert_raises(HexaPDF::Error) { @obj.validate {|*a| invoked << a } }
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it "catches errors raised in perform_validation and produces an appropriate message" do
|
|
197
|
+
@obj.define_singleton_method(:perform_validation) { raise "Unknown" }
|
|
198
|
+
invoked = []
|
|
199
|
+
refute(@obj.validate {|*a| invoked << a })
|
|
200
|
+
assert_equal([["Error: Unexpected value encountered", false, @obj]], invoked)
|
|
201
|
+
end
|
|
189
202
|
end
|
|
190
203
|
|
|
191
204
|
it "can represent itself during inspection" do
|
|
@@ -286,17 +299,5 @@ describe HexaPDF::Object do
|
|
|
286
299
|
obj.validate
|
|
287
300
|
assert_equal(1, obj.oid)
|
|
288
301
|
end
|
|
289
|
-
|
|
290
|
-
it "validates collection values" do
|
|
291
|
-
x = HexaPDF::Object.new(:x, document: @doc)
|
|
292
|
-
x.must_be_indirect = true
|
|
293
|
-
y = HexaPDF::Object.new(:y, document: @doc)
|
|
294
|
-
y.must_be_indirect = true
|
|
295
|
-
|
|
296
|
-
obj = HexaPDF::Object.new([1, 2, 3, [4, x], {X: [y, 5]}])
|
|
297
|
-
obj.validate
|
|
298
|
-
assert_equal(1, x.oid)
|
|
299
|
-
assert_equal(1, y.oid)
|
|
300
|
-
end
|
|
301
302
|
end
|
|
302
303
|
end
|
|
@@ -166,4 +166,13 @@ describe HexaPDF::PDFArray do
|
|
|
166
166
|
it "can be converted to a simple array" do
|
|
167
167
|
assert_equal([1, :data, "deref", @array[3]], @array.to_ary)
|
|
168
168
|
end
|
|
169
|
+
|
|
170
|
+
describe "perform_validation" do
|
|
171
|
+
it "validates nested objects" do
|
|
172
|
+
@array.value << HexaPDF::PDFArray.new([HexaPDF::Reference.new(1, 0)], document: self)
|
|
173
|
+
assert(@array.validate)
|
|
174
|
+
assert_kind_of(HexaPDF::Object, @array.value[2])
|
|
175
|
+
assert_kind_of(HexaPDF::Object, @array.value.last.value[0])
|
|
176
|
+
end
|
|
177
|
+
end
|
|
169
178
|
end
|
data/test/hexapdf/test_writer.rb
CHANGED
|
@@ -40,7 +40,7 @@ describe HexaPDF::Writer do
|
|
|
40
40
|
219
|
|
41
41
|
%%EOF
|
|
42
42
|
3 0 obj
|
|
43
|
-
<</Producer(HexaPDF version 0.
|
|
43
|
+
<</Producer(HexaPDF version 0.35.0)>>
|
|
44
44
|
endobj
|
|
45
45
|
xref
|
|
46
46
|
3 1
|
|
@@ -72,7 +72,7 @@ describe HexaPDF::Writer do
|
|
|
72
72
|
141
|
|
73
73
|
%%EOF
|
|
74
74
|
6 0 obj
|
|
75
|
-
<</Producer(HexaPDF version 0.
|
|
75
|
+
<</Producer(HexaPDF version 0.35.0)>>
|
|
76
76
|
endobj
|
|
77
77
|
2 0 obj
|
|
78
78
|
<</Length 10>>stream
|
|
@@ -214,7 +214,7 @@ describe HexaPDF::Writer do
|
|
|
214
214
|
<</Type/Page/MediaBox[0 0 595 842]/Parent 2 0 R/Resources<<>>>>
|
|
215
215
|
endobj
|
|
216
216
|
5 0 obj
|
|
217
|
-
<</Producer(HexaPDF version 0.
|
|
217
|
+
<</Producer(HexaPDF version 0.35.0)>>
|
|
218
218
|
endobj
|
|
219
219
|
4 0 obj
|
|
220
220
|
<</Root 1 0 R/Info 5 0 R/Size 6/Type/XRef/W[1 1 2]/Index[0 6]/Filter/FlateDecode/DecodeParms<</Columns 4/Predictor 12>>/Length 33>>stream
|
|
@@ -453,7 +453,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
|
453
453
|
before do
|
|
454
454
|
@widget[:Rect].height = 20
|
|
455
455
|
@widget[:Rect].width = 100
|
|
456
|
-
@field
|
|
456
|
+
@field[:V] = ''
|
|
457
457
|
end
|
|
458
458
|
|
|
459
459
|
it "uses the non-zero font size" do
|
|
@@ -477,7 +477,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
|
477
477
|
end
|
|
478
478
|
|
|
479
479
|
it "shrinks the font size if necessary to fit the rectangle width" do
|
|
480
|
-
@field
|
|
480
|
+
@field[:V] = "This is some arbitrary, long text"
|
|
481
481
|
@generator.create_appearances
|
|
482
482
|
assert_operators(@widget[:AP][:N].stream,
|
|
483
483
|
[:set_font_and_size, [:F1, 6.909955]],
|
|
@@ -498,7 +498,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
|
498
498
|
describe "single line text fields" do
|
|
499
499
|
describe "quadding e.g. text alignment" do
|
|
500
500
|
before do
|
|
501
|
-
@field
|
|
501
|
+
@field[:V] = 'Test'
|
|
502
502
|
@field.set_default_appearance_string(font_size: 10)
|
|
503
503
|
@widget[:Rect].height = 20
|
|
504
504
|
end
|
|
@@ -551,7 +551,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
|
551
551
|
|
|
552
552
|
describe "Javascript action AFNumber_Format" do
|
|
553
553
|
before do
|
|
554
|
-
@field
|
|
554
|
+
@field[:V] = '1234567.898765'
|
|
555
555
|
@action = {S: :JavaScript, JS: ''}
|
|
556
556
|
@field[:AA] = {F: @action}
|
|
557
557
|
end
|
|
@@ -576,7 +576,8 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
|
576
576
|
end
|
|
577
577
|
|
|
578
578
|
it "respects the negative value styling" do
|
|
579
|
-
@field
|
|
579
|
+
@field[:V] = '-1234567.898'
|
|
580
|
+
@widget[:Rect].height = 11.25
|
|
580
581
|
["-E1234567,90", "E1234567,90", "(E1234567,90)", "(E1234567,90)"].each_with_index do |result, style|
|
|
581
582
|
assert_format("2, 3, #{style}, 0, \"E\", true",
|
|
582
583
|
[[:set_device_rgb_non_stroking_color, [style % 2, 0.0, 0.0]],
|
|
@@ -597,8 +598,11 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
|
597
598
|
end
|
|
598
599
|
|
|
599
600
|
it "creates the /N appearance stream according to the set string" do
|
|
600
|
-
@
|
|
601
|
+
@doc.config['font.on_invalid_glyph'] = lambda do |codepoint, _|
|
|
602
|
+
[@doc.fonts.add('ZapfDingbats').decode_codepoint(codepoint)]
|
|
603
|
+
end
|
|
601
604
|
@field.set_default_appearance_string(font_color: "red")
|
|
605
|
+
@field[:V] = 'Te ✂ xt'
|
|
602
606
|
@generator.create_appearances
|
|
603
607
|
assert_operators(@widget[:AP][:N].stream,
|
|
604
608
|
[[:begin_marked_content, [:Tx]],
|
|
@@ -606,11 +610,17 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
|
606
610
|
[:append_rectangle, [1, 1, 98, 9.25]],
|
|
607
611
|
[:clip_path_non_zero],
|
|
608
612
|
[:end_path],
|
|
609
|
-
[:set_font_and_size, [:F1,
|
|
613
|
+
[:set_font_and_size, [:F1, 10]],
|
|
610
614
|
[:set_device_rgb_non_stroking_color, [1.0, 0.0, 0.0]],
|
|
611
615
|
[:begin_text],
|
|
612
|
-
[:set_text_matrix, [1, 0, 0, 1, 2,
|
|
613
|
-
[:show_text, ["
|
|
616
|
+
[:set_text_matrix, [1, 0, 0, 1, 2, 2.035]],
|
|
617
|
+
[:show_text, ["Te "]],
|
|
618
|
+
[:set_font_and_size, [:F2, 10]],
|
|
619
|
+
[:move_text, [14.45, 0]],
|
|
620
|
+
[:show_text, ["\""]],
|
|
621
|
+
[:set_font_and_size, [:F1, 10]],
|
|
622
|
+
[:move_text, [9.61, 0]],
|
|
623
|
+
[:show_text, [" xt"]],
|
|
614
624
|
[:end_text],
|
|
615
625
|
[:restore_graphics_state],
|
|
616
626
|
[:end_marked_content]])
|
|
@@ -656,7 +666,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
|
656
666
|
end
|
|
657
667
|
|
|
658
668
|
it "creates the /N appearance stream according to the set string" do
|
|
659
|
-
@field
|
|
669
|
+
@field[:V] = "Test\nValue"
|
|
660
670
|
@field.set_default_appearance_string(font_size: 10, font_color: "red")
|
|
661
671
|
@generator.create_appearances
|
|
662
672
|
assert_operators(@widget[:AP][:N].stream,
|
|
@@ -679,7 +689,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
|
679
689
|
[:restore_graphics_state],
|
|
680
690
|
[:end_marked_content]])
|
|
681
691
|
|
|
682
|
-
@field
|
|
692
|
+
@field[:V] = "Test\nTest\nTest"
|
|
683
693
|
@field.set_default_appearance_string(font_size: 0)
|
|
684
694
|
@generator.create_appearances
|
|
685
695
|
assert_operators(@widget[:AP][:N].stream,
|
|
@@ -744,7 +754,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
|
744
754
|
end
|
|
745
755
|
|
|
746
756
|
it "handles centering like Adobe, e.g. shift left, when text cannot be completely centered" do
|
|
747
|
-
@field
|
|
757
|
+
@field[:V] = 'Hello'
|
|
748
758
|
@field.text_alignment(:center)
|
|
749
759
|
@generator.create_appearances
|
|
750
760
|
assert_operators(@widget[:AP][:N].stream,
|
|
@@ -754,7 +764,7 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
|
754
764
|
end
|
|
755
765
|
|
|
756
766
|
it "creates the /N appearance stream according to the set string" do
|
|
757
|
-
@field
|
|
767
|
+
@field[:V] = 'Text'
|
|
758
768
|
@field.set_default_appearance_string(font_size: 10, font_color: "red")
|
|
759
769
|
@generator.create_appearances
|
|
760
770
|
assert_operators(@widget[:AP][:N].stream,
|
|
@@ -773,11 +783,29 @@ describe HexaPDF::Type::AcroForm::AppearanceGenerator do
|
|
|
773
783
|
[:end_marked_content]])
|
|
774
784
|
end
|
|
775
785
|
|
|
786
|
+
it "works for empty strings" do
|
|
787
|
+
@field[:V] = ''
|
|
788
|
+
@generator.create_appearances
|
|
789
|
+
assert_operators(@widget[:AP][:N].stream,
|
|
790
|
+
[[:begin_text],
|
|
791
|
+
[:set_text_matrix, [1, 0, 0, 1, 2, 6.41]],
|
|
792
|
+
[:end_text]], range: 6..8)
|
|
793
|
+
end
|
|
794
|
+
|
|
776
795
|
it "fails if the /MaxLen key is not set" do
|
|
777
796
|
@field.delete(:MaxLen)
|
|
778
797
|
@field[:V] = 't'
|
|
779
798
|
assert_raises(HexaPDF::Error) { @generator.create_appearances }
|
|
780
799
|
end
|
|
800
|
+
|
|
801
|
+
it "fails if fallback glyphs are needed for rendering" do
|
|
802
|
+
@doc.config['font.on_invalid_glyph'] = lambda do |codepoint, _|
|
|
803
|
+
[@doc.fonts.add('ZapfDingbats').decode_codepoint(codepoint)]
|
|
804
|
+
end
|
|
805
|
+
@field[:V] = 'Test ✂'
|
|
806
|
+
ex = assert_raises(HexaPDF::Error) { @generator.create_appearances }
|
|
807
|
+
assert_match(/Fallback glyphs/, ex.message)
|
|
808
|
+
end
|
|
781
809
|
end
|
|
782
810
|
|
|
783
811
|
describe "choice fields" do
|
|
@@ -209,7 +209,7 @@ describe HexaPDF::Utils::SortedTreeNode do
|
|
|
209
209
|
@root[:Kids][0] = ref
|
|
210
210
|
@kid1.oid = 0
|
|
211
211
|
assert(@root.validate do |message, c|
|
|
212
|
-
assert_match(/must be indirect
|
|
212
|
+
assert_match(/must be an indirect object/, message)
|
|
213
213
|
assert(c)
|
|
214
214
|
end)
|
|
215
215
|
assert(@kid1.indirect?)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hexapdf
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.35.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Thomas Leitner
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-01-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cmdparse
|
|
@@ -301,6 +301,8 @@ files:
|
|
|
301
301
|
- examples/025-table_box.rb
|
|
302
302
|
- examples/026-optional_content.rb
|
|
303
303
|
- examples/027-composer_optional_content.rb
|
|
304
|
+
- examples/028-frame_mask_mode.rb
|
|
305
|
+
- examples/029-composer_fallback_fonts.rb
|
|
304
306
|
- examples/emoji-smile.png
|
|
305
307
|
- examples/emoji-wink.png
|
|
306
308
|
- examples/machupicchu.jpg
|
|
@@ -324,6 +326,7 @@ files:
|
|
|
324
326
|
- lib/hexapdf/configuration.rb
|
|
325
327
|
- lib/hexapdf/content.rb
|
|
326
328
|
- lib/hexapdf/content/canvas.rb
|
|
329
|
+
- lib/hexapdf/content/canvas_composer.rb
|
|
327
330
|
- lib/hexapdf/content/color_space.rb
|
|
328
331
|
- lib/hexapdf/content/graphic_object.rb
|
|
329
332
|
- lib/hexapdf/content/graphic_object/arc.rb
|
|
@@ -603,6 +606,7 @@ files:
|
|
|
603
606
|
- test/hexapdf/content/graphic_object/test_geom2d.rb
|
|
604
607
|
- test/hexapdf/content/graphic_object/test_solid_arc.rb
|
|
605
608
|
- test/hexapdf/content/test_canvas.rb
|
|
609
|
+
- test/hexapdf/content/test_canvas_composer.rb
|
|
606
610
|
- test/hexapdf/content/test_color_space.rb
|
|
607
611
|
- test/hexapdf/content/test_graphics_state.rb
|
|
608
612
|
- test/hexapdf/content/test_operator.rb
|
|
@@ -795,7 +799,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
795
799
|
- !ruby/object:Gem::Version
|
|
796
800
|
version: '0'
|
|
797
801
|
requirements: []
|
|
798
|
-
rubygems_version: 3.
|
|
802
|
+
rubygems_version: 3.5.3
|
|
799
803
|
signing_key:
|
|
800
804
|
specification_version: 4
|
|
801
805
|
summary: HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|