]> git.saurik.com Git - wxWidgets.git/commitdiff
Dang, can't remember what I changed now
authorJulian Smart <julian@anthemion.co.uk>
Thu, 3 Sep 1998 07:34:26 +0000 (07:34 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Thu, 3 Sep 1998 07:34:26 +0000 (07:34 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@650 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/bitmap.h
include/wx/msw/dc.h
src/msw/bitmap.cpp
src/msw/dc.cpp
src/msw/dcmemory.cpp

index a8c9c2507bfc11ea472612500a84290b675cb504..200f9705eece6031f638827dc078bd924e6a5cf3 100644 (file)
@@ -197,6 +197,19 @@ public:
   inline wxDC *GetSelectedInto(void) const { return (M_BITMAPDATA ? M_BITMAPDATA->m_selectedInto : NULL); }
   bool FreeResource(bool force = FALSE);
 
+  // Creates a bitmap that matches the device context's depth, from
+  // an arbitray bitmap. At present, the original bitmap must have an
+  // associated palette. (TODO: use a default palette if no palette exists.)
+  // This function is necessary for you to Blit an arbitrary bitmap (which may have
+  // the wrong depth). wxDC::SelectObject will compare the depth of the bitmap
+  // with the DC's depth, and create a new bitmap if the depths differ.
+  // Eventually we should perhaps make this a public API function so that
+  // an app can efficiently produce bitmaps of the correct depth.
+  // The Windows solution is to use SetDibBits to blit an arbotrary DIB directly to a DC, but
+  // this is too Windows-specific, hence this solution of quietly converting the wxBitmap.
+  // Contributed by Frederic Villeneuve <frederic.villeneuve@natinst.com>
+  wxBitmap GetBitmapForDC(wxDC& dc) const;
+
 };
 #endif
   // _WX_BITMAP_H_
index ab4d2b1c8728f04aff6e98a251b30d444de9e8cb..94e313b9735b42ee7b4003a9106b75060b9de707 100644 (file)
@@ -261,6 +261,10 @@ public:
     GetClippingBox(&x, &y, &w, &h); rect.x = x; rect.y = y; rect.width = w; rect.height = h;
   }
 
+  // This should probably be made available on other platforms
+  int wxDC::GetDepth(void) const ;
+
+// Implementation
   virtual void SetRop(WXHDC cdc);
   virtual void DoClipping(WXHDC cdc);
   virtual void SelectOldObjects(WXHDC dc);
index d3ed8bc019407a8a11965319f0115935d854c2ff..a7c0cb8e1d527da3374d15f8c0424b935a2595f4 100644 (file)
@@ -379,6 +379,47 @@ wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
   return NULL;
 }
 
+// New Create/FreeDIB functions since ones in dibutils.cpp are confusing
+static long createDIB(long xSize, long ySize, long bitsPerPixel,
+                       HPALETTE hPal, LPBITMAPINFO* lpDIBHeader);
+static long freeDIB(LPBITMAPINFO lpDIBHeader);
+
+// Creates a bitmap that matches the device context, from
+// an arbitray bitmap. At present, the original bitmap must have an
+// associated palette. TODO: use a default palette if no palette exists.
+// Contributed by Frederic Villeneuve <frederic.villeneuve@natinst.com>
+wxBitmap wxBitmap::GetBitmapForDC(wxDC& dc) const
+{
+    wxMemoryDC      memDC;
+    wxBitmap        tmpBitmap(this->GetWidth(), this->GetHeight(), dc.GetDepth());
+    HPALETTE        hPal = NULL;
+    LPBITMAPINFO    lpDib;
+    void            *lpBits = NULL;
+
+    wxASSERT( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != NULL) );
+
+    tmpBitmap.SetPalette(this->GetPalette());
+    memDC.SelectObject(tmpBitmap);
+    memDC.SetPalette(this->GetPalette());
+
+    hPal = (HPALETTE) this->GetPalette()->GetHPALETTE();
+
+    // set the height negative because in a DIB the order of the lines is reversed
+    createDIB(this->GetWidth(), -this->GetHeight(), this->GetDepth(), hPal, &lpDib);
+
+    lpBits = malloc(lpDib->bmiHeader.biSizeImage);
+
+    ::GetBitmapBits((HBITMAP)GetHBITMAP(), lpDib->bmiHeader.biSizeImage, lpBits);
+
+    ::SetDIBitsToDevice((HDC) memDC.GetHDC(), 0, 0, this->GetWidth(), this->GetHeight(),
+                        0, 0, 0, this->GetHeight(), lpBits, lpDib, DIB_RGB_COLORS);
+
+    free(lpBits);
+
+    freeDIB(lpDib);
+    return (tmpBitmap);
+}
+
 /*
  * wxMask
  */
@@ -573,7 +614,7 @@ bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long
       GetObject((HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap, sizeof(BITMAP), (LPSTR) &bm);
       M_BITMAPHANDLERDATA->m_width = bm.bmWidth;
       M_BITMAPHANDLERDATA->m_height = bm.bmHeight;
-      M_BITMAPHANDLERDATA->m_depth = bm.bmPlanes;
+      M_BITMAPHANDLERDATA->m_depth = bm.bmBitsPixel;
       return TRUE;
     }
 
@@ -821,4 +862,66 @@ void wxBitmap::InitStandardHandlers(void)
   AddHandler(new wxXPMDataHandler);
   AddHandler(new wxICOResourceHandler);
   AddHandler(new wxICOFileHandler);
-}
\ No newline at end of file
+}
+
+static long createDIB(long xSize, long ySize, long bitsPerPixel,
+                       HPALETTE hPal, LPBITMAPINFO* lpDIBHeader)
+{
+   unsigned long   i, headerSize;
+   LPBITMAPINFO    lpDIBheader = NULL;
+   LPPALETTEENTRY  lpPe = NULL;
+
+
+   // Allocate space for a DIB header
+   headerSize = (sizeof(BITMAPINFOHEADER) + (256 * sizeof(PALETTEENTRY)));
+   lpDIBheader = (BITMAPINFO *) malloc(headerSize);
+   lpPe = (PALETTEENTRY *)((BYTE*)lpDIBheader + sizeof(BITMAPINFOHEADER));
+
+   GetPaletteEntries(hPal, 0, 256, lpPe);
+
+
+   memset(lpDIBheader, 0x00, sizeof(BITMAPINFOHEADER));
+
+
+   // Fill in the static parts of the DIB header
+   lpDIBheader->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+   lpDIBheader->bmiHeader.biWidth = xSize;
+   lpDIBheader->bmiHeader.biHeight = ySize;
+   lpDIBheader->bmiHeader.biPlanes = 1;
+
+   // this value must be 1, 4, 8 or 24 so PixelDepth can only be
+   lpDIBheader->bmiHeader.biBitCount = (WORD)(bitsPerPixel);
+   lpDIBheader->bmiHeader.biCompression = BI_RGB;
+   lpDIBheader->bmiHeader.biSizeImage = xSize * abs(ySize) * bitsPerPixel >>
+3;
+   lpDIBheader->bmiHeader.biClrUsed = 256;
+
+
+   // Initialize the DIB palette
+   for (i = 0; i < 256; i++) {
+      lpDIBheader->bmiColors[i].rgbReserved = lpPe[i].peFlags;
+      lpDIBheader->bmiColors[i].rgbRed = lpPe[i].peRed;
+      lpDIBheader->bmiColors[i].rgbGreen = lpPe[i].peGreen;
+      lpDIBheader->bmiColors[i].rgbBlue = lpPe[i].peBlue;
+   }
+
+   *lpDIBHeader = lpDIBheader;
+
+
+   return (0);
+
+}
+
+
+
+static long freeDIB(LPBITMAPINFO lpDIBHeader)
+{
+
+   if (lpDIBHeader != NULL) {
+      free(lpDIBHeader);
+   }
+
+   return (0);
+}
+
+
index f4201d6e49b2bf8c7308e27c893cfb251335a0f6..432769c8c0dad1aa9f1ff4ab76a170be2c62d172 100644 (file)
@@ -1441,3 +1441,9 @@ void wxDC::GetTextExtent(const wxString& string, float *x, float *y,
 }
 #endif
 
+int wxDC::GetDepth(void) const
+{
+  return (int) ::GetDeviceCaps((HDC) m_hDC,BITSPIXEL);
+}
+
+
index a89b217bcb3fedf925aa0cc50ae72300fd62a8a3..243861faccdde23dcc5285dce3dbb6b02ffd209a 100644 (file)
@@ -84,8 +84,19 @@ void wxMemoryDC::SelectObject(const wxBitmap& bitmap)
     wxFatalError("Error in wxMemoryDC::SelectObject\nBitmap is selected in another wxMemoryDC.\nDelete the first wxMemoryDC or use SelectObject(NULL)");
     return;
   }
-  
-  m_selectedBitmap = bitmap;
+
+  // Check if the bitmap has the correct depth for this device context
+  if (bitmap.Ok() && (bitmap.GetDepth() != GetDepth()))
+  {
+      // Make a new bitmap that has the correct depth.
+      wxBitmap newBitmap = bitmap.GetBitmapForDC(* this);
+
+      m_selectedBitmap = newBitmap ;
+  }
+  else
+  {
+      m_selectedBitmap = bitmap;
+  }
 
   if (!m_selectedBitmap.Ok())
     return;