@@ -126,9 +126,10 @@ class CharacterTracker:
126
126
If *subset_size* is not set, then there will only be one subset per font
127
127
filename.
128
128
glyph_map : dict
129
- A dictionary of font files to glyph maps. The glyph map is from (character code,
130
- glyph index)-pairs to (subset index, subset character code)-pairs. You probably
131
- will want to use the `.subset_to_unicode` method instead of this attribute.
129
+ A dictionary of font files to glyph maps. The glyph map is from (character
130
+ code(s), glyph index)-pairs to (subset index, subset character code)-pairs. You
131
+ probably will want to use the `.subset_to_unicode` method instead of this
132
+ attribute.
132
133
"""
133
134
134
135
def __init__ (self , subset_size : int = 0 ):
@@ -141,7 +142,7 @@ def __init__(self, subset_size: int = 0):
141
142
"""
142
143
self .used : dict [str , list [dict [CharacterCodeType , GlyphIndexType ]]] = {}
143
144
self .glyph_map : dict [str ,
144
- dict [tuple [CharacterCodeType , GlyphIndexType ],
145
+ dict [tuple [tuple [ CharacterCodeType , ...] , GlyphIndexType ],
145
146
tuple [int , CharacterCodeType ]]] = {}
146
147
self .subset_size = subset_size
147
148
@@ -170,18 +171,18 @@ def track(self, font: FT2Font, s: str) -> list[tuple[int, CharacterCodeType]]:
170
171
for _c , _f in font ._get_fontmap (s ).items ()
171
172
]
172
173
173
- def track_glyph (
174
- self , font : FT2Font , charcode : CharacterCodeType ,
175
- glyph : GlyphIndexType ) -> tuple [int , CharacterCodeType ]:
174
+ def track_glyph (self , font : FT2Font , chars : str | CharacterCodeType ,
175
+ glyph : GlyphIndexType ) -> tuple [int , CharacterCodeType ]:
176
176
"""
177
177
Record character code *charcode* at glyph index *glyph* as using font *font*.
178
178
179
179
Parameters
180
180
----------
181
181
font : FT2Font
182
182
A font that is being used for the provided string.
183
- charcode : CharacterCodeType
184
- The character code to record.
183
+ chars : str or CharacterCodeType
184
+ The character(s) to record. This may be a single character code, or multiple
185
+ characters in a string, if the glyph maps to several characters.
185
186
glyph : GlyphIndexType
186
187
The corresponding glyph index to record.
187
188
@@ -194,25 +195,38 @@ def track_glyph(
194
195
The character code within the above subset. If *subset_size* was not
195
196
specified on this instance, then this is just *charcode* unmodified.
196
197
"""
198
+ # Normalize for the key.
199
+ if isinstance (chars , str ):
200
+ charcode = tuple (ord (c ) for c in chars )
201
+ elif not isinstance (chars , tuple ):
202
+ charcode = (chars , )
203
+ else :
204
+ charcode = chars
205
+
197
206
glyph_map = self .glyph_map .setdefault (font .fname , {})
198
207
key = (charcode , glyph )
199
208
if key in glyph_map :
200
209
return glyph_map [key ]
201
210
202
211
subset_maps = self .used .setdefault (font .fname , [{}])
203
- # Default to preserving the character code as it was.
204
- subset = 0
205
- subset_charcode = charcode
206
212
use_next_charmap = False
207
- if self .subset_size != 0 :
208
- # But start filling a new subset if outside the first block; this preserves
209
- # ASCII (for Type 3) or the Basic Multilingual Plane (for Type 42).
210
- if charcode >= self .subset_size :
211
- use_next_charmap = True
212
- # Or, use a new subset if the character code is already mapped for the first
213
- # block. This means it's using an alternate glyph.
214
- elif charcode in subset_maps [0 ]:
215
- use_next_charmap = True
213
+ if len (charcode ) > 1 :
214
+ # Multi-character glyphs always go in the non-0 subset.
215
+ use_next_charmap = True
216
+ else :
217
+ # Default to preserving the character code as it was.
218
+ subset = 0
219
+ subset_charcode = charcode [0 ]
220
+ if self .subset_size != 0 :
221
+ # But start filling a new subset if outside the first block; this
222
+ # preserves ASCII (for Type 3) or the Basic Multilingual Plane
223
+ # (for Type 42).
224
+ if charcode [0 ] >= self .subset_size :
225
+ use_next_charmap = True
226
+ # Or, use a new subset if the character code is already mapped for the
227
+ # first block. This means it's using an alternate glyph.
228
+ elif charcode [0 ] in subset_maps [0 ]:
229
+ use_next_charmap = True
216
230
if use_next_charmap :
217
231
if len (subset_maps ) == 1 or len (subset_maps [- 1 ]) == self .subset_size :
218
232
subset_maps .append ({})
@@ -223,7 +237,7 @@ def track_glyph(
223
237
return (subset , subset_charcode )
224
238
225
239
def subset_to_unicode (self , fontname : str , index : int ,
226
- charcode : CharacterCodeType ) -> CharacterCodeType :
240
+ charcode : CharacterCodeType ) -> tuple [ CharacterCodeType , ...] :
227
241
"""
228
242
Map a subset index and character code to a Unicode character code.
229
243
@@ -238,8 +252,8 @@ def subset_to_unicode(self, fontname: str, index: int,
238
252
239
253
Returns
240
254
-------
241
- CharacterCodeType
242
- The Unicode character code corresponding to the subsetted one.
255
+ tuple of CharacterCodeType
256
+ The Unicode character code(s) corresponding to the subsetted one.
243
257
"""
244
258
search = (index , charcode )
245
259
for orig_info , subset_info in self .glyph_map [fontname ].items ():
0 commit comments