prawn 0.11.1 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (353) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +10 -0
  3. data/COPYING +2 -2
  4. data/GPLv2 +340 -0
  5. data/GPLv3 +674 -0
  6. data/Gemfile +11 -0
  7. data/LICENSE +1 -1
  8. data/Rakefile +29 -38
  9. data/data/images/16bit.alpha +0 -0
  10. data/data/images/16bit.color +0 -0
  11. data/data/images/dice.alpha +0 -0
  12. data/data/images/dice.color +0 -0
  13. data/data/images/indexed_color.dat +0 -0
  14. data/data/images/indexed_color.png +0 -0
  15. data/data/images/page_white_text.alpha +0 -0
  16. data/data/images/page_white_text.color +0 -0
  17. data/data/pdfs/nested_pages.pdf +13 -13
  18. data/lib/prawn/document/bounding_box.rb +87 -12
  19. data/lib/prawn/document/column_box.rb +57 -28
  20. data/lib/prawn/document/graphics_state.rb +11 -74
  21. data/lib/prawn/document/internals.rb +25 -23
  22. data/lib/prawn/document/snapshot.rb +11 -8
  23. data/lib/prawn/document/span.rb +12 -10
  24. data/lib/prawn/document.rb +250 -194
  25. data/lib/prawn/encoding.rb +9 -10
  26. data/lib/prawn/errors.rb +18 -29
  27. data/lib/prawn/font/afm.rb +52 -41
  28. data/lib/prawn/font/dfont.rb +4 -3
  29. data/lib/prawn/font/ttf.rb +44 -48
  30. data/lib/prawn/font.rb +138 -88
  31. data/lib/prawn/font_metric_cache.rb +47 -0
  32. data/lib/prawn/graphics/cap_style.rb +4 -3
  33. data/lib/prawn/graphics/color.rb +13 -5
  34. data/lib/prawn/graphics/dash.rb +53 -31
  35. data/lib/prawn/graphics/join_style.rb +9 -7
  36. data/lib/prawn/graphics/patterns.rb +138 -0
  37. data/lib/prawn/graphics/transformation.rb +10 -9
  38. data/lib/prawn/graphics/transparency.rb +3 -1
  39. data/lib/prawn/graphics.rb +316 -61
  40. data/lib/prawn/image_handler.rb +36 -0
  41. data/lib/prawn/images/image.rb +49 -0
  42. data/lib/prawn/images/jpg.rb +21 -15
  43. data/lib/prawn/images/png.rb +62 -119
  44. data/lib/prawn/images.rb +89 -108
  45. data/lib/prawn/layout/grid.rb +66 -54
  46. data/lib/prawn/layout.rb +10 -15
  47. data/lib/prawn/measurement_extensions.rb +10 -6
  48. data/lib/prawn/measurements.rb +27 -21
  49. data/lib/prawn/outline.rb +6 -308
  50. data/lib/prawn/repeater.rb +11 -9
  51. data/lib/prawn/security/arcfour.rb +1 -0
  52. data/lib/prawn/security.rb +55 -33
  53. data/lib/prawn/soft_mask.rb +96 -0
  54. data/lib/prawn/stamp.rb +5 -3
  55. data/lib/prawn/table/cell/image.rb +69 -0
  56. data/lib/prawn/table/cell/in_table.rb +4 -2
  57. data/lib/prawn/table/cell/span_dummy.rb +93 -0
  58. data/lib/prawn/table/cell/subtable.rb +2 -2
  59. data/lib/prawn/table/cell/text.rb +44 -26
  60. data/lib/prawn/table/cell.rb +302 -50
  61. data/lib/prawn/table/cells.rb +147 -49
  62. data/lib/prawn/table/column_width_calculator.rb +61 -0
  63. data/lib/prawn/table.rb +297 -118
  64. data/lib/prawn/text/box.rb +21 -5
  65. data/lib/prawn/text/formatted/arranger.rb +290 -0
  66. data/lib/prawn/text/formatted/box.rb +103 -59
  67. data/lib/prawn/text/formatted/fragment.rb +34 -23
  68. data/lib/prawn/text/formatted/line_wrap.rb +266 -0
  69. data/lib/prawn/text/formatted/parser.rb +15 -5
  70. data/lib/prawn/text/formatted/wrap.rb +150 -0
  71. data/lib/prawn/text/formatted.rb +5 -4
  72. data/lib/prawn/text.rb +38 -24
  73. data/lib/prawn/utilities.rb +46 -0
  74. data/lib/prawn.rb +85 -20
  75. data/manual/basic_concepts/adding_pages.rb +27 -0
  76. data/manual/basic_concepts/basic_concepts.rb +34 -0
  77. data/manual/basic_concepts/creation.rb +39 -0
  78. data/manual/basic_concepts/cursor.rb +33 -0
  79. data/manual/basic_concepts/measurement.rb +25 -0
  80. data/manual/basic_concepts/origin.rb +38 -0
  81. data/manual/basic_concepts/other_cursor_helpers.rb +40 -0
  82. data/manual/bounding_box/bounding_box.rb +39 -0
  83. data/manual/bounding_box/bounds.rb +49 -0
  84. data/manual/bounding_box/canvas.rb +24 -0
  85. data/manual/bounding_box/creation.rb +23 -0
  86. data/manual/bounding_box/indentation.rb +46 -0
  87. data/manual/bounding_box/nesting.rb +45 -0
  88. data/manual/bounding_box/russian_boxes.rb +40 -0
  89. data/manual/bounding_box/stretchy.rb +31 -0
  90. data/manual/document_and_page_options/background.rb +27 -0
  91. data/manual/document_and_page_options/document_and_page_options.rb +32 -0
  92. data/manual/document_and_page_options/metadata.rb +23 -0
  93. data/manual/document_and_page_options/page_margins.rb +38 -0
  94. data/manual/document_and_page_options/page_size.rb +34 -0
  95. data/manual/document_and_page_options/print_scaling.rb +20 -0
  96. data/manual/example_file.rb +111 -0
  97. data/manual/example_helper.rb +411 -0
  98. data/manual/example_package.rb +53 -0
  99. data/manual/example_section.rb +46 -0
  100. data/manual/graphics/circle_and_ellipse.rb +22 -0
  101. data/manual/graphics/color.rb +24 -0
  102. data/manual/graphics/common_lines.rb +30 -0
  103. data/manual/graphics/fill_and_stroke.rb +42 -0
  104. data/manual/graphics/fill_rules.rb +37 -0
  105. data/manual/graphics/gradients.rb +37 -0
  106. data/manual/graphics/graphics.rb +58 -0
  107. data/manual/graphics/helper.rb +24 -0
  108. data/manual/graphics/line_width.rb +35 -0
  109. data/manual/graphics/lines_and_curves.rb +41 -0
  110. data/manual/graphics/polygon.rb +29 -0
  111. data/manual/graphics/rectangle.rb +21 -0
  112. data/manual/graphics/rotate.rb +28 -0
  113. data/manual/graphics/scale.rb +41 -0
  114. data/manual/graphics/soft_masks.rb +46 -0
  115. data/manual/graphics/stroke_cap.rb +31 -0
  116. data/manual/graphics/stroke_dash.rb +48 -0
  117. data/manual/graphics/stroke_join.rb +30 -0
  118. data/manual/graphics/translate.rb +29 -0
  119. data/manual/graphics/transparency.rb +35 -0
  120. data/manual/images/absolute_position.rb +23 -0
  121. data/manual/images/fit.rb +21 -0
  122. data/manual/images/horizontal.rb +25 -0
  123. data/manual/images/images.rb +40 -0
  124. data/manual/images/plain_image.rb +18 -0
  125. data/manual/images/scale.rb +22 -0
  126. data/manual/images/vertical.rb +28 -0
  127. data/manual/images/width_and_height.rb +25 -0
  128. data/manual/layout/boxes.rb +27 -0
  129. data/manual/layout/content.rb +25 -0
  130. data/manual/layout/layout.rb +28 -0
  131. data/manual/layout/simple_grid.rb +23 -0
  132. data/manual/manual/cover.rb +36 -0
  133. data/manual/manual/foreword.rb +85 -0
  134. data/manual/manual/how_to_read_this_manual.rb +41 -0
  135. data/manual/manual/manual.rb +34 -0
  136. data/manual/outline/add_subsection_to.rb +61 -0
  137. data/manual/outline/insert_section_after.rb +47 -0
  138. data/manual/outline/outline.rb +32 -0
  139. data/manual/outline/sections_and_pages.rb +67 -0
  140. data/manual/repeatable_content/page_numbering.rb +54 -0
  141. data/manual/repeatable_content/repeatable_content.rb +31 -0
  142. data/manual/repeatable_content/repeater.rb +55 -0
  143. data/manual/repeatable_content/stamp.rb +41 -0
  144. data/manual/security/encryption.rb +31 -0
  145. data/manual/security/permissions.rb +38 -0
  146. data/manual/security/security.rb +28 -0
  147. data/manual/syntax_highlight.rb +52 -0
  148. data/manual/table/basic_block.rb +53 -0
  149. data/manual/table/before_rendering_page.rb +26 -0
  150. data/manual/table/cell_border_lines.rb +24 -0
  151. data/manual/table/cell_borders_and_bg.rb +31 -0
  152. data/manual/table/cell_dimensions.rb +30 -0
  153. data/manual/table/cell_text.rb +38 -0
  154. data/manual/table/column_widths.rb +30 -0
  155. data/manual/table/content_and_subtables.rb +39 -0
  156. data/manual/table/creation.rb +27 -0
  157. data/manual/table/filtering.rb +36 -0
  158. data/manual/table/flow_and_header.rb +17 -0
  159. data/manual/table/image_cells.rb +33 -0
  160. data/manual/table/position.rb +29 -0
  161. data/manual/table/row_colors.rb +20 -0
  162. data/manual/table/span.rb +30 -0
  163. data/manual/table/style.rb +22 -0
  164. data/manual/table/table.rb +52 -0
  165. data/manual/table/width.rb +27 -0
  166. data/manual/text/alignment.rb +44 -0
  167. data/manual/text/color.rb +24 -0
  168. data/manual/text/column_box.rb +32 -0
  169. data/manual/text/fallback_fonts.rb +37 -0
  170. data/manual/text/font.rb +41 -0
  171. data/manual/text/font_size.rb +45 -0
  172. data/manual/text/font_style.rb +23 -0
  173. data/manual/text/formatted_callbacks.rb +60 -0
  174. data/manual/text/formatted_text.rb +54 -0
  175. data/manual/text/free_flowing_text.rb +51 -0
  176. data/manual/text/group.rb +31 -0
  177. data/manual/text/inline.rb +43 -0
  178. data/manual/text/kerning_and_character_spacing.rb +39 -0
  179. data/manual/text/leading.rb +25 -0
  180. data/manual/text/line_wrapping.rb +41 -0
  181. data/manual/text/paragraph_indentation.rb +26 -0
  182. data/manual/text/positioned_text.rb +38 -0
  183. data/manual/text/registering_families.rb +48 -0
  184. data/manual/text/rendering_and_color.rb +37 -0
  185. data/manual/text/right_to_left_text.rb +43 -0
  186. data/manual/text/rotation.rb +43 -0
  187. data/manual/text/single_usage.rb +37 -0
  188. data/manual/text/text.rb +75 -0
  189. data/manual/text/text_box_excess.rb +32 -0
  190. data/manual/text/text_box_extensions.rb +45 -0
  191. data/manual/text/text_box_overflow.rb +44 -0
  192. data/manual/text/utf8.rb +28 -0
  193. data/{examples/m17n → manual/text}/win_ansi_charset.rb +14 -10
  194. data/prawn.gemspec +27 -17
  195. data/spec/acceptance/png.rb +23 -0
  196. data/spec/annotations_spec.rb +16 -32
  197. data/spec/bounding_box_spec.rb +284 -2
  198. data/spec/cell_spec.rb +169 -38
  199. data/spec/column_box_spec.rb +65 -0
  200. data/spec/data/curves.pdf +66 -0
  201. data/spec/destinations_spec.rb +5 -5
  202. data/spec/document_spec.rb +212 -113
  203. data/spec/extensions/encoding_helpers.rb +9 -0
  204. data/spec/extensions/mocha.rb +2 -3
  205. data/spec/font_metric_cache_spec.rb +52 -0
  206. data/spec/font_spec.rb +205 -95
  207. data/spec/formatted_text_arranger_spec.rb +43 -43
  208. data/spec/formatted_text_box_spec.rb +63 -24
  209. data/spec/formatted_text_fragment_spec.rb +8 -8
  210. data/spec/graphics_spec.rb +175 -68
  211. data/spec/grid_spec.rb +26 -15
  212. data/spec/image_handler_spec.rb +54 -0
  213. data/spec/images_spec.rb +58 -30
  214. data/spec/inline_formatted_text_parser_spec.rb +73 -19
  215. data/spec/jpg_spec.rb +4 -4
  216. data/spec/line_wrap_spec.rb +28 -28
  217. data/spec/measurement_units_spec.rb +6 -6
  218. data/spec/object_store_spec.rb +17 -106
  219. data/spec/outline_spec.rb +103 -63
  220. data/spec/png_spec.rb +25 -25
  221. data/spec/reference_spec.rb +8 -65
  222. data/spec/repeater_spec.rb +25 -11
  223. data/spec/security_spec.rb +44 -12
  224. data/spec/snapshot_spec.rb +38 -6
  225. data/spec/soft_mask_spec.rb +117 -0
  226. data/spec/span_spec.rb +10 -15
  227. data/spec/spec_helper.rb +32 -8
  228. data/spec/stamp_spec.rb +29 -30
  229. data/spec/stroke_styles_spec.rb +36 -18
  230. data/spec/table/span_dummy_spec.rb +17 -0
  231. data/spec/table_spec.rb +850 -104
  232. data/spec/text_at_spec.rb +19 -33
  233. data/spec/text_box_spec.rb +117 -64
  234. data/spec/text_rendering_mode_spec.rb +5 -5
  235. data/spec/text_spacing_spec.rb +20 -2
  236. data/spec/text_spec.rb +111 -59
  237. data/spec/transparency_spec.rb +5 -5
  238. metadata +477 -328
  239. data/HACKING +0 -50
  240. data/README +0 -141
  241. data/data/fonts/Action Man.dfont +0 -0
  242. data/data/fonts/Activa.ttf +0 -0
  243. data/data/fonts/Chalkboard.ttf +0 -0
  244. data/data/fonts/DejaVuSans.ttf +0 -0
  245. data/data/fonts/Dustismo_Roman.ttf +0 -0
  246. data/data/fonts/comicsans.ttf +0 -0
  247. data/data/fonts/gkai00mp.ttf +0 -0
  248. data/data/images/16bit.dat +0 -0
  249. data/data/images/dice.dat +0 -0
  250. data/data/images/page_white_text.dat +0 -0
  251. data/data/images/rails.dat +0 -0
  252. data/data/images/rails.png +0 -0
  253. data/examples/bounding_box/bounding_boxes.rb +0 -44
  254. data/examples/bounding_box/indentation.rb +0 -35
  255. data/examples/bounding_box/russian_boxes.rb +0 -37
  256. data/examples/bounding_box/stretched_nesting.rb +0 -68
  257. data/examples/example_helper.rb +0 -8
  258. data/examples/general/background.rb +0 -24
  259. data/examples/general/canvas.rb +0 -16
  260. data/examples/general/context_sensitive_headers.rb +0 -38
  261. data/examples/general/float.rb +0 -12
  262. data/examples/general/margin.rb +0 -37
  263. data/examples/general/measurement_units.rb +0 -52
  264. data/examples/general/metadata-info.rb +0 -17
  265. data/examples/general/multi_page_layout.rb +0 -19
  266. data/examples/general/outlines.rb +0 -67
  267. data/examples/general/page_geometry.rb +0 -32
  268. data/examples/general/page_numbering.rb +0 -40
  269. data/examples/general/page_templates.rb +0 -20
  270. data/examples/general/repeaters.rb +0 -48
  271. data/examples/general/stamp.rb +0 -42
  272. data/examples/general/templates.rb +0 -14
  273. data/examples/graphics/basic_images.rb +0 -24
  274. data/examples/graphics/cmyk.rb +0 -13
  275. data/examples/graphics/curves.rb +0 -12
  276. data/examples/graphics/gradient.rb +0 -23
  277. data/examples/graphics/hexagon.rb +0 -14
  278. data/examples/graphics/image_fit.rb +0 -16
  279. data/examples/graphics/image_flow.rb +0 -38
  280. data/examples/graphics/image_position.rb +0 -18
  281. data/examples/graphics/line.rb +0 -33
  282. data/examples/graphics/png_types.rb +0 -23
  283. data/examples/graphics/polygons.rb +0 -17
  284. data/examples/graphics/remote_images.rb +0 -13
  285. data/examples/graphics/rounded_polygons.rb +0 -20
  286. data/examples/graphics/rounded_rectangle.rb +0 -21
  287. data/examples/graphics/ruport_style_helpers.rb +0 -20
  288. data/examples/graphics/stroke_bounds.rb +0 -21
  289. data/examples/graphics/stroke_cap_and_join.rb +0 -46
  290. data/examples/graphics/stroke_dash.rb +0 -43
  291. data/examples/graphics/transformations.rb +0 -53
  292. data/examples/graphics/transparency.rb +0 -27
  293. data/examples/grid/bounding_boxes.rb +0 -22
  294. data/examples/grid/column_gutter_grid.rb +0 -21
  295. data/examples/grid/multi_boxes.rb +0 -52
  296. data/examples/grid/show_grid.rb +0 -14
  297. data/examples/grid/simple_grid.rb +0 -21
  298. data/examples/m17n/chinese_text_wrapping.rb +0 -18
  299. data/examples/m17n/euro.rb +0 -16
  300. data/examples/m17n/full_win_ansi_character_list.rb +0 -20
  301. data/examples/m17n/sjis.rb +0 -29
  302. data/examples/m17n/utf8.rb +0 -14
  303. data/examples/security/hello_foo.rb +0 -9
  304. data/examples/table/bill.rb +0 -54
  305. data/examples/table/borders.rb +0 -25
  306. data/examples/table/cell.rb +0 -13
  307. data/examples/table/checkerboard.rb +0 -23
  308. data/examples/table/header.rb +0 -15
  309. data/examples/table/inline_format_table.rb +0 -13
  310. data/examples/table/multi_page_table.rb +0 -10
  311. data/examples/table/simple_table.rb +0 -25
  312. data/examples/table/subtable.rb +0 -13
  313. data/examples/table/widths.rb +0 -21
  314. data/examples/text/alignment.rb +0 -19
  315. data/examples/text/character_spacing.rb +0 -13
  316. data/examples/text/dfont.rb +0 -49
  317. data/examples/text/family_based_styling.rb +0 -25
  318. data/examples/text/font_calculations.rb +0 -92
  319. data/examples/text/font_size.rb +0 -34
  320. data/examples/text/hyphenation.rb +0 -45
  321. data/examples/text/indent_paragraphs.rb +0 -24
  322. data/examples/text/inline_format.rb +0 -104
  323. data/examples/text/kerning.rb +0 -31
  324. data/examples/text/rendering_mode.rb +0 -21
  325. data/examples/text/rotated.rb +0 -99
  326. data/examples/text/shaped_text_box.rb +0 -32
  327. data/examples/text/simple_text.rb +0 -18
  328. data/examples/text/simple_text_ttf.rb +0 -18
  329. data/examples/text/span.rb +0 -30
  330. data/examples/text/text_box.rb +0 -90
  331. data/examples/text/text_box_returning_excess.rb +0 -52
  332. data/examples/text/text_flow.rb +0 -68
  333. data/lib/prawn/compatibility.rb +0 -51
  334. data/lib/prawn/core/annotations.rb +0 -61
  335. data/lib/prawn/core/byte_string.rb +0 -9
  336. data/lib/prawn/core/destinations.rb +0 -90
  337. data/lib/prawn/core/document_state.rb +0 -78
  338. data/lib/prawn/core/literal_string.rb +0 -16
  339. data/lib/prawn/core/name_tree.rb +0 -165
  340. data/lib/prawn/core/object_store.rb +0 -264
  341. data/lib/prawn/core/page.rb +0 -213
  342. data/lib/prawn/core/pdf_object.rb +0 -108
  343. data/lib/prawn/core/reference.rb +0 -112
  344. data/lib/prawn/core/text/formatted/arranger.rb +0 -293
  345. data/lib/prawn/core/text/formatted/line_wrap.rb +0 -272
  346. data/lib/prawn/core/text/formatted/wrap.rb +0 -149
  347. data/lib/prawn/core/text.rb +0 -268
  348. data/lib/prawn/core.rb +0 -85
  349. data/lib/prawn/document/page_geometry.rb +0 -136
  350. data/lib/prawn/graphics/gradient.rb +0 -84
  351. data/spec/name_tree_spec.rb +0 -112
  352. data/spec/pdf_object_spec.rb +0 -170
  353. data/spec/template_spec.rb +0 -291
