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