alphasights-prawn 0.10.0

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 (244) hide show
  1. data/COPYING +340 -0
  2. data/HACKING +50 -0
  3. data/LICENSE +56 -0
  4. data/README +141 -0
  5. data/Rakefile +52 -0
  6. data/data/encodings/win_ansi.txt +29 -0
  7. data/data/fonts/Action Man.dfont +0 -0
  8. data/data/fonts/Activa.ttf +0 -0
  9. data/data/fonts/Chalkboard.ttf +0 -0
  10. data/data/fonts/Courier-Bold.afm +342 -0
  11. data/data/fonts/Courier-BoldOblique.afm +342 -0
  12. data/data/fonts/Courier-Oblique.afm +342 -0
  13. data/data/fonts/Courier.afm +342 -0
  14. data/data/fonts/DejaVuSans.ttf +0 -0
  15. data/data/fonts/Dustismo_Roman.ttf +0 -0
  16. data/data/fonts/Helvetica-Bold.afm +2827 -0
  17. data/data/fonts/Helvetica-BoldOblique.afm +2827 -0
  18. data/data/fonts/Helvetica-Oblique.afm +3051 -0
  19. data/data/fonts/Helvetica.afm +3051 -0
  20. data/data/fonts/MustRead.html +19 -0
  21. data/data/fonts/Symbol.afm +213 -0
  22. data/data/fonts/Times-Bold.afm +2588 -0
  23. data/data/fonts/Times-BoldItalic.afm +2384 -0
  24. data/data/fonts/Times-Italic.afm +2667 -0
  25. data/data/fonts/Times-Roman.afm +2419 -0
  26. data/data/fonts/ZapfDingbats.afm +225 -0
  27. data/data/fonts/comicsans.ttf +0 -0
  28. data/data/fonts/gkai00mp.ttf +0 -0
  29. data/data/images/16bit.alpha +0 -0
  30. data/data/images/16bit.dat +0 -0
  31. data/data/images/16bit.png +0 -0
  32. data/data/images/arrow.png +0 -0
  33. data/data/images/arrow2.png +0 -0
  34. data/data/images/barcode_issue.png +0 -0
  35. data/data/images/dice.alpha +0 -0
  36. data/data/images/dice.dat +0 -0
  37. data/data/images/dice.png +0 -0
  38. data/data/images/dice_interlaced.png +0 -0
  39. data/data/images/fractal.jpg +0 -0
  40. data/data/images/letterhead.jpg +0 -0
  41. data/data/images/page_white_text.alpha +0 -0
  42. data/data/images/page_white_text.dat +0 -0
  43. data/data/images/page_white_text.png +0 -0
  44. data/data/images/pigs.jpg +0 -0
  45. data/data/images/rails.dat +0 -0
  46. data/data/images/rails.png +0 -0
  47. data/data/images/ruport.png +0 -0
  48. data/data/images/ruport_data.dat +0 -0
  49. data/data/images/ruport_transparent.png +0 -0
  50. data/data/images/ruport_type0.png +0 -0
  51. data/data/images/stef.jpg +0 -0
  52. data/data/images/tru256.bmp +0 -0
  53. data/data/images/web-links.dat +1 -0
  54. data/data/images/web-links.png +0 -0
  55. data/data/pdfs/complex_template.pdf +0 -0
  56. data/data/pdfs/contains_ttf_font.pdf +0 -0
  57. data/data/pdfs/encrypted.pdf +0 -0
  58. data/data/pdfs/hexagon.pdf +61 -0
  59. data/data/pdfs/indirect_reference.pdf +86 -0
  60. data/data/pdfs/nested_pages.pdf +118 -0
  61. data/data/pdfs/resources_as_indirect_object.pdf +83 -0
  62. data/data/pdfs/two_hexagons.pdf +90 -0
  63. data/data/pdfs/version_1_6.pdf +61 -0
  64. data/data/shift_jis_text.txt +1 -0
  65. data/examples/bounding_box/bounding_boxes.rb +43 -0
  66. data/examples/bounding_box/indentation.rb +34 -0
  67. data/examples/bounding_box/russian_boxes.rb +36 -0
  68. data/examples/bounding_box/stretched_nesting.rb +67 -0
  69. data/examples/builder/simple.rb +28 -0
  70. data/examples/example_helper.rb +4 -0
  71. data/examples/general/background.rb +23 -0
  72. data/examples/general/canvas.rb +15 -0
  73. data/examples/general/context_sensitive_headers.rb +37 -0
  74. data/examples/general/float.rb +11 -0
  75. data/examples/general/margin.rb +36 -0
  76. data/examples/general/measurement_units.rb +51 -0
  77. data/examples/general/metadata-info.rb +16 -0
  78. data/examples/general/multi_page_layout.rb +18 -0
  79. data/examples/general/outlines.rb +50 -0
  80. data/examples/general/page_geometry.rb +31 -0
  81. data/examples/general/page_numbering.rb +15 -0
  82. data/examples/general/repeaters.rb +47 -0
  83. data/examples/general/stamp.rb +41 -0
  84. data/examples/general/templates.rb +13 -0
  85. data/examples/graphics/basic_images.rb +23 -0
  86. data/examples/graphics/chunkable.rb +38 -0
  87. data/examples/graphics/cmyk.rb +12 -0
  88. data/examples/graphics/curves.rb +11 -0
  89. data/examples/graphics/hexagon.rb +13 -0
  90. data/examples/graphics/image_fit.rb +15 -0
  91. data/examples/graphics/image_flow.rb +37 -0
  92. data/examples/graphics/image_position.rb +17 -0
  93. data/examples/graphics/line.rb +32 -0
  94. data/examples/graphics/png_types.rb +22 -0
  95. data/examples/graphics/polygons.rb +16 -0
  96. data/examples/graphics/remote_images.rb +12 -0
  97. data/examples/graphics/rounded_polygons.rb +19 -0
  98. data/examples/graphics/rounded_rectangle.rb +20 -0
  99. data/examples/graphics/ruport_style_helpers.rb +19 -0
  100. data/examples/graphics/stroke_bounds.rb +20 -0
  101. data/examples/graphics/stroke_cap_and_join.rb +45 -0
  102. data/examples/graphics/stroke_dash.rb +42 -0
  103. data/examples/graphics/transformations.rb +52 -0
  104. data/examples/graphics/transparency.rb +26 -0
  105. data/examples/m17n/chinese_text_wrapping.rb +17 -0
  106. data/examples/m17n/euro.rb +15 -0
  107. data/examples/m17n/sjis.rb +28 -0
  108. data/examples/m17n/utf8.rb +13 -0
  109. data/examples/m17n/win_ansi_charset.rb +54 -0
  110. data/examples/security/hello_foo.rb +8 -0
  111. data/examples/table/bill.rb +53 -0
  112. data/examples/table/cell.rb +12 -0
  113. data/examples/table/checkerboard.rb +22 -0
  114. data/examples/table/header.rb +14 -0
  115. data/examples/table/inline_format_table.rb +12 -0
  116. data/examples/table/multi_page_table.rb +9 -0
  117. data/examples/table/simple_table.rb +24 -0
  118. data/examples/table/subtable.rb +12 -0
  119. data/examples/table/widths.rb +20 -0
  120. data/examples/text/alignment.rb +18 -0
  121. data/examples/text/character_spacing.rb +12 -0
  122. data/examples/text/dfont.rb +48 -0
  123. data/examples/text/family_based_styling.rb +24 -0
  124. data/examples/text/font_calculations.rb +91 -0
  125. data/examples/text/font_size.rb +33 -0
  126. data/examples/text/hyphenation.rb +45 -0
  127. data/examples/text/indent_paragraphs.rb +22 -0
  128. data/examples/text/inline_format.rb +103 -0
  129. data/examples/text/kerning.rb +30 -0
  130. data/examples/text/rotated.rb +98 -0
  131. data/examples/text/shaped_text_box.rb +31 -0
  132. data/examples/text/simple_text.rb +17 -0
  133. data/examples/text/simple_text_ttf.rb +17 -0
  134. data/examples/text/text_box.rb +88 -0
  135. data/examples/text/text_box_returning_excess.rb +51 -0
  136. data/examples/text/text_flow.rb +67 -0
  137. data/lib/prawn.rb +27 -0
  138. data/lib/prawn/canvas.rb +119 -0
  139. data/lib/prawn/chunkable.rb +37 -0
  140. data/lib/prawn/compatibility.rb +51 -0
  141. data/lib/prawn/core.rb +85 -0
  142. data/lib/prawn/core/annotations.rb +61 -0
  143. data/lib/prawn/core/byte_string.rb +9 -0
  144. data/lib/prawn/core/chunk.rb +36 -0
  145. data/lib/prawn/core/destinations.rb +90 -0
  146. data/lib/prawn/core/document_state.rb +78 -0
  147. data/lib/prawn/core/literal_string.rb +16 -0
  148. data/lib/prawn/core/name_tree.rb +165 -0
  149. data/lib/prawn/core/object_store.rb +236 -0
  150. data/lib/prawn/core/page.rb +179 -0
  151. data/lib/prawn/core/pdf_object.rb +108 -0
  152. data/lib/prawn/core/reference.rb +112 -0
  153. data/lib/prawn/core/text.rb +140 -0
  154. data/lib/prawn/core/text/formatted/arranger.rb +266 -0
  155. data/lib/prawn/core/text/formatted/line_wrap.rb +127 -0
  156. data/lib/prawn/core/text/formatted/wrap.rb +112 -0
  157. data/lib/prawn/core/text/line_wrap.rb +209 -0
  158. data/lib/prawn/core/text/wrap.rb +80 -0
  159. data/lib/prawn/document.rb +573 -0
  160. data/lib/prawn/document/bounding_box.rb +425 -0
  161. data/lib/prawn/document/graphics_state.rb +48 -0
  162. data/lib/prawn/document/internals.rb +170 -0
  163. data/lib/prawn/document/page_geometry.rb +136 -0
  164. data/lib/prawn/document/snapshot.rb +87 -0
  165. data/lib/prawn/document_builder.rb +51 -0
  166. data/lib/prawn/document_builder/command.rb +38 -0
  167. data/lib/prawn/document_builder/constructs.rb +2 -0
  168. data/lib/prawn/document_builder/constructs/flowing_text_construct.rb +18 -0
  169. data/lib/prawn/document_builder/constructs/path_construct.rb +9 -0
  170. data/lib/prawn/document_builder/layout.rb +25 -0
  171. data/lib/prawn/document_builder/modifications.rb +2 -0
  172. data/lib/prawn/document_builder/modifications/layout_modification.rb +9 -0
  173. data/lib/prawn/document_builder/modifications/path_modification.rb +9 -0
  174. data/lib/prawn/encoding.rb +121 -0
  175. data/lib/prawn/errors.rb +94 -0
  176. data/lib/prawn/font.rb +341 -0
  177. data/lib/prawn/font/afm.rb +225 -0
  178. data/lib/prawn/font/dfont.rb +42 -0
  179. data/lib/prawn/font/ttf.rb +350 -0
  180. data/lib/prawn/graphics.rb +325 -0
  181. data/lib/prawn/graphics/cap_style.rb +38 -0
  182. data/lib/prawn/graphics/color.rb +205 -0
  183. data/lib/prawn/graphics/dash.rb +71 -0
  184. data/lib/prawn/graphics/join_style.rb +38 -0
  185. data/lib/prawn/graphics/transformation.rb +156 -0
  186. data/lib/prawn/graphics/transparency.rb +99 -0
  187. data/lib/prawn/images.rb +348 -0
  188. data/lib/prawn/images/jpg.rb +46 -0
  189. data/lib/prawn/images/png.rb +226 -0
  190. data/lib/prawn/measurement_extensions.rb +46 -0
  191. data/lib/prawn/measurements.rb +71 -0
  192. data/lib/prawn/outline.rb +278 -0
  193. data/lib/prawn/repeater.rb +129 -0
  194. data/lib/prawn/security.rb +262 -0
  195. data/lib/prawn/security/arcfour.rb +51 -0
  196. data/lib/prawn/stamp.rb +126 -0
  197. data/lib/prawn/table.rb +421 -0
  198. data/lib/prawn/table/accessors.rb +180 -0
  199. data/lib/prawn/table/cell.rb +350 -0
  200. data/lib/prawn/table/cell/in_table.rb +27 -0
  201. data/lib/prawn/table/cell/subtable.rb +65 -0
  202. data/lib/prawn/table/cell/text.rb +125 -0
  203. data/lib/prawn/text.rb +449 -0
  204. data/lib/prawn/text/box.rb +392 -0
  205. data/lib/prawn/text/formatted.rb +4 -0
  206. data/lib/prawn/text/formatted/box.rb +228 -0
  207. data/lib/prawn/text/formatted/fragment.rb +181 -0
  208. data/lib/prawn/text/formatted/parser.rb +213 -0
  209. data/spec/annotations_spec.rb +90 -0
  210. data/spec/bounding_box_spec.rb +190 -0
  211. data/spec/cell_spec.rb +348 -0
  212. data/spec/destinations_spec.rb +15 -0
  213. data/spec/document_spec.rb +473 -0
  214. data/spec/font_spec.rb +324 -0
  215. data/spec/formatted_text_arranger_spec.rb +426 -0
  216. data/spec/formatted_text_box_spec.rb +756 -0
  217. data/spec/formatted_text_fragment_spec.rb +211 -0
  218. data/spec/graphics_spec.rb +446 -0
  219. data/spec/images_spec.rb +96 -0
  220. data/spec/inline_formatted_text_parser_spec.rb +502 -0
  221. data/spec/jpg_spec.rb +25 -0
  222. data/spec/line_wrap_spec.rb +341 -0
  223. data/spec/measurement_units_spec.rb +23 -0
  224. data/spec/name_tree_spec.rb +112 -0
  225. data/spec/object_store_spec.rb +160 -0
  226. data/spec/outline_spec.rb +269 -0
  227. data/spec/pdf_object_spec.rb +170 -0
  228. data/spec/png_spec.rb +237 -0
  229. data/spec/reference_spec.rb +82 -0
  230. data/spec/repeater_spec.rb +96 -0
  231. data/spec/security_spec.rb +120 -0
  232. data/spec/snapshot_spec.rb +138 -0
  233. data/spec/spec_helper.rb +26 -0
  234. data/spec/stamp_spec.rb +108 -0
  235. data/spec/stroke_styles_spec.rb +163 -0
  236. data/spec/table_spec.rb +598 -0
  237. data/spec/template_spec.rb +158 -0
  238. data/spec/text_at_spec.rb +119 -0
  239. data/spec/text_box_spec.rb +742 -0
  240. data/spec/text_spacing_spec.rb +75 -0
  241. data/spec/text_spec.rb +333 -0
  242. data/spec/text_with_inline_formatting_spec.rb +193 -0
  243. data/spec/transparency_spec.rb +89 -0
  244. metadata +331 -0
@@ -0,0 +1,158 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
2
+
3
+ describe "Document built from a template" do
4
+
5
+ it "should have the same page count as the source document" do
6
+ filename = "#{Prawn::BASEDIR}/reference_pdfs/curves.pdf"
7
+ @pdf = Prawn::Document.new(:template => filename)
8
+ page_counter = PDF::Inspector::Page.analyze(@pdf.render)
9
+
10
+ page_counter.pages.size.should == 1
11
+ end
12
+
13
+ it "should have start with the Y cursor at the top of the document" do
14
+ filename = "#{Prawn::BASEDIR}/reference_pdfs/curves.pdf"
15
+
16
+ @pdf = Prawn::Document.new(:template => filename)
17
+ (@pdf.y == nil).should == false
18
+ end
19
+
20
+ it "should respect margins set by Prawn" do
21
+ filename = "#{Prawn::BASEDIR}/reference_pdfs/curves.pdf"
22
+
23
+ @pdf = Prawn::Document.new(:template => filename, :margin => 0)
24
+ assert_equal @pdf.page.margins, { :left => 0,
25
+ :right => 0,
26
+ :top => 0,
27
+ :bottom => 0 }
28
+
29
+ @pdf = Prawn::Document.new(:template => filename, :left_margin => 0)
30
+
31
+ assert_equal @pdf.page.margins, { :left => 0,
32
+ :right => 36,
33
+ :top => 36,
34
+ :bottom => 36 }
35
+
36
+ @pdf.start_new_page(:right_margin => 0)
37
+
38
+ assert_equal @pdf.page.margins, { :left => 0,
39
+ :right => 0,
40
+ :top => 36,
41
+ :bottom => 36 }
42
+
43
+
44
+
45
+ end
46
+
47
+ it "should not add an extra restore_graphics_state operator to the end of any content stream" do
48
+ filename = "#{Prawn::BASEDIR}/reference_pdfs/curves.pdf"
49
+
50
+ @pdf = Prawn::Document.new(:template => filename)
51
+ output = StringIO.new(@pdf.render)
52
+ hash = PDF::Hash.new(output)
53
+
54
+ hash.each_value do |obj|
55
+ next unless obj.kind_of?(PDF::Reader::Stream)
56
+
57
+ data = obj.data.tr(" \n\r","")
58
+ data.include?("QQ").should == false
59
+ end
60
+ end
61
+
62
+ it "should have a single page object if importing a single page template" do
63
+ filename = "#{Prawn::BASEDIR}/data/pdfs/hexagon.pdf"
64
+
65
+ @pdf = Prawn::Document.new(:template => filename)
66
+ output = StringIO.new(@pdf.render)
67
+ hash = PDF::Hash.new(output)
68
+
69
+ pages = hash.values.select { |obj| obj.kind_of?(Hash) && obj[:Type] == :Page }
70
+
71
+ pages.size.should == 1
72
+ end
73
+
74
+ it "should have two content streams if importing a single page template" do
75
+ filename = "#{Prawn::BASEDIR}/data/pdfs/hexagon.pdf"
76
+
77
+ @pdf = Prawn::Document.new(:template => filename)
78
+ output = StringIO.new(@pdf.render)
79
+ hash = PDF::Hash.new(output)
80
+
81
+ streams = hash.values.select { |obj| obj.kind_of?(PDF::Reader::Stream) }
82
+
83
+ streams.size.should == 2
84
+ end
85
+
86
+ it "should not die if using this PDF as a template" do
87
+ filename = "#{Prawn::BASEDIR}/data/pdfs/complex_template.pdf"
88
+
89
+ assert_nothing_raised do
90
+ @pdf = Prawn::Document.new(:template => filename)
91
+ end
92
+ end
93
+
94
+
95
+ it "should have balance q/Q operators on all content streams" do
96
+ filename = "#{Prawn::BASEDIR}/data/pdfs/hexagon.pdf"
97
+
98
+ @pdf = Prawn::Document.new(:template => filename)
99
+ output = StringIO.new(@pdf.render)
100
+ hash = PDF::Hash.new(output)
101
+
102
+ streams = hash.values.select { |obj| obj.kind_of?(PDF::Reader::Stream) }
103
+
104
+ streams.each do |stream|
105
+ data = stream.unfiltered_data
106
+ data.scan("q").size.should == 1
107
+ data.scan("Q").size.should == 1
108
+ end
109
+ end
110
+
111
+ it "should allow text to be added to a single page template" do
112
+ filename = "#{Prawn::BASEDIR}/data/pdfs/hexagon.pdf"
113
+
114
+ @pdf = Prawn::Document.new(:template => filename)
115
+
116
+ @pdf.text "Adding some text"
117
+
118
+ text = PDF::Inspector::Text.analyze(@pdf.render)
119
+ text.strings.first.should == "Adding some text"
120
+ end
121
+
122
+ it "should allow PDFs with page resources behind an indirect object to be used as templates" do
123
+ filename = "#{Prawn::BASEDIR}/data/pdfs/resources_as_indirect_object.pdf"
124
+
125
+ @pdf = Prawn::Document.new(:template => filename)
126
+
127
+ @pdf.text "Adding some text"
128
+
129
+ text = PDF::Inspector::Text.analyze(@pdf.render)
130
+ all_text = text.strings.join("")
131
+ all_text.include?("Adding some text").should == true
132
+ end
133
+
134
+ it "should copy the PDF version from the template file" do
135
+ filename = "#{Prawn::BASEDIR}/data/pdfs/version_1_6.pdf"
136
+
137
+ @pdf = Prawn::Document.new(:template => filename)
138
+ str = @pdf.render
139
+ str[0,8].should == "%PDF-1.6"
140
+ end
141
+
142
+ xit "should correctly add a TTF font to a template that has existing fonts" do
143
+ filename = "#{Prawn::BASEDIR}/data/pdfs/contains_ttf_font.pdf"
144
+ @pdf = Prawn::Document.new(:template => filename)
145
+ @pdf.font "#{Prawn::BASEDIR}/data/fonts/Chalkboard.ttf"
146
+ @pdf.move_down(40)
147
+ @pdf.text "Hi There"
148
+
149
+ output = StringIO.new(@pdf.render)
150
+ hash = PDF::Hash.new(output)
151
+
152
+ page_dict = hash.values.detect{ |obj| obj.is_a?(Hash) && obj[:Type] == :Page }
153
+ resources = page_dict[:Resources]
154
+ fonts = resources[:Font]
155
+ fonts.size.should == 2
156
+ end
157
+
158
+ end
@@ -0,0 +1,119 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
+
5
+ describe "#draw_text" do
6
+ before(:each) { create_pdf }
7
+
8
+ it "should raise ArgumentError if :at option omitted" do
9
+ lambda { @pdf.draw_text("hai", { }) }.should.raise(ArgumentError)
10
+ end
11
+
12
+ it "should raise ArgumentError if :align option included" do
13
+ lambda { @pdf.draw_text("hai", :at => [0, 0], :align => :center) }.should.raise(ArgumentError)
14
+ end
15
+
16
+ it "should default to 12 point helvetica" do
17
+ @pdf.draw_text("Blah", :at => [100,100])
18
+ text = PDF::Inspector::Text.analyze(@pdf.render)
19
+ text.font_settings[0][:name].should == :Helvetica
20
+ text.font_settings[0][:size].should == 12
21
+ text.strings.first.should == "Blah"
22
+ end
23
+
24
+ it "should allow setting font size" do
25
+ @pdf.draw_text("Blah", :at => [100,100], :size => 16)
26
+ text = PDF::Inspector::Text.analyze(@pdf.render)
27
+ text.font_settings[0][:size].should == 16
28
+ end
29
+
30
+ it "should allow setting a default font size" do
31
+ @pdf.font_size = 16
32
+ @pdf.draw_text("Blah", :at => [0, 0])
33
+ text = PDF::Inspector::Text.analyze(@pdf.render)
34
+ text.font_settings[0][:size].should == 16
35
+ end
36
+
37
+ it "should allow overriding default font for a single instance" do
38
+ @pdf.font_size = 16
39
+
40
+ @pdf.draw_text("Blah", :size => 11, :at => [0, 0])
41
+ @pdf.draw_text("Blaz", :at => [0, 0])
42
+ text = PDF::Inspector::Text.analyze(@pdf.render)
43
+ text.font_settings[0][:size].should == 11
44
+ text.font_settings[1][:size].should == 16
45
+ end
46
+
47
+ it "should allow setting a font size transaction with a block" do
48
+ @pdf.font_size 16 do
49
+ @pdf.draw_text('Blah', :at => [0, 0])
50
+ end
51
+
52
+ @pdf.draw_text('blah', :at => [0, 0])
53
+
54
+ text = PDF::Inspector::Text.analyze(@pdf.render)
55
+ text.font_settings[0][:size].should == 16
56
+ text.font_settings[1][:size].should == 12
57
+ end
58
+
59
+ it "should allow manual setting the font size " +
60
+ "when in a font size block" do
61
+ @pdf.font_size(16) do
62
+ @pdf.draw_text('Foo', :at => [0, 0])
63
+ @pdf.draw_text('Blah', :size => 11, :at => [0, 0])
64
+ @pdf.draw_text('Blaz', :at => [0, 0])
65
+ end
66
+ text = PDF::Inspector::Text.analyze(@pdf.render)
67
+ text.font_settings[0][:size].should == 16
68
+ text.font_settings[1][:size].should == 11
69
+ text.font_settings[2][:size].should == 16
70
+ end
71
+
72
+ it "should allow registering of built-in font_settings on the fly" do
73
+ @pdf.font "Times-Roman"
74
+ @pdf.draw_text("Blah", :at => [100,100], :at => [0, 0])
75
+ @pdf.font "Courier"
76
+ @pdf.draw_text("Blaz", :at => [150,150], :at => [0, 0])
77
+ text = PDF::Inspector::Text.analyze(@pdf.render)
78
+ text.font_settings[0][:name].should == :"Times-Roman"
79
+ text.font_settings[1][:name].should == :Courier
80
+ end
81
+
82
+ it "should raise an exception when an unknown font is used" do
83
+ lambda { @pdf.font "Pao bu" }.should.raise(Prawn::Errors::UnknownFont)
84
+ end
85
+
86
+ it "should correctly render a utf-8 string when using a built-in font" do
87
+ str = "©" # copyright symbol
88
+ @pdf.draw_text(str, :at => [0, 0])
89
+
90
+ # grab the text from the rendered PDF and ensure it matches
91
+ text = PDF::Inspector::Text.analyze(@pdf.render)
92
+ text.strings.first.should == str
93
+ end
94
+
95
+ if "spec".respond_to?(:encode!)
96
+ # Handle non utf-8 string encodings in a sane way on M17N aware VMs
97
+ it "should raise an exception when a utf-8 incompatible string is rendered" do
98
+ str = "Blah \xDD"
99
+ str.force_encoding("ASCII-8BIT")
100
+ lambda { @pdf.draw_text(str, :at => [0, 0]) }.should.raise(ArgumentError)
101
+ end
102
+ it "should not raise an exception when a shift-jis string is rendered" do
103
+ datafile = "#{Prawn::BASEDIR}/data/shift_jis_text.txt"
104
+ sjis_str = File.open(datafile, "r:shift_jis") { |f| f.gets }
105
+ @pdf.font("#{Prawn::BASEDIR}/data/fonts/gkai00mp.ttf")
106
+ lambda { @pdf.draw_text(sjis_str, :at => [0, 0]) }.should.not.raise(ArgumentError)
107
+ end
108
+ else
109
+ # Handle non utf-8 string encodings in a sane way on non-M17N aware VMs
110
+ it "should raise an exception when a corrupt utf-8 string is rendered" do
111
+ str = "Blah \xDD"
112
+ lambda { @pdf.draw_text(str, :at => [0, 0]) }.should.raise(ArgumentError)
113
+ end
114
+ it "should raise an exception when a shift-jis string is rendered" do
115
+ sjis_str = File.read("#{Prawn::BASEDIR}/data/shift_jis_text.txt")
116
+ lambda { @pdf.draw_text(sjis_str, :at => [0, 0]) }.should.raise(ArgumentError)
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,742 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
+
5
+ describe "Text::Box" do
6
+
7
+ it "should be able to set leading document wide" do
8
+ create_pdf
9
+ @pdf.default_leading(7)
10
+ @pdf.default_leading = 7
11
+ text_box = Prawn::Text::Box.new("hello world",
12
+ :document => @pdf)
13
+ text_box.leading.should == 7
14
+ end
15
+
16
+ it "option should be able to override document wide leading" do
17
+ create_pdf
18
+ @pdf.default_leading = 7
19
+ text_box = Prawn::Text::Box.new("hello world",
20
+ :document => @pdf,
21
+ :leading => 20)
22
+ text_box.leading.should == 20
23
+ end
24
+ it "should default to document-wide leading if no" +
25
+ "leading option is provided" do
26
+
27
+ end
28
+ end
29
+
30
+ describe "Text::Box#extensions" do
31
+ it "should be able to override default line wrapping" do
32
+ create_pdf
33
+ Prawn::Text::Box.extensions << TestWrapOverride
34
+ @pdf.text_box("hello world", {})
35
+ text = PDF::Inspector::Text.analyze(@pdf.render)
36
+ text.strings[0].should == "all your base are belong to us"
37
+ Prawn::Text::Box.extensions.delete(TestWrapOverride)
38
+ end
39
+ end
40
+
41
+ describe "Text::Box#render with :align => :justify" do
42
+ it "should draw the word spacing to the document" do
43
+ create_pdf
44
+ string = "hello world " * 10
45
+ options = { :document => @pdf, :align => :justify }
46
+ text_box = Prawn::Text::Box.new(string, options)
47
+ text_box.render
48
+ contents = PDF::Inspector::Text.analyze(@pdf.render)
49
+ contents.word_spacing[0].should.be > 0
50
+ end
51
+ end
52
+
53
+ describe "Text::Box#height without leading" do
54
+ it "should equal the sum of the height of each line" do
55
+ create_pdf
56
+ text = "Oh hai text rect.\nOh hai text rect."
57
+ options = { :document => @pdf }
58
+ text_box = Prawn::Text::Box.new(text, options)
59
+ text_box.render
60
+ text_box.height.should == @pdf.font.height * 2
61
+ end
62
+ end
63
+
64
+ describe "Text::Box#height with leading" do
65
+ it "should equal the sum of the height of each line" do
66
+ create_pdf
67
+ text = "Oh hai text rect.\nOh hai text rect."
68
+ leading = 12
69
+ options = { :document => @pdf, :leading => leading }
70
+ text_box = Prawn::Text::Box.new(text, options)
71
+ text_box.render
72
+ text_box.height.should == @pdf.font.height * 2 + leading
73
+ end
74
+ end
75
+
76
+ describe "Text::Box#valid_options" do
77
+ it "should return an array" do
78
+ create_pdf
79
+ text_box = Prawn::Text::Box.new("", :document => @pdf)
80
+ text_box.valid_options.should.be.kind_of(Array)
81
+ end
82
+ end
83
+
84
+ describe "Text::Box#render" do
85
+ it "should not fail if height is smaller than 1 line" do
86
+ create_pdf
87
+ @text = "Oh hai text rect. " * 10
88
+ @options = {
89
+ :height => @pdf.font.height * 0.5,
90
+ :document => @pdf
91
+ }
92
+ text_box = Prawn::Text::Box.new(@text, @options)
93
+ text_box.render
94
+ text_box.text.should == ""
95
+ end
96
+ it "should draw content to the page" do
97
+ create_pdf
98
+ @text = "Oh hai text rect. " * 10
99
+ @options = { :document => @pdf }
100
+ text_box = Prawn::Text::Box.new(@text, @options)
101
+ text_box.render
102
+ text = PDF::Inspector::Text.analyze(@pdf.render)
103
+ text.strings.should.not.be.empty
104
+ end
105
+ it "should not draw a transformation matrix" do
106
+ create_pdf
107
+ @text = "Oh hai text rect. " * 10
108
+ @options = { :document => @pdf }
109
+ text_box = Prawn::Text::Box.new(@text, @options)
110
+ text_box.render
111
+ matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
112
+ matrices.matrices.length.should == 0
113
+ end
114
+ end
115
+
116
+ describe "Text::Box#render(:single_line => true)" do
117
+ it "should draw only one line to the page" do
118
+ create_pdf
119
+ @text = "Oh hai text rect. " * 10
120
+ @options = { :document => @pdf,
121
+ :single_line => true }
122
+ text_box = Prawn::Text::Box.new(@text, @options)
123
+ text_box.render
124
+ text = PDF::Inspector::Text.analyze(@pdf.render)
125
+ text.strings.length.should == 1
126
+ end
127
+ end
128
+
129
+ describe "Text::Box#render(:dry_run => true)" do
130
+ it "should not draw any content to the page" do
131
+ create_pdf
132
+ @text = "Oh hai text rect. " * 10
133
+ @options = { :document => @pdf }
134
+ text_box = Prawn::Text::Box.new(@text, @options)
135
+ text_box.render(:dry_run => true)
136
+ text = PDF::Inspector::Text.analyze(@pdf.render)
137
+ text.strings.should.be.empty
138
+ end
139
+ it "subsequent calls to render should not raise an ArgumentError exception" do
140
+ create_pdf
141
+ @text = "™©"
142
+ @options = { :document => @pdf }
143
+ text_box = Prawn::Text::Box.new(@text, @options)
144
+ text_box.render(:dry_run => true)
145
+ lambda { text_box.render }.should.not.raise(ArgumentError)
146
+ end
147
+ end
148
+
149
+ describe "Text::Box#render with :rotate option of 30)" do
150
+ before(:each) do
151
+ create_pdf
152
+ rotate = 30
153
+ @x = 300
154
+ @y = 70
155
+ @width = 100
156
+ @height = 50
157
+ @cos = Math.cos(rotate * Math::PI / 180)
158
+ @sin = Math.sin(rotate * Math::PI / 180)
159
+ @text = "Oh hai text rect. " * 10
160
+ @options = { :document => @pdf,
161
+ :rotate => rotate,
162
+ :at => [@x, @y],
163
+ :width => @width,
164
+ :height => @height }
165
+ end
166
+ context ":rotate_around option of :center" do
167
+ it "should draw content to the page rotated about the center of the text" do
168
+ @options[:rotate_around] = :center
169
+ text_box = Prawn::Text::Box.new(@text, @options)
170
+ text_box.render
171
+
172
+ matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
173
+ x = @x + @width / 2
174
+ y = @y - @height / 2
175
+ x_prime = x * @cos - y * @sin
176
+ y_prime = x * @sin + y * @cos
177
+ matrices.matrices[0].should == [1, 0, 0, 1,
178
+ reduce_precision(x - x_prime),
179
+ reduce_precision(y - y_prime)]
180
+ matrices.matrices[1].should == [reduce_precision(@cos),
181
+ reduce_precision(@sin),
182
+ reduce_precision(-@sin),
183
+ reduce_precision(@cos), 0, 0]
184
+
185
+ text = PDF::Inspector::Text.analyze(@pdf.render)
186
+ text.strings.should.not.be.empty
187
+ end
188
+ end
189
+ context ":rotate_around option of :upper_left" do
190
+ it "should draw content to the page rotated about the upper left corner of the text" do
191
+ @options[:rotate_around] = :upper_left
192
+ text_box = Prawn::Text::Box.new(@text, @options)
193
+ text_box.render
194
+
195
+ matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
196
+ x = @x
197
+ y = @y
198
+ x_prime = x * @cos - y * @sin
199
+ y_prime = x * @sin + y * @cos
200
+ matrices.matrices[0].should == [1, 0, 0, 1,
201
+ reduce_precision(x - x_prime),
202
+ reduce_precision(y - y_prime)]
203
+ matrices.matrices[1].should == [reduce_precision(@cos),
204
+ reduce_precision(@sin),
205
+ reduce_precision(-@sin),
206
+ reduce_precision(@cos), 0, 0]
207
+
208
+ text = PDF::Inspector::Text.analyze(@pdf.render)
209
+ text.strings.should.not.be.empty
210
+ end
211
+ end
212
+ context "default :rotate_around" do
213
+ it "should draw content to the page rotated about the upper left corner of the text" do
214
+ text_box = Prawn::Text::Box.new(@text, @options)
215
+ text_box.render
216
+
217
+ matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
218
+ x = @x
219
+ y = @y
220
+ x_prime = x * @cos - y * @sin
221
+ y_prime = x * @sin + y * @cos
222
+ matrices.matrices[0].should == [1, 0, 0, 1,
223
+ reduce_precision(x - x_prime),
224
+ reduce_precision(y - y_prime)]
225
+ matrices.matrices[1].should == [reduce_precision(@cos),
226
+ reduce_precision(@sin),
227
+ reduce_precision(-@sin),
228
+ reduce_precision(@cos), 0, 0]
229
+
230
+ text = PDF::Inspector::Text.analyze(@pdf.render)
231
+ text.strings.should.not.be.empty
232
+ end
233
+ end
234
+ context ":rotate_around option of :upper_right" do
235
+ it "should draw content to the page rotated about the upper right corner of the text" do
236
+ @options[:rotate_around] = :upper_right
237
+ text_box = Prawn::Text::Box.new(@text, @options)
238
+ text_box.render
239
+
240
+ matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
241
+ x = @x + @width
242
+ y = @y
243
+ x_prime = x * @cos - y * @sin
244
+ y_prime = x * @sin + y * @cos
245
+ matrices.matrices[0].should == [1, 0, 0, 1,
246
+ reduce_precision(x - x_prime),
247
+ reduce_precision(y - y_prime)]
248
+ matrices.matrices[1].should == [reduce_precision(@cos),
249
+ reduce_precision(@sin),
250
+ reduce_precision(-@sin),
251
+ reduce_precision(@cos), 0, 0]
252
+
253
+ text = PDF::Inspector::Text.analyze(@pdf.render)
254
+ text.strings.should.not.be.empty
255
+ end
256
+ end
257
+ context ":rotate_around option of :lower_right" do
258
+ it "should draw content to the page rotated about the lower right corner of the text" do
259
+ @options[:rotate_around] = :lower_right
260
+ text_box = Prawn::Text::Box.new(@text, @options)
261
+ text_box.render
262
+
263
+ matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
264
+ x = @x + @width
265
+ y = @y - @height
266
+ x_prime = x * @cos - y * @sin
267
+ y_prime = x * @sin + y * @cos
268
+ matrices.matrices[0].should == [1, 0, 0, 1,
269
+ reduce_precision(x - x_prime),
270
+ reduce_precision(y - y_prime)]
271
+ matrices.matrices[1].should == [reduce_precision(@cos),
272
+ reduce_precision(@sin),
273
+ reduce_precision(-@sin),
274
+ reduce_precision(@cos), 0, 0]
275
+
276
+ text = PDF::Inspector::Text.analyze(@pdf.render)
277
+ text.strings.should.not.be.empty
278
+ end
279
+ end
280
+ context ":rotate_around option of :lower_left" do
281
+ it "should draw content to the page rotated about the lower left corner of the text" do
282
+ @options[:rotate_around] = :lower_left
283
+ text_box = Prawn::Text::Box.new(@text, @options)
284
+ text_box.render
285
+
286
+ matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
287
+ x = @x
288
+ y = @y - @height
289
+ x_prime = x * @cos - y * @sin
290
+ y_prime = x * @sin + y * @cos
291
+ matrices.matrices[0].should == [1, 0, 0, 1,
292
+ reduce_precision(x - x_prime),
293
+ reduce_precision(y - y_prime)]
294
+ matrices.matrices[1].should == [reduce_precision(@cos),
295
+ reduce_precision(@sin),
296
+ reduce_precision(-@sin),
297
+ reduce_precision(@cos), 0, 0]
298
+
299
+ text = PDF::Inspector::Text.analyze(@pdf.render)
300
+ text.strings.should.not.be.empty
301
+ end
302
+ end
303
+ end
304
+
305
+ describe "Text::Box default height" do
306
+ it "should be the height from the bottom bound to document.y" do
307
+ create_pdf
308
+ target_height = @pdf.y - @pdf.bounds.bottom
309
+ @text = "Oh hai\n" * 60
310
+ @options = { :document => @pdf }
311
+ text_box = Prawn::Text::Box.new(@text, @options)
312
+ text_box.render
313
+ text_box.height.should.be.close(target_height, @pdf.font.height)
314
+ end
315
+ end
316
+
317
+ describe "Text::Box default at" do
318
+ it "should be the left corner of the bounds, and the current document.y" do
319
+ create_pdf
320
+ target_at = [@pdf.bounds.left, @pdf.y]
321
+ @text = "Oh hai text rect. " * 100
322
+ @options = { :document => @pdf }
323
+ text_box = Prawn::Text::Box.new(@text, @options)
324
+ text_box.render
325
+ text_box.at.should == target_at
326
+ end
327
+ end
328
+
329
+ describe "Text::Box with text than can fit in the box" do
330
+ before(:each) do
331
+ create_pdf
332
+ @text = "Oh hai text rect. " * 10
333
+ @options = {
334
+ :width => 162.0,
335
+ :height => 162.0,
336
+ :document => @pdf
337
+ }
338
+ end
339
+
340
+ it "printed text should match requested text, except for trailing or leading white space and that spaces may be replaced by newlines" do
341
+ text_box = Prawn::Text::Box.new(@text, @options)
342
+ text_box.render
343
+ text_box.text.gsub("\n", " ").should == @text.strip
344
+ end
345
+
346
+ it "render should return an empty string because no text remains unprinted" do
347
+ text_box = Prawn::Text::Box.new(@text, @options)
348
+ text_box.render.should == ""
349
+ end
350
+
351
+ it "should be truncated when the leading is set high enough to prevent all the lines from being printed" do
352
+ @options[:leading] = 40
353
+ text_box = Prawn::Text::Box.new(@text, @options)
354
+ text_box.render
355
+ text_box.text.gsub("\n", " ").should.not == @text.strip
356
+ end
357
+ end
358
+
359
+ describe "Text::Box with text than can fit in the box with :ellipses overflow and :valign => :bottom" do
360
+ it "should not print ellipses" do
361
+ create_pdf
362
+ @text = "Oh hai text rect. " * 10
363
+ @options = {
364
+ :width => 162.0,
365
+ :height => 162.0,
366
+ :overflow => :ellipses,
367
+ :valign => :bottom,
368
+ :document => @pdf
369
+ }
370
+ @text_box = Prawn::Text::Box.new(@text, @options)
371
+ @text_box.render
372
+ @text_box.text.should.not =~ /\.\.\./
373
+ end
374
+ end
375
+
376
+
377
+
378
+ describe "Text::Box printing UTF-8 string with higher bit characters" do
379
+ before(:each) do
380
+ create_pdf
381
+ @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
+ file = "#{Prawn::BASEDIR}/data/fonts/Action Man.dfont"
390
+ @pdf.font_families["Action Man"] = {
391
+ :normal => { :file => file, :font => "ActionMan" },
392
+ :italic => { :file => file, :font => "ActionMan-Italic" },
393
+ :bold => { :file => file, :font => "ActionMan-Bold" },
394
+ :bold_italic => { :file => file, :font => "ActionMan-BoldItalic" }
395
+ }
396
+ @text_box = Prawn::Text::Box.new(@text, options)
397
+ end
398
+ describe "when using a TTF font" do
399
+ it "unprinted text should be in UTF-8 encoding" do
400
+ @pdf.font("Action Man")
401
+ remaining_text = @text_box.render
402
+ remaining_text.should == @text
403
+ end
404
+ it "subsequent calls to Text::Box need not include the" +
405
+ " :skip_encoding => true option" do
406
+ @pdf.font("Action Man")
407
+ remaining_text = @text_box.render
408
+ lambda {
409
+ @pdf.text_box(remaining_text, :document => @pdf)
410
+ }.should.not.raise(ArgumentError)
411
+ end
412
+ end
413
+ describe "when using an AFM font" do
414
+ it "unprinted text should be in WinAnsi encoding" do
415
+ remaining_text = @text_box.render
416
+ remaining_text.should == @pdf.font.normalize_encoding(@text)
417
+ end
418
+ it "subsequent calls to Text::Box must include the" +
419
+ " :skip_encoding => true option" do
420
+ remaining_text = @text_box.render
421
+ lambda {
422
+ @pdf.text_box(remaining_text, :document => @pdf)
423
+ }.should.raise(ArgumentError)
424
+ lambda {
425
+ @pdf.text_box(remaining_text, :skip_encoding => true,
426
+ :document => @pdf)
427
+ }.should.not.raise(ArgumentError)
428
+ end
429
+ end
430
+ end
431
+
432
+
433
+ describe "Text::Box with more text than can fit in the box" do
434
+ before(:each) do
435
+ create_pdf
436
+ @text = "Oh hai text rect. " * 30
437
+ @bounding_height = 162.0
438
+ @options = {
439
+ :width => 162.0,
440
+ :height => @bounding_height,
441
+ :document => @pdf
442
+ }
443
+ end
444
+
445
+ context "truncated overflow" do
446
+ before(:each) do
447
+ @options[:overflow] = :truncate
448
+ @text_box = Prawn::Text::Box.new(@text, @options)
449
+ end
450
+ it "should not display ellipses" do
451
+ @text_box.render
452
+ @text_box.text.should.not =~ /\.\.\./
453
+ end
454
+ it "should be truncated" do
455
+ @text_box.render
456
+ @text_box.text.gsub("\n", " ").should.not == @text.strip
457
+ end
458
+ it "render should not return an empty string because some text remains 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
+ @bounding_height.should.be.close(@text_box.height, @pdf.font.height)
468
+ end
469
+ context "with :rotate option" do
470
+ it "unrendered text should be the same as when not rotated" do
471
+ remaining_text = @text_box.render
472
+
473
+ rotate = 30
474
+ x = 300
475
+ y = 70
476
+ width = @options[:width]
477
+ height = @options[:height]
478
+ @options[:document] = @pdf
479
+ @options[:rotate] = rotate
480
+ @options[:at] = [x, y]
481
+ rotated_text_box = Prawn::Text::Box.new(@text, @options)
482
+ rotated_text_box.render.should == remaining_text
483
+ end
484
+ end
485
+ end
486
+
487
+ context "ellipses overflow" do
488
+ before(:each) do
489
+ @options[:overflow] = :ellipses
490
+ @text_box = Prawn::Text::Box.new(@text, @options)
491
+ end
492
+ it "should display ellipses" do
493
+ @text_box.render
494
+ @text_box.text.should =~ /\.\.\./
495
+ end
496
+ it "render should not return an empty string because some text remains unprinted" do
497
+ @text_box.render.should.not == ""
498
+ end
499
+ end
500
+
501
+ context "expand overflow" do
502
+ before(:each) do
503
+ @options[:overflow] = :expand
504
+ @text_box = Prawn::Text::Box.new(@text, @options)
505
+ end
506
+ it "height should expand to encompass all the text (but not exceed the height of the page)" do
507
+ @text_box.render
508
+ @text_box.height.should > @bounding_height
509
+ end
510
+ it "should display the entire string (as long as there was space remaining on the page to print all the text)" do
511
+ @text_box.render
512
+ @text_box.text.gsub("\n", " ").should == @text.strip
513
+ end
514
+ it "render should return an empty string because no text remains unprinted(as long as there was space remaining on the page to print all the text)" do
515
+ @text_box.render.should == ""
516
+ end
517
+ end
518
+
519
+ context "shrink_to_fit overflow" do
520
+ before(:each) do
521
+ @options[:overflow] = :shrink_to_fit
522
+ @options[:min_font_size] = 2
523
+ @text_box = Prawn::Text::Box.new(@text, @options)
524
+ end
525
+ it "should display the entire text" do
526
+ @text_box.render
527
+ @text_box.text.gsub("\n", " ").should == @text.strip
528
+ end
529
+ it "render should return an empty string because no text remains unprinted" do
530
+ @text_box.render.should == ""
531
+ end
532
+ end
533
+ end
534
+
535
+ describe "Text::Box with a solid block of Chinese characters" do
536
+ it "printed text should match requested text, except for newlines" do
537
+ create_pdf
538
+ @text = "写中国字" * 10
539
+ @options = {
540
+ :width => 162.0,
541
+ :height => 162.0,
542
+ :document => @pdf
543
+ }
544
+ @pdf.font "#{Prawn::BASEDIR}/data/fonts/gkai00mp.ttf"
545
+ @options[:overflow] = :truncate
546
+ text_box = Prawn::Text::Box.new(@text, @options)
547
+ text_box.render
548
+ text_box.text.gsub("\n", "").should == @text.strip
549
+ end
550
+ end
551
+
552
+
553
+ describe "drawing bounding boxes" do
554
+
555
+ before(:each) { create_pdf }
556
+
557
+ it "should restore the margin box when bounding box exits" do
558
+ margin_box = @pdf.bounds
559
+
560
+ @pdf.text_box "Oh hai text box. " * 11, :height => @pdf.font.height * 10
561
+
562
+ @pdf.bounds.should == margin_box
563
+
564
+ end
565
+
566
+ end
567
+
568
+
569
+ describe "Text::Box#render with :character_spacing option" do
570
+ it "should draw the character spacing to the document" do
571
+ create_pdf
572
+ string = "hello world"
573
+ options = { :document => @pdf, :character_spacing => 10 }
574
+ text_box = Prawn::Text::Box.new(string, options)
575
+ text_box.render
576
+ contents = PDF::Inspector::Text.analyze(@pdf.render)
577
+ contents.character_spacing[0].should == 10
578
+ end
579
+ it "should take character spacing into account when wrapping" do
580
+ create_pdf
581
+ @pdf.font "Courier"
582
+ text_box = Prawn::Text::Box.new("hello world",
583
+ :width => 100,
584
+ :overflow => :expand,
585
+ :character_spacing => 10,
586
+ :document => @pdf)
587
+ text_box.render
588
+ text_box.text.should == "hello\nworld"
589
+ end
590
+ end
591
+
592
+ describe "Text::Box wrapping" do
593
+ before(:each) do
594
+ create_pdf
595
+ end
596
+
597
+ it "should wrap text" do
598
+ text = "Please wrap this text about HERE. More text that should be wrapped"
599
+ expect = "Please wrap this text about\nHERE. More text that should be\nwrapped"
600
+
601
+ @pdf.font "Courier"
602
+ text_box = Prawn::Text::Box.new(text,
603
+ :width => 220,
604
+ :overflow => :expand,
605
+ :document => @pdf)
606
+ text_box.render
607
+ text_box.text.should == expect
608
+ end
609
+
610
+ # white space was being stripped after the entire line was generated, meaning
611
+ # that leading white space characters reduced the amount of space on the line
612
+ # for other characters, so wrapping "hello hello" resulted in
613
+ # "hello\n\nhello", rather than "hello\nhello"
614
+ #
615
+ it "white space at beginning of line should not be taken into account when" +
616
+ " computing line width" do
617
+ text = "hello hello"
618
+ expect = "hello\nhello"
619
+
620
+ @pdf.font "Courier"
621
+ text_box = Prawn::Text::Box.new(text,
622
+ :width => 40,
623
+ :overflow => :expand,
624
+ :document => @pdf)
625
+ text_box.render
626
+ text_box.text.should == expect
627
+ end
628
+
629
+ it "should respect end of line when wrapping text" do
630
+ text = "Please wrap only before\nTHIS word. Don't wrap this"
631
+ expect = text
632
+
633
+ @pdf.font "Courier"
634
+ text_box = Prawn::Text::Box.new(text,
635
+ :width => 220,
636
+ :overflow => :expand,
637
+ :document => @pdf)
638
+ text_box.render
639
+ text_box.text.should == expect
640
+ end
641
+
642
+ it "should respect multiple newlines when wrapping text" do
643
+ text = "Please wrap only before THIS\n\nword. Don't wrap this"
644
+ expect= "Please wrap only before\nTHIS\n\nword. Don't wrap this"
645
+
646
+ @pdf.font "Courier"
647
+ text_box = Prawn::Text::Box.new(text,
648
+ :width => 200,
649
+ :overflow => :expand,
650
+ :document => @pdf)
651
+ text_box.render
652
+ text_box.text.should == expect
653
+ end
654
+
655
+ it "should respect multiple newlines when wrapping text when those newlines coincide with a line break" do
656
+ text = "Please wrap only before\n\nTHIS word. Don't wrap this"
657
+ expect = text
658
+
659
+ @pdf.font "Courier"
660
+ text_box = Prawn::Text::Box.new(text,
661
+ :width => 220,
662
+ :overflow => :expand,
663
+ :document => @pdf)
664
+ text_box.render
665
+ text_box.text.should == expect
666
+ end
667
+
668
+ it "should respect initial newlines" do
669
+ text = "\nThis should be on line 2"
670
+ expect = text
671
+
672
+ @pdf.font "Courier"
673
+ text_box = Prawn::Text::Box.new(text,
674
+ :width => 220,
675
+ :overflow => :expand,
676
+ :document => @pdf)
677
+ text_box.render
678
+ text_box.text.should == expect
679
+ end
680
+
681
+ it "should wrap lines comprised of a single word of the bounds when wrapping text" do
682
+ text = "You_can_wrap_this_text_HERE"
683
+ expect = "You_can_wrap_this_text_HE\nRE"
684
+
685
+ @pdf.font "Courier"
686
+ text_box = Prawn::Text::Box.new(text,
687
+ :width => 180,
688
+ :overflow => :expand,
689
+ :document => @pdf)
690
+ text_box.render
691
+ text_box.text.should == expect
692
+ end
693
+
694
+ it "should wrap lines comprised of a single word of the bounds when wrapping text" do
695
+ text = "©" * 30
696
+
697
+ @pdf.font "Courier"
698
+ text_box = Prawn::Text::Box.new(text, :width => 180,
699
+ :overflow => :expand,
700
+ :document => @pdf)
701
+
702
+ text_box.render
703
+
704
+ expected = "©" * 25 + "\n" + "©" * 5
705
+ @pdf.font.normalize_encoding!(expected)
706
+
707
+ text_box.text.should == expected
708
+ end
709
+
710
+ it "should wrap non-unicode strings using single-byte word-wrapping" do
711
+ text = "continúa esforzandote " * 5
712
+ text_box = Prawn::Text::Box.new(text, :width => 180,
713
+ :document => @pdf)
714
+ text_box.render
715
+ results_with_accent = text_box.text
716
+
717
+ text = "continua esforzandote " * 5
718
+ text_box = Prawn::Text::Box.new(text, :width => 180,
719
+ :document => @pdf)
720
+ text_box.render
721
+ results_without_accent = text_box.text
722
+
723
+ results_with_accent.first_line.length.should == results_without_accent.first_line.length
724
+ end
725
+
726
+ end
727
+
728
+ def reduce_precision(float)
729
+ ("%.5f" % float).to_f
730
+ end
731
+
732
+ module TestWrapOverride
733
+ def wrap(string)
734
+ @text = nil
735
+ @line_height = @document.font.height
736
+ @descender = @document.font.descender
737
+ @ascender = @document.font.ascender
738
+ @baseline_y = -@ascender
739
+ draw_line("all your base are belong to us")
740
+ ""
741
+ end
742
+ end