Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "glut-font-effects.h"
00035
00036 #include "perf/perf.h"
00037 #include "util/parsing.h"
00038 #include "wave-glut/wave-glut.h"
00039
00040
00041 namespace glut {
00042
00043
00044
00045 FontEffect::~FontEffect(void) throw() { }
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 class CharStep : public FontEffect {
00063 public:
00064 ~CharStep(void) throw() { }
00065
00066
00067 void initialize(IN smart_ptr<Font>& font,
00068 IN const char * lines,
00069 IN int msPerChar,
00070 IN const glut_color_t& color);
00071
00072
00073 void tick(IN float deltaT);
00074 void render(void);
00075 void reset(void);
00076 void advance(void);
00077 void complete(void);
00078
00079 private:
00080
00081
00082 utf8_char_t addChar(void);
00083
00084
00085 smart_ptr<Font> m_font;
00086 glut_color_t m_color;
00087 std::string m_text;
00088 VecString m_lines;
00089 int m_msPerChar;
00090 float m_time;
00091 const char * m_curr;
00092 int m_currLine;
00093 };
00094
00095
00096
00097 void
00098 CharStep::initialize
00099 (
00100 IN smart_ptr<Font>& font,
00101 IN const char * lines,
00102 IN int msPerChar,
00103 IN const glut_color_t& color
00104 )
00105 {
00106 ASSERT(font, "null");
00107 ASSERT(lines, "null");
00108 ASSERT(msPerChar >= 0, "Bad ms per character: %d", msPerChar);
00109
00110 m_font = font;
00111 m_color = color;
00112 m_time = 0.0;
00113 m_msPerChar = msPerChar;
00114
00115
00116 m_text = lines;
00117
00118 this->reset();
00119 }
00120
00121
00122
00123 void
00124 CharStep::tick
00125 (
00126 IN float deltaT
00127 )
00128 {
00129 if (deltaT <= 0.0 || !m_curr)
00130 return;
00131 m_time += deltaT;
00132
00133
00134 int nChars = (int) (1000.0 * m_time / m_msPerChar);
00135 m_time -= 0.001 * nChars * m_msPerChar;
00136
00137
00138
00139 for (int i = 0; i < nChars; ++i) {
00140 this->addChar();
00141 }
00142 }
00143
00144
00145
00146 void
00147 CharStep::render
00148 (
00149 void
00150 )
00151 {
00152 ASSERT(m_font, "null");
00153
00154 glColor4f(m_color.red, m_color.green, m_color.blue, m_color.alpha);
00155
00156 int dy = m_font->getLineHeight() + 2;
00157
00158 int nLines = m_lines.size();
00159 for (int i = 0; i < nLines; ++i) {
00160 const char * line = m_lines[i].c_str();
00161 m_font->display(0, 0, 0, line);
00162 glTranslatef(0, dy, 0);
00163 }
00164 }
00165
00166
00167
00168 void
00169 CharStep::advance
00170 (
00171 void
00172 )
00173 {
00174 while (true) {
00175 utf8_char_t c = this->addChar();
00176 if (!c || c == '\n')
00177 return;
00178 }
00179 }
00180
00181
00182
00183 void
00184 CharStep::complete
00185 (
00186 void
00187 )
00188 {
00189 while (this->addChar()) { }
00190 }
00191
00192
00193
00194 void
00195 CharStep::reset
00196 (
00197 void
00198 )
00199 {
00200
00201 m_curr = m_text.c_str();
00202
00203
00204 m_lines.clear();
00205
00206
00207 m_lines.push_back("");
00208 m_currLine = 0;
00209 }
00210
00211
00212
00213 utf8_char_t
00214 CharStep::addChar
00215 (
00216 void
00217 )
00218 {
00219 utf8_char_t c;
00220 if (!m_curr)
00221 return c;
00222
00223 m_curr = getUTF8CharacterFromString(m_curr, c);
00224 if (c.nBytes < 1) {
00225 DPRINTF("Bad UTF8 character in string?");
00226 m_curr = NULL;
00227 return c;
00228 }
00229 if (0 == c.value[0]) {
00230
00231 m_curr = NULL;
00232 } else if ('\n' == c.value[0]) {
00233
00234 m_currLine++;
00235 m_lines.push_back("");
00236 } else {
00237
00238 const char * line = m_lines[m_currLine].c_str();
00239 std::string newLine = line;
00240 newLine += c.value;
00241
00242 m_lines[m_currLine] = newLine;
00243 }
00244
00245 return c;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 smart_ptr<FontEffect>
00257 getCharacterAdvanceEffect
00258 (
00259 IN smart_ptr<Font>& font,
00260 IN const char * lines,
00261 IN int millisecondsPerCharacter,
00262 IN const glut_color_t& color
00263 )
00264 {
00265 ASSERT(font, "null");
00266 ASSERT(lines, "null");
00267 ASSERT(millisecondsPerCharacter >= 0, "bad milliseconds: %d",
00268 millisecondsPerCharacter);
00269
00270 smart_ptr<CharStep> local = new CharStep;
00271 ASSERT(local, "out of memory");
00272
00273 local->initialize(font, lines, millisecondsPerCharacter, color);
00274
00275 return local;
00276 }
00277
00278
00279
00280 void
00281 breakLongString
00282 (
00283 IN const char * text,
00284 IN Font * font,
00285 IN int maxPixelWidth,
00286 OUT std::string& out
00287 )
00288 {
00289 ASSERT(text, "null");
00290 ASSERT(font, "null");
00291 out.clear();
00292
00293
00294 std::string line;
00295 while (*text) {
00296 std::string word;
00297
00298
00299 text = getNextWord(text, word);
00300 if ("\n" == word) {
00301
00302 out += line;
00303 out += "\n";
00304 line.clear();
00305 } else if ("" == line) {
00306
00307 line = word;
00308 } else {
00309
00310 std::string candidate_line = line;
00311 candidate_line += " ";
00312 candidate_line += word;
00313
00314
00315 font_rect_t fr =
00316 font->getBoundingRect(candidate_line.c_str());
00317 int width = fr.lead + fr.trail;
00318 if (width > maxPixelWidth) {
00319
00320 if ("" != line) {
00321 out += line;
00322 out += "\n";
00323 }
00324 line = word;
00325 } else {
00326
00327 line = candidate_line;
00328 }
00329 }
00330 }
00331
00332 if (!line.empty()) {
00333 out += line;
00334 }
00335 }
00336
00337
00338
00339 };
00340