Font.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include <string.h>
  2. #include <zlib.h>
  3. #include <cstdio>
  4. #include <cstdarg>
  5. #include "Font.h"
  6. #include "utility/misc.h"
  7. using WalrusRPG::Graphics::Font;
  8. using WalrusRPG::Graphics::CharacterParameters;
  9. using WalrusRPG::Graphics::Texture;
  10. using WalrusRPG::Graphics::Pixel;
  11. Font::Font(Texture &font_tex, WalrusRPG::PIAF::File font_config)
  12. : baseline(0), space_width(1), font_tex(font_tex)
  13. {
  14. const uint8_t *ptr = font_config.get();
  15. // TODO : parse file
  16. // TODO : forgot to put the version and the font type
  17. if (strncmp((const char *) ptr, "WFONT", 4) != 0)
  18. {
  19. // TODO : wrong header
  20. }
  21. uint32_t expected_checksum = read_big_endian_value<uint32_t>(&ptr[4]);
  22. uint32_t calculated_checksum =
  23. crc32(0L, (const unsigned char *) (&ptr[8]), font_config.file_size - 8);
  24. if (expected_checksum != calculated_checksum)
  25. {
  26. // printf("Bad checksum : %x != %x\n", expected_checksum, calculated_checksum);
  27. }
  28. baseline = read_big_endian_value<uint8_t>(&ptr[12]);
  29. space_width = read_big_endian_value<uint32_t>(&ptr[20]);
  30. // Stupid thing to accelerate a biiiit the font loading, I think.
  31. uint8_t *current_char = (uint8_t *) ptr + 24;
  32. for (int i = 0; i < 256; ++i)
  33. {
  34. chars[i].dimensions.x = read_big_endian_value<int16_t>(current_char);
  35. chars[i].dimensions.y = read_big_endian_value<int16_t>(current_char + 2);
  36. chars[i].dimensions.width = read_big_endian_value<uint16_t>(current_char + 4);
  37. chars[i].dimensions.height = read_big_endian_value<uint16_t>(current_char + 6);
  38. chars[i].x_offset = read_big_endian_value<int16_t>(current_char + 8);
  39. chars[i].y_offset = read_big_endian_value<int16_t>(current_char + 10);
  40. current_char += (6 * sizeof(uint16_t));
  41. }
  42. }
  43. Font::~Font()
  44. {
  45. }
  46. void Font::draw(uint16_t x, uint16_t y, const char c) const
  47. {
  48. uint8_t c2 = (uint8_t) c;
  49. put_sprite(font_tex, x + chars[c2].x_offset, y + chars[c2].y_offset,
  50. chars[c2].dimensions);
  51. }
  52. void Font::draw(uint16_t x, uint16_t y, const char c, const Pixel &col) const
  53. {
  54. uint8_t c2 = (uint8_t) c;
  55. put_sprite_tint(font_tex, x + chars[c2].x_offset, y + chars[c2].y_offset,
  56. chars[c2].dimensions, col);
  57. }
  58. void Font::draw(uint16_t x, uint16_t y, const char *str) const
  59. {
  60. for (unsigned i = 0; str[i] && x < 320; i++)
  61. {
  62. unsigned char c = str[i];
  63. if (c == 32)
  64. {
  65. x += space_width;
  66. continue;
  67. }
  68. draw(x, y, c);
  69. x += chars[c].dimensions.width + 1;
  70. }
  71. }
  72. void Font::draw(uint16_t x, uint16_t y, const char *str, const Pixel &col) const
  73. {
  74. for (unsigned i = 0; str[i] && x < 320; i++)
  75. {
  76. unsigned char c = str[i];
  77. if (c == 32)
  78. {
  79. x += space_width;
  80. continue;
  81. }
  82. draw(x, y, c, col);
  83. x += chars[c].dimensions.width + 1;
  84. }
  85. }
  86. void Font::draw_format(uint16_t x, uint16_t y, const char *format, ...) const
  87. {
  88. char buffer[513] = {0};
  89. va_list args;
  90. va_start(args, format);
  91. int size = std::vsnprintf(buffer, 512, format, args);
  92. va_end(args);
  93. if (size < 0)
  94. return;
  95. draw(x, y, buffer);
  96. }
  97. void Font::draw_format(uint16_t x, uint16_t y, const Pixel &col, const char *format,
  98. ...) const
  99. {
  100. char buffer[513] = {0};
  101. va_list args;
  102. va_start(args, format);
  103. int size = std::vsnprintf(buffer, 512, format, args);
  104. va_end(args);
  105. if (size < 0)
  106. return;
  107. draw(x, y, buffer, col);
  108. }