summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-11-20 10:36:03 -0500
committerJonathan Bradley <jcb@pikum.xyz>2025-11-20 10:38:19 -0500
commitf2ab9881866de69291c98c1214e54680ae9a60f1 (patch)
treefb3b71e2ecf939a9facc7b1f9577edf63ea2a671
parent3c2260cc462c4638de2a490ceb90b4937c5bb2a7 (diff)
pke: chkpt: line length, pre fibi write refactor
-rw-r--r--src/font.cpp50
-rw-r--r--tests/pke-test-font.cpp449
2 files changed, 324 insertions, 175 deletions
diff --git a/src/font.cpp b/src/font.cpp
index cce9cc4..fd35019 100644
--- a/src/font.cpp
+++ b/src/font.cpp
@@ -129,22 +129,26 @@ float FontType_Inner_LookAheadLineLength(const FontType *const ft, const FontRen
}
// we want to burn white-space characters at the front and at the back
if (PK_HAS_FLAG(fgc->flags, FONT_GLYPH_CHAR_FLAGS_WHITESPACE) == true) {
- ret += fgc->advance * font_glyph_spacing;
- // burn the front
- if (i == index) {
+ sz = fgc->advance * font_glyph_spacing;
+ if (ret + sz > fr->settings.surface_area_size.x) {
+ break;
+ }
+ ret += sz;
+ // burn the front - but only if we wrapped
+ fgc2 = nullptr;
+ if (i != 0) {
+ fgc2 = &ft->glyphs[fr->glyph_indices[i-1]];
+ if (!PK_HAS_FLAG(fgc2->flags, FONT_GLYPH_CHAR_FLAGS_NEW_LINE)) {
+ fgc2 = nullptr;
+ }
+ }
+ if (i == index && fgc2 != nullptr) {
ret = 0;
}
continue;
}
sz = FontType_Inner_LookAheadWordLength(ft, fr, i, font_glyph_spacing, &ii);
if (ret + sz > fr->settings.surface_area_size.x) {
- // burn the back
- if (i != index) {
- fgc2 = fgc-1;
- if (PK_HAS_FLAG(fgc2->flags, FONT_GLYPH_CHAR_FLAGS_WHITESPACE) == true) {
- ret -= fgc2->advance * font_glyph_spacing;
- }
- }
break;
}
// -1 because the for loop is about to +1.
@@ -153,6 +157,20 @@ float FontType_Inner_LookAheadLineLength(const FontType *const ft, const FontRen
i += ii-1;
ret += sz;
}
+ // If we are at the end of a line:
+ // Burn all white-space until we have a non-white-space
+ // subtract the extra width of `advance` (char spacing, don't need it)
+ ii = 1;
+ while (i != 0 && i - ii >= index && i - ii > 0) {
+ fgc = &ft->glyphs[fr->glyph_indices[i-ii]];
+ ret -= fgc->advance * font_glyph_spacing;
+ if (PK_HAS_FLAG(fgc->flags, FONT_GLYPH_CHAR_FLAGS_WHITESPACE)) {
+ ii += 1;
+ continue;
+ }
+ ret += (fgc->plane_bounds.z - fgc->plane_bounds.x) * font_glyph_spacing;
+ break;
+ }
if (char_count != nullptr) {
*char_count = i - index;
}
@@ -236,11 +254,8 @@ bool FontType_Inner_CalcTransforms(const FontType *ft, FontRender *fr, FontInsta
cursor_head = (fr->settings.surface_area_size.x - line_length) / 2.0;
}
if (PK_HAS_FLAG(fr->settings.surface_area_type_flags, FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_CENTER_VERTICAL)) {
- float text_height = FontType_Inner_LookAheadLineCount(ft, fr, 0) * line_height;
- // TODO
- // This is wrong but I'm not sure how/why.
- // Mathematically it should be ` / 2.0`.
- line_offset += (fr->settings.surface_area_size.y - text_height) / 4.0;
+ float text_height = FontType_Inner_LookAheadLineCount(ft, fr, 0, font_glyph_spacing) * line_height;
+ line_offset += (fr->settings.surface_area_size.y - text_height) / 2.0;
}
for (i = 0, ii = 0; i < fr->n_glyphs; ++i) {
@@ -331,7 +346,10 @@ bool FontType_Inner_CalcTransforms(const FontType *ft, FontRender *fr, FontInsta
// box position
translate.y = fr->settings.surface_area_pos.y;
// baseline - current line (+1 to not draw above the box)
- translate.y += ((line_index + 1) * line_height);
+ // - first line ignore line height, just use EM
+ translate.y += font_glyph_spacing;
+ translate.y += (line_index * line_height);
+ // - if vertically centered
translate.y += line_offset;
// places the top line of the glyph on the baseline
translate.y += (font_glyph_spacing / 2.0) + (glyph_size.y / 2.0);
diff --git a/tests/pke-test-font.cpp b/tests/pke-test-font.cpp
index d475fdd..dd078ab 100644
--- a/tests/pke-test-font.cpp
+++ b/tests/pke-test-font.cpp
@@ -79,6 +79,9 @@ int pke_test_font_003() {
FontTypeRender handles[count];
FontRenderSettings frs{};
+ frs.surface_area_size = glm::vec2(300, 300);
+ frs.surface_area_type_flags |= FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_CENTER_BOTH;
+
for (u = 0; u < count; ++u) {
handles[u].font_type_handle = {0,0};
handles[u].font_render_handle = {0,0};
@@ -100,37 +103,29 @@ int pke_test_font_003() {
struct pke_test_font_inner_func_params {
uint32_t index;
uint32_t char_count;
- float length;
+ float val;
};
int pke_test_font_inner_word_length(const FontType *const ft, const FontRender *const fr, float font_glyph_spacing, pke_test_font_inner_func_params *params, uint32_t n_params) {
- float len;
- uint32_t u, ii;
+ uint32_t u;
for (u = 0; u < n_params; ++u) {
- len = FontType_Inner_LookAheadWordLength(ft, fr, params[u].index, font_glyph_spacing, &ii);
- PK_TEST_ASSERT_EQ_RET(params[u].char_count, ii);
- PK_TEST_ASSERT_NEQ_RET(params[u].length, len);
+ params[u].val = FontType_Inner_LookAheadWordLength(ft, fr, params[u].index, font_glyph_spacing, &params[u].char_count);
}
return 0;
}
int pke_test_font_inner_line_length(const FontType *const ft, const FontRender *const fr, float font_glyph_spacing, pke_test_font_inner_func_params *params, uint32_t n_params) {
- float len;
- uint32_t u, ii;
+ uint32_t u;
for (u = 0; u < n_params; ++u) {
- len = FontType_Inner_LookAheadLineLength(ft, fr, params[u].index, font_glyph_spacing, &ii);
- PK_TEST_ASSERT_EQ_RET(params[u].char_count, ii);
- PK_TEST_ASSERT_NEQ_RET(params[u].length, len);
+ params[u].val = FontType_Inner_LookAheadLineLength(ft, fr, params[u].index, font_glyph_spacing, &params[u].char_count);
}
return 0;
}
int pke_test_font_inner_line_count(const FontType *const ft, const FontRender *const fr, float font_glyph_spacing, pke_test_font_inner_func_params *params, uint32_t n_params) {
- float len;
uint32_t u;
for (u = 0; u < n_params; ++u) {
- len = FontType_Inner_LookAheadLineCount(ft, fr, params[u].index, font_glyph_spacing);
- PK_TEST_ASSERT_EQ_RET(params[u].length, len);
+ params[u].val = FontType_Inner_LookAheadLineCount(ft, fr, params[u].index, font_glyph_spacing);
}
return 0;
}
@@ -161,71 +156,60 @@ int pke_test_font_004() {
font_glyph_spacing = ft->spacing.em_size * fr->settings.char_scale;
+ pke_test_font_inner_func_params params[5];
+ params[0].index = 0;
+ params[1].index = 6;
+ params[2].index = 7;
+ params[3].index = 9;
+ params[4].index = 10;
+
// word length
{
- pke_test_font_inner_func_params params_word_len[5];
- params_word_len[0].index = 0;
- params_word_len[0].char_count = 6;
- params_word_len[0].length = 0.f;
- params_word_len[1].index = 6;
- params_word_len[1].char_count = 0;
- params_word_len[1].length = 1.f;
- params_word_len[2].index = 7;
- params_word_len[2].char_count = 3;
- params_word_len[2].length = 0.f;
- params_word_len[3].index = 9;
- params_word_len[3].char_count = 1;
- params_word_len[3].length = 0.f;
- params_word_len[4].index = 10;
- params_word_len[4].char_count = 0;
- params_word_len[4].length = 1.f;
-
- if ((u = pke_test_font_inner_word_length(ft, fr, font_glyph_spacing, params_word_len, 5)), u != 0) {
- return u;
+ for (u = 0; u < 5; ++u) {
+ params[u].val = FontType_Inner_LookAheadWordLength(ft, fr, params[u].index, font_glyph_spacing, &params[u].char_count);
}
+
+ PK_TEST_ASSERT_EQ_RET (6, params[0].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[0].val);
+ PK_TEST_ASSERT_EQ_RET (0, params[1].char_count);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[1].val);
+ PK_TEST_ASSERT_EQ_RET (3, params[2].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[2].val);
+ PK_TEST_ASSERT_EQ_RET (1, params[3].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[3].val);
+ PK_TEST_ASSERT_EQ_RET (0, params[4].char_count);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[4].val);
}
// line length
{
- pke_test_font_inner_func_params params_line_len[5];
- params_line_len[0].index = 0;
- params_line_len[0].char_count = 10;
- params_line_len[0].length = 0.f;
- params_line_len[1].index = 6;
- params_line_len[1].char_count = 4;
- params_line_len[1].length = 0.f;
- params_line_len[2].index = 7;
- params_line_len[2].char_count = 3;
- params_line_len[2].length = 0.f;
- params_line_len[3].index = 9;
- params_line_len[3].char_count = 1;
- params_line_len[3].length = 0.f;
- params_line_len[4].index = 10;
- params_line_len[4].char_count = 0;
- params_line_len[4].length = 1.f;
-
- if ((u = pke_test_font_inner_line_length(ft, fr, font_glyph_spacing, params_line_len, 5)), u != 0) {
- return u;
+ for (u = 0; u < 5; ++u) {
+ params[u].val = FontType_Inner_LookAheadLineLength(ft, fr, params[u].index, font_glyph_spacing, &params[u].char_count);
}
+
+ PK_TEST_ASSERT_EQ_RET (10, params[0].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[0].val);
+ PK_TEST_ASSERT_EQ_RET (4, params[1].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[1].val);
+ PK_TEST_ASSERT_EQ_RET (3, params[2].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[2].val);
+ PK_TEST_ASSERT_EQ_RET (1, params[3].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[3].val);
+ PK_TEST_ASSERT_EQ_RET (0, params[4].char_count);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[4].val);
}
// line count
{
- pke_test_font_inner_func_params params_line_count[5];
- params_line_count[0].index = 0;
- params_line_count[0].length = 1.f;
- params_line_count[1].index = 6;
- params_line_count[1].length = 1.f;
- params_line_count[2].index = 7;
- params_line_count[2].length = 1.f;
- params_line_count[3].index = 9;
- params_line_count[3].length = 1.f;
- params_line_count[4].index = 10;
- params_line_count[4].length = 0.f;
-
- if ((u = pke_test_font_inner_line_count(ft, fr, font_glyph_spacing, params_line_count, 5)), u != 0) {
- return u;
+ for (u = 0; u < 5; ++u) {
+ params[u].val = FontType_Inner_LookAheadLineCount(ft, fr, params[u].index, font_glyph_spacing);
}
+
+ PK_TEST_ASSERT_EQ_RET (1.f, params[0].val);
+ PK_TEST_ASSERT_EQ_RET (1.f, params[1].val);
+ PK_TEST_ASSERT_EQ_RET (1.f, params[2].val);
+ PK_TEST_ASSERT_EQ_RET (1.f, params[3].val);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[4].val);
}
return 0;
@@ -257,118 +241,255 @@ int pke_test_font_005() {
font_glyph_spacing = ft->spacing.em_size * fr->settings.char_scale;
+ pke_test_font_inner_func_params params[10];
+ params[0].index = 0;
+ params[1].index = 4;
+ params[2].index = 5;
+ params[3].index = 8;
+ params[4].index = 9;
+ params[5].index = 17;
+ params[6].index = 18;
+ params[7].index = 19;
+ params[8].index = 23;
+ params[9].index = 24;
+
// word length
{
- pke_test_font_inner_func_params params_word_len[10];
- params_word_len[0].index = 0;
- params_word_len[0].char_count = 4;
- params_word_len[0].length = 0.f;
- params_word_len[1].index = 4;
- params_word_len[1].char_count = 0;
- params_word_len[1].length = 1.f;
- params_word_len[2].index = 5;
- params_word_len[2].char_count = 3;
- params_word_len[2].length = 0.f;
- params_word_len[3].index = 8;
- params_word_len[3].char_count = 0;
- params_word_len[3].length = 1.f;
- params_word_len[4].index = 9;
- params_word_len[4].char_count = 8;
- params_word_len[4].length = 0.f;
- params_word_len[5].index = 17;
- params_word_len[5].char_count = 0;
- params_word_len[5].length = 1.f;
- params_word_len[6].index = 18;
- params_word_len[6].char_count = 0;
- params_word_len[6].length = 1.f;
- params_word_len[7].index = 19;
- params_word_len[7].char_count = 4;
- params_word_len[7].length = 0.f;
- params_word_len[8].index = 23;
- params_word_len[8].char_count = 0;
- params_word_len[8].length = 1.f;
- params_word_len[9].index = 24;
- params_word_len[9].char_count = 1;
- params_word_len[9].length = 0.f;
-
- if ((u = pke_test_font_inner_word_length(ft, fr, font_glyph_spacing, params_word_len, 10)), u != 0) {
- return u;
+ for (u = 0; u < 10; ++u) {
+ params[u].val = FontType_Inner_LookAheadWordLength(ft, fr, params[u].index, font_glyph_spacing, &params[u].char_count);
}
+
+ PK_TEST_ASSERT_EQ_RET (4, params[0].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[0].val);
+ PK_TEST_ASSERT_EQ_RET (0, params[1].char_count);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[1].val);
+ PK_TEST_ASSERT_EQ_RET (3, params[2].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[2].val);
+ PK_TEST_ASSERT_EQ_RET (0, params[3].char_count);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[3].val);
+ PK_TEST_ASSERT_EQ_RET (8, params[4].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[4].val);
+ PK_TEST_ASSERT_EQ_RET (0, params[5].char_count);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[5].val);
+ PK_TEST_ASSERT_EQ_RET (0, params[6].char_count);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[6].val);
+ PK_TEST_ASSERT_EQ_RET (4, params[7].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[7].val);
+ PK_TEST_ASSERT_EQ_RET (0, params[8].char_count);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[8].val);
+ PK_TEST_ASSERT_EQ_RET (1, params[9].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[9].val);
}
// line length
{
- pke_test_font_inner_func_params params_line_len[10];
- params_line_len[0].index = 0;
- params_line_len[0].char_count = 8;
- params_line_len[0].length = 0.f;
- params_line_len[1].index = 4;
- params_line_len[1].char_count = 4;
- params_line_len[1].length = 0.f;
- params_line_len[2].index = 5;
- params_line_len[2].char_count = 3;
- params_line_len[2].length = 0.f;
- params_line_len[3].index = 8;
- params_line_len[3].char_count = 0;
- params_line_len[3].length = 1.f;
- params_line_len[4].index = 9;
- params_line_len[4].char_count = 8;
- params_line_len[4].length = 0.f;
- params_line_len[5].index = 17;
- params_line_len[5].char_count = 0;
- params_line_len[5].length = 1.f;
- params_line_len[6].index = 18;
- params_line_len[6].char_count = 0;
- params_line_len[6].length = 1.f;
- params_line_len[7].index = 19;
- params_line_len[7].char_count = 6;
- params_line_len[7].length = 0.f;
- params_line_len[8].index = 23;
- params_line_len[8].char_count = 2;
- params_line_len[8].length = 0.f;
- params_line_len[9].index = 24;
- params_line_len[9].char_count = 1;
- params_line_len[9].length = 0.f;
-
- if ((u = pke_test_font_inner_line_length(ft, fr, font_glyph_spacing, params_line_len, 10)), u != 0) {
- return u;
+ for (u = 0; u < 10; ++u) {
+ params[u].val = FontType_Inner_LookAheadLineLength(ft, fr, params[u].index, font_glyph_spacing, &params[u].char_count);
}
+
+ PK_TEST_ASSERT_EQ_RET (8, params[0].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[0].val);
+ PK_TEST_ASSERT_EQ_RET (4, params[1].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[1].val);
+ PK_TEST_ASSERT_EQ_RET (3, params[2].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[2].val);
+ PK_TEST_ASSERT_EQ_RET (0, params[3].char_count);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[3].val);
+ PK_TEST_ASSERT_EQ_RET (8, params[4].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[4].val);
+ PK_TEST_ASSERT_EQ_RET (0, params[5].char_count);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[5].val);
+ PK_TEST_ASSERT_EQ_RET (0, params[6].char_count);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[6].val);
+ PK_TEST_ASSERT_EQ_RET (6, params[7].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[7].val);
+ PK_TEST_ASSERT_EQ_RET (2, params[8].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[8].val);
+ PK_TEST_ASSERT_EQ_RET (1, params[9].char_count);
+ PK_TEST_ASSERT_NEQ_RET(0.f, params[9].val);
}
// line count
{
- pke_test_font_inner_func_params params_line_count[10];
- params_line_count[0].index = 0;
- params_line_count[0].length = 3.f;
- params_line_count[1].index = 4;
- params_line_count[1].length = 3.f;
- params_line_count[2].index = 5;
- params_line_count[2].length = 3.f;
- params_line_count[3].index = 8;
- params_line_count[3].length = 3.f;
- params_line_count[4].index = 9;
- params_line_count[4].length = 2.f;
- params_line_count[5].index = 17;
- params_line_count[5].length = 2.f;
- params_line_count[6].index = 18;
- params_line_count[6].length = 2.f;
- params_line_count[7].index = 19;
- params_line_count[7].length = 1.f;
- params_line_count[8].index = 23;
- params_line_count[8].length = 1.f;
- params_line_count[9].index = 24;
- params_line_count[9].length = 1.f;
-
- if ((u = pke_test_font_inner_line_count(ft, fr, font_glyph_spacing, params_line_count, 10)), u != 0) {
- return u;
+ for (u = 0; u < 10; ++u) {
+ params[u].val = FontType_Inner_LookAheadLineCount(ft, fr, params[u].index, font_glyph_spacing);
}
+
+ PK_TEST_ASSERT_EQ_RET (3.f, params[0].val);
+ PK_TEST_ASSERT_EQ_RET (3.f, params[1].val);
+ PK_TEST_ASSERT_EQ_RET (3.f, params[2].val);
+ PK_TEST_ASSERT_EQ_RET (3.f, params[3].val);
+ PK_TEST_ASSERT_EQ_RET (2.f, params[4].val);
+ PK_TEST_ASSERT_EQ_RET (2.f, params[5].val);
+ PK_TEST_ASSERT_EQ_RET (2.f, params[6].val);
+ PK_TEST_ASSERT_EQ_RET (1.f, params[7].val);
+ PK_TEST_ASSERT_EQ_RET (1.f, params[8].val);
+ PK_TEST_ASSERT_EQ_RET (1.f, params[9].val);
+ }
+
+ return 0;
+}
+
+int pke_test_font_006() {
+ FontTypeHandle fti{};
+ FontTypeRender handle_001{};
+ FontType *ft;
+ FontRender *fr;
+ FontRenderSettings frs{};
+ uint32_t u;
+ float font_glyph_spacing;
+ const char *str = "cowabungalong\ttest";
+
+ frs.char_scale = 10;
+ frs.surface_area_size = glm::vec2(300, 300);
+
+ handle_001 = FontType_AddStringRender(fti, std::move(cstring_to_pk_cstr(str)), &frs);
+
+ FontType_Tick(0.f);
+
+ ft = FontType_Get(fti);
+ fr = FontType_GetFontRender(handle_001);
+
+ PK_TEST_ASSERT_EQ_RET(18, fr->n_glyphs);
+
+ font_glyph_spacing = ft->spacing.em_size * fr->settings.char_scale;
+
+ pke_test_font_inner_func_params params[3];
+ params[0].index = 0;
+ params[1].index = 13;
+ params[2].index = 14;
+
+ // word length
+ {
+ for (u = 0; u < 3; ++u) {
+ params[u].val = FontType_Inner_LookAheadWordLength(ft, fr, params[u].index, font_glyph_spacing, &params[u].char_count);
+ }
+
+ PK_TEST_ASSERT_EQ_RET (13, params[0].char_count);
+ PK_TEST_ASSERT_EQ_RET (75.f, params[0].val);
+ PK_TEST_ASSERT_EQ_RET (0, params[1].char_count);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[1].val);
+ PK_TEST_ASSERT_EQ_RET (4, params[2].char_count);
+ PK_TEST_ASSERT_EQ_RET (21.25f, params[2].val);
+ }
+
+ // line length
+ {
+ for (u = 0; u < 3; ++u) {
+ params[u].val = FontType_Inner_LookAheadLineLength(ft, fr, params[u].index, font_glyph_spacing, &params[u].char_count);
+ }
+
+ PK_TEST_ASSERT_EQ_RET (18, params[0].char_count);
+ PK_TEST_ASSERT_EQ_RET (11527.f, floor((double)params[0].val * 100));
+ PK_TEST_ASSERT_EQ_RET (5, params[1].char_count);
+ PK_TEST_ASSERT_EQ_RET (402777.f, floor((double)params[1].val * 10000));
+ PK_TEST_ASSERT_EQ_RET (4, params[2].char_count);
+ PK_TEST_ASSERT_EQ_RET (202777.f, floor((double)params[2].val * 10000));
+ }
+
+ // line count
+ {
+ for (u = 0; u < 3; ++u) {
+ params[u].val = FontType_Inner_LookAheadLineCount(ft, fr, params[u].index, font_glyph_spacing);
+ }
+
+ PK_TEST_ASSERT_EQ_RET (1.f, params[0].val);
+ PK_TEST_ASSERT_EQ_RET (1.f, params[1].val);
+ PK_TEST_ASSERT_EQ_RET (1.f, params[2].val);
+ }
+
+ return 0;
+}
+
+int pke_test_font_007() {
+ FontTypeHandle fti{};
+ FontTypeRender handle_001{};
+ FontType *ft;
+ FontRender *fr;
+ FontRenderSettings frs{};
+ uint32_t u;
+ float font_glyph_spacing;
+ pke_test_font_inner_func_params params[3];
+ params[0].index = 0;
+ params[1].index = 13;
+ params[2].index = 14;
+ const char *str = "cowabungalong\ttest";
+
+ frs.char_scale = 10;
+ frs.surface_area_size = glm::vec2(75, 300);
+ 1 = 0; // TODO
+ // there's something wrong with wrapping.
+ // The issue is that the first line doesn't re-center when the line wraps,
+ // but only for like one pixel.
+ // It's possible the "inner" funcs are correct and the error is happening in
+ // the logic that writes the fibis.
+ // The fact it's a 1-pixel error makes me think it's a `<` vs `<=` thing, but
+ // it isn't jumping out at me. - Perhaps a different "off-by-one" scenario.
+ // I may need to refactor the font logic that builds fibis to happen in a
+ // separate function so that I can add it to the asserts here in the tests.
+ // I should also consider refactoring the "inner" funcs to just write the
+ // fibis as we go (sans centering). I would need to track:
+ // - index of where new lines start
+ // - line length of each line for centering (do not write to fibi)
+ // - would need to loop a second time to add centering padding
+ // I should wait on this until I do the first refactor, so I can test for
+ // accuracy as I make the changes.
+
+ handle_001 = FontType_AddStringRender(fti, std::move(cstring_to_pk_cstr(str)), &frs);
+
+ FontType_Tick(0.f);
+
+ ft = FontType_Get(fti);
+ fr = FontType_GetFontRender(handle_001);
+
+ PK_TEST_ASSERT_EQ_RET(18, fr->n_glyphs);
+
+ font_glyph_spacing = ft->spacing.em_size * fr->settings.char_scale;
+
+ // word length
+ {
+ for (u = 0; u < 3; ++u) {
+ params[u].val = FontType_Inner_LookAheadWordLength(ft, fr, params[u].index, font_glyph_spacing, &params[u].char_count);
+ }
+
+ PK_TEST_ASSERT_EQ_RET (13, params[0].char_count);
+ PK_TEST_ASSERT_EQ_RET (75.f, params[0].val);
+ PK_TEST_ASSERT_EQ_RET (0, params[1].char_count);
+ PK_TEST_ASSERT_EQ_RET (0.f, params[1].val);
+ PK_TEST_ASSERT_EQ_RET (4, params[2].char_count);
+ PK_TEST_ASSERT_EQ_RET (21.25f, params[2].val);
+ }
+
+ // line length
+ {
+ for (u = 0; u < 3; ++u) {
+ params[u].val = FontType_Inner_LookAheadLineLength(ft, fr, params[u].index, font_glyph_spacing, &params[u].char_count);
+ }
+
+ PK_TEST_ASSERT_EQ_RET (13, params[0].char_count);
+ PK_TEST_ASSERT_EQ_RET (7402.f, floor((double)params[0].val * 100));
+ PK_TEST_ASSERT_EQ_RET (5, params[1].char_count);
+ PK_TEST_ASSERT_EQ_RET (402777.f, floor((double)params[1].val * 10000));
+ PK_TEST_ASSERT_EQ_RET (4, params[2].char_count);
+ PK_TEST_ASSERT_EQ_RET (202777.f, floor((double)params[2].val * 10000));
+ }
+
+ // line count
+ {
+ for (u = 0; u < 3; ++u) {
+ params[u].val = FontType_Inner_LookAheadLineCount(ft, fr, params[u].index, font_glyph_spacing);
+ }
+
+ PK_TEST_ASSERT_EQ_RET (2.f, params[0].val);
+ PK_TEST_ASSERT_EQ_RET (1.f, params[1].val);
+ PK_TEST_ASSERT_EQ_RET (1.f, params[2].val);
}
return 0;
}
struct pk_test_group *pke_test_font_get_group() {
- static const uint64_t test_count = 5;
+ static const uint64_t test_count = 7;
static struct pk_test tests[test_count] = {
{
.title = "test 001",
@@ -395,6 +516,16 @@ struct pk_test_group *pke_test_font_get_group() {
.func = pke_test_font_005,
.expected_result = 0,
},
+ {
+ .title = "test 006",
+ .func = pke_test_font_006,
+ .expected_result = 0,
+ },
+ {
+ .title = "test 007",
+ .func = pke_test_font_007,
+ .expected_result = 0,
+ },
};
static struct pk_test_group group = {};
group.title = "font test";