From c752ef0fe15adab939f3fd339f327270a6caa176 Mon Sep 17 00:00:00 2001 From: Mark de Wever Date: Tue, 13 May 2008 15:54:45 +0000 Subject: [PATCH] Move the save and restore background routines into generic code... ...so it can be used at other parts (the listbox will need it). --- src/gui/widgets/control.cpp | 50 ++------------------------- src/gui/widgets/helper.cpp | 67 +++++++++++++++++++++++++++++++++++-- src/gui/widgets/helper.hpp | 29 ++++++++++++++++ 3 files changed, 97 insertions(+), 49 deletions(-) diff --git a/src/gui/widgets/control.cpp b/src/gui/widgets/control.cpp index 26aa2c726e4..77bc693eb02 100644 --- a/src/gui/widgets/control.cpp +++ b/src/gui/widgets/control.cpp @@ -16,6 +16,7 @@ #include "font.hpp" #include "foreach.hpp" +#include "gui/widgets/helper.hpp" #include "gui/widgets/window.hpp" #include "log.hpp" #include "marked-up_text.hpp" @@ -269,32 +270,9 @@ void tcontrol::draw(surface& surface) //! @param src background to save. void tcontrol::save_background(const surface& src) { - assert(src); assert(!restorer_); - const SDL_Rect rect = get_rect(); - - restorer_.assign(SDL_CreateRGBSurface(SDL_SWSURFACE, - rect.w, rect.h, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000)); - - { - // Extra scoping used for the surface_lock. - surface_lock src_lock(src); - surface_lock dst_lock(restorer_); - - Uint32* src_pixels = reinterpret_cast(src_lock.pixels()); - Uint32* dst_pixels = reinterpret_cast(dst_lock.pixels()); - - unsigned offset = rect.y * src->w + rect.x; - for(unsigned y = 0; y < rect.h; ++y) { - for(unsigned x = 0; x < rect.w; ++x) { - - *dst_pixels++ = src_pixels[offset + x]; - - } - offset += src->w; - } - } + restorer_ = gui2::save_background(src, get_rect()); } //! Restores a portion of the background. @@ -304,29 +282,7 @@ void tcontrol::save_background(const surface& src) //! @param dst Background to restore. void tcontrol::restore_background(surface& dst) { - assert(restorer_); - assert(dst); - - const SDL_Rect rect = get_rect(); - - { - // Extra scoping used for the surface_lock. - surface_lock src_lock(restorer_); - surface_lock dst_lock(dst); - - Uint32* src_pixels = reinterpret_cast(src_lock.pixels()); - Uint32* dst_pixels = reinterpret_cast(dst_lock.pixels()); - - unsigned offset = rect.y * dst->w + rect.x; - for(unsigned y = 0; y < rect.h; ++y) { - for(unsigned x = 0; x < rect.w; ++x) { - - dst_pixels[offset + x] = *src_pixels++; - - } - offset += dst->w; - } - } + gui2::restore_background(restorer_, dst, get_rect()); } //! Inherited from twidget. diff --git a/src/gui/widgets/helper.cpp b/src/gui/widgets/helper.cpp index 0b6e09ce72b..476af44b12f 100644 --- a/src/gui/widgets/helper.cpp +++ b/src/gui/widgets/helper.cpp @@ -13,9 +13,10 @@ */ #include "gui/widgets/helper.hpp" -#include "gui/widgets/settings.hpp" -#include "serialization/string_utils.hpp" +#include "gui/widgets/settings.hpp" +#include "sdl_utils.hpp" +#include "serialization/string_utils.hpp" #include "log.hpp" #include "SDL_ttf.h" @@ -111,5 +112,67 @@ Uint32 decode_colour(const std::string& colour) return result; } +surface save_background(const surface& background, const SDL_Rect& rect) +{ + assert(background); + assert((background->flags & SDL_RLEACCEL) == 0); + assert(rect.x + rect.w < background->w); + assert(rect.y + rect.h < background->h); + + surface result(SDL_CreateRGBSurface(SDL_SWSURFACE, + rect.w, rect.h, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000)); + + { + // Extra scoping used for the surface_lock. + surface_lock src_lock(background); + surface_lock dst_lock(result); + + Uint32* src_pixels = reinterpret_cast(src_lock.pixels()); + Uint32* dst_pixels = reinterpret_cast(dst_lock.pixels()); + + unsigned offset = rect.y * background->w + rect.x; + for(unsigned y = 0; y < rect.h; ++y) { + for(unsigned x = 0; x < rect.w; ++x) { + + *dst_pixels++ = src_pixels[offset + x]; + + } + offset += background->w; + } + } + + return result; +} + +void restore_background(const surface& restorer, + surface& background, const SDL_Rect& rect) +{ + assert(background); + assert(restorer); + assert((background->flags & SDL_RLEACCEL) == 0); + assert((restorer->flags & SDL_RLEACCEL) == 0); + assert(rect.x + rect.w < background->w); + assert(rect.y + rect.h < background->h); + + { + // Extra scoping used for the surface_lock. + surface_lock src_lock(restorer); + surface_lock dst_lock(background); + + Uint32* src_pixels = reinterpret_cast(src_lock.pixels()); + Uint32* dst_pixels = reinterpret_cast(dst_lock.pixels()); + + unsigned offset = rect.y * background->w + rect.x; + for(unsigned y = 0; y < rect.h; ++y) { + for(unsigned x = 0; x < rect.w; ++x) { + + dst_pixels[offset + x] = *src_pixels++; + + } + offset += background->w; + } + } +} + } // namespace gui2 diff --git a/src/gui/widgets/helper.hpp b/src/gui/widgets/helper.hpp index 73c43262aa6..72b9e71b24b 100644 --- a/src/gui/widgets/helper.hpp +++ b/src/gui/widgets/helper.hpp @@ -19,6 +19,8 @@ #include +class surface; + namespace gui2 { // init needs a cfg object later to init the subsystem @@ -65,6 +67,33 @@ Uint32 decode_colour(const std::string& colour); int decode_font_style(const std::string& style); + +/** + * Copies a portion of a surface. + * + * Unlike get_surface_portion it copies rather then using SDL_Blit. Using + * SDL_Blit gives problems with transparent surfaces. + * + * @param background The surface to safe a portion from, this + * surface shouldn't be a RLE surface. + * @param rect The part of the surface to copy, the part of + * the rect should be entirely on the surface. + * + * @returns A copy of the wanted part of the background. + */ +surface save_background(const surface& background, const SDL_Rect& rect); + + +/** + * Copies one surface unto another one. + * + * @param restore The surface to copy to the background. + * @param background The surface to copy unto. + * @param rect The area to copy to on the background. + */ +void restore_background(const surface& restorer, + surface& background,const SDL_Rect& rect); + } // namespace gui2 #endif