ManimCommunity / manim

A community-maintained Python framework for creating mathematical animations.
https://www.manim.community
MIT License
24.35k stars 1.7k forks source link

Tex submobject scaling incorrect characters depending on font used. #880

Closed newell closed 3 years ago

newell commented 3 years ago

Description of bug / unexpected behavior

When scaling Tex submobjects, sometimes it incorrectly scales other characters not in the scaled submobject or only part of the submobject. I have seen this for a couple of fonts, including EB Garamond below, while for the default font I don't see the issues.

Expected behavior

I would expect the intended scaled submobject to be the actual one that is scaled in the animations regardless of the font used.

How to reproduce the issue

To reproduce this issue you can use the open source EB Garamond font at https://github.com/octaviopardo/EBGaramond12/tree/master/fonts/ and then run the code below which uses my Tex preamble.

Using EB Garamond: https://user-images.githubusercontent.com/4163356/103179319-a0a15800-483f-11eb-9c81-49cac2618ddc.mp4

Not using EB Garamond: https://user-images.githubusercontent.com/4163356/103179321-a434df00-483f-11eb-945a-313f993e6a54.mp4

Code for reproducing the problem ```py # TeX preamble. TEX_PREAMBLE = r""" \usepackage{lettrine} \usepackage{fontspec} \setmainfont{EBGaramond-Regular.otf}[ BoldFont = EBGaramond-Bold.otf, ItalicFont = EBGaramond-Italic.otf, BoldItalicFont = EBGaramond-BoldItalic.otf, SmallCapsFont = EBGaramond12-AllSC.otf, Numbers = {OldStyle,Proportional}, RawFeature = {+ss06} ] \newfontfamily\euclidinitials{EuclidInitialsnormal.ttf} """ def get_tex_template(): """ Retrieve the TeX template. """ tex_template = TexTemplateLibrary.simple tex_template.add_to_preamble(TEX_PREAMBLE) tex_template.tex_compiler = "xelatex" tex_template.output_format = ".pdf" return tex_template TEX_TEMPLATE = get_tex_template() from manim import * class NotWorking(Scene): def construct(self): tex = ( Tex( r"\raggedright 5. If from the angle ", r"\textbf{ABC}", r", there be taken the angle ", r"\textbf{BAC}", r", the remainder\\ will be equal to the angle ", r"\textbf{ACB}", r".", tex_template=TEX_TEMPLATE, ) .scale(0.5) ) self.play(FadeInFrom(tex, DOWN)) self.play(tex[1].scale, 2) self.play(tex[1].scale, 0.5) self.play(tex[3].scale, 2) self.play(tex[3].scale, 0.5) self.play(tex[5].scale, 2) self.play(tex[5].scale, 0.5) ```

Additional media files

Images/GIFs

Logs

Terminal output ``` PASTE HERE OR PROVIDE LINK TO https://pastebin.com/ OR SIMILAR ```

System specifications

