hexapdf 0.6.0 → 0.7.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 (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
@@ -5,37 +5,37 @@ require 'hexapdf/font/cmap/writer'
5
5
 
6
6
  describe HexaPDF::Font::CMap::Writer do
7
7
  before do
8
- @cmap_data = <<EOF
9
- /CIDInit /ProcSet findresource begin
10
- 12 dict begin
11
- begincmap
12
- /CIDSystemInfo
13
- << /Registry (Adobe)
14
- /Ordering (UCS)
15
- /Supplement 0
16
- >> def
17
- /CMapName /Adobe-Identity-UCS def
18
- /CMapType 2 def
19
- 1 begincodespacerange
20
- <0000> <FFFF>
21
- endcodespacerange
22
- 2 beginbfchar
23
- <0060><0090>
24
- <3A51><d840dc3e>
25
- endbfchar
26
- 2 beginbfrange
27
- <0000><005E><0020>
28
- <1379><137B><90fe>
29
- endbfrange
30
- endcmap
31
- CMapName currentdict /CMap defineresource pop
32
- end
33
- end
34
- EOF
8
+ @cmap_data = <<~EOF
9
+ /CIDInit /ProcSet findresource begin
10
+ 12 dict begin
11
+ begincmap
12
+ /CIDSystemInfo
13
+ << /Registry (Adobe)
14
+ /Ordering (UCS)
15
+ /Supplement 0
16
+ >> def
17
+ /CMapName /Adobe-Identity-UCS def
18
+ /CMapType 2 def
19
+ 1 begincodespacerange
20
+ <0000> <FFFF>
21
+ endcodespacerange
22
+ 2 beginbfchar
23
+ <0060><0090>
24
+ <3A51><d840dc3e>
25
+ endbfchar
26
+ 2 beginbfrange
27
+ <0000><005E><0020>
28
+ <1379><137B><90fe>
29
+ endbfrange
30
+ endcmap
31
+ CMapName currentdict /CMap defineresource pop
32
+ end
33
+ end
34
+ EOF
35
35
  @mapping = []
36
- 0x00.upto(0x5e) {|i| @mapping << [i, 0x20 + i]}
36
+ 0x00.upto(0x5e) {|i| @mapping << [i, 0x20 + i] }
37
37
  @mapping << [0x60, 0x90]
38
- 0x1379.upto(0x137B) {|i| @mapping << [i, 0x90FE + i - 0x1379]}
38
+ 0x1379.upto(0x137B) {|i| @mapping << [i, 0x90FE + i - 0x1379] }
39
39
  @mapping << [0x3A51, 0x2003E]
40
40
  end
41
41
 
@@ -32,7 +32,7 @@ describe HexaPDF::Font::TrueTypeWrapper do
32
32
  describe "decode_utf8" do
33
33
  it "returns an array of glyph objects" do
34
34
  assert_equal("Test",
35
- @font_wrapper.decode_utf8("Test").map {|g| @cmap.gid_to_code(g.id)}.pack('U*'))
35
+ @font_wrapper.decode_utf8("Test").map {|g| @cmap.gid_to_code(g.id) }.pack('U*'))
36
36
  end
37
37
 
38
38
  it "invokes font.on_missing_glyph for UTF-8 characters for which no glyph exists" do
@@ -110,7 +110,8 @@ describe HexaPDF::Font::TrueTypeWrapper do
110
110
  cidfont = dict[:DescendantFonts][0]
111
111
  assert_equal(:Font, cidfont[:Type])
112
112
  assert_equal(:CIDFontType2, cidfont[:Subtype])
113
- assert_equal({Registry: "Adobe", Ordering: "Identity", Supplement: 0}, cidfont[:CIDSystemInfo])
113
+ assert_equal({Registry: "Adobe", Ordering: "Identity", Supplement: 0},
114
+ cidfont[:CIDSystemInfo])
114
115
  assert_equal(:Identity, cidfont[:CIDToGIDMap])
115
116
  assert_equal(@font_wrapper.glyph(3).width, cidfont[:DW])
116
117
  assert_equal([2, [glyph.width]], cidfont[:W])
@@ -5,11 +5,13 @@ require 'hexapdf/font/true_type/table'
5
5
  module TestHelper
6
6
 
