prawn-table-continued 1.0.0.rc1

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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +2 -0
  3. data/GPLv2 +340 -0
  4. data/GPLv3 +674 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +56 -0
  7. data/lib/prawn/table/cell/image.rb +69 -0
  8. data/lib/prawn/table/cell/in_table.rb +33 -0
  9. data/lib/prawn/table/cell/span_dummy.rb +93 -0
  10. data/lib/prawn/table/cell/subtable.rb +66 -0
  11. data/lib/prawn/table/cell/text.rb +155 -0
  12. data/lib/prawn/table/cell.rb +787 -0
  13. data/lib/prawn/table/cells.rb +261 -0
  14. data/lib/prawn/table/column_width_calculator.rb +182 -0
  15. data/lib/prawn/table/version.rb +5 -0
  16. data/lib/prawn/table.rb +711 -0
  17. data/manual/contents.rb +13 -0
  18. data/manual/example_helper.rb +8 -0
  19. data/manual/images/prawn.png +0 -0
  20. data/manual/images/stef.jpg +0 -0
  21. data/manual/table/basic_block.rb +53 -0
  22. data/manual/table/before_rendering_page.rb +26 -0
  23. data/manual/table/cell_border_lines.rb +24 -0
  24. data/manual/table/cell_borders_and_bg.rb +31 -0
  25. data/manual/table/cell_dimensions.rb +36 -0
  26. data/manual/table/cell_text.rb +38 -0
  27. data/manual/table/column_widths.rb +30 -0
  28. data/manual/table/content_and_subtables.rb +39 -0
  29. data/manual/table/creation.rb +27 -0
  30. data/manual/table/filtering.rb +36 -0
  31. data/manual/table/flow_and_header.rb +17 -0
  32. data/manual/table/image_cells.rb +33 -0
  33. data/manual/table/position.rb +29 -0
  34. data/manual/table/row_colors.rb +20 -0
  35. data/manual/table/span.rb +30 -0
  36. data/manual/table/style.rb +33 -0
  37. data/manual/table/table.rb +52 -0
  38. data/manual/table/width.rb +27 -0
  39. data/prawn-table.gemspec +36 -0
  40. data/spec/cell_spec.rb +652 -0
  41. data/spec/extensions/encoding_helpers.rb +11 -0
  42. data/spec/extensions/file_fixture_helper.rb +15 -0
  43. data/spec/fixtures/files/prawn.png +0 -0
  44. data/spec/spec_helper.rb +50 -0
  45. data/spec/table/span_dummy_spec.rb +26 -0
  46. data/spec/table_spec.rb +1626 -0
  47. metadata +234 -0
