handle wrong-sized saved images better
This commit is contained in:
parent
f476e7d526
commit
3f1d49626e
2 changed files with 192 additions and 159 deletions
|
|
@ -8,6 +8,14 @@ http://www.newbreedsoftware.com/tuxpaint/
|
||||||
|
|
||||||
|
|
||||||
2004.December.5 (0.9.15)
|
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
|
* Magic blur effect now gamma-aware, circular, and modifying all points
|
||||||
within the brush instead of just 25% of them.
|
within the brush instead of just 25% of them.
|
||||||
Albert Cahalan <albert@users.sf.net>
|
Albert Cahalan <albert@users.sf.net>
|
||||||
|
|
|
||||||
343
src/tuxpaint.c
343
src/tuxpaint.c
|
|
@ -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: */
|
/* Load current (if any) image: */
|
||||||
|
|
||||||
static void load_current(void)
|
static void load_current(void)
|
||||||
|
|
@ -9367,8 +9548,6 @@ static void load_current(void)
|
||||||
char * fname;
|
char * fname;
|
||||||
char ftmp[1024];
|
char ftmp[1024];
|
||||||
FILE * fi;
|
FILE * fi;
|
||||||
SDL_Rect dest;
|
|
||||||
|
|
||||||
|
|
||||||
/* Determine the current picture's ID: */
|
/* Determine the current picture's ID: */
|
||||||
|
|
||||||
|
|
@ -9425,15 +9604,7 @@ static void load_current(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SDL_FillRect(canvas, NULL, SDL_MapRGB(canvas->format, 255, 255, 255));
|
autoscale_copy_smear_free(tmp,canvas);
|
||||||
|
|
||||||
dest.x = (canvas->w - tmp->w) / 2;
|
|
||||||
dest.y = (canvas->h - tmp->h) / 2;
|
|
||||||
SDL_BlitSurface(tmp, NULL, canvas, &dest);
|
|
||||||
|
|
||||||
SDL_FreeSurface(tmp);
|
|
||||||
|
|
||||||
|
|
||||||
load_starter_id(file_id);
|
load_starter_id(file_id);
|
||||||
load_starter(starter_id);
|
load_starter(starter_id);
|
||||||
|
|
||||||
|
|
@ -10766,6 +10937,7 @@ static int do_quit(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Open a saved image: */
|
/* Open a saved image: */
|
||||||
|
|
||||||
#define PLACE_STARTERS_DIR 0
|
#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 last_click_which, last_click_button;
|
||||||
int places_to_look;
|
int places_to_look;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
do_setcursor(cursor_watch);
|
do_setcursor(cursor_watch);
|
||||||
|
|
||||||
|
|
||||||
/* Allocate some space: */
|
/* Allocate some space: */
|
||||||
|
|
||||||
things_alloced = 32;
|
things_alloced = 32;
|
||||||
|
|
@ -11730,19 +11899,8 @@ static int do_open(int want_new_tool)
|
||||||
free_surface(&img_starter_bkgd);
|
free_surface(&img_starter_bkgd);
|
||||||
starter_mirrored = 0;
|
starter_mirrored = 0;
|
||||||
starter_flipped = 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
|
autoscale_copy_smear_free(img,canvas);
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
cur_undo = 0;
|
cur_undo = 0;
|
||||||
oldest_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)
|
static TTF_Font *try_alternate_font(int language)
|
||||||
{
|
{
|
||||||
char str[128];
|
char str[128];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue