diff --git a/doc/changes/dev/13778.newfeature.rst b/doc/changes/dev/13778.newfeature.rst new file mode 100644 index 00000000000..ad9dbafe8ac --- /dev/null +++ b/doc/changes/dev/13778.newfeature.rst @@ -0,0 +1 @@ +Added a ``font_file`` parameter to :meth:`mne.viz.Brain.add_text` to support rendering glyphs not available in the default font, by `Pragnya Khandelwal`_. \ No newline at end of file diff --git a/mne/viz/_brain/_brain.py b/mne/viz/_brain/_brain.py index 226cf158682..ad7c7a40995 100644 --- a/mne/viz/_brain/_brain.py +++ b/mne/viz/_brain/_brain.py @@ -2796,6 +2796,7 @@ def add_text( col=0, font_size=None, justification=None, + font_file=None, ): """Add a text to the visualization. @@ -2824,6 +2825,10 @@ def add_text( The font size to use. justification : str | None The text justification. + font_file : str | None + Path to an absolute path of a font file to use for rendering + the text. See https://freetype.org/freetype2/docs/index.html for a list of + supported font file formats. """ _validate_type(name, (str, None), "name") name = text if name is None else name @@ -2840,6 +2845,7 @@ def add_text( color=color, size=font_size, justification=justification, + font_file=font_file, ) if "text" not in self._actors: self._actors["text"] = dict() diff --git a/mne/viz/backends/_abstract.py b/mne/viz/backends/_abstract.py index a5b605fc137..7c9d97167aa 100644 --- a/mne/viz/backends/_abstract.py +++ b/mne/viz/backends/_abstract.py @@ -487,7 +487,16 @@ def quiver3d( @classmethod @abstractmethod - def text2d(self, x_window, y_window, text, size=14, color="white"): + def text2d( + self, + x_window, + y_window, + text, + size=14, + color="white", + justification=None, + font_file=None, + ): """Add 2d text in the scene. Parameters @@ -506,6 +515,13 @@ def text2d(self, x_window, y_window, text, size=14, color="white"): The color of the text as a tuple (red, green, blue) of float values between 0 and 1 or a valid color name (i.e. 'white' or 'w'). + justification : str | None + The text justification. Can be 'left', 'center', or 'right'. + font_file : str | None + Path to an absolute path of a font file to use for rendering + the text. FreeType is used for loading, supporting many font + formats beyond ``.ttf`` and ``.ttc``. This can be helpful for + non-ASCII glyph coverage. """ pass diff --git a/mne/viz/backends/_pyvista.py b/mne/viz/backends/_pyvista.py index 500319467fd..b24084e60f5 100644 --- a/mne/viz/backends/_pyvista.py +++ b/mne/viz/backends/_pyvista.py @@ -720,12 +720,24 @@ def quiver3d( return actor, mesh def text2d( - self, x_window, y_window, text, size=14, color="white", justification=None + self, + x_window, + y_window, + text, + size=14, + color="white", + justification=None, + font_file=None, ): size = 14 if size is None else size position = (x_window, y_window) actor = self.plotter.add_text( - text, position=position, font_size=size, color=color, viewport=True + text=text, + position=position, + font_size=size, + color=color, + viewport=True, + font_file=font_file, ) if isinstance(justification, str): if justification == "left": diff --git a/mne/viz/backends/tests/test_renderer.py b/mne/viz/backends/tests/test_renderer.py index 09833c6d503..399aced2cfd 100644 --- a/mne/viz/backends/tests/test_renderer.py +++ b/mne/viz/backends/tests/test_renderer.py @@ -8,6 +8,7 @@ import numpy as np import pytest +from matplotlib.font_manager import findfont from mne.utils import run_subprocess from mne.viz import Figure3D, get_3d_backend, set_3d_backend @@ -168,6 +169,14 @@ def test_3d_backend(renderer): size=txt_size, justification="right", ) + # test font_file passthrough with a real font from matplotlib + font_path = findfont("serif") + rend.text2d( + x_window=txt_x + 0.1, + y_window=txt_y + 0.1, + text="font test", + font_file=font_path, + ) rend.text3d(x=0, y=0, z=0, text=txt_text, scale=1.0) rend.set_camera( azimuth=180.0, elevation=90.0, distance=cam_distance, focalpoint=center