[Text Server] Prevent composite glyphs which incorporate kashida from being used for justification. Update TextServer tests to clean up on fail.

This commit is contained in:
bruvzg 2022-08-05 18:06:08 +03:00
parent 8f05263bd5
commit 4b155b939b
No known key found for this signature in database
GPG key ID: 7960FCF39844EC38
2 changed files with 121 additions and 79 deletions

View file

@ -4706,7 +4706,7 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(const RID &p_shape
for (int i = 0; i < sd_size; i++) {
if (sd_glyphs[i].count > 0) {
char32_t c = sd->text[sd_glyphs[i].start - sd->start];
if (c == 0x0640) {
if (c == 0x0640 && sd_glyphs[i].start == sd_glyphs[i].end - 1) {
sd_glyphs[i].flags |= GRAPHEME_IS_ELONGATION;
}
if (sd->jstops.has(sd_glyphs[i].start)) {

View file

@ -44,7 +44,7 @@ TEST_SUITE("[TextServer]") {
SUBCASE("[TextServer] Loading fonts") {
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface.");
if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC)) {
continue;
@ -52,7 +52,7 @@ TEST_SUITE("[TextServer]") {
RID font = ts->create_font();
ts->font_set_data_ptr(font, _font_NotoSans_Regular, _font_NotoSans_Regular_size);
TEST_FAIL_COND(font == RID(), "Loading font failed.");
CHECK_FALSE_MESSAGE(font == RID(), "Loading font failed.");
ts->free_rid(font);
}
}
@ -60,7 +60,7 @@ TEST_SUITE("[TextServer]") {
SUBCASE("[TextServer] Text layout: Font fallback") {
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface.");
if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
continue;
@ -79,26 +79,26 @@ TEST_SUITE("[TextServer]") {
// 6^ 17^
RID ctx = ts->create_shaped_text();
TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed.");
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
bool ok = ts->shaped_text_add_string(ctx, test, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx);
int gl_size = ts->shaped_text_get_glyph_count(ctx);
TEST_FAIL_COND(gl_size == 0, "Shaping failed");
CHECK_FALSE_MESSAGE(gl_size == 0, "Shaping failed");
for (int j = 0; j < gl_size; j++) {
if (glyphs[j].start < 6) {
TEST_FAIL_COND(glyphs[j].font_rid != font[1], "Incorrect font selected.");
CHECK_FALSE_MESSAGE(glyphs[j].font_rid != font[1], "Incorrect font selected.");
}
if ((glyphs[j].start > 6) && (glyphs[j].start < 16)) {
TEST_FAIL_COND(glyphs[j].font_rid != font[0], "Incorrect font selected.");
CHECK_FALSE_MESSAGE(glyphs[j].font_rid != font[0], "Incorrect font selected.");
}
if (glyphs[j].start > 16) {
TEST_FAIL_COND(glyphs[j].font_rid != RID(), "Incorrect font selected.");
TEST_FAIL_COND(glyphs[j].index != test[glyphs[j].start], "Incorrect glyph index.");
CHECK_FALSE_MESSAGE(glyphs[j].font_rid != RID(), "Incorrect font selected.");
CHECK_FALSE_MESSAGE(glyphs[j].index != test[glyphs[j].start], "Incorrect glyph index.");
}
TEST_FAIL_COND((glyphs[j].start < 0 || glyphs[j].end > test.length()), "Incorrect glyph range.");
TEST_FAIL_COND(glyphs[j].font_size != 16, "Incorrect glyph font size.");
CHECK_FALSE_MESSAGE((glyphs[j].start < 0 || glyphs[j].end > test.length()), "Incorrect glyph range.");
CHECK_FALSE_MESSAGE(glyphs[j].font_size != 16, "Incorrect glyph font size.");
}
ts->free_rid(ctx);
@ -113,7 +113,7 @@ TEST_SUITE("[TextServer]") {
SUBCASE("[TextServer] Text layout: BiDi") {
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface.");
if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_BIDI_LAYOUT)) {
continue;
@ -132,23 +132,23 @@ TEST_SUITE("[TextServer]") {
// 7^ 26^
RID ctx = ts->create_shaped_text();
TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed.");
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
bool ok = ts->shaped_text_add_string(ctx, test, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx);
int gl_size = ts->shaped_text_get_glyph_count(ctx);
TEST_FAIL_COND(gl_size == 0, "Shaping failed");
CHECK_FALSE_MESSAGE(gl_size == 0, "Shaping failed");
for (int j = 0; j < gl_size; j++) {
if (glyphs[j].count > 0) {
if (glyphs[j].start < 7) {
TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction.");
CHECK_FALSE_MESSAGE(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction.");
}
if ((glyphs[j].start > 8) && (glyphs[j].start < 23)) {
TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) != TextServer::GRAPHEME_IS_RTL), "Incorrect direction.");
CHECK_FALSE_MESSAGE(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) != TextServer::GRAPHEME_IS_RTL), "Incorrect direction.");
}
if (glyphs[j].start > 26) {
TEST_FAIL_COND(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction.");
CHECK_FALSE_MESSAGE(((glyphs[j].flags & TextServer::GRAPHEME_IS_RTL) == TextServer::GRAPHEME_IS_RTL), "Incorrect direction.");
}
}
}
@ -165,7 +165,7 @@ TEST_SUITE("[TextServer]") {
SUBCASE("[TextServer] Text layout: Line break and align points") {
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface.");
if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
continue;
@ -186,16 +186,16 @@ TEST_SUITE("[TextServer]") {
{
String test = U"Test test long text long text\n";
RID ctx = ts->create_shaped_text();
TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed.");
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
bool ok = ts->shaped_text_add_string(ctx, test, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
ts->shaped_text_update_breaks(ctx);
ts->shaped_text_update_justification_ops(ctx);
const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx);
int gl_size = ts->shaped_text_get_glyph_count(ctx);
TEST_FAIL_COND(gl_size != 30, "Invalid glyph count.");
CHECK_FALSE_MESSAGE(gl_size != 30, "Invalid glyph count.");
for (int j = 0; j < gl_size; j++) {
bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD;
bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT;
@ -203,11 +203,11 @@ TEST_SUITE("[TextServer]") {
bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL;
bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION;
if (j == 4 || j == 9 || j == 14 || j == 19 || j == 24) {
TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags.");
} else if (j == 29) {
TEST_FAIL_COND((soft || !space || !hard || virt || elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((soft || !space || !hard || virt || elo), "Invalid glyph flags.");
} else {
TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags.");
}
}
ts->free_rid(ctx);
@ -216,21 +216,63 @@ TEST_SUITE("[TextServer]") {
{
String test = U"الحمـد";
RID ctx = ts->create_shaped_text();
TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed.");
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
bool ok = ts->shaped_text_add_string(ctx, test, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
ts->shaped_text_update_breaks(ctx);
const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx);
int gl_size = ts->shaped_text_get_glyph_count(ctx);
TEST_FAIL_COND(gl_size != 6, "Invalid glyph count.");
CHECK_FALSE_MESSAGE(gl_size != 6, "Invalid glyph count.");
for (int j = 0; j < gl_size; j++) {
bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD;
bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT;
bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE;
bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL;
bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION;
TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags.");
}
if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) {
ts->shaped_text_update_justification_ops(ctx);
glyphs = ts->shaped_text_get_glyphs(ctx);
gl_size = ts->shaped_text_get_glyph_count(ctx);
CHECK_FALSE_MESSAGE(gl_size != 6, "Invalid glyph count.");
for (int j = 0; j < gl_size; j++) {
bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD;
bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT;
bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE;
bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL;
bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION;
if (j == 1) {
CHECK_FALSE_MESSAGE((soft || space || hard || virt || !elo), "Invalid glyph flags.");
} else {
CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags.");
}
}
}
ts->free_rid(ctx);
}
{
String test = U"الحمد";
RID ctx = ts->create_shaped_text();
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
bool ok = ts->shaped_text_add_string(ctx, test, font, 16);
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
ts->shaped_text_update_breaks(ctx);
const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx);
int gl_size = ts->shaped_text_get_glyph_count(ctx);
CHECK_FALSE_MESSAGE(gl_size != 5, "Invalid glyph count.");
for (int j = 0; j < gl_size; j++) {
bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD;
bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT;
bool space = (glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE;
bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL;
bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION;
CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags.");
}
if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) {
@ -239,7 +281,7 @@ TEST_SUITE("[TextServer]") {
glyphs = ts->shaped_text_get_glyphs(ctx);
gl_size = ts->shaped_text_get_glyph_count(ctx);
TEST_FAIL_COND(gl_size != 6, "Invalid glyph count.");
CHECK_FALSE_MESSAGE(gl_size != 6, "Invalid glyph count.");
for (int j = 0; j < gl_size; j++) {
bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD;
bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT;
@ -247,9 +289,9 @@ TEST_SUITE("[TextServer]") {
bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL;
bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION;
if (j == 1) {
TEST_FAIL_COND((soft || space || hard || virt || !elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((soft || space || hard || !virt || !elo), "Invalid glyph flags.");
} else {
TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags.");
}
}
}
@ -259,15 +301,15 @@ TEST_SUITE("[TextServer]") {
{
String test = U"الحمـد الرياضي العربي";
RID ctx = ts->create_shaped_text();
TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed.");
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
bool ok = ts->shaped_text_add_string(ctx, test, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
ts->shaped_text_update_breaks(ctx);
const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx);
int gl_size = ts->shaped_text_get_glyph_count(ctx);
TEST_FAIL_COND(gl_size != 21, "Invalid glyph count.");
CHECK_FALSE_MESSAGE(gl_size != 21, "Invalid glyph count.");
for (int j = 0; j < gl_size; j++) {
bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD;
bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT;
@ -275,9 +317,9 @@ TEST_SUITE("[TextServer]") {
bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL;
bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION;
if (j == 6 || j == 14) {
TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags.");
} else {
TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags.");
}
}
@ -287,7 +329,7 @@ TEST_SUITE("[TextServer]") {
glyphs = ts->shaped_text_get_glyphs(ctx);
gl_size = ts->shaped_text_get_glyph_count(ctx);
TEST_FAIL_COND(gl_size != 23, "Invalid glyph count.");
CHECK_FALSE_MESSAGE(gl_size != 23, "Invalid glyph count.");
for (int j = 0; j < gl_size; j++) {
bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD;
bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT;
@ -295,13 +337,13 @@ TEST_SUITE("[TextServer]") {
bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL;
bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION;
if (j == 7 || j == 16) {
TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags.");
} else if (j == 3 || j == 9) {
TEST_FAIL_COND((soft || space || hard || !virt || !elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((soft || space || hard || !virt || !elo), "Invalid glyph flags.");
} else if (j == 18) {
TEST_FAIL_COND((soft || space || hard || virt || !elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((soft || space || hard || virt || !elo), "Invalid glyph flags.");
} else {
TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags.");
}
}
}
@ -312,16 +354,16 @@ TEST_SUITE("[TextServer]") {
{
String test = U"เป็น ภาษา ราชการ และ ภาษา";
RID ctx = ts->create_shaped_text();
TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed.");
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
bool ok = ts->shaped_text_add_string(ctx, test, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
ts->shaped_text_update_breaks(ctx);
ts->shaped_text_update_justification_ops(ctx);
const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx);
int gl_size = ts->shaped_text_get_glyph_count(ctx);
TEST_FAIL_COND(gl_size != 25, "Invalid glyph count.");
CHECK_FALSE_MESSAGE(gl_size != 25, "Invalid glyph count.");
for (int j = 0; j < gl_size; j++) {
bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD;
bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT;
@ -329,9 +371,9 @@ TEST_SUITE("[TextServer]") {
bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL;
bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION;
if (j == 4 || j == 9 || j == 16 || j == 20) {
TEST_FAIL_COND((!soft || !space || hard || virt || elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((!soft || !space || hard || virt || elo), "Invalid glyph flags.");
} else {
TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags.");
}
}
ts->free_rid(ctx);
@ -340,16 +382,16 @@ TEST_SUITE("[TextServer]") {
if (ts->has_feature(TextServer::FEATURE_BREAK_ITERATORS)) {
String test = U"เป็นภาษาราชการและภาษา";
RID ctx = ts->create_shaped_text();
TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed.");
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
bool ok = ts->shaped_text_add_string(ctx, test, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
ts->shaped_text_update_breaks(ctx);
ts->shaped_text_update_justification_ops(ctx);
const Glyph *glyphs = ts->shaped_text_get_glyphs(ctx);
int gl_size = ts->shaped_text_get_glyph_count(ctx);
TEST_FAIL_COND(gl_size != 25, "Invalid glyph count.");
CHECK_FALSE_MESSAGE(gl_size != 25, "Invalid glyph count.");
for (int j = 0; j < gl_size; j++) {
bool hard = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_HARD) == TextServer::GRAPHEME_IS_BREAK_HARD;
bool soft = (glyphs[j].flags & TextServer::GRAPHEME_IS_BREAK_SOFT) == TextServer::GRAPHEME_IS_BREAK_SOFT;
@ -357,9 +399,9 @@ TEST_SUITE("[TextServer]") {
bool virt = (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL;
bool elo = (glyphs[j].flags & TextServer::GRAPHEME_IS_ELONGATION) == TextServer::GRAPHEME_IS_ELONGATION;
if (j == 4 || j == 9 || j == 16 || j == 20) {
TEST_FAIL_COND((!soft || !space || hard || !virt || elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((!soft || !space || hard || !virt || elo), "Invalid glyph flags.");
} else {
TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags.");
CHECK_FALSE_MESSAGE((soft || space || hard || virt || elo), "Invalid glyph flags.");
}
}
ts->free_rid(ctx);
@ -375,7 +417,7 @@ TEST_SUITE("[TextServer]") {
SUBCASE("[TextServer] Text layout: Line breaking") {
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface.");
if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
continue;
@ -394,21 +436,21 @@ TEST_SUITE("[TextServer]") {
font.push_back(font2);
RID ctx = ts->create_shaped_text();
TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed.");
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
bool ok = ts->shaped_text_add_string(ctx, test_1, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
PackedInt32Array brks = ts->shaped_text_get_line_breaks(ctx, 1);
TEST_FAIL_COND(brks.size() != 6, "Invalid line breaks number.");
CHECK_FALSE_MESSAGE(brks.size() != 6, "Invalid line breaks number.");
if (brks.size() == 6) {
TEST_FAIL_COND(brks[0] != 0, "Invalid line break position.");
TEST_FAIL_COND(brks[1] != 5, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[0] != 0, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[1] != 5, "Invalid line break position.");
TEST_FAIL_COND(brks[2] != 5, "Invalid line break position.");
TEST_FAIL_COND(brks[3] != 10, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[2] != 5, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[3] != 10, "Invalid line break position.");
TEST_FAIL_COND(brks[4] != 10, "Invalid line break position.");
TEST_FAIL_COND(brks[5] != 14, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[4] != 10, "Invalid line break position.");
CHECK_FALSE_MESSAGE(brks[5] != 14, "Invalid line break position.");
}
ts->free_rid(ctx);
@ -423,7 +465,7 @@ TEST_SUITE("[TextServer]") {
SUBCASE("[TextServer] Text layout: Justification") {
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface.");
if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
continue;
@ -448,40 +490,40 @@ TEST_SUITE("[TextServer]") {
float width_old, width;
if (ts->has_feature(TextServer::FEATURE_KASHIDA_JUSTIFICATION)) {
ctx = ts->create_shaped_text();
TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed.");
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
ok = ts->shaped_text_add_string(ctx, test_1, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
width_old = ts->shaped_text_get_width(ctx);
width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND);
TEST_FAIL_COND((width != width_old), "Invalid fill width.");
CHECK_FALSE_MESSAGE((width != width_old), "Invalid fill width.");
width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA);
TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width.");
CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width.");
ts->free_rid(ctx);
ctx = ts->create_shaped_text();
TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed.");
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
ok = ts->shaped_text_add_string(ctx, test_2, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
width_old = ts->shaped_text_get_width(ctx);
width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND);
TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width.");
CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width.");
width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA);
TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width.");
CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width.");
ts->free_rid(ctx);
}
ctx = ts->create_shaped_text();
TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed.");
CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed.");
ok = ts->shaped_text_add_string(ctx, test_3, font, 16);
TEST_FAIL_COND(!ok, "Adding text to the buffer failed.");
CHECK_FALSE_MESSAGE(!ok, "Adding text to the buffer failed.");
width_old = ts->shaped_text_get_width(ctx);
width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND);
TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width.");
CHECK_FALSE_MESSAGE((width <= width_old || width > 100), "Invalid fill width.");
ts->free_rid(ctx);
@ -495,7 +537,7 @@ TEST_SUITE("[TextServer]") {
SUBCASE("[TextServer] Unicode identifiers") {
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface.");
static const char32_t *data[19] = { U"-30", U"100", U"10.1", U"10,1", U"1e2", U"1e-2", U"1e2e3", U"0xAB", U"AB", U"Test1", U"1Test", U"Test*1", U"test_testeT", U"test_tes teT", U"عَلَيْكُمْ", U"عَلَيْكُمْTest", U"ӒӖӚӜ", U"_test", U"ÂÃÄÅĀĂĄÇĆĈĊ" };
static bool isid[19] = { false, false, false, false, false, false, false, false, true, true, false, false, true, false, true, true, true, true, true };
@ -516,7 +558,7 @@ TEST_SUITE("[TextServer]") {
SUBCASE("[TextServer] Strip Diacritics") {
for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface.");
if (ts->has_feature(TextServer::FEATURE_SHAPING)) {
CHECK(ts->strip_diacritics(U"ٱلسَّلَامُ عَلَيْكُمْ") == U"ٱلسلام عليكم");
@ -544,7 +586,7 @@ TEST_SUITE("[TextServer]") {
continue;
}
TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
CHECK_FALSE_MESSAGE(ts.is_null(), "Invalid TS interface.");
{
String text1 = U"linguistically similar and effectively form";
// 14^ 22^ 26^ 38^