pdf-core 0.6.1 → 0.7.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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -0
- data/Rakefile +9 -5
- data/lib/pdf/core.rb +20 -19
- data/lib/pdf/core/annotations.rb +16 -17
- data/lib/pdf/core/byte_string.rb +1 -1
- data/lib/pdf/core/destinations.rb +17 -14
- data/lib/pdf/core/document_state.rb +21 -16
- data/lib/pdf/core/filter_list.rb +4 -4
- data/lib/pdf/core/filters.rb +4 -4
- data/lib/pdf/core/graphics_state.rb +15 -19
- data/lib/pdf/core/name_tree.rb +44 -40
- data/lib/pdf/core/object_store.rb +13 -18
- data/lib/pdf/core/outline_item.rb +11 -6
- data/lib/pdf/core/outline_root.rb +1 -1
- data/lib/pdf/core/page.rb +93 -64
- data/lib/pdf/core/page_geometry.rb +52 -56
- data/lib/pdf/core/pdf_object.rb +41 -41
- data/lib/pdf/core/reference.rb +12 -17
- data/lib/pdf/core/renderer.rb +41 -32
- data/lib/pdf/core/stream.rb +6 -8
- data/lib/pdf/core/text.rb +83 -47
- data/lib/pdf/core/utils.rb +12 -0
- data/pdf-core.gemspec +33 -20
- metadata +79 -24
- metadata.gz.sig +0 -0
- data/spec/decimal_rounding_spec.rb +0 -12
- data/spec/document_state_spec.rb +0 -30
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b927f3fa2dd24b6cdb4985d8b0d72f6b753cc3d1
|
4
|
+
data.tar.gz: 51de8ad704088ef8738768969444443379b57bcc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 589610d88baa8f03bbe3b4532cef5d780e0264d021933622d816c7b87b34ae8df06b5cd4e4276a2b159bcf6bbb1ae2ff0710d2cbe8cf37e44ce4c12ab7e04007
|
7
|
+
data.tar.gz: 525447dd1ed202a7880bbac27a7acc4cda730eae17b726c5ef2b3c46ec777dbdd8d794db8e36207d6a764b6e45caf007e628e76b139fc93d1f5c2ec8cb0f181d
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
data/Rakefile
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler'
|
2
2
|
Bundler.setup
|
3
3
|
|
4
4
|
require 'rake'
|
5
5
|
require 'rspec/core/rake_task'
|
6
|
-
task :default => [:spec]
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
task default: [:spec, :rubocop]
|
8
|
+
|
9
|
+
desc 'Run all rspec files'
|
10
|
+
RSpec::Core::RakeTask.new('spec') do |c|
|
11
|
+
c.rspec_opts = '-t ~unresolved'
|
11
12
|
end
|
13
|
+
|
14
|
+
require 'rubocop/rake_task'
|
15
|
+
RuboCop::RakeTask.new
|
data/lib/pdf/core.rb
CHANGED
@@ -1,26 +1,27 @@
|
|
1
|
-
require_relative
|
2
|
-
require_relative
|
3
|
-
require_relative
|
4
|
-
require_relative
|
5
|
-
require_relative
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
-
require_relative
|
9
|
-
require_relative
|
10
|
-
require_relative
|
11
|
-
require_relative
|
12
|
-
require_relative
|
13
|
-
require_relative
|
14
|
-
require_relative
|
15
|
-
require_relative
|
16
|
-
require_relative
|
17
|
-
require_relative
|
18
|
-
require_relative
|
1
|
+
require_relative 'core/pdf_object'
|
2
|
+
require_relative 'core/annotations'
|
3
|
+
require_relative 'core/byte_string'
|
4
|
+
require_relative 'core/destinations'
|
5
|
+
require_relative 'core/filters'
|
6
|
+
require_relative 'core/stream'
|
7
|
+
require_relative 'core/reference'
|
8
|
+
require_relative 'core/literal_string'
|
9
|
+
require_relative 'core/filter_list'
|
10
|
+
require_relative 'core/page'
|
11
|
+
require_relative 'core/object_store'
|
12
|
+
require_relative 'core/document_state'
|
13
|
+
require_relative 'core/name_tree'
|
14
|
+
require_relative 'core/graphics_state'
|
15
|
+
require_relative 'core/page_geometry'
|
16
|
+
require_relative 'core/outline_root'
|
17
|
+
require_relative 'core/outline_item'
|
18
|
+
require_relative 'core/renderer'
|
19
|
+
require_relative 'core/text'
|
19
20
|
|
20
21
|
module PDF
|
21
22
|
module Core
|
22
23
|
module Errors
|
23
|
-
# This error is raised when
|
24
|
+
# This error is raised when pdf_object() fails
|
24
25
|
FailedObjectConversion = Class.new(StandardError)
|
25
26
|
|
26
27
|
# This error is raise when trying to restore a graphic state that
|
data/lib/pdf/core/annotations.rb
CHANGED
@@ -11,7 +11,6 @@ module PDF
|
|
11
11
|
# Provides very low-level support for annotations.
|
12
12
|
#
|
13
13
|
module Annotations #:nodoc:
|
14
|
-
|
15
14
|
# Adds a new annotation (section 8.4 in PDF spec) to the current page.
|
16
15
|
# +options+ must be a Hash describing the annotation.
|
17
16
|
#
|
@@ -19,34 +18,35 @@ module PDF
|
|
19
18
|
state.page.dictionary.data[:Annots] ||= []
|
20
19
|
options = sanitize_annotation_hash(options)
|
21
20
|
state.page.dictionary.data[:Annots] << ref!(options)
|
22
|
-
|
21
|
+
options
|
23
22
|
end
|
24
23
|
|
25
|
-
# A convenience method for creating Text annotations. +rect+ must be an
|
26
|
-
# of four numbers, describing the bounds of the annotation.
|
27
|
-
# be a string, to be shown when the annotation is
|
24
|
+
# A convenience method for creating Text annotations. +rect+ must be an
|
25
|
+
# array of four numbers, describing the bounds of the annotation.
|
26
|
+
# +contents+ should be a string, to be shown when the annotation is
|
27
|
+
# activated.
|
28
28
|
#
|
29
|
-
def text_annotation(rect, contents, options={})
|
30
|
-
options = options.merge(:
|
29
|
+
def text_annotation(rect, contents, options = {})
|
30
|
+
options = options.merge(Subtype: :Text, Rect: rect, Contents: contents)
|
31
31
|
annotate(options)
|
32
32
|
end
|
33
33
|
|
34
|
-
# A convenience method for creating Link annotations. +rect+ must be an
|
35
|
-
# of four numbers, describing the bounds of the annotation. The
|
36
|
-
# should include either :Dest (describing the target
|
37
|
-
# string that has been recorded in the
|
38
|
-
#
|
39
|
-
# link to).
|
34
|
+
# A convenience method for creating Link annotations. +rect+ must be an
|
35
|
+
# array of four numbers, describing the bounds of the annotation. The
|
36
|
+
# +options+ hash should include either :Dest (describing the target
|
37
|
+
# destination, usually as a string that has been recorded in the
|
38
|
+
# document's Dests tree), or :A (describing an action to perform on
|
39
|
+
# clicking the link), or :PA (for describing a URL to link to).
|
40
40
|
#
|
41
|
-
def link_annotation(rect, options={})
|
42
|
-
options = options.merge(:
|
41
|
+
def link_annotation(rect, options = {})
|
42
|
+
options = options.merge(Subtype: :Link, Rect: rect)
|
43
43
|
annotate(options)
|
44
44
|
end
|
45
45
|
|
46
46
|
private
|
47
47
|
|
48
48
|
def sanitize_annotation_hash(options)
|
49
|
-
options = options.merge(:
|
49
|
+
options = options.merge(Type: :Annot)
|
50
50
|
|
51
51
|
if options[:Dest].is_a?(String)
|
52
52
|
options[:Dest] = PDF::Core::LiteralString.new(options[:Dest])
|
@@ -54,7 +54,6 @@ module PDF
|
|
54
54
|
|
55
55
|
options
|
56
56
|
end
|
57
|
-
|
58
57
|
end
|
59
58
|
end
|
60
59
|
end
|
data/lib/pdf/core/byte_string.rb
CHANGED
@@ -9,16 +9,19 @@
|
|
9
9
|
module PDF
|
10
10
|
module Core
|
11
11
|
module Destinations #:nodoc:
|
12
|
-
|
13
|
-
#
|
12
|
+
# The maximum number of children to fit into a single node in the Dests
|
13
|
+
# tree.
|
14
14
|
NAME_TREE_CHILDREN_LIMIT = 20 #:nodoc:
|
15
15
|
|
16
|
-
# The Dests name tree in the Name dictionary (see
|
17
|
-
# This name tree is used to store named
|
18
|
-
# (For more on name trees, see section
|
16
|
+
# The Dests name tree in the Name dictionary (see
|
17
|
+
# Prawn::Document::Internal#names). This name tree is used to store named
|
18
|
+
# destinations (PDF spec 8.2.1). (For more on name trees, see section
|
19
|
+
# 3.8.4 in the PDF spec.)
|
19
20
|
#
|
20
21
|
def dests
|
21
|
-
names.data[:Dests] ||= ref!(
|
22
|
+
names.data[:Dests] ||= ref!(
|
23
|
+
PDF::Core::NameTree::Node.new(self, NAME_TREE_CHILDREN_LIMIT)
|
24
|
+
)
|
22
25
|
end
|
23
26
|
|
24
27
|
# Adds a new destination to the dests name tree (see #dests). The
|
@@ -33,56 +36,56 @@ module PDF
|
|
33
36
|
# Return a Dest specification for a specific location (and optional zoom
|
34
37
|
# level).
|
35
38
|
#
|
36
|
-
def dest_xyz(left, top, zoom=nil, dest_page=page)
|
39
|
+
def dest_xyz(left, top, zoom = nil, dest_page = page)
|
37
40
|
[dest_page.dictionary, :XYZ, left, top, zoom]
|
38
41
|
end
|
39
42
|
|
40
43
|
# Return a Dest specification that will fit the given page into the
|
41
44
|
# viewport.
|
42
45
|
#
|
43
|
-
def dest_fit(dest_page=page)
|
46
|
+
def dest_fit(dest_page = page)
|
44
47
|
[dest_page.dictionary, :Fit]
|
45
48
|
end
|
46
49
|
|
47
50
|
# Return a Dest specification that will fit the given page horizontally
|
48
51
|
# into the viewport, aligned vertically at the given top coordinate.
|
49
52
|
#
|
50
|
-
def dest_fit_horizontally(top, dest_page=page)
|
53
|
+
def dest_fit_horizontally(top, dest_page = page)
|
51
54
|
[dest_page.dictionary, :FitH, top]
|
52
55
|
end
|
53
56
|
|
54
57
|
# Return a Dest specification that will fit the given page vertically
|
55
58
|
# into the viewport, aligned horizontally at the given left coordinate.
|
56
59
|
#
|
57
|
-
def dest_fit_vertically(left, dest_page=page)
|
60
|
+
def dest_fit_vertically(left, dest_page = page)
|
58
61
|
[dest_page.dictionary, :FitV, left]
|
59
62
|
end
|
60
63
|
|
61
64
|
# Return a Dest specification that will fit the given rectangle into the
|
62
65
|
# viewport, for the given page.
|
63
66
|
#
|
64
|
-
def dest_fit_rect(left, bottom, right, top, dest_page=page)
|
67
|
+
def dest_fit_rect(left, bottom, right, top, dest_page = page)
|
65
68
|
[dest_page.dictionary, :FitR, left, bottom, right, top]
|
66
69
|
end
|
67
70
|
|
68
71
|
# Return a Dest specfication that will fit the given page's bounding box
|
69
72
|
# into the viewport.
|
70
73
|
#
|
71
|
-
def dest_fit_bounds(dest_page=page)
|
74
|
+
def dest_fit_bounds(dest_page = page)
|
72
75
|
[dest_page.dictionary, :FitB]
|
73
76
|
end
|
74
77
|
|
75
78
|
# Same as #dest_fit_horizontally, but works on the page's bounding box
|
76
79
|
# instead of the entire page.
|
77
80
|
#
|
78
|
-
def dest_fit_bounds_horizontally(top, dest_page=page)
|
81
|
+
def dest_fit_bounds_horizontally(top, dest_page = page)
|
79
82
|
[dest_page.dictionary, :FitBH, top]
|
80
83
|
end
|
81
84
|
|
82
85
|
# Same as #dest_fit_vertically, but works on the page's bounding box
|
83
86
|
# instead of the entire page.
|
84
87
|
#
|
85
|
-
def dest_fit_bounds_vertically(left, dest_page=page)
|
88
|
+
def dest_fit_bounds_vertically(left, dest_page = page)
|
86
89
|
[dest_page.dictionary, :FitBV, left]
|
87
90
|
end
|
88
91
|
end
|
@@ -4,12 +4,15 @@ module PDF
|
|
4
4
|
def initialize(options)
|
5
5
|
normalize_metadata(options)
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
@store =
|
8
|
+
if options[:print_scaling]
|
9
|
+
PDF::Core::ObjectStore.new(
|
10
|
+
info: options[:info],
|
11
|
+
print_scaling: options[:print_scaling]
|
12
|
+
)
|
13
|
+
else
|
14
|
+
PDF::Core::ObjectStore.new(info: options[:info])
|
15
|
+
end
|
13
16
|
|
14
17
|
@version = 1.3
|
15
18
|
@pages = []
|
@@ -28,20 +31,19 @@ module PDF
|
|
28
31
|
:before_render_callbacks, :on_page_create_callback
|
29
32
|
|
30
33
|
def populate_pages_from_store(document)
|
31
|
-
return 0 if @store.page_count <= 0 ||
|
34
|
+
return 0 if @store.page_count <= 0 || !@pages.empty?
|
32
35
|
|
33
36
|
count = (1..@store.page_count)
|
34
37
|
@pages = count.map do |index|
|
35
38
|
orig_dict_id = @store.object_id_for_page(index)
|
36
|
-
PDF::Core::Page.new(document, :
|
39
|
+
PDF::Core::Page.new(document, object_id: orig_dict_id)
|
37
40
|
end
|
38
|
-
|
39
41
|
end
|
40
42
|
|
41
43
|
def normalize_metadata(options)
|
42
44
|
options[:info] ||= {}
|
43
|
-
options[:info][:Creator] ||=
|
44
|
-
options[:info][:Producer] ||=
|
45
|
+
options[:info][:Creator] ||= 'Prawn'
|
46
|
+
options[:info][:Producer] ||= 'Prawn'
|
45
47
|
|
46
48
|
options[:info]
|
47
49
|
end
|
@@ -56,8 +58,8 @@ module PDF
|
|
56
58
|
on_page_create_callback[doc] if on_page_create_callback
|
57
59
|
end
|
58
60
|
|
59
|
-
def before_render_actions(
|
60
|
-
before_render_callbacks.each{ |c| c.call(self) }
|
61
|
+
def before_render_actions(_doc)
|
62
|
+
before_render_callbacks.each { |c| c.call(self) }
|
61
63
|
end
|
62
64
|
|
63
65
|
def page_count
|
@@ -67,11 +69,14 @@ module PDF
|
|
67
69
|
def render_body(output)
|
68
70
|
store.each do |ref|
|
69
71
|
ref.offset = output.size
|
70
|
-
output <<
|
71
|
-
|
72
|
+
output <<
|
73
|
+
if @encrypt
|
74
|
+
ref.encrypted_object(@encryption_key)
|
75
|
+
else
|
76
|
+
ref.object
|
77
|
+
end
|
72
78
|
end
|
73
79
|
end
|
74
|
-
|
75
80
|
end
|
76
81
|
end
|
77
82
|
end
|
data/lib/pdf/core/filter_list.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
module PDF
|
1
|
+
module PDF
|
2
2
|
module Core
|
3
3
|
class FilterList
|
4
4
|
def initialize
|
@@ -23,7 +23,7 @@ module PDF
|
|
23
23
|
def normalized
|
24
24
|
@list
|
25
25
|
end
|
26
|
-
|
26
|
+
alias to_a normalized
|
27
27
|
|
28
28
|
def names
|
29
29
|
@list.map do |(name, _)|
|
@@ -41,9 +41,9 @@ module PDF
|
|
41
41
|
@list.inspect
|
42
42
|
end
|
43
43
|
|
44
|
-
def each
|
44
|
+
def each
|
45
45
|
@list.each do |filter|
|
46
|
-
|
46
|
+
yield(filter)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
data/lib/pdf/core/filters.rb
CHANGED
@@ -12,22 +12,22 @@ module PDF
|
|
12
12
|
module Core
|
13
13
|
module Filters
|
14
14
|
module FlateDecode
|
15
|
-
def self.encode(stream,
|
15
|
+
def self.encode(stream, _params = nil)
|
16
16
|
Zlib::Deflate.deflate(stream)
|
17
17
|
end
|
18
18
|
|
19
|
-
def self.decode(stream,
|
19
|
+
def self.decode(stream, _params = nil)
|
20
20
|
Zlib::Inflate.inflate(stream)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
# Pass through stub
|
25
25
|
module DCTDecode
|
26
|
-
def self.encode(stream,
|
26
|
+
def self.encode(stream, _params = nil)
|
27
27
|
stream
|
28
28
|
end
|
29
29
|
|
30
|
-
def self.decode(stream,
|
30
|
+
def self.decode(stream, _params = nil)
|
31
31
|
stream
|
32
32
|
end
|
33
33
|
end
|
@@ -7,7 +7,6 @@
|
|
7
7
|
# This is free software. Please see the LICENSE and COPYING files for details
|
8
8
|
#
|
9
9
|
|
10
|
-
|
11
10
|
module PDF
|
12
11
|
module Core
|
13
12
|
class GraphicStateStack
|
@@ -34,28 +33,27 @@ module PDF
|
|
34
33
|
end
|
35
34
|
|
36
35
|
def present?
|
37
|
-
stack.
|
36
|
+
!stack.empty?
|
38
37
|
end
|
39
38
|
|
40
39
|
def empty?
|
41
40
|
stack.empty?
|
42
41
|
end
|
43
|
-
|
44
42
|
end
|
45
43
|
|
46
44
|
# NOTE: This class may be a good candidate for a copy-on-write hash.
|
47
45
|
class GraphicState
|
48
|
-
attr_accessor :color_space, :dash, :cap_style, :join_style, :line_width,
|
49
|
-
|
46
|
+
attr_accessor :color_space, :dash, :cap_style, :join_style, :line_width,
|
47
|
+
:fill_color, :stroke_color
|
50
48
|
|
51
49
|
def initialize(previous_state = nil)
|
52
50
|
if previous_state
|
53
51
|
initialize_copy(previous_state)
|
54
52
|
else
|
55
53
|
@color_space = {}
|
56
|
-
@fill_color =
|
57
|
-
@stroke_color =
|
58
|
-
@dash = { :
|
54
|
+
@fill_color = '000000'
|
55
|
+
@stroke_color = '000000'
|
56
|
+
@dash = { dash: nil, space: nil, phase: 0 }
|
59
57
|
@cap_style = :butt
|
60
58
|
@join_style = :miter
|
61
59
|
@line_width = 1
|
@@ -63,17 +61,16 @@ module PDF
|
|
63
61
|
end
|
64
62
|
|
65
63
|
def dash_setting
|
66
|
-
return
|
64
|
+
return '[] 0 d' unless @dash[:dash]
|
67
65
|
|
68
|
-
if @dash[:dash].
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
"#{PDF::Core.real(@dash[:phase])} d"
|
66
|
+
array = if @dash[:dash].is_a?(Array)
|
67
|
+
@dash[:dash]
|
68
|
+
else
|
69
|
+
[@dash[:dash], @dash[:space]]
|
70
|
+
end
|
71
|
+
|
72
|
+
"[#{PDF::Core.real_params(array)}] "\
|
73
|
+
"#{PDF::Core.real(@dash[:phase])} d"
|
77
74
|
end
|
78
75
|
|
79
76
|
private
|
@@ -93,4 +90,3 @@ module PDF
|
|
93
90
|
end
|
94
91
|
end
|
95
92
|
end
|
96
|
-
|