@@ -58,7 +58,7 @@ def construct(self):
5858import hashlib
5959import re
6060from collections .abc import Iterable , Iterator , Sequence
61- from contextlib import contextmanager
61+ from contextlib import contextmanager , suppress
6262from itertools import chain
6363from pathlib import Path
6464from typing import TYPE_CHECKING , Any
@@ -368,7 +368,21 @@ def construct(self):
368368 t2c={'[:1]': '#3174f0', '[1:2]': '#e53125',
369369 '[2:3]': '#fbb003', '[3:4]': '#3174f0',
370370 '[4:5]': '#269a43', '[5:]': '#e53125'}, font_size=58).scale(3)
371- self.add(text1)
371+ self.add(text1)
372+
373+ OpenType features example:
374+
375+ .. manim:: TextNumericFeatures
376+ :save_last_frame:
377+
378+ class TextNumericFeatures(Scene):
379+ def construct(self):
380+ t = Text(
381+ '123,456.78',
382+ font='Inter',
383+ font_features='tnum=1,lnum=1',
384+ ).scale(2)
385+ self.add(t)
372386
373387 As :class:`Text` uses Pango to render text, rendering non-English
374388 characters is easily possible:
@@ -444,6 +458,8 @@ def __init__(
444458 should_center : bool = True ,
445459 disable_ligatures : bool = False ,
446460 use_svg_cache : bool = False ,
461+ font_features : str | None = None ,
462+ font_variant : str | None = None ,
447463 ** kwargs : Any ,
448464 ):
449465 self .line_spacing = line_spacing
@@ -470,6 +486,8 @@ def __init__(
470486 self .weight = weight
471487 self .gradient = gradient
472488 self .tab_width = tab_width
489+ self .font_features = font_features
490+ self .font_variant = font_variant
473491 if t2c is None :
474492 t2c = {}
475493 if t2f is None :
@@ -657,6 +675,8 @@ def _text2hash(self, color: ParsableManimColor) -> str:
657675 settings += str (self .line_spacing ) + str (self ._font_size )
658676 settings += str (self .disable_ligatures )
659677 settings += str (self .gradient )
678+ settings += str (self .font_features )
679+ settings += str (self .font_variant )
660680 id_str = self .text + settings
661681 hasher = hashlib .sha256 ()
662682 hasher .update (id_str .encode ())
@@ -791,6 +811,16 @@ def _text2settings(self, color: ParsableManimColor) -> list[TextSetting]:
791811 if setting .line_num == - 1 :
792812 setting .line_num = line_num
793813
814+ # Attach OpenType font features (if provided) so manimpango can utilize them
815+ if self .font_features :
816+ for setting in settings :
817+ with suppress (Exception ):
818+ setting .font_features = self .font_features
819+ if self .font_variant :
820+ for setting in settings :
821+ with suppress (Exception ):
822+ setting .font_variant = self .font_variant
823+
794824 return settings
795825
796826 def _text2svg (self , color : ParsableManimColor ) -> str :
@@ -966,6 +996,13 @@ def construct(self):
966996 Global weight setting, e.g. `NORMAL` or `BOLD`. Local overrides are possible.
967997 gradient
968998 Global gradient setting. Local overrides are possible.
999+ font_features
1000+ OpenType feature string to request on the font (e.g., "tnum=1,lnum=1" for
1001+ tabular + lining figures, or "onum=1" for old-style figures). Applied when
1002+ supported by ManimPango; otherwise ignored.
1003+ font_variant
1004+ Optional font variant name provided by the typeface (e.g., "condensed").
1005+ Applied when supported by ManimPango; otherwise ignored.
9691006 warn_missing_font
9701007 If True (default), Manim will issue a warning if the font does not exist in the
9711008 (case-sensitive) list of fonts returned from `manimpango.list_fonts()`.
0 commit comments