]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/dc.cpp
fixed wxDirDialog ctor docs
[wxWidgets.git] / src / os2 / dc.cpp
index 2bee9f08e637ce9cd3fe9458967caec7a03331d7..daa44afdece941369e9f036f8572adeeac43f1cd 100644 (file)
@@ -557,7 +557,7 @@ void wxDC::Clear()
     ::GpiErase(m_hPS);
 } // end of wxDC::Clear
 
-void wxDC::DoFloodFill(
+bool wxDC::DoFloodFill(
   wxCoord                           vX
 , wxCoord                           vY
 , const wxColour&                   rCol
@@ -567,6 +567,8 @@ void wxDC::DoFloodFill(
     POINTL                          vPtlPos;
     LONG                            lColor;
     LONG                            lOptions;
+    LONG                            lHits;
+    bool                            bSuccess = FALSE;
 
     vPtlPos.x = vX;             // Loads x-coordinate
     vPtlPos.y = OS2Y(vY,0);     // Loads y-coordinate
@@ -576,7 +578,9 @@ void wxDC::DoFloodFill(
     if(wxFLOOD_SURFACE == nStyle)
         lOptions = FF_SURFACE;
 
-    ::GpiFloodFill(m_hPS, lOptions, lColor);
+    if ((lHits = ::GpiFloodFill(m_hPS, lOptions, lColor)) != GPI_ERROR)
+        bSuccess = TRUE;
+    return TRUE;
 } // end of wxDC::DoFloodFill
 
 bool wxDC::DoGetPixel(
@@ -974,15 +978,22 @@ void wxDC::DoDrawRectangle(
     LONG                            lBorderColor;
     int                             nIsTRANSPARENT = 0;
 
-    vY = OS2Y(vY,vHeight);
+    //
+    // Might be a memory DC with no Paint rect
+    //
+    if (!(m_vRclPaint.yTop == 0 &&
+          m_vRclPaint.yBottom == 0 &&
+          m_vRclPaint.xRight == 0 &&
+          m_vRclPaint.xLeft == 0))
+        vY = OS2Y(vY,vHeight);
 
     wxCoord                         vX2 = vX + vWidth;
     wxCoord                         vY2 = vY + vHeight;
 
     vPoint[0].x = vX;
     vPoint[0].y = vY;
-    vPoint[1].x = vX + vWidth;
-    vPoint[1].y = vY + vHeight;
+    vPoint[1].x = vX + vWidth - 1;
+    vPoint[1].y = vY + vHeight - 1;
     ::GpiMove(m_hPS, &vPoint[0]);
     lColor       = m_brush.GetColour().GetPixel();
     lBorderColor = m_pen.GetColour().GetPixel();
@@ -1020,8 +1031,8 @@ void wxDC::DoDrawRectangle(
                      );
         vPoint[0].x = vX + 1;
         vPoint[0].y = vY + 1;
-        vPoint[1].x = vX + vWidth - 1;
-        vPoint[1].y = vY + vHeight - 1;
+        vPoint[1].x = vX + vWidth - 2;
+        vPoint[1].y = vY + vHeight - 2;
         ::GpiMove(m_hPS, &vPoint[0]);
         ::GpiBox( m_hPS
                  ,lControl
@@ -1198,16 +1209,264 @@ void wxDC::DoDrawBitmap(
 , bool                              bUseMask
 )
 {
-    POINTL                          vPoint = {vX, vY};
+    if (!IsKindOf(CLASSINFO(wxPrinterDC)))
+    {
+        HBITMAP                         hBitmap =  (HBITMAP)rBmp.GetHBITMAP();
+        HBITMAP                         hBitmapOld;
 
-    ::WinDrawBitmap( GetHPS()
-                    ,(HBITMAP)GetHbitmapOf(rBmp)
-                    ,NULL
-                    ,&vPoint
-                    ,0L
-                    ,0L
-                    ,DBM_NORMAL
-                   );
+        vY = OS2Y(vY,rBmp.GetHeight());
+
+        //
+        // Flip the picture as OS/2 is upside-down
+        //
+        POINTL                      vPoint[4] = { vX, vY + rBmp.GetHeight()
+                                                 ,vX + rBmp.GetWidth(), vY
+                                                 ,0, 0
+                                                 ,rBmp.GetWidth(), rBmp.GetHeight()
+                                                };
+        if (bUseMask)
+        {
+            wxMask*                     pMask = rBmp.GetMask();
+
+            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);
+
+                //
+                // 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
+
+                //
+                // 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)pucBits
+                                                   ,&vInfo
+                                                  )) == GPI_ALTERROR)
+                {
+                    vError = ::WinGetLastError(vHabmain);
+                    sError = wxPMErrorToStr(vError);
+                }
+                if ((hOldBitmap = ::GpiSetBitmap(hPS, hMask)) == HBM_ERROR)
+                {
+                    vError = ::WinGetLastError(vHabmain);
+                    sError = wxPMErrorToStr(vError);
+                }
+                if ((lScans = ::GpiQueryBitmapBits( hPS
+                                                   ,0L
+                                                   ,(LONG)rBmp.GetHeight()
+                                                   ,(PBYTE)pucBitsMask
+                                                   ,&vInfo
+                                                  )) == GPI_ALTERROR)
+                {
+                    vError = ::WinGetLastError(vHabmain);
+                    sError = wxPMErrorToStr(vError);
+                }
+
+                //
+                // 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++)
+                {
+                    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);
+                }
+
+                //
+                // 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);
+                }
+
+                //
+                // 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
+                          ,vPoint
+                          ,ROP_SRCCOPY
+                          ,BBO_IGNORE
+                         );
+            ::GpiSetBitmap((HPS)GetHPS(), hBitmapOld);
+            ::GpiSetColor((HPS)GetHPS(), lOldTextground);
+            ::GpiSetBackColor((HPS)GetHPS(), lOldBackground);
+        }
+    }
 } // end of wxDC::DoDrawBitmap
 
 void wxDC::DoDrawText(
@@ -1366,6 +1625,52 @@ void wxDC::DoDrawRotatedText(
 // set GDI objects
 // ---------------------------------------------------------------------------
 
+void wxDC::DoSelectPalette(
+  bool                              bRealize
+)
+{
+    //
+    // Set the old object temporarily, in case the assignment deletes an object
+    // that's not yet selected out.
+    //
+    if (m_hOldPalette)
+    {
+        m_hOldPalette = 0;
+    }
+
+    if (m_palette.Ok())
+    {
+        HPALETTE                    hOldPal;
+
+        hOldPal = ::GpiSelectPalette((HDC) m_hPS, (HPALETTE) m_palette.GetHPALETTE());
+        if (!m_hOldPalette)
+            m_hOldPalette = (WXHPALETTE)hOldPal;
+    }
+} // end of wxDC::DoSelectPalette
+
+void wxDC::InitializePalette()
+{
+    if (wxDisplayDepth() <= 8 )
+    {
+        //
+        // Look for any window or parent that has a custom palette. If any has
+        // one then we need to use it in drawing operations
+        //
+        wxWindow*                   pWin = m_pCanvas->GetAncestorWithCustomPalette();
+
+        m_hasCustomPalette = pWin && pWin->HasCustomPalette();
+        if (m_hasCustomPalette)
+        {
+            m_palette = pWin->GetPalette();
+
+            //
+            // turn on PM translation for this palette
+            //
+            DoSelectPalette();
+        }
+    }
+} // end of wxDC::InitializePalette
+
 void wxDC::SetPalette(
   const wxPalette&                  rPalette
 )
@@ -1808,8 +2113,8 @@ void wxDC::SetMapMode(
         ulOptions = PU_ARBITRARY | GPIF_DEFAULT;
         ::GpiSetPS(m_hPS, &vSize, ulOptions);
     }
-    m_nWindowExtX = (int)MS_XDEV2LOGREL(VIEWPORT_EXTENT);
-    m_nWindowExtY = (int)MS_YDEV2LOGREL(VIEWPORT_EXTENT);
+    m_nWindowExtX = (int)MS_XDEV2LOG(VIEWPORT_EXTENT);
+    m_nWindowExtY = (int)MS_YDEV2LOG(VIEWPORT_EXTENT);
     // ????
 }; // end of wxDC::SetMapMode
 
@@ -1897,7 +2202,8 @@ wxCoord wxDCBase::DeviceToLogicalX(wxCoord x) const
 
 wxCoord wxDCBase::DeviceToLogicalXRel(wxCoord x) const
 {
-    return (wxCoord) ((x)/(m_logicalScaleX*m_userScaleX*m_signX*m_scaleX));
+       // axis orientation is not taken into account for conversion of a distance
+    return (wxCoord) ((x)/(m_logicalScaleX*m_userScaleX*m_scaleX));
 }
 
 wxCoord wxDCBase::DeviceToLogicalY(wxCoord y) const
@@ -1907,7 +2213,8 @@ wxCoord wxDCBase::DeviceToLogicalY(wxCoord y) const
 
 wxCoord wxDCBase::DeviceToLogicalYRel(wxCoord y) const
 {
-    return (wxCoord) ((y)/(m_logicalScaleY*m_userScaleY*m_signY*m_scaleY));
+       // axis orientation is not taken into account for conversion of a distance
+    return (wxCoord) ((y)/(m_logicalScaleY*m_userScaleY*m_scaleY));
 }
 
 wxCoord wxDCBase::LogicalToDeviceX(wxCoord x) const
@@ -1917,7 +2224,8 @@ wxCoord wxDCBase::LogicalToDeviceX(wxCoord x) const
 
 wxCoord wxDCBase::LogicalToDeviceXRel(wxCoord x) const
 {
-    return (wxCoord) (x*m_logicalScaleX*m_userScaleX*m_signX*m_scaleX);
+       // axis orientation is not taken into account for conversion of a distance
+    return (wxCoord) (x*m_logicalScaleX*m_userScaleX*m_scaleX);
 }
 
 wxCoord wxDCBase::LogicalToDeviceY(wxCoord y) const
@@ -1927,7 +2235,8 @@ wxCoord wxDCBase::LogicalToDeviceY(wxCoord y) const
 
 wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const
 {
-    return (wxCoord) (y*m_logicalScaleY*m_userScaleY*m_signY*m_scaleY);
+       // axis orientation is not taken into account for conversion of a distance
+    return (wxCoord) (y*m_logicalScaleY*m_userScaleY*m_scaleY);
 }
 
 // ---------------------------------------------------------------------------