summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-12-01 16:59:40 -0500
committerJonathan Bradley <jcb@pikum.xyz>2025-12-01 16:59:40 -0500
commitb86dfd9db0bf04807458388cb3b86c317f912cb2 (patch)
tree0ad09c2b92f455e6876b26977daa9d1719291238
parent89b0e2f2133f9889d8ee51c29f34d16ddc1c4400 (diff)
pke: font centering tweaks handling char padding
-rw-r--r--src/font.cpp57
1 files changed, 53 insertions, 4 deletions
diff --git a/src/font.cpp b/src/font.cpp
index d368b5a..2296466 100644
--- a/src/font.cpp
+++ b/src/font.cpp
@@ -112,10 +112,43 @@ float FontType_Inner_LookAheadWordLength(const FontType *const ft, const FontRen
return ret;
}
+float FontType_Inner_LookAheadWordLength_NoPadding(const FontType *const ft, const FontRender *const fr, uint32_t index, float font_glyph_spacing, uint32_t *char_count = nullptr) {
+ uint32_t i;
+ float ret = 0;
+ FontGlyphChar *fgc;
+ for (i = index; i < fr->n_glyphs; ++i) {
+ fgc = &ft->glyphs[fr->glyph_indices[i]];
+ if (PK_HAS_FLAG(fgc->flags, FONT_GLYPH_CHAR_FLAGS_WHITESPACE) == true) {
+ break;
+ }
+ if (PK_HAS_FLAG(fgc->flags, FONT_GLYPH_CHAR_FLAGS_NEW_LINE) == true) {
+ break;
+ }
+ ret += fgc->advance * font_glyph_spacing;
+ if (i == index) {
+ // if -x, makes word larger
+ // if +x, makes word shorter
+ ret -= fgc->plane_bounds.x * font_glyph_spacing;
+ }
+ }
+ if (i != index) {
+ fgc = &ft->glyphs[fr->glyph_indices[i-1]];
+ ret -= (fgc->advance - fgc->plane_bounds.z) * font_glyph_spacing;
+ }
+ if (char_count != nullptr) {
+ *char_count = i - index;
+ }
+ return ret;
+}
+
float FontType_Inner_LookAheadLineLength(const FontType *const ft, const FontRender *const fr, const uint32_t index, float font_glyph_spacing, uint32_t *char_count = nullptr) {
uint32_t i, ii;
float sz, ret = 0;
+ bool front_whitespace = true;
FontGlyphChar *fgc, *fgc2;
+ // When centering, we want to burn white-space characters:
+ // at the front.
+ // at the back.
for (i = index; i < fr->n_glyphs; ++i) {
fgc = &ft->glyphs[fr->glyph_indices[i]];
if (PK_HAS_FLAG(fgc->flags, FONT_GLYPH_CHAR_FLAGS_NEW_LINE) == true) {
@@ -127,16 +160,18 @@ float FontType_Inner_LookAheadLineLength(const FontType *const ft, const FontRen
}
break;
}
- // 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) {
+ if (front_whitespace == true && PK_HAS_FLAG(fr->settings.surface_area_type_flags, FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_CENTER_HORIZONTAL)) {
+ // burn white-spacing at the front
+ continue;
+ }
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) {
+ if (index != 0) {
fgc2 = &ft->glyphs[fr->glyph_indices[i-1]];
if (!PK_HAS_FLAG(fgc2->flags, FONT_GLYPH_CHAR_FLAGS_NEW_LINE)) {
fgc2 = nullptr;
@@ -156,6 +191,12 @@ float FontType_Inner_LookAheadLineLength(const FontType *const ft, const FontRen
// On the last word, not subtracting 1 causes the char_count to be off-by-one
i += ii-1;
ret += sz;
+ if (front_whitespace == true) {
+ // if -x, makes line larger
+ // if +x, makes line shorter
+ ret -= fgc->plane_bounds.x * font_glyph_spacing;
+ }
+ front_whitespace = false;
}
// If we are at the end of a line:
// Burn all white-space until we have a non-white-space
@@ -168,7 +209,8 @@ float FontType_Inner_LookAheadLineLength(const FontType *const ft, const FontRen
ii += 1;
continue;
}
- ret += (fgc->plane_bounds.z - fgc->plane_bounds.x) * font_glyph_spacing;
+ // literal right edge of the char
+ ret += fgc->plane_bounds.z * font_glyph_spacing;
break;
}
if (char_count != nullptr) {
@@ -316,6 +358,9 @@ bool FontType_Inner_CalcTransforms(const FontType *ft, FontRender *fr, FontInsta
cursor_head = (fr->settings.surface_area_size.x - line_length) / 2.0;
}
}
+ if (first_word_of_line == true) {
+ cursor_head -= fgc->plane_bounds.x * font_glyph_spacing;
+ }
}
first_word_of_line = false;
new_word = false;
@@ -332,6 +377,10 @@ bool FontType_Inner_CalcTransforms(const FontType *ft, FontRender *fr, FontInsta
scale *= glm::vec3(glyph_size.x / (float)Extent.width, glyph_size.y / (float)Extent.height, 1.0);
// move to appropriate position + char placement
+ // Reminder that we are converting -1,1 positioning to screen-space.
+ // This means that we have to shift by half the width and half the height
+ // in order to position the box correctly (glyph_size).
+ // ; Without this, the character would be OOB on the left and/or top.
// ((val) - (width/2)) / (width/2)
// box position