Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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. }