Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FontTRLE.cpp 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*!
  2. * \file src/FontTRLE.cpp
  3. * \brief SDL Font implementation
  4. *
  5. * \author xythobuz
  6. */
  7. #include <fstream>
  8. #include <sstream>
  9. #include "global.h"
  10. #include "utils/strings.h"
  11. #include "FontTRLE.h"
  12. FontTRLE::FontTRLE() {
  13. mFontInit = false;
  14. mFontName = NULL;
  15. mFontTexture = 0;
  16. tempText.text = new char[256];
  17. tempText.color[0] = 0xFF;
  18. tempText.color[1] = 0xFF;
  19. tempText.color[2] = 0xFF;
  20. tempText.color[3] = 0xFF;
  21. tempText.scale = 1.2f;
  22. tempText.w = 0;
  23. tempText.h = 0;
  24. }
  25. FontTRLE::~FontTRLE() {
  26. delete [] tempText.text;
  27. tempText.text = NULL;
  28. }
  29. int FontTRLE::initialize() {
  30. //! \todo Font coloring not working when .pc has color?!?!
  31. assert(mFontInit == false);
  32. assert(mFontName != NULL);
  33. assert(mFontName[0] != '\0');
  34. assert(stringEndsWith(mFontName, ".pc") == true);
  35. // Load .pc file...
  36. std::ifstream file(mFontName, std::ios::in | std::ios::binary);
  37. unsigned char *pixels = new unsigned char[256 * 256 * 4];
  38. if (!file.read((char *)pixels, 256 * 256 * 4)) {
  39. delete [] pixels;
  40. return -1;
  41. }
  42. // ...into GL texture
  43. glGenTextures(1, &mFontTexture);
  44. glBindTexture(GL_TEXTURE_2D, mFontTexture);
  45. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  46. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  47. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
  48. delete [] pixels;
  49. // Try to load .lps file, overwriting default glyph positions
  50. char *lpsFile = stringReplace(mFontName, ".pc", ".lps");
  51. loadLPS(lpsFile);
  52. delete [] lpsFile;
  53. mFontInit = true;
  54. return 0;
  55. }
  56. void FontTRLE::loadLPS(const char *f) {
  57. std::ifstream file(f);
  58. if (!file)
  59. return;
  60. /*!
  61. * \todo This is probably the worlds most unreliable parser...
  62. */
  63. for (std::string line; std::getline(file, line);) {
  64. std::istringstream stream(line);
  65. std::string tok1, tok2;
  66. std::getline(stream, tok1, '=');
  67. std::getline(stream, tok2);
  68. // we are only interested in lines starting with
  69. // xxx=
  70. // Where xxx is a 3 digit number
  71. try {
  72. int index = std::stoi(tok1);
  73. if ((index >= 0) && (index <= 105)) {
  74. std::istringstream row(tok2);
  75. std::string a, b, c, d, e;
  76. std::getline(row, a, ',');
  77. std::getline(row, b, ',');
  78. std::getline(row, c, ',');
  79. std::getline(row, d, ',');
  80. std::getline(row, e);
  81. offsets[index][0] = std::stoi(a);
  82. offsets[index][1] = std::stoi(b);
  83. offsets[index][2] = std::stoi(c);
  84. offsets[index][3] = std::stoi(d);
  85. offsets[index][4] = std::stoi(e);
  86. }
  87. } catch (std::invalid_argument) {
  88. }
  89. }
  90. }
  91. #define SCALING 2.0f
  92. void FontTRLE::writeChar(unsigned int index, unsigned int xDraw, FontString &s) {
  93. int width = (int)(((vec_t)offsets[index][2]) * s.scale * SCALING);
  94. int height = (int)(((vec_t)offsets[index][3]) * s.scale * SCALING);
  95. int offset = (int)(((vec_t)offsets[index][4]) * s.scale * SCALING);
  96. // screen coordinates
  97. int xMin = xDraw;
  98. int yMin = s.y + offset + (int)(10.0f * s.scale * SCALING);
  99. int xMax = xMin + width;
  100. int yMax = yMin + height;
  101. // texture part
  102. vec_t txMin = ((vec_t)offsets[index][0]) / 256.0f;
  103. vec_t txMax = ((vec_t)(offsets[index][0] + offsets[index][2])) / 256.0f;
  104. vec_t tyMin = ((vec_t)offsets[index][1]) / 256.0f;
  105. vec_t tyMax = ((vec_t)(offsets[index][1] + offsets[index][3])) / 256.0f;
  106. // draw
  107. glBindTexture(GL_TEXTURE_2D, mFontTexture);
  108. glColor4f(s.color[0], s.color[1], s.color[2], s.color[3]);
  109. glBegin(GL_QUADS);
  110. glTexCoord2f(txMin, tyMin);
  111. glVertex2i(xMin, yMin);
  112. glTexCoord2f(txMin, tyMax);
  113. glVertex2i(xMin, yMax);
  114. glTexCoord2f(txMax, tyMax);
  115. glVertex2i(xMax, yMax);
  116. glTexCoord2f(txMax, tyMin);
  117. glVertex2i(xMax, yMin);
  118. glEnd();
  119. }
  120. void FontTRLE::writeString(FontString &s) {
  121. assert(mFontInit == true);
  122. assert(s.text != NULL);
  123. unsigned int x = s.x;
  124. for (unsigned int i = 0; s.text[i] != '\0'; i++) {
  125. // index into offset table
  126. int index = s.text[i] - '!';
  127. if (index == -1) // space
  128. x += (unsigned int)(14.0f * s.scale * SCALING);
  129. if ((index < 0) || (index > 105))
  130. continue; // skip unprintable chars
  131. writeChar((unsigned int)index, x, s);
  132. x += (int)((vec_t)(offsets[index][2] + 1) * s.scale * SCALING); // width
  133. }
  134. // TODO scaling?!
  135. s.w = x;
  136. /*
  137. s.w = (int)((float)surface->w * s.scale * SCALING);
  138. s.h = (int)((float)surface->h * s.scale * SCALING);
  139. */
  140. }
  141. void FontTRLE::drawText(unsigned int x, unsigned int y, float scale, const float color[4], const char *s, ...) {
  142. va_list args;
  143. va_start(args, s);
  144. vsnprintf(tempText.text, 256, s, args);
  145. tempText.text[255] = '\0';
  146. va_end(args);
  147. tempText.scale = scale;
  148. tempText.x = x;
  149. tempText.y = y;
  150. if (color) {
  151. tempText.color[0] = color[0];
  152. tempText.color[1] = color[1];
  153. tempText.color[2] = color[2];
  154. tempText.color[3] = color[3];
  155. }
  156. writeString(tempText);
  157. }