to = from;
}
-int my_draw_text(const widestring &str, unsigned char *buf, int xpos, int ypos, bool real_render, int r, int g, int b, FT_Face face, FT_Face symbolface);
+int my_draw_text(const widestring &str, unsigned char *buf, int xpos, int ypos, bool real_render, int r, int g, int b, std::vector<FT_Face> &fontlist);
class Tournament {
public:
};
Tournament active_tournament;
-FT_Face font, symbolfont;
+std::vector<FT_Face> fonts;
/* A trigger that sets a flag whenever it's trigged. */
class FlagTrigger : pqxx::trigger {
pqxx::result res( t.exec("SELECT * FROM songs WHERE title LIKE 'M%'") );
unsigned y = 0;
for (pqxx::result::const_iterator i = res.begin(); i != res.end(); ++i) {
- my_draw_text(i["title"].as(widestring()), framebuf, 0, y, 1, 255, 255, 255, font, symbolfont);
+ my_draw_text(i["title"].as(widestring()), framebuf, 0, y, 1, 255, 255, 255, fonts);
y += 20;
// std::fprintf(stderr, "%s\n", i["title"].c_str());
}
void init_freetype()
{
FT_Library library;
+ FT_Face face;
if (FT_Init_FreeType(&library))
throw std::runtime_error("FreeType init failed.");
- if (FT_New_Face(library, "/usr/share/fonts/truetype/msttcorefonts/Georgia.ttf", 0, &font))
- throw std::runtime_error("Face opening failed.");
- if (FT_New_Face(library, "/usr/share/fonts/truetype/freefont/FreeSerif.ttf", 0, &symbolfont))
+
+ // Georgia
+ if (FT_New_Face(library, "/usr/share/fonts/truetype/msttcorefonts/Georgia.ttf", 0, &face))
throw std::runtime_error("Face opening failed.");
- if (FT_Set_Char_Size(font, 0, 12 * 64, 96, 96))
- throw std::runtime_error("Size set failed.");
- if (FT_Set_Char_Size(symbolfont, 0, 12 * 64, 96, 96))
+ if (FT_Set_Char_Size(face, 0, 12 * 64, 96, 96))
throw std::runtime_error("Size set failed.");
+ fonts.push_back(face);
+
+ // FreeSerif
+ if (FT_New_Face(library, "/usr/share/fonts/truetype/freefont/FreeSerif.ttf", 0, &face)) {
+ std::fprintf(stderr, "Warning: Couldn't open FreeSerif, some glyphs might not be available\n");
+ } else {
+ if (FT_Set_Char_Size(face, 0, 12 * 64, 96, 96))
+ throw std::runtime_error("Size set failed.");
+ fonts.push_back(face);
+ }
+
+ // FreeSerif
+ if (FT_New_Face(library, "arialuni.ttf", 0, &face)) {
+ std::fprintf(stderr, "Warning: Couldn't open Arial Unicode MS, some glyphs might not be available\n");
+ } else {
+ if (FT_Set_Char_Size(face, 0, 12 * 64, 96, 96))
+ throw std::runtime_error("Size set failed.");
+ fonts.push_back(face);
+ }
}
-int my_draw_text(const widestring &str, unsigned char *buf, int xpos, int ypos, bool real_render, int r, int g, int b, FT_Face face, FT_Face symbolface)
+int my_draw_text(const widestring &str, unsigned char *buf, int xpos, int ypos, bool real_render, int r, int g, int b, std::vector<FT_Face> &fontlist)
{
FT_GlyphSlot slot;
int x = 0;
for (widestring::const_iterator i = str.begin(); i != str.end(); ++i) {
- // try the normal font first, fall back if there's some special character
- int glyph_index = FT_Get_Char_Index(face, *i);
- if (glyph_index == 0) {
- std::fprintf(stderr, "Couldn't find U+%x in primary face, falling back to symbol face\n",
- *i);
- glyph_index = FT_Get_Char_Index(symbolface, *i);
- if (glyph_index == 0) {
- std::fprintf(stderr, "Couldn't find U+%x in symbol face, ignoring\n", *i);
+ int glyph_index;
+ for (std::vector<FT_Face>::const_iterator j = fontlist.begin(); j != fontlist.end(); ++j) {
+ glyph_index = FT_Get_Char_Index(*j, *i);
+ if (glyph_index == 0)
continue;
- }
- if (FT_Load_Glyph(symbolface, glyph_index, FT_LOAD_RENDER))
- throw std::runtime_error("Couldn't load glyph from symbol face");
- slot = symbolface->glyph;
- } else {
- if (FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER))
- throw std::runtime_error("Couldn't load glyph from primary face");
- slot = face->glyph;
+
+ if (FT_Load_Glyph(*j, glyph_index, FT_LOAD_RENDER))
+ throw std::runtime_error("Couldn't load glyph");
+ slot = (*j)->glyph;
+ break;
+ }
+ if (glyph_index == 0) {
+ std::fprintf(stderr, "Warning: Could not find a glyph in any font for U+%x, ignoring\n", *i);
+ continue;
}
if (real_render) {
+++ /dev/null
-#include <stdio.h>
-
-#ifdef WIN32
-#include <windows.h>
-#endif
-
-#ifdef __linux__
-#include <unistd.h>
-#include <GL/glx.h>
-#include <X11/extensions/xf86vmode.h>
-#include <X11/keysym.h>
-#endif
-
-#include <GL/gl.h>
-#include <GL/glu.h>
-
-#include "glwindow.h"
-
-#ifdef WIN32
-LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
-
-/* this is ugly, but so is Win32 ;-) */
-GLWindow *win;
-#endif
-
-#define DEMOLIB_XASPECT 4.0f
-#define DEMOLIB_YASPECT 3.0f
-
-void GLWindow::resize(int x, int y, int w, int h)
-{
- /* Prevent division by zero */
- if (h == 0) {
- h = 1;
- }
-
- float aspect = (float)w / (float)h;
- if (aspect > DEMOLIB_XASPECT / DEMOLIB_YASPECT) {
- int new_w = (int)((float)h * DEMOLIB_XASPECT / DEMOLIB_YASPECT);
- x += (w - new_w) / 2;
- w = new_w;
- } else if (aspect < DEMOLIB_XASPECT / DEMOLIB_YASPECT) {
- int new_h = (int)((float)w * DEMOLIB_YASPECT / DEMOLIB_XASPECT);
- y += (h - new_h) / 2;
- h = new_h;
- }
-
- glViewport(x, y, w, h);
-
-#ifdef __linux__
-// XClearWindow(this->dpy, this->win);
-#endif
-}
-
-GLWindow::GLWindow(char *title, int width, int height, int bpp, bool fullscreen, int zbuffer, int visual_id)
-{
-#ifdef WIN32
- GLuint PixelFormat;
- WNDCLASS wc;
- DWORD dwExStyle;
- DWORD dwStyle;
- DEVMODE dmScreenSettings;
-
- if (visual_id != -1) {
- EnumDisplaySettings(NULL, visual_id, &dmScreenSettings);
- width = dmScreenSettings.dmPelsWidth;
- height = dmScreenSettings.dmPelsHeight;
- bpp = dmScreenSettings.dmBitsPerPel;
- } else {
- memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
- dmScreenSettings.dmSize = sizeof(dmScreenSettings);
- dmScreenSettings.dmPelsWidth = width;
- dmScreenSettings.dmPelsHeight = height;
- dmScreenSettings.dmBitsPerPel = bpp;
- dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
- }
- win = this;
-
- RECT WindowRect;
- WindowRect.left = (long)0;
- WindowRect.right = (long)width;
- WindowRect.top = (long)0;
- WindowRect.bottom = (long)height;
-
-#endif /* WIN32 */
-#ifdef __linux__
- XVisualInfo *vi;
- int dpyWidth = 0, dpyHeight = 0;
- int i;
- XF86VidModeModeInfo **modes;
- int modeNum;
- int bestMode;
- Atom wmDelete;
- Window winDummy;
- unsigned int borderDummy;
-
- static int attrList[] = {
- GLX_RGBA,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- GLX_DOUBLEBUFFER,
- GLX_DEPTH_SIZE, zbuffer,
- GLX_STENCIL_SIZE, 4,
- None
- };
-#endif /* __linux__ */
-
- this->x = 0;
- this->y = 0;
- this->width = width;
- this->height = height;
- this->bpp = bpp;
- this->fullscreen = fullscreen;
- this->zbuffer = zbuffer;
- this->done = 0;
-
-#ifdef WIN32
- this->hInstance = GetModuleHandle(NULL);
- wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
- wc.lpfnWndProc = WndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = this->hInstance;
- wc.hIcon = NULL;
- wc.hCursor = NULL;
- wc.hbrBackground = NULL;
- wc.lpszMenuName = NULL;
- wc.lpszClassName = "Excess-OGL";
-
- if( !RegisterClass(&wc) ) throw "Couldn't register Window Class";
-
-#endif /* WIN32 */
-#ifdef __linux__
- /* set best mode to current */
- bestMode = 0;
-
- /* get a connection */
- this->dpy = XOpenDisplay(0);
- this->screen = DefaultScreen(this->dpy);
-
- if (fullscreen) {
- XF86VidModeGetAllModeLines(this->dpy, this->screen, &modeNum, &modes);
-
- /* save desktop-resolution before switching modes */
- this->deskMode = *modes[0];
-
- /* look for mode with requested resolution */
- for (i = 0; i < modeNum; i++) {
- if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height)) {
- bestMode = i;
- }
- }
-
- /* if we don't have it, bomb out */
- if (bestMode == 0 && (modes[0]->hdisplay != width || modes[0]->vdisplay != height)) {
- throw "Couldn't set requested screen mode.";
- }
- }
-
- if (visual_id != -1) {
- XVisualInfo tmplate;
- int nret;
-
- tmplate.visualid = visual_id;
- vi = XGetVisualInfo(this->dpy, VisualIDMask, &tmplate, &nret);
- if (vi == NULL) {
- throw "Couldn't get selected visual!";
- }
- } else {
- /* get an appropriate visual */
- vi = glXChooseVisual(this->dpy, this->screen, attrList);
- if (vi == NULL) {
- throw "Couldn't get double-buffered visual";
- }
- }
-
- /* create a GLX context */
- this->ctx = glXCreateContext(this->dpy, vi, NULL, GL_TRUE);
-
- /* create a color map (umm, needed?) */
- Colormap cmap = XCreateColormap(this->dpy, RootWindow(this->dpy, vi->screen),
- vi->visual, AllocNone);
- this->attr.colormap = cmap;
-
- /* make a blank cursor */
- {
- static char data[1] = {0};
- Cursor cursor;
- Pixmap blank;
- XColor dummy;
-
- blank = XCreateBitmapFromData(this->dpy, RootWindow(this->dpy, vi->screen), data, 1, 1);
- if (blank == None)
- throw "Out of memory!";
- cursor = XCreatePixmapCursor(this->dpy, blank, blank, &dummy, &dummy, 0, 0);
- XFreePixmap(this->dpy, blank);
- this->attr.cursor = cursor;
- }
-
- this->attr.border_pixel = 0;
-#endif /* __linux__ */
-
- /* change screen mode */
- if (fullscreen) {
-#ifdef WIN32
- if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
- throw "Couldn't set requested screen mode.";
- }
-#endif /* WIN32 */
-#ifdef __linux__
- XF86VidModeSwitchToMode(this->dpy, this->screen, modes[bestMode]);
- XF86VidModeSetViewPort(this->dpy, this->screen, 0, 0);
- dpyWidth = modes[bestMode]->hdisplay;
- dpyHeight = modes[bestMode]->vdisplay;
- XFree(modes);
-#endif /* __linux__ */
- }
-
- /* create the window */
-#ifdef WIN32
- if (fullscreen) {
- dwExStyle = WS_EX_APPWINDOW;
- dwStyle = WS_POPUP;
- ShowCursor(FALSE);
- } else {
- dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
- dwStyle = WS_OVERLAPPEDWINDOW;
- }
-
- AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
-
- if (!(hWnd = CreateWindowEx(dwExStyle,
- "Excess-OGL",
- title,
- dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
- 0, 0,
- WindowRect.right - WindowRect.left,
- WindowRect.bottom - WindowRect.top,
- NULL,
- NULL,
- this->hInstance,
- NULL))) {
- delete this;
- throw "Could not change screenmode";
- }
-#endif
-#ifdef __linux__
- this->attr.background_pixel = 0;
-
- if (fullscreen) {
- /* create a fullscreen window */
- this->attr.override_redirect = True;
- this->attr.event_mask = KeyPressMask | ButtonPressMask |
- StructureNotifyMask;
-
- this->win = XCreateWindow(this->dpy, RootWindow(this->dpy, vi->screen),
- 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual,
- CWColormap | CWCursor | CWEventMask | CWOverrideRedirect,
- &this->attr);
- XWarpPointer(this->dpy, None, this->win, 0, 0, 0, 0, 0, 0);
- XMapRaised(this->dpy, this->win);
- XGrabKeyboard(this->dpy, this->win, True, GrabModeAsync,
- GrabModeAsync, CurrentTime);
- XGrabPointer(this->dpy, this->win, True, ButtonPressMask,
- GrabModeAsync, GrabModeAsync, this->win, None, CurrentTime);
- } else {
- /* create a window in window mode*/
- this->attr.event_mask = KeyPressMask | ButtonPressMask |
- StructureNotifyMask;
- this->win = XCreateWindow(this->dpy, RootWindow(this->dpy, vi->screen),
- 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
- CWColormap | CWBorderPixel | CWEventMask, &this->attr);
-
- /* only set window title and handle wm_delete_events if in windowed mode */
- wmDelete = XInternAtom(this->dpy, "WM_DELETE_WINDOW", True);
- XSetWMProtocols(this->dpy, this->win, &wmDelete, 1);
- XSetStandardProperties(this->dpy, this->win, title,
- title, None, NULL, 0, NULL);
- XMapRaised(this->dpy, this->win);
- }
-#endif /* __linux__ */
-
-#ifdef WIN32
- static PIXELFORMATDESCRIPTOR pfd = {
- sizeof(PIXELFORMATDESCRIPTOR),
- 1,
- PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
- PFD_TYPE_RGBA,
- bpp,
- 0, 0, 0, 0, 0, 0,
- 0,
- 0,
- 0,
- 0, 0, 0, 0,
- zbuffer,
- 8,
- 0,
- PFD_MAIN_PLANE,
- 0,
- 0, 0, 0
- };
-
- hDC = GetDC(hWnd);
- PixelFormat = ChoosePixelFormat(hDC, &pfd);
- if (PixelFormat == 0) {
- throw "Could not find a usable pixelformat";
- }
- SetPixelFormat(hDC, PixelFormat, &pfd);
- hRC = wglCreateContext(hDC);
- wglMakeCurrent(hDC, hRC);
- ShowWindow(hWnd, SW_SHOW);
- SetForegroundWindow(hWnd);
- SetFocus(hWnd);
-
- SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
-#endif /* WIN32 */
-#ifdef __linux__
- /* connect the glx-context to the window */
- glXMakeCurrent(this->dpy, this->win, this->ctx);
- XClearWindow(this->dpy, this->win);
- XGetGeometry(this->dpy, this->win, &winDummy, &this->x, &this->y,
- &this->width, &this->height, &borderDummy, &this->bpp);
- if (!glXIsDirect(this->dpy, this->ctx)) {
- throw "No direct rendering (hardware acceleration) available!";
- }
-
- nice(-7);
-#endif /* __linux__ */
-
- this->resize(0, 0, this->width, this->height);
-}
-
-GLWindow::~GLWindow()
-{
-#ifdef __linux__
- if (this->ctx) {
- if (!glXMakeCurrent(this->dpy, None, NULL)) {
- throw "Could not release drawing context.";
- }
- glXDestroyContext(this->dpy, this->ctx);
- this->ctx = NULL;
- }
-#endif
-
- if (fullscreen) {
-#ifdef __linux__
- XF86VidModeSwitchToMode(this->dpy, this->screen, &this->deskMode);
- XF86VidModeSetViewPort(this->dpy, this->screen, 0, 0);
-#endif
-#ifdef WIN32
- ChangeDisplaySettings(NULL,0);
- ShowCursor(TRUE);
-#endif
- }
-
-#ifdef __linux__
- XCloseDisplay(this->dpy);
-#endif
-
-#ifdef WIN32
- if (hRC) {
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(hRC);
- hRC = NULL;
- }
-
- if (hDC != NULL && ReleaseDC(hWnd, hDC)) hDC = NULL;
- if (hWnd != NULL && DestroyWindow(hWnd)) hWnd = NULL;
- UnregisterClass("Excess-OGL", hInstance);
-#endif
-}
-
-void GLWindow::flip()
-{
-#ifdef WIN32
- MSG msg;
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- if (msg.message == WM_QUIT) {
- this->done = TRUE;
- } else {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- SwapBuffers(this->hDC);
-#endif
-#ifdef __linux__
- glXSwapBuffers(this->dpy, this->win);
-#endif
-}
-
-bool GLWindow::is_done()
-{
- return this->done;
-}
-
-#ifdef WIN32
-LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- switch (uMsg) {
- case WM_SYSCOMMAND:
- switch (wParam) {
- case SC_SCREENSAVE:
- case SC_MONITORPOWER:
- return 0;
- }
- break;
-
- case WM_CLOSE:
- PostQuitMessage(0);
- return 0;
-
- case WM_KEYUP:
- if (wParam == VK_ESCAPE)
- PostQuitMessage(0);
- return 0;
-
- case WM_SIZE:
- win->resize(0, 0, LOWORD(lParam), HIWORD(lParam));
- return 0;
- }
-
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
-}
-#endif //WIN32