Class: Prawn::Font::AFM

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

Constant Summary collapse

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

#initialize(document, name, options = {}) ⇒ AFM

:nodoc:



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

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

  super

  @attributes     = {}
  @glyph_widths   = {}
  @bounding_boxes = {}
  @kern_pairs     = {}

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

  parse_afm(file_name)

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

Instance Attribute Details

#attributesObject (readonly)

:nodoc:



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

def attributes
  @attributes
end

Class Method Details

.metrics_pathObject



23
24
25
26
27
28
29
30
31
32
33
# 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::BASEDIR+'/data/fonts/']
  end
end

Instance Method Details

#bboxObject

The font bbox, as an array of integers



62
63
64
# File 'lib/prawn/font/afm.rb', line 62

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

#character_count(str) ⇒ Object

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



99
100
101
# File 'lib/prawn/font/afm.rb', line 99

def character_count(str)
  str.length
end

#compute_width_of(string, options = {}) ⇒ Object

NOTE: String must be encoded as WinAnsi



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/prawn/font/afm.rb', line 67

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

#encode_text(text, options = {}) ⇒ Object

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



115
116
117
# File 'lib/prawn/font/afm.rb', line 115

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

#glyph_present?(char) ⇒ Boolean

Returns:

  • (Boolean)


119
120
121
122
123
124
125
# File 'lib/prawn/font/afm.rb', line 119

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

#has_kerning_data?Boolean

Returns true if the font has kerning data, false otherwise

Returns:

  • (Boolean)


81
82
83
# File 'lib/prawn/font/afm.rb', line 81

def has_kerning_data?
  @kern_pairs.any?
end

#normalize_encoding(text) ⇒ Object

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.



89
90
91
92
93
94
95
# File 'lib/prawn/font/afm.rb', line 89

def normalize_encoding(text)
  enc = Prawn::Encoding::WinAnsi.new
  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?Boolean

Returns:

  • (Boolean)


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

def unicode?
  false
end