prawn-blank 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -26
- data/lib/prawn-blank.rb +2 -0
- data/lib/prawn/blank.rb +90 -19
- data/lib/prawn/blank/appearance.rb +247 -16
- data/lib/prawn/blank/checkbox.rb +35 -0
- data/lib/prawn/blank/field.rb +13 -82
- data/lib/prawn/blank/field_base.rb +220 -0
- data/lib/prawn/blank/form.rb +11 -6
- data/lib/prawn/blank/radio.rb +33 -0
- data/lib/prawn/blank/radio_group.rb +17 -0
- data/lib/prawn/blank/select.rb +26 -0
- data/lib/prawn/blank/text_field.rb +17 -17
- data/lib/prawn/blank/text_style.rb +24 -0
- metadata +42 -18
- data/lib/prawn/blank/style.rb +0 -3
- data/lib/prawn/page.rb +0 -19
data/Rakefile
CHANGED
@@ -1,33 +1,9 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.require :default, :development
|
2
4
|
require 'rake'
|
3
5
|
require 'rake/gempackagetask'
|
4
|
-
gem 'rspec'
|
5
|
-
require 'spec/version'
|
6
|
-
require 'spec/rake/spectask'
|
7
|
-
require 'spec/ruby'
|
8
|
-
|
9
|
-
task :default => [:package]
|
10
6
|
|
11
7
|
spec = Gem::Specification.load "prawn-blank.gemspec"
|
12
8
|
Rake::GemPackageTask.new(spec) do |pkg|
|
13
|
-
pkg.need_zip = true
|
14
|
-
pkg.need_tar = true
|
15
|
-
end
|
16
|
-
|
17
|
-
gem 'hoe', '>=2.0.0'
|
18
|
-
require 'hoe'
|
19
|
-
|
20
|
-
require 'spec/version'
|
21
|
-
require 'spec/rake/spectask'
|
22
|
-
require 'spec/ruby'
|
23
|
-
|
24
|
-
Spec::Rake::SpecTask.new('spec') do |t|
|
25
|
-
t.spec_files = FileList['spec/**/*.rb']
|
26
9
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
desc "Look for TODO and FIXME tags in the code"
|
31
|
-
task :todo do
|
32
|
-
egrep /(FIXME|TODO|TBD)/
|
33
|
-
end
|
data/lib/prawn-blank.rb
ADDED
data/lib/prawn/blank.rb
CHANGED
@@ -1,44 +1,115 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
module Prawn
|
2
3
|
module Blank
|
3
4
|
autoload :Form,"prawn/blank/form"
|
4
5
|
autoload :Style,"prawn/blank/style"
|
6
|
+
autoload :FieldBase,"prawn/blank/field_base"
|
5
7
|
autoload :Field,"prawn/blank/field"
|
6
8
|
autoload :Appearance,"prawn/blank/appearance"
|
7
9
|
autoload :TextField,"prawn/blank/text_field"
|
10
|
+
autoload :Checkbox,"prawn/blank/checkbox"
|
11
|
+
autoload :Select,"prawn/blank/select"
|
12
|
+
autoload :Combo,"prawn/blank/combo"
|
13
|
+
autoload :RadioGroup, "prawn/blank/radio_group"
|
14
|
+
autoload :Radio, "prawn/blank/radio"
|
15
|
+
autoload :TextStyle,"prawn/blank/text_style"
|
8
16
|
|
9
17
|
def text_field(options={})
|
10
|
-
|
18
|
+
if options[:at]
|
19
|
+
options[:at] = self.send(:map_to_absolute,options[:at])
|
20
|
+
end
|
21
|
+
#puts self.bounds.inspect
|
22
|
+
f=TextField.create(self,options)
|
11
23
|
if block_given?
|
12
24
|
yield(f)
|
13
25
|
end
|
14
26
|
add_field(f)
|
15
27
|
end
|
16
28
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
else
|
21
|
-
x,y=image_position(width,height,{})
|
22
|
-
move_text_position height
|
29
|
+
def select(options={})
|
30
|
+
if options[:at]
|
31
|
+
options[:at] = self.send(:map_to_absolute,options[:at])
|
23
32
|
end
|
24
|
-
|
33
|
+
f=Select.create(self,options)
|
34
|
+
if block_given?
|
35
|
+
yield(f)
|
36
|
+
end
|
37
|
+
add_field(f)
|
25
38
|
end
|
26
39
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
40
|
+
def checkbox(options={})
|
41
|
+
if options[:at]
|
42
|
+
options[:at] = self.send(:map_to_absolute,options[:at])
|
43
|
+
end
|
44
|
+
f=Checkbox.create(self,options)
|
45
|
+
if block_given?
|
46
|
+
yield(f)
|
47
|
+
end
|
48
|
+
add_field(f)
|
49
|
+
end
|
50
|
+
|
51
|
+
def radiogroup(options={})
|
52
|
+
f=RadioGroup.create(self,options)
|
53
|
+
if block_given?
|
54
|
+
yield(f)
|
55
|
+
end
|
56
|
+
return add_field(f)
|
57
|
+
end
|
58
|
+
|
59
|
+
def radio(options={})
|
60
|
+
if options[:at]
|
61
|
+
options[:at] = self.send(:map_to_absolute,options[:at])
|
62
|
+
end
|
63
|
+
f=Radio.create(self,options)
|
64
|
+
if block_given?
|
65
|
+
yield(f)
|
66
|
+
end
|
67
|
+
return add_field(f)
|
33
68
|
end
|
34
|
-
|
69
|
+
|
35
70
|
def acroform
|
36
|
-
store.root.data[:AcroForm] ||= ref!(Form.new)
|
37
|
-
store.root.data[:AcroForm].data
|
71
|
+
state.store.root.data[:AcroForm] ||= ref!(Form.new)
|
72
|
+
state.store.root.data[:AcroForm].data
|
73
|
+
end
|
74
|
+
|
75
|
+
attr_accessor :default_appearance
|
76
|
+
|
77
|
+
def default_appearance
|
78
|
+
@default_appearance ||= Appearance.new(self)
|
38
79
|
end
|
39
|
-
|
80
|
+
|
81
|
+
protected
|
82
|
+
def add_field(field)
|
83
|
+
field.finalize(self)
|
84
|
+
field.page = page.dictionary
|
85
|
+
acroform.add_field(field) if field.root?
|
86
|
+
page.dictionary.data[:Annots] ||= []
|
87
|
+
page.dictionary.data[:Annots] << field
|
88
|
+
return field
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def TextStyle(*args)
|
93
|
+
|
94
|
+
Prawn::Blank::TextStyle.new(*args)
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
def BorderStyle(doc,width,style=:S)
|
99
|
+
{
|
100
|
+
:W => width,
|
101
|
+
:Type => :Border,
|
102
|
+
:S => style
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
def ColorStyle(doc,fill,stroke)
|
107
|
+
{
|
108
|
+
:BC => doc.send(:normalize_color,stroke),
|
109
|
+
:BG => doc.send(:normalize_color,fill)
|
110
|
+
}
|
40
111
|
end
|
112
|
+
|
41
113
|
end
|
42
114
|
require 'prawn/document'
|
43
115
|
Prawn::Document.extensions << Prawn::Blank
|
44
|
-
require 'prawn/page'
|
@@ -1,22 +1,253 @@
|
|
1
|
-
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Prawn::Blank
|
3
|
+
class Appearance
|
2
4
|
|
3
|
-
attr_accessor :font,:font_subset,:font_size
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
class Item
|
7
|
+
|
8
|
+
|
9
|
+
def self.arguments(args={})
|
10
|
+
@arguments = args
|
11
|
+
end
|
12
|
+
|
13
|
+
def cache_key(elem)
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
|
8
18
|
end
|
9
|
-
end
|
10
19
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
20
|
+
attr_reader :document
|
21
|
+
|
22
|
+
STYLE = {
|
23
|
+
|
24
|
+
:border_color => '202020',
|
25
|
+
:background_color => 'ffffff',
|
26
|
+
:border_width => 1
|
27
|
+
|
28
|
+
}
|
29
|
+
|
30
|
+
def initialize(document)
|
31
|
+
@document = document
|
32
|
+
@cache = {}
|
33
|
+
#@style = STYLE.dup
|
16
34
|
end
|
35
|
+
|
36
|
+
def render(dict)
|
37
|
+
dict = {:Subtype => :Form,
|
38
|
+
:Resources => {:ProcSet => [:PDF, :ImageC, :ImageI, :ImageB]}}.merge(dict)
|
39
|
+
|
40
|
+
result = @document.ref!(dict)
|
41
|
+
@document.state.page.stamp_stream(result) do
|
42
|
+
yield
|
43
|
+
end
|
44
|
+
@document.acroform.add_resources(result.data[:Resources])
|
45
|
+
return result
|
46
|
+
end
|
47
|
+
|
48
|
+
def button(element)
|
49
|
+
if !element.width or element.width <= 0
|
50
|
+
element.width = 10
|
51
|
+
end
|
52
|
+
if !element.height or element.height <= 0
|
53
|
+
element.height = 10
|
54
|
+
end
|
55
|
+
width = element.width
|
56
|
+
height = element.height
|
57
|
+
style = element.style ||= Prawn::ColorStyle(@document,'ffffff','000000')
|
58
|
+
border_style = element.border_style ||= Prawn::BorderStyle(@document,1)
|
59
|
+
return cached(:checkbox_off, width, height, style, border_style) do
|
60
|
+
render( :BBox => [0, 0, width, height] ) do
|
61
|
+
document.canvas do
|
62
|
+
# render background
|
63
|
+
document.fill_color( *denormalize_color(style[:BG]) )
|
64
|
+
document.stroke_color( *denormalize_color(style[:BC]) )
|
65
|
+
document.line_width(border_style[:W])
|
66
|
+
bw = border_style[:W]/2.0
|
67
|
+
document.fill_and_stroke_rectangle( [bw, height - bw], width - border_style[:W], height - border_style[:W] )
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
alias_method :button_over, :button
|
74
|
+
alias_method :button_down, :button
|
75
|
+
|
76
|
+
def checkbox_off(element)
|
77
|
+
if !element.width or element.width <= 0
|
78
|
+
element.width = 10
|
79
|
+
end
|
80
|
+
if !element.height or element.height <= 0
|
81
|
+
element.height = 10
|
82
|
+
end
|
83
|
+
width = element.width
|
84
|
+
height = element.height
|
85
|
+
style = element.style ||= Prawn::ColorStyle(@document,'ffffff','000000')
|
86
|
+
border_style = element.border_style ||= Prawn::BorderStyle(@document,1)
|
87
|
+
return cached(:checkbox_off, width, height, style, border_style) do
|
88
|
+
render( :BBox => [0, 0, width, height] ) do
|
89
|
+
document.canvas do
|
90
|
+
# render background
|
91
|
+
document.fill_color( *denormalize_color(style[:BG]) )
|
92
|
+
document.stroke_color( *denormalize_color(style[:BC]) )
|
93
|
+
document.line_width(border_style[:W])
|
94
|
+
bw = border_style[:W]/2.0
|
95
|
+
document.fill_and_stroke_rectangle( [bw, height - bw], width - border_style[:W], height - border_style[:W] )
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
alias_method :checkbox_off_over, :checkbox_off
|
102
|
+
alias_method :checkbox_off_down, :checkbox_off
|
103
|
+
|
104
|
+
def checkbox_on(element)
|
105
|
+
if !element.width or element.width <= 0
|
106
|
+
element.width = 10
|
107
|
+
end
|
108
|
+
if !element.height or element.height <= 0
|
109
|
+
element.height = 10
|
110
|
+
end
|
111
|
+
width = element.width
|
112
|
+
height = element.height
|
113
|
+
style = element.style ||= Prawn::ColorStyle(@document,'ffffff','000000')
|
114
|
+
border_style = element.border_style ||= Prawn::BorderStyle(@document,1)
|
115
|
+
return cached(:checkbox_on, width, height, style, border_style) do
|
116
|
+
render( :BBox => [0, 0, width, height] ) do
|
117
|
+
document.canvas do
|
118
|
+
# render background
|
119
|
+
document.fill_color( *denormalize_color(style[:BG]) )
|
120
|
+
document.stroke_color( *denormalize_color(style[:BC]) )
|
121
|
+
document.line_width(border_style[:W])
|
122
|
+
bw = border_style[:W]/2.0
|
123
|
+
document.fill_and_stroke_rectangle( [bw, height - bw], width - border_style[:W], height - border_style[:W] )
|
124
|
+
document.stroke_line(0,0,width, height)
|
125
|
+
document.stroke_line(width,0,0, height)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
alias_method :checkbox_on_over, :checkbox_on
|
132
|
+
alias_method :checkbox_on_down, :checkbox_on
|
133
|
+
|
134
|
+
def radio_off(element)
|
135
|
+
if !element.width or element.width <= 0
|
136
|
+
element.width = 10
|
137
|
+
end
|
138
|
+
if !element.height or element.height <= 0
|
139
|
+
element.height = 10
|
140
|
+
end
|
141
|
+
width = element.width
|
142
|
+
height = element.height
|
143
|
+
style = element.style ||= Prawn::ColorStyle(@document,'ffffff','000000')
|
144
|
+
border_style = element.border_style ||= Prawn::BorderStyle(@document,1)
|
145
|
+
return cached(:radio_off, width, height, style, border_style) do
|
146
|
+
render( :BBox => [0, 0, width, height] ) do
|
147
|
+
document.canvas do
|
148
|
+
# render background
|
149
|
+
document.fill_color( *denormalize_color(style[:BG]) )
|
150
|
+
document.stroke_color( *denormalize_color(style[:BC]) )
|
151
|
+
document.line_width(border_style[:W])
|
152
|
+
rx = (width / 2.0)
|
153
|
+
ry = (height / 2.0)
|
154
|
+
document.fill_and_stroke_ellipse_at([rx,ry], rx-border_style[:W], ry-border_style[:W])
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
alias_method :radio_off_over, :radio_off
|
161
|
+
alias_method :radio_off_down, :radio_off
|
162
|
+
|
163
|
+
def radio_on(element)
|
164
|
+
if !element.width or element.width <= 0
|
165
|
+
element.width = 10
|
166
|
+
end
|
167
|
+
if !element.height or element.height <= 0
|
168
|
+
element.height = 10
|
169
|
+
end
|
170
|
+
width = element.width
|
171
|
+
height = element.height
|
172
|
+
style = element.style ||= Prawn::ColorStyle(@document,'ffffff','000000')
|
173
|
+
border_style = element.border_style ||= Prawn::BorderStyle(@document,1)
|
174
|
+
return cached(:radio_on, width, height, style, border_style) do
|
175
|
+
render( :BBox => [0, 0, width, height] ) do
|
176
|
+
document.canvas do
|
177
|
+
# render background
|
178
|
+
document.fill_color( *denormalize_color(style[:BG]) )
|
179
|
+
document.stroke_color( *denormalize_color(style[:BC]) )
|
180
|
+
document.line_width(border_style[:W])
|
181
|
+
rx = (width / 2.0)
|
182
|
+
ry = (height / 2.0)
|
183
|
+
document.fill_and_stroke_ellipse_at([rx,ry], rx-border_style[:W], ry-border_style[:W])
|
184
|
+
|
185
|
+
document.fill_color( *denormalize_color(style[:BC]) )
|
186
|
+
document.fill_ellipse_at([rx,ry], rx-border_style[:W]-2, ry-border_style[:W]-2)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
alias_method :radio_on_over, :radio_on
|
193
|
+
alias_method :radio_on_down, :radio_on
|
194
|
+
|
195
|
+
def text_field(element)
|
196
|
+
|
197
|
+
text_style = element.text_style ||= Prawn::TextStyle(@document,"Helvetica",9,'000000')
|
198
|
+
border_style = element.border_style ||= Prawn::BorderStyle(@document,1)
|
199
|
+
|
200
|
+
if !element.width or element.width <= 0
|
201
|
+
element.width = 100
|
202
|
+
end
|
203
|
+
if !element.height or element.height <= 0
|
204
|
+
element.height = text_style.size + 6 + 2 * border_style[:W]
|
205
|
+
end
|
206
|
+
width = element.width
|
207
|
+
height = element.height
|
208
|
+
style = element.style ||= Prawn::ColorStyle(@document,'ffffff','000000')
|
209
|
+
multiline = element.multiline
|
210
|
+
value = element.value
|
211
|
+
return cached(:text_field, width, height, style, border_style, text_style, multiline, value) do
|
212
|
+
render( :BBox => [0, 0, width, height] ) do
|
213
|
+
document.canvas do
|
214
|
+
document.save_font do
|
215
|
+
# render background
|
216
|
+
document.fill_color( *denormalize_color(style[:BG]) )
|
217
|
+
document.stroke_color( *denormalize_color(style[:BC]) )
|
218
|
+
document.line_width(border_style[:W])
|
219
|
+
bw = border_style[:W]/2.0
|
220
|
+
document.fill_and_stroke_rectangle( [bw, height - bw], width - border_style[:W], height - border_style[:W])
|
221
|
+
if text_style
|
222
|
+
document.font(text_style.font, :size=>text_style.size )
|
223
|
+
document.fill_color( *text_style.color )
|
224
|
+
end
|
225
|
+
if value
|
226
|
+
document.draw_text(value, :at =>[border_style[:W]+1, [1,height - document.font_size - border_style[:W]- 1.5].max ] )
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
protected
|
236
|
+
def cached(*args)
|
237
|
+
@cache[args] ||= yield
|
238
|
+
end
|
239
|
+
|
240
|
+
def denormalize_color(color)
|
241
|
+
s = color.size
|
242
|
+
if( s == 1 ) # gray
|
243
|
+
return [0,0,0,color[0]]
|
244
|
+
elsif( s == 3 ) # rgb
|
245
|
+
return Prawn::Graphics::Color.rgb2hex(color.map{|component| component * 255.0})
|
246
|
+
elsif( s == 4 ) # cmyk
|
247
|
+
return color.map{|component| component * 100.0}
|
248
|
+
end
|
249
|
+
raise "Unknown color: #{color}"
|
250
|
+
end
|
251
|
+
|
17
252
|
end
|
18
|
-
|
19
|
-
def to_s
|
20
|
-
Prawn::LiteralString.new "/#{font.identifier_for(0)} #{font_size} Tf"
|
21
|
-
end
|
22
|
-
end
|
253
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
class Prawn::Blank::Checkbox < Prawn::Blank::Field
|
3
|
+
|
4
|
+
def checked
|
5
|
+
return @data[:AS] == :Yes
|
6
|
+
end
|
7
|
+
|
8
|
+
def checked=(value)
|
9
|
+
if value
|
10
|
+
@data[:AS] = :Yes
|
11
|
+
@data[:V] = :Yes
|
12
|
+
else
|
13
|
+
@data[:AS] = :Off
|
14
|
+
@data[:V] = :Off
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def finalize(document)
|
19
|
+
# render this field
|
20
|
+
|
21
|
+
app = self.appearance || document.default_appearance
|
22
|
+
|
23
|
+
@data[:AP] = {:N =>{:Off=>app.checkbox_off(self),:Yes=>app.checkbox_on(self)},
|
24
|
+
:R =>{:Off=>app.checkbox_off_over(self),:Yes=>app.checkbox_on_over(self)},
|
25
|
+
:D =>{:Off=>app.checkbox_off_down(self),:Yes=>app.checkbox_on_down(self)}}
|
26
|
+
return
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def default_options
|
33
|
+
super.merge({:FT=>:Btn})
|
34
|
+
end
|
35
|
+
end
|
data/lib/prawn/blank/field.rb
CHANGED
@@ -1,89 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
# see pdf reference for documentation
|
4
|
-
FF_FLAGS={
|
5
|
-
:readonly => 1,
|
6
|
-
:required => 2,
|
7
|
-
:no_export => 3,
|
8
|
-
|
9
|
-
# for text fields
|
10
|
-
:multiline => 13,
|
11
|
-
:password => 14,
|
12
|
-
|
13
|
-
# for buttons
|
14
|
-
:no_toggle_to_off => 15
|
15
|
-
}
|
16
|
-
|
17
|
-
def initialize(document,*args)
|
18
|
-
@document=document
|
19
|
-
options = (args.last.kind_of?(Hash) ? args.pop : {})
|
20
|
-
Prawn.verify_options self.class.get_possible_options, options
|
21
|
-
puts self.methods.sort.inspect
|
22
|
-
options = default_options.merge(options)
|
23
|
-
options.each do |k,v|
|
24
|
-
self.send "#{k.to_s}=".to_sym,v
|
25
|
-
end
|
26
|
-
puts options.inspect
|
27
|
-
#@options=options
|
28
|
-
end
|
29
|
-
|
30
|
-
|
31
|
-
def to_h
|
32
|
-
get_dict
|
33
|
-
end
|
34
|
-
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
class Prawn::Blank::Field < Prawn::Blank::FieldBase
|
35
3
|
|
36
4
|
protected
|
37
5
|
def get_dict
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
base={
|
47
|
-
:Type => :Annot,
|
48
|
-
:Subtype => :Widget,
|
49
|
-
:DA => app.to_s,
|
50
|
-
:F => 4,
|
51
|
-
:BS => {:Type => :Border, :W => 1, :S => :S},
|
52
|
-
:MK => {:BC => [0, 0, 0]}
|
53
|
-
}
|
54
|
-
unless self.name.kind_of? Prawn::LiteralString
|
55
|
-
self.name= Prawn::LiteralString.new(self.name)
|
56
|
-
end
|
57
|
-
|
58
|
-
base[:T]=self.name
|
59
|
-
|
60
|
-
base[:Rect]=@document.get_field_rect(self.at, self.width, self.height)
|
61
|
-
|
62
|
-
base[:V]=self.value if self.value
|
63
|
-
base[:DV]=self.default_value if self.default_value
|
64
|
-
|
65
|
-
ff=0
|
66
|
-
|
67
|
-
FF_FLAGS.each do |key,value|
|
68
|
-
if self.send(key)
|
69
|
-
ff += (1<<(value-1))
|
6
|
+
base = super
|
7
|
+
if self.appearance
|
8
|
+
|
9
|
+
app=Prawn::Blank::Appearance.cast(self.appearance)
|
10
|
+
|
11
|
+
app.font.instance_eval do
|
12
|
+
@references[0] ||= register(0)
|
13
|
+
@document.acroform.add_resource(:Font,identifier_for(0),@references[0])
|
70
14
|
end
|
15
|
+
|
16
|
+
base.merge! app.apply_to(self)
|
71
17
|
end
|
72
|
-
|
73
|
-
base[:Ff]=ff
|
74
|
-
|
75
18
|
return base
|
76
19
|
end
|
77
|
-
|
78
|
-
def default_options
|
79
|
-
{}
|
80
|
-
end
|
81
|
-
|
82
|
-
def self.get_possible_options
|
83
|
-
[:at, :height, :width, :name, :appearance, :value, :default_value] + FF_FLAGS.keys
|
84
|
-
end
|
85
|
-
|
86
|
-
public
|
87
|
-
attr_accessor *get_possible_options
|
88
|
-
|
89
|
-
end
|
20
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
class Prawn::Blank::FieldBase < Prawn::Core::Reference
|
3
|
+
|
4
|
+
|
5
|
+
# see pdf reference for documentation
|
6
|
+
FF_FLAGS={
|
7
|
+
:readonly => 1,
|
8
|
+
:required => 2,
|
9
|
+
:no_export => 3,
|
10
|
+
|
11
|
+
# for text fields
|
12
|
+
:multiline => 13,
|
13
|
+
:password => 14,
|
14
|
+
|
15
|
+
# for buttons
|
16
|
+
:no_toggle_to_off => 15
|
17
|
+
}
|
18
|
+
|
19
|
+
class << self
|
20
|
+
|
21
|
+
def field_attr_accessor(name,key,inheritable=true)
|
22
|
+
self.class_eval <<EVAL
|
23
|
+
def #{name.to_s}
|
24
|
+
if #{inheritable.inspect} and !@data.key?(#{key.to_sym.inspect}) and self.parent?
|
25
|
+
return self.parent.#{name.to_s}
|
26
|
+
end
|
27
|
+
@data[#{key.to_sym.inspect}]
|
28
|
+
end
|
29
|
+
def #{name.to_s}=(value)
|
30
|
+
@data[#{key.to_sym.inspect}]=value
|
31
|
+
end
|
32
|
+
def delete_#{name.to_s}
|
33
|
+
@data.delete #{key.to_sym.inspect}
|
34
|
+
end
|
35
|
+
def #{name.to_s}?
|
36
|
+
if #{inheritable.inspect}
|
37
|
+
@data.key?(#{key.to_sym.inspect}) or ( self.parent? and self.parent.#{name.to_s}?)
|
38
|
+
else
|
39
|
+
@data.key? #{key.to_sym.inspect}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
def own_#{name.to_s}?
|
43
|
+
@data.key? #{key.to_sym.inspect}
|
44
|
+
end
|
45
|
+
EVAL
|
46
|
+
end
|
47
|
+
|
48
|
+
def flag_accessor(name,bit,flag_name='flags')
|
49
|
+
mask = (1 << (bit-1))
|
50
|
+
|
51
|
+
self.class_eval <<EVAL
|
52
|
+
def #{name.to_s}
|
53
|
+
(self.#{flag_name} || 0) & #{mask.inspect}
|
54
|
+
end
|
55
|
+
|
56
|
+
alias #{name.to_s}? #{name.to_s}
|
57
|
+
|
58
|
+
def #{name.to_s}=(value)
|
59
|
+
if value
|
60
|
+
self.#{flag_name} = (self.#{flag_name} || 0) | #{mask.inspect}
|
61
|
+
else
|
62
|
+
self.#{flag_name} = (self.#{flag_name} || 0) & ~#{mask.inspect}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
EVAL
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
field_attr_accessor :rect,:Rect, false
|
71
|
+
field_attr_accessor :parent,:Parent, false
|
72
|
+
field_attr_accessor :children,:Kids, false
|
73
|
+
field_attr_accessor :type, :FT
|
74
|
+
field_attr_accessor :aflags, :F
|
75
|
+
field_attr_accessor :flags, :Ff
|
76
|
+
field_attr_accessor :name, :T, false
|
77
|
+
field_attr_accessor :fullname, :TU, false
|
78
|
+
field_attr_accessor :value, :V
|
79
|
+
field_attr_accessor :default_value, :DV
|
80
|
+
field_attr_accessor :text_style, :DA
|
81
|
+
field_attr_accessor :_app, :AP
|
82
|
+
field_attr_accessor :border_style, :BS
|
83
|
+
field_attr_accessor :style, :MK
|
84
|
+
field_attr_accessor :page, :P
|
85
|
+
field_attr_accessor :options, :Opt
|
86
|
+
|
87
|
+
flag_accessor :invisible, 1, 'aflags'
|
88
|
+
flag_accessor :hidden, 2, 'aflags'
|
89
|
+
flag_accessor :print, 3, 'aflags'
|
90
|
+
flag_accessor :no_zoom, 4, 'aflags'
|
91
|
+
|
92
|
+
flag_accessor :readonly, 1
|
93
|
+
flag_accessor :required, 2
|
94
|
+
flag_accessor :no_export, 3
|
95
|
+
|
96
|
+
flag_accessor :multiline, 13
|
97
|
+
flag_accessor :password, 14
|
98
|
+
flag_accessor :no_toggle_to_off, 15
|
99
|
+
|
100
|
+
flag_accessor :combo, 18
|
101
|
+
flag_accessor :editable, 19
|
102
|
+
|
103
|
+
alias_method :_parent=, :parent=
|
104
|
+
|
105
|
+
def parent=(p)
|
106
|
+
if parent?
|
107
|
+
self.parent.children.delete(self)
|
108
|
+
end
|
109
|
+
p.children ||= []
|
110
|
+
p.children << self
|
111
|
+
self._parent = p
|
112
|
+
end
|
113
|
+
|
114
|
+
def appearance
|
115
|
+
return @appearance if @appearance
|
116
|
+
if parent?
|
117
|
+
return parent.appearance
|
118
|
+
end
|
119
|
+
return nil
|
120
|
+
end
|
121
|
+
|
122
|
+
def appearance=(app)
|
123
|
+
@appearance=app
|
124
|
+
end
|
125
|
+
|
126
|
+
def leaf?
|
127
|
+
!children?
|
128
|
+
end
|
129
|
+
|
130
|
+
def root?
|
131
|
+
!parent?
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.create(document, *args, &block)
|
135
|
+
document.state.store.push( self.new(document.state.store.size+1,*args, &block) )
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.from_ref(ref)
|
139
|
+
result = self.new(ref.identifier)
|
140
|
+
result.data = ref.data
|
141
|
+
return result
|
142
|
+
end
|
143
|
+
|
144
|
+
def initialize(id,*args)
|
145
|
+
super( id, self.default_options )
|
146
|
+
|
147
|
+
# okay, we print this annot by default
|
148
|
+
self.print = true
|
149
|
+
|
150
|
+
options = (args.last.kind_of?(Hash) ? args.pop : {})
|
151
|
+
options.each do |k,v|
|
152
|
+
self.send "#{k.to_s}=".to_sym,v
|
153
|
+
end
|
154
|
+
|
155
|
+
yield self if block_given?
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
def width
|
160
|
+
r = self.rect
|
161
|
+
return (r[2] - r[0]).abs
|
162
|
+
end
|
163
|
+
|
164
|
+
def width=(w)
|
165
|
+
self.rect[2] = self.rect[0] + w
|
166
|
+
end
|
167
|
+
|
168
|
+
def height
|
169
|
+
r = self.rect
|
170
|
+
return (r[3] - r[1]).abs
|
171
|
+
end
|
172
|
+
|
173
|
+
def height=(h)
|
174
|
+
self.rect[3] = self.rect[1] + h
|
175
|
+
end
|
176
|
+
|
177
|
+
def at
|
178
|
+
self.rect[0..1]
|
179
|
+
end
|
180
|
+
|
181
|
+
def at=(*args)
|
182
|
+
x,y = args.flatten
|
183
|
+
self.rect = [x,y,x + width, y - height]
|
184
|
+
end
|
185
|
+
|
186
|
+
def validate!
|
187
|
+
raise "Blank: Type must be :Annot " if self.data[:Type] != :Annot
|
188
|
+
raise "Blank: Subtype must be :Annot " if self.data[:Subtype] != :Widget
|
189
|
+
if leaf?
|
190
|
+
raise "Blank: FT ( Field Type ) must be :Btn, :Tx, :Ch or :Sig " unless [:Btn, :Tx, :Ch, :Sig].include self.type
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def finalize(document)
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
def denormalize_color(color)
|
199
|
+
s = color.size
|
200
|
+
if( s == 1 ) # gray
|
201
|
+
return [0,0,0,color[0]]
|
202
|
+
elsif( s == 3 ) # rgb
|
203
|
+
return Prawn::Graphics::Color.rgb2hex(color.map{|component| component * 255.0})
|
204
|
+
elsif( s == 4 ) # cmyk
|
205
|
+
return color.map{|component| component * 100.0}
|
206
|
+
end
|
207
|
+
raise "Unknown color: #{color}"
|
208
|
+
end
|
209
|
+
|
210
|
+
protected
|
211
|
+
|
212
|
+
def default_options
|
213
|
+
{
|
214
|
+
:Type=>:Annot,
|
215
|
+
:Subtype=>:Widget,
|
216
|
+
:Rect=>[0,0,0,0]
|
217
|
+
}
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
data/lib/prawn/blank/form.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
class Prawn::Blank::Form < Hash
|
2
3
|
def initialize()
|
3
4
|
super()
|
@@ -5,16 +6,20 @@ class Prawn::Blank::Form < Hash
|
|
5
6
|
self[:Fields] = []
|
6
7
|
end
|
7
8
|
|
8
|
-
def
|
9
|
+
def add_resource(type,name,dict)
|
9
10
|
self[:DR][type] ||={}
|
10
11
|
self[:DR][type][name] ||= dict
|
11
12
|
end
|
12
13
|
|
13
|
-
def
|
14
|
-
puts hash.inspect
|
14
|
+
def add_resources(hash)
|
15
15
|
hash.each do |type, names|
|
16
|
-
names.
|
17
|
-
|
16
|
+
if names.kind_of? Array
|
17
|
+
self[:DR][type] ||= []
|
18
|
+
self[:DR][type] = self[:DR][type] | names
|
19
|
+
else
|
20
|
+
names.each do |name,dict|
|
21
|
+
add_resource(type, name, dict)
|
22
|
+
end
|
18
23
|
end
|
19
24
|
end
|
20
25
|
end
|
@@ -22,4 +27,4 @@ class Prawn::Blank::Form < Hash
|
|
22
27
|
def add_field(field)
|
23
28
|
self[:Fields] << field
|
24
29
|
end
|
25
|
-
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Prawn::Blank
|
3
|
+
class Radio < Field
|
4
|
+
|
5
|
+
def value=(v)
|
6
|
+
@value = v
|
7
|
+
end
|
8
|
+
|
9
|
+
def value
|
10
|
+
@value
|
11
|
+
end
|
12
|
+
|
13
|
+
def finalize(document)
|
14
|
+
# render this field
|
15
|
+
|
16
|
+
app = self.appearance || document.default_appearance
|
17
|
+
|
18
|
+
@data[:AP] = {:N =>{:Off=>app.radio_off(self), @value=>app.radio_on(self)},
|
19
|
+
:R =>{:Off=>app.radio_off_over(self),@value=>app.radio_on_over(self)},
|
20
|
+
:D =>{:Off=>app.radio_off_down(self),@value=>app.radio_on_down(self)}}
|
21
|
+
@data[:AS] = (self.parent.value == @value) ? @value : :Off
|
22
|
+
@data[:V] = @value
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
def default_options
|
28
|
+
super.merge({:FT => :Btn, :Ff => 32768})
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Prawn::Blank
|
3
|
+
class RadioGroup < Field
|
4
|
+
|
5
|
+
def finalize(document)
|
6
|
+
#@data[:DA] = "/F1.0 9 Tf 0.000 1.000 0.000 rg"
|
7
|
+
#@data[:V] = :Off
|
8
|
+
@data.delete :Rect
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
def default_options
|
13
|
+
super.merge({:FT => :Btn, :Ff => 32768})
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
class Prawn::Blank::Select < Prawn::Blank::Field
|
3
|
+
|
4
|
+
def initialize(*args)
|
5
|
+
super
|
6
|
+
self.combo = true
|
7
|
+
end
|
8
|
+
|
9
|
+
def finalize(document)
|
10
|
+
# render this field
|
11
|
+
|
12
|
+
app = self.appearance || document.default_appearance
|
13
|
+
|
14
|
+
@data[:AP] = {:N=>app.text_field(self)}
|
15
|
+
@data[:AS] = :N
|
16
|
+
|
17
|
+
#document.acroform.add_resources(da.data[:Resources])
|
18
|
+
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
def default_options
|
24
|
+
super.merge({:FT => :Ch})
|
25
|
+
end
|
26
|
+
end
|
@@ -1,23 +1,23 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
class Prawn::Blank::TextField < Prawn::Blank::Field
|
2
3
|
|
4
|
+
#attr_accessor :text_style
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
def get_dict
|
7
|
-
base = super
|
8
|
-
base[:BS][:S]=:U
|
9
|
-
base[:FT]=:Tx
|
10
|
-
|
11
|
-
return base
|
12
|
-
end
|
6
|
+
def finalize(document)
|
7
|
+
# render this field
|
13
8
|
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
app = self.appearance || document.default_appearance
|
10
|
+
|
11
|
+
@data[:AP] = {:N=>app.text_field(self)}
|
12
|
+
@data[:AS] = :N
|
13
|
+
|
14
|
+
#document.acroform.add_resources(da.data[:Resources])
|
15
|
+
|
16
|
+
return
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
protected
|
20
|
+
def default_options
|
21
|
+
super.merge({:FT => :Tx})
|
20
22
|
end
|
21
|
-
|
22
|
-
attr_accessor *get_possible_options
|
23
|
-
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Prawn::Blank
|
3
|
+
class TextStyle < Prawn::Core::LiteralString
|
4
|
+
|
5
|
+
attr_reader :font, :color, :size
|
6
|
+
|
7
|
+
def initialize(document, font,size,color,font_subset=0)
|
8
|
+
@font = font
|
9
|
+
@font_subset = font_subset
|
10
|
+
@size = size
|
11
|
+
@color = color
|
12
|
+
@color = [@color] unless color.kind_of? Array
|
13
|
+
super("/#{document.font(font).identifier_for(font_subset)} #{size} Tf #{document.send(:color_to_s,*@color)} #{color_cmd(@color)}")
|
14
|
+
end
|
15
|
+
|
16
|
+
def color_cmd(color)
|
17
|
+
if color[0].kind_of? String
|
18
|
+
return 'rg'
|
19
|
+
else
|
20
|
+
return 'k'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prawn-blank
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
|
-
-
|
12
|
+
- HannesG
|
8
13
|
autorequire:
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
@@ -14,24 +19,33 @@ default_executable:
|
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: prawn
|
17
|
-
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
20
24
|
requirements:
|
21
|
-
- - "
|
25
|
+
- - "="
|
22
26
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 11
|
30
|
+
- 1
|
31
|
+
- pre
|
32
|
+
version: 0.11.1.pre
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *id001
|
25
36
|
- !ruby/object:Gem::Dependency
|
26
37
|
name: rspec
|
27
|
-
|
28
|
-
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
30
40
|
requirements:
|
31
41
|
- - ">="
|
32
42
|
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 0
|
33
45
|
version: "0"
|
34
|
-
|
46
|
+
type: :development
|
47
|
+
prerelease: false
|
48
|
+
version_requirements: *id002
|
35
49
|
description: prawn-blank adds forms to prawn
|
36
50
|
email: hannes.georg@googlemail.com
|
37
51
|
executables: []
|
@@ -41,13 +55,18 @@ extensions: []
|
|
41
55
|
extra_rdoc_files: []
|
42
56
|
|
43
57
|
files:
|
58
|
+
- lib/prawn/blank/text_style.rb
|
59
|
+
- lib/prawn/blank/radio_group.rb
|
60
|
+
- lib/prawn/blank/radio.rb
|
44
61
|
- lib/prawn/blank/text_field.rb
|
45
|
-
- lib/prawn/blank/
|
62
|
+
- lib/prawn/blank/checkbox.rb
|
46
63
|
- lib/prawn/blank/appearance.rb
|
64
|
+
- lib/prawn/blank/select.rb
|
65
|
+
- lib/prawn/blank/field_base.rb
|
47
66
|
- lib/prawn/blank/field.rb
|
48
67
|
- lib/prawn/blank/form.rb
|
49
|
-
- lib/prawn/page.rb
|
50
68
|
- lib/prawn/blank.rb
|
69
|
+
- lib/prawn-blank.rb
|
51
70
|
- Rakefile
|
52
71
|
has_rdoc: true
|
53
72
|
homepage:
|
@@ -59,23 +78,28 @@ rdoc_options: []
|
|
59
78
|
require_paths:
|
60
79
|
- lib
|
61
80
|
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
62
82
|
requirements:
|
63
83
|
- - ">="
|
64
84
|
- !ruby/object:Gem::Version
|
85
|
+
hash: 2928840902442101454
|
86
|
+
segments:
|
87
|
+
- 0
|
65
88
|
version: "0"
|
66
|
-
version:
|
67
89
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
68
91
|
requirements:
|
69
92
|
- - ">="
|
70
93
|
- !ruby/object:Gem::Version
|
94
|
+
segments:
|
95
|
+
- 0
|
71
96
|
version: "0"
|
72
|
-
version:
|
73
97
|
requirements: []
|
74
98
|
|
75
99
|
rubyforge_project:
|
76
|
-
rubygems_version: 1.3.
|
100
|
+
rubygems_version: 1.3.7
|
77
101
|
signing_key:
|
78
102
|
specification_version: 3
|
79
|
-
summary:
|
103
|
+
summary: This is a experimental library. See the basic example for usage and abilities.
|
80
104
|
test_files: []
|
81
105
|
|
data/lib/prawn/blank/style.rb
DELETED
data/lib/prawn/page.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
class Prawn::Core::Page
|
2
|
-
|
3
|
-
def appearance_stream(appearance)
|
4
|
-
@stamp_stream = ""
|
5
|
-
@stamp_dictionary = appearance.dictionary
|
6
|
-
|
7
|
-
appearance.block.call()
|
8
|
-
|
9
|
-
document.instance_eval do
|
10
|
-
font.add_to_current_page(0)
|
11
|
-
add_content "/#{font.identifier_for(0)} #{font_size} Tf"
|
12
|
-
end
|
13
|
-
|
14
|
-
appearance.stream = @stamp_stream
|
15
|
-
|
16
|
-
@stamp_stream = nil
|
17
|
-
@stamp_dictionary = nil
|
18
|
-
end
|
19
|
-
end
|