2 |
2 |
3 #include <exception> |
3 #include <exception> |
4 #include <algorithm> |
4 #include <algorithm> |
5 |
5 |
6 |
6 |
|
7 void ColorMap::index_to_rgb(int index, SDL_Color &color) |
|
8 { |
|
9 color.r = _map[index][0]; |
|
10 color.g = _map[index][1]; |
|
11 color.b = _map[index][2]; |
|
12 } |
|
13 |
|
14 |
7 SDL_Surface *GlyphCache::lookup_glyph(Uint16 ch) |
15 SDL_Surface *GlyphCache::lookup_glyph(Uint16 ch) |
8 { |
16 { |
9 auto iter = _glyph_map.find(ch); |
17 auto iter = _glyph_map.find(ch); |
10 if (iter == _glyph_map.end()) |
18 if (iter == _glyph_map.end()) |
11 { |
19 { |
30 _glyph_map.clear(); |
38 _glyph_map.clear(); |
31 } |
39 } |
32 |
40 |
33 |
41 |
34 GlyphRenderer::GlyphRenderer() |
42 GlyphRenderer::GlyphRenderer() |
35 : _font_regular(NULL), _font_bold(NULL) |
43 : _font_regular(NULL), _font_bold(NULL), _cell_width(0), _cell_height(0), _cache(), _colormap() |
36 { |
44 { |
37 if (TTF_Init() == -1) |
45 if (TTF_Init() == -1) |
38 { |
46 { |
39 printf("TTF_Init: %s\n", TTF_GetError()); |
47 printf("TTF_Init: %s\n", TTF_GetError()); |
40 throw std::exception(); |
48 throw std::exception(); |
109 _font_bold = NULL; |
117 _font_bold = NULL; |
110 } |
118 } |
111 } |
119 } |
112 |
120 |
113 |
121 |
114 SDL_Surface *GlyphRenderer::render_glyph(Uint16 ch) |
122 SDL_Surface *GlyphRenderer::render_cell(Uint16 ch, Uint16 attr) |
115 { |
123 { |
116 SDL_Surface *cell_surface; |
124 SDL_Surface *cell_surface; |
|
125 TTF_Font *font; |
|
126 SDL_Color fgcolor, bgcolor; |
117 |
127 |
118 // try cache |
128 // try cache |
119 cell_surface = _cache.lookup_glyph(ch); |
129 cell_surface = _cache.lookup_glyph(ch); |
120 if (cell_surface) |
130 if (cell_surface) |
121 { |
131 { |
122 return cell_surface; |
132 return cell_surface; |
123 } |
133 } |
124 |
134 |
125 TTF_Font *font = _font_regular; |
135 // load attributes |
126 SDL_Color color={0xff,0xff,0xff}, bgcolor={0,0,0}; |
136 _colormap.index_to_rgb(attr & 0x000F, fgcolor); |
|
137 _colormap.index_to_rgb((attr & 0x00F0) >> 4, bgcolor); |
|
138 Style style = (Style) ((attr & 0xFF00) >> 8); |
|
139 font = (style == Style::BOLD) ? _font_bold : _font_regular; |
127 |
140 |
128 // create surface for whole cell and fill it with bg color |
141 // create surface for whole cell and fill it with bg color |
129 cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, |
142 cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, |
130 _cell_width, _cell_height, 32, 0, 0, 0, 0); |
143 _cell_width, _cell_height, 32, 0, 0, 0, 0); |
131 SDL_Rect dst_rect; |
144 SDL_Rect dst_rect; |
137 SDL_FillRect(cell_surface, &dst_rect, bgcolor_mapped); |
150 SDL_FillRect(cell_surface, &dst_rect, bgcolor_mapped); |
138 |
151 |
139 // render glyph, blit it onto cell surface |
152 // render glyph, blit it onto cell surface |
140 if (ch) |
153 if (ch) |
141 { |
154 { |
142 SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, color, bgcolor); |
155 SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, fgcolor, bgcolor); |
143 int minx, maxy; |
156 int minx, maxy; |
144 TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL); |
157 TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL); |
145 dst_rect.x = minx; |
158 dst_rect.x = minx; |
146 dst_rect.y = TTF_FontAscent(font) - maxy; |
159 dst_rect.y = TTF_FontAscent(font) - maxy; |
147 SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect); |
160 SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect); |
201 |
214 |
202 void TerminalScreen::commit() |
215 void TerminalScreen::commit() |
203 { |
216 { |
204 auto front_iter = _cells_front.begin(); |
217 auto front_iter = _cells_front.begin(); |
205 auto back_iter = _cells_back.begin(); |
218 auto back_iter = _cells_back.begin(); |
206 SDL_Surface *glyph_surface; |
219 SDL_Surface *cell_surface; |
207 SDL_Rect dst_rect; |
220 SDL_Rect dst_rect; |
208 for (int y = 0; y < _height; y++) |
221 for (int y = 0; y < _height; y++) |
209 { |
222 { |
210 for (int x = 0; x < _width; x++) |
223 for (int x = 0; x < _width; x++) |
211 { |
224 { |
212 if (*front_iter != *back_iter) |
225 if (*front_iter != *back_iter) |
213 { |
226 { |
214 dst_rect.x = x * _cell_width; |
227 dst_rect.x = x * _cell_width; |
215 dst_rect.y = y * _cell_height; |
228 dst_rect.y = y * _cell_height; |
216 glyph_surface = _render.render_glyph(front_iter->ch); |
229 cell_surface = _render.render_cell(front_iter->ch, front_iter->attr); |
217 SDL_BlitSurface(glyph_surface, NULL, _screen_surface, &dst_rect); |
230 SDL_BlitSurface(cell_surface, NULL, _screen_surface, &dst_rect); |
218 *back_iter = *front_iter; |
231 *back_iter = *front_iter; |
219 } |
232 } |
220 front_iter++; |
233 front_iter++; |
221 back_iter++; |
234 back_iter++; |
222 } |
235 } |
228 |
241 |
229 void TerminalScreen::_reset_cells() |
242 void TerminalScreen::_reset_cells() |
230 { |
243 { |
231 _cell_width = _render.get_cell_width(); |
244 _cell_width = _render.get_cell_width(); |
232 _cell_height = _render.get_cell_height(); |
245 _cell_height = _render.get_cell_height(); |
|
246 if (!_cell_width || !_cell_height) |
|
247 return; |
|
248 |
233 _width = _pixel_width / _cell_width; |
249 _width = _pixel_width / _cell_width; |
234 _height = _pixel_height / _cell_height; |
250 _height = _pixel_height / _cell_height; |
|
251 if (!_width || !_height) |
|
252 return; |
235 |
253 |
236 int num_cells = _width * _height; |
254 int num_cells = _width * _height; |
237 _cells_front.resize(num_cells); |
255 _cells_front.resize(num_cells, TerminalCell()); |
238 _cells_back.resize(num_cells); |
256 _cells_back.resize(num_cells, TerminalCell()); |
239 } |
257 } |
240 |
258 |
241 |
259 |
242 Terminal::Terminal() |
260 Terminal::Terminal() |
243 : _screen(), _mousemove_last_x(-1) |
261 : _screen(), _attr(7), _mousemove_last_x(-1) |
244 { |
262 { |
245 if (SDL_Init(SDL_INIT_VIDEO) == -1) |
263 if (SDL_Init(SDL_INIT_VIDEO) == -1) |
246 { |
264 { |
247 fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); |
265 fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); |
248 throw std::exception(); |
266 throw std::exception(); |
325 { |
343 { |
326 case SDLK_BACKSPACE: return "backspace"; |
344 case SDLK_BACKSPACE: return "backspace"; |
327 case SDLK_TAB: return "tab"; |
345 case SDLK_TAB: return "tab"; |
328 case SDLK_RETURN: return "enter"; |
346 case SDLK_RETURN: return "enter"; |
329 case SDLK_KP_ENTER: return "enter"; |
347 case SDLK_KP_ENTER: return "enter"; |
330 case SDLK_PAUSE: return "pause"; |
|
331 case SDLK_ESCAPE: return "escape"; |
348 case SDLK_ESCAPE: return "escape"; |
332 case SDLK_DELETE: return "delete"; |
349 case SDLK_DELETE: return "delete"; |
333 case SDLK_INSERT: return "insert"; |
350 case SDLK_INSERT: return "insert"; |
334 case SDLK_UP: return "up"; |
351 case SDLK_UP: return "up"; |
335 case SDLK_DOWN: return "down"; |
352 case SDLK_DOWN: return "down"; |
349 case SDLK_F8: return "f8"; |
366 case SDLK_F8: return "f8"; |
350 case SDLK_F9: return "f9"; |
367 case SDLK_F9: return "f9"; |
351 case SDLK_F10: return "f10"; |
368 case SDLK_F10: return "f10"; |
352 case SDLK_F11: return "f11"; |
369 case SDLK_F11: return "f11"; |
353 case SDLK_F12: return "f12"; |
370 case SDLK_F12: return "f12"; |
|
371 case SDLK_PRINT: return "print"; |
|
372 case SDLK_SCROLLOCK: return "scrllock"; |
|
373 case SDLK_PAUSE: return "pause"; |
354 default: return NULL; |
374 default: return NULL; |
355 } |
375 } |
356 } |
376 } |
357 |
377 |