pdf-core 0.5.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  #
3
4
  # Implements graphics state saving and restoring
4
5
  #
@@ -7,7 +8,6 @@
7
8
  # This is free software. Please see the LICENSE and COPYING files for details
8
9
  #
9
10
 
10
-
11
11
  module PDF
12
12
  module Core
13
13
  class GraphicStateStack
@@ -34,28 +34,26 @@ module PDF
34
34
  end
35
35
 
36
36
  def present?
37
- stack.size > 0
37
+ !stack.empty?
38
38
  end
39
39
 
40
40
  def empty?
41
41
  stack.empty?
42
42
  end
43
-
44
43
  end
45
44
 
46
45
  # NOTE: This class may be a good candidate for a copy-on-write hash.
47
46
  class GraphicState
48
- attr_accessor :color_space, :dash, :cap_style, :join_style, :line_width,
49
- :fill_color, :stroke_color
47
+ attr_accessor :color_space, :dash, :cap_style, :join_style, :line_width, :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 = "000000"
57
- @stroke_color = "000000"
58
- @dash = { :dash => nil, :space => nil, :phase => 0 }
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,17 @@ module PDF
63
61
  end
64
62
 
65
63
  def dash_setting
66
- return "[] 0 d" unless @dash[:dash]
64
+ return '[] 0 d' unless @dash[:dash]
67
65
 
68
- if @dash[:dash].kind_of?(Array)
69
- array = @dash[:dash]
70
- else
71
- array = [@dash[:dash], @dash[:space]]
72
- end
73
-
74
-
75
- "[#{PDF::Core.real_params(array)}] "+
76
- "#{PDF::Core.real(@dash[:phase])} d"
66
+ array =
67
+ if @dash[:dash].is_a?(Array)
68
+ @dash[:dash]
69
+ else
70
+ [@dash[:dash], @dash[:space]]
71
+ end
72
+
73
+ "[#{PDF::Core.real_params(array)}] "\
74
+ "#{PDF::Core.real(@dash[:phase])} d"
77
75
  end
78
76
 
79
77
  private
@@ -93,4 +91,3 @@ module PDF
93
91
  end
94
92
  end
95
93
  end
96
-
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module PDF
3
4
  module Core
4
5
  # This is used to differentiate strings that must be encoded as
@@ -1,4 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
3
+ require 'pdf/core/utils'
2
4
 
3
5
  # name_tree.rb : Implements NameTree for PDF
4
6
  #
@@ -16,7 +18,7 @@ module PDF
16
18
  attr_accessor :parent
17
19
  attr_accessor :ref
18
20
 
19
- def initialize(document, limit, parent=nil)
21
+ def initialize(document, limit, parent = nil)
20
22
  @document = document
21
23
  @children = []
22
24
  @limit = limit
@@ -29,7 +31,7 @@ module PDF
29
31
  end
30
32
 
31
33
  def size
32
- leaf? ? children.size : children.inject(0) { |sum, child| sum + child.size }
34
+ leaf? ? children.size : children.sum(&:size)
33
35
  end
34
36
 
35
37
  def leaf?
@@ -47,10 +49,10 @@ module PDF
47
49
  if leaf?
48
50
  hash[:Names] = children if leaf?
49
51
  else
50
- hash[:Kids] = children.map { |child| child.ref }
52
+ hash[:Kids] = children.map(&:ref)
51
53
  end
52
54
 
53
- return hash
55
+ hash
54
56
  end
55
57
 
56
58
  def least
@@ -76,23 +78,24 @@ module PDF
76
78
  children.insert(insertion_point(value), value)
77
79
  split! if children.length > limit
78
80
  else
79
- fit = children.detect { |child| child >= value }
80
- fit = children.last unless fit
81
+ fit = children.find { |child| child >= value }
82
+ fit ||= children.last
81
83
  fit << value
82
84
  end
83
85
 
84
86
  value
85
87
  end
86
88
 
