#include <windows.h>
#include <gl\gl.h>
#include <stdio.h>
#include <math.h>
void remapColourRange(UCHAR *data, int numberOfItems) {
for(int i=0; i<numberOfItems; i++) {
data[i] = (data[i] * 255) / 64;
}
}
void copyLine(UCHAR *in, UCHAR *out, int width) {
for(int i=0; i<width; i++) {
out[i] = in[i];
}
}
void flipImage(UCHAR *data, int width, int height) {
//===========
UCHAR *temp;
DWORD offset;
DWORD offset2;
//===========
offset = 0;
offset2 = 0;
temp = new UCHAR[width];
for(int i=0; i<height/2; i++) {
offset = ((width+3) & ~3) * i;
copyLine(data+offset,temp,width); // copy bottom line
offset2 = ((width+3) & ~3) * (height-i-1);
copyLine(data+offset2,data+offset,width); // copy top line to bottom
copyLine(temp,data+offset2,width); // temp line to top
}
delete []temp;
}
void convertLine(UCHAR *in, UCHAR *out, int width) {
for(int i=0; i<width*4; i+=4) {
out[i+0] = 255;
out[i+1] = 255;
out[i+2] = 255;
out[i+3] = in[i/4];
}
}
void convertToRGB(UCHAR *in, UCHAR *out, int width, int height) {
//==========
int offset;
int offset2;
//==========
offset = (width+3) & ~3;
offset2 = (((width*4)+3) & ~3);
for(int i=0; i<height; i++) {
convertLine(in+(offset*i),out+(offset2*i),width);
}
}
BOOL createFont(HDC hdc, DWORD first, DWORD count, DWORD listBase) {
//===========================
GLYPHMETRICS gm;
MAT2 mat2;
DWORD size;
UCHAR *data;
UCHAR *RGBData;
//===========================
// safety checks
if(!count) return FALSE;
if(!hdc) return FALSE;
// initiate variables
size = 0;
data = NULL;
RGBData = NULL;
memset(&gm,0,sizeof(GLYPHMETRICS));
// identity matrix
memset(&mat2, 0, sizeof(mat2));
mat2.eM11.value = 1; mat2.eM21.value = 0;
mat2.eM12.value = 0; mat2.eM22.value = 1;
glPushAttrib(GL_PIXEL_MODE_BIT);
glPixelStorei(GL_UNPACK_ALIGNMENT,4);
for(DWORD i = 0 ; i< count; i++) {
glNewList(listBase+i,GL_COMPILE);
glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT);
// get size of the structure first
size = GetGlyphOutline(hdc,first+i,GGO_GRAY8_BITMAP, &gm, 0, NULL, &mat2);
if(size == GDI_ERROR) { glEndList(); continue; }
if(size) {
data = new UCHAR[size];
GetGlyphOutline(hdc,first+i,GGO_GRAY8_BITMAP,&gm,size,data,&mat2);
remapColourRange(data,size);
flipImage (data,gm.gmBlackBoxX,gm.gmBlackBoxY);
RGBData = new UCHAR[(((gm.gmBlackBoxX*4)+3) & ~3) * gm.gmBlackBoxY ];
convertToRGB(data,RGBData,gm.gmBlackBoxX,gm.gmBlackBoxY);
}
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBitmap (0,0,0,0,(GLfloat)gm.gmptGlyphOrigin.x,(GLfloat)gm.gmptGlyphOrigin.y-(GLfloat)gm.gmBlackBoxY,NULL); //incriment raster position
if(size) glDrawPixels(gm.gmBlackBoxX,gm.gmBlackBoxY, GL_RGBA, GL_UNSIGNED_BYTE, RGBData);
glBitmap (0,0,0,0,(GLfloat)-gm.gmptGlyphOrigin.x,-((GLfloat)gm.gmptGlyphOrigin.y-(GLfloat)gm.gmBlackBoxY),NULL); //incriment raster position
glBitmap (0,0,0,0,(GLfloat)gm.gmCellIncX,(GLfloat)gm.gmCellIncY,NULL); //incriment raster position
glDisable (GL_BLEND);
glPopAttrib ();
glEndList ();
delete []data;
delete []RGBData;
}
glPopAttrib ();
return TRUE;
}