diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-12-01 16:59:40 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-12-01 16:59:40 -0500 |
| commit | b86dfd9db0bf04807458388cb3b86c317f912cb2 (patch) | |
| tree | 0ad09c2b92f455e6876b26977daa9d1719291238 | |
| parent | 89b0e2f2133f9889d8ee51c29f34d16ddc1c4400 (diff) | |
pke: font centering tweaks handling char padding
| -rw-r--r-- | src/font.cpp | 57 |
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 |
