prawn-core 0.7.2 → 0.8.4

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.
Files changed (65) hide show
  1. data/Rakefile +1 -1
  2. data/examples/general/background.rb +1 -1
  3. data/examples/general/measurement_units.rb +2 -2
  4. data/examples/general/outlines.rb +50 -0
  5. data/examples/general/repeaters.rb +11 -7
  6. data/examples/general/stamp.rb +6 -6
  7. data/examples/graphics/basic_images.rb +1 -1
  8. data/examples/graphics/curves.rb +1 -1
  9. data/examples/graphics/rounded_polygons.rb +19 -0
  10. data/examples/graphics/rounded_rectangle.rb +20 -0
  11. data/examples/graphics/transformations.rb +52 -0
  12. data/examples/m17n/win_ansi_charset.rb +1 -1
  13. data/examples/text/font_calculations.rb +3 -3
  14. data/examples/text/indent_paragraphs.rb +18 -0
  15. data/examples/text/kerning.rb +4 -4
  16. data/examples/text/rotated.rb +98 -0
  17. data/examples/text/simple_text.rb +3 -3
  18. data/examples/text/simple_text_ttf.rb +1 -1
  19. data/lib/prawn/byte_string.rb +1 -0
  20. data/lib/prawn/core.rb +12 -5
  21. data/lib/prawn/core/object_store.rb +99 -0
  22. data/lib/prawn/core/page.rb +96 -0
  23. data/lib/prawn/core/text.rb +75 -0
  24. data/lib/prawn/document.rb +71 -78
  25. data/lib/prawn/document/annotations.rb +2 -2
  26. data/lib/prawn/document/bounding_box.rb +19 -9
  27. data/lib/prawn/document/column_box.rb +13 -12
  28. data/lib/prawn/document/graphics_state.rb +49 -0
  29. data/lib/prawn/document/internals.rb +5 -40
  30. data/lib/prawn/document/page_geometry.rb +1 -18
  31. data/lib/prawn/document/snapshot.rb +12 -7
  32. data/lib/prawn/errors.rb +18 -0
  33. data/lib/prawn/font.rb +4 -2
  34. data/lib/prawn/font/afm.rb +8 -0
  35. data/lib/prawn/font/dfont.rb +12 -4
  36. data/lib/prawn/font/ttf.rb +9 -0
  37. data/lib/prawn/graphics.rb +66 -9
  38. data/lib/prawn/graphics/color.rb +1 -1
  39. data/lib/prawn/graphics/transformation.rb +156 -0
  40. data/lib/prawn/graphics/transparency.rb +3 -7
  41. data/lib/prawn/images.rb +4 -3
  42. data/lib/prawn/images/png.rb +2 -2
  43. data/lib/prawn/outline.rb +278 -0
  44. data/lib/prawn/pdf_object.rb +5 -3
  45. data/lib/prawn/repeater.rb +25 -13
  46. data/lib/prawn/stamp.rb +6 -29
  47. data/lib/prawn/text.rb +139 -121
  48. data/lib/prawn/text/box.rb +168 -102
  49. data/spec/bounding_box_spec.rb +7 -2
  50. data/spec/document_spec.rb +7 -5
  51. data/spec/font_spec.rb +9 -1
  52. data/spec/graphics_spec.rb +229 -0
  53. data/spec/object_store_spec.rb +5 -5
  54. data/spec/outline_spec.rb +229 -0
  55. data/spec/repeater_spec.rb +18 -1
  56. data/spec/snapshot_spec.rb +7 -7
  57. data/spec/span_spec.rb +6 -2
  58. data/spec/spec_helper.rb +7 -3
  59. data/spec/stamp_spec.rb +13 -0
  60. data/spec/text_at_spec.rb +119 -0
  61. data/spec/text_box_spec.rb +257 -4
  62. data/spec/text_spec.rb +278 -180
  63. data/vendor/pdf-inspector/lib/pdf/inspector/graphics.rb +12 -0
  64. metadata +16 -3
  65. data/lib/prawn/object_store.rb +0 -92
