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 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
@@ -0,0 +1,2 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require "prawn/blank"
@@ -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
- f=TextField.new(self,options)
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 get_field_rect(at,width,height)
18
- unless at.nil?
19
- x,y=map_to_absolute(at)
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
- return [x,y,x+width,y+height]
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
- #protected
28
- def add_field(field)
29
- annotation = ref!(field.to_h)
30
- acroform.add_field(annotation)
31
- page.dictionary.data[:Annots] ||= []
32
- page.dictionary.data[:Annots] << annotation
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
- class Prawn::Blank::Appearance
1
+ # -*- encoding : utf-8 -*-
2
+ module Prawn::Blank
3
+ class Appearance
2
4
 
3
- attr_accessor :font,:font_subset,:font_size
4
5
 
5
- def initialize(options={})
6
- options.each do |k,v|
7
- self.send "#{k.to_s}=".to_sym,v
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
- def self.cast(hsh)
12
- if hsh.kind_of? self
13
- return hsh
14
- else
15
- return self.new(hsh)
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
@@ -1,89 +1,20 @@
1
- class Prawn::Blank::Field
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
- app=Prawn::Blank::Appearance.cast(self.appearance)
40
-
41
- app.font.instance_eval do
42
- @references[0] ||= register(0)
43
- @document.acroform.add_ressource(:Font,identifier_for(0),@references[0])
44
- end
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
@@ -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 add_ressource(type,name,dict)
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 add_ressources(hash)
14
- puts hash.inspect
14
+ def add_resources(hash)
15
15
  hash.each do |type, names|
16
- names.each do |name,dict|
17
- add_ressource(type, name, dict)
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
- protected
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
- def default_options
15
- super().merge({:height=>10})
16
- end
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
- def self.get_possible_options
19
- super() + [:font,:font_size]
19
+ protected
20
+ def default_options
21
+ super.merge({:FT => :Tx})
20
22
  end
21
- public
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
- version: 0.0.1
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
5
10
  platform: ruby
6
11
  authors:
7
- - HanneG
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
- type: :runtime
18
- version_requirement:
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
- version: "0.84"
24
- version:
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
- type: :development
28
- version_requirement:
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
- version:
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/style.rb
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.5
100
+ rubygems_version: 1.3.7
77
101
  signing_key:
78
102
  specification_version: 3
79
- summary: prawn-blank adds forms to prawn
103
+ summary: This is a experimental library. See the basic example for usage and abilities.
80
104
  test_files: []
81
105
 
@@ -1,3 +0,0 @@
1
- class Prawn::Blank::Style
2
-
3
- end
@@ -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