supporting StampFill for 32bpp images; optional support for alpha fonts (via 32bpp)

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1977 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2005-11-10 00:33:29 +00:00
parent 3a3cdf61fd
commit 9b7f3c46c7
5 changed files with 201 additions and 34 deletions
+64 -25
View File
@@ -113,6 +113,8 @@ processFontChar (FRAMEPTR FramePtr, SDL_Surface *surf, int charInd)
Uint32 p; Uint32 p;
SDL_Color colors[256]; SDL_Color colors[256];
SDL_Surface *new_surf; SDL_Surface *new_surf;
SDL_PixelFormat* srcfmt = surf->format;
SDL_PixelFormat* dstfmt;
GetPixelFn getpix; GetPixelFn getpix;
PutPixelFn putpix; PutPixelFn putpix;
@@ -120,13 +122,21 @@ processFontChar (FRAMEPTR FramePtr, SDL_Surface *surf, int charInd)
INDEX_SET (FramePtr->TypeIndexAndFlags, charInd); INDEX_SET (FramePtr->TypeIndexAndFlags, charInd);
// XXX: Is this still relevant? // XXX: Is this still relevant?
//#define ALPHA_FONTS
SDL_LockSurface (surf); SDL_LockSurface (surf);
// convert 32-bit png font to indexed #if defined(ALPHA_FONTS)
// convert png font to truecolor + alpha
new_surf = TFB_DrawCanvas_New_TrueColor (surf->w, surf->h, TRUE);
#else // indexed fonts
// convert 32-bit png font to indexed
new_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, surf->w, surf->h, new_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, surf->w, surf->h,
8, 0, 0, 0, 0); 8, 0, 0, 0, 0);
#endif
dstfmt = new_surf->format;
getpix = getpixel_for (surf); getpix = getpixel_for (surf);
putpix = putpixel_for (new_surf); putpix = putpixel_for (new_surf);
@@ -135,15 +145,29 @@ processFontChar (FRAMEPTR FramePtr, SDL_Surface *surf, int charInd)
for (x = 0; x < surf->w; ++x) for (x = 0; x < surf->w; ++x)
{ {
p = getpix (surf, x, y); p = getpix (surf, x, y);
SDL_GetRGBA (p, surf->format, &r, &g, &b, &a); SDL_GetRGBA (p, srcfmt, &r, &g, &b, &a);
#if defined(ALPHA_FONTS)
if (!srcfmt->Amask)
{ // produce alpha from intensity (Y component)
// using a fast approximation
// contributions to Y are: R=2, G=4, B=1
a = (((int)r << 1) + ((int)g << 2) + b) / 7;
}
// normalize font pixel
putpix (new_surf, x, y, SDL_MapRGBA (dstfmt,
255, 255, 255, a));
#else // indexed fonts
if (r == 0 && g == 0 && b == 0) if (r == 0 && g == 0 && b == 0)
putpix (new_surf, x, y, 0); putpix (new_surf, x, y, 0);
else else
putpix (new_surf, x, y, 1); putpix (new_surf, x, y, 1);
#endif
} }
} }
#if !defined(ALPHA_FONTS)
colors[0].r = 0; colors[0].r = 0;
colors[0].g = 0; colors[0].g = 0;
colors[0].b = 0; colors[0].b = 0;
@@ -156,6 +180,7 @@ processFontChar (FRAMEPTR FramePtr, SDL_Surface *surf, int charInd)
SDL_SetColors (new_surf, colors, 0, 256); SDL_SetColors (new_surf, colors, 0, 256);
SDL_SetColorKey (new_surf, SDL_SRCCOLORKEY, 0); SDL_SetColorKey (new_surf, SDL_SRCCOLORKEY, 0);
#endif
SDL_UnlockSurface (surf); SDL_UnlockSurface (surf);
SDL_FreeSurface (surf); SDL_FreeSurface (surf);
@@ -355,6 +380,7 @@ FRAMEPTR Build_Font_Effect (FRAMEPTR FramePtr, Uint32 from, Uint32 to, BYTE type
int x, y; int x, y;
int width, height; int width, height;
Uint32 color, clear; Uint32 color, clear;
Uint32 srcmask, threshold;
BYTE from_r, from_g, from_b, from_a; BYTE from_r, from_g, from_b, from_a;
BYTE to_r, to_g, to_b, to_a; BYTE to_r, to_g, to_b, to_a;
TFB_Image *tfbImg, *tfbOrigImg; TFB_Image *tfbImg, *tfbOrigImg;
@@ -362,14 +388,17 @@ FRAMEPTR Build_Font_Effect (FRAMEPTR FramePtr, Uint32 from, Uint32 to, BYTE type
PutPixelFn putpix; PutPixelFn putpix;
GetPixelFn getpix; GetPixelFn getpix;
width = GetFrameWidth (FramePtr);
height = GetFrameHeight (FramePtr);
NewFrame = CaptureDrawable (CreateDrawable ((CREATE_FLAGS)RAM_DRAWABLE,
(SIZE)width, (SIZE)height, 1));
tfbOrigImg = FramePtr->image; tfbOrigImg = FramePtr->image;
OrigImg = (SDL_Surface *)tfbOrigImg->NormalImg; OrigImg = (SDL_Surface *)tfbOrigImg->NormalImg;
SDL_LockSurface (OrigImg); SDL_LockSurface (OrigImg);
width = OrigImg->w;
height = OrigImg->h;
NewFrame = CaptureDrawable (CreateDrawable ((CREATE_FLAGS)RAM_DRAWABLE,
(SIZE)width, (SIZE)height, 1));
NewFrame->Bounds = FramePtr->Bounds;
NewFrame->HotSpot = FramePtr->HotSpot;
tfbImg = NewFrame->image; tfbImg = NewFrame->image;
img = (SDL_Surface *)tfbImg->NormalImg; img = (SDL_Surface *)tfbImg->NormalImg;
SDL_LockSurface (img); SDL_LockSurface (img);
@@ -389,19 +418,24 @@ FRAMEPTR Build_Font_Effect (FRAMEPTR FramePtr, Uint32 from, Uint32 to, BYTE type
clear = SDL_MapRGBA (img->format, 0, 0, 0, 0); clear = SDL_MapRGBA (img->format, 0, 0, 0, 0);
TFB_DrawCanvas_SetTransparentColor (img, 0, 0, 0, FALSE); TFB_DrawCanvas_SetTransparentColor (img, 0, 0, 0, FALSE);
for (y = 0; y < 2; y++) #if defined(ALPHA_FONTS)
for (x = 0; x < width; x++) srcmask = OrigImg->format->Amask;
putpix (img, x, y, clear); threshold = (srcmask >> 1) & srcmask;
#else // indexed fonts
srcmask = 255;
threshold = 0; // any index != 0
#endif
width--;
if (type == GRADIENT_EFFECT) if (type == GRADIENT_EFFECT)
{ {
int clrstep_r, clrstep_g, clrstep_b, clrstep_a; int clrstep_r, clrstep_g, clrstep_b, clrstep_a;
clrstep_r = (to_r - from_r) / (height - 5);
clrstep_g = (to_g - from_g) / (height - 5); clrstep_r = (to_r - from_r) / (height - 1);
clrstep_b = (to_b - from_b) / (height - 5); clrstep_g = (to_g - from_g) / (height - 1);
clrstep_a = (to_a - from_a) / (height - 5); clrstep_b = (to_b - from_b) / (height - 1);
for (; y < height - 1; y++) clrstep_a = (to_a - from_a) / (height - 1);
for (y = 0; y < height; y++)
{ {
color = SDL_MapRGBA (img->format, from_r, from_g, from_b, from_a); color = SDL_MapRGBA (img->format, from_r, from_g, from_b, from_a);
from_r += clrstep_r; from_r += clrstep_r;
@@ -409,41 +443,46 @@ FRAMEPTR Build_Font_Effect (FRAMEPTR FramePtr, Uint32 from, Uint32 to, BYTE type
from_b += clrstep_b; from_b += clrstep_b;
from_a += clrstep_a; from_a += clrstep_a;
for (x = 0; x < width; x++) for (x = 0; x < width; x++)
if (getpix (OrigImg, x, y) == 1) {
Uint32 p = getpix (OrigImg, x, y);
if ((p & srcmask) > threshold)
putpix (img, x, y, color); putpix (img, x, y, color);
else else
putpix (img, x, y, clear); putpix (img, x, y, clear);
putpix (img, x, y, clear); }
} }
} }
else if (type == ALTERNATE_EFFECT) else if (type == ALTERNATE_EFFECT)
{ {
Uint32 color1, color2; Uint32 color1, color2;
color1 = SDL_MapRGBA (img->format, from_r, from_g, from_b, from_a); color1 = SDL_MapRGBA (img->format, from_r, from_g, from_b, from_a);
color2 = SDL_MapRGBA (img->format, to_r, to_g, to_b, to_a); color2 = SDL_MapRGBA (img->format, to_r, to_g, to_b, to_a);
for (; y < height - 1; y++)
for (y = 0; y < height; y++)
{ {
for (x = 0; x < width; x++) for (x = 0; x < width; x++)
if (getpix (OrigImg, x, y) == 1) {
Uint32 p = getpix (OrigImg, x, y);
if ((p & srcmask) > threshold)
{ {
color = ((y & 0x01) ^ (x & 0x01)) ? color2 : color1; color = ((y & 0x01) ^ (x & 0x01)) ? color2 : color1;
putpix (img, x, y, color); putpix (img, x, y, color);
} }
else else
putpix (img, x, y, clear); putpix (img, x, y, clear);
putpix (img, x, y, clear); }
} }
} }
width++;
for (x = 0; x < width; x++)
putpix (img, x, y, clear);
SDL_UnlockSurface (img); SDL_UnlockSurface (img);
SDL_UnlockSurface (OrigImg); SDL_UnlockSurface (OrigImg);
NewFrame->HotSpot = FramePtr->HotSpot;
return (NewFrame);
return (NewFrame);
} }
// Generate a pixel (in the correct format to be applied to FramePtr) from the // Generate a pixel (in the correct format to be applied to FramePtr) from the
// r,g,b,a values supplied // r,g,b,a values supplied
Uint32 frame_mapRGBA (FRAMEPTR FramePtr,Uint8 r, Uint8 g, Uint8 b, Uint8 a) Uint32 frame_mapRGBA (FRAMEPTR FramePtr,Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+130 -9
View File
@@ -103,6 +103,83 @@ TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale, TFB_Palette *pale
UnlockMutex (img->mutex); UnlockMutex (img->mutex);
} }
void
TFB_DrawCanvas_Fill (TFB_Canvas source, int width, int height,
Uint32 fillcolor, TFB_Canvas target)
{
SDL_Surface *src = (SDL_Surface *)source;
SDL_Surface *dst = (SDL_Surface *)target;
const SDL_PixelFormat *srcfmt = src->format;
SDL_PixelFormat *dstfmt = dst->format;
const int bpp = dstfmt->BytesPerPixel;
const int sp = src->pitch, dp = dst->pitch;
const int slen = sp / bpp, dlen = dp / bpp;
const int dsrc = slen - width, ddst = dlen - width;
Uint32 *src_p = (Uint32 *)src->pixels;
Uint32 *dst_p = (Uint32 *)dst->pixels;
int x, y;
if (srcfmt->BytesPerPixel != 4 || dstfmt->BytesPerPixel != 4)
{
fprintf (stderr, "TFB_DrawCanvas_Fill: Unsupported surface formats: "
"%d bytes/pixel source, %d bytes/pixel destination\n",
(int)srcfmt->BytesPerPixel, (int)dstfmt->BytesPerPixel);
return;
}
if ((src->flags & SDL_SRCALPHA) && srcfmt->Amask)
{ // alpha-based fill
Uint32 amask = srcfmt->Amask;
for (y = 0; y < height; ++y)
{
for (x = 0; x < width; ++x, ++src_p, ++dst_p)
{
*dst_p = (*src_p & amask) | fillcolor;
}
dst_p += ddst;
src_p += dsrc;
}
}
else if (src->flags & SDL_SRCCOLORKEY)
{ // colorkey-based fill
Uint32 srckey = srcfmt->colorkey;
Uint32 dstkey = srckey;
Uint32 notmask = ~srcfmt->Amask;
if (src->flags & SDL_RLEACCEL)
{
fprintf (stderr, "TFB_DrawCanvas_Fill: Unsupported source "
"surface format: SDL_RLEACCEL\n");
return;
}
if (dstkey == fillcolor)
{ // color collision, must switch colorkey
if (dstkey != 0)
// new colorkey is black (0,0,0)
dstkey = 0;
else
// new colorkey is grey (1/2,1/2,1/2)
dstkey = SDL_MapRGB (dstfmt, 127, 127, 127);
}
SDL_SetColorKey (dst, SDL_SRCCOLORKEY, dstkey);
for (y = 0; y < height; ++y)
{
for (x = 0; x < width; ++x, ++src_p, ++dst_p)
{
Uint32 p = *src_p & notmask;
*dst_p = (p == srckey) ? dstkey : p;
}
dst_p += ddst;
src_p += dsrc;
}
}
}
void void
TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int g, int b, TFB_Canvas target) TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int g, int b, TFB_Canvas target)
{ {
@@ -110,6 +187,7 @@ TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int
SDL_Surface *surf; SDL_Surface *surf;
int i; int i;
SDL_Color pal[256]; SDL_Color pal[256];
EXTENT prevextent = img->extent;
if (img == 0) if (img == 0)
{ {
@@ -137,16 +215,59 @@ TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int
surf = img->NormalImg; surf = img->NormalImg;
pSrcRect = NULL; pSrcRect = NULL;
} }
for (i = 0; i < 256; i++)
{
pal[i].r = r;
pal[i].g = g;
pal[i].b = b;
}
SDL_SetColors (surf, pal, 0, 256);
SDL_BlitSurface(surf, pSrcRect, (NativeCanvas) target, &targetRect); if (surf->format->palette)
{ // set palette for fill-stamp
for (i = 0; i < 256; i++)
{
pal[i].r = r;
pal[i].g = g;
pal[i].b = b;
}
SDL_SetColors (surf, pal, 0, 256);
}
else
{ // fill the non-transparent parts of the image with fillcolor
SDL_Surface *src = img->NormalImg;
SDL_Surface *newfill = img->FilledImg;
BOOLEAN force = FALSE;
// prepare the filled image
if (!newfill)
{
newfill = SDL_CreateRGBSurface (SDL_SWSURFACE,
src->w, src->h,
surf->format->BitsPerPixel,
surf->format->Rmask,
surf->format->Gmask,
surf->format->Bmask,
surf->format->Amask);
force = TRUE;
}
if (force ||
prevextent.height != img->extent.height ||
prevextent.width != img->extent.width ||
img->last_fill.r != r ||
img->last_fill.g != g ||
img->last_fill.b != b)
{ // image or fillcolor changed - regenerate
TFB_DrawCanvas_Fill (surf, img->extent.width, img->extent.height,
SDL_MapRGBA (newfill->format, r, g, b, 0), newfill);
// important to keep alpha=0 in fillcolor
// -- we process alpha ourselves
}
// cache filled image if possible
img->last_fill.r = r;
img->last_fill.g = g;
img->last_fill.b = b;
img->FilledImg = newfill;
surf = newfill;
}
SDL_BlitSurface (surf, pSrcRect, (NativeCanvas) target, &targetRect);
UnlockMutex (img->mutex); UnlockMutex (img->mutex);
} }
@@ -76,6 +76,9 @@ extern Uint64 mmx_YUV_threshold;
# undef HAVE_PREFETCH # undef HAVE_PREFETCH
#endif #endif
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
# pragma warning( disable : 4799 )
#endif
static inline void static inline void
SCALE_(PlatInit) (void) SCALE_(PlatInit) (void)
+2
View File
@@ -289,6 +289,7 @@ TFB_DrawImage_New (TFB_Canvas canvas)
img->mutex = CreateMutex ("image lock", SYNC_CLASS_VIDEO); img->mutex = CreateMutex ("image lock", SYNC_CLASS_VIDEO);
img->ScaledImg = NULL; img->ScaledImg = NULL;
img->MipmapImg = NULL; img->MipmapImg = NULL;
img->FilledImg = NULL;
img->colormap_index = -1; img->colormap_index = -1;
img->last_scale_type = -1; img->last_scale_type = -1;
TFB_DrawCanvas_GetExtent (canvas, &img->extent); TFB_DrawCanvas_GetExtent (canvas, &img->extent);
@@ -314,6 +315,7 @@ TFB_DrawImage_CreateForScreen (int w, int h, BOOLEAN withalpha)
img->mutex = CreateMutex ("image lock", SYNC_CLASS_VIDEO); img->mutex = CreateMutex ("image lock", SYNC_CLASS_VIDEO);
img->ScaledImg = NULL; img->ScaledImg = NULL;
img->MipmapImg = NULL; img->MipmapImg = NULL;
img->FilledImg = NULL;
img->colormap_index = -1; img->colormap_index = -1;
img->last_scale_type = -1; img->last_scale_type = -1;
img->Palette = NULL; img->Palette = NULL;
+2
View File
@@ -53,9 +53,11 @@ typedef struct tfb_image
TFB_Canvas NormalImg; TFB_Canvas NormalImg;
TFB_Canvas ScaledImg; TFB_Canvas ScaledImg;
TFB_Canvas MipmapImg; TFB_Canvas MipmapImg;
TFB_Canvas FilledImg;
TFB_Palette *Palette; TFB_Palette *Palette;
int colormap_index; int colormap_index;
int last_scale_type; int last_scale_type;
TFB_Palette last_fill;
EXTENT extent; EXTENT extent;
Mutex mutex; Mutex mutex;
BOOLEAN dirty; BOOLEAN dirty;