data/lib/prawn/text.rb CHANGED
@@ -5,15 +5,18 @@
5
5
  # Copyright May 2008, Gregory Brown. All Rights Reserved.
6
6
  #
7
7
  # This is free software. Please see the LICENSE and COPYING files for details.
8
- require "prawn/core/text"
9
- require "prawn/text/formatted"
10
- require "prawn/text/box"
8
+
11
9
  require "zlib"
12
10
 
11
+ require "pdf/core/text"
12
+
13
+ require_relative "text/formatted"
14
+ require_relative "text/box"
15
+
13
16
  module Prawn
14
17
  module Text
15
18
 
16
- include Prawn::Core::Text
19
+ include PDF::Core::Text
17
20
  include Prawn::Text::Formatted
18
21
 
19
22
  # No-Break Space
@@ -23,11 +26,13 @@ module Prawn
23
26
  # Soft Hyphen (invisible, except when causing a line break)
24
27
  Prawn::Text::SHY = "­"
25
28
 
29
+ # @group Stable API
30
+
26
31
  # If you want text to flow onto a new page or between columns, this is the
27
32
  # method to use. If, instead, if you want to place bounded text outside of
28
33
  # the flow of a document (for captions, labels, charts, etc.), use Text::Box
29
34
  # or its convenience method text_box.
30
- #
35
+ #
31
36
  # Draws text on the page. Prawn attempts to wrap the text to fit within your
32
37
  # current bounding box (or margin_box if no bounding box is being used).
33
38
  # Text will flow onto the next page when it reaches the bottom of the
@@ -49,28 +54,29 @@ module Prawn
49
54
  # entire document, set default_kerning = false for that document
50
55
  #
51
56
  # === Text Positioning Details
52
- #
57
+ #
53
58
  # The text is positioned at font.ascender below the baseline,
54
59
  # making it easy to use this method within bounding boxes and spans.
55
60
  #
56
61
  # == Encoding
57
62
  #
58
63
  # Note that strings passed to this function should be encoded as UTF-8.
59
- # If you get unexpected characters appearing in your rendered document,
64
+ # If you get unexpected characters appearing in your rendered document,
60
65
  # check this.
61
66
  #
62
67
  # If the current font is a built-in one, although the string must be
63
68
  # encoded as UTF-8, only characters that are available in WinAnsi
64
69
  # are allowed.
65
70
  #
66
- # If an empty box is rendered to your PDF instead of the character you
71
+ # If an empty box is rendered to your PDF instead of the character you
67
72
  # wanted it usually means the current font doesn't include that character.
68
73
  #
69
74
  # == Options (default values marked in [])
70
75
  #
71
76
  # <tt>:inline_format</tt>::
72
77
  # <tt>boolean</tt>. If true, then the string parameter is interpreted
73
- # as a HTML-esque string that recognizes the following tags:
78
+ # as a HTML-esque string that recognizes the following tags
79
+ # (assuming the default text formatter is used):
74
80
  # <tt>\<b></b></tt>:: bold
75
81
  # <tt>\<i></i></tt>:: italic
76
82
  # <tt>\<u></u></tt>:: underline
@@ -97,8 +103,8 @@ module Prawn
97
103
  # <tt>anchor="ToC"</tt>::
98
104
  # where the value of the anchor attribute is the name of a
99
105
  # destination that has already been or will be registered
100
- # using Prawn::Core::Destinations#add_dest. A clickable link
101
- # will be created to that destination.
106
+ # using PDF::Core::Destinations#add_dest. A clickable link
107
+ # will be created to that destination.
102
108
  # Note that you must explicitly underline and color using the
103
109
  # appropriate tags if you which to draw attention to the link
104
110
  #
@@ -107,6 +113,7 @@ module Prawn
107
113
  # [value of document.default_kerning?]
108
114
  # <tt>:size</tt>:: <tt>number</tt>. The font size to use. [current font
109
115
  # size]
116
+ # <tt>:color</tt>:: an RGB color ("ff0000") or CMYK array [10, 20, 30, 40].
110
117
  # <tt>:character_spacing</tt>:: <tt>number</tt>. The amount of space to add
111
118
  # to or remove from the default character
112
119
  # spacing. [0]
@@ -142,7 +149,7 @@ module Prawn
142
149
  # text should render with the fill color, stroke color or
143
150
  # both. See the comments to text_rendering_mode() to see
144
151
  # a list of valid options. [0]
145
- #
152
+ #
146
153
  # == Exceptions
147
154
  #
148
155
  # Raises <tt>ArgumentError</tt> if <tt>:at</tt> option included
@@ -151,12 +158,14 @@ module Prawn
151
158
  # any text
152
159
  #
153
160
  def text(string, options={})
161
+ return false if string.nil?
154
162
  # we modify the options. don't change the user's hash
155
163
  options = options.dup
156
164
 
157
- if options[:inline_format]
165
+ if p = options[:inline_format]
166
+ p = [] unless p.is_a?(Array)
158
167
  options.delete(:inline_format)
159
- array = Text::Formatted::Parser.to_array(string)
168
+ array = self.text_formatter.format(string, *p)
160
169
  else
161
170
  array = [{ :text => string }]
162
171
  end
@@ -164,7 +173,6 @@ module Prawn
164
173
  formatted_text(array, options)
165
174
  end
166
175
 
167
-
168
176
  # Draws formatted text to the page.
169
177
  # Formatted text is comprised of an array of hashes, where each hash defines
170
178
  # text and format information. See Text::Formatted#formatted_text_box for
@@ -175,7 +183,7 @@ module Prawn
175
183
  # text([{ :text => "hello" },
176
184
  # { :text => "world",
177
185
  # :size => 24,
178
- # :style => [:bold, :italic] }])
186
+ # :styles => [:bold, :italic] }])
179
187
  #
180
188
  # == Options
181
189
  #
@@ -188,8 +196,14 @@ module Prawn
188
196
  def formatted_text(array, options={})
189
197
  options = inspect_options_for_text(options.dup)
190
198
 
199
+ if color = options.delete(:color)
200
+ array = array.map do |fragment|
201
+ fragment[:color] ? fragment : fragment.merge(:color => color)
202
+ end
203
+ end
204
+
191
205
  if @indent_paragraphs
192
- Text::Formatted::Parser.array_paragraphs(array).each do |paragraph|
206
+ self.text_formatter.array_paragraphs(array).each do |paragraph|
193
207
  options[:skip_encoding] = false
194
208
  remaining_text = draw_indented_formatted_line(paragraph, options)
195
209
  options[:skip_encoding] = true
@@ -216,7 +230,7 @@ module Prawn
216
230
 
217
231
  # Draws text on the page, beginning at the point specified by the :at option
218
232
  # the string is assumed to be pre-formatted to properly fit the page.
219
- #
233
+ #
220
234
  # pdf.draw_text "Hello World", :at => [100,100]
221
235
  # pdf.draw_text "Goodbye World", :at => [50,50], :size => 16
222
236
  #
@@ -238,14 +252,14 @@ module Prawn
238
252
  # == Encoding
239
253
  #
240
254
  # Note that strings passed to this function should be encoded as UTF-8.
241
- # If you get unexpected characters appearing in your rendered document,
255
+ # If you get unexpected characters appearing in your rendered document,
242
256
  # check this.
243
257
  #
244
258
  # If the current font is a built-in one, although the string must be
245
259
  # encoded as UTF-8, only characters that are available in WinAnsi
246
260
  # are allowed.
247
261
  #
248
- # If an empty box is rendered to your PDF instead of the character you
262
+ # If an empty box is rendered to your PDF instead of the character you
249
263
  # wanted it usually means the current font doesn't include that character.
250
264
  #
251
265
  # == Options (default values marked in [])
@@ -274,7 +288,7 @@ module Prawn
274
288
  text = text.to_s.dup
275
289
  save_font do
276
290
  process_text_options(options)
277
- font.normalize_encoding!(text) unless @skip_encoding
291
+ font.normalize_encoding!(text)
278
292
  font_size(options[:size]) { draw_text!(text, options) }
279
293
  end
280
294
  end
@@ -307,7 +321,7 @@ module Prawn
307
321
  # height_of_formatted([{ :text => "hello" },
308
322
  # { :text => "world",
309
323
  # :size => 24,
310
- # :style => [:bold, :italic] }])
324
+ # :styles => [:bold, :italic] }])
311
325
  #
312
326
  def height_of_formatted(array, options={})
313
327
  if options[:indent_paragraphs]
@@ -318,7 +332,7 @@ module Prawn
318
332
  box = Text::Formatted::Box.new(array,
319
333
  options.merge(:height => 100000000,
320
334
  :document => self))
321
- printed = box.render(:dry_run => true)
335
+ box.render(:dry_run => true)
322
336
 
323
337
  height = box.height
324
338
  height += box.line_gap + box.leading if @final_gap
@@ -374,7 +388,7 @@ module Prawn
374
388
  if options[:kerning].nil? then
375
389
  options[:kerning] = default_kerning?
376
390
  end
377
- valid_options = Prawn::Core::Text::VALID_OPTIONS + [:at, :rotate]
391
+ valid_options = PDF::Core::Text::VALID_OPTIONS + [:at, :rotate]
378
392
  Prawn.verify_options(valid_options, options)
379
393
  options
380
394
  end
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+
3
+ # utilities.rb : General-purpose utility classes which don't fit anywhere else
4
+ #
5
+ # Copyright August 2012, Alex Dowad. All Rights Reserved.
6
+ #
7
+ # This is free software. Please see the LICENSE and COPYING files for details.
8
+
9
+ require 'thread'
10
+
11
+ module Prawn
12
+
13
+ # Throughout the Prawn codebase, repeated calculations which can benefit from caching are made
14
+ # In some cases, caching and reusing results can not only save CPU cycles but also greatly
15
+ # reduce memory requirements
16
+ # But at the same time, we don't want to throw away thread safety
17
+ # We have two interchangeable thread-safe cache implementations:
18
+
19
+ # @private
20
+ class SynchronizedCache
21
+ # As an optimization, this could access the hash directly on VMs with a global interpreter lock (like MRI)
22
+ def initialize
23
+ @cache = {}
24
+ @mutex = Mutex.new
25
+ end
26
+ def [](key)
27
+ @mutex.synchronize { @cache[key] }
28
+ end
29
+ def []=(key,value)
30
+ @mutex.synchronize { @cache[key] = value }
31
+ end
32
+ end
33
+
34
+ # @private
35
+ class ThreadLocalCache
36
+ def initialize
37
+ @cache_id = "cache_#{self.object_id}".to_sym
38
+ end
39
+ def [](key)
40
+ (Thread.current[@cache_id] ||= {})[key]
41
+ end
42
+ def []=(key,value)
43
+ (Thread.current[@cache_id] ||= {})[key] = value
44
+ end
45
+ end
46
+ end
data/lib/prawn.rb CHANGED
@@ -1,26 +1,91 @@
1
1
  # Welcome to Prawn, the best PDF Generation library ever.
2
2
  # This documentation covers user level functionality.
3
3
  #
4
- # Those looking to contribute code or write extensions should look
5
- # into the lib/prawn/core/* source tree.
6
- #
7
- module Prawn #:nodoc:
8
- VERSION = "0.11.1"
4
+ require "set"
5
+
6
+ require 'ttfunk'
7
+ require "pdf/core"
8
+
9
+ module Prawn
10
+ VERSION = "0.15.0"
11
+
12
+ extend self
13
+
14
+ file = __FILE__
15
+ file = File.readlink(file) if File.symlink?(file)
16
+ dir = File.dirname(file)
17
+
18
+ # The base source directory for Prawn as installed on the system
19
+ #
20
+ #
21
+ BASEDIR = File.expand_path(File.join(dir, '..'))
22
+ DATADIR = File.expand_path(File.join(dir, '..', 'data'))
23
+
24
+ FLOAT_PRECISION = 1.0e-9
25
+
26
+ # Whe set to true, Prawn will verify hash options to ensure only valid keys
27
+ # are used. Off by default.
28
+ #
29
+ # Example:
30
+ # >> Prawn::Document.new(:tomato => "Juicy")
31
+ # Prawn::Errors::UnknownOption:
32
+ # Detected unknown option(s): [:tomato]
33
+ # Accepted options are: [:page_size, :page_layout, :left_margin, ...]
34
+ #
35
+ attr_accessor :debug # @private
36
+
37
+ def verify_options(accepted, actual) # @private
38
+ return unless debug || $DEBUG
39
+ unless (act=Set[*actual.keys]).subset?(acc=Set[*accepted])
40
+ raise Prawn::Errors::UnknownOption,
41
+ "\nDetected unknown option(s): #{(act - acc).to_a.inspect}\n" <<
42
+ "Accepted options are: #{accepted.inspect}"
43
+ end
44
+ yield if block_given?
45
+ end
46
+
47
+ module Configurable # @private
48
+ def configuration(*args)
49
+ @config ||= Marshal.load(Marshal.dump(default_configuration))
50
+ if Hash === args[0]
51
+ @config.update(args[0])
52
+ elsif args.length > 1
53
+ @config.values_at(*args)
54
+ elsif args.length == 1
55
+ @config[args[0]]
56
+ else
57
+ @config
58
+ end
59
+ end
60
+
61
+ alias_method :C, :configuration
62
+ end
9
63
  end
10
64
 
11
- require "prawn/core"
12
- require "prawn/text"
13
- require "prawn/graphics"
14
- require "prawn/images"
15
- require "prawn/images/jpg"
16
- require "prawn/images/png"
17
- require "prawn/stamp"
18
- require "prawn/security"
19
- require "prawn/document"
20
- require "prawn/font"
21
- require "prawn/encoding"
22
- require "prawn/measurements"
23
- require "prawn/repeater"
24
- require "prawn/outline"
25
- require "prawn/layout"
65
+ require_relative "prawn/errors"
66
+
67
+
68
+ require_relative "prawn/utilities"
69
+ require_relative "prawn/text"
70
+ require_relative "prawn/graphics"
71
+ require_relative "prawn/images"
72
+ require_relative "prawn/images/image"
73
+ require_relative "prawn/images/jpg"
74
+ require_relative "prawn/images/png"
75
+ require_relative "prawn/stamp"
76
+ require_relative "prawn/soft_mask"
77
+ require_relative "prawn/security"
78
+ require_relative "prawn/document"
79
+ require_relative "prawn/font"
80
+ require_relative "prawn/encoding"
81
+ require_relative "prawn/measurements"
82
+ require_relative "prawn/repeater"
83
+ require_relative "prawn/outline"
84
+ require_relative "prawn/layout"
85
+
86
+ require_relative "prawn/image_handler"
87
+
88
+
26
89
 
90
+ Prawn.image_handler.register(Prawn::Images::PNG)
91
+ Prawn.image_handler.register(Prawn::Images::JPG)
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ #
3
+ # A PDF document is a collection of pages. When we create a new document be it
4
+ # with <code>Document.new</code> or on a <code>Document.generate</code> block
5
+ # one initial page is created for us.
6
+ #
7
+ # Some methods might create new pages automatically like <code>text</code> which
8
+ # will create a new page whenever the text string cannot fit on the current
9
+ # page.
10
+ #
11
+ # But what if you want to go to the next page by yourself? That is easy.
12
+ #
13
+ # Just use the <code>start_new_page</code> method and a shiny new page will be
14
+ # created for you just like in the following snippet.
15
+ #
16
+ require File.expand_path(File.join(File.dirname(__FILE__),
17
+ %w[.. example_helper]))
18
+
19
+ filename = File.basename(__FILE__).gsub('.rb', '.pdf')
20
+ Prawn::Example.generate(filename) do
21
+ text "We are still on the initial page for this example. Now I'll ask " +
22
+ "Prawn to gently start a new page. Please follow me to the next page."
23
+
24
+ start_new_page
25
+
26
+ text "See. We've left the previous page behind."
27
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Examples for Prawn basic concepts.
4
+ #
5
+ require File.expand_path(File.join(File.dirname(__FILE__),
6
+ %w[.. example_helper]))
7
+
8
+ Prawn::Example.generate("basic_concepts.pdf", :page_size => "FOLIO") do
9
+
10
+ package "basic_concepts" do |p|
11
+
12
+ p.example "creation", :eval_source => false, :full_source => true
13
+ p.example "origin"
14
+ p.example "cursor"
15
+ p.example "other_cursor_helpers"
16
+ p.example "adding_pages"
17
+ p.example "measurement"
18
+
19
+ p.intro do
20
+ prose("This chapter covers the minimum amount of functionality you'll need to start using Prawn.
21
+
22
+ If you are new to Prawn this is the first chapter to read. Once you are comfortable with the concepts shown here you might want to check the Basics section of the Graphics, Bounding Box and Text sections.
23
+
24
+ The examples show:")
25
+
26
+ list( "How to create new pdf documents in every possible way",
27
+ "Where the origin for the document coordinates is. What are Bounding Boxes and how they interact with the origin",
28
+ "How the cursor behaves",
29
+ "How to start new pages",
30
+ "What the base unit for measurement and coordinates is and how to use other convenient measures"
31
+ )
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ #
3
+ # There are three ways to create a PDF Document in Prawn: creating a new
4
+ # <code>Prawn::Document</code> instance, or using the
5
+ # <code>Prawn::Document.generate</code> method with and without block arguments.
6
+ #
7
+ # The following snippet showcase each way by creating a simple document with
8
+ # some text drawn.
9
+ #
10
+ # When we instantiate the <code>Prawn::Document</code> object the actual pdf
11
+ # document will only be created after we call <code>render_file</code>.
12
+ #
13
+ # The generate method will render the actual pdf object after exiting the block.
14
+ # When we use it without a block argument the provided block is evaluated in the
15
+ # context of a newly created <code>Prawn::Document</code> instance. When we use
16
+ # it with a block argument a <code>Prawn::Document</code> instance is created
17
+ # and passed to the block.
18
+ #
19
+ # The generate method without block arguments requires
20
+ # less typing and defines and renders the pdf document in one shot.
21
+ # Almost all of the examples are coded this way.
22
+ #
23
+ require File.expand_path(File.join(File.dirname(__FILE__),
24
+ %w[.. example_helper]))
25
+
26
+ # Assignment
27
+ pdf = Prawn::Document.new
28
+ pdf.text "Hello World"
29
+ pdf.render_file "assignment.pdf"
30
+
31
+ # Implicit Block
32
+ Prawn::Document.generate("implicit.pdf") do
33
+ text "Hello World"
34
+ end
35
+
36
+ # Explicit Block
37
+ Prawn::Document.generate("explicit.pdf") do |pdf|
38
+ pdf.text "Hello World"
39
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ #
3
+ # We normally write our documents from top to bottom and it is no different with
4
+ # Prawn. Even if the origin is on the bottom left corner we still fill the page
5
+ # from the top to the bottom. In other words the cursor for inserting content
6
+ # starts on the top of the page.
7
+ #
8
+ # Most of the functions that insert content on the page will start at the
9
+ # current cursor position and proceed to the bottom of the page.
10
+ #
11
+ # The following snippet shows how the cursor behaves when we add some text to
12
+ # the page and demonstrates some of the helpers to manage the cursor position.
13
+ # The <code>cursor</code> method returns the current cursor position.
14
+ #
15
+ require File.expand_path(File.join(File.dirname(__FILE__),
16
+ %w[.. example_helper]))
17
+
18
+ filename = File.basename(__FILE__).gsub('.rb', '.pdf')
19
+ Prawn::Example.generate(filename) do
20
+ stroke_axis
21
+
22
+ text "the cursor is here: #{cursor}"
23
+ text "now it is here: #{cursor}"
24
+
25
+ move_down 200
26
+ text "on the first move the cursor went down to: #{cursor}"
27
+
28
+ move_up 100
29
+ text "on the second move the cursor went up to: #{cursor}"
30
+
31
+ move_cursor_to 50
32
+ text "on the last move the cursor went directly to: #{cursor}"
33
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ #
3
+ # The base unit in Prawn is the PDF Point. One PDF Point is equal to 1/72 of
4
+ # an inch.
5
+ #
6
+ # There is no need to waste time converting this measures. Prawn provides
7
+ # helpers for converting from other measurements
8
+ # to PDF Points.
9
+ #
10
+ # Just <code>require "prawn/measurement_extensions"</code> and it will mix some
11
+ # helpers onto <code>Numeric</code> for converting common measurement units to
12
+ # PDF Points.
13
+ #
14
+ require File.expand_path(File.join(File.dirname(__FILE__),
15
+ %w[.. example_helper]))
16
+
17
+ filename = File.basename(__FILE__).gsub('.rb', '.pdf')
18
+ Prawn::Example.generate(filename) do
19
+ require "prawn/measurement_extensions"
20
+
21
+ [:mm, :cm, :dm, :m, :in, :yd, :ft].each do |measurement|
22
+ text "1 #{measurement} in PDF Points: #{1.send(measurement)} pt"
23
+ move_down 5.mm
24
+ end
25
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This is the most important concept you need to learn about Prawn:
4
+ #
5
+ # PDF documents have the origin <code>[0,0]</code> at the bottom-left corner of
6
+ # the page.
7
+ #
8
+ # A bounding box is a structure which provides boundaries for inserting content.
9
+ # A bounding box also has the property of relocating the origin to its relative
10
+ # bottom-left corner. However, be aware that the location specified when
11
+ # creating a bounding box is its top-left corner, not bottom-left (hence the
12
+ # <code>[100, 300]</code> coordinates below).
13
+ #
14
+ # Even if you never create a bounding box explictly, each document already comes
15
+ # with one called the margin box. This initial bounding box is the one
16
+ # responsible for the document margins.
17
+ #
18
+ # So practically speaking the origin of a page on a default generated document
19
+ # isn't the absolute bottom left corner but the bottom left corner of the margin
20
+ # box.
21
+ #
22
+ # The following snippet strokes a circle on the margin box origin. Then strokes
23
+ # the boundaries of a bounding box and a circle on its origin.
24
+ #
25
+ require File.expand_path(File.join(File.dirname(__FILE__),
26
+ %w[.. example_helper]))
27
+
28
+ filename = File.basename(__FILE__).gsub('.rb', '.pdf')
29
+ Prawn::Example.generate(filename) do
30
+ stroke_axis
31
+
32
+ stroke_circle [0, 0], 10
33
+
34
+ bounding_box([100, 300], :width => 300, :height => 200) do
35
+ stroke_bounds
36
+ stroke_circle [0, 0], 10
37
+ end
38
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Another group of helpers for changing the cursor position are the pad methods.
4
+ # They accept a numeric value and a block. <code>pad</code> will use the numeric
5
+ # value to move the cursor down both before and after the block content.
6
+ # <code>pad_top</code> will only move the cursor before the block while
7
+ # <code>pad_bottom</code> will only move after.
8
+ #
9
+ # <code>float</code> is a method for not changing the cursor. Pass it a block
10
+ # and the cursor will remain on the same place when the block returns.
11
+ #
12
+ require File.expand_path(File.join(File.dirname(__FILE__),
13
+ %w[.. example_helper]))
14
+
15
+ filename = File.basename(__FILE__).gsub('.rb', '.pdf')
16
+ Prawn::Example.generate(filename) do
17
+ stroke_horizontal_rule
18
+ pad(20) { text "Text padded both before and after." }
19
+
20
+ stroke_horizontal_rule
21
+ pad_top(20) { text "Text padded on the top." }
22
+
23
+ stroke_horizontal_rule
24
+ pad_bottom(20) { text "Text padded on the bottom." }
25
+
26
+ stroke_horizontal_rule
27
+ move_down 30
28
+
29
+ text "Text written before the float block."
30
+
31
+ float do
32
+ move_down 30
33
+ bounding_box([0, cursor], :width => 200) do
34
+ text "Text written inside the float block."
35
+ stroke_bounds
36
+ end
37
+ end
38
+
39
+ text "Text written after the float block."
40
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Examples for bounding boxes.
4
+ #
5
+ require File.expand_path(File.join(File.dirname(__FILE__),
6
+ %w[.. example_helper]))
7
+
8
+ Prawn::Example.generate("bounding_box.pdf", :page_size => "FOLIO") do
9
+
10
+ package "bounding_box" do |p|
11
+
12
+ p.section "Basics" do |s|
13
+ s.example "creation"
14
+ s.example "bounds"
15
+ end
16
+
17
+ p.section "Advanced" do |s|
18
+ s.example "stretchy"
19
+ s.example "nesting"
20
+ s.example "indentation"
21
+ s.example "canvas"
22
+ s.example "russian_boxes"
23
+ end
24
+
25
+ p.intro do
26
+ prose("Bounding boxes are the basic containers for structuring the content flow. Even being low level building blocks sometimes their simplicity is very welcome.
27
+
28
+ The examples show:")
29
+
30
+ list( "How to create bounding boxes with specific dimensions",
31
+ "How to inspect the current bounding box for its coordinates",
32
+ "Stretchy bounding boxes",
33
+ "Nested bounding boxes",
34
+ "Indent blocks"
35
+ )
36
+ end
37
+
38
+ end
39
+ end