Skip to content

Commit 110d89f

Browse files
authored
Use height to determine font_size instead of the _font_size attribute. (#1985)
* fix set_value and add some docs * improve font_size property for tex/text_mobject.py * add tests * add more font_size tests * round test_set_value_size) * scale based on self._font_size * add changing_font_size test * rewrite test and add test i forgot to add * improve hacky solution that didn't work * add change font_size test for tex_mobject.py * improve tests * split into separate test * remove component of old test * fix docs * simplify the setter
1 parent ab28d5b commit 110d89f

File tree

8 files changed

+142
-37
lines changed

8 files changed

+142
-37
lines changed

manim/mobject/numbers.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def __init__(
9999
@property
100100
def font_size(self):
101101
"""The font size of the tex mobject."""
102-
return self._font_size
102+
return self.height / self.initial_height * self._font_size
103103

104104
@font_size.setter
105105
def font_size(self, font_val):
@@ -111,8 +111,7 @@ def font_size(self, font_val):
111111

112112
# scale to a factor of the initial height so that setting
113113
# font_size does not depend on current size.
114-
self.scale(1 / 48 * font_val * self.initial_height / self.height)
115-
self._font_size = font_val
114+
self.scale(font_val / self.font_size)
116115

117116
def set_submobjects_from_number(self, number):
118117
self.number = number
@@ -146,12 +145,12 @@ def set_submobjects_from_number(self, number):
146145
if self.unit and self.unit.startswith("^"):
147146
self.unit_sign.align_to(self, UP)
148147

149-
if self.include_background_rectangle:
150-
self.add_background_rectangle()
151-
152148
# track the initial height to enable scaling via font_size
153149
self.initial_height = self.height
154150

151+
if self.include_background_rectangle:
152+
self.add_background_rectangle()
153+
155154
def get_num_string(self, number):
156155
if isinstance(number, complex):
157156
formatter = self.get_complex_formatter()
@@ -217,11 +216,28 @@ def get_complex_formatter(self):
217216
]
218217
)
219218

220-
def set_value(self, number):
219+
def set_value(self, number: float):
220+
"""Set the value of the :class:`~.DecimalNumber` to a new number.
221+
222+
Parameters
223+
----------
224+
number
225+
The value that will overwrite the current number of the :class:`~.DecimalNumber`.
226+
227+
"""
228+
# creates a new number mob via `set_submobjects_from_number`
229+
# then matches the properties (color, font_size, etc...)
230+
# of the previous mobject to the new one
231+
232+
# old_family needed with cairo
221233
old_family = self.get_family()
234+
235+
old_font_size = self.font_size
222236
move_to_point = self.get_edge_center(self.edge_to_fix)
223237
old_submobjects = self.submobjects
238+
224239
self.set_submobjects_from_number(number)
240+
self.font_size = old_font_size
225241
self.move_to(move_to_point, self.edge_to_fix)
226242
for sm1, sm2 in zip(self.submobjects, old_submobjects):
227243
sm1.match_style(sm2)
@@ -236,11 +252,6 @@ def set_value(self, number):
236252

237253
return self
238254

239-
def scale(self, scale_factor, **kwargs):
240-
super().scale(scale_factor, **kwargs)
241-
self._font_size *= scale_factor
242-
return self
243-
244255
def get_value(self):
245256
return self.number
246257

manim/mobject/svg/tex_mobject.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def __repr__(self):
121121
@property
122122
def font_size(self):
123123
"""The font size of the tex mobject."""
124-
return self._font_size
124+
return self.height / self.initial_height / SCALE_FACTOR_PER_FONT_POINT
125125

126126
@font_size.setter
127127
def font_size(self, font_val):
@@ -133,13 +133,7 @@ def font_size(self, font_val):
133133

134134
# scale to a factor of the initial height so that setting
135135
# font_size does not depend on current size.
136-
self.scale(
137-
SCALE_FACTOR_PER_FONT_POINT
138-
* font_val
139-
* self.initial_height
140-
/ self.height
141-
)
142-
self._font_size = font_val
136+
self.scale(font_val / self.font_size)
143137

144138
def get_modified_expression(self, tex_string):
145139
result = tex_string

manim/mobject/svg/text_mobject.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -535,21 +535,22 @@ def __repr__(self):
535535

536536
@property
537537
def font_size(self):
538-
return self._font_size
538+
return (
539+
self.height
540+
/ self.initial_height
541+
/ TEXT_MOB_SCALE_FACTOR
542+
* 2.4
543+
* self._font_size
544+
/ DEFAULT_FONT_SIZE
545+
)
539546

540547
@font_size.setter
541548
def font_size(self, font_val):
549+
# TODO: use pango's font size scaling.
542550
if font_val <= 0:
543551
raise ValueError("font_size must be greater than 0.")
544552
else:
545-
# multiply by (1/2.4) because it makes it work.
546-
self.scale(
547-
TEXT_MOB_SCALE_FACTOR
548-
* (1 / 2.4)
549-
* font_val
550-
* self.initial_height
551-
/ self.height
552-
)
553+
self.scale(font_val / self.font_size)
553554

