diff options
Diffstat (limited to 'android/skin/surface.c')
-rw-r--r-- | android/skin/surface.c | 613 |
1 files changed, 0 insertions, 613 deletions
diff --git a/android/skin/surface.c b/android/skin/surface.c deleted file mode 100644 index 4424bd8..0000000 --- a/android/skin/surface.c +++ /dev/null @@ -1,613 +0,0 @@ -/* Copyright (C) 2007-2008 The Android Open Source Project -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -*/ -#include "android/skin/surface.h" -#include "android/skin/argb.h" -#include <SDL.h> - -#define DEBUG 1 - -#if DEBUG -#include "android/utils/debug.h" -#define D(...) VERBOSE_PRINT(surface,__VA_ARGS__) -#else -#define D(...) ((void)0) -#endif - -struct SkinSurface { - int refcount; - uint32_t* pixels; - SDL_Surface* surface; - SkinSurfaceDoneFunc done_func; - void* done_user; -}; - -static void -skin_surface_free( SkinSurface* s ) -{ - if (s->done_func) { - s->done_func( s->done_user ); - s->done_func = NULL; - } - if (s->surface) { - SDL_FreeSurface(s->surface); - s->surface = NULL; - } - free(s); -} - -extern SkinSurface* -skin_surface_ref( SkinSurface* surface ) -{ - if (surface) - surface->refcount += 1; - return surface; -} - -extern void -skin_surface_unrefp( SkinSurface* *psurface ) -{ - SkinSurface* surf = *psurface; - if (surf) { - if (--surf->refcount <= 0) - skin_surface_free(surf); - *psurface = NULL; - } -} - - -void -skin_surface_set_done( SkinSurface* s, SkinSurfaceDoneFunc done_func, void* done_user ) -{ - s->done_func = done_func; - s->done_user = done_user; -} - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN -# define ARGB32_R_MASK 0xff000000 -# define ARGB32_G_MASK 0x00ff0000 -# define ARGB32_B_MASK 0x0000ff00 -# define ARGB32_A_MASK 0x000000ff -#else -# define ARGB32_R_MASK 0x000000ff -# define ARGB32_G_MASK 0x0000ff00 -# define ARGB32_B_MASK 0x00ff0000 -# define ARGB32_A_MASK 0xff000000 -#endif - -static SDL_Surface* -_sdl_surface_create_rgb( int width, - int height, - int depth, - int flags ) -{ - Uint32 rmask, gmask, bmask, amask; - - if (depth == 8) { - rmask = gmask = bmask = 0; - amask = 0xff; - } else if (depth == 32) { - rmask = ARGB32_R_MASK; - gmask = ARGB32_G_MASK; - bmask = ARGB32_B_MASK; - amask = ARGB32_A_MASK; - } else - return NULL; - - return SDL_CreateRGBSurface( flags, width, height, depth, - rmask, gmask, bmask, amask ); -} - - -static SDL_Surface* -_sdl_surface_create_rgb_from( int width, - int height, - int pitch, - void* pixels, - int depth ) -{ - Uint32 rmask, gmask, bmask, amask; - - if (depth == 8) { - rmask = gmask = bmask = 0; - amask = 0xff; - } else if (depth == 32) { - rmask = ARGB32_R_MASK; - gmask = ARGB32_G_MASK; - bmask = ARGB32_B_MASK; - amask = ARGB32_A_MASK; - } else - return NULL; - - return SDL_CreateRGBSurfaceFrom( pixels, width, height, pitch, depth, - rmask, gmask, bmask, amask ); -} - - -static SkinSurface* -_skin_surface_create( SDL_Surface* surface, - void* pixels ) -{ - SkinSurface* s = malloc(sizeof(*s)); - if (s != NULL) { - s->refcount = 1; - s->pixels = pixels; - s->surface = surface; - s->done_func = NULL; - s->done_user = NULL; - } - else { - SDL_FreeSurface(surface); - free(pixels); - D( "not enough memory to allocate new skin surface !" ); - } - return s; -} - - -SkinSurface* -skin_surface_create_fast( int w, int h ) -{ - SDL_Surface* surface; - - surface = _sdl_surface_create_rgb( w, h, 32, SDL_HWSURFACE ); - if (surface == NULL) { - surface = _sdl_surface_create_rgb( w, h, 32, SDL_SWSURFACE ); - if (surface == NULL) { - D( "could not create fast %dx%d ARGB32 surface: %s", - w, h, SDL_GetError() ); - return NULL; - } - } - return _skin_surface_create( surface, NULL ); -} - - -SkinSurface* -skin_surface_create_slow( int w, int h ) -{ - SDL_Surface* surface; - - surface = _sdl_surface_create_rgb( w, h, 32, SDL_SWSURFACE ); - if (surface == NULL) { - D( "could not create slow %dx%d ARGB32 surface: %s", - w, h, SDL_GetError() ); - return NULL; - } - return _skin_surface_create( surface, NULL ); -} - - -SkinSurface* -skin_surface_create_argb32_from( - int w, - int h, - int pitch, - uint32_t* pixels, - int do_copy ) -{ - SDL_Surface* surface; - uint32_t* pixcopy = NULL; - - if (do_copy) { - size_t size = h*pitch; - pixcopy = malloc( size ); - if (pixcopy == NULL && size > 0) { - D( "not enough memory to create %dx%d ARGB32 surface", - w, h ); - return NULL; - } - memcpy( pixcopy, pixels, size ); - } - - surface = _sdl_surface_create_rgb_from( w, h, pitch, - pixcopy ? pixcopy : pixels, - 32 ); - if (surface == NULL) { - D( "could not create %dx%d slow ARGB32 surface: %s", - w, h, SDL_GetError() ); - return NULL; - } - return _skin_surface_create( surface, pixcopy ); -} - - - - -extern int -skin_surface_lock( SkinSurface* s, SkinSurfacePixels *pix ) -{ - if (!s || !s->surface) { - D( "error: trying to lock stale surface %p", s ); - return -1; - } - if ( SDL_LockSurface( s->surface ) != 0 ) { - D( "could not lock surface %p: %s", s, SDL_GetError() ); - return -1; - } - pix->w = s->surface->w; - pix->h = s->surface->h; - pix->pitch = s->surface->pitch; - pix->pixels = s->surface->pixels; - return 0; -} - -/* unlock a slow surface that was previously locked */ -extern void -skin_surface_unlock( SkinSurface* s ) -{ - if (s && s->surface) - SDL_UnlockSurface( s->surface ); -} - - -#if 0 -static uint32_t -skin_surface_map_argb( SkinSurface* s, uint32_t c ) -{ - if (s && s->surface) { - return SDL_MapRGBA( s->surface->format, - ((c) >> 16) & 255, - ((c) >> 8) & 255, - ((c) & 255), - ((c) >> 24) & 255 ); - } - return 0x00000000; -} -#endif - -typedef struct { - int x; - int y; - int w; - int h; - int sx; - int sy; - - uint8_t* dst_line; - int dst_pitch; - SDL_Surface* dst_lock; - - uint8_t* src_line; - int src_pitch; - SDL_Surface* src_lock; - uint32_t src_color; - -} SkinBlit; - - -static int -skin_blit_init_fill( SkinBlit* blit, - SkinSurface* dst, - SkinRect* dst_rect, - uint32_t color ) -{ - int x = dst_rect->pos.x; - int y = dst_rect->pos.y; - int w = dst_rect->size.w; - int h = dst_rect->size.h; - int delta; - - if (x < 0) { - w += x; - x = 0; - } - delta = (x + w) - dst->surface->w; - if (delta > 0) - w -= delta; - - if (y < 0) { - h += y; - y = 0; - } - delta = (y + h) - dst->surface->h; - if (delta > 0) - h -= delta; - - if (w <= 0 || h <= 0) - return 0; - - blit->x = x; - blit->y = y; - blit->w = w; - blit->h = h; - - if ( !SDL_LockSurface(dst->surface) ) - return 0; - - blit->dst_lock = dst->surface; - blit->dst_pitch = dst->surface->pitch; - blit->dst_line = dst->surface->pixels + y*blit->dst_pitch; - - blit->src_lock = NULL; - blit->src_color = color; - - return 1; -} - -static int -skin_blit_init_blit( SkinBlit* blit, - SkinSurface* dst, - SkinPos* dst_pos, - SkinSurface* src, - SkinRect* src_rect ) -{ - int x = dst_pos->x; - int y = dst_pos->y; - int sx = src_rect->pos.x; - int sy = src_rect->pos.y; - int w = src_rect->size.w; - int h = src_rect->size.h; - int delta; - - if (x < 0) { - w += x; - sx -= x; - x = 0; - } - if (sx < 0) { - w += sx; - x -= sx; - sx = 0; - } - - delta = (x + w) - dst->surface->w; - if (delta > 0) - w -= delta; - - delta = (sx + w) - src->surface->w; - if (delta > 0) - w -= delta; - - if (y < 0) { - h += y; - sy += y; - y = 0; - } - if (sy < 0) { - h += sy; - y -= sy; - sy = 0; - } - delta = (y + h) - dst->surface->h; - if (delta > 0) - h -= delta; - - delta = (sy + h) - src->surface->h; - - if (w <= 0 || h <= 0) - return 0; - - blit->x = x; - blit->y = y; - blit->w = w; - blit->h = h; - - blit->sx = sx; - blit->sy = sy; - - if ( !SDL_LockSurface(dst->surface) ) - return 0; - - blit->dst_lock = dst->surface; - blit->dst_pitch = dst->surface->pitch; - blit->dst_line = (uint8_t*) dst->surface->pixels + y*blit->dst_pitch; - - if ( !SDL_LockSurface(src->surface) ) { - SDL_UnlockSurface(dst->surface); - return 0; - } - - blit->src_lock = src->surface; - blit->src_pitch = src->surface->pitch; - blit->src_line = (uint8_t*) src->surface->pixels + sy*blit->src_pitch; - - return 1; -} - -static void -skin_blit_done( SkinBlit* blit ) -{ - if (blit->src_lock) - SDL_UnlockSurface( blit->src_lock ); - if (blit->dst_lock) - SDL_UnlockSurface( blit->dst_lock ); - ARGB_DONE; -} - -typedef void (*SkinLineFillFunc)( uint32_t* dst, uint32_t color, int len ); -typedef void (*SkinLineBlitFunc)( uint32_t* dst, const uint32_t* src, int len ); - -static void -skin_line_fill_copy( uint32_t* dst, uint32_t color, int len ) -{ - uint32_t* end = dst + len; - - while (dst + 4 <= end) { - dst[0] = dst[1] = dst[2] = dst[3] = color; - dst += 4; - } - while (dst < end) { - dst[0] = color; - dst += 1; - } -} - -static void -skin_line_fill_srcover( uint32_t* dst, uint32_t color, int len ) -{ - uint32_t* end = dst + len; - uint32_t alpha = (color >> 24); - - if (alpha == 255) - { - skin_line_fill_copy(dst, color, len); - } - else - { - ARGB_DECL(src_c); - ARGB_DECL_ZERO(); - - alpha = 255 - alpha; - alpha += (alpha >> 7); - - ARGB_UNPACK(src_c,color); - - for ( ; dst < end; dst++ ) - { - ARGB_DECL(dst_c); - - ARGB_READ(dst_c,dst); - ARGB_MULSHIFT(dst_c,dst_c,alpha,8); - ARGB_ADD(dst_c,src_c); - ARGB_WRITE(dst_c,dst); - } - } -} - -static void -skin_line_fill_dstover( uint32_t* dst, uint32_t color, int len ) -{ - uint32_t* end = dst + len; - ARGB_DECL(src_c); - ARGB_DECL_ZERO(); - - ARGB_UNPACK(src_c,color); - - for ( ; dst < end; dst++ ) - { - ARGB_DECL(dst_c); - ARGB_DECL(val); - - uint32_t alpha; - - ARGB_READ(dst_c,dst); - alpha = 256 - (dst[0] >> 24); - ARGB_MULSHIFT(val,src_c,alpha,8); - ARGB_ADD(val,dst_c); - ARGB_WRITE(val,dst); - } -} - -extern void -skin_surface_fill( SkinSurface* dst, - SkinRect* rect, - uint32_t argb_premul, - SkinBlitOp blitop ) -{ - SkinLineFillFunc fill; - SkinBlit blit[1]; - - switch (blitop) { - case SKIN_BLIT_COPY: fill = skin_line_fill_copy; break; - case SKIN_BLIT_SRCOVER: fill = skin_line_fill_srcover; break; - case SKIN_BLIT_DSTOVER: fill = skin_line_fill_dstover; break; - default: return; - } - - if ( skin_blit_init_fill( blit, dst, rect, argb_premul ) ) { - uint8_t* line = blit->dst_line; - int pitch = blit->dst_pitch; - uint8_t* end = line + pitch*blit->h; - - for ( ; line != end; line += pitch ) - fill( (uint32_t*)line + blit->x, argb_premul, blit->w ); - } -} - - -static void -skin_line_blit_copy( uint32_t* dst, const uint32_t* src, int len ) -{ - memcpy( (char*)dst, (const char*)src, len*4 ); -} - - - -static void -skin_line_blit_srcover( uint32_t* dst, const uint32_t* src, int len ) -{ - uint32_t* end = dst + len; - ARGB_DECL_ZERO(); - - for ( ; dst < end; dst++ ) { - ARGB_DECL(s); - ARGB_DECL(d); - ARGB_DECL(v); - uint32_t alpha; - - ARGB_READ(s,src); - alpha = (src[0] >> 24); - if (alpha > 0) { - ARGB_READ(d,dst); - alpha = 256 - alpha; - ARGB_MULSHIFT(v,d,alpha,8); - ARGB_ADD(v,d); - ARGB_WRITE(v,dst); - } - } -} - -static void -skin_line_blit_dstover( uint32_t* dst, const uint32_t* src, int len ) -{ - uint32_t* end = dst + len; - ARGB_DECL_ZERO(); - - for ( ; dst < end; dst++ ) { - ARGB_DECL(s); - ARGB_DECL(d); - ARGB_DECL(v); - uint32_t alpha; - - ARGB_READ(d,dst); - alpha = (dst[0] >> 24); - if (alpha < 255) { - ARGB_READ(s,src); - alpha = 256 - alpha; - ARGB_MULSHIFT(v,s,alpha,8); - ARGB_ADD(v,s); - ARGB_WRITE(v,dst); - } - } -} - - -extern void -skin_surface_blit( SkinSurface* dst, - SkinPos* dst_pos, - SkinSurface* src, - SkinRect* src_rect, - SkinBlitOp blitop ) -{ - SkinLineBlitFunc func; - SkinBlit blit[1]; - - switch (blitop) { - case SKIN_BLIT_COPY: func = skin_line_blit_copy; break; - case SKIN_BLIT_SRCOVER: func = skin_line_blit_srcover; break; - case SKIN_BLIT_DSTOVER: func = skin_line_blit_dstover; break; - default: return; - } - - if ( skin_blit_init_blit( blit, dst, dst_pos, src, src_rect ) ) { - uint8_t* line = blit->dst_line; - uint8_t* sline = blit->src_line; - int pitch = blit->dst_pitch; - int spitch = blit->src_pitch; - uint8_t* end = line + pitch*blit->h; - - for ( ; line != end; line += pitch, sline += spitch ) - func( (uint32_t*)line + blit->x, (uint32_t*)sline + blit->sx, blit->w ); - - skin_blit_done(blit); - } -} |