/* ----------------------------------------------------------------- print - */ void TextRender::print(const std::wstring &_text, const float &_x, const float &_y) { m_mutex.lock(); m_pen = { { _x, _y } }; m_markup.font = font_manager_get_from_markup(m_text_buffer->manager, &m_markup); text_buffer_clear(m_text_buffer); text_buffer_add_text(m_text_buffer, &m_pen, &m_markup, const_cast<wchar_t*>(_text.c_str()), _text.size()); m_mutex.unlock(); }
// ------------------------------------------------------------------ print --- void print( text_buffer_t * buffer, vec2 * pen, char *text, markup_t *markup ) { char *seq_start = text, *seq_end = text; char *p; size_t i; for( p=text; p<(text+strlen(text)); ++p ) { char *start = strstr( p, "\033[" ); char *end = NULL; if( start) { end = strstr( start+1, "m" ); } if( (start == p) && (end > start) ) { seq_start = start+2; seq_end = end; p = end; } else { int seq_size = (seq_end-seq_start)+1; char * text_start = p; int text_size = 0; if( start ) { text_size = start-p; p = start-1; } else { text_size = text+strlen(text)-p; p = text+strlen(text); } ansi_to_markup(seq_start, seq_size, markup ); markup->font = font_manager_get_from_markup( buffer->manager, markup ); text_buffer_add_text( buffer, pen, markup, text_start, text_size ); } } }
// ---------------------------------------------------------------------------- void text_buffer_printf( text_buffer_t * self, vec2 *pen, ... ) { markup_t *markup; wchar_t *text; va_list args; if( vertex_buffer_size( self->buffer ) == 0 ) { self->origin = *pen; } va_start ( args, pen ); do { markup = va_arg( args, markup_t * ); if( markup == NULL ) { return; } text = va_arg( args, wchar_t * ); text_buffer_add_text( self, pen, markup, text, wcslen(text) ); } while( markup != 0 ); va_end ( args ); }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING fprintf(stderr, "This demo requires freetype to be compiled " "with subpixel rendering.\n"); exit( EXIT_FAILURE) ; #endif glutInit( &argc, argv ); glutInitWindowSize( 260, 330 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( argv[0] ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); #ifndef __APPLE__ glewExperimental = GL_TRUE; GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf( stderr, "Error: %s\n", glewGetErrorString(err) ); exit( EXIT_FAILURE ); } fprintf( stderr, "Using GLEW %s\n", glewGetString(GLEW_VERSION) ); #endif buffer = vertex_buffer_new( "vertex:3f,color:4f" ); vertex_t vertices[4*2] = { { 15, 0,0, 0,0,0,1}, { 15,330,0, 0,0,0,1}, {245, 0,0, 0,0,0,1}, {245,330,0, 0,0,0,1} }; GLuint indices[4*3] = { 0,1,2,3, }; vertex_buffer_push_back( buffer, vertices, 4, indices, 4 ); text_buffer = text_buffer_new( LCD_FILTERING_ON ); vec4 black = {{0.0, 0.0, 0.0, 1.0}}; text_buffer->base_color = black; vec4 none = {{1.0, 1.0, 1.0, 0.0}}; markup_t markup; markup.family = "fonts/Vera.ttf"; markup.size = 9.0; markup.bold = 0; markup.italic = 0; markup.rise = 0.0; markup.spacing = 0.0; markup.gamma = 1.0; markup.foreground_color = black; markup.background_color = none; markup.underline = 0; markup.underline_color = black; markup.overline = 0; markup.overline_color = black; markup.strikethrough = 0; markup.strikethrough_color = black; markup.font = 0; size_t i; vec2 pen = {{20, 320}}; wchar_t *text = L"| A Quick Brown Fox Jumps Over The Lazy Dog\n"; for( i=0; i < 30; ++i) { text_buffer_add_text( text_buffer, &pen, &markup, text, wcslen(text) ); pen.x += i*0.1; } shader = shader_load("shaders/v3f-c4f.vert", "shaders/v3f-c4f.frag"); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); glutMainLoop( ); return 0; }
void CFont::TextAdd(float x, float y, float _size, float rectw, float recth, const char *text, const unsigned length) { bool hasSizeChange = abs(_size - normal.size) > 0.01f; bool hasTextChange = (0 == lasttext.size() || 0 != strcmp(text, lasttext.c_str())); if (hasSizeChange || hasTextChange || nullptr == font_manager) { // DONE: rebuild a font texture and atlas if (nullptr != font_manager) { glDeleteTextures(1, &font_manager->atlas->id); font_manager->atlas->id = 0; font_manager_delete(font_manager); font_manager = nullptr; } normal.size = _size; font_manager = font_manager_new(ATLAS_SIZE, ATLAS_SIZE, LCD_FILTERING_ON); normal.font = font_manager_get_from_markup(font_manager, &normal); normal.font->kerning = 0; text_buffer_clear(buffer); vec2 pen = { { 0, 0 } }; text_buffer_add_text(buffer, &pen, &normal, text, length); //text_buffer_align(buffer, &pen, ALIGN_CENTER); glGenTextures(1, &font_manager->atlas->id); glBindTexture(GL_TEXTURE_2D, font_manager->atlas->id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, font_manager->atlas->width, font_manager->atlas->height, 0, GL_RGB, GL_UNSIGNED_BYTE, font_manager->atlas->data); vec4 bounds = text_buffer_get_bounds(buffer, &pen); mBounds[0] = bounds.x; mBounds[1] = bounds.y; mBounds[2] = bounds.z; mBounds[3] = bounds.w; lasttext = text; } // //vec2 pen = { { x, y } }; //text_buffer_add_text(buffer, &pen, &normal, text, length); mat4_set_identity(&model); float stretch = 1.01f; // mBounds[2] / (0.8f * rectw); float xoffset = 0.25f * mBounds[2] / length; float yoffset = recth - 0.5f * (recth - mBounds[3]); mat4_set_scaling(&model, stretch, 1.0f, 1.0f); mat4_translate(&model, x + xoffset, y + yoffset, 0.0f); }