combine_pdf 0.0.5 → 0.0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 169d63fc09f86f09a633e199582c65212fbcd158
4
- data.tar.gz: 6f5d94234603827a33100c77e4b66ac41492c60c
3
+ metadata.gz: 91a403f449ba29c772a9e6d12e114e0271129ecb
4
+ data.tar.gz: 9b94530e869fe1a5936706305c2407eeeb9f35a7
5
5
  SHA512:
6
- metadata.gz: ffb49820460e29f7d6d857fe6f66af7a9b0f97edae28a2ab1caa814eb5e84d521f91b76e091b2b33fe36f716684253a30fc51cc777e8696c5ee09ed21ebae0ae
7
- data.tar.gz: fb6e175436280fd64499684151f29c7cf9254ca21be6a0052e42f80c6d29ede70ed982afbf7aef07fd31cbcf88c460f9eb1a84bea3f363a74ac78d3bb5bc44e2
6
+ metadata.gz: ce4a31ce78d6ff246f51ced6567b73fb5b5905cfbcf43fa2d980996d16e66570e1777a350cec53527d5772eae07be8dfc768f7b68811505428e4788cb55e195f
7
+ data.tar.gz: 9fc48d3e72643e48b179ceb01d755fc928585b5d911f53bc83fa96f41c87353c46a517966c9c094ff0e116dcb95010d7aced07cb3aafe1a12ea8d0c1b21da2bd
@@ -37,9 +37,12 @@ require "combine_pdf/font_metrics/metrics_dictionary.rb"
37
37
  # == Combine / Merge
38
38
  # To combine PDF files (or data):
39
39
  # pdf = CombinePDF.new
40
- # pdf << CombinePDF.new "file1.pdf" # one way to combine, very fast.
40
+ # pdf << CombinePDF.new("file1.pdf") # one way to combine, very fast.
41
41
  # CombinePDF.new("file2.pdf").pages.each {|page| pdf << page} # different way to combine, slower.
42
42
  # pdf.save "combined.pdf"
43
+ #
44
+ # Or, you can do it all in one line:
45
+ # ( CombinePDF.new("file1.pdf") << CombinePDF.new("file2.pdf") << CombinePDF.new("file3.pdf") ).save "combined.pdf"
43
46
  # == Stamp / Watermark
44
47
  # <b>has issues with specific PDF files - please see the issues</b>: https://github.com/boazsegev/combine_pdf/issues/2
45
48
  # To combine PDF files (or data), first create the stamp from a PDF file:
@@ -50,6 +53,10 @@ require "combine_pdf/font_metrics/metrics_dictionary.rb"
50
53
  # pdf.pages.each {|page| page << stamp_page}
51
54
  # Notice the << operator is on a page and not a PDF object. The << operator acts differently on PDF objects and on Pages.
52
55
  #
56
+ # The << operator defaults to secure injection by renaming references to avoid conflics. For overlaying pages using compressed data that might not be editable (due to limited filter support), you can use:
57
+ # pdf.pages(nil, false).each {|page| page << stamp_page}
58
+ #
59
+ #
53
60
  # Notice that page objects are Hash class objects and the << operator was added to the Page instances without altering the class.
54
61
  #
55
62
  # == Decryption & Filters
@@ -15,7 +15,7 @@ module CombinePDF
15
15
  #
16
16
  # <b>This doesn't work yet!</b>
17
17
  #
18
- # and alsom, for even when it will work, UNICODE SUPPORT IS MISSING!
18
+ # and also, even when it will work, UNICODE SUPPORT IS MISSING!
19
19
  #
20
20
  # in the future I wish to make a simple PDF page writer, that has only one functions - the text box.
21
21
  # Once the simple writer is ready (creates a text box in a self contained Page element),
@@ -26,7 +26,9 @@ module CombinePDF
26
26
  #
27
27
  # Writing on this Page is done using the text_box function.
28
28
  #
29
- # the rest of the functions are for internal use.
29
+ # Setting the page dimentions can be either at the new or using the media_box method.
30
+ #
31
+ # the rest of the methods are for internal use.
30
32
  #
31
33
  # Once the Page is completed (the last text box was added),
32
34
  # we can insert the page to a CombinePDF object.
@@ -53,16 +55,6 @@ module CombinePDF
53
55
  self[:Contents] = { is_reference_only: true , referenced_object: {indirect_reference_id: 0, raw_stream_content: ""} }
54
56
  self[:MediaBox] = media_box
55
57
  end
