Class: Pdfrb::Font::AFMParser

Inherits:
Object
  • Object
show all
Defined in:
lib/pdfrb/font/afm_parser.rb

Overview

AFM (Adobe Font Metrics) parser. Reads the text-based AFM format used by the 14 standard Type1 fonts.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAFMParser

Returns a new instance of AFMParser.



13
14
15
16
17
# File 'lib/pdfrb/font/afm_parser.rb', line 13

def initialize
  @char_metrics = {}
  @average_width = nil
  @max_width = nil
end

Instance Attribute Details

#ascenderObject (readonly)

Returns the value of attribute ascender.



8
9
10
# File 'lib/pdfrb/font/afm_parser.rb', line 8

def ascender
  @ascender
end

#average_widthObject (readonly)

Returns the value of attribute average_width.



8
9
10
# File 'lib/pdfrb/font/afm_parser.rb', line 8

def average_width
  @average_width
end

#bboxObject (readonly)

Returns the value of attribute bbox.



8
9
10
# File 'lib/pdfrb/font/afm_parser.rb', line 8

def bbox
  @bbox
end

#cap_heightObject (readonly)

Returns the value of attribute cap_height.



8
9
10
# File 'lib/pdfrb/font/afm_parser.rb', line 8

def cap_height
  @cap_height
end

#char_metricsObject (readonly)

Returns the value of attribute char_metrics.



8
9
10
# File 'lib/pdfrb/font/afm_parser.rb', line 8

def char_metrics
  @char_metrics
end

#descenderObject (readonly)

Returns the value of attribute descender.



8
9
10
# File 'lib/pdfrb/font/afm_parser.rb', line 8

def descender
  @descender
end

#encoding_schemeObject (readonly)

Returns the value of attribute encoding_scheme.



8
9
10
# File 'lib/pdfrb/font/afm_parser.rb', line 8

def encoding_scheme
  @encoding_scheme
end

#family_nameObject (readonly)

Returns the value of attribute family_name.



8
9
10
# File 'lib/pdfrb/font/afm_parser.rb', line 8

def family_name
  @family_name
end

#font_nameObject (readonly)

Returns the value of attribute font_name.



8
9
10
# File 'lib/pdfrb/font/afm_parser.rb', line 8

def font_name
  @font_name
end

#full_nameObject (readonly)

Returns the value of attribute full_name.



8
9
10
# File 'lib/pdfrb/font/afm_parser.rb', line 8

def full_name
  @full_name
end

#italic_angleObject (readonly)

Returns the value of attribute italic_angle.



8
9
10
# File 'lib/pdfrb/font/afm_parser.rb', line 8

def italic_angle
  @italic_angle
end

#max_widthObject (readonly)

Returns the value of attribute max_width.



8
9
10
# File 'lib/pdfrb/font/afm_parser.rb', line 8

def max_width
  @max_width
end

#x_heightObject (readonly)

Returns the value of attribute x_height.



8
9
10
# File 'lib/pdfrb/font/afm_parser.rb', line 8

def x_height
  @x_height
end

Class Method Details

.from_file(path) ⇒ Object



23
24
25
# File 'lib/pdfrb/font/afm_parser.rb', line 23

def self.from_file(path)
  parse(File.read(path, encoding: "UTF-8"))
end

.parse(text) ⇒ Object



19
20
21
# File 'lib/pdfrb/font/afm_parser.rb', line 19

def self.parse(text)
  new.tap { |p| p.parse(text) }
end

Instance Method Details

#handle_state_change(line, in_char_metrics) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/pdfrb/font/afm_parser.rb', line 42

def handle_state_change(line, in_char_metrics)
  if line.start_with?("StartCharMetrics")
    true
  elsif line.start_with?("EndCharMetrics")
    compute_average_and_max_widths
    false
  elsif in_char_metrics && line.start_with?("C ")
    parse_char_metric(line)
    in_char_metrics
  else
    in_char_metrics
  end
end

#parse(text) ⇒ Object



27
28
29
30
31
32
33
34
# File 'lib/pdfrb/font/afm_parser.rb', line 27

def parse(text)
  in_char_metrics = false
  text.each_line do |line|
    line = line.strip
    in_char_metrics = parse_line(line, in_char_metrics)
  end
  self
end

#parse_global_metric(line) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/pdfrb/font/afm_parser.rb', line 56

def parse_global_metric(line)
  case line
  when /\AFontName / then @font_name = line.split(" ", 2)[1]
  when /\AFullName / then @full_name = line.split(" ", 2)[1]
  when /\AFamilyName / then @family_name = line.split(" ", 2)[1]
  when /\AEncodingScheme / then @encoding_scheme = line.split(" ", 2)[1]
  when /\AFontBBox / then @bbox = line.split.drop(1).map(&:to_f)
  when /\ACapHeight / then @cap_height = line.split[1].to_f
  when /\AXHeight / then @x_height = line.split[1].to_f
  when /\AAscender / then @ascender = line.split[1].to_f
  when /\ADescender / then @descender = line.split[1].to_f
  when /\AItalicAngle / then @italic_angle = line.split[1].to_f
  else return nil
  end
  :handled
end

#parse_line(line, in_char_metrics) ⇒ Object



36
37
38
39
40
# File 'lib/pdfrb/font/afm_parser.rb', line 36

def parse_line(line, in_char_metrics)
  return handle_state_change(line, in_char_metrics) if parse_global_metric(line) == :handled

  handle_state_change(line, in_char_metrics)
end

#width_for(glyph_name_or_code) ⇒ Object



73
74
75
76
77
# File 'lib/pdfrb/font/afm_parser.rb', line 73

def width_for(glyph_name_or_code)
  metric = @char_metrics[glyph_name_or_code] ||
           @char_metrics[glyph_name_or_code.to_i]
  metric ? metric[:width] : 0
end