Rework mapping of dvi glyph indices to freetype indices. · matplotlib/matplotlib@7a760d1 · GitHub
Skip to content

Commit 7a760d1

Browse files
committed
Rework mapping of dvi glyph indices to freetype indices.
In 89a7e19, an API for converting "dvi glyph indices" (as stored in a dvi file) to FreeType-compatible keys (either "indices into the native charmap" or "glyph names") was introduced. It was intended that end users (i.e., backends) would check the type of `text.glyph_name_or_index` ((A) int or (B) str) and load the glyph accordingly ((A) `FT_Set_Charmap(native_cmap); FT_Load_Char(index);` or (B) `FT_Load_Glyph(FT_Get_Name_Index(name));`); however, with the future introduction of {xe,lua}tex support, this kind of type checking becomes inconvenient, because {xe,lua}tex's "dvi glyph indices", which are directly equal to FreeType glyph indices (i.e. they would be loaded with `FT_Load_Glyph(index);`), would normally also be converted to ints. This PR introduces a new API (`_index_dvi_to_freetype`) to perform this mapping, always mapping to FreeType glyph indices (i.e. one can always just call `FT_Load_Glyph` on the result). To do so, in case (A) it loads itself the native charmap (something the end user needed to do by themselves previously) and performs the cmap-to-index conversion (`FT_Get_Char_Index`) previously implicit in `FT_Load_Char`; in case (B) it performs itself the name-to-index conversion (`FT_Get_Name_Index`). When {xe,lua}tex support is introduced in the future, `_index_dvi_to_freetype` will just return the index as is. Note that this API is intentionally kept private for now (even though it is used by textpath) and the old APIs are not deprecated yet; I intend to wait until {xe,lua}tex support is actually merged to do so, to avoid possible future back-and-forth changes on the public APIs. In case (A), this PR also improves on the detection of the native charmap, which was previously detected via heuristics (`_select_native_charmap`), but is now read by directly accessing the Type 1 font "encoding vector".
1 parent 7d5d027 commit 7a760d1

3 files changed

Lines changed: 65 additions & 39 deletions

File tree

lib/matplotlib/dviread.py

Lines changed: 35 additions & 11 deletions

lib/matplotlib/textpath.py

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -238,17 +238,8 @@ def get_glyphs_tex(self, prop, s, glyph_map=None,
238238
if char_id not in glyph_map:
239239
font.clear()
240240
font.set_size(self.FONT_SCALE, self.DPI)
241-
glyph_name_or_index = text.glyph_name_or_index
242-
if isinstance(glyph_name_or_index, str):
243-
index = font.get_name_index(glyph_name_or_index)
244-
font.load_glyph(index, flags=LoadFlags.TARGET_LIGHT)
245-
elif isinstance(glyph_name_or_index, int):
246-
self._select_native_charmap(font)
247-
font.load_char(
248-
glyph_name_or_index, flags=LoadFlags.TARGET_LIGHT)
249-
else: # Should not occur.
250-
raise TypeError(f"Glyph spec of unexpected type: "
251-
f"{glyph_name_or_index!r}")
241+
idx = text.font._index_dvi_to_freetype(text.glyph)
242+
font.load_glyph(idx, flags=LoadFlags.TARGET_LIGHT)
252243
glyph_map_new[char_id] = font.get_path()
253244

254245
glyph_ids.append(char_id)
@@ -269,23 +260,6 @@ def get_glyphs_tex(self, prop, s, glyph_map=None,
269260
return (list(zip(glyph_ids, xpositions, ypositions, sizes)),
270261
glyph_map_new, myrects)
271262

272-
@staticmethod
273-
def _select_native_charmap(font):
274-
# Select the native charmap. (we can't directly identify it but it's
275-
# typically an Adobe charmap).
276-
for charmap_code in [
277-
1094992451, # ADOBE_CUSTOM.
278-
1094995778, # ADOBE_STANDARD.
279-
]:
280-
try:
281-
font.select_charmap(charmap_code)
282-
except (ValueError, RuntimeError):
283-
pass
284-
else:
285-
break
286-
else:
287-
_log.warning("No supported encoding in font (%s).", font.fname)
288-
289263

290264
text_to_path = TextToPath()
291265

src/ft2font_wrapper.cpp

Lines changed: 28 additions & 0 deletions

0 commit comments

Comments
 (0)