56
-
57
- # accessor (getter) for the :Resources element of the page
58
- def resources
59
- self[:Resources]
60
- end
61
- # accessor (getter) for the stream in the :Contents element of the page
62
- # after getting the string object, you can operate on it but not replace it (use << or other String methods).
63
- def contents
64
- self[:Contents][:referenced_object][:raw_stream_content]
65
- end
66
58
  # accessor (getter) for the :MediaBox element of the page
67
59
  def media_box
68
60
  self[:MediaBox]
@@ -72,73 +64,6 @@ module CombinePDF
72
64
  def media_box=(dimentions = [0.0, 0.0, 612.0, 792.0])
73
65
  self[:MediaBox] = dimentions
74
66
  end
75
- # creates a font object and adds the font to the resources dictionary
76
- # returns the name of the font for the content stream.
77
- # font_name:: a Symbol of one of the 14 Type 1 fonts, known as the standard 14 fonts:
78
- # - :"Times-Roman"
79
- # - :"Times-Bold"
80
- # - :"Times-Italic"
81
- # - :"Times-BoldItalic"
82
- # - :Helvetica
83
- # - :"Helvetica-Bold"
84
- # - :"Helvetica-BoldOblique"
85
- # - :"Helvetica- Oblique"
86
- # - :Courier
87
- # - :"Courier-Bold"
88
- # - :"Courier-Oblique"
89
- # - :"Courier-BoldOblique"
90
- # - :Symbol
91
- # - :ZapfDingbats
92
- def font(font_name = :Helvetica)
93
- # refuse any other fonts that arn't basic standard fonts
94
- allow_fonts = [ :"Times-Roman",
95
- :"Times-Bold",
96
- :"Times-Italic",
97
- :"Times-BoldItalic",
98
- :Helvetica,
99
- :"Helvetica-Bold",
100
- :"Helvetica-BoldOblique",
101
- :"Helvetica-Oblique",
102
- :Courier,
103
- :"Courier-Bold",
104
- :"Courier-Oblique",
105
- :"Courier-BoldOblique",
106
- :Symbol,
107
- :ZapfDingbats ]
108
- raise "add_font(font_name) accepts only one of the 14 standards fonts - wrong font_name!" unless allow_fonts.include? font_name
109
- # if the font exists, return it's name
110
- resources[:Font] ||= {}
111
- resources[:Font].each do |k,v|
112
- if v.is_a?(Hash) && v[:Type] == :Font && v[:BaseFont] == font_name
113
- return k
114
- end
115
- end
116
- # create font object
117
- font_object = { Type: :Font, Subtype: :Type1, BaseFont: font_name}
118
- # set a secure name for the font
119
- name = (SecureRandom.urlsafe_base64(9)).to_sym
120
- # add object to reasource
121
- resources[:Font][name] = font_object
122
- #return name
123
- name
124
- end
125
- def graphic_state(graphic_state_dictionary = {})
126
- # if the graphic state exists, return it's name
127
- resources[:ExtGState] ||= {}
128
- resources[:ExtGState].each do |k,v|
129
- if v.is_a?(Hash) && v == graphic_state_dictionary
130
- return k
131
- end
132
- end
133
- # set graphic state type
134
- graphic_state_dictionary[:Type] = :ExtGState
135
- # set a secure name for the graphic state
136
- name = (SecureRandom.urlsafe_base64(9)).to_sym
137
- # add object to reasource
138
- resources[:ExtGState][name] = graphic_state_dictionary
139
- #return name
140
- name
141
- end
142
67
 
143
68
  # <b>INCOMPLETE</b>
144
69
  #
@@ -226,6 +151,84 @@ module CombinePDF
226
151
  self
227
152
  end
228
153
 
