2002-02-28 16:45:27 +00:00
|
|
|
#include <colors.h>
|
|
|
|
#include <image.h>
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// TImage
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
// Certified 99%
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
|
|
// @mfunc Setta l'immagine e le sue dimensioni
|
|
|
|
//
|
|
|
|
// @rdesc Ritorna l'immagine stessa
|
|
|
|
XVT_IMAGE TImage::set(
|
|
|
|
XVT_IMAGE i) // @parm Immagine da settare
|
|
|
|
|
|
|
|
// @comm L'immagine precedente viene cancellata quando viene settata una nuova
|
|
|
|
{
|
|
|
|
if (_image)
|
|
|
|
xvt_image_destroy(_image);
|
|
|
|
_image = i;
|
|
|
|
if (i)
|
|
|
|
{
|
|
|
|
_src.left = _src.top = 0;
|
|
|
|
short w, h;
|
|
|
|
xvt_image_get_dimensions(i, &w, &h);
|
|
|
|
_src.right = w;
|
|
|
|
_src.bottom = h;
|
|
|
|
_dst = _src;
|
|
|
|
}
|
|
|
|
return _image;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
2007-03-06 16:37:44 +00:00
|
|
|
bool TImage::build_filename(TFilename & file)
|
|
|
|
{
|
|
|
|
const char * const exts[] = {"gif", "png", "bmp", "jpg", NULL};
|
|
|
|
bool ok = false;
|
|
|
|
|
|
|
|
if (file.ext()[0] != '\0')
|
|
|
|
ok = file.custom_path();
|
|
|
|
if (!ok)
|
|
|
|
{
|
|
|
|
for (int i = 0; !ok && exts[i]; i++)
|
|
|
|
{
|
|
|
|
file.ext(exts[i]);
|
|
|
|
ok = file.custom_path();
|
|
|
|
if (!ok)
|
|
|
|
{
|
|
|
|
TFilename res(file);
|
|
|
|
|
|
|
|
res.insert("res/");
|
|
|
|
ok = res.exist();
|
|
|
|
if (ok)
|
|
|
|
file = res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
2002-02-28 16:45:27 +00:00
|
|
|
// @mfunc Legge l'immagine dal file
|
|
|
|
XVT_IMAGE TImage::load(
|
|
|
|
const char* n) // @parm Nome del file contenente l'immagine
|
2007-03-06 16:37:44 +00:00
|
|
|
{
|
|
|
|
TFilename f(n);
|
|
|
|
XVT_IMAGE i = NULL;
|
|
|
|
|
|
|
|
if (build_filename(f))
|
|
|
|
{
|
|
|
|
i = xvt_image_read(f);
|
|
|
|
if (i != NULL)
|
|
|
|
set(i);
|
|
|
|
}
|
2002-02-28 16:45:27 +00:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
XVT_IMAGE TImage::load(short id)
|
|
|
|
{
|
|
|
|
return set(xvt_res_get_image(id));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
TImage::TImage(const char* n) : _image(NULL)
|
|
|
|
{
|
2005-09-19 12:45:16 +00:00
|
|
|
if (n && *n)
|
|
|
|
load(n);
|
2002-02-28 16:45:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
TImage::TImage(short id) : _image(NULL)
|
|
|
|
{
|
|
|
|
if (id > 0) load(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 90%
|
|
|
|
TImage::TImage(const TImage& im, short w, short h) : _image(NULL)
|
|
|
|
{
|
|
|
|
const XVT_IMAGE_FORMAT fmt = xvt_image_get_format(im._image);
|
|
|
|
if (w < 0 || h < 0)
|
|
|
|
{
|
|
|
|
short iw, ih;
|
|
|
|
xvt_image_get_dimensions(im._image, &iw, &ih);
|
|
|
|
if (w < 0) w = iw;
|
|
|
|
if (h < 0) h = ih;
|
|
|
|
}
|
2004-03-12 16:01:27 +00:00
|
|
|
set(xvt_image_create(fmt, w, h, 0L));
|
2002-02-28 16:45:27 +00:00
|
|
|
|
|
|
|
if (ok())
|
|
|
|
xvt_image_transfer(_image, (XVT_IMAGE)im._image, &_src, (RCT*)&im._src);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 90%
|
|
|
|
TImage::TImage(short w, short h, XVT_IMAGE_FORMAT fmt) : _image(NULL)
|
|
|
|
{
|
2004-03-12 16:01:27 +00:00
|
|
|
set(xvt_image_create(fmt, w, h, 0L));
|
2002-02-28 16:45:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
TImage::~TImage()
|
|
|
|
{
|
|
|
|
if (_image != NULL)
|
|
|
|
xvt_image_destroy(_image);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
|
|
// @mfunc Permette di settare la posizione della figura
|
|
|
|
void TImage::set_pos(
|
|
|
|
int x, // @parm Coordinata x dell'immagine da settare
|
|
|
|
int y) // @parm Coordinata y dell'immagine da settare
|
|
|
|
|
|
|
|
// @comm Permette di aggiornare il mebro <p _dst> sommandogli i valori
|
|
|
|
// passati con <p x> e <p y>
|
|
|
|
{
|
|
|
|
_dst = _src;
|
|
|
|
xvt_rect_offset(&_dst, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
void TImage::draw(WINDOW w) const
|
|
|
|
{
|
|
|
|
xvt_dwin_draw_image(w, _image, (RCT*)&_dst, (RCT*)&_src);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
|
|
// @mfunc Permette di gestire il disegno dell'immagine sullo schermo
|
|
|
|
void TImage::draw(
|
|
|
|
WINDOW w, // @parm Immagine da disegnare
|
|
|
|
int x, // @parm Coordinata x in cui disegnare l'immagine
|
|
|
|
int y) const // @parm Coordinata y in cui disegnare l'immagine
|
|
|
|
// @parm RCT& | _src | Rettangolo contenente l'immagine da disegnare
|
|
|
|
// @parm RCT& | _dst | Rettangolo in cui disegnare l'immagine
|
|
|
|
|
|
|
|
// @syntax void draw(WINDOW w);
|
|
|
|
// @syntax void draw(WINDOW w, int x, int y);
|
|
|
|
// @syntax void draw(WINDOW w, const RCT& dst);
|
|
|
|
// @syntax void draw(WINDOW w, const RCT& dst, const RCT& src);
|
|
|
|
|
|
|
|
// @comm Nel caso utilizzo l'ultima sintassi e' possibile disegnare solo una parte
|
|
|
|
// dell'immagine, precisamente delle dimensioni <p _dst> se tale parametro e'
|
|
|
|
// minore di <p _pst>
|
|
|
|
{
|
|
|
|
RCT dst = _src;
|
|
|
|
xvt_rect_offset(&dst, x, y);
|
|
|
|
xvt_dwin_draw_image(w, _image, &dst, (RCT*)&_src);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
void TImage::draw(WINDOW w, const RCT& dst) const
|
|
|
|
{
|
|
|
|
xvt_dwin_draw_image(w, _image, (RCT*)&dst, (RCT*)&_src);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
void TImage::draw(WINDOW w, const RCT& dst, const RCT& src) const
|
|
|
|
{
|
|
|
|
xvt_dwin_draw_image(w, _image, (RCT*)&dst, (RCT*)&src);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 99%
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
|
|
// @mfunc Fa corrispondere la palette della finestra a quella dell'immagine
|
|
|
|
void TImage::set_palette(
|
|
|
|
WINDOW w) const // @parm Finestra a cui settare la palette
|
|
|
|
{
|
|
|
|
XVT_PALETTE wp = xvt_vobj_get_palet(w);
|
|
|
|
if (wp != NULL)
|
|
|
|
{
|
2004-03-12 16:01:27 +00:00
|
|
|
XVT_PALETTE p = xvt_palet_create(XVT_PALETTE_USER, 0L);
|
2002-02-28 16:45:27 +00:00
|
|
|
const int ncolors = xvt_palet_get_ncolors(wp);
|
|
|
|
COLOR* color = new COLOR[ncolors];
|
|
|
|
xvt_palet_get_colors(wp, color, ncolors);
|
|
|
|
xvt_palet_add_colors(p, color, ncolors);
|
|
|
|
delete color;
|
|
|
|
xvt_palet_add_colors_from_image(p, _image);
|
|
|
|
xvt_vobj_set_palet(w, p);
|
|
|
|
xvt_palet_destroy(wp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 100%
|
|
|
|
void TImage::set_clut(byte n, COLOR c)
|
|
|
|
{
|
|
|
|
if (xvt_image_get_format(_image) == XVT_IMAGE_CL8)
|
|
|
|
xvt_image_set_clut(_image, n, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TImage::set_pixel(int x, int y, COLOR col)
|
|
|
|
{
|
|
|
|
xvt_image_set_pixel(_image, x, y, col);
|
|
|
|
}
|
|
|
|
|
|
|
|
COLOR TImage::get_pixel(int x, int y) const
|
|
|
|
{
|
|
|
|
return xvt_image_get_pixel(_image, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Certified 99%
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
|
|
// @mfunc Setta i colori dell'immagine in modo da renderla trasparente
|
|
|
|
void TImage::convert_to_default_colors()
|
|
|
|
|
|
|
|
// @comm Legge nell'immagine i colori CYAN e DARK_CYAN e li setta a seconda del colore
|
|
|
|
// della finestra per fare in modo di rendere trasparenti tali colori.
|
|
|
|
{
|
|
|
|
if (MASK_BACK_COLOR != COLOR_DKCYAN)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (xvt_image_get_format(_image) == XVT_IMAGE_CL8)
|
|
|
|
{
|
|
|
|
for (int index = xvt_image_get_ncolors(_image)-1; index >=0; index--)
|
|
|
|
{
|
|
|
|
const COLOR c = xvt_image_get_clut(_image, index) & 0x00FFFFFF;
|
|
|
|
switch (c)
|
|
|
|
{
|
2007-03-07 13:49:11 +00:00
|
|
|
case COLOR_DKCYAN & 0x00FFFFFF: xvt_image_set_clut(_image, index, MASK_BACK_COLOR); break;
|
|
|
|
case COLOR_CYAN & 0x00FFFFFF: xvt_image_set_clut(_image, index, MASK_LIGHT_COLOR); break;
|
|
|
|
case COLOR_GRAY & 0x00FFFFFF: xvt_image_set_clut(_image, index, MASK_DARK_COLOR); break;
|
|
|
|
default: break;
|
2002-02-28 16:45:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
short dx, dy; xvt_image_get_dimensions(_image, &dx, &dy);
|
|
|
|
for (short y = 0; y < dy; y++) for (short x = 0; x < dx; x++)
|
|
|
|
{
|
|
|
|
const COLOR c = get_pixel(x, y) & 0x00FFFFFF;
|
|
|
|
switch (c)
|
|
|
|
{
|
2007-03-07 13:49:11 +00:00
|
|
|
case COLOR_DKCYAN & 0x00FFFFFF: set_pixel(x, y, MASK_BACK_COLOR); break;
|
|
|
|
case COLOR_CYAN & 0x00FFFFFF : set_pixel(x, y, MASK_LIGHT_COLOR); break;
|
|
|
|
case COLOR_GRAY & 0x00FFFFFF : set_pixel(x, y, MASK_DARK_COLOR); break;
|
|
|
|
default: break;
|
2002-02-28 16:45:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// @mfunc Setta i colori dell'immagine in modo da renderla trasparente
|
|
|
|
void TImage::convert_transparent_color(COLOR transparent)
|
|
|
|
// @comm Legge nell'immagine i pixel uguali a quello in alto a sinistra e li setta
|
|
|
|
// uguali allo sfondo delle maschere
|
|
|
|
{
|
|
|
|
if (_image == NULL)
|
|
|
|
return; // Null image
|
|
|
|
|
2004-05-13 15:09:51 +00:00
|
|
|
const COLOR trans = get_pixel(0,0) & 0x00FFFFFF;
|
2002-02-28 16:45:27 +00:00
|
|
|
if (trans == (transparent & 0x00FFFFFF))
|
|
|
|
return; // Nothing to do
|
|
|
|
|
|
|
|
if (xvt_image_get_format(_image) == XVT_IMAGE_CL8)
|
|
|
|
{
|
|
|
|
for (int index = xvt_image_get_ncolors(_image)-1; index >=0; index--)
|
|
|
|
if (trans == (xvt_image_get_clut(_image, index) & 0x00FFFFFF))
|
|
|
|
{
|
|
|
|
xvt_image_set_clut(_image, index, transparent);
|
|
|
|
// break; don't break: replace all colors equal to upper left in the palette
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
short dx, dy; xvt_image_get_dimensions(_image, &dx, &dy);
|
|
|
|
for (short y = 0; y < dy; y++) for (short x = 0; x < dx; x++)
|
|
|
|
{
|
2003-05-13 15:12:54 +00:00
|
|
|
const COLOR c = get_pixel(x, y);
|
2004-05-13 15:09:51 +00:00
|
|
|
if ((c & 0x00FFFFFF) == trans)
|
2003-01-07 12:20:49 +00:00
|
|
|
set_pixel(x, y, transparent);
|
2002-02-28 16:45:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-07 13:49:11 +00:00
|
|
|
inline COLOR btncolor2btngray(COLOR color, bool use_btn)
|
|
|
|
{
|
|
|
|
static COLOR last_color = -1, last_gray = -1;
|
|
|
|
if (color != last_color)
|
|
|
|
{
|
|
|
|
last_gray = grayed_color(last_color = color);
|
|
|
|
if (use_btn)
|
|
|
|
{
|
|
|
|
// Prendo una sola componente del grigio: tanto sono identiche
|
|
|
|
const int g = XVT_COLOR_GET_RED(last_gray);
|
|
|
|
if (g > 128) // Chiaro
|
|
|
|
last_gray = blend_colors(BTN_LIGHT_COLOR, BTN_BACK_COLOR, (g-128.0)/128.0);
|
|
|
|
else // Scuro
|
|
|
|
last_gray = blend_colors(BTN_BACK_COLOR, BTN_DARK_COLOR, g/128.0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return last_gray;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TImage::fade_to_gray(bool use_btn_colors)
|
2007-02-23 08:17:38 +00:00
|
|
|
// @comm Legge nell'immagine i pixel diversi da quello in alto a sinistra e li setta
|
|
|
|
// in grigio
|
|
|
|
{
|
|
|
|
if (_image == NULL)
|
|
|
|
return; // Null image
|
|
|
|
|
|
|
|
const COLOR trans = get_pixel(0,0) & 0x00FFFFFF;
|
2007-03-07 13:49:11 +00:00
|
|
|
btncolor2btngray(trans, use_btn_colors); // Reset color conversion
|
2007-02-23 08:17:38 +00:00
|
|
|
if (xvt_image_get_format(_image) == XVT_IMAGE_CL8)
|
|
|
|
{
|
|
|
|
for (int index = xvt_image_get_ncolors(_image)-1; index >=0; index--)
|
|
|
|
{
|
|
|
|
COLOR pixie = xvt_image_get_clut(_image, index) & 0x00FFFFFF;
|
|
|
|
if (pixie != trans)
|
2007-03-07 13:49:11 +00:00
|
|
|
xvt_image_set_clut(_image, index, btncolor2btngray(pixie, use_btn_colors));
|
2007-02-23 08:17:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
short dx, dy; xvt_image_get_dimensions(_image, &dx, &dy);
|
|
|
|
for (short y = 0; y < dy; y++) for (short x = 0; x < dx; x++)
|
|
|
|
{
|
|
|
|
COLOR pixie = get_pixel(x, y) & 0x00FFFFFF;
|
|
|
|
if (pixie != trans)
|
2007-03-07 13:49:11 +00:00
|
|
|
set_pixel(x, y, btncolor2btngray(pixie, use_btn_colors));
|
2007-02-23 08:17:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|