1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  16     #include "wx/window.h" 
  19     #include "wx/dialog.h" 
  21     #include "wx/bitmap.h" 
  22     #include "wx/dcmemory.h" 
  27 #include "wx/dcprint.h" 
  32 #include "wx/os2/private.h" 
  34     IMPLEMENT_ABSTRACT_CLASS(wxDC
, wxObject
) 
  36 // --------------------------------------------------------------------------- 
  38 // --------------------------------------------------------------------------- 
  40 static const int VIEWPORT_EXTENT 
= 1000; 
  42 static const int MM_POINTS 
= 9; 
  43 static const int MM_METRIC 
= 10; 
  45 // usually this is defined in math.h 
  47     static const double M_PI 
= 3.14159265358979323846; 
  50 // --------------------------------------------------------------------------- 
  52 // --------------------------------------------------------------------------- 
  54 // convert degrees to radians 
  55 static inline double DegToRad(double deg
) { return (deg 
* M_PI
) / 180.0; } 
  59 , int                               nForegroundColour
 
  64     vCbnd
.lColor 
=  nForegroundColour
; 
  65     ::GpiSetAttrs( hPS       
// presentation-space handle 
  66                   ,PRIM_CHAR 
// Char primitive. 
  67                   ,CBB_COLOR 
// sets color. 
  69                   ,&vCbnd    
// buffer for attributes. 
  80     ::GpiQueryAttrs( hPS            
// presentation-space handle 
  81                     ,PRIM_CHAR      
// Char primitive. 
  82                     ,CBB_BACK_COLOR 
// Background color. 
  83                     ,&vCbnd         
// buffer for attributes. 
  85     return vCbnd
.lBackColor
; 
  91 , int                               nBackgroundColour
 
  97     rc 
=  QueryTextBkColor(hPS
); 
  99     vCbnd
.lBackColor 
= nBackgroundColour
; 
 100     ::GpiSetAttrs(hPS
,            // presentation-space handle 
 101                   PRIM_CHAR
,      // Char primitive. 
 102                   CBB_BACK_COLOR
, // sets color. 
 104                   &vCbnd          
// buffer for attributes. 
 111 , int                               nBackgroundMode
 
 114     if(nBackgroundMode 
== wxTRANSPARENT
) 
 119         // the background of the primitive takes  over whatever is underneath. 
 126 // =========================================================================== 
 128 // =========================================================================== 
 130 // --------------------------------------------------------------------------- 
 132 // --------------------------------------------------------------------------- 
 149     m_bIsPaintTime 
= FALSE
; // True at Paint Time 
 150     m_brush
.GetColour().Set("WHITE"); 
 157 // This will select current objects out of the DC, 
 158 // which is what you have to do before deleting the 
 160 void wxDC::SelectOldObjects(WXHDC dc
) 
 166 //            ::SelectObject((HDC) dc, (HBITMAP) m_oldBitmap); 
 167             if (m_vSelectedBitmap
.Ok()) 
 169                 m_vSelectedBitmap
.SetSelectedInto(NULL
); 
 175 //            ::SelectObject((HDC) dc, (HPEN) m_oldPen); 
 180 //            ::SelectObject((HDC) dc, (HBRUSH) m_oldBrush); 
 185 //            ::SelectObject((HDC) dc, (HFONT) m_oldFont); 
 190 //            ::SelectPalette((HDC) dc, (HPALETTE) m_oldPalette, TRUE); 
 195     m_brush           
= wxNullBrush
; 
 197     m_palette         
= wxNullPalette
; 
 199     m_backgroundBrush 
= wxNullBrush
; 
 200     m_vSelectedBitmap 
= wxNullBitmap
; 
 203 // --------------------------------------------------------------------------- 
 205 // --------------------------------------------------------------------------- 
 207 #define DO_SET_CLIPPING_BOX()                    \ 
 211     ::GpiQueryClipBox(m_hPS, &rect);             \ 
 213     m_clipX1 = (wxCoord) XDEV2LOG(rect.xLeft);   \ 
 214     m_clipY1 = (wxCoord) YDEV2LOG(rect.yTop);    \ 
 215     m_clipX2 = (wxCoord) XDEV2LOG(rect.xRight);  \ 
 216     m_clipY2 = (wxCoord) YDEV2LOG(rect.yBottom); \ 
 219 void wxDC::DoSetClippingRegion( 
 229     vRect
.xLeft   
= XLOG2DEV(x
); 
 230     vRect
.yTop    
= YLOG2DEV(m_vRclPaint
.yTop 
- y
); 
 231     vRect
.xRight  
= XLOG2DEV(x 
+ width
); 
 232     vRect
.yBottom 
= YLOG2DEV(m_vRclPaint
.yTop 
- (y 
+ height
)); 
 233     ::GpiIntersectClipRectangle(m_hPS
, &vRect
); 
 234     DO_SET_CLIPPING_BOX() 
 235 } // end of wxDC::DoSetClippingRegion 
 237 void wxDC::DoSetClippingRegionAsRegion( 
 238   const wxRegion
&                   rRegion
 
 241      wxCHECK_RET(rRegion
.GetHRGN(), wxT("invalid clipping region")); 
 245      ::GpiSetClipRegion( m_hPS
 
 246                         ,(HRGN
)rRegion
.GetHRGN() 
 249     DO_SET_CLIPPING_BOX() 
 250 } // end of wxDC::DoSetClippingRegionAsRegion 
 252 void wxDC::DestroyClippingRegion(void) 
 254     if (m_clipping 
&& m_hPS
) 
 259          // TODO: this should restore the previous clipped region 
 260          //       so that OnPaint processing works correctly, and 
 261          //       the update doesn't get destroyed after the first 
 262          //       DestroyClippingRegion 
 263          vRect
.xLeft   
= XLOG2DEV(0); 
 264          vRect
.yTop    
= YLOG2DEV(32000); 
 265          vRect
.xRight  
= XLOG2DEV(32000); 
 266          vRect
.yBottom 
= YLOG2DEV(0); 
 268          HRGN                       hRgn 
= ::GpiCreateRegion(m_hPS
, 1, &vRect
); 
 270          ::GpiSetClipRegion(m_hPS
, hRgn
, &hRgnOld
); 
 273 } // end of wxDC::DestroyClippingRegion 
 275 // --------------------------------------------------------------------------- 
 276 // query capabilities 
 277 // --------------------------------------------------------------------------- 
 279 bool wxDC::CanDrawBitmap() const 
 284 bool wxDC::CanGetTextExtent() const 
 286     // What sort of display is it? 
 287     int technology 
= 0; // TODO:  ::GetDeviceCaps(GetHdc(), TECHNOLOGY); 
 289     // TODO: return (technology == DT_RASDISPLAY) || (technology == DT_RASPRINTER); 
 293 int wxDC::GetDepth() const 
 299 // --------------------------------------------------------------------------- 
 301 // --------------------------------------------------------------------------- 
 308 void wxDC::DoFloodFill( 
 311 , const wxColour
&                   rCol
 
 319     vPtlPos
.x 
= vX
;             // Loads x-coordinate 
 320     vPtlPos
.y 
= vY
;             // Loads y-coordinate 
 321     ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position 
 322     lColor 
= rCol
.GetPixel(); 
 323     lOptions 
= FF_BOUNDARY
; 
 324     if(wxFLOOD_SURFACE 
== nStyle
) 
 325         lOptions 
= FF_SURFACE
; 
 327     ::GpiFloodFill(m_hPS
, lOptions
, lColor
); 
 330 bool wxDC::DoGetPixel( 
 341     lColor 
= ::GpiSetPel(m_hPS
, &vPoint
); 
 342     pCol
->Set((unsigned long)lColor
); 
 349 void wxDC::DoCrossHair(wxCoord x
, wxCoord y
) 
 354 void wxDC::DoDrawLine( 
 364     vPoint
[0].y 
= m_vRclPaint
.yTop 
- vY1
; 
 366     vPoint
[1].y 
= m_vRclPaint
.yTop 
- vY2
; 
 367     ::GpiMove(m_hPS
, &vPoint
[0]); 
 368     ::GpiLine(m_hPS
, &vPoint
[1]); 
 371 ////////////////////////////////////////////////////////////////////////////// 
 372 // Draws an arc of a circle, centred on (xc, yc), with starting point (x1, y1) 
 373 // and ending at (x2, y2). The current pen is used for the outline and the 
 374 // current brush for filling the shape. The arc is drawn in an anticlockwise 
 375 // direction from the start point to the end point. 
 376 ////////////////////////////////////////////////////////////////////////////// 
 377 void wxDC::DoDrawArc( 
 387      POINTL                         vPtlArc
[2]; // Structure for current position 
 396      ARCPARAMS                      vArcp
; // Structure for arc parameters 
 398     if((vX1 
== vXc 
&& vY1 
== vXc
) || (vX2 
== vXc 
&& vY2 
== vXc
)) 
 399         return; // Draw point ?? 
 400     dRadius 
= 0.5 * ( hypot( (double)(vY1 
- vYc
) 
 403                       hypot( (double)(vY2 
- vYc
) 
 408     dAngl1 
= atan2( (double)(vY1 
- vYc
) 
 411     dAngl2 
= atan2( (double)(vY2 
- vYc
) 
 418     // GpiPointArc can't draw full arc 
 420      if(dAngl2 
== dAngl1 
|| (vX1 
== vX2 
&& vY1 
== vY2
) ) 
 425         dAnglmid 
= (dAngl1 
+ dAngl2
)/2. + M_PI
; 
 426         vXm      
= vXc 
+ dRadius 
* cos(dAnglmid
); 
 427         vYm      
= vYc 
+ dRadius 
* sin(dAnglmid
); 
 442     dAnglmid 
= (dAngl1 
+ dAngl2
)/2.; 
 443     vXm      
= vXc 
+ dRadius 
* cos(dAnglmid
); 
 444     vYm      
= vYc 
+ dRadius 
* sin(dAnglmid
); 
 447     // Ellipse main axis (r,q), (p,s) with center at (0,0) */ 
 453     ::GpiSetArcParams(m_hPS
, &vArcp
); // Sets parameters to default 
 455     vPtlPos
.x 
= vX1
; // Loads x-coordinate 
 456     vPtlPos
.y 
= vY1
; // Loads y-coordinate 
 457     ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position 
 462     ::GpiPointArc(m_hPS
, vPtlArc
); // Draws the arc 
 465 void wxDC::DoDrawCheckMark( 
 476     vPoint
[1].x 
= vX1 
+ vWidth
; 
 477     vPoint
[1].y 
= vY1 
+ vHeight
; 
 479     ::GpiMove(m_hPS
, &vPoint
[0]); 
 480     ::GpiBox( m_hPS       
// handle to a presentation space 
 481              ,DRO_OUTLINE 
// draw the box outline ? or ? 
 482              ,&vPoint
[1]  // address of the corner 
 483              ,0L          // horizontal corner radius 
 484              ,0L          // vertical corner radius 
 486     if(vWidth 
> 4 && vHeight 
> 4) 
 490         vPoint
[0].x 
+= 2; vPoint
[0].y 
+= 2; 
 491         vPoint
[1].x 
-= 2; vPoint
[1].y 
-= 2; 
 492         ::GpiMove(m_hPS
, &vPoint
[0]); 
 493         ::GpiLine(m_hPS
, &vPoint
[1]); 
 495         vPoint
[0].x 
= vPoint
[1].x
; 
 497         ::GpiMove(m_hPS
, &vPoint
[0]); 
 498         ::GpiLine(m_hPS
, &vPoint
[1]); 
 502 void wxDC::DoDrawPoint( 
 510     vPoint
.y 
= m_vRclPaint
.yTop 
- vY
; 
 511     ::GpiSetPel(m_hPS
, &vPoint
); 
 514 void wxDC::DoDrawPolygon( 
 522     ULONG                           ulCount 
= 1;    // Number of polygons. 
 523     POLYGON                         vPlgn
;          // polygon. 
 524     ULONG                           flOptions 
= 0L; // Drawing options. 
 526 ////////////////////////////////////////////////////////////////////////////// 
 527 // This contains fields of option bits... to draw boundary lines as well as 
 528 // the area interior. 
 530 // Drawing boundary lines: 
 531 //   POLYGON_NOBOUNDARY              Does not draw boundary lines. 
 532 //   POLYGON_BOUNDARY                Draws boundary lines (the default). 
 534 // Construction of the area interior: 
 535 //   POLYGON_ALTERNATE               Constructs interior in alternate mode 
 537 //   POLYGON_WINDING                 Constructs interior in winding mode. 
 538 ////////////////////////////////////////////////////////////////////////////// 
 540     ULONG                           flModel 
= 0L; // Drawing model. 
 542 ////////////////////////////////////////////////////////////////////////////// 
 544 //   POLYGON_INCL  Fill is inclusive of bottom right (the default). 
 545 //   POLYGON_EXCL  Fill is exclusive of bottom right. 
 546 //       This is provided to aid migration from other graphics models. 
 547 ////////////////////////////////////////////////////////////////////////////// 
 549     LONG                            lHits 
= 0L; // Correlation/error indicator. 
 552     int                             nIsTRANSPARENT 
= 0; 
 553     LONG                            lBorderColor 
= 0L; 
 556     lBorderColor 
= m_pen
.GetColour().GetPixel(); 
 557     lColor       
= m_brush
.GetColour().GetPixel(); 
 558     if(m_brush
.GetStyle() == wxTRANSPARENT
) 
 562     vPlgn
.aPointl 
= (POINTL
*) calloc( n 
+ 1 
 564                                     ); // well, new will call malloc 
 566     for(i 
= 0; i 
< n
; i
++) 
 568         vPlgn
.aPointl
[i
].x 
= vPoints
[i
].x
; // +xoffset; 
 569         vPlgn
.aPointl
[i
].y 
= vPoints
[i
].y
; // +yoffset; 
 571     flModel 
= POLYGON_BOUNDARY
; 
 572     if(nFillStyle 
== wxWINDING_RULE
) 
 573         flModel 
|= POLYGON_WINDING
; 
 575         flModel 
|= POLYGON_ALTERNATE
; 
 580     ::GpiSetColor(m_hPS
, lBorderColor
); 
 581     ::GpiMove(m_hPS
, &vPoint
); 
 582     lHits 
= ::GpiPolygons(m_hPS
, ulCount
, &vPlgn
, flOptions
, flModel
); 
 586 void wxDC::DoDrawLines( 
 596     vPoint
.x 
= vPoints
[0].x 
+ vXoffset
; 
 597     vPoint
.y 
= vPoints
[0].y 
+ vYoffset
; 
 598     ::GpiMove(m_hPS
, &vPoint
); 
 600     LONG                            lBorderColor 
= m_pen
.GetColour().GetPixel(); 
 602     ::GpiSetColor(m_hPS
, lBorderColor
); 
 603     for(i 
= 1; i 
< n
; i
++) 
 605         vPoint
.x 
= vPoints
[0].x 
+ vXoffset
; 
 606         vPoint
.y 
= vPoints
[0].y 
+ vYoffset
; 
 607         ::GpiLine(m_hPS
, &vPoint
); 
 611 void wxDC::DoDrawRectangle( 
 622     int                             nIsTRANSPARENT 
= 0; 
 625     vPoint
[0].y 
= m_vRclPaint
.yTop 
- (vY 
+ vHeight
); 
 626     vPoint
[1].x 
= vX 
+ vWidth
; 
 627     vPoint
[1].y 
= m_vRclPaint
.yTop 
- vY
; 
 628     ::GpiMove(m_hPS
, &vPoint
[0]); 
 629     lColor       
= m_brush
.GetColour().GetPixel(); 
 630     lBorderColor 
= m_pen
.GetColour().GetPixel(); 
 631     if (m_brush
.GetStyle() == wxTRANSPARENT
) 
 633     if(lColor 
== lBorderColor 
|| nIsTRANSPARENT
) 
 635         lControl 
= DRO_OUTLINEFILL
; //DRO_FILL; 
 636         if(m_brush
.GetStyle() == wxTRANSPARENT
) 
 637             lControl 
= DRO_OUTLINE
; 
 639         ::GpiSetColor(m_hPS
, lColor
); 
 640         ::GpiBox( m_hPS       
// handle to a presentation space 
 641                  ,lControl   
// draw the box outline ? or ? 
 642                  ,&vPoint
[1]  // address of the corner 
 643                  ,0L          // horizontal corner radius 
 644                  ,0L          // vertical corner radius 
 649         lControl 
= DRO_OUTLINE
; 
 663         vPoint
[0].x 
= vX 
+ 1; 
 664         vPoint
[0].y 
= m_vRclPaint
.yTop 
- (vY 
+ vHeight
) + 1; 
 665         vPoint
[1].x 
= vX 
+ vWidth 
- 2; 
 666         vPoint
[1].y 
= m_vRclPaint
.yTop 
- (vY 
+ 2); 
 667         ::GpiMove(m_hPS
, &vPoint
[0]); 
 677 void wxDC::DoDrawRoundedRectangle( 
 689     vPoint
[0].y 
= YLOG2DEV(vY
) - vHeight
; 
 690     vPoint
[1].x 
= vX 
+ vWidth
; 
 692     ::GpiMove(m_hPS
, &vPoint
[0]); 
 694     lControl 
= DRO_OUTLINEFILL
; //DRO_FILL; 
 695     if (m_brush
.GetStyle() == wxTRANSPARENT
) 
 696         lControl 
= DRO_OUTLINE
; 
 697     ::GpiBox( m_hPS         
// handle to a presentation space 
 698              ,DRO_OUTLINE   
// draw the box outline ? or ? 
 699              ,&vPoint
[1]    // address of the corner 
 700              ,(LONG
)dRadius 
// horizontal corner radius 
 701              ,(LONG
)dRadius 
// vertical corner radius 
 705 // Draw Ellipse within box (x,y) - (x+width, y+height) 
 706 void wxDC::DoDrawEllipse( 
 713     POINTL                          vPtlPos
; // Structure for current position 
 714     FIXED                           vFxMult
; // Multiplier for ellipse 
 715     ARCPARAMS                       vArcp
;   // Structure for arc parameters 
 718     vArcp
.lQ 
= vHeight
/2; 
 721     ::GpiSetArcParams( m_hPS
 
 723                      ); // Sets parameters to default 
 724     vPtlPos
.x 
= vX 
+ vWidth
/2;  // Loads x-coordinate 
 725     vPtlPos
.y 
= vY 
+ vHeight
/2; // Loads y-coordinate 
 728              ); // Sets current position 
 729     vFxMult 
= MAKEFIXED(1, 0);             /* Sets multiplier            */ 
 732     // DRO_FILL, DRO_OTLINEFILL - where to get 
 737                 ); // Draws full arc with center at current position 
 740 void wxDC::DoDrawEllipticArc( 
 749     POINTL                          vPtlPos
; // Structure for current position 
 750     FIXED                           vFxMult
; // Multiplier for ellipse 
 751     ARCPARAMS                       vArcp
;   // Structure for arc parameters 
 753     FIXED                           vFSweepa
; // Start angle, sweep angle 
 758     dFractPart 
= modf(dSa
,&dIntPart
); 
 759     vFSa 
= MAKEFIXED((int)dIntPart
, (int)(dFractPart 
* 0xffff) ); 
 760     dFractPart 
= modf(dEa 
- dSa
, &dIntPart
); 
 761     vFSweepa 
= MAKEFIXED((int)dIntPart
, (int)(dFractPart 
* 0xffff) ); 
 764     // Ellipse main axis (r,q), (p,s) with center at (0,0) 
 767     vArcp
.lQ 
= vHeight
/2; 
 770     ::GpiSetArcParams(m_hPS
, &vArcp
); // Sets parameters to default 
 771     vPtlPos
.x 
= vX 
+ vWidth
/2  * (1. + cos(DegToRad(dSa
))); // Loads x-coordinate 
 772     vPtlPos
.y 
= vY 
+ vHeight
/2 * (1. + sin(DegToRad(dSa
))); // Loads y-coordinate 
 773     ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position 
 776     // May be not to the center ? 
 778     vPtlPos
.x 
= vX 
+ vWidth
/2 ; // Loads x-coordinate 
 779     vPtlPos
.y 
= vY 
+ vHeight
/2; // Loads y-coordinate 
 780     vFxMult 
= MAKEFIXED(1, 0);  // Sets multiplier 
 783     // DRO_FILL, DRO_OTLINEFILL - where to get 
 785     ::GpiPartialArc( m_hPS
 
 793 void wxDC::DoDrawIcon(const wxIcon
& icon
, wxCoord x
, wxCoord y
) 
 798 void wxDC::DoDrawBitmap( const wxBitmap 
&bmp
 
 799                         ,wxCoord x
, wxCoord y
 
 806 void wxDC::DoDrawText( 
 807   const wxString
&                   rsText
 
 818 void wxDC::DrawAnyText( 
 819   const wxString
&                   rsText
 
 824     int                             nOldBackground 
= 0; 
 829     // prepare for drawing the text 
 833     // Set text color attributes 
 835     if (m_textForegroundColour
.Ok()) 
 838                      ,(int)m_textForegroundColour
.GetPixel() 
 842     if (m_textBackgroundColour
.Ok()) 
 844         nOldBackground 
= SetTextBkColor( m_hPS
 
 845                                         ,(int)m_textBackgroundColour
.GetPixel() 
 854     lHits 
= ::GpiCharStringAt( m_hPS
 
 861         wxLogLastError(wxT("TextOut")); 
 865     // Restore the old parameters (text foreground colour may be left because 
 866     // it never is set to anything else, but background should remain 
 867     // transparent even if we just drew an opaque string) 
 869     if (m_textBackgroundColour
.Ok()) 
 870             SetTextBkColor( m_hPS
 
 878 void wxDC::DoDrawRotatedText( 
 879   const wxString
&                   rsText
 
 897         DoDrawText(text, x, y); 
 902         wxFillLogFont(&lf, &m_font); 
 904         // GDI wants the angle in tenth of degree 
 905         long angle10 = (long)(angle * 10); 
 906         lf.lfEscapement = angle10; 
 907         lf. lfOrientation = angle10; 
 909         HFONT hfont = ::CreateFontIndirect(&lf); 
 912             wxLogLastError("CreateFont"); 
 916             HFONT hfontOld = ::SelectObject(GetHdc(), hfont); 
 918             DrawAnyText(text, x, y); 
 920             (void)::SelectObject(GetHdc(), hfontOld); 
 923         // call the bounding box by adding all four vertices of the rectangle 
 924         // containing the text to it (simpler and probably not slower than 
 925         // determining which of them is really topmost/leftmost/...) 
 927         GetTextExtent(text, &w, &h); 
 929         double rad = DegToRad(angle); 
 931         // "upper left" and "upper right" 
 932         CalcBoundingBox(x, y); 
 933         CalcBoundingBox(x + w*cos(rad), y - h*sin(rad)); 
 934         CalcBoundingBox(x + h*sin(rad), y + h*cos(rad)); 
 936         // "bottom left" and "bottom right" 
 937         x += (wxCoord)(h*sin(rad)); 
 938         y += (wxCoord)(h*cos(rad)); 
 939         CalcBoundingBox(x, y); 
 940         CalcBoundingBox(x + h*sin(rad), y + h*cos(rad)); 
 945 // --------------------------------------------------------------------------- 
 947 // --------------------------------------------------------------------------- 
 949 void wxDC::SetPalette(const wxPalette
& palette
) 
 959     // Set the old object temporarily, in case the assignment deletes an object 
 960     // that's not yet selected out. 
 972     m_font
.SetPS(m_hPS
); // this will realize the font 
 976         HFONT                       hFont 
= m_font
.GetResourceHandle(); 
 977         if (hFont 
== (HFONT
) NULL
) 
 979             wxLogDebug(wxT("::SelectObject failed in wxDC::SetFont.")); 
 982             m_hOldFont 
= (WXHFONT
) hFont
; 
 984 } // end of wxDC::SetFont 
 990     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1006             m_pen
.SetPS((HPS
)m_hOldPen
); 
1013         if (m_pen
.GetResourceHandle()) 
1017                 m_hOldPen 
= m_pen
.GetPS(); 
1022 void wxDC::SetBrush( 
1023   const wxBrush
&                    rBrush
 
1026     wxCHECK_RET( Ok(), wxT("invalid window dc") ); 
1028     if (m_brush 
== rBrush
) 
1042             m_brush
.SetPS((HPS
)m_hOldBrush
); 
1049         if (m_brush
.GetResourceHandle()) 
1051             m_brush
.SetPS(m_hPS
); 
1053                 m_hOldBrush 
= m_brush
.GetPS(); 
1056 } // end of wxDC::SetBrush 
1058 void wxDC::SetBackground(const wxBrush
& brush
) 
1063 void wxDC::SetBackgroundMode( 
1067     m_backgroundMode 
= nMode
; 
1070 void wxDC::SetLogicalFunction(int function
) 
1075 void wxDC::SetRop(WXHDC dc
) 
1077     if (!dc 
|| m_logicalFunction 
< 0) 
1081     // These may be wrong 
1082     switch (m_logicalFunction
) 
1084 // TODO: Figure this stuff out 
1085         //    case wxXOR: c_rop = R2_XORPEN; break; 
1086 //    case wxXOR: c_rop = R2_NOTXORPEN; break; 
1087 //    case wxINVERT: c_rop = R2_NOT; break; 
1088 //    case wxOR_REVERSE: c_rop = R2_MERGEPENNOT; break; 
1089 //    case wxAND_REVERSE: c_rop = R2_MASKPENNOT; break; 
1090 //    case wxCLEAR: c_rop = R2_WHITE; break; 
1091 //    case wxSET: c_rop = R2_BLACK; break; 
1092 //    case wxSRC_INVERT: c_rop = R2_NOTCOPYPEN; break; 
1093 //    case wxOR_INVERT: c_rop = R2_MERGENOTPEN; break; 
1094 //    case wxAND: c_rop = R2_MASKPEN; break; 
1095 //    case wxOR: c_rop = R2_MERGEPEN; break; 
1096 //    case wxAND_INVERT: c_rop = R2_MASKNOTPEN; break; 
1101 //      c_rop = R2_COPYPEN; 
1104 //    SetROP2((HDC) dc, c_rop); 
1107 bool wxDC::StartDoc(const wxString
& message
) 
1109     // We might be previewing, so return TRUE to let it continue. 
1117 void wxDC::StartPage() 
1121 void wxDC::EndPage() 
1125 // --------------------------------------------------------------------------- 
1127 // --------------------------------------------------------------------------- 
1129 wxCoord 
wxDC::GetCharHeight() const 
1131     FONTMETRICS                     vFM
; // metrics structure 
1133     ::GpiQueryFontMetrics( m_hPS
 
1134                           ,sizeof(FONTMETRICS
) 
1137     return YDEV2LOGREL(vFM
.lXHeight
); 
1140 wxCoord 
wxDC::GetCharWidth() const 
1142     FONTMETRICS                     vFM
; // metrics structure 
1144     ::GpiQueryFontMetrics( m_hPS
 
1145                           ,sizeof(FONTMETRICS
) 
1148     return XDEV2LOGREL(vFM
.lAveCharWidth
); 
1151 void wxDC::DoGetTextExtent( 
1152   const wxString
&                   rsString
 
1155 , wxCoord
*                          pvDescent
 
1156 , wxCoord
*                          pvExternalLeading
 
1160     POINTL                          avPoint
[TXTBOX_COUNT
]; 
1165     FONTMETRICS                     vFM
; // metrics structure 
1168     ERRORID                         vErrorCode
; // last error id code 
1169     wxFont
*                         pFontToUse 
= (wxFont
*)pTheFont
; 
1171     char                            zMsg
[128]; // DEBUG 
1175         pFontToUse 
= (wxFont
*)&m_font
; 
1176     l 
= rsString
.length(); 
1177     pStr 
= (PCH
) rsString
.c_str(); 
1180     // In world coordinates. 
1182     bRc 
= ::GpiQueryTextBox( m_hPS
 
1185                             ,TXTBOX_COUNT 
// return maximum information 
1186                             ,avPoint      
// array of coordinates points 
1190        vErrorCode 
= ::WinGetLastError(wxGetInstance()); 
1191        sError 
= wxPMErrorToStr(vErrorCode
); 
1193        sprintf(zMsg
, "GpiQueryTextBox for %s: failed with Error: %x - %s", pStr
, vErrorCode
, sError
.c_str()); 
1194        (void)wxMessageBox( "wxWindows Menu sample" 
1200     vPtMin
.x 
= avPoint
[0].x
; 
1201     vPtMax
.x 
= avPoint
[0].x
; 
1202     vPtMin
.y 
= avPoint
[0].y
; 
1203     vPtMax
.y 
= avPoint
[0].y
; 
1204     for (i 
= 1; i 
< 4; i
++) 
1206         if(vPtMin
.x 
> avPoint
[i
].x
) vPtMin
.x 
= avPoint
[i
].x
; 
1207         if(vPtMin
.y 
> avPoint
[i
].y
) vPtMin
.y 
= avPoint
[i
].y
; 
1208         if(vPtMax
.x 
< avPoint
[i
].x
) vPtMax
.x 
= avPoint
[i
].x
; 
1209         if(vPtMax
.y 
< avPoint
[i
].y
) vPtMax
.y 
= avPoint
[i
].y
; 
1211     ::GpiQueryFontMetrics( m_hPS
 
1212                           ,sizeof(FONTMETRICS
) 
1217         *pvX 
= (wxCoord
)(vPtMax
.x 
- vPtMin
.x 
+ 1); 
1219         *pvY 
= (wxCoord
)(vPtMax
.y 
- vPtMin
.y 
+ 1); 
1221         *pvDescent 
= vFM
.lMaxDescender
; 
1222     if (pvExternalLeading
) 
1223         *pvExternalLeading 
= vFM
.lExternalLeading
; 
1226 void wxDC::SetMapMode( int mode 
) 
1231 void wxDC::SetUserScale(double x
, double y
) 
1236     SetMapMode(m_mappingMode
); 
1239 void wxDC::SetAxisOrientation(bool xLeftRight
, bool yBottomUp
) 
1241     m_signX 
= xLeftRight 
? 1 : -1; 
1242     m_signY 
= yBottomUp 
? -1 : 1; 
1244     SetMapMode(m_mappingMode
); 
1247 void wxDC::SetSystemScale(double x
, double y
) 
1252     SetMapMode(m_mappingMode
); 
1255 void wxDC::SetLogicalOrigin( wxCoord x
, wxCoord y 
) 
1260 void wxDC::SetDeviceOrigin( 
1267     m_deviceOriginX 
= x
; 
1268     m_deviceOriginY 
= y
; 
1269     ::GpiQueryPageViewport( m_hPS
 
1276     ::GpiSetPageViewport( m_hPS
 
1281 // --------------------------------------------------------------------------- 
1282 // coordinates transformations 
1283 // --------------------------------------------------------------------------- 
1285 wxCoord 
wxDCBase::DeviceToLogicalX(wxCoord x
) const 
1287     return (wxCoord
) (((x
) - m_deviceOriginX
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
) - m_logicalOriginX
); 
1290 wxCoord 
wxDCBase::DeviceToLogicalXRel(wxCoord x
) const 
1292     return (wxCoord
) ((x
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
)); 
1295 wxCoord 
wxDCBase::DeviceToLogicalY(wxCoord y
) const 
1297     return (wxCoord
) (((y
) - m_deviceOriginY
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
) - m_logicalOriginY
); 
1300 wxCoord 
wxDCBase::DeviceToLogicalYRel(wxCoord y
) const 
1302     return (wxCoord
) ((y
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
)); 
1305 wxCoord 
wxDCBase::LogicalToDeviceX(wxCoord x
) const 
1307     return (wxCoord
) ((x 
- m_logicalOriginX
)*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX 
+ m_deviceOriginX
); 
1310 wxCoord 
wxDCBase::LogicalToDeviceXRel(wxCoord x
) const 
1312     return (wxCoord
) (x
*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
); 
1315 wxCoord 
wxDCBase::LogicalToDeviceY(wxCoord y
) const 
1317     return (wxCoord
) ((y 
- m_logicalOriginY
)*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY 
+ m_deviceOriginY
); 
1320 wxCoord 
wxDCBase::LogicalToDeviceYRel(wxCoord y
) const 
1322     return (wxCoord
) (y
*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
); 
1325 // --------------------------------------------------------------------------- 
1327 // --------------------------------------------------------------------------- 
1341     wxMask
*                         pMask 
= NULL
; 
1343     COLORREF                        vOldTextColor
; 
1344     COLORREF                        vOldBackground 
= ::GpiQueryBackColor(m_hPS
); 
1348         const wxBitmap
&             rBmp 
= pSource
->m_vSelectedBitmap
; 
1350         pMask 
= rBmp
.GetMask(); 
1351         if (!(rBmp
.Ok() && pMask 
&& pMask
->GetMaskBitmap())) 
1357     ::GpiQueryAttrs( m_hPS
 
1362     vOldTextColor 
= (COLORREF
)vCbnd
.lColor
; 
1364     if (m_textForegroundColour
.Ok()) 
1366         vCbnd
.lColor 
= (LONG
)m_textForegroundColour
.GetPixel(); 
1367         ::GpiSetAttrs( m_hPS           
// presentation-space handle 
1368                       ,PRIM_CHAR       
// Char primitive. 
1369                       ,CBB_COLOR       
// sets color. 
1371                       ,&vCbnd          
// buffer for attributes. 
1374     if (m_textBackgroundColour
.Ok()) 
1376         ::GpiSetBackColor(m_hPS
, (LONG
)m_textBackgroundColour
.GetPixel()); 
1379     LONG                            lRop 
= ROP_SRCCOPY
; 
1383         case wxXOR
:          lRop 
= ROP_SRCINVERT
;        break; 
1384         case wxINVERT
:       lRop 
= ROP_DSTINVERT
;        break; 
1385         case wxOR_REVERSE
:   lRop 
= 0x00DD0228;           break; 
1386         case wxAND_REVERSE
:  lRop 
= ROP_SRCERASE
;         break; 
1387         case wxCLEAR
:        lRop 
= ROP_ZERO
;             break; 
1388         case wxSET
:          lRop 
= ROP_ONE
;              break; 
1389         case wxOR_INVERT
:    lRop 
= ROP_MERGEPAINT
;       break; 
1390         case wxAND
:          lRop 
= ROP_SRCAND
;           break; 
1391         case wxOR
:           lRop 
= ROP_SRCPAINT
;         break; 
1392         case wxEQUIV
:        lRop 
= 0x00990066;           break; 
1393         case wxNAND
:         lRop 
= 0x007700E6;           break; 
1394         case wxAND_INVERT
:   lRop 
= 0x00220326;           break; 
1395         case wxCOPY
:         lRop 
= ROP_SRCCOPY
;          break; 
1396         case wxNO_OP
:        lRop 
= ROP_NOTSRCERASE
;      break; 
1397         case wxSRC_INVERT
:   lRop 
= ROP_SRCINVERT
;        break; 
1398         case wxNOR
:          lRop 
= ROP_NOTSRCCOPY
;       break; 
1400            wxFAIL_MSG( wxT("unsupported logical function") ); 
1409         // Blit bitmap with mask 
1413         // Create a temp buffer bitmap and DCs/PSs to access it and the mask 
1419         DEVOPENSTRUC                    vDOP 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1420         BITMAPINFOHEADER2               vBmpHdr
; 
1421         SIZEL                           vSize 
= {0, 0}; 
1424         hDCMask 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDOP
, NULLHANDLE
); 
1425         hDCBuffer 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDOP
, NULLHANDLE
); 
1426         hPSMask 
= ::GpiCreatePS(vHabmain
, hDCMask
, &vSize
, PU_PELS 
| GPIT_MICRO 
| GPIA_ASSOC
); 
1427         hPSBuffer 
= ::GpiCreatePS(vHabmain
, hDCBuffer
, &vSize
, PU_PELS 
| GPIT_MICRO 
| GPIA_ASSOC
); 
1429         memset(&vBmpHdr
, 0, sizeof(BITMAPINFOHEADER2
)); 
1430         vBmpHdr
.cbFix     
= sizeof(BITMAPINFOHEADER2
); 
1431         vBmpHdr
.cx        
= vWidth
; 
1432         vBmpHdr
.cy        
= vHeight
; 
1433         vBmpHdr
.cPlanes   
= 1; 
1434         vBmpHdr
.cBitCount 
= 24; 
1436         HBITMAP                         hBufBitmap 
= ::GpiCreateBitmap(GetHPS(), &vBmpHdr
, 0L, NULL
, NULL
); 
1437         POINTL                          aPoint1
[4] = { 0, 0 
1440                                                       ,vXdest 
+ vWidth
, vYdest 
+ vHeight
 
1442         POINTL                          aPoint2
[4] = { 0, 0 
1445                                                       ,vXsrc 
+ vWidth
, vYsrc 
+ vHeight
 
1447         POINTL                          aPoint3
[4] = { vXdest
, vYdest
 
1448                                                       ,vXdest 
+ vWidth
, vYdest 
+ vHeight
 
1450                                                       ,vXsrc 
+ vWidth
, vYsrc 
+ vHeight
 
1452         POINTL                          aPoint4
[4] = { vXdest
, vYdest
 
1453                                                       ,vXdest 
+ vWidth
, vYdest 
+ vHeight
 
1457         ::GpiSetBitmap(hPSMask
, (HBITMAP
) pMask
->GetMaskBitmap()); 
1458         ::GpiSetBitmap(hPSBuffer
, (HBITMAP
) hBufBitmap
); 
1461         // Copy dest to buffer 
1463         rc 
= ::GpiBitBlt( hPSBuffer
 
1470         if (rc 
== GPI_ERROR
) 
1472             wxLogLastError(wxT("BitBlt")); 
1476         // Copy src to buffer using selected raster op 
1478         rc 
= ::GpiBitBlt( hPSBuffer
 
1485         if (rc 
== GPI_ERROR
) 
1487             wxLogLastError(wxT("BitBlt")); 
1491         // Set masked area in buffer to BLACK (pixel value 0) 
1493         COLORREF                        vPrevBkCol 
= ::GpiQueryBackColor(GetHPS()); 
1494         COLORREF                        vPrevCol 
= ::GpiQueryColor(GetHPS()); 
1496         ::GpiSetBackColor(GetHPS(), OS2RGB(255, 255, 255)); 
1497         ::GpiSetColor(GetHPS(), OS2RGB(0, 0, 0)); 
1499         rc 
= ::GpiBitBlt( hPSBuffer
 
1506         if (rc 
== GPI_ERROR
) 
1508             wxLogLastError(wxT("BitBlt")); 
1512         // Set unmasked area in dest to BLACK 
1514         ::GpiSetBackColor(GetHPS(), OS2RGB(0, 0, 0)); 
1515         ::GpiSetColor(GetHPS(), OS2RGB(255, 255, 255)); 
1516         rc 
= ::GpiBitBlt( GetHPS() 
1523         if (rc 
== GPI_ERROR
) 
1525             wxLogLastError(wxT("BitBlt")); 
1529         // Restore colours to original values 
1531         ::GpiSetBackColor(GetHPS(), vPrevBkCol
); 
1532         ::GpiSetColor(GetHPS(), vPrevCol
); 
1535         // OR buffer to dest 
1537         rc 
= ::GpiBitBlt( GetHPS() 
1544         if (rc 
== GPI_ERROR
) 
1547             wxLogLastError(wxT("BitBlt")); 
1551         // Tidy up temporary DCs and bitmap 
1553         ::GpiSetBitmap(hPSMask
, NULLHANDLE
); 
1554         ::GpiSetBitmap(hPSBuffer
, NULLHANDLE
); 
1555         ::GpiDestroyPS(hPSMask
); 
1556         ::GpiDestroyPS(hPSBuffer
); 
1557         ::DevCloseDC(hDCMask
); 
1558         ::DevCloseDC(hDCBuffer
); 
1559         ::GpiDeleteBitmap(hBufBitmap
); 
1562     else // no mask, just BitBlt() it 
1564         POINTL                          aPoint
[4] = { vXdest
, vYdest
 
1565                                                      ,vXdest 
+ vWidth
, vYdest 
+ vHeight
 
1567                                                      ,vXsrc 
+ vWidth
, vYsrc 
+ vHeight
 
1570         bSuccess 
= (::GpiBitBlt( m_hPS
 
1579             wxLogLastError(wxT("BitBlt")); 
1582     vCbnd
.lColor 
= (LONG
)vOldTextColor
; 
1583     ::GpiSetAttrs( m_hPS           
// presentation-space handle 
1584                   ,PRIM_CHAR       
// Char primitive. 
1585                   ,CBB_COLOR       
// sets color. 
1587                   ,&vCbnd          
// buffer for attributes. 
1589     ::GpiSetBackColor(m_hPS
, (LONG
)vOldBackground
); 
1593 void wxDC::DoGetSize( int* width
, int* height 
) const 
1598 void wxDC::DoGetSizeMM( int* width
, int* height 
) const 
1603 wxSize 
wxDC::GetPPI() const 
1608    return (wxSize(x
,y
)); 
1611 void wxDC::SetLogicalScale( double x
, double y 
) 
1616 #if WXWIN_COMPATIBILITY 
1617 void wxDC::DoGetTextExtent(const wxString
& string
, float *x
, float *y
, 
1618                          float *descent
, float *externalLeading
, 
1619                          wxFont 
*theFont
, bool use16bit
) const 
1621     wxCoord x1
, y1
, descent1
, externalLeading1
; 
1622     GetTextExtent(string
, & x1
, & y1
, & descent1
, & externalLeading1
, theFont
, use16bit
); 
1625         *descent 
= descent1
; 
1626     if (externalLeading
) 
1627         *externalLeading 
= externalLeading1
;