1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-11-25 22:45:20 +02:00

Surface: Load image with factory method instead of constructor.

If loading fails, the factory method returns NULL, while previously the
constructor would create a Surface object with a NULL "raw" field.
However, since most of the methods dereference "raw" without checking,
such a Surface would likely crash the application when used.
This commit is contained in:
Maarten ter Huurne 2011-06-02 22:09:03 +02:00
parent 0a9229ff3f
commit 52f4686e4a
5 changed files with 59 additions and 48 deletions

View File

@ -351,7 +351,7 @@ void GMenu2X::initBG() {
bg->box(0,0,resX,resY,0,0,0); bg->box(0,0,resX,resY,0,0,0);
} else { } else {
// Note: Copy constructor converts to display format. // Note: Copy constructor converts to display format.
bg = new Surface(Surface(confStr["wallpaper"])); bg = new Surface(Surface::loadImage(confStr["wallpaper"]));
} }
drawTopBar(bg); drawTopBar(bg);
@ -360,37 +360,46 @@ void GMenu2X::initBG() {
Surface *bgmain = new Surface(bg); Surface *bgmain = new Surface(bg);
sc.add(bgmain,"bgmain"); sc.add(bgmain,"bgmain");
Surface sd("imgs/sd.png", confStr["skin"]); Surface *sd = Surface::loadImage("imgs/sd.png", confStr["skin"]);
Surface cpu("imgs/cpu.png", confStr["skin"]); if (sd) sd->blit(sc["bgmain"], 3, bottomBarIconY);
Surface volume("imgs/volume.png", confStr["skin"]);
string df = getDiskFree(); string df = getDiskFree();
sd.blit( sc["bgmain"], 3, bottomBarIconY );
sc["bgmain"]->write(font, df, 22, bottomBarTextY, ASFont::HAlignLeft, ASFont::VAlignMiddle); sc["bgmain"]->write(font, df, 22, bottomBarTextY, ASFont::HAlignLeft, ASFont::VAlignMiddle);
free(sd);
Surface *volume = Surface::loadImage("imgs/volume.png", confStr["skin"]);
volumeX = 27+font->getTextWidth(df); volumeX = 27+font->getTextWidth(df);
volume.blit( sc["bgmain"], volumeX, bottomBarIconY ); if (volume) volume->blit(sc["bgmain"], volumeX, bottomBarIconY);
volumeX += 19; volumeX += 19;
free(volume);
Surface *cpu = Surface::loadImage("imgs/cpu.png", confStr["skin"]);
cpuX = volumeX+font->getTextWidth("100")+5; cpuX = volumeX+font->getTextWidth("100")+5;
cpu.blit( sc["bgmain"], cpuX, bottomBarIconY ); if (cpu) cpu->blit(sc["bgmain"], cpuX, bottomBarIconY);
cpuX += 19; cpuX += 19;
manualX = cpuX+font->getTextWidth("300Mhz")+5; manualX = cpuX+font->getTextWidth("300Mhz")+5;
free(cpu);
int serviceX = resX-38; int serviceX = resX-38;
if (usbnet) { if (usbnet) {
if (web) { if (web) {
Surface webserver("imgs/webserver.png", confStr["skin"]); Surface *webserver = Surface::loadImage(
webserver.blit( sc["bgmain"], serviceX, bottomBarIconY ); "imgs/webserver.png", confStr["skin"]);
if (webserver) webserver->blit(sc["bgmain"], serviceX, bottomBarIconY);
serviceX -= 19; serviceX -= 19;
free(webserver);
} }
if (samba) { if (samba) {
Surface sambaS("imgs/samba.png", confStr["skin"]); Surface *sambaS = Surface::loadImage(
sambaS.blit( sc["bgmain"], serviceX, bottomBarIconY ); "imgs/samba.png", confStr["skin"]);
if (sambaS) sambaS->blit(sc["bgmain"], serviceX, bottomBarIconY);
serviceX -= 19; serviceX -= 19;
free(sambaS);
} }
if (inet) { if (inet) {
Surface inetS("imgs/inet.png", confStr["skin"]); Surface *inetS = Surface::loadImage("imgs/inet.png", confStr["skin"]);
inetS.blit( sc["bgmain"], serviceX, bottomBarIconY ); if (inetS) inetS->blit(sc["bgmain"], serviceX, bottomBarIconY);
serviceX -= 19; serviceX -= 19;
free(inetS);
} }
} }
} }

View File

@ -300,14 +300,17 @@ void LinkApp::showManual() {
//Raise the clock to speed-up the loading of the manual //Raise the clock to speed-up the loading of the manual
gmenu2x->setClock(336); gmenu2x->setClock(336);
Surface pngman(manual); Surface *pngman = Surface::loadImage(manual);
if (!pngman) {
return;
}
// Note: Copy constructor converts to display format. // Note: Copy constructor converts to display format.
Surface bg(Surface(gmenu2x->confStr["wallpaper"])); Surface bg(Surface::loadImage(gmenu2x->confStr["wallpaper"]));
stringstream ss; stringstream ss;
string pageStatus; string pageStatus;
bool close = false, repaint = true; bool close = false, repaint = true;
int page=0, pagecount=pngman.raw->w/320; int page=0, pagecount=pngman->raw->w/320;
ss << pagecount; ss << pagecount;
string spagecount; string spagecount;
@ -319,7 +322,7 @@ void LinkApp::showManual() {
while (!close) { while (!close) {
if (repaint) { if (repaint) {
bg.blit(gmenu2x->s, 0, 0); bg.blit(gmenu2x->s, 0, 0);
pngman.blit(gmenu2x->s, -page*320, 0); pngman->blit(gmenu2x->s, -page*320, 0);
gmenu2x->drawBottomBar(); gmenu2x->drawBottomBar();
gmenu2x->drawButton(gmenu2x->s, "x", gmenu2x->tr["Exit"], gmenu2x->drawButton(gmenu2x->s, "x", gmenu2x->tr["Exit"],

View File

@ -44,10 +44,31 @@ Surface *Surface::openOutputSurface(int width, int height, int bitsperpixel) {
return raw ? new Surface(raw, false) : NULL; return raw ? new Surface(raw, false) : NULL;
} }
Surface *Surface::loadImage(const string &img, const string &skin) {
string skinpath;
if (!skin.empty() && !img.empty() && img[0]!='/') {
skinpath = "skins/"+skin+"/"+img;
if (!fileExists(skinpath))
skinpath = "skins/Default/"+img;
} else {
skinpath = img;
}
SDL_Surface *raw = loadPNG(skinpath);
if (!raw) {
ERROR("Couldn't load surface '%s'\n", img.c_str());
return NULL;
}
return new Surface(raw, true);
}
Surface::Surface(SDL_Surface *raw_, bool freeWhenDone_) Surface::Surface(SDL_Surface *raw_, bool freeWhenDone_)
: raw(raw_) : raw(raw_)
, freeWhenDone(freeWhenDone_) , freeWhenDone(freeWhenDone_)
{ {
halfW = raw->w/2;
halfH = raw->h/2;
} }
Surface::Surface(Surface *s) { Surface::Surface(Surface *s) {
@ -57,14 +78,6 @@ Surface::Surface(Surface *s) {
halfH = raw->h/2; halfH = raw->h/2;
} }
Surface::Surface(const string &img, const string &skin) {
raw = NULL;
load(img, skin);
freeWhenDone = (raw != NULL);
halfW = raw->w/2;
halfH = raw->h/2;
}
Surface::~Surface() { Surface::~Surface() {
if (freeWhenDone) { if (freeWhenDone) {
SDL_FreeSurface(raw); SDL_FreeSurface(raw);
@ -78,22 +91,6 @@ SDL_PixelFormat *Surface::format() {
return raw->format; return raw->format;
} }
void Surface::load(const string &img, const string &skin) {
string skinpath;
if (!skin.empty() && !img.empty() && img[0]!='/') {
skinpath = "skins/"+skin+"/"+img;
if (!fileExists(skinpath))
skinpath = "skins/Default/"+img;
} else {
skinpath = img;
}
raw = loadPNG(skinpath);
if (!raw) {
ERROR("Couldn't load surface '%s'\n", img.c_str());
}
}
void Surface::flip() { void Surface::flip() {
SDL_Flip(raw); SDL_Flip(raw);
} }

View File

@ -40,9 +40,9 @@ RGBAColor strtorgba(const string &strColor);
class Surface { class Surface {
public: public:
static Surface *openOutputSurface(int width, int height, int bitsperpixel); static Surface *openOutputSurface(int width, int height, int bitsperpixel);
static Surface *loadImage(const string &img, const string &skin="");
Surface(Surface *s); Surface(Surface *s);
Surface(const string &img, const string &skin="");
~Surface(); ~Surface();
SDL_Surface *raw; SDL_Surface *raw;
@ -74,7 +74,6 @@ public:
private: private:
Surface(SDL_Surface *raw, bool freeWhenDone); Surface(SDL_Surface *raw, bool freeWhenDone);
SDL_PixelFormat *format(); SDL_PixelFormat *format();
void load(const string &img, const string &skin);
bool blit(SDL_Surface *destination, int x, int y, int w=0, int h=0, int a=-1); bool blit(SDL_Surface *destination, int x, int y, int w=0, int h=0, int a=-1);
bool blitCenter(SDL_Surface *destination, int x, int y, int w=0, int h=0, int a=-1); bool blitCenter(SDL_Surface *destination, int x, int y, int w=0, int h=0, int a=-1);
bool blitRight(SDL_Surface *destination, int x, int y, int w=0, int h=0, int a=-1); bool blitRight(SDL_Surface *destination, int x, int y, int w=0, int h=0, int a=-1);

View File

@ -80,8 +80,10 @@ Surface *SurfaceCollection::add(const string &path) {
return NULL; return NULL;
} else if (!fileExists(filePath)) return NULL; } else if (!fileExists(filePath)) return NULL;
Surface *s = new Surface(filePath); Surface *s = Surface::loadImage(filePath);
if (s != NULL) {
surfaces[path] = s; surfaces[path] = s;
}
return s; return s;
} }
@ -94,9 +96,10 @@ Surface *SurfaceCollection::addSkinRes(const string &path) {
string skinpath = getSkinFilePath(path); string skinpath = getSkinFilePath(path);
if (skinpath.empty()) if (skinpath.empty())
return NULL; return NULL;
Surface *s = new Surface(skinpath); Surface *s = Surface::loadImage(skinpath);
if (s != NULL) if (s != NULL) {
surfaces[path] = s; surfaces[path] = s;
}
return s; return s;
} }