87
- def >=(value)
88
- children.empty? || children.last >= value
89
+ def >=(other)
90
+ children.empty? || children.last >= other
89
91
  end
90
92
 
91
93
  def split!
92
94
  if parent
93
95
  parent.split(self)
94
96
  else
95
- left, right = new_node(self), new_node(self)
97
+ left = new_node(self)
98
+ right = new_node(self)
96
99
  split_children(self, left, right)
97
100
  children.replace([left, right])
98
101
  end
@@ -103,51 +106,50 @@ module PDF
103
106
  #
104
107
  def deep_copy
105
108
  node = dup
106
- node.instance_variable_set("@children",
107
- Marshal.load(Marshal.dump(children)))
108
- node.instance_variable_set("@ref",
109
- node.ref ? node.ref.deep_copy : nil)
109
+ node.instance_variable_set('@children', Utils.deep_clone(children))
110
+ node.instance_variable_set('@ref', node.ref ? node.ref.deep_copy : nil)
110
111
  node
111
112
  end
112
113
 
113
114
  protected
114
115
 
115
- def split(node)
116
- new_child = new_node(self)
117
- split_children(node, node, new_child)
118
- index = children.index(node)
119
- children.insert(index+1, new_child)
120
- split! if children.length > limit
121
- end
116
+ def split(node)
117
+ new_child = new_node(self)
118
+ split_children(node, node, new_child)
119
+ index = children.index(node)
120
+ children.insert(index + 1, new_child)
121
+ split! if children.length > limit
122
+ end
122
123
 
123
124
  private
124
125
 
125
- def new_node(parent=nil)
126
- node = Node.new(document, limit, parent)
127
- node.ref = document.ref!(node)
128
- return node
129
- end
126
+ def new_node(parent = nil)
127
+ node = Node.new(document, limit, parent)
128
+ node.ref = document.ref!(node)
129
+ node
130
+ end
130
131
 
131
- def split_children(node, left, right)
132
- half = (node.limit+1)/2
132
+ def split_children(node, left, right)
133
+ half = (node.limit + 1) / 2
133
134
 
134
- left_children, right_children = node.children[0...half], node.children[half..-1]
135
+ left_children = node.children[0...half]
136
+ right_children = node.children[half..-1]
135
137
 
136
- left.children.replace(left_children)
137
- right.children.replace(right_children)
138
+ left.children.replace(left_children)
139
+ right.children.replace(right_children)
138
140
 
139
- unless node.leaf?
140
- left_children.each { |child| child.parent = left }
141
- right_children.each { |child| child.parent = right }
142
- end
141
+ unless node.leaf?
142
+ left_children.each { |child| child.parent = left }
143
+ right_children.each { |child| child.parent = right }
143
144
  end
145
+ end
144
146
 
145
- def insertion_point(value)
146
- children.each_with_index do |child, index|
147
- return index if child >= value
148
- end
149
- return children.length
147
+ def insertion_point(value)
148
+ children.each_with_index do |child, index|
149
+ return index if child >= value
150
150
  end
151
+ children.length
152
+ end
151
153
  end
152
154
 
153
155
  class Value #:nodoc:
@@ -157,11 +159,12 @@ module PDF
157
159
  attr_reader :value
158
160
 
159
161
  def initialize(name, value)
160
- @name, @value = PDF::Core::LiteralString.new(name), value
162
+ @name = PDF::Core::LiteralString.new(name)
163
+ @value = value
161
164
  end
162
165
 
163
- def <=>(leaf)
164
- name <=> leaf.name
166
+ def <=>(other)
167
+ name <=> other.name
165
168
  end
166
169
 
167
170
  def inspect
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  # Implements PDF object repository
4
4
  #
@@ -18,12 +18,12 @@ module PDF
18
18
  @identifiers = []
19
19
 
20
20
  @info ||= ref(opts[:info] || {}).identifier
21
- @root ||= ref(:Type => :Catalog).identifier
21
+ @root ||= ref(Type: :Catalog).identifier
22
22
  if opts[:print_scaling] == :none
