Class: Prawn::Font::AFM

Inherits:
Prawn::Font show all
Defined in:
lib/prawn/font/afm.rb

Constant Summary

BUILT_INS =
%w[ Courier Helvetica Times-Roman Symbol ZapfDingbats
Courier-Bold Courier-Oblique Courier-BoldOblique
Times-Bold Times-Italic Times-BoldItalic
Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique ]

Instance Attribute Summary (collapse)

Attributes inherited from Prawn::Font

#family, #name, #options

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods inherited from Prawn::Font

#add_to_current_page, #ascender, #descender, #height, #height_at, #identifier_for, #inspect, #line_gap, load, #normalize_encoding!

Constructor Details

- (AFM) initialize(document, name, options = {})

:nodoc:



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/prawn/font/afm.rb', line 38

def initialize(document, name, options={}) #:nodoc:
  unless BUILT_INS.include?(name)
    raise Prawn::Errors::UnknownFont, "#{name} is not a known font."
  end

  super

  @@winansi   ||= Prawn::Encoding::WinAnsi.new # parse data/encodings/win_ansi.txt once only
  @@font_data ||= SynchronizedCache.new        # parse each ATM font file once only

  file_name = @name.dup
  file_name << ".afm" unless file_name =~ /\.afm$/
  file_name = file_name[0] == ?/ ? file_name : find_font(file_name)

  font_data = @@font_data[file_name] ||= ::AFM::Font.new(file_name)
  @glyph_table     = build_glyph_table(font_data)
  @kern_pairs      = font_data.kern_pairs
  @kern_pair_table = build_kern_pair_table(@kern_pairs)
  @attributes      = font_data.

  @ascender  = @attributes["Ascender"].to_i
  @descender = @attributes["Descender"].to_i
  @line_gap  = Float(bbox[3] - bbox[1]) - (@ascender - @descender)
end

Instance Attribute Details

- (Object) attributes (readonly)

:nodoc:



36
37
38
# File 'lib/prawn/font/afm.rb', line 36

def attributes
  @attributes
end

Class Method Details

+ (Object) metrics_path



24
25
26
27
28
29
30
31
32
33
34
# File 'lib/prawn/font/afm.rb', line 24

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

Instance Method Details

- (Object) bbox

The font bbox, as an array of integers



65
66
67
# File 'lib/prawn/font/afm.rb', line 65

def bbox
  @bbox ||= @attributes['FontBBox'].split(/\s+/).map { |e| Integer(e) }
end

- (Object) character_count(str)

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



102
103
104
# File 'lib/prawn/font/afm.rb', line 102

def character_count(str)
  str.length
end

- (Object) compute_width_of(string, options = {})

NOTE: String must be encoded as WinAnsi



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/prawn/font/afm.rb', line 70

def compute_width_of(string, options={}) #:nodoc:
  scale = (options[:size] || size) / 1000.0

  if options[:kerning]
    strings, numbers = kern(string).partition { |e| e.is_a?(String) }
    total_kerning_offset = numbers.inject(0.0) { |s,r| s + r }
    (unscaled_width_of(strings.join) - total_kerning_offset) * scale
  else
    unscaled_width_of(string) * scale
  end
end

- (Object) encode_text(text, options = {})

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



118
119
120
# File 'lib/prawn/font/afm.rb', line 118

def encode_text(text, options={})
  [[0, options[:kerning] ? kern(text) : text]]
end

- (Boolean) glyph_present?(char)

Returns:

  • (Boolean)


122
123
124
125
126
127
128
# File 'lib/prawn/font/afm.rb', line 122

def glyph_present?(char)
  if char == "_"
    true
  else
    normalize_encoding(char) != "_"
  end
end

- (Boolean) has_kerning_data?

Returns true if the font has kerning data, false otherwise

Returns:

  • (Boolean)


84
85
86
# File 'lib/prawn/font/afm.rb', line 84

def has_kerning_data?
  @kern_pairs.any?
end

- (Object) normalize_encoding(text)

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.



92
93
94
95
96
97
98
# File 'lib/prawn/font/afm.rb', line 92

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

- (Boolean) unicode?

Returns:

  • (Boolean)


20
21
22
# File 'lib/prawn/font/afm.rb', line 20

def unicode?
  false
end