X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/893758d507abf66a429666b9f0b2c1baa195b398..ddf14c1346a729f37e37fa6b5944cc899a6f2471:/src/os2/dc.cpp diff --git a/src/os2/dc.cpp b/src/os2/dc.cpp index c0f1fefcd4..56f4dacc08 100644 --- a/src/os2/dc.cpp +++ b/src/os2/dc.cpp @@ -23,34 +23,37 @@ #include "wx/log.h" #include "wx/icon.h" #include "wx/msgdlg.h" +#if wxUSE_STATUSBAR + #include "wx/statusbr.h" +#endif #endif +#include "wx/module.h" #include "wx/dcprint.h" #include -#include #include "wx/os2/private.h" IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject) // -// wxWindows uses the Microsoft convention that the origin is the UPPER left. +// wxWidgets uses the Microsoft convention that the origin is the UPPER left. // Native OS/2 however in the GPI and PM define the origin as the LOWER left. -// In order to map OS/2 GPI/PM y coordinates to wxWindows coordinates we must +// In order to map OS/2 GPI/PM y coordinates to wxWidgets coordinates we must // perform the following transformation: // // Parent object height: POBJHEIGHT // Desried origin: WXORIGINY // Object to place's height: OBJHEIGHT // -// To get the OS2 position from the wxWindows one: +// To get the OS2 position from the wxWidgets one: // // OS2Y = POBJHEIGHT - (WXORIGINY + OBJHEIGHT) // // For OS/2 wxDC's we will always determine m_vRclPaint as the size of the // OS/2 Presentation Space associated with the device context. y is the -// desired application's y coordinate of the origin in wxWindows space. +// desired application's y coordinate of the origin in wxWidgets space. // objy is the height of the object we are going to draw. // #define OS2Y(y, objy) ((m_vRclPaint.yTop - m_vRclPaint.yBottom) - (y + objy)) @@ -64,11 +67,6 @@ static const int VIEWPORT_EXTENT = 1000; static const int MM_POINTS = 9; static const int MM_METRIC = 10; -// usually this is defined in math.h -#ifndef M_PI - static const double M_PI = 3.14159265358979323846; -#endif // M_PI - // --------------------------------------------------------------------------- // private functions // --------------------------------------------------------------------------- @@ -204,7 +202,7 @@ wxDCCacheEntry* wxDC::FindBitmapInCache( , int nHeight ) { - int nDepth = 24 // we'll fix this later ::GetDeviceCaps((HDC) dc, PLANES) * ::GetDeviceCaps((HDC) dc, BITSPIXEL); + int nDepth = 24; // we'll fix this later ::GetDeviceCaps((HDC) dc, PLANES) * ::GetDeviceCaps((HDC) dc, BITSPIXEL); wxNode* pNode = m_svBitmapCache.First(); BITMAPINFOHEADER2 vBmpHdr; @@ -312,19 +310,19 @@ void wxDC::AddToDCCache( void wxDC::ClearCache() { - m_svBitmapCache.DeleteContents(TRUE); + m_svBitmapCache.DeleteContents(true); m_svBitmapCache.Clear(); - m_svBitmapCache.DeleteContents(FALSE); - m_svDCCache.DeleteContents(TRUE); + m_svBitmapCache.DeleteContents(false); + m_svDCCache.DeleteContents(true); m_svDCCache.Clear(); - m_svDCCache.DeleteContents(FALSE); + m_svDCCache.DeleteContents(false); } // end of wxDC::ClearCache // Clean up cache at app exit class wxDCModule : public wxModule { public: - virtual bool OnInit() { return TRUE; } + virtual bool OnInit() { return true; } virtual void OnExit() { wxDC::ClearCache(); } private: @@ -341,8 +339,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule) wxDC::wxDC(void) { - wxColour vColor; - m_pCanvas = NULL; m_hOldBitmap = 0; @@ -351,16 +347,18 @@ wxDC::wxDC(void) m_hOldFont = 0; m_hOldPalette = 0; - m_bOwnsDC = FALSE; + m_bOwnsDC = false; m_hDC = 0; m_hOldPS = NULL; m_hPS = NULL; - m_bIsPaintTime = FALSE; // True at Paint Time + m_bIsPaintTime = false; // True at Paint Time - vColor.InitFromName("BLACK"); + wxColour vColor( wxT("BLACK") ); m_pen.SetColour(vColor); - vColor.Set("WHITE"); + + vColor.Set( wxT("WHITE") ); m_brush.SetColour(vColor); + } // end of wxDC::wxDC wxDC::~wxDC(void) @@ -455,7 +453,7 @@ void wxDC::DoSetClippingRegion( RECTL vRect; vY = OS2Y(vY,vHeight); - m_clipping = TRUE; + m_clipping = true; vRect.xLeft = vX; vRect.yTop = vY + vHeight; vRect.xRight = vX + vWidth; @@ -471,7 +469,7 @@ void wxDC::DoSetClippingRegionAsRegion( wxCHECK_RET(rRegion.GetHRGN(), wxT("invalid clipping region")); HRGN hRgnOld; - m_clipping = TRUE; + m_clipping = true; ::GpiSetClipRegion( m_hPS ,(HRGN)rRegion.GetHRGN() ,&hRgnOld @@ -499,7 +497,7 @@ void wxDC::DestroyClippingRegion(void) ::GpiSetClipRegion(m_hPS, hRgn, &hRgnOld); } - m_clipping = FALSE; + ResetClipping(); } // end of wxDC::DestroyClippingRegion // --------------------------------------------------------------------------- @@ -508,7 +506,7 @@ void wxDC::DestroyClippingRegion(void) bool wxDC::CanDrawBitmap() const { - return TRUE; + return true; } bool wxDC::CanGetTextExtent() const @@ -522,7 +520,7 @@ bool wxDC::CanGetTextExtent() const int wxDC::GetDepth() const { LONG lArray[CAPS_COLOR_BITCOUNT]; - int nBitsPerPixel; + int nBitsPerPixel = 0; if(::DevQueryCaps( GetHDC() ,CAPS_FAMILY @@ -541,10 +539,22 @@ int wxDC::GetDepth() const void wxDC::Clear() { + // + // If this is a canvas DC then just fill with the background color + // Otherwise purge the whole thing + // + if (m_pCanvas) + { + RECTL vRect; + + ::GpiQueryClipBox(m_hPS, &vRect); + ::WinFillRect(m_hPS, &vRect, ::GpiQueryBackColor(m_hPS)); + } + else ::GpiErase(m_hPS); } // end of wxDC::Clear -void wxDC::DoFloodFill( +bool wxDC::DoFloodFill( wxCoord vX , wxCoord vY , const wxColour& rCol @@ -554,6 +564,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 @@ -563,7 +575,10 @@ 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( @@ -642,14 +657,38 @@ void wxDC::DoDrawLine( ) { POINTL vPoint[2]; + COLORREF vColor = 0x00ffffff; - vY1 = OS2Y(vY1,0); - vY2 = OS2Y(vY2,0); - + // + // 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)) + { + vY1 = OS2Y(vY1,0); + vY2 = OS2Y(vY2,0); + } + else + { + if (m_vSelectedBitmap != wxNullBitmap) + { + m_vRclPaint.yTop = m_vSelectedBitmap.GetHeight(); + m_vRclPaint.xRight = m_vSelectedBitmap.GetWidth(); + vY1 = OS2Y(vY1,0); + vY2 = OS2Y(vY2,0); + } + } vPoint[0].x = vX1; vPoint[0].y = vY1; vPoint[1].x = vX2; vPoint[1].y = vY2; + if (m_pen.Ok()) + { + vColor = m_pen.GetColour().GetPixel(); + } + ::GpiSetColor(m_hPS, vColor); ::GpiMove(m_hPS, &vPoint[0]); ::GpiLine(m_hPS, &vPoint[1]); CalcBoundingBox(vX1, vY1); @@ -673,8 +712,6 @@ void wxDC::DoDrawArc( { POINTL vPtlPos; POINTL vPtlArc[2]; // Structure for current position - int nDx; - int nDy; double dRadius; double dAngl1; double dAngl2; @@ -711,8 +748,8 @@ void wxDC::DoDrawArc( // Medium point // dAnglmid = (dAngl1 + dAngl2)/2. + M_PI; - vXm = vXc + dRadius * cos(dAnglmid); - vYm = vYc + dRadius * sin(dAnglmid); + vXm = (wxCoord)(vXc + dRadius * cos(dAnglmid)); + vYm = (wxCoord)(vYc + dRadius * sin(dAnglmid)); DoDrawArc( vX1, vY1 ,vXm, vYm ,vXc, vYc @@ -728,8 +765,8 @@ void wxDC::DoDrawArc( // Medium point // dAnglmid = (dAngl1 + dAngl2)/2.; - vXm = vXc + dRadius * cos(dAnglmid); - vYm = vYc + dRadius * sin(dAnglmid); + vXm = (wxCoord)(vXc + dRadius * cos(dAnglmid)); + vYm = (wxCoord)(vYc + dRadius * sin(dAnglmid)); // // Ellipse main axis (r,q), (p,s) with center at (0,0) */ @@ -748,11 +785,11 @@ void wxDC::DoDrawArc( vPtlArc[1].x = vX2; vPtlArc[1].y = vY2; ::GpiPointArc(m_hPS, vPtlArc); // Draws the arc - CalcBoundingBox( (vXc - dRadius) - ,(vYc - dRadius) + CalcBoundingBox( (wxCoord)(vXc - dRadius) + ,(wxCoord)(vYc - dRadius) ); - CalcBoundingBox( (vXc + dRadius) - ,(vYc + dRadius) + CalcBoundingBox( (wxCoord)(vXc + dRadius) + ,(wxCoord)(vYc + dRadius) ); } // end of wxDC::DoDrawArc @@ -929,8 +966,8 @@ void wxDC::DoDrawLines( { int i; - CalcBoundingBox( vPoints[i].x - ,vPoints[i].y + CalcBoundingBox( vPoints[0].x + ,vPoints[0].y ); vPoint.x = vPoints[0].x; vPoint.y = OS2Y(vPoints[0].y,0); @@ -961,15 +998,31 @@ 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); + else + { + if (m_vSelectedBitmap != wxNullBitmap) + { + m_vRclPaint.yTop = m_vSelectedBitmap.GetHeight(); + m_vRclPaint.xRight = m_vSelectedBitmap.GetWidth(); + 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(); @@ -981,7 +1034,7 @@ void wxDC::DoDrawRectangle( if(m_brush.GetStyle() == wxTRANSPARENT) lControl = DRO_OUTLINE; - ::GpiSetColor(m_hPS, lColor); + ::GpiSetColor(m_hPS, lBorderColor); ::GpiBox( m_hPS // handle to a presentation space ,lControl // draw the box outline ? or ? ,&vPoint[1] // address of the corner @@ -1007,8 +1060,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 @@ -1031,27 +1084,85 @@ void wxDC::DoDrawRoundedRectangle( { POINTL vPoint[2]; LONG lControl; + LONG lColor; + 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); + else + { + if (m_vSelectedBitmap != wxNullBitmap) + { + m_vRclPaint.yTop = m_vSelectedBitmap.GetHeight(); + m_vRclPaint.xRight = m_vSelectedBitmap.GetWidth(); + vY = OS2Y(vY,vHeight); + } + } wxCoord vX2 = (vX + vWidth); wxCoord vY2 = (vY + vHeight); vPoint[0].x = vX; - vPoint[0].y = YLOG2DEV(vY) - vHeight; - vPoint[1].x = vX + vWidth; - vPoint[1].y = vY; + vPoint[0].y = vY; + 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(); lControl = DRO_OUTLINEFILL; //DRO_FILL; if (m_brush.GetStyle() == wxTRANSPARENT) + nIsTRANSPARENT = 1; + if(lColor == lBorderColor || nIsTRANSPARENT) + { + lControl = DRO_OUTLINEFILL; //DRO_FILL; + if(m_brush.GetStyle() == wxTRANSPARENT) + lControl = DRO_OUTLINE; + + ::GpiSetColor(m_hPS, lColor); + ::GpiBox( m_hPS // handle to a presentation space + ,lControl // draw the box outline ? or ? + ,&vPoint[1] // address of the corner + ,(LONG)dRadius // horizontal corner radius + ,(LONG)dRadius // vertical corner radius + ); + } + else + { lControl = DRO_OUTLINE; - ::GpiBox( m_hPS // handle to a presentation space - ,DRO_OUTLINE // draw the box outline ? or ? - ,&vPoint[1] // address of the corner - ,(LONG)dRadius // horizontal corner radius - ,(LONG)dRadius // vertical corner radius - ); + ::GpiSetColor( m_hPS + ,lBorderColor + ); + ::GpiBox( m_hPS + ,lControl + ,&vPoint[1] + ,(LONG)dRadius + ,(LONG)dRadius + ); + lControl = DRO_FILL; + ::GpiSetColor( m_hPS + ,lColor + ); + vPoint[0].x = vX + 1; + vPoint[0].y = vY + 1; + vPoint[1].x = vX + vWidth - 2; + vPoint[1].y = vY + vHeight - 2; + ::GpiMove(m_hPS, &vPoint[0]); + ::GpiBox( m_hPS + ,lControl + ,&vPoint[1] + ,(LONG)dRadius + ,(LONG)dRadius + ); + } + CalcBoundingBox(vX, vY); CalcBoundingBox(vX2, vY2); } // end of wxDC::DoDrawRoundedRectangle @@ -1115,7 +1226,6 @@ void wxDC::DoDrawEllipticArc( FIXED vFSweepa; // Start angle, sweep angle double dIntPart; double dFractPart; - double dRadius; vY = OS2Y(vY,vHeight); @@ -1132,8 +1242,8 @@ void wxDC::DoDrawEllipticArc( vArcp.lP = vWidth/2; vArcp.lS = 0; ::GpiSetArcParams(m_hPS, &vArcp); // Sets parameters to default - vPtlPos.x = vX + vWidth/2 * (1. + cos(DegToRad(dSa))); // Loads x-coordinate - vPtlPos.y = vY + vHeight/2 * (1. + sin(DegToRad(dSa))); // Loads y-coordinate + vPtlPos.x = (wxCoord)(vX + vWidth/2 * (1. + cos(DegToRad(dSa)))); // Loads x-coordinate + vPtlPos.y = (wxCoord)(vY + vHeight/2 * (1. + sin(DegToRad(dSa)))); // Loads y-coordinate ::GpiMove(m_hPS, &vPtlPos); // Sets current position // @@ -1165,15 +1275,21 @@ void wxDC::DoDrawIcon( , wxCoord vY ) { - vY = OS2Y(vY,rIcon.GetHeight()); - wxCHECK_RET( rIcon.Ok(), wxT("invalid icon in DrawIcon") ); + // + // Need to copy back into a bitmap. ::WinDrawPointer uses device coords + // and I don't feel like figuring those out for scrollable windows so + // just convert to a bitmap then let the DoDrawBitmap routing display it + // + if (rIcon.IsXpm()) + { + DoDrawBitmap(rIcon.GetXpmSrc(), vX, vY, true); + } + else + { + wxBitmap vBitmap(rIcon); - ::WinDrawPointer( GetHPS() - ,vX - ,vY - ,(HPOINTER)GetHiconOf(rIcon) - ,DP_NORMAL - ); + DoDrawBitmap(vBitmap, vX, vY, false); + } CalcBoundingBox(vX, vY); CalcBoundingBox(vX + rIcon.GetWidth(), vY + rIcon.GetHeight()); } // end of wxDC::DoDrawIcon @@ -1185,16 +1301,400 @@ void wxDC::DoDrawBitmap( , bool bUseMask ) { - POINTL vPoint = {vX, vY}; + if (!IsKindOf(CLASSINFO(wxPrinterDC))) + { + HBITMAP hBitmap = (HBITMAP)rBmp.GetHBITMAP(); + HBITMAP hBitmapOld; + POINTL vPoint[4]; + + vY = OS2Y(vY,rBmp.GetHeight()); + + vPoint[0].x = vX; + vPoint[0].y = vY + rBmp.GetHeight(); + vPoint[1].x = vX + rBmp.GetWidth(); + vPoint[1].y = vY; + vPoint[2].x = 0; + vPoint[2].y = 0; + vPoint[3].x = rBmp.GetWidth(); + vPoint[3].y = rBmp.GetHeight(); + if (bUseMask) + { + wxMask* pMask = rBmp.GetMask(); - ::WinDrawBitmap( GetHPS() - ,(HBITMAP)GetHbitmapOf(rBmp) - ,NULL - ,&vPoint - ,0L - ,0L - ,DBM_NORMAL - ); + 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 hOldMask = NULLHANDLE; + 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; + + 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(wxWindowDC))) + { + wxWindowDC* pWindowDC = wxDynamicCast(this, wxWindowDC); + + lColor = pWindowDC->m_pCanvas->GetBackgroundColour().GetPixel(); + } + else if (GetBrush().Ok()) + 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); + } + ::GpiQueryBitmapInfoHeader(hBitmap, &vHeader); + vInfo.cBitCount = 24; + if ((lScans = ::GpiQueryBitmapBits( hPS + ,0L + ,(LONG)rBmp.GetHeight() + ,(PBYTE)pucBits + ,&vInfo + )) == GPI_ALTERROR) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + } + if ((hOldMask = ::GpiSetBitmap(hPS, hMask)) == HBM_ERROR) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + } + ::GpiQueryBitmapInfoHeader(hMask, &vHeader); + vInfo.cBitCount = 24; + if ((lScans = ::GpiQueryBitmapBits( hPS + ,0L + ,(LONG)rBmp.GetHeight() + ,(PBYTE)pucBitsMask + ,&vInfo + )) == GPI_ALTERROR) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + } + if (( hMask = ::GpiSetBitmap(hPS, hOldMask)) == HBM_ERROR) + { + 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; + + // + // 16 bit kludge really only kinda works. The mask gets applied + // where needed but the original bitmap bits are dorked sometimes + // + bool bpp16 = (wxDisplayDepth() == 16); + + for (i = 0; i < rBmp.GetHeight(); i++) + { + for (j = 0; j < rBmp.GetWidth(); j++) + { + // Byte 1 + if (bpp16 && *pucDataMask == 0xF8) // 16 bit display gobblygook + pucData++; + else if (*pucDataMask == 0xFF) // leave bitmap byte alone + pucData++; + else + { + *pucData = ((unsigned char)(lColor >> 16)); + pucData++; + } + // Byte 2 + if (bpp16 && *(pucDataMask + 1) == 0xFC) // 16 bit display gobblygook + pucData++; + else if (*(pucDataMask + 1) == 0xFF) // leave bitmap byte alone + pucData++; + else + { + *pucData = ((unsigned char)(lColor >> 8)); + pucData++; + } + + // Byte 3 + if (bpp16 && *(pucDataMask + 2) == 0xF8) // 16 bit display gobblygook + pucData++; + else if (*(pucDataMask + 2) == 0xFF) // leave bitmap byte alone + pucData++; + else + { + *pucData = ((unsigned char)lColor); + pucData++; + } + pucDataMask += 3; + } + for (j = 0; j < nPadding; j++) + { + pucData++; + pucDataMask++; + } + } + // + // Create a new bitmap + // + vHeader.cx = (ULONG)rBmp.GetWidth(); + vHeader.cy = (ULONG)rBmp.GetHeight(); + vHeader.cPlanes = 1L; + vHeader.cBitCount = 24; + 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); + ::GpiDeleteBitmap(hNewBitmap); + ::GpiDestroyPS(hPS); + ::DevCloseDC(hDC); + } + } + else + { + ULONG lOldForeGround = ::GpiQueryColor((HPS)GetHPS()); + ULONG lOldBackGround = ::GpiQueryBackColor((HPS)GetHPS()); + + if (m_textForegroundColour.Ok()) + { + ::GpiSetColor( (HPS)GetHPS() + ,m_textForegroundColour.GetPixel() + ); + } + if (m_textBackgroundColour.Ok()) + { + ::GpiSetBackColor( (HPS)GetHPS() + ,m_textBackgroundColour.GetPixel() + ); + } + // + // Need to alter bits in a mono bitmap to match the new + // background-foreground if it is different. + // + if (rBmp.IsMono() && + ((m_textForegroundColour.GetPixel() != lOldForeGround) || + (m_textBackgroundColour.GetPixel() != lOldBackGround))) + { + 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); + + int nBytesPerLine = rBmp.GetWidth() * 3; + int i, j; + LONG lForeGround = m_textForegroundColour.GetPixel(); + LONG lBackGround = m_textBackgroundColour.GetPixel(); + LONG lScans; + HBITMAP hOldBitmap = NULLHANDLE; + BITMAPINFO2 vInfo; + ERRORID vError; + wxString sError; + + + memset(&vInfo, '\0', 16); + vInfo.cbFix = 16; + vInfo.cx = (ULONG)rBmp.GetWidth(); + vInfo.cy = (ULONG)rBmp.GetHeight(); + vInfo.cPlanes = 1; + vInfo.cBitCount = 24; + + unsigned char* pucBits; // buffer that will contain the bitmap data + unsigned char* pucData; // pointer to use to traverse bitmap data + + pucBits = new unsigned char[nBytesPerLine * rBmp.GetHeight()]; + memset(pucBits, '\0', (nBytesPerLine * rBmp.GetHeight())); + + if ((hOldBitmap = ::GpiSetBitmap(hPS, hBitmap)) == HBM_ERROR) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + return; + } + if ((lScans = ::GpiQueryBitmapBits( hPS + ,0L + ,(LONG)rBmp.GetHeight() + ,(PBYTE)pucBits + ,&vInfo + )) == GPI_ALTERROR) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + return; + } + unsigned char cOldRedFore = (unsigned char)(lOldForeGround >> 16); + unsigned char cOldGreenFore = (unsigned char)(lOldForeGround >> 8); + unsigned char cOldBlueFore = (unsigned char)lOldForeGround; + + unsigned char cRedFore = (unsigned char)(lForeGround >> 16); + unsigned char cGreenFore = (unsigned char)(lForeGround >> 8); + unsigned char cBlueFore = (unsigned char)lForeGround; + + unsigned char cRedBack = (unsigned char)(lBackGround >> 16); + unsigned char cGreenBack = (unsigned char)(lBackGround >> 8); + unsigned char cBlueBack = (unsigned char)lBackGround; + + pucData = pucBits; + for (i = 0; i < rBmp.GetHeight(); i++) + { + for (j = 0; j < rBmp.GetWidth(); j++) + { + unsigned char cBmpRed = *pucData; + unsigned char cBmpGreen = *(pucData + 1); + unsigned char cBmpBlue = *(pucData + 2); + + if ((cBmpRed == cOldRedFore) && + (cBmpGreen == cOldGreenFore) && + (cBmpBlue == cOldBlueFore)) + { + *pucData = cBlueFore; + pucData++; + *pucData = cGreenFore; + pucData++; + *pucData = cRedFore; + pucData++; + } + else + { + *pucData = cBlueBack; + pucData++; + *pucData = cGreenBack; + pucData++; + *pucData = cRedBack; + pucData++; + } + } + } + if ((lScans = ::GpiSetBitmapBits( hPS + ,0L + ,(LONG)rBmp.GetHeight() + ,(PBYTE)pucBits + ,&vInfo + )) == GPI_ALTERROR) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + return; + } + delete [] pucBits; + ::GpiSetBitmap(hPS, NULLHANDLE); + ::GpiDestroyPS(hPS); + ::DevCloseDC(hDC); + } + ::GpiWCBitBlt( (HPS)GetHPS() + ,hBitmap + ,4 + ,vPoint + ,ROP_SRCCOPY + ,BBO_IGNORE + ); + ::GpiSetBitmap((HPS)GetHPS(), hBitmapOld); + ::GpiSetColor((HPS)GetHPS(), lOldForeGround); + ::GpiSetBackColor((HPS)GetHPS(), lOldBackGround); + } + } } // end of wxDC::DoDrawBitmap void wxDC::DoDrawText( @@ -1256,13 +1756,41 @@ void wxDC::DrawAnyText( ,&vTextY ); vPtlStart.x = vX; - vPtlStart.y = OS2Y(vY,vTextY); + if (!(m_vRclPaint.yTop == 0 && + m_vRclPaint.yBottom == 0 && + m_vRclPaint.xRight == 0 && + m_vRclPaint.xLeft == 0)) + { + // + // Position Text a little differently in the Statusbar from other panels + // + if (m_pCanvas && m_pCanvas->IsKindOf(CLASSINFO(wxStatusBar))) + vPtlStart.y = OS2Y(vY,vTextY); + else + vPtlStart.y = (wxCoord)(OS2Y(vY,vTextY/1.5)); // Full extent is a bit much + } + else + { + if (m_vSelectedBitmap != wxNullBitmap) + { + m_vRclPaint.yTop = m_vSelectedBitmap.GetHeight(); + m_vRclPaint.xRight = m_vSelectedBitmap.GetWidth(); + if (m_pCanvas && m_pCanvas->IsKindOf(CLASSINFO(wxStatusBar))) + vPtlStart.y = OS2Y(vY,vTextY); + else + vPtlStart.y = (LONG)(OS2Y(vY,vTextY/1.5)); + } + else + vPtlStart.y = vY; + } - lHits = ::GpiCharStringAt( m_hPS - ,&vPtlStart - ,rsText.length() - ,(PCH)rsText.c_str() - ); + PCH pzStr = (PCH)rsText.c_str(); + + ::GpiMove(m_hPS, &vPtlStart); + lHits = ::GpiCharString( m_hPS + ,rsText.length() + ,pzStr + ); if (lHits != GPI_OK) { wxLogLastError(wxT("TextOut")); @@ -1353,6 +1881,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 ) @@ -1439,6 +2013,7 @@ void wxDC::SetPen( if (!m_hOldPen) m_hOldPen = m_pen.GetPS(); } + ::GpiSetColor(m_hPS, m_pen.GetColour().GetPixel()); } } @@ -1487,7 +2062,7 @@ void wxDC::SetBackground( return; if (m_pCanvas) { - bool bCustomColours = TRUE; + bool bCustomColours = true; // // If we haven't specified wxUSER_COLOURS, don't allow the panel/dialog box to @@ -1495,12 +2070,12 @@ void wxDC::SetBackground( // if (m_pCanvas->IsKindOf(CLASSINFO(wxWindow)) && ((m_pCanvas->GetWindowStyleFlag() & wxUSER_COLOURS) != wxUSER_COLOURS)) - bCustomColours = FALSE; + bCustomColours = false; if (bCustomColours) { if (m_backgroundBrush.GetStyle()==wxTRANSPARENT) { - m_pCanvas->SetTransparent(TRUE); + m_pCanvas->SetTransparent(true); } else { @@ -1514,7 +2089,7 @@ void wxDC::SetBackground( // parent? // m_canvas->SetBackgroundColour(m_backgroundBrush.GetColour()); // - m_pCanvas->SetTransparent(FALSE); + m_pCanvas->SetTransparent(false); } } } @@ -1605,8 +2180,8 @@ bool wxDC::StartDoc( const wxString& rsMessage ) { - // We might be previewing, so return TRUE to let it continue. - return TRUE; + // We might be previewing, so return true to let it continue. + return true; } // end of wxDC::StartDoc void wxDC::EndDoc() @@ -1689,8 +2264,8 @@ void wxDC::DoGetTextExtent( vErrorCode = ::WinGetLastError(wxGetInstance()); sError = wxPMErrorToStr(vErrorCode); // DEBUG - sprintf(zMsg, "GpiQueryTextBox for %s: failed with Error: %x - %s", pStr, vErrorCode, sError.c_str()); - (void)wxMessageBox( "wxWindows Menu sample" + sprintf(zMsg, "GpiQueryTextBox for %s: failed with Error: %lx - %s", pStr, vErrorCode, sError.c_str()); + (void)wxMessageBox( "wxWidgets Menu sample" ,zMsg ,wxICON_INFORMATION ); @@ -1795,8 +2370,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 @@ -1884,7 +2459,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 @@ -1894,7 +2470,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 @@ -1904,7 +2481,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 @@ -1914,7 +2492,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); } // --------------------------------------------------------------------------- @@ -1947,7 +2526,7 @@ bool wxDC::DoBlit( pMask = rBmp.GetMask(); if (!(rBmp.Ok() && pMask && pMask->GetMaskBitmap())) { - bUseMask = FALSE; + bUseMask = false; } } @@ -1995,7 +2574,7 @@ bool wxDC::DoBlit( case wxNOR: lRop = ROP_NOTSRCCOPY; break; default: wxFAIL_MSG( wxT("unsupported logical function") ); - return FALSE; + return false; } bool bSuccess; @@ -2027,7 +2606,7 @@ bool wxDC::DoBlit( vBmpHdr.cBitCount = 24; #if wxUSE_DC_CACHEING - if (TRUE) + if (true) { // // create a temp buffer bitmap and DCs to access it and the mask @@ -2057,25 +2636,25 @@ bool wxDC::DoBlit( hBufBitmap = ::GpiCreateBitmap(GetHPS(), &vBmpHdr, 0L, NULL, NULL); } - POINTL aPoint1[4] = { 0, 0 - ,vWidth, vHeight - ,vXdest, vYdest - ,vXdest + vWidth, vYdest + vHeight + POINTL aPoint1[4] = { {0, 0} + ,{vWidth, vHeight} + ,{vXdest, vYdest} + ,{vXdest + vWidth, vYdest + vHeight} }; - POINTL aPoint2[4] = { 0, 0 - ,vWidth, vHeight - ,vXsrc, vYsrc - ,vXsrc + vWidth, vYsrc + vHeight + POINTL aPoint2[4] = { {0, 0} + ,{vWidth, vHeight} + ,{vXsrc, vYsrc} + ,{vXsrc + vWidth, vYsrc + vHeight} }; - POINTL aPoint3[4] = { vXdest, vYdest - ,vXdest + vWidth, vYdest + vHeight - ,vXsrc, vYsrc - ,vXsrc + vWidth, vYsrc + vHeight + POINTL aPoint3[4] = { {vXdest, vYdest} + ,{vXdest + vWidth, vYdest + vHeight} + ,{vXsrc, vYsrc} + ,{vXsrc + vWidth, vYsrc + vHeight} }; - POINTL aPoint4[4] = { vXdest, vYdest - ,vXdest + vWidth, vYdest + vHeight - ,0, 0 - ,vWidth, vHeight + POINTL aPoint4[4] = { {vXdest, vYdest} + ,{vXdest + vWidth, vYdest + vHeight} + ,{0, 0} + ,{vWidth, vHeight} }; ::GpiSetBitmap(hPSMask, (HBITMAP) pMask->GetMaskBitmap()); ::GpiSetBitmap(hPSBuffer, (HBITMAP) hBufBitmap); @@ -2166,7 +2745,7 @@ bool wxDC::DoBlit( ); if (rc == GPI_ERROR) { - bSuccess = FALSE; + bSuccess = false; wxLogLastError(wxT("BitBlt")); } @@ -2182,14 +2761,14 @@ bool wxDC::DoBlit( ::DevCloseDC(hDCBuffer); ::GpiDeleteBitmap(hBufBitmap); #endif - bSuccess = TRUE; + bSuccess = true; } else // no mask, just BitBlt() it { - POINTL aPoint[4] = { vXdest, vYdest - ,vXdest + vWidth, vYdest + vHeight - ,vXsrc, vYsrc - ,vXsrc + vWidth, vYsrc + vHeight + POINTL aPoint[4] = { {vXdest, vYdest} + ,{vXdest + vWidth, vYdest + vHeight} + ,{vXsrc, vYsrc} + ,{vXsrc + vWidth, vYsrc + vHeight} }; bSuccess = (::GpiBitBlt( m_hPS @@ -2281,8 +2860,8 @@ wxSize wxDC::GetPPI() const nPelHeight = lArray[CAPS_HEIGHT]; nHorzRes = lArray[CAPS_HORIZONTAL_RESOLUTION]; // returns pel/meter nVertRes = lArray[CAPS_VERTICAL_RESOLUTION]; // returns pel/meter - nWidth = (nHorzRes/39.3) * nPelWidth; - nHeight = (nVertRes/39.3) * nPelHeight; + nWidth = (int)((nHorzRes/39.3) * nPelWidth); + nHeight = (int)((nVertRes/39.3) * nPelHeight); } return (wxSize(nWidth,nHeight)); } // end of wxDC::GetPPI @@ -2296,18 +2875,5 @@ void wxDC::SetLogicalScale( m_logicalScaleY = dY; }; // end of wxDC::SetLogicalScale -#if WXWIN_COMPATIBILITY -void wxDC::DoGetTextExtent(const wxString& string, float *x, float *y, - float *descent, float *externalLeading, - wxFont *theFont, bool use16bit) const -{ - wxCoord x1, y1, descent1, externalLeading1; - GetTextExtent(string, & x1, & y1, & descent1, & externalLeading1, theFont, use16bit); - *x = x1; *y = y1; - if (descent) - *descent = descent1; - if (externalLeading) - *externalLeading = externalLeading1; -} -#endif +