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
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.