summaryrefslogtreecommitdiff
path: root/src/font.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/font.cpp')
-rw-r--r--src/font.cpp78
1 files changed, 75 insertions, 3 deletions
diff --git a/src/font.cpp b/src/font.cpp
index 3dba635..3204f58 100644
--- a/src/font.cpp
+++ b/src/font.cpp
@@ -108,6 +108,47 @@ float FontType_Inner_LookAheadWordLength(const FontType *const ft, const FontRen
return ret;
}
+float FontType_Inner_LookAheadLineLength(const FontType *const ft, const FontRender *const fr, uint32_t index, float font_glyph_spacing) {
+ 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_NEW_LINE) == true) {
+ break;
+ }
+ if (ret + (fgc->advance * font_glyph_spacing) > fr->settings.surface_area_size.x) {
+ break;
+ }
+ ret += fgc->advance * font_glyph_spacing;
+ }
+ return ret;
+}
+
+float FontType_Inner_LookAheadLineCount(const FontType *const ft, const FontRender *const fr, const uint32_t index) {
+ uint32_t i, u;
+ float ret = 1;
+ 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_NEW_LINE) == true) {
+ if (i+1 < fr->n_glyphs) {
+ if (fgc->unicode == 10) {
+ u = 11;
+ } else {
+ u = 10;
+ }
+ // handle \r\n
+ if (ft->glyphs[fr->glyph_indices[i+1]].unicode == u) {
+ i += 1; // burn
+ }
+ }
+ ret += 1;
+ }
+ }
+ return ret;
+}
+
void FontType_Inner_CalcTransforms(const FontType *ft, FontRender *fr, FontInstanceBufferItem *ptr_dst) {
assert(ft != nullptr);
assert(fr != nullptr);
@@ -117,7 +158,7 @@ void FontType_Inner_CalcTransforms(const FontType *ft, FontRender *fr, FontInsta
bool new_word = true;
uint32_t i;
float font_glyph_spacing;
- float cursor_head, line_index, line_height;
+ float cursor_head, line_index, line_height, line_length, line_offset;
glm::vec2 glyph_size;
glm::vec3 translate;
glm::vec3 scale;
@@ -129,12 +170,31 @@ void FontType_Inner_CalcTransforms(const FontType *ft, FontRender *fr, FontInsta
// Trying to get pixel-perfect rendering with mannequin-7.
// Everything is now sized and positioned correctly.
// However, there is a ghost layer around the letter.
+ // 2025-09-22 - JCB
+ // I believe this is because of how the anti-aliasing works.
+ // When this gets re-visited, attempt to disable anti-aliasing entirely.
+ // Suggestion: require min distance to be 0?
+ // Also note that I don't think we're doing any calculations to make sure the
+ // left-most pixel is exact to the Extent (screen size).
font_glyph_spacing = ft->spacing.em_size * fr->settings.char_scale;
cursor_head = 0;
line_index = 0;
+ line_offset = 0;
line_height = font_glyph_spacing * ft->spacing.line_height * fr->settings.line_height_scale;
+ line_length = FontType_Inner_LookAheadLineLength(ft, fr, 0, font_glyph_spacing);
+ if (PK_HAS_FLAG(fr->settings.surface_area_type_flags, FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_CENTER_HORIZONTAL)) {
+ 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;
+ }
+
for (i = 0; i < fr->n_glyphs; ++i) {
translate = glm::vec3(0);
scale = glm::vec3(1);
@@ -149,7 +209,12 @@ void FontType_Inner_CalcTransforms(const FontType *ft, FontRender *fr, FontInsta
}
}
line_index += 1;
- cursor_head = 0;
+ line_length = FontType_Inner_LookAheadLineLength(ft, fr, i+1, font_glyph_spacing);
+ if (PK_HAS_FLAG(fr->settings.surface_area_type_flags, FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_CENTER_HORIZONTAL)) {
+ cursor_head = (fr->settings.surface_area_size.x - line_length) / 2.0;
+ } else {
+ cursor_head = 0;
+ }
continue;
}
if (PK_HAS_FLAG(fgc->flags, FONT_GLYPH_CHAR_FLAGS_WHITESPACE) == true) {
@@ -172,7 +237,13 @@ void FontType_Inner_CalcTransforms(const FontType *ft, FontRender *fr, FontInsta
float word_width = FontType_Inner_LookAheadWordLength(ft, fr, i, font_glyph_spacing);
if (cursor_head + word_width > fr->settings.surface_area_size.x) {
line_index += 1;
- cursor_head = 0;
+ line_length = FontType_Inner_LookAheadLineLength(ft, fr, i+1, font_glyph_spacing);
+
+ if (PK_HAS_FLAG(fr->settings.surface_area_type_flags, FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_CENTER_HORIZONTAL)) {
+ cursor_head = (fr->settings.surface_area_size.x - line_length) / 2.0;
+ } else {
+ cursor_head = 0;
+ }
}
new_word = false;
}
@@ -207,6 +278,7 @@ void FontType_Inner_CalcTransforms(const FontType *ft, FontRender *fr, FontInsta
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);
+ 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);
// move glyph to the height relative to the baseline (cursor)