Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

stretch_painter.cpp

00001 // stretch_painter.cpp
00002 
00003 // Copyright (C) 2004 Steven Weiß (steven11@gmx.de)
00004 //
00005 // Permission to copy, use, sell and distribute this software is granted
00006 // provided this copyright notice appears in all copies.
00007 // Permission to modify the code and to distribute modified code is granted
00008 // provided this copyright notice appears in all copies, and a notice
00009 // that the code was modified is included with the copyright notice.
00010 //
00011 // This software is provided "as is" without express or implied warranty,
00012 // and with no claim as to its suitability for any purpose.
00013 
00014 
00015 #include <background_wnd/painters/stretch_painter.hpp>
00016 #include <background_wnd/painters/transparent_painter.hpp>
00017 
00018 
00019 namespace win32 { namespace gui {
00020 
00021 namespace detail {
00022      // ========================================================================================================= //
00023      // helper painter for stretch_painter which stretches the image
00024 
00025      class stretch_painter_helper : public painter_base
00026      {
00027           HDC hPainterDC_;    
00028           SIZE orig_size_;
00029 
00030      public:
00031           typedef HDC param0; 
00032           typedef SIZE param1;
00033 
00034           stretch_painter_helper(HDC hPainterDC, SIZE orig_size)
00035                : hPainterDC_(hPainterDC), orig_size_(orig_size)
00036           {}
00037 
00038           stretch_painter_helper* clone() const
00039           {
00040                return new stretch_painter_helper(*this);
00041           }
00042 
00043           void draw(HDC hDC, int cx, int cy)
00044           {
00045                // stretch image
00046                StretchBlt(hDC, 0, 0, cx, cy, hPainterDC_, 0, 0, orig_size_.cx, orig_size_.cy, SRCCOPY);       
00047           }
00048      };
00049 
00050 }    // namespace detail
00051 
00052 // ========================================================================================================= //
00053 // stretch_painter
00054 
00061 stretch_painter::stretch_painter(param0 rc_stretch, param1 cr_not_used) : rc_stretch_(rc_stretch), cr_not_used_(cr_not_used)
00062 {}
00063 
00064 stretch_painter* stretch_painter::clone() const
00065 {
00066      return new stretch_painter(*this);
00067 }
00068 
00069 void stretch_painter::draw(HDC hDC, int cx, int cy)
00070 {    
00071      if (cx <= 0 || cy <= 0 || rc_stretch_.width() == 0 || rc_stretch_.height() == 0 || cx < rc_stretch_.left || cy < rc_stretch_.top)
00072           return;
00073 
00074      if (painter_available()) {
00075           // create the memory dc
00076           HDC hPainterDC  = CreateCompatibleDC(hDC);                  
00077           HBITMAP hBmp    = CreateCompatibleBitmap(hDC, cx, cy);      
00078           HBITMAP hOldBmp = (HBITMAP) SelectObject(hPainterDC, hBmp);      
00079                               
00080           // fill with color not used in the adapted painter
00081           RECT rc = { 0, 0, cx, cy };
00082           HBRUSH hbr = CreateSolidBrush(cr_not_used_);
00083           FillRect(hPainterDC, &rc, hbr);
00084           DeleteObject(hbr);
00085 
00086           // draw the painter
00087           painter_base& painter = get_painter();
00088           painter.draw(hPainterDC, cx, cy);       
00089           
00090           // if the painter is opaque we can safely stretch it
00091           if (painter.is_opaque(cx, cy)) {
00092                StretchBlt(hDC, rc_stretch_.left, rc_stretch_.top, rc_stretch_.width(), rc_stretch_.height(), 
00093                             hPainterDC, 0, 0, cx, cy, SRCCOPY);       
00094           }
00095           // painter isn't opaque. we must be aware that the transparent background is cut
00096           else {
00097                // - the image is stretched in stretch_painter_helper::draw()         
00098                // - set the viewport origin to the position of the drawing-rectangle to trick transparent_painter ;-)
00099                // - after the stretching transparent_painter does the dirty job of drawing
00100                //    the background transparently ;-)
00101                POINT pt;
00102                SetViewportOrgEx(hDC, rc_stretch_.left, rc_stretch_.top, &pt);
00103                transparent_painter p(cr_not_used_);
00104                p.set_painter<detail::stretch_painter_helper> (hPainterDC, wnd_size(cx, cy));
00105                p.draw(hDC, rc_stretch_.width(), rc_stretch_.height());          
00106                SetViewportOrgEx(hDC, pt.x, pt.y, NULL);
00107           }
00108                     
00109           // clean up
00110           SelectObject(hPainterDC, hOldBmp);      
00111           DeleteObject(hBmp);      
00112           DeleteDC(hPainterDC);                   
00113      }
00114 }
00115 
00117 void stretch_painter::stretched_rect(const rectangle& rc_stretch)
00118 {
00119      rc_stretch_  = rc_stretch;
00120 }
00121 
00123 rectangle stretch_painter::stretched_rect() const
00124 {
00125      return rc_stretch_;
00126 }
00127 
00128 } }  // namespace win32::gui

Generated on Mon Dec 27 15:30:11 2004 for background_wnd by  doxygen 1.3.9.1