ImageFont.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /**
  2. * Copyright (c) 2006-2010 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #include "ImageFont.h"
  21. #include <common/math.h>
  22. #include <SDL_opengl.h>
  23. namespace love
  24. {
  25. namespace graphics
  26. {
  27. namespace opengl
  28. {
  29. ImageFont::ImageFont(Image * image, const std::string& glyphs)
  30. : Font(0), image(image), glyphs(glyphs)
  31. {
  32. image->retain();
  33. }
  34. ImageFont::~ImageFont()
  35. {
  36. unload();
  37. image->release();
  38. }
  39. void ImageFont::print(std::string text, float x, float y) const
  40. {
  41. glPushMatrix();
  42. glTranslatef(x, y, 0.0f);
  43. GLuint OpenGLFont = list;
  44. glListBase(OpenGLFont);
  45. glCallLists((int)text.length(), GL_UNSIGNED_BYTE, text.c_str());
  46. glPopMatrix();
  47. }
  48. void ImageFont::print(std::string text, float x, float y, float angle, float sx, float sy) const
  49. {
  50. glPushMatrix();
  51. glTranslatef(x, y, 0.0f);
  52. glRotatef(LOVE_TORAD(angle), 0, 0, 1.0f);
  53. glScalef(sx, sy, 1.0f);
  54. GLuint OpenGLFont = list;
  55. glListBase(OpenGLFont);
  56. glCallLists((int)text.length(), GL_UNSIGNED_BYTE, text.c_str());
  57. glPopMatrix();
  58. }
  59. void ImageFont::print(char character, float x, float y) const
  60. {
  61. glPushMatrix();
  62. glTranslatef(x, y, 0.0f);
  63. GLuint OpenGLFont = list;
  64. glListBase(OpenGLFont);
  65. glCallList(list + (int)character);
  66. glPopMatrix();
  67. }
  68. bool ImageFont::load()
  69. {
  70. return loadVolatile();
  71. }
  72. void ImageFont::unload()
  73. {
  74. unloadVolatile();
  75. }
  76. bool ImageFont::loadVolatile()
  77. {
  78. love::image::pixel * pixels = (love::image::pixel *)(image->getData()->getData());
  79. unsigned imgw = (unsigned)image->getWidth();
  80. unsigned imgh = (unsigned)image->getHeight();
  81. unsigned imgs = imgw*imgh;
  82. // Reading texture data begins
  83. size = imgh;
  84. for(unsigned int i = 0; i < MAX_CHARS; i++)
  85. positions[i] = -1;
  86. love::image::pixel spacer = pixels[0];
  87. unsigned num = glyphs.size();
  88. unsigned start = 0;
  89. unsigned end = 0;
  90. unsigned space = 0;
  91. for(unsigned i = 0; i < num; ++i)
  92. {
  93. if(i >= MAX_CHARS)
  94. break;
  95. start = end;
  96. // Finds out where the first character starts
  97. while(start < imgw && equal(pixels[start], spacer))
  98. ++start;
  99. if(i > 0)
  100. spacing[glyphs[i - 1]] = (start > end) ? (start - end) : 0;
  101. end = start;
  102. // Find where glyph ends.
  103. while(end < imgw && !equal(pixels[end], spacer))
  104. ++end;
  105. if(start >= end)
  106. break;
  107. unsigned c = glyphs[i];
  108. positions[c] = start;
  109. widths[c] = (end - start);
  110. }
  111. // Replace spacer color with an empty pixel
  112. for(unsigned int i = 0; i < imgs; ++i)
  113. {
  114. if(equal(pixels[i], spacer))
  115. {
  116. pixels[i].r = 0;
  117. pixels[i].g = 0;
  118. pixels[i].b = 0;
  119. pixels[i].a = 0;
  120. }
  121. }
  122. // Create display lists
  123. list = glGenLists(MAX_CHARS);
  124. for(unsigned int i = 0; i < MAX_CHARS; i++)
  125. {
  126. glNewList(list + i, GL_COMPILE);
  127. if(positions[i] != -1)
  128. {
  129. Quad::Viewport v;
  130. v.x = positions[i];
  131. v.y = 0;
  132. v.w = widths[i];
  133. v.h = imgh;
  134. Quad q(v, imgw, imgh);
  135. image->drawq(&q, 0, 0, 0, 1, 1, 0, 0);
  136. glTranslatef((float)widths[i] + ((float)spacing[i] * mSpacing), 0, 0);
  137. }
  138. else
  139. glTranslatef((float)widths[(int)' '], 0, 0); // empty character are replaced with a whitespace
  140. glEndList();
  141. }
  142. return true;
  143. }
  144. void ImageFont::unloadVolatile()
  145. {
  146. glDeleteLists(list, MAX_CHARS);
  147. }
  148. bool ImageFont::equal(const love::image::pixel& a, const love::image::pixel& b)
  149. {
  150. return (a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a);
  151. }
  152. int ImageFont::next_p2(int num)
  153. {
  154. int powered = 2;
  155. while(powered < num) powered <<= 1;
  156. return powered;
  157. }
  158. } // opengl
  159. } // graphics
  160. } // love