hexapdf 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (257) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +33 -0
  3. data/CONTRIBUTERS +1 -1
  4. data/LICENSE +1 -1
  5. data/Rakefile +1 -1
  6. data/VERSION +1 -1
  7. data/bin/hexapdf +1 -1
  8. data/examples/text_layouter_styling.rb +1 -2
  9. data/lib/hexapdf.rb +2 -2
  10. data/lib/hexapdf/cli.rb +3 -3
  11. data/lib/hexapdf/cli/batch.rb +5 -5
  12. data/lib/hexapdf/cli/command.rb +15 -17
  13. data/lib/hexapdf/cli/files.rb +3 -3
  14. data/lib/hexapdf/cli/images.rb +3 -4
  15. data/lib/hexapdf/cli/info.rb +5 -5
  16. data/lib/hexapdf/cli/inspect.rb +6 -6
  17. data/lib/hexapdf/cli/merge.rb +6 -6
  18. data/lib/hexapdf/cli/modify.rb +4 -4
  19. data/lib/hexapdf/cli/optimize.rb +3 -3
  20. data/lib/hexapdf/configuration.rb +4 -5
  21. data/lib/hexapdf/content.rb +2 -2
  22. data/lib/hexapdf/content/canvas.rb +35 -36
  23. data/lib/hexapdf/content/color_space.rb +9 -14
  24. data/lib/hexapdf/content/graphic_object.rb +2 -2
  25. data/lib/hexapdf/content/graphic_object/arc.rb +3 -3
  26. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +2 -2
  27. data/lib/hexapdf/content/graphic_object/solid_arc.rb +4 -8
  28. data/lib/hexapdf/content/graphics_state.rb +4 -13
  29. data/lib/hexapdf/content/operator.rb +33 -35
  30. data/lib/hexapdf/content/parser.rb +28 -18
  31. data/lib/hexapdf/content/processor.rb +4 -5
  32. data/lib/hexapdf/content/transformation_matrix.rb +2 -2
  33. data/lib/hexapdf/data_dir.rb +2 -2
  34. data/lib/hexapdf/dictionary.rb +8 -9
  35. data/lib/hexapdf/dictionary_fields.rb +7 -10
  36. data/lib/hexapdf/document.rb +18 -18
  37. data/lib/hexapdf/document/files.rb +12 -10
  38. data/lib/hexapdf/document/fonts.rb +2 -2
  39. data/lib/hexapdf/document/images.rb +3 -3
  40. data/lib/hexapdf/document/pages.rb +4 -4
  41. data/lib/hexapdf/encryption.rb +2 -2
  42. data/lib/hexapdf/encryption/aes.rb +2 -2
  43. data/lib/hexapdf/encryption/arc4.rb +4 -4
  44. data/lib/hexapdf/encryption/fast_aes.rb +2 -2
  45. data/lib/hexapdf/encryption/fast_arc4.rb +4 -4
  46. data/lib/hexapdf/encryption/identity.rb +5 -4
  47. data/lib/hexapdf/encryption/ruby_aes.rb +147 -139
  48. data/lib/hexapdf/encryption/ruby_arc4.rb +4 -4
  49. data/lib/hexapdf/encryption/security_handler.rb +11 -12
  50. data/lib/hexapdf/encryption/standard_security_handler.rb +6 -9
  51. data/lib/hexapdf/error.rb +7 -9
  52. data/lib/hexapdf/filter.rb +2 -3
  53. data/lib/hexapdf/filter/ascii85_decode.rb +3 -3
  54. data/lib/hexapdf/filter/ascii_hex_decode.rb +2 -2
  55. data/lib/hexapdf/filter/dct_decode.rb +2 -2
  56. data/lib/hexapdf/filter/encryption.rb +2 -2
  57. data/lib/hexapdf/filter/flate_decode.rb +16 -33
  58. data/lib/hexapdf/filter/jpx_decode.rb +2 -2
  59. data/lib/hexapdf/filter/lzw_decode.rb +4 -4
  60. data/lib/hexapdf/filter/predictor.rb +2 -6
  61. data/lib/hexapdf/filter/run_length_decode.rb +2 -2
  62. data/lib/hexapdf/font/cmap.rb +2 -3
  63. data/lib/hexapdf/font/cmap/parser.rb +11 -11
  64. data/lib/hexapdf/font/cmap/writer.rb +25 -25
  65. data/lib/hexapdf/font/encoding.rb +2 -2
  66. data/lib/hexapdf/font/encoding/base.rb +2 -2
  67. data/lib/hexapdf/font/encoding/difference_encoding.rb +2 -2
  68. data/lib/hexapdf/font/encoding/glyph_list.rb +6 -6
  69. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +2 -2
  70. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +2 -2
  71. data/lib/hexapdf/font/encoding/standard_encoding.rb +2 -2
  72. data/lib/hexapdf/font/encoding/symbol_encoding.rb +2 -2
  73. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +2 -2
  74. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +2 -2
  75. data/lib/hexapdf/font/invalid_glyph.rb +7 -7
  76. data/lib/hexapdf/font/true_type.rb +2 -2
  77. data/lib/hexapdf/font/true_type/builder.rb +13 -7
  78. data/lib/hexapdf/font/true_type/font.rb +2 -3
  79. data/lib/hexapdf/font/true_type/optimizer.rb +2 -2
  80. data/lib/hexapdf/font/true_type/subsetter.rb +4 -4
  81. data/lib/hexapdf/font/true_type/table.rb +3 -5
  82. data/lib/hexapdf/font/true_type/table/cmap.rb +2 -2
  83. data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +9 -16
  84. data/lib/hexapdf/font/true_type/table/directory.rb +4 -4
  85. data/lib/hexapdf/font/true_type/table/glyf.rb +2 -2
  86. data/lib/hexapdf/font/true_type/table/head.rb +3 -2
  87. data/lib/hexapdf/font/true_type/table/hhea.rb +2 -2
  88. data/lib/hexapdf/font/true_type/table/hmtx.rb +2 -2
  89. data/lib/hexapdf/font/true_type/table/kern.rb +3 -3
  90. data/lib/hexapdf/font/true_type/table/loca.rb +3 -3
  91. data/lib/hexapdf/font/true_type/table/maxp.rb +2 -2
  92. data/lib/hexapdf/font/true_type/table/name.rb +3 -5
  93. data/lib/hexapdf/font/true_type/table/os2.rb +4 -3
  94. data/lib/hexapdf/font/true_type/table/post.rb +3 -7
  95. data/lib/hexapdf/font/true_type_wrapper.rb +20 -22
  96. data/lib/hexapdf/font/type1.rb +2 -2
  97. data/lib/hexapdf/font/type1/afm_parser.rb +7 -7
  98. data/lib/hexapdf/font/type1/character_metrics.rb +2 -2
  99. data/lib/hexapdf/font/type1/font.rb +3 -3
  100. data/lib/hexapdf/font/type1/font_metrics.rb +2 -4
  101. data/lib/hexapdf/font/type1/pfb_parser.rb +2 -2
  102. data/lib/hexapdf/font/type1_wrapper.rb +8 -9
  103. data/lib/hexapdf/font_loader.rb +2 -2
  104. data/lib/hexapdf/font_loader/from_configuration.rb +2 -2
  105. data/lib/hexapdf/font_loader/from_file.rb +2 -2
  106. data/lib/hexapdf/font_loader/standard14.rb +2 -2
  107. data/lib/hexapdf/image_loader.rb +2 -2
  108. data/lib/hexapdf/image_loader/jpeg.rb +6 -4
  109. data/lib/hexapdf/image_loader/pdf.rb +2 -2
  110. data/lib/hexapdf/image_loader/png.rb +6 -6
  111. data/lib/hexapdf/importer.rb +6 -4
  112. data/lib/hexapdf/layout.rb +2 -2
  113. data/lib/hexapdf/layout/box.rb +4 -4
  114. data/lib/hexapdf/layout/inline_box.rb +2 -2
  115. data/lib/hexapdf/layout/line.rb +6 -6
  116. data/lib/hexapdf/layout/numeric_refinements.rb +2 -2
  117. data/lib/hexapdf/layout/style.rb +17 -8
  118. data/lib/hexapdf/layout/text_fragment.rb +86 -48
  119. data/lib/hexapdf/layout/text_layouter.rb +40 -21
  120. data/lib/hexapdf/layout/text_shaper.rb +2 -2
  121. data/lib/hexapdf/name_tree_node.rb +2 -2
  122. data/lib/hexapdf/number_tree_node.rb +2 -2
  123. data/lib/hexapdf/object.rb +6 -8
  124. data/lib/hexapdf/parser.rb +10 -10
  125. data/lib/hexapdf/rectangle.rb +4 -4
  126. data/lib/hexapdf/reference.rb +2 -2
  127. data/lib/hexapdf/revision.rb +4 -4
  128. data/lib/hexapdf/revisions.rb +5 -5
  129. data/lib/hexapdf/serializer.rb +27 -24
  130. data/lib/hexapdf/stream.rb +4 -4
  131. data/lib/hexapdf/task.rb +2 -2
  132. data/lib/hexapdf/task/dereference.rb +4 -4
  133. data/lib/hexapdf/task/optimize.rb +5 -4
  134. data/lib/hexapdf/tokenizer.rb +12 -14
  135. data/lib/hexapdf/type.rb +2 -2
  136. data/lib/hexapdf/type/action.rb +3 -3
  137. data/lib/hexapdf/type/actions.rb +2 -2
  138. data/lib/hexapdf/type/actions/go_to.rb +2 -2
  139. data/lib/hexapdf/type/actions/go_to_r.rb +2 -2
  140. data/lib/hexapdf/type/actions/launch.rb +2 -2
  141. data/lib/hexapdf/type/actions/uri.rb +3 -3
  142. data/lib/hexapdf/type/annotation.rb +3 -3
  143. data/lib/hexapdf/type/annotations.rb +2 -2
  144. data/lib/hexapdf/type/annotations/link.rb +2 -2
  145. data/lib/hexapdf/type/annotations/markup_annotation.rb +2 -2
  146. data/lib/hexapdf/type/annotations/text.rb +2 -2
  147. data/lib/hexapdf/type/catalog.rb +4 -4
  148. data/lib/hexapdf/type/cid_font.rb +4 -5
  149. data/lib/hexapdf/type/embedded_file.rb +3 -3
  150. data/lib/hexapdf/type/file_specification.rb +6 -7
  151. data/lib/hexapdf/type/font.rb +4 -4
  152. data/lib/hexapdf/type/font_descriptor.rb +3 -4
  153. data/lib/hexapdf/type/font_simple.rb +12 -16
  154. data/lib/hexapdf/type/font_true_type.rb +2 -2
  155. data/lib/hexapdf/type/font_type0.rb +5 -5
  156. data/lib/hexapdf/type/font_type1.rb +4 -4
  157. data/lib/hexapdf/type/form.rb +3 -3
  158. data/lib/hexapdf/type/graphics_state_parameter.rb +3 -3
  159. data/lib/hexapdf/type/image.rb +13 -14
  160. data/lib/hexapdf/type/info.rb +2 -2
  161. data/lib/hexapdf/type/names.rb +2 -2
  162. data/lib/hexapdf/type/object_stream.rb +5 -5
  163. data/lib/hexapdf/type/page.rb +9 -10
  164. data/lib/hexapdf/type/page_tree_node.rb +5 -6
  165. data/lib/hexapdf/type/resources.rb +11 -11
  166. data/lib/hexapdf/type/trailer.rb +3 -3
  167. data/lib/hexapdf/type/viewer_preferences.rb +2 -2
  168. data/lib/hexapdf/type/xref_stream.rb +8 -4
  169. data/lib/hexapdf/utils/bit_field.rb +4 -4
  170. data/lib/hexapdf/utils/bit_stream.rb +4 -4
  171. data/lib/hexapdf/utils/graphics_helpers.rb +2 -2
  172. data/lib/hexapdf/utils/lru_cache.rb +2 -2
  173. data/lib/hexapdf/utils/math_helpers.rb +2 -2
  174. data/lib/hexapdf/utils/object_hash.rb +3 -3
  175. data/lib/hexapdf/utils/pdf_doc_encoding.rb +3 -3
  176. data/lib/hexapdf/utils/sorted_tree_node.rb +12 -11
  177. data/lib/hexapdf/version.rb +3 -3
  178. data/lib/hexapdf/writer.rb +8 -8
  179. data/lib/hexapdf/xref_section.rb +3 -3
  180. data/test/hexapdf/common_tokenizer_tests.rb +6 -7
  181. data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +0 -1
  182. data/test/hexapdf/content/test_canvas.rb +28 -36
  183. data/test/hexapdf/content/test_color_space.rb +4 -0
  184. data/test/hexapdf/content/test_graphics_state.rb +2 -0
  185. data/test/hexapdf/content/test_operator.rb +6 -7
  186. data/test/hexapdf/content/test_parser.rb +2 -2
  187. data/test/hexapdf/content/test_processor.rb +1 -1
  188. data/test/hexapdf/document/test_files.rb +1 -0
  189. data/test/hexapdf/document/test_images.rb +1 -1
  190. data/test/hexapdf/encryption/common.rb +3 -3
  191. data/test/hexapdf/encryption/test_aes.rb +10 -4
  192. data/test/hexapdf/encryption/test_identity.rb +1 -1
  193. data/test/hexapdf/encryption/test_security_handler.rb +13 -17
  194. data/test/hexapdf/encryption/test_standard_security_handler.rb +12 -12
  195. data/test/hexapdf/filter/test_ascii85_decode.rb +2 -3
  196. data/test/hexapdf/filter/test_ascii_hex_decode.rb +6 -1
  197. data/test/hexapdf/filter/test_flate_decode.rb +2 -2
  198. data/test/hexapdf/filter/test_lzw_decode.rb +10 -10
  199. data/test/hexapdf/filter/test_predictor.rb +10 -2
  200. data/test/hexapdf/filter/test_run_length_decode.rb +1 -1
  201. data/test/hexapdf/font/cmap/test_parser.rb +40 -40
  202. data/test/hexapdf/font/cmap/test_writer.rb +29 -29
  203. data/test/hexapdf/font/test_true_type_wrapper.rb +3 -2
  204. data/test/hexapdf/font/true_type/common.rb +2 -0
  205. data/test/hexapdf/font/true_type/table/test_cmap.rb +1 -1
  206. data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +5 -4
  207. data/test/hexapdf/font/true_type/table/test_glyf.rb +2 -2
  208. data/test/hexapdf/font/true_type/table/test_head.rb +2 -2
  209. data/test/hexapdf/font/true_type/table/test_name.rb +9 -6
  210. data/test/hexapdf/font/true_type/test_builder.rb +8 -3
  211. data/test/hexapdf/font/true_type/test_optimizer.rb +1 -2
  212. data/test/hexapdf/font/type1/test_afm_parser.rb +2 -2
  213. data/test/hexapdf/image_loader/test_jpeg.rb +1 -1
  214. data/test/hexapdf/image_loader/test_pdf.rb +1 -1
  215. data/test/hexapdf/image_loader/test_png.rb +3 -3
  216. data/test/hexapdf/layout/test_inline_box.rb +10 -1
  217. data/test/hexapdf/layout/test_line.rb +4 -4
  218. data/test/hexapdf/layout/test_style.rb +19 -7
  219. data/test/hexapdf/layout/test_text_fragment.rb +73 -27
  220. data/test/hexapdf/layout/test_text_layouter.rb +84 -68
  221. data/test/hexapdf/layout/test_text_shaper.rb +4 -6
  222. data/test/hexapdf/task/test_dereference.rb +2 -2
  223. data/test/hexapdf/task/test_optimize.rb +16 -7
  224. data/test/hexapdf/test_configuration.rb +1 -1
  225. data/test/hexapdf/test_data_dir.rb +2 -2
  226. data/test/hexapdf/test_dictionary.rb +6 -3
  227. data/test/hexapdf/test_dictionary_fields.rb +15 -14
  228. data/test/hexapdf/test_document.rb +47 -48
  229. data/test/hexapdf/test_filter.rb +30 -26
  230. data/test/hexapdf/test_importer.rb +14 -0
  231. data/test/hexapdf/test_object.rb +16 -4
  232. data/test/hexapdf/test_parser.rb +36 -36
  233. data/test/hexapdf/test_reference.rb +7 -5
  234. data/test/hexapdf/test_revision.rb +1 -1
  235. data/test/hexapdf/test_revisions.rb +90 -90
  236. data/test/hexapdf/test_serializer.rb +3 -2
  237. data/test/hexapdf/test_stream.rb +2 -4
  238. data/test/hexapdf/test_tokenizer.rb +2 -2
  239. data/test/hexapdf/test_writer.rb +80 -80
  240. data/test/hexapdf/test_xref_section.rb +1 -1
  241. data/test/hexapdf/type/annotations/test_link.rb +1 -1
  242. data/test/hexapdf/type/annotations/test_text.rb +3 -3
  243. data/test/hexapdf/type/test_font_descriptor.rb +1 -1
  244. data/test/hexapdf/type/test_font_simple.rb +2 -2
  245. data/test/hexapdf/type/test_font_type0.rb +0 -1
  246. data/test/hexapdf/type/test_image.rb +0 -3
  247. data/test/hexapdf/type/test_object_stream.rb +2 -1
  248. data/test/hexapdf/type/test_page.rb +5 -1
  249. data/test/hexapdf/type/test_page_tree_node.rb +4 -4
  250. data/test/hexapdf/type/test_trailer.rb +1 -1
  251. data/test/hexapdf/type/test_xref_stream.rb +4 -0
  252. data/test/hexapdf/utils/test_bit_field.rb +2 -0
  253. data/test/hexapdf/utils/test_bit_stream.rb +1 -1
  254. data/test/hexapdf/utils/test_lru_cache.rb +1 -1
  255. data/test/hexapdf/utils/test_sorted_tree_node.rb +10 -4
  256. data/test/test_helper.rb +3 -6
  257. metadata +3 -3
