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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +33 -0
- data/CONTRIBUTERS +1 -1
- data/LICENSE +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/hexapdf +1 -1
- data/examples/text_layouter_styling.rb +1 -2
- data/lib/hexapdf.rb +2 -2
- data/lib/hexapdf/cli.rb +3 -3
- data/lib/hexapdf/cli/batch.rb +5 -5
- data/lib/hexapdf/cli/command.rb +15 -17
- data/lib/hexapdf/cli/files.rb +3 -3
- data/lib/hexapdf/cli/images.rb +3 -4
- data/lib/hexapdf/cli/info.rb +5 -5
- data/lib/hexapdf/cli/inspect.rb +6 -6
- data/lib/hexapdf/cli/merge.rb +6 -6
- data/lib/hexapdf/cli/modify.rb +4 -4
- data/lib/hexapdf/cli/optimize.rb +3 -3
- data/lib/hexapdf/configuration.rb +4 -5
- data/lib/hexapdf/content.rb +2 -2
- data/lib/hexapdf/content/canvas.rb +35 -36
- data/lib/hexapdf/content/color_space.rb +9 -14
- data/lib/hexapdf/content/graphic_object.rb +2 -2
- data/lib/hexapdf/content/graphic_object/arc.rb +3 -3
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +2 -2
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +4 -8
- data/lib/hexapdf/content/graphics_state.rb +4 -13
- data/lib/hexapdf/content/operator.rb +33 -35
- data/lib/hexapdf/content/parser.rb +28 -18
- data/lib/hexapdf/content/processor.rb +4 -5
- data/lib/hexapdf/content/transformation_matrix.rb +2 -2
- data/lib/hexapdf/data_dir.rb +2 -2
- data/lib/hexapdf/dictionary.rb +8 -9
- data/lib/hexapdf/dictionary_fields.rb +7 -10
- data/lib/hexapdf/document.rb +18 -18
- data/lib/hexapdf/document/files.rb +12 -10
- data/lib/hexapdf/document/fonts.rb +2 -2
- data/lib/hexapdf/document/images.rb +3 -3
- data/lib/hexapdf/document/pages.rb +4 -4
- data/lib/hexapdf/encryption.rb +2 -2
- data/lib/hexapdf/encryption/aes.rb +2 -2
- data/lib/hexapdf/encryption/arc4.rb +4 -4
- data/lib/hexapdf/encryption/fast_aes.rb +2 -2
- data/lib/hexapdf/encryption/fast_arc4.rb +4 -4
- data/lib/hexapdf/encryption/identity.rb +5 -4
- data/lib/hexapdf/encryption/ruby_aes.rb +147 -139
- data/lib/hexapdf/encryption/ruby_arc4.rb +4 -4
- data/lib/hexapdf/encryption/security_handler.rb +11 -12
- data/lib/hexapdf/encryption/standard_security_handler.rb +6 -9
- data/lib/hexapdf/error.rb +7 -9
- data/lib/hexapdf/filter.rb +2 -3
- data/lib/hexapdf/filter/ascii85_decode.rb +3 -3
- data/lib/hexapdf/filter/ascii_hex_decode.rb +2 -2
- data/lib/hexapdf/filter/dct_decode.rb +2 -2
- data/lib/hexapdf/filter/encryption.rb +2 -2
- data/lib/hexapdf/filter/flate_decode.rb +16 -33
- data/lib/hexapdf/filter/jpx_decode.rb +2 -2
- data/lib/hexapdf/filter/lzw_decode.rb +4 -4
- data/lib/hexapdf/filter/predictor.rb +2 -6
- data/lib/hexapdf/filter/run_length_decode.rb +2 -2
- data/lib/hexapdf/font/cmap.rb +2 -3
- data/lib/hexapdf/font/cmap/parser.rb +11 -11
- data/lib/hexapdf/font/cmap/writer.rb +25 -25
- data/lib/hexapdf/font/encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/base.rb +2 -2
- data/lib/hexapdf/font/encoding/difference_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/glyph_list.rb +6 -6
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/standard_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/symbol_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +2 -2
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +2 -2
- data/lib/hexapdf/font/invalid_glyph.rb +7 -7
- data/lib/hexapdf/font/true_type.rb +2 -2
- data/lib/hexapdf/font/true_type/builder.rb +13 -7
- data/lib/hexapdf/font/true_type/font.rb +2 -3
- data/lib/hexapdf/font/true_type/optimizer.rb +2 -2
- data/lib/hexapdf/font/true_type/subsetter.rb +4 -4
- data/lib/hexapdf/font/true_type/table.rb +3 -5
- data/lib/hexapdf/font/true_type/table/cmap.rb +2 -2
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +9 -16
- data/lib/hexapdf/font/true_type/table/directory.rb +4 -4
- data/lib/hexapdf/font/true_type/table/glyf.rb +2 -2
- data/lib/hexapdf/font/true_type/table/head.rb +3 -2
- data/lib/hexapdf/font/true_type/table/hhea.rb +2 -2
- data/lib/hexapdf/font/true_type/table/hmtx.rb +2 -2
- data/lib/hexapdf/font/true_type/table/kern.rb +3 -3
- data/lib/hexapdf/font/true_type/table/loca.rb +3 -3
- data/lib/hexapdf/font/true_type/table/maxp.rb +2 -2
- data/lib/hexapdf/font/true_type/table/name.rb +3 -5
- data/lib/hexapdf/font/true_type/table/os2.rb +4 -3
- data/lib/hexapdf/font/true_type/table/post.rb +3 -7
- data/lib/hexapdf/font/true_type_wrapper.rb +20 -22
- data/lib/hexapdf/font/type1.rb +2 -2
- data/lib/hexapdf/font/type1/afm_parser.rb +7 -7
- data/lib/hexapdf/font/type1/character_metrics.rb +2 -2
- data/lib/hexapdf/font/type1/font.rb +3 -3
- data/lib/hexapdf/font/type1/font_metrics.rb +2 -4
- data/lib/hexapdf/font/type1/pfb_parser.rb +2 -2
- data/lib/hexapdf/font/type1_wrapper.rb +8 -9
- data/lib/hexapdf/font_loader.rb +2 -2
- data/lib/hexapdf/font_loader/from_configuration.rb +2 -2
- data/lib/hexapdf/font_loader/from_file.rb +2 -2
- data/lib/hexapdf/font_loader/standard14.rb +2 -2
- data/lib/hexapdf/image_loader.rb +2 -2
- data/lib/hexapdf/image_loader/jpeg.rb +6 -4
- data/lib/hexapdf/image_loader/pdf.rb +2 -2
- data/lib/hexapdf/image_loader/png.rb +6 -6
- data/lib/hexapdf/importer.rb +6 -4
- data/lib/hexapdf/layout.rb +2 -2
- data/lib/hexapdf/layout/box.rb +4 -4
- data/lib/hexapdf/layout/inline_box.rb +2 -2
- data/lib/hexapdf/layout/line.rb +6 -6
- data/lib/hexapdf/layout/numeric_refinements.rb +2 -2
- data/lib/hexapdf/layout/style.rb +17 -8
- data/lib/hexapdf/layout/text_fragment.rb +86 -48
- data/lib/hexapdf/layout/text_layouter.rb +40 -21
- data/lib/hexapdf/layout/text_shaper.rb +2 -2
- data/lib/hexapdf/name_tree_node.rb +2 -2
- data/lib/hexapdf/number_tree_node.rb +2 -2
- data/lib/hexapdf/object.rb +6 -8
- data/lib/hexapdf/parser.rb +10 -10
- data/lib/hexapdf/rectangle.rb +4 -4
- data/lib/hexapdf/reference.rb +2 -2
- data/lib/hexapdf/revision.rb +4 -4
- data/lib/hexapdf/revisions.rb +5 -5
- data/lib/hexapdf/serializer.rb +27 -24
- data/lib/hexapdf/stream.rb +4 -4
- data/lib/hexapdf/task.rb +2 -2
- data/lib/hexapdf/task/dereference.rb +4 -4
- data/lib/hexapdf/task/optimize.rb +5 -4
- data/lib/hexapdf/tokenizer.rb +12 -14
- data/lib/hexapdf/type.rb +2 -2
- data/lib/hexapdf/type/action.rb +3 -3
- data/lib/hexapdf/type/actions.rb +2 -2
- data/lib/hexapdf/type/actions/go_to.rb +2 -2
- data/lib/hexapdf/type/actions/go_to_r.rb +2 -2
- data/lib/hexapdf/type/actions/launch.rb +2 -2
- data/lib/hexapdf/type/actions/uri.rb +3 -3
- data/lib/hexapdf/type/annotation.rb +3 -3
- data/lib/hexapdf/type/annotations.rb +2 -2
- data/lib/hexapdf/type/annotations/link.rb +2 -2
- data/lib/hexapdf/type/annotations/markup_annotation.rb +2 -2
- data/lib/hexapdf/type/annotations/text.rb +2 -2
- data/lib/hexapdf/type/catalog.rb +4 -4
- data/lib/hexapdf/type/cid_font.rb +4 -5
- data/lib/hexapdf/type/embedded_file.rb +3 -3
- data/lib/hexapdf/type/file_specification.rb +6 -7
- data/lib/hexapdf/type/font.rb +4 -4
- data/lib/hexapdf/type/font_descriptor.rb +3 -4
- data/lib/hexapdf/type/font_simple.rb +12 -16
- data/lib/hexapdf/type/font_true_type.rb +2 -2
- data/lib/hexapdf/type/font_type0.rb +5 -5
- data/lib/hexapdf/type/font_type1.rb +4 -4
- data/lib/hexapdf/type/form.rb +3 -3
- data/lib/hexapdf/type/graphics_state_parameter.rb +3 -3
- data/lib/hexapdf/type/image.rb +13 -14
- data/lib/hexapdf/type/info.rb +2 -2
- data/lib/hexapdf/type/names.rb +2 -2
- data/lib/hexapdf/type/object_stream.rb +5 -5
- data/lib/hexapdf/type/page.rb +9 -10
- data/lib/hexapdf/type/page_tree_node.rb +5 -6
- data/lib/hexapdf/type/resources.rb +11 -11
- data/lib/hexapdf/type/trailer.rb +3 -3
- data/lib/hexapdf/type/viewer_preferences.rb +2 -2
- data/lib/hexapdf/type/xref_stream.rb +8 -4
- data/lib/hexapdf/utils/bit_field.rb +4 -4
- data/lib/hexapdf/utils/bit_stream.rb +4 -4
- data/lib/hexapdf/utils/graphics_helpers.rb +2 -2
- data/lib/hexapdf/utils/lru_cache.rb +2 -2
- data/lib/hexapdf/utils/math_helpers.rb +2 -2
- data/lib/hexapdf/utils/object_hash.rb +3 -3
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +3 -3
- data/lib/hexapdf/utils/sorted_tree_node.rb +12 -11
- data/lib/hexapdf/version.rb +3 -3
- data/lib/hexapdf/writer.rb +8 -8
- data/lib/hexapdf/xref_section.rb +3 -3
- data/test/hexapdf/common_tokenizer_tests.rb +6 -7
- data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +0 -1
- data/test/hexapdf/content/test_canvas.rb +28 -36
- data/test/hexapdf/content/test_color_space.rb +4 -0
- data/test/hexapdf/content/test_graphics_state.rb +2 -0
- data/test/hexapdf/content/test_operator.rb +6 -7
- data/test/hexapdf/content/test_parser.rb +2 -2
- data/test/hexapdf/content/test_processor.rb +1 -1
- data/test/hexapdf/document/test_files.rb +1 -0
- data/test/hexapdf/document/test_images.rb +1 -1
- data/test/hexapdf/encryption/common.rb +3 -3
- data/test/hexapdf/encryption/test_aes.rb +10 -4
- data/test/hexapdf/encryption/test_identity.rb +1 -1
- data/test/hexapdf/encryption/test_security_handler.rb +13 -17
- data/test/hexapdf/encryption/test_standard_security_handler.rb +12 -12
- data/test/hexapdf/filter/test_ascii85_decode.rb +2 -3
- data/test/hexapdf/filter/test_ascii_hex_decode.rb +6 -1
- data/test/hexapdf/filter/test_flate_decode.rb +2 -2
- data/test/hexapdf/filter/test_lzw_decode.rb +10 -10
- data/test/hexapdf/filter/test_predictor.rb +10 -2
- data/test/hexapdf/filter/test_run_length_decode.rb +1 -1
- data/test/hexapdf/font/cmap/test_parser.rb +40 -40
- data/test/hexapdf/font/cmap/test_writer.rb +29 -29
- data/test/hexapdf/font/test_true_type_wrapper.rb +3 -2
- data/test/hexapdf/font/true_type/common.rb +2 -0
- data/test/hexapdf/font/true_type/table/test_cmap.rb +1 -1
- data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +5 -4
- data/test/hexapdf/font/true_type/table/test_glyf.rb +2 -2
- data/test/hexapdf/font/true_type/table/test_head.rb +2 -2
- data/test/hexapdf/font/true_type/table/test_name.rb +9 -6
- data/test/hexapdf/font/true_type/test_builder.rb +8 -3
- data/test/hexapdf/font/true_type/test_optimizer.rb +1 -2
- data/test/hexapdf/font/type1/test_afm_parser.rb +2 -2
- data/test/hexapdf/image_loader/test_jpeg.rb +1 -1
- data/test/hexapdf/image_loader/test_pdf.rb +1 -1
- data/test/hexapdf/image_loader/test_png.rb +3 -3
- data/test/hexapdf/layout/test_inline_box.rb +10 -1
- data/test/hexapdf/layout/test_line.rb +4 -4
- data/test/hexapdf/layout/test_style.rb +19 -7
- data/test/hexapdf/layout/test_text_fragment.rb +73 -27
- data/test/hexapdf/layout/test_text_layouter.rb +84 -68
- data/test/hexapdf/layout/test_text_shaper.rb +4 -6
- data/test/hexapdf/task/test_dereference.rb +2 -2
- data/test/hexapdf/task/test_optimize.rb +16 -7
- data/test/hexapdf/test_configuration.rb +1 -1
- data/test/hexapdf/test_data_dir.rb +2 -2
- data/test/hexapdf/test_dictionary.rb +6 -3
- data/test/hexapdf/test_dictionary_fields.rb +15 -14
- data/test/hexapdf/test_document.rb +47 -48
- data/test/hexapdf/test_filter.rb +30 -26
- data/test/hexapdf/test_importer.rb +14 -0
- data/test/hexapdf/test_object.rb +16 -4
- data/test/hexapdf/test_parser.rb +36 -36
- data/test/hexapdf/test_reference.rb +7 -5
- data/test/hexapdf/test_revision.rb +1 -1
- data/test/hexapdf/test_revisions.rb +90 -90
- data/test/hexapdf/test_serializer.rb +3 -2
- data/test/hexapdf/test_stream.rb +2 -4
- data/test/hexapdf/test_tokenizer.rb +2 -2
- data/test/hexapdf/test_writer.rb +80 -80
- data/test/hexapdf/test_xref_section.rb +1 -1
- data/test/hexapdf/type/annotations/test_link.rb +1 -1
- data/test/hexapdf/type/annotations/test_text.rb +3 -3
- data/test/hexapdf/type/test_font_descriptor.rb +1 -1
- data/test/hexapdf/type/test_font_simple.rb +2 -2
- data/test/hexapdf/type/test_font_type0.rb +0 -1
- data/test/hexapdf/type/test_image.rb +0 -3
- data/test/hexapdf/type/test_object_stream.rb +2 -1
- data/test/hexapdf/type/test_page.rb +5 -1
- data/test/hexapdf/type/test_page_tree_node.rb +4 -4
- data/test/hexapdf/type/test_trailer.rb +1 -1
- data/test/hexapdf/type/test_xref_stream.rb +4 -0
- data/test/hexapdf/utils/test_bit_field.rb +2 -0
- data/test/hexapdf/utils/test_bit_stream.rb +1 -1
- data/test/hexapdf/utils/test_lru_cache.rb +1 -1
- data/test/hexapdf/utils/test_sorted_tree_node.rb +10 -4
- data/test/test_helper.rb +3 -6
- metadata +3 -3
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -113,6 +113,11 @@ module HexaPDF
|
|
|
113
113
|
@shrinkability = shrinkability
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
+
# The width of the item.
|
|
117
|
+
def width
|
|
118
|
+
@item.width
|
|
119
|
+
end
|
|
120
|
+
|
|
116
121
|
# Returns :glue.
|
|
117
122
|
def type
|
|
118
123
|
:glue
|
|
@@ -219,38 +224,39 @@ module HexaPDF
|
|
|
219
224
|
end
|
|
220
225
|
|
|
221
226
|
# A hyphen belongs to the text fragment
|
|
222
|
-
box_items << glyph if glyph && !glyph.kind_of?(Numeric) && glyph.str == '-'
|
|
227
|
+
box_items << glyph if glyph && !glyph.kind_of?(Numeric) && glyph.str == '-'
|
|
223
228
|
|
|
224
229
|
unless box_items.empty?
|
|
225
|
-
result << Box.new(TextFragment.new(
|
|
230
|
+
result << Box.new(TextFragment.new(box_items.freeze, item.style))
|
|
226
231
|
end
|
|
227
232
|
|
|
228
233
|
if glyph
|
|
229
234
|
case glyph.str
|
|
230
235
|
when ' '
|
|
231
236
|
glues[item.style] ||=
|
|
232
|
-
Glue.new(TextFragment.new(
|
|
237
|
+
Glue.new(TextFragment.new([glyph].freeze, item.style))
|
|
233
238
|
result << glues[item.style]
|
|
234
239
|
when "\n", "\v", "\f", "\u{85}", "\u{2029}"
|
|
235
240
|
result << Penalty::MandatoryParagraphBreak
|
|
236
241
|
when "\u{2028}"
|
|
237
242
|
result << Penalty::MandatoryLineBreak
|
|
238
243
|
when "\r"
|
|
239
|
-
if item.items[i + 1]
|
|
244
|
+
if !item.items[i + 1] || item.items[i + 1].kind_of?(Numeric) ||
|
|
245
|
+
item.items[i + 1].str != "\n"
|
|
240
246
|
result << Penalty::MandatoryParagraphBreak
|
|
241
247
|
end
|
|
242
248
|
when '-'
|
|
243
249
|
result << Penalty::Standard
|
|
244
250
|
when "\t"
|
|
245
251
|
spaces = [item.style.font.decode_utf8(" ").first] * 8
|
|
246
|
-
result << Glue.new(TextFragment.new(
|
|
252
|
+
result << Glue.new(TextFragment.new(spaces.freeze, item.style))
|
|
247
253
|
when "\u{00AD}"
|
|
248
254
|
hyphen = item.style.font.decode_utf8("-").first
|
|
249
|
-
frag = TextFragment.new(
|
|
255
|
+
frag = TextFragment.new([hyphen].freeze, item.style)
|
|
250
256
|
result << Penalty.new(Penalty::Standard.penalty, frag.width, item: frag)
|
|
251
257
|
when "\u{00A0}"
|
|
252
258
|
space = item.style.font.decode_utf8(" ").first
|
|
253
|
-
frag = TextFragment.new(
|
|
259
|
+
frag = TextFragment.new([space].freeze, item.style)
|
|
254
260
|
result << Penalty.new(Penalty::ProhibitedBreak.penalty, frag.width, item: frag)
|
|
255
261
|
when "\u{200B}"
|
|
256
262
|
result << Penalty.new(0)
|
|
@@ -358,7 +364,7 @@ module HexaPDF
|
|
|
358
364
|
if item_fits_on_line?(item)
|
|
359
365
|
next_index = index + 1
|
|
360
366
|
next_item = @items[next_index]
|
|
361
|
-
next_item = @items[next_index += 1] while next_item
|
|
367
|
+
next_item = @items[next_index += 1] while next_item&.type == :penalty
|
|
362
368
|
if next_item && !item_fits_on_line?(next_item)
|
|
363
369
|
@line_items.concat(@glue_items).push(item.item)
|
|
364
370
|
@width += item.width
|
|
@@ -421,7 +427,7 @@ module HexaPDF
|
|
|
421
427
|
if item_fits_on_line?(item)
|
|
422
428
|
next_index = index + 1
|
|
423
429
|
next_item = @items[next_index]
|
|
424
|
-
next_item = @items[
|
|
430
|
+
next_item = @items[next_index += 1] while next_item&.type == :penalty
|
|
425
431
|
new_height = @height_calc.simulate_height(next_item.item)
|
|
426
432
|
if next_item && @width + next_item.width > @width_block.call(new_height)
|
|
427
433
|
@line_items.concat(@glue_items).push(item.item)
|
|
@@ -521,7 +527,6 @@ module HexaPDF
|
|
|
521
527
|
|
|
522
528
|
end
|
|
523
529
|
|
|
524
|
-
|
|
525
530
|
# Creates a new TextLayouter object for the given text and returns it.
|
|
526
531
|
#
|
|
527
532
|
# See ::new for information on +height+.
|
|
@@ -622,7 +627,7 @@ module HexaPDF
|
|
|
622
627
|
too_wide_box = nil
|
|
623
628
|
|
|
624
629
|
rest = style.text_line_wrapping_algorithm.call(rest, width_block) do |line, item|
|
|
625
|
-
line << TextFragment.new(
|
|
630
|
+
line << TextFragment.new([], style) if item&.type != :box && line.items.empty?
|
|
626
631
|
new_height = @actual_height + line.height +
|
|
627
632
|
(@lines.empty? ? 0 : style.line_spacing.gap(@lines.last, line))
|
|
628
633
|
|
|
@@ -667,10 +672,10 @@ module HexaPDF
|
|
|
667
672
|
end
|
|
668
673
|
end
|
|
669
674
|
|
|
670
|
-
if too_wide_box && too_wide_box.item.kind_of?(TextFragment) &&
|
|
671
|
-
|
|
675
|
+
if too_wide_box && (too_wide_box.item.kind_of?(TextFragment) &&
|
|
676
|
+
too_wide_box.item.items.size > 1)
|
|
672
677
|
rest[0..rest.index(too_wide_box)] = too_wide_box.item.items.map do |item|
|
|
673
|
-
Box.new(TextFragment.new(
|
|
678
|
+
Box.new(TextFragment.new([item], too_wide_box.item.style))
|
|
674
679
|
end
|
|
675
680
|
too_wide_box = nil
|
|
676
681
|
else
|
|
@@ -682,6 +687,9 @@ module HexaPDF
|
|
|
682
687
|
[rest, reason]
|
|
683
688
|
end
|
|
684
689
|
|
|
690
|
+
# :call-seq:
|
|
691
|
+
# tl.draws(canvas, x, y, fit: :if_needed) -> [remaining_items, reason] or nil
|
|
692
|
+
#
|
|
685
693
|
# Draws the layed out text onto the canvas with the top-left corner being at [x, y].
|
|
686
694
|
#
|
|
687
695
|
# Depending on the value of +fit+ the text may also be fitted:
|
|
@@ -689,26 +697,37 @@ module HexaPDF
|
|
|
689
697
|
# * If +true+, then #fit is always called.
|
|
690
698
|
# * If +:if_needed+, then #fit is only called if it has not been called before.
|
|
691
699
|
# * If +false+, then #fit is never called.
|
|
700
|
+
#
|
|
701
|
+
# If #fit was called, its return value is returned. Otherwise +nil+ is returned.
|
|
692
702
|
def draw(canvas, x, y, fit: :if_needed)
|
|
693
|
-
self.fit if fit == true || (!@actual_height && fit == :if_needed)
|
|
694
|
-
return if @lines.empty?
|
|
703
|
+
fit_result = self.fit if fit == true || (!@actual_height && fit == :if_needed)
|
|
704
|
+
return fit_result if @lines.empty?
|
|
695
705
|
|
|
706
|
+
last_item = nil
|
|
696
707
|
canvas.save_graphics_state do
|
|
708
|
+
if @lines.size > 1
|
|
709
|
+
canvas.leading(style.line_spacing.baseline_distance(@lines[0], @lines[1]))
|
|
710
|
+
end
|
|
697
711
|
y -= initial_baseline_offset + @lines.first.y_offset
|
|
698
712
|
@lines.each_with_index do |line, index|
|
|
699
713
|
line_x = x + line.x_offset
|
|
700
714
|
line.each do |item, item_x, item_y|
|
|
701
715
|
if item.kind_of?(TextFragment)
|
|
702
|
-
item.draw(canvas, line_x + item_x, y + item_y
|
|
716
|
+
item.draw(canvas, line_x + item_x, y + item_y,
|
|
717
|
+
ignore_text_properties: last_item&.style == item.style)
|
|
718
|
+
last_item = item
|
|
703
719
|
elsif !item.empty?
|
|
704
720
|
canvas.restore_graphics_state
|
|
705
721
|
item.draw(canvas, line_x + item_x, y + item_y)
|
|
706
722
|
canvas.save_graphics_state
|
|
723
|
+
last_item = nil
|
|
707
724
|
end
|
|
708
725
|
end
|
|
709
726
|
y -= @lines[index + 1].y_offset if @lines[index + 1]
|
|
710
727
|
end
|
|
711
728
|
end
|
|
729
|
+
|
|
730
|
+
fit_result
|
|
712
731
|
end
|
|
713
732
|
|
|
714
733
|
private
|
|
@@ -750,7 +769,7 @@ module HexaPDF
|
|
|
750
769
|
line.items.each_with_index do |item, item_index|
|
|
751
770
|
next if item.kind_of?(InlineBox)
|
|
752
771
|
item.items.each_with_index do |glyph, glyph_index|
|
|
753
|
-
if !glyph.kind_of?(Numeric) && glyph.str == ' '
|
|
772
|
+
if !glyph.kind_of?(Numeric) && glyph.str == ' '
|
|
754
773
|
sum += glyph.width * item.style.scaled_font_size
|
|
755
774
|
indexes << item_index << glyph_index
|
|
756
775
|
end
|
|
@@ -764,7 +783,7 @@ module HexaPDF
|
|
|
764
783
|
frag = line.items[indexes[i]]
|
|
765
784
|
value = -frag.items[indexes[i + 1]].width * adjustment
|
|
766
785
|
if frag.items.frozen?
|
|
767
|
-
value = HexaPDF::Layout::TextFragment.new(
|
|
786
|
+
value = HexaPDF::Layout::TextFragment.new([value], frag.style)
|
|
768
787
|
line.items.insert(indexes[i], value)
|
|
769
788
|
else
|
|
770
789
|
frag.items.insert(indexes[i + 1], value)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
data/lib/hexapdf/object.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -64,7 +64,6 @@ module HexaPDF
|
|
|
64
64
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
|
|
68
67
|
# Objects of the PDF object system.
|
|
69
68
|
#
|
|
70
69
|
# == Overview
|
|
@@ -130,9 +129,9 @@ module HexaPDF
|
|
|
130
129
|
def self.deep_copy(object)
|
|
131
130
|
case object
|
|
132
131
|
when Hash
|
|
133
|
-
object.each_with_object({}) {|(key, val), memo| memo[key] = deep_copy(val)}
|
|
132
|
+
object.each_with_object({}) {|(key, val), memo| memo[key] = deep_copy(val) }
|
|
134
133
|
when Array
|
|
135
|
-
object.map {|o| deep_copy(o)}
|
|
134
|
+
object.map {|o| deep_copy(o) }
|
|
136
135
|
when HexaPDF::Object
|
|
137
136
|
(object.indirect? || object.must_be_indirect? ? object : deep_copy(object.value))
|
|
138
137
|
when HexaPDF::Reference
|
|
@@ -144,7 +143,6 @@ module HexaPDF
|
|
|
144
143
|
end
|
|
145
144
|
end
|
|
146
145
|
|
|
147
|
-
|
|
148
146
|
# The wrapped HexaPDF::PDFData value.
|
|
149
147
|
#
|
|
150
148
|
# This attribute is not part of the public API!
|
|
@@ -365,9 +363,9 @@ module HexaPDF
|
|
|
365
363
|
if obj.kind_of?(HexaPDF::Object) && !obj.indirect?
|
|
366
364
|
obj.validate(&block)
|
|
367
365
|
elsif obj.kind_of?(Hash)
|
|
368
|
-
obj.each_value {|val| validate_nested(val, &block)}
|
|
366
|
+
obj.each_value {|val| validate_nested(val, &block) }
|
|
369
367
|
elsif obj.kind_of?(Array)
|
|
370
|
-
obj.each {|val| validate_nested(val, &block)}
|
|
368
|
+
obj.each {|val| validate_nested(val, &block) }
|
|
371
369
|
end
|
|
372
370
|
end
|
|
373
371
|
|
data/lib/hexapdf/parser.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -96,11 +96,11 @@ module HexaPDF
|
|
|
96
96
|
gen = @tokenizer.next_token
|
|
97
97
|
tok = @tokenizer.next_token
|
|
98
98
|
unless oid.kind_of?(Integer) && gen.kind_of?(Integer) &&
|
|
99
|
-
tok.kind_of?(Tokenizer::Token) && tok == 'obj'
|
|
99
|
+
tok.kind_of?(Tokenizer::Token) && tok == 'obj'
|
|
100
100
|
raise_malformed("No valid object found", pos: offset)
|
|
101
101
|
end
|
|
102
102
|
|
|
103
|
-
if (tok = @tokenizer.peek_token) && tok.kind_of?(Tokenizer::Token) && tok == 'endobj'
|
|
103
|
+
if (tok = @tokenizer.peek_token) && tok.kind_of?(Tokenizer::Token) && tok == 'endobj'
|
|
104
104
|
maybe_raise("No indirect object value between 'obj' and 'endobj'", pos: @tokenizer.pos)
|
|
105
105
|
object = nil
|
|
106
106
|
else
|
|
@@ -109,7 +109,7 @@ module HexaPDF
|
|
|
109
109
|
|
|
110
110
|
tok = @tokenizer.next_token
|
|
111
111
|
|
|
112
|
-
if tok.kind_of?(Tokenizer::Token) && tok == 'stream'
|
|
112
|
+
if tok.kind_of?(Tokenizer::Token) && tok == 'stream'
|
|
113
113
|
unless object.kind_of?(Hash)
|
|
114
114
|
raise_malformed("A stream needs a dictionary, not a(n) #{object.class}", pos: offset)
|
|
115
115
|
end
|
|
@@ -135,7 +135,7 @@ module HexaPDF
|
|
|
135
135
|
@tokenizer.pos = pos + length
|
|
136
136
|
|
|
137
137
|
tok = @tokenizer.next_token
|
|
138
|
-
unless tok.kind_of?(Tokenizer::Token) && tok == 'endstream'
|
|
138
|
+
unless tok.kind_of?(Tokenizer::Token) && tok == 'endstream'
|
|
139
139
|
maybe_raise("Invalid stream length, keyword endstream not found", pos: @tokenizer.pos)
|
|
140
140
|
@tokenizer.pos = pos
|
|
141
141
|
if @tokenizer.scan_until(/(?=\n?endstream)/)
|
|
@@ -154,7 +154,7 @@ module HexaPDF
|
|
|
154
154
|
decode_parms: @document.unwrap(object[:DecodeParms]))
|
|
155
155
|
end
|
|
156
156
|
|
|
157
|
-
unless tok.kind_of?(Tokenizer::Token) && tok == 'endobj'
|
|
157
|
+
unless tok.kind_of?(Tokenizer::Token) && tok == 'endobj'
|
|
158
158
|
maybe_raise("Indirect object must be followed by keyword endobj", pos: @tokenizer.pos)
|
|
159
159
|
end
|
|
160
160
|
|
|
@@ -234,7 +234,7 @@ module HexaPDF
|
|
|
234
234
|
end
|
|
235
235
|
if xref.entry?(oid)
|
|
236
236
|
next
|
|
237
|
-
elsif type == 'n'
|
|
237
|
+
elsif type == 'n'
|
|
238
238
|
if pos == 0 || gen > 65535
|
|
239
239
|
maybe_raise("Invalid in use cross-reference entry in cross-reference section",
|
|
240
240
|
pos: @tokenizer.pos)
|
|
@@ -255,7 +255,7 @@ module HexaPDF
|
|
|
255
255
|
|
|
256
256
|
trailer = @tokenizer.next_object
|
|
257
257
|
unless trailer.kind_of?(Hash)
|
|
258
|
-
raise_malformed("Trailer is
|
|
258
|
+
raise_malformed("Trailer is #{trailer.class} instead of dictionary ", pos: @tokenizer.pos)
|
|
259
259
|
end
|
|
260
260
|
|
|
261
261
|
[xref, trailer]
|
|
@@ -339,7 +339,7 @@ module HexaPDF
|
|
|
339
339
|
# HexaPDF::MalformedPDFError. Otherwise the error is corrected and parsing continues.
|
|
340
340
|
#
|
|
341
341
|
# If the option +force+ is used, the block is not called and the error is raised immediately.
|
|
342
|
-
def maybe_raise(msg, pos
|
|
342
|
+
def maybe_raise(msg, pos:, force: false)
|
|
343
343
|
if force || @document.config['parser.on_correctable_error'].call(@document, msg, pos)
|
|
344
344
|
error = HexaPDF::MalformedPDFError.new(msg, pos: pos)
|
|
345
345
|
error.set_backtrace(caller(1))
|
data/lib/hexapdf/rectangle.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -87,7 +87,7 @@ module HexaPDF
|
|
|
87
87
|
# upper-right corner.
|
|
88
88
|
def after_data_change
|
|
89
89
|
super
|
|
90
|
-
unless value.kind_of?(Array) && value.size == 4 && value.all? {|i| i.kind_of?(Numeric)}
|
|
90
|
+
unless value.kind_of?(Array) && value.size == 4 && value.all? {|i| i.kind_of?(Numeric) }
|
|
91
91
|
raise ArgumentError, "A PDF rectangle structure must contain an array of four numbers"
|
|
92
92
|
end
|
|
93
93
|
value[0], value[2] = value[2], value[0] if value[0] > value[2]
|
|
@@ -96,7 +96,7 @@ module HexaPDF
|
|
|
96
96
|
|
|
97
97
|
def perform_validation #:nodoc:
|
|
98
98
|
super
|
|
99
|
-
unless value.kind_of?(Array) && value.size == 4 && value.all? {|i| i.kind_of?(Numeric)}
|
|
99
|
+
unless value.kind_of?(Array) && value.size == 4 && value.all? {|i| i.kind_of?(Numeric) }
|
|
100
100
|
yield("A PDF rectangle structure must contain an array of four numbers", false)
|
|
101
101
|
end
|
|
102
102
|
end
|
data/lib/hexapdf/reference.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
data/lib/hexapdf/revision.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -175,10 +175,10 @@ module HexaPDF
|
|
|
175
175
|
return to_enum(__method__) unless block_given?
|
|
176
176
|
|
|
177
177
|
if defined?(@all_objects_loaded)
|
|
178
|
-
@objects.each {|_oid, _gen, data| yield(data)}
|
|
178
|
+
@objects.each {|_oid, _gen, data| yield(data) }
|
|
179
179
|
else
|
|
180
180
|
seen = {}
|
|
181
|
-
@objects.each {|oid, _gen, data| seen[oid] = true; yield(data)}
|
|
181
|
+
@objects.each {|oid, _gen, data| seen[oid] = true; yield(data) }
|
|
182
182
|
@xref_section.each do |oid, _gen, data|
|
|
183
183
|
next if seen.key?(oid)
|
|
184
184
|
yield(@objects[oid] || load_object(data))
|
data/lib/hexapdf/revisions.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
2
|
#
|
|
3
3
|
#--
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2018 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -61,7 +61,7 @@ module HexaPDF
|
|
|
61
61
|
return new(document) if io.nil?
|
|
62
62
|
|
|
63
63
|
parser = Parser.new(io, document)
|
|
64
|
-
object_loader = lambda {|xref_entry| parser.load_object(xref_entry)}
|
|
64
|
+
object_loader = lambda {|xref_entry| parser.load_object(xref_entry) }
|
|
65
65
|
|
|
66
66
|
revisions = []
|
|
67
67
|
xref_section, trailer = parser.load_revision(parser.startxref_offset)
|
|
@@ -116,7 +116,7 @@ module HexaPDF
|
|
|
116
116
|
def revision(index)
|
|
117
117
|
@revisions[index]
|
|
118
118
|
end
|
|
119
|
-
alias
|
|
119
|
+
alias [] revision
|
|
120
120
|
|
|
121
121
|
# Returns the current revision.
|
|
122
122
|
def current
|
|
@@ -181,7 +181,7 @@ module HexaPDF
|
|
|
181
181
|
end
|
|
182
182
|
end
|
|
183
183
|
_first, *other = *@revisions[range]
|
|
184
|
-
other.each {|rev| @revisions.delete(rev)}
|
|
184
|
+
other.each {|rev| @revisions.delete(rev) }
|
|
185
185
|
self
|
|
186
186
|
end
|
|
187
187
|
|