summaryrefslogtreecommitdiff
path: root/common/texfont.cpp
blob: fa3fe0fe1b2f4aa19de34a4e2c743afbc389d162 (plain)
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
//
// Texture Font
//

#include "globals.h"
#include "project.h"
#include "texfont.h"
#include "texture.h"
#include "library.h"
#include "file.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 = project->GetPiecesLibrary()->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::PrintText (float left, float top, const char* text) const
{
  while (*text != 0)
  {
    glTexCoord2f (m_Glyphs[*text].left, m_Glyphs[*text].top);
    glVertex2f (left, top);
    glTexCoord2f (m_Glyphs[*text].left, m_Glyphs[*text].bottom);
    glVertex2f (left, top - m_nFontHeight);
    glTexCoord2f (m_Glyphs[*text].right, m_Glyphs[*text].bottom);
    glVertex2f (left + m_Glyphs[*text].width, top - m_nFontHeight);
    glTexCoord2f (m_Glyphs[*text].right, m_Glyphs[*text].top);
    glVertex2f (left + m_Glyphs[*text].width, top);

    left += m_Glyphs[*text].width;
    text++;
  }
}

// Temporary function to draw the axis icon text
void TexFont::PrintCharScaled (float scale, char 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);
}