@@ -1,10 +1,10 @@
1
- # -*- encoding: utf-8 -*-
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
2
  #
3
3
  #--
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-2017 Thomas Leitner
7
+ # Copyright (C) 2014-2018 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
@@ -162,7 +162,7 @@ module HexaPDF
162
162
  if @color_type == INDEXED
163
163
  trns = io.read(length).unpack('C*')
164
164
  elsif @color_type == TRUECOLOR || @color_type == GREYSCALE
165
- dict[:Mask] = io.read(length).unpack('n*').map {|val| [val, val]}.flatten
165
+ dict[:Mask] = io.read(length).unpack('n*').map {|val| [val, val] }.flatten
166
166
  else
167
167
  io.seek(length, IO::SEEK_CUR)
168
168
  end
@@ -179,7 +179,7 @@ module HexaPDF
179
179
  end
180
180
  when 'cHRM' # PNG s11.3.3.1
181
181
  chrm = io.read(length)
182
- @chrm = chrm.unpack('N8').map {|v| v / 100_000.0} unless @intent # sRGB trumps cHRM
182
+ @chrm = chrm.unpack('N8').map {|v| v / 100_000.0 } unless @intent # sRGB trumps cHRM
183
183
  else
184
184
  io.seek(length, IO::SEEK_CUR)
