jyurek-prawn-layout 0.8.4
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.
- data/README +7 -0
- data/Rakefile +70 -0
- data/examples/example_helper.rb +10 -0
- data/examples/grid/bounding_boxes.rb +21 -0
- data/examples/grid/column_gutter_grid.rb +20 -0
- data/examples/grid/multi_boxes.rb +51 -0
- data/examples/grid/show_grid.rb +13 -0
- data/examples/grid/simple_grid.rb +20 -0
- data/examples/page_layout/lazy_bounding_boxes.rb +27 -0
- data/examples/page_layout/padded_box.rb +23 -0
- data/examples/table/addressbook.csv +6 -0
- data/examples/table/cell.rb +39 -0
- data/examples/table/currency.csv +1834 -0
- data/examples/table/fancy_table.rb +63 -0
- data/examples/table/table.rb +50 -0
- data/examples/table/table_alignment.rb +17 -0
- data/examples/table/table_border_color.rb +16 -0
- data/examples/table/table_colspan.rb +18 -0
- data/examples/table/table_header_color.rb +18 -0
- data/examples/table/table_header_underline.rb +14 -0
- data/examples/table/table_widths.rb +60 -0
- data/lib/prawn/layout.rb +21 -0
- data/lib/prawn/layout/grid.rb +260 -0
- data/lib/prawn/layout/page.rb +76 -0
- data/lib/prawn/table.rb +416 -0
- data/lib/prawn/table/cell.rb +285 -0
- data/spec/grid_spec.rb +85 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/table_spec.rb +337 -0
- metadata +105 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Demonstrates various table and cell features.
|
|
4
|
+
#
|
|
5
|
+
require "#{File.dirname(__FILE__)}/../example_helper.rb"
|
|
6
|
+
|
|
7
|
+
headers, body = nil, nil
|
|
8
|
+
|
|
9
|
+
dir = File.expand_path(File.dirname(__FILE__))
|
|
10
|
+
|
|
11
|
+
ruby_18 do
|
|
12
|
+
require "fastercsv"
|
|
13
|
+
headers, *body = FasterCSV.read("#{dir}/addressbook.csv")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
ruby_19 do
|
|
17
|
+
require "csv"
|
|
18
|
+
headers, *body = CSV.read("#{dir}/addressbook.csv",
|
|
19
|
+
:encoding => "utf-8")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
Prawn::Document.generate("fancy_table.pdf", :page_layout => :landscape) do
|
|
23
|
+
|
|
24
|
+
#font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
|
|
25
|
+
|
|
26
|
+
mask(:y) { table body, :headers => headers,
|
|
27
|
+
:align => :center,
|
|
28
|
+
:border_style => :grid }
|
|
29
|
+
|
|
30
|
+
table [["This is", "A Test" ],
|
|
31
|
+
[ Prawn::Table::Cell.new( :text => "Of tables",
|
|
32
|
+
:background_color => "ffccff" ),
|
|
33
|
+
"Drawn Side"], ["By side", "and stuff" ]],
|
|
34
|
+
:position => 600,
|
|
35
|
+
:headers => ["Col A", "Col B"],
|
|
36
|
+
:border_width => 1,
|
|
37
|
+
:vertical_padding => 5,
|
|
38
|
+
:horizontal_padding => 3,
|
|
39
|
+
:font_size => 10,
|
|
40
|
+
:row_colors => :pdf_writer,
|
|
41
|
+
:column_widths => { 1 => 50 }
|
|
42
|
+
|
|
43
|
+
move_down 150
|
|
44
|
+
|
|
45
|
+
table [%w[1 2 3],%w[4 5 6],%w[7 8 9]],
|
|
46
|
+
:position => :center,
|
|
47
|
+
:border_width => 0,
|
|
48
|
+
:font_size => 40
|
|
49
|
+
|
|
50
|
+
cell [500,300],
|
|
51
|
+
:text => "This free flowing textbox shows how you can use Prawn's "+
|
|
52
|
+
"cells outside of a table with ease. Think of a 'cell' as " +
|
|
53
|
+
"simply a limited purpose bounding box that is meant for laying " +
|
|
54
|
+
"out blocks of text and optionally placing a border around it",
|
|
55
|
+
:width => 225, :padding => 10, :border_width => 2
|
|
56
|
+
|
|
57
|
+
font_size 24
|
|
58
|
+
|
|
59
|
+
cell [50,75],
|
|
60
|
+
:text => "This document demonstrates a number of Prawn's table features",
|
|
61
|
+
:border_style => :no_top, # :all, :no_bottom, :sides
|
|
62
|
+
:horizontal_padding => 5
|
|
63
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Generates a couple simple tables, including some UTF-8 text cells.
|
|
4
|
+
# Although this does not show all of the options available to table, the most
|
|
5
|
+
# common are used here. See fancy_table.rb for a more comprehensive example.
|
|
6
|
+
#
|
|
7
|
+
require "#{File.dirname(__FILE__)}/../example_helper.rb"
|
|
8
|
+
|
|
9
|
+
Prawn::Document.generate("table.pdf") do
|
|
10
|
+
font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
|
|
11
|
+
table [["ὕαλον ϕαγεῖν", "baaar", "1" ],
|
|
12
|
+
["This is","a sample", "2" ],
|
|
13
|
+
["Table", "dont\ncha\nknow?", "3" ],
|
|
14
|
+
[ "It", "Rules", "4" ],
|
|
15
|
+
[ "It", "Rules", "4" ],
|
|
16
|
+
[ "It", "Rules", "4123231" ],
|
|
17
|
+
[ "It", "Rules", "22.5" ],
|
|
18
|
+
[ "It", "Rules", "4" ],
|
|
19
|
+
[ "It", "Rules", "4" ],
|
|
20
|
+
[ "It", "Rules", "4" ],
|
|
21
|
+
[ "It", "Rules", "4" ],
|
|
22
|
+
[ "It", "Rules", "4" ],
|
|
23
|
+
[ "It", "Rules\nwith an iron fist", "x" ],
|
|
24
|
+
[ "It", "Rules", "4" ],
|
|
25
|
+
[ "It", "Rules", "4" ],
|
|
26
|
+
[ "It", "Rules", "4" ],
|
|
27
|
+
[ "It", "Rules", "4" ],
|
|
28
|
+
[ "It", "Rules", "4" ],
|
|
29
|
+
[ "It", "Rules", "4" ],
|
|
30
|
+
[ "It", "Rules", "4" ],
|
|
31
|
+
[ "It", "Rules", "4" ],
|
|
32
|
+
[ "It", "Rules", "4" ]],
|
|
33
|
+
|
|
34
|
+
:font_size => 24,
|
|
35
|
+
:horizontal_padding => 10,
|
|
36
|
+
:vertical_padding => 3,
|
|
37
|
+
:border_width => 2,
|
|
38
|
+
:position => :center,
|
|
39
|
+
:headers => ["Column A","Column B","#"],
|
|
40
|
+
:align => {1 => :center},
|
|
41
|
+
:align_headers => :center
|
|
42
|
+
|
|
43
|
+
text "This should appear in the original font size, just below the table"
|
|
44
|
+
move_down 10
|
|
45
|
+
|
|
46
|
+
table [[ "Wide", "columns", "streeetch"],
|
|
47
|
+
["are","mighty fine", "streeeeeeeech"]],
|
|
48
|
+
:column_widths => { 0 => 200, 1 => 200 }, :position => 5
|
|
49
|
+
|
|
50
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Demonstrates the many controls over alignment and positioning in Prawn
|
|
4
|
+
# tables.
|
|
5
|
+
#
|
|
6
|
+
require "#{File.dirname(__FILE__)}/../example_helper.rb"
|
|
7
|
+
|
|
8
|
+
Prawn::Document.generate "table_header_align.pdf" do
|
|
9
|
+
table [ ['01/01/2008', 'John Doe', '4.2', '125.00', '525.00'],
|
|
10
|
+
['01/12/2008', 'Jane Doe', '3.2', { :text => '75.5', :align => :center }, '241.60'] ] * 20,
|
|
11
|
+
:position => :center,
|
|
12
|
+
:headers => ['Date', 'Employee', 'Hours', 'Rate', 'Total'],
|
|
13
|
+
:column_widths => { 0 => 75, 1 => 100, 2 => 50, 3 => 50, 4 => 50},
|
|
14
|
+
:border_style => :grid,
|
|
15
|
+
:align => { 0 => :right, 1 => :left, 2 => :right, 3 => :right, 4 => :right },
|
|
16
|
+
:align_headers => { 0 => :center, 2 => :left, 3 => :left, 4 => :right }
|
|
17
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Demonstrates how to set the table border color with the :border_color
|
|
4
|
+
# attribute.
|
|
5
|
+
#
|
|
6
|
+
require "#{File.dirname(__FILE__)}/../example_helper.rb"
|
|
7
|
+
|
|
8
|
+
Prawn::Document.generate "table_border_color.pdf" do
|
|
9
|
+
table [ ['01/01/2008', 'John Doe', '4.2', '125.00', '525.00'],
|
|
10
|
+
['01/12/2008', 'Jane Doe', '3.2', '75.50', '241.60'] ] * 20,
|
|
11
|
+
:position => :center,
|
|
12
|
+
:headers => ['Date', 'Employee', 'Hours', 'Rate', 'Total'],
|
|
13
|
+
:column_widths => { 0 => 75, 1 => 100, 2 => 50, 3 => 50, 4 => 50},
|
|
14
|
+
:border_style => :grid,
|
|
15
|
+
:border_color => "ff0000"
|
|
16
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Demonstrates the use of the :col_span option when using Document#table
|
|
4
|
+
#
|
|
5
|
+
require "#{File.dirname(__FILE__)}/../example_helper.rb"
|
|
6
|
+
|
|
7
|
+
Prawn::Document.generate "table_colspan.pdf" do
|
|
8
|
+
data = [ ['01/01/2008', 'John Doe', '4.2', '125.00', '525.00'],
|
|
9
|
+
['01/12/2008', 'Jane Doe', '3.2', '75.50', '241.60'] ] * 5
|
|
10
|
+
|
|
11
|
+
data << [{:text => 'Total', :colspan => 2, :align => :center}, '37.0', '1002.5', '3833']
|
|
12
|
+
|
|
13
|
+
table data,
|
|
14
|
+
:position => :center,
|
|
15
|
+
:headers => ['Date', 'Employee', 'Hours', 'Rate', 'Total'],
|
|
16
|
+
:column_widths => { 0 => 75, 1 => 100, 2 => 50, 3 => 50, 4 => 50},
|
|
17
|
+
:border_style => :grid
|
|
18
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Demonstrates explicitly setting the :header_color rather than inferring
|
|
4
|
+
# it from :row_colors in Document#table
|
|
5
|
+
#
|
|
6
|
+
require "#{File.dirname(__FILE__)}/../example_helper.rb"
|
|
7
|
+
|
|
8
|
+
Prawn::Document.generate "table_header_color.pdf" do
|
|
9
|
+
table [ ['01/01/2008', 'John Doe', '4.2', '125.00', '525.00'],
|
|
10
|
+
['01/12/2008', 'Jane Doe', '3.2', '75.50', '241.60'] ] * 20,
|
|
11
|
+
:position => :center,
|
|
12
|
+
:headers => ['Date', 'Employee', 'Hours', 'Rate', 'Total'],
|
|
13
|
+
:column_widths => { 0 => 75, 1 => 100, 2 => 50, 3 => 50, 4 => 50},
|
|
14
|
+
:border_style => :grid,
|
|
15
|
+
:header_color => 'f07878',
|
|
16
|
+
:header_text_color => "990000",
|
|
17
|
+
:row_colors => ["FFCCFF","CCFFCC"]
|
|
18
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Demonstrates the :underline_header border style for Document#table.
|
|
4
|
+
#
|
|
5
|
+
require "#{File.dirname(__FILE__)}/../example_helper.rb"
|
|
6
|
+
|
|
7
|
+
Prawn::Document.generate "table_header_underline.pdf" do
|
|
8
|
+
table [ ['01/01/2008', 'John Doe', '4.2', '125.00', '525.00'],
|
|
9
|
+
['01/12/2008', 'Jane Doe', '3.2', '75.50', '241.60'] ] * 5,
|
|
10
|
+
:position => :center,
|
|
11
|
+
:headers => ['Date', 'Employee', 'Hours', 'Rate', 'Total'],
|
|
12
|
+
:column_widths => { 0 => 75, 1 => 100, 2 => 50, 3 => 50, 4 => 50},
|
|
13
|
+
:border_style => :underline_header
|
|
14
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# Generates a couple simple tables, including some UTF-8 text cells.
|
|
4
|
+
# Although this does not show all of the options available to table, the most
|
|
5
|
+
# common are used here. See fancy_table.rb for a more comprehensive example.
|
|
6
|
+
#
|
|
7
|
+
require "#{File.dirname(__FILE__)}/../example_helper.rb"
|
|
8
|
+
|
|
9
|
+
Prawn::Document.generate("table_widths.pdf") do
|
|
10
|
+
|
|
11
|
+
data = [
|
|
12
|
+
%w(one two three four),
|
|
13
|
+
%w(five six seven eight),
|
|
14
|
+
%w(nine ten eleven twelve),
|
|
15
|
+
%w(thirteen fourteen fifteen sixteen),
|
|
16
|
+
%w(seventeen eighteen nineteen twenty)
|
|
17
|
+
]
|
|
18
|
+
headers = ["Column A","Column B","Column C", "Column D"]
|
|
19
|
+
|
|
20
|
+
text "A table with a specified width of the document width (within margins)"
|
|
21
|
+
move_down 10
|
|
22
|
+
|
|
23
|
+
table data,
|
|
24
|
+
:position => :center,
|
|
25
|
+
:headers => headers,
|
|
26
|
+
:width => margin_box.width
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
move_down 20
|
|
30
|
+
text "A table with a specified width of the document width (within margins) and two fixed width columns"
|
|
31
|
+
move_down 10
|
|
32
|
+
|
|
33
|
+
table data,
|
|
34
|
+
:position => :center,
|
|
35
|
+
:headers => headers,
|
|
36
|
+
:width => margin_box.width,
|
|
37
|
+
:column_widths => {0 => 70, 1 => 70}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
move_down 20
|
|
41
|
+
text "A table with a specified width of 300"
|
|
42
|
+
move_down 10
|
|
43
|
+
|
|
44
|
+
table data,
|
|
45
|
+
:position => :center,
|
|
46
|
+
:headers => headers,
|
|
47
|
+
:width => 300
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
move_down 20
|
|
51
|
+
text "A table with too much data is automatically limited to the document width"
|
|
52
|
+
move_down 10
|
|
53
|
+
|
|
54
|
+
data << ['some text', 'A long piece of text that will make this cell too wide for the page', 'some more text', 'And more text']
|
|
55
|
+
|
|
56
|
+
table data,
|
|
57
|
+
:position => :center,
|
|
58
|
+
:headers => headers
|
|
59
|
+
|
|
60
|
+
end
|
data/lib/prawn/layout.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require "prawn/table"
|
|
2
|
+
require "prawn/layout/page"
|
|
3
|
+
require 'prawn/layout/grid'
|
|
4
|
+
|
|
5
|
+
module Prawn
|
|
6
|
+
|
|
7
|
+
module Errors
|
|
8
|
+
|
|
9
|
+
# This error is raised when table data is malformed
|
|
10
|
+
#
|
|
11
|
+
InvalidTableData = Class.new(StandardError)
|
|
12
|
+
|
|
13
|
+
# This error is raised when an empty or nil table is rendered
|
|
14
|
+
#
|
|
15
|
+
EmptyTable = Class.new(StandardError)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
module Layout
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
module Prawn
|
|
2
|
+
class Document
|
|
3
|
+
|
|
4
|
+
# Defines the grid system for a particular document. Takes the number of
|
|
5
|
+
# rows and columns and the width to use for the gutter as the
|
|
6
|
+
# keys :rows, :columns, :gutter, :row_gutter, :column_gutter
|
|
7
|
+
#
|
|
8
|
+
def define_grid(options = {})
|
|
9
|
+
@grid = Grid.new(self, options)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# A method that can either be used to access a particular grid on the page
|
|
13
|
+
# or work with the grid system directly.
|
|
14
|
+
#
|
|
15
|
+
# @pdf.grid # Get the Grid directly
|
|
16
|
+
# @pdf.grid([0,1]) # Get the box at [0,1]
|
|
17
|
+
# @pdf.grid([0,1], [1,2]) # Get a multi-box spanning from [0,1] to [1,2]
|
|
18
|
+
#
|
|
19
|
+
def grid(*args)
|
|
20
|
+
@boxes ||= {}
|
|
21
|
+
@boxes[args] ||= if args.empty?
|
|
22
|
+
@grid
|
|
23
|
+
else
|
|
24
|
+
g1, g2 = args
|
|
25
|
+
if(g1.class == Array && g2.class == Array &&
|
|
26
|
+
g1.length == 2 && g2.length == 2)
|
|
27
|
+
multi_box(single_box(*g1), single_box(*g2))
|
|
28
|
+
else
|
|
29
|
+
single_box(g1, g2)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# A Grid represents the entire grid system of a Page and calculates
|
|
35
|
+
# the column width and row height of the base box.
|
|
36
|
+
class Grid
|
|
37
|
+
attr_reader :pdf, :columns, :rows, :gutter, :row_gutter, :column_gutter
|
|
38
|
+
# :nodoc
|
|
39
|
+
def initialize(pdf, options = {})
|
|
40
|
+
valid_options = [:columns, :rows, :gutter, :row_gutter, :column_gutter]
|
|
41
|
+
Prawn.verify_options valid_options, options
|
|
42
|
+
|
|
43
|
+
@pdf = pdf
|
|
44
|
+
@columns = options[:columns]
|
|
45
|
+
@rows = options[:rows]
|
|
46
|
+
set_gutter(options)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Calculates the base width of boxes.
|
|
50
|
+
def column_width
|
|
51
|
+
@column_width ||= subdivide(pdf.bounds.width, columns, column_gutter)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Calculates the base height of boxes.
|
|
55
|
+
def row_height
|
|
56
|
+
@row_height ||= subdivide(pdf.bounds.height, rows, row_gutter)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Diagnostic tool to show all of the grids. Defaults to gray.
|
|
60
|
+
def show_all(color = "CCCCCC")
|
|
61
|
+
self.rows.times do |i|
|
|
62
|
+
self.columns.times do |j|
|
|
63
|
+
pdf.grid(i,j).show(color)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def subdivide(total, num, gutter)
|
|
71
|
+
(total.to_f - (gutter * (num - 1).to_f)) / num.to_f
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def set_gutter(options)
|
|
75
|
+
if options.has_key?(:gutter)
|
|
76
|
+
@gutter = options[:gutter].to_f
|
|
77
|
+
@row_gutter, @column_gutter = @gutter, @gutter
|
|
78
|
+
else
|
|
79
|
+
@row_gutter = options[:row_gutter].to_f
|
|
80
|
+
@column_gutter = options[:column_gutter].to_f
|
|
81
|
+
@gutter = 0
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# A Box is a class that represents a bounded area of a page.
|
|
87
|
+
# A Grid object has methods that allow easy access to the coordinates of
|
|
88
|
+
# its corners, which can be plugged into most existing prawnmethods.
|
|
89
|
+
#
|
|
90
|
+
class Box
|
|
91
|
+
attr_reader :pdf
|
|
92
|
+
|
|
93
|
+
def initialize(pdf, i, j)
|
|
94
|
+
@pdf = pdf
|
|
95
|
+
@i = i
|
|
96
|
+
@j = j
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Mostly diagnostic method that outputs the name of a box as
|
|
100
|
+
# col_num, row_num
|
|
101
|
+
#
|
|
102
|
+
def name
|
|
103
|
+
"#{@i.to_s},#{@j.to_s}"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# :nodoc
|
|
107
|
+
def total_height
|
|
108
|
+
pdf.bounds.height.to_f
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Width of a box
|
|
112
|
+
def width
|
|
113
|
+
grid.column_width.to_f
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Height of a box
|
|
117
|
+
def height
|
|
118
|
+
grid.row_height.to_f
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Width of the gutter
|
|
122
|
+
def gutter
|
|
123
|
+
grid.gutter.to_f
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# x-coordinate of left side
|
|
127
|
+
def left
|
|
128
|
+
@left ||= (width + grid.column_gutter) * @j.to_f
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# x-coordinate of right side
|
|
132
|
+
def right
|
|
133
|
+
@right ||= left + width
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# y-coordinate of the top
|
|
137
|
+
def top
|
|
138
|
+
@top ||= total_height - ((height + grid.row_gutter) * @i.to_f)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# y-coordinate of the bottom
|
|
142
|
+
def bottom
|
|
143
|
+
@bottom ||= top - height
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# x,y coordinates of top left corner
|
|
147
|
+
def top_left
|
|
148
|
+
[left, top]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# x,y coordinates of top right corner
|
|
152
|
+
def top_right
|
|
153
|
+
[right, top]
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# x,y coordinates of bottom left corner
|
|
157
|
+
def bottom_left
|
|
158
|
+
[left, bottom]
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# x,y coordinates of bottom right corner
|
|
162
|
+
def bottom_right
|
|
163
|
+
[right, bottom]
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Creates a standard bounding box based on the grid box.
|
|
167
|
+
def bounding_box(&blk)
|
|
168
|
+
pdf.bounding_box(top_left, :width => width, :height => height, &blk)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Diagnostic method
|
|
172
|
+
def show(grid_color = "CCCCCC")
|
|
173
|
+
self.bounding_box do
|
|
174
|
+
original_stroke_color = pdf.stroke_color
|
|
175
|
+
|
|
176
|
+
pdf.stroke_color = grid_color
|
|
177
|
+
pdf.text self.name
|
|
178
|
+
pdf.stroke_bounds
|
|
179
|
+
|
|
180
|
+
pdf.stroke_color = original_stroke_color
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
private
|
|
185
|
+
def grid
|
|
186
|
+
pdf.grid
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# A MultiBox is specified by 2 Boxes and spans the areas between.
|
|
191
|
+
class MultiBox < Box
|
|
192
|
+
def initialize(pdf, b1, b2)
|
|
193
|
+
@pdf = pdf
|
|
194
|
+
@bs = [b1, b2]
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def name
|
|
198
|
+
@bs.map {|b| b.name}.join(":")
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def total_height
|
|
202
|
+
@bs[0].total_height
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def width
|
|
206
|
+
right_box.right - left_box.left
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def height
|
|
210
|
+
top_box.top - bottom_box.bottom
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def gutter
|
|
214
|
+
@bs[0].gutter
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def left
|
|
218
|
+
left_box.left
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def right
|
|
222
|
+
right_box.right
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def top
|
|
226
|
+
top_box.top
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def bottom
|
|
230
|
+
bottom_box.bottom
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
private
|
|
234
|
+
def left_box
|
|
235
|
+
@left_box ||= @bs.min {|a,b| a.left <=> b.left}
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def right_box
|
|
239
|
+
@right_box ||= @bs.max {|a,b| a.right <=> b.right}
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def top_box
|
|
243
|
+
@top_box ||= @bs.max {|a,b| a.top <=> b.top}
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def bottom_box
|
|
247
|
+
@bottom_box ||= @bs.min {|a,b| a.bottom <=> b.bottom}
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
private
|
|
252
|
+
def single_box(i, j)
|
|
253
|
+
Box.new(self, i, j)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def multi_box(b1, b2)
|
|
257
|
+
MultiBox.new(self, b1, b2)
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
end
|