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