pdf_gen 0.7
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/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
|
+
|