txt.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <stdio.h>
  19. #include <math.h>
  20. #include "pot.h"
  21. #include "txt.h"
  22. #include "bsurface.h"
  23. #include "texture.h"
  24. #include "font.h"
  25. #include "nstrdup.h"
  26. TextTextureClass::TextTextureClass(void) :
  27. TextureString(NULL),
  28. Texture(NULL),
  29. TextureSize(0),
  30. ForegroundColor(0),
  31. BackgroundColor(0),
  32. Font(0),
  33. Convert(0)
  34. {
  35. }
  36. TextTextureClass::~TextTextureClass(void)
  37. {
  38. REF_PTR_RELEASE(Texture);
  39. if (TextureString) {
  40. delete[] TextureString;
  41. }
  42. }
  43. bool TextTextureClass::Is_Texture_Valid(FontClass &font, const char *str, int fore, int back, ConvertClass &conv)
  44. {
  45. // if there is no texture at all then obviously it is not valid
  46. if (!Texture) return false;
  47. // if all the parameters the texture was created with the last time are the same as the parameters the texture
  48. // was created with this time then the texture is fine!
  49. if (TextureString == str && Font == &font && Convert == &conv && ForegroundColor == fore && BackgroundColor == back)
  50. return true;
  51. return false;
  52. }
  53. bool TextTextureClass::Build_Texture(FontClass &font, const char *str, int fore, int back, ConvertClass &conv)
  54. {
  55. static char default_font_palette[] = {
  56. 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  57. };
  58. // right off determine if we need to rebuild the texture or the current texture
  59. // is just fine. If we are rebuilding store of the properties of the texture
  60. // we are building for next time.
  61. if (Is_Texture_Valid(font, str, fore, back, conv)) {
  62. return false;
  63. } else {
  64. if (TextureString) delete[] TextureString;
  65. Font = &font;
  66. TextureString = nstrdup(str);
  67. Convert = &conv;
  68. BackgroundColor = back;
  69. ForegroundColor = fore;
  70. }
  71. default_font_palette[0] = back;
  72. default_font_palette[1] = fore;
  73. // find the width and height of the text we want to display to the screen
  74. // note that the width could be more than the max width of a texture
  75. // so we must be prepared to break it down into blocks. Theoretically the
  76. // height could be greater than the texture max but lets not be ridiculous
  77. int fw = font.String_Pixel_Width(str)+1;
  78. int fh = font.Get_Height()+1;
  79. // Note: we are currently printing the text into
  80. // a rectangular buffer. We will later blit the text into a square buffer
  81. // since some cards require square textures.
  82. Rect rect(0,0,fw,fh);
  83. BSurface bsurf(fw, fh, 1);
  84. bsurf.Fill(0);
  85. font.Print(str, bsurf, rect, TPoint2D<int>(0,0), conv, (unsigned char *)default_font_palette);
  86. // figure out the size of the best texture which can hold the
  87. // text we wrote. Since textures need to be assumed to be square
  88. // the best size should be found by finding the rectangular surface
  89. // area of the text, and creating a Power of Two sized square which
  90. // can hold the data in the ractangular surface area.
  91. float fsize = sqrt(fw * fh);
  92. TextureSize = Find_POT(ceil(fsize));
  93. // If this is still not enough, quadruple area:
  94. if ((TextureSize / fh) * TextureSize < fw) {
  95. TextureSize *= 2;
  96. }
  97. // we now need to create a westwood style surface out of the surrender surface
  98. // so we can use all the westwood drawing primitives. Clear this surface to
  99. // black (shouldn't need to do this I dont think)
  100. BSurface bsurf2(TextureSize, TextureSize, 1);
  101. bsurf2.Fill(0);
  102. // we need to calculate how many texture pot widths it takes
  103. // to hold the width of our font.
  104. int mw = (fw & (TextureSize - 1)) ? (fw / TextureSize)+1 : (fw /TextureSize);
  105. // now we need to blit the old surface into the new surface (effectively
  106. // making the text in a square surface).
  107. for (int lp = 0; lp < mw; lp ++) {
  108. int blitw = MIN(fw - (TextureSize *lp), TextureSize);
  109. int lp_tsize = lp * TextureSize;
  110. Rect destrect(0,fh*lp,blitw,fh*lp+fh);
  111. Rect srcrect(lp_tsize, 0, lp_tsize + blitw, fh);
  112. /* original code
  113. d->blit(0, fh * lp, *s, lp_tsize, 0, lp_tsize + blitw, fh);
  114. */
  115. bsurf2.Blit_From(destrect,bsurf,srcrect);
  116. }
  117. // Create texture without mip mapping
  118. REF_PTR_RELEASE(Texture);
  119. // TODO: copy bsurf2 into texture
  120. return true;
  121. }