10 color.g = _map[index][1]; |
10 color.g = _map[index][1]; |
11 color.b = _map[index][2]; |
11 color.b = _map[index][2]; |
12 } |
12 } |
13 |
13 |
14 |
14 |
15 SDL_Surface *GlyphCache::lookup_glyph(Uint16 ch) |
15 SDL_Surface *GlyphCache::lookup_glyph(Uint64 id) |
16 { |
16 { |
17 auto iter = _glyph_map.find(ch); |
17 auto iter = _glyph_map.find(id); |
18 if (iter == _glyph_map.end()) |
18 if (iter == _glyph_map.end()) |
19 { |
19 { |
20 return NULL; |
20 return NULL; |
21 } |
21 } |
22 return iter->second; |
22 return iter->second; |
23 } |
23 } |
24 |
24 |
25 |
25 |
26 void GlyphCache::put_glyph(Uint16 ch, SDL_Surface *srf) |
26 void GlyphCache::put_glyph(Uint64 id, SDL_Surface *srf) |
27 { |
27 { |
28 _glyph_map[ch] = srf; |
28 _glyph_map[id] = srf; |
29 } |
29 } |
30 |
30 |
31 |
31 |
32 void GlyphCache::flush() |
32 void GlyphCache::flush() |
33 { |
33 { |
117 _font_bold = NULL; |
117 _font_bold = NULL; |
118 } |
118 } |
119 } |
119 } |
120 |
120 |
121 |
121 |
122 SDL_Surface *GlyphRenderer::render_cell(Uint16 ch, Uint16 attr) |
122 SDL_Surface *GlyphRenderer::render_cell(Uint32 ch, Uint32 attr) |
123 { |
123 { |
124 SDL_Surface *cell_surface; |
124 SDL_Surface *cell_surface; |
125 TTF_Font *font; |
125 TTF_Font *font; |
126 SDL_Color fgcolor, bgcolor; |
126 SDL_Color fgcolor, bgcolor; |
127 |
127 |
128 // try cache |
128 // try cache |
129 cell_surface = _cache.lookup_glyph(ch); |
129 Uint64 id = (Uint64)ch | (Uint64)attr << 32; |
|
130 cell_surface = _cache.lookup_glyph(id); |
130 if (cell_surface) |
131 if (cell_surface) |
131 { |
132 { |
132 return cell_surface; |
133 return cell_surface; |
133 } |
134 } |
134 |
135 |
135 // load attributes |
136 // load attributes |
136 _colormap.index_to_rgb(attr & 0x000F, fgcolor); |
137 _colormap.index_to_rgb((attr & 0x000000FF), fgcolor); |
137 _colormap.index_to_rgb((attr & 0x00F0) >> 4, bgcolor); |
138 _colormap.index_to_rgb((attr & 0x0000FF00) >> 8, bgcolor); |
138 Style style = (Style) ((attr & 0xFF00) >> 8); |
139 int style = (attr & 0xFF000000) >> 24; |
139 font = (style == Style::BOLD) ? _font_bold : _font_regular; |
140 font = (style & Style::BOLD) ? _font_bold : _font_regular; |
|
141 if (style & Style::STANDOUT) |
|
142 { |
|
143 std::swap(fgcolor, bgcolor); |
|
144 } |
140 |
145 |
141 // create surface for whole cell and fill it with bg color |
146 // create surface for whole cell and fill it with bg color |
142 cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, |
147 cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, |
143 _cell_width, _cell_height, 32, 0, 0, 0, 0); |
148 _cell_width, _cell_height, 32, 0, 0, 0, 0); |
144 SDL_Rect dst_rect; |
149 SDL_Rect dst_rect; |
150 SDL_FillRect(cell_surface, &dst_rect, bgcolor_mapped); |
155 SDL_FillRect(cell_surface, &dst_rect, bgcolor_mapped); |
151 |
156 |
152 // render glyph, blit it onto cell surface |
157 // render glyph, blit it onto cell surface |
153 if (ch) |
158 if (ch) |
154 { |
159 { |
155 SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, fgcolor, bgcolor); |
160 // when glyph is not provided by BOLD font but is provided by REGULAR font, use that (better than nothing) |
156 int minx, maxy; |
161 if ((style & Style::BOLD) && !TTF_GlyphIsProvided(font, ch) && TTF_GlyphIsProvided(_font_regular, ch)) |
157 TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL); |
162 { |
158 dst_rect.x = minx; |
163 // use bold style of regular font instead of bold font |
159 dst_rect.y = TTF_FontAscent(font) - maxy; |
164 TTF_SetFontStyle(_font_regular, TTF_STYLE_BOLD); |
160 SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect); |
165 _render_glyph(cell_surface, _font_regular, ch, fgcolor, bgcolor); |
161 SDL_FreeSurface(glyph_surface); |
166 TTF_SetFontStyle(_font_regular, TTF_STYLE_NORMAL); |
|
167 } |
|
168 else |
|
169 { |
|
170 // normal case |
|
171 _render_glyph(cell_surface, font, ch, fgcolor, bgcolor); |
|
172 } |
|
173 if (style & Style::UNDERLINE) |
|
174 { |
|
175 // draw underline |
|
176 SDL_LockSurface(cell_surface); |
|
177 int y = 1 + TTF_FontAscent(font); |
|
178 Uint32 fgcolor_mapped = SDL_MapRGB(cell_surface->format, fgcolor.r, fgcolor.g, fgcolor.b); |
|
179 Uint32 *p = (Uint32 *)(cell_surface->pixels + y * cell_surface->pitch); |
|
180 for (int x = 0; x < _cell_width; x++) |
|
181 *p++ = fgcolor_mapped; |
|
182 SDL_UnlockSurface(cell_surface); |
|
183 } |
162 } |
184 } |
163 |
185 |
164 // convert to display format |
186 // convert to display format |
165 SDL_Surface *tmp_surface = cell_surface; |
187 SDL_Surface *tmp_surface = cell_surface; |
166 cell_surface = SDL_DisplayFormat(tmp_surface); |
188 cell_surface = SDL_DisplayFormat(tmp_surface); |
167 SDL_FreeSurface(tmp_surface); |
189 SDL_FreeSurface(tmp_surface); |
168 |
190 |
169 // put to cache |
191 // put to cache |
170 _cache.put_glyph(ch, cell_surface); |
192 _cache.put_glyph(id, cell_surface); |
171 |
193 |
172 return cell_surface; |
194 return cell_surface; |
|
195 } |
|
196 |
|
197 |
|
198 void GlyphRenderer::_render_glyph(SDL_Surface *cell_surface, TTF_Font *font, Uint32 ch, |
|
199 SDL_Color fgcolor, SDL_Color bgcolor) |
|
200 { |
|
201 int minx, maxy; |
|
202 SDL_Rect dst_rect; |
|
203 SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, fgcolor, bgcolor); |
|
204 TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL); |
|
205 dst_rect.x = minx; |
|
206 dst_rect.y = TTF_FontAscent(font) - maxy; |
|
207 SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect); |
|
208 SDL_FreeSurface(glyph_surface); |
173 } |
209 } |
174 |
210 |
175 |
211 |
176 void TerminalScreen::select_font(const char *fname_regular, const char *fname_bold, int ptsize) |
212 void TerminalScreen::select_font(const char *fname_regular, const char *fname_bold, int ptsize) |
177 { |
213 { |