public
Description: Fast, Nimble PDF Writer for Ruby
Homepage: http://prawn.majesticseacreature.com
Clone URL: git://github.com/sandal/prawn.git
Now I think the kerning stuff is all patched up.  But we're looking at some pure 
evil here
sandal (author)
Mon Jul 21 12:08:34 -0700 2008
commit  77dba18246fd9008bc841b9ebda8df409b38d68b
tree    a9163c8809e228bf18b913596af172eb7cf151a1
parent  5b085020154b07cd031951b877b14858900ca90e
...
3
4
5
6
 
7
8
 
 
 
 
 
 
 
 
 
9
10
11
 
 
 
 
 
 
 
 
12
...
3
4
5
 
6
7
 
8
9
10
11
12
13
14
15
16
17
18
 
19
20
21
22
23
24
25
26
27
0
@@ -3,10 +3,25 @@ require "prawn"
0
 
0
 Prawn::Document.generate "kerning.pdf" do
0
   text "To kern?", :at => [200,720], :size => 24, :kerning => true
0
-  text "To not kern?", :at => [200,690], :size => 24, :kerning => false
0
+  text "To not kern?", :at => [200,690], :size => 24, :kerning => false 
0
   
0
-  font "#{Prawn::BASEDIR}/data/fonts/Dustismo_Roman.ttf"
0
+  move_down 100
0
+                                                                     
0
+  pad(30) do
0
+    text "To kern and wrap. " * 5, :size => 24, :kerning => true   
0
+  end
0
+  
0
+  text "To not kern and wrap. " * 5, :size => 24, :kerning => false
0
+
0
+  font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
0
   
0
   text "To kern?", :at => [200,660], :size => 24, :kerning => true
0
-  text "To not kern?", :at => [200,630], :size => 24, :kerning => false
0
+  text "To not kern?", :at => [200,630], :size => 24, :kerning => false     
0
+  
0
+  pad(30) do
0
+    text "To kern and wrap. " * 5, :size => 24, :kerning => true   
0
+  end
0
+  
0
+  text "To not kern and wrap. " * 5, :size => 24, :kerning => false
0
+  
0
 end
...
81
82
83
84
85
86
 
 
87
88
89
...
180
181
182
183
184
185
186
187
188
 
189
190
191
 
192
193
194
195
196
 
 
 
197
198
199
200
201
 
 
 
 
 
 
202
203
 
204
205
206
...
297
298
299
300
 
 
301
302
303
...
81
82
83
 
 
 
84
85
86
87
88
...
179
180
181
 
182
183
184
185
 
186
187
 
 
188
189
190
191
 
 
192
193
194
195
196
197
198
 
199
200
201
202
203
204
205
 
206
207
208
209
...
300
301
302
 
303
304
305
306
307
0
@@ -81,9 +81,8 @@ module Prawn
0
         x,y = translate(options[:at])
0
         font_size(options[:size] || current_font_size) do
0
           font_name = font_registry[fonts[@font]]          
0
-
0
-
0
-          text = @font_metrics.convert_text(text,options)
0
+          
0
+          text = @font_metrics.convert_text(text,options)    
0
 
0
           add_content %Q{
0
             BT
0
@@ -180,27 +179,31 @@ module Prawn
0
 
0
       # TODO: Get kerning working with wrapped text
0
       def wrapped_text(text,options)
0
-        options[:kerning] = false
0
         font_size(options[:size] || current_font_size) do
0
           font_name = font_registry[fonts[@font]]
0
 
0
           text = @font_metrics.naive_wrap(text, bounds.right, current_font_size, 
0
-            :kerning => options[:kerning])
0
+            :kerning => options[:kerning]) 
0
 
0
-          lines = text.lines.map { |t| 
0
-            @font_metrics.convert_text(t, options) }
0
+          lines = text.lines
0
 
0
           lines.each do |e|
0
             move_text_position(@font_metrics.font_height(current_font_size) +
0
-                               @font_metrics.descender / 1000.0 * current_font_size)
0
-
0
+                               @font_metrics.descender / 1000.0 * current_font_size)  
0
+                               
0
+                               
0
             add_content %Q{
0
               BT
0
               /#{font_name} #{current_font_size} Tf
0
               #{@bounding_box.absolute_left} #{y} Td
0
-              #{Prawn::PdfObject(e.to_s.chomp)} Tj
0
+            }    
0
+             
0
+           add_content Prawn::PdfObject(@font_metrics.convert_text(e,options)) << 
0
+             " #{options[:kerning] ? 'TJ' : 'Tj'}\n"   
0
+
0
+            add_content %Q{
0
               ET
0
-            }
0
+            }                
0
 
0
             move_text_position(-@font_metrics.descender / 1000.0 * current_font_size)
