1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
# encoding: utf-8
#
# column_box.rb: Extends BoundingBox to allow for columns of text
#
# Author Paul Ostazeski.
require "prawn/document/bounding_box"
module Prawn
class Document
# A column box is a bounding box with the additional property that when
# text flows past the bottom, it will wrap first to another column on the
# same page, and only flow to the next page when all the columns are
# filled.
#
# column_box accepts the same parameters as bounding_box, as well as the
# number of :columns and a :spacer (in points) between columns.
#
# Defaults are :columns = 3 and :spacer = font_size
#
# Under PDF::Writer, "spacer" was known as "gutter"
#
def column_box(*args, &block)
init_column_box(block) do |parent_box|
map_to_absolute!(args[0])
@bounding_box = ColumnBox.new(self, parent_box, *args)
end
end
private
def init_column_box(user_block, options={}, &init_block)
parent_box = @bounding_box
init_block.call(parent_box)
self.y = @bounding_box.absolute_top
user_block.call
self.y = @bounding_box.absolute_bottom unless options[:hold_position]
@bounding_box = parent_box
end
# Implements the necessary functionality to allow Document#column_box to
# work.
#
class ColumnBox < BoundingBox
def initialize(document, parent, point, options={}) #:nodoc:
super
@columns = options[:columns] || 3
@spacer = options[:spacer] || @document.font_size
@current_column = 0
end
# The column width, not the width of the whole box. Used to calculate
# how long a line of text can be.
#
def width
super / @columns - @spacer - @total_left_padding - @total_right_padding
end
# Column width including the spacer.
#
def width_of_column
width + @spacer
end
# x coordinate of the left edge of the current column
#
def left_side
absolute_left + (width_of_column * @current_column)
end
# x co-orordinate of the right edge of the current column
#
def right_side
columns_from_right = @columns - (1 + @current_column)
absolute_right - (width_of_column * columns_from_right)
end
# Moves to the next column or starts a new page if currently positioned at
# the rightmost column.
def move_past_bottom
@current_column = (@current_column + 1) % @columns
@document.y = @y
if 0 == @current_column
@document.start_new_page
end
end
# Override the padding functions so as not to split the padding amount
# between all columns on the page.
def add_left_padding(left_padding)
@total_left_padding += left_padding
@x += left_padding
end
def subtract_left_padding(left_padding)
@total_left_padding -= left_padding
@x -= left_padding
end
def add_right_padding(right_padding)
@total_right_padding += right_padding
end
def subtract_right_padding(right_padding)
@total_right_padding -= right_padding
end
end
end
end
|