From bff4ec6360d28f3309e5199685950b43ab5e079a Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Thu, 21 Feb 2002 15:22:58 +0000
Subject: [PATCH] wxCursor(wxImage) added (Chris Elliott, patch 517439)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14340 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/cursor.tex |  9 +++++
 include/wx/msw/cursor.h  |  4 ++-
 src/msw/cursor.cpp       | 73 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/docs/latex/wx/cursor.tex b/docs/latex/wx/cursor.tex
index 5719407d43..44e28edc18 100644
--- a/docs/latex/wx/cursor.tex
+++ b/docs/latex/wx/cursor.tex
@@ -67,6 +67,15 @@ icon file, to specify the cursor hotspot relative to the top left of the image.
 
 Constructs a cursor using a cursor identifier.
 
+\func{}{wxCursor}{\param{const wxImage\&}{ image}}
+
+Constructs a cursor from a wxImage. The cursor is monochome, colors with the RGB elements all greater
+than 127 will be foreground, colors less than this background. The mask (if any) will be used as transparent.
+
+In MSW the foreground will be white and the background black. The cursor is resized to 32x32
+In GTK, the two most frequent colors will be used for foreground and background. The cursor will be displayed
+at the size of the image.
+
 \func{}{wxCursor}{\param{const wxCursor\&}{ cursor}}
 
 Copy constructor. This uses reference counting so is a cheap operation.
diff --git a/include/wx/msw/cursor.h b/include/wx/msw/cursor.h
index 4e28fcc178..9b98d72390 100644
--- a/include/wx/msw/cursor.h
+++ b/include/wx/msw/cursor.h
@@ -12,6 +12,8 @@
 #ifndef _WX_CURSOR_H_
 #define _WX_CURSOR_H_
 
+#include <wx/image.h>
+
 #ifdef __GNUG__
     #pragma interface "cursor.h"
 #endif
@@ -55,7 +57,7 @@ public:
 
     // Copy constructors
     wxCursor(const wxCursor& cursor) { Ref(cursor); }
-
+    wxCursor(const wxImage & image) ;
     wxCursor(const char bits[], int width, int height,
              int hotSpotX = -1, int hotSpotY = -1,
              const char maskBits[] = NULL);
diff --git a/src/msw/cursor.cpp b/src/msw/cursor.cpp
index 09ab2ba32e..bbe9e4662c 100644
--- a/src/msw/cursor.cpp
+++ b/src/msw/cursor.cpp
@@ -120,6 +120,79 @@ wxCursor::wxCursor()
 {
 }
 
+wxCursor::wxCursor( const wxImage & image )
+{
+    //image has to be 32x32
+    wxImage image32 = image.Scale(32,32);
+    unsigned char * rgbBits = image32.GetData();
+    int w = image32.GetWidth()  ;
+    int h = image32.GetHeight() ;
+    bool bHasMask = image32.HasMask() ;
+    int imagebitcount = (w*h)/8;
+
+    unsigned char r, g, b ;
+    unsigned char * bits = new unsigned char [imagebitcount];
+    unsigned char * maskBits = new unsigned char [imagebitcount];
+
+    int i,j, i8; unsigned char c, cMask;
+    for (i=0; i<imagebitcount; i++)
+        {
+        bits[i] = 0;
+        i8 = i * 8;
+//unlike gtk, the pixels go in the opposite order in the bytes
+        cMask = 128;
+        for (j=0; j<8; j++)
+           {
+           // possible overflow if we do the summation first ?
+           c = rgbBits[(i8+j)*3]/3 + rgbBits[(i8+j)*3+1]/3 + rgbBits[(i8+j)*3+2]/3 ;
+           //if average value is > mid grey
+           if (c>127)
+              bits[i] = bits[i] | cMask ;
+           cMask = cMask / 2 ;
+           }
+        }
+    if (bHasMask)
+        {
+        r = image32.GetMaskRed() ;
+        g = image32.GetMaskGreen() ;
+        b = image32.GetMaskBlue() ;
+
+        for (i=0; i<imagebitcount; i++)
+        {
+        maskBits[i] = 0x0;
+        i8 = i * 8;
+
+        cMask = 128;
+        for (j=0; j<8; j++)
+           {
+           if (rgbBits[(i8+j)*3] == r && rgbBits[(i8+j)*3+1] == g && rgbBits[(i8+j)*3+2] == b)
+              maskBits[i] = maskBits[i] | cMask ;
+           cMask = cMask / 2 ;
+           }
+        }
+        }
+      else
+        {
+        for (i=0; i<imagebitcount; i++)
+            maskBits[i]= 0x0 ;
+        }
+
+    int hotSpotX = image32.GetOptionInt(wxCUR_HOTSPOT_X);
+    int hotSpotY = image32.GetOptionInt(wxCUR_HOTSPOT_Y);
+    if (hotSpotX < 0 || hotSpotX >= w)
+            hotSpotX = 0;
+    if (hotSpotY < 0 || hotSpotY >= h)
+            hotSpotY = 0;
+
+    wxCursorRefData *refData = new wxCursorRefData;
+    m_refData = refData;
+    refData->m_hCursor = (WXHCURSOR) CreateCursor ( wxGetInstance(), hotSpotX, hotSpotY, w, h, /*AND*/ maskBits, /*XOR*/ bits   );
+  
+    delete [] bits ;
+    delete [] maskBits;
+
+}
+
 wxCursor::wxCursor(const char WXUNUSED(bits)[],
                    int WXUNUSED(width),
                    int WXUNUSED(height),
-- 
2.50.0