@@ -48,7 +48,7 @@ module Prawn
48
48
  when String
49
49
  obj = "\xFE\xFF" + obj.unpack("U*").pack("n*") unless in_content_stream
50
50
  "<" << obj.unpack("H*").first << ">"
51
- when Symbol
51
+ when Symbol
52
52
  if (obj = obj.to_s) =~ /\s/
53
53
  raise Prawn::Errors::FailedObjectConversion,
54
54
  "A PDF Name cannot contain whitespace"
@@ -57,14 +57,14 @@ module Prawn
57
57
  end
58
58
  when Hash
59
59
  output = "<< "
60
- obj.each do |k,v|
60
+ obj.each do |k,v|
61
61
  unless String === k || Symbol === k
62
62
  raise Prawn::Errors::FailedObjectConversion,
63
63
  "A PDF Dictionary must be keyed by names"
64
64
  end
65
65
  output << PdfObject(k.to_sym, in_content_stream) << " " <<
66
66
  PdfObject(v, in_content_stream) << "\n"
67
- end
67
+ end
68
68
  output << ">>"
69
69
  when Prawn::Reference
70
70
  obj.to_s
@@ -72,6 +72,8 @@ module Prawn
72
72
  PdfObject(obj.to_hash)
73
73
  when Prawn::NameTree::Value
74
74
  PdfObject(obj.name) + " " + PdfObject(obj.value)
75
+ when Prawn::OutlineRoot, Prawn::OutlineItem
76
+ PdfObject(obj.to_hash)
75
77
  else
76
78
  raise Prawn::Errors::FailedObjectConversion,
77
79
  "This object cannot be serialized to PDF"
@@ -31,43 +31,50 @@ module Prawn
31
31
  # some_range -- repeats on every page included in the range
32
32
  # some_lambda -- yields page number and repeats for true return values
33
33
  #
34
+ # Also accepts an optional second argument for dynamic content which executes the code
35
+ # in the context of the filtered pages without using a Stamp.
36
+ #
34
37
  # Example:
35
38
  #
36
39
  # Prawn::Document.generate("repeat.pdf", :skip_page_creation => true) do
37
40
  #
38
41
  # repeat :all do
39
- # text "ALLLLLL", :at => bounds.top_left
42
+ # draw_text "ALLLLLL", :at => bounds.top_left
40
43
  # end
41
44
  #
42
45
  # repeat :odd do
43
- # text "ODD", :at => [0,0]
46
+ # draw_text "ODD", :at => [0,0]
44
47
  # end
45
48
  #
46
49
  # repeat :even do
47
- # text "EVEN", :at => [0,0]
50
+ # draw_text "EVEN", :at => [0,0]
48
51
  # end
49
52
  #
50
53
  # repeat [1,2] do
51
- # text "[1,2]", :at => [100,0]
54
+ # draw_text "[1,2]", :at => [100,0]
52
55
  # end
53
56
  #
54
57
  # repeat 2..4 do
55
- # text "2..4", :at => [200,0]
58
+ # draw_text "2..4", :at => [200,0]
56
59
  # end
57
60
  #
58
61
  # repeat(lambda { |pg| pg % 3 == 0 }) do
59
- # text "Every third", :at => [250, 20]
62
+ # draw_text "Every third", :at => [250, 20]
60
63
  # end
61
64
  #
62
65
  # 10.times do
63
66
  # start_new_page
64
- # text "A wonderful page", :at => [400,400]
67
+ # draw_text "A wonderful page", :at => [400,400]
68
+ # end
69
+ #
70
+ # repeat(:all, :dynamic => true) do
71
+ # text page_number, :at => [500, 0]
65
72
  # end
66
73
  #
67
74
  # end
68
75
  #
69
- def repeat(page_filter, &block)
70
- repeaters << Prawn::Repeater.new(self, page_filter, &block)
76
+ def repeat(page_filter, options={}, &block)
77
+ repeaters << Prawn::Repeater.new(self, page_filter, !!options[:dynamic], &block)
71
78
  end
