From 801bdf34d8c8420029c953148b92cd3b7892b837 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Thu, 5 Oct 2006 05:28:35 +0000 Subject: [PATCH] joses fixes for grads with premul SVN revision: 26348 --- .../src/lib/canvas/evas_object_gradient.c | 6 +- .../lib/engines/common/evas_gradient_linear.c | 2 +- .../common/evas_scale_smooth_scaler_up.c | 10 +- .../engines/xrender_x11/evas_engine_xrender.c | 107 +++++++++++++----- 4 files changed, 89 insertions(+), 36 deletions(-) diff --git a/legacy/evas/src/lib/canvas/evas_object_gradient.c b/legacy/evas/src/lib/canvas/evas_object_gradient.c index 3d834d3ed8..0d7b191841 100644 --- a/legacy/evas/src/lib/canvas/evas_object_gradient.c +++ b/legacy/evas/src/lib/canvas/evas_object_gradient.c @@ -923,14 +923,14 @@ evas_object_gradient_render_pre(Evas_Object *obj) (obj->cur.color.g != obj->prev.color.g) || (obj->cur.color.b != obj->prev.color.b) || (obj->cur.color.a != obj->prev.color.a)) - o->gradient_changed = 1; + { o->gradient_changed = 1; o->changed = 1; } if ((!o->gradient_changed) && ((obj->cur.cache.clip.r != obj->prev.cache.clip.r) || (obj->cur.cache.clip.g != obj->prev.cache.clip.g) || (obj->cur.cache.clip.b != obj->prev.cache.clip.b) || (obj->cur.cache.clip.a != obj->prev.cache.clip.a))) - o->gradient_changed = 1; + { o->gradient_changed = 1; o->changed = 1; } if (!o->gradient_changed && (obj->cur.interpolation.color_space != obj->prev.interpolation.color_space)) - o->gradient_changed = 1; + { o->gradient_changed = 1; o->changed = 1; } if (!o->changed && (obj->cur.render_op != obj->prev.render_op)) o->changed = 1; if (!o->changed && (obj->cur.anti_alias != obj->prev.anti_alias)) diff --git a/legacy/evas/src/lib/engines/common/evas_gradient_linear.c b/legacy/evas/src/lib/engines/common/evas_gradient_linear.c index 09dbcdcc8c..ca3e4775b3 100644 --- a/legacy/evas/src/lib/engines/common/evas_gradient_linear.c +++ b/legacy/evas/src/lib/engines/common/evas_gradient_linear.c @@ -384,7 +384,7 @@ linear_get_fill_func(RGBA_Gradient *gr, int op, unsigned char aa) #endif #define AXIS_ALIGNED \ - ( ((ayy == 0) || (ayx == 0)) && ((gdata->ca == 0.0) || (gdata->sa = 0.0)) ) + ( ((ayy == 0) || (ayx == 0)) && ((gdata->ca == 0.0) || (gdata->sa == 0.0)) ) #define SETUP_LINEAR_FILL \ if (gdata->at_angle) \ diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_up.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_up.c index 0972239bfe..91cf4c1c3c 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_up.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_up.c @@ -41,8 +41,14 @@ else buf = pdst; - dsxx = (((srw == 1) ? (1 << 16) : ((srw - 1) << 16))) / ((drw == 1) ? 1 : (drw - 1)); - dsyy = (((srh == 1) ? (1 << 16) : ((srh - 1) << 16))) / ((drh == 1) ? 1 : (drh - 1)); + if ((srw > 1) && (drw > 1)) + dsxx = ((srw - 1) << 16) / (drw - 1); + else + dsxx = (srw << 16) / drw; + if ((srh > 1) && (drh > 1)) + dsyy = ((srh - 1) << 16) / (drh - 1); + else + dsyy = (srh << 16) / drh; cx = dst_clip_x - drx; cy = dst_clip_y - dry; diff --git a/legacy/evas/src/modules/engines/xrender_x11/evas_engine_xrender.c b/legacy/evas/src/modules/engines/xrender_x11/evas_engine_xrender.c index 031e2a2a93..8a9e5c7663 100644 --- a/legacy/evas/src/modules/engines/xrender_x11/evas_engine_xrender.c +++ b/legacy/evas/src/modules/engines/xrender_x11/evas_engine_xrender.c @@ -2,7 +2,7 @@ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 */ #include "evas_common.h" -#include "evas_macros.h" +//#include "evas_macros.h" #include "evas_private.h" #include "evas_engine.h" #include "Evas_Engine_XRender_X11.h" @@ -307,7 +307,8 @@ _xr_render_surface_clips_set(Xrender_Surface *rs, RGBA_Draw_Context *dc, int rx, } /* initialized the transform to the identity */ -static void init_transform (XTransform *t) +static void +init_xtransform(XTransform *t) { int i, j; @@ -316,6 +317,16 @@ static void init_transform (XTransform *t) t->matrix[i][j] = XDoubleToFixed((i == j) ? 1 : 0); } +static void +set_xtransform_scale(XTransform *t, int sw, int sh, int w, int h) +{ + if ((sw > 1) && (w > 1)) + { sw--; w--; } + if ((sh > 1) && (h > 1)) + { sh--; h--; } + t->matrix[0][0] = XDoubleToFixed((double)sw / (double)w); + t->matrix[1][1] = XDoubleToFixed((double)sh / (double)h); +} // when color multiplier is used want: instead // CA src IN mask SRC temp; non-CA temp OVER dst. - i think. need to check. @@ -325,29 +336,45 @@ _xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Dr Xrender_Surface *trs = NULL; XTransform xf; XRenderPictureAttributes att; - Picture mask; - int r, g, b, a, op; - int e, is_scaling; + Picture mask = None; + int e, is_scaling, op; if ((sw <= 0) || (sh <= 0) || (w <= 0) || (h <= 0)) return; - is_scaling = (sw != w) || (sh != h); - e = is_scaling ? 0 : 1; + is_scaling = e = ((sw != w) || (sh != h)); att.clip_mask = None; XRenderChangePicture(srs->xinf->disp, srs->pic, CPClipMask, &att); - XRenderChangePicture(srs->xinf->disp, drs->pic, CPClipMask, &att); + XRenderChangePicture(drs->xinf->disp, drs->pic, CPClipMask, &att); - op = PictOpSrc; - if (srs->alpha) op = PictOpOver; - mask = None; + init_xtransform(&xf); + + op = PictOpOver; + if (dc->render_op == _EVAS_RENDER_BLEND) + { + if (!srs->alpha) op = PictOpSrc; + } + else if (dc->render_op == _EVAS_RENDER_BLEND_REL) + op = PictOpAtop; + else if (dc->render_op == _EVAS_RENDER_MUL) + op = PictOpIn; + else if (dc->render_op == _EVAS_RENDER_COPY) + op = PictOpSrc; + else if (dc->render_op == _EVAS_RENDER_COPY_REL) + op = PictOpIn; + else if (dc->render_op == _EVAS_RENDER_MASK) + op = PictOpInReverse; + if ((dc) && (dc->mul.use)) { - r = (int)(R_VAL(&dc->mul.col)); - g = (int)(G_VAL(&dc->mul.col)); - b = (int)(B_VAL(&dc->mul.col)); - a = (int)(A_VAL(&dc->mul.col)); - if ((r != 0xff) || (g != 0xff) || (b != 0xff) || (a != 0xff)) + int r, g, b, a; + + if ((op == PictOpOver) && (!dc->mul.col)) return; + a = dc->mul.col >> 24; + r = (dc->mul.col >> 16) & 0xff; + g = (dc->mul.col >> 8) & 0xff; + b = dc->mul.col & 0xff; + if (dc->mul.col != 0xffffffff) { if ((srs->xinf->mul_r != r) || (srs->xinf->mul_g != g) || (srs->xinf->mul_b != b) || (srs->xinf->mul_a != a)) @@ -360,9 +387,8 @@ _xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Dr r, g, b, a, 0, 0, 1, 1); } - op = PictOpOver; mask = srs->xinf->mul->pic; - if ((r == 0xff) && (g == 0xff) && (b == 0xff) && (a != 0xff)) + if (dc->mul.col == (a * 0x01010101)) { att.component_alpha = 0; XRenderChangePicture(srs->xinf->disp, mask, CPComponentAlpha, &att); @@ -379,6 +405,7 @@ _xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Dr att.component_alpha = 1; XRenderChangePicture(srs->xinf->disp, mask, CPComponentAlpha, &att); + XRenderSetPictureTransform(srs->xinf->disp, srs->pic, &xf); XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, mask, trs->pic, sx, sy, 0, 0, 0, 0, sw, sh); /* fill right and bottom pixel so interpolation works right */ @@ -396,18 +423,19 @@ _xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Dr } } - init_transform(&xf); - xf.matrix[0][0] = XDoubleToFixed((double) sw / (double) w); - xf.matrix[1][1] = XDoubleToFixed((double) sh / (double) h); - _xr_render_surface_clips_set(drs, dc, x, y, w, h); if (trs) { - if (is_scaling) - XRenderSetPictureFilter(trs->xinf->disp, trs->pic, get_filter(smooth), NULL, 0); + XRenderSetPictureFilter(trs->xinf->disp, trs->pic, get_filter(smooth), NULL, 0); + set_xtransform_scale(&xf, sw, sh, w, h); XRenderSetPictureTransform(trs->xinf->disp, trs->pic, &xf); - + + att.component_alpha = 0; + if (dc->render_op == _EVAS_RENDER_MUL) + att.component_alpha = 1; + XRenderChangePicture(trs->xinf->disp, trs->pic, CPComponentAlpha, &att); + XRenderComposite(trs->xinf->disp, op, trs->pic, mask, drs->pic, 0, 0, 0, 0, x, y, w, h); _xr_render_surface_free(trs); @@ -420,8 +448,12 @@ _xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Dr srs->fmt, srs->alpha); if (!trs) return; + att.component_alpha = 0; + XRenderChangePicture(srs->xinf->disp, srs->pic, CPComponentAlpha, &att); + XRenderSetPictureTransform(srs->xinf->disp, srs->pic, &xf); XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, None, trs->pic, sx, sy, 0, 0, 0, 0, sw, sh); + XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, None, trs->pic, sx + sw - 1, sy, 0, 0, sw, 0, 1, sh); XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, None, @@ -431,17 +463,31 @@ _xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Dr XRenderSetPictureFilter(trs->xinf->disp, trs->pic, get_filter(smooth), NULL, 0); + set_xtransform_scale(&xf, sw, sh, w, h); XRenderSetPictureTransform(trs->xinf->disp, trs->pic, &xf); + + if (dc->render_op == _EVAS_RENDER_MUL) + { + att.component_alpha = 1; + XRenderChangePicture(trs->xinf->disp, trs->pic, CPComponentAlpha, &att); + } + XRenderComposite(trs->xinf->disp, op, trs->pic, mask, drs->pic, 0, 0, 0, 0, x, y, w, h); _xr_render_surface_free(trs); } else { - if (is_scaling) - XRenderSetPictureFilter(srs->xinf->disp, srs->pic, get_filter(smooth), NULL, 0); + XRenderSetPictureFilter(srs->xinf->disp, srs->pic, get_filter(smooth), NULL, 0); + set_xtransform_scale(&xf, sw, sh, w, h); XRenderSetPictureTransform(srs->xinf->disp, srs->pic, &xf); + + att.component_alpha = 0; + if (dc->render_op == _EVAS_RENDER_MUL) + att.component_alpha = 1; + XRenderChangePicture(srs->xinf->disp, srs->pic, CPComponentAlpha, &att); + XRenderComposite(srs->xinf->disp, op, srs->pic, mask, drs->pic, ((sx * w) + (sw / 2)) / sw, ((sy * h) + (sh / 2)) / sh, @@ -458,21 +504,22 @@ _xr_render_surface_copy(Xrender_Surface *srs, Xrender_Surface *drs, int sx, int if ((w <= 0) || (h <= 0) || (!srs) || (!drs)) return; + init_xtransform(&xf); #ifdef BROKEN_XORG_XRENDER /* FIXME: why do we need to change the identity matrix ifthe src surface * is 1 bit deep? */ if (srs->depth == 1) { - init_transform(&xf); xf.matrix[0][0] = xf.matrix[1][1] = xf.matrix[2][2] = 1; - XRenderSetPictureTransform(srs->xinf->disp, srs->pic, &xf); } #endif + XRenderSetPictureTransform(srs->xinf->disp, srs->pic, &xf); +// XRenderSetPictureFilter(srs->xinf->disp, srs->pic, FilterNearest, NULL, 0); att.clip_mask = None; XRenderChangePicture(srs->xinf->disp, srs->pic, CPClipMask, &att); - XRenderChangePicture(srs->xinf->disp, drs->pic, CPClipMask, &att); + XRenderChangePicture(drs->xinf->disp, drs->pic, CPClipMask, &att); XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, None, drs->pic, sx, sy, 0, 0, x, y, w, h);