Skip to content
1 change: 1 addition & 0 deletions doc/changes/dev/13778.newfeature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added a ``font_file`` parameter to :meth:`mne.viz.Brain.add_text` to allow custom ``.ttf``/``.ttc`` fonts for improved Unicode glyph rendering, by `Pragnya Khandelwal`_.
Comment thread
drammock marked this conversation as resolved.
Outdated
5 changes: 5 additions & 0 deletions mne/viz/_brain/_brain.py
Original file line number Diff line number Diff line change
Expand Up @@ -2796,6 +2796,7 @@ def add_text(
col=0,
font_size=None,
justification=None,
font_file=None,
):
"""Add a text to the visualization.

Expand Down Expand Up @@ -2824,6 +2825,9 @@ def add_text(
The font size to use.
justification : str | None
The text justification.
font_file : path-like | None
Path to a ``.ttf`` or ``.ttc`` font file to use for rendering
the text. This can be helpful for Unicode glyph coverage.
Comment thread
PragnyaKhandelwal marked this conversation as resolved.
Outdated
"""
_validate_type(name, (str, None), "name")
name = text if name is None else name
Expand All @@ -2840,6 +2844,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()
Expand Down
2 changes: 1 addition & 1 deletion mne/viz/_brain/tests/test_brain.py
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ def __init__(self):
with pytest.raises(ValueError, match="already exists"):
brain.add_text(x=0, y=0, text="foo")
brain.remove_text("foo")
brain.add_text(x=0, y=0, text="foo")
brain.add_text(x=0, y=0, text="foo", font_file=None)
Comment thread
PragnyaKhandelwal marked this conversation as resolved.
Outdated
brain.remove_text()

brain.close()
Expand Down
15 changes: 14 additions & 1 deletion mne/viz/backends/_abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,16 @@ def quiver3d(
pass

@abstractclassmethod
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
Expand All @@ -493,6 +502,10 @@ 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.
Comment thread
PragnyaKhandelwal marked this conversation as resolved.
Outdated
font_file : path-like | None
Path to a ``.ttf`` or ``.ttc`` font file for rendering text.
Comment thread
PragnyaKhandelwal marked this conversation as resolved.
Outdated
"""
pass

Expand Down
19 changes: 16 additions & 3 deletions mne/viz/backends/_pyvista.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,13 +720,26 @@ 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
kwargs = dict(
text=text,
position=position,
font_size=size,
color=color,
viewport=True,
font_file=font_file,
)
actor = self.plotter.add_text(**kwargs)
if isinstance(justification, str):
if justification == "left":
actor.GetTextProperty().SetJustificationToLeft()
Expand Down
31 changes: 31 additions & 0 deletions mne/viz/backends/tests/test_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ def test_3d_backend(renderer):
text=txt_text,
size=txt_size,
justification="right",
font_file=None,
Comment thread
PragnyaKhandelwal marked this conversation as resolved.
Outdated
)
rend.text3d(x=0, y=0, z=0, text=txt_text, scale=1.0)
rend.set_camera(
Expand All @@ -175,6 +176,36 @@ def test_3d_backend(renderer):
rend.show()


def test_text2d_font_file_passthrough(renderer, monkeypatch):
Comment thread
PragnyaKhandelwal marked this conversation as resolved.
Outdated
"""Test that text2d forwards font_file values to the backend."""
rend = renderer.create_3d_figure(
size=(300, 300),
bgcolor="black",
smooth_shading=True,
scene=False,
)
seen = []

class _DummyActor:
def GetTextProperty(self):
return None

def SetVisibility(self, value):
return None

def _add_text(**kwargs):
seen.append(kwargs)
return _DummyActor()

monkeypatch.setattr(rend.plotter, "add_text", _add_text)
rend.text2d(x_window=0.0, y_window=0.0, text="label", font_file="dummy.ttf")
rend.text2d(x_window=0.0, y_window=0.0, text="label", font_file=None)

assert seen[0]["font_file"] == "dummy.ttf"
assert "font_file" in seen[1]
assert seen[1]["font_file"] is None


def test_get_3d_backend(renderer):
"""Test get_3d_backend function call for side-effects."""
# Test twice to ensure the first call had no side-effect
Expand Down
Loading