72
79
  end
73
80
 
@@ -82,12 +89,13 @@ module Prawn
82
89
 
83
90
  attr_reader :name
84
91
 
85
- def initialize(document, page_filter, &block)
92
+ def initialize(document, page_filter, dynamic = false, &block)
86
93
  @document = document
87
94
  @page_filter = page_filter
95
+ @dynamic = dynamic
88
96
  @stamp_name = "prawn_repeater(#{Repeater.count})"
89
-
90
- @document.create_stamp(@stamp_name, &block)
97
+ @document.create_stamp(@stamp_name, &block) unless dynamic
98
+ @block = block if dynamic
91
99
 
92
100
  Repeater.count += 1
93
101
  end
@@ -108,7 +116,11 @@ module Prawn
108
116
  end
109
117
 
110
118
  def run(page_number)
111
- @document.stamp(@stamp_name) if match?(page_number)
119
+ if !@dynamic
120
+ @document.stamp(@stamp_name) if match?(page_number)
121
+ elsif @block
122
+ @block.arity < 1 ? @document.instance_eval(&@block) : @block[@document]
123
+ end
112
124
  end
113
125
 
114
126
  end
@@ -22,7 +22,7 @@ module Prawn
22
22
  # Example:
23
23
  # pdf.create_stamp("my_stamp") {
24
24
  # pdf.fill_circle_at([10, 15], :radius => 5)
25
- # pdf.text("hello world", :at => [20, 10])
25
+ # pdf.draw_text("hello world", :at => [20, 10])
26
26
  # }
27
27
  # pdf.stamp("my_stamp")
28
28
  #
@@ -43,7 +43,7 @@ module Prawn
43
43
  def stamp(name)
44
44
  dictionary_name, dictionary = stamp_dictionary(name)
45
45
  add_content "/#{dictionary_name} Do"
46
- page_xobjects.merge!(dictionary_name => dictionary)
46
+ page.xobjects.merge!(dictionary_name => dictionary)
47
47
  end
48
48
 
49
49
  # Renders the stamp named <tt>name</tt> at a position offset from
@@ -60,19 +60,7 @@ module Prawn
60
60
  # See stamp() for exceptions that might be raised
61
61
  #
62
62
  def stamp_at(name, point)
63
- # Save the graphics state
64
- add_content "q"
65
-
66
- # Translate the user space
67
- x,y = point
68
- translate_position = "1 0 0 1 %.3f %.3f cm" % [x, y]
69
- add_content translate_position
70
-
71
- # Draw the stamp in the now translated user space
72
- stamp(name)
73
-
74
- # Restore the graphics state to remove the translation
75
- add_content "Q"
63
+ translate(point[0], point[1]) { stamp(name) }
76
64
  end
77
65
 
78
66
  # Creates a re-usable stamp named <tt>name</tt>
@@ -84,24 +72,13 @@ module Prawn
84
72
  # Example:
85
73
  # pdf.create_stamp("my_stamp") {
86
74
  # pdf.fill_circle_at([10, 15], :radius => 5)
87
- # pdf.text("hello world", :at => [20, 10])
75
+ # pdf.draw_text("hello world", :at => [20, 10])
88
76
  # }
89
77
  #
90
78
  def create_stamp(name, &block)
91
79
  dictionary = create_stamp_dictionary(name)
92
80
 
93
- @active_stamp_stream = ""
94
- @active_stamp_dictionary = dictionary
95
-
96
- update_colors
97
- yield if block_given?
98
- update_colors
99
-
100
- dictionary.data[:Length] = @active_stamp_stream.length + 1
101
- dictionary << @active_stamp_stream
102
-
103
- @active_stamp_stream = nil
104
- @active_stamp_dictionary = nil
81
+ page.stamp_stream(dictionary, &block)
105
82
  end
106
83
 
107
84
  private
