+ POINTL vPoint;
+
+ if (vXoffset != 0L || vXoffset != 0L)
+ {
+ int i;
+
+ vPoint.x = vPoints[0].x + vXoffset;
+ vPoint.y = OS2Y(vPoints[0].y + vYoffset,0);
+ ::GpiMove(m_hPS, &vPoint);
+
+ LONG lBorderColor = m_pen.GetColour().GetPixel();
+
+ ::GpiSetColor(m_hPS, lBorderColor);
+ for(i = 1; i < n; i++)
+ {
+ vPoint.x = vPoints[i].x + vXoffset;
+ vPoint.y = OS2Y(vPoints[i].y + vYoffset,0);
+ ::GpiLine(m_hPS, &vPoint);
+ }
+ }
+ else
+ {
+ int i;
+
+ CalcBoundingBox( vPoints[i].x
+ ,vPoints[i].y
+ );
+ vPoint.x = vPoints[0].x;
+ vPoint.y = OS2Y(vPoints[0].y,0);
+ ::GpiMove(m_hPS, &vPoint);
+
+ for (i = 0; i < n; i++)
+ {
+ CalcBoundingBox( vPoints[i].x
+ ,vPoints[i].y
+ );
+ vPoint.x = vPoints[i].x;
+ vPoint.y = OS2Y(vPoints[i].y,0);
+ ::GpiLine(m_hPS, &vPoint);
+ }
+ }
+} // end of wxDC::DoDrawLines
+
+void wxDC::DoDrawRectangle(
+ wxCoord vX
+, wxCoord vY
+, wxCoord vWidth
+, wxCoord vHeight
+)
+{
+ POINTL vPoint[2];
+ LONG lControl;
+ LONG lColor;
+ LONG lBorderColor;
+ int nIsTRANSPARENT = 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))
+ 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 - 1;
+ vPoint[1].y = vY + vHeight - 1;
+ ::GpiMove(m_hPS, &vPoint[0]);
+ lColor = m_brush.GetColour().GetPixel();
+ lBorderColor = m_pen.GetColour().GetPixel();
+ 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
+ ,0L // horizontal corner radius
+ ,0L // vertical corner radius
+ );
+ }
+ else
+ {
+ lControl = DRO_OUTLINE;
+ ::GpiSetColor( m_hPS
+ ,lBorderColor
+ );
+ ::GpiBox( m_hPS
+ ,lControl
+ ,&vPoint[1]
+ ,0L
+ ,0L
+ );
+ 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]
+ ,0L
+ ,0L
+ );
+ }
+ CalcBoundingBox(vX, vY);
+ CalcBoundingBox(vX2, vY2);
+} // end of wxDC::DoDrawRectangle
+
+void wxDC::DoDrawRoundedRectangle(
+ wxCoord vX
+, wxCoord vY
+, wxCoord vWidth
+, wxCoord vHeight
+, double dRadius
+)
+{
+ POINTL vPoint[2];
+ LONG lControl;
+ LONG lColor;
+ LONG lBorderColor;
+ int nIsTRANSPARENT = 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))
+ 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 - 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;
+ ::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
+
+// Draw Ellipse within box (x,y) - (x+width, y+height)
+void wxDC::DoDrawEllipse(
+ wxCoord vX
+, wxCoord vY
+, wxCoord vWidth
+, wxCoord vHeight
+)
+{
+ POINTL vPtlPos; // Structure for current position
+ FIXED vFxMult; // Multiplier for ellipse
+ ARCPARAMS vArcp; // Structure for arc parameters
+
+ vY = OS2Y(vY,vHeight);
+
+ vArcp.lR = 0;
+ vArcp.lQ = vHeight/2;
+ vArcp.lP = vWidth/2;
+ vArcp.lS = 0;
+ ::GpiSetArcParams( m_hPS
+ ,&vArcp
+ ); // Sets parameters to default
+ vPtlPos.x = vX + vWidth/2; // Loads x-coordinate
+ vPtlPos.y = vY + vHeight/2; // Loads y-coordinate
+ ::GpiMove( m_hPS
+ ,&vPtlPos
+ ); // Sets current position
+ vFxMult = MAKEFIXED(1, 0); /* Sets multiplier */
+
+ //
+ // DRO_FILL, DRO_OTLINEFILL - where to get
+ //
+ ::GpiFullArc( m_hPS
+ ,DRO_OUTLINE
+ ,vFxMult
+ ); // Draws full arc with center at current position
+
+ wxCoord vX2 = (vX + vWidth);
+ wxCoord vY2 = (vY + vHeight);
+
+ CalcBoundingBox(vX, vY);
+ CalcBoundingBox(vX2, vY2);
+} // end of wxDC::DoDrawEllipse
+
+void wxDC::DoDrawEllipticArc(
+ wxCoord vX
+, wxCoord vY
+, wxCoord vWidth
+, wxCoord vHeight
+, double dSa
+, double dEa
+)
+{
+ POINTL vPtlPos; // Structure for current position
+ FIXED vFxMult; // Multiplier for ellipse
+ ARCPARAMS vArcp; // Structure for arc parameters
+ FIXED vFSa;
+ FIXED vFSweepa; // Start angle, sweep angle
+ double dIntPart;
+ double dFractPart;
+ double dRadius;
+
+ vY = OS2Y(vY,vHeight);
+
+ dFractPart = modf(dSa,&dIntPart);
+ vFSa = MAKEFIXED((int)dIntPart, (int)(dFractPart * 0xffff) );
+ dFractPart = modf(dEa - dSa, &dIntPart);
+ vFSweepa = MAKEFIXED((int)dIntPart, (int)(dFractPart * 0xffff) );
+
+ //
+ // Ellipse main axis (r,q), (p,s) with center at (0,0)
+ //
+ vArcp.lR = 0;
+ vArcp.lQ = vHeight/2;
+ 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
+ ::GpiMove(m_hPS, &vPtlPos); // Sets current position
+
+ //
+ // May be not to the center ?
+ //
+ vPtlPos.x = vX + vWidth/2 ; // Loads x-coordinate
+ vPtlPos.y = vY + vHeight/2; // Loads y-coordinate
+ vFxMult = MAKEFIXED(1, 0); // Sets multiplier
+
+ //
+ // DRO_FILL, DRO_OTLINEFILL - where to get
+ //
+ ::GpiPartialArc( m_hPS
+ ,&vPtlPos
+ ,vFxMult
+ ,vFSa
+ ,vFSweepa
+ );
+ wxCoord vX2 = (vX + vWidth);
+ wxCoord vY2 = (vY + vHeight);
+
+ CalcBoundingBox(vX, vY);
+ CalcBoundingBox(vX2, vY2);
+} // end of wxDC::DoDrawEllipticArc
+
+void wxDC::DoDrawIcon(
+ const wxIcon& rIcon
+, wxCoord vX
+, wxCoord vY
+)
+{
+ //
+ // 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);
+
+ DoDrawBitmap(vBitmap, vX, vY, FALSE);
+ }
+ CalcBoundingBox(vX, vY);
+ CalcBoundingBox(vX + rIcon.GetWidth(), vY + rIcon.GetHeight());
+} // end of wxDC::DoDrawIcon
+
+void wxDC::DoDrawBitmap(
+ const wxBitmap& rBmp
+, wxCoord vX
+, wxCoord vY
+, bool bUseMask
+)
+{
+ 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();
+
+ 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(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);
+ }
+ ::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
+ {
+ LONG lOldForeGround = ::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()
+ );
+ }
+ //
+ // 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 cOldRedBack = (unsigned char)(lOldBackGround >> 16);
+ unsigned char cOldGreenBack = (unsigned char)(lOldBackGround >> 8);
+ unsigned char cOldBlueBack = (unsigned char)lOldBackGround;
+
+ 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(
+ const wxString& rsText
+, wxCoord vX
+, wxCoord vY
+)
+{
+ wxCoord vWidth;
+ wxCoord vHeight;
+
+ DrawAnyText( rsText
+ ,vX
+ ,vY
+ );
+
+ CalcBoundingBox(vX, vY);
+ GetTextExtent(rsText, &vWidth, &vHeight);
+ CalcBoundingBox((vX + vWidth), (vY + vHeight));
+} // end of wxDC::DoDrawText
+
+void wxDC::DrawAnyText(
+ const wxString& rsText
+, wxCoord vX
+, wxCoord vY
+)
+{
+ int nOldBackground = 0;
+ POINTL vPtlStart;
+ LONG lHits;
+ wxCoord vTextX = 0;
+ wxCoord vTextY = 0;
+
+ //
+ // prepare for drawing the text
+ //
+
+ //
+ // Set text color attributes
+ //
+ if (m_textForegroundColour.Ok())
+ {
+ SetTextColor( m_hPS
+ ,(int)m_textForegroundColour.GetPixel()
+ );
+ }
+
+ if (m_textBackgroundColour.Ok())
+ {
+ nOldBackground = SetTextBkColor( m_hPS
+ ,(int)m_textBackgroundColour.GetPixel()
+ );
+ }
+ SetBkMode( m_hPS
+ ,m_backgroundMode
+ );
+ GetTextExtent( rsText
+ ,&vTextX
+ ,&vTextY
+ );
+ vPtlStart.x = vX;
+ if (!(m_vRclPaint.yTop == 0 &&
+ m_vRclPaint.yBottom == 0 &&
+ m_vRclPaint.xRight == 0 &&
+ m_vRclPaint.xLeft == 0))
+ vPtlStart.y = 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();
+ vPtlStart.y = OS2Y(vY,vTextY/1.5);
+ }
+ else
+ vPtlStart.y = vY;
+ }
+
+ PCH pzStr = (PCH)rsText.c_str();
+
+ ::GpiMove(m_hPS, &vPtlStart);
+ lHits = ::GpiCharString( m_hPS
+ ,rsText.length()
+ ,pzStr
+ );
+ if (lHits != GPI_OK)
+ {
+ wxLogLastError(wxT("TextOut"));
+ }
+
+ //
+ // Restore the old parameters (text foreground colour may be left because
+ // it never is set to anything else, but background should remain
+ // transparent even if we just drew an opaque string)
+ //
+ if (m_textBackgroundColour.Ok())
+ SetTextBkColor( m_hPS
+ ,nOldBackground
+ );
+ SetBkMode( m_hPS
+ ,wxTRANSPARENT
+ );