@@ -732,6 +732,8 @@ class DejaVuSansFonts(DejaVuFonts):
732732 0 : 'DejaVu Sans' ,
733733 }
734734
735+ def _to_device_units (font_units , fontsize , units_per_EM , dpi ):
736+ return font_units / units_per_EM * fontsize / 72 * dpi
735737
736738class UnicodeMathFonts (TruetypeFonts ):
737739 """
@@ -760,6 +762,32 @@ def _get_font(self, font: str | int) -> FT2Font:
760762
761763 return super ()._get_font (font )
762764
765+ def get_xheight (self , fontname : str , fontsize : float , dpi : float ) -> float :
766+ font = self ._get_font ('mathfont' )
767+
768+ os2 = font .get_sfnt_table ('OS/2' )
769+ height_raw = os2 .get ('sxHeight' )
770+ if height_raw is not None :
771+ # use value of OS/2 table, if present
772+ x_height = _to_device_units (height_raw , fontsize , font .units_per_EM , dpi )
773+ else :
774+ # fall back to measure height of the x glyph
775+ num = get_unicode_index ('x' )
776+ font .set_size (fontsize , dpi )
777+ glyph_index = font .get_char_index (num )
778+ glyph = font .load_glyph (glyph_index , flags = self .load_glyph_flags )
779+ x_height = glyph .height / 64
780+
781+ return x_height
782+
783+ def get_underline_thickness (self , font : str , fontsize : float , dpi : float ) -> float :
784+ font = self ._get_font ('mathfont' )
785+ thickness_raw = font .underline_thickness
786+ # alternative: use font.get_sfnt_tables('OS/2').get('yStrikeoutSize')
787+ underline_thickness = _to_device_units (thickness_raw , fontsize , font .units_per_EM , dpi )
788+
789+ return underline_thickness
790+
763791 def _get_glyph (self , fontname : str , font_class : str ,
764792 sym : str ) -> tuple [FT2Font , CharacterCodeType , bool ]:
765793 # `fontname' is one of rm cal it tt sf bf bfit default bb frak scr regular
0 commit comments