1. make software font draw code actually use cutouts.

2. make gl engine able to use cutouts - in some cases its faster, some
slower. it's a mixed bag. not sure what to make of it. it's #defined to be
disabled atm.



SVN revision: 39114
This commit is contained in:
Carsten Haitzler 2009-02-21 03:13:49 +00:00
parent b496774e9e
commit 7a74942b41
5 changed files with 189 additions and 64 deletions

View File

@ -166,59 +166,23 @@ evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, int gl)
return 0;
}
EAPI void
evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const char *text)
static void
evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const char *text,
RGBA_Gfx_Func func, int ext_x, int ext_y, int ext_w, int ext_h, RGBA_Font_Int *fi,
int im_w, int im_h, int use_kerning
)
{
int use_kerning;
int pen_x, pen_y;
int chr;
FT_UInt prev_index;
RGBA_Gfx_Func func;
int ext_x, ext_y, ext_w, ext_h;
DATA32 *im;
int im_w, im_h;
int c;
RGBA_Font_Int *fi;
FT_Face pface = NULL;
fi = fn->fonts->data;
im = dst->image.data;
im_w = dst->cache_entry.w;
im_h = dst->cache_entry.h;
ext_x = 0; ext_y = 0; ext_w = im_w; ext_h = im_h;
if (dc->clip.use)
{
ext_x = dc->clip.x;
ext_y = dc->clip.y;
ext_w = dc->clip.w;
ext_h = dc->clip.h;
if (ext_x < 0)
{
ext_w += ext_x;
ext_x = 0;
}
if (ext_y < 0)
{
ext_h += ext_y;
ext_y = 0;
}
if ((ext_x + ext_w) > im_w)
ext_w = im_w - ext_x;
if ((ext_y + ext_h) > im_h)
ext_h = im_h - ext_y;
}
if (ext_w <= 0) return;
if (ext_h <= 0) return;
FT_UInt prev_index;
DATA32 *im;
int c;
pen_x = x;
pen_y = y;
LKL(fn->lock);
evas_common_font_size_use(fn);
use_kerning = FT_HAS_KERNING(fi->src->ft.face);
prev_index = 0;
func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst, 1, dc->render_op);
im = dst->image.data;
for (c = 0, chr = 0; text[chr];)
{
FT_UInt index;
@ -383,5 +347,82 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
pen_x += fg->glyph->advance.x >> 16;
prev_index = index;
}
}
EAPI void
evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const char *text)
{
int ext_x, ext_y, ext_w, ext_h;
int im_w, im_h;
int use_kerning;
RGBA_Gfx_Func func;
RGBA_Font_Int *fi;
Cutout_Rects *rects;
Cutout_Rect *r;
int c, cx, cy, cw, ch;
int i;
fi = fn->fonts->data;
im_w = dst->cache_entry.w;
im_h = dst->cache_entry.h;
ext_x = 0; ext_y = 0; ext_w = im_w; ext_h = im_h;
if (dc->clip.use)
{
ext_x = dc->clip.x;
ext_y = dc->clip.y;
ext_w = dc->clip.w;
ext_h = dc->clip.h;
if (ext_x < 0)
{
ext_w += ext_x;
ext_x = 0;
}
if (ext_y < 0)
{
ext_h += ext_y;
ext_y = 0;
}
if ((ext_x + ext_w) > im_w)
ext_w = im_w - ext_x;
if ((ext_y + ext_h) > im_h)
ext_h = im_h - ext_y;
}
if (ext_w <= 0) return;
if (ext_h <= 0) return;
LKL(fn->lock);
evas_common_font_size_use(fn);
use_kerning = FT_HAS_KERNING(fi->src->ft.face);
func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst, 1, dc->render_op);
if (!dc->cutout.rects)
{
evas_common_font_draw_internal(dst, dc, fn, x, y, text,
func, ext_x, ext_y, ext_w, ext_h, fi,
im_w, im_h, use_kerning
);
}
else
{
evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
/* our clip is 0 size.. abort */
if ((dc->clip.w > 0) && (dc->clip.h > 0))
{
rects = evas_common_draw_context_apply_cutouts(dc);
for (i = 0; i < rects->active; ++i)
{
r = rects->rects + i;
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
evas_common_font_draw_internal(dst, dc, fn, x, y, text,
func, r->x, r->y, r->w, r->h, fi,
im_w, im_h, use_kerning
);
}
evas_common_draw_context_apply_clear_cutouts(rects);
}
}
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
LKU(fn->lock);
}

View File

@ -1,6 +1,8 @@
#ifndef EVAS_GL_COMMON_H
#define EVAS_GL_COMMON_H
#define EVAS_GL_COMMON_NOCUTOUTS 1
/* FIXME: need to handle memory errors */
/* FIXME: need to handle list errors */
/* FIXME: need to handle gl errors */

View File

