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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. }
  17. FontTRLE::~FontTRLE() {
  18. }
  19. int FontTRLE::initialize() {
  20. assert(mFontInit == false);
  21. assert(mFontName != NULL);
  22. assert(mFontName[0] != '\0');
  23. assert(stringEndsWith(mFontName, ".pc") == true);
  24. // Load .pc file...
  25. std::ifstream file(mFontName, std::ios::in | std::ios::binary);
  26. unsigned char *pixels = new unsigned char[256 * 256 * 4];
  27. if (!file.read((char *)pixels, 256 * 256 * 4)) {
  28. delete [] pixels;
  29. return -1;
  30. }
  31. // Fix coloring
  32. for (unsigned int i = 0; i < (256 * 256 * 4); i += 4) {
  33. float y = (0.2126f * pixels[i + 2]);
  34. y += (0.7152f * pixels[i + 1]);
  35. y += (0.0722f * pixels[i]);
  36. pixels[i] = pixels[i + 1] = pixels[i + 2] = (unsigned char)y;
  37. }
  38. // ...into GL texture
  39. glGenTextures(1, &mFontTexture);
  40. glBindTexture(GL_TEXTURE_2D, mFontTexture);
  41. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  42. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  43. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
  44. delete [] pixels;
  45. // Try to load .lps file, overwriting default glyph positions
  46. char *lpsFile = stringReplace(mFontName, ".pc", ".lps");
  47. loadLPS(lpsFile);
  48. delete [] lpsFile;
  49. mFontInit = true;
  50. return 0;
  51. }
  52. void FontTRLE::loadLPS(const char *f) {
  53. std::ifstream file(f);
  54. if (!file)
  55. return;
  56. /*!
  57. * \todo This is probably the worlds most unreliable parser...
  58. */
  59. for (std::string line; std::getline(file, line);) {
  60. std::istringstream stream(line);
  61. std::string tok1, tok2;
  62. std::getline(stream, tok1, '=');
  63. std::getline(stream, tok2);
  64. // we are only interested in lines starting with
  65. // xxx=
  66. // Where xxx is a 3 digit number
  67. try {
  68. int index = std::stoi(tok1);
  69. if ((index >= 0) && (index <= 105)) {
  70. std::istringstream row(tok2);
  71. std::string a, b, c, d, e;
  72. std::getline(row, a, ',');
  73. std::getline(row, b, ',');
  74. std::getline(row, c, ',');
  75. std::getline(row, d, ',');
  76. std::getline(row, e);
  77. offsets[index][0] = std::stoi(a);
  78. offsets[index][1] = std::stoi(b);
  79. offsets[index][2] = std::stoi(c);
  80. offsets[index][3] = std::stoi(d);
  81. offsets[index][4] = std::stoi(e);
  82. }
  83. } catch (std::invalid_argument) {
  84. }
  85. }
  86. }
  87. #define SCALING 2.0f
  88. void FontTRLE::writeChar(unsigned int index, unsigned int xDraw, FontString &s) {
  89. int width = (int)(((vec_t)offsets[index][2]) * s.scale * SCALING);
  90. int height = (int)(((vec_t)offsets[index][3]) * s.scale * SCALING);
  91. int offset = (int)(((vec_t)offsets[index][4]) * s.scale * SCALING);
  92. // screen coordinates
  93. int xMin = xDraw;
  94. int yMin = s.y + offset + (int)(10.0f * s.scale * SCALING);
  95. int xMax = xMin + width;
  96. int yMax = yMin + height;
  97. // texture part
  98. vec_t txMin = ((vec_t)offsets[index][0]) / 256.0f;
  99. vec_t txMax = ((vec_t)(offsets[index][0] + offsets[index][2])) / 256.0f;
  100. vec_t tyMin = ((vec_t)offsets[index][1]) / 256.0f;
  101. vec_t tyMax = ((vec_t)(offsets[index][1] + offsets[index][3])) / 256.0f;
  102. // draw
  103. glBindTexture(GL_TEXTURE_2D, mFontTexture);
  104. glColor4f(s.color[0] * 256.0f, s.color[1] * 256.0f, s.color[2] * 256.0f, s.color[3] * 256.0f);
  105. glBegin(GL_QUADS);
  106. glTexCoord2f(txMin, tyMin);
  107. glVertex2i(xMin, yMin);
  108. glTexCoord2f(txMin, tyMax);
  109. glVertex2i(xMin, yMax);
  110. glTexCoord2f(txMax, tyMax);
  111. glVertex2i(xMax, yMax);
  112. glTexCoord2f(txMax, tyMin);
  113. glVertex2i(xMax, yMin);
  114. glEnd();
  115. }
  116. void FontTRLE::writeString(FontString &s) {
  117. assert(mFontInit == true);
  118. assert(s.text != NULL);
  119. unsigned int x = s.x;
  120. unsigned int y = 0;
  121. for (unsigned int i = 0; s.text[i] != '\0'; i++) {
  122. // index into offset table
  123. int index = s.text[i] - '!';
  124. if (index == -1) // space
  125. x += (unsigned int)(14.0f * s.scale * SCALING);
  126. if ((index < 0) || (index > 105))
  127. continue; // skip unprintable chars
  128. writeChar((unsigned int)index, x, s);
  129. x += (int)((vec_t)(offsets[index][2] + 1) * s.scale * SCALING); // width
  130. if (y < (unsigned int)(((vec_t)offsets[index][3]) * s.scale * SCALING))
  131. y = (unsigned int)(((vec_t)offsets[index][3]) * s.scale * SCALING);
  132. }
  133. s.w = x - s.x;
  134. s.h = y;
  135. }