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

Surface: Make pixel format conversion explicit.

Instead of having the copy constructor convert to display format, the new
copy constructor preserves the pixel format and a separate method was
introduced to convert surfaces to display format.

The code was made more robust as well: it should no longer crash if the
wallpaper cannot be loaded.
This commit is contained in:
Maarten ter Huurne 2011-06-03 11:46:36 +02:00
parent 7861e07eb0
commit 8a81837c04
9 changed files with 58 additions and 20 deletions

View File

@ -344,14 +344,11 @@ void GMenu2X::quit() {
void GMenu2X::initBG() { void GMenu2X::initBG() {
sc.del("bgmain"); sc.del("bgmain");
if (bg != NULL) free(bg); // Load wallpaper.
free(bg);
if (!fileExists(confStr["wallpaper"])) { bg = Surface::loadImage(confStr["wallpaper"]);
bg = new Surface(s); if (!bg) {
bg->box(0,0,resX,resY,0,0,0); bg = Surface::emptySurface(resX, resY);
} else {
// Note: Copy constructor converts to display format.
bg = new Surface(Surface::loadImage(confStr["wallpaper"]));
} }
drawTopBar(bg); drawTopBar(bg);
@ -361,20 +358,20 @@ void GMenu2X::initBG() {
sc.add(bgmain,"bgmain"); sc.add(bgmain,"bgmain");
Surface *sd = Surface::loadImage("imgs/sd.png", confStr["skin"]); Surface *sd = Surface::loadImage("imgs/sd.png", confStr["skin"]);
if (sd) sd->blit(sc["bgmain"], 3, bottomBarIconY); if (sd) sd->blit(bgmain, 3, bottomBarIconY);
string df = getDiskFree(); string df = getDiskFree();
sc["bgmain"]->write(font, df, 22, bottomBarTextY, ASFont::HAlignLeft, ASFont::VAlignMiddle); bgmain->write(font, df, 22, bottomBarTextY, ASFont::HAlignLeft, ASFont::VAlignMiddle);
free(sd); free(sd);
Surface *volume = Surface::loadImage("imgs/volume.png", confStr["skin"]); Surface *volume = Surface::loadImage("imgs/volume.png", confStr["skin"]);
volumeX = 27+font->getTextWidth(df); volumeX = 27+font->getTextWidth(df);
if (volume) volume->blit(sc["bgmain"], volumeX, bottomBarIconY); if (volume) volume->blit(bgmain, volumeX, bottomBarIconY);
volumeX += 19; volumeX += 19;
free(volume); free(volume);
Surface *cpu = Surface::loadImage("imgs/cpu.png", confStr["skin"]); Surface *cpu = Surface::loadImage("imgs/cpu.png", confStr["skin"]);
cpuX = volumeX+font->getTextWidth("100")+5; cpuX = volumeX+font->getTextWidth("100")+5;
if (cpu) cpu->blit(sc["bgmain"], cpuX, bottomBarIconY); if (cpu) cpu->blit(bgmain, cpuX, bottomBarIconY);
cpuX += 19; cpuX += 19;
manualX = cpuX+font->getTextWidth("300Mhz")+5; manualX = cpuX+font->getTextWidth("300Mhz")+5;
free(cpu); free(cpu);
@ -384,24 +381,26 @@ void GMenu2X::initBG() {
if (web) { if (web) {
Surface *webserver = Surface::loadImage( Surface *webserver = Surface::loadImage(
"imgs/webserver.png", confStr["skin"]); "imgs/webserver.png", confStr["skin"]);
if (webserver) webserver->blit(sc["bgmain"], serviceX, bottomBarIconY); if (webserver) webserver->blit(bgmain, serviceX, bottomBarIconY);
serviceX -= 19; serviceX -= 19;
free(webserver); free(webserver);
} }
if (samba) { if (samba) {
Surface *sambaS = Surface::loadImage( Surface *sambaS = Surface::loadImage(
"imgs/samba.png", confStr["skin"]); "imgs/samba.png", confStr["skin"]);
if (sambaS) sambaS->blit(sc["bgmain"], serviceX, bottomBarIconY); if (sambaS) sambaS->blit(bgmain, serviceX, bottomBarIconY);
serviceX -= 19; serviceX -= 19;
free(sambaS); free(sambaS);
} }
if (inet) { if (inet) {
Surface *inetS = Surface::loadImage("imgs/inet.png", confStr["skin"]); Surface *inetS = Surface::loadImage("imgs/inet.png", confStr["skin"]);
if (inetS) inetS->blit(sc["bgmain"], serviceX, bottomBarIconY); if (inetS) inetS->blit(bgmain, serviceX, bottomBarIconY);
serviceX -= 19; serviceX -= 19;
free(inetS); free(inetS);
} }
} }
bgmain->convertToDisplayFormat();
} }
void GMenu2X::initFont() { void GMenu2X::initFont() {
@ -1632,6 +1631,7 @@ void GMenu2X::scanner() {
drawButton(&scanbg, "x", tr["Exit"], drawButton(&scanbg, "x", tr["Exit"],
drawButton(&scanbg, "b", "", 5)-10); drawButton(&scanbg, "b", "", 5)-10);
scanbg.write(font,tr["Link Scanner"],halfX,7,ASFont::HAlignCenter,ASFont::VAlignMiddle); scanbg.write(font,tr["Link Scanner"],halfX,7,ASFont::HAlignCenter,ASFont::VAlignMiddle);
scanbg.convertToDisplayFormat();
uint lineY = 42; uint lineY = 42;

View File

@ -304,8 +304,12 @@ void LinkApp::showManual() {
if (!pngman) { if (!pngman) {
return; return;
} }
// Note: Copy constructor converts to display format. Surface *bg = Surface::loadImage(gmenu2x->confStr["wallpaper"]);
Surface bg(Surface::loadImage(gmenu2x->confStr["wallpaper"])); if (!bg) {
bg = Surface::emptySurface(gmenu2x->s->width(), gmenu2x->s->height());
}
bg->convertToDisplayFormat();
stringstream ss; stringstream ss;
string pageStatus; string pageStatus;
@ -321,7 +325,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();
@ -361,6 +365,7 @@ void LinkApp::showManual() {
break; break;
} }
} }
free(bg);
return; return;
} }

