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

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