diff --git a/configure.in b/configure.in index b5d32de..655dbde 100644 --- a/configure.in +++ b/configure.in @@ -21,6 +21,8 @@ AC_ARG_WITH(sdl-gfx-prefix, AC_CHECK_LIB(SDL_gfx, rotozoomSurfaceXY,,check_sdl_gfx="no") +AC_CHECK_LIB(SDL_ttf, TTF_OpenFont) + # Check for libpng AC_CHECK_LIB(png, png_read_image,,check_png="no") diff --git a/src/asfont.cpp b/src/asfont.cpp index 7fb2b55..2274b34 100644 --- a/src/asfont.cpp +++ b/src/asfont.cpp @@ -1,150 +1,67 @@ #include "asfont.h" -#include "imageio.h" +#include "debug.h" #include "surface.h" #include "utilities.h" -#include -#include -#include +#include +#include +#include -#define SFONTPLUS_CHARSET "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~¡¿ÀÁÈÉÌÍÒÓÙÚÝÄËÏÖÜŸÂÊÎÔÛÅÃÕÑÆÇČĎĚĽĹŇÔŘŔŠŤŮŽàáèéìíòóùúýäëïöüÿâêîôûåãõñæçčďěľĺňôřŕšťžůðßÐÞþАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюяØøąćęłńśżźĄĆĘŁŃŚŻŹ" +/* TODO: Let the theme choose the font and font size */ +#define TTF_FONT "/usr/share/fonts/truetype/dejavu/DejaVuSansCondensed.ttf" +#define TTF_FONT_SIZE 12 -ASFont::ASFont(const std::string &fontImagePath) - : characters(SFONTPLUS_CHARSET) +using namespace std; + +ASFont::ASFont(const string &path) { - surface = loadPNG(fontImagePath); - if (!surface) { + if (!TTF_WasInit() && TTF_Init() < 0) { + ERROR("Unable to init SDL_ttf library\n"); return; } - assert(surface->format->BytesPerPixel == 4); - SDL_LockSurface(surface); - - // Determine character widths. - Uint32 pink = SDL_MapRGB(surface->format, 255, 0, 255); - Uint32 *topLine = static_cast(surface->pixels); - const unsigned width = surface->w; - unsigned x = 0; - unsigned c = 0; - while (c < characters.length()) { - while (x < width && topLine[x] != pink) x++; - unsigned startx = x; - x++; - while (x < width && topLine[x] == pink) x++; - - charpos.push_back(startx); - charpos.push_back(x); - if (c > 0 && utf8Code(characters[c - 1])) { - // UTF8 character - charpos.push_back(startx); - charpos.push_back(x); - c++; - } - c++; + font = TTF_OpenFont(TTF_FONT, TTF_FONT_SIZE); + if (!font) { + ERROR("Unable to open font\n"); + return; } - // Scan height of "0" glyph. - std::string::size_type pos = characters.find("0") * 2; - SDL_Rect srcrect = { - static_cast(charpos[pos]), - 1, - static_cast(charpos[pos + 2] - charpos[pos]), - static_cast(surface->h - 1) - }; - const unsigned alphaMask = surface->format->Amask; - unsigned y = srcrect.h; - bool nonTransparentFound = false; - while (!nonTransparentFound && y-- > 0) { - Uint32 *line = reinterpret_cast( - reinterpret_cast(surface->pixels) - + (srcrect.y + y) * surface->pitch - ); - for (unsigned x = 0; !nonTransparentFound && x < srcrect.w; x++) { - nonTransparentFound = (line[srcrect.x + x] & alphaMask) != 0; - } - } - lineHeight = y + 1; - - SDL_UnlockSurface(surface); + fontheight = TTF_FontHeight(font); } -ASFont::~ASFont() { - if (surface) { - SDL_FreeSurface(surface); +ASFont::~ASFont() +{ + TTF_CloseFont(font); + TTF_Quit(); +} + +int ASFont::getTextWidth(const char *text) +{ + int w, h; + TTF_SizeUTF8(font, text, &w, &h); + return w; +} + +void ASFont::write(Surface *surface, const string &text, + int x, int y, HAlign halign, VAlign valign) +{ + if (text.find("\n", 0) == string::npos) { + writeLine(surface, text.c_str(), x, y, halign, valign); + return; + } + + vector v; + split(v, text, "\n"); + + for (vector::const_iterator it = v.begin(); it != v.end(); it++) { + writeLine(surface, it->c_str(), x, y, halign, valign); + y += fontheight; } } -bool ASFont::utf8Code(unsigned char c) { - return (c>=194 && c<=198) || c==208 || c==209; - //return c>=194; -} - -void ASFont::writeLine(Surface *s, const std::string &text, int x, int y) { - if (text.empty()) return; - - std::string::size_type pos; - SDL_Rect srcrect, dstrect; - - // these values won't change in the loop - srcrect.y = 1; - dstrect.y = y; - srcrect.h = dstrect.h = surface->h-1; - - for(unsigned i=0; iw; i++) { - //Utf8 characters - if (utf8Code(text[i]) && i+1raw, &dstrect); - - x += charpos[pos+2] - charpos[pos+1]; - } -} - -int ASFont::getTextWidth(const char *text) { - int maxWidth = 0, width = 0; - while (char ch = *text++) { - if (ch == '\n') { - // New line. - maxWidth = std::max(width, maxWidth); - width = 0; - } else { - std::string::size_type pos; - if (utf8Code(ch) && *text) { - // 2-byte character. - pos = characters.find(std::string(&text[-1], 2)); - text++; - } else { - // 1-byte character. - pos = characters.find(ch); - } - if (pos == std::string::npos) { - pos = 0; - } - width += charpos[pos * 2 + 2] - charpos[pos * 2 + 1]; - } - } - return std::max(width, maxWidth); -} - -int ASFont::getTextWidth(const std::string& text) { - return getTextWidth(text.c_str()); -} - -void ASFont::writeLine(Surface* surface, const std::string& text, int x, int y, HAlign halign) { +void ASFont::writeLine(Surface *surface, const char *text, + int x, int y, HAlign halign, VAlign valign) +{ switch (halign) { case HAlignLeft: break; @@ -155,46 +72,46 @@ void ASFont::writeLine(Surface* surface, const std::string& text, int x, int y, x -= getTextWidth(text); break; } - writeLine(surface, text, x, y); -} -void ASFont::writeLine(Surface* surface, const std::string& text, int x, int y, HAlign halign, VAlign valign) { switch (valign) { case VAlignTop: break; case VAlignMiddle: - y -= getHeight() / 2; + y -= fontheight / 2; break; case VAlignBottom: - y -= getHeight(); - break; - } - writeLine(surface, text, x, y, halign); -} - -void ASFont::writeLine(Surface* surface, const std::vector &text, int x, int y, HAlign halign, VAlign valign) { - switch (valign) { - case VAlignTop: - break; - case VAlignMiddle: - y -= (getHeight() / 2) * text.size(); - break; - case VAlignBottom: - y -= getHeight() * text.size(); + y -= fontheight; break; } - for (std::vector::const_iterator it = text.begin(); it != text.end(); ++it) { - write(surface, *it, x, y, halign); - y += getHeight(); - } -} + SDL_Color color = { 0, 0, 0, 0 }; + SDL_Surface *s = TTF_RenderUTF8_Blended(font, text, color); -void ASFont::write(Surface* surface, const std::string& text, int x, int y, HAlign halign, VAlign valign) { - if (text.find("\n", 0) != std::string::npos) { - std::vector textArr; - split(textArr, text, "\n"); - writeLine(surface, textArr, x, y, halign, valign); - } else - writeLine(surface, text, x, y, halign, valign); + SDL_Rect rect = { (Sint16) x, (Sint16) (y - 1), 0, 0 }; + SDL_BlitSurface(s, NULL, surface->raw, &rect); + + /* Note: rect.x / rect.y are reset everytime because SDL_BlitSurface + * will modify them if negative */ + rect.x = x; + rect.y = y + 1; + SDL_BlitSurface(s, NULL, surface->raw, &rect); + + rect.x = x - 1; + rect.y = y; + SDL_BlitSurface(s, NULL, surface->raw, &rect); + + rect.x = x + 1; + rect.y = y; + SDL_BlitSurface(s, NULL, surface->raw, &rect); + SDL_FreeSurface(s); + + rect.x = x; + rect.y = y; + color.r = 0xff; + color.g = 0xff; + color.b = 0xff; + + s = TTF_RenderUTF8_Blended(font, text, color); + SDL_BlitSurface(s, NULL, surface->raw, &rect); + SDL_FreeSurface(s); } diff --git a/src/asfont.h b/src/asfont.h index 80e08e7..d8397f6 100644 --- a/src/asfont.h +++ b/src/asfont.h @@ -6,7 +6,7 @@ #ifndef ASFONT_H #define ASFONT_H -#include +#include #include #include @@ -20,30 +20,33 @@ public: ASFont(const std::string &font); ~ASFont(); - bool utf8Code(unsigned char c); - int getTextWidth(const char *text); - int getTextWidth(const std::string& text); - int getHeight() { - return surface->h - 1; - } - int getLineHeight() { - return lineHeight; + int getTextWidth(const std::string& text) + { + return getTextWidth(text.c_str()); } - void write(Surface* surface, const std::string& text, int x, int y, HAlign halign = HAlignLeft, VAlign valign = VAlignTop); + bool utf8Code(unsigned char c) + { + return (c>=194 && c<=198) || c==208 || c==209; + } + + int getHeight() + { + return fontheight; + } + + void write(Surface *surface, + const std::string &text, int x, int y, + HAlign halign = HAlignLeft, VAlign valign = VAlignTop); private: - void writeLine(Surface *surface, const std::string &text, int x, int y); - void writeLine(Surface *surface, const std::string &text, int x, int y, HAlign halign); - void writeLine(Surface *surface, const std::string &text, int x, int y, HAlign halign, VAlign valign); - void writeLine(Surface *surface, const std::vector &text, int x, int y, HAlign halign, VAlign valign); + void writeLine(Surface *surface, const char *text, + int x, int y, HAlign halign, VAlign valign); - SDL_Surface *surface; - std::vector charpos; - std::string characters; - int lineHeight; + TTF_Font *font; + unsigned int fontheight; }; #endif /* ASFONT_H */ diff --git a/src/gmenu2x.cpp b/src/gmenu2x.cpp index 3c1aab2..6baddc5 100644 --- a/src/gmenu2x.cpp +++ b/src/gmenu2x.cpp @@ -647,7 +647,7 @@ void GMenu2X::main() { uint linksPerPage = linkColumns*linkRows; int linkSpacingX = (resX-10 - linkColumns*skinConfInt["linkWidth"])/linkColumns; int linkSpacingY = (resY-35 - skinConfInt["topBarHeight"] - linkRows*skinConfInt["linkHeight"])/linkRows; - uint sectionLinkPadding = (skinConfInt["topBarHeight"] - 32 - font->getLineHeight()) / 3; + uint sectionLinkPadding = (skinConfInt["topBarHeight"] - 32 - font->getHeight()) / 3; bool quit = false; int x,y; diff --git a/src/link.cpp b/src/link.cpp index b331fa4..b6a1700 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -137,7 +137,7 @@ void Link::setPosition(int x, int y) { void Link::recalcCoordinates() { iconX = rect.x+(rect.w-32)/2; - padding = (gmenu2x->skinConfInt["linkHeight"] - 32 - gmenu2x->font->getLineHeight()) / 3; + padding = (gmenu2x->skinConfInt["linkHeight"] - 32 - gmenu2x->font->getHeight()) / 3; } void Link::run() {