@@ -536,7 +536,7 @@ def afmFontProperty(fontpath, font):
536536
537537def _cleanup_fontproperties_init (init_method ):
538538 """
539- A decorator to limit the call signature to single a positional argument
539+ A decorator to limit the call signature to a single positional argument
540540 or alternatively only keyword arguments.
541541
542542 We still accept but deprecate all other call signatures.
@@ -624,6 +624,13 @@ class FontProperties:
624624 Supported values are: 'dejavusans', 'dejavuserif', 'cm',
625625 'stix', 'stixsans' and 'custom'. Default: :rc:`mathtext.fontset`
626626
627+ - features: A list of advanced font feature tags to enable. Font features are a
628+ component of OpenType fonts that allows picking from multiple stylistic variations
629+ within a single font. This may include small caps, ligatures, alternate forms of
630+ commonly-confused glyphs (e.g., capital I vs. lower-case l), and various other
631+ options. A `list of feature tags may be found here
632+ <https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist>`__.
633+
627634 Alternatively, a font may be specified using the absolute path to a font
628635 file, by using the *fname* kwarg. However, in this case, it is typically
629636 simpler to just pass the path (as a `pathlib.Path`, not a `str`) to the
@@ -657,7 +664,8 @@ class FontProperties:
657664 def __init__ (self , family = None , style = None , variant = None , weight = None ,
658665 stretch = None , size = None ,
659666 fname = None , # if set, it's a hardcoded filename to use
660- math_fontfamily = None ):
667+ math_fontfamily = None ,
668+ features = None ):
661669 self .set_family (family )
662670 self .set_style (style )
663671 self .set_variant (variant )
@@ -666,6 +674,7 @@ def __init__(self, family=None, style=None, variant=None, weight=None,
666674 self .set_file (fname )
667675 self .set_size (size )
668676 self .set_math_fontfamily (math_fontfamily )
677+ self .set_features (features )
669678 # Treat family as a fontconfig pattern if it is the only parameter
670679 # provided. Even in that case, call the other setters first to set
671680 # attributes not specified by the pattern to the rcParams defaults.
@@ -705,7 +714,8 @@ def __hash__(self):
705714 self .get_stretch (),
706715 self .get_size (),
707716 self .get_file (),
708- self .get_math_fontfamily ())
717+ self .get_math_fontfamily (),
718+ self .get_features ())
709719 return hash (l )
710720
711721 def __eq__ (self , other ):
@@ -952,6 +962,41 @@ def set_math_fontfamily(self, fontfamily):
952962 _api .check_in_list (valid_fonts , math_fontfamily = fontfamily )
953963 self ._math_fontfamily = fontfamily
954964
965+ def get_features (self ):
966+ """Return a tuple of font feature tags to enable."""
967+ return self ._features
968+
969+ def set_features (self , features ):
970+ """
971+ Set the font feature tags to enable on this font.
972+
973+ Parameters
974+ ----------
975+ features : list[str]
976+ A list of feature tags to be used with the associated font. These strings
977+ are eventually passed to HarfBuzz, and so all `string formats supported by
978+ hb_feature_from_string()
979+ <https://harfbuzz.github.io/harfbuzz-hb-common.html#hb-feature-from-string>`__
980+ are supported.
981+
982+ For example, if your desired font includes Stylistic Sets which enable
983+ various typographic alternates including one that you do not wish to use
984+ (e.g., Contextual Ligatures), then you can pass the following to enable one
985+ and not the other::
986+
987+ fp.set_features([
988+ 'ss01', # Use Stylistic Set 1.
989+ '-clig', # But disable Contextural Ligatures.
990+ ])
991+
992+ Available font feature tags may be found at
993+ https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist
994+ """
995+ _api .check_isinstance ((list , tuple , None ), features = features )
996+ if features is not None :
997+ features = tuple (features )
998+ self ._features = features
999+
9551000 def copy (self ):
9561001 """Return a copy of self."""
9571002 return copy .copy (self )
0 commit comments