handle wrong-sized saved images better

This commit is contained in:
Albert Cahalan 2004-12-09 23:12:45 +00:00
parent f476e7d526
commit 3f1d49626e
2 changed files with 192 additions and 159 deletions

View file

@ -8,6 +8,14 @@ http://www.newbreedsoftware.com/tuxpaint/
2004.December.5 (0.9.15)
* Somewhat better treatment of wrong-sized images when loading them.
It works well for typical kid drawings, as long as objects don't
touch the edge of the screen. (the earth and sky -- and anything
else at the edge -- get extended to fill the space) This could be
better done with wavelets I think, or some vector-based notion of
what lies at the edge of the screen. Starters, as usual, need work.
Albert Cahalan <albert@users.sf.net>
* Magic blur effect now gamma-aware, circular, and modifying all points
within the brush instead of just 25% of them.
Albert Cahalan <albert@users.sf.net>

View file

@ -9359,6 +9359,187 @@ static void do_wait(void)
}
static void autoscale_copy_smear_free(SDL_Surface *src, SDL_Surface *dst)
{
SDL_Surface *src1;
SDL_Rect dest;
// What to do when in 640x480 mode, and loading an
// 800x600 (or larger) image!? Scale it. Starters must
// be scaled too. Keep the pixels square though, filling
// in the gaps via a smear.
if(src->w != dst->w || src->h != dst->h)
{
if(src->w / (float)dst->w > src->h / (float)dst->h)
src1 = thumbnail(src, dst->w, src->h*dst->w/src->w, 0);
else
src1 = thumbnail(src, src->w*dst->h/src->h, dst->h, 0);
SDL_FreeSurface(src);
src = src1;
}
dest.x = (dst->w - src->w) / 2;
dest.y = (dst->h - src->h) / 2;
SDL_BlitSurface(src, NULL, dst, &dest);
if(src->w != dst->w)
{
// we know that the heights match, and src is narrower
SDL_Rect sour;
int i = (dst->w - src->w) / 2;
sour.w = 1;
sour.x = 0;
sour.h = src->h;
sour.y = 0;
while(i-- > 0)
{
dest.x = i;
SDL_BlitSurface(src, &sour, dst, &dest);
}
sour.x = src->w - 1;
i = (dst->w - src->w) / 2 + src->w - 1;
while(++i < dst->w)
{
dest.x = i;
SDL_BlitSurface(src, &sour, dst, &dest);
}
}
if(src->h != dst->h)
{
// we know that the widths match, and src is shorter
SDL_Rect sour;
int i = (dst->h - src->h) / 2;
sour.w = src->w;
sour.x = 0;
sour.h = 1;
sour.y = 0;
while(i-- > 0)
{
dest.y = i;
SDL_BlitSurface(src, &sour, dst, &dest);
}
sour.y = src->h - 1;
i = (dst->h - src->h) / 2 + src->h - 1;
while(++i < dst->h)
{
dest.y = i;
SDL_BlitSurface(src, &sour, dst, &dest);
}
}
SDL_FreeSurface(src);
}
static void load_starter_id(char * saved_id)
{
char * rname;
char fname[32];
FILE * fi;
snprintf(fname, sizeof(fname), "saved/%s.dat", saved_id);
rname = get_fname(fname);
starter_id[0] = '\0';
fi = fopen(rname, "r");
if (fi != NULL)
{
fgets(starter_id, sizeof(starter_id), fi);
starter_id[strlen(starter_id) - 1] = '\0';
fscanf(fi, "%d", &starter_mirrored);
fscanf(fi, "%d", &starter_flipped);
fclose(fi);
}
free(rname);
}
static void load_starter(char * img_id)
{
char * dirname;
char fname[256];
SDL_Surface * tmp_surf;
/* Determine path to starter files: */
dirname = strdup(DATA_PREFIX "starters");
/* Clear them to NULL first: */
img_starter = NULL;
img_starter_bkgd = NULL;
/* Load the core image: */
snprintf(fname, sizeof(fname), "%s/%s.png", dirname, img_id);
tmp_surf = IMG_Load(fname);
if (tmp_surf != NULL)
{
img_starter = SDL_DisplayFormatAlpha(tmp_surf);
SDL_FreeSurface(tmp_surf);
}
if (img_starter != NULL &&
(img_starter->w != canvas->w || img_starter->h != canvas->h))
{
tmp_surf = img_starter;
img_starter = SDL_CreateRGBSurface(canvas->flags,
canvas->w, canvas->h,
tmp_surf->format->BitsPerPixel,
tmp_surf->format->Rmask,
tmp_surf->format->Gmask,
tmp_surf->format->Bmask,
tmp_surf->format->Amask);
SDL_SetAlpha(tmp_surf, 0, 0);
autoscale_copy_smear_free(tmp_surf,img_starter);
}
/* Try to load the a background image: */
/* (JPEG first) */
snprintf(fname, sizeof(fname), "%s/%s-back.jpeg", dirname, img_id);
tmp_surf = IMG_Load(fname);
/* (Failed? Try PNG next) */
if (tmp_surf == NULL)
{
snprintf(fname, sizeof(fname), "%s/%s-back.png", dirname, img_id);
tmp_surf = IMG_Load(fname);
}
if (tmp_surf != NULL)
{
img_starter_bkgd = SDL_DisplayFormat(tmp_surf);
SDL_FreeSurface(tmp_surf);
}
if (img_starter_bkgd != NULL &&
(img_starter_bkgd->w != canvas->w || img_starter_bkgd->h != canvas->h))
{
tmp_surf = img_starter_bkgd;
img_starter_bkgd = SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w, canvas->h,
canvas->format->BitsPerPixel,
canvas->format->Rmask,
canvas->format->Gmask,
canvas->format->Bmask,
0);
autoscale_copy_smear_free(tmp_surf,img_starter_bkgd);
}
free(dirname);
}
/* Load current (if any) image: */
static void load_current(void)
@ -9367,8 +9548,6 @@ static void load_current(void)
char * fname;
char ftmp[1024];
FILE * fi;
SDL_Rect dest;
/* Determine the current picture's ID: */
@ -9425,15 +9604,7 @@ static void load_current(void)
}
else
{
SDL_FillRect(canvas, NULL, SDL_MapRGB(canvas->format, 255, 255, 255));
dest.x = (canvas->w - tmp->w) / 2;
dest.y = (canvas->h - tmp->h) / 2;
SDL_BlitSurface(tmp, NULL, canvas, &dest);
SDL_FreeSurface(tmp);
autoscale_copy_smear_free(tmp,canvas);
load_starter_id(file_id);
load_starter(starter_id);
@ -10766,6 +10937,7 @@ static int do_quit(void)
}
/* Open a saved image: */
#define PLACE_STARTERS_DIR 0
@ -10798,11 +10970,8 @@ static int do_open(int want_new_tool)
int last_click_which, last_click_button;
int places_to_look;
do_setcursor(cursor_watch);
/* Allocate some space: */
things_alloced = 32;
@ -11730,19 +11899,8 @@ static int do_open(int want_new_tool)
free_surface(&img_starter_bkgd);
starter_mirrored = 0;
starter_flipped = 0;
SDL_FillRect(canvas, NULL,
SDL_MapRGB(canvas->format, 255, 255, 255));
/* FIXME: What to do when in 640x480 mode, and loading an
800x600 (or larger) image!? */
dest.x = (canvas->w - img->w) / 2;
dest.y = (canvas->h - img->h) / 2;
SDL_BlitSurface(img, NULL, canvas, &dest);
SDL_FreeSurface(img);
autoscale_copy_smear_free(img,canvas);
cur_undo = 0;
oldest_undo = 0;
@ -13852,139 +14010,6 @@ static int mySDL_PollEvent(SDL_Event *event)
}
static void load_starter_id(char * saved_id)
{
char * rname;
char fname[32];
FILE * fi;
snprintf(fname, sizeof(fname), "saved/%s.dat", saved_id);
rname = get_fname(fname);
starter_id[0] = '\0';
fi = fopen(rname, "r");
if (fi != NULL)
{
fgets(starter_id, sizeof(starter_id), fi);
starter_id[strlen(starter_id) - 1] = '\0';
fscanf(fi, "%d", &starter_mirrored);
fscanf(fi, "%d", &starter_flipped);
fclose(fi);
}
free(rname);
}
static void load_starter(char * img_id)
{
char * dirname;
char fname[256];
SDL_Surface * tmp_surf;
SDL_Rect dest;
/* Determine path to starter files: */
/* FIXME: On Windows, MacOSX, BeOS, etc. -- do it their way! */
#if defined(WIN32) || defined(__BEOS__)
dirname = strdup(DATA_PREFIX "starters");
#else
dirname = strdup("/usr/local/share/tuxpaint/starters");
#endif
/* Clear them to NULL first: */
img_starter = NULL;
img_starter_bkgd = NULL;
/* Load the core image: */
snprintf(fname, sizeof(fname), "%s/%s.png", dirname, img_id);
tmp_surf = IMG_Load(fname);
if (tmp_surf != NULL)
{
img_starter = SDL_DisplayFormatAlpha(tmp_surf);
SDL_FreeSurface(tmp_surf);
}
if (img_starter != NULL &&
(img_starter->w != canvas->w || img_starter->h != canvas->h))
{
tmp_surf = img_starter;
img_starter = SDL_CreateRGBSurface(canvas->flags,
canvas->w, canvas->h,
tmp_surf->format->BitsPerPixel,
tmp_surf->format->Rmask,
tmp_surf->format->Gmask,
tmp_surf->format->Bmask,
tmp_surf->format->Amask);
SDL_SetAlpha(tmp_surf, 0, 0);
if (img_starter != NULL)
{
dest.x = (canvas->w - tmp_surf->w) / 2;
dest.y = (canvas->h - tmp_surf->h) / 2;
SDL_BlitSurface(tmp_surf, NULL, img_starter, &dest);
SDL_FreeSurface(tmp_surf);
}
}
/* Try to load the a background image: */
/* (JPEG first) */
snprintf(fname, sizeof(fname), "%s/%s-back.jpeg", dirname, img_id);
tmp_surf = IMG_Load(fname);
/* (Failed? Try PNG next) */
if (tmp_surf == NULL)
{
snprintf(fname, sizeof(fname), "%s/%s-back.png", dirname, img_id);
tmp_surf = IMG_Load(fname);
}
if (tmp_surf != NULL)
{
img_starter_bkgd = SDL_DisplayFormat(tmp_surf);
SDL_FreeSurface(tmp_surf);
}
if (img_starter_bkgd != NULL &&
(img_starter_bkgd->w != canvas->w || img_starter_bkgd->h != canvas->h))
{
tmp_surf = img_starter_bkgd;
img_starter_bkgd = SDL_CreateRGBSurface(SDL_SWSURFACE,
canvas->w, canvas->h,
canvas->format->BitsPerPixel,
canvas->format->Rmask,
canvas->format->Gmask,
canvas->format->Bmask,
0);
if (img_starter_bkgd != NULL)
{
dest.x = (canvas->w - tmp_surf->w) / 2;
dest.y = (canvas->h - tmp_surf->h) / 2;
SDL_BlitSurface(tmp_surf, NULL, img_starter_bkgd, &dest);
SDL_FreeSurface(tmp_surf);
}
}
free(dirname);
}
static TTF_Font *try_alternate_font(int language)
{
char str[128];