Hello there !
I'm currently working on manim-web, a js port of this amazing project.
I noticed that the font-size logic was different, so I wanted to investigate to be sure the behavior is the same.
But looking at the source-code of manim, I'm very confused. I think this would be a good opportunity to rewrite, simplify, comment, and rename variables in the code regarding this logic.
I consider contributing, but I have some questions I would like to clarify before.
From what I understand, the pipeline for MathTex is:
- render the source string to Tex, DPI then SVG. You get an arbitrary size measured empirically (~10 units in the SVG world ?)
- extract the paths of the SVG, do NOT normalize them
- call
self.font_size = self._font_size which in turns call the setter
- the setter does
self.scale(font_val / self.font_size), where font_size is a getter
- the font_size getter returns the confusing
self.height / self.initial_height / SCALE_FACTOR_PER_FONT_POINT where SCALE_FACTOR_PER_FONT_POINT=1/960.
So that means the output height is SVG_COMPUTED_HEIGHT * (INPUT_FONT_SIZE / (1 / SCALE_FACTOR_PER_FONT_POINT)), which means SCALE_FACTOR_PER_FONT_POINT is a combination of 2 things: "X svg points should be Y pt" and "Y pts should be Z units in manim"
And the pipeline for Text is:
- compute
size = self._font_size and size /= TEXT2SVG_ADJUSTMENT_FACTOR where TEXT2SVG_ADJUSTMENT_FACTOR = 4.8 (
|
size = self._font_size |
|
line_spacing = self.line_spacing |
|
size /= TEXT2SVG_ADJUSTMENT_FACTOR |
)
- Use
manimpango to extract svg from text with size=size
- call
self.scale(TEXT_MOB_SCALE_FACTOR) where TEXT_MOB_SCALE_FACTOR=0.05
And for one obscure reason the font-size is defined as:
@property
def font_size(self) -> float:
return (
self.height
/ self.initial_height
/ TEXT_MOB_SCALE_FACTOR
* 2.4
* self._font_size
/ DEFAULT_FONT_SIZE
)
with a hardcoded 2.4 value
For this one, I'm still trying to make sense of it.
Questions
- is it true that the svg paths returned by
Tex are not normalized ? It's a probably naive question but why ?
- has
SCALE_FACTOR_PER_FONT_POINT been set empirically or is there a reason ?
- what does the
size argument of manimpango do ? Why is there scaling after svg generation ?
- I suspect the
2.4 has been added just because 2.4 / TEXT_MOB_SCALE_FACTOR is exactly 48, the default font size. Since they cancel out, why not just do self.height / self.initial_height * self._font_size ?
- Wouldn't it be cleaner to have the same logic for Tex and SVG ? Render SVG in
SVG point space, and do the same scaling afterward with one single SCALE_FACTOR_PER_SVG_FONT_POINT constant ?
Notes:
|
self.font_size = self._font_size |
has both font_size as a setter and _font_size, quite hard to make sense of
_font_size could be renamed _required_font_size, and assertions could be added so that the person reading the code knows what properties to expect in the code
SCALE_FACTOR_PER_FONT_POINT should be renamed SCALE_FACTOR_PER_SVG_FONT_POINT at least
TEXT_MOB_SCALE_FACTOR is defined in this file: https://github.com/ManimCommunity/manim/blob/main/manim/mobject/text/text_mobject.py . If it is really needed, it should go to the constants.py file
- the
size argument of manimpango is not documented
I hope my walkthrough is understandable, It was quite an adventure 😅
Hello there !
I'm currently working on manim-web, a js port of this amazing project.
I noticed that the font-size logic was different, so I wanted to investigate to be sure the behavior is the same.
But looking at the source-code of
manim, I'm very confused. I think this would be a good opportunity to rewrite, simplify, comment, and rename variables in the code regarding this logic.I consider contributing, but I have some questions I would like to clarify before.
From what I understand, the pipeline for
MathTexis:self.font_size = self._font_sizewhich in turns call the setterself.scale(font_val / self.font_size), wherefont_sizeis a getterself.height / self.initial_height / SCALE_FACTOR_PER_FONT_POINTwhereSCALE_FACTOR_PER_FONT_POINT=1/960.So that means the output height is
SVG_COMPUTED_HEIGHT * (INPUT_FONT_SIZE / (1 / SCALE_FACTOR_PER_FONT_POINT)), which meansSCALE_FACTOR_PER_FONT_POINTis a combination of 2 things: "X svg points should be Y pt" and "Y pts should be Z units in manim"And the pipeline for
Textis:size = self._font_sizeandsize /= TEXT2SVG_ADJUSTMENT_FACTORwhereTEXT2SVG_ADJUSTMENT_FACTOR = 4.8(manim/manim/mobject/text/text_mobject.py
Lines 801 to 803 in af70b6f
manimpangoto extract svg from text withsize=sizeself.scale(TEXT_MOB_SCALE_FACTOR)whereTEXT_MOB_SCALE_FACTOR=0.05And for one obscure reason the font-size is defined as:
with a hardcoded
2.4valueFor this one, I'm still trying to make sense of it.
Questions
Texare not normalized ? It's a probably naive question but why ?SCALE_FACTOR_PER_FONT_POINTbeen set empirically or is there a reason ?sizeargument ofmanimpangodo ? Why is there scaling after svg generation ?2.4has been added just because2.4 / TEXT_MOB_SCALE_FACTORis exactly 48, the default font size. Since they cancel out, why not just doself.height / self.initial_height * self._font_size?SVG point space, and do the same scaling afterward with one singleSCALE_FACTOR_PER_SVG_FONT_POINTconstant ?Notes:
manim/manim/mobject/text/tex_mobject.py
Line 101 in bbdcda1
font_sizeas a setter and_font_size, quite hard to make sense of_font_sizecould be renamed_required_font_size, and assertions could be added so that the person reading the code knows what properties to expect in the codeSCALE_FACTOR_PER_FONT_POINTshould be renamedSCALE_FACTOR_PER_SVG_FONT_POINTat leastTEXT_MOB_SCALE_FACTORis defined in this file: https://github.com/ManimCommunity/manim/blob/main/manim/mobject/text/text_mobject.py . If it is really needed, it should go to the constants.py filesizeargument ofmanimpangois not documentedI hope my walkthrough is understandable, It was quite an adventure 😅