]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/core/bitmap.cpp
Added missing wxBitmapComboBox::Insert() implementation
[wxWidgets.git] / src / osx / core / bitmap.cpp
index 71b8bda63aee43da5861312831e3a684d68bcb1d..72ba979c41562c87353e5d733fd8eda0f4778861 100644 (file)
@@ -57,6 +57,7 @@ class WXDLLEXPORT wxBitmapRefData: public wxGDIRefData
     friend class WXDLLIMPEXP_FWD_CORE wxCursor;
 public:
     wxBitmapRefData(int width , int height , int depth);
+    wxBitmapRefData(CGImageRef image);
     wxBitmapRefData();
     wxBitmapRefData(const wxBitmapRefData &tocopy);
 
@@ -111,6 +112,7 @@ public:
     int           GetBytesPerRow() const { return m_bytesPerRow; }
     private :
     bool Create(int width , int height , int depth);
+    bool Create( CGImageRef image );
     void Init();
 
     int           m_width;
@@ -280,6 +282,53 @@ wxBitmapRefData::wxBitmapRefData( int w , int h , int d )
     Create( w , h , d ) ;
 }
 
+wxBitmapRefData::wxBitmapRefData(CGImageRef image)
+{
+    Init();
+    Create( image );
+}    
+// code from Technical Q&A QA1509
+
+bool wxBitmapRefData::Create(CGImageRef image)
+{
+    if ( image != NULL )
+    {
+        m_width = CGImageGetWidth(image);
+        m_height = CGImageGetHeight(image);
+        m_depth = 32;
+        m_hBitmap = NULL;
+        
+        m_bytesPerRow = GetBestBytesPerRow( m_width * 4 ) ;
+        size_t size = m_bytesPerRow * m_height ;
+        void* data = m_memBuf.GetWriteBuf( size ) ;
+        if ( data != NULL )
+        {
+            memset( data , 0 , size ) ;
+            m_memBuf.UngetWriteBuf( size ) ;
+            CGImageAlphaInfo alpha = CGImageGetAlphaInfo(image);
+            if ( alpha == kCGImageAlphaNone || alpha == kCGImageAlphaNoneSkipLast || alpha == kCGImageAlphaNoneSkipLast )
+            {
+                m_hBitmap = CGBitmapContextCreate((char*) data, m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst );
+            }
+            else 
+            {
+                m_hasAlpha = true;
+                m_hBitmap = CGBitmapContextCreate((char*) data, m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), kCGImageAlphaPremultipliedFirst );
+            }
+            CGRect rect = {{0,0},{m_width,m_height}}; 
+            CGContextDrawImage(m_hBitmap, rect, image);
+            
+            wxASSERT_MSG( m_hBitmap , wxT("Unable to create CGBitmapContext context") ) ;
+            CGContextTranslateCTM( m_hBitmap, 0,  m_height );
+            CGContextScaleCTM( m_hBitmap, 1, -1 );
+        } /* data != NULL */
+    }
+    m_ok = ( m_hBitmap != NULL ) ;
+    
+    return m_ok ;
+    
+}
+
 bool wxBitmapRefData::Create( int w , int h , int d )
 {
     m_width = wxMax(1, w);
@@ -287,8 +336,8 @@ bool wxBitmapRefData::Create( int w , int h , int d )
     m_depth = d ;
     m_hBitmap = NULL ;
 
-    m_bytesPerRow = GetBestBytesPerRow( w * 4 ) ;
-    size_t size = m_bytesPerRow * h ;
+    m_bytesPerRow = GetBestBytesPerRow( m_width * 4 ) ;
+    size_t size = m_bytesPerRow * m_height ;
     void* data = m_memBuf.GetWriteBuf( size ) ;
     if ( data != NULL )
     {
@@ -496,8 +545,13 @@ IconRef wxBitmapRefData::GetIconRef()
                      }
                 }
                 HUnlock( data );
+
                 OSStatus err = SetIconFamilyData( iconFamily, dataType , data );
