ManimCommunity / ManimCommunity/manim

Font size calculation for text and MathTex is very confusing

Open
#4,690 3 comments 0 reactions 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.