hexapdf 0.11.4 → 0.11.5
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 +17 -0
- data/CONTRIBUTERS +1 -1
- data/VERSION +1 -1
- data/lib/hexapdf/cli/image2pdf.rb +3 -3
- data/lib/hexapdf/document.rb +5 -0
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +22 -5
- data/lib/hexapdf/font/true_type/table/hmtx.rb +15 -5
- data/lib/hexapdf/layout/text_layouter.rb +1 -0
- data/lib/hexapdf/version.rb +1 -1
- data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +4 -4
- data/test/hexapdf/font/true_type/table/test_hmtx.rb +5 -5
- data/test/hexapdf/layout/test_text_layouter.rb +30 -11
- data/test/hexapdf/test_writer.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 245de775fa069ad91f2fe9f5e72610df40211e8b15a92b376cdf217c63b877fe
|
4
|
+
data.tar.gz: 34891827479def7d0efd506c9cd62f10abced99b8e694e39bc0dd06b1fa88bfe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c8bedff161a8aa756d6ffc426c89554e82537198692250a78f0eaad36fa896767681bda681d43bdcd5237f3eba91d25679499bbbe56ff525a16813c06187636
|
7
|
+
data.tar.gz: 35f82390333d2110c7ccb3059c93914e7ab03bbcd986c0ca7da1d3425c5a2c619aa42513da15d218423917e01f696b7b4e156f00b1997007c9feb637ae921d20
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
## 0.11.5 - 2020-01-27
|
2
|
+
|
3
|
+
### Changed
|
4
|
+
|
5
|
+
* [HexaPDF::Font::TrueType::Table::CmapSubtable] to lazily parse the subtable
|
6
|
+
* [HexaPDF::Font::TrueType::Table::Hmtx] to lazily parse the width data
|
7
|
+
* CLI command `hexapdf image2pdf` to use the last argument as output file
|
8
|
+
instead of the first (same order as `merge`)
|
9
|
+
* Automatically require the HexaPDF C extension if it is installed
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
* Wrong line length calculation for variable width layouting when a text box is
|
14
|
+
too wide and needs to be broken into parts
|
15
|
+
* CLI command `hexapdf image2pdf` so that treating a PDF as image works
|
16
|
+
|
17
|
+
|
1
18
|
## 0.11.4 - 2019-12-28
|
2
19
|
|
3
20
|
### Fixed
|
data/CONTRIBUTERS
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.11.
|
1
|
+
0.11.5
|
@@ -99,15 +99,15 @@ module HexaPDF
|
|
99
99
|
@margins = [0, 0, 0, 0]
|
100
100
|
end
|
101
101
|
|
102
|
-
def execute(
|
102
|
+
def execute(*images, out_file) #:nodoc:
|
103
103
|
maybe_raise_on_existing_file(out_file)
|
104
104
|
|
105
105
|
out = HexaPDF::Document.new
|
106
106
|
|
107
107
|
images.each do |image_file|
|
108
108
|
image = out.images.add(image_file)
|
109
|
-
iw = image.
|
110
|
-
ih = image.
|
109
|
+
iw = image.width.to_f
|
110
|
+
ih = image.height.to_f
|
111
111
|
if @scale != :fit
|
112
112
|
iw *= 72 / @scale
|
113
113
|
ih *= 72 / @scale
|
data/lib/hexapdf/document.rb
CHANGED
@@ -52,6 +52,11 @@ require 'hexapdf/image_loader'
|
|
52
52
|
require 'hexapdf/font_loader'
|
53
53
|
require 'hexapdf/layout'
|
54
54
|
|
55
|
+
begin
|
56
|
+
require 'hexapdf/cext'
|
57
|
+
rescue LoadError
|
58
|
+
end
|
59
|
+
|
55
60
|
# == HexaPDF API Documentation
|
56
61
|
#
|
57
62
|
# Here are some pointers to more in depth information:
|
@@ -73,9 +73,14 @@ module HexaPDF
|
|
73
73
|
attr_accessor :language
|
74
74
|
|
75
75
|
# The complete code map.
|
76
|
+
#
|
77
|
+
# Is only fully initialized for existing fonts when a mapping is first accessed via #[].
|
76
78
|
attr_accessor :code_map
|
77
79
|
|
78
80
|
# The complete gid map.
|
81
|
+
#
|
82
|
+
# Is only fully initialized for existing fonts when a mapping is first accessed via
|
83
|
+
# #gid_to_code.
|
79
84
|
attr_accessor :gid_map
|
80
85
|
|
81
86
|
# Creates a new subtable.
|
@@ -127,7 +132,22 @@ module HexaPDF
|
|
127
132
|
elsif [0, 2, 4, 6].include?(@format)
|
128
133
|
length, @language = io.read(4).unpack('n2')
|
129
134
|
end
|
130
|
-
|
135
|
+
|
136
|
+
return false unless [0, 2, 4, 6, 10, 12].include?(@format)
|
137
|
+
offset = io.pos
|
138
|
+
@code_map = lambda do |code|
|
139
|
+
parse_mapping(io, offset, length)
|
140
|
+
@code_map[code]
|
141
|
+
end
|
142
|
+
@gid_map = lambda do |gid|
|
143
|
+
parse_mapping(io, offset, length)
|
144
|
+
@gid_map[gid]
|
145
|
+
end
|
146
|
+
true
|
147
|
+
end
|
148
|
+
|
149
|
+
def parse_mapping(io, offset, length)
|
150
|
+
io.pos = offset
|
131
151
|
@code_map, @gid_map = case @format
|
132
152
|
when 0 then Format0.parse(io, length)
|
133
153
|
when 2 then Format2.parse(io, length)
|
@@ -135,12 +155,9 @@ module HexaPDF
|
|
135
155
|
when 6 then Format6.parse(io, length)
|
136
156
|
when 10 then Format10.parse(io, length)
|
137
157
|
when 12 then Format12.parse(io, length)
|
138
|
-
else
|
139
|
-
supported = false
|
140
|
-
[{}, {}]
|
141
158
|
end
|
142
|
-
supported
|
143
159
|
end
|
160
|
+
private :parse_mapping
|
144
161
|
|
145
162
|
def inspect #:nodoc:
|
146
163
|
"#<#{self.class.name} (#{platform_id}, #{encoding_id}, #{language}, " \
|
@@ -51,7 +51,7 @@ module HexaPDF
|
|
51
51
|
# the :left_side_bearing.
|
52
52
|
Metric = Struct.new(:advance_width, :left_side_bearing)
|
53
53
|
|
54
|
-
#
|
54
|
+
# A hash of glyph ID to Metric objects mapping.
|
55
55
|
attr_accessor :horizontal_metrics
|
56
56
|
|
57
57
|
# Returns the Metric object for the give glyph ID.
|
@@ -63,10 +63,20 @@ module HexaPDF
|
|
63
63
|
|
64
64
|
def parse_table #:nodoc:
|
65
65
|
nr_entries = font[:hhea].num_of_long_hor_metrics
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
max_id = nr_entries + (directory_entry.length - 4 * nr_entries) / 2
|
67
|
+
@horizontal_metrics = Hash.new do |hash, glyph_id|
|
68
|
+
return nil if glyph_id >= max_id
|
69
|
+
if glyph_id >= nr_entries
|
70
|
+
with_io_pos(directory_entry.offset + 4 * nr_entries + (glyph_id - nr_entries) * 2) do
|
71
|
+
hash[glyph_id] = Metric.new(@horizontal_metrics[nr_entries - 1].advance_width,
|
72
|
+
*read_formatted(2, 's>'))
|
73
|
+
end
|
74
|
+
else
|
75
|
+
with_io_pos(directory_entry.offset + 4 * glyph_id) do
|
76
|
+
hash[glyph_id] = Metric.new(*read_formatted(4, 'ns>'))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
hash[glyph_id]
|
70
80
|
end
|
71
81
|
end
|
72
82
|
|
data/lib/hexapdf/version.rb
CHANGED
@@ -43,14 +43,14 @@ describe HexaPDF::Font::TrueType::Table::CmapSubtable do
|
|
43
43
|
|
44
44
|
it "works for format 0" do
|
45
45
|
t = table([0, 262, 0].pack('n3') + [255].pack('C*') + (0..254).to_a.pack('C*'))
|
46
|
+
assert_equal(0, t.gid_to_code(255))
|
47
|
+
assert_equal(234, t.gid_to_code(233))
|
48
|
+
|
46
49
|
assert_equal(255, t[0])
|
47
50
|
assert_equal(233, t[234])
|
48
51
|
assert_nil(t[256])
|
49
52
|
|
50
|
-
|
51
|
-
assert_equal(234, t.gid_to_code(233))
|
52
|
-
|
53
|
-
assert_raises(HexaPDF::Error) { table([0, 20, 0].pack('n3') + "a" * 20) }
|
53
|
+
assert_raises(HexaPDF::Error) { table([0, 20, 0].pack('n3') + "a" * 20)[0] }
|
54
54
|
end
|
55
55
|
|
56
56
|
it "works for format 2" do
|
@@ -5,7 +5,7 @@ require_relative 'common'
|
|
5
5
|
require 'hexapdf/font/true_type/table/hhea'
|
6
6
|
require 'hexapdf/font/true_type/table/hmtx'
|
7
7
|
|
8
|
-
describe HexaPDF::Font::TrueType::Table::
|
8
|
+
describe HexaPDF::Font::TrueType::Table::Hmtx do
|
9
9
|
before do
|
10
10
|
data = [1, -2, 3, -4, 5, -6].pack('ns>ns>s>2')
|
11
11
|
set_up_stub_true_type_font(data)
|
@@ -17,14 +17,14 @@ describe HexaPDF::Font::TrueType::Table::Hhea do
|
|
17
17
|
describe "initialize" do
|
18
18
|
it "reads the data from the associated file" do
|
19
19
|
table = create_table(:Hmtx)
|
20
|
-
assert_equal(1, table[0].advance_width)
|
21
|
-
assert_equal(-2, table[0].left_side_bearing)
|
22
|
-
assert_equal(3, table[1].advance_width)
|
23
|
-
assert_equal(-4, table[1].left_side_bearing)
|
24
20
|
assert_equal(3, table[2].advance_width)
|
25
21
|
assert_equal(5, table[2].left_side_bearing)
|
26
22
|
assert_equal(3, table[3].advance_width)
|
27
23
|
assert_equal(-6, table[3].left_side_bearing)
|
24
|
+
assert_equal(1, table[0].advance_width)
|
25
|
+
assert_equal(-2, table[0].left_side_bearing)
|
26
|
+
assert_equal(3, table[1].advance_width)
|
27
|
+
assert_equal(-4, table[1].left_side_bearing)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -556,18 +556,37 @@ describe HexaPDF::Layout::TextLayouter do
|
|
556
556
|
end
|
557
557
|
end
|
558
558
|
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
assert_equal(:success, result.status)
|
565
|
-
assert_equal(str.strip.length, result.lines.sum {|l| l.items.sum {|i| i.items.count } })
|
566
|
-
assert_equal(45, result.height)
|
559
|
+
describe "breaks a text fragment into parts if it is wider than the available width" do
|
560
|
+
before do
|
561
|
+
@str = " This is averylongstring"
|
562
|
+
@frag = HexaPDF::Layout::TextFragment.create(@str, font: @font)
|
563
|
+
end
|
567
564
|
|
568
|
-
|
569
|
-
|
570
|
-
|
565
|
+
it "works with fixed width" do
|
566
|
+
result = @layouter.fit([@frag], 20, 100)
|
567
|
+
assert(result.remaining_items.empty?)
|
568
|
+
assert_equal(:success, result.status)
|
569
|
+
assert_equal(@str.delete(" ").length, result.lines.sum {|l| l.items.sum {|i| i.items.count } })
|
570
|
+
assert_equal(54, result.height)
|
571
|
+
|
572
|
+
result = @layouter.fit([@frag], 1, 100)
|
573
|
+
assert_equal(8, result.remaining_items.count)
|
574
|
+
assert_equal(:box_too_wide, result.status)
|
575
|
+
end
|
576
|
+
|
577
|
+
it "works with variable width" do
|
578
|
+
width_block = lambda do |height, line_height|
|
579
|
+
# 'averylongstring' would fit when only considering height but not height + line_height
|
580
|
+
if height + line_height < 15
|
581
|
+
63
|
582
|
+
else
|
583
|
+
10
|
584
|
+
end
|
585
|
+
end
|
586
|
+
result = @layouter.fit([@frag], width_block, 30)
|
587
|
+
assert_equal(:height, result.status)
|
588
|
+
assert_equal([26.95, 9.44, 7.77], result.lines.map {|l| l.width.round(3) })
|
589
|
+
end
|
571
590
|
end
|
572
591
|
|
573
592
|
describe "horizontal alignment" 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.11.
|
43
|
+
<</Producer(HexaPDF version 0.11.5)>>
|
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.11.
|
75
|
+
<</Producer(HexaPDF version 0.11.5)>>
|
76
76
|
endobj
|
77
77
|
2 0 obj
|
78
78
|
<</Length 10>>stream
|
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.11.
|
4
|
+
version: 0.11.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Leitner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cmdparse
|
@@ -637,7 +637,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
637
637
|
- !ruby/object:Gem::Version
|
638
638
|
version: '0'
|
639
639
|
requirements: []
|
640
|
-
rubygems_version: 3.
|
640
|
+
rubygems_version: 3.1.2
|
641
641
|
signing_key:
|
642
642
|
specification_version: 4
|
643
643
|
summary: HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|