Mercurial > dillo_port1.3
view dw/imgbuf.hh @ 1742:6ff5d5aeb9a5
inline setNonCssHint()
author | Johannes Hofmann <Johannes.Hofmann@gmx.de> |
---|---|
date | Thu, 14 Oct 2010 09:04:52 +0200 |
parents | 4704ad910042 |
children |
line wrap: on
line source
#ifndef __DW_IMGBUF_HH__ #define __DW_IMGBUF_HH__ #ifndef __INCLUDED_FROM_DW_CORE_HH__ # error Do not include this file directly, use "core.hh" instead. #endif namespace dw { namespace core { /** * \brief The platform independent interface for image buffers. * * %Image buffers depend on the platform (see \ref dw-images-and-backgrounds), * but have this general, platform independent interface. The purpose of * an image buffer is * * <ol> * <li> storing the image data, * <li> handling scaled versions of this buffer, and * <li> drawing. * </ol> * * The latter must be done independently from the window. * * <h3>Creating</h3> * * %Image buffers are created by calling dw::core::Platform::createImgbuf. * * <h3>Storing %Image Data</h3> * * dw::core::Imgbuf supports five image types, which are listed in the table * below. The representation defines, how the colors are stored within * the data, which is passed to dw::core::Imgbuf::copyRow. * * <table> * <tr><th>Type (dw::core::Imgbuf::Type) <th>Bytes per * Pixel <th>Representation * <tr><td>dw::core::Imgbuf::RGB <td>3 <td>red, green, blue * <tr><td>dw::core::Imgbuf::RGBA <td>4 <td>red, green, blue, alpha * <tr><td>dw::core::Imgbuf::GRAY <td>1 <td>gray value * <tr><td>dw::core::Imgbuf::INDEXED <td>1 <td>index to colormap * <tr><td>dw::core::Imgbuf::INDEXED_ALPHA <td>1 <td>index to colormap * </table> * * The last two types need a colormap, which is set by * dw::core::Imgbuf::setCMap, which must be called before * dw::core::Imgbuf::copyRow. This function expects the colors as 32 bit * unsigned integers, which have the format 0xrrbbgg (for indexed * images), or 0xaarrggbb (for indexed alpha), respectively. * * * <h3>Scaling</h3> * * The buffer with the original size, which was created by * dw::core::Platform::createImgbuf, is called root buffer. Imgbuf provides * the ability to scale buffers. Generally, both root buffers, as well as * scaled buffers, may be shared, memory management is done by reference * counters. * * Via dw::core::Imgbuf::getScaledBuf, you can retrieve a scaled buffer. * Generally, something like this must work always, in an efficient way: * * \code * dw::core::Imgbuf *curBuf, *oldBuf; * int width, heigt, * // ... * oldBuf = curBuf; * curBuf = oldBuf->getScaledBuf(oldBuf, width, height); * oldBuf->unref(); * \endcode * * \em oldBuf may both be a root buffer, or a scaled buffer. * * The root buffer keeps a list of all children, and all methods * operating on the image data (dw::core::Imgbuf::copyRow and * dw::core::Imgbuf::setCMap) are delegated to the scaled buffers, when * processed, and inherited, when a new scaled buffer is created. This * means, that they must only be performed for the root buffer. * * A possible implementation could be (dw::fltk::FltkImgbuf does it this way): * * <ul> * <li> If the method is called with an already scaled image buffer, this is * delegated to the root buffer. * * <li> If the given size is the original size, the root buffer is * returned, with an increased reference counter. * * <li> Otherwise, if this buffer has already been scaled to the given * size, return this scaled buffer, with an increased reference * counter. * * <li> Otherwise, return a new scaled buffer with reference counter 1. * </ul> * * Special care is to be taken, when the root buffer is not used anymore, * i.e. after dw::core::Imgbuf::unref the reference counter is 0, but there * are still scaled buffers. Since all methods operating on the image data * (dw::core::Imgbuf::copyRow and dw::core::Imgbuf::setCMap) are called for * the root buffer, the root buffer is still needed, and so must not be * deleted at this point. This is, how dw::fltk::FltkImgbuf solves this * problem: * * <ul> * <li> dw::fltk::FltkImgbuf::unref does, for root buffers, check, not only * whether dw::fltk::FltkImgbuf::refCount is 0, but also, whether * there are children left. When the latter is the case, the buffer * is not deleted. * * <li> There is an additional check in dw::fltk::FltkImgbuf::detachScaledBuf, * which deals with the case, that dw::fltk::FltkImgbuf::refCount is 0, * and the last scaled buffer is removed. * </ul> * * In the following example: * * \code * dw::fltk::FltkPlatform *platform = new dw::fltk::FltkPlatform (); * dw::core::Layout *layout = new dw::core::Layout (platform); * * dw::core::Imgbuf *rootbuf = * layout->createImgbuf (dw::core::Imgbuf::RGB, 100, 100); * dw::core::Imgbuf *scaledbuf = rootbuf->getScaledBuf (50, 50); * rootbuf->unref (); * scaledbuf->unref (); * \endcode * * the root buffer is not deleted, when dw::core::Imgbuf::unref is called, * since a scaled buffer is left. After calling dw::core::Imgbuf::unref for * the scaled buffer, it is deleted, and after it, the root buffer. * * <h3>Drawing</h3> * * dw::core::Imgbuf provides no methods for drawing, instead, this is * done by the views (implementation of dw::core::View). * * There are two situations, when drawing is necessary: * * <ol> * <li> To react on expose events, the function dw::core::View::drawImage * should be used, with the following parameters: * <ul> * <li> of course, the image buffer, * <li> where the root of the image would be displayed (as \em xRoot * and \em yRoot), and * <li> the region within the image, which should be displayed (\em x, * \em y, \em width, \em height). * </ul> * * <li> When a row has been copied, it has to be drawn. To determine the * area, which has to be drawn, the dw::core::Imgbuf::getRowArea * should be used. The result can then passed * to dw::core::View::drawImage. * </ol> * * \sa \ref dw-images-and-backgrounds */ class Imgbuf: public lout::object::Object, public lout::signal::ObservedObject { public: enum Type { RGB, RGBA, GRAY, INDEXED, INDEXED_ALPHA }; /* * Methods called from the image decoding */ virtual void setCMap (int *colors, int num_colors) = 0; virtual void copyRow (int row, const byte *data) = 0; virtual void newScan () = 0; /* * Methods called from dw::Image */ virtual Imgbuf* getScaledBuf (int width, int height) = 0; virtual void getRowArea (int row, dw::core::Rectangle *area) = 0; virtual int getRootWidth () = 0; virtual int getRootHeight () = 0; /* * Reference counting. */ virtual void ref () = 0; virtual void unref () = 0; /** * \todo Comment */ virtual bool lastReference () = 0; /** * \todo Comment */ virtual void setDeleteOnUnref (bool deleteOnUnref) = 0; /** * \todo Comment */ virtual bool isReferred () = 0; }; } // namespace dw } // namespace core #endif // __DW_IMGBUF_HH__