X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin3_src%2FWM%2Fwm_render_text.c;h=8258531bcc71c5097fd56986c66c0dc680815e9d;hb=6a99a6d70179161964d47de9a825fd61e8445b86;hp=9135ed3d5d7b4f4eb040ba32bbcf412f3b7055d0;hpb=82a4f841eafaff80b7dc258099abd865faaa0467;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 9135ed3d..8258531b 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); tGlyph *_SystemFont_CacheGlyph(tFont *Font, uint32_t Codepoint); - int ReadUTF8(const char *Input, uint32_t *Output); // === GLOBALS === tFont gSystemFont = { @@ -67,31 +68,41 @@ 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; uint32_t ch = 0; - _SysDebug("WM_Render_DrawText: (X=%i,Y=%i,W=%i,H=%i,Font=%p,", X, Y, W, H, Font); - _SysDebug(" Colour=%08x,Text='%s')", Colour, Text); +// _SysDebug("WM_Render_DrawText: (X=%i,Y=%i,W=%i,H=%i,Font=%p,", X, Y, W, H, Font); +// _SysDebug(" Colour=%08x,Text='%s')", Colour, Text); if(!Text) return 0; + if(MaxLen < 0) MaxLen = INT_MAX; + + X += Window->BorderL; + Y += Window->BorderT; + // Check the bounds - if(W < 0 || X < 0 || X >= Window->W) return 0; - if(X + W > Window->W) W = Window->W - X; + if(W < 0 || X < 0 || X >= Window->RealW) return 0; + if(X + W > Window->RealW) W = Window->RealW - X; - if(H < 0 || Y < 0 || Y >= Window->H) return 0; - if(Y + H > Window->H) H = Window->H - Y; + if(H < 0 || Y < 0 || Y >= Window->RealH) return 0; + if(Y + H > Window->RealH) H = Window->RealH - Y; + // TODO: Catch trampling of decorations + // 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); @@ -108,16 +119,21 @@ int WM_Render_DrawText(tWindow *Window, int X, int Y, int W, int H, tFont *Font, 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; @@ -156,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; } @@ -170,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; } } @@ -239,7 +255,7 @@ void _RenderGlyph(tWindow *Window, short X, short Y, tGlyph *Glyph, uint32_t Col } // _SysDebug("X = %i, Y = %i", X, Y); - outBuf = (uint32_t*)Window->RenderBuffer + Y*Window->W + X; + outBuf = (uint32_t*)Window->RenderBuffer + Y*Window->RealW + X; inBuf = Glyph->Bitmap + yStart*Glyph->TrueWidth; for( y = yStart; y < Glyph->TrueHeight; y ++ ) @@ -248,7 +264,7 @@ void _RenderGlyph(tWindow *Window, short X, short Y, tGlyph *Glyph, uint32_t Col { outBuf[dst_x] = Video_AlphaBlend( outBuf[dst_x], Color, inBuf[x] ); } - outBuf += Window->W; + outBuf += Window->RealW; inBuf += Glyph->TrueWidth; } } @@ -310,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; -} - - - -