combine_pdf 0.0.7 → 0.0.8

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: 6e1bf0dc605e123de2a5e4e809c079c64da812a5
4
- data.tar.gz: a3f744fbab605cb9abd85332566219ab9735e421
3
+ metadata.gz: 51a498d24b46760b925e4127a175868febcdb19a
4
+ data.tar.gz: 653351536fb043e14f94afc14805f488dc612c7a
5
5
  SHA512:
6
- metadata.gz: 73845fbdabd424d02f5c1494df97a2e790d38c0c8575ee78214ab2279ba359bd41533ba9a493e755059904a18bd8ef39e78d574f3eae2ccd60c411733735f942
7
- data.tar.gz: 7bd08ed3ea3131a1170f583e1a2c17eae17b406af1f4cec8d19b6c8cbbc59c36dd651d1e70a848b13be7d0767bad127686f9eae288037eba881517c492505c27
6
+ metadata.gz: c0089692cf609b368631b7e7afd59381c65403a69bfba0e27429cef04224f08074592781500b4e8ecf645ec0b422542920dd620a18e6e5fcdfaf6459d834640e
7
+ data.tar.gz: 95489bd58f7afab15904398fd9d52e3594ab44ce54f75390805c4f87073162d543a2eece82501895ed495fb78b7fe6a908140ed89dcf16fe64c1db009df19fc8
@@ -45,7 +45,7 @@ require "combine_pdf/font_metrics/metrics_dictionary.rb"
45
45
  # you can also add just odd or even pages:
46
46
  # pdf = CombinePDF.new
47
47
  # i = 0
48
- # CombinePDF.new("file.pdf").pages.each do |page
48
+ # CombinePDF.new("file.pdf").pages.each do |page|
49
49
  # i += 1
50
50
  # pdf << page if i.even?
51
51
  # end
@@ -129,6 +129,11 @@ module CombinePDF
129
129
  raise TypeError, "couldn't parse and data, expecting type String" unless data.is_a? String
130
130
  PDF.new( PDFParser.new(data) )
131
131
  end
132
+ # makes a PDFWriter object
133
+ # ::mediabox an Array representing the size of the PDF document. defaults to: [0.0, 0.0, 612.0, 792.0]
134
+ def create_page(mediabox = [0.0, 0.0, 612.0, 792.0])
135
+ PDFWriter.new mediabox
136
+ end
132
137
  end
133
138
 
134
139
 
@@ -25,7 +25,7 @@ module CombinePDF
25
25
  #
26
26
  # Writing on this Page is done using the textbox function.
27
27
  #
28
- # Setting the page dimentions can be either at the new or using the mediabox method.
28
+ # Setting the page dimensions can be either at the new or using the mediabox method.
29
29
  #
30
30
  # the rest of the methods are for internal use.
31
31
  #
@@ -59,25 +59,23 @@ module CombinePDF
59
59
  self[:MediaBox]
60
60
  end
61
61
  # accessor (setter) for the :MediaBox element of the page
62
- # dimentions:: an Array consisting of four numbers (can be floats) setting the size of the media box.
63
- def mediabox=(dimentions = [0.0, 0.0, 612.0, 792.0])
64
- self[:MediaBox] = dimentions
62
+ # dimensions:: an Array consisting of four numbers (can be floats) setting the size of the media box.
63
+ def mediabox=(dimensions = [0.0, 0.0, 612.0, 792.0])
64
+ self[:MediaBox] = dimensions
65
65
  end
66
66
 
67
- # <b>INCOMPLETE</b>
68
- #
69
- # This function, when completed, will add a simple text box to the Page represented by the PDFWriter class.
67
+ # This method adds a simple text box to the Page represented by the PDFWriter class.
70
68
  # This function takes two values:
71
69
  # text:: the text to potin the box.
72
70
  # properties:: a Hash of box properties.
73
71
  # the symbols and values in the properties Hash could be any or all of the following:
74
72
  # x:: the left position of the box.
75
73
  # y:: the BUTTOM position of the box.
76
- # length:: the length of the box.
77
- # height:: the height of the box.
74
+ # length:: the length of the box. negative values will be computed from edge of page. defaults to 0 (end of page).
75
+ # height:: the height of the box. negative values will be computed from edge of page. defaults to 0 (end of page).
78
76
  # text_align:: symbol for horizontal text alignment, can be ":center" (default), ":right", ":left"
79
77
  # text_valign:: symbol for vertical text alignment, can be ":center" (default), ":top", ":buttom"
80
- # font_name:: a Symbol representing one of the 14 standard fonts. defaults to ":Helvetica". the options are:
78
+ # font:: a Symbol representing one of the 14 standard fonts. defaults to ":Helvetica". the options are:
81
79
  # - :"Times-Roman"
82
80
  # - :"Times-Bold"
83
81
  # - :"Times-Italic"
@@ -102,16 +100,15 @@ module CombinePDF
102
100
  # border_width:: border width in PDF units. defaults to nil (none).
103
101
  # box_radius:: border radius in PDF units. defaults to 0 (no corner rounding).
104
102
  # opacity:: textbox opacity, a float between 0 (transparent) and 1 (opaque)
105
- # <b>now on testing mode, defaults are different! box defaults to gray with border and rounding.</b>
106
103
  def textbox(text, properties = {})
107
104
  options = {
108
105
  x: 0,
109
106
  y: 0,
110
- length: -1,
107
+ length: 0,
111
108
  height: -1,
112
109
  text_align: :center,
113
110
  text_valign: :center,
114
- font_name: :Helvetica,
111
+ font: :Helvetica,
115
112
  font_size: :fit_text,
116
113
  max_font_size: nil,
117
114
  font_color: [0,0,0],
@@ -125,12 +122,12 @@ module CombinePDF
125
122
  }
126
123
  options.update properties
127
124
  # reset the length and height to meaningful values, if negative
128
- options[:length] = mediabox[2] - options[:x] if options[:length] < 0
129
- options[:height] = mediabox[3] - options[:y] if options[:height] < 0
125
+ options[:length] = mediabox[2] - options[:x] + options[:length] if options[:length] <= 0
126
+ options[:height] = mediabox[3] - options[:y] + options[:height] if options[:height] <= 0
130
127
  # fit text in box, if requested
131
128
  font_size = options[:font_size]
132
129
  if options[:font_size] == :fit_text
133
- font_size = self.fit_text text, options[:font_name], options[:length], options[:height]
130
+ font_size = self.fit_text text, options[:font], options[:length], options[:height]
134
131
  font_size = options[:max_font_size] if options[:max_font_size] && font_size > options[:max_font_size]
135
132
  end
136
133
 
@@ -215,7 +212,7 @@ module CombinePDF
215
212
  x = options[:x]
216
213
  y = options[:y]
217
214
 
218
- text_size = dimentions_of text, options[:font_name], font_size
215
+ text_size = dimensions_of text, options[:font], font_size
219
216
  if options[:text_align] == :center
220
217
  x = (options[:length] - text_size[0])/2 + x
221
218
  elsif options[:text_align] == :right
@@ -249,7 +246,7 @@ module CombinePDF
249
246
  end
250
247
  # format text object
251
248
  text_stream << "BT\n" # the Begine Text marker
252
- text_stream << PDFOperations._format_name_to_pdf(font options[:font_name]) # Set font name
249
+ text_stream << PDFOperations._format_name_to_pdf(set_font options[:font]) # Set font name
253
250
  text_stream << " #{font_size} Tf\n" # set font size and add font operator
254
251
  text_stream << "#{options[:font_color].join(' ')} rg\n" # sets the color state
255
252
  text_stream << "#{x} #{y} Td\n" # set location for text object
@@ -276,7 +273,7 @@ module CombinePDF
276
273
  end
277
274
  # creates a font object and adds the font to the resources dictionary
278
275
  # returns the name of the font for the content stream.
279
- # font_name:: a Symbol of one of the 14 Type 1 fonts, known as the standard 14 fonts:
276
+ # font:: a Symbol of one of the 14 Type 1 fonts, known as the standard 14 fonts:
280
277
  # - :"Times-Roman"
281
278
  # - :"Times-Bold"
282
279
  # - :"Times-Italic"
@@ -291,7 +288,7 @@ module CombinePDF
291
288
  # - :"Courier-BoldOblique"
292
289
  # - :Symbol
293
290
  # - :ZapfDingbats
294
- def font(font_name = :Helvetica)
291
+ def set_font(font = :Helvetica)
295
292
  # refuse any other fonts that arn't basic standard fonts
296
293
  allow_fonts = [ :"Times-Roman",
297
294
  :"Times-Bold",
@@ -307,16 +304,16 @@ module CombinePDF
307
304
  :"Courier-BoldOblique",
308
305
  :Symbol,
309
306
  :ZapfDingbats ]
310
- raise "add_font(font_name) accepts only one of the 14 standards fonts - wrong font_name!" unless allow_fonts.include? font_name
307
+ raise "set_font(font) accepts only one of the 14 standards fonts - wrong font!" unless allow_fonts.include? font
311
308
  # if the font exists, return it's name
312
309
  resources[:Font] ||= {}
313
310
  resources[:Font].each do |k,v|
314
- if v.is_a?(Hash) && v[:Type] == :Font && v[:BaseFont] == font_name
311
+ if v.is_a?(Hash) && v[:Type] == :Font && v[:BaseFont] == font
315
312
  return k
316
313
  end
317
314
  end
318
315
  # create font object
319
- font_object = { Type: :Font, Subtype: :Type1, BaseFont: font_name}
316
+ font_object = { Type: :Font, Subtype: :Type1, BaseFont: font}
320
317
  # set a secure name for the font
321
318
  name = (SecureRandom.urlsafe_base64(9)).to_sym
322
319
  # add object to reasource
@@ -164,6 +164,12 @@ module CombinePDF
164
164
  return object # objects that aren't Strings, Arrays or Hashes (such as Symbols and Fixnums) aren't pointers in Ruby and are always copied.
165
165
  end
166
166
  end
167
+ # removes id and generation number values, for better comparrison
168
+ # and avoiding object duplication
169
+ # objects:: one or more objects in a PDF file/page.
170
+ def remove_old_ids objects
171
+ _each_object(objects) {|obj| obj.delete(:indirect_reference_id); obj.delete(:indirect_generation_number)}
172
+ end
167
173
  def get_refernced_object(objects_array = [], reference_hash = {})
168
174
  objects_array.each do |stored_object|
