@ -3998,143 +3998,401 @@ evas_object_image_was_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
return obj - > prev . opaque ;
}
static inline Eina_Bool
_pixel_alpha_get ( RGBA_Image * im , int x , int y , DATA8 * alpha ,
int src_region_x , int src_region_y , int src_region_w , int src_region_h ,
int dst_region_x , int dst_region_y , int dst_region_w , int dst_region_h )
{
int px , py , dx , dy , sx , sy , src_w , src_h ;
double scale_w , scale_h ;
if ( ( dst_region_x > x ) | | ( x > = ( dst_region_x + dst_region_w ) ) | |
( dst_region_y > y ) | | ( y > = ( dst_region_y + dst_region_h ) ) )
{
* alpha = 0 ;
return EINA_FALSE ;
}
src_w = im - > cache_entry . w ;
src_h = im - > cache_entry . h ;
if ( ( src_w = = 0 ) | | ( src_h = = 0 ) )
{
* alpha = 0 ;
return EINA_TRUE ;
}
EINA_SAFETY_ON_TRUE_GOTO ( src_region_x < 0 , error_oob ) ;
EINA_SAFETY_ON_TRUE_GOTO ( src_region_y < 0 , error_oob ) ;
EINA_SAFETY_ON_TRUE_GOTO ( src_region_x + src_region_w > src_w , error_oob ) ;
EINA_SAFETY_ON_TRUE_GOTO ( src_region_y + src_region_h > src_h , error_oob ) ;
scale_w = ( double ) dst_region_w / ( double ) src_region_w ;
scale_h = ( double ) dst_region_h / ( double ) src_region_h ;
/* point at destination */
dx = x - dst_region_x ;
dy = y - dst_region_y ;
/* point at source */
sx = dx / scale_w ;
sy = dy / scale_h ;
/* pixel point (translated) */
px = src_region_x + sx ;
py = src_region_y + sy ;
EINA_SAFETY_ON_TRUE_GOTO ( px > = src_w , error_oob ) ;
EINA_SAFETY_ON_TRUE_GOTO ( py > = src_h , error_oob ) ;
switch ( im - > cache_entry . space )
{
case EVAS_COLORSPACE_ARGB8888 :
{
DATA32 * pixel = im - > image . data ;
pixel + = ( ( py * src_w ) + px ) ;
* alpha = ( ( * pixel ) > > 24 ) & 0xff ;
}
break ;
default :
ERR ( " Colorspace %d not supported. " , im - > cache_entry . space ) ;
* alpha = 0 ;
}
return EINA_TRUE ;
error_oob :
ERR ( " Invalid region src=(%d, %d, %d, %d), dst=(%d, %d, %d, %d), image=%dx%d " ,
src_region_x , src_region_y , src_region_w , src_region_h ,
dst_region_x , dst_region_y , dst_region_w , dst_region_h ,
src_w , src_h ) ;
* alpha = 0 ;
return EINA_TRUE ;
}
static int
evas_object_image_is_inside ( Evas_Object * eo_obj , Evas_Object_Protected_Data * obj , Evas_Coord x , Evas_Coord y )
evas_object_image_is_inside ( Evas_Object * eo_obj , Evas_Object_Protected_Data * obj , Evas_Coord p x, Evas_Coord p y)
{
Evas_Object_Image * o = eo_data_get ( eo_obj , MY_CLASS ) ;
DATA32 * data ;
int w , h , stride , iw , ih ;
int a ;
int return_value ;
x - = obj - > cur . cache . clip . x ;
y - = obj - > cur . cache . clip . y ;
w = obj - > cur . cache . clip . w ;
h = obj - > cur . cache . clip . h ;
iw = o - > cur . image . w ;
ih = o - > cur . image . h ;
if ( ( x < 0 ) | | ( y < 0 ) | | ( x > = w ) | | ( y > = h ) ) return 0 ;
if ( ! o - > cur . has_alpha ) return 1 ;
// FIXME: proxy needs to be honored
if ( obj - > cur . map )
int imagew , imageh , uvw , uvh ;
void * pixels ;
int is_inside = 0 ;
/* the following code is similar to evas_object_image_render(), but doesn't
* draw , just get the pixels so we can check the transparency .
*/
Evas_Object_Protected_Data * source =
( o - > cur . source ?
eo_data_get ( o - > cur . source , EVAS_OBJ_CLASS ) :
NULL ) ;
if ( ! o - > cur . source )
{
pixels = o - > engine_data ;
imagew = o - > cur . image . w ;
imageh = o - > cur . image . h ;
uvw = imagew ;
uvh = imageh ;
}
else if ( source - > proxy . surface & & ! source - > proxy . redraw )
{
x = obj - > cur . map - > mx ;
y = obj - > cur . map - > my ;
pixels = source - > proxy . surface ;
imagew = source - > proxy . w ;
imageh = source - > proxy . h ;
uvw = imagew ;
uvh = imageh ;
}
else if ( source - > type = = o_type & &
( ( Evas_Object_Image * ) eo_data_get ( o - > cur . source , MY_CLASS ) ) - > engine_data )
{
Evas_Object_Image * oi ;
oi = eo_data_get ( o - > cur . source , MY_CLASS ) ;
pixels = oi - > engine_data ;
imagew = oi - > cur . image . w ;
imageh = oi - > cur . image . h ;
uvw = source - > cur . geometry . w ;
uvh = source - > cur . geometry . h ;
}
else
{
int bl , br , bt , bb , bsl , bsr , bst , bsb ;
o - > proxyrendering = EINA_TRUE ;
_proxy_subrender ( obj - > layer - > evas - > evas , o - > cur . source , EINA_FALSE ) ;
pixels = source - > proxy . surface ;
imagew = source - > proxy . w ;
imageh = source - > proxy . h ;
uvw = imagew ;
uvh = imageh ;
o - > proxyrendering = EINA_FALSE ;
}
bl = o - > cur . border . l ;
br = o - > cur . border . r ;
bt = o - > cur . border . t ;
bb = o - > cur . border . b ;
if ( ( bl + br ) > iw )
{
bl = iw / 2 ;
br = iw - bl ;
}
if ( ( bl + br ) > iw )
{
bl = iw / 2 ;
br = iw - bl ;
}
if ( ( bt + bb ) > ih )
{
bt = ih / 2 ;
bb = ih - bt ;
}
if ( ( bt + bb ) > ih )
if ( pixels )
{
Evas_Coord idw , idh , idx , idy ;
int ix , iy , iw , ih ;
/* TODO: not handling o->dirty_pixels && o->func.get_pixels,
* should we handle it now or believe they were done in the last render ?
*/
if ( o - > dirty_pixels )
{
bt = ih / 2 ;
bb = ih - bt ;
if ( o - > func . get_pixels )
{
ERR ( " dirty_pixels && get_pixels not supported " ) ;
}
}
if ( o - > cur . border . scale ! = 1.0 )
/* TODO: not handling map, need to apply map to point */
if ( ( obj - > cur . map ) & & ( obj - > cur . map - > count > 3 ) & & ( obj - > cur . usemap ) )
{
bsl = ( ( double ) bl * o - > cur . border . scale ) ;
bsr = ( ( double ) br * o - > cur . border . scale ) ;
bst = ( ( double ) bt * o - > cur . border . scale ) ;
bsb = ( ( double ) bb * o - > cur . border . scale ) ;
evas_object_map_update ( eo_obj , 0 , 0 , imagew , imageh , uvw , uvh ) ;
ERR ( " map not supported " ) ;
}
else
{
bsl = bl ; bsr = br ; bst = bt ; bsb = bb ;
}
w = o - > cur . fill . w ;
h = o - > cur . fill . h ;
x - = o - > cur . fill . x ;
y - = o - > cur . fill . y ;
x % = w ;
y % = h ;
if ( x < 0 ) x + = w ;
if ( y < 0 ) y + = h ;
RGBA_Image * im ;
DATA32 * data = NULL ;
int err = 0 ;
if ( o - > cur . border . fill ! = EVAS_BORDER_FILL_DEFAULT )
{
if ( ( x > bsl ) & & ( x < ( w - bsr ) ) & &
( y > bst ) & & ( y < ( h - bsb ) ) )
im = obj - > layer - > evas - > engine . func - > image_data_get
( obj - > layer - > evas - > engine . data . output , pixels , 0 , & data , & err ) ;
if ( ( ! im ) | | ( ! data ) | | ( err ) )
{
if ( o - > cur . border . fill = = EVAS_BORDER_FILL_SOLID ) return 1 ;
return 0 ;
ERR ( " Couldn't get image pixels RGBA_Image %p: im=%p, data=%p, err=%d " , pixels , im , data , err ) ;
goto end ;
}
}
if ( x < bsl ) x = ( x * bl ) / bsl ;
else if ( x > ( w - bsr ) ) x = iw - ( ( ( w - x ) * br ) / bsr ) ;
else if ( ( bsl + bsr ) < w ) x = bl + ( ( ( x - bsl ) * ( iw - bl - br ) ) / ( w - bsl - bsr ) ) ;
else return 1 ;
if ( y < bst ) y = ( y * bt ) / bst ;
else if ( y > ( h - bsb ) ) y = ih - ( ( ( h - y ) * bb ) / bsb ) ;
else if ( ( bst + bsb ) < h ) y = bt + ( ( ( y - bst ) * ( ih - bt - bb ) ) / ( h - bst - bsb ) ) ;
else return 1 ;
}
if ( x < 0 ) x = 0 ;
if ( y < 0 ) y = 0 ;
if ( x > = iw ) x = iw - 1 ;
if ( y > = ih ) y = ih - 1 ;
stride = o - > cur . image . stride ;
idx = evas_object_image_figure_x_fill ( eo_obj , obj , o - > cur . fill . x , o - > cur . fill . w , & idw ) ;
idy = evas_object_image_figure_y_fill ( eo_obj , obj , o - > cur . fill . y , o - > cur . fill . h , & idh ) ;
if ( idw < 1 ) idw = 1 ;
if ( idh < 1 ) idh = 1 ;
if ( idx > 0 ) idx - = idw ;
if ( idy > 0 ) idy - = idh ;
while ( ( int ) idx < obj - > cur . geometry . w )
{
Evas_Coord ydy ;
int dobreak_w = 0 ;
ydy = idy ;
ix = idx ;
if ( ( o - > cur . fill . w = = obj - > cur . geometry . w ) & &
( o - > cur . fill . x = = 0 ) )
{
dobreak_w = 1 ;
iw = obj - > cur . geometry . w ;
}
else
iw = ( ( int ) ( idx + idw ) ) - ix ;
while ( ( int ) idy < obj - > cur . geometry . h )
{
int dobreak_h = 0 ;
o - > engine_data = obj - > layer - > evas - > engine . func - > image_data_get
( obj - > layer - > evas - > engine . data . output ,
o - > engine_data ,
0 ,
& data ,
& o - > load_error ) ;
iy = idy ;
if ( ( o - > cur . fill . h = = obj - > cur . geometry . h ) & &
( o - > cur . fill . y = = 0 ) )
{
ih = obj - > cur . geometry . h ;
dobreak_h = 1 ;
}
else
ih = ( ( int ) ( idy + idh ) ) - iy ;
if ( ( o - > cur . border . l = = 0 ) & &
( o - > cur . border . r = = 0 ) & &
( o - > cur . border . t = = 0 ) & &
( o - > cur . border . b = = 0 ) & &
( o - > cur . border . fill ! = 0 ) )
{
/* NOTE: render handles cserve2 here,
* we don ' t need to
*/
{
DATA8 alpha = 0 ;
if ( _pixel_alpha_get ( pixels , px , py , & alpha , 0 , 0 , imagew , imageh , obj - > cur . geometry . x + ix , obj - > cur . geometry . y + iy , iw , ih ) )
{
is_inside = alpha > 0 ;
dobreak_h = 1 ;
dobreak_w = 1 ;
break ;
}
}
}
else
{
int inx , iny , inw , inh , outx , outy , outw , outh ;
int bl , br , bt , bb , bsl , bsr , bst , bsb ;
int imw , imh , ox , oy ;
DATA8 alpha = 0 ;
if ( ! data )
{
return_value = 0 ;
goto finish ;
}
ox = obj - > cur . geometry . x + ix ;
oy = obj - > cur . geometry . y + iy ;
imw = imagew ;
imh = imageh ;
bl = o - > cur . border . l ;
br = o - > cur . border . r ;
bt = o - > cur . border . t ;
bb = o - > cur . border . b ;
if ( ( bl + br ) > iw )
{
bl = iw / 2 ;
br = iw - bl ;
}
if ( ( bl + br ) > imw )
{
bl = imw / 2 ;
br = imw - bl ;
}
if ( ( bt + bb ) > ih )
{
bt = ih / 2 ;
bb = ih - bt ;
}
if ( ( bt + bb ) > imh )
{
bt = imh / 2 ;
bb = imh - bt ;
}
if ( o - > cur . border . scale ! = 1.0 )
{
bsl = ( ( double ) bl * o - > cur . border . scale ) ;
bsr = ( ( double ) br * o - > cur . border . scale ) ;
bst = ( ( double ) bt * o - > cur . border . scale ) ;
bsb = ( ( double ) bb * o - > cur . border . scale ) ;
}
else
{
bsl = bl ; bsr = br ; bst = bt ; bsb = bb ;
}
// #--
// |
inx = 0 ; iny = 0 ;
inw = bl ; inh = bt ;
outx = ox ; outy = oy ;
outw = bsl ; outh = bst ;
if ( _pixel_alpha_get ( pixels , px , py , & alpha , inx , iny , inw , inh , outx , outy , outw , outh ) )
{
is_inside = alpha > 0 ;
dobreak_h = 1 ;
dobreak_w = 1 ;
break ;
}
switch ( o - > cur . cspace )
{
case EVAS_COLORSPACE_ARGB8888 :
data = ( ( DATA32 * ) ( data ) + ( ( y * ( stride > > 2 ) ) + x ) ) ;
a = ( * ( ( DATA32 * ) ( data ) ) > > 24 ) & 0xff ;
break ;
case EVAS_COLORSPACE_RGB565_A5P :
data = ( void * ) ( ( DATA16 * ) ( data ) + ( h * ( stride > > 1 ) ) ) ;
data = ( void * ) ( ( DATA8 * ) ( data ) + ( ( y * ( stride > > 1 ) ) + x ) ) ;
a = ( * ( ( DATA8 * ) ( data ) ) ) & 0x1f ;
break ;
default :
return_value = 1 ;
goto finish ;
break ;
// .##
// |
inx = bl ; iny = 0 ;
inw = imw - bl - br ; inh = bt ;
outx = ox + bsl ; outy = oy ;
outw = iw - bsl - bsr ; outh = bst ;
if ( _pixel_alpha_get ( pixels , px , py , & alpha , inx , iny , inw , inh , outx , outy , outw , outh ) )
{
is_inside = alpha > 0 ;
dobreak_h = 1 ;
dobreak_w = 1 ;
break ;
}
// --#
// |
inx = imw - br ; iny = 0 ;
inw = br ; inh = bt ;
outx = ox + iw - bsr ; outy = oy ;
outw = bsr ; outh = bst ;
if ( _pixel_alpha_get ( pixels , px , py , & alpha , inx , iny , inw , inh , outx , outy , outw , outh ) )
{
is_inside = alpha > 0 ;
dobreak_h = 1 ;
dobreak_w = 1 ;
break ;
}
// .--
// #
inx = 0 ; iny = bt ;
inw = bl ; inh = imh - bt - bb ;
outx = ox ; outy = oy + bst ;
outw = bsl ; outh = ih - bst - bsb ;
if ( _pixel_alpha_get ( pixels , px , py , & alpha , inx , iny , inw , inh , outx , outy , outw , outh ) )
{
is_inside = alpha > 0 ;
dobreak_h = 1 ;
dobreak_w = 1 ;
break ;
}
// .--.
// |##|
if ( o - > cur . border . fill > EVAS_BORDER_FILL_NONE )
{
inx = bl ; iny = bt ;
inw = imw - bl - br ; inh = imh - bt - bb ;
outx = ox + bsl ; outy = oy + bst ;
outw = iw - bsl - bsr ; outh = ih - bst - bsb ;
if ( _pixel_alpha_get ( pixels , px , py , & alpha , inx , iny , inw , inh , outx , outy , outw , outh ) )
{
is_inside = alpha > 0 ;
dobreak_h = 1 ;
dobreak_w = 1 ;
break ;
}
}
// --.
// #
inx = imw - br ; iny = bt ;
inw = br ; inh = imh - bt - bb ;
outx = ox + iw - bsr ; outy = oy + bst ;
outw = bsr ; outh = ih - bst - bsb ;
if ( _pixel_alpha_get ( pixels , px , py , & alpha , inx , iny , inw , inh , outx , outy , outw , outh ) )
{
is_inside = alpha > 0 ;
dobreak_h = 1 ;
dobreak_w = 1 ;
break ;
}
// |
// #--
inx = 0 ; iny = imh - bb ;
inw = bl ; inh = bb ;
outx = ox ; outy = oy + ih - bsb ;
outw = bsl ; outh = bsb ;
if ( _pixel_alpha_get ( pixels , px , py , & alpha , inx , iny , inw , inh , outx , outy , outw , outh ) )
{
is_inside = alpha > 0 ;
dobreak_h = 1 ;
dobreak_w = 1 ;
break ;
}
// |
// .##
inx = bl ; iny = imh - bb ;
inw = imw - bl - br ; inh = bb ;
outx = ox + bsl ; outy = oy + ih - bsb ;
outw = iw - bsl - bsr ; outh = bsb ;
if ( _pixel_alpha_get ( pixels , px , py , & alpha , inx , iny , inw , inh , outx , outy , outw , outh ) )
{
is_inside = alpha > 0 ;
dobreak_h = 1 ;
dobreak_w = 1 ;
break ;
}
// |
// --#
inx = imw - br ; iny = imh - bb ;
inw = br ; inh = bb ;
outx = ox + iw - bsr ; outy = oy + ih - bsb ;
outw = bsr ; outh = bsb ;
if ( _pixel_alpha_get ( pixels , px , py , & alpha , inx , iny , inw , inh , outx , outy , outw , outh ) )
{
is_inside = alpha > 0 ;
dobreak_h = 1 ;
dobreak_w = 1 ;
break ;
}
}
idy + = idh ;
if ( dobreak_h ) break ;
}
idx + = idw ;
idy = ydy ;
if ( dobreak_w ) break ;
}
}
}
return_value = ( a ! = 0 ) ;
finish :
return return_value ;
end :
return is_inside ;
}
static int