hexapdf 0.23.0 → 0.24.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 (243) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/LICENSE +1 -1
  4. data/Rakefile +1 -1
  5. data/examples/016-frame_automatic_box_placement.rb +7 -2
  6. data/examples/017-frame_text_flow.rb +10 -18
  7. data/examples/020-column_box.rb +40 -0
  8. data/examples/021-list_box.rb +26 -0
  9. data/lib/hexapdf/cli/batch.rb +1 -1
  10. data/lib/hexapdf/cli/command.rb +1 -1
  11. data/lib/hexapdf/cli/files.rb +1 -1
  12. data/lib/hexapdf/cli/fonts.rb +1 -1
  13. data/lib/hexapdf/cli/form.rb +2 -2
  14. data/lib/hexapdf/cli/image2pdf.rb +1 -1
  15. data/lib/hexapdf/cli/images.rb +1 -1
  16. data/lib/hexapdf/cli/info.rb +2 -2
  17. data/lib/hexapdf/cli/inspect.rb +2 -2
  18. data/lib/hexapdf/cli/merge.rb +1 -1
  19. data/lib/hexapdf/cli/modify.rb +1 -1
  20. data/lib/hexapdf/cli/optimize.rb +1 -1
  21. data/lib/hexapdf/cli/split.rb +1 -1
  22. data/lib/hexapdf/cli/watermark.rb +1 -1
  23. data/lib/hexapdf/cli.rb +1 -1
  24. data/lib/hexapdf/composer.rb +45 -126
  25. data/lib/hexapdf/configuration.rb +17 -1
  26. data/lib/hexapdf/content/canvas.rb +1 -1
  27. data/lib/hexapdf/content/color_space.rb +1 -1
  28. data/lib/hexapdf/content/graphic_object/arc.rb +1 -1
  29. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
  30. data/lib/hexapdf/content/graphic_object/geom2d.rb +2 -1
  31. data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
  32. data/lib/hexapdf/content/graphic_object.rb +1 -1
  33. data/lib/hexapdf/content/graphics_state.rb +1 -1
  34. data/lib/hexapdf/content/operator.rb +1 -1
  35. data/lib/hexapdf/content/parser.rb +1 -1
  36. data/lib/hexapdf/content/processor.rb +1 -1
  37. data/lib/hexapdf/content/transformation_matrix.rb +1 -1
  38. data/lib/hexapdf/content.rb +1 -1
  39. data/lib/hexapdf/data_dir.rb +1 -1
  40. data/lib/hexapdf/dictionary.rb +1 -1
  41. data/lib/hexapdf/dictionary_fields.rb +1 -1
  42. data/lib/hexapdf/document/files.rb +1 -1
  43. data/lib/hexapdf/document/fonts.rb +1 -1
  44. data/lib/hexapdf/document/images.rb +1 -1
  45. data/lib/hexapdf/document/layout.rb +397 -0
  46. data/lib/hexapdf/document/pages.rb +17 -1
  47. data/lib/hexapdf/document/signatures.rb +5 -4
  48. data/lib/hexapdf/document.rb +8 -1
  49. data/lib/hexapdf/encryption/aes.rb +1 -1
  50. data/lib/hexapdf/encryption/arc4.rb +1 -1
  51. data/lib/hexapdf/encryption/fast_aes.rb +1 -1
  52. data/lib/hexapdf/encryption/fast_arc4.rb +30 -21
  53. data/lib/hexapdf/encryption/identity.rb +1 -1
  54. data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
  55. data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
  56. data/lib/hexapdf/encryption/security_handler.rb +1 -1
  57. data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
  58. data/lib/hexapdf/encryption.rb +1 -1
  59. data/lib/hexapdf/error.rb +1 -1
  60. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  61. data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
  62. data/lib/hexapdf/filter/crypt.rb +1 -1
  63. data/lib/hexapdf/filter/encryption.rb +1 -1
  64. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  65. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  66. data/lib/hexapdf/filter/pass_through.rb +1 -1
  67. data/lib/hexapdf/filter/predictor.rb +1 -1
  68. data/lib/hexapdf/filter/run_length_decode.rb +1 -1
  69. data/lib/hexapdf/filter.rb +1 -1
  70. data/lib/hexapdf/font/cmap/parser.rb +1 -1
  71. data/lib/hexapdf/font/cmap/writer.rb +1 -1
  72. data/lib/hexapdf/font/cmap.rb +1 -1
  73. data/lib/hexapdf/font/encoding/base.rb +1 -1
  74. data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
  75. data/lib/hexapdf/font/encoding/glyph_list.rb +2 -2
  76. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
  77. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
  78. data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
  79. data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
  80. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
  81. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
  82. data/lib/hexapdf/font/encoding.rb +1 -1
  83. data/lib/hexapdf/font/invalid_glyph.rb +1 -1
  84. data/lib/hexapdf/font/true_type/builder.rb +1 -1
  85. data/lib/hexapdf/font/true_type/font.rb +1 -1
  86. data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
  87. data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
  88. data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
  89. data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
  90. data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
  91. data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
  92. data/lib/hexapdf/font/true_type/table/head.rb +1 -1
  93. data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
  94. data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
  95. data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
  96. data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
  97. data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
  98. data/lib/hexapdf/font/true_type/table/name.rb +1 -1
  99. data/lib/hexapdf/font/true_type/table/os2.rb +1 -1
  100. data/lib/hexapdf/font/true_type/table/post.rb +1 -1
  101. data/lib/hexapdf/font/true_type/table.rb +1 -1
  102. data/lib/hexapdf/font/true_type.rb +1 -1
  103. data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
  104. data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
  105. data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
  106. data/lib/hexapdf/font/type1/font.rb +1 -1
  107. data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
  108. data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
  109. data/lib/hexapdf/font/type1.rb +1 -1
  110. data/lib/hexapdf/font/type1_wrapper.rb +1 -1
  111. data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
  112. data/lib/hexapdf/font_loader/from_file.rb +1 -1
  113. data/lib/hexapdf/font_loader/standard14.rb +1 -1
  114. data/lib/hexapdf/font_loader.rb +1 -1
  115. data/lib/hexapdf/image_loader/jpeg.rb +1 -1
  116. data/lib/hexapdf/image_loader/pdf.rb +1 -1
  117. data/lib/hexapdf/image_loader/png.rb +1 -1
  118. data/lib/hexapdf/image_loader.rb +1 -1
  119. data/lib/hexapdf/importer.rb +1 -1
  120. data/lib/hexapdf/layout/box.rb +121 -22
  121. data/lib/hexapdf/layout/box_fitter.rb +136 -0
  122. data/lib/hexapdf/layout/column_box.rb +247 -0
  123. data/lib/hexapdf/layout/frame.rb +155 -139
  124. data/lib/hexapdf/layout/image_box.rb +19 -4
  125. data/lib/hexapdf/layout/inline_box.rb +1 -1
  126. data/lib/hexapdf/layout/line.rb +1 -1
  127. data/lib/hexapdf/layout/list_box.rb +355 -0
  128. data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
  129. data/lib/hexapdf/layout/style.rb +5 -1
  130. data/lib/hexapdf/layout/text_box.rb +20 -9
  131. data/lib/hexapdf/layout/text_fragment.rb +3 -2
  132. data/lib/hexapdf/layout/text_layouter.rb +17 -2
  133. data/lib/hexapdf/layout/text_shaper.rb +1 -1
  134. data/lib/hexapdf/layout/width_from_polygon.rb +12 -7
  135. data/lib/hexapdf/layout.rb +4 -1
  136. data/lib/hexapdf/name_tree_node.rb +1 -1
  137. data/lib/hexapdf/number_tree_node.rb +1 -1
  138. data/lib/hexapdf/object.rb +1 -1
  139. data/lib/hexapdf/parser.rb +1 -8
  140. data/lib/hexapdf/pdf_array.rb +1 -1
  141. data/lib/hexapdf/rectangle.rb +1 -1
  142. data/lib/hexapdf/reference.rb +1 -1
  143. data/lib/hexapdf/revision.rb +1 -1
  144. data/lib/hexapdf/revisions.rb +1 -1
  145. data/lib/hexapdf/serializer.rb +1 -1
  146. data/lib/hexapdf/stream.rb +1 -1
  147. data/lib/hexapdf/task/dereference.rb +1 -1
  148. data/lib/hexapdf/task/optimize.rb +1 -1
  149. data/lib/hexapdf/task.rb +1 -1
  150. data/lib/hexapdf/tokenizer.rb +1 -1
  151. data/lib/hexapdf/type/acro_form/appearance_generator.rb +1 -1
  152. data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
  153. data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
  154. data/lib/hexapdf/type/acro_form/field.rb +1 -1
  155. data/lib/hexapdf/type/acro_form/form.rb +1 -1
  156. data/lib/hexapdf/type/acro_form/signature_field.rb +1 -1
  157. data/lib/hexapdf/type/acro_form/text_field.rb +1 -1
  158. data/lib/hexapdf/type/acro_form/variable_text_field.rb +1 -1
  159. data/lib/hexapdf/type/acro_form.rb +1 -1
  160. data/lib/hexapdf/type/action.rb +1 -1
  161. data/lib/hexapdf/type/actions/go_to.rb +1 -1
  162. data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
  163. data/lib/hexapdf/type/actions/launch.rb +1 -1
  164. data/lib/hexapdf/type/actions/uri.rb +1 -1
  165. data/lib/hexapdf/type/actions.rb +1 -1
  166. data/lib/hexapdf/type/annotation.rb +1 -1
  167. data/lib/hexapdf/type/annotations/link.rb +1 -1
  168. data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
  169. data/lib/hexapdf/type/annotations/text.rb +1 -1
  170. data/lib/hexapdf/type/annotations/widget.rb +1 -1
  171. data/lib/hexapdf/type/annotations.rb +1 -1
  172. data/lib/hexapdf/type/catalog.rb +1 -1
  173. data/lib/hexapdf/type/cid_font.rb +1 -1
  174. data/lib/hexapdf/type/embedded_file.rb +1 -1
  175. data/lib/hexapdf/type/file_specification.rb +1 -1
  176. data/lib/hexapdf/type/font.rb +1 -1
  177. data/lib/hexapdf/type/font_descriptor.rb +1 -1
  178. data/lib/hexapdf/type/font_simple.rb +1 -1
  179. data/lib/hexapdf/type/font_true_type.rb +1 -1
  180. data/lib/hexapdf/type/font_type0.rb +1 -1
  181. data/lib/hexapdf/type/font_type1.rb +1 -1
  182. data/lib/hexapdf/type/font_type3.rb +1 -1
  183. data/lib/hexapdf/type/form.rb +1 -1
  184. data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
  185. data/lib/hexapdf/type/icon_fit.rb +1 -1
  186. data/lib/hexapdf/type/image.rb +1 -1
  187. data/lib/hexapdf/type/info.rb +1 -1
  188. data/lib/hexapdf/type/names.rb +1 -1
  189. data/lib/hexapdf/type/object_stream.rb +1 -1
  190. data/lib/hexapdf/type/page.rb +1 -1
  191. data/lib/hexapdf/type/page_tree_node.rb +19 -2
  192. data/lib/hexapdf/type/resources.rb +1 -1
  193. data/lib/hexapdf/type/signature/adbe_pkcs7_detached.rb +1 -1
  194. data/lib/hexapdf/type/signature/adbe_x509_rsa_sha1.rb +1 -1
  195. data/lib/hexapdf/type/signature/handler.rb +1 -1
  196. data/lib/hexapdf/type/signature/verification_result.rb +1 -1
  197. data/lib/hexapdf/type/signature.rb +1 -1
  198. data/lib/hexapdf/type/trailer.rb +2 -2
  199. data/lib/hexapdf/type/viewer_preferences.rb +1 -1
  200. data/lib/hexapdf/type/xref_stream.rb +1 -1
  201. data/lib/hexapdf/type.rb +1 -1
  202. data/lib/hexapdf/utils/bit_field.rb +1 -1
  203. data/lib/hexapdf/utils/bit_stream.rb +1 -1
  204. data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
  205. data/lib/hexapdf/utils/lru_cache.rb +1 -1
  206. data/lib/hexapdf/utils/math_helpers.rb +1 -1
  207. data/lib/hexapdf/utils/object_hash.rb +1 -1
  208. data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
  209. data/lib/hexapdf/utils/sorted_tree_node.rb +1 -1
  210. data/lib/hexapdf/version.rb +2 -2
  211. data/lib/hexapdf/writer.rb +9 -7
  212. data/lib/hexapdf/xref_section.rb +1 -1
  213. data/lib/hexapdf.rb +1 -1
  214. data/test/hexapdf/content/graphic_object/test_geom2d.rb +1 -1
  215. data/test/hexapdf/document/test_destinations.rb +1 -1
  216. data/test/hexapdf/document/test_images.rb +1 -1
  217. data/test/hexapdf/document/test_layout.rb +264 -0
  218. data/test/hexapdf/document/test_pages.rb +9 -0
  219. data/test/hexapdf/document/test_signatures.rb +10 -3
  220. data/test/hexapdf/encryption/test_security_handler.rb +1 -1
  221. data/test/hexapdf/font/encoding/test_glyph_list.rb +4 -0
  222. data/test/hexapdf/layout/test_box.rb +53 -3
  223. data/test/hexapdf/layout/test_box_fitter.rb +62 -0
  224. data/test/hexapdf/layout/test_column_box.rb +159 -0
  225. data/test/hexapdf/layout/test_frame.rb +99 -38
  226. data/test/hexapdf/layout/test_image_box.rb +1 -1
  227. data/test/hexapdf/layout/test_list_box.rb +249 -0
  228. data/test/hexapdf/layout/test_text_box.rb +17 -2
  229. data/test/hexapdf/layout/test_text_fragment.rb +1 -1
  230. data/test/hexapdf/layout/test_text_layouter.rb +42 -17
  231. data/test/hexapdf/layout/test_width_from_polygon.rb +13 -0
  232. data/test/hexapdf/test_composer.rb +11 -0
  233. data/test/hexapdf/test_dictionary_fields.rb +9 -9
  234. data/test/hexapdf/test_document.rb +4 -4
  235. data/test/hexapdf/test_filter.rb +1 -1
  236. data/test/hexapdf/test_parser.rb +0 -2
  237. data/test/hexapdf/test_revisions.rb +2 -2
  238. data/test/hexapdf/test_serializer.rb +1 -5
  239. data/test/hexapdf/test_writer.rb +58 -3
  240. data/test/hexapdf/type/test_page_tree_node.rb +21 -1
  241. data/test/hexapdf/type/test_trailer.rb +3 -3
  242. data/test/test_helper.rb +5 -1
  243. metadata +28 -3
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -58,24 +58,6 @@ module HexaPDF
58
58
  # page. Behind the scenes HexaPDF::Layout::Box (and subclass) objects are created and drawn on the
