hexapdf 0.15.9 → 0.17.2

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 (216) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +62 -0
  3. data/LICENSE +1 -1
  4. data/README.md +11 -2
  5. data/Rakefile +2 -1
  6. data/examples/002-graphics.rb +4 -4
  7. data/lib/hexapdf/cli/batch.rb +1 -1
  8. data/lib/hexapdf/cli/command.rb +10 -1
  9. data/lib/hexapdf/cli/files.rb +1 -1
  10. data/lib/hexapdf/cli/fonts.rb +145 -0
  11. data/lib/hexapdf/cli/form.rb +27 -26
  12. data/lib/hexapdf/cli/image2pdf.rb +1 -1
  13. data/lib/hexapdf/cli/images.rb +1 -10
  14. data/lib/hexapdf/cli/info.rb +1 -1
  15. data/lib/hexapdf/cli/inspect.rb +1 -1
  16. data/lib/hexapdf/cli/merge.rb +1 -1
  17. data/lib/hexapdf/cli/modify.rb +1 -1
  18. data/lib/hexapdf/cli/optimize.rb +1 -1
  19. data/lib/hexapdf/cli/split.rb +1 -1
  20. data/lib/hexapdf/cli/watermark.rb +1 -1
  21. data/lib/hexapdf/cli.rb +3 -1
  22. data/lib/hexapdf/composer.rb +1 -1
  23. data/lib/hexapdf/configuration.rb +11 -2
  24. data/lib/hexapdf/content/canvas.rb +658 -167
  25. data/lib/hexapdf/content/color_space.rb +185 -3
  26. data/lib/hexapdf/content/graphic_object/arc.rb +111 -12
  27. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +67 -1
  28. data/lib/hexapdf/content/graphic_object/geom2d.rb +14 -1
  29. data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
  30. data/lib/hexapdf/content/graphic_object.rb +1 -1
  31. data/lib/hexapdf/content/graphics_state.rb +1 -1
  32. data/lib/hexapdf/content/operator.rb +1 -1
  33. data/lib/hexapdf/content/parser.rb +1 -1
  34. data/lib/hexapdf/content/processor.rb +1 -1
  35. data/lib/hexapdf/content/transformation_matrix.rb +1 -1
  36. data/lib/hexapdf/content.rb +1 -1
  37. data/lib/hexapdf/data_dir.rb +1 -1
  38. data/lib/hexapdf/dictionary.rb +1 -1
  39. data/lib/hexapdf/dictionary_fields.rb +30 -4
  40. data/lib/hexapdf/document/files.rb +3 -3
  41. data/lib/hexapdf/document/fonts.rb +1 -1
  42. data/lib/hexapdf/document/images.rb +1 -1
  43. data/lib/hexapdf/document/pages.rb +1 -1
  44. data/lib/hexapdf/document.rb +1 -1
  45. data/lib/hexapdf/encryption/aes.rb +1 -1
  46. data/lib/hexapdf/encryption/arc4.rb +1 -1
  47. data/lib/hexapdf/encryption/fast_aes.rb +1 -1
  48. data/lib/hexapdf/encryption/fast_arc4.rb +1 -1
  49. data/lib/hexapdf/encryption/identity.rb +1 -1
  50. data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
  51. data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
  52. data/lib/hexapdf/encryption/security_handler.rb +1 -1
  53. data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
  54. data/lib/hexapdf/encryption.rb +1 -1
  55. data/lib/hexapdf/error.rb +1 -1
  56. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  57. data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
  58. data/lib/hexapdf/filter/crypt.rb +1 -1
  59. data/lib/hexapdf/filter/encryption.rb +1 -1
  60. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  61. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  62. data/lib/hexapdf/filter/pass_through.rb +1 -1
  63. data/lib/hexapdf/filter/predictor.rb +1 -1
  64. data/lib/hexapdf/filter/run_length_decode.rb +1 -1
  65. data/lib/hexapdf/filter.rb +1 -1
  66. data/lib/hexapdf/font/cmap/parser.rb +1 -1
  67. data/lib/hexapdf/font/cmap/writer.rb +1 -1
  68. data/lib/hexapdf/font/cmap.rb +1 -1
  69. data/lib/hexapdf/font/encoding/base.rb +1 -1
  70. data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
  71. data/lib/hexapdf/font/encoding/glyph_list.rb +1 -1
  72. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
  73. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
  74. data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
  75. data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
  76. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
  77. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
  78. data/lib/hexapdf/font/encoding.rb +1 -1
  79. data/lib/hexapdf/font/invalid_glyph.rb +1 -1
  80. data/lib/hexapdf/font/true_type/builder.rb +1 -1
  81. data/lib/hexapdf/font/true_type/font.rb +1 -1
  82. data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
  83. data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
  84. data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
  85. data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
  86. data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
  87. data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
  88. data/lib/hexapdf/font/true_type/table/head.rb +1 -1
  89. data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
  90. data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
  91. data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
  92. data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
  93. data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
  94. data/lib/hexapdf/font/true_type/table/name.rb +1 -1
  95. data/lib/hexapdf/font/true_type/table/os2.rb +1 -1
  96. data/lib/hexapdf/font/true_type/table/post.rb +1 -1
  97. data/lib/hexapdf/font/true_type/table.rb +1 -1
  98. data/lib/hexapdf/font/true_type.rb +1 -1
  99. data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
  100. data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
  101. data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
  102. data/lib/hexapdf/font/type1/font.rb +1 -1
  103. data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
  104. data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
  105. data/lib/hexapdf/font/type1.rb +1 -1
  106. data/lib/hexapdf/font/type1_wrapper.rb +1 -1
  107. data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
  108. data/lib/hexapdf/font_loader/from_file.rb +1 -1
  109. data/lib/hexapdf/font_loader/standard14.rb +1 -1
  110. data/lib/hexapdf/font_loader.rb +1 -1
  111. data/lib/hexapdf/image_loader/jpeg.rb +1 -1
  112. data/lib/hexapdf/image_loader/pdf.rb +1 -1
  113. data/lib/hexapdf/image_loader/png.rb +1 -1
  114. data/lib/hexapdf/image_loader.rb +1 -1
  115. data/lib/hexapdf/importer.rb +1 -1
  116. data/lib/hexapdf/layout/box.rb +4 -2
  117. data/lib/hexapdf/layout/frame.rb +1 -1
  118. data/lib/hexapdf/layout/image_box.rb +1 -1
  119. data/lib/hexapdf/layout/inline_box.rb +1 -1
  120. data/lib/hexapdf/layout/line.rb +1 -1
  121. data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
  122. data/lib/hexapdf/layout/style.rb +40 -2
  123. data/lib/hexapdf/layout/text_box.rb +1 -1
  124. data/lib/hexapdf/layout/text_fragment.rb +1 -1
  125. data/lib/hexapdf/layout/text_layouter.rb +1 -1
  126. data/lib/hexapdf/layout/text_shaper.rb +1 -1
  127. data/lib/hexapdf/layout/width_from_polygon.rb +2 -2
  128. data/lib/hexapdf/layout.rb +1 -1
  129. data/lib/hexapdf/name_tree_node.rb +1 -1
  130. data/lib/hexapdf/number_tree_node.rb +1 -1
  131. data/lib/hexapdf/object.rb +1 -1
  132. data/lib/hexapdf/parser.rb +1 -1
  133. data/lib/hexapdf/pdf_array.rb +1 -1
  134. data/lib/hexapdf/rectangle.rb +1 -1
  135. data/lib/hexapdf/reference.rb +1 -1
  136. data/lib/hexapdf/revision.rb +1 -1
  137. data/lib/hexapdf/revisions.rb +1 -1
  138. data/lib/hexapdf/serializer.rb +1 -1
  139. data/lib/hexapdf/stream.rb +1 -1
  140. data/lib/hexapdf/task/dereference.rb +1 -1
  141. data/lib/hexapdf/task/optimize.rb +1 -1
  142. data/lib/hexapdf/task.rb +1 -1
  143. data/lib/hexapdf/tokenizer.rb +1 -1
  144. data/lib/hexapdf/type/acro_form/appearance_generator.rb +14 -7
  145. data/lib/hexapdf/type/acro_form/button_field.rb +53 -28
  146. data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
  147. data/lib/hexapdf/type/acro_form/field.rb +21 -2
  148. data/lib/hexapdf/type/acro_form/form.rb +48 -29
  149. data/lib/hexapdf/type/acro_form/text_field.rb +2 -2
  150. data/lib/hexapdf/type/acro_form/variable_text_field.rb +17 -9
  151. data/lib/hexapdf/type/acro_form.rb +1 -1
  152. data/lib/hexapdf/type/action.rb +1 -1
  153. data/lib/hexapdf/type/actions/go_to.rb +1 -1
  154. data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
  155. data/lib/hexapdf/type/actions/launch.rb +1 -1
  156. data/lib/hexapdf/type/actions/uri.rb +1 -1
  157. data/lib/hexapdf/type/actions.rb +1 -1
  158. data/lib/hexapdf/type/annotation.rb +1 -1
  159. data/lib/hexapdf/type/annotations/link.rb +1 -1
  160. data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
  161. data/lib/hexapdf/type/annotations/text.rb +1 -1
  162. data/lib/hexapdf/type/annotations/widget.rb +2 -2
  163. data/lib/hexapdf/type/annotations.rb +1 -1
  164. data/lib/hexapdf/type/catalog.rb +1 -1
  165. data/lib/hexapdf/type/cid_font.rb +1 -1
  166. data/lib/hexapdf/type/embedded_file.rb +1 -1
  167. data/lib/hexapdf/type/file_specification.rb +1 -1
  168. data/lib/hexapdf/type/font.rb +1 -1
  169. data/lib/hexapdf/type/font_descriptor.rb +1 -1
  170. data/lib/hexapdf/type/font_simple.rb +1 -1
  171. data/lib/hexapdf/type/font_true_type.rb +1 -1
  172. data/lib/hexapdf/type/font_type0.rb +1 -1
  173. data/lib/hexapdf/type/font_type1.rb +1 -1
  174. data/lib/hexapdf/type/font_type3.rb +1 -1
  175. data/lib/hexapdf/type/form.rb +1 -1
  176. data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
  177. data/lib/hexapdf/type/icon_fit.rb +1 -1
  178. data/lib/hexapdf/type/image.rb +1 -1
  179. data/lib/hexapdf/type/info.rb +1 -1
  180. data/lib/hexapdf/type/names.rb +1 -1
  181. data/lib/hexapdf/type/object_stream.rb +1 -1
  182. data/lib/hexapdf/type/page.rb +15 -1
  183. data/lib/hexapdf/type/page_tree_node.rb +1 -1
  184. data/lib/hexapdf/type/resources.rb +1 -1
  185. data/lib/hexapdf/type/trailer.rb +1 -1
  186. data/lib/hexapdf/type/viewer_preferences.rb +1 -1
  187. data/lib/hexapdf/type/xref_stream.rb +1 -1
  188. data/lib/hexapdf/type.rb +1 -1
  189. data/lib/hexapdf/utils/bit_field.rb +1 -1
  190. data/lib/hexapdf/utils/bit_stream.rb +1 -1
  191. data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
  192. data/lib/hexapdf/utils/lru_cache.rb +1 -1
  193. data/lib/hexapdf/utils/math_helpers.rb +1 -1
  194. data/lib/hexapdf/utils/object_hash.rb +1 -1
  195. data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
  196. data/lib/hexapdf/utils/sorted_tree_node.rb +1 -1
  197. data/lib/hexapdf/version.rb +2 -2
  198. data/lib/hexapdf/writer.rb +1 -1
  199. data/lib/hexapdf/xref_section.rb +1 -1
  200. data/lib/hexapdf.rb +1 -1
  201. data/test/hexapdf/content/graphic_object/test_arc.rb +16 -7
  202. data/test/hexapdf/content/test_canvas.rb +63 -0
  203. data/test/hexapdf/content/test_color_space.rb +13 -1
  204. data/test/hexapdf/layout/test_box.rb +2 -0
  205. data/test/hexapdf/layout/test_style.rb +11 -0
  206. data/test/hexapdf/layout/test_width_from_polygon.rb +1 -0
  207. data/test/hexapdf/test_dictionary_fields.rb +24 -0
  208. data/test/hexapdf/test_writer.rb +2 -2
  209. data/test/hexapdf/type/acro_form/test_appearance_generator.rb +2 -1
  210. data/test/hexapdf/type/acro_form/test_button_field.rb +19 -13
  211. data/test/hexapdf/type/acro_form/test_field.rb +12 -0
  212. data/test/hexapdf/type/acro_form/test_form.rb +4 -0
  213. data/test/hexapdf/type/acro_form/test_text_field.rb +6 -0
  214. data/test/hexapdf/type/acro_form/test_variable_text_field.rb +15 -4
  215. data/test/hexapdf/type/test_page.rb +11 -0
  216. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 24d17dfd6c8dc9e3f7014e1ea769dede6f8cea81529bb201a8447f21873d3b25