185
185
  end
@@ -320,7 +320,7 @@ module HexaPDF
320
320
  length, type = io.read(8).unpack('Na4') # PNG s5.3
321
321
  break if type != 'IDAT'
322
322
 
323
- chunk_size = @document.config['io.chunk_size'.freeze]
323
+ chunk_size = @document.config['io.chunk_size']
324
324
  while length > 0
325
325
  chunk_size = length if chunk_size > length
326
326
  Fiber.yield(io.read(chunk_size))
@@ -363,7 +363,7 @@ module HexaPDF
363
363
  mask_data << data.byteslice(i, bytes_per_alpha)
364
364
  i += bytes_per_alpha
365
365
  end
366
- data[0, bytes_per_row] = ''.freeze
366
+ data[0, bytes_per_row] = ''
367
367
  end
368
368
  end
369
369
 
@@ -1,10 +1,10 @@
1
- # -*- encoding: utf-8 -*-
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
2
  #
3
3
  #--
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-2017 Thomas Leitner
7
+ # Copyright (C) 2014-2018 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
@@ -50,16 +50,18 @@ module HexaPDF
50
50
  class Importer
51
51
 
52
52
  class NullableWeakRef < WeakRef #:nodoc:
53
+
53
54
  def __getobj__ #:nodoc:
