diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/sdlfont.cpp | 21 | ||||
-rw-r--r-- | src/resources/image.cpp | 77 | ||||
-rw-r--r-- | src/resources/image.h | 2 |
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. */ |