Added stretch_surface_horizontal and stretch_surface_vertical.
The functions stretch a surface based on the first row/column. This looks better for the widget borders as scale_surface and should be faster (not tested). Added the option to the widget library to use these functions and convert the window borders to use the new option.
This commit is contained in:
parent
1efde93aa0
commit
8bcb690932
5 changed files with 155 additions and 4 deletions
|
@ -48,6 +48,7 @@
|
|||
x = 5
|
||||
y = 0
|
||||
w = "(width - 14)"
|
||||
stretch = "true"
|
||||
name = "dialogs/opaque-border-top.png"
|
||||
[/image]
|
||||
|
||||
|
@ -61,6 +62,7 @@
|
|||
x = "(width - 9)"
|
||||
y = 5
|
||||
h = "(height - 14)"
|
||||
stretch = "true"
|
||||
name = "dialogs/opaque-border-right.png"
|
||||
[/image]
|
||||
|
||||
|
@ -74,6 +76,7 @@
|
|||
x = 5
|
||||
y = "(height - 9)"
|
||||
w = "(width - 14)"
|
||||
stretch = "true"
|
||||
name = "dialogs/opaque-border-bottom.png"
|
||||
[/image]
|
||||
|
||||
|
@ -87,6 +90,7 @@
|
|||
x = 0
|
||||
y = 5
|
||||
h = "(height - 14)"
|
||||
stretch = "true"
|
||||
name = "dialogs/opaque-border-left.png"
|
||||
[/image]
|
||||
|
||||
|
|
|
@ -596,7 +596,8 @@ tcanvas::timage::timage(const config& cfg) :
|
|||
h_formula_(""),
|
||||
src_clip_(),
|
||||
dst_clip_(),
|
||||
image_()
|
||||
image_(),
|
||||
stretch_(utils::string_bool(cfg["stretch"]))
|
||||
{
|
||||
/*WIKI
|
||||
* [image]
|
||||
|
@ -608,6 +609,11 @@ tcanvas::timage::timage(const config& cfg) :
|
|||
* image will be scaled to the desired width.
|
||||
* h (f_unsigned = 0) The height of the image, if not zero the
|
||||
* image will be scaled to the desired height.
|
||||
* stretch (bool = false) Border images often need to be either
|
||||
* stretched in the width or the height. If
|
||||
* that's the case use stretch. It only works
|
||||
* if only the heigth or the width is not zero.
|
||||
* It will copy the first pixel the the others.
|
||||
* name (string = "") The name of the image.
|
||||
* debug = (string = "") Debug message to show upon creation
|
||||
* this message is not stored.
|
||||
|
@ -668,18 +674,37 @@ void tcanvas::timage::draw(surface& canvas,
|
|||
|
||||
// Test whether we need to scale and do the scaling if needed.
|
||||
if(w || h) {
|
||||
bool done = false;
|
||||
bool stretch = stretch_ && (!!w ^ !!h);
|
||||
if(!w) {
|
||||
if(stretch) {
|
||||
DBG_G_D << "Image: vertical stretch from " << image_->w
|
||||
<< ',' << image_->h << " to a height of " << h << ".\n";
|
||||
|
||||
surf = stretch_surface_vertical(image_, h);
|
||||
done = true;
|
||||
}
|
||||
w = image_->w;
|
||||
}
|
||||
|
||||
if(!h) {
|
||||
if(stretch) {
|
||||
DBG_G_D << "Image: horizontal stretch from " << image_->w
|
||||
<< ',' << image_->h << " to a width of " << w << ".\n";
|
||||
|
||||
surf = stretch_surface_horizontal(image_, w);
|
||||
done = true;
|
||||
}
|
||||
h = image_->h;
|
||||
}
|
||||
|
||||
DBG_G_D << "Image: scaling from " << image_->w
|
||||
<< ',' << image_->h << " to " << w << ',' << h << ".\n";
|
||||
if(!done) {
|
||||
|
||||
surf = scale_surface(image_, w, h);
|
||||
DBG_G_D << "Image: scaling from " << image_->w
|
||||
<< ',' << image_->h << " to " << w << ',' << h << ".\n";
|
||||
|
||||
surf = scale_surface(image_, w, h);
|
||||
}
|
||||
src_clip.w = w;
|
||||
src_clip.h = h;
|
||||
} else {
|
||||
|
|
|
@ -147,6 +147,8 @@ public:
|
|||
SDL_Rect src_clip_;
|
||||
SDL_Rect dst_clip_;
|
||||
surface image_;
|
||||
|
||||
bool stretch_;
|
||||
};
|
||||
|
||||
//! Definition of a text shape.
|
||||
|
|
|
@ -151,6 +151,119 @@ surface create_optimized_surface(surface const &surf)
|
|||
return result;
|
||||
}
|
||||
|
||||
//! Streches a surface in the horizontal direction.
|
||||
//!
|
||||
//! The stretches a surface it uses the first pixel in the horizontal
|
||||
//! direction of the original surface and copies that to the destination.
|
||||
//! This means only the first column of the original is used for the destination.
|
||||
//! @param surf The source surface.
|
||||
//! @param w The width of the resulting surface.
|
||||
//!
|
||||
//! @return An optimized surface.
|
||||
//! returned.
|
||||
//! @retval 0 Returned upon error.
|
||||
//! @retval surf Returned if w == surf->w.
|
||||
surface stretch_surface_horizontal(const surface& surf, const unsigned w)
|
||||
{
|
||||
// Since SDL version 1.1.5 0 is transparent, before 255 was transparent.
|
||||
assert(SDL_ALPHA_TRANSPARENT==0);
|
||||
|
||||
if(surf == NULL)
|
||||
return NULL;
|
||||
|
||||
if(w == surf->w) {
|
||||
return surf;
|
||||
}
|
||||
assert(w > 0);
|
||||
|
||||
surface dst(SDL_CreateRGBSurface(SDL_SWSURFACE,
|
||||
w, surf->h, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000));
|
||||
|
||||
surface src(make_neutral_surface(surf));
|
||||
// Now both surfaces are always in the "neutral" pixel format
|
||||
|
||||
if(src == NULL || dst == NULL) {
|
||||
std::cerr << "Could not create surface to scale onto\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
// Extra scoping used for the surface_lock.
|
||||
surface_lock src_lock(src);
|
||||
surface_lock dst_lock(dst);
|
||||
|
||||
Uint32* const src_pixels = reinterpret_cast<Uint32*>(src_lock.pixels());
|
||||
Uint32* dst_pixels = reinterpret_cast<Uint32*>(dst_lock.pixels());
|
||||
|
||||
for(unsigned y = 0; y < src->h; ++y) {
|
||||
const Uint32 pixel = src_pixels [y * src->w];
|
||||
for(unsigned x = 0; x < w; ++x) {
|
||||
|
||||
*dst_pixels++ = pixel;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return create_optimized_surface(dst);
|
||||
}
|
||||
|
||||
//! Streches a surface in the vertical direction.
|
||||
//!
|
||||
//! The stretches a surface it uses the first pixel in the vertical
|
||||
//! direction of the original surface and copies that to the destination.
|
||||
//! This means only the first row of the original is used for the destination.
|
||||
//! @param surf The source surface.
|
||||
//! @param h The height of the resulting surface.
|
||||
//!
|
||||
//! @return An optimized surface.
|
||||
//! returned.
|
||||
//! @retval 0 Returned upon error.
|
||||
//! @retval surf Returned if h == surf->h.
|
||||
surface stretch_surface_vertical(const surface& surf, const unsigned h)
|
||||
{
|
||||
// Since SDL version 1.1.5 0 is transparent, before 255 was transparent.
|
||||
assert(SDL_ALPHA_TRANSPARENT==0);
|
||||
|
||||
if(surf == NULL)
|
||||
return NULL;
|
||||
|
||||
if(h == surf->h) {
|
||||
return surf;
|
||||
}
|
||||
assert(h > 0);
|
||||
|
||||
surface dst(SDL_CreateRGBSurface(SDL_SWSURFACE,
|
||||
surf->w, h, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000));
|
||||
|
||||
surface src(make_neutral_surface(surf));
|
||||
// Now both surfaces are always in the "neutral" pixel format
|
||||
|
||||
if(src == NULL || dst == NULL) {
|
||||
std::cerr << "Could not create surface to scale onto\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
// Extra scoping used for the surface_lock.
|
||||
surface_lock src_lock(src);
|
||||
surface_lock dst_lock(dst);
|
||||
|
||||
Uint32* const src_pixels = reinterpret_cast<Uint32*>(src_lock.pixels());
|
||||
Uint32* dst_pixels = reinterpret_cast<Uint32*>(dst_lock.pixels());
|
||||
|
||||
for(unsigned y = 0; y < h; ++y) {
|
||||
for(unsigned x = 0; x < src->w; ++x) {
|
||||
|
||||
*dst_pixels++ = src_pixels[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return create_optimized_surface(dst);
|
||||
}
|
||||
|
||||
|
||||
// NOTE: Don't pass this function 0 scaling arguments.
|
||||
surface scale_surface(surface const &surf, int w, int h)
|
||||
{
|
||||
|
|
|
@ -119,6 +119,13 @@ bool operator<(const surface& a, const surface& b);
|
|||
|
||||
surface make_neutral_surface(surface const &surf);
|
||||
surface create_optimized_surface(surface const &surf);
|
||||
|
||||
//! Streches a surface in the horizontal direction.
|
||||
surface stretch_surface_horizontal(const surface& surf, const unsigned w);
|
||||
|
||||
//! Streches a surface in the vertical direction.
|
||||
surface stretch_surface_vertical(const surface& surf, const unsigned h);
|
||||
|
||||
surface scale_surface(surface const &surf, int w, int h);
|
||||
surface scale_surface_blended(surface const &surf, int w, int h);
|
||||
surface adjust_surface_colour(surface const &surf, int r, int g, int b);
|
||||
|
|
Loading…
Add table
Reference in a new issue