00001 /* 00002 glh - is a platform-indepenedent C++ OpenGL helper library 00003 00004 00005 Copyright (c) 2000 Cass Everitt 00006 Copyright (c) 2000 NVIDIA Corporation 00007 All rights reserved. 00008 00009 Redistribution and use in source and binary forms, with or 00010 without modification, are permitted provided that the following 00011 conditions are met: 00012 00013 * Redistributions of source code must retain the above 00014 copyright notice, this list of conditions and the following 00015 disclaimer. 00016 00017 * Redistributions in binary form must reproduce the above 00018 copyright notice, this list of conditions and the following 00019 disclaimer in the documentation and/or other materials 00020 provided with the distribution. 00021 00022 * The names of contributors to this software may not be used 00023 to endorse or promote products derived from this software 00024 without specific prior written permission. 00025 00026 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00027 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00028 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00029 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00030 REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00031 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00032 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00033 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00034 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00035 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00036 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00037 POSSIBILITY OF SUCH DAMAGE. 00038 00039 00040 Cass Everitt - cass@r3.nu 00041 */ 00042 00043 #ifndef GLH_TEXT_H 00044 #define GLH_TEXT_H 00045 00046 #include <string> 00047 00048 #ifdef _WIN32 00049 # include <windows.h> 00050 #endif 00051 00052 #ifdef MACOS 00053 #include <OpenGL/gl.h> 00054 #else 00055 #include <GL/gl.h> 00056 #endif 00057 00058 #include <glh/glh_obs.h> 00059 00060 namespace glh 00061 { 00062 00063 struct font 00064 { 00065 // build display lists and the like 00066 virtual void initialize() = 0; 00067 // get font metrics 00068 virtual float get_ascent() = 0; 00069 virtual float get_descent() = 0; 00070 virtual float get_width(int i) = 0; 00071 00072 // draw 00073 virtual void render(int i) = 0; 00074 }; 00075 00076 inline float string_width(font * f, string text) 00077 { 00078 float w = 0; 00079 for(unsigned int i=0; i < text.size(); i++) 00080 { 00081 w += f->get_width(text[i]); 00082 } 00083 return w; 00084 } 00085 // skip a line 00086 inline void next_line(font * f) 00087 { 00088 glTranslatef(0, - (f->get_ascent() + f->get_descent()), 0); 00089 } 00090 00091 // renders text horizontally 00092 inline void render_single_line(font * f, string text) 00093 { 00094 glPushMatrix(); 00095 for(unsigned int i=0; i < text.size(); i++) 00096 { 00097 f->render(text[i]); 00098 } 00099 glPopMatrix(); 00100 } 00101 00102 00103 // render text on multiple lines (based on newlines) 00104 struct simple_multi_line_text 00105 { 00106 public: 00107 simple_multi_line_text() : f(0), line_spacing(1.1f) {} 00108 00109 00110 void render() 00111 { 00112 if(!f) return; 00113 if(dirty) 00114 { 00115 dirty = false; 00116 dl.new_list(GL_COMPILE); 00117 make_render_calls(); 00118 dl.end_list(); 00119 } 00120 dl.call_list(); 00121 } 00122 void get_dimensions(float & width, float & height) 00123 { 00124 if(!f) return; 00125 if(dirty) 00126 { 00127 dirty = false; 00128 dl.new_list(GL_COMPILE); 00129 make_render_calls(); 00130 dl.end_list(); 00131 } 00132 width = w; 00133 height = h; 00134 } 00135 void set_font(font * new_font) 00136 { 00137 dirty = true; 00138 f = new_font; 00139 } 00140 void set_text(const string & new_text) 00141 { 00142 dirty = true; 00143 text = new_text; 00144 } 00145 font * get_font() { return f; } 00146 const string & get_text() { return text; } 00147 private: 00148 // skip a line 00149 void next_line() 00150 { 00151 glTranslatef(0, - (f->get_ascent() + f->get_descent()) * line_spacing, 0); 00152 } 00153 00154 void make_render_calls() 00155 { 00156 w = h = 0; 00157 float curr_width = 0; 00158 float font_height = f->get_ascent() + f->get_descent(); 00159 int lines = 0; 00160 00161 if(text.size() != 0) lines++; 00162 00163 glPushMatrix(); // vertical translation 00164 glPushMatrix(); // horizontal translation 00165 for(unsigned int i=0; i < text.size(); i++) 00166 { 00167 if(text[i] == '\n') 00168 { 00169 lines++; 00170 if(curr_width > w) w = curr_width; 00171 curr_width = 0; 00172 00173 glPopMatrix(); // back to beginning of line 00174 next_line(); // translate futher down 00175 glPushMatrix(); 00176 } 00177 f->render(text[i]); 00178 curr_width += f->get_width(text[i]); 00179 } 00180 glPopMatrix(); 00181 glPopMatrix(); 00182 if(curr_width > w) w = curr_width; 00183 h = lines * font_height * line_spacing; 00184 } 00185 00186 font * f; 00187 string text; 00188 display_list dl; 00189 float w, h; 00190 bool dirty; 00191 float line_spacing; 00192 }; 00193 00194 00195 } 00196 00197 #endif