void blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y) { rctf rect; if ((!g->width) || (!g->height)) return; if (g->build_tex == 0) { GlyphCacheBLF *gc = font->glyph_cache; if (font->max_tex_size == -1) glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&font->max_tex_size); if (gc->cur_tex == BLF_CURTEX_UNSET) { blf_glyph_cache_texture(font, gc); gc->x_offs = gc->pad; gc->y_offs = 0; } if (gc->x_offs > (gc->p2_width - gc->max_glyph_width)) { gc->x_offs = gc->pad; gc->y_offs += gc->max_glyph_height; if (gc->y_offs > (gc->p2_height - gc->max_glyph_height)) { gc->y_offs = 0; blf_glyph_cache_texture(font, gc); } } g->tex = gc->textures[gc->cur_tex]; g->xoff = gc->x_offs; g->yoff = gc->y_offs; /* prevent glTexSubImage2D from failing if the character * asks for pixels out of bounds, this tends only to happen * with very small sizes (5px high or less) */ if (UNLIKELY((g->xoff + g->width) > gc->p2_width)) { g->width -= (g->xoff + g->width) - gc->p2_width; BLI_assert(g->width > 0); } if (UNLIKELY((g->yoff + g->height) > gc->p2_height)) { g->height -= (g->yoff + g->height) - gc->p2_height; BLI_assert(g->height > 0); } glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glBindTexture(GL_TEXTURE_2D, g->tex); glTexSubImage2D(GL_TEXTURE_2D, 0, g->xoff, g->yoff, g->width, g->height, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap); glPopClientAttrib(); g->uv[0][0] = ((float)g->xoff) / ((float)gc->p2_width); g->uv[0][1] = ((float)g->yoff) / ((float)gc->p2_height); g->uv[1][0] = ((float)(g->xoff + g->width)) / ((float)gc->p2_width); g->uv[1][1] = ((float)(g->yoff + g->height)) / ((float)gc->p2_height); /* update the x offset for the next glyph. */ gc->x_offs += (int)BLI_rctf_size_x(&g->box) + gc->pad; gc->rem_glyphs--; g->build_tex = 1; } blf_glyph_calc_rect(&rect, g, x, y); if (font->flags & BLF_CLIPPING) { /* intentionally check clipping without shadow offset */ rctf rect_test = rect; BLI_rctf_translate(&rect_test, font->pos[0], font->pos[1]); if (!BLI_rctf_inside_rctf(&font->clip_rec, &rect_test)) { return; } } if (font->tex_bind_state != g->tex) { glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state = g->tex)); } if (font->flags & BLF_SHADOW) { rctf rect_ofs; blf_glyph_calc_rect(&rect_ofs, g, x + (float)font->shadow_x, y + (float)font->shadow_y); switch (font->shadow) { case 3: blf_texture3_draw(font->shadow_col, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax); break; case 5: blf_texture5_draw(font->shadow_col, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax); break; default: glColor4fv(font->shadow_col); blf_texture_draw(g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax); break; } glColor4fv(font->orig_col); } switch (font->blur) { case 3: blf_texture3_draw(font->orig_col, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax); break; case 5: blf_texture5_draw(font->orig_col, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax); break; default: blf_texture_draw(g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax); break; } return; }
int blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y) { float dx, dx1; float y1, y2; float xo, yo; if ((!g->width) || (!g->height)) return 1; if (g->build_tex == 0) { GlyphCacheBLF *gc = font->glyph_cache; if (font->max_tex_size == -1) glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&font->max_tex_size); if (gc->cur_tex == -1) { blf_glyph_cache_texture(font, gc); gc->x_offs = gc->pad; gc->y_offs = gc->pad; } if (gc->x_offs > (gc->p2_width - gc->max_glyph_width)) { gc->x_offs = gc->pad; gc->y_offs += gc->max_glyph_height; if (gc->y_offs > (gc->p2_height - gc->max_glyph_height)) { gc->y_offs = gc->pad; blf_glyph_cache_texture(font, gc); } } g->tex = gc->textures[gc->cur_tex]; g->xoff = gc->x_offs; g->yoff = gc->y_offs; glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glBindTexture(GL_TEXTURE_2D, g->tex); glTexSubImage2D(GL_TEXTURE_2D, 0, g->xoff, g->yoff, g->width, g->height, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap); glPopClientAttrib(); g->uv[0][0] = ((float)g->xoff) / ((float)gc->p2_width); g->uv[0][1] = ((float)g->yoff) / ((float)gc->p2_height); g->uv[1][0] = ((float)(g->xoff + g->width)) / ((float)gc->p2_width); g->uv[1][1] = ((float)(g->yoff + g->height)) / ((float)gc->p2_height); /* update the x offset for the next glyph. */ gc->x_offs += (int)(g->box.xmax - g->box.xmin + gc->pad); gc->rem_glyphs--; g->build_tex = 1; } xo = 0.0f; yo = 0.0f; if (font->flags & BLF_SHADOW) { xo = x; yo = y; x += font->shadow_x; y += font->shadow_y; } dx = floor(x + g->pos_x); dx1 = dx + g->width; y1 = y + g->pos_y; y2 = y + g->pos_y - g->height; if (font->flags & BLF_CLIPPING) { if (!BLI_in_rctf(&font->clip_rec, dx + font->pos[0], y1 + font->pos[1])) return 0; if (!BLI_in_rctf(&font->clip_rec, dx + font->pos[0], y2 + font->pos[1])) return 0; if (!BLI_in_rctf(&font->clip_rec, dx1 + font->pos[0], y2 + font->pos[1])) return 0; if (!BLI_in_rctf(&font->clip_rec, dx1 + font->pos[0], y1 + font->pos[1])) return 0; } if (font->tex_bind_state != g->tex) { glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state = g->tex)); } if (font->flags & BLF_SHADOW) { switch (font->shadow) { case 3: blf_texture3_draw(font->shadow_col, g->uv, dx, y1, dx1, y2); break; case 5: blf_texture5_draw(font->shadow_col, g->uv, dx, y1, dx1, y2); break; default: glColor4fv(font->shadow_col); blf_texture_draw(g->uv, dx, y1, dx1, y2); break; } glColor4fv(font->orig_col); x = xo; y = yo; dx = floor(x + g->pos_x); dx1 = dx + g->width; y1 = y + g->pos_y; y2 = y + g->pos_y - g->height; } switch (font->blur) { case 3: blf_texture3_draw(font->orig_col, g->uv, dx, y1, dx1, y2); break; case 5: blf_texture5_draw(font->orig_col, g->uv, dx, y1, dx1, y2); break; default: blf_texture_draw(g->uv, dx, y1, dx1, y2); break; } return 1; }