diff -r dce7325109c1 -r 50a1857557da sdlterm/src/sdlterm.cc --- 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;