23
- root.data[:ViewerPreferences] = {:PrintScaling => :None}
23
+ root.data[:ViewerPreferences] = { PrintScaling: :None }
24
24
  end
25
25
  if pages.nil?
26
- root.data[:Pages] = ref(:Type => :Pages, :Count => 0, :Kids => [])
26
+ root.data[:Pages] = ref(Type: :Pages, Count: 0, Kids: [])
27
27
  end
28
28
  end
29
29
 
@@ -48,22 +48,23 @@ module PDF
48
48
  end
49
49
 
50
50
  # Adds the given reference to the store and returns the reference object.
51
- # If the object provided is not a PDF::Core::Reference, one is created from the
52
- # arguments provided.
51
+ # If the object provided is not a PDF::Core::Reference, one is created
52
+ # from the arguments provided.
53
53
  #
54
54
  def push(*args, &block)
55
- reference = if args.first.is_a?(PDF::Core::Reference)
56
- args.first
57
- else
58
- PDF::Core::Reference.new(*args, &block)
59
- end
55
+ reference =
56
+ if args.first.is_a?(PDF::Core::Reference)
57
+ args.first
58
+ else
59
+ PDF::Core::Reference.new(*args, &block)
60
+ end
60
61
 
61
62
  @objects[reference.identifier] = reference
62
63
  @identifiers << reference.identifier
63
64
  reference
64
65
  end
65
66
 
66
- alias_method :<<, :push
67
+ alias << push
67
68
 
68
69
  def each
69
70
  @identifiers.each do |id|
@@ -78,7 +79,7 @@ module PDF
78
79
  def size
79
80
  @identifiers.size
80
81
  end
81
- alias_method :length, :size
82
+ alias length size
82
83
 
83
84
  # returns the object ID for a particular page in the document. Pages
84
85
  # are indexed starting at 1 (not 0!).
@@ -90,17 +91,11 @@ module PDF
90
91
  # object_id_for_page(-11)
91
92
  # => 17
92
93
  #
93
- def object_id_for_page(k)
94
- k -= 1 if k > 0
94
+ def object_id_for_page(page)
95
+ page -= 1 if page.positive?
95
96
  flat_page_ids = get_page_objects(pages).flatten
96
- flat_page_ids[k]
97
- end
98
-
99
- def is_utf8?(str)
100
- str.force_encoding(::Encoding::UTF_8)
101
- str.valid_encoding?
97
+ flat_page_ids[page]
102
98
  end
103
99
  end
104
100
  end
105
101
  end
106
-
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PDF
2
4
  module Core
3
5
  class OutlineItem #:nodoc:
@@ -11,11 +13,15 @@ module PDF
11
13
  end
12
14
 
13
15
  def to_hash
14
- hash = { :Title => title,
15
- :Parent => parent,
16
- :Count => closed ? -count : count }
17
- [{:First => first}, {:Last => last}, {:Next => defined?(@next) && @next},
18
- {:Prev => prev}, {:Dest => dest}].each do |h|
16
+ hash = {
17
+ Title: title,
18
+ Parent: parent,
19
+ Count: closed ? -count : count
20
+ }
21
+ [
22
+ { First: first }, { Last: last }, { Next: defined?(@next) && @next },
23
+ { Prev: prev }, { Dest: dest }
24
+ ].each do |h|
19
25
  unless h.values.first.nil?
20
26
  hash.merge!(h)
21
27
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PDF
2
4
  module Core
3
5
  class OutlineRoot #:nodoc:
@@ -8,7 +10,7 @@ module PDF
8
10
  end
9
11
 
10
12
  def to_hash
11
- {:Type => :Outlines, :Count => count, :First => first, :Last => last}
13
+ { Type: :Outlines, Count: count, First: first, Last: last }
12
14
  end
13
15
  end
14
16
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  # prawn/core/page.rb : Implements low-level representation of a PDF page
4
4
  #
