]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/bitmap.cpp
rewritten to use wxTheMimeTypesManager
[wxWidgets.git] / src / msw / bitmap.cpp
index 3dddc4177e9728509dd05904e740460f156f1b7b..8eba1311e536c396c4b1e7069cd6767056e976ec 100644 (file)
 // macros
 // ----------------------------------------------------------------------------
 
-#if !USE_SHARED_LIBRARIES
     IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
     IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
 
     IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
-#endif
 
 // ============================================================================
 // implementation
@@ -122,12 +120,37 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon)
     wxBitmapRefData *refData = new wxBitmapRefData;
     m_refData = refData;
 
-    refData->m_width = icon.GetWidth();
-    refData->m_height = icon.GetHeight();
+    int w = icon.GetWidth(),
+        h = icon.GetHeight();
+
+    refData->m_width = w;
+    refData->m_height = h;
     refData->m_depth = wxDisplayDepth();
 
     refData->m_hBitmap = (WXHBITMAP)iconInfo.hbmColor;
-    refData->m_bitmapMask = new wxMask((WXHBITMAP)iconInfo.hbmMask);
+
+    // the mask returned by GetIconInfo() is inversed compared to the usual
+    // wxWin convention
+    HBITMAP hbmpMask = ::CreateBitmap(w, h, 1, 1, 0);
+
+    // the icons mask is opposite to the usual wxWin convention
+    HDC dcSrc = ::CreateCompatibleDC(NULL);
+    HDC dcDst = ::CreateCompatibleDC(NULL);
+    (void)SelectObject(dcSrc, iconInfo.hbmMask);
+    (void)SelectObject(dcDst, hbmpMask);
+
+    HBRUSH brush = ::CreateSolidBrush(RGB(255, 255, 255));
+    RECT rect = { 0, 0, w, h };
+    FillRect(dcDst, &rect, brush);
+
+    BitBlt(dcDst, 0, 0, w, h, dcSrc, 0, 0, SRCINVERT);
+
+    SelectObject(dcDst, NULL);
+    SelectObject(dcSrc, NULL);
+    DeleteDC(dcDst);
+    DeleteDC(dcSrc);
+
+    refData->m_bitmapMask = new wxMask((WXHBITMAP)hbmpMask);
 
 #if WXWIN_COMPATIBILITY_2
     refData->m_ok = TRUE;
@@ -149,9 +172,9 @@ bool wxBitmap::CopyFromCursor(const wxCursor& cursor)
     wxFAIL_MSG( _T("don't know how to convert cursor to bitmap") );
 
     return FALSE;
-#endif // Win16
-
+#else
     return CopyFromIconOrCursor(cursor);
+#endif // Win16
 }
 
 bool wxBitmap::CopyFromIcon(const wxIcon& icon)
@@ -204,28 +227,106 @@ wxBitmap::~wxBitmap()
         wxTheBitmapList->DeleteObject(this);
 }
 
-wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
+wxBitmap::wxBitmap(const char bits[], int width, int height, int depth)
 {
     Init();
 
     wxBitmapRefData *refData = new wxBitmapRefData;
     m_refData = refData;
 
-    refData->m_width = the_width;
-    refData->m_height = the_height;
-    refData->m_depth = no_bits;
+    refData->m_width = width;
+    refData->m_height = height;
+    refData->m_depth = depth;
     refData->m_numColors = 0;
     refData->m_selectedInto = NULL;
 
-    HBITMAP hbmp = ::CreateBitmap(the_width, the_height, 1, no_bits, bits);
+    char *data;
+    if ( depth == 1 )
+    {
+        // we assume that it is in XBM format which is not quite the same as
+        // the format CreateBitmap() wants because the order of bytes in the
+        // line is inversed!
+        static const size_t bytesPerLine = (width + 7) / 8;
+        static const size_t padding = bytesPerLine % 2;
+        static const size_t len = height * ( padding + bytesPerLine );
+        data = (char *)malloc(len);
+        const char *src = bits;
+        char *dst = data;
+
+        for ( int rows = 0; rows < height; rows++ )
+        {
+            // note that offset cannot be size_t due to >= 0 test!
+            for ( int offset = bytesPerLine - 1; offset >= 0; offset-- )
+            {
+                *dst++ = *(src + offset);
+            }
+
+            if ( padding )
+                *dst++ = 0;
+
+            src += bytesPerLine;
+        }
+    }
+    else
+    {
+        // bits should already be in Windows standard format
+        data = (char *)bits;    // const_cast is harmless
+    }
+
+    HBITMAP hbmp = ::CreateBitmap(width, height, 1, depth, data);
     if ( !hbmp )
     {
         wxLogLastError("CreateBitmap");
     }
 
+    if ( data != bits )
+    {
+        free(data);
+    }
+
     SetHBITMAP((WXHBITMAP)hbmp);
 }
 
+// GRG, Dic/99
+wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const
+{
+    wxCHECK_MSG( Ok() &&
+                 (rect.x >= 0) && (rect.y >= 0) &&
+                 (rect.x+rect.width <= GetWidth()) &&
+                 (rect.y+rect.height <= GetHeight()),
+                 wxNullBitmap, wxT("Invalid bitmap or bitmap region") );
+
+    wxBitmap ret( rect.width, rect.height, GetDepth() );
+    wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
+
+    // copy bitmap data
+    HDC dcSrc = ::CreateCompatibleDC(NULL);
+    HDC dcDst = ::CreateCompatibleDC(NULL);
+    SelectObject(dcSrc, (HBITMAP) GetHBITMAP());
+    SelectObject(dcDst, (HBITMAP) ret.GetHBITMAP());
+    BitBlt(dcDst, 0, 0, rect.width, rect.height, dcSrc, rect.x, rect.y, SRCCOPY);
+
+    // copy mask if there is one
+    if (GetMask())
+    {
+        HBITMAP hbmpMask = ::CreateBitmap(rect.width, rect.height, 1, 1, 0);
+
+        SelectObject(dcSrc, (HBITMAP) GetMask()->GetMaskBitmap());
+        SelectObject(dcDst, (HBITMAP) hbmpMask);
+        BitBlt(dcDst, 0, 0, rect.width, rect.height, dcSrc, rect.x, rect.y, SRCCOPY);
+
+        wxMask *mask = new wxMask((WXHBITMAP) hbmpMask);
+        ret.SetMask(mask);
+    }
+
+    SelectObject(dcDst, NULL);
+    SelectObject(dcSrc, NULL);
+    DeleteDC(dcDst);
+    DeleteDC(dcSrc);
+
+    return ret;
+}
+
 // Create from XPM data
 wxBitmap::wxBitmap(char **data, wxControl *WXUNUSED(anItem))
 {