cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=66a2f71c1a7bc657e5b3b695111117bad0f86248
commit 66a2f71c1a7bc657e5b3b695111117bad0f86248 Author: Cedric BAIL <ced...@osg.samsung.com> Date: Tue May 5 10:15:02 2015 +0200 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. --- .../evas/engines/gl_common/evas_gl_context.c | 220 +++++++++++++++------ 1 file changed, 155 insertions(+), 65 deletions(-) diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c b/src/modules/evas/engines/gl_common/evas_gl_context.c index b526eab..97d5c32 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_context.c +++ b/src/modules/evas/engines/gl_common/evas_gl_context.c @@ -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; } - if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert)) + ox1 = sx; + oy1 = sy; + ox2 = sx + sw; + oy2 = sy; + ox3 = sx + sw; + oy3 = sy + sh; + ox4 = sx; + oy4 = sy + sh; + + if (tex->im) { - 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; + 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); + } } - else + + 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 = ((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) --