X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=Usermode%2FApplications%2Faxwin3_src%2FWM%2Fwm_render_text.c;h=01b82ff8307fc28445bd9b7c1a996fcc9a7d2948;hb=4696a38ba9ea5798e67ccd475c8b77f318db133d;hp=4ce35cb7df8b0547dd7494ad5c6358f6786320b1;hpb=cee7338738f1a68c7eb7b956cab8d9fb83f95714;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin3_src/WM/wm_render_text.c b/Usermode/Applications/axwin3_src/WM/wm_render_text.c index 4ce35cb7..01b82ff8 100644 --- a/Usermode/Applications/axwin3_src/WM/wm_render_text.c +++ b/Usermode/Applications/axwin3_src/WM/wm_render_text.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include // INT_MAX // === TYPES === typedef struct sGlyph tGlyph; @@ -51,12 +53,11 @@ struct sFont // === PROTOTYPES === - int WM_Render_DrawText(tWindow *Window, int X, int Y, int W, int H, tFont *Font, tColour Color, const char *Text); -void WM_Render_GetTextDims(tFont *Font, const char *Text, int *W, int *H); + int WM_Render_DrawText(tWindow *Window, int X, int Y, int W, int H, tFont *Font, tColour Color, const char *Text, int MaxLen); +void WM_Render_GetTextDims(tFont *Font, const char *Text, int MaxLen, int *W, int *H); tGlyph *_GetGlyph(tFont *Font, uint32_t Codepoint); -void _RenderGlyph(tWindow *Window, short X, short Y, tGlyph *Glyph, uint32_t Color); +void _RenderGlyph(tWindow *Window, short X, short Y, short ClipW, short ClipH, tGlyph *Glyph, uint32_t Color); tGlyph *_SystemFont_CacheGlyph(tFont *Font, uint32_t Codepoint); - int ReadUTF8(const char *Input, uint32_t *Output); // === GLOBALS === tFont gSystemFont = { @@ -67,7 +68,7 @@ tFont gSystemFont = { /** * \brief Draw text to the screen */ -int WM_Render_DrawText(tWindow *Window, int X, int Y, int W, int H, tFont *Font, tColour Colour, const char *Text) +int WM_Render_DrawText(tWindow *Window, int X, int Y, int W, int H, tFont *Font, tColour Colour, const char *Text, int MaxLen) { int xOfs = 0; tGlyph *glyph; @@ -78,6 +79,7 @@ int WM_Render_DrawText(tWindow *Window, int X, int Y, int W, int H, tFont *Font, if(!Text) return 0; + if(MaxLen < 0) MaxLen = INT_MAX; X += Window->BorderL; Y += Window->BorderT; @@ -94,36 +96,44 @@ int WM_Render_DrawText(tWindow *Window, int X, int Y, int W, int H, tFont *Font, // Handle NULL font (system default monospace) if( !Font ) Font = &gSystemFont; - while( *Text ) + while( MaxLen > 0 && *Text ) { + int len; // Read character - Text += ReadUTF8(Text, &ch); + len = ReadUTF8(Text, &ch); + Text += len; + MaxLen -= len; // Find (or load) the glyph glyph = _GetGlyph(Font, ch); if( !glyph ) continue ; // If not found, just don't render it - // End render if it will overflow the provided range - if( xOfs + glyph->TrueWidth > W ) + // End render if it will not fit at all + if( xOfs >= W ) break; - _RenderGlyph(Window, X + xOfs, Y, glyph, Colour); + _RenderGlyph(Window, X + xOfs, Y, W-xOfs, H, glyph, Colour); xOfs += glyph->Width; } return xOfs; } -void WM_Render_GetTextDims(tFont *Font, const char *Text, int *W, int *H) +void WM_Render_GetTextDims(tFont *Font, const char *Text, int MaxLen, int *W, int *H) { int w=0, h=0; uint32_t ch; tGlyph *glyph; if( !Font ) Font = &gSystemFont; - while( *Text ) + if(MaxLen < 0) MaxLen = INT_MAX; + + while( MaxLen > 0 && *Text ) { - Text += ReadUTF8(Text, &ch); + int len; + len = ReadUTF8(Text, &ch); + Text += len; + MaxLen -= len; glyph = _GetGlyph(Font, ch); if( !glyph ) continue; @@ -162,7 +172,7 @@ tGlyph *_GetGlyph(tFont *Font, uint32_t Codepoint) prev = next, next = next->Next ); - if( next->Codepoint == Codepoint ) + if( next && next->Codepoint == Codepoint ) return next; } @@ -176,7 +186,7 @@ tGlyph *_GetGlyph(tFont *Font, uint32_t Codepoint) prev && prev->Codepoint > Codepoint; next = prev, prev = prev->Prev ); - if( prev->Codepoint == Codepoint ) + if( prev && prev->Codepoint == Codepoint ) return prev; } } @@ -225,7 +235,7 @@ tGlyph *_GetGlyph(tFont *Font, uint32_t Codepoint) /** */ -void _RenderGlyph(tWindow *Window, short X, short Y, tGlyph *Glyph, uint32_t Color) +void _RenderGlyph(tWindow *Window, short X, short Y, short ClipW, short ClipH, tGlyph *Glyph, uint32_t Color) { int xStart = 0, yStart = 0; int x, y, dst_x; @@ -248,9 +258,9 @@ void _RenderGlyph(tWindow *Window, short X, short Y, tGlyph *Glyph, uint32_t Col outBuf = (uint32_t*)Window->RenderBuffer + Y*Window->RealW + X; inBuf = Glyph->Bitmap + yStart*Glyph->TrueWidth; - for( y = yStart; y < Glyph->TrueHeight; y ++ ) + for( y = yStart; y < Glyph->TrueHeight && ClipH--; y ++ ) { - for( x = xStart, dst_x = 0; x < Glyph->TrueWidth; x ++, dst_x ++ ) + for( x = xStart, dst_x = 0; x < Glyph->TrueWidth && dst_x < ClipW; x ++, dst_x ++ ) { outBuf[dst_x] = Video_AlphaBlend( outBuf[dst_x], Color, inBuf[x] ); } @@ -316,67 +326,3 @@ tGlyph *_SystemFont_CacheGlyph(tFont *Font, uint32_t Codepoint) return ret; } - -/** - * \fn int ReadUTF8(char *Input, uint32_t *Val) - * \brief Read a UTF-8 character from a string - */ -int ReadUTF8(const char *Input, uint32_t *Val) -{ - const uint8_t *str = (const uint8_t *)Input; - *Val = 0xFFFD; // Assume invalid character - - // ASCII - if( !(*str & 0x80) ) { - *Val = *str; - return 1; - } - - // Middle of a sequence - if( (*str & 0xC0) == 0x80 ) { - return 1; - } - - // Two Byte - if( (*str & 0xE0) == 0xC0 ) { - *Val = (*str & 0x1F) << 6; // Upper 6 Bits - str ++; - if( (*str & 0xC0) != 0x80) return -1; // Validity check - *Val |= (*str & 0x3F); // Lower 6 Bits - return 2; - } - - // Three Byte - if( (*str & 0xF0) == 0xE0 ) { - *Val = (*str & 0x0F) << 12; // Upper 4 Bits - str ++; - if( (*str & 0xC0) != 0x80) return -1; // Validity check - *Val |= (*str & 0x3F) << 6; // Middle 6 Bits - str ++; - if( (*str & 0xC0) != 0x80) return -1; // Validity check - *Val |= (*str & 0x3F); // Lower 6 Bits - return 3; - } - - // Four Byte - if( (*str & 0xF1) == 0xF0 ) { - *Val = (*str & 0x07) << 18; // Upper 3 Bits - str ++; - if( (*str & 0xC0) != 0x80) return -1; // Validity check - *Val |= (*str & 0x3F) << 12; // Middle-upper 6 Bits - str ++; - if( (*str & 0xC0) != 0x80) return -1; // Validity check - *Val |= (*str & 0x3F) << 6; // Middle-lower 6 Bits - str ++; - if( (*str & 0xC0) != 0x80) return -1; // Validity check - *Val |= (*str & 0x3F); // Lower 6 Bits - return 4; - } - - // UTF-8 Doesn't support more than four bytes - return 4; -} - - - -