154
+ protected
155
+
156
+ # accessor (getter) for the :Resources element of the page
157
+ def resources
158
+ self[:Resources]
159
+ end
160
+ # accessor (getter) for the stream in the :Contents element of the page
161
+ # after getting the string object, you can operate on it but not replace it (use << or other String methods).
162
+ def contents
163
+ self[:Contents][:referenced_object][:raw_stream_content]
164
+ end
165
+ # creates a font object and adds the font to the resources dictionary
166
+ # returns the name of the font for the content stream.
167
+ # font_name:: a Symbol of one of the 14 Type 1 fonts, known as the standard 14 fonts:
168
+ # - :"Times-Roman"
169
+ # - :"Times-Bold"
170
+ # - :"Times-Italic"
171
+ # - :"Times-BoldItalic"
172
+ # - :Helvetica
173
+ # - :"Helvetica-Bold"
174
+ # - :"Helvetica-BoldOblique"
175
+ # - :"Helvetica- Oblique"
176
+ # - :Courier
177
+ # - :"Courier-Bold"
178
+ # - :"Courier-Oblique"
179
+ # - :"Courier-BoldOblique"
180
+ # - :Symbol
181
+ # - :ZapfDingbats
182
+ def font(font_name = :Helvetica)
183
+ # refuse any other fonts that arn't basic standard fonts
184
+ allow_fonts = [ :"Times-Roman",
185
+ :"Times-Bold",
186
+ :"Times-Italic",
187
+ :"Times-BoldItalic",
188
+ :Helvetica,
189
+ :"Helvetica-Bold",
190
+ :"Helvetica-BoldOblique",
191
+ :"Helvetica-Oblique",
192
+ :Courier,
193
+ :"Courier-Bold",
194
+ :"Courier-Oblique",
195
+ :"Courier-BoldOblique",
196
+ :Symbol,
197
+ :ZapfDingbats ]
198
+ raise "add_font(font_name) accepts only one of the 14 standards fonts - wrong font_name!" unless allow_fonts.include? font_name
199
+ # if the font exists, return it's name
200
+ resources[:Font] ||= {}
201
+ resources[:Font].each do |k,v|
202
+ if v.is_a?(Hash) && v[:Type] == :Font && v[:BaseFont] == font_name
203
+ return k
204
+ end
205
+ end
206
+ # create font object
207
+ font_object = { Type: :Font, Subtype: :Type1, BaseFont: font_name}
208
+ # set a secure name for the font
209
+ name = (SecureRandom.urlsafe_base64(9)).to_sym
210
+ # add object to reasource
211
+ resources[:Font][name] = font_object
212
+ #return name
213
+ name
214
+ end
215
+ def graphic_state(graphic_state_dictionary = {})
216
+ # if the graphic state exists, return it's name
217
+ resources[:ExtGState] ||= {}
218
+ resources[:ExtGState].each do |k,v|
219
+ if v.is_a?(Hash) && v == graphic_state_dictionary
220
+ return k
221
+ end
222
+ end
223
+ # set graphic state type
224
+ graphic_state_dictionary[:Type] = :ExtGState
225
+ # set a secure name for the graphic state
226
+ name = (SecureRandom.urlsafe_base64(9)).to_sym
227
+ # add object to reasource
228
+ resources[:ExtGState][name] = graphic_state_dictionary
229
+ #return name
230
+ name
231
+ end
229
232
  end
230
233
 
231
234
  end
@@ -10,29 +10,26 @@
10
10
 
11
11
  module CombinePDF
12
12
 
13
- ########################################################
14
- ## This is the Parser class.
15
- ## It takes PDF data and parses it, returning an array
16
- ## of data.
17
- ## That array can be used to initialize a PDF object.
18
- ## The Parser class doesn't involve itself with the
19
- ## file version.
20
- ########################################################
21
13
 
14
+ #######################################################
22
15
  #@private
23
16
  #:nodoc: all
17
+ # This is the Parser class.
18
+ #
19
+ # It takes PDF data and parses it.
20
+ #
21
+ # The information is then used to initialize a PDF object.
22
+ #######################################################
24
23
  class PDFParser
25
- # LITERAL_STRING_REPLACEMENT_HASH = {
26
- # 110 => 10, # "\\n".bytes = [92, 110] "\n".ord = 10
27
- # 114 => 13, #r
28
- # 116 => 9, #t
29
- # 98 => 8, #b
30
- # 102 => 255, #f
31
- # 40 => 40, #(
32
- # 41 => 41, #)
33
- # 92 => 92 #\
34
- # }
35
- attr_reader :parsed, :version, :info_object, :root_object
24
+
25
+ # the array containing all the parsed data (PDF Objects)
26
+ attr_reader :parsed
27
+ # a Float representing the PDF version of the data parsed (if exists).
28
+ attr_reader :version
29
+ # the info and root objects, as found (if found) in the PDF file.
30
+ #
31
+ # they are mainly to used to know if the file is (was) encrypted and to get more details.
32
+ attr_reader :info_object, :root_object
36
33
  def initialize (string)
37
34
  raise TypeError, "couldn't parse and data, expecting type String" unless string.is_a? String
38
35
  @string_to_parse = string.force_encoding(Encoding::ASCII_8BIT)
@@ -46,6 +43,7 @@ module CombinePDF
46
43
  @scanner = nil
47
44
  end
48
45
 
46
+ # parse the data in the parser (set in the initialize / new method)
49
47
  def parse
50
48
  return @parsed unless @parsed.empty?
51
49
  @scanner = StringScanner.new @string_to_parse
@@ -38,13 +38,13 @@ module CombinePDF
38
38
  # use, for example:
39
39
  # pdf.info[:Title] = "title"