@@ -136,7 +113,7 @@ module Prawn
136
113
  dictionary = ref!(:Type => :XObject,
137
114
  :Subtype => :Form,
138
115
  :BBox => [0, 0,
139
- page_dimensions[2], page_dimensions[3]])
116
+ page.dimensions[2], page.dimensions[3]])
140
117
 
141
118
  dictionary_name = "Stamp#{next_stamp_dictionary_id}"
142
119
 
@@ -5,25 +5,33 @@
5
5
  # Copyright May 2008, Gregory Brown. All Rights Reserved.
6
6
  #
7
7
  # This is free software. Please see the LICENSE and COPYING files for details.
8
- require "zlib"
8
+
9
+ require "prawn/core/text"
9
10
  require "prawn/text/box"
11
+ require "zlib"
10
12
 
11
13
  module Prawn
12
14
  module Text
13
- attr_reader :text_options
14
- attr_reader :skip_encoding
15
15
 
16
- ruby_18 { $KCODE="U" }
16
+ include Prawn::Core::Text
17
17
 
18
- # Gets height of text in PDF points. See text() for valid options.
18
+ VALID_OPTIONS = Prawn::Core::Text::VALID_OPTIONS + [:at, :rotate]
19
+
20
+ # Gets height of text in PDF points.
21
+ # Same options as text(), except as noted.
22
+ # Not compatible with :indent_paragraphs option
23
+ #
24
+ # Raises <tt>Prawn::Errors::UnknownOption</tt> if
25
+ # <tt>:indent_paragraphs</tt> option included and debug flag is set
19
26
  #
20
27
  def height_of(string, options={})
28
+ process_final_gap_option(options)
21
29
  box = Text::Box.new(string,
22
30
  options.merge(:height => 100000000,
23
31
  :document => self))
24
32
  box.render(:dry_run => true)
25
33
  height = box.height - box.descender
26
- height += box.line_height + box.leading - box.ascender # if final_gap
34
+ height += box.line_height + box.leading - box.ascender if @final_gap
27
35
  height
28
36
  end
29
37
 
@@ -32,19 +40,12 @@ module Prawn
32
40
  # the flow of a document (for captions, labels, charts, etc.), use Text::Box
33
41
  # or its convenience method text_box.
34
42
  #
35
- # Draws text on the page. If a point is specified via the <tt>:at</tt>
36
- # option the text will begin exactly at that point, and the string is
37
- # assumed to be pre-formatted to properly fit the page.
38
- #
39
- # pdf.text "Hello World", :at => [100,100]
40
- # pdf.text "Goodbye World", :at => [50,50], :size => 16
41
- #
42
- # When <tt>:at</tt> is not specified, Prawn attempts to wrap the text to
43
- # fit within your current bounding box (or margin_box if no bounding box
44
- # is being used ). Text will flow onto the next page when it reaches
45
- # the bottom of the bounding box. Text wrap in Prawn does not re-flow
46
- # linebreaks, so if you want fully automated text wrapping, be sure to
47
- # remove newlines before attempting to draw your string.
43
+ # Draws text on the page. Prawn attempts to wrap the text to fit within your
44
+ # current bounding box (or margin_box if no bounding box is being used).
45
+ # Text will flow onto the next page when it reaches the bottom of the
46
+ # bounding box. Text wrap in Prawn does not re-flow linebreaks, so if you
47
+ # want fully automated text wrapping, be sure to remove newlines before
48
+ # attempting to draw your string.
48
49
  #
49
50
  # pdf.text "Will be wrapped when it hits the edge of your bounding box"
50
51
  # pdf.text "This will be centered", :align => :center
@@ -55,20 +56,10 @@ module Prawn
55
56
  # <tt>:kerning => false</tt>.
56
57
  #
57
58
  # === Text Positioning Details:
58
- #
59
- # When using the :at parameter, Prawn will position your text by the
60
- # left-most edge of its baseline, and flow along a single line. (This
61
- # means that :align will not work)
62
59
  #
