mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
166 lines
4.1 KiB
C++
166 lines
4.1 KiB
C++
|
#include "Icon.h"
|
||
|
#include "debug.h"
|
||
|
|
||
|
// Default icon
|
||
|
#include "tux.xpm"
|
||
|
|
||
|
#define I(i) ((Fl_Image*)i)
|
||
|
|
||
|
static Fl_Image default_icon(tux_xpm);
|
||
|
|
||
|
uint8 *cvt1to32(XImage *xim, int ow, int oh)
|
||
|
{
|
||
|
int pixel;
|
||
|
int pitch = Fl_Renderer::calc_pitch(4, ow);
|
||
|
uint8 *data = new uint8[oh*pitch];
|
||
|
uint32 *ptr;
|
||
|
int x,y;
|
||
|
for(y = 0; y < oh; y++)
|
||
|
{
|
||
|
ptr = (uint32*) (data + (pitch*y));
|
||
|
for(x = 0; x < ow; x++) {
|
||
|
pixel = XGetPixel(xim, x, y);
|
||
|
if(pixel) *ptr++ = 0x00000000;
|
||
|
else *ptr++ = 0xFFFFFFFF;
|
||
|
}
|
||
|
}
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
extern uint8 *ximage_to_data(XImage *im, Fl_PixelFormat *desired);
|
||
|
|
||
|
Icon::Icon(XWMHints *wm_hints)
|
||
|
{
|
||
|
// Max size 128x128
|
||
|
Fl_Rect r(0, 0, 128, 128);
|
||
|
XImage *xim;
|
||
|
|
||
|
image=0;
|
||
|
mask=0;
|
||
|
|
||
|
// ICON
|
||
|
if(wm_hints && wm_hints->flags & IconPixmapHint && wm_hints->icon_pixmap)
|
||
|
{
|
||
|
xim = Fl_Renderer::ximage_from_pixmap(wm_hints->icon_pixmap, r);
|
||
|
if(xim)
|
||
|
{
|
||
|
Fl_PixelFormat fmt;
|
||
|
|
||
|
DBG("Icon format: %dx%d %d\n",xim->width, xim->height, xim->depth);
|
||
|
DBG("depth/padding: %d/%d; r/g/b mask: %lx/%lx/%lx\n",
|
||
|
xim->depth, xim->bitmap_pad,
|
||
|
xim->red_mask, xim->green_mask, xim->blue_mask);
|
||
|
|
||
|
uint8 *data=0;
|
||
|
if(xim->depth==1) {
|
||
|
data = cvt1to32(xim, xim->width, xim->height);
|
||
|
fmt.realloc(32,0xFF0000,0x00FF00,0x0000FF,0);
|
||
|
} else {
|
||
|
data = ximage_to_data(xim, Fl_Renderer::system_format());
|
||
|
fmt.copy(Fl_Renderer::system_format());
|
||
|
}
|
||
|
|
||
|
// Create Fl_Image, masks are calculated automaticly
|
||
|
image = new Fl_Image(xim->width, xim->height, &fmt, data);
|
||
|
image->mask_type(FL_MASK_NONE);
|
||
|
XDestroyImage(xim);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// MASK
|
||
|
if(wm_hints && image && wm_hints->flags & IconMaskHint && wm_hints->icon_mask)
|
||
|
{
|
||
|
xim = Fl_Renderer::ximage_from_pixmap(wm_hints->icon_mask, r);
|
||
|
if(xim) {
|
||
|
uint8 *data = cvt1to32(xim, xim->width, xim->height);
|
||
|
mask = new Fl_Image(xim->width, xim->height, 32, data, 0,0,0,0);
|
||
|
mask->no_screen(true);
|
||
|
XDestroyImage(xim);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If no icon, set default
|
||
|
if(!image) {
|
||
|
image = &default_icon;
|
||
|
mask = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Icon::~Icon()
|
||
|
{
|
||
|
if(image && image!=&default_icon) { delete image; image=0; }
|
||
|
if(mask) { delete mask; mask=0; }
|
||
|
|
||
|
for(ImageMap::Iterator it(images); it.current(); it++) {
|
||
|
Fl_Image *i = I(it.value());
|
||
|
if(i && i!=&default_icon) {
|
||
|
delete i;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Fl_Image *Icon::get_icon(int W, int H)
|
||
|
{
|
||
|
if (!image) return 0;
|
||
|
|
||
|
Fl_Image *scaled=0, *cached=0;
|
||
|
|
||
|
Fl_String key;
|
||
|
key += Fl_String(W);
|
||
|
key += 'x';
|
||
|
key += Fl_String(H);
|
||
|
|
||
|
if(image==&default_icon)
|
||
|
{
|
||
|
if(W!=image->width() || H!=image->height())
|
||
|
{
|
||
|
cached = I(images.get_value(key));
|
||
|
if(cached) {
|
||
|
//printf("1. Cached\n");
|
||
|
return cached;
|
||
|
}
|
||
|
|
||
|
scaled = image->scale(W, H);
|
||
|
scaled->set_mask(default_icon.create_scaled_bitmap_mask(W, H), true);
|
||
|
images.insert(key, scaled);
|
||
|
return scaled;
|
||
|
|
||
|
} else
|
||
|
return image;
|
||
|
}
|
||
|
|
||
|
cached = I(images.get_value(key));
|
||
|
if(cached) {
|
||
|
//printf("2. Cached\n");
|
||
|
return cached;
|
||
|
}
|
||
|
|
||
|
// Check for default size image
|
||
|
if(W==image->width() && H==image->height()) {
|
||
|
if(mask && mask->get_mask()==0) {
|
||
|
// Init mask
|
||
|
mask->mask_type(MASK_COLORKEY);
|
||
|
mask->colorkey(0xFFFFFFFF);
|
||
|
Pixmap m = mask->create_mask(W, H);
|
||
|
mask->set_mask(m, true);
|
||
|
image->set_mask(mask->get_mask());
|
||
|
}
|
||
|
return image;
|
||
|
}
|
||
|
|
||
|
// Create NEW
|
||
|
scaled = image->scale(W,H);
|
||
|
if(mask) {
|
||
|
Fl_Image *smask = mask->scale(W, H);
|
||
|
smask->mask_type(MASK_COLORKEY);
|
||
|
smask->colorkey(0xFFFFFFFF);
|
||
|
Pixmap m = smask->create_mask(W, H);
|
||
|
delete smask;
|
||
|
scaled->set_mask(m, true);
|
||
|
}
|
||
|
|
||
|
images.insert(key, scaled);
|
||
|
return scaled;
|
||
|
}
|
||
|
|