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