pixmap.h

Go to the documentation of this file.
00001 /*
00002   libwt - Vassilis Virvilis Toolkit - a widget library
00003   Copyright (C) 2006 Vassilis Virvilis <vasvir2@fastmail.fm>
00004  
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Lesser General Public
00007   License as published by the Free Software Foundation; either
00008   version 2.1 of the License, or (at your option) any later version.
00009   
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Lesser General Public License for more details.
00014   
00015   You should have received a copy of the GNU Lesser General Public
00016   License along with this library; if not, write to the
00017   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018   Boston, MA  02111-1307, SA.
00019 */
00020 
00021 #ifndef WT_PIXMAP_H
00022 #define WT_PIXMAP_H
00023 
00024 #include <wt/region.h>
00025 #include <wt/color.h>
00026 
00027 #include "sdlsurface.h"
00028 
00029 namespace Wt {
00030 
00031 /// used as a base for the Pixmap and the Display
00032 /*! \note SDLPixmap must be a SDLSurface descendant */
00033 template <typename SDLPixmap>
00034 class PixmapOf: public SDLPixmap {
00035 protected:
00036     typedef PixmapOf<SDLSurface> PixmapBase;
00037 
00038 public:
00039     /// constructor for NULL pixmap or default display
00040     PixmapOf()
00041             : SDLPixmap() {}
00042     /// constructor for a sized display
00043     PixmapOf(int w, int h, int depth, int flags = 0)
00044             : SDLPixmap(w, h, depth, flags) {}
00045     /// constructor for a sized display
00046     PixmapOf(const Size& size, int depth, int flags = 0)
00047             : SDLPixmap(size.width(), size.height(), depth, flags) {}
00048 
00049     /// copy shares the pixmap
00050     PixmapOf(const PixmapBase& pixmap)
00051             : SDLSurface(pixmap) {}
00052     /// constructor from SDLSurface (for scale to work implicitely)
00053     PixmapOf(const SDLSurface& sdlsurface)
00054             : SDLSurface(sdlsurface) {}
00055     /// constructor from file
00056     PixmapOf(const std::string& filename)
00057             : SDLSurface(filename) {}
00058 
00059     //! \name Informative methods
00060     //@{
00061     bool isNull() const {
00062         return (!*this || (SDLPixmap::width() == 0 && SDLPixmap::height() == 0));
00063     }
00064 
00065     Size size() const {
00066         return Size(SDLPixmap::width(), SDLPixmap::height());
00067     }
00068 
00069     Rect rect() const {
00070         return Rect(0, 0, SDLPixmap::width(), SDLPixmap::height());
00071     }
00072     //@}
00073 
00074     using SDLPixmap::fill;
00075     void fill(const Color& color = Color("white")) {
00076         fill(SDLPixmap::pixelFormat().mapToPixelValue(color));
00077     }
00078     void fill(const Rect& dst, const Color& color = Color("white")) {
00079         fill(dst, SDLPixmap::pixelFormat().mapToPixelValue(color));
00080     }
00081 
00082     void fill(const Region& dst, const Color& color = Color("white")) {
00083         const RectArray& ra = dst.rects();
00084         const int n = ra.size();
00085 
00086         for (int i = 0; i < n; i++) {
00087             fill(ra[i], color);
00088         }
00089     }
00090 
00091     void blend(const Color& color = Color("white"),
00092                int alpha_blend_factor = Color::Transparent) {
00093         blend(rect(), SDLPixmap::pixelFormat().mapToPixelValue(color), alpha_blend_factor);
00094     }
00095 
00096     void blend(const Rect& dst, const Color& color = Color("white"),
00097                int alpha_blend_factor = Color::Transparent) {
00098 
00099         switch(color.alpha()) {
00100         case Color::Transparent:
00101             return;
00102         case Color::Opaque:
00103             fill(dst, color);
00104             return;
00105         default:
00106             break;
00107         }
00108 
00109         const Rect overlap = dst.intersect(SDLPixmap::clipRect());
00110         if(overlap.isEmpty())
00111             return;
00112 
00113         int new_part, old_part;
00114         Color::calcBlendFactors(color.alpha(), new_part, old_part);
00115         int alpha_new_part, alpha_old_part;
00116         Color::calcBlendFactors(alpha_blend_factor, alpha_new_part, alpha_old_part);
00117 
00118         SDLPixmap::lock()
00119             ;
00120         const int bpp = SDLPixmap::pixelFormat().bytesPerPixel();
00121         for(int y = overlap.y(); y < overlap.y() + overlap.height(); y++) {
00122             int offset = SDLPixmap::pixelOffset(overlap.x(), y);
00123             for(int x = overlap.x(); x < overlap.x() + overlap.width(); x++) {
00124 
00125                 Color c = SDLPixmap::pixelColor(offset);
00126                 c = Color::blend(c, old_part, color, new_part,
00127                                  alpha_new_part, alpha_old_part);
00128 
00129                 SDLPixmap::setPixelColor(offset, c);
00130                 offset += bpp;
00131             }
00132         }
00133         SDLPixmap::unlock();
00134 
00135         return;
00136     }
00137 
00138     void blend(const Region& dst, const Color& color = Color("white"),
00139                int alpha_blend_factor = Color::Transparent) {
00140         const RectArray& ra = dst.rects();
00141         const int n = ra.size();
00142 
00143         for (int i = 0; i < n; i++) {
00144             blend(ra[i], color, alpha_blend_factor);
00145         }
00146     }
00147 
00148     using SDLPixmap::blit;
00149     int blit(const Point& p, const PixmapBase& src) {
00150         return blit(p.x(), p.y(), src);
00151     }
00152     int blit(const Point& p, const PixmapBase& src, const Rect& src_rect) {
00153         return blit(p.x(), p.y(), src, src_rect);
00154     }
00155 
00156     using SDLPixmap::blitAlphaCopy;
00157     int blitAlphaCopy(const Point& p, const PixmapBase& src) {
00158         return blitAlphaCopy(p.x(), p.y(), src);
00159     }
00160     int blitAlphaCopy(const Point& p, const PixmapBase& src, const Rect& src_rect) {
00161         return blitAlphaCopy(p.x(), p.y(), src, src_rect);
00162     }
00163 
00164     /// copy to from src rect with alpha blending
00165     /*!
00166     if alpha_blend_factor = Color::Transparent (default) we keep the
00167     destination alpha (blit semantics). If it is set to Color::Opaque
00168     we replace alpha values with the new one (blitAlphaCopy semantics).
00169 
00170     The blending of the color happens anyway.
00171     */
00172     int blitAlphaBlend(int x, int y, const PixmapBase& src,
00173                        const Rect& src_rect,
00174                        int alpha_blend_factor = Color::Transparent) {
00175         const Rect dst = Rect(x, y, src_rect.width(), src_rect.height());
00176         const Rect overlap = dst.intersect(SDLPixmap::clipRect());
00177 
00178         if(overlap.isEmpty())
00179             return 0;
00180 
00181         assert(SDLPixmap::depth() == src.depth());
00182 
00183         const int bpp = SDLPixmap::pixelFormat().bytesPerPixel();
00184         const int src_bpp = src.pixelFormat().bytesPerPixel();
00185 
00186         int alpha_new_part, alpha_old_part;
00187         Color::calcBlendFactors(alpha_blend_factor, alpha_new_part, alpha_old_part);
00188         SDLPixmap::lock()
00189             ;
00190         for(int y = overlap.y(); y < overlap.y() + overlap.height(); y++) {
00191             int offset = SDLPixmap::pixelOffset(overlap.x(), y);
00192             int src_offset = src.pixelOffset(src_rect.x(), src_rect.y() + y - overlap.y());
00193             for(int x = overlap.x(); x < overlap.x() + overlap.width(); x++) {
00194                 Color c = pixelColor(offset);
00195                 Color src_c = src.pixelColor(src_offset);
00196 
00197                 int new_part, old_part;
00198                 Color::calcBlendFactors(src_c.alpha(), new_part, old_part);
00199                 c = Color::blend(c, old_part, src_c, new_part,
00200                                  alpha_new_part, alpha_old_part);
00201                 SDLPixmap::setPixelColor(offset, c);
00202 
00203                 offset += bpp;
00204                 src_offset += src_bpp;
00205             }
00206         }
00207         SDLPixmap::unlock();
00208 
00209         return 0;
00210     }
00211 
00212     /// copy to from src with alpha blending
00213     int blitAlphaBlend(const PixmapBase& src,
00214                        int alpha_blend_factor = Color::Transparent) {
00215         return blitAlphaBlend(0, 0, src,
00216                               Rect(0, 0, src.width(), src.height()),
00217                               alpha_blend_factor);
00218     }
00219     /// copy to from src with alpha blending
00220     int blitAlphaBlend(int x, int y, const PixmapBase& src,
00221                        int alpha_blend_factor = Color::Transparent) {
00222         return blitAlphaBlend(x, y, src,
00223                               Rect(0, 0, src.width(), src.height()),
00224                               alpha_blend_factor);
00225     }
00226     int blitAlphaBlend(const Point& p, const PixmapBase& src,
00227                        int alpha_blend_factor = Color::Transparent) {
00228         return blitAlphaBlend(p.x(), p.y(), src, alpha_blend_factor);
00229     }
00230     int blitAlphaBlend(const Point& p, const PixmapBase& src, const Rect& src_rect,
00231                        int alpha_blend_factor = Color::Transparent) {
00232         return blitAlphaBlend(p.x(), p.y(), src, src_rect, alpha_blend_factor);
00233     }
00234 
00235     using SDLPixmap::resize;
00236     void resize(const Size& size) {
00237         resize(size.width(), size.height());
00238     }
00239 
00240     using SDLPixmap::scale;
00241     PixmapBase scale(const Size& size,
00242                      SDLSurface::ScaleMode mode = SDLSurface::ScaleFree) const {
00243         return scale(size.width(), size.height(), mode);
00244     }
00245 
00246     using SDLPixmap::smoothScale;
00247     PixmapBase smoothScale(const Size& size,
00248                            SDLSurface::ScaleMode mode = SDLSurface::ScaleFree) const {
00249         return smoothScale(size.width(), size.height(), mode);
00250     }
00251 
00252     using SDLPixmap::pixel;
00253     int pixel(const Point& p) const {
00254         return pixel(p.x(), p.y());
00255     }
00256 
00257     using SDLPixmap::pixelColor;
00258     Color pixelColor(const Point& p) const {
00259         return pixelColor(p.x(), p.y());
00260     }
00261 
00262     using SDLPixmap::setPixel;
00263     void setPixel(const Point& p, int pixel_value) {
00264         setPixel(p.x(), p.y(), pixel_value);
00265     }
00266 
00267     using SDLPixmap::setPixelColor;
00268     void setPixelColor(const Point& p, const SDLColor& color) {
00269         setPixelColor(p.x(), p.y(), color);
00270     }
00271 
00272     PixmapBase copy() const {
00273         return copy(rect());
00274     }
00275 
00276     PixmapBase copy(int x, int y, int w, int h) const {
00277         return copy(Rect(x, y, w, h));
00278     }
00279 
00280     PixmapBase copy(const Rect& r) const {
00281         PixmapBase p(r.width(), r.height());
00282         p.convertTo(*this);
00283         p.blit(0, 0, *this, r);
00284         return p;
00285     }
00286 };
00287 
00288 class Pixmap : public PixmapOf<SDLSurface> {
00289 public:
00290     typedef enum {
00291         NoOptim,
00292         BestOptim,
00293         DefaultOptim = BestOptim
00294     } Optimization;
00295 
00296     /// constructor for NULL pixmap or default display
00297     Pixmap()
00298             : PixmapBase() {}
00299 
00300     /// constructor for a sized, non display, pixmap
00301     Pixmap(int w, int h, int depth = -1, int flags = 0, Optimization optimization = DefaultOptim)
00302             :  PixmapOf<SDLSurface>(w, h, depth, flags) {
00303         if (optimization == BestOptim)
00304             convertToDisplay();
00305     }
00306     /// constructor for a sized, non display, pixmap
00307     Pixmap(const Size& size, int depth = -1, int flags = 0, Optimization optimization = DefaultOptim)
00308             :  PixmapOf<SDLSurface>(size.width(), size.height(), depth, flags) {
00309         if (optimization == BestOptim)
00310             convertToDisplay();
00311     }
00312 
00313     /// copy shares the pixmap
00314     Pixmap(const PixmapBase& pixmap)
00315         : PixmapBase(pixmap) {}
00316     /// constructor from SDLSurface (for scale to work implicitely)
00317     Pixmap(const SDLSurface& sdlsurface)
00318             : PixmapBase(sdlsurface) {}
00319     /// constructor from file
00320     Pixmap(const std::string& filename)
00321             : PixmapBase(filename) {}
00322 }
00323 ;
00324 
00325 } // namespace Wt
00326 
00327 #endif // WT_PIXMAP_H

Generated Fri Jul 28 19:23:00 2006.
Copyright © 1998-2003 by the respective authors.

This document is licensed under the terms of the GNU Free Documentation License and may be freely distributed under the conditions given by this license.