combine_pdf 0.1.1 → 0.1.2

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: 1415b642f2d84f101f6f444d16191faa35d3a6b9
4
- data.tar.gz: aa872079b6576afd266bcb2b628772e80e33b9b8
3
+ metadata.gz: c5d50f2ddbf6142442857b65ec46d9565ae774e2
4
+ data.tar.gz: caaa8ac30c72919c54d28d21a4d30979a40ff41e
5
5
  SHA512:
6
- metadata.gz: 78ada1b24bc160cc492b272dd31a1115a76dd217baebbac78fc259a077720427c837c053c5fe54cdfab6f84629142a45275629a714f693a6e8416bf47cb3bfa7
7
- data.tar.gz: 03ced7106be2f831f5dc51df810d810f1f8b1828f8d6364800eb4d248764d30a6e67281b5d34d40fdbe5581673e9da1bed7a494f094e4a7ef4d6550c6e2984f2
6
+ metadata.gz: 0814bd7cfdfbd06d58506dc83f2160099bb6741c60625279850b6d8f525fa970228ce99425223a54998136cecff3593e1530bd0e77f5071d931a173bc26128ff
7
+ data.tar.gz: 88230912c86e10a0949c63c0a10b358da411a96a615860bd8c62985c2c62ff4d98a05b0fb5982e9f6fab7a6fb3cd8d049254660d6c1c449e84c5922783cf7552
data/lib/combine_pdf.rb CHANGED
@@ -184,6 +184,114 @@ module CombinePDF
184
184
  PDFWriter.new mediabox
185
185
  end
186
186
 
187
+ # makes a PDF object containing a table
188
+ #
189
+ # all the pages in this PDF object are PDFWriter objects and are
190
+ # writable using the texbox function (should you wish to add a title, or more info)
191
+ #
192
+ # the main intended use of this method is to create indexes (a table of contents) for merged data.
193
+ #
194
+ # example:
195
+ # pdf = CombinePDF.new_table headers: ["header 1", "another header"], table_data: [ ["this is one row", "with two columns"] , ["this is another row", "also two columns", "the third will be ignored"] ]
196
+ # pdf.save "table_file.pdf"
197
+ #
198
+ # accepts a Hash with any of the following keys as well as any of the PDFWriter#textbox options:
199
+ # headers:: an Array of strings with the headers (will be repeated every page).
200
+ # table_data:: as Array of Arrays, each containing a string for each column. the first row sets the number of columns. extra columns will be ignored.
201
+ # font:: a registered or standard font name (see PDFWriter). defaults to nil (:Helvetica).
202
+ # header_font:: a registered or standard font name for the headers (see PDFWriter). defaults to nil (the font for all the table rows).
203
+ # max_font_size:: the maximum font size. if the string doesn't fit, it will be resized. defaults to 14.
204
+ # column_widths:: an array of relative column widths ([1,2] will display only the first two columns, the second twice as big as the first). defaults to nil (even widths).
205
+ # header_color:: the header color. defaults to [0.8, 0.8, 0.8] (light gray).
206
+ # main_color:: main row color. defaults to nil (transparent / white).
207
+ # alternate_color: alternate row color. defaults to [0.95, 0.95, 0.95] (very light gray).
208
+ # font_color: font color. defaults to [0,0,0] (black).
209
+ # border_color: border color. defaults to [0,0,0] (black).
210
+ # border_width: border width in PDF units. defaults to 1.
211
+ # header_align: the header text alignment within each column (:right, :left, :center). defaults to :center.
212
+ # row_align:: the row text alignment within each column. defaults to :left (:right for RTL table).
213
+ # direction: the table's writing direction (:ltr or :rtl). this reffers to the direction of the columns and doesn't effect text (rtl text is automatically recognized). defaults to :ltr.
214
+ # rows_per_page: the number of rows per page, INCLUDING the header row. deafults to 25.
215
+ # page_size: the size of the page in PDF points. defaults to [0, 0, 595.3, 841.9] (A4).
216
+ def new_table (options = {})
217
+ defaults = {
218
+ headers: nil,
219
+ table_data: [[]],
220
+ font: nil,
221
+ header_font: nil,
222
+ max_font_size: 14,
223
+ column_widths: nil,
224
+ header_color: [0.8, 0.8, 0.8],
225
+ main_color: nil,
226
+ alternate_color: [0.95, 0.95, 0.95],
227
+ font_color: [0,0,0],
228
+ border_color: [0,0,0],
229
+ border_width: 1,
230
+ header_align: :center,
231
+ row_align: nil,
232
+ direction: :ltr,
233
+ rows_per_page: 25,
234
+ page_size: [0, 0, 595.3, 841.9] #A4
235
+ }
236
+ options = defaults.merge options
237
+ options[:header_font] = options[:font] unless options[:header_font]
238
+ options[:row_align] ||= ( (options[:direction] == :rtl) ? :right : :left )
239
+ # assert table_data is an array of arrays
240
+ return false unless (options[:table_data].select {|r| !r.is_a?(Array) }).empty?
241
+ # compute sizes
242
+ page_size = options[:page_size]
243
+ top = page_size[3] * 0.9
244
+ height = page_size[3] * 0.8 / options[:rows_per_page]
245
+ from_side = page_size[2] * 0.1
246
+ width = page_size[2] * 0.8
247
+ columns = options[:table_data][0].length
248
+ column_widths = []
249
+ columns.times {|i| column_widths << (width/columns) }
250
+ if options[:column_widths]
251
+ scale = 0
252
+ options[:column_widths].each {|w| scale += w}
253
+ column_widths = []
254
+ options[:column_widths].each { |w| column_widths << (width*w/scale) }
255
+ end
256
+ column_widths = column_widths.reverse if options[:direction] == :rtl
257
+ # set pdf object and start writing the data
258
+ table = PDF.new()
259
+ page = nil
260
+ rows_per_page = options[:rows_per_page]
261
+ row_number = rows_per_page + 1
262
+
263
+ options[:table_data].each do |row_data|
264
+ if row_number > rows_per_page
265
+ page = create_page page_size
266
+ table << page
267
+ row_number = 1
268
+ # add headers
269
+ if options[:headers]
270
+ x = from_side
271
+ headers = options[:headers]
272
+ headers = headers.reverse if options[:direction] == :rtl
273
+ column_widths.each_index do |i|
274
+ text = headers[i].to_s
275
+ page.textbox text, {x: x, y: (top - (height*row_number)), width: column_widths[i], height: height, box_color: options[:header_color], text_align: options[:header_align] }.merge(options).merge({font: options[:header_font]})
276
+ x += column_widths[i]
277
+ end
278
+ row_number += 1
279
+ end
280
+ end
281
+ x = from_side
282
+ row_data = row_data.reverse if options[:direction] == :rtl
283
+ column_widths.each_index do |i|
284
+ text = row_data[i].to_s
285
+ box_color = options[:main_color]
286
+ box_color = options[:alternate_color] if options[:alternate_color] && row_number.odd?
287
+ page.textbox text, {x: x, y: (top - (height*row_number)), width: column_widths[i], height: height, box_color: box_color, text_align: options[:row_align]}.merge(options)
288
+ x += column_widths[i]
289
+ end
290
+ row_number += 1
291
+ end
292
+ table
293
+ end
294
+
187
295
  # adds a correctly formatted font object to the font library.
188
296
  #
189
297
  # registered fonts will remain in the library and will only be embeded in
@@ -72,6 +72,7 @@ module CombinePDF
72
72
  # height:: the height of the box. negative values will be computed from edge of page. defaults to 0 (end of page).
73
73
  # text_align:: symbol for horizontal text alignment, can be ":center" (default), ":right", ":left"
74
74
  # text_valign:: symbol for vertical text alignment, can be ":center" (default), ":top", ":buttom"
75
+ # text_padding:: a Float between 0 and 1, setting the padding for the text. defaults to 0.05 (5%).
75
76
  # font:: a registered font name or an Array of names. defaults to ":Helvetica". The 14 standard fonts names are:
76
77
  # - :"Times-Roman"
77
78
  # - :"Times-Bold"
@@ -105,6 +106,7 @@ module CombinePDF
105
106
  height: -1,
106
107
  text_align: :center,
107
108
  text_valign: :center,
109
+ text_padding: 0.1,
108
110
  font: nil,
109
111
  font_size: :fit_text,
110
112
  max_font_size: nil,
@@ -122,6 +124,9 @@ module CombinePDF
122
124
  options[:width] = mediabox[2] - options[:x] + options[:width] if options[:width] <= 0
123
125
  options[:height] = mediabox[3] - options[:y] + options[:height] if options[:height] <= 0
124
126
 
127
+ # reset the padding value
128
+ options[:text_padding] = 0 if options[:text_padding].to_f >= 1
129
+
125
130
  # create box stream
126
131
  box_stream = ""
127
132
  # set graphic state for box
@@ -199,29 +204,29 @@ module CombinePDF
199
204
  text_stream = ""
200
205
  if text.to_s != "" && options[:font_size] != 0 && (options[:font_color] || options[:stroke_color])
201
206
  # compute x and y position for text
202
- x = options[:x]
203
- y = options[:y]
207
+ x = options[:x] + (options[:width]*options[:text_padding])
208
+ y = options[:y] + (options[:height]*options[:text_padding])
204
209
 
205
210
  # set the fonts (fonts array, with :Helvetica as fallback).
206
211
  fonts = [*options[:font], :Helvetica]
207
212
  # fit text in box, if requested
208
213
  font_size = options[:font_size]
209
214
  if options[:font_size] == :fit_text
210
- font_size = self.fit_text text, fonts, options[:width], options[:height]
215
+ font_size = self.fit_text text, fonts, (options[:width]*(1-options[:text_padding])), (options[:height]*(1-options[:text_padding]))
211
216
  font_size = options[:max_font_size] if options[:max_font_size] && font_size > options[:max_font_size]
212
217
  end
213
218
 
214
219
  text_size = dimensions_of text, fonts, font_size
215
220
 
216
221
  if options[:text_align] == :center
217
- x = (options[:width] - text_size[0])/2 + x
222
+ x = ( ( options[:width]*(1-(2*options[:text_padding])) ) - text_size[0] )/2 + x
218
223
  elsif options[:text_align] == :right
219
- x = (options[:width] - text_size[0]) + x
224
+ x = ( ( options[:width]*(1-(1.5*options[:text_padding])) ) - text_size[0] ) + x
220
225
  end
221
226
  if options[:text_valign] == :center
222
- y = (options[:height] - text_size[1])/2 + y
227
+ y = ( ( options[:height]*(1-(2*options[:text_padding])) ) - text_size[1] )/2 + y
223
228
  elsif options[:text_valign] == :top
224
- y = (options[:height] - text_size[1]) + y
229
+ y = ( options[:height]*(1-(1.5*options[:text_padding])) ) - text_size[1] + y
225
230
  end
226
231
 
227
232
  # set graphic state for text
@@ -217,7 +217,11 @@ module CombinePDF
217
217
  old_widths = font_object[:DescendantFonts]
218
218
  old_widths = old_widths[:referenced_object][:indirect_without_dictionary] if old_widths[:is_reference_only]
219
219
  old_widths = old_widths[0][:referenced_object]
220
- avarage_bbox = [0, 0, 0, 0] # data is missing for full box metrics, just ignore
220
+ avrg_height = 360
221
+ avrg_height = old_widths[:XHeight] if old_widths[:XHeight]
222
+ avrg_height = (avrg_height + old_widths[:CapHeight])/2 if old_widths[:CapHeight]
223
+ avrg_width = old_widths[:AvgWidth] || 0
224
+ avarage_bbox = [0, 0, avrg_width, avrg_height] # data is missing for full box metrics, just ignore
221
225
  end
