]> git.saurik.com Git - wxWidgets.git/commitdiff
Added wxDC::GetAsBitmap, and implemented wxWindowDC::DoGetAsBitmap on OS X, in order...
authorKevin Ollivier <kevino@theolliviers.com>
Sun, 29 Oct 2006 05:29:04 +0000 (05:29 +0000)
committerKevin Ollivier <kevino@theolliviers.com>
Sun, 29 Oct 2006 05:29:04 +0000 (05:29 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42604 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/dc.h
include/wx/mac/carbon/dcclient.h
src/common/dcgraph.cpp
src/mac/carbon/dcclient.cpp

index d6bfafdc61978cb9086ae1fc0292119105119614..ebf665a5808b341ed054b8b374f593e6f611855e 100644 (file)
@@ -313,6 +313,11 @@ public:
         return DoBlit(destPt.x, destPt.y, sz.x, sz.y,
                       source, srcPt.x, srcPt.y, rop, useMask, srcPtMask.x, srcPtMask.y);
     }
+    
+    wxBitmap GetAsBitmap()
+    {
+        return DoGetAsBitmap();
+    }
 
 #if wxUSE_SPLINES
     // TODO: this API needs fixing (wxPointList, why (!const) "wxList *"?)
@@ -712,6 +717,8 @@ protected:
                         wxDC *source, wxCoord xsrc, wxCoord ysrc,
                         int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord) = 0;
 
+    virtual wxBitmap DoGetAsBitmap() const { return wxNullBitmap; }
+
     virtual void DoGetSize(int *width, int *height) const = 0;
     virtual void DoGetSizeMM(int* width, int* height) const = 0;
 
index 4fc84defdd661af82bc8a6c6e65183723aa8d720..2817c20a9a4c1592f3fa67b5b19639f98078ffbb 100644 (file)
@@ -35,6 +35,7 @@ class WXDLLEXPORT wxWindowDC: public wxDC
   wxWindow *GetWindow() const { return m_window; }
   protected :
     virtual void DoGetSize( int *width, int *height ) const;
+    virtual wxBitmap DoGetAsBitmap() const; 
     wxWindow     *m_window;
 #if wxMAC_USE_CORE_GRAPHICS
        bool            m_release;
index 4234c0ccbe15281740d6ae6665f8cc7c630184fe..0819d2f919bed4bfac136a98d2bdc37f8792e3ed 100644 (file)
@@ -854,9 +854,14 @@ bool wxGCDC::DoBlit(
 {
     wxCHECK_MSG( Ok(), false, wxT("wxGCDC(cg)::DoBlit - invalid DC") );
     wxCHECK_MSG( source->Ok(), false, wxT("wxGCDC(cg)::DoBlit - invalid source DC") );
-
+    
     if ( logical_func == wxNO_OP )
         return true;
+    else if ( logical_func != wxCOPY )
+    {
+        wxFAIL_MSG( wxT("Blitting is only supported with wxCOPY logical operation.") );
+        return false;
+    }
 
     if (xsrcMask == -1 && ysrcMask == -1)
     {
@@ -874,10 +879,11 @@ bool wxGCDC::DoBlit(
     wxCoord wwdest = LogicalToDeviceXRel(width);
     wxCoord hhdest = LogicalToDeviceYRel(height);
 
+    wxBitmap blit;
     wxMemoryDC* memdc = wxDynamicCast(source,wxMemoryDC);
-    if ( memdc && logical_func == wxCOPY )
+    if ( memdc )
     {
-        wxBitmap blit = memdc->GetSelectedBitmap();
+        blit = memdc->GetSelectedBitmap();
 
         wxASSERT_MSG( blit.Ok() , wxT("Invalid bitmap for blitting") );
 
@@ -908,15 +914,26 @@ bool wxGCDC::DoBlit(
                 blit = wxNullBitmap;
             }
         }
-
-        if ( blit.Ok() )
-        {
-            m_graphicContext->DrawBitmap( blit, xxdest , yydest , wwdest , hhdest );
+    }
+    else
+    {  
+        wxWindowDC* windc = wxDynamicCast(source,wxWindowDC);
+        if (windc)
+        {   
+            wxBitmap bmp;
+            bmp = windc->GetAsBitmap();
+            if (bmp.IsOk())
+                blit = bmp.GetSubBitmap( wxRect(xsrc, ysrc, width, height ) ); 
         }
     }
+    
+    if ( blit.Ok() )
+    {
+        m_graphicContext->DrawBitmap( blit, xxdest , yydest , wwdest , hhdest );
+    }
     else
     {
-        wxFAIL_MSG( wxT("Blitting is only supported from bitmap contexts, and only with wxCOPY logical operation.") );
+        wxFAIL_MSG( wxT("Cannot Blit. Unable to get contents of DC as bitmap.") );
         return false;
     }
 
index 73d0d4d301c058a9fe96fcc60c3be923f48412ff..970370092b8a16ea3c53d561ceb130898a0ff389 100644 (file)
@@ -24,6 +24,7 @@
 #endif
 
 #include "wx/graphics.h"
+#include "wx/rawbmp.h"
 #include "wx/mac/private.h"
 
 //-----------------------------------------------------------------------------
@@ -187,6 +188,54 @@ void wxWindowDC::DoGetSize( int* width, int* height ) const
 #endif
 }
 
+wxBitmap wxWindowDC::DoGetAsBitmap() const
+{
+    ControlRef handle = (ControlRef) m_window->GetHandle(); 
+    if ( !handle )
+        return wxNullBitmap;
+
+    HIRect rect;    
+    CGImageRef image;
+    CGContextRef context;
+    void* data;
+     
+    size_t bytesPerRow;
+    
+    HIViewCreateOffscreenImage( handle, 0, &rect, &image);
+    
+    int width = rect.size.width;
+    int height = rect.size.height; 
+    
+    bytesPerRow = ( ( width * 8 * 4 + 7 ) / 8 );
+
+    data = calloc( 1, bytesPerRow * height );
+    context = CGBitmapContextCreate( data, width, height, 8, bytesPerRow, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedFirst );
+    
+    CGContextDrawImage( context, rect, image );
+
+    unsigned char* buffer = (unsigned char*) data;          
+    wxBitmap bmp = wxBitmap(width, height, 32);
+    wxAlphaPixelData pixData(bmp, wxPoint(0,0), wxSize(width, height));
+    
+    pixData.UseAlpha();
+    wxAlphaPixelData::Iterator p(pixData);
+    for (int y=0; y<height; y++) {
+        wxAlphaPixelData::Iterator rowStart = p;
+        for (int x=0; x<width; x++) {
+            unsigned char a = buffer[3];
+            p.Red()   = a; buffer++;
+            p.Green() = a; buffer++;
+            p.Blue()  = a; buffer++;
+            p.Alpha() = a; buffer++;
+            ++p; 
+        }
+        p = rowStart;
+        p.OffsetY(pixData, 1);
+    }
+    
+    return bmp;
+}
+
 /*
  * wxClientDC
  */