prawn-blank 0.0.1 → 0.0.2

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/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