63
- # Otherwise, the text is positioned at font.ascender below the baseline,
60
+ # The text is positioned at font.ascender below the baseline,
64
61
  # making it easy to use this method within bounding boxes and spans.
65
62
  #
66
- # == Rotation
67
- #
68
- # Text can be rotated before it is placed on the canvas by specifying the
69
- # <tt>:rotate</tt> option with a given angle. Rotation occurs counter-clockwise.
70
- # Note that <tt>:rotate</tt> is only compatible when using the <tt>:at</tt> option
71
- #
72
63
  # == Encoding
73
64
  #
74
65
  # Note that strings passed to this function should be encoded as UTF-8.
@@ -90,14 +81,9 @@ module Prawn
90
81
  # size]
91
82
  # <tt>:style</tt>:: The style to use. The requested style must be part of
92
83
  # the current font familly. [current style]
93
- #
94
- # === Additional options available when <tt>:at</tt> option is provided
95
- #
96
- # <tt>:at</tt>:: <tt>[x, y]</tt>. The position at which to start the text
97
- # <tt>:rotate</tt>:: <tt>number</tt>. The angle to which to rotate text
98
- #
99
- # === Additional options available when <tt>:at</tt> option is omitted
100
- #
84
+ # <tt>:indent_paragraphs</tt>:: <tt>number</tt>. The amount to indent the
85
+ # first line of each paragraph. Omit this
86
+ # option if you do not want indenting
101
87
  # <tt>:align</tt>:: <tt>:left</tt>, <tt>:center</tt>, or <tt>:right</tt>.
102
88
  # Alignment within the bounding box [:left]
103
89
  # <tt>:valign</tt>:: <tt>:top</tt>, <tt>:center</tt>, or <tt>:bottom</tt>.
@@ -121,69 +107,113 @@ module Prawn
121
107
  # <tt>:kerning</tt>:: boolean
122
108
  # <tt>:size</tt>:: the font size
123
109
  #
124
- # Raises <tt>ArgumentError</tt> if both <tt>:at</tt> and <tt>:align</tt>
125
- # options included
126
- #
127
- # Raises <tt>ArgumentError</tt> if <tt>:rotate</tt> option included, but
128
- # <tt>:at</tt> option omitted
110
+ # Raises <tt>ArgumentError</tt> if <tt>:at</tt> option included
129
111
  #
130
- def text(text, options={})
131
- # we might modify the options. don't change the user's hash
112
+ def text(string, options={})
113
+ # we modify the options. don't change the user's hash
132
114
  options = options.dup
133
- if options[:at]
134
- inspect_options_for_text_at(options)
135
- # we'll be messing with the strings encoding, don't change the user's
136
- # original string
137
- text = text.to_s.dup
138
- options = @text_options.merge(options)
139
- save_font do
140
- process_text_options(options)
141
- font.normalize_encoding!(text) unless @skip_encoding
142
- font_size(options[:size]) { text_at(text, options) }
143
- end
144
- else
145
- remaining_text = fill_text_box(text, options)
146
- while remaining_text.length > 0
147
- @bounding_box.move_past_bottom
148
- previous_remaining_text = remaining_text
115
+ inspect_options_for_text(options)
116
+
117
+ if @indent_paragraphs
118
+ string.split("\n").each do |paragraph|
119
+ options[:skip_encoding] = false
120
+ remaining_text = draw_indented_line(paragraph, options)
121
+ options[:skip_encoding] = true
122
+ if remaining_text == paragraph
123
+ # we were too close to the bottom of the page to print even one line
124
+ @bounding_box.move_past_bottom
125
+ remaining_text = draw_indented_line(paragraph, options)
126
+ end
149
127
  remaining_text = fill_text_box(remaining_text, options)
150
- break if remaining_text == previous_remaining_text
128
+ draw_remaining_text_on_new_pages(remaining_text, options)
151
129
  end
130
+ else
131
+ remaining_text = fill_text_box(string, options)
132
+ options[:skip_encoding] = true
133
+ draw_remaining_text_on_new_pages(remaining_text, options)
152
134
  end
