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 CHANGED
@@ -4,7 +4,7 @@ require 'rake/testtask'
4
4
  require "rake/rdoctask"
5
5
  require "rake/gempackagetask"
6
6
 
7
- PRAWN_VERSION = "0.4.0"
7
+ PRAWN_VERSION = "0.4.1"
8
8
 
9
9
  task :default => [:test]
10
10
 
@@ -20,7 +20,7 @@ module Prawn
20
20
  # The base source directory for Prawn as installed on the system
21
21
  BASEDIR = File.expand_path(File.join(dir, '..'))
22
22
 
23
- VERSION = "0.4.0"
23
+ VERSION = "0.4.1"
24
24
 
25
25
  extend self
26
26
 
@@ -55,7 +55,7 @@ module Prawn
55
55
  # end
56
56
  #
57
57
  def self.generate(filename,options={},&block)
58
- pdf = Prawn::Document.new(options,&block)
58
+ pdf = new(options,&block)
59
59
  pdf.render_file(filename)
60
60
  end
61
61
 
@@ -61,7 +61,7 @@ module Prawn
61
61
 
62
62
  lines = text.lines.to_a
63
63
 
64
- unless lines.length < max_lines
64
+ if lines.length > max_lines
65
65
  @text = lines[0...max_lines].join
66
66
  case(@overflow)
67
67
  when :ellipses
@@ -57,18 +57,11 @@ module Prawn
57
57
  scale = (options[:size] || size) / 1000.0
58
58
 
59
59
  if options[:kerning]
60
- no_kern_opts = options.merge(:kerning => false)
61
- kern(string).inject(0) do |s,r|
62
- if r.is_a? String
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.unpack("C*").inject(0) do |s,r|
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 = string.unpack("C*").inject([]) do |a,r|
166
- if a.last.is_a? Array
167
- if k = latin_kern_pairs_table[[a.last.last, r]]
168
- a << k << [r]
169
- else
170
- a.last << r
171
- end
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
- a << [r]
174
- end
175
- a
167
+ kerned.last << byte
168
+ end
169
+ last_byte = byte
176
170
  end
177
171
 
178
- kerned.map { |r|
179
- i = r.is_a?(Array) ? r.pack("C*") : r
180
- i.force_encoding("Windows-1252") if i.respond_to?(:force_encoding)
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
@@ -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
- basename = font.name.postscript_name
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 => 0,
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*/, "")
@@ -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.0
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-17 00:00:00 -05:00
12
+ date: 2009-01-24 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency