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:
@@ -113,6 +113,8 @@ processFontChar (FRAMEPTR FramePtr, SDL_Surface *surf, int charInd)
|
||||
Uint32 p;
|
||||
SDL_Color colors[256];
|
||||
SDL_Surface *new_surf;
|
||||
SDL_PixelFormat* srcfmt = surf->format;
|
||||
SDL_PixelFormat* dstfmt;
|
||||
GetPixelFn getpix;
|
||||
PutPixelFn putpix;
|
||||
|
||||
@@ -120,13 +122,21 @@ processFontChar (FRAMEPTR FramePtr, SDL_Surface *surf, int charInd)
|
||||
INDEX_SET (FramePtr->TypeIndexAndFlags, charInd);
|
||||
// XXX: Is this still relevant?
|
||||
|
||||
//#define ALPHA_FONTS
|
||||
|
||||
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,
|
||||
8, 0, 0, 0, 0);
|
||||
#endif
|
||||
|
||||
dstfmt = new_surf->format;
|
||||
getpix = getpixel_for (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)
|
||||
{
|
||||
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)
|
||||
putpix (new_surf, x, y, 0);
|
||||
else
|
||||
putpix (new_surf, x, y, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(ALPHA_FONTS)
|
||||
colors[0].r = 0;
|
||||
colors[0].g = 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_SetColorKey (new_surf, SDL_SRCCOLORKEY, 0);
|
||||
#endif
|
||||
|
||||
SDL_UnlockSurface (surf);
|
||||
SDL_FreeSurface (surf);
|
||||
@@ -355,6 +380,7 @@ FRAMEPTR Build_Font_Effect (FRAMEPTR FramePtr, Uint32 from, Uint32 to, BYTE type
|
||||
int x, y;
|
||||
int width, height;
|
||||
Uint32 color, clear;
|
||||
Uint32 srcmask, threshold;
|
||||
BYTE from_r, from_g, from_b, from_a;
|
||||
BYTE to_r, to_g, to_b, to_a;
|
||||
TFB_Image *tfbImg, *tfbOrigImg;
|
||||
@@ -362,14 +388,17 @@ FRAMEPTR Build_Font_Effect (FRAMEPTR FramePtr, Uint32 from, Uint32 to, BYTE type
|
||||
PutPixelFn putpix;
|
||||
GetPixelFn getpix;
|
||||
|
||||
width = GetFrameWidth (FramePtr);
|
||||
height = GetFrameHeight (FramePtr);
|
||||
NewFrame = CaptureDrawable (CreateDrawable ((CREATE_FLAGS)RAM_DRAWABLE,
|
||||
(SIZE)width, (SIZE)height, 1));
|
||||
tfbOrigImg = FramePtr->image;
|
||||
OrigImg = (SDL_Surface *)tfbOrigImg->NormalImg;
|
||||
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;
|
||||
img = (SDL_Surface *)tfbImg->NormalImg;
|
||||
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);
|
||||
TFB_DrawCanvas_SetTransparentColor (img, 0, 0, 0, FALSE);
|
||||
for (y = 0; y < 2; y++)
|
||||
for (x = 0; x < width; x++)
|
||||
putpix (img, x, y, clear);
|
||||
#if defined(ALPHA_FONTS)
|
||||
srcmask = OrigImg->format->Amask;
|
||||
threshold = (srcmask >> 1) & srcmask;
|
||||
#else // indexed fonts
|
||||
srcmask = 255;
|
||||
threshold = 0; // any index != 0
|
||||
#endif
|
||||
|
||||
width--;
|
||||
if (type == GRADIENT_EFFECT)
|
||||
{
|
||||
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_b = (to_b - from_b) / (height - 5);
|
||||
clrstep_a = (to_a - from_a) / (height - 5);
|
||||
for (; y < height - 1; y++)
|
||||
|
||||
clrstep_r = (to_r - from_r) / (height - 1);
|
||||
clrstep_g = (to_g - from_g) / (height - 1);
|
||||
clrstep_b = (to_b - from_b) / (height - 1);
|
||||
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);
|
||||
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_a += clrstep_a;
|
||||
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);
|
||||
else
|
||||
putpix (img, x, y, clear);
|
||||
putpix (img, x, y, clear);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == ALTERNATE_EFFECT)
|
||||
{
|
||||
Uint32 color1, color2;
|
||||
|
||||
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);
|
||||
for (; y < height - 1; y++)
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
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;
|
||||
putpix (img, x, y, color);
|
||||
}
|
||||
else
|
||||
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 (OrigImg);
|
||||
NewFrame->HotSpot = FramePtr->HotSpot;
|
||||
return (NewFrame);
|
||||
|
||||
return (NewFrame);
|
||||
}
|
||||
|
||||
// Generate a pixel (in the correct format to be applied to FramePtr) from the
|
||||
// r,g,b,a values supplied
|
||||
Uint32 frame_mapRGBA (FRAMEPTR FramePtr,Uint8 r, Uint8 g, Uint8 b, Uint8 a)
|
||||
|
||||
@@ -103,6 +103,83 @@ TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale, TFB_Palette *pale
|
||||
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
|
||||
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;
|
||||
int i;
|
||||
SDL_Color pal[256];
|
||||
EXTENT prevextent = img->extent;
|
||||
|
||||
if (img == 0)
|
||||
{
|
||||
@@ -138,6 +216,8 @@ TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int
|
||||
pSrcRect = NULL;
|
||||
}
|
||||
|
||||
if (surf->format->palette)
|
||||
{ // set palette for fill-stamp
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
pal[i].r = r;
|
||||
@@ -145,6 +225,47 @@ TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int
|
||||
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);
|
||||
|
||||
@@ -76,6 +76,9 @@ extern Uint64 mmx_YUV_threshold;
|
||||
# undef HAVE_PREFETCH
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
|
||||
# pragma warning( disable : 4799 )
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
SCALE_(PlatInit) (void)
|
||||
|
||||
@@ -289,6 +289,7 @@ TFB_DrawImage_New (TFB_Canvas canvas)
|
||||
img->mutex = CreateMutex ("image lock", SYNC_CLASS_VIDEO);
|
||||
img->ScaledImg = NULL;
|
||||
img->MipmapImg = NULL;
|
||||
img->FilledImg = NULL;
|
||||
img->colormap_index = -1;
|
||||
img->last_scale_type = -1;
|
||||
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->ScaledImg = NULL;
|
||||
img->MipmapImg = NULL;
|
||||
img->FilledImg = NULL;
|
||||
img->colormap_index = -1;
|
||||
img->last_scale_type = -1;
|
||||
img->Palette = NULL;
|
||||
|
||||
@@ -53,9 +53,11 @@ typedef struct tfb_image
|
||||
TFB_Canvas NormalImg;
|
||||
TFB_Canvas ScaledImg;
|
||||
TFB_Canvas MipmapImg;
|
||||
TFB_Canvas FilledImg;
|
||||
TFB_Palette *Palette;
|
||||
int colormap_index;
|
||||
int last_scale_type;
|
||||
TFB_Palette last_fill;
|
||||
EXTENT extent;
|
||||
Mutex mutex;
|
||||
BOOLEAN dirty;
|
||||
|
||||
Reference in New Issue
Block a user