Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ COPY . /opt/manim
WORKDIR /opt/manim
RUN pip install --no-cache .

# ensure that ffi bindings are generated
RUN python -c "import pangocairocffi"

# create working directory for user to mount local directory into
WORKDIR /manim
RUN chmod 666 /manim
Expand Down
10 changes: 0 additions & 10 deletions docs/source/installation/mac.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,6 @@ To install cairo:

brew install cairo

To install Pango and it dependencies:

.. code-block:: bash

brew install pkg-config
brew install libffi
brew install pango
brew install glib


To install ffmpeg:

.. code-block:: bash
Expand Down
38 changes: 18 additions & 20 deletions docs/source/installation/troubleshooting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,28 @@ Troubleshooting

List of known installation problems.

(Windows) OSError: dlopen() failed to load a library: pango?
------------------------------------------------------------

If your manual installation of Manim (or even the installation using
Chocolatey) fails with the error
``pip install manim`` fails when installing manimpango?
-------------------------------------------------------
Most likely this means that pip was not able to use our pre-built wheels
of ``manimpango``. Let us know (via our `Discord <https://discord.gg/mMRrZQW>`_
or by opening a
`new issue on GitHub <https://github.com/ManimCommunity/ManimPango/issues/new>`_)
which architecture you would like to see supported, and we'll see what we
can do about it.

To fix errors when installing ``manimpango``, you need to make sure you
have all the necessary build requirements. Check out the detailed
instructions given in
`the BUILDING section <https://github.com/ManimCommunity/ManimPango#BUILDING>`_
of the corresponding `GitHub repository <https://github.com/ManimCommunity/ManimPango>`_.

.. code-block::

OSError: dlopen() failed to load a library: pango / pango-1 / pango-1.0 / pango-1.0-0

possibly combined with alerts warning about procedure entry points
``"deflateSetHeader"`` and ``"inflateReset2"`` that could not be
located, you might run into an issue with a patched version of ``zlib1.dll``
shipped by Intel, `as described here <https://github.com/msys2/MINGW-packages/issues/813>`_.
(Windows) OSError: dlopen() failed to load a library: pango?
------------------------------------------------------------

To resolve this issue, you can copy ``zlib1.dll`` from the directory
provided for the Pango binaries to the directory Manim is installed to.
This should be fixed in Manim's latest version, update
using ``pip install --upgrade manim``.

For a more global solution (try at your own risk!), try renaming the
file ``zlib1.dll`` located at ``C:\Program Files\Intel\Wifi\bin`` to
something like ``zlib1.dll.bak`` -- and then try installing Manim again
(either using ``pip install manim`` or with Chocolatey). Ensure that
you are able to revert this name change in case you run into troubles
with your WiFi (we did not get any reports about such a problem, however).


Some letters are missing from TextMobject/TexMobject output?
Expand Down
26 changes: 0 additions & 26 deletions docs/source/installation/win.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,6 @@ You can install manim very easily using chocolatey, by typing the following comm
And then you can skip all the other steps and move to installing :ref:`latex-installation`.
Please see :doc:`troubleshooting` section for details about OSError.

Pango Installation
******************

These steps would get you `libpango-1.0-0.dll` to your ``PATH`` along
with other dependencies. You may probably have them before itself if
you have installed `GTK <https://www.gtk.org/>`_ or any ``GTK``
based app like emacs. If you have it you can just add it to your
path and skip these steps.

1. Go to `Release Page
<https://github.com/ManimCommunity/manim-windows/releases/latest>`_
and download the one according to your PC architechture.

.. important:: Please download the ``zip`` file for architechture of python installed.
It is possible to have installed ``x86`` python installed on ``x64`` PC.

2. Extract the zip file using File Explorer or 7z to the loaction you want to install.

.. code-block:: bash

7z x pango-windows-binaires-x64.zip -oC:\Pango

3. Finally, add it `PATH variable
<https://www.computerhope.com/issues/ch000549.htm>`_.


FFmpeg installation
*******************

Expand Down
164 changes: 33 additions & 131 deletions manim/mobject/svg/text_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,15 @@ def construct(self):
from xml.sax.saxutils import escape

import cairo
import cairocffi
import pangocairocffi
import pangocffi
import manimpango
from manimpango import PangoUtils, TextSetting, MarkupUtils

from ... import config, logger
from ...constants import *
from ...mobject.geometry import Dot
from ...mobject.svg.svg_mobject import SVGMobject
from ...mobject.types.vectorized_mobject import VGroup
from ...utils.color import WHITE
from ...utils.color import Colors

from ...utils.color import WHITE, Colors

TEXT_MOB_SCALE_FACTOR = 0.05

Expand Down Expand Up @@ -103,68 +100,6 @@ def remove_invisible_chars(mobject):
return mobject_without_dots


class PangoUtils:
@staticmethod
def str2style(string: str) -> pangocffi.Style:
"""Internally used function. Converts text to Pango Understandable Styles."""
if string == NORMAL:
return pangocffi.Style.NORMAL
elif string == ITALIC:
return pangocffi.Style.ITALIC
elif string == OBLIQUE:
return pangocffi.Style.OBLIQUE
else:
raise AttributeError("There is no Style Called %s" % string)

