mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-05-29 02:03:25 +03:00
Merge pull request #5062 from nulano/fribidi-link
Dynamically link FriBiDi instead of Raqm
This commit is contained in:
commit
3addd7df4e
5
.github/workflows/test-windows.yml
vendored
5
.github/workflows/test-windows.yml
vendored
|
@ -137,14 +137,11 @@ jobs:
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_harfbuzz.cmd"
|
run: "& winbuild\\build\\build_dep_harfbuzz.cmd"
|
||||||
|
|
||||||
|
# Raqm dependencies
|
||||||
- name: Build dependencies / FriBidi
|
- name: Build dependencies / FriBidi
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
run: "& winbuild\\build\\build_dep_fribidi.cmd"
|
run: "& winbuild\\build\\build_dep_fribidi.cmd"
|
||||||
|
|
||||||
- name: Build dependencies / Raqm
|
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
|
||||||
run: "& winbuild\\build\\build_dep_libraqm.cmd"
|
|
||||||
|
|
||||||
# trim ~150MB x 9
|
# trim ~150MB x 9
|
||||||
- name: Optimize build cache
|
- name: Optimize build cache
|
||||||
if: steps.build-cache.outputs.cache-hit != 'true'
|
if: steps.build-cache.outputs.cache-hit != 'true'
|
||||||
|
|
120
setup.py
120
setup.py
|
@ -29,6 +29,8 @@ def get_version():
|
||||||
NAME = "Pillow"
|
NAME = "Pillow"
|
||||||
PILLOW_VERSION = get_version()
|
PILLOW_VERSION = get_version()
|
||||||
FREETYPE_ROOT = None
|
FREETYPE_ROOT = None
|
||||||
|
HARFBUZZ_ROOT = None
|
||||||
|
FRIBIDI_ROOT = None
|
||||||
IMAGEQUANT_ROOT = None
|
IMAGEQUANT_ROOT = None
|
||||||
JPEG2K_ROOT = None
|
JPEG2K_ROOT = None
|
||||||
JPEG_ROOT = None
|
JPEG_ROOT = None
|
||||||
|
@ -228,6 +230,19 @@ def _find_library_file(self, library):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def _find_include_dir(self, dirname, include):
|
||||||
|
for directory in self.compiler.include_dirs:
|
||||||
|
_dbg("Checking for include file %s in %s", (include, directory))
|
||||||
|
if os.path.isfile(os.path.join(directory, include)):
|
||||||
|
_dbg("Found %s in %s", (include, directory))
|
||||||
|
return True
|
||||||
|
subdir = os.path.join(directory, dirname)
|
||||||
|
_dbg("Checking for include file %s in %s", (include, subdir))
|
||||||
|
if os.path.isfile(os.path.join(subdir, include)):
|
||||||
|
_dbg("Found %s in %s", (include, subdir))
|
||||||
|
return subdir
|
||||||
|
|
||||||
|
|
||||||
def _cmd_exists(cmd):
|
def _cmd_exists(cmd):
|
||||||
return any(
|
return any(
|
||||||
os.access(os.path.join(path, cmd), os.X_OK)
|
os.access(os.path.join(path, cmd), os.X_OK)
|
||||||
|
@ -267,6 +282,7 @@ class pil_build_ext(build_ext):
|
||||||
"jpeg",
|
"jpeg",
|
||||||
"tiff",
|
"tiff",
|
||||||
"freetype",
|
"freetype",
|
||||||
|
"raqm",
|
||||||
"lcms",
|
"lcms",
|
||||||
"webp",
|
"webp",
|
||||||
"webpmux",
|
"webpmux",
|
||||||
|
@ -276,6 +292,7 @@ class pil_build_ext(build_ext):
|
||||||
]
|
]
|
||||||
|
|
||||||
required = {"jpeg", "zlib"}
|
required = {"jpeg", "zlib"}
|
||||||
|
vendor = set()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
for f in self.features:
|
for f in self.features:
|
||||||
|
@ -287,6 +304,9 @@ class pil_build_ext(build_ext):
|
||||||
def want(self, feat):
|
def want(self, feat):
|
||||||
return getattr(self, feat) is None
|
return getattr(self, feat) is None
|
||||||
|
|
||||||
|
def want_vendor(self, feat):
|
||||||
|
return feat in self.vendor
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
yield from self.features
|
yield from self.features
|
||||||
|
|
||||||
|
@ -296,6 +316,10 @@ class pil_build_ext(build_ext):
|
||||||
build_ext.user_options
|
build_ext.user_options
|
||||||
+ [(f"disable-{x}", None, f"Disable support for {x}") for x in feature]
|
+ [(f"disable-{x}", None, f"Disable support for {x}") for x in feature]
|
||||||
+ [(f"enable-{x}", None, f"Enable support for {x}") for x in feature]
|
+ [(f"enable-{x}", None, f"Enable support for {x}") for x in feature]
|
||||||
|
+ [
|
||||||
|
(f"vendor-{x}", None, f"Use vendored version of {x}")
|
||||||
|
for x in ("raqm", "fribidi")
|
||||||
|
]
|
||||||
+ [
|
+ [
|
||||||
("disable-platform-guessing", None, "Disable platform guessing on Linux"),
|
("disable-platform-guessing", None, "Disable platform guessing on Linux"),
|
||||||
("debug", None, "Debug logging"),
|
("debug", None, "Debug logging"),
|
||||||
|
@ -310,6 +334,8 @@ class pil_build_ext(build_ext):
|
||||||
for x in self.feature:
|
for x in self.feature:
|
||||||
setattr(self, f"disable_{x}", None)
|
setattr(self, f"disable_{x}", None)
|
||||||
setattr(self, f"enable_{x}", None)
|
setattr(self, f"enable_{x}", None)
|
||||||
|
for x in ("raqm", "fribidi"):
|
||||||
|
setattr(self, f"vendor_{x}", None)
|
||||||
|
|
||||||
def finalize_options(self):
|
def finalize_options(self):
|
||||||
build_ext.finalize_options(self)
|
build_ext.finalize_options(self)
|
||||||
|
@ -334,18 +360,40 @@ class pil_build_ext(build_ext):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Conflicting options: --enable-{x} and --disable-{x}"
|
f"Conflicting options: --enable-{x} and --disable-{x}"
|
||||||
)
|
)
|
||||||
|
if x == "freetype":
|
||||||
|
_dbg("--disable-freetype implies --disable-raqm")
|
||||||
|
if getattr(self, "enable_raqm"):
|
||||||
|
raise ValueError(
|
||||||
|
"Conflicting options: --enable-raqm and --disable-freetype"
|
||||||
|
)
|
||||||
|
setattr(self, "disable_raqm", True)
|
||||||
if getattr(self, f"enable_{x}"):
|
if getattr(self, f"enable_{x}"):
|
||||||
_dbg("Requiring %s", x)
|
_dbg("Requiring %s", x)
|
||||||
self.feature.required.add(x)
|
self.feature.required.add(x)
|
||||||
|
if x == "raqm":
|
||||||
|
_dbg("--enable-raqm implies --enable-freetype")
|
||||||
|
self.feature.required.add("freetype")
|
||||||
|
for x in ("raqm", "fribidi"):
|
||||||
|
if getattr(self, f"vendor_{x}"):
|
||||||
|
if getattr(self, "disable_raqm"):
|
||||||
|
raise ValueError(
|
||||||
|
f"Conflicting options: --vendor-{x} and --disable-raqm"
|
||||||
|
)
|
||||||
|
if x == "fribidi" and not getattr(self, "vendor_raqm"):
|
||||||
|
raise ValueError(
|
||||||
|
f"Conflicting options: --vendor-{x} and not --vendor-raqm"
|
||||||
|
)
|
||||||
|
_dbg("Using vendored version of %s", x)
|
||||||
|
self.feature.vendor.add(x)
|
||||||
|
|
||||||
def _update_extension(self, name, libraries, define_macros=None, include_dirs=None):
|
def _update_extension(self, name, libraries, define_macros=None, sources=None):
|
||||||
for extension in self.extensions:
|
for extension in self.extensions:
|
||||||
if extension.name == name:
|
if extension.name == name:
|
||||||
extension.libraries += libraries
|
extension.libraries += libraries
|
||||||
if define_macros is not None:
|
if define_macros is not None:
|
||||||
extension.define_macros += define_macros
|
extension.define_macros += define_macros
|
||||||
if include_dirs is not None:
|
if sources is not None:
|
||||||
extension.include_dirs += include_dirs
|
extension.sources += sources
|
||||||
if FUZZING_BUILD:
|
if FUZZING_BUILD:
|
||||||
extension.language = "c++"
|
extension.language = "c++"
|
||||||
extension.extra_link_args = ["--stdlib=libc++"]
|
extension.extra_link_args = ["--stdlib=libc++"]
|
||||||
|
@ -374,6 +422,8 @@ class pil_build_ext(build_ext):
|
||||||
TIFF_ROOT=("libtiff-5", "libtiff-4"),
|
TIFF_ROOT=("libtiff-5", "libtiff-4"),
|
||||||
ZLIB_ROOT="zlib",
|
ZLIB_ROOT="zlib",
|
||||||
FREETYPE_ROOT="freetype2",
|
FREETYPE_ROOT="freetype2",
|
||||||
|
HARFBUZZ_ROOT="harfbuzz",
|
||||||
|
FRIBIDI_ROOT="fribidi",
|
||||||
LCMS_ROOT="lcms2",
|
LCMS_ROOT="lcms2",
|
||||||
IMAGEQUANT_ROOT="libimagequant",
|
IMAGEQUANT_ROOT="libimagequant",
|
||||||
).items():
|
).items():
|
||||||
|
@ -659,6 +709,39 @@ 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.freetype and feature.want("raqm"):
|
||||||
|
if not feature.want_vendor("raqm"): # want system Raqm
|
||||||
|
_dbg("Looking for Raqm")
|
||||||
|
if _find_include_file(self, "raqm.h"):
|
||||||
|
if _find_library_file(self, "raqm"):
|
||||||
|
feature.raqm = "raqm"
|
||||||
|
elif _find_library_file(self, "libraqm"):
|
||||||
|
feature.raqm = "libraqm"
|
||||||
|
else: # want to build Raqm from src/thirdparty
|
||||||
|
_dbg("Looking for HarfBuzz")
|
||||||
|
feature.harfbuzz = None
|
||||||
|
hb_dir = _find_include_dir(self, "harfbuzz", "hb.h")
|
||||||
|
if hb_dir:
|
||||||
|
if isinstance(hb_dir, str):
|
||||||
|
_add_directory(self.compiler.include_dirs, hb_dir, 0)
|
||||||
|
if _find_library_file(self, "harfbuzz"):
|
||||||
|
feature.harfbuzz = "harfbuzz"
|
||||||
|
if feature.harfbuzz:
|
||||||
|
if not feature.want_vendor("fribidi"): # want system FriBiDi
|
||||||
|
_dbg("Looking for FriBiDi")
|
||||||
|
feature.fribidi = None
|
||||||
|
fribidi_dir = _find_include_dir(self, "fribidi", "fribidi.h")
|
||||||
|
if fribidi_dir:
|
||||||
|
if isinstance(fribidi_dir, str):
|
||||||
|
_add_directory(
|
||||||
|
self.compiler.include_dirs, fribidi_dir, 0
|
||||||
|
)
|
||||||
|
if _find_library_file(self, "fribidi"):
|
||||||
|
feature.fribidi = "fribidi"
|
||||||
|
feature.raqm = True
|
||||||
|
else: # want to build FriBiDi shim from src/thirdparty
|
||||||
|
feature.raqm = True
|
||||||
|
|
||||||
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"):
|
||||||
|
@ -754,9 +837,25 @@ class pil_build_ext(build_ext):
|
||||||
# additional libraries
|
# additional libraries
|
||||||
|
|
||||||
if feature.freetype:
|
if feature.freetype:
|
||||||
|
srcs = []
|
||||||
libs = ["freetype"]
|
libs = ["freetype"]
|
||||||
defs = []
|
defs = []
|
||||||
self._update_extension("PIL._imagingft", libs, defs)
|
if feature.raqm:
|
||||||
|
if not feature.want_vendor("raqm"): # using system Raqm
|
||||||
|
defs.append(("HAVE_RAQM", None))
|
||||||
|
defs.append(("HAVE_RAQM_SYSTEM", None))
|
||||||
|
libs.append(feature.raqm)
|
||||||
|
else: # building Raqm from src/thirdparty
|
||||||
|
defs.append(("HAVE_RAQM", None))
|
||||||
|
srcs.append("src/thirdparty/raqm/raqm.c")
|
||||||
|
libs.append(feature.harfbuzz)
|
||||||
|
if not feature.want_vendor("fribidi"): # using system FriBiDi
|
||||||
|
defs.append(("HAVE_FRIBIDI_SYSTEM", None))
|
||||||
|
libs.append(feature.fribidi)
|
||||||
|
else: # building FriBiDi shim from src/thirdparty
|
||||||
|
srcs.append("src/thirdparty/fribidi-shim/fribidi.c")
|
||||||
|
self._update_extension("PIL._imagingft", libs, defs, srcs)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self._remove_extension("PIL._imagingft")
|
self._remove_extension("PIL._imagingft")
|
||||||
|
|
||||||
|
@ -803,6 +902,12 @@ class pil_build_ext(build_ext):
|
||||||
print(f" [{v.strip()}")
|
print(f" [{v.strip()}")
|
||||||
print("-" * 68)
|
print("-" * 68)
|
||||||
|
|
||||||
|
raqm_extra_info = ""
|
||||||
|
if feature.want_vendor("raqm"):
|
||||||
|
raqm_extra_info += "bundled"
|
||||||
|
if feature.want_vendor("fribidi"):
|
||||||
|
raqm_extra_info += ", FriBiDi shim"
|
||||||
|
|
||||||
options = [
|
options = [
|
||||||
(feature.jpeg, "JPEG"),
|
(feature.jpeg, "JPEG"),
|
||||||
(feature.jpeg2000, "OPENJPEG (JPEG2000)", feature.openjpeg_version),
|
(feature.jpeg2000, "OPENJPEG (JPEG2000)", feature.openjpeg_version),
|
||||||
|
@ -810,6 +915,7 @@ class pil_build_ext(build_ext):
|
||||||
(feature.imagequant, "LIBIMAGEQUANT"),
|
(feature.imagequant, "LIBIMAGEQUANT"),
|
||||||
(feature.tiff, "LIBTIFF"),
|
(feature.tiff, "LIBTIFF"),
|
||||||
(feature.freetype, "FREETYPE2"),
|
(feature.freetype, "FREETYPE2"),
|
||||||
|
(feature.raqm, "RAQM (Text shaping)", raqm_extra_info),
|
||||||
(feature.lcms, "LITTLECMS2"),
|
(feature.lcms, "LITTLECMS2"),
|
||||||
(feature.webp, "WEBP"),
|
(feature.webp, "WEBP"),
|
||||||
(feature.webpmux, "WEBPMUX"),
|
(feature.webpmux, "WEBPMUX"),
|
||||||
|
@ -819,10 +925,10 @@ class pil_build_ext(build_ext):
|
||||||
all = 1
|
all = 1
|
||||||
for option in options:
|
for option in options:
|
||||||
if option[0]:
|
if option[0]:
|
||||||
version = ""
|
extra_info = ""
|
||||||
if len(option) >= 3 and option[2]:
|
if len(option) >= 3 and option[2]:
|
||||||
version = f" ({option[2]})"
|
extra_info = f" ({option[2]})"
|
||||||
print(f"--- {option[1]} support available{version}")
|
print(f"--- {option[1]} support available{extra_info}")
|
||||||
else:
|
else:
|
||||||
print(f"*** {option[1]} support not available")
|
print(f"*** {option[1]} support not available")
|
||||||
all = 0
|
all = 0
|
||||||
|
|
|
@ -118,6 +118,8 @@ features = {
|
||||||
"webp_mux": ("PIL._webp", "HAVE_WEBPMUX", None),
|
"webp_mux": ("PIL._webp", "HAVE_WEBPMUX", None),
|
||||||
"transp_webp": ("PIL._webp", "HAVE_TRANSPARENCY", None),
|
"transp_webp": ("PIL._webp", "HAVE_TRANSPARENCY", None),
|
||||||
"raqm": ("PIL._imagingft", "HAVE_RAQM", "raqm_version"),
|
"raqm": ("PIL._imagingft", "HAVE_RAQM", "raqm_version"),
|
||||||
|
"fribidi": ("PIL._imagingft", "HAVE_FRIBIDI", "fribidi_version"),
|
||||||
|
"harfbuzz": ("PIL._imagingft", "HAVE_HARFBUZZ", "harfbuzz_version"),
|
||||||
"libjpeg_turbo": ("PIL._imaging", "HAVE_LIBJPEGTURBO", "libjpeg_turbo_version"),
|
"libjpeg_turbo": ("PIL._imaging", "HAVE_LIBJPEGTURBO", "libjpeg_turbo_version"),
|
||||||
"libimagequant": ("PIL._imaging", "HAVE_LIBIMAGEQUANT", "imagequant_version"),
|
"libimagequant": ("PIL._imaging", "HAVE_LIBIMAGEQUANT", "imagequant_version"),
|
||||||
"xcb": ("PIL._imaging", "HAVE_XCB", None),
|
"xcb": ("PIL._imaging", "HAVE_XCB", None),
|
||||||
|
@ -274,6 +276,11 @@ def pilinfo(out=None, supported_formats=True):
|
||||||
# this check is also in src/_imagingcms.c:setup_module()
|
# this check is also in src/_imagingcms.c:setup_module()
|
||||||
version_static = tuple(int(x) for x in v.split(".")) < (2, 7)
|
version_static = tuple(int(x) for x in v.split(".")) < (2, 7)
|
||||||
t = "compiled for" if version_static else "loaded"
|
t = "compiled for" if version_static else "loaded"
|
||||||
|
if name == "raqm":
|
||||||
|
for f in ("fribidi", "harfbuzz"):
|
||||||
|
v2 = version_feature(f)
|
||||||
|
if v2 is not None:
|
||||||
|
v += f", {f} {v2}"
|
||||||
print("---", feature, "support ok,", t, v, file=out)
|
print("---", feature, "support ok,", t, v, file=out)
|
||||||
else:
|
else:
|
||||||
print("---", feature, "support ok", file=out)
|
print("---", feature, "support ok", file=out)
|
||||||
|
|
291
src/_imagingft.c
291
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,21 @@
|
||||||
} \
|
} \
|
||||||
;
|
;
|
||||||
|
|
||||||
#include "libImaging/raqm.h"
|
#ifdef HAVE_RAQM
|
||||||
|
# ifdef HAVE_RAQM_SYSTEM
|
||||||
|
# include <raqm.h>
|
||||||
|
# else
|
||||||
|
# include "thirdparty/raqm/raqm.h"
|
||||||
|
# ifdef HAVE_FRIBIDI_SYSTEM
|
||||||
|
# include <fribidi.h>
|
||||||
|
# else
|
||||||
|
# include "thirdparty/fribidi-shim/fribidi.h"
|
||||||
|
# include <hb.h>
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int have_raqm = 0;
|
||||||
|
|
||||||
#define LAYOUT_FALLBACK 0
|
#define LAYOUT_FALLBACK 0
|
||||||
#define LAYOUT_RAQM 1
|
#define LAYOUT_RAQM 1
|
||||||
|
@ -86,42 +96,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)
|
||||||
|
|
||||||
|
@ -140,105 +114,6 @@ geterror(int code) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
setraqm(void) {
|
|
||||||
/* set the static function pointers for dynamic raqm linking */
|
|
||||||
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 *
|
||||||
getfont(PyObject *self_, PyObject *args, PyObject *kw) {
|
getfont(PyObject *self_, PyObject *args, PyObject *kw) {
|
||||||
/* create a font object from a file name and a size (in pixels) */
|
/* create a font object from a file name and a size (in pixels) */
|
||||||
|
@ -346,6 +221,8 @@ font_getchar(PyObject *string, int index, FT_ULong *char_out) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_RAQM
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
text_layout_raqm(
|
text_layout_raqm(
|
||||||
PyObject *string,
|
PyObject *string,
|
||||||
|
@ -359,10 +236,9 @@ 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_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 +252,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 +277,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 !defined(RAQM_VERSION_ATLEAST) || !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;
|
||||||
}
|
#endif
|
||||||
} 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 +290,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,37 +322,28 @@ 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) {
|
glyphs = raqm_get_glyphs(rq, &count);
|
||||||
glyphs_01 = (*p_raqm.get_glyphs_01)(rq, &count);
|
if (glyphs == 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 */
|
|
||||||
glyphs = (*p_raqm.get_glyphs)(rq, &count);
|
|
||||||
if (glyphs == NULL) {
|
|
||||||
PyErr_SetString(PyExc_ValueError, "raqm_get_glyphs() failed.");
|
|
||||||
count = 0;
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(*glyph_info) = PyMem_New(GlyphInfo, count);
|
(*glyph_info) = PyMem_New(GlyphInfo, count);
|
||||||
|
@ -486,31 +353,22 @@ text_layout_raqm(
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_raqm.version == 1) {
|
for (i = 0; i < count; i++) {
|
||||||
for (i = 0; i < count; i++) {
|
(*glyph_info)[i].index = glyphs[i].index;
|
||||||
(*glyph_info)[i].index = glyphs_01[i].index;
|
(*glyph_info)[i].x_offset = glyphs[i].x_offset;
|
||||||
(*glyph_info)[i].x_offset = glyphs_01[i].x_offset;
|
(*glyph_info)[i].x_advance = glyphs[i].x_advance;
|
||||||
(*glyph_info)[i].x_advance = glyphs_01[i].x_advance;
|
(*glyph_info)[i].y_offset = glyphs[i].y_offset;
|
||||||
(*glyph_info)[i].y_offset = glyphs_01[i].y_offset;
|
(*glyph_info)[i].y_advance = glyphs[i].y_advance;
|
||||||
(*glyph_info)[i].y_advance = glyphs_01[i].y_advance;
|
(*glyph_info)[i].cluster = glyphs[i].cluster;
|
||||||
(*glyph_info)[i].cluster = glyphs_01[i].cluster;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
(*glyph_info)[i].index = glyphs[i].index;
|
|
||||||
(*glyph_info)[i].x_offset = glyphs[i].x_offset;
|
|
||||||
(*glyph_info)[i].x_advance = glyphs[i].x_advance;
|
|
||||||
(*glyph_info)[i].y_offset = glyphs[i].y_offset;
|
|
||||||
(*glyph_info)[i].y_advance = glyphs[i].y_advance;
|
|
||||||
(*glyph_info)[i].cluster = glyphs[i].cluster;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
(*p_raqm.destroy)(rq);
|
raqm_destroy(rq);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
text_layout_fallback(
|
text_layout_fallback(
|
||||||
PyObject *string,
|
PyObject *string,
|
||||||
|
@ -606,11 +464,13 @@ text_layout(
|
||||||
int mask,
|
int mask,
|
||||||
int color) {
|
int color) {
|
||||||
size_t count;
|
size_t count;
|
||||||
|
#ifdef HAVE_RAQM
|
||||||
if (p_raqm.raqm && self->layout_engine == LAYOUT_RAQM) {
|
if (have_raqm && 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
|
||||||
|
#endif
|
||||||
|
{
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -1490,12 +1350,51 @@ setup_module(PyObject *m) {
|
||||||
v = PyUnicode_FromFormat("%d.%d.%d", major, minor, patch);
|
v = PyUnicode_FromFormat("%d.%d.%d", major, minor, patch);
|
||||||
PyDict_SetItemString(d, "freetype2_version", v);
|
PyDict_SetItemString(d, "freetype2_version", v);
|
||||||
|
|
||||||
setraqm();
|
#ifdef HAVE_RAQM
|
||||||
v = PyBool_FromLong(!!p_raqm.raqm);
|
#if defined(HAVE_RAQM_SYSTEM) || defined(HAVE_FRIBIDI_SYSTEM)
|
||||||
|
have_raqm = 1;
|
||||||
|
#else
|
||||||
|
load_fribidi();
|
||||||
|
have_raqm = !!p_fribidi;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
have_raqm = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* if we have Raqm, we have all three (but possibly no version info) */
|
||||||
|
v = PyBool_FromLong(have_raqm);
|
||||||
PyDict_SetItemString(d, "HAVE_RAQM", v);
|
PyDict_SetItemString(d, "HAVE_RAQM", v);
|
||||||
if (p_raqm.version_string) {
|
PyDict_SetItemString(d, "HAVE_FRIBIDI", v);
|
||||||
PyDict_SetItemString(
|
PyDict_SetItemString(d, "HAVE_HARFBUZZ", v);
|
||||||
d, "raqm_version", PyUnicode_FromString(p_raqm.version_string()));
|
if (have_raqm) {
|
||||||
|
#ifdef RAQM_VERSION_MAJOR
|
||||||
|
v = PyUnicode_FromString(raqm_version_string());
|
||||||
|
#else
|
||||||
|
v = Py_None;
|
||||||
|
#endif
|
||||||
|
PyDict_SetItemString(d, "raqm_version", v);
|
||||||
|
|
||||||
|
#ifdef FRIBIDI_MAJOR_VERSION
|
||||||
|
{
|
||||||
|
const char *a = strchr(fribidi_version_info, ')');
|
||||||
|
const char *b = strchr(fribidi_version_info, '\n');
|
||||||
|
if (a && b && a + 2 < b) {
|
||||||
|
v = PyUnicode_FromStringAndSize(a + 2, b - (a + 2));
|
||||||
|
} else {
|
||||||
|
v = Py_None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
v = Py_None;
|
||||||
|
#endif
|
||||||
|
PyDict_SetItemString(d, "fribidi_version", v);
|
||||||
|
|
||||||
|
#ifdef HB_VERSION_STRING
|
||||||
|
v = PyUnicode_FromString(hb_version_string());
|
||||||
|
#else
|
||||||
|
v = Py_None;
|
||||||
|
#endif
|
||||||
|
PyDict_SetItemString(d, "harfbuzz_version", v);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
101
src/thirdparty/fribidi-shim/fribidi.c
vendored
Normal file
101
src/thirdparty/fribidi-shim/fribidi.c
vendored
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#else
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FRIBIDI_SHIM_IMPLEMENTATION
|
||||||
|
|
||||||
|
#include "fribidi.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* FriBiDi>=1.0.0 adds bracket_types param, ignore and call legacy function */
|
||||||
|
FriBidiLevel fribidi_get_par_embedding_levels_ex_compat(
|
||||||
|
const FriBidiCharType *bidi_types,
|
||||||
|
const FriBidiBracketType *bracket_types,
|
||||||
|
const FriBidiStrIndex len,
|
||||||
|
FriBidiParType *pbase_dir,
|
||||||
|
FriBidiLevel *embedding_levels)
|
||||||
|
{
|
||||||
|
return fribidi_get_par_embedding_levels(
|
||||||
|
bidi_types, len, pbase_dir, embedding_levels);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FriBiDi>=1.0.0 gets bracket types here, ignore */
|
||||||
|
void fribidi_get_bracket_types_compat(
|
||||||
|
const FriBidiChar *str,
|
||||||
|
const FriBidiStrIndex len,
|
||||||
|
const FriBidiCharType *types,
|
||||||
|
FriBidiBracketType *btypes)
|
||||||
|
{ /* no-op*/ }
|
||||||
|
|
||||||
|
|
||||||
|
int load_fribidi(void) {
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
p_fribidi = 0;
|
||||||
|
|
||||||
|
/* Microsoft needs a totally different system */
|
||||||
|
#ifndef _WIN32
|
||||||
|
#define LOAD_FUNCTION(func) \
|
||||||
|
func = (t_##func)dlsym(p_fribidi, #func); \
|
||||||
|
error = error || (func == 0);
|
||||||
|
|
||||||
|
p_fribidi = dlopen("libfribidi.so", RTLD_LAZY);
|
||||||
|
if (!p_fribidi) {
|
||||||
|
p_fribidi = dlopen("libfribidi.so.0", RTLD_LAZY);
|
||||||
|
}
|
||||||
|
if (!p_fribidi) {
|
||||||
|
p_fribidi = dlopen("libfribidi.dylib", RTLD_LAZY);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define LOAD_FUNCTION(func) \
|
||||||
|
func = (t_##func)GetProcAddress(p_fribidi, #func); \
|
||||||
|
error = error || (func == 0);
|
||||||
|
|
||||||
|
p_fribidi = LoadLibrary("fribidi");
|
||||||
|
/* MSYS2 */
|
||||||
|
if (!p_fribidi) {
|
||||||
|
p_fribidi = LoadLibrary("libfribidi-0");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!p_fribidi) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* load FriBiDi>=1.0.0 functions first, use error to detect version */
|
||||||
|
LOAD_FUNCTION(fribidi_get_par_embedding_levels_ex);
|
||||||
|
LOAD_FUNCTION(fribidi_get_bracket_types);
|
||||||
|
if (error) {
|
||||||
|
/* using FriBiDi<1.0.0, ignore new parameters */
|
||||||
|
error = 0;
|
||||||
|
fribidi_get_par_embedding_levels_ex = &fribidi_get_par_embedding_levels_ex_compat;
|
||||||
|
fribidi_get_bracket_types = &fribidi_get_bracket_types_compat;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOAD_FUNCTION(fribidi_unicode_to_charset);
|
||||||
|
LOAD_FUNCTION(fribidi_charset_to_unicode);
|
||||||
|
LOAD_FUNCTION(fribidi_get_bidi_types);
|
||||||
|
LOAD_FUNCTION(fribidi_get_par_embedding_levels);
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
fribidi_version_info = *(const char**)dlsym(p_fribidi, "fribidi_version_info");
|
||||||
|
if (dlerror() || error || (fribidi_version_info == 0)) {
|
||||||
|
dlclose(p_fribidi);
|
||||||
|
p_fribidi = 0;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
fribidi_version_info = *(const char**)GetProcAddress(p_fribidi, "fribidi_version_info");
|
||||||
|
if (error || (fribidi_version_info == 0)) {
|
||||||
|
FreeLibrary(p_fribidi);
|
||||||
|
p_fribidi = 0;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
111
src/thirdparty/fribidi-shim/fribidi.h
vendored
Normal file
111
src/thirdparty/fribidi-shim/fribidi.h
vendored
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
|
||||||
|
#define FRIBIDI_MAJOR_VERSION 1
|
||||||
|
|
||||||
|
/* 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(FriBidiStrIndex, fribidi_unicode_to_charset,
|
||||||
|
FriBidiCharSet, const FriBidiChar *, FriBidiStrIndex, char *);
|
||||||
|
|
||||||
|
FRIBIDI_FUNC(FriBidiStrIndex, fribidi_charset_to_unicode,
|
||||||
|
FriBidiCharSet, const char *, FriBidiStrIndex, FriBidiChar *);
|
||||||
|
|
||||||
|
FRIBIDI_FUNC(void, fribidi_get_bidi_types,
|
||||||
|
const FriBidiChar *, const FriBidiStrIndex, FriBidiCharType *);
|
||||||
|
|
||||||
|
FRIBIDI_FUNC(FriBidiLevel, fribidi_get_par_embedding_levels,
|
||||||
|
const FriBidiCharType *, const FriBidiStrIndex, FriBidiParType *,
|
||||||
|
FriBidiLevel *);
|
||||||
|
|
||||||
|
/* FriBiDi>=1.0.0 */
|
||||||
|
FRIBIDI_FUNC(FriBidiLevel, fribidi_get_par_embedding_levels_ex,
|
||||||
|
const FriBidiCharType *, const FriBidiBracketType *, const FriBidiStrIndex,
|
||||||
|
FriBidiParType *, FriBidiLevel *);
|
||||||
|
|
||||||
|
/* FriBiDi>=1.0.0 */
|
||||||
|
FRIBIDI_FUNC(void, fribidi_get_bracket_types,
|
||||||
|
const FriBidiChar *, const FriBidiStrIndex, const FriBidiCharType *,
|
||||||
|
FriBidiBracketType *);
|
||||||
|
|
||||||
|
#undef FRIBIDI_FUNC
|
||||||
|
|
||||||
|
/* constant, not a function */
|
||||||
|
FRIBIDI_ENTRY const char *fribidi_version_info;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* shim */
|
||||||
|
|
||||||
|
FRIBIDI_ENTRY void *p_fribidi;
|
||||||
|
|
||||||
|
FRIBIDI_ENTRY int load_fribidi(void);
|
||||||
|
|
||||||
|
#undef FRIBIDI_ENTRY
|
9
src/thirdparty/raqm/AUTHORS
vendored
Normal file
9
src/thirdparty/raqm/AUTHORS
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
Abderraouf Adjal
|
||||||
|
Ali Yousuf
|
||||||
|
Anood Almuharbi
|
||||||
|
Asma Albahanta
|
||||||
|
Fahad Alsaidi
|
||||||
|
Ibtisam Almabsali
|
||||||
|
Khaled Hosny
|
||||||
|
Mazoon Almaamari
|
||||||
|
Shamsa Alqassabi
|
22
src/thirdparty/raqm/COPYING
vendored
Normal file
22
src/thirdparty/raqm/COPYING
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
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.
|
89
src/thirdparty/raqm/NEWS
vendored
Normal file
89
src/thirdparty/raqm/NEWS
vendored
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
Overview of changes leading to 0.7.1
|
||||||
|
Sunday, November 22, 2020
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Require HarfBuzz >= 2.0.0
|
||||||
|
|
||||||
|
Build and documentation fixes.
|
||||||
|
|
||||||
|
Overview of changes leading to 0.7.0
|
||||||
|
Monday, May 27, 2019
|
||||||
|
====================================
|
||||||
|
|
||||||
|
New API:
|
||||||
|
* raqm_version
|
||||||
|
* raqm_version_string
|
||||||
|
* raqm_version_atleast
|
||||||
|
* RAQM_VERSION_MAJOR
|
||||||
|
* RAQM_VERSION_MICRO
|
||||||
|
* RAQM_VERSION_MINOR
|
||||||
|
* RAQM_VERSION_STRING
|
||||||
|
* RAQM_VERSION_ATLEAST
|
||||||
|
|
||||||
|
Overview of changes leading to 0.6.0
|
||||||
|
Sunday, May 5, 2019
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Fix TTB direction regression from the previous release.
|
||||||
|
|
||||||
|
Correctly detect script of Common and Inherite characters at start of text.
|
||||||
|
|
||||||
|
Undef HAVE_CONFIG_H workaround, for older versions of Fribidi.
|
||||||
|
|
||||||
|
Drop test suite dependency on GLib.
|
||||||
|
|
||||||
|
Port test runner to Python instead of shell script.
|
||||||
|
|
||||||
|
New API:
|
||||||
|
* raqm_set_invisible_glyph()
|
||||||
|
|
||||||
|
Overview of changes leading to 0.5.0
|
||||||
|
Saturday, February 24, 2018
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Use FriBiDi 1.x API when available.
|
||||||
|
|
||||||
|
Overview of changes leading to 0.4.0
|
||||||
|
Sunday, January 21, 2018
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Set begin-of-text and end-of-text HarfBuzz buffer flags.
|
||||||
|
|
||||||
|
Dynamically allocate memory instead of using stack allocation for input text.
|
||||||
|
|
||||||
|
Accept zero length text and do nothing instead of treating it as error.
|
||||||
|
|
||||||
|
Overview of changes leading to 0.3.0
|
||||||
|
Monday, August 21, 2017
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Fix stack corruption on MSVC.
|
||||||
|
|
||||||
|
New API:
|
||||||
|
* raqm_set_freetype_load_flags
|
||||||
|
|
||||||
|
Overview of changes leading to 0.2.0
|
||||||
|
Wednesday, August 25, 2016
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Fix building with MSVC due to lacking C99 support.
|
||||||
|
|
||||||
|
Make multiple fonts support actually work. Start and length now respect the
|
||||||
|
input encoding.
|
||||||
|
|
||||||
|
New API:
|
||||||
|
* raqm_index_to_position
|
||||||
|
* raqm_position_to_index
|
||||||
|
* raqm_set_language
|
||||||
|
|
||||||
|
Overview of changes leading to 0.1.1
|
||||||
|
Sunday, May 1, 2016
|
||||||
|
====================================
|
||||||
|
|
||||||
|
Fix make check on 32-bit systems.
|
||||||
|
|
||||||
|
Overview of changes leading to 0.1.0
|
||||||
|
Wednesday, January 20, 2016
|
||||||
|
====================================
|
||||||
|
|
||||||
|
First release.
|
85
src/thirdparty/raqm/README
vendored
Normal file
85
src/thirdparty/raqm/README
vendored
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
Raqm
|
||||||
|
====
|
||||||
|
|
||||||
|
[](https://travis-ci.org/HOST-Oman/libraqm)
|
||||||
|
[](https://ci.appveyor.com/project/HOSTOman/libraqm)
|
||||||
|
|
||||||
|
Raqm is a small library that encapsulates the logic for complex text layout and
|
||||||
|
provides a convenient API.
|
||||||
|
|
||||||
|
It currently provides bidirectional text support (using [FriBiDi][1]), shaping
|
||||||
|
(using [HarfBuzz][2]), and proper script itemization. As a result,
|
||||||
|
Raqm can support most writing systems covered by Unicode.
|
||||||
|
|
||||||
|
The documentation can be accessed on the web at:
|
||||||
|
> http://host-oman.github.io/libraqm/
|
||||||
|
|
||||||
|
Raqm (Arabic: رَقْم) is writing, also number or digit and the Arabic word for
|
||||||
|
digital (رَقَمِيّ) shares the same root, so it is a play on “digital writing”.
|
||||||
|
|
||||||
|
Building
|
||||||
|
--------
|
||||||
|
|
||||||
|
Raqm depends on the following libraries:
|
||||||
|
* [FreeType][3]
|
||||||
|
* [HarfBuzz][2]
|
||||||
|
* [FriBiDi][1]
|
||||||
|
|
||||||
|
To build the documentation you will also need:
|
||||||
|
* [GTK-Doc][4]
|
||||||
|
|
||||||
|
To install dependencies on Fedora:
|
||||||
|
|
||||||
|
sudo dnf install freetype-devel harfbuzz-devel fribidi-devel gtk-doc
|
||||||
|
|
||||||
|
To install dependencies on Ubuntu:
|
||||||
|
|
||||||
|
sudo apt-get install libfreetype6-dev libharfbuzz-dev libfribidi-dev \
|
||||||
|
gtk-doc-tools
|
||||||
|
|
||||||
|
On Mac OS X you can use Homebrew:
|
||||||
|
|
||||||
|
brew install freetype harfbuzz fribidi gtk-doc
|
||||||
|
export XML_CATALOG_FILES="/usr/local/etc/xml/catalog" # for the docs
|
||||||
|
|
||||||
|
Once you have the source code and the dependencies, you can proceed to build.
|
||||||
|
To do that, run the customary sequence of commands in the source code
|
||||||
|
directory:
|
||||||
|
|
||||||
|
$ ./configure
|
||||||
|
$ make
|
||||||
|
$ make install
|
||||||
|
|
||||||
|
To build the documentation, pass `--enable-gtk-doc` to the `configure` script.
|
||||||
|
|
||||||
|
To run the tests:
|
||||||
|
|
||||||
|
$ make check
|
||||||
|
|
||||||
|
Contributing
|
||||||
|
------------
|
||||||
|
|
||||||
|
Once you have made a change that you are happy with, contribute it back, we’ll
|
||||||
|
be happy to integrate it! Just fork the repository and make a pull request.
|
||||||
|
|
||||||
|
Projects using Raqm
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
1. [ImageMagick](https://github.com/ImageMagick/ImageMagick)
|
||||||
|
2. [LibGD](https://github.com/libgd/libgd)
|
||||||
|
3. [FontView](https://github.com/googlei18n/fontview)
|
||||||
|
4. [Pillow](https://github.com/python-pillow)
|
||||||
|
5. [mplcairo](https://github.com/anntzer/mplcairo)
|
||||||
|
|
||||||
|
The following projects have patches to support complex text layout using Raqm:
|
||||||
|
|
||||||
|
2. SDL_ttf: https://bugzilla.libsdl.org/show_bug.cgi?id=3211
|
||||||
|
3. Pygame: https://bitbucket.org/pygame/pygame/pull-requests/52
|
||||||
|
4. Blender: https://developer.blender.org/D1809
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[1]: http://fribidi.org
|
||||||
|
[2]: http://harfbuzz.org
|
||||||
|
[3]: https://www.freetype.org
|
||||||
|
[4]: https://www.gtk.org/gtk-doc
|
44
src/thirdparty/raqm/raqm-version.h
vendored
Normal file
44
src/thirdparty/raqm/raqm-version.h
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2011 Google, Inc.
|
||||||
|
*
|
||||||
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, without written agreement and without
|
||||||
|
* license or royalty fees, to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose, provided that the
|
||||||
|
* above copyright notice and the following two paragraphs appear in
|
||||||
|
* all copies of this software.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||||
|
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||||
|
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
*
|
||||||
|
* Google Author(s): Behdad Esfahbod
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RAQM_H_IN_
|
||||||
|
#error "Include <raqm.h> instead."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _RAQM_VERSION_H_
|
||||||
|
#define _RAQM_VERSION_H_
|
||||||
|
|
||||||
|
#define RAQM_VERSION_MAJOR 0
|
||||||
|
#define RAQM_VERSION_MINOR 7
|
||||||
|
#define RAQM_VERSION_MICRO 1
|
||||||
|
|
||||||
|
#define RAQM_VERSION_STRING "0.7.1"
|
||||||
|
|
||||||
|
#define RAQM_VERSION_ATLEAST(major,minor,micro) \
|
||||||
|
((major)*10000+(minor)*100+(micro) <= \
|
||||||
|
RAQM_VERSION_MAJOR*10000+RAQM_VERSION_MINOR*100+RAQM_VERSION_MICRO)
|
||||||
|
|
||||||
|
#endif /* _RAQM_VERSION_H_ */
|
2074
src/thirdparty/raqm/raqm.c
vendored
Normal file
2074
src/thirdparty/raqm/raqm.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -24,17 +24,14 @@
|
||||||
|
|
||||||
#ifndef _RAQM_H_
|
#ifndef _RAQM_H_
|
||||||
#define _RAQM_H_
|
#define _RAQM_H_
|
||||||
|
#define _RAQM_H_IN_
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef bool
|
#include <stdbool.h>
|
||||||
typedef int bool;
|
#include <stdint.h>
|
||||||
#endif
|
|
||||||
#ifndef uint32_t
|
|
||||||
typedef UINT32 uint32_t;
|
|
||||||
#endif
|
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
|
@ -42,6 +39,8 @@ typedef UINT32 uint32_t;
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "raqm-version.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* raqm_t:
|
* raqm_t:
|
||||||
*
|
*
|
||||||
|
@ -63,7 +62,8 @@ typedef struct _raqm raqm_t;
|
||||||
*
|
*
|
||||||
* Since: 0.1
|
* Since: 0.1
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
RAQM_DIRECTION_DEFAULT,
|
RAQM_DIRECTION_DEFAULT,
|
||||||
RAQM_DIRECTION_RTL,
|
RAQM_DIRECTION_RTL,
|
||||||
RAQM_DIRECTION_LTR,
|
RAQM_DIRECTION_LTR,
|
||||||
|
@ -93,64 +93,93 @@ typedef struct raqm_glyph_t {
|
||||||
FT_Face ftface;
|
FT_Face ftface;
|
||||||
} raqm_glyph_t;
|
} raqm_glyph_t;
|
||||||
|
|
||||||
/**
|
raqm_t *
|
||||||
* version 0.1 of the raqm_glyph_t structure
|
raqm_create (void);
|
||||||
*/
|
|
||||||
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_t *
|
||||||
raqm_create(void);
|
raqm_reference (raqm_t *rq);
|
||||||
|
|
||||||
raqm_t *
|
|
||||||
raqm_reference(raqm_t *rq);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
raqm_destroy(raqm_t *rq);
|
raqm_destroy (raqm_t *rq);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_text(raqm_t *rq, const uint32_t *text, size_t len);
|
raqm_set_text (raqm_t *rq,
|
||||||
|
const uint32_t *text,
|
||||||
|
size_t len);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_text_utf8(raqm_t *rq, const char *text, size_t len);
|
raqm_set_text_utf8 (raqm_t *rq,
|
||||||
|
const char *text,
|
||||||
|
size_t len);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_par_direction(raqm_t *rq, raqm_direction_t dir);
|
raqm_set_par_direction (raqm_t *rq,
|
||||||
|
raqm_direction_t dir);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_language(raqm_t *rq, const char *lang, size_t start, size_t len);
|
raqm_set_language (raqm_t *rq,
|
||||||
|
const char *lang,
|
||||||
|
size_t start,
|
||||||
|
size_t len);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_add_font_feature(raqm_t *rq, const char *feature, int len);
|
raqm_add_font_feature (raqm_t *rq,
|
||||||
|
const char *feature,
|
||||||
|
int len);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_freetype_face(raqm_t *rq, FT_Face face);
|
raqm_set_freetype_face (raqm_t *rq,
|
||||||
|
FT_Face face);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_freetype_face_range(raqm_t *rq, FT_Face face, size_t start, size_t len);
|
raqm_set_freetype_face_range (raqm_t *rq,
|
||||||
|
FT_Face face,
|
||||||
|
size_t start,
|
||||||
|
size_t len);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_set_freetype_load_flags(raqm_t *rq, int flags);
|
raqm_set_freetype_load_flags (raqm_t *rq,
|
||||||
|
int flags);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_layout(raqm_t *rq);
|
raqm_set_invisible_glyph (raqm_t *rq,
|
||||||
|
int gid);
|
||||||
|
|
||||||
|
bool
|
||||||
|
raqm_layout (raqm_t *rq);
|
||||||
|
|
||||||
raqm_glyph_t *
|
raqm_glyph_t *
|
||||||
raqm_get_glyphs(raqm_t *rq, size_t *length);
|
raqm_get_glyphs (raqm_t *rq,
|
||||||
|
size_t *length);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_index_to_position(raqm_t *rq, size_t *index, int *x, int *y);
|
raqm_index_to_position (raqm_t *rq,
|
||||||
|
size_t *index,
|
||||||
|
int *x,
|
||||||
|
int *y);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
raqm_position_to_index(raqm_t *rq, int x, int y, size_t *index);
|
raqm_position_to_index (raqm_t *rq,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
size_t *index);
|
||||||
|
|
||||||
|
void
|
||||||
|
raqm_version (unsigned int *major,
|
||||||
|
unsigned int *minor,
|
||||||
|
unsigned int *micro);
|
||||||
|
|
||||||
|
const char *
|
||||||
|
raqm_version_string (void);
|
||||||
|
|
||||||
|
bool
|
||||||
|
raqm_version_atleast (unsigned int major,
|
||||||
|
unsigned int minor,
|
||||||
|
unsigned int micro);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#undef _RAQM_H_IN_
|
||||||
#endif /* _RAQM_H_ */
|
#endif /* _RAQM_H_ */
|
|
@ -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"],
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,7 +472,7 @@ def build_pillow():
|
||||||
cmd_set("DISTUTILS_USE_SDK", "1"), # use same compiler to build Pillow
|
cmd_set("DISTUTILS_USE_SDK", "1"), # use same compiler to build Pillow
|
||||||
cmd_set("MSSdk", "1"), # for PyPy3.6
|
cmd_set("MSSdk", "1"), # for PyPy3.6
|
||||||
cmd_set("py_vcruntime_redist", "true"), # use /MD, not /MT
|
cmd_set("py_vcruntime_redist", "true"), # use /MD, not /MT
|
||||||
r'"{python_dir}\{python_exe}" setup.py build_ext %*',
|
r'"{python_dir}\{python_exe}" setup.py build_ext --vendor-raqm --vendor-fribidi %*', # noqa: E501
|
||||||
]
|
]
|
||||||
|
|
||||||
write_script("build_pillow.cmd", lines)
|
write_script("build_pillow.cmd", lines)
|
||||||
|
@ -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_BUILD")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user