153
135
  end
154
136
 
155
- # Low level text placement method. All font and size alterations
156
- # should already be set
137
+ # Draws text on the page, beginning at the point specified by the :at option
138
+ # the string is assumed to be pre-formatted to properly fit the page.
139
+ #
140
+ # pdf.draw_text "Hello World", :at => [100,100]
141
+ # pdf.draw_text "Goodbye World", :at => [50,50], :size => 16
142
+ #
143
+ # If your font contains kerning pairs data that Prawn can parse, the
144
+ # text will be kerned by default. You can disable this feature by passing
145
+ # <tt>:kerning => false</tt>.
146
+ #
147
+ # === Text Positioning Details:
148
+ #
149
+ # Prawn will position your text by the left-most edge of its baseline, and
150
+ # flow along a single line. (This means that :align will not work)
151
+ #
152
+ # == Rotation
153
+ #
154
+ # Text can be rotated before it is placed on the canvas by specifying the
155
+ # <tt>:rotate</tt> option with a given angle. Rotation occurs counter-clockwise.
156
+ #
157
+ # == Encoding
157
158
  #
158
- def text_at(text, options)
159
- x,y = translate(options[:at])
160
- add_text_content(text,x,y,options)
159
+ # Note that strings passed to this function should be encoded as UTF-8.
160
+ # If you get unexpected characters appearing in your rendered document,
161
+ # check this.
162
+ #
163
+ # If the current font is a built-in one, although the string must be
164
+ # encoded as UTF-8, only characters that are available in WinAnsi
165
+ # are allowed.
166
+ #
167
+ # If an empty box is rendered to your PDF instead of the character you
168
+ # wanted it usually means the current font doesn't include that character.
169
+ #
170
+ # == Options (default values marked in [])
171
+ #
172
+ # <tt>:at</tt>:: <tt>[x, y]</tt>(required). The position at which to start the text
173
+ # <tt>:kerning</tt>:: <tt>boolean</tt>. Whether or not to use kerning (if it
174
+ # is available with the current font) [true]
175
+ # <tt>:size</tt>:: <tt>number</tt>. The font size to use. [current font
176
+ # size]
177
+ # <tt>:style</tt>:: The style to use. The requested style must be part of
178
+ # the current font familly. [current style]
179
+ #
180
+ # <tt>:rotate</tt>:: <tt>number</tt>. The angle to which to rotate text
181
+ #
182
+ # Raises <tt>ArgumentError</tt> if <tt>:at</tt> option omitted
183
+ # Raises <tt>ArgumentError</tt> if <tt>:align</tt> option included
184
+ #
185
+ def draw_text(text, options)
186
+ # we modify the options. don't change the user's hash
187
+ options = options.dup
188
+ inspect_options_for_draw_text(options)
189
+ # dup because normalize_encoding changes the string
190
+ text = text.to_s.dup
191
+ options = @text_options.merge(options)
192
+ save_font do
193
+ process_text_options(options)
194
+ font.normalize_encoding!(text) unless @skip_encoding
195
+ font_size(options[:size]) { draw_text!(text, options) }
196
+ end
161
197
  end
162
198
 
163
- # These should be used as a base. Extensions may build on this list
164
- VALID_TEXT_OPTIONS = [:kerning, :size, :style]
199
+ private
165
200
 
166
- # Low level call to set the current font style and extract text options from
167
- # an options hash. Should be called from within a save_font block
168
- #
169
- def process_text_options(options)
170
- if options[:style]
171
- raise "Bad font family" unless font.family
172
- font(font.family, :style => options[:style])
201
+ def draw_remaining_text_on_new_pages(remaining_text, options)
202
+ while remaining_text.length > 0
203
+ @bounding_box.move_past_bottom
204
+ previous_remaining_text = remaining_text
205
+ remaining_text = fill_text_box(remaining_text, options)
206
+ break if remaining_text == previous_remaining_text
173
207
  end
208
+ end
174
209
 
