leocad/common/texfont.cpp
2011-09-07 21:06:51 +00:00

160 lines
4 KiB
C++

//
// Texture Font
//
#include "globals.h"
#include "project.h"
#include "texfont.h"
#include "texture.h"
#include "library.h"
#include "file.h"
#include "lc_application.h"
#define LC_TEXFONT_FILE_VERSION 1 // LeoCAD 0.74
#define LC_TEXFONT_FILE_HEADER "LeoCAD Texture Font\0\0\0\0\0\0\0\0\0\0\0\0"
// ============================================================================
TexFont::TexFont ()
{
m_bLoaded = false;
m_pTexture = NULL;
memset (&m_Glyphs, 0, sizeof (m_Glyphs));
}
TexFont::~TexFont ()
{
if (m_pTexture != NULL)
m_pTexture->DeRef ();
}
bool TexFont::FileLoad (File& file)
{
unsigned char version;
char buf[64];
if (m_bLoaded)
{
console.PrintError ("Texture font already loaded.\n");
return false;
}
file.Read (buf, 32);
if (strncmp (buf, LC_TEXFONT_FILE_HEADER, 32) != 0)
{
console.PrintError ("Texture font file header mismatch.\n");
return false;
}
file.ReadByte (&version, 1);
if (version > LC_TEXFONT_FILE_VERSION)
{
console.PrintError ("Wrong version of texture font file.\n");
return false;
}
memset (buf, 0, 32);
file.Read (buf, 8);
m_pTexture = lcGetPiecesLibrary()->FindTexture (buf);
if (m_pTexture == NULL)
{
console.PrintError ("Cannot find texture for font %s.\n", buf);
return false;
}
m_pTexture->AddRef (false);
file.ReadByte (&m_nFontHeight, 1);
for (;;)
{
unsigned char glyph;
file.ReadByte (&glyph, 1);
if (glyph == 0)
break;
file.ReadByte (&m_Glyphs[glyph].width, 1);
file.ReadFloat (&m_Glyphs[glyph].left, 1);
file.ReadFloat (&m_Glyphs[glyph].right, 1);
file.ReadFloat (&m_Glyphs[glyph].top, 1);
file.ReadFloat (&m_Glyphs[glyph].bottom, 1);
m_Glyphs[glyph].left /= m_pTexture->m_nWidth;
m_Glyphs[glyph].right /= m_pTexture->m_nWidth;
m_Glyphs[glyph].top /= m_pTexture->m_nHeight;
m_Glyphs[glyph].bottom /= m_pTexture->m_nHeight;
}
m_bLoaded = true;
return true;
}
void TexFont::GetStringDimensions(int* cx, int* cy, const char* Text) const
{
*cx = 0;
*cy = m_nFontHeight;
while (*Text != 0)
{
*cx += m_Glyphs[(int)(*Text)].width;
Text++;
}
}
void TexFont::PrintText(float Left, float Top, float ScaleX, float ScaleY, const char* Text) const
{
float Height = m_nFontHeight * ScaleY;
while (*Text != 0)
{
int ch = *Text;
glTexCoord2f(m_Glyphs[ch].left, m_Glyphs[ch].top);
glVertex2f(Left, Top);
glTexCoord2f(m_Glyphs[ch].left, m_Glyphs[ch].bottom);
glVertex2f(Left, Top - Height);
glTexCoord2f(m_Glyphs[ch].right, m_Glyphs[ch].bottom);
glVertex2f(Left + m_Glyphs[ch].width * ScaleX, Top - Height);
glTexCoord2f(m_Glyphs[ch].right, m_Glyphs[ch].top);
glVertex2f(Left + m_Glyphs[ch].width * ScaleX, Top);
Left += m_Glyphs[ch].width * ScaleX;
Text++;
}
}
// Old function, should probably be removed.
void TexFont::PrintText(float Left, float Top, float Z, const char* Text) const
{
while (*Text != 0)
{
int ch = *Text;
glTexCoord2f(m_Glyphs[ch].left, m_Glyphs[ch].top);
glVertex3f(Left, Top, Z);
glTexCoord2f(m_Glyphs[ch].left, m_Glyphs[ch].bottom);
glVertex3f(Left, Top - m_nFontHeight, Z);
glTexCoord2f(m_Glyphs[ch].right, m_Glyphs[ch].bottom);
glVertex3f(Left + m_Glyphs[ch].width, Top - m_nFontHeight, Z);
glTexCoord2f(m_Glyphs[ch].right, m_Glyphs[ch].top);
glVertex3f(Left + m_Glyphs[ch].width, Top, Z);
Left += m_Glyphs[ch].width;
Text++;
}
}
// Temporary function to draw the axis icon text
void TexFont::PrintCharScaled (float scale, int ch) const
{
glTexCoord2f (m_Glyphs[ch].left, m_Glyphs[ch].top);
glVertex2f (-scale * m_Glyphs[ch].width, scale * m_nFontHeight);
glTexCoord2f (m_Glyphs[ch].left, m_Glyphs[ch].bottom);
glVertex2f (-scale * m_Glyphs[ch].width, -scale * m_nFontHeight);
glTexCoord2f (m_Glyphs[ch].right, m_Glyphs[ch].bottom);
glVertex2f (scale * m_Glyphs[ch].width, -scale * m_nFontHeight);
glTexCoord2f (m_Glyphs[ch].right, m_Glyphs[ch].top);
glVertex2f (scale * m_Glyphs[ch].width, scale * m_nFontHeight);
}