@@ -12,21 +12,49 @@ require_relative 'graphics_state'
12
12
  module PDF
13
13
  module Core
14
14
  class Page #:nodoc:
15
- attr_accessor :document, :margins, :stack
15
+ attr_accessor :art_indents, :bleeds, :crops, :document, :margins, :stack, :trims
16
16
  attr_writer :content, :dictionary
17
17
 
18
- def initialize(document, options={})
18
+ ZERO_INDENTS = {
19
+ left: 0,
20
+ bottom: 0,
21
+ right: 0,
22
+ top: 0
23
+ }.freeze
24
+
25
+ def initialize(document, options = {})
19
26
  @document = document
20
- @margins = options[:margins] || { :left => 36,
21
- :right => 36,
22
- :top => 36,
23
- :bottom => 36 }
27
+ @margins = options[:margins] || {
28
+ left: 36,
29
+ right: 36,
30
+ top: 36,
31
+ bottom: 36
32
+ }
33
+ @crops = options[:crops] || ZERO_INDENTS
34
+ @bleeds = options[:bleeds] || ZERO_INDENTS
35
+ @trims = options[:trims] || ZERO_INDENTS
36
+ @art_indents = options[:art_indents] || ZERO_INDENTS
24
37
  @stack = GraphicStateStack.new(options[:graphic_state])
25
- if options[:object_id]
26
- init_from_object(options)
27
- else
28
- init_new_page(options)
29
- end
38
+ @size = options[:size] || 'LETTER'
39
+ @layout = options[:layout] || :portrait
40
+
41
+ @stamp_stream = nil
42
+ @stamp_dictionary = nil
43
+
44
+ @content = document.ref({})
45
+ content << 'q' << "\n"
46
+ @dictionary = document.ref(
47
+ Type: :Page,
48
+ Parent: document.state.store.pages,
49
+ MediaBox: dimensions,
50
+ CropBox: crop_box,
51
+ BleedBox: bleed_box,
52
+ TrimBox: trim_box,
53
+ ArtBox: art_box,
54
+ Contents: content
55
+ )
56
+
57
+ resources[:ProcSet] = %i[PDF Text ImageB ImageC ImageI]
30
58
  end
31
59
 
32
60
  def graphic_state
@@ -45,28 +73,26 @@ module PDF
45
73
  end
46
74
 
47
75
  def size
48
- defined?(@size) && @size || dimensions[2,2]
76
+ defined?(@size) && @size || dimensions[2, 2]
49
77
  end
50
78
 
51
79
  def in_stamp_stream?
52
- !!@stamp_stream
80
+ !@stamp_stream.nil?
53
81
  end
54
82
 
55
83
  def stamp_stream(dictionary)
56
- @stamp_stream = ""
57
84
  @stamp_dictionary = dictionary
85
+ @stamp_stream = @stamp_dictionary.stream
58
86
  graphic_stack_size = stack.stack.size
59
87
 
60
88
  document.save_graphics_state
61
- document.send(:freeze_stamp_graphics)
89
+ document.__send__(:freeze_stamp_graphics)
62
90
  yield if block_given?
63
91
 
64
92
  until graphic_stack_size == stack.stack.size
65
93
  document.restore_graphics_state
66
94
  end
67
95
 
68
- @stamp_dictionary << @stamp_stream
69
-
70
96
  @stamp_stream = nil
71
97
  @stamp_dictionary = nil
72
98
  end
@@ -76,7 +102,8 @@ module PDF
76
102
  end
77
103
 
78
104
  def dictionary
79
- defined?(@stamp_dictionary) && @stamp_dictionary || document.state.store[@dictionary]
105
+ defined?(@stamp_dictionary) && @stamp_dictionary ||
106
+ document.state.store[@dictionary]
80
107
  end
81
108
 
82
109
  def resources
@@ -116,62 +143,67 @@ module PDF
116
143
  dictionary.data[:Contents].each do |stream|
117
144
  stream.stream.compress! if document.compression_enabled?
