prawn 0.11.1.pre → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. data/COPYING +2 -340
  2. data/HACKING +1 -1
  3. data/LICENSE +3 -3
  4. data/Rakefile +17 -6
  5. data/data/encodings/win_ansi.txt +1 -1
  6. data/data/images/prawn.png +0 -0
  7. data/data/pdfs/form.pdf +820 -0
  8. data/data/pdfs/multipage_template.pdf +127 -0
  9. data/examples/bounding_box/bounding_boxes.rb +4 -3
  10. data/examples/bounding_box/indentation.rb +2 -1
  11. data/examples/bounding_box/russian_boxes.rb +3 -2
  12. data/examples/bounding_box/stretched_nesting.rb +2 -1
  13. data/examples/general/background.rb +2 -1
  14. data/examples/general/canvas.rb +2 -1
  15. data/examples/general/context_sensitive_headers.rb +2 -1
  16. data/examples/general/float.rb +2 -1
  17. data/examples/general/margin.rb +2 -1
  18. data/examples/general/measurement_units.rb +2 -1
  19. data/examples/general/metadata-info.rb +2 -1
  20. data/examples/general/multi_page_layout.rb +2 -1
  21. data/examples/general/outlines.rb +2 -1
  22. data/examples/general/page_geometry.rb +2 -1
  23. data/examples/general/page_numbering.rb +27 -2
  24. data/examples/general/page_templates.rb +20 -0
  25. data/examples/general/repeaters.rb +2 -1
  26. data/examples/general/stamp.rb +4 -3
  27. data/examples/general/templates.rb +2 -1
  28. data/examples/graphics/basic_images.rb +2 -1
  29. data/examples/graphics/cmyk.rb +2 -1
  30. data/examples/graphics/curves.rb +4 -3
  31. data/examples/graphics/gradient.rb +23 -0
  32. data/examples/graphics/hexagon.rb +3 -2
  33. data/examples/graphics/image_fit.rb +3 -2
  34. data/examples/graphics/image_flow.rb +2 -1
  35. data/examples/graphics/image_position.rb +3 -2
  36. data/examples/graphics/line.rb +2 -1
  37. data/examples/graphics/png_types.rb +3 -2
  38. data/examples/graphics/polygons.rb +3 -2
  39. data/examples/graphics/remote_images.rb +2 -1
  40. data/examples/graphics/rounded_polygons.rb +2 -1
  41. data/examples/graphics/rounded_rectangle.rb +2 -1
  42. data/examples/graphics/ruport_style_helpers.rb +3 -2
  43. data/examples/graphics/stroke_bounds.rb +2 -1
  44. data/examples/graphics/stroke_cap_and_join.rb +2 -1
  45. data/examples/graphics/stroke_dash.rb +2 -1
  46. data/examples/graphics/transformations.rb +2 -1
  47. data/examples/graphics/transparency.rb +4 -3
  48. data/examples/grid/bounding_boxes.rb +2 -1
  49. data/examples/grid/column_gutter_grid.rb +2 -1
  50. data/examples/grid/multi_boxes.rb +2 -1
  51. data/examples/grid/show_grid.rb +2 -1
  52. data/examples/grid/simple_grid.rb +2 -1
  53. data/examples/m17n/chinese_text_wrapping.rb +2 -1
  54. data/examples/m17n/euro.rb +3 -2
  55. data/examples/m17n/full_win_ansi_character_list.rb +20 -0
  56. data/examples/m17n/sjis.rb +2 -1
  57. data/examples/m17n/utf8.rb +3 -2
  58. data/examples/m17n/win_ansi_charset.rb +2 -1
  59. data/examples/security/hello_foo.rb +2 -1
  60. data/examples/table/bill.rb +2 -1
  61. data/examples/table/borders.rb +25 -0
  62. data/examples/table/cell.rb +3 -2
  63. data/examples/table/checkerboard.rb +2 -1
  64. data/examples/table/header.rb +3 -2
  65. data/examples/table/inline_format_table.rb +2 -1
  66. data/examples/table/multi_page_table.rb +2 -1
  67. data/examples/table/simple_table.rb +2 -1
  68. data/examples/table/subtable.rb +2 -1
  69. data/examples/table/widths.rb +2 -1
  70. data/examples/text/alignment.rb +2 -1
  71. data/examples/text/character_spacing.rb +2 -1
  72. data/examples/text/dfont.rb +2 -1
  73. data/examples/text/family_based_styling.rb +3 -2
  74. data/examples/text/font_calculations.rb +2 -1
  75. data/examples/text/font_size.rb +2 -1
  76. data/examples/text/hyphenation.rb +2 -2
  77. data/examples/text/indent_paragraphs.rb +7 -5
  78. data/examples/text/inline_format.rb +7 -6
  79. data/examples/text/kerning.rb +2 -1
  80. data/examples/text/rendering_mode.rb +21 -0
  81. data/examples/text/rotated.rb +2 -1
  82. data/examples/text/shaped_text_box.rb +2 -1
  83. data/examples/text/simple_text.rb +2 -1
  84. data/examples/text/simple_text_ttf.rb +2 -1
  85. data/examples/text/span.rb +3 -2
  86. data/examples/text/text_box.rb +7 -5
  87. data/examples/text/text_box_returning_excess.rb +4 -3
  88. data/examples/text/text_flow.rb +2 -1
  89. data/lib/prawn.rb +1 -1
  90. data/lib/prawn/core/object_store.rb +42 -14
  91. data/lib/prawn/core/page.rb +22 -8
  92. data/lib/prawn/core/text.rb +141 -13
  93. data/lib/prawn/core/text/formatted/arranger.rb +39 -12
  94. data/lib/prawn/core/text/formatted/line_wrap.rb +205 -60
  95. data/lib/prawn/core/text/formatted/wrap.rb +72 -35
  96. data/lib/prawn/document.rb +174 -70
  97. data/lib/prawn/document/bounding_box.rb +122 -83
  98. data/lib/prawn/document/column_box.rb +113 -0
  99. data/lib/prawn/document/graphics_state.rb +90 -2
  100. data/lib/prawn/document/internals.rb +5 -3
  101. data/lib/prawn/errors.rb +5 -0
  102. data/lib/prawn/font.rb +4 -4
  103. data/lib/prawn/font/afm.rb +11 -0
  104. data/lib/prawn/font/ttf.rb +5 -0
  105. data/lib/prawn/graphics.rb +77 -14
  106. data/lib/prawn/graphics/cap_style.rb +13 -5
  107. data/lib/prawn/graphics/color.rb +54 -35
  108. data/lib/prawn/graphics/dash.rb +27 -16
  109. data/lib/prawn/graphics/gradient.rb +84 -0
  110. data/lib/prawn/graphics/join_style.rb +12 -3
  111. data/lib/prawn/graphics/transparency.rb +4 -4
  112. data/lib/prawn/images.rb +18 -160
  113. data/lib/prawn/images/jpg.rb +39 -0
  114. data/lib/prawn/images/png.rb +130 -0
  115. data/lib/prawn/repeater.rb +6 -13
  116. data/lib/prawn/security.rb +6 -1
  117. data/lib/prawn/stamp.rb +12 -4
  118. data/lib/prawn/table.rb +36 -4
  119. data/lib/prawn/table/cell.rb +224 -63
  120. data/lib/prawn/table/cell/text.rb +20 -10
  121. data/lib/prawn/table/cells.rb +23 -6
  122. data/lib/prawn/text.rb +54 -91
  123. data/lib/prawn/text/box.rb +29 -283
  124. data/lib/prawn/text/formatted/box.rb +349 -24
  125. data/lib/prawn/text/formatted/fragment.rb +63 -2
  126. data/lib/prawn/text/formatted/parser.rb +2 -1
  127. data/prawn.gemspec +21 -5
  128. data/spec/bounding_box_spec.rb +61 -28
  129. data/spec/cell_spec.rb +168 -30
  130. data/spec/document_spec.rb +187 -3
  131. data/spec/extensions/mocha.rb +45 -0
  132. data/spec/font_spec.rb +32 -1
  133. data/spec/formatted_text_arranger_spec.rb +35 -40
  134. data/spec/formatted_text_box_spec.rb +287 -443
  135. data/spec/formatted_text_fragment_spec.rb +87 -0
  136. data/spec/graphics_spec.rb +128 -12
  137. data/spec/grid_spec.rb +1 -1
  138. data/spec/images_spec.rb +11 -3
  139. data/spec/inline_formatted_text_parser_spec.rb +8 -0
  140. data/spec/line_wrap_spec.rb +200 -208
  141. data/spec/object_store_spec.rb +10 -0
  142. data/spec/outline_spec.rb +7 -3
  143. data/spec/repeater_spec.rb +58 -10
  144. data/spec/security_spec.rb +6 -0
  145. data/spec/spec_helper.rb +12 -8
  146. data/spec/stamp_spec.rb +52 -1
  147. data/spec/stroke_styles_spec.rb +30 -0
  148. data/spec/table_spec.rb +93 -3
  149. data/spec/template_spec.rb +132 -6
  150. data/spec/text_at_spec.rb +14 -4
  151. data/spec/text_box_spec.rb +309 -70
  152. data/spec/text_rendering_mode_spec.rb +45 -0
  153. data/spec/text_spec.rb +60 -17
  154. data/spec/text_with_inline_formatting_spec.rb +4 -162
  155. metadata +241 -241
  156. data/lib/prawn/core/text/line_wrap.rb +0 -211
  157. data/lib/prawn/core/text/wrap.rb +0 -82
  158. data/vendor/pdf-inspector/README +0 -18
  159. data/vendor/pdf-inspector/lib/pdf/inspector.rb +0 -26
  160. data/vendor/pdf-inspector/lib/pdf/inspector/extgstate.rb +0 -18
  161. data/vendor/pdf-inspector/lib/pdf/inspector/graphics.rb +0 -131
  162. data/vendor/pdf-inspector/lib/pdf/inspector/page.rb +0 -25
  163. data/vendor/pdf-inspector/lib/pdf/inspector/text.rb +0 -46
  164. data/vendor/pdf-inspector/lib/pdf/inspector/xobject.rb +0 -19
  165. data/vendor/ttfunk/data/fonts/DejaVuSans.ttf +0 -0
  166. data/vendor/ttfunk/data/fonts/comicsans.ttf +0 -0
  167. data/vendor/ttfunk/example.rb +0 -45
  168. data/vendor/ttfunk/lib/ttfunk.rb +0 -102
  169. data/vendor/ttfunk/lib/ttfunk/directory.rb +0 -17
  170. data/vendor/ttfunk/lib/ttfunk/encoding/mac_roman.rb +0 -88
  171. data/vendor/ttfunk/lib/ttfunk/encoding/windows_1252.rb +0 -69
  172. data/vendor/ttfunk/lib/ttfunk/reader.rb +0 -44
  173. data/vendor/ttfunk/lib/ttfunk/resource_file.rb +0 -78
  174. data/vendor/ttfunk/lib/ttfunk/subset.rb +0 -18
  175. data/vendor/ttfunk/lib/ttfunk/subset/base.rb +0 -141
  176. data/vendor/ttfunk/lib/ttfunk/subset/mac_roman.rb +0 -50
  177. data/vendor/ttfunk/lib/ttfunk/subset/unicode.rb +0 -48
  178. data/vendor/ttfunk/lib/ttfunk/subset/unicode_8bit.rb +0 -63
  179. data/vendor/ttfunk/lib/ttfunk/subset/windows_1252.rb +0 -55
  180. data/vendor/ttfunk/lib/ttfunk/subset_collection.rb +0 -72
  181. data/vendor/ttfunk/lib/ttfunk/table.rb +0 -46
  182. data/vendor/ttfunk/lib/ttfunk/table/cmap.rb +0 -34
  183. data/vendor/ttfunk/lib/ttfunk/table/cmap/format00.rb +0 -54
  184. data/vendor/ttfunk/lib/ttfunk/table/cmap/format04.rb +0 -126
  185. data/vendor/ttfunk/lib/ttfunk/table/cmap/subtable.rb +0 -79
  186. data/vendor/ttfunk/lib/ttfunk/table/glyf.rb +0 -64
  187. data/vendor/ttfunk/lib/ttfunk/table/glyf/compound.rb +0 -81
  188. data/vendor/ttfunk/lib/ttfunk/table/glyf/simple.rb +0 -37
  189. data/vendor/ttfunk/lib/ttfunk/table/head.rb +0 -44
  190. data/vendor/ttfunk/lib/ttfunk/table/hhea.rb +0 -41
  191. data/vendor/ttfunk/lib/ttfunk/table/hmtx.rb +0 -47
  192. data/vendor/ttfunk/lib/ttfunk/table/kern.rb +0 -79
  193. data/vendor/ttfunk/lib/ttfunk/table/kern/format0.rb +0 -62
  194. data/vendor/ttfunk/lib/ttfunk/table/loca.rb +0 -43
  195. data/vendor/ttfunk/lib/ttfunk/table/maxp.rb +0 -40
  196. data/vendor/ttfunk/lib/ttfunk/table/name.rb +0 -125
  197. data/vendor/ttfunk/lib/ttfunk/table/os2.rb +0 -78
  198. data/vendor/ttfunk/lib/ttfunk/table/post.rb +0 -91
  199. data/vendor/ttfunk/lib/ttfunk/table/post/format10.rb +0 -43
  200. data/vendor/ttfunk/lib/ttfunk/table/post/format20.rb +0 -35
  201. data/vendor/ttfunk/lib/ttfunk/table/post/format25.rb +0 -23
  202. data/vendor/ttfunk/lib/ttfunk/table/post/format30.rb +0 -17
  203. data/vendor/ttfunk/lib/ttfunk/table/post/format40.rb +0 -17
  204. data/vendor/ttfunk/lib/ttfunk/table/simple.rb +0 -14
