2 * Acess GUI (AxWin) Version 2
3 * By John Hodge (thePowersGang)
7 typedef struct sGlyph {
13 // Effective dimensions (distance to move 'cursor')
17 // Distance from the current cursor position to render at
21 // True dimensions (size of the bitmap
34 tGlyph *AsciiGlyphs[128]; // Glyphs 0-127
39 tGlyph *(*CacheGlyph)(struct sFont *this, uint32_t Codepoint);
45 int Video_DrawText(short X, short Y, short W, short H, tFont *Font, uint32_t Color, char *Text);
46 tGlyph *_GetGlyph(tFont *Font, uint32_t Codepoint);
47 void _RenderGlyph(short X, short Y, tGlyph *Glyph, uint32_t Color);
48 tGlyph *_SystemFont_CacheGlyph(tFont *Font, uint32_t Codepoint);
49 int ReadUTF8(char *Input, uint32_t *Output);
53 CacheGlyph: _SystemFont_CacheGlyph
58 * \brief Draw text to the screen
60 int Video_DrawText(short X, short Y, short W, short H, tFont *Font, uint32_t Color, char *Text)
66 _SysDebug("Video_DrawText: (X=%i,Y=%i,W=%i,H=%i,Font=%p,Color=%08x,Text='%s')",
67 X, Y, W, H, Font, Color, Text);
70 if(W < 0 || X < 0 || X >= giScreenWidth) return 0;
71 if(X + W > giScreenWidth) W = giScreenWidth - X;
73 if(H < 0 || Y < 0 || Y >= giScreenHeight) return 0;
74 if(Y + H > giScreenHeight) H = giScreenHeight - Y;
76 // Handle NULL font (system default monospace)
77 if( !Font ) Font = &gSystemFont;
82 Text += ReadUTF8(Text, &ch);
84 // Find (or load) the glyph
85 glyph = _GetGlyph(Font, ch);
86 if( !glyph ) continue ; // If not found, just don't render it
88 // End render if it will overflow the perscribed range
89 if( xOfs + glyph->TrueWidth > W )
93 _RenderGlyph(X + xOfs, Y, glyph, Color);
99 tGlyph *_GetGlyph(tFont *Font, uint32_t Codepoint)
101 tGlyph *next = NULL, *prev = NULL;
105 if( Codepoint < 128 )
107 if( Font->AsciiGlyphs[Codepoint] == NULL ) {
108 Font->CacheGlyph(Font, Codepoint);
111 return Font->AsciiGlyphs[Codepoint];
114 // If within the range
115 if( Font->FirstGlyph && Font->FirstGlyph->Codepoint < Codepoint && Codepoint < Font->LastGlyph->Codepoint )
117 // Find what end is "closest"
118 if( Codepoint - Font->FirstGlyph->Codepoint < Font->LastGlyph->Codepoint - Codepoint )
120 // Start from the bottom
121 for( next = Font->FirstGlyph;
122 next && next->Codepoint < Codepoint;
123 prev = next, next = next->Next
126 if( next->Codepoint == Codepoint )
133 // NOTE: The roles of next and prev are reversed here to allow
134 // the insert to be able to assume that `prev` is the
135 // previous entry, and `next` is the next.
136 for( prev = Font->LastGlyph;
137 prev && prev->Codepoint > Codepoint;
138 next = prev, prev = prev->Prev
140 if( prev->Codepoint == Codepoint )
147 if( !Font->FirstGlyph || Font->FirstGlyph->Codepoint > Codepoint ) {
149 next = Font->FirstGlyph;
153 prev = Font->LastGlyph;
159 new = Font->CacheGlyph(Font, Codepoint);
160 if( !new ) return NULL;
165 new->Next = prev->Next;
169 new->Next = Font->FirstGlyph;
170 Font->FirstGlyph = new;
175 new->Prev = next->Prev;
179 new->Prev = Font->LastGlyph;
180 Font->LastGlyph = new;
189 void _RenderGlyph(short X, short Y, tGlyph *Glyph, uint32_t Color)
194 // Load system font (8x16 monospace)
195 #include "font_8x16.h"
199 tGlyph *_SystemFont_CacheGlyph(tFont *Font, uint32_t Codepoint)
205 if( Codepoint < 128 ) {
209 index = '?'; // Unknowns come out as a question mark
212 ret = malloc( sizeof(tGlyph) + FONT_WIDTH*FONT_HEIGHT );
214 ret->Width = FONT_WIDTH;
215 ret->Height = FONT_HEIGHT;
217 ret->TrueWidth = FONT_WIDTH;
218 ret->TrueHeight = FONT_HEIGHT;
223 for( i = 0; i < FONT_HEIGHT; i ++ )
225 ret->Bitmap[ i * 8 + 0 ] = VTermFont[index] & (1 << 0) ? 255 : 0;
226 ret->Bitmap[ i * 8 + 1 ] = VTermFont[index] & (1 << 1) ? 255 : 0;
227 ret->Bitmap[ i * 8 + 2 ] = VTermFont[index] & (1 << 2) ? 255 : 0;
228 ret->Bitmap[ i * 8 + 3 ] = VTermFont[index] & (1 << 3) ? 255 : 0;
229 ret->Bitmap[ i * 8 + 4 ] = VTermFont[index] & (1 << 4) ? 255 : 0;
230 ret->Bitmap[ i * 8 + 5 ] = VTermFont[index] & (1 << 5) ? 255 : 0;
231 ret->Bitmap[ i * 8 + 6 ] = VTermFont[index] & (1 << 6) ? 255 : 0;
232 ret->Bitmap[ i * 8 + 7 ] = VTermFont[index] & (1 << 7) ? 255 : 0;
240 * \fn int ReadUTF8(char *Input, uint32_t *Val)
241 * \brief Read a UTF-8 character from a string
243 int ReadUTF8(char *Input, uint32_t *Val)
245 uint8_t *str = (uint8_t *)Input;
246 *Val = 0xFFFD; // Assume invalid character
249 if( !(*str & 0x80) ) {
254 // Middle of a sequence
255 if( (*str & 0xC0) == 0x80 ) {
260 if( (*str & 0xE0) == 0xC0 ) {
261 *Val = (*str & 0x1F) << 6; // Upper 6 Bits
263 if( (*str & 0xC0) != 0x80) return -1; // Validity check
264 *Val |= (*str & 0x3F); // Lower 6 Bits
269 if( (*str & 0xF0) == 0xE0 ) {
270 *Val = (*str & 0x0F) << 12; // Upper 4 Bits
272 if( (*str & 0xC0) != 0x80) return -1; // Validity check
273 *Val |= (*str & 0x3F) << 6; // Middle 6 Bits
275 if( (*str & 0xC0) != 0x80) return -1; // Validity check
276 *Val |= (*str & 0x3F); // Lower 6 Bits
281 if( (*str & 0xF1) == 0xF0 ) {
282 *Val = (*str & 0x07) << 18; // Upper 3 Bits
284 if( (*str & 0xC0) != 0x80) return -1; // Validity check
285 *Val |= (*str & 0x3F) << 12; // Middle-upper 6 Bits
287 if( (*str & 0xC0) != 0x80) return -1; // Validity check
288 *Val |= (*str & 0x3F) << 6; // Middle-lower 6 Bits
290 if( (*str & 0xC0) != 0x80) return -1; // Validity check
291 *Val |= (*str & 0x3F); // Lower 6 Bits
295 // UTF-8 Doesn't support more than four bytes