59
59
  # page via the frame.
60
60
  #
61
- # All drawing methods accept HexaPDF::Layout::Style objects or names for style objects (defined
62
- # via #style). The HexaPDF::Layout::Style#font is handled specially:
63
- #
64
- # * If no font is set on a style, the font "Times" is automatically set because otherwise there
65
- # would be problems with text drawing operations (font is the only style property that has no
66
- # valid default value).
67
- #
68
- # * Standard style objects only allow font wrapper objects to be set via the
69
- # HexaPDF::Layout::Style#font method. Composer makes usage easier by allowing strings or an
70
- # array [name, options_hash] to be used, like with e.g Content::Canvas. So using Helvetica as
71
- # font, one could just do this by saying
72
- #
73
- # style.font = 'Helvetica'
74
- #
75
- # And if Helvetica bold should be used it would be
76
- #
77
- # style.font = ['Helvetica', variant: :bold]
78
- #
79
61
  # If the frame of a page is full and a box doesn't fit anymore, a new page is automatically
80
62
  # created. The box is either split into two boxes where one fits on the first page and the other
81
63
  # on the new page, or it is drawn completely on the new page. A new page can also be created by
@@ -146,7 +128,6 @@ module HexaPDF
146
128
  @page_size = page_size
147
129
  @page_orientation = page_orientation
