From 52315bc3bb8b2afcca85c3c910e1bfd9b33f19f9 Mon Sep 17 00:00:00 2001
From: David Webster <Dave.Webster@bhmi.com>
Date: Tue, 30 Apr 2002 22:31:01 +0000
Subject: [PATCH] More image processing updates

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15319 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 src/os2/bitmap.cpp   |  23 ++--
 src/os2/dc.cpp       | 285 +++++++++++++++++++++++++++++--------------
 src/os2/dcclient.cpp |   2 +-
 src/os2/dcmemory.cpp | 233 +++++++++++++++--------------------
 src/os2/icon.cpp     |  48 ++++++--
 src/os2/wx23.def     |  12 +-
 6 files changed, 349 insertions(+), 254 deletions(-)

diff --git a/src/os2/bitmap.cpp b/src/os2/bitmap.cpp
index 486cfed0af..94dcdeaa5d 100644
--- a/src/os2/bitmap.cpp
+++ b/src/os2/bitmap.cpp
@@ -568,8 +568,6 @@ bool wxBitmap::CreateFromImage (
     //
     BITMAPINFOHEADER2               vHeader;
     BITMAPINFO2                     vInfo;
-    LONG                            alFormats[24]; // Max formats OS/2 PM supports
-    ULONG                           ulBitcount;
 
     //
     // Fill in the DIB header
@@ -592,6 +590,7 @@ bool wxBitmap::CreateFromImage (
         wxFAIL_MSG(wxT("could not allocate memory for DIB"));
         return FALSE;
     }
+    memset(pucBits, '\0', (nBytePerLine * nHeight));
 
     //
     // Create and set the device-dependent bitmap
@@ -606,16 +605,12 @@ bool wxBitmap::CreateFromImage (
     HBITMAP                         hBmp;
     HBITMAP                         hBmpOld;
 
-    ::GpiQueryDeviceBitmapFormats(hPS, 24, alFormats);
-    ulBitcount = alFormats[1]; // the best one for the device
-    if (ulBitcount > 24)
-        ulBitcount = 24;  // MAX bits supported by PM
     memset(&vInfo, '\0', 16);
     vInfo.cbFix           = 16;
     vInfo.cx              = (ULONG)nWidth;
     vInfo.cy              = (ULONG)nHeight;
     vInfo.cPlanes         = 1;
-    vInfo.cBitCount       = ulBitcount;
+    vInfo.cBitCount       = 24; // Set to desired count going in
 
     hBmp = ::GpiCreateBitmap( hPS
                              ,&vHeader
@@ -686,6 +681,9 @@ bool wxBitmap::CreateFromImage (
             vError = ::WinGetLastError(vHabmain);
             sError = wxPMErrorToStr(vError);
         }
+        //
+        // Debug stuff
+        //
 
         hPSScreen = ::GpiCreatePS( vHabmain
                                   ,hDCScreen
@@ -855,13 +853,7 @@ wxImage wxBitmap::ConvertToImage() const
     DEVOPENSTRUC                    vDop  = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
     SIZEL                           vSizlPage = {0,0};
     HDC                             hDCMem;
-    LONG                            alFormats[24]; // 24 is MAX formats supported
-    ULONG                           ulBitcount;
 
-    ::GpiQueryDeviceBitmapFormats(hPS, 24, alFormats);
-    ulBitcount = alFormats[1]; // the best one
-    if (ulBitcount > 24) // PM supports a max of 24
-        ulBitcount = 24;
     vImage.Create( nWidth
                   ,nHeight
                  );
@@ -894,7 +886,7 @@ wxImage wxBitmap::ConvertToImage() const
     vDIBInfo.cx              = nWidth;
     vDIBInfo.cy              = nHeight;
     vDIBInfo.cPlanes         = 1;
-    vDIBInfo.cBitCount       = ulBitcount;
+    vDIBInfo.cBitCount       = 24;
 
     lpBits = (unsigned char *)malloc(nBytePerLine * nHeight);
     if (!lpBits)
@@ -903,6 +895,8 @@ wxImage wxBitmap::ConvertToImage() const
         free(pData);
         return wxNullImage;
     }
+    memset(lpBits, '\0', (nBytePerLine * nHeight));
+    hBitmap = (HBITMAP)GetHBITMAP();
 
     //
     // May already be selected into a PS
@@ -925,7 +919,6 @@ wxImage wxBitmap::ConvertToImage() const
                                ,&vSizlPage
                                ,PU_PELS | GPIA_ASSOC
                               );
-        hBitmap = (HBITMAP)GetHBITMAP();
         if ((hOldBitmap = ::GpiSetBitmap(hPSMem, hBitmap)) == HBM_ERROR)
         {
             ERRORID                 vError;
diff --git a/src/os2/dc.cpp b/src/os2/dc.cpp
index 87610e6d63..daa44afdec 100644
--- a/src/os2/dc.cpp
+++ b/src/os2/dc.cpp
@@ -1212,13 +1212,7 @@ void wxDC::DoDrawBitmap(
     if (!IsKindOf(CLASSINFO(wxPrinterDC)))
     {
         HBITMAP                         hBitmap =  (HBITMAP)rBmp.GetHBITMAP();
-        wxBitmap                        vNewBitmap( rBmp.GetWidth()
-                                                   ,rBmp.GetHeight()
-                                                   ,rBmp.GetDepth()
-                                                  );
-        HBITMAP                         hBitmapOld = ::GpiSetBitmap((HPS)GetHPS(), vNewBitmap.GetHBITMAP());
-        LONG                            lOldTextground = ::GpiQueryColor((HPS)GetHPS());
-        LONG                            lOldBackground = ::GpiQueryBackColor((HPS)GetHPS());
+        HBITMAP                         hBitmapOld;
 
         vY = OS2Y(vY,rBmp.GetHeight());
 
@@ -1230,124 +1224,237 @@ void wxDC::DoDrawBitmap(
                                                  ,0, 0
                                                  ,rBmp.GetWidth(), rBmp.GetHeight()
                                                 };
-
-        if (m_textForegroundColour.Ok())
-        {
-            ::GpiSetColor( (HPS)GetHPS()
-                           ,m_textForegroundColour.GetPixel()
-                          );
-        }
-        if (m_textBackgroundColour.Ok())
-        {
-            ::GpiSetBackColor( (HPS)GetHPS()
-                              ,m_textBackgroundColour.GetPixel()
-                             );
-        }
         if (bUseMask)
         {
             wxMask*                     pMask = rBmp.GetMask();
-            HPS                         hPS;
-            HDC                         hDC;
 
-            if (!IsKindOf(CLASSINFO(wxMemoryDC)))
+            if (pMask)
             {
+                //
+                // Need to imitate ::MaskBlt in windows.
+                // 1) Extract the bits from from the bitmap.
+                // 2) Extract the bits from the mask
+                // 3) Using the mask bits do the following:
+                //   A) If the mask byte is 00 leave the bitmap byte alone
+                //   B) If the mask byte is FF copy the screen color into
+                //      bitmap byte
+                // 4) Create a new bitmap and set its bits to the above result
+                // 5) Blit this to the screen PS
+                //
+                HBITMAP                 hMask = (HBITMAP)pMask->GetMaskBitmap();
+                HBITMAP                 hOldBitmap = NULLHANDLE;
+                HBITMAP                 hNewBitmap = NULLHANDLE;
+                unsigned char*          pucBits;     // buffer that will contain the bitmap data
+                unsigned char*          pucBitsMask; // buffer that will contain the mask data
+                unsigned char*          pucData;     // pointer to use to traverse bitmap data
+                unsigned char*          pucDataMask; // pointer to use to traverse mask data
+                LONG                    lHits;
+                ERRORID                 vError;
+                wxString                sError;
+
+                //
+                // The usual Memory context creation stuff
+                //
                 DEVOPENSTRUC                    vDop  = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
                 SIZEL                           vSize = {0, 0};
+                HDC                             hDC   = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
+                HPS                             hPS   = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
 
-                hDC   = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
-                hPS   = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
-            }
-            else
-                hPS = m_hPS;
+                //
+                // The usual bitmap header stuff
+                //
+                BITMAPINFOHEADER2               vHeader;
+                BITMAPINFO2                     vInfo;
+
+                memset(&vHeader, '\0', 16);
+                vHeader.cbFix           = 16;
+                vHeader.cx              = (ULONG)rBmp.GetWidth();
+                vHeader.cy              = (ULONG)rBmp.GetHeight();
+                vHeader.cPlanes         = 1L;
+                vHeader.cBitCount       = 24;
+
+                memset(&vInfo, '\0', 16);
+                vInfo.cbFix           = 16;
+                vInfo.cx              = (ULONG)rBmp.GetWidth();
+                vInfo.cy              = (ULONG)rBmp.GetHeight();
+                vInfo.cPlanes         = 1;
+                vInfo.cBitCount       = 24; // Set to desired count going in
 
-            if (pMask)
-            {
-                BITMAPINFOHEADER2           vHeader;
-                BITMAPINFO2                 vInfo;
-                int                         nBytesPerLine = rBmp.GetWidth() * 3;
-                unsigned char*              pucData;
-                LONG                        lScans = 0L;
-                LONG                        alFormats[24]; // Max formats OS/2 PM supports
-                ULONG                       ulBitcount;
-                HBITMAP                     hMask = (HBITMAP)pMask->GetMaskBitmap();
-                POINTL                      vPointMask[4] = { 0, 0, rBmp.GetWidth(), rBmp.GetHeight()
-                                                             ,0, 0, rBmp.GetWidth(), rBmp.GetHeight()
-                                                            };
-
-                ::GpiSetBitmap(hPS, hMask);
-
-                ::GpiQueryDeviceBitmapFormats(hPS, 24, alFormats);
-                ulBitcount = alFormats[1]; // the best one
-                if (ulBitcount > 24) // PM supports a max of 24
-                    ulBitcount = 24;
-
-                vInfo.cbFix     = 16;
-                vInfo.cx        = rBmp.GetWidth();
-                vInfo.cy        = rBmp.GetHeight();
-                vInfo.cPlanes   = 1;
-                vInfo.cBitCount = ulBitcount;
-                pucData = (unsigned char*)malloc(nBytesPerLine * rBmp.GetHeight());
+                //
+                // Create the buffers for data....all wxBitmaps are 24 bit internally
+                //
+                int                     nBytesPerLine = rBmp.GetWidth() * 3;
+                int                     nSizeDWORD    = sizeof(DWORD);
+                int                     nLineBoundary = nBytesPerLine % nSizeDWORD;
+                int                     nPadding = 0;
+                int                     i;
+                int                     j;
+                LONG                    lScans = 0L;
+                LONG                    lColor = 0L;
+
+                //
+                // Need to get a background color for mask blitting
+                //
+                if (IsKindOf(CLASSINFO(wxPaintDC)))
+                {
+                    wxPaintDC*              pPaintDC = wxDynamicCast(this, wxPaintDC);
+
+                    lColor = pPaintDC->m_pCanvas->GetBackgroundColour().GetPixel();
+                }
+                else if (GetBrush() != wxNullBrush)
+                    lColor = GetBrush().GetColour().GetPixel();
+                else
+                    lColor = m_textBackgroundColour.GetPixel();
+
+                //
+                // Bitmap must be ina double-word alligned address so we may
+                // have some padding to worry about
+                //
+                if (nLineBoundary > 0)
+                {
+                    nPadding     = nSizeDWORD - nLineBoundary;
+                    nBytesPerLine += nPadding;
+                }
+                pucBits = (unsigned char *)malloc(nBytesPerLine * rBmp.GetHeight());
+                pucBitsMask = (unsigned char *)malloc(nBytesPerLine * rBmp.GetHeight());
+                memset(pucBits, '\0', (nBytesPerLine * rBmp.GetHeight()));
+                memset(pucBitsMask, '\0', (nBytesPerLine * rBmp.GetHeight()));
+
+                //
+                // Extract the bitmap and mask data
+                //
+                if ((hOldBitmap = ::GpiSetBitmap(hPS, hBitmap)) == HBM_ERROR)
+                {
+                    vError = ::WinGetLastError(vHabmain);
+                    sError = wxPMErrorToStr(vError);
+                }
                 if ((lScans = ::GpiQueryBitmapBits( hPS
                                                    ,0L
                                                    ,(LONG)rBmp.GetHeight()
-                                                   ,(PBYTE)pucData
+                                                   ,(PBYTE)pucBits
                                                    ,&vInfo
                                                   )) == GPI_ALTERROR)
                 {
-                    ERRORID                     vError;
-                    wxString                    sError;
-
                     vError = ::WinGetLastError(vHabmain);
                     sError = wxPMErrorToStr(vError);
                 }
-                if ((hBitmapOld = ::GpiSetBitmap(hPS, (HBITMAP)vNewBitmap.GetHBITMAP())) == HBM_ERROR)
+                if ((hOldBitmap = ::GpiSetBitmap(hPS, hMask)) == HBM_ERROR)
                 {
-                    ERRORID                     vError;
-                    wxString                    sError;
-
                     vError = ::WinGetLastError(vHabmain);
                     sError = wxPMErrorToStr(vError);
                 }
-                if ((lScans = ::GpiSetBitmapBits( hPS
-                                                 ,0
-                                                 ,(LONG)rBmp.GetHeight()
-                                                 ,(PBYTE)pucData
-                                                 ,&vInfo
-                                                )) == GPI_ALTERROR)
+                if ((lScans = ::GpiQueryBitmapBits( hPS
+                                                   ,0L
+                                                   ,(LONG)rBmp.GetHeight()
+                                                   ,(PBYTE)pucBitsMask
+                                                   ,&vInfo
+                                                  )) == GPI_ALTERROR)
                 {
-                    ERRORID                 vError;
-                    wxString                sError;
-
                     vError = ::WinGetLastError(vHabmain);
                     sError = wxPMErrorToStr(vError);
                 }
-                if ((hBitmapOld = ::GpiSetBitmap(hPS, NULLHANDLE)) == HBM_ERROR)
+
+                //
+                // Now set the bytes(bits) according to the mask values
+                // 3 bytes per pel...must handle one at a time
+                //
+                pucData     = pucBits;
+                pucDataMask = pucBitsMask;
+
+                for (i = 0; i < rBmp.GetHeight(); i++)
                 {
-                    ERRORID                     vError;
-                    wxString                    sError;
+                    for (j = 0; j < rBmp.GetWidth(); j++)
+                    {
+                        // Byte 1
+                        if (*pucDataMask == 0x00) // leave bitmap byte alone
+                            pucData++;
+                        else
+                        {
+                            *pucData = (unsigned char)lColor;
+                            pucData++;
+                        }
+                        // Byte 2
+                        if (*(pucDataMask + 1) == 0x00) // leave bitmap byte alone
+                            pucData++;
+                        else
+                        {
+                            *pucData = (unsigned char)lColor >> 8;
+                            pucData++;
+                        }
+
+                        // Byte 3
+                        if (*(pucDataMask + 2) == 0x00) // leave bitmap byte alone
+                            pucData++;
+                        else
+                        {
+                            *pucData = (unsigned char)lColor >> 16;
+                            pucData++;
+                        }
+                        pucDataMask += 3;
+                    }
+                    for (j = 0; j < nPadding; j++)
+                    {
+                        pucData++;
+                        pucDataMask++;
+                    }
+                }
 
+                //
+                // Create a new bitmap
+                //
+                if ((hNewBitmap = ::GpiCreateBitmap( hPS
+                                                    ,&vHeader
+                                                    ,CBM_INIT
+                                                    ,(PBYTE)pucBits
+                                                    ,&vInfo
+                                                   )) == GPI_ERROR)
+                {
                     vError = ::WinGetLastError(vHabmain);
                     sError = wxPMErrorToStr(vError);
                 }
-                if ((hBitmapOld = ::GpiSetBitmap((HPS)GetHPS(), vNewBitmap.GetHBITMAP())) == HBM_ERROR)
-                {
-                    ERRORID                     vError;
-                    wxString                    sError;
 
+                //
+                // Now blit it to the screen PS
+                //
+                if ((lHits = ::GpiWCBitBlt( (HPS)GetHPS()
+                                           ,hNewBitmap
+                                           ,4
+                                           ,vPoint
+                                           ,ROP_SRCCOPY
+                                           ,BBO_IGNORE
+                                          )) == GPI_ERROR)
+                {
                     vError = ::WinGetLastError(vHabmain);
                     sError = wxPMErrorToStr(vError);
                 }
-                ::GpiWCBitBlt( (HPS)GetHPS()
-                              ,hBitmap
-                              ,4
-                              ,vPoint
-                              ,ROP_SRCAND
-                              ,BBO_IGNORE
-                             );
+
+                //
+                // Clean up
+                //
+                free(pucBits);
+                free(pucBitsMask);
+                ::GpiSetBitmap(hPS, NULLHANDLE);
+                ::GpiDestroyPS(hPS);
+                ::DevCloseDC(hDC);
             }
         }
         else
         {
+            LONG                        lOldTextground = ::GpiQueryColor((HPS)GetHPS());
+            LONG                        lOldBackground = ::GpiQueryBackColor((HPS)GetHPS());
+
+            if (m_textForegroundColour.Ok())
+            {
+                ::GpiSetColor( (HPS)GetHPS()
+                               ,m_textForegroundColour.GetPixel()
+                              );
+            }
+            if (m_textBackgroundColour.Ok())
+            {
+                ::GpiSetBackColor( (HPS)GetHPS()
+                                  ,m_textBackgroundColour.GetPixel()
+                                 );
+            }
             ::GpiWCBitBlt( (HPS)GetHPS()
                           ,hBitmap
                           ,4
@@ -1355,10 +1462,10 @@ void wxDC::DoDrawBitmap(
                           ,ROP_SRCCOPY
                           ,BBO_IGNORE
                          );
+            ::GpiSetBitmap((HPS)GetHPS(), hBitmapOld);
+            ::GpiSetColor((HPS)GetHPS(), lOldTextground);
+            ::GpiSetBackColor((HPS)GetHPS(), lOldBackground);
         }
-        ::GpiSetBitmap((HPS)GetHPS(), hBitmapOld);
-        ::GpiSetColor((HPS)GetHPS(), lOldTextground);
-        ::GpiSetBackColor((HPS)GetHPS(), lOldBackground);
     }
 } // end of wxDC::DoDrawBitmap
 
diff --git a/src/os2/dcclient.cpp b/src/os2/dcclient.cpp
index e1be6a1052..083b902b3d 100644
--- a/src/os2/dcclient.cpp
+++ b/src/os2/dcclient.cpp
@@ -319,7 +319,7 @@ wxPaintDC::wxPaintDC(
     {
         HPS                         hPS;
 
-        m_hDC = (WXHDC)::WinOpenWindowDC(GetWinHwnd(m_pCanvas));
+        m_hDC = ::WinOpenWindowDC(GetWinHwnd(m_pCanvas));
         hPS = ::WinBeginPaint( GetWinHwnd(m_pCanvas)
                               ,NULLHANDLE
                               ,&g_paintStruct
diff --git a/src/os2/dcmemory.cpp b/src/os2/dcmemory.cpp
index 71f06468ae..6383d1a876 100644
--- a/src/os2/dcmemory.cpp
+++ b/src/os2/dcmemory.cpp
@@ -24,6 +24,12 @@
 
 IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxDC)
 
+extern void wxLoadBitmapWithData( HPS     hPS
+                                 ,HBITMAP hBitmap
+                                 ,int     nWidth
+                                 ,int     nHeight
+                                );
+
 /////////////////////////////////////////////////////////////////////////////
 // Memory DC
 /////////////////////////////////////////////////////////////////////////////
@@ -191,77 +197,11 @@ void wxMemoryDC::DoDrawRectangle(
 {
     wxDC::DoDrawRectangle(vX, vY, vWidth, vHeight);
 
-    //
-    // Debug testing:
-    //
-    if (m_vSelectedBitmap.GetHBITMAP() != NULLHANDLE)
-    {
-        BITMAPINFOHEADER2           vHeader;
-        BITMAPINFO2                 vInfo;
-
-        vHeader.cbFix = 16L;
-        if (::GpiQueryBitmapInfoHeader(m_vSelectedBitmap.GetHBITMAP(), &vHeader))
-        {
-            unsigned char*          pucData = NULL;
-            unsigned char*          pucBits;
-            int                     nBytesPerLine = m_vSelectedBitmap.GetWidth() * 3;
-            LONG                    lScans = 0L;
-            POINTL                  vPoint;
-            LONG                    lColor;
-            LONG                    alFormats[24]; // Max formats OS/2 PM supports
-            ULONG                   ulBitcount;
-
-            ::GpiQueryDeviceBitmapFormats(m_hPS, 24, alFormats);
-            ulBitcount = alFormats[1]; // the best one for the device
-            if (ulBitcount > 24)
-                ulBitcount = 24;  // MAX bits supported by PM
-            vInfo.cbFix     = 16;
-            vInfo.cx        = vHeader.cx;
-            vInfo.cy        = vHeader.cy;
-            vInfo.cPlanes   = vHeader.cPlanes;
-            vInfo.cBitCount = ulBitcount;
-            pucData = (unsigned char*)malloc(nBytesPerLine * m_vSelectedBitmap.GetHeight());
-            if ((lScans = ::GpiQueryBitmapBits( m_hPS
-                                               ,0L
-                                               ,(LONG)m_vSelectedBitmap.GetHeight()
-                                               ,(PBYTE)pucData
-                                               ,&vInfo
-                                              )) == GPI_ALTERROR)
-            {
-                ERRORID                     vError;
-                wxString                    sError;
-
-                vError = ::WinGetLastError(vHabmain);
-                sError = wxPMErrorToStr(vError);
-            }
-            pucBits = pucData;
-            for (int i = 0; i < m_vSelectedBitmap.GetHeight(); i++)
-            {
-                for (int j = 0; j < m_vSelectedBitmap.GetWidth(); j++)
-                {
-                    vPoint.x = j; vPoint.y = i;
-                    lColor = ::GpiQueryPel(m_hPS, &vPoint);
-                    *(pucBits++) = (unsigned char)lColor;
-                    *(pucBits++) = (unsigned char)(lColor >> 8);
-                    *(pucBits++) = (unsigned char)(lColor >> 16);
-                }
-            }
-            if ((lScans = ::GpiSetBitmapBits( m_hPS
-                                             ,0
-                                             ,(LONG)m_vSelectedBitmap.GetHeight()
-                                             ,(PBYTE)pucData
-                                             ,&vInfo
-                                            )) == GPI_ALTERROR)
-            {
-                ERRORID             vError;
-                wxString            sError;
-
-                vError = ::WinGetLastError(vHabmain);
-                sError = wxPMErrorToStr(vError);
-            }
-            free(pucData);
-        }
-    }
+    wxLoadBitmapWithData( m_hPS
+                         ,(HBITMAP)m_vSelectedBitmap.GetHBITMAP()
+                         ,m_vSelectedBitmap.GetWidth()
+                         ,m_vSelectedBitmap.GetHeight()
+                        );
 } // end of wxMemoryDC::DoDrawRectangle
 
 void wxMemoryDC::DoDrawRoundedRectangle(
@@ -274,76 +214,95 @@ void wxMemoryDC::DoDrawRoundedRectangle(
 {
     wxDC::DoDrawRoundedRectangle(vX, vY, vWidth, vHeight, dRadius);
 
-    //
-    // Debug testing:
-    //
-    if (m_vSelectedBitmap.GetHBITMAP() != NULLHANDLE)
-    {
-        BITMAPINFOHEADER2           vHeader;
-        BITMAPINFO2                 vInfo;
+    wxLoadBitmapWithData( m_hPS
+                         ,(HBITMAP)m_vSelectedBitmap.GetHBITMAP()
+                         ,m_vSelectedBitmap.GetWidth()
+                         ,m_vSelectedBitmap.GetHeight()
+                        );
+} // end of wxMemoryDC::DoDrawRoundedRectangle
 
-        vHeader.cbFix = 16L;
-        if (::GpiQueryBitmapInfoHeader(m_vSelectedBitmap.GetHBITMAP(), &vHeader))
-        {
-            unsigned char*          pucData = NULL;
-            unsigned char*          pucBits;
-            int                     nBytesPerLine = m_vSelectedBitmap.GetWidth() * 3;
-            LONG                    lScans = 0L;
-            POINTL                  vPoint;
-            LONG                    lColor;
-            LONG                    alFormats[24]; // Max formats OS/2 PM supports
-            ULONG                   ulBitcount;
-
-            ::GpiQueryDeviceBitmapFormats(m_hPS, 24, alFormats);
-            ulBitcount = alFormats[1]; // the best one for the device
-            if (ulBitcount > 24)
-                ulBitcount = 24;  // MAX bits supported by PM
-            vInfo.cbFix     = 16;
-            vInfo.cx        = vHeader.cx;
-            vInfo.cy        = vHeader.cy;
-            vInfo.cPlanes   = vHeader.cPlanes;
-            vInfo.cBitCount = ulBitcount;
-            pucData = (unsigned char*)malloc(nBytesPerLine * m_vSelectedBitmap.GetHeight());
-            if ((lScans = ::GpiQueryBitmapBits( m_hPS
-                                               ,0L
-                                               ,(LONG)m_vSelectedBitmap.GetHeight()
-                                               ,(PBYTE)pucData
-                                               ,&vInfo
-                                              )) == GPI_ALTERROR)
-            {
-                ERRORID                     vError;
-                wxString                    sError;
+void wxMemoryDC::DoDrawText(
+  const wxString&                   rsText
+, wxCoord                           vX
+, wxCoord                           vY
+)
+{
+    wxDC::DoDrawText(rsText, vX, vY);
 
-                vError = ::WinGetLastError(vHabmain);
-                sError = wxPMErrorToStr(vError);
-            }
-            pucBits = pucData;
-            for (int i = 0; i < m_vSelectedBitmap.GetHeight(); i++)
+    wxLoadBitmapWithData( m_hPS
+                         ,(HBITMAP)m_vSelectedBitmap.GetHBITMAP()
+                         ,m_vSelectedBitmap.GetWidth()
+                         ,m_vSelectedBitmap.GetHeight()
+                        );
+} // end of wxMemoryDC::DoDrawRectangle
+
+void wxMemoryDC::DoDrawLine(
+  wxCoord                           vX1
+, wxCoord                           vY1
+, wxCoord                           vX2
+, wxCoord                           vY2
+)
+{
+    wxDC::DoDrawLine(vX1, vY1, vX2, vY2);
+
+    wxLoadBitmapWithData( m_hPS
+                         ,(HBITMAP)m_vSelectedBitmap.GetHBITMAP()
+                         ,m_vSelectedBitmap.GetWidth()
+                         ,m_vSelectedBitmap.GetHeight()
+                        );
+} // end of wxMemoryDC::DoDrawRoundedRectangle
+
+void wxLoadBitmapWithData(
+  HPS                               hPS
+, HBITMAP                           hBitmap
+, int                               nWidth
+, int                               nHeight
+)
+{
+    BITMAPINFOHEADER2               vHeader;
+    BITMAPINFO2                     vInfo;
+
+    vHeader.cbFix = 16L;
+    if (::GpiQueryBitmapInfoHeader(hBitmap, &vHeader))
+    {
+        unsigned char*              pucData = NULL;
+        unsigned char*              pucBits;
+        int                         nBytesPerLine = nWidth * 3;
+        LONG                        lScans = 0L;
+        POINTL                      vPoint;
+        LONG                        lColor;
+
+        vInfo.cbFix     = 16;
+        vInfo.cx        = vHeader.cx;
+        vInfo.cy        = vHeader.cy;
+        vInfo.cPlanes   = vHeader.cPlanes;
+        vInfo.cBitCount = 24;
+        pucData = (unsigned char*)malloc(nBytesPerLine * nHeight);
+        pucBits = pucData;
+        for (int i = 0; i < nHeight; i++)
+        {
+            for (int j = 0; j < nWidth; j++)
             {
-                for (int j = 0; j < m_vSelectedBitmap.GetWidth(); j++)
-                {
-                    vPoint.x = j; vPoint.y = i;
-                    lColor = ::GpiQueryPel(m_hPS, &vPoint);
-                    *(pucBits++) = (unsigned char)lColor;
-                    *(pucBits++) = (unsigned char)(lColor >> 8);
-                    *(pucBits++) = (unsigned char)(lColor >> 16);
-                }
+                vPoint.x = j; vPoint.y = i;
+                lColor = ::GpiQueryPel(hPS, &vPoint);
+                *(pucBits++) = (unsigned char)lColor;
+                *(pucBits++) = (unsigned char)(lColor >> 8);
+                *(pucBits++) = (unsigned char)(lColor >> 16);
             }
-            if ((lScans = ::GpiSetBitmapBits( m_hPS
-                                             ,0
-                                             ,(LONG)m_vSelectedBitmap.GetHeight()
-                                             ,(PBYTE)pucData
-                                             ,&vInfo
-                                            )) == GPI_ALTERROR)
-            {
-                ERRORID             vError;
-                wxString            sError;
+        }
+        if ((lScans = ::GpiSetBitmapBits( hPS
+                                         ,0
+                                         ,(LONG)nHeight
+                                         ,(PBYTE)pucData
+                                         ,&vInfo
+                                        )) == GPI_ALTERROR)
+        {
+            ERRORID             vError;
+            wxString            sError;
 
-                vError = ::WinGetLastError(vHabmain);
-                sError = wxPMErrorToStr(vError);
-            }
-            free(pucData);
+            vError = ::WinGetLastError(vHabmain);
+            sError = wxPMErrorToStr(vError);
         }
+        free(pucData);
     }
-} // end of wxMemoryDC::DoDrawRectangle
-
+}
diff --git a/src/os2/icon.cpp b/src/os2/icon.cpp
index 56b77d73ed..d1c390da8f 100644
--- a/src/os2/icon.cpp
+++ b/src/os2/icon.cpp
@@ -101,6 +101,10 @@ void wxIcon::CopyFromBitmap(
 )
 {
     wxMask*                         pMask = rBmp.GetMask();
+    HBITMAP                         hOldBitmap = NULLHANDLE;
+    ERRORID                         vError;
+    wxString                        sError;
+    LONG                            lHits;
 
     if (!pMask)
     {
@@ -117,6 +121,7 @@ void wxIcon::CopyFromBitmap(
 
     memset(&vIconInfo, '\0', sizeof(POINTERINFO));
     vIconInfo.fPointer = FALSE;  // we want an icon, not a pointer
+    vIconInfo.hbmPointer = (HBITMAP) pMask->GetMaskBitmap();
     vIconInfo.hbmColor = GetHbitmapOf(rBmp);
 
     SIZEL                           vSize = {0, 0};
@@ -128,15 +133,38 @@ void wxIcon::CopyFromBitmap(
     POINTL                          vPoint[4] = { 0, 0, rBmp.GetWidth(), rBmp.GetHeight(),
                                                   0, 0, rBmp.GetWidth(), rBmp.GetHeight()
                                                 };
-    ::GpiSetBitmap(hPSSrc, (HBITMAP) pMask->GetMaskBitmap());
-    ::GpiSetBitmap(hPSDst, (HBITMAP) vIconInfo.hbmColor);
-    ::GpiBitBlt( hPSDst
-                ,hPSSrc
-                ,4L
-                ,vPoint
-                ,ROP_SRCAND
-                ,BBO_IGNORE
-               );
+    if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, (HBITMAP) pMask->GetMaskBitmap())) == HBM_ERROR)
+    {
+        vError = ::WinGetLastError(vHabmain);
+        sError = wxPMErrorToStr(vError);
+    }
+    if ((hOldBitmap = ::GpiSetBitmap(hPSDst, (HBITMAP) vIconInfo.hbmColor)) == HBM_ERROR)
+    {
+        vError = ::WinGetLastError(vHabmain);
+        sError = wxPMErrorToStr(vError);
+    }
+    ::GpiSetBitmapId(hPSDst, (HBITMAP) vIconInfo.hbmColor, 1L);
+    if ((lHits = ::GpiBitBlt( hPSDst
+                             ,hPSSrc
+                             ,4L
+                             ,vPoint
+                             ,ROP_SRCAND
+                             ,BBO_IGNORE
+                            )) == GPI_ERROR)
+    {
+        vError = ::WinGetLastError(vHabmain);
+        sError = wxPMErrorToStr(vError);
+    }
+    if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, NULLHANDLE)) == HBM_ERROR)
+    {
+        vError = ::WinGetLastError(vHabmain);
+        sError = wxPMErrorToStr(vError);
+    }
+    if ((hOldBitmap = ::GpiSetBitmap(hPSDst, NULLHANDLE)) == HBM_ERROR)
+    {
+        vError = ::WinGetLastError(vHabmain);
+        sError = wxPMErrorToStr(vError);
+    }
 
     ::GpiSetBitmap(hPSSrc, NULL);
     ::GpiSetBitmap(hPSDst, NULL);
@@ -152,6 +180,8 @@ void wxIcon::CopyFromBitmap(
     if (!hIcon)
     {
         wxLogLastError(wxT("WinCreatePointerIndirect"));
+        vError = ::WinGetLastError(vHabmain);
+        sError = wxPMErrorToStr(vError);
     }
     else
     {
diff --git a/src/os2/wx23.def b/src/os2/wx23.def
index 3a53e93468..46d454bddb 100644
--- a/src/os2/wx23.def
+++ b/src/os2/wx23.def
@@ -4,7 +4,7 @@ DATA MULTIPLE NONSHARED READWRITE LOADONCALL
 CODE LOADONCALL
 
 EXPORTS
-;From library:  F:\DEV\WX2\WXWINDOWS\LIB\wx.lib
+;From library:  H:\DEV\WX2\WXWINDOWS\LIB\wx.lib
   ;From object file:  dummy.cpp
     ;PUBDEFs (Symbols available from object file):
       wxDummyChar
@@ -1925,7 +1925,7 @@ EXPORTS
       wxEVT_NC_LEFT_DCLICK
       wxEVT_INIT_DIALOG
       wxEVT_COMMAND_SET_FOCUS
-  ;From object file:  F:\DEV\WX2\WXWINDOWS\src\common\extended.c
+  ;From object file:  H:\DEV\WX2\WXWINDOWS\src\common\extended.c
     ;PUBDEFs (Symbols available from object file):
       ConvertToIeeeExtended
       ConvertFromIeeeExtended
@@ -6039,7 +6039,7 @@ EXPORTS
       Read32__17wxTextInputStreamFv
       ;wxTextInputStream::SkipIfEndOfLine(char)
       SkipIfEndOfLine__17wxTextInputStreamFc
-  ;From object file:  F:\DEV\WX2\WXWINDOWS\src\common\unzip.c
+  ;From object file:  H:\DEV\WX2\WXWINDOWS\src\common\unzip.c
     ;PUBDEFs (Symbols available from object file):
       unzReadCurrentFile
       unzGetCurrentFileInfo
@@ -12303,11 +12303,17 @@ EXPORTS
     ;PUBDEFs (Symbols available from object file):
       ;wxMemoryDC::DoDrawRoundedRectangle(int,int,int,int,double)
       DoDrawRoundedRectangle__10wxMemoryDCFiN31d
+      ;wxMemoryDC::DoDrawText(const wxString&,int,int)
+      DoDrawText__10wxMemoryDCFRC8wxStringiT2
       ;wxMemoryDC::SelectObject(const wxBitmap&)
       SelectObject__10wxMemoryDCFRC8wxBitmap
       __vft10wxMemoryDC8wxObject
+      ;wxMemoryDC::DoDrawLine(int,int,int,int)
+      DoDrawLine__10wxMemoryDCFiN31
       ;wxMemoryDC::Init()
       Init__10wxMemoryDCFv
+      ;wxLoadBitmapWithData(unsigned long,unsigned long,int,int)
+      wxLoadBitmapWithData__FUlT1iT3
       ;wxMemoryDC::DoGetSize(int*,int*) const
       DoGetSize__10wxMemoryDCCFPiT1
       ;wxMemoryDC::wxMemoryDC(wxDC*)
-- 
2.47.2