554555
def gen_chars(self):
555556
chars = self.get_group_class()()
@@ -1153,21 +1154,22 @@ def __init__(
11531154

11541155
@property
11551156
def font_size(self):
1156-
return self._font_size
1157+
return (
1158+
self.height
1159+
/ self.initial_height
1160+
/ TEXT_MOB_SCALE_FACTOR
1161+
* 2.4
1162+
* self._font_size
1163+
/ DEFAULT_FONT_SIZE
1164+
)
11571165

11581166
@font_size.setter
11591167
def font_size(self, font_val):
11601168
# TODO: use pango's font size scaling.
11611169
if font_val <= 0:
11621170
raise ValueError("font_size must be greater than 0.")
11631171
else:
1164-
self.scale(
1165-
TEXT_MOB_SCALE_FACTOR
1166-
* (1 / 2.4)
1167-
* font_val
1168-
* self.initial_height
1169-
/ self.height
1170-
)
1172+
self.scale(font_val / self.font_size)
11711173

11721174
def text2hash(self):
11731175
"""Generates ``sha256`` hash for file name."""
Binary file not shown.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from manim import *
2+
from tests.test_graphical_units.testing.frames_comparison import frames_comparison
3+
4+
__module_test__ = "numbers"
5+
6+
7+
@frames_comparison(last_frame=False)
8+
def test_set_value_with_updaters(scene):
9+
"""Test that the position of the decimal updates properly"""
10+
decimal = DecimalNumber(
11+
0,
12+
show_ellipsis=True,
13+
num_decimal_places=3,
14+
include_sign=True,
15+
)
16+
square = Square().to_edge(UP)
17+
18+
decimal.add_updater(lambda d: d.next_to(square, RIGHT))
19+
decimal.add_updater(lambda d: d.set_value(square.get_center()[1]))
20+
scene.add(square, decimal)
21+
scene.play(
22+
square.animate.to_edge(DOWN),
23+
rate_func=there_and_back,
24+
)

tests/test_numbers.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import pytest
2+
3+
from manim.mobject.numbers import DecimalNumber
4+
5+
6+
def test_font_size():
7+
"""Test that DecimalNumber returns the correct font_size value
8+
after being scaled."""
9+
num = DecimalNumber(0).scale(0.3)
10+
11+
assert round(num.font_size, 5) == 14.4
12+
13+
14+
def test_font_size_vs_scale():
15+
"""Test that scale produces the same results as .scale()"""
16+
num = DecimalNumber(0, font_size=12)
17+
num_scale = DecimalNumber(0).scale(1 / 4)
18+
19+
assert num.height == num_scale.height
20+
21+
22+
def test_changing_font_size():
23+
"""Test that the font_size property properly scales DecimalNumber."""
24+
num = DecimalNumber(0, font_size=12)
25+
num.font_size = 48
26+
27+
assert num.height == DecimalNumber(0, font_size=48).height
28+
29+
30+
def test_set_value_size():
31+
"""Test that the size of DecimalNumber after set_value is correct."""
32+
num = DecimalNumber(0).scale(0.3)
33+
test_num = num.copy()
34+
num.set_value(0)
35+
36+
# round because the height is off by 1e-17
37+
assert round(num.height, 12) == round(test_num.height, 12)

tests/test_texmobject.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,27 @@ def test_tex_size():
8181
horizontal = text.get_right() - text.get_left()
8282
assert round(vertical[1], 4) == 0.3512
8383
assert round(horizontal[0], 4) == 1.0420
84+
85+
86+
def test_font_size():
87+
"""Test that tex_mobject classes return
88+
the correct font_size value after being scaled."""
89+
string = MathTex(0).scale(0.3)
90+
91+
assert round(string.font_size, 5) == 14.4
92+
93+
94+
def test_font_size_vs_scale():
95+
"""Test that scale produces the same results as .scale()"""
96+
num = MathTex(0, font_size=12)
97+
num_scale = MathTex(0).scale(1 / 4)
98+
99+
assert num.height == num_scale.height
100+
101+
102+
def test_changing_font_size():
103+
"""Test that the font_size property properly scales tex_mobject.py classes."""
104+
num = Tex("0", font_size=12)
105+
num.font_size = 48
106+
107+
assert num.height == Tex("0", font_size=48).height

tests/test_text_mobject.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import pytest
2+
3+
from manim.mobject.svg.text_mobject import MarkupText, Text
4+
5+
6+
def test_font_size():
7+
"""Test that Text and MarkupText return the
8+
correct font_size value after being scaled."""
9+
text_string = Text("0").scale(0.3)
10+
markuptext_string = MarkupText("0").scale(0.3)
11+
12+
assert round(text_string.font_size, 5) == 14.4
13+
assert round(markuptext_string.font_size, 5) == 14.4

0 commit comments

Comments
 (0)