class HexaPDF::Font::Encoding::GlyphList

Provides access to and mapping functionality for the Adobe Glyph List.

The Adobe Glyph List is used for mapping glyph names to Unicode values. The mapping itself is not a one-to-one mapping because some glyphs are mapped to the same Unicode sequence, e.g. the glyph name for 'A' and the glyph name for 'small capital A'.

Since a reverse mapping is needed for converting UTF-8 strings to glyph names when encoding text, this (not unique) reverse mapping is also available. However, only the first occurence of a particular Unicode string is reverse-mapped.

See:

Public Class Methods

name_to_unicode(name, zapf_dingbats: false) click to toggle source

See name_to_unicode

# File lib/hexapdf/font/encoding/glyph_list.rb, line 63
def self.name_to_unicode(name, zapf_dingbats: false)
  new.name_to_unicode(name, zapf_dingbats: zapf_dingbats)
end
new() click to toggle source

Creates and returns the single GlyphList instance.

Calls superclass method
# File lib/hexapdf/font/encoding/glyph_list.rb, line 58
def self.new
  @instance ||= super
end
unicode_to_name(unicode, zapf_dingbats: false) click to toggle source

See unicode_to_name

# File lib/hexapdf/font/encoding/glyph_list.rb, line 68
def self.unicode_to_name(unicode, zapf_dingbats: false)
  new.unicode_to_name(unicode, zapf_dingbats: zapf_dingbats)
end

Public Instance Methods

name_to_unicode(name, zapf_dingbats: false) click to toggle source

Maps the given name to a string by following the Adobe Glyph Specification. Returns nil if the name has no correct mapping.

If this method is invoked when dealing with the ZapfDingbats font, the zapf_dingbats option needs to be set to true.

Assumes that the name is a Symbol and that it includes just one component (no underscores)!

# File lib/hexapdf/font/encoding/glyph_list.rb, line 84
def name_to_unicode(name, zapf_dingbats: false)
  if zapf_dingbats && @zapf_name_to_uni.key?(name)
    @zapf_name_to_uni[name]
  elsif @standard_name_to_uni.key?(name)
    @standard_name_to_uni[name]
  else
    name = name.to_s
    if name =~ /\Auni([0-9A-F]{4})\Z/ || name =~ /\Au([0-9A-f]{4,6})\Z/
      +'' << $1.hex
    end
  end
end
unicode_to_name(unicode, zapf_dingbats: false) click to toggle source

Maps the given Unicode codepoint/string to a name in the Adobe Glyph List, or to .notdef if there is no mapping.

If this method is invoked when dealing with the ZapfDingbats font, the zapf_dingbats option needs to be set to true.

# File lib/hexapdf/font/encoding/glyph_list.rb, line 102
def unicode_to_name(unicode, zapf_dingbats: false)
  if zapf_dingbats
    @zapf_uni_to_name.fetch(unicode, :'.notdef')
  else
    @standard_uni_to_name.fetch(unicode, :'.notdef')
  end
end

Private Instance Methods

load() click to toggle source

Loads the needed Adobe Glyph List files.

# File lib/hexapdf/font/encoding/glyph_list.rb, line 113
def load
  @standard_name_to_uni, @standard_uni_to_name =
    load_file(File.join(HexaPDF.data_dir, 'encoding', 'glyphlist.txt'))
  @zapf_name_to_uni, @zapf_uni_to_name =
    load_file(File.join(HexaPDF.data_dir, 'encoding', 'zapfdingbats.txt'))
end
load_file(file) click to toggle source

Loads an Adobe Glyph List from the specified file and returns the name-to-unicode and unicode-to-name mappings.

Regarding the mappings:

  • The name-to-unicode mapping maps a name (Symbol) to an UTF-8 string consisting of one or more characters.

  • The unicode-to-name mapping is not unique! It only uses the first occurence of a Unicode sequence.

# File lib/hexapdf/font/encoding/glyph_list.rb, line 130
def load_file(file)
  name2uni = {}
  uni2name = {}
  File.open(file, 'rb') do |f|
    while (line = f.gets)
      next if line.start_with?('#')
      index = line.index(';')
      name = line[0, index].to_sym
      codes = line[index + 1, 50].split(" ").map(&:hex).pack('U*')
      name2uni[name] = codes
      uni2name[codes] = name unless uni2name.key?(codes)
    end
  end
  [name2uni.freeze, uni2name.freeze]
end