40
40
  attr_reader :info
41
- # sets the string output format (PDF files store strings in to type of formats).
41
+ # gets/sets the string output format (PDF files store strings in to type of formats).
42
42
  #
43
43
  # Accepts:
44
44
  # - :literal
45
45
  # - :hex
46
46
  attr_accessor :string_output
47
- # A Float attrinute, setting and returning the PDF version of the file (1.1-1.7).
47
+ # set/get the PDF version of the file (1.1-1.7) - shuold be type Float.
48
48
  attr_accessor :version
49
49
  def initialize (*args)
50
50
  # default before setting
@@ -139,8 +139,18 @@ module CombinePDF
139
139
  # This method also adds the << operator to each page instance, so that content can be
140
140
  # injected to the pages, as described above.
141
141
  #
142
+ # if the secure_injection is false, then the << operator will not alter the any of the information added to the page.
143
+ # this might cause conflicts in the added content, but is available for situations in which
144
+ # the content added is compressed using unsupported filters or options.
145
+ #
146
+ # the default is for the << operator to attempt a secure copy, by attempting to rename the content references and avoiding conflicts.
147
+ # because of not all PDF files are created equal (some might have formating errors or differences), it is imposiible to learn if the attempt wa successful.
148
+ #
142
149
  # (page objects are Hash class objects. the << operator is added to the specific instances without changing the class)
143
- def pages(catalogs = nil)
150
+ #
151
+ # catalogs:: a catalog, or an Array of catalog objects. defaults to the existing catalog.
152
+ # secure_injection:: a boolean (true / false) controling the behavior of the << operator.
153
+ def pages(catalogs = nil, secure_injection = true)
144
154
  page_list = []
145
155
  if catalogs == nil
146
156
  catalogs = @objects.select {|obj| obj.is_a?(Hash) && obj[:Type] == :Catalog}
@@ -161,11 +171,20 @@ module CombinePDF
161
171
  case catalogs[:Type]
162
172
  when :Page
163
173
  holder = self
164
- catalogs.define_singleton_method("<<".to_sym) do |obj|
165
- obj = PDFOperations.copy_and_secure_for_injection obj
166
- PDFOperations.inject_to_page self, obj
167
- holder.add_referenced self # add new referenced objects
168
- self
174
+ if secure_injection
175
+ catalogs.define_singleton_method("<<".to_sym) do |obj|
176
+ obj = PDFOperations.copy_and_secure_for_injection obj
177
+ PDFOperations.inject_to_page self, obj
178
+ holder.add_referenced self # add new referenced objects
179
+ self
180
+ end
181
+ else
182
+ catalogs.define_singleton_method("<<".to_sym) do |obj|
183
+ obj = PDFOperations.create_deep_copy obj
184
+ PDFOperations.inject_to_page self, obj
185
+ holder.add_referenced self # add new referenced objects
186
+ self
187
+ end
169
188
  end
170
189
  page_list << catalogs
171
190
  when :Pages
@@ -222,30 +241,62 @@ module CombinePDF
222
241
  end
223
242
 
224
243
  # get the title for the pdf
225
- # The title is stored in the information dictionary and isn't requited
244
+ # The title is stored in the information dictionary and isn't required
226
245
  def title
227
246
  return @info[:Title]
228
247
  end
229
248
  # set the title for the pdf
230
- # The title is stored in the information dictionary and isn't requited
249
+ # The title is stored in the information dictionary and isn't required
231
250
  # new_title:: a string that is the new author value.
232
251
  def title=(new_title = nil)
233
252
  @info[:Title] = new_title
234
253
  end
235
- # get the author value for the pdf
236
- # The author is stored in the information dictionary and isn't requited
254
+ # get the author value for the pdf.
255
+ # The author is stored in the information dictionary and isn't required
237
256
  def author
238
257
  return @info[:Author]
239
258
  end
240
- # set the author for the pdf
241
- # The author is stored in the information dictionary and isn't requited
259
+ # set the author value for the pdf.
260
+ # The author is stored in the information dictionary and isn't required
261
+ #
242
262
  # new_title:: a string that is the new author value.
243
263
  def author=(new_author = nil)
244
264
  @info[:Author] = new_author
245
265
  end
246
266
  end
247
267
  class PDF #:nodoc: all
