@@ -223,7 +223,7 @@ def _get_info(self, fontname, font_class, sym, fontsize, dpi, math=True):
223
223
if bunch is not None :
224
224
return bunch
225
225
226
- font ,num ,slanted = self ._get_glyph (
226
+ font ,num ,slanted , substituted_glyph = self ._get_glyph (
227
227
fontname ,font_class ,sym ,fontsize ,math )
228
228
229
229
font .set_size (fontsize ,dpi )
@@ -242,7 +242,8 @@ def _get_info(self, fontname, font_class, sym, fontsize, dpi, math=True):
242
242
ymax = ymax + offset ,
243
243
# iceberg is the equivalent of TeX's "height"
244
244
iceberg = glyph .horiBearingY / 64.0 + offset ,
245
- slanted = slanted
245
+ slanted = slanted ,
246
+ substituted_glyph = substituted_glyph
246
247
)
247
248
248
249
result = self .glyphd [key ]= types .SimpleNamespace (
@@ -326,7 +327,7 @@ def _get_glyph(self, fontname, font_class, sym, fontsize, math=True):
326
327
if font is not None :
327
328
num = ord (sym )
328
329
if font is not None and font .get_char_index (num )!= 0 :
329
- return font ,num ,slanted
330
+ return font ,num ,slanted , False
330
331
else :
331
332
return self ._stix_fallback ._get_glyph (
332
333
fontname ,font_class ,sym ,fontsize ,math )
@@ -451,6 +452,8 @@ def _get_glyph(self, fontname, font_class, sym, fontsize, math=True):
451
452
found_symbol = False
452
453
_log .warning ("No TeX to Unicode mapping for {!a}." .format (sym ))
453
454
455
+ substituted_glyph = False
456
+
454
457
fontname ,uniindex = self ._map_virtual_font (
455
458
fontname ,font_class ,uniindex )
456
459
@@ -502,8 +505,9 @@ def _get_glyph(self, fontname, font_class, sym, fontsize, math=True):
502
505
font = self ._get_font ('rm' )
503
506
uniindex = 0xA4 # currency char, for lack of anything better
504
507
slanted = False
508
+ substituted_glyph = True
505
509
506
- return font ,uniindex ,slanted
510
+ return font ,uniindex ,slanted , substituted_glyph
507
511
508
512
def get_sized_alternatives_for_symbol (self ,fontname ,sym ):
509
513
if self ._fallback_font :
@@ -943,6 +947,9 @@ def _update_metrics(self):
943
947
def is_slanted (self ):
944
948
return self ._metrics .slanted
945
949
950
+ def is_substituted (self ):
951
+ return self ._metrics .substituted_glyph
952
+
946
953
def get_kerning (self ,next ):
947
954
"""
948
955
Return the amount of kerning between this and the given character.
@@ -2011,7 +2018,7 @@ def unknown_symbol(self, s, loc, toks):
2011
2018
raise ParseFatalException (s ,loc ,f"Unknown symbol:{ toks ['name' ]} " )
2012
2019
2013
2020
_accent_map = {
2014
- r'hat' :r'\circumflexaccent ' ,
2021
+ r'hat' :r'\combiningcircumflexaccent ' ,
2015
2022
r'breve' :r'\combiningbreve' ,
2016
2023
r'bar' :r'\combiningoverline' ,
2017
2024
r'grave' :r'\combininggraveaccent' ,
@@ -2027,10 +2034,13 @@ def unknown_symbol(self, s, loc, toks):
2027
2034
r"'" :r'\combiningacuteaccent' ,
2028
2035
r'~' :r'\combiningtilde' ,
2029
2036
r'.' :r'\combiningdotabove' ,
2030
- r'^' :r'\circumflexaccent' ,
2031
- r'overrightarrow' :r'\rightarrow' ,
2032
- r'overleftarrow' :r'\leftarrow' ,
2033
- r'mathring' :r'\circ' ,
2037
+ r'^' :r'\combiningcircumflexaccent' ,
2038
+ r'overrightarrow' :r'\combiningrightarrowabove' ,
2039
+ r'overleftarrow' :r'\combiningleftarrowabove' ,
2040
+ r'mathring' :r'\combiningringabove' ,
2041
+ r'=' :r'\combiningoverline' ,
2042
+ r'H' :r'\combiningdoubleacuteaccent' ,
2043
+ r'check' :r'\combiningcaron' ,
2034
2044
}
2035
2045
2036
2046
_wide_accents = set (r"widehat widetilde widebar" .split ())
@@ -2050,10 +2060,20 @@ def accent(self, s, loc, toks):
2050
2060
accent_box = AutoWidthChar (
2051
2061
'\\ ' + accent ,sym .width ,state ,char_class = Accent )
2052
2062
else :
2063
+ # Check if accent and character can be combined
2064
+ a = get_unicode_index (self ._accent_map [accent ])
2065
+ if isinstance (sym ,Char ):
2066
+ c = sym .c
2067
+ else :
2068
+ c = sym .children [0 ].c
2069
+ comb = unicodedata .normalize ('NFC' ,c + chr (a ))
2070
+ if len (comb )== 1 :# Check that they did combine
2071
+ c = Char (comb ,state )
2072
+ # Check that glyph exists
2073
+ if not c .is_substituted ():
2074
+ return c
2075
+ # Cannot be combined
2053
2076
accent_box = Accent (self ._accent_map [accent ],state )
2054
- if accent == 'mathring' :
2055
- accent_box .shrink ()
2056
- accent_box .shrink ()
2057
2077
centered = HCentered ([Hbox (sym .width / 4.0 ),accent_box ])
2058
2078
centered .hpack (sym .width ,'exactly' )
2059
2079
return Vlist ([
@@ -2137,9 +2157,6 @@ def is_slanted(self, nucleus):
2137
2157
return nucleus .is_slanted ()
2138
2158
return False
2139
2159
2140
- def is_between_brackets (self ,s ,loc ):
2141
- return False
2142
-
2143
2160
def subsuper (self ,s ,loc ,toks ):
2144
2161
nucleus = toks .get ("nucleus" ,Hbox (0 ))
2145
2162
subsuper = toks .get ("subsuper" , [])