54
55
  super rescue nil
55
56
  end
57
+
56
58
  end
57
59
 
58
60
  # Returns the Importer object for copying objects from the +source+ to the +destination+
59
61
  # document.
60
62
  def self.for(source:, destination:)
61
63
  @map ||= {}
62
- @map.keep_if {|_, v| v.source.weakref_alive? && v.destination.weakref_alive?}
64
+ @map.keep_if {|_, v| v.source.weakref_alive? && v.destination.weakref_alive? }
63
65
  source = NullableWeakRef.new(source)
64
66
  destination = NullableWeakRef.new(destination)
65
67
  @map[[source.hash, destination.hash]] ||= new(source: source, destination: destination)
@@ -108,7 +110,7 @@ module HexaPDF
108
110
  obj[k] = duplicate(v)
109
111
  end
110
112
  when Array
111
- object.map {|v| duplicate(v)}
113
+ object.map {|v| duplicate(v) }
112
114
  when HexaPDF::Reference
113
115
  import(@source.object(object))
114
116
  when HexaPDF::Object
@@ -1,10 +1,10 @@
1
- # -*- encoding: utf-8 -*-
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
2
  #
3
3
  #--
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-2017 Thomas Leitner
7
+ # Copyright (C) 2014-2018 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
@@ -1,10 +1,10 @@
1
- # -*- encoding: utf-8 -*-
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
2
  #
