ManimCommunity / ManimCommunity/manim
Font size calculation for text and MathTex is very confusing
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 40.9k
- Forks
- 3.1k
- Avg merge
- 3d 12h
- Merged PRs (30d)
- 25
Description
Hello there !
I'm currently working on [manim-web](https://github.com/maloyan/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:
1. render the source string to Tex, DPI then SVG. You get an arbitrary size measured empirically (~10 units in the SVG world ?)
2. extract the paths of the SVG, do NOT normalize them
3. call `self.font_size = self._font_size` which in turns call the setter
4. the setter does `self.scale(font_val / self.font_size)`, where `font_size` is a getter
5. 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:
1. compute `size = self._font_size` and `size /= TEXT2SVG_ADJUSTMENT_FACTOR` where `TEXT2SVG_ADJUSTMENT_FACTOR = 4.8` (https://github.com/ManimCommunity/manim/blob/af70b6fef2180a926c47aa0cb309e2314672926f/manim/mobject/text/text_mobject.py#L801-L803)
2. Use `manimpango` to extract svg from text with `size=size`
3. 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:
- https://github.com/ManimCommunity/manim/blob/bbdcda1ff56d1f3b082218cfb598e7a1c0c2fc6c/manim/mobject/text/tex_mobject.py#L101 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 😅
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by comparing the font_size implementations and constants in manim/mobject/text/tex_mobject.py and manim/mobject/text/text_mobject.py, then investigate the undocumented size argument passed to manimpango. Review the linked source locations and determine the intended scaling behavior before proposing renames, comments, or shared logic; done means the behavior and constants are clearly explained and an agreed refactor scope is established.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- computer-graphics
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 32/100