@staticmethod
def str2weight(string: str) -> pangocffi.Weight:
"""Internally used function. Convert text to Pango Understandable Weight"""
if string == NORMAL:
return pangocffi.Weight.NORMAL
elif string == BOLD:
return pangocffi.Weight.BOLD
elif string == THIN:
return pangocffi.Weight.THIN
elif string == ULTRALIGHT:
return pangocffi.Weight.ULTRALIGHT
elif string == LIGHT:
return pangocffi.Weight.LIGHT
elif string == SEMILIGHT:
return pangocffi.Weight.SEMILIGHT
elif string == BOOK:
return pangocffi.Weight.BOOK
elif string == MEDIUM:
return pangocffi.Weight.MEDIUM
elif string == SEMIBOLD:
return pangocffi.Weight.SEMIBOLD
elif string == ULTRABOLD:
return pangocffi.Weight.ULTRABOLD
elif string == HEAVY:
return pangocffi.Weight.HEAVY
elif string == ULTRAHEAVY:
return pangocffi.Weight.ULTRAHEAVY
else:
raise AttributeError("There is no Font Weight Called %s" % string)

@staticmethod
def remove_last_M(file_name: str) -> None:
with open(file_name, "r") as fpr:
content = fpr.read()
content = re.sub(r'Z M [^A-Za-z]*? "\/>', 'Z "/>', content)
with open(file_name, "w") as fpw:
fpw.write(content)


class TextSetting(object):
def __init__(self, start, end, font, slant, weight, line_num=-1):
self.start = start
self.end = end
self.font = font
self.slant = slant
self.weight = weight
self.line_num = line_num


class CairoText(SVGMobject):
"""Display (non-LaTeX) text.

Expand Down Expand Up @@ -448,7 +383,7 @@ def text2svg(self):
offset_x = 0
last_line_num = 0
for setting in settings:
font = setting.font
font = setting.font.decode("utf-8")
slant = self.str2slant(setting.slant)
weight = self.str2weight(setting.weight)
text = self.text[setting.start : setting.end].replace("\n", " ")
Expand Down Expand Up @@ -1012,45 +947,22 @@ def text2svg(self):
file_name = os.path.join(dir_name, hash_name) + ".svg"
if os.path.exists(file_name):
return file_name
surface = cairocffi.SVGSurface(file_name, 600, 400)
context = cairocffi.Context(surface)
context.move_to(START_X, START_Y)
settings = self.text2settings()
offset_x = 0
last_line_num = 0
layout = pangocairocffi.create_layout(context)
layout.set_width(pangocffi.units_from_double(600))
for setting in settings:
family = setting.font
style = PangoUtils.str2style(setting.slant)
weight = PangoUtils.str2weight(setting.weight)
text = self.text[setting.start : setting.end].replace("\n", " ")
fontdesc = pangocffi.FontDescription()
fontdesc.set_size(pangocffi.units_from_double(size))
if family:
fontdesc.set_family(family)
fontdesc.set_style(style)
fontdesc.set_weight(weight)
layout.set_font_description(fontdesc)
if setting.line_num != last_line_num:
offset_x = 0
last_line_num = setting.line_num
context.move_to(
START_X + offset_x, START_Y + line_spacing * setting.line_num
)
pangocairocffi.update_layout(context, layout)
if disable_liga:
text = escape(text)
layout.set_markup(
f"<span font_features='liga=0,dlig=0,clig=0,hlig=0'>{text}</span>"
)
else:
layout.set_text(text)
logger.debug(f"Setting Text {text}")
pangocairocffi.show_layout(context, layout)
offset_x += pangocffi.units_to_double(layout.get_size()[0])
surface.finish()
return file_name
width = 600
height = 400

return manimpango.text2svg(
settings,
size,
line_spacing,
disable_liga,
file_name,
START_X,
START_Y,
width,
height,
self.text,
)


class MarkupText(SVGMobject):
Expand Down Expand Up @@ -1360,32 +1272,22 @@ def text2svg(self):
file_name = os.path.join(dir_name, hash_name) + ".svg"
if os.path.exists(file_name):
return file_name
surface = cairocffi.SVGSurface(file_name, 600, 400)
context = cairocffi.Context(surface)
context.move_to(START_X, START_Y)
layout = pangocairocffi.create_layout(context)
layout.set_width(pangocffi.units_from_double(600))

fontdesc = pangocffi.FontDescription()
fontdesc.set_size(pangocffi.units_from_double(size))
if self.font:
fontdesc.set_family(self.font)
fontdesc.set_style(PangoUtils.str2style(self.slant))
fontdesc.set_weight(PangoUtils.str2weight(self.weight))
layout.set_font_description(fontdesc)

context.move_to(START_X, START_Y)
pangocairocffi.update_layout(context, layout)
if disable_liga:
layout.set_markup(
f"<span font_features='liga=0,dlig=0,clig=0,hlig=0'>{self.text}</span>"
)
else:
layout.set_markup(self.text)
logger.debug(f"Setting Text {self.text}")
pangocairocffi.show_layout(context, layout)
surface.finish()
return file_name
return MarkupUtils.text2svg(
self.text,
self.font,
self.slant,
self.weight,
size,
line_spacing,
disable_liga,
file_name,
START_X,
START_Y,
600, # width
400, # height
)

def _count_real_chars(self, s):
"""Counts characters that will be displayed.
Expand Down
Loading