Newer
Older
invertedlogic / InvertedLogic / iLFramework / toolkit / src / GL / Font.cpp
@John Ryland John Ryland on 10 Nov 2019 4 KB rename
// 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