148
130
  @margin = Layout::Style::Quad.new(margin)
149
- @styles = {base: Layout::Style.new}
150
131
 
151
132
  new_page
152
133
  yield(self) if block_given?
@@ -189,24 +170,14 @@ module HexaPDF
189
170
  end
190
171
 
191
172
  # :call-seq:
192
- # composer.style(:header) -> style
193
- # composer.style(:header, base: :base, **properties) -> style
173
+ # composer.style(name) -> style
174
+ # composer.style(name, base: :base, **properties) -> style
194
175
  #
195
176
  # Creates or updates the HexaPDF::Layout::Style object called +name+ with the given property
196
- # values and returns it. Such a style can then be used by name in the various box drawing
197
- # methods, e.g. #text or #image.
198
- #
199
- # If neither +base+ nor any style properties are specified, the style +name+ is just returned.
200
- #
201
- # If the style +name+ does not exist yet and the argument +base+ specifies the name of another
202
- # style, that style is duplicated and used as basis for the style.
177
+ # values and returns it.
203
178
  #
204
- # The special name :base should be used for setting the base style which is used when no
205
- # specific style is set. It is best to fully initialize the base style before creating any
206
- # other styles.
207
- #
208
- # Note that the style property 'font' is handled specially by Composer, see the class
209
- # documentation for details.
179
+ # See HexaPDF::Document::Layout#style for details; this method is just a thin wrapper around
180
+ # that method.
210
181
  #
211
182
  # Example:
212
183
  #
@@ -216,35 +187,20 @@ module HexaPDF
216
187
  #
217
188
  # See: HexaPDF::Layout::Style
218
189
  def style(name, base: :base, **properties)
219
- style = @styles[name] ||= (@styles.key?(base) ? @styles[base].dup : Layout::Style.new)
220
- style.update(**properties) unless properties.empty?
221
- style
190
+ @document.layout.style(name, base: base, **properties)
222
191
  end
223
192
 
224
193
  # Draws the given text at the current position into the current frame.
225
194
  #
226
- # This method is the main method for displaying text on a PDF page. It uses a
227
- # HexaPDF::Layout::TextBox behind the scenes to do the actual work.
228
- #
229
195
  # The text will be positioned at the current position if possible. Otherwise the next best
230
196
  # position is used. If the text doesn't fit onto the current page or only partially, new pages
231
197
  # are created automatically.
232
198
  #
233
- # +width+, +height+::
234
- # The arguments +width+ and +height+ are used as constraints and are respected when fitting
235
- # the box. The default value of 0 means that no constraints are set.
199
+ # This method is of the two main methods for creating text boxes, the other being
200
+ # #formatted_text. It uses HexaPDF::Document::Layout#text_box behind the scenes to create the
201
+ # HexaPDF::Layout::TextBox that does the actual work.
236
202
  #