3
3
  #--
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-2017 Thomas Leitner
7
+ # Copyright (C) 2014-2018 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
@@ -69,8 +69,8 @@ module HexaPDF
69
69
  attr_reader :style
70
70
 
71
71
  # :call-seq:
72
- # Box.new(content_width: 0, content_height: 0, style: Style.new) {|canvas, box| block} -> box
73
- # Box.new(width: 0, height: 0, style: Style.new) {|canvas, box| block} -> box
72
+ # Box.new(content_width: 0, content_height: 0, style: Style.new) {|canv, box| block} -> box
73
+ # Box.new(width: 0, height: 0, style: Style.new) {|canv, box| block} -> box
74
74
  #
75
75
  # Creates a new Box object with the given width and height for its content that uses the
76
76
  # provided block when it is asked to draw itself on a canvas (see #draw).
@@ -1,10 +1,10 @@
1
- # -*- encoding: utf-8 -*-
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
2
  #
3
3
  #--
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-2017 Thomas Leitner
7
+ # Copyright (C) 2014-2018 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
@@ -1,10 +1,10 @@
1
- # -*- encoding: utf-8 -*-
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
2
  #
3
3
  #--
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-2017 Thomas Leitner
7
+ # Copyright (C) 2014-2018 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
@@ -93,7 +93,7 @@ module HexaPDF
93
93
  # Creates a new calculator with the given initial items.
