hexapdf 0.35.0 → 0.36.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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, 4768, 6741].freeze,
66
- A0x2: [0, 0, 3370, 4768].freeze,
67
- A0: [0, 0, 2384, 3370].freeze,
68
- A1: [0, 0, 1684, 2384].freeze,
69
- A2: [0, 0, 1191, 1684].freeze,
70
- A3: [0, 0, 842, 1191].freeze,
71
- A4: [0, 0, 595, 842].freeze,
72
- A5: [0, 0, 420, 595].freeze,
73
- A6: [0, 0, 298, 420].freeze,
74
- A7: [0, 0, 210, 298].freeze,
75
- A8: [0, 0, 147, 210].freeze,
76
- A9: [0, 0, 105, 147].freeze,
77
- A10: [0, 0, 74, 105].freeze,
78
- B0: [0, 0, 2835, 4008].freeze,
79
- B1: [0, 0, 2004, 2835].freeze,
80
- B2: [0, 0, 1417, 2004].freeze,
81
- B3: [0, 0, 1001, 1417].freeze,
82
- B4: [0, 0, 709, 1001].freeze,
83
- B5: [0, 0, 499, 709].freeze,
84
- B6: [0, 0, 354, 499].freeze,
85
- B7: [0, 0, 249, 354].freeze,
86
- B8: [0, 0, 176, 249].freeze,
87
- B9: [0, 0, 125, 176].freeze,
88
- B10: [0, 0, 88, 125].freeze,
89
- C0: [0, 0, 2599, 3677].freeze,
90
- C1: [0, 0, 1837, 2599].freeze,
91
- C2: [0, 0, 1298, 1837].freeze,
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, 230, 323].freeze,
97
- C8: [0, 0, 162, 230].freeze,
98
- C9: [0, 0, 113, 162].freeze,
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
@@ -37,6 +37,6 @@
37
37
  module HexaPDF
38
38
 
39
39
  # The version of HexaPDF.
40
- VERSION = '0.35.0'
40
+ VERSION = '0.36.0'
41
41
 
42
42
  end
@@ -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, 742]],
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, 742]],
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, 642]],
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, 742]],
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, 642]],
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, 842], page.box(:media).value)
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, 842, 1191], page.box(:media).value)
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, 842, 595], page.box(:media).value)
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, 842, 595], page.box(:media).value)
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, 842, 595], @doc.pages[0].box(:media).value)
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, nil)
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, nil))
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, nil))
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, nil))
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, nil))
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, nil))
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, nil))
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, nil)
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, -80]],
200
+ [:concatenate_matrix, [1, 0, 0, 1, 20, -72]],
201
201
  [:save_graphics_state],
202
- [:concatenate_matrix, [1, 0, 0, 1, 0, 90]],
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, 55, 90]],
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 0 0 cm
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, 842], page.box(:media))
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(770, style.frame.height)
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(812, frame.height)
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(770, @composer.frame.height)
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, 842, 595], composer.page.box.value)
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
- assert_equal(475, composer.frame.width)
39
- assert_equal(682, composer.frame.height)
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(806, @composer.y)
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, 706]],
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, 406]],
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, 6]],
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, 706]],
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, 406]],
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, 306]],
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, 406]],
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
@@ -40,7 +40,7 @@ describe HexaPDF::Writer do
40
40
  219
41
41
  %%EOF
42
42
  3 0 obj
43
- <</Producer(HexaPDF version 0.35.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.35.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.0)>>
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