// Windows Headers
#define Rectangle WinRectangle
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#undef Rectangle
#include <GL/gl.h>
#include <string>
#include "GL/Font.h"
#include "GL/ImmediateMode.h"
#include "GL/Program.h"
BEGIN_NAMESPACE
GLYPHMETRICSFLOAT fontMetrics[256];
GLuint listBase;
GLuint listBase2;
float charWidth(char ch)
{
return fontMetrics[ch].gmfCellIncX;
}
float textWidth(const char* text)
{
float w = 0;
for (unsigned i = 0; i < strlen(text); ++i)
w += fontMetrics[text[i]].gmfCellIncX;
return w;
}
void glDrawText(int x, int y, const char* text, uint32_t a_color, uint32_t a_dropColor, int32_t a_fontSize, bool a_invertColors)
{
// move bottom left, southwest of the red triangle
glSetColor(a_color);
glPolygonMode(GL_FRONT, GL_FILL);
float scalar = 0.55f;
// This first part is the subtle drop shadow under the text to give better contrast
// Sort of emulates multi-sampling and also a blurring of the text that slightly increases as zooming away
for (int i = 0; i < 25; i++)
{
glPushMatrix();
float xOff = 0.125f*(i%5) - 0.25f;
float yOff = 0.125f*(i/5) - 0.25f;
xOff *= scalar * 5.0f;
yOff *= scalar * 5.0f;
xOff /= g_zoomFactor;
yOff /= g_zoomFactor;
glTranslatef(x + xOff - 1/g_zoomFactor, y + yOff + 1/g_zoomFactor, 0.0f);
glScalef((float)a_fontSize, (float)-a_fontSize, 1.0f);
glLineWidth(0.0001f);
xOff /= scalar * 5.0f;
yOff /= scalar * 5.0f;
xOff *= g_zoomFactor;
yOff *= g_zoomFactor;
float dist = xOff*xOff + yOff*yOff;
// dist range is 0 to 0.125
// 0.125-dist is from 0.125 to 0
float scale = 1 - dist;
if (a_invertColors)
scale = dist;
//glColor4f(scale, scale, scale, (0.125 - dist)*0.08);
glColor4f(scale * ((a_dropColor >> 16) & 0xff) / 255.0f,
scale * ((a_dropColor >> 8) & 0xff) / 255.0f,
scale * (a_dropColor & 0xff) / 255.0f, (0.125f - dist)*0.08f * ((a_color >> 24) & 0xff) / 255.0f);
//glColor4ub(0x00, 0x00, 0x00, 0xf0);
glPushAttrib(GL_LIST_BIT);
glListBase(listBase2);
glCallLists((GLsizei)strlen(text), GL_UNSIGNED_BYTE, text);
glPopAttrib();
glLineWidth(0.75f);
glPopMatrix();
}
// Emulate multi-sampling to smooth the polygon edges of the fill text outlines
for (int i = 0; i < 25; i++)
{
glPushMatrix();
float xOff = 0.125f*(i%5) - 0.25f;
float yOff = 0.125f*(i/5) - 0.25f;
xOff *= scalar * 3.0f;
yOff *= scalar * 3.0f;
xOff /= g_zoomFactor;
yOff /= g_zoomFactor;
glTranslatef(x + xOff, y + yOff, 0.0f);
glScalef((float)a_fontSize, (float)-a_fontSize, 1.0f);
glLineWidth(0.0001f);
xOff /= scalar * 3.0f;
yOff /= scalar * 3.0f;
xOff *= g_zoomFactor;
yOff *= g_zoomFactor;
float dist = xOff*xOff + yOff*yOff;
// dist range is 0 to 0.125
// 0.125-dist is from 0.125 to 0
/*
if (a_invertColors)
glColor4f(1,1,1, (0.125 - dist) * 0.9); // 0xff >> 2);
else
glColor4f(0,0,0, (0.125 - dist) * 0.9); // 0xff >> 2);
*/
glColor4f( ((a_color >> 16) & 0xff) / 255.0f,
((a_color >> 8) & 0xff) / 255.0f,
(a_color & 0xff) / 255.0f, (0.125f - dist)*0.9f * ((a_color >> 24) & 0xff) / 255.0f);
//glColor4ub(0x00, 0x00, 0x00, 0xf0);
glPushAttrib(GL_LIST_BIT);
glListBase(listBase2);
glCallLists((GLsizei)strlen(text), GL_UNSIGNED_BYTE, text);
glPopAttrib();
glLineWidth(0.75f);
glPopMatrix();
}
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glCheckErrors();
//glFlush();
}
void glInitFont()
{
// This stuff with the font is really expensive. TODO: remove from happening during resizeEvents
const int glyphCount = 256;
const int fontSize = 64;
listBase = glGenLists(glyphCount);
HFONT hFont = CreateFontA(fontSize, 0, 0, 0, 0, 0, 0, 0, 0, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_DONTCARE|DEFAULT_PITCH, "Segoe UI"); // "Segoe Script"); // "Fixedsys");
SelectObject(wglGetCurrentDC(), hFont);
// create bitmaps for the device context font's first 256 glyphs
wglUseFontOutlines(wglGetCurrentDC(), 0, glyphCount, listBase, 0.0001f, 0.0f, WGL_FONT_LINES, fontMetrics);
//wglUseFontOutlines(wglGetCurrentDC(), 0, glyphCount, listBase, 100.0, 10.0, WGL_FONT_OUTLINES, fontMetrics);
//wglUseFontBitmaps(wglGetCurrentDC(), 0, glyphCount, listBase);
listBase2 = glGenLists(glyphCount);
wglUseFontOutlines(wglGetCurrentDC(), 0, glyphCount, listBase2, 0.0001f, 0.0f, WGL_FONT_POLYGONS, NULL);
DeleteObject(hFont);
glCheckErrors();
}
void glCleanupFont()
{
const int glyphCount = 256;
glDeleteLists(listBase, glyphCount);
}
END_NAMESPACE