222
226
 
223
227
  # compute the metrics values using the appropiate system (TrueType vs. Type0 fonts)
@@ -87,17 +87,32 @@ module CombinePDF
87
87
  @info = {}
88
88
  if args[0].is_a? PDFParser
89
89
  @objects = args[0].parse
90
+ # connecting references with original objects
91
+ serialize_objects_and_references
92
+ # make sure there is only one Catalog (the latest Catalog)
93
+ if args[0].root_object[:Root]
94
+ @objects.delete_if {|obj| obj[:Type] == :Catalog}
95
+ @objects << args[0].root_object[:Root]
96
+ else
97
+ last_calalog = (@objects.select {|obj| obj[:Type] == :Catalog}).last
98
+ unless last_calalog.nil?
99
+ @objects.delete_if {|obj| obj[:Type] == :Catalog}
100
+ @objects << last_calalog
101
+ end
102
+ end
90
103
  @version = args[0].version if args[0].version.is_a? Float
91
104
  @info = args[0].info_object || {}
92
105
  elsif args[0].is_a? Array
93
106
  # object initialization
94
107
  @objects = args[0]
95
108
  @version = args[1] if args[1].is_a? Float
109
+ # connecting references with original objects
110
+ serialize_objects_and_references
96
111
  elsif args[0].is_a? Hash
97
112
  @objects = args
113
+ # connecting references with original objects
114
+ serialize_objects_and_references
98
115
  end
99
- # connecting references with original objects
100
- serialize_objects_and_references
101
116
  # general globals
102
117
  @string_output = :literal
103
118
  @need_to_rebuild_resources = false
@@ -224,6 +239,10 @@ module CombinePDF
224
239
  self
225
240
  end
226
241
  end
242
+ catalogs[:MediaBox] ||= catalogs[:Parent][:referenced_object][:MediaBox] if catalogs[:Parent].is_a?(Hash) && catalogs[:Parent][:referenced_object].is_a?(Hash) && catalogs[:Parent][:referenced_object][:MediaBox]
243
+ catalogs[:CropBox] ||= catalogs[:Parent][:referenced_object][:CropBox] if catalogs[:CropBox].is_a?(Hash) && catalogs[:CropBox][:referenced_object].is_a?(Hash) && catalogs[:Parent][:referenced_object][:CropBox]
244
+ catalogs[:MediaBox] = catalogs[:MediaBox][:referenced_object][:indirect_without_dictionary] if catalogs[:MediaBox].is_a?(Hash) && catalogs[:MediaBox][:referenced_object].is_a?(Hash) && catalogs[:MediaBox][:referenced_object][:indirect_without_dictionary]
245
+ catalogs[:CropBox] = catalogs[:CropBox][:referenced_object][:indirect_without_dictionary] if catalogs[:CropBox].is_a?(Hash) && catalogs[:CropBox][:referenced_object].is_a?(Hash) && catalogs[:CropBox][:referenced_object][:indirect_without_dictionary]
227
246
  page_list << catalogs
228
247
  when :Pages
229
248
  page_list.push *(pages(catalogs[:Kids])) unless catalogs[:Kids].nil?
@@ -330,11 +349,8 @@ module CombinePDF
330
349
  page_number = opt[:start_at]
331
350
  pages.each do |page|
332
351
  # create a "stamp" PDF page with the same size as the target page
333
- mediabox = page[:MediaBox]
352
+ mediabox = page[:CropBox] || page[:MediaBox] || [0, 0, 595.3, 841.9]
334
353
  stamp = PDFWriter.new mediabox
335
- # set the visible dimensions to the CropBox, if it exists.
336
- cropbox = page[:CropBox]
337
- mediabox = cropbox if cropbox
338
354
  # set stamp text
339
355
  text = opt[:number_format] % page_number
340
356
  # compute locations for text boxes
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.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-09-13 00:00:00.000000000 Z
12
+ date: 2014-09-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ruby-rc4