hexapdf 0.35.0 → 0.36.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 +37 -0
- data/lib/hexapdf/composer.rb +2 -1
- data/lib/hexapdf/configuration.rb +1 -0
- data/lib/hexapdf/content/canvas_composer.rb +1 -1
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +2 -8
- data/lib/hexapdf/document/layout.rb +15 -6
- data/lib/hexapdf/document.rb +1 -0
- data/lib/hexapdf/layout/box.rb +107 -31
- data/lib/hexapdf/layout/container_box.rb +159 -0
- data/lib/hexapdf/layout/frame.rb +8 -5
- data/lib/hexapdf/layout/list_box.rb +2 -1
- data/lib/hexapdf/layout/width_from_polygon.rb +1 -1
- data/lib/hexapdf/layout.rb +1 -0
- data/lib/hexapdf/type/font_simple.rb +2 -1
- data/lib/hexapdf/type/icon_fit.rb +2 -2
- data/lib/hexapdf/type/page.rb +35 -35
- data/lib/hexapdf/utils.rb +66 -0
- data/lib/hexapdf/version.rb +1 -1
- data/test/hexapdf/content/test_canvas_composer.rb +5 -5
- data/test/hexapdf/document/test_layout.rb +6 -0
- data/test/hexapdf/document/test_pages.rb +5 -5
- data/test/hexapdf/layout/test_box.rb +46 -13
- data/test/hexapdf/layout/test_column_box.rb +4 -4
- data/test/hexapdf/layout/test_container_box.rb +84 -0
- data/test/hexapdf/layout/test_frame.rb +3 -2
- data/test/hexapdf/layout/test_page_style.rb +5 -5
- data/test/hexapdf/test_composer.rb +13 -13
- data/test/hexapdf/test_utils.rb +20 -0
- data/test/hexapdf/test_writer.rb +3 -3
- data/test/hexapdf/type/test_font_simple.rb +9 -1
- data/test/hexapdf/type/test_page.rb +3 -3
- data/test/hexapdf/type/test_page_tree_node.rb +1 -1
- metadata +6 -2
data/lib/hexapdf/type/page.rb
CHANGED
@@ -62,41 +62,41 @@ module HexaPDF
|
|
62
62
|
# * ISO sizes: A0x4, A0x2, A0-A10, B0-B10, C0-C10
|
63
63
|
# * Letter, Legal, Ledger, Tabloid, Executive
|
64
64
|
PAPER_SIZE = {
|
65
|
-
A0x4: [0, 0,
|
66
|
-
A0x2: [0, 0, 3370,
|
67
|
-
A0: [0, 0,
|
68
|
-
A1: [0, 0,
|
69
|
-
A2: [0, 0,
|
70
|
-
A3: [0, 0,
|
71
|
-
A4: [0, 0, 595,
|
72
|
-
A5: [0, 0,
|
73
|
-
A6: [0, 0,
|
74
|
-
A7: [0, 0,
|
75
|
-
A8: [0, 0, 147,
|
76
|
-
A9: [0, 0,
|
77
|
-
A10: [0, 0,
|
78
|
-
B0: [0, 0,
|
79
|
-
B1: [0, 0, 2004,
|
80
|
-
B2: [0, 0, 1417, 2004].freeze,
|
81
|
-
B3: [0, 0,
|
82
|
-
B4: [0, 0,
|
83
|
-
B5: [0, 0,
|
84
|
-
B6: [0, 0, 354,
|
85
|
-
B7: [0, 0, 249, 354].freeze,
|
86
|
-
B8: [0, 0,
|
87
|
-
B9: [0, 0,
|
88
|
-
B10: [0, 0,
|
89
|
-
C0: [0, 0, 2599,
|
90
|
-
C1: [0, 0,
|
91
|
-
C2: [0, 0, 1298,
|
92
|
-
C3: [0, 0, 918, 1298].freeze,
|
93
|
-
C4: [0, 0, 649, 918].freeze,
|
94
|
-
C5: [0, 0, 459, 649].freeze,
|
95
|
-
C6: [0, 0, 323, 459].freeze,
|
96
|
-
C7: [0, 0,
|
97
|
-
C8: [0, 0,
|
98
|
-
C9: [0, 0, 113,
|
99
|
-
C10: [0, 0, 79, 113].freeze,
|
65
|
+
A0x4: [0, 0, 4767.874016, 6740.787402].freeze,
|
66
|
+
A0x2: [0, 0, 3370.393701, 4767.874016].freeze,
|
67
|
+
A0: [0, 0, 2383.937008, 3370.393701].freeze,
|
68
|
+
A1: [0, 0, 1683.779528, 2383.937008].freeze,
|
69
|
+
A2: [0, 0, 1190.551181, 1683.779528].freeze,
|
70
|
+
A3: [0, 0, 841.889764, 1190.551181].freeze,
|
71
|
+
A4: [0, 0, 595.275591, 841.889764].freeze,
|
72
|
+
A5: [0, 0, 419.527559, 595.275591].freeze,
|
73
|
+
A6: [0, 0, 297.637795, 419.527559].freeze,
|
74
|
+
A7: [0, 0, 209.76378, 297.637795].freeze,
|
75
|
+
A8: [0, 0, 147.401575, 209.76378].freeze,
|
76
|
+
A9: [0, 0, 104.88189, 147.401575].freeze,
|
77
|
+
A10: [0, 0, 73.700787, 104.88189].freeze,
|
78
|
+
B0: [0, 0, 2834.645669, 4008.188976].freeze,
|
79
|
+
B1: [0, 0, 2004.094488, 2834.645669].freeze,
|
80
|
+
B2: [0, 0, 1417.322835, 2004.094488].freeze,
|
81
|
+
B3: [0, 0, 1000.629921, 1417.322835].freeze,
|
82
|
+
B4: [0, 0, 708.661417, 1000.629921].freeze,
|
83
|
+
B5: [0, 0, 498.897638, 708.661417].freeze,
|
84
|
+
B6: [0, 0, 354.330709, 498.897638].freeze,
|
85
|
+
B7: [0, 0, 249.448819, 354.330709].freeze,
|
86
|
+
B8: [0, 0, 175.748031, 249.448819].freeze,
|
87
|
+
B9: [0, 0, 124.724409, 175.748031].freeze,
|
88
|
+
B10: [0, 0, 87.874016, 124.724409].freeze,
|
89
|
+
C0: [0, 0, 2599.370079, 3676.535433].freeze,
|
90
|
+
C1: [0, 0, 1836.850394, 2599.370079].freeze,
|
91
|
+
C2: [0, 0, 1298.267717, 1836.850394].freeze,
|
92
|
+
C3: [0, 0, 918.425197, 1298.267717].freeze,
|
93
|
+
C4: [0, 0, 649.133858, 918.425197].freeze,
|
94
|
+
C5: [0, 0, 459.212598, 649.133858].freeze,
|
95
|
+
C6: [0, 0, 323.149606, 459.212598].freeze,
|
96
|
+
C7: [0, 0, 229.606299, 323.149606].freeze,
|
97
|
+
C8: [0, 0, 161.574803, 229.606299].freeze,
|
98
|
+
C9: [0, 0, 113.385827, 161.574803].freeze,
|
99
|
+
C10: [0, 0, 79.370079, 113.385827].freeze,
|
100
100
|
Letter: [0, 0, 612, 792].freeze,
|
101
101
|
Legal: [0, 0, 612, 1008].freeze,
|
102
102
|
Ledger: [0, 0, 792, 1224].freeze,
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# This file is part of HexaPDF.
|
5
|
+
#
|
6
|
+
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
+
# Copyright (C) 2014-2023 Thomas Leitner
|
8
|
+
#
|
9
|
+
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
|
+
# under the terms of the GNU Affero General Public License version 3 as
|
11
|
+
# published by the Free Software Foundation with the addition of the
|
12
|
+
# following permission added to Section 15 as permitted in Section 7(a):
|
13
|
+
# FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
14
|
+
# THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
|
15
|
+
# INFRINGEMENT OF THIRD PARTY RIGHTS.
|
16
|
+
#
|
17
|
+
# HexaPDF is distributed in the hope that it will be useful, but WITHOUT
|
18
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
20
|
+
# License for more details.
|
21
|
+
#
|
22
|
+
# You should have received a copy of the GNU Affero General Public License
|
23
|
+
# along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
|
24
|
+
#
|
25
|
+
# The interactive user interfaces in modified source and object code
|
26
|
+
# versions of HexaPDF must display Appropriate Legal Notices, as required
|
27
|
+
# under Section 5 of the GNU Affero General Public License version 3.
|
28
|
+
#
|
29
|
+
# In accordance with Section 7(b) of the GNU Affero General Public
|
30
|
+
# License, a covered work must retain the producer line in every PDF that
|
31
|
+
# is created or manipulated using HexaPDF.
|
32
|
+
#
|
33
|
+
# If the GNU Affero General Public License doesn't fit your need,
|
34
|
+
# commercial licenses are available at <https://gettalong.at/hexapdf/>.
|
35
|
+
#++
|
36
|
+
|
37
|
+
require 'geom2d/utils'
|
38
|
+
|
39
|
+
module HexaPDF
|
40
|
+
module Utils
|
41
|
+
|
42
|
+
# The precision with which to compare floating point numbers.
|
43
|
+
#
|
44
|
+
# This is chosen with respect to precision that is used for serializing floating point numbers.
|
45
|
+
EPSILON = 1e-6
|
46
|
+
|
47
|
+
# Best effort of setting Geom2D's precision to the one used by HexaPDF.
|
48
|
+
::Geom2D::Utils.precision = EPSILON
|
49
|
+
|
50
|
+
module_function
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# Compares two floats whether they are equal using the FLOAT_EPSILON precision.
|
55
|
+
def float_equal(a, b)
|
56
|
+
(a - b).abs < EPSILON
|
57
|
+
end
|
58
|
+
|
59
|
+
# Compares two floats like the <=> operator but using the FLOAT_EPSILON precision for detecting
|
60
|
+
# whether they are equal.
|
61
|
+
def float_compare(a, b)
|
62
|
+
(a - b).abs < EPSILON ? 0 : a <=> b
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
data/lib/hexapdf/version.rb
CHANGED
@@ -39,7 +39,7 @@ describe HexaPDF::Content::CanvasComposer do
|
|
39
39
|
@composer.draw_box(create_box)
|
40
40
|
assert_operators(@composer.canvas.contents,
|
41
41
|
[[:save_graphics_state],
|
42
|
-
[:concatenate_matrix, [1, 0, 0, 1, 0,
|
42
|
+
[:concatenate_matrix, [1, 0, 0, 1, 0, 741.889764]],
|
43
43
|
[:restore_graphics_state],
|
44
44
|
[:save_graphics_state],
|
45
45
|
[:concatenate_matrix, [1, 0, 0, 1, 0, 0]],
|
@@ -58,10 +58,10 @@ describe HexaPDF::Content::CanvasComposer do
|
|
58
58
|
[:concatenate_matrix, [1, 0, 0, 1, 0, 0]],
|
59
59
|
[:restore_graphics_state],
|
60
60
|
[:save_graphics_state],
|
61
|
-
[:concatenate_matrix, [1, 0, 0, 1, 400,
|
61
|
+
[:concatenate_matrix, [1, 0, 0, 1, 400, 741.889764]],
|
62
62
|
[:restore_graphics_state],
|
63
63
|
[:save_graphics_state],
|
64
|
-
[:concatenate_matrix, [1, 0, 0, 1, 400,
|
64
|
+
[:concatenate_matrix, [1, 0, 0, 1, 400, 641.889764]],
|
65
65
|
[:restore_graphics_state]])
|
66
66
|
end
|
67
67
|
|
@@ -70,10 +70,10 @@ describe HexaPDF::Content::CanvasComposer do
|
|
70
70
|
@composer.draw_box(create_box(width: 400, height: 100))
|
71
71
|
assert_operators(@composer.canvas.contents,
|
72
72
|
[[:save_graphics_state],
|
73
|
-
[:concatenate_matrix, [1, 0, 0, 1, 0,
|
73
|
+
[:concatenate_matrix, [1, 0, 0, 1, 0, 741.889764]],
|
74
74
|
[:restore_graphics_state],
|
75
75
|
[:save_graphics_state],
|
76
|
-
[:concatenate_matrix, [1, 0, 0, 1, 0,
|
76
|
+
[:concatenate_matrix, [1, 0, 0, 1, 0, 641.889764]],
|
77
77
|
[:restore_graphics_state]])
|
78
78
|
end
|
79
79
|
|
@@ -175,6 +175,12 @@ describe HexaPDF::Document::Layout do
|
|
175
175
|
assert_equal(2, box.children.size)
|
176
176
|
end
|
177
177
|
|
178
|
+
it "uses the provided block as drawing block for the base box class if name=:base" do
|
179
|
+
block = proc {}
|
180
|
+
box = @layout.box(width: 100, &block)
|
181
|
+
assert_equal(block, box.instance_variable_get(:@draw_block))
|
182
|
+
end
|
183
|
+
|
178
184
|
it "fails if the name is not registered" do
|
179
185
|
assert_raises(HexaPDF::Error) { @layout.box(:unknown) }
|
180
186
|
end
|
@@ -17,20 +17,20 @@ describe HexaPDF::Document::Pages do
|
|
17
17
|
describe "create" do
|
18
18
|
it "uses the defaults from the configuration for missing arguments" do
|
19
19
|
page = @doc.pages.create
|
20
|
-
assert_equal([0, 0, 595,
|
20
|
+
assert_equal([0, 0, 595.275591, 841.889764], page.box(:media).value)
|
21
21
|
end
|
22
22
|
|
23
23
|
it "allows specifying a reference to a predefined page size" do
|
24
24
|
page = @doc.pages.create(media_box: :A3)
|
25
|
-
assert_equal([0, 0,
|
25
|
+
assert_equal([0, 0, 841.889764, 1190.551181], page.box(:media).value)
|
26
26
|
end
|
27
27
|
|
28
28
|
it "allows specifying the orientation for a predefined page size" do
|
29
29
|
page = @doc.pages.create(media_box: :A4, orientation: :landscape)
|
30
|
-
assert_equal([0, 0,
|
30
|
+
assert_equal([0, 0, 841.889764, 595.275591], page.box(:media).value)
|
31
31
|
|
32
32
|
page = @doc.pages.create(orientation: :landscape)
|
33
|
-
assert_equal([0, 0,
|
33
|
+
assert_equal([0, 0, 841.889764, 595.275591], page.box(:media).value)
|
34
34
|
end
|
35
35
|
|
36
36
|
it "allows using a media box array" do
|
@@ -54,7 +54,7 @@ describe HexaPDF::Document::Pages do
|
|
54
54
|
it "adds a new empty page with the given page format" do
|
55
55
|
page = @doc.pages.add(:A4, orientation: :landscape)
|
56
56
|
assert_same(page, @doc.pages[0])
|
57
|
-
assert_equal([0, 0,
|
57
|
+
assert_equal([0, 0, 841.889764, 595.275591], @doc.pages[0].box(:media).value)
|
58
58
|
end
|
59
59
|
|
60
60
|
it "adds the given page to the end" do
|
@@ -5,6 +5,12 @@ require 'hexapdf/document'
|
|
5
5
|
require 'hexapdf/layout/box'
|
6
6
|
|
7
7
|
describe HexaPDF::Layout::Box do
|
8
|
+
before do
|
9
|
+
@frame = Object.new
|
10
|
+
def @frame.x; 0; end
|
11
|
+
def @frame.y; 100; end
|
12
|
+
end
|
13
|
+
|
8
14
|
def create_box(**args, &block)
|
9
15
|
HexaPDF::Layout::Box.new(**args, &block)
|
10
16
|
end
|
@@ -70,15 +76,13 @@ describe HexaPDF::Layout::Box do
|
|
70
76
|
end
|
71
77
|
|
72
78
|
describe "fit" do
|
73
|
-
before do
|
74
|
-
@frame = Object.new
|
75
|
-
end
|
76
|
-
|
77
79
|
it "fits a fixed sized box" do
|
78
|
-
box = create_box(width: 50, height: 50)
|
80
|
+
box = create_box(width: 50, height: 50, style: {padding: 5})
|
79
81
|
assert(box.fit(100, 100, @frame))
|
80
82
|
assert_equal(50, box.width)
|
81
83
|
assert_equal(50, box.height)
|
84
|
+
assert_equal(5, box.instance_variable_get(:@fit_x))
|
85
|
+
assert_equal(55, box.instance_variable_get(:@fit_y))
|
82
86
|
end
|
83
87
|
|
84
88
|
it "uses the maximum available width" do
|
@@ -95,53 +99,82 @@ describe HexaPDF::Layout::Box do
|
|
95
99
|
assert_equal(100, box.height)
|
96
100
|
end
|
97
101
|
|
102
|
+
it "uses float comparison" do
|
103
|
+
box = create_box(width: 50.0000002, height: 49.9999996)
|
104
|
+
assert(box.fit(50, 50, @frame))
|
105
|
+
assert_equal(50.0000002, box.width)
|
106
|
+
assert_equal(49.9999996, box.height)
|
107
|
+
end
|
108
|
+
|
98
109
|
it "returns false if the box doesn't fit" do
|
99
110
|
box = create_box(width: 101)
|
100
111
|
refute(box.fit(100, 100, @frame))
|
101
112
|
end
|
113
|
+
|
114
|
+
it "can use the #content_width/#content_height helper methods" do
|
115
|
+
box = create_box
|
116
|
+
box.define_singleton_method(:fit_content) do |aw, ah, frame|
|
117
|
+
update_content_width { 10 }
|
118
|
+
update_content_height { 20 }
|
119
|
+
true
|
120
|
+
end
|
121
|
+
assert(box.fit(100, 100, @frame))
|
122
|
+
assert_equal(10, box.width)
|
123
|
+
assert_equal(20, box.height)
|
124
|
+
|
125
|
+
box = create_box(width: 30, height: 50)
|
126
|
+
box.define_singleton_method(:fit_content) do |aw, ah, frame|
|
127
|
+
update_content_width { 10 }
|
128
|
+
update_content_height { 20 }
|
129
|
+
true
|
130
|
+
end
|
131
|
+
assert(box.fit(100, 100, @frame))
|
132
|
+
assert_equal(30, box.width)
|
133
|
+
assert_equal(50, box.height)
|
134
|
+
end
|
102
135
|
end
|
103
136
|
|
104
137
|
describe "split" do
|
105
138
|
before do
|
106
139
|
@box = create_box(width: 100, height: 100)
|
107
|
-
@box.fit(100, 100,
|
140
|
+
@box.fit(100, 100, @frame)
|
108
141
|
end
|
109
142
|
|
110
143
|
it "doesn't need to be split if it completely fits" do
|
111
|
-
assert_equal([@box, nil], @box.split(100, 100,
|
144
|
+
assert_equal([@box, nil], @box.split(100, 100, @frame))
|
112
145
|
end
|
113
146
|
|
114
147
|
it "can't be split if it doesn't (completely) fit and its width is greater than the available width" do
|
115
148
|
@box.fit(90, 100, nil)
|
116
|
-
assert_equal([nil, @box], @box.split(50, 150,
|
149
|
+
assert_equal([nil, @box], @box.split(50, 150, @frame))
|
117
150
|
end
|
118
151
|
|
119
152
|
it "can't be split if it doesn't (completely) fit and its height is greater than the available height" do
|
120
153
|
@box.fit(90, 100, nil)
|
121
|
-
assert_equal([nil, @box], @box.split(150, 50,
|
154
|
+
assert_equal([nil, @box], @box.split(150, 50, @frame))
|
122
155
|
end
|
123
156
|
|
124
157
|
it "can't be split if it doesn't (completely) fit and its content width is zero" do
|
125
158
|
box = create_box(width: 0, height: 100)
|
126
|
-
assert_equal([nil, box], box.split(150, 150,
|
159
|
+
assert_equal([nil, box], box.split(150, 150, @frame))
|
127
160
|
end
|
128
161
|
|
129
162
|
it "can't be split if it doesn't (completely) fit and its content height is zero" do
|
130
163
|
box = create_box(width: 100, height: 0)
|
131
|
-
assert_equal([nil, box], box.split(150, 150,
|
164
|
+
assert_equal([nil, box], box.split(150, 150, @frame))
|
132
165
|
end
|
133
166
|
|
134
167
|
it "can't be split if it doesn't (completely) fit as the default implementation " \
|
135
168
|
"knows nothing about the content" do
|
136
169
|
@box.style.position = :flow # make sure we would generally be splitable
|
137
170
|
@box.fit(90, 100, nil)
|
138
|
-
assert_equal([nil, @box], @box.split(150, 150,
|
171
|
+
assert_equal([nil, @box], @box.split(150, 150, @frame))
|
139
172
|
end
|
140
173
|
end
|
141
174
|
|
142
175
|
it "can create a cloned box for splitting" do
|
143
176
|
box = create_box
|
144
|
-
box.fit(100, 100,
|
177
|
+
box.fit(100, 100, @frame)
|
145
178
|
cloned_box = box.send(:create_split_box)
|
146
179
|
assert(cloned_box.split_box?)
|
147
180
|
refute(cloned_box.instance_variable_get(:@fit_successful))
|
@@ -192,19 +192,19 @@ describe HexaPDF::Layout::ColumnBox do
|
|
192
192
|
end
|
193
193
|
|
194
194
|
it "takes a different final location into account" do
|
195
|
-
box = create_box(children: @fixed_size_boxes[0, 2])
|
195
|
+
box = create_box(children: @fixed_size_boxes[0, 2], style: {padding: [2, 4, 6, 8]})
|
196
196
|
box.fit(100, 100, @frame)
|
197
197
|
box.draw(@canvas, 20, 10)
|
198
198
|
operators = [
|
199
199
|
[:save_graphics_state],
|
200
|
-
[:concatenate_matrix, [1, 0, 0, 1, 20, -
|
200
|
+
[:concatenate_matrix, [1, 0, 0, 1, 20, -72]],
|
201
201
|
[:save_graphics_state],
|
202
|
-
[:concatenate_matrix, [1, 0, 0, 1,
|
202
|
+
[:concatenate_matrix, [1, 0, 0, 1, 8, 88]],
|
203
203
|
[:move_to, [0, 0]],
|
204
204
|
[:end_path],
|
205
205
|
[:restore_graphics_state],
|
206
206
|
[:save_graphics_state],
|
207
|
-
[:concatenate_matrix, [1, 0, 0, 1,
|
207
|
+
[:concatenate_matrix, [1, 0, 0, 1, 57, 88]],
|
208
208
|
[:move_to, [0, 0]],
|
209
209
|
[:end_path],
|
210
210
|
[:restore_graphics_state],
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/document'
|
5
|
+
require 'hexapdf/layout/container_box'
|
6
|
+
|
7
|
+
describe HexaPDF::Layout::ContainerBox do
|
8
|
+
before do
|
9
|
+
@doc = HexaPDF::Document.new
|
10
|
+
@frame = HexaPDF::Layout::Frame.new(0, 0, 100, 100)
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_box(children, **kwargs)
|
14
|
+
HexaPDF::Layout::ContainerBox.new(children: Array(children), **kwargs)
|
15
|
+
end
|
16
|
+
|
17
|
+
def check_box(box, width, height, fit_pos = nil)
|
18
|
+
assert(box.fit(@frame.available_width, @frame.available_height, @frame), "box didn't fit")
|
19
|
+
assert_equal(width, box.width, "box width")
|
20
|
+
assert_equal(height, box.height, "box height")
|
21
|
+
if fit_pos
|
22
|
+
box_fitter = box.instance_variable_get(:@box_fitter)
|
23
|
+
assert_equal(fit_pos.size, box_fitter.fit_results.size)
|
24
|
+
fit_pos.each_with_index do |(x, y), index|
|
25
|
+
assert_equal(x, box_fitter.fit_results[index].x, "result[#{index}].x")
|
26
|
+
assert_equal(y, box_fitter.fit_results[index].y, "result[#{index}].y")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "empty?" do
|
32
|
+
it "is empty if nothing is fit yet" do
|
33
|
+
assert(create_box([]).empty?)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "is empty if no box fits" do
|
37
|
+
box = create_box(@doc.layout.box(width: 110))
|
38
|
+
box.fit(@frame.available_width, @frame.available_height, @frame)
|
39
|
+
assert(box.empty?)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "is not empty if at least one box fits" do
|
43
|
+
box = create_box(@doc.layout.box(width: 50, height: 20))
|
44
|
+
check_box(box, 100, 20)
|
45
|
+
refute(box.empty?)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "fit_content" do
|
50
|
+
it "fits the children according to their mask_mode, valign, and align style properties" do
|
51
|
+
box = create_box([@doc.layout.box(height: 20),
|
52
|
+
@doc.layout.box(height: 20, style: {valign: :bottom, mask_mode: :fill_horizontal}),
|
53
|
+
@doc.layout.box(width: 20, style: {align: :right, mask_mode: :fill_vertical})])
|
54
|
+
check_box(box, 100, 100, [[0, 80], [0, 0], [80, 20]])
|
55
|
+
end
|
56
|
+
|
57
|
+
it "respects the initially set width/height as well as border/padding" do
|
58
|
+
box = create_box(@doc.layout.box(height: 20), height: 50, width: 40,
|
59
|
+
style: {padding: 2, border: {width: 3}})
|
60
|
+
check_box(box, 40, 50, [[5, 75]])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "draw_content" do
|
65
|
+
before do
|
66
|
+
@canvas = @doc.pages.add.canvas
|
67
|
+
end
|
68
|
+
|
69
|
+
it "draws the result onto the canvas" do
|
70
|
+
child_box = @doc.layout.box(height: 20) do |canvas, b|
|
71
|
+
canvas.line(0, 0, b.content_width, b.content_height).end_path
|
72
|
+
end
|
73
|
+
box = create_box(child_box)
|
74
|
+
box.fit(100, 100, @frame)
|
75
|
+
box.draw(@canvas, 0, 50)
|
76
|
+
assert_operators(@canvas.contents, [[:save_graphics_state],
|
77
|
+
[:concatenate_matrix, [1, 0, 0, 1, 0, 50]],
|
78
|
+
[:move_to, [0, 0]],
|
79
|
+
[:line_to, [100, 20]],
|
80
|
+
[:end_path],
|
81
|
+
[:restore_graphics_state]])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -13,10 +13,11 @@ describe HexaPDF::Layout::Frame::FitResult do
|
|
13
13
|
result = HexaPDF::Layout::Frame::FitResult.new(box)
|
14
14
|
result.mask = Geom2D::Rectangle(0, 0, 20, 20)
|
15
15
|
result.x = result.y = 0
|
16
|
-
result.draw(canvas)
|
16
|
+
result.draw(canvas, dx: 10, dy: 15)
|
17
17
|
assert_equal(<<~CONTENTS, canvas.contents)
|
18
18
|
/OC /P1 BDC
|
19
19
|
q
|
20
|
+
1 0 0 1 10 15 cm
|
20
21
|
0.0 0.501961 0.0 rg
|
21
22
|
0.0 0.392157 0.0 RG
|
22
23
|
/GS1 gs
|
@@ -25,7 +26,7 @@ describe HexaPDF::Layout::Frame::FitResult do
|
|
25
26
|
Q
|
26
27
|
EMC
|
27
28
|
q
|
28
|
-
1 0 0 1
|
29
|
+
1 0 0 1 10 15 cm
|
29
30
|
Q
|
30
31
|
CONTENTS
|
31
32
|
ocg = doc.optional_content.ocgs.first
|
@@ -35,7 +35,7 @@ describe HexaPDF::Layout::PageStyle do
|
|
35
35
|
istyle.next_style = :other
|
36
36
|
end
|
37
37
|
page = style.create_page(@doc)
|
38
|
-
assert_equal([0, 0, 595,
|
38
|
+
assert_equal([0, 0, 595.275591, 841.889764], page.box(:media))
|
39
39
|
assert_equal("0 0 10 10 re\nS\n", page.contents)
|
40
40
|
assert_equal(:frame, style.frame)
|
41
41
|
assert_equal(:other, style.next_style)
|
@@ -54,8 +54,8 @@ describe HexaPDF::Layout::PageStyle do
|
|
54
54
|
assert_kind_of(HexaPDF::Layout::Frame, style.frame)
|
55
55
|
assert_equal(36, style.frame.left)
|
56
56
|
assert_equal(36, style.frame.bottom)
|
57
|
-
assert_equal(523, style.frame.width)
|
58
|
-
assert_equal(
|
57
|
+
assert_equal(523.275591, style.frame.width)
|
58
|
+
assert_equal(769.889764, style.frame.height)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -65,7 +65,7 @@ describe HexaPDF::Layout::PageStyle do
|
|
65
65
|
frame = style.create_frame(style.create_page(doc), [15, 10])
|
66
66
|
assert_equal(10, frame.left)
|
67
67
|
assert_equal(15, frame.bottom)
|
68
|
-
assert_equal(575, frame.width)
|
69
|
-
assert_equal(
|
68
|
+
assert_equal(575.275591, frame.width)
|
69
|
+
assert_equal(811.889764, frame.height)
|
70
70
|
end
|
71
71
|
end
|
@@ -16,8 +16,8 @@ describe HexaPDF::Composer do
|
|
16
16
|
assert_kind_of(HexaPDF::Type::Page, @composer.page)
|
17
17
|
assert_equal(36, @composer.frame.left)
|
18
18
|
assert_equal(36, @composer.frame.bottom)
|
19
|
-
assert_equal(523, @composer.frame.width)
|
20
|
-
assert_equal(
|
19
|
+
assert_equal(523.275591, @composer.frame.width)
|
20
|
+
assert_equal(769.889764, @composer.frame.height)
|
21
21
|
assert_kind_of(HexaPDF::Layout::Style, @composer.style(:base))
|
22
22
|
end
|
23
23
|
|
@@ -28,15 +28,15 @@ describe HexaPDF::Composer do
|
|
28
28
|
|
29
29
|
it "allows the customization of the page orientation" do
|
30
30
|
composer = HexaPDF::Composer.new(page_orientation: :landscape)
|
31
|
-
assert_equal([0, 0,
|
31
|
+
assert_equal([0, 0, 841.889764, 595.275591], composer.page.box.value)
|
32
32
|
end
|
33
33
|
|
34
34
|
it "allows the customization of the margin" do
|
35
35
|
composer = HexaPDF::Composer.new(margin: [100, 80, 60, 40])
|
36
36
|
assert_equal(40, composer.frame.left)
|
37
37
|
assert_equal(60, composer.frame.bottom)
|
38
|
-
|
39
|
-
assert_equal(
|
38
|
+
assert_in_delta(475.275591, composer.frame.width)
|
39
|
+
assert_equal(681.889764, composer.frame.height)
|
40
40
|
end
|
41
41
|
|
42
42
|
it "allows skipping the initial page creation" do
|
@@ -107,7 +107,7 @@ describe HexaPDF::Composer do
|
|
107
107
|
end
|
108
108
|
|
109
109
|
it "returns the current y-position" do
|
110
|
-
assert_equal(
|
110
|
+
assert_equal(805.889764, @composer.y)
|
111
111
|
end
|
112
112
|
|
113
113
|
describe "style" do
|
@@ -203,7 +203,7 @@ describe HexaPDF::Composer do
|
|
203
203
|
@composer.draw_box(create_box)
|
204
204
|
assert_operators(@composer.canvas.contents,
|
205
205
|
[[:save_graphics_state],
|
206
|
-
[:concatenate_matrix, [1, 0, 0, 1, 36,
|
206
|
+
[:concatenate_matrix, [1, 0, 0, 1, 36, 705.889764]],
|
207
207
|
[:restore_graphics_state],
|
208
208
|
[:save_graphics_state],
|
209
209
|
[:concatenate_matrix, [1, 0, 0, 1, 36, 36]],
|
@@ -232,14 +232,14 @@ describe HexaPDF::Composer do
|
|
232
232
|
@composer.draw_box(box)
|
233
233
|
assert_operators(first_page_contents,
|
234
234
|
[[:save_graphics_state],
|
235
|
-
[:concatenate_matrix, [1, 0, 0, 1, 36,
|
235
|
+
[:concatenate_matrix, [1, 0, 0, 1, 36, 405.889764]],
|
236
236
|
[:restore_graphics_state],
|
237
237
|
[:save_graphics_state],
|
238
|
-
[:concatenate_matrix, [1, 0, 0, 1, 36,
|
238
|
+
[:concatenate_matrix, [1, 0, 0, 1, 36, 5.889764]],
|
239
239
|
[:restore_graphics_state]])
|
240
240
|
assert_operators(@composer.canvas.contents,
|
241
241
|
[[:save_graphics_state],
|
242
|
-
[:concatenate_matrix, [1, 0, 0, 1, 36,
|
242
|
+
[:concatenate_matrix, [1, 0, 0, 1, 36, 705.889764]],
|
243
243
|
[:restore_graphics_state]])
|
244
244
|
end
|
245
245
|
|
@@ -252,14 +252,14 @@ describe HexaPDF::Composer do
|
|
252
252
|
@composer.draw_box(box)
|
253
253
|
assert_operators(first_page_contents,
|
254
254
|
[[:save_graphics_state],
|
255
|
-
[:concatenate_matrix, [1, 0, 0, 1, 36,
|
255
|
+
[:concatenate_matrix, [1, 0, 0, 1, 36, 405.889764]],
|
256
256
|
[:restore_graphics_state],
|
257
257
|
[:save_graphics_state],
|
258
|
-
[:concatenate_matrix, [1, 0, 0, 1, 36,
|
258
|
+
[:concatenate_matrix, [1, 0, 0, 1, 36, 305.889764]],
|
259
259
|
[:restore_graphics_state]])
|
260
260
|
assert_operators(@composer.canvas.contents,
|
261
261
|
[[:save_graphics_state],
|
262
|
-
[:concatenate_matrix, [1, 0, 0, 1, 36,
|
262
|
+
[:concatenate_matrix, [1, 0, 0, 1, 36, 405.889764]],
|
263
263
|
[:restore_graphics_state]])
|
264
264
|
end
|
265
265
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/utils.rb'
|
5
|
+
|
6
|
+
describe HexaPDF::Utils do
|
7
|
+
include HexaPDF::Utils
|
8
|
+
|
9
|
+
it "checks floats for equality with a certain precision" do
|
10
|
+
assert(float_equal(1.0, 1))
|
11
|
+
assert(float_equal(1.0, 1.0000003))
|
12
|
+
end
|
13
|
+
|
14
|
+
it "compares floats like the <=> operator" do
|
15
|
+
assert_equal(0, float_compare(1.0, 1))
|
16
|
+
assert_equal(0, float_compare(1.0, 1.0000003))
|
17
|
+
assert_equal(-1, float_compare(1.0, 1.03))
|
18
|
+
assert_equal(1, float_compare(1.0, 0.9997))
|
19
|
+
end
|
20
|
+
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.36.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.36.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.35.
|
217
|
+
<</Producer(HexaPDF version 0.35.1)>>
|
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
|