View File

@ -99,6 +99,7 @@ int MessageBox::exec() {
} }
} }
bg.convertToDisplayFormat();
bg.blit(gmenu2x->s,0,0); bg.blit(gmenu2x->s,0,0);
gmenu2x->s->flip(); gmenu2x->s->flip();

View File

@ -71,6 +71,8 @@ int Selector::exec(int startSelection) {
gmenu2x->drawButton(&bg, "b", gmenu2x->tr["Select a file"], 5)); gmenu2x->drawButton(&bg, "b", gmenu2x->tr["Select a file"], 5));
} }
bg.convertToDisplayFormat();
Uint32 selTick = SDL_GetTicks(), curTick; Uint32 selTick = SDL_GetTicks(), curTick;
uint i, firstElement = 0, iY; uint i, firstElement = 0, iY;

View File

@ -45,8 +45,8 @@ SettingsDialog::~SettingsDialog() {
} }
bool SettingsDialog::exec() { bool SettingsDialog::exec() {
//Surface bg (gmenu2x->confStr["wallpaper"],false);
Surface bg(gmenu2x->bg); Surface bg(gmenu2x->bg);
bg.convertToDisplayFormat();
bool close = false, ts_pressed = false; bool close = false, ts_pressed = false;
uint i, sel = 0, iY, firstElement = 0, action; uint i, sel = 0, iY, firstElement = 0, action;

View File

@ -44,6 +44,14 @@ 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::emptySurface(int width, int height) {
SDL_Surface *raw = SDL_CreateRGBSurface(
SDL_SWSURFACE, width, height, 32, 0, 0, 0, 0);
if (!raw) return NULL;
SDL_FillRect(raw, NULL, SDL_MapRGB(raw->format, 0, 0, 0));
return new Surface(raw, true);
}
Surface *Surface::loadImage(const string &img, const string &skin) { Surface *Surface::loadImage(const string &img, const string &skin) {
string skinpath; string skinpath;
if (!skin.empty() && !img.empty() && img[0]!='/') { if (!skin.empty() && !img.empty() && img[0]!='/') {
@ -72,7 +80,7 @@ Surface::Surface(SDL_Surface *raw_, bool freeWhenDone_)
} }
Surface::Surface(Surface *s) { Surface::Surface(Surface *s) {
raw = SDL_DisplayFormat(s->raw); raw = SDL_ConvertSurface(s->raw, s->raw->format, SDL_SWSURFACE);
freeWhenDone = true; freeWhenDone = true;
halfW = raw->w/2; halfW = raw->w/2;
halfH = raw->h/2; halfH = raw->h/2;
@ -84,6 +92,17 @@ Surface::~Surface() {
} }
} }
void Surface::convertToDisplayFormat() {
SDL_Surface *newSurface = SDL_DisplayFormat(raw);
if (newSurface) {
if (freeWhenDone) {
SDL_FreeSurface(raw);
}
raw = newSurface;
freeWhenDone = true;
}
}
void Surface::flip() { void Surface::flip() {
SDL_Flip(raw); SDL_Flip(raw);
} }

View File

@ -40,11 +40,18 @@ 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 *emptySurface(int width, int height);
static Surface *loadImage(const string &img, const string &skin=""); static Surface *loadImage(const string &img, const string &skin="");
Surface(Surface *s); Surface(Surface *s);
~Surface(); ~Surface();
/** Converts the underlying surface to the same pixel format as the frame
* buffer, for faster blitting. This removes the alpha channel if the
* image has done.
*/
void convertToDisplayFormat();
int width() { return raw->w; } int width() { return raw->w; }
int height() { return raw->h; } int height() { return raw->h; }

View File

@ -110,6 +110,8 @@ void TextDialog::exec() {
gmenu2x->drawButton(&bg, "down", gmenu2x->tr["Scroll"], gmenu2x->drawButton(&bg, "down", gmenu2x->tr["Scroll"],
gmenu2x->drawButton(&bg, "up", "", 5)-10)); gmenu2x->drawButton(&bg, "up", "", 5)-10));
bg.convertToDisplayFormat();
uint firstRow = 0, rowsPerPage = (gmenu2x->resY-60)/gmenu2x->font->getHeight(); uint firstRow = 0, rowsPerPage = (gmenu2x->resY-60)/gmenu2x->font->getHeight();
while (!close) { while (!close) {
bg.blit(gmenu2x->s,0,0); bg.blit(gmenu2x->s,0,0);

View File

@ -80,6 +80,8 @@ void TextManualDialog::exec() {
gmenu2x->drawButton(&bg, "down", gmenu2x->tr["Scroll"], gmenu2x->drawButton(&bg, "down", gmenu2x->tr["Scroll"],
gmenu2x->drawButton(&bg, "up", "", 5)-10))-10)); gmenu2x->drawButton(&bg, "up", "", 5)-10))-10));
bg.convertToDisplayFormat();
uint firstRow = 0, rowsPerPage = 180/gmenu2x->font->getHeight(); uint firstRow = 0, rowsPerPage = 180/gmenu2x->font->getHeight();
stringstream ss; stringstream ss;
ss << pages.size(); ss << pages.size();