4
- data.tar.gz: 7165a2e11983731ba2597d2e4a824415abc96936d2b58f3fb737a4fed94dcf16
3
+ metadata.gz: 71e5d38f8a3d1a6b4371e5f8e2f991d36c0ea8c01ca5dc4ec1e132043fad00aa
4
+ data.tar.gz: cf78ef5b6fa915bac30fe75157fc414148c8bd2b8c5c7ee10fe4bb3cbf70076a
5
5
  SHA512:
6
- metadata.gz: 244332a4f024c90cf6344b462ed422a5f73b32d3a4d04d0dcdadc6e7ede2cd0724f7a3329fa3aad68c99e47f49a9dff66806d9b8b152b9551eaecd7365c807d4
7
- data.tar.gz: 06c4b9fd5ecd8f045a37e85ce4a6539f52b48bb16fb685290bcc2a0210b5f2e66bcfa9b7efb1115c45dd1618de9421c479d7a66d84556d1b9c37b19b1f8b6075
6
+ metadata.gz: 2153a1c0eadc0ca940480502b42780717e2777416f1e85e1c9506b879e01df0b2bc4e6d838ecd140af4a62e93bd16aa08ab42bbf522f6bbd234c0d9da82e4115
7
+ data.tar.gz: e91b860ece2751633350739852b392719d9d09cb1bdd9e1c1896ef76e5828db9d2d0f9204b93521efbd6e5dcefc84b0451984392c2a4de3703a6060def1f5c75
data/CHANGELOG.md CHANGED
@@ -1,3 +1,65 @@
1
+ ## 0.17.2 - 2021-10-26
2
+
3
+ ### Fixed
4
+
5
+ * Deployment of HexaPDF's Rubygem
6
+
7
+
8
+ ## 0.17.1 - 2021-10-21
9
+
10
+ ### Fixed
11
+
12
+ * Handling of files containing invalid UTF-16 strings
13
+
14
+
15
+ ## 0.17.0 - 2021-10-21
16
+
17
+ ### Added
18
+
19
+ * CLI command `hexapdf fonts` for listing fonts of a PDF file
20
+ * [HexaPDF::Layout::Style#background_alpha] for defining the opacity of the
21
+ background
22
+ * [HexaPDF::Type::Page#each_annotation] for iterating over all annotations of a
23
+ page
24
+
25
+ ### Changed
26
+
27
+ * **Breaking change**: Handling of AcroForm check boxes to allow multiple
28
+ widgets with different values
29
+ * CLI command `hexapdf form` to support new check box features
30
+ * [HexaPDF::Content::Canvas#text] to use the font size as leading if no leading
31
+ has been set
32
+ * [HexaPDF::Content::Canvas#line_with_rounded_corner] to be a public method
33
+ * [HexaPDF::Layout::Style::LineSpacing] to allow using integers or floats as
34
+ type argument to mean proportional line spacing
35
+ * [HexaPDF::Type::AcroForm::VariableTextField#set_default_appearance_string] to
36
+ allow specifying font options
37
+ * AcroForm text field creation methods in [HexaPDF::Type::AcroForm::Form] to
38
+ allow specifying font options
39
+
40
+ ### Fixed
41
+
42
+ * [HexaPDF::Type::AcroForm::Field#each_widget] to also return widgets of other
43
+ form fields that have the same name
44
+ * `hexapdf form` to allow filling in multiline and comb text fields
45
+ * `hexapdf form` to correctly work for PDF files containing null values in the
46
+ list of annotations
47
+ * Handling of files that contain invalid default appearance strings
48
+ * [HexaPDF::Type::AcroForm::TextField#field_value] to allow setting a `nil`
49
+ value for single line text fields
50
+ * [HexaPDF::Content::GraphicObject::Arc] to respect the value set by the
51
+ `#max_curves` accessor
52
+
53
+
54
+ ## 0.16.0 - 2021-09-28
55
+
56
+ ## Added
57
+
58
+ * Support for RGB color values of the form "RGB" in addition to "RRGGBB" and for
59
+ CSS color module level 3 color names
60
+ * Conversion module for Integer fields to fix certain invalid PDF files
61
+
62
+
1
63
  ## 0.15.9 - 2021-09-04
2
64
 
3
65
  ### Fixed
data/LICENSE CHANGED
@@ -1,5 +1,5 @@
1
1
  HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
2
- Copyright (C) 2014-2020 Thomas Leitner
2
+ Copyright (C) 2014-2021 Thomas Leitner
3
3
 
4
4
  HexaPDF is free software: you can redistribute it and/or modify it
5
5
  under the terms of the GNU Affero General Public License version 3 as
data/README.md CHANGED
@@ -37,6 +37,9 @@ doc.write("hello-world.pdf")
37
37
  For detailed information have a look at the [HexaPDF website][website] where you will the API
38
38
  documentation, example code and more.
39
39
 
40
+ It is recommend to use the HTML API documentation provided by the HexaPDF website as it is enhanced
41
+ with example graphics and PDF files and tightly integrated into the rest of the website.
42
+
40
43
  [website]: http://hexapdf.gettalong.org
41
44
 
42
45
 
@@ -46,8 +49,9 @@ Since HexaPDF is written in Ruby, a working Ruby installation is needed - see th
46
49
  [official installation documentation][rbinstall] for details. Note that you need Ruby version 2.4 or
47
50
  higher as prior versions are not supported!
48
51
 
49
- Apart from Ruby itself the HexaPDF library has no external dependencies. The `hexapdf` application
50
- has a dependency on `cmdparse`, a command line parsing library.
52
+ Apart from Ruby itself the HexaPDF library has only one external dependency `geom2d` which is
53
+ written and provided by the HexaPDF authors. The `hexapdf` application has an additional dependency
54
+ on `cmdparse`, a command line parsing library.
51
55
 
52
56
  HexaPDF itself is distributed via Rubygems and therefore easily installable via `gem install
53
57
  hexapdf`.
@@ -90,6 +94,11 @@ So why use HexaPDF?
90
94
  [Prawn]: http://prawnpdf.org
91
95
  [page canvas API]: https://hexapdf.gettalong.org/api/HexaPDF/Content/Canvas.html
92
96
 
97
+ ## Development
98
+
99
+ Clone the repository and then run `rake dev:setup`. This will install the needed Rubygem
100
+ dependencies as well as make sure that all applications needed for the tests are available.
101
+
93
102
 
94
103
  ## License
95
104
 
data/Rakefile CHANGED
@@ -34,7 +34,8 @@ namespace :dev do
34
34
  end
35
35
 
36
36
  ENV['REAL_GEM'] = "true"
37
- Gem::PackageTask.new(eval(File.read('hexapdf.gemspec'), binding, 'hexapdf.gemspec')) do |pkg|
37
+ spec = eval(File.read('hexapdf.gemspec'), binding, 'hexapdf.gemspec')
38
+ Gem::PackageTask.new(spec) do |pkg|
38
39
  pkg.need_zip = true
39
40
  pkg.need_tar = true
40
41
  end
@@ -145,13 +145,13 @@ canvas.translate(0, 320) do
145
145
  canvas.fill_color(0.4, 0.3, 0.4)
146
146
  canvas.move_to(450, 50)
147
147
  canvas.line_to(*arc.start_point)
148
- arc.curves.each {|c| canvas.curve_to(*c)}
148
+ arc.curves.each {|x, y, hash| canvas.curve_to(x, y, **hash)}
149
149
  canvas.fill
150
150
  arc.configure(start_angle: 105, end_angle: -30)
151
151
  canvas.fill_color(0.3, 0.7, 0.7)
152
152
  canvas.move_to(450, 50)
153
153
  canvas.line_to(*arc.start_point)
154
- arc.curves.each {|c| canvas.curve_to(*c)}
154
+ arc.curves.each {|x, y, hash| canvas.curve_to(x, y, **hash)}
155
155
  canvas.fill
156
156
 
157
157
  arc = canvas.graphic_object(:arc, cx: 530, cy: 50, a: 40, b: 20,
@@ -159,13 +159,13 @@ canvas.translate(0, 320) do
159
159
  canvas.fill_color(0.4, 0.3, 0.4)
160
160
  canvas.move_to(530, 50)
161
161
  canvas.line_to(*arc.start_point)
162
- arc.curves.each {|c| canvas.curve_to(*c)}
162
+ arc.curves.each {|x, y, hash| canvas.curve_to(x, y, **hash)}
163
163
  canvas.fill
164
164
  arc.configure(start_angle: 105, end_angle: -30)
165
165
  canvas.fill_color(0.7, 0.7, 0.3)
166
166
  canvas.move_to(530, 50)
167
167
  canvas.line_to(*arc.start_point)
168
- arc.curves.each {|c| canvas.curve_to(*c)}
168
+ arc.curves.each {|x, y, hash| canvas.curve_to(x, y, **hash)}
169
169
  canvas.fill
170
170
  end
171
171
 
@@ -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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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
@@ -354,6 +354,15 @@ module HexaPDF
354
354
  end
355
355
  end
356
356
 
357
+ # Returns the human readable file size.
358
+ def human_readable_file_size(size)
359
+ case size
360
+ when 0..9999 then "#{size}B"
361
+ when 10_000..999_999 then "#{(size / 1024.to_f).round(1)}K"
362
+ else "#{(size.to_f / 1024 / 1024).round(1)}M"
363
+ end
364
+ end
365
+
357
366
  private
358
367
 
359
368
  # Displays the given prompt, reads from the console without echo and returns the read string.
@@ -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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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
@@ -0,0 +1,145 @@
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2014-2021 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #
33
+ # If the GNU Affero General Public License doesn't fit your need,
34
+ # commercial licenses are available at <https://gettalong.at/hexapdf/>.
35
+ #++
36
+
37
+ require 'set'
38
+ require 'hexapdf/cli/command'
39
+
40
+ module HexaPDF
41
+ module CLI
42
+
43
+ # Lists fonts from a PDF file.
44
+ #
45
+ # See: HexaPDF::Type::Font
46
+ class Fonts < Command
47
+
48
+ def initialize #:nodoc:
49
+ super('fonts', takes_commands: false)
50
+ short_desc("List fonts from a PDF file")
51
+ long_desc(<<~EOF)
52
+ Lists the fonts used in the PDF with additional information, sorted by page number.
53
+ EOF
54
+ options.on("--password PASSWORD", "-p", String,
55
+ "The password for decryption. Use - for reading from standard input.") do |pwd|
56
+ @password = (pwd == '-' ? read_password : pwd)
57
+ end
58
+ options.on("-i", "--pages PAGES", "The subset of pages that should be looked at") do |pages|
59
+ @pages = pages
60
+ end
61
+
62
+ @password = nil
63
+ @pages = nil
64
+ end
65
+
66
+ def execute(pdf) #:nodoc:
67
+ with_document(pdf, password: @password) do |doc|
68
+ printf("%5s %-40s %-12s %-10s %-3s %-3s %8s %9s\n",
69
+ "page", "name", "type", "encoding", "emb", "sub", "size", "oid")
70
+ puts("-" * 97)
71
+ each_font(doc) do |pindex, font|
72
+ font_type = case font[:Subtype]
73
+ when :Type1
74
+ if font.embedded? && font[:FontDescriptor][:FontFile3]
75
+ "Type 1C"
76
+ else
77
+ "Type 1"
78
+ end
79
+ when :Type3 then "Type 3"
80
+ when :TrueType then "TrueType"
81
+ when :Type0
82
+ if font.descendant_font[:Subtype] == :CIDFontType0
83
+ "CID CFF"
84
+ else
85
+ "CID TrueType"
86
+ end
87
+ else
88
+ "Unknown"
89
+ end
90
+ encoding = font[:Encoding]
91
+ encoding = if encoding.kind_of?(Symbol)
92
+ encoding.to_s.sub(/Encoding/, '')
93
+ elsif encoding.kind_of?(Dictionary) &&
94
+ [:Type1, :Type3, :TrueType].include?(font[:Subtype])
95
+ "Custom"
96
+ else
97
+ "Built-in"
98
+ end
99
+ size = human_readable_file_size(font.embedded? ? font.font_file[:Length] : 0)
100
+ embedded = (font.embedded? ? "yes" : "no")
101
+ subset = (font[:BaseFont].match?(/\A[A-Z]{6}\+/) ? "yes" : "no")
102
+ printf("%5s %-40s %-12s %-10s %-3s %-3s %8s %9s\n",
103
+ pindex, font[:BaseFont], font_type, encoding,
104
+ embedded, subset, size, "#{font.oid},#{font.gen}")
105
+ end
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ # Iterates over all fonts by page.
112
+ def each_font(doc) # :yields: obj, index, page_index
113
+ if @pages
114
+ pages = parse_pages_specification(@pages, doc.pages.count).each_with_object({}) do |(i, _), h|
115
+ h[i] = true
116
+ end
117
+ end
118
+ seen = {}
119
+
120
+ doc.pages.each_with_index do |page, pindex|
121
+ next if pages && !pages[pindex]
122
+ font_proc = lambda do |_, font|
123
+ next if seen[font]
124
+ yield(pindex + 1, font)
125
+ seen[font] = true
126
+ end
127
+ page.resources[:Font]&.each(&font_proc)
128
+ page.resources[:XObject]&.each do |_, xobj|
129
+ next unless xobj[:Subtype] == :Form
130
+ xobj.ressources[:Font]&.each(&font_proc)
131
+ end
132
+ page.each_annotation do |annotation|
133
+ appearance = annotation.appearance
134
+ next unless appearance
135
+ appearance.resources[:Font]&.each(&font_proc)
136
+ end
137
+
138
+ seen.clear if pages
139
+ end
140
+ end
141
+
142
+ end
143
+
144
+ end
145
+ 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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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
@@ -108,12 +108,10 @@ module HexaPDF
108
108
  fill_form(doc)
109
109
  end
110
110
  end
111
- if @flatten
112
- unless doc.acro_form.flatten.empty?
113
- $stderr.puts "Warning: Not all form fields could be flattened"
114
- doc.catalog.delete(:AcroForm)
115
- doc.delete(doc.acro_form)
116
- end
111
+ if @flatten && !doc.acro_form.flatten.empty?
112
+ $stderr.puts "Warning: Not all form fields could be flattened"
113
+ doc.catalog.delete(:AcroForm)
114
+ doc.delete(doc.acro_form)
117
115
  end
118
116
  else
119
117
  list_form_fields(doc)
@@ -146,8 +144,8 @@ module HexaPDF
146
144
  if command_parser.verbosity_info?
147
145
  if field.field_type == :Ch
148
146
  puts " └─ Options: #{field.option_items.map(&:inspect).join(', ')}"
149
- elsif concrete_field_type == :radio_button
150
- puts " └─ Options: #{field.radio_button_values.map(&:inspect).join(', ')}"
147
+ elsif concrete_field_type == :radio_button || concrete_field_type == :check_box
148
+ puts " └─ Options: #{([:Off] + field.allowed_values).map(&:to_s).join(', ')}"
151
149
  end
152
150
  end
153
151
  end
@@ -170,11 +168,13 @@ module HexaPDF
170
168
  puts " └─ Current value: #{field.field_value.inspect}"
171
169
 
172
170
  if field.field_type == :Ch
173
- puts " └─ Possible values: #{field.option_items.map(&:inspect).join(', ')}"
171
+ puts " └─ Possible values: #{field.option_items.map(&:to_s).join(', ')}"
174
172
  elsif concrete_field_type == :radio_button
175
- puts " └─ Possible values: #{field.radio_button_values.map(&:inspect).join(', ')}"
173
+ puts " └─ Possible values: Off, #{field.allowed_values.map(&:to_s).join(', ')}"
176
174
  elsif concrete_field_type == :check_box
177
- puts " └─ Possible values: y(es), t(rue); n(o), f(alse)"
175
+ av = field.allowed_values
176
+ puts " └─ Possible values: n(o), f(alse); #{av.size == 1 ? 'y(es), t(rue); ' : ''}" \
177
+ "#{av.map(&:to_s).join(', ')}"
178
178
  end
179
179
 
180
180
  begin
@@ -220,21 +220,22 @@ module HexaPDF
220
220
  # Applies the given value to the field.
221
221
  def apply_field_value(field, value)
222
222
  case field.concrete_field_type
223
- when :single_line_text_field
224
- field.field_value = value
225
- when :combo_box, :list_box
226
- field.field_value = value
227
- when :editable_combo_box
223
+ when :single_line_text_field, :multiline_text_field, :comb_text_field, :combo_box,
224
+ :list_box, :editable_combo_box
228
225
  field.field_value = value
229
226
  when :check_box
230
- unless value.match?(/y(es)?|t(rue)?|f(alse)?|n(o)/)
231
- raise HexaPDF::Error, "Invalid input, use one of the possible values"
232
- end
233
- field.field_value = value.match?(/y(es)?|t(rue)?/)
227
+ field.field_value = case value
228
+ when /y(es)?|t(rue)?/
229
+ true
230
+ when /n(o)?|f(alse)?/
231
+ false
232
+ else
233
+ value
234
+ end
234
235
  when :radio_button
235
- field.field_value = value.intern
236
+ field.field_value = value.to_sym
236
237
  else
237
- raise "Field type not yet supported"
238
+ raise "Field type #{field.concrete_field_type} not yet supported"
238
239
  end
239
240
  end
240
241
 
@@ -244,13 +245,13 @@ module HexaPDF
244
245
  seen = {}
245
246
 
246
247
  doc.pages.each_with_index do |page, page_index|
247
- page[:Annots]&.each do |annotation|
248
+ page.each_annotation do |annotation|
248
249
  next unless annotation[:Subtype] == :Widget
249
250
  field = annotation.form_field
250
251
  next if field.concrete_field_type == :push_button
251
- unless seen[field]
252
+ unless seen[field.full_field_name]
252
253
  yield(page, page_index, field, annotation)
253
- seen[field] = true
254
+ seen[field.full_field_name] = true
254
255
  end
255
256
  end
256
257
  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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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
@@ -197,15 +197,6 @@ module HexaPDF
197
197
  end
198
198
  end
199
199
 
200
- # Returns the human readable file size.
201
- def human_readable_file_size(size)
202
- case size
203
- when 0..9999 then "#{size}B"
204
- when 10_000..999_999 then "#{(size / 1024.to_f).round(1)}K"
205
- else "#{(size.to_f / 1024 / 1024).round(1)}M"
206
- end
207
- end
208
-
209
200
  end
210
201
 
211
202
  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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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
data/lib/hexapdf/cli.rb CHANGED
@@ -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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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
@@ -47,6 +47,7 @@ require 'hexapdf/cli/split'
47
47
  require 'hexapdf/cli/watermark'
48
48
  require 'hexapdf/cli/image2pdf'
49
49
  require 'hexapdf/cli/form'
50
+ require 'hexapdf/cli/fonts'
50
51
  require 'hexapdf/version'
51
52
  require 'hexapdf/document'
52
53
 
@@ -101,6 +102,7 @@ module HexaPDF
101
102
  add_command(HexaPDF::CLI::Watermark.new)
102
103
  add_command(HexaPDF::CLI::Image2PDF.new)
103
104
  add_command(HexaPDF::CLI::Form.new)
105
+ add_command(HexaPDF::CLI::Fonts.new)
104
106
  add_command(CmdParse::HelpCommand.new)
105
107
  version_command = CmdParse::VersionCommand.new(add_switches: false)
106
108
  add_command(version_command)
@@ -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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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-2020 Thomas Leitner
7
+ # Copyright (C) 2014-2021 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
@@ -203,6 +203,12 @@ module HexaPDF
203
203
  #
204
204
  # In nearly all cases this option should not be changed from its default setting!
205
205
  #
206
+ # document.on_invalid_string::
207
+ # A callable object that takes the invalid UTF-16BE encoded string and returns a valid UTF-8
208
+ # encoded string.
209
+ #
210
+ # The default is to remove all invalid characters.
211
+ #
206
212
  # encryption.aes::
207
213
  # The class that should be used for AES encryption. If the value is a String, it should
208
214
  # contain the name of a constant to such a class.
@@ -245,7 +251,7 @@ module HexaPDF
245
251
  # Defines a mapping from font names and variants to font files.
246
252
  #
247
253
  # The value needs to be a hash of the form:
248
- # {"font_name": {variant: file_name, variant2: file_name2, ...}, ...}
254
+ # {"font_name" => {variant: file_name, variant2: file_name2, ...}, ...}
249
255
  #
250
256
  # Once a font is registered in this way, the font name together with a variant name can be used
251
257
  # with the HexaPDF::Document::Fonts#add method to load the font.
@@ -380,6 +386,9 @@ module HexaPDF
380
386
  end,
381
387
  'acro_form.text_field.default_width' => 100,
382
388
  'document.auto_decrypt' => true,
389
+ 'document.on_invalid_string' => proc do |str|
390
+ str.encode(Encoding::UTF_8, invalid: :replace, replace: '')
391
+ end,
383
392
  'encryption.aes' => 'HexaPDF::Encryption::FastAES',
384
393
  'encryption.arc4' => 'HexaPDF::Encryption::FastARC4',
385
394
  'encryption.filter_map' => {