hexapdf 0.11.9 → 0.13.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +157 -0
- data/LICENSE +1 -1
- data/examples/001-hello_world.rb +1 -1
- data/examples/002-graphics.rb +1 -1
- data/examples/003-arcs.rb +1 -1
- data/examples/004-optimizing.rb +1 -1
- data/examples/005-merging.rb +1 -1
- data/examples/006-standard_pdf_fonts.rb +1 -1
- data/examples/007-truetype.rb +1 -1
- data/examples/008-show_char_bboxes.rb +1 -1
- data/examples/009-text_layouter_alignment.rb +1 -1
- data/examples/010-text_layouter_inline_boxes.rb +1 -1
- data/examples/011-text_layouter_line_wrapping.rb +1 -1
- data/examples/012-text_layouter_styling.rb +1 -1
- data/examples/013-text_layouter_shapes.rb +1 -1
- data/examples/014-text_in_polygon.rb +1 -1
- data/examples/015-boxes.rb +1 -1
- data/examples/016-frame_automatic_box_placement.rb +1 -1
- data/examples/017-frame_text_flow.rb +1 -1
- data/examples/018-composer.rb +1 -1
- data/examples/019-acro_form.rb +51 -0
- data/lib/hexapdf.rb +1 -1
- data/lib/hexapdf/cli.rb +3 -1
- data/lib/hexapdf/cli/batch.rb +1 -1
- data/lib/hexapdf/cli/command.rb +22 -11
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/form.rb +240 -0
- data/lib/hexapdf/cli/image2pdf.rb +3 -2
- data/lib/hexapdf/cli/images.rb +1 -1
- data/lib/hexapdf/cli/info.rb +52 -3
- data/lib/hexapdf/cli/inspect.rb +31 -9
- data/lib/hexapdf/cli/merge.rb +2 -2
- data/lib/hexapdf/cli/modify.rb +1 -1
- data/lib/hexapdf/cli/optimize.rb +1 -1
- data/lib/hexapdf/cli/split.rb +1 -1
- data/lib/hexapdf/cli/watermark.rb +1 -1
- data/lib/hexapdf/composer.rb +2 -2
- data/lib/hexapdf/configuration.rb +81 -11
- data/lib/hexapdf/content.rb +3 -1
- data/lib/hexapdf/content/canvas.rb +5 -18
- data/lib/hexapdf/content/color_space.rb +111 -32
- data/lib/hexapdf/content/graphic_object.rb +1 -1
- data/lib/hexapdf/content/graphic_object/arc.rb +4 -4
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
- data/lib/hexapdf/content/graphics_state.rb +1 -1
- data/lib/hexapdf/content/operator.rb +9 -9
- data/lib/hexapdf/content/parser.rb +18 -5
- data/lib/hexapdf/content/processor.rb +1 -1
- data/lib/hexapdf/content/transformation_matrix.rb +1 -1
- data/lib/hexapdf/data_dir.rb +1 -1
- data/lib/hexapdf/dictionary.rb +5 -5
- data/lib/hexapdf/dictionary_fields.rb +2 -10
- data/lib/hexapdf/document.rb +45 -17
- data/lib/hexapdf/document/files.rb +1 -2
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/images.rb +1 -1
- data/lib/hexapdf/document/pages.rb +3 -14
- data/lib/hexapdf/encryption.rb +1 -1
- data/lib/hexapdf/encryption/aes.rb +1 -1
- data/lib/hexapdf/encryption/arc4.rb +1 -1
- data/lib/hexapdf/encryption/fast_aes.rb +1 -1
- data/lib/hexapdf/encryption/fast_arc4.rb +2 -2
- data/lib/hexapdf/encryption/identity.rb +1 -1
- data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
- data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
- data/lib/hexapdf/encryption/security_handler.rb +2 -1
- data/lib/hexapdf/encryption/standard_security_handler.rb +2 -1
- data/lib/hexapdf/error.rb +1 -1
- data/lib/hexapdf/filter.rb +3 -3
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
- data/lib/hexapdf/filter/encryption.rb +1 -1
- data/lib/hexapdf/filter/flate_decode.rb +1 -1
- data/lib/hexapdf/filter/lzw_decode.rb +1 -1
- data/lib/hexapdf/filter/{jpx_decode.rb → pass_through.rb} +5 -5
- data/lib/hexapdf/filter/predictor.rb +1 -1
- data/lib/hexapdf/filter/run_length_decode.rb +1 -1
- data/lib/hexapdf/font/cmap.rb +2 -5
- data/lib/hexapdf/font/cmap/parser.rb +1 -1
- data/lib/hexapdf/font/cmap/writer.rb +1 -1
- data/lib/hexapdf/font/encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/base.rb +9 -1
- data/lib/hexapdf/font/encoding/difference_encoding.rb +7 -1
- data/lib/hexapdf/font/encoding/glyph_list.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
- data/lib/hexapdf/font/invalid_glyph.rb +1 -1
- data/lib/hexapdf/font/true_type.rb +1 -1
- data/lib/hexapdf/font/true_type/builder.rb +1 -1
- data/lib/hexapdf/font/true_type/font.rb +1 -1
- data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
- data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
- data/lib/hexapdf/font/true_type/table.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
- data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
- data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
- data/lib/hexapdf/font/true_type/table/head.rb +2 -1
- data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
- data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
- data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
- data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
- data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
- data/lib/hexapdf/font/true_type/table/name.rb +1 -1
- data/lib/hexapdf/font/true_type/table/os2.rb +3 -1
- data/lib/hexapdf/font/true_type/table/post.rb +1 -1
- data/lib/hexapdf/font/true_type_wrapper.rb +54 -51
- data/lib/hexapdf/font/type1.rb +1 -1
- data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
- data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/font.rb +1 -1
- data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
- data/lib/hexapdf/font/type1_wrapper.rb +68 -52
- data/lib/hexapdf/font_loader.rb +1 -1
- data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
- data/lib/hexapdf/font_loader/from_file.rb +1 -1
- data/lib/hexapdf/font_loader/standard14.rb +1 -1
- data/lib/hexapdf/image_loader.rb +1 -1
- data/lib/hexapdf/image_loader/jpeg.rb +1 -1
- data/lib/hexapdf/image_loader/pdf.rb +1 -1
- data/lib/hexapdf/image_loader/png.rb +4 -3
- data/lib/hexapdf/importer.rb +2 -4
- data/lib/hexapdf/layout.rb +1 -1
- data/lib/hexapdf/layout/box.rb +1 -1
- data/lib/hexapdf/layout/frame.rb +1 -1
- data/lib/hexapdf/layout/image_box.rb +1 -1
- data/lib/hexapdf/layout/inline_box.rb +1 -1
- data/lib/hexapdf/layout/line.rb +2 -2
- data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
- data/lib/hexapdf/layout/style.rb +24 -24
- data/lib/hexapdf/layout/text_box.rb +1 -1
- data/lib/hexapdf/layout/text_fragment.rb +1 -1
- data/lib/hexapdf/layout/text_layouter.rb +1 -1
- data/lib/hexapdf/layout/text_shaper.rb +4 -3
- data/lib/hexapdf/layout/width_from_polygon.rb +1 -1
- data/lib/hexapdf/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +32 -27
- data/lib/hexapdf/parser.rb +69 -6
- data/lib/hexapdf/pdf_array.rb +10 -3
- data/lib/hexapdf/rectangle.rb +31 -1
- data/lib/hexapdf/reference.rb +1 -1
- data/lib/hexapdf/revision.rb +2 -1
- data/lib/hexapdf/revisions.rb +30 -22
- data/lib/hexapdf/serializer.rb +2 -2
- data/lib/hexapdf/stream.rb +1 -1
- data/lib/hexapdf/task.rb +1 -1
- data/lib/hexapdf/task/dereference.rb +1 -1
- data/lib/hexapdf/task/optimize.rb +7 -5
- data/lib/hexapdf/tokenizer.rb +5 -4
- data/lib/hexapdf/type.rb +1 -1
- data/lib/hexapdf/type/acro_form.rb +7 -1
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +405 -0
- data/lib/hexapdf/type/acro_form/button_field.rb +305 -0
- data/lib/hexapdf/type/acro_form/choice_field.rb +220 -0
- data/lib/hexapdf/type/acro_form/field.rb +250 -17
- data/lib/hexapdf/type/acro_form/form.rb +159 -7
- data/lib/hexapdf/type/acro_form/text_field.rb +187 -0
- data/lib/hexapdf/type/acro_form/variable_text_field.rb +122 -0
- data/lib/hexapdf/type/action.rb +1 -1
- data/lib/hexapdf/type/actions.rb +1 -1
- data/lib/hexapdf/type/actions/go_to.rb +1 -1
- data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
- data/lib/hexapdf/type/actions/launch.rb +1 -1
- data/lib/hexapdf/type/actions/uri.rb +4 -3
- data/lib/hexapdf/type/annotation.rb +73 -3
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/annotations/link.rb +2 -2
- data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
- data/lib/hexapdf/type/annotations/text.rb +1 -1
- data/lib/hexapdf/type/annotations/widget.rb +238 -2
- data/lib/hexapdf/type/catalog.rb +23 -3
- data/lib/hexapdf/type/cid_font.rb +1 -1
- data/lib/hexapdf/type/embedded_file.rb +1 -1
- data/lib/hexapdf/type/file_specification.rb +2 -2
- data/lib/hexapdf/type/font.rb +18 -1
- data/lib/hexapdf/type/font_descriptor.rb +2 -2
- data/lib/hexapdf/type/font_simple.rb +4 -2
- data/lib/hexapdf/type/font_true_type.rb +7 -3
- data/lib/hexapdf/type/font_type0.rb +2 -2
- data/lib/hexapdf/type/font_type1.rb +16 -1
- data/lib/hexapdf/type/font_type3.rb +1 -1
- data/lib/hexapdf/type/form.rb +12 -2
- data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
- data/lib/hexapdf/type/icon_fit.rb +1 -1
- data/lib/hexapdf/type/image.rb +5 -3
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/names.rb +1 -1
- data/lib/hexapdf/type/object_stream.rb +1 -1
- data/lib/hexapdf/type/page.rb +36 -12
- data/lib/hexapdf/type/page_tree_node.rb +37 -16
- data/lib/hexapdf/type/resources.rb +17 -3
- data/lib/hexapdf/type/trailer.rb +4 -6
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +1 -1
- data/lib/hexapdf/utils/bit_field.rb +38 -24
- data/lib/hexapdf/utils/bit_stream.rb +1 -1
- data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
- data/lib/hexapdf/utils/lru_cache.rb +1 -1
- data/lib/hexapdf/utils/math_helpers.rb +1 -1
- data/lib/hexapdf/utils/object_hash.rb +1 -1
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
- data/lib/hexapdf/utils/sorted_tree_node.rb +19 -16
- data/lib/hexapdf/version.rb +2 -2
- data/lib/hexapdf/writer.rb +1 -1
- data/lib/hexapdf/xref_section.rb +1 -1
- data/test/hexapdf/common_tokenizer_tests.rb +6 -1
- data/test/hexapdf/content/common.rb +2 -2
- data/test/hexapdf/content/graphic_object/test_arc.rb +4 -4
- data/test/hexapdf/content/test_canvas.rb +3 -3
- data/test/hexapdf/content/test_color_space.rb +71 -8
- data/test/hexapdf/content/test_operator.rb +22 -22
- data/test/hexapdf/content/test_parser.rb +14 -0
- data/test/hexapdf/document/test_fonts.rb +1 -1
- data/test/hexapdf/document/test_pages.rb +6 -6
- data/test/hexapdf/encryption/test_aes.rb +4 -4
- data/test/hexapdf/encryption/test_standard_security_handler.rb +11 -11
- data/test/hexapdf/filter/test_ascii85_decode.rb +1 -1
- data/test/hexapdf/filter/test_ascii_hex_decode.rb +1 -1
- data/test/hexapdf/font/encoding/test_base.rb +10 -0
- data/test/hexapdf/font/encoding/test_difference_encoding.rb +8 -0
- data/test/hexapdf/font/test_true_type_wrapper.rb +10 -7
- data/test/hexapdf/font/test_type1_wrapper.rb +33 -8
- data/test/hexapdf/layout/test_style.rb +1 -1
- data/test/hexapdf/layout/test_text_layouter.rb +3 -4
- data/test/hexapdf/test_configuration.rb +2 -2
- data/test/hexapdf/test_dictionary.rb +3 -1
- data/test/hexapdf/test_dictionary_fields.rb +2 -2
- data/test/hexapdf/test_document.rb +16 -4
- data/test/hexapdf/test_object.rb +44 -26
- data/test/hexapdf/test_parser.rb +125 -55
- data/test/hexapdf/test_pdf_array.rb +7 -0
- data/test/hexapdf/test_rectangle.rb +14 -0
- data/test/hexapdf/test_revision.rb +3 -0
- data/test/hexapdf/test_revisions.rb +35 -0
- data/test/hexapdf/test_writer.rb +2 -2
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +521 -0
- data/test/hexapdf/type/acro_form/test_button_field.rb +281 -0
- data/test/hexapdf/type/acro_form/test_choice_field.rb +137 -0
- data/test/hexapdf/type/acro_form/test_field.rb +163 -6
- data/test/hexapdf/type/acro_form/test_form.rb +189 -22
- data/test/hexapdf/type/acro_form/test_text_field.rb +121 -0
- data/test/hexapdf/type/acro_form/test_variable_text_field.rb +77 -0
- data/test/hexapdf/type/annotations/test_text.rb +1 -1
- data/test/hexapdf/type/annotations/test_widget.rb +199 -0
- data/test/hexapdf/type/test_annotation.rb +45 -0
- data/test/hexapdf/type/test_catalog.rb +18 -0
- data/test/hexapdf/type/test_font.rb +5 -0
- data/test/hexapdf/type/test_font_simple.rb +2 -1
- data/test/hexapdf/type/test_font_true_type.rb +6 -0
- data/test/hexapdf/type/test_font_type1.rb +8 -0
- data/test/hexapdf/type/test_form.rb +19 -1
- data/test/hexapdf/type/test_image.rb +7 -0
- data/test/hexapdf/type/test_page.rb +45 -7
- data/test/hexapdf/type/test_page_tree_node.rb +62 -12
- data/test/hexapdf/type/test_resources.rb +20 -0
- data/test/hexapdf/type/test_trailer.rb +4 -0
- data/test/hexapdf/utils/test_bit_field.rb +15 -1
- data/test/hexapdf/utils/test_sorted_tree_node.rb +10 -9
- data/test/test_helper.rb +1 -1
- metadata +34 -21
- data/lib/hexapdf/filter/dct_decode.rb +0 -60
|
@@ -254,89 +254,89 @@ end
|
|
|
254
254
|
|
|
255
255
|
describe_operator :SetStrokingColor, :SC do
|
|
256
256
|
it "sets the stroking color" do
|
|
257
|
-
invoke(
|
|
258
|
-
assert_equal(@processor.resources.color_space(:DeviceGray).color(
|
|
257
|
+
invoke(0.2)
|
|
258
|
+
assert_equal(@processor.resources.color_space(:DeviceGray).color(51),
|
|
259
259
|
@processor.graphics_state.stroke_color)
|
|
260
260
|
end
|
|
261
261
|
|
|
262
262
|
it "serializes correctly" do
|
|
263
|
-
assert_serialized(
|
|
263
|
+
assert_serialized(0.2, 0.5, 0.8)
|
|
264
264
|
end
|
|
265
265
|
end
|
|
266
266
|
|
|
267
267
|
describe_operator :SetNonStrokingColor, :sc do
|
|
268
268
|
it "sets the non stroking color" do
|
|
269
|
-
invoke(
|
|
270
|
-
assert_equal(@processor.resources.color_space(:DeviceGray).color(
|
|
269
|
+
invoke(0.2)
|
|
270
|
+
assert_equal(@processor.resources.color_space(:DeviceGray).color(51),
|
|
271
271
|
@processor.graphics_state.fill_color)
|
|
272
272
|
end
|
|
273
273
|
|
|
274
274
|
it "serializes correctly" do
|
|
275
|
-
assert_serialized(
|
|
275
|
+
assert_serialized(0.2, 0.5, 0.8)
|
|
276
276
|
end
|
|
277
277
|
end
|
|
278
278
|
|
|
279
279
|
describe_operator :SetDeviceGrayStrokingColor, :G do
|
|
280
280
|
it "sets the DeviceGray stroking color" do
|
|
281
|
-
invoke(
|
|
282
|
-
assert_equal(@processor.resources.color_space(:DeviceGray).color(
|
|
281
|
+
invoke(0.2)
|
|
282
|
+
assert_equal(@processor.resources.color_space(:DeviceGray).color(51),
|
|
283
283
|
@processor.graphics_state.stroke_color)
|
|
284
284
|
end
|
|
285
285
|
end
|
|
286
286
|
|
|
287
287
|
describe_operator :SetDeviceGrayNonStrokingColor, :g do
|
|
288
288
|
it "sets the DeviceGray non stroking color" do
|
|
289
|
-
invoke(
|
|
290
|
-
assert_equal(@processor.resources.color_space(:DeviceGray).color(
|
|
289
|
+
invoke(0.2)
|
|
290
|
+
assert_equal(@processor.resources.color_space(:DeviceGray).color(51),
|
|
291
291
|
@processor.graphics_state.fill_color)
|
|
292
292
|
end
|
|
293
293
|
end
|
|
294
294
|
|
|
295
295
|
describe_operator :SetDeviceRGBStrokingColor, :RG do
|
|
296
296
|
it "sets the DeviceRGB stroking color" do
|
|
297
|
-
invoke(
|
|
298
|
-
assert_equal(@processor.resources.color_space(:DeviceRGB).color(
|
|
297
|
+
invoke(0.2, 0, 0.2)
|
|
298
|
+
assert_equal(@processor.resources.color_space(:DeviceRGB).color(51, 0, 51),
|
|
299
299
|
@processor.graphics_state.stroke_color)
|
|
300
300
|
end
|
|
301
301
|
|
|
302
302
|
it "serializes correctly" do
|
|
303
|
-
assert_serialized(
|
|
303
|
+
assert_serialized(0.2, 0.3, 0.4)
|
|
304
304
|
end
|
|
305
305
|
end
|
|
306
306
|
|
|
307
307
|
describe_operator :SetDeviceRGBNonStrokingColor, :rg do
|
|
308
308
|
it "sets the DeviceRGB non stroking color" do
|
|
309
|
-
invoke(
|
|
310
|
-
assert_equal(@processor.resources.color_space(:DeviceRGB).color(
|
|
309
|
+
invoke(0.2, 0, 0.2)
|
|
310
|
+
assert_equal(@processor.resources.color_space(:DeviceRGB).color(51, 0, 51),
|
|
311
311
|
@processor.graphics_state.fill_color)
|
|
312
312
|
end
|
|
313
313
|
|
|
314
314
|
it "serializes correctly" do
|
|
315
|
-
assert_serialized(
|
|
315
|
+
assert_serialized(0.2, 0.3, 0.4)
|
|
316
316
|
end
|
|
317
317
|
end
|
|
318
318
|
|
|
319
319
|
describe_operator :SetDeviceCMYKStrokingColor, :K do
|
|
320
320
|
it "sets the DeviceCMYK stroking color" do
|
|
321
|
-
invoke(
|
|
322
|
-
assert_equal(@processor.resources.color_space(:DeviceCMYK).color(
|
|
321
|
+
invoke(0.51, 0, 0.51, 0.51)
|
|
322
|
+
assert_equal(@processor.resources.color_space(:DeviceCMYK).color(51, 0, 51, 51),
|
|
323
323
|
@processor.graphics_state.stroke_color)
|
|
324
324
|
end
|
|
325
325
|
|
|
326
326
|
it "serializes correctly" do
|
|
327
|
-
assert_serialized(
|
|
327
|
+
assert_serialized(0.2, 0.3, 0.4, 0.5)
|
|
328
328
|
end
|
|
329
329
|
end
|
|
330
330
|
|
|
331
331
|
describe_operator :SetDeviceCMYKNonStrokingColor, :k do
|
|
332
332
|
it "sets the DeviceCMYK non stroking color" do
|
|
333
|
-
invoke(
|
|
334
|
-
assert_equal(@processor.resources.color_space(:DeviceCMYK).color(
|
|
333
|
+
invoke(0.51, 0, 0.51, 0.51)
|
|
334
|
+
assert_equal(@processor.resources.color_space(:DeviceCMYK).color(51, 0, 51, 51),
|
|
335
335
|
@processor.graphics_state.fill_color)
|
|
336
336
|
end
|
|
337
337
|
|
|
338
338
|
it "serializes correctly" do
|
|
339
|
-
assert_serialized(
|
|
339
|
+
assert_serialized(0.2, 0.3, 0.4, 0.5)
|
|
340
340
|
end
|
|
341
341
|
end
|
|
342
342
|
|
|
@@ -81,5 +81,19 @@ describe HexaPDF::Content::Parser do
|
|
|
81
81
|
end
|
|
82
82
|
assert_match(/EI not found/, exp.message)
|
|
83
83
|
end
|
|
84
|
+
|
|
85
|
+
it "can use a block instead of the processor object" do
|
|
86
|
+
called = 0
|
|
87
|
+
@parser.parse("/F1 5 Tf") do |obj, params|
|
|
88
|
+
called += 1
|
|
89
|
+
assert_equal(:Tf, obj)
|
|
90
|
+
assert_equal([:F1, 5], params)
|
|
91
|
+
end
|
|
92
|
+
assert_equal(1, called)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "fails if neither a processor object or a block is provided" do
|
|
96
|
+
assert_raises(ArgumentError) { @parser.parse("test") }
|
|
97
|
+
end
|
|
84
98
|
end
|
|
85
99
|
end
|
|
@@ -36,7 +36,7 @@ describe HexaPDF::Document::Fonts do
|
|
|
36
36
|
assert_same(font, @doc.fonts.add(:TestFont, variant: :none))
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
it "fails if the requested font is not found"
|
|
39
|
+
it "fails if the requested font is not found" do
|
|
40
40
|
@doc.config['font_loader'] << 'HexaPDF::FontLoader::Standard14'
|
|
41
41
|
error = assert_raises(HexaPDF::Error) { @doc.fonts.add("Unknown") }
|
|
42
42
|
assert_match(/Times \(none/, error.message)
|
|
@@ -74,20 +74,20 @@ describe HexaPDF::Document::Pages do
|
|
|
74
74
|
|
|
75
75
|
describe "delete" do
|
|
76
76
|
it "deletes a given page" do
|
|
77
|
-
|
|
78
|
-
@doc.pages.add
|
|
77
|
+
page1 = @doc.pages.add
|
|
78
|
+
page2 = @doc.pages.add
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
@doc.pages.delete(page1)
|
|
81
|
+
assert_equal([page2], @doc.pages.root[:Kids].value)
|
|
82
82
|
end
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
describe "delete_at" do
|
|
86
86
|
it "deletes a page at a given index" do
|
|
87
87
|
page1 = @doc.pages.add
|
|
88
|
-
|
|
88
|
+
@doc.pages.add
|
|
89
89
|
page3 = @doc.pages.add
|
|
90
|
-
|
|
90
|
+
@doc.pages.delete_at(1)
|
|
91
91
|
assert_equal([page1, page3], @doc.pages.root[:Kids].value)
|
|
92
92
|
end
|
|
93
93
|
end
|
|
@@ -101,13 +101,13 @@ describe HexaPDF::Encryption::AES do
|
|
|
101
101
|
result = TestHelper.collector(@algorithm_class.decryption_fiber('some' * 4, f))
|
|
102
102
|
assert_equal('a' * 16, result)
|
|
103
103
|
|
|
104
|
-
f = Fiber.new { 'a' * 31
|
|
104
|
+
f = Fiber.new { 'a' * 31 << "\x00" }
|
|
105
105
|
result = TestHelper.collector(@algorithm_class.decryption_fiber('some' * 4, f))
|
|
106
|
-
assert_equal('a' * 15
|
|
106
|
+
assert_equal('a' * 15 << "\x00", result)
|
|
107
107
|
|
|
108
|
-
f = Fiber.new { 'a' * 29
|
|
108
|
+
f = Fiber.new { 'a' * 29 << "\x00\x01\x03" }
|
|
109
109
|
result = TestHelper.collector(@algorithm_class.decryption_fiber('some' * 4, f))
|
|
110
|
-
assert_equal('a' * 13
|
|
110
|
+
assert_equal('a' * 13 << "\x00\x01\x03", result)
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
it "fails on decryption if not enough bytes are provided" do
|
|
@@ -53,24 +53,24 @@ describe HexaPDF::Encryption::StandardEncryptionDictionary do
|
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
describe HexaPDF::Encryption::StandardSecurityHandler do
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
test_files = Dir[File.join(TEST_DATA_DIR, 'standard-security-handler', '*.pdf')].sort
|
|
57
|
+
user_password = 'uhexapdf'
|
|
58
|
+
owner_password = 'ohexapdf'
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
minimal_doc = HexaPDF::Document.new(io: StringIO.new(MINIMAL_PDF))
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
test_files.each do |file|
|
|
63
63
|
basename = File.basename(file)
|
|
64
64
|
it "can decrypt, encrypt and decrypt the encrypted file #{basename} with the user password" do
|
|
65
65
|
begin
|
|
66
66
|
doc = HexaPDF::Document.new(io: StringIO.new(File.binread(file)),
|
|
67
|
-
decryption_opts: {password:
|
|
68
|
-
assert_equal(
|
|
67
|
+
decryption_opts: {password: user_password})
|
|
68
|
+
assert_equal(minimal_doc.trailer[:Info][:ModDate], doc.trailer[:Info][:ModDate])
|
|
69
69
|
|
|
70
70
|
out = StringIO.new(''.b)
|
|
71
71
|
HexaPDF::Writer.new(doc, out).write
|
|
72
|
-
doc = HexaPDF::Document.new(io: out, decryption_opts: {password:
|
|
73
|
-
assert_equal(
|
|
72
|
+
doc = HexaPDF::Document.new(io: out, decryption_opts: {password: user_password})
|
|
73
|
+
assert_equal(minimal_doc.trailer[:Info][:ModDate], doc.trailer[:Info][:ModDate])
|
|
74
74
|
rescue HexaPDF::EncryptionError => e
|
|
75
75
|
flunk("Error processing #{basename}: #{e}")
|
|
76
76
|
end
|
|
@@ -80,8 +80,8 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
|
|
|
80
80
|
it "can decrypt the encrypted file #{basename} with the owner password" do
|
|
81
81
|
begin
|
|
82
82
|
doc = HexaPDF::Document.new(io: StringIO.new(File.binread(file)),
|
|
83
|
-
decryption_opts: {password:
|
|
84
|
-
assert_equal(
|
|
83
|
+
decryption_opts: {password: owner_password})
|
|
84
|
+
assert_equal(minimal_doc.trailer[:Info][:ModDate], doc.trailer[:Info][:ModDate])
|
|
85
85
|
rescue HexaPDF::EncryptionError => e
|
|
86
86
|
flunk("Error processing #{basename}: #{e}")
|
|
87
87
|
end
|
|
@@ -33,7 +33,7 @@ describe HexaPDF::Filter::ASCII85Decode do
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it "ignores data after the EOD marker" do
|
|
36
|
-
assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded
|
|
36
|
+
assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded << "~>abcdefg"))))
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
it "fails if the input contains invalid characters" do
|
|
@@ -24,7 +24,7 @@ describe HexaPDF::Filter::ASCIIHexDecode do
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
it "ignores data after the EOD marker" do
|
|
27
|
-
assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded
|
|
27
|
+
assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded << '4e6f7gzz'))))
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
it "assumes the missing char is '0' if the input length is odd" do
|
|
@@ -32,4 +32,14 @@ describe HexaPDF::Font::Encoding::Base do
|
|
|
32
32
|
assert_nil(@base.unicode(66))
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
|
+
|
|
36
|
+
describe "code" do
|
|
37
|
+
it "returns the code for an existing glyph name" do
|
|
38
|
+
assert_equal(65, @base.code(:A))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "returns nil if the glyph name is not referenced" do
|
|
42
|
+
assert_nil(@base.code(:Unknown))
|
|
43
|
+
end
|
|
44
|
+
end
|
|
35
45
|
end
|
|
@@ -18,4 +18,12 @@ describe HexaPDF::Font::Encoding::DifferenceEncoding do
|
|
|
18
18
|
assert_equal(:B, @enc.name(66))
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
|
+
|
|
22
|
+
describe "code" do
|
|
23
|
+
it "takes the encoding differences into account" do
|
|
24
|
+
assert_equal(65, @enc.code(:A))
|
|
25
|
+
@enc.code_to_name[65] = :Known
|
|
26
|
+
assert_equal(65, @enc.code(:Known))
|
|
27
|
+
end
|
|
28
|
+
end
|
|
21
29
|
end
|
|
@@ -94,7 +94,10 @@ describe HexaPDF::Font::TrueTypeWrapper do
|
|
|
94
94
|
@font_wrapper.encode(glyph)
|
|
95
95
|
@doc.dispatch_message(:complete_objects)
|
|
96
96
|
|
|
97
|
-
dict = @font_wrapper.
|
|
97
|
+
dict = @font_wrapper.pdf_object
|
|
98
|
+
|
|
99
|
+
# Checking the circular reference
|
|
100
|
+
assert_same(@font_wrapper, dict.font_wrapper)
|
|
98
101
|
|
|
99
102
|
# Checking Type 0 font dictionary
|
|
100
103
|
assert_equal(:Font, dict[:Type])
|
|
@@ -129,7 +132,7 @@ describe HexaPDF::Font::TrueTypeWrapper do
|
|
|
129
132
|
@font[:'OS/2'].typo_ascender = 1000
|
|
130
133
|
font_wrapper = HexaPDF::Font::TrueTypeWrapper.new(@doc, @font)
|
|
131
134
|
font_wrapper.encode(glyph)
|
|
132
|
-
fd = font_wrapper.
|
|
135
|
+
fd = font_wrapper.pdf_object[:DescendantFonts][0][:FontDescriptor]
|
|
133
136
|
assert_equal(800, fd[:CapHeight])
|
|
134
137
|
assert_equal(500, fd[:XHeight])
|
|
135
138
|
end
|
|
@@ -139,7 +142,7 @@ describe HexaPDF::Font::TrueTypeWrapper do
|
|
|
139
142
|
@font[:'OS/2'].cap_height = 1000 * @font[:head].units_per_em / 1000
|
|
140
143
|
font_wrapper = HexaPDF::Font::TrueTypeWrapper.new(@doc, @font)
|
|
141
144
|
font_wrapper.encode(glyph)
|
|
142
|
-
fd = font_wrapper.
|
|
145
|
+
fd = font_wrapper.pdf_object[:DescendantFonts][0][:FontDescriptor]
|
|
143
146
|
assert_equal(1000, fd[:CapHeight])
|
|
144
147
|
assert_equal(500, fd[:XHeight])
|
|
145
148
|
end
|
|
@@ -151,7 +154,7 @@ describe HexaPDF::Font::TrueTypeWrapper do
|
|
|
151
154
|
@font_wrapper.encode(glyph)
|
|
152
155
|
@doc.dispatch_message(:complete_objects)
|
|
153
156
|
|
|
154
|
-
dict = @font_wrapper.
|
|
157
|
+
dict = @font_wrapper.pdf_object
|
|
155
158
|
|
|
156
159
|
assert_equal(HexaPDF::Font::CMap.create_to_unicode_cmap([[3, ' '.ord], [glyph.id, 'H'.ord]]),
|
|
157
160
|
dict[:ToUnicode].stream)
|
|
@@ -164,7 +167,7 @@ describe HexaPDF::Font::TrueTypeWrapper do
|
|
|
164
167
|
@font_wrapper.encode(@font_wrapper.glyph(10))
|
|
165
168
|
@doc.dispatch_message(:complete_objects)
|
|
166
169
|
|
|
167
|
-
font_data = @font_wrapper.
|
|
170
|
+
font_data = @font_wrapper.pdf_object[:DescendantFonts][0][:FontDescriptor][:FontFile2].stream
|
|
168
171
|
font = HexaPDF::Font::TrueType::Font.new(StringIO.new(font_data))
|
|
169
172
|
assert_equal(@font[:glyf][0].raw_data, font[:glyf][0].raw_data)
|
|
170
173
|
assert_equal(@font[:glyf][10].raw_data, font[:glyf][1].raw_data)
|
|
@@ -175,9 +178,9 @@ describe HexaPDF::Font::TrueTypeWrapper do
|
|
|
175
178
|
@doc.dispatch_message(:complete_objects)
|
|
176
179
|
|
|
177
180
|
assert_equal(File.size(@font_file),
|
|
178
|
-
@font_wrapper.
|
|
181
|
+
@font_wrapper.pdf_object[:DescendantFonts][0][:FontDescriptor][:FontFile2][:Length1])
|
|
179
182
|
assert_equal(File.binread(@font_file),
|
|
180
|
-
@font_wrapper.
|
|
183
|
+
@font_wrapper.pdf_object[:DescendantFonts][0][:FontDescriptor][:FontFile2].stream)
|
|
181
184
|
end
|
|
182
185
|
end
|
|
183
186
|
end
|
|
@@ -12,6 +12,15 @@ describe HexaPDF::Font::Type1Wrapper do
|
|
|
12
12
|
@symbol_wrapper = HexaPDF::Font::Type1Wrapper.new(@doc, FONT_SYMBOL)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
it "can be used with an existing PDF object" do
|
|
16
|
+
font = @doc.add({Type: :Font, Subtype: :Type1, Encoding: {Differences: [65, :B]},
|
|
17
|
+
BaseFont: :"Times-Roman"})
|
|
18
|
+
wrapper = HexaPDF::Font::Type1Wrapper.new(@doc, FONT_TIMES, pdf_object: font)
|
|
19
|
+
assert_equal([:B, :E, :A, :S, :T], wrapper.decode_utf8("BEAST").map(&:name))
|
|
20
|
+
assert_equal("A", wrapper.encode(wrapper.glyph(:A)))
|
|
21
|
+
assert_equal("A", wrapper.encode(wrapper.glyph(:B)))
|
|
22
|
+
end
|
|
23
|
+
|
|
15
24
|
it "returns 1 for the scaling factor" do
|
|
16
25
|
assert_equal(1, @times_wrapper.scaling_factor)
|
|
17
26
|
end
|
|
@@ -21,6 +30,10 @@ describe HexaPDF::Font::Type1Wrapper do
|
|
|
21
30
|
assert_equal([:T, :e, :s, :t], @times_wrapper.decode_utf8("Test").map(&:name))
|
|
22
31
|
end
|
|
23
32
|
|
|
33
|
+
it "falls back to the internal font encoding if the Unicode codepoint is not mapped" do
|
|
34
|
+
assert_equal([:Delta, :Delta], @symbol_wrapper.decode_utf8("D∆").map(&:name))
|
|
35
|
+
end
|
|
36
|
+
|
|
24
37
|
it "UTF-8 characters for which no glyph name exists, are mapped to InvalidGlyph objects" do
|
|
25
38
|
glyphs = @times_wrapper.decode_utf8("😁")
|
|
26
39
|
assert_equal(1, glyphs.length)
|
|
@@ -58,7 +71,7 @@ describe HexaPDF::Font::Type1Wrapper do
|
|
|
58
71
|
code = @times_wrapper.encode(@times_wrapper.glyph(:a))
|
|
59
72
|
@doc.dispatch_message(:complete_objects)
|
|
60
73
|
assert_equal("a", code)
|
|
61
|
-
assert_equal(:WinAnsiEncoding, @times_wrapper.
|
|
74
|
+
assert_equal(:WinAnsiEncoding, @times_wrapper.pdf_object[:Encoding])
|
|
62
75
|
end
|
|
63
76
|
|
|
64
77
|
it "fails if an InvalidGlyph is encoded" do
|
|
@@ -70,13 +83,25 @@ describe HexaPDF::Font::Type1Wrapper do
|
|
|
70
83
|
end
|
|
71
84
|
end
|
|
72
85
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
86
|
+
it "uses the font's internal encoding for fonts with the Special character set" do
|
|
87
|
+
code = @symbol_wrapper.encode(@symbol_wrapper.glyph(:plus))
|
|
88
|
+
@doc.dispatch_message(:complete_objects)
|
|
89
|
+
assert_equal("+", code)
|
|
90
|
+
assert_nil(@symbol_wrapper.pdf_object[:Encoding])
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "uses an empty encoding as initial encoding if a custom encoding is needed" do
|
|
94
|
+
wrapper = HexaPDF::Font::Type1Wrapper.new(@doc, FONT_TIMES, custom_encoding: true)
|
|
95
|
+
code = wrapper.encode(wrapper.glyph(:plus))
|
|
96
|
+
@doc.dispatch_message(:complete_objects)
|
|
97
|
+
assert_equal("\x21", code)
|
|
98
|
+
assert_equal({Differences: [32, :space, :plus]}, wrapper.pdf_object[:Encoding].value)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
describe "creates the necessary PDF dictionaries" do
|
|
103
|
+
it "sets the circular reference" do
|
|
104
|
+
assert_same(@times_wrapper, @times_wrapper.pdf_object.font_wrapper)
|
|
80
105
|
end
|
|
81
106
|
end
|
|
82
107
|
end
|
|
@@ -537,7 +537,7 @@ describe HexaPDF::Layout::Style::LinkLayer do
|
|
|
537
537
|
end
|
|
538
538
|
|
|
539
539
|
it "does nothing if the context is not a page object" do
|
|
540
|
-
@canvas = HexaPDF::Document.new.add({Type: :XObject, Subtype: :Form}).canvas
|
|
540
|
+
@canvas = HexaPDF::Document.new.add({Type: :XObject, Subtype: :Form, BBox: [0, 0, 1, 1]}).canvas
|
|
541
541
|
assert_nil(call_link(dest: true))
|
|
542
542
|
end
|
|
543
543
|
|
|
@@ -674,10 +674,9 @@ describe HexaPDF::Layout::TextLayouter do
|
|
|
674
674
|
pos = [0, 0]
|
|
675
675
|
result.select! {|name, _| name == :set_text_matrix || name == :move_text_next_line }.
|
|
676
676
|
map! do |name, ops|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
pos[1] -= leading
|
|
677
|
+
case name
|
|
678
|
+
when :set_text_matrix then pos = ops[-2, 2]
|
|
679
|
+
when :move_text_next_line then pos[1] -= leading
|
|
681
680
|
end
|
|
682
681
|
pos.dup
|
|
683
682
|
end
|
|
@@ -66,8 +66,8 @@ describe HexaPDF::Configuration do
|
|
|
66
66
|
assert_equal(HexaPDF, @config.constantize('test', 1))
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
def assert_constantize_error # :nodoc:
|
|
70
|
-
exp = assert_raises(HexaPDF::Error)
|
|
69
|
+
def assert_constantize_error(&block) # :nodoc:
|
|
70
|
+
exp = assert_raises(HexaPDF::Error, &block)
|
|
71
71
|
assert_match(/Error getting constant for configuration option/, exp.message)
|
|
72
72
|
end
|
|
73
73
|
|
|
@@ -14,7 +14,9 @@ describe HexaPDF::Dictionary do
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def add(obj)
|
|
17
|
-
HexaPDF::Object
|
|
17
|
+
klass = HexaPDF::Object
|
|
18
|
+
klass = HexaPDF::Dictionary if obj.kind_of?(HexaPDF::Dictionary) || obj.kind_of?(Hash)
|
|
19
|
+
klass.new(obj, oid: 1)
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
def delete(_obj)
|