373 static size_t
374 text_layout_fallback(
375 PyObject *string,
376 FontObject *self,
377 const char *dir,
378 PyObject *features,
379 const char *lang,
380 GlyphInfo **glyph_info,
381 int mask,
382 int color) {
383 int error, load_flags;
384 FT_ULong ch;
385 Py_ssize_t count;
386 FT_GlyphSlot glyph;
387 FT_Bool kerning = FT_HAS_KERNING(self->face);
when treating unknown struct FT_FaceRec_ * from src/_imagingft.c:387 as non-NULL
388 FT_UInt last_index = 0;
389 int i;
390
391 if (features != Py_None || dir != NULL || lang != NULL) {
taking True path
392 PyErr_SetString(
calling PyErr_SetString()
393 PyExc_KeyError,
394 "setting text direction, language or font features is not supported "
395 "without libraqm");
396 }
397 if (!PyUnicode_Check(string)) {
when considering range: 1 <= value <= 0x10000000
taking False path
398 PyErr_SetString(PyExc_TypeError, "expected string");
399 return 0;
400 }
401
402 count = 0;
403 while (font_getchar(string, count, &ch)) {
when considering range: -0x80000000 <= value <= -1
taking True path
when considering value == (int)0 from src/_imagingft.c:403
taking False path
404 count++;
405 }
406 if (count == 0) {
taking False path
407 return 0;
408 }
409
410 (*glyph_info) = PyMem_New(GlyphInfo, count);
taking True path
when PyMem_Malloc() succeeds
when treating unknown struct GlyphInfo * * from src/_imagingft.c:380 as non-NULL
411 if ((*glyph_info) == NULL) {
taking False path
412 PyErr_SetString(PyExc_MemoryError, "PyMem_New() failed");
413 return 0;
414 }
415
416 load_flags = FT_LOAD_DEFAULT;
417 if (mask) {
when considering range: -0x80000000 <= value <= -1
taking True path
418 load_flags |= FT_LOAD_TARGET_MONO;
419 }
420 #ifdef FT_LOAD_COLOR
421 if (color) {
when considering range: -0x80000000 <= value <= -1
taking True path
422 load_flags |= FT_LOAD_COLOR;
423 }
424 #endif
425 for (i = 0; font_getchar(string, i, &ch); i++) {
when considering range: 1 <= value <= 0x7fffffff
taking True path
426 (*glyph_info)[i].index = FT_Get_Char_Index(self->face, ch);
427 error = FT_Load_Glyph(self->face, (*glyph_info)[i].index, load_flags);
428 if (error) {
when considering range: -0x80000000 <= value <= -1
taking True path
429 geterror(error);
when geterror() succeeds
new ref from (unknown) geterror was allocated at: geterror(error);
ob_refcnt is now refs: 1 owned
430 return 0;
431 }
432 glyph = self->face->glyph;
433 (*glyph_info)[i].x_offset = 0;
434 (*glyph_info)[i].y_offset = 0;
435 if (kerning && last_index && (*glyph_info)[i].index) {
436 FT_Vector delta;
437 if (FT_Get_Kerning(
438 self->face,
439 last_index,
440 (*glyph_info)[i].index,
441 ft_kerning_default,
442 &delta) == 0) {
443 (*glyph_info)[i - 1].x_advance += PIXEL(delta.x);
444 (*glyph_info)[i - 1].y_advance += PIXEL(delta.y);
445 }
446 }
447
448 (*glyph_info)[i].x_advance = glyph->metrics.horiAdvance;
449 // y_advance is only used in ttb, which is not supported by basic layout
450 (*glyph_info)[i].y_advance = 0;
451 last_index = (*glyph_info)[i].index;
452 (*glyph_info)[i].cluster = ch;
453 }
454 return count;
455 }