118
145
  end
119
- else
120
- content.stream.compress! if document.compression_enabled?
146
+ elsif document.compression_enabled?
147
+ content.stream.compress!
121
148
  end
122
149
  end
123
150
 
124
- def imported_page?
125
- @imported_page
126
- end
127
-
128
151
  def dimensions
129
- return inherited_dictionary_value(:MediaBox) if imported_page?
130
-
131
152
  coords = PDF::Core::PageGeometry::SIZES[size] || size
132
- [0,0] + case(layout)
133
- when :portrait
134
- coords
135
- when :landscape
136
- coords.reverse
137
- else
138
- raise PDF::Core::Errors::InvalidPageLayout,
139
- "Layout must be either :portrait or :landscape"
140
- end
153
+ [0, 0] +
154
+ case layout
155
+ when :portrait
156
+ coords
157
+ when :landscape
158
+ coords.reverse
159
+ else
160
+ raise PDF::Core::Errors::InvalidPageLayout,
161
+ 'Layout must be either :portrait or :landscape'
162
+ end
141
163
  end
142
164
 
143
- private
144
-
145
- def init_from_object(options)
146
- @dictionary = options[:object_id].to_i
147
-
148
- unless dictionary.data[:Contents].is_a?(Array) # content only on leafs
149
- @content = dictionary.data[:Contents].identifier
150
- end
151
-
152
- @stamp_stream = nil
153
- @stamp_dictionary = nil
154
- @imported_page = true
165
+ def art_box
166
+ left, bottom, right, top = dimensions
167
+ [
168
+ left + art_indents[:left],
169
+ bottom + art_indents[:bottom],
170
+ right - art_indents[:right],
171
+ top - art_indents[:top]
172
+ ]
155
173
  end
156
174
 
157
- def init_new_page(options)
158
- @size = options[:size] || "LETTER"
159
- @layout = options[:layout] || :portrait
160
-
161
- @stamp_stream = nil
162
- @stamp_dictionary = nil
163
- @imported_page = false
175
+ def bleed_box
176
+ left, bottom, right, top = dimensions
177
+ [
178
+ left + bleeds[:left],
179
+ bottom + bleeds[:bottom],
180
+ right - bleeds[:right],
181
+ top - bleeds[:top]
182
+ ]
183
+ end
164
184
 
165
- @content = document.ref({})
166
- content << "q" << "\n"
167
- @dictionary = document.ref(:Type => :Page,
168
- :Parent => document.state.store.pages,
169
- :MediaBox => dimensions,
170
- :Contents => content)
185
+ def crop_box
186
+ left, bottom, right, top = dimensions
187
+ [
188
+ left + crops[:left],
189
+ bottom + crops[:bottom],
190
+ right - crops[:right],
191
+ top - crops[:top]
192
+ ]
193
+ end
171
194
 
172
- resources[:ProcSet] = [:PDF, :Text, :ImageB, :ImageC, :ImageI]
195
+ def trim_box
196
+ left, bottom, right, top = dimensions
197
+ [
198
+ left + trims[:left],
199
+ bottom + trims[:bottom],
200
+ right - trims[:right],
201
+ top - trims[:top]
202
+ ]
173
203
  end
174
204
 
205
+ private
206
+
175
207
  # some entries in the Page dict can be inherited from parent Pages dicts.
176
208
  #
177
209
  # Starting with the current page dict, this method will walk up the
@@ -183,12 +215,10 @@ module PDF
183
215
  def inherited_dictionary_value(key, local_dict = nil)
184
216
  local_dict ||= dictionary.data
185
217
 
186
- if local_dict.has_key?(key)
218
+ if local_dict.key?(key)
187
219
  local_dict[key]
188
- elsif local_dict.has_key?(:Parent)
220
+ elsif local_dict.key?(:Parent)
189
221
  inherited_dictionary_value(key, local_dict[:Parent].data)
190
- else
191
- nil
192
222
  end
193
223
  end
194
224
  end