System Details - OS (with version, e.g Windows 10 v2004 or macOS 10.15 (Catalina)): Ubuntu 20.04.1 LTS - RAM: 16 GB - Python version (`python/py/python3 --version`): Python 3.8.5 - Installed modules (provide output from `pip list`): ``` Package Version ----------------------------- ------------------------------ alabaster 0.7.8 apparmor 2.13.3 appdirs 1.4.3 apturl 0.5.2 argon2-cffi 20.1.0 astroid 2.3.3 async-generator 1.10 atomicwrites 1.1.5 attrs 19.3.0 Automat 0.8.0 Babel 2.6.0 backcall 0.1.0 bcrypt 3.1.7 beautifulsoup4 4.8.2 black 19.3b0 bleach 3.2.1 blinker 1.4 boto 2.49.0 breezy 3.0.2 Brlapi 0.7.0 brz-debian 3.0.0 cairocffi 1.2.0 certifi 2019.11.28 cffi 1.14.3 chardet 3.0.4 chrome-gnome-shell 0.0.0 Click 7.0 colorama 0.4.3 colour 0.1.5 command-not-found 0.3 commonmark 0.9.1 configobj 5.0.6 constantly 15.1.0 convoy 0.4.4 crochet 1.4.0 cryptography 2.8 cssselect 1.1.0 cupshelpers 1.0 cycler 0.10.0 dbus-python 1.2.16 debtcollector 2.0.0 decorator 4.4.2 defer 1.0.6 defusedxml 0.6.0 Deprecated 1.2.7 devscripts 2.20.2ubuntu2 distlib 0.3.0 distro 1.4.0 distro-info 0.23ubuntu1 Django 2.2.12 django-nose 1.4.6 django-piston3 0.3rc2 dnspython 1.16.0 docutils 0.16 dulwich 0.19.15 duplicity 0.8.12.0 entrypoints 0.3 et-xmlfile 1.0.1 fasteners 0.14.1 fastimport 0.9.8 feedparser 5.2.1 filelock 3.0.12 Flask 1.1.1 FormEncode 1.3.0 future 0.18.2 gmpy2 2.1.0b3 gpg 1.13.1-unknown html5lib 1.0.1 httplib2 0.14.0 hyperlink 19.0.0 idna 2.8 imagesize 1.2.0 importlib-metadata 1.5.0 incremental 16.10.1 ipykernel 5.3.4 ipython 7.13.0 ipython-genutils 0.2.0 ipywidgets 7.5.1 isc 2.0 iso8601 0.1.12 isort 4.3.4 itsdangerous 1.1.0 jdcal 1.0 jedi 0.15.2 Jinja2 2.10.1 jsonschema 3.2.0 jupyter 1.0.0 jupyter-client 6.1.7 jupyter-console 6.2.0 jupyter-core 4.7.0 jupyterlab-pygments 0.1.2 keyring 18.0.1 keyrings.alt 3.4.0 keystoneauth1 4.0.0 kiwisolver 1.0.1 language-selector 0.1 launchpadlib 1.10.13 lazr.restfulclient 0.14.2 lazr.uri 1.0.3 lazy-object-proxy 1.4.3 LibAppArmor 2.13.3 libvirt-python 6.1.0 lockfile 0.12.2 logilab-common 1.4.3 louis 3.12.0 lxml 4.5.0 macaroonbakery 1.3.1 Mako 1.1.0 manim 0.1.1 manimce 0.1.0 MarkupSafe 1.1.0 matplotlib 3.1.2 mccabe 0.6.1 mistune 0.8.4 mock 3.0.5 monotonic 1.5 more-itertools 4.2.0 mpmath 1.1.0 msgpack 0.6.2 nbclient 0.5.1 nbconvert 6.0.7 nbformat 5.0.8 nest-asyncio 1.4.3 netaddr 0.7.19 netifaces 0.10.4 nose 1.3.7 notebook 6.1.5 numexpr 2.7.1 numpy 1.17.4 oauth 1.0.1 oauthlib 3.1.0 olefile 0.46 onboard 1.4.1 openpyxl 3.0.3 openshot-qt 2.4.3 os-service-types 1.7.0 oslo.i18n 4.0.1 oslo.serialization 3.1.1 oslo.utils 4.1.1 packaging 20.3 padme 1.1.1 pandas 0.25.3 pandocfilters 1.4.3 pangocairocffi 0.4.0 pangocffi 0.8.0 paramiko 2.6.0 parso 0.5.2 pbr 5.4.5 petname 2.6 pexpect 4.6.0 pickleshare 0.7.5 Pillow 7.0.0 pip 20.0.2 Pivy 0.6.5 pluggy 0.13.0 ply 3.11 prettytable 0.7.2 progressbar 2.5 prometheus-client 0.7.1 prompt-toolkit 2.0.10 protobuf 3.6.1 psutil 5.5.1 psycopg2 2.8.4 ptyprocess 0.6.0 py 1.8.1 py3dns 3.2.1 pyasn1 0.4.2 pyasn1-modules 0.2.1 pycairo 1.20.0 pycparser 2.20 pycrypto 2.6.1 pycups 1.9.73 pycurl 7.43.0.2 pydub 0.23.1 PyGithub 1.43.7 Pygments 2.7.2 PyGObject 3.36.0 PyHamcrest 1.9.0 pyinotify 0.9.6 PyJWT 1.7.1 pylint 2.4.4 pylxd 2.2.10 pymacaroons 0.13.0 PyNaCl 1.3.0 pyOpenSSL 19.0.0 pyparsing 2.4.6 PyQt5 5.14.1 pyRFC3339 1.1 pyrsistent 0.15.5 PySimpleSOAP 1.16.2 PyStemmer 1.3.0 pytest 4.6.9 python-apt 2.0.0+ubuntu0.20.4.2 python-dateutil 2.7.3 python-debian 0.1.36ubuntu1 python-debianbts 3.0.2 python-gitlab 2.0.1 python-magic 0.4.16 python-mimeparse 1.6.0 python-novaclient 17.0.0 python-seamicroclient 0.4.0+2016.5.20.git.40ee44c664 python-tx-tftp 0.2 pytz 2019.3 PyVISA 1.10.1 PyVISA-py 0.3.1 pyvmomi 6.7.1 pyxattr 0.6.1 pyxdg 0.26 PyYAML 5.3.1 pyzmq 20.0.0 qtconsole 4.7.7 QtPy 1.9.0 reportbug 7.6.0ubuntu1 reportlab 3.5.34 requests 2.22.0 requests-toolbelt 0.8.0 requests-unixsocket 0.2.0 rich 6.2.0 roman 2.0.0 scipy 1.3.3 SecretStorage 2.3.1 Send2Trash 1.5.0 service-identity 18.1.0 setuptools 45.2.0 simplejson 3.16.0 sip 4.19.21 six 1.14.0 soupsieve 1.9.5 Sphinx 1.8.5 sqlparse 0.2.4 ssh-import-id 5.10 stevedore 1.32.0 sushy 2.0.0 system-service 0.3 systemd-python 234 tables 3.6.1 Tempita 0.5.2 terminado 0.9.1 testpath 0.4.4 toml 0.10.0 tornado 5.1.1 tqdm 4.30.0 traitlets 4.3.3 Twisted 18.9.0 typing-extensions 3.7.4.3 ubuntu-advantage-tools 20.3 ubuntu-dev-tools 0.176 ubuntu-drivers-common 0.0.0 ufw 0.36 unattended-upgrades 0.1 unidiff 0.5.5 unity-scope-calculator 0.1 unity-scope-chromiumbookmarks 0.1 unity-scope-colourlovers 0.1 unity-scope-devhelp 0.1 unity-scope-firefoxbookmarks 0.1 unity-scope-gdrive 0.7 unity-scope-manpages 0.1 unity-scope-openclipart 0.1 unity-scope-texdoc 0.1 unity-scope-tomboy 0.1 unity-scope-virtualbox 0.1 unity-scope-yelp 0.1 unity-scope-zotero 0.1 urllib3 1.25.8 urwid 2.0.1 usb-creator 0.3.7 uvloop 0.14.0 virtualenv 20.0.17 virtualenv-clone 0.3.0 virtualenvwrapper 4.8.4 wadllib 1.3.3 wcwidth 0.1.8 webencodings 0.5.1 Werkzeug 0.16.1 wheel 0.34.2 widgetsnbextension 3.5.1 wrapt 1.11.2 ws4py 0.4.2 xdiagnose 3.8.9 xkit 0.0.0 xlrd 1.1.0 XlsxWriter 1.1.2 xlwt 1.3.0 youtube-dl 2020.3.24 zipp 1.0.0 zope.interface 4.7.1 ```
LaTeX details + LaTeX distribution (e.g. TeX Live 2020): + Installed LaTeX packages: texlive-full
FFMPEG Output of `ffmpeg -version`: ``` fmpeg version 4.2.4-1ubuntu0.1 Copyright (c) 2000-2020 the FFmpeg developers built with gcc 9 (Ubuntu 9.3.0-10ubuntu2) configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared libavutil 56. 31.100 / 56. 31.100 libavcodec 58. 54.100 / 58. 54.100 libavformat 58. 29.100 / 58. 29.100 libavdevice 58. 8.100 / 58. 8.100 libavfilter 7. 57.100 / 7. 57.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 5.100 / 5. 5.100 libswresample 3. 5.100 / 3. 5.100 libpostproc 55. 5.100 / 55. 5.100 ```

