![]() |
Kukatz 3D
0.1
Török Attila szakdolgozata
|
00001 /* 00002 * string.cpp - Kukatz 3D 00003 * Copyright (c) 2011 - TÖRÖK Attila (torokati44@gmail.com) 00004 * 00005 * This software is provided 'as-is', without any express or implied 00006 * warranty. In no event will the authors be held liable for any damages 00007 * arising from the use of this software. 00008 * 00009 * Permission is granted to anyone to use this software for any purpose, 00010 * including commercial applications, and to alter it and redistribute it 00011 * freely, subject to the following restrictions: 00012 * 00013 * 1. The origin of this software must not be misrepresented; you must not 00014 * claim that you wrote the original software. If you use this software 00015 * in a product, an acknowledgment in the product documentation would be 00016 * appreciated but is not required. 00017 * 00018 * 2. Altered source versions must be plainly marked as such, and must not be 00019 * misrepresented as being the original software. 00020 * 00021 * 3. This notice may not be removed or altered from any source 00022 * distribution. 00023 */ 00024 00025 #include "string.hpp" 00026 00027 #include <iostream> 00028 00029 #include <SFML/Graphics.hpp> 00030 00031 #include "resourcemanager.hpp" 00032 #include "font.hpp" 00033 00034 String::String(const sf::Unicode::Text& t, const std::string& f, float s): 00035 font_id(f), text(t), contains_color_reset(false), color(255, 255, 255, 255), 00036 font_ptr(ResourceManager::instance().fonts[f]), billboard(false), size(s) 00037 { 00038 displaylist = glGenLists(1); 00039 make_list(); 00040 } 00041 00042 String::String(const sf::Unicode::Text& t, const std::string& f): 00043 font_id(f), text(t), contains_color_reset(false), color(255, 255, 255, 255), 00044 font_ptr(ResourceManager::instance().fonts[f]), billboard(false), 00045 size(font_ptr->line_height) 00046 { 00047 displaylist = glGenLists(1); 00048 make_list(); 00049 } 00050 00051 void String::make_list() 00052 { 00053 contains_color_reset = false; 00054 bool first = true; 00055 00056 sf::Vector2i cursor(0, font_ptr->size); 00057 00058 Font::glyph_t* prev_glyph_ptr = 0; 00059 Font::glyph_t* glyph_ptr = 0; 00060 00061 glNewList(displaylist, GL_COMPILE); 00062 glBegin(GL_QUADS); 00063 for (size_t i = 0; i < text.length(); ++i) 00064 { 00065 prev_glyph_ptr = glyph_ptr; 00066 glyph_ptr = &(font_ptr->glyphs[text[i]]); 00067 00068 switch (text[i]) 00069 { 00070 case '\n': 00071 { 00072 cursor.x = 0; 00073 cursor.y -= font_ptr->line_height; 00074 } 00075 break; 00076 case '\t': 00077 { 00078 cursor.x /= font_ptr->line_height; 00079 cursor.x += 1; 00080 cursor.x *= font_ptr->line_height; 00081 } 00082 break; 00083 case 0xC: 00084 { 00085 sf::Uint8 r = text[++i]; 00086 sf::Uint8 g = text[++i]; 00087 sf::Uint8 b = text[++i]; 00088 sf::Uint8 a = text[++i]; 00089 00090 glColor4ub(r, g, b, a); 00091 } 00092 break; 00093 case 0xE: 00094 { 00095 contains_color_reset = true; 00096 glColor4ub(color.r, color.g, color.b, color.a); 00097 } 00098 break; 00099 default: 00100 { 00101 if (i > 0) // kerning 00102 { 00103 for (sf::Uint32 j = 0; j < prev_glyph_ptr->kernings.size(); ++j) 00104 { 00105 if (prev_glyph_ptr->kernings[j].first == i) 00106 { 00107 cursor.x -= prev_glyph_ptr->kernings[j].second; 00108 break; 00109 } 00110 } 00111 } 00112 00113 sf::Vector2i fontmap_size(font_ptr->texture_ptr->get_width(), 00114 font_ptr->texture_ptr->get_height()); 00115 00116 int vx; 00117 int vy; 00118 00119 // BOTTOM LEFT 00120 glTexCoord2f((float)glyph_ptr->x / (float)fontmap_size.x, 00121 (float)(glyph_ptr->y + glyph_ptr->h) / (float)fontmap_size.y); 00122 00123 vx = cursor.x + glyph_ptr->xo; 00124 vy = cursor.y - glyph_ptr->h - glyph_ptr->yo; 00125 00126 glVertex2i(vx, vy); 00127 00128 if (first) 00129 { 00130 bottom_left.x = vx; 00131 bottom_left.y = vy; 00132 } 00133 else 00134 { 00135 if (vx < bottom_left.x) 00136 { 00137 bottom_left.x = vx; 00138 } 00139 if (vy < bottom_left.y) 00140 { 00141 bottom_left.y = vy; 00142 } 00143 } 00144 00145 // BOTTOM RIGHT 00146 glTexCoord2f((float)(glyph_ptr->x + glyph_ptr->w) / (float)fontmap_size.x, 00147 (float)(glyph_ptr->y + glyph_ptr->h) / (float)fontmap_size.y); 00148 glVertex2i(cursor.x + glyph_ptr->w + glyph_ptr->xo, cursor.y - glyph_ptr->h - glyph_ptr->yo); 00149 00150 // TOP RIGHT 00151 glTexCoord2f((float)(glyph_ptr->x + glyph_ptr->w) / (float)fontmap_size.x, 00152 (float)(glyph_ptr->y) / (float)fontmap_size.y); 00153 00154 vx = cursor.x + glyph_ptr->w + glyph_ptr->xo; 00155 vy = cursor.y - glyph_ptr->yo; 00156 00157 glVertex2i(vx, vy); 00158 00159 if (first) 00160 { 00161 top_right.x = vx; 00162 top_right.y = vy; 00163 } 00164 else 00165 { 00166 if (vx > top_right.x) 00167 { 00168 top_right.x = vx; 00169 } 00170 if (vy > top_right.y) 00171 { 00172 top_right.y = vy; 00173 } 00174 } 00175 00176 // TOP LEFT 00177 glTexCoord2f((float)glyph_ptr->x / (float)fontmap_size.x, 00178 (float)(glyph_ptr->y) / (float)fontmap_size.y); 00179 glVertex2i(cursor.x + glyph_ptr->xo, cursor.y - glyph_ptr->yo); 00180 00181 cursor.x += glyph_ptr->xa; 00182 00183 first = false; 00184 } 00185 break; 00186 } 00187 } 00188 glEnd(); 00189 glEndList(); 00190 } 00191 00192 float String::get_width() 00193 { 00194 return (float)(top_right.x - bottom_left.x) * (float)size / (float)font_ptr->line_height; 00195 } 00196 00197 float String::get_height() 00198 { 00199 return (float)(top_right.y - bottom_left.y) * (float)size / (float)font_ptr->line_height; 00200 } 00201 00202 unsigned int String::num_lines() 00203 { 00204 unsigned int ret = 1; 00205 for (size_t i = 0; i < text.size(); ++i) 00206 { 00207 if (text[i] == '\n') 00208 { 00209 ++ret; 00210 } 00211 } 00212 return ret; 00213 } 00214 00215 void String::render() 00216 { 00217 ResourceManager::instance().use_program(0); 00218 00219 font_ptr->texture_ptr->bind(); 00220 00221 glDisable(GL_DEPTH_TEST); 00222 00223 glPushMatrix(); 00224 float scale = (float)size / (float)(font_ptr->line_height); 00225 00226 if (billboard) 00227 { 00228 float modelview[16]; 00229 00230 glGetFloatv(GL_MODELVIEW_MATRIX, modelview); 00231 00232 for (unsigned int i = 0; i < 3; i++) 00233 { 00234 for ( unsigned int j = 0; j < 3; j++) 00235 { 00236 modelview[i * 4 + j] = ((i == j)?(scale / 200.f):0.0f); 00237 } 00238 } 00239 00240 glLoadMatrixf(modelview); 00241 glTranslatef(-get_width() / 2.0f, -get_height() / 2.0f, 0); 00242 } 00243 else 00244 { 00245 glScalef(scale, scale, 1.0f); 00246 } 00247 glTranslatef(0, (num_lines() - 1) * font_ptr->line_height, 0); 00248 glColor4ub(color.r, color.g, color.b, color.a); 00249 00250 glCallList(displaylist); 00251 glColor4ub(255, 255, 255, 255); 00252 00253 glPopMatrix(); 00254 glEnable(GL_DEPTH_TEST); 00255 } 00256 00257 void String::set_text(const sf::Unicode::Text& t) 00258 { 00259 if (text.compare(t) != 0) 00260 { 00261 text = t; 00262 make_list(); 00263 } 00264 } 00265 00266 sf::Unicode::Text String::get_text() 00267 { 00268 return text; 00269 } 00270 00271 void String::set_color(const sf::Color& c) 00272 { 00273 color = c; 00274 00275 if (contains_color_reset) 00276 { 00277 make_list(); 00278 } 00279 } 00280 00281 void String::set_color(sf::Uint8 r, sf::Uint8 g, sf::Uint8 b, sf::Uint8 a) 00282 { 00283 color.r = r; 00284 color.g = g; 00285 color.b = b; 00286 color.a = a; 00287 00288 if (contains_color_reset) 00289 { 00290 make_list(); 00291 } 00292 } 00293 00294 String::~String() 00295 { 00296 glDeleteLists(displaylist, 1); 00297 }