class Prawn::Font::AFM
Constants
- BUILT_INS
Public Class Methods
# 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
Public Instance Methods
The font bbox, as an array of integers
# File lib/prawn/font/afm.rb, line 62 def bbox @bbox ||= @attributes['fontbbox'].split(/\s+/).map { |e| Integer(e) } end
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 106 def encode_text(text, options={}) [[0, options[:kerning] ? kern(text) : text]] end
Returns true if the font has kerning data, false otherwise
# File lib/prawn/font/afm.rb, line 81 def has_kerning_data? @kern_pairs.any? end
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 89 def normalize_encoding(text) enc = Prawn::Encoding::WinAnsi.new text.unpack("U*").collect { |i| enc[i] }.pack("C*") end
# File lib/prawn/font/afm.rb, line 19 def unicode? false end
Private Instance Methods
# File lib/prawn/font/afm.rb, line 127 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
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 180 def kern(string) kerned = [[]] last_byte = nil kern_pairs = latin_kern_pairs_table string.unpack("C*").each do |byte| if k = last_byte && kern_pairs[[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
# File lib/prawn/font/afm.rb, line 208 def latin_glyphs_table @glyphs_table ||= (0..255).map do |i| @glyph_widths[Encoding::WinAnsi::CHARACTERS[i]].to_i end end
# File lib/prawn/font/afm.rb, line 201 def latin_kern_pairs_table @kern_pairs_table ||= @kern_pairs.inject({}) do |h,p| h[p[0].map { |n| Encoding::WinAnsi::CHARACTERS.index(n) }] = p[1] h end end
# File lib/prawn/font/afm.rb, line 135 def parse_afm(file_name) section = [] File.foreach(file_name) do |line| case line when /^Start(\w+)/ section.push $1 next when /^End(\w+)/ section.pop next end case section when ["FontMetrics", "CharMetrics"] next unless line =~ /^CH?\s/ name = line[/\bN\s+(\.?\w+)\s*;/, 1] @glyph_widths[name] = line[/\bWX\s+(\d+)\s*;/, 1].to_i @bounding_boxes[name] = line[/\bB\s+([^;]+);/, 1].to_s.rstrip when ["FontMetrics", "KernData", "KernPairs"] next unless line =~ /^KPX\s+(\.?\w+)\s+(\.?\w+)\s+(-?\d+)/ @kern_pairs[[$1, $2]] = $3.to_i when ["FontMetrics", "KernData", "TrackKern"], ["FontMetrics", "Composites"] next else parse_generic_afm_attribute(line) end end end
# File lib/prawn/font/afm.rb, line 167 def parse_generic_afm_attribute(line) line =~ /(^\w+)\s+(.*)/ key, value = $1.to_s.downcase, $2 @attributes[key] = @attributes[key] ? Array(@attributes[key]) << value : value end
# File lib/prawn/font/afm.rb, line 112 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
# File lib/prawn/font/afm.rb, line 123 def symbolic? attributes["characterset"] == "Special" end
# File lib/prawn/font/afm.rb, line 216 def unscaled_width_of(string) glyph_table = latin_glyphs_table string.unpack("C*").inject(0) do |s,r| s + glyph_table[r] end end