Font.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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 "Font.h"
  21. #include <font/GlyphData.h>
  22. #include <common/math.h>
  23. #include <math.h>
  24. namespace love
  25. {
  26. namespace graphics
  27. {
  28. namespace opengl
  29. {
  30. Font::Font(love::font::FontData * data)
  31. : height(data->getHeight()), lineHeight(1.25), mSpacing(1)
  32. {
  33. glyphs = new Glyph*[MAX_CHARS];
  34. type = FONT_UNKNOWN;
  35. love::font::GlyphData * gd;
  36. for(unsigned int i = 0; i < MAX_CHARS; i++)
  37. {
  38. gd = data->getGlyphData(i);
  39. glyphs[i] = new Glyph(gd);
  40. glyphs[i]->load();
  41. widths[i] = gd->getWidth();
  42. spacing[i] = gd->getAdvance();
  43. bearingX[i] = gd->getBearingX();
  44. bearingY[i] = gd->getBearingY();
  45. if (type == FONT_UNKNOWN) type = (gd->getFormat() == love::font::GlyphData::FORMAT_LUMINANCE_ALPHA ? FONT_TRUETYPE : FONT_IMAGE);
  46. }
  47. }
  48. Font::~Font()
  49. {
  50. for(unsigned int i = 0; i < MAX_CHARS; i++)
  51. {
  52. glyphs[i]->release();
  53. }
  54. delete[] glyphs;
  55. }
  56. float Font::getHeight() const
  57. {
  58. return height / lineHeight;
  59. }
  60. void Font::print(std::string text, float x, float y) const
  61. {
  62. print(text, x, y, 0.0f, 1.0f, 1.0f);
  63. }
  64. void Font::print(std::string text, float x, float y, float angle, float sx, float sy) const
  65. {
  66. float dx = 0.0f; // spacing counter for newline handling
  67. glPushMatrix();
  68. glTranslatef(ceil(x), ceil(y), 0.0f);
  69. glRotatef(LOVE_TODEG(angle), 0, 0, 1.0f);
  70. glScalef(sx, sy, 1.0f);
  71. for (unsigned int i = 0; i < text.size(); i++) {
  72. unsigned char g = (unsigned char)text[i];
  73. if (g == '\n') { // wrap newline, but do not print it
  74. glTranslatef(-dx, floor(getHeight() + 0.5f), 0);
  75. dx = 0.0f;
  76. continue;
  77. }
  78. if (!glyphs[g]) g = 32; // space
  79. glPushMatrix();
  80. if (type == FONT_TRUETYPE) glTranslatef(0, floor(getHeight() + 0.5f), 0);
  81. glyphs[g]->draw(0, 0, 0, 1, 1, 0, 0);
  82. glPopMatrix();
  83. glTranslatef(spacing[g], 0, 0);
  84. dx += spacing[g];
  85. }
  86. glPopMatrix();
  87. }
  88. void Font::print(char character, float x, float y) const
  89. {
  90. if (!glyphs[character]) character = ' ';
  91. glPushMatrix();
  92. glTranslatef(x, floor(y+getHeight() + 0.5f), 0.0f);
  93. glCallList(list+character);
  94. glPopMatrix();
  95. }
  96. int Font::getWidth(const std::string & line) const
  97. {
  98. if(line.size() == 0) return 0;
  99. int temp = 0;
  100. for(unsigned int i = 0; i < line.size(); i++)
  101. {
  102. temp += (spacing[(int)line[i]] * mSpacing);
  103. }
  104. return temp;
  105. }
  106. int Font::getWidth(const char * line) const
  107. {
  108. return this->getWidth(std::string(line));
  109. }
  110. int Font::getWidth(const char character) const
  111. {
  112. return spacing[(int)character];
  113. }
  114. int Font::getWrap(const std::string & line, float wrap, int * lines) const
  115. {
  116. if(line.size() == 0) return 0;
  117. int maxw = 0;
  118. int linen = 1;
  119. int temp = 0;
  120. std::string text;
  121. for(unsigned int i = 0; i < line.size(); i++)
  122. {
  123. if(temp > wrap && text.find(" ") != std::string::npos)
  124. {
  125. unsigned int space = text.find_last_of(' ');
  126. std::string tmp = text.substr(0, space);
  127. int w = getWidth(tmp);
  128. if(w > maxw) maxw = w;
  129. text = text.substr(space+1);
  130. temp = getWidth(text);
  131. linen++;
  132. }
  133. temp += (spacing[(int)line[i]] * mSpacing);
  134. text += line[i];
  135. }
  136. if(temp > maxw) maxw = temp;
  137. if(lines) *lines = linen;
  138. return maxw;
  139. }
  140. int Font::getWrap(const char * line, float wrap, int * lines) const
  141. {
  142. return getWrap(std::string(line), wrap, lines);
  143. }
  144. void Font::setLineHeight(float height)
  145. {
  146. this->lineHeight = height;
  147. }
  148. float Font::getLineHeight() const
  149. {
  150. return lineHeight;
  151. }
  152. void Font::setSpacing(float amount)
  153. {
  154. mSpacing = amount;
  155. }
  156. float Font::getSpacing() const
  157. {
  158. return mSpacing;
  159. }
  160. bool Font::loadVolatile()
  161. {
  162. // reload all glyphs
  163. for(unsigned int i = 0; i < MAX_CHARS; i++)
  164. {
  165. glyphs[i]->load();
  166. glNewList(list + i, GL_COMPILE);
  167. glyphs[i]->draw(0, 0, 0, 1, 1, 0, 0);
  168. glEndList();
  169. }
  170. return true;
  171. }
  172. void Font::unloadVolatile()
  173. {
  174. // delete the glyphs
  175. glDeleteLists(list, MAX_CHARS);
  176. }
  177. } // opengl
  178. } // graphics
  179. } // love