mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-10 19:56:47 +03:00
Added byte support to FreeTypeFont
This commit is contained in:
parent
cdd2bbe95e
commit
b3e3784b8e
|
@ -1096,6 +1096,23 @@ def test_too_many_characters(font: ImageFont.FreeTypeFont) -> None:
|
|||
imagefont.getmask("A" * 1_000_001)
|
||||
|
||||
|
||||
def test_bytes(font: ImageFont.FreeTypeFont) -> None:
|
||||
assert font.getlength(b"test") == font.getlength("test")
|
||||
|
||||
assert font.getbbox(b"test") == font.getbbox("test")
|
||||
|
||||
assert_image_equal(
|
||||
Image.Image()._new(font.getmask(b"test")),
|
||||
Image.Image()._new(font.getmask("test")),
|
||||
)
|
||||
|
||||
assert_image_equal(
|
||||
Image.Image()._new(font.getmask2(b"test")[0]),
|
||||
Image.Image()._new(font.getmask2("test")[0]),
|
||||
)
|
||||
assert font.getmask2(b"test")[1] == font.getmask2("test")[1]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_file",
|
||||
[
|
||||
|
|
|
@ -279,7 +279,7 @@ class FreeTypeFont:
|
|||
return self.font.ascent, self.font.descent
|
||||
|
||||
def getlength(
|
||||
self, text: str, mode="", direction=None, features=None, language=None
|
||||
self, text: str | bytes, mode="", direction=None, features=None, language=None
|
||||
) -> float:
|
||||
"""
|
||||
Returns length (in pixels with 1/64 precision) of given text when rendered
|
||||
|
@ -354,7 +354,7 @@ class FreeTypeFont:
|
|||
|
||||
def getbbox(
|
||||
self,
|
||||
text: str,
|
||||
text: str | bytes,
|
||||
mode: str = "",
|
||||
direction: str | None = None,
|
||||
features: list[str] | None = None,
|
||||
|
@ -511,7 +511,7 @@ class FreeTypeFont:
|
|||
|
||||
def getmask2(
|
||||
self,
|
||||
text: str,
|
||||
text: str | bytes,
|
||||
mode="",
|
||||
direction=None,
|
||||
features=None,
|
||||
|
@ -730,7 +730,7 @@ class TransposedFont:
|
|||
return 0, 0, height, width
|
||||
return 0, 0, width, height
|
||||
|
||||
def getlength(self, text: str, *args, **kwargs) -> float:
|
||||
def getlength(self, text: str | bytes, *args, **kwargs) -> float:
|
||||
if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270):
|
||||
msg = "text length is undefined for text rotated by 90 or 270 degrees"
|
||||
raise ValueError(msg)
|
||||
|
|
|
@ -27,7 +27,7 @@ class Font:
|
|||
def glyphs(self) -> int: ...
|
||||
def render(
|
||||
self,
|
||||
string: str,
|
||||
string: str | bytes,
|
||||
fill,
|
||||
mode=...,
|
||||
dir=...,
|
||||
|
@ -51,7 +51,7 @@ class Font:
|
|||
/,
|
||||
) -> tuple[tuple[int, int], tuple[int, int]]: ...
|
||||
def getlength(
|
||||
self, string: str, mode=..., dir=..., features=..., lang=..., /
|
||||
self, string: str | bytes, mode=..., dir=..., features=..., lang=..., /
|
||||
) -> float: ...
|
||||
def getvarnames(self) -> list[bytes]: ...
|
||||
def getvaraxes(self) -> list[_Axis] | None: ...
|
||||
|
|
|
@ -233,18 +233,6 @@ getfont(PyObject *self_, PyObject *args, PyObject *kw) {
|
|||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
static int
|
||||
font_getchar(PyObject *string, int index, FT_ULong *char_out) {
|
||||
if (PyUnicode_Check(string)) {
|
||||
if (index >= PyUnicode_GET_LENGTH(string)) {
|
||||
return 0;
|
||||
}
|
||||
*char_out = PyUnicode_READ_CHAR(string, index);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_RAQM
|
||||
|
||||
static size_t
|
||||
|
@ -266,28 +254,34 @@ text_layout_raqm(
|
|||
goto failed;
|
||||
}
|
||||
|
||||
Py_ssize_t size;
|
||||
int set_text;
|
||||
if (PyUnicode_Check(string)) {
|
||||
Py_UCS4 *text = PyUnicode_AsUCS4Copy(string);
|
||||
Py_ssize_t size = PyUnicode_GET_LENGTH(string);
|
||||
size = PyUnicode_GET_LENGTH(string);
|
||||
if (!text || !size) {
|
||||
/* return 0 and clean up, no glyphs==no size,
|
||||
and raqm fails with empty strings */
|
||||
goto failed;
|
||||
}
|
||||
int set_text = raqm_set_text(rq, text, size);
|
||||
set_text = raqm_set_text(rq, text, size);
|
||||
PyMem_Free(text);
|
||||
if (!set_text) {
|
||||
PyErr_SetString(PyExc_ValueError, "raqm_set_text() failed");
|
||||
} else {
|
||||
char *buffer;
|
||||
PyBytes_AsStringAndSize(string, &buffer, &size);
|
||||
if (!buffer || !size) {
|
||||
/* return 0 and clean up, no glyphs==no size,
|
||||
and raqm fails with empty strings */
|
||||
goto failed;
|
||||
}
|
||||
if (lang) {
|
||||
if (!raqm_set_language(rq, lang, start, size)) {
|
||||
PyErr_SetString(PyExc_ValueError, "raqm_set_language() failed");
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "expected string");
|
||||
set_text = raqm_set_text_utf8(rq, buffer, size);
|
||||
}
|
||||
if (!set_text) {
|
||||
PyErr_SetString(PyExc_ValueError, "raqm_set_text() failed");
|
||||
goto failed;
|
||||
}
|
||||
if (lang && !raqm_set_language(rq, lang, start, size)) {
|
||||
PyErr_SetString(PyExc_ValueError, "raqm_set_language() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -405,13 +399,13 @@ text_layout_fallback(
|
|||
GlyphInfo **glyph_info,
|
||||
int mask,
|
||||
int color) {
|
||||
int error, load_flags;
|
||||
int error, load_flags, i;
|
||||
char *buffer = NULL;
|
||||
FT_ULong ch;
|
||||
Py_ssize_t count;
|
||||
FT_GlyphSlot glyph;
|
||||
FT_Bool kerning = FT_HAS_KERNING(self->face);
|
||||
FT_UInt last_index = 0;
|
||||
int i;
|
||||
|
||||
if (features != Py_None || dir != NULL || lang != NULL) {
|
||||
PyErr_SetString(
|
||||
|
@ -419,14 +413,11 @@ text_layout_fallback(
|
|||
"setting text direction, language or font features is not supported "
|
||||
"without libraqm");
|
||||
}
|
||||
if (!PyUnicode_Check(string)) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected string");
|
||||
return 0;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
while (font_getchar(string, count, &ch)) {
|
||||
count++;
|
||||
if (PyUnicode_Check(string)) {
|
||||
count = PyUnicode_GET_LENGTH(string);
|
||||
} else {
|
||||
PyBytes_AsStringAndSize(string, &buffer, &count);
|
||||
}
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
|
@ -445,7 +436,12 @@ text_layout_fallback(
|
|||
if (color) {
|
||||
load_flags |= FT_LOAD_COLOR;
|
||||
}
|
||||
for (i = 0; font_getchar(string, i, &ch); i++) {
|
||||
for (i = 0; i < count; i++) {
|
||||
if (buffer) {
|
||||
ch = buffer[i];
|
||||
} else {
|
||||
ch = PyUnicode_READ_CHAR(string, i);
|
||||
}
|
||||
(*glyph_info)[i].index = FT_Get_Char_Index(self->face, ch);
|
||||
error = FT_Load_Glyph(self->face, (*glyph_info)[i].index, load_flags);
|
||||
if (error) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user