0
           end
0
@@ -297,7 +300,8 @@ module Prawn
0
 
0
       def enctables #:nodoc
0
         @enctables ||= {}
0
-      end
0
+      end 
0
+      
0
       def font_registry #:nodoc:
0
         @font_registry ||= {}
0
       end
...
107
108
109
110
 
111
112
113
...
243
244
245
246
247
 
 
248
249
 
250
251
252
...
255
256
257
258
 
259
260
261
 
262
263
264
...
272
273
274
275
276
277
278
279
280
281
 
 
282
283
 
 
 
 
 
 
 
 
 
 
 
284
285
286
287
288
...
107
108
109
 
110
111
112
113
...
243
244
245
 
 
246
247
248
 
249
250
251
252
...
255
256
257
 
258
259
260
 
261
262
263
264
...
272
273
274
 
 
 
 
 
 
 
275
276
277
 
278
279
280
281
282
283
284
285
286
287
288
289
 
290
291
292
0
@@ -107,7 +107,7 @@ module Prawn
0
           end
0
         end
0
         
0
-        def kern(string)
0
+        def kern(string) 
0
           kerned = string.unpack("U*").inject([]) do |a,r|
0
             if a.last.is_a? Array
0
               if kern = latin_kern_pairs_table[[a.last.last, r]]
0
@@ -243,10 +243,10 @@ module Prawn
0
         def string_width(string, font_size, options = {})
0
           scale = font_size / 1000.0
0
           if options[:kerning]
0
-            kern(string).inject(0) do |s,r|
0
-              if r.is_a? String
0
+            kern(string,:skip_conversion => true).inject(0) do |s,r|
0
+              if r.is_a? String  
0
                 s + string_width(r, font_size, :kerning => false)
0
-              else
0
+              else 
0
                 s + r * scale
0
               end
0
             end
0
@@ -255,10 +255,10 @@ module Prawn
0
               s + character_width_by_code(r)
0
             end * scale
0
           end
0
-        end
0
+        end   
0
         
0
         # TODO: NASTY. 
0
-        def kern(string)
0
+        def kern(string,options={})   
0
           string.unpack("U*").inject([]) do |a,r|
0
             if a.last.is_a? Array
0
               if kern = kern_pairs_table[[cmap[a.last.last], cmap[r]]] 
0
@@ -272,17 +272,21 @@ module Prawn
0
             end
0
             a
0
           end.map { |r| 
0
-            i = r.is_a?(Array) ? r.pack("U*") : r 
0
-            x = if i.is_a?(String)
0
-              unicode_codepoints = i.unpack("U*")
0
-              glyph_codes = unicode_codepoints.map { |u| 
0
-                enc_table.get_glyph_id_for_unicode(u)
0
-              }
0
-              glyph_codes.pack("n*")
0
+            if options[:skip_conversion]
0
+              r.is_a?(Array) ? r.pack("U*") : r
0
             else
0
-              i
0
+              i = r.is_a?(Array) ? r.pack("U*") : r 
0
+              x = if i.is_a?(String)
0
+                unicode_codepoints = i.unpack("U*")
0
+                glyph_codes = unicode_codepoints.map { |u| 
0
+                  enc_table.get_glyph_id_for_unicode(u)
0
+                }
0
+                glyph_codes.pack("n*")
0
+              else
0
+                i
0
+              end
0
+              x.is_a?(Numeric) ? -x : x 
0
             end
0
-            x.is_a?(Numeric) ? -x : x
0
           }
0
         end
0
 
...
15
16
17
18
19
20
 
 
 
21
22
23
...
15
16
17
 
 
 
18
19
20
21
22
23
0
@@ -15,9 +15,9 @@ module Prawn
0
         string.lines.each do |line|
0
           accumulated_width = 0
0
           segments = line.scan(/\S+|\s+/)
0
-          
0
-          segments.each do |segment|
0
-            segment_width = string_width(segment, font_size, :kerning => options[:kerning])
0
+                                        
0
+          segments.each do |segment|    
0
+            segment_width = string_width(segment, font_size, :kerning => options[:kerning]) 
0
       
0
             if (accumulated_width + segment_width).round > line_width.round
0
               output << "\n"
...
97
98
99
 
 
 
 
 
100
101
102
...
97
98
99
100
101
102
103
104
105
106
107
0
@@ -97,6 +97,11 @@ class TableTextObserver
0
   def show_text(*params)
0
     @strings << params[0]
0
   end
0
+  
0
+  def show_text_with_positioning(*params)      
0
+    # ignore kerning information
0
+    @strings << params[0].reject { |e| Numeric === e }.join
0
+  end
0
 end
0
 
0
 

Comments