-                wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") );
+                if ( err != noErr )
+                {
+                    wxFAIL_MSG("Error when adding bitmap");
+                }
+
                 DisposeHandle( data );
             }
             else
@@ -634,6 +688,9 @@ CGImageRef wxBitmapRefData::CreateCGImage() const
     {
         if ( m_depth != 1 && m_bitmapMask == NULL )
         {
+#if 0
+            // in order for this code to work properly, wxMask would have to invert black and white
+            // in the native bitmap
             if ( m_bitmapMask )
             {
                 CGImageRef tempImage = CGBitmapContextCreateImage( m_hBitmap );
@@ -643,6 +700,7 @@ CGImageRef wxBitmapRefData::CreateCGImage() const
                 CGImageRelease(tempImage);
             }
             else
+#endif
                 image = CGBitmapContextCreateImage( m_hBitmap );
         }
         else
@@ -773,11 +831,7 @@ void wxBitmapRefData::Free()
         m_hBitmap = NULL ;
     }
 
-    if (m_bitmapMask)
-    {
-        delete m_bitmapMask;
-        m_bitmapMask = NULL;
-    }
+    wxDELETE(m_bitmapMask);
 }
 
 wxBitmapRefData::~wxBitmapRefData()
@@ -960,6 +1014,11 @@ wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type)
     LoadFile(filename, type);
 }
 
+wxBitmap::wxBitmap(CGImageRef image)
+{
+    (void) Create(image);
+}
+
 wxGDIRefData* wxBitmap::CreateGDIRefData() const
 {
     return new wxBitmapRefData;
@@ -1014,16 +1073,25 @@ IconRef wxBitmap::CreateIconRef() const
 }
 #endif
 
-#if wxOSX_USE_COCOA_OR_IPHONE
+#if wxOSX_USE_COCOA
 
 WX_NSImage wxBitmap::GetNSImage() const
 {
     wxCFRef< CGImageRef > cgimage(CreateCGImage());
-    return wxOSXCreateNSImageFromCGImage( cgimage );
+    return wxOSXGetNSImageFromCGImage( cgimage );
 }
 
 #endif
 
