efl/legacy/evas/src/modules/engines/gl_common/evas_gl_font.c

201 lines
6.4 KiB
C
Raw Normal View History

#include "evas_gl_private.h"
Evas_GL_Texture *
evas_gl_font_texture_new(Evas_GL_Context *gc, RGBA_Font_Glyph *fg)
{
Evas_GL_Texture *tex;
DATA8 *data;
int w, h, j, nw;
DATA8 *ndata;
int fh;
2005-05-21 19:49:50 -07:00
if (fg->ext_dat) return fg->ext_dat; // FIXME: one engine at a time can do this :(
w = fg->glyph_out->bitmap.width;
h = fg->glyph_out->bitmap.rows;
if ((w == 0) || (h == 0)) return NULL;
data = fg->glyph_out->bitmap.buffer;
j = fg->glyph_out->bitmap.pitch;
if (j < w) j = w;
2005-05-21 19:49:50 -07:00
nw = w;
ndata = alloca(nw *h);
if (!ndata) return NULL;
if (fg->glyph_out->bitmap.num_grays == 256)
{
int x, y;
DATA8 *p1, *p2;
2005-05-21 19:49:50 -07:00
for (y = 0; y < h; y++)
{
p1 = data + (j * y);
p2 = ndata + (nw * y);
for (x = 0; x < w; x++)
{
*p2 = *p1;
p1++;
p2++;
}
}
}
else if (fg->glyph_out->bitmap.num_grays == 0)
{
DATA8 *tmpbuf = NULL, *dp, *tp, bits;
int bi, bj, end;
const DATA8 bitrepl[2] = {0x0, 0xff};
tmpbuf = alloca(w);
if (tmpbuf)
{
int x, y;
DATA8 *p1, *p2;
for (y = 0; y < h; y++)
{
p1 = tmpbuf;
p2 = ndata + (nw * y);
tp = tmpbuf;
dp = data + (y * fg->glyph_out->bitmap.pitch);
for (bi = 0; bi < w; bi += 8)
{
bits = *dp;
if ((w - bi) < 8) end = w - bi;
else end = 8;
for (bj = 0; bj < end; bj++)
{
*tp = bitrepl[(bits >> (7 - bj)) & 0x1];
tp++;
}
dp++;
}
for (x = 0; x < w; x++)
{
*p2 = *p1;
p1++;
p2++;
}
}
}
}
// fh = h;
fh = fg->fi->max_h;
tex = evas_gl_common_texture_alpha_new(gc, ndata, w, h, fh);
tex->sx1 = ((double)(tex->x)) / (double)tex->pt->w;
tex->sy1 = ((double)(tex->y)) / (double)tex->pt->h;
tex->sx2 = ((double)(tex->x + tex->w)) / (double)tex->pt->w;
tex->sy2 = ((double)(tex->y + tex->h)) / (double)tex->pt->h;
return tex;
}
void
evas_gl_font_texture_free(Evas_GL_Texture *tex)
{
if (!tex) return;
evas_gl_common_texture_free(tex);
}
void
evas_gl_font_texture_draw(Evas_GL_Context *gc, void *surface __UNUSED__, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y)
{
Evas_GL_Texture *tex;
Cutout_Rects *rects;
Cutout_Rect *rct;
int r, g, b, a;
double ssx, ssy, ssw, ssh;
int c, cx, cy, cw, ch;
int i;
int sx, sy, sw, sh;
if (dc != gc->dc) return;
tex = fg->ext_dat;
if (!tex) return;
a = (dc->col.col >> 24) & 0xff;
if (a == 0) return;
r = (dc->col.col >> 16) & 0xff;
g = (dc->col.col >> 8 ) & 0xff;
b = (dc->col.col ) & 0xff;
sx = 0; sy = 0; sw = tex->w, sh = tex->h;
if ((!gc->dc->cutout.rects)
// || (gc->dc->cutout.active > 32)
)
{
if (gc->dc->clip.use)
{
int nx, ny, nw, nh;
nx = x; ny = y; nw = tex->w; nh = tex->h;
RECTS_CLIP_TO_RECT(nx, ny, nw, nh,
gc->dc->clip.x, gc->dc->clip.y,
gc->dc->clip.w, gc->dc->clip.h);
if ((nw < 1) || (nh < 1)) return;
if ((nx == x) && (ny == y) && (nw == tex->w) && (nh == tex->h))
{
evas_gl_common_context_font_push(gc, tex,
0.0, 0.0, 0.0, 0.0,
// sx, sy, sw, sh,
x, y, tex->w, tex->h,
r, g, b, a);
return;
}
ssx = (double)sx + ((double)(sw * (nx - x)) / (double)(tex->w));
ssy = (double)sy + ((double)(sh * (ny - y)) / (double)(tex->h));
ssw = ((double)sw * (double)(nw)) / (double)(tex->w);
ssh = ((double)sh * (double)(nh)) / (double)(tex->h);
evas_gl_common_context_font_push(gc, tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
r, g, b, a);
}
else
{
evas_gl_common_context_font_push(gc, tex,
0.0, 0.0, 0.0, 0.0,
// sx, sy, sw, sh,
x, y, tex->w, tex->h,
r, g, b, a);
}
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, x, y, tex->w, tex->h);
/* 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)
{
int nx, ny, nw, nh;
rct = rects->rects + i;
nx = x; ny = y; nw = tex->w; nh = tex->h;
RECTS_CLIP_TO_RECT(nx, ny, nw, nh, rct->x, rct->y, rct->w, rct->h);
if ((nw < 1) || (nh < 1)) continue;
if ((nx == x) && (ny == y) && (nw == tex->w) && (nh == tex->h))
{
evas_gl_common_context_font_push(gc, tex,
0.0, 0.0, 0.0, 0.0,
// sx, sy, sw, sh,
x, y, tex->w, tex->h,
r, g, b, a);
continue;
}
ssx = (double)sx + ((double)(sw * (nx - x)) / (double)(tex->w));
ssy = (double)sy + ((double)(sh * (ny - y)) / (double)(tex->h));
ssw = ((double)sw * (double)(nw)) / (double)(tex->w);
ssh = ((double)sh * (double)(nh)) / (double)(tex->h);
evas_gl_common_context_font_push(gc, tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
r, g, b, a);
}
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;
}