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

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