7
7
  class TrueTypeTestTable < HexaPDF::Font::TrueType::Table
8
+
8
9
  attr_reader :data
9
10
 
10
11
  def parse_table
11
12
  @data = io.read(directory_entry.length)
12
13
  end
14
+
13
15
  end
14
16
 
15
17
  end
@@ -11,7 +11,7 @@ describe HexaPDF::Font::TrueType::Table::Cmap do
11
11
  [0, 1, 28],
12
12
  [3, 1, 28 + f0.length],
13
13
  [1, 0, 28],
14
- ].map {|a| a.pack('n2N')}.join('') << f0 << f0
14
+ ].map {|a| a.pack('n2N') }.join('') << f0 << f0
15
15
  set_up_stub_true_type_font(data)
16
16
  end
17
17
 
@@ -38,7 +38,7 @@ describe HexaPDF::Font::TrueType::Table::CmapSubtable do
38
38
 
39
39
  describe "parse" do
40
40
  def table(data)
41
- @klass.new(3, 1).tap {|obj| obj.parse(StringIO.new(data), 0)}
41
+ @klass.new(3, 1).tap {|obj| obj.parse(StringIO.new(data), 0) }
42
42
  end
43
43
 
44
44
  it "works for format 0" do
@@ -49,11 +49,13 @@ describe HexaPDF::Font::TrueType::Table::CmapSubtable do
49
49
 
50
50
  assert_equal(0, t.gid_to_code(255))
51
51
  assert_equal(234, t.gid_to_code(233))
52
+
53
+ assert_raises(HexaPDF::Error) { table([0, 20, 0].pack('n3') + "a" * 20) }
52
54
  end
53
55
 
54
56
  it "works for format 2" do
55
57
  f2 = ([0, 8] + [0] * 254).pack('n*') + \
56
- [[0, 256, 0, 2 + 8], [0x33, 3, 5, 2 + 256 * 2]].map {|a| a.pack('n2s>n')}.join('') + \
58
+ [[0, 256, 0, 2 + 8], [0x33, 3, 5, 2 + 256 * 2]].map {|a| a.pack('n2s>n') }.join('') + \
57
59
  ((0..255).to_a + [35, 65534, 0]).pack('n*')
58
60
  t = table([2, f2.length + 6, 0].pack('n3') << f2)
59
61
  assert_nil(t[0x0132])
@@ -70,7 +72,7 @@ describe HexaPDF::Font::TrueType::Table::CmapSubtable do
70
72
  end
71
73
 
72
74
  it "works for format 4" do
73
- f4 = [6, 8, 2, 4, 35, 134, 65535, 0, 30, 133, 65535, 100, 110, 120,
75
+ f4 = [6, 8, 2, 4, 35, 134, 65535, 0, 30, 133, 65535, 100, 110, 120,
74
76
  0, 6, 2, 65500, 0, 1].pack('n*')
75
77
  t = table([4, f4.length + 6, 0].pack('n3') << f4)
76
78
  assert_nil(t[25])
@@ -135,6 +137,5 @@ describe HexaPDF::Font::TrueType::Table::CmapSubtable do
135
137
  it "returns false if a format is not supported" do
136
138
  refute(@klass.new(3, 1).parse(StringIO.new("\x00\x03".b), 0))
137
139
  end
138
-
139
140
  end
140
141
  end
@@ -8,8 +8,8 @@ describe HexaPDF::Font::TrueType::Table::Glyf do
8
8
  before do
9
9
  loca = Object.new
10
10
  loca.define_singleton_method(:offsets) { @offsets ||= [] }
11
- loca.define_singleton_method(:offset) {|i| @offsets[i]}
12
- loca.define_singleton_method(:length) {|i| @offsets[i + 1] - @offsets[i]}
11
+ loca.define_singleton_method(:offset) {|i| @offsets[i] }
12
+ loca.define_singleton_method(:length) {|i| @offsets[i + 1] - @offsets[i] }
13
13
  loca.offsets << 0 << 0
14
14
  data = [1, -10, -20, 100, 150].pack('s>5')
15
15
  loca.offsets << data.size
@@ -16,8 +16,8 @@ describe HexaPDF::Font::TrueType::Table::Head do
16
16
  describe "initialize" do
17
17
  it "reads the data from the associated file" do
18
18
  table = create_table(:Head)
19
- assert_equal('1.0', '%1.1f' % table.version)
20
- assert_equal('2.1', '%1.1f' % table.font_revision)
19
+ assert_equal('1.0', sprintf('%1.1f', table.version))
20
+ assert_equal('2.1', sprintf('%1.1f', table.font_revision))
21
21
  assert_equal(42, table.checksum_adjustment)
22
22
  assert_equal(3, table.flags)
23
23
  assert_equal(64, table.units_per_em)
@@ -9,7 +9,7 @@ describe HexaPDF::Font::TrueType::Table::Name do
9
9
  data = [0, 3, 42].pack('n3') << \
10
10
  [1, 0, 0, 0, 4, 0].pack('n6') << \
11
11
  [0, 3, 1, 0, 8, 4].pack('n6') << \
12
- [0, 3, 2, 1, 14, 12].pack('n6') << \
12
+ [3, 1, 1033, 1, 14, 12].pack('n6') << \
13
13
  'hexa'.encode('MACROMAN').b << \
14
14
  'hexa'.encode('UTF-16BE').b <<
15
15
  'hexapdf'.encode('UTF-16BE').b
@@ -30,10 +30,12 @@ describe HexaPDF::Font::TrueType::Table::Name do
30
30
  assert_equal(3, table[:copyright][1].encoding_id)
31
31
  assert_equal(1, table[:copyright][1].language_id)
32
32
  assert_equal('hexapdf', table[:font_family][0])
33
- assert_equal(0, table[:font_family][0].platform_id)
34
- assert_equal(3, table[:font_family][0].encoding_id)
35
- assert_equal(2, table[:font_family][0].language_id)
36
- assert_equal(table[:copyright][0], table[:copyright].preferred_record)
33
+ assert_equal(3, table[:font_family][0].platform_id)
34
+ assert_equal(1, table[:font_family][0].encoding_id)
35
+ assert_equal(1033, table[:font_family][0].language_id)
36
+
37
+ assert_equal(table[0][0], table[0].preferred_record)
38
+ assert_equal(table[:font_family][0], table[:font_family].preferred_record)
37
39
  end
38
40
 
39
41
  it "reads the data in format 1 from the associated file" do
@@ -55,7 +57,7 @@ describe HexaPDF::Font::TrueType::Table::Name do
55
57
  it "returns the correct value" do
56
58
  assert(@table[:copyright][0].platform?(:macintosh))
57
59
  assert(@table[:copyright][1].platform?(:unicode))
58
- refute(@table[:copyright][0].platform?(:microsoft))
60
+ assert(@table[:font_family][0].platform?(:microsoft))
59
61
  end
60
62
 
61
63
  it "raises an error when called with an unknown identifier" do
@@ -67,6 +69,7 @@ describe HexaPDF::Font::TrueType::Table::Name do
67
69
  it "returns true for names in US English that had been converted to UTF-8" do
68
70
  assert(@table[:copyright][0].preferred?)
69
71
  refute(@table[:copyright][1].preferred?)
72
+ assert(@table[:font_family][0].preferred?)
70
73
  end
71
74
  end
72
75
  end
@@ -9,7 +9,6 @@ describe HexaPDF::Font::TrueType::Builder do
9
9
  before do
10
10
  font_file = File.join(TEST_DATA_DIR, "fonts", "Ubuntu-Title.ttf")
11
11
  @font = HexaPDF::Font::TrueType::Font.new(File.open(font_file))
12
- @subsetter = HexaPDF::Font::TrueType::Subsetter.new(@font)
13
12
  end
14
13
 
15
14
  after do
@@ -18,9 +17,9 @@ describe HexaPDF::Font::TrueType::Builder do
18
17
 
19
18
  it "builds the font file" do
20
19
  tables = {
20
+ "loca" => @font[:loca].raw_data << "0",
21
21
  "head" => @font[:head].raw_data,
22
22
  "glyf" => @font[:glyf].raw_data,
23
- "loca" => @font[:loca].raw_data,
24
23
  "maxp" => @font[:maxp].raw_data,
25
24
  }
26
25
  font_data = HexaPDF::Font::TrueType::Builder.build(tables)
@@ -28,10 +27,16 @@ describe HexaPDF::Font::TrueType::Builder do
28
27
 
29
28
  assert(built_font[:head].checksum_valid?)
30
29
  assert_equal(@font[:glyf].raw_data, built_font[:glyf].raw_data)
30
+ assert(built_font.directory.entry('glyf').offset % 4 == 0)
31
31
  assert(built_font[:glyf].checksum_valid?)
32
- assert_equal(@font[:loca].raw_data, built_font[:loca].raw_data)
32
+ assert_equal(@font[:loca].raw_data << "0", built_font[:loca].raw_data)
33
33
  assert(built_font[:loca].checksum_valid?)
34
+ assert(built_font.directory.entry('loca').offset % 4 == 0)
34
35
  assert_equal(@font[:maxp].raw_data, built_font[:maxp].raw_data)
35
36
  assert(built_font[:maxp].checksum_valid?)
37
+ assert(built_font.directory.entry('maxp').offset % 4 == 0)
38
+
39
+ tables = built_font.directory.instance_variable_get(:@tables)
40
+ assert_equal(tables.keys.sort, tables.keys)
36
41
  end
37
42
  end
@@ -8,7 +8,6 @@ describe HexaPDF::Font::TrueType::Optimizer do
8
8
  before do
9
9
  font_file = File.join(TEST_DATA_DIR, "fonts", "Ubuntu-Title.ttf")
10
10
  @font = HexaPDF::Font::TrueType::Font.new(File.open(font_file))
11
- @subsetter = HexaPDF::Font::TrueType::Subsetter.new(@font)
12
11
  end
13
12
 
14
13
  after do
@@ -19,7 +18,7 @@ describe HexaPDF::Font::TrueType::Optimizer do
19
18
  it "builds a font file that is optimized for use with PDFs" do
20
19
  font_data = HexaPDF::Font::TrueType::Optimizer.build_for_pdf(@font)
21
20
  built_font = HexaPDF::Font::TrueType::Font.new(StringIO.new(font_data))
22
- %I(FFTM GDEF GPOS GSUB name post).each do |table|
21
+ [:FFTM, :GDEF, :GPOS, :GSUB, :name, :post].each do |table|
23
22
  refute(built_font[table])
24
23
  end
25
24
  end
@@ -11,7 +11,7 @@ describe HexaPDF::Font::Type1::AFMParser do
11
11
  describe "::parse" do
12
12
  before do
13
13
  @file = Tempfile.new('hexapdf-afm')
14
- @file.write("StartFontMetrics 4.1\nFontName Test\nEndFontMetrics\n")
14
+ @file.write("StartFontMetrics 4.1\nFontName Test\nEndFontMetrics\nFontName Other\n")
15
15
  @file.close
16
16
  end
17
17
 
@@ -35,7 +35,7 @@ describe HexaPDF::Font::Type1::AFMParser do
35
35
  basename = File.basename(file, '.*')
36
36
  assert_equal(basename, metrics.font_name, basename)
37
37
  assert_equal(basename.sub(/-.*/, ''), metrics.family_name, basename)
38
- assert(metrics.character_metrics.size > 0, basename)
38
+ refute(metrics.character_metrics.empty?, basename)
39
39
  end
40
40
  end
41
41
 
@@ -15,7 +15,7 @@ describe HexaPDF::ImageLoader::JPEG do
15
15
  it "works for jpeg files" do
16
16
  @images.each do |image|
17
17
  assert(@loader.handles?(image))
18
- File.open(image, 'rb') {|file| assert(@loader.handles?(file))}
18
+ File.open(image, 'rb') {|file| assert(@loader.handles?(file)) }
19
19
  end
20
20
  end
21
21
  end
@@ -14,7 +14,7 @@ describe HexaPDF::ImageLoader::PDF do
14
14
  describe "handles?" do
15
15
  it "works for PDF files" do
16
16
  assert(@loader.handles?(@pdf))
17
- File.open(@pdf, 'rb') {|file| assert(@loader.handles?(file))}
17
+ File.open(@pdf, 'rb') {|file| assert(@loader.handles?(file)) }
18
18
  end
19
19
  end
20
20
 
@@ -15,7 +15,7 @@ describe HexaPDF::ImageLoader::PNG do
15
15
  it "works for png files" do
16
16
  @images.each do |image|
17
17
  assert(@loader.handles?(image))
18
- File.open(image, 'rb') {|file| assert(@loader.handles?(file))}
18
+ File.open(image, 'rb') {|file| assert(@loader.handles?(file)) }
19
19
  end
20
20
  end
21
21
  end
@@ -30,7 +30,7 @@ describe HexaPDF::ImageLoader::PNG do
30
30
  assert_equal(height, image[:Height])
31
31
  assert_equal(bpc, image[:BitsPerComponent])
32
32
  assert_equal(color_space, image[:ColorSpace]) if color_space
33
- data = stream.map {|row| [row.map {|i| i.to_s(2).rjust(bpc, '0')}.join("")].pack('B*')}.join("")
33
+ data = stream.map {|row| [row.map {|i| i.to_s(2).rjust(bpc, '0') }.join("")].pack('B*') }.join("")
34
34
  assert_equal(data, image.stream)
35
35
  end
36
36
 
@@ -231,7 +231,7 @@ describe HexaPDF::ImageLoader::PNG do
231
231
  zip(image[:ColorSpace][1][:Matrix]).each do |r, e|
232
232
  assert_in_delta(r, e, 0.0001)
233
233
  end
234
- if png =~ /srgb/
234
+ if png.match?(/srgb/)
235
235
  assert_equal(:AbsoluteColorimetric, image[:Intent])
236
236
  end
237
237
  end
@@ -8,9 +8,18 @@ describe HexaPDF::Layout::InlineBox do
8
8
  @box = HexaPDF::Layout::InlineBox.create(width: 10, height: 15, style: {margin: [15, 10]})
9
9
  end
10
10
 
11
+ it "needs a box to wrap and an optional alignment on initialization" do
12
+ ibox = HexaPDF::Layout::InlineBox.new(@box)
13
+ assert_equal(@box, ibox.box)
14
+ assert_equal(:baseline, ibox.valign)
15
+
16
+ ibox = HexaPDF::Layout::InlineBox.new(@box, valign: :top)
17
+ assert_equal(:top, ibox.valign)
18
+ end
19
+
11
20
  it "draws the wrapped box at the correct position" do
12
21
  canvas = Object.new
13
- block = ->(c, x, y) do
22
+ block = lambda do |c, x, y|
14
23
  assert_equal(canvas, c)
15
24
  assert_equal(10, x)
16
25
  assert_equal(15, y)
@@ -35,7 +35,7 @@ describe HexaPDF::Layout::Line do
35
35
  describe "initialize" do
36
36
  it "allows setting the items of the line fragment" do
37
37
  frag1 = setup_fragment("Hello")
38
- frag2 = HexaPDF::Layout::TextFragment.new(items: frag1.items.slice!(3, 2), style: frag1.style)
38
+ frag2 = HexaPDF::Layout::TextFragment.new(frag1.items.slice!(3, 2), frag1.style)
39
39
  line = HexaPDF::Layout::Line.new([frag1, frag2])
40
40
  assert_equal(1, line.items.count)
41
41
  assert_equal(5, line.items[0].items.count)
@@ -50,7 +50,7 @@ describe HexaPDF::Layout::Line do
50
50
 
51
51
  it "combines text fragments if possible" do
52
52
  frag1 = setup_fragment("Home")
53
- frag2 = HexaPDF::Layout::TextFragment.new(items: frag1.items.slice!(2, 2), style: frag1.style)
53
+ frag2 = HexaPDF::Layout::TextFragment.new(frag1.items.slice!(2, 2), frag1.style)
54
54
  @line << setup_fragment("o") << :other << frag1 << frag2
55
55
  assert_equal(3, @line.items.length)
56
56
  assert_equal(4, @line.items.last.items.length)
@@ -58,7 +58,7 @@ describe HexaPDF::Layout::Line do
58
58
 
59
59
  it "duplicates the first of two combinable text fragments if its items are frozen" do
60
60
  frag1 = setup_fragment("Home")
61
- frag2 = HexaPDF::Layout::TextFragment.new(items: frag1.items.slice!(2, 2), style: frag1.style)
61
+ frag2 = HexaPDF::Layout::TextFragment.new(frag1.items.slice!(2, 2), frag1.style)
62
62
  frag1.items.freeze
63
63
  frag2.items.freeze
64
64
 
@@ -189,7 +189,7 @@ describe HexaPDF::Layout::Line do
189
189
  [@line.items[4], @line.items[0].width + 30, @line.text_y_min],
190
190
  [@line.items[5], @line.items[0].width + 40, @line.y_min],
191
191
  ]
192
- assert_equal(result, @line.to_enum(:each).map {|*a| a})
192
+ assert_equal(result, @line.to_enum(:each).map {|*a| a })
193
193
  end
194
194
 
195
195
  it "fails if an item uses an invalid valign value" do
@@ -10,7 +10,7 @@ require 'hexapdf/layout/box'
10
10
  describe HexaPDF::Layout::Style::LineSpacing do
11
11
  before do
12
12
  @line1 = Object.new
13
- @line1.define_singleton_method(:y_min) { - 1}
13
+ @line1.define_singleton_method(:y_min) { - 1 }
14
14
  @line1.define_singleton_method(:y_max) { 2 }
15
15
  @line2 = Object.new
16
16
  @line2.define_singleton_method(:y_min) { -3 }
@@ -87,6 +87,12 @@ describe HexaPDF::Layout::Style::Quad do
87
87
  assert_equal(5, quad.right)
88
88
  assert_equal(5, quad.bottom)
89
89
  assert_equal(5, quad.left)
90
+
91
+ quad = create_quad([5])
92
+ assert_equal(5, quad.top)
93
+ assert_equal(5, quad.right)
94
+ assert_equal(5, quad.bottom)
95
+ assert_equal(5, quad.left)
90
96
  end
91
97
 
92
98
  it "works with two values" do
@@ -351,14 +357,14 @@ describe HexaPDF::Layout::Style::Layers do
351
357
  end
352
358
 
353
359
  it "can be initialized with an array of layers" do
354
- data = [-> {}]
360
+ data = [lambda {}]
355
361
  layers = HexaPDF::Layout::Style::Layers.new(data)
356
362
  assert_equal(data, layers.enum_for(:each, {}).to_a)
357
363
  end
358
364
 
359
365
  describe "add and each" do
360
366
  it "can use a given block" do
361
- block = proc { true}
367
+ block = proc { true }
362
368
  @layers.add(&block)
363
369
  assert_equal([block], @layers.enum_for(:each, {}).to_a)
364
370
  end
@@ -366,9 +372,9 @@ describe HexaPDF::Layout::Style::Layers do
366
372
  it "can store a reference" do
367
373
  @layers.add(:link, option: :value)
368
374
  value = Object.new
369
- value.define_singleton_method(:new) {|*args| :new }
375
+ value.define_singleton_method(:new) {|*| :new }
370
376
  config = Object.new
371
- config.define_singleton_method(:constantize) {|*args| value }
377
+ config.define_singleton_method(:constantize) {|*| value }
372
378
  assert_equal([:new], @layers.enum_for(:each, config).to_a)
373
379
  end
374
380
 
@@ -395,7 +401,8 @@ describe HexaPDF::Layout::Style::Layers do
395
401
  canvas = HexaPDF::Document.new.pages.add.canvas
396
402
  canvas.context.document.config['style.layers_map'][:test] = klass
397
403
 
398
- @layers.add {|canv, ibox| assert_equal(box, ibox); canv.line_width(10)}
404
+ @layers.draw(canvas, 10, 15, box)
405
+ @layers.add {|canv, ibox| assert_equal(box, ibox); canv.line_width(10) }
399
406
  @layers.add(:test, option: :value)
400
407
  @layers.draw(canvas, 10, 15, box)
401
408
  ops = [[:save_graphics_state],
@@ -435,7 +442,12 @@ describe HexaPDF::Layout::Style::LinkLayer do
435
442
  def call_link(hash)
436
443
  link = HexaPDF::Layout::Style::LinkLayer.new(hash)
437
444
  link.call(@canvas, @box)
438
- @canvas.context[:Annots][0]
445
+ @canvas.context[:Annots]&.first
446
+ end
447
+
448
+ it "does nothing if the context is not a page object" do
449
+ @canvas = HexaPDF::Document.new.add(Type: :XObject, Subtype: :Form).canvas
450
+ assert_nil(call_link(dest: true))
439
451
  end
440
452
 
441
453
  it "sets general values like /Rect and /QuadPoints" do