1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
#include "fontsystem.h"
namespace NGUI
{
CFont::CFont()
{
SetupFont();
}
CFont::~CFont() {}
template<typename tChar>
char* CFont::DrawString(tChar *apString, int aiSize, int aiX, int aiY)
{
// Search the string from most significant character to least significant.
int iSelectIndex = 0;
for(size_t i = 0; apString[i] != NULL; ++i)
{
iSelectIndex = apString[i] >= '0' && apString[i] <= '9' ? (apString[i] - '0') :
apString[i] >= 'A' && apString[i] <= 'Z' ? (apString[i] - 'A' + 10) :
apString[i] >= 'a' && apString[i] <= 'z' ? (apString[i] - 'a' + 10) :
apString[i] == ' ' ? 36 : // This is a special case, This see's if the current character is a space or not.
-1;
if(iSelectIndex == -1)
{
return "The String Is Corrupt! Aborting!";
}
// Add the current selected character to the drawing array.
miDrawIDs[i] = iSelectIndex;
}
// Go through and draw each and every character.
for(size_t i = 0; i < DIM(miDrawIDs); ++i)
{
// Paint each qaud with the X,Y coordinates. After each quad has been successfully drawn,
// Add the size to the X coordinate. NOTE: Each character is square!!!
if(miDrawIDs[i] != 36)
{
glBindTexture(GL_TEXTURE_2D, miDrawIDs[i]);
}
// The font color is always white.
glColor4f(1.0, 1.0, 1.0, 0.0); // The alpha argument in the function call is set to 0 to allow color only where image data is present.
glBegin(GL_QUADS);
glTexCoord2i(0, 0);
glVertex2i(aiX, aiY);
glTexCoord2i(1, 0);
glVertex2i(aiX + aiSize, aiY);
glTexCoord2i(1, 1);
glVertex2i(aiX + aiSize, aiY + aiSize);
glTexCoord2i(0, 1);
glVertex2i(aiX, aiY + aiSize);
glEnd();
// Now, increase the X position by the size.
aiX += aiSize;
}
return "Successful Drawing of String!";
}
template<typename tNum>
char* CFont::DrawString(tNum anNumber, int aiSize, int aiX, int aiY)
{
// Convert the supplied number to a character string via snprintf().
char *vTempString = new char[1024];
snprintf(vTempString, 1024, "%f", anNumber);
// Next, run DrawString().
return DrawString<char>(vTempString, aiSize, aiX, aiY);
}
char* CFont::SetupFont()
{
// First Load The PNG file holding the font.
FreeImage_Initialise(false);
FIBITMAP *spBitmap = FreeImage_Load(FIF_PNG, "Font.png", BMP_DEFAULT);
if(!spBitmap)
{
return "Was Unable To Open/Decode Bitmap!";
}
// Do an image sanity check.
if(!FreeImage_HasPixels(spBitmap))
{
return "The Image doesn't contain any pixel data! Aborting!";
}
// The Image will have the red and blue channel reversed, so we need to correct them.
SwapRedBlue32(spBitmap);
// Retrieve all the image data from FreeImage.
unsigned char *pData = FreeImage_GetBits(spBitmap);
int iWidth = FreeImage_GetWidth(spBitmap);
// Cutup the PNG.
int iFontElementSize = (32*32)*4; // The first two numbers, are the dimensions fo the element, the last number (4) is the number of color channels (Red Green Blue and Alpha)
bool bDone = false; // This bit is only set when the entire image has been loaded.
unsigned char *pElemBuff = new unsigned char[iFontElementSize]; // The temporary element buffer.
int iDataSeek = 4; // Start with an offset of 4 because the first byte of image data starts there.
int iTexIdx = 0; // This is an offset specifing which texture to create/bind to.
// Create all 36 OpenGL texures. 0-9 and A-Z and finally space (' ')
glGenTextures(37, miTextIDs);
while(!bDone)
{
// Now load the an element into the buffer.
for(int i = 0, iXCount = 0, iYCount = 0;
i < iFontElementSize; ++i, ++iXCount)
{
if(iXCount >= (32*4))
{
iXCount = 0; // Reset the column offset.
++iYCount; // Move down 1 row.
iDataSeek += ((iWidth * 4) - (32*4)); // Set the data seek to the next corrosponding piece of image data.
}
if(pData[iDataSeek] == NULL)
{
break;
}
pElemBuff[i] = pData[iDataSeek];
}
// Check to see if we are done loading to prevent memory corruption and leakage.
if(bDone || iTexIdx >= 37)
{
break;
}
// Create The OpenGL Texture with the current Element.
glBindTexture(GL_TEXTURE_2D, miTextIDs[iTexIdx]);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, 32, 32, GL_RGBA, GL_UNSIGNED_BYTE, pElemBuff);
// Create the correct texture envirnment to the current texture.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
}
// Do a little house cleaning!
delete[] pElemBuff;
delete pData;
FreeImage_Unload(spBitmap);
FreeImage_DeInitialise();
}
}
|