prawn 0.4.0 → 0.4.1
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.
- data/Rakefile +1 -1
- data/lib/prawn.rb +1 -1
- data/lib/prawn/document.rb +1 -1
- data/lib/prawn/document/text/box.rb +1 -1
- data/lib/prawn/font/afm.rb +28 -25
- data/lib/prawn/font/ttf.rb +37 -29
- data/spec/document_spec.rb +12 -0
- metadata +2 -2
data/Rakefile
CHANGED
data/lib/prawn.rb
CHANGED
data/lib/prawn/document.rb
CHANGED
data/lib/prawn/font/afm.rb
CHANGED
@@ -57,18 +57,11 @@ module Prawn
|
|
57
57
|
scale = (options[:size] || size) / 1000.0
|
58
58
|
|
59
59
|
if options[:kerning]
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
s + width_of(r, no_kern_opts)
|
64
|
-
else
|
65
|
-
s - (r * scale)
|
66
|
-
end
|
67
|
-
end
|
60
|
+
strings, numbers = kern(string).partition { |e| e.is_a?(String) }
|
61
|
+
total_kerning_offset = numbers.inject(0.0) { |s,r| s + r }
|
62
|
+
(unscaled_width_of(strings.join) - total_kerning_offset) * scale
|
68
63
|
else
|
69
|
-
string
|
70
|
-
s + latin_glyphs_table[r]
|
71
|
-
end * scale
|
64
|
+
unscaled_width_of(string) * scale
|
72
65
|
end
|
73
66
|
end
|
74
67
|
|
@@ -162,23 +155,23 @@ module Prawn
|
|
162
155
|
# String *must* be encoded as WinAnsi
|
163
156
|
#
|
164
157
|
def kern(string)
|
165
|
-
kerned =
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
158
|
+
kerned = [[]]
|
159
|
+
last_byte = nil
|
160
|
+
|
161
|
+
kern_pairs = latin_kern_pairs_table
|
162
|
+
|
163
|
+
string.unpack("C*").each do |byte|
|
164
|
+
if k = last_byte && kern_pairs[[last_byte, byte]]
|
165
|
+
kerned << -k << [byte]
|
172
166
|
else
|
173
|
-
|
174
|
-
end
|
175
|
-
|
167
|
+
kerned.last << byte
|
168
|
+
end
|
169
|
+
last_byte = byte
|
176
170
|
end
|
177
171
|
|
178
|
-
kerned.map { |
|
179
|
-
|
180
|
-
|
181
|
-
i.is_a?(Numeric) ? -i : i
|
172
|
+
kerned.map { |e|
|
173
|
+
e = (Array === e ? e.pack("C*") : e)
|
174
|
+
e.respond_to?(:force_encoding) ? e.force_encoding("Windows-1252") : e
|
182
175
|
}
|
183
176
|
end
|
184
177
|
|
@@ -194,6 +187,16 @@ module Prawn
|
|
194
187
|
@glyph_widths[Encoding::WinAnsi::CHARACTERS[i]].to_i
|
195
188
|
end
|
196
189
|
end
|
190
|
+
|
191
|
+
private
|
192
|
+
|
193
|
+
def unscaled_width_of(string)
|
194
|
+
glyph_table = latin_glyphs_table
|
195
|
+
|
196
|
+
string.unpack("C*").inject(0) do |s,r|
|
197
|
+
s + glyph_table[r]
|
198
|
+
end
|
199
|
+
end
|
197
200
|
end
|
198
201
|
end
|
199
202
|
end
|
data/lib/prawn/font/ttf.rb
CHANGED
@@ -229,7 +229,10 @@ module Prawn
|
|
229
229
|
# subset. Perhaps this could be done by querying the subset,
|
230
230
|
# rather than by parsing the font that the subset produces?
|
231
231
|
font = TTFunk::File.new(font_content)
|
232
|
-
|
232
|
+
|
233
|
+
# empirically, it looks like Adobe Reader will not display fonts
|
234
|
+
# if their font name is more than 33 bytes long. Strange. But true.
|
235
|
+
basename = font.name.postscript_name[0, 33]
|
233
236
|
|
234
237
|
raise "Can't detect a postscript name for #{file}" if basename.nil?
|
235
238
|
|
@@ -254,39 +257,44 @@ module Prawn
|
|
254
257
|
|
255
258
|
hmtx = font.horizontal_metrics
|
256
259
|
widths = font.cmap.tables.first.code_map.map { |gid|
|
257
|
-
Integer(hmtx.widths[gid] * scale_factor) }
|
260
|
+
Integer(hmtx.widths[gid] * scale_factor) }[32..-1]
|
261
|
+
|
262
|
+
# It would be nice to have Encoding set for the macroman subsets,
|
263
|
+
# and only do a ToUnicode cmap for non-encoded unicode subsets.
|
264
|
+
# However, apparently Adobe Reader won't render MacRoman encoded
|
265
|
+
# subsets if original font contains unicode characters. (It has to
|
266
|
+
# be some flag or something that ttfunk is simply copying over...
|
267
|
+
# but I can't figure out which flag that is.)
|
268
|
+
#
|
269
|
+
# For now, it's simplest to just create a unicode cmap for every font.
|
270
|
+
# It offends my inner purist, but it'll do.
|
271
|
+
|
272
|
+
map = @subsets[subset].to_unicode_map
|
273
|
+
|
274
|
+
ranges = [[]]
|
275
|
+
lines = map.keys.sort.inject("") do |s, code|
|
276
|
+
ranges << [] if ranges.last.length >= 100
|
277
|
+
unicode = map[code]
|
278
|
+
ranges.last << "<%02x><%04x>" % [code, unicode]
|
279
|
+
end
|
280
|
+
|
281
|
+
range_blocks = ranges.inject("") do |s, list|
|
282
|
+
s << "%d beginbfchar\n%s\nendbfchar\n" % [list.length, list.join("\n")]
|
283
|
+
end
|
284
|
+
|
285
|
+
to_unicode_cmap = UNICODE_CMAP_TEMPLATE % range_blocks.strip
|
286
|
+
|
287
|
+
cmap = @document.ref({})
|
288
|
+
cmap << to_unicode_cmap
|
289
|
+
cmap.compress_stream
|
258
290
|
|
259
291
|
reference.data.update(:Subtype => :TrueType,
|
260
292
|
:BaseFont => basename,
|
261
293
|
:FontDescriptor => descriptor,
|
262
|
-
:FirstChar =>
|
294
|
+
:FirstChar => 32,
|
263
295
|
:LastChar => 255,
|
264
|
-
:Widths => @document.ref(widths)
|
265
|
-
|
266
|
-
if @subsets[subset].unicode?
|
267
|
-
map = @subsets[subset].to_unicode_map
|
268
|
-
|
269
|
-
ranges = [[]]
|
270
|
-
lines = map.keys.sort.inject("") do |s, code|
|
271
|
-
ranges << [] if ranges.last.length >= 100
|
272
|
-
unicode = map[code]
|
273
|
-
ranges.last << "<%02x><%04x>" % [code, unicode]
|
274
|
-
end
|
275
|
-
|
276
|
-
range_blocks = ranges.inject("") do |s, list|
|
277
|
-
s << "%d beginbfchar\n%s\nendbfchar\n" % [list.length, list.join("\n")]
|
278
|
-
end
|
279
|
-
|
280
|
-
to_unicode_cmap = UNICODE_CMAP_TEMPLATE % range_blocks.strip
|
281
|
-
|
282
|
-
cmap = @document.ref({})
|
283
|
-
cmap << to_unicode_cmap
|
284
|
-
cmap.compress_stream
|
285
|
-
|
286
|
-
@references[subset].data[:ToUnicode] = cmap
|
287
|
-
else
|
288
|
-
@references[subset].data[:Encoding] = :MacRomanEncoding
|
289
|
-
end
|
296
|
+
:Widths => @document.ref(widths),
|
297
|
+
:ToUnicode => cmap)
|
290
298
|
end
|
291
299
|
|
292
300
|
UNICODE_CMAP_TEMPLATE = <<-STR.strip.gsub(/^\s*/, "")
|
data/spec/document_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require "tempfile"
|
2
3
|
|
3
4
|
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
4
5
|
|
@@ -11,6 +12,17 @@ describe "The cursor" do
|
|
11
12
|
pdf.cursor.should == pdf.y - pdf.bounds.absolute_bottom
|
12
13
|
end
|
13
14
|
end
|
15
|
+
|
16
|
+
describe "when generating a document from a subclass" do
|
17
|
+
it "should be an instance_eval of the subclass" do
|
18
|
+
custom_document = Class.new(Prawn::Document)
|
19
|
+
custom_document.generate(Tempfile.new("generate_test").path) do |e|
|
20
|
+
e.class.should == custom_document
|
21
|
+
assert e.kind_of?(Prawn::Document)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
14
26
|
|
15
27
|
describe "When creating multi-page documents" do
|
16
28
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prawn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gregory Brown
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-01-
|
12
|
+
date: 2009-01-24 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|