@@ -2,23 +2,256 @@
2
2
 
3
3
  require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
4
 
5
+ describe "Text::Formatted::Box wrapping" do
6
+ before(:each) do
7
+ create_pdf
8
+ end
9
+
10
+ it "should not wrap between two fragments" do
11
+ texts = [
12
+ {:text => "Hello "},
13
+ {:text => "World"},
14
+ {:text => "2", :styles => [:superscript]},
15
+ ]
16
+ text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
17
+ text_box.render
18
+ text_box.text.should == "Hello\nWorld2"
19
+ end
20
+
21
+ it "should not raise Encoding::CompatibilityError when keeping a TTF and an " +
22
+ "AFM font together" do
23
+ ruby_19 do
24
+ file = "#{Prawn::BASEDIR}/data/fonts/gkai00mp.ttf"
25
+ @pdf.font_families["Kai"] = {
26
+ :normal => { :file => file, :font => "Kai" }
27
+ }
28
+
29
+ texts = [{ :text => "Hello " },
30
+ { :text => "再见", :font => "Kai"},
31
+ { :text => "World" }]
32
+ text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
33
+ lambda {
34
+ text_box.render
35
+ }.should.not.raise(Encoding::CompatibilityError)
36
+ end
37
+ end
38
+
39
+ it "should wrap between two fragments when the preceding fragment ends with white space" do
40
+ texts = [
41
+ {:text => "Hello "},
42
+ {:text => "World "},
43
+ {:text => "2", :styles => [:superscript]},
44
+ ]
45
+ text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
46
+ text_box.render
47
+ text_box.text.should == "Hello World\n2"
48
+
49
+ texts = [
50
+ {:text => "Hello "},
51
+ {:text => "World\n"},
52
+ {:text => "2", :styles => [:superscript]},
53
+ ]
54
+ text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
55
+ text_box.render
56
+ text_box.text.should == "Hello World\n2"
57
+ end
58
+
59
+ it "should wrap between two fragments when the final fragment begins with white space" do
60
+ texts = [
61
+ {:text => "Hello "},
62
+ {:text => "World"},
63
+ {:text => " 2", :styles => [:superscript]},
64
+ ]
65
+ text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
66
+ text_box.render
67
+ text_box.text.should == "Hello World\n2"
68
+
69
+ texts = [
70
+ {:text => "Hello "},
71
+ {:text => "World"},
72
+ {:text => "\n2", :styles => [:superscript]},
73
+ ]
74
+ text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
75
+ text_box.render
76
+ text_box.text.should == "Hello World\n2"
77
+ end
78
+ end
79
+
80
+ describe "Text::Formatted::Box with :fallback_fonts option that includes" +
81
+ "a Chinese font and set of Chinese glyphs not in the current font" do
82
+ it "should change the font to the Chinese font for the Chinese glyphs" do
83
+ create_pdf
84
+ file = "#{Prawn::BASEDIR}/data/fonts/gkai00mp.ttf"
85
+ @pdf.font_families["Kai"] = {
86
+ :normal => { :file => file, :font => "Kai" }
87
+ }
88
+ formatted_text = [{ :text => "hello你好" },
89
+ { :text => "再见goodbye" }]
90
+ @pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Kai"])
91
+
92
+ text = PDF::Inspector::Text.analyze(@pdf.render)
93
+
94
+ fonts_used = text.font_settings.map { |e| e[:name] }
95
+ fonts_used.length.should == 4
96
+ fonts_used[0].should == :"Helvetica"
97
+ fonts_used[1].to_s.should =~ /GBZenKai-Medium/
98
+ fonts_used[2].to_s.should =~ /GBZenKai-Medium/
99
+ fonts_used[3].should == :"Helvetica"
100
+
101
+ text.strings[0].should == "hello"
102
+ text.strings[1].should == "你好"
103
+ text.strings[2].should == "再见"
104
+ text.strings[3].should == "goodbye"
105
+ end
106
+ end
107
+
108
+ describe "Text::Formatted::Box with :fallback_fonts option that includes" +
109
+ "an AFM font and Win-Ansi glyph not in the current Chinese font" do
110
+ it "should change the font to the AFM font for the Win-Ansi glyph" do
111
+ create_pdf
112
+ file = "#{Prawn::BASEDIR}/data/fonts/gkai00mp.ttf"
113
+ @pdf.font_families["Kai"] = {
114
+ :normal => { :file => file, :font => "Kai" }
115
+ }
116
+ @pdf.font("Kai")
117
+ formatted_text = [{ :text => "hello你好" },
118
+ { :text => "再见€" }]
119
+ @pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Helvetica"])
120
+
121
+ text = PDF::Inspector::Text.analyze(@pdf.render)
122
+
123
+ fonts_used = text.font_settings.map { |e| e[:name] }
124
+ fonts_used.length.should == 4
125
+ fonts_used[0].to_s.should =~ /GBZenKai-Medium/
126
+ fonts_used[1].to_s.should =~ /GBZenKai-Medium/
127
+ fonts_used[2].to_s.should =~ /GBZenKai-Medium/
128
+ fonts_used[3].should == :"Helvetica"
129
+
130
+ text.strings[0].should == "hello"
131
+ text.strings[1].should == "你好"
132
+ text.strings[2].should == "再见"
133
+ text.strings[3].should == "€"
134
+ end
135
+ end
136
+
137
+ describe "Text::Formatted::Box with :fallback_fonts option and fragment " +
138
+ "level font" do
139
+ it "should use the fragment level font except for glyphs not in that font" do
140
+ create_pdf
141
+ file = "#{Prawn::BASEDIR}/data/fonts/gkai00mp.ttf"
142
+ @pdf.font_families["Kai"] = {
143
+ :normal => { :file => file, :font => "Kai" }
144
+ }
145
+ formatted_text = [{ :text => "hello你好" },
146
+ { :text => "再见goodbye", :font => "Times-Roman" }]
147
+ @pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Kai"])
148
+
149
+ text = PDF::Inspector::Text.analyze(@pdf.render)
150
+
151
+ fonts_used = text.font_settings.map { |e| e[:name] }
152
+ fonts_used.length.should == 4
153
+ fonts_used[0].should == :"Helvetica"
154
+ fonts_used[1].to_s.should =~ /GBZenKai-Medium/
155
+ fonts_used[2].to_s.should =~ /GBZenKai-Medium/
156
+ fonts_used[3].should == :"Times-Roman"
157
+
158
+ text.strings[0].should == "hello"
159
+ text.strings[1].should == "你好"
160
+ text.strings[2].should == "再见"
161
+ text.strings[3].should == "goodbye"
162
+ end
163
+ end
164
+
165
+ describe "Text::Formatted::Box" do
166
+ before(:each) do
167
+ create_pdf
168
+ file = "#{Prawn::BASEDIR}/data/fonts/gkai00mp.ttf"
169
+ @pdf.font_families["Kai"] = {
170
+ :normal => { :file => file, :font => "Kai" }
171
+ }
172
+ @formatted_text = [{ :text => "hello你好" }]
173
+ @pdf.fallback_fonts(["Kai"])
174
+ @pdf.fallback_fonts = ["Kai"]
175
+ end
176
+ it "#fallback_fonts should return the document-wide fallback fonts" do
177
+ @pdf.fallback_fonts.should == ["Kai"]
178
+ end
179
+ it "should be able to set text fallback_fonts document-wide" do
180
+ @pdf.formatted_text_box(@formatted_text)
181
+
182
+ text = PDF::Inspector::Text.analyze(@pdf.render)
183
+
184
+ fonts_used = text.font_settings.map { |e| e[:name] }
185
+ fonts_used.length.should == 2
186
+ fonts_used[0].should == :"Helvetica"
187
+ fonts_used[1].to_s.should =~ /GBZenKai-Medium/
188
+ end
189
+ it "should be able to override document-wide fallback_fonts" do
190
+ @pdf.formatted_text_box(@formatted_text, :fallback_fonts => ["Courier"])
191
+
192
+ text = PDF::Inspector::Text.analyze(@pdf.render)
193
+
194
+ fonts_used = text.font_settings.map { |e| e[:name] }
195
+ fonts_used.length.should == 1
196
+ fonts_used[0].should == :"Helvetica"
197
+ end
198
+ it "should omit the fallback fonts overhead when passing an empty array " +
199
+ "as the :fallback_fonts" do
200
+ box = Prawn::Text::Formatted::Box.new(@formatted_text,
201
+ :document => @pdf,
202
+ :fallback_fonts => [])
203
+ box.expects(:process_fallback_fonts).never
204
+ box.render
205
+ end
206
+ it "should be able to clear document-wide fallback_fonts" do
207
+ @pdf.fallback_fonts([])
208
+ box = Prawn::Text::Formatted::Box.new(@formatted_text,
209
+ :document => @pdf)
210
+ box.expects(:process_fallback_fonts).never
211
+ box.render
212
+ end
213
+ end
214
+
215
+ describe "Text::Formatted::Box with :fallback_fonts option " +
216
+ "with glyphs not in the primary or the fallback fonts" do
217
+ it "should use the primary font" do
218
+ create_pdf
219
+ formatted_text = [{ :text => "hello world. 世界你好。" }]
220
+ @pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Helvetica"])
221
+
222
+ text = PDF::Inspector::Text.analyze(@pdf.render)
223
+
224
+ fonts_used = text.font_settings.map { |e| e[:name] }
225
+ fonts_used.length.should == 1
226
+ fonts_used[0].should == :"Helvetica"
227
+ end
228
+ end
229
+
5
230
  describe "Text::Formatted::Box#extensions" do