237
- # +style+, +style_properties+::
238
- # The box and the text are styled using the given +style+. This can either be a style name
239
- # set via #style or anything HexaPDF::Layout::Style::create accepts. If any additional
240
- # +style_properties+ are specified, the style is duplicated and the additional styles are
241
- # applied.
242
- #
243
- # +box_style+::
244
- # Sometimes it is necessary for the box to have a different style than the text, e.g. when
245
- # using overlays. In such a case use +box_style+ for specifiying the style of the box (a
246
- # style name set via #style or anything HexaPDF::Layout::Style::create accepts). The +style+
247
- # together with the +style_properties+ will be used for the text style.
203
+ # See HexaPDF::Document::Layout#text_box for details on the arguments.
248
204
  #
249
205
  # Examples:
250
206
  #
@@ -255,35 +211,16 @@ module HexaPDF
255
211
  # composer.text("Different box style", fill_color: 'white', box_style: {
256
212
  # underlays: [->(c, b) { c.rectangle(0, 0, b.content_width, b.content_height).fill }]
257
213
  # })
258
- #
259
- # See HexaPDF::HexaPDF::Layout::TextBox for details.
260
214
  def text(str, width: 0, height: 0, style: nil, box_style: nil, **style_properties)
261
- style = retrieve_style(style, style_properties)
262
- box_style = (box_style ? retrieve_style(box_style) : style)
263
- draw_box(Layout::TextBox.new([Layout::TextFragment.create(str, style)],
264
- width: width, height: height, style: box_style))
215
+ draw_box(@document.layout.text_box(str, width: width, height: height, style: style,
216
+ box_style: box_style, **style_properties))
265
217
  end
266
218
 
267
219
  # Draws text like #text but allows parts of the text to be formatted differently.
268
220
  #
269
- # The argument +data+ needs to be an array of String and/or Hash objects:
270
- #
271
- # * A String object is treated like {text: data}.
272
- #
273
- # * Hashes can contain any style properties and the following special keys:
274
- #
275
- # text:: The text to be formatted.
276
- #
277
- # link:: A URL that should be linked to. If no text is provided but a link, the link is used
278
- # as text.
279
- #
280
- # style:: The style to be use as basis instead of the style created from the +style+ and
281
- # +style_properties+ arguments. See HexaPDF::Layout::Style::create for allowed values.
282
- #
283
- # If any style properties are set, the used style is copied and the additional properties
284
- # applied.
285
- #
286
- # See #text for details on +width+, +height+, +style+, +style_properties+ and +box_style+.
221
+ # It uses HexaPDF::Document::Layout#formatted_text_box behind the scenes to create the
222
+ # HexaPDF::Layout::TextBox that does the actual work. See that method for details on the
223
+ # arguments.
287
224
  #
