PolyLabel.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * PolyLabel.cpp
  3. * Poly
  4. *
  5. * Created by Ivan Safrin on 3/16/08.
  6. * Copyright 2008 Ivan Safrin. All rights reserved.
  7. *
  8. */
  9. #include "PolyLabel.h"
  10. using namespace Polycode;
  11. #define NORMAL_FT_FLAGS FT_LOAD_TARGET_LIGHT
  12. Label::Label(Font *font, String text, int size, int antiAliasMode) {
  13. setPixelType(Image::IMAGE_RGBA);
  14. this->font = font;
  15. this->size = size;
  16. imageData = NULL;
  17. this->antiAliasMode = antiAliasMode;
  18. currentTextWidth = 0;
  19. currentTextHeight = 0;
  20. setText(text);
  21. }
  22. Label::~Label() {
  23. }
  24. int Label::getTextWidth(Font *font, String text, int size) {
  25. FT_Vector delta;
  26. FT_UInt previous = 0;
  27. FT_UInt glyph_index;
  28. FT_GlyphSlot slot = font->getFace()->glyph;
  29. FT_Set_Pixel_Sizes(font->getFace(), 0, size);
  30. int width = 0;
  31. String actualString = text; //StringUtil::replace(text, "\t", TAB_REPLACE);
  32. for(int i=0; i< actualString.length();i++)
  33. {
  34. if(actualString[i] == '\t') {
  35. glyph_index = FT_Get_Char_Index( font->getFace(), ' ');
  36. FT_Load_Glyph( font->getFace(), glyph_index, NORMAL_FT_FLAGS );
  37. for(int k=0 ; k < 4; k++) {
  38. FT_Render_Glyph(slot, FT_RENDER_MODE_MONO);
  39. width += slot->advance.x >> 6;
  40. }
  41. } else {
  42. glyph_index = FT_Get_Char_Index( font->getFace(), actualString[i] );
  43. if(previous && glyph_index) {
  44. FT_Get_Kerning(font->getFace(), previous, glyph_index, FT_KERNING_DEFAULT, &delta);
  45. width += delta.x >> 6;
  46. }
  47. FT_Load_Glyph( font->getFace(), glyph_index, NORMAL_FT_FLAGS );
  48. switch(antiAliasMode) {
  49. case ANTIALIAS_FULL:
  50. FT_Render_Glyph(slot, FT_RENDER_MODE_LIGHT );
  51. break;
  52. case ANTIALIAS_NONE:
  53. FT_Render_Glyph(slot, FT_RENDER_MODE_MONO);
  54. break;
  55. }
  56. width += slot->advance.x >> 6;
  57. }
  58. }
  59. // +5 pixels safety zone :)
  60. return width+5;
  61. }
  62. int Label::getTextHeight(Font *font, String text, int size) {
  63. String actualString = text; //StringUtil::replace(text, "\t", TAB_REPLACE);
  64. int height = 0;
  65. FT_UInt glyph_index;
  66. FT_GlyphSlot slot = font->getFace()->glyph;
  67. FT_Set_Pixel_Sizes(font->getFace(), 0, size);
  68. for(int i=0; i< actualString.length();i++)
  69. {
  70. glyph_index = FT_Get_Char_Index( font->getFace(), actualString[i] );
  71. FT_Load_Glyph(font->getFace(), glyph_index, NORMAL_FT_FLAGS );
  72. switch(antiAliasMode) {
  73. case ANTIALIAS_FULL:
  74. FT_Render_Glyph(slot, FT_RENDER_MODE_LIGHT );
  75. break;
  76. case ANTIALIAS_NONE:
  77. FT_Render_Glyph(slot, FT_RENDER_MODE_MONO);
  78. break;
  79. }
  80. if(slot->bitmap_top > height)
  81. height = slot->bitmap_top;
  82. }
  83. return height;
  84. }
  85. Number Label::getTextWidth() {
  86. return currentTextWidth;
  87. }
  88. Number Label::getTextHeight() {
  89. return currentTextHeight;
  90. }
  91. Font *Label::getFont() {
  92. return font;
  93. }
  94. String Label::getText() {
  95. return text;
  96. }
  97. void Label::setText(String text) {
  98. // Logger::logw((char*)text.c_str());
  99. this->text = text;
  100. if(!font)
  101. return;
  102. if(!font->isValid())
  103. return;
  104. String actualString = text; //StringUtil::replace(text, "\t", TAB_REPLACE);
  105. int textWidth = getTextWidth(font, actualString, size);
  106. int textHeight = size+getTextHeight(font, actualString, size);
  107. currentTextHeight = 0;
  108. createEmpty(textWidth,textHeight);
  109. int penX = 0;
  110. int xoff = 0;
  111. // int x,y;
  112. FT_Vector delta;
  113. FT_UInt previous = 0;
  114. FT_UInt glyph_index;
  115. FT_GlyphSlot slot = font->getFace()->glyph;
  116. FT_Set_Pixel_Sizes(font->getFace(), 0, size);
  117. // copy the freetype data into the texture
  118. for(int i=0; i< actualString.length();i++)
  119. {
  120. if(actualString[i] == (wchar_t)'\t') {
  121. glyph_index = FT_Get_Char_Index( font->getFace(), ' ');
  122. FT_Load_Glyph( font->getFace(), glyph_index, NORMAL_FT_FLAGS );
  123. for(int k=0 ; k < 4; k++) {
  124. FT_Render_Glyph(slot, FT_RENDER_MODE_MONO);
  125. penX += slot->advance.x >> 6;
  126. currentTextWidth = penX;
  127. previous = glyph_index;
  128. }
  129. } else {
  130. glyph_index = FT_Get_Char_Index( font->getFace(), (wchar_t)actualString[i]);
  131. if(previous && glyph_index) {
  132. FT_Get_Kerning(font->getFace(), previous, glyph_index, FT_KERNING_DEFAULT, &delta);
  133. penX += delta.x >> 6;
  134. }
  135. FT_Load_Glyph(font->getFace(), glyph_index, NORMAL_FT_FLAGS);
  136. switch(antiAliasMode) {
  137. case ANTIALIAS_FULL:
  138. FT_Render_Glyph(slot, FT_RENDER_MODE_LIGHT );
  139. break;
  140. case ANTIALIAS_NONE:
  141. FT_Render_Glyph(slot, FT_RENDER_MODE_MONO);
  142. break;
  143. }
  144. int lineoffset = ((size-slot->bitmap_top) * (textWidth*4));
  145. xoff = ((penX + slot->bitmap_left)*4);
  146. switch(antiAliasMode) {
  147. case ANTIALIAS_FULL:
  148. for(int j = 0; j < ((slot->bitmap.width * slot->bitmap.rows)); j++) {
  149. if(!(j%slot->bitmap.width) && j !=0)
  150. lineoffset += (textWidth*4)-(slot->bitmap.width * 4);
  151. imageData[xoff+lineoffset] = 255;
  152. imageData[xoff+lineoffset+1] = 255;
  153. imageData[xoff+lineoffset+2] = 255;
  154. if(imageData[xoff+lineoffset+3] == 0)
  155. imageData[xoff+lineoffset+3] = slot->bitmap.buffer[j];
  156. xoff += 4;
  157. }
  158. break;
  159. case ANTIALIAS_NONE:
  160. unsigned char *src = slot->bitmap.buffer;
  161. for(int j=0; j <slot->bitmap.rows;j++) {
  162. unsigned char b;
  163. unsigned char *bptr = src;
  164. for(int k=0; k < slot->bitmap.width ; k++){
  165. if (k%8==0){ b = (*bptr++);}
  166. imageData[xoff+lineoffset] = 255;
  167. imageData[xoff+lineoffset+1] = 255;
  168. imageData[xoff+lineoffset+2] = 255;
  169. imageData[xoff+lineoffset+3] = b&0x80 ? 255 : 0;
  170. xoff += 4;
  171. b <<= 1;
  172. }
  173. lineoffset += (textWidth*4)-(slot->bitmap.width * 4);
  174. src += slot->bitmap.pitch;
  175. }
  176. break;
  177. }
  178. if(slot->bitmap_top > currentTextHeight)
  179. currentTextHeight = slot->bitmap_top;
  180. penX += slot->advance.x >> 6;
  181. currentTextWidth = penX;
  182. previous = glyph_index;
  183. }
  184. }
  185. }