diff --git a/System/Utilities/TrueType.HC b/System/Utilities/TrueType.HC index 9185ae9..2dc75da 100644 --- a/System/Utilities/TrueType.HC +++ b/System/Utilities/TrueType.HC @@ -50,6 +50,19 @@ U8* @stbtt_RenderText(stbtt_fontinfo* info, I32 b_w, I32 b_h, I32 l_h, I32* word } } +I32 @stbtt_GetTextWidth(stbtt_fontinfo* info, I32 l_h, I32* word, I32* advance = NULL) +{ + U64 reg RDI rdi = info; + U64 reg RSI rsi = l_h; + U64 reg RDX rdx = word; + U64 reg RCX rcx = advance; + no_warn rdi, rsi, rdx, rcx; + asm { + MOV RAX, STBTT_GETTEXTWIDTH + CALL RAX + } +} + U8* @stbtt_GetFontNameDefault(stbtt_fontinfo* font, I32* length) { U64 reg RDI rdi = font; diff --git a/scripts/build-all b/scripts/build-all index 22f0a82..66d6f26 100755 --- a/scripts/build-all +++ b/scripts/build-all @@ -209,6 +209,7 @@ def generate_iso_c_file(): truetype_hc_fixup('STBTT_INITFONT', 'stbtt_InitFont', truetype_bin_path, truetype_hc_path) truetype_hc_fixup('STBTT_RENDERTEXT', 'stbtt_RenderText', truetype_bin_path, truetype_hc_path) + truetype_hc_fixup('STBTT_GETTEXTWIDTH', 'stbtt_GetTextWidth', truetype_bin_path, truetype_hc_path) truetype_hc_fixup('STBTT_GETFONTNAMEDEFAULT', 'stbtt_GetFontNameDefault', truetype_bin_path, truetype_hc_path) # Fixup addresses for Tlse.HC diff --git a/src/truetype/truetype.c b/src/truetype/truetype.c index 964c118..dc58bc8 100644 --- a/src/truetype/truetype.c +++ b/src/truetype/truetype.c @@ -55,4 +55,52 @@ unsigned char* stbtt_RenderText(stbtt_fontinfo* info, int b_w, int b_h, int l_h, return bitmap; } +int stbtt_GetTextWidth(stbtt_fontinfo* info, int l_h, int* word, int* advance) +{ + // https://github.com/justinmeiners/stb-truetype-example + + /* calculate font scaling */ + float scale = stbtt_ScaleForPixelHeight(info, l_h); + + int x = 0; + + int ascent, descent, lineGap; + stbtt_GetFontVMetrics(info, &ascent, &descent, &lineGap); + + ascent = roundf(ascent * scale); + descent = roundf(descent * scale); + + int i = 0; + while (word[i]) { + /* how wide is this character */ + int ax; + int lsb; + stbtt_GetCodepointHMetrics(info, word[i], &ax, &lsb); + /* (Note that each Codepoint call has an alternative Glyph version which caches the work required to lookup the character word[i].) */ + + /* get bounding box for character (may be offset to account for chars that dip above or below the line) */ + int c_x1, c_y1, c_x2, c_y2; + stbtt_GetCodepointBitmapBox(info, word[i], scale, scale, &c_x1, &c_y1, &c_x2, &c_y2); + + /* compute y (different characters have different heights) */ + int y = ascent + c_y1; + + /* advance x */ + x += roundf(ax * scale); + + /* add kerning */ + int kern; + kern = stbtt_GetCodepointKernAdvance(info, word[i], word[i + 1]); + x += roundf(kern * scale); + + if (advance) { + advance[i] = x; + } + + ++i; + } + + return x; +} + int main() { return 0; }