diff --git a/Tests/fonts/LICENSE.txt b/Tests/fonts/LICENSE.txt
index 528eed9ef..538862b97 100644
--- a/Tests/fonts/LICENSE.txt
+++ b/Tests/fonts/LICENSE.txt
@@ -9,6 +9,7 @@ ter-x20b.pcf, from http://terminus-font.sourceforge.net/
All of the above fonts are published under the SIL Open Font License (OFL) v1.1 (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL), which allows you to copy, modify, and redistribute them if you need to.
+OpenSansCondensed-LightItalic.tt, from https://fonts.google.com/specimen/Open+Sans, under Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
10x20-ISO8859-1.pcf, from https://packages.ubuntu.com/xenial/xfonts-base
diff --git a/Tests/fonts/OpenSansCondensed-LightItalic.ttf b/Tests/fonts/OpenSansCondensed-LightItalic.ttf
new file mode 100644
index 000000000..b4ee4951f
Binary files /dev/null and b/Tests/fonts/OpenSansCondensed-LightItalic.ttf differ
diff --git a/Tests/images/test_anchor_multiline_lm_center.png b/Tests/images/test_anchor_multiline_lm_center.png
new file mode 100644
index 000000000..6fff287e4
Binary files /dev/null and b/Tests/images/test_anchor_multiline_lm_center.png differ
diff --git a/Tests/images/test_anchor_multiline_lm_left.png b/Tests/images/test_anchor_multiline_lm_left.png
new file mode 100644
index 000000000..b76a81b81
Binary files /dev/null and b/Tests/images/test_anchor_multiline_lm_left.png differ
diff --git a/Tests/images/test_anchor_multiline_lm_right.png b/Tests/images/test_anchor_multiline_lm_right.png
new file mode 100644
index 000000000..c12a8d63e
Binary files /dev/null and b/Tests/images/test_anchor_multiline_lm_right.png differ
diff --git a/Tests/images/test_anchor_multiline_ma_center.png b/Tests/images/test_anchor_multiline_ma_center.png
new file mode 100644
index 000000000..4f35d781f
Binary files /dev/null and b/Tests/images/test_anchor_multiline_ma_center.png differ
diff --git a/Tests/images/test_anchor_multiline_md_center.png b/Tests/images/test_anchor_multiline_md_center.png
new file mode 100644
index 000000000..8290d045c
Binary files /dev/null and b/Tests/images/test_anchor_multiline_md_center.png differ
diff --git a/Tests/images/test_anchor_multiline_mm_center.png b/Tests/images/test_anchor_multiline_mm_center.png
new file mode 100644
index 000000000..773cf2a4a
Binary files /dev/null and b/Tests/images/test_anchor_multiline_mm_center.png differ
diff --git a/Tests/images/test_anchor_multiline_mm_left.png b/Tests/images/test_anchor_multiline_mm_left.png
new file mode 100644
index 000000000..87d56636a
Binary files /dev/null and b/Tests/images/test_anchor_multiline_mm_left.png differ
diff --git a/Tests/images/test_anchor_multiline_mm_right.png b/Tests/images/test_anchor_multiline_mm_right.png
new file mode 100644
index 000000000..cf002b12c
Binary files /dev/null and b/Tests/images/test_anchor_multiline_mm_right.png differ
diff --git a/Tests/images/test_anchor_multiline_rm_center.png b/Tests/images/test_anchor_multiline_rm_center.png
new file mode 100644
index 000000000..98073144b
Binary files /dev/null and b/Tests/images/test_anchor_multiline_rm_center.png differ
diff --git a/Tests/images/test_anchor_multiline_rm_left.png b/Tests/images/test_anchor_multiline_rm_left.png
new file mode 100644
index 000000000..838fd7858
Binary files /dev/null and b/Tests/images/test_anchor_multiline_rm_left.png differ
diff --git a/Tests/images/test_anchor_multiline_rm_right.png b/Tests/images/test_anchor_multiline_rm_right.png
new file mode 100644
index 000000000..290f58417
Binary files /dev/null and b/Tests/images/test_anchor_multiline_rm_right.png differ
diff --git a/Tests/images/test_combine_multiline_lm_center.png b/Tests/images/test_combine_multiline_lm_center.png
new file mode 100644
index 000000000..02d28b27a
Binary files /dev/null and b/Tests/images/test_combine_multiline_lm_center.png differ
diff --git a/Tests/images/test_combine_multiline_lm_left.png b/Tests/images/test_combine_multiline_lm_left.png
new file mode 100644
index 000000000..461483d00
Binary files /dev/null and b/Tests/images/test_combine_multiline_lm_left.png differ
diff --git a/Tests/images/test_combine_multiline_lm_right.png b/Tests/images/test_combine_multiline_lm_right.png
new file mode 100644
index 000000000..7cba6415f
Binary files /dev/null and b/Tests/images/test_combine_multiline_lm_right.png differ
diff --git a/Tests/images/test_combine_multiline_mm_center.png b/Tests/images/test_combine_multiline_mm_center.png
new file mode 100644
index 000000000..dfb6b7b39
Binary files /dev/null and b/Tests/images/test_combine_multiline_mm_center.png differ
diff --git a/Tests/images/test_combine_multiline_mm_left.png b/Tests/images/test_combine_multiline_mm_left.png
new file mode 100644
index 000000000..1571cf155
Binary files /dev/null and b/Tests/images/test_combine_multiline_mm_left.png differ
diff --git a/Tests/images/test_combine_multiline_mm_right.png b/Tests/images/test_combine_multiline_mm_right.png
new file mode 100644
index 000000000..3e88d218a
Binary files /dev/null and b/Tests/images/test_combine_multiline_mm_right.png differ
diff --git a/Tests/images/test_combine_multiline_rm_center.png b/Tests/images/test_combine_multiline_rm_center.png
new file mode 100644
index 000000000..7c743f228
Binary files /dev/null and b/Tests/images/test_combine_multiline_rm_center.png differ
diff --git a/Tests/images/test_combine_multiline_rm_left.png b/Tests/images/test_combine_multiline_rm_left.png
new file mode 100644
index 000000000..8aae219d3
Binary files /dev/null and b/Tests/images/test_combine_multiline_rm_left.png differ
diff --git a/Tests/images/test_combine_multiline_rm_right.png b/Tests/images/test_combine_multiline_rm_right.png
new file mode 100644
index 000000000..b5f7f0397
Binary files /dev/null and b/Tests/images/test_combine_multiline_rm_right.png differ
diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py
index 37587a0da..e58945524 100644
--- a/Tests/test_imagefont.py
+++ b/Tests/test_imagefont.py
@@ -34,9 +34,24 @@ class TestImageFont:
# Freetype has different metrics depending on the version.
# (and, other things, but first things first)
METRICS = {
- (">=2.3", "<2.4"): {"multiline": 30, "textsize": 12, "getters": (12, 16)},
- (">=2.7",): {"multiline": 6.2, "textsize": 2.5, "getters": (12, 16)},
- "Default": {"multiline": 0.5, "textsize": 0.5, "getters": (12, 16)},
+ (">=2.3", "<2.4"): {
+ "multiline": 30,
+ "textsize": 12,
+ "multiline-anchor": 6,
+ "getlength": (36, 27, 27, 33),
+ },
+ (">=2.7",): {
+ "multiline": 6.2,
+ "textsize": 2.5,
+ "multiline-anchor": 4,
+ "getlength": (36, 21, 24, 33),
+ },
+ "Default": {
+ "multiline": 0.5,
+ "textsize": 0.5,
+ "multiline-anchor": 4,
+ "getlength": (36, 24, 24, 33),
+ },
}
@classmethod
@@ -179,6 +194,34 @@ class TestImageFont:
# Epsilon ~.5 fails with FreeType 2.7
assert_image_similar(im, target_img, self.metrics["textsize"])
+ @pytest.mark.parametrize(
+ "text,mode,font,size,length_basic_index,length_raqm",
+ (
+ # basic test
+ ("text", "L", "FreeMono.ttf", 15, 0, 36),
+ ("text", "1", "FreeMono.ttf", 15, 0, 36),
+ # issue 4177
+ ("rrr", "L", "DejaVuSans.ttf", 18, 1, 22.21875),
+ ("rrr", "1", "DejaVuSans.ttf", 18, 2, 22.21875),
+ # test 'l' not including extra margin
+ # using exact value 2047 / 64 for raqm, checked with debugger
+ ("ill", "L", "OpenSansCondensed-LightItalic.ttf", 63, 3, 31.984375),
+ ("ill", "1", "OpenSansCondensed-LightItalic.ttf", 63, 3, 31.984375),
+ ),
+ )
+ def test_getlength(self, text, mode, font, size, length_basic_index, length_raqm):
+ f = ImageFont.truetype(
+ "Tests/fonts/" + font, size, layout_engine=self.LAYOUT_ENGINE
+ )
+
+ if self.LAYOUT_ENGINE == ImageFont.LAYOUT_BASIC:
+ length = f.getlength(text, mode)
+ assert length == self.metrics["getlength"][length_basic_index]
+ else:
+ # disable kerning, kerning metrics changed
+ length = f.getlength(text, mode, features=["-kern"])
+ assert length == length_raqm
+
def test_render_multiline(self):
im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im)
@@ -581,7 +624,7 @@ class TestImageFont:
assert t.font.glyphs == 4177
assert t.getsize("A") == (12, 16)
assert t.getsize("AB") == (24, 16)
- assert t.getsize("M") == self.metrics["getters"]
+ assert t.getsize("M") == (12, 16)
assert t.getsize("y") == (12, 20)
assert t.getsize("a") == (12, 16)
assert t.getsize_multiline("A") == (12, 16)
@@ -735,35 +778,87 @@ class TestImageFont:
self._check_text(font, "Tests/images/variation_tiny_axes.png", 32.5)
@pytest.mark.parametrize(
- "name,text,anchor",
+ "anchor,left,left_raqm,top",
(
# test horizontal anchors
- ("quick", "Quick", "ls"),
- ("quick", "Quick", "ms"),
- ("quick", "Quick", "rs"),
+ ("ls", 0, 0, -36),
+ ("ms", -64, -65, -36),
+ ("rs", -128, -129, -36),
# test vertical anchors
- ("quick", "Quick", "ma"),
- ("quick", "Quick", "mt"),
- ("quick", "Quick", "mm"),
- ("quick", "Quick", "mb"),
- ("quick", "Quick", "md"),
+ ("ma", -64, -65, 16),
+ ("mt", -64, -65, 0),
+ ("mm", -64, -65, -17),
+ ("mb", -64, -65, -44),
+ ("md", -64, -65, -51),
),
)
- def test_anchor(self, name, text, anchor):
- path = "Tests/images/test_anchor_%s_%s.png" % (name, anchor)
+ def test_anchor(self, anchor, left, left_raqm, top):
+ name, text = "quick", "Quick"
+ target = "Tests/images/test_anchor_%s_%s.png" % (name, anchor)
+ freetype = distutils.version.StrictVersion(ImageFont.core.freetype2_version)
+
+ if self.LAYOUT_ENGINE == ImageFont.LAYOUT_RAQM or freetype < "2.4":
+ width, height = (129, 44)
+ left = left_raqm
+ else:
+ width, height = (128, 44)
+
f = ImageFont.truetype(
"Tests/fonts/NotoSans-Regular.ttf", 48, layout_engine=self.LAYOUT_ENGINE
)
+ # test getbbox
+ assert f.getbbox(text, anchor=anchor) == (left, top, left + width, top + height)
+
+ # test render
im = Image.new("RGB", (200, 200), "white")
d = ImageDraw.Draw(im)
d.line(((0, 100), (200, 100)), "gray")
d.line(((100, 0), (100, 200)), "gray")
d.text((100, 100), text, fill="black", anchor=anchor, font=f)
- with Image.open(path) as expected:
+ with Image.open(target) as expected:
assert_image_similar(im, expected, 7)
+ @pytest.mark.parametrize(
+ "anchor,align",
+ (
+ # test horizontal anchors
+ ("lm", "left"),
+ ("lm", "center"),
+ ("lm", "right"),
+ ("mm", "left"),
+ ("mm", "center"),
+ ("mm", "right"),
+ ("rm", "left"),
+ ("rm", "center"),
+ ("rm", "right"),
+ # test vertical anchors
+ ("ma", "center"),
+ # ("mm", "center"),
+ ("md", "center"),
+ ),
+ )
+ def test_anchor_multiline(self, anchor, align):
+ target = "Tests/images/test_anchor_multiline_%s_%s.png" % (anchor, align)
+ text = "a\nlong\ntext sample"
+
+ f = ImageFont.truetype(
+ "Tests/fonts/NotoSans-Regular.ttf", 48, layout_engine=self.LAYOUT_ENGINE
+ )
+
+ # test render
+ im = Image.new("RGB", (600, 400), "white")
+ d = ImageDraw.Draw(im)
+ d.line(((0, 200), (600, 200)), "gray")
+ d.line(((300, 0), (300, 400)), "gray")
+ d.multiline_text(
+ (300, 200), text, fill="black", anchor=anchor, font=f, align=align
+ )
+
+ with Image.open(target) as expected:
+ assert_image_similar(im, expected, self.metrics["multiline-anchor"])
+
@skip_unless_feature("raqm")
class TestImageFont_RaqmLayout(TestImageFont):
diff --git a/Tests/test_imagefontctl.py b/Tests/test_imagefontctl.py
index 0abd681fe..85f9cdc20 100644
--- a/Tests/test_imagefontctl.py
+++ b/Tests/test_imagefontctl.py
@@ -209,6 +209,57 @@ def test_language():
assert_image_similar(im, target_img, 0.5)
+@pytest.mark.parametrize("mode", ("L", "1"))
+@pytest.mark.parametrize(
+ "text,direction,expected",
+ (
+ ("سلطنة عمان Oman", None, 173.703125),
+ ("سلطنة عمان Oman", "ltr", 173.703125),
+ ("Oman سلطنة عمان", "rtl", 173.703125),
+ ("English عربي", "rtl", 123.796875),
+ ("test", "ttb", 80.0),
+ ),
+ ids=("None", "ltr", "rtl2", "rtl", "ttb"),
+)
+def test_getlength(mode, text, direction, expected):
+ try:
+ ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
+
+ assert ttf.getlength(text, mode, direction) == expected
+ except ValueError as ex:
+ if (
+ direction == "ttb"
+ and str(ex) == "libraqm 0.7 or greater required for 'ttb' direction"
+ ):
+ pytest.skip("libraqm 0.7 or greater not available")
+
+
+@pytest.mark.parametrize("mode", ("L", "1"))
+@pytest.mark.parametrize("direction", ("ltr", "ttb"))
+@pytest.mark.parametrize(
+ "text",
+ ("i" + ("\u030C" * 15) + "i", "i" + "\u032C" * 15 + "i", "\u035Cii", "i\u0305i"),
+ ids=("caron-above", "caron-below", "double-breve", "overline"),
+)
+def test_getlength_combine(mode, direction, text):
+ if text == "i\u0305i" and direction == "ttb":
+ pytest.skip("fails with this font")
+
+ ttf = ImageFont.truetype("Tests/fonts/NotoSans-Regular.ttf", 48)
+
+ try:
+ target = ttf.getlength("ii", mode, direction)
+ actual = ttf.getlength(text, mode, direction)
+
+ assert actual == target
+ except ValueError as ex:
+ if (
+ direction == "ttb"
+ and str(ex) == "libraqm 0.7 or greater required for 'ttb' direction"
+ ):
+ pytest.skip("libraqm 0.7 or greater not available")
+
+
@pytest.mark.parametrize("anchor", ("lt", "mm", "rb", "sm"))
def test_anchor_ttb(anchor):
if distutils.version.StrictVersion(ImageFont.core.freetype2_version) < "2.5.1":
@@ -291,8 +342,42 @@ def test_combine(name, text, dir, anchor, epsilon):
try:
d.text((200, 200), text, fill="black", anchor=anchor, direction=dir, font=f)
except ValueError as ex:
- if str(ex) == "libraqm 0.7 or greater required for 'ttb' direction":
+ if (
+ dir == "ttb"
+ and str(ex) == "libraqm 0.7 or greater required for 'ttb' direction"
+ ):
pytest.skip("libraqm 0.7 or greater not available")
with Image.open(path) as expected:
assert_image_similar(im, expected, epsilon)
+
+
+@pytest.mark.parametrize(
+ "anchor,align",
+ (
+ ("lm", "left"), # pass with getsize
+ ("lm", "center"), # fail at 2.12
+ ("lm", "right"), # fail at 2.57
+ ("mm", "left"), # fail at 2.12
+ ("mm", "center"), # pass with getsize
+ ("mm", "right"), # fail at 2.12
+ ("rm", "left"), # fail at 2.57
+ ("rm", "center"), # fail at 2.12
+ ("rm", "right"), # pass with getsize
+ ),
+)
+def test_combine_multiline(anchor, align):
+ # test that multiline text uses getline, not getsize or getbbox
+
+ path = "Tests/images/test_combine_multiline_%s_%s.png" % (anchor, align)
+ f = ImageFont.truetype("Tests/fonts/NotoSans-Regular.ttf", 48)
+ text = "i\u0305\u035C\ntext" # i with overline and double breve, and a word
+
+ im = Image.new("RGB", (400, 400), "white")
+ d = ImageDraw.Draw(im)
+ d.line(((0, 200), (400, 200)), "gray")
+ d.line(((200, 0), (200, 400)), "gray")
+ d.multiline_text((200, 200), text, fill="black", anchor=anchor, font=f, align=align)
+
+ with Image.open(path) as expected:
+ assert_image_similar(im, expected, 0.015)
diff --git a/src/PIL/ImageDraw.py b/src/PIL/ImageDraw.py
index 07b3a640d..bef0d7964 100644
--- a/src/PIL/ImageDraw.py
+++ b/src/PIL/ImageDraw.py
@@ -379,6 +379,9 @@ class ImageDraw:
elif anchor[1] in "tb":
raise ValueError("anchor not supported for multiline text")
+ if font is None:
+ font = self.getfont()
+
widths = []
max_width = 0
lines = self._multiline_split(text)
@@ -386,13 +389,12 @@ class ImageDraw:
self.textsize("A", font=font, stroke_width=stroke_width)[1] + spacing
)
for line in lines:
- line_width, line_height = self.textsize(
+ line_width = font.getlength(
line,
- font,
+ self.fontmode,
direction=direction,
features=features,
language=language,
- stroke_width=stroke_width,
)
widths.append(line_width)
max_width = max(max_width, line_width)
diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py
index 5612270d4..533f239c4 100644
--- a/src/PIL/ImageFont.py
+++ b/src/PIL/ImageFont.py
@@ -215,6 +215,113 @@ class FreeTypeFont:
"""
return self.font.ascent, self.font.descent
+ def getlength(self, text, mode="", direction=None, features=None, language=None):
+ """
+ Returns length (in pixels) of given text if rendered in font with
+ provided direction, features, and language.
+
+ This is the amount by which following text should be offset.
+ Text bounding box may extend past the length in some fonts,
+ e.g. when using italics or accents.
+
+ The result is returned as a float; it is a whole number if using basic layout.
+
+ :param text: Text to measure.
+ :param mode: Used by some graphics drivers to indicate what mode the
+ driver prefers; if empty, the renderer may return either
+ mode. Note that the mode is always a string, to simplify
+ C-level implementations.
+
+ :param direction: Direction of the text. It can be 'rtl' (right to
+ left), 'ltr' (left to right) or 'ttb' (top to bottom).
+ Requires libraqm.
+
+ :param features: A list of OpenType font features to be used during text
+ layout. This is usually used to turn on optional
+ font features that are not enabled by default,
+ for example 'dlig' or 'ss01', but can be also
+ used to turn off default font features for
+ example '-liga' to disable ligatures or '-kern'
+ to disable kerning. To get all supported
+ features, see
+ https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
+ Requires libraqm.
+
+ :param language: Language of the text. Different languages may use
+ different glyph shapes or ligatures. This parameter tells
+ the font which language the text is in, and to apply the
+ correct substitutions as appropriate, if available.
+ It should be a `BCP 47 language code
+ `
+ Requires libraqm.
+
+ :return: Width for horizontal, height for vertical text.
+ """
+ return (
+ self.font.getlength(text, mode == "1", direction, features, language) / 64
+ )
+
+ def getbbox(
+ self,
+ text,
+ mode="",
+ direction=None,
+ features=None,
+ language=None,
+ stroke_width=0,
+ anchor=None,
+ ):
+ """
+ Returns bounding box (in pixels) of given text relative to given anchor
+ if rendered in font with provided direction, features, and language.
+
+ Use :py:func`getlength()` to get the offset of following text. The bounding
+ box includes extra margins for some fonts, e.g. italics or accents.
+
+ :param text: Text to render.
+ :param mode: Used by some graphics drivers to indicate what mode the
+ driver prefers; if empty, the renderer may return either
+ mode. Note that the mode is always a string, to simplify
+ C-level implementations.
+
+ :param direction: Direction of the text. It can be 'rtl' (right to
+ left), 'ltr' (left to right) or 'ttb' (top to bottom).
+ Requires libraqm.
+
+ :param features: A list of OpenType font features to be used during text
+ layout. This is usually used to turn on optional
+ font features that are not enabled by default,
+ for example 'dlig' or 'ss01', but can be also
+ used to turn off default font features for
+ example '-liga' to disable ligatures or '-kern'
+ to disable kerning. To get all supported
+ features, see
+ https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist
+ Requires libraqm.
+
+ :param language: Language of the text. Different languages may use
+ different glyph shapes or ligatures. This parameter tells
+ the font which language the text is in, and to apply the
+ correct substitutions as appropriate, if available.
+ It should be a `BCP 47 language code
+ `
+ Requires libraqm.
+
+ :param stroke_width: The width of the text stroke.
+
+ :param anchor: The text anchor alignment. Determines the relative location of
+ the anchor to the text. The default alignment is top left.
+ See :ref:`text-anchors` for valid values.
+
+ :return: ``(left, top, right, bottom)`` bounding box
+ """
+ size, offset = self.font.getsize(
+ text, mode == "1", direction, features, language, anchor
+ )
+ left, top = offset[0] - stroke_width, offset[1] - stroke_width
+ width, height = size[0] + stroke_width, size[1] + stroke_width
+ return left, top, left + width, top + height
+
def getsize(
self, text, direction=None, features=None, language=None, stroke_width=0
):
@@ -222,6 +329,9 @@ class FreeTypeFont:
Returns width and height (in pixels) of given text if rendered in font with
provided direction, features, and language.
+ Use :py:func:`getlength()` to measure the offset of following text.
+ Use :py:func:`getbbox()` to get the exact bounding box based on an anchor.
+
:param text: Text to measure.
:param direction: Direction of the text. It can be 'rtl' (right to
diff --git a/src/_imagingft.c b/src/_imagingft.c
index ac4e28ebc..4e60de5c5 100644
--- a/src/_imagingft.c
+++ b/src/_imagingft.c
@@ -607,6 +607,50 @@ text_layout(PyObject* string, FontObject* self, const char* dir, PyObject *featu
return count;
}
+static PyObject*
+font_getlength(FontObject* self, PyObject* args)
+{
+ int length;
+ FT_Face face;
+ int horizontal_dir;
+ int mask = 0;
+ const char *dir = NULL;
+ const char *lang = NULL;
+ size_t i, count;
+ GlyphInfo *glyph_info = NULL;
+ PyObject *features = Py_None;
+
+ /* calculate size and bearing for a given string */
+
+ PyObject* string;
+ if (!PyArg_ParseTuple(args, "O|izOz:getlength", &string, &mask, &dir, &features, &lang)) {
+ return NULL;
+ }
+
+ horizontal_dir = dir && strcmp(dir, "ttb") == 0 ? 0 : 1;
+
+ count = text_layout(string, self, dir, features, lang, &glyph_info, mask);
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+
+ length = 0;
+ for (i = 0; i < count; i++) {
+ if (horizontal_dir) {
+ length += glyph_info[i].x_advance;
+ } else {
+ length -= glyph_info[i].y_advance;
+ }
+ }
+
+ if (glyph_info) {
+ PyMem_Free(glyph_info);
+ glyph_info = NULL;
+ }
+
+ return PyLong_FromLong(length);
+}
+
static PyObject*
font_getsize(FontObject* self, PyObject* args)
{
@@ -1169,6 +1213,7 @@ font_dealloc(FontObject* self)
static PyMethodDef font_methods[] = {
{"render", (PyCFunction) font_render, METH_VARARGS},
{"getsize", (PyCFunction) font_getsize, METH_VARARGS},
+ {"getlength", (PyCFunction) font_getlength, METH_VARARGS},
#if FREETYPE_MAJOR > 2 ||\
(FREETYPE_MAJOR == 2 && FREETYPE_MINOR > 9) ||\
(FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 9 && FREETYPE_PATCH == 1)