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
@@ -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