mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
159 lines
5.2 KiB
C++
159 lines
5.2 KiB
C++
|
//
|
||
|
// PImage.hh for pekwm
|
||
|
// Copyright © 2004-2009 Claes Nasten <me@pekdon.net>
|
||
|
//
|
||
|
// This program is licensed under the GNU GPL.
|
||
|
// See the LICENSE file for more information.
|
||
|
//
|
||
|
|
||
|
#ifdef HAVE_CONFIG_H
|
||
|
#include "config.h"
|
||
|
#endif // HAVE_CONFIG_H
|
||
|
|
||
|
#ifndef _PIMAGE_HH_
|
||
|
#define _PIMAGE_HH_
|
||
|
|
||
|
#include "pekwm.hh"
|
||
|
#include "PImageLoader.hh"
|
||
|
|
||
|
#include <list>
|
||
|
#include <string>
|
||
|
|
||
|
//! @brief Image baseclass defining interface for image handling.
|
||
|
class PImage {
|
||
|
public:
|
||
|
//! @brief PImage constructor.
|
||
|
PImage(Display *dpy, const std::string &path="") throw(LoadException&);
|
||
|
//! @brief PImage destructor.
|
||
|
virtual ~PImage(void);
|
||
|
|
||
|
//! @brief Add loader to loader list.
|
||
|
static void loaderAdd(PImageLoader *loader) {
|
||
|
_loader_list.push_back(loader);
|
||
|
}
|
||
|
//! @brief Removes and frees all loaders.
|
||
|
static void loaderClear(void) {
|
||
|
while (_loader_list.size()) {
|
||
|
delete _loader_list.back();
|
||
|
_loader_list.pop_back();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//! @brief Returns type of image.
|
||
|
inline ImageType getType(void) const { return _type; }
|
||
|
//! @brief Sets type of image.
|
||
|
inline void setType(ImageType type) { _type = type; }
|
||
|
|
||
|
//! @brief Returns width of image.
|
||
|
inline uint getWidth(void) const { return _width; }
|
||
|
//! @brief Returns height of image.
|
||
|
inline uint getHeight(void) const { return _height; }
|
||
|
|
||
|
virtual bool load(const std::string &file);
|
||
|
virtual void unload(void);
|
||
|
virtual void draw(Drawable dest, int x, int y,
|
||
|
uint width = 0, uint height = 0);
|
||
|
virtual Pixmap getPixmap(bool &need_free, uint width = 0, uint height = 0);
|
||
|
virtual Pixmap getMask(bool &need_free, uint width = 0, uint height = 0);
|
||
|
virtual void scale(uint width, uint height);
|
||
|
|
||
|
protected:
|
||
|
void drawFixed(Drawable dest, int x, int y, uint width, uint height);
|
||
|
void drawScaled(Drawable dest, int x, int y, uint widht, uint height);
|
||
|
void drawTiled(Drawable dest, int x, int y, uint widht, uint height);
|
||
|
void drawAlphaFixed(Drawable dest, int x, int y, uint widht, uint height,
|
||
|
uchar *data = 0);
|
||
|
void drawAlphaScaled(Drawable dest, int x, int y, uint widht, uint height);
|
||
|
void drawAlphaTiled(Drawable dest, int x, int y, uint widht, uint height);
|
||
|
|
||
|
Pixmap createPixmap(uchar *data, uint width, uint height);
|
||
|
Pixmap createMask(uchar *data, uint width, uint height);
|
||
|
|
||
|
private:
|
||
|
XImage *createXImage(uchar *data, uint width, uint height);
|
||
|
uchar *getScaledData(uint width, uint height);
|
||
|
|
||
|
/**
|
||
|
* Create pixel value suitable for ximage from R, G and B.
|
||
|
*/
|
||
|
inline ulong
|
||
|
getPixelFromRgb(XImage *ximage, uchar r, uchar g, uchar b)
|
||
|
{
|
||
|
// 5 R, 5 G, 5 B (15 bit display)
|
||
|
if ((ximage->red_mask == 0x7c00)
|
||
|
&& (ximage->green_mask == 0x3e0) && (ximage->blue_mask == 0x1f)) {
|
||
|
return ((r << 7) & 0x7c00)
|
||
|
| ((g << 2) & 0x03e0) | ((b >> 3) & 0x001f);
|
||
|
|
||
|
// 5 R, 6 G, 5 B (16 bit display)
|
||
|
} else if ((ximage->red_mask == 0xf800)
|
||
|
&& (ximage->green_mask == 0x07e0)
|
||
|
&& (ximage->blue_mask == 0x001f)) {
|
||
|
return ((r << 8) & 0xf800)
|
||
|
| ((g << 3) & 0x07e0) | ((b >> 3) & 0x001f);
|
||
|
|
||
|
// 8 R, 8 G, 8 B (24/32 bit display)
|
||
|
} else if ((ximage->red_mask == 0xff0000)
|
||
|
&& (ximage->green_mask == 0xff00)
|
||
|
&& (ximage->blue_mask == 0xff)) {
|
||
|
return ((r << 16) & 0xff0000)
|
||
|
| ((g << 8) & 0x00ff00) | (b & 0x0000ff);
|
||
|
} else {
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Fill in RGB values from pixel value from ximage.
|
||
|
*/
|
||
|
inline void
|
||
|
getRgbFromPixel(XImage *ximage, ulong pixel, uchar &r, uchar &g, uchar &b)
|
||
|
{
|
||
|
// 5 R, 5 G, 5 B (15 bit display)
|
||
|
if ((ximage->red_mask == 0x7c00)
|
||
|
&& (ximage->green_mask == 0x3e0) && (ximage->blue_mask == 0x1f)) {
|
||
|
r = (pixel >> 7) & 0x7c;
|
||
|
g = (pixel >> 2) & 0x3e;
|
||
|
b = (pixel << 3) & 0x1f;
|
||
|
// 5 R, 6 G, 5 B (16 bit display)
|
||
|
} else if ((ximage->red_mask == 0xf800)
|
||
|
&& (ximage->green_mask == 0x07e0)
|
||
|
&& (ximage->blue_mask == 0x001f)) {
|
||
|
r = (pixel >> 8) & 0xf8;
|
||
|
g = (pixel >> 3) & 0x7e;
|
||
|
b = (pixel << 3) & 0x1f;
|
||
|
// 8 R, 8 G, 8 B (24/32 bit display)
|
||
|
} else if ((ximage->red_mask == 0xff0000)
|
||
|
&& (ximage->green_mask == 0xff00)
|
||
|
&& (ximage->blue_mask == 0xff)) {
|
||
|
r = (pixel >> 16) & 0xff;
|
||
|
g = (pixel >> 8) & 0xff;
|
||
|
b = pixel & 0xff;
|
||
|
} else {
|
||
|
r = 0;
|
||
|
g = 0;
|
||
|
b = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
Display *_dpy; //!< Display image is on.
|
||
|
|
||
|
ImageType _type; //!< Type of image.
|
||
|
|
||
|
Pixmap _pixmap; //!< Pixmap representation of image.
|
||
|
Pixmap _mask; //!< Pixmap representation of image shape mask.
|
||
|
|
||
|
uint _width; //!< Width of image.
|
||
|
uint _height; //!< Height of image.
|
||
|
|
||
|
uchar *_data; //!< Data describing image.
|
||
|
bool _has_alpha; //!< Wheter image has alpha channel.
|
||
|
bool _use_alpha; //!< Wheter image has alpha < 100%
|
||
|
|
||
|
private:
|
||
|
static std::list<PImageLoader*> _loader_list; //!< List of loaders.
|
||
|
};
|
||
|
|
||
|
#endif // _PIMAGE_HH_
|