288
225
  # Examples:
289
226
  #
@@ -296,37 +233,41 @@ module HexaPDF
296
233
  #
297
234
  # See: #text, HexaPDF::Layout::TextBox, HexaPDF::Layout::TextFragment
298
235
  def formatted_text(data, width: 0, height: 0, style: nil, box_style: nil, **style_properties)
299
- style = retrieve_style(style, style_properties)
300
- box_style = (box_style ? retrieve_style(box_style) : style)
301
- data.map! do |hash|
302
- if hash.kind_of?(String)
303
- Layout::TextFragment.create(hash, style)
304
- else
305
- link = hash.delete(:link)
306
- (hash[:overlays] ||= []) << [:link, {uri: link}] if link
307
- text = hash.delete(:text) || link || ""
308
- Layout::TextFragment.create(text, retrieve_style(hash.delete(:style) || style, hash))
309
- end
310
- end
311
- draw_box(Layout::TextBox.new(data, width: width, height: height, style: box_style))
236
+ draw_box(@document.layout.formatted_text_box(data, width: width, height: height, style: style,
237
+ box_style: box_style, **style_properties))
312
238
  end
313
239
 
314
240
  # Draws the given image at the current position.
315
241
  #
316
- # The +file+ argument can be anything that is accepted by HexaPDF::Document::Images#add or a
317
- # HexaPDF::Type::Form object.
318
- #
319
- # See #text for details on +width+, +height+, +style+ and +style_properties+.
242
+ # It uses HexaPDF::Document::Layout#image_box behind the scenes to create the
243
+ # HexaPDF::Layout::ImageBox that does the actual work. See that method for details on the
244
+ # arguments.
320
245
  #
321
246
  # Examples:
322
247
  #
323
248
  # #>pdf-composer
324
249
  # composer.image(machu_picchu, border: {width: 3})
325
250
  # composer.image(machu_picchu, height: 30)
251
+ #
252
+ # See: HexaPDF::Layout::ImageBox
326
253
  def image(file, width: 0, height: 0, style: nil, **style_properties)
327
- style = retrieve_style(style, style_properties)
328
- image = file.kind_of?(HexaPDF::Stream) ? file : document.images.add(file)
329
- draw_box(Layout::ImageBox.new(image, width: width, height: height, style: style))
254
+ draw_box(@document.layout.image_box(file, width: width, height: height,
255
+ style: style, **style_properties))
256
+ end
257
+
258
+ # Draws the named box at the current position.
259
+ #
260
+ # It uses HexaPDF::Document::Layout#box behind the scenes to create the named box. See that
261
+ # method for details on the arguments.
262
+ #
263
+ # Examples:
264
+ #
265
+ # #>pdf-composer
266
+ # composer.box(:image, image: composer.document.images.add(machu_picchu))
267
+ #
268
+ # See: HexaPDF::Document::Layout#box
269
+ def box(name, width: 0, height: 0, style: nil, **box_options, &block)
270
+ draw_box(@document.layout.box(name, width: width, height: height, style: style, **box_options, &block))
330
271
  end
331
272
 
332
273
  # Draws the given HexaPDF::Layout::Box.
@@ -340,16 +281,17 @@ module HexaPDF
340
281
  def draw_box(box)
341
282
  drawn_on_page = true
342
283
  while true
343
- if @frame.fit(box)
344
- @frame.draw(@canvas, box)
284
+ result = @frame.fit(box)
285
+ if result.success?
286
+ @frame.draw(@canvas, result)
345
287
  break
346
288
  elsif @frame.full?
347
289
  new_page
348
290
  drawn_on_page = false
349
291
  else
350
- draw_box, box = @frame.split(box)
292
+ draw_box, box = @frame.split(result)
351
293
  if draw_box
352
- @frame.draw(@canvas, draw_box)
294
+ @frame.draw(@canvas, result)
353
295
  drawn_on_page = true
354
296
  elsif !@frame.find_next_region
