hexapdf 0.11.4 → 0.11.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|