mack-pdf_writer 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/gems/archive-tar-minitar-0.5.2/bin/minitar +27 -0
- data/lib/gems/archive-tar-minitar-0.5.2/lib/archive/tar/minitar/command.rb +814 -0
- data/lib/gems/archive-tar-minitar-0.5.2/lib/archive/tar/minitar.rb +979 -0
- data/lib/gems/color-1.4.0/lib/color/cmyk.rb +281 -0
- data/lib/gems/color-1.4.0/lib/color/css.rb +30 -0
- data/lib/gems/color-1.4.0/lib/color/grayscale.rb +214 -0
- data/lib/gems/color-1.4.0/lib/color/hsl.rb +223 -0
- data/lib/gems/color-1.4.0/lib/color/palette/adobecolor.rb +274 -0
- data/lib/gems/color-1.4.0/lib/color/palette/gimp.rb +118 -0
- data/lib/gems/color-1.4.0/lib/color/palette/monocontrast.rb +182 -0
- data/lib/gems/color-1.4.0/lib/color/palette.rb +18 -0
- data/lib/gems/color-1.4.0/lib/color/rgb/metallic.rb +45 -0
- data/lib/gems/color-1.4.0/lib/color/rgb-colors.rb +357 -0
- data/lib/gems/color-1.4.0/lib/color/rgb.rb +455 -0
- data/lib/gems/color-1.4.0/lib/color/yiq.rb +86 -0
- data/lib/gems/color-1.4.0/lib/color.rb +147 -0
- data/lib/gems/pdf-writer-1.1.8/bin/techbook +24 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/charts/stddev.rb +430 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/charts.rb +13 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/math.rb +108 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/quickref.rb +332 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/simpletable.rb +947 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/techbook.rb +901 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/arc4.rb +63 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fontmetrics.rb +203 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/Courier-Bold.afm +342 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/Courier-BoldOblique.afm +342 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/Courier-Oblique.afm +342 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/Courier.afm +342 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/Helvetica-Bold.afm +2827 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/Helvetica-BoldOblique.afm +2827 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/Helvetica-Oblique.afm +3051 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/Helvetica.afm +3051 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/MustRead.html +19 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/Symbol.afm +213 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/Times-Bold.afm +2588 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/Times-BoldItalic.afm +2384 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/Times-Italic.afm +2667 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/Times-Roman.afm +2419 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/fonts/ZapfDingbats.afm +225 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/graphics/imageinfo.rb +365 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/graphics.rb +813 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/lang/en.rb +99 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/lang.rb +43 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/action.rb +35 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/annotation.rb +42 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/catalog.rb +39 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/contents.rb +65 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/destination.rb +40 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/encryption.rb +53 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/font.rb +72 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/fontdescriptor.rb +34 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/fontencoding.rb +40 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/image.rb +304 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/info.rb +51 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/outline.rb +30 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/outlines.rb +30 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/page.rb +195 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/pages.rb +115 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/procset.rb +46 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object/viewerpreferences.rb +74 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/object.rb +23 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/ohash.rb +58 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/oreader.rb +25 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/state.rb +48 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer/strokestyle.rb +138 -0
- data/lib/gems/pdf-writer-1.1.8/lib/pdf/writer.rb +2729 -0
- data/lib/gems/transaction-simple-1.4.0/lib/transaction/simple/group.rb +146 -0
- data/lib/gems/transaction-simple-1.4.0/lib/transaction/simple/threadsafe/group.rb +36 -0
- data/lib/gems/transaction-simple-1.4.0/lib/transaction/simple/threadsafe.rb +68 -0
- data/lib/gems/transaction-simple-1.4.0/lib/transaction/simple.rb +486 -0
- data/lib/gems.rb +13 -0
- data/lib/mack-pdf_writer.rb +2 -0
- metadata +111 -16
@@ -0,0 +1,947 @@
|
|
1
|
+
#--
|
2
|
+
# PDF::Writer for Ruby.
|
3
|
+
# http://rubyforge.org/projects/ruby-pdf/
|
4
|
+
# Copyright 2003 - 2005 Austin Ziegler.
|
5
|
+
#
|
6
|
+
# Licensed under a MIT-style licence. See LICENCE in the main distribution
|
7
|
+
# for full licensing information.
|
8
|
+
#
|
9
|
+
# $Id: simpletable.rb 186 2007-12-10 22:58:48Z sandal $
|
10
|
+
#++
|
11
|
+
require 'pdf/writer'
|
12
|
+
require 'transaction/simple/group'
|
13
|
+
|
14
|
+
# This class will create tables with a relatively simple API and internal
|
15
|
+
# implementation.
|
16
|
+
class PDF::SimpleTable
|
17
|
+
|
18
|
+
include Transaction::Simple
|
19
|
+
|
20
|
+
# Defines formatting options for a column.
|
21
|
+
class Column
|
22
|
+
def initialize(name)
|
23
|
+
@name = name
|
24
|
+
|
25
|
+
yield self if block_given?
|
26
|
+
end
|
27
|
+
|
28
|
+
# The heading of the column. This should be an instance of
|
29
|
+
# PDF::SimpleTable::Column::Heading. If it is not, it will be
|
30
|
+
# converted into one.
|
31
|
+
attr_accessor :heading
|
32
|
+
def heading=(hh) #:nodoc:
|
33
|
+
unless hh.kind_of?(Heading)
|
34
|
+
hh = Heading.new(hh)
|
35
|
+
end
|
36
|
+
@heading = hh
|
37
|
+
end
|
38
|
+
# The name of the column.
|
39
|
+
attr_reader :name
|
40
|
+
# The width of the column. If this value is set, the column will be
|
41
|
+
# exactly this number of units wide.
|
42
|
+
attr_accessor :width
|
43
|
+
# The data name that will be used to provide a hyperlink for values in
|
44
|
+
# this column.
|
45
|
+
attr_accessor :link_name
|
46
|
+
# The justification of the column. May be :left, :right, :center, or
|
47
|
+
# :full.
|
48
|
+
attr_accessor :justification
|
49
|
+
|
50
|
+
# Formatting options for heading rows. Each column can have a separate
|
51
|
+
# heading value.
|
52
|
+
class Heading
|
53
|
+
def initialize(title = nil)
|
54
|
+
@title = title
|
55
|
+
yield self if block_given?
|
56
|
+
end
|
57
|
+
|
58
|
+
# Indicates that the heading should be rendered bold.
|
59
|
+
attr_accessor :bold
|
60
|
+
# The justification of the heading of the column. May be :left,
|
61
|
+
# :center, :right, or :full.
|
62
|
+
attr_accessor :justification
|
63
|
+
# The title of the heading. If nothing is present, the name of the
|
64
|
+
# column will be used when headings are displayed.
|
65
|
+
attr_accessor :title
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def initialize
|
70
|
+
@column_order = []
|
71
|
+
@data = []
|
72
|
+
@columns = {}
|
73
|
+
|
74
|
+
@show_lines = :outer
|
75
|
+
@show_headings = true
|
76
|
+
@shade_rows = :shaded
|
77
|
+
@shade_color = Color::RGB::Grey80
|
78
|
+
@shade_color2 = Color::RGB::Grey70
|
79
|
+
@shade_headings = false
|
80
|
+
@shade_heading_color = Color::RGB::Grey90
|
81
|
+
@font_size = 10
|
82
|
+
@heading_font_size = 12
|
83
|
+
@title_font_size = 12
|
84
|
+
@title_gap = 5
|
85
|
+
@title_color = Color::RGB::Black
|
86
|
+
@heading_color = Color::RGB::Black
|
87
|
+
@text_color = Color::RGB::Black
|
88
|
+
@line_color = Color::RGB::Black
|
89
|
+
@position = :center
|
90
|
+
@orientation = :center
|
91
|
+
@bold_headings = false
|
92
|
+
|
93
|
+
@cols = PDF::Writer::OHash.new
|
94
|
+
@width = 0
|
95
|
+
@maximum_width = 0
|
96
|
+
|
97
|
+
@gap = 5
|
98
|
+
@row_gap = 2
|
99
|
+
@column_gap = 5
|
100
|
+
@header_gap = 0
|
101
|
+
|
102
|
+
@minimum_space = 0
|
103
|
+
@protect_rows = 1
|
104
|
+
@split_rows = false
|
105
|
+
|
106
|
+
@inner_line_style = PDF::Writer::StrokeStyle.new(1)
|
107
|
+
@outer_line_style = PDF::Writer::StrokeStyle.new(1)
|
108
|
+
|
109
|
+
yield self if block_given?
|
110
|
+
end
|
111
|
+
|
112
|
+
# An array of Hash entries. Each row is a Hash where the keys are the
|
113
|
+
# names of the columns as specified in #column_order and the values are
|
114
|
+
# the values of the cell.
|
115
|
+
attr_accessor :data
|
116
|
+
# An array that defines the order of the columns in the table. The
|
117
|
+
# values in this array are the column names in #data. The columns will
|
118
|
+
# be presented in the order defined here.
|
119
|
+
attr_accessor :column_order
|
120
|
+
# An array that defines columns and column options for the table. The
|
121
|
+
# entries should be PDF::SimpleTable::Column objects.
|
122
|
+
attr_accessor :columns
|
123
|
+
|
124
|
+
# The title to be put on the top of the table.
|
125
|
+
attr_accessor :title
|
126
|
+
|
127
|
+
# Whether to display the lines on the table or not. Valid values are:
|
128
|
+
#
|
129
|
+
# <tt>:none</tt>:: Displays no lines.
|
130
|
+
# <tt>:outer</tt>:: Displays outer lines only. *Default*
|
131
|
+
# <tt>:inner</tt>:: Displays inner lines only.
|
132
|
+
# <tt>:all</tt>:: Displays all lines, inner and outer.
|
133
|
+
attr_accessor :show_lines
|
134
|
+
# Displays the headings for the table if +true+. The default is +true+.
|
135
|
+
attr_accessor :show_headings
|
136
|
+
# Controls row shading.
|
137
|
+
#
|
138
|
+
# <tt>:none</tt>:: No row shading; all rows are the standard
|
139
|
+
# background colour.
|
140
|
+
# <tt>:shaded</tt>:: Alternate lines will be shaded; half of the rows
|
141
|
+
# will be the standard background colour; the rest
|
142
|
+
# of the rows will be shaded with #shade_color.
|
143
|
+
# *Default*
|
144
|
+
# <tt>:striped</tt>:: Alternate lines will be shaded; half of the rows
|
145
|
+
# will be shaded with #shade_color; the rest of the
|
146
|
+
# rows will be shaded with #shade_color2.
|
147
|
+
attr_accessor :shade_rows
|
148
|
+
# The main row shading colour. Defaults to Color::RGB::Grey80. Used with
|
149
|
+
# #shade_rows of <tt>:shaded</tt> and <tt>:striped</tt>.
|
150
|
+
attr_accessor :shade_color
|
151
|
+
# The alternate row shading colour, used with #shade_rows of
|
152
|
+
# <tt>:striped</tt>. Defaults to Color::RGB::Grey70.
|
153
|
+
attr_accessor :shade_color2
|
154
|
+
# Places a background colour in the heading if +true+.
|
155
|
+
attr_accessor :shade_headings
|
156
|
+
# Defines the colour of the background shading for the heading if
|
157
|
+
# #shade_headings is +true+. Default is Color::RGB::Grey90.
|
158
|
+
attr_accessor :shade_heading_color
|
159
|
+
# The font size of the data cells, in points. Defaults to 10 points.
|
160
|
+
attr_accessor :font_size
|
161
|
+
# The font size of the heading cells, in points. Defaults to 12 points.
|
162
|
+
attr_accessor :heading_font_size
|
163
|
+
# The font size of the title, in points. Defaults to 12 points.
|
164
|
+
attr_accessor :title_font_size
|
165
|
+
# The gap, in PDF units, between the title and the table. Defaults to 5
|
166
|
+
# units.
|
167
|
+
attr_accessor :title_gap
|
168
|
+
# The text colour of the title. Defaults to Color::RGB::Black.
|
169
|
+
attr_accessor :title_color
|
170
|
+
# The text colour of the heading. Defaults to Color::RGB::Black.
|
171
|
+
attr_accessor :heading_color
|
172
|
+
# The text colour of the body cells. Defaults to Color::RGB::Black.
|
173
|
+
attr_accessor :text_color
|
174
|
+
# The colour of the table lines. Defaults to Color::RGB::Black.
|
175
|
+
attr_accessor :line_color
|
176
|
+
# The +x+ position of the table. This will be one of:
|
177
|
+
#
|
178
|
+
# <tt>:left</tt>:: Aligned with the left margin.
|
179
|
+
# <tt>:right</tt>:: Aligned with the right margin.
|
180
|
+
# <tt>:center</tt>:: Centered between the margins. *Default*.
|
181
|
+
# <em>offset</em>:: The absolute position of the table, relative from
|
182
|
+
# the left margin.
|
183
|
+
attr_accessor :position
|
184
|
+
# The orientation of the table relative to #position.
|
185
|
+
#
|
186
|
+
# <tt>:left</tt>:: The table is to the left of #position.
|
187
|
+
# <tt>:right</tt>:: The table is to the right of #position.
|
188
|
+
# <tt>:center</tt>:: The table is centred at #position.
|
189
|
+
# <em>offset</em>:: The left of the table is offset from #position.
|
190
|
+
attr_accessor :orientation
|
191
|
+
# Makes the heading text bold if +true+. Defaults to +false+.
|
192
|
+
attr_accessor :bold_headings
|
193
|
+
# Specifies the width of the table. If the table is smaller than the
|
194
|
+
# provided width, columns are proportionally stretched to fit the width
|
195
|
+
# of the table. If the table is wider than the provided width, columns
|
196
|
+
# are proportionally shrunk to fit the width of the table. Content may
|
197
|
+
# need to wrap in this case.
|
198
|
+
#
|
199
|
+
# Defaults to zero, which indicates that the size whould be determined
|
200
|
+
# automatically based on the content and the margins.
|
201
|
+
attr_accessor :width
|
202
|
+
# Specifies the maximum width of the table. The table will not grow
|
203
|
+
# larger than this width under any circumstances.
|
204
|
+
#
|
205
|
+
# Defaults to zero, which indicates that there is no maximum width
|
206
|
+
# (aside from the margin size).
|
207
|
+
attr_accessor :maximum_width
|
208
|
+
# The space, in PDF user units, added to the top and bottom of each row
|
209
|
+
# between the text and the lines of the cell. Default 2 units.
|
210
|
+
attr_accessor :row_gap
|
211
|
+
# The space, in PDF user units, on the left and right sides of each
|
212
|
+
# cell. Default 5 units.
|
213
|
+
attr_accessor :column_gap
|
214
|
+
|
215
|
+
# The minimum space between the bottom of each row and the bottom
|
216
|
+
# margin. If the amount of space is less than this, a new page will be
|
217
|
+
# started. Default is 100 PDF user units.
|
218
|
+
attr_accessor :minimum_space
|
219
|
+
# The number of rows to hold with the heading on the page. If there are
|
220
|
+
# less than this number of rows on the page, then move the whole lot
|
221
|
+
# onto the next page. Default is one row.
|
222
|
+
attr_accessor :protect_rows
|
223
|
+
# Allows a table's rows to be split across page boundaries if +true+.
|
224
|
+
# This defaults to +false+.
|
225
|
+
attr_accessor :split_rows
|
226
|
+
# The number of PDF user units to leave open at the top of a page after
|
227
|
+
# a page break. This is typically used for a repeating page header, etc.
|
228
|
+
# Defaults to zero units.
|
229
|
+
attr_accessor :header_gap
|
230
|
+
# Defines the inner line style. The default style is a solid line with a
|
231
|
+
# thickness of 1 unit.
|
232
|
+
attr_accessor :inner_line_style
|
233
|
+
# Defines the outer line style. The default style is a solid line with a
|
234
|
+
# thickness of 1 unit.
|
235
|
+
attr_accessor :outer_line_style
|
236
|
+
|
237
|
+
# Render the table on the PDF::Writer document provided.
|
238
|
+
def render_on(pdf)
|
239
|
+
if @column_order.empty?
|
240
|
+
raise TypeError, PDF::Writer::Lang[:simpletable_columns_undefined]
|
241
|
+
end
|
242
|
+
if @data.empty?
|
243
|
+
raise TypeError, PDF::Writer::Lang[:simpletable_data_empty]
|
244
|
+
end
|
245
|
+
|
246
|
+
low_y = descender = y0 = y1 = y = nil
|
247
|
+
|
248
|
+
@cols = PDF::Writer::OHash.new
|
249
|
+
@column_order.each do |name|
|
250
|
+
col = @columns[name]
|
251
|
+
if col
|
252
|
+
@cols[name] = col
|
253
|
+
else
|
254
|
+
@cols[name] = PDF::SimpleTable::Column.new(name)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
@gap = 2 * @column_gap
|
259
|
+
|
260
|
+
max_width = __find_table_max_width__(pdf)
|
261
|
+
pos, t, x, adjustment_width, set_width = __find_table_positions__(pdf, max_width)
|
262
|
+
|
263
|
+
# if max_width is specified, and the table is too wide, and the width
|
264
|
+
# has not been set, then set the width.
|
265
|
+
if @width.zero? and @maximum_width.nonzero? and ((t - x) > @maximum_width)
|
266
|
+
@width = @maximum_width
|
267
|
+
end
|
268
|
+
|
269
|
+
if @width and (adjustment_width > 0) and (set_width < @width)
|
270
|
+
# First find the current widths of the columns involved in this
|
271
|
+
# mystery
|
272
|
+
cols0 = PDF::Writer::OHash.new
|
273
|
+
cols1 = PDF::Writer::OHash.new
|
274
|
+
|
275
|
+
xq = presentWidth = 0
|
276
|
+
last = nil
|
277
|
+
|
278
|
+
pos.each do |name, colpos|
|
279
|
+
if @cols[last].nil? or
|
280
|
+
@cols[last].width.nil? or
|
281
|
+
@cols[last].width <= 0
|
282
|
+
unless last.nil? or last.empty?
|
283
|
+
cols0[last] = colpos - xq - @gap
|
284
|
+
presentWidth += (colpos - xq - @gap)
|
285
|
+
end
|
286
|
+
else
|
287
|
+
cols1[last] = colpos - xq
|
288
|
+
end
|
289
|
+
last = name
|
290
|
+
xq = colpos
|
291
|
+
end
|
292
|
+
|
293
|
+
# cols0 contains the widths of all the columns which are not set
|
294
|
+
needed_width = @width - set_width
|
295
|
+
|
296
|
+
# If needed width is negative then add it equally to each column,
|
297
|
+
# else get more tricky.
|
298
|
+
if presentWidth < needed_width
|
299
|
+
diff = (needed_width - presentWidth) / cols0.size.to_f
|
300
|
+
cols0.each_key { |name| cols0[name] += diff }
|
301
|
+
else
|
302
|
+
cnt = 0
|
303
|
+
loop do
|
304
|
+
break if (presentWidth <= needed_width) or (cnt >= 100)
|
305
|
+
cnt += 1 # insurance policy
|
306
|
+
# Find the widest columns and the next to widest width
|
307
|
+
aWidest = []
|
308
|
+
nWidest = widest = 0
|
309
|
+
cols0.each do |name, w|
|
310
|
+
if w > widest
|
311
|
+
aWidest = [ name ]
|
312
|
+
nWidest = widest
|
313
|
+
widest = w
|
314
|
+
elsif w == widest
|
315
|
+
aWidest << name
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
# Then figure out what the width of the widest columns would
|
320
|
+
# have to be to take up all the slack.
|
321
|
+
newWidestWidth = widest - (presentWidth - needed_width) / aWidest.size.to_f
|
322
|
+
if newWidestWidth > nWidest
|
323
|
+
aWidest.each { |name| cols0[name] = newWidestWidth }
|
324
|
+
presentWidth = needed_width
|
325
|
+
else
|
326
|
+
# There is no space, reduce the size of the widest ones down
|
327
|
+
# to the next size down, and we will go round again
|
328
|
+
aWidest.each { |name| cols0[name] = nWidest }
|
329
|
+
presentWidth -= (widest - nWidest) * aWidest.size
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
# cols0 now contains the new widths of the constrained columns. now
|
335
|
+
# need to update the pos and max_width arrays
|
336
|
+
xq = 0
|
337
|
+
pos.each do |name, colpos|
|
338
|
+
pos[name] = xq
|
339
|
+
|
340
|
+
if @cols[name].nil? or
|
341
|
+
@cols[name].width.nil? or
|
342
|
+
@cols[name].width <= 0
|
343
|
+
if not cols0[name].nil?
|
344
|
+
xq += cols0[name] + @gap
|
345
|
+
max_width[name] = cols0[name]
|
346
|
+
end
|
347
|
+
else
|
348
|
+
xq += cols1[name] unless cols1[name].nil?
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
t = x + @width
|
353
|
+
pos[:__last_column__] = t
|
354
|
+
end
|
355
|
+
|
356
|
+
# now adjust the table to the correct location across the page
|
357
|
+
case @position
|
358
|
+
when :left
|
359
|
+
xref = pdf.absolute_left_margin
|
360
|
+
when :right
|
361
|
+
xref = pdf.absolute_right_margin
|
362
|
+
when :center
|
363
|
+
xref = pdf.margin_x_middle
|
364
|
+
else
|
365
|
+
xref = @position
|
366
|
+
end
|
367
|
+
|
368
|
+
case @orientation
|
369
|
+
when :left
|
370
|
+
dx = xref - t
|
371
|
+
when :right
|
372
|
+
dx = xref
|
373
|
+
when :center
|
374
|
+
dx = xref - (t / 2.0)
|
375
|
+
else
|
376
|
+
dx = xref + @orientation
|
377
|
+
end
|
378
|
+
|
379
|
+
pos.each { |k, v| pos[k] = v + dx }
|
380
|
+
|
381
|
+
base_x0 = x0 = x + dx
|
382
|
+
base_x1 = x1 = t + dx
|
383
|
+
|
384
|
+
base_left_margin = pdf.absolute_left_margin
|
385
|
+
base_pos = pos.dup
|
386
|
+
|
387
|
+
# Ok, just about ready to make me a table.
|
388
|
+
pdf.fill_color @text_color
|
389
|
+
pdf.stroke_color @shade_color
|
390
|
+
|
391
|
+
middle = (x0 + x1) / 2.0
|
392
|
+
|
393
|
+
# Start a transaction. This transaction will be used to regress the
|
394
|
+
# table if there are not enough rows protected.
|
395
|
+
tg = Transaction::Simple::Group.new(pdf, self)
|
396
|
+
tg.start_transaction(:table)
|
397
|
+
moved_once = false if @protect_rows.nonzero?
|
398
|
+
|
399
|
+
abortTable = true
|
400
|
+
loop do # while abortTable
|
401
|
+
break unless abortTable
|
402
|
+
abortTable = false
|
403
|
+
|
404
|
+
dm = pdf.absolute_left_margin - base_left_margin
|
405
|
+
base_pos.each { |k, v| pos[k] = v + dm }
|
406
|
+
x0 = base_x0 + dm
|
407
|
+
x1 = base_x1 + dm
|
408
|
+
middle = (x0 + x1) / 2.0
|
409
|
+
|
410
|
+
# If the title is set, then render it.
|
411
|
+
unless @title.nil? or @title.empty?
|
412
|
+
w = pdf.text_width(@title, @title_font_size)
|
413
|
+
_y = pdf.y - pdf.font_height(@title_font_size)
|
414
|
+
if _y < pdf.absolute_bottom_margin
|
415
|
+
pdf.start_new_page
|
416
|
+
|
417
|
+
# margins may have changed on the new page
|
418
|
+
dm = pdf.absolute_left_margin - base_left_margin
|
419
|
+
base_pos.each { |k, v| pos[k] = v + dm }
|
420
|
+
x0 = base_x0 + dm
|
421
|
+
x1 = base_x1 + dm
|
422
|
+
middle = (x0 + x1) / 2.0
|
423
|
+
end
|
424
|
+
|
425
|
+
pdf.y -= pdf.font_height(@title_font_size)
|
426
|
+
pdf.fill_color @title_color
|
427
|
+
pdf.add_text(middle - w / 2.0, pdf.y, title, @title_font_size)
|
428
|
+
pdf.y -= @title_gap
|
429
|
+
end
|
430
|
+
|
431
|
+
# Margins may have changed on the new_page.
|
432
|
+
dm = pdf.absolute_left_margin - base_left_margin
|
433
|
+
base_pos.each { |k, v| pos[k] = v + dm }
|
434
|
+
x0 = base_x0 + dm
|
435
|
+
x1 = base_x1 + dm
|
436
|
+
middle = (x0 + x1) / 2.0
|
437
|
+
|
438
|
+
y = pdf.y # simplifies the code a bit
|
439
|
+
low_y = y if low_y.nil? or y < low_y
|
440
|
+
|
441
|
+
# Make the table
|
442
|
+
height = pdf.font_height @font_size
|
443
|
+
descender = pdf.font_descender @font_size
|
444
|
+
|
445
|
+
y0 = y + descender
|
446
|
+
dy = 0
|
447
|
+
|
448
|
+
if @show_headings
|
449
|
+
# This function will move the start of the table to a new page if
|
450
|
+
# it does not fit on this one.
|
451
|
+
hOID = __open_new_object__(pdf) if @shade_headings
|
452
|
+
pdf.fill_color @heading_color
|
453
|
+
_height, y = __table_column_headings__(pdf, pos, max_width, height,
|
454
|
+
descender, @row_gap, @heading_font_size, y)
|
455
|
+
pdf.fill_color @text_color
|
456
|
+
y0 = y + _height
|
457
|
+
y1 = y
|
458
|
+
|
459
|
+
if @shade_headings
|
460
|
+
pdf.close_object
|
461
|
+
pdf.fill_color! @shade_heading_color
|
462
|
+
pdf.rectangle(x0 - @gap / 2.0, y, x1 - x0, _height).fill
|
463
|
+
pdf.reopen_object(hOID)
|
464
|
+
pdf.close_object
|
465
|
+
pdf.restore_state
|
466
|
+
end
|
467
|
+
|
468
|
+
# Margins may have changed on the new_page
|
469
|
+
dm = pdf.absolute_left_margin - base_left_margin
|
470
|
+
base_pos.each { |k, v| pos[k] = v + dm }
|
471
|
+
x0 = base_x0 + dm
|
472
|
+
x1 = base_x1 + dm
|
473
|
+
middle = (x0 + x1) / 2.0
|
474
|
+
else
|
475
|
+
y1 = y0
|
476
|
+
end
|
477
|
+
|
478
|
+
first_line = true
|
479
|
+
|
480
|
+
# open an object here so that the text can be put in over the
|
481
|
+
# shading
|
482
|
+
tOID = __open_new_object__(pdf) unless :none == @shade_rows
|
483
|
+
|
484
|
+
cnt = 0
|
485
|
+
cnt = 1 unless @shade_headings
|
486
|
+
newPage = false
|
487
|
+
@data.each do |row|
|
488
|
+
cnt += 1
|
489
|
+
# Start a transaction that will be used for this row to prevent it
|
490
|
+
# from being split.
|
491
|
+
unless @split_rows
|
492
|
+
pageStart = pdf.pageset.size
|
493
|
+
|
494
|
+
columnStart = pdf.column_number if pdf.columns?
|
495
|
+
|
496
|
+
tg.start_transaction(:row)
|
497
|
+
row_orig = row
|
498
|
+
y_orig = y
|
499
|
+
y0_orig = y0
|
500
|
+
y1_orig = y1
|
501
|
+
end # unless @split_rows
|
502
|
+
|
503
|
+
ok = false
|
504
|
+
second_turn = false
|
505
|
+
loop do # while !abortTable and !ok
|
506
|
+
break if abortTable or ok
|
507
|
+
|
508
|
+
mx = 0
|
509
|
+
newRow = true
|
510
|
+
|
511
|
+
loop do # while !abortTable and (newPage or newRow)
|
512
|
+
break if abortTable or not (newPage or newRow)
|
513
|
+
|
514
|
+
y -= height
|
515
|
+
low_y = y if low_y.nil? or y < low_y
|
516
|
+
|
517
|
+
if newPage or y < (pdf.absolute_bottom_margin + @minimum_space)
|
518
|
+
# check that enough rows are with the heading
|
519
|
+
moved_once = abortTable = true if @protect_rows.nonzero? and not moved_once and cnt <= @protect_rows
|
520
|
+
|
521
|
+
y2 = y - mx + (2 * height) + descender - (newRow ? 1 : 0) * height
|
522
|
+
|
523
|
+
unless :none == @show_lines
|
524
|
+
y0 = y1 unless @show_headings
|
525
|
+
|
526
|
+
__table_draw_lines__(pdf, pos, @gap, x0, x1, y0, y1, y2,
|
527
|
+
@line_color, @inner_line_style, @outer_line_style,
|
528
|
+
@show_lines)
|
529
|
+
end
|
530
|
+
|
531
|
+
unless :none == @shade_rows
|
532
|
+
pdf.close_object
|
533
|
+
pdf.restore_state
|
534
|
+
end
|
535
|
+
|
536
|
+
pdf.start_new_page
|
537
|
+
pdf.save_state
|
538
|
+
|
539
|
+
# and the margins may have changed, this is due to the
|
540
|
+
# possibility of the columns being turned on as the columns are
|
541
|
+
# managed by manipulating the margins
|
542
|
+
dm = pdf.absolute_left_margin - base_left_margin
|
543
|
+
base_pos.each { |k, v| pos[k] = v + dm }
|
544
|
+
x0 = base_x0 + dm
|
545
|
+
x1 = base_x1 + dm
|
546
|
+
|
547
|
+
tOID = __open_new_object__(pdf) unless :none == @shade_rows
|
548
|
+
|
549
|
+
pdf.fill_color! @text_color
|
550
|
+
|
551
|
+
y = pdf.absolute_top_margin - @header_gap
|
552
|
+
low_y = y
|
553
|
+
y0 = y + descender
|
554
|
+
mx = 0
|
555
|
+
|
556
|
+
if @show_headings
|
557
|
+
old_y = y
|
558
|
+
|
559
|
+
pdf.fill_color @heading_color
|
560
|
+
_height, y = __table_column_headings__(pdf, pos, max_width,
|
561
|
+
height, descender, @row_gap, @heading_font_size, y)
|
562
|
+
pdf.fill_color @text_color
|
563
|
+
|
564
|
+
y0 = y + _height
|
565
|
+
y1 = y
|
566
|
+
|
567
|
+
if @shade_headings
|
568
|
+
pdf.fill_color! @shade_heading_color
|
569
|
+
pdf.rectangle(x0 - @gap / 2, y, x1 - x0, _height).fill
|
570
|
+
pdf.fill_color @heading_color
|
571
|
+
__table_column_headings__(pdf, pos, max_width, height,
|
572
|
+
descender, @row_gap,
|
573
|
+
@heading_font_size, old_y)
|
574
|
+
pdf.fill_color @text_color
|
575
|
+
end
|
576
|
+
|
577
|
+
dm = pdf.absolute_left_margin - base_left_margin
|
578
|
+
base_pos.each { |k, v| pos[k] = v + dm }
|
579
|
+
x0 = base_x0 + dm
|
580
|
+
x1 = base_x1 + dm
|
581
|
+
middle = (x0 + x1) / 2.0
|
582
|
+
else
|
583
|
+
y1 = y0
|
584
|
+
end
|
585
|
+
|
586
|
+
first_line = true
|
587
|
+
y -= height
|
588
|
+
low_y = y if low_y.nil? or y < low_y
|
589
|
+
end
|
590
|
+
|
591
|
+
newRow = false
|
592
|
+
|
593
|
+
# Write the actual data. If these cells need to be split over
|
594
|
+
# a page, then newPage will be set, and the remaining text
|
595
|
+
# will be placed in leftOvers
|
596
|
+
newPage = false
|
597
|
+
leftOvers = PDF::Writer::OHash.new
|
598
|
+
|
599
|
+
@cols.each do |name, column|
|
600
|
+
pdf.pointer = y + height
|
601
|
+
colNewPage = false
|
602
|
+
|
603
|
+
unless row[name].nil?
|
604
|
+
lines = row[name].to_s.split(/\n/)
|
605
|
+
if column and column.link_name
|
606
|
+
lines.map! do |kk|
|
607
|
+
link = row[column.link_name]
|
608
|
+
if link
|
609
|
+
"<c:alink uri='#{link}'>#{kk}</c:alink>"
|
610
|
+
else
|
611
|
+
kk
|
612
|
+
end
|
613
|
+
end
|
614
|
+
end
|
615
|
+
else
|
616
|
+
lines = []
|
617
|
+
end
|
618
|
+
|
619
|
+
pdf.y -= @row_gap
|
620
|
+
|
621
|
+
lines.each do |line|
|
622
|
+
pdf.send(:preprocess_text, line)
|
623
|
+
start = true
|
624
|
+
|
625
|
+
loop do
|
626
|
+
break if (line.nil? or line.empty?) and not start
|
627
|
+
start = false
|
628
|
+
|
629
|
+
_y = pdf.y - height if not colNewPage
|
630
|
+
|
631
|
+
# a new page is required
|
632
|
+
newPage = colNewPage = true if _y < pdf.absolute_bottom_margin
|
633
|
+
|
634
|
+
if colNewPage
|
635
|
+
if leftOvers[name].nil?
|
636
|
+
leftOvers[name] = [line]
|
637
|
+
else
|
638
|
+
leftOvers[name] << "\n#{line}"
|
639
|
+
end
|
640
|
+
line = nil
|
641
|
+
else
|
642
|
+
if column and column.justification
|
643
|
+
just = column.justification
|
644
|
+
end
|
645
|
+
just ||= :left
|
646
|
+
|
647
|
+
pdf.y = _y
|
648
|
+
line = pdf.add_text_wrap(pos[name], pdf.y,
|
649
|
+
max_width[name], line,
|
650
|
+
@font_size, just)
|
651
|
+
end
|
652
|
+
end
|
653
|
+
end
|
654
|
+
|
655
|
+
dy = y + height - pdf.y + @row_gap
|
656
|
+
mx = dy - height * (newPage ? 1 : 0) if (dy - height * (newPage ? 1 : 0)) > mx
|
657
|
+
end
|
658
|
+
|
659
|
+
# Set row to leftOvers so that they will be processed onto the
|
660
|
+
# new page
|
661
|
+
row = leftOvers
|
662
|
+
|
663
|
+
# Now add the shading underneath
|
664
|
+
unless :none == @shade_rows
|
665
|
+
pdf.close_object
|
666
|
+
|
667
|
+
if (cnt % 2).zero?
|
668
|
+
pdf.fill_color!(@shade_color)
|
669
|
+
pdf.rectangle(x0 - @gap / 2.0, y + descender + height - mx, x1 - x0, mx).fill
|
670
|
+
elsif (cnt % 2).nonzero? and :striped == @shade_rows
|
671
|
+
pdf.fill_color!(@shade_color2)
|
672
|
+
pdf.rectangle(x0 - @gap / 2.0, y + descender + height - mx, x1 - x0, mx).fill
|
673
|
+
end
|
674
|
+
pdf.reopen_object(tOID)
|
675
|
+
end
|
676
|
+
|
677
|
+
if :inner == @show_lines or :all == @show_lines
|
678
|
+
# draw a line on the top of the block
|
679
|
+
pdf.save_state
|
680
|
+
pdf.stroke_color! @line_color
|
681
|
+
if first_line
|
682
|
+
pdf.stroke_style @outer_line_style
|
683
|
+
first_line = false
|
684
|
+
else
|
685
|
+
pdf.stroke_style @inner_line_style
|
686
|
+
end
|
687
|
+
pdf.line(x0 - @gap / 2.0, y + descender + height, x1 - @gap / 2.0, y + descender + height).stroke
|
688
|
+
pdf.restore_state
|
689
|
+
end
|
690
|
+
end
|
691
|
+
|
692
|
+
y = y - mx + height
|
693
|
+
pdf.y = y
|
694
|
+
low_y = y if low_y.nil? or y < low_y
|
695
|
+
|
696
|
+
# checking row split over pages
|
697
|
+
unless @split_rows
|
698
|
+
if (((pdf.pageset.size != pageStart) or (pdf.columns? and columnStart != pdf.column_number)) and not second_turn)
|
699
|
+
# then we need to go back and try that again!
|
700
|
+
newPage = second_turn = true
|
701
|
+
tg.rewind_transaction(:row)
|
702
|
+
row = row_orig
|
703
|
+
low_y = y = y_orig
|
704
|
+
y0 = y0_orig
|
705
|
+
y1 = y1_orig
|
706
|
+
ok = false
|
707
|
+
|
708
|
+
dm = pdf.absolute_left_margin - base_left_margin
|
709
|
+
base_pos.each { |k, v| pos[k] = v + dm }
|
710
|
+
x0 = base_x0 + dm
|
711
|
+
x1 = base_x1 + dm
|
712
|
+
else
|
713
|
+
tg.commit_transaction(:row)
|
714
|
+
ok = true
|
715
|
+
end
|
716
|
+
else
|
717
|
+
ok = true # don't go 'round the loop if splitting rows is allowed
|
718
|
+
end
|
719
|
+
end
|
720
|
+
|
721
|
+
if abortTable
|
722
|
+
# abort_transaction if not ok only the outer transaction should
|
723
|
+
# be operational.
|
724
|
+
tg.rewind_transaction(:table)
|
725
|
+
pdf.start_new_page
|
726
|
+
# fix a bug where a moved table will take up the whole page.
|
727
|
+
low_y = nil
|
728
|
+
pdf.save_state
|
729
|
+
break
|
730
|
+
end
|
731
|
+
end
|
732
|
+
end
|
733
|
+
|
734
|
+
if low_y <= y
|
735
|
+
y2 = low_y + descender
|
736
|
+
else
|
737
|
+
y2 = y + descender
|
738
|
+
end
|
739
|
+
|
740
|
+
unless :none == @show_lines
|
741
|
+
y0 = y1 unless @show_headings
|
742
|
+
|
743
|
+
__table_draw_lines__(pdf, pos, @gap, x0, x1, y0, y1, y2, @line_color,
|
744
|
+
@inner_line_style, @outer_line_style, @show_lines)
|
745
|
+
end
|
746
|
+
|
747
|
+
# close the object for drawing the text on top
|
748
|
+
unless :none == @shade_rows
|
749
|
+
pdf.close_object
|
750
|
+
pdf.restore_state
|
751
|
+
end
|
752
|
+
|
753
|
+
pdf.y = low_y
|
754
|
+
|
755
|
+
# Table has been put on the page, the rows guarded as required; commit.
|
756
|
+
tg.commit_transaction(:table)
|
757
|
+
|
758
|
+
y
|
759
|
+
rescue Exception => ex
|
760
|
+
begin
|
761
|
+
tg.abort_transaction(:table) if tg.transaction_open?
|
762
|
+
rescue
|
763
|
+
nil
|
764
|
+
end
|
765
|
+
raise ex
|
766
|
+
end
|
767
|
+
|
768
|
+
WIDTH_FACTOR = 1.01
|
769
|
+
|
770
|
+
# Find the maximum widths of the text within each column. Default to
|
771
|
+
# zero.
|
772
|
+
def __find_table_max_width__(pdf)
|
773
|
+
max_width = PDF::Writer::OHash.new(-1)
|
774
|
+
|
775
|
+
# Find the maximum cell widths based on the data and the headings.
|
776
|
+
# Passing through the data multiple times is unavoidable as we must
|
777
|
+
# do some analysis first.
|
778
|
+
@data.each do |row|
|
779
|
+
@cols.each do |name, column|
|
780
|
+
w = pdf.text_width(row[name].to_s, @font_size)
|
781
|
+
w *= PDF::SimpleTable::WIDTH_FACTOR
|
782
|
+
|
783
|
+
max_width[name] = w if w > max_width[name]
|
784
|
+
end
|
785
|
+
end
|
786
|
+
|
787
|
+
@cols.each do |name, column|
|
788
|
+
title = column.heading.title if column.heading
|
789
|
+
title ||= column.name
|
790
|
+
w = pdf.text_width(title, @heading_font_size)
|
791
|
+
w *= PDF::SimpleTable::WIDTH_FACTOR
|
792
|
+
max_width[name] = w if w > max_width[name]
|
793
|
+
end
|
794
|
+
max_width
|
795
|
+
end
|
796
|
+
private :__find_table_max_width__
|
797
|
+
|
798
|
+
# Calculate the start positions of each of the columns. This is based
|
799
|
+
# on max_width, but may be modified with column options.
|
800
|
+
def __find_table_positions__(pdf, max_width)
|
801
|
+
pos = PDF::Writer::OHash.new
|
802
|
+
x = t = adjustment_width = set_width = 0
|
803
|
+
|
804
|
+
max_width.each do |name, w|
|
805
|
+
pos[name] = t
|
806
|
+
# If the column width has been specified then set that here, also
|
807
|
+
# total the width avaliable for adjustment.
|
808
|
+
if not @cols[name].nil? and
|
809
|
+
not @cols[name].width.nil? and
|
810
|
+
@cols[name].width > 0
|
811
|
+
t += @cols[name].width
|
812
|
+
max_width[name] = @cols[name].width - @gap
|
813
|
+
set_width += @cols[name].width
|
814
|
+
else
|
815
|
+
t += w + @gap
|
816
|
+
adjustment_width += w
|
817
|
+
set_width += @gap
|
818
|
+
end
|
819
|
+
end
|
820
|
+
pos[:__last_column__] = t
|
821
|
+
|
822
|
+
[pos, t, x, adjustment_width, set_width]
|
823
|
+
end
|
824
|
+
private :__find_table_positions__
|
825
|
+
|
826
|
+
# Uses ezText to add the text, and returns the height taken by the
|
827
|
+
# largest heading. This page will move the headings to a new page if
|
828
|
+
# they will not fit completely on this one transaction support will be
|
829
|
+
# used to implement this.
|
830
|
+
def __table_column_headings__(pdf, pos, max_width, height, descender, gap, size, y)
|
831
|
+
mx = second_go = 0
|
832
|
+
start_page = pdf.pageset.size
|
833
|
+
|
834
|
+
# y is the position at which the top of the table should start, so the
|
835
|
+
# base of the first text, is y-height-gap-descender, but ezText starts
|
836
|
+
# by dropping height.
|
837
|
+
|
838
|
+
# The return from this function is the total cell height, including
|
839
|
+
# gaps, and y is adjusted to be the postion of the bottom line.
|
840
|
+
tg = Transaction::Simple::Group.new(pdf, self)
|
841
|
+
tg.start_transaction(:column_headings)
|
842
|
+
|
843
|
+
ok = false
|
844
|
+
y -= gap
|
845
|
+
loop do
|
846
|
+
break if ok
|
847
|
+
@cols.each do |name, column|
|
848
|
+
pdf.pointer = y
|
849
|
+
|
850
|
+
if column.heading
|
851
|
+
justification = column.heading.justification
|
852
|
+
bold = column.heading.bold
|
853
|
+
title = column.heading.title
|
854
|
+
end
|
855
|
+
|
856
|
+
justification ||= :left
|
857
|
+
bold ||= @bold_headings
|
858
|
+
title ||= column.name
|
859
|
+
|
860
|
+
title = "<b>#{title}</b>" if bold
|
861
|
+
|
862
|
+
pdf.text(title, :font_size => size, :absolute_left => pos[name],
|
863
|
+
:absolute_right => (max_width[name] + pos[name]),
|
864
|
+
:justification => justification)
|
865
|
+
dy = y - pdf.y
|
866
|
+
mx = dy if dy > mx
|
867
|
+
end
|
868
|
+
|
869
|
+
y -= (mx + gap) - descender # y = y - mx - gap + descender
|
870
|
+
|
871
|
+
# If this has been moved to a new page, then abort the transaction;
|
872
|
+
# move to a new page, and put it there. Do not check on the second
|
873
|
+
# time around to avoid an infinite loop.
|
874
|
+
if (pdf.pageset.size != start_page and not second_go)
|
875
|
+
tg.rewind_transaction(:column_headings)
|
876
|
+
|
877
|
+
pdf.start_new_page
|
878
|
+
save_state
|
879
|
+
y = @y - gap - descender
|
880
|
+
ok = false
|
881
|
+
second_go = true
|
882
|
+
mx = 0
|
883
|
+
else
|
884
|
+
tg.commit_transaction(:column_headings)
|
885
|
+
ok = true
|
886
|
+
end
|
887
|
+
end
|
888
|
+
|
889
|
+
return [mx + gap * 2 - descender, y]
|
890
|
+
rescue Exception => ex
|
891
|
+
begin
|
892
|
+
tg.abort_transaction(:column_headings) if tg.transaction_open?(:column_headings)
|
893
|
+
rescue
|
894
|
+
nil
|
895
|
+
end
|
896
|
+
raise ex
|
897
|
+
end
|
898
|
+
private :__table_column_headings__
|
899
|
+
|
900
|
+
def __table_draw_lines__(pdf, pos, gap, x0, x1, y0, y1, y2, col, inner, outer, opt = :outer)
|
901
|
+
x0 = 1000
|
902
|
+
x1 = 0
|
903
|
+
|
904
|
+
pdf.stroke_color(col)
|
905
|
+
|
906
|
+
cnt = 0
|
907
|
+
n = pos.size
|
908
|
+
|
909
|
+
pos.each do |name, x|
|
910
|
+
cnt += 1
|
911
|
+
|
912
|
+
if (cnt == 1 or cnt == n)
|
913
|
+
pdf.stroke_style outer
|
914
|
+
else
|
915
|
+
pdf.stroke_style inner
|
916
|
+
end
|
917
|
+
|
918
|
+
pdf.line(x - gap / 2.0, y0, x - gap / 2.0, y2).stroke
|
919
|
+
x1 = x if x > x1
|
920
|
+
x0 = x if x < x0
|
921
|
+
end
|
922
|
+
|
923
|
+
pdf.stroke_style outer
|
924
|
+
|
925
|
+
pdf.line(x0 - (gap / 2.0) - (outer.width / 2.0), y0,
|
926
|
+
x1 - (gap / 2.0) + (outer.width / 2.0), y0).stroke
|
927
|
+
|
928
|
+
# Only do the second line if it is different than the first AND each
|
929
|
+
# row does not have a line on it.
|
930
|
+
if y0 != y1 and @show_lines == :outer
|
931
|
+
pdf.line(x0 - gap / 2.0, y1, x1 - gap / 2.0, y1).stroke
|
932
|
+
end
|
933
|
+
pdf.line(x0 - (gap / 2.0) - (outer.width / 2.0), y2,
|
934
|
+
x1 - (gap / 2.0) + (outer.width / 2.0), y2).stroke
|
935
|
+
end
|
936
|
+
private :__table_draw_lines__
|
937
|
+
|
938
|
+
def __open_new_object__(pdf)
|
939
|
+
pdf.save_state
|
940
|
+
tOID = pdf.open_object
|
941
|
+
pdf.close_object
|
942
|
+
pdf.add_object(tOID)
|
943
|
+
pdf.reopen_object(tOID)
|
944
|
+
tOID
|
945
|
+
end
|
946
|
+
private :__open_new_object__
|
947
|
+
end
|