summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2011-07-20 02:57:47 +0300
committerAndrei Karas <akaras@inbox.ru>2011-07-20 03:41:35 +0300
commite645959d2dc85ee6a50d9927df3d9f6e374c8317 (patch)
tree6e5c348a7c89c4c864bab299fc9989fc0b0a5791
parentca945c9bd62318109246443c6d43091885e817b1 (diff)
downloadmv-e645959d2dc85ee6a50d9927df3d9f6e374c8317.tar.gz
mv-e645959d2dc85ee6a50d9927df3d9f6e374c8317.tar.bz2
mv-e645959d2dc85ee6a50d9927df3d9f6e374c8317.tar.xz
mv-e645959d2dc85ee6a50d9927df3d9f6e374c8317.zip
Improve perfomance in creation SDL font surfaces.
-rw-r--r--src/gui/sdlfont.cpp21
-rw-r--r--src/resources/image.cpp77
-rw-r--r--src/resources/image.h2
3 files changed, 92 insertions, 8 deletions
diff --git a/src/gui/sdlfont.cpp b/src/gui/sdlfont.cpp
index 9cbee4e89..a0f8699f8 100644
--- a/src/gui/sdlfont.cpp
+++ b/src/gui/sdlfont.cpp
@@ -64,7 +64,7 @@ class SDLTextChunk
return (chunk.text == text && chunk.color == color);
}
- void generate(TTF_Font *font)
+ void generate(TTF_Font *font, float alpha)
{
SDL_Color sdlCol;
sdlCol.b = static_cast<Uint8>(color.b);
@@ -83,7 +83,8 @@ class SDLTextChunk
return;
}
- img = Image::load(surface);
+ img = Image::createTextSurface(surface, alpha);
+// img = Image::load(surface);
SDL_FreeSurface(surface);
}
@@ -243,7 +244,7 @@ void SDLFont::drawString(gcn::Graphics *graphics,
mCreateCounter ++;
#endif
cache->push_front(chunk);
- cache->front().generate(mFont);
+ cache->front().generate(mFont, alpha);
if (!mCleanTime)
{
@@ -254,9 +255,13 @@ void SDLFont::drawString(gcn::Graphics *graphics,
doClean();
mCleanTime = cur_time + CLEAN_TIME;
}
+ if (cache->front().img)
+ {
+// cache->front().img->setAlpha(alpha);
+ g->drawImage(cache->front().img, x, y);
+ }
}
-
- if (cache->front().img)
+ else if (cache->front().img)
{
cache->front().img->setAlpha(alpha);
g->drawImage(cache->front().img, x, y);
@@ -271,9 +276,9 @@ void SDLFont::createSDLTextChunk(SDLTextChunk *chunk)
const float alpha = static_cast<float>(chunk->color.a) / 255.0f;
chunk->color.a = 255;
- chunk->generate(mFont);
- if (chunk->img)
- chunk->img->setAlpha(alpha);
+ chunk->generate(mFont, alpha);
+// if (chunk->img)
+// chunk->img->setAlpha(alpha);
}
int SDLFont::getWidth(const std::string &text) const
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 29e89d26e..583cf7343 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -189,6 +189,83 @@ Image *Image::load(SDL_Surface *tmpImage)
return _SDLload(tmpImage);
}
+Image *Image::createTextSurface(SDL_Surface *tmpImage, float alpha)
+{
+ if (!tmpImage)
+ return NULL;
+
+ Image *img;
+#ifdef USE_OPENGL
+ if (mUseOpenGL)
+ {
+ img = _GLload(tmpImage);
+ img->setAlpha(alpha);
+ return img;
+ }
+#endif
+
+ bool hasAlpha = false;
+ bool converted = false;
+
+ // The alpha channel to be filled with alpha values
+ Uint8 *alphaChannel = new Uint8[tmpImage->w * tmpImage->h];
+
+ const int sz = tmpImage->w * tmpImage->h;
+ const SDL_PixelFormat * const fmt = tmpImage->format;
+ if (fmt->Amask)
+ {
+ for (int i = 0; i < sz; ++ i)
+ {
+ unsigned v = ((static_cast<Uint32*>(tmpImage->pixels))[i]
+ & fmt->Amask) >> fmt->Ashift;
+ Uint8 a = (v << fmt->Aloss) + (v >> (8 - (fmt->Aloss << 1)));
+
+ Uint8 a2 = static_cast<Uint8>(static_cast<float>(a) * alpha);
+
+ (static_cast<Uint32*>(tmpImage->pixels))[i] &= ~fmt->Amask;
+ (static_cast<Uint32*>(tmpImage->pixels))[i] |=
+ ((a2 >> fmt->Aloss) << fmt->Ashift & fmt->Amask);
+
+ if (a != 255)
+ hasAlpha = true;
+
+ alphaChannel[i] = a;
+
+ }
+ }
+
+ SDL_Surface *image;
+
+ // Convert the surface to the current display format
+ if (hasAlpha)
+ {
+ image = SDL_DisplayFormatAlpha(tmpImage);
+ }
+ else
+ {
+ image = SDL_DisplayFormat(tmpImage);
+
+ // We also delete the alpha channel since
+ // it's not used.
+ delete[] alphaChannel;
+ alphaChannel = 0;
+ }
+
+ if (!image)
+ {
+ logger->log1("Error: Image convert failed.");
+ delete[] alphaChannel;
+ return 0;
+ }
+
+ if (converted)
+ SDL_FreeSurface(tmpImage);
+
+ img = new Image(image, hasAlpha, alphaChannel);
+ img->mAlpha = alpha;
+ return img;
+}
+
void Image::SDLCleanCache()
{
ResourceManager *resman = ResourceManager::getInstance();
diff --git a/src/resources/image.h b/src/resources/image.h
index 718301f81..9ac2b163e 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -95,6 +95,8 @@ class Image : public Resource
static SDL_Surface* convertTo32Bit(SDL_Surface* tmpImage);
+ static Image *createTextSurface(SDL_Surface *tmpImage, float alpha);
+
/**
* Frees the resources created by SDL.
*/