_imagingft.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317
  1. /*
  2. * PIL FreeType Driver
  3. *
  4. * a FreeType 2.X driver for PIL
  5. *
  6. * history:
  7. * 2001-02-17 fl Created (based on old experimental freetype 1.0 code)
  8. * 2001-04-18 fl Fixed some egcs compiler nits
  9. * 2002-11-08 fl Added unicode support; more font metrics, etc
  10. * 2003-05-20 fl Fixed compilation under 1.5.2 and newer non-unicode builds
  11. * 2003-09-27 fl Added charmap encoding support
  12. * 2004-05-15 fl Fixed compilation for FreeType 2.1.8
  13. * 2004-09-10 fl Added support for monochrome bitmaps
  14. * 2006-06-18 fl Fixed glyph bearing calculation
  15. * 2007-12-23 fl Fixed crash in family/style attribute fetch
  16. * 2008-01-02 fl Handle Unicode filenames properly
  17. *
  18. * Copyright (c) 1998-2007 by Secret Labs AB
  19. */
  20. #define PY_SSIZE_T_CLEAN
  21. #include "Python.h"
  22. #include "Imaging.h"
  23. #include <ft2build.h>
  24. #include FT_FREETYPE_H
  25. #include FT_GLYPH_H
  26. #include FT_STROKER_H
  27. #include FT_MULTIPLE_MASTERS_H
  28. #include FT_SFNT_NAMES_H
  29. #define KEEP_PY_UNICODE
  30. #include "py3.h"
  31. #if !defined(_MSC_VER)
  32. #include <dlfcn.h>
  33. #endif
  34. #if !defined(FT_LOAD_TARGET_MONO)
  35. #define FT_LOAD_TARGET_MONO FT_LOAD_MONOCHROME
  36. #endif
  37. /* -------------------------------------------------------------------- */
  38. /* error table */
  39. #undef FTERRORS_H
  40. #undef __FTERRORS_H__
  41. #define FT_ERRORDEF( e, v, s ) { e, s },
  42. #define FT_ERROR_START_LIST {
  43. #define FT_ERROR_END_LIST { 0, 0 } };
  44. #include <raqm.h>
  45. #define LAYOUT_FALLBACK 0
  46. #define LAYOUT_RAQM 1
  47. typedef struct
  48. {
  49. int index, x_offset, x_advance, y_offset, y_advance;
  50. unsigned int cluster;
  51. } GlyphInfo;
  52. struct {
  53. int code;
  54. const char* message;
  55. } ft_errors[] =
  56. #include FT_ERRORS_H
  57. /* -------------------------------------------------------------------- */
  58. /* font objects */
  59. static FT_Library library;
  60. typedef struct {
  61. PyObject_HEAD
  62. FT_Face face;
  63. unsigned char *font_bytes;
  64. int layout_engine;
  65. } FontObject;
  66. static PyTypeObject Font_Type;
  67. typedef bool (*t_raqm_version_atleast)(unsigned int major,
  68. unsigned int minor,
  69. unsigned int micro);
  70. typedef raqm_t* (*t_raqm_create)(void);
  71. typedef int (*t_raqm_set_text)(raqm_t *rq,
  72. const uint32_t *text,
  73. size_t len);
  74. typedef bool (*t_raqm_set_text_utf8) (raqm_t *rq,
  75. const char *text,
  76. size_t len);
  77. typedef bool (*t_raqm_set_par_direction) (raqm_t *rq,
  78. raqm_direction_t dir);
  79. typedef bool (*t_raqm_set_language) (raqm_t *rq,
  80. const char *lang,
  81. size_t start,
  82. size_t len);
  83. typedef bool (*t_raqm_add_font_feature) (raqm_t *rq,
  84. const char *feature,
  85. int len);
  86. typedef bool (*t_raqm_set_freetype_face) (raqm_t *rq,
  87. FT_Face face);
  88. typedef bool (*t_raqm_layout) (raqm_t *rq);
  89. typedef raqm_glyph_t* (*t_raqm_get_glyphs) (raqm_t *rq,
  90. size_t *length);
  91. typedef raqm_glyph_t_01* (*t_raqm_get_glyphs_01) (raqm_t *rq,
  92. size_t *length);
  93. typedef void (*t_raqm_destroy) (raqm_t *rq);
  94. typedef struct {
  95. void* raqm;
  96. int version;
  97. t_raqm_version_atleast version_atleast;
  98. t_raqm_create create;
  99. t_raqm_set_text set_text;
  100. t_raqm_set_text_utf8 set_text_utf8;
  101. t_raqm_set_par_direction set_par_direction;
  102. t_raqm_set_language set_language;
  103. t_raqm_add_font_feature add_font_feature;
  104. t_raqm_set_freetype_face set_freetype_face;
  105. t_raqm_layout layout;
  106. t_raqm_get_glyphs get_glyphs;
  107. t_raqm_get_glyphs_01 get_glyphs_01;
  108. t_raqm_destroy destroy;
  109. } p_raqm_func;
  110. static p_raqm_func p_raqm;
  111. /* round a 26.6 pixel coordinate to the nearest larger integer */
  112. #define PIXEL(x) ((((x)+63) & -64)>>6)
  113. static PyObject*
  114. geterror(int code)
  115. {
  116. int i;
  117. for (i = 0; ft_errors[i].message; i++)
  118. if (ft_errors[i].code == code) {
  119. PyErr_SetString(PyExc_IOError, ft_errors[i].message);
  120. return NULL;
  121. }
  122. PyErr_SetString(PyExc_IOError, "unknown freetype error");
  123. return NULL;
  124. }
  125. static int
  126. setraqm(void)
  127. {
  128. /* set the static function pointers for dynamic raqm linking */
  129. p_raqm.raqm = NULL;
  130. /* Microsoft needs a totally different system */
  131. #if !defined(_MSC_VER)
  132. p_raqm.raqm = dlopen("libraqm.so.0", RTLD_LAZY);
  133. if (!p_raqm.raqm) {
  134. p_raqm.raqm = dlopen("libraqm.dylib", RTLD_LAZY);
  135. }
  136. #else
  137. p_raqm.raqm = LoadLibrary("libraqm");
  138. #endif
  139. if (!p_raqm.raqm) {
  140. return 1;
  141. }
  142. #if !defined(_MSC_VER)
  143. p_raqm.version_atleast = (t_raqm_version_atleast)dlsym(p_raqm.raqm, "raqm_version_atleast");
  144. p_raqm.create = (t_raqm_create)dlsym(p_raqm.raqm, "raqm_create");
  145. p_raqm.set_text = (t_raqm_set_text)dlsym(p_raqm.raqm, "raqm_set_text");
  146. p_raqm.set_text_utf8 = (t_raqm_set_text_utf8)dlsym(p_raqm.raqm, "raqm_set_text_utf8");
  147. p_raqm.set_par_direction = (t_raqm_set_par_direction)dlsym(p_raqm.raqm, "raqm_set_par_direction");
  148. p_raqm.set_language = (t_raqm_set_language)dlsym(p_raqm.raqm, "raqm_set_language");
  149. p_raqm.add_font_feature = (t_raqm_add_font_feature)dlsym(p_raqm.raqm, "raqm_add_font_feature");
  150. p_raqm.set_freetype_face = (t_raqm_set_freetype_face)dlsym(p_raqm.raqm, "raqm_set_freetype_face");
  151. p_raqm.layout = (t_raqm_layout)dlsym(p_raqm.raqm, "raqm_layout");
  152. p_raqm.destroy = (t_raqm_destroy)dlsym(p_raqm.raqm, "raqm_destroy");
  153. if(dlsym(p_raqm.raqm, "raqm_index_to_position")) {
  154. p_raqm.get_glyphs = (t_raqm_get_glyphs)dlsym(p_raqm.raqm, "raqm_get_glyphs");
  155. p_raqm.version = 2;
  156. } else {
  157. p_raqm.version = 1;
  158. p_raqm.get_glyphs_01 = (t_raqm_get_glyphs_01)dlsym(p_raqm.raqm, "raqm_get_glyphs");
  159. }
  160. if (dlerror() ||
  161. !(p_raqm.create &&
  162. p_raqm.set_text &&
  163. p_raqm.set_text_utf8 &&
  164. p_raqm.set_par_direction &&
  165. p_raqm.set_language &&
  166. p_raqm.add_font_feature &&
  167. p_raqm.set_freetype_face &&
  168. p_raqm.layout &&
  169. (p_raqm.get_glyphs || p_raqm.get_glyphs_01) &&
  170. p_raqm.destroy)) {
  171. dlclose(p_raqm.raqm);
  172. p_raqm.raqm = NULL;
  173. return 2;
  174. }
  175. #else
  176. p_raqm.version_atleast = (t_raqm_version_atleast)GetProcAddress(p_raqm.raqm, "raqm_version_atleast");
  177. p_raqm.create = (t_raqm_create)GetProcAddress(p_raqm.raqm, "raqm_create");
  178. p_raqm.set_text = (t_raqm_set_text)GetProcAddress(p_raqm.raqm, "raqm_set_text");
  179. p_raqm.set_text_utf8 = (t_raqm_set_text_utf8)GetProcAddress(p_raqm.raqm, "raqm_set_text_utf8");
  180. p_raqm.set_par_direction = (t_raqm_set_par_direction)GetProcAddress(p_raqm.raqm, "raqm_set_par_direction");
  181. p_raqm.set_language = (t_raqm_set_language)GetProcAddress(p_raqm.raqm, "raqm_set_language");
  182. p_raqm.add_font_feature = (t_raqm_add_font_feature)GetProcAddress(p_raqm.raqm, "raqm_add_font_feature");
  183. p_raqm.set_freetype_face = (t_raqm_set_freetype_face)GetProcAddress(p_raqm.raqm, "raqm_set_freetype_face");
  184. p_raqm.layout = (t_raqm_layout)GetProcAddress(p_raqm.raqm, "raqm_layout");
  185. p_raqm.destroy = (t_raqm_destroy)GetProcAddress(p_raqm.raqm, "raqm_destroy");
  186. if(GetProcAddress(p_raqm.raqm, "raqm_index_to_position")) {
  187. p_raqm.get_glyphs = (t_raqm_get_glyphs)GetProcAddress(p_raqm.raqm, "raqm_get_glyphs");
  188. p_raqm.version = 2;
  189. } else {
  190. p_raqm.version = 1;
  191. p_raqm.get_glyphs_01 = (t_raqm_get_glyphs_01)GetProcAddress(p_raqm.raqm, "raqm_get_glyphs");
  192. }
  193. if (!(p_raqm.create &&
  194. p_raqm.set_text &&
  195. p_raqm.set_text_utf8 &&
  196. p_raqm.set_par_direction &&
  197. p_raqm.set_language &&
  198. p_raqm.add_font_feature &&
  199. p_raqm.set_freetype_face &&
  200. p_raqm.layout &&
  201. (p_raqm.get_glyphs || p_raqm.get_glyphs_01) &&
  202. p_raqm.destroy)) {
  203. FreeLibrary(p_raqm.raqm);
  204. p_raqm.raqm = NULL;
  205. return 2;
  206. }
  207. #endif
  208. return 0;
  209. }
  210. static PyObject*
  211. getfont(PyObject* self_, PyObject* args, PyObject* kw)
  212. {
  213. /* create a font object from a file name and a size (in pixels) */
  214. FontObject* self;
  215. int error = 0;
  216. char* filename = NULL;
  217. Py_ssize_t size;
  218. Py_ssize_t index = 0;
  219. Py_ssize_t layout_engine = 0;
  220. unsigned char* encoding;
  221. unsigned char* font_bytes;
  222. Py_ssize_t font_bytes_size = 0;
  223. static char* kwlist[] = {
  224. "filename", "size", "index", "encoding", "font_bytes",
  225. "layout_engine", NULL
  226. };
  227. if (!library) {
  228. PyErr_SetString(
  229. PyExc_IOError,
  230. "failed to initialize FreeType library"
  231. );
  232. return NULL;
  233. }
  234. if (!PyArg_ParseTupleAndKeywords(args, kw, "etn|ns"PY_ARG_BYTES_LENGTH"n",
  235. kwlist,
  236. Py_FileSystemDefaultEncoding, &filename,
  237. &size, &index, &encoding, &font_bytes,
  238. &font_bytes_size, &layout_engine)) {
  239. return NULL;
  240. }
  241. self = PyObject_New(FontObject, &Font_Type);
  242. if (!self) {
  243. if (filename)
  244. PyMem_Free(filename);
  245. return NULL;
  246. }
  247. self->face = NULL;
  248. self->layout_engine = layout_engine;
  249. if (filename && font_bytes_size <= 0) {
  250. self->font_bytes = NULL;
  251. error = FT_New_Face(library, filename, index, &self->face);
  252. } else {
  253. /* need to have allocated storage for font_bytes for the life of the object.*/
  254. /* Don't free this before FT_Done_Face */
  255. self->font_bytes = PyMem_Malloc(font_bytes_size);
  256. if (!self->font_bytes) {
  257. error = 65; // Out of Memory in Freetype.
  258. }
  259. if (!error) {
  260. memcpy(self->font_bytes, font_bytes, (size_t)font_bytes_size);
  261. error = FT_New_Memory_Face(library, (FT_Byte*)self->font_bytes,
  262. font_bytes_size, index, &self->face);
  263. }
  264. }
  265. if (!error)
  266. error = FT_Set_Pixel_Sizes(self->face, 0, size);
  267. if (!error && encoding && strlen((char*) encoding) == 4) {
  268. FT_Encoding encoding_tag = FT_MAKE_TAG(
  269. encoding[0], encoding[1], encoding[2], encoding[3]
  270. );
  271. error = FT_Select_Charmap(self->face, encoding_tag);
  272. }
  273. if (filename)
  274. PyMem_Free(filename);
  275. if (error) {
  276. if (self->font_bytes) {
  277. PyMem_Free(self->font_bytes);
  278. self->font_bytes = NULL;
  279. }
  280. Py_DECREF(self);
  281. return geterror(error);
  282. }
  283. return (PyObject*) self;
  284. }
  285. static int
  286. font_getchar(PyObject* string, int index, FT_ULong* char_out)
  287. {
  288. #if (PY_VERSION_HEX < 0x03030000) || (defined(PYPY_VERSION_NUM))
  289. if (PyUnicode_Check(string)) {
  290. Py_UNICODE* p = PyUnicode_AS_UNICODE(string);
  291. int size = PyUnicode_GET_SIZE(string);
  292. if (index >= size)
  293. return 0;
  294. *char_out = p[index];
  295. return 1;
  296. }
  297. #if PY_VERSION_HEX < 0x03000000
  298. if (PyString_Check(string)) {
  299. unsigned char* p = (unsigned char*) PyString_AS_STRING(string);
  300. int size = PyString_GET_SIZE(string);
  301. if (index >= size)
  302. return 0;
  303. *char_out = (unsigned char) p[index];
  304. return 1;
  305. }
  306. #endif
  307. #else
  308. if (PyUnicode_Check(string)) {
  309. if (index >= PyUnicode_GET_LENGTH(string))
  310. return 0;
  311. *char_out = PyUnicode_READ_CHAR(string, index);
  312. return 1;
  313. }
  314. #endif
  315. return 0;
  316. }
  317. static size_t
  318. text_layout_raqm(PyObject* string, FontObject* self, const char* dir, PyObject *features,
  319. const char* lang, GlyphInfo **glyph_info, int mask)
  320. {
  321. size_t i = 0, count = 0, start = 0;
  322. raqm_t *rq;
  323. raqm_glyph_t *glyphs = NULL;
  324. raqm_glyph_t_01 *glyphs_01 = NULL;
  325. raqm_direction_t direction;
  326. rq = (*p_raqm.create)();
  327. if (rq == NULL) {
  328. PyErr_SetString(PyExc_ValueError, "raqm_create() failed.");
  329. goto failed;
  330. }
  331. #if (PY_VERSION_HEX < 0x03030000) || (defined(PYPY_VERSION_NUM))
  332. if (PyUnicode_Check(string)) {
  333. Py_UNICODE *text = PyUnicode_AS_UNICODE(string);
  334. Py_ssize_t size = PyUnicode_GET_SIZE(string);
  335. if (! size) {
  336. /* return 0 and clean up, no glyphs==no size,
  337. and raqm fails with empty strings */
  338. goto failed;
  339. }
  340. if (!(*p_raqm.set_text)(rq, (const uint32_t *)(text), size)) {
  341. PyErr_SetString(PyExc_ValueError, "raqm_set_text() failed");
  342. goto failed;
  343. }
  344. if (lang) {
  345. if (!(*p_raqm.set_language)(rq, lang, start, size)) {
  346. PyErr_SetString(PyExc_ValueError, "raqm_set_language() failed");
  347. goto failed;
  348. }
  349. }
  350. }
  351. #if PY_VERSION_HEX < 0x03000000
  352. else if (PyString_Check(string)) {
  353. char *text = PyString_AS_STRING(string);
  354. int size = PyString_GET_SIZE(string);
  355. if (! size) {
  356. goto failed;
  357. }
  358. if (!(*p_raqm.set_text_utf8)(rq, text, size)) {
  359. PyErr_SetString(PyExc_ValueError, "raqm_set_text_utf8() failed");
  360. goto failed;
  361. }
  362. if (lang) {
  363. if (!(*p_raqm.set_language)(rq, lang, start, size)) {
  364. PyErr_SetString(PyExc_ValueError, "raqm_set_language() failed");
  365. goto failed;
  366. }
  367. }
  368. }
  369. #endif
  370. #else
  371. if (PyUnicode_Check(string)) {
  372. Py_UCS4 *text = PyUnicode_AsUCS4Copy(string);
  373. Py_ssize_t size = PyUnicode_GET_LENGTH(string);
  374. if (!text || !size) {
  375. /* return 0 and clean up, no glyphs==no size,
  376. and raqm fails with empty strings */
  377. goto failed;
  378. }
  379. int set_text = (*p_raqm.set_text)(rq, (const uint32_t *)(text), size);
  380. PyMem_Free(text);
  381. if (!set_text) {
  382. PyErr_SetString(PyExc_ValueError, "raqm_set_text() failed");
  383. goto failed;
  384. }
  385. if (lang) {
  386. if (!(*p_raqm.set_language)(rq, lang, start, size)) {
  387. PyErr_SetString(PyExc_ValueError, "raqm_set_language() failed");
  388. goto failed;
  389. }
  390. }
  391. }
  392. #endif
  393. else {
  394. PyErr_SetString(PyExc_TypeError, "expected string");
  395. goto failed;
  396. }
  397. direction = RAQM_DIRECTION_DEFAULT;
  398. if (dir) {
  399. if (strcmp(dir, "rtl") == 0)
  400. direction = RAQM_DIRECTION_RTL;
  401. else if (strcmp(dir, "ltr") == 0)
  402. direction = RAQM_DIRECTION_LTR;
  403. else if (strcmp(dir, "ttb") == 0) {
  404. direction = RAQM_DIRECTION_TTB;
  405. if (p_raqm.version_atleast == NULL || !(*p_raqm.version_atleast)(0, 7, 0)) {
  406. PyErr_SetString(PyExc_ValueError, "libraqm 0.7 or greater required for 'ttb' direction");
  407. goto failed;
  408. }
  409. } else {
  410. PyErr_SetString(PyExc_ValueError, "direction must be either 'rtl', 'ltr' or 'ttb'");
  411. goto failed;
  412. }
  413. }
  414. if (!(*p_raqm.set_par_direction)(rq, direction)) {
  415. PyErr_SetString(PyExc_ValueError, "raqm_set_par_direction() failed");
  416. goto failed;
  417. }
  418. if (features != Py_None) {
  419. int j, len;
  420. PyObject *seq = PySequence_Fast(features, "expected a sequence");
  421. if (!seq) {
  422. goto failed;
  423. }
  424. len = PySequence_Size(seq);
  425. for (j = 0; j < len; j++) {
  426. PyObject *item = PySequence_Fast_GET_ITEM(seq, j);
  427. char *feature = NULL;
  428. Py_ssize_t size = 0;
  429. PyObject *bytes;
  430. #if PY_VERSION_HEX >= 0x03000000
  431. if (!PyUnicode_Check(item)) {
  432. #else
  433. if (!PyUnicode_Check(item) && !PyString_Check(item)) {
  434. #endif
  435. PyErr_SetString(PyExc_TypeError, "expected a string");
  436. goto failed;
  437. }
  438. if (PyUnicode_Check(item)) {
  439. bytes = PyUnicode_AsUTF8String(item);
  440. if (bytes == NULL)
  441. goto failed;
  442. feature = PyBytes_AS_STRING(bytes);
  443. size = PyBytes_GET_SIZE(bytes);
  444. }
  445. #if PY_VERSION_HEX < 0x03000000
  446. else {
  447. feature = PyString_AsString(item);
  448. size = PyString_GET_SIZE(item);
  449. }
  450. #endif
  451. if (!(*p_raqm.add_font_feature)(rq, feature, size)) {
  452. PyErr_SetString(PyExc_ValueError, "raqm_add_font_feature() failed");
  453. goto failed;
  454. }
  455. }
  456. }
  457. if (!(*p_raqm.set_freetype_face)(rq, self->face)) {
  458. PyErr_SetString(PyExc_RuntimeError, "raqm_set_freetype_face() failed.");
  459. goto failed;
  460. }
  461. if (!(*p_raqm.layout)(rq)) {
  462. PyErr_SetString(PyExc_RuntimeError, "raqm_layout() failed.");
  463. goto failed;
  464. }
  465. if (p_raqm.version == 1) {
  466. glyphs_01 = (*p_raqm.get_glyphs_01)(rq, &count);
  467. if (glyphs_01 == NULL) {
  468. PyErr_SetString(PyExc_ValueError, "raqm_get_glyphs() failed.");
  469. count = 0;
  470. goto failed;
  471. }
  472. } else { /* version == 2 */
  473. glyphs = (*p_raqm.get_glyphs)(rq, &count);
  474. if (glyphs == NULL) {
  475. PyErr_SetString(PyExc_ValueError, "raqm_get_glyphs() failed.");
  476. count = 0;
  477. goto failed;
  478. }
  479. }
  480. (*glyph_info) = PyMem_New(GlyphInfo, count);
  481. if ((*glyph_info) == NULL) {
  482. PyErr_SetString(PyExc_MemoryError, "PyMem_New() failed");
  483. count = 0;
  484. goto failed;
  485. }
  486. if (p_raqm.version == 1) {
  487. for (i = 0; i < count; i++) {
  488. (*glyph_info)[i].index = glyphs_01[i].index;
  489. (*glyph_info)[i].x_offset = glyphs_01[i].x_offset;
  490. (*glyph_info)[i].x_advance = glyphs_01[i].x_advance;
  491. (*glyph_info)[i].y_offset = glyphs_01[i].y_offset;
  492. (*glyph_info)[i].y_advance = glyphs_01[i].y_advance;
  493. (*glyph_info)[i].cluster = glyphs_01[i].cluster;
  494. }
  495. } else {
  496. for (i = 0; i < count; i++) {
  497. (*glyph_info)[i].index = glyphs[i].index;
  498. (*glyph_info)[i].x_offset = glyphs[i].x_offset;
  499. (*glyph_info)[i].x_advance = glyphs[i].x_advance;
  500. (*glyph_info)[i].y_offset = glyphs[i].y_offset;
  501. (*glyph_info)[i].y_advance = glyphs[i].y_advance;
  502. (*glyph_info)[i].cluster = glyphs[i].cluster;
  503. }
  504. }
  505. failed:
  506. (*p_raqm.destroy)(rq);
  507. return count;
  508. }
  509. static size_t
  510. text_layout_fallback(PyObject* string, FontObject* self, const char* dir, PyObject *features,
  511. const char* lang, GlyphInfo **glyph_info, int mask)
  512. {
  513. int error, load_flags;
  514. FT_ULong ch;
  515. Py_ssize_t count;
  516. FT_GlyphSlot glyph;
  517. FT_Bool kerning = FT_HAS_KERNING(self->face);
  518. FT_UInt last_index = 0;
  519. int i;
  520. if (features != Py_None || dir != NULL || lang != NULL) {
  521. PyErr_SetString(PyExc_KeyError, "setting text direction, language or font features is not supported without libraqm");
  522. }
  523. #if PY_VERSION_HEX >= 0x03000000
  524. if (!PyUnicode_Check(string)) {
  525. #else
  526. if (!PyUnicode_Check(string) && !PyString_Check(string)) {
  527. #endif
  528. PyErr_SetString(PyExc_TypeError, "expected string");
  529. return 0;
  530. }
  531. count = 0;
  532. while (font_getchar(string, count, &ch)) {
  533. count++;
  534. }
  535. if (count == 0) {
  536. return 0;
  537. }
  538. (*glyph_info) = PyMem_New(GlyphInfo, count);
  539. if ((*glyph_info) == NULL) {
  540. PyErr_SetString(PyExc_MemoryError, "PyMem_New() failed");
  541. return 0;
  542. }
  543. load_flags = FT_LOAD_RENDER|FT_LOAD_NO_BITMAP;
  544. if (mask) {
  545. load_flags |= FT_LOAD_TARGET_MONO;
  546. }
  547. for (i = 0; font_getchar(string, i, &ch); i++) {
  548. (*glyph_info)[i].index = FT_Get_Char_Index(self->face, ch);
  549. error = FT_Load_Glyph(self->face, (*glyph_info)[i].index, load_flags);
  550. if (error) {
  551. geterror(error);
  552. return 0;
  553. }
  554. glyph = self->face->glyph;
  555. (*glyph_info)[i].x_offset=0;
  556. (*glyph_info)[i].y_offset=0;
  557. if (kerning && last_index && (*glyph_info)[i].index) {
  558. FT_Vector delta;
  559. if (FT_Get_Kerning(self->face, last_index, (*glyph_info)[i].index,
  560. ft_kerning_default,&delta) == 0)
  561. (*glyph_info)[i-1].x_advance += PIXEL(delta.x);
  562. (*glyph_info)[i-1].y_advance += PIXEL(delta.y);
  563. }
  564. (*glyph_info)[i].x_advance = glyph->metrics.horiAdvance;
  565. (*glyph_info)[i].y_advance = glyph->metrics.vertAdvance;
  566. last_index = (*glyph_info)[i].index;
  567. (*glyph_info)[i].cluster = ch;
  568. }
  569. return count;
  570. }
  571. static size_t
  572. text_layout(PyObject* string, FontObject* self, const char* dir, PyObject *features,
  573. const char* lang, GlyphInfo **glyph_info, int mask)
  574. {
  575. size_t count;
  576. if (p_raqm.raqm && self->layout_engine == LAYOUT_RAQM) {
  577. count = text_layout_raqm(string, self, dir, features, lang, glyph_info, mask);
  578. } else {
  579. count = text_layout_fallback(string, self, dir, features, lang, glyph_info, mask);
  580. }
  581. return count;
  582. }
  583. static PyObject*
  584. font_getsize(FontObject* self, PyObject* args)
  585. {
  586. int x_position, x_max, x_min, y_max, y_min;
  587. FT_Face face;
  588. int xoffset, yoffset;
  589. int horizontal_dir;
  590. const char *dir = NULL;
  591. const char *lang = NULL;
  592. size_t i, count;
  593. GlyphInfo *glyph_info = NULL;
  594. PyObject *features = Py_None;
  595. /* calculate size and bearing for a given string */
  596. PyObject* string;
  597. if (!PyArg_ParseTuple(args, "O|zOz:getsize", &string, &dir, &features, &lang))
  598. return NULL;
  599. count = text_layout(string, self, dir, features, lang, &glyph_info, 0);
  600. if (PyErr_Occurred()) {
  601. return NULL;
  602. }
  603. face = NULL;
  604. xoffset = yoffset = 0;
  605. x_position = x_max = x_min = y_max = y_min = 0;
  606. horizontal_dir = dir && strcmp(dir, "ttb") == 0 ? 0 : 1;
  607. for (i = 0; i < count; i++) {
  608. int index, error, offset, x_advanced;
  609. FT_BBox bbox;
  610. FT_Glyph glyph;
  611. face = self->face;
  612. index = glyph_info[i].index;
  613. /* Note: bitmap fonts within ttf fonts do not work, see #891/pr#960
  614. * Yifu Yu<root@jackyyf.com>, 2014-10-15
  615. */
  616. error = FT_Load_Glyph(face, index, FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP);
  617. if (error)
  618. return geterror(error);
  619. if (i == 0) {
  620. if (horizontal_dir) {
  621. if (face->glyph->metrics.horiBearingX < 0) {
  622. xoffset = face->glyph->metrics.horiBearingX;
  623. x_position -= xoffset;
  624. }
  625. } else {
  626. if (face->glyph->metrics.vertBearingY < 0) {
  627. yoffset = face->glyph->metrics.vertBearingY;
  628. y_max -= yoffset;
  629. }
  630. }
  631. }
  632. FT_Get_Glyph(face->glyph, &glyph);
  633. FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_SUBPIXELS, &bbox);
  634. if (horizontal_dir) {
  635. x_position += glyph_info[i].x_advance;
  636. x_advanced = x_position;
  637. offset = glyph_info[i].x_advance -
  638. face->glyph->metrics.width -
  639. face->glyph->metrics.horiBearingX;
  640. if (offset < 0)
  641. x_advanced -= offset;
  642. if (x_advanced > x_max)
  643. x_max = x_advanced;
  644. bbox.yMax += glyph_info[i].y_offset;
  645. bbox.yMin += glyph_info[i].y_offset;
  646. if (bbox.yMax > y_max)
  647. y_max = bbox.yMax;
  648. if (bbox.yMin < y_min)
  649. y_min = bbox.yMin;
  650. // find max distance of baseline from top
  651. if (face->glyph->metrics.horiBearingY > yoffset)
  652. yoffset = face->glyph->metrics.horiBearingY;
  653. } else {
  654. y_max -= glyph_info[i].y_advance;
  655. if (i == count - 1) {
  656. // trim end gap from final glyph
  657. int offset;
  658. offset = -glyph_info[i].y_advance -
  659. face->glyph->metrics.height -
  660. face->glyph->metrics.vertBearingY;
  661. if (offset < 0)
  662. y_max -= offset;
  663. }
  664. if (bbox.xMax > x_max)
  665. x_max = bbox.xMax;
  666. if (i == 0 || bbox.xMin < x_min)
  667. x_min = bbox.xMin;
  668. }
  669. FT_Done_Glyph(glyph);
  670. }
  671. if (glyph_info) {
  672. PyMem_Free(glyph_info);
  673. glyph_info = NULL;
  674. }
  675. if (face) {
  676. if (horizontal_dir) {
  677. // left bearing
  678. if (xoffset < 0)
  679. x_max -= xoffset;
  680. else
  681. xoffset = 0;
  682. /* difference between the font ascender and the distance of
  683. * the baseline from the top */
  684. yoffset = PIXEL(self->face->size->metrics.ascender - yoffset);
  685. } else {
  686. // top bearing
  687. if (yoffset < 0)
  688. y_max -= yoffset;
  689. else
  690. yoffset = 0;
  691. }
  692. }
  693. return Py_BuildValue(
  694. "(ii)(ii)",
  695. PIXEL(x_max - x_min), PIXEL(y_max - y_min),
  696. PIXEL(xoffset), yoffset
  697. );
  698. }
  699. static PyObject*
  700. font_render(FontObject* self, PyObject* args)
  701. {
  702. int x;
  703. unsigned int y;
  704. Imaging im;
  705. int index, error, ascender, horizontal_dir;
  706. int load_flags;
  707. unsigned char *source;
  708. FT_Glyph glyph;
  709. FT_GlyphSlot glyph_slot;
  710. FT_Bitmap bitmap;
  711. FT_BitmapGlyph bitmap_glyph;
  712. int stroke_width = 0;
  713. FT_Stroker stroker = NULL;
  714. FT_Int left;
  715. /* render string into given buffer (the buffer *must* have
  716. the right size, or this will crash) */
  717. PyObject* string;
  718. Py_ssize_t id;
  719. int mask = 0;
  720. int temp;
  721. int xx, x0, x1;
  722. int yy;
  723. unsigned int bitmap_y;
  724. const char *dir = NULL;
  725. const char *lang = NULL;
  726. size_t i, count;
  727. GlyphInfo *glyph_info;
  728. PyObject *features = NULL;
  729. if (!PyArg_ParseTuple(args, "On|izOzi:render", &string, &id, &mask, &dir, &features, &lang,
  730. &stroke_width)) {
  731. return NULL;
  732. }
  733. glyph_info = NULL;
  734. count = text_layout(string, self, dir, features, lang, &glyph_info, mask);
  735. if (PyErr_Occurred()) {
  736. return NULL;
  737. }
  738. if (count == 0) {
  739. Py_RETURN_NONE;
  740. }
  741. if (stroke_width) {
  742. error = FT_Stroker_New(library, &stroker);
  743. if (error) {
  744. return geterror(error);
  745. }
  746. FT_Stroker_Set(stroker, (FT_Fixed)stroke_width*64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0);
  747. }
  748. im = (Imaging) id;
  749. /* Note: bitmap fonts within ttf fonts do not work, see #891/pr#960 */
  750. load_flags = FT_LOAD_NO_BITMAP;
  751. if (stroker == NULL) {
  752. load_flags |= FT_LOAD_RENDER;
  753. }
  754. if (mask) {
  755. load_flags |= FT_LOAD_TARGET_MONO;
  756. }
  757. ascender = 0;
  758. for (i = 0; i < count; i++) {
  759. index = glyph_info[i].index;
  760. error = FT_Load_Glyph(self->face, index, load_flags);
  761. if (error) {
  762. return geterror(error);
  763. }
  764. glyph_slot = self->face->glyph;
  765. bitmap = glyph_slot->bitmap;
  766. temp = bitmap.rows - glyph_slot->bitmap_top;
  767. temp -= PIXEL(glyph_info[i].y_offset);
  768. if (temp > ascender)
  769. ascender = temp;
  770. }
  771. x = y = 0;
  772. horizontal_dir = dir && strcmp(dir, "ttb") == 0 ? 0 : 1;
  773. for (i = 0; i < count; i++) {
  774. index = glyph_info[i].index;
  775. error = FT_Load_Glyph(self->face, index, load_flags);
  776. if (error) {
  777. return geterror(error);
  778. }
  779. glyph_slot = self->face->glyph;
  780. if (stroker != NULL) {
  781. error = FT_Get_Glyph(glyph_slot, &glyph);
  782. if (!error) {
  783. error = FT_Glyph_Stroke(&glyph, stroker, 1);
  784. }
  785. if (!error) {
  786. FT_Vector origin = {0, 0};
  787. error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, &origin, 1);
  788. }
  789. if (error) {
  790. return geterror(error);
  791. }
  792. bitmap_glyph = (FT_BitmapGlyph)glyph;
  793. bitmap = bitmap_glyph->bitmap;
  794. left = bitmap_glyph->left;
  795. FT_Done_Glyph(glyph);
  796. } else {
  797. bitmap = glyph_slot->bitmap;
  798. left = glyph_slot->bitmap_left;
  799. }
  800. if (horizontal_dir) {
  801. if (i == 0 && glyph_slot->metrics.horiBearingX < 0) {
  802. x = -glyph_slot->metrics.horiBearingX;
  803. }
  804. xx = PIXEL(x) + left;
  805. xx += PIXEL(glyph_info[i].x_offset) + stroke_width;
  806. } else {
  807. if (glyph_slot->metrics.vertBearingX < 0) {
  808. x = -glyph_slot->metrics.vertBearingX;
  809. }
  810. xx = im->xsize / 2 - bitmap.width / 2;
  811. }
  812. x0 = 0;
  813. x1 = bitmap.width;
  814. if (xx < 0)
  815. x0 = -xx;
  816. if (xx + x1 > im->xsize)
  817. x1 = im->xsize - xx;
  818. source = (unsigned char*) bitmap.buffer;
  819. for (bitmap_y = 0; bitmap_y < bitmap.rows; bitmap_y++) {
  820. if (horizontal_dir) {
  821. yy = bitmap_y + im->ysize - (PIXEL(glyph_slot->metrics.horiBearingY) + ascender);
  822. yy -= PIXEL(glyph_info[i].y_offset) + stroke_width * 2;
  823. } else {
  824. yy = bitmap_y + PIXEL(y + glyph_slot->metrics.vertBearingY) + ascender;
  825. yy += PIXEL(glyph_info[i].y_offset);
  826. }
  827. if (yy >= 0 && yy < im->ysize) {
  828. // blend this glyph into the buffer
  829. unsigned char *target = im->image8[yy] + xx;
  830. if (mask) {
  831. // use monochrome mask (on palette images, etc)
  832. int j, k, m = 128;
  833. for (j = k = 0; j < x1; j++) {
  834. if (j >= x0 && (source[k] & m))
  835. target[j] = 255;
  836. if (!(m >>= 1)) {
  837. m = 128;
  838. k++;
  839. }
  840. }
  841. } else {
  842. // use antialiased rendering
  843. int k;
  844. for (k = x0; k < x1; k++) {
  845. if (target[k] < source[k])
  846. target[k] = source[k];
  847. }
  848. }
  849. }
  850. source += bitmap.pitch;
  851. }
  852. x += glyph_info[i].x_advance;
  853. y -= glyph_info[i].y_advance;
  854. }
  855. FT_Stroker_Done(stroker);
  856. PyMem_Del(glyph_info);
  857. Py_RETURN_NONE;
  858. }
  859. #if FREETYPE_MAJOR > 2 ||\
  860. (FREETYPE_MAJOR == 2 && FREETYPE_MINOR > 9) ||\
  861. (FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 9 && FREETYPE_PATCH == 1)
  862. static PyObject*
  863. font_getvarnames(FontObject* self, PyObject* args)
  864. {
  865. int error;
  866. FT_UInt i, j, num_namedstyles, name_count;
  867. FT_MM_Var *master;
  868. FT_SfntName name;
  869. PyObject *list_names, *list_name;
  870. error = FT_Get_MM_Var(self->face, &master);
  871. if (error)
  872. return geterror(error);
  873. num_namedstyles = master->num_namedstyles;
  874. list_names = PyList_New(num_namedstyles);
  875. name_count = FT_Get_Sfnt_Name_Count(self->face);
  876. for (i = 0; i < name_count; i++) {
  877. error = FT_Get_Sfnt_Name(self->face, i, &name);
  878. if (error)
  879. return geterror(error);
  880. for (j = 0; j < num_namedstyles; j++) {
  881. if (PyList_GetItem(list_names, j) != NULL)
  882. continue;
  883. if (master->namedstyle[j].strid == name.name_id) {
  884. list_name = Py_BuildValue(PY_ARG_BYTES_LENGTH,
  885. name.string, name.string_len);
  886. PyList_SetItem(list_names, j, list_name);
  887. break;
  888. }
  889. }
  890. }
  891. FT_Done_MM_Var(library, master);
  892. return list_names;
  893. }
  894. static PyObject*
  895. font_getvaraxes(FontObject* self, PyObject* args)
  896. {
  897. int error;
  898. FT_UInt i, j, num_axis, name_count;
  899. FT_MM_Var* master;
  900. FT_Var_Axis axis;
  901. FT_SfntName name;
  902. PyObject *list_axes, *list_axis, *axis_name;
  903. error = FT_Get_MM_Var(self->face, &master);
  904. if (error)
  905. return geterror(error);
  906. num_axis = master->num_axis;
  907. name_count = FT_Get_Sfnt_Name_Count(self->face);
  908. list_axes = PyList_New(num_axis);
  909. for (i = 0; i < num_axis; i++) {
  910. axis = master->axis[i];
  911. list_axis = PyDict_New();
  912. PyDict_SetItemString(list_axis, "minimum",
  913. PyInt_FromLong(axis.minimum / 65536));
  914. PyDict_SetItemString(list_axis, "default",
  915. PyInt_FromLong(axis.def / 65536));
  916. PyDict_SetItemString(list_axis, "maximum",
  917. PyInt_FromLong(axis.maximum / 65536));
  918. for (j = 0; j < name_count; j++) {
  919. error = FT_Get_Sfnt_Name(self->face, j, &name);
  920. if (error)
  921. return geterror(error);
  922. if (name.name_id == axis.strid) {
  923. axis_name = Py_BuildValue(PY_ARG_BYTES_LENGTH,
  924. name.string, name.string_len);
  925. PyDict_SetItemString(list_axis, "name", axis_name);
  926. break;
  927. }
  928. }
  929. PyList_SetItem(list_axes, i, list_axis);
  930. }
  931. FT_Done_MM_Var(library, master);
  932. return list_axes;
  933. }
  934. static PyObject*
  935. font_setvarname(FontObject* self, PyObject* args)
  936. {
  937. int error;
  938. int instance_index;
  939. if (!PyArg_ParseTuple(args, "i", &instance_index))
  940. return NULL;
  941. error = FT_Set_Named_Instance(self->face, instance_index);
  942. if (error)
  943. return geterror(error);
  944. Py_INCREF(Py_None);
  945. return Py_None;
  946. }
  947. static PyObject*
  948. font_setvaraxes(FontObject* self, PyObject* args)
  949. {
  950. int error;
  951. PyObject *axes, *item;
  952. Py_ssize_t i, num_coords;
  953. FT_Fixed *coords;
  954. FT_Fixed coord;
  955. if (!PyArg_ParseTuple(args, "O", &axes))
  956. return NULL;
  957. if (!PyList_Check(axes)) {
  958. PyErr_SetString(PyExc_TypeError, "argument must be a list");
  959. return NULL;
  960. }
  961. num_coords = PyObject_Length(axes);
  962. coords = malloc(2 * sizeof(coords));
  963. if (coords == NULL) {
  964. return PyErr_NoMemory();
  965. }
  966. for (i = 0; i < num_coords; i++) {
  967. item = PyList_GET_ITEM(axes, i);
  968. if (PyFloat_Check(item))
  969. coord = PyFloat_AS_DOUBLE(item);
  970. else if (PyInt_Check(item))
  971. coord = (float) PyInt_AS_LONG(item);
  972. else if (PyNumber_Check(item))
  973. coord = PyFloat_AsDouble(item);
  974. else {
  975. free(coords);
  976. PyErr_SetString(PyExc_TypeError, "list must contain numbers");
  977. return NULL;
  978. }
  979. coords[i] = coord * 65536;
  980. }
  981. error = FT_Set_Var_Design_Coordinates(self->face, num_coords, coords);
  982. free(coords);
  983. if (error)
  984. return geterror(error);
  985. Py_INCREF(Py_None);
  986. return Py_None;
  987. }
  988. #endif
  989. static void
  990. font_dealloc(FontObject* self)
  991. {
  992. if (self->face) {
  993. FT_Done_Face(self->face);
  994. }
  995. if (self->font_bytes) {
  996. PyMem_Free(self->font_bytes);
  997. }
  998. PyObject_Del(self);
  999. }
  1000. static PyMethodDef font_methods[] = {
  1001. {"render", (PyCFunction) font_render, METH_VARARGS},
  1002. {"getsize", (PyCFunction) font_getsize, METH_VARARGS},
  1003. #if FREETYPE_MAJOR > 2 ||\
  1004. (FREETYPE_MAJOR == 2 && FREETYPE_MINOR > 9) ||\
  1005. (FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 9 && FREETYPE_PATCH == 1)
  1006. {"getvarnames", (PyCFunction) font_getvarnames, METH_VARARGS },
  1007. {"getvaraxes", (PyCFunction) font_getvaraxes, METH_VARARGS },
  1008. {"setvarname", (PyCFunction) font_setvarname, METH_VARARGS},
  1009. {"setvaraxes", (PyCFunction) font_setvaraxes, METH_VARARGS},
  1010. #endif
  1011. {NULL, NULL}
  1012. };
  1013. static PyObject*
  1014. font_getattr_family(FontObject* self, void* closure)
  1015. {
  1016. #if PY_VERSION_HEX >= 0x03000000
  1017. if (self->face->family_name)
  1018. return PyUnicode_FromString(self->face->family_name);
  1019. #else
  1020. if (self->face->family_name)
  1021. return PyString_FromString(self->face->family_name);
  1022. #endif
  1023. Py_RETURN_NONE;
  1024. }
  1025. static PyObject*
  1026. font_getattr_style(FontObject* self, void* closure)
  1027. {
  1028. #if PY_VERSION_HEX >= 0x03000000
  1029. if (self->face->style_name)
  1030. return PyUnicode_FromString(self->face->style_name);
  1031. #else
  1032. if (self->face->style_name)
  1033. return PyString_FromString(self->face->style_name);
  1034. #endif
  1035. Py_RETURN_NONE;
  1036. }
  1037. static PyObject*
  1038. font_getattr_ascent(FontObject* self, void* closure)
  1039. {
  1040. return PyInt_FromLong(PIXEL(self->face->size->metrics.ascender));
  1041. }
  1042. static PyObject*
  1043. font_getattr_descent(FontObject* self, void* closure)
  1044. {
  1045. return PyInt_FromLong(-PIXEL(self->face->size->metrics.descender));
  1046. }
  1047. static PyObject*
  1048. font_getattr_height(FontObject* self, void* closure)
  1049. {
  1050. return PyInt_FromLong(PIXEL(self->face->size->metrics.height));
  1051. }
  1052. static PyObject*
  1053. font_getattr_x_ppem(FontObject* self, void* closure)
  1054. {
  1055. return PyInt_FromLong(self->face->size->metrics.x_ppem);
  1056. }
  1057. static PyObject*
  1058. font_getattr_y_ppem(FontObject* self, void* closure)
  1059. {
  1060. return PyInt_FromLong(self->face->size->metrics.y_ppem);
  1061. }
  1062. static PyObject*
  1063. font_getattr_glyphs(FontObject* self, void* closure)
  1064. {
  1065. return PyInt_FromLong(self->face->num_glyphs);
  1066. }
  1067. static struct PyGetSetDef font_getsetters[] = {
  1068. { "family", (getter) font_getattr_family },
  1069. { "style", (getter) font_getattr_style },
  1070. { "ascent", (getter) font_getattr_ascent },
  1071. { "descent", (getter) font_getattr_descent },
  1072. { "height", (getter) font_getattr_height },
  1073. { "x_ppem", (getter) font_getattr_x_ppem },
  1074. { "y_ppem", (getter) font_getattr_y_ppem },
  1075. { "glyphs", (getter) font_getattr_glyphs },
  1076. { NULL }
  1077. };
  1078. static PyTypeObject Font_Type = {
  1079. PyVarObject_HEAD_INIT(NULL, 0)
  1080. "Font", sizeof(FontObject), 0,
  1081. /* methods */
  1082. (destructor)font_dealloc, /* tp_dealloc */
  1083. 0, /* tp_print */
  1084. 0, /*tp_getattr*/
  1085. 0, /*tp_setattr*/
  1086. 0, /*tp_compare*/
  1087. 0, /*tp_repr*/
  1088. 0, /*tp_as_number */
  1089. 0, /*tp_as_sequence */
  1090. 0, /*tp_as_mapping */
  1091. 0, /*tp_hash*/
  1092. 0, /*tp_call*/
  1093. 0, /*tp_str*/
  1094. 0, /*tp_getattro*/
  1095. 0, /*tp_setattro*/
  1096. 0, /*tp_as_buffer*/
  1097. Py_TPFLAGS_DEFAULT, /*tp_flags*/
  1098. 0, /*tp_doc*/
  1099. 0, /*tp_traverse*/
  1100. 0, /*tp_clear*/
  1101. 0, /*tp_richcompare*/
  1102. 0, /*tp_weaklistoffset*/
  1103. 0, /*tp_iter*/
  1104. 0, /*tp_iternext*/
  1105. font_methods, /*tp_methods*/
  1106. 0, /*tp_members*/
  1107. font_getsetters, /*tp_getset*/
  1108. };
  1109. static PyMethodDef _functions[] = {
  1110. {"getfont", (PyCFunction) getfont, METH_VARARGS|METH_KEYWORDS},
  1111. {NULL, NULL}
  1112. };
  1113. static int
  1114. setup_module(PyObject* m) {
  1115. PyObject* d;
  1116. PyObject* v;
  1117. int major, minor, patch;
  1118. d = PyModule_GetDict(m);
  1119. /* Ready object type */
  1120. PyType_Ready(&Font_Type);
  1121. if (FT_Init_FreeType(&library))
  1122. return 0; /* leave it uninitialized */
  1123. FT_Library_Version(library, &major, &minor, &patch);
  1124. #if PY_VERSION_HEX >= 0x03000000
  1125. v = PyUnicode_FromFormat("%d.%d.%d", major, minor, patch);
  1126. #else
  1127. v = PyString_FromFormat("%d.%d.%d", major, minor, patch);
  1128. #endif
  1129. PyDict_SetItemString(d, "freetype2_version", v);
  1130. setraqm();
  1131. v = PyBool_FromLong(!!p_raqm.raqm);
  1132. PyDict_SetItemString(d, "HAVE_RAQM", v);
  1133. return 0;
  1134. }
  1135. #if PY_VERSION_HEX >= 0x03000000
  1136. PyMODINIT_FUNC
  1137. PyInit__imagingft(void) {
  1138. PyObject* m;
  1139. static PyModuleDef module_def = {
  1140. PyModuleDef_HEAD_INIT,
  1141. "_imagingft", /* m_name */
  1142. NULL, /* m_doc */
  1143. -1, /* m_size */
  1144. _functions, /* m_methods */
  1145. };
  1146. m = PyModule_Create(&module_def);
  1147. if (setup_module(m) < 0)
  1148. return NULL;
  1149. return m;
  1150. }
  1151. #else
  1152. PyMODINIT_FUNC
  1153. init_imagingft(void)
  1154. {
  1155. PyObject* m = Py_InitModule("_imagingft", _functions);
  1156. setup_module(m);
  1157. }
  1158. #endif