Skip to content

Commit 23fb857

Browse files
committed
Replace TEXT_MOB_SCALE_FACTOR with a dynamically calculated value
- Set font_size_for_unit_height: 144 in config - Calculate the relevant scaling factors for Text and Text using a rendered "0" as a reference, ensuring that a font size of 144 (or whatever is set) would give it a height of 1 in manim coordinates.
1 parent 901cc7c commit 23fb857

File tree

5 files changed

+48
-8
lines changed

5 files changed

+48
-8
lines changed

manimlib/default_config.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,14 @@ mobject:
8282
tex:
8383
# See tex_templates.yml
8484
template: "default"
85+
# The font size at which Tex("0") has a height of 1 manim unit
86+
font_size_for_unit_height: 144
8587
text:
8688
# font: "Cambria Math"
8789
font: "Consolas"
8890
alignment: "LEFT"
91+
# The font size at which Text("0") has a height of 1 manim unit
92+
font_size_for_unit_height: 144
8993
embed:
9094
exception_mode: "Verbose"
9195
autoreload: False

manimlib/mobject/svg/old_tex_mobject.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from manimlib.constants import BLACK, DEFAULT_MOBJECT_COLOR
88
from manimlib.mobject.svg.svg_mobject import SVGMobject
9+
from manimlib.mobject.svg.tex_mobject import get_tex_mob_scale_factor
910
from manimlib.mobject.types.vectorized_mobject import VGroup
1011
from manimlib.utils.tex_file_writing import latex_to_svg
1112

@@ -16,9 +17,6 @@
1617
from manimlib.typing import ManimColor
1718

1819

19-
SCALE_FACTOR_PER_FONT_POINT = 0.001
20-
21-
2220
class SingleStringTex(SVGMobject):
2321
height: float | None = None
2422

@@ -59,7 +57,7 @@ def __init__(
5957
)
6058

6159
if self.height is None:
62-
self.scale(SCALE_FACTOR_PER_FONT_POINT * self.font_size)
60+
self.scale(get_tex_mob_scale_factor() * self.font_size)
6361
if self.organize_left_to_right:
6462
self.organize_submobjects_left_to_right()
6563

manimlib/mobject/svg/svg_mobject.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,21 @@
3131
PATH_TO_POINTS: dict[str, Vect3Array] = {}
3232

3333

34+
def get_svg_content_height(svg_string: str) -> float:
35+
# Strip root attributes to match SVGMobject.modify_xml_tree,
36+
# which avoids viewBox unit conversions (e.g. pt to px for dvisvgm)
37+
root = ET.fromstring(svg_string)
38+
root.attrib.clear()
39+
data_stream = io.BytesIO()
40+
ET.ElementTree(root).write(data_stream)
41+
data_stream.seek(0)
42+
svg = se.SVG.parse(data_stream)
43+
bbox = svg.bbox()
44+
if bbox is None:
45+
raise ValueError("SVG has no content to measure")
46+
return bbox[3] - bbox[1]
47+
48+
3449
def _convert_point_to_3d(x: float, y: float) -> np.ndarray:
3550
return np.array([x, y, 0.0])
3651

manimlib/mobject/svg/tex_mobject.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
import re
44
from pathlib import Path
55

6+
from functools import lru_cache
7+
8+
from manimlib.config import manim_config
69
from manimlib.mobject.svg.string_mobject import StringMobject
10+
from manimlib.mobject.svg.svg_mobject import get_svg_content_height
711
from manimlib.mobject.types.vectorized_mobject import VGroup
812
from manimlib.mobject.types.vectorized_mobject import VMobject
913
from manimlib.utils.color import color_to_hex
@@ -18,7 +22,14 @@
1822
from manimlib.typing import ManimColor, Span, Selector, Self
1923

2024

21-
TEX_MOB_SCALE_FACTOR = 0.001
25+
@lru_cache(maxsize=1)
26+
def get_tex_mob_scale_factor() -> float:
27+
# Render a reference "0" and calibrate so that font_size_for_unit_height
28+
# gives a height of 1 manim unit. Compensates for platform dvisvgm differences.
29+
font_size_for_unit_height = manim_config.tex.font_size_for_unit_height
30+
svg_string = latex_to_svg("0", show_message_during_execution=False)
31+
svg_height = get_svg_content_height(svg_string)
32+
return 1.0 / (font_size_for_unit_height * svg_height)
2233

2334

2435
class Tex(StringMobject):
@@ -63,7 +74,7 @@ def __init__(
6374
)
6475

6576
self.set_color_by_tex_to_color_map(self.tex_to_color_map)
66-
self.scale(TEX_MOB_SCALE_FACTOR * font_size)
77+
self.scale(get_tex_mob_scale_factor() * font_size)
6778

6879
self.font_size = font_size # Important for this to go after the scale call
6980

manimlib/mobject/svg/text_mobject.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from manimlib.constants import NORMAL
1818
from manimlib.logger import log
1919
from manimlib.mobject.svg.string_mobject import StringMobject
20+
from manimlib.mobject.svg.svg_mobject import get_svg_content_height
2021
from manimlib.utils.cache import cache_on_disk
2122
from manimlib.utils.color import color_to_hex
2223
from manimlib.utils.color import int_to_hex
@@ -31,7 +32,6 @@
3132
from manimlib.typing import ManimColor, Span, Selector
3233

3334

34-
TEXT_MOB_SCALE_FACTOR = 0.0076
3535
DEFAULT_LINE_SPACING_SCALE = 0.6
3636
# Ensure the canvas is large enough to hold all glyphs.
3737
DEFAULT_CANVAS_WIDTH = 16384
@@ -100,6 +100,18 @@ def markup_to_svg(
100100
return result
101101

102102

103+
@lru_cache(maxsize=1)
104+
def get_text_mob_scale_factor() -> float:
105+
# Render a reference "0" and calibrate so that font_size_for_unit_height
106+
# gives a height of 1 manim unit. Compensates for platform DPI differences.
107+
ref_size = 48
108+
font_size_for_unit_height = manim_config.text.font_size_for_unit_height
109+
pango_size = str(round(ref_size * 1024))
110+
svg_string = markup_to_svg(f'<span font_size="{pango_size}">0</span>')
111+
svg_height = get_svg_content_height(svg_string)
112+
return ref_size / (font_size_for_unit_height * svg_height)
113+
114+
103115
class MarkupText(StringMobject):
104116
# See https://docs.gtk.org/Pango/pango_markup.html
105117
MARKUP_TAGS = {
@@ -188,7 +200,7 @@ def __init__(
188200
if self.t2c:
189201
self.set_color_by_text_to_color_map(self.t2c)
190202
if height is None:
191-
self.scale(TEXT_MOB_SCALE_FACTOR)
203+
self.scale(get_text_mob_scale_factor())
192204

193205
def get_svg_string_by_content(self, content: str) -> str:
194206
self.content = content

0 commit comments

Comments
 (0)