From c5e591789b5af00f82b98f0c19833f8d8c1bdc62 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sun, 2 Mar 2003 22:44:08 +0000 Subject: [PATCH] xpm support, color cursor support git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19435 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/mac/carbon/cursor.cpp | 140 +++++++++++++++++++++++++++++++++++++- src/mac/cursor.cpp | 140 +++++++++++++++++++++++++++++++++++++- 2 files changed, 276 insertions(+), 4 deletions(-) diff --git a/src/mac/carbon/cursor.cpp b/src/mac/carbon/cursor.cpp index 79633bf14d..d698913890 100644 --- a/src/mac/carbon/cursor.cpp +++ b/src/mac/carbon/cursor.cpp @@ -19,6 +19,8 @@ #include "wx/cursor.h" #include "wx/icon.h" #include "wx/image.h" +#include "wx/xpmdecod.h" + #include "wx/mac/private.h" #if !USE_SHARED_LIBRARIES @@ -86,6 +88,44 @@ wxCursor::wxCursor( const wxImage &image ) CreateFromImage( image ) ; } +wxCursor::wxCursor(const char **bits) +{ + (void) CreateFromXpm(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") ) + wxXPMDecoder decoder; + wxImage img = decoder.ReadData(bits); + wxCHECK_MSG( img.Ok(), FALSE, wxT("invalid cursor data") ) + CreateFromImage( img ) ; + return TRUE; +} + +short GetCTabIndex( CTabHandle colors , RGBColor *col ) +{ + short retval = 0 ; + unsigned long bestdiff = 0xFFFF ; + for ( int i = 0 ; i < (**colors).ctSize ; ++i ) + { + unsigned long diff = abs(col->red - (**colors).ctTable[i].rgb.red ) + + abs(col->green - (**colors).ctTable[i].rgb.green ) + + abs(col->blue - (**colors).ctTable[i].rgb.blue ) ; + if ( diff < bestdiff ) + { + bestdiff = diff ; + retval = (**colors).ctTable[i].value ; + } + } + return retval ; +} + void wxCursor::CreateFromImage(const wxImage & image) { m_refData = new wxCursorRefData; @@ -105,6 +145,8 @@ void wxCursor::CreateFromImage(const wxImage & image) if (hotSpotY < 0 || hotSpotY >= h) hotSpotY = 0; +#if 0 + // monochrome implementation M_CURSORDATA->m_hCursor = NewHandle( sizeof( Cursor ) ) ; M_CURSORDATA->m_disposeHandle = true ; HLock( (Handle) M_CURSORDATA->m_hCursor ) ; @@ -133,7 +175,7 @@ void wxCursor::CreateFromImage(const wxImage & image) } else { - if ( (int)r + (int)g + (int)b < 0x60 ) + if ( (int)r + (int)g + (int)b < 0x0200 ) { rowbits |= ( 1 << (15-x) ) ; } @@ -147,10 +189,101 @@ void wxCursor::CreateFromImage(const wxImage & image) { memcpy( cp->mask , cp->data , sizeof( Bits16) ) ; } - cp->hotSpot.h = hotSpotX ; cp->hotSpot.v = hotSpotY ; HUnlock( (Handle) M_CURSORDATA->m_hCursor ) ; +#else + PixMapHandle pm = (PixMapHandle) NewHandleClear( sizeof (PixMap)) ; + short extent = 16 ; + short bytesPerPixel = 1 ; + short depth = 8 ; + Rect bounds = { 0 , 0 , extent , extent } ; + CCrsrHandle ch = (CCrsrHandle) NewHandleClear ( sizeof( CCrsr ) ) ; + CTabHandle newColors = GetCTable( 8 ) ; + HandToHand((Handle *) &newColors); + // set the values to the indices + for ( int i = 0 ; i < (**newColors).ctSize ; ++i ) + { + (**newColors).ctTable[i].value = i ; + } + HLock( (Handle) ch) ; + (**ch).crsrType = 0x8001 ; // color cursors + (**ch).crsrMap = pm ; + short bytesPerRow = bytesPerPixel * extent ; + + (**pm).baseAddr = 0; + (**pm).rowBytes = bytesPerRow | 0x8000; + (**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).cmpSize = depth; + (**pm).pmTable = newColors; + + (**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).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() ; + for ( int y = 0 ; y < h ; ++y ) + { + short rowbits = 0 ; + short maskbits = 0 ; + + for ( int x = 0 ; x < w ; ++x ) + { + long pos = (y * w + x) * 3; + + unsigned char r = rgbBits[pos] ; + 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 + } + else + { + if ( (int)r + (int)g + (int)b < 0x0200 ) + { + rowbits |= ( 1 << (15-x) ) ; + } + maskbits |= ( 1 << (15-x) ) ; + + col = *((RGBColor*) wxColor( r , g , b ).GetPixel()) ; + } + *((*(**ch).crsrData) + y * bytesPerRow + x) = + GetCTabIndex( newColors , &col) ; + } + (**ch).crsr1Data[y] = rowbits ; + (**ch).crsrMask[y] = maskbits ; + } + if ( !bHasMask ) + { + memcpy( (**ch).crsrMask , (**ch).crsr1Data , sizeof( Bits16) ) ; + } + + HUnlock((Handle) ch) ; + M_CURSORDATA->m_hCursor = ch ; + M_CURSORDATA->m_isColorCursor = true ; +#endif } wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int hotSpotY) @@ -215,6 +348,9 @@ wxCursor::wxCursor(int cursor_type) switch (cursor_type) { + case wxCURSOR_COPY_ARROW: + M_CURSORDATA->m_themeCursor = kThemeCopyArrowCursor ; + break; case wxCURSOR_WAIT: M_CURSORDATA->m_themeCursor = kThemeWatchCursor ; break; diff --git a/src/mac/cursor.cpp b/src/mac/cursor.cpp index 79633bf14d..d698913890 100644 --- a/src/mac/cursor.cpp +++ b/src/mac/cursor.cpp @@ -19,6 +19,8 @@ #include "wx/cursor.h" #include "wx/icon.h" #include "wx/image.h" +#include "wx/xpmdecod.h" + #include "wx/mac/private.h" #if !USE_SHARED_LIBRARIES @@ -86,6 +88,44 @@ wxCursor::wxCursor( const wxImage &image ) CreateFromImage( image ) ; } +wxCursor::wxCursor(const char **bits) +{ + (void) CreateFromXpm(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") ) + wxXPMDecoder decoder; + wxImage img = decoder.ReadData(bits); + wxCHECK_MSG( img.Ok(), FALSE, wxT("invalid cursor data") ) + CreateFromImage( img ) ; + return TRUE; +} + +short GetCTabIndex( CTabHandle colors , RGBColor *col ) +{ + short retval = 0 ; + unsigned long bestdiff = 0xFFFF ; + for ( int i = 0 ; i < (**colors).ctSize ; ++i ) + { + unsigned long diff = abs(col->red - (**colors).ctTable[i].rgb.red ) + + abs(col->green - (**colors).ctTable[i].rgb.green ) + + abs(col->blue - (**colors).ctTable[i].rgb.blue ) ; + if ( diff < bestdiff ) + { + bestdiff = diff ; + retval = (**colors).ctTable[i].value ; + } + } + return retval ; +} + void wxCursor::CreateFromImage(const wxImage & image) { m_refData = new wxCursorRefData; @@ -105,6 +145,8 @@ void wxCursor::CreateFromImage(const wxImage & image) if (hotSpotY < 0 || hotSpotY >= h) hotSpotY = 0; +#if 0 + // monochrome implementation M_CURSORDATA->m_hCursor = NewHandle( sizeof( Cursor ) ) ; M_CURSORDATA->m_disposeHandle = true ; HLock( (Handle) M_CURSORDATA->m_hCursor ) ; @@ -133,7 +175,7 @@ void wxCursor::CreateFromImage(const wxImage & image) } else { - if ( (int)r + (int)g + (int)b < 0x60 ) + if ( (int)r + (int)g + (int)b < 0x0200 ) { rowbits |= ( 1 << (15-x) ) ; } @@ -147,10 +189,101 @@ void wxCursor::CreateFromImage(const wxImage & image) { memcpy( cp->mask , cp->data , sizeof( Bits16) ) ; } - cp->hotSpot.h = hotSpotX ; cp->hotSpot.v = hotSpotY ; HUnlock( (Handle) M_CURSORDATA->m_hCursor ) ; +#else + PixMapHandle pm = (PixMapHandle) NewHandleClear( sizeof (PixMap)) ; + short extent = 16 ; + short bytesPerPixel = 1 ; + short depth = 8 ; + Rect bounds = { 0 , 0 , extent , extent } ; + CCrsrHandle ch = (CCrsrHandle) NewHandleClear ( sizeof( CCrsr ) ) ; + CTabHandle newColors = GetCTable( 8 ) ; + HandToHand((Handle *) &newColors); + // set the values to the indices + for ( int i = 0 ; i < (**newColors).ctSize ; ++i ) + { + (**newColors).ctTable[i].value = i ; + } + HLock( (Handle) ch) ; + (**ch).crsrType = 0x8001 ; // color cursors + (**ch).crsrMap = pm ; + short bytesPerRow = bytesPerPixel * extent ; + + (**pm).baseAddr = 0; + (**pm).rowBytes = bytesPerRow | 0x8000; + (**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).cmpSize = depth; + (**pm).pmTable = newColors; + + (**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).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() ; + for ( int y = 0 ; y < h ; ++y ) + { + short rowbits = 0 ; + short maskbits = 0 ; + + for ( int x = 0 ; x < w ; ++x ) + { + long pos = (y * w + x) * 3; + + unsigned char r = rgbBits[pos] ; + 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 + } + else + { + if ( (int)r + (int)g + (int)b < 0x0200 ) + { + rowbits |= ( 1 << (15-x) ) ; + } + maskbits |= ( 1 << (15-x) ) ; + + col = *((RGBColor*) wxColor( r , g , b ).GetPixel()) ; + } + *((*(**ch).crsrData) + y * bytesPerRow + x) = + GetCTabIndex( newColors , &col) ; + } + (**ch).crsr1Data[y] = rowbits ; + (**ch).crsrMask[y] = maskbits ; + } + if ( !bHasMask ) + { + memcpy( (**ch).crsrMask , (**ch).crsr1Data , sizeof( Bits16) ) ; + } + + HUnlock((Handle) ch) ; + M_CURSORDATA->m_hCursor = ch ; + M_CURSORDATA->m_isColorCursor = true ; +#endif } wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int hotSpotY) @@ -215,6 +348,9 @@ wxCursor::wxCursor(int cursor_type) switch (cursor_type) { + case wxCURSOR_COPY_ARROW: + M_CURSORDATA->m_themeCursor = kThemeCopyArrowCursor ; + break; case wxCURSOR_WAIT: M_CURSORDATA->m_themeCursor = kThemeWatchCursor ; break; -- 2.45.2