@@ -58,7 +58,7 @@ def construct(self):
58
58
import hashlib
59
59
import re
60
60
from collections .abc import Iterable , Iterator , Sequence
61
- from contextlib import contextmanager
61
+ from contextlib import contextmanager , suppress
62
62
from itertools import chain
63
63
from pathlib import Path
64
64
from typing import TYPE_CHECKING , Any
@@ -370,6 +370,18 @@ def construct(self):
370
370
'[4:5]': '#269a43', '[5:]': '#e53125'}, font_size=58).scale(3)
371
371
self.add(text1)
372
372
373
+ .. manim:: TextNumericFeatures
374
+ :save_last_frame:
375
+
376
+ class TextNumericFeatures(Scene):
377
+ def construct(self):
378
+ t = Text(
379
+ '123,456.78',
380
+ font='Inter',
381
+ font_features='tnum=1,lnum=1',
382
+ ).scale(2)
383
+ self.add(t)
384
+
373
385
As :class:`Text` uses Pango to render text, rendering non-English
374
386
characters is easily possible:
375
387
@@ -444,6 +456,8 @@ def __init__(
444
456
should_center : bool = True ,
445
457
disable_ligatures : bool = False ,
446
458
use_svg_cache : bool = False ,
459
+ font_features : str | None = None ,
460
+ font_variant : str | None = None ,
447
461
** kwargs : Any ,
448
462
):
449
463
self .line_spacing = line_spacing
@@ -470,6 +484,8 @@ def __init__(
470
484
self .weight = weight
471
485
self .gradient = gradient
472
486
self .tab_width = tab_width
487
+ self .font_features = font_features
488
+ self .font_variant = font_variant
473
489
if t2c is None :
474
490
t2c = {}
475
491
if t2f is None :
@@ -657,6 +673,8 @@ def _text2hash(self, color: ParsableManimColor) -> str:
657
673
settings += str (self .line_spacing ) + str (self ._font_size )
658
674
settings += str (self .disable_ligatures )
659
675
settings += str (self .gradient )
676
+ settings += str (self .font_features )
677
+ settings += str (self .font_variant )
660
678
id_str = self .text + settings
661
679
hasher = hashlib .sha256 ()
662
680
hasher .update (id_str .encode ())
@@ -791,6 +809,16 @@ def _text2settings(self, color: ParsableManimColor) -> list[TextSetting]:
791
809
if setting .line_num == - 1 :
792
810
setting .line_num = line_num
793
811
812
+ # Attach OpenType font features (if provided) so manimpango can utilize them
813
+ if self .font_features :
814
+ for setting in settings :
815
+ with suppress (Exception ):
816
+ setting .font_features = self .font_features
817
+ if self .font_variant :
818
+ for setting in settings :
819
+ with suppress (Exception ):
820
+ setting .font_variant = self .font_variant
821
+
794
822
return settings
795
823
796
824
def _text2svg (self , color : ParsableManimColor ) -> str :
@@ -966,6 +994,13 @@ def construct(self):
966
994
Global weight setting, e.g. `NORMAL` or `BOLD`. Local overrides are possible.
967
995
gradient
968
996
Global gradient setting. Local overrides are possible.
997
+ font_features
998
+ OpenType feature string to request on the font (e.g., "tnum=1,lnum=1" for
999
+ tabular + lining figures, or "onum=1" for old-style figures). Applied when
1000
+ supported by ManimPango; otherwise ignored.
1001
+ font_variant
1002
+ Optional font variant name provided by the typeface (e.g., "condensed").
1003
+ Applied when supported by ManimPango; otherwise ignored.
969
1004
warn_missing_font
970
1005
If True (default), Manim will issue a warning if the font does not exist in the
971
1006
(case-sensitive) list of fonts returned from `manimpango.list_fonts()`.
0 commit comments