ManimPango’s documentation!

ManimPango is a library for rendering text to images (SVGs also supported) using Pango. It also provides various other utilities like registering fonts in system library for use with Pango (could also be used with GTK apps for example).

Installation

Installation

You can install ManimPango using pip:

pip install manimpango

There are prebuild wheels for both Windows and macOS.

For Linux Users, there are no Wheels. You must have a C compiler as well as Pango and its dependencies along with the Pango development headers. See Building ManimPango for more information.

Building ManimPango

Linux/MacOS

For building ManimPango, you need

  • a C compiler

  • Python’s development headers

  • pkg-config

  • Pango along with its development headers and its dependencies.

If you are on MacOS, you can use brew to install those. Using MacPorts is also possible.

brew install pango pkg-config

If you are on Linux, you can use a system package manager to do so. For example, if you are on Debian based system, you can use apt

apt install libpango1.0-dev pkg-config python3-dev

Arch Linux: pacman -S pango pkgconf

Fedora: dnf install pango-devel pkg-config python3-devel

Or similar in your system’s package manager.

Using tar archives

If you don’t want to contribute to this repository, you can use the tar archives published on PyPi, or just use pip to install using

pip install manimpango --no-binary :all:

Note: pip by default uses wheels, so make sure to pass the --no-binary parameter.

Using git clones / Contributing

Please remember to do this inside your virtual environment, if you want to use your Manimpango with Manim.

python -m venv ./venv
source venv/bin/activate # Linux/macOS
venv\Scripts\activate # Windows

If you are using a clone of this repository, you will need Cython which can be easily installed using pip:

pip install Cython

After that you can use pip to install the clone with the following command:

pip install -e .
pip install -r requirements-dev.txt .

Next, build the library inplace using:

python setup.py build_ext -i

After installation is complete, you should be able to run pytest:

pytest

Windows

Note

If you are a normal user, don’t read this, you have wheels which you can just install directly using pip.

If you want to contribute to ManimPango and you are on Windows, this section is for you.

As Windows does not include a C compiler by default, you will first need to install one. You have two choices:

  1. MinGW/Msys2

  2. Visual Studio

MinGW/Msys2
  1. Download MSYS2 from the download link provided on their page https://www.msys2.org/#installation and install it according to their instructions.

  2. Once you have MSYS2 installed, it offers you three different shells: the MinGW32 shell, the MinGW64 shell and MSYS shell. In order for the following steps to work, you have to open the MSYS2 MinGW64 shell (you can search for this). Small hint: it has a blue color logo.

  3. Run the following commands to install Python, Pango, Cython, Numpy, Scipy, Pillow, Pycairo and ffmpeg

pacman -S mingw-w64-x86_64-python
pacman -S mingw-w64-x86_64-python-pip
pacman -S mingw-w64-x86_64-pango
pacman -S mingw-w64-x86_64-cython
pacman -S mingw-w64-x86_64-python-numpy
pacman -S mingw-w64-x86_64-python-scipy
pacman -S mingw-w64-x86_64-python-pillow
pacman -S mingw-w64-x86_64-python-cairo
pacman -S mingw-w64-x86_64-ffmpeg
  1. Still in the same shell, install Manim using pip install manim.

  2. Finally, get your clone of ManimPango, cd into that directory and then run pip install -e ..

Note

You can’t use it with your regular Python version. It will cause weird errors if you do so. For working with ManimPango, you must be inside the MSYS2 MINGW64 shell.

  1. You can then use manim inside that shell, to run Manim.

Note

If you want to try out Python interactively, you can open idle using the command python -m idlelib inside that shell.

Visual Studio

First, install Visual Studio as specified in https://wiki.python.org/moin/WindowsCompilers. Possibly Visual Studio Build Tools 2022 with Windows11 SDK.

Then run the script at packing/download_dlls.py. This will get a Pango build along with pkg-config and install it at C:\cibw\vendor. Add C:\cibw\vendor\bin and C:\cibw\vendor\pkg-config\bin to PATH.

Note

You can change the install location by editing line 24 of the file packing/download_dlls.py.

Then set an environment variable PKG_CONFIG_PATH=C:\cibw\vendor\lib\pkgconfig.

Then you can install Cython using

pip install Cython

Finally, you can install your local ManimPango clone just like any other python package by typing:

pip install -e .

Important

You have to to use https://docs.python.org/3/library/os.html#os.add_dll_directory before running ManimPango. This is applicable for Python 3.8 and above.

import os
os.add_dll_directory('C:\cibw\vendor\bin')

Note that this is done automatically when running test suite.

Examples

Examples

Simple Example

The simplest way to render a text into a image create a new instance of Layout and then a renderer and call the Layout.render().

from manimpango import *
l = Layout("Hello World")
r = ImageRenderer(400, 400, l, "test.png")
r.render()
r.save()

This will create a 400x400 image with the text “Hello World” in it at the position (0, 0) in the image.

Calculating Bounding Box

The bounding box of the text can be obtained by calling the Layout.get_bounding_box() method. This will return a tuple of the form (x, y, width, height).

>>> from manimpango import *
>>> l = Layout("Hello World")
>>> print(l.get_bounding_box())
(0, 0, 90, 19)

The bounding box is the smallest rectangle that contains all the glyphs of the text.

Changing the Font

The font can be changed by passing a FontDescription while creating the Layout.

>>> from manimpango import *
>>> l = Layout("Hello World", font_desc=FontDescription.from_string("Arial 60"))
>>> l.render('test.png')

The font description can also be changed after the Layout has been created by setting the Layout.font_desc attribute.

Integration with other libraries

This section contains how to use ManimPango with other libraries.

Integrations

ManimPango is designed to be used with other libraries. It provides utilities for rendering text to images, but only supports rendering PNG or SVG images. For renderering to other formats, you can use various other libraries such as PIL.

Integration with Pillow

The following example shows how to create a Pillow image from a Layout object.

import manimpango as mp
from PIL import Image

layout = mp.Layout(
    "Hello World",
    font_desc=mp.FontDescription.from_string("Georgia 80")
)
bbox = layout.get_bounding_box()
renderer = mp.ImageRenderer(*bbox[2:], layout)

renderer.render()
img = Image.frombuffer(
    "RGBA",
    (renderer.width, renderer.height),
    bytes(renderer.get_buffer()),
    "raw",
    "BGRa",
    renderer.stride,
)

# Now you can save the image or open it
img.show()

Integration with NumPy

The following example shows how to create a NumPy array from a Layout object.

import manimpango as mp
import numpy as np

layout = mp.Layout(
    "Hello World",
    font_desc=mp.FontDescription.from_string("Georgia 80")
)
bbox = layout.get_bounding_box()

renderer = mp.ImageRenderer(*bbox[2:], layout)
renderer.render()

# Create a numpy array from the buffer
arr = np.ndarray(
    shape=(renderer.height, renderer.width),
    dtype=np.uint32,
    buffer=renderer.get_buffer(),
)

print(arr)

Integration with ModernGL

The following example shows how to create a ModernGL texture from a Layout object.

import manimpango as mp
import moderngl

layout = mp.Layout(
    "Hello World",
    font_desc=mp.FontDescription.from_string("Georgia 80")
)
bbox = layout.get_bounding_box()

renderer = mp.ImageRenderer(*bbox[2:], layout)
renderer.render()

# Create a ModernGL texture from the buffer
ctx = moderngl.create_standalone_context(standalone=True)
texture = ctx.texture(
    (renderer.width, renderer.height),
    4,
    renderer.get_buffer(),
)

Reference

Manimpango Reference

Text Attributes

manimpango.attributes.TextAttribute([...])

TextAttribute defines the properties/attributes of the text within a specific range of the text.

Font Description

manimpango.fonts.FontDescription([family, ...])

A FontDescription describes a font.

manimpango.fonts.enums

Contains Enums which defines text properties from Pango.

Layout

manimpango.Layout([text, markup, font_desc, ...])

A Layout class represents an entire paragraph of text.

Renderers

manimpango.renderer.SVGRenderer

SVGRenderer is a renderer which renders the Layout to an SVG file.

manimpango.renderer.ImageRenderer

ImageRenderer is a renderer which renders the Layout to an image buffer.

Exceptions

manimpango.exceptions.MarkupParseError

MarkupParseError is raised when the markup passed in invalid.

Utilities

manimpango.register_font

This function registers the font file using fontconfig so that it is available for use by Pango.

manimpango.unregister_font

This function unregisters(removes) the font file using fontconfig.

manimpango.list_fonts

Lists the fonts available to Pango.

Deprecated API

manimpango.TextSetting(start, end, font, ...)

Formatting for slices of a manim.mobject.svg.text_mobject.Text object.

manimpango.PangoUtils()

manimpango.text2svg

Render an SVG file from a manim.mobject.svg.text_mobject.Text object.

manimpango.MarkupUtils()

Changelog

Release Notes

Manimpango 1.0.0a2 (2023-04-30)

Bugfixes
  • Include *.pxi files in tarball. Without these the package cannot be installed from source.

  • Raise on invalid string passed to FontDescriptor constructor. Previously, it silently crashed.

Manimpango 1.0.0a1 (2023-04-29)

Features
  • The package has undergone a complete rewrite to offer an improved API. The new API provides a greater degree of consistency and flexibility compared to its predecessor. (#28)

Developer documentation

Release Procedure

This is the maintainer note on how to Release. All versioning is in accordance to Semantic Versioning 2.0.0. This means older version would have a backport of bugs fixes.

  1. Check whether the test suite passes on the main branch.

  2. Revert any changes which seems to be not working, and check for the milestone if PR are merged accordingly.

  3. Check whether the Wheels Build, against the main branch works as expected.

  4. Clone the repository locally.

  5. Bump the version in manimpango/_version accordingly.

  6. Generate the changelog using towncrier.

towncrier
  1. Make a commit with the changes done, as Release v<version here>

  2. Create a tag, locally with

git tag -s v<version-number>

Note

Here, -s is used to sign the tag with gpg so that users can later verify it, and a tag shouldn’t be created with signing because Github shows it unverified.

Important

The message should include the changelog of the release. There is a github actions which will creates a draft release with the changelog. You can edit them and copy it to the tag you create.

  1. Push the tag to remote.

  2. Go to Github, and draft a new release with the same tag pushed. You can copy the same changelog you copied when you created the tag.

Important

You should actually “draft a new release” instead of just publishing a previously present draft release created by the Github Action. This is important so that the wheels build workflow triggers.

  1. Check whether the CI uploads the wheels and the .tar.gz file to PyPi.

  2. Finally, test the .tar.gz which was uploaded to PyPi, and install it in a new virtual environment.