mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-25 09:26:16 +03:00
add color support to new text measuring functions
This commit is contained in:
parent
90e8255ba4
commit
d7a08cbd15
|
@ -513,7 +513,7 @@ Methods
|
||||||
|
|
||||||
.. versionadded:: 6.2.0
|
.. versionadded:: 6.2.0
|
||||||
|
|
||||||
.. py:method:: ImageDraw.textlength(text, font=None, direction=None, features=None, language=None)
|
.. py:method:: ImageDraw.textlength(text, font=None, direction=None, features=None, language=None, embedded_color=False)
|
||||||
|
|
||||||
Returns length (in pixels with 1/64 precision) of given text when rendered
|
Returns length (in pixels with 1/64 precision) of given text when rendered
|
||||||
in font with provided direction, features, and language.
|
in font with provided direction, features, and language.
|
||||||
|
@ -577,8 +577,9 @@ Methods
|
||||||
correct substitutions as appropriate, if available.
|
correct substitutions as appropriate, if available.
|
||||||
It should be a `BCP 47 language code`_.
|
It should be a `BCP 47 language code`_.
|
||||||
Requires libraqm.
|
Requires libraqm.
|
||||||
|
:param embedded_color: Whether to use font embedded color glyphs (COLR or CBDT).
|
||||||
|
|
||||||
.. py:method:: ImageDraw.textbbox(xy, text, font=None, anchor=None, spacing=4, align="left", direction=None, features=None, language=None, stroke_width=0)
|
.. py:method:: ImageDraw.textbbox(xy, text, font=None, anchor=None, spacing=4, align="left", direction=None, features=None, language=None, stroke_width=0, embedded_color=False)
|
||||||
|
|
||||||
Returns bounding box (in pixels) of given text relative to given anchor
|
Returns bounding box (in pixels) of given text relative to given anchor
|
||||||
when rendered in font with provided direction, features, and language.
|
when rendered in font with provided direction, features, and language.
|
||||||
|
@ -625,8 +626,9 @@ Methods
|
||||||
It should be a `BCP 47 language code`_.
|
It should be a `BCP 47 language code`_.
|
||||||
Requires libraqm.
|
Requires libraqm.
|
||||||
:param stroke_width: The width of the text stroke.
|
:param stroke_width: The width of the text stroke.
|
||||||
|
:param embedded_color: Whether to use font embedded color glyphs (COLR or CBDT).
|
||||||
|
|
||||||
.. py:method:: ImageDraw.multiline_textbbox(xy, text, font=None, anchor=None, spacing=4, align="left", direction=None, features=None, language=None, stroke_width=0)
|
.. py:method:: ImageDraw.multiline_textbbox(xy, text, font=None, anchor=None, spacing=4, align="left", direction=None, features=None, language=None, stroke_width=0, embedded_color=False)
|
||||||
|
|
||||||
Returns bounding box (in pixels) of given text relative to given anchor
|
Returns bounding box (in pixels) of given text relative to given anchor
|
||||||
when rendered in font with provided direction, features, and language.
|
when rendered in font with provided direction, features, and language.
|
||||||
|
@ -667,6 +669,7 @@ Methods
|
||||||
It should be a `BCP 47 language code`_.
|
It should be a `BCP 47 language code`_.
|
||||||
Requires libraqm.
|
Requires libraqm.
|
||||||
:param stroke_width: The width of the text stroke.
|
:param stroke_width: The width of the text stroke.
|
||||||
|
:param embedded_color: Whether to use font embedded color glyphs (COLR or CBDT).
|
||||||
|
|
||||||
.. py:method:: getdraw(im=None, hints=None)
|
.. py:method:: getdraw(im=None, hints=None)
|
||||||
|
|
||||||
|
|
|
@ -500,15 +500,26 @@ class ImageDraw:
|
||||||
max_width = max(max_width, line_width)
|
max_width = max(max_width, line_width)
|
||||||
return max_width, len(lines) * line_spacing - spacing
|
return max_width, len(lines) * line_spacing - spacing
|
||||||
|
|
||||||
def textlength(self, text, font=None, direction=None, features=None, language=None):
|
def textlength(
|
||||||
|
self,
|
||||||
|
text,
|
||||||
|
font=None,
|
||||||
|
direction=None,
|
||||||
|
features=None,
|
||||||
|
language=None,
|
||||||
|
embedded_color=False,
|
||||||
|
):
|
||||||
"""Get the length of a given string, in pixels with 1/64 precision."""
|
"""Get the length of a given string, in pixels with 1/64 precision."""
|
||||||
if self._multiline_check(text):
|
if self._multiline_check(text):
|
||||||
raise ValueError("can't measure length of multiline text")
|
raise ValueError("can't measure length of multiline text")
|
||||||
|
if embedded_color and self.mode not in ("RGB", "RGBA"):
|
||||||
|
raise ValueError("Embedded color supported only in RGB and RGBA modes")
|
||||||
|
|
||||||
if font is None:
|
if font is None:
|
||||||
font = self.getfont()
|
font = self.getfont()
|
||||||
|
mode = "RGBA" if embedded_color else self.fontmode
|
||||||
try:
|
try:
|
||||||
return font.getlength(text, self.fontmode, direction, features, language)
|
return font.getlength(text, mode, direction, features, language)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
size = self.textsize(
|
size = self.textsize(
|
||||||
text, font, direction=direction, features=features, language=language
|
text, font, direction=direction, features=features, language=language
|
||||||
|
@ -529,8 +540,12 @@ class ImageDraw:
|
||||||
features=None,
|
features=None,
|
||||||
language=None,
|
language=None,
|
||||||
stroke_width=0,
|
stroke_width=0,
|
||||||
|
embedded_color=False,
|
||||||
):
|
):
|
||||||
"""Get the bounding box of a given string, in pixels."""
|
"""Get the bounding box of a given string, in pixels."""
|
||||||
|
if embedded_color and self.mode not in ("RGB", "RGBA"):
|
||||||
|
raise ValueError("Embedded color supported only in RGB and RGBA modes")
|
||||||
|
|
||||||
if self._multiline_check(text):
|
if self._multiline_check(text):
|
||||||
return self.multiline_textbbox(
|
return self.multiline_textbbox(
|
||||||
xy,
|
xy,
|
||||||
|
@ -543,12 +558,14 @@ class ImageDraw:
|
||||||
features,
|
features,
|
||||||
language,
|
language,
|
||||||
stroke_width,
|
stroke_width,
|
||||||
|
embedded_color,
|
||||||
)
|
)
|
||||||
|
|
||||||
if font is None:
|
if font is None:
|
||||||
font = self.getfont()
|
font = self.getfont()
|
||||||
|
mode = "RGBA" if embedded_color else self.fontmode
|
||||||
bbox = font.getbbox(
|
bbox = font.getbbox(
|
||||||
text, self.fontmode, direction, features, language, stroke_width, anchor
|
text, mode, direction, features, language, stroke_width, anchor
|
||||||
)
|
)
|
||||||
return bbox[0] + xy[0], bbox[1] + xy[1], bbox[2] + xy[0], bbox[3] + xy[1]
|
return bbox[0] + xy[0], bbox[1] + xy[1], bbox[2] + xy[0], bbox[3] + xy[1]
|
||||||
|
|
||||||
|
@ -564,6 +581,7 @@ class ImageDraw:
|
||||||
features=None,
|
features=None,
|
||||||
language=None,
|
language=None,
|
||||||
stroke_width=0,
|
stroke_width=0,
|
||||||
|
embedded_color=False,
|
||||||
):
|
):
|
||||||
if direction == "ttb":
|
if direction == "ttb":
|
||||||
raise ValueError("ttb direction is unsupported for multiline text")
|
raise ValueError("ttb direction is unsupported for multiline text")
|
||||||
|
@ -583,7 +601,12 @@ class ImageDraw:
|
||||||
)
|
)
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line_width = self.textlength(
|
line_width = self.textlength(
|
||||||
line, font, direction=direction, features=features, language=language
|
line,
|
||||||
|
font,
|
||||||
|
direction=direction,
|
||||||
|
features=features,
|
||||||
|
language=language,
|
||||||
|
embedded_color=embedded_color,
|
||||||
)
|
)
|
||||||
widths.append(line_width)
|
widths.append(line_width)
|
||||||
max_width = max(max_width, line_width)
|
max_width = max(max_width, line_width)
|
||||||
|
@ -625,6 +648,7 @@ class ImageDraw:
|
||||||
features=features,
|
features=features,
|
||||||
language=language,
|
language=language,
|
||||||
stroke_width=stroke_width,
|
stroke_width=stroke_width,
|
||||||
|
embedded_color=embedded_color,
|
||||||
)
|
)
|
||||||
if bbox is None:
|
if bbox is None:
|
||||||
bbox = bbox_line
|
bbox = bbox_line
|
||||||
|
|
|
@ -290,9 +290,7 @@ class FreeTypeFont:
|
||||||
|
|
||||||
:return: Width for horizontal, height for vertical text.
|
:return: Width for horizontal, height for vertical text.
|
||||||
"""
|
"""
|
||||||
return (
|
return self.font.getlength(text, mode, direction, features, language) / 64
|
||||||
self.font.getlength(text, mode == "1", direction, features, language) / 64
|
|
||||||
)
|
|
||||||
|
|
||||||
def getbbox(
|
def getbbox(
|
||||||
self,
|
self,
|
||||||
|
@ -352,7 +350,7 @@ class FreeTypeFont:
|
||||||
:return: ``(left, top, right, bottom)`` bounding box
|
:return: ``(left, top, right, bottom)`` bounding box
|
||||||
"""
|
"""
|
||||||
size, offset = self.font.getsize(
|
size, offset = self.font.getsize(
|
||||||
text, mode == "1", direction, features, language, anchor
|
text, mode, direction, features, language, anchor
|
||||||
)
|
)
|
||||||
left, top = offset[0] - stroke_width, offset[1] - stroke_width
|
left, top = offset[0] - stroke_width, offset[1] - stroke_width
|
||||||
width, height = size[0] + 2 * stroke_width, size[1] + 2 * stroke_width
|
width, height = size[0] + 2 * stroke_width, size[1] + 2 * stroke_width
|
||||||
|
|
|
@ -624,6 +624,8 @@ font_getlength(FontObject* self, PyObject* args)
|
||||||
size_t i, count; /* glyph_info index and length */
|
size_t i, count; /* glyph_info index and length */
|
||||||
int horizontal_dir; /* is primary axis horizontal? */
|
int horizontal_dir; /* is primary axis horizontal? */
|
||||||
int mask = 0; /* is FT_LOAD_TARGET_MONO enabled? */
|
int mask = 0; /* is FT_LOAD_TARGET_MONO enabled? */
|
||||||
|
int color = 0; /* is FT_LOAD_COLOR enabled? */
|
||||||
|
const char *mode = NULL;
|
||||||
const char *dir = NULL;
|
const char *dir = NULL;
|
||||||
const char *lang = NULL;
|
const char *lang = NULL;
|
||||||
PyObject *features = Py_None;
|
PyObject *features = Py_None;
|
||||||
|
@ -631,13 +633,16 @@ font_getlength(FontObject* self, PyObject* args)
|
||||||
|
|
||||||
/* calculate size and bearing for a given string */
|
/* calculate size and bearing for a given string */
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O|izOz:getlength", &string, &mask, &dir, &features, &lang)) {
|
if (!PyArg_ParseTuple(args, "O|zzOz:getlength", &string, &mode, &dir, &features, &lang)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
horizontal_dir = dir && strcmp(dir, "ttb") == 0 ? 0 : 1;
|
horizontal_dir = dir && strcmp(dir, "ttb") == 0 ? 0 : 1;
|
||||||
|
|
||||||
count = text_layout(string, self, dir, features, lang, &glyph_info, mask);
|
mask = mode && strcmp(mode, "1") == 0;
|
||||||
|
color = mode && strcmp(mode, "RGBA") == 0;
|
||||||
|
|
||||||
|
count = text_layout(string, self, dir, features, lang, &glyph_info, mask, color);
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user