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,211 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
+
5
+ describe "Text::Formatted::Fragment#word_spacing=" do
6
+ before(:each) do
7
+ create_pdf
8
+ format_state = { :styles => [:bold, :italic],
9
+ :color => nil,
10
+ :link => nil,
11
+ :anchor => nil,
12
+ :font => nil,
13
+ :size => nil }
14
+ @fragment = Prawn::Text::Formatted::Fragment.new("hello world",
15
+ format_state,
16
+ @pdf)
17
+ @fragment.width = 100
18
+ @fragment.left = 50
19
+ @fragment.baseline = 200
20
+ @fragment.line_height = 27
21
+ @fragment.descender = 7
22
+ @fragment.ascender = 17
23
+ @fragment.word_spacing = 10
24
+ end
25
+
26
+ it "should account for word_spacing in #width" do
27
+ @fragment.width.should == 110
28
+ end
29
+ it "should account for word_spacing in #bounding_box" do
30
+ target_box = [50, 193, 160, 217]
31
+ @fragment.bounding_box.should == target_box
32
+ end
33
+ it "should account for word_spacing in #absolute_bounding_box" do
34
+ target_box = [50, 193, 160, 217]
35
+ target_box[0] += @pdf.bounds.absolute_left
36
+ target_box[1] += @pdf.bounds.absolute_bottom
37
+ target_box[2] += @pdf.bounds.absolute_left
38
+ target_box[3] += @pdf.bounds.absolute_bottom
39
+ @fragment.absolute_bounding_box.should == target_box
40
+ end
41
+ it "should account for word_spacing in #underline_points" do
42
+ y = 198.75
43
+ target_points = [[50, y], [160, y]]
44
+ @fragment.underline_points.should == target_points
45
+ end
46
+ it "should account for word_spacing in #strikethrough_points" do
47
+ y = 200 + @fragment.ascender * 0.3
48
+ target_points = [[50, y], [160, y]]
49
+ @fragment.strikethrough_points.should == target_points
50
+ end
51
+ end
52
+
53
+ describe "Text::Formatted::Fragment" do
54
+ before(:each) do
55
+ create_pdf
56
+ format_state = { :styles => [:bold, :italic],
57
+ :color => nil,
58
+ :link => nil,
59
+ :anchor => nil,
60
+ :font => nil,
61
+ :size => nil }
62
+ @fragment = Prawn::Text::Formatted::Fragment.new("hello world",
63
+ format_state,
64
+ @pdf)
65
+ @fragment.width = 100
66
+ @fragment.left = 50
67
+ @fragment.baseline = 200
68
+ @fragment.line_height = 27
69
+ @fragment.descender = 7
70
+ @fragment.ascender = 17
71
+ end
72
+
73
+ describe "#width" do
74
+ it "should return the width" do
75
+ @fragment.width.should == 100
76
+ end
77
+ end
78
+
79
+ describe "#styles" do
80
+ it "should return the styles array" do
81
+ @fragment.styles.should == [:bold, :italic]
82
+ end
83
+ it "should never return nil" do
84
+ format_state = { :styles => nil,
85
+ :color => nil,
86
+ :link => nil,
87
+ :anchor => nil,
88
+ :font => nil,
89
+ :size => nil }
90
+ fragment = Prawn::Text::Formatted::Fragment.new("hello world",
91
+ format_state,
92
+ @pdf)
93
+ fragment.styles.should == []
94
+ end
95
+ end
96
+
97
+ describe "#line_height" do
98
+ it "should return the line_height" do
99
+ @fragment.line_height.should == 27
100
+ end
101
+ end
102
+
103
+ describe "#ascender" do
104
+ it "should return the ascender" do
105
+ @fragment.ascender.should == 17
106
+ end
107
+ end
108
+
109
+ describe "#descender" do
110
+ it "should return the descender" do
111
+ @fragment.descender.should == 7
112
+ end
113
+ end
114
+
115
+ describe "#y_offset" do
116
+ it "should be zero" do
117
+ @fragment.y_offset.should == 0
118
+ end
119
+ end
120
+
121
+ describe "#bounding_box" do
122
+ it "should return the bounding box surrounding the fragment" do
123
+ target_box = [50, 193, 150, 217]
124
+ @fragment.bounding_box.should == target_box
125
+ end
126
+ end
127
+
128
+ describe "#absolute_bounding_box" do
129
+ it "should return the bounding box surrounding the fragment" +
130
+ " in absolute coordinates" do
131
+ target_box = [50, 193, 150, 217]
132
+ target_box[0] += @pdf.bounds.absolute_left
133
+ target_box[1] += @pdf.bounds.absolute_bottom
134
+ target_box[2] += @pdf.bounds.absolute_left
135
+ target_box[3] += @pdf.bounds.absolute_bottom
136
+ @fragment.absolute_bounding_box.should == target_box
137
+ end
138
+ end
139
+
140
+ describe "#underline_points" do
141
+ it "should define a line under the fragment" do
142
+ y = 198.75
143
+ target_points = [[50, y], [150, y]]
144
+ @fragment.underline_points.should == target_points
145
+ end
146
+ end
147
+
148
+ describe "#strikethrough_points" do
149
+ it "should define a line through the fragment" do
150
+ y = 200 + @fragment.ascender * 0.3
151
+ target_points = [[50, y], [150, y]]
152
+ @fragment.strikethrough_points.should == target_points
153
+ end
154
+ end
155
+ end
156
+
157
+ describe "Text::Formatted::Fragment that is a subscript" do
158
+ before(:each) do
159
+ create_pdf
160
+ format_state = { :styles => [:subscript],
161
+ :color => nil,
162
+ :link => nil,
163
+ :anchor => nil,
164
+ :font => nil,
165
+ :size => nil }
166
+ @fragment = Prawn::Text::Formatted::Fragment.new("hello world",
167
+ format_state,
168
+ @pdf)
169
+ @fragment.line_height = 27
170
+ @fragment.descender = 7
171
+ @fragment.ascender = 17
172
+ end
173
+ describe "#subscript?" do
174
+ it "should be true" do
175
+ @fragment.should.be.subscript
176
+ end
177
+ end
178
+ describe "#y_offset" do
179
+ it "should return a negative value" do
180
+ @fragment.y_offset.should.be < 0
181
+ end
182
+ end
183
+ end
184
+
185
+ describe "Text::Formatted::Fragment that is a superscript" do
186
+ before(:each) do
187
+ create_pdf
188
+ format_state = { :styles => [:superscript],
189
+ :color => nil,
190
+ :link => nil,
191
+ :anchor => nil,
192
+ :font => nil,
193
+ :size => nil }
194
+ @fragment = Prawn::Text::Formatted::Fragment.new("hello world",
195
+ format_state,
196
+ @pdf)
197
+ @fragment.line_height = 27
198
+ @fragment.descender = 7
199
+ @fragment.ascender = 17
200
+ end
201
+ describe "#superscript?" do
202
+ it "should be true" do
203
+ @fragment.should.be.superscript
204
+ end
205
+ end
206
+ describe "#y_offset" do
207
+ it "should return a positive value" do
208
+ @fragment.y_offset.should.be > 0
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,446 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
+
5
+ describe "When drawing a line" do
6
+
7
+ before(:each) { create_pdf }
8
+
9
+ it "should draw a line from (100,600) to (100,500)" do
10
+ @pdf.line([100,600],[100,500])
11
+
12
+ line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
13
+
14
+ line_drawing.points.should == [[100,600],[100,500]]
15
+ end
16
+
17
+ it "should draw two lines at (100,600) to (100,500) " +
18
+ "and (75,100) to (50,125)" do
19
+ @pdf.line(100,600,100,500)
20
+ @pdf.line(75,100,50,125)
21
+
22
+ line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
23
+
24
+ line_drawing.points.should ==
25
+ [[100.0, 600.0], [100.0, 500.0], [75.0, 100.0], [50.0, 125.0]]
26
+ end
27
+
28
+ it "should properly set line width via line_width=" do
29
+ @pdf.line_width = 10
30
+ line = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
31
+ line.widths.first.should == 10
32
+ end
33
+
34
+ it "should properly set line width via line_width(width)" do
35
+ @pdf.line_width(10)
36
+ line = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
37
+ line.widths.first.should == 10
38
+ end
39
+
40
+ it "should carry the current line width settings over to new pages" do
41
+ @pdf.line_width(10)
42
+ @pdf.start_new_page
43
+ line = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
44
+ line.widths.length.should == 2
45
+ line.widths[1].should == 10
46
+ end
47
+
48
+ describe "(Horizontally)" do
49
+ it "should draw from [x1,pdf.y],[x2,pdf.y]" do
50
+ @pdf.horizontal_line(100,150)
51
+ @line = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
52
+ @line.points.should == [[100.0 + @pdf.bounds.absolute_left, @pdf.y],
53
+ [150.0 + @pdf.bounds.absolute_left, @pdf.y]]
54
+ end
55
+
56
+ it "should draw a line from (200, 250) to (300, 250)" do
57
+ @pdf.horizontal_line(200,300,:at => 250)
58
+ line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
59
+ line_drawing.points.should == [[200,250],[300,250]]
60
+ end
61
+ end
62
+
63
+ describe "(Vertically)" do
64
+ it "should draw a line from (350, 300) to (350, 400)" do
65
+ @pdf.vertical_line(300,400,:at => 350)
66
+ line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
67
+ line_drawing.points.should == [[350,300],[350,400]]
68
+ end
69
+ it "should require a y coordinate" do
70
+ lambda { @pdf.vertical_line(400,500) }.
71
+ should.raise(ArgumentError)
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ describe "When drawing a polygon" do
78
+
79
+ before(:each) { create_pdf }
80
+
81
+ it "should draw each line passed to polygon()" do
82
+ @pdf.polygon([100,500],[100,400],[200,400])
83
+
84
+ line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
85
+ line_drawing.points.should == [[100,500],[100,400],[200,400],[100,500]]
86
+ end
87
+
88
+ end
89
+
90
+ describe "When drawing a rectangle" do
91
+
92
+ before(:each) { create_pdf }
93
+
94
+ it "should use a point, width, and height for coords" do
95
+ @pdf.rectangle [200,200], 50, 100
96
+
97
+ rectangles = PDF::Inspector::Graphics::Rectangle.
98
+ analyze(@pdf.render).rectangles
99
+ # PDF uses bottom left corner
100
+ rectangles[0][:point].should == [200,100]
101
+ rectangles[0][:width].should == 50
102
+ rectangles[0][:height].should == 100
103
+
104
+ end
105
+
106
+ end
107
+
108
+ describe "When drawing a curve" do
109
+
110
+ before(:each) { create_pdf }
111
+
112
+ it "should draw a bezier curve from 50,50 to 100,100" do
113
+ @pdf.move_to [50,50]
114
+ @pdf.curve_to [100,100],:bounds => [[20,90], [90,70]]
115
+ curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
116
+ curve.coords.should == [50.0, 50.0, 20.0, 90.0, 90.0, 70.0, 100.0, 100.0]
117
+ end
118
+
119
+ it "should draw a bezier curve from 100,100 to 50,50" do
120
+ @pdf.curve [100,100], [50,50], :bounds => [[20,90], [90,75]]
121
+ curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
122
+ curve.coords.should == [100.0, 100.0, 20.0, 90.0, 90.0, 75.0, 50.0, 50.0]
123
+ end
124
+
125
+
126
+ end
127
+
128
+ describe "When drawing a rounded rectangle" do
129
+ before(:each) do
130
+ create_pdf
131
+ @pdf.rounded_rectangle([50, 550], 50, 100, 10)
132
+ curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
133
+ curve_points = []
134
+ curve.coords.each_slice(2) {|p| curve_points << p}
135
+ @original_point = curve_points.shift
136
+ curves = []
137
+ curve_points.each_slice(3) {|c| curves << c}
138
+ line_points = PDF::Inspector::Graphics::Line.analyze(@pdf.render).points
139
+ line_points.shift
140
+ @all_coords = []
141
+ line_points.zip(curves).flatten.each_slice(2) {|p| @all_coords << p }
142
+ @all_coords.unshift @original_point
143
+ end
144
+
145
+ it "should draw a rectangle by connecting lines with rounded bezier curves" do
146
+ @all_coords.should == [[60.0, 550.0],[90.0, 550.0], [95.523, 550.0], [100.0, 545.523], [100.0, 540.0],
147
+ [100.0, 460.0], [100.0, 454.477], [95.523, 450.0], [90.0, 450.0],
148
+ [60.0, 450.0], [54.477, 450.0], [50.0, 454.477], [50.0, 460.0],
149
+ [50.0, 540.0], [50.0, 545.523], [54.477, 550.0], [60.0, 550.0]]
150
+ end
151
+
152
+ it "should start and end with the same point" do
153
+ @original_point.should == @all_coords.last
154
+ end
155
+
156
+
157
+ end
158
+
159
+ describe "When drawing an ellipse" do
160
+ before(:each) do
161
+ create_pdf
162
+ @pdf.ellipse_at [100,100], 25, 50
163
+ @curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
164
+ end
165
+
166
+ it "should move the pointer to the center of the ellipse after drawing" do
167
+ @curve.coords[-2..-1].should == [100,100]
168
+ end
169
+
170
+ end
171
+
172
+ describe "When drawing a circle" do
173
+ before(:each) do
174
+ create_pdf
175
+ @pdf.circle_at [100,100], :radius => 25
176
+ @pdf.ellipse_at [100,100], 25, 25
177
+ @curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
178
+ end
179
+
180
+ it "should stroke the same path as the equivalent ellipse" do
181
+ middle = @curve.coords.length / 2
182
+ @curve.coords[0...middle].should == @curve.coords[middle..-1]
183
+ end
184
+ end
185
+
186
+ describe "When setting colors" do
187
+
188
+ before(:each) { create_pdf }
189
+
190
+ it "should set stroke colors" do
191
+ @pdf.stroke_color "ffcccc"
192
+ colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
193
+ # 100% red, 80% green, 80% blue
194
+ colors.stroke_color.should == [1.0, 0.8, 0.8]
195
+ end
196
+
197
+ it "should set fill colors" do
198
+ @pdf.fill_color "ccff00"
199
+ colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
200
+ # 80% red, 100% green, 0% blue
201
+ colors.fill_color.should == [0.8,1.0,0]
202
+ end
203
+
204
+ it "should reset the colors on each new page if they have been defined" do
205
+ @pdf.fill_color "ccff00"
206
+ colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
207
+
208
+ colors.fill_color_count.should == 2
209
+ colors.stroke_color_count.should == 1
210
+ @pdf.start_new_page
211
+ @pdf.stroke_color "ff00cc"
212
+
213
+ colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
214
+ colors.fill_color_count.should == 3
215
+ colors.stroke_color_count.should == 3
216
+
217
+ @pdf.start_new_page
218
+ colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
219
+ colors.fill_color_count.should == 4
220
+ colors.stroke_color_count.should == 4
221
+
222
+ colors.fill_color.should == [0.8,1.0,0.0]
223
+ colors.stroke_color.should == [1.0,0.0,0.8]
224
+ end
225
+
226
+ end
227
+
228
+ describe "When using painting shortcuts" do
229
+ before(:each) { create_pdf }
230
+
231
+ it "should convert stroke_some_method(args) into some_method(args); stroke" do
232
+ @pdf.expects(:line_to).with([100,100])
233
+ @pdf.expects(:stroke)
234
+
235
+ @pdf.stroke_line_to [100,100]
236
+ end
237
+
238
+ it "should convert fill_some_method(args) into some_method(args); fill" do
239
+ @pdf.expects(:line_to).with([100,100])
240
+ @pdf.expects(:fill)
241
+
242
+ @pdf.fill_line_to [100,100]
243
+ end
244
+
245
+ it "should not break method_missing" do
246
+ lambda { @pdf.i_have_a_pretty_girlfriend_named_jia }.
247
+ should.raise(NoMethodError)
248
+ end
249
+ end
250
+
251
+ describe "When using graphics states" do
252
+ before(:each) { create_pdf }
253
+
254
+ it "should add the right content on save_graphics_state" do
255
+ @pdf.expects(:add_content).with('q')
256
+
257
+ @pdf.save_graphics_state
258
+ end
259
+
260
+ it "should add the right content on restore_graphics_state" do
261
+ @pdf.expects(:add_content).with('Q')
262
+
263
+ @pdf.restore_graphics_state
264
+ end
265
+
266
+ it "should save and restore when save_graphics_state is used with a block" do
267
+ state = sequence "state"
268
+ @pdf.expects(:add_content).with('q').in_sequence(state)
269
+ @pdf.expects(:foo).in_sequence(state)
270
+ @pdf.expects(:add_content).with('Q').in_sequence(state)
271
+
272
+ @pdf.save_graphics_state do
273
+ @pdf.foo
274
+ end
275
+ end
276
+ end
277
+
278
+ describe "When using transformation matrix" do
279
+ before(:each) { create_pdf }
280
+
281
+ # Note: The (approximate) number of significant decimal digits of precision in fractional
282
+ # part is 5 (PDF Reference, Third Edition, p. 706)
283
+
284
+ it "should send the right content on transformation_matrix" do
285
+ @pdf.expects(:add_content).with('1.00000 0.00000 0.12346 -1.00000 5.50000 20.00000 cm')
286
+ @pdf.transformation_matrix 1, 0, 0.123456789, -1.0, 5.5, 20
287
+ end
288
+
289
+ it "should use fixed digits with very small number" do
290
+ values = Array.new(6, 0.000000000001)
291
+ string = Array.new(6, "0.00000").join " "
292
+ @pdf.expects(:add_content).with("#{string} cm")
293
+ @pdf.transformation_matrix *values
294
+ end
295
+
296
+ it "should be received by the inspector" do
297
+ @pdf.transformation_matrix 1, 0, 0, -1, 5.5, 20
298
+ matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
299
+ matrices.matrices.should == [[1, 0, 0, -1, 5.5, 20]]
300
+ end
301
+
302
+ it "should save the graphics state inside the given block" do
303
+ values = Array.new(6, 0.000000000001)
304
+ string = Array.new(6, "0.00000").join " "
305
+ process = sequence "process"
306
+
307
+ @pdf.expects(:save_graphics_state).with().in_sequence(process)
308
+ @pdf.expects(:add_content).with("#{string} cm").in_sequence(process)
309
+ @pdf.expects(:do_something).with().in_sequence(process)
310
+ @pdf.expects(:restore_graphics_state).with().in_sequence(process)
311
+ @pdf.transformation_matrix(*values) do
312
+ @pdf.do_something
313
+ end
314
+ end
315
+
316
+ end
317
+
318
+ describe "When using transformations shortcuts" do
319
+ before(:each) do
320
+ create_pdf
321
+ @x, @y = 12, 54.32
322
+ @angle = 12.32
323
+ @cos = Math.cos(@angle * Math::PI / 180)
324
+ @sin = Math.sin(@angle * Math::PI / 180)
325
+ @factor = 0.12
326
+ end
327
+
328
+ describe "#rotate" do
329
+ it "should rotate" do
330
+ @pdf.expects(:transformation_matrix).with(@cos, @sin, -@sin, @cos, 0, 0)
331
+ @pdf.rotate(@angle)
332
+ end
333
+ end
334
+
335
+ describe "#rotate with :origin option" do
336
+ it "should rotate around the origin" do
337
+ x_prime = @x * @cos - @y * @sin
338
+ y_prime = @x * @sin + @y * @cos
339
+
340
+ @pdf.rotate(@angle, :origin => [@x, @y]) { @pdf.text('hello world') }
341
+
342
+ matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
343
+ matrices.matrices[0].should == [1, 0, 0, 1,
344
+ reduce_precision(@x - x_prime),
345
+ reduce_precision(@y - y_prime)]
346
+ matrices.matrices[1].should == [reduce_precision(@cos),
347
+ reduce_precision(@sin),
348
+ reduce_precision(-@sin),
349
+ reduce_precision(@cos), 0, 0]
350
+ end
351
+
352
+ it "should rotate around the origin in a document with a margin" do
353
+ @pdf = Prawn::Document.new
354
+
355
+ @pdf.rotate(@angle, :origin => [@x, @y]) { @pdf.text('hello world') }
356
+
357
+ x = @x + @pdf.bounds.absolute_left
358
+ y = @y + @pdf.bounds.absolute_bottom
359
+ x_prime = x * @cos - y * @sin
360
+ y_prime = x * @sin + y * @cos
361
+
362
+ matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
363
+ matrices.matrices[0].should == [1, 0, 0, 1,
364
+ reduce_precision(x - x_prime),
365
+ reduce_precision(y - y_prime)]
366
+ matrices.matrices[1].should == [reduce_precision(@cos),
367
+ reduce_precision(@sin),
368
+ reduce_precision(-@sin),
369
+ reduce_precision(@cos), 0, 0]
370
+ end
371
+
372
+ it "should raise BlockRequired if no block is given" do
373
+ lambda {
374
+ @pdf.rotate(@angle, :origin => [@x, @y])
375
+ }.should.raise(Prawn::Errors::BlockRequired)
376
+ end
377
+
378
+ def reduce_precision(float)
379
+ ("%.5f" % float).to_f
380
+ end
381
+ end
382
+
383
+ describe "#translate" do
384
+ it "should translate" do
385
+ x, y = 12, 54.32
386
+ @pdf.expects(:transformation_matrix).with(1, 0, 0, 1, x, y)
387
+ @pdf.translate(x, y)
388
+ end
389
+ end
390
+
391
+ describe "#scale" do
392
+ it "should scale" do
393
+ @pdf.expects(:transformation_matrix).with(@factor, 0, 0, @factor, 0, 0)
394
+ @pdf.scale(@factor)
395
+ end
396
+ end
397
+
398
+ describe "#scale with :origin option" do
399
+ it "should scale from the origin" do
400
+ x_prime = @factor * @x
401
+ y_prime = @factor * @y
402
+
403
+ @pdf.scale(@factor, :origin => [@x, @y]) { @pdf.text('hello world') }
404
+
405
+ matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
406
+ matrices.matrices[0].should == [1, 0, 0, 1,
407
+ reduce_precision(@x - x_prime),
408
+ reduce_precision(@y - y_prime)]
409
+ matrices.matrices[1].should == [@factor, 0, 0, @factor, 0, 0]
410
+ end
411
+
412
+ it "should scale from the origin in a document with a margin" do
413
+ @pdf = Prawn::Document.new
414
+ x = @x + @pdf.bounds.absolute_left
415
+ y = @y + @pdf.bounds.absolute_bottom
416
+ x_prime = @factor * x
417
+ y_prime = @factor * y
418
+
419
+ @pdf.scale(@factor, :origin => [@x, @y]) { @pdf.text('hello world') }
420
+
421
+ matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
422
+ matrices.matrices[0].should == [1, 0, 0, 1,
423
+ reduce_precision(x - x_prime),
424
+ reduce_precision(y - y_prime)]
425
+ matrices.matrices[1].should == [@factor, 0, 0, @factor, 0, 0]
426
+ end
427
+
428
+ it "should raise BlockRequired if no block is given" do
429
+ lambda {
430
+ @pdf.scale(@factor, :origin => [@x, @y])
431
+ }.should.raise(Prawn::Errors::BlockRequired)
432
+ end
433
+
434
+ def reduce_precision(float)
435
+ ("%.5f" % float).to_f
436
+ end
437
+ end
438
+
439
+ # describe "skew" do
440
+ # it "should skew" do
441
+ # a, b = 30, 50.2
442
+ # @pdf.expects(:transformation_matrix).with(1, Math.tan(a * Math::PI / 180), Math.tan(b * Math::PI / 180), 1, 0, 0)
443
+ # @pdf.skew(a, b)
444
+ # end
445
+ # end
446
+ end