Class: Emfsvg::GlyphIndexMapper
- Inherits:
-
Object
- Object
- Emfsvg::GlyphIndexMapper
- Defined in:
- lib/emfsvg/glyph_index_mapper.rb
Overview
Maps glyph indices to Unicode codepoints using the system font's
cmap table. Mirrors libemf2svg's fontindex_to_utf8 which uses
fontconfig + freetype. We use fc-match to find the font file
and fontisan to parse the cmap.
The reverse cmap is cached per (font_family, weight, italic) triple since parsing the cmap is expensive and the same font is typically referenced many times.
Constant Summary collapse
- ETO_GLYPH_INDEX =
per MS-WMF ExtTextOutOptions
0x0010- HEBREW_CHARSET =
Hebrew/Arabic charsets that need RTL reversal after mapping.
177- ARABIC_CHARSET =
178
Instance Method Summary collapse
-
#initialize ⇒ GlyphIndexMapper
constructor
A new instance of GlyphIndexMapper.
-
#map(glyph_ids, font_family:, weight:, italic:, charset:) ⇒ Object
Map an array of glyph indices to a UTF-8 string using the font's reverse cmap.
Constructor Details
#initialize ⇒ GlyphIndexMapper
Returns a new instance of GlyphIndexMapper.
21 22 23 |
# File 'lib/emfsvg/glyph_index_mapper.rb', line 21 def initialize @cache = {} end |
Instance Method Details
#map(glyph_ids, font_family:, weight:, italic:, charset:) ⇒ Object
Map an array of glyph indices to a UTF-8 string using the font's reverse cmap. Mirrors libemf2svg's fontindex_to_utf8
- text_convert:
- Build UTF-8 string with null chars (U+0000) for unmapped glyphs.
- If charset is Hebrew/Arabic, reverse the string (Ruby's String#reverse correctly handles multibyte UTF-8 chars).
- Truncate at the first null char — matches fprintf %s behavior.
This means: for RTL languages, if ANY glyph is unmapped, the reversed string may start with null → empty output.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/emfsvg/glyph_index_mapper.rb', line 36 def map(glyph_ids, font_family:, weight:, italic:, charset:) reverse_map = build_reverse_map(font_family, weight, italic) return nil unless reverse_map codepoints = glyph_ids.map { |gid| reverse_map[gid] || 0 } utf8 = codepoints.pack("U*") if charset == HEBREW_CHARSET || charset == ARABIC_CHARSET utf8 = utf8.reverse end null_pos = utf8.index("\x00") utf8 = utf8[0, null_pos] if null_pos utf8 end |