data/LICENSE ADDED
@@ -0,0 +1,56 @@
1
+ Prawn is copyrighted free software produced by Gregory Brown along with
2
+ community contributions. See git log for authorship information.
3
+
4
+ Licensing terms follow:
5
+
6
+ You can redistribute Prawn and/or modify it under either the terms of the GPLv2
7
+ or GPLv3 (see GPLv2 and GPLv3 files), or the conditions below:
8
+
9
+ 1. You may make and give away verbatim copies of the source form of the
10
+ software without restriction, provided that you duplicate all of the
11
+ original copyright notices and associated disclaimers.
12
+
13
+ 2. You may modify your copy of the software in any way, provided that
14
+ you do at least ONE of the following:
15
+
16
+ a) place your modifications in the Public Domain or otherwise
17
+ make them Freely Available, such as by posting said
18
+ modifications to Usenet or an equivalent medium, or by allowing
19
+ the author to include your modifications in the software.
20
+
21
+ b) use the modified software only within your corporation or
22
+ organization.
23
+
24
+ c) rename any non-standard executables so the names do not conflict
25
+ with standard executables, which must also be provided.
26
+
27
+ d) make other distribution arrangements with the author.
28
+
29
+ 3. You may distribute the software in object code or executable
30
+ form, provided that you do at least ONE of the following:
31
+
32
+ a) distribute the executables and library files of the software,
33
+ together with instructions (in the manual page or equivalent)
34
+ on where to get the original distribution.
35
+
36
+ b) accompany the distribution with the machine-readable source of
37
+ the software.
38
+
39
+ c) give non-standard executables non-standard names, with
40
+ instructions on where to get the original software distribution.
41
+
42
+ d) make other distribution arrangements with the author.
43
+
44
+ 4. You may modify and include the part of the software into any other
45
+ software (possibly commercial).
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+
3
+ # image.rb: Table image cells.
4
+ #
5
+ # Copyright September 2010, Brad Ediger. All Rights Reserved.
6
+ #
7
+ # This is free software. Please see the LICENSE and COPYING files for details.
8
+ module Prawn
9
+ class Table
10
+ class Cell
11
+
12
+ # @private
13
+ class Image < Cell
14
+
15
+ def initialize(pdf, point, options={})
16
+ @image_options = {}
17
+ super
18
+
19
+ @pdf_object, @image_info = @pdf.build_image_object(@file)
20
+ @natural_width, @natural_height = @image_info.calc_image_dimensions(
21
+ @image_options)
22
+ end
23
+
24
+ def image=(file)
25
+ @file = file
26
+ end
27
+
28
+ def scale=(s)
29
+ @image_options[:scale] = s
30
+ end
31
+
32
+ def fit=(f)
33
+ @image_options[:fit] = f
34
+ end
35
+
36
+ def image_height=(h)
37
+ @image_options[:height] = h
38
+ end
39
+
40
+ def image_width=(w)
41
+ @image_options[:width] = w
42
+ end
43
+
44
+ def position=(p)
45
+ @image_options[:position] = p
46
+ end
47
+
48
+ def vposition=(vp)
49
+ @image_options[:vposition] = vp
50
+ end
51
+
52
+ def natural_content_width
53
+ @natural_width
54
+ end
55
+
56
+ def natural_content_height
57
+ @natural_height
58
+ end
59
+
60
+ # Draw the image on the page.
61
+ #
62
+ def draw_content
63
+ @pdf.embed_image(@pdf_object, @image_info, @image_options)
64
+ end
65
+
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ # Accessors for using a Cell inside a Table.
4
+ #
5
+ # Contributed by Brad Ediger.
6
+ #
7
+ # This is free software. Please see the LICENSE and COPYING files for details.
8
+
9
+ module Prawn
10
+ class Table
11
+
12
+ class Cell
13
+
14
+ # This module extends Cell objects when they are used in a table (as
15
+ # opposed to standalone). Its properties apply to cells-in-tables but not
16
+ # cells themselves.
17
+ #
18
+ # @private
19
+ module InTable
20
+
21
+ # Row number (0-based).
22
+ #
23
+ attr_accessor :row
24
+
25
+ # Column number (0-based).
26
+ #
27
+ attr_accessor :column
28
+
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,93 @@
1
+ # encoding: utf-8
2
+
3
+ # span_dummy.rb: Placeholder for non-master spanned cells.
4
+ #
5
+ # Copyright December 2011, Brad Ediger. All Rights Reserved.
6
+ #
7
+ # This is free software. Please see the LICENSE and COPYING files for details.
8
+ module Prawn
9
+ class Table
10
+ class Cell
11
+
12
+ # A Cell object used to represent all but the topmost cell in a span
13
+ # group.
14
+ #
15
+ # @private
16
+ class SpanDummy < Cell
17
+ def initialize(pdf, master_cell)
18
+ super(pdf, [0, pdf.cursor])
19
+ @master_cell = master_cell
20
+ @padding = [0, 0, 0, 0]
21
+ end
22
+
23
+ # By default, a span dummy will never increase the height demand.
24
+ #
25
+ def natural_content_height
26
+ 0
27
+ end
28
+
29
+ # By default, a span dummy will never increase the width demand.
30
+ #
31
+ def natural_content_width
32
+ 0
33
+ end
34
+
35
+ def avg_spanned_min_width
36
+ @master_cell.avg_spanned_min_width
37
+ end
38
+
39
+ # Dummy cells have nothing to draw.
40
+ #
41
+ def draw_borders(pt)
42
+ end
43
+
44
+ # Dummy cells have nothing to draw.
45
+ #
46
+ def draw_bounded_content(pt)
47
+ end
48
+
49
+ def padding_right=(val)
50
+ @master_cell.padding_right = val if rightmost?
51
+ end
52
+
53
+ def padding_bottom=(val)
54
+ @master_cell.padding_bottom = val if bottommost?
55
+ end
56
+
57
+ def border_right_color=(val)
58
+ @master_cell.border_right_color = val if rightmost?
59
+ end
60
+
61
+ def border_bottom_color=(val)
62
+ @master_cell.border_bottom_color = val if bottommost?
63
+ end
64
+
65
+ def border_right_width=(val)
66
+ @master_cell.border_right_width = val if rightmost?
67
+ end
68
+
69
+ def border_bottom_width=(val)
70
+ @master_cell.border_bottom_width = val if bottommost?
71
+ end
72
+
73
+ def background_color
74
+ @master_cell.background_color
75
+ end
76
+
77
+ private
78
+
79
+ # Are we on the right border of the span?
80
+ #
81
+ def rightmost?
82
+ @column == @master_cell.column + @master_cell.colspan - 1
83
+ end
84
+
85
+ # Are we on the bottom border of the span?
86
+ #
87
+ def bottommost?
88
+ @row == @master_cell.row + @master_cell.rowspan - 1
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+
3
+ # subtable.rb: Yo dawg.
4
+ #
5
+ # Copyright January 2010, Brad Ediger. All Rights Reserved.
6
+ #
7
+ # This is free software. Please see the LICENSE and COPYING files for details.
8
+ module Prawn
9
+ class Table
10
+ class Cell
11
+
12
+ # A Cell that contains another table.
13
+ #
14
+ # @private
15
+ class Subtable < Cell
16
+
17
+ attr_reader :subtable
18
+
19
+ def initialize(pdf, point, options={})
20
+ options[:padding] ||= [0, 0, 0, 0]
21
+
22
+ super
23
+
24
+ @subtable = options[:content]
25
+ end
26
+
27
+ # Sets the text color of the entire subtable.
28
+ #
29
+ def text_color=(color)
30
+ @subtable.cells.text_color = color
31
+ end
32
+
33
+ # Proxied to subtable.
34
+ #
35
+ def natural_content_width
36
+ @subtable.cells.width
37
+ end
38
+
39
+ # Proxied to subtable.
40
+ #
41
+ def min_width
42
+ @subtable.cells.min_width
43
+ end
44
+
45
+ # Proxied to subtable.
46
+ #
47
+ def max_width
48
+ @subtable.cells.max_width
49
+ end
50
+
51
+ # Proxied to subtable.
52
+ #
53
+ def natural_content_height
54
+ @subtable.cells.height
55
+ end
56
+
57
+ # Draws the subtable.
58
+ #
59
+ def draw_content
60
+ @subtable.draw
61
+ end
62
+
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,155 @@
1
+ # encoding: utf-8
2
+
3
+ # text.rb: Text table cells.
4
+ #
5
+ # Copyright December 2009, Gregory Brown and Brad Ediger. All Rights Reserved.
6
+ #
7
+ # This is free software. Please see the LICENSE and COPYING files for details.
8
+ module Prawn
9
+ class Table
10
+ class Cell
11
+
12
+ # A Cell that contains text. Has some limited options to set font family,
13
+ # size, and style.
14
+ #
15
+ # @private
16
+ class Text < Cell
17
+
18
+ TextOptions = [:inline_format, :kerning, :size, :align, :valign,
19
+ :rotate, :rotate_around, :leading, :single_line, :skip_encoding,
20
+ :overflow, :min_font_size]
21
+
22
+ TextOptions.each do |option|
23
+ define_method("#{option}=") { |v| @text_options[option] = v }
24
+ define_method(option) { @text_options[option] }
25
+ end
26
+
27
+ attr_writer :font, :text_color
28
+
29
+ def initialize(pdf, point, options={})
30
+ @text_options = {}
31
+ super
32
+ end
33
+
34
+ # Returns the font that will be used to draw this cell.
35
+ #
36
+ def font
37
+ with_font { @pdf.font }
38
+ end
39
+
40
+ # Sets the style of the font in use. Equivalent to the Text::Box
41
+ # +style+ option, but we already have a style method.
42
+ #
43
+ def font_style=(style)
44
+ @text_options[:style] = style
45
+ end
46
+
47
+ # Returns the width of this text with no wrapping. This will be far off
48
+ # from the final width if the text is long.
49
+ #
50
+ def natural_content_width
51
+ @natural_content_width ||= [styled_width_of(@content), @pdf.bounds.width].min
52
+ end
53
+
54
+ # Returns the natural height of this block of text, wrapped to the
55
+ # preset width.
56
+ #
57
+ def natural_content_height
58
+ with_font do
59
+ b = text_box(:width => spanned_content_width + FPTolerance)
60
+ b.render(:dry_run => true)
61
+ b.height + b.line_gap
62
+ end
63
+ end
64
+
65
+ # Draws the text content into its bounding box.
66
+ #
67
+ def draw_content
68
+ with_font do
69
+ @pdf.move_down((@pdf.font.line_gap + @pdf.font.descender)/2)
70
+ with_text_color do
71
+ text_box(:width => spanned_content_width + FPTolerance,
72
+ :height => spanned_content_height + FPTolerance,
73
+ :at => [0, @pdf.cursor]).render
74
+ end
75
+ end
76
+ end
77
+
78
+ def set_width_constraints
79
+ # Sets a reasonable minimum width. If the cell has any content, make
80
+ # sure we have enough width to be at least one character wide. This is
81
+ # a bit of a hack, but it should work well enough.
82
+ unless defined?(@min_width) && @min_width
83
+ min_content_width = [natural_content_width, styled_width_of_single_character].min
84
+ @min_width = padding_left + padding_right + min_content_width
85
+ super
86
+ end
87
+ end
88
+
89
+ protected
90
+
91
+ def with_font
92
+ @pdf.save_font do
93
+ options = {}
94
+ options[:style] = @text_options[:style] if @text_options[:style]
95
+ options[:style] ||= @pdf.font.options[:style] if @pdf.font.options[:style]
96
+
97
+ @pdf.font(defined?(@font) && @font || @pdf.font.family, options)
98
+
99
+ yield
100
+ end
101
+ end
102
+
103
+ def with_text_color
104
+ if defined?(@text_color) && @text_color
105
+ begin
106
+ old_color = @pdf.fill_color || '000000'
107
+ @pdf.fill_color(@text_color)
108
+ yield
109
+ ensure
110
+ @pdf.fill_color(old_color)
111
+ end
112
+ else
113
+ yield
114
+ end
115
+ end
116
+
117
+ def text_box(extra_options={})
118
+ if p = @text_options[:inline_format]
119
+ p = [] unless p.is_a?(Array)
120
+ options = @text_options.dup
121
+ options.delete(:inline_format)
122
+ options.merge!(extra_options)
123
+ options[:document] = @pdf
124
+
125
+ array = @pdf.text_formatter.format(@content, *p)
126
+ ::Prawn::Text::Formatted::Box.new(array,
127
+ options.merge(extra_options).merge(:document => @pdf))
128
+ else
129
+ ::Prawn::Text::Box.new(@content, @text_options.merge(extra_options).
130
+ merge(:document => @pdf))
131
+ end
132
+ end
133
+
134
+ # Returns the width of +text+ under the given text options.
135
+ #
136
+ def styled_width_of(text)
137
+ options = @text_options.reject { |k| k == :style }
138
+ with_font { @pdf.width_of(text, options) }
139
+ end
140
+
141
+ private
142
+
143
+ # Returns the greatest possible width of any single character
144
+ # under the given text options.
145
+ # (We use this to determine the minimum width of a table cell)
146
+ # (Although we currently determine this by measuring "M", it should really
147
+ # use whichever character is widest under the current font)
148
+ #
149
+ def styled_width_of_single_character
150
+ styled_width_of("M")
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end