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

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