class Prawn::Font::AFM

Constants

BUILT_INS

Public Class Methods

metrics_path() click to toggle source
# File lib/prawn/font/afm.rb, line 23
def self.metrics_path
  if m = ENV['METRICS']
    @metrics_path ||= m.split(':')
  else
    @metrics_path ||= [
      ".", "/usr/lib/afm",
      "/usr/local/lib/afm",
      "/usr/openwin/lib/fonts/afm",
       Prawn::DATADIR+'/fonts']
  end
end

Public Instance Methods

bbox() click to toggle source

The font bbox, as an array of integers

# File lib/prawn/font/afm.rb, line 64
def bbox
  @bbox ||= @attributes['FontBBox'].split(/\s+/).map { |e| Integer(e) }
end
character_count(str) click to toggle source

Returns the number of characters in str (a WinAnsi-encoded string).

# File lib/prawn/font/afm.rb, line 101
def character_count(str)
  str.length
end
encode_text(text, options={}) click to toggle source

Perform any changes to the string that need to happen before it is rendered to the canvas. Returns an array of subset “chunks”, where each chunk is an array of two elements. The first element is the font subset number, and the second is either a string or an array (for kerned text).

For Adobe fonts, there is only ever a single subset, so the first element of the array is “0”, and the second is the string itself (or an array, if kerning is performed).

The text parameter must be in WinAnsi encoding (cp1252).

# File lib/prawn/font/afm.rb, line 117
def encode_text(text, options={})
  [[0, options[:kerning] ? kern(text) : text]]
end
glyph_present?(char) click to toggle source
# File lib/prawn/font/afm.rb, line 121
def glyph_present?(char)
  if char == "_"
    true
  else
    normalize_encoding(char) != "_"
  end
end
has_kerning_data?() click to toggle source

Returns true if the font has kerning data, false otherwise

# File lib/prawn/font/afm.rb, line 83
def has_kerning_data?
  @kern_pairs.any?
end
normalize_encoding(text) click to toggle source

built-in fonts only work with winansi encoding, so translate the string. Changes the encoding in-place, so the argument itself is replaced with a string in WinAnsi encoding.

# File lib/prawn/font/afm.rb, line 91
def normalize_encoding(text) 
  enc = @@winansi
  text.unpack("U*").collect { |i| enc[i] }.pack("C*")
rescue ArgumentError
  raise Prawn::Errors::IncompatibleStringEncoding,
    "Arguments to text methods must be UTF-8 encoded"
end
unicode?() click to toggle source
# File lib/prawn/font/afm.rb, line 19
def unicode?
  false
end

Private Instance Methods

build_glyph_table(font_data) click to toggle source
# File lib/prawn/font/afm.rb, line 188
def build_glyph_table(font_data)
  (0..255).map do |char|
    metrics = font_data.metrics_for(char)
    metrics ? metrics[:wx] : 0
  end
end
build_kern_pair_table(kern_pairs) click to toggle source
# File lib/prawn/font/afm.rb, line 178
def build_kern_pair_table(kern_pairs)
  character_hash = Hash[Encoding::WinAnsi::CHARACTERS.zip((0..Encoding::WinAnsi::CHARACTERS.size).to_a)]
  kern_pairs.inject({}) do |h,p|
    h[
      [character_hash[p[0]], character_hash[p[1]]]
    ] = p[2]
    h
  end
end
find_font(file) click to toggle source
# File lib/prawn/font/afm.rb, line 146
def find_font(file)
  self.class.metrics_path.find { |f| File.exist? "#{f}/#{file}" } + "/#{file}"
rescue NoMethodError
  raise Prawn::Errors::UnknownFont,
    "Couldn't find the font: #{file} in any of:\n" +
     self.class.metrics_path.join("\n")
end
kern(string) click to toggle source

converts a string into an array with spacing offsets bewteen characters that need to be kerned

String must be encoded as WinAnsi

# File lib/prawn/font/afm.rb, line 159
def kern(string)
  kerned = [[]]
  last_byte = nil

  string.bytes do |byte|
    if k = last_byte && @kern_pair_table[[last_byte, byte]]
      kerned << -k << [byte]
    else
      kerned.last << byte
    end         
    last_byte = byte
  end

  kerned.map { |e| 
    e = (Array === e ? e.pack("C*") : e)
    e.respond_to?(:force_encoding) ? e.force_encoding("Windows-1252") : e  
  }
end
register(subset) click to toggle source
# File lib/prawn/font/afm.rb, line 131
def register(subset)
  font_dict = {:Type     => :Font,
               :Subtype  => :Type1,
               :BaseFont => name.to_sym}

  # Symbolic AFM fonts (Symbol, ZapfDingbats) have their own encodings
  font_dict.merge!(:Encoding => :WinAnsiEncoding) unless symbolic?

  @document.ref!(font_dict)
end
symbolic?() click to toggle source
# File lib/prawn/font/afm.rb, line 142
def symbolic?
  attributes["CharacterSet"] == "Special"
end
unscaled_width_of(string) click to toggle source
# File lib/prawn/font/afm.rb, line 195
def unscaled_width_of(string)
  string.bytes.inject(0) do |s,r|
    s + @glyph_table[r]
  end
end