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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. mFontName = NULL;
  16. mFontTexture = 0;
  17. }
  18. FontTRLE::~FontTRLE() {
  19. }
  20. int FontTRLE::initialize() {
  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. int index;
  63. stream >> index;
  64. if (stream.get() != '=')
  65. continue;
  66. stream >> offsets[index][0];
  67. if (stream.get() != ',')
  68. continue;
  69. stream >> offsets[index][1];
  70. if (stream.get() != ',')
  71. continue;
  72. stream >> offsets[index][2];
  73. if (stream.get() != ',')
  74. continue;
  75. stream >> offsets[index][3];
  76. if (stream.get() != ',')
  77. continue;
  78. stream >> offsets[index][4];
  79. }
  80. }
  81. #define SCALING 2.0f
  82. void FontTRLE::writeChar(unsigned int index, unsigned int xDraw, FontString &s) {
  83. int width = (int)(((float)offsets[index][2]) * s.scale * SCALING);
  84. int height = (int)(((float)offsets[index][3]) * s.scale * SCALING);
  85. int offset = (int)(((float)offsets[index][4]) * s.scale * SCALING);
  86. // screen coordinates
  87. int xMin = xDraw;
  88. int yMin = s.y + offset + (int)(10.0f * s.scale * SCALING);
  89. int xMax = xMin + width;
  90. int yMax = yMin + height;
  91. // texture part
  92. float txMin = ((float)offsets[index][0]) / 256.0f;
  93. float txMax = ((float)(offsets[index][0] + offsets[index][2])) / 256.0f;
  94. float tyMin = ((float)offsets[index][1]) / 256.0f;
  95. float tyMax = ((float)(offsets[index][1] + offsets[index][3])) / 256.0f;
  96. // draw
  97. glBindTexture(GL_TEXTURE_2D, mFontTexture);
  98. glColor4f(s.color[0] * 256.0f, s.color[1] * 256.0f, s.color[2] * 256.0f, s.color[3] * 256.0f);
  99. glBegin(GL_QUADS);
  100. glTexCoord2f(txMin, tyMin);
  101. glVertex2i(xMin, yMin);
  102. glTexCoord2f(txMin, tyMax);
  103. glVertex2i(xMin, yMax);
  104. glTexCoord2f(txMax, tyMax);
  105. glVertex2i(xMax, yMax);
  106. glTexCoord2f(txMax, tyMin);
  107. glVertex2i(xMax, yMin);
  108. glEnd();
  109. }
  110. void FontTRLE::writeString(FontString &s) {
  111. assert(mFontInit == true);
  112. assert(s.text != NULL);
  113. unsigned int x = s.x;
  114. unsigned int y = 0;
  115. for (unsigned int i = 0; s.text[i] != '\0'; i++) {
  116. // index into offset table
  117. int index = s.text[i] - '!';
  118. if (index == -1) // space
  119. x += (unsigned int)(14.0f * s.scale * SCALING);
  120. if ((index < 0) || (index > 105))
  121. continue; // skip unprintable chars
  122. writeChar((unsigned int)index, x, s);
  123. x += (int)((float)(offsets[index][2] + 1) * s.scale * SCALING); // width
  124. if (y < (unsigned int)(((float)offsets[index][3]) * s.scale * SCALING))
  125. y = (unsigned int)(((float)offsets[index][3]) * s.scale * SCALING);
  126. }
  127. s.w = x - s.x;
  128. s.h = y;
  129. }