mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 18:06:18 +03:00
use FriBiDi shim in Raqm
This commit is contained in:
parent
e5e5761da4
commit
8bc1ff35b4
16
setup.py
16
setup.py
|
@ -267,6 +267,7 @@ class pil_build_ext(build_ext):
|
||||||
"jpeg",
|
"jpeg",
|
||||||
"tiff",
|
"tiff",
|
||||||
"freetype",
|
"freetype",
|
||||||
|
"harfbuzz",
|
||||||
"lcms",
|
"lcms",
|
||||||
"webp",
|
"webp",
|
||||||
"webpmux",
|
"webpmux",
|
||||||
|
@ -656,6 +657,12 @@ class pil_build_ext(build_ext):
|
||||||
if subdir:
|
if subdir:
|
||||||
_add_directory(self.compiler.include_dirs, subdir, 0)
|
_add_directory(self.compiler.include_dirs, subdir, 0)
|
||||||
|
|
||||||
|
if feature.want("harfbuzz"):
|
||||||
|
_dbg("Looking for harfbuzz")
|
||||||
|
if _find_include_file(self, "hb-version.h"):
|
||||||
|
if _find_library_file(self, "harfbuzz"):
|
||||||
|
feature.harfbuzz = "harfbuzz"
|
||||||
|
|
||||||
if feature.want("lcms"):
|
if feature.want("lcms"):
|
||||||
_dbg("Looking for lcms")
|
_dbg("Looking for lcms")
|
||||||
if _find_include_file(self, "lcms2.h"):
|
if _find_include_file(self, "lcms2.h"):
|
||||||
|
@ -850,7 +857,14 @@ for src_file in _LIB_IMAGING:
|
||||||
files.append(os.path.join("src/libImaging", src_file + ".c"))
|
files.append(os.path.join("src/libImaging", src_file + ".c"))
|
||||||
ext_modules = [
|
ext_modules = [
|
||||||
Extension("PIL._imaging", files),
|
Extension("PIL._imaging", files),
|
||||||
Extension("PIL._imagingft", ["src/_imagingft.c"]),
|
Extension(
|
||||||
|
"PIL._imagingft",
|
||||||
|
[
|
||||||
|
"src/_imagingft.c",
|
||||||
|
"src/thirdparty/raqm/raqm.c",
|
||||||
|
"src/thirdparty/fribidi-shim/fribidi.c",
|
||||||
|
],
|
||||||
|
),
|
||||||
Extension("PIL._imagingcms", ["src/_imagingcms.c"]),
|
Extension("PIL._imagingcms", ["src/_imagingcms.c"]),
|
||||||
Extension("PIL._webp", ["src/_webp.c"]),
|
Extension("PIL._webp", ["src/_webp.c"]),
|
||||||
Extension("PIL._imagingtk", ["src/_imagingtk.c", "src/Tk/tkImaging.c"]),
|
Extension("PIL._imagingtk", ["src/_imagingtk.c", "src/Tk/tkImaging.c"]),
|
||||||
|
|
225
src/_imagingft.c
225
src/_imagingft.c
|
@ -35,10 +35,6 @@
|
||||||
|
|
||||||
#define KEEP_PY_UNICODE
|
#define KEEP_PY_UNICODE
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(FT_LOAD_TARGET_MONO)
|
#if !defined(FT_LOAD_TARGET_MONO)
|
||||||
#define FT_LOAD_TARGET_MONO FT_LOAD_MONOCHROME
|
#define FT_LOAD_TARGET_MONO FT_LOAD_MONOCHROME
|
||||||
#endif
|
#endif
|
||||||
|
@ -56,7 +52,8 @@
|
||||||
} \
|
} \
|
||||||
;
|
;
|
||||||
|
|
||||||
#include "libImaging/raqm.h"
|
#include "thirdparty/raqm/raqm.h"
|
||||||
|
#include "thirdparty/fribidi-shim/fribidi.h"
|
||||||
|
|
||||||
#define LAYOUT_FALLBACK 0
|
#define LAYOUT_FALLBACK 0
|
||||||
#define LAYOUT_RAQM 1
|
#define LAYOUT_RAQM 1
|
||||||
|
@ -86,42 +83,6 @@ typedef struct {
|
||||||
|
|
||||||
static PyTypeObject Font_Type;
|
static PyTypeObject Font_Type;
|
||||||
|
|
||||||
typedef const char *(*t_raqm_version_string)(void);
|
|
||||||
typedef bool (*t_raqm_version_atleast)(
|
|
||||||
unsigned int major, unsigned int minor, unsigned int micro);
|
|
||||||
typedef raqm_t *(*t_raqm_create)(void);
|
|
||||||
typedef int (*t_raqm_set_text)(raqm_t *rq, const uint32_t *text, size_t len);
|
|
||||||
typedef bool (*t_raqm_set_text_utf8)(raqm_t *rq, const char *text, size_t len);
|
|
||||||
typedef bool (*t_raqm_set_par_direction)(raqm_t *rq, raqm_direction_t dir);
|
|
||||||
typedef bool (*t_raqm_set_language)(
|
|
||||||
raqm_t *rq, const char *lang, size_t start, size_t len);
|
|
||||||
typedef bool (*t_raqm_add_font_feature)(raqm_t *rq, const char *feature, int len);
|
|
||||||
typedef bool (*t_raqm_set_freetype_face)(raqm_t *rq, FT_Face face);
|
|
||||||
typedef bool (*t_raqm_layout)(raqm_t *rq);
|
|
||||||
typedef raqm_glyph_t *(*t_raqm_get_glyphs)(raqm_t *rq, size_t *length);
|
|
||||||
typedef raqm_glyph_t_01 *(*t_raqm_get_glyphs_01)(raqm_t *rq, size_t *length);
|
|
||||||
typedef void (*t_raqm_destroy)(raqm_t *rq);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void *raqm;
|
|
||||||
int version;
|
|
||||||
t_raqm_version_string version_string;
|
|
||||||
t_raqm_version_atleast version_atleast;
|
|
||||||
t_raqm_create create;
|
|
||||||
t_raqm_set_text set_text;
|
|
||||||
t_raqm_set_text_utf8 set_text_utf8;
|
|
||||||
t_raqm_set_par_direction set_par_direction;
|
|
||||||
t_raqm_set_language set_language;
|
|
||||||
t_raqm_add_font_feature add_font_feature;
|
|
||||||
t_raqm_set_freetype_face set_freetype_face;
|
|
||||||
t_raqm_layout layout;
|
|
||||||
t_raqm_get_glyphs get_glyphs;
|
|
||||||
t_raqm_get_glyphs_01 get_glyphs_01;
|
|
||||||
t_raqm_destroy destroy;
|
|
||||||
} p_raqm_func;
|
|
||||||
|
|
||||||
static p_raqm_func p_raqm;
|
|
||||||
|
|
||||||
/* round a 26.6 pixel coordinate to the nearest integer */
|
/* round a 26.6 pixel coordinate to the nearest integer */
|
||||||
#define PIXEL(x) ((((x) + 32) & -64) >> 6)
|
#define PIXEL(x) ((((x) + 32) & -64) >> 6)
|
||||||
|
|
||||||
|
@ -142,101 +103,7 @@ geterror(int code) {
|
||||||
|
|
||||||
static int
|
static int
|
||||||
setraqm(void) {
|
setraqm(void) {
|
||||||
/* set the static function pointers for dynamic raqm linking */
|
return load_fribidi();
|
||||||
p_raqm.raqm = NULL;
|
|
||||||
|
|
||||||
/* Microsoft needs a totally different system */
|
|
||||||
#ifndef _WIN32
|
|
||||||
p_raqm.raqm = dlopen("libraqm.so.0", RTLD_LAZY);
|
|
||||||
if (!p_raqm.raqm) {
|
|
||||||
p_raqm.raqm = dlopen("libraqm.dylib", RTLD_LAZY);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
p_raqm.raqm = LoadLibrary("libraqm");
|
|
||||||
/* MSYS */
|
|
||||||
if (!p_raqm.raqm) {
|
|
||||||
p_raqm.raqm = LoadLibrary("libraqm-0");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!p_raqm.raqm) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
p_raqm.version_string =
|
|
||||||
(t_raqm_version_string)dlsym(p_raqm.raqm, "raqm_version_string");
|
|
||||||
p_raqm.version_atleast =
|
|
||||||
(t_raqm_version_atleast)dlsym(p_raqm.raqm, "raqm_version_atleast");
|
|
||||||
p_raqm.create = (t_raqm_create)dlsym(p_raqm.raqm, "raqm_create");
|
|
||||||
p_raqm.set_text = (t_raqm_set_text)dlsym(p_raqm.raqm, "raqm_set_text");
|
|
||||||
p_raqm.set_text_utf8 =
|
|
||||||
(t_raqm_set_text_utf8)dlsym(p_raqm.raqm, "raqm_set_text_utf8");
|
|
||||||
p_raqm.set_par_direction =
|
|
||||||
(t_raqm_set_par_direction)dlsym(p_raqm.raqm, "raqm_set_par_direction");
|
|
||||||
p_raqm.set_language = (t_raqm_set_language)dlsym(p_raqm.raqm, "raqm_set_language");
|
|
||||||
p_raqm.add_font_feature =
|
|
||||||
(t_raqm_add_font_feature)dlsym(p_raqm.raqm, "raqm_add_font_feature");
|
|
||||||
p_raqm.set_freetype_face =
|
|
||||||
(t_raqm_set_freetype_face)dlsym(p_raqm.raqm, "raqm_set_freetype_face");
|
|
||||||
p_raqm.layout = (t_raqm_layout)dlsym(p_raqm.raqm, "raqm_layout");
|
|
||||||
p_raqm.destroy = (t_raqm_destroy)dlsym(p_raqm.raqm, "raqm_destroy");
|
|
||||||
if (dlsym(p_raqm.raqm, "raqm_index_to_position")) {
|
|
||||||
p_raqm.get_glyphs = (t_raqm_get_glyphs)dlsym(p_raqm.raqm, "raqm_get_glyphs");
|
|
||||||
p_raqm.version = 2;
|
|
||||||
} else {
|
|
||||||
p_raqm.version = 1;
|
|
||||||
p_raqm.get_glyphs_01 =
|
|
||||||
(t_raqm_get_glyphs_01)dlsym(p_raqm.raqm, "raqm_get_glyphs");
|
|
||||||
}
|
|
||||||
if (dlerror() ||
|
|
||||||
!(p_raqm.create && p_raqm.set_text && p_raqm.set_text_utf8 &&
|
|
||||||
p_raqm.set_par_direction && p_raqm.set_language && p_raqm.add_font_feature &&
|
|
||||||
p_raqm.set_freetype_face && p_raqm.layout &&
|
|
||||||
(p_raqm.get_glyphs || p_raqm.get_glyphs_01) && p_raqm.destroy)) {
|
|
||||||
dlclose(p_raqm.raqm);
|
|
||||||
p_raqm.raqm = NULL;
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
p_raqm.version_string =
|
|
||||||
(t_raqm_version_string)GetProcAddress(p_raqm.raqm, "raqm_version_string");
|
|
||||||
p_raqm.version_atleast =
|
|
||||||
(t_raqm_version_atleast)GetProcAddress(p_raqm.raqm, "raqm_version_atleast");
|
|
||||||
p_raqm.create = (t_raqm_create)GetProcAddress(p_raqm.raqm, "raqm_create");
|
|
||||||
p_raqm.set_text = (t_raqm_set_text)GetProcAddress(p_raqm.raqm, "raqm_set_text");
|
|
||||||
p_raqm.set_text_utf8 =
|
|
||||||
(t_raqm_set_text_utf8)GetProcAddress(p_raqm.raqm, "raqm_set_text_utf8");
|
|
||||||
p_raqm.set_par_direction =
|
|
||||||
(t_raqm_set_par_direction)GetProcAddress(p_raqm.raqm, "raqm_set_par_direction");
|
|
||||||
p_raqm.set_language =
|
|
||||||
(t_raqm_set_language)GetProcAddress(p_raqm.raqm, "raqm_set_language");
|
|
||||||
p_raqm.add_font_feature =
|
|
||||||
(t_raqm_add_font_feature)GetProcAddress(p_raqm.raqm, "raqm_add_font_feature");
|
|
||||||
p_raqm.set_freetype_face =
|
|
||||||
(t_raqm_set_freetype_face)GetProcAddress(p_raqm.raqm, "raqm_set_freetype_face");
|
|
||||||
p_raqm.layout = (t_raqm_layout)GetProcAddress(p_raqm.raqm, "raqm_layout");
|
|
||||||
p_raqm.destroy = (t_raqm_destroy)GetProcAddress(p_raqm.raqm, "raqm_destroy");
|
|
||||||
if (GetProcAddress(p_raqm.raqm, "raqm_index_to_position")) {
|
|
||||||
p_raqm.get_glyphs =
|
|
||||||
(t_raqm_get_glyphs)GetProcAddress(p_raqm.raqm, "raqm_get_glyphs");
|
|
||||||
p_raqm.version = 2;
|
|
||||||
} else {
|
|
||||||
p_raqm.version = 1;
|
|
||||||
p_raqm.get_glyphs_01 =
|
|
||||||
(t_raqm_get_glyphs_01)GetProcAddress(p_raqm.raqm, "raqm_get_glyphs");
|
|
||||||
}
|
|
||||||
if (!(p_raqm.create && p_raqm.set_text && p_raqm.set_text_utf8 &&
|
|
||||||
p_raqm.set_par_direction && p_raqm.set_language && p_raqm.add_font_feature &&
|
|
||||||
p_raqm.set_freetype_face && p_raqm.layout &&
|
|
||||||
(p_raqm.get_glyphs || p_raqm.get_glyphs_01) && p_raqm.destroy)) {
|
|
||||||
FreeLibrary(p_raqm.raqm);
|
|
||||||
p_raqm.raqm = NULL;
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -359,10 +226,10 @@ text_layout_raqm(
|
||||||
size_t i = 0, count = 0, start = 0;
|
size_t i = 0, count = 0, start = 0;
|
||||||
raqm_t *rq;
|
raqm_t *rq;
|
||||||
raqm_glyph_t *glyphs = NULL;
|
raqm_glyph_t *glyphs = NULL;
|
||||||
raqm_glyph_t_01 *glyphs_01 = NULL;
|
// raqm_glyph_t_01 *glyphs_01 = NULL;
|
||||||
raqm_direction_t direction;
|
raqm_direction_t direction;
|
||||||
|
|
||||||
rq = (*p_raqm.create)();
|
rq = raqm_create();
|
||||||
if (rq == NULL) {
|
if (rq == NULL) {
|
||||||
PyErr_SetString(PyExc_ValueError, "raqm_create() failed.");
|
PyErr_SetString(PyExc_ValueError, "raqm_create() failed.");
|
||||||
goto failed;
|
goto failed;
|
||||||
|
@ -376,14 +243,14 @@ text_layout_raqm(
|
||||||
and raqm fails with empty strings */
|
and raqm fails with empty strings */
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
int set_text = (*p_raqm.set_text)(rq, text, size);
|
int set_text = raqm_set_text(rq, text, size);
|
||||||
PyMem_Free(text);
|
PyMem_Free(text);
|
||||||
if (!set_text) {
|
if (!set_text) {
|
||||||
PyErr_SetString(PyExc_ValueError, "raqm_set_text() failed");
|
PyErr_SetString(PyExc_ValueError, "raqm_set_text() failed");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
if (lang) {
|
if (lang) {
|
||||||
if (!(*p_raqm.set_language)(rq, lang, start, size)) {
|
if (!raqm_set_language(rq, lang, start, size)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "raqm_set_language() failed");
|
PyErr_SetString(PyExc_ValueError, "raqm_set_language() failed");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
@ -401,12 +268,12 @@ text_layout_raqm(
|
||||||
direction = RAQM_DIRECTION_LTR;
|
direction = RAQM_DIRECTION_LTR;
|
||||||
} else if (strcmp(dir, "ttb") == 0) {
|
} else if (strcmp(dir, "ttb") == 0) {
|
||||||
direction = RAQM_DIRECTION_TTB;
|
direction = RAQM_DIRECTION_TTB;
|
||||||
if (p_raqm.version_atleast == NULL || !(*p_raqm.version_atleast)(0, 7, 0)) {
|
// if (p_raqm.version_atleast == NULL || !(*p_raqm.version_atleast)(0, 7, 0)) {
|
||||||
PyErr_SetString(
|
// PyErr_SetString(
|
||||||
PyExc_ValueError,
|
// PyExc_ValueError,
|
||||||
"libraqm 0.7 or greater required for 'ttb' direction");
|
// "libraqm 0.7 or greater required for 'ttb' direction");
|
||||||
goto failed;
|
// goto failed;
|
||||||
}
|
// }
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(
|
PyErr_SetString(
|
||||||
PyExc_ValueError, "direction must be either 'rtl', 'ltr' or 'ttb'");
|
PyExc_ValueError, "direction must be either 'rtl', 'ltr' or 'ttb'");
|
||||||
|
@ -414,7 +281,7 @@ text_layout_raqm(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*p_raqm.set_par_direction)(rq, direction)) {
|
if (!raqm_set_par_direction(rq, direction)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "raqm_set_par_direction() failed");
|
PyErr_SetString(PyExc_ValueError, "raqm_set_par_direction() failed");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
@ -446,38 +313,38 @@ text_layout_raqm(
|
||||||
feature = PyBytes_AS_STRING(bytes);
|
feature = PyBytes_AS_STRING(bytes);
|
||||||
size = PyBytes_GET_SIZE(bytes);
|
size = PyBytes_GET_SIZE(bytes);
|
||||||
}
|
}
|
||||||
if (!(*p_raqm.add_font_feature)(rq, feature, size)) {
|
if (!raqm_add_font_feature(rq, feature, size)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "raqm_add_font_feature() failed");
|
PyErr_SetString(PyExc_ValueError, "raqm_add_font_feature() failed");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*p_raqm.set_freetype_face)(rq, self->face)) {
|
if (!raqm_set_freetype_face(rq, self->face)) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "raqm_set_freetype_face() failed.");
|
PyErr_SetString(PyExc_RuntimeError, "raqm_set_freetype_face() failed.");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*p_raqm.layout)(rq)) {
|
if (!raqm_layout(rq)) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "raqm_layout() failed.");
|
PyErr_SetString(PyExc_RuntimeError, "raqm_layout() failed.");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_raqm.version == 1) {
|
// if (p_raqm.version == 1) {
|
||||||
glyphs_01 = (*p_raqm.get_glyphs_01)(rq, &count);
|
// glyphs_01 = raqm_get_glyphs_01(rq, &count);
|
||||||
if (glyphs_01 == NULL) {
|
// if (glyphs_01 == NULL) {
|
||||||
PyErr_SetString(PyExc_ValueError, "raqm_get_glyphs() failed.");
|
// PyErr_SetString(PyExc_ValueError, "raqm_get_glyphs() failed.");
|
||||||
count = 0;
|
// count = 0;
|
||||||
goto failed;
|
// goto failed;
|
||||||
}
|
// }
|
||||||
} else { /* version == 2 */
|
// } else { /* version == 2 */
|
||||||
glyphs = (*p_raqm.get_glyphs)(rq, &count);
|
glyphs = raqm_get_glyphs(rq, &count);
|
||||||
if (glyphs == NULL) {
|
if (glyphs == NULL) {
|
||||||
PyErr_SetString(PyExc_ValueError, "raqm_get_glyphs() failed.");
|
PyErr_SetString(PyExc_ValueError, "raqm_get_glyphs() failed.");
|
||||||
count = 0;
|
count = 0;
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
|
|
||||||
(*glyph_info) = PyMem_New(GlyphInfo, count);
|
(*glyph_info) = PyMem_New(GlyphInfo, count);
|
||||||
if ((*glyph_info) == NULL) {
|
if ((*glyph_info) == NULL) {
|
||||||
|
@ -486,16 +353,16 @@ text_layout_raqm(
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_raqm.version == 1) {
|
// if (p_raqm.version == 1) {
|
||||||
for (i = 0; i < count; i++) {
|
// for (i = 0; i < count; i++) {
|
||||||
(*glyph_info)[i].index = glyphs_01[i].index;
|
// (*glyph_info)[i].index = glyphs_01[i].index;
|
||||||
(*glyph_info)[i].x_offset = glyphs_01[i].x_offset;
|
// (*glyph_info)[i].x_offset = glyphs_01[i].x_offset;
|
||||||
(*glyph_info)[i].x_advance = glyphs_01[i].x_advance;
|
// (*glyph_info)[i].x_advance = glyphs_01[i].x_advance;
|
||||||
(*glyph_info)[i].y_offset = glyphs_01[i].y_offset;
|
// (*glyph_info)[i].y_offset = glyphs_01[i].y_offset;
|
||||||
(*glyph_info)[i].y_advance = glyphs_01[i].y_advance;
|
// (*glyph_info)[i].y_advance = glyphs_01[i].y_advance;
|
||||||
(*glyph_info)[i].cluster = glyphs_01[i].cluster;
|
// (*glyph_info)[i].cluster = glyphs_01[i].cluster;
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
(*glyph_info)[i].index = glyphs[i].index;
|
(*glyph_info)[i].index = glyphs[i].index;
|
||||||
(*glyph_info)[i].x_offset = glyphs[i].x_offset;
|
(*glyph_info)[i].x_offset = glyphs[i].x_offset;
|
||||||
|
@ -504,10 +371,10 @@ text_layout_raqm(
|
||||||
(*glyph_info)[i].y_advance = glyphs[i].y_advance;
|
(*glyph_info)[i].y_advance = glyphs[i].y_advance;
|
||||||
(*glyph_info)[i].cluster = glyphs[i].cluster;
|
(*glyph_info)[i].cluster = glyphs[i].cluster;
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
(*p_raqm.destroy)(rq);
|
raqm_destroy(rq);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,9 +474,9 @@ text_layout(
|
||||||
int color) {
|
int color) {
|
||||||
size_t count;
|
size_t count;
|
||||||
|
|
||||||
if (p_raqm.raqm && self->layout_engine == LAYOUT_RAQM) {
|
if (p_fribidi && self->layout_engine == LAYOUT_RAQM) {
|
||||||
count = text_layout_raqm(
|
count = text_layout_raqm(
|
||||||
string, self, dir, features, lang, glyph_info, mask, color);
|
string, self, dir, features, lang, glyph_info, mask, color);
|
||||||
} else {
|
} else {
|
||||||
count = text_layout_fallback(
|
count = text_layout_fallback(
|
||||||
string, self, dir, features, lang, glyph_info, mask, color);
|
string, self, dir, features, lang, glyph_info, mask, color);
|
||||||
|
@ -1491,12 +1358,14 @@ setup_module(PyObject *m) {
|
||||||
PyDict_SetItemString(d, "freetype2_version", v);
|
PyDict_SetItemString(d, "freetype2_version", v);
|
||||||
|
|
||||||
setraqm();
|
setraqm();
|
||||||
v = PyBool_FromLong(!!p_raqm.raqm);
|
v = PyBool_FromLong(!!p_fribidi);
|
||||||
PyDict_SetItemString(d, "HAVE_RAQM", v);
|
PyDict_SetItemString(d, "HAVE_RAQM", v);
|
||||||
if (p_raqm.version_string) {
|
// if (p_raqm.version_string) {
|
||||||
PyDict_SetItemString(
|
PyDict_SetItemString(
|
||||||
d, "raqm_version", PyUnicode_FromString(p_raqm.version_string()));
|
d, "raqm_version", PyUnicode_FromString(raqm_version_string()));
|
||||||
}
|
// };
|
||||||
|
|
||||||
|
PyDict_SetItemString(d, "HAVE_FRIBIDI", v);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,156 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright © 2015 Information Technology Authority (ITA) <foss@ita.gov.om>
|
|
||||||
* Copyright © 2016 Khaled Hosny <khaledhosny@eglug.org>
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to
|
|
||||||
* deal in the Software without restriction, including without limitation the
|
|
||||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
* sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
* IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _RAQM_H_
|
|
||||||
#define _RAQM_H_
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef bool
|
|
||||||
typedef int bool;
|
|
||||||
#endif
|
|
||||||
#ifndef uint32_t
|
|
||||||
typedef UINT32 uint32_t;
|
|
||||||
#endif
|
|
||||||
#include <ft2build.h>
|
|
||||||
#include FT_FREETYPE_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* raqm_t:
|
|
||||||
*
|
|
||||||
* This is the main object holding all state of the currently processed text as
|
|
||||||
* well as its output.
|
|
||||||
*
|
|
||||||
* Since: 0.1
|
|
||||||
*/
|
|
||||||
typedef struct _raqm raqm_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* raqm_direction_t:
|
|
||||||
* @RAQM_DIRECTION_DEFAULT: Detect paragraph direction automatically.
|
|
||||||
* @RAQM_DIRECTION_RTL: Paragraph is mainly right-to-left text.
|
|
||||||
* @RAQM_DIRECTION_LTR: Paragraph is mainly left-to-right text.
|
|
||||||
* @RAQM_DIRECTION_TTB: Paragraph is mainly vertical top-to-bottom text.
|
|
||||||
*
|
|
||||||
* Base paragraph direction, see raqm_set_par_direction().
|
|
||||||
*
|
|
||||||
* Since: 0.1
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
RAQM_DIRECTION_DEFAULT,
|
|
||||||
RAQM_DIRECTION_RTL,
|
|
||||||
RAQM_DIRECTION_LTR,
|
|
||||||
RAQM_DIRECTION_TTB
|
|
||||||
} raqm_direction_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* raqm_glyph_t:
|
|
||||||
* @index: the index of the glyph in the font file.
|
|
||||||
* @x_advance: the glyph advance width in horizontal text.
|
|
||||||
* @y_advance: the glyph advance width in vertical text.
|
|
||||||
* @x_offset: the horizontal movement of the glyph from the current point.
|
|
||||||
* @y_offset: the vertical movement of the glyph from the current point.
|
|
||||||
* @cluster: the index of original character in input text.
|
|
||||||
* @ftface: the @FT_Face of the glyph.
|
|
||||||
*
|
|
||||||
* The structure that holds information about output glyphs, returned from
|
|
||||||
* raqm_get_glyphs().
|
|
||||||
*/
|
|
||||||
typedef struct raqm_glyph_t {
|
|
||||||
unsigned int index;
|
|
||||||
int x_advance;
|
|
||||||
int y_advance;
|
|
||||||
int x_offset;
|
|
||||||
int y_offset;
|
|
||||||
uint32_t cluster;
|
|
||||||
FT_Face ftface;
|
|
||||||
} raqm_glyph_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* version 0.1 of the raqm_glyph_t structure
|
|
||||||
*/
|
|
||||||
typedef struct raqm_glyph_t_01 {
|
|
||||||
unsigned int index;
|
|
||||||
int x_advance;
|
|
||||||
int y_advance;
|
|
||||||
int x_offset;
|
|
||||||
int y_offset;
|
|
||||||
uint32_t cluster;
|
|
||||||
} raqm_glyph_t_01;
|
|
||||||
|
|
||||||
raqm_t *
|
|
||||||
raqm_create(void);
|
|
||||||
|
|
||||||
raqm_t *
|
|
||||||
raqm_reference(raqm_t *rq);
|
|
||||||
|
|
||||||
void
|
|
||||||
raqm_destroy(raqm_t *rq);
|
|
||||||
|
|
||||||
bool
|
|
||||||
raqm_set_text(raqm_t *rq, const uint32_t *text, size_t len);
|
|
||||||
|
|
||||||
bool
|
|
||||||
raqm_set_text_utf8(raqm_t *rq, const char *text, size_t len);
|
|
||||||
|
|
||||||
bool
|
|
||||||
raqm_set_par_direction(raqm_t *rq, raqm_direction_t dir);
|
|
||||||
|
|
||||||
bool
|
|
||||||
raqm_set_language(raqm_t *rq, const char *lang, size_t start, size_t len);
|
|
||||||
|
|
||||||
bool
|
|
||||||
raqm_add_font_feature(raqm_t *rq, const char *feature, int len);
|
|
||||||
|
|
||||||
bool
|
|
||||||
raqm_set_freetype_face(raqm_t *rq, FT_Face face);
|
|
||||||
|
|
||||||
bool
|
|
||||||
raqm_set_freetype_face_range(raqm_t *rq, FT_Face face, size_t start, size_t len);
|
|
||||||
|
|
||||||
bool
|
|
||||||
raqm_set_freetype_load_flags(raqm_t *rq, int flags);
|
|
||||||
|
|
||||||
bool
|
|
||||||
raqm_layout(raqm_t *rq);
|
|
||||||
|
|
||||||
raqm_glyph_t *
|
|
||||||
raqm_get_glyphs(raqm_t *rq, size_t *length);
|
|
||||||
|
|
||||||
bool
|
|
||||||
raqm_index_to_position(raqm_t *rq, size_t *index, int *x, int *y);
|
|
||||||
|
|
||||||
bool
|
|
||||||
raqm_position_to_index(raqm_t *rq, int x, int y, size_t *index);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* _RAQM_H_ */
|
|
68
src/thirdparty/fribidi-shim/fribidi.c
vendored
Normal file
68
src/thirdparty/fribidi-shim/fribidi.c
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#else
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FRIBIDI_SHIM_IMPLEMENTATION
|
||||||
|
|
||||||
|
#include "fribidi.h"
|
||||||
|
|
||||||
|
int load_fribidi(void) {
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
p_fribidi = NULL;
|
||||||
|
|
||||||
|
/* Microsoft needs a totally different system */
|
||||||
|
#ifndef _WIN32
|
||||||
|
p_fribidi = dlopen("libfribidi.so.1", RTLD_LAZY);
|
||||||
|
if (!p_fribidi) {
|
||||||
|
p_fribidi = dlopen("libfribidi.dylib", RTLD_LAZY);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
p_fribidi = LoadLibrary("fribidi");
|
||||||
|
/* MSYS2 */
|
||||||
|
if (!p_fribidi) {
|
||||||
|
p_fribidi = LoadLibrary("libfribidi-1");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!p_fribidi) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#define LOAD_FUNCTION(func) \
|
||||||
|
func = (t_##func)dlsym(p_fribidi, #func); \
|
||||||
|
error = error || (func == NULL);
|
||||||
|
#else
|
||||||
|
#define LOAD_FUNCTION(func) \
|
||||||
|
func = (t_##func)GetProcAddress(p_fribidi, #func); \
|
||||||
|
error = error || (func == NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LOAD_FUNCTION(fribidi_get_bidi_types);
|
||||||
|
LOAD_FUNCTION(fribidi_get_bracket_types);
|
||||||
|
LOAD_FUNCTION(fribidi_get_par_embedding_levels_ex);
|
||||||
|
// LOAD_FUNCTION(fribidi_get_par_embedding_levels);
|
||||||
|
LOAD_FUNCTION(fribidi_unicode_to_charset);
|
||||||
|
LOAD_FUNCTION(fribidi_charset_to_unicode);
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
if (dlerror() || error) {
|
||||||
|
dlclose(p_fribidi);
|
||||||
|
p_fribidi = NULL;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (error) {
|
||||||
|
FreeLibrary(p_fribidi);
|
||||||
|
p_fribidi = NULL;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
104
src/thirdparty/fribidi-shim/fribidi.h
vendored
Normal file
104
src/thirdparty/fribidi-shim/fribidi.h
vendored
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
|
||||||
|
/* fribidi-types.h */
|
||||||
|
|
||||||
|
# if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \
|
||||||
|
defined (_sgi) || defined (__sun) || defined (sun) || \
|
||||||
|
defined (__digital__) || defined (__HP_cc)
|
||||||
|
# include <inttypes.h>
|
||||||
|
# elif defined (_AIX)
|
||||||
|
# include <sys/inttypes.h>
|
||||||
|
# else
|
||||||
|
# include <stdint.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
typedef uint32_t FriBidiChar;
|
||||||
|
typedef int FriBidiStrIndex;
|
||||||
|
|
||||||
|
typedef FriBidiChar FriBidiBracketType;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* fribidi-char-sets.h */
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
_FRIBIDI_CHAR_SET_NOT_FOUND,
|
||||||
|
FRIBIDI_CHAR_SET_UTF8,
|
||||||
|
FRIBIDI_CHAR_SET_CAP_RTL,
|
||||||
|
FRIBIDI_CHAR_SET_ISO8859_6,
|
||||||
|
FRIBIDI_CHAR_SET_ISO8859_8,
|
||||||
|
FRIBIDI_CHAR_SET_CP1255,
|
||||||
|
FRIBIDI_CHAR_SET_CP1256,
|
||||||
|
_FRIBIDI_CHAR_SETS_NUM_PLUS_ONE
|
||||||
|
}
|
||||||
|
FriBidiCharSet;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* fribidi-bidi-types.h */
|
||||||
|
|
||||||
|
typedef signed char FriBidiLevel;
|
||||||
|
|
||||||
|
#define FRIBIDI_TYPE_LTR_VAL 0x00000110L
|
||||||
|
#define FRIBIDI_TYPE_RTL_VAL 0x00000111L
|
||||||
|
#define FRIBIDI_TYPE_ON_VAL 0x00000040L
|
||||||
|
|
||||||
|
typedef uint32_t FriBidiCharType;
|
||||||
|
#define FRIBIDI_TYPE_LTR FRIBIDI_TYPE_LTR_VAL
|
||||||
|
|
||||||
|
typedef uint32_t FriBidiParType;
|
||||||
|
#define FRIBIDI_PAR_LTR FRIBIDI_TYPE_LTR_VAL
|
||||||
|
#define FRIBIDI_PAR_RTL FRIBIDI_TYPE_RTL_VAL
|
||||||
|
#define FRIBIDI_PAR_ON FRIBIDI_TYPE_ON_VAL
|
||||||
|
|
||||||
|
#define FRIBIDI_LEVEL_IS_RTL(lev) ((lev) & 1)
|
||||||
|
#define FRIBIDI_DIR_TO_LEVEL(dir) ((FriBidiLevel) (FRIBIDI_IS_RTL(dir) ? 1 : 0))
|
||||||
|
#define FRIBIDI_IS_RTL(p) ((p) & 0x00000001L)
|
||||||
|
#define FRIBIDI_IS_EXPLICIT_OR_BN_OR_WS(p) ((p) & 0x00901000L)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* functions */
|
||||||
|
|
||||||
|
#ifdef FRIBIDI_SHIM_IMPLEMENTATION
|
||||||
|
#define FRIBIDI_ENTRY
|
||||||
|
#else
|
||||||
|
#define FRIBIDI_ENTRY extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FRIBIDI_FUNC(ret, name, ...) \
|
||||||
|
typedef ret (*t_##name) (__VA_ARGS__); \
|
||||||
|
FRIBIDI_ENTRY t_##name name;
|
||||||
|
|
||||||
|
FRIBIDI_FUNC(void, fribidi_get_bidi_types,
|
||||||
|
const FriBidiChar *, const FriBidiStrIndex, FriBidiCharType *);
|
||||||
|
|
||||||
|
FRIBIDI_FUNC(void, fribidi_get_bracket_types,
|
||||||
|
const FriBidiChar *, const FriBidiStrIndex, const FriBidiCharType *,
|
||||||
|
FriBidiBracketType *);
|
||||||
|
|
||||||
|
FRIBIDI_FUNC(FriBidiLevel, fribidi_get_par_embedding_levels_ex,
|
||||||
|
const FriBidiCharType *, const FriBidiBracketType *, const FriBidiStrIndex,
|
||||||
|
FriBidiParType *, FriBidiLevel *);
|
||||||
|
|
||||||
|
//FRIBIDI_FUNC(FriBidiLevel, fribidi_get_par_embedding_levels,
|
||||||
|
// const FriBidiCharType *, const FriBidiStrIndex, FriBidiParType *,
|
||||||
|
// FriBidiLevel *);
|
||||||
|
|
||||||
|
FRIBIDI_FUNC(FriBidiStrIndex, fribidi_unicode_to_charset,
|
||||||
|
FriBidiCharSet, const FriBidiChar *, FriBidiStrIndex, char *);
|
||||||
|
|
||||||
|
FRIBIDI_FUNC(FriBidiStrIndex, fribidi_charset_to_unicode,
|
||||||
|
FriBidiCharSet, const char *, FriBidiStrIndex, FriBidiChar *);
|
||||||
|
|
||||||
|
#undef FRIBIDI_FUNC
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* shim */
|
||||||
|
|
||||||
|
FRIBIDI_ENTRY void *p_fribidi;
|
||||||
|
|
||||||
|
FRIBIDI_ENTRY int load_fribidi(void);
|
||||||
|
|
||||||
|
#undef FRIBIDI_ENTRY
|
7
src/thirdparty/raqm/raqm.c
vendored
7
src/thirdparty/raqm/raqm.c
vendored
|
@ -30,15 +30,16 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <fribidi.h>
|
#include "../fribidi-shim/fribidi.h"
|
||||||
|
|
||||||
#include <hb.h>
|
#include <hb.h>
|
||||||
#include <hb-ft.h>
|
#include <hb-ft.h>
|
||||||
|
|
||||||
#include "raqm.h"
|
#include "raqm.h"
|
||||||
|
|
||||||
#if FRIBIDI_MAJOR_VERSION >= 1
|
//#if FRIBIDI_MAJOR_VERSION >= 1
|
||||||
#define USE_FRIBIDI_EX_API
|
#define USE_FRIBIDI_EX_API
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:raqm
|
* SECTION:raqm
|
||||||
|
|
|
@ -296,21 +296,7 @@ deps = {
|
||||||
cmd_nmake(target="clean"),
|
cmd_nmake(target="clean"),
|
||||||
cmd_nmake(target="fribidi"),
|
cmd_nmake(target="fribidi"),
|
||||||
],
|
],
|
||||||
"headers": [r"lib\*.h"],
|
"bins": [r"*.dll"],
|
||||||
"libs": [r"*.lib"],
|
|
||||||
},
|
|
||||||
"libraqm": {
|
|
||||||
"url": "https://github.com/HOST-Oman/libraqm/archive/v0.7.1.zip",
|
|
||||||
"filename": "libraqm-0.7.1.zip",
|
|
||||||
"dir": "libraqm-0.7.1",
|
|
||||||
"build": [
|
|
||||||
cmd_copy(r"{winbuild_dir}\raqm.cmake", r"CMakeLists.txt"),
|
|
||||||
cmd_cmake(),
|
|
||||||
cmd_nmake(target="clean"),
|
|
||||||
cmd_nmake(target="libraqm"),
|
|
||||||
],
|
|
||||||
"headers": [r"src\*.h"],
|
|
||||||
"bins": [r"libraqm.dll"],
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,8 +497,8 @@ if __name__ == "__main__":
|
||||||
verbose = True
|
verbose = True
|
||||||
elif arg == "--no-imagequant":
|
elif arg == "--no-imagequant":
|
||||||
disabled += ["libimagequant"]
|
disabled += ["libimagequant"]
|
||||||
elif arg == "--no-raqm":
|
elif arg == "--no-raqm" or arg == "--no-fribidi":
|
||||||
disabled += ["fribidi", "libraqm"]
|
disabled += ["fribidi"]
|
||||||
elif arg.startswith("--depends="):
|
elif arg.startswith("--depends="):
|
||||||
depends_dir = arg[10:]
|
depends_dir = arg[10:]
|
||||||
elif arg.startswith("--python="):
|
elif arg.startswith("--python="):
|
||||||
|
|
|
@ -93,10 +93,10 @@ fribidi_tab(brackets-type unidata/BidiBrackets.txt)
|
||||||
file(GLOB FRIBIDI_SOURCES lib/*.c)
|
file(GLOB FRIBIDI_SOURCES lib/*.c)
|
||||||
file(GLOB FRIBIDI_HEADERS lib/*.h)
|
file(GLOB FRIBIDI_HEADERS lib/*.h)
|
||||||
|
|
||||||
add_library(fribidi STATIC
|
add_library(fribidi SHARED
|
||||||
${FRIBIDI_SOURCES}
|
${FRIBIDI_SOURCES}
|
||||||
${FRIBIDI_HEADERS}
|
${FRIBIDI_HEADERS}
|
||||||
${FRIBIDI_SOURCES_GENERATED})
|
${FRIBIDI_SOURCES_GENERATED})
|
||||||
fribidi_definitions(fribidi)
|
fribidi_definitions(fribidi)
|
||||||
target_compile_definitions(fribidi
|
target_compile_definitions(fribidi
|
||||||
PUBLIC -DFRIBIDI_LIB_STATIC)
|
PUBLIC "-DFRIBIDI_ENTRY=__declspec(dllexport)")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user