Merge branch 'master' of git://git.ucc.asn.au/tpg/acess2
[tpg/acess2.git] / KernelLand / 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 Uint16 VT_Colour24to12(Uint32 Col24)
136 {
137         Uint16  ret = 0;
138         
139         for( int i = 0; i < 3; i ++ )
140         {
141                 Uint32  comp = (Col24 >> (i*8)) & 0xFF;
142                 ret |= ((comp * 15) / 255) << (i*4);
143         }
144         return ret;
145 }
146
147 /**
148  * \fn Uint32 VT_Colour12to24(Uint16 Col12)
149  * \brief Converts a 12-bit colour into 24 bits
150  */
151 Uint32 VT_Colour12to24(Uint16 Col12)
152 {
153         Uint32  ret;
154          int    tmp;
155         tmp = Col12 & 0xF;
156         ret  = (tmp << 0) | (tmp << 4);
157         tmp = (Col12 & 0xF0) >> 4;
158         ret |= (tmp << 8) | (tmp << 12);
159         tmp = (Col12 & 0xF00) >> 8;
160         ret |= (tmp << 16) | (tmp << 20);
161         return ret;
162 }
163 /**
164  * \brief Converts a 12-bit colour into 15 bits
165  */
166 Uint16 VT_Colour12to15(Uint16 Col12)
167 {
168         Uint32  ret;
169          int    tmp;
170         tmp = Col12 & 0xF;
171         ret  = (tmp << 1) | (tmp & 1);
172         tmp = (Col12 & 0xF0) >> 4;
173         ret |= ( (tmp << 1) | (tmp & 1) ) << 5;
174         tmp = (Col12 & 0xF00) >> 8;
175         ret |= ( (tmp << 1) | (tmp & 1) ) << 10;
176         return ret;
177 }
178
179 /**
180  * \brief Converts a 12-bit colour into any other depth
181  * \param Col12 12-bit source colour
182  * \param Depth Desired bit depth
183  * \note Green then blue get the extra avaliable bits (16:5-6-5, 14:4-5-5)
184  */
185 Uint32 VT_Colour12toN(Uint16 Col12, int Depth)
186 {
187         Uint32  ret;
188         Uint32  r, g, b;
189          int    rSize, gSize, bSize;
190         
191         // Fast returns
192         if( Depth == 24 )       return VT_Colour12to24(Col12);
193         if( Depth == 15 )       return VT_Colour12to15(Col12);
194         // - 32 is a special case, it's usually 24-bit colour with an unused byte
195         if( Depth == 32 )       return VT_Colour12to24(Col12);
196         
197         // Bounds checks
198         if( Depth < 8 ) return 0;
199         if( Depth > 32 )        return 0;
200         
201         r = Col12 & 0xF;
202         g = (Col12 & 0xF0) >> 4;
203         b = (Col12 & 0xF00) >> 8;
204         
205         rSize = gSize = bSize = Depth / 3;
206         if( rSize + gSize + bSize < Depth )     // Depth % 3 == 1
207                 gSize ++;
208         if( rSize + gSize + bSize < Depth )     // Depth % 3 == 2
209                 bSize ++;
210         
211         // Expand
212         r <<= rSize - 4;        g <<= gSize - 4;        b <<= bSize - 4;
213         // Fill with the lowest bit
214         if( Col12 & 0x001 )     r |= (1 << (rSize - 4)) - 1;
215         if( Col12 & 0x010 )     r |= (1 << (gSize - 4)) - 1;
216         if( Col12 & 0x100 )     r |= (1 << (bSize - 4)) - 1;
217         
218         // Create output
219         ret  = r;
220         ret |= g << rSize;
221         ret |= b << (rSize + gSize);
222         
223         return ret;
224 }
225
226 /**
227  * \fn Uint8 *VT_Font_GetChar(Uint32 Codepoint)
228  * \brief Gets an index into the font array given a Unicode Codepoint
229  * \note See http://en.wikipedia.org/wiki/CP437
230  */
231 Uint8 *VT_Font_GetChar(Uint32 Codepoint)
232 {
233          int    index = 0;
234         if(Codepoint < 128)
235                 return &VTermFont[Codepoint*FONT_HEIGHT];
236         switch(Codepoint)
237         {
238         case 0xC7:      index = 128;    break;  // Ç
239         case 0xFC:      index = 129;    break;  // ü
240         case 0xE9:      index = 130;    break;  // é
241         case 0xE2:      index = 131;    break;  // â
242         case 0xE4:      index = 132;    break;  // ä
243         case 0xE0:      index = 133;    break;  // à
244         case 0xE5:      index = 134;    break;  // å
245         case 0xE7:      index = 135;    break;  // ç
246         case 0xEA:      index = 136;    break;  // ê
247         case 0xEB:      index = 137;    break;  // ë
248         case 0xE8:      index = 138;    break;  // è
249         case 0xEF:      index = 139;    break;  // ï
250         case 0xEE:      index = 140;    break;  // î
251         case 0xEC:      index = 141;    break;  // ì
252         case 0xC4:      index = 142;    break;  // Ä
253         case 0xC5:      index = 143;    break;  // Å
254         }
255         
256         return &VTermFont[index*FONT_HEIGHT];
257 }
258
259 EXPORTAS(&giVT_CharWidth, giVT_CharWidth);
260 EXPORTAS(&giVT_CharHeight, giVT_CharHeight);
261 EXPORT(VT_Font_Render);
262 EXPORT(VT_Colour12to24);

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