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

Returns a new instance of AFM.


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/prawn/font/afm.rb', line 25

def initialize(document, name, options={})
  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)

Returns the value of attribute attributes


23
24
25
# File 'lib/prawn/font/afm.rb', line 23

def attributes
  @attributes
end

Class Method Details

.metrics_pathObject


11
12
13
14
15
16
17
18
19
20
21
# File 'lib/prawn/font/afm.rb', line 11

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


48
49
50
# File 'lib/prawn/font/afm.rb', line 48

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

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

calculates the width of the supplied string.

String must be encoded as WinAnsi


56
57
58
59
60
61
62
63
64
65
66
# File 'lib/prawn/font/afm.rb', line 56

def compute_width_of(string, options={})
  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).


91
92
93
# File 'lib/prawn/font/afm.rb', line 91

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

#has_kerning_data?Boolean

Returns:

  • (Boolean)

68
69
70
# File 'lib/prawn/font/afm.rb', line 68

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.


75
76
77
78
# File 'lib/prawn/font/afm.rb', line 75

def normalize_encoding(text)
  enc = Prawn::Encoding::WinAnsi.new
  text.unpack("U*").collect { |i| enc[i] }.pack("C*")
end