Пример #1
0
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;
}
Пример #2
0
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;
}