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 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