+#if wxOSX_USE_IPHONE
+
+WX_UIImage wxBitmap::GetUIImage() const
+{
+    wxCFRef< CGImageRef > cgimage(CreateCGImage());
+    return wxOSXGetUIImageFromCGImage( cgimage );
+}
+
+#endif
 wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
 {
     wxCHECK_MSG( Ok() &&
@@ -1098,6 +1166,16 @@ bool wxBitmap::Create(int w, int h, int d)
     return M_BITMAPDATA->IsOk() ;
 }
 
+
+bool wxBitmap::Create(CGImageRef image)
+{
+    UnRef();
+    
+    m_refData = new wxBitmapRefData( image );
+    
+    return M_BITMAPDATA->IsOk() ;
+}
+
 bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type)
 {
     UnRef();
@@ -1157,7 +1235,7 @@ wxBitmap::wxBitmap(const wxImage& image, int depth)
     int height = image.GetHeight();
 
     wxBitmapRefData* bitmapRefData;
-    
+
     m_refData = bitmapRefData = new wxBitmapRefData( width , height , depth ) ;
 
     if ( bitmapRefData->IsOk())
@@ -1640,7 +1718,89 @@ WXHBITMAP wxMask::GetHBITMAP() const
 // Standard Handlers
 // ----------------------------------------------------------------------------
 
-#if !defined( __LP64__ ) && !defined(__WXOSX_IPHONE__) 
+class WXDLLEXPORT wxBundleResourceHandler: public wxBitmapHandler
+{
+    DECLARE_ABSTRACT_CLASS(wxPNGResourceHandler)
+    
+public:
+    inline wxBundleResourceHandler()
+    {
+    };
+    
+    virtual bool LoadFile(wxBitmap *bitmap,
+                          const wxString& name,
+                          wxBitmapType type,
+                          int desiredWidth,
+                          int desiredHeight);
+};
+
+IMPLEMENT_ABSTRACT_CLASS(wxBundleResourceHandler, wxBitmapHandler);
+
+class WXDLLEXPORT wxPNGResourceHandler: public wxBundleResourceHandler
+{
+    DECLARE_DYNAMIC_CLASS(wxPNGResourceHandler)
+    
+public:
+    inline wxPNGResourceHandler()
+    {
+        SetName(wxT("PNG resource"));
+        SetExtension("PNG");
+        SetType(wxBITMAP_TYPE_PNG_RESOURCE);
+    };
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxPNGResourceHandler, wxBundleResourceHandler)
+
+class WXDLLEXPORT wxJPEGResourceHandler: public wxBundleResourceHandler
+{
+    DECLARE_DYNAMIC_CLASS(wxPNGResourceHandler)
+    
+public:
+    inline wxJPEGResourceHandler()
+    {
+        SetName(wxT("JPEG resource"));
+        SetExtension("JPEG");
+        SetType(wxBITMAP_TYPE_JPEG_RESOURCE);
+    };
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxJPEGResourceHandler, wxBundleResourceHandler)
+
+bool wxBundleResourceHandler::LoadFile(wxBitmap *bitmap,
+                                     const wxString& name,
+                                     wxBitmapType WXUNUSED(type),
+                                     int WXUNUSED(desiredWidth),
+                                     int WXUNUSED(desiredHeight))
+{
+    wxString ext = GetExtension().Lower();
+    wxCFStringRef resname(name);
+    wxCFStringRef restype(ext);
+    
+    wxCFRef<CFURLRef> imageURL(CFBundleCopyResourceURL(CFBundleGetMainBundle(), resname, restype, NULL));
+    
+    if ( imageURL.get() != NULL )
+    {
+        // Create the data provider object
+        wxCFRef<CGDataProviderRef> provider(CGDataProviderCreateWithURL (imageURL) );
+        CGImageRef image = NULL;
+        
+        if ( ext == "jpeg" )
+            image = CGImageCreateWithJPEGDataProvider (provider, NULL, true,
+                                                   kCGRenderingIntentDefault);
+        else if ( ext == "png" )
+            image = CGImageCreateWithPNGDataProvider (provider, NULL, true,
+                                                       kCGRenderingIntentDefault);
+        if ( image != NULL )
+        {
+            bitmap->Create(image);
+            CGImageRelease(image);
+        }
+    }
+        
+    return false ;
+}
+
+#if !defined( __LP64__ ) && !defined(__WXOSX_IPHONE__)
 
 class WXDLLEXPORT wxPICTResourceHandler: public wxBitmapHandler
 {
@@ -1654,8 +1814,11 @@ public:
         SetType(wxBITMAP_TYPE_PICT_RESOURCE);
     };
 
-    virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
-          int desiredWidth, int desiredHeight);
+    virtual bool LoadFile(wxBitmap *bitmap,
+                          const wxString& name,
+                          wxBitmapType type,
+                          int desiredWidth,
+                          int desiredHeight);
 };
 
 IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler)
@@ -1663,7 +1826,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler)
 
 bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap,
                                      const wxString& name,
-                                     long WXUNUSED(flags),
+                                     wxBitmapType WXUNUSED(type),
                                      int WXUNUSED(desiredWidth),
                                      int WXUNUSED(desiredHeight))
 {
@@ -1696,9 +1859,11 @@ void wxBitmap::InitStandardHandlers()
 #if !defined( __LP64__ ) && !defined(__WXOSX_IPHONE__)
     AddHandler( new wxPICTResourceHandler ) ;
 #endif
-#if wxOSX_USE_CARBON
+#if wxOSX_USE_COCOA_OR_CARBON
     AddHandler( new wxICONResourceHandler ) ;
 #endif
+    AddHandler( new wxPNGResourceHandler );
+    AddHandler( new wxJPEGResourceHandler );
 }
 
 // ----------------------------------------------------------------------------