X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2c4a8d17cd2a8d956e989fd27dd60f5cee49e3fa..6c34d0ede9d6f7086896a1e4467091f0360846de:/src/os2/dc.cpp diff --git a/src/os2/dc.cpp b/src/os2/dc.cpp index 5b740a9cc4..6644a2f340 100644 --- a/src/os2/dc.cpp +++ b/src/os2/dc.cpp @@ -143,52 +143,67 @@ wxDC::wxDC(void) m_bOwnsDC = FALSE; m_hDC = 0; - m_nDCCount = 0; m_hOldPS = NULL; m_hPS = NULL; m_bIsPaintTime = FALSE; // True at Paint Time m_brush.GetColour().Set("WHITE"); -} +} // end of wxDC::wxDC wxDC::~wxDC(void) { -} + if ( m_hDC != 0 ) + { + SelectOldObjects(m_hDC); + + // if we own the HDC, we delete it, otherwise we just release it + + if (m_bOwnsDC) + { + if(m_hPS) + { + ::GpiAssociate(m_hPS, NULLHANDLE); + ::GpiDestroyPS(m_hPS); + } + m_hPS = NULLHANDLE; + ::DevCloseDC((HDC)m_hDC); + } + else + { + // + // Just Dissacociate, not destroy if we don't own the DC + // + if(m_hPS) + { + ::GpiAssociate(m_hPS, NULLHANDLE); + } + } + } +} // end of wxDC::~wxDC // This will select current objects out of the DC, // which is what you have to do before deleting the // DC. -void wxDC::SelectOldObjects(WXHDC dc) +void wxDC::SelectOldObjects( + WXHDC hPS +) { - if (dc) + if (hPS) { if (m_hOldBitmap) { -// ::SelectObject((HDC) dc, (HBITMAP) m_oldBitmap); + ::GpiSetBitmap(hPS, (HBITMAP) m_hOldBitmap); if (m_vSelectedBitmap.Ok()) { m_vSelectedBitmap.SetSelectedInto(NULL); } } m_hOldBitmap = 0; - if (m_hOldPen) - { -// ::SelectObject((HDC) dc, (HPEN) m_oldPen); - } + // + // OS/2 has no other native GDI objects to set in a PS/DC like windows + // m_hOldPen = 0; - if (m_hOldBrush) - { -// ::SelectObject((HDC) dc, (HBRUSH) m_oldBrush); - } m_hOldBrush = 0; - if (m_hOldFont) - { -// ::SelectObject((HDC) dc, (HFONT) m_oldFont); - } m_hOldFont = 0; - if (m_hOldPalette) - { -// ::SelectPalette((HDC) dc, (HPALETTE) m_oldPalette, TRUE); - } m_hOldPalette = 0; } @@ -198,7 +213,7 @@ void wxDC::SelectOldObjects(WXHDC dc) m_font = wxNullFont; m_backgroundBrush = wxNullBrush; m_vSelectedBitmap = wxNullBitmap; -} +} // end of wxDC::SelectOldObjects // --------------------------------------------------------------------------- // clipping @@ -283,18 +298,27 @@ bool wxDC::CanDrawBitmap() const bool wxDC::CanGetTextExtent() const { - // What sort of display is it? - int technology = 0; // TODO: ::GetDeviceCaps(GetHdc(), TECHNOLOGY); + LONG lTechnology = 0L; - // TODO: return (technology == DT_RASDISPLAY) || (technology == DT_RASPRINTER); - return FALSE; -} + ::DevQueryCaps(GetHDC(), CAPS_TECHNOLOGY, 1L, &lTechnology); + return (lTechnology == CAPS_TECH_RASTER_DISPLAY) || (lTechnology == CAPS_TECH_RASTER_PRINTER); +} // end of wxDC::CanGetTextExtent int wxDC::GetDepth() const { - // TODO: - return (1); -} + LONG lArray[CAPS_COLOR_BITCOUNT]; + int nBitsPerPixel; + + if(::DevQueryCaps( GetHDC() + ,CAPS_FAMILY + ,CAPS_COLOR_BITCOUNT + ,lArray + )) + { + nBitsPerPixel = (int)lArray[CAPS_COLOR_BITCOUNT]; + } + return nBitsPerPixel; +} // end of wxDC::GetDepth // --------------------------------------------------------------------------- // drawing @@ -346,10 +370,35 @@ bool wxDC::DoGetPixel( return(FALSE); } -void wxDC::DoCrossHair(wxCoord x, wxCoord y) +void wxDC::DoCrossHair( + wxCoord vX +, wxCoord vY +) { - // TODO -} + wxCoord vX1 = vX - VIEWPORT_EXTENT; + wxCoord vY1 = vY - VIEWPORT_EXTENT; + wxCoord vX2 = vX + VIEWPORT_EXTENT; + wxCoord vY2 = vY + VIEWPORT_EXTENT; + POINTL vPoint[4]; + + vPoint[0].x = vX1; + vPoint[0].y = m_vRclPaint.yTop - vY; + + vPoint[1].x = vX2; + vPoint[1].y = m_vRclPaint.yTop - vY; + + ::GpiMove(m_hPS, &vPoint[0]); + ::GpiLine(m_hPS, &vPoint[1]); + + vPoint[2].x = vX; + vPoint[2].y = m_vRclPaint.yTop - vY1; + + vPoint[3].x = vX; + vPoint[3].y = m_vRclPaint.yTop - vY2; + + ::GpiMove(m_hPS, &vPoint[2]); + ::GpiLine(m_hPS, &vPoint[3]); +} // end of wxDC::DoCrossHair void wxDC::DoDrawLine( wxCoord vX1 @@ -366,7 +415,7 @@ void wxDC::DoDrawLine( vPoint[1].y = m_vRclPaint.yTop - vY2; ::GpiMove(m_hPS, &vPoint[0]); ::GpiLine(m_hPS, &vPoint[1]); -} +} // end of wxDC::DoDrawLine ////////////////////////////////////////////////////////////////////////////// // Draws an arc of a circle, centred on (xc, yc), with starting point (x1, y1) @@ -460,7 +509,7 @@ void wxDC::DoDrawArc( vPtlArc[1].x = vX2; vPtlArc[1].y = vY2; ::GpiPointArc(m_hPS, vPtlArc); // Draws the arc -} +} // end of wxDC::DoDrawArc void wxDC::DoDrawCheckMark( wxCoord vX1 @@ -497,7 +546,7 @@ void wxDC::DoDrawCheckMark( ::GpiMove(m_hPS, &vPoint[0]); ::GpiLine(m_hPS, &vPoint[1]); } -} +} // end of wxDC::DoDrawCheckMark void wxDC::DoDrawPoint( wxCoord vX @@ -509,7 +558,7 @@ void wxDC::DoDrawPoint( vPoint.x = vX; vPoint.y = m_vRclPaint.yTop - vY; ::GpiSetPel(m_hPS, &vPoint); -} +} // end of wxDC::DoDrawPoint void wxDC::DoDrawPolygon( int n @@ -581,7 +630,7 @@ void wxDC::DoDrawPolygon( ::GpiMove(m_hPS, &vPoint); lHits = ::GpiPolygons(m_hPS, ulCount, &vPlgn, flOptions, flModel); free(vPlgn.aPointl); -} +} // end of wxDC::DoDrawPolygon void wxDC::DoDrawLines( int n @@ -606,7 +655,7 @@ void wxDC::DoDrawLines( vPoint.y = vPoints[0].y + vYoffset; ::GpiLine(m_hPS, &vPoint); } -} +} // end of wxDC::DoDrawLines void wxDC::DoDrawRectangle( wxCoord vX @@ -672,7 +721,7 @@ void wxDC::DoDrawRectangle( ,0L ); } -} +} // end of wxDC::DoDrawRectangle void wxDC::DoDrawRoundedRectangle( wxCoord vX @@ -700,7 +749,7 @@ void wxDC::DoDrawRoundedRectangle( ,(LONG)dRadius // horizontal corner radius ,(LONG)dRadius // vertical corner radius ); -} +} // end of wxDC::DoDrawRoundedRectangle // Draw Ellipse within box (x,y) - (x+width, y+height) void wxDC::DoDrawEllipse( @@ -735,7 +784,7 @@ void wxDC::DoDrawEllipse( ,DRO_OUTLINE ,vFxMult ); // Draws full arc with center at current position -} +} // end of wxDC::DoDrawEllipse void wxDC::DoDrawEllipticArc( wxCoord vX @@ -788,20 +837,42 @@ void wxDC::DoDrawEllipticArc( ,vFSa ,vFSweepa ); -} +} // end of wxDC::DoDrawEllipticArc -void wxDC::DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y) +void wxDC::DoDrawIcon( + const wxIcon& rIcon +, wxCoord vX +, wxCoord vY +) { - // TODO: -} + wxCHECK_RET( rIcon.Ok(), wxT("invalid icon in DrawIcon") ); -void wxDC::DoDrawBitmap( const wxBitmap &bmp - ,wxCoord x, wxCoord y - ,bool useMask - ) + ::WinDrawPointer( GetHPS() + ,vX + ,vY + ,(HPOINTER)GetHiconOf(rIcon) + ,DP_NORMAL + ); +} // end of wxDC::DoDrawIcon + +void wxDC::DoDrawBitmap( + const wxBitmap& rBmp +, wxCoord vX +, wxCoord vY +, bool bUseMask +) { - // TODO -} + POINTL vPoint = {vX, vY}; + + ::WinDrawBitmap( GetHPS() + ,(HBITMAP)GetHbitmapOf(rBmp) + ,NULL + ,&vPoint + ,0L + ,0L + ,DBM_NORMAL + ); +} // end of wxDC::DoDrawBitmap void wxDC::DoDrawText( const wxString& rsText @@ -1208,17 +1279,6 @@ void wxDC::DoGetTextExtent( if(vPtMax.x < avPoint[i].x) vPtMax.x = avPoint[i].x; if(vPtMax.y < avPoint[i].y) vPtMax.y = avPoint[i].y; } -#if 0 - sprintf(zMsg, "Extents for %s, are: Minx: %ld, Miny: %ld, Maxx: %ld, Maxy: %ld", vPtMin.x - , vPtMin.y - , vPtMax.x - , vPtMax.y - ); - (void)wxMessageBox( "wxWindows Menu sample" - ,zMsg - ,wxICON_INFORMATION - ); -#endif ::GpiQueryFontMetrics( m_hPS ,sizeof(FONTMETRICS) ,&vFM @@ -1337,19 +1397,268 @@ wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const // bit blit // --------------------------------------------------------------------------- -bool wxDC::DoBlit( wxCoord xdest - ,wxCoord ydest - ,wxCoord width - ,wxCoord height - ,wxDC *source - ,wxCoord xsrc - ,wxCoord ysrc - ,int rop - ,bool useMask - ) +bool wxDC::DoBlit( + wxCoord vXdest +, wxCoord vYdest +, wxCoord vWidth +, wxCoord vHeight +, wxDC* pSource +, wxCoord vXsrc +, wxCoord vYsrc +, int nRop +, bool bUseMask +) { - // TODO - return(TRUE); + wxMask* pMask = NULL; + CHARBUNDLE vCbnd; + COLORREF vOldTextColor; + COLORREF vOldBackground = ::GpiQueryBackColor(m_hPS); + + if (bUseMask) + { + const wxBitmap& rBmp = pSource->m_vSelectedBitmap; + + pMask = rBmp.GetMask(); + if (!(rBmp.Ok() && pMask && pMask->GetMaskBitmap())) + { + bUseMask = FALSE; + } + } + + ::GpiQueryAttrs( m_hPS + ,PRIM_CHAR + ,CBB_COLOR + ,&vCbnd + ); + vOldTextColor = (COLORREF)vCbnd.lColor; + + if (m_textForegroundColour.Ok()) + { + vCbnd.lColor = (LONG)m_textForegroundColour.GetPixel(); + ::GpiSetAttrs( m_hPS // presentation-space handle + ,PRIM_CHAR // Char primitive. + ,CBB_COLOR // sets color. + ,0 + ,&vCbnd // buffer for attributes. + ); + } + if (m_textBackgroundColour.Ok()) + { + ::GpiSetBackColor(m_hPS, (LONG)m_textBackgroundColour.GetPixel()); + } + + LONG lRop = ROP_SRCCOPY; + + switch (nRop) + { + case wxXOR: lRop = ROP_SRCINVERT; break; + case wxINVERT: lRop = ROP_DSTINVERT; break; + case wxOR_REVERSE: lRop = 0x00DD0228; break; + case wxAND_REVERSE: lRop = ROP_SRCERASE; break; + case wxCLEAR: lRop = ROP_ZERO; break; + case wxSET: lRop = ROP_ONE; break; + case wxOR_INVERT: lRop = ROP_MERGEPAINT; break; + case wxAND: lRop = ROP_SRCAND; break; + case wxOR: lRop = ROP_SRCPAINT; break; + case wxEQUIV: lRop = 0x00990066; break; + case wxNAND: lRop = 0x007700E6; break; + case wxAND_INVERT: lRop = 0x00220326; break; + case wxCOPY: lRop = ROP_SRCCOPY; break; + case wxNO_OP: lRop = ROP_NOTSRCERASE; break; + case wxSRC_INVERT: lRop = ROP_SRCINVERT; break; + case wxNOR: lRop = ROP_NOTSRCCOPY; break; + default: + wxFAIL_MSG( wxT("unsupported logical function") ); + return FALSE; + } + + bool bSuccess; + + if (bUseMask) + { + // + // Blit bitmap with mask + // + + // + // Create a temp buffer bitmap and DCs/PSs to access it and the mask + // + HDC hDCMask; + HDC hDCBuffer; + HPS hPSMask; + HPS hPSBuffer; + DEVOPENSTRUC vDOP = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L}; + BITMAPINFOHEADER2 vBmpHdr; + SIZEL vSize = {0, 0}; + LONG rc; + + hDCMask = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDOP, NULLHANDLE); + hDCBuffer = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDOP, NULLHANDLE); + hPSMask = ::GpiCreatePS(vHabmain, hDCMask, &vSize, PU_PELS | GPIT_MICRO | GPIA_ASSOC); + hPSBuffer = ::GpiCreatePS(vHabmain, hDCBuffer, &vSize, PU_PELS | GPIT_MICRO | GPIA_ASSOC); + + memset(&vBmpHdr, 0, sizeof(BITMAPINFOHEADER2)); + vBmpHdr.cbFix = sizeof(BITMAPINFOHEADER2); + vBmpHdr.cx = vWidth; + vBmpHdr.cy = vHeight; + vBmpHdr.cPlanes = 1; + vBmpHdr.cBitCount = 24; + + HBITMAP hBufBitmap = ::GpiCreateBitmap(GetHPS(), &vBmpHdr, 0L, NULL, NULL); + 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 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 + }; + ::GpiSetBitmap(hPSMask, (HBITMAP) pMask->GetMaskBitmap()); + ::GpiSetBitmap(hPSBuffer, (HBITMAP) hBufBitmap); + + // + // Copy dest to buffer + // + rc = ::GpiBitBlt( hPSBuffer + ,GetHPS() + ,4L + ,aPoint1 + ,ROP_SRCCOPY + ,BBO_IGNORE + ); + if (rc == GPI_ERROR) + { + wxLogLastError(wxT("BitBlt")); + } + + // + // Copy src to buffer using selected raster op + // + rc = ::GpiBitBlt( hPSBuffer + ,GetHPS() + ,4L + ,aPoint2 + ,lRop + ,BBO_IGNORE + ); + if (rc == GPI_ERROR) + { + wxLogLastError(wxT("BitBlt")); + } + + // + // Set masked area in buffer to BLACK (pixel value 0) + // + COLORREF vPrevBkCol = ::GpiQueryBackColor(GetHPS()); + COLORREF vPrevCol = ::GpiQueryColor(GetHPS()); + + ::GpiSetBackColor(GetHPS(), OS2RGB(255, 255, 255)); + ::GpiSetColor(GetHPS(), OS2RGB(0, 0, 0)); + + rc = ::GpiBitBlt( hPSBuffer + ,hPSMask + ,4L + ,aPoint2 + ,ROP_SRCAND + ,BBO_IGNORE + ); + if (rc == GPI_ERROR) + { + wxLogLastError(wxT("BitBlt")); + } + + // + // Set unmasked area in dest to BLACK + // + ::GpiSetBackColor(GetHPS(), OS2RGB(0, 0, 0)); + ::GpiSetColor(GetHPS(), OS2RGB(255, 255, 255)); + rc = ::GpiBitBlt( GetHPS() + ,hPSMask + ,4L + ,aPoint3 + ,ROP_SRCAND + ,BBO_IGNORE + ); + if (rc == GPI_ERROR) + { + wxLogLastError(wxT("BitBlt")); + } + + // + // Restore colours to original values + // + ::GpiSetBackColor(GetHPS(), vPrevBkCol); + ::GpiSetColor(GetHPS(), vPrevCol); + + // + // OR buffer to dest + // + rc = ::GpiBitBlt( GetHPS() + ,hPSMask + ,4L + ,aPoint4 + ,ROP_SRCPAINT + ,BBO_IGNORE + ); + if (rc == GPI_ERROR) + { + bSuccess = FALSE; + wxLogLastError(wxT("BitBlt")); + } + + // + // Tidy up temporary DCs and bitmap + // + ::GpiSetBitmap(hPSMask, NULLHANDLE); + ::GpiSetBitmap(hPSBuffer, NULLHANDLE); + ::GpiDestroyPS(hPSMask); + ::GpiDestroyPS(hPSBuffer); + ::DevCloseDC(hDCMask); + ::DevCloseDC(hDCBuffer); + ::GpiDeleteBitmap(hBufBitmap); + bSuccess = TRUE; + } + else // no mask, just BitBlt() it + { + POINTL aPoint[4] = { vXdest, vYdest + ,vXdest + vWidth, vYdest + vHeight + ,vXsrc, vYsrc + ,vXsrc + vWidth, vYsrc + vHeight + }; + + bSuccess = (::GpiBitBlt( m_hPS + ,pSource->GetHPS() + ,4L + ,aPoint + ,lRop + ,BBO_IGNORE + ) != GPI_ERROR); + if (!bSuccess ) + { + wxLogLastError(wxT("BitBlt")); + } + } + vCbnd.lColor = (LONG)vOldTextColor; + ::GpiSetAttrs( m_hPS // presentation-space handle + ,PRIM_CHAR // Char primitive. + ,CBB_COLOR // sets color. + ,0 + ,&vCbnd // buffer for attributes. + ); + ::GpiSetBackColor(m_hPS, (LONG)vOldBackground); + return bSuccess; } void wxDC::DoGetSize( int* width, int* height ) const