2013-08-03 23:30:12 +03:00
|
|
|
#include "font.h"
|
|
|
|
|
2013-07-05 21:07:46 +03:00
|
|
|
#include "debug.h"
|
2010-02-04 13:33:47 +02:00
|
|
|
#include "surface.h"
|
|
|
|
#include "utilities.h"
|
|
|
|
|
2013-07-05 21:07:46 +03:00
|
|
|
#include <SDL.h>
|
|
|
|
#include <SDL_ttf.h>
|
|
|
|
#include <vector>
|
2011-05-09 15:25:16 +03:00
|
|
|
|
2013-07-05 21:07:46 +03:00
|
|
|
/* 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
|
2011-05-09 15:54:11 +03:00
|
|
|
|
2013-07-05 21:07:46 +03:00
|
|
|
using namespace std;
|
|
|
|
|
2013-08-04 01:58:32 +03:00
|
|
|
Font *Font::defaultFont()
|
2011-05-12 02:20:26 +03:00
|
|
|
{
|
2013-07-05 21:07:46 +03:00
|
|
|
if (!TTF_WasInit() && TTF_Init() < 0) {
|
|
|
|
ERROR("Unable to init SDL_ttf library\n");
|
2013-08-04 01:58:32 +03:00
|
|
|
return nullptr;
|
2011-05-09 15:25:16 +03:00
|
|
|
}
|
2011-05-12 03:10:40 +03:00
|
|
|
|
2013-08-04 01:58:32 +03:00
|
|
|
TTF_Font *font = TTF_OpenFont(TTF_FONT, TTF_FONT_SIZE);
|
2013-07-05 21:07:46 +03:00
|
|
|
if (!font) {
|
|
|
|
ERROR("Unable to open font\n");
|
2013-08-04 01:58:32 +03:00
|
|
|
return nullptr;
|
2011-05-09 15:25:16 +03:00
|
|
|
}
|
2011-05-12 03:10:40 +03:00
|
|
|
|
2013-08-04 01:58:32 +03:00
|
|
|
return new Font(font);
|
|
|
|
}
|
|
|
|
|
|
|
|
Font::Font(TTF_Font *font)
|
|
|
|
: font(font)
|
|
|
|
{
|
2013-07-05 21:07:46 +03:00
|
|
|
fontheight = TTF_FontHeight(font);
|
2011-05-09 15:25:16 +03:00
|
|
|
}
|
|
|
|
|
2013-08-03 23:30:12 +03:00
|
|
|
Font::~Font()
|
2013-07-05 21:07:46 +03:00
|
|
|
{
|
|
|
|
TTF_CloseFont(font);
|
|
|
|
TTF_Quit();
|
2011-05-09 15:25:16 +03:00
|
|
|
}
|
|
|
|
|
2013-08-03 23:30:12 +03:00
|
|
|
int Font::getTextWidth(const char *text)
|
2013-07-05 21:07:46 +03:00
|
|
|
{
|
|
|
|
int w, h;
|
|
|
|
TTF_SizeUTF8(font, text, &w, &h);
|
|
|
|
return w;
|
2011-05-09 15:54:11 +03:00
|
|
|
}
|
|
|
|
|
2013-08-03 23:30:12 +03:00
|
|
|
void Font::write(Surface *surface, const string &text,
|
2013-07-05 21:07:46 +03:00
|
|
|
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;
|
2011-05-09 15:25:16 +03:00
|
|
|
}
|
|
|
|
|
2013-07-05 21:07:46 +03:00
|
|
|
vector<string> v;
|
|
|
|
split(v, text, "\n");
|
2011-05-09 15:25:16 +03:00
|
|
|
|
2013-07-05 21:07:46 +03:00
|
|
|
for (vector<string>::const_iterator it = v.begin(); it != v.end(); it++) {
|
|
|
|
writeLine(surface, it->c_str(), x, y, halign, valign);
|
|
|
|
y += fontheight;
|
|
|
|
}
|
2010-02-04 13:33:47 +02:00
|
|
|
}
|
|
|
|
|
2013-08-03 23:30:12 +03:00
|
|
|
void Font::writeLine(Surface *surface, const char *text,
|
2013-07-05 21:07:46 +03:00
|
|
|
int x, int y, HAlign halign, VAlign valign)
|
|
|
|
{
|
2010-02-04 13:33:47 +02:00
|
|
|
switch (halign) {
|
2011-05-09 06:17:25 +03:00
|
|
|
case HAlignLeft:
|
|
|
|
break;
|
|
|
|
case HAlignCenter:
|
2011-05-10 03:23:13 +03:00
|
|
|
x -= getTextWidth(text) / 2;
|
2010-02-04 13:33:47 +02:00
|
|
|
break;
|
2011-05-09 06:17:25 +03:00
|
|
|
case HAlignRight:
|
2010-02-04 13:33:47 +02:00
|
|
|
x -= getTextWidth(text);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (valign) {
|
2011-05-09 06:17:25 +03:00
|
|
|
case VAlignTop:
|
|
|
|
break;
|
|
|
|
case VAlignMiddle:
|
2013-07-05 21:07:46 +03:00
|
|
|
y -= fontheight / 2;
|
2010-02-04 13:33:47 +02:00
|
|
|
break;
|
2011-05-09 06:17:25 +03:00
|
|
|
case VAlignBottom:
|
2013-07-05 21:07:46 +03:00
|
|
|
y -= fontheight;
|
2010-02-04 13:33:47 +02:00
|
|
|
break;
|
|
|
|
}
|
2011-05-10 03:43:15 +03:00
|
|
|
|
2013-07-05 21:07:46 +03:00
|
|
|
SDL_Color color = { 0, 0, 0, 0 };
|
|
|
|
SDL_Surface *s = TTF_RenderUTF8_Blended(font, text, color);
|
2010-02-04 13:33:47 +02:00
|
|
|
|
2013-07-05 21:07:46 +03:00
|
|
|
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;
|
2010-02-04 13:33:47 +02:00
|
|
|
|
2013-07-05 21:07:46 +03:00
|
|
|
s = TTF_RenderUTF8_Blended(font, text, color);
|
|
|
|
SDL_BlitSurface(s, NULL, surface->raw, &rect);
|
|
|
|
SDL_FreeSurface(s);
|
2010-02-04 13:33:47 +02:00
|
|
|
}
|