Merge branch 'master' of git://git.ucc.asn.au/tpg/acess2
[tpg/acess2.git] / Kernel / drv / vterm_font.c
1 /*
2  * Acess2 Kernel
3  * - By John Hodge (thePowersGang)
4  *
5  * drv/vterm_font.c
6  * - Virtual Terminal - Font rendering code
7  */
8 #include "vterm.h"
9 #include <api_drv_terminal.h>
10
11 // ---
12 // Font Render
13 // ---
14 #define MONOSPACE_FONT  10816
15
16 #if MONOSPACE_FONT == 10808     // 8x8
17 # include "vterm_font_8x8.h"
18 #elif MONOSPACE_FONT == 10816   // 8x16
19 # include "vterm_font_8x16.h"
20 #endif
21
22 // === PROTOTYPES ===
23 Uint8   *VT_Font_GetChar(Uint32 Codepoint);
24
25 // === GLOBALS ===
26 int     giVT_CharWidth = FONT_WIDTH;
27 int     giVT_CharHeight = FONT_HEIGHT;
28
29 // === CODE ===
30 /**
31  * \brief Render a font character
32  */
33 void VT_Font_Render(Uint32 Codepoint, void *Buffer, int Depth, int Pitch, Uint32 BGC, Uint32 FGC)
34 {
35         Uint8   *font;
36          int    x, y;
37         
38         // 8-bpp and below
39         if( Depth <= 8 )
40         {
41                 Uint8   *buf = Buffer;
42                 
43                 font = VT_Font_GetChar(Codepoint);
44                 
45                 for(y = 0; y < FONT_HEIGHT; y ++)
46                 {
47                         for(x = 0; x < FONT_WIDTH; x ++)
48                         {
49                                 if(*font & (1 << (FONT_WIDTH-x-1)))
50                                         buf[x] = FGC;
51                                 else
52                                         buf[x] = BGC;
53                         }
54                         buf = (void*)( (tVAddr)buf + Pitch );
55                         font ++;
56                 }
57         }
58         // 16-bpp and below
59         else if( Depth <= 16 )
60         {
61                 Uint16  *buf = Buffer;
62                 
63                 font = VT_Font_GetChar(Codepoint);
64                 
65                 for(y = 0; y < FONT_HEIGHT; y ++)
66                 {
67                         for(x = 0; x < FONT_WIDTH; x ++)
68                         {
69                                 if(*font & (1 << (FONT_WIDTH-x-1)))
70                                         buf[x] = FGC;
71                                 else
72                                         buf[x] = BGC;
73                         }
74                         buf = (void*)( (tVAddr)buf + Pitch );
75                         font ++;
76                 }
77         }
78         // 24-bpp colour
79         // - Special handling to not overwrite the next pixel
80         //TODO: Endian issues here
81         else if( Depth == 24 )
82         {
83                 Uint8   *buf = Buffer;
84                 Uint8   bg_r = (BGC >> 16) & 0xFF;
85                 Uint8   bg_g = (BGC >>  8) & 0xFF;
86                 Uint8   bg_b = (BGC >>  0) & 0xFF;
87                 Uint8   fg_r = (FGC >> 16) & 0xFF;
88                 Uint8   fg_g = (FGC >>  8) & 0xFF;
89                 Uint8   fg_b = (FGC >>  0) & 0xFF;
90                 
91                 font = VT_Font_GetChar(Codepoint);
92                 
93                 for(y = 0; y < FONT_HEIGHT; y ++)
94                 {
95                         for(x = 0; x < FONT_WIDTH; x ++)
96                         {
97                                 Uint8   r, g, b;
98                                 
99                                 if(*font & (1 << (FONT_WIDTH-x-1))) {
100                                         r = fg_r;       g = fg_g;       b = fg_b;
101                                 }
102                                 else {
103                                         r = bg_r;       g = bg_g;       b = bg_b;
104                                 }
105                                 buf[x*3+0] = b;
106                                 buf[x*3+1] = g;
107                                 buf[x*3+2] = r;
108                         }
109                         buf = (void*)( (tVAddr)buf + Pitch );
110                         font ++;
111                 }
112         }
113         // 32-bpp colour (nice and easy)
114         else if( Depth == 32 )
115         {
116                 Uint32  *buf = Buffer;
117                 
118                 font = VT_Font_GetChar(Codepoint);
119                 
120                 for(y = 0; y < FONT_HEIGHT; y ++)
121                 {
122                         for(x = 0; x < FONT_WIDTH; x ++)
123                         {
124                                 if(*font & (1 << (FONT_WIDTH-x-1)))
125                                         buf[x] = FGC;
126                                 else
127                                         buf[x] = BGC;
128                         }
129                         buf = (Uint32*)( (tVAddr)buf + Pitch );
130                         font ++;
131                 }
132         }
133 }
134
135 /**
136  * \fn Uint32 VT_Colour12to24(Uint16 Col12)
137  * \brief Converts a 12-bit colour into 24 bits
138  */
139 Uint32 VT_Colour12to24(Uint16 Col12)
140 {
141         Uint32  ret;
142          int    tmp;
143         tmp = Col12 & 0xF;
144         ret  = (tmp << 0) | (tmp << 4);
145         tmp = (Col12 & 0xF0) >> 4;
146         ret |= (tmp << 8) | (tmp << 12);
147         tmp = (Col12 & 0xF00) >> 8;
148         ret |= (tmp << 16) | (tmp << 20);
149         return ret;
150 }
151 /**
152  * \brief Converts a 12-bit colour into 15 bits
153  */
154 Uint16 VT_Colour12to15(Uint16 Col12)
155 {
156         Uint32  ret;
157          int    tmp;
158         tmp = Col12 & 0xF;
159         ret  = (tmp << 1) | (tmp & 1);
160         tmp = (Col12 & 0xF0) >> 4;
161         ret |= ( (tmp << 1) | (tmp & 1) ) << 5;
162         tmp = (Col12 & 0xF00) >> 8;
163         ret |= ( (tmp << 1) | (tmp & 1) ) << 10;
164         return ret;
165 }
166
167 /**
168  * \brief Converts a 12-bit colour into any other depth
169  * \param Col12 12-bit source colour
170  * \param Depth Desired bit deptj
171  * \note Green then blue get the extra avaliable bits (16:5-6-5, 14:4-5-5)
172  */
173 Uint32 VT_Colour12toN(Uint16 Col12, int Depth)
174 {
175         Uint32  ret;
176         Uint32  r, g, b;
177          int    rSize, gSize, bSize;
178         
179         // Fast returns
180         if( Depth == 24 )       return VT_Colour12to24(Col12);
181         if( Depth == 15 )       return VT_Colour12to15(Col12);
182         // - 32 is a special case, it's usually 24-bit colour with an unused byte
183         if( Depth == 32 )       return VT_Colour12to24(Col12);
184         
185         // Bounds checks
186         if( Depth < 8 ) return 0;
187         if( Depth > 32 )        return 0;
188         
189         r = Col12 & 0xF;
190         g = (Col12 & 0xF0) >> 4;
191         b = (Col12 & 0xF00) >> 8;
192         
193         rSize = gSize = bSize = Depth / 3;
194         if( rSize + gSize + bSize < Depth )     // Depth % 3 == 1
195                 gSize ++;
196         if( rSize + gSize + bSize < Depth )     // Depth % 3 == 2
197                 bSize ++;
198         
199         // Expand
200         r <<= rSize - 4;        g <<= gSize - 4;        b <<= bSize - 4;
201         // Fill with the lowest bit
202         if( Col12 & 0x001 )     r |= (1 << (rSize - 4)) - 1;
203         if( Col12 & 0x010 )     r |= (1 << (gSize - 4)) - 1;
204         if( Col12 & 0x100 )     r |= (1 << (bSize - 4)) - 1;
205         
206         // Create output
207         ret  = r;
208         ret |= g << rSize;
209         ret |= b << (rSize + gSize);
210         
211         return ret;
212 }
213
214 /**
215  * \fn Uint8 *VT_Font_GetChar(Uint32 Codepoint)
216  * \brief Gets an index into the font array given a Unicode Codepoint
217  * \note See http://en.wikipedia.org/wiki/CP437
218  */
219 Uint8 *VT_Font_GetChar(Uint32 Codepoint)
220 {
221          int    index = 0;
222         if(Codepoint < 128)
223                 return &VTermFont[Codepoint*FONT_HEIGHT];
224         switch(Codepoint)
225         {
226         case 0xC7:      index = 128;    break;  // Ç
227         case 0xFC:      index = 129;    break;  // ü
228         case 0xE9:      index = 130;    break;  // é
229         case 0xE2:      index = 131;    break;  // â
230         case 0xE4:      index = 132;    break;  // ä
231         case 0xE0:      index = 133;    break;  // à
232         case 0xE5:      index = 134;    break;  // å
233         case 0xE7:      index = 135;    break;  // ç
234         case 0xEA:      index = 136;    break;  // ê
235         case 0xEB:      index = 137;    break;  // ë
236         case 0xE8:      index = 138;    break;  // è
237         case 0xEF:      index = 139;    break;  // ï
238         case 0xEE:      index = 140;    break;  // î
239         case 0xEC:      index = 141;    break;  // ì
240         case 0xC4:      index = 142;    break;  // Ä
241         case 0xC5:      index = 143;    break;  // Å
242         }
243         
244         return &VTermFont[index*FONT_HEIGHT];
245 }
246
247 EXPORTAS(&giVT_CharWidth, giVT_CharWidth);
248 EXPORTAS(&giVT_CharHeight, giVT_CharHeight);
249 EXPORT(VT_Font_Render);
250 EXPORT(VT_Colour12to24);

UCC git Repository :: git.ucc.asn.au