]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/classic/cursor.cpp
Override GetPixelSize on OS X as the base impl creates a wxScreenDC each time, which...
[wxWidgets.git] / src / mac / classic / cursor.cpp
index b780a675c9baa1f7ced9d82fc0052de733569aff..d299c18b340260bc48184e8b77b71d54f319ef49 100644 (file)
@@ -1,31 +1,33 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        cursor.cpp
+// Name:        src/mac/classic/cursor.cpp
 // Purpose:     wxCursor class
 // Author:      Stefan Csomor
 // Modified by:
 // Created:     1998-01-01
 // RCS-ID:      $Id$
 // Copyright:   (c) Stefan Csomor
-// Licence:       wxWindows licence
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "cursor.h"
-#endif
+#include "wx/wxprec.h"
 
-#include "wx/defs.h"
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
 
-#include "wx/app.h"
 #include "wx/cursor.h"
-#include "wx/icon.h"
-#include "wx/image.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/app.h"
+    #include "wx/icon.h"
+    #include "wx/image.h"
+#endif // WX_PRECOMP
+
 #include "wx/xpmdecod.h"
 
 #include "wx/mac/private.h"
 
-#if !USE_SHARED_LIBRARIES
 IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxBitmap)
-#endif
 
 const short kwxCursorBullseye = 10 ;
 const short kwxCursorBlank = 11 ;
@@ -47,7 +49,7 @@ wxCursor    gMacCurrentCursor ;
 
 wxCursorRefData::wxCursorRefData()
 {
-    m_width = 16; 
+    m_width = 16;
     m_height = 16;
     m_hCursor = NULL ;
     m_disposeHandle = false ;
@@ -65,7 +67,7 @@ wxCursorRefData::~wxCursorRefData()
     else if ( m_disposeHandle )
     {
         ::DisposeHandle( (Handle ) m_hCursor ) ;
-    } 
+    }
     else if ( m_releaseHandle )
     {
         // we don't release the resource since it may already
@@ -88,24 +90,24 @@ wxCursor::wxCursor( const wxImage &image )
     CreateFromImage( image ) ;
 }
 
-wxCursor::wxCursor(const char **bits) 
+wxCursor::wxCursor(const char **bits)
 {
     (void) CreateFromXpm(bits);
 }
 
-wxCursor::wxCursor(char **bits) 
+wxCursor::wxCursor(char **bits)
 {
     (void) CreateFromXpm((const char **)bits);
 }
 
 bool wxCursor::CreateFromXpm(const char **bits)
 {
-    wxCHECK_MSG( bits != NULL, FALSE, wxT("invalid cursor data") )
+    wxCHECK_MSG( bits != NULL, false, wxT("invalid cursor data") );
     wxXPMDecoder decoder;
     wxImage img = decoder.ReadData(bits);
-    wxCHECK_MSG( img.Ok(), FALSE, wxT("invalid cursor data") )    
-       CreateFromImage( img ) ;
-    return TRUE;
+    wxCHECK_MSG( img.Ok(), false, wxT("invalid cursor data") );
+    CreateFromImage( img ) ;
+    return true;
 }
 
 short GetCTabIndex( CTabHandle colors , RGBColor *col )
@@ -126,25 +128,44 @@ short GetCTabIndex( CTabHandle colors , RGBColor *col )
     return retval ;
 }
 
-void wxCursor::CreateFromImage(const wxImage & image) 
+void wxCursor::CreateFromImage(const wxImage & image)
 {
     m_refData = new wxCursorRefData;
 
-    wxImage image16 = image.Scale(16,16) ;
-       unsigned char * rgbBits = image16.GetData();
-    
-    int w = image16.GetWidth()  ;
-    int h = image16.GetHeight() ;
+    int w = 16;
+    int h = 16;
+
+    int hotSpotX = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X);
+    int hotSpotY = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y);
+    int image_w = image.GetWidth();
+    int image_h = image.GetHeight();
+
+    wxASSERT_MSG( hotSpotX >= 0 && hotSpotX < image_w &&
+                  hotSpotY >= 0 && hotSpotY < image_h,
+                  _T("invalid cursor hot spot coordinates") );
+
+    wxImage image16(image); // final image of correct size
+
+    // if image is too small then place it in the center, resize it if too big
+    if ((w > image_w) && (h > image_h))
+    {
+        wxPoint offset((w - image_w)/2, (h - image_h)/2);
+        hotSpotX = hotSpotX + offset.x;
+        hotSpotY = hotSpotY + offset.y;
+
+        image16 = image.Size(wxSize(w, h), offset);
+    }
+    else if ((w != image_w) || (h != image_h))
+    {
+        hotSpotX = int(hotSpotX * double(w) / double(image_w));
+        hotSpotY = int(hotSpotY * double(h) / double(image_h));
+
+        image16 = image.Scale(w, h);
+    }
+
+    unsigned char * rgbBits = image16.GetData();
     bool bHasMask = image16.HasMask() ;
 
-       int hotSpotX = image16.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X);
-    int hotSpotY = image16.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y);
-    if (hotSpotX < 0 || hotSpotX >= w)
-            hotSpotX = 0;
-    if (hotSpotY < 0 || hotSpotY >= h)
-            hotSpotY = 0;
-            
 #if 0
     // monochrome implementation
     M_CURSORDATA->m_hCursor = NewHandle( sizeof( Cursor ) ) ;
@@ -153,7 +174,7 @@ void wxCursor::CreateFromImage(const wxImage & image)
     CursPtr cp = *(CursHandle)M_CURSORDATA->m_hCursor ;
     memset( cp->data , 0 , sizeof( Bits16 ) ) ;
     memset( cp->mask , 0 , sizeof( Bits16 ) ) ;
-    
+
     unsigned char mr = image16.GetMaskRed() ;
     unsigned char mg = image16.GetMaskGreen() ;
     unsigned char mb = image16.GetMaskBlue() ;