@ -198,7 +198,11 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy
double tx1, ty1, tx2, ty2;
int ow, oh;
int space;
Cutout_Rects *rects;
Cutout_Rect *rct;
int c, cx, cy, cw, ch;
int i;
if (sw < 1) sw = 1;
if (sh < 1) sh = 1;
dc = gc->dc;
@ -299,7 +303,7 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy
abort();
break;
}
// if ((!im->tex->have_mipmaps) && (smooth) &&
// ((im->tex->uw < im->tex->tw) || (im->tex->uh < im->tex->th)) &&
// (!gc->ext.sgis_generate_mipmap))
@ -309,20 +313,53 @@ evas_gl_common_image_draw(Evas_GL_Context *gc, Evas_GL_Image *im, int sx, int sy
if ((a < 255) || im->im->cache_entry.flags.alpha)
evas_gl_common_context_blend_set(gc, 1);
else evas_gl_common_context_blend_set(gc, 0);
if (dc->clip.use)
evas_gl_common_context_clip_set(gc, 1,
dc->clip.x, dc->clip.y,
dc->clip.w, dc->clip.h);
else
evas_gl_common_context_clip_set(gc, 0,
0, 0, 0, 0);
evas_gl_common_context_read_buf_set(gc, GL_BACK);
evas_gl_common_context_write_buf_set(gc, GL_BACK);
glBegin(GL_QUADS);
glTexCoord2d(tx1, ty1); glVertex2i(dx , dy );
glTexCoord2d(tx2, ty1); glVertex2i(dx + dw, dy );
glTexCoord2d(tx2, ty2); glVertex2i(dx + dw, dy + dh);
glTexCoord2d(tx1, ty2); glVertex2i(dx , dy + dh);
glEnd();
if (!gc->dc->cutout.rects)
{
if (gc->dc->clip.use)
evas_gl_common_context_clip_set(gc, 1,
gc->dc->clip.x, gc->dc->clip.y,
gc->dc->clip.w, gc->dc->clip.h);
else
evas_gl_common_context_clip_set(gc, 0,
0, 0, 0, 0);
glBegin(GL_QUADS);
glTexCoord2d(tx1, ty1); glVertex2i(dx , dy );
glTexCoord2d(tx2, ty1); glVertex2i(dx + dw, dy );
glTexCoord2d(tx2, ty2); glVertex2i(dx + dw, dy + dh);
glTexCoord2d(tx1, ty2); glVertex2i(dx , dy + dh);
glEnd();
return;
}
/* save out clip info */
c = gc->dc->clip.use; cx = gc->dc->clip.x; cy = gc->dc->clip.y; cw = gc->dc->clip.w; ch = gc->dc->clip.h;
evas_common_draw_context_clip_clip(gc->dc, 0, 0, gc->w, gc->h);
evas_common_draw_context_clip_clip(gc->dc, dx, dy, dw, dh);
/* our clip is 0 size.. abort */
if ((gc->dc->clip.w <= 0) || (gc->dc->clip.h <= 0))
{
gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
return;
}
rects = evas_common_draw_context_apply_cutouts(dc);
for (i = 0; i < rects->active; ++i)
{
rct = rects->rects + i;
if (gc->dc->clip.use)
evas_gl_common_context_clip_set(gc, 1, rct->x, rct->y, rct->w, rct->h);
else
evas_gl_common_context_clip_set(gc, 0,
0, 0, 0, 0);
glBegin(GL_QUADS);
glTexCoord2d(tx1, ty1); glVertex2i(dx , dy );
glTexCoord2d(tx2, ty1); glVertex2i(dx + dw, dy );
glTexCoord2d(tx2, ty2); glVertex2i(dx + dw, dy + dh);
glTexCoord2d(tx1, ty2); glVertex2i(dx , dy + dh);
glEnd();
}
evas_common_draw_context_apply_clear_cutouts(rects);
/* restore clip info */
gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
}

View File

@ -1,7 +1,7 @@
#include "evas_gl_private.h"
void
evas_gl_common_rect_draw(Evas_GL_Context *gc, int x, int y, int w, int h)
static void
evas_gl_common_rect_draw_internal(Evas_GL_Context *gc, int x, int y, int w, int h)
{
int r, g, b, a;
RGBA_Draw_Context *dc = gc->dc;
@ -30,3 +30,42 @@ evas_gl_common_rect_draw(Evas_GL_Context *gc, int x, int y, int w, int h)
glVertex2i(x, y + h);
glEnd();
}
void
evas_gl_common_rect_draw(Evas_GL_Context *gc, int x, int y, int w, int h)
{
Cutout_Rects *rects;
Cutout_Rect *r;
int c, cx, cy, cw, ch;
int i;
if ((w <= 0) || (h <= 0)) return;
if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, gc->w, gc->h)))
return;
/* save out clip info */
c = gc->dc->clip.use; cx = gc->dc->clip.x; cy = gc->dc->clip.y; cw = gc->dc->clip.w; ch = gc->dc->clip.h;
evas_common_draw_context_clip_clip(gc->dc, 0, 0, gc->w, gc->h);
/* no cutouts - cut right to the chase */
if (!gc->dc->cutout.rects)
{
evas_gl_common_rect_draw_internal(gc, x, y, w, h);
}
else
{
evas_common_draw_context_clip_clip(gc->dc, x, y, w, h);
/* our clip is 0 size.. abort */
if ((gc->dc->clip.w > 0) && (gc->dc->clip.h > 0))
{
rects = evas_common_draw_context_apply_cutouts(gc->dc);
for (i = 0; i < rects->active; ++i)
{
r = rects->rects + i;
evas_common_draw_context_set_clip(gc->dc, r->x, r->y, r->w, r->h);
evas_gl_common_rect_draw_internal(gc, x, y, w, h);
}
evas_common_draw_context_apply_clear_cutouts(rects);
}
}
/* restore clip info */
gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
}

View File

@ -313,7 +313,10 @@ eng_context_cutout_add(void *data, void *context, int x, int y, int w, int h)
Render_Engine *re;
re = (Render_Engine *)data;
/* not used in gl engine */
#ifndef EVAS_GL_COMMON_NOCUTOUTS
re->win->gl_context->dc = context;
evas_common_draw_context_add_cutout(context, x, y, w, h);
#endif
}
static void
@ -322,7 +325,10 @@ eng_context_cutout_clear(void *data, void *context)
Render_Engine *re;
re = (Render_Engine *)data;
/* not used in gl engine */
#ifndef EVAS_GL_COMMON_NOCUTOUTS
re->win->gl_context->dc = context;
evas_common_draw_context_clear_cutouts(context);
#endif
}
static void