248
-
268
+ # @private
269
+ # Some PDF objects contain references to other PDF objects.
270
+ #
271
+ # this function adds the references contained in "object", but DOESN'T add the object itself.
272
+ #
273
+ # this is used for internal operations, such as injectng data using the << operator.
274
+ def add_referenced(object)
275
+ # add references but not root
276
+ case
277
+ when object.is_a?(Array)
278
+ object.each {|it| add_referenced(it)}
279
+ when object.is_a?(Hash)
280
+ if object[:is_reference_only] && object[:referenced_object]
281
+ unless @objects.include? object[:referenced_object]
282
+ @objects << object[:referenced_object]
283
+ object[:referenced_object].each do |k, v|
284
+ add_referenced(v) unless k == :Parent
285
+ end
286
+ end
287
+ else
288
+ object.each do |k, v|
289
+ add_referenced(v) unless k == :Parent
290
+ end
291
+ end
292
+ end
293
+ end
294
+ # @private
295
+ # run block of code on evey object (Hash)
296
+ def each_object(&block)
297
+ PDFOperations._each_object(@objects, &block)
298
+ end
299
+ protected
249
300
  # @private
250
301
  # this function returns all the Page objects - regardless of order and even if not cataloged
251
302
  # could be used for finding "lost" pages... but actually rather useless.
@@ -339,31 +390,8 @@ module CombinePDF
339
390
  end
340
391
  end
341
392
 
342
- # @private
343
- def add_referenced(object)
344
- # add references but not root
345
- case
346
- when object.is_a?(Array)
347
- object.each {|it| add_referenced(it)}
348
- when object.is_a?(Hash)
349
- if object[:is_reference_only] && object[:referenced_object]
350
- unless @objects.include? object[:referenced_object]
351
- @objects << object[:referenced_object]
352
- object[:referenced_object].each do |k, v|
353
- add_referenced(v) unless k == :Parent
354
- end
355
- end
356
- else
357
- object.each do |k, v|
358
- add_referenced(v) unless k == :Parent
359
- end
360
- end
361
- end
362
- end
363
393
  # @private
364
394
  def rebuild_catalog(*with_pages)
365
- ##########################
366
- ## Test-Run - How is that done?
367
395
  warn "Re-Building Catalog"
368
396
 
369
397
  # # build page list v.1 Slow but WORKS
@@ -373,7 +401,7 @@ module CombinePDF
373
401
  # page_list = []
374
402
  # PDFOperations._each_object(old_catalogs,false) { |p| page_list << p if p.is_a?(Hash) && p[:Type] == :Page }
375
403
 
376
- # build page list v.2
404
+ # build page list v.2 faster, better, and works
377
405
  # Benchmark testing value: 0.215114
378
406
  page_list = pages
379
407
 
@@ -458,12 +486,6 @@ module CombinePDF
458
486
  # rebuild stream lengths?
459
487
  end
460
488
 
461
- # @private
462
- # run block of code on evey object (Hash)
463
- def each_object(&block)
464
- PDFOperations._each_object(@objects, &block)
465
- end
466
-
467
489
  # @private
468
490
  # the function rerturns true if the reference belongs to the object
469
491
  def compare_reference_values(obj, ref)
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  COURIER_BOLD_METRICS =
5
6
  {"space"=>{:charcode=>32,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  COURIER_BOLDOBLIQUE_METRICS =
5
6
  {"space"=>{:charcode=>32,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  COURIER_OBLIQUE_METRICS =
5
6
  {"space"=>{:charcode=>32,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  COURIER_METRICS =
5
6
  {"space"=>{:charcode=>32,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  HELVETICA_BOLD_METRICS =
5
6
  {"space"=>{:charcode=>32,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  HELVETICA_BOLDOBLIQUE_METRICS =
5
6
  {"space"=>{:charcode=>32,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  HELVETICA_OBLIQUE_METRICS =
5
6
  {"space"=>{:charcode=>32,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  HELVETICA_METRICS =
5
6
  {"space"=>{:charcode=>32,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  METRICS_DICTIONARY = {
4
5
  :"Times-Roman" => TIMES_ROMAN_METRICS,
5
6
  :"Times-Bold" => TIMES_BOLD_METRICS,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  SYMBOL_METRICS =
5
6
  {"space"=>{:charcode=>32,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  TIMES_BOLD_METRICS =
5
6
  {"space"=>{:charcode=>32,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  TIMES_BOLDITALIC_METRICS =
5
6
  {"space"=>{:charcode=>32,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  TIMES_ITALIC_METRICS =
5
6
  {"space"=>{:charcode=>32,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  TIMES_ROMAN_METRICS =
5
6
  {"space"=>{:charcode=>32,
@@ -1,5 +1,6 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
+ protected
3
4
  # with thanks to Jan Krutisch, the creator of the afm gem.
4
5
  ZAPFDINGBATS_METRICS =
5
6
  {"space"=>{:charcode=>32,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: combine_pdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev