prawn 0.13.0 → 2.4.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 (348) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.yardopts +10 -0
  4. data/GPLv2 +20 -21
  5. data/Gemfile +3 -16
  6. data/Rakefile +17 -39
  7. data/lib/prawn/document/bounding_box.rb +85 -42
  8. data/lib/prawn/document/column_box.rb +21 -11
  9. data/lib/prawn/document/internals.rb +40 -147
  10. data/lib/prawn/document/span.rb +25 -17
  11. data/lib/prawn/document.rb +286 -245
  12. data/lib/prawn/encoding.rb +68 -101
  13. data/lib/prawn/errors.rb +47 -43
  14. data/lib/prawn/font.rb +204 -155
  15. data/lib/prawn/font_metric_cache.rb +25 -21
  16. data/lib/prawn/fonts/afm.rb +292 -0
  17. data/lib/prawn/{font → fonts}/dfont.rb +7 -13
  18. data/lib/prawn/fonts/otf.rb +11 -0
  19. data/lib/prawn/fonts/ttc.rb +36 -0
  20. data/lib/prawn/{font → fonts}/ttf.rb +142 -80
  21. data/lib/prawn/graphics/blend_mode.rb +65 -0
  22. data/lib/prawn/graphics/cap_style.rb +6 -5
  23. data/lib/prawn/graphics/color.rb +47 -44
  24. data/lib/prawn/graphics/dash.rb +30 -13
  25. data/lib/prawn/graphics/join_style.rb +13 -6
  26. data/lib/prawn/graphics/patterns.rb +221 -90
  27. data/lib/prawn/graphics/transformation.rb +21 -12
  28. data/lib/prawn/graphics/transparency.rb +21 -17
  29. data/lib/prawn/graphics.rb +155 -128
  30. data/lib/prawn/{layout/grid.rb → grid.rb} +110 -47
  31. data/lib/prawn/image_handler.rb +16 -2
  32. data/lib/prawn/images/image.rb +4 -2
  33. data/lib/prawn/images/jpg.rb +39 -30
  34. data/lib/prawn/images/png.rb +132 -169
  35. data/lib/prawn/images.rb +70 -62
  36. data/lib/prawn/measurement_extensions.rb +15 -10
  37. data/lib/prawn/measurements.rb +22 -23
  38. data/lib/prawn/outline.rb +301 -13
  39. data/lib/prawn/repeater.rb +19 -17
  40. data/lib/prawn/security/arcfour.rb +54 -0
  41. data/lib/prawn/security.rb +108 -86
  42. data/lib/prawn/soft_mask.rb +40 -41
  43. data/lib/prawn/stamp.rb +29 -12
  44. data/lib/prawn/text/box.rb +27 -29
  45. data/lib/prawn/text/formatted/arranger.rb +110 -67
  46. data/lib/prawn/text/formatted/box.rb +233 -165
  47. data/lib/prawn/text/formatted/fragment.rb +27 -27
  48. data/lib/prawn/text/formatted/line_wrap.rb +137 -97
  49. data/lib/prawn/text/formatted/parser.rb +149 -127
  50. data/lib/prawn/text/formatted/wrap.rb +57 -37
  51. data/lib/prawn/text/formatted.rb +6 -4
  52. data/lib/prawn/text.rb +105 -73
  53. data/lib/prawn/transformation_stack.rb +44 -0
  54. data/lib/prawn/utilities.rb +11 -21
  55. data/lib/prawn/version.rb +5 -0
  56. data/lib/prawn/view.rb +101 -0
  57. data/lib/prawn.rb +42 -68
  58. data/{data/images/fractal.jpg → manual/absolute_position.pdf} +0 -0
  59. data/manual/basic_concepts/adding_pages.rb +9 -10
  60. data/manual/basic_concepts/basic_concepts.rb +33 -24
  61. data/manual/basic_concepts/creation.rb +10 -11
  62. data/manual/basic_concepts/cursor.rb +9 -10
  63. data/manual/basic_concepts/measurement.rb +10 -11
  64. data/manual/basic_concepts/origin.rb +8 -9
  65. data/manual/basic_concepts/other_cursor_helpers.rb +17 -18
  66. data/manual/basic_concepts/view.rb +48 -0
  67. data/manual/bounding_box/bounding_box.rb +31 -29
  68. data/manual/bounding_box/bounds.rb +17 -18
  69. data/manual/bounding_box/canvas.rb +8 -9
  70. data/manual/bounding_box/creation.rb +8 -9
  71. data/manual/bounding_box/indentation.rb +22 -23
  72. data/manual/bounding_box/nesting.rb +32 -25
  73. data/manual/bounding_box/russian_boxes.rb +19 -19
  74. data/manual/bounding_box/stretchy.rb +18 -20
  75. data/manual/contents.rb +35 -0
  76. data/manual/cover.rb +43 -0
  77. data/manual/document_and_page_options/background.rb +16 -14
  78. data/manual/document_and_page_options/document_and_page_options.rb +26 -23
  79. data/manual/document_and_page_options/metadata.rb +21 -19
  80. data/manual/document_and_page_options/page_margins.rb +20 -22
  81. data/manual/document_and_page_options/page_size.rb +15 -15
  82. data/manual/document_and_page_options/print_scaling.rb +23 -0
  83. data/manual/example_helper.rb +5 -408
  84. data/manual/graphics/blend_mode.rb +52 -0
  85. data/manual/graphics/circle_and_ellipse.rb +8 -9
  86. data/manual/graphics/color.rb +11 -13
  87. data/manual/graphics/common_lines.rb +13 -12
  88. data/manual/graphics/fill_and_stroke.rb +10 -11
  89. data/manual/graphics/fill_rules.rb +13 -12
  90. data/manual/graphics/gradients.rb +28 -22
  91. data/manual/graphics/graphics.rb +52 -46
  92. data/manual/graphics/helper.rb +20 -10
  93. data/manual/graphics/line_width.rb +13 -12
  94. data/manual/graphics/lines_and_curves.rb +13 -14
  95. data/manual/graphics/polygon.rb +10 -12
  96. data/manual/graphics/rectangle.rb +7 -8
  97. data/manual/graphics/rotate.rb +9 -12
  98. data/manual/graphics/scale.rb +19 -18
  99. data/manual/graphics/soft_masks.rb +5 -7
  100. data/manual/graphics/stroke_cap.rb +10 -11
  101. data/manual/graphics/stroke_dash.rb +16 -17
  102. data/manual/graphics/stroke_join.rb +10 -11
  103. data/manual/graphics/translate.rb +13 -13
  104. data/manual/graphics/transparency.rb +11 -13
  105. data/manual/{manual/how_to_read_this_manual.rb → how_to_read_this_manual.rb} +23 -25
  106. data/manual/images/absolute_position.rb +9 -10
  107. data/manual/images/fit.rb +9 -10
  108. data/manual/images/horizontal.rb +13 -14
  109. data/manual/images/images.rb +31 -30
  110. data/manual/images/plain_image.rb +6 -7
  111. data/manual/images/scale.rb +12 -13
  112. data/manual/images/vertical.rb +19 -17
  113. data/manual/images/width_and_height.rb +13 -14
  114. data/manual/layout/boxes.rb +14 -15
  115. data/manual/layout/content.rb +12 -13
  116. data/manual/layout/layout.rb +19 -20
  117. data/manual/layout/simple_grid.rb +8 -9
  118. data/manual/outline/add_subsection_to.rb +26 -27
  119. data/manual/outline/insert_section_after.rb +19 -20
  120. data/manual/outline/outline.rb +23 -22
  121. data/manual/outline/sections_and_pages.rb +24 -25
  122. data/manual/repeatable_content/alternate_page_numbering.rb +36 -0
  123. data/manual/repeatable_content/page_numbering.rb +20 -19
  124. data/manual/repeatable_content/repeatable_content.rb +26 -22
  125. data/manual/repeatable_content/repeater.rb +18 -19
  126. data/manual/repeatable_content/stamp.rb +18 -19
  127. data/manual/security/encryption.rb +8 -11
  128. data/manual/security/permissions.rb +20 -15
  129. data/manual/security/security.rb +20 -20
  130. data/manual/table.rb +16 -0
  131. data/manual/text/alignment.rb +17 -18
  132. data/manual/text/color.rb +13 -13
  133. data/manual/text/column_box.rb +10 -12
  134. data/manual/text/fallback_fonts.rb +29 -25
  135. data/manual/text/font.rb +17 -18
  136. data/manual/text/font_size.rb +21 -22
  137. data/manual/text/font_style.rb +12 -10
  138. data/manual/text/formatted_callbacks.rb +36 -26
  139. data/manual/text/formatted_text.rb +41 -34
  140. data/manual/text/free_flowing_text.rb +28 -29
  141. data/manual/text/inline.rb +23 -26
  142. data/manual/text/kerning_and_character_spacing.rb +20 -21
  143. data/manual/text/leading.rb +10 -11
  144. data/manual/text/line_wrapping.rb +40 -21
  145. data/manual/text/paragraph_indentation.rb +17 -12
  146. data/manual/text/positioned_text.rb +19 -20
  147. data/manual/text/registering_families.rb +33 -30
  148. data/manual/text/rendering_and_color.rb +11 -12
  149. data/manual/text/right_to_left_text.rb +31 -20
  150. data/manual/text/rotation.rb +36 -27
  151. data/manual/text/single_usage.rb +13 -14
  152. data/manual/text/text.rb +62 -62
  153. data/manual/text/text_box_excess.rb +22 -19
  154. data/manual/text/text_box_extensions.rb +21 -18
  155. data/manual/text/text_box_overflow.rb +28 -21
  156. data/manual/text/utf8.rb +16 -17
  157. data/manual/text/win_ansi_charset.rb +29 -26
  158. data/prawn.gemspec +45 -43
  159. data/spec/extensions/encoding_helpers.rb +4 -3
  160. data/spec/prawn/document/bounding_box_spec.rb +550 -0
  161. data/spec/prawn/document/column_box_spec.rb +75 -0
  162. data/spec/prawn/document/security_spec.rb +176 -0
  163. data/spec/prawn/document_annotations_spec.rb +76 -0
  164. data/spec/prawn/document_destinations_spec.rb +15 -0
  165. data/spec/prawn/document_grid_spec.rb +99 -0
  166. data/spec/prawn/document_reference_spec.rb +27 -0
  167. data/spec/prawn/document_span_spec.rb +44 -0
  168. data/spec/prawn/document_spec.rb +805 -0
  169. data/spec/prawn/font_metric_cache_spec.rb +54 -0
  170. data/spec/prawn/font_spec.rb +544 -0
  171. data/spec/prawn/graphics/blend_mode_spec.rb +63 -0
  172. data/spec/prawn/graphics/transparency_spec.rb +81 -0
  173. data/spec/prawn/graphics_spec.rb +872 -0
  174. data/spec/prawn/graphics_stroke_styles_spec.rb +229 -0
  175. data/spec/prawn/image_handler_spec.rb +53 -0
  176. data/spec/prawn/images/jpg_spec.rb +20 -0
  177. data/spec/prawn/images/png_spec.rb +283 -0
  178. data/spec/prawn/images_spec.rb +229 -0
  179. data/spec/prawn/measurements_extensions_spec.rb +24 -0
  180. data/spec/prawn/outline_spec.rb +512 -0
  181. data/spec/prawn/repeater_spec.rb +166 -0
  182. data/spec/prawn/soft_mask_spec.rb +74 -0
  183. data/spec/prawn/stamp_spec.rb +173 -0
  184. data/spec/prawn/text/box_spec.rb +1110 -0
  185. data/spec/prawn/text/formatted/arranger_spec.rb +466 -0
  186. data/spec/prawn/text/formatted/box_spec.rb +849 -0
  187. data/spec/prawn/text/formatted/fragment_spec.rb +343 -0
  188. data/spec/prawn/text/formatted/line_wrap_spec.rb +495 -0
  189. data/spec/prawn/text/formatted/parser_spec.rb +697 -0
  190. data/spec/prawn/text_draw_text_spec.rb +150 -0
  191. data/spec/prawn/text_rendering_mode_spec.rb +48 -0
  192. data/spec/prawn/text_spacing_spec.rb +95 -0
  193. data/spec/prawn/text_spec.rb +603 -0
  194. data/spec/prawn/text_with_inline_formatting_spec.rb +35 -0
  195. data/spec/prawn/transformation_stack_spec.rb +66 -0
  196. data/spec/prawn/view_spec.rb +63 -0
  197. data/spec/prawn_manual_spec.rb +35 -0
  198. data/spec/spec_helper.rb +22 -21
  199. data.tar.gz.sig +0 -0
  200. metadata +168 -307
  201. metadata.gz.sig +0 -0
  202. data/README.md +0 -109
  203. data/data/encodings/win_ansi.txt +0 -29
  204. data/data/images/16bit.alpha +0 -0
  205. data/data/images/16bit.dat +0 -0
  206. data/data/images/16bit.png +0 -0
  207. data/data/images/arrow.png +0 -0
  208. data/data/images/arrow2.png +0 -0
  209. data/data/images/barcode_issue.png +0 -0
  210. data/data/images/dice.alpha +0 -0
  211. data/data/images/dice.dat +0 -0
  212. data/data/images/dice.png +0 -0
  213. data/data/images/dice_interlaced.png +0 -0
  214. data/data/images/indexed_color.dat +0 -0
  215. data/data/images/indexed_color.png +0 -0
  216. data/data/images/letterhead.jpg +0 -0
  217. data/data/images/page_white_text.alpha +0 -0
  218. data/data/images/page_white_text.dat +0 -0
  219. data/data/images/page_white_text.png +0 -0
  220. data/data/images/pigs.jpg +0 -0
  221. data/data/images/prawn.png +0 -0
  222. data/data/images/ruport.png +0 -0
  223. data/data/images/ruport_data.dat +0 -0
  224. data/data/images/ruport_transparent.png +0 -0
  225. data/data/images/ruport_type0.png +0 -0
  226. data/data/images/stef.jpg +0 -0
  227. data/data/images/tru256.bmp +0 -0
  228. data/data/images/web-links.dat +0 -1
  229. data/data/images/web-links.png +0 -0
  230. data/data/pdfs/complex_template.pdf +0 -0
  231. data/data/pdfs/contains_ttf_font.pdf +0 -0
  232. data/data/pdfs/encrypted.pdf +0 -0
  233. data/data/pdfs/form.pdf +1 -819
  234. data/data/pdfs/hexagon.pdf +0 -61
  235. data/data/pdfs/indirect_reference.pdf +0 -86
  236. data/data/pdfs/multipage_template.pdf +0 -127
  237. data/data/pdfs/nested_pages.pdf +0 -118
  238. data/data/pdfs/page_without_mediabox.pdf +0 -193
  239. data/data/pdfs/resources_as_indirect_object.pdf +0 -83
  240. data/data/pdfs/two_hexagons.pdf +0 -90
  241. data/data/pdfs/version_1_6.pdf +0 -61
  242. data/data/shift_jis_text.txt +0 -1
  243. data/lib/pdf/core/annotations.rb +0 -60
  244. data/lib/pdf/core/byte_string.rb +0 -9
  245. data/lib/pdf/core/destinations.rb +0 -90
  246. data/lib/pdf/core/document_state.rb +0 -78
  247. data/lib/pdf/core/filter_list.rb +0 -51
  248. data/lib/pdf/core/filters.rb +0 -36
  249. data/lib/pdf/core/graphics_state.rb +0 -68
  250. data/lib/pdf/core/literal_string.rb +0 -16
  251. data/lib/pdf/core/name_tree.rb +0 -177
  252. data/lib/pdf/core/object_store.rb +0 -320
  253. data/lib/pdf/core/outline.rb +0 -315
  254. data/lib/pdf/core/page.rb +0 -212
  255. data/lib/pdf/core/page_geometry.rb +0 -126
  256. data/lib/pdf/core/pdf_object.rb +0 -124
  257. data/lib/pdf/core/reference.rb +0 -103
  258. data/lib/pdf/core/stream.rb +0 -98
  259. data/lib/pdf/core/text.rb +0 -275
  260. data/lib/pdf/core.rb +0 -35
  261. data/lib/prawn/compatibility.rb +0 -91
  262. data/lib/prawn/document/graphics_state.rb +0 -73
  263. data/lib/prawn/document/snapshot.rb +0 -89
  264. data/lib/prawn/font/afm.rb +0 -203
  265. data/lib/prawn/layout.rb +0 -20
  266. data/lib/prawn/table/cell/image.rb +0 -70
  267. data/lib/prawn/table/cell/in_table.rb +0 -27
  268. data/lib/prawn/table/cell/span_dummy.rb +0 -92
  269. data/lib/prawn/table/cell/subtable.rb +0 -65
  270. data/lib/prawn/table/cell/text.rb +0 -153
  271. data/lib/prawn/table/cell.rb +0 -770
  272. data/lib/prawn/table/cells.rb +0 -295
  273. data/lib/prawn/table.rb +0 -643
  274. data/manual/example_file.rb +0 -116
  275. data/manual/example_package.rb +0 -53
  276. data/manual/example_section.rb +0 -46
  277. data/manual/manual/cover.rb +0 -35
  278. data/manual/manual/foreword.rb +0 -85
  279. data/manual/manual/manual.rb +0 -35
  280. data/manual/syntax_highlight.rb +0 -52
  281. data/manual/table/basic_block.rb +0 -53
  282. data/manual/table/before_rendering_page.rb +0 -26
  283. data/manual/table/cell_border_lines.rb +0 -24
  284. data/manual/table/cell_borders_and_bg.rb +0 -31
  285. data/manual/table/cell_dimensions.rb +0 -30
  286. data/manual/table/cell_text.rb +0 -38
  287. data/manual/table/column_widths.rb +0 -30
  288. data/manual/table/content_and_subtables.rb +0 -39
  289. data/manual/table/creation.rb +0 -27
  290. data/manual/table/filtering.rb +0 -36
  291. data/manual/table/flow_and_header.rb +0 -17
  292. data/manual/table/image_cells.rb +0 -33
  293. data/manual/table/position.rb +0 -29
  294. data/manual/table/row_colors.rb +0 -20
  295. data/manual/table/span.rb +0 -30
  296. data/manual/table/style.rb +0 -22
  297. data/manual/table/table.rb +0 -52
  298. data/manual/table/width.rb +0 -27
  299. data/manual/templates/full_template.rb +0 -25
  300. data/manual/templates/page_template.rb +0 -48
  301. data/manual/templates/templates.rb +0 -27
  302. data/manual/text/group.rb +0 -29
  303. data/spec/acceptance/png.rb +0 -23
  304. data/spec/annotations_spec.rb +0 -74
  305. data/spec/bounding_box_spec.rb +0 -493
  306. data/spec/cell_spec.rb +0 -628
  307. data/spec/column_box_spec.rb +0 -33
  308. data/spec/destinations_spec.rb +0 -15
  309. data/spec/document_spec.rb +0 -761
  310. data/spec/extensions/mocha.rb +0 -44
  311. data/spec/filters_spec.rb +0 -34
  312. data/spec/font_metric_cache_spec.rb +0 -52
  313. data/spec/font_spec.rb +0 -464
  314. data/spec/formatted_text_arranger_spec.rb +0 -421
  315. data/spec/formatted_text_box_spec.rb +0 -650
  316. data/spec/formatted_text_fragment_spec.rb +0 -298
  317. data/spec/graphics_spec.rb +0 -651
  318. data/spec/grid_spec.rb +0 -85
  319. data/spec/image_handler_spec.rb +0 -42
  320. data/spec/images_spec.rb +0 -157
  321. data/spec/inline_formatted_text_parser_spec.rb +0 -564
  322. data/spec/jpg_spec.rb +0 -25
  323. data/spec/line_wrap_spec.rb +0 -333
  324. data/spec/measurement_units_spec.rb +0 -23
  325. data/spec/name_tree_spec.rb +0 -112
  326. data/spec/object_store_spec.rb +0 -170
  327. data/spec/outline_spec.rb +0 -448
  328. data/spec/pdf_object_spec.rb +0 -172
  329. data/spec/png_spec.rb +0 -240
  330. data/spec/reference_spec.rb +0 -82
  331. data/spec/repeater_spec.rb +0 -158
  332. data/spec/security_spec.rb +0 -158
  333. data/spec/snapshot_spec.rb +0 -186
  334. data/spec/soft_mask_spec.rb +0 -117
  335. data/spec/span_spec.rb +0 -44
  336. data/spec/stamp_spec.rb +0 -158
  337. data/spec/stream_spec.rb +0 -58
  338. data/spec/stroke_styles_spec.rb +0 -211
  339. data/spec/table/span_dummy_spec.rb +0 -17
  340. data/spec/table_spec.rb +0 -1355
  341. data/spec/template_spec.rb +0 -351
  342. data/spec/text_at_spec.rb +0 -130
  343. data/spec/text_box_spec.rb +0 -1030
  344. data/spec/text_rendering_mode_spec.rb +0 -45
  345. data/spec/text_spacing_spec.rb +0 -93
  346. data/spec/text_spec.rb +0 -425
  347. data/spec/text_with_inline_formatting_spec.rb +0 -35
  348. data/spec/transparency_spec.rb +0 -89
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  # text/formatted/rectangle.rb : Implements text boxes with formatted text
4
4
  #
@@ -10,6 +10,7 @@
10
10
  module Prawn
11
11
  module Text
12
12
  module Formatted
13
+ # @group Stable API
13
14
 
14
15
  # Draws the requested formatted text into a box. When the text overflows
15
16
  # the rectangle shrink to fit or truncate the text. Text boxes are
@@ -53,8 +54,8 @@ module Prawn
53
54
  # a file or application to be opened locally. A clickable link will be
54
55
  # created to the provided local file or application. If the file is
55
56
  # another PDF, it will be opened in a new window. Note that you must
56
- # explicitly underline and color using the appropriate tags if you which
57
- # to draw attention to the link
57
+ # explicitly underline and color using the appropriate tags if you
58
+ # which to draw attention to the link
58
59
  # <tt>:draw_text_callback</tt>:
59
60
  # if provided, this Proc will be called instead of #draw_text! once
60
61
  # per fragment for every low-level addition of text to the page.
@@ -82,13 +83,14 @@ module Prawn
82
83
  #
83
84
  # == Exceptions
84
85
  #
85
- # Raises "Bad font family" if no font family is defined for the current font
86
+ # Raises "Bad font family" if no font family is defined for the current
87
+ # font
86
88
  #
87
- # Raises <tt>Prawn::Errrors::CannotFit</tt> if not wide enough to print
89
+ # Raises <tt>Prawn::Errors::CannotFit</tt> if not wide enough to print
88
90
  # any text
89
91
  #
90
- def formatted_text_box(array, options={})
91
- Text::Formatted::Box.new(array, options.merge(:document => self)).render
92
+ def formatted_text_box(array, options = {})
93
+ Text::Formatted::Box.new(array, options.merge(document: self)).render
92
94
  end
93
95
 
94
96
  # Generally, one would use the Prawn::Text::Formatted#formatted_text_box
@@ -100,31 +102,19 @@ module Prawn
100
102
  class Box
101
103
  include Prawn::Text::Formatted::Wrap
102
104
 
103
- def valid_options
104
- PDF::Core::Text::VALID_OPTIONS + [:at, :height, :width,
105
- :align, :valign,
106
- :rotate, :rotate_around,
107
- :overflow, :min_font_size,
108
- :leading, :character_spacing,
109
- :mode, :single_line,
110
- :skip_encoding,
111
- :document,
112
- :direction,
113
- :fallback_fonts,
114
- :draw_text_callback]
115
- end
105
+ # @group Experimental API
116
106
 
117
107
  # The text that was successfully printed (or, if <tt>dry_run</tt> was
118
108
  # used, the text that would have been successfully printed)
119
109
  attr_reader :text
120
110
 
121
- # True iff nothing printed (or, if <tt>dry_run</tt> was
111
+ # True if nothing printed (or, if <tt>dry_run</tt> was
122
112
  # used, nothing would have been successfully printed)
123
113
  def nothing_printed?
124
114
  @nothing_printed
125
115
  end
126
116
 
127
- # True iff everything printed (or, if <tt>dry_run</tt> was
117
+ # True if everything printed (or, if <tt>dry_run</tt> was
128
118
  # used, everything would have been successfully printed)
129
119
  def everything_printed?
130
120
  @everything_printed
@@ -145,76 +135,41 @@ module Prawn
145
135
  line_height - (ascender + descender)
146
136
  end
147
137
 
148
- #
149
- # Example (see Prawn::Text::Core::Formatted::Wrap for what is required
150
- # of the wrap method if you want to override the default wrapping
151
- # algorithm):
152
- #
153
- #
154
- # module MyWrap
155
- #
156
- # def wrap(array)
157
- # initialize_wrap([{ :text => 'all your base are belong to us' }])
158
- # @line_wrap.wrap_line(:document => @document,
159
- # :kerning => @kerning,
160
- # :width => 10000,
161
- # :arranger => @arranger)
162
- # fragment = @arranger.retrieve_fragment
163
- # format_and_draw_fragment(fragment, 0, @line_wrap.width, 0)
164
- # []
165
- # end
166
- #
167
- # end
168
- #
169
- # Prawn::Text::Formatted::Box.extensions << MyWrap
170
- #
171
- # box = Prawn::Text::Formatted::Box.new('hello world')
172
- # box.render('why can't I print anything other than' +
173
- # '"all your base are belong to us"?')
174
- #
175
- #
176
- def self.extensions
177
- @extensions ||= []
178
- end
179
-
180
- def self.inherited(base) #:nodoc:
181
- extensions.each { |e| base.extensions << e }
182
- end
183
-
184
138
  # See Prawn::Text#text_box for valid options
185
139
  #
186
- def initialize(formatted_text, options={})
187
- @inked = false
140
+ def initialize(formatted_text, options = {})
141
+ @inked = false
188
142
  Prawn.verify_options(valid_options, options)
189
- options = options.dup
143
+ options = options.dup
190
144
 
191
145
  self.class.extensions.reverse_each { |e| extend e }
192
146
 
193
- @overflow = options[:overflow] || :truncate
147
+ @overflow = options[:overflow] || :truncate
148
+ @disable_wrap_by_char = options[:disable_wrap_by_char]
194
149
 
195
150
  self.original_text = formatted_text
196
- @text = nil
197
-
198
- @document = options[:document]
199
- @direction = options[:direction] || @document.text_direction
200
- @fallback_fonts = options[:fallback_fonts] ||
201
- @document.fallback_fonts
202
- @at = (options[:at] ||
203
- [@document.bounds.left, @document.bounds.top]).dup
204
- @width = options[:width] ||
205
- @document.bounds.right - @at[0]
206
- @height = options[:height] || default_height
207
- @align = options[:align] ||
208
- (@direction == :rtl ? :right : :left)
209
- @vertical_align = options[:valign] || :top
210
- @leading = options[:leading] || @document.default_leading
151
+ @text = nil
152
+
153
+ @document = options[:document]
154
+ @direction = options[:direction] || @document.text_direction
155
+ @fallback_fonts = options[:fallback_fonts] ||
156
+ @document.fallback_fonts
157
+ @at = (
158
+ options[:at] || [@document.bounds.left, @document.bounds.top]
159
+ ).dup
160
+ @width = options[:width] ||
161
+ @document.bounds.right - @at[0]
162
+ @height = options[:height] || default_height
163
+ @align = options[:align] ||
164
+ (@direction == :rtl ? :right : :left)
165
+ @vertical_align = options[:valign] || :top
166
+ @leading = options[:leading] || @document.default_leading
211
167
  @character_spacing = options[:character_spacing] ||
212
- @document.character_spacing
213
- @mode = options[:mode] || @document.text_rendering_mode
214
- @rotate = options[:rotate] || 0
215
- @rotate_around = options[:rotate_around] || :upper_left
216
- @single_line = options[:single_line]
217
- @skip_encoding = options[:skip_encoding] || @document.skip_encoding
168
+ @document.character_spacing
169
+ @mode = options[:mode] || @document.text_rendering_mode
170
+ @rotate = options[:rotate] || 0
171
+ @rotate_around = options[:rotate_around] || :upper_left
172
+ @single_line = options[:single_line]
218
173
  @draw_text_callback = options[:draw_text_callback]
219
174
 
220
175
  # if the text rendering mode is :unknown, force it back to :fill
@@ -230,27 +185,30 @@ module Prawn
230
185
  @overflow = :truncate
231
186
  end
232
187
  @min_font_size = options[:min_font_size] || 5
233
- if options[:kerning].nil? then
188
+ if options[:kerning].nil?
234
189
  options[:kerning] = @document.default_kerning?
235
190
  end
236
- @options = { :kerning => options[:kerning],
237
- :size => options[:size],
238
- :style => options[:style] }
191
+ @options = {
192
+ kerning: options[:kerning],
193
+ size: options[:size],
194
+ style: options[:style]
195
+ }
239
196
 
240
197
  super(formatted_text, options)
241
198
  end
242
199
 
243
- # Render text to the document based on the settings defined in initialize.
200
+ # Render text to the document based on the settings defined in
201
+ # initialize.
244
202
  #
245
- # In order to facilitate look-ahead calculations, <tt>render</tt> accepts
246
- # a <tt>:dry_run => true</tt> option. If provided, then everything is
247
- # executed as if rendering, with the exception that nothing is drawn on
248
- # the page. Useful for look-ahead computations of height, unprinted text,
249
- # etc.
203
+ # In order to facilitate look-ahead calculations, <tt>render</tt>
204
+ # accepts a <tt>:dry_run => true</tt> option. If provided, then
205
+ # everything is executed as if rendering, with the exception that
206
+ # nothing is drawn on the page. Useful for look-ahead computations of
207
+ # height, unprinted text, etc.
250
208
  #
251
- # Returns any text that did not print under the current settings
209
+ # Returns any text that did not print under the current settings.
252
210
  #
253
- def render(flags={})
211
+ def render(flags = {})
254
212
  unprinted_text = []
255
213
 
256
214
  @document.save_font do
@@ -258,28 +216,27 @@ module Prawn
258
216
  @document.text_rendering_mode(@mode) do
259
217
  process_options
260
218
 
261
- if @skip_encoding
262
- text = original_text
263
- else
264
- text = normalize_encoding
265
- end
219
+ text = normalized_text(flags)
266
220
 
267
221
  @document.font_size(@font_size) do
268
222
  shrink_to_fit(text) if @overflow == :shrink_to_fit
269
223
  process_vertical_alignment(text)
270
224
  @inked = true unless flags[:dry_run]
271
- if @rotate != 0 && @inked
272
- unprinted_text = render_rotated(text)
273
- else
274
- unprinted_text = wrap(text)
275
- end
225
+ unprinted_text =
226
+ if @rotate != 0 && @inked
227
+ render_rotated(text)
228
+ else
229
+ wrap(text)
230
+ end
276
231
  @inked = false
277
232
  end
278
233
  end
279
234
  end
280
235
  end
281
236
 
282
- unprinted_text
237
+ unprinted_text.map do |e|
238
+ e.merge(text: @document.font.to_utf8(e[:text]))
239
+ end
283
240
  end
284
241
 
285
242
  # The width available at this point in the box
@@ -292,13 +249,16 @@ module Prawn
292
249
  #
293
250
  def height
294
251
  return 0 if @baseline_y.nil? || @descender.nil?
252
+
295
253
  (@baseline_y - @descender).abs
296
254
  end
297
255
 
298
256
  # <tt>fragment</tt> is a Prawn::Text::Formatted::Fragment object
299
257
  #
300
- def draw_fragment(fragment, accumulated_width=0, line_width=0, word_spacing=0) #:nodoc:
301
- case(@align)
258
+ def draw_fragment(
259
+ fragment, accumulated_width = 0, line_width = 0, word_spacing = 0
260
+ ) #:nodoc:
261
+ case @align
302
262
  when :left
303
263
  x = @at[0]
304
264
  when :center
@@ -306,11 +266,15 @@ module Prawn
306
266
  when :right
307
267
  x = @at[0] + @width - line_width
308
268
  when :justify
309
- if @direction == :ltr
310
- x = @at[0]
311
- else
312
- x = @at[0] + @width - line_width
313
- end
269
+ x =
270
+ if @direction == :ltr
271
+ @at[0]
272
+ else
273
+ @at[0] + @width - line_width
274
+ end
275
+ else
276
+ raise ArgumentError,
277
+ 'align must be one of :left, :right, :center or :justify symbols'
314
278
  end
315
279
 
316
280
  x += accumulated_width
@@ -325,24 +289,94 @@ module Prawn
325
289
  if @inked
326
290
  draw_fragment_underlays(fragment)
327
291
 
328
- @document.word_spacing(word_spacing) {
292
+ @document.word_spacing(word_spacing) do
329
293
  if @draw_text_callback
330
- @draw_text_callback.call(fragment.text, :at => [x, y],
331
- :kerning => @kerning)
294
+ @draw_text_callback.call(
295
+ fragment.text,
296
+ at: [x, y],
297
+ kerning: @kerning
298
+ )
332
299
  else
333
- @document.draw_text!(fragment.text, :at => [x, y],
334
- :kerning => @kerning)
300
+ @document.draw_text!(
301
+ fragment.text,
302
+ at: [x, y],
303
+ kerning: @kerning
304
+ )
335
305
  end
336
- }
306
+ end
337
307
 
338
308
  draw_fragment_overlays(fragment)
339
309
  end
340
310
  end
341
311
 
312
+ # @group Extension API
313
+
314
+ # Example (see Prawn::Text::Core::Formatted::Wrap for what is required
315
+ # of the wrap method if you want to override the default wrapping
316
+ # algorithm):
317
+ #
318
+ #
319
+ # module MyWrap
320
+ #
321
+ # def wrap(array)
322
+ # initialize_wrap([{ :text => 'all your base are belong to us' }])
323
+ # @line_wrap.wrap_line(:document => @document,
324
+ # :kerning => @kerning,
325
+ # :width => 10000,
326
+ # :arranger => @arranger)
327
+ # fragment = @arranger.retrieve_fragment
328
+ # format_and_draw_fragment(fragment, 0, @line_wrap.width, 0)
329
+ # []
330
+ # end
331
+ #
332
+ # end
333
+ #
334
+ # Prawn::Text::Formatted::Box.extensions << MyWrap
335
+ #
336
+ # box = Prawn::Text::Formatted::Box.new('hello world')
337
+ # box.render('why can't I print anything other than' +
338
+ # '"all your base are belong to us"?')
339
+ #
340
+ #
341
+ def self.extensions
342
+ @extensions ||= []
343
+ end
344
+
345
+ # @private
346
+ def self.inherited(base)
347
+ super
348
+ extensions.each { |e| base.extensions << e }
349
+ end
350
+
351
+ def valid_options
352
+ PDF::Core::Text::VALID_OPTIONS + %i[
353
+ at
354
+ height width
355
+ align valign
356
+ rotate rotate_around
357
+ overflow min_font_size
358
+ disable_wrap_by_char
359
+ leading character_spacing
360
+ mode single_line
361
+ document
362
+ direction
363
+ fallback_fonts
364
+ draw_text_callback
365
+ ]
366
+ end
367
+
342
368
  private
343
369
 
370
+ def normalized_text(flags)
371
+ text = normalize_encoding
372
+
373
+ text.each { |t| t.delete(:color) } if flags[:dry_run]
374
+
375
+ text
376
+ end
377
+
344
378
  def original_text
345
- @original_array.collect { |hash| hash.dup }
379
+ @original_array.map(&:dup)
346
380
  end
347
381
 
348
382
  def original_text=(formatted_text)
@@ -385,33 +419,41 @@ module Prawn
385
419
 
386
420
  original_font = @document.font.family
387
421
  fragment_font = hash[:font] || original_font
388
- @document.font(fragment_font)
389
422
 
390
423
  fallback_fonts = @fallback_fonts.dup
391
424
  # always default back to the current font if the glyph is missing from
392
425
  # all fonts
393
426
  fallback_fonts << fragment_font
394
427
 
395
- hash[:text].unicode_characters do |char|
396
- @document.font(fragment_font)
397
- font_glyph_pairs << [find_font_for_this_glyph(char,
398
- @document.font.family,
399
- fallback_fonts.dup),
400
- char]
428
+ @document.save_font do
429
+ hash[:text].each_char do |char|
430
+ font_glyph_pairs << [
431
+ find_font_for_this_glyph(
432
+ char,
433
+ fragment_font,
434
+ fallback_fonts.dup
435
+ ),
436
+ char
437
+ ]
438
+ end
401
439
  end
402
440
 
403
- @document.font(original_font)
441
+ # Don't add a :font to fragments if it wasn't there originally
442
+ if hash[:font].nil?
443
+ font_glyph_pairs.each do |pair|
444
+ pair[0] = nil if pair[0] == original_font
445
+ end
446
+ end
404
447
 
405
448
  form_fragments_from_like_font_glyph_pairs(font_glyph_pairs, hash)
406
449
  end
407
450
 
408
451
  def find_font_for_this_glyph(char, current_font, fallback_fonts)
409
- if fallback_fonts.length == 0 || @document.font.glyph_present?(char)
452
+ @document.font(current_font)
453
+ if fallback_fonts.empty? || @document.font.glyph_present?(char)
410
454
  current_font
411
455
  else
412
- current_font = fallback_fonts.shift
413
- @document.font(current_font)
414
- find_font_for_this_glyph(char, @document.font.family, fallback_fonts)
456
+ find_font_for_this_glyph(char, fallback_fonts.shift, fallback_fonts)
415
457
  end
416
458
  end
417
459
 
@@ -421,11 +463,11 @@ module Prawn
421
463
  current_font = nil
422
464
 
423
465
  font_glyph_pairs.each do |font, char|
424
- if font != current_font
466
+ if font != current_font || fragments.count.zero?
425
467
  current_font = font
426
468
  fragment = hash.dup
427
469
  fragment[:text] = char
428
- fragment[:font] = font
470
+ fragment[:font] = font unless font.nil?
429
471
  fragments << fragment
430
472
  else
431
473
  fragment[:text] += char
@@ -436,8 +478,8 @@ module Prawn
436
478
  end
437
479
 
438
480
  def move_baseline_down
439
- if @baseline_y == 0
440
- @baseline_y = -@ascender
481
+ if @baseline_y.zero?
482
+ @baseline_y = -@ascender
441
483
  else
442
484
  @baseline_y -= (@line_height + @leading)
443
485
  end
@@ -461,38 +503,55 @@ module Prawn
461
503
  # we need to wait until render() is called so that the fonts are set
462
504
  # up properly for wrapping. So guard with a boolean to ensure this is
463
505
  # only run once.
464
- return if defined?(@vertical_alignment_processed) && @vertical_alignment_processed
506
+ if defined?(@vertical_alignment_processed) &&
507
+ @vertical_alignment_processed
508
+ return
509
+ end
510
+
465
511
  @vertical_alignment_processed = true
466
512
 
467
513
  return if @vertical_align == :top
514
+
468
515
  wrap(text)
469
516
 
470
517
  case @vertical_align
471
518
  when :center
472
- @at[1] = @at[1] - (@height - height) * 0.5
519
+ @at[1] -= (@height - height + @descender) * 0.5
473
520
  when :bottom
474
- @at[1] = @at[1] - (@height - height) + @descender
521
+ @at[1] -= (@height - height)
475
522
  end
523
+
476
524
  @height = height
477
525
  end
478
526
 
479
527
  # Decrease the font size until the text fits or the min font
480
528
  # size is reached
481
529
  def shrink_to_fit(text)
482
- wrap(text)
483
- until @everything_printed || @font_size <= @min_font_size
530
+ loop do
531
+ if @disable_wrap_by_char && @font_size > @min_font_size
532
+ begin
533
+ wrap(text)
534
+ rescue Errors::CannotFit
535
+ # Ignore errors while we can still attempt smaller
536
+ # font sizes.
537
+ end
538
+ else
539
+ wrap(text)
540
+ end
541
+
542
+ break if @everything_printed || @font_size <= @min_font_size
543
+
484
544
  @font_size = [@font_size - 0.5, @min_font_size].max
485
545
  @document.font_size = @font_size
486
- wrap(text)
487
546
  end
488
547
  end
489
548
 
490
549
  def process_options
491
- # must be performed within a save_font bock because
550
+ # must be performed within a save_font block because
492
551
  # document.process_text_options sets the font
493
552
  @document.process_text_options(@options)
494
553
  @font_size = @options[:size]
495
- @kerning = @options[:kerning]
554
+ @kerning = @options[:kerning]
496
555
  end
497
556
 
498
557
  def render_rotated(text)
@@ -516,7 +575,7 @@ module Prawn
516
575
  y = @at[1]
517
576
  end
518
577
 
519
- @document.rotate(@rotate, :origin => [x, y]) do
578
+ @document.rotate(@rotate, origin: [x, y]) do
520
579
  unprinted_text = wrap(text)
521
580
  end
522
581
  unprinted_text
@@ -540,47 +599,56 @@ module Prawn
540
599
 
541
600
  def draw_fragment_overlay_link(fragment)
542
601
  return unless fragment.link
602
+
543
603
  box = fragment.absolute_bounding_box
544
- @document.link_annotation(box,
545
- :Border => [0, 0, 0],
546
- :A => { :Type => :Action,
547
- :S => :URI,
548
- :URI => PDF::Core::LiteralString.new(fragment.link) })
604
+ @document.link_annotation(
605
+ box,
606
+ Border: [0, 0, 0],
607
+ A: {
608
+ Type: :Action,
609
+ S: :URI,
610
+ URI: PDF::Core::LiteralString.new(fragment.link)
611
+ }
612
+ )
549
613
  end
550
614
 
551
615
  def draw_fragment_overlay_anchor(fragment)
552
616
  return unless fragment.anchor
617
+
553
618
  box = fragment.absolute_bounding_box
554
- @document.link_annotation(box,
555
- :Border => [0, 0, 0],
556
- :Dest => fragment.anchor)
619
+ @document.link_annotation(
620
+ box,
621
+ Border: [0, 0, 0],
622
+ Dest: fragment.anchor
623
+ )
557
624
  end
558
625
 
559
626
  def draw_fragment_overlay_local(fragment)
560
627
  return unless fragment.local
628
+
561
629
  box = fragment.absolute_bounding_box
562
- @document.link_annotation(box,
563
- :Border => [0, 0, 0],
564
- :A => { :Type => :Action,
565
- :S => :Launch,
566
- :F => PDF::Core::LiteralString.new(fragment.local),
567
- :NewWindow => true })
630
+ @document.link_annotation(
631
+ box,
632
+ Border: [0, 0, 0],
633
+ A: {
634
+ Type: :Action,
635
+ S: :Launch,
636
+ F: PDF::Core::LiteralString.new(fragment.local),
637
+ NewWindow: true
638
+ }
639
+ )
568
640
  end
569
641
 
570
642
  def draw_fragment_overlay_styles(fragment)
571
- underline = fragment.styles.include?(:underline)
572
- if underline
643
+ if fragment.styles.include?(:underline)
573
644
  @document.stroke_line(fragment.underline_points)
574
645
  end
575
646
 
576
- strikethrough = fragment.styles.include?(:strikethrough)
577
- if strikethrough
647
+ if fragment.styles.include?(:strikethrough)
578
648
  @document.stroke_line(fragment.strikethrough_points)
579
649
  end
580
650
  end
581
-
582
651
  end
583
-
584
652
  end
585
653
  end
586
654
  end