00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <iostream>
00012
00013 #include "glut-demo/glut-demo.h"
00014 #include "glut-font/glut-font-effects.h"
00015 #include "perf/perf.h"
00016 #include "util/file.h"
00017
00018
00019
00020 static const int s_border = 32;
00021
00022 static const int s_desiredHeight = 24;
00023
00024 static const char * s_lines =
00025 "This is a test. "
00026 "This is line 2. "
00027 "This is line 3. "
00028 "This is a really, really long line. Really. It's quite long. "
00029 "Short. "
00030 "You have found +3 dollars and +8 Euros! Spend them wisely. "
00031 "0123456789 "
00032 "abcdefghijklmnopqrstuvwxyz That isn't really a word. "
00033 "Today: cloudy with showers. High 59F. Winds SSE at 5 to 10 mph. Chance of rain 60%. "
00034 "Good bye! "
00035 "End of line.";
00036
00037 static const int s_msPerChar = 50;
00038
00039 static const glut_color_t s_color(0.5, 1.0, 0.5);
00040
00041
00042
00043
00044
00045
00046
00047
00048 class Drawer : public glut::DemoHost {
00049 public:
00050 Drawer(IN const char * dir) {
00051 ASSERT(dir, "null");
00052 m_fontDir = dir;
00053 m_index = -2;
00054 }
00055 ~Drawer(void) throw() { }
00056
00057
00058 void onInit(void) {
00059
00060 this->addFiles("ttf");
00061
00062
00063 m_fontMgr = glut::FontManager::create();
00064 ASSERT_THROW(m_fontMgr,
00065 "failed to create font manager");
00066
00067 m_width = 800;
00068 this->updateFont(-1);
00069
00070
00071 m_time = perf::getNow();
00072 }
00073
00074 bool displayAxes(void) { return false; }
00075
00076 void onKey(IN int key, IN int mods) {
00077 int deltaIndex = 0;
00078 switch (key) {
00079 case 'n': deltaIndex = +1; break;
00080 case 'N': deltaIndex = -1; break;
00081 case ' ': m_effect->reset(); break;
00082 case 'a': m_effect->advance(); break;
00083 case 'c': m_effect->complete(); break;
00084 default:
00085
00086 break;
00087 }
00088
00089 int nMax = m_paths.size();
00090 int newIndex = m_index + deltaIndex;
00091 if (newIndex < -1) {
00092 newIndex = nMax - 1;
00093 } else if (newIndex >= nMax) {
00094 newIndex = -1;
00095 }
00096 this->updateFont(newIndex);
00097 }
00098
00099 void display2D(IN int width, IN int height) {
00100 ASSERT(m_currFont, "null");
00101 ASSERT(m_effect, "null");
00102
00103 m_width = width;
00104
00105 int nMax = m_paths.size();
00106 const int bufsize = 1024;
00107 char buffer[bufsize];
00108 snprintf(buffer, bufsize, "font: %s",
00109 m_currFont->getName());
00110 glut::Font * defFont = glut::getDefaultFont();
00111 defFont->display(1, 47, 0, buffer);
00112 snprintf(buffer, bufsize, "font %d of %d",
00113 m_index + 1, nMax);
00114 defFont->display(1, 62, 0, buffer);
00115 snprintf(buffer, bufsize, "font size: %4.1f point",
00116 m_currFont->getFaceSize());
00117 defFont->display(1, 77, 0, buffer);
00118 defFont->display(1, 92, 0, "(n)ext font");
00119 defFont->display(width - 300, 62, 0, "(space): reset");
00120 defFont->display(width - 300, 77, 0, "(a)dvance");
00121 defFont->display(width - 300, 92, 0, "(c)omplete");
00122 int yStart = 92 + s_border + m_currFont->getLineHeight();
00123
00124 perf::time_t now = perf::getNow();
00125 perf::time_t delta = now;
00126 delta.decrement(m_time);
00127 m_time = now;
00128 m_effect->tick(delta.getSeconds());
00129
00130 glBegin(GL_LINES);
00131 glVertex3f(s_border, 0, 0);
00132 glVertex3f(s_border, height, 0);
00133 glVertex3f(width - s_border, 0, 0);
00134 glVertex3f(width - s_border, height, 0);
00135 glEnd();
00136
00137 glMatrixMode(GL_MODELVIEW);
00138 glPushMatrix();
00139 glTranslatef(s_border, yStart, 0);
00140
00141 m_effect->render();
00142
00143 glPopMatrix();
00144 }
00145
00146 private:
00147
00148
00149
00150 void addFiles(IN const char * ext) {
00151 ASSERT(ext, "null extension");
00152 VecString files;
00153 walkDirectoryTree(m_fontDir.c_str(), ext, files);
00154 int nFiles = files.size();
00155 for (int i = 0; i < nFiles; ++i) {
00156 const char * path = files[i].c_str();
00157 DPRINTF("Font file: '%s'", path);
00158 m_paths.push_back(path);
00159 }
00160
00161 m_streamMgr =
00162 nstream::getFilesystemManager(m_fontDir.c_str());
00163 ASSERT(m_streamMgr, "null");
00164 }
00165
00166 void updateFont(IN int newIndex) {
00167 if (m_currFont && m_index == newIndex)
00168 return;
00169 m_index = newIndex;
00170
00171 int nMax = m_paths.size();
00172 const char * path = NULL;
00173 if (m_index >= 0 && m_index < nMax) {
00174 path = m_paths[m_index].c_str();
00175 }
00176
00177
00178 smart_ptr<nstream::Stream> stream;
00179 if (path) {
00180 stream =
00181 nstream::openNamedStream(m_streamMgr, path);
00182 ASSERT(stream,
00183 "failed to open stream: %s", path);
00184 }
00185
00186
00187 m_currFont = m_fontMgr->getFont(stream);
00188 ASSERT(m_currFont, "null font?");
00189
00190
00191 scaleFontToPixelHeight(m_currFont, "M", s_desiredHeight);
00192
00193
00194 std::string lines;
00195 glut::breakLongString(s_lines, m_currFont,
00196 m_width - 2 * s_border, lines);
00197 DPRINTF("Lines:\n%s", lines.c_str());
00198
00199
00200 m_effect = glut::getCharacterAdvanceEffect(m_currFont,
00201 lines.c_str(), s_msPerChar, s_color);
00202 }
00203
00204
00205 std::string m_fontDir;
00206 VecString m_paths;
00207 smart_ptr<glut::FontManager> m_fontMgr;
00208 smart_ptr<nstream::Manager> m_streamMgr;
00209 smart_ptr<glut::Font> m_currFont;
00210 smart_ptr<glut::FontEffect> m_effect;
00211 int m_index;
00212 perf::time_t m_time;
00213 int m_width;
00214 };
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 int
00225 main
00226 (
00227 IN int argc,
00228 IN const char * argv[]
00229 )
00230 {
00231 ASSERT(2 == argc, "Usage: glut-font-effects <font-dir>");
00232 const char * font_dir = argv[1];
00233 DPRINTF("Using font directory: '%s'", font_dir);
00234
00235 try {
00236
00237 std::string title = "glut-font FontEffect test: ";
00238 title += font_dir;
00239
00240
00241 smart_ptr<glut::DemoHost> host = new Drawer(font_dir);
00242 ASSERT(host, "out of memory");
00243 glut::startDemo(argc, argv, title.c_str(), host);
00244
00245 } catch (std::exception& e) {
00246 DPRINTF("Exception: %s", e.what());
00247 }
00248
00249
00250 return -1;
00251 }
00252