169
175
  return stored_object if ( stored_object.is_a?(Hash) &&
@@ -28,7 +28,7 @@ module CombinePDF
28
28
  # you can also add just odd or even pages:
29
29
  # pdf = CombinePDF.new
30
30
  # i = 0
31
- # CombinePDF.new("file.pdf").pages.each do |page
31
+ # CombinePDF.new("file.pdf").pages.each do |page|
32
32
  # i += 1
33
33
  # pdf << page if i.even?
34
34
  # end
@@ -280,12 +280,12 @@ module CombinePDF
280
280
 
281
281
  # and page numbers to the PDF
282
282
  # options:: a Hash of options setting the behavior and format of the page numbers:
283
- # - :number_format a string representing the format for page number. defaults to ' - %d - '.
284
- # - :number_location an Array containing the location for the page numbers, can be :top, :buttom, :top_left, :top_right, :bottom_left, :bottom_right. defaults to [:top, :buttom].
285
- # - :start_at a Fixnum that sets the number for first page number. defaults to 1.
286
- # - :margin_from_height a number (PDF points) for the top and buttom margins. defaults to 45.
287
- # - :margin_from_side a number (PDF points) for the left and right margins. defaults to 15.
288
- # also take all the options for PDFWriter.textbox.
283
+ # - :number_format a string representing the format for page number. defaults to ' - %d - '.
284
+ # - :number_location an Array containing the location for the page numbers, can be :top, :buttom, :top_left, :top_right, :bottom_left, :bottom_right. defaults to [:top, :buttom].
285
+ # - :start_at a Fixnum that sets the number for first page number. defaults to 1.
286
+ # - :margin_from_height a number (PDF points) for the top and buttom margins. defaults to 45.
287
+ # - :margin_from_side a number (PDF points) for the left and right margins. defaults to 15.
288
+ # the options Hash can also take all the options for PDFWriter.textbox.
289
289
  # defaults to font_name: :Helvetica, font_size: 12 and no box (:border_width => 0, :box_color => nil).
290
290
  def number_pages(options = {})
291
291
  opt = {
@@ -293,7 +293,7 @@ module CombinePDF
293
293
  number_location: [:top, :bottom],
294
294
  start_at: 1,
295
295
  font_size: 12,
296
- font_name: :Helvetica,
296
+ font: :Helvetica,
297
297
  margin_from_height: 45,
298
298
  margin_from_side: 15
299
299
  }
@@ -303,17 +303,17 @@ module CombinePDF
303
303
  # create a "stamp" PDF page with the same size as the target page
304
304
  mediabox = page[:MediaBox]
305
305
  stamp = PDFWriter.new mediabox
306
- # set the visible dimentions to the CropBox, if it exists.
306
+ # set the visible dimensions to the CropBox, if it exists.
307
307
  cropbox = page[:CropBox]
308
308
  mediabox = cropbox if cropbox
309
309
  # set stamp text
310
310
  text = opt[:number_format] % page_number
311
311
  # compute locations for text boxes
312
- text_dimantions = stamp.dimentions_of( text, opt[:font_name], opt[:font_size] )
312
+ text_dimantions = stamp.dimensions_of( text, opt[:font], opt[:font_size] )
313
313
  box_width = text_dimantions[0] * 1.2
314
314
  box_height = text_dimantions[1] * 2
315
- opt[:length] ||= box_width
316
- opt[:height] ||= box_height
315
+ opt[:length] = box_width
316
+ opt[:height] = box_height
317
317
  from_height = 45
318
318
  from_side = 15
319
319
  page_width = mediabox[2]
@@ -397,12 +397,20 @@ module CombinePDF
397
397
  object.each {|it| add_referenced(it)}
398
398
  when object.is_a?(Hash)
399
399
  if object[:is_reference_only] && object[:referenced_object]
400
- unless @objects.include? object[:referenced_object]
400
+ found_at = @objects.find_index object[:referenced_object]
401
+ if found_at
402
+ #if the objects are equal, they might still be different objects!
403
+ # so, we need to make sure they are the same object for the pointers to effect id numbering
404
+ # and formatting operations.
405
+ object[:referenced_object] = @objects[found_at]
406
+ else @objects.include? object[:referenced_object]
407
+ #the object wasn't found - add it to the @objects array
401
408
  @objects << object[:referenced_object]
402
409
  object[:referenced_object].each do |k, v|
403
410
  add_referenced(v) unless k == :Parent
404
411
  end
405
412
  end
413
+
406
414
  else
407
415
  object.each do |k, v|
408
416
  add_referenced(v) unless k == :Parent
@@ -458,6 +466,9 @@ module CombinePDF
458
466
  end
459
467
  end
460
468
 
469
+ # when finished, remove the old numbering system and keep only pointers
470
+ PDFOperations.remove_old_ids @objects
471
+
461
472
  # # Version 3
462
473
  # # benchmark 1000.times was 3.568246 sec for pdf = CombinePDF.new "/Users/2Be/Desktop/מוצגים/20121002\ הודעת\ הערעור.pdf" }
463
474
  # # puts Benchmark.measure { 1000.times {pdf.serialize_objects_and_references} }
@@ -1,17 +1,24 @@
1
1
  module CombinePDF
2
2
  class PDFWriter < Hash
3
- # This function calculates the dimentions of a string in a PDF.
3
+ # This function calculates the dimensions of a string in a PDF.
4
4
  #
5
5
  # UNICODE SUPPORT IS MISSING!
6
6
  #
7
7
  # text:: String containing the text for which the demantion box will be calculated.
8
- # font_name:: the font name, from the 14 fonts possible. @see font
8
+ # font:: the font name, from the 14 fonts possible. @see font
9
9
  # size:: the size of the text, as it will be applied in the PDF.
10
- def dimentions_of(text, font_name, size = 1000)
11
- metrics = METRICS_DICTIONARY[font_name]
10
+ def dimensions_of(text, font, size = 1000)
11
+ metrics = METRICS_DICTIONARY[font]
12
12
  metrics_array = []
13
13
  # the following is only good for latin text - unicode support is missing!!!!
14
- text.each_char{|c| metrics_array << (metrics.select {|k,v| v[:charcode] == c.bytes[0].ord}).to_a[0][1] }
14
+ text.each_char do |c|
15
+ metrics_mappings = metrics.select {|k,v| v[:charcode] == c.bytes[0].ord}
16
+ ######
17
+ # need to add unicode support
18
+ # this is a lousy patch that puts the bounds of @ inside...
19
+ metrics_mappings = metrics.select {|k,v| v[:charcode] == "@".ord} if metrics_mappings.empty?
20
+ metrics_array << metrics_mappings.to_a[0][1]
21
+ end
15
22
  max_width = metrics_array.map {|m| m ? m[:wx] : 0} .max
16
23
  height = metrics_array.map {|m| m ? m[:boundingbox][3] : 0} .max
17
24
  height = height - (metrics_array.map {|m| m ? m[:boundingbox][1] : 0} ).min
@@ -59,7 +66,7 @@ module CombinePDF
59
66
  def fit_text(text, font, length, height = 10000000)
60
67
  size = 100000
61
68
  size_array = [size]
62
- metrics = dimentions_of text, font, size
69
+ metrics = dimensions_of text, font, size
63
70
  if metrics[0] > length
64
71
  size_array << size * length/metrics[0]
65
72
  end
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.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev