@@ -176,6 +176,88 @@ def test_ft2font_clear():
176
176
assert font .get_bitmap_offset () == (0 , 0 )
177
177
178
178
179
+ def test_ft2font_charmaps ():
180
+ def enc (name ):
181
+ # We don't expose the encoding enum from FreeType, but can generate it here.
182
+ # For DejaVu, there are 5 charmaps, but only 2 have enum entries in FreeType.
183
+ e = 0
184
+ for x in name :
185
+ e <<= 8
186
+ e += ord (x )
187
+ return e
188
+
189
+ file = fm .findfont ('DejaVu Sans' )
190
+ font = ft2font .FT2Font (file )
191
+ assert font .num_charmaps == 5
192
+
193
+ # Unicode.
194
+ font .select_charmap (enc ('unic' ))
195
+ unic = font .get_charmap ()
196
+ font .set_charmap (0 ) # Unicode platform, Unicode BMP only.
197
+ after = font .get_charmap ()
198
+ assert len (after ) <= len (unic )
199
+ for chr , glyph in after .items ():
200
+ assert unic [chr ] == glyph == font .get_char_index (chr )
201
+ font .set_charmap (1 ) # Unicode platform, modern subtable.
202
+ after = font .get_charmap ()
203
+ assert unic == after
204
+ font .set_charmap (3 ) # Windows platform, Unicode BMP only.
205
+ after = font .get_charmap ()
206
+ assert len (after ) <= len (unic )
207
+ for chr , glyph in after .items ():
208
+ assert unic [chr ] == glyph == font .get_char_index (chr )
209
+ font .set_charmap (4 ) # Windows platform, Unicode full repertoire, modern subtable.
210
+ after = font .get_charmap ()
211
+ assert unic == after
212
+
213
+ # This is just a random sample from FontForge.
214
+ glyph_names = {
215
+ 'non-existent-glyph-name' : 0 ,
216
+ 'plusminus' : 115 ,
217
+ 'Racute' : 278 ,
218
+ 'perthousand' : 2834 ,
219
+ 'seveneighths' : 3057 ,
220
+ 'triagup' : 3721 ,
221
+ 'uni01D3' : 405 ,
222
+ 'uni0417' : 939 ,
223
+ 'uni2A02' : 4464 ,
224
+ 'u1D305' : 5410 ,
225
+ 'u1F0A1' : 5784 ,
226
+ }
227
+ for name , index in glyph_names .items ():
228
+ assert font .get_name_index (name ) == index
229
+ if name == 'non-existent-glyph-name' :
230
+ name = '.notdef'
231
+ # This doesn't always apply, but it does for DejaVu Sans.
232
+ assert font .get_glyph_name (index ) == name
233
+
234
+ # Apple Roman.
235
+ font .select_charmap (enc ('armn' ))
236
+ armn = font .get_charmap ()
237
+ font .set_charmap (2 ) # Macintosh platform, Roman.
238
+ after = font .get_charmap ()
239
+ assert armn == after
240
+ assert len (armn ) <= 256 # 8-bit encoding.
241
+ # The first 128 characters of Apple Roman match ASCII, which also matches Unicode.
242
+ for o in range (1 , 128 ):
243
+ if o not in armn or o not in unic :
244
+ continue
245
+ assert unic [o ] == armn [o ]
246
+ # Check a couple things outside the ASCII set that are different in each charset.
247
+ examples = [
248
+ # (Unicode, Macintosh)
249
+ (0x2020 , 0xA0 ), # Dagger.
250
+ (0x00B0 , 0xA1 ), # Degree symbol.
251
+ (0x00A3 , 0xA3 ), # Pound sign.
252
+ (0x00A7 , 0xA4 ), # Section sign.
253
+ (0x00B6 , 0xA6 ), # Pilcrow.
254
+ (0x221E , 0xB0 ), # Infinity symbol.
255
+ ]
256
+ for u , m in examples :
257
+ # Though the encoding is different, the glyph should be the same.
258
+ assert unic [u ] == armn [m ]
259
+
260
+
179
261
@pytest .mark .parametrize ('family_name, file_name' ,
180
262
[("WenQuanYi Zen Hei" , "wqy-zenhei.ttc" ),
181
263
("Noto Sans CJK JP" , "NotoSansCJK.ttc" ),
0 commit comments