evas: handle orientation while an object is cutout.

T2338

Thanks to DaveMDS to take the time to report accurately the issue. That helped
a lot figuring out things. And another thanks to Vincent Torri for the help on
the math side.
This commit is contained in:
Cedric BAIL 2015-05-05 10:15:02 +02:00
parent 8a7b73ccbc
commit 66a2f71c1a
1 changed files with 156 additions and 66 deletions

View File

@ -1256,54 +1256,13 @@ evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc,
PUSH_VERTEX(pn, x , y + h, 0); PUSH_VERTEX(pn, x + w, y , 0); \
PUSH_VERTEX(pn, x + w, y + h, 0); PUSH_VERTEX(pn, x , y + h, 0); \
} while (0)
#define PUSH_6_TEXUV(pn, Tex, x1, y1, x2, y2) do { \
Evas_GL_Texture *_tex = Tex; \
if (_tex && _tex->im) \
{ \
switch (_tex->im->orient) \
{ \
case EVAS_IMAGE_ORIENT_NONE: \
PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x1, y2); \
PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x1, y2); \
break; \
case EVAS_IMAGE_ORIENT_90: \
PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y2); \
PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x2, y2); \
break; \
case EVAS_IMAGE_ORIENT_180: \
PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x2, y1); \
PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y1); \
break; \
case EVAS_IMAGE_ORIENT_270: \
PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x1, y1); \
PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x1, y1); \
break; \
case EVAS_IMAGE_FLIP_HORIZONTAL: \
PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y2); \
PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x2, y2); \
break; \
case EVAS_IMAGE_FLIP_VERTICAL: \
PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x1, y1); \
PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x1, y1); \
break; \
case EVAS_IMAGE_FLIP_TRANSVERSE: \
PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x1, y2); \
PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x1, y2); \
break; \
case EVAS_IMAGE_FLIP_TRANSPOSE: \
PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x2, y1); \
PUSH_TEXUV(pn, x1, y2); PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x2, y1); \
break; \
default: \
ERR("Wrong orientation"); \
} \
} \
else \
{ \
PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x1, y2); \
PUSH_TEXUV(pn, x2, y1); PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x1, y2); \
} \
} while (0)
#define PUSH_6_QUAD(pn, x1, y1, x2, y2, x3, y3, x4, y4) \
PUSH_TEXUV(pn, x1, y1); PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x4, y4);\
PUSH_TEXUV(pn, x2, y2); PUSH_TEXUV(pn, x3, y3); PUSH_TEXUV(pn, x4, y4);
#define PUSH_6_TEXUV(pn, x1, y1, x2, y2) \
PUSH_6_QUAD(pn, x1, y1, x2, y1, x2, y2, x1, y2);
#define PUSH_6_TEXUV2(pn, x1, y1, x2, y2) do { \
PUSH_TEXUV2(pn, x1, y1); PUSH_TEXUV2(pn, x2, y1); PUSH_TEXUV2(pn, x1, y2); \
PUSH_TEXUV2(pn, x2, y1); PUSH_TEXUV2(pn, x2, y2); PUSH_TEXUV2(pn, x1, y2); \
@ -1950,6 +1909,73 @@ again:
PUSH_6_COLORS(pn, r, g, b, a);
}
static void
_rotate_point_90(double *x, double *y, double w, double h)
{
double tx, ty, t;
tx = *x - w / 2;
ty = *y - h / 2;
t = tx;
tx = ty;
ty = t;
tx = tx + h / 2;
ty = ty + w / 2;
*x = tx * h / w;
*y = w - ty * w / h;
}
static void
_rotate_point_180(double *x, double *y, double w, double h)
{
double tx, ty;
tx = *x - w / 2;
ty = *y - h / 2;
tx = -tx;
ty = -ty;
tx = tx + w / 2;
ty = ty + h / 2;
*x = tx;
*y = ty;
}
static void
_rotate_point_270(double *x, double *y, double w, double h)
{
double tx, ty, t;
tx = *x - h / 2;
ty = *y - w / 2;
t = tx;
tx = ty;
ty = t;
tx = tx + w / 2;
ty = ty + h / 2;
*x = h - tx * h / w;
*y = ty * w / h;
}
static void
_transpose(double *x, double *y, double w, double h)
{
double t;
t = *x;
*x = *y * h / w;
*y = t * w / h;
}
static void
_transverse(double *x, double *y, double w, double h)
{
double t;
t = *x;
*x = (w - *y) * h / w;
*y = (h - t) * w / h;
}
void
evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
@ -1960,7 +1986,8 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
Eina_Bool smooth, Eina_Bool tex_only)
{
Evas_GL_Texture_Pool *pt;
GLfloat tx1, tx2, ty1, ty2;
double ox1, oy1, ox2, oy2, ox3, oy3, ox4, oy4;
GLfloat tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4;
GLfloat offsetx, offsety;
double pw, ph;
Eina_Bool blend = EINA_FALSE;
@ -2050,23 +2077,86 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
ph = pt->w;
}
ox1 = sx;
oy1 = sy;
ox2 = sx + sw;
oy2 = sy;
ox3 = sx + sw;
oy3 = sy + sh;
ox4 = sx;
oy4 = sy + sh;
if (tex->im)
{
switch (tex->im->orient)
{
case EVAS_IMAGE_ORIENT_NONE:
break;
case EVAS_IMAGE_ORIENT_90:
_rotate_point_90(&ox1, &oy1, tex->im->w, tex->im->h);
_rotate_point_90(&ox2, &oy2, tex->im->w, tex->im->h);
_rotate_point_90(&ox3, &oy3, tex->im->w, tex->im->h);
_rotate_point_90(&ox4, &oy4, tex->im->w, tex->im->h);
break;
case EVAS_IMAGE_ORIENT_180:
_rotate_point_180(&ox1, &oy1, tex->im->w, tex->im->h);
_rotate_point_180(&ox2, &oy2, tex->im->w, tex->im->h);
_rotate_point_180(&ox3, &oy3, tex->im->w, tex->im->h);
_rotate_point_180(&ox4, &oy4, tex->im->w, tex->im->h);
break;
case EVAS_IMAGE_ORIENT_270:
_rotate_point_270(&ox1, &oy1, tex->im->w, tex->im->h);
_rotate_point_270(&ox2, &oy2, tex->im->w, tex->im->h);
_rotate_point_270(&ox3, &oy3, tex->im->w, tex->im->h);
_rotate_point_270(&ox4, &oy4, tex->im->w, tex->im->h);
break;
case EVAS_IMAGE_FLIP_HORIZONTAL:
ox1 = tex->im->w - ox1;
ox2 = tex->im->w - ox2;
ox3 = tex->im->w - ox3;
ox4 = tex->im->w - ox4;
break;
case EVAS_IMAGE_FLIP_VERTICAL:
oy1 = tex->im->h - oy1;
oy2 = tex->im->h - oy2;
oy3 = tex->im->h - oy3;
oy4 = tex->im->h - oy4;
break;
case EVAS_IMAGE_FLIP_TRANSVERSE:
_transverse(&ox1, &oy1, tex->im->w, tex->im->h);
_transverse(&ox2, &oy2, tex->im->w, tex->im->h);
_transverse(&ox3, &oy3, tex->im->w, tex->im->h);
_transverse(&ox4, &oy4, tex->im->w, tex->im->h);
break;
case EVAS_IMAGE_FLIP_TRANSPOSE:
_transpose(&ox1, &oy1, tex->im->w, tex->im->h);
_transpose(&ox2, &oy2, tex->im->w, tex->im->h);
_transpose(&ox3, &oy3, tex->im->w, tex->im->h);
_transpose(&ox4, &oy4, tex->im->w, tex->im->h);
break;
default:
ERR("Wrong orientation ! %i", tex->im->orient);
}
}
tx1 = ((double)(offsetx) + ox1) / pw;
ty1 = ((double)(offsety) + oy1) / ph;
tx2 = ((double)(offsetx) + ox2) / pw;
ty2 = ((double)(offsety) + oy2) / ph;
tx3 = ((double)(offsetx) + ox3) / pw;
ty3 = ((double)(offsety) + oy3) / ph;
tx4 = ((double)(offsetx) + ox4) / pw;
ty4 = ((double)(offsety) + oy4) / ph;
if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
{
tx1 = ((double)(offsetx) + sx) / pw;
ty1 = 1.0 - ((double)(offsety) + sy) / ph;
tx2 = ((double)(offsetx) + sx + sw) / pw;
ty2 = 1.0 - ((double)(offsety) + sy + sh) / ph;
}
else
{
tx1 = ((double)(offsetx) + sx) / pw;
ty1 = ((double)(offsety) + sy) / ph;
tx2 = ((double)(offsetx) + sx + sw) / pw;
ty2 = ((double)(offsety) + sy + sh) / ph;
ty1 = 1.0 - ty1;
ty2 = 1.0 - ty2;
ty3 = 1.0 - ty3;
ty4 = 1.0 - ty4;
}
PUSH_6_VERTICES(pn, x, y, w, h);
PUSH_6_TEXUV(pn, tex, tx1, ty1, tx2, ty2);
PUSH_6_QUAD(pn, tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4);
if (sam)
{
@ -2156,7 +2246,7 @@ evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
}
PUSH_6_VERTICES(pn, x, y, w, h);
PUSH_6_TEXUV(pn, NULL, tx1, ty1, tx2, ty2);
PUSH_6_TEXUV(pn, tx1, ty1, tx2, ty2);
PUSH_MASK(pn, mtex, mx, my, mw, mh);
PUSH_6_COLORS(pn, r, g, b, a);
}
@ -2232,7 +2322,7 @@ evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
t2y2 = ((sy + sh) / 2) / (double)tex->ptu->h;
PUSH_6_VERTICES(pn, x, y, w, h);
PUSH_6_TEXUV(pn, NULL, tx1, ty1, tx2, ty2);
PUSH_6_TEXUV(pn, tx1, ty1, tx2, ty2);
PUSH_6_TEXUV2(pn, t2x1, t2y1, t2x2, t2y2);
PUSH_6_TEXUV3(pn, t2x1, t2y1, t2x2, t2y2);
PUSH_MASK(pn, mtex, mx, my, mw, mh);
@ -2310,7 +2400,7 @@ evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
t2y2 = (sy + sh) / (double)tex->ptuv->h;
PUSH_6_VERTICES(pn, x, y, w, h);
PUSH_6_TEXUV(pn, NULL, tx1, ty1, tx2, ty2);
PUSH_6_TEXUV(pn, tx1, ty1, tx2, ty2);
PUSH_6_TEXUV2(pn, t2x1, t2y1, t2x2, t2y2);
PUSH_MASK(pn, mtex, mx, my, mw, mh);
if (!nomul)
@ -2390,7 +2480,7 @@ evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
t2y2 = (sy + sh) / (double)tex->ptuv->h;
PUSH_6_VERTICES(pn, x, y, w, h);
PUSH_6_TEXUV(pn, NULL, tx1, ty1, tx2, ty2);
PUSH_6_TEXUV(pn, tx1, ty1, tx2, ty2);
PUSH_6_TEXUV2(pn, t2x1, t2y1, t2x2, t2y2);
PUSH_MASK(pn, mtex, mx, my, mw, mh);
if (!nomul)
@ -2474,7 +2564,7 @@ evas_gl_common_context_rgb_a_pair_push(Evas_Engine_GL_Context *gc,
t2y2 = (tex->y + sy + sh) / (double)tex->pta->h;
PUSH_6_VERTICES(pn, x, y, w, h);
PUSH_6_TEXUV(pn, NULL, tx1, ty1, tx2, ty2);
PUSH_6_TEXUV(pn, tx1, ty1, tx2, ty2);
PUSH_6_TEXA(pn, t2x1, t2y1, t2x2, t2y2);
PUSH_MASK(pn, mtex, mx, my, mw, mh);
if (!nomul)