Skip to content

Commit

Permalink
Merge pull request #3780 from nulano/update_py_unicode
Browse files Browse the repository at this point in the history
Update Py_UNICODE to Py_UCS4
  • Loading branch information
hugovk committed Jun 30, 2019
2 parents 12695b8 + 25cf101 commit 8d4bb33
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Tests/fonts/LICENSE.txt
@@ -1,5 +1,5 @@

NotoNastaliqUrdu-Regular.ttf, from https://github.com/googlei18n/noto-fonts
NotoNastaliqUrdu-Regular.ttf and NotoSansSymbols-Regular.ttf, from https://github.com/googlei18n/noto-fonts
NotoSansJP-Thin.otf, from https://www.google.com/get/noto/help/cjk/
AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype
TINY5x3GX.ttf, from http://velvetyne.fr/fonts/tiny
Expand Down
Binary file added Tests/fonts/NotoSansSymbols-Regular.ttf
Binary file not shown.
Binary file added Tests/images/unicode_extended.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions Tests/test_imagefont.py
Expand Up @@ -463,6 +463,26 @@ def test_unicode_pilfont(self):
with self.assertRaises(UnicodeEncodeError):
font.getsize(u"’")

@unittest.skipIf(
sys.platform.startswith("win32") and sys.version.startswith("2"),
"requires Python 3.x on Windows",
)
def test_unicode_extended(self):
# issue #3777
text = u"A\u278A\U0001F12B"
target = "Tests/images/unicode_extended.png"

ttf = ImageFont.truetype(
"Tests/fonts/NotoSansSymbols-Regular.ttf",
FONT_SIZE,
layout_engine=self.LAYOUT_ENGINE,
)
img = Image.new("RGB", (100, 60))
d = ImageDraw.Draw(img)
d.text((10, 10), text, font=ttf)

self.assert_image_similar_tofile(img, target, self.metrics["multiline"])

def _test_fake_loading_font(self, path_to_fake, fontname):
# Make a copy of FreeTypeFont so we can patch the original
free_type_font = copy.deepcopy(ImageFont.FreeTypeFont)
Expand Down
36 changes: 32 additions & 4 deletions src/_imagingft.c
Expand Up @@ -327,6 +327,7 @@ getfont(PyObject* self_, PyObject* args, PyObject* kw)
static int
font_getchar(PyObject* string, int index, FT_ULong* char_out)
{
#if PY_VERSION_HEX < 0x03000000
if (PyUnicode_Check(string)) {
Py_UNICODE* p = PyUnicode_AS_UNICODE(string);
int size = PyUnicode_GET_SIZE(string);
Expand All @@ -336,7 +337,6 @@ font_getchar(PyObject* string, int index, FT_ULong* char_out)
return 1;
}

#if PY_VERSION_HEX < 0x03000000
if (PyString_Check(string)) {
unsigned char* p = (unsigned char*) PyString_AS_STRING(string);
int size = PyString_GET_SIZE(string);
Expand All @@ -345,6 +345,13 @@ font_getchar(PyObject* string, int index, FT_ULong* char_out)
*char_out = (unsigned char) p[index];
return 1;
}
#else
if (PyUnicode_Check(string)) {
if (index >= PyUnicode_GET_LENGTH(string))
return 0;
*char_out = PyUnicode_READ_CHAR(string, index);
return 1;
}
#endif

return 0;
Expand All @@ -366,6 +373,7 @@ text_layout_raqm(PyObject* string, FontObject* self, const char* dir, PyObject *
goto failed;
}

#if PY_VERSION_HEX < 0x03000000
if (PyUnicode_Check(string)) {
Py_UNICODE *text = PyUnicode_AS_UNICODE(string);
Py_ssize_t size = PyUnicode_GET_SIZE(string);
Expand All @@ -385,9 +393,7 @@ text_layout_raqm(PyObject* string, FontObject* self, const char* dir, PyObject *
}
}

}
#if PY_VERSION_HEX < 0x03000000
else if (PyString_Check(string)) {
} else if (PyString_Check(string)) {
char *text = PyString_AS_STRING(string);
int size = PyString_GET_SIZE(string);
if (! size) {
Expand All @@ -404,6 +410,28 @@ text_layout_raqm(PyObject* string, FontObject* self, const char* dir, PyObject *
}
}
}
#else
if (PyUnicode_Check(string)) {
Py_UCS4 *text = PyUnicode_AsUCS4Copy(string);
Py_ssize_t 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 = (*p_raqm.set_text)(rq, (const uint32_t *)(text), size);
PyMem_Free(text);
if (!set_text) {
PyErr_SetString(PyExc_ValueError, "raqm_set_text() failed");
goto failed;
}
if (lang) {
if (!(*p_raqm.set_language)(rq, lang, start, size)) {
PyErr_SetString(PyExc_ValueError, "raqm_set_language() failed");
goto failed;
}
}
}
#endif
else {
PyErr_SetString(PyExc_TypeError, "expected string");
Expand Down

0 comments on commit 8d4bb33

Please sign in to comment.