@@ -161,7 +182,7 @@ void wxCursor::CreateFromImage(const wxImage & image)
     {
         short rowbits = 0 ;
         short maskbits = 0 ;
-        
+
         for ( int x = 0 ; x < w ; ++x )
         {
             long pos = (y * w + x) * 3;
@@ -208,36 +229,36 @@ void wxCursor::CreateFromImage(const wxImage & image)
     }
     HLock( (Handle) ch) ;
     (**ch).crsrType = 0x8001 ; // color cursors
-    (**ch).crsrMap = pm ; 
+    (**ch).crsrMap = pm ;
     short bytesPerRow = bytesPerPixel * extent ;
 
-    (**pm).baseAddr = 0; 
+    (**pm).baseAddr = 0;
     (**pm).rowBytes = bytesPerRow | 0x8000;
-    (**pm).bounds = bounds;        
-    (**pm).pmVersion = 0;           
-    (**pm).packType = 0;            
-    (**pm).packSize = 0;            
+    (**pm).bounds = bounds;
+    (**pm).pmVersion = 0;
+    (**pm).packType = 0;
+    (**pm).packSize = 0;
     (**pm).hRes = 0x00480000; /* 72 DPI default res */
     (**pm).vRes = 0x00480000; /* 72 DPI default res */
     (**pm).pixelSize = depth;
     (**pm).pixelType = 0;
-    (**pm).cmpCount = 1; 
+    (**pm).cmpCount = 1;
     (**pm).cmpSize = depth;
     (**pm).pmTable = newColors;
 
-    (**ch).crsrData = NewHandleClear( extent * bytesPerRow ) ;  
+    (**ch).crsrData = NewHandleClear( extent * bytesPerRow ) ;
     (**ch).crsrXData = NULL ;
     (**ch).crsrXValid = 0;
     (**ch).crsrXHandle = NULL;
 
     (**ch).crsrHotSpot.h = hotSpotX ;
     (**ch).crsrHotSpot.v = hotSpotY ;
-    (**ch).crsrXTable = NULL ; 
+    (**ch).crsrXTable = NULL ;
     (**ch).crsrID = GetCTSeed() ;
-    
+
     memset( (**ch).crsr1Data  , 0 , sizeof( Bits16 ) ) ;
     memset( (**ch).crsrMask , 0 , sizeof( Bits16 ) ) ;
-    
+
     unsigned char mr = image16.GetMaskRed() ;
     unsigned char mg = image16.GetMaskGreen() ;
     unsigned char mb = image16.GetMaskBlue() ;
@@ -245,7 +266,7 @@ void wxCursor::CreateFromImage(const wxImage & image)
     {
         short rowbits = 0 ;
         short maskbits = 0 ;
-        
+
         for ( int x = 0 ; x < w ; ++x )
         {
             long pos = (y * w + x) * 3;
@@ -254,7 +275,7 @@ void wxCursor::CreateFromImage(const wxImage & image)
             unsigned char g = rgbBits[pos+1] ;
             unsigned char b = rgbBits[pos+2] ;
             RGBColor col = { 0xFFFF ,0xFFFF, 0xFFFF } ;
-            
+
             if ( bHasMask && r==mr && g==mg && b==mb )
             {
                 // masked area, does not appear anywhere
@@ -266,10 +287,10 @@ void wxCursor::CreateFromImage(const wxImage & image)
                     rowbits |= ( 1 << (15-x) ) ;
                 }
                 maskbits |= ( 1 << (15-x) ) ;
-                
+
                 col = *((RGBColor*) wxColor( r , g , b ).GetPixel()) ;
             }
-            *((*(**ch).crsrData) + y * bytesPerRow + x) = 
+            *((*(**ch).crsrData) + y * bytesPerRow + x) =
                 GetCTabIndex( newColors , &col) ;
         }
         (**ch).crsr1Data[y] = rowbits ;
@@ -279,7 +300,7 @@ void wxCursor::CreateFromImage(const wxImage & image)
     {
         memcpy( (**ch).crsrMask , (**ch).crsr1Data , sizeof( Bits16) ) ;
     }
-    
+
     HUnlock((Handle) ch) ;
     M_CURSORDATA->m_hCursor = ch ;
     M_CURSORDATA->m_isColorCursor = true ;
@@ -292,8 +313,8 @@ wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int ho
     if ( flags == wxBITMAP_TYPE_MACCURSOR_RESOURCE )
     {
         Str255 theName ;
-               wxMacStringToPascal( cursor_file , theName ) ;
-        
+        wxMacStringToPascal( cursor_file , theName ) ;
+
         wxStAppResource resload ;
         Handle resHandle = ::GetNamedResource( 'crsr' , theName ) ;
         if ( resHandle )
@@ -307,7 +328,7 @@ wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int ho
                 M_CURSORDATA->m_isColorCursor = true ;
         }
         else
-        {       
+        {
             Handle resHandle = ::GetNamedResource( 'CURS' , theName ) ;
             if ( resHandle )
             {
@@ -339,7 +360,7 @@ wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int ho
 wxCursor::wxCursor(int cursor_type)
 {
     m_refData = new wxCursorRefData;
-    
+
     switch (cursor_type)
     {
     case wxCURSOR_COPY_ARROW:
@@ -472,7 +493,7 @@ wxCursor::wxCursor(int cursor_type)
         M_CURSORDATA->m_releaseHandle = true ;
 }
 
-void wxCursor::MacInstall() const 
+void wxCursor::MacInstall() const
 {
     gMacCurrentCursor = *this ;
     if ( m_refData && M_CURSORDATA->m_themeCursor != -1 )
@@ -501,5 +522,3 @@ void wxSetCursor(const wxCursor& cursor)
 {
     cursor.MacInstall() ;
 }
-
-