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 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*!
  2. * \file src/FontTRLE.cpp
  3. * \brief SDL Font implementation
  4. *
  5. * \author xythobuz
  6. */
  7. #include <fstream>
  8. #include <sstream>
  9. #include <stdexcept>
  10. #include "global.h"
  11. #include "utils/strings.h"
  12. #include "FontTRLE.h"
  13. FontTRLE::FontTRLE() {
  14. mFontInit = false;
  15. mFontTexture = 0;
  16. }
  17. FontTRLE::~FontTRLE() {
  18. }
  19. int FontTRLE::initialize() {
  20. assert(mFontInit == false);
  21. assert(stringEndsWith(mFontName, ".pc") == true);
  22. // Load .pc file...
  23. std::ifstream file(mFontName, std::ios::in | std::ios::binary);
  24. unsigned char *pixels = new unsigned char[256 * 256 * 4];
  25. if (!file.read((char *)pixels, 256 * 256 * 4)) {
  26. delete [] pixels;
  27. return -1;
  28. }
  29. // Fix coloring
  30. for (unsigned int i = 0; i < (256 * 256 * 4); i += 4) {
  31. float y = (0.2126f * pixels[i + 2]);
  32. y += (0.7152f * pixels[i + 1]);
  33. y += (0.0722f * pixels[i]);
  34. pixels[i] = pixels[i + 1] = pixels[i + 2] = (unsigned char)y;
  35. }
  36. // ...into GL texture
  37. glGenTextures(1, &mFontTexture);
  38. glBindTexture(GL_TEXTURE_2D, mFontTexture);
  39. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  40. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  41. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
  42. delete [] pixels;
  43. // Try to load .lps file, overwriting default glyph positions
  44. std::string lpsFile = findAndReplace(mFontName, ".pc", ".lps");
  45. loadLPS(lpsFile);
  46. mFontInit = true;
  47. return 0;
  48. }
  49. void FontTRLE::loadLPS(std::string f) {
  50. std::ifstream file(f);
  51. if (!file)
  52. return;
  53. /*!
  54. * \todo This is probably the worlds most unreliable parser...
  55. */
  56. for (std::string line; std::getline(file, line);) {
  57. std::istringstream stream(line);
  58. int index;
  59. stream >> index;
  60. if (stream.get() != '=')
  61. continue;
  62. stream >> offsets[index][0];
  63. if (stream.get() != ',')
  64. continue;
  65. stream >> offsets[index][1];
  66. if (stream.get() != ',')
  67. continue;
  68. stream >> offsets[index][2];
  69. if (stream.get() != ',')
  70. continue;
  71. stream >> offsets[index][3];
  72. if (stream.get() != ',')
  73. continue;
  74. stream >> offsets[index][4];
  75. }
  76. }
  77. #define SCALING 2.0f
  78. void FontTRLE::writeChar(unsigned int index, unsigned int xDraw, unsigned int yDraw,
  79. float scale, const unsigned char color[4]) {
  80. assert(mFontInit == true);
  81. int width = (int)(((float)offsets[index][2]) * scale * SCALING);
  82. int height = (int)(((float)offsets[index][3]) * scale * SCALING);
  83. int offset = (int)(((float)offsets[index][4]) * scale * SCALING);
  84. // screen coordinates
  85. int xMin = xDraw;
  86. int yMin = ((int)yDraw) + offset + (int)(10.0f * scale * SCALING);
  87. int xMax = xMin + width;
  88. int yMax = yMin + height;
  89. // texture part
  90. float txMin = ((float)offsets[index][0]) / 256.0f;
  91. float txMax = ((float)(offsets[index][0] + offsets[index][2])) / 256.0f;
  92. float tyMin = ((float)offsets[index][1]) / 256.0f;
  93. float tyMax = ((float)(offsets[index][1] + offsets[index][3])) / 256.0f;
  94. // draw
  95. glBindTexture(GL_TEXTURE_2D, mFontTexture);
  96. glColor4f(color[0] * 256.0f, color[1] * 256.0f, color[2] * 256.0f, color[3] * 256.0f);
  97. glBegin(GL_QUADS);
  98. glTexCoord2f(txMin, tyMin);
  99. glVertex2i(xMin, yMin);
  100. glTexCoord2f(txMin, tyMax);
  101. glVertex2i(xMin, yMax);
  102. glTexCoord2f(txMax, tyMax);
  103. glVertex2i(xMax, yMax);
  104. glTexCoord2f(txMax, tyMin);
  105. glVertex2i(xMax, yMin);
  106. glEnd();
  107. }
  108. unsigned int FontTRLE::widthText(float scale, std::string s) {
  109. assert(mFontInit == true);
  110. assert(s.length() > 0);
  111. unsigned int width = 0;
  112. for (unsigned int i = 0; i < s.length(); i++) {
  113. // index into offset table
  114. int index = s[i] - '!';
  115. if (index == -1) // space
  116. width += (unsigned int)(14.0f * scale * SCALING);
  117. if ((index < 0) || (index > 105))
  118. continue; // skip unprintable chars
  119. width += (float)(offsets[index][2] + 1) * scale * SCALING; // glyph width
  120. }
  121. return width;
  122. }
  123. void FontTRLE::drawText(unsigned int x, unsigned int y, float scale,
  124. const unsigned char color[4], std::string s) {
  125. assert(mFontInit == true);
  126. assert(s.length() > 0);
  127. for (unsigned int i = 0; i < s.length(); i++) {
  128. // index into offset table
  129. int index = s[i] - '!';
  130. if (index == -1) // space
  131. x += (unsigned int)(14.0f * scale * SCALING);
  132. if ((index < 0) || (index > 105))
  133. continue; // skip unprintable chars
  134. writeChar((unsigned int)index, x, y, scale, color);
  135. x += (int)((float)(offsets[index][2] + 1) * scale * SCALING); // width
  136. }
  137. }
  138. unsigned int FontTRLE::heightText(float scale, unsigned int maxWidth, std::string s) {
  139. assert(mFontInit == true);
  140. assert(s.length() > 0);
  141. unsigned int x = 0;
  142. unsigned int yMax = 0;
  143. unsigned int yReturn = 0;
  144. for (unsigned int i = 0; i < s.length(); i++) {
  145. // index into offset table
  146. int index = s[i] - '!';
  147. if (index == -1) // space
  148. x += (unsigned int)(14.0f * scale * SCALING);
  149. if ((index < 0) || (index > 105))
  150. continue; // skip unprintable chars
  151. if (yMax < (unsigned int)(((float)offsets[index][3]) * scale * SCALING))
  152. yMax = (unsigned int)(((float)offsets[index][3]) * scale * SCALING);
  153. x += (int)((float)(offsets[index][2] + 1) * scale * SCALING); // width
  154. if (x > maxWidth) {
  155. // go to the next line
  156. yReturn += yMax + 2;
  157. yMax = 0;
  158. x = (int)((float)(offsets[index][2] + 1) * scale * SCALING);
  159. }
  160. }
  161. return yReturn + yMax + 2;
  162. }
  163. void FontTRLE::drawTextWrapped(unsigned int x, unsigned int y, float scale,
  164. const unsigned char color[4], unsigned int maxWidth, std::string s) {
  165. assert(mFontInit == true);
  166. assert(s.length() > 0);
  167. unsigned int xStart = x;
  168. unsigned int yMax = 0;
  169. for (unsigned int i = 0; i < s.length(); i++) {
  170. // index into offset table
  171. int index = s[i] - '!';
  172. if (index == -1) // space
  173. x += (unsigned int)(14.0f * scale * SCALING);
  174. if ((index < 0) || (index > 105))
  175. continue; // skip unprintable chars
  176. if (yMax < (unsigned int)(((float)offsets[index][3]) * scale * SCALING))
  177. yMax = (unsigned int)(((float)offsets[index][3]) * scale * SCALING);
  178. x += (int)((float)(offsets[index][2] + 1) * scale * SCALING); // width
  179. if ((x - xStart) > maxWidth) {
  180. // go to the next line
  181. y += yMax + 2;
  182. yMax = 0;
  183. x = xStart;
  184. } else {
  185. x -= (int)((float)(offsets[index][2] + 1) * scale * SCALING);
  186. }
  187. writeChar((unsigned int)index, x, y, scale, color);
  188. x += (int)((float)(offsets[index][2] + 1) * scale * SCALING); // width
  189. }
  190. }