void TTFFontAsset::GetBakedQuad(BakedChar *chardata, int pw, int ph, int unicodeCodepoint, float *xpos, float *ypos, AlignedQuad *q) const { // Bias for DirectX rendering #ifdef USE_OPENGL float d3d_bias = 0; #else float d3d_bias = -0.5f; #endif // USE_OPENGL float ipw = 1.0f / pw, iph = 1.0f / ph; GlyphMap::const_iterator codepointIter = glyphMap.find(unicodeCodepoint); if (codepointIter != glyphMap.end()) { int bakedIdx = codepointIter->second; BakedChar *b = chardata + bakedIdx; int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5); int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5); q->x0 = round_x + d3d_bias; q->y0 = round_y + d3d_bias; q->x1 = round_x + b->x1 - b->x0 + d3d_bias; q->y1 = round_y + b->y1 - b->y0 + d3d_bias; q->s0 = b->x0 * ipw; q->t0 = b->y0 * ipw; q->s1 = b->x1 * iph; q->t1 = b->y1 * iph; *xpos += b->xadvance; } }
static float getTextLength(stbtt_bakedchar *chardata, const char* text) { float xpos = 0; float len = 0; while (*text) { int c = (unsigned char)*text; if (c == '\t') { for (int i = 0; i < 4; ++i) { if (xpos < g_tabStops[i]) { xpos = g_tabStops[i]; break; } } } else if (c >= 32 && c < 128) { stbtt_bakedchar *b = chardata + c - 32; int round_x = STBTT_ifloor((xpos + b->xoff) + 0.5); len = round_x + b->x1 - b->x0 + 0.5f; xpos += b->xadvance; } ++text; } return len; }
float Font::GetTextLength(const char* text, int count) { float xpos = 0; float len = 0; if (count <= 0) count = strlen(text); while (*text && count--) { int c = (unsigned char)*text; if (c == '\t') { for (int i = 0; i < 4; ++i) { if (xpos < g_tabStops[i]) { xpos = g_tabStops[i]; break; } } } else if (c >= 32 && c < 128) { stbtt_bakedchar *b = this->_charData + c-32; int round_x = STBTT_ifloor((xpos + b->xoff) + 0.5); len = round_x + b->x1 - b->x0 + 0.5f; xpos += b->xadvance; } ++text; } return len; }
void Font::GetBakedQuad(int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q) { stbtt_bakedchar *b = this->_charData + char_index; int round_x = STBTT_ifloor(*xpos + b->xoff); int round_y = STBTT_ifloor(*ypos - b->yoff); q->x0 = (float)round_x; q->y0 = (float)round_y; q->x1 = (float)round_x + b->x1 - b->x0; q->y1 = (float)round_y - b->y1 + b->y0; q->s0 = b->x0 / (float)pw; q->t0 = b->y0 / (float)pw; q->s1 = b->x1 / (float)ph; q->t1 = b->y1 / (float)ph; *xpos += b->xadvance; }
void FONT_print( FONT *font, float x, float y, char *text, vec4 *color ) { char vertex_attribute = PROGRAM_get_vertex_attrib_location( font->program, ( char * )"POSITION" ), texcoord_attribute = PROGRAM_get_vertex_attrib_location( font->program, ( char * )"TEXCOORD0" ); glBindVertexArrayOES( 0 ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glDisable( GL_CULL_FACE ); glDisable( GL_DEPTH_TEST ); glDepthMask( GL_FALSE ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); PROGRAM_draw( font->program ); glUniformMatrix4fv( PROGRAM_get_uniform_location( font->program, ( char * )"MODELVIEWPROJECTIONMATRIX"), 1, GL_FALSE, ( float * )GFX_get_modelview_projection_matrix() ); glUniform1i( PROGRAM_get_uniform_location( font->program, ( char * )"DIFFUSE" ), 0 ); if( color ) glUniform4fv( PROGRAM_get_uniform_location( font->program, ( char * )"COLOR" ), 1, ( float * )color ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, font->tid ); glEnableVertexAttribArray( vertex_attribute ); glEnableVertexAttribArray( texcoord_attribute ); while( *text ) { if( *text >= font->first_character && *text <= ( font->first_character + font->count_character ) ) { vec2 vert[ 4 ]; vec2 uv[ 4 ]; stbtt_aligned_quad quad; stbtt_bakedchar *bakedchar = font->character_data + ( *text - font->first_character ); int round_x = STBTT_ifloor( x + bakedchar->xoff ); int round_y = STBTT_ifloor( y - bakedchar->yoff ); quad.x0 = ( float )round_x; quad.y0 = ( float )round_y; quad.x1 = ( float )round_x + bakedchar->x1 - bakedchar->x0; quad.y1 = ( float )round_y - bakedchar->y1 + bakedchar->y0; quad.s0 = bakedchar->x0 / ( float )font->texture_width; quad.t0 = bakedchar->y0 / ( float )font->texture_width; quad.s1 = bakedchar->x1 / ( float )font->texture_height; quad.t1 = bakedchar->y1 / ( float )font->texture_height; x += bakedchar->xadvance; vert[ 0 ].x = quad.x1; vert[ 0 ].y = quad.y0; uv [ 0 ].x = quad.s1; uv [ 0 ].y = quad.t0; vert[ 1 ].x = quad.x0; vert[ 1 ].y = quad.y0; uv [ 1 ].x = quad.s0; uv [ 1 ].y = quad.t0; vert[ 2 ].x = quad.x1; vert[ 2 ].y = quad.y1; uv [ 2 ].x = quad.s1; uv [ 2 ].y = quad.t1; vert[ 3 ].x = quad.x0; vert[ 3 ].y = quad.y1; uv [ 3 ].x = quad.s0; uv [ 3 ].y = quad.t1; glVertexAttribPointer( vertex_attribute, 2, GL_FLOAT, GL_FALSE, 0, ( float * )&vert[ 0 ] ); glVertexAttribPointer( texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 0, ( float * )&uv[ 0 ] ); glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); } ++text; } glEnable( GL_CULL_FACE ); glEnable( GL_DEPTH_TEST ); glDepthMask( GL_TRUE ); glDisable( GL_BLEND ); }