From 1b272aec90c2b03b4df3906c261bca4917f42cde Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sat, 3 Dec 2005 09:27:53 +0000 Subject: [PATCH] joses's gradient work - gradient look nice. one problem jose.. USE BRACKETS! do NOT depend on order operation precedence. it broke scaling. laos other completely bizarre mmx things were going wrong with mm7 ending up not 0 so i've had to force it to be 0. SVN revision: 18811 --- legacy/evas/src/bin/evas_test_main.c | 224 ++- legacy/evas/src/lib/Evas.h | 26 + legacy/evas/src/lib/canvas/evas_main.c | 9 +- .../src/lib/canvas/evas_object_gradient.c | 456 ++++- legacy/evas/src/lib/canvas/evas_object_main.c | 72 + legacy/evas/src/lib/canvas/evas_render.c | 52 +- .../evas/src/lib/engines/buffer/evas_engine.c | 148 +- .../src/lib/engines/cairo_x11/evas_engine.c | 116 +- .../evas/src/lib/engines/common/Makefile.am | 5 + .../common/evas_blend_alpha_color_pixel.c | 703 +++++-- .../engines/common/evas_blend_color_pixel.c | 381 ++-- .../src/lib/engines/common/evas_blend_main.c | 13 + .../common/evas_blend_pixel_mul_pixel.c | 1757 +++++++++++++++-- .../engines/common/evas_blend_pixel_pixel.c | 675 ++++--- .../src/lib/engines/common/evas_draw_main.c | 364 +--- .../src/lib/engines/common/evas_font_draw.c | 2 +- .../engines/common/evas_gradient_angular.c | 764 +++++++ .../lib/engines/common/evas_gradient_linear.c | 582 ++++++ .../lib/engines/common/evas_gradient_main.c | 889 +++++++-- .../lib/engines/common/evas_gradient_radial.c | 453 +++++ .../common/evas_gradient_rectangular.c | 483 +++++ .../engines/common/evas_gradient_sinusoidal.c | 342 ++++ .../src/lib/engines/common/evas_image_main.c | 60 +- .../lib/engines/common/evas_scale_smooth.c | 8 +- .../engines/common/evas_scale_smooth_scaler.c | 74 +- .../common/evas_scale_smooth_scaler_down.c | 53 +- .../common/evas_scale_smooth_scaler_downx.c | 125 +- .../evas_scale_smooth_scaler_downx_downy.c | 117 +- .../common/evas_scale_smooth_scaler_downy.c | 143 +- .../common/evas_scale_smooth_scaler_noscale.c | 11 +- .../common/evas_scale_smooth_scaler_up.c | 561 ++++-- .../lib/engines/directfb/evas_engine_dfb.c | 120 +- .../lib/engines/directfb/evas_engine_dfb.h | 14 +- legacy/evas/src/lib/engines/fb/evas_engine.c | 142 +- .../lib/engines/gl_common/evas_gl_gradient.c | 78 +- .../evas/src/lib/engines/gl_x11/evas_engine.c | 127 +- .../lib/engines/software_qtopia/evas_engine.c | 133 +- .../lib/engines/software_x11/evas_engine.c | 133 +- .../lib/engines/software_xcb/evas_engine.c | 133 +- .../src/lib/engines/xrender_x11/evas_engine.c | 126 +- .../src/lib/engines/xrender_x11/evas_engine.h | 11 +- .../xrender_x11/evas_engine_gradient.c | 80 +- .../engines/xrender_x11/evas_engine_xrender.c | 44 +- legacy/evas/src/lib/include/evas_common.h | 92 +- legacy/evas/src/lib/include/evas_gl_common.h | 10 +- legacy/evas/src/lib/include/evas_private.h | 18 +- 46 files changed, 9069 insertions(+), 1860 deletions(-) create mode 100644 legacy/evas/src/lib/engines/common/evas_gradient_angular.c create mode 100644 legacy/evas/src/lib/engines/common/evas_gradient_linear.c create mode 100644 legacy/evas/src/lib/engines/common/evas_gradient_radial.c create mode 100644 legacy/evas/src/lib/engines/common/evas_gradient_rectangular.c create mode 100644 legacy/evas/src/lib/engines/common/evas_gradient_sinusoidal.c diff --git a/legacy/evas/src/bin/evas_test_main.c b/legacy/evas/src/bin/evas_test_main.c index e5991ea6b8..7c7d153595 100644 --- a/legacy/evas/src/bin/evas_test_main.c +++ b/legacy/evas/src/bin/evas_test_main.c @@ -282,14 +282,16 @@ loop(void) evas_object_image_size_get(p_i[i], &iw, &ih); v = (((t - 6.0) / 10.0) * EVAS_PI * 2) * 2; - x = cos(v * (double)(i + 1) * 3) * ((240 - iw) / 2); - y = sin(v * (double)(i + 1) * 2) * ((240 - ih) / 2); +#define MULTI 1.0 + x = cos(v * MULTI * (double)(i + 1) * 3) * ((240 - iw) / 2); + y = sin(v * MULTI * (double)(i + 1) * 2) * ((240 - ih) / 2); evas_object_move(p_i[i], 120 + x - 80, win_h - 120 + y - 80); v = (((t - 6.0) / 35.0) * EVAS_PI * 2) * 2; - x = (cos(v * (double)(i + 1) * 7) * iw) + iw; - y = (sin(v * (double)(i + 1) * 6) * ih) + ih; + x = (cos(v * MULTI * (double)(i + 1) * 7) * iw) + iw; + y = (sin(v * MULTI * (double)(i + 1) * 6) * ih) + ih; evas_object_resize(p_i[i], x, y); evas_object_image_fill_set(p_i[i], 0, 0, x, y); +// evas_object_hide(p_i[1]); } for (i = 0; i < 16; i++) { @@ -949,17 +951,18 @@ loop(void) if (!t1) { Evas_Object *ob; + float d = 128 * sqrt(2); evas_object_text_text_set(comment, "Destroy gradient blue, create red"); ob = evas_object_gradient_add(evas); + evas_object_gradient_color_add(ob, 255, 0, 0, 255, 1); evas_object_gradient_color_add(ob, 255, 0, 0, 0, 1); - evas_object_gradient_color_add(ob, 255, 255, 0, 255, 1); - evas_object_gradient_color_add(ob, 255, 255, 255, 255, 1); evas_object_gradient_angle_set(ob, 45.0); evas_object_move(ob, (win_w - 128) / 2, (win_h - 240) + ((240 - 128) / 2)); evas_object_resize(ob, 128, 128); + evas_object_gradient_fill_set(ob, 0, 127, d, d); evas_object_layer_set(ob, 5); evas_object_clip_set(ob, panel_clip); evas_object_show(ob); @@ -974,17 +977,18 @@ loop(void) if (!t2) { Evas_Object *ob; + float d = 128 * sqrt(2); evas_object_text_text_set(comment, "Destroy gradient red, create blue"); ob = evas_object_gradient_add(evas); + evas_object_gradient_color_add(ob, 0, 0, 255, 255, 1); evas_object_gradient_color_add(ob, 0, 0, 255, 0, 1); - evas_object_gradient_color_add(ob, 0, 255, 255, 255, 1); - evas_object_gradient_color_add(ob, 255, 255, 255, 255, 1); evas_object_gradient_angle_set(ob, 45.0); evas_object_move(ob, (win_w - 128) / 2, (win_h - 240) + ((240 - 128) / 2)); evas_object_resize(ob, 128, 128); + evas_object_gradient_fill_set(ob, 127, 0, d, d); evas_object_layer_set(ob, 5); evas_object_clip_set(ob, panel_clip); evas_object_show(ob); @@ -1540,16 +1544,17 @@ loop(void) if (!t1) { Evas_Object *ob; + int d = (120 / 2) * sqrt(2); ob = evas_object_gradient_add(evas); evas_object_gradient_color_add(ob, 255, 255, 255, 255, 1); - evas_object_gradient_color_add(ob, 250, 240, 50, 180, 1); - evas_object_gradient_color_add(ob, 220, 60, 0, 120, 1); - evas_object_gradient_color_add(ob, 200, 0, 0, 80, 1); - evas_object_gradient_color_add(ob, 0, 0, 0, 0, 0); + evas_object_gradient_color_add(ob, 250, 192, 64, 255, 1); + evas_object_gradient_color_add(ob, 220, 128, 0, 255, 1); + evas_object_gradient_color_add(ob, 200, 64, 0, 255, 1); evas_object_gradient_angle_set(ob, 45.0); evas_object_move(ob, 60, win_h - 240 + 60); evas_object_resize(ob, 120, 120); + evas_object_gradient_fill_set(ob, 0, 0, 120, d); evas_object_clip_set(ob, panel_clip); evas_object_layer_set(ob, 5); evas_object_show(ob); @@ -1583,6 +1588,8 @@ loop(void) y = sin(v * 1.9) * ((220) / 2); evas_object_move(t1, 10, win_h - 240 + 10); evas_object_resize(t1, x + 110, y + 110); +// evas_object_gradient_fill_set(t1, 0, 0, x + 110, y + 110); + evas_object_gradient_fill_set(t1, 0, 0, 110, 110); } } else if (t <= 369.0) @@ -1590,7 +1597,7 @@ loop(void) Evas_Coord tw, th; evas_object_text_text_set(comment, - "We can change gradient angle fills & resize"); + "We can change gradient angle & resize"); evas_object_text_text_set(title, "Test 30: Gradient angles"); evas_object_geometry_get(title, NULL, NULL, &tw, &th); evas_object_move(title, (win_w - tw) / 2, win_h - th); @@ -1602,6 +1609,8 @@ loop(void) x = cos(v * 1.7) * ((220) / 2); y = sin(v * 1.9) * ((220) / 2); evas_object_resize(t1, x + 110, y + 110); +// evas_object_gradient_fill_set(t1, 0, 0, x + 110, y + 110); + evas_object_gradient_fill_set(t1, 0, 0, 110, 110); evas_object_gradient_angle_set(t1, t * 60); } } @@ -1610,7 +1619,7 @@ loop(void) Evas_Coord tw, th; evas_object_text_text_set(comment, - "We can change color gradient, angle fill & resize"); + "We can change color gradient, angle & resize"); evas_object_text_text_set(title, "Test 31: Gradient Range"); evas_object_geometry_get(title, NULL, NULL, &tw, &th); evas_object_move(title, (win_w - tw) / 2, win_h - th); @@ -1622,6 +1631,7 @@ loop(void) x = cos(v * 1.7) * ((220) / 2); y = sin(v * 1.9) * ((220) / 2); evas_object_resize(t1, x + 110, y + 110); + evas_object_gradient_fill_set(t1, 0, 0, 110, 110); evas_object_gradient_angle_set(t1, t * 60); evas_object_gradient_colors_clear(t1); evas_object_gradient_color_add(t1, 255, 255, 255, 255, 1); @@ -1643,7 +1653,7 @@ loop(void) evas_object_gradient_color_add(t1, 0, 0, 0, 0, 0); } } - else if (t <= 369.0) /* FAIL! software_x11, fb */ + else if (t <= 389.0) { Evas_Coord tw, th; @@ -1660,6 +1670,7 @@ loop(void) x = cos(v * 1.7) * ((220) / 2); y = sin(v * 1.9) * ((220) / 2); evas_object_resize(t1, x + 110, y + 110); + evas_object_gradient_fill_set(t1, 0, 0, 110, 110); evas_object_gradient_angle_set(t1, t * 60); evas_object_gradient_colors_clear(t1); evas_object_gradient_color_add(t1, 255, 255, 255, 255, 1); @@ -1671,7 +1682,158 @@ loop(void) ((int)(t * 230)) & 0xff); } } - else if (t <= 390.0) + else if (t <= 409.0) + { + Evas_Coord tw, th; + + evas_object_text_text_set(comment, + "We can change the fill and spread of a gradient"); + evas_object_text_text_set(title, "Test 33: Gradient Object Fill and Spread"); + evas_object_geometry_get(title, NULL, NULL, &tw, &th); + evas_object_move(title, (win_w - tw) / 2, win_h - th); + { + Evas_Coord x, y; + double v, d = (160 * sqrt(2)) / 2; + + v = (((t - 6.0) / 10.0) * EVAS_PI * 2) * 2; +// x = cos(v * 1.7) * ((220) / 2); + y = sin(v * 0.5) * d; + evas_object_color_set(t1, 255, 255, 255, 255); + evas_object_resize(t1, 160, 160); + evas_object_move(t1, (win_w - 160) / 2, (win_h - 240) + ((240 - 160) / 2)); + evas_object_gradient_fill_set(t1, 0, 0, 55, y); + evas_object_gradient_angle_set(t1, 45.0); + evas_object_gradient_colors_clear(t1); + evas_object_gradient_color_add(t1, 255, 255, 255, 255, 2); + evas_object_gradient_color_add(t1, 250, 192, 64, 255, 1); + evas_object_gradient_color_add(t1, 220, 128, 0, 255, 1); + evas_object_gradient_color_add(t1, 200, 64, 0, 255, 1); + if (t <= 394.0) + evas_object_gradient_spread_set(t1, EVAS_TEXTURE_REFLECT); + else if (t <= 399.0) + evas_object_gradient_spread_set(t1, EVAS_TEXTURE_REPEAT); + else if (t <= 404.0) + evas_object_gradient_spread_set(t1, EVAS_TEXTURE_RESTRICT); + else + { + char s[32]; + + d = (0.6 * y) / 55; if (d < 0) d = -d; + memset(s,0,32); + sprintf(s, "extent = %f3.3;", d); + evas_object_gradient_type_set(t1, "linear", s); + evas_object_gradient_fill_set(t1, 90, 2, 55, 200); + evas_object_gradient_spread_set(t1, EVAS_TEXTURE_RESTRICT); + evas_object_gradient_angle_set(t1, 20.0); + evas_object_resize(t1, 160, 220); + evas_object_move(t1, (win_w - 160) / 2, (win_h - 240) + ((240 - 220) / 2)); + } + } + } + else if (t <= 419.0) + { + Evas_Coord tw, th; + + evas_object_text_text_set(comment, + "We can change the geometry of a gradient"); + evas_object_text_text_set(title, "Test 34: Gradient Object Radial"); + evas_object_geometry_get(title, NULL, NULL, &tw, &th); + evas_object_move(title, (win_w - tw) / 2, win_h - th); + { + Evas_Coord x, y; + double v; + + v = (((t - 6.0) / 10.0) * EVAS_PI * 2) * 2; +// x = cos(v * 1.7) * ((220) / 2); + y = sin(v * 0.5) * ((110) / 2); + if (y < 0) y = -y; + evas_object_gradient_fill_set(t1, 55, 55, 55, y); + evas_object_gradient_angle_set(t1, t * 60); + evas_object_gradient_spread_set(t1, EVAS_TEXTURE_RESTRICT); + evas_object_resize(t1, 110, 110); + evas_object_move(t1, (win_w - 110) / 2, (win_h - 240) + ((240 - 110) / 2)); + if (t <= 414.0) + { + evas_object_gradient_type_set(t1, "radial", NULL); + } + else + { + char s[32]; + + memset(s,0,32); + sprintf(s, "inner_radius = %f3.3;", 0.7 * (1.0 - (y / 55.0))); + evas_object_gradient_type_set(t1, "radial", s); + } + } + } + else if (t <= 439.0) + { + Evas_Coord tw, th; + + evas_object_text_text_set(title, "Test 34: Gradient Object Angular"); + evas_object_geometry_get(title, NULL, NULL, &tw, &th); + evas_object_move(title, (win_w - tw) / 2, win_h - th); + { + Evas_Coord x, y; + double v; + + v = (((t - 6.0) / 10.0) * EVAS_PI * 2) * 2; +// x = cos(v * 1.7) * ((220) / 2); + y = sin(v * 0.5) * ((110) / 2); + if (y < 0) y = -y; + evas_object_gradient_angle_set(t1, t * 60); + evas_object_gradient_spread_set(t1, EVAS_TEXTURE_REFLECT); + evas_object_resize(t1, 110, 110); + evas_object_move(t1, (win_w - 110) / 2, (win_h - 240) + ((240 - 110) / 2)); + if (t <= 429.0) + { + evas_object_gradient_fill_set(t1, 55, 55, 55, 55); + evas_object_gradient_type_set(t1, "angular", NULL); + } + else + { + char s[32]; + + memset(s,0,32); + evas_object_gradient_fill_set(t1, 55, 55, 55, y); + sprintf(s, "annulus = %f3.3; wrap = 0.25;", 0.7 * (1.0 - (y / 55.0))); + evas_object_gradient_type_set(t1, "angular", s); + } + } + } + else if (t <= 454.0) + { + Evas_Coord tw, th; + + evas_object_text_text_set(title, "Test 34: Gradient Object Sinusoidal"); + evas_object_geometry_get(title, NULL, NULL, &tw, &th); + evas_object_move(title, (win_w - tw) / 2, win_h - th); + { + Evas_Coord x, y; + double v; + + evas_object_gradient_angle_set(t1, t * 60); + v = (((t - 6.0) / 10.0) * EVAS_PI * 2) * 2; +// x = cos(v * 1.7) * ((220) / 2); + y = sin(v * 0.5) * (110 / 2); + evas_object_gradient_fill_set(t1, 55, 55, 55, y); + evas_object_gradient_type_set(t1, "sinusoidal", NULL); + if (t <= 444.0) + { + evas_object_gradient_spread_set(t1, EVAS_TEXTURE_REFLECT); + } + else if (t <= 449.0) + { + evas_object_gradient_spread_set(t1, EVAS_TEXTURE_REPEAT); + } + else + { + evas_object_gradient_spread_set(t1, EVAS_TEXTURE_RESTRICT); + } + + } + } + else if (t <= 455.0) { if (t1) evas_object_del(t1); @@ -1680,13 +1842,13 @@ loop(void) evas_object_del(t2); t2 = NULL; } - else if (t <= 400.0) + else if (t <= 464.0) { Evas_Coord tw, th; evas_object_text_text_set(comment, "We can move, resize and recolor rectangles"); - evas_object_text_text_set(title, "Test 33: Rectangles"); + evas_object_text_text_set(title, "Test 35: Rectangles"); evas_object_geometry_get(title, NULL, NULL, &tw, &th); evas_object_move(title, (win_w - tw) / 2, win_h - th); if (!t1) @@ -1721,7 +1883,7 @@ loop(void) ((int)(t * 230)) & 0xff); } } - else if (t <= 401.0) + else if (t <= 465.0) { if (t1) evas_object_del(t1); @@ -1730,13 +1892,13 @@ loop(void) evas_object_del(t2); t2 = NULL; } - else if (t <= 411.0) + else if (t <= 474.0) { Evas_Coord tw, th; evas_object_text_text_set(comment, "We can modify line begin & end coords"); - evas_object_text_text_set(title, "Test 34: Lines"); + evas_object_text_text_set(title, "Test 36: Lines"); evas_object_geometry_get(title, NULL, NULL, &tw, &th); evas_object_move(title, (win_w - tw) / 2, win_h - th); if (!t1) @@ -1773,13 +1935,13 @@ loop(void) ((int)(t * 230)) & 0xff); } } - else if (t <= 421.0) + else if (t <= 483.0) { Evas_Coord tw, th; evas_object_text_text_set(comment, "We can move, resize and recolor lines"); - evas_object_text_text_set(title, "Test 35: Line Move & Resize"); + evas_object_text_text_set(title, "Test 37: Line Move & Resize"); evas_object_geometry_get(title, NULL, NULL, &tw, &th); evas_object_move(title, (win_w - tw) / 2, win_h - th); { @@ -1802,7 +1964,7 @@ loop(void) ((int)(t * 230)) & 0xff); } } - else if (t <= 422.0) + else if (t <= 484.0) { if (t1) evas_object_del(t1); @@ -1811,12 +1973,12 @@ loop(void) evas_object_del(t2); t2 = NULL; } - else if (t <= 432.0) + else if (t <= 494.0) { Evas_Coord tw, th; evas_object_text_text_set(comment, "We can modify polygon points"); - evas_object_text_text_set(title, "Test 36: Polygons"); + evas_object_text_text_set(title, "Test 38: Polygons"); evas_object_geometry_get(title, NULL, NULL, &tw, &th); evas_object_move(title, (win_w - tw) / 2, win_h - th); if (!t1) @@ -1864,13 +2026,13 @@ loop(void) ((int)(t * 230)) & 0xff); } } - else if (t <= 442.0) + else if (t <= 503.0) { Evas_Coord tw, th; evas_object_text_text_set(comment, "We can move, resize and recolor polygons"); - evas_object_text_text_set(title, "Test 37: Polygon Move & Resize"); + evas_object_text_text_set(title, "Test 39: Polygon Move & Resize"); evas_object_geometry_get(title, NULL, NULL, &tw, &th); evas_object_move(title, (win_w - tw) / 2, win_h - th); { @@ -1893,7 +2055,7 @@ loop(void) ((int)(t * 230)) & 0xff); } } - else if (t <= 443.0) + else if (t <= 504.0) { if (t1) evas_object_del(t1); @@ -1902,7 +2064,7 @@ loop(void) evas_object_del(t2); t2 = NULL; } - else if (t <= 453.0) + else if (t <= 509.0) { Evas_Coord tw, th; @@ -1912,7 +2074,7 @@ loop(void) evas_object_geometry_get(title, NULL, NULL, &tw, &th); evas_object_move(title, (win_w - tw) / 2, win_h - th); } - else if (t <= 463.0) + else if (t <= 514.0) { printf("################ evas free\n"); evas_free(evas); diff --git a/legacy/evas/src/lib/Evas.h b/legacy/evas/src/lib/Evas.h index 4bbe6d5fbf..cf314b823d 100644 --- a/legacy/evas/src/lib/Evas.h +++ b/legacy/evas/src/lib/Evas.h @@ -138,6 +138,13 @@ struct _Evas_Pixel_Import_Source #define EVAS_PIXEL_FORMAT_ARGB32 1 /**< ARGB 32bit pixel format with A in the high byte per 32bit pixel word */ #define EVAS_PIXEL_FORMAT_YUV420P_601 2 /**< YUV 420 Planar format with CCIR 601 color encoding wuth contiguous planes in the order Y, U and V */ +#define EVAS_COLOR_SPACE_ARGB 0 /**< ARGB color space */ +#define EVAS_COLOR_SPACE_AHSV 1 /**< AHSV color space */ + +#define EVAS_TEXTURE_REFLECT 0 /**< Gradient and image fill tiling mode - tiling reflects */ +#define EVAS_TEXTURE_REPEAT 1 /**< tiling repeats */ +#define EVAS_TEXTURE_RESTRICT 2 /**< tiling clamps */ + struct _Evas_Engine_Info /** Generic engine information. Generic info is useless */ { int magic; /**< Magic number */ @@ -367,6 +374,13 @@ extern "C" { EAPI void evas_object_gradient_colors_clear (Evas_Object *obj); EAPI void evas_object_gradient_angle_set (Evas_Object *obj, Evas_Angle angle); EAPI Evas_Angle evas_object_gradient_angle_get (Evas_Object *obj); + EAPI void evas_object_gradient_type_set (Evas_Object *obj, const char *type, const char *instance_params); + EAPI void evas_object_gradient_type_get (Evas_Object *obj, char **type, char **instance_params); + EAPI void evas_object_gradient_fill_set (Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); + EAPI void evas_object_gradient_fill_get (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h); + EAPI void evas_object_gradient_spread_set (Evas_Object *obj, int +tile_mode); + EAPI int evas_object_gradient_spread_get (Evas_Object *obj); EAPI Evas_Object *evas_object_polygon_add (Evas *e); EAPI void evas_object_polygon_point_add (Evas_Object *obj, Evas_Coord x, Evas_Coord y); @@ -558,9 +572,15 @@ extern "C" { EAPI void evas_object_hide (Evas_Object *obj); EAPI Evas_Bool evas_object_visible_get (Evas_Object *obj); + EAPI void evas_object_anti_alias_set (Evas_Object *obj, Evas_Bool antialias); + EAPI Evas_Bool evas_object_anti_alias_get (Evas_Object *obj); + EAPI void evas_object_color_set (Evas_Object *obj, int r, int g, int b, int a); EAPI void evas_object_color_get (Evas_Object *obj, int *r, int *g, int *b, int *a); + EAPI void evas_object_color_interpolation_set (Evas_Object *obj, int color_space); + EAPI int evas_object_color_interpolation_get (Evas_Object *obj); + EAPI void evas_object_clip_set (Evas_Object *obj, Evas_Object *clip); EAPI Evas_Object *evas_object_clip_get (Evas_Object *obj); EAPI void evas_object_clip_unset (Evas_Object *obj); @@ -668,6 +688,12 @@ extern "C" { EAPI void evas_object_intercept_layer_set_callback_add (Evas_Object *obj, void (*func) (void *data, Evas_Object *obj, int l), const void *data); EAPI void *evas_object_intercept_layer_set_callback_del (Evas_Object *obj, void (*func) (void *data, Evas_Object *obj, int l)); +/* Evas utility routines for color space conversions */ +/* hsv color space has h in the range 0.0 to 360.0, and s,v in the range 0.0 to 1.0 */ +/* rgb color space has r,g,b in the range 0 to 255 */ + EAPI void evas_color_hsv_to_rgb (float h, float s, float v, int *r, int *g, int *b); + EAPI void evas_color_rgb_to_hsv (int r, int g, int b, float *h, float *s, float *v); + /* Evas imaging api - exports some of the comon gfx engine routines */ /* this is not complete and should be considered experimental. use at your */ /* own risk */ diff --git a/legacy/evas/src/lib/canvas/evas_main.c b/legacy/evas/src/lib/canvas/evas_main.c index cd6c70882a..39462a9c9a 100644 --- a/legacy/evas/src/lib/canvas/evas_main.c +++ b/legacy/evas/src/lib/canvas/evas_main.c @@ -43,11 +43,10 @@ int evas_shutdown(void) { if (--initcount == 0) - { - evas_font_dir_cache_free(); - evas_common_image_free_cache(); - } - + { + evas_font_dir_cache_free(); + evas_common_shutdown(); + } return initcount; } diff --git a/legacy/evas/src/lib/canvas/evas_object_gradient.c b/legacy/evas/src/lib/canvas/evas_object_gradient.c index 35854215fd..a6af82f916 100644 --- a/legacy/evas/src/lib/canvas/evas_object_gradient.c +++ b/legacy/evas/src/lib/canvas/evas_object_gradient.c @@ -13,10 +13,19 @@ struct _Evas_Object_Gradient struct { Evas_Angle angle; + int spread; + struct { + Evas_Coord x, y, w, h; + } fill; + struct { + char *name; + char *params; + } type; + unsigned char gradient_opaque : 1; } cur, prev; - char changed : 1; - char gradient_changed : 1; - char gradient_opaque : 1; + + unsigned char changed : 1; + unsigned char gradient_changed : 1; void *engine_data; }; @@ -118,8 +127,9 @@ evas_object_gradient_color_add(Evas_Object *obj, int r, int g, int b, int a, int o->engine_data, r, g, b, a, distance); + if (a != 255) o->cur.gradient_opaque = 0; o->gradient_changed = 1; - if (a != 255) o->gradient_opaque = 0; + o->changed = 1; evas_object_change(obj); } @@ -144,7 +154,8 @@ evas_object_gradient_colors_clear(Evas_Object *obj) obj->layer->evas->engine.data.context, o->engine_data); o->gradient_changed = 1; - o->gradient_opaque = 1; + o->changed = 1; + o->cur.gradient_opaque = 1; evas_object_change(obj); } @@ -196,7 +207,280 @@ evas_object_gradient_angle_get(Evas_Object *obj) evas_object_change(obj); } +/** + * @defgroup Evas_Object_Gradient_Fill_Group Gradient Object Fill Rectangle Functions + * + * Functions that deal with what areas of the gradient object are to be + * tiled with the gradient. + */ +/** + * Sets the rectangle on the gradient object that the gradient will be + * drawn to. + * + * Note that the gradient may be tiled around this one rectangle, + * according to its spread value - restrict, repeat, or reflect. To have + * only one 'cycle' of the gradient drawn, the spread value must be set + * to restrict, or @p x and @p y must be 0 and @p w and @p h need to be + * the width and height of the gradient object respectively. + * + * The default values for the fill parameters is @p x = 0, @p y = 0, + * @p w = 32 and @p h = 32. + * + * @param obj The given evas gradient object. + * @param x The X coordinate for the top left corner of the rect. + * @param y The Y coordinate for the top left corner of the rect. + * @param w The width of the rect. + * @param h The height of the rect. + * @ingroup Evas_Object_Gradient_Fill_Group + */ +void +evas_object_gradient_fill_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) +{ + Evas_Object_Gradient *o; + + if (w < 0) w = -w; + if (h < 0) h = -h; + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + o = (Evas_Object_Gradient *)(obj->object_data); + MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT); + return; + MAGIC_CHECK_END(); + if ((o->cur.fill.x == x) && + (o->cur.fill.y == y) && + (o->cur.fill.w == w) && + (o->cur.fill.h == h)) return; + o->cur.fill.x = x; + o->cur.fill.y = y; + o->cur.fill.w = w; + o->cur.fill.h = h; + o->changed = 1; + o->gradient_changed = 1; + evas_object_change(obj); +} + +/** + * Retrieves the dimensions of the rectangle on the gradient object that + * the gradient will use as its fill rect. + * + * See @ref evas_object_gradient_fill_set for more details. + * + * @param obj The given evas gradient object. + * @param x Pointer to an Evas_Coord to store the X coordinate in. + * @param y Pointer to an Evas_Coord to store the Y coordinate in. + * @param w Pointer to an Evas_Coord to store the width in. + * @param h Pointer to an Evas_Coord to store the height in. + * @ingroup Evas_Object_Gradient_Fill_Group + */ +void +evas_object_gradient_fill_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) +{ + Evas_Object_Gradient *o; + + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = 0; + if (h) *h = 0; + return; + MAGIC_CHECK_END(); + o = (Evas_Object_Gradient *)(obj->object_data); + MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT); + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = 0; + if (h) *h = 0; + return; + MAGIC_CHECK_END(); + if (x) *x = o->cur.fill.x; + if (y) *y = o->cur.fill.y; + if (w) *w = o->cur.fill.w; + if (h) *h = o->cur.fill.h; +} + +/** + * Sets the tiling mode for the given evas gradient object. + * @param obj The given evas gradient object. + * @param spread One of EVAS_TEXTURE_RESTRICT, EVAS_TEXTURE_REPEAT, + * or EVAS_TEXTURE_REFLECT. + * @ingroup Evas_Object_Gradient_Group + */ +void +evas_object_gradient_spread_set(Evas_Object *obj, int spread) +{ + Evas_Object_Gradient *o; + + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + o = (Evas_Object_Gradient *)(obj->object_data); + MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT); + return; + MAGIC_CHECK_END(); + if (spread == o->cur.spread) return; + o->cur.spread = spread; + o->changed = 1; + o->gradient_changed = 1; + if (spread == EVAS_TEXTURE_RESTRICT) + o->cur.gradient_opaque = 0; + evas_object_change(obj); +} + +/** + * Retrieves the spread (tiling mode) for the given gradient object. + * @param obj The given evas gradient object. + * @return The current spread mode of the gradient object. + * @ingroup Evas_Object_Gradient_Group + */ +int +evas_object_gradient_spread_get(Evas_Object *obj) +{ + Evas_Object_Gradient *o; + + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return EVAS_TEXTURE_REFLECT; + MAGIC_CHECK_END(); + o = (Evas_Object_Gradient *)(obj->object_data); + MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT); + return EVAS_TEXTURE_REFLECT; + MAGIC_CHECK_END(); + return o->cur.spread; +} + +/** + * @defgroup Evas_Object_Gradient_Type_Group Gradient Object Type Functions + * + * Functions that set or get a gradient's geometric type. Examples are "linear", + * "radial", "rectangular", "sinusoidal", ... Some types may accept added parameters + * to further specify the look. + */ + +/** + * Sets the geometric type displayed by the given gradient object. + * @param obj The given gradient object. + * @param name Name of the geometric type that the gradient is to be drawn as. + * @param params List of allowable param_name, param_value pairs. Must be in the + * format "param_name=param_value; param_name2=param_value2;", eg. "amplitude=0.8;". + * Can be NULL. + * @ingroup Evas_Object_Gradient_Type_Group + */ +void +evas_object_gradient_type_set(Evas_Object *obj, const char *name, const char *params) +{ + Evas_Object_Gradient *o; + + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + o = (Evas_Object_Gradient *)(obj->object_data); + MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT); + return; + MAGIC_CHECK_END(); + if (!name || !*name) + { + name = "linear"; + params = NULL; + } + if (params && !*params) + params = NULL; + if ((o->cur.type.name) && (!strcmp(o->cur.type.name, name))) + { + if ((!o->cur.type.params) && (!params)) + return; + if ((o->cur.type.params) && (params) && (!strcmp(o->cur.type.params, params))) + return; + if (o->cur.type.params) + { + if (o->prev.type.params == o->cur.type.params) + o->prev.type.params = strdup(o->cur.type.params); + free(o->cur.type.params); + o->cur.type.params = NULL; + } + if (params) + o->cur.type.params = strdup(params); + o->changed = 1; + o->gradient_changed = 1; + evas_object_change(obj); + return; + } + + if (o->cur.type.name) + { + if (o->prev.type.name == o->cur.type.name) + o->prev.type.name = strdup(o->cur.type.name); + free(o->cur.type.name); + o->cur.type.name = NULL; + } + o->cur.type.name = strdup(name); + + if (o->cur.type.params) + { + if (o->prev.type.params == o->cur.type.params) + o->prev.type.params = strdup(o->cur.type.params); + free(o->cur.type.params); + o->cur.type.params = NULL; + } + if (params) + o->cur.type.params = strdup(params); + o->changed = 1; + o->gradient_changed = 1; + evas_object_change(obj); +} + +/** + * Retrieves the type name and params of the given gradient object. + * @param obj The given gradient object. + * @param name Pointer to a character pointer to store the pointer to the type + * name in. + * @param params Pointer to a character pointer to store the pointer to the type + * params string in. + * @ingroup Evas_Object_Gradient_Type_Group + */ +void +evas_object_gradient_type_get(Evas_Object *obj, char **name, char **params) +{ + Evas_Object_Gradient *o; + + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + if (name) *name = NULL; + if (params) *params = NULL; + return; + MAGIC_CHECK_END(); + o = (Evas_Object_Gradient *)(obj->object_data); + MAGIC_CHECK(o, Evas_Object_Gradient, MAGIC_OBJ_GRADIENT); + if (name) *name = NULL; + if (params) *params = NULL; + return; + MAGIC_CHECK_END(); + if (name) *name = o->cur.type.name; + if (params) *params = o->cur.type.params; +} + + +/* + these two functions don't really belong here as they can apply to other + objs as well, but for now.. +*/ + +/** + FIXME: ... +**/ +void +evas_color_hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b) +{ + evas_common_convert_hsv_to_rgb(h, s, v, r, g, b); +} + +/** + FIXME: ... +**/ +void +evas_color_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v) +{ + evas_common_convert_rgb_to_hsv(r, g, b, h, s, v); +} @@ -216,11 +500,14 @@ evas_object_gradient_init(Evas_Object *obj) obj->cur.geometry.w = 32.0; obj->cur.geometry.h = 32.0; obj->cur.layer = 0; + obj->cur.anti_alias = 1; + obj->cur.interpolation.color_space = EVAS_COLOR_SPACE_ARGB; /* set up object-specific settings */ obj->prev = obj->cur; /* set up methods (compulsory) */ obj->func = &object_func; obj->type = o_type; + obj->changed = 1; } static void * @@ -232,8 +519,17 @@ evas_object_gradient_new(void) o = calloc(1, sizeof(Evas_Object_Gradient)); o->magic = MAGIC_OBJ_GRADIENT; o->cur.angle = 0.0; + o->cur.spread = EVAS_TEXTURE_REFLECT; + o->cur.fill.x = 0; + o->cur.fill.y = 0; + o->cur.fill.w = 32; + o->cur.fill.h = 32; + o->cur.type.name = strdup("linear"); + o->cur.type.params = NULL; + o->cur.gradient_opaque = 1; o->prev = o->cur; - o->gradient_opaque = 1; + o->gradient_changed = 1; + o->changed = 1; return o; } @@ -248,13 +544,44 @@ evas_object_gradient_free(Evas_Object *obj) return; MAGIC_CHECK_END(); /* free obj */ - o->engine_data = obj->layer->evas->engine.func->gradient_colors_clear(obj->layer->evas->engine.data.output, - obj->layer->evas->engine.data.context, - o->engine_data); + if (o->prev.type.name && (o->prev.type.name != o->cur.type.name)) + free(o->prev.type.name); + if (o->prev.type.params && (o->prev.type.params != o->cur.type.params)) + free(o->prev.type.params); + if (o->cur.type.name) + free(o->cur.type.name); + if (o->cur.type.params) + free(o->cur.type.params); + obj->layer->evas->engine.func->gradient_free(obj->layer->evas->engine.data.output, + o->engine_data); o->magic = 0; free(o); } + +static void +evas_object_grad_get_fill_coords(Evas_Object *obj, Evas_Coord fx, Evas_Coord fy, Evas_Coord fw, Evas_Coord fh, Evas_Coord *fx_ret, Evas_Coord *fy_ret, Evas_Coord *fw_ret, +Evas_Coord *fh_ret) +{ + Evas_Coord x, y, w, h; + + x = ((fx * obj->layer->evas->output.w) / + (Evas_Coord)obj->layer->evas->viewport.w); + w = ((fw * obj->layer->evas->output.w) / + (Evas_Coord)obj->layer->evas->viewport.w); + if (fw <= 0) fw = 1; + y = ((fy * obj->layer->evas->output.h) / + (Evas_Coord)obj->layer->evas->viewport.h); + h = ((fh * obj->layer->evas->output.h) / + (Evas_Coord)obj->layer->evas->viewport.h); + if (fh <= 0) fh = 1; + + *fx_ret = x; *fw_ret = w; + *fy_ret = y; *fh_ret = h; +} + + + static void evas_object_gradient_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y) { @@ -269,25 +596,30 @@ evas_object_gradient_render(Evas_Object *obj, void *output, void *context, void (obj->cur.cache.clip.g == 255) && (obj->cur.cache.clip.b == 255) && (obj->cur.cache.clip.a == 255)) - obj->layer->evas->engine.func->context_multiplier_unset(output, - context); + obj->layer->evas->engine.func->context_multiplier_unset(output, context); else - obj->layer->evas->engine.func->context_multiplier_set(output, - context, + obj->layer->evas->engine.func->context_multiplier_set(output, context, obj->cur.cache.clip.r, obj->cur.cache.clip.g, obj->cur.cache.clip.b, obj->cur.cache.clip.a); + obj->layer->evas->engine.func->context_anti_alias_set(output, context, + obj->cur.anti_alias); + obj->layer->evas->engine.func->context_color_interpolation_set(output, context, + obj->cur.interpolation.color_space); if (o->engine_data) - obj->layer->evas->engine.func->gradient_draw(output, - context, - surface, - o->engine_data, - obj->cur.cache.geometry.x + x, - obj->cur.cache.geometry.y + y, - obj->cur.cache.geometry.w, - obj->cur.cache.geometry.h, - o->cur.angle); + { + if (o->gradient_changed) + obj->layer->evas->engine.func->gradient_map(output, context, o->engine_data, + o->cur.spread); + obj->layer->evas->engine.func->gradient_draw(output, context, surface, + o->engine_data, + obj->cur.cache.geometry.x + x, + obj->cur.cache.geometry.y + y, + obj->cur.cache.geometry.w, + obj->cur.cache.geometry.h, + o->cur.angle, o->cur.spread); + } } static void @@ -313,6 +645,43 @@ evas_object_gradient_render_pre(Evas_Object *obj) evas_object_clip_recalc(obj->cur.clipper); obj->cur.clipper->func->render_pre(obj->cur.clipper); } + /* if it changed color */ + if ((obj->cur.color.r != obj->prev.color.r) || + (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; + if ((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; + if (obj->cur.anti_alias != obj->prev.anti_alias) + o->gradient_changed = 1; + if (obj->cur.interpolation.color_space != obj->prev.interpolation.color_space) + o->gradient_changed = 1; + if (obj->cur.cache.clip.a != 255) + o->cur.gradient_opaque = 0; + if (o->gradient_changed && o->engine_data) + { + Evas_Coord fx, fy, fw, fh; + + evas_object_grad_get_fill_coords(obj, o->cur.fill.x, o->cur.fill.y, + o->cur.fill.w, o->cur.fill.h, + &fx, &fy, &fw, &fh); + obj->layer->evas->engine.func->gradient_fill_set(obj->layer->evas->engine.data.output, o->engine_data, + fx, fy, fw, fh); + obj->layer->evas->engine.func->gradient_type_set(obj->layer->evas->engine.data.output, o->engine_data, + o->cur.type.name); + obj->layer->evas->engine.func->gradient_type_params_set(obj->layer->evas->engine.data.output, o->engine_data, + o->cur.type.params); + + o->engine_data = obj->layer->evas->engine.func->gradient_geometry_init(obj->layer->evas->engine.data.output, o->engine_data, o->cur.spread); + if (o->engine_data) + { + o->cur.gradient_opaque &= !(obj->layer->evas->engine.func->gradient_alpha_get(obj->layer->evas->engine.data.output, o->engine_data, o->cur.spread)); + } + } /* now figure what changed and add draw rects */ /* if it just became visible or invisible */ is_v = evas_object_is_visible(obj); @@ -326,24 +695,19 @@ evas_object_gradient_render_pre(Evas_Object *obj) if (!is_v) goto done; /* clipper changed this is in addition to anything else for obj */ updates = evas_object_render_pre_clipper_change(updates, obj); + /* gradient changed */ + if (o->gradient_changed) + { + updates = evas_object_render_pre_prev_cur_add(updates, obj); + goto done; + } /* if we restacked (layer or just within a layer) and dont clip anyone */ if (obj->restack) { updates = evas_object_render_pre_prev_cur_add(updates, obj); goto done; } - /* if it changed color */ - if ((obj->cur.color.r != obj->prev.color.r) || - (obj->cur.color.g != obj->prev.color.g) || - (obj->cur.color.b != obj->prev.color.b) || - (obj->cur.color.a != obj->prev.color.a)) - { - updates = evas_object_render_pre_prev_cur_add(updates, obj); - goto done; - } - /* if it changed geometry - and obviously not visibility or color */ - /* caluclate differences since we have a constant color fill */ - /* we really only need to update the differences */ + /* if it changed geometry */ if ((obj->cur.geometry.x != obj->prev.geometry.x) || (obj->cur.geometry.y != obj->prev.geometry.y) || (obj->cur.geometry.w != obj->prev.geometry.w) || @@ -358,15 +722,10 @@ evas_object_gradient_render_pre(Evas_Object *obj) updates = evas_object_render_pre_prev_cur_add(updates, obj); goto done; } - /* angle changed */ - if (o->gradient_changed) - { - updates = evas_object_render_pre_prev_cur_add(updates, obj); - goto done; - } /* it obviously didn't change - add a NO obscure - this "unupdates" this */ /* area so if there were updates for it they get wiped. don't do it if we */ /* arent fully opaque and we are visible */ + if (evas_object_is_visible(obj) && evas_object_is_opaque(obj)) obj->layer->evas->engine.func->output_redraws_rect_del(obj->layer->evas->engine.data.output, @@ -374,6 +733,7 @@ evas_object_gradient_render_pre(Evas_Object *obj) obj->cur.cache.clip.y, obj->cur.cache.clip.w, obj->cur.cache.clip.h); + done: evas_object_render_pre_effect_updates(updates, obj, is_v, was_v); } @@ -398,6 +758,11 @@ evas_object_gradient_render_post(Evas_Object *obj) } /* move cur to prev safely for object data */ obj->prev = obj->cur; + obj->changed = 0; + if (o->prev.type.name && (o->prev.type.name != o->cur.type.name)) + free(o->prev.type.name); + if (o->prev.type.params && (o->prev.type.params != o->cur.type.params)) + free(o->prev.type.params); o->prev = o->cur; o->changed = 0; o->gradient_changed = 0; @@ -411,8 +776,12 @@ evas_object_gradient_is_opaque(Evas_Object *obj) /* this returns 1 if the internal object data implies that the object is */ /* currently fulyl opque over the entire gradient it occupies */ o = (Evas_Object_Gradient *)(obj->object_data); - return o->gradient_opaque; -} + if (!o->engine_data) return 1; + o->cur.gradient_opaque &= + !(obj->layer->evas->engine.func->gradient_alpha_get(obj->layer->evas->engine.data.output, + o->engine_data, o->cur.spread)); + return o->cur.gradient_opaque; + } static int evas_object_gradient_was_opaque(Evas_Object *obj) @@ -422,5 +791,6 @@ evas_object_gradient_was_opaque(Evas_Object *obj) /* this returns 1 if the internal object data implies that the object was */ /* currently fulyl opque over the entire gradient it occupies */ o = (Evas_Object_Gradient *)(obj->object_data); - return o->gradient_opaque; + if (!o->engine_data) return 1; + return o->prev.gradient_opaque; } diff --git a/legacy/evas/src/lib/canvas/evas_object_main.c b/legacy/evas/src/lib/canvas/evas_object_main.c index a778f940ff..e80210ee8f 100644 --- a/legacy/evas/src/lib/canvas/evas_object_main.c +++ b/legacy/evas/src/lib/canvas/evas_object_main.c @@ -821,6 +821,78 @@ evas_object_color_get(Evas_Object *obj, int *r, int *g, int *b, int *a) if (a) *a = obj->cur.color.a; } +/** + * Sets whether or not the given evas object is to be drawn anti_aliased. + * @param obj The given evas object. + * @param anti_alias. 1 if the object is to be anti_aliased, 0 otherwise. + * @ingroup Evas_Object_Group + */ +void +evas_object_anti_alias_set(Evas_Object *obj, Evas_Bool anti_alias) +{ + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + if (obj->delete_me) return; + if (obj->cur.anti_alias == !!anti_alias) + return; + obj->cur.anti_alias = !!anti_alias; + evas_object_change(obj); +} + + +/** + * Retrieves whether or not the given evas object is to be drawn anti_aliased. + * @param obj The given evas object. + * @return @c 1 if the object is to be anti_aliased. @c 0 otherwise. + * @ingroup Evas_Object_Group + */ +Evas_Bool +evas_object_anti_alias_get(Evas_Object *obj) +{ + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return 0; + MAGIC_CHECK_END(); + if (obj->delete_me) return 0; + return obj->cur.anti_alias; +} + +/** + * Sets the color_space to be used for linear interpolation of colors. + * @param obj The given evas object. + * @param color_space, one of EVAS_COLOR_SPACE_ARGB or EVAS_COLOR_SPACE_AHSV. + * @ingroup Evas_Object_Group + */ +void +evas_object_color_interpolation_set(Evas_Object *obj, int color_space) +{ + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + if (obj->delete_me) return; + if (obj->cur.interpolation.color_space == color_space) + return; + obj->cur.interpolation.color_space = color_space; + evas_object_change(obj); +} + + +/** + * Retrieves the current value of the color space used for linear interpolation. + * @param obj The given evas object. + * @return @c EVAS_COLOR_SPACE_ARGB or EVAS_COLOR_SPACE_AHSV. + * @ingroup Evas_Object_Group + */ +int +evas_object_color_interpolation_get(Evas_Object *obj) +{ + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return 0; + MAGIC_CHECK_END(); + if (obj->delete_me) return 0; + return obj->cur.interpolation.color_space; +} + /** * Retrieves the evas that the given evas object is on. * @param obj The given evas object. diff --git a/legacy/evas/src/lib/canvas/evas_render.c b/legacy/evas/src/lib/canvas/evas_render.c index b77674af71..036ce43232 100644 --- a/legacy/evas/src/lib/canvas/evas_render.c +++ b/legacy/evas/src/lib/canvas/evas_render.c @@ -1,6 +1,9 @@ #include "evas_common.h" #include "evas_private.h" +static Evas_List * +evas_render_updates_internal(Evas *e, unsigned char make_updates); + /** * To be documented. * @@ -169,14 +172,8 @@ _evas_render_phase1_process(Evas *e, Evas_List **active_objects, Evas_List **res } } -/** - * To be documented. - * - * FIXME: To be fixed. - * - */ -Evas_List * -evas_render_updates(Evas *e) +static Evas_List * +evas_render_updates_internal(Evas *e, unsigned char make_updates) { Evas_List *updates = NULL; Evas_List *obscuring_objects = NULL; @@ -275,14 +272,18 @@ evas_render_updates(Evas *e) &ux, &uy, &uw, &uh, &cx, &cy, &cw, &ch))) { - Evas_Rectangle *rect; int off_x, off_y; - rect = malloc(sizeof(Evas_Rectangle)); - if (rect) + if (make_updates) { - rect->x = ux; rect->y = uy; rect->w = uw; rect->h = uh; - updates = evas_list_append(updates, rect); + Evas_Rectangle *rect; + + rect = malloc(sizeof(Evas_Rectangle)); + if (rect) + { + rect->x = ux; rect->y = uy; rect->w = uw; rect->h = uh; + updates = evas_list_append(updates, rect); + } } off_x = cx - ux; off_y = cy - uy; @@ -415,6 +416,24 @@ evas_render_updates_free(Evas_List *updates) } } +/** + * To be documented. + * + * FIXME: To be fixed. + * + */ +Evas_List * +evas_render_updates(Evas *e) +{ + MAGIC_CHECK(e, Evas, MAGIC_EVAS); + return NULL; + MAGIC_CHECK_END(); + + if (!e->changed) + return NULL; + return evas_render_updates_internal(e, 1); +} + /** * To be documented. * @@ -424,12 +443,11 @@ evas_render_updates_free(Evas_List *updates) void evas_render(Evas *e) { - Evas_List *updates; - MAGIC_CHECK(e, Evas, MAGIC_EVAS); return; MAGIC_CHECK_END(); - updates = evas_render_updates(e); - if (updates) evas_render_updates_free(updates); + if (!e->changed) + return; + (void)evas_render_updates_internal(e, 0); } diff --git a/legacy/evas/src/lib/engines/buffer/evas_engine.c b/legacy/evas/src/lib/engines/buffer/evas_engine.c index 879be58515..7a5dcb4628 100644 --- a/legacy/evas/src/lib/engines/buffer/evas_engine.c +++ b/legacy/evas/src/lib/engines/buffer/evas_engine.c @@ -42,14 +42,25 @@ static void evas_engine_buffer_context_multiplier_unset(void *data, void *contex static int evas_engine_buffer_context_multiplier_get(void *data, void *context, int *r, int *g, int *b, int *a); static void evas_engine_buffer_context_cutout_add(void *data, void *context, int x, int y, int w, int h); static void evas_engine_buffer_context_cutout_clear(void *data, void *context); -static void evas_engine_buffer_draw_rectangle(void *data, void *context, void *surface, int x, int y, int w, int h); +static void evas_engine_buffer_context_anti_alias_set(void *data, void *context, unsigned char aa); +static unsigned char evas_engine_buffer_context_anti_alias_get(void *data, void *context); +static void evas_engine_buffer_context_color_interpolation_set(void *data, void *context, int color_space); +static int evas_engine_buffer_context_color_interpolation_get(void *data, void *context); +static void evas_engine_buffer_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h); static void evas_engine_buffer_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2); static void *evas_engine_buffer_polygon_point_add(void *data, void *context, void *polygon, int x, int y); static void *evas_engine_buffer_polygon_points_clear(void *data, void *context, void *polygon); static void evas_engine_buffer_polygon_draw(void *data, void *context, void *surface, void *polygon); static void *evas_engine_buffer_gradient_color_add(void *data, void *context, void *gradient, int r, int g, int b, int a, int distance); static void *evas_engine_buffer_gradient_colors_clear(void *data, void *context, void *gradient); -static void evas_engine_buffer_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle); +static void evas_engine_buffer_gradient_free(void *data, void *gradient); +static void evas_engine_buffer_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h); +static void evas_engine_buffer_gradient_type_set(void *data, void *gradient, char *name); +static void evas_engine_buffer_gradient_type_params_set(void *data, void *gradient, char *params); +static void *evas_engine_buffer_gradient_geometry_init(void *data, void *gradient, int spread); +static int evas_engine_buffer_gradient_alpha_get(void *data, void *gradient, int spread); +static void evas_engine_buffer_gradient_map(void *data, void *context, void *gradient, int spread); +static void evas_engine_buffer_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread); static void *evas_engine_buffer_image_load(void *data, char *file, char *key, int *error); static void *evas_engine_buffer_image_new_from_data(void *data, int w, int h, DATA32 *image_data); static void *evas_engine_buffer_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data); @@ -126,14 +137,28 @@ Evas_Func evas_engine_buffer_func = evas_engine_buffer_context_multiplier_get, evas_engine_buffer_context_cutout_add, evas_engine_buffer_context_cutout_clear, - /* rectangle draw funcs */ - evas_engine_buffer_draw_rectangle, + evas_engine_buffer_context_anti_alias_set, + evas_engine_buffer_context_anti_alias_get, + evas_engine_buffer_context_color_interpolation_set, + evas_engine_buffer_context_color_interpolation_get, + /* rect draw funcs */ + evas_engine_buffer_rectangle_draw, + /* line draw funcs */ evas_engine_buffer_line_draw, + /* polygon draw funcs */ evas_engine_buffer_polygon_point_add, evas_engine_buffer_polygon_points_clear, evas_engine_buffer_polygon_draw, + /* gradient draw funcs */ evas_engine_buffer_gradient_color_add, evas_engine_buffer_gradient_colors_clear, + evas_engine_buffer_gradient_free, + evas_engine_buffer_gradient_fill_set, + evas_engine_buffer_gradient_type_set, + evas_engine_buffer_gradient_type_params_set, + evas_engine_buffer_gradient_geometry_init, + evas_engine_buffer_gradient_alpha_get, + evas_engine_buffer_gradient_map, evas_engine_buffer_gradient_draw, /* image draw funcs */ evas_engine_buffer_image_load, @@ -576,7 +601,45 @@ evas_engine_buffer_context_cutout_clear(void *data, void *context) } static void -evas_engine_buffer_draw_rectangle(void *data, void *context, void *surface, int x, int y, int w, int h) +evas_engine_buffer_context_anti_alias_set(void *data, void *context, unsigned char aa) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_anti_alias(context, aa); +} + +static unsigned char +evas_engine_buffer_context_anti_alias_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->anti_alias; +} + +static void +evas_engine_buffer_context_color_interpolation_set(void *data, void *context, int color_space) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_color_interpolation(context, color_space); +} + +static int +evas_engine_buffer_context_color_interpolation_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->interpolation.color_space; +} + + + +static void +evas_engine_buffer_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h) { Render_Engine *re; @@ -644,18 +707,83 @@ evas_engine_buffer_gradient_colors_clear(void *data, void *context, void *gradie Render_Engine *re; re = (Render_Engine *)data; - if (gradient) evas_common_gradient_free(gradient); - return NULL; - context = 0; + evas_common_gradient_colors_clear(gradient); + return gradient; + context = NULL; } static void -evas_engine_buffer_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle) +evas_engine_buffer_gradient_free(void *data, void *gradient) { Render_Engine *re; re = (Render_Engine *)data; - evas_common_gradient_draw(surface, context, x, y, w, h, gradient, angle); + evas_common_gradient_free(gradient); +} + +static void +evas_engine_buffer_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_fill_set(gradient, x, y, w, h); +} + +static void +evas_engine_buffer_gradient_type_set(void *data, void *gradient, char *name) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_type_set(gradient, name); +} + +static void +evas_engine_buffer_gradient_type_params_set(void *data, void *gradient, char *params) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_type_params_set(gradient, params); +} + +static void * +evas_engine_buffer_gradient_geometry_init(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + gradient = evas_common_gradient_geometry_init(gradient, spread); + return gradient; +} + +static int +evas_engine_buffer_gradient_alpha_get(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_gradient_has_alpha(gradient, spread); +} + +static void +evas_engine_buffer_gradient_map(void *data, void *context, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_map(context, gradient, spread); + evas_common_cpu_end_opt(); +} + +static void +evas_engine_buffer_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_draw(surface, context, x, y, w, h, gradient, angle, spread); evas_common_cpu_end_opt(); } diff --git a/legacy/evas/src/lib/engines/cairo_x11/evas_engine.c b/legacy/evas/src/lib/engines/cairo_x11/evas_engine.c index 48a55ba6fd..abda2e085a 100644 --- a/legacy/evas/src/lib/engines/cairo_x11/evas_engine.c +++ b/legacy/evas/src/lib/engines/cairo_x11/evas_engine.c @@ -34,6 +34,10 @@ static void evas_engine_cairo_x11_context_multiplier_unset(void *data, void *con static int evas_engine_cairo_x11_context_multiplier_get(void *data, void *context, int *r, int *g, int *b, int *a); static void evas_engine_cairo_x11_context_cutout_add(void *data, void *context, int x, int y, int w, int h); static void evas_engine_cairo_x11_context_cutout_clear(void *data, void *context); +static void evas_engine_cairo_x11_context_anti_alias_set(void *data, void *context, unsigned char aa); +static unsigned char evas_engine_cairo_x11_context_anti_alias_get(void *data, void *context); +static void evas_engine_cairo_x11_context_color_interpolation_set(void *data, void *context, int color_space); +static int evas_engine_cairo_x11_context_color_interpolation_get(void *data, void *context); static void evas_engine_cairo_x11_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h); static void evas_engine_cairo_x11_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2); static void *evas_engine_cairo_x11_polygon_point_add(void *data, void *context, void *polygon, int x, int y); @@ -41,7 +45,14 @@ static void *evas_engine_cairo_x11_polygon_points_clear(void *data, void *contex static void evas_engine_cairo_x11_polygon_draw(void *data, void *context, void *surface, void *polygon); static void *evas_engine_cairo_x11_gradient_color_add(void *data, void *context, void *gradient, int r, int g, int b, int a, int distance); static void *evas_engine_cairo_x11_gradient_colors_clear(void *data, void *context, void *gradient); -static void evas_engine_cairo_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle); +static void evas_engine_cairo_x11_gradient_free(void *data, void *gradient); +static void evas_engine_cairo_x11_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h); +static void evas_engine_cairo_x11_gradient_type_set(void *data, void *gradient, char *name); +static void evas_engine_cairo_x11_gradient_type_params_set(void *data, void *gradient, char *params); +static void *evas_engine_cairo_x11_gradient_geometry_init(void *data, void *gradient, int spread); +static int evas_engine_cairo_x11_gradient_alpha_get(void *data, void *gradient, int spread); +static void evas_engine_cairo_x11_gradient_map(void *data, void *context, void *gradient, int spread); +static void evas_engine_cairo_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread); static void *evas_engine_cairo_x11_image_load(void *data, char *file, char *key, int *error); static void *evas_engine_cairo_x11_image_new_from_data(void *data, int w, int h, DATA32 *image_data); static void *evas_engine_cairo_x11_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data); @@ -114,6 +125,10 @@ Evas_Func evas_engine_cairo_x11_func = evas_engine_cairo_x11_context_multiplier_get, evas_engine_cairo_x11_context_cutout_add, evas_engine_cairo_x11_context_cutout_clear, + evas_engine_cairo_x11_context_anti_alias_set, + evas_engine_cairo_x11_context_anti_alias_get, + evas_engine_cairo_x11_context_color_interpolation_set, + evas_engine_cairo_x11_context_color_interpolation_get, /* rectangle draw funcs */ evas_engine_cairo_x11_rectangle_draw, /* line draw funcs */ @@ -125,6 +140,13 @@ Evas_Func evas_engine_cairo_x11_func = /* gradient draw funcs */ evas_engine_cairo_x11_gradient_color_add, evas_engine_cairo_x11_gradient_colors_clear, + evas_engine_cairo_x11_gradient_free, + evas_engine_cairo_x11_gradient_fill_set, + evas_engine_cairo_x11_gradient_type_set, + evas_engine_cairo_x11_gradient_type_params_set, + evas_engine_cairo_x11_gradient_geometry_init, + evas_engine_cairo_x11_gradient_alpha_get, + evas_engine_cairo_x11_gradient_map, evas_engine_cairo_x11_gradient_draw, /* image draw funcs */ evas_engine_cairo_x11_image_load, @@ -520,6 +542,40 @@ evas_engine_cairo_x11_context_cutout_clear(void *data, void *context) /* not used in cairo engine */ } +static void +evas_engine_cairo_x11_context_anti_alias_set(void *data, void *context, unsigned char aa) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +} + +static unsigned char +evas_engine_cairo_x11_context_anti_alias_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return 1; +} + +static void +evas_engine_cairo_x11_context_color_interpolation_set(void *data, void *context, int color_space) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +} + +static int +evas_engine_cairo_x11_context_color_interpolation_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return 0; +} + static void evas_engine_cairo_x11_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h) { @@ -675,6 +731,64 @@ evas_engine_cairo_x11_gradient_colors_clear(void *data, void *context, void *gra return NULL; } +static void +evas_engine_cairo_x11_gradient_free(void *data, void *gradient) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +} + +static void +evas_engine_cairo_x11_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +} + +static void +evas_engine_cairo_x11_gradient_type_set(void *data, void *gradient, char *name) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +} + +static void +evas_engine_cairo_x11_gradient_type_params_set(void *data, void *gradient, char *params) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +} + +static void * +evas_engine_cairo_x11_gradient_geometry_init(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return gradient; +} + +static int +evas_engine_cairo_x11_gradient_alpha_get(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return 1; +} + +static void +evas_engine_cairo_x11_gradient_map(void *data, void *context, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +} + static void evas_engine_cairo_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle) { diff --git a/legacy/evas/src/lib/engines/common/Makefile.am b/legacy/evas/src/lib/engines/common/Makefile.am index e3271a8458..b3a4f44ebe 100644 --- a/legacy/evas/src/lib/engines/common/Makefile.am +++ b/legacy/evas/src/lib/engines/common/Makefile.am @@ -37,6 +37,11 @@ evas_font_load.c \ evas_font_main.c \ evas_font_query.c \ evas_gradient_main.c \ +evas_gradient_linear.c \ +evas_gradient_radial.c \ +evas_gradient_angular.c \ +evas_gradient_rectangular.c \ +evas_gradient_sinusoidal.c \ evas_image_load.c \ evas_image_save.c \ evas_image_main.c \ diff --git a/legacy/evas/src/lib/engines/common/evas_blend_alpha_color_pixel.c b/legacy/evas/src/lib/engines/common/evas_blend_alpha_color_pixel.c index ddd17eae48..4c358dff56 100644 --- a/legacy/evas/src/lib/engines/common/evas_blend_alpha_color_pixel.c +++ b/legacy/evas/src/lib/engines/common/evas_blend_alpha_color_pixel.c @@ -4,179 +4,620 @@ #include "evas_mmx.h" #endif +// extern DATA8 *_evas_pow_lut; extern const DATA8 _evas_pow_lut[65536]; extern const DATA16 _evas_const_c1[4]; #ifdef BUILD_C void -evas_common_blend_alpha_color_rgba_to_rgb_c (DATA8 *src, DATA32 *dst, int len, DATA32 col) +evas_common_blend_alpha_color_rgba_to_rgba_c (DATA8 *mask, DATA32 *dst, int len, DATA32 col) { - DATA8 *src_ptr; - DATA32 *dst_ptr, *dst_end_ptr; + DATA32 *dst_end = dst + len, ca = A_VAL(&col); - src_ptr = src; - dst_ptr = dst; - dst_end_ptr = dst + len; - - if (A_VAL(&col) == 0) return; - - while (dst_ptr < dst_end_ptr) + ca += ca >> 7; + mask--; dst--; + while (++mask, ++dst < dst_end) { - DATA32 tmp; - DATA8 aa; + DATA32 a = *mask; - aa = (((*src_ptr) +1) * A_VAL(&col)) >> 8; - switch (aa) + switch (a) { case 0: - break; + break; case 255: - *dst_ptr = col; - break; + { + DATA32 da = A_VAL(dst); + + switch(da) + { + case 0: + *dst = col; + break; + case 255: + *dst += RGB_JOIN( ((R_VAL(&col) - R_VAL(dst)) * ca) >> 8, + ((G_VAL(&col) - G_VAL(dst)) * ca) >> 8, + ((B_VAL(&col) - B_VAL(dst)) * ca) >> 8 ); + break; + default: + da = _evas_pow_lut[(A_VAL(&col) << 8) | da]; + da += da >> 7; + *dst += ARGB_JOIN( ((255 - A_VAL(dst)) * ca) >> 8, + ((R_VAL(&col) - R_VAL(dst)) * da) >> 8, + ((G_VAL(&col) - G_VAL(dst)) * da) >> 8, + ((B_VAL(&col) - B_VAL(dst)) * da) >> 8 ); + break; + } + } + break; default: - BLEND_ALPHA_SETUP(aa, tmp); - BLEND_COLOR(aa, R_VAL(dst_ptr), - R_VAL(&col), R_VAL(dst_ptr), - tmp); - BLEND_COLOR(aa, G_VAL(dst_ptr), - G_VAL(&col), G_VAL(dst_ptr), - tmp); - BLEND_COLOR(aa, B_VAL(dst_ptr), - B_VAL(&col), B_VAL(dst_ptr), - tmp); - break; + { + DATA32 da = A_VAL(dst); + + a = (a * ca) >> 8; + switch(da) + { + case 0: + *dst = (col & 0x00ffffff) | (a << 24); + break; + case 255: + a += a >> 7; + *dst += RGB_JOIN( ((R_VAL(&col) - R_VAL(dst)) * a) >> 8, + ((G_VAL(&col) - G_VAL(dst)) * a) >> 8, + ((B_VAL(&col) - B_VAL(dst)) * a) >> 8 ); + break; + default: + da = _evas_pow_lut[(a << 8) | da]; + da += da >> 7; a += a >> 7; + *dst += ARGB_JOIN( ((255 - A_VAL(dst)) * a) >> 8, + ((R_VAL(&col) - R_VAL(dst)) * da) >> 8, + ((G_VAL(&col) - G_VAL(dst)) * da) >> 8, + ((B_VAL(&col) - B_VAL(dst)) * da) >> 8 ); + break; + } + } + break; + } + } +} + +void +evas_common_blend_alpha_color_rgb_to_rgba_c (DATA8 *mask, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + + mask--; dst--; + while (++mask, ++dst < dst_end) + { + DATA32 a = *mask; + + switch (a) + { + case 0: + break; + case 255: + *dst = col; + break; + default: + { + DATA32 da = A_VAL(dst); + + switch(da) + { + case 0: + *dst = (col & 0x00ffffff) | (a << 24); + break; + case 255: + a += a >> 7; + *dst += RGB_JOIN( ((R_VAL(&col) - R_VAL(dst)) * a) >> 8, + ((G_VAL(&col) - G_VAL(dst)) * a) >> 8, + ((B_VAL(&col) - B_VAL(dst)) * a) >> 8 ); + break; + default: + da = _evas_pow_lut[(a << 8) | da]; + da += da >> 7; a += a >> 7; + *dst += ARGB_JOIN( ((255 - A_VAL(dst)) * a) >> 8, + ((R_VAL(&col) - R_VAL(dst)) * da) >> 8, + ((G_VAL(&col) - G_VAL(dst)) * da) >> 8, + ((B_VAL(&col) - B_VAL(dst)) * da) >> 8 ); + break; + } + } + break; + } + } +} + +void +evas_common_blend_alpha_color_rgba_to_rgb_c (DATA8 *mask, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len, ca = A_VAL(&col); + + ca += ca >> 7; + mask--; dst--; + while (++mask, ++dst < dst_end) + { + DATA32 a = *mask; + + switch (a) + { + case 0: + break; + case 255: + *dst += RGB_JOIN( ((R_VAL(&col) - R_VAL(dst)) * ca) >> 8, + ((G_VAL(&col) - G_VAL(dst)) * ca) >> 8, + ((B_VAL(&col) - B_VAL(dst)) * ca) >> 8 ); + break; + default: + a = (a * ca) >> 8; + a += a >> 7; + *dst += RGB_JOIN( ((R_VAL(&col) - R_VAL(dst)) * a) >> 8, + ((G_VAL(&col) - G_VAL(dst)) * a) >> 8, + ((B_VAL(&col) - B_VAL(dst)) * a) >> 8 ); + break; + } + } +} + +void +evas_common_blend_alpha_color_rgb_to_rgb_c (DATA8 *mask, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + + mask--; dst--; + while (++mask, ++dst < dst_end) + { + DATA32 a = *mask; + + switch (a) + { + case 0: + break; + case 255: + *dst = (*dst | 0x00ffffff) & col; + break; + default: + a += a >> 7; + *dst += RGB_JOIN( ((R_VAL(&col) - R_VAL(dst)) * a) >> 8, + ((G_VAL(&col) - G_VAL(dst)) * a) >> 8, + ((B_VAL(&col) - B_VAL(dst)) * a) >> 8 ); + break; } - src_ptr++; - dst_ptr++; } } #endif +/* ************************************************************************** */ + #ifdef BUILD_MMX void -evas_common_blend_alpha_color_rgba_to_rgb_mmx (DATA8 *src, DATA32 *dst, int len, DATA32 col) +evas_common_blend_alpha_color_rgba_to_rgba_mmx (DATA8 *mask, DATA32 *dst, int len, DATA32 col) { - DATA8 *src_ptr; - DATA32 *dst_ptr, *dst_end_ptr; + DATA32 *dst_end = dst + len; - if (A_VAL(&col) == 0) return; + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); - src_ptr = src; - dst_ptr = dst; - dst_end_ptr = dst + len; + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); - pxor_r2r(mm6, mm6); + movq_r2r(mm3, mm5); + + len = A_VAL(&col); + col |= 0xff000000; movd_m2r(col, mm1); - punpcklbw_r2r(mm1, mm6); - psrlw_i2r(8, mm6); - movq_m2r(*_evas_const_c1, mm5); - paddw_r2r(mm5, mm6); + punpcklbw_r2r(mm0, mm1); + A_VAL(&col) = len; - pxor_r2r(mm4, mm4); - - while (dst_ptr < dst_end_ptr) + mask--; dst--; + while (++mask, ++dst < dst_end) { - DATA32 tmp; - DATA8 aa; + DATA32 a = *mask; - aa = (((*src_ptr) +1) * A_VAL(&col)) >> 8; - switch (aa) + switch (a) { case 0: - break; + break; case 255: - *dst_ptr = col; - break; + { + DATA32 da = A_VAL(dst); + + switch(da) + { + case 0: + *dst = col; + break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movq_r2r(mm1, mm3); + psubw_r2r(mm2, mm3); + psllw_i2r(1, mm3); + paddw_r2r(mm6, mm3); + pmulhw_r2r(mm5, mm3); + paddw_r2r(mm3, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + default: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + da = _evas_pow_lut[(A_VAL(&col) << 8) + da]; + da = ARGB_JOIN(A_VAL(&col), da, da, da); + movd_m2r(da, mm3); + punpcklbw_r2r(mm3, mm3); // mm3 = [AA][dAdA][dAdA][dAdA] + psrlw_i2r(1, mm3); + + movq_r2r(mm1, mm4); + psubw_r2r(mm2, mm4); + psllw_i2r(1, mm4); + paddw_r2r(mm6, mm4); + + pmulhw_r2r(mm3, mm4); + paddw_r2r(mm4, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + } + } + break; default: - tmp = 0xffffff; - A_VAL(&tmp) = *src_ptr; + { + DATA32 da = A_VAL(dst); - movd_m2r(tmp, mm1); + a = RGB_JOIN(a,a,a); + movd_m2r(a, mm3); + punpcklbw_r2r(mm0, mm3); + psllw_i2r(1, mm3); + paddw_r2r(mm6, mm3); + pmulhw_r2r(mm5, mm3); + + packuswb_r2r(mm0, mm3); + movd_r2m(mm3, a); + a &= 0xff; + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + switch(da) + { + case 0: + *dst = (col & 0x00ffffff) | (a << 24); + break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); - /* this could be more optimial.. but it beats the c code by almost */ - /* double */ - pxor_r2r(mm7, mm7); - punpcklbw_r2r(mm1, mm7); - psrlw_i2r(8, mm7); - pmullw_r2r(mm6, mm7); - psrlw_i2r(8, mm7); - packuswb_r2r(mm7, mm7); - movq_r2r(mm7, mm1); - /* and back to our normal programming... */ - movd_m2r(dst_ptr[0], mm2); + movq_r2r(mm1, mm4); + psubw_r2r(mm2, mm4); + psllw_i2r(1, mm4); + paddw_r2r(mm6, mm4); + + pmulhw_r2r(mm3, mm4); + paddw_r2r(mm4, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); - movq_r2r(mm1, mm3); + break; + default: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); - punpcklbw_r2r(mm3, mm3); - punpckhwd_r2r(mm3, mm3); - punpckhdq_r2r(mm3, mm3); - psrlw_i2r(1, mm3); + da = _evas_pow_lut[(a << 8) + da]; + da = ARGB_JOIN(a, da, da, da); + movd_m2r(da, mm3); + punpcklbw_r2r(mm3, mm3); // mm3 = [AA][dAdA][dAdA][dAdA] + psrlw_i2r(1, mm3); -// psrlq_i2r(16, mm3); + movq_r2r(mm1, mm4); + psubw_r2r(mm2, mm4); + psllw_i2r(1, mm4); + paddw_r2r(mm6, mm4); + + pmulhw_r2r(mm3, mm4); + paddw_r2r(mm4, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); - punpcklbw_r2r(mm4, mm1); - punpcklbw_r2r(mm4, mm2); - - psubw_r2r(mm2, mm1); - psllw_i2r(1, mm1); - paddw_r2r(mm5, mm1); - pmulhw_r2r(mm3, mm1); - paddw_r2r(mm1, mm2); - - packuswb_r2r(mm4, mm2); - movd_r2m(mm2, dst_ptr[0]); - break; + break; + } + } + break; + } + } +} + +void +evas_common_blend_alpha_color_rgb_to_rgba_mmx (DATA8 *mask, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + movd_m2r(col, mm1); + punpcklbw_r2r(mm0, mm1); + + mask--; dst--; + while (++mask, ++dst < dst_end) + { + DATA32 a = *mask; + + switch (a) + { + case 0: + break; + case 255: + *dst = col; + break; + default: + { + DATA32 da = A_VAL(dst); + + switch(da) + { + case 0: + *dst = (col & 0x00ffffff) | (a << 24); + break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + a = a << 24; + movd_m2r(a, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm1, mm4); + psubw_r2r(mm2, mm4); + psllw_i2r(1, mm4); + paddw_r2r(mm6, mm4); + + pmulhw_r2r(mm3, mm4); + paddw_r2r(mm4, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + default: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + da = _evas_pow_lut[(a << 8) + da]; + da = ARGB_JOIN(a, da, da, da); + movd_m2r(da, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm1, mm4); + psubw_r2r(mm2, mm4); + psllw_i2r(1, mm4); + paddw_r2r(mm6, mm4); + + pmulhw_r2r(mm3, mm4); + paddw_r2r(mm4, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + } + } + break; + } + } +} + +void +evas_common_blend_alpha_color_rgba_to_rgb_mmx (DATA8 *mask, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + movq_r2r(mm3, mm5); + + col |= 0xff000000; + movd_m2r(col, mm1); + punpcklbw_r2r(mm0, mm1); + + mask--; dst--; + while (++mask, ++dst < dst_end) + { + DATA32 a = *mask; + + switch (a) + { + case 0: + break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movq_r2r(mm1, mm3); + psubw_r2r(mm2, mm3); // mm3 = [A-a][R-r][G-g][B-b] + psllw_i2r(1, mm3); // mm3 = [A*2][R*2][G*2][B*2] + paddw_r2r(mm6, mm3); // mm3 = [A+1][R+1][G+1][B+1] + pmulhw_r2r(mm5, mm3); // mm3 = [A*0][(R*AA)>>16][(G*AA)>>16][(B*AA)>>16] + paddw_r2r(mm3, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + default: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + a = RGB_JOIN(a,a,a); + movd_m2r(a, mm3); + punpcklbw_r2r(mm0, mm3); + psllw_i2r(1, mm3); + paddw_r2r(mm6, mm3); + pmulhw_r2r(mm5, mm3); + + packuswb_r2r(mm0, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm1, mm4); + psubw_r2r(mm2, mm4); + psllw_i2r(1, mm4); + paddw_r2r(mm6, mm4); + + pmulhw_r2r(mm3, mm4); + paddw_r2r(mm4, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + } + } +} + +void +evas_common_blend_alpha_color_rgb_to_rgb_mmx (DATA8 *mask, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + col &= 0x00ffffff; + movd_m2r(col, mm1); + punpcklbw_r2r(mm0, mm1); + + mask--; dst--; + while (++mask, ++dst < dst_end) + { + DATA32 a = *mask; + + switch (a) + { + case 0: + break; + case 255: + *dst = (*dst & 0xff000000) | col; + break; + default: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + a = a << 24; + movd_m2r(a, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); +// psrlq_i2r(16, mm3); + + movq_r2r(mm1, mm4); + psubw_r2r(mm2, mm4); + psllw_i2r(1, mm4); + paddw_r2r(mm6, mm4); + + pmulhw_r2r(mm3, mm4); + paddw_r2r(mm4, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; } - src_ptr++; - dst_ptr++; } } #endif -void -evas_common_blend_alpha_color_rgba_to_rgba_c (DATA8 *src, DATA32 *dst, int len, DATA32 col) +/* ************************************************************************** */ + +static void +evas_common_blend_alpha_color_nothing (DATA8 *mask, DATA32 *dst, int len, DATA32 col) { - DATA8 *src_ptr; - DATA32 *dst_ptr, *dst_end_ptr; - - if (A_VAL(&col) == 0) return; - - src_ptr = src; - dst_ptr = dst; - dst_end_ptr = dst + len; - - while (dst_ptr < dst_end_ptr) - { - DATA32 tmp; - DATA8 a, aa; - - aa = (((*src_ptr) + 1) * A_VAL(&col)) >> 8; - switch (aa) - { - case 0: - break; - case 255: - *dst_ptr = col; - break; - default: - BLEND_ADST_ALPHA_SETUP(aa, tmp); - a = _evas_pow_lut[(aa << 8) | A_VAL(dst_ptr)]; - BLEND_ADST_COLOR(aa, A_VAL(dst_ptr), - 255, A_VAL(dst_ptr), - tmp); - BLEND_ADST_ALPHA_SETUP(a, tmp); - BLEND_ADST_COLOR(a, R_VAL(dst_ptr), - R_VAL(&col), R_VAL(dst_ptr), - tmp); - BLEND_ADST_COLOR(a, G_VAL(dst_ptr), - G_VAL(&col), G_VAL(dst_ptr), - tmp); - BLEND_ADST_COLOR(a, B_VAL(dst_ptr), - B_VAL(&col), B_VAL(dst_ptr), - tmp); - break; - } - src_ptr++; - dst_ptr++; - } } +/* ************************************************************************** */ + +#ifdef BUILD_MMX +static Gfx_Func_Blend_Src_Alpha_Mul_Dst +evas_common_gfx_func_blend_alpha_col_get_mmx(DATA32 col, RGBA_Image *dst) +{ + if (A_VAL(&col) < 255) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_alpha_color_rgba_to_rgba_mmx; + } + return evas_common_blend_alpha_color_rgba_to_rgb_mmx; + } + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_alpha_color_rgb_to_rgba_mmx; + } + return evas_common_blend_alpha_color_rgb_to_rgb_mmx; +} +#endif + +#ifdef BUILD_C +static Gfx_Func_Blend_Src_Alpha_Mul_Dst +evas_common_gfx_func_blend_alpha_col_get_c(DATA32 col, RGBA_Image *dst) +{ + if (A_VAL(&col) < 255) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_alpha_color_rgba_to_rgba_c; + } + return evas_common_blend_alpha_color_rgba_to_rgb_c; + } + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_alpha_color_rgb_to_rgba_c; + } + return evas_common_blend_alpha_color_rgb_to_rgb_c; +} +#endif + +Gfx_Func_Blend_Src_Alpha_Mul_Dst +evas_common_draw_func_blend_alpha_get (DATA32 col, RGBA_Image *dst) +{ + Gfx_Func_Blend_Src_Alpha_Mul_Dst func = NULL; + +#ifdef BUILD_MMX + if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) + { + func = evas_common_gfx_func_blend_alpha_col_get_mmx(col, dst); + if (func) return func; + } +#endif +#ifdef BUILD_C + func = evas_common_gfx_func_blend_alpha_col_get_c(col, dst); + if (func) return func; +#endif + return evas_common_blend_alpha_color_nothing; +} + diff --git a/legacy/evas/src/lib/engines/common/evas_blend_color_pixel.c b/legacy/evas/src/lib/engines/common/evas_blend_color_pixel.c index 09e9f6f4e5..0b58bafaba 100644 --- a/legacy/evas/src/lib/engines/common/evas_blend_color_pixel.c +++ b/legacy/evas/src/lib/engines/common/evas_blend_color_pixel.c @@ -4,151 +4,214 @@ #include "evas_mmx.h" #endif -extern const DATA8 _evas_pow_lut[65536]; +// extern DATA8 *_evas_pow_lut; +extern const DATA8 _evas_pow_lut[65536]; extern const DATA16 _evas_const_c1[4]; #ifdef BUILD_C void -evas_common_blend_color_rgba_to_rgb_c(DATA32 src, DATA32 *dst, int len) +evas_common_blend_color_rgba_to_rgba_c(DATA32 col, DATA32 *dst, int len) { - DATA32 *dst_ptr, *dst_end_ptr; + DATA32 *dst_end = dst + len, ca = A_VAL(&col); - dst_ptr = dst; - dst_end_ptr = dst + len; - - while (dst_ptr < dst_end_ptr) + ca += ca >> 7; + dst--; + while (++dst < dst_end) { - DATA32 tmp; + DATA32 da = A_VAL(dst); - BLEND_ALPHA_SETUP(A_VAL(&src), tmp); - BLEND_COLOR(A_VAL(&src), R_VAL(dst_ptr), - R_VAL(&src), R_VAL(dst_ptr), - tmp); - BLEND_COLOR(A_VAL(&src), G_VAL(dst_ptr), - G_VAL(&src), G_VAL(dst_ptr), - tmp); - BLEND_COLOR(A_VAL(&src), B_VAL(dst_ptr), - B_VAL(&src), B_VAL(dst_ptr), - tmp); - dst_ptr++; + switch(da) + { + case 0: + *dst = col; + break; + case 255: + *dst += RGB_JOIN( ((R_VAL(&col) - R_VAL(dst)) * ca) >> 8, + ((G_VAL(&col) - G_VAL(dst)) * ca) >> 8, + ((B_VAL(&col) - B_VAL(dst)) * ca) >> 8 ); + break; + default: + da = _evas_pow_lut[(A_VAL(&col) << 8) | da]; + da += da >> 7; + *dst += ARGB_JOIN( ((255 - A_VAL(dst)) * ca) >> 8, + ((R_VAL(&col) - R_VAL(dst)) * da) >> 8, + ((G_VAL(&col) - G_VAL(dst)) * da) >> 8, + ((B_VAL(&col) - B_VAL(dst)) * da) >> 8 ); + break; + } } } + +void +evas_common_blend_color_rgba_to_rgb_c(DATA32 col, DATA32 *dst, int len) +{ + DATA32 *dst_end = dst + len, ca = A_VAL(&col); + + ca += ca >> 7; + while (dst < dst_end) + *dst++ += RGB_JOIN( ((R_VAL(&col) - R_VAL(dst)) * ca) >> 8, + ((G_VAL(&col) - G_VAL(dst)) * ca) >> 8, + ((B_VAL(&col) - B_VAL(dst)) * ca) >> 8 ); +} + +void +evas_common_copy_color_rgba_to_rgba_c(DATA32 col, DATA32 *dst, int len) +{ + DATA32 *dst_end = dst + len; + + while (dst < dst_end) + *dst++ = col; +} + +void +evas_common_copy_color_rgb_to_rgba_c(DATA32 col, DATA32 *dst, int len) +{ + DATA32 *dst_end = dst + len; + + col |= PIXEL_SOLID_ALPHA; + + while (dst < dst_end) + *dst++ = col; +} + +void +evas_common_copy_color_rgb_to_rgb_c(DATA32 col, DATA32 *dst, int len) +{ + DATA32 *dst_end = dst + len; + + while (dst < dst_end) + *dst++ = col & (*dst | 0x00ffffff); +} #endif +/****************************************************************************/ + #ifdef BUILD_MMX void -evas_common_blend_color_rgba_to_rgb_mmx(DATA32 src, DATA32 *dst, int len) +evas_common_blend_color_rgba_to_rgba_mmx(DATA32 col, DATA32 *dst, int len) { - DATA32 *dst_ptr, *dst_end_ptr; + DATA32 *dst_end = dst + len; - dst_ptr = dst; - dst_end_ptr = dst + len; + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); - pxor_r2r(mm4, mm4); - movq_m2r(*_evas_const_c1, mm5); - - movd_m2r(src, mm6); - - movq_r2r(mm6, mm3); + movd_m2r(col, mm3); + movd_m2r(col, mm3); punpcklbw_r2r(mm3, mm3); punpckhwd_r2r(mm3, mm3); punpckhdq_r2r(mm3, mm3); psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); -// psrlq_i2r(16, mm3); + movq_r2r(mm3, mm5); - while (dst_ptr < dst_end_ptr) + len = A_VAL(&col); + col |= 0xff000000; + movd_m2r(col, mm1); + punpcklbw_r2r(mm0, mm1); + A_VAL(&col) = len; + + dst--; + while (++dst < dst_end) { - movq_r2r(mm6, mm1); + DATA32 da = A_VAL(dst); - movd_m2r(dst_ptr[0], mm2); + switch(da) + { + case 0: + *dst = col; + break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movq_r2r(mm1, mm3); + psubw_r2r(mm2, mm3); + psllw_i2r(1, mm3); + paddw_r2r(mm6, mm3); + pmulhw_r2r(mm5, mm3); + paddw_r2r(mm3, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); - punpcklbw_r2r(mm4, mm1); - punpcklbw_r2r(mm4, mm2); + break; + default: + da = _evas_pow_lut[(A_VAL(&col) << 8) + da]; + da = ARGB_JOIN(A_VAL(&col), da, da, da); + movd_m2r(da, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); - psubw_r2r(mm2, mm1); - psllw_i2r(1, mm1); - paddw_r2r(mm5, mm1); - pmulhw_r2r(mm3, mm1); - paddw_r2r(mm1, mm2); + movq_r2r(mm1, mm4); + psubw_r2r(mm2, mm4); + psllw_i2r(1, mm4); + paddw_r2r(mm6, mm4); + + pmulhw_r2r(mm3, mm4); + paddw_r2r(mm4, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); - packuswb_r2r(mm4, mm2); - movd_r2m(mm2, dst_ptr[0]); - - dst_ptr++; + break; + } } } -#endif - -/****************************************************************************/ void -evas_common_blend_color_rgba_to_rgba_c(DATA32 src, DATA32 *dst, int len) +evas_common_blend_color_rgba_to_rgb_mmx(DATA32 col, DATA32 *dst, int len) { - DATA32 *dst_ptr, *dst_end_ptr; + DATA32 *dst_end = dst + len; - dst_ptr = dst; - dst_end_ptr = dst + len; + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); - while (dst_ptr < dst_end_ptr) + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + movq_r2r(mm3, mm5); + + col |= 0xff000000; + movd_m2r(col, mm1); + punpcklbw_r2r(mm0, mm1); + + dst--; + while (++dst < dst_end) { - DATA32 tmp; - DATA8 a; - - BLEND_ADST_ALPHA_SETUP(A_VAL(&src), tmp); - a = _evas_pow_lut[(A_VAL(&src) << 8) | A_VAL(dst_ptr)]; - BLEND_ADST_COLOR(A_VAL(&src), A_VAL(dst_ptr), - 255, A_VAL(dst_ptr), - tmp); - BLEND_ADST_ALPHA_SETUP(a, tmp); - BLEND_ADST_COLOR(a, R_VAL(dst_ptr), - R_VAL(&src), R_VAL(dst_ptr), - tmp); - BLEND_ADST_COLOR(a, G_VAL(dst_ptr), - G_VAL(&src), G_VAL(dst_ptr), - tmp); - BLEND_ADST_COLOR(a, B_VAL(dst_ptr), - B_VAL(&src), B_VAL(dst_ptr), - tmp); - - dst_ptr++; + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movq_r2r(mm1, mm3); + psubw_r2r(mm2, mm3); + psllw_i2r(1, mm3); + paddw_r2r(mm6, mm3); + pmulhw_r2r(mm5, mm3); + paddw_r2r(mm3, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); } } -/****************************************************************************/ - -#ifdef BUILD_C void -evas_common_copy_color_rgba_to_rgba_c(DATA32 src, DATA32 *dst, int len) -{ - DATA32 *dst_ptr, *dst_end_ptr; - - dst_ptr = dst; - dst_end_ptr = dst + len; - - while (dst_ptr < dst_end_ptr) - { - *dst_ptr = src; - dst_ptr++; - } -} -#endif - -#ifdef BUILD_MMX -void -evas_common_copy_color_rgba_to_rgba_mmx(DATA32 src, DATA32 *dst, int len) +evas_common_copy_color_rgba_to_rgba_mmx(DATA32 col, DATA32 *dst, int len) { DATA32 *dst_ptr, *dst_end_ptr, *dst_end_ptr_pre; - + dst_ptr = dst; dst_end_ptr = dst + len; dst_end_ptr_pre = dst + ((len / 10) * 10); - movd_m2r(src, mm0); - movd_m2r(src, mm1); + movd_m2r(col, mm0); + movd_m2r(col, mm1); psllq_i2r(32, mm0); por_r2r(mm1, mm0); - + while (dst_ptr < dst_end_ptr_pre) { movq_r2m(mm0, dst_ptr[0]); @@ -160,27 +223,32 @@ evas_common_copy_color_rgba_to_rgba_mmx(DATA32 src, DATA32 *dst, int len) } while (dst_ptr < dst_end_ptr) { - *dst_ptr = src; + *dst_ptr = col; dst_ptr++; } } + +#define evas_common_copy_color_rgb_to_rgb_mmx evas_common_copy_color_rgba_to_rgba_mmx +#define evas_common_copy_color_rgb_to_rgba_mmx evas_common_copy_color_rgba_to_rgba_mmx #endif +/****************************************************************************/ + #ifdef BUILD_SSE void -evas_common_copy_color_rgba_to_rgba_sse(DATA32 src, DATA32 *dst, int len) +evas_common_copy_color_rgba_to_rgba_sse(DATA32 col, DATA32 *dst, int len) { DATA32 *dst_ptr, *dst_end_ptr, *dst_end_ptr_pre; - + dst_ptr = dst; dst_end_ptr = dst + len; dst_end_ptr_pre = dst + ((len / 10) * 10); - movd_m2r(src, mm0); - movd_m2r(src, mm1); + movd_m2r(col, mm0); + movd_m2r(col, mm1); psllq_i2r(32, mm0); por_r2r(mm1, mm0); - + while (dst_ptr < dst_end_ptr_pre) { prefetch(&dst_ptr[128]); @@ -193,27 +261,104 @@ evas_common_copy_color_rgba_to_rgba_sse(DATA32 src, DATA32 *dst, int len) } while (dst_ptr < dst_end_ptr) { - *dst_ptr = src; + *dst_ptr = col; dst_ptr++; } } + +#define evas_common_blend_color_rgba_to_rgba_sse NULL +#define evas_common_blend_color_rgba_to_rgb_sse NULL +#define evas_common_copy_color_rgb_to_rgb_sse evas_common_copy_color_rgba_to_rgba_sse +#define evas_common_copy_color_rgb_to_rgba_sse evas_common_copy_color_rgba_to_rgba_sse #endif /****************************************************************************/ -void -evas_common_copy_color_rgb_to_rgba_c(DATA32 src, DATA32 *dst, int len) +static void +evas_common_blend_color_nothing(DATA32 col, DATA32 *dst, int len) { - DATA32 *dst_ptr, *dst_end_ptr; - - dst_ptr = dst; - dst_end_ptr = dst + len; - - src |= PIXEL_SOLID_ALPHA; - - while (dst_ptr < dst_end_ptr) - { - *dst_ptr = src; - dst_ptr++; - } } + +/****************************************************************************/ + +#ifdef BUILD_SSE +static Gfx_Func_Blend_Color_Dst +evas_common_gfx_func_blend_col_get_sse(DATA32 col, RGBA_Image *dst, int pixels) +{ + if (A_VAL(&col) < 255) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + return evas_common_blend_color_rgba_to_rgba_sse; + return evas_common_blend_color_rgba_to_rgb_sse; + } + if (pixels <= 65536) return NULL; + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + return evas_common_copy_color_rgb_to_rgba_sse; + return evas_common_copy_color_rgb_to_rgb_sse; +} +#endif + +#ifdef BUILD_MMX +static Gfx_Func_Blend_Color_Dst +evas_common_gfx_func_blend_col_get_mmx(DATA32 col, RGBA_Image *dst, int pixels) +{ + if (A_VAL(&col) < 255) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_color_rgba_to_rgba_mmx; + } + return evas_common_blend_color_rgba_to_rgb_mmx; + } + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + return evas_common_copy_color_rgb_to_rgba_mmx; + return evas_common_copy_color_rgb_to_rgb_mmx; +} +#endif + +#ifdef BUILD_C +static Gfx_Func_Blend_Color_Dst +evas_common_gfx_func_blend_col_get_c(DATA32 col, RGBA_Image *dst, int pixels) +{ + if (A_VAL(&col) < 255) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_color_rgba_to_rgba_c; + } + return evas_common_blend_color_rgba_to_rgb_c; + } + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + return evas_common_copy_color_rgb_to_rgba_c; + return evas_common_copy_color_rgb_to_rgb_c; +} +#endif + +Gfx_Func_Blend_Color_Dst +evas_common_draw_func_blend_color_get (DATA32 col, RGBA_Image *dst, int pixels) +{ + Gfx_Func_Blend_Color_Dst func = NULL; + +#ifdef BUILD_SSE + if (evas_common_cpu_has_feature(CPU_FEATURE_SSE)) + { + func = evas_common_gfx_func_blend_col_get_sse(col, dst, pixels); + if (func) return func; + } +#endif +#ifdef BUILD_MMX + if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) + { + func = evas_common_gfx_func_blend_col_get_mmx(col, dst, pixels); + if (func) return func; + } +#endif +#ifdef BUILD_C + func = evas_common_gfx_func_blend_col_get_c(col, dst, pixels); + if (func) return func; +#endif + return evas_common_blend_color_nothing; +} + diff --git a/legacy/evas/src/lib/engines/common/evas_blend_main.c b/legacy/evas/src/lib/engines/common/evas_blend_main.c index 62328b6379..0316ed71c5 100644 --- a/legacy/evas/src/lib/engines/common/evas_blend_main.c +++ b/legacy/evas/src/lib/engines/common/evas_blend_main.c @@ -288,6 +288,7 @@ evas_common_blend_init_evas_pow_lut(void) /* int i, j; + if (_evas_pow_lut) return; _evas_pow_lut = malloc(256 * 256); if (!_evas_pow_lut) return; printf("const DATA8 _evas_pow_lut[65536] = {\n"); @@ -308,3 +309,15 @@ evas_common_blend_init_evas_pow_lut(void) printf("};\n"); */ } + +void +evas_common_blend_free_evas_pow_lut(void) +{ + return; +/* + if (!_evas_pow_lut) return; + free(_evas_pow_lut); + _evas_pow_lut = NULL; +*/ +} + diff --git a/legacy/evas/src/lib/engines/common/evas_blend_pixel_mul_pixel.c b/legacy/evas/src/lib/engines/common/evas_blend_pixel_mul_pixel.c index a3392ff199..c4cea50688 100644 --- a/legacy/evas/src/lib/engines/common/evas_blend_pixel_mul_pixel.c +++ b/legacy/evas/src/lib/engines/common/evas_blend_pixel_mul_pixel.c @@ -4,263 +4,1588 @@ #include "evas_mmx.h" #endif +// extern DATA8 *_evas_pow_lut; extern const DATA8 _evas_pow_lut[65536]; extern const DATA16 _evas_const_c1[4]; + #ifdef BUILD_C void -evas_common_blend_pixels_mul_color_rgba_to_rgb_c(DATA32 *src, DATA32 *dst, int len, DATA32 mul_color) +evas_common_blend_pixels_rgba_mul_color_rgba_to_rgba_c(DATA32 *src, DATA32 *dst, int len, DATA32 col) { - DATA32 *src_ptr, *dst_ptr, *dst_end_ptr; + DATA32 *dst_end = (dst + len); + DATA32 ca = A_VAL(&col), cr = R_VAL(&col), + cg = G_VAL(&col), cb = B_VAL(&col); - src_ptr = src; - dst_ptr = dst; - dst_end_ptr = dst + len; - - if ((R_VAL(&mul_color) == 255) && - (G_VAL(&mul_color) == 255) && - (B_VAL(&mul_color) == 255)) + ca += ca >>7; cr += cr >> 7; + cg += cg >> 7; cb += cb >> 7; + src--; dst--; + while(++src, ++dst < dst_end) { - while (dst_ptr < dst_end_ptr) - { - DATA32 tmp; - DATA8 a; + DATA32 a = A_VAL(src); - a = (A_VAL(src_ptr) * (A_VAL(&mul_color) + 1)) >> 8; - switch (a) - { - case 0: - break; - case 255: - *dst_ptr = *src_ptr; - break; - default: - BLEND_ALPHA_SETUP(a, tmp); - BLEND_COLOR(a, R_VAL(dst_ptr), - R_VAL(src_ptr), R_VAL(dst_ptr), - tmp); - BLEND_COLOR(a, G_VAL(dst_ptr), - G_VAL(src_ptr), G_VAL(dst_ptr), - tmp); - BLEND_COLOR(a, B_VAL(dst_ptr), - B_VAL(src_ptr), B_VAL(dst_ptr), - tmp); - break; - } - src_ptr++; - dst_ptr++; - } - } - else - { - while (dst_ptr < dst_end_ptr) + switch (a) { - DATA32 tmp; - DATA8 a; + case 0: break; + case 255: + { + DATA32 da = A_VAL(dst); - a = (A_VAL(src_ptr) * (A_VAL(&mul_color) + 1)) >> 8; - switch (a) - { - case 0: - break; - case 255: - R_VAL(dst_ptr) = ((R_VAL(src_ptr) * (R_VAL(&mul_color) + 1)) >> 8); - G_VAL(dst_ptr) = ((G_VAL(src_ptr) * (G_VAL(&mul_color) + 1)) >> 8); - B_VAL(dst_ptr) = ((B_VAL(src_ptr) * (B_VAL(&mul_color) + 1)) >> 8); - break; - default: - BLEND_ALPHA_SETUP(a, tmp); - BLEND_COLOR(a, R_VAL(dst_ptr), - ((R_VAL(src_ptr) * (R_VAL(&mul_color) + 1)) >> 8), R_VAL(dst_ptr), - tmp); - BLEND_COLOR(a, G_VAL(dst_ptr), - ((G_VAL(src_ptr) * (G_VAL(&mul_color) + 1)) >> 8), G_VAL(dst_ptr), - tmp); - BLEND_COLOR(a, B_VAL(dst_ptr), - ((B_VAL(src_ptr) * (B_VAL(&mul_color) + 1)) >> 8), B_VAL(dst_ptr), - tmp); - break; - } - src_ptr++; - dst_ptr++; + switch(da) + { + case 0: + *dst = ARGB_JOIN( A_VAL(&col), + (R_VAL(src) * cr) >> 8, + (G_VAL(src) * cg) >> 8, + (B_VAL(src) * cb) >> 8 ); + break; + case 255: + *dst += RGB_JOIN( ((((R_VAL(src) * cr) >> 8) - R_VAL(dst)) * ca) >> 8, + ((((G_VAL(src) * cg) >> 8) - G_VAL(dst)) * ca) >> 8, + ((((B_VAL(src) * cb) >> 8) - B_VAL(dst)) * ca) >> 8 ); + break; + default: + da = _evas_pow_lut[(A_VAL(&col) << 8) | da]; + da += da >> 7; + *dst += ARGB_JOIN( ((255 - A_VAL(dst)) * ca) >> 8, + ((((R_VAL(src) * cr) >> 8) - R_VAL(dst)) * da) >> 8, + ((((G_VAL(src) * cg) >> 8) - G_VAL(dst)) * da) >> 8, + ((((B_VAL(src) * cb) >> 8) - B_VAL(dst)) * da) >> 8 ); + break; + } + } + break; + default: + { + DATA32 da = A_VAL(dst); + + a = (a * ca) >> 8; + switch(da) + { + case 0: + *dst = ARGB_JOIN( a, + (R_VAL(src) * cr) >> 8, + (G_VAL(src) * cg) >> 8, + (B_VAL(src) * cb) >> 8 ); + break; + case 255: + a += a >> 7; + *dst += RGB_JOIN( ((((R_VAL(src) * cr) >> 8) - R_VAL(dst)) * a) >> 8, + ((((G_VAL(src) * cg) >> 8) - G_VAL(dst)) * a) >> 8, + ((((B_VAL(src) * cb) >> 8) - B_VAL(dst)) * a) >> 8 ); + break; + default: + da = _evas_pow_lut[(a << 8) | da]; + da += da >> 7; a += a >> 7; + *dst += ARGB_JOIN( ((255 - A_VAL(dst)) * a) >> 8, + ((((R_VAL(src) * cr) >> 8) - R_VAL(dst)) * da) >> 8, + ((((G_VAL(src) * cg) >> 8) - G_VAL(dst)) * da) >> 8, + ((((B_VAL(src) * cb) >> 8) - B_VAL(dst)) * da) >> 8 ); + break; + } + } + break; } } } -#endif -#ifdef BUILD_MMX void -evas_common_blend_pixels_mul_color_rgba_to_rgb_mmx(DATA32 *src, DATA32 *dst, int len, DATA32 mul_color) +evas_common_blend_pixels_rgba_mul_color_rgb_to_rgba_c(DATA32 *src, DATA32 *dst, int len, DATA32 col) { - DATA32 *src_ptr, *dst_ptr, *dst_end_ptr; + DATA32 *dst_end = dst + len; + DATA32 cr = R_VAL(&col), cg = G_VAL(&col), cb = B_VAL(&col); - src_ptr = src; - dst_ptr = dst; - dst_end_ptr = dst + len; - - pxor_r2r(mm6, mm6); - movd_m2r(mul_color, mm1); - punpcklbw_r2r(mm1, mm6); - psrlw_i2r(8, mm6); - movq_m2r(*_evas_const_c1, mm5); - paddw_r2r(mm5, mm6); - - pxor_r2r(mm4, mm4); - - while (dst_ptr < dst_end_ptr) + cr += cr >> 7; cg += cg >> 7; cb += cb >> 7; + src--; dst--; + while(++src, ++dst < dst_end) { - DATA8 a; + DATA32 a = A_VAL(src); - a = (A_VAL(src_ptr) * (A_VAL(&mul_color) + 1)) >> 8; switch (a) { case 0: - break; + break; case 255: - movd_m2r(src_ptr[0], mm1); - - /* this could be more optimial.. but it beats the c code by almost */ - /* double */ - pxor_r2r(mm7, mm7); - punpcklbw_r2r(mm1, mm7); - psrlw_i2r(8, mm7); - pmullw_r2r(mm6, mm7); - psrlw_i2r(8, mm7); - packuswb_r2r(mm7, mm7); - movq_r2r(mm7, mm1); - movd_r2m(mm1, dst_ptr[0]); - break; + *dst = ARGB_JOIN( 255, + (R_VAL(src) * cr) >> 8, + (G_VAL(src) * cg) >> 8, + (B_VAL(src) * cb) >> 8 ); + break; default: - movd_m2r(src_ptr[0], mm1); + { + DATA32 da = A_VAL(dst); - /* this could be more optimial.. but it beats the c code by almost */ - /* double */ - pxor_r2r(mm7, mm7); - punpcklbw_r2r(mm1, mm7); - psrlw_i2r(8, mm7); - pmullw_r2r(mm6, mm7); - psrlw_i2r(8, mm7); - packuswb_r2r(mm7, mm7); - movq_r2r(mm7, mm1); - /* and back to our normal programming... */ - movd_m2r(dst_ptr[0], mm2); - - movq_r2r(mm1, mm3); - - punpcklbw_r2r(mm3, mm3); - punpckhwd_r2r(mm3, mm3); - punpckhdq_r2r(mm3, mm3); - psrlw_i2r(1, mm3); - -// psrlq_i2r(16, mm3); - - punpcklbw_r2r(mm4, mm1); - punpcklbw_r2r(mm4, mm2); - - psubw_r2r(mm2, mm1); - psllw_i2r(1, mm1); - paddw_r2r(mm5, mm1); - pmulhw_r2r(mm3, mm1); - paddw_r2r(mm1, mm2); - - packuswb_r2r(mm4, mm2); - movd_r2m(mm2, dst_ptr[0]); - break; + switch(da) + { + case 0: + *dst = ARGB_JOIN( a, + (R_VAL(src) * cr) >> 8, + (G_VAL(src) * cg) >> 8, + (B_VAL(src) * cb) >> 8 ); + break; + case 255: + a += a >> 7; + *dst += RGB_JOIN( ((((R_VAL(src) * cr) >> 8) - R_VAL(dst)) * a) >> 8, + ((((G_VAL(src) * cg) >> 8) - G_VAL(dst)) * a) >> 8, + ((((B_VAL(src) * cb) >> 8) - B_VAL(dst)) * a) >> 8 ); + break; + default: + da = _evas_pow_lut[(a << 8) | da]; + da += da >> 7; a += a >> 7; + *dst += ARGB_JOIN( ((255 - A_VAL(dst)) * a) >> 8, + ((((R_VAL(src) * cr) >> 8) - R_VAL(dst)) * da) >> 8, + ((((G_VAL(src) * cg) >> 8) - G_VAL(dst)) * da) >> 8, + ((((B_VAL(src) * cb) >> 8) - B_VAL(dst)) * da) >> 8 ); + break; + } + } + break; } - src_ptr++; - dst_ptr++; } } + +void +evas_common_blend_pixels_rgba_mul_color_a_to_rgba_c(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = (dst + len); + DATA32 ca = A_VAL(&col); + + ca += ca >>7; + src--; dst--; + while(++src, ++dst < dst_end) + { + DATA32 a = A_VAL(src); + + switch (a) + { + case 0: break; + case 255: + { + DATA32 da = A_VAL(dst); + + switch(da) + { + case 0: + *dst = (*src & 0x00ffffff) | (A_VAL(&col) << 24); + break; + case 255: + *dst += RGB_JOIN( ((R_VAL(src) - R_VAL(dst)) * ca) >> 8, + ((G_VAL(src) - G_VAL(dst)) * ca) >> 8, + ((B_VAL(src) - B_VAL(dst)) * ca) >> 8 ); + break; + default: + da = _evas_pow_lut[(A_VAL(&col) << 8) | da]; + da += da >> 7; + *dst += ARGB_JOIN( ((255 - A_VAL(dst)) * ca) >> 8, + ((R_VAL(src) - R_VAL(dst)) * da) >> 8, + ((G_VAL(src) - G_VAL(dst)) * da) >> 8, + ((B_VAL(src) - B_VAL(dst)) * da) >> 8 ); + break; + } + } + break; + default: + { + DATA32 da = A_VAL(dst); + + a = (a * ca) >> 8; + switch(da) + { + case 0: + *dst = (*src & 0x00ffffff) | (a << 24); + break; + case 255: + a += a >> 7; + *dst += RGB_JOIN( ((R_VAL(src) - R_VAL(dst)) * a) >> 8, + ((G_VAL(src) - G_VAL(dst)) * a) >> 8, + ((B_VAL(src) - B_VAL(dst)) * a) >> 8 ); + break; + default: + da = _evas_pow_lut[(a << 8) | da]; + da += da >> 7; a += a >> 7; + *dst += ARGB_JOIN( ((255 - A_VAL(dst)) * a) >> 8, + ((R_VAL(src) - R_VAL(dst)) * da) >> 8, + ((G_VAL(src) - G_VAL(dst)) * da) >> 8, + ((B_VAL(src) - B_VAL(dst)) * da) >> 8 ); + break; + } + } + break; + } + } +} + +void +evas_common_blend_pixels_rgb_mul_color_rgba_to_rgba_c(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = (dst + len); + DATA32 ca = A_VAL(&col), cr = R_VAL(&col), + cg = G_VAL(&col), cb = B_VAL(&col); + + ca += ca >>7; cr += cr >> 7; + cg += cg >> 7; cb += cb >> 7; + src--; dst--; + while(++src, ++dst < dst_end) + { + DATA32 da = A_VAL(dst); + + switch (da) + { + case 0: + *dst = ARGB_JOIN( A_VAL(&col), + (R_VAL(src) * cr) >> 8, + (G_VAL(src) * cg) >> 8, + (B_VAL(src) * cb) >> 8 ); + break; + case 255: + *dst += RGB_JOIN( ((((R_VAL(src) * cr) >> 8) - R_VAL(dst)) * ca) >> 8, + ((((G_VAL(src) * cg) >> 8) - G_VAL(dst)) * ca) >> 8, + ((((B_VAL(src) * cb) >> 8) - B_VAL(dst)) * ca) >> 8 ); + break; + default: + da = _evas_pow_lut[(A_VAL(&col) << 8) | da]; + da += da >> 7; + *dst += ARGB_JOIN( ((255 - A_VAL(dst)) * ca) >> 8, + ((((R_VAL(src) * cr) >> 8) - R_VAL(dst)) * da) >> 8, + ((((G_VAL(src) * cg) >> 8) - G_VAL(dst)) * da) >> 8, + ((((B_VAL(src) * cb) >> 8) - B_VAL(dst)) * da) >> 8 ); + break; + } + } +} + +void +evas_common_blend_pixels_rgb_mul_color_a_to_rgba_c(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + DATA32 ca = A_VAL(&col); + + ca += ca >> 7; + src--; dst--; + while (++src, ++dst < dst_end) + { + DATA32 da = A_VAL(dst); + + switch (da) + { + case 0: + *dst = (*src & 0x00ffffff) | (A_VAL(&col) << 24); + break; + case 255: + *dst += RGB_JOIN( ((R_VAL(src) - R_VAL(dst)) * ca) >> 8, + ((G_VAL(src) - G_VAL(dst)) * ca) >> 8, + ((B_VAL(src) - B_VAL(dst)) * ca) >> 8 ); + break; + default: + da = _evas_pow_lut[(A_VAL(&col) << 8) | da]; + da += da >> 7; + *dst += ARGB_JOIN( ((255 - A_VAL(dst)) * ca) >> 8, + ((R_VAL(src) - R_VAL(dst)) * da) >> 8, + ((G_VAL(src) - G_VAL(dst)) * da) >> 8, + ((B_VAL(src) - B_VAL(dst)) * da) >> 8 ); + break; + } + } +} + +void +evas_common_blend_pixels_rgba_mul_color_rgba_to_rgb_c(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = (dst + len); + DATA32 ca = A_VAL(&col), cr = R_VAL(&col), + cg = G_VAL(&col), cb = B_VAL(&col); + + ca += ca >>7; cr += cr >> 7; + cg += cg >> 7; cb += cb >> 7; + src--; dst--; + while(++src, ++dst < dst_end) + { + DATA32 a = A_VAL(src); + + switch (a) + { + case 0: break; + case 255: + *dst += RGB_JOIN( ((((R_VAL(src) * cr) >> 8) - R_VAL(dst)) * ca) >> 8, + ((((G_VAL(src) * cg) >> 8) - G_VAL(dst)) * ca) >> 8, + ((((B_VAL(src) * cb) >> 8) - B_VAL(dst)) * ca) >> 8 ); + break; + default: + a = (a * ca) >> 8; a += a >> 7; + *dst += RGB_JOIN( ((((R_VAL(src) * cr) >> 8) - R_VAL(dst)) * a) >> 8, + ((((G_VAL(src) * cg) >> 8) - G_VAL(dst)) * a) >> 8, + ((((B_VAL(src) * cb) >> 8) - B_VAL(dst)) * a) >> 8 ); + break; + } + } +} + +void +evas_common_blend_pixels_rgba_mul_color_rgb_to_rgb_c(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + DATA32 cr = R_VAL(&col), cg = G_VAL(&col), cb = B_VAL(&col); + + cr += cr >> 7; cg += cg >> 7; cb += cb >> 7; + src--; dst--; + while (++src, ++dst < dst_end) + { + DATA32 a = A_VAL(src); + + switch (a) + { + case 0: + break; + case 255: + *dst = (*dst & 0xff000000) | RGB_JOIN( (R_VAL(src) * cr) >> 8, + (G_VAL(src) * cg) >> 8, + (B_VAL(src) * cb) >> 8 ); + break; + default: + a += a >> 7; + *dst += RGB_JOIN( ((((R_VAL(src) * cr) >> 8) - R_VAL(dst)) * a) >> 8, + ((((G_VAL(src) * cg) >> 8) - G_VAL(dst)) * a) >> 8, + ((((B_VAL(src) * cb) >> 8) - B_VAL(dst)) * a) >> 8 ); + break; + } + } +} + +void +evas_common_blend_pixels_rgb_mul_color_rgba_to_rgb_c(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = (dst + len); + DATA32 ca = A_VAL(&col), cr = R_VAL(&col), + cg = G_VAL(&col), cb = B_VAL(&col); + + ca += ca >>7; cr += cr >> 7; + cg += cg >> 7; cb += cb >> 7; + src--; dst--; + while(++src, ++dst < dst_end) + *dst += RGB_JOIN( ((((R_VAL(src) * cr) >> 8) - R_VAL(dst)) * ca) >> 8, + ((((G_VAL(src) * cg) >> 8) - G_VAL(dst)) * ca) >> 8, + ((((B_VAL(src) * cb) >> 8) - B_VAL(dst)) * ca) >> 8 ); +} + +void +evas_common_blend_pixels_rgba_mul_color_a_to_rgb_c(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = (dst + len); + DATA32 ca = A_VAL(&col); + + ca += ca >>7; + src--; dst--; + while(++src, ++dst < dst_end) + { + DATA32 a = A_VAL(src); + + switch (a) + { + case 0: break; + case 255: + *dst += RGB_JOIN( ((R_VAL(src) - R_VAL(dst)) * ca) >> 8, + ((G_VAL(src) - G_VAL(dst)) * ca) >> 8, + ((B_VAL(src) - B_VAL(dst)) * ca) >> 8 ); + break; + default: + a = (a * ca) >> 8; a += a >> 7; + *dst += RGB_JOIN( ((R_VAL(src) - R_VAL(dst)) * a) >> 8, + ((G_VAL(src) - G_VAL(dst)) * a) >> 8, + ((B_VAL(src) - B_VAL(dst)) * a) >> 8 ); + break; + } + } +} + +void +evas_common_blend_pixels_rgb_mul_color_a_to_rgb_c(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + DATA32 ca = A_VAL(&col); + + ca += ca >> 7; + src--; dst--; + while (++src, ++dst < dst_end) + *dst += RGB_JOIN( ((R_VAL(src) - R_VAL(dst)) * ca) >> 8, + ((G_VAL(src) - G_VAL(dst)) * ca) >> 8, + ((B_VAL(src) - B_VAL(dst)) * ca) >> 8 ); +} + +void +evas_common_copy_pixels_rgb_mul_color_rgb_to_rgba_c(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + DATA32 cr = R_VAL(&col), cg = G_VAL(&col), cb = B_VAL(&col); + + cr += cr >> 7; cg += cg >> 7; cb += cb >> 7; + src--; dst--; + while (++src, ++dst < dst_end) + *dst = ARGB_JOIN( 255, + (R_VAL(src) * cr) >> 8, + (G_VAL(src) * cg) >> 8, + (B_VAL(src) * cb) >> 8 ); +} + +void +evas_common_copy_pixels_rgb_mul_color_rgb_to_rgb_c(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + DATA32 cr = R_VAL(&col), cg = G_VAL(&col), cb = B_VAL(&col); + + cr += cr >> 7; cg += cg >> 7; cb += cb >> 7; + src--; dst--; + while (++src, ++dst < dst_end) + *dst = (*dst & 0xff000000) | RGB_JOIN( (R_VAL(src) * cr) >> 8, + (G_VAL(src) * cg) >> 8, + (B_VAL(src) * cb) >> 8 ); +} #endif /****************************************************************************/ +#ifdef BUILD_MMX void -evas_common_blend_pixels_mul_color_rgba_to_rgba_c(DATA32 *src, DATA32 *dst, int len, DATA32 mul_color) +evas_common_blend_pixels_rgba_mul_color_rgba_to_rgba_mmx(DATA32 *src, DATA32 *dst, int len, DATA32 col) { - DATA32 *src_ptr, *dst_ptr, *dst_end_ptr; + DATA32 *dst_end = dst + len; - src_ptr = src; - dst_ptr = dst; - dst_end_ptr = dst + len; + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); - if ((R_VAL(&mul_color) == 255) && - (G_VAL(&mul_color) == 255) && - (B_VAL(&mul_color) == 255)) + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm3, mm5); + + len = A_VAL(&col); + col |= 0xff000000; + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm3, mm4); + A_VAL(&col) = len; + + src--; dst--; + while (++src, ++dst < dst_end) { - while (dst_ptr < dst_end_ptr) - { - DATA32 tmp; - DATA8 a, aa; + DATA32 a = A_VAL(src); - aa = (A_VAL(src_ptr) * (A_VAL(&mul_color) + 1)) >> 8; - switch (aa) - { - case 0: - break; - case 255: - *dst_ptr = *src_ptr; - break; - default: - BLEND_ADST_ALPHA_SETUP(aa, tmp); - a = _evas_pow_lut[(aa << 8) | A_VAL(dst_ptr)]; - BLEND_ADST_COLOR(aa, A_VAL(dst_ptr), - 255, A_VAL(dst_ptr), - tmp); - BLEND_ADST_ALPHA_SETUP(a, tmp); - BLEND_ADST_COLOR(a, R_VAL(dst_ptr), - R_VAL(src_ptr), R_VAL(dst_ptr), - tmp); - BLEND_ADST_COLOR(a, G_VAL(dst_ptr), - G_VAL(src_ptr), G_VAL(dst_ptr), - tmp); - BLEND_ADST_COLOR(a, B_VAL(dst_ptr), - B_VAL(src_ptr), B_VAL(dst_ptr), - tmp); - break; - } - src_ptr++; - dst_ptr++; - } - } - else - { - while (dst_ptr < dst_end_ptr) + switch (a) { - DATA32 tmp; - DATA8 a, aa; + case 0: + break; + case 255: + { + DATA32 da = A_VAL(dst); - aa = (A_VAL(src_ptr) * (A_VAL(&mul_color) + 1)) >> 8; - switch (aa) - { - case 0: - break; - case 255: - A_VAL(dst_ptr) = 255; - R_VAL(dst_ptr) = ((R_VAL(src_ptr) * (R_VAL(&mul_color) + 1)) >> 8); - G_VAL(dst_ptr) = ((G_VAL(src_ptr) * (G_VAL(&mul_color) + 1)) >> 8); - B_VAL(dst_ptr) = ((B_VAL(src_ptr) * (B_VAL(&mul_color) + 1)) >> 8); - break; - default: - BLEND_ADST_ALPHA_SETUP(aa, tmp); - a = _evas_pow_lut[(aa << 8) | A_VAL(dst_ptr)]; - BLEND_ADST_COLOR(aa, A_VAL(dst_ptr), - 255, A_VAL(dst_ptr), - tmp); - BLEND_ADST_ALPHA_SETUP(a, tmp); - BLEND_ADST_COLOR(a, R_VAL(dst_ptr), - ((R_VAL(src_ptr) * (R_VAL(&mul_color) + 1)) >> 8), R_VAL(dst_ptr), - tmp); - BLEND_ADST_COLOR(a, G_VAL(dst_ptr), - ((G_VAL(src_ptr) * (G_VAL(&mul_color) + 1)) >> 8), G_VAL(dst_ptr), - tmp); - BLEND_ADST_COLOR(a, B_VAL(dst_ptr), - ((B_VAL(src_ptr) * (B_VAL(&mul_color) + 1)) >> 8), B_VAL(dst_ptr), - tmp); - break; - } - src_ptr++; - dst_ptr++; + switch(da) + { + case 0: + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + packuswb_r2r(mm0, mm1); + movd_r2m(mm1, *dst); + + break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + packuswb_r2r(mm0, mm1); + + movq_r2r(mm1, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + default: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm4, mm1); + packuswb_r2r(mm0, mm1); + + da = _evas_pow_lut[(A_VAL(&col) << 8) + da]; + da = ARGB_JOIN(A_VAL(&col), da, da, da); + movd_m2r(da, mm3); + punpcklbw_r2r(mm3, mm3); // mm3 = [AA][dAdA][dAdA][dAdA] + psrlw_i2r(1, mm3); // mm3 = [AA/2][dAdA/2][dAdA/2][dAdA/2] + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + } + } + break; + default: + { + DATA32 da = A_VAL(dst); + + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + packuswb_r2r(mm0, mm1); + + switch(da) + { + case 0: + movd_r2m(mm1, *dst); + + break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movq_r2r(mm1, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + punpcklbw_r2r(mm0, mm1); + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + default: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movd_r2m(mm1, a); + da = _evas_pow_lut[(A_VAL(&a) << 8) + da]; + da = ARGB_JOIN(A_VAL(&a), da, da, da); + movd_m2r(da, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); // mm3 = [AA/2][dAdA/2][dAdA/2][dAdA/2] + + a |= 0xff000000; + movd_m2r(a, mm1); // mm1 = [ ][ ][255R][GB] (COL*SRC) + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + } + } + break; } } } + +void +evas_common_blend_pixels_rgba_mul_color_rgb_to_rgba_mmx(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + col |= 0xff000000; + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm3, mm5); + + src--; dst--; + while (++src, ++dst < dst_end) + { + DATA32 a = A_VAL(src); + + switch (a) + { + case 0: + break; + case 255: + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + packuswb_r2r(mm0, mm1); + movd_r2m(mm1, *dst); + + break; + default: + { + DATA32 da = A_VAL(dst); + + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + packuswb_r2r(mm0, mm1); + + switch(da) + { + case 0: + movd_r2m(mm1, *dst); + + break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movq_r2r(mm1, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + punpcklbw_r2r(mm0, mm1); + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + default: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + da = _evas_pow_lut[(a << 8) | da]; + da = ARGB_JOIN(a, da, da, da); + movd_m2r(da, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movd_r2m(mm1, a); + a |= 0xff000000; + movd_m2r(a, mm1); // mm1 = [ ][ ][255R][GB] (COL*SRC) + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + } + } + break; + } + } +} + +void +evas_common_blend_pixels_rgba_mul_color_a_to_rgba_mmx(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = (dst + len); + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + len = A_VAL(&col); + col &= 0xff000000; + col |= RGB_JOIN(len,len,len); + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm3, mm5); + col |= 0x00ffffff; + + src--; dst--; + while(++src, ++dst < dst_end) + { + DATA32 a = A_VAL(src); + + switch (a) + { + case 0: break; + case 255: + { + DATA32 da = A_VAL(dst); + + switch(da) + { + case 0: + *dst = (*src & col); + break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + a = *src & col; + movd_m2r(a, mm1); + movq_r2r(mm1, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + default: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + + da = _evas_pow_lut[(A_VAL(&col) << 8) + da]; + da = ARGB_JOIN(A_VAL(&col), da, da, da); + movd_m2r(da, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + } + } + break; + default: + { + DATA32 da = A_VAL(dst); + + a = RGB_JOIN(a,a,a); + movd_m2r(a, mm3); + punpcklbw_r2r(mm0, mm3); + psllw_i2r(1, mm3); + paddw_r2r(mm6, mm3); + pmulhw_r2r(mm5, mm3); + + packuswb_r2r(mm0, mm3); + movd_r2m(mm3, a); + a &= 0xff; + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); +// psrlq_i2r(16, mm3); + + switch(da) + { + case 0: + *dst = (*src & 0x00ffffff) | (a << 24); + break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + default: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + da = _evas_pow_lut[(a << 8) + da]; + da = ARGB_JOIN(a, da, da, da); + movd_m2r(da, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + a = *src | 0xff000000; + movd_m2r(a, mm1); + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + } + } + break; + } + } +} + +void +evas_common_blend_pixels_rgb_mul_color_rgba_to_rgba_mmx(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = (dst + len); + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm3, mm5); + + len = A_VAL(&col); + col |= 0xff000000; + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm3, mm4); + A_VAL(&col) = len; + + src--; dst--; + while(++src, ++dst < dst_end) + { + DATA32 da = A_VAL(dst); + + switch (da) + { + case 0: + movd_m2r(*src, mm2); + punpcklbw_r2r(mm0, mm2); + psllw_i2r(1, mm2); + paddw_r2r(mm6, mm2); + pmulhw_r2r(mm5, mm2); + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + packuswb_r2r(mm0, mm1); + + movq_r2r(mm1, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + default: + { + DATA32 a = *src | 0xff000000; + + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movd_m2r(a, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm4, mm1); + packuswb_r2r(mm0, mm1); + + da = _evas_pow_lut[(A_VAL(&col) << 8) + da]; + da = ARGB_JOIN(A_VAL(&col), da, da, da); + movd_m2r(da, mm3); + punpcklbw_r2r(mm3, mm3); // mm3 = [AA][dAdA][dAdA][dAdA] + psrlw_i2r(1, mm3); // mm3 = [AA/2][dAdA/2][dAdA/2][dAdA/2] + + punpcklbw_r2r(mm0, mm1); + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + } + break; + } + } +} + +void +evas_common_blend_pixels_rgb_mul_color_a_to_rgba_mmx(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + col |= 0x00ffffff; + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + movq_r2r(mm3, mm5); + + src--; dst--; + while (++src, ++dst < dst_end) + { + DATA32 da = A_VAL(dst); + + switch (da) + { + case 0: + *dst = (*src | 0xff000000) & col; + break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + default: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + da = _evas_pow_lut[(A_VAL(&col) << 8) | da]; + da = ARGB_JOIN(A_VAL(&col), da, da, da); + movd_m2r(da, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); // mm3 = [AA/2][dAdA/2][dAdA/2][dAdA/2] + + da = *src | 0xff000000; + movd_m2r(da, mm1); + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + } + } +} + +void +evas_common_blend_pixels_rgba_mul_color_rgba_to_rgb_mmx(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = (dst + len); + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm3, mm5); + + src--; dst--; + while(++src, ++dst < dst_end) + { + DATA32 a = A_VAL(src); + + switch (a) + { + case 0: break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + packuswb_r2r(mm0, mm1); + + movq_r2r(mm1, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + default: + + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + packuswb_r2r(mm0, mm1); + + movq_r2r(mm1, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + } + } +} + +void +evas_common_blend_pixels_rgba_mul_color_rgb_to_rgb_mmx(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + col |= 0xff000000; + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm3, mm5); + + src--; dst--; + while (++src, ++dst < dst_end) + { + DATA32 a = A_VAL(src); + + switch (a) + { + case 0: break; + case 255: + a = (*dst | 0x00ffffff) & *src; + movd_m2r(a, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + packuswb_r2r(mm0, mm1); + movd_r2m(mm1, *dst); + + break; + default: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + packuswb_r2r(mm0, mm1); + + movq_r2r(mm1, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + punpcklbw_r2r(mm0, mm1); + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + } + } +} + +void +evas_common_blend_pixels_rgb_mul_color_rgba_to_rgb_mmx(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = (dst + len); + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm3, mm5); + + src--; dst--; + while(++src, ++dst < dst_end) + { + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + packuswb_r2r(mm0, mm1); + + movq_r2r(mm1, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + } +} + +void +evas_common_blend_pixels_rgba_mul_color_a_to_rgb_mmx(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = (dst + len); + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + len = A_VAL(&col); + col &= 0xff000000; + col |= RGB_JOIN(len,len,len); + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm3, mm5); + col |= 0x00ffffff; + + src--; dst--; + while(++src, ++dst < dst_end) + { + DATA32 a = A_VAL(src); + + switch (a) + { + case 0: break; + case 255: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + a = *src & col; + movd_m2r(a, mm1); + movq_r2r(mm1, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + default: + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + a = RGB_JOIN(a,a,a); + movd_m2r(a, mm3); + punpcklbw_r2r(mm0, mm3); + psllw_i2r(1, mm3); + paddw_r2r(mm6, mm3); + pmulhw_r2r(mm5, mm3); + + packuswb_r2r(mm0, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); +// psrlq_i2r(16, mm3); + + movd_m2r(*src, mm1); + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + } + } +} + +void +evas_common_blend_pixels_rgb_mul_color_a_to_rgb_mmx(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + col |= 0x00ffffff; + + src--; dst--; + while (++src, ++dst < dst_end) + { + DATA32 a = *src & col; + + movd_m2r(*dst, mm2); + punpcklbw_r2r(mm0, mm2); + + movd_m2r(a, mm1); + movq_r2r(mm1, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + psrlq_i2r(16, mm3); + + punpcklbw_r2r(mm0, mm1); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + } +} + +void +evas_common_copy_pixels_rgb_mul_color_rgb_to_rgba_mmx(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + col |= 0xff000000; + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm3, mm5); + + src--; dst--; + while (++src, ++dst < dst_end) + { + col = *src | 0xff000000; + movd_m2r(col, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + packuswb_r2r(mm0, mm1); + movd_r2m(mm1, *dst); + } +} + +void +evas_common_copy_pixels_rgb_mul_color_rgb_to_rgb_mmx(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ + DATA32 *dst_end = dst + len; + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + col |= 0xff000000; + movd_m2r(col, mm3); + punpcklbw_r2r(mm3, mm3); + psrlw_i2r(1, mm3); + + movq_r2r(mm3, mm5); + + src--; dst--; + while (++src, ++dst < dst_end) + { + col = (*src & 0x00ffffff) | (*dst & 0xff000000); + movd_m2r(col, mm1); + punpcklbw_r2r(mm0, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm5, mm1); + packuswb_r2r(mm0, mm1); + movd_r2m(mm1, *dst); + } +} +#endif + + +/****************************************************************************/ +void +evas_common_blend_pixels_mul_color_nothing(DATA32 *src, DATA32 *dst, int len, DATA32 col) +{ +} +/* ************************************************************************** */ + + +#ifdef BUILD_C +static Gfx_Func_Blend_Src_Mul_Dst +evas_common_gfx_func_blend_col_src_get_c(DATA32 col, RGBA_Image *src, RGBA_Image *dst, int pixels) +{ + if ((col | PIXEL_SOLID_ALPHA) == 0xffffffff) + { + if (src->flags & RGBA_IMAGE_HAS_ALPHA) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_pixels_rgba_mul_color_a_to_rgba_c; + } + return evas_common_blend_pixels_rgba_mul_color_a_to_rgb_c; + } + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_pixels_rgb_mul_color_a_to_rgba_c; + } + return evas_common_blend_pixels_rgb_mul_color_a_to_rgb_c; + } + + if (A_VAL(&col) < 255) + { + if (src->flags & RGBA_IMAGE_HAS_ALPHA) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_pixels_rgba_mul_color_rgba_to_rgba_c; + } + return evas_common_blend_pixels_rgba_mul_color_rgba_to_rgb_c; + } + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_pixels_rgb_mul_color_rgba_to_rgba_c; + } + return evas_common_blend_pixels_rgb_mul_color_rgba_to_rgb_c; + } + + if (src->flags & RGBA_IMAGE_HAS_ALPHA) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_pixels_rgba_mul_color_rgb_to_rgba_c; + } + return evas_common_blend_pixels_rgba_mul_color_rgb_to_rgb_c; + } + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + return evas_common_copy_pixels_rgb_mul_color_rgb_to_rgba_c; + return evas_common_copy_pixels_rgb_mul_color_rgb_to_rgb_c; + pixels = 0; +} +#endif + +#ifdef BUILD_MMX +static Gfx_Func_Blend_Src_Mul_Dst +evas_common_gfx_func_blend_col_src_get_mmx(DATA32 col, RGBA_Image *src, RGBA_Image *dst, int pixels) +{ + if ((col | PIXEL_SOLID_ALPHA) == 0xffffffff) + { + if (src->flags & RGBA_IMAGE_HAS_ALPHA) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_pixels_rgba_mul_color_a_to_rgba_mmx; + } + return evas_common_blend_pixels_rgba_mul_color_a_to_rgb_mmx; + } + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_pixels_rgb_mul_color_a_to_rgba_mmx; + } + return evas_common_blend_pixels_rgb_mul_color_a_to_rgb_mmx; + } + + if (A_VAL(&col) < 255) + { + if (src->flags & RGBA_IMAGE_HAS_ALPHA) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_pixels_rgba_mul_color_rgba_to_rgba_mmx; + } + return evas_common_blend_pixels_rgba_mul_color_rgba_to_rgb_mmx; + } + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_pixels_rgb_mul_color_rgba_to_rgba_mmx; + } + return evas_common_blend_pixels_rgb_mul_color_rgba_to_rgb_mmx; + } + + if (src->flags & RGBA_IMAGE_HAS_ALPHA) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_pixels_rgba_mul_color_rgb_to_rgba_mmx; + } + return evas_common_blend_pixels_rgba_mul_color_rgb_to_rgb_mmx; + } + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + return evas_common_copy_pixels_rgb_mul_color_rgb_to_rgba_mmx; + return evas_common_copy_pixels_rgb_mul_color_rgb_to_rgb_mmx; + pixels = 0; +} +#endif + + +Gfx_Func_Blend_Src_Mul_Dst +evas_common_draw_func_blend_mul_get(RGBA_Image *src, DATA32 col, RGBA_Image *dst, int pixels) +{ + Gfx_Func_Blend_Src_Mul_Dst func = NULL; + +#ifdef BUILD_MMX + if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) + { + func = evas_common_gfx_func_blend_col_src_get_mmx(col, src, dst, pixels); + if (func) return func; + } +#endif +#ifdef BUILD_C + func = evas_common_gfx_func_blend_col_src_get_c(col, src, dst, pixels); + if (func) return func; +#endif + return evas_common_blend_pixels_mul_color_nothing; +} + diff --git a/legacy/evas/src/lib/engines/common/evas_blend_pixel_pixel.c b/legacy/evas/src/lib/engines/common/evas_blend_pixel_pixel.c index 1f2dcd2176..b7bcb6f198 100644 --- a/legacy/evas/src/lib/engines/common/evas_blend_pixel_pixel.c +++ b/legacy/evas/src/lib/engines/common/evas_blend_pixel_pixel.c @@ -6,171 +6,277 @@ #define ALIGN_FIX +// extern DATA8 *_evas_pow_lut; extern const DATA8 _evas_pow_lut[65536]; extern const DATA16 _evas_const_c1[4]; #ifdef BUILD_C void -evas_common_blend_pixels_rgba_to_rgb_c(DATA32 *src, DATA32 *dst, int len) +evas_common_blend_pixels_rgba_to_rgba_c(DATA32 *src, DATA32 *dst, int len) { - DATA32 *src_ptr, *dst_ptr, *dst_end_ptr; + DATA32 *dst_end = dst + len; - src_ptr = src; - dst_ptr = dst; - dst_end_ptr = dst + len; - - while (dst_ptr < dst_end_ptr) + src--; dst--; + while (++src, ++dst < dst_end) { - DATA32 tmp; - DATA8 a; - - a = A_VAL(src_ptr); + DATA32 a = A_VAL(src); switch (a) { case 0: break; case 255: - *dst_ptr = *src_ptr; + *dst = *src; break; default: - BLEND_ALPHA_SETUP(a, tmp); - BLEND_COLOR(a, R_VAL(dst_ptr), - R_VAL(src_ptr), R_VAL(dst_ptr), - tmp); - BLEND_COLOR(a, G_VAL(dst_ptr), - G_VAL(src_ptr), G_VAL(dst_ptr), - tmp); - BLEND_COLOR(a, B_VAL(dst_ptr), - B_VAL(src_ptr), B_VAL(dst_ptr), - tmp); + { + DATA32 da = A_VAL(dst); + + switch(da) + { + case 0: + *dst = *src; + break; + case 255: + a += a >> 7; + *dst += RGB_JOIN( ((R_VAL(src) - R_VAL(dst)) * a) >> 8, + ((G_VAL(src) - G_VAL(dst)) * a) >> 8, + ((B_VAL(src) - B_VAL(dst)) * a) >> 8 ); + break; + default: + da = _evas_pow_lut[(a << 8) + da]; + da += da >> 7; a += a >> 7; + *dst += ARGB_JOIN( ((255 - A_VAL(dst)) * a) >> 8, + ((R_VAL(src) - R_VAL(dst)) * da) >> 8, + ((G_VAL(src) - G_VAL(dst)) * da) >> 8, + ((B_VAL(src) - B_VAL(dst)) * da) >> 8 ); + break; + } + } break; } - src_ptr++; - dst_ptr++; } } -#endif -#ifdef BUILD_MMX void -evas_common_blend_pixels_rgba_to_rgb_mmx(DATA32 *src, DATA32 *dst, int len) +evas_common_blend_pixels_rgba_to_rgb_c(DATA32 *src, DATA32 *dst, int len) { - DATA32 *src_ptr, *dst_ptr, *dst_end_ptr; + DATA32 *dst_end = dst + len; - src_ptr = src; - dst_ptr = dst; - dst_end_ptr = dst + len; - - pxor_r2r(mm4, mm4); - movq_m2r(*_evas_const_c1, mm5); - - while (dst_ptr < dst_end_ptr) + src--; dst--; + while (++src, ++dst < dst_end) { - switch (A_VAL(src_ptr)) + DATA32 a = A_VAL(src); + + switch (a) { case 0: break; case 255: - *dst_ptr = *src_ptr; + *dst = (*dst | 0x00ffffff) & (*src); break; default: - movd_m2r(src_ptr[0], mm1); // mm1 = [ ][ ][AR][GB] (SRC) - movd_m2r(dst_ptr[0], mm2); // mm2 = [ ][ ][ar][gb] (DST) + a += a >> 7; + *dst += RGB_JOIN( ((R_VAL(src) - R_VAL(dst)) * a) >> 8, + ((G_VAL(src) - G_VAL(dst)) * a) >> 8, + ((B_VAL(src) - B_VAL(dst)) * a) >> 8 ); + break; + } + } +} + +void +evas_common_copy_pixels_rgba_to_rgba_c(DATA32 *src, DATA32 *dst, int len) +{ + DATA32 *dst_end = dst + len; + + while (dst < dst_end) + *dst++ = *src++; +} + +void +evas_common_copy_pixels_rgb_to_rgba_c(DATA32 *src, DATA32 *dst, int len) +{ + DATA32 *dst_end = dst + len; + + while (dst < dst_end) + *dst++ = *src++ | PIXEL_SOLID_ALPHA; +} + +void +evas_common_copy_pixels_rgb_to_rgb_c(DATA32 *src, DATA32 *dst, int len) +{ + DATA32 *dst_end = dst + len; + + while (dst < dst_end) + *dst++ = (*src++ | PIXEL_SOLID_ALPHA) & (*dst | 0x00ffffff); +} + +void +evas_common_copy_pixels_rev_rgba_to_rgba_c(DATA32 *src, DATA32 *dst, int len) +{ + DATA32 *dst_start = dst; + + src = src + len - 1; + dst = dst + len - 1; + + while (dst >= dst_start) + *dst-- = *src--; +} + + +void +evas_common_copy_pixels_rev_rgb_to_rgba_c(DATA32 *src, DATA32 *dst, int len) +{ + DATA32 *src_ptr, *dst_ptr, *dst_end_ptr; + + src_ptr = src + len - 1; + dst_ptr = dst + len - 1; + dst_end_ptr = dst; + + while (dst_ptr >= dst_end_ptr) + { + *dst_ptr = *src_ptr | PIXEL_SOLID_ALPHA; + src_ptr--; + dst_ptr--; + } +} +#endif + +/****************************************************************************/ + +#ifdef BUILD_MMX +void +evas_common_blend_pixels_rgba_to_rgba_mmx(DATA32 *src, DATA32 *dst, int len) +{ + DATA32 *dst_end = dst + len; + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + src--; dst--; + while (++src, ++dst < dst_end) + { + DATA32 a = A_VAL(src); + + switch (a) + { + case 0: + break; + case 255: + *dst = *src; + break; + default: + { + DATA32 da = A_VAL(dst); + + switch(da) + { + case 0: + *dst = *src; + break; + case 255: + movd_m2r(*src, mm1); // mm1 = [ ][ ][AR][GB] (SRC) + movd_m2r(*dst, mm2); // mm2 = [ ][ ][ar][gb] (DST) + + movq_r2r(mm1, mm3); + punpcklbw_r2r(mm3, mm3); + punpckhwd_r2r(mm3, mm3); + punpckhdq_r2r(mm3, mm3); + psrlw_i2r(1, mm3); +// psrlq_i2r(16, mm3); + + punpcklbw_r2r(mm0, mm1); + punpcklbw_r2r(mm0, mm2); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + default: + da = _evas_pow_lut[(a << 8) + da]; + da = ARGB_JOIN(a, da, da, da); + movd_m2r(da, mm3); + punpcklbw_r2r(mm3, mm3); // mm3 = [AA][dAdA][dAdA][dAdA] + psrlw_i2r(1, mm3); // mm3 = [AA/2][dAdA/2][dAdA/2][dAdA/2] + + a = *src | 0xff000000; + movd_m2r(a, mm1); // mm1 = [ ][ ][255R][GB] (SRC) + punpcklbw_r2r(mm0, mm1); + movd_m2r(*dst, mm2); // mm1 = [ ][ ][ar][gb] (DST) + punpcklbw_r2r(mm0, mm2); + + psubw_r2r(mm2, mm1); + psllw_i2r(1, mm1); + paddw_r2r(mm6, mm1); + pmulhw_r2r(mm3, mm1); + paddw_r2r(mm1, mm2); + + packuswb_r2r(mm0, mm2); + movd_r2m(mm2, *dst); + + break; + } + } + break; + } + } +} + +void +evas_common_blend_pixels_rgba_to_rgb_mmx(DATA32 *src, DATA32 *dst, int len) +{ + DATA32 *dst_end = dst + len; + + pxor_r2r(mm0, mm0); + movq_m2r(*_evas_const_c1, mm6); + + src--; dst--; + while (++src, ++dst < dst_end) + { + DATA32 a = A_VAL(src); + + switch (a) + { + case 0: + break; + case 255: + *dst = (*dst | 0x00ffffff) & (*src); + break; + default: + movd_m2r(*src, mm1); // mm1 = [ ][ ][AR][GB] (SRC) + movd_m2r(*dst, mm2); // mm2 = [ ][ ][ar][gb] (DST) movq_r2r(mm1, mm3); // mm3 = [ ][ ][AR][GB] punpcklbw_r2r(mm3, mm3); // mm3 = [AA][RR][GG][BB] punpckhwd_r2r(mm3, mm3); // mm3 = [AA][AA][RR][RR] punpckhdq_r2r(mm3, mm3); // mm3 = [AA][AA][AA][AA] psrlw_i2r(1, mm3); // mm3 = [AA/2][AA/2][AA/2][AA/2] - // psrlq_i2r(16, mm3); // mm3 = [00][AA/2][AA/2][AA/2] - punpcklbw_r2r(mm4, mm1); // mm1 = [0A][0R][0G][0B] - punpcklbw_r2r(mm4, mm2); // mm2 = [0a][0r][0g][0b] + punpcklbw_r2r(mm0, mm1); // mm1 = [0A][0R][0G][0B] + punpcklbw_r2r(mm0, mm2); // mm2 = [0a][0r][0g][0b] psubw_r2r(mm2, mm1); // mm1 = [A-a][R-r][G-g][B-b] psllw_i2r(1, mm1); // mm1 = [A*2][R*2][G*2][B*2] - paddw_r2r(mm5, mm1); // mm1 = [A+1][R+1][G+1][B+1] + paddw_r2r(mm6, mm1); // mm1 = [A+1][R+1][G+1][B+1] pmulhw_r2r(mm3, mm1); // mm1 = [A*0][(R*AA)>>16][(G*AA)>>16][(B*AA)>>16] paddw_r2r(mm1, mm2); // mm2 = [0a][R-r][G-g][B-b] - packuswb_r2r(mm4, mm2); // mm2 = [ ][ ][AR][GB] - movd_r2m(mm2, dst_ptr[0]); // DST = mm2 + packuswb_r2r(mm0, mm2); // mm2 = [ ][ ][AR][GB] + movd_r2m(mm2, *dst); // DST = mm2 + break; } - src_ptr++; - dst_ptr++; - } -} -#endif - -void -evas_common_blend_pixels_rgba_to_rgba_c(DATA32 *src, DATA32 *dst, int len) -{ - DATA32 *src_ptr, *dst_ptr, *dst_end_ptr; - - src_ptr = src; - dst_ptr = dst; - dst_end_ptr = dst + len; - - while (dst_ptr < dst_end_ptr) - { - DATA32 tmp; - DATA8 a, aa; - - aa = A_VAL(src_ptr); - switch (aa) - { - case 0: - break; - case 255: - *dst_ptr = *src_ptr; - break; - default: - BLEND_ADST_ALPHA_SETUP(aa, tmp); - a = _evas_pow_lut[(aa << 8) | A_VAL(dst_ptr)]; - BLEND_ADST_COLOR(aa, A_VAL(dst_ptr), - 255, A_VAL(dst_ptr), - tmp); - BLEND_ADST_ALPHA_SETUP(a, tmp); - BLEND_ADST_COLOR(a, R_VAL(dst_ptr), - R_VAL(src_ptr), R_VAL(dst_ptr), - tmp); - BLEND_ADST_COLOR(a, G_VAL(dst_ptr), - G_VAL(src_ptr), G_VAL(dst_ptr), - tmp); - BLEND_ADST_COLOR(a, B_VAL(dst_ptr), - B_VAL(src_ptr), B_VAL(dst_ptr), - tmp); - } - src_ptr++; - dst_ptr++; } } -/****************************************************************************/ - -#ifdef BUILD_C -void -evas_common_copy_pixels_rgba_to_rgba_c(DATA32 *src, DATA32 *dst, int len) -{ - DATA32 *src_ptr, *dst_ptr, *dst_end_ptr; - - src_ptr = src; - dst_ptr = dst; - dst_end_ptr = dst + len; - - while (dst_ptr < dst_end_ptr) - { - *dst_ptr = *src_ptr; - src_ptr++; - dst_ptr++; - } -} -#endif - -#ifdef BUILD_MMX void evas_common_copy_pixels_rgba_to_rgba_mmx(DATA32 *src, DATA32 *dst, int len) { @@ -219,9 +325,7 @@ evas_common_copy_pixels_rgba_to_rgba_mmx(DATA32 *src, DATA32 *dst, int len) dst_ptr++; } } -#endif -#ifdef BUILD_MMX void evas_common_copy_pixels_rgba_to_rgba_mmx2(DATA32 *src, DATA32 *dst, int len) { @@ -270,99 +374,7 @@ evas_common_copy_pixels_rgba_to_rgba_mmx2(DATA32 *src, DATA32 *dst, int len) dst_ptr++; } } -#endif -#ifdef BUILD_SSE -void -evas_common_copy_pixels_rgba_to_rgba_sse(DATA32 *src, DATA32 *dst, int len) -{ - DATA32 *src_ptr, *dst_ptr, *dst_end_ptr, *dst_end_ptr_pre; -#ifdef ALIGN_FIX - int src_align; - int dst_align; - - src_align = (int)src & 0x3f; /* 64 byte alignment */ - dst_align = (int)dst & 0x3f; /* 64 byte alignment */ - - if ((src_align != dst_align) || - ((src_align & 0x3) != 0)) - { -#ifdef BUILD_C - evas_common_copy_pixels_rgba_to_rgba_c(src, dst, len); -#endif - return; - } - - while ((src_align > 0) && (len > 0)) - { - *dst = *src; - dst++; - src++; - len--; - src_align -= sizeof(DATA32); - } -#endif /* ALIGN_FIX */ - - src_ptr = src; - dst_ptr = dst; - dst_end_ptr = dst + len; - dst_end_ptr_pre = dst + ((len / 16) * 16); - - while (dst_ptr < dst_end_ptr_pre) - { - prefetch(&src_ptr[16]); - MOVE_16DWORDS_MMX(src_ptr, dst_ptr); - src_ptr+=16; - dst_ptr+=16; - } - while (dst_ptr < dst_end_ptr) - { - *dst_ptr = *src_ptr; - src_ptr++; - dst_ptr++; - } -} -#endif - -void -evas_common_copy_pixels_rgb_to_rgba_c(DATA32 *src, DATA32 *dst, int len) -{ - DATA32 *src_ptr, *dst_ptr, *dst_end_ptr; - - src_ptr = src; - dst_ptr = dst; - dst_end_ptr = dst + len; - - while (dst_ptr < dst_end_ptr) - { - *dst_ptr = *src_ptr | PIXEL_SOLID_ALPHA; - src_ptr++; - dst_ptr++; - } -} - -/****************************************************************************/ - -#ifdef BUILD_C -void -evas_common_copy_pixels_rev_rgba_to_rgba_c(DATA32 *src, DATA32 *dst, int len) -{ - DATA32 *src_ptr, *dst_ptr, *dst_end_ptr; - - src_ptr = src + len - 1; - dst_ptr = dst + len - 1; - dst_end_ptr = dst; - - while (dst_ptr >= dst_end_ptr) - { - *dst_ptr = *src_ptr; - src_ptr--; - dst_ptr--; - } -} -#endif - -#ifdef BUILD_MMX void evas_common_copy_pixels_rev_rgba_to_rgba_mmx(DATA32 *src, DATA32 *dst, int len) { @@ -393,7 +405,7 @@ evas_common_copy_pixels_rev_rgba_to_rgba_mmx(DATA32 *src, DATA32 *dst, int len) else { src_ptr = src + len - 1; - dst_ptr = dst + len - 1; + dst_ptr = dst + len - 1; while (dst_ptr >= dst_end_ptr) { *dst_ptr = *src_ptr; @@ -402,9 +414,69 @@ evas_common_copy_pixels_rev_rgba_to_rgba_mmx(DATA32 *src, DATA32 *dst, int len) } } } + +#define evas_common_copy_pixels_rgb_to_rgb_mmx evas_common_copy_pixels_rgba_to_rgba_mmx +#define evas_common_copy_pixels_rgb_to_rgba_mmx NULL + +#define evas_common_copy_pixels_rgb_to_rgb_mmx2 evas_common_copy_pixels_rgba_to_rgba_mmx2 +#define evas_common_copy_pixels_rgb_to_rgba_mmx2 NULL #endif + +/****************************************************************************/ + + #ifdef BUILD_SSE +void +evas_common_copy_pixels_rgba_to_rgba_sse(DATA32 *src, DATA32 *dst, int len) +{ + DATA32 *src_ptr, *dst_ptr, *dst_end_ptr, *dst_end_ptr_pre; +#ifdef ALIGN_FIX + int src_align; + int dst_align; + + src_align = (int)src & 0x3f; /* 64 byte alignment */ + dst_align = (int)dst & 0x3f; /* 64 byte alignment */ + + if ((src_align != dst_align) || + ((src_align & 0x3) != 0)) + { +#ifdef BUILD_C + evas_common_copy_pixels_rgba_to_rgba_c(src, dst, len); +#endif + return; + } + + while ((src_align > 0) && (len > 0)) + { + *dst = *src; + dst++; + src++; + len--; + src_align -= sizeof(DATA32); + } +#endif /* ALIGN_FIX */ + + src_ptr = src; + dst_ptr = dst; + dst_end_ptr = dst + len; + dst_end_ptr_pre = dst + ((len / 16) * 16); + + while (dst_ptr < dst_end_ptr_pre) + { + prefetch(&src_ptr[16]); + MOVE_16DWORDS_MMX(src_ptr, dst_ptr); + src_ptr+=16; + dst_ptr+=16; + } + while (dst_ptr < dst_end_ptr) + { + *dst_ptr = *src_ptr; + src_ptr++; + dst_ptr++; + } +} + void evas_common_copy_pixels_rev_rgba_to_rgba_sse(DATA32 *src, DATA32 *dst, int len) { @@ -436,7 +508,7 @@ evas_common_copy_pixels_rev_rgba_to_rgba_sse(DATA32 *src, DATA32 *dst, int len) else { src_ptr = src + len - 1; - dst_ptr = dst + len - 1; + dst_ptr = dst + len - 1; while (dst_ptr >= dst_end_ptr) { *dst_ptr = *src_ptr; @@ -445,21 +517,174 @@ evas_common_copy_pixels_rev_rgba_to_rgba_sse(DATA32 *src, DATA32 *dst, int len) } } } + +#define evas_common_blend_pixels_rgba_to_rgba_sse NULL +#define evas_common_blend_pixels_rgba_to_rgb_sse NULL +#define evas_common_copy_pixels_rgb_to_rgb_sse evas_common_copy_pixels_rgba_to_rgba_sse +#define evas_common_copy_pixels_rgb_to_rgba_sse NULL #endif -void -evas_common_copy_pixels_rev_rgb_to_rgba_c(DATA32 *src, DATA32 *dst, int len) + +/****************************************************************************/ +static void +evas_common_blend_pixels_nothing(DATA32 *src, DATA32 *dst, int len) { - DATA32 *src_ptr, *dst_ptr, *dst_end_ptr; - - src_ptr = src + len - 1; - dst_ptr = dst + len - 1; - dst_end_ptr = dst; - - while (dst_ptr >= dst_end_ptr) - { - *dst_ptr = *src_ptr | PIXEL_SOLID_ALPHA; - src_ptr--; - dst_ptr--; - } } + +static void +evas_common_copy_pixels_nothing(DATA32 *src, DATA32 *dst, int len) +{ +} +/****************************************************************************/ + +#ifdef BUILD_SSE +static Gfx_Func_Blend_Src_Dst +evas_common_gfx_func_blend_pixels_get_sse(RGBA_Image *src, RGBA_Image *dst, int pixels) +{ + if (src->flags & RGBA_IMAGE_HAS_ALPHA) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + return evas_common_blend_pixels_rgba_to_rgba_sse; + return evas_common_blend_pixels_rgba_to_rgb_sse; + } + if (pixels <= (256 * 256)) + return NULL; + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + return evas_common_copy_pixels_rgb_to_rgba_sse; + return evas_common_copy_pixels_rgb_to_rgb_sse; +} +#endif + +#ifdef BUILD_MMX +static Gfx_Func_Blend_Src_Dst +evas_common_gfx_func_blend_pixels_get_mmx(RGBA_Image *src, RGBA_Image *dst, int pixels) +{ + if (src->flags & RGBA_IMAGE_HAS_ALPHA) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_pixels_rgba_to_rgba_mmx; + } + return evas_common_blend_pixels_rgba_to_rgb_mmx; + } + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + return evas_common_copy_pixels_rgb_to_rgba_mmx; + if (evas_common_cpu_has_feature(CPU_FEATURE_MMX2)) + return evas_common_copy_pixels_rgb_to_rgb_mmx2; + return evas_common_copy_pixels_rgb_to_rgb_mmx; + pixels = 0; +} +#endif + +#ifdef BUILD_C +static Gfx_Func_Blend_Src_Dst +evas_common_gfx_func_blend_pixels_get_c(RGBA_Image *src, RGBA_Image *dst, int pixels) +{ + if (src->flags & RGBA_IMAGE_HAS_ALPHA) + { + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + { +// evas_common_blend_init_evas_pow_lut(); + return evas_common_blend_pixels_rgba_to_rgba_c; + } + return evas_common_blend_pixels_rgba_to_rgb_c; + } + if (dst->flags & RGBA_IMAGE_HAS_ALPHA) + return evas_common_copy_pixels_rgb_to_rgba_c; + return evas_common_copy_pixels_rgb_to_rgb_c; + pixels = 0; +} +#endif + +Gfx_Func_Blend_Src_Dst +evas_common_draw_func_blend_get (RGBA_Image *src, RGBA_Image *dst, int pixels) +{ + Gfx_Func_Blend_Src_Dst func = NULL; + +#ifdef BUILD_SSE + if (evas_common_cpu_has_feature(CPU_FEATURE_SSE)) + { + func = evas_common_gfx_func_blend_pixels_get_sse(src, dst, pixels); + if (func) return func; + } +#endif +#ifdef BUILD_MMX + if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) + { + func = evas_common_gfx_func_blend_pixels_get_mmx(src, dst, pixels); + if (func) return func; + } +#endif +#ifdef BUILD_C + func = evas_common_gfx_func_blend_pixels_get_c(src, dst, pixels); + if (func) return func; +#endif + return evas_common_blend_pixels_nothing; +} + +/* ********************************************* */ + +#ifdef BUILD_SSE +static Gfx_Func_Blend_Src_Dst +evas_common_gfx_func_copy_get_sse(int pixels, int reverse) +{ + if (pixels <= (256 * 256)) + return NULL; + if (reverse) + return evas_common_copy_pixels_rev_rgba_to_rgba_sse; + return evas_common_copy_pixels_rgba_to_rgba_sse; +} +#endif + +#ifdef BUILD_MMX +static Gfx_Func_Blend_Src_Dst +evas_common_gfx_func_copy_get_mmx(int pixels, int reverse) +{ + if (reverse) + return evas_common_copy_pixels_rev_rgba_to_rgba_mmx; + if (evas_common_cpu_has_feature(CPU_FEATURE_MMX2)) + return evas_common_copy_pixels_rgba_to_rgba_mmx2; + return evas_common_copy_pixels_rgba_to_rgba_mmx; + pixels = 0; +} +#endif + +#ifdef BUILD_C +static Gfx_Func_Blend_Src_Dst +evas_common_gfx_func_copy_get_c(int pixels, int reverse) +{ + if (reverse) + return evas_common_copy_pixels_rev_rgba_to_rgba_c; + return evas_common_copy_pixels_rgba_to_rgba_c; + pixels = 0; +} +#endif + + +Gfx_Func_Blend_Src_Dst +evas_common_draw_func_copy_get(int pixels, int reverse) +{ + Gfx_Func_Blend_Src_Dst func = NULL; + +#ifdef BUILD_SSE + if (evas_common_cpu_has_feature(CPU_FEATURE_SSE)) + { + func = evas_common_gfx_func_copy_get_sse(pixels, reverse); + if (func) return func; + } +#endif +#ifdef BUILD_MMX + if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) + { + func = evas_common_gfx_func_copy_get_mmx(pixels, reverse); + if (func) return func; + } +#endif +#ifdef BUILD_C + func = evas_common_gfx_func_copy_get_c(pixels, reverse); + if (func) return func; +#endif + return evas_common_copy_pixels_nothing; +} + diff --git a/legacy/evas/src/lib/engines/common/evas_draw_main.c b/legacy/evas/src/lib/engines/common/evas_draw_main.c index 22548a63e2..fab8cb795a 100644 --- a/legacy/evas/src/lib/engines/common/evas_draw_main.c +++ b/legacy/evas/src/lib/engines/common/evas_draw_main.c @@ -2,6 +2,33 @@ extern const DATA8 _evas_pow_lut[65536]; +void +evas_common_init(void) +{ + evas_common_cpu_init(); + + evas_common_blend_init(); + evas_common_image_init(); + evas_common_convert_init(); + evas_common_scale_init(); + evas_common_rectangle_init(); + evas_common_gradient_init(); + evas_common_polygon_init(); + evas_common_line_init(); + evas_common_font_init(); + evas_common_draw_init(); + evas_common_tilebuf_init(); +} + +void +evas_common_shutdown(void) +{ +// evas_common_blend_free_evas_pow_lut(); + evas_font_dir_cache_free(); + evas_common_image_line_buffer_free(); + evas_common_image_cache_free(); +} + void evas_common_draw_init(void) { @@ -539,162 +566,16 @@ evas_common_draw_context_cutout_merge(Cutout_Rect *in, Cutout_Rect *merge) return out; } -Gfx_Func_Blend_Src_Dst -evas_common_draw_func_blend_get(RGBA_Image *src, RGBA_Image *dst, int pixels) +void +evas_common_draw_context_set_anti_alias(RGBA_Draw_Context *dc , unsigned char aa) { - if (src->flags & RGBA_IMAGE_HAS_ALPHA) - { - if (dst->flags & RGBA_IMAGE_HAS_ALPHA) - { - if (!_evas_pow_lut) evas_common_blend_init_evas_pow_lut(); - return evas_common_blend_pixels_rgba_to_rgba_c; - } - else - { -#ifdef BUILD_MMX -# ifdef BUILD_C - if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) -# endif - return evas_common_blend_pixels_rgba_to_rgb_mmx; -# ifdef BUILD_C - else -# endif -#endif -#ifdef BUILD_C - return evas_common_blend_pixels_rgba_to_rgb_c; -#endif - } - } - else - { - if (dst->flags & RGBA_IMAGE_HAS_ALPHA) - { - return evas_common_copy_pixels_rgb_to_rgba_c; - } - else - { -#if 1 - -# ifdef BUILD_MMX -# ifdef BUILD_C - if (evas_common_cpu_has_feature(CPU_FEATURE_MMX2)) -# endif - return evas_common_copy_pixels_rgba_to_rgba_mmx2; -# ifdef BUILD_SSE - else -# endif -#endif -#ifdef BUILD_SSE -# ifdef BUILD_C - if (evas_common_cpu_has_feature(CPU_FEATURE_SSE) && (pixels > 64 * 64)) -# endif - return evas_common_copy_pixels_rgba_to_rgba_sse; -# ifdef BUILD_MMX - else -# endif -#endif -#ifdef BUILD_MMX -# ifdef BUILD_C - if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) -# endif - return evas_common_copy_pixels_rgba_to_rgba_mmx; -# ifdef BUILD_C - else -# endif -#endif -#ifdef BUILD_C - return evas_common_copy_pixels_rgba_to_rgba_c; -#endif - -#else - -# ifdef BUILD_SSE - if (evas_common_cpu_has_feature(CPU_FEATURE_SSE) && (pixels > 256 * 256)) - return evas_common_copy_pixels_rgba_to_rgba_sse; -# ifdef BUILD_MMX - else -# endif -#endif -#ifdef BUILD_MMX -# ifdef BUILD_C - if (evas_common_cpu_has_feature(CPU_FEATURE_MMX2)) -# endif - return evas_common_copy_pixels_rgba_to_rgba_mmx2; -# ifdef BUILD_C - else if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) -# endif - return evas_common_copy_pixels_rgba_to_rgba_mmx; -# ifdef BUILD_C - else -# endif -#endif -#ifdef BUILD_C - return evas_common_copy_pixels_rgba_to_rgba_c; -#endif - -#endif - } - } - if (!_evas_pow_lut) evas_common_blend_init_evas_pow_lut(); - return evas_common_blend_pixels_rgba_to_rgba_c; - pixels = 0; + dc->anti_alias = !!aa; } -Gfx_Func_Blend_Color_Dst -evas_common_draw_func_blend_color_get(DATA32 src, RGBA_Image *dst, int pixels) +void +evas_common_draw_context_set_color_interpolation(RGBA_Draw_Context *dc, int color_space) { - if (A_VAL(&src) != 0xff) - { - if (dst->flags & RGBA_IMAGE_HAS_ALPHA) - { - if (!_evas_pow_lut) evas_common_blend_init_evas_pow_lut(); - return evas_common_blend_color_rgba_to_rgba_c; - } - else - { -#ifdef BUILD_MMX - if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) - return evas_common_blend_color_rgba_to_rgb_mmx; -#endif -#ifdef BUILD_C -# ifdef BUILD_MMX - else -# endif - return evas_common_blend_color_rgba_to_rgb_c; -#endif - } - } - else - { - if (dst->flags & RGBA_IMAGE_HAS_ALPHA) - { - if (!_evas_pow_lut) evas_common_blend_init_evas_pow_lut(); - return evas_common_copy_color_rgb_to_rgba_c; - } - else - { -#ifdef BUILD_SSE - if (evas_common_cpu_has_feature(CPU_FEATURE_SSE) && (pixels > 64 * 64)) - return evas_common_copy_color_rgba_to_rgba_sse; -#endif -#ifdef BUILD_MMX -# ifdef BUILD_SSE - else -# endif - if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) - return evas_common_copy_color_rgba_to_rgba_mmx; -#endif -#ifdef BUILD_C -# ifdef BUILD_MMX - else -# endif - return evas_common_copy_color_rgba_to_rgba_c; -#endif - } - } - if (!_evas_pow_lut) evas_common_blend_init_evas_pow_lut(); - return evas_common_blend_color_rgba_to_rgba_c; - pixels = 0; + dc->interpolation.color_space = color_space; } Gfx_Func_Blend_Src_Cmod_Dst @@ -704,7 +585,7 @@ evas_common_draw_func_blend_cmod_get(RGBA_Image *src, RGBA_Image *dst, int pixel { if (dst->flags & RGBA_IMAGE_HAS_ALPHA) { - if (!_evas_pow_lut) evas_common_blend_init_evas_pow_lut(); +// evas_common_blend_init_evas_pow_lut(); return evas_common_blend_pixels_cmod_rgba_to_rgba_c; } else @@ -716,7 +597,7 @@ evas_common_draw_func_blend_cmod_get(RGBA_Image *src, RGBA_Image *dst, int pixel { if (dst->flags & RGBA_IMAGE_HAS_ALPHA) { - if (!_evas_pow_lut) evas_common_blend_init_evas_pow_lut(); +// evas_common_blend_init_evas_pow_lut(); return evas_common_copy_pixels_cmod_rgb_to_rgba_c; } else @@ -724,182 +605,9 @@ evas_common_draw_func_blend_cmod_get(RGBA_Image *src, RGBA_Image *dst, int pixel return evas_common_copy_pixels_cmod_rgba_to_rgba_c; } } - if (!_evas_pow_lut) evas_common_blend_init_evas_pow_lut(); +// evas_common_blend_init_evas_pow_lut(); return evas_common_blend_pixels_cmod_rgba_to_rgba_c; pixels = 0; } -Gfx_Func_Blend_Src_Mul_Dst -evas_common_draw_func_blend_mul_get(RGBA_Image *src, DATA32 col, RGBA_Image *dst, int pixels) -{ - if (src->flags & RGBA_IMAGE_HAS_ALPHA) - { - if (dst->flags & RGBA_IMAGE_HAS_ALPHA) - { - if (!_evas_pow_lut) evas_common_blend_init_evas_pow_lut(); - return evas_common_blend_pixels_mul_color_rgba_to_rgba_c; - } - else - { -#ifdef BUILD_MMX - if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) - return evas_common_blend_pixels_mul_color_rgba_to_rgb_mmx; -#endif -#ifdef BUILD_C -# ifdef BUILD_MMX - else -# endif - return evas_common_blend_pixels_mul_color_rgba_to_rgb_c; -#endif - } - } - else - { - if (dst->flags & RGBA_IMAGE_HAS_ALPHA) - { - if (!_evas_pow_lut) evas_common_blend_init_evas_pow_lut(); - return evas_common_blend_pixels_mul_color_rgba_to_rgba_c; - } - else - { -#ifdef BUILD_MMX - if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) - return evas_common_blend_pixels_mul_color_rgba_to_rgb_mmx; -#endif -#ifdef BUILD_C -# ifdef BUILD_MMX - else -# endif - return evas_common_blend_pixels_mul_color_rgba_to_rgb_c; -#endif - } - } - if (!_evas_pow_lut) evas_common_blend_init_evas_pow_lut(); - return evas_common_blend_pixels_mul_color_rgba_to_rgba_c; - col = 0; - pixels = 0; -} - -Gfx_Func_Blend_Src_Alpha_Mul_Dst -evas_common_draw_func_blend_alpha_get(RGBA_Image *dst) -{ - if (dst->flags & RGBA_IMAGE_HAS_ALPHA) - { - if (!_evas_pow_lut) evas_common_blend_init_evas_pow_lut(); - return evas_common_blend_alpha_color_rgba_to_rgba_c; - } - else - { -#ifdef BUILD_MMX - if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) - return evas_common_blend_alpha_color_rgba_to_rgb_mmx; -#endif -#ifdef BUILD_C -# ifdef BUILD_MMX - else -# endif - return evas_common_blend_alpha_color_rgba_to_rgb_c; -#endif - } -#ifdef BUILD_C - return evas_common_blend_alpha_color_rgba_to_rgba_c; -#else - return NULL; -#endif -} - -Gfx_Func_Blend_Src_Dst -evas_common_draw_func_copy_get(int pixels, int reverse) -{ - if (reverse) - { -#ifdef BUILD_SSE - if (evas_common_cpu_has_feature(CPU_FEATURE_SSE) && (pixels > 256 * 256)) - return evas_common_copy_pixels_rev_rgba_to_rgba_sse; -#endif -#ifdef BUILD_MMX -# ifdef BUILD_SSE - else -# endif - if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) - return evas_common_copy_pixels_rev_rgba_to_rgba_mmx; -#endif -#ifdef BUILD_C -# ifdef BUILD_MMX - else -# endif - return evas_common_copy_pixels_rev_rgba_to_rgba_c; -#endif - } - else - { -#if 1 - -# ifdef BUILD_MMX -# ifdef BUILD_C - if (evas_common_cpu_has_feature(CPU_FEATURE_MMX2)) -# endif - return evas_common_copy_pixels_rgba_to_rgba_mmx2; -# ifdef BUILD_SSE - else -# endif -#endif -#ifdef BUILD_SSE -# ifdef BUILD_C - if (evas_common_cpu_has_feature(CPU_FEATURE_SSE) && (pixels > 64 * 64)) -# endif - return evas_common_copy_pixels_rgba_to_rgba_sse; -# ifdef BUILD_MMX - else -# endif -#endif -#ifdef BUILD_MMX -# ifdef BUILD_C - if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) -# endif - return evas_common_copy_pixels_rgba_to_rgba_mmx; -# ifdef BUILD_C - else -# endif -#endif -#ifdef BUILD_C - return evas_common_copy_pixels_rgba_to_rgba_c; -#endif - -#else - -# ifdef BUILD_SSE - if (evas_common_cpu_has_feature(CPU_FEATURE_SSE) && (pixels > 256 * 256)) - return evas_common_copy_pixels_rgba_to_rgba_sse; -# ifdef BUILD_MMX - else -# endif -#endif -#ifdef BUILD_MMX -# ifdef BUILD_C - if (evas_common_cpu_has_feature(CPU_FEATURE_MMX2)) -# endif - return evas_common_copy_pixels_rgba_to_rgba_mmx2; -# ifdef BUILD_C - else if (evas_common_cpu_has_feature(CPU_FEATURE_MMX)) -# endif - return evas_common_copy_pixels_rgba_to_rgba_mmx; -# ifdef BUILD_C - else -# endif -#endif -#ifdef BUILD_C - return evas_common_copy_pixels_rgba_to_rgba_c; -#endif - -#endif - } - if (!_evas_pow_lut) evas_common_blend_init_evas_pow_lut(); -#ifdef BUILD_C - return evas_common_copy_pixels_rgba_to_rgba_c; -#else - return NULL; -#endif - pixels = 0; -} diff --git a/legacy/evas/src/lib/engines/common/evas_font_draw.c b/legacy/evas/src/lib/engines/common/evas_font_draw.c index 6a79ece0ae..b05ec4144c 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_draw.c +++ b/legacy/evas/src/lib/engines/common/evas_font_draw.c @@ -120,7 +120,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int evas_common_font_size_use(fn); use_kerning = FT_HAS_KERNING(fi->src->ft.face); prev_index = 0; - func = evas_common_draw_func_blend_alpha_get(dst); + func = evas_common_draw_func_blend_alpha_get(dc->col.col, dst); for (c = 0, chr = 0; text[chr];) { FT_UInt index; diff --git a/legacy/evas/src/lib/engines/common/evas_gradient_angular.c b/legacy/evas/src/lib/engines/common/evas_gradient_angular.c new file mode 100644 index 0000000000..ff6762a2fd --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_gradient_angular.c @@ -0,0 +1,764 @@ +#include "evas_common.h" +#include + + +typedef struct _Angular_Data Angular_Data; +struct _Angular_Data +{ + int sx, sy, s; + float an, cy; +}; + +static Angular_Data angular_data = {32, 32, 32, -1.0, 1.0}; + + +static void +angular_setup_geom(RGBA_Gradient *gr, int spread); + +static int +angular_has_alpha(RGBA_Gradient *gr, int spread); + +static int +angular_get_map_len(RGBA_Gradient *gr, int spread); + +static Gfx_Func_Gradient_Span +angular_get_span_func(RGBA_Gradient *gr, int spread, unsigned char aa); + +static RGBA_Gradient_Type angular = {"angular", &angular_data, angular_setup_geom, angular_has_alpha, angular_get_map_len, angular_get_span_func}; + + +/** internal functions **/ + +static void +angular_reflect_aa_annulus(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +angular_reflect_annulus(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +angular_reflect(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +angular_repeat_aa_annulus(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +angular_repeat_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +angular_repeat_annulus(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +angular_repeat(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +angular_restrict_aa_annulus(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +angular_restrict_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); +static void +angular_restrict_annulus(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +angular_restrict(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + + + +RGBA_Gradient_Type * +evas_common_gradient_angular_get(void) +{ + return &angular; +} + +static void +angular_setup_geom(RGBA_Gradient *gr, int spread) +{ + int err = 1; + char *s, *p, key[256]; + float val, an = -1.0, cy = 1.0; + + if (!gr || (gr->type.geometer != &angular)) return; + + angular_data.sx = gr->fill.w; + angular_data.sy = gr->fill.h; + angular_data.s = angular_data.sx; + if (angular_data.sy > angular_data.sx) + angular_data.s = angular_data.sy; + angular_data.an = -1.0; + angular_data.cy = 1.0; + + if (!gr->type.params || !*(gr->type.params)) + return; + + s = strdup(gr->type.params); + if (!s) return; + + p = s; + while (p = evas_common_gradient_get_key_fval(p, key, &val)) + { + if (!strcmp(key, "annulus")) + { + err = 0; + an = val; + } + else if (!strcmp(key, "wrap")) + { + err = 0; + cy = val; + } + else + { + err = 1; + goto done; + } + } + done: + if (!err) + { + if (an < 0.0) an = 0.0; + if (an > 1.0) an = 1.0; + angular_data.an = an; + if (cy < 0.0) cy = 0.0; + if (cy > 1.0) cy = 1.0; + angular_data.cy = cy; + } + free(s); +} + + +static int +angular_has_alpha(RGBA_Gradient *gr, int spread) +{ + if (!gr || (gr->type.geometer != &angular)) return 0; + if (gr->map.has_alpha) + return 1; + if ((int)angular_data.an >= 0) + return 1; + if ((spread == _EVAS_TEXTURE_RESTRICT) && (angular_data.cy < 1.0)) + return 1; + return 0; +} + +static int +angular_get_map_len(RGBA_Gradient *gr, int spread) +{ + int l; + + if (!gr || (gr->type.geometer != &angular)) return 0; + l = (2 * M_PI) * angular_data.s * angular_data.cy; + return l; +} + +static Gfx_Func_Gradient_Span +angular_get_span_func(RGBA_Gradient *gr, int spread, unsigned char aa) +{ + Gfx_Func_Gradient_Span sfunc = NULL; + + if (!gr || (gr->type.geometer != &angular)) return sfunc; + switch (spread) + { + case _EVAS_TEXTURE_REFLECT: + { + if (aa) + { + if ((int)angular_data.an >= 0) + sfunc = angular_reflect_aa_annulus; + else + sfunc = angular_reflect; + } + else + { + if ((int)angular_data.an >= 0) + sfunc = angular_reflect_annulus; + else + sfunc = angular_reflect; + } + } + break; + case _EVAS_TEXTURE_REPEAT: + { + if (aa) + { + if ((int)angular_data.an >= 0) + sfunc = angular_repeat_aa_annulus; + else + sfunc = angular_repeat_aa; + } + else + { + if ((int)angular_data.an >= 0) + sfunc = angular_repeat_annulus; + else + sfunc = angular_repeat; + } + } + break; + case _EVAS_TEXTURE_RESTRICT: + { + if (aa) + { + if ((int)angular_data.an >= 0) + sfunc = angular_restrict_aa_annulus; + else + sfunc = angular_restrict_aa; + } + else + { + if ((int)angular_data.an >= 0) + sfunc = angular_restrict_annulus; + else + sfunc = angular_restrict; + } + } + break; + default: + sfunc = angular_reflect; + break; + } + return sfunc; +} + +static void +angular_reflect_aa_annulus(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Angular_Data *gdata = (Angular_Data *)params_data; + + int xx, yy; + int ss = (gdata->s) << 16; + int r1 = gdata->s, r0 = gdata->an * r1; + int rr0 = r0 << 16, rr1 = r1 << 16; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + + while (dst < dst_end) + { + int rr = hypot(xx, yy), r = (rr >> 16); + + *dst = 0; + if ((r >= r0) && (r <= r1)) + { + int ll = ss * (M_PI + atan2(yy, xx)), l = (ll >> 16); + + if (l >= map_len) + { + int m = (l % (2 * map_len)); + + l = (l % map_len); + if (m >= map_len) + l = map_len - l - 1; + } + *dst = map[l]; + if (r == r0) + { + int a = 1 + ((rr - rr0) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (r == r1) + { + int a = 256 - ((rr - rr1) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + } + dst++; xx += axx; yy += ayx; + } +} + +static void +angular_reflect(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Angular_Data *gdata = (Angular_Data *)params_data; + + int xx, yy; + int ss = (gdata->s) << 16; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + + while (dst < dst_end) + { + int ll = ss * (M_PI + atan2(yy, xx)), l = (ll >> 16); + + if (l >= map_len) + { + int m = (l % (2 * map_len)); + + l = (l % map_len); + if (m >= map_len) + l = map_len - l - 1; + } + *dst = map[l]; + dst++; xx += axx; yy += ayx; + } +} + +static void +angular_reflect_annulus(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Angular_Data *gdata = (Angular_Data *)params_data; + + int xx, yy; + int ss = (gdata->s) << 16; + int r1 = gdata->s, r0 = gdata->an * r1; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + + while (dst < dst_end) + { + int rr = hypot(xx, yy), r = (rr >> 16); + + *dst = 0; + if ((r >= r0) && (r <= r1)) + { + int ll = ss * (M_PI + atan2(yy, xx)), l = ll >> 16; + + l += (ll - (l << 16)) >> 15; + if (l >= map_len) + { + int m = (l % (2 * map_len)); + + l = (l % map_len); + if (m >= map_len) + l = map_len - l - 1; + } + *dst = map[l]; + } + dst++; xx += axx; yy += ayx; + } +} + +static void +angular_repeat_aa_annulus(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Angular_Data *gdata = (Angular_Data *)params_data; + + int xx, yy; + int ss = (gdata->s) << 16; + int r1 = gdata->s, r0 = gdata->an * r1; + int rr0 = r0 << 16, rr1 = r1 << 16; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + + while (dst < dst_end) + { + int rr = hypot(xx, yy), r = (rr >> 16); + + *dst = 0; + if ((r >= r0) && (r <= r1)) + { + int ll = ss * (M_PI + atan2(yy, xx)), l = ll >> 16; + + if (l >= map_len) + l = (l % map_len); + *dst = map[l]; + if (r == r0) + { + int a = 1 + ((rr - rr0) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (r == r1) + { + int a = 256 - ((rr - rr1) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + + if (l == (map_len - 1)) + { + int a = 1 + (ll >> 8); + + *dst += ARGB_JOIN((a * (A_VAL(map) - A_VAL(dst))) >> 8, + (a * (R_VAL(map) - R_VAL(dst))) >> 8, + (a * (G_VAL(map) - G_VAL(dst))) >> 8, + (a * (B_VAL(map) - B_VAL(dst))) >> 8); + } + } + dst++; xx += axx; yy += ayx; + } +} + +static void +angular_repeat_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Angular_Data *gdata = (Angular_Data *)params_data; + + int xx, yy; + int ss = (gdata->s) << 16; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + + while (dst < dst_end) + { + int ll = ss * (M_PI + atan2(yy, xx)), l = ll >> 16; + + if (l >= map_len) + l = (l % map_len); + *dst = map[l]; + if (l == (map_len - 1)) + { + int a = 1 + (ll >> 8); + + *dst += ARGB_JOIN((a * (A_VAL(map) - A_VAL(dst))) >> 8, + (a * (R_VAL(map) - R_VAL(dst))) >> 8, + (a * (G_VAL(map) - G_VAL(dst))) >> 8, + (a * (B_VAL(map) - B_VAL(dst))) >> 8); + } + dst++; xx += axx; yy += ayx; + } +} + +static void +angular_repeat_annulus(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Angular_Data *gdata = (Angular_Data *)params_data; + + int xx, yy; + int ss = (gdata->s) << 16; + int r1 = gdata->s, r0 = gdata->an * r1; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + + while (dst < dst_end) + { + int rr = hypot(xx, yy), r = (rr >> 16); + + *dst = 0; + if ((r >= r0) && (r <= r1)) + { + int ll = ss * (M_PI + atan2(yy, xx)), l = ll >> 16; + + l += (ll - (l << 16)) >> 15; + if (l >= map_len) + l = (l % map_len); + *dst = map[l]; + } + dst++; xx += axx; yy += ayx; + } +} + +static void +angular_repeat(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Angular_Data *gdata = (Angular_Data *)params_data; + + int xx, yy; + int ss = (gdata->s) << 16; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + + while (dst < dst_end) + { + int ll = ss * (M_PI + atan2(yy, xx)), l = ll >> 16; + + l += (ll - (l << 16)) >> 15; + if (l >= map_len) + l = (l % map_len); + *dst = map[l]; + dst++; xx += axx; yy += ayx; + } +} + +static void +angular_restrict_aa_annulus(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Angular_Data *gdata = (Angular_Data *)params_data; + + int xx, yy; + int ss = (gdata->s) << 16; + int r1 = gdata->s, r0 = gdata->an * r1; + int rr0 = r0 << 16, rr1 = r1 << 16; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + + while (dst < dst_end) + { + int rr = hypot(xx, yy), r = (rr >> 16); + + *dst = 0; + if ( (r >= r0) && (r <= r1) ) + { + int ll = ss * (M_PI + atan2(yy, xx)), l = ll >> 16; + + if (l < map_len) + { + *dst = map[l]; + if (r == r0) + { + int a = 1 + ((rr - rr0) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (r == r1) + { + int a = 256 - ((rr - rr1) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (l == (map_len - 1)) + { + int a = 256 - ((ll - (l << 16)) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (l == 0) + { + int a = 1 + (ll >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + } + } + dst++; xx += axx; yy += ayx; + } +} + +static void +angular_restrict_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Angular_Data *gdata = (Angular_Data *)params_data; + + int xx, yy; + int ss = (gdata->s) << 16; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + + while (dst < dst_end) + { + int ll = ss * (M_PI + atan2(yy, xx)), l = ll >> 16; + + *dst = 0; + if (l < map_len) + { + *dst = map[l]; + if (l == (map_len - 1)) + { + int a = 256 - ((ll - (l << 16)) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (l == 0) + { + int a = 1 + (ll >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + } + dst++; xx += axx; yy += ayx; + } +} + +static void +angular_restrict_annulus(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Angular_Data *gdata = (Angular_Data *)params_data; + + int xx, yy; + int ss = (gdata->s) << 16; + int r1 = gdata->s, r0 = gdata->an * r1; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + + while (dst < dst_end) + { + int rr = hypot(xx, yy), r = (rr >> 16); + + *dst = 0; + if ( (r >= r0) && (r <= r1) ) + { + int ll = ss * (M_PI + atan2(yy, xx)), l = ll >> 16; + + l += (ll - (l << 16)) >> 15; + if (l < map_len) + *dst = map[l]; + } + dst++; xx += axx; yy += ayx; + } +} + +static void +angular_restrict(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Angular_Data *gdata = (Angular_Data *)params_data; + + int xx, yy; + int ss = (gdata->s) << 16; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + + while (dst < dst_end) + { + int ll = ss * (M_PI + atan2(yy, xx)), l = ll >> 16; + + *dst = 0; + l += (ll - (l << 16)) >> 15; + if (l < map_len) + *dst = map[l]; + dst++; xx += axx; yy += ayx; + } +} + diff --git a/legacy/evas/src/lib/engines/common/evas_gradient_linear.c b/legacy/evas/src/lib/engines/common/evas_gradient_linear.c new file mode 100644 index 0000000000..62f85f87d9 --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_gradient_linear.c @@ -0,0 +1,582 @@ +#include "evas_common.h" +#include + + +typedef struct _Linear_Data Linear_Data; +struct _Linear_Data +{ + int sx; +}; + +static Linear_Data linear_data = {-1}; + + +static void +linear_setup_geom(RGBA_Gradient *gr, int spread); + +static int +linear_has_alpha(RGBA_Gradient *gr, int spread); + +static int +linear_get_map_len(RGBA_Gradient *gr, int spread); + +static Gfx_Func_Gradient_Span +linear_get_span_func(RGBA_Gradient *gr, int spread, unsigned char aa); + +static RGBA_Gradient_Type linear = {"linear", &linear_data, linear_setup_geom, linear_has_alpha, linear_get_map_len, linear_get_span_func}; + + +/** internal functions **/ +static void +linear_reflect(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +linear_reflect_aa_cropped(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +linear_reflect_cropped(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +linear_repeat_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +linear_repeat(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +linear_repeat_aa_cropped(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +linear_repeat_cropped(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +linear_restrict(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +linear_restrict_cropped(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +linear_restrict_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +linear_restrict_aa_cropped(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + + + +RGBA_Gradient_Type * +evas_common_gradient_linear_get(void) +{ + return &linear; +} + + +static void +linear_setup_geom(RGBA_Gradient *gr, int spread) +{ + int err = 1; + char *s, *p, key[256]; + float val = -1; + + if (!gr || (gr->type.geometer != &linear)) return; + + linear_data.sx = -1; + if (!gr->type.params || !*(gr->type.params)) + return; + + s = strdup(gr->type.params); + if (!s) return; + + p = s; + while (p = evas_common_gradient_get_key_fval(p, key, &val)) + { + if (!strcmp(key, "extent")) + err = 0; + else + { + err = 1; + goto done; + } + } + done: + if (!err) + { + if (val < 0.0) + val = -val; + linear_data.sx = val * gr->fill.w; + } + free(s); +} + + +static int +linear_has_alpha(RGBA_Gradient *gr, int spread) +{ + if (!gr || (gr->type.geometer != &linear)) return 0; + if (gr->map.has_alpha) + return 1; + if (linear_data.sx >= 0) + return 1; + if (spread == _EVAS_TEXTURE_RESTRICT) + return 1; + return 0; +} + +static int +linear_get_map_len(RGBA_Gradient *gr, int spread) +{ + if (!gr || (gr->type.geometer != &linear)) return 0; + return gr->fill.h; +} + +static Gfx_Func_Gradient_Span +linear_get_span_func(RGBA_Gradient *gr, int spread, unsigned char aa) +{ + Gfx_Func_Gradient_Span sfunc = NULL; + + if (!gr || (gr->type.geometer != &linear)) return sfunc; + switch (spread) + { + case _EVAS_TEXTURE_REFLECT: + { + if (aa) + { + if (linear_data.sx >= 0) + sfunc = linear_reflect_aa_cropped; + else + sfunc = linear_reflect; + } + else + { + if (linear_data.sx >= 0) + sfunc = linear_reflect_cropped; + else + sfunc = linear_reflect; + } + } + break; + case _EVAS_TEXTURE_REPEAT: + { + if (aa) + { + if (linear_data.sx >= 0) + sfunc = linear_repeat_aa_cropped; + else + sfunc = linear_repeat_aa; + } + else + { + if (linear_data.sx >= 0) + sfunc = linear_repeat_cropped; + else + sfunc = linear_repeat; + } + } + break; + case _EVAS_TEXTURE_RESTRICT: + { + if (aa) + { + if (linear_data.sx >= 0) + sfunc = linear_restrict_aa_cropped; + else + sfunc = linear_restrict_aa; + } + else + { + if (linear_data.sx >= 0) + sfunc = linear_restrict_cropped; + else + sfunc = linear_restrict; + } + } + break; + default: + sfunc = linear_reflect; + break; + } + return sfunc; +} + +static void +linear_reflect(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + int yy = ayx * x + ayy * y; + + while (dst < dst_end) + { + int l = (yy >> 16); + + l += (yy - (l << 16)) >> 15; + if (l < 0) l = -l; + + if (l >= map_len) + { + int m = (l % (2 * map_len)); + + l = (l % map_len); + if (m >= map_len) + l = map_len - l - 1; + } + *dst++ = map[l]; yy += ayx; + } +} + +static void +linear_reflect_aa_cropped(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Linear_Data *gdata = (Linear_Data *)params_data; + int yy = (ayx * x) + (ayy * y); + int xx = (axx * x) + (axy * y); + int w = gdata->sx; + + while (dst < dst_end) + { + int ex = (xx >> 16); + + *dst = 0; + if ((unsigned)ex < w) + { + int l = (yy >> 16); + + l += (yy - (l << 16)) >> 15; + if (l < 0) l = -l; + + if (l >= map_len) + { + int m = (l % (2 * map_len)); + + l = (l % map_len); + if (m >= map_len) + l = map_len - l - 1; + } + *dst = map[l]; + if (ex == 0) + { + int a = 1 + (xx >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (ex == (w - 1)) + { + int a = 256 - ((xx - (ex << 16)) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + } + dst++; yy += ayx; xx += axx; + } +} + +static void +linear_reflect_cropped(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Linear_Data *gdata = (Linear_Data *)params_data; + int yy = (ayx * x) + (ayy * y); + int xx = (axx * x) + (axy * y); + int w = gdata->sx; + + while (dst < dst_end) + { + int ex = (xx >> 16); + + ex += (xx - (ex << 16)) >> 15; + *dst = 0; + if ((unsigned)ex < w) + { + int l = (yy >> 16); + + l += (yy - (l << 16)) >> 15; + if (l < 0) l = -l; + if (l >= map_len) + { + int m = (l % (2 * map_len)); + + l = (l % map_len); + if (m >= map_len) + l = map_len - l - 1; + } + *dst = map[l]; + } + dst++; yy += ayx; xx += axx; + } +} + +static void +linear_repeat_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + int yy = ayx * x + ayy * y; + + while (dst < dst_end) + { + int l = (yy >> 16); + + l = l % map_len; + if (l < 0) + l += map_len; + + *dst = map[l]; + if (l == 0) + { + int a = 256 - ((yy - ((yy >> 16) << 16)) >> 8); + DATA32 *c = map + (map_len - 1); + + *dst += ARGB_JOIN((a * (A_VAL(c) - A_VAL(dst))) >> 8, + (a * (R_VAL(c) - R_VAL(dst))) >> 8, + (a * (G_VAL(c) - G_VAL(dst))) >> 8, + (a * (B_VAL(c) - B_VAL(dst))) >> 8); + } + dst++; yy += ayx; + } +} + +static void +linear_repeat_aa_cropped(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Linear_Data *gdata = (Linear_Data *)params_data; + int yy = (ayx * x) + (ayy * y); + int xx = (axx * x) + (axy * y); + int w = gdata->sx; + + while (dst < dst_end) + { + int ex = (xx >> 16); + + *dst = 0; + if ((unsigned)ex < w) + { + int l = (yy >> 16); + + l = l % map_len; + if (l < 0) + l += map_len; + + *dst = map[l]; + if (ex == 0) + { + int a = 1 + (xx >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (ex == (w - 1)) + { + int a = 256 - ((xx - (ex << 16)) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if ((l == 0) && (ex != 0)) + { + int a = 256 - ((yy - ((yy >> 16) << 16)) >> 8); + DATA32 *c = map + (map_len - 1); + + *dst += ARGB_JOIN((a * (A_VAL(c) - A_VAL(dst))) >> 8, + (a * (R_VAL(c) - R_VAL(dst))) >> 8, + (a * (G_VAL(c) - G_VAL(dst))) >> 8, + (a * (B_VAL(c) - B_VAL(dst))) >> 8); + } + } + dst++; yy += ayx; xx += axx; + } +} + +static void +linear_repeat(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + int yy = ayx * x + ayy * y; + + while (dst < dst_end) + { + int l = (yy >> 16); + + l += (yy - (l << 16)) >> 15; + l = l % map_len; + if (l < 0) + l += map_len; + *dst++ = map[l]; yy += ayx; + } +} + +static void +linear_repeat_cropped(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Linear_Data *gdata = (Linear_Data *)params_data; + int yy = (ayx * x) + (ayy * y); + int xx = (axx * x) + (axy * y); + int w = gdata->sx; + + while (dst < dst_end) + { + int ex = (xx >> 16); + + ex += (xx - (ex << 16)) >> 15; + *dst = 0; + if ((unsigned)ex < w) + { + int l = (yy >> 16); + + l += (yy - (l << 16)) >> 15; + l = l % map_len; + if (l < 0) + l += map_len; + *dst = map[l]; + } + dst++; yy += ayx; xx += axx; + } +} + +static void +linear_restrict_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + int yy = ayx * x + ayy * y; + + while (dst < dst_end) + { + int l = (yy >> 16); + + *dst = 0; + if ((unsigned)l < map_len) + { + *dst = map[l]; + if (l == (map_len - 1)) + { + int a = 256 - ((yy - (l << 16)) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (l == 0) + { + int a = 1 + (yy >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + } + dst++; yy += ayx; + } +} + +static void +linear_restrict_aa_cropped(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Linear_Data *gdata = (Linear_Data *)params_data; + int yy = (ayx * x) + (ayy * y); + int xx = (axx * x) + (axy * y); + int w = gdata->sx; + + while (dst < dst_end) + { + int ex = (xx >> 16); + + *dst = 0; + if ((unsigned)ex < w) + { + int l = (yy >> 16); + + if ((unsigned)l < map_len) + { + *dst = map[l]; + if (ex == 0) + { + int a = 1 + (xx >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (ex == (w - 1)) + { + int a = 256 - ((xx - (ex << 16)) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (l == 0) + { + int a = 1 + (yy >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (l == (map_len - 1)) + { + int a = 256 - ((yy - (l << 16)) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + } + } + dst++; yy += ayx; xx += axx; + } +} + +static void +linear_restrict(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + int yy = (ayx * x) + (ayy * y); + + while (dst < dst_end) + { + int l = (yy >> 16); + + l += (yy - (l << 16)) >> 15; + *dst = 0; + if ((unsigned)l < map_len) + *dst = map[l]; + dst++; yy += ayx; + } +} + +static void +linear_restrict_cropped(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Linear_Data *gdata = (Linear_Data *)params_data; + int yy = (ayx * x) + (ayy * y); + int xx = (axx * x) + (axy * y); + int w = gdata->sx; + + while (dst < dst_end) + { + int ex = (xx >> 16); + + ex += (xx - (ex << 16)) >> 15; + + *dst = 0; + if ((unsigned)ex < w) + { + int l = (yy >> 16); + + l += (yy - (l << 16)) >> 15; + if ((unsigned)l < map_len) + *dst = map[l]; + } + dst++; yy += ayx; xx += axx; + } +} + + diff --git a/legacy/evas/src/lib/engines/common/evas_gradient_main.c b/legacy/evas/src/lib/engines/common/evas_gradient_main.c index dec526fc77..dcd61ca08f 100644 --- a/legacy/evas/src/lib/engines/common/evas_gradient_main.c +++ b/legacy/evas/src/lib/engines/common/evas_gradient_main.c @@ -1,11 +1,69 @@ #include "evas_common.h" #include + +static void _get_word(char *in, char *key); +static void evas_common_gradient_map_argb(RGBA_Draw_Context *dc, RGBA_Gradient *gr, + int spread); +static void evas_common_gradient_map_ahsv(RGBA_Draw_Context *dc, RGBA_Gradient *gr, + int spread); + +static void +_get_word(char *in, char *key) +{ + char *p, *pp; + int l; + + if (!key) return; + *key = 0; + if (!in || !*in) return; + + p = in; + while (*p && isspace(*p)) + p++; + if (!*p) return; + pp = p; + while (*pp && !isspace(*pp)) + pp++; + l = pp - p; + if (l >= 255) return; + *(p + l) = 0; + strncpy(key, p, l + 1); +} + +char * +evas_common_gradient_get_key_fval(char *in, char *key, float *val) +{ + char *p, *pp, sval[256]; + + if (!key || !val) return NULL; + *key = 0; + if (!in || !*in) return NULL; + p = strchr(in, '='); + if (!p || !*p) return NULL; + *p = 0; p++; + if (!*p) return NULL; + pp = strchr(p, ';'); + if (!pp || !*pp) return NULL; + _get_word(in, key); + if (!*key) return NULL; + *pp = 0; + _get_word(p, sval); + if (!sval[0]) return NULL; + *val = atof(sval); + return (pp + 1); +} + void evas_common_gradient_init(void) { } +void +evas_common_gradient_shutdown(void) +{ +} + RGBA_Gradient * evas_common_gradient_new(void) { @@ -18,58 +76,184 @@ evas_common_gradient_new(void) void evas_common_gradient_free(RGBA_Gradient *gr) { + if (!gr) return; evas_common_gradient_colors_clear(gr); + if (gr->type.name) free(gr->type.name); + if (gr->type.params) free(gr->type.params); + if (gr->map.data) free(gr->map.data); free(gr); } void evas_common_gradient_colors_clear(RGBA_Gradient *gr) { + RGBA_Gradient_Color *p, *pp; + + if (!gr) return; if (gr->colors) { Evas_Object_List *l; while (gr->colors) { - l = gr->colors; - gr->colors = evas_object_list_remove(gr->colors, gr->colors); - free(l); + l = gr->colors; + gr->colors = evas_object_list_remove(gr->colors, gr->colors); + free(l); } gr->colors = NULL; + gr->ncolors = 0; + gr->len = 0; } } void evas_common_gradient_color_add(RGBA_Gradient *gr, int r, int g, int b, int a, int dist) { - RGBA_Gradient_Color *gc; + RGBA_Gradient_Color *gc, *gcm, *gc_last; - gc = malloc(sizeof(RGBA_Gradient_Color)); - gc->r = r; - gc->g = g; - gc->b = b; - gc->a = a; - gc->dist = dist; + if (!gr) return; + gc = malloc(sizeof(RGBA_Gradient_Color)); + if (!gc) return; + if (dist < 1) dist = 1; + if (r < 0) r = 0; if (r > 255) r = 255; + if (g < 0) g = 0; if (g > 255) g = 255; + if (b < 0) b = 0; if (b > 255) b = 255; + if (a < 0) a = 0; if (a > 255) a = 255; + gc->r = r; + gc->g = g; + gc->b = b; + gc->a = a; + gc->dist = dist; + + if (!gr->colors) + { + gr->colors = evas_object_list_append(gr->colors, gc); + gr->ncolors = 1; + gr->len = 1; + if (a < 255) + gr->has_alpha = 1; + return; + } + gcm = malloc(sizeof(RGBA_Gradient_Color)); + if (!gcm) { free(gc); return; } + gc_last = (RGBA_Gradient_Color *)(gr->colors->last); + gcm->r = (gc_last->r + r) / 2; + gcm->g = (gc_last->g + g) / 2; + gcm->b = (gc_last->b + b) / 2; + gcm->a = (gc_last->a + a) / 2; + gcm->dist = dist; + gr->colors = evas_object_list_append(gr->colors, gcm); + gr->len += gc_last->dist; gr->colors = evas_object_list_append(gr->colors, gc); + gr->len += dist; + gr->ncolors += 2; + if (a < 255) + gr->has_alpha = 1; } void -evas_common_gradient_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h, RGBA_Gradient *gr, double angle) +evas_common_gradient_type_set(RGBA_Gradient *gr, char *name) { - Gfx_Func_Blend_Src_Dst func; - int yy, xx, i, len; - int xoff, yoff, divw, divh; - DATA32 *ptr, *dptr, *buf, *map; - int *hlut, *vlut; - int o_x, o_y, o_w, o_h; - RGBA_Image *tmp; + if (!gr) return; + if (!name || !*name) + name = "linear"; + gr->type.geometer = evas_common_gradient_geometer_get(name); + if (gr->type.name) free(gr->type.name); + gr->type.name = strdup(gr->type.geometer->name); +} - o_x = x; o_y = y; o_w = w; o_h = h; +void +evas_common_gradient_type_params_set(RGBA_Gradient *gr, char *params) +{ + if (!gr) return; + if (params && !*params) + params = NULL; + if (gr->type.params) free(gr->type.params); + gr->type.params = NULL; + if (params) gr->type.params = strdup(params); +} - if ((w <= 0) || (h <= 0)) return; +void +evas_common_gradient_fill_set(RGBA_Gradient *gr, int x, int y, int w, int h) +{ + if (!gr) return; + gr->fill.x = x; + gr->fill.y = y; + gr->fill.w = w; + gr->fill.h = h; +} +RGBA_Gradient * +evas_common_gradient_geometry_init(RGBA_Gradient *gr, int spread) +{ + if (!gr) return NULL; + gr->type.geometer = evas_common_gradient_geometer_get(gr->type.name); + if (!gr->type.geometer) + { + evas_common_gradient_free(gr); + return NULL; + } + gr->type.geometer->setup_geom(gr, spread); + return gr; +} + +int +evas_common_gradient_has_alpha(RGBA_Gradient *gr, int spread) +{ + if (!gr || !gr->type.geometer) return 0; + return gr->type.geometer->has_alpha(gr, spread); +} + +RGBA_Gradient_Type * +evas_common_gradient_geometer_get(char *name) +{ + RGBA_Gradient_Type *geom = NULL; + + if (!name || !*name) + name = "linear"; + if (!strcmp(name,"linear")) + geom = evas_common_gradient_linear_get(); + else if (!strcmp(name,"radial")) + geom = evas_common_gradient_radial_get(); + else if (!strcmp(name,"angular")) + geom = evas_common_gradient_angular_get(); + else if (!strcmp(name,"sinusoidal")) + geom = evas_common_gradient_sinusoidal_get(); + else if (!strcmp(name,"rectangular")) + geom = evas_common_gradient_rectangular_get(); + if (!geom) + geom = evas_common_gradient_linear_get(); + return geom; +} + + +void +evas_common_gradient_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, + int x, int y, int w, int h, RGBA_Gradient *gr, + double angle, int spread) +{ + Gfx_Func_Gradient_Span sfunc; + Gfx_Func_Blend_Src_Dst bfunc; + int len; + int xin, yin, xoff, yoff; + int axx, axy, ayx, ayy; + DATA32 *pdst, *dst_end, *buf, *map; + RGBA_Image *line_buf; + void *gdata; + unsigned char buf_a = 0; + + if (!dst || !dc || !gr) + return; + if (!gr->map.data || !gr->type.geometer) + return; + if ((gr->fill.w < 1) || (gr->fill.h < 1)) + return; + if ((w < 1) || (h < 1)) + return; if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, dst->image->w, dst->image->h))) - return; + return; + + xin = x; yin = y; if (x < 0) { w += x; @@ -105,170 +289,541 @@ evas_common_gradient_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, } if ((w <= 0) || (h <= 0)) return; - hlut = malloc(sizeof(int) * o_w); - if (!hlut) return; - vlut = malloc(sizeof(int) * o_h); - if (!vlut) + xoff = (xin - x) - gr->fill.x; + yoff = (yin - y) - gr->fill.y; + + line_buf = evas_common_image_line_buffer_obtain(w); + if (!line_buf) { - free(hlut); + evas_common_image_line_buffer_release(); return; } - - xoff = x - o_x; - yoff = y - o_y; - - if (o_w > o_h) len = o_w * 16; - else len = o_h * 16; - - map = evas_common_gradient_map(gr, dc, len); - if (!map) - { - free(hlut); - free(vlut); - return; - } - tmp = evas_common_image_create(w, 1); - if (!tmp) - { - free(hlut); - free(vlut); - free(map); - return; - } - tmp->flags |= RGBA_IMAGE_HAS_ALPHA; - - evas_common_cpu_end_opt(); - xx = (int)(32 * sin(((angle + 180) * 2 * 3.141592654) / 360)); - yy = -(int)(32 * cos(((angle + 180) * 2 * 3.141592654) / 360)); - divw = ((o_w - 1) << 5); - divh = ((o_h - 1) << 5); - if (divw < 1) divw = 1; - if (divh < 1) divh = 1; - - if (xx < 0) - { - for (i = 0; i < o_w; i++) hlut[i] = (-xx * (o_w - 1 - i) * len) / divw; - } + + if ((spread < 0) || (spread > 2)) spread = 0; + buf_a = gr->type.geometer->has_alpha(gr, spread); + if (buf_a) + line_buf->flags |= RGBA_IMAGE_HAS_ALPHA; else - { - for (i = 0; i < o_w; i++) hlut[i] = (xx * i * len) / divw; - } - if (yy < 0) - { - for (i = 0; i < o_h; i++) vlut[i] = (-yy * (o_h - 1 - i) * len) / divh; - } - else - { - for (i = 0; i < o_h; i++) vlut[i] = (yy * i * len) / divh; - } + line_buf->flags &= ~RGBA_IMAGE_HAS_ALPHA; + + gdata = gr->type.geometer->geom_data; - buf = tmp->image->data; - func = evas_common_draw_func_blend_get(tmp, dst, w); - ptr = dst->image->data + (y * dst->image->w) + x; - for (yy = 0; yy < h; yy++) + sfunc = gr->type.geometer->get_span_func(gr, spread, dc->anti_alias); + bfunc = evas_common_draw_func_blend_get(line_buf, dst, w); + + angle = (angle * M_PI) / 180.0; + axx = (cos(angle) * 65536.0); + ayy = axx; + axy = (sin(angle) * 65536.0); + ayx = -axy; + + map = gr->map.data; + len = gr->map.len; + buf = line_buf->image->data; + pdst = dst->image->data + (y * dst->image->w) + x; + dst_end = pdst + (h * dst->image->w); + + while (pdst < dst_end) { - dptr = buf; - for (xx = 0; xx < w; xx++) - { - i = vlut[yoff + yy] + hlut[xoff + xx]; - if (i < 0) i = 0; - else if (i >= len) i = len - 1; - *dptr = map[i]; - dptr++; - } - func(buf, ptr, w); - ptr += dst->image->w; + evas_common_cpu_end_opt(); + sfunc(map, len, buf, w, xoff, yoff, axx, axy, ayx, ayy, gdata); + bfunc(buf, pdst, w); + pdst += dst->image->w; + yoff++; } - free(hlut); - free(vlut); - free(map); - evas_common_image_free(tmp); + + evas_common_image_line_buffer_release(); } -DATA32 * -evas_common_gradient_map(RGBA_Gradient *gr, RGBA_Draw_Context *dc, int len) + +static void +evas_common_gradient_map_argb(RGBA_Draw_Context *dc, RGBA_Gradient *gr, int spread) { - DATA32 *map, *pmap, v, vv; - Evas_Object_List *l; + Evas_Object_List *lc; + DATA32 *pmap, *map_end; RGBA_Gradient_Color *gc, *gc_next; - int r, g, b, a, rr, gg, bb, aa, i, j, inc, v1, v2, total; + int d, n; + int i, prev_i, ii, dii; + int r, g, b, a; + int next_r, next_g, next_b, next_a; + int rr, drr, gg, dgg, bb, dbb, aa, daa; + int mr = 256, mg = 256, mb = 256, ma = 256; - if (!gr->colors) return NULL; - if (!gr->colors->next) return NULL; - - total = 1; - for (l = gr->colors; l->next; l = l->next) + if (!gr || !gr->colors || !dc) + return; + if ((gr->fill.w < 1) || (gr->fill.h < 1)) + return; + if (!gr->type.geometer) + return; + d = gr->type.geometer->get_map_len(gr, spread); + if (d < 1) { - gc = (RGBA_Gradient_Color *)l; - total += gc->dist; + if (gr->map.data) + free(gr->map.data); + gr->map.data = NULL; + gr->map.len = 0; + return; } - map = malloc(len * sizeof(DATA32)); - if (!map) return NULL; - pmap = malloc(total * sizeof(DATA32)); - if (!pmap) - { - free(map); - return NULL; - } - i = 0; - for (l = gr->colors; l; l = l->next) - { - gc = (RGBA_Gradient_Color *)l; + if ((d != gr->map.len) || (!gr->map.data)) + gr->map.data = realloc(gr->map.data, d * sizeof(DATA32)); + if (!gr->map.data) + { gr->map.len = 0; return; } + gr->map.len = d; + gr->map.has_alpha = gr->has_alpha; - if (l->next) + pmap = gr->map.data; + map_end = pmap + gr->map.len; + + gc = (RGBA_Gradient_Color *)gr->colors; + r = gc->r; g = gc->g; b = gc->b; a = gc->a; + if (dc->mul.use) + { + mr = 1 + R_VAL(&dc->mul.col); mg = 1 + G_VAL(&dc->mul.col); + mb = 1 + B_VAL(&dc->mul.col); ma = 1 + A_VAL(&dc->mul.col); + if (ma < 256) gr->map.has_alpha = 1; + r = (r * mr) >> 8; g = (g * mg) >> 8; + b = (b * mb) >> 8; a = (a * ma) >> 8; + } + + /* two 'trivial' cases: */ + + /* just one color, or the grad map is of length 1 */ + if (!gr->colors->next || (gr->map.len == 1)) + { + DATA32 c = ARGB_JOIN(a,r,g,b); + + while (pmap < map_end) + *pmap++ = c; + return; + } + + /* do simple gradient mapping if just two equally weighted colors */ + if ((gr->ncolors == 3) && ((2 * gc->dist) == (gr->len - 1))) + { + gc_next = (RGBA_Gradient_Color *)(gr->colors->last); + next_r = gc_next->r; next_g = gc_next->g; + next_b = gc_next->b; next_a = gc_next->a; + if (dc->mul.use) + { + next_r = (next_r * mr) >> 8; next_g = (next_g * mg) >> 8; + next_b = (next_b * mb) >> 8; next_a = (next_a * ma) >> 8; + } + d = (gr->map.len - 1); + rr = r << 16; drr = ((next_r - r) << 16) / d; + gg = g << 16; dgg = ((next_g - g) << 16) / d; + bb = b << 16; dbb = ((next_b - b) << 16) / d; + aa = a << 16; daa = ((next_a - a) << 16) / d; + + while (pmap < map_end) { - gc_next = (RGBA_Gradient_Color *)l->next; - for (j = 0; j < gc->dist; j++) - { - v1 = (j << 16) / gc->dist; - v2 = 65536 - v1; - r = ((gc->r * v2) + (gc_next->r * v1)) >> 16; - g = ((gc->g * v2) + (gc_next->g * v1)) >> 16; - b = ((gc->b * v2) + (gc_next->b * v1)) >> 16; - a = ((gc->a * v2) + (gc_next->a * v1)) >> 16; - if (dc->mul.use) - { - r = ((r + 1) * (R_VAL(&dc->mul.col))) >> 8; - g = ((g + 1) * (G_VAL(&dc->mul.col))) >> 8; - b = ((b + 1) * (B_VAL(&dc->mul.col))) >> 8; - a = ((a + 1) * (A_VAL(&dc->mul.col))) >> 8; - } - pmap[i++] = (a << 24) | (r << 16) | (g << 8) | b; - } - } - else - { - r = gc->r; - g = gc->g; - b = gc->b; - a = gc->a; - pmap[i++] = (a << 24) | (r << 16) | (g << 8) | b; + r = rr >> 16; r += (rr - (r << 16)) >> 15; + g = gg >> 16; g += (gg - (g << 16)) >> 15; + b = bb >> 16; b += (bb - (b << 16)) >> 15; + a = aa >> 16; a += (aa - (a << 16)) >> 15; + *pmap++ = ARGB_JOIN(a,r,g,b); + rr += drr; gg += dgg; bb += dbb; aa += daa; } + return; } - inc = ((total - 1) << 16) / (len); - j = 0; - for (i = 0; i < len; i++) + + /* general case, gr->map.len > 1 */ + lc = gr->colors->next; + gc_next = (RGBA_Gradient_Color *)lc; + next_r = gc_next->r; next_g = gc_next->g; + next_b = gc_next->b; next_a = gc_next->a; + if (dc->mul.use) { - v = pmap[j >> 16]; - if ((j >> 16) < total) vv = pmap[(j >> 16) + 1]; - else vv = pmap[(j >> 16) ]; - v1 = j - ((j >> 16) << 16); - v2 = 65536 - v1; - b = ((v) ) & 0xff; - g = ((v) >> 8 ) & 0xff; - r = ((v) >> 16 ) & 0xff; - a = ((v) >> 24 ) & 0xff; - bb = ((vv) ) & 0xff; - gg = ((vv) >> 8 ) & 0xff; - rr = ((vv) >> 16) & 0xff; - aa = ((vv) >> 24) & 0xff; - r = ((r * v2) + (rr * v1)) >> 16; - g = ((g * v2) + (gg * v1)) >> 16; - b = ((b * v2) + (bb * v1)) >> 16; - a = ((a * v2) + (aa * v1)) >> 16; - map[i] = (a << 24) | (r << 16) | (g << 8) | b; - j += inc; + next_r = (next_r * mr) >> 8; next_g = (next_g * mg) >> 8; + next_b = (next_b * mb) >> 8; next_a = (next_a * ma) >> 8; + } + + n = (gr->len - 1) << 16; + d = gc->dist * (gr->map.len - 1); + + i = 1; + prev_i = i; + ii = i << 16; + dii = n / d; + + rr = r << 16; drr = ((next_r - r) * dii); + gg = g << 16; dgg = ((next_g - g) * dii); + bb = b << 16; dbb = ((next_b - b) * dii); + aa = a << 16; daa = ((next_a - a) * dii); + + while (pmap < map_end) + { + i = ii >> 16; + if ((prev_i != i) && (i < gr->ncolors)) + { + while (prev_i < i) + { + prev_i++; + gc = gc_next; lc = lc->next; + gc_next = (RGBA_Gradient_Color *)lc; + } + d = gc->dist * (gr->map.len - 1); + dii = n / d; + r = gc->r; g = gc->g; b = gc->b; a = gc->a; + next_r = gc_next->r; next_g = gc_next->g; + next_b = gc_next->b; next_a = gc_next->a; + if (dc->mul.use) + { + r = (r * mr) >> 8; g = (g * mg) >> 8; + b = (b * mb) >> 8; a = (a * ma) >> 8; + next_r = (next_r * mr) >> 8; next_g = (next_g * mg) >> 8; + next_b = (next_b * mb) >> 8; next_a = (next_a * ma) >> 8; + } + drr = ((next_r - r) * dii); + dgg = ((next_g - g) * dii); + dbb = ((next_b - b) * dii); + daa = ((next_a - a) * dii); + } + r = rr >> 16; r += (rr - (r << 16)) >> 15; + g = gg >> 16; g += (gg - (g << 16)) >> 15; + b = bb >> 16; b += (bb - (b << 16)) >> 15; + a = aa >> 16; a += (aa - (a << 16)) >> 15; + if (r > 255) r = 255; if (r < 0) r = 0; + if (g > 255) g = 255; if (g < 0) g = 0; + if (b > 255) b = 255; if (b < 0) b = 0; + if (a > 255) a = 255; if (a < 0) a = 0; + *pmap++ = ARGB_JOIN(a,r,g,b); + rr += drr; gg += dgg; bb += dbb; aa += daa; + ii += dii; } - free(pmap); - return map; } + +static void +evas_common_gradient_map_ahsv(RGBA_Draw_Context *dc, RGBA_Gradient *gr, int spread) +{ + Evas_Object_List *lc; + DATA32 *pmap, *map_end; + RGBA_Gradient_Color *gc, *gc_next; + int d, n; + int i, prev_i, ii, dii; + int h, s, v, a; + int next_h, next_s, next_v, next_a; + int hh, dhh, ss, dss, vv, dvv, aa, daa; + int r, g, b; + int mr = 256, mg = 256, mb = 256, ma = 256; + + if (!gr || !gr->colors || !dc) + return; + if ((gr->fill.w < 1) || (gr->fill.h < 1)) + return; + if (!gr->type.geometer) + return; + d = gr->type.geometer->get_map_len(gr, spread); + if (d < 1) + { + if (gr->map.data) + free(gr->map.data); + gr->map.data = NULL; + gr->map.len = 0; + return; + } + if ((d != gr->map.len) || (!gr->map.data)) + gr->map.data = realloc(gr->map.data, d * sizeof(DATA32)); + if (!gr->map.data) + { gr->map.len = 0; return; } + gr->map.len = d; + gr->map.has_alpha = gr->has_alpha; + + pmap = gr->map.data; + map_end = pmap + gr->map.len; + + if (dc->mul.use) + { + mr = 1 + R_VAL(&dc->mul.col); mg = 1 + G_VAL(&dc->mul.col); + mb = 1 + B_VAL(&dc->mul.col); ma = 1 + A_VAL(&dc->mul.col); + if (ma < 256) gr->map.has_alpha = 1; + } + + gc = (RGBA_Gradient_Color *)gr->colors; + r = gc->r; g = gc->g; b = gc->b; a = gc->a; + + /* two 'trivial' cases: */ + + /* just one color, or the grad map is of length 1 */ + if (!gr->colors->next || (gr->map.len == 1)) + { + DATA32 c; + + if (dc->mul.use) + { + r = (r * mr) >> 8; g = (g * mg) >> 8; + b = (b * mb) >> 8; a = (a * ma) >> 8; + } + c = ARGB_JOIN(a,r,g,b); + while (pmap < map_end) + *pmap++ = c; + return; + } + + evas_common_convert_rgb_to_hsv_int(r, g, b, &h, &s, &v); + + /* do simple gradient mapping if just two equally weighted colors */ + if ((gr->ncolors == 3) && ((2 * gc->dist) == (gr->len - 1))) + { + gc_next = (RGBA_Gradient_Color *)(gr->colors->last); + next_a = gc_next->a; + evas_common_convert_rgb_to_hsv_int(gc_next->r, gc_next->g, gc_next->b, + &next_h, &next_s, &next_v); + d = (gr->map.len - 1); + hh = h << 16; dhh = ((next_h - h) << 16) / d; + ss = s << 16; dss = ((next_s - s) << 16) / d; + vv = v << 16; dvv = ((next_v - v) << 16) / d; + aa = a << 16; daa = ((next_a - a) << 16) / d; + + while (pmap < map_end) + { + h = hh >> 16; h += (hh - (h << 16)) >> 15; + s = ss >> 16; s += (ss - (s << 16)) >> 15; + v = vv >> 16; v += (vv - (v << 16)) >> 15; + a = aa >> 16; a += (aa - (a << 16)) >> 15; + evas_common_convert_hsv_to_rgb_int(h, s, v, &r, &g, &b); + if (dc->mul.use) + { + r = (r * mr) >> 8; g = (g * mg) >> 8; + b = (b * mb) >> 8; a = (a * ma) >> 8; + } + *pmap++ = ARGB_JOIN(a,r,g,b); + hh += dhh; ss += dss; vv += dvv; aa += daa; + } + return; + } + + /* general case, gr->map.len > 1 */ + lc = gr->colors->next; + gc_next = (RGBA_Gradient_Color *)lc; + next_a = gc_next->a; + evas_common_convert_rgb_to_hsv_int(gc_next->r, gc_next->g, gc_next->b, + &next_h, &next_s, &next_v); + + n = (gr->len - 1) << 16; + d = gc->dist * (gr->map.len - 1); + + i = 1; + prev_i = i; + ii = i << 16; + dii = n / d; + + hh = h << 16; dhh = ((next_h - h) * dii); + ss = s << 16; dss = ((next_s - s) * dii); + vv = v << 16; dvv = ((next_v - v) * dii); + aa = a << 16; daa = ((next_a - a) * dii); + + while (pmap < map_end) + { + i = ii >> 16; + if ((prev_i != i) && (i < gr->ncolors)) + { + while (prev_i < i) + { + prev_i++; + gc = gc_next; lc = lc->next; + gc_next = (RGBA_Gradient_Color *)lc; + } + d = gc->dist * (gr->map.len - 1); + dii = n / d; + a = gc->a; + evas_common_convert_rgb_to_hsv_int(gc->r, gc->g, gc->b, + &h, &s, &v); + next_a = gc_next->a; + evas_common_convert_rgb_to_hsv_int(gc_next->r, gc_next->g, gc_next->b, + &next_h, &next_s, &next_v); + + dhh = ((next_h - h) * dii); + dss = ((next_s - s) * dii); + dvv = ((next_v - v) * dii); + daa = ((next_a - a) * dii); + } + h = hh >> 16; h += (hh - (h << 16)) >> 15; + s = ss >> 16; s += (ss - (s << 16)) >> 15; + v = vv >> 16; v += (vv - (v << 16)) >> 15; + a = aa >> 16; a += (aa - (a << 16)) >> 15; + if (h > 1530) h = 1530; if (h < 0) h = 0; + if (s > 255) s = 255; if (s < 0) s = 0; + if (v > 255) v = 255; if (v < 0) v = 0; + if (a > 255) a = 255; if (a < 0) a = 0; + evas_common_convert_hsv_to_rgb_int(h, s, v, &r, &g, &b); + if (dc->mul.use) + { + r = (r * mr) >> 8; g = (g * mg) >> 8; + b = (b * mb) >> 8; a = (a * ma) >> 8; + } + *pmap++ = ARGB_JOIN(a,r,g,b); + hh += dhh; ss += dss; vv += dvv; aa += daa; + ii += dii; + } +} + +void +evas_common_gradient_map(RGBA_Draw_Context *dc, RGBA_Gradient *gr, int spread) +{ + if (!gr || !dc) return; + if (dc->interpolation.color_space == _EVAS_COLOR_SPACE_AHSV) + { + evas_common_gradient_map_ahsv(dc, gr, spread); + return; + } + evas_common_gradient_map_argb(dc, gr, spread); +} + +/* from imlib2 code */ +void +evas_common_convert_hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b) +{ + int i; + float f, p, q, t; + + v = 255 * v; + if (s == 0) + { + if (r) *r = v; + if (g) *g = v; + if (b) *b = v; + return; + } + h /= 60; + i = h; + f = h - i; + + s = v * s; + f = s * f; + p = v - s; + q = v - f; + t = p + f; + switch (i) + { + case 0: + if (r) *r = v; + if (g) *g = t; + if (b) *b = p; + return; + case 1: + if (r) *r = q; + if (g) *g = v; + if (b) *b = p; + return; + case 2: + if (r) *r = p; + if (g) *g = v; + if (b) *b = t; + return; + case 3: + if (r) *r = p; + if (g) *g = q; + if (b) *b = v; + return; + case 4: + if (r) *r = t; + if (g) *g = p; + if (b) *b = v; + return; + default: + if (r) *r = v; + if (g) *g = p; + if (b) *b = q; + } +} + +void +evas_common_convert_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v) +{ + float min, max, del; + + min = MIN(r,g); min = MIN(min,b); + max = MAX(r,g); max = MAX(max,b); + del = max - min; + + if (v) *v = (max / 255); + if ((max == 0) || (del == 0)) + { + if (s) *s = 0; + if (h) *h = 0; + return; + } + + if (s) *s = (del / max); + + if (!h) return; + if (r == max) + *h = ((g - b) / del); + else if (g == max) + *h = 2 + ((b - r) / del); + else if (b == max) + *h = 4 + ((r - g) / del); + + *h *= 60; + if (*h < 0) *h += 360; +} + +void +evas_common_convert_hsv_to_rgb_int(int h, int s, int v, int *r, int *g, int *b) +{ + int i, f, p, q, t; + + if (s == 0) + { + *r = *g = *b = v; + return; + } + + i = h / 255; + f = h - (i * 255); + s = (v * s) / 255; + f = (s * f) / 255; + p = v - s; + q = v - f; + t = p + f; + switch (i) + { + case 0: + *r = v; *g = t; *b = p; + return; + case 1: + *r = q; *g = v; *b = p; + return; + case 2: + *r = p; *g = v; *b = t; + return; + case 3: + *r = p; *g = q; *b = v; + return; + case 4: + *r = t; *g = p; *b = v; + return; + default: + *r = v; *g = p; *b = q; + } +} + +void +evas_common_convert_rgb_to_hsv_int(int r, int g, int b, int *h, int *s, int *v) +{ + int min, max, del; + + min = MIN(r,g); min = MIN(min,b); + max = MAX(r,g); max = MAX(max,b); + del = max - min; + + *v = max; + if ((max == 0) || (del == 0)) + { + *s = *h = 0; + return; + } + + *s = ((del * 255) / max); + + if (r == max) + *h = (((g - b) * 255) / del); + else if (g == max) + *h = 510 + (((b - r) * 255) / del); + else if (b == max) + *h = 1020 + (((r - g) * 255) / del); + + if (*h < 0) *h += 1530; + +} + diff --git a/legacy/evas/src/lib/engines/common/evas_gradient_radial.c b/legacy/evas/src/lib/engines/common/evas_gradient_radial.c new file mode 100644 index 0000000000..204099c4a1 --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_gradient_radial.c @@ -0,0 +1,453 @@ +#include "evas_common.h" +#include + + +typedef struct _Radial_Data Radial_Data; +struct _Radial_Data +{ + int sx, sy, s; + float r0; +}; + +static Radial_Data radial_data = {32, 32, 32, 0.0}; + + +static void +radial_setup_geom(RGBA_Gradient *gr, int spread); + +static int +radial_has_alpha(RGBA_Gradient *gr, int spread); + +static int +radial_get_map_len(RGBA_Gradient *gr, int spread); + +static Gfx_Func_Gradient_Span +radial_get_span_func(RGBA_Gradient *gr, int spread, unsigned char aa); + +static RGBA_Gradient_Type radial = {"radial", &radial_data, radial_setup_geom, radial_has_alpha, radial_get_map_len, radial_get_span_func}; + + +/** internal functions **/ + +static void +radial_reflect_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +radial_repeat_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +radial_restrict_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +radial_reflect(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +radial_repeat(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +radial_restrict(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +RGBA_Gradient_Type * +evas_common_gradient_radial_get(void) +{ + return &radial; +} + +static void +radial_setup_geom(RGBA_Gradient *gr, int spread) +{ + int err = 1; + char *s, *p, key[256]; + float r0 = 0.0; + + if (!gr || (gr->type.geometer != &radial)) return; + + radial_data.sx = gr->fill.w; + radial_data.sy = gr->fill.h; + radial_data.s = radial_data.sx; + if (radial_data.sy > radial_data.sx) + radial_data.s = radial_data.sy; + radial_data.r0 = 0.0; + + if (!gr->type.params || !*(gr->type.params)) + return; + + s = strdup(gr->type.params); + if (!s) return; + + p = s; + while (p = evas_common_gradient_get_key_fval(p, key, &r0)) + { + if (!strcmp(key, "inner_radius")) + err = 0; + else + { + err = 1; + goto done; + } + } + done: + if (!err) + { + if (r0 < 0.0) r0 = 0.0; + if (r0 > 1.0) r0 = 1.0; + radial_data.r0 = r0; + } + free(s); +} + + +static int +radial_has_alpha(RGBA_Gradient *gr, int spread) +{ + if (!gr || (gr->type.geometer != &radial)) return 0; + if (gr->map.has_alpha) + return 1; + if ((int)radial_data.r0 > 0) + return 1; + if (spread == _EVAS_TEXTURE_RESTRICT) + return 1; + return 0; +} + +static int +radial_get_map_len(RGBA_Gradient *gr, int spread) +{ + int l; + + if (!gr || (gr->type.geometer != &radial)) return 0; + l = radial_data.s; + l -= (int)(l * radial_data.r0); + return l; +} + +static Gfx_Func_Gradient_Span +radial_get_span_func(RGBA_Gradient *gr, int spread, unsigned char aa) +{ + Gfx_Func_Gradient_Span sfunc = NULL; + + if (!gr || (gr->type.geometer != &radial)) return sfunc; + switch (spread) + { + case _EVAS_TEXTURE_REFLECT: + { + if (aa) + sfunc = radial_reflect_aa; + else + sfunc = radial_reflect; + } + break; + case _EVAS_TEXTURE_REPEAT: + { + if (aa) + sfunc = radial_repeat_aa; + else + sfunc = radial_repeat; + } + break; + case _EVAS_TEXTURE_RESTRICT: + { + if (aa) + sfunc = radial_restrict_aa; + else + sfunc = radial_restrict; + } + break; + default: + sfunc = radial_reflect; + break; + } + return sfunc; +} + +static void +radial_reflect_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Radial_Data *gdata = (Radial_Data *)params_data; + + int xx, yy, rr0; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + rr0 = gdata->r0 * gdata->s; + rr0 <<= 16; + + while (dst < dst_end) + { + int ll = (hypot(xx, yy) - rr0), l = (ll >> 16); + + *dst = 0; + if (l == 0) + { + int a = 1 + (ll >> 8); + + *dst = map[0]; + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (l > 0) + { + if (l >= map_len) + { + int m = (l % (2 * map_len)); + + l = (l % map_len); + if (m >= map_len) + l = map_len - l - 1; + } + *dst = map[l]; + } + dst++; xx += axx; yy += ayx; + } +} + +static void +radial_reflect(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Radial_Data *gdata = (Radial_Data *)params_data; + + int xx, yy, rr0; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + rr0 = gdata->r0 * gdata->s; + rr0 <<= 16; + + while (dst < dst_end) + { + int ll = (hypot(xx, yy) - rr0), l = (ll >> 16); + + l += (ll - (l << 16)) >> 15; + *dst = 0; + if (l >= 0) + { + if (l >= map_len) + { + int m = (l % (2 * map_len)); + + l = (l % map_len); + if (m >= map_len) + l = map_len - l - 1; + } + *dst = map[l]; + } + dst++; xx += axx; yy += ayx; + } +} + +static void +radial_repeat_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Radial_Data *gdata = (Radial_Data *)params_data; + + int xx, yy, rr0; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + rr0 = gdata->r0 * gdata->s; + rr0 <<= 16; + + while (dst < dst_end) + { + int ll = (hypot(xx, yy) - rr0), l = (ll >> 16); + + *dst = 0; + if (l == 0) + { + int a = 1 + (ll >> 8); + + *dst = map[0]; + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (l > 0) + { + if (l >= map_len) + l = (l % map_len); + *dst = map[l]; + if (l == 0) + { + int a = 256 - ((ll - ((ll >> 16) << 16)) >> 8); + DATA32 *c = map + (map_len - 1); + + *dst += ARGB_JOIN((a * (A_VAL(c) - A_VAL(dst))) >> 8, + (a * (R_VAL(c) - R_VAL(dst))) >> 8, + (a * (G_VAL(c) - G_VAL(dst))) >> 8, + (a * (B_VAL(c) - B_VAL(dst))) >> 8); + } + } + dst++; xx += axx; yy += ayx; + } +} + +static void +radial_repeat(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Radial_Data *gdata = (Radial_Data *)params_data; + + int xx, yy, rr0; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + rr0 = gdata->r0 * gdata->s; + rr0 <<= 16; + + while (dst < dst_end) + { + int ll = (hypot(xx, yy) - rr0), l = (ll >> 16); + + l += (ll - (l << 16)) >> 15; + *dst = 0; + if (l >= 0) + { + if (l >= map_len) + l = (l % map_len); + *dst = map[l]; + } + dst++; xx += axx; yy += ayx; + } +} + +static void +radial_restrict_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Radial_Data *gdata = (Radial_Data *)params_data; + + int xx, yy, rr0; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + rr0 = gdata->r0 * gdata->s; + rr0 <<= 16; + + while (dst < dst_end) + { + int ll = (hypot(xx, yy) - rr0), l = (ll >> 16); + + *dst = 0; + if ((unsigned)l < map_len) + { + *dst = map[l]; + if (l == (map_len - 1)) + { + int a = 256 - ((ll - (l << 16)) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if ((l == 0) && rr0) + { + int a = 1 + (ll >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + } + dst++; xx += axx; yy += ayx; + } +} + +static void +radial_restrict(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Radial_Data *gdata = (Radial_Data *)params_data; + + int xx, yy, rr0; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + rr0 = gdata->r0 * gdata->s; + rr0 <<= 16; + + while (dst < dst_end) + { + int ll = (hypot(xx, yy) - rr0), l = (ll >> 16); + + l += (ll - (l << 16)) >> 15; + *dst = 0; + if ((unsigned)l < map_len) + *dst = map[l]; + dst++; xx += axx; yy += ayx; + } +} + diff --git a/legacy/evas/src/lib/engines/common/evas_gradient_rectangular.c b/legacy/evas/src/lib/engines/common/evas_gradient_rectangular.c new file mode 100644 index 0000000000..f6ea7fa447 --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_gradient_rectangular.c @@ -0,0 +1,483 @@ +#include "evas_common.h" +#include + + +typedef struct _Rectangular_Data Rectangular_Data; +struct _Rectangular_Data +{ + int sx, sy, s; + float r0; +}; + +static Rectangular_Data rectangular_data = {32, 32, 32, 0.0}; + + +static void +rectangular_setup_geom(RGBA_Gradient *gr, int spread); + +static int +rectangular_has_alpha(RGBA_Gradient *gr, int spread); + +static int +rectangular_get_map_len(RGBA_Gradient *gr, int spread); + +static Gfx_Func_Gradient_Span +rectangular_get_span_func(RGBA_Gradient *gr, int spread, unsigned char aa); + +static RGBA_Gradient_Type rectangular = {"rectangular", &rectangular_data, rectangular_setup_geom, rectangular_has_alpha, rectangular_get_map_len, rectangular_get_span_func}; + + +/** internal functions **/ + +static void +rectangular_reflect_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +rectangular_repeat_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +rectangular_restrict_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +rectangular_reflect(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +rectangular_repeat(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +rectangular_restrict(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +RGBA_Gradient_Type * +evas_common_gradient_rectangular_get(void) +{ + return &rectangular; +} + +static void +rectangular_setup_geom(RGBA_Gradient *gr, int spread) +{ + int err = 1; + char *s, *p, key[256]; + float r0 = 0.0; + + if (!gr || (gr->type.geometer != &rectangular)) return; + + rectangular_data.sx = gr->fill.w; + rectangular_data.sy = gr->fill.h; + rectangular_data.s = rectangular_data.sx; + if (rectangular_data.sy > rectangular_data.sx) + rectangular_data.s = rectangular_data.sy; + rectangular_data.r0 = 0.0; + + if (!gr->type.params || !*(gr->type.params)) + return; + + s = strdup(gr->type.params); + if (!s) return; + + p = s; + while (p = evas_common_gradient_get_key_fval(p, key, &r0)) + { + if (!strcmp(key, "inner_radius")) + err = 0; + else + { + err = 1; + goto done; + } + } + done: + if (!err) + { + if (r0 < 0.0) r0 = 0.0; + if (r0 > 1.0) r0 = 1.0; + rectangular_data.r0 = r0; + } + free(s); +} + + +static int +rectangular_has_alpha(RGBA_Gradient *gr, int spread) +{ + if (!gr || (gr->type.geometer != &rectangular)) return 0; + if (gr->map.has_alpha) + return 1; + if (rectangular_data.r0 > 0.0) + return 1; + if (spread == _EVAS_TEXTURE_RESTRICT) + return 1; + return 0; +} + +static int +rectangular_get_map_len(RGBA_Gradient *gr, int spread) +{ + int l; + + if (!gr || (gr->type.geometer != &rectangular)) return 0; + l = rectangular_data.s; + l -= (int)(l * rectangular_data.r0); + return l; +} + +static Gfx_Func_Gradient_Span +rectangular_get_span_func(RGBA_Gradient *gr, int spread, unsigned char aa) +{ + Gfx_Func_Gradient_Span sfunc = NULL; + + if (!gr || (gr->type.geometer != &rectangular)) return sfunc; + switch (spread) + { + case _EVAS_TEXTURE_REFLECT: + { + if (aa) + sfunc = rectangular_reflect_aa; + else + sfunc = rectangular_reflect; + } + break; + case _EVAS_TEXTURE_REPEAT: + { + if (aa) + sfunc = rectangular_repeat_aa; + else + sfunc = rectangular_repeat; + } + break; + case _EVAS_TEXTURE_RESTRICT: + { + if (aa) + sfunc = rectangular_restrict_aa; + else + sfunc = rectangular_restrict; + } + break; + default: + sfunc = rectangular_reflect; + break; + } + return sfunc; +} + +static void +rectangular_reflect_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Rectangular_Data *gdata = (Rectangular_Data *)params_data; + + int xx, yy, rr0; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + rr0 = gdata->r0 * gdata->s; + rr0 <<= 16; + + while (dst < dst_end) + { + int ll = xx, l = yy; + + if (ll < 0) ll = -ll; + if (l < 0) l = -l; + if (ll < l) ll = l; + ll = ll - rr0; l = ll >> 16; + + *dst = 0; + if (l == 0) + { + int a = 1 + (ll >> 8); + + *dst = map[0]; + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (l > 0) + { + if (l >= map_len) + { + int m = (l % (2 * map_len)); + + l = (l % map_len); + if (m >= map_len) + l = map_len - l - 1; + } + *dst = map[l]; + } + dst++; xx += axx; yy += ayx; + } +} + +static void +rectangular_reflect(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Rectangular_Data *gdata = (Rectangular_Data *)params_data; + + int xx, yy, rr0; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + rr0 = gdata->r0 * gdata->s; + rr0 <<= 16; + + while (dst < dst_end) + { + int ll = xx, l = yy; + + if (ll < 0) ll = -ll; + if (l < 0) l = -l; + if (ll < l) ll = l; + ll = ll - rr0; l = ll >> 16; + + l += (ll - (l << 16)) >> 15; + *dst = 0; + if (l >= 0) + { + if (l >= map_len) + { + int m = (l % (2 * map_len)); + + l = (l % map_len); + if (m >= map_len) + l = map_len - l - 1; + } + *dst = map[l]; + } + dst++; xx += axx; yy += ayx; + } +} + +static void +rectangular_repeat_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Rectangular_Data *gdata = (Rectangular_Data *)params_data; + + int xx, yy, rr0; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + rr0 = gdata->r0 * gdata->s; + rr0 <<= 16; + + while (dst < dst_end) + { + int ll = xx, l = yy; + + if (ll < 0) ll = -ll; + if (l < 0) l = -l; + if (ll < l) ll = l; + ll = ll - rr0; l = ll >> 16; + + *dst = 0; + if (l == 0) + { + int a = 1 + (ll >> 8); + + *dst = map[0]; + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (l > 0) + { + if (l >= map_len) + l = (l % map_len); + *dst = map[l]; + if (l == 0) + { + int a = 256 - ((ll - ((ll >> 16) << 16)) >> 8); + DATA32 *c = map + (map_len - 1); + + *dst += ARGB_JOIN((a * (A_VAL(c) - A_VAL(dst))) >> 8, + (a * (R_VAL(c) - R_VAL(dst))) >> 8, + (a * (G_VAL(c) - G_VAL(dst))) >> 8, + (a * (B_VAL(c) - B_VAL(dst))) >> 8); + } + } + dst++; xx += axx; yy += ayx; + } +} + +static void +rectangular_repeat(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Rectangular_Data *gdata = (Rectangular_Data *)params_data; + + int xx, yy, rr0; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + rr0 = gdata->r0 * gdata->s; + rr0 <<= 16; + + while (dst < dst_end) + { + int ll = xx, l = yy; + + if (ll < 0) ll = -ll; + if (l < 0) l = -l; + if (ll < l) ll = l; + ll = ll - rr0; l = ll >> 16; + + l += (ll - (l << 16)) >> 15; + *dst = 0; + if (l >= 0) + { + if (l >= map_len) + l = (l % map_len); + *dst = map[l]; + } + dst++; xx += axx; yy += ayx; + } +} + +static void +rectangular_restrict_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Rectangular_Data *gdata = (Rectangular_Data *)params_data; + + int xx, yy, rr0; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + rr0 = gdata->r0 * gdata->s; + rr0 <<= 16; + + while (dst < dst_end) + { + int ll = xx, l = yy; + + if (ll < 0) ll = -ll; + if (l < 0) l = -l; + if (ll < l) ll = l; + ll = ll - rr0; l = ll >> 16; + + *dst = 0; + if ((unsigned)l < map_len) + { + *dst = map[l]; + if (l == (map_len - 1)) + { + int a = 256 - ((ll - (l << 16)) >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if ((l == 0) && rr0) + { + int a = 1 + (ll >> 8); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + } + dst++; xx += axx; yy += ayx; + } +} + +static void +rectangular_restrict(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Rectangular_Data *gdata = (Rectangular_Data *)params_data; + + int xx, yy, rr0; + + if (gdata->sx != gdata->s) + { + axx = (gdata->s * axx) / gdata->sx; + axy = (gdata->s * axy) / gdata->sx; + } + if (gdata->sy != gdata->s) + { + ayy = (gdata->s * ayy) / gdata->sy; + ayx = (gdata->s * ayx) / gdata->sy; + } + + xx = (axx * x) + (axy * y); + yy = (ayx * x) + (ayy * y); + rr0 = gdata->r0 * gdata->s; + rr0 <<= 16; + + while (dst < dst_end) + { + int ll = xx, l = yy; + + if (ll < 0) ll = -ll; + if (l < 0) l = -l; + if (ll < l) ll = l; + ll = ll - rr0; l = ll >> 16; + + l += (ll - (l << 16)) >> 15; + *dst = 0; + if ((unsigned)l < map_len) + *dst = map[l]; + dst++; xx += axx; yy += ayx; + } +} + diff --git a/legacy/evas/src/lib/engines/common/evas_gradient_sinusoidal.c b/legacy/evas/src/lib/engines/common/evas_gradient_sinusoidal.c new file mode 100644 index 0000000000..a5f6743c09 --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_gradient_sinusoidal.c @@ -0,0 +1,342 @@ +#include "evas_common.h" +#include + +typedef struct _Sinusoidal_Data Sinusoidal_Data; +struct _Sinusoidal_Data +{ + float sa, sp; +}; + +static Sinusoidal_Data sinusoidal_data = {32.0, M_PI / 32.0}; + + +static void +sinusoidal_setup_geom(RGBA_Gradient *gr, int spread); + +static int +sinusoidal_has_alpha(RGBA_Gradient *gr, int spread); + +static int +sinusoidal_get_map_len(RGBA_Gradient *gr, int spread); + +static Gfx_Func_Gradient_Span +sinusoidal_get_span_func(RGBA_Gradient *gr, int spread, unsigned char aa); + +static RGBA_Gradient_Type sinusoidal = {"sinusoidal", &sinusoidal_data, sinusoidal_setup_geom, sinusoidal_has_alpha, sinusoidal_get_map_len, sinusoidal_get_span_func}; + +/** internal functions **/ + +static void +sinusoidal_reflect(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +sinusoidal_repeat_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +sinusoidal_repeat(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +sinusoidal_restrict_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + +static void +sinusoidal_restrict(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data); + + +RGBA_Gradient_Type * +evas_common_gradient_sinusoidal_get(void) +{ + return &sinusoidal; +} + +static void +sinusoidal_setup_geom(RGBA_Gradient *gr, int spread) +{ + int err = 1; + char *s, *p, key[256]; + float amp = 1.0, per = 1.0, val; + + if (!gr || (gr->type.geometer != &sinusoidal)) return; + + sinusoidal_data.sa = gr->fill.h; + sinusoidal_data.sp = M_PI / gr->fill.w; + + if (!gr->type.params || !*(gr->type.params)) + return; + + s = strdup(gr->type.params); + if (!s) return; + + p = s; + while (p = evas_common_gradient_get_key_fval(p, key, &val)) + { + if (!strcmp(key, "amplitude")) + { + err = 0; + amp = val; + } + else if (!strcmp(key, "period")) + { + err = 0; + per = val; + } + else + { + err = 1; + goto done; + } + } + done: + if (!err) + { + sinusoidal_data.sa *= amp; + if (per < 0.0) per = -per; + sinusoidal_data.sp *= per; + } + free(s); +} + + +static int +sinusoidal_has_alpha(RGBA_Gradient *gr, int spread) +{ + if (!gr || (gr->type.geometer != &sinusoidal)) return 0; + + if (gr->map.has_alpha) + return 1; + if (spread == _EVAS_TEXTURE_RESTRICT) + return 1; + return 0; +} + +static int +sinusoidal_get_map_len(RGBA_Gradient *gr, int spread) +{ + if (!gr || (gr->type.geometer != &sinusoidal)) return 0; + + return gr->fill.h; +} + +static Gfx_Func_Gradient_Span +sinusoidal_get_span_func(RGBA_Gradient *gr, int spread, unsigned char aa) +{ + Gfx_Func_Gradient_Span sfunc = NULL; + + if (!gr || (gr->type.geometer != &sinusoidal)) return sfunc; + switch (spread) + { + case _EVAS_TEXTURE_REPEAT: + { + if (aa) + sfunc = sinusoidal_repeat_aa; + else + sfunc = sinusoidal_repeat; + } + break; + case _EVAS_TEXTURE_RESTRICT: + { + if (aa) + sfunc = sinusoidal_restrict_aa; + else + sfunc = sinusoidal_restrict; + } + break; + default: + sfunc = sinusoidal_reflect; + break; + } + return sfunc; +} + +static void +sinusoidal_reflect(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Sinusoidal_Data *gdata = (Sinusoidal_Data *)params_data; + float xf, yf, sa = gdata->sa; + float a00, a01, a10, a11; + + a00 = gdata->sp * (axx / 65536.0); + a01 = gdata->sp * (axy / 65536.0); + a10 = ayx / 65536.0; + a11 = ayy / 65536.0; + + xf = (a00 * x) + (a01 * y); + yf = (a10 * x) + (a11 * y); + + while (dst < dst_end) + { + int l = (yf - (sa * sin(xf))); + + if (l < 0) l = -l; + if (l >= map_len) + { + int m = (l % (2 * map_len)); + + l = (l % map_len); + if (m >= map_len) + l = map_len - l - 1; + } + *dst++ = map[l]; xf += a00; yf += a10; + } +} + +static void +sinusoidal_repeat_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Sinusoidal_Data *gdata = (Sinusoidal_Data *)params_data; + float xf, yf, sa = gdata->sa; + float a00, a01, a10, a11; + + a00 = gdata->sp * (axx / 65536.0); + a01 = gdata->sp * (axy / 65536.0); + a10 = ayx / 65536.0; + a11 = ayy / 65536.0; + + xf = (a00 * x) + (a01 * y); + yf = (a10 * x) + (a11 * y); + + while (dst < dst_end) + { + float r = (yf - (sa * sin(xf))); + int l = r; + + l = (l % map_len); + if (l < 0) + l += map_len; + + *dst = map[l]; + if (l == 0) + { + int a = 0; + DATA32 *c = map + (map_len - 1); + + if ((r > 0) && (r >= map_len)) + { + r -= (int)r; + a = 256 - (int)(255 * r); + } + if (r < 0) + { + r = -r; r -= (int)r; + a = 1 + (int)(255 * r); + } + *dst += ARGB_JOIN((a * (A_VAL(c) - A_VAL(dst))) >> 8, + (a * (R_VAL(c) - R_VAL(dst))) >> 8, + (a * (G_VAL(c) - G_VAL(dst))) >> 8, + (a * (B_VAL(c) - B_VAL(dst))) >> 8); + } + dst++; xf += a00; yf += a10; + } +} + +static void +sinusoidal_repeat(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Sinusoidal_Data *gdata = (Sinusoidal_Data *)params_data; + float xf, yf, sa = gdata->sa; + float a00, a01, a10, a11; + + a00 = gdata->sp * (axx / 65536.0); + a01 = gdata->sp * (axy / 65536.0); + a10 = ayx / 65536.0; + a11 = ayy / 65536.0; + + xf = (a00 * x) + (a01 * y); + yf = (a10 * x) + (a11 * y); + + while (dst < dst_end) + { + int l = (yf - (sa * sin(xf))); + + l = (l % map_len); + if (l < 0) + l += map_len; + + *dst++ = map[l]; xf += a00; yf += a10; + } +} + +static void +sinusoidal_restrict_aa(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Sinusoidal_Data *gdata = (Sinusoidal_Data *)params_data; + float xf, yf, sa = gdata->sa; + float a00, a01, a10, a11; + + a00 = gdata->sp * (axx / 65536.0); + a01 = gdata->sp * (axy / 65536.0); + a10 = ayx / 65536.0; + a11 = ayy / 65536.0; + + xf = (a00 * x) + (a01 * y); + yf = (a10 * x) + (a11 * y); + + while (dst < dst_end) + { + float r = (yf - (sa * sin(xf))); + int l = r; + + *dst = 0; + if ((unsigned)l < map_len) + { + *dst = map[l]; + if (l == (map_len - 1)) + { + int a = 1 + (int)(255 * (map_len - r)); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + if (l == 0) + { + int a = 256; + + if (r < 0) + a = 1 + (int)(255 * (1.0 + r)); + + A_VAL(dst) = (A_VAL(dst) * a) >> 8; + } + } + dst++; xf += a00; yf += a10; + } +} + +static void +sinusoidal_restrict(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, void *params_data) +{ + DATA32 *dst_end = dst + dst_len; + Sinusoidal_Data *gdata = (Sinusoidal_Data *)params_data; + float xf, yf, sa = gdata->sa; + float a00, a01, a10, a11; + + a00 = gdata->sp * (axx / 65536.0); + a01 = gdata->sp * (axy / 65536.0); + a10 = ayx / 65536.0; + a11 = ayy / 65536.0; + + xf = (a00 * x) + (a01 * y); + yf = (a10 * x) + (a11 * y); + + while (dst < dst_end) + { + int l = (yf - (sa * sin(xf))); + + *dst = 0; + if ((unsigned)l < map_len) + *dst = map[l]; + dst++; xf += a00; yf += a10; + } +} + diff --git a/legacy/evas/src/lib/engines/common/evas_image_main.c b/legacy/evas/src/lib/engines/common/evas_image_main.c index 1e8035dd92..28f3a2ad99 100644 --- a/legacy/evas/src/lib/engines/common/evas_image_main.c +++ b/legacy/evas/src/lib/engines/common/evas_image_main.c @@ -14,6 +14,11 @@ static Evas_Object_List * cache = NULL; static int cache_size = 0; static int cache_usage = 0; +static RGBA_Image *evas_rgba_line_buffer = NULL; + +#define EVAS_RGBA_LINE_BUFFER_MIN_LEN 256 +#define EVAS_RGBA_LINE_BUFFER_MAX_LEN 1024 + #if 0 int image_debug_hash_cb(Evas_Hash *hash, const char *key, void *data, void *fdata) @@ -484,14 +489,57 @@ evas_common_image_dirty(RGBA_Image *im) } void -evas_common_image_free_cache(void) +evas_common_image_cache_free(void) { - while (cache) + evas_common_image_set_cache(0); +} + +RGBA_Image * +evas_common_image_line_buffer_obtain(int len) +{ + if (len < 1) return NULL; + if (len < EVAS_RGBA_LINE_BUFFER_MIN_LEN) + len = EVAS_RGBA_LINE_BUFFER_MIN_LEN; + if (evas_rgba_line_buffer) { - RGBA_Image *im = (RGBA_Image *) cache; - - evas_common_image_uncache(im); - evas_common_image_free(im); + if (evas_rgba_line_buffer->image->w >= len) + return evas_rgba_line_buffer; + evas_rgba_line_buffer->image->data = (DATA32 *)realloc(evas_rgba_line_buffer->image->data, len * sizeof(DATA32)); + if (!evas_rgba_line_buffer->image->data) + { + evas_common_image_free(evas_rgba_line_buffer); + evas_rgba_line_buffer = NULL; + return NULL; + } + evas_rgba_line_buffer->image->w = len; + return evas_rgba_line_buffer; + } + evas_rgba_line_buffer = evas_common_image_create(len, 1); + if (!evas_rgba_line_buffer) return NULL; + return evas_rgba_line_buffer; +} + +void +evas_common_image_line_buffer_release(void) +{ + if (!evas_rgba_line_buffer) return; + if (EVAS_RGBA_LINE_BUFFER_MAX_LEN < evas_rgba_line_buffer->image->w) + { + evas_rgba_line_buffer->image->w = EVAS_RGBA_LINE_BUFFER_MAX_LEN; + evas_rgba_line_buffer->image->data = (DATA32 *)realloc(evas_rgba_line_buffer->image->data, + evas_rgba_line_buffer->image->w * sizeof(DATA32)); + if (!evas_rgba_line_buffer->image->data) + { + evas_common_image_free(evas_rgba_line_buffer); + evas_rgba_line_buffer = NULL; + } } } +void +evas_common_image_line_buffer_free(void) +{ + if (!evas_rgba_line_buffer) return; + evas_common_image_free(evas_rgba_line_buffer); + evas_rgba_line_buffer = NULL; +} diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth.c index e749e27784..38257abf5f 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth.c @@ -6,7 +6,7 @@ #include "evas_blend_ops.h" -extern const DATA8 _evas_pow_lut[65536]; +extern DATA8 *_evas_pow_lut; extern const DATA16 _evas_const_c1[4]; static DATA32 **scale_calc_y_points(DATA32 *src, int sw, int sh, int dh); @@ -20,7 +20,7 @@ scale_calc_y_points(DATA32 *src, int sw, int sh, int dh) int i, val, inc; p = malloc((dh + 1) * sizeof(DATA32 *)); -// if (!p) return NULL; + if (!p) return NULL; val = 0; inc = (sh << 16) / dh; for (i = 0; i < dh; i++) @@ -39,7 +39,7 @@ scale_calc_x_points(int sw, int dw) int i, val, inc; p = malloc((dw + 1) * sizeof(int)); -// if (!p) return NULL; + if (!p) return NULL; val = 0; inc = (sw << 16) / dw; for (i = 0; i < dw; i++) @@ -58,7 +58,7 @@ scale_calc_a_points(int s, int d) int i, val, inc; p = malloc(d * sizeof(int)); -// if (!p) return NULL; + if (!p) return NULL; if (d >= s) { val = 0; diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler.c index db6e78b3d4..f9ab6d2979 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler.c @@ -6,17 +6,10 @@ SCALE_FUNC(RGBA_Image *src, RGBA_Image *dst, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h) { - int x, y; - int *lin_ptr, *lin2_ptr; - int *interp_x, *interp_y; - int *sample_x, *sample_y; - char *iterate_x, *iterate_y; - DATA32 *buf, *dptr; - DATA32 **row_ptr, **row2_ptr; - DATA32 *ptr, *dst_ptr, *dst_data, *ptr2, *ptr3, *ptr4; + DATA32 *dst_ptr; int dst_jump; int dst_clip_x, dst_clip_y, dst_clip_w, dst_clip_h; - int src_w, src_h, dst_w, dst_h; + int src_w, src_h, dst_w, dst_h; if (!(RECTS_INTERSECT(dst_region_x, dst_region_y, dst_region_w, dst_region_h, 0, 0, dst->image->w, dst->image->h))) return; @@ -28,8 +21,6 @@ SCALE_FUNC(RGBA_Image *src, RGBA_Image *dst, dst_w = dst->image->w; dst_h = dst->image->h; - dst_data = dst->image->data; - if (dc->clip.use) { dst_clip_x = dc->clip.x; @@ -146,32 +137,11 @@ SCALE_FUNC(RGBA_Image *src, RGBA_Image *dst, } if (dst_clip_h <= 0) return; - lin_ptr = malloc(dst_clip_w * sizeof(int)); - if (!lin_ptr) goto no_lin_ptr; - row_ptr = malloc(dst_clip_h * sizeof(DATA32 *)); - if (!row_ptr) goto no_row_ptr; - lin2_ptr = malloc(dst_clip_w * sizeof(int)); - if (!lin2_ptr) goto no_lin2_ptr; - row2_ptr = malloc(dst_clip_h * sizeof(DATA32 *)); - if (!row2_ptr) goto no_row2_ptr; - interp_x = malloc(dst_clip_w * sizeof(int)); - if (!interp_x) goto no_interp_x; - interp_y = malloc(dst_clip_h * sizeof(int)); - if (!interp_y) goto no_interp_y; - sample_x = malloc(dst_clip_w * sizeof(int) * 3); - if (!sample_x) goto no_sample_x; - sample_y = malloc(dst_clip_h * sizeof(int) * 3); - if (!sample_y) goto no_sample_y; - iterate_x = malloc(dst_clip_w * sizeof(char)); - if (!iterate_x) goto no_iterate_x; - iterate_y = malloc(dst_clip_h * sizeof(char)); - if (!iterate_y) goto no_iterate_y; - /* figure out dst jump */ dst_jump = dst_w - dst_clip_w; /* figure out dest start ptr */ - dst_ptr = dst_data + dst_clip_x + (dst_clip_y * dst_w); + dst_ptr = dst->image->data + dst_clip_x + (dst_clip_y * dst_w); /* FIXME: * @@ -218,51 +188,17 @@ SCALE_FUNC(RGBA_Image *src, RGBA_Image *dst, } else { - Gfx_Func_Blend_Src_Cmod_Dst func_cmod; - Gfx_Func_Blend_Src_Mul_Dst func_mul; - Gfx_Func_Blend_Src_Dst func; - - /* a scanline buffer */ - buf = malloc(dst_clip_w * sizeof(DATA32)); - if (!buf) goto no_buf; - - func = evas_common_draw_func_blend_get (src, dst, dst_clip_w); - func_cmod = evas_common_draw_func_blend_cmod_get (src, dst, dst_clip_w); - func_mul = evas_common_draw_func_blend_mul_get (src, dc->mul.col, dst, dst_clip_w); - /* scaling up only - dont need anything except original */ if ((dst_region_w >= src_region_w) && (dst_region_h >= src_region_h)) { #include "evas_scale_smooth_scaler_up.c" + return; } else /* scaling down... funkiness */ { #include "evas_scale_smooth_scaler_down.c" + return; } - free(buf); } - no_buf: - /* free scale tables */ - free(iterate_y); - no_iterate_y: - free(iterate_x); - no_iterate_x: - free(sample_y); - no_sample_y: - free(sample_x); - no_sample_x: - free(interp_y); - no_interp_y: - free(interp_x); - no_interp_x: - free(row2_ptr); - no_row2_ptr: - free(lin2_ptr); - no_lin2_ptr: - free(row_ptr); - no_row_ptr: - free(lin_ptr); - no_lin_ptr: - ; } diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_down.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_down.c index e514b4df23..30c1c84b3e 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_down.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_down.c @@ -1,25 +1,37 @@ -#define RGBA_COMPOSE(r, g, b, a) ((a) << 24) | ((r) << 16) | ((g) << 8) | (b) -#define INV_XAP (256 - xapoints[dxx + x]) -#define XAP (xapoints[dxx + x]) -#define INV_YAP (256 - yapoints[dyy + y]) -#define YAP (yapoints[dyy + y]) - { - DATA32 *sptr; - int x, y; - DATA32 **ypoints; - int *xpoints; - int *xapoints; - int *yapoints; - DATA32 *src_data; + DATA32 *sptr; + int x, y; + DATA32 **ypoints; + int *xpoints; + int *xapoints, *xapp; + int *yapoints, *yapp; + DATA32 *buf, *src_data; + RGBA_Image *line_buf; + + Gfx_Func_Blend_Src_Cmod_Dst func_cmod; + Gfx_Func_Blend_Src_Mul_Dst func_mul; + Gfx_Func_Blend_Src_Dst func; src_data = src->image->data; xpoints = scale_calc_x_points(src_region_w, dst_region_w); - ypoints = scale_calc_y_points(src_data, src->image->w, src_region_h, dst_region_h); + ypoints = scale_calc_y_points(src_data, src_w, src_region_h, dst_region_h); xapoints = scale_calc_a_points(src_region_w, dst_region_w); yapoints = scale_calc_a_points(src_region_h, dst_region_h); - /* scaling down vertically */ + if ( (!xpoints) || (!ypoints) || (!xapoints) || (!yapoints) ) + goto done_scale_down; + + /* a scanline buffer */ + line_buf = evas_common_image_line_buffer_obtain(dst_clip_w); + if (!line_buf) + goto done_scale_down; + buf = line_buf->image->data; + + func = evas_common_draw_func_blend_get (src, dst, dst_clip_w); + func_cmod = evas_common_draw_func_blend_cmod_get (src, dst, dst_clip_w); + func_mul = evas_common_draw_func_blend_mul_get (src, dc->mul.col, dst, dst_clip_w); + + /* scaling down vertically */ if ((dst_region_w >= src_region_w) && (dst_region_h < src_region_h)) { @@ -37,8 +49,11 @@ { #include "evas_scale_smooth_scaler_downx_downy.c" } - free(xpoints); - free(ypoints); - free(xapoints); - free(yapoints); + + done_scale_down: + evas_common_image_line_buffer_release(); + if (xpoints) free(xpoints); + if (ypoints) free(ypoints); + if (xapoints) free(xapoints); + if (yapoints) free(yapoints); } diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx.c index f17e76c60c..5cc3e44962 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx.c @@ -1,105 +1,108 @@ { int Cx, j; - DATA32 *pix; + DATA32 *pix, *dptr, *pbuf, **yp; int r, g, b, a, rr, gg, bb, aa; - int xap; - int sow; + int *xp, xap, yap, pos; int dyy, dxx; - + int w = dst_clip_w; + dptr = dst_ptr; - sow = src->image->w; + pos = (src_region_y * src_w) + src_region_x; dyy = dst_clip_y - dst_region_y; dxx = dst_clip_x - dst_region_x; + + xp = xpoints + dxx; + yp = ypoints + dyy; + xapp = xapoints + dxx; + yapp = yapoints + dyy; + pbuf = buf; + if (src->flags & RGBA_IMAGE_HAS_ALPHA) { - for (y = 0; y < dst_clip_h; y++) + while (dst_clip_h--) { - for (x = 0; x < dst_clip_w; x++) + while (dst_clip_w--) { - Cx = XAP >> 16; - xap = XAP & 0xffff; + Cx = *xapp >> 16; + xap = *xapp & 0xffff; + pix = *yp + *xp + pos; - pix = ypoints[dyy + y] + xpoints[dxx + x] + (src_region_y * sow) + src_region_x; + a = (A_VAL(pix) * xap) >> 10; r = (R_VAL(pix) * xap) >> 10; g = (G_VAL(pix) * xap) >> 10; b = (B_VAL(pix) * xap) >> 10; - a = (A_VAL(pix) * xap) >> 10; for (j = (1 << 14) - xap; j > Cx; j -= Cx) { pix++; + a += (A_VAL(pix) * Cx) >> 10; r += (R_VAL(pix) * Cx) >> 10; g += (G_VAL(pix) * Cx) >> 10; b += (B_VAL(pix) * Cx) >> 10; - a += (A_VAL(pix) * Cx) >> 10; } if (j > 0) { pix++; + a += (A_VAL(pix) * j) >> 10; r += (R_VAL(pix) * j) >> 10; g += (G_VAL(pix) * j) >> 10; b += (B_VAL(pix) * j) >> 10; - a += (A_VAL(pix) * j) >> 10; } - if (YAP > 0) + if ((yap = *yapp) > 0) { - pix = ypoints[dyy + y] + xpoints[dxx + x] + sow + (src_region_y * sow) + src_region_x; + pix = *yp + *xp + src_w + pos; + aa = (A_VAL(pix) * xap) >> 10; rr = (R_VAL(pix) * xap) >> 10; gg = (G_VAL(pix) * xap) >> 10; bb = (B_VAL(pix) * xap) >> 10; - aa = (A_VAL(pix) * xap) >> 10; for (j = (1 << 14) - xap; j > Cx; j -= Cx) { pix++; + aa += (A_VAL(pix) * Cx) >> 10; rr += (R_VAL(pix) * Cx) >> 10; gg += (G_VAL(pix) * Cx) >> 10; bb += (B_VAL(pix) * Cx) >> 10; - aa += (A_VAL(pix) * Cx) >> 10; } if (j > 0) { pix++; + aa += (A_VAL(pix) * j) >> 10; rr += (R_VAL(pix) * j) >> 10; gg += (G_VAL(pix) * j) >> 10; bb += (B_VAL(pix) * j) >> 10; - aa += (A_VAL(pix) * j) >> 10; } - r = r * INV_YAP; - g = g * INV_YAP; - b = b * INV_YAP; - a = a * INV_YAP; - r = (r + ((rr * YAP))) >> 12; - g = (g + ((gg * YAP))) >> 12; - b = (b + ((bb * YAP))) >> 12; - a = (a + ((aa * YAP))) >> 12; + a += ((aa - a) * yap) >> 8; + r += ((rr - r) * yap) >> 8; + g += ((gg - g) * yap) >> 8; + b += ((bb - b) * yap) >> 8; } - else - { - r >>= 4; - g >>= 4; - b >>= 4; - a >>= 4; - } - buf[x] = RGBA_COMPOSE(r, g, b, a); + *pbuf++ = ARGB_JOIN(a >> 4, r >> 4, g >> 4, b >> 4); + xp++; xapp++; } + if (dc->mod.use) - func_cmod(buf, dptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); + func_cmod(buf, dptr, w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); else if (dc->mul.use) - func_mul(buf, dptr, dst_clip_w, dc->mul.col); + func_mul(buf, dptr, w, dc->mul.col); else - func(buf, dptr, dst_clip_w); - dptr += dst_w; + func(buf, dptr, w); + + pbuf = buf; + dptr += dst_w; dst_clip_w = w; + yp++; yapp++; + xp = xpoints + dxx; + xapp = xapoints + dxx; } } else { - for (y = 0; y < dst_clip_h; y++) + while (dst_clip_h--) { - for (x = 0; x < dst_clip_w; x++) + while (dst_clip_w--) { - Cx = XAP >> 16; - xap = XAP & 0xffff; + Cx = *xapp >> 16; + xap = *xapp & 0xffff; + pix = *yp + *xp + pos; - pix = ypoints[dyy + y] + xpoints[dxx + x] + (src_region_y * sow) + src_region_x; r = (R_VAL(pix) * xap) >> 10; g = (G_VAL(pix) * xap) >> 10; b = (B_VAL(pix) * xap) >> 10; @@ -117,9 +120,9 @@ g += (G_VAL(pix) * j) >> 10; b += (B_VAL(pix) * j) >> 10; } - if (YAP > 0) + if ((yap = *yapp) > 0) { - pix = ypoints[dyy + y] + xpoints[dxx + x] + sow + (src_region_y * sow) + src_region_x; + pix = *yp + *xp + src_w + pos; rr = (R_VAL(pix) * xap) >> 10; gg = (G_VAL(pix) * xap) >> 10; bb = (B_VAL(pix) * xap) >> 10; @@ -137,28 +140,26 @@ gg += (G_VAL(pix) * j) >> 10; bb += (B_VAL(pix) * j) >> 10; } - r = r * INV_YAP; - g = g * INV_YAP; - b = b * INV_YAP; - r = (r + ((rr * YAP))) >> 12; - g = (g + ((gg * YAP))) >> 12; - b = (b + ((bb * YAP))) >> 12; + r += ((rr - r) * yap) >> 8; + g += ((gg - g) * yap) >> 8; + b += ((bb - b) * yap) >> 8; } - else - { - r >>= 4; - g >>= 4; - b >>= 4; - } - buf[x] = RGBA_COMPOSE(r, g, b, 0xff); + *pbuf++ = ARGB_JOIN(0xff, r >> 4, g >> 4, b >> 4); + xp++; xapp++; } + if (dc->mod.use) - func_cmod(buf, dptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); + func_cmod(buf, dptr, w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); else if (dc->mul.use) - func_mul(buf, dptr, dst_clip_w, dc->mul.col); + func_mul(buf, dptr, w, dc->mul.col); else - func(buf, dptr, dst_clip_w); - dptr += dst_w; + func(buf, dptr, w); + + pbuf = buf; + dptr += dst_w; dst_clip_w = w; + yp++; yapp++; + xp = xpoints + dxx; + xapp = xapoints + dxx; } } } diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx_downy.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx_downy.c index d548c601fd..4285743775 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx_downy.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx_downy.c @@ -1,145 +1,163 @@ { int Cx, Cy, i, j; - DATA32 *pix; + DATA32 *dptr, *sptr, *pix, *pbuf; int a, r, g, b, rx, gx, bx, ax; - int xap, yap; - int sow; + int xap, yap, pos; int dyy, dxx; + + DATA32 **yp; + int *xp; + int w = dst_clip_w; dptr = dst_ptr; - sow = src->image->w; + pos = (src_region_y * src_w) + src_region_x; dyy = dst_clip_y - dst_region_y; dxx = dst_clip_x - dst_region_x; + + xp = xpoints + dxx; + yp = ypoints + dyy; + xapp = xapoints + dxx; + yapp = yapoints + dyy; + pbuf = buf; /*#ifndef SCALE_USING_MMX */ /* for now there's no mmx down scaling - so C only */ #if 1 if (src->flags & RGBA_IMAGE_HAS_ALPHA) { - for (y = 0; y < dst_clip_h; y++) + while (dst_clip_h--) { - Cy = YAP >> 16; - yap = YAP & 0xffff; + Cy = *yapp >> 16; + yap = *yapp & 0xffff; - for (x = 0; x < dst_clip_w; x++) + while (dst_clip_w--) { - Cx = XAP >> 16; - xap = XAP & 0xffff; + Cx = *xapp >> 16; + xap = *xapp & 0xffff; - sptr = ypoints[dyy + y] + xpoints[dxx + x] + (src_region_y * sow) + src_region_x; + sptr = *yp + *xp + pos; pix = sptr; - sptr += sow; + sptr += src_w; + + ax = (A_VAL(pix) * xap) >> 9; rx = (R_VAL(pix) * xap) >> 9; gx = (G_VAL(pix) * xap) >> 9; bx = (B_VAL(pix) * xap) >> 9; - ax = (A_VAL(pix) * xap) >> 9; pix++; for (i = (1 << 14) - xap; i > Cx; i -= Cx) { + ax += (A_VAL(pix) * Cx) >> 9; rx += (R_VAL(pix) * Cx) >> 9; gx += (G_VAL(pix) * Cx) >> 9; bx += (B_VAL(pix) * Cx) >> 9; - ax += (A_VAL(pix) * Cx) >> 9; pix++; } if (i > 0) { + ax += (A_VAL(pix) * i) >> 9; rx += (R_VAL(pix) * i) >> 9; gx += (G_VAL(pix) * i) >> 9; bx += (B_VAL(pix) * i) >> 9; - ax += (A_VAL(pix) * i) >> 9; } + a = (ax * yap) >> 14; r = (rx * yap) >> 14; g = (gx * yap) >> 14; b = (bx * yap) >> 14; - a = (ax * yap) >> 14; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { pix = sptr; - sptr += sow; + sptr += src_w; + ax = (A_VAL(pix) * xap) >> 9; rx = (R_VAL(pix) * xap) >> 9; gx = (G_VAL(pix) * xap) >> 9; bx = (B_VAL(pix) * xap) >> 9; - ax = (A_VAL(pix) * xap) >> 9; pix++; for (i = (1 << 14) - xap; i > Cx; i -= Cx) { + ax += (A_VAL(pix) * Cx) >> 9; rx += (R_VAL(pix) * Cx) >> 9; gx += (G_VAL(pix) * Cx) >> 9; bx += (B_VAL(pix) * Cx) >> 9; - ax += (A_VAL(pix) * Cx) >> 9; pix++; } if (i > 0) { + ax += (A_VAL(pix) * i) >> 9; rx += (R_VAL(pix) * i) >> 9; gx += (G_VAL(pix) * i) >> 9; bx += (B_VAL(pix) * i) >> 9; - ax += (A_VAL(pix) * i) >> 9; } + a += (ax * Cy) >> 14; r += (rx * Cy) >> 14; g += (gx * Cy) >> 14; b += (bx * Cy) >> 14; - a += (ax * Cy) >> 14; } if (j > 0) { pix = sptr; - sptr += sow; + sptr += src_w; + ax = (A_VAL(pix) * xap) >> 9; rx = (R_VAL(pix) * xap) >> 9; gx = (G_VAL(pix) * xap) >> 9; bx = (B_VAL(pix) * xap) >> 9; - ax = (A_VAL(pix) * xap) >> 9; pix++; for (i = (1 << 14) - xap; i > Cx; i -= Cx) { + ax += (A_VAL(pix) * Cx) >> 9; rx += (R_VAL(pix) * Cx) >> 9; gx += (G_VAL(pix) * Cx) >> 9; bx += (B_VAL(pix) * Cx) >> 9; - ax += (A_VAL(pix) * Cx) >> 9; pix++; } if (i > 0) { + ax += (A_VAL(pix) * i) >> 9; rx += (R_VAL(pix) * i) >> 9; gx += (G_VAL(pix) * i) >> 9; bx += (B_VAL(pix) * i) >> 9; - ax += (A_VAL(pix) * i) >> 9; } + a += (ax * j) >> 14; r += (rx * j) >> 14; g += (gx * j) >> 14; b += (bx * j) >> 14; - a += (ax * j) >> 14; } - buf[x] = RGBA_COMPOSE(r >> 5, g >> 5, b >> 5, a >> 5); + *pbuf++ = ARGB_JOIN(a >> 5, r >> 5, g >> 5, b >> 5); + xp++; xapp++; } + if (dc->mod.use) - func_cmod(buf, dptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); + func_cmod(buf, dptr, w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); else if (dc->mul.use) - func_mul(buf, dptr, dst_clip_w, dc->mul.col); + func_mul(buf, dptr, w, dc->mul.col); else - func(buf, dptr, dst_clip_w); - dptr += dst_w; + func(buf, dptr, w); + + pbuf = buf; + dptr += dst_w; dst_clip_w = w; + xp = xpoints + dxx; + xapp = xapoints + dxx; + yp++; yapp++; } } else { - for (y = 0; y < dst_clip_h; y++) + while (dst_clip_h--) { - Cy = YAP >> 16; - yap = YAP & 0xffff; + Cy = *yapp >> 16; + yap = *yapp & 0xffff; - for (x = 0; x < dst_clip_w; x++) + while (dst_clip_w--) { - Cx = XAP >> 16; - xap = XAP & 0xffff; + Cx = *xapp >> 16; + xap = *xapp & 0xffff; - sptr = ypoints[dyy + y] + xpoints[dxx + x] + (src_region_y * sow) + src_region_x; + sptr = *yp + *xp + pos; pix = sptr; - sptr += sow; + sptr += src_w; + rx = (R_VAL(pix) * xap) >> 9; gx = (G_VAL(pix) * xap) >> 9; bx = (B_VAL(pix) * xap) >> 9; @@ -165,7 +183,7 @@ for (j = (1 << 14) - yap; j > Cy; j -= Cy) { pix = sptr; - sptr += sow; + sptr += src_w; rx = (R_VAL(pix) * xap) >> 9; gx = (G_VAL(pix) * xap) >> 9; bx = (B_VAL(pix) * xap) >> 9; @@ -191,7 +209,7 @@ if (j > 0) { pix = sptr; - sptr += sow; + sptr += src_w; rx = (R_VAL(pix) * xap) >> 9; gx = (G_VAL(pix) * xap) >> 9; bx = (B_VAL(pix) * xap) >> 9; @@ -214,15 +232,22 @@ g += (gx * j) >> 14; b += (bx * j) >> 14; } - buf[x] = RGBA_COMPOSE(r >> 5, g >> 5, b >> 5, 0xff); + *pbuf++ = ARGB_JOIN(0xff, r >> 5, g >> 5, b >> 5); + xp++; xapp++; } + if (dc->mod.use) - func_cmod(buf, dptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); + func_cmod(buf, dptr, w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); else if (dc->mul.use) - func_mul(buf, dptr, dst_clip_w, dc->mul.col); + func_mul(buf, dptr, w, dc->mul.col); else - func(buf, dptr, dst_clip_w); - dptr += dst_w; + func(buf, dptr, w); + + pbuf = buf; + dptr += dst_w; dst_clip_w = w; + xp = xpoints + dxx; + xapp = xapoints + dxx; + yp++; yapp++; } } #else diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downy.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downy.c index 005d801eee..718367c3db 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downy.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downy.c @@ -1,162 +1,167 @@ { int Cy, j; - DATA32 *pix; + DATA32 *dptr, *pix, *pbuf, **yp; int r, g, b, a, rr, gg, bb, aa; - int yap; - int sow; + int *xp, xap, yap, pos; int dyy, dxx; + int w = dst_clip_w; dptr = dst_ptr; - sow = src->image->w; + pos = (src_region_y * src_w) + src_region_x; dyy = dst_clip_y - dst_region_y; dxx = dst_clip_x - dst_region_x; + + xp = xpoints + dxx; + yp = ypoints + dyy; + xapp = xapoints + dxx; + yapp = yapoints + dyy; + pbuf = buf; + if (src->flags & RGBA_IMAGE_HAS_ALPHA) { - for (y = 0; y < dst_clip_h; y++) + while (dst_clip_h--) { - Cy = YAP >> 16; - yap = YAP & 0xffff; - for (x = 0; x < dst_clip_w; x++) + Cy = *yapp >> 16; + yap = *yapp & 0xffff; + + while (dst_clip_w--) { - pix = ypoints[dyy + y] + xpoints[dxx + x] + (src_region_y * sow) + src_region_x; + pix = *yp + *xp + pos; + + a = (A_VAL(pix) * yap) >> 10; r = (R_VAL(pix) * yap) >> 10; g = (G_VAL(pix) * yap) >> 10; b = (B_VAL(pix) * yap) >> 10; - a = (A_VAL(pix) * yap) >> 10; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { - pix += sow; + pix += src_w; + a += (A_VAL(pix) * Cy) >> 10; r += (R_VAL(pix) * Cy) >> 10; g += (G_VAL(pix) * Cy) >> 10; b += (B_VAL(pix) * Cy) >> 10; - a += (A_VAL(pix) * Cy) >> 10; } if (j > 0) { - pix += sow; + pix += src_w; + a += (A_VAL(pix) * j) >> 10; r += (R_VAL(pix) * j) >> 10; g += (G_VAL(pix) * j) >> 10; b += (B_VAL(pix) * j) >> 10; - a += (A_VAL(pix) * j) >> 10; } - if (XAP > 0) + if ((xap = *xapp) > 0) { - pix = ypoints[dyy + y] + xpoints[dxx + x] + 1 + (src_region_y * sow) + src_region_x; + pix = *yp + *xp + 1 + pos; + aa = (A_VAL(pix) * yap) >> 10; rr = (R_VAL(pix) * yap) >> 10; gg = (G_VAL(pix) * yap) >> 10; bb = (B_VAL(pix) * yap) >> 10; - aa = (A_VAL(pix) * yap) >> 10; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { - pix += sow; + pix += src_w; + aa += (A_VAL(pix) * Cy) >> 10; rr += (R_VAL(pix) * Cy) >> 10; gg += (G_VAL(pix) * Cy) >> 10; bb += (B_VAL(pix) * Cy) >> 10; - aa += (A_VAL(pix) * Cy) >> 10; } if (j > 0) { - pix += sow; + pix += src_w; + aa += (A_VAL(pix) * j) >> 10; rr += (R_VAL(pix) * j) >> 10; gg += (G_VAL(pix) * j) >> 10; bb += (B_VAL(pix) * j) >> 10; - aa += (A_VAL(pix) * j) >> 10; } - r = r * INV_XAP; - g = g * INV_XAP; - b = b * INV_XAP; - a = a * INV_XAP; - r = (r + ((rr * XAP))) >> 12; - g = (g + ((gg * XAP))) >> 12; - b = (b + ((bb * XAP))) >> 12; - a = (a + ((aa * XAP))) >> 12; + a += ((aa - a) * xap) >> 8; + r += ((rr - r) * xap) >> 8; + g += ((gg - g) * xap) >> 8; + b += ((bb - b) * xap) >> 8; } - else - { - r >>= 4; - g >>= 4; - b >>= 4; - a >>= 4; - } - buf[x] = RGBA_COMPOSE(r, g, b, a); + *pbuf++ = ARGB_JOIN(a >> 4, r >> 4, g >> 4, b >> 4); + xp++; xapp++; } + if (dc->mod.use) - func_cmod(buf, dptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); + func_cmod(buf, dptr, w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); else if (dc->mul.use) - func_mul(buf, dptr, dst_clip_w, dc->mul.col); + func_mul(buf, dptr, w, dc->mul.col); else - func(buf, dptr, dst_clip_w); - dptr += dst_w; + func(buf, dptr, w); + + pbuf = buf; + dptr += dst_w; dst_clip_w = w; + yp++; yapp++; + xp = xpoints + dxx; + xapp = xapoints + dxx; } } else { - for (y = 0; y < dst_clip_h; y++) + while (dst_clip_h--) { - Cy = YAP >> 16; - yap = YAP & 0xffff; - for (x = 0; x < dst_clip_w; x++) + Cy = *yapp >> 16; + yap = *yapp & 0xffff; + + while (dst_clip_w--) { - pix = ypoints[dyy + y] + xpoints[dxx + x] + (src_region_y * sow) + src_region_x; + pix = *yp + *xp + pos; + r = (R_VAL(pix) * yap) >> 10; g = (G_VAL(pix) * yap) >> 10; b = (B_VAL(pix) * yap) >> 10; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { - pix += sow; + pix += src_w; r += (R_VAL(pix) * Cy) >> 10; g += (G_VAL(pix) * Cy) >> 10; b += (B_VAL(pix) * Cy) >> 10; } if (j > 0) { - pix += sow; + pix += src_w; r += (R_VAL(pix) * j) >> 10; g += (G_VAL(pix) * j) >> 10; b += (B_VAL(pix) * j) >> 10; } - if (XAP > 0) + if ((xap = *xapp) > 0) { - pix = ypoints[dyy + y] + xpoints[dxx + x] + 1 + (src_region_y * sow) + src_region_x; + pix = *yp + *xp + 1 + pos; rr = (R_VAL(pix) * yap) >> 10; gg = (G_VAL(pix) * yap) >> 10; bb = (B_VAL(pix) * yap) >> 10; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { - pix += sow; + pix += src_w; rr += (R_VAL(pix) * Cy) >> 10; gg += (G_VAL(pix) * Cy) >> 10; bb += (B_VAL(pix) * Cy) >> 10; } if (j > 0) { - pix += sow; + pix += src_w; rr += (R_VAL(pix) * j) >> 10; gg += (G_VAL(pix) * j) >> 10; bb += (B_VAL(pix) * j) >> 10; } - r = r * INV_XAP; - g = g * INV_XAP; - b = b * INV_XAP; - r = (r + ((rr * XAP))) >> 12; - g = (g + ((gg * XAP))) >> 12; - b = (b + ((bb * XAP))) >> 12; + r += ((rr - r) * xap) >> 8; + g += ((gg - g) * xap) >> 8; + b += ((bb - b) * xap) >> 8; } - else - { - r >>= 4; - g >>= 4; - b >>= 4; - } - buf[x] = RGBA_COMPOSE(r, g, b, 0xff); + *pbuf++ = ARGB_JOIN(0xff, r >> 4, g >> 4, b >> 4); + xp++; xapp++; } + if (dc->mod.use) - func_cmod(buf, dptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); + func_cmod(buf, dptr, w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); else if (dc->mul.use) - func_mul(buf, dptr, dst_clip_w, dc->mul.col); + func_mul(buf, dptr, w, dc->mul.col); else - func(buf, dptr, dst_clip_w); - dptr += dst_w; + func(buf, dptr, w); + + pbuf = buf; + dptr += dst_w; dst_clip_w = w; + yp++; yapp++; + xp = xpoints + dxx; + xapp = xapoints + dxx; } } } diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_noscale.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_noscale.c index 95a0fcfc0a..addd626e9d 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_noscale.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_noscale.c @@ -1,14 +1,13 @@ { - DATA32 *src_data; + DATA32 *ptr; - src_data = src->image->data; - ptr = src_data + ((dst_clip_y - dst_region_y + src_region_y) * src_w) + (dst_clip_x - dst_region_x) + src_region_x; + ptr = src->image->data + ((dst_clip_y - dst_region_y + src_region_y) * src_w) + (dst_clip_x - dst_region_x) + src_region_x; if (dc->mod.use) { Gfx_Func_Blend_Src_Cmod_Dst func; func = evas_common_draw_func_blend_cmod_get(src, dst, dst_clip_w); - for (y = 0; y < dst_clip_h; y++) + while (dst_clip_h--) { func(ptr, dst_ptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); ptr += src_w; @@ -20,7 +19,7 @@ Gfx_Func_Blend_Src_Mul_Dst func; func = evas_common_draw_func_blend_mul_get(src, dc->mul.col, dst, dst_clip_w); - for (y = 0; y < dst_clip_h; y++) + while (dst_clip_h--) { func(ptr, dst_ptr, dst_clip_w, dc->mul.col); ptr += src_w; @@ -32,7 +31,7 @@ Gfx_Func_Blend_Src_Dst func; func = evas_common_draw_func_blend_get(src, dst, dst_clip_w); - for (y = 0; y < dst_clip_h; y++) + while (dst_clip_h--) { func(ptr, dst_ptr, dst_clip_w); ptr += src_w; 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 2e1c9a4d16..7907a1c56a 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 @@ -1,6 +1,30 @@ { - DATA32 *src_data; + int x, y, w; + int *lin_ptr, *lp; + int *interp_x, *interp_y, *ix, *iy; + DATA32 *buf, *dptr; + DATA32 **row_ptr, **rp; + DATA32 *ptr, *ptr2, *ptr3, *ptr4; + DATA32 *src_data, *src_end; + RGBA_Image *line_buf; + Gfx_Func_Blend_Src_Cmod_Dst func_cmod; + Gfx_Func_Blend_Src_Mul_Dst func_mul; + Gfx_Func_Blend_Src_Dst func; + + lin_ptr = (int *)malloc(dst_clip_w * sizeof(int)); + row_ptr = (DATA32 **)malloc(dst_clip_h * sizeof(DATA32 *)); + interp_x = (int *)malloc(dst_clip_w * sizeof(int)); + interp_y = (int *)malloc(dst_clip_h * sizeof(int)); + if ( (!lin_ptr) || (!row_ptr) || (!interp_x) || (!interp_y) ) + goto done_scale_up; + + /* a scanline buffer */ + line_buf = evas_common_image_line_buffer_obtain(dst_clip_w); + if (!line_buf) + goto done_scale_up; + buf = line_buf->image->data; + src_data = src->image->data; for (x = 0; x < dst_clip_w; x++) @@ -110,91 +134,100 @@ } } + src_end = src_data + (src_w * src_h) - 1; + func = evas_common_draw_func_blend_get (src, dst, dst_clip_w); + func_cmod = evas_common_draw_func_blend_cmod_get (src, dst, dst_clip_w); + func_mul = evas_common_draw_func_blend_mul_get (src, dc->mul.col, dst, dst_clip_w); + dptr = dst_ptr; + rp = row_ptr; iy = interp_y; + lp = lin_ptr; ix = interp_x; + w = dst_clip_w; +//#undef SCALE_USING_MMX #ifndef SCALE_USING_MMX if (src->flags & RGBA_IMAGE_HAS_ALPHA) { - for (y = 0; y < dst_clip_h; y++) + int k, px, i, pv; + DATA8 p1r = 0, p1g = 0, p1b = 0, p1a = 0; + DATA8 p2r = 0, p2g = 0, p2b = 0, p2a = 0; + DATA32 *lptr1, *lptr2; + + while (dst_clip_h--) { - int i, j, k, l, px; - DATA8 p1r, p1g, p1b, p1a; - DATA8 p2r, p2g, p2b, p2a; - DATA32 *lptr1, *lptr2; - - p1r = p1g = p1b = p1a = 0; - p2r = p2g = p2b = p2a = 0; - - lptr1 = row_ptr[y]; - if ((lptr1 + src_w) >= - (src->image->data + - (src->image->w * - src->image->h))) - lptr2 = lptr1; - else - lptr2 = lptr1 + src_w; - - k = interp_y[y]; - l = 256 - k; - + lptr1 = *rp; + lptr2 = lptr1 + src_w; + if (lptr2 > src_end) lptr2 = lptr1; + k = *iy; dst_ptr = buf; + lp = lin_ptr; ix = interp_x; + ptr = lptr1 + *lp; + ptr2 = lptr2 + *lp; + p2r = R_VAL(ptr) + ((k * (R_VAL(ptr2) - R_VAL(ptr))) >> 8); + p2g = G_VAL(ptr) + ((k * (G_VAL(ptr2) - G_VAL(ptr))) >> 8); + p2b = B_VAL(ptr) + ((k * (B_VAL(ptr2) - B_VAL(ptr))) >> 8); + p2a = A_VAL(ptr) + ((k * (A_VAL(ptr2) - A_VAL(ptr))) >> 8); + pv = 1; px = -1; - - for (x = 0; x < dst_clip_w; x++) + while (dst_clip_w--) { - i = interp_x[x]; - j = 256 - i; - - if (px != lin_ptr[x]) + if (px != *lp) { - px = lin_ptr[x]; + px = *lp; - ptr = lptr1 + lin_ptr[x]; - ptr3 = lptr2 + lin_ptr[x]; - if (lin_ptr[x] >= (src->image->w - 1)) + ptr = lptr1 + px; + ptr2 = ptr + 1; + ptr3 = lptr2 + px; + ptr4 = ptr3 + 1; + if (px >= (src_w - 1)) { ptr2 = ptr; ptr4 = ptr3; } - else - { - ptr2 = ptr + 1; - ptr4 = ptr3 + 1; - } - if (A_VAL(ptr) | - A_VAL(ptr2) | - A_VAL(ptr3) | - A_VAL(ptr4)) + if ((*ptr | *ptr2 | *ptr3 | *ptr4) & 0xff000000) { - p1r = INTERP_2(R_VAL(ptr), R_VAL(ptr3), k, l); - p1g = INTERP_2(G_VAL(ptr), G_VAL(ptr3), k, l); - p1b = INTERP_2(B_VAL(ptr), B_VAL(ptr3), k, l); - p1a = INTERP_2(A_VAL(ptr), A_VAL(ptr3), k, l); - p2r = INTERP_2(R_VAL(ptr2), R_VAL(ptr4), k, l); - p2g = INTERP_2(G_VAL(ptr2), G_VAL(ptr4), k, l); - p2b = INTERP_2(B_VAL(ptr2), B_VAL(ptr4), k, l); - p2a = INTERP_2(A_VAL(ptr2), A_VAL(ptr4), k, l); + if (pv) + { + p1r = p2r; + p1g = p2g; + p1b = p2b; + p1a = p2a; + } + else + { + p1r = R_VAL(ptr) + ((k * (R_VAL(ptr3) - R_VAL(ptr))) >> 8); + p1g = G_VAL(ptr) + ((k * (G_VAL(ptr3) - G_VAL(ptr))) >> 8); + p1b = B_VAL(ptr) + ((k * (B_VAL(ptr3) - B_VAL(ptr))) >> 8); + p1a = A_VAL(ptr) + ((k * (A_VAL(ptr3) - A_VAL(ptr))) >> 8); + } + p2r = R_VAL(ptr2) + ((k * (R_VAL(ptr4) - R_VAL(ptr2))) >> 8); + p2g = G_VAL(ptr2) + ((k * (G_VAL(ptr4) - G_VAL(ptr2))) >> 8); + p2b = B_VAL(ptr2) + ((k * (B_VAL(ptr4) - B_VAL(ptr2))) >> 8); + p2a = A_VAL(ptr2) + ((k * (A_VAL(ptr4) - A_VAL(ptr2))) >> 8); + pv = 1; } else { - p1a = 0; - p2a = 0; + pv = 0; + p1a = p2a = 0; } } + + *dst_ptr = 0; if (p1a | p2a) { - R_VAL(dst_ptr) = INTERP_2(p1r, p2r, i, j); - G_VAL(dst_ptr) = INTERP_2(p1g, p2g, i, j); - B_VAL(dst_ptr) = INTERP_2(p1b, p2b, i, j); - A_VAL(dst_ptr) = INTERP_2(p1a, p2a, i, j); + i = *ix; + R_VAL(dst_ptr) = p1r + ((i * (p2r - p1r)) >> 8); + G_VAL(dst_ptr) = p1g + ((i * (p2g - p1g)) >> 8); + B_VAL(dst_ptr) = p1b + ((i * (p2b - p1b)) >> 8); + A_VAL(dst_ptr) = p1a + ((i * (p2a - p1a)) >> 8); } - else - A_VAL(dst_ptr) = 0; - - dst_ptr++; + + dst_ptr++; ix++; lp++; } + dst_clip_w = w; ix = interp_x; lp = lin_ptr; /* * blend here [clip_w *] buf -> dptr * */ if (dc->mod.use) func_cmod(buf, dptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); @@ -202,73 +235,60 @@ func_mul(buf, dptr, dst_clip_w, dc->mul.col); else func(buf, dptr, dst_clip_w); - dptr += dst_w; + dptr += dst_w; iy++; rp++; } } else { - for (y = 0; y < dst_clip_h; y++) + int k, px, i; + DATA8 p1r = 0, p1g = 0, p1b = 0; + DATA8 p2r = 0, p2g = 0, p2b = 0; + DATA32 *lptr1, *lptr2; + + while (dst_clip_h--) { - int i, j, k, l, px; - DATA8 p1r, p1g, p1b; - DATA8 p2r, p2g, p2b; - DATA32 *lptr1, *lptr2; - - p1r = p1g = p1b = 0; - p2r = p2g = p2b = 0; - - lptr1 = row_ptr[y]; - if ((lptr1 + src_w) >= - (src->image->data + - (src->image->w * - src->image->h))) - lptr2 = lptr1; - else - lptr2 = lptr1 + src_w; - - k = interp_y[y]; - l = 256 - k; - + lptr1 = *rp; + lptr2 = lptr1 + src_w; + if (lptr2 > src_end) lptr2 = lptr1; + k = *iy; dst_ptr = buf; - - px = -1; - - for (x = 0; x < dst_clip_w; x++) + + lp = lin_ptr; ix = interp_x; + ptr = lptr1 + *lp; + ptr2 = lptr2 + *lp; + p2r = R_VAL(ptr) + ((k * (R_VAL(ptr2) - R_VAL(ptr))) >> 8); + p2g = G_VAL(ptr) + ((k * (G_VAL(ptr2) - G_VAL(ptr))) >> 8); + p2b = B_VAL(ptr) + ((k * (B_VAL(ptr2) - B_VAL(ptr))) >> 8); + px = -1; + while (dst_clip_w--) { - i = interp_x[x]; - j = 256 - i; - - if (px != lin_ptr[x]) + if (px != *lp) { - px = lin_ptr[x]; + px = *lp; - ptr = lptr1 + lin_ptr[x]; - ptr3 = lptr2 + lin_ptr[x]; - if (lin_ptr[x] >= (src->image->w - 1)) + ptr2 = lptr1 + px + 1; + ptr4 = lptr2 + px + 1; + if (px >= (src_w - 1)) { - ptr2 = ptr; - ptr4 = ptr3; + ptr2--; + ptr4--; } - else - { - ptr2 = ptr + 1; - ptr4 = ptr3 + 1; - } - - p1r = INTERP_2(R_VAL(ptr), R_VAL(ptr3), k, l); - p1g = INTERP_2(G_VAL(ptr), G_VAL(ptr3), k, l); - p1b = INTERP_2(B_VAL(ptr), B_VAL(ptr3), k, l); - p2r = INTERP_2(R_VAL(ptr2), R_VAL(ptr4), k, l); - p2g = INTERP_2(G_VAL(ptr2), G_VAL(ptr4), k, l); - p2b = INTERP_2(B_VAL(ptr2), B_VAL(ptr4), k, l); + p1r = p2r; + p1g = p2g; + p1b = p2b; + p2r = R_VAL(ptr2) + ((k * (R_VAL(ptr4) - R_VAL(ptr2))) >> 8); + p2g = G_VAL(ptr2) + ((k * (G_VAL(ptr4) - G_VAL(ptr2))) >> 8); + p2b = B_VAL(ptr2) + ((k * (B_VAL(ptr4) - B_VAL(ptr2))) >> 8); } - R_VAL(dst_ptr) = INTERP_2(p1r, p2r, i, j); - G_VAL(dst_ptr) = INTERP_2(p1g, p2g, i, j); - B_VAL(dst_ptr) = INTERP_2(p1b, p2b, i, j); + i = *ix; + R_VAL(dst_ptr) = p1r + ((i * (p2r - p1r)) >> 8); + G_VAL(dst_ptr) = p1g + ((i * (p2g - p1g)) >> 8); + B_VAL(dst_ptr) = p1b + ((i * (p2b - p1b)) >> 8); A_VAL(dst_ptr) = 0xff; - dst_ptr++; + dst_ptr++; ix++; lp++; } + dst_clip_w = w; ix = interp_x; lp = lin_ptr; /* * blend here [clip_w *] buf -> dptr * */ if (dc->mod.use) func_cmod(buf, dptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); @@ -276,123 +296,232 @@ func_mul(buf, dptr, dst_clip_w, dc->mul.col); else func(buf, dptr, dst_clip_w); - dptr += dst_w; + dptr += dst_w; iy++; rp++; } } #else - pxor_r2r(mm7, mm7); - for (y = 0; y < dst_clip_h; y++) + if (src->flags & RGBA_IMAGE_HAS_ALPHA) { + int k, px, a, i; DATA32 *lptr1, *lptr2; - int i, j, k, l, px; - - lptr1 = row_ptr[y]; - if ((lptr1 + src_w) >= - (src->image->data + - (src->image->w * - src->image->h))) - lptr2 = lptr1; - else - lptr2 = lptr1 + src_w; - - k = interp_y[y]; - l = 256 - k; - - dst_ptr = buf; - - /* mm5 = k */ - /* mm6 = l */ - movd_m2r(k, mm5); - punpcklwd_r2r(mm5, mm5); - punpckldq_r2r(mm5, mm5); - movd_m2r(l, mm6); - punpcklwd_r2r(mm6, mm6); - punpckldq_r2r(mm6, mm6); - - px = -1; - - for (x = 0; x < dst_clip_w; x++) + + while (dst_clip_h--) { - i = interp_x[x]; - j = 256 - i; - - /* if we have a new pair of horizontal pixels to */ - /* interpolate between them vertically */ - if (px != lin_ptr[x]) + + lptr1 = *rp; + lptr2 = lptr1 + src_w; + if (lptr2 > src_end) lptr2 = lptr1; + k = *iy / 2; + dst_ptr = buf; + + /* mm5 = k */ + movd_m2r(k, mm5); + punpcklwd_r2r(mm5, mm5); + punpckldq_r2r(mm5, mm5); + + px = -1; + a = 0; + lp = lin_ptr; ix = interp_x; + while (dst_clip_w--) { - px = lin_ptr[x]; - - ptr = lptr1 + lin_ptr[x]; - ptr3 = lptr2 + lin_ptr[x]; - if (lin_ptr[x] >= (src->image->w - 1)) + /* if we have a new pair of horizontal pixels to */ + /* interpolate between them vertically */ + if (px != *lp) { - ptr2 = ptr; - ptr4 = ptr3; + px = *lp; + + ptr = lptr1 + px; + ptr2 = ptr + 1; + ptr3 = lptr2 + px; + ptr4 = ptr3 + 1; + if (px >= (src_w - 1)) + { + ptr2 = ptr; + ptr4 = ptr3; + } + + a = 0; + if ((*ptr | *ptr2 | *ptr3 | *ptr4) & 0xff000000) + { + a = 1; + /* left edge */ + movd_m2r(*ptr, mm0); + pxor_r2r(mm7, mm7); + punpcklbw_r2r(mm7, mm0); + + movd_m2r(*ptr3, mm1); + pxor_r2r(mm7, mm7); + punpcklbw_r2r(mm7, mm1); + psubsw_r2r(mm0, mm1); + pmullw_r2r(mm5, mm1); + psraw_i2r(7, mm1); + + paddsw_r2r(mm1, mm0); + /* mm0 = left edge */ + + /* right edge */ + movd_m2r(*ptr2, mm1); + pxor_r2r(mm7, mm7); + punpcklbw_r2r(mm7, mm1); + + movd_m2r(*ptr4, mm2); + pxor_r2r(mm7, mm7); + punpcklbw_r2r(mm7, mm2); + psubsw_r2r(mm1, mm2); + pmullw_r2r(mm5, mm2); + psraw_i2r(7, mm2); + + paddsw_r2r(mm2, mm1); + /* mm1 = right edge */ + } + } + + if (a) + { + i = *ix / 2; + movq_r2r(mm1, mm4); + + movd_m2r(i, mm2); + punpcklwd_r2r(mm2, mm2); + punpckldq_r2r(mm2, mm2); + + movq_r2r(mm0, mm3); + + psubsw_r2r(mm3, mm4); + pmullw_r2r(mm2, mm4); + psraw_i2r(7, mm4); + paddsw_r2r(mm4, mm3); + + packuswb_r2r(mm3, mm3); + /* blend mm3... */ + movd_r2m(mm3, *dst_ptr); } else - { - ptr2 = ptr + 1; - ptr4 = ptr3 + 1; - } - - /* left edge */ - movd_m2r(ptr[0], mm0); - punpcklbw_r2r(mm7, mm0); - pmullw_r2r(mm6, mm0); - - movd_m2r(ptr3[0], mm1); - punpcklbw_r2r(mm7, mm1); - pmullw_r2r(mm5, mm1); - - paddw_r2r(mm1, mm0); - psrlw_i2r(8, mm0); - /* mm0 = left edge */ - - /* right edge */ - movd_m2r(ptr2[0], mm1); - punpcklbw_r2r(mm7, mm1); - pmullw_r2r(mm6, mm1); - - movd_m2r(ptr4[0], mm2); - punpcklbw_r2r(mm7, mm2); - pmullw_r2r(mm5, mm2); - - paddw_r2r(mm2, mm1); - psrlw_i2r(8, mm1); - /* mm1 = right edge */ + *dst_ptr = 0; + + dst_ptr++; ix++; lp++; } - - movq_r2r(mm1, mm4); - - movd_m2r(i, mm2); - punpcklwd_r2r(mm2, mm2); - punpckldq_r2r(mm2, mm2); - pmullw_r2r(mm2, mm4); - - movq_r2r(mm0, mm3); - - movd_m2r(j, mm2); - punpcklwd_r2r(mm2, mm2); - punpckldq_r2r(mm2, mm2); - pmullw_r2r(mm2, mm3); - - paddw_r2r(mm4, mm3); - psrlw_i2r(8, mm3); - - packuswb_r2r(mm3, mm3); - /* blend mm3... */ - movd_r2m(mm3, dst_ptr[0]); - - dst_ptr++; + /* * blend here [clip_w *] buf -> dptr * */ + dst_clip_w = w; ix = interp_x; lp = lin_ptr; + if (dc->mod.use) + func_cmod(buf, dptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); + else if (dc->mul.use) + func_mul(buf, dptr, dst_clip_w, dc->mul.col); + else + func(buf, dptr, dst_clip_w); + dptr += dst_w; iy++; rp++; + } + } + else + { + int k, px, i; + DATA32 *lptr1, *lptr2; + + while (dst_clip_h--) + { + lptr1 = *rp; + lptr2 = lptr1 + src_w; + if (lptr2 > src_end) lptr2 = lptr1; + k = *iy / 2; + dst_ptr = buf; + + /* mm5 = k */ + movd_m2r(k, mm5); + punpcklwd_r2r(mm5, mm5); + punpckldq_r2r(mm5, mm5); + + lp = lin_ptr; ix = interp_x; + ptr = lptr1 + *lp; + ptr2 = lptr2 + *lp; + /* right edge */ + movd_m2r(*ptr, mm1); + pxor_r2r(mm7, mm7); + punpcklbw_r2r(mm7, mm1); + + movd_m2r(*ptr2, mm2); + pxor_r2r(mm7, mm7); + punpcklbw_r2r(mm7, mm2); + + psubsw_r2r(mm1, mm2); + pmullw_r2r(mm5, mm2); + psraw_i2r(7, mm2); + + paddsw_r2r(mm2, mm1); + /* mm1 = right edge */ + + px = -1; + while (dst_clip_w--) + { + /* if we have a new pair of horizontal pixels to */ + /* interpolate between them vertically */ + if (px != *lp) + { + px = *lp; + + ptr2 = lptr1 + px + 1; + ptr4 = lptr2 + px + 1; + if (px >= (src_w - 1)) + { + ptr2--; + ptr4--; + } + movq_r2r(mm1, mm0); + + /* right edge */ + movd_m2r(*ptr2, mm1); + pxor_r2r(mm7, mm7); + punpcklbw_r2r(mm7, mm1); + + movd_m2r(*ptr4, mm2); + pxor_r2r(mm7, mm7); + punpcklbw_r2r(mm7, mm2); + + psubsw_r2r(mm1, mm2); + pmullw_r2r(mm5, mm2); + psraw_i2r(7, mm2); + + paddsw_r2r(mm2, mm1); + /* mm1 = right edge */ + } + + i = *ix / 2; + + movq_r2r(mm1, mm4); + + movd_m2r(i, mm2); + punpcklwd_r2r(mm2, mm2); + punpckldq_r2r(mm2, mm2); + + movq_r2r(mm0, mm3); + + psubsw_r2r(mm3, mm4); + pmullw_r2r(mm2, mm4); + psraw_i2r(7, mm4); + paddsw_r2r(mm4, mm3); + + packuswb_r2r(mm3, mm3); + /* blend mm3... */ + movd_r2m(mm3, *dst_ptr); + + dst_ptr++; ix++; lp++; + } + /* * blend here [clip_w *] buf -> dptr * */ + dst_clip_w = w; ix = interp_x; lp = lin_ptr; + if (dc->mod.use) + func_cmod(buf, dptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); + else if (dc->mul.use) + func_mul(buf, dptr, dst_clip_w, dc->mul.col); + else + func(buf, dptr, dst_clip_w); + dptr += dst_w; iy++; rp++; } - /* * blend here [clip_w *] buf -> dptr * */ - if (dc->mod.use) - func_cmod(buf, dptr, dst_clip_w, dc->mod.r, dc->mod.g, dc->mod.b, dc->mod.a); - else if (dc->mul.use) - func_mul(buf, dptr, dst_clip_w, dc->mul.col); - else - func(buf, dptr, dst_clip_w); - dptr += dst_w; } #endif + + done_scale_up: + evas_common_image_line_buffer_release(); + if (interp_y) free(interp_y); + if (interp_x) free(interp_x); + if (row_ptr) free(row_ptr); + if (lin_ptr) free(lin_ptr); } diff --git a/legacy/evas/src/lib/engines/directfb/evas_engine_dfb.c b/legacy/evas/src/lib/engines/directfb/evas_engine_dfb.c index a5aaebcf98..f12b04a320 100644 --- a/legacy/evas/src/lib/engines/directfb/evas_engine_dfb.c +++ b/legacy/evas/src/lib/engines/directfb/evas_engine_dfb.c @@ -29,6 +29,10 @@ Evas_Func evas_engine_directfb_func = { evas_engine_directfb_context_multiplier_get, evas_engine_directfb_context_cutout_add, evas_engine_directfb_context_cutout_clear, + evas_engine_directfb_context_anti_alias_set, + evas_engine_directfb_context_anti_alias_get, + evas_engine_directfb_context_color_interpolation_set, + evas_engine_directfb_context_color_interpolation_get, /* rectangle draw funcs */ evas_engine_directfb_draw_rectangle, /* line draw funcs */ @@ -40,6 +44,13 @@ Evas_Func evas_engine_directfb_func = { /* gardient draw funcs */ evas_engine_directfb_gradient_color_add, evas_engine_directfb_gradient_colors_clear, + evas_engine_directfb_gradient_free, + evas_engine_directfb_gradient_fill_set, + evas_engine_directfb_gradient_type_set, + evas_engine_directfb_gradient_type_params_set, + evas_engine_directfb_gradient_geometry_init, + evas_engine_directfb_gradient_alpha_get, + evas_engine_directfb_gradient_map, evas_engine_directfb_gradient_draw, /* image draw funcs */ evas_engine_directfb_image_load, @@ -499,6 +510,42 @@ evas_engine_directfb_context_cutout_clear(void *data, void *context) evas_common_draw_context_clear_cutouts(context); } +void +evas_engine_directfb_context_anti_alias_set(void *data, void *context, unsigned char aa) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_anti_alias(context, aa); +} + +unsigned char +evas_engine_directfb_context_anti_alias_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->anti_alias; +} + +void +evas_engine_directfb_context_color_interpolation_set(void *data, void *context, int color_space) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_color_interpolation(context, color_space); +} + +int +evas_engine_directfb_context_color_interpolation_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->interpolation.color_space; +} + /* * Rectangles * @@ -707,13 +754,78 @@ evas_engine_directfb_gradient_colors_clear(void *data, void *context, void *grad Render_Engine *re; re = (Render_Engine *)data; - if (gradient) evas_common_gradient_free(gradient); - return NULL; + evas_common_gradient_colors_clear(gradient); + return gradient; context = NULL; } void -evas_engine_directfb_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle) +evas_engine_directfb_gradient_free(void *data, void *gradient) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_free(gradient); +} + +void +evas_engine_directfb_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_fill_set(gradient, x, y, w, h); +} + +void +evas_engine_directfb_gradient_type_set(void *data, void *gradient, char *name) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_type_set(gradient, name); +} + +void +evas_engine_directfb_gradient_type_params_set(void *data, void *gradient, char *params) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_type_params_set(gradient, params); +} + +void * +evas_engine_directfb_gradient_geometry_init(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + gradient = evas_common_gradient_geometry_init(gradient, spread); + return gradient; +} + +int +evas_engine_directfb_gradient_alpha_get(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_gradient_has_alpha(gradient, spread); +} + +void +evas_engine_directfb_gradient_map(void *data, void *context, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_map(context, gradient, spread); + evas_common_cpu_end_opt(); +} + +void +evas_engine_directfb_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread) { Render_Engine *re; IDirectFBSurface *surf; @@ -726,7 +838,7 @@ evas_engine_directfb_gradient_draw(void *data, void *context, void *surface, voi surf = (IDirectFBSurface *)im->image->data; surf->Lock(surf, DSLF_WRITE, &p, & pitch); im->image->data = p; - evas_common_gradient_draw(im, context, x, y, w, h, gradient, angle); + evas_common_gradient_draw(im, context, x, y, w, h, gradient, angle, spread); surf->Unlock(surf); im->image->data = (void *)surf; evas_common_cpu_end_opt(); diff --git a/legacy/evas/src/lib/engines/directfb/evas_engine_dfb.h b/legacy/evas/src/lib/engines/directfb/evas_engine_dfb.h index 8bc5f26766..e9e8935689 100644 --- a/legacy/evas/src/lib/engines/directfb/evas_engine_dfb.h +++ b/legacy/evas/src/lib/engines/directfb/evas_engine_dfb.h @@ -99,6 +99,11 @@ void evas_engine_directfb_context_cutout_add(void *data, int h); void evas_engine_directfb_context_cutout_clear(void *data, void *context); +void evas_engine_directfb_context_anti_alias_set(void *data, void *context, unsigned char aa); +unsigned char evas_engine_directfb_context_anti_alias_get(void *data, void *context); +void evas_engine_directfb_context_color_interpolation_set(void *data, + void *context, int color_space); +int evas_engine_directfb_context_color_interpolation_get(void *data, void *context); void evas_engine_directfb_draw_rectangle(void *data, void *context, void *surface, int x, @@ -125,12 +130,19 @@ void *evas_engine_directfb_gradient_color_add(void *data, void *evas_engine_directfb_gradient_colors_clear(void *data, void *context, void *gradient); +void evas_engine_directfb_gradient_free(void *data, void *gradient); +void evas_engine_directfb_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h); +void evas_engine_directfb_gradient_type_set(void *data, void *gradient, char *name); +void evas_engine_directfb_gradient_type_params_set(void *data, void *gradient, char *params); +void *evas_engine_directfb_gradient_geometry_init(void *data, void *gradient, int spread); +int evas_engine_directfb_gradient_alpha_get(void *data, void *gradient, int spread); +void evas_engine_directfb_gradient_map(void *data, void *context, void *gradient, int spread); void evas_engine_directfb_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, - double angle); + double angle, int spread); void *evas_engine_directfb_font_load(void *data, char *name, int size); void *evas_engine_directfb_font_memory_load(void *data, diff --git a/legacy/evas/src/lib/engines/fb/evas_engine.c b/legacy/evas/src/lib/engines/fb/evas_engine.c index 138f7e1070..2425ebea0a 100644 --- a/legacy/evas/src/lib/engines/fb/evas_engine.c +++ b/legacy/evas/src/lib/engines/fb/evas_engine.c @@ -30,14 +30,25 @@ static void evas_engine_fb_context_multiplier_unset(void *data, void *context); static int evas_engine_fb_context_multiplier_get(void *data, void *context, int *r, int *g, int *b, int *a); static void evas_engine_fb_context_cutout_add(void *data, void *context, int x, int y, int w, int h); static void evas_engine_fb_context_cutout_clear(void *data, void *context); -static void evas_engine_fb_draw_rectangle(void *data, void *context, void *surface, int x, int y, int w, int h); +static void evas_engine_fb_context_anti_alias_set(void *data, void *context, unsigned char aa); +static unsigned char evas_engine_fb_context_anti_alias_get(void *data, void *context); +static void evas_engine_fb_context_color_interpolation_set(void *data, void *context, int color_space); +static int evas_engine_fb_context_color_interpolation_get(void *data, void *context); +static void evas_engine_fb_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h); static void evas_engine_fb_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2); static void *evas_engine_fb_polygon_point_add(void *data, void *context, void *polygon, int x, int y); static void *evas_engine_fb_polygon_points_clear(void *data, void *context, void *polygon); static void evas_engine_fb_polygon_draw(void *data, void *context, void *surface, void *polygon); static void *evas_engine_fb_gradient_color_add(void *data, void *context, void *gradient, int r, int g, int b, int a, int distance); static void *evas_engine_fb_gradient_colors_clear(void *data, void *context, void *gradient); -static void evas_engine_fb_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle); +static void evas_engine_fb_gradient_free(void *data, void *gradient); +static void evas_engine_fb_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h); +static void evas_engine_fb_gradient_type_set(void *data, void *gradient, char *name); +static void evas_engine_fb_gradient_type_params_set(void *data, void *gradient, char *params); +static void *evas_engine_fb_gradient_geometry_init(void *data, void *gradient, int spread); +static int evas_engine_fb_gradient_alpha_get(void *data, void *gradient, int spread); +static void evas_engine_fb_gradient_map(void *data, void *context, void *gradient, int spread); +static void evas_engine_fb_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread); static void *evas_engine_fb_image_load(void *data, char *file, char *key, int *error); static void *evas_engine_fb_image_new_from_data(void *data, int w, int h, DATA32 *image_data); static void *evas_engine_fb_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data); @@ -114,14 +125,28 @@ Evas_Func evas_engine_fb_func = evas_engine_fb_context_multiplier_get, evas_engine_fb_context_cutout_add, evas_engine_fb_context_cutout_clear, + evas_engine_fb_context_anti_alias_set, + evas_engine_fb_context_anti_alias_get, + evas_engine_fb_context_color_interpolation_set, + evas_engine_fb_context_color_interpolation_get, /* rectangle draw funcs */ - evas_engine_fb_draw_rectangle, + evas_engine_fb_rectangle_draw, + /* line draw funcs */ evas_engine_fb_line_draw, + /* polygon draw funcs */ evas_engine_fb_polygon_point_add, evas_engine_fb_polygon_points_clear, evas_engine_fb_polygon_draw, + /* gradient draw funcs */ evas_engine_fb_gradient_color_add, evas_engine_fb_gradient_colors_clear, + evas_engine_fb_gradient_free, + evas_engine_fb_gradient_fill_set, + evas_engine_fb_gradient_type_set, + evas_engine_fb_gradient_type_params_set, + evas_engine_fb_gradient_geometry_init, + evas_engine_fb_gradient_alpha_get, + evas_engine_fb_gradient_map, evas_engine_fb_gradient_draw, /* image draw funcs */ evas_engine_fb_image_load, @@ -489,7 +514,43 @@ evas_engine_fb_context_cutout_clear(void *data, void *context) } static void -evas_engine_fb_draw_rectangle(void *data, void *context, void *surface, int x, int y, int w, int h) +evas_engine_fb_context_anti_alias_set(void *data, void *context, unsigned char aa) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_anti_alias(context, aa); +} + +static unsigned char +evas_engine_fb_context_anti_alias_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->anti_alias; +} + +static void +evas_engine_fb_context_color_interpolation_set(void *data, void *context, int color_space) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_color_interpolation(context, color_space); +} + +static int +evas_engine_fb_context_color_interpolation_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->interpolation.color_space; +} + +static void +evas_engine_fb_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h) { Render_Engine *re; @@ -557,18 +618,83 @@ evas_engine_fb_gradient_colors_clear(void *data, void *context, void *gradient) Render_Engine *re; re = (Render_Engine *)data; - if (gradient) evas_common_gradient_free(gradient); - return NULL; + evas_common_gradient_colors_clear(gradient); + return gradient; context = 0; } static void -evas_engine_fb_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle) +evas_engine_fb_gradient_free(void *data, void *gradient) { Render_Engine *re; re = (Render_Engine *)data; - evas_common_gradient_draw(surface, context, x, y, w, h, gradient, angle); + evas_common_gradient_free(gradient); +} + +static void +evas_engine_fb_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_fill_set(gradient, x, y, w, h); +} + +static void +evas_engine_fb_gradient_type_set(void *data, void *gradient, char *name) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_type_set(gradient, name); +} + +static void +evas_engine_fb_gradient_type_params_set(void *data, void *gradient, char *params) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_type_params_set(gradient, params); +} + +static void * +evas_engine_fb_gradient_geometry_init(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + gradient = evas_common_gradient_geometry_init(gradient, spread); + return gradient; +} + +static int +evas_engine_fb_gradient_alpha_get(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_gradient_has_alpha(gradient, spread); +} + +static void +evas_engine_fb_gradient_map(void *data, void *context, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_map(context, gradient, spread); + evas_common_cpu_end_opt(); +} + +static void +evas_engine_fb_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_draw(surface, context, x, y, w, h, gradient, angle, spread); evas_common_cpu_end_opt(); } diff --git a/legacy/evas/src/lib/engines/gl_common/evas_gl_gradient.c b/legacy/evas/src/lib/engines/gl_common/evas_gl_gradient.c index 4b9a5d23b3..66036c38c2 100644 --- a/legacy/evas/src/lib/engines/gl_common/evas_gl_gradient.c +++ b/legacy/evas/src/lib/engines/gl_common/evas_gl_gradient.c @@ -18,15 +18,76 @@ Evas_GL_Gradient * evas_gl_common_gradient_colors_clear(Evas_GL_Gradient *gr) { if (!gr) return NULL; + evas_common_gradient_colors_clear(gr->grad); + return gr; +} + +void +evas_gl_common_gradient_free(Evas_GL_Gradient *gr) +{ + if (!gr) return; if (gr->grad) evas_common_gradient_free(gr->grad); if (gr->tex) evas_gl_common_texture_free(gr->tex); gr->tex = NULL; free(gr); - return NULL; } void -evas_gl_common_gradient_draw(Evas_GL_Context *gc, RGBA_Draw_Context *dc, Evas_GL_Gradient *gr, int x, int y, int w, int h, double angle) +evas_gl_common_gradient_fill_set(Evas_GL_Gradient *gr, int x, int y, int w, int h) +{ + if (!gr) return; + evas_common_gradient_fill_set(gr->grad, x, y, w, h); +} + +void +evas_gl_common_gradient_type_set(Evas_GL_Gradient *gr, char *name) +{ + if (!gr) return; + evas_common_gradient_type_set(gr->grad, name); +} + +void +evas_gl_common_gradient_type_params_set(Evas_GL_Gradient *gr, char *params) +{ + if (!gr) return; + evas_common_gradient_type_params_set(gr->grad, params); +} + +void * +evas_gl_common_gradient_geometry_init(Evas_GL_Gradient *gr, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + if (!gr) return NULL; + gr->grad = evas_common_gradient_geometry_init(gr->grad, spread); + return gr; +} + +int +evas_gl_common_gradient_alpha_get(Evas_GL_Gradient *gr, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + if (!gr) return 0; + return evas_common_gradient_has_alpha(gr->grad, spread); +} + +void +evas_gl_common_gradient_map(RGBA_Draw_Context *dc, Evas_GL_Gradient *gr, int spread) +{ + int mul_use; + + if (!gr || !dc) return; + mul_use = dc->mul.use; + dc->mul.use = 0; + evas_common_gradient_map(dc, gr->grad, spread); + dc->mul.use = mul_use; + evas_common_cpu_end_opt(); +} +void +evas_gl_common_gradient_draw(Evas_GL_Context *gc, RGBA_Draw_Context *dc, Evas_GL_Gradient *gr, int x, int y, int w, int h, double angle, int spread) { int r, g, b, a; @@ -111,10 +172,15 @@ _evas_gl_common_gradient_texture_build(Evas_GL_Context *gc, Evas_GL_Gradient *gr RGBA_Draw_Context *dc; RGBA_Image *im; + return; +/* +FIXME: this has been broken by the new gradient code!! +*/ +/* dc = evas_common_draw_context_new(); if (!dc) return; - map = evas_common_gradient_map(gr->grad, dc, 256); - if (map) + evas_common_gradient_map(dc, gr->grad, 0); + if (map = gr->grad->map.data) { im = evas_common_image_create(256, 4); if (im) @@ -127,7 +193,7 @@ _evas_gl_common_gradient_texture_build(Evas_GL_Context *gc, Evas_GL_Gradient *gr gr->tex = evas_gl_common_texture_new(gc, im, 0); evas_common_image_free(im); } - free(map); } - evas_common_draw_context_free(dc); +*/ +// evas_common_draw_context_free(dc); } diff --git a/legacy/evas/src/lib/engines/gl_x11/evas_engine.c b/legacy/evas/src/lib/engines/gl_x11/evas_engine.c index 7455b74126..ac5857f692 100644 --- a/legacy/evas/src/lib/engines/gl_x11/evas_engine.c +++ b/legacy/evas/src/lib/engines/gl_x11/evas_engine.c @@ -31,6 +31,10 @@ static void evas_engine_gl_x11_context_multiplier_unset(void *data, void *contex static int evas_engine_gl_x11_context_multiplier_get(void *data, void *context, int *r, int *g, int *b, int *a); static void evas_engine_gl_x11_context_cutout_add(void *data, void *context, int x, int y, int w, int h); static void evas_engine_gl_x11_context_cutout_clear(void *data, void *context); +static void evas_engine_gl_x11_context_anti_alias_set(void *data, void *context, unsigned char aa); +static unsigned char evas_engine_gl_x11_context_anti_alias_get(void *data, void *context); +static void evas_engine_gl_x11_context_color_interpolation_set(void *data, void *context, int color_space); +static int evas_engine_gl_x11_context_color_interpolation_get(void *data, void *context); static void evas_engine_gl_x11_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h); static void evas_engine_gl_x11_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2); static void *evas_engine_gl_x11_polygon_point_add(void *data, void *context, void *polygon, int x, int y); @@ -38,7 +42,14 @@ static void *evas_engine_gl_x11_polygon_points_clear(void *data, void *context, static void evas_engine_gl_x11_polygon_draw(void *data, void *context, void *surface, void *polygon); static void *evas_engine_gl_x11_gradient_color_add(void *data, void *context, void *gradient, int r, int g, int b, int a, int distance); static void *evas_engine_gl_x11_gradient_colors_clear(void *data, void *context, void *gradient); -static void evas_engine_gl_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle); +static void evas_engine_gl_x11_gradient_free(void *data, void *gradient); +static void evas_engine_gl_x11_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h); +static void evas_engine_gl_x11_gradient_type_set(void *data, void *gradient, char *name); +static void evas_engine_gl_x11_gradient_type_params_set(void *data, void *gradient, char *params); +static void *evas_engine_gl_x11_gradient_geometry_init(void *data, void *gradient, int spread); +static int evas_engine_gl_x11_gradient_alpha_get(void *data, void *gradient, int spread); +static void evas_engine_gl_x11_gradient_map(void *data, void *context, void *gradient, int spread); +static void evas_engine_gl_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread); static void *evas_engine_gl_x11_image_load(void *data, char *file, char *key, int *error); static void *evas_engine_gl_x11_image_new_from_data(void *data, int w, int h, DATA32 *image_data); static void *evas_engine_gl_x11_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data); @@ -117,6 +128,10 @@ Evas_Func evas_engine_gl_x11_func = evas_engine_gl_x11_context_multiplier_get, evas_engine_gl_x11_context_cutout_add, evas_engine_gl_x11_context_cutout_clear, + evas_engine_gl_x11_context_anti_alias_set, + evas_engine_gl_x11_context_anti_alias_get, + evas_engine_gl_x11_context_color_interpolation_set, + evas_engine_gl_x11_context_color_interpolation_get, /* rectangle draw funcs */ evas_engine_gl_x11_rectangle_draw, /* line draw funcs */ @@ -128,6 +143,13 @@ Evas_Func evas_engine_gl_x11_func = /* gradient draw funcs */ evas_engine_gl_x11_gradient_color_add, evas_engine_gl_x11_gradient_colors_clear, + evas_engine_gl_x11_gradient_free, + evas_engine_gl_x11_gradient_fill_set, + evas_engine_gl_x11_gradient_type_set, + evas_engine_gl_x11_gradient_type_params_set, + evas_engine_gl_x11_gradient_geometry_init, + evas_engine_gl_x11_gradient_alpha_get, + evas_engine_gl_x11_gradient_map, evas_engine_gl_x11_gradient_draw, /* image draw funcs */ evas_engine_gl_x11_image_load, @@ -523,6 +545,42 @@ evas_engine_gl_x11_context_cutout_clear(void *data, void *context) /* not used in gl engine */ } +static void +evas_engine_gl_x11_context_anti_alias_set(void *data, void *context, unsigned char aa) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_anti_alias(context, aa); +} + +static unsigned char +evas_engine_gl_x11_context_anti_alias_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->anti_alias; +} + +static void +evas_engine_gl_x11_context_color_interpolation_set(void *data, void *context, int color_space) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_color_interpolation(context, color_space); +} + +static int +evas_engine_gl_x11_context_color_interpolation_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->interpolation.color_space; +} + @@ -594,13 +652,76 @@ evas_engine_gl_x11_gradient_colors_clear(void *data, void *context, void *gradie } static void -evas_engine_gl_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle) +evas_engine_gl_x11_gradient_free(void *data, void *gradient) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_gl_common_gradient_free(gradient); +} + +static void +evas_engine_gl_x11_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_gl_common_gradient_fill_set(gradient, x, y, w, h); +} + +static void +evas_engine_gl_x11_gradient_type_set(void *data, void *gradient, char *name) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_gl_common_gradient_type_set(gradient, name); +} + +static void +evas_engine_gl_x11_gradient_type_params_set(void *data, void *gradient, char *params) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_gl_common_gradient_type_params_set(gradient, params); +} + +static void * +evas_engine_gl_x11_gradient_geometry_init(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_gl_common_gradient_geometry_init(gradient, spread); +} + +static int +evas_engine_gl_x11_gradient_alpha_get(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_gl_common_gradient_has_alpha(gradient, spread); +} + +static void +evas_engine_gl_x11_gradient_map(void *data, void *context, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_gl_common_gradient_map(context, gradient, spread); +} + +static void +evas_engine_gl_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread) { Render_Engine *re; re = (Render_Engine *)data; evas_engine_gl_x11_window_use(re->win); - evas_gl_common_gradient_draw(re->win->gl_context, context, gradient, x, y, w, h, angle); + evas_gl_common_gradient_draw(re->win->gl_context, context, gradient, x, y, w, h, angle, spread); } static void * diff --git a/legacy/evas/src/lib/engines/software_qtopia/evas_engine.c b/legacy/evas/src/lib/engines/software_qtopia/evas_engine.c index c70e073e81..b16a6995e4 100644 --- a/legacy/evas/src/lib/engines/software_qtopia/evas_engine.c +++ b/legacy/evas/src/lib/engines/software_qtopia/evas_engine.c @@ -30,6 +30,10 @@ static void evas_engine_software_qtopia_context_multiplier_unset(void *data, voi static int evas_engine_software_qtopia_context_multiplier_get(void *data, void *context, int *r, int *g, int *b, int *a); static void evas_engine_software_qtopia_context_cutout_add(void *data, void *context, int x, int y, int w, int h); static void evas_engine_software_qtopia_context_cutout_clear(void *data, void *context); +static void evas_engine_software_qtopia_context_anti_alias_set(void *data, void *context, unsigned char aa); +static unsigned char evas_engine_software_qtopia_context_anti_alias_get(void *data, void *context); +static void evas_engine_software_qtopia_context_color_interpolation_set(void *data, void *context, int color_space); +static int evas_engine_software_qtopia_context_color_interpolation_get(void *data, void *context); static void evas_engine_software_qtopia_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h); static void evas_engine_software_qtopia_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2); static void *evas_engine_software_qtopia_polygon_point_add(void *data, void *context, void *polygon, int x, int y); @@ -37,7 +41,14 @@ static void *evas_engine_software_qtopia_polygon_points_clear(void *data, void * static void evas_engine_software_qtopia_polygon_draw(void *data, void *context, void *surface, void *polygon); static void *evas_engine_software_qtopia_gradient_color_add(void *data, void *context, void *gradient, int r, int g, int b, int a, int distance); static void *evas_engine_software_qtopia_gradient_colors_clear(void *data, void *context, void *gradient); -static void evas_engine_software_qtopia_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle); +static void evas_engine_software_qtopia_gradient_free(void *data, void *gradient); +static void evas_engine_software_qtopia_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h); +static void evas_engine_software_qtopia_gradient_type_set(void *data, void *gradient, char *name); +static void evas_engine_software_qtopia_gradient_type_params_set(void *data, void *gradient, char *params); +static void *evas_engine_software_qtopia_gradient_geometry_init(void *data, void *gradient, int spread); +static int evas_engine_software_qtopia_gradient_alpha_get(void *data, void *gradient, int spread); +static void evas_engine_software_qtopia_gradient_map(void *data, void *context, void *gradient, int spread); +static void evas_engine_software_qtopia_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread); static void *evas_engine_software_qtopia_image_load(void *data, char *file, char *key, int *error); static void *evas_engine_software_qtopia_image_new_from_data(void *data, int w, int h, DATA32 *image_data); static void *evas_engine_software_qtopia_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data); @@ -114,6 +125,10 @@ Evas_Func evas_engine_software_qtopia_func = evas_engine_software_qtopia_context_multiplier_get, evas_engine_software_qtopia_context_cutout_add, evas_engine_software_qtopia_context_cutout_clear, + evas_engine_software_qtopia_context_anti_alias_set, + evas_engine_software_qtopia_context_anti_alias_get, + evas_engine_software_qtopia_context_color_interpolation_set, + evas_engine_software_qtopia_context_color_interpolation_get, /* rectangle draw funcs */ evas_engine_software_qtopia_rectangle_draw, /* line draw funcs */ @@ -125,6 +140,13 @@ Evas_Func evas_engine_software_qtopia_func = /* gradient draw funcs */ evas_engine_software_qtopia_gradient_color_add, evas_engine_software_qtopia_gradient_colors_clear, + evas_engine_software_qtopia_gradient_free, + evas_engine_software_qtopia_gradient_fill_set, + evas_engine_software_qtopia_gradient_type_set, + evas_engine_software_qtopia_gradient_type_params_set, + evas_engine_software_qtopia_gradient_geometry_init, + evas_engine_software_qtopia_gradient_alpha_get, + evas_engine_software_qtopia_gradient_map, evas_engine_software_qtopia_gradient_draw, /* image draw funcs */ evas_engine_software_qtopia_image_load, @@ -506,6 +528,42 @@ evas_engine_software_qtopia_context_cutout_clear(void *data, void *context) evas_common_draw_context_clear_cutouts(context); } +static void +evas_engine_software_qtopia_context_anti_alias_set(void *data, void *context, unsigned char aa) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_anti_alias(context, aa); +} + +static unsigned char +evas_engine_software_qtopia_context_anti_alias_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->anti_alias; +} + +static void +evas_engine_software_qtopia_context_color_interpolation_set(void *data, void *context, int color_space) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_color_interpolation(context, color_space); +} + +static int +evas_engine_software_qtopia_context_color_interpolation_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->interpolation.color_space; +} + @@ -580,18 +638,83 @@ evas_engine_software_qtopia_gradient_colors_clear(void *data, void *context, voi Render_Engine *re; re = (Render_Engine *)data; - if (gradient) evas_common_gradient_free(gradient); - return NULL; + evas_common_gradient_colors_clear(gradient); + return gradient; context = NULL; } static void -evas_engine_software_qtopia_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle) +evas_engine_software_qtopia_gradient_free(void *data, void *gradient) { Render_Engine *re; re = (Render_Engine *)data; - evas_common_gradient_draw(surface, context, x, y, w, h, gradient, angle); + evas_common_gradient_free(gradient); +} + +static void +evas_engine_software_qtopia_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_fill_set(gradient, x, y, w, h); +} + +static void +evas_engine_software_qtopia_gradient_type_set(void *data, void *gradient, char *name) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_type_set(gradient, name); +} + +static void +evas_engine_software_qtopia_gradient_type_params_set(void *data, void *gradient, char *params) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_type_params_set(gradient, params); +} + +static void * +evas_engine_software_qtopia_gradient_geometry_init(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + gradient = evas_common_gradient_geometry_init(gradient, spread); + return gradient; +} + +static int +evas_engine_software_qtopia_gradient_alpha_get(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_gradient_has_alpha(gradient, spread); +} + +static void +evas_engine_software_qtopia_gradient_map(void *data, void *context, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_map(context, gradient, spread); + evas_common_cpu_end_opt(); +} + +static void +evas_engine_software_qtopia_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_draw(surface, context, x, y, w, h, gradient, angle, spread); evas_common_cpu_end_opt(); } diff --git a/legacy/evas/src/lib/engines/software_x11/evas_engine.c b/legacy/evas/src/lib/engines/software_x11/evas_engine.c index 73d0e46427..8b68fc6875 100644 --- a/legacy/evas/src/lib/engines/software_x11/evas_engine.c +++ b/legacy/evas/src/lib/engines/software_x11/evas_engine.c @@ -30,6 +30,10 @@ static void evas_engine_software_x11_context_multiplier_unset(void *data, void * static int evas_engine_software_x11_context_multiplier_get(void *data, void *context, int *r, int *g, int *b, int *a); static void evas_engine_software_x11_context_cutout_add(void *data, void *context, int x, int y, int w, int h); static void evas_engine_software_x11_context_cutout_clear(void *data, void *context); +static void evas_engine_software_x11_context_anti_alias_set(void *data, void *context, unsigned char aa); +static unsigned char evas_engine_software_x11_context_anti_alias_get(void *data, void *context); +static void evas_engine_software_x11_context_color_interpolation_set(void *data, void *context, int color_space); +static int evas_engine_software_x11_context_color_interpolation_get(void *data, void *context); static void evas_engine_software_x11_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h); static void evas_engine_software_x11_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2); static void *evas_engine_software_x11_polygon_point_add(void *data, void *context, void *polygon, int x, int y); @@ -37,7 +41,14 @@ static void *evas_engine_software_x11_polygon_points_clear(void *data, void *con static void evas_engine_software_x11_polygon_draw(void *data, void *context, void *surface, void *polygon); static void *evas_engine_software_x11_gradient_color_add(void *data, void *context, void *gradient, int r, int g, int b, int a, int distance); static void *evas_engine_software_x11_gradient_colors_clear(void *data, void *context, void *gradient); -static void evas_engine_software_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle); +static void evas_engine_software_x11_gradient_free(void *data, void *gradient); +static void evas_engine_software_x11_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h); +static void evas_engine_software_x11_gradient_type_set(void *data, void *gradient, char *name); +static void evas_engine_software_x11_gradient_type_params_set(void *data, void *gradient, char *params); +static void *evas_engine_software_x11_gradient_geometry_init(void *data, void *gradient, int spread); +static int evas_engine_software_x11_gradient_alpha_get(void *data, void *gradient, int spread); +static void evas_engine_software_x11_gradient_map(void *data, void *context, void *gradient, int spread); +static void evas_engine_software_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread); static void *evas_engine_software_x11_image_load(void *data, char *file, char *key, int *error); static void *evas_engine_software_x11_image_new_from_data(void *data, int w, int h, DATA32 *image_data); static void *evas_engine_software_x11_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data); @@ -126,6 +137,10 @@ Evas_Func evas_engine_software_x11_func = evas_engine_software_x11_context_multiplier_get, evas_engine_software_x11_context_cutout_add, evas_engine_software_x11_context_cutout_clear, + evas_engine_software_x11_context_anti_alias_set, + evas_engine_software_x11_context_anti_alias_get, + evas_engine_software_x11_context_color_interpolation_set, + evas_engine_software_x11_context_color_interpolation_get, /* rectangle draw funcs */ evas_engine_software_x11_rectangle_draw, /* line draw funcs */ @@ -137,6 +152,13 @@ Evas_Func evas_engine_software_x11_func = /* gradient draw funcs */ evas_engine_software_x11_gradient_color_add, evas_engine_software_x11_gradient_colors_clear, + evas_engine_software_x11_gradient_free, + evas_engine_software_x11_gradient_fill_set, + evas_engine_software_x11_gradient_type_set, + evas_engine_software_x11_gradient_type_params_set, + evas_engine_software_x11_gradient_geometry_init, + evas_engine_software_x11_gradient_alpha_get, + evas_engine_software_x11_gradient_map, evas_engine_software_x11_gradient_draw, /* image draw funcs */ evas_engine_software_x11_image_load, @@ -546,6 +568,42 @@ evas_engine_software_x11_context_cutout_clear(void *data, void *context) evas_common_draw_context_clear_cutouts(context); } +static void +evas_engine_software_x11_context_anti_alias_set(void *data, void *context, unsigned char aa) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_anti_alias(context, aa); +} + +static unsigned char +evas_engine_software_x11_context_anti_alias_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->anti_alias; +} + +static void +evas_engine_software_x11_context_color_interpolation_set(void *data, void *context, int color_space) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_color_interpolation(context, color_space); +} + +static int +evas_engine_software_x11_context_color_interpolation_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->interpolation.color_space; +} + @@ -629,13 +687,78 @@ evas_engine_software_x11_gradient_colors_clear(void *data, void *context, void * Render_Engine *re; re = (Render_Engine *)data; - if (gradient) evas_common_gradient_free(gradient); - return NULL; + evas_common_gradient_colors_clear(gradient); + return gradient; context = NULL; } static void -evas_engine_software_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle) +evas_engine_software_x11_gradient_free(void *data, void *gradient) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_free(gradient); +} + +static void +evas_engine_software_x11_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_fill_set(gradient, x, y, w, h); +} + +static void +evas_engine_software_x11_gradient_type_set(void *data, void *gradient, char *name) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_type_set(gradient, name); +} + +static void +evas_engine_software_x11_gradient_type_params_set(void *data, void *gradient, char *params) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_type_params_set(gradient, params); +} + +static void * +evas_engine_software_x11_gradient_geometry_init(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + gradient = evas_common_gradient_geometry_init(gradient, spread); + return gradient; +} + +static int +evas_engine_software_x11_gradient_alpha_get(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_gradient_has_alpha(gradient, spread); +} + +static void +evas_engine_software_x11_gradient_map(void *data, void *context, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_map(context, gradient, spread); + evas_common_cpu_end_opt(); +} + +static void +evas_engine_software_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread) { Render_Engine *re; @@ -643,7 +766,7 @@ evas_engine_software_x11_gradient_draw(void *data, void *context, void *surface, #ifdef IMGONLY return; #endif - evas_common_gradient_draw(surface, context, x, y, w, h, gradient, angle); + evas_common_gradient_draw(surface, context, x, y, w, h, gradient, angle, spread); evas_common_cpu_end_opt(); } diff --git a/legacy/evas/src/lib/engines/software_xcb/evas_engine.c b/legacy/evas/src/lib/engines/software_xcb/evas_engine.c index 6617d8f9ef..0ed34e11d4 100644 --- a/legacy/evas/src/lib/engines/software_xcb/evas_engine.c +++ b/legacy/evas/src/lib/engines/software_xcb/evas_engine.c @@ -30,6 +30,10 @@ static void evas_engine_software_xcb_context_multiplier_unset(void *data, void * static int evas_engine_software_xcb_context_multiplier_get(void *data, void *context, int *r, int *g, int *b, int *a); static void evas_engine_software_xcb_context_cutout_add(void *data, void *context, int x, int y, int w, int h); static void evas_engine_software_xcb_context_cutout_clear(void *data, void *context); +static void evas_engine_software_xcb_context_anti_alias_set(void *data, void *context, unsigned char aa); +static unsigned char evas_engine_software_xcb_context_anti_alias_get(void *data, void *context); +static void evas_engine_software_xcb_context_color_interpolation_set(void *data, void *context, int color_space); +static int evas_engine_software_xcb_context_color_interpolation_get(void *data, void *context); static void evas_engine_software_xcb_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h); static void evas_engine_software_xcb_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2); static void *evas_engine_software_xcb_polygon_point_add(void *data, void *context, void *polygon, int x, int y); @@ -37,7 +41,14 @@ static void *evas_engine_software_xcb_polygon_points_clear(void *data, void *con static void evas_engine_software_xcb_polygon_draw(void *data, void *context, void *surface, void *polygon); static void *evas_engine_software_xcb_gradient_color_add(void *data, void *context, void *gradient, int r, int g, int b, int a, int distance); static void *evas_engine_software_xcb_gradient_colors_clear(void *data, void *context, void *gradient); -static void evas_engine_software_xcb_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle); +static void evas_engine_software_xcb_gradient_free(void *data, void *gradient); +static void evas_engine_software_xcb_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h); +static void evas_engine_software_xcb_gradient_type_set(void *data, void *gradient, char *name); +static void evas_engine_software_xcb_gradient_type_params_set(void *data, void *gradient, char *params); +static void *evas_engine_software_xcb_gradient_geometry_init(void *data, void *gradient, int spread); +static int evas_engine_software_xcb_gradient_alpha_get(void *data, void *gradient, int spread); +static void evas_engine_software_xcb_gradient_map(void *data, void *context, void *gradient, int spread); +static void evas_engine_software_xcb_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread); static void *evas_engine_software_xcb_image_load(void *data, char *file, char *key, int *error); static void *evas_engine_software_xcb_image_new_from_data(void *data, int w, int h, DATA32 *image_data); static void *evas_engine_software_xcb_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data); @@ -126,6 +137,10 @@ Evas_Func evas_engine_software_xcb_func = evas_engine_software_xcb_context_multiplier_get, evas_engine_software_xcb_context_cutout_add, evas_engine_software_xcb_context_cutout_clear, + evas_engine_software_xcb_context_anti_alias_set, + evas_engine_software_xcb_context_anti_alias_get, + evas_engine_software_xcb_context_color_interpolation_set, + evas_engine_software_xcb_context_color_interpolation_get, /* rectangle draw funcs */ evas_engine_software_xcb_rectangle_draw, /* line draw funcs */ @@ -137,6 +152,13 @@ Evas_Func evas_engine_software_xcb_func = /* gradient draw funcs */ evas_engine_software_xcb_gradient_color_add, evas_engine_software_xcb_gradient_colors_clear, + evas_engine_software_xcb_gradient_free, + evas_engine_software_xcb_gradient_fill_set, + evas_engine_software_xcb_gradient_type_set, + evas_engine_software_xcb_gradient_type_params_set, + evas_engine_software_xcb_gradient_geometry_init, + evas_engine_software_xcb_gradient_alpha_get, + evas_engine_software_xcb_gradient_map, evas_engine_software_xcb_gradient_draw, /* image draw funcs */ evas_engine_software_xcb_image_load, @@ -569,6 +591,42 @@ evas_engine_software_xcb_context_cutout_clear(void *data, void *context) evas_common_draw_context_clear_cutouts(context); } +static void +evas_engine_software_xcb_context_anti_alias_set(void *data, void *context, unsigned char aa) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_anti_alias(context, aa); +} + +static unsigned char +evas_engine_software_xcb_context_anti_alias_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->anti_alias; +} + +static void +evas_engine_software_xcb_context_color_interpolation_set(void *data, void *context, int color_space) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_color_interpolation(context, color_space); +} + +static int +evas_engine_software_xcb_context_color_interpolation_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->interpolation.color_space; +} + @@ -652,13 +710,78 @@ evas_engine_software_xcb_gradient_colors_clear(void *data, void *context, void * Render_Engine *re; re = (Render_Engine *)data; - if (gradient) evas_common_gradient_free(gradient); - return NULL; + evas_common_gradient_colors_clear(gradient); + return gradient; context = NULL; } static void -evas_engine_software_xcb_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle) +evas_engine_software_xcb_gradient_free(void *data, void *gradient) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_free(gradient); +} + +static void +evas_engine_software_xcb_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_fill_set(gradient, x, y, w, h); +} + +static void +evas_engine_software_xcb_gradient_type_set(void *data, void *gradient, char *name) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_type_set(gradient, name); +} + +static void +evas_engine_software_xcb_gradient_type_params_set(void *data, void *gradient, char *params) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_type_params_set(gradient, params); +} + +static void * +evas_engine_software_xcb_gradient_geometry_init(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + gradient = evas_common_gradient_geometry_init(gradient, spread); + return gradient; +} + +static int +evas_engine_software_xcb_gradient_alpha_get(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return evas_common_gradient_has_alpha(gradient, spread); +} + +static void +evas_engine_software_xcb_gradient_map(void *data, void *context, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_gradient_map(context, gradient, spread); + evas_common_cpu_end_opt(); +} + +static void +evas_engine_software_xcb_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread) { Render_Engine *re; @@ -666,7 +789,7 @@ evas_engine_software_xcb_gradient_draw(void *data, void *context, void *surface, #ifdef IMGONLY return; #endif - evas_common_gradient_draw(surface, context, x, y, w, h, gradient, angle); + evas_common_gradient_draw(surface, context, x, y, w, h, gradient, angle, spread); evas_common_cpu_end_opt(); } diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine.c b/legacy/evas/src/lib/engines/xrender_x11/evas_engine.c index ec081d692e..e19f9a5132 100644 --- a/legacy/evas/src/lib/engines/xrender_x11/evas_engine.c +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine.c @@ -29,6 +29,10 @@ static void evas_engine_xrender_x11_context_multiplier_unset(void *data, void *c static int evas_engine_xrender_x11_context_multiplier_get(void *data, void *context, int *r, int *g, int *b, int *a); static void evas_engine_xrender_x11_context_cutout_add(void *data, void *context, int x, int y, int w, int h); static void evas_engine_xrender_x11_context_cutout_clear(void *data, void *context); +static void evas_engine_xrender_x11_context_anti_alias_set(void *data, void *context, unsigned char aa); +static unsigned char evas_engine_xrender_x11_context_anti_alias_get(void *data, void *context); +static void evas_engine_xrender_x11_context_color_interpolation_set(void *data, void *context, int color_space); +static int evas_engine_xrender_x11_context_color_interpolation_get(void *data, void *context); static void evas_engine_xrender_x11_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h); static void evas_engine_xrender_x11_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2); static void *evas_engine_xrender_x11_polygon_point_add(void *data, void *context, void *polygon, int x, int y); @@ -36,7 +40,14 @@ static void *evas_engine_xrender_x11_polygon_points_clear(void *data, void *cont static void evas_engine_xrender_x11_polygon_draw(void *data, void *context, void *surface, void *polygon); static void *evas_engine_xrender_x11_gradient_color_add(void *data, void *context, void *gradient, int r, int g, int b, int a, int distance); static void *evas_engine_xrender_x11_gradient_colors_clear(void *data, void *context, void *gradient); -static void evas_engine_xrender_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle); +static void evas_engine_xrender_x11_gradient_free(void *data, void *gradient); +static void evas_engine_xrender_x11_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h); +static void evas_engine_xrender_x11_gradient_type_set(void *data, void *gradient, char *name); +static void evas_engine_xrender_x11_gradient_type_params_set(void *data, void *gradient, char *params); +static void *evas_engine_xrender_x11_gradient_geometry_init(void *data, void *gradient, int spread); +static int evas_engine_xrender_x11_gradient_alpha_get(void *data, void *gradient, int spread); +static void evas_engine_xrender_x11_gradient_map(void *data, void *context, void *gradient, int spread); +static void evas_engine_xrender_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread); static void *evas_engine_xrender_x11_image_load(void *data, char *file, char *key, int *error); static void *evas_engine_xrender_x11_image_new_from_data(void *data, int w, int h, DATA32 *image_data); static void *evas_engine_xrender_x11_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data); @@ -131,6 +142,10 @@ Evas_Func evas_engine_xrender_x11_func = evas_engine_xrender_x11_context_multiplier_get, evas_engine_xrender_x11_context_cutout_add, evas_engine_xrender_x11_context_cutout_clear, + evas_engine_xrender_x11_context_anti_alias_set, + evas_engine_xrender_x11_context_anti_alias_get, + evas_engine_xrender_x11_context_color_interpolation_set, + evas_engine_xrender_x11_context_color_interpolation_get, /* rectangle draw funcs */ evas_engine_xrender_x11_rectangle_draw, /* line draw funcs */ @@ -142,6 +157,13 @@ Evas_Func evas_engine_xrender_x11_func = /* gradient draw funcs */ evas_engine_xrender_x11_gradient_color_add, evas_engine_xrender_x11_gradient_colors_clear, + evas_engine_xrender_x11_gradient_free, + evas_engine_xrender_x11_gradient_fill_set, + evas_engine_xrender_x11_gradient_type_set, + evas_engine_xrender_x11_gradient_type_params_set, + evas_engine_xrender_x11_gradient_geometry_init, + evas_engine_xrender_x11_gradient_alpha_get, + evas_engine_xrender_x11_gradient_map, evas_engine_xrender_x11_gradient_draw, /* image draw funcs */ evas_engine_xrender_x11_image_load, @@ -571,6 +593,41 @@ evas_engine_xrender_x11_context_cutout_clear(void *data, void *context) evas_common_draw_context_clear_cutouts(context); } +static void +evas_engine_xrender_x11_context_anti_alias_set(void *data, void *context, unsigned char aa) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_anti_alias(context, aa); +} + +static unsigned char +evas_engine_xrender_x11_context_anti_alias_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->anti_alias; +} + +static void +evas_engine_xrender_x11_context_color_interpolation_set(void *data, void *context, int color_space) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_draw_context_set_color_interpolation(context, color_space); +} + +static int +evas_engine_xrender_x11_context_color_interpolation_get(void *data, void *context) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return ((RGBA_Draw_Context *)context)->interpolation.color_space; +} @@ -642,14 +699,77 @@ evas_engine_xrender_x11_gradient_colors_clear(void *data, void *context, void *g } static void -evas_engine_xrender_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle) +evas_engine_xrender_x11_gradient_free(void *data, void *gradient) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + _xre_gradient_free((XR_Gradient *)gradient); +} + +static void +evas_engine_xrender_x11_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + _xre_gradient_fill_set((XR_Gradient *)gradient, x, y, w, h); +} + +static void +evas_engine_xrender_x11_gradient_type_set(void *data, void *gradient, char *name) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + _xre_gradient_type_set((XR_Gradient *)gradient, name); +} + +static void +evas_engine_xrender_x11_gradient_type_params_set(void *data, void *gradient, char *params) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + _xre_gradient_type_params_set((XR_Gradient *)gradient, params); +} + +static void * +evas_engine_xrender_x11_gradient_geometry_init(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return _xre_gradient_geometry_init((XR_Gradient *)gradient, spread); +} + +static int +evas_engine_xrender_x11_gradient_alpha_get(void *data, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return _xre_gradient_alpha_get((XR_Gradient *)gradient, spread); +} + +static void +evas_engine_xrender_x11_gradient_map(void *data, void *context, void *gradient, int spread) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + _xre_gradient_map((RGBA_Draw_Context *)context, (XR_Gradient *)gradient, spread); +} + +static void +evas_engine_xrender_x11_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread) { Render_Engine *re; re = (Render_Engine *)data; _xre_gradient_draw((Xrender_Surface *)surface, (RGBA_Draw_Context *)context, - (XR_Gradient *)gradient, x, y, w, h, angle); + (XR_Gradient *)gradient, x, y, w, h, angle, spread); } static void * diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine.h b/legacy/evas/src/lib/engines/xrender_x11/evas_engine.h index 269c88a20f..330e8e5abb 100644 --- a/legacy/evas/src/lib/engines/xrender_x11/evas_engine.h +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine.h @@ -144,10 +144,19 @@ struct _XR_Gradient Xrender_Surface *surface; RGBA_Gradient *grad; double angle; + int spread; + unsigned char changed; }; XR_Gradient *_xre_gradient_color_add(Ximage_Info *xinf, XR_Gradient *gr, int r, int g, int b, int a, int distance); XR_Gradient *_xre_gradient_colors_clear(XR_Gradient *gr); -void _xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, int x, int y, int w, int h, double angle); +void _xre_gradient_free(XR_Gradient *gr); +void _xre_gradient_fill_set(XR_Gradient *gr, int x, int y, int w, int h); +void _xre_gradient_type_set(XR_Gradient *gr, char *name); +void _xre_gradient_type_params_set(XR_Gradient *gr, char *params); +void *_xre_gradient_geometry_init(XR_Gradient *gr, int spread); +int _xre_gradient_alpha_get(XR_Gradient *gr, int spread); +void _xre_gradient_map(RGBA_Draw_Context *dc, XR_Gradient *gr, int spread); +void _xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, int x, int y, int w, int h, double angle, int spread); #endif diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_gradient.c b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_gradient.c index ddf69d6aa3..be78f906e9 100644 --- a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_gradient.c +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_gradient.c @@ -28,6 +28,7 @@ _xre_gradient_color_add(Ximage_Info *xinf, XR_Gradient *gr, int r, int g, int b, _xr_render_surface_free(gr->surface); gr->surface = NULL; } + gr->changed = 1; return gr; } @@ -35,6 +36,20 @@ XR_Gradient * _xre_gradient_colors_clear(XR_Gradient *gr) { if (!gr) return NULL; + evas_common_gradient_colors_clear(gr->grad); + if (gr->surface) + { + _xr_render_surface_free(gr->surface); + gr->surface = NULL; + } + gr->changed = 1; + return gr; +} + +void +_xre_gradient_free(XR_Gradient *gr) +{ + if (!gr) return; if (gr->grad) { evas_common_gradient_free(gr->grad); @@ -47,17 +62,64 @@ _xre_gradient_colors_clear(XR_Gradient *gr) } _xr_image_info_free(gr->xinf); free(gr); - return NULL; } void -_xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, int x, int y, int w, int h, double angle) +_xre_gradient_fill_set(XR_Gradient *gr, int x, int y, int w, int h) +{ + if (!gr) return; + evas_common_gradient_fill_set(gr->grad, x, y, w, h); + gr->changed = 1; +} + +void +_xre_gradient_type_set(XR_Gradient *gr, char *name) +{ + if (!gr) return; + evas_common_gradient_type_set(gr->grad, name); + gr->changed = 1; +} + +void +_xre_gradient_type_params_set(XR_Gradient *gr, char *params) +{ + if (!gr) return; + evas_common_gradient_type_params_set(gr->grad, params); + gr->changed = 1; +} + +void * +_xre_gradient_geometry_init(XR_Gradient *gr, int spread) +{ + if (!gr) return NULL; + gr->grad = evas_common_gradient_geometry_init(gr->grad, spread); + return gr; +} + +int +_xre_gradient_alpha_get(XR_Gradient *gr, int spread) +{ + if (!gr) return 0; + return evas_common_gradient_has_alpha(gr->grad, spread); +} + +void +_xre_gradient_map(RGBA_Draw_Context *dc, XR_Gradient *gr, int spread) +{ + if (!gr) return; + evas_common_gradient_map(dc, gr->grad, spread); + evas_common_cpu_end_opt(); + gr->changed = 1; +} + +void +_xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, int x, int y, int w, int h, double angle, int spread) { RGBA_Image *im; if ((w <= 0) || (h <= 0)) return; - if (angle != gr->angle) + if ((angle != gr->angle) || (spread != gr->spread) || (gr->changed)) { if (gr->surface) { @@ -67,7 +129,7 @@ _xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, } if (!gr->surface) { - im = evas_common_image_create(256, 256); + im = evas_common_image_create(w, h); if (im) { RGBA_Draw_Context *dc2; @@ -77,16 +139,20 @@ _xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, { im->flags |= RGBA_IMAGE_HAS_ALPHA; memset(im->image->data, 0, im->image->w * im->image->h * sizeof(DATA32)); - evas_common_gradient_draw(im, dc2, 0, 0, 256, 256, gr->grad, angle); - gr->surface = _xr_render_surface_new(gr->xinf, 256, 256, gr->xinf->fmt32, 1); + dc2->anti_alias = dc->anti_alias; + dc2->interpolation.color_space = dc->interpolation.color_space; + evas_common_gradient_draw(im, dc2, 0, 0, w, h, gr->grad, angle, spread); + gr->surface = _xr_render_surface_new(gr->xinf, w, h, gr->xinf->fmt32, 1); if (gr->surface) - _xr_render_surface_argb_pixels_fill(gr->surface, 256, 256, im->image->data, 0, 0, 256, 256); + _xr_render_surface_argb_pixels_fill(gr->surface, w, h, im->image->data, 0, 0, w, h); evas_common_draw_context_free(dc2); gr->angle = angle; + gr->spread = spread; } evas_common_image_free(im); } } if (gr->surface) _xr_render_surface_composite(gr->surface, rs, dc, 0, 0, gr->surface->w, gr->surface->h, x, y, w, h, 1); + gr->changed = 0; } diff --git a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_xrender.c b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_xrender.c index f4afc01d33..200ab666b8 100644 --- a/legacy/evas/src/lib/engines/xrender_x11/evas_engine_xrender.c +++ b/legacy/evas/src/lib/engines/xrender_x11/evas_engine_xrender.c @@ -143,12 +143,22 @@ _xr_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *p sple = sp + w; while (sp < sple) { - a = A_VAL(sp); - aa = a + 1; - r = ((R_VAL(sp)) * aa) >> 8; - g = ((G_VAL(sp)) * aa) >> 8; - b = ((B_VAL(sp)) * aa) >> 8; - *p = (b << 24) | (g << 16) | (r << 8) | a; + switch (a = A_VAL(sp)) + { + case 0: + *p = 0; + break; + case 255: + *p = (B_VAL(sp) << 24) | (G_VAL(sp) << 16) | (R_VAL(sp) << 8) | 0xff; + break; + default: + aa = a + 1; + r = ((R_VAL(sp)) * aa) >> 8; + g = ((G_VAL(sp)) * aa) >> 8; + b = ((B_VAL(sp)) * aa) >> 8; + *p = (b << 24) | (g << 16) | (r << 8) | a; + break; + } p++; sp++; } @@ -163,12 +173,22 @@ _xr_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *p sple = sp + w; while (sp < sple) { - a = A_VAL(sp); - aa = a + 1; - r = ((R_VAL(sp)) * aa) >> 8; - g = ((G_VAL(sp)) * aa) >> 8; - b = ((B_VAL(sp)) * aa) >> 8; - *p = (a << 24) | (r << 16) | (g << 8) | b; + switch (a = A_VAL(sp)) + { + case 0: + *p = 0; + break; + case 255: + *p = *sp; + break; + default: + aa = a + 1; + r = ((R_VAL(sp)) * aa) >> 8; + g = ((G_VAL(sp)) * aa) >> 8; + b = ((B_VAL(sp)) * aa) >> 8; + *p = (a << 24) | (r << 16) | (g << 8) | b; + break; + } p++; sp++; } diff --git a/legacy/evas/src/lib/include/evas_common.h b/legacy/evas/src/lib/include/evas_common.h index afa7b76515..67247596dc 100644 --- a/legacy/evas/src/lib/include/evas_common.h +++ b/legacy/evas/src/lib/include/evas_common.h @@ -80,6 +80,7 @@ typedef struct _RGBA_Image_Span RGBA_Image_Span; typedef struct _RGBA_Draw_Context RGBA_Draw_Context; typedef struct _RGBA_Gradient RGBA_Gradient; typedef struct _RGBA_Gradient_Color RGBA_Gradient_Color; +typedef struct _RGBA_Gradient_Type RGBA_Gradient_Type; typedef struct _RGBA_Polygon_Point RGBA_Polygon_Point; typedef struct _RGBA_Font RGBA_Font; typedef struct _RGBA_Font_Int RGBA_Font_Int; @@ -105,6 +106,10 @@ typedef void (*Gfx_Func_Blend_Src_Alpha_Mul_Dst) (DATA8 *src, DATA32 *dst, int l typedef void (*Gfx_Func_Convert) (DATA32 *src, DATA8 *dst, int src_jump, int dst_jump, int w, int h, int dith_x, int dith_y, DATA8 *pal); +typedef void (*Gfx_Func_Gradient_Span)(DATA32 *map, int map_len, DATA32 *dst, int dst_len, + int x, int y, int axx, int axy, int ayx, int ayy, + void *geom_data); + /*****************************************************************************/ typedef enum _RGBA_Image_Flags @@ -195,6 +200,10 @@ struct _RGBA_Draw_Context } func; void *data; } font_ext; + struct { + int color_space; + } interpolation; + unsigned char anti_alias : 1; }; struct _RGBA_Surface @@ -233,6 +242,36 @@ struct _RGBA_Gradient_Color struct _RGBA_Gradient { Evas_Object_List *colors; + int ncolors; + int len; + + unsigned char has_alpha : 1; + struct + { + int x, y, w, h; + } fill; + struct + { + char *name; + char *params; + RGBA_Gradient_Type *geometer; + } type; + struct + { + DATA32 *data; + int len; + unsigned char has_alpha : 1; + } map; +}; + +struct _RGBA_Gradient_Type +{ + char *name; + void *geom_data; + void (*setup_geom)(RGBA_Gradient *gr, int spread); + int (*has_alpha)(RGBA_Gradient *gr, int spread); + int (*get_map_len)(RGBA_Gradient *gr, int spread); + Gfx_Func_Gradient_Span (*get_span_func)(RGBA_Gradient *gr, int spread, unsigned char aa); }; struct _RGBA_Polygon_Point @@ -362,6 +401,7 @@ struct _Convert_Pal }; /*****************************************************************************/ +#include "evas_macros.h" #define CONVERT_LOOP_START_ROT_0() \ src_ptr = src; \ @@ -474,6 +514,12 @@ x++; #define GB_VAL(p) ((DATA16 *)(p)[1]) #endif +#define RGB_JOIN(r,g,b) \ + (((r) << 16) + ((g) << 8) + (b)) + +#define ARGB_JOIN(a,r,g,b) \ + (((a) << 24) + ((r) << 16) + ((g) << 8) + (b)) + /* thanks to some chats with Mirek Fidler... the new blender code for C * blender fallbacks is faster. benchmarks (for the blending code only): * @@ -541,6 +587,12 @@ x++; } \ } +#define _EVAS_TEXTURE_REFLECT 0 +#define _EVAS_TEXTURE_REPEAT 1 +#define _EVAS_TEXTURE_RESTRICT 2 + +#define _EVAS_COLOR_SPACE_ARGB 0 +#define _EVAS_COLOR_SPACE_AHSV 1 /*****************************************************************************/ @@ -586,6 +638,9 @@ void *evas_object_list_remove (void *in_list, void *in_item); void *evas_object_list_find (void *in_list, void *in_item); /****/ +void evas_common_init (void); +void evas_common_shutdown (void); + void evas_common_cpu_init (void); int evas_common_cpu_have_cpuid (void); @@ -596,6 +651,7 @@ void evas_common_cpu_end_opt (void); /****/ void evas_common_blend_init (void); void evas_common_blend_init_evas_pow_lut (void); +void evas_common_blend_free_evas_pow_lut (void); void evas_common_blend_pixels_rgba_to_rgb_c (DATA32 *src, DATA32 *dst, int len); void evas_common_blend_pixels_rgba_to_rgb_mmx (DATA32 *src, DATA32 *dst, int len); @@ -627,10 +683,6 @@ void evas_common_blend_pixels_cmod_rgba_to_rgba_c (DATA32 *src, DATA32 *ds void evas_common_copy_pixels_cmod_rgba_to_rgba_c (DATA32 *src, DATA32 *dst, int len, DATA8 *rmod, DATA8 *gmod, DATA8 *bmod, DATA8 *amod); void evas_common_copy_pixels_cmod_rgb_to_rgba_c (DATA32 *src, DATA32 *dst, int len, DATA8 *rmod, DATA8 *gmod, DATA8 *bmod, DATA8 *amod); -void evas_common_blend_pixels_mul_color_rgba_to_rgb_c (DATA32 *src, DATA32 *dst, int len, DATA32 mul_color); -void evas_common_blend_pixels_mul_color_rgba_to_rgb_mmx (DATA32 *src, DATA32 *dst, int len, DATA32 mul_color); -void evas_common_blend_pixels_mul_color_rgba_to_rgba_c (DATA32 *src, DATA32 *dst, int len, DATA32 mul_color); - void evas_common_blend_alpha_color_rgba_to_rgb_c (DATA8 *src, DATA32 *dst, int len, DATA32 col); void evas_common_blend_alpha_color_rgba_to_rgb_mmx (DATA8 *src, DATA32 *dst, int len, DATA32 col); void evas_common_blend_alpha_color_rgba_to_rgba_c (DATA8 *src, DATA32 *dst, int len, DATA32 col); @@ -702,6 +754,11 @@ void evas_common_convert_rgba_to_1bpp_gry_1_dith (DATA32 *src, DAT void evas_common_convert_yuv_420p_601_rgba (DATA8 **src, DATA8 *dst, int w, int h); +void evas_common_convert_hsv_to_rgb (float h, float s, float v, int *r, int *g, int *b); +void evas_common_convert_rgb_to_hsv (int r, int g, int b, float *h, float *s, float *v); +void evas_common_convert_hsv_to_rgb_int (int h, int s, int v, int *r, int *g, int *b); +void evas_common_convert_rgb_to_hsv_int (int r, int g, int b, int *h, int *s, int *v); + /****/ void evas_common_scale_init (void); @@ -746,11 +803,16 @@ void evas_common_image_unstore (RGBA_Image *im); RGBA_Image *evas_common_image_find (const char *filename, const char *key, DATA64 timestamp); int evas_common_image_ram_usage (RGBA_Image *im); void evas_common_image_dirty (RGBA_Image *im); +void evas_common_image_cache_free (void); RGBA_Image *evas_common_load_image_from_file (const char *file, const char *key); void evas_common_load_image_data_from_file(RGBA_Image *im); int evas_common_save_image_to_file (RGBA_Image *im, const char *file, const char *key, int quality, int compress); +RGBA_Image *evas_common_image_line_buffer_obtain (int len); +void evas_common_image_line_buffer_release (void); +void evas_common_image_line_buffer_free (void); + /****/ void evas_common_rectangle_init (void); @@ -763,8 +825,21 @@ RGBA_Gradient *evas_common_gradient_new (void); void evas_common_gradient_free (RGBA_Gradient *gr); void evas_common_gradient_colors_clear (RGBA_Gradient *gr); void evas_common_gradient_color_add (RGBA_Gradient *gr, int r, int g, int b, int a, int dist); -void evas_common_gradient_draw (RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h, RGBA_Gradient *gr, double angle); -DATA32 *evas_common_gradient_map (RGBA_Gradient *gr, RGBA_Draw_Context *dc, int len); +void evas_common_gradient_type_set (RGBA_Gradient *gr, char *name); +void evas_common_gradient_type_params_set (RGBA_Gradient *gr, char *params); +void evas_common_gradient_fill_set (RGBA_Gradient *gr, int x, int y, int w, int h); +RGBA_Gradient *evas_common_gradient_geometry_init (RGBA_Gradient *gr, int spread); +int evas_common_gradient_has_alpha (RGBA_Gradient *gr, int spread); +void evas_common_gradient_map (RGBA_Draw_Context *dc, RGBA_Gradient *gr, int spread); +void evas_common_gradient_draw (RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h, RGBA_Gradient *gr, double angle, int spread); + +RGBA_Gradient_Type *evas_common_gradient_geometer_get (char *name); +RGBA_Gradient_Type *evas_common_gradient_linear_get (void); +RGBA_Gradient_Type *evas_common_gradient_radial_get (void); +RGBA_Gradient_Type *evas_common_gradient_angular_get (void); +RGBA_Gradient_Type *evas_common_gradient_rectangular_get (void); +RGBA_Gradient_Type *evas_common_gradient_sinusoidal_get (void); +char *evas_common_gradient_get_key_fval (char *in, char *key, float *val); /****/ void evas_common_line_init (void); @@ -870,11 +945,14 @@ void evas_common_draw_context_apply_free_cutouts(Cutout_Rect *rect Cutout_Rect *evas_common_draw_context_cutouts_split (Cutout_Rect *in, Cutout_Rect *split); Cutout_Rect *evas_common_draw_context_cutout_split (Cutout_Rect *in, Cutout_Rect *split); Cutout_Rect *evas_common_draw_context_cutout_merge (Cutout_Rect *in, Cutout_Rect *merge); +void evas_common_draw_context_set_anti_alias (RGBA_Draw_Context *dc, unsigned char aa); +void evas_common_draw_context_set_color_interpolation (RGBA_Draw_Context *dc, int color_space); + Gfx_Func_Blend_Src_Dst evas_common_draw_func_blend_get (RGBA_Image *src, RGBA_Image *dst, int pixels); Gfx_Func_Blend_Color_Dst evas_common_draw_func_blend_color_get (DATA32 src, RGBA_Image *dst, int pixels); Gfx_Func_Blend_Src_Cmod_Dst evas_common_draw_func_blend_cmod_get (RGBA_Image *src, RGBA_Image *dst, int pixels); Gfx_Func_Blend_Src_Mul_Dst evas_common_draw_func_blend_mul_get (RGBA_Image *src, DATA32 col, RGBA_Image *dst, int pixels); -Gfx_Func_Blend_Src_Alpha_Mul_Dst evas_common_draw_func_blend_alpha_get (RGBA_Image *dst); +Gfx_Func_Blend_Src_Alpha_Mul_Dst evas_common_draw_func_blend_alpha_get (DATA32 src, RGBA_Image *dst); Gfx_Func_Blend_Src_Dst evas_common_draw_func_copy_get (int pixels, int reverse); void evas_font_dir_cache_free(void); diff --git a/legacy/evas/src/lib/include/evas_gl_common.h b/legacy/evas/src/lib/include/evas_gl_common.h index 32562af02d..bc435a9c9d 100644 --- a/legacy/evas/src/lib/include/evas_gl_common.h +++ b/legacy/evas/src/lib/include/evas_gl_common.h @@ -187,6 +187,14 @@ Evas_GL_Polygon *evas_gl_common_poly_points_clear(Evas_GL_Polygon *poly); Evas_GL_Gradient *evas_gl_common_gradient_color_add(Evas_GL_Gradient *gr, int r, int g, int b, int a, int distance); Evas_GL_Gradient *evas_gl_common_gradient_colors_clear(Evas_GL_Gradient *gr); +void evas_gl_common_gradient_free(Evas_GL_Gradient *gr); +void evas_gl_common_gradient_fill_set(Evas_GL_Gradient *gr, int x, int y, int w, int h); +void evas_gl_common_gradient_type_set(Evas_GL_Gradient *gr, char *name); +void evas_gl_common_gradient_type_params_set(Evas_GL_Gradient *gr, char *params); +void *evas_gl_common_gradient_geometry_init(Evas_GL_Gradient *gr, int spread); +int evas_gl_common_gradient_alpha_get(Evas_GL_Gradient *gr, int spread); + +void evas_gl_common_gradient_map(RGBA_Draw_Context *dc, Evas_GL_Gradient *gr, int spread); void evas_gl_common_swap_rect(Evas_GL_Context *gc, int x, int y, int w, int h); @@ -194,7 +202,7 @@ void evas_gl_common_rect_draw(Evas_GL_Context *gc, RGBA_Draw_Contex void evas_gl_common_image_draw(Evas_GL_Context *gc, RGBA_Draw_Context *dc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth); void evas_gl_common_line_draw(Evas_GL_Context *gc, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2); void evas_gl_common_poly_draw(Evas_GL_Context *gc, RGBA_Draw_Context *dc, Evas_GL_Polygon *poly); -void evas_gl_common_gradient_draw(Evas_GL_Context *gc, RGBA_Draw_Context *dc, Evas_GL_Gradient *gr, int x, int y, int w, int h, double angle); +void evas_gl_common_gradient_draw(Evas_GL_Context *gc, RGBA_Draw_Context *dc, Evas_GL_Gradient *gr, int x, int y, int w, int h, double angle, int spread); Evas_GL_Font_Texture *evas_gl_font_texture_new(Evas_GL_Context *gc, RGBA_Font_Glyph *fg); void evas_gl_font_texture_free(Evas_GL_Font_Texture *ft); diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index 23f887711d..5d98c92d74 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -322,6 +322,10 @@ struct _Evas_Object unsigned char have_clipees : 1; int layer; Evas_Object *clipper; + unsigned char anti_alias; + struct { + int color_space; + } interpolation; } cur, prev; char *name; @@ -467,6 +471,10 @@ struct _Evas_Func int (*context_multiplier_get) (void *data, void *context, int *r, int *g, int *b, int *a); void (*context_cutout_add) (void *data, void *context, int x, int y, int w, int h); void (*context_cutout_clear) (void *data, void *context); + void (*context_anti_alias_set) (void *data, void *context, unsigned char aa); + unsigned char (*context_anti_alias_get) (void *data, void *context); + void (*context_color_interpolation_set) (void *data, void *context, int color_space); + int (*context_color_interpolation_get) (void *data, void *context); void (*rectangle_draw) (void *data, void *context, void *surface, int x, int y, int w, int h); @@ -478,8 +486,14 @@ struct _Evas_Func void *(*gradient_color_add) (void *data, void *context, void *gradient, int r, int g, int b, int a, int distance); void *(*gradient_colors_clear) (void *data, void *context, void *gradient); - - void (*gradient_draw) (void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle); + void (*gradient_free) (void *data, void *gradient); + void (*gradient_fill_set) (void *data, void *gradient, int x, int y, int w, int h); + void (*gradient_type_set) (void *data, void *gradient, char *name); + void (*gradient_type_params_set) (void *data, void *gradient, char *params); + void *(*gradient_geometry_init) (void *data, void *gradient, int spread); + int (*gradient_alpha_get) (void *data, void *gradient, int spread); + void (*gradient_map) (void *data, void *context, void *gradient, int spread); + void (*gradient_draw) (void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h, double angle, int spread); void *(*image_load) (void *data, char *file, char *key, int *error); void *(*image_new_from_data) (void *data, int w, int h, DATA32 *image_data);