// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 800, 400 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Freetype OpenGL / vertex arrays" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); size_t i; texture_font_t *font = 0; texture_atlas_t *atlas = texture_atlas_new( 512, 512, 1 ); const char * filename = "./Vera.ttf"; wchar_t *text = L"A Quick Brown Fox Jumps Over The Lazy Dog 0123456789"; buffer = vertex_buffer_new( "v3f:t2f:c4f" ); vec2 pen = {{0,0}}; vec4 black = {{0,0,0,1}}; for( i=7; i < 27; ++i) { font = texture_font_new( atlas, filename, i ); pen.x = 0; pen.y -= font->height; texture_font_load_glyphs( font, text ); add_text( buffer, font, text, &black, &pen ); texture_font_delete( font ); } glBindTexture( GL_TEXTURE_2D, atlas->id ); glutMainLoop( ); return 0; }
// ------------------------------------------- texture_font_new_from_memory --- texture_font_t * texture_font_new_from_memory(texture_atlas_t *atlas, float pt_size, const void *memory_base, size_t memory_size) { texture_font_t *self; assert(memory_base); assert(memory_size); self = (texture_font_t*)calloc(1, sizeof(*self)); if (!self) { fprintf(stderr, "line %d: No more memory for allocating data\n", __LINE__); return NULL; } self->atlas = atlas; self->size = pt_size; self->location = TEXTURE_FONT_MEMORY; self->memory.base = memory_base; self->memory.size = memory_size; if (texture_font_init(self)) { texture_font_delete(self); return NULL; } return self; }
void opengl_font_delete(font_t* font) { opengl_font_t* f = (opengl_font_t*)font->data; texture_atlas_delete(f->atlas); texture_font_delete(f->font); free(f); }
// --------------------------------------------- texture_font_new_from_file --- texture_font_t * texture_font_new_from_file(texture_atlas_t *atlas, const float pt_size, const char *filename) { texture_font_t *self; assert(filename); self = (texture_font_t*)calloc(1, sizeof(*self)); if (!self) { fprintf(stderr, "line %d: No more memory for allocating data\n", __LINE__); return NULL; } self->atlas = atlas; self->size = pt_size; self->location = TEXTURE_FONT_FILE; self->filename = _strdup(filename); if (texture_font_init(self)) { texture_font_delete(self); return NULL; } return self; }
Font::~Font() { texture_font_delete(m_font); texture_atlas_delete(m_atlas); vertex_buffer_delete(m_buffer); delete m_fontFile; }
void opengl_font_reload(font_t* f) { opengl_font_t* o = (opengl_font_t*)f->data; texture_font_delete(o->font); texture_atlas_delete(o->atlas); o->atlas = texture_atlas_new(512, 512, 1); o->font = texture_font_new(o->atlas, o->name, f->size * window_zoom); texture_font_load_glyphs(o->font, cache); }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 512, 512 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Freetype OpenGL width shaders" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutMotionFunc( mouse_drag ); glutPassiveMotionFunc( mouse_motion ); glutKeyboardFunc( keyboard ); 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) ); unsigned char *map; texture_font_t * font; const char *filename = "fonts/Vera.ttf"; const wchar_t *cache = L" !\"#$%&'()*+,-./0123456789:;<=>?" L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" L"`abcdefghijklmnopqrstuvwxyz{|}~"; atlas = texture_atlas_new( 512, 512, 1 ); font = texture_font_new_from_file( atlas, 72, filename ); texture_font_load_glyphs( font, cache ); texture_font_delete( font ); fprintf( stderr, "Generating distance map...\n" ); map = make_distance_map(atlas->data, atlas->width, atlas->height); fprintf( stderr, "done !\n"); memcpy( atlas->data, map, atlas->width*atlas->height*sizeof(unsigned char) ); free(map); texture_atlas_upload( atlas ); // Create the GLSL program program = shader_load( "shaders/distance-field.vert", "shaders/distance-field.frag" ); glUseProgram( program ); glutMainLoop( ); return 0; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 800, 400 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Freetype OpenGL / LCD filtering" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); 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) ); size_t i; texture_font_t *font = 0; atlas = texture_atlas_new( 512, 512, 3 ); const char * filename = "fonts/Vera.ttf"; wchar_t *text = L"A Quick Brown Fox Jumps Over The Lazy Dog 0123456789"; buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f,ashift:1f,agamma:1f" ); vec2 pen = {{0,0}}; vec4 color = {{0,0,0,1}}; for( i=7; i < 27; ++i) { font = texture_font_new_from_file( atlas, i, filename ); pen.x = 0; pen.y -= font->height; texture_font_load_glyphs( font, text ); add_text( buffer, font, text, &color, &pen ); texture_font_delete( font ); } glBindTexture( GL_TEXTURE_2D, atlas->id ); shader = shader_load( "shaders/text.vert", "shaders/text.frag" ); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); glutMainLoop( ); return 0; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 512, 512 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( argv[0] ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); atlas = texture_atlas_new( 512, 512, 1 ); assert(atlas); const char *filename = "../fonts/Vera.ttf"; const wchar_t *cache = L" !\"#$%&'()*+,-./0123456789:;<=>?" L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" L"`abcdefghijklmnopqrstuvwxyz{|}~"; size_t minsize = 8, maxsize = 27; size_t count = maxsize - minsize; size_t i, missed = 0; for( i=minsize; i < maxsize; ++i ) { texture_font_t * font = texture_font_new( atlas, filename, i ); if(!font) { fprintf(stderr, "Failed to load font: \"%s\"\n", filename); return -1; } if(!texture_font_load_glyphs( font, cache )) { missed++; } texture_font_delete( font ); } printf( "Matched font : %s\n", filename ); printf( "Number of fonts : %zd\n", count ); printf( "Number of glyphs per font : %zd\n", wcslen(cache) ); printf( "Number of missed glyphs : %zd\n", missed ); printf( "Total number of glyphs : %zd/%zd\n", wcslen(cache)*count - missed, wcslen(cache)*count ); printf( "Texture size : %zdx%zd\n", atlas->width, atlas->height ); printf( "Texture occupancy : %.2f%%\n", 100.0*atlas->used/(float)(atlas->width*atlas->height) ); glutMainLoop( ); return 0; }
void Font::ResizeFont(int size) { if(m_font) texture_font_delete(m_font); if(m_atlas) texture_atlas_delete(m_atlas); delete m_textureAtlas; m_atlas = texture_atlas_new(512, 512, 1); m_font = texture_font_new(m_atlas, m_fontFile->m_buffer, m_fontFile->m_bufLength, (float)size); texture_font_load_glyphs(m_font, L" !\"#$%&'()*+,-./0123456789:;<=>?" L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" L"`abcdefghijklmnopqrstuvwxyz{|}~", m_fontFile->m_buffer, m_fontFile->m_bufLength); m_textureAtlas = new GLTexture(m_atlas->id, 512, 512); }
ofxFreeTypeGL::ofxFreeTypeGL(){ texture_atlas_t * atlas = texture_atlas_new( ofGetWidth(), ofGetHeight(), 1 ); texture.allocate(1024, 1024, GL_LUMINANCE_ALPHA); const char *filename = "../../../data/fonts/hiraginoKakugoW6.otf"; const wchar_t *cache = L"Wow,これは面白い!!夜露死苦〠"; size_t minsize = 4, maxsize = 80; size_t count = maxsize - minsize; size_t i, missed = 0; for( i=minsize; i < maxsize; ++i ){ texture_font_t * font = texture_font_new( atlas, filename, i ); missed += texture_font_load_glyphs( font, cache ); texture_font_delete( font ); } printf( "Matched font : %s\n", filename ); printf( "Number of fonts : %ld\n", count ); printf( "Number of glyphs per font : %ld\n", wcslen(cache) ); printf( "Number of missed glyphs : %ld\n", missed ); printf( "Total number of glyphs : %ld/%ld\n", wcslen(cache)*count - missed, wcslen(cache)*count ); printf( "Texture size : %ldx%ld\n", atlas->width, atlas->height ); printf( "Texture occupancy : %.2f%%\n", 100.0*atlas->used/(float)(atlas->width*atlas->height) ); const int SIZE = atlas->width * atlas->height; vector<unsigned char> temp; temp.resize(SIZE * 2); unsigned char *src = atlas->data; unsigned char *dst = temp.data(); for (int i = 0; i < SIZE; i++){ dst[0] = 255; dst[1] = *src; src++; dst += 2; } texture.loadData(temp.data(), 1024, 1024, GL_LUMINANCE_ALPHA); }
// ---------------------------------------------------- font_manager_delete --- void font_manager_delete( font_manager_t * self ) { size_t i; texture_font_t *font; assert( self ); for( i=0; i<vector_size( self->fonts ); ++i) { font = *(texture_font_t **) vector_get( self->fonts, i ); texture_font_delete( font ); } vector_delete( self->fonts ); texture_atlas_delete( self->atlas ); if( self->cache ) { free( self->cache ); } free( self ); }
// ----------------------------------------------- font_manager_delete_font --- void font_manager_delete_font( font_manager_t * self, texture_font_t * font) { size_t i; texture_font_t *other; assert( self ); assert( font ); for( i=0; i<self->fonts->size;++i ) { other = (texture_font_t *) vector_get( self->fonts, i ); if ( (strcmp(font->filename, other->filename) == 0) && ( font->size == other->size) ) { vector_erase( self->fonts, i); break; } } texture_font_delete( font ); }
// ------------------------------------------------------------------- init --- void init( void ) { size_t i; texture_font_t *font = 0; atlas = texture_atlas_new( 512, 512, 3 ); const char * filename = "fonts/Vera.ttf"; char * text = "A Quick Brown Fox Jumps Over The Lazy Dog 0123456789"; buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f,ashift:1f,agamma:1f" ); vec2 pen = {{0,0}}; vec4 color = {{0,0,0,1}}; for( i=7; i < 27; ++i) { font = texture_font_new_from_file( atlas, i, filename ); pen.x = 0; pen.y -= font->height; texture_font_load_glyphs( font, text ); add_text( buffer, font, text, &color, &pen ); texture_font_delete( font ); } glGenTextures( 1, &atlas->id ); glBindTexture( GL_TEXTURE_2D, 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, atlas->width, atlas->height, 0, GL_RGB, GL_UNSIGNED_BYTE, atlas->data ); shader = shader_load( "shaders/text.vert", "shaders/text.frag" ); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); }
// ------------------------------------------------------------------- main --- int main_texture( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 512, 512 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( argv[0] ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); // 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) ); texture_atlas_t * atlas = texture_atlas_new( 512, 512, 1 ); // const char *filename = "/Users/jie/svn/v8/deps/freetype-gl-read-only/fonts/Vera.ttf"; const char *filename = "/Users/jie/svn/v8/deps/freetype-gl-read-only/fonts/fat.ttf"; // const wchar_t *cache = L" !\"#$%&'()*+,-./0123456789:;<=>?" // L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" // L"`abcdefghijklmnopqrstuvwxyz{|}~"; wchar_t unicode[6]; unicode[0] = 22909; unicode[1] = 20320; unicode[2] = 25438; unicode[3] = 28156; unicode[4] = 48; unicode[5] = 0; wchar_t* cache = (wchar_t*)unicode; printf("%d %d\n", cache[0], wcslen(cache)); size_t minsize = 20, maxsize = 40; size_t count = maxsize - minsize; size_t i, missed = 0; for( i=minsize; i < maxsize; ++i ) { texture_font_t * font = texture_font_new( atlas, filename, i ); missed += texture_font_load_glyphs( font, cache ); texture_font_delete( font ); } printf( "Matched font : %s\n", filename ); printf( "Number of fonts : %ld\n", count ); printf( "Number of glyphs per font : %ld\n", wcslen(cache) ); printf( "Number of missed glyphs : %ld\n", missed ); printf( "Total number of glyphs : %ld/%ld\n", wcslen(cache)*count - missed, wcslen(cache)*count ); printf( "Texture size : %ldx%ld\n", atlas->width, atlas->height ); printf( "Texture occupancy : %.2f%%\n", 100.0*atlas->used/(float)(atlas->width*atlas->height) ); glClearColor(1,1,1,1); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, atlas->id ); typedef struct { float x,y,z, u,v, r,g,b,a; } vertex_t; vertex_t vertices[4] = { { 0, 0, 0, 0,1, 0,0,0,1}, { 0, 512,0, 0,0, 0,0,0,1}, { 512,512,0, 1,0, 0,0,0,1}, { 512, 0,0, 1,1, 0,0,0,1} }; GLuint indices[6] = { 0,1,2, 0,2,3 }; buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); vertex_buffer_push_back( buffer, vertices, 4, indices, 6 ); shader = shader_load("/Users/jie/svn/v8/deps/freetype-gl-read-only/shaders/v3f-t2f-c4f.vert", "/Users/jie/svn/v8/deps/freetype-gl-read-only/shaders/v3f-t2f-c4f.frag"); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); glutMainLoop( ); return 0; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { GLFWwindow* window; glfwSetErrorCallback( error_callback ); if (!glfwInit( )) { exit( EXIT_FAILURE ); } glfwWindowHint( GLFW_VISIBLE, GL_TRUE ); glfwWindowHint( GLFW_RESIZABLE, GL_FALSE ); window = glfwCreateWindow( 1, 1, "Freetype OpenGL / LCD filtering", NULL, NULL ); if (!window) { glfwTerminate( ); exit( EXIT_FAILURE ); } glfwMakeContextCurrent( window ); glfwSwapInterval( 1 ); glfwSetFramebufferSizeCallback( window, reshape ); glfwSetWindowRefreshCallback( window, display ); glfwSetKeyCallback( window, 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 size_t i; texture_font_t *font = 0; atlas = texture_atlas_new( 512, 512, 3 ); const char * filename = "fonts/Vera.ttf"; wchar_t *text = L"A Quick Brown Fox Jumps Over The Lazy Dog 0123456789"; buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f,ashift:1f,agamma:1f" ); vec2 pen = {{0,0}}; vec4 color = {{0,0,0,1}}; for( i=7; i < 27; ++i) { font = texture_font_new_from_file( atlas, i, filename ); pen.x = 0; pen.y -= font->height; texture_font_load_glyphs( font, text ); add_text( buffer, font, text, &color, &pen ); texture_font_delete( font ); } glBindTexture( GL_TEXTURE_2D, atlas->id ); shader = shader_load( "shaders/text.vert", "shaders/text.frag" ); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); glfwSetWindowSize( window, 800, 500 ); glfwShowWindow( window ); while(!glfwWindowShouldClose( window )) { display( window ); glfwPollEvents( ); } glfwDestroyWindow( window ); glfwTerminate( ); return 0; }
// ----------------------------------------------------------- build_buffer --- void build_buffer( void ) { vec2 pen; size_t i; texture_font_t *font; texture_glyph_t *glyph; vec4 white = {{1.0, 1.0, 1.0, 1.0}}; vec4 none = {{1.0, 1.0, 1.0, 0.0}}; markup_t markup = { .family = "Arial", .size = 10.0, .bold = 0, .italic = 0, .rise = 0.0, .spacing = 0.0, .gamma = 2.2, .foreground_color = white, .background_color = none, .underline = 0, .underline_color = white, .overline = 0, .overline_color = white, .strikethrough = 0, .strikethrough_color = white, .font = 0, }; vertex_buffer_clear( buffer ); texture_atlas_clear( atlas ); if( p_family == VERA) { font = texture_font_new( atlas, "fonts/Vera.ttf", p_size ); } else if( p_family == VERA_MONO) { font = texture_font_new( atlas, "fonts/VeraMono.ttf", p_size ); } else if( p_family == GEORGIA) { font = texture_font_new( atlas, "fonts/Georgia.ttf", p_size ); } else if( p_family == TIMES ) { font = texture_font_new( atlas, "fonts/Times.ttf", p_size ); } else if( p_family == TAHOMA ) { font = texture_font_new( atlas, "fonts/Tahoma.ttf", p_size ); } else if( p_family == ARIAL ) { font = texture_font_new( atlas, "fonts/Arial.ttf", p_size ); } else if( p_family == VERDANA ) { font = texture_font_new( atlas, "fonts/Verdana.ttf", p_size ); } else { fprintf( stderr, "Error : Unknown family type\n" ); return; } font->hinting = p_hinting; font->filtering = 1; float norm = 1.0/(p_primary + 2*p_secondary + 2*p_tertiary); font->lcd_weights[0] = (unsigned char)(p_tertiary*norm*256); font->lcd_weights[1] = (unsigned char)(p_secondary*norm*256); font->lcd_weights[2] = (unsigned char)(p_primary*norm*256); font->lcd_weights[3] = (unsigned char)(p_secondary*norm*256); font->lcd_weights[4] = (unsigned char)(p_tertiary*norm*256); texture_font_load_glyphs( font, L" !\"#$%&'()*+,-./0123456789:;<=>?" L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" L"`abcdefghijklmnopqrstuvwxyz{|}~" ); pen.x = 10; pen.y = 600 - font->height - 10; glyph = texture_font_get_glyph( font, text[0] ); add_glyph( glyph, buffer, &markup, &pen, 0 ); for( i=1; i<wcslen(text); ++i ) { if( text[i] == '\n' ) { pen.x = 10; pen.y -= font->height; // + 0.01*(size - (int)size)*font->height; } else { glyph = texture_font_get_glyph( font, text[i] ); float kerning = 0.0; if( p_kerning ) { kerning = texture_glyph_get_kerning( glyph, text[i-1] ); } add_glyph( glyph, buffer, &markup, &pen, kerning ); } } texture_font_delete (font ); } // ---------------------------------------------------------------- display --- void display(void) { if( p_invert ) { glClearColor( 0, 0, 0, 1 ); } else { glClearColor( 1, 1, 1, 1 ); } glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glEnable( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, atlas->id ); if( !p_lcd_filtering ) { glEnable( GL_COLOR_MATERIAL ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); if( p_invert ) { glColor4f(1,1,1,1); } else { glColor4f(0,0,0,1); } } else { glEnable( GL_COLOR_MATERIAL ); glBlendFunc( GL_CONSTANT_COLOR_EXT, GL_ONE_MINUS_SRC_COLOR ); glEnable( GL_BLEND ); glColor3f( 1,1,1 ); if( p_invert ) { glBlendColor( 1, 1, 1, 1 ); } else { glBlendColor( 0, 0, 0, 1 ); } } if( !p_lcd_filtering ) { vertex_buffer_render( buffer, GL_TRIANGLES, "vt" ); } else { glUseProgram( program ); glUniform1i( texture_location, 0 ); glUniform1f( gamma_location, p_gamma ); float norm = 1.0/(p_primary+2*p_secondary+2*p_tertiary); glUniform1f( primary_location, p_primary*norm ); glUniform1f( secondary_location, p_secondary*norm ); glUniform1f( tertiary_location, p_tertiary*norm ); glUniform2f( pixel_location, 1.0/atlas->width, 1.0/atlas->height ); vertex_buffer_render( buffer, GL_TRIANGLES, "vtc" ); glUseProgram( 0 ); } TwDraw( ); glutSwapBuffers( ); } // ---------------------------------------------------------------- reshape --- void reshape( int width, int height ) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, width, 0, height, -1, 1); glMatrixMode(GL_MODELVIEW); TwWindowSize( width, height ); }
// ----------------------------------------------------------- build_buffer --- void build_buffer( void ) { vec2 pen; texture_font_t *font; vec4 black = {{0.0, 0.0, 0.0, 1.0}}; vec4 white = {{1.0, 1.0, 1.0, 1.0}}; vec4 none = {{1.0, 1.0, 1.0, 0.0}}; vec4 color = white; if( p_invert ) { color = black; } markup_t markup = { .family = "Source Sans Pro", .size = 10.0, .bold = 0, .italic = 0, .spacing = p_interval, .gamma = p_gamma, .foreground_color = color, .background_color = none, .underline = 0, .underline_color = color, .overline = 0, .overline_color = color, .strikethrough = 0, .strikethrough_color = color, .font = 0, }; text_buffer_clear( text_buffer ); texture_atlas_t * atlas = font_manager->atlas; texture_atlas_clear( atlas ); if( p_family == VERA) { font = texture_font_new_from_file( atlas, p_size, "fonts/Vera.ttf" ); } else if( p_family == VERA_MONO) { font = texture_font_new_from_file( atlas, p_size, "fonts/VeraMono.ttf" ); } else if( p_family == LUCKIEST_GUY) { font = texture_font_new_from_file( atlas, p_size, "fonts/LuckiestGuy.ttf" ); } else if( p_family == SOURCE_SANS ) { font = texture_font_new_from_file( atlas, p_size, "fonts/SourceSansPro-Regular.ttf" ); } else if( p_family == SOURCE_CODE ) { font = texture_font_new_from_file( atlas, p_size, "fonts/SourceCodePro-Regular.ttf" ); } else if( p_family == OLD_STANDARD ) { font = texture_font_new_from_file( atlas, p_size, "fonts/OldStandard-Regular.ttf" ); } else if( p_family == LOBSTER ) { font = texture_font_new_from_file( atlas, p_size, "fonts/Lobster-Regular.ttf" ); } else { fprintf( stderr, "Error : Unknown family type\n" ); return; } if (!font) return; markup.font = font; font->hinting = p_hinting; font->kerning = p_kerning; font->filtering = 1; float norm = 1.0/(p_primary + 2*p_secondary + 2*p_tertiary); font->lcd_weights[0] = (unsigned char)(p_tertiary*norm*255); font->lcd_weights[1] = (unsigned char)(p_secondary*norm*255); font->lcd_weights[2] = (unsigned char)(p_primary*norm*255); font->lcd_weights[3] = (unsigned char)(p_secondary*norm*255); font->lcd_weights[4] = (unsigned char)(p_tertiary*norm*255); pen.x = 10; pen.y = 600 - font->height - 10; text_buffer_printf( text_buffer, &pen, &markup, text, NULL ); // Post-processing for width and orientation vertex_buffer_t * vbuffer = text_buffer->buffer; size_t i; for( i=0; i < vector_size( vbuffer->items ); ++i ) { ivec4 *item = (ivec4 *) vector_get( vbuffer->items, i); glyph_vertex_t * v0 = /* x0,y0 */ (glyph_vertex_t *) vector_get( vbuffer->vertices, item->vstart+0 ); //glyph_vertex_t * v1 = /* x0,y1 */ // (glyph_vertex_t *) vector_get( vbuffer->vertices, item->vstart+1 ); glyph_vertex_t * v2 = /* x1,y1 */ (glyph_vertex_t *) vector_get( vbuffer->vertices, item->vstart+2 ); glyph_vertex_t * v3 = /* x1,y0 */ (glyph_vertex_t *) vector_get( vbuffer->vertices, item->vstart+3 ); float x0 = v0->x, y0 = v0->y; float x1 = v2->x, y1 = v2->y; v2->x = v3->x = x0 + (x1-x0)*p_width; float dy = fabs(y1-y0); float dx = tan(p_faux_italic/180.0 * M_PI) * dy; v0->x += dx; v0->shift = fmod(v0->shift + dx-(int)(dx),1.0); v3->x += dx; v3->shift = fmod(v3->shift + dx-(int)(dx),1.0); } glBindTexture( GL_TEXTURE_2D, font_manager->atlas->id ); GLenum gl_format = (font_manager->atlas->depth == LCD_FILTERING_OFF) ? GL_RED : GL_RGB; glTexImage2D( GL_TEXTURE_2D, 0, gl_format, font_manager->atlas->width, font_manager->atlas->height, 0, gl_format, GL_UNSIGNED_BYTE, font_manager->atlas->data ); texture_font_delete( font ); } // ------------------------------------------------------------------- quit --- void reset( void ) { p_family = VERA; p_size = 12.0; p_invert = 0; p_kerning = 1; p_hinting = 1; p_lcd_filtering = 1; p_gamma = 1.75; p_interval = 0.0; p_weight = 0.33; p_width = 1.0; p_faux_weight = 0.0; p_faux_italic = 0.0; // FT_LCD_FILTER_LIGHT p_primary = 1.0/3.0; p_secondary = 1.0/3.0; p_tertiary = 0.0/3.0; // FT_LCD_FILTER_DEFAULT // p_primary = 3.0/9.0; // p_secondary = 2.0/9.0; // p_tertiary = 1.0/9.0; build_buffer(); }
// ----------------------------------------------------------- build_buffer --- void build_buffer( void ) { vec2 pen; texture_font_t *font; vec4 black = {{0.0, 0.0, 0.0, 1.0}}; vec4 white = {{1.0, 1.0, 1.0, 1.0}}; vec4 none = {{1.0, 1.0, 1.0, 0.0}}; vec4 color = white; if( p_invert ) { color = black; } markup_t markup = { .family = "Source Sans Pro", .size = 10.0, .bold = 0, .italic = 0, .rise = 0.0, .spacing = p_interval, .gamma = p_gamma, .foreground_color = color, .background_color = none, .underline = 0, .underline_color = color, .overline = 0, .overline_color = color, .strikethrough = 0, .strikethrough_color = color, .font = 0, }; text_buffer_clear( buffer ); texture_atlas_t * atlas = buffer->manager->atlas; texture_atlas_clear( atlas ); if( p_family == VERA) { font = texture_font_new_from_file( atlas, p_size, "fonts/Vera.ttf" ); } else if( p_family == VERA_MONO) { font = texture_font_new_from_file( atlas, p_size, "fonts/VeraMono.ttf" ); } else if( p_family == LUCKIEST_GUY) { font = texture_font_new_from_file( atlas, p_size, "fonts/LuckiestGuy.ttf" ); } else if( p_family == SOURCE_SANS ) { font = texture_font_new_from_file( atlas, p_size, "fonts/SourceSansPro-Regular.ttf" ); } else if( p_family == SOURCE_CODE ) { font = texture_font_new_from_file( atlas, p_size, "fonts/SourceCodePro-Regular.ttf" ); } else if( p_family == OLD_STANDARD ) { font = texture_font_new_from_file( atlas, p_size, "fonts/OldStandard-Regular.ttf" ); } else if( p_family == LOBSTER ) { font = texture_font_new_from_file( atlas, p_size, "fonts/Lobster-Regular.ttf" ); } else { fprintf( stderr, "Error : Unknown family type\n" ); return; } if (!font) return; markup.font = font; font->hinting = p_hinting; font->kerning = p_kerning; font->filtering = 1; float norm = 1.0/(p_primary + 2*p_secondary + 2*p_tertiary); font->lcd_weights[0] = (unsigned char)(p_tertiary*norm*256); font->lcd_weights[1] = (unsigned char)(p_secondary*norm*256); font->lcd_weights[2] = (unsigned char)(p_primary*norm*256); font->lcd_weights[3] = (unsigned char)(p_secondary*norm*256); font->lcd_weights[4] = (unsigned char)(p_tertiary*norm*256); pen.x = 10; pen.y = 600 - font->height - 10; text_buffer_printf( buffer, &pen, &markup, text, NULL ); // Post-processing for width and orientation vertex_buffer_t * vbuffer = buffer->buffer; size_t i; for( i=0; i < vector_size( vbuffer->items ); ++i ) { ivec4 *item = (ivec4 *) vector_get( vbuffer->items, i); glyph_vertex_t * v0 = /* x0,y0 */ (glyph_vertex_t *) vector_get( vbuffer->vertices, item->vstart+0 ); //glyph_vertex_t * v1 = /* x0,y1 */ // (glyph_vertex_t *) vector_get( vbuffer->vertices, item->vstart+1 ); glyph_vertex_t * v2 = /* x1,y1 */ (glyph_vertex_t *) vector_get( vbuffer->vertices, item->vstart+2 ); glyph_vertex_t * v3 = /* x1,y0 */ (glyph_vertex_t *) vector_get( vbuffer->vertices, item->vstart+3 ); float x0 = v0->x, y0 = v0->y; float x1 = v2->x, y1 = v2->y; v2->x = v3->x = x0 + (x1-x0)*p_width; float dy = abs(y1-y0); float dx = tan(p_faux_italic/180.0 * M_PI) * dy; v0->x += dx; v0->shift = fmod(v0->shift + dx-(int)(dx),1.0); v3->x += dx; v3->shift = fmod(v3->shift + dx-(int)(dx),1.0); } texture_font_delete( font ); } // ---------------------------------------------------------------- display --- void display( GLFWwindow* window ) { vec4 black = {{0.0, 0.0, 0.0, 1.0}}; vec4 white = {{1.0, 1.0, 1.0, 1.0}}; if( !p_invert ) { glClearColor( 0, 0, 0, 1 ); buffer->base_color = white; } else { glClearColor( 1, 1, 1, 1 ); buffer->base_color = black; } glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glUseProgram( buffer->shader ); { glUniformMatrix4fv( glGetUniformLocation( buffer->shader, "model" ), 1, 0, model.data); glUniformMatrix4fv( glGetUniformLocation( buffer->shader, "view" ), 1, 0, view.data); glUniformMatrix4fv( glGetUniformLocation( buffer->shader, "projection" ), 1, 0, projection.data); text_buffer_render( buffer ); } TwDraw( ); glfwSwapBuffers( window ); }
TextureFont::~TextureFont() { for(std::map<void*, TextureGlyph*>::iterator it = glyphs_.begin(); it != glyphs_.end(); ++it) delete it->second; texture_font_delete(static_cast<texture_font_t*>(self_)); }
Font::~Font() { if(this->FontHandle == 0) { return; } texture_font_delete(this->FontHandle); }
void Font::doRelease() { texture_font_delete(font); font = 0; }