--- a/sdlterm/src/sdlterm.cc Sat Jan 05 18:56:45 2013 +0100
+++ b/sdlterm/src/sdlterm.cc Sat Jan 05 23:00:41 2013 +0100
@@ -12,9 +12,9 @@
}
-SDL_Surface *GlyphCache::lookup_glyph(Uint16 ch)
+SDL_Surface *GlyphCache::lookup_glyph(Uint64 id)
{
- auto iter = _glyph_map.find(ch);
+ auto iter = _glyph_map.find(id);
if (iter == _glyph_map.end())
{
return NULL;
@@ -23,9 +23,9 @@
}
-void GlyphCache::put_glyph(Uint16 ch, SDL_Surface *srf)
+void GlyphCache::put_glyph(Uint64 id, SDL_Surface *srf)
{
- _glyph_map[ch] = srf;
+ _glyph_map[id] = srf;
}
@@ -119,24 +119,29 @@
}
-SDL_Surface *GlyphRenderer::render_cell(Uint16 ch, Uint16 attr)
+SDL_Surface *GlyphRenderer::render_cell(Uint32 ch, Uint32 attr)
{
SDL_Surface *cell_surface;
TTF_Font *font;
SDL_Color fgcolor, bgcolor;
// try cache
- cell_surface = _cache.lookup_glyph(ch);
+ Uint64 id = (Uint64)ch | (Uint64)attr << 32;
+ cell_surface = _cache.lookup_glyph(id);
if (cell_surface)
{
return cell_surface;
}
// load attributes
- _colormap.index_to_rgb(attr & 0x000F, fgcolor);
- _colormap.index_to_rgb((attr & 0x00F0) >> 4, bgcolor);
- Style style = (Style) ((attr & 0xFF00) >> 8);
- font = (style == Style::BOLD) ? _font_bold : _font_regular;
+ _colormap.index_to_rgb((attr & 0x000000FF), fgcolor);
+ _colormap.index_to_rgb((attr & 0x0000FF00) >> 8, bgcolor);
+ int style = (attr & 0xFF000000) >> 24;
+ font = (style & Style::BOLD) ? _font_bold : _font_regular;
+ if (style & Style::STANDOUT)
+ {
+ std::swap(fgcolor, bgcolor);
+ }
// create surface for whole cell and fill it with bg color
cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
@@ -152,13 +157,30 @@
// render glyph, blit it onto cell surface
if (ch)
{
- SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, fgcolor, bgcolor);
- int minx, maxy;
- TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL);
- dst_rect.x = minx;
- dst_rect.y = TTF_FontAscent(font) - maxy;
- SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect);
- SDL_FreeSurface(glyph_surface);
+ // when glyph is not provided by BOLD font but is provided by REGULAR font, use that (better than nothing)
+ if ((style & Style::BOLD) && !TTF_GlyphIsProvided(font, ch) && TTF_GlyphIsProvided(_font_regular, ch))
+ {
+ // use bold style of regular font instead of bold font
+ TTF_SetFontStyle(_font_regular, TTF_STYLE_BOLD);
+ _render_glyph(cell_surface, _font_regular, ch, fgcolor, bgcolor);
+ TTF_SetFontStyle(_font_regular, TTF_STYLE_NORMAL);
+ }
+ else
+ {
+ // normal case
+ _render_glyph(cell_surface, font, ch, fgcolor, bgcolor);
+ }
+ if (style & Style::UNDERLINE)
+ {
+ // draw underline
+ SDL_LockSurface(cell_surface);
+ int y = 1 + TTF_FontAscent(font);
+ Uint32 fgcolor_mapped = SDL_MapRGB(cell_surface->format, fgcolor.r, fgcolor.g, fgcolor.b);
+ Uint32 *p = (Uint32 *)(cell_surface->pixels + y * cell_surface->pitch);
+ for (int x = 0; x < _cell_width; x++)
+ *p++ = fgcolor_mapped;
+ SDL_UnlockSurface(cell_surface);
+ }
}
// convert to display format
@@ -167,12 +189,26 @@
SDL_FreeSurface(tmp_surface);
// put to cache
- _cache.put_glyph(ch, cell_surface);
+ _cache.put_glyph(id, cell_surface);
return cell_surface;
}
+void GlyphRenderer::_render_glyph(SDL_Surface *cell_surface, TTF_Font *font, Uint32 ch,
+ SDL_Color fgcolor, SDL_Color bgcolor)
+{
+ int minx, maxy;
+ SDL_Rect dst_rect;
+ SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, fgcolor, bgcolor);
+ TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL);
+ dst_rect.x = minx;
+ dst_rect.y = TTF_FontAscent(font) - maxy;
+ SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect);
+ SDL_FreeSurface(glyph_surface);
+}
+
+
void TerminalScreen::select_font(const char *fname_regular, const char *fname_bold, int ptsize)
{
_render.open_font(fname_regular, fname_bold, ptsize);
@@ -204,7 +240,7 @@
}
-void TerminalScreen::putch(int x, int y, Uint16 ch, Uint16 attr)
+void TerminalScreen::putch(int x, int y, Uint32 ch, Uint32 attr)
{
TerminalCell &cell = _cells_front[y * _width + x];
cell.ch = ch;