pdf-core 0.4.0 → 0.10.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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data/lib/pdf/core/annotations.rb +58 -21
- data/lib/pdf/core/byte_string.rb +6 -3
- data/lib/pdf/core/destinations.rb +77 -34
- data/lib/pdf/core/document_state.rb +121 -30
- data/lib/pdf/core/filter_list.rb +47 -6
- data/lib/pdf/core/filters.rb +31 -12
- data/lib/pdf/core/graphics_state.rb +80 -32
- data/lib/pdf/core/literal_string.rb +11 -10
- data/lib/pdf/core/name_tree.rb +118 -54
- data/lib/pdf/core/object_store.rb +82 -37
- data/lib/pdf/core/outline_item.rb +62 -7
- data/lib/pdf/core/outline_root.rb +21 -3
- data/lib/pdf/core/page.rb +232 -77
- data/lib/pdf/core/page_geometry.rb +56 -112
- data/lib/pdf/core/pdf_object.rb +93 -57
- data/lib/pdf/core/reference.rb +70 -30
- data/lib/pdf/core/renderer.rb +149 -68
- data/lib/pdf/core/stream.rb +48 -12
- data/lib/pdf/core/text.rb +300 -106
- data/lib/pdf/core/utils.rb +21 -0
- data/lib/pdf/core.rb +38 -25
- data/pdf-core.gemspec +43 -24
- data.tar.gz.sig +0 -0
- metadata +56 -64
- metadata.gz.sig +2 -0
- data/Gemfile +0 -3
- data/Rakefile +0 -11
- data/spec/filters_spec.rb +0 -34
- data/spec/name_tree_spec.rb +0 -122
- data/spec/object_store_spec.rb +0 -49
- data/spec/pdf_object_spec.rb +0 -172
- data/spec/reference_spec.rb +0 -62
- data/spec/spec_helper.rb +0 -32
- data/spec/stream_spec.rb +0 -59
data/pdf-core.gemspec
CHANGED
|
@@ -1,29 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
Gem::Specification.new do |spec|
|
|
2
|
-
spec.name =
|
|
3
|
-
spec.version =
|
|
4
|
+
spec.name = 'pdf-core'
|
|
5
|
+
spec.version = '0.10.0'
|
|
4
6
|
spec.platform = Gem::Platform::RUBY
|
|
5
|
-
spec.summary =
|
|
6
|
-
spec.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
spec.
|
|
12
|
-
spec.
|
|
7
|
+
spec.summary = 'Low level PDF generator.'
|
|
8
|
+
spec.description = 'PDF::Core is used by Prawn to render PDF documents. It provides low-level format support.'
|
|
9
|
+
spec.files =
|
|
10
|
+
Dir.glob('lib/**/**/*') +
|
|
11
|
+
%w[COPYING GPLv2 GPLv3 LICENSE] +
|
|
12
|
+
['pdf-core.gemspec']
|
|
13
|
+
spec.require_path = 'lib'
|
|
14
|
+
spec.required_ruby_version = '>= 2.7'
|
|
15
|
+
spec.required_rubygems_version = '>= 1.3.6'
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
if File.basename($PROGRAM_NAME) == 'gem' && ARGV.include?('build')
|
|
18
|
+
signing_key = File.expand_path('~/.gem/gem-private_key.pem')
|
|
19
|
+
if File.exist?(signing_key)
|
|
20
|
+
spec.cert_chain = ['certs/pointlessone.pem']
|
|
21
|
+
spec.signing_key = signing_key
|
|
22
|
+
else
|
|
23
|
+
warn 'WARNING: Signing key is missing. The gem is not signed and its authenticity can not be verified.'
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
spec.authors = [
|
|
28
|
+
'Alexander Mankuta', 'Gregory Brown', 'Brad Ediger', 'Daniel Nelson',
|
|
29
|
+
'Jonathan Greenberg', 'James Healy',
|
|
30
|
+
]
|
|
31
|
+
spec.email = [
|
|
32
|
+
'alex@pointless.one', 'gregory.t.brown@gmail.com', 'brad@bradediger.com',
|
|
33
|
+
'dnelson@bluejade.com', 'greenberg@entryway.net', 'jimmy@deefa.com',
|
|
34
|
+
]
|
|
35
|
+
spec.licenses = %w[Nonstandard GPL-2.0-only GPL-3.0-only]
|
|
36
|
+
spec.homepage = 'http://prawnpdf.org/'
|
|
37
|
+
spec.metadata = {
|
|
38
|
+
'rubygems_mfa_required' => 'true',
|
|
39
|
+
'homepage_uri' => spec.homepage,
|
|
40
|
+
'changelog_uri' => "https://github.com/prawnpdf/pdf-core/blob/#{spec.version}/CHANGELOG.md",
|
|
41
|
+
'source_code_uri' => 'https://github.com/prawnpdf/pdf-core',
|
|
42
|
+
'documentation_uri' => "https://prawnpdf.org/docs/pdf-core/#{spec.version}/",
|
|
43
|
+
'bug_tracker_uri' => 'https://github.com/prawnpdf/pdf-core/issues',
|
|
44
|
+
}
|
|
24
45
|
spec.add_development_dependency('pdf-inspector', '~> 1.1.0')
|
|
25
|
-
spec.add_development_dependency('
|
|
26
|
-
spec.add_development_dependency('
|
|
27
|
-
spec.homepage = "http://prawn.majesticseacreature.com"
|
|
28
|
-
spec.description = "PDF::Core is used by Prawn to render PDF documents"
|
|
46
|
+
spec.add_development_dependency('pdf-reader', '~>1.2')
|
|
47
|
+
spec.add_development_dependency('prawn-dev', '~> 0.4.0')
|
|
29
48
|
end
|
data.tar.gz.sig
ADDED
|
Binary file
|
metadata
CHANGED
|
@@ -1,47 +1,41 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pdf-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
+
- Alexander Mankuta
|
|
7
8
|
- Gregory Brown
|
|
8
9
|
- Brad Ediger
|
|
9
10
|
- Daniel Nelson
|
|
10
11
|
- Jonathan Greenberg
|
|
11
12
|
- James Healy
|
|
12
|
-
autorequire:
|
|
13
|
+
autorequire:
|
|
13
14
|
bindir: bin
|
|
14
|
-
cert_chain:
|
|
15
|
-
|
|
15
|
+
cert_chain:
|
|
16
|
+
- |
|
|
17
|
+
-----BEGIN CERTIFICATE-----
|
|
18
|
+
MIIDMjCCAhqgAwIBAgIBAjANBgkqhkiG9w0BAQsFADA/MQ0wCwYDVQQDDARhbGV4
|
|
19
|
+
MRkwFwYKCZImiZPyLGQBGRYJcG9pbnRsZXNzMRMwEQYKCZImiZPyLGQBGRYDb25l
|
|
20
|
+
MB4XDTIzMTIxMjE0Mzc0MFoXDTI0MTIxMTE0Mzc0MFowPzENMAsGA1UEAwwEYWxl
|
|
21
|
+
eDEZMBcGCgmSJomT8ixkARkWCXBvaW50bGVzczETMBEGCgmSJomT8ixkARkWA29u
|
|
22
|
+
ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM85Us8YQr55o/rMl+J+
|
|
23
|
+
ula89ODiqjdc0kk+ibzRLCpfaFUJWxEMrhFiApRCopFDMeGXHXjBkfBYsRMFVs0M
|
|
24
|
+
Zfe6rIKdNZQlQqHfJ2JlKFek0ehX81buGERi82wNwECNhOZu9c6G5gKjRPP/Q3Y6
|
|
25
|
+
K6f/TAggK0+/K1j1NjT+WSVaMBuyomM067ejwhiQkEA3+tT3oT/paEXCOfEtxOdX
|
|
26
|
+
1F8VFd2MbmMK6CGgHbFLApfyDBtDx+ydplGZ3IMZg2nPqwYXTPJx+IuRO21ssDad
|
|
27
|
+
gBMIAvL3wIeezJk2xONvhYg0K5jbIQOPB6zD1/9E6Q0LrwSBDkz5oyOn4PRZxgZ/
|
|
28
|
+
OiMCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFE+A
|
|
29
|
+
jBJVt6ie5r83L/znvqjF1RuuMA0GCSqGSIb3DQEBCwUAA4IBAQCwy1p9OUw97QBi
|
|
30
|
+
A4mp0YFfPx76ZAuBBy//POnstDu5tBPpaiE2pOC4Hr8d23QhQhi7TNHMhFbbviLN
|
|
31
|
+
3PSD95fgZ5ZYiZWNUV5Z7IeDhpH3rWE070SH3PYfDKnzKewBn4KBLg2fGKm1HqsO
|
|
32
|
+
UqvUp1HP0VdAUHTf3JsOaYg24GIN8f4Q6rIekG6C6z/MLkVLPHjh57y4jfdJkFMP
|
|
33
|
+
LrBc0vY9enBMXykQjvnq1R4lD+2RkaAE2KwrjIPtPQR1mo9hPJvjWhvM+th1pk6E
|
|
34
|
+
j+VZOY/0o89hstamSTBkvSK+kX7LhSX7ELlldyjQqPR1ZMmnznv2+1mVl733TfRl
|
|
35
|
+
G3y/80js
|
|
36
|
+
-----END CERTIFICATE-----
|
|
37
|
+
date: 2024-03-05 00:00:00.000000000 Z
|
|
16
38
|
dependencies:
|
|
17
|
-
- !ruby/object:Gem::Dependency
|
|
18
|
-
name: pdf-reader
|
|
19
|
-
requirement: !ruby/object:Gem::Requirement
|
|
20
|
-
requirements:
|
|
21
|
-
- - "~>"
|
|
22
|
-
- !ruby/object:Gem::Version
|
|
23
|
-
version: '1.2'
|
|
24
|
-
type: :development
|
|
25
|
-
prerelease: false
|
|
26
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
27
|
-
requirements:
|
|
28
|
-
- - "~>"
|
|
29
|
-
- !ruby/object:Gem::Version
|
|
30
|
-
version: '1.2'
|
|
31
|
-
- !ruby/object:Gem::Dependency
|
|
32
|
-
name: simplecov
|
|
33
|
-
requirement: !ruby/object:Gem::Requirement
|
|
34
|
-
requirements:
|
|
35
|
-
- - ">="
|
|
36
|
-
- !ruby/object:Gem::Version
|
|
37
|
-
version: '0'
|
|
38
|
-
type: :development
|
|
39
|
-
prerelease: false
|
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
-
requirements:
|
|
42
|
-
- - ">="
|
|
43
|
-
- !ruby/object:Gem::Version
|
|
44
|
-
version: '0'
|
|
45
39
|
- !ruby/object:Gem::Dependency
|
|
46
40
|
name: pdf-inspector
|
|
47
41
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -57,35 +51,37 @@ dependencies:
|
|
|
57
51
|
- !ruby/object:Gem::Version
|
|
58
52
|
version: 1.1.0
|
|
59
53
|
- !ruby/object:Gem::Dependency
|
|
60
|
-
name:
|
|
54
|
+
name: pdf-reader
|
|
61
55
|
requirement: !ruby/object:Gem::Requirement
|
|
62
56
|
requirements:
|
|
63
|
-
- - "
|
|
57
|
+
- - "~>"
|
|
64
58
|
- !ruby/object:Gem::Version
|
|
65
|
-
version: '
|
|
59
|
+
version: '1.2'
|
|
66
60
|
type: :development
|
|
67
61
|
prerelease: false
|
|
68
62
|
version_requirements: !ruby/object:Gem::Requirement
|
|
69
63
|
requirements:
|
|
70
|
-
- - "
|
|
64
|
+
- - "~>"
|
|
71
65
|
- !ruby/object:Gem::Version
|
|
72
|
-
version: '
|
|
66
|
+
version: '1.2'
|
|
73
67
|
- !ruby/object:Gem::Dependency
|
|
74
|
-
name:
|
|
68
|
+
name: prawn-dev
|
|
75
69
|
requirement: !ruby/object:Gem::Requirement
|
|
76
70
|
requirements:
|
|
77
|
-
- - "
|
|
71
|
+
- - "~>"
|
|
78
72
|
- !ruby/object:Gem::Version
|
|
79
|
-
version:
|
|
73
|
+
version: 0.4.0
|
|
80
74
|
type: :development
|
|
81
75
|
prerelease: false
|
|
82
76
|
version_requirements: !ruby/object:Gem::Requirement
|
|
83
77
|
requirements:
|
|
84
|
-
- - "
|
|
78
|
+
- - "~>"
|
|
85
79
|
- !ruby/object:Gem::Version
|
|
86
|
-
version:
|
|
87
|
-
description: PDF::Core is used by Prawn to render PDF documents
|
|
80
|
+
version: 0.4.0
|
|
81
|
+
description: PDF::Core is used by Prawn to render PDF documents. It provides low-level
|
|
82
|
+
format support.
|
|
88
83
|
email:
|
|
84
|
+
- alex@pointless.one
|
|
89
85
|
- gregory.t.brown@gmail.com
|
|
90
86
|
- brad@bradediger.com
|
|
91
87
|
- dnelson@bluejade.com
|
|
@@ -98,9 +94,7 @@ files:
|
|
|
98
94
|
- COPYING
|
|
99
95
|
- GPLv2
|
|
100
96
|
- GPLv3
|
|
101
|
-
- Gemfile
|
|
102
97
|
- LICENSE
|
|
103
|
-
- Rakefile
|
|
104
98
|
- lib/pdf/core.rb
|
|
105
99
|
- lib/pdf/core/annotations.rb
|
|
106
100
|
- lib/pdf/core/byte_string.rb
|
|
@@ -121,21 +115,21 @@ files:
|
|
|
121
115
|
- lib/pdf/core/renderer.rb
|
|
122
116
|
- lib/pdf/core/stream.rb
|
|
123
117
|
- lib/pdf/core/text.rb
|
|
118
|
+
- lib/pdf/core/utils.rb
|
|
124
119
|
- pdf-core.gemspec
|
|
125
|
-
|
|
126
|
-
- spec/name_tree_spec.rb
|
|
127
|
-
- spec/object_store_spec.rb
|
|
128
|
-
- spec/pdf_object_spec.rb
|
|
129
|
-
- spec/reference_spec.rb
|
|
130
|
-
- spec/spec_helper.rb
|
|
131
|
-
- spec/stream_spec.rb
|
|
132
|
-
homepage: http://prawn.majesticseacreature.com
|
|
120
|
+
homepage: http://prawnpdf.org/
|
|
133
121
|
licenses:
|
|
134
|
-
-
|
|
135
|
-
- GPL-2
|
|
136
|
-
- GPL-3
|
|
137
|
-
metadata:
|
|
138
|
-
|
|
122
|
+
- Nonstandard
|
|
123
|
+
- GPL-2.0-only
|
|
124
|
+
- GPL-3.0-only
|
|
125
|
+
metadata:
|
|
126
|
+
rubygems_mfa_required: 'true'
|
|
127
|
+
homepage_uri: http://prawnpdf.org/
|
|
128
|
+
changelog_uri: https://github.com/prawnpdf/pdf-core/blob/0.10.0/CHANGELOG.md
|
|
129
|
+
source_code_uri: https://github.com/prawnpdf/pdf-core
|
|
130
|
+
documentation_uri: https://prawnpdf.org/docs/pdf-core/0.10.0/
|
|
131
|
+
bug_tracker_uri: https://github.com/prawnpdf/pdf-core/issues
|
|
132
|
+
post_install_message:
|
|
139
133
|
rdoc_options: []
|
|
140
134
|
require_paths:
|
|
141
135
|
- lib
|
|
@@ -143,17 +137,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
143
137
|
requirements:
|
|
144
138
|
- - ">="
|
|
145
139
|
- !ruby/object:Gem::Version
|
|
146
|
-
version:
|
|
140
|
+
version: '2.7'
|
|
147
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
142
|
requirements:
|
|
149
143
|
- - ">="
|
|
150
144
|
- !ruby/object:Gem::Version
|
|
151
145
|
version: 1.3.6
|
|
152
146
|
requirements: []
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
signing_key:
|
|
147
|
+
rubygems_version: 3.5.3
|
|
148
|
+
signing_key:
|
|
156
149
|
specification_version: 4
|
|
157
|
-
summary:
|
|
150
|
+
summary: Low level PDF generator.
|
|
158
151
|
test_files: []
|
|
159
|
-
has_rdoc:
|
metadata.gz.sig
ADDED
data/Gemfile
DELETED
data/Rakefile
DELETED
data/spec/filters_spec.rb
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require_relative "spec_helper"
|
|
4
|
-
|
|
5
|
-
FILTERS = {
|
|
6
|
-
:FlateDecode => {'test' => "x\x9C+I-.\x01\x00\x04]\x01\xC1".force_encoding(Encoding::ASCII_8BIT) },
|
|
7
|
-
:DCTDecode => {'test' => "test"}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
FILTERS.each do |filter_name, examples|
|
|
11
|
-
filter = PDF::Core::Filters.const_get(filter_name)
|
|
12
|
-
|
|
13
|
-
describe "#{filter_name} filter" do
|
|
14
|
-
it "should encode stream" do
|
|
15
|
-
examples.each do |in_stream, out_stream|
|
|
16
|
-
filter.encode(in_stream).should == out_stream
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "should decode stream" do
|
|
21
|
-
examples.each do |in_stream, out_stream|
|
|
22
|
-
filter.decode(out_stream).should == in_stream
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it "should be symmetric" do
|
|
27
|
-
examples.each do |in_stream, out_stream|
|
|
28
|
-
filter.decode(filter.encode(in_stream)).should == in_stream
|
|
29
|
-
|
|
30
|
-
filter.encode(filter.decode(out_stream)).should == out_stream
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
data/spec/name_tree_spec.rb
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
require_relative "spec_helper"
|
|
2
|
-
|
|
3
|
-
def tree_dump(tree)
|
|
4
|
-
if tree.is_a?(PDF::Core::NameTree::Node)
|
|
5
|
-
"[" + tree.children.map { |child| tree_dump(child) }.join(",") + "]"
|
|
6
|
-
else
|
|
7
|
-
"#{tree.name}=#{tree.value}"
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def tree_add(tree, *args)
|
|
12
|
-
args.each do |(name, value)|
|
|
13
|
-
tree.add(name, value)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def tree_value(name, value)
|
|
18
|
-
PDF::Core::NameTree::Value.new(name, value)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# FIXME: This is a dummy that's meant to stand in for a Prawn::Document.
|
|
22
|
-
# It causes the tests to pass but I have no idea if it's really a
|
|
23
|
-
# sufficient test double or not.
|
|
24
|
-
class RefExposingDocument
|
|
25
|
-
def initialize
|
|
26
|
-
@object_store = []
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
attr_reader :object_store
|
|
30
|
-
|
|
31
|
-
def ref!(obj)
|
|
32
|
-
@object_store << obj
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
describe "Name Tree" do
|
|
37
|
-
before(:each) { @pdf = RefExposingDocument.new }
|
|
38
|
-
|
|
39
|
-
it "should have no children when first initialized" do
|
|
40
|
-
node = PDF::Core::NameTree::Node.new(@pdf, 3)
|
|
41
|
-
node.children.length.should == 0
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "should have no subtrees while child limit is not reached" do
|
|
45
|
-
node = PDF::Core::NameTree::Node.new(@pdf, 3)
|
|
46
|
-
tree_add(node, ["one", 1], ["two", 2], ["three", 3])
|
|
47
|
-
tree_dump(node).should == "[one=1,three=3,two=2]"
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it "should split into subtrees when limit is exceeded" do
|
|
51
|
-
node = PDF::Core::NameTree::Node.new(@pdf, 3)
|
|
52
|
-
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
|
|
53
|
-
tree_dump(node).should == "[[four=4,one=1],[three=3,two=2]]"
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it "should create a two new references when root is split" do
|
|
57
|
-
ref_count = @pdf.object_store.length
|
|
58
|
-
node = PDF::Core::NameTree::Node.new(@pdf, 3)
|
|
59
|
-
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
|
|
60
|
-
@pdf.object_store.length.should == ref_count+2
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
it "should create a one new reference when subtree is split" do
|
|
64
|
-
node = PDF::Core::NameTree::Node.new(@pdf, 3)
|
|
65
|
-
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
|
|
66
|
-
|
|
67
|
-
ref_count = @pdf.object_store.length # save when root is split
|
|
68
|
-
tree_add(node, ["five", 5], ["six", 6], ["seven", 7])
|
|
69
|
-
tree_dump(node).should == "[[five=5,four=4,one=1],[seven=7,six=6],[three=3,two=2]]"
|
|
70
|
-
@pdf.object_store.length.should == ref_count+1
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
it "should keep tree balanced when subtree split cascades to root" do
|
|
74
|
-
node = PDF::Core::NameTree::Node.new(@pdf, 3)
|
|
75
|
-
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
|
|
76
|
-
tree_add(node, ["five", 5], ["six", 6], ["seven", 7], ["eight", 8])
|
|
77
|
-
tree_dump(node).should == "[[[eight=8,five=5],[four=4,one=1]],[[seven=7,six=6],[three=3,two=2]]]"
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
it "should maintain order of already properly ordered nodes" do
|
|
81
|
-
node = PDF::Core::NameTree::Node.new(@pdf, 3)
|
|
82
|
-
tree_add(node, ["eight", 8], ["five", 5], ["four", 4], ["one", 1])
|
|
83
|
-
tree_add(node, ['seven', 7], ['six', 6], ['three', 3], ['two', 2])
|
|
84
|
-
tree_dump(node).should == "[[[eight=8,five=5],[four=4,one=1]],[[seven=7,six=6],[three=3,two=2]]]"
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
it "should emit only :Names key with to_hash if root is only node" do
|
|
88
|
-
node = PDF::Core::NameTree::Node.new(@pdf, 3)
|
|
89
|
-
tree_add(node, ["one", 1], ["two", 2], ["three", 3])
|
|
90
|
-
node.to_hash.should ==(
|
|
91
|
-
{ :Names => [tree_value("one", 1), tree_value("three", 3), tree_value("two", 2)] }
|
|
92
|
-
)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
it "should emit only :Kids key with to_hash if root has children" do
|
|
96
|
-
node = PDF::Core::NameTree::Node.new(@pdf, 3)
|
|
97
|
-
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
|
|
98
|
-
node.to_hash.should ==({ :Kids => node.children.map { |child| child.ref } })
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
it "should emit :Limits and :Names keys with to_hash for leaf node" do
|
|
102
|
-
node = PDF::Core::NameTree::Node.new(@pdf, 3)
|
|
103
|
-
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
|
|
104
|
-
node.children.first.to_hash.should ==(
|
|
105
|
-
{ :Limits => %w(four one),
|
|
106
|
-
:Names => [tree_value("four", 4), tree_value("one", 1)] }
|
|
107
|
-
)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
it "should emit :Limits and :Kids keys with to_hash for inner node" do
|
|
111
|
-
node = PDF::Core::NameTree::Node.new(@pdf, 3)
|
|
112
|
-
tree_add(node, ["one", 1], ["two", 2], ["three", 3], ["four", 4])
|
|
113
|
-
tree_add(node, ["five", 5], ["six", 6], ["seven", 7], ["eight", 8])
|
|
114
|
-
tree_add(node, ["nine", 9], ["ten", 10], ["eleven", 11], ["twelve", 12])
|
|
115
|
-
tree_add(node, ["thirteen", 13], ["fourteen", 14], ["fifteen", 15], ["sixteen", 16])
|
|
116
|
-
node.children.first.to_hash.should ==(
|
|
117
|
-
{ :Limits => %w(eight one),
|
|
118
|
-
:Kids => node.children.first.children.map { |child| child.ref } }
|
|
119
|
-
)
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
data/spec/object_store_spec.rb
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require_relative "spec_helper"
|
|
4
|
-
|
|
5
|
-
describe "PDF::Core::ObjectStore" do
|
|
6
|
-
before(:each) do
|
|
7
|
-
@store = PDF::Core::ObjectStore.new
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it "should create required roots by default, including info passed to new" do
|
|
11
|
-
store = PDF::Core::ObjectStore.new(:info => {:Test => 3})
|
|
12
|
-
store.size.should == 3 # 3 default roots
|
|
13
|
-
store.info.data[:Test].should == 3
|
|
14
|
-
store.pages.data[:Count].should == 0
|
|
15
|
-
store.root.data[:Pages].should == store.pages
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
it "should add to its objects when ref() is called" do
|
|
20
|
-
count = @store.size
|
|
21
|
-
@store.ref("blah")
|
|
22
|
-
@store.size.should == count + 1
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it "should accept push with a Prawn::Reference" do
|
|
26
|
-
r = PDF::Core::Reference(123, "blah")
|
|
27
|
-
@store.push(r)
|
|
28
|
-
@store[r.identifier].should == r
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it "should accept arbitrary data and use it to create a Prawn::Reference" do
|
|
32
|
-
@store.push(123, "blahblah")
|
|
33
|
-
@store[123].data.should == "blahblah"
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it "should be Enumerable, yielding in order of submission" do
|
|
37
|
-
# higher IDs to bypass the default roots
|
|
38
|
-
[10, 11, 12].each do |id|
|
|
39
|
-
@store.push(id, "some data #{id}")
|
|
40
|
-
end
|
|
41
|
-
@store.map{|ref| ref.identifier}[-3..-1].should == [10, 11, 12]
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "should accept option to disabling PDF scaling in PDF clients" do
|
|
45
|
-
@store = PDF::Core::ObjectStore.new(:print_scaling => :none)
|
|
46
|
-
@store.root.data[:ViewerPreferences].should == {:PrintScaling => :None}
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
end
|
data/spec/pdf_object_spec.rb
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
# encoding: ASCII-8BIT
|
|
2
|
-
require_relative "spec_helper"
|
|
3
|
-
|
|
4
|
-
# See PDF Reference, Sixth Edition (1.7) pp51-60 for details
|
|
5
|
-
describe "PDF Object Serialization" do
|
|
6
|
-
|
|
7
|
-
it "should convert Ruby's nil to PDF null" do
|
|
8
|
-
PDF::Core::PdfObject(nil).should == "null"
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
it "should convert Ruby booleans to PDF booleans" do
|
|
12
|
-
PDF::Core::PdfObject(true).should == "true"
|
|
13
|
-
PDF::Core::PdfObject(false).should == "false"
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it "should convert a Ruby number to PDF number" do
|
|
17
|
-
PDF::Core::PdfObject(1).should == "1"
|
|
18
|
-
PDF::Core::PdfObject(1.214112421).should == "1.214112421"
|
|
19
|
-
# scientific notation is not valid in PDF
|
|
20
|
-
PDF::Core::PdfObject(0.000005).should == "0.000005"
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "should convert a Ruby time object to a PDF timestamp" do
|
|
24
|
-
t = Time.now
|
|
25
|
-
PDF::Core::PdfObject(t).should == t.strftime("(D:%Y%m%d%H%M%S%z").chop.chop + "'00')"
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it "should convert a Ruby string to PDF string when inside a content stream" do
|
|
29
|
-
s = "I can has a string"
|
|
30
|
-
PDF::Inspector.parse(PDF::Core::PdfObject(s, true)).should == s
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it "should convert a Ruby string to a UTF-16 PDF string when outside a content stream" do
|
|
34
|
-
s = "I can has a string"
|
|
35
|
-
s_utf16 = "\xFE\xFF" + s.unpack("U*").pack("n*")
|
|
36
|
-
PDF::Inspector.parse(PDF::Core::PdfObject(s, false)).should == s_utf16
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
it "should convert a Ruby string with characters outside the BMP to its " +
|
|
40
|
-
"UTF-16 representation with a BOM" do
|
|
41
|
-
# U+10192 ROMAN SEMUNCIA SIGN
|
|
42
|
-
semuncia = [65938].pack("U")
|
|
43
|
-
PDF::Core::PdfObject(semuncia, false).upcase.should == "<FEFFD800DD92>"
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it "should pass through bytes regardless of content stream status for ByteString" do
|
|
47
|
-
PDF::Core::PdfObject(PDF::Core::ByteString.new("\xDE\xAD\xBE\xEF")).upcase.
|
|
48
|
-
should == "<DEADBEEF>"
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
it "should escape parens when converting from Ruby string to PDF" do
|
|
52
|
-
s = 'I )(can has a string'
|
|
53
|
-
PDF::Inspector.parse(PDF::Core::PdfObject(s, true)).should == s
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it "should handle ruby escaped parens when converting to PDF string" do
|
|
57
|
-
s = 'I can \\)( has string'
|
|
58
|
-
PDF::Inspector.parse(PDF::Core::PdfObject(s, true)).should == s
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it "should escape various strings correctly when converting a LiteralString" do
|
|
62
|
-
ls = PDF::Core::LiteralString.new("abc")
|
|
63
|
-
PDF::Core::PdfObject(ls).should == "(abc)"
|
|
64
|
-
|
|
65
|
-
ls = PDF::Core::LiteralString.new("abc\x0Ade") # should escape \n
|
|
66
|
-
PDF::Core::PdfObject(ls).should == "(abc\x5C\x0Ade)"
|
|
67
|
-
|
|
68
|
-
ls = PDF::Core::LiteralString.new("abc\x0Dde") # should escape \r
|
|
69
|
-
PDF::Core::PdfObject(ls).should == "(abc\x5C\x0Dde)"
|
|
70
|
-
|
|
71
|
-
ls = PDF::Core::LiteralString.new("abc\x09de") # should escape \t
|
|
72
|
-
PDF::Core::PdfObject(ls).should == "(abc\x5C\x09de)"
|
|
73
|
-
|
|
74
|
-
ls = PDF::Core::LiteralString.new("abc\x08de") # should escape \b
|
|
75
|
-
PDF::Core::PdfObject(ls).should == "(abc\x5C\x08de)"
|
|
76
|
-
|
|
77
|
-
ls = PDF::Core::LiteralString.new("abc\x0Cde") # should escape \f
|
|
78
|
-
PDF::Core::PdfObject(ls).should == "(abc\x5C\x0Cde)"
|
|
79
|
-
|
|
80
|
-
ls = PDF::Core::LiteralString.new("abc(de") # should escape \(
|
|
81
|
-
PDF::Core::PdfObject(ls).should == "(abc\x5C(de)"
|
|
82
|
-
|
|
83
|
-
ls = PDF::Core::LiteralString.new("abc)de") # should escape \)
|
|
84
|
-
PDF::Core::PdfObject(ls).should == "(abc\x5C)de)"
|
|
85
|
-
|
|
86
|
-
ls = PDF::Core::LiteralString.new("abc\x5Cde") # should escape \\
|
|
87
|
-
PDF::Core::PdfObject(ls).should == "(abc\x5C\x5Cde)"
|
|
88
|
-
PDF::Core::PdfObject(ls).size.should == 9
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
it "should escape strings correctly when converting a LiteralString that is not utf-8" do
|
|
92
|
-
data = "\x43\xaf\xc9\x7f\xef\xf\xe6\xa8\xcb\x5c\xaf\xd0"
|
|
93
|
-
ls = PDF::Core::LiteralString.new(data)
|
|
94
|
-
PDF::Core::PdfObject(ls).should == "(\x43\xaf\xc9\x7f\xef\xf\xe6\xa8\xcb\x5c\x5c\xaf\xd0)"
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
it "should convert a Ruby symbol to PDF name" do
|
|
98
|
-
PDF::Core::PdfObject(:my_symbol).should == "/my_symbol"
|
|
99
|
-
PDF::Core::PdfObject(:"A;Name_With-Various***Characters?").should ==
|
|
100
|
-
"/A;Name_With-Various***Characters?"
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
it "should convert a whitespace or delimiter containing Ruby symbol to a PDF name" do
|
|
104
|
-
PDF::Core::PdfObject(:"my symbol").should == "/my#20symbol"
|
|
105
|
-
PDF::Core::PdfObject(:"my#symbol").should == "/my#23symbol"
|
|
106
|
-
PDF::Core::PdfObject(:"my/symbol").should == "/my#2Fsymbol"
|
|
107
|
-
PDF::Core::PdfObject(:"my(symbol").should == "/my#28symbol"
|
|
108
|
-
PDF::Core::PdfObject(:"my)symbol").should == "/my#29symbol"
|
|
109
|
-
PDF::Core::PdfObject(:"my<symbol").should == "/my#3Csymbol"
|
|
110
|
-
PDF::Core::PdfObject(:"my>symbol").should == "/my#3Esymbol"
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
it "should convert a Ruby array to PDF Array when inside a content stream" do
|
|
114
|
-
PDF::Core::PdfObject([1,2,3]).should == "[1 2 3]"
|
|
115
|
-
PDF::Inspector.parse(PDF::Core::PdfObject([[1,2],:foo,"Bar"], true)).should ==
|
|
116
|
-
[[1,2],:foo, "Bar"]
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
it "should convert a Ruby array to PDF Array when outside a content stream" do
|
|
120
|
-
bar = "\xFE\xFF" + "Bar".unpack("U*").pack("n*")
|
|
121
|
-
PDF::Core::PdfObject([1,2,3]).should == "[1 2 3]"
|
|
122
|
-
PDF::Inspector.parse(PDF::Core::PdfObject([[1,2],:foo,"Bar"], false)).should ==
|
|
123
|
-
[[1,2],:foo, bar]
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
it "should convert a Ruby hash to a PDF Dictionary when inside a content stream" do
|
|
127
|
-
dict = PDF::Core::PdfObject( {:foo => :bar,
|
|
128
|
-
"baz" => [1,2,3],
|
|
129
|
-
:bang => {:a => "what", :b => [:you, :say] }}, true )
|
|
130
|
-
|
|
131
|
-
res = PDF::Inspector.parse(dict)
|
|
132
|
-
|
|
133
|
-
res[:foo].should == :bar
|
|
134
|
-
res[:baz].should == [1,2,3]
|
|
135
|
-
res[:bang].should == { :a => "what", :b => [:you, :say] }
|
|
136
|
-
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
it "should convert a Ruby hash to a PDF Dictionary when outside a content stream" do
|
|
140
|
-
what = "\xFE\xFF" + "what".unpack("U*").pack("n*")
|
|
141
|
-
dict = PDF::Core::PdfObject( {:foo => :bar,
|
|
142
|
-
"baz" => [1,2,3],
|
|
143
|
-
:bang => {:a => "what", :b => [:you, :say] }}, false )
|
|
144
|
-
|
|
145
|
-
res = PDF::Inspector.parse(dict)
|
|
146
|
-
|
|
147
|
-
res[:foo].should == :bar
|
|
148
|
-
res[:baz].should == [1,2,3]
|
|
149
|
-
res[:bang].should == { :a => what, :b => [:you, :say] }
|
|
150
|
-
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
it "should not allow keys other than strings or symbols for PDF dicts" do
|
|
154
|
-
lambda { PDF::Core::PdfObject(:foo => :bar, :baz => :bang, 1 => 4) }.
|
|
155
|
-
should raise_error(PDF::Core::Errors::FailedObjectConversion)
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
it "should convert a Prawn::Reference to a PDF indirect object reference" do
|
|
159
|
-
ref = PDF::Core::Reference(1,true)
|
|
160
|
-
PDF::Core::PdfObject(ref).should == ref.to_s
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
it "should convert a NameTree::Node to a PDF hash" do
|
|
164
|
-
# FIXME: Soft dependench on Prawn::Document exists in Node
|
|
165
|
-
node = PDF::Core::NameTree::Node.new(nil, 10)
|
|
166
|
-
node.add "hello", 1.0
|
|
167
|
-
node.add "world", 2.0
|
|
168
|
-
data = PDF::Core::PdfObject(node)
|
|
169
|
-
res = PDF::Inspector.parse(data)
|
|
170
|
-
res.should == {:Names => ["hello", 1.0, "world", 2.0]}
|
|
171
|
-
end
|
|
172
|
-
end
|