@@ -176,6 +176,88 @@ def test_ft2font_clear():
176176 assert font .get_bitmap_offset () == (0 , 0 )
177177
178178
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+
179261@pytest .mark .parametrize ('family_name, file_name' ,
180262 [("WenQuanYi Zen Hei" , "wqy-zenhei.ttc" ),
181263 ("Noto Sans CJK JP" , "NotoSansCJK.ttc" ),
0 commit comments