Moved get_non_transparent_portion to the more appropriate file

This commit is contained in:
Charles Dang 2016-11-13 22:22:14 +11:00
parent 291a751720
commit 0a325797b4
5 changed files with 79 additions and 87 deletions

View file

@ -2734,7 +2734,7 @@ image::TYPE display::get_image_type(const map_location& /*loc*/) {
void display::draw_image_for_report(surface& img, SDL_Rect& rect)
{
SDL_Rect visible_area = get_non_transparent_portion(img);
SDL_Rect visible_area = sdl::get_non_transparent_portion(img);
SDL_Rect target = rect;
if(visible_area.x != 0 || visible_area.y != 0 || visible_area.w != img->w || visible_area.h != img->h) {
if(visible_area.w == 0 || visible_area.h == 0) {

View file

@ -16,6 +16,8 @@
#include "sdl/rect.hpp"
#include "sdl/utils.hpp"
#include <iostream>
namespace sdl
{
@ -115,6 +117,77 @@ void draw_solid_tinted_rectangle(int x, int y, int w, int h,
fill_rect_alpha(rect,SDL_MapRGB(target->format,r,g,b),Uint8(alpha*255),target);
}
SDL_Rect get_non_transparent_portion(const surface &surf)
{
SDL_Rect res = {0,0,0,0};
surface nsurf(make_neutral_surface(surf));
if(nsurf == nullptr) {
std::cerr << "failed to make neutral surface\n";
return res;
}
const auto calc = [](Uint32 pixel) {
Uint8 alpha = pixel >> 24;
return alpha != 0x00;
};
surface_lock lock(nsurf);
const Uint32* const pixels = lock.pixels();
int n;
for(n = 0; n != nsurf->h; ++n) {
const Uint32* const start_row = pixels + n*nsurf->w;
const Uint32* const end_row = start_row + nsurf->w;
if(std::find_if(start_row,end_row,calc) != end_row)
break;
}
res.y = n;
for(n = 0; n != nsurf->h-res.y; ++n) {
const Uint32* const start_row = pixels + (nsurf->h-n-1)*surf->w;
const Uint32* const end_row = start_row + nsurf->w;
if(std::find_if(start_row,end_row,calc) != end_row)
break;
}
// The height is the height of the surface,
// minus the distance from the top and
// the distance from the bottom.
res.h = nsurf->h - res.y - n;
for(n = 0; n != nsurf->w; ++n) {
int y;
for(y = 0; y != nsurf->h; ++y) {
const Uint32 pixel = pixels[y*nsurf->w + n];
if(calc(pixel))
break;
}
if(y != nsurf->h)
break;
}
res.x = n;
for(n = 0; n != nsurf->w-res.x; ++n) {
int y;
for(y = 0; y != nsurf->h; ++y) {
const Uint32 pixel = pixels[y*nsurf->w + surf->w - n - 1];
if(calc(pixel))
break;
}
if(y != nsurf->h)
break;
}
res.w = nsurf->w - res.x - n;
return res;
}
} // namespace sdl

View file

@ -141,6 +141,11 @@ inline void fill_rect(surface& dst, SDL_Rect* dst_rect, const Uint32 color)
SDL_FillRect(dst, dst_rect, color);
}
/**
* Returns the dimensions of the non-transparent portion of an image
*/
SDL_Rect get_non_transparent_portion(const surface &surf);
} // namespace sdl
bool operator==(const SDL_Rect& a, const SDL_Rect& b);

View file

@ -2407,90 +2407,6 @@ surface get_surface_portion(const surface &src, SDL_Rect &area)
return dst;
}
namespace {
struct not_alpha
{
not_alpha() {}
// we assume neutral format
bool operator()(Uint32 pixel) const {
Uint8 alpha = pixel >> 24;
return alpha != 0x00;
}
};
}
SDL_Rect get_non_transparent_portion(const surface &surf)
{
SDL_Rect res = {0,0,0,0};
surface nsurf(make_neutral_surface(surf));
if(nsurf == nullptr) {
std::cerr << "failed to make neutral surface\n";
return res;
}
const not_alpha calc;
surface_lock lock(nsurf);
const Uint32* const pixels = lock.pixels();
int n;
for(n = 0; n != nsurf->h; ++n) {
const Uint32* const start_row = pixels + n*nsurf->w;
const Uint32* const end_row = start_row + nsurf->w;
if(std::find_if(start_row,end_row,calc) != end_row)
break;
}
res.y = n;
for(n = 0; n != nsurf->h-res.y; ++n) {
const Uint32* const start_row = pixels + (nsurf->h-n-1)*surf->w;
const Uint32* const end_row = start_row + nsurf->w;
if(std::find_if(start_row,end_row,calc) != end_row)
break;
}
// The height is the height of the surface,
// minus the distance from the top and
// the distance from the bottom.
res.h = nsurf->h - res.y - n;
for(n = 0; n != nsurf->w; ++n) {
int y;
for(y = 0; y != nsurf->h; ++y) {
const Uint32 pixel = pixels[y*nsurf->w + n];
if(calc(pixel))
break;
}
if(y != nsurf->h)
break;
}
res.x = n;
for(n = 0; n != nsurf->w-res.x; ++n) {
int y;
for(y = 0; y != nsurf->h; ++y) {
const Uint32 pixel = pixels[y*nsurf->w + surf->w - n - 1];
if(calc(pixel))
break;
}
if(y != nsurf->h)
break;
}
res.w = nsurf->w - res.x - n;
return res;
}
bool operator==(const SDL_Color& a, const SDL_Color& b) {
return a.r == b.r && a.g == b.g && a.b == b.b;
}

View file

@ -425,8 +425,6 @@ surface create_compatible_surface(const surface &surf, int width = -1, int heigh
void blit_surface(const surface& src,
const SDL_Rect* srcrect, surface& dst, const SDL_Rect* dstrect);
SDL_Rect get_non_transparent_portion(const surface &surf);
bool operator==(const SDL_Color& a, const SDL_Color& b);
bool operator!=(const SDL_Color& a, const SDL_Color& b);