fix Raqm fallback algorithm when a missing glyph is followed by a non-missing glyph in a single cluster

This commit is contained in:
nulano 2023-02-02 15:41:29 +00:00 committed by Nulano
parent 3b3cac84a8
commit c244169a8e
2 changed files with 23 additions and 21 deletions

View File

@ -731,7 +731,7 @@ class FreeTypeFontFamily:
# f2 = ImageFont.truetype("segoeui.ttf", 24) # f2 = ImageFont.truetype("segoeui.ttf", 24)
# f3 = ImageFont.truetype("seguisym.ttf", 24) # f3 = ImageFont.truetype("seguisym.ttf", 24)
# ff = ImageFont.FreeTypeFontFamily(f1, f2, f3, layout_engine=le) # ff = ImageFont.FreeTypeFontFamily(f1, f2, f3, layout_engine=le)
# for s in ("testčingšsšccčcč", "ية↦α,abc", "a↦ľ"): # for s in ("testčingšsšccčcč", "ية↦α,abc", "a↦ľ", "ῶ,ω̃,ώ,ώ, ́,á"):
# im = Image.new("RGBA", (300, 300), "white") # im = Image.new("RGBA", (300, 300), "white")
# d = ImageDraw.Draw(im) # d = ImageDraw.Draw(im)
# d.text((10, 60), s, "black", f1, direction="ltr", anchor="ls") # d.text((10, 60), s, "black", f1, direction="ltr", anchor="ls")

View File

@ -398,7 +398,7 @@ text_layout_raqm(
GlyphInfo **glyph_info GlyphInfo **glyph_info
) { ) {
int face = 0; int face = 0;
size_t i = 0, j = 0, count = 0, start = 0; size_t i = 0, count = 0, start = 0;
raqm_t *rq = NULL; raqm_t *rq = NULL;
raqm_glyph_t *glyphs = NULL; raqm_glyph_t *glyphs = NULL;
raqm_direction_t direction; raqm_direction_t direction;
@ -458,9 +458,8 @@ text_layout_raqm(
PyErr_SetString(PyExc_ValueError, "failed to allocate fallback buffer."); PyErr_SetString(PyExc_ValueError, "failed to allocate fallback buffer.");
goto failed; goto failed;
} }
fallback[0] = -1; for (i = 0; i < size; i++) {
for (j = 1; j < size; j++) { fallback[i] = -2;
fallback[j] = -2;
} }
} }
@ -545,25 +544,25 @@ text_layout_raqm(
} }
} else { } else {
start = 0; start = 0;
for (j = 0; j <= size; j++) { for (i = 0; i <= size; i++) {
if (j < size) { if (i < size) {
if (fallback[j] == -2) { if (fallback[i] == -2) {
/* not a cluster boundary */ /* not a cluster boundary */
continue; continue;
} }
if (fallback[start] == fallback[j]) { if (fallback[start] == fallback[i]) {
/* use same font face for this cluster */ /* use same font face for this cluster */
continue; continue;
} }
} }
if (fallback[start] == -1) { if (fallback[start] < 0) {
raqm_set_freetype_face_range( raqm_set_freetype_face_range(
rq, family->faces[face], start, j - start); rq, family->faces[face], start, i - start);
} else { } else {
raqm_set_freetype_face_range( raqm_set_freetype_face_range(
rq, family->faces[fallback[start]], start, j - start); rq, family->faces[fallback[start]], start, i - start);
} }
start = j; start = i;
} }
} }
@ -579,24 +578,27 @@ text_layout_raqm(
goto failed; goto failed;
} }
if (i + 1 == family->font_count) { //if (face + 1 == family->font_count) {
// break;
//}
if (family->font_count == 1) {
break; break;
} }
for (j = 1; j < size; j++) { for (i = 1; i < size; i++) {
if (fallback[j] == -1) { if (fallback[i] == -1) {
fallback[j] = -2; fallback[i] = -2;
} }
} }
int missing = 0; int missing = 0;
for (j = 0; j < count; j++) { for (i = 0; i < count; i++) {
int cluster = glyphs[j].cluster; int cluster = glyphs[i].cluster;
if (glyphs[j].index == 0) { if (glyphs[i].index == 0) {
/* cluster contains missing glyph */ /* cluster contains missing glyph */
fallback[cluster] = -1; fallback[cluster] = -1;
missing = 1; missing = 1;
} else if (fallback[cluster] < 0) { } else if (fallback[cluster] == -2) {
/* use current font face for this cluster */ /* use current font face for this cluster */
fallback[cluster] = face; fallback[cluster] = face;
} }