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
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
Creates and returns the single GlyphList
instance.
# File lib/hexapdf/font/encoding/glyph_list.rb, line 58 def self.new @instance ||= super end
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
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
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
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
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