hexapdf 0.12.1 → 0.12.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/lib/hexapdf/type/form.rb +9 -0
- data/lib/hexapdf/type/page.rb +19 -4
- data/lib/hexapdf/version.rb +1 -1
- data/test/hexapdf/layout/test_style.rb +1 -1
- data/test/hexapdf/test_writer.rb +2 -2
- data/test/hexapdf/type/test_form.rb +18 -0
- data/test/hexapdf/type/test_page.rb +37 -6
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d95e6e2abba7581aab78e449bf860c3955170d4c266850373296300495236c44
|
4
|
+
data.tar.gz: '0950af72d8864e98a70367ee28bdf09bc09aa83cace38933aa613bc8d476263d'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3c4ad1073d3ea9b820dc129348cf2d571159ea129aa65a10546552ae52e19cf29d74a4716e3fcefac10b34f9d2ad7e833bb90355c81564a152c853e0a406ea4
|
7
|
+
data.tar.gz: 637e17817d1aa8eb3b75035aa5d654f5bdbd7b531fb16776da49945c5100ab0705ab7d59b300f192b865d75ded43edae48d2f15541c2a93edbdedba9318f896a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## 0.12.2 - 2020-08-17
|
2
|
+
|
3
|
+
### Fixed
|
4
|
+
|
5
|
+
- Wrong origin for page canvases when bottom left corner of media box doesn't
|
6
|
+
coincide with origin of coordinate system
|
7
|
+
- Wrong origin for Form XObject canvas when bottom left corner of bounding box
|
8
|
+
doesn't coincide with origin of coordinate system
|
9
|
+
|
10
|
+
|
1
11
|
## 0.12.1 - 2020-08-16
|
2
12
|
|
3
13
|
### Added
|
data/lib/hexapdf/type/form.rb
CHANGED
@@ -126,13 +126,22 @@ module HexaPDF
|
|
126
126
|
# The canvas object is cached once it is created so that its graphics state is correctly
|
127
127
|
# retained without the need for parsing its contents.
|
128
128
|
#
|
129
|
+
# If the bounding box of the form XObject doesn't have its origin at (0, 0), the canvas origin
|
130
|
+
# is translated into the bottom left corner so that this detail doesn't matter when using the
|
131
|
+
# canvas. This means that the canvas' origin is always at the bottom left corner of the
|
132
|
+
# bounding box.
|
133
|
+
#
|
129
134
|
# *Note* that a canvas can only be retrieved for initially empty form XObjects!
|
130
135
|
def canvas
|
131
136
|
document.cache(@data, :canvas) do
|
132
137
|
unless stream.empty?
|
133
138
|
raise HexaPDF::Error, "Cannot create a canvas for a form XObjects with contents"
|
134
139
|
end
|
140
|
+
|
135
141
|
canvas = Content::Canvas.new(self)
|
142
|
+
if box.left != 0 || box.bottom != 0
|
143
|
+
canvas.save_graphics_state.translate(box.left, box.bottom)
|
144
|
+
end
|
136
145
|
self.stream = canvas.stream_data
|
137
146
|
set_filter(:FlateDecode)
|
138
147
|
canvas
|
data/lib/hexapdf/type/page.rb
CHANGED
@@ -358,6 +358,11 @@ module HexaPDF
|
|
358
358
|
# The canvas object is cached once it is created so that its graphics state is correctly
|
359
359
|
# retained without the need for parsing its contents.
|
360
360
|
#
|
361
|
+
# If the media box of the page doesn't have its origin at (0, 0), the canvas origin is
|
362
|
+
# translated into the bottom left corner so that this detail doesn't matter when using the
|
363
|
+
# canvas. This means that the canvas' origin is always at the bottom left corner of the media
|
364
|
+
# box.
|
365
|
+
#
|
361
366
|
# type::
|
362
367
|
# Can either be
|
363
368
|
# * :page for getting the canvas for the page itself (only valid for initially empty pages)
|
@@ -374,16 +379,25 @@ module HexaPDF
|
|
374
379
|
raise HexaPDF::Error, "Cannot get the canvas for a page with contents"
|
375
380
|
end
|
376
381
|
|
382
|
+
create_canvas = lambda do
|
383
|
+
Content::Canvas.new(self).tap do |canvas|
|
384
|
+
media_box = box(:media)
|
385
|
+
if media_box.left != 0 || media_box.bottom != 0
|
386
|
+
canvas.translate(media_box.left, media_box.bottom)
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
377
391
|
contents = self[:Contents]
|
378
392
|
if contents.nil?
|
379
|
-
page_canvas = document.cache(@data, :page_canvas,
|
393
|
+
page_canvas = document.cache(@data, :page_canvas, create_canvas.call)
|
380
394
|
self[:Contents] = document.add({Filter: :FlateDecode},
|
381
395
|
stream: page_canvas.stream_data)
|
382
396
|
end
|
383
397
|
|
384
398
|
if type == :overlay || type == :underlay
|
385
|
-
underlay_canvas = document.cache(@data, :underlay_canvas,
|
386
|
-
overlay_canvas = document.cache(@data, :overlay_canvas,
|
399
|
+
underlay_canvas = document.cache(@data, :underlay_canvas, create_canvas.call)
|
400
|
+
overlay_canvas = document.cache(@data, :overlay_canvas, create_canvas.call)
|
387
401
|
|
388
402
|
stream = HexaPDF::StreamData.new do
|
389
403
|
Fiber.yield(" q ")
|
@@ -396,11 +410,12 @@ module HexaPDF
|
|
396
410
|
underlay = document.add({Filter: :FlateDecode}, stream: stream)
|
397
411
|
|
398
412
|
stream = HexaPDF::StreamData.new do
|
399
|
-
Fiber.yield(" Q ")
|
413
|
+
Fiber.yield(" Q q ")
|
400
414
|
fiber = overlay_canvas.stream_data.fiber
|
401
415
|
while fiber.alive? && (data = fiber.resume)
|
402
416
|
Fiber.yield(data)
|
403
417
|
end
|
418
|
+
" Q "
|
404
419
|
end
|
405
420
|
overlay = document.add({Filter: :FlateDecode}, stream: stream)
|
406
421
|
|
data/lib/hexapdf/version.rb
CHANGED
@@ -537,7 +537,7 @@ describe HexaPDF::Layout::Style::LinkLayer do
|
|
537
537
|
end
|
538
538
|
|
539
539
|
it "does nothing if the context is not a page object" do
|
540
|
-
@canvas = HexaPDF::Document.new.add({Type: :XObject, Subtype: :Form}).canvas
|
540
|
+
@canvas = HexaPDF::Document.new.add({Type: :XObject, Subtype: :Form, BBox: [0, 0, 1, 1]}).canvas
|
541
541
|
assert_nil(call_link(dest: true))
|
542
542
|
end
|
543
543
|
|
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.12.
|
43
|
+
<</Producer(HexaPDF version 0.12.2)>>
|
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.12.
|
75
|
+
<</Producer(HexaPDF version 0.12.2)>>
|
76
76
|
endobj
|
77
77
|
2 0 obj
|
78
78
|
<</Length 10>>stream
|
@@ -82,9 +82,27 @@ describe HexaPDF::Type::Form do
|
|
82
82
|
end
|
83
83
|
|
84
84
|
describe "canvas" do
|
85
|
+
# Asserts that the form's contents contains the operators.
|
86
|
+
def assert_operators(form, operators)
|
87
|
+
processor = TestHelper::OperatorRecorder.new
|
88
|
+
form.process_contents(processor)
|
89
|
+
assert_equal(operators, processor.recorded_ops)
|
90
|
+
end
|
91
|
+
|
85
92
|
it "always returns the same Canvas instance" do
|
93
|
+
@form[:BBox] = [0, 0, 100, 100]
|
86
94
|
canvas = @form.canvas
|
87
95
|
assert_same(canvas, @form.canvas)
|
96
|
+
assert_operators(@form, [])
|
97
|
+
end
|
98
|
+
|
99
|
+
it "always moves the origin to the bottom left corner of the bounding box" do
|
100
|
+
@form[:BBox] = [-10, -5, 100, 300]
|
101
|
+
@form.canvas.line_width = 5
|
102
|
+
assert_operators(@form, [[:save_graphics_state],
|
103
|
+
[:concatenate_matrix, [1, 0, 0, 1, -10, -5]],
|
104
|
+
[:set_line_width, [5]],
|
105
|
+
[:restore_graphics_state]])
|
88
106
|
end
|
89
107
|
|
90
108
|
it "fails if the form XObject already has data" do
|
@@ -331,31 +331,36 @@ describe HexaPDF::Type::Page do
|
|
331
331
|
@page.canvas(type: :overlay).line_width = 5
|
332
332
|
assert_operators(@page, [[:save_graphics_state], [:restore_graphics_state],
|
333
333
|
[:save_graphics_state], [:set_line_width, [10]],
|
334
|
-
[:restore_graphics_state], [:
|
334
|
+
[:restore_graphics_state], [:save_graphics_state],
|
335
|
+
[:set_line_width, [5]], [:restore_graphics_state]])
|
335
336
|
|
336
337
|
@page.canvas(type: :underlay).line_width = 2
|
337
338
|
assert_operators(@page, [[:save_graphics_state], [:set_line_width, [2]],
|
338
339
|
[:restore_graphics_state], [:save_graphics_state],
|
339
340
|
[:set_line_width, [10]],
|
340
|
-
[:restore_graphics_state], [:
|
341
|
+
[:restore_graphics_state], [:save_graphics_state],
|
342
|
+
[:set_line_width, [5]], [:restore_graphics_state]])
|
341
343
|
end
|
342
344
|
|
343
345
|
it "works correctly if invoked on an empty page, using type :underlay in first invocation" do
|
344
346
|
@page.canvas(type: :underlay).line_width = 2
|
345
347
|
assert_operators(@page, [[:save_graphics_state], [:set_line_width, [2]],
|
348
|
+
[:restore_graphics_state], [:save_graphics_state],
|
346
349
|
[:restore_graphics_state], [:save_graphics_state],
|
347
350
|
[:restore_graphics_state]])
|
348
351
|
|
349
352
|
@page.canvas.line_width = 10
|
350
353
|
assert_operators(@page, [[:save_graphics_state], [:set_line_width, [2]],
|
351
354
|
[:restore_graphics_state], [:save_graphics_state],
|
352
|
-
[:set_line_width, [10]], [:restore_graphics_state]
|
355
|
+
[:set_line_width, [10]], [:restore_graphics_state],
|
356
|
+
[:save_graphics_state], [:restore_graphics_state]])
|
353
357
|
|
354
358
|
@page.canvas(type: :overlay).line_width = 5
|
355
359
|
assert_operators(@page, [[:save_graphics_state], [:set_line_width, [2]],
|
356
360
|
[:restore_graphics_state], [:save_graphics_state],
|
357
361
|
[:set_line_width, [10]],
|
358
|
-
[:restore_graphics_state], [:
|
362
|
+
[:restore_graphics_state], [:save_graphics_state],
|
363
|
+
[:set_line_width, [5]], [:restore_graphics_state]])
|
359
364
|
end
|
360
365
|
|
361
366
|
it "works correctly if invoked on a page with existing contents" do
|
@@ -364,13 +369,39 @@ describe HexaPDF::Type::Page do
|
|
364
369
|
@page.canvas(type: :overlay).line_width = 5
|
365
370
|
assert_operators(@page, [[:save_graphics_state], [:restore_graphics_state],
|
366
371
|
[:save_graphics_state], [:set_line_width, [10]],
|
367
|
-
[:restore_graphics_state],
|
372
|
+
[:restore_graphics_state],
|
373
|
+
[:save_graphics_state], [:set_line_width, [5]],
|
374
|
+
[:restore_graphics_state]])
|
368
375
|
|
369
376
|
@page.canvas(type: :underlay).line_width = 2
|
370
377
|
assert_operators(@page, [[:save_graphics_state], [:set_line_width, [2]],
|
371
378
|
[:restore_graphics_state], [:save_graphics_state],
|
372
379
|
[:set_line_width, [10]],
|
373
|
-
[:restore_graphics_state],
|
380
|
+
[:restore_graphics_state],
|
381
|
+
[:save_graphics_state], [:set_line_width, [5]],
|
382
|
+
[:restore_graphics_state]])
|
383
|
+
end
|
384
|
+
|
385
|
+
it "works correctly if the page has its origin not at (0,0)" do
|
386
|
+
@page.box(:media, [-10, -5, 100, 300])
|
387
|
+
@page.canvas(type: :underlay).line_width = 2
|
388
|
+
@page.canvas(type: :page).line_width = 2
|
389
|
+
@page.canvas(type: :overlay).line_width = 2
|
390
|
+
|
391
|
+
assert_operators(@page, [[:save_graphics_state],
|
392
|
+
[:concatenate_matrix, [1, 0, 0, 1, -10, -5]],
|
393
|
+
[:set_line_width, [2]],
|
394
|
+
[:restore_graphics_state],
|
395
|
+
|
396
|
+
[:save_graphics_state],
|
397
|
+
[:concatenate_matrix, [1, 0, 0, 1, -10, -5]],
|
398
|
+
[:set_line_width, [2]],
|
399
|
+
[:restore_graphics_state],
|
400
|
+
|
401
|
+
[:save_graphics_state],
|
402
|
+
[:concatenate_matrix, [1, 0, 0, 1, -10, -5]],
|
403
|
+
[:set_line_width, [2]],
|
404
|
+
[:restore_graphics_state]])
|
374
405
|
end
|
375
406
|
|
376
407
|
it "fails if the page canvas is requested for a page with existing contents" do
|
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.12.
|
4
|
+
version: 0.12.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Leitner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-08-
|
11
|
+
date: 2020-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cmdparse
|
@@ -653,7 +653,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
653
653
|
- !ruby/object:Gem::Version
|
654
654
|
version: '0'
|
655
655
|
requirements: []
|
656
|
-
|
656
|
+
rubyforge_project:
|
657
|
+
rubygems_version: 2.7.6.2
|
657
658
|
signing_key:
|
658
659
|
specification_version: 4
|
659
660
|
summary: HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|