Exemple #1
0
bool FontRenderer::InitFontRenderer()
{
    m_pManager = font_manager_new( 512, 512, 1 );
    
    if (!m_pManager) {
        fprintf(stderr, "%s:%d - error initializing the font manager\n", __FILE__, __LINE__);
        return false;
    }
    
    m_pFont = font_manager_get_from_markup( m_pManager, &markup );

    if (!m_pFont) {
        fprintf(stderr, "%s:%d - error getting the font\n", __FILE__, __LINE__);
        return false;
    }

    m_pTextBuffer = vertex_buffer_new( "v3f:t2f:c4f" );
    
    if (!m_pTextBuffer) {
        fprintf(stderr, "%s:%d - error creating the text buffer\n", __FILE__, __LINE__);
        return false;
    }
       
    if (!m_fontShader.InitFontShader()) {
        fprintf(stderr, "%s:%d - error compiling the shader program\n", __FILE__, __LINE__);
        return false;
    }    
    
    m_fontShader.Enable();
    m_fontShader.SetFontMapTextureUnit(0);
    
    return true;    
}
Exemple #2
0
// ----------------------------------------------------------------------------
void
text_buffer_add_text( text_buffer_t * self,
                      vec2 * pen, markup_t * markup,
                      const char * text, size_t length )
{
    font_manager_t * manager = self->manager;
    size_t i;
    const char * prev_character = NULL;

    if( markup == NULL )
    {
        return;
    }

    if( !markup->font )
    {
        markup->font = font_manager_get_from_markup( manager, markup );
        if( ! markup->font )
        {
            fprintf( stderr, "Houston, we've got a problem !\n" );
            exit( EXIT_FAILURE );
        }
    }

    if( length == 0 )
    {
        length = utf8_strlen(text);
    }
    if( vertex_buffer_size( self->buffer ) == 0 )
    {
        self->origin = *pen;
        self->line_left = pen->x;
        self->bounds.left = pen->x;
        self->bounds.top = pen->y;
    }
    else
    {
        if (pen->x < self->origin.x)
        {
            self->origin.x = pen->x;
        }
        if (pen->y != self->last_pen_y)
        {
            text_buffer_finish_line(self, pen, false);
        }
    }

    for( i = 0; utf8_strlen( text + i ) && length; i += utf8_surrogate_len( text + i ) )
    {
        text_buffer_add_char( self, pen, markup, text + i, prev_character );
        prev_character = text + i;
        length--;
    }

    self->last_pen_y = pen->y;
}
/* ----------------------------------------------------------------- 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 );
        }
    }
}
Exemple #5
0
// ----------------------------------------------------------------------------
void
text_buffer_add_text( text_buffer_t * self,
                      vec2 * pen, markup_t * markup,
                      wchar_t * text, size_t length )
{
    font_manager_t * manager = self->manager;
    size_t i;

    if( markup == NULL )
    {
        return;
    }

    if( !markup->font )
    {
        markup->font = font_manager_get_from_markup( manager, markup );
        if( ! markup->font )
        {
            fprintf( stderr, "Houston, we've got a problem !\n" );
            exit( EXIT_FAILURE );
        }
    }

    if( length == 0 )
    {
        length = wcslen(text);
    }
    if( vertex_buffer_size( self->buffer ) == 0 )
    {
        self->origin = *pen;
    }

    text_buffer_add_wchar( self, pen, markup, text[0], 0 );
    for( i=1; i<length; ++i )
    {
        text_buffer_add_wchar( self, pen, markup, text[i], text[i-1] );
    }
}
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);
	
}
Exemple #7
0
void init()
{
    text_shader = shader_load( "text.vert",
                               "text.frag" );

    font_manager = font_manager_new( 512, 512, LCD_FILTERING_ON );
    buffer = text_buffer_new( );

    vec4 black  = {{0.0, 0.0, 0.0, 1.0}};
    vec4 white  = {{1.0, 1.0, 1.0, 1.0}};
    vec4 yellow = {{1.0, 1.0, 0.0, 1.0}};
    vec4 grey   = {{0.5, 0.5, 0.5, 1.0}};
    vec4 none   = {{1.0, 1.0, 1.0, 0.0}};

    //char *f_normal   = match_description("Vera:size=50");
    char *f_normal   = match_description("Arial");
    char *f_bold     = match_description("Arial", true);
    //char *f_bold     = match_description("sans\\-serif:size=24");
    char *f_italic   = match_description("sans\\-serif", false, true);
    //char *f_italic   = match_description("SimSun", false, true);
    //char *f_japanese = match_description("Droid Sans:size=18:lang=ja");
    //char *f_japanese = match_description("sans-serif:size=18:lang=zh");
    //char *f_japanese = match_description("sans\\-serif:size=18:lang=zh\\-CN");
    //char *f_japanese = match_description("FZLanTingHeiS\\-UL\\-GB:size=18:lang=zh\\-CN"); //ok
    //char *f_japanese = match_description("FZLanTingHeiS\\-UL\\-GB"); //ok
    //char *f_japanese = match_description("Yu Gothic UI Semibold"); //ok
    //char *f_japanese = match_description("jj:size=18"); //ok
    //char *f_japanese = match_description("Brush Script MT"); //ok
    char *f_japanese = match_description("Microsoft JhengHei UI"); //ok
    //char *f_japanese = match_description("华文隶书:size=28:lang=zh\\-CN"); //no
    char *f_math     = match_description("DejaVu Sans");
    printf("init. f_normal: %s f_bold: %s f_italic: %s f_japanese: %s f_math: %s\n" , f_normal, f_bold, f_italic, f_japanese, f_math);
    //printf("init. f_japanese: %s\n" , f_japanese);

    //exit(0);
    markup_t normal = {
        .family  = f_normal,
        .size    = 20.0, .bold    = 0,   .italic  = 0,
        .spacing = 0.0,  .gamma   = 2.,
        .foreground_color    = white, .background_color    = none,
        .outline           = 0,     .outline_color     = white,
        .underline           = 0,     .underline_color     = white,
        .overline            = 0,     .overline_color      = white,
        .strikethrough       = 0,     .strikethrough_color = white,
        .font = 0,
    };
    markup_t highlight = normal; highlight.background_color = grey;
    markup_t reverse   = normal; reverse.foreground_color = black;
                                 reverse.background_color = white;
                                 reverse.gamma = 1.0;
    markup_t overline  = normal; overline.overline = 1;
    markup_t underline = normal; underline.underline = 1;
    markup_t small     = normal; small.size = 10.0;
    markup_t big       = normal; big.size = 48.0;
                                 big.italic = 1;
                                 big.foreground_color = yellow;
    markup_t bold      = normal; bold.bold = 1; bold.family = f_bold;
    markup_t italic    = normal; italic.italic = 1; italic.family = f_italic;
    markup_t japanese  = normal; japanese.family = f_japanese;
    //markup_t japanese  = normal; japanese.family = "C:/Windows/Fonts/simsun.ttc";
    //markup_t japanese  = normal; japanese.family = "c:/qtproject/opengl/freetype-gl/fonts/fireflysung.ttf";
                                 japanese.size = 25.0;
    markup_t math      = normal; math.family = f_math;
#if 1
    normal.font = font_manager_get_from_markup( font_manager, &normal );
    highlight.font = font_manager_get_from_markup( font_manager, &highlight );
    reverse.font = font_manager_get_from_markup( font_manager, &reverse );
    overline.font = font_manager_get_from_markup( font_manager, &overline );
    underline.font = font_manager_get_from_markup( font_manager, &underline );
    small.font = font_manager_get_from_markup( font_manager, &small );
    big.font = font_manager_get_from_markup( font_manager, &big );
    bold.font = font_manager_get_from_markup( font_manager, &bold );
    italic.font = font_manager_get_from_markup( font_manager, &italic );
    japanese.font = font_manager_get_from_markup( font_manager, &japanese );
    math.font = font_manager_get_from_markup( font_manager, &math );
#else
    japanese.font = font_manager_get_from_markup( font_manager, &japanese );
#endif

    vec2 pen = {{20, 200}};
#if 1
    text_buffer_printf( buffer, &pen,
                        &underline, "The",
                        &normal,    " Quick",
                        &big,       " brown ",
                        &reverse,   " fox \n",
                        &italic,    "jumps over ",
                        &bold,      "the lazy ",
                        &normal,    "dog.\n",
                        &small,     "Now is the time for all good men "
                                    "to come to the aid of the party.\n",
                        &italic,    "Ég get etið gler án þess að meiða mig.\n",
                        &japanese,  "aaa张私はガラスを食べられます。 それは私を傷つけません\n",
                        &math,      "ℕ ⊆ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ",
                        NULL );
#else
    text_buffer_printf( buffer, &pen,
                        &japanese,  "Brush Script MT张私はガラスを食べられます。 それは私を傷つけません\n",
                        NULL );
#endif

    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 );
    printf("init font_manager->atlas->width: %d font_manager->atlas->height: %d\n"
            , font_manager->atlas->width, font_manager->atlas->height);

    text_buffer_align( buffer, &pen, ALIGN_CENTER );

    vec4 bounds = text_buffer_get_bounds( buffer, &pen );
    float left = bounds.left;
    float right = bounds.left + bounds.width;
    float top = bounds.top;
    float bottom = bounds.top - bounds.height;

    bounds_shader = shader_load( "v3f-c4f.vert",
                                 "v3f-c4f.frag" );

    lines_buffer = vertex_buffer_new( "vertex:3f,color:4f" );
    vertex_t vertices[] = { { left - 10,         top, 0, 0,0,0,1}, // top
                            {right + 10,         top, 0, 0,0,0,1},

                            { left - 10,      bottom, 0, 0,0,0,1}, // bottom
                            {right + 10,      bottom, 0, 0,0,0,1},

                            {      left,    top + 10, 0, 0,0,0,1}, // left
                            {      left, bottom - 10, 0, 0,0,0,1},
                            {     right,    top + 10, 0, 0,0,0,1}, // right
                            {     right, bottom - 10, 0, 0,0,0,1} };
    GLuint indices[] = { 0,1,2,3,4,5,6,7 };
    vertex_buffer_push_back( lines_buffer, vertices, 8, indices, 8);

    mat4_set_identity( &projection );
    mat4_set_identity( &model );
    mat4_set_identity( &view );
}


// ---------------------------------------------------------------- display ---
void display( GLFWwindow* window )
{
    glClearColor(0.40,0.40,0.45,1.00);
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glColor4f(1.00,1.00,1.00,1.00);
    glUseProgram( text_shader );
    {
        glUniformMatrix4fv( glGetUniformLocation( text_shader, "model" ),
                            1, 0, model.data);
        glUniformMatrix4fv( glGetUniformLocation( text_shader, "view" ),
                            1, 0, view.data);
        glUniformMatrix4fv( glGetUniformLocation( text_shader, "projection" ),
                            1, 0, projection.data);
        glUniform1i( glGetUniformLocation( text_shader, "tex" ), 0 );
        glUniform3f( glGetUniformLocation( text_shader, "pixel" ),
                     1.0f/font_manager->atlas->width,
                     1.0f/font_manager->atlas->height,
                     (float)font_manager->atlas->depth );

        glEnable( GL_BLEND );

        glActiveTexture( GL_TEXTURE0 );
        glBindTexture( GL_TEXTURE_2D, font_manager->atlas->id );

        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
        glBlendColor( 1, 1, 1, 1 );

        vertex_buffer_render( buffer->buffer, GL_TRIANGLES );
        glBindTexture( GL_TEXTURE_2D, 0 );
        glBlendColor( 0, 0, 0, 0 );
        glUseProgram( 0 );
    }

    glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
    glBlendColor( 1.0, 1.0, 1.0, 1.0 );
    glUseProgram( bounds_shader );
    {
        glUniformMatrix4fv( glGetUniformLocation( bounds_shader, "model" ),
                            1, 0, model.data);
        glUniformMatrix4fv( glGetUniformLocation( bounds_shader, "view" ),
                            1, 0, view.data);
        glUniformMatrix4fv( glGetUniformLocation( bounds_shader, "projection" ),
                            1, 0, projection.data);
        vertex_buffer_render( lines_buffer, GL_LINES );
    }
    
    glfwSwapBuffers( window );
}
Exemple #8
0
// ----------------------------------------------------------------------------
void
text_buffer_add_text( text_buffer_t * self,
                      vec2 * pen, markup_t * markup,
                      wchar_t * text, size_t length )
{
    vertex_buffer_t * buffer = self->buffer;
    font_manager_t * manager = self->manager;

    if( markup == NULL )
    {
        return;
    }

    if( !markup->font )
    {
        markup->font = font_manager_get_from_markup( manager, markup );
        if( ! markup->font )
        {
            fprintf( stderr, "Houston, we've got a problem !\n" );
            exit( EXIT_FAILURE );
        }
    }

    if( length == 0 )
    {
        length = wcslen(text);
    }

    if( vertex_buffer_size( self->buffer ) == 0 )
    {
        self->origin = *pen;
    }

    if( markup->font->ascender > self->line_ascender )
    {
        size_t i, j;
        float dy = (int)(markup->font->ascender - self->line_ascender);
        for( i=self->line_start; i < vector_size( buffer->items ); ++i )
        {
            ivec4 *item = (ivec4 *) vector_get( buffer->items, i);
            for( j=item->vstart; j<item->vstart+item->vcount; ++j)
            {
                glyph_vertex_t * vertex =
                    (glyph_vertex_t *)  vector_get( buffer->vertices, j );
                vertex->y -= dy;
            }
        }
        self->line_ascender = markup->font->ascender;
        pen->y -= dy;
    }
    if( markup->font->descender < self->line_descender )
    {
        self->line_descender = markup->font->descender;
    }

    text_buffer_add_wchar( self, pen, markup, text[0], 0 );

    size_t i;
    for( i=1; i<length; ++i )
    {
        text_buffer_add_wchar( self, pen, markup, text[i], text[i-1] );
    }
}