Additional comments

leotrs commented 3 years ago

Thank you for reporting! This is a very strange bug indeed - cc @ManimCommunity/latex

cobordism commented 3 years ago

I believe this is an old known issue. If I am correct it is the following:

Once we have rendered tex to dvi to svg and then imported the svg mobject back into manim, we don't know exactly which svg element matches which bit of original tex code. Manim tries to guess, but that can go wrong. Sometimes a different font causes two svg paths to be merged into one (or some other change in the underlying SVG) that causes the count to be off. (similar problems occur when counting characters in regular text when the font provides ligatures).

I'm afraid in cases like these it's always just trial[n] and[m] error[k] until you find the correct indices.

See also here for a similar issue: https://github.com/ManimCommunity/manim/issues/209#issuecomment-729003810

In the long term, if we really really wanted to fix this, I suspect it would have to be done on the dvisvgm level. Either we learn to handle svg's with embedded fonts - thus knowing which svg element corresponds to character, at least in theory; Or we patch dvisvgm to 'tag' the svg elements in the font-free svg with some description of which bit of tex code they correspond to.

I am not hopeful that either of those will be possible within a reasonable timeframe. I suggest you use trial and error to find the indices that work for you.

sorry.

cobordism commented 3 years ago

I will close this issue for now as there is no clear path forward. For the time being, it will have to remain a trial-and-error solution.