2000-08-01 21:01:18 -07:00
|
|
|
#include "evas_gl_routines.h"
|
2000-08-06 17:50:40 -07:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/types.h>
|
2000-12-27 12:51:39 -08:00
|
|
|
#include <assert.h>
|
|
|
|
|
2000-12-27 13:47:38 -08:00
|
|
|
/* uncomment this is partial buffer swaps slow - problem with glcopypixels? */
|
|
|
|
#define GLSWB 1
|
2000-12-27 12:51:39 -08:00
|
|
|
/* uncomment if your GL implimentation is CRAP at clipping */
|
|
|
|
/* #define GLNOCLIP 1 */
|
|
|
|
|
|
|
|
#define INTERSECTS(x, y, w, h, xx, yy, ww, hh) \
|
|
|
|
((x < (xx + ww)) && \
|
|
|
|
(y < (yy + hh)) && \
|
|
|
|
((x + w) > xx) && \
|
|
|
|
((y + h) > yy))
|
|
|
|
|
|
|
|
#define CLIP_TO(_x, _y, _w, _h, _cx, _cy, _cw, _ch) \
|
|
|
|
{ \
|
|
|
|
if (INTERSECTS(_x, _y, _w, _h, _cx, _cy, _cw, _ch)) \
|
|
|
|
{ \
|
|
|
|
if (_x < _cx) \
|
|
|
|
{ \
|
|
|
|
_w += _x - _cx; \
|
|
|
|
_x = _cx; \
|
|
|
|
if (_w < 0) _w = 0; \
|
|
|
|
} \
|
|
|
|
if ((_x + _w) > (_cx + _cw)) \
|
|
|
|
_w = _cx + _cw - _x; \
|
|
|
|
if (_y < _cy) \
|
|
|
|
{ \
|
|
|
|
_h += _y - _cy; \
|
|
|
|
_y = _cy; \
|
|
|
|
if (_h < 0) _h = 0; \
|
|
|
|
} \
|
|
|
|
if ((_y + _h) > (_cy + _ch)) \
|
|
|
|
_h = _cy + _ch - _y; \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
{ \
|
|
|
|
_w = 0; _h = 0; \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define TT_VALID( handle ) ( ( handle ).z != NULL )
|
2000-08-01 20:33:11 -07:00
|
|
|
|
2000-08-13 17:14:22 -07:00
|
|
|
#ifdef HAVE_GL
|
|
|
|
|
2000-08-01 20:33:11 -07:00
|
|
|
static int __evas_gl_configuration[] =
|
|
|
|
{
|
|
|
|
GLX_DOUBLEBUFFER,
|
|
|
|
GLX_RGBA,
|
|
|
|
GLX_RED_SIZE, 1,
|
|
|
|
GLX_GREEN_SIZE, 1,
|
|
|
|
GLX_BLUE_SIZE, 1,
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static Evas_GL_Window *__evas_current = NULL;
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static Evas_List __evas_windows = NULL;
|
|
|
|
static Evas_List __evas_contexts = NULL;
|
|
|
|
static Evas_List __evas_images = NULL;
|
|
|
|
static Evas_List __evas_fonts = NULL;
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static int __evas_image_cache = 0;
|
|
|
|
static int __evas_image_cache_max = 512 * 1024;
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static char **__evas_fpath = NULL;
|
|
|
|
static int __evas_fpath_num = 0;
|
|
|
|
static int __evas_font_cache = 0;
|
|
|
|
static int __evas_font_cache_max = 512 * 1024;
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static int __evas_rend_lut[9] = { 0, 64, 128, 192, 255, 255, 255, 255, 255};
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static int __evas_have_tt_engine = 0;
|
|
|
|
static TT_Engine __evas_tt_engine;
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
/* smooth (linear interp / supersample/mipmap scaling or "nearest" sampling */
|
|
|
|
static int __evas_smooth = 1;
|
|
|
|
/* the current clip region and color */
|
|
|
|
static int __evas_clip = 0;
|
|
|
|
static int __evas_clip_x = 0;
|
|
|
|
static int __evas_clip_y = 0;
|
|
|
|
static int __evas_clip_w = 0;
|
|
|
|
static int __evas_clip_h = 0;
|
|
|
|
static int __evas_clip_r = 0;
|
|
|
|
static int __evas_clip_g = 0;
|
|
|
|
static int __evas_clip_b = 0;
|
|
|
|
static int __evas_clip_a = 0;
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static Evas_GL_Context *
|
|
|
|
__evas_gl_context_new(Display *disp, int screen)
|
|
|
|
{
|
|
|
|
Evas_GL_Context *c;
|
|
|
|
XSetWindowAttributes att;
|
|
|
|
int eb, evb;
|
|
|
|
|
|
|
|
if (!glXQueryExtension(disp, &eb, &evb)) return NULL;
|
|
|
|
c = malloc(sizeof(Evas_GL_Context));
|
|
|
|
c->disp = disp;
|
|
|
|
c->screen = screen;
|
|
|
|
c->visualinfo = glXChooseVisual(c->disp, c->screen, __evas_gl_configuration);
|
|
|
|
c->visual = c->visualinfo->visual;
|
|
|
|
c->context = glXCreateContext(c->disp, c->visualinfo, NULL, GL_TRUE);
|
|
|
|
c->root = RootWindow(c->disp, c->screen);
|
|
|
|
c->colormap = XCreateColormap(c->disp, c->root, c->visual, 0);
|
|
|
|
att.colormap = c->colormap;
|
|
|
|
att.border_pixel = 0;
|
|
|
|
att.event_mask = 0;
|
|
|
|
c->win = XCreateWindow(c->disp, c->root, 0, 0, 1, 1, 0,
|
|
|
|
c->visualinfo->depth, InputOutput,
|
|
|
|
c->visual, CWColormap | CWBorderPixel | CWEventMask,
|
|
|
|
&att);
|
|
|
|
glXMakeCurrent(c->disp, c->win, c->context);
|
|
|
|
glShadeModel(GL_FLAT);
|
|
|
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
|
|
|
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
|
|
|
glEnable(GL_LINE_SMOOTH);
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
|
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
|
|
|
|
|
|
|
c->texture = 0;
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
c->dither = 0;
|
|
|
|
glDisable(GL_DITHER);
|
|
|
|
c->blend = 1;
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
c->color = 0xffffffff;
|
|
|
|
glColor4f(1.0, 1.0, 1.0, 1.0);
|
|
|
|
|
|
|
|
c->clip.active = 0;
|
|
|
|
c->clip.x = 0;
|
|
|
|
c->clip.y = 0;
|
|
|
|
c->clip.w = 0;
|
|
|
|
c->clip.h = 0;
|
|
|
|
glDisable(GL_SCISSOR_TEST);
|
|
|
|
|
|
|
|
c->read_buf = GL_BACK;
|
|
|
|
glReadBuffer(GL_BACK);
|
|
|
|
c->write_buf = GL_FRONT;
|
|
|
|
glDrawBuffer(GL_BACK);
|
|
|
|
|
|
|
|
c->bound_texture = NULL;
|
|
|
|
|
|
|
|
/* FIXME: need to determine these */
|
|
|
|
c->max_texture_depth = 32;
|
|
|
|
c->max_texture_size = 256;
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static Evas_GL_Context *
|
|
|
|
__evas_gl_context_lookup(Display *disp, int screen)
|
|
|
|
{
|
|
|
|
Evas_List l;
|
|
|
|
Evas_GL_Context *c;
|
|
|
|
|
|
|
|
for (l = __evas_contexts; l; l = l->next)
|
|
|
|
{
|
|
|
|
c = l->data;
|
|
|
|
if ((c->disp == disp) && (c->screen == screen))
|
|
|
|
{
|
|
|
|
if (l != __evas_contexts)
|
|
|
|
{
|
|
|
|
__evas_contexts = evas_list_remove(__evas_contexts, c);
|
|
|
|
__evas_contexts = evas_list_prepend(__evas_contexts, c);
|
|
|
|
}
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
c = __evas_gl_context_new(disp, screen);
|
|
|
|
if (!c) return NULL;
|
|
|
|
__evas_contexts = evas_list_prepend(__evas_contexts, c);
|
|
|
|
return c;
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static Evas_GL_Window *
|
|
|
|
__evas_gl_window_new(Display *disp, Window win)
|
|
|
|
{
|
|
|
|
Evas_GL_Context *c;
|
|
|
|
Evas_GL_Window *w;
|
|
|
|
Window root;
|
|
|
|
int screen, i;
|
|
|
|
XWindowAttributes att;
|
|
|
|
|
|
|
|
XGetWindowAttributes(disp, win, &att);
|
|
|
|
root = att.root;
|
|
|
|
screen = 0;
|
|
|
|
for (i = 0; i < ScreenCount(disp); i++)
|
|
|
|
{
|
|
|
|
if (RootWindow(disp, i) == root)
|
|
|
|
{
|
|
|
|
screen = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
c = __evas_gl_context_lookup(disp, screen);
|
|
|
|
if (!c) return NULL;
|
|
|
|
w = malloc(sizeof(Evas_GL_Window));
|
|
|
|
w->disp = disp;
|
|
|
|
w->win = win;
|
|
|
|
w->context = c;
|
|
|
|
w->root = root;
|
|
|
|
w->screen = screen;
|
|
|
|
w->updates = NULL;
|
|
|
|
w->w = 0;
|
|
|
|
w->h = 0;
|
|
|
|
return w;
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static Evas_GL_Window *
|
|
|
|
__evas_gl_window_lookup(Display *disp, Window win)
|
|
|
|
{
|
|
|
|
Evas_List l;
|
|
|
|
Evas_GL_Window *w;
|
|
|
|
|
|
|
|
for (l = __evas_windows; l; l = l->next)
|
|
|
|
{
|
|
|
|
w = l->data;
|
|
|
|
if ((w->win == win) && (w->disp == disp))
|
|
|
|
{
|
|
|
|
if (l != __evas_windows)
|
|
|
|
{
|
|
|
|
__evas_windows = evas_list_remove(__evas_windows, w);
|
|
|
|
__evas_windows = evas_list_prepend(__evas_windows, w);
|
|
|
|
}
|
|
|
|
return w;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
w = __evas_gl_window_new(disp, win);
|
|
|
|
if (!w) return NULL;
|
|
|
|
__evas_windows = evas_list_prepend(__evas_windows, w);
|
|
|
|
return w;
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static Evas_GL_Window *
|
|
|
|
__evas_gl_window_current(Display *disp, Window win, int w, int h)
|
|
|
|
{
|
|
|
|
Evas_GL_Window *glw;
|
|
|
|
|
|
|
|
glw = __evas_gl_window_lookup(disp, win);
|
|
|
|
if (!glw) return NULL;
|
|
|
|
if (glw != __evas_current)
|
|
|
|
{
|
|
|
|
__evas_current = glw;
|
|
|
|
glXMakeCurrent(glw->disp, glw->win, glw->context->context);
|
|
|
|
glShadeModel(GL_FLAT);
|
|
|
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
|
|
|
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
|
|
|
glEnable(GL_LINE_SMOOTH);
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
|
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
|
|
|
if (glw->context->dither) glEnable(GL_DITHER);
|
|
|
|
else glDisable(GL_DITHER);
|
|
|
|
if (glw->context->blend)
|
|
|
|
{
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
}
|
|
|
|
else glDisable(GL_BLEND);
|
|
|
|
if (glw->context->texture) glEnable(GL_TEXTURE_2D);
|
|
|
|
else glDisable(GL_TEXTURE_2D);
|
|
|
|
glColor4d((double)((glw->context->color >> 24) & 0xff) / 255.0,
|
|
|
|
(double)((glw->context->color >> 16) & 0xff) / 255.0,
|
|
|
|
(double)((glw->context->color >> 8) & 0xff) / 255.0,
|
|
|
|
(double)((glw->context->color ) & 0xff) / 255.0);
|
|
|
|
if (glw->context->clip.active)
|
|
|
|
{
|
|
|
|
glEnable(GL_SCISSOR_TEST);
|
|
|
|
glScissor(glw->context->clip.x,
|
|
|
|
glw->h - glw->context->clip.y - glw->context->clip.h,
|
|
|
|
glw->context->clip.w,
|
|
|
|
glw->context->clip.h);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
glDisable(GL_SCISSOR_TEST);
|
|
|
|
if (glw->context->bound_texture)
|
|
|
|
glBindTexture(GL_TEXTURE_2D, glw->context->bound_texture->texture);
|
|
|
|
}
|
2001-02-15 17:33:14 -08:00
|
|
|
if ((glw->w != w) || (glw->h != h))
|
|
|
|
{
|
|
|
|
double dr, dg, db, da;
|
|
|
|
|
|
|
|
glw->w = w;
|
|
|
|
glw->h = h;
|
|
|
|
glViewport(0, 0, glw->w, h);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
|
|
|
glOrtho(0, glw->w, 0, glw->h, -1, 1);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glLoadIdentity();
|
|
|
|
glScalef(1, -1, 1);
|
|
|
|
glTranslatef(0, - glw->h, 0);
|
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
return glw;
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static void
|
|
|
|
__evas_gl_window_dither(Evas_GL_Window *w, int onoff)
|
|
|
|
{
|
|
|
|
if (!w) return;
|
|
|
|
if (w->context->dither == onoff) return;
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
w->context->dither = onoff;
|
|
|
|
if (w->context->dither) glEnable(GL_DITHER);
|
|
|
|
else glDisable(GL_DITHER);
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static void
|
|
|
|
__evas_gl_window_blend(Evas_GL_Window *w, int onoff)
|
|
|
|
{
|
|
|
|
if (!w) return;
|
|
|
|
if (w->context->blend == onoff) return;
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
w->context->blend = onoff;
|
|
|
|
if (w->context->blend)
|
|
|
|
{
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
}
|
|
|
|
else glDisable(GL_BLEND);
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static void
|
|
|
|
__evas_gl_window_texture(Evas_GL_Window *w, int onoff)
|
|
|
|
{
|
|
|
|
if (!w) return;
|
|
|
|
if (w->context->texture == onoff) return;
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
w->context->texture = onoff;
|
|
|
|
if (w->context->texture) glEnable(GL_TEXTURE_2D);
|
|
|
|
else glDisable(GL_TEXTURE_2D);
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static void
|
|
|
|
__evas_gl_window_color(Evas_GL_Window *w, int r, int g, int b, int a)
|
|
|
|
{
|
|
|
|
DATA32 col;
|
|
|
|
|
|
|
|
if (!w) return;
|
|
|
|
col = (r << 24) | (g << 16) | (b << 8) | (a);
|
|
|
|
if (w->context->color == col) return;
|
|
|
|
|
|
|
|
w->context->color = col;
|
|
|
|
glColor4d((double)r / 255.0,
|
|
|
|
(double)g / 255.0,
|
|
|
|
(double)b / 255.0,
|
|
|
|
(double)a / 255.0);
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static void
|
|
|
|
__evas_gl_window_clip(Evas_GL_Window *w, int c, int cx, int cy, int cw, int ch)
|
|
|
|
{
|
|
|
|
if (!w) return;
|
|
|
|
if (w->context->clip.active == c)
|
|
|
|
{
|
|
|
|
if ((c) &&
|
|
|
|
(w->context->clip.x == cx) && (w->context->clip.y == cy) &&
|
|
|
|
(w->context->clip.w == cw) && (w->context->clip.h == ch))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
w->context->clip.active = c;
|
|
|
|
w->context->clip.x = cx;
|
|
|
|
w->context->clip.y = cy;
|
|
|
|
w->context->clip.w = cw;
|
|
|
|
w->context->clip.h = ch;
|
|
|
|
if (w->context->clip.active)
|
|
|
|
{
|
|
|
|
glEnable(GL_SCISSOR_TEST);
|
|
|
|
glScissor(w->context->clip.x,
|
|
|
|
w->h - w->context->clip.y - w->context->clip.h,
|
|
|
|
w->context->clip.w,
|
|
|
|
w->context->clip.h);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
glDisable(GL_SCISSOR_TEST);
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static void
|
|
|
|
__evas_gl_window_write_buf(Evas_GL_Window *w, GLenum buf)
|
|
|
|
{
|
|
|
|
if (!w) return;
|
|
|
|
if (w->context->write_buf != buf)
|
|
|
|
{
|
|
|
|
w->context->write_buf = buf;
|
|
|
|
glDrawBuffer(buf);
|
|
|
|
}
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
|
|
|
static void
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_gl_window_read_buf(Evas_GL_Window *w, GLenum buf)
|
2000-08-01 20:33:11 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
if (!w) return;
|
|
|
|
if (w->context->read_buf != buf)
|
2000-08-10 15:12:42 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
w->context->read_buf = buf;
|
|
|
|
glReadBuffer(buf);
|
2000-08-10 15:12:42 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
__evas_gl_window_swap_rect(Evas_GL_Window *w, int rx, int ry, int rw, int rh)
|
|
|
|
{
|
|
|
|
if (!w) return;
|
|
|
|
|
|
|
|
__evas_gl_window_read_buf(w, GL_BACK);
|
|
|
|
__evas_gl_window_write_buf(w, GL_FRONT);
|
|
|
|
__evas_gl_window_blend(w, 0);
|
|
|
|
__evas_gl_window_clip(w, 0, 0, 0, 0, 0);
|
|
|
|
__evas_gl_window_dither(w, 0);
|
2000-12-27 13:47:38 -08:00
|
|
|
ry = w->h - ry - rh;
|
2000-12-27 12:51:39 -08:00
|
|
|
glRasterPos2i(rx, w->h - ry);
|
|
|
|
glCopyPixels(rx, ry, rw, rh, GL_COLOR);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
__evas_gl_window_use_texture(Evas_GL_Window *w, Evas_GL_Texture *tex, int smooth)
|
|
|
|
{
|
|
|
|
if (!w) return;
|
|
|
|
if (w->context->bound_texture != tex)
|
2000-08-13 17:14:22 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->texture);
|
|
|
|
w->context->bound_texture = tex;
|
2000-08-13 17:14:22 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
if (smooth != tex->smooth)
|
2000-08-10 15:12:42 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
#ifdef HAVE_GLU
|
|
|
|
if (smooth)
|
|
|
|
{
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#else
|
|
|
|
if (smooth)
|
|
|
|
{
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
}
|
|
|
|
tex->smooth = smooth;
|
2000-08-10 15:12:42 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_GL_Texture *
|
|
|
|
__evas_gl_texture_new(Evas_GL_Window *w, Imlib_Image im, int ix, int iy, int iw, int ih)
|
|
|
|
{
|
|
|
|
Evas_GL_Texture *tex;
|
|
|
|
int tx, ty, tw, th, im_w, im_h;
|
|
|
|
DATA32 *data, *p1, *p2, *im_data;
|
|
|
|
int shift;
|
|
|
|
Imlib_Image prev_im;
|
|
|
|
|
|
|
|
if (!w) return NULL;
|
|
|
|
tex = malloc(sizeof(Evas_GL_Texture));
|
|
|
|
shift = 1; while (iw > shift) shift = shift << 1; tw = shift;
|
|
|
|
shift = 1; while (ih > shift) shift = shift << 1; th = shift;
|
|
|
|
tex->w = tw;
|
|
|
|
tex->h = th;
|
|
|
|
glGenTextures(1, &(tex->texture));
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->texture);
|
|
|
|
w->context->bound_texture = tex;
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
|
|
|
tex->smooth = 0;
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
prev_im = imlib_context_get_image();
|
|
|
|
imlib_context_set_image(im);
|
|
|
|
im_data = imlib_image_get_data_for_reading_only();
|
2001-04-28 19:58:17 -07:00
|
|
|
if (!im_data) return tex;
|
|
|
|
data = malloc(tw * th * 4);
|
2000-12-27 12:51:39 -08:00
|
|
|
im_w = imlib_image_get_width();
|
|
|
|
im_h = imlib_image_get_height();
|
|
|
|
for (ty = 0; ty < ih; ty++)
|
2000-08-01 20:33:11 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
p1 = im_data + ((iy + ty) * im_w) + ix;
|
2000-08-01 20:33:11 -07:00
|
|
|
p2 = data + (ty * tw);
|
2000-12-27 12:51:39 -08:00
|
|
|
for (tx = 0; tx < iw; tx++)
|
2000-08-01 20:33:11 -07:00
|
|
|
{
|
2000-08-14 09:43:52 -07:00
|
|
|
#ifndef WORDS_BIGENDIAN
|
2000-08-01 20:33:11 -07:00
|
|
|
*p2 =
|
2000-12-27 12:51:39 -08:00
|
|
|
((*p1 & 0xff000000)) |
|
|
|
|
((*p1 & 0x00ff0000) >> 16) |
|
|
|
|
((*p1 & 0x0000ff00)) |
|
|
|
|
((*p1 & 0x000000ff) << 16);
|
2000-08-14 09:43:52 -07:00
|
|
|
#else
|
|
|
|
*p2 =
|
2000-12-27 12:51:39 -08:00
|
|
|
((*p1 & 0xff000000) >> 24) |
|
|
|
|
((*p1 & 0x00ff0000) << 8) |
|
|
|
|
((*p1 & 0x0000ff00) << 8) |
|
|
|
|
((*p1 & 0x000000ff) << 8);
|
|
|
|
#endif
|
2000-08-01 20:33:11 -07:00
|
|
|
p2++; p1++;
|
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
if (tx < tw)
|
|
|
|
{
|
|
|
|
for (; tx < tw; tx++) *p2 = p2[-1];
|
|
|
|
}
|
2000-08-10 03:14:55 -07:00
|
|
|
}
|
|
|
|
if (ty < th)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
for (; ty < th; ty++)
|
2000-08-10 03:14:55 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
p1 = data + ((ty - 1) * tw);
|
|
|
|
p2 = data + (ty * tw);
|
|
|
|
for (tx = 0; tx < tw; tx++)
|
|
|
|
{
|
|
|
|
*p2 = *p1; p2++; p1++;
|
|
|
|
}
|
2000-08-10 03:14:55 -07:00
|
|
|
}
|
2000-08-01 20:33:11 -07:00
|
|
|
}
|
2000-08-13 17:14:22 -07:00
|
|
|
#ifdef HAVE_GLU
|
2001-04-28 17:48:55 -07:00
|
|
|
/* FIXME: GLU mipmap generation is BLOODY SLOW */
|
|
|
|
if (0) /* if libGLU is fucking slow piece of shit - do it ourselves */
|
2000-10-13 18:10:53 -07:00
|
|
|
{
|
2001-04-28 17:48:55 -07:00
|
|
|
if (imlib_image_has_alpha())
|
|
|
|
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA8, tw, th, GL_RGBA,
|
|
|
|
GL_UNSIGNED_BYTE, data);
|
|
|
|
else
|
|
|
|
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB8, tw, th, GL_RGBA,
|
|
|
|
GL_UNSIGNED_BYTE, data);
|
2000-12-27 12:51:39 -08:00
|
|
|
}
|
|
|
|
#else
|
2001-04-28 17:48:55 -07:00
|
|
|
if (0)
|
2000-12-27 12:51:39 -08:00
|
|
|
{
|
2001-04-28 17:48:55 -07:00
|
|
|
if (imlib_image_has_alpha())
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tw, th, 0,
|
|
|
|
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
|
|
|
else
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, tw, th, 0,
|
|
|
|
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
2000-10-13 18:10:53 -07:00
|
|
|
}
|
2001-04-28 17:48:55 -07:00
|
|
|
#endif
|
2000-08-10 15:12:42 -07:00
|
|
|
else
|
2000-10-13 18:10:53 -07:00
|
|
|
{
|
2001-04-28 17:48:55 -07:00
|
|
|
int mw, mh;
|
|
|
|
int level;
|
|
|
|
Imlib_Image im1 = NULL, im2 = NULL;
|
|
|
|
int alpha = 0;
|
|
|
|
|
|
|
|
mw = tw;
|
|
|
|
mh = th;
|
|
|
|
level = 0;
|
|
|
|
alpha = imlib_image_has_alpha();
|
|
|
|
im1 = imlib_create_image_using_data(tw, th, data);
|
|
|
|
imlib_context_set_image(im1);
|
|
|
|
imlib_image_set_has_alpha(1);
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
int pw, ph;
|
|
|
|
DATA32 *idat;
|
|
|
|
|
|
|
|
imlib_context_set_image(im1);
|
|
|
|
idat = imlib_image_get_data_for_reading_only();
|
|
|
|
if (alpha)
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, mw, mh, 0,
|
|
|
|
GL_RGBA, GL_UNSIGNED_BYTE, idat);
|
|
|
|
else
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, level, GL_RGB8, mw, mh, 0,
|
|
|
|
GL_RGBA, GL_UNSIGNED_BYTE, idat);
|
|
|
|
imlib_image_put_back_data(idat);
|
|
|
|
if ((mw == 1) && (mh == 1)) break;
|
|
|
|
level++;
|
|
|
|
pw = mw; ph = mh;
|
|
|
|
mw >>= 1; if (mw < 1) mw = 1;
|
|
|
|
mh >>= 1; if (mh < 1) mh = 1;
|
|
|
|
im2 = imlib_create_cropped_scaled_image(0, 0, pw, ph, mw, mh);
|
|
|
|
imlib_free_image();
|
|
|
|
im1 = im2; im2 = NULL;
|
|
|
|
imlib_context_set_image(im1);
|
|
|
|
imlib_image_set_has_alpha(1);
|
|
|
|
}
|
|
|
|
if (im1)
|
|
|
|
{
|
|
|
|
imlib_context_set_image(im1);
|
|
|
|
imlib_free_image();
|
|
|
|
im1 = NULL;
|
|
|
|
}
|
2000-10-13 18:10:53 -07:00
|
|
|
}
|
2000-08-01 20:33:11 -07:00
|
|
|
free(data);
|
2001-04-28 17:48:55 -07:00
|
|
|
imlib_context_set_image(im);
|
2000-12-27 12:51:39 -08:00
|
|
|
imlib_image_put_back_data(im_data);
|
|
|
|
imlib_context_set_image(prev_im);
|
|
|
|
return tex;
|
2000-08-01 20:33:11 -07:00
|
|
|
}
|
|
|
|
|
2000-08-05 17:26:34 -07:00
|
|
|
static void
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_gl_texture_free(Evas_GL_Window *w, Evas_GL_Texture *tex)
|
|
|
|
{
|
|
|
|
if (!w) return;
|
|
|
|
glDeleteTextures(1, &tex->texture);
|
|
|
|
if (w->context->bound_texture == tex) w->context->bound_texture = NULL;
|
|
|
|
free(tex);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_GL_Texmesh *
|
|
|
|
__evas_gl_make_image_textures(Evas_GL_Window *w, Evas_GL_Image *image)
|
2000-08-01 20:33:11 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_List l;
|
|
|
|
Evas_GL_Texmesh *tm;
|
|
|
|
int tx, ty, ex, ey, tw, th, ix, iy, iw, ih;
|
|
|
|
int i, shift;
|
|
|
|
Imlib_Image prev_im;
|
2000-08-01 20:33:11 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
for (l = image->textures; l; l = l->next)
|
2000-08-05 13:11:27 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
tm = l->data;
|
|
|
|
if (tm->context == w->context) return tm;
|
2000-08-05 13:11:27 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
tm = malloc(sizeof(Evas_GL_Texmesh));
|
|
|
|
tm->window = w;
|
|
|
|
tm->context = w->context;
|
|
|
|
|
|
|
|
image->textures = evas_list_prepend(image->textures, tm);
|
|
|
|
|
|
|
|
if ((!image->im) && (image->file))
|
|
|
|
image->im = imlib_load_image(image->file);
|
|
|
|
|
|
|
|
tx = (image->w - 2) / (w->context->max_texture_size - 2);
|
|
|
|
ex = (image->w - 1) - (tx * (w->context->max_texture_size - 2));
|
|
|
|
if (tx == 0) ex = image->w;
|
|
|
|
tm->tiles.x_left = ex;
|
|
|
|
shift = 1; while (ex > shift) shift = shift << 1; ex = shift;
|
|
|
|
|
|
|
|
ty = (image->h - 2) / (w->context->max_texture_size - 2);
|
|
|
|
ey = (image->h - 1) - (ty * (w->context->max_texture_size - 2));
|
|
|
|
if (ty == 0) ey = image->h;
|
|
|
|
tm->tiles.y_left = ey;
|
|
|
|
shift = 1; while (ey > shift) shift = shift << 1; ey = shift;
|
|
|
|
|
|
|
|
tm->tiles.x = tx;
|
|
|
|
tm->tiles.y = ty;
|
|
|
|
tm->tiles.x_edge = ex;
|
|
|
|
tm->tiles.y_edge = ey;
|
|
|
|
tm->textures = malloc(sizeof(Evas_GL_Texmesh *) * (tm->tiles.x + 1) * (tm->tiles.y + 1));
|
|
|
|
i = 0;
|
|
|
|
for (ty = 0; ty <= tm->tiles.y; ty++)
|
2000-08-01 20:33:11 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
/* figure out image y,h */
|
|
|
|
/* texture is only an edge size */
|
|
|
|
if ((ty == 0) && (tm->tiles.y == 0))
|
2000-08-01 20:33:11 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
iy = 0;
|
|
|
|
ih = image->h;
|
|
|
|
}
|
|
|
|
/* start edge */
|
|
|
|
else if (ty == 0)
|
|
|
|
{
|
|
|
|
iy = 0;
|
|
|
|
ih = w->context->max_texture_size;
|
|
|
|
}
|
|
|
|
/* end edge */
|
|
|
|
else if (ty == tm->tiles.y)
|
|
|
|
{
|
2000-12-29 12:43:48 -08:00
|
|
|
iy = (w->context->max_texture_size - 1) - 1 +
|
|
|
|
((ty - 1) * (w->context->max_texture_size - 2));
|
2000-12-27 12:51:39 -08:00
|
|
|
ih = image->h - iy;
|
|
|
|
}
|
|
|
|
/* middle tex */
|
|
|
|
else
|
|
|
|
{
|
2000-12-29 12:43:48 -08:00
|
|
|
iy = (w->context->max_texture_size - 1) - 1 +
|
|
|
|
((ty - 1) * (w->context->max_texture_size - 2));
|
2000-12-27 12:51:39 -08:00
|
|
|
ih = w->context->max_texture_size;
|
|
|
|
}
|
|
|
|
for (tx = 0; tx <= tm->tiles.x; tx++)
|
|
|
|
{
|
|
|
|
/* figure out image x,w */
|
|
|
|
/* texture is only an edge size */
|
|
|
|
if ((tx == 0) && (tm->tiles.x == 0))
|
|
|
|
{
|
|
|
|
ix = 0;
|
|
|
|
iw = image->w;
|
|
|
|
}
|
|
|
|
/* start edge */
|
|
|
|
else if (tx == 0)
|
|
|
|
{
|
|
|
|
ix = 0;
|
|
|
|
iw = w->context->max_texture_size;
|
|
|
|
}
|
|
|
|
/* end edge */
|
|
|
|
else if (tx == tm->tiles.x)
|
|
|
|
{
|
2000-12-29 12:43:48 -08:00
|
|
|
ix = (w->context->max_texture_size - 1) - 1 +
|
|
|
|
((tx - 1) * (w->context->max_texture_size - 2));
|
2000-12-27 12:51:39 -08:00
|
|
|
iw = image->w - ix;
|
|
|
|
}
|
|
|
|
/* middle tex */
|
|
|
|
else
|
|
|
|
{
|
2000-12-29 12:43:48 -08:00
|
|
|
ix = (w->context->max_texture_size - 1) - 1 +
|
|
|
|
((tx - 1) * (w->context->max_texture_size - 2));
|
2000-12-27 12:51:39 -08:00
|
|
|
iw = w->context->max_texture_size;
|
|
|
|
}
|
|
|
|
if (image->im)
|
|
|
|
tm->textures[i] = __evas_gl_texture_new(w, image->im,
|
|
|
|
ix, iy, iw, ih);
|
|
|
|
i++;
|
2000-08-01 20:33:11 -07:00
|
|
|
}
|
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
if ((image->file) && (image->im))
|
2000-08-05 13:11:27 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
prev_im = imlib_context_get_image();
|
|
|
|
imlib_context_set_image(image->im);
|
|
|
|
imlib_free_image_and_decache();
|
|
|
|
image->im = NULL;
|
|
|
|
imlib_context_set_image(prev_im);
|
2000-08-05 13:11:27 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
return tm;
|
2000-08-01 20:33:11 -07:00
|
|
|
}
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static void
|
|
|
|
__evas_gl_free_image_textures(Evas_GL_Image *image)
|
2000-08-01 20:33:11 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_List l;
|
|
|
|
|
|
|
|
if (image->textures)
|
2000-08-01 20:33:11 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
for (l = image->textures; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Texmesh *tm;
|
|
|
|
Evas_GL_Window *w;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
tm = l->data;
|
|
|
|
w = __evas_gl_window_current(tm->window->disp, tm->window->win,
|
|
|
|
tm->window->w, tm->window->h);
|
|
|
|
for (i = 0; i < (tm->tiles.x + 1) * (tm->tiles.y + 1); i++)
|
|
|
|
__evas_gl_texture_free(w, tm->textures[i]);
|
|
|
|
free(tm->textures);
|
|
|
|
tm->tiles.x = 0;
|
|
|
|
tm->tiles.y = 0;
|
|
|
|
tm->tiles.x_edge = 0;
|
|
|
|
tm->tiles.y_edge = 0;
|
|
|
|
free(tm);
|
|
|
|
}
|
|
|
|
evas_list_free(image->textures);
|
2000-08-01 20:33:11 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
image->textures = NULL;
|
2000-08-01 20:33:11 -07:00
|
|
|
}
|
|
|
|
|
2000-08-05 17:26:34 -07:00
|
|
|
static Evas_GL_Image *
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_gl_image_alloc(char *file)
|
2000-08-01 20:33:11 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Image *image;
|
|
|
|
Imlib_Image im, prev_im;
|
2000-08-01 20:33:11 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
im = imlib_load_image(file);
|
|
|
|
if (!im) return NULL;
|
|
|
|
image = malloc(sizeof(Evas_GL_Image));
|
|
|
|
image->file = strdup(file);
|
|
|
|
image->im = im;
|
|
|
|
prev_im = imlib_context_get_image();
|
|
|
|
imlib_context_set_image(im);
|
|
|
|
image->w = imlib_image_get_width();
|
|
|
|
image->h = imlib_image_get_height();
|
|
|
|
image->has_alpha = imlib_image_has_alpha();
|
|
|
|
image->border.l = 0;
|
|
|
|
image->border.r = 0;
|
|
|
|
image->border.t = 0;
|
|
|
|
image->border.b = 0;
|
|
|
|
image->references = 1;
|
|
|
|
image->textures = NULL;
|
|
|
|
imlib_context_set_image(prev_im);
|
|
|
|
return image;
|
2000-08-05 13:11:27 -07:00
|
|
|
}
|
|
|
|
|
2000-08-05 17:26:34 -07:00
|
|
|
static void
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_gl_image_dealloc(Evas_GL_Image *image)
|
2000-08-05 17:26:34 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Imlib_Image prev_im;
|
|
|
|
|
|
|
|
if (image->file) free(image->file);
|
|
|
|
if (image->im)
|
2000-08-05 17:26:34 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
prev_im = imlib_context_get_image();
|
|
|
|
imlib_context_set_image(image->im);
|
|
|
|
imlib_free_image();
|
|
|
|
imlib_context_set_image(prev_im);
|
2000-08-05 17:26:34 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
if (image->textures)
|
|
|
|
__evas_gl_free_image_textures(image);
|
|
|
|
free(image);
|
2000-08-05 17:26:34 -07:00
|
|
|
}
|
|
|
|
|
2000-08-05 19:06:24 -07:00
|
|
|
static void
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_gl_image_cache_flush(void)
|
2000-08-05 19:06:24 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
while (__evas_image_cache > __evas_image_cache_max)
|
2000-08-05 19:06:24 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Image *im, *im_last;
|
|
|
|
Evas_List l;
|
2000-08-05 19:06:24 -07:00
|
|
|
|
|
|
|
im_last = NULL;
|
2000-12-27 12:51:39 -08:00
|
|
|
for (l = __evas_images; l; l = l->next)
|
|
|
|
{
|
2000-08-05 19:06:24 -07:00
|
|
|
im = l->data;
|
2000-12-27 12:51:39 -08:00
|
|
|
if (im->references == 0) im_last = im;
|
2000-08-05 19:06:24 -07:00
|
|
|
}
|
|
|
|
if (im_last)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_image_cache -= im_last->w * im_last->h * 4;
|
2000-08-05 19:06:24 -07:00
|
|
|
__evas_images = evas_list_remove(__evas_images, im_last);
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_gl_image_dealloc(im_last);
|
2000-08-05 19:06:24 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static Evas_GL_Graident_Texture *
|
|
|
|
__evas_gl_gradient_texture_new(Evas_GL_Window *w, Evas_GL_Graident *gr)
|
2000-08-05 17:26:34 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_List l;
|
|
|
|
Evas_GL_Graident_Texture *tg;
|
|
|
|
|
|
|
|
for (l = gr->textures; l; l = l->next)
|
2000-08-10 03:14:55 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
tg = l->data;
|
|
|
|
if (tg->context == w->context) return tg;
|
2000-08-10 03:14:55 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
tg = malloc(sizeof(Evas_GL_Graident_Texture));
|
|
|
|
tg->window = w;
|
|
|
|
tg->context = w->context;
|
|
|
|
tg->texture = NULL;
|
|
|
|
gr->textures = evas_list_prepend(gr->textures, tg);
|
|
|
|
return tg;
|
2000-08-05 13:11:27 -07:00
|
|
|
}
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static void
|
|
|
|
__evas_gl_gradient_texture_free(Evas_GL_Graident_Texture *tg)
|
2000-08-10 03:14:55 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
if (tg->texture)
|
|
|
|
__evas_gl_texture_free(tg->window, tg->texture);
|
|
|
|
free(tg);
|
2000-08-10 03:14:55 -07:00
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static Evas_GL_Texture *
|
|
|
|
__evas_gl_texture_alpha_new(Evas_GL_Window *w)
|
2000-08-10 15:12:42 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Texture *tex;
|
|
|
|
DATA8 *data;
|
|
|
|
|
|
|
|
if (!w) return NULL;
|
|
|
|
tex = malloc(sizeof(Evas_GL_Texture));
|
|
|
|
tex->w = w->context->max_texture_size;
|
|
|
|
tex->h = w->context->max_texture_size;
|
|
|
|
glGenTextures(1, &(tex->texture));
|
|
|
|
glBindTexture(GL_TEXTURE_2D, tex->texture);
|
|
|
|
w->context->bound_texture = tex;
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
|
|
|
tex->smooth = 0;
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
data = malloc(w->context->max_texture_size * w->context->max_texture_size);
|
|
|
|
memset(data, 0, w->context->max_texture_size * w->context->max_texture_size);
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA4,
|
|
|
|
w->context->max_texture_size, w->context->max_texture_size, 0,
|
|
|
|
GL_ALPHA, GL_UNSIGNED_BYTE, data);
|
|
|
|
free(data);
|
|
|
|
return tex;
|
2000-08-10 15:12:42 -07:00
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-08-06 17:50:40 -07:00
|
|
|
static void
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_gl_texture_paste_data(Evas_GL_Window *w, Evas_GL_Texture *tex, int x, int y, DATA8 *data, int iw, int ih)
|
2000-08-06 17:50:40 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_gl_window_use_texture(w, tex, 0);
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, iw, ih,
|
|
|
|
GL_ALPHA, GL_UNSIGNED_BYTE, data);
|
2000-08-06 17:50:40 -07:00
|
|
|
}
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static Evas_GL_Glyph *
|
|
|
|
__evas_gl_text_font_get_glyph(Evas_GL_Font *fn, int glyph)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Glyph *g;
|
|
|
|
Evas_List l;
|
|
|
|
int hash;
|
|
|
|
int code;
|
2000-08-06 14:19:37 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
hash = glyph & 0xff;
|
|
|
|
for (l = fn->glyphs[hash]; l; l = l->next)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
g = l->data;
|
|
|
|
if (g->glyph_id == glyph)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
if (l != fn->glyphs[hash])
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
fn->glyphs[hash] = evas_list_remove(fn->glyphs[hash], g);
|
|
|
|
fn->glyphs[hash] = evas_list_prepend(fn->glyphs[hash], g);
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
return g;
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
g = malloc(sizeof(Evas_GL_Glyph));
|
|
|
|
g->glyph_id = glyph;
|
|
|
|
TT_New_Glyph(fn->face, &(g->glyph));
|
|
|
|
code = TT_Char_Index(fn->char_map, glyph);
|
|
|
|
TT_Load_Glyph(fn->instance, g->glyph, code, TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH);
|
|
|
|
TT_Get_Glyph_Metrics(g->glyph, &(g->metrics));
|
|
|
|
g->texture = NULL;
|
|
|
|
g->textures = NULL;
|
|
|
|
g->tex.x1 = 0.0;
|
|
|
|
g->tex.x2 = 0.0;
|
|
|
|
g->tex.y1 = 0.0;
|
|
|
|
g->tex.y2 = 0.0;
|
|
|
|
fn->glyphs[hash] = evas_list_prepend(fn->glyphs[hash], g);
|
|
|
|
return g;
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static TT_Raster_Map *
|
|
|
|
__evas_gl_text_font_raster_new(int width, int height)
|
|
|
|
{
|
|
|
|
TT_Raster_Map *rmap;
|
|
|
|
|
|
|
|
rmap = malloc(sizeof(TT_Raster_Map));
|
|
|
|
if (!rmap) return NULL;
|
|
|
|
rmap->width = (width + 3) & -4;
|
|
|
|
rmap->rows = height;
|
|
|
|
rmap->flow = TT_Flow_Up;
|
|
|
|
rmap->cols = rmap->width;
|
|
|
|
rmap->size = rmap->rows * rmap->width;
|
|
|
|
if (rmap->size <= 0)
|
|
|
|
{
|
|
|
|
free(rmap);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
rmap->bitmap = malloc(rmap->size);
|
|
|
|
if (!rmap->bitmap)
|
|
|
|
{
|
|
|
|
free(rmap);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
memset(rmap->bitmap, 0, rmap->size);
|
|
|
|
return rmap;
|
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
|
2000-08-06 14:19:37 -07:00
|
|
|
static void
|
|
|
|
__evas_gl_text_font_raster_free(TT_Raster_Map * rmap)
|
2000-12-27 12:51:39 -08:00
|
|
|
{
|
2000-08-06 14:19:37 -07:00
|
|
|
if (rmap->bitmap) free(rmap->bitmap);
|
|
|
|
free(rmap);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_gl_text_font_render_glyph(Evas_GL_Window *glw, Evas_GL_Font *fn, Evas_GL_Glyph *g)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_List l;
|
|
|
|
Evas_GL_Font_Texture *ft;
|
|
|
|
Evas_GL_Glyph_Texture *gt;
|
|
|
|
Evas_GL_Texture *tex;
|
|
|
|
int tx, ty, tw, th, xmin, ymin, xmax, ymax;
|
|
|
|
TT_Raster_Map *rmap;
|
2000-08-06 14:19:37 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
if ((g->texture) && (g->texture->context == glw->context)) return;
|
|
|
|
for (l = g->textures; l; l = l->next)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
gt = l->data;
|
|
|
|
if (gt->context == glw->context)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
g->texture = gt;
|
|
|
|
g->tex.x1 = gt->tex.x1;
|
|
|
|
g->tex.x2 = gt->tex.x2;
|
|
|
|
g->tex.y1 = gt->tex.y1;
|
|
|
|
g->tex.y2 = gt->tex.y2;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
xmin = g->metrics.bbox.xMin & -64;
|
|
|
|
ymin = g->metrics.bbox.yMin & -64;
|
|
|
|
xmax = (g->metrics.bbox.xMax + 63) & -64;
|
|
|
|
ymax = (g->metrics.bbox.yMax + 63) & -64;
|
|
|
|
tw = ((xmax - xmin) / 64) + 1;
|
|
|
|
th = ((ymax - ymin) / 64) + 1;
|
|
|
|
/* could never fit glyph into max texture size tile */
|
|
|
|
if ((tw > glw->context->max_texture_size) ||
|
|
|
|
(th > glw->context->max_texture_size))
|
|
|
|
{
|
|
|
|
g->texture = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* find a new texture with space */
|
|
|
|
ft = NULL;
|
|
|
|
tex = NULL;
|
|
|
|
tx = 0;
|
|
|
|
ty = 0;
|
|
|
|
for (l = fn->textures; l; l = l->next)
|
|
|
|
{
|
|
|
|
ft = l->data;
|
|
|
|
if (ft->context == glw->context)
|
|
|
|
{
|
|
|
|
tex = ft->texture;
|
|
|
|
|
|
|
|
if ((tex->h - ft->cursor.y) >= th)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
if ((tex->w - ft->cursor.x) >= tw)
|
|
|
|
{
|
|
|
|
if (ft->cursor.row_h < th) ft->cursor.row_h = th;
|
|
|
|
tx = ft->cursor.x;
|
|
|
|
ty = ft->cursor.y;
|
|
|
|
ft->cursor.x += tw;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ty = ft->cursor.y + ft->cursor.row_h;
|
|
|
|
if ((tex->h - ty) >= th)
|
|
|
|
{
|
|
|
|
ft->cursor.y += ft->cursor.row_h;
|
|
|
|
ft->cursor.row_h = th;
|
|
|
|
ft->cursor.x = tw;
|
|
|
|
tx = 0;
|
|
|
|
ty = ft->cursor.y;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
}
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
ft = NULL;
|
|
|
|
}
|
|
|
|
done:
|
|
|
|
if (!ft)
|
|
|
|
{
|
|
|
|
/* make a new texture with space */
|
|
|
|
tex = __evas_gl_texture_alpha_new(glw);
|
|
|
|
ft = malloc(sizeof(Evas_GL_Font_Texture));
|
|
|
|
ft->cursor.x = tw;
|
|
|
|
ft->cursor.y = 0;
|
|
|
|
ft->cursor.row_h = th;
|
|
|
|
ft->window = glw;
|
|
|
|
ft->context = glw->context;
|
|
|
|
ft->texture = tex;
|
|
|
|
|
|
|
|
fn->textures = evas_list_prepend(fn->textures, ft);
|
|
|
|
tx = 0;
|
|
|
|
ty = 0;
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
/* paste glyph in free spot in texture */
|
|
|
|
gt = malloc(sizeof(Evas_GL_Glyph_Texture));
|
2000-08-06 14:19:37 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
rmap = __evas_gl_text_font_raster_new(tw, th);
|
|
|
|
if (rmap)
|
|
|
|
{
|
|
|
|
int x, y;
|
|
|
|
DATA8 *data;
|
|
|
|
|
|
|
|
TT_Get_Glyph_Pixmap(g->glyph, rmap, -xmin, -ymin);
|
|
|
|
data = malloc(tw * th * sizeof(DATA8));
|
|
|
|
for (y = 0; y < th; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < tw; x++)
|
|
|
|
{
|
|
|
|
int rval;
|
|
|
|
|
|
|
|
rval = (int)(((unsigned char *)(rmap->bitmap))[((rmap->rows - y - 1) * rmap->cols) + x]);
|
|
|
|
data[(y * tw) + x] = __evas_rend_lut[rval];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
__evas_gl_texture_paste_data(glw, tex, tx, ty, data, tw, th);
|
|
|
|
free(data);
|
|
|
|
__evas_gl_text_font_raster_free(rmap);
|
|
|
|
}
|
|
|
|
gt->texture = tex;
|
|
|
|
gt->window = glw;
|
|
|
|
gt->context = glw->context;
|
|
|
|
gt->tex.x1 = (double)tx / (double)glw->context->max_texture_size;
|
|
|
|
gt->tex.x2 = (double)(tx + tw) / (double)glw->context->max_texture_size;
|
|
|
|
gt->tex.y1 = (double)ty / (double)glw->context->max_texture_size;
|
|
|
|
gt->tex.y2 = (double)(ty + th) / (double)glw->context->max_texture_size;
|
|
|
|
g->textures = evas_list_prepend(g->textures, gt);
|
|
|
|
|
|
|
|
g->texture = gt;
|
|
|
|
g->tex.x1 = gt->tex.x1;
|
|
|
|
g->tex.x2 = gt->tex.x2;
|
|
|
|
g->tex.y1 = gt->tex.y1;
|
|
|
|
g->tex.y2 = gt->tex.y2;
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
|
|
|
|
2000-08-06 17:50:40 -07:00
|
|
|
static int
|
|
|
|
__evas_gl_is_file(char *file)
|
|
|
|
{
|
|
|
|
struct stat st;
|
2000-12-27 12:51:39 -08:00
|
|
|
|
2000-08-06 17:50:40 -07:00
|
|
|
if (stat(file, &st) < 0)
|
2000-12-27 12:51:39 -08:00
|
|
|
return 0;
|
2000-08-06 17:50:40 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static char *
|
|
|
|
__evas_gl_font_find(char *font)
|
|
|
|
{
|
|
|
|
char buf[4096];
|
|
|
|
char *ext[] = {".ttf", ".TTF", ""};
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
sprintf(buf, "%s%s", font, ext[i]);
|
|
|
|
if (__evas_gl_is_file(buf)) return strdup(buf);
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
for (j = 0; j < __evas_fpath_num; j++)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
for (i = 0; i < 3; i++)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
sprintf(buf, "%s/%s%s", __evas_fpath[j], font, ext[i]);
|
|
|
|
if (__evas_gl_is_file(buf)) return strdup(buf);
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_GL_Font *
|
|
|
|
__evas_gl_font_load(char *font, int size)
|
|
|
|
{
|
|
|
|
Evas_GL_Font *fn;
|
|
|
|
char *file;
|
|
|
|
TT_Error error;
|
|
|
|
int i, num_cmap, upm;
|
|
|
|
const int dpi = 96;
|
|
|
|
|
|
|
|
file = __evas_gl_font_find(font);
|
2000-12-29 12:43:48 -08:00
|
|
|
if (!file) return NULL;
|
2000-12-27 12:51:39 -08:00
|
|
|
if (!__evas_have_tt_engine)
|
|
|
|
{
|
|
|
|
error = TT_Init_FreeType(&__evas_tt_engine);
|
|
|
|
if (error) return NULL;
|
|
|
|
__evas_have_tt_engine = 1;
|
|
|
|
}
|
|
|
|
fn = malloc(sizeof(Evas_GL_Font));
|
|
|
|
fn->font = strdup(font);
|
|
|
|
fn->size = size;
|
|
|
|
fn->engine = __evas_tt_engine;
|
|
|
|
error = TT_Open_Face(fn->engine, file, &fn->face);
|
2000-08-06 14:19:37 -07:00
|
|
|
if (error)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
free(fn->font);
|
|
|
|
free(fn);
|
|
|
|
free(file);
|
2000-08-06 14:19:37 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
free(file);
|
2000-12-27 12:51:39 -08:00
|
|
|
error = TT_Get_Face_Properties(fn->face, &fn->properties);
|
2000-08-06 14:19:37 -07:00
|
|
|
if (error)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
TT_Close_Face(fn->face);
|
|
|
|
free(fn->font);
|
|
|
|
free(fn);
|
2000-08-06 14:19:37 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
error = TT_New_Instance(fn->face, &fn->instance);
|
2000-08-06 14:19:37 -07:00
|
|
|
if (error)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
TT_Close_Face(fn->face);
|
|
|
|
free(fn->font);
|
|
|
|
free(fn);
|
2000-08-06 14:19:37 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
TT_Set_Instance_Resolutions(fn->instance, dpi, dpi);
|
|
|
|
TT_Set_Instance_CharSize(fn->instance, size * 64);
|
|
|
|
TT_Get_Instance_Metrics(fn->instance, &fn->metrics);
|
|
|
|
upm = fn->properties.header->Units_Per_EM;
|
|
|
|
fn->ascent = (fn->properties.horizontal->Ascender * fn->metrics.y_ppem) / upm;
|
|
|
|
fn->descent = (fn->properties.horizontal->Descender * fn->metrics.y_ppem) / upm;
|
|
|
|
if (fn->descent < 0) fn->descent = -fn->descent;
|
|
|
|
num_cmap = fn->properties.num_CharMaps;
|
|
|
|
for (i = 0; i < num_cmap; i++)
|
|
|
|
{
|
|
|
|
unsigned short platform, encoding;
|
|
|
|
|
|
|
|
TT_Get_CharMap_ID(fn->face, i, &platform, &encoding);
|
|
|
|
if ((platform == 3 && encoding == 1) ||
|
|
|
|
(platform == 0 && encoding == 0))
|
|
|
|
{
|
|
|
|
TT_Get_CharMap(fn->face, i, &fn->char_map);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (i == num_cmap)
|
|
|
|
TT_Get_CharMap(fn->face, 0, &fn->char_map);
|
|
|
|
fn->max_descent = 0;
|
|
|
|
fn->max_ascent = 0;
|
|
|
|
memset(fn->glyphs, 0, sizeof(Evas_List) * 256);
|
|
|
|
fn->textures = NULL;
|
|
|
|
fn->references = 1;
|
2000-08-06 14:19:37 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
/* go thru the first 256 glyps to calculate max ascent/descent */
|
|
|
|
{
|
|
|
|
Evas_GL_Glyph *g;
|
|
|
|
|
|
|
|
for (i = 0; i < 256; i++)
|
|
|
|
{
|
|
|
|
g = __evas_gl_text_font_get_glyph(fn, i);
|
|
|
|
if (!g) continue;
|
|
|
|
if (!TT_VALID(g->glyph)) continue;
|
|
|
|
if ((g->metrics.bbox.yMin & -64) < fn->max_descent)
|
|
|
|
fn->max_descent = (g->metrics.bbox.yMin & -64);
|
|
|
|
if (((g->metrics.bbox.yMax + 63) & -64) > fn->max_ascent)
|
|
|
|
fn->max_ascent = ((g->metrics.bbox.yMax + 63) & -64);
|
|
|
|
}
|
|
|
|
}
|
2000-08-06 14:19:37 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
if (((fn->ascent == 0) && (fn->descent == 0)) || (fn->ascent == 0))
|
|
|
|
{
|
|
|
|
fn->ascent = fn->max_ascent / 64;
|
|
|
|
fn->descent = -fn->max_descent / 64;
|
|
|
|
}
|
|
|
|
TT_Flush_Face(fn->face);
|
|
|
|
return fn;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
__evas_gl_text_font_cache_flush(void)
|
|
|
|
{
|
|
|
|
Evas_List l;
|
|
|
|
Evas_GL_Font *fn_last;
|
|
|
|
Evas_GL_Font *fn;
|
2000-08-06 14:19:37 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
while (__evas_font_cache > __evas_font_cache_max)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
fn_last = NULL;
|
|
|
|
for (l = __evas_fonts; l; l = l->next)
|
|
|
|
{
|
|
|
|
fn = l->data;
|
|
|
|
if (fn->references == 0) fn_last = fn;
|
|
|
|
}
|
|
|
|
if (fn_last)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (l = fn_last->textures; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Font_Texture *ft;
|
|
|
|
|
|
|
|
ft = l->data;
|
|
|
|
__evas_font_cache -= ft->texture->w * ft->texture->h;
|
|
|
|
}
|
|
|
|
TT_Done_Instance(fn_last->instance);
|
|
|
|
TT_Close_Face(fn_last->face);
|
|
|
|
if (fn_last->font) free(fn_last->font);
|
|
|
|
for (i = 0; i < 256; i++)
|
|
|
|
{
|
|
|
|
if (fn_last->glyphs[i])
|
|
|
|
{
|
|
|
|
for (l = fn_last->glyphs[i]; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Glyph *g;
|
|
|
|
Evas_List ll;
|
|
|
|
|
|
|
|
g = l->data;
|
|
|
|
if (g->textures)
|
|
|
|
{
|
|
|
|
for (ll = g->textures; ll; ll = ll->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Glyph_Texture *gt;
|
|
|
|
|
|
|
|
gt = ll->data;
|
|
|
|
free(gt);
|
|
|
|
}
|
|
|
|
evas_list_free(g->textures);
|
|
|
|
}
|
|
|
|
free(g);
|
|
|
|
}
|
|
|
|
evas_list_free(fn_last->glyphs[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (fn_last->textures)
|
|
|
|
{
|
|
|
|
for (l = fn_last->textures; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Font_Texture *ft;
|
|
|
|
|
|
|
|
ft = l->data;
|
|
|
|
__evas_gl_texture_free(ft->window, ft->texture);
|
|
|
|
free(ft);
|
|
|
|
}
|
|
|
|
evas_list_free(fn_last->textures);
|
|
|
|
}
|
|
|
|
__evas_fonts = evas_list_remove(__evas_fonts, fn_last);
|
|
|
|
free(fn_last);
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2000-12-29 12:43:48 -08:00
|
|
|
__evas_gl_image_intern_draw(Evas_GL_Image *im,
|
|
|
|
Evas_GL_Window *glw,
|
|
|
|
int src_x, int src_y, int src_w, int src_h,
|
|
|
|
int dst_x, int dst_y, int dst_w, int dst_h,
|
|
|
|
int allow_smooth)
|
2000-12-27 12:51:39 -08:00
|
|
|
{
|
|
|
|
Evas_List l;
|
|
|
|
Evas_GL_Texmesh *tm;
|
|
|
|
|
|
|
|
double scx, scy;
|
|
|
|
double x0, y0, w0, h0;
|
|
|
|
int go;
|
|
|
|
|
|
|
|
if (src_w < 1) src_w = 1;
|
|
|
|
if (src_h < 1) src_h = 1;
|
|
|
|
if (dst_w < 1) return;
|
|
|
|
if (dst_h < 1) return;
|
|
|
|
|
|
|
|
tm = __evas_gl_make_image_textures(glw, im);
|
|
|
|
scx = (double)dst_w / (double)src_w;
|
|
|
|
scy = (double)dst_h / (double)src_h;
|
|
|
|
|
|
|
|
x0 = (double)dst_x - ((double)src_x * scx);
|
|
|
|
y0 = (double)dst_y - ((double)src_y * scy);
|
|
|
|
w0 = (double)im->w * scx;
|
|
|
|
h0 = (double)im->h * scy;
|
|
|
|
|
|
|
|
#ifndef GLNOCLIP
|
|
|
|
for (l = glw->updates; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Rect *rect;
|
2000-08-06 14:19:37 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
go = 1;
|
|
|
|
rect = l->data;
|
|
|
|
{
|
|
|
|
int rx, ry, rw, rh;
|
|
|
|
|
|
|
|
rx = dst_x;
|
|
|
|
ry = dst_y;
|
|
|
|
rw = dst_w;
|
|
|
|
rh = dst_h;
|
|
|
|
CLIP_TO(rx, ry, rw, rh, rect->x, rect->y, rect->w, rect->h);
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
CLIP_TO(rx, ry, rw, rh,
|
|
|
|
__evas_clip_x, __evas_clip_y,
|
|
|
|
__evas_clip_w, __evas_clip_h);
|
|
|
|
}
|
|
|
|
if ((rw > 0) && (rh > 0))
|
|
|
|
__evas_gl_window_clip(glw, 1, rx, ry, rw, rh);
|
|
|
|
else go = 0;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
go = 1;
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
int rx, ry, rw, rh;
|
|
|
|
|
|
|
|
rx = dst_x;
|
|
|
|
ry = dst_y;
|
|
|
|
rw = dst_w;
|
|
|
|
rh = dst_h;
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
CLIP_TO(rx, ry, rw, rh,
|
|
|
|
__evas_clip_x, __evas_clip_y,
|
|
|
|
__evas_clip_w, __evas_clip_h);
|
|
|
|
if ((rw > 0) && (rh > 0))
|
|
|
|
__evas_gl_window_clip(glw, 1, rx, ry, rw, rh);
|
|
|
|
else go = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!((src_x != 0) || (src_w != im->w) ||
|
|
|
|
(src_y != 0) || (src_h != im->h)))
|
|
|
|
__evas_gl_window_clip(glw, 0, 0, 0, 0, 0);
|
|
|
|
}
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
#endif
|
|
|
|
/* render image here */
|
|
|
|
if (go)
|
|
|
|
{
|
|
|
|
int tx, ty, t;
|
|
|
|
double ty1, ty2, tx1, tx2;
|
|
|
|
double x1, x2, y1, y2;
|
|
|
|
int smooth = 0;
|
|
|
|
|
2000-12-29 12:43:48 -08:00
|
|
|
if ((__evas_smooth) && (allow_smooth))
|
2000-12-27 12:51:39 -08:00
|
|
|
{
|
|
|
|
if ((dst_w == src_w) && (dst_h == src_h))
|
|
|
|
smooth = 0;
|
|
|
|
else smooth = __evas_smooth;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
smooth = 0;
|
|
|
|
t = 0;
|
|
|
|
for (ty = 0; ty <= tm->tiles.y; ty++)
|
|
|
|
{
|
2000-12-29 12:43:48 -08:00
|
|
|
if ((ty == 0) && (ty < tm->tiles.y))
|
2000-12-27 12:51:39 -08:00
|
|
|
{
|
|
|
|
y1 = y0;
|
|
|
|
y2 = y1 + ((double)(glw->context->max_texture_size - 1) * scy);
|
|
|
|
ty1 = 0.0;
|
2000-12-29 12:43:48 -08:00
|
|
|
ty2 = (double)(glw->context->max_texture_size - 2) / (double)(glw->context->max_texture_size - 1);
|
2000-12-27 12:51:39 -08:00
|
|
|
}
|
|
|
|
else if (ty < tm->tiles.y)
|
|
|
|
{
|
|
|
|
y1 = y0 + (((double)(glw->context->max_texture_size - 1) + ((double)(ty - 1) * (double)(glw->context->max_texture_size - 2))) * scy);
|
|
|
|
y2 = y1 + ((double)(glw->context->max_texture_size - 2) * scy);
|
2000-12-29 12:43:48 -08:00
|
|
|
ty1 = 1.0 / (double)(glw->context->max_texture_size - 1);
|
|
|
|
ty2 = (double)(glw->context->max_texture_size - 2) / (double)(glw->context->max_texture_size - 1);
|
2000-12-27 12:51:39 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (ty == 0) y1 = y0;
|
2000-12-29 12:43:48 -08:00
|
|
|
else
|
2000-12-27 12:51:39 -08:00
|
|
|
y1 = y0 + h0 - ((double)tm->tiles.y_left * scy);
|
|
|
|
y2 = y0 + h0;
|
2000-12-29 12:43:48 -08:00
|
|
|
if (ty == 0)
|
|
|
|
{
|
|
|
|
ty1 = 0.0;
|
|
|
|
ty2 = (double)(tm->tiles.y_left - 1) / (double)(tm->tiles.y_edge - 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ty1 = 1.0 / (double)(tm->tiles.y_edge - 1);
|
|
|
|
ty2 = (double)(1 + tm->tiles.y_left - 1) / (double)(tm->tiles.y_edge - 1);
|
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
}
|
|
|
|
for (tx = 0; tx <= tm->tiles.x; tx++)
|
|
|
|
{
|
|
|
|
if ((tx == 0) && (tx < tm->tiles.x))
|
|
|
|
{
|
2000-12-29 12:43:48 -08:00
|
|
|
x1 = x0;
|
2000-12-27 12:51:39 -08:00
|
|
|
x2 = x1 + (255 * scx);
|
|
|
|
tx1 = 0.0;
|
2000-12-29 12:43:48 -08:00
|
|
|
tx2 = (double)(glw->context->max_texture_size - 2) / (double)(glw->context->max_texture_size - 1);
|
2000-12-27 12:51:39 -08:00
|
|
|
}
|
|
|
|
else if (tx < tm->tiles.x)
|
|
|
|
{
|
|
|
|
x1 = x0 + (((double)(glw->context->max_texture_size - 1) + ((double)(tx - 1) * (double)(glw->context->max_texture_size - 2))) * scx);
|
|
|
|
x2 = x1 + ((double)(glw->context->max_texture_size - 2) * scx);
|
2000-12-29 12:43:48 -08:00
|
|
|
tx1 = 1.0 / (double)(glw->context->max_texture_size - 1);
|
|
|
|
tx2 = (double)(glw->context->max_texture_size - 2) / (double)(glw->context->max_texture_size - 1);
|
2000-12-27 12:51:39 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (tx == 0) x1 = x0;
|
|
|
|
else
|
|
|
|
x1 = x0 + w0 - ((double)tm->tiles.x_left * scx);
|
|
|
|
x2 = x0 + w0;
|
2000-12-29 12:43:48 -08:00
|
|
|
if (tx == 0)
|
|
|
|
{
|
|
|
|
tx1 = 0.0;
|
|
|
|
tx2 = (double)(tm->tiles.x_left - 1) / (double)(tm->tiles.x_edge - 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tx1 = 1.0 / (double)(tm->tiles.x_edge - 1);
|
|
|
|
tx2 = (double)(1 + tm->tiles.x_left - 1) / (double)(tm->tiles.x_edge - 1);
|
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
}
|
|
|
|
__evas_gl_window_use_texture(glw, tm->textures[t++], smooth);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glTexCoord2d(tx1, ty1); glVertex2d(x1, y1);
|
|
|
|
glTexCoord2d(tx2, ty1); glVertex2d(x2, y1);
|
|
|
|
glTexCoord2d(tx2, ty2); glVertex2d(x2, y2);
|
|
|
|
glTexCoord2d(tx1, ty2); glVertex2d(x1, y2);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#ifndef GLNOCLIP
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2000-12-29 12:43:48 -08:00
|
|
|
/*****************************************************************************/
|
|
|
|
/* image externals ***********************************************************/
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
void
|
|
|
|
__evas_gl_image_draw(Evas_GL_Image *im,
|
|
|
|
Display *disp, Imlib_Image dstim,
|
|
|
|
Window w, int win_w, int win_h,
|
|
|
|
int src_x, int src_y, int src_w, int src_h,
|
|
|
|
int dst_x, int dst_y, int dst_w, int dst_h,
|
|
|
|
int cr, int cg, int cb, int ca)
|
|
|
|
{
|
|
|
|
Evas_GL_Window *glw;
|
|
|
|
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
cr = (cr * __evas_clip_r) / 255;
|
|
|
|
cg = (cg * __evas_clip_g) / 255;
|
|
|
|
cb = (cb * __evas_clip_b) / 255;
|
|
|
|
ca = (ca * __evas_clip_a) / 255;
|
|
|
|
}
|
|
|
|
if (ca <= 0) return;
|
|
|
|
if (src_w < 1) src_w = 1;
|
|
|
|
if (src_h < 1) src_h = 1;
|
|
|
|
if (dst_w < 1) return;
|
|
|
|
if (dst_h < 1) return;
|
|
|
|
glw = __evas_gl_window_current(disp, w, win_w, win_h);
|
|
|
|
if (!glw) return;
|
|
|
|
__evas_gl_window_texture(glw, 1);
|
|
|
|
__evas_gl_window_blend(glw, im->has_alpha);
|
|
|
|
__evas_gl_window_write_buf(glw, GL_BACK);
|
|
|
|
__evas_gl_window_read_buf(glw, GL_BACK);
|
|
|
|
__evas_gl_window_color(glw, cr, cg, cb, ca);
|
|
|
|
__evas_gl_window_dither(glw, 1);
|
|
|
|
|
|
|
|
if ((im->border.l == 0) && (im->border.r == 0) &&
|
|
|
|
(im->border.t == 0) && (im->border.b == 0))
|
|
|
|
__evas_gl_image_intern_draw(im, glw, src_x, src_y, src_w, src_h,
|
|
|
|
dst_x, dst_y, dst_w, dst_h,
|
|
|
|
1);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double scx, scy;
|
|
|
|
double x0, y0, w0, h0;
|
|
|
|
int ecx, ecy, ecw, ech, ec;
|
|
|
|
int x, y, w, h, dx, dy, dw, dh;
|
|
|
|
int smooth;
|
|
|
|
|
|
|
|
scx = (double)dst_w / (double)src_w;
|
|
|
|
scy = (double)dst_h / (double)src_h;
|
|
|
|
|
|
|
|
x0 = (double)dst_x - ((double)src_x * scx);
|
|
|
|
y0 = (double)dst_y - ((double)src_y * scy);
|
|
|
|
w0 = (double)im->w * scx;
|
|
|
|
h0 = (double)im->h * scy;
|
|
|
|
|
|
|
|
ec = __evas_clip;
|
|
|
|
ecx = __evas_clip_x;
|
|
|
|
ecy = __evas_clip_y;
|
|
|
|
ecw = __evas_clip_w;
|
|
|
|
ech = __evas_clip_h;
|
|
|
|
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
CLIP_TO(dst_x, dst_y, dst_w, dst_h,
|
|
|
|
__evas_clip_x, __evas_clip_y,
|
|
|
|
__evas_clip_w, __evas_clip_h);
|
|
|
|
}
|
|
|
|
|
|
|
|
__evas_clip = 1;
|
|
|
|
__evas_clip_x = dst_x;
|
|
|
|
__evas_clip_y = dst_y;
|
|
|
|
__evas_clip_w = dst_w;
|
|
|
|
__evas_clip_h = dst_h;
|
|
|
|
|
|
|
|
dst_x = x0;
|
|
|
|
dst_y = y0;
|
|
|
|
dst_w = w0;
|
|
|
|
dst_h = h0;
|
|
|
|
|
|
|
|
x = 0; y = 0;
|
|
|
|
w = im->border.l; h = im->border.t;
|
|
|
|
dx = dst_x; dy = dst_y;
|
|
|
|
dw = w; dh = h;
|
|
|
|
__evas_gl_image_intern_draw(im, glw, x, y, w, h, dx, dy, dw, dh, 0);
|
|
|
|
|
|
|
|
smooth = 0; if (scx > 1.0) smooth = 1;
|
|
|
|
x = im->border.l; y = 0;
|
|
|
|
w = im->w - (im->border.l + im->border.r); h = im->border.t;
|
|
|
|
dx = dst_x + im->border.l; dy = dst_y;
|
|
|
|
dw = dst_w - (im->border.l + im->border.r); dh = h;
|
|
|
|
__evas_gl_image_intern_draw(im, glw, x, y, w, h, dx, dy, dw, dh, smooth);
|
|
|
|
|
|
|
|
x = im->w - im->border.r; y = 0;
|
|
|
|
w = im->border.r; h = im->border.t;
|
|
|
|
dx = dst_x + dst_w - im->border.r;
|
|
|
|
dy = dst_y; dw = w; dh = h;
|
|
|
|
__evas_gl_image_intern_draw(im, glw, x, y, w, h, dx, dy, dw, dh, 0);
|
|
|
|
|
|
|
|
smooth = 0; if (scy > 1.0) smooth = 1;
|
|
|
|
x = 0; y = im->border.t;
|
|
|
|
w = im->border.l; h = im->h - (im->border.t + im->border.b);
|
|
|
|
dx = dst_x; dy = dst_y + im->border.t; dw = w;
|
|
|
|
dh = dst_h - (im->border.t + im->border.b);
|
|
|
|
__evas_gl_image_intern_draw(im, glw, x, y, w, h, dx, dy, dw, dh, smooth);
|
|
|
|
|
|
|
|
smooth = 0; if ((scx > 1.0) && (scy > 1.0)) smooth = 1;
|
|
|
|
x = im->border.l; y = im->border.t;
|
|
|
|
w = im->w - (im->border.l + im->border.r); h = im->h - (im->border.t + im->border.b);
|
|
|
|
dx = dst_x + im->border.l; dy = dst_y + im->border.t;
|
|
|
|
dw = dst_w - (im->border.l + im->border.r); dh = dst_h - (im->border.t + im->border.b);
|
|
|
|
__evas_gl_image_intern_draw(im, glw, x, y, w, h, dx, dy, dw, dh, smooth);
|
|
|
|
|
|
|
|
smooth = 0; if (scy > 1.0) smooth = 1;
|
|
|
|
x = im->w - im->border.r; y = im->border.t;
|
|
|
|
w = im->border.r; h = im->h - (im->border.t + im->border.b);
|
|
|
|
dx = dst_x + dst_w - im->border.r; dy = dst_y + im->border.t;
|
|
|
|
dw = w; dh = dst_h - (im->border.t + im->border.b);
|
|
|
|
__evas_gl_image_intern_draw(im, glw, x, y, w, h, dx, dy, dw, dh, smooth);
|
|
|
|
|
|
|
|
x = 0; y = im->h - im->border.b;
|
|
|
|
w = im->border.l; h = im->border.b;
|
|
|
|
dx = dst_x; dy = dst_y + dst_h - im->border.b;
|
|
|
|
dw = w; dh = h;
|
|
|
|
__evas_gl_image_intern_draw(im, glw, x, y, w, h, dx, dy, dw, dh, 0);
|
|
|
|
|
|
|
|
smooth = 0; if (scx > 1.0) smooth = 1;
|
|
|
|
x = im->border.l; y = im->h - im->border.b;
|
|
|
|
w = im->w - (im->border.l + im->border.r); h = im->border.b;
|
|
|
|
dx = dst_x + im->border.l; dy = dst_y + dst_h - im->border.b;
|
|
|
|
dw = dst_w - (im->border.l + im->border.r); dh = h;
|
|
|
|
__evas_gl_image_intern_draw(im, glw, x, y, w, h, dx, dy, dw, dh, smooth);
|
|
|
|
|
|
|
|
x = im->w - im->border.r; y = im->h - im->border.b;
|
|
|
|
w = im->border.r; h = im->border.b;
|
|
|
|
dx = dst_x + dst_w - im->border.r; dy = dst_y + dst_h - im->border.b;
|
|
|
|
dw = w; dh = h;
|
|
|
|
__evas_gl_image_intern_draw(im, glw, x, y, w, h, dx, dy, dw, dh, 0);
|
|
|
|
|
|
|
|
__evas_clip = ec;
|
|
|
|
__evas_clip_x = ecx;
|
|
|
|
__evas_clip_y = ecy;
|
|
|
|
__evas_clip_w = ecw;
|
|
|
|
__evas_clip_h = ech;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Image *
|
|
|
|
__evas_gl_image_new_from_file(Display *disp, char *file)
|
|
|
|
{
|
|
|
|
Evas_List l;
|
|
|
|
Evas_GL_Image *image;
|
|
|
|
|
|
|
|
for (l = __evas_images; l; l = l->next)
|
|
|
|
{
|
|
|
|
|
|
|
|
image = l->data;
|
2000-08-06 14:19:37 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
if ((image->file) && (!strcmp(image->file, file)))
|
|
|
|
{
|
|
|
|
if (image->references == 0)
|
|
|
|
{
|
|
|
|
__evas_image_cache -= image->w * image->h * 4;
|
|
|
|
}
|
|
|
|
image->references++;
|
|
|
|
if (l != __evas_images)
|
|
|
|
{
|
|
|
|
__evas_images = evas_list_remove(__evas_images, image);
|
|
|
|
__evas_images = evas_list_prepend(__evas_images, image);
|
|
|
|
}
|
|
|
|
return image;
|
|
|
|
}
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
image = __evas_gl_image_alloc(file);
|
|
|
|
if (image) __evas_images = evas_list_prepend(__evas_images, image);
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__evas_gl_image_free(Evas_GL_Image *im)
|
|
|
|
{
|
|
|
|
if (im->references > 0)
|
|
|
|
im->references--;
|
|
|
|
if (im->references == 0)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_image_cache += im->w * im->h * 4;
|
|
|
|
__evas_gl_image_cache_flush();
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
void
|
|
|
|
__evas_gl_image_cache_empty(Display *disp)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
int prev_cache;
|
2000-08-06 14:19:37 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
prev_cache = __evas_image_cache_max;
|
|
|
|
__evas_image_cache_max = 0;
|
|
|
|
__evas_gl_image_cache_flush();
|
|
|
|
__evas_image_cache_max = prev_cache;
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
void
|
|
|
|
__evas_gl_image_cache_set_size(Display *disp, int size)
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_image_cache_max = size;
|
|
|
|
__evas_gl_image_cache_flush();
|
|
|
|
}
|
2000-08-06 14:19:37 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
int
|
|
|
|
__evas_gl_image_cache_get_size(Display *disp)
|
|
|
|
{
|
|
|
|
return __evas_image_cache_max;
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
int
|
|
|
|
__evas_gl_image_get_width(Evas_GL_Image *im)
|
2000-08-06 18:54:22 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
return im->w;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
__evas_gl_image_get_height(Evas_GL_Image *im)
|
|
|
|
{
|
|
|
|
return im->h;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__evas_gl_image_set_borders(Evas_GL_Image *im, int left, int right,
|
|
|
|
int top, int bottom)
|
|
|
|
{
|
|
|
|
im->border.l = left;
|
|
|
|
im->border.r = right;
|
|
|
|
im->border.t = top;
|
|
|
|
im->border.b = bottom;
|
2000-08-06 18:54:22 -07:00
|
|
|
}
|
2000-08-06 14:19:37 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
void
|
|
|
|
__evas_gl_image_set_smooth_scaling(int on)
|
|
|
|
{
|
|
|
|
__evas_smooth = on;
|
|
|
|
}
|
2000-08-06 14:19:37 -07:00
|
|
|
|
2000-08-05 17:26:34 -07:00
|
|
|
/*****************************************************************************/
|
|
|
|
/* font externals ************************************************************/
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
Evas_GL_Font *
|
2000-08-05 19:06:24 -07:00
|
|
|
__evas_gl_text_font_new(Display *disp, char *font, int size)
|
2000-08-05 17:26:34 -07:00
|
|
|
{
|
2000-08-06 14:19:37 -07:00
|
|
|
Evas_List l;
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Font *fn;
|
|
|
|
|
|
|
|
if (!font) return NULL;
|
2000-08-06 14:19:37 -07:00
|
|
|
for (l = __evas_fonts; l; l = l->next)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Font *fn;
|
|
|
|
|
|
|
|
fn = l->data;
|
|
|
|
if (!strcmp(fn->font, font) && (size == fn->size))
|
2000-08-06 14:19:37 -07:00
|
|
|
{
|
|
|
|
if (l != __evas_fonts)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_fonts = evas_list_remove(__evas_fonts, fn);
|
|
|
|
__evas_fonts = evas_list_prepend(__evas_fonts, fn);
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
if (fn->references == 0)
|
|
|
|
{
|
|
|
|
for (l = fn->textures; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Font_Texture *ft;
|
|
|
|
|
|
|
|
ft = l->data;
|
|
|
|
__evas_font_cache -= ft->texture->w * ft->texture->h;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn->references++;
|
|
|
|
return fn;
|
|
|
|
}
|
2000-08-06 14:19:37 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
fn = __evas_gl_font_load(font, size);
|
|
|
|
if (!fn) return NULL;
|
|
|
|
__evas_fonts = evas_list_prepend(__evas_fonts, fn);
|
|
|
|
return fn;
|
2000-08-05 13:11:27 -07:00
|
|
|
}
|
|
|
|
|
2000-08-05 17:26:34 -07:00
|
|
|
void
|
|
|
|
__evas_gl_text_font_free(Evas_GL_Font *fn)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
if (!fn) return;
|
2000-08-11 00:47:52 -07:00
|
|
|
if (fn->references >= 0)
|
2000-12-27 12:51:39 -08:00
|
|
|
{
|
|
|
|
fn->references--;
|
|
|
|
if (fn->references == 0)
|
|
|
|
{
|
|
|
|
Evas_List l;
|
|
|
|
|
|
|
|
for (l = fn->textures; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Font_Texture *ft;
|
|
|
|
|
|
|
|
ft = l->data;
|
|
|
|
__evas_font_cache += ft->texture->w * ft->texture->h;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
__evas_gl_text_font_cache_flush();
|
2000-08-05 17:26:34 -07:00
|
|
|
}
|
|
|
|
|
2000-09-13 08:08:05 -07:00
|
|
|
int
|
|
|
|
__evas_gl_text_font_get_ascent(Evas_GL_Font *fn)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
if (!fn) return 0;
|
2001-04-12 13:25:43 -07:00
|
|
|
return fn->ascent / 64;
|
2000-09-13 08:08:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
__evas_gl_text_font_get_descent(Evas_GL_Font *fn)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
if (!fn) return 0;
|
2001-04-12 13:25:43 -07:00
|
|
|
return fn->descent / 64;
|
2000-09-13 08:08:05 -07:00
|
|
|
}
|
|
|
|
|
2000-09-13 10:11:53 -07:00
|
|
|
int
|
|
|
|
__evas_gl_text_font_get_max_ascent(Evas_GL_Font *fn)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
if (!fn) return 0;
|
2001-04-12 13:25:43 -07:00
|
|
|
return fn->max_ascent / 64;
|
2000-09-13 10:11:53 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
__evas_gl_text_font_get_max_descent(Evas_GL_Font *fn)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
if (!fn) return 0;
|
2001-04-12 13:25:43 -07:00
|
|
|
return fn->max_descent / 64;
|
2000-09-13 10:11:53 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__evas_gl_text_font_get_advances(Evas_GL_Font *fn, char *text,
|
|
|
|
int *advance_horiz,
|
|
|
|
int *advance_vert)
|
|
|
|
{
|
2000-12-29 12:43:48 -08:00
|
|
|
int i, ascent, descent, pw, ph;
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
if (advance_horiz) *advance_horiz = 0;
|
|
|
|
if (advance_horiz) *advance_vert = 0;
|
|
|
|
if (!fn) return;
|
|
|
|
if (!text) return;
|
|
|
|
if (text[0] == 0) return;
|
2000-12-29 12:43:48 -08:00
|
|
|
|
|
|
|
ascent = fn->ascent;
|
|
|
|
descent = fn->descent;
|
|
|
|
pw = 0;
|
|
|
|
ph = ascent + descent;
|
|
|
|
|
|
|
|
for (i = 0; text[i]; i++)
|
|
|
|
{
|
|
|
|
Evas_GL_Glyph *g;
|
|
|
|
int glyph;
|
|
|
|
|
|
|
|
glyph = ((unsigned char *)text)[i];
|
|
|
|
g = __evas_gl_text_font_get_glyph(fn, glyph);
|
|
|
|
if (!g) continue;
|
|
|
|
if (!TT_VALID(g->glyph)) continue;
|
|
|
|
if (i == 0)
|
|
|
|
pw += ((-g->metrics.bearingX) / 64);
|
|
|
|
pw += g->metrics.advance / 64;
|
|
|
|
}
|
|
|
|
*advance_horiz = pw;
|
|
|
|
*advance_vert = ph;
|
2000-09-13 10:11:53 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
__evas_gl_text_font_get_first_inset(Evas_GL_Font *fn, char *text)
|
|
|
|
{
|
2000-12-29 12:43:48 -08:00
|
|
|
int i;
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
if (!fn) return 0;
|
|
|
|
if (!text) return 0;
|
|
|
|
if (text[0] == 0) return 0;
|
2000-12-29 12:43:48 -08:00
|
|
|
|
|
|
|
for (i = 0; text[i]; i++)
|
|
|
|
{
|
|
|
|
Evas_GL_Glyph *g;
|
|
|
|
int glyph;
|
|
|
|
|
|
|
|
glyph = ((unsigned char *)text)[i];
|
|
|
|
g = __evas_gl_text_font_get_glyph(fn, glyph);
|
|
|
|
if (!g) continue;
|
|
|
|
if (!TT_VALID(g->glyph)) continue;
|
|
|
|
return ((-g->metrics.bearingX) / 64);
|
|
|
|
}
|
|
|
|
return 0;
|
2000-09-13 10:11:53 -07:00
|
|
|
}
|
|
|
|
|
2000-08-05 17:26:34 -07:00
|
|
|
void
|
|
|
|
__evas_gl_text_font_add_path(char *path)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < __evas_fpath_num; i++)
|
|
|
|
{
|
|
|
|
if (!strcmp(path, __evas_fpath[i])) return;
|
|
|
|
}
|
|
|
|
__evas_fpath_num++;
|
|
|
|
if (!__evas_fpath) __evas_fpath = malloc(sizeof(char *));
|
|
|
|
else __evas_fpath = realloc(__evas_fpath,
|
|
|
|
(__evas_fpath_num * sizeof(char *)));
|
|
|
|
__evas_fpath[__evas_fpath_num - 1] = strdup(path);
|
2000-08-05 17:26:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__evas_gl_text_font_del_path(char *path)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
int i, j;
|
|
|
|
|
|
|
|
for (i = 0; i < __evas_fpath_num; i++)
|
|
|
|
{
|
|
|
|
if (!strcmp(path, __evas_fpath[i]))
|
|
|
|
{
|
|
|
|
__evas_fpath_num--;
|
|
|
|
for (j = i; j < __evas_fpath_num; j++)
|
|
|
|
__evas_fpath[j] = __evas_fpath[j + 1];
|
|
|
|
if (__evas_fpath_num > 0)
|
|
|
|
__evas_fpath = realloc(__evas_fpath,
|
|
|
|
__evas_fpath_num * sizeof(char *));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
free(__evas_fpath);
|
|
|
|
__evas_fpath = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
char **
|
|
|
|
__evas_gl_text_font_list_paths(int *count)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
*count = __evas_fpath_num;
|
|
|
|
return __evas_fpath;
|
2000-08-05 17:26:34 -07:00
|
|
|
}
|
|
|
|
|
2000-08-05 19:06:24 -07:00
|
|
|
void
|
|
|
|
__evas_gl_text_cache_empty(Display *disp)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
int prev_cache;
|
2000-08-06 18:54:22 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
prev_cache = __evas_font_cache_max;
|
|
|
|
__evas_font_cache_max = 0;
|
|
|
|
__evas_gl_text_font_cache_flush();
|
|
|
|
__evas_font_cache_max = prev_cache;
|
2000-08-05 19:06:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__evas_gl_text_cache_set_size(Display *disp, int size)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
__evas_font_cache_max = size;
|
|
|
|
__evas_gl_text_font_cache_flush();
|
2000-08-05 19:06:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
__evas_gl_text_cache_get_size(Display *disp)
|
|
|
|
{
|
2000-08-06 18:54:22 -07:00
|
|
|
return __evas_font_cache_max;
|
2000-08-05 19:06:24 -07:00
|
|
|
}
|
|
|
|
|
2000-08-05 17:26:34 -07:00
|
|
|
void
|
2000-09-13 15:36:46 -07:00
|
|
|
__evas_gl_text_draw(Evas_GL_Font *fn, Display *disp, Imlib_Image dstim, Window win,
|
2000-08-06 17:50:40 -07:00
|
|
|
int win_w, int win_h, int x, int y, char *text,
|
2000-12-27 12:51:39 -08:00
|
|
|
int cr, int cg, int cb, int ca)
|
2000-08-05 17:26:34 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Window *glw;
|
|
|
|
Evas_List l;
|
|
|
|
int go;
|
|
|
|
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
cr = (cr * __evas_clip_r) / 255;
|
|
|
|
cg = (cg * __evas_clip_g) / 255;
|
|
|
|
cb = (cb * __evas_clip_b) / 255;
|
|
|
|
ca = (ca * __evas_clip_a) / 255;
|
|
|
|
}
|
|
|
|
if (ca <= 0) return;
|
|
|
|
glw = __evas_gl_window_current(disp, win, win_w, win_h);
|
|
|
|
if (!glw) return;
|
|
|
|
__evas_gl_window_texture(glw, 1);
|
|
|
|
__evas_gl_window_blend(glw, 1);
|
|
|
|
__evas_gl_window_write_buf(glw, GL_BACK);
|
|
|
|
__evas_gl_window_read_buf(glw, GL_BACK);
|
|
|
|
__evas_gl_window_color(glw, cr, cg, cb, ca);
|
|
|
|
__evas_gl_window_dither(glw, 1);
|
|
|
|
|
|
|
|
#ifndef GLNOCLIP
|
|
|
|
for (l = glw->updates; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Rect *rect;
|
|
|
|
|
|
|
|
go = 1;
|
|
|
|
rect = l->data;
|
|
|
|
{
|
|
|
|
int rx, ry, rw, rh;
|
|
|
|
|
|
|
|
rx = 0;
|
|
|
|
ry = 0;
|
|
|
|
rw = win_w;
|
|
|
|
rh = win_h;
|
|
|
|
CLIP_TO(rx, ry, rw, rh, rect->x, rect->y, rect->w, rect->h);
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
CLIP_TO(rx, ry, rw, rh,
|
|
|
|
__evas_clip_x, __evas_clip_y,
|
|
|
|
__evas_clip_w, __evas_clip_h);
|
|
|
|
}
|
|
|
|
if ((rw > 0) && (rh > 0))
|
|
|
|
__evas_gl_window_clip(glw, 1, rx, ry, rw, rh);
|
|
|
|
else go = 0;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
go = 1;
|
|
|
|
{
|
|
|
|
int rx, ry, rw, rh;
|
|
|
|
|
|
|
|
rx = 0;
|
|
|
|
ry = 0;
|
|
|
|
rw = win_w;
|
|
|
|
rh = win_h;
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
CLIP_TO(rx, ry, rw, rh,
|
|
|
|
__evas_clip_x, __evas_clip_y,
|
|
|
|
__evas_clip_w, __evas_clip_h);
|
|
|
|
if ((rw > 0) && (rh > 0))
|
|
|
|
__evas_gl_window_clip(glw, 1, rx, ry, rw, rh);
|
|
|
|
else go = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
__evas_gl_window_clip(glw, 0, 0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
/* render string here */
|
|
|
|
if (go)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int x_offset, y_offset;
|
|
|
|
int glyph, rows;
|
|
|
|
Evas_GL_Glyph *g;
|
|
|
|
|
|
|
|
if (text[0] == 0) return;
|
|
|
|
glyph = ((unsigned char *)text)[0];
|
|
|
|
g = __evas_gl_text_font_get_glyph(fn, glyph);
|
2000-12-27 13:47:38 -08:00
|
|
|
if (!TT_VALID(g->glyph))
|
|
|
|
#ifndef GLNOCLIP
|
|
|
|
continue;
|
|
|
|
#else
|
|
|
|
return;
|
|
|
|
#endif
|
2000-12-27 12:51:39 -08:00
|
|
|
x_offset = 0;
|
|
|
|
if (g) x_offset = - (g->metrics.bearingX / 64);
|
|
|
|
y_offset = -(fn->max_descent / 64);
|
|
|
|
__evas_gl_text_get_size(fn, text, NULL, &rows);
|
|
|
|
for (i = 0; text[i]; i++)
|
|
|
|
{
|
|
|
|
int xmin, ymin, xmax, ymax, off, adj;
|
|
|
|
|
|
|
|
/* for internationalization this here wouldnt just use */
|
|
|
|
/* the char value of the text[i] but translate form utf-8 */
|
|
|
|
/* or whetever and incriment i appropriately and set g to */
|
|
|
|
/* the glyph index */
|
|
|
|
glyph = ((unsigned char *)text)[i];
|
|
|
|
g = __evas_gl_text_font_get_glyph(fn, glyph);
|
|
|
|
__evas_gl_text_font_render_glyph(glw, fn, g);
|
|
|
|
if (!g) continue;
|
|
|
|
if (!TT_VALID(g->glyph)) continue;
|
|
|
|
|
|
|
|
xmin = g->metrics.bbox.xMin & -64;
|
|
|
|
ymin = g->metrics.bbox.yMin & -64;
|
|
|
|
xmax = (g->metrics.bbox.xMax + 63) & -64;
|
|
|
|
ymax = (g->metrics.bbox.yMax + 63) & -64;
|
|
|
|
|
|
|
|
xmin = (xmin >> 6) + x_offset;
|
|
|
|
ymin = (ymin >> 6) + y_offset;
|
|
|
|
xmax = (xmax >> 6) + x_offset;
|
|
|
|
ymax = (ymax >> 6) + y_offset;
|
|
|
|
|
|
|
|
if (ymin < 0) off = 0;
|
|
|
|
else off = rows - ymin - 1;
|
|
|
|
adj = (rows - ymax) -
|
|
|
|
((fn->max_ascent - fn->max_descent) >> 6);
|
|
|
|
if ((g->texture) && (g->texture->texture))
|
|
|
|
{
|
|
|
|
__evas_gl_window_texture(glw, 1);
|
|
|
|
__evas_gl_window_use_texture(glw,
|
|
|
|
g->texture->texture,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
__evas_gl_window_texture(glw, 0);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glTexCoord2d(g->tex.x1, g->tex.y1);
|
|
|
|
glVertex2i(x + xmin, y + ymin + off + adj);
|
|
|
|
glTexCoord2d(g->tex.x2, g->tex.y1);
|
|
|
|
glVertex2i(x + xmax + 1, y + ymin + off + adj);
|
|
|
|
glTexCoord2d(g->tex.x2, g->tex.y2);
|
|
|
|
glVertex2i(x + xmax + 1, y + ymax + off + adj + 1);
|
|
|
|
glTexCoord2d(g->tex.x1, g->tex.y2);
|
|
|
|
glVertex2i(x + xmin, y + ymax + off + adj + 1);
|
|
|
|
glEnd();
|
|
|
|
x_offset += g->metrics.advance / 64;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#ifndef GLNOCLIP
|
|
|
|
}
|
|
|
|
#endif
|
2000-08-05 17:26:34 -07:00
|
|
|
}
|
|
|
|
|
2000-08-06 18:54:22 -07:00
|
|
|
void
|
|
|
|
__evas_gl_text_get_size(Evas_GL_Font *fn, char *text, int *w, int *h)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
int i, pw, ph;
|
|
|
|
Evas_GL_Glyph *g;
|
|
|
|
int glyph;
|
2000-08-10 15:12:42 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
if (!fn) return;
|
|
|
|
if (!text) return;
|
|
|
|
if (text[0] == 0) return;
|
|
|
|
pw = 0;
|
|
|
|
ph = (fn->max_ascent - fn->max_descent) / 64;
|
2000-08-10 15:12:42 -07:00
|
|
|
for (i = 0; text[i]; i++)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
/* for internationalization this here wouldnt just use */
|
|
|
|
/* the char value of the text[i] but translate form utf-8 */
|
|
|
|
/* or whetever and incriment i appropriately and set g to */
|
|
|
|
/* the glyph index */
|
|
|
|
glyph = ((unsigned char *)text)[i];
|
|
|
|
g = __evas_gl_text_font_get_glyph(fn, glyph);
|
|
|
|
if (!g) continue;
|
|
|
|
if (!TT_VALID(g->glyph)) continue;
|
2000-08-10 15:12:42 -07:00
|
|
|
if (i == 0)
|
2000-12-27 12:51:39 -08:00
|
|
|
pw += ((-g->metrics.bearingX) / 64);
|
|
|
|
if (text[i + 1] == 0) /* last char - ineternationalization issue */
|
2001-01-17 13:31:30 -08:00
|
|
|
{
|
|
|
|
if ((g->metrics.bbox.xMax / 64) == 0)
|
|
|
|
pw += (g->metrics.advance / 64);
|
|
|
|
else
|
|
|
|
pw += (g->metrics.bbox.xMax / 64);
|
|
|
|
}
|
2000-08-10 15:12:42 -07:00
|
|
|
else
|
2000-12-27 12:51:39 -08:00
|
|
|
pw += g->metrics.advance / 64;
|
2000-08-10 15:12:42 -07:00
|
|
|
}
|
2000-12-29 12:43:48 -08:00
|
|
|
if (w) *w = pw;
|
|
|
|
if (h) *h = ph;
|
2000-08-10 15:12:42 -07:00
|
|
|
}
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
int
|
|
|
|
__evas_gl_text_get_character_at_pos(Evas_GL_Font *fn, char *text, int x, int y, int *cx, int *cy, int *cw, int *ch)
|
2000-08-10 15:12:42 -07:00
|
|
|
{
|
|
|
|
int i, px, ppx;
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
if (cx) *cx = 0;
|
|
|
|
if (cy) *cy = 0;
|
|
|
|
if (cw) *cw = 0;
|
|
|
|
if (ch) *ch = 0;
|
|
|
|
if (!fn) return -1;
|
|
|
|
if (!text) return -1;
|
|
|
|
if (text[0] == 0) return -1;
|
|
|
|
|
|
|
|
if ((y < 0) || (y > (fn->ascent + fn->descent))) return -1;
|
|
|
|
if (cy) *cy = 0;
|
|
|
|
if (ch) *ch = fn->ascent + fn->descent;
|
2000-08-10 15:12:42 -07:00
|
|
|
ppx = 0;
|
|
|
|
px = 0;
|
|
|
|
for (i = 0; text[i]; i++)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Glyph *g;
|
|
|
|
int glyph;
|
2000-08-10 15:12:42 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
glyph = ((unsigned char *)text)[i];
|
|
|
|
g = __evas_gl_text_font_get_glyph(fn, glyph);
|
|
|
|
if (!g) continue;
|
|
|
|
if (!TT_VALID(g->glyph)) continue;
|
|
|
|
if (i == 0)
|
|
|
|
px += ((-g->metrics.bearingX) / 64);
|
2000-08-10 15:12:42 -07:00
|
|
|
if (text[i + 1] == 0)
|
2000-12-27 12:51:39 -08:00
|
|
|
px += (g->metrics.bbox.xMax / 64);
|
2000-08-10 15:12:42 -07:00
|
|
|
else
|
2000-12-27 12:51:39 -08:00
|
|
|
px += g->metrics.advance / 64;
|
|
|
|
if ((x >= ppx) && (x < px))
|
2000-08-10 15:12:42 -07:00
|
|
|
{
|
|
|
|
if (cx)
|
2000-12-27 12:51:39 -08:00
|
|
|
*cx = ppx;
|
2000-08-10 15:12:42 -07:00
|
|
|
if (cw)
|
2000-12-27 12:51:39 -08:00
|
|
|
*cw = px - ppx;
|
|
|
|
return i;
|
2000-08-10 15:12:42 -07:00
|
|
|
}
|
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
return -1;
|
|
|
|
}
|
2000-08-10 03:14:55 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
void
|
|
|
|
__evas_gl_text_get_character_number(Evas_GL_Font *fn, char *text, int num, int *cx, int *cy, int *cw, int *ch)
|
|
|
|
{
|
|
|
|
int i, px, ppx;
|
2000-08-06 20:11:05 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
if (cx) *cx = 0;
|
|
|
|
if (cy) *cy = 0;
|
|
|
|
if (cw) *cw = 0;
|
|
|
|
if (ch) *ch = 0;
|
|
|
|
if (!fn) return;
|
|
|
|
if (!text) return;
|
|
|
|
if (text[0] == 0) return;
|
2000-08-06 20:11:05 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
if (cy) *cy = 0;
|
|
|
|
if (ch) *ch = fn->ascent + fn->descent;
|
|
|
|
ppx = 0;
|
|
|
|
px = 0;
|
|
|
|
for (i = 0; text[i]; i++)
|
|
|
|
{
|
|
|
|
Evas_GL_Glyph *g;
|
|
|
|
int glyph;
|
|
|
|
|
|
|
|
glyph = ((unsigned char *)text)[i];
|
|
|
|
g = __evas_gl_text_font_get_glyph(fn, glyph);
|
|
|
|
if (!g) continue;
|
|
|
|
if (!TT_VALID(g->glyph)) continue;
|
|
|
|
ppx = px;
|
|
|
|
if (i == 0)
|
|
|
|
px += ((-g->metrics.bearingX) / 64);
|
|
|
|
if (text[i + 1] == 0)
|
|
|
|
px += (g->metrics.bbox.xMax / 64);
|
|
|
|
else
|
|
|
|
px += g->metrics.advance / 64;
|
|
|
|
if (i == num)
|
|
|
|
{
|
|
|
|
if (cx) *cx = ppx;
|
|
|
|
if (cw) *cw = px - ppx;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2000-08-06 20:11:05 -07:00
|
|
|
}
|
|
|
|
|
2000-08-09 21:20:29 -07:00
|
|
|
/*****************************************************************************/
|
2000-12-27 12:51:39 -08:00
|
|
|
/* rectangle externals *******************************************************/
|
2000-08-09 21:20:29 -07:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
void __evas_gl_rectangle_draw(Display *disp, Imlib_Image dstim, Window win,
|
|
|
|
int win_w, int win_h,
|
|
|
|
int x, int y, int w, int h,
|
|
|
|
int cr, int cg, int cb, int ca)
|
2000-08-09 21:20:29 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Window *glw;
|
|
|
|
Evas_List l;
|
|
|
|
int go;
|
|
|
|
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
cr = (cr * __evas_clip_r) / 255;
|
|
|
|
cg = (cg * __evas_clip_g) / 255;
|
|
|
|
cb = (cb * __evas_clip_b) / 255;
|
|
|
|
ca = (ca * __evas_clip_a) / 255;
|
|
|
|
}
|
|
|
|
if (ca <= 0) return;
|
|
|
|
if (w < 1) return;
|
|
|
|
if (h < 1) return;
|
|
|
|
glw = __evas_gl_window_current(disp, win, win_w, win_h);
|
|
|
|
if (!glw) return;
|
|
|
|
__evas_gl_window_texture(glw, 0);
|
|
|
|
if (ca < 255) __evas_gl_window_blend(glw, 1);
|
|
|
|
else __evas_gl_window_blend(glw, 0);
|
|
|
|
__evas_gl_window_write_buf(glw, GL_BACK);
|
|
|
|
__evas_gl_window_read_buf(glw, GL_BACK);
|
|
|
|
__evas_gl_window_color(glw, cr, cg, cb, ca);
|
|
|
|
__evas_gl_window_dither(glw, 1);
|
|
|
|
|
|
|
|
#ifndef GLNOCLIP
|
|
|
|
for (l = glw->updates; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Rect *rect;
|
2000-08-09 21:20:29 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
go = 1;
|
|
|
|
rect = l->data;
|
2000-08-09 21:20:29 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
int rx, ry, rw, rh;
|
|
|
|
|
|
|
|
rx = x;
|
|
|
|
ry = y;
|
|
|
|
rw = w;
|
|
|
|
rh = h;
|
|
|
|
CLIP_TO(rx, ry, rw, rh, rect->x, rect->y, rect->w, rect->h);
|
|
|
|
if (__evas_clip)
|
2000-08-09 21:20:29 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
CLIP_TO(rx, ry, rw, rh,
|
|
|
|
__evas_clip_x, __evas_clip_y,
|
|
|
|
__evas_clip_w, __evas_clip_h);
|
2000-08-09 21:20:29 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
if ((rw > 0) && (rh > 0))
|
|
|
|
__evas_gl_window_clip(glw, 1, rx, ry, rw, rh);
|
|
|
|
else go = 0;
|
2000-08-09 21:20:29 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
#else
|
|
|
|
go = 1;
|
2000-08-09 21:20:29 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
int rx, ry, rw, rh;
|
|
|
|
|
|
|
|
rx = x;
|
|
|
|
ry = y;
|
|
|
|
rw = w;
|
|
|
|
rh = h;
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
CLIP_TO(rx, ry, rw, rh,
|
|
|
|
__evas_clip_x, __evas_clip_y,
|
|
|
|
__evas_clip_w, __evas_clip_h);
|
|
|
|
if ((rw > 0) && (rh > 0))
|
|
|
|
__evas_gl_window_clip(glw, 1, rx, ry, rw, rh);
|
|
|
|
else go = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
__evas_gl_window_clip(glw, 0, 0, 0, 0, 0);
|
2000-08-09 21:20:29 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
#endif
|
|
|
|
/* render rect here */
|
|
|
|
if (go)
|
2000-08-09 21:20:29 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
double x1, x2, y1, y2;
|
|
|
|
|
|
|
|
x1 = (double)x;
|
|
|
|
y1 = (double)y;
|
|
|
|
x2 = (double)(x + w);
|
|
|
|
y2 = (double)(y + h);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glVertex2d(x1, y1);
|
|
|
|
glVertex2d(x2, y1);
|
|
|
|
glVertex2d(x2, y2);
|
|
|
|
glVertex2d(x1, y2);
|
|
|
|
glEnd();
|
2000-08-09 21:20:29 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
#ifndef GLNOCLIP
|
2000-08-09 21:20:29 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* line externals ************************************************************/
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
void __evas_gl_line_draw(Display *disp, Imlib_Image dstim, Window win,
|
|
|
|
int win_w, int win_h,
|
|
|
|
int x1, int y1, int x2, int y2,
|
|
|
|
int cr, int cg, int cb, int ca)
|
|
|
|
{
|
|
|
|
Evas_GL_Window *glw;
|
|
|
|
Evas_List l;
|
|
|
|
int go;
|
|
|
|
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
cr = (cr * __evas_clip_r) / 255;
|
|
|
|
cg = (cg * __evas_clip_g) / 255;
|
|
|
|
cb = (cb * __evas_clip_b) / 255;
|
|
|
|
ca = (ca * __evas_clip_a) / 255;
|
|
|
|
}
|
|
|
|
if (ca <= 0) return;
|
|
|
|
glw = __evas_gl_window_current(disp, win, win_w, win_h);
|
|
|
|
if (!glw) return;
|
|
|
|
__evas_gl_window_texture(glw, 0);
|
|
|
|
if (ca < 255) __evas_gl_window_blend(glw, 1);
|
|
|
|
else __evas_gl_window_blend(glw, 0);
|
|
|
|
__evas_gl_window_write_buf(glw, GL_BACK);
|
|
|
|
__evas_gl_window_read_buf(glw, GL_BACK);
|
|
|
|
__evas_gl_window_color(glw, cr, cg, cb, ca);
|
|
|
|
__evas_gl_window_dither(glw, 1);
|
|
|
|
|
|
|
|
#ifndef GLNOCLIP
|
|
|
|
for (l = glw->updates; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Rect *rect;
|
|
|
|
|
|
|
|
go = 1;
|
|
|
|
rect = l->data;
|
|
|
|
{
|
|
|
|
int rx, ry, rw, rh;
|
|
|
|
|
|
|
|
rx = 0;
|
|
|
|
ry = 0;
|
|
|
|
rw = win_w;
|
|
|
|
rh = win_h;
|
|
|
|
CLIP_TO(rx, ry, rw, rh, rect->x, rect->y, rect->w, rect->h);
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
CLIP_TO(rx, ry, rw, rh,
|
|
|
|
__evas_clip_x, __evas_clip_y,
|
|
|
|
__evas_clip_w, __evas_clip_h);
|
|
|
|
}
|
|
|
|
if ((rw > 0) && (rh > 0))
|
|
|
|
__evas_gl_window_clip(glw, 1, rx, ry, rw, rh);
|
|
|
|
else go = 0;
|
2000-08-09 21:20:29 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
#else
|
|
|
|
go = 1;
|
2000-08-10 03:14:55 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
int rx, ry, rw, rh;
|
|
|
|
|
|
|
|
rx = 0;
|
|
|
|
ry = 0;
|
|
|
|
rw = win_w;
|
|
|
|
rh = win_h;
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
CLIP_TO(rx, ry, rw, rh,
|
|
|
|
__evas_clip_x, __evas_clip_y,
|
|
|
|
__evas_clip_w, __evas_clip_h);
|
|
|
|
if ((rw > 0) && (rh > 0))
|
|
|
|
__evas_gl_window_clip(glw, 1, rx, ry, rw, rh);
|
|
|
|
else go = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
__evas_gl_window_clip(glw, 0, 0, 0, 0, 0);
|
2000-08-10 03:14:55 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
#endif
|
|
|
|
/* render rect here */
|
|
|
|
if (go)
|
|
|
|
{
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex2d((double)x1 + 0.5, (double)y1 + 0.5);
|
|
|
|
glVertex2d((double)x2 + 0.5, (double)y2 + 0.5);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
#ifndef GLNOCLIP
|
2000-08-09 21:20:29 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
#endif
|
2000-08-09 21:20:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* gradient externals ********************************************************/
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
Evas_GL_Graident *
|
|
|
|
__evas_gl_gradient_new(Display *disp)
|
|
|
|
{
|
|
|
|
Evas_GL_Graident *gr;
|
|
|
|
|
|
|
|
gr = malloc(sizeof(Evas_GL_Graident));
|
2000-12-27 12:51:39 -08:00
|
|
|
gr->col_range = NULL;
|
|
|
|
gr->textures = NULL;
|
2000-08-09 21:20:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__evas_gl_gradient_free(Evas_GL_Graident *gr)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
if (gr->col_range)
|
|
|
|
{
|
|
|
|
imlib_context_set_color_range(gr->col_range);
|
|
|
|
imlib_free_color_range();
|
|
|
|
}
|
|
|
|
if (gr->textures);
|
|
|
|
{
|
|
|
|
Evas_List l;
|
|
|
|
|
|
|
|
for (l = gr->textures; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Graident_Texture *tg;
|
|
|
|
|
|
|
|
tg = l->data;
|
|
|
|
__evas_gl_gradient_texture_free(tg);
|
|
|
|
}
|
|
|
|
evas_list_free(gr->textures);
|
|
|
|
}
|
|
|
|
free(gr);
|
2000-08-09 21:20:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__evas_gl_gradient_color_add(Evas_GL_Graident *gr, int r, int g, int b,
|
|
|
|
int a, int dist)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
if (!gr->col_range) gr->col_range = imlib_create_color_range();
|
|
|
|
imlib_context_set_color_range(gr->col_range);
|
|
|
|
imlib_context_set_color(r, g, b, a);
|
|
|
|
imlib_add_color_to_color_range(dist);
|
2000-08-09 21:20:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__evas_gl_gradient_draw(Evas_GL_Graident *gr,
|
2000-09-13 15:36:46 -07:00
|
|
|
Display *disp, Imlib_Image dstim, Window win, int win_w, int win_h,
|
2000-08-09 21:20:29 -07:00
|
|
|
int x, int y, int w, int h, double angle)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Window *glw;
|
|
|
|
Evas_List l;
|
|
|
|
int go;
|
|
|
|
int cr, cg, cb, ca;
|
|
|
|
Evas_GL_Graident_Texture *tg;
|
2000-08-09 21:20:29 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
if (__evas_clip)
|
2000-08-09 21:20:29 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
cr = __evas_clip_r;
|
|
|
|
cg = __evas_clip_g;
|
|
|
|
cb = __evas_clip_b;
|
|
|
|
ca = __evas_clip_a;
|
2000-08-09 21:20:29 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
else
|
2000-08-09 21:20:29 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
cr = 255;
|
|
|
|
cg = 255;
|
|
|
|
cb = 255;
|
|
|
|
ca = 255;
|
|
|
|
}
|
|
|
|
if (ca <= 0) return;
|
|
|
|
if (w < 1) return;
|
|
|
|
if (h < 1) return;
|
|
|
|
glw = __evas_gl_window_current(disp, win, win_w, win_h);
|
|
|
|
if (!glw) return;
|
|
|
|
__evas_gl_window_texture(glw, 1);
|
|
|
|
__evas_gl_window_blend(glw, 1);
|
|
|
|
__evas_gl_window_write_buf(glw, GL_BACK);
|
|
|
|
__evas_gl_window_read_buf(glw, GL_BACK);
|
|
|
|
__evas_gl_window_color(glw, cr, cg, cb, ca);
|
|
|
|
__evas_gl_window_dither(glw, 1);
|
|
|
|
|
|
|
|
#ifndef GLNOCLIP
|
|
|
|
for (l = glw->updates; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Rect *rect;
|
|
|
|
|
|
|
|
go = 1;
|
|
|
|
rect = l->data;
|
|
|
|
{
|
|
|
|
int rx, ry, rw, rh;
|
|
|
|
|
|
|
|
rx = x;
|
|
|
|
ry = y;
|
|
|
|
rw = w;
|
|
|
|
rh = h;
|
|
|
|
CLIP_TO(rx, ry, rw, rh, rect->x, rect->y, rect->w, rect->h);
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
CLIP_TO(rx, ry, rw, rh,
|
|
|
|
__evas_clip_x, __evas_clip_y,
|
|
|
|
__evas_clip_w, __evas_clip_h);
|
|
|
|
}
|
|
|
|
if ((rw > 0) && (rh > 0))
|
|
|
|
__evas_gl_window_clip(glw, 1, rx, ry, rw, rh);
|
|
|
|
else go = 0;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
go = 1;
|
|
|
|
{
|
|
|
|
int rx, ry, rw, rh;
|
|
|
|
|
|
|
|
rx = x;
|
|
|
|
ry = y;
|
|
|
|
rw = w;
|
|
|
|
rh = h;
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
CLIP_TO(rx, ry, rw, rh,
|
|
|
|
__evas_clip_x, __evas_clip_y,
|
|
|
|
__evas_clip_w, __evas_clip_h);
|
|
|
|
if ((rw > 0) && (rh > 0))
|
|
|
|
__evas_gl_window_clip(glw, 1, rx, ry, rw, rh);
|
|
|
|
else go = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
__evas_gl_window_clip(glw, 0, 0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
/* render gradient here */
|
|
|
|
if (go)
|
|
|
|
{
|
|
|
|
double x1, x2, y1, y2;
|
|
|
|
double max, t[8];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
tg = __evas_gl_gradient_texture_new(glw, gr);
|
|
|
|
if (!tg->texture)
|
|
|
|
{
|
|
|
|
Imlib_Image prev_im, im;
|
|
|
|
DATA32 *data;
|
|
|
|
int tw, th;
|
|
|
|
|
|
|
|
tw = glw->context->max_texture_size;
|
|
|
|
th = 4;
|
|
|
|
im = imlib_create_image(tw, th);
|
|
|
|
prev_im = imlib_context_get_image();
|
|
|
|
imlib_context_set_image(im);
|
|
|
|
imlib_image_set_has_alpha(1);
|
|
|
|
data = imlib_image_get_data();
|
|
|
|
memset(data, 0, tw * th * sizeof(DATA32));
|
|
|
|
imlib_image_put_back_data(data);
|
|
|
|
imlib_context_set_color_range(gr->col_range);
|
|
|
|
imlib_image_fill_color_range_rectangle(1, 1, tw - 2, th - 2,
|
|
|
|
270.0);
|
|
|
|
data = imlib_image_get_data();
|
|
|
|
memcpy(&(data[(1) + (0 * tw)]), &(data[(1) + (1 * tw)]),
|
|
|
|
(tw - 2) * sizeof(DATA32));
|
|
|
|
memcpy(&(data[(1) + (3 * tw)]), &(data[(1) + (2 * tw)]),
|
|
|
|
(tw - 2) * sizeof(DATA32));
|
|
|
|
data[(0) + (0 * tw)] = data[(1) + (0 * tw)];
|
|
|
|
data[(0) + (1 * tw)] = data[(1) + (1 * tw)];
|
|
|
|
data[(0) + (2 * tw)] = data[(1) + (2 * tw)];
|
|
|
|
data[(0) + (3 * tw)] = data[(1) + (3 * tw)];
|
|
|
|
data[(tw - 1) + (0 * tw)] = data[(tw - 2) + (0 * tw)];
|
|
|
|
data[(tw - 1) + (1 * tw)] = data[(tw - 2) + (1 * tw)];
|
|
|
|
data[(tw - 1) + (2 * tw)] = data[(tw - 2) + (2 * tw)];
|
|
|
|
data[(tw - 1) + (3 * tw)] = data[(tw - 2) + (3 * tw)];
|
|
|
|
imlib_image_put_back_data(data);
|
|
|
|
tg->texture = __evas_gl_texture_new(glw, im, 0, 0, tw, th);
|
|
|
|
imlib_free_image();
|
|
|
|
}
|
|
|
|
__evas_gl_window_use_texture(glw, tg->texture, 1);
|
|
|
|
t[0] = cos(((-angle + 45 + 90) * 2 * 3.141592654) / 360);
|
|
|
|
t[1] = sin(((-angle + 45 + 90) * 2 * 3.141592654) / 360);
|
|
|
|
|
|
|
|
t[2] = cos(((-angle + 45 + 180) * 2 * 3.141592654) / 360);
|
|
|
|
t[3] = sin(((-angle + 45 + 180) * 2 * 3.141592654) / 360);
|
|
|
|
|
|
|
|
t[4] = cos(((-angle + 45 + 270) * 2 * 3.141592654) / 360);
|
|
|
|
t[5] = sin(((-angle + 45 + 270) * 2 * 3.141592654) / 360);
|
|
|
|
|
|
|
|
t[6] = cos(((-angle + 45 + 0) * 2 * 3.141592654) / 360);
|
|
|
|
t[7] = sin(((-angle + 45 + 0) * 2 * 3.141592654) / 360);
|
|
|
|
max = 0;
|
|
|
|
for (i = 0; i < 8; i++)
|
|
|
|
{
|
|
|
|
if ((t[i] < 0) && (-t[i] > max)) max = -t[i];
|
|
|
|
else if ((t[i] > max)) max = t[i];
|
|
|
|
}
|
|
|
|
if (max > 0)
|
|
|
|
{
|
|
|
|
for (i = 0; i < 8; i++) t[i] *= 1 / max;
|
|
|
|
}
|
|
|
|
for (i = 0; i < 8; i+=2)
|
|
|
|
{
|
|
|
|
t[i] = (1.0 +
|
|
|
|
((((0.5) + (t[i] / 2.0)) *
|
|
|
|
((double)glw->context->max_texture_size - 2.0)))) /
|
|
|
|
(double)glw->context->max_texture_size;
|
|
|
|
t[i + 1] = (1.0 + ((((0.5) - (t[i + 1] / 2.0))) * 2.0)) / 4.0;
|
|
|
|
}
|
|
|
|
x1 = (double)x;
|
|
|
|
y1 = (double)y;
|
|
|
|
x2 = (double)(x + w);
|
|
|
|
y2 = (double)(y + h);
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glTexCoord2d(t[0], t[1]); glVertex2d(x1, y1);
|
|
|
|
glTexCoord2d(t[2], t[3]); glVertex2d(x2, y1);
|
|
|
|
glTexCoord2d(t[4], t[5]); glVertex2d(x2, y2);
|
|
|
|
glTexCoord2d(t[6], t[7]); glVertex2d(x1, y2);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
#ifndef GLNOCLIP
|
2000-08-09 21:20:29 -07:00
|
|
|
}
|
2000-10-12 06:57:49 -07:00
|
|
|
#endif
|
2000-12-27 12:51:39 -08:00
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-12-29 12:43:48 -08:00
|
|
|
/* something is wrong here - GL experts? the polys dont get tesselated */
|
|
|
|
/* correctly */
|
|
|
|
|
|
|
|
#ifdef HAVE_GLU
|
|
|
|
static void
|
|
|
|
__evas_gl_tess_begin_cb(GLenum which)
|
|
|
|
{
|
|
|
|
glBegin(which);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
__evas_gl_tess_end_cb(void)
|
|
|
|
{
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
__evas_gl_tess_error_cb(GLenum errorcode)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
__evas_gl_tess_vertex_cb(GLvoid *vertex)
|
|
|
|
{
|
|
|
|
GLdouble *v;
|
|
|
|
|
|
|
|
v = vertex;
|
|
|
|
glVertex2d(v[0], v[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
__evas_gl_tess_combine_cb(GLdouble coords[3],
|
|
|
|
GLdouble *vertex_data[4],
|
|
|
|
GLfloat weight[4], GLdouble **data_out)
|
|
|
|
{
|
|
|
|
GLdouble *vertex;
|
|
|
|
|
|
|
|
vertex = (GLdouble *) malloc(6 * sizeof(GLdouble));
|
|
|
|
vertex[0] = coords[0];
|
|
|
|
vertex[1] = coords[1];
|
|
|
|
*data_out = vertex;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2000-10-11 17:26:34 -07:00
|
|
|
/************/
|
|
|
|
/* polygons */
|
|
|
|
/************/
|
|
|
|
void
|
|
|
|
__evas_gl_poly_draw (Display *disp, Imlib_Image dstim, Window win,
|
|
|
|
int win_w, int win_h,
|
|
|
|
Evas_List points,
|
2000-12-27 12:51:39 -08:00
|
|
|
int cr, int cg, int cb, int ca)
|
2000-10-11 17:26:34 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Window *glw;
|
|
|
|
Evas_List l;
|
|
|
|
int go;
|
2000-10-12 06:57:49 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
cr = (cr * __evas_clip_r) / 255;
|
|
|
|
cg = (cg * __evas_clip_g) / 255;
|
|
|
|
cb = (cb * __evas_clip_b) / 255;
|
|
|
|
ca = (ca * __evas_clip_a) / 255;
|
|
|
|
}
|
|
|
|
if (ca <= 0) return;
|
|
|
|
glw = __evas_gl_window_current(disp, win, win_w, win_h);
|
|
|
|
if (!glw) return;
|
|
|
|
__evas_gl_window_texture(glw, 0);
|
|
|
|
if (ca < 255) __evas_gl_window_blend(glw, 1);
|
|
|
|
else __evas_gl_window_blend(glw, 0);
|
|
|
|
__evas_gl_window_write_buf(glw, GL_BACK);
|
|
|
|
__evas_gl_window_read_buf(glw, GL_BACK);
|
|
|
|
__evas_gl_window_color(glw, cr, cg, cb, ca);
|
|
|
|
__evas_gl_window_dither(glw, 1);
|
|
|
|
|
|
|
|
#ifndef GLNOCLIP
|
|
|
|
for (l = glw->updates; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Rect *rect;
|
2000-10-12 06:57:49 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
go = 1;
|
|
|
|
rect = l->data;
|
2000-10-12 06:57:49 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
int rx, ry, rw, rh;
|
2000-10-12 06:57:49 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
rx = 0;
|
|
|
|
ry = 0;
|
|
|
|
rw = win_w;
|
|
|
|
rh = win_h;
|
|
|
|
CLIP_TO(rx, ry, rw, rh, rect->x, rect->y, rect->w, rect->h);
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
CLIP_TO(rx, ry, rw, rh,
|
|
|
|
__evas_clip_x, __evas_clip_y,
|
|
|
|
__evas_clip_w, __evas_clip_h);
|
|
|
|
}
|
|
|
|
if ((rw > 0) && (rh > 0))
|
|
|
|
__evas_gl_window_clip(glw, 1, rx, ry, rw, rh);
|
|
|
|
else go = 0;
|
2000-10-12 06:57:49 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
#else
|
|
|
|
go = 1;
|
2000-10-12 06:57:49 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
int rx, ry, rw, rh;
|
2000-10-12 06:57:49 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
rx = 0;
|
|
|
|
ry = 0;
|
|
|
|
rw = win_w;
|
|
|
|
rh = win_h;
|
|
|
|
if (__evas_clip)
|
|
|
|
{
|
|
|
|
CLIP_TO(rx, ry, rw, rh,
|
|
|
|
__evas_clip_x, __evas_clip_y,
|
|
|
|
__evas_clip_w, __evas_clip_h);
|
|
|
|
if ((rw > 0) && (rh > 0))
|
|
|
|
__evas_gl_window_clip(glw, 1, rx, ry, rw, rh);
|
|
|
|
else go = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
__evas_gl_window_clip(glw, 0, 0, 0, 0, 0);
|
2000-10-12 06:57:49 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
#endif
|
|
|
|
/* render poly here */
|
|
|
|
if (go)
|
|
|
|
{
|
2000-12-29 12:43:48 -08:00
|
|
|
Evas_List l2;
|
|
|
|
#ifdef HAVE_GLU
|
|
|
|
{
|
|
|
|
static void *tess = NULL;
|
|
|
|
GLdouble *glp = NULL;
|
|
|
|
int i, num;
|
|
|
|
|
|
|
|
if (!tess)
|
|
|
|
{
|
|
|
|
tess = gluNewTess();
|
|
|
|
|
|
|
|
gluTessCallback(tess, GLU_TESS_BEGIN, __evas_gl_tess_begin_cb);
|
|
|
|
gluTessCallback(tess, GLU_TESS_END, __evas_gl_tess_end_cb);
|
|
|
|
gluTessCallback(tess, GLU_TESS_ERROR, __evas_gl_tess_error_cb);
|
|
|
|
gluTessCallback(tess, GLU_TESS_VERTEX, __evas_gl_tess_vertex_cb);
|
|
|
|
gluTessCallback(tess, GLU_TESS_COMBINE, __evas_gl_tess_combine_cb);
|
|
|
|
}
|
2001-01-02 15:09:32 -08:00
|
|
|
num = 0;
|
|
|
|
for (l2 = points; l2; l2 = l2->next) num++;
|
|
|
|
i = 0;
|
|
|
|
glp = malloc(num * 6 * sizeof(GLdouble));
|
2000-12-29 12:43:48 -08:00
|
|
|
gluTessNormal(tess, 0, 0, 1);
|
|
|
|
gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
|
|
|
|
gluTessBeginPolygon(tess, NULL);
|
|
|
|
gluTessBeginContour(tess);
|
|
|
|
for (l2 = points; l2; l2 = l2->next)
|
|
|
|
{
|
|
|
|
Evas_Point p;
|
|
|
|
|
|
|
|
p = l2->data;
|
|
|
|
glp[i++] = p->x;
|
|
|
|
glp[i++] = p->y;
|
|
|
|
glp[i++] = 0;
|
|
|
|
gluTessVertex(tess, &(glp[i - 3]), &(glp[i - 3]));
|
2001-01-02 15:09:32 -08:00
|
|
|
i += 3;
|
2000-12-29 12:43:48 -08:00
|
|
|
}
|
|
|
|
gluTessEndContour(tess);
|
|
|
|
gluTessEndPolygon(tess);
|
|
|
|
free(glp);
|
|
|
|
}
|
|
|
|
#else
|
2000-12-27 12:51:39 -08:00
|
|
|
glBegin(GL_POLYGON);
|
2000-12-29 12:43:48 -08:00
|
|
|
for (l2 = points; l2; l2 = l2->next)
|
2000-12-27 12:51:39 -08:00
|
|
|
{
|
|
|
|
Evas_Point p;
|
|
|
|
|
2000-12-29 12:43:48 -08:00
|
|
|
p = l2->data;
|
2000-12-27 12:51:39 -08:00
|
|
|
glVertex2d(p->x, p->y);
|
|
|
|
}
|
|
|
|
glEnd();
|
2000-12-29 12:43:48 -08:00
|
|
|
#endif
|
2000-12-27 12:51:39 -08:00
|
|
|
}
|
|
|
|
#ifndef GLNOCLIP
|
2000-10-12 06:57:49 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
#endif
|
2000-10-11 17:26:34 -07:00
|
|
|
}
|
|
|
|
|
2000-08-05 17:26:34 -07:00
|
|
|
/*****************************************************************************/
|
|
|
|
/* general externals *********************************************************/
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
void
|
|
|
|
__evas_gl_set_clip_rect(int on, int x, int y, int w, int h, int r, int g, int b, int a)
|
|
|
|
{
|
|
|
|
__evas_clip = on;
|
|
|
|
__evas_clip_x = x;
|
|
|
|
__evas_clip_y = y;
|
|
|
|
__evas_clip_w = w;
|
|
|
|
__evas_clip_h = h;
|
|
|
|
__evas_clip_r = r;
|
|
|
|
__evas_clip_g = g;
|
|
|
|
__evas_clip_b = b;
|
|
|
|
__evas_clip_a = a;
|
|
|
|
}
|
|
|
|
|
2000-08-05 13:11:27 -07:00
|
|
|
void
|
|
|
|
__evas_gl_sync(Display *disp)
|
2000-08-01 20:33:11 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
glFlush();
|
2000-08-01 20:33:11 -07:00
|
|
|
glXWaitGL();
|
|
|
|
XSync(disp, False);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2000-09-13 15:36:46 -07:00
|
|
|
__evas_gl_flush_draw(Display *disp, Imlib_Image dstim, Window win)
|
2000-08-01 20:33:11 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Window *glw;
|
|
|
|
Evas_List l;
|
|
|
|
|
|
|
|
glw = __evas_gl_window_lookup(disp, win);
|
|
|
|
if (!glw) return;
|
|
|
|
if (glw->updates)
|
2000-08-11 00:47:52 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
for (l = glw->updates; l; l = l->next)
|
|
|
|
{
|
|
|
|
Evas_GL_Rect *rect;
|
|
|
|
|
|
|
|
rect = l->data;
|
|
|
|
#ifndef GLSWB
|
|
|
|
__evas_gl_window_swap_rect(glw, rect->x, rect->y, rect->w, rect->h);
|
|
|
|
#endif
|
|
|
|
free(rect);
|
|
|
|
}
|
|
|
|
evas_list_free(glw->updates);
|
|
|
|
glw->updates = NULL;
|
2000-08-11 00:47:52 -07:00
|
|
|
}
|
2000-12-27 12:51:39 -08:00
|
|
|
#ifdef GLSWB
|
2000-08-01 20:33:11 -07:00
|
|
|
glXSwapBuffers(disp, win);
|
2000-12-27 12:51:39 -08:00
|
|
|
#endif
|
2000-08-01 20:33:11 -07:00
|
|
|
}
|
|
|
|
|
2001-07-25 20:31:03 -07:00
|
|
|
void
|
|
|
|
__evas_gl_set_vis_cmap(Visual *vis, Colormap cmap)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2000-08-05 17:26:34 -07:00
|
|
|
int
|
|
|
|
__evas_gl_capable(Display *disp)
|
|
|
|
{
|
|
|
|
int eb, evb;
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_List l;
|
|
|
|
static Evas_List capables = NULL;
|
2000-08-13 17:14:22 -07:00
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
for (l = capables; l; l = l->next)
|
|
|
|
{
|
|
|
|
if (l->data == disp) return 1;
|
|
|
|
}
|
|
|
|
if (glXQueryExtension(disp, &eb, &evb))
|
2000-08-13 17:14:22 -07:00
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
capables = evas_list_prepend(capables, disp);
|
|
|
|
return 1;
|
2000-08-13 17:14:22 -07:00
|
|
|
}
|
|
|
|
return 0;
|
2000-08-05 17:26:34 -07:00
|
|
|
}
|
|
|
|
|
2000-12-27 12:51:39 -08:00
|
|
|
static XVisualInfo *__evas_vi = NULL;
|
|
|
|
|
2000-08-05 17:26:34 -07:00
|
|
|
Visual *
|
2000-08-05 19:06:24 -07:00
|
|
|
__evas_gl_get_visual(Display *disp, int screen)
|
2000-08-05 17:26:34 -07:00
|
|
|
{
|
|
|
|
static Display *d = NULL;
|
2000-12-27 12:51:39 -08:00
|
|
|
|
2000-08-05 17:26:34 -07:00
|
|
|
if (d != disp)
|
|
|
|
{
|
|
|
|
d = disp;
|
2000-08-05 19:06:24 -07:00
|
|
|
__evas_vi = glXChooseVisual(disp, screen, __evas_gl_configuration);
|
2000-08-05 17:26:34 -07:00
|
|
|
}
|
|
|
|
return __evas_vi->visual;
|
|
|
|
}
|
|
|
|
|
|
|
|
XVisualInfo *
|
2000-08-05 19:06:24 -07:00
|
|
|
__evas_gl_get_visual_info(Display *disp, int screen)
|
2000-08-05 17:26:34 -07:00
|
|
|
{
|
2000-08-05 19:06:24 -07:00
|
|
|
__evas_gl_get_visual(disp, screen);
|
2000-08-05 17:26:34 -07:00
|
|
|
return __evas_vi;
|
|
|
|
}
|
|
|
|
|
|
|
|
Colormap
|
2000-08-05 19:06:24 -07:00
|
|
|
__evas_gl_get_colormap(Display *disp, int screen)
|
2000-08-05 17:26:34 -07:00
|
|
|
{
|
|
|
|
static Display *d = NULL;
|
|
|
|
static Colormap cmap = 0;
|
|
|
|
|
2000-08-05 19:06:24 -07:00
|
|
|
if (!__evas_vi) __evas_gl_get_visual(disp, screen);
|
2000-08-05 17:26:34 -07:00
|
|
|
if (d != disp)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
d = disp;
|
|
|
|
cmap = XCreateColormap(disp, RootWindow(disp, screen), __evas_vi->visual, 0);
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
return cmap;
|
|
|
|
}
|
|
|
|
|
2000-08-01 20:33:11 -07:00
|
|
|
void
|
2000-09-15 08:04:48 -07:00
|
|
|
__evas_gl_init(Display *disp, int screen, int colors)
|
2000-08-01 20:33:11 -07:00
|
|
|
{
|
|
|
|
}
|
2000-08-05 17:26:34 -07:00
|
|
|
|
2000-08-05 21:53:53 -07:00
|
|
|
void
|
2000-09-13 15:36:46 -07:00
|
|
|
__evas_gl_draw_add_rect(Display *disp, Imlib_Image dstim, Window win,
|
2000-08-05 21:53:53 -07:00
|
|
|
int x, int y, int w, int h)
|
|
|
|
{
|
2000-12-27 12:51:39 -08:00
|
|
|
Evas_GL_Window *glw;
|
|
|
|
Evas_GL_Rect *rect;
|
|
|
|
|
|
|
|
glw = __evas_gl_window_lookup(disp, win);
|
|
|
|
if (!glw) return;
|
|
|
|
rect = malloc(sizeof(Evas_GL_Rect));
|
|
|
|
rect->x = x;
|
|
|
|
rect->y = y;
|
|
|
|
rect->w = w;
|
|
|
|
rect->h = h;
|
|
|
|
glw->updates = evas_list_append(glw->updates, rect);
|
2000-08-05 21:53:53 -07:00
|
|
|
}
|
|
|
|
|
2000-08-13 17:14:22 -07:00
|
|
|
#else
|
|
|
|
|
|
|
|
/***************/
|
|
|
|
/* image stuff */
|
|
|
|
/***************/
|
|
|
|
Evas_GL_Image *__evas_gl_image_new_from_file(Display *disp, char *file){return NULL;}
|
|
|
|
void __evas_gl_image_free(Evas_GL_Image *im){}
|
|
|
|
void __evas_gl_image_cache_empty(Display *disp){}
|
|
|
|
void __evas_gl_image_cache_set_size(Display *disp, int size){}
|
|
|
|
int __evas_gl_image_cache_get_size(Display *disp){return 0;}
|
|
|
|
int __evas_gl_image_get_width(Evas_GL_Image *im){return 0;}
|
|
|
|
int __evas_gl_image_get_height(Evas_GL_Image *im){return 0;}
|
|
|
|
void __evas_gl_image_set_borders(Evas_GL_Image *im, int left, int right, int top, int bottom){}
|
|
|
|
void __evas_gl_image_set_smooth_scaling(int on){}
|
2000-09-23 08:03:39 -07:00
|
|
|
void __evas_gl_image_draw(Evas_GL_Image *im, Display *disp, Imlib_Image dstim, Window w, int win_w, int win_h, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int cr, int cg, int cb, int ca){}
|
2000-08-13 17:14:22 -07:00
|
|
|
|
|
|
|
/********/
|
|
|
|
/* text */
|
|
|
|
/********/
|
|
|
|
Evas_GL_Font *__evas_gl_text_font_new(Display *disp, char *font, int size){return NULL;}
|
|
|
|
void __evas_gl_text_font_free(Evas_GL_Font *fn){}
|
|
|
|
void __evas_gl_text_font_add_path(char *path){}
|
2000-10-12 14:04:13 -07:00
|
|
|
int __evas_gl_text_font_get_ascent(Evas_GL_Font *fn){return 0;}
|
|
|
|
int __evas_gl_text_font_get_descent(Evas_GL_Font *fn){return 0;}
|
|
|
|
int __evas_gl_text_font_get_max_ascent(Evas_GL_Font *fn){return 0;}
|
|
|
|
int __evas_gl_text_font_get_max_descent(Evas_GL_Font *fn){return 0;}
|
|
|
|
void __evas_gl_text_font_get_advances(Evas_GL_Font *fn, char *text, int *advance_horiz, int *advance_vert){}
|
|
|
|
int __evas_gl_text_font_get_first_inset(Evas_GL_Font *fn, char *text){return 0;}
|
2000-08-13 17:14:22 -07:00
|
|
|
void __evas_gl_text_font_del_path(char *path){}
|
|
|
|
char **__evas_gl_text_font_list_paths(int *count){return NULL;}
|
|
|
|
void __evas_gl_text_cache_empty(Display *disp){}
|
|
|
|
void __evas_gl_text_cache_set_size(Display *disp, int size){}
|
|
|
|
int __evas_gl_text_cache_get_size(Display *disp){return 0;}
|
|
|
|
void __evas_gl_text_get_size(Evas_GL_Font *fn, char *text, int *w, int *h){}
|
|
|
|
int __evas_gl_text_get_character_at_pos(Evas_GL_Font *fn, char *text, int x, int y, int *cx, int *cy, int *cw, int *ch){return 0;}
|
|
|
|
void __evas_gl_text_get_character_number(Evas_GL_Font *fn, char *text, int num, int *cx, int *cy, int *cw, int *ch){}
|
2000-09-13 15:36:46 -07:00
|
|
|
void __evas_gl_text_draw(Evas_GL_Font *fn, Display *disp, Imlib_Image dstim, Window win, int win_w, int win_h, int x, int y, char *text, int r, int g, int b, int a){}
|
2000-08-13 17:14:22 -07:00
|
|
|
|
|
|
|
/**************/
|
|
|
|
/* rectangles */
|
|
|
|
/**************/
|
2000-09-13 15:36:46 -07:00
|
|
|
void __evas_gl_rectangle_draw(Display *disp, Imlib_Image dstim, Window win, int win_w, int win_h, int x, int y, int w, int h, int r, int g, int b, int a){}
|
2000-08-13 17:14:22 -07:00
|
|
|
|
|
|
|
/*********/
|
|
|
|
/* lines */
|
|
|
|
/*********/
|
2000-09-13 15:36:46 -07:00
|
|
|
void __evas_gl_line_draw(Display *disp, Imlib_Image dstim, Window win, int win_w, int win_h, int x1, int y1, int x2, int y2, int r, int g, int b, int a){}
|
2000-08-13 17:14:22 -07:00
|
|
|
|
|
|
|
/*************/
|
|
|
|
/* gradients */
|
|
|
|
/*************/
|
|
|
|
Evas_GL_Graident *__evas_gl_gradient_new(Display *disp){return NULL;}
|
|
|
|
void __evas_gl_gradient_free(Evas_GL_Graident *gr){}
|
|
|
|
void __evas_gl_gradient_color_add(Evas_GL_Graident *gr, int r, int g, int b, int a, int dist){}
|
2000-09-13 15:36:46 -07:00
|
|
|
void __evas_gl_gradient_draw(Evas_GL_Graident *gr, Display *disp, Imlib_Image dstim, Window win, int win_w, int win_h, int x, int y, int w, int h, double angle){}
|
2000-08-13 17:14:22 -07:00
|
|
|
|
2000-10-11 17:26:34 -07:00
|
|
|
/************/
|
|
|
|
/* polygons */
|
|
|
|
/************/
|
|
|
|
void __evas_gl_poly_draw (Display *disp, Imlib_Image dstim, Window win, int win_w, int win_h, Evas_List points, int r, int g, int b, int a) {}
|
|
|
|
|
2000-08-13 17:14:22 -07:00
|
|
|
/***********/
|
|
|
|
/* drawing */
|
|
|
|
/***********/
|
2000-09-23 08:03:39 -07:00
|
|
|
void __evas_gl_init(Display *disp, int screen, int colors){}
|
2000-08-13 17:14:22 -07:00
|
|
|
int __evas_gl_capable(Display *disp){return 0;}
|
2000-09-13 15:36:46 -07:00
|
|
|
void __evas_gl_flush_draw(Display *disp, Imlib_Image dstim, Window win){}
|
2000-08-13 17:14:22 -07:00
|
|
|
void __evas_gl_sync(Display *disp){}
|
|
|
|
Visual *__evas_gl_get_visual(Display *disp, int screen){return NULL;}
|
|
|
|
XVisualInfo *__evas_gl_get_visual_info(Display *disp, int screen){return NULL;}
|
|
|
|
Colormap __evas_gl_get_colormap(Display *disp, int screen){return 0;}
|
2000-09-13 15:36:46 -07:00
|
|
|
void __evas_gl_draw_add_rect(Display *disp, Imlib_Image dstim, Window win, int x, int y, int w, int h){}
|
2000-08-13 17:14:22 -07:00
|
|
|
|
|
|
|
#endif
|