pdf_gen 0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -0
- data/README.rdoc +189 -0
- data/lib/base_region.rb +95 -0
- data/lib/caption.rb +78 -0
- data/lib/containers/caption_container.rb +15 -0
- data/lib/containers/div_container.rb +14 -0
- data/lib/containers/image_container.rb +15 -0
- data/lib/containers/span_container.rb +14 -0
- data/lib/containers/table_container.rb +14 -0
- data/lib/data/ds_ar.rb +31 -0
- data/lib/data/ds_base.rb +24 -0
- data/lib/data/ds_hash.rb +24 -0
- data/lib/div.rb +148 -0
- data/lib/document.rb +50 -0
- data/lib/fixnum.rb +18 -0
- data/lib/float.rb +18 -0
- data/lib/image.rb +46 -0
- data/lib/modules/base_attributes.rb +86 -0
- data/lib/modules/canvas.rb +15 -0
- data/lib/modules/composite.rb +54 -0
- data/lib/pdf_gen.rb +30 -0
- data/lib/smart_table.rb +155 -0
- data/lib/span.rb +69 -0
- data/lib/table.rb +116 -0
- data/lib/writer.rb +30 -0
- data/samples/border.rb +15 -0
- data/samples/div.rb +23 -0
- data/samples/div_illustration.rb +64 -0
- data/samples/headerfooter.rb +94 -0
- data/samples/image.rb +9 -0
- data/samples/ruby_logo.jpg +0 -0
- data/samples/sampl1_1.png +0 -0
- data/samples/sampl1_2.png +0 -0
- data/samples/sampl1_3.png +0 -0
- data/samples/simple.rb +7 -0
- data/samples/smart_table.rb +98 -0
- data/samples/span.rb +12 -0
- data/samples/span_illustration.rb +41 -0
- data/samples/spanindiv_ill.rb +53 -0
- data/samples/table.rb +37 -0
- data/samples/table_illustration.rb +177 -0
- data/samples/tableindiv_ill.rb +99 -0
- data/test/caption_test.rb +99 -0
- data/test/container_test.rb +29 -0
- data/test/div_test.rb +39 -0
- data/test/helpers_for_testing.rb +19 -0
- data/test/image_test.rb +54 -0
- data/test/shared_examples.rb +68 -0
- data/test/span_test.rb +83 -0
- data/test/table_test.rb +27 -0
- metadata +139 -0
data/lib/document.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require "lib/base_region"
|
2
|
+
require "lib/modules/composite"
|
3
|
+
require "lib/containers/div_container"
|
4
|
+
require "lib/containers/span_container"
|
5
|
+
require "lib/containers/caption_container"
|
6
|
+
require "lib/containers/image_container"
|
7
|
+
require "lib/containers/table_container"
|
8
|
+
|
9
|
+
module PDFGen
|
10
|
+
|
11
|
+
class Document < BaseRegion
|
12
|
+
|
13
|
+
include Canvas, Composite, TableContainer, CaptionContainer, SpanContainer,
|
14
|
+
DivContainer, ImageContainer
|
15
|
+
|
16
|
+
def initialize(pdf, page_pad_top)
|
17
|
+
super(nil)
|
18
|
+
pdf.y += pdf.top_margin # clear predefined top_margin
|
19
|
+
pdf.y -= page_pad_top # set y considering page_pad_top
|
20
|
+
pdf.top_margin = 0
|
21
|
+
|
22
|
+
@pdf = pdf
|
23
|
+
@page_pad_top = page_pad_top
|
24
|
+
@header = []
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :pdf, :header
|
28
|
+
|
29
|
+
#creates new page
|
30
|
+
def break_page
|
31
|
+
pdf.page_break @page_pad_top
|
32
|
+
end
|
33
|
+
|
34
|
+
def render
|
35
|
+
pos = [0, pdf.y]
|
36
|
+
regions.each do |region|
|
37
|
+
pos[1] = pdf.y
|
38
|
+
status = region.render(pos, pdf.y)
|
39
|
+
if status[1]
|
40
|
+
pdf.y -= status[0]
|
41
|
+
else
|
42
|
+
self.break_page
|
43
|
+
redo
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/lib/fixnum.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "pdf/writer"
|
2
|
+
|
3
|
+
|
4
|
+
#Extension of the standard Fixnum class
|
5
|
+
#with PDF - related units conversions
|
6
|
+
class Fixnum
|
7
|
+
|
8
|
+
#cm2pts
|
9
|
+
def cm
|
10
|
+
PDF::Writer.cm2pts(self)
|
11
|
+
end
|
12
|
+
|
13
|
+
#in2pts
|
14
|
+
def in
|
15
|
+
PDF::Writer.in2pts(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/lib/float.rb
ADDED
data/lib/image.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require "pdf/writer"
|
2
|
+
require 'lib/base_region'
|
3
|
+
|
4
|
+
|
5
|
+
module PDFGen
|
6
|
+
|
7
|
+
class Image < BaseRegion
|
8
|
+
|
9
|
+
def initialize(parent, image_res)
|
10
|
+
super(parent)
|
11
|
+
|
12
|
+
@image = image_res
|
13
|
+
@info = PDF::Writer::Graphics::ImageInfo.new(@image)
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_accessor :image
|
17
|
+
|
18
|
+
def set_properties(props = {})
|
19
|
+
super
|
20
|
+
|
21
|
+
if width.zero? && height.zero?
|
22
|
+
self.width = @info.width
|
23
|
+
self.height = @info.height
|
24
|
+
elsif width.zero?
|
25
|
+
self.width = height / @info.height.to_f * @info.width
|
26
|
+
elsif height.zero?
|
27
|
+
self.height = width * @info.height / @info.width.to_f
|
28
|
+
end
|
29
|
+
self.height = self.height - pad_top - pad_bottom
|
30
|
+
end
|
31
|
+
|
32
|
+
def render(pos, av_height, test=false)
|
33
|
+
self.check_fit_in_height
|
34
|
+
if av_height >= self.height
|
35
|
+
document.pdf.add_image(@image, pos[0]+pad_left, pos[1]-height+pad_bottom,
|
36
|
+
width-pad_left-pad_right, height-pad_top-pad_bottom)
|
37
|
+
super
|
38
|
+
[self.height, true]
|
39
|
+
else
|
40
|
+
[0, false]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module BaseAttributes
|
2
|
+
|
3
|
+
module ClassMethods
|
4
|
+
def common_setter(*setters)
|
5
|
+
setters.each do |set|
|
6
|
+
define_method("#{set}=") do |val|
|
7
|
+
if val && set != val
|
8
|
+
self.instance_variable_set("@#{set}",val)
|
9
|
+
clear_minimal_height
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
extend ClassMethods
|
17
|
+
|
18
|
+
common_setter :pad_left, :pad_right, :pad_top, :pad_bottom, :width
|
19
|
+
|
20
|
+
def self.included(base)
|
21
|
+
base.extend(ClassMethods)
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_accessor :background_color
|
25
|
+
|
26
|
+
def var_init
|
27
|
+
@width = 0 #document.pdf.page_width - document.pdf.left_margin - document.pdf.right_margin
|
28
|
+
@height = 0
|
29
|
+
|
30
|
+
@pad_top = 0
|
31
|
+
@pad_bottom = 0
|
32
|
+
@pad_left = 0
|
33
|
+
@pad_right = 0
|
34
|
+
|
35
|
+
@border_top = false
|
36
|
+
@border_left = false
|
37
|
+
@border_right = false
|
38
|
+
@border_bottom = false
|
39
|
+
@border_style = :solid
|
40
|
+
@border_width = 1
|
41
|
+
@border_color = Color::RGB::Black
|
42
|
+
|
43
|
+
@is_breakable = false
|
44
|
+
|
45
|
+
@background_color = nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def breakable?
|
49
|
+
@is_breakable
|
50
|
+
end
|
51
|
+
|
52
|
+
attr_writer :is_breakable, :height
|
53
|
+
|
54
|
+
def height
|
55
|
+
[minimal_height, @height].max
|
56
|
+
end
|
57
|
+
|
58
|
+
#padding from the page top after page break
|
59
|
+
attr_accessor :page_pad_top
|
60
|
+
|
61
|
+
attr_reader :width
|
62
|
+
|
63
|
+
attr_accessor :border_top, :border_bottom, :border_left, :border_right,
|
64
|
+
:border_style, :border_color, :border_width
|
65
|
+
|
66
|
+
def border= value
|
67
|
+
self.border_top = self.border_bottom = self.border_left =
|
68
|
+
self.border_right = value
|
69
|
+
end
|
70
|
+
|
71
|
+
attr_reader :pad_top, :pad_bottom, :pad_left, :pad_right
|
72
|
+
|
73
|
+
def paddings=(value)
|
74
|
+
@pad_bottom = @pad_left = @pad_right = @pad_top = value
|
75
|
+
end
|
76
|
+
|
77
|
+
def border_params
|
78
|
+
border_type = {:solid => [1, 0], :dotted => [1, 1], :none => [0, 1]}
|
79
|
+
PDF::Writer::StrokeStyle.new(@border_width, :dash => {:pattern => border_type[@border_style]})
|
80
|
+
end
|
81
|
+
|
82
|
+
def av_width
|
83
|
+
width - pad_left - pad_right
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module PDFGen
|
2
|
+
|
3
|
+
module Composite
|
4
|
+
|
5
|
+
def regions
|
6
|
+
@regions ||= []
|
7
|
+
end
|
8
|
+
|
9
|
+
def [](index)
|
10
|
+
regions[index]
|
11
|
+
end
|
12
|
+
|
13
|
+
#executes specified initialization block on all inner regions
|
14
|
+
def elements(style = {}, &initialization_block)
|
15
|
+
regions.each do |region|
|
16
|
+
region.set_properties style unless style.nil?
|
17
|
+
region.instance_eval(&initialization_block) if initialization_block
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
#applies specified values
|
22
|
+
def apply_values(values = {})
|
23
|
+
regions.each{|region| region.apply_values values}
|
24
|
+
end
|
25
|
+
|
26
|
+
def page_pad_top=(value)
|
27
|
+
super
|
28
|
+
|
29
|
+
regions.each {|region| region.page_pad_top=value}
|
30
|
+
end
|
31
|
+
|
32
|
+
#adds new region to the span
|
33
|
+
def add_region region
|
34
|
+
regions << region if region
|
35
|
+
end
|
36
|
+
|
37
|
+
def render_regions(x, y, test = false)
|
38
|
+
regions.each { |region| region.render([x, document.pdf.y], document.pdf.y, test)}
|
39
|
+
end
|
40
|
+
|
41
|
+
#renders specified span at the specified position
|
42
|
+
#returns real position that caption was generated on
|
43
|
+
def render(pos,av_height, test = false)
|
44
|
+
if av_height >= self.height
|
45
|
+
render_regions(pos[0],pos[1], test)
|
46
|
+
[self.height, true]
|
47
|
+
else
|
48
|
+
[0, false]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
data/lib/pdf_gen.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
$:.unshift(File.expand_path(File.dirname(__FILE__) + "/../"))
|
2
|
+
require "rubygems"
|
3
|
+
require "pdf/writer"
|
4
|
+
require "lib/writer"
|
5
|
+
require "lib/base_region"
|
6
|
+
require "lib/fixnum"
|
7
|
+
require "lib/float"
|
8
|
+
require "lib/table"
|
9
|
+
require "lib/caption"
|
10
|
+
require "lib/modules/canvas"
|
11
|
+
require "lib/modules/composite"
|
12
|
+
require "lib/span"
|
13
|
+
require "lib/div"
|
14
|
+
require "lib/image"
|
15
|
+
require "lib/containers/table_container"
|
16
|
+
require "lib/smart_table"
|
17
|
+
require "lib/document"
|
18
|
+
|
19
|
+
|
20
|
+
module PDFGen
|
21
|
+
|
22
|
+
def self.document(pdf, page_pad_top, &initialization_block)
|
23
|
+
document = Document.new(pdf, page_pad_top)
|
24
|
+
document.width = document.pdf.page_width
|
25
|
+
document.instance_eval(&initialization_block)
|
26
|
+
document.render
|
27
|
+
pdf
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/lib/smart_table.rb
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
require "lib/data/ds_hash"
|
2
|
+
require 'lib/data/ds_ar'
|
3
|
+
require "lib/table"
|
4
|
+
require "lib/div"
|
5
|
+
|
6
|
+
|
7
|
+
module PDFGen
|
8
|
+
|
9
|
+
class SmartTable < Table
|
10
|
+
|
11
|
+
attr_accessor :header_region, :body_regions
|
12
|
+
|
13
|
+
class RowsContainer < Div
|
14
|
+
|
15
|
+
def initialize(parent)
|
16
|
+
super
|
17
|
+
@cells = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def ds
|
21
|
+
parent.data_source
|
22
|
+
end
|
23
|
+
|
24
|
+
def cell(region=nil,style=nil)
|
25
|
+
if region.is_a?(Array)
|
26
|
+
@cells << region.last #todo
|
27
|
+
region.delete(region.last)
|
28
|
+
else
|
29
|
+
caption = Caption.new(parent)
|
30
|
+
caption.text = region
|
31
|
+
caption.border_left = true
|
32
|
+
caption.set_properties style unless style.nil?
|
33
|
+
@cells << caption
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def row
|
38
|
+
span = Span.new(self.document)
|
39
|
+
span.width = self.width
|
40
|
+
span.border = true
|
41
|
+
yield if block_given?
|
42
|
+
@cells.each do |cell|
|
43
|
+
if cell.width.zero? || cell.width == self.width
|
44
|
+
cell.width = span.width / @cells.size
|
45
|
+
end
|
46
|
+
span.add_region(cell)
|
47
|
+
end
|
48
|
+
|
49
|
+
@cells.clear
|
50
|
+
self.add_region(span)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
def initialize(parent)
|
56
|
+
super(parent)
|
57
|
+
@title = RowsContainer.new(self)
|
58
|
+
@header = RowsContainer.new(self)
|
59
|
+
@body = RowsContainer.new(self)
|
60
|
+
@footer = RowsContainer.new(self)
|
61
|
+
|
62
|
+
init_width(parent)
|
63
|
+
|
64
|
+
@data_source = nil
|
65
|
+
@header_data = nil
|
66
|
+
@body_data = nil
|
67
|
+
|
68
|
+
@is_header_rendered = false
|
69
|
+
@is_body_rendered = false
|
70
|
+
@columns = nil
|
71
|
+
|
72
|
+
@body_regions = []
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
def data_source=(data)
|
77
|
+
if data.is_a?(Array)
|
78
|
+
@data_source = DsActiveRecord.new(data)
|
79
|
+
else
|
80
|
+
@data_source = DsHash.new(data)
|
81
|
+
end
|
82
|
+
@header_data = @data_source.columns
|
83
|
+
@body_data = @data_source.body
|
84
|
+
end
|
85
|
+
|
86
|
+
attr_reader :data_source
|
87
|
+
|
88
|
+
def calculate_minimal_height
|
89
|
+
regions_formation
|
90
|
+
super
|
91
|
+
end
|
92
|
+
|
93
|
+
def regions_formation
|
94
|
+
@header.add_region(build_header) unless @is_header_rendered
|
95
|
+
build_body unless @is_body_rendered
|
96
|
+
|
97
|
+
@body_regions.each { |region| @body.add_region(region) }
|
98
|
+
end
|
99
|
+
|
100
|
+
def render(pos, av_height, test=false)
|
101
|
+
@header_region = nil if @is_header_rendered
|
102
|
+
@body_regions.clear if @is_body_rendered
|
103
|
+
|
104
|
+
regions_formation
|
105
|
+
|
106
|
+
super
|
107
|
+
end
|
108
|
+
|
109
|
+
def build_header()
|
110
|
+
span = Span.new(self.document)
|
111
|
+
span.width = self.width
|
112
|
+
span.border = true
|
113
|
+
@header_data.each do |cap|
|
114
|
+
caption = Caption.new(self.document)
|
115
|
+
caption.text = cap
|
116
|
+
caption.width = self.width / @header_data.size
|
117
|
+
caption.border_left = true
|
118
|
+
yield(span, caption) if block_given?
|
119
|
+
span.add_region(caption)
|
120
|
+
end
|
121
|
+
@is_header_rendered = true
|
122
|
+
span
|
123
|
+
end
|
124
|
+
|
125
|
+
def build_body()
|
126
|
+
@body_data.each do |row|
|
127
|
+
span = Span.new(self.document)
|
128
|
+
span.width = self.width
|
129
|
+
span.border = true
|
130
|
+
row.each do |cap|
|
131
|
+
caption = Caption.new(self.document)
|
132
|
+
caption.text = cap
|
133
|
+
caption.width = self.width / row.size
|
134
|
+
caption.border_left = true
|
135
|
+
yield(span, caption) if block_given?
|
136
|
+
span.add_region(caption)
|
137
|
+
end
|
138
|
+
@body_regions << span
|
139
|
+
end
|
140
|
+
@is_body_rendered = true
|
141
|
+
end
|
142
|
+
|
143
|
+
def header(style = nil, &initialization_block)
|
144
|
+
super
|
145
|
+
@is_header_rendered = true
|
146
|
+
end
|
147
|
+
|
148
|
+
def body(style = nil, &initialization_block)
|
149
|
+
super
|
150
|
+
@is_body_rendered = true
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
data/lib/span.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require "pdf/writer"
|
2
|
+
require "lib/image"
|
3
|
+
require "lib/base_region"
|
4
|
+
require "lib/modules/composite"
|
5
|
+
require "lib/caption"
|
6
|
+
require "lib/containers/caption_container"
|
7
|
+
require "lib/containers/image_container"
|
8
|
+
require "lib/containers/div_container"
|
9
|
+
|
10
|
+
module PDFGen
|
11
|
+
|
12
|
+
#Horizontal captions line
|
13
|
+
class Span < BaseRegion
|
14
|
+
|
15
|
+
include Composite, CaptionContainer, ImageContainer, SpanContainer,
|
16
|
+
DivContainer, TableContainer
|
17
|
+
|
18
|
+
def initialize(parent)
|
19
|
+
super
|
20
|
+
|
21
|
+
@vertical_interval = 0
|
22
|
+
@vertical_align = false
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_accessor :vertical_interval, :vertical_align
|
26
|
+
|
27
|
+
def calculate_minimal_height
|
28
|
+
render_regions
|
29
|
+
(regions.collect{|region| region.height}.max || 0) + pad_top + pad_bottom
|
30
|
+
end
|
31
|
+
|
32
|
+
#renders inner regions
|
33
|
+
#returns height of the region content
|
34
|
+
def render_regions(x=0, y=document.y, test=true)
|
35
|
+
content_width = pad_left
|
36
|
+
last = regions.last
|
37
|
+
regions.each do |region|
|
38
|
+
if region.breakable?
|
39
|
+
region.check_fit_in_height
|
40
|
+
end
|
41
|
+
|
42
|
+
if (content_width + region.width) > self.width
|
43
|
+
regions[regions.index(region), regions.size].each do |item|
|
44
|
+
regions.delete(item)
|
45
|
+
end
|
46
|
+
else
|
47
|
+
if vertical_align && !test
|
48
|
+
region.height = height
|
49
|
+
end
|
50
|
+
region.render([(x + content_width), (y - pad_top)], y-pad_top) unless test
|
51
|
+
|
52
|
+
content_width += region.width
|
53
|
+
content_width += vertical_interval unless region == last
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
content_width + pad_right
|
58
|
+
end
|
59
|
+
|
60
|
+
def render(pos, av_height, test=false)
|
61
|
+
self.check_fit_in_height
|
62
|
+
fill(pos) unless test
|
63
|
+
add_border(pos) unless test
|
64
|
+
super
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/lib/table.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
require "lib/base_region"
|
2
|
+
require "lib/div"
|
3
|
+
require "lib/containers/table_container"
|
4
|
+
|
5
|
+
|
6
|
+
module PDFGen
|
7
|
+
|
8
|
+
class Table < BaseRegion
|
9
|
+
|
10
|
+
def initialize(parent)
|
11
|
+
super(parent)
|
12
|
+
@is_breakable = true
|
13
|
+
@title = Div.new(self)
|
14
|
+
@header = Div.new(self)
|
15
|
+
@body = Div.new(self)
|
16
|
+
@footer = Div.new(self)
|
17
|
+
|
18
|
+
init_width(parent)
|
19
|
+
|
20
|
+
@repeat_header_on_each_page = false
|
21
|
+
@repeat_footer_on_each_page = false
|
22
|
+
end
|
23
|
+
|
24
|
+
def init_width(parent)
|
25
|
+
self.width = parent.width - parent.pad_left - parent.pad_right
|
26
|
+
end
|
27
|
+
|
28
|
+
def width=(value)
|
29
|
+
[@title,@header,@body,@footer].each do |region|
|
30
|
+
region.width = value
|
31
|
+
end
|
32
|
+
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_accessor :repeat_header_on_each_page, :repeat_footer_on_each_page
|
37
|
+
|
38
|
+
def align_cell_in_row
|
39
|
+
[@header,@body,@footer].each do |container|
|
40
|
+
container.regions.each do |row|
|
41
|
+
row.vertical_align = true if row.respond_to?(:vertical_align)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def calculate_minimal_height
|
47
|
+
[@title,@header,@body,@footer].inject(0){ |height, region| height + region.height }
|
48
|
+
end
|
49
|
+
|
50
|
+
def render(pos, av_height, test=false)
|
51
|
+
align_cell_in_row
|
52
|
+
super
|
53
|
+
|
54
|
+
pos_x, pos_y = pos
|
55
|
+
title_height = @title.render([pos_x, pos_y], pos_y, true)
|
56
|
+
header_height = @header.render([pos_x, pos_y], pos_y, true)
|
57
|
+
|
58
|
+
if (title_height[0] + header_height[0]) > av_height
|
59
|
+
return [0, false]
|
60
|
+
end
|
61
|
+
|
62
|
+
title_status = @title.render([pos_x, pos_y], pos_y)
|
63
|
+
pos_y -= title_status[0]
|
64
|
+
@header.reset_count_rendered_regions if @repeat_header_on_each_page
|
65
|
+
header_status = @header.render([pos_x, pos_y], pos_y)
|
66
|
+
pos_y -= header_status[0]
|
67
|
+
|
68
|
+
status = @body.render([pos_x, pos_y], pos_y)
|
69
|
+
pos_y -= status[0]
|
70
|
+
|
71
|
+
footer_height = @footer.render([pos_x, pos_y], pos_y, true)
|
72
|
+
if footer_height[0] > pos[1]
|
73
|
+
return [av_height-pos_y, false]
|
74
|
+
end
|
75
|
+
|
76
|
+
if status[1]
|
77
|
+
footer_status = @footer.render([pos_x, pos_y], pos_y)
|
78
|
+
else
|
79
|
+
if @repeat_footer_on_each_page
|
80
|
+
footer_status = @footer.render([pos_x, pos_y], pos_y)
|
81
|
+
|
82
|
+
@footer.reset_count_rendered_regions
|
83
|
+
end
|
84
|
+
end
|
85
|
+
pos_y -= footer_status[0] if footer_status
|
86
|
+
|
87
|
+
[av_height-pos_y, status[1] && footer_status[1]]
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
def title(style = nil, &initialization_block)
|
92
|
+
access_region(@title, style, &initialization_block)
|
93
|
+
end
|
94
|
+
|
95
|
+
def header(style = nil, &initialization_block)
|
96
|
+
access_region(@header, style, &initialization_block)
|
97
|
+
end
|
98
|
+
|
99
|
+
def body(style = nil, &initialization_block)
|
100
|
+
access_region(@body, style, &initialization_block)
|
101
|
+
end
|
102
|
+
|
103
|
+
def footer(style = nil, &initialization_block)
|
104
|
+
access_region(@footer, style, &initialization_block)
|
105
|
+
end
|
106
|
+
|
107
|
+
def access_region(region, style=nil, &initialization_block)
|
108
|
+
region.set_properties style unless style.nil?
|
109
|
+
region.instance_eval(&initialization_block) if initialization_block
|
110
|
+
end
|
111
|
+
|
112
|
+
private :access_region
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
data/lib/writer.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "pdf/writer"
|
2
|
+
|
3
|
+
|
4
|
+
module PDF
|
5
|
+
|
6
|
+
class Writer
|
7
|
+
|
8
|
+
alias_method :save, :save_as
|
9
|
+
#extends PDF writer class StrikeStyle with several well known styles
|
10
|
+
class StrokeStyle
|
11
|
+
|
12
|
+
DOTTED = StrokeStyle.new(1, :dash => {:pattern => [1, 1]})
|
13
|
+
SOLID = StrokeStyle.new(1, :dash => {:pattern => [1, 0]})
|
14
|
+
NONE = StrokeStyle.new(1, :dash => {:pattern => [0, 1]})
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
#performs page break with the specified top padding (page header height for ex.)
|
19
|
+
def page_break(pad_top)
|
20
|
+
start_new_page
|
21
|
+
self.y = self.y - pad_top
|
22
|
+
end
|
23
|
+
|
24
|
+
def y=(yy)
|
25
|
+
@y = yy
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/samples/border.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$:.unshift(File.expand_path(File.dirname(__FILE__) + "/../"))
|
2
|
+
require "lib/pdf_gen"
|
3
|
+
|
4
|
+
|
5
|
+
PDFGen::document PDF::Writer.new, 2.cm do
|
6
|
+
span :pad_left => 2.cm do
|
7
|
+
caption 'test text'*50, :width=>5.cm,
|
8
|
+
:border => true, :border_style => :solid, :border_width => 2
|
9
|
+
|
10
|
+
caption 'test text'*50, :width=>5.cm,
|
11
|
+
:border => true, :border_style => :dotted, :border_width => 3
|
12
|
+
end
|
13
|
+
end.save("#{File.basename(__FILE__, ".rb")}.pdf")
|
14
|
+
|
15
|
+
|