mirror of
git://projects.qi-hardware.com/gmenu2x.git
synced 2024-11-25 20:25:54 +02:00
PNG: Make loadPNG() responsible for creating an RGBA surface.
Before this commit loadPNG() could return any surface format and the caller was responsible for converting it to the desired format. However, in practice all callers want a surface with an alpha channel and SDL only supports that with 32bpp surfaces, so RGBA or a permutation thereof. So I changed the contract for loadPNG() so it is required to return an RGBA surface, and removed the conversion code in the callers. The next step is to replace IMG_Load() by a function that calls libpng directly and loads a fixed 32bpp pixel format. That way, we can drop the SDL_image dependency and avoid unnecessary pixel format conversions.
This commit is contained in:
parent
7877fee3fa
commit
8b17e2ef62
@ -11,35 +11,10 @@
|
|||||||
ASFont::ASFont(const std::string &fontImagePath)
|
ASFont::ASFont(const std::string &fontImagePath)
|
||||||
: characters(SFONTPLUS_CHARSET)
|
: characters(SFONTPLUS_CHARSET)
|
||||||
{
|
{
|
||||||
// Load PNG file into an SDL surface.
|
surface = loadPNG(fontImagePath);
|
||||||
SDL_Surface *buf = loadPNG(fontImagePath);
|
if (!surface) {
|
||||||
if (!buf) {
|
|
||||||
surface = NULL;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we have a surface that can be blitted using alpha blending.
|
|
||||||
if (buf->format->BytesPerPixel == 4) {
|
|
||||||
surface = buf;
|
|
||||||
SDL_SetAlpha(surface, SDL_SRCALPHA, 255);
|
|
||||||
} else {
|
|
||||||
SDL_PixelFormat format32;
|
|
||||||
memset(&format32, 0, sizeof(format32));
|
|
||||||
format32.BitsPerPixel = 32;
|
|
||||||
format32.BytesPerPixel = 4;
|
|
||||||
format32.Rmask =
|
|
||||||
SDL_BYTEORDER == SDL_BIG_ENDIAN ? 0x00FF0000 : 0x000000FF;
|
|
||||||
format32.Gmask = 0x0000FF00;
|
|
||||||
format32.Bmask =
|
|
||||||
SDL_BYTEORDER == SDL_BIG_ENDIAN ? 0x000000FF : 0x00FF0000;
|
|
||||||
format32.Amask = 0xFF000000;
|
|
||||||
format32.Rshift = SDL_BYTEORDER == SDL_BIG_ENDIAN ? 16 : 0;
|
|
||||||
format32.Gshift = 8;
|
|
||||||
format32.Bshift = SDL_BYTEORDER == SDL_BIG_ENDIAN ? 0 : 16;
|
|
||||||
format32.Ashift = 24;
|
|
||||||
surface = SDL_ConvertSurface(buf, &format32, SDL_SRCALPHA);
|
|
||||||
SDL_FreeSurface(buf);
|
|
||||||
}
|
|
||||||
assert(surface->format->BytesPerPixel == 4);
|
assert(surface->format->BytesPerPixel == 4);
|
||||||
|
|
||||||
SDL_LockSurface(surface);
|
SDL_LockSurface(surface);
|
||||||
|
@ -2,7 +2,35 @@
|
|||||||
|
|
||||||
#include <SDL_image.h>
|
#include <SDL_image.h>
|
||||||
|
|
||||||
SDL_Surface *loadPNG(const std::string &path)
|
SDL_Surface *loadPNG(const std::string &path) {
|
||||||
{
|
// Load PNG file into an SDL surface.
|
||||||
return IMG_Load(path.c_str());
|
SDL_Surface *surface = IMG_Load(path.c_str());
|
||||||
|
if (!surface) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we have a surface that can be blitted using alpha blending.
|
||||||
|
if (surface->format->BytesPerPixel == 4) {
|
||||||
|
SDL_SetAlpha(surface, SDL_SRCALPHA, 255);
|
||||||
|
return surface;
|
||||||
|
} else {
|
||||||
|
SDL_PixelFormat format32;
|
||||||
|
memset(&format32, 0, sizeof(format32));
|
||||||
|
format32.BitsPerPixel = 32;
|
||||||
|
format32.BytesPerPixel = 4;
|
||||||
|
format32.Rmask =
|
||||||
|
SDL_BYTEORDER == SDL_BIG_ENDIAN ? 0x00FF0000 : 0x000000FF;
|
||||||
|
format32.Gmask = 0x0000FF00;
|
||||||
|
format32.Bmask =
|
||||||
|
SDL_BYTEORDER == SDL_BIG_ENDIAN ? 0x000000FF : 0x00FF0000;
|
||||||
|
format32.Amask = 0xFF000000;
|
||||||
|
format32.Rshift = SDL_BYTEORDER == SDL_BIG_ENDIAN ? 16 : 0;
|
||||||
|
format32.Gshift = 8;
|
||||||
|
format32.Bshift = SDL_BYTEORDER == SDL_BIG_ENDIAN ? 0 : 16;
|
||||||
|
format32.Ashift = 24;
|
||||||
|
SDL_Surface *surface32 =
|
||||||
|
SDL_ConvertSurface(surface, &format32, SDL_SRCALPHA);
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
return surface32;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
struct SDL_Surface;
|
struct SDL_Surface;
|
||||||
|
|
||||||
|
/** Loads an image from a PNG file into a newly allocated 32bpp RGBA surface.
|
||||||
|
*/
|
||||||
SDL_Surface *loadPNG(const std::string &path);
|
SDL_Surface *loadPNG(const std::string &path);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -90,11 +90,8 @@ void Surface::load(const string &img, const string &skin) {
|
|||||||
skinpath = img;
|
skinpath = img;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Surface *buf = loadPNG(skinpath);
|
raw = loadPNG(skinpath);
|
||||||
if (buf!=NULL) {
|
if (!raw) {
|
||||||
raw = SDL_DisplayFormatAlpha(buf);
|
|
||||||
SDL_FreeSurface(buf);
|
|
||||||
} else {
|
|
||||||
ERROR("Couldn't load surface '%s'\n", img.c_str());
|
ERROR("Couldn't load surface '%s'\n", img.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user