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"
25 #include "wx/msgdlg.h"
28 #include "wx/dcprint.h"
33 #include "wx/os2/private.h"
35 IMPLEMENT_ABSTRACT_CLASS(wxDC
, wxObject
)
37 // ---------------------------------------------------------------------------
39 // ---------------------------------------------------------------------------
41 static const int VIEWPORT_EXTENT
= 1000;
43 static const int MM_POINTS
= 9;
44 static const int MM_METRIC
= 10;
46 // usually this is defined in math.h
48 static const double M_PI
= 3.14159265358979323846;
51 // ---------------------------------------------------------------------------
53 // ---------------------------------------------------------------------------
55 // convert degrees to radians
56 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
60 , int nForegroundColour
65 vCbnd
.lColor
= nForegroundColour
;
66 ::GpiSetAttrs( hPS
// presentation-space handle
67 ,PRIM_CHAR
// Char primitive.
68 ,CBB_COLOR
// sets color.
70 ,&vCbnd
// buffer for attributes.
81 ::GpiQueryAttrs( hPS
// presentation-space handle
82 ,PRIM_CHAR
// Char primitive.
83 ,CBB_BACK_COLOR
// Background color.
84 ,&vCbnd
// buffer for attributes.
86 return vCbnd
.lBackColor
;
92 , int nBackgroundColour
98 rc
= QueryTextBkColor(hPS
);
100 vCbnd
.lBackColor
= nBackgroundColour
;
101 ::GpiSetAttrs(hPS
, // presentation-space handle
102 PRIM_CHAR
, // Char primitive.
103 CBB_BACK_COLOR
, // sets color.
105 &vCbnd
// buffer for attributes.
112 , int nBackgroundMode
115 if(nBackgroundMode
== wxTRANSPARENT
)
120 // the background of the primitive takes over whatever is underneath.
127 // ===========================================================================
129 // ===========================================================================
131 // ---------------------------------------------------------------------------
133 // ---------------------------------------------------------------------------
149 m_bIsPaintTime
= FALSE
; // True at Paint Time
150 m_brush
.GetColour().Set("WHITE");
151 } // end of wxDC::wxDC
157 SelectOldObjects(m_hDC
);
159 // if we own the HDC, we delete it, otherwise we just release it
165 ::GpiAssociate(m_hPS
, NULLHANDLE
);
166 ::GpiDestroyPS(m_hPS
);
169 ::DevCloseDC((HDC
)m_hDC
);
174 // Just Dissacociate, not destroy if we don't own the DC
178 ::GpiAssociate(m_hPS
, NULLHANDLE
);
182 } // end of wxDC::~wxDC
184 // This will select current objects out of the DC,
185 // which is what you have to do before deleting the
187 void wxDC::SelectOldObjects(
195 ::GpiSetBitmap(hPS
, (HBITMAP
) m_hOldBitmap
);
196 if (m_vSelectedBitmap
.Ok())
198 m_vSelectedBitmap
.SetSelectedInto(NULL
);
203 // OS/2 has no other native GDI objects to set in a PS/DC like windows
211 m_brush
= wxNullBrush
;
213 m_palette
= wxNullPalette
;
215 m_backgroundBrush
= wxNullBrush
;
216 m_vSelectedBitmap
= wxNullBitmap
;
217 } // end of wxDC::SelectOldObjects
219 // ---------------------------------------------------------------------------
221 // ---------------------------------------------------------------------------
223 #define DO_SET_CLIPPING_BOX() \
227 ::GpiQueryClipBox(m_hPS, &rect); \
229 m_clipX1 = (wxCoord) XDEV2LOG(rect.xLeft); \
230 m_clipY1 = (wxCoord) YDEV2LOG(rect.yTop); \
231 m_clipX2 = (wxCoord) XDEV2LOG(rect.xRight); \
232 m_clipY2 = (wxCoord) YDEV2LOG(rect.yBottom); \
235 void wxDC::DoSetClippingRegion(
245 vRect
.xLeft
= XLOG2DEV(x
);
246 vRect
.yTop
= YLOG2DEV(m_vRclPaint
.yTop
- y
);
247 vRect
.xRight
= XLOG2DEV(x
+ width
);
248 vRect
.yBottom
= YLOG2DEV(m_vRclPaint
.yTop
- (y
+ height
));
249 ::GpiIntersectClipRectangle(m_hPS
, &vRect
);
250 DO_SET_CLIPPING_BOX()
251 } // end of wxDC::DoSetClippingRegion
253 void wxDC::DoSetClippingRegionAsRegion(
254 const wxRegion
& rRegion
257 wxCHECK_RET(rRegion
.GetHRGN(), wxT("invalid clipping region"));
261 ::GpiSetClipRegion( m_hPS
262 ,(HRGN
)rRegion
.GetHRGN()
265 DO_SET_CLIPPING_BOX()
266 } // end of wxDC::DoSetClippingRegionAsRegion
268 void wxDC::DestroyClippingRegion(void)
270 if (m_clipping
&& m_hPS
)
275 // TODO: this should restore the previous clipped region
276 // so that OnPaint processing works correctly, and
277 // the update doesn't get destroyed after the first
278 // DestroyClippingRegion
279 vRect
.xLeft
= XLOG2DEV(0);
280 vRect
.yTop
= YLOG2DEV(32000);
281 vRect
.xRight
= XLOG2DEV(32000);
282 vRect
.yBottom
= YLOG2DEV(0);
284 HRGN hRgn
= ::GpiCreateRegion(m_hPS
, 1, &vRect
);
286 ::GpiSetClipRegion(m_hPS
, hRgn
, &hRgnOld
);
289 } // end of wxDC::DestroyClippingRegion
291 // ---------------------------------------------------------------------------
292 // query capabilities
293 // ---------------------------------------------------------------------------
295 bool wxDC::CanDrawBitmap() const
300 bool wxDC::CanGetTextExtent() const
302 LONG lTechnology
= 0L;
304 ::DevQueryCaps(GetHDC(), CAPS_TECHNOLOGY
, 1L, &lTechnology
);
305 return (lTechnology
== CAPS_TECH_RASTER_DISPLAY
) || (lTechnology
== CAPS_TECH_RASTER_PRINTER
);
306 } // end of wxDC::CanGetTextExtent
308 int wxDC::GetDepth() const
310 LONG lArray
[CAPS_COLOR_BITCOUNT
];
313 if(::DevQueryCaps( GetHDC()
319 nBitsPerPixel
= (int)lArray
[CAPS_COLOR_BITCOUNT
];
321 return nBitsPerPixel
;
322 } // end of wxDC::GetDepth
324 // ---------------------------------------------------------------------------
326 // ---------------------------------------------------------------------------
333 void wxDC::DoFloodFill(
336 , const wxColour
& rCol
344 vPtlPos
.x
= vX
; // Loads x-coordinate
345 vPtlPos
.y
= vY
; // Loads y-coordinate
346 ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position
347 lColor
= rCol
.GetPixel();
348 lOptions
= FF_BOUNDARY
;
349 if(wxFLOOD_SURFACE
== nStyle
)
350 lOptions
= FF_SURFACE
;
352 ::GpiFloodFill(m_hPS
, lOptions
, lColor
);
355 bool wxDC::DoGetPixel(
366 lColor
= ::GpiSetPel(m_hPS
, &vPoint
);
367 pCol
->Set((unsigned long)lColor
);
374 void wxDC::DoCrossHair(
379 wxCoord vX1
= vX
- VIEWPORT_EXTENT
;
380 wxCoord vY1
= vY
- VIEWPORT_EXTENT
;
381 wxCoord vX2
= vX
+ VIEWPORT_EXTENT
;
382 wxCoord vY2
= vY
+ VIEWPORT_EXTENT
;
386 vPoint
[0].y
= m_vRclPaint
.yTop
- vY
;
389 vPoint
[1].y
= m_vRclPaint
.yTop
- vY
;
391 ::GpiMove(m_hPS
, &vPoint
[0]);
392 ::GpiLine(m_hPS
, &vPoint
[1]);
395 vPoint
[2].y
= m_vRclPaint
.yTop
- vY1
;
398 vPoint
[3].y
= m_vRclPaint
.yTop
- vY2
;
400 ::GpiMove(m_hPS
, &vPoint
[2]);
401 ::GpiLine(m_hPS
, &vPoint
[3]);
402 } // end of wxDC::DoCrossHair
404 void wxDC::DoDrawLine(
414 vPoint
[0].y
= m_vRclPaint
.yTop
- vY1
;
416 vPoint
[1].y
= m_vRclPaint
.yTop
- vY2
;
417 ::GpiMove(m_hPS
, &vPoint
[0]);
418 ::GpiLine(m_hPS
, &vPoint
[1]);
419 } // end of wxDC::DoDrawLine
421 //////////////////////////////////////////////////////////////////////////////
422 // Draws an arc of a circle, centred on (xc, yc), with starting point (x1, y1)
423 // and ending at (x2, y2). The current pen is used for the outline and the
424 // current brush for filling the shape. The arc is drawn in an anticlockwise
425 // direction from the start point to the end point.
426 //////////////////////////////////////////////////////////////////////////////
427 void wxDC::DoDrawArc(
437 POINTL vPtlArc
[2]; // Structure for current position
446 ARCPARAMS vArcp
; // Structure for arc parameters
448 if((vX1
== vXc
&& vY1
== vXc
) || (vX2
== vXc
&& vY2
== vXc
))
449 return; // Draw point ??
450 dRadius
= 0.5 * ( hypot( (double)(vY1
- vYc
)
453 hypot( (double)(vY2
- vYc
)
458 dAngl1
= atan2( (double)(vY1
- vYc
)
461 dAngl2
= atan2( (double)(vY2
- vYc
)
468 // GpiPointArc can't draw full arc
470 if(dAngl2
== dAngl1
|| (vX1
== vX2
&& vY1
== vY2
) )
475 dAnglmid
= (dAngl1
+ dAngl2
)/2. + M_PI
;
476 vXm
= vXc
+ dRadius
* cos(dAnglmid
);
477 vYm
= vYc
+ dRadius
* sin(dAnglmid
);
492 dAnglmid
= (dAngl1
+ dAngl2
)/2.;
493 vXm
= vXc
+ dRadius
* cos(dAnglmid
);
494 vYm
= vYc
+ dRadius
* sin(dAnglmid
);
497 // Ellipse main axis (r,q), (p,s) with center at (0,0) */
503 ::GpiSetArcParams(m_hPS
, &vArcp
); // Sets parameters to default
505 vPtlPos
.x
= vX1
; // Loads x-coordinate
506 vPtlPos
.y
= vY1
; // Loads y-coordinate
507 ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position
512 ::GpiPointArc(m_hPS
, vPtlArc
); // Draws the arc
513 } // end of wxDC::DoDrawArc
515 void wxDC::DoDrawCheckMark(
526 vPoint
[1].x
= vX1
+ vWidth
;
527 vPoint
[1].y
= vY1
+ vHeight
;
529 ::GpiMove(m_hPS
, &vPoint
[0]);
530 ::GpiBox( m_hPS
// handle to a presentation space
531 ,DRO_OUTLINE
// draw the box outline ? or ?
532 ,&vPoint
[1] // address of the corner
533 ,0L // horizontal corner radius
534 ,0L // vertical corner radius
536 if(vWidth
> 4 && vHeight
> 4)
540 vPoint
[0].x
+= 2; vPoint
[0].y
+= 2;
541 vPoint
[1].x
-= 2; vPoint
[1].y
-= 2;
542 ::GpiMove(m_hPS
, &vPoint
[0]);
543 ::GpiLine(m_hPS
, &vPoint
[1]);
545 vPoint
[0].x
= vPoint
[1].x
;
547 ::GpiMove(m_hPS
, &vPoint
[0]);
548 ::GpiLine(m_hPS
, &vPoint
[1]);
550 } // end of wxDC::DoDrawCheckMark
552 void wxDC::DoDrawPoint(
560 vPoint
.y
= m_vRclPaint
.yTop
- vY
;
561 ::GpiSetPel(m_hPS
, &vPoint
);
562 } // end of wxDC::DoDrawPoint
564 void wxDC::DoDrawPolygon(
572 ULONG ulCount
= 1; // Number of polygons.
573 POLYGON vPlgn
; // polygon.
574 ULONG flOptions
= 0L; // Drawing options.
576 //////////////////////////////////////////////////////////////////////////////
577 // This contains fields of option bits... to draw boundary lines as well as
578 // the area interior.
580 // Drawing boundary lines:
581 // POLYGON_NOBOUNDARY Does not draw boundary lines.
582 // POLYGON_BOUNDARY Draws boundary lines (the default).
584 // Construction of the area interior:
585 // POLYGON_ALTERNATE Constructs interior in alternate mode
587 // POLYGON_WINDING Constructs interior in winding mode.
588 //////////////////////////////////////////////////////////////////////////////
590 ULONG flModel
= 0L; // Drawing model.
592 //////////////////////////////////////////////////////////////////////////////
594 // POLYGON_INCL Fill is inclusive of bottom right (the default).
595 // POLYGON_EXCL Fill is exclusive of bottom right.
596 // This is provided to aid migration from other graphics models.
597 //////////////////////////////////////////////////////////////////////////////
599 LONG lHits
= 0L; // Correlation/error indicator.
602 int nIsTRANSPARENT
= 0;
603 LONG lBorderColor
= 0L;
606 lBorderColor
= m_pen
.GetColour().GetPixel();
607 lColor
= m_brush
.GetColour().GetPixel();
608 if(m_brush
.GetStyle() == wxTRANSPARENT
)
612 vPlgn
.aPointl
= (POINTL
*) calloc( n
+ 1
614 ); // well, new will call malloc
616 for(i
= 0; i
< n
; i
++)
618 vPlgn
.aPointl
[i
].x
= vPoints
[i
].x
; // +xoffset;
619 vPlgn
.aPointl
[i
].y
= vPoints
[i
].y
; // +yoffset;
621 flModel
= POLYGON_BOUNDARY
;
622 if(nFillStyle
== wxWINDING_RULE
)
623 flModel
|= POLYGON_WINDING
;
625 flModel
|= POLYGON_ALTERNATE
;
630 ::GpiSetColor(m_hPS
, lBorderColor
);
631 ::GpiMove(m_hPS
, &vPoint
);
632 lHits
= ::GpiPolygons(m_hPS
, ulCount
, &vPlgn
, flOptions
, flModel
);
634 } // end of wxDC::DoDrawPolygon
636 void wxDC::DoDrawLines(
646 vPoint
.x
= vPoints
[0].x
+ vXoffset
;
647 vPoint
.y
= vPoints
[0].y
+ vYoffset
;
648 ::GpiMove(m_hPS
, &vPoint
);
650 LONG lBorderColor
= m_pen
.GetColour().GetPixel();
652 ::GpiSetColor(m_hPS
, lBorderColor
);
653 for(i
= 1; i
< n
; i
++)
655 vPoint
.x
= vPoints
[0].x
+ vXoffset
;
656 vPoint
.y
= vPoints
[0].y
+ vYoffset
;
657 ::GpiLine(m_hPS
, &vPoint
);
659 } // end of wxDC::DoDrawLines
661 void wxDC::DoDrawRectangle(
672 int nIsTRANSPARENT
= 0;
675 vPoint
[0].y
= m_vRclPaint
.yTop
- (vY
+ vHeight
);
676 vPoint
[1].x
= vX
+ vWidth
;
677 vPoint
[1].y
= m_vRclPaint
.yTop
- vY
;
678 ::GpiMove(m_hPS
, &vPoint
[0]);
679 lColor
= m_brush
.GetColour().GetPixel();
680 lBorderColor
= m_pen
.GetColour().GetPixel();
681 if (m_brush
.GetStyle() == wxTRANSPARENT
)
683 if(lColor
== lBorderColor
|| nIsTRANSPARENT
)
685 lControl
= DRO_OUTLINEFILL
; //DRO_FILL;
686 if(m_brush
.GetStyle() == wxTRANSPARENT
)
687 lControl
= DRO_OUTLINE
;
689 ::GpiSetColor(m_hPS
, lColor
);
690 ::GpiBox( m_hPS
// handle to a presentation space
691 ,lControl
// draw the box outline ? or ?
692 ,&vPoint
[1] // address of the corner
693 ,0L // horizontal corner radius
694 ,0L // vertical corner radius
699 lControl
= DRO_OUTLINE
;
713 vPoint
[0].x
= vX
+ 1;
714 vPoint
[0].y
= m_vRclPaint
.yTop
- (vY
+ vHeight
) + 1;
715 vPoint
[1].x
= vX
+ vWidth
- 2;
716 vPoint
[1].y
= m_vRclPaint
.yTop
- (vY
+ 2);
717 ::GpiMove(m_hPS
, &vPoint
[0]);
725 } // end of wxDC::DoDrawRectangle
727 void wxDC::DoDrawRoundedRectangle(
739 vPoint
[0].y
= YLOG2DEV(vY
) - vHeight
;
740 vPoint
[1].x
= vX
+ vWidth
;
742 ::GpiMove(m_hPS
, &vPoint
[0]);
744 lControl
= DRO_OUTLINEFILL
; //DRO_FILL;
745 if (m_brush
.GetStyle() == wxTRANSPARENT
)
746 lControl
= DRO_OUTLINE
;
747 ::GpiBox( m_hPS
// handle to a presentation space
748 ,DRO_OUTLINE
// draw the box outline ? or ?
749 ,&vPoint
[1] // address of the corner
750 ,(LONG
)dRadius
// horizontal corner radius
751 ,(LONG
)dRadius
// vertical corner radius
753 } // end of wxDC::DoDrawRoundedRectangle
755 // Draw Ellipse within box (x,y) - (x+width, y+height)
756 void wxDC::DoDrawEllipse(
763 POINTL vPtlPos
; // Structure for current position
764 FIXED vFxMult
; // Multiplier for ellipse
765 ARCPARAMS vArcp
; // Structure for arc parameters
768 vArcp
.lQ
= vHeight
/2;
771 ::GpiSetArcParams( m_hPS
773 ); // Sets parameters to default
774 vPtlPos
.x
= vX
+ vWidth
/2; // Loads x-coordinate
775 vPtlPos
.y
= vY
+ vHeight
/2; // Loads y-coordinate
778 ); // Sets current position
779 vFxMult
= MAKEFIXED(1, 0); /* Sets multiplier */
782 // DRO_FILL, DRO_OTLINEFILL - where to get
787 ); // Draws full arc with center at current position
788 } // end of wxDC::DoDrawEllipse
790 void wxDC::DoDrawEllipticArc(
799 POINTL vPtlPos
; // Structure for current position
800 FIXED vFxMult
; // Multiplier for ellipse
801 ARCPARAMS vArcp
; // Structure for arc parameters
803 FIXED vFSweepa
; // Start angle, sweep angle
808 dFractPart
= modf(dSa
,&dIntPart
);
809 vFSa
= MAKEFIXED((int)dIntPart
, (int)(dFractPart
* 0xffff) );
810 dFractPart
= modf(dEa
- dSa
, &dIntPart
);
811 vFSweepa
= MAKEFIXED((int)dIntPart
, (int)(dFractPart
* 0xffff) );
814 // Ellipse main axis (r,q), (p,s) with center at (0,0)
817 vArcp
.lQ
= vHeight
/2;
820 ::GpiSetArcParams(m_hPS
, &vArcp
); // Sets parameters to default
821 vPtlPos
.x
= vX
+ vWidth
/2 * (1. + cos(DegToRad(dSa
))); // Loads x-coordinate
822 vPtlPos
.y
= vY
+ vHeight
/2 * (1. + sin(DegToRad(dSa
))); // Loads y-coordinate
823 ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position
826 // May be not to the center ?
828 vPtlPos
.x
= vX
+ vWidth
/2 ; // Loads x-coordinate
829 vPtlPos
.y
= vY
+ vHeight
/2; // Loads y-coordinate
830 vFxMult
= MAKEFIXED(1, 0); // Sets multiplier
833 // DRO_FILL, DRO_OTLINEFILL - where to get
835 ::GpiPartialArc( m_hPS
841 } // end of wxDC::DoDrawEllipticArc
843 void wxDC::DoDrawIcon(
849 wxCHECK_RET( rIcon
.Ok(), wxT("invalid icon in DrawIcon") );
851 ::WinDrawPointer( GetHPS()
854 ,(HPOINTER
)GetHiconOf(rIcon
)
857 } // end of wxDC::DoDrawIcon
859 void wxDC::DoDrawBitmap(
866 POINTL vPoint
= {vX
, vY
};
868 ::WinDrawBitmap( GetHPS()
869 ,(HBITMAP
)GetHbitmapOf(rBmp
)
876 } // end of wxDC::DoDrawBitmap
878 void wxDC::DoDrawText(
879 const wxString
& rsText
890 void wxDC::DrawAnyText(
891 const wxString
& rsText
896 int nOldBackground
= 0;
901 // prepare for drawing the text
905 // Set text color attributes
907 if (m_textForegroundColour
.Ok())
910 ,(int)m_textForegroundColour
.GetPixel()
914 if (m_textBackgroundColour
.Ok())
916 nOldBackground
= SetTextBkColor( m_hPS
917 ,(int)m_textBackgroundColour
.GetPixel()
926 lHits
= ::GpiCharStringAt( m_hPS
933 wxLogLastError(wxT("TextOut"));
937 // Restore the old parameters (text foreground colour may be left because
938 // it never is set to anything else, but background should remain
939 // transparent even if we just drew an opaque string)
941 if (m_textBackgroundColour
.Ok())
942 SetTextBkColor( m_hPS
950 void wxDC::DoDrawRotatedText(
951 const wxString
& rsText
969 DoDrawText(text, x, y);
974 wxFillLogFont(&lf, &m_font);
976 // GDI wants the angle in tenth of degree
977 long angle10 = (long)(angle * 10);
978 lf.lfEscapement = angle10;
979 lf. lfOrientation = angle10;
981 HFONT hfont = ::CreateFontIndirect(&lf);
984 wxLogLastError("CreateFont");
988 HFONT hfontOld = ::SelectObject(GetHdc(), hfont);
990 DrawAnyText(text, x, y);
992 (void)::SelectObject(GetHdc(), hfontOld);
995 // call the bounding box by adding all four vertices of the rectangle
996 // containing the text to it (simpler and probably not slower than
997 // determining which of them is really topmost/leftmost/...)
999 GetTextExtent(text, &w, &h);
1001 double rad = DegToRad(angle);
1003 // "upper left" and "upper right"
1004 CalcBoundingBox(x, y);
1005 CalcBoundingBox(x + w*cos(rad), y - h*sin(rad));
1006 CalcBoundingBox(x + h*sin(rad), y + h*cos(rad));
1008 // "bottom left" and "bottom right"
1009 x += (wxCoord)(h*sin(rad));
1010 y += (wxCoord)(h*cos(rad));
1011 CalcBoundingBox(x, y);
1012 CalcBoundingBox(x + h*sin(rad), y + h*cos(rad));
1017 // ---------------------------------------------------------------------------
1019 // ---------------------------------------------------------------------------
1021 void wxDC::SetPalette(const wxPalette
& palette
)
1031 // Set the old object temporarily, in case the assignment deletes an object
1032 // that's not yet selected out.
1044 m_font
.SetPS(m_hPS
); // this will realize the font
1048 HFONT hFont
= m_font
.GetResourceHandle();
1049 if (hFont
== (HFONT
) NULL
)
1051 wxLogDebug(wxT("::SelectObject failed in wxDC::SetFont."));
1054 m_hOldFont
= (WXHFONT
) hFont
;
1056 } // end of wxDC::SetFont
1062 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1078 m_pen
.SetPS((HPS
)m_hOldPen
);
1085 if (m_pen
.GetResourceHandle())
1089 m_hOldPen
= m_pen
.GetPS();
1094 void wxDC::SetBrush(
1095 const wxBrush
& rBrush
1098 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1100 if (m_brush
== rBrush
)
1114 m_brush
.SetPS((HPS
)m_hOldBrush
);
1121 if (m_brush
.GetResourceHandle())
1123 m_brush
.SetPS(m_hPS
);
1125 m_hOldBrush
= m_brush
.GetPS();
1128 } // end of wxDC::SetBrush
1130 void wxDC::SetBackground(const wxBrush
& brush
)
1135 void wxDC::SetBackgroundMode(
1139 m_backgroundMode
= nMode
;
1142 void wxDC::SetLogicalFunction(int function
)
1147 void wxDC::SetRop(WXHDC dc
)
1149 if (!dc
|| m_logicalFunction
< 0)
1153 // These may be wrong
1154 switch (m_logicalFunction
)
1156 // TODO: Figure this stuff out
1157 // case wxXOR: c_rop = R2_XORPEN; break;
1158 // case wxXOR: c_rop = R2_NOTXORPEN; break;
1159 // case wxINVERT: c_rop = R2_NOT; break;
1160 // case wxOR_REVERSE: c_rop = R2_MERGEPENNOT; break;
1161 // case wxAND_REVERSE: c_rop = R2_MASKPENNOT; break;
1162 // case wxCLEAR: c_rop = R2_WHITE; break;
1163 // case wxSET: c_rop = R2_BLACK; break;
1164 // case wxSRC_INVERT: c_rop = R2_NOTCOPYPEN; break;
1165 // case wxOR_INVERT: c_rop = R2_MERGENOTPEN; break;
1166 // case wxAND: c_rop = R2_MASKPEN; break;
1167 // case wxOR: c_rop = R2_MERGEPEN; break;
1168 // case wxAND_INVERT: c_rop = R2_MASKNOTPEN; break;
1173 // c_rop = R2_COPYPEN;
1176 // SetROP2((HDC) dc, c_rop);
1179 bool wxDC::StartDoc(const wxString
& message
)
1181 // We might be previewing, so return TRUE to let it continue.
1189 void wxDC::StartPage()
1193 void wxDC::EndPage()
1197 // ---------------------------------------------------------------------------
1199 // ---------------------------------------------------------------------------
1201 wxCoord
wxDC::GetCharHeight() const
1203 FONTMETRICS vFM
; // metrics structure
1205 ::GpiQueryFontMetrics( m_hPS
1206 ,sizeof(FONTMETRICS
)
1209 return YDEV2LOGREL(vFM
.lXHeight
);
1212 wxCoord
wxDC::GetCharWidth() const
1214 FONTMETRICS vFM
; // metrics structure
1216 ::GpiQueryFontMetrics( m_hPS
1217 ,sizeof(FONTMETRICS
)
1220 return XDEV2LOGREL(vFM
.lAveCharWidth
);
1223 void wxDC::DoGetTextExtent(
1224 const wxString
& rsString
1227 , wxCoord
* pvDescent
1228 , wxCoord
* pvExternalLeading
1232 POINTL avPoint
[TXTBOX_COUNT
];
1237 FONTMETRICS vFM
; // metrics structure
1240 ERRORID vErrorCode
; // last error id code
1241 wxFont
* pFontToUse
= (wxFont
*)pTheFont
;
1243 char zMsg
[128]; // DEBUG
1247 pFontToUse
= (wxFont
*)&m_font
;
1248 l
= rsString
.length();
1249 pStr
= (PCH
) rsString
.c_str();
1252 // In world coordinates.
1254 bRc
= ::GpiQueryTextBox( m_hPS
1257 ,TXTBOX_COUNT
// return maximum information
1258 ,avPoint
// array of coordinates points
1262 vErrorCode
= ::WinGetLastError(wxGetInstance());
1263 sError
= wxPMErrorToStr(vErrorCode
);
1265 sprintf(zMsg
, "GpiQueryTextBox for %s: failed with Error: %x - %s", pStr
, vErrorCode
, sError
.c_str());
1266 (void)wxMessageBox( "wxWindows Menu sample"
1272 vPtMin
.x
= avPoint
[0].x
;
1273 vPtMax
.x
= avPoint
[0].x
;
1274 vPtMin
.y
= avPoint
[0].y
;
1275 vPtMax
.y
= avPoint
[0].y
;
1276 for (i
= 1; i
< 4; i
++)
1278 if(vPtMin
.x
> avPoint
[i
].x
) vPtMin
.x
= avPoint
[i
].x
;
1279 if(vPtMin
.y
> avPoint
[i
].y
) vPtMin
.y
= avPoint
[i
].y
;
1280 if(vPtMax
.x
< avPoint
[i
].x
) vPtMax
.x
= avPoint
[i
].x
;
1281 if(vPtMax
.y
< avPoint
[i
].y
) vPtMax
.y
= avPoint
[i
].y
;
1283 ::GpiQueryFontMetrics( m_hPS
1284 ,sizeof(FONTMETRICS
)
1289 *pvX
= (wxCoord
)(vPtMax
.x
- vPtMin
.x
+ 1);
1291 *pvY
= (wxCoord
)(vPtMax
.y
- vPtMin
.y
+ 1);
1293 *pvDescent
= vFM
.lMaxDescender
;
1294 if (pvExternalLeading
)
1295 *pvExternalLeading
= vFM
.lExternalLeading
;
1298 void wxDC::SetMapMode( int mode
)
1303 void wxDC::SetUserScale(double x
, double y
)
1308 SetMapMode(m_mappingMode
);
1311 void wxDC::SetAxisOrientation(bool xLeftRight
, bool yBottomUp
)
1313 m_signX
= xLeftRight
? 1 : -1;
1314 m_signY
= yBottomUp
? -1 : 1;
1316 SetMapMode(m_mappingMode
);
1319 void wxDC::SetSystemScale(double x
, double y
)
1324 SetMapMode(m_mappingMode
);
1327 void wxDC::SetLogicalOrigin( wxCoord x
, wxCoord y
)
1332 void wxDC::SetDeviceOrigin(
1339 m_deviceOriginX
= x
;
1340 m_deviceOriginY
= y
;
1341 ::GpiQueryPageViewport( m_hPS
1348 ::GpiSetPageViewport( m_hPS
1353 // ---------------------------------------------------------------------------
1354 // coordinates transformations
1355 // ---------------------------------------------------------------------------
1357 wxCoord
wxDCBase::DeviceToLogicalX(wxCoord x
) const
1359 return (wxCoord
) (((x
) - m_deviceOriginX
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
) - m_logicalOriginX
);
1362 wxCoord
wxDCBase::DeviceToLogicalXRel(wxCoord x
) const
1364 return (wxCoord
) ((x
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
));
1367 wxCoord
wxDCBase::DeviceToLogicalY(wxCoord y
) const
1369 return (wxCoord
) (((y
) - m_deviceOriginY
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
) - m_logicalOriginY
);
1372 wxCoord
wxDCBase::DeviceToLogicalYRel(wxCoord y
) const
1374 return (wxCoord
) ((y
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
));
1377 wxCoord
wxDCBase::LogicalToDeviceX(wxCoord x
) const
1379 return (wxCoord
) ((x
- m_logicalOriginX
)*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
+ m_deviceOriginX
);
1382 wxCoord
wxDCBase::LogicalToDeviceXRel(wxCoord x
) const
1384 return (wxCoord
) (x
*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
);
1387 wxCoord
wxDCBase::LogicalToDeviceY(wxCoord y
) const
1389 return (wxCoord
) ((y
- m_logicalOriginY
)*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
+ m_deviceOriginY
);
1392 wxCoord
wxDCBase::LogicalToDeviceYRel(wxCoord y
) const
1394 return (wxCoord
) (y
*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
);
1397 // ---------------------------------------------------------------------------
1399 // ---------------------------------------------------------------------------
1413 wxMask
* pMask
= NULL
;
1415 COLORREF vOldTextColor
;
1416 COLORREF vOldBackground
= ::GpiQueryBackColor(m_hPS
);
1420 const wxBitmap
& rBmp
= pSource
->m_vSelectedBitmap
;
1422 pMask
= rBmp
.GetMask();
1423 if (!(rBmp
.Ok() && pMask
&& pMask
->GetMaskBitmap()))
1429 ::GpiQueryAttrs( m_hPS
1434 vOldTextColor
= (COLORREF
)vCbnd
.lColor
;
1436 if (m_textForegroundColour
.Ok())
1438 vCbnd
.lColor
= (LONG
)m_textForegroundColour
.GetPixel();
1439 ::GpiSetAttrs( m_hPS
// presentation-space handle
1440 ,PRIM_CHAR
// Char primitive.
1441 ,CBB_COLOR
// sets color.
1443 ,&vCbnd
// buffer for attributes.
1446 if (m_textBackgroundColour
.Ok())
1448 ::GpiSetBackColor(m_hPS
, (LONG
)m_textBackgroundColour
.GetPixel());
1451 LONG lRop
= ROP_SRCCOPY
;
1455 case wxXOR
: lRop
= ROP_SRCINVERT
; break;
1456 case wxINVERT
: lRop
= ROP_DSTINVERT
; break;
1457 case wxOR_REVERSE
: lRop
= 0x00DD0228; break;
1458 case wxAND_REVERSE
: lRop
= ROP_SRCERASE
; break;
1459 case wxCLEAR
: lRop
= ROP_ZERO
; break;
1460 case wxSET
: lRop
= ROP_ONE
; break;
1461 case wxOR_INVERT
: lRop
= ROP_MERGEPAINT
; break;
1462 case wxAND
: lRop
= ROP_SRCAND
; break;
1463 case wxOR
: lRop
= ROP_SRCPAINT
; break;
1464 case wxEQUIV
: lRop
= 0x00990066; break;
1465 case wxNAND
: lRop
= 0x007700E6; break;
1466 case wxAND_INVERT
: lRop
= 0x00220326; break;
1467 case wxCOPY
: lRop
= ROP_SRCCOPY
; break;
1468 case wxNO_OP
: lRop
= ROP_NOTSRCERASE
; break;
1469 case wxSRC_INVERT
: lRop
= ROP_SRCINVERT
; break;
1470 case wxNOR
: lRop
= ROP_NOTSRCCOPY
; break;
1472 wxFAIL_MSG( wxT("unsupported logical function") );
1481 // Blit bitmap with mask
1485 // Create a temp buffer bitmap and DCs/PSs to access it and the mask
1491 DEVOPENSTRUC vDOP
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1492 BITMAPINFOHEADER2 vBmpHdr
;
1493 SIZEL vSize
= {0, 0};
1496 hDCMask
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDOP
, NULLHANDLE
);
1497 hDCBuffer
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDOP
, NULLHANDLE
);
1498 hPSMask
= ::GpiCreatePS(vHabmain
, hDCMask
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
1499 hPSBuffer
= ::GpiCreatePS(vHabmain
, hDCBuffer
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
1501 memset(&vBmpHdr
, 0, sizeof(BITMAPINFOHEADER2
));
1502 vBmpHdr
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1503 vBmpHdr
.cx
= vWidth
;
1504 vBmpHdr
.cy
= vHeight
;
1505 vBmpHdr
.cPlanes
= 1;
1506 vBmpHdr
.cBitCount
= 24;
1508 HBITMAP hBufBitmap
= ::GpiCreateBitmap(GetHPS(), &vBmpHdr
, 0L, NULL
, NULL
);
1509 POINTL aPoint1
[4] = { 0, 0
1512 ,vXdest
+ vWidth
, vYdest
+ vHeight
1514 POINTL aPoint2
[4] = { 0, 0
1517 ,vXsrc
+ vWidth
, vYsrc
+ vHeight
1519 POINTL aPoint3
[4] = { vXdest
, vYdest
1520 ,vXdest
+ vWidth
, vYdest
+ vHeight
1522 ,vXsrc
+ vWidth
, vYsrc
+ vHeight
1524 POINTL aPoint4
[4] = { vXdest
, vYdest
1525 ,vXdest
+ vWidth
, vYdest
+ vHeight
1529 ::GpiSetBitmap(hPSMask
, (HBITMAP
) pMask
->GetMaskBitmap());
1530 ::GpiSetBitmap(hPSBuffer
, (HBITMAP
) hBufBitmap
);
1533 // Copy dest to buffer
1535 rc
= ::GpiBitBlt( hPSBuffer
1542 if (rc
== GPI_ERROR
)
1544 wxLogLastError(wxT("BitBlt"));
1548 // Copy src to buffer using selected raster op
1550 rc
= ::GpiBitBlt( hPSBuffer
1557 if (rc
== GPI_ERROR
)
1559 wxLogLastError(wxT("BitBlt"));
1563 // Set masked area in buffer to BLACK (pixel value 0)
1565 COLORREF vPrevBkCol
= ::GpiQueryBackColor(GetHPS());
1566 COLORREF vPrevCol
= ::GpiQueryColor(GetHPS());
1568 ::GpiSetBackColor(GetHPS(), OS2RGB(255, 255, 255));
1569 ::GpiSetColor(GetHPS(), OS2RGB(0, 0, 0));
1571 rc
= ::GpiBitBlt( hPSBuffer
1578 if (rc
== GPI_ERROR
)
1580 wxLogLastError(wxT("BitBlt"));
1584 // Set unmasked area in dest to BLACK
1586 ::GpiSetBackColor(GetHPS(), OS2RGB(0, 0, 0));
1587 ::GpiSetColor(GetHPS(), OS2RGB(255, 255, 255));
1588 rc
= ::GpiBitBlt( GetHPS()
1595 if (rc
== GPI_ERROR
)
1597 wxLogLastError(wxT("BitBlt"));
1601 // Restore colours to original values
1603 ::GpiSetBackColor(GetHPS(), vPrevBkCol
);
1604 ::GpiSetColor(GetHPS(), vPrevCol
);
1607 // OR buffer to dest
1609 rc
= ::GpiBitBlt( GetHPS()
1616 if (rc
== GPI_ERROR
)
1619 wxLogLastError(wxT("BitBlt"));
1623 // Tidy up temporary DCs and bitmap
1625 ::GpiSetBitmap(hPSMask
, NULLHANDLE
);
1626 ::GpiSetBitmap(hPSBuffer
, NULLHANDLE
);
1627 ::GpiDestroyPS(hPSMask
);
1628 ::GpiDestroyPS(hPSBuffer
);
1629 ::DevCloseDC(hDCMask
);
1630 ::DevCloseDC(hDCBuffer
);
1631 ::GpiDeleteBitmap(hBufBitmap
);
1634 else // no mask, just BitBlt() it
1636 POINTL aPoint
[4] = { vXdest
, vYdest
1637 ,vXdest
+ vWidth
, vYdest
+ vHeight
1639 ,vXsrc
+ vWidth
, vYsrc
+ vHeight
1642 bSuccess
= (::GpiBitBlt( m_hPS
1651 wxLogLastError(wxT("BitBlt"));
1654 vCbnd
.lColor
= (LONG
)vOldTextColor
;
1655 ::GpiSetAttrs( m_hPS
// presentation-space handle
1656 ,PRIM_CHAR
// Char primitive.
1657 ,CBB_COLOR
// sets color.
1659 ,&vCbnd
// buffer for attributes.
1661 ::GpiSetBackColor(m_hPS
, (LONG
)vOldBackground
);
1665 void wxDC::DoGetSize( int* width
, int* height
) const
1670 void wxDC::DoGetSizeMM( int* width
, int* height
) const
1675 wxSize
wxDC::GetPPI() const
1680 return (wxSize(x
,y
));
1683 void wxDC::SetLogicalScale( double x
, double y
)
1688 #if WXWIN_COMPATIBILITY
1689 void wxDC::DoGetTextExtent(const wxString
& string
, float *x
, float *y
,
1690 float *descent
, float *externalLeading
,
1691 wxFont
*theFont
, bool use16bit
) const
1693 wxCoord x1
, y1
, descent1
, externalLeading1
;
1694 GetTextExtent(string
, & x1
, & y1
, & descent1
, & externalLeading1
, theFont
, use16bit
);
1697 *descent
= descent1
;
1698 if (externalLeading
)
1699 *externalLeading
= externalLeading1
;