355
297
  unless drawn_on_page
@@ -394,29 +336,6 @@ module HexaPDF
394
336
  media_box.height - @margin.bottom - @margin.top)
395
337
  end
396
338
 
397
- # Retrieves the appropriate HexaPDF::Layout::Style object based on the +style+ and +properties+
398
- # arguments.
399
- #
400
- # The +style+ argument specifies the style to retrieve. It can either be a registered style name
401
- # (see #style), a hash with style properties or +nil+. In the latter case the registered style
402
- # :base is used
403
- #
404
- # If the +properties+ hash is not empty, the retrieved style is duplicated and the properties
405
- # hash is applied to it.
406
- #
407
- # Finally, a default font is set if necessary to ensure that the style object works in all
408
- # cases.
409
- def retrieve_style(style, properties = nil)
410
- style = Layout::Style.create(@styles[style] || style || @styles[:base])
411
- style = style.dup.update(**properties) unless properties.nil? || properties.empty?
412
- style.font('Times') unless style.font?
413
- unless style.font.respond_to?(:pdf_object)
414
- name, options = *style.font
415
- style.font(@document.fonts.add(name, **(options || {})))
416
- end
417
- style
418
- end
419
-
420
339
  end
421
340
 
422
341
  end
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -193,6 +193,9 @@ module HexaPDF
193
193
  # acro_form.text_field.default_width::
194
194
  # A number specifying the default width of AcroForm text fields which should be auto-sized.
195
195
  #
196
+ # debug::
197
+ # If set to +true+, enables debug output.
198
+ #
196
199
  # document.auto_decrypt::
197
200
  # A boolean determining whether the document should be decrypted automatically when parsed.
198
201
  #
@@ -337,6 +340,12 @@ module HexaPDF
337
340
  # This can be used to limit the memory needed for reading or writing PDF files with huge
338
341
  # stream objects.
339
342
  #
343
+ # layout.boxes.map::
344
+ # A mapping from layout box names to box classes. If the value is a String, it should contain
345
+ # the name of a constant to such a class.
346
+ #
347
+ # See HexaPDF::Layout::Box for more information.
348
+ #
340
349
  # page.default_media_box::
341
350
  # The media box that is used for new pages that don't define a media box. Default value is
342
351
  # A4. See HexaPDF::Type::Page::PAPER_SIZE for a list of predefined paper sizes.
@@ -403,6 +412,7 @@ module HexaPDF
403
412
  "#{field.concrete_field_type} field #{field.full_field_name}"
404
413
  end,
405
414
  'acro_form.text_field.default_width' => 100,
415
+ 'debug' => false,
406
416
  'document.auto_decrypt' => true,
407
417
  'document.on_invalid_string' => proc do |str|
408
418
  str.encode(Encoding::UTF_8, invalid: :replace, replace: '')
@@ -461,6 +471,12 @@ module HexaPDF
461
471
  ],
462
472
  'image_loader.pdf.use_stringio' => true,
463
473
  'io.chunk_size' => 2**16,
474
+ 'layout.boxes.map' => {
475
+ text: 'HexaPDF::Layout::TextBox',
476
+ image: 'HexaPDF::Layout::ImageBox',
477
+ column: 'HexaPDF::Layout::ColumnBox',
478
+ list: 'HexaPDF::Layout::ListBox',
479
+ },
464
480
  'page.default_media_box' => :A4,
465
481
  'page.default_media_orientation' => :portrait,
466
482
  'parser.on_correctable_error' => proc { false },
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -128,6 +128,7 @@ module HexaPDF
128
128
  return unless @object.nr_of_vertices > 1
129
129
  canvas.move_to(@object[0].x, @object[0].y)
130
130
  1.upto(@object.nr_of_vertices - 1) {|i| canvas.line_to(@object[i].x, @object[i].y) }
131
+ canvas.close_subpath
131
132
  canvas.stroke unless @path_only
132
133
  end
133
134
 
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as
@@ -4,7 +4,7 @@
4
4
  # This file is part of HexaPDF.
5
5
  #
6
6
  # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
- # Copyright (C) 2014-2021 Thomas Leitner
7
+ # Copyright (C) 2014-2022 Thomas Leitner
8
8
  #
9
9
  # HexaPDF is free software: you can redistribute it and/or modify it
10
10
  # under the terms of the GNU Affero General Public License version 3 as