175
- # must compare against false to keep kerning on as default
176
- unless options[:kerning] == false
177
- options[:kerning] = font.has_kerning_data?
210
+ def draw_indented_line(string, options)
211
+ indent(@indent_paragraphs) do
212
+ fill_text_box(string, options.dup.merge(:single_line => true))
178
213
  end
179
-
180
- options[:size] ||= font_size
181
214
  end
182
215
 
183
- private
184
-
185
216
  def fill_text_box(text, options)
186
- final_gap = inspect_options_for_text_box(options)
187
217
  bottom = @bounding_box.stretchy? ? @margin_box.absolute_bottom :
188
218
  @bounding_box.absolute_bottom
189
219
 
@@ -196,27 +226,39 @@ module Prawn
196
226
  remaining_text = box.render
197
227
 
198
228
  self.y -= box.height - box.descender
199
- self.y -= box.line_height + box.leading - box.ascender if final_gap
200
-
229
+ if @final_gap
230
+ self.y -= box.line_height + box.leading - box.ascender
231
+ end
201
232
  remaining_text
202
233
  end
203
234
 
204
- def inspect_options_for_text_at(options)
205
- if options[:align]
206
- raise ArgumentError, "The :align option does not work with :at"
235
+ def inspect_options_for_draw_text(options)
236
+ if options[:at].nil?
237
+ raise ArgumentError, "The :at option is required for draw_text"
238
+ elsif options[:align]
239
+ raise ArgumentError, "The :align option does not work with draw_text"
207
240
  end
208
- valid_options = VALID_TEXT_OPTIONS.dup.concat([:at, :rotate])
209
- Prawn.verify_options(valid_options, options)
241
+ Prawn.verify_options(VALID_OPTIONS, options)
210
242
  end
211
243
 
212
- def inspect_options_for_text_box(options)
213
- if options[:rotate]
214
- raise ArgumentError, "Rotated text may only be used with :at"
244
+ def inspect_options_for_text(options)
245
+ if options[:at]
246
+ raise ArgumentError, ":at is no longer a valid option with text." +
247
+ "use draw_text or text_box instead"
215
248
  end
216
- options.merge!(:document => self)
217
- final_gap = options[:final_gap].nil? ? true : options[:final_gap]
249
+ process_final_gap_option(options)
250
+ process_indent_paragraphs_option(options)
251
+ options[:document] = self
252
+ end
253
+
254
+ def process_final_gap_option(options)
255
+ @final_gap = options[:final_gap].nil? || options[:final_gap]
218
256
  options.delete(:final_gap)
219
- final_gap
257
+ end
258
+
259
+ def process_indent_paragraphs_option(options)
260
+ @indent_paragraphs = options[:indent_paragraphs]
261
+ options.delete(:indent_paragraphs)
220
262
  end
221
263
 
222
264
  def move_text_position(dy)
@@ -227,29 +269,5 @@ module Prawn
227
269
 
228
270
  self.y -= dy
229
271
  end
230
-
231
- def add_text_content(text, x, y, options)
232
- chunks = font.encode_text(text,options)
233
-
234
- add_content "\nBT"
235
-
236
- if options[:rotate]
237
- rad = options[:rotate].to_i * Math::PI / 180
238
- arr = [ Math.cos(rad), Math.sin(rad), -Math.sin(rad), Math.cos(rad), x, y ]
239
- add_content "%.3f %.3f %.3f %.3f %.3f %.3f Tm" % arr
240
- else
241
- add_content "#{x} #{y} Td"
242
- end
243
-
244
- chunks.each do |(subset, string)|
245
- font.add_to_current_page(subset)
246
- add_content "/#{font.identifier_for(subset)} #{font_size} Tf"
247
-
248
- operation = options[:kerning] && string.is_a?(Array) ? "TJ" : "Tj"
249
- add_content Prawn::PdfObject(string, true) << " " << operation
250
- end
251
-
252
- add_content "ET\n"
253
- end
254
272
  end
255
273
  end