hexapdf 0.8.0 → 0.9.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 +52 -1
- data/CONTRIBUTERS +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/examples/018-composer.rb +44 -0
- data/lib/hexapdf/cli.rb +2 -0
- data/lib/hexapdf/cli/command.rb +2 -2
- data/lib/hexapdf/cli/optimize.rb +1 -1
- data/lib/hexapdf/cli/split.rb +82 -0
- data/lib/hexapdf/composer.rb +303 -0
- data/lib/hexapdf/configuration.rb +2 -2
- data/lib/hexapdf/content/canvas.rb +3 -6
- data/lib/hexapdf/dictionary.rb +0 -3
- data/lib/hexapdf/document.rb +30 -22
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/images.rb +1 -1
- data/lib/hexapdf/filter/predictor.rb +8 -8
- data/lib/hexapdf/layout.rb +1 -0
- data/lib/hexapdf/layout/box.rb +55 -12
- data/lib/hexapdf/layout/frame.rb +143 -46
- data/lib/hexapdf/layout/image_box.rb +96 -0
- data/lib/hexapdf/layout/inline_box.rb +10 -0
- data/lib/hexapdf/layout/line.rb +1 -1
- data/lib/hexapdf/layout/style.rb +55 -3
- data/lib/hexapdf/layout/text_box.rb +38 -8
- data/lib/hexapdf/layout/text_layouter.rb +66 -52
- data/lib/hexapdf/object.rb +3 -2
- data/lib/hexapdf/parser.rb +6 -1
- data/lib/hexapdf/rectangle.rb +6 -0
- data/lib/hexapdf/reference.rb +4 -6
- data/lib/hexapdf/revision.rb +34 -8
- data/lib/hexapdf/revisions.rb +12 -2
- data/lib/hexapdf/stream.rb +18 -0
- data/lib/hexapdf/task.rb +1 -1
- data/lib/hexapdf/task/dereference.rb +1 -1
- data/lib/hexapdf/task/optimize.rb +2 -2
- data/lib/hexapdf/type/form.rb +10 -0
- data/lib/hexapdf/version.rb +1 -1
- data/lib/hexapdf/writer.rb +25 -5
- data/man/man1/hexapdf.1 +17 -0
- data/test/hexapdf/layout/test_box.rb +7 -1
- data/test/hexapdf/layout/test_frame.rb +38 -1
- data/test/hexapdf/layout/test_image_box.rb +73 -0
- data/test/hexapdf/layout/test_inline_box.rb +8 -0
- data/test/hexapdf/layout/test_line.rb +1 -1
- data/test/hexapdf/layout/test_style.rb +58 -1
- data/test/hexapdf/layout/test_text_box.rb +57 -12
- data/test/hexapdf/layout/test_text_layouter.rb +14 -4
- data/test/hexapdf/task/test_optimize.rb +3 -3
- data/test/hexapdf/test_composer.rb +258 -0
- data/test/hexapdf/test_document.rb +29 -3
- data/test/hexapdf/test_importer.rb +8 -2
- data/test/hexapdf/test_object.rb +3 -1
- data/test/hexapdf/test_parser.rb +6 -0
- data/test/hexapdf/test_rectangle.rb +7 -0
- data/test/hexapdf/test_reference.rb +3 -1
- data/test/hexapdf/test_revision.rb +13 -0
- data/test/hexapdf/test_revisions.rb +1 -0
- data/test/hexapdf/test_stream.rb +13 -0
- data/test/hexapdf/test_writer.rb +13 -2
- data/test/hexapdf/type/test_annotation.rb +1 -1
- data/test/hexapdf/type/test_form.rb +13 -2
- metadata +10 -4
| @@ -386,17 +386,22 @@ describe HexaPDF::Document do | |
| 386 386 |  | 
| 387 387 | 
             
              describe "each" do
         | 
| 388 388 | 
             
                it "iterates over the current objects" do
         | 
| 389 | 
            -
                  assert_equal([10, 200, nil], @io_doc.each( | 
| 389 | 
            +
                  assert_equal([10, 200, nil], @io_doc.each(only_current: true).sort.map(&:value))
         | 
| 390 390 | 
             
                end
         | 
| 391 391 |  | 
| 392 392 | 
             
                it "iterates over all objects" do
         | 
| 393 | 
            -
                  assert_equal([10, 200, 20, 30, nil], @io_doc.each( | 
| 393 | 
            +
                  assert_equal([10, 200, 20, 30, nil], @io_doc.each(only_current: false).sort.map(&:value))
         | 
| 394 | 
            +
                end
         | 
| 395 | 
            +
             | 
| 396 | 
            +
                it "iterates over all loaded objects" do
         | 
| 397 | 
            +
                  assert_equal(200, @io_doc.object(2).value)
         | 
| 398 | 
            +
                  assert_equal([200], @io_doc.each(only_loaded: true).sort.map(&:value))
         | 
| 394 399 | 
             
                end
         | 
| 395 400 |  | 
| 396 401 | 
             
                it "yields the revision as second argument if the block accepts exactly two arguments" do
         | 
| 397 402 | 
             
                  objs = [[10, 20, 30], [200, nil]]
         | 
| 398 403 | 
             
                  data = @io_doc.revisions.map.with_index {|rev, i| objs[i].map {|o| [o, rev] } }.reverse.flatten
         | 
| 399 | 
            -
                  @io_doc.each( | 
| 404 | 
            +
                  @io_doc.each(only_current: false) do |obj, rev|
         | 
| 400 405 | 
             
                    assert(data.shift == obj.value)
         | 
| 401 406 | 
             
                    assert_equal(data.shift, rev)
         | 
| 402 407 | 
             
                  end
         | 
| @@ -448,6 +453,21 @@ describe HexaPDF::Document do | |
| 448 453 | 
             
                  @doc.trailer[:ID] = :Symbol
         | 
| 449 454 | 
             
                  refute(@doc.validate {|obj| assert_same(@doc.trailer, obj) })
         | 
| 450 455 | 
             
                end
         | 
| 456 | 
            +
             | 
| 457 | 
            +
                it "validates only loaded objects" do
         | 
| 458 | 
            +
                  io = StringIO.new
         | 
| 459 | 
            +
                  doc = HexaPDF::Document.new
         | 
| 460 | 
            +
                  doc.pages.add.delete(:Resources)
         | 
| 461 | 
            +
                  page = doc.pages.add
         | 
| 462 | 
            +
                  page[:Annots] = [doc.add(Type: :Annot, Subtype: :Link, Rect: [0, 0, 1, 1], H: :Z)]
         | 
| 463 | 
            +
                  doc.write(io, validate: false)
         | 
| 464 | 
            +
                  doc = HexaPDF::Document.new(io: io)
         | 
| 465 | 
            +
                  doc.pages[0] # force loading of the first page
         | 
| 466 | 
            +
             | 
| 467 | 
            +
                  refute(doc.validate(auto_correct: false, only_loaded: true)) # bc of Resources
         | 
| 468 | 
            +
                  assert(doc.validate(only_loaded: true))
         | 
| 469 | 
            +
                  refute(doc.validate(auto_correct: false)) # bc of annot key H
         | 
| 470 | 
            +
                end
         | 
| 451 471 | 
             
              end
         | 
| 452 472 |  | 
| 453 473 | 
             
              describe "write" do
         | 
| @@ -470,6 +490,12 @@ describe HexaPDF::Document do | |
| 470 490 | 
             
                  refute(io.string.empty?)
         | 
| 471 491 | 
             
                end
         | 
| 472 492 |  | 
| 493 | 
            +
                it "writes the document incrementally" do
         | 
| 494 | 
            +
                  io = StringIO.new
         | 
| 495 | 
            +
                  @io_doc.write(io, incremental: true)
         | 
| 496 | 
            +
                  assert_equal(@io.string, io.string[0, @io.string.length])
         | 
| 497 | 
            +
                end
         | 
| 498 | 
            +
             | 
| 473 499 | 
             
                it "fails if the document is not valid" do
         | 
| 474 500 | 
             
                  @doc.trailer[:Size] = :Symbol
         | 
| 475 501 | 
             
                  assert_raises(HexaPDF::Error) { @doc.write(StringIO.new(''.b)) }
         | 
| @@ -6,8 +6,14 @@ require 'hexapdf/document' | |
| 6 6 |  | 
| 7 7 | 
             
            describe HexaPDF::Importer::NullableWeakRef do
         | 
| 8 8 | 
             
              it "returns nil instead of an error when the referred-to object is GCed" do
         | 
| 9 | 
            -
                 | 
| 10 | 
            -
                 | 
| 9 | 
            +
                refs = []
         | 
| 10 | 
            +
                obj = nil
         | 
| 11 | 
            +
                100.times do
         | 
| 12 | 
            +
                  refs << HexaPDF::Importer::NullableWeakRef.new(Object.new)
         | 
| 13 | 
            +
                  ObjectSpace.garbage_collect
         | 
| 14 | 
            +
                  ObjectSpace.garbage_collect
         | 
| 15 | 
            +
                  break if (obj = refs.find {|ref| !ref.weakref_alive? })
         | 
| 16 | 
            +
                end
         | 
| 11 17 | 
             
                assert_equal("", obj.to_s)
         | 
| 12 18 | 
             
              end
         | 
| 13 19 | 
             
            end
         | 
    
        data/test/hexapdf/test_object.rb
    CHANGED
    
    | @@ -135,7 +135,7 @@ describe HexaPDF::Object do | |
| 135 135 | 
             
                assert_match(/\[5, 0\].*value=5/, obj.inspect)
         | 
| 136 136 | 
             
              end
         | 
| 137 137 |  | 
| 138 | 
            -
              it "can be compared to another object" do
         | 
| 138 | 
            +
              it "can be compared to another object or reference" do
         | 
| 139 139 | 
             
                obj = HexaPDF::Object.new(5, oid: 5)
         | 
| 140 140 |  | 
| 141 141 | 
             
                assert_equal(obj, HexaPDF::Object.new(obj))
         | 
| @@ -143,6 +143,8 @@ describe HexaPDF::Object do | |
| 143 143 | 
             
                refute_equal(obj, HexaPDF::Object.new(6, oid: 5))
         | 
| 144 144 | 
             
                refute_equal(obj, HexaPDF::Object.new(5, oid: 1))
         | 
| 145 145 | 
             
                refute_equal(obj, HexaPDF::Object.new(5, oid: 5, gen: 1))
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                assert_equal(obj, HexaPDF::Reference.new(5, 0))
         | 
| 146 148 | 
             
              end
         | 
| 147 149 |  | 
| 148 150 | 
             
              it "works correctly as hash key, is interchangable in this regard with Reference objects" do
         | 
    
        data/test/hexapdf/test_parser.rb
    CHANGED
    
    | @@ -194,6 +194,12 @@ describe HexaPDF::Parser do | |
| 194 194 | 
             
              end
         | 
| 195 195 |  | 
| 196 196 | 
             
              describe "startxref_offset" do
         | 
| 197 | 
            +
                it "caches the offset value" do
         | 
| 198 | 
            +
                  assert_equal(308, @parser.startxref_offset)
         | 
| 199 | 
            +
                  @parser.instance_eval { @io }.string.sub!(/308\n/, "309\n")
         | 
| 200 | 
            +
                  assert_equal(308, @parser.startxref_offset)
         | 
| 201 | 
            +
                end
         | 
| 202 | 
            +
             | 
| 197 203 | 
             
                it "returns the correct offset" do
         | 
| 198 204 | 
             
                  assert_equal(308, @parser.startxref_offset)
         | 
| 199 205 | 
             
                end
         | 
| @@ -35,6 +35,13 @@ describe HexaPDF::Rectangle do | |
| 35 35 | 
             
                assert_equal(4, rect.height)
         | 
| 36 36 | 
             
              end
         | 
| 37 37 |  | 
| 38 | 
            +
              it "allows comparison to arrays" do
         | 
| 39 | 
            +
                rect = HexaPDF::Rectangle.new([0, 1, 2, 5])
         | 
| 40 | 
            +
                assert(rect == [0, 1, 2, 5])
         | 
| 41 | 
            +
                rect.oid = 5
         | 
| 42 | 
            +
                refute(rect == [0, 1, 2, 5])
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 38 45 | 
             
              describe "validation" do
         | 
| 39 46 | 
             
                it "ensures that it is a correct PDF rectangle" do
         | 
| 40 47 | 
             
                  doc = HexaPDF::Document.new
         | 
| @@ -2,6 +2,7 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            require 'test_helper'
         | 
| 4 4 | 
             
            require 'hexapdf/reference'
         | 
| 5 | 
            +
            require 'hexapdf/object'
         | 
| 5 6 |  | 
| 6 7 | 
             
            describe HexaPDF::Reference do
         | 
| 7 8 | 
             
              it "correctly assigns oid and gen on initialization" do
         | 
| @@ -25,10 +26,11 @@ describe HexaPDF::Reference do | |
| 25 26 | 
             
                assert_nil(HexaPDF::Reference.new(1, 0) <=> 5)
         | 
| 26 27 | 
             
              end
         | 
| 27 28 |  | 
| 28 | 
            -
              it "is comparable to  | 
| 29 | 
            +
              it "is comparable to objects that have an oid and gen" do
         | 
| 29 30 | 
             
                assert_equal(HexaPDF::Reference.new(5, 7), HexaPDF::Reference.new(5, 7))
         | 
| 30 31 | 
             
                refute_equal(HexaPDF::Reference.new(5, 7), HexaPDF::Reference.new(5, 8))
         | 
| 31 32 | 
             
                refute_equal(HexaPDF::Reference.new(5, 7), HexaPDF::Reference.new(4, 7))
         | 
| 33 | 
            +
                assert_equal(HexaPDF::Reference.new(5, 7), HexaPDF::Object.new(:data, oid: 5, gen: 7))
         | 
| 32 34 | 
             
              end
         | 
| 33 35 |  | 
| 34 36 | 
             
              it "behaves correctly as hash key" do
         | 
| @@ -125,6 +125,11 @@ describe HexaPDF::Revision do | |
| 125 125 | 
             
                  obj3 = @rev.object(3)
         | 
| 126 126 | 
             
                  assert_equal([@obj, obj2, obj3], @rev.each.to_a)
         | 
| 127 127 | 
             
                end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                it "iterates only over loaded objects" do
         | 
| 130 | 
            +
                  obj = @rev.object(2)
         | 
| 131 | 
            +
                  assert_equal([obj], @rev.each(only_loaded: true).to_a)
         | 
| 132 | 
            +
                end
         | 
| 128 133 | 
             
              end
         | 
| 129 134 |  | 
| 130 135 | 
             
              it "works without a cross-reference section" do
         | 
| @@ -136,4 +141,12 @@ describe HexaPDF::Revision do | |
| 136 141 | 
             
                rev.delete(@ref, mark_as_free: false)
         | 
| 137 142 | 
             
                refute(rev.object?(@ref))
         | 
| 138 143 | 
             
              end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
              it "can iterate over all modified objects" do
         | 
| 146 | 
            +
                obj = @rev.object(2)
         | 
| 147 | 
            +
                assert_equal([], @rev.each_modified_object.to_a)
         | 
| 148 | 
            +
                obj.value = :Other
         | 
| 149 | 
            +
                @rev.add(@obj)
         | 
| 150 | 
            +
                assert_equal([obj, @obj], @rev.each_modified_object.to_a)
         | 
| 151 | 
            +
              end
         | 
| 139 152 | 
             
            end
         | 
| @@ -118,6 +118,7 @@ describe HexaPDF::Revisions do | |
| 118 118 |  | 
| 119 119 | 
             
              describe "initialize" do
         | 
| 120 120 | 
             
                it "automatically loads all revisions from the underlying IO object" do
         | 
| 121 | 
            +
                  assert_kind_of(HexaPDF::Parser, @revisions.parser)
         | 
| 121 122 | 
             
                  assert_equal(20, @revisions.revision(0).object(2).value)
         | 
| 122 123 | 
             
                  assert_equal(300, @revisions[1].object(2).value)
         | 
| 123 124 | 
             
                  assert_equal(400, @revisions[2].object(2).value)
         | 
    
        data/test/hexapdf/test_stream.rb
    CHANGED
    
    | @@ -58,6 +58,19 @@ describe HexaPDF::StreamData do | |
| 58 58 | 
             
                  end
         | 
| 59 59 | 
             
                end
         | 
| 60 60 | 
             
              end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
              describe "==" do
         | 
| 63 | 
            +
                it "compares with other stream data objects" do
         | 
| 64 | 
            +
                  s = HexaPDF::StreamData.new(:source, decode_parms: [:a, nil, :b])
         | 
| 65 | 
            +
                  assert_equal(s, HexaPDF::StreamData.new(:source, decode_parms: [:a, nil, :b]))
         | 
| 66 | 
            +
                  refute_equal(s, HexaPDF::StreamData.new(:source, decode_parms: [:a, :b]))
         | 
| 67 | 
            +
                  refute_equal(s, HexaPDF::StreamData.new(:source, decode_parms: [:a, nil, :b], offset: 5))
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                it "returns false if compared with an other object of a different class" do
         | 
| 71 | 
            +
                  refute_equal(:source, HexaPDF::StreamData.new(:source))
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 61 74 | 
             
            end
         | 
| 62 75 |  | 
| 63 76 | 
             
            describe HexaPDF::Stream do
         | 
    
        data/test/hexapdf/test_writer.rb
    CHANGED
    
    | @@ -40,7 +40,7 @@ describe HexaPDF::Writer do | |
| 40 40 | 
             
                  219
         | 
| 41 41 | 
             
                  %%EOF
         | 
| 42 42 | 
             
                  3 0 obj
         | 
| 43 | 
            -
                  <</Producer(HexaPDF version 0. | 
| 43 | 
            +
                  <</Producer(HexaPDF version 0.9.0)>>
         | 
| 44 44 | 
             
                  endobj
         | 
| 45 45 | 
             
                  xref
         | 
| 46 46 | 
             
                  3 1
         | 
| @@ -72,7 +72,7 @@ describe HexaPDF::Writer do | |
| 72 72 | 
             
                  141
         | 
| 73 73 | 
             
                  %%EOF
         | 
| 74 74 | 
             
                  6 0 obj
         | 
| 75 | 
            -
                  <</Producer(HexaPDF version 0. | 
| 75 | 
            +
                  <</Producer(HexaPDF version 0.9.0)>>
         | 
| 76 76 | 
             
                  endobj
         | 
| 77 77 | 
             
                  2 0 obj
         | 
| 78 78 | 
             
                  <</Length 10>>stream
         | 
| @@ -103,6 +103,17 @@ describe HexaPDF::Writer do | |
| 103 103 | 
             
                assert_document_conversion(@compressed_input_io)
         | 
| 104 104 | 
             
              end
         | 
| 105 105 |  | 
| 106 | 
            +
              it "writes a document in incremental mode" do
         | 
| 107 | 
            +
                doc = HexaPDF::Document.new(io: @std_input_io)
         | 
| 108 | 
            +
                doc.pages.add
         | 
| 109 | 
            +
                output_io = StringIO.new
         | 
| 110 | 
            +
                HexaPDF::Writer.write(doc, output_io, incremental: true)
         | 
| 111 | 
            +
                assert_equal(output_io.string[0, @std_input_io.string.length], @std_input_io.string)
         | 
| 112 | 
            +
                doc = HexaPDF::Document.new(io: output_io)
         | 
| 113 | 
            +
                assert_equal(4, doc.revisions.size)
         | 
| 114 | 
            +
                assert_equal(2, doc.revisions.current.each.to_a.size)
         | 
| 115 | 
            +
              end
         | 
| 116 | 
            +
             | 
| 106 117 | 
             
              it "raises an error if no xref stream is in a revision but object streams are" do
         | 
| 107 118 | 
             
                document = HexaPDF::Document.new
         | 
| 108 119 | 
             
                document.add(Type: :ObjStm)
         | 
| @@ -12,9 +12,20 @@ describe HexaPDF::Type::Form do | |
| 12 12 | 
             
              end
         | 
| 13 13 |  | 
| 14 14 | 
             
              describe "box" do
         | 
| 15 | 
            +
                before do
         | 
| 16 | 
            +
                  @form[:BBox] = [10, 10, 110, 60]
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 15 19 | 
             
                it "returns the /BBox entry" do
         | 
| 16 | 
            -
                   | 
| 17 | 
            -
             | 
| 20 | 
            +
                  assert_equal([10, 10, 110, 60], @form.box.value)
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                it "returns the box's width" do
         | 
| 24 | 
            +
                  assert_equal(100, @form.width)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                it "returns the box's height" do
         | 
| 28 | 
            +
                  assert_equal(50, @form.height)
         | 
| 18 29 | 
             
                end
         | 
| 19 30 | 
             
              end
         | 
| 20 31 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: hexapdf
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.9.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Thomas Leitner
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2018- | 
| 11 | 
            +
            date: 2018-12-31 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: cmdparse
         | 
| @@ -36,14 +36,14 @@ dependencies: | |
| 36 36 | 
             
                requirements:
         | 
| 37 37 | 
             
                - - "~>"
         | 
| 38 38 | 
             
                  - !ruby/object:Gem::Version
         | 
| 39 | 
            -
                    version: '0. | 
| 39 | 
            +
                    version: '0.2'
         | 
| 40 40 | 
             
              type: :runtime
         | 
| 41 41 | 
             
              prerelease: false
         | 
| 42 42 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 43 43 | 
             
                requirements:
         | 
| 44 44 | 
             
                - - "~>"
         | 
| 45 45 | 
             
                  - !ruby/object:Gem::Version
         | 
| 46 | 
            -
                    version: '0. | 
| 46 | 
            +
                    version: '0.2'
         | 
| 47 47 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 48 48 | 
             
              name: kramdown
         | 
| 49 49 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -205,6 +205,7 @@ files: | |
| 205 205 | 
             
            - examples/015-boxes.rb
         | 
| 206 206 | 
             
            - examples/016-frame_automatic_box_placement.rb
         | 
| 207 207 | 
             
            - examples/017-frame_text_flow.rb
         | 
| 208 | 
            +
            - examples/018-composer.rb
         | 
| 208 209 | 
             
            - examples/emoji-smile.png
         | 
| 209 210 | 
             
            - examples/emoji-wink.png
         | 
| 210 211 | 
             
            - examples/machupicchu.jpg
         | 
| @@ -219,6 +220,8 @@ files: | |
| 219 220 | 
             
            - lib/hexapdf/cli/merge.rb
         | 
| 220 221 | 
             
            - lib/hexapdf/cli/modify.rb
         | 
| 221 222 | 
             
            - lib/hexapdf/cli/optimize.rb
         | 
| 223 | 
            +
            - lib/hexapdf/cli/split.rb
         | 
| 224 | 
            +
            - lib/hexapdf/composer.rb
         | 
| 222 225 | 
             
            - lib/hexapdf/configuration.rb
         | 
| 223 226 | 
             
            - lib/hexapdf/content.rb
         | 
| 224 227 | 
             
            - lib/hexapdf/content/canvas.rb
         | 
| @@ -315,6 +318,7 @@ files: | |
| 315 318 | 
             
            - lib/hexapdf/layout.rb
         | 
| 316 319 | 
             
            - lib/hexapdf/layout/box.rb
         | 
| 317 320 | 
             
            - lib/hexapdf/layout/frame.rb
         | 
| 321 | 
            +
            - lib/hexapdf/layout/image_box.rb
         | 
| 318 322 | 
             
            - lib/hexapdf/layout/inline_box.rb
         | 
| 319 323 | 
             
            - lib/hexapdf/layout/line.rb
         | 
| 320 324 | 
             
            - lib/hexapdf/layout/numeric_refinements.rb
         | 
| @@ -533,6 +537,7 @@ files: | |
| 533 537 | 
             
            - test/hexapdf/image_loader/test_png.rb
         | 
| 534 538 | 
             
            - test/hexapdf/layout/test_box.rb
         | 
| 535 539 | 
             
            - test/hexapdf/layout/test_frame.rb
         | 
| 540 | 
            +
            - test/hexapdf/layout/test_image_box.rb
         | 
| 536 541 | 
             
            - test/hexapdf/layout/test_inline_box.rb
         | 
| 537 542 | 
             
            - test/hexapdf/layout/test_line.rb
         | 
| 538 543 | 
             
            - test/hexapdf/layout/test_style.rb
         | 
| @@ -543,6 +548,7 @@ files: | |
| 543 548 | 
             
            - test/hexapdf/layout/test_width_from_polygon.rb
         | 
| 544 549 | 
             
            - test/hexapdf/task/test_dereference.rb
         | 
| 545 550 | 
             
            - test/hexapdf/task/test_optimize.rb
         | 
| 551 | 
            +
            - test/hexapdf/test_composer.rb
         | 
| 546 552 | 
             
            - test/hexapdf/test_configuration.rb
         | 
| 547 553 | 
             
            - test/hexapdf/test_data_dir.rb
         | 
| 548 554 | 
             
            - test/hexapdf/test_dictionary.rb
         |