hexapdf 0.10.0 → 0.11.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 +33 -0
- data/CONTRIBUTERS +1 -1
- data/Rakefile +35 -50
- data/VERSION +1 -1
- data/lib/hexapdf/cli.rb +4 -0
- data/lib/hexapdf/cli/command.rb +6 -2
- data/lib/hexapdf/cli/image2pdf.rb +141 -0
- data/lib/hexapdf/cli/info.rb +1 -1
- data/lib/hexapdf/cli/inspect.rb +32 -2
- data/lib/hexapdf/cli/modify.rb +1 -1
- data/lib/hexapdf/cli/optimize.rb +1 -1
- data/lib/hexapdf/cli/watermark.rb +130 -0
- data/lib/hexapdf/composer.rb +2 -2
- data/lib/hexapdf/configuration.rb +7 -1
- data/lib/hexapdf/content/canvas.rb +2 -2
- data/lib/hexapdf/content/graphic_object/arc.rb +2 -2
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +2 -2
- data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
- data/lib/hexapdf/dictionary.rb +11 -3
- data/lib/hexapdf/dictionary_fields.rb +32 -3
- data/lib/hexapdf/document.rb +7 -3
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/fonts.rb +21 -1
- data/lib/hexapdf/document/pages.rb +2 -2
- data/lib/hexapdf/encryption/standard_security_handler.rb +2 -2
- data/lib/hexapdf/font/cmap/parser.rb +1 -1
- data/lib/hexapdf/font/true_type/table/head.rb +2 -2
- data/lib/hexapdf/font/true_type/table/os2.rb +4 -4
- data/lib/hexapdf/font/true_type_wrapper.rb +16 -16
- data/lib/hexapdf/font/type1_wrapper.rb +16 -16
- data/lib/hexapdf/font_loader.rb +2 -0
- data/lib/hexapdf/font_loader/from_configuration.rb +5 -0
- data/lib/hexapdf/font_loader/standard14.rb +5 -0
- data/lib/hexapdf/image_loader/png.rb +1 -1
- data/lib/hexapdf/layout/box.rb +2 -2
- data/lib/hexapdf/layout/image_box.rb +1 -1
- data/lib/hexapdf/layout/style.rb +50 -24
- data/lib/hexapdf/layout/text_box.rb +1 -1
- data/lib/hexapdf/layout/text_fragment.rb +2 -2
- data/lib/hexapdf/layout/text_layouter.rb +14 -10
- data/lib/hexapdf/name_tree_node.rb +3 -3
- data/lib/hexapdf/number_tree_node.rb +3 -3
- data/lib/hexapdf/pdf_array.rb +207 -0
- data/lib/hexapdf/rectangle.rb +12 -12
- data/lib/hexapdf/serializer.rb +1 -1
- data/lib/hexapdf/stream.rb +6 -4
- data/lib/hexapdf/task/optimize.rb +3 -3
- data/lib/hexapdf/type.rb +2 -0
- data/lib/hexapdf/type/acro_form.rb +51 -0
- data/lib/hexapdf/type/acro_form/field.rb +129 -0
- data/lib/hexapdf/type/acro_form/form.rb +124 -0
- 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/annotation.rb +2 -2
- data/lib/hexapdf/type/annotations.rb +1 -0
- data/lib/hexapdf/type/annotations/link.rb +4 -15
- data/lib/hexapdf/type/annotations/markup_annotation.rb +2 -1
- data/lib/hexapdf/type/annotations/text.rb +3 -6
- data/lib/hexapdf/type/annotations/widget.rb +90 -0
- data/lib/hexapdf/type/catalog.rb +12 -9
- data/lib/hexapdf/type/cid_font.rb +3 -3
- data/lib/hexapdf/type/file_specification.rb +2 -2
- data/lib/hexapdf/type/font_descriptor.rb +5 -2
- data/lib/hexapdf/type/font_simple.rb +1 -1
- data/lib/hexapdf/type/font_type0.rb +1 -1
- data/lib/hexapdf/type/font_type3.rb +1 -1
- data/lib/hexapdf/type/form.rb +2 -2
- data/lib/hexapdf/type/graphics_state_parameter.rb +11 -6
- data/lib/hexapdf/type/icon_fit.rb +58 -0
- data/lib/hexapdf/type/image.rb +14 -8
- data/lib/hexapdf/type/info.rb +2 -1
- data/lib/hexapdf/type/page.rb +4 -4
- data/lib/hexapdf/type/page_tree_node.rb +3 -7
- data/lib/hexapdf/type/resources.rb +1 -1
- data/lib/hexapdf/type/trailer.rb +4 -4
- data/lib/hexapdf/type/viewer_preferences.rb +7 -4
- data/lib/hexapdf/type/xref_stream.rb +2 -2
- data/lib/hexapdf/utils/sorted_tree_node.rb +1 -1
- data/lib/hexapdf/version.rb +1 -1
- data/man/man1/hexapdf.1 +77 -8
- data/test/hexapdf/content/test_canvas.rb +2 -2
- data/test/hexapdf/content/test_processor.rb +3 -3
- data/test/hexapdf/document/test_files.rb +4 -4
- data/test/hexapdf/document/test_fonts.rb +13 -1
- data/test/hexapdf/document/test_images.rb +6 -6
- data/test/hexapdf/document/test_pages.rb +8 -8
- data/test/hexapdf/encryption/test_security_handler.rb +7 -7
- data/test/hexapdf/encryption/test_standard_security_handler.rb +5 -5
- data/test/hexapdf/font/test_true_type_wrapper.rb +2 -2
- data/test/hexapdf/font_loader/test_from_configuration.rb +4 -0
- data/test/hexapdf/font_loader/test_standard14.rb +10 -0
- data/test/hexapdf/image_loader/test_jpeg.rb +1 -1
- data/test/hexapdf/image_loader/test_png.rb +3 -3
- data/test/hexapdf/layout/test_box.rb +2 -2
- data/test/hexapdf/layout/test_frame.rb +1 -1
- data/test/hexapdf/layout/test_image_box.rb +1 -1
- data/test/hexapdf/layout/test_style.rb +18 -13
- data/test/hexapdf/layout/test_text_box.rb +1 -1
- data/test/hexapdf/layout/test_text_layouter.rb +11 -6
- data/test/hexapdf/task/test_dereference.rb +2 -2
- data/test/hexapdf/task/test_optimize.rb +11 -11
- data/test/hexapdf/test_composer.rb +1 -1
- data/test/hexapdf/test_dictionary.rb +10 -2
- data/test/hexapdf/test_dictionary_fields.rb +27 -3
- data/test/hexapdf/test_document.rb +16 -15
- data/test/hexapdf/test_importer.rb +4 -4
- data/test/hexapdf/test_object.rb +1 -1
- data/test/hexapdf/test_pdf_array.rb +162 -0
- data/test/hexapdf/test_rectangle.rb +3 -5
- data/test/hexapdf/test_serializer.rb +1 -1
- data/test/hexapdf/test_stream.rb +1 -0
- data/test/hexapdf/test_writer.rb +3 -3
- data/test/hexapdf/type/acro_form/test_field.rb +85 -0
- data/test/hexapdf/type/acro_form/test_form.rb +69 -0
- data/test/hexapdf/type/annotations/test_text.rb +2 -6
- data/test/hexapdf/type/annotations/test_widget.rb +24 -0
- data/test/hexapdf/type/test_annotation.rb +1 -1
- data/test/hexapdf/type/test_catalog.rb +1 -1
- data/test/hexapdf/type/test_cid_font.rb +3 -3
- data/test/hexapdf/type/test_font.rb +2 -2
- data/test/hexapdf/type/test_font_descriptor.rb +2 -1
- data/test/hexapdf/type/test_font_simple.rb +3 -3
- data/test/hexapdf/type/test_font_true_type.rb +6 -6
- data/test/hexapdf/type/test_font_type0.rb +5 -5
- data/test/hexapdf/type/test_font_type1.rb +8 -8
- data/test/hexapdf/type/test_font_type3.rb +4 -4
- data/test/hexapdf/type/test_image.rb +16 -12
- data/test/hexapdf/type/test_page.rb +11 -11
- data/test/hexapdf/type/test_page_tree_node.rb +20 -20
- data/test/hexapdf/type/test_resources.rb +6 -6
- data/test/hexapdf/type/test_trailer.rb +5 -2
- data/test/hexapdf/type/test_xref_stream.rb +1 -0
- data/test/hexapdf/utils/test_sorted_tree_node.rb +35 -35
- metadata +23 -7
- data/test/hexapdf/type/annotations/test_link.rb +0 -19
@@ -6,8 +6,9 @@ require 'hexapdf/document'
|
|
6
6
|
|
7
7
|
describe HexaPDF::Rectangle do
|
8
8
|
describe "after_data_change" do
|
9
|
-
it "fails if the
|
10
|
-
assert_raises(ArgumentError) { HexaPDF::Rectangle.new(
|
9
|
+
it "fails if the rectangle doesn't contain four numbers" do
|
10
|
+
assert_raises(ArgumentError) { HexaPDF::Rectangle.new([1, 2, 3]) }
|
11
|
+
assert_raises(ArgumentError) { HexaPDF::Rectangle.new([1, 2, 3, :a]) }
|
11
12
|
end
|
12
13
|
|
13
14
|
it "normalizes the array values" do
|
@@ -53,9 +54,6 @@ describe HexaPDF::Rectangle do
|
|
53
54
|
|
54
55
|
rect.value.unshift(:A)
|
55
56
|
refute(rect.validate)
|
56
|
-
|
57
|
-
rect.data.value = :A
|
58
|
-
refute(rect.validate)
|
59
57
|
end
|
60
58
|
end
|
61
59
|
end
|
@@ -137,7 +137,7 @@ describe HexaPDF::Serializer do
|
|
137
137
|
it "serializes streams" do
|
138
138
|
@stream.stream = "somedata"
|
139
139
|
assert_serialized("<</Key(value)/Length 8>>stream\nsomedata\nendstream", @stream)
|
140
|
-
assert_serialized("<</Name 2 0 R>>", HexaPDF::Object.new(Name: @stream))
|
140
|
+
assert_serialized("<</Name 2 0 R>>", HexaPDF::Object.new({Name: @stream}))
|
141
141
|
end
|
142
142
|
|
143
143
|
it "handles self-referencing streams" do
|
data/test/hexapdf/test_stream.rb
CHANGED
@@ -81,6 +81,7 @@ describe HexaPDF::Stream do
|
|
81
81
|
@document.config = HexaPDF::Configuration.with_defaults
|
82
82
|
@document.instance_variable_set(:@version, '1.2')
|
83
83
|
def (@document).unwrap(obj); obj; end
|
84
|
+
def (@document).wrap(obj, *); obj; end
|
84
85
|
def (@document).deref(obj); obj; end
|
85
86
|
|
86
87
|
@stm = HexaPDF::Stream.new({}, oid: 1, document: @document)
|
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.11.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.11.0)>>
|
76
76
|
endobj
|
77
77
|
2 0 obj
|
78
78
|
<</Length 10>>stream
|
@@ -116,7 +116,7 @@ describe HexaPDF::Writer do
|
|
116
116
|
|
117
117
|
it "raises an error if no xref stream is in a revision but object streams are" do
|
118
118
|
document = HexaPDF::Document.new
|
119
|
-
document.add(Type: :ObjStm)
|
119
|
+
document.add({Type: :ObjStm})
|
120
120
|
assert_raises(HexaPDF::Error) { HexaPDF::Writer.new(document, StringIO.new).write }
|
121
121
|
end
|
122
122
|
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/document'
|
5
|
+
require 'hexapdf/type/acro_form/field'
|
6
|
+
|
7
|
+
describe HexaPDF::Type::AcroForm::Field do
|
8
|
+
before do
|
9
|
+
@doc = HexaPDF::Document.new
|
10
|
+
@field = @doc.add({}, type: :XXAcroFormField)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "must always be an indirect object" do
|
14
|
+
assert(@field.must_be_indirect?)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "resolves inherited field values" do
|
18
|
+
assert_nil(@field[:FT])
|
19
|
+
|
20
|
+
@field[:Parent] = {FT: :Tx}
|
21
|
+
assert_equal(:Tx, @field[:FT])
|
22
|
+
|
23
|
+
@field[:FT] = :Ch
|
24
|
+
assert_equal(:Ch, @field[:FT])
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns the field type" do
|
28
|
+
assert_nil(@field.field_type)
|
29
|
+
|
30
|
+
@field[:FT] = :Tx
|
31
|
+
assert_equal(:Tx, @field.field_type)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns the full name of the field" do
|
35
|
+
assert_nil(@field.full_name)
|
36
|
+
|
37
|
+
@field[:T] = "Test"
|
38
|
+
assert_equal("Test", @field.full_name)
|
39
|
+
|
40
|
+
@field[:Parent] = {}
|
41
|
+
assert_equal("Test", @field.full_name)
|
42
|
+
|
43
|
+
@field[:Parent] = {T: 'Parent'}
|
44
|
+
assert_equal("Parent.Test", @field.full_name)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns whether the field is a terminal field" do
|
48
|
+
assert(@field.terminal_field?)
|
49
|
+
|
50
|
+
@field[:Kids] = []
|
51
|
+
assert(@field.terminal_field?)
|
52
|
+
|
53
|
+
@field[:Kids] = [{Subtype: :Widget}]
|
54
|
+
assert(@field.terminal_field?)
|
55
|
+
|
56
|
+
@field[:Kids] = [{FT: :Tx}]
|
57
|
+
refute(@field.terminal_field?)
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "perform_validation" do
|
61
|
+
before do
|
62
|
+
@field[:FT] = :Tx
|
63
|
+
end
|
64
|
+
|
65
|
+
it "requires the /FT key to be present for terminal fields" do
|
66
|
+
assert(@field.validate)
|
67
|
+
|
68
|
+
@field.delete(:FT)
|
69
|
+
refute(@field.validate)
|
70
|
+
|
71
|
+
@field[:Kids] = [{}]
|
72
|
+
assert(@field.validate)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "doesn't allow periods in partial field names" do
|
76
|
+
assert(@field.validate)
|
77
|
+
|
78
|
+
@field[:T] = "Test"
|
79
|
+
assert(@field.validate)
|
80
|
+
|
81
|
+
@field[:T] = "Te.st"
|
82
|
+
refute(@field.validate)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/document'
|
5
|
+
require 'hexapdf/type/acro_form/form'
|
6
|
+
|
7
|
+
describe HexaPDF::Type::AcroForm::Form do
|
8
|
+
before do
|
9
|
+
@doc = HexaPDF::Document.new
|
10
|
+
@acroform = @doc.add({}, type: :XXAcroForm)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "signature flags" do
|
14
|
+
before do
|
15
|
+
@acroform[:SigFlags] = 3
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns all signature flags" do
|
19
|
+
assert_equal([:signatures_exist, :append_only], @acroform.signature_flags)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns true if the given flag is set" do
|
23
|
+
assert(@acroform.signature_flag?(:signatures_exist))
|
24
|
+
end
|
25
|
+
|
26
|
+
it "raises an error if an unknown flag name is provided" do
|
27
|
+
assert_raises(ArgumentError) { @acroform.signature_flag?(:non_exist) }
|
28
|
+
end
|
29
|
+
|
30
|
+
it "sets the given flag bits" do
|
31
|
+
@acroform[:SigFlags] = 0
|
32
|
+
@acroform.signature_flag(:append_only)
|
33
|
+
assert_equal([:append_only], @acroform.signature_flags)
|
34
|
+
@acroform.signature_flag(:signatures_exist, clear_existing: true)
|
35
|
+
assert_equal([:signatures_exist], @acroform.signature_flags)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "finds the root fields" do
|
40
|
+
@doc.pages.add[:Annots] = [{FT: :Tx1}, {FT: :Tx2, Parent: {FT: :Tx3}}]
|
41
|
+
@doc.pages.add[:Annots] = [{Subtype: :Widget}]
|
42
|
+
|
43
|
+
result = [{FT: :Tx1}, {FT: :Tx3}]
|
44
|
+
assert_equal(result, @acroform.find_root_fields.map(&:value))
|
45
|
+
refute(@acroform.key?(:Fields))
|
46
|
+
|
47
|
+
@acroform.find_root_fields!
|
48
|
+
assert_equal(result, @acroform[:Fields].value.map(&:value))
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "each_field" do
|
52
|
+
before do
|
53
|
+
@acroform[:Fields] = [
|
54
|
+
{FT: :Tx1},
|
55
|
+
{FT: :Tx2, Kids: [{Subtype: :Widget}]},
|
56
|
+
{FT: :Tx3, Kids: [{FT: :Tx4}, {FT: :Tx5, Kids: [{FT: :Tx6}]}]},
|
57
|
+
]
|
58
|
+
end
|
59
|
+
|
60
|
+
it "iterates over all terminal fields" do
|
61
|
+
assert_equal([:Tx1, :Tx2, :Tx4, :Tx6], @acroform.each_field.map {|h| h[:FT] })
|
62
|
+
end
|
63
|
+
|
64
|
+
it "iterates over all fields" do
|
65
|
+
assert_equal([:Tx1, :Tx2, :Tx3, :Tx4, :Tx5, :Tx6],
|
66
|
+
@acroform.each_field(terminal_only: false).map {|h| h[:FT] })
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -14,17 +14,13 @@ describe HexaPDF::Type::Annotations::Text do
|
|
14
14
|
describe "validation" do
|
15
15
|
it "checks for correct /StateModel values" do
|
16
16
|
@annot[:StateModel] = 'Invalid'
|
17
|
-
refute(@annot.validate {|msg| assert_match(/
|
17
|
+
refute(@annot.validate {|msg| assert_match(/does not contain an allowed value/, msg) })
|
18
18
|
end
|
19
19
|
|
20
|
-
it "automatically sets /StateModel based on the /State entry
|
20
|
+
it "automatically sets /StateModel based on the /State entry" do
|
21
21
|
@annot[:State] = 'Marked'
|
22
22
|
assert(@annot.validate)
|
23
23
|
assert_equal('Marked', @annot[:StateModel])
|
24
|
-
|
25
|
-
@annot.delete(:StateModel)
|
26
|
-
@annot[:State] = 'Unknown'
|
27
|
-
refute(@annot.validate {|msg| assert_match(/StateModel required/, msg) })
|
28
24
|
end
|
29
25
|
|
30
26
|
it "checks whether /State and /StateModel match" do
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/document'
|
5
|
+
require 'hexapdf/type/annotations/widget'
|
6
|
+
|
7
|
+
describe HexaPDF::Type::Annotations::Widget::AppearanceCharacteristics do
|
8
|
+
before do
|
9
|
+
@doc = HexaPDF::Document.new
|
10
|
+
@annot = @doc.wrap({}, type: :XXAppearanceCharacteristics)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "validation" do
|
14
|
+
it "needs /R to be a multiple of 90" do
|
15
|
+
assert(@annot.validate)
|
16
|
+
|
17
|
+
@annot[:R] = 45
|
18
|
+
refute(@annot.validate)
|
19
|
+
|
20
|
+
@annot[:R] = 90
|
21
|
+
assert(@annot.validate)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -7,8 +7,8 @@ require 'hexapdf/type/cid_font'
|
|
7
7
|
describe HexaPDF::Type::CIDFont do
|
8
8
|
before do
|
9
9
|
@doc = HexaPDF::Document.new
|
10
|
-
@font = @doc.wrap(Type: :Font, Subtype: :CIDFontType2, W: [1, 2, 3], DW: 100,
|
11
|
-
|
10
|
+
@font = @doc.wrap({Type: :Font, Subtype: :CIDFontType2, W: [1, 2, 3], DW: 100,
|
11
|
+
CIDSystemInfo: {Registry: 'Adobe', Ordering: 'Japan1', Supplement: 1}})
|
12
12
|
end
|
13
13
|
|
14
14
|
describe "width" do
|
@@ -39,7 +39,7 @@ describe HexaPDF::Type::CIDFont do
|
|
39
39
|
it "allows setting the widths" do
|
40
40
|
@font.set_widths([[1, 1], [2, 2], [4, 4], [5, 5], [7, 7.1]], default_width: 5.1)
|
41
41
|
assert_equal(5, @font[:DW])
|
42
|
-
assert_equal([1, [1, 2], 4, [4, 5], 7, [7]], @font[:W])
|
42
|
+
assert_equal([1, [1, 2], 4, [4, 5], 7, [7]], @font[:W].value)
|
43
43
|
end
|
44
44
|
|
45
45
|
it "handles an empty widths array correctly" do
|
@@ -13,8 +13,8 @@ describe HexaPDF::Type::Font do
|
|
13
13
|
<22> <0042>
|
14
14
|
endbfchar
|
15
15
|
EOF
|
16
|
-
fd = @doc.add(Type: :FontDescriptor, FontBBox: [0, 1, 2, 3])
|
17
|
-
@font = @doc.add(Type: :Font, BaseFont: :TestFont, FontDescriptor: fd, ToUnicode: cmap)
|
16
|
+
fd = @doc.add({Type: :FontDescriptor, FontBBox: [0, 1, 2, 3]})
|
17
|
+
@font = @doc.add({Type: :Font, BaseFont: :TestFont, FontDescriptor: fd, ToUnicode: cmap})
|
18
18
|
end
|
19
19
|
|
20
20
|
it "must always be an indirect" do
|
@@ -7,7 +7,8 @@ require 'hexapdf/type/font_descriptor'
|
|
7
7
|
describe HexaPDF::Type::FontDescriptor do
|
8
8
|
before do
|
9
9
|
@doc = HexaPDF::Document.new
|
10
|
-
@font_desc = @doc.add(Type: :FontDescriptor, FontName: :Test, Flags: 0b1001001,
|
10
|
+
@font_desc = @doc.add({Type: :FontDescriptor, FontName: :Test, Flags: 0b1001001,
|
11
|
+
ItalicAngle: 10})
|
11
12
|
end
|
12
13
|
|
13
14
|
describe "flags" do
|
@@ -13,9 +13,9 @@ describe HexaPDF::Type::FontSimple do
|
|
13
13
|
<22> <0042>
|
14
14
|
endbfchar
|
15
15
|
EOF
|
16
|
-
font_descriptor = @doc.add(Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
|
17
|
-
|
18
|
-
|
16
|
+
font_descriptor = @doc.add({Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
|
17
|
+
FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
|
18
|
+
Descent: -100, CapHeight: 800, StemV: 20})
|
19
19
|
@font = @doc.add({Type: :Font, Encoding: :WinAnsiEncoding,
|
20
20
|
BaseFont: :Embedded, FontDescriptor: font_descriptor, ToUnicode: cmap,
|
21
21
|
FirstChar: 32, LastChar: 34, Widths: [600, 0, 700]},
|
@@ -7,12 +7,12 @@ require 'hexapdf/type/font_true_type'
|
|
7
7
|
describe HexaPDF::Type::FontTrueType do
|
8
8
|
before do
|
9
9
|
@doc = HexaPDF::Document.new
|
10
|
-
font_descriptor = @doc.add(Type: :FontDescriptor, FontName: :Something, Flags: 0b100,
|
11
|
-
|
12
|
-
|
13
|
-
@font = @doc.add(Type: :Font, Subtype: :TrueType, Encoding: :WinAnsiEncoding,
|
14
|
-
|
15
|
-
|
10
|
+
font_descriptor = @doc.add({Type: :FontDescriptor, FontName: :Something, Flags: 0b100,
|
11
|
+
FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
|
12
|
+
Descent: -100, CapHeight: 800, StemV: 20})
|
13
|
+
@font = @doc.add({Type: :Font, Subtype: :TrueType, Encoding: :WinAnsiEncoding,
|
14
|
+
FirstChar: 32, LastChar: 34, Widths: [600, 0, 700],
|
15
|
+
BaseFont: :Something, FontDescriptor: font_descriptor})
|
16
16
|
end
|
17
17
|
|
18
18
|
describe "validation" do
|
@@ -7,15 +7,15 @@ require 'hexapdf/type/font_type0'
|
|
7
7
|
describe HexaPDF::Type::FontType0 do
|
8
8
|
before do
|
9
9
|
@doc = HexaPDF::Document.new
|
10
|
-
fd = @doc.add(Type: :FontDescriptor, FontBBox: [0, 1, 2, 3])
|
11
|
-
@cid_font = @doc.wrap(Type: :Font, Subtype: :CIDFontType2, W: [633, [100]], FontDescriptor: fd,
|
12
|
-
|
13
|
-
@font = @doc.wrap(Type: :Font, Subtype: :Type0, Encoding: :H, DescendantFonts: [@cid_font])
|
10
|
+
fd = @doc.add({Type: :FontDescriptor, FontBBox: [0, 1, 2, 3]})
|
11
|
+
@cid_font = @doc.wrap({Type: :Font, Subtype: :CIDFontType2, W: [633, [100]], FontDescriptor: fd,
|
12
|
+
CIDSystemInfo: {Registry: 'Adobe', Ordering: 'Japan1', Supplement: 1}})
|
13
|
+
@font = @doc.wrap({Type: :Font, Subtype: :Type0, Encoding: :H, DescendantFonts: [@cid_font]})
|
14
14
|
end
|
15
15
|
|
16
16
|
it "returns the correct writing mode" do
|
17
17
|
assert_equal(:horizontal, @font.writing_mode)
|
18
|
-
font = @doc.wrap(Type: :Font, Subtype: :Type0, Encoding: :V)
|
18
|
+
font = @doc.wrap({Type: :Font, Subtype: :Type0, Encoding: :V})
|
19
19
|
assert_equal(:vertical, font.writing_mode)
|
20
20
|
end
|
21
21
|
|
@@ -39,8 +39,8 @@ end
|
|
39
39
|
describe HexaPDF::Type::FontType1 do
|
40
40
|
before do
|
41
41
|
@doc = HexaPDF::Document.new
|
42
|
-
@font = @doc.add(Type: :Font, Subtype: :Type1, Encoding: :WinAnsiEncoding,
|
43
|
-
|
42
|
+
@font = @doc.add({Type: :Font, Subtype: :Type1, Encoding: :WinAnsiEncoding,
|
43
|
+
BaseFont: :"Times-Roman"})
|
44
44
|
|
45
45
|
font_file = @doc.add({}, stream: <<-EOF)
|
46
46
|
/Encoding 256 array
|
@@ -49,12 +49,12 @@ describe HexaPDF::Type::FontType1 do
|
|
49
49
|
dup 34 /B put
|
50
50
|
readonly def
|
51
51
|
EOF
|
52
|
-
font_descriptor = @doc.add(Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
|
53
|
-
|
54
|
-
|
55
|
-
@embedded_font = @doc.add(Type: :Font, Subtype: :Type1, Encoding: :WinAnsiEncoding,
|
56
|
-
|
57
|
-
|
52
|
+
font_descriptor = @doc.add({Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
|
53
|
+
FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
|
54
|
+
Descent: -100, CapHeight: 800, StemV: 20, FontFile: font_file})
|
55
|
+
@embedded_font = @doc.add({Type: :Font, Subtype: :Type1, Encoding: :WinAnsiEncoding,
|
56
|
+
BaseFont: :Embedded, FontDescriptor: font_descriptor,
|
57
|
+
FirstChar: 32, LastChar: 34, Widths: [600, 0, 700]})
|
58
58
|
end
|
59
59
|
|
60
60
|
describe "encoding" do
|
@@ -7,10 +7,10 @@ require 'hexapdf/type/font_type3'
|
|
7
7
|
describe HexaPDF::Type::FontType3 do
|
8
8
|
before do
|
9
9
|
@doc = HexaPDF::Document.new
|
10
|
-
@font = @doc.add(Type: :Font, Subtype: :Type3, Encoding: :WinAnsiEncoding,
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
@font = @doc.add({Type: :Font, Subtype: :Type3, Encoding: :WinAnsiEncoding,
|
11
|
+
FirstChar: 32, LastChar: 34, Widths: [600, 0, 700],
|
12
|
+
FontBBox: [0, 0, 100, 100], FontMatrix: [1, 0, 0, 1, 0, 0],
|
13
|
+
CharProcs: {}})
|
14
14
|
end
|
15
15
|
|
16
16
|
describe "validation" do
|
@@ -12,19 +12,19 @@ describe HexaPDF::Type::Image do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it "returns the width of the image" do
|
15
|
-
@image = @doc.wrap(Type: :XObject, Subtype: :Image, Width: 10)
|
15
|
+
@image = @doc.wrap({Type: :XObject, Subtype: :Image, Width: 10})
|
16
16
|
assert_equal(10, @image.width)
|
17
17
|
end
|
18
18
|
|
19
19
|
it "returns the height of the image" do
|
20
|
-
@image = @doc.wrap(Type: :XObject, Subtype: :Image, Height: 10)
|
20
|
+
@image = @doc.wrap({Type: :XObject, Subtype: :Image, Height: 10})
|
21
21
|
assert_equal(10, @image.height)
|
22
22
|
end
|
23
23
|
|
24
24
|
describe "info" do
|
25
25
|
before do
|
26
|
-
@image = @doc.wrap(Type: :XObject, Subtype: :Image, Width: 10, Height: 5,
|
27
|
-
|
26
|
+
@image = @doc.wrap({Type: :XObject, Subtype: :Image, Width: 10, Height: 5,
|
27
|
+
ColorSpace: :DeviceRGB, BitsPerComponent: 4})
|
28
28
|
end
|
29
29
|
|
30
30
|
it "uses the Width, Height and BitsPerComponent values" do
|
@@ -184,6 +184,10 @@ describe HexaPDF::Type::Image do
|
|
184
184
|
Dir.glob(File.join(TEST_DATA_DIR, 'images', '*.png')).each do |png_file|
|
185
185
|
it "writes #{File.basename(png_file)} correctly as PNG file" do
|
186
186
|
image = @doc.images.add(png_file)
|
187
|
+
if png_file =~ /greyscale-1bit.png/ # force use of arrays for one image
|
188
|
+
image[:DecodeParms] = [image[:DecodeParms]]
|
189
|
+
image[:Filter] = [image[:Filter]]
|
190
|
+
end
|
187
191
|
image.write(@file.path)
|
188
192
|
assert_valid_png(@file.path, png_file)
|
189
193
|
|
@@ -197,7 +201,7 @@ describe HexaPDF::Type::Image do
|
|
197
201
|
assert_equal(image[:Height], new_image[:Height], "file: #{png_file}")
|
198
202
|
assert_equal(image[:BitsPerComponent], new_image[:BitsPerComponent], "file: #{png_file}")
|
199
203
|
if image[:Mask]
|
200
|
-
assert_equal(image[:Mask], new_image[:Mask], "file: #{png_file}")
|
204
|
+
assert_equal(image[:Mask].value, new_image[:Mask].value, "file: #{png_file}")
|
201
205
|
else
|
202
206
|
assert_nil(new_image[:Mask], "file: #{png_file}")
|
203
207
|
end
|
@@ -217,15 +221,15 @@ describe HexaPDF::Type::Image do
|
|
217
221
|
end
|
218
222
|
|
219
223
|
it "works for greyscale indexed images" do
|
220
|
-
image = @doc.add(Type: :XObject, Subtype: :Image, Width: 2, Height: 2, BitsPerComponent: 2,
|
221
|
-
|
224
|
+
image = @doc.add({Type: :XObject, Subtype: :Image, Width: 2, Height: 2, BitsPerComponent: 2,
|
225
|
+
ColorSpace: [:Indexed, :DeviceGray, 3, "\x00\x40\x80\xFF".b]})
|
222
226
|
image.stream = HexaPDF::StreamData.new(filter: :ASCIIHexDecode) { "10 B0".b }
|
223
227
|
image.write(@file.path)
|
224
228
|
assert_valid_png(@file.path)
|
225
229
|
|
226
230
|
new_image = @doc.images.add(@file.path)
|
227
231
|
assert_equal([:Indexed, :DeviceRGB, 3, "\x00\x00\x00\x40\x40\x40\x80\x80\x80\xFF\xFF\xFF".b],
|
228
|
-
new_image[:ColorSpace])
|
232
|
+
new_image[:ColorSpace].value)
|
229
233
|
assert_equal(image.stream, new_image.stream)
|
230
234
|
end
|
231
235
|
|
@@ -236,14 +240,14 @@ describe HexaPDF::Type::Image do
|
|
236
240
|
end
|
237
241
|
|
238
242
|
it "fails if an unsupported colorspace is used" do
|
239
|
-
image = @doc.add(Type: :XObject, Subtype: :Image, Width: 1, Height: 1, BitsPerComponent: 8,
|
240
|
-
|
243
|
+
image = @doc.add({Type: :XObject, Subtype: :Image, Width: 1, Height: 1, BitsPerComponent: 8,
|
244
|
+
ColorSpace: :ICCBased})
|
241
245
|
assert_raises(HexaPDF::Error) { image.write(@file) }
|
242
246
|
end
|
243
247
|
|
244
248
|
it "fails if an indexed image with an unsupported colorspace is used" do
|
245
|
-
image = @doc.add(Type: :XObject, Subtype: :Image, Width: 1, Height: 1, BitsPerComponent: 8,
|
246
|
-
|
249
|
+
image = @doc.add({Type: :XObject, Subtype: :Image, Width: 1, Height: 1, BitsPerComponent: 8,
|
250
|
+
ColorSpace: [:Indexed, :ICCBased, 0, "0"]})
|
247
251
|
assert_raises(HexaPDF::Error) { image.write(@file) }
|
248
252
|
end
|
249
253
|
end
|