hexapdf 0.12.1 → 0.12.2
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 +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
|