+#if wxUSE_PRINTING_ARCHITECTURE
+ if (!IsKindOf(CLASSINFO(wxPrinterDC)))
+#endif
+ {
+ HBITMAP hBitmap = (HBITMAP)rBmp.GetHBITMAP();
+ HBITMAP hBitmapOld = NULLHANDLE;
+ 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(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 in a double-word aligned 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(
+ 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);
+ }
+ else
+ {
+ if (m_vSelectedBitmap != wxNullBitmap)
+ {
+ m_vRclPaint.yTop = m_vSelectedBitmap.GetHeight();
+ m_vRclPaint.xRight = m_vSelectedBitmap.GetWidth();
+ vPtlStart.y = OS2Y(vY,vTextY);
+ }
+ 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
+ );
+}
+
+void wxDC::DoDrawRotatedText(
+ const wxString& rsText
+, wxCoord vX
+, wxCoord vY
+, double dAngle
+)
+{
+ if (dAngle == 0.0)
+ {
+ DoDrawText( rsText
+ ,vX
+ ,vY
+ );
+ }
+
+ // TODO:
+ /*
+ if ( angle == 0.0 )
+ {
+ DoDrawText(text, x, y);
+ }
+ else
+ {
+ LOGFONT lf;
+ wxFillLogFont(&lf, &m_font);
+
+ // GDI wants the angle in tenth of degree
+ long angle10 = (long)(angle * 10);
+ lf.lfEscapement = angle10;
+ lf. lfOrientation = angle10;
+
+ HFONT hfont = ::CreateFontIndirect(&lf);
+ if ( !hfont )
+ {
+ wxLogLastError("CreateFont");
+ }
+ else
+ {
+ HFONT hfontOld = ::SelectObject(GetHdc(), hfont);
+
+ DrawAnyText(text, x, y);
+
+ (void)::SelectObject(GetHdc(), hfontOld);
+ }
+
+ // call the bounding box by adding all four vertices of the rectangle
+ // containing the text to it (simpler and probably not slower than
+ // determining which of them is really topmost/leftmost/...)
+ wxCoord w, h;
+ GetTextExtent(text, &w, &h);
+
+ double rad = DegToRad(angle);
+
+ // "upper left" and "upper right"
+ CalcBoundingBox(x, y);
+ CalcBoundingBox(x + w*cos(rad), y - h*sin(rad));
+ CalcBoundingBox(x + h*sin(rad), y + h*cos(rad));
+
+ // "bottom left" and "bottom right"
+ x += (wxCoord)(h*sin(rad));
+ y += (wxCoord)(h*cos(rad));
+ CalcBoundingBox(x, y);
+ CalcBoundingBox(x + h*sin(rad), y + h*cos(rad));
+ }
+*/
+}
+
+// ---------------------------------------------------------------------------
+// set GDI objects
+// ---------------------------------------------------------------------------
+
+void wxDC::DoSelectPalette( bool WXUNUSED(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
+)
+{
+ if (m_hOldFont)
+ {
+ m_hOldFont = 0;
+ }
+ m_palette = rPalette;
+ if (!rPalette.Ok())
+ {
+ if (m_hOldFont)
+ {
+ m_hOldFont = 0;
+ }
+ }
+ HPALETTE hOldPal = ::GpiSelectPalette((HDC) m_hPS, (HPALETTE) m_palette.GetHPALETTE());
+ if (!m_hOldPalette)
+ m_hOldPalette = (WXHPALETTE)hOldPal;
+} // end of wxDC::SetPalette
+
+void wxDC::SetFont(
+ const wxFont& rFont
+)
+{
+ //
+ // Set the old object temporarily, in case the assignment deletes an object
+ // that's not yet selected out.
+ //
+ if (m_hOldFont)
+ {
+ m_hOldFont = 0;
+ }
+ m_font = rFont;
+ if (!rFont.Ok())
+ {
+ m_hOldFont = 0;
+ }
+
+ m_font.SetPS(m_hPS); // this will realize the font
+
+ if (m_font.Ok())
+ {
+ HFONT hFont = m_font.GetResourceHandle();
+ if (hFont == (HFONT) NULL)
+ {
+ wxLogDebug(wxT("::SelectObject failed in wxDC::SetFont."));
+ }
+ if (!m_hOldFont)
+ m_hOldFont = (WXHFONT) hFont;
+ }
+} // end of wxDC::SetFont
+
+void wxDC::SetPen(
+ const wxPen& rPen
+)
+{
+ wxCHECK_RET( Ok(), wxT("invalid window dc") );
+
+ if (m_pen == rPen)
+ return;
+ m_pen = rPen;
+ if (!m_pen.Ok())
+ return;
+
+ if (m_hOldPen)
+ m_hOldPen = 0L;
+ m_pen = rPen;
+
+ if (!m_pen.Ok())
+ {
+ if (m_hOldPen)
+ {
+ m_pen.SetPS((HPS)m_hOldPen);
+ }
+ m_hOldPen = 0L;
+ }
+
+ if (m_pen.Ok())
+ {
+ if (m_pen.GetResourceHandle())
+ {
+ m_pen.SetPS(m_hPS);
+ if (!m_hOldPen)
+ m_hOldPen = m_pen.GetPS();
+ }
+ ::GpiSetColor(m_hPS, m_pen.GetColour().GetPixel());
+ }
+}
+
+void wxDC::SetBrush(
+ const wxBrush& rBrush
+)
+{
+ wxCHECK_RET( Ok(), wxT("invalid window dc") );
+
+ if (m_hOldBrush)
+ m_hOldBrush = 0L;
+ m_brush = rBrush;
+ if (!m_brush.Ok())
+ if (m_brush == rBrush)
+ return;
+ if (!m_brush.Ok())
+ if (m_hOldBrush)
+ m_hOldBrush = 0L;
+
+ if (!m_brush.Ok())
+ {
+ if (m_hOldBrush)
+ {
+ m_brush.SetPS((HPS)m_hOldBrush);
+ }
+ m_hOldBrush = 0L;
+ }
+
+ if (m_brush.Ok())
+ {
+ if (m_brush.GetResourceHandle())
+ {
+ m_brush.SetPS(m_hPS);
+ if (!m_hOldBrush)
+ m_hOldBrush = (WXHWND)m_brush.GetPS();
+ }
+ }
+} // end of wxDC::SetBrush
+
+void wxDC::SetBackground(const wxBrush& rBrush)
+{
+ m_backgroundBrush = rBrush;
+
+ if (m_backgroundBrush.Ok())
+ {
+ (void)::GpiSetBackColor((HPS)m_hPS, m_backgroundBrush.GetColour().GetPixel());
+ }
+} // end of wxDC::SetBackground
+
+void wxDC::SetBackgroundMode(int nMode)
+{
+ m_backgroundMode = nMode;
+} // end of wxDC::SetBackgroundMode
+
+void wxDC::SetLogicalFunction(int nFunction)
+{
+ m_logicalFunction = nFunction;
+ SetRop((WXHDC)m_hDC);
+} // wxDC::SetLogicalFunction
+
+void wxDC::SetRop(WXHDC hDC)
+{
+ if (!hDC || m_logicalFunction < 0)
+ return;
+
+ LONG lCRop;
+ switch (m_logicalFunction)
+ {
+ case wxXOR:
+ lCRop = FM_XOR;
+ break;
+
+ case wxINVERT:
+ lCRop = FM_INVERT;
+ break;
+
+ case wxOR_REVERSE:
+ lCRop = FM_MERGESRCNOT;
+ break;
+
+ case wxAND_REVERSE:
+ lCRop = FM_NOTMASKSRC;
+ break;
+
+ case wxCLEAR:
+ lCRop = FM_ONE;
+ break;
+
+ case wxSET:
+ lCRop = FM_ZERO;
+ break;
+
+ case wxSRC_INVERT:
+ lCRop = FM_MERGENOTSRC;
+ break;
+
+ case wxOR_INVERT:
+ lCRop = FM_MERGESRCNOT;
+ break;
+
+ case wxAND:
+ lCRop = FM_AND;
+ break;
+
+ case wxOR:
+ lCRop = FM_OR;
+ break;
+
+ case wxAND_INVERT:
+ lCRop = FM_SUBTRACT;
+ break;
+
+ case wxEQUIV:
+ case wxNAND:
+ case wxCOPY:
+ default:
+ lCRop = FM_OVERPAINT;
+ break;
+ }
+ ::GpiSetMix((HPS)hDC, lCRop);
+} // end of wxDC::SetRop
+
+bool wxDC::StartDoc( const wxString& WXUNUSED(rsMessage) )
+{
+ // We might be previewing, so return true to let it continue.
+ return true;
+} // end of wxDC::StartDoc
+
+void wxDC::EndDoc()
+{
+} // end of wxDC::EndDoc
+
+void wxDC::StartPage()
+{
+} // end of wxDC::StartPage
+
+void wxDC::EndPage()
+{
+} // end of wxDC::EndPage
+
+// ---------------------------------------------------------------------------
+// text metrics
+// ---------------------------------------------------------------------------
+
+wxCoord wxDC::GetCharHeight() const
+{
+ FONTMETRICS vFM; // metrics structure
+
+ ::GpiQueryFontMetrics( m_hPS
+ ,sizeof(FONTMETRICS)
+ ,&vFM
+ );
+ return YDEV2LOGREL(vFM.lXHeight);
+}
+
+wxCoord wxDC::GetCharWidth() const
+{
+ FONTMETRICS vFM; // metrics structure
+
+ ::GpiQueryFontMetrics( m_hPS
+ ,sizeof(FONTMETRICS)
+ ,&vFM
+ );
+ return XDEV2LOGREL(vFM.lAveCharWidth);
+}
+
+void wxDC::DoGetTextExtent(
+ const wxString& rsString
+, wxCoord* pvX
+, wxCoord* pvY
+, wxCoord* pvDescent
+, wxCoord* pvExternalLeading
+, wxFont* pTheFont
+) const
+{
+ POINTL avPoint[TXTBOX_COUNT];
+ POINTL vPtMin;
+ POINTL vPtMax;
+ int i;
+ int l;
+ FONTMETRICS vFM; // metrics structure
+ BOOL bRc;
+ ERRORID vErrorCode; // last error id code
+ wxFont* pFontToUse = (wxFont*)pTheFont;
+
+ wxChar zMsg[128]; // DEBUG
+ wxString sError;
+
+ if (!pFontToUse)
+ pFontToUse = (wxFont*)&m_font;
+ l = rsString.length();
+
+ //
+ // In world coordinates.
+ //
+ bRc = ::GpiQueryTextBox( m_hPS
+ ,l
+ ,(PCH)rsString.c_str()
+ ,TXTBOX_COUNT // return maximum information
+ ,avPoint // array of coordinates points
+ );
+ if(!bRc)
+ {
+ vErrorCode = ::WinGetLastError(wxGetInstance());
+ sError = wxPMErrorToStr(vErrorCode);
+ // DEBUG
+ wxSprintf(zMsg, _T("GpiQueryTextBox for %s: failed with Error: %lx - %s"), rsString.c_str(), vErrorCode, sError.c_str());
+ (void)wxMessageBox( _T("wxWidgets Menu sample")
+ ,zMsg
+ ,wxICON_INFORMATION
+ );
+ }
+
+ vPtMin.x = avPoint[0].x;
+ vPtMax.x = avPoint[0].x;
+ vPtMin.y = avPoint[0].y;
+ vPtMax.y = avPoint[0].y;
+ for (i = 1; i < 4; i++)
+ {
+ if(vPtMin.x > avPoint[i].x) vPtMin.x = avPoint[i].x;
+ if(vPtMin.y > avPoint[i].y) vPtMin.y = avPoint[i].y;
+ if(vPtMax.x < avPoint[i].x) vPtMax.x = avPoint[i].x;
+ if(vPtMax.y < avPoint[i].y) vPtMax.y = avPoint[i].y;
+ }
+ ::GpiQueryFontMetrics( m_hPS
+ ,sizeof(FONTMETRICS)
+ ,&vFM
+ );
+
+ if (pvX)
+ *pvX = (wxCoord)(vPtMax.x - vPtMin.x + 1);
+ if (pvY)
+ *pvY = (wxCoord)(vPtMax.y - vPtMin.y + 1);
+ if (pvDescent)
+ *pvDescent = vFM.lMaxDescender;
+ if (pvExternalLeading)
+ *pvExternalLeading = vFM.lExternalLeading;
+}
+
+void wxDC::SetMapMode(
+ int nMode
+)
+{
+ int nPixelWidth = 0;
+ int nPixelHeight = 0;
+ int nMmWidth = 1;
+ int nMmHeight = 1;
+ LONG lArray[CAPS_VERTICAL_RESOLUTION];
+
+ m_mappingMode = nMode;
+
+ if(::DevQueryCaps( m_hDC
+ ,CAPS_FAMILY
+ ,CAPS_VERTICAL_RESOLUTION
+ ,lArray
+ ))
+ {
+ LONG lHorzRes;
+ LONG lVertRes;
+
+ nPixelWidth = lArray[CAPS_WIDTH];
+ nPixelHeight = lArray[CAPS_HEIGHT];
+ lHorzRes = lArray[CAPS_HORIZONTAL_RESOLUTION]; // returns pel/meter
+ lVertRes = lArray[CAPS_VERTICAL_RESOLUTION]; // returns pel/meter
+ nMmWidth = (lHorzRes/1000) * nPixelWidth;
+ nMmWidth = (lVertRes/1000) * nPixelHeight;
+ }
+ if ((nPixelWidth == 0) || (nPixelHeight == 0) || (nMmWidth == 0) || (nMmHeight == 0))
+ {
+ return;
+ }
+
+ double dMm2pixelsX = nPixelWidth/nMmWidth;
+ double dMm2pixelsY = nPixelHeight/nMmHeight;
+
+ switch (nMode)
+ {
+ case wxMM_TWIPS:
+ m_logicalScaleX = (twips2mm * dMm2pixelsX);
+ m_logicalScaleY = (twips2mm * dMm2pixelsY);
+ break;
+
+ case wxMM_POINTS:
+ m_logicalScaleX = (pt2mm * dMm2pixelsX);
+ m_logicalScaleY = (pt2mm * dMm2pixelsY);
+ break;
+
+ case wxMM_METRIC:
+ m_logicalScaleX = dMm2pixelsX;
+ m_logicalScaleY = dMm2pixelsY;
+ break;
+
+ case wxMM_LOMETRIC:
+ m_logicalScaleX = (dMm2pixelsX/10.0);
+ m_logicalScaleY = (dMm2pixelsY/10.0);
+ break;
+
+ case wxMM_TEXT:
+ default:
+ m_logicalScaleX = 1.0;
+ m_logicalScaleY = 1.0;
+ break;
+ }
+ SIZEL vSize;
+ ULONG ulOptions;
+
+ ulOptions = ::GpiQueryPS(m_hPS, &vSize);
+ if (!ulOptions & PU_ARBITRARY)
+ {
+ ulOptions = PU_ARBITRARY | GPIF_DEFAULT;
+ ::GpiSetPS(m_hPS, &vSize, ulOptions);
+ }
+ m_nWindowExtX = (int)MS_XDEV2LOG(VIEWPORT_EXTENT);
+ m_nWindowExtY = (int)MS_YDEV2LOG(VIEWPORT_EXTENT);
+ // ????
+}; // end of wxDC::SetMapMode
+
+void wxDC::SetUserScale( double dX,
+ double dY )