6
231
  it "should be able to override default line wrapping" do
7
232
  create_pdf
8
233
  Prawn::Text::Formatted::Box.extensions << TestFormattedWrapOverride
9
234
  @pdf.formatted_text_box([{ :text => "hello world" }], {})
235
+ Prawn::Text::Formatted::Box.extensions.delete(TestFormattedWrapOverride)
10
236
  text = PDF::Inspector::Text.analyze(@pdf.render)
11
237
  text.strings[0].should == "all your base are belong to us"
12
- Prawn::Text::Formatted::Box.extensions.delete(TestFormattedWrapOverride)
13
238
  end
14
- it "overriding Text::Box line wrapping should not affect " +
15
- "Text::Formatted::Box wrapping" do
239
+ it "overriding Text::Formatted::Box line wrapping should not affect " +
240
+ "Text::Box wrapping" do
16
241
  create_pdf
17
- Prawn::Text::Box.extensions << TestWrapOverride
18
- @pdf.formatted_text_box([{ :text => "hello world" }], {})
242
+ Prawn::Text::Formatted::Box.extensions << TestFormattedWrapOverride
243
+ @pdf.text_box("hello world", {})
244
+ Prawn::Text::Formatted::Box.extensions.delete(TestFormattedWrapOverride)
19
245
  text = PDF::Inspector::Text.analyze(@pdf.render)
20
246
  text.strings[0].should == "hello world"
21
- Prawn::Text::Box.extensions.delete(TestWrapOverride)
247
+ end
248
+ it "overriding Text::Box line wrapping should override Text::Box wrapping" do
249
+ create_pdf
250
+ Prawn::Text::Box.extensions << TestFormattedWrapOverride
251
+ @pdf.text_box("hello world", {})
252
+ Prawn::Text::Box.extensions.delete(TestFormattedWrapOverride)
253
+ text = PDF::Inspector::Text.analyze(@pdf.render)
254
+ text.strings[0].should == "all your base are belong to us"
22
255
  end
23
256
  end
24
257
 
@@ -39,97 +272,40 @@ describe "Text::Formatted::Box#render" do
39
272
  text_box.render
40
273
  text_box.text.should == "hello\nworld"
41
274
  end
42
- it "should omit spaces from the end of the line" do
43
- create_pdf
44
- array = [{ :text => "hello \nworld "}]
45
- options = { :document => @pdf }
46
- text_box = Prawn::Text::Formatted::Box.new(array, options)
47
- text_box.render
48
- text_box.text.should == "hello\nworld"
49
- end
50
275
  it "should be okay printing a line of whitespace" do
51
276
  create_pdf
52
- array = [{ :text => "hello\n \nworld "}]
277
+ array = [{ :text => "hello\n \nworld"}]
53
278
  options = { :document => @pdf }
54
279
  text_box = Prawn::Text::Formatted::Box.new(array, options)
55
280
  text_box.render
56
281
  text_box.text.should == "hello\n\nworld"
57
- end
58
- end
59
282
 
60
- describe "Text::Formatted::Box#render with :align => :justify" do
61
- it "should draw the word spacing to the document" do
62
- create_pdf
63
- array = [{ :text => "hello world " * 10}]
64
- options = { :document => @pdf, :align => :justify }
65
- text_box = Prawn::Text::Formatted::Box.new(array, options)
66
- text_box.render
67
- contents = PDF::Inspector::Text.analyze(@pdf.render)
68
- contents.word_spacing[0].should.be > 0
69
- end
70
- end
71
283
 
72
- describe "Text::Formatted::Box#height without leading" do
73
- it "should equal the sum of the height of each line" do
74
- create_pdf
75
- format_array = [{ :text => "line 1" },
76
- { :text => "\n" },
77
- { :text => "line 2" }]
284
+ array = [{ :text => "hello" + " " * 500},
285
+ { :text => " " * 500 },
286
+ { :text => " " * 500 + "\n"},
287
+ { :text => "world"}]
78
288
  options = { :document => @pdf }
79
- text_box = Prawn::Text::Formatted::Box.new(format_array, options)
80
- text_box.render
81
- text_box.height.should == @pdf.font.height * 2
82
- end
83
- end
84
-
85
- describe "Text::Formatted::Box#height with leading" do
86
- it "should equal the sum of the height of each line" +
87
- " plus all but the last leading" do
88
- create_pdf
89
- format_array = [{ :text => "line 1" },
90
- { :text => "\n" },
91
- { :text => "line 2" }]
92
- leading = 12
93
- options = { :document => @pdf, :leading => leading }
94
- text_box = Prawn::Text::Formatted::Box.new(format_array, options)
289
+ text_box = Prawn::Text::Formatted::Box.new(array, options)
95
290
  text_box.render
96
- text_box.height.should == @pdf.font.height * 2 + leading
291
+ text_box.text.should == "hello\n\nworld"
97
292
  end
98
- end
99
-
100
- describe "Text::Formatted::Box#render(:single_line => true)" do
101
- it "should draw only one line to the page" do
293
+ it "should enable fragment level direction setting" do
102
294
  create_pdf
103
- text = "Oh hai text rect. " * 10
104
- format_array = [:text => text]
105
- options = { :document => @pdf,
106
- :single_line => true }
107
- text_box = Prawn::Text::Formatted::Box.new(format_array, options)
295
+ number_of_hellos = 18
296
+ array = [
297
+ { :text => "hello " * number_of_hellos },
298
+ { :text => "world", :direction => :ltr },
299
+ { :text => ", how are you?" }
300
+ ]
301
+ options = { :document => @pdf, :direction => :rtl }
302
+ text_box = Prawn::Text::Formatted::Box.new(array, options)
108
303
  text_box.render
109
- contents = PDF::Inspector::Text.analyze(@pdf.render)
110
- contents.strings.length.should == 1
111
- end
112
- end
113
-
114
- describe "Text::Formatted::Box#render(:dry_run => true)" do
115
- it "should not draw any content to the page" do
116
- create_pdf
117
- text = "Oh hai text rect. " * 10
118
- format_array = [:text => text]
119
- options = { :document => @pdf }
120
- text_box = Prawn::Text::Formatted::Box.new(format_array, options)
121
- text_box.render(:dry_run => true)
122
- contents = PDF::Inspector::Text.analyze(@pdf.render)
123
- contents.strings.should.be.empty
124
- end
125
- it "subsequent calls to render should not raise an ArgumentError exception" do
126
- create_pdf
127
- text = "™©"
128
- format_array = [:text => text]
129
- options = { :document => @pdf }
130
- text_box = Prawn::Text::Formatted::Box.new(format_array, options)
131
- text_box.render(:dry_run => true)
132
- lambda { text_box.render }.should.not.raise(ArgumentError)
304
+ text = PDF::Inspector::Text.analyze(@pdf.render)
305
+ text.strings[0].should == "era woh ,"
306
+ text.strings[1].should == "world"
307
+ text.strings[2].should == " olleh" * number_of_hellos
308
+ text.strings[3].should == "?uoy"
133
309
  end
134
310
  end
135
311
 
@@ -227,24 +403,24 @@ describe "Text::Formatted::Box#render" do
227
403
  it "should be able to set subscript" do
228
404
  create_pdf
229
405
  array = [{ :text => "this contains " },
230
- { :text => "subscript", :styles => [:subscript] },
406
+ { :text => "subscript", :size => 18, :styles => [:subscript] },
231
407
  { :text => " text" }]
232
408
  text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
233
409
  text_box.render
234
410
  contents = PDF::Inspector::Text.analyze(@pdf.render)
235
411
  contents.font_settings[0][:size].should == 12
236
- contents.font_settings[1][:size].should.be.close(12 * 0.583, 0.0001)
412
+ contents.font_settings[1][:size].should.be.close(18 * 0.583, 0.0001)
237
413
  end
238
414
  it "should be able to set superscript" do
239
415
  create_pdf
240
416
  array = [{ :text => "this contains " },
241
- { :text => "superscript", :styles => [:superscript] },
417
+ { :text => "superscript", :size => 18, :styles => [:superscript] },
242
418
  { :text => " text" }]
243
419
  text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
244
420
  text_box.render
245
421
  contents = PDF::Inspector::Text.analyze(@pdf.render)
246
422
  contents.font_settings[0][:size].should == 12
247
- contents.font_settings[1][:size].should.be.close(12 * 0.583, 0.0001)
423
+ contents.font_settings[1][:size].should.be.close(18 * 0.583, 0.0001)
248
424
  end
249
425
  it "should be able to set compound bold and italic text" do
250
426
  create_pdf
@@ -315,7 +491,7 @@ describe "Text::Formatted::Box#render" do
315
491
  text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
316
492
  text_box.render
317
493
  @pdf.font_size(24) do
318
- text_box.height.should.be.close(@pdf.font.height, 0.001)
494
+ text_box.height.should.be.close(@pdf.font.ascender + @pdf.font.descender, 0.001)
319
495
  end
320
496
  end
321
497
  it "should be able to set color via an rgb hex string" do
@@ -325,8 +501,8 @@ describe "Text::Formatted::Box#render" do
325
501
  text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
326
502
  text_box.render
327
503
  colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
328
- colors.fill_color_count.should == 3
329
- colors.stroke_color_count.should == 3
504
+ colors.fill_color_count.should == 2
505
+ colors.stroke_color_count.should == 2
330
506
  end
331
507
  it "should be able to set color using a cmyk array" do
332
508
  create_pdf
@@ -335,210 +511,8 @@ describe "Text::Formatted::Box#render" do
335
511
  text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
336
512
  text_box.render
337
513
  colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
338
- colors.fill_color_count.should == 3
339
- colors.stroke_color_count.should == 3
340
- end
341
- end
342
-
343
- describe "Text::Formatted::Box with text than can fit in the box" do
344
- before(:each) do
345
- create_pdf
346
- @text = "Oh hai text rect. " * 10
347
- @format_array = [:text => @text]
348
- @options = {
349
- :width => 162.0,
350
- :height => 162.0,
351
- :document => @pdf
352
- }
353
- end
354
-
355
- it "printed text should match requested text, except for trailing or" +
356
- " leading white space and that spaces may be replaced by newlines" do
357
- text_box = Prawn::Text::Formatted::Box.new(@format_array, @options)
358
- text_box.render
359
- text_box.text.gsub("\n", " ").should == @text.strip
360
- end
361
-
362
- it "render should return an empty array because no text remains unprinted" do
363
- text_box = Prawn::Text::Formatted::Box.new(@format_array, @options)
364
- text_box.render.should == []
365
- end
366
-
367
- it "should be truncated when the leading is set high enough to prevent all" +
368
- " the lines from being printed" do
369
- @options[:leading] = 40
370
- text_box = Prawn::Text::Formatted::Box.new(@format_array, @options)
371
- text_box.render
372
- text_box.text.gsub("\n", " ").should.not == @text.strip
373
- end
374
- end
375
-
376
- describe "Text::Formatted::Box printing UTF-8 string with higher bit characters with" +
377
- " inline styling" do
378
- before(:each) do
379
- create_pdf
380
- @text = "©"
381
- format_array = [:text => @text]
382
- # not enough height to print any text, so we can directly compare against
383
- # the input string
384
- bounding_height = 1.0
385
- options = {
386
- :height => bounding_height,
387
- :document => @pdf
388
- }
389
- @text_box = Prawn::Text::Formatted::Box.new(format_array, options)
390
- end
391
- describe "when using a TTF font" do
392
- before(:each) do
393
- file = "#{Prawn::BASEDIR}/data/fonts/Action Man.dfont"
394
- @pdf.font_families["Action Man"] = {
395
- :normal => { :file => file, :font => "ActionMan" },
396
- :italic => { :file => file, :font => "ActionMan-Italic" },
397
- :bold => { :file => file, :font => "ActionMan-Bold" },
398
- :bold_italic => { :file => file, :font => "ActionMan-BoldItalic" }
399
- }
400
- end
401
- it "unprinted text should be in UTF-8 encoding" do
402
- @pdf.font("Action Man")
403
- remaining_text = @text_box.render
404
- remaining_text.first[:text].should == @text
405
- end
406
- it "subsequent calls to Text::Formatted::Box need not include the" +
407
- " :skip_encoding => true option" do
408
- @pdf.font("Action Man")
409
- remaining_text = @text_box.render
410
- lambda {
411
- @pdf.formatted_text_box(remaining_text, :document => @pdf)
412
- }.should.not.raise(ArgumentError)
413
- end
414
- end
415
- describe "when using an AFM font" do
416
- it "unprinted text should be in WinAnsi encoding" do
417
- remaining_text = @text_box.render
418
- remaining_text.first[:text].should == @pdf.font.normalize_encoding(@text)
419
- end
420
- it "subsequent calls to Text::Formatted::Box must include the" +
421
- " :skip_encoding => true option" do
422
- remaining_text = @text_box.render
423
- lambda {
424
- @pdf.formatted_text_box(remaining_text, :document => @pdf)
425
- }.should.raise(ArgumentError)
426
- lambda {
427
- @pdf.formatted_text_box(remaining_text, :document => @pdf,
428
- :skip_encoding => true)
429
- }.should.not.raise(ArgumentError)
430
- end
431
- end
432
- end
433
-
434
-
435
- describe "Text::Formatted::Box with more text than can fit in the box" do
436
- before(:each) do
437
- create_pdf
438
- @text = "Oh hai text rect. " * 30
439
- @format_array = [:text => @text]
440
- @bounding_height = 162.0
441
- @options = {
442
- :width => 162.0,
443
- :height => @bounding_height,
444
- :document => @pdf
445
- }
446
- end
447
-
448
- context "truncated overflow" do
449
- before(:each) do
450
- @options[:overflow] = :truncate
451
- @text_box = Prawn::Text::Formatted::Box.new(@format_array, @options)
452
- end
453
- it "should be truncated" do
454
- @text_box.render
455
- @text_box.text.gsub("\n", " ").should.not == @text.strip
456
- end
457
- it "render should not return an empty string because some text remains" +
458
- " unprinted" do
459
- @text_box.render.should.not == ""
460
- end
461
- it "#height should be no taller than the specified height" do
462
- @text_box.render
463
- @text_box.height.should.be <= @bounding_height
464
- end
465
- it "#height should be within one font height of the specified height" do
466
- @text_box.render
467
- @text_box.height.should.be.close(@bounding_height, @pdf.font.height)
468
- end
469
- end
470
-
471
- context "ellipses overflow" do
472
- it "should raise NotImplementedError" do
473
- @options[:overflow] = :ellipses
474
- lambda {
475
- Prawn::Text::Formatted::Box.new(@format_array, @options)
476
- }.should.raise(NotImplementedError)
477
- end
478
- end
479
-
480
- context "expand overflow" do
481
- before(:each) do
482
- @options[:overflow] = :expand
483
- @text_box = Prawn::Text::Formatted::Box.new(@format_array, @options)
484
- end
485
- it "height should expand to encompass all the text (but not exceed the" +
486
- "height of the page)" do
487
- @text_box.render
488
- @text_box.height.should > @bounding_height
489
- end
490
- it "should display the entire string (as long as there was space" +
491
- " remaining on the page to print all the text)" do
492
- @text_box.render
493
- @text_box.text.gsub("\n", " ").should == @text.strip
494
- end
495
- it "render should return an empty array because no text remains" +
496
- " unprinted(as long as there was space remaining on the page to" +
497
- " print all the text)" do
498
- @text_box.render.should == []
499
- end
500
- end
501
-
502
- context "shrink_to_fit overflow" do
503
- before(:each) do
504
- @options[:overflow] = :shrink_to_fit
505
- @options[:min_font_size] = 2
506
- @text_box = Prawn::Text::Formatted::Box.new(@format_array, @options)
507
- end
508
- it "should display the entire text" do
509
- @text_box.render
510
- @text_box.text.gsub("\n", " ").should == @text.strip
511
- end
512
- it "render should return an empty array because no text" +
513
- " remains unprinted" do
514
- @text_box.render.should == []
515
- end
516
- end
517
- end
518
-
519
- describe "Text::Formatted::Box#render with box level :character_spacing option" do
520
- it "should draw the character spacing to the document only one time" do
521
- create_pdf
522
- array = [{ :text => "hello world" }]
523
- options = { :document => @pdf,
524
- :character_spacing => 7 }
525
- text_box = Prawn::Text::Formatted::Box.new(array, options)
526
- text_box.render
527
- contents = PDF::Inspector::Text.analyze(@pdf.render)
528
- contents.character_spacing[0].should == 7
529
- contents.character_spacing.length.should == 2
530
- end
531
- it "should draw the character spacing to the document" do
532
- create_pdf
533
- array = [{ :text => "hello world",
534
- :font => "Courier" }]
535
- options = { :document => @pdf,
536
- :width => 100,
537
- :overflow => :expand,
538
- :character_spacing => 10 }
539
- text_box = Prawn::Text::Formatted::Box.new(array, options)
540
- text_box.render
541
- text_box.text.should == "hello\nworld"
514
+ colors.fill_color_count.should == 2
515
+ colors.stroke_color_count.should == 2
542
516
  end
543
517
  end
544
518
 
@@ -567,138 +541,18 @@ describe "Text::Formatted::Box#render with fragment level :character_spacing opt
567
541
  end
568
542
  end
569
543
 
570
- describe "Text::Formatted::Box wrapping" do
571
- before(:each) do
544
+ describe "Text::Formatted::Box#render with :align => :justify" do
545
+ it "should not justify the last line of a paragraph" do
572
546
  create_pdf
573
- end
574
-
575
- it "should wrap text" do
576
- text = "Please wrap this text about HERE. More text that should be wrapped"
577
- format_array = [:text => text]
578
- expect = "Please wrap this text about\nHERE. " +
579
- "More text that should be\nwrapped"
580
-
581
- @pdf.font "Courier"
582
- text_box = Prawn::Text::Formatted::Box.new(format_array,
583
- :width => 220,
584
- :overflow => :expand,
585
- :document => @pdf)
586
- text_box.render
587
- text_box.text.should == expect
588
- end
589
-
590
- it "should respect end of line when wrapping text" do
591
- text = "Please wrap only before\nTHIS word. Don't wrap this"
592
- format_array = [:text => text]
593
- expect = text
594
-
595
- @pdf.font "Courier"
596
- text_box = Prawn::Text::Formatted::Box.new(format_array,
597
- :width => 220,
598
- :overflow => :expand,
599
- :document => @pdf)
600
- text_box.render
601
- text_box.text.should == expect
602
- end
603
-
604
- it "should respect multiple newlines when wrapping text" do
605
- text = "Please wrap only before THIS\n\nword. Don't wrap this"
606
- format_array = [:text => text]
607
- expect= "Please wrap only before\nTHIS\n\nword. Don't wrap this"
608
-
609
- @pdf.font "Courier"
610
- text_box = Prawn::Text::Formatted::Box.new(format_array,
611
- :width => 200,
612
- :overflow => :expand,
613
- :document => @pdf)
614
- text_box.render
615
- text_box.text.should == expect
616
- end
617
-
618
- it "should respect multiple newlines when wrapping text when those newlines" +
619
- " coincide with a line break" do
620
- text = "Please wrap only before\n\nTHIS word. Don't wrap this"
621
- format_array = [:text => text]
622
- expect = text
623
-
624
- @pdf.font "Courier"
625
- text_box = Prawn::Text::Formatted::Box.new(format_array,
626
- :width => 220,
627
- :overflow => :expand,
628
- :document => @pdf)
629
- text_box.render
630
- text_box.text.should == expect
631
- end
632
-
633
- it "should respect initial newlines" do
634
- text = "\nThis should be on line 2"
635
- format_array = [:text => text]
636
- expect = text
637
-
638
- @pdf.font "Courier"
639
- text_box = Prawn::Text::Formatted::Box.new(format_array,
640
- :width => 220,
641
- :overflow => :expand,
642
- :document => @pdf)
643
- text_box.render
644
- text_box.text.should == expect
645
- end
646
-
647
- it "should wrap lines comprised of a single word of the bounds when" +
648
- " wrapping text" do
649
- text = "You_can_wrap_this_text_HERE"
650
- format_array = [:text => text]
651
- expect = "You_can_wrap_this_text_HE\nRE"
652
-
653
- @pdf.font "Courier"
654
- text_box = Prawn::Text::Formatted::Box.new(format_array,
655
- :width => 180,
656
- :overflow => :expand,
657
- :document => @pdf)
658
- text_box.render
659
- text_box.text.should == expect
660
- end
661
-
662
- it "should wrap lines comprised of a single word of the bounds when" +
663
- " wrapping text" do
664
- text = "©" * 30
665
- format_array = [:text => text]
666
-
667
- @pdf.font "Courier"
668
- text_box = Prawn::Text::Formatted::Box.new(format_array, :width => 180,
669
- :overflow => :expand,
670
- :document => @pdf)
671
-
672
- text_box.render
673
-
674
- expected = "©" * 25 + "\n" + "©" * 5
675
- @pdf.font.normalize_encoding!(expected)
676
-
677
- text_box.text.should == expected
678
- end
679
-
680
- it "should wrap non-unicode strings using single-byte word-wrapping" do
681
- text = "continúa esforzandote " * 5
682
- format_array = [:text => text]
683
- text_box = Prawn::Text::Formatted::Box.new(format_array, :width => 180,
684
- :document => @pdf)
685
- text_box.render
686
- results_with_accent = text_box.text
687
-
688
- text = "continua esforzandote " * 5
689
- format_array = [:text => text]
690
- text_box = Prawn::Text::Formatted::Box.new(format_array, :width => 180,
691
- :document => @pdf)
547
+ array = [{ :text => "hello world " },
548
+ { :text => "\n" },
549
+ { :text => "goodbye" }]
550
+ options = { :document => @pdf, :align => :justify }
551
+ text_box = Prawn::Text::Formatted::Box.new(array, options)
692
552
  text_box.render
693
- no_accent = text_box.text
694
-
695
- results_with_accent.first_line.length.should == no_accent.first_line.length
553
+ contents = PDF::Inspector::Text.analyze(@pdf.render)
554
+ contents.word_spacing.should.be.empty
696
555
  end
697
-
698
- end
699
-
700
- def reduce_precision(float)
701
- ("%.5f" % float).to_f
702
556
  end
703
557
 
704
558
  class TestFragmentCallback
@@ -732,25 +586,15 @@ class TestFragmentCallbackInFront
732
586
  end
733
587
 
734
588
  module TestFormattedWrapOverride
735
- def wrap(string)
736
- @text = nil
737
- @line_height = @document.font.height
738
- @descender = @document.font.descender
739
- @ascender = @document.font.ascender
740
- @baseline_y = -@ascender
741
- draw_line("all your base are belong to us")
742
- []
743
- end
744
- end
589
+ def wrap(array)
590
+ initialize_wrap([{ :text => 'all your base are belong to us' }])
591
+ line_to_print = @line_wrap.wrap_line(:document => @document,
592
+ :kerning => @kerning,
593
+ :width => 10000,
594
+ :arranger => @arranger)
595
+ fragment = @arranger.retrieve_fragment
596
+ format_and_draw_fragment(fragment, 0, @line_wrap.width, 0)
745
597
 
746
- module TestWrapOverride
747
- def wrap(string)
748
- @text = nil
749
- @line_height = @document.font.height
750
- @descender = @document.font.descender
751
- @ascender = @document.font.ascender
752
- @baseline_y = -@ascender
753
- draw_line("all your base are belong to us")
754
- ""
598
+ []
755
599
  end
756
600
  end