94
94
  def initialize(items = [])
95
95
  reset
96
- items.each {|item| add(item)}
96
+ items.each {|item| add(item) }
97
97
  end
98
98
 
99
99
  # Adds a new item to be considered when calculating the various dimensions.
@@ -117,7 +117,7 @@ module HexaPDF
117
117
  end
118
118
  self
119
119
  end
120
- alias_method :<<, :add
120
+ alias << add
121
121
 
122
122
  # Returns the result of the calculations, the array [y_min, y_max, text_y_min, text_y_max].
123
123
  #
@@ -182,7 +182,7 @@ module HexaPDF
182
182
  # Creates a new Line object, adding all given items to it.
183
183
  def initialize(items = [])
184
184
  @items = []
185
- items.each {|i| add(i)}
185
+ items.each {|i| add(i) }
186
186
  @x_offset = 0
187
187
  @y_offset = 0
188
188
  end
@@ -207,7 +207,7 @@ module HexaPDF
207
207
  end
208
208
  self
209
209
  end
210
- alias :<< :add
210
+ alias << add
211
211
 
212
212
  # :call-seq:
213
213
  # line.each {|item, x, y| block }
@@ -1,10 +1,10 @@
1
- # -*- encoding: utf-8 -*-
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
2
  #
3
3
  #--
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-2017 Thomas Leitner
7
+ # Copyright (C) 2014-2018 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
@@ -1,10 +1,10 @@
1
- # -*- encoding: utf-8 -*-
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
2
  #
3
3
  #--
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-2017 Thomas Leitner
7
+ # Copyright (C) 2014-2018 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
@@ -466,7 +466,8 @@ module HexaPDF
466
466
  @border_color = border_color
467
467
  end
468
468
 
469
- # Creates the needed link annotation if possible, i.e. if the context of the canvas is a page.
469
+ # Creates the needed link annotation if possible, i.e. if the context of the canvas is a
470
+ # page.
470
471
  def call(canvas, box)
471
472
  return unless canvas.context.type == :Page
472
473
  page = canvas.context
@@ -493,16 +494,25 @@ module HexaPDF
493
494
 
494
495
  # Creates a new Style object.
495
496
  #
496
- # The +options+ hash may be used to set the initial values of properties by using keys
497
+ # The +properties+ hash may be used to set the initial values of properties by using keys
497
498
  # equivalent to the property names.
498
499
  #
499
500
  # Example:
500
501
  # Style.new(font_size: 15, align: :center, valign: center)
501
- def initialize(**options)
502
- options.each {|key, value| send(key, value)}
502
+ def initialize(**properties)
503
+ update(properties)
503
504
  @scaled_item_widths = {}
504
505
  end
505
506
 
507
+ # :call-seq:
508
+ # style.update(**properties) -> style
509
+ #
510
+ # Updates the style's properties using the key-value pairs specified by the +properties+ hash.
511
+ def update(**properties)
512
+ properties.each {|key, value| send(key, value) }
513
+ self
514
+ end
515
+
506
516
  ##
507
517
  # :method: font
508
518
  # :call-seq:
@@ -799,7 +809,6 @@ module HexaPDF
799
809
  alias_method("#{name}=", name)
800
810
  end
801
811
 
802
-
803
812
  ##
804
813
  # :method: text_segmentation_algorithm
805
814
  # :call-seq:
@@ -945,7 +954,7 @@ module HexaPDF
945
954
 
946
955
  # Returns the default color for an empty PDF page, i.e. black.
947
956
  def default_color
948
- GlobalConfiguration.constantize('color_space.map'.freeze, :DeviceGray).new.default_color
957
+ GlobalConfiguration.constantize('color_space.map', :DeviceGray).new.default_color
949
958
  end
950
959
 
951
960
  end
@@ -1,10 +1,10 @@
1
- # -*- encoding: utf-8 -*-
1
+ # -*- encoding: utf-8; frozen_string_literal: true -*-
2
2
  #
3
3
  #--
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-2017 Thomas Leitner
7
+ # Copyright (C) 2014-2018 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,10 +58,12 @@ module HexaPDF
58
58
 
59
59
  # Creates a new TextFragment object for the given text, shapes it and returns it.
60
60
  #
61
- # The style of the text fragment can be specified using additional options, of which font is
62
- # mandatory.
63
- def self.create(text, font:, **options)
64
- fragment = new(items: font.decode_utf8(text), style: Style.new(font: font, **options))
61
+ # The needed style of the text fragment can either be specified by the +style+ argument or via
62
+ # the +options+ (in which case a new Style object is created). Regardless of the way, the
63
+ # resulting style object needs at least the font set.
64
+ def self.create(text, style = nil, **options)
65
+ style = (style.nil? ? Style.new(options) : style)
66
+ fragment = new(style.font.decode_utf8(text), style)
65
67
  TextShaper.new.shape_text(fragment)
66
68
  end
67
69
 
@@ -99,64 +101,100 @@ module HexaPDF
99
101
  # Creates a new TextFragment object with the given items and style.
100
102
  #
101
103
  # The argument +style+ can either be a Style object or a hash of style options.
102
- def initialize(items:, style: Style.new)
103
- @items = items || []
104
+ def initialize(items, style)
105
+ @items = items
104
106
  @style = (style.kind_of?(Style) ? style : Style.new(style))
105
107
  end
106
108
 
109
+ # The precision used to determine whether two floats represent the same value.
110
+ PRECISION = 0.000001 # :nodoc:
111
+
107
112
  # Draws the text onto the canvas at the given position.
108
113
  #
109
- # Before the text is drawn using HexaPDF::Content;:Canvas#show_glyphs, the text properties
110
- # mentioned in the description of #style are set.
111
- def draw(canvas, x, y)
112
- return if items.empty?
113
-
114
+ # This method is the main styled text drawing facility and therefore some optimizations are
115
+ # done:
116
+ #
117
+ # * The text is drawn using HexaPDF::Content;:Canvas#show_glyphs_only which means that the
118
+ # text matrix is *not* updated. Therefore the caller must *not* rely on it!
119
+ #
120
+ # * All text style properties mentioned in the description of #style are set except if
121
+ # +ignore_text_properties+ is set to +true+. Note that this only applies to style properties
122
+ # that directly affect text drawing, so, for example, underlays/overlays and
123
+ # underlining/strikeout is always done.
124
+ #
125
+ # The caller should set +ignore_text_properties+ to +true+ if the graphics state hasn't been
126
+ # changed. This is the case, for example, if the last thing drawn was a text fragment with
127
+ # the same style.
128
+ #
129
+ # * It is assumed that the text matrix is not rotated, skewed, etc. so that setting the text
130
+ # position can be done using the optimal method.
131
+ def draw(canvas, x, y, ignore_text_properties: false)
114
132
  style.underlays.draw(canvas, x, y + y_min, self)
115
133
 
116
- # Set general font related graphics state
117
- canvas.move_text_cursor(offset: [x, y])
118
- canvas.font(style.font, size: style.calculated_font_size).
119
- horizontal_scaling(style.horizontal_scaling).
120
- character_spacing(style.character_spacing).
121
- word_spacing(style.word_spacing).
122
- text_rise(style.calculated_text_rise).
123
- text_rendering_mode(style.text_rendering_mode)
124
-
125
- # Set fill and/or stroke related graphics state
126
- canvas.opacity(fill_alpha: style.fill_alpha, stroke_alpha: style.stroke_alpha)
127
- trm = canvas.text_rendering_mode
128
- if trm.value.even? # text is filled
129
- canvas.fill_color(style.fill_color)
130
- end
131
- if trm == :stroke || trm == :fill_stroke || trm == :stroke_clip || trm == :fill_stroke_clip
132
- canvas.stroke_color(style.stroke_color).
133
- line_width(style.stroke_width).
134
- line_cap_style(style.stroke_cap_style).
135
- line_join_style(style.stroke_join_style).
136
- miter_limit(style.stroke_miter_limit).
137
- line_dash_pattern(style.stroke_dash_pattern)
134
+ # Set general font related graphics state if necessary
135
+ unless ignore_text_properties
136
+ canvas.font(style.font, size: style.calculated_font_size).
137
+ horizontal_scaling(style.horizontal_scaling).
138
+ character_spacing(style.character_spacing).
139
+ word_spacing(style.word_spacing).
140
+ text_rise(style.calculated_text_rise).
141
+ text_rendering_mode(style.text_rendering_mode)
142
+
143
+ # Set fill and/or stroke related graphics state
144
+ canvas.opacity(fill_alpha: style.fill_alpha, stroke_alpha: style.stroke_alpha)
145
+ trm = canvas.text_rendering_mode
146
+ if trm.value.even? # text is filled
147
+ canvas.fill_color(style.fill_color)
148
+ end
149
+ if trm == :stroke || trm == :fill_stroke || trm == :stroke_clip || trm == :fill_stroke_clip
150
+ canvas.stroke_color(style.stroke_color).
151
+ line_width(style.stroke_width).
152
+ line_cap_style(style.stroke_cap_style).
153
+ line_join_style(style.stroke_join_style).
154
+ miter_limit(style.stroke_miter_limit).
155
+ line_dash_pattern(style.stroke_dash_pattern)
156
+ end
138
157
  end
139
158
 
159
+ canvas.begin_text
160
+ tlm = canvas.graphics_state.tlm
161
+ tx = x - tlm.e
162
+ ty = y - tlm.f
163
+ if tx.abs < PRECISION
164
+ if (ty + canvas.graphics_state.leading).abs < PRECISION
165
+ canvas.move_text_cursor
166
+ else
167
+ canvas.move_text_cursor(offset: [0, ty], absolute: false)
168
+ end
169
+ elsif ty.abs < PRECISION
170
+ canvas.move_text_cursor(offset: [tx, 0], absolute: false)
171
+ else
172
+ canvas.move_text_cursor(offset: [x, y])
173
+ end
140
174
  canvas.show_glyphs_only(items)
141
175
 
142
176
  if style.underline
143
177
  y_offset = style.calculated_underline_position
144
- canvas.stroke_color(style.fill_color).
145
- line_width(style.calculated_underline_thickness).
146
- line_cap_style(:butt).
147
- line_dash_pattern(0).
148
- line(x, y + y_offset, x + width, y + y_offset).
149
- stroke
178
+ canvas.save_graphics_state do
179
+ canvas.stroke_color(style.fill_color).
180
+ line_width(style.calculated_underline_thickness).
181
+ line_cap_style(:butt).
182
+ line_dash_pattern(0).
183
+ line(x, y + y_offset, x + width, y + y_offset).
184
+ stroke
185
+ end
150
186
  end
151
187
 
152
188
  if style.strikeout
153
189
  y_offset = style.calculated_strikeout_position
154
- canvas.stroke_color(style.fill_color).
155
- line_width(style.calculated_strikeout_thickness).
156
- line_cap_style(:butt).
157
- line_dash_pattern(0).
158
- line(x, y + y_offset, x + width, y + y_offset).
159
- stroke
190
+ canvas.save_graphics_state do
191
+ canvas.stroke_color(style.fill_color).
192
+ line_width(style.calculated_strikeout_thickness).
193
+ line_cap_style(:butt).
194
+ line_dash_pattern(0).
195
+ line(x, y + y_offset, x + width, y + y_offset).
196
+ stroke
197
+ end
160
198
  end
161
199
 
162
200
  style.overlays.draw(canvas, x, y + y_min, self)
@@ -200,7 +238,7 @@ module HexaPDF
200
238
  # in PDF1.7 s9.4.4. By using kerning values as the first and/or last items, the text contained
201
239
  # in the fragment may spill over the left and/or right boundary.
202
240
  def width
203
- @width ||= @items.sum {|item| style.scaled_item_width(item)}
241
+ @width ||= @items.sum {|item| style.scaled_item_width(item) }
204
242
  end
205
243
 
206
244
  # The height of the text fragment.