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 // ---------------------------------------------------------------------------
148 m_bIsPaintTime
= FALSE
; // True at Paint Time
149 m_brush
.GetColour().Set("WHITE");
150 } // end of wxDC::wxDC
156 SelectOldObjects(m_hDC
);
158 // if we own the HDC, we delete it, otherwise we just release it
164 ::GpiAssociate(m_hPS
, NULLHANDLE
);
165 ::GpiDestroyPS(m_hPS
);
168 ::DevCloseDC((HDC
)m_hDC
);
173 // Just Dissacociate, not destroy if we don't own the DC
177 ::GpiAssociate(m_hPS
, NULLHANDLE
);
181 } // end of wxDC::~wxDC
183 // This will select current objects out of the DC,
184 // which is what you have to do before deleting the
186 void wxDC::SelectOldObjects(
194 ::GpiSetBitmap(hPS
, (HBITMAP
) m_hOldBitmap
);
195 if (m_vSelectedBitmap
.Ok())
197 m_vSelectedBitmap
.SetSelectedInto(NULL
);
202 // OS/2 has no other native GDI objects to set in a PS/DC like windows
210 m_brush
= wxNullBrush
;
212 m_palette
= wxNullPalette
;
214 m_backgroundBrush
= wxNullBrush
;
215 m_vSelectedBitmap
= wxNullBitmap
;
216 } // end of wxDC::SelectOldObjects
218 // ---------------------------------------------------------------------------
220 // ---------------------------------------------------------------------------
222 #define DO_SET_CLIPPING_BOX() \
226 ::GpiQueryClipBox(m_hPS, &rect); \
228 m_clipX1 = (wxCoord) XDEV2LOG(rect.xLeft); \
229 m_clipY1 = (wxCoord) YDEV2LOG(rect.yTop); \
230 m_clipX2 = (wxCoord) XDEV2LOG(rect.xRight); \
231 m_clipY2 = (wxCoord) YDEV2LOG(rect.yBottom); \
234 void wxDC::DoSetClippingRegion(
244 vRect
.xLeft
= XLOG2DEV(x
);
245 vRect
.yTop
= YLOG2DEV(m_vRclPaint
.yTop
- y
);
246 vRect
.xRight
= XLOG2DEV(x
+ width
);
247 vRect
.yBottom
= YLOG2DEV(m_vRclPaint
.yTop
- (y
+ height
));
248 ::GpiIntersectClipRectangle(m_hPS
, &vRect
);
249 DO_SET_CLIPPING_BOX()
250 } // end of wxDC::DoSetClippingRegion
252 void wxDC::DoSetClippingRegionAsRegion(
253 const wxRegion
& rRegion
256 wxCHECK_RET(rRegion
.GetHRGN(), wxT("invalid clipping region"));
260 ::GpiSetClipRegion( m_hPS
261 ,(HRGN
)rRegion
.GetHRGN()
264 DO_SET_CLIPPING_BOX()
265 } // end of wxDC::DoSetClippingRegionAsRegion
267 void wxDC::DestroyClippingRegion(void)
269 if (m_clipping
&& m_hPS
)
274 // TODO: this should restore the previous clipped region
275 // so that OnPaint processing works correctly, and
276 // the update doesn't get destroyed after the first
277 // DestroyClippingRegion
278 vRect
.xLeft
= XLOG2DEV(0);
279 vRect
.yTop
= YLOG2DEV(32000);
280 vRect
.xRight
= XLOG2DEV(32000);
281 vRect
.yBottom
= YLOG2DEV(0);
283 HRGN hRgn
= ::GpiCreateRegion(m_hPS
, 1, &vRect
);
285 ::GpiSetClipRegion(m_hPS
, hRgn
, &hRgnOld
);
288 } // end of wxDC::DestroyClippingRegion
290 // ---------------------------------------------------------------------------
291 // query capabilities
292 // ---------------------------------------------------------------------------
294 bool wxDC::CanDrawBitmap() const
299 bool wxDC::CanGetTextExtent() const
301 LONG lTechnology
= 0L;
303 ::DevQueryCaps(GetHDC(), CAPS_TECHNOLOGY
, 1L, &lTechnology
);
304 return (lTechnology
== CAPS_TECH_RASTER_DISPLAY
) || (lTechnology
== CAPS_TECH_RASTER_PRINTER
);
305 } // end of wxDC::CanGetTextExtent
307 int wxDC::GetDepth() const
309 LONG lArray
[CAPS_COLOR_BITCOUNT
];
312 if(::DevQueryCaps( GetHDC()
318 nBitsPerPixel
= (int)lArray
[CAPS_COLOR_BITCOUNT
];
320 return nBitsPerPixel
;
321 } // end of wxDC::GetDepth
323 // ---------------------------------------------------------------------------
325 // ---------------------------------------------------------------------------
332 void wxDC::DoFloodFill(
335 , const wxColour
& rCol
343 vPtlPos
.x
= vX
; // Loads x-coordinate
344 vPtlPos
.y
= vY
; // Loads y-coordinate
345 ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position
346 lColor
= rCol
.GetPixel();
347 lOptions
= FF_BOUNDARY
;
348 if(wxFLOOD_SURFACE
== nStyle
)
349 lOptions
= FF_SURFACE
;
351 ::GpiFloodFill(m_hPS
, lOptions
, lColor
);
354 bool wxDC::DoGetPixel(
365 lColor
= ::GpiSetPel(m_hPS
, &vPoint
);
366 pCol
->Set((unsigned long)lColor
);
373 void wxDC::DoCrossHair(
378 wxCoord vX1
= vX
- VIEWPORT_EXTENT
;
379 wxCoord vY1
= vY
- VIEWPORT_EXTENT
;
380 wxCoord vX2
= vX
+ VIEWPORT_EXTENT
;
381 wxCoord vY2
= vY
+ VIEWPORT_EXTENT
;
385 vPoint
[0].y
= m_vRclPaint
.yTop
- vY
;
388 vPoint
[1].y
= m_vRclPaint
.yTop
- vY
;
390 ::GpiMove(m_hPS
, &vPoint
[0]);
391 ::GpiLine(m_hPS
, &vPoint
[1]);
394 vPoint
[2].y
= m_vRclPaint
.yTop
- vY1
;
397 vPoint
[3].y
= m_vRclPaint
.yTop
- vY2
;
399 ::GpiMove(m_hPS
, &vPoint
[2]);
400 ::GpiLine(m_hPS
, &vPoint
[3]);
401 } // end of wxDC::DoCrossHair
403 void wxDC::DoDrawLine(
413 vPoint
[0].y
= m_vRclPaint
.yTop
- vY1
;
415 vPoint
[1].y
= m_vRclPaint
.yTop
- vY2
;
416 ::GpiMove(m_hPS
, &vPoint
[0]);
417 ::GpiLine(m_hPS
, &vPoint
[1]);
418 } // end of wxDC::DoDrawLine
420 //////////////////////////////////////////////////////////////////////////////
421 // Draws an arc of a circle, centred on (xc, yc), with starting point (x1, y1)
422 // and ending at (x2, y2). The current pen is used for the outline and the
423 // current brush for filling the shape. The arc is drawn in an anticlockwise
424 // direction from the start point to the end point.
425 //////////////////////////////////////////////////////////////////////////////
426 void wxDC::DoDrawArc(
436 POINTL vPtlArc
[2]; // Structure for current position
445 ARCPARAMS vArcp
; // Structure for arc parameters
447 if((vX1
== vXc
&& vY1
== vXc
) || (vX2
== vXc
&& vY2
== vXc
))
448 return; // Draw point ??
449 dRadius
= 0.5 * ( hypot( (double)(vY1
- vYc
)
452 hypot( (double)(vY2
- vYc
)
457 dAngl1
= atan2( (double)(vY1
- vYc
)
460 dAngl2
= atan2( (double)(vY2
- vYc
)
467 // GpiPointArc can't draw full arc
469 if(dAngl2
== dAngl1
|| (vX1
== vX2
&& vY1
== vY2
) )
474 dAnglmid
= (dAngl1
+ dAngl2
)/2. + M_PI
;
475 vXm
= vXc
+ dRadius
* cos(dAnglmid
);
476 vYm
= vYc
+ dRadius
* sin(dAnglmid
);
491 dAnglmid
= (dAngl1
+ dAngl2
)/2.;
492 vXm
= vXc
+ dRadius
* cos(dAnglmid
);
493 vYm
= vYc
+ dRadius
* sin(dAnglmid
);
496 // Ellipse main axis (r,q), (p,s) with center at (0,0) */
502 ::GpiSetArcParams(m_hPS
, &vArcp
); // Sets parameters to default
504 vPtlPos
.x
= vX1
; // Loads x-coordinate
505 vPtlPos
.y
= vY1
; // Loads y-coordinate
506 ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position
511 ::GpiPointArc(m_hPS
, vPtlArc
); // Draws the arc
512 } // end of wxDC::DoDrawArc
514 void wxDC::DoDrawCheckMark(
525 vPoint
[1].x
= vX1
+ vWidth
;
526 vPoint
[1].y
= vY1
+ vHeight
;
528 ::GpiMove(m_hPS
, &vPoint
[0]);
529 ::GpiBox( m_hPS
// handle to a presentation space
530 ,DRO_OUTLINE
// draw the box outline ? or ?
531 ,&vPoint
[1] // address of the corner
532 ,0L // horizontal corner radius
533 ,0L // vertical corner radius
535 if(vWidth
> 4 && vHeight
> 4)
539 vPoint
[0].x
+= 2; vPoint
[0].y
+= 2;
540 vPoint
[1].x
-= 2; vPoint
[1].y
-= 2;
541 ::GpiMove(m_hPS
, &vPoint
[0]);
542 ::GpiLine(m_hPS
, &vPoint
[1]);
544 vPoint
[0].x
= vPoint
[1].x
;
546 ::GpiMove(m_hPS
, &vPoint
[0]);
547 ::GpiLine(m_hPS
, &vPoint
[1]);
549 } // end of wxDC::DoDrawCheckMark
551 void wxDC::DoDrawPoint(
559 vPoint
.y
= m_vRclPaint
.yTop
- vY
;
560 ::GpiSetPel(m_hPS
, &vPoint
);
561 } // end of wxDC::DoDrawPoint
563 void wxDC::DoDrawPolygon(
571 ULONG ulCount
= 1; // Number of polygons.
572 POLYGON vPlgn
; // polygon.
573 ULONG flOptions
= 0L; // Drawing options.
575 //////////////////////////////////////////////////////////////////////////////
576 // This contains fields of option bits... to draw boundary lines as well as
577 // the area interior.
579 // Drawing boundary lines:
580 // POLYGON_NOBOUNDARY Does not draw boundary lines.
581 // POLYGON_BOUNDARY Draws boundary lines (the default).
583 // Construction of the area interior:
584 // POLYGON_ALTERNATE Constructs interior in alternate mode
586 // POLYGON_WINDING Constructs interior in winding mode.
587 //////////////////////////////////////////////////////////////////////////////
589 ULONG flModel
= 0L; // Drawing model.
591 //////////////////////////////////////////////////////////////////////////////
593 // POLYGON_INCL Fill is inclusive of bottom right (the default).
594 // POLYGON_EXCL Fill is exclusive of bottom right.
595 // This is provided to aid migration from other graphics models.
596 //////////////////////////////////////////////////////////////////////////////
598 LONG lHits
= 0L; // Correlation/error indicator.
601 int nIsTRANSPARENT
= 0;
602 LONG lBorderColor
= 0L;
605 lBorderColor
= m_pen
.GetColour().GetPixel();
606 lColor
= m_brush
.GetColour().GetPixel();
607 if(m_brush
.GetStyle() == wxTRANSPARENT
)
611 vPlgn
.aPointl
= (POINTL
*) calloc( n
+ 1
613 ); // well, new will call malloc
615 for(i
= 0; i
< n
; i
++)
617 vPlgn
.aPointl
[i
].x
= vPoints
[i
].x
; // +xoffset;
618 vPlgn
.aPointl
[i
].y
= vPoints
[i
].y
; // +yoffset;
620 flModel
= POLYGON_BOUNDARY
;
621 if(nFillStyle
== wxWINDING_RULE
)
622 flModel
|= POLYGON_WINDING
;
624 flModel
|= POLYGON_ALTERNATE
;
629 ::GpiSetColor(m_hPS
, lBorderColor
);
630 ::GpiMove(m_hPS
, &vPoint
);
631 lHits
= ::GpiPolygons(m_hPS
, ulCount
, &vPlgn
, flOptions
, flModel
);
633 } // end of wxDC::DoDrawPolygon
635 void wxDC::DoDrawLines(
645 vPoint
.x
= vPoints
[0].x
+ vXoffset
;
646 vPoint
.y
= vPoints
[0].y
+ vYoffset
;
647 ::GpiMove(m_hPS
, &vPoint
);
649 LONG lBorderColor
= m_pen
.GetColour().GetPixel();
651 ::GpiSetColor(m_hPS
, lBorderColor
);
652 for(i
= 1; i
< n
; i
++)
654 vPoint
.x
= vPoints
[0].x
+ vXoffset
;
655 vPoint
.y
= vPoints
[0].y
+ vYoffset
;
656 ::GpiLine(m_hPS
, &vPoint
);
658 } // end of wxDC::DoDrawLines
660 void wxDC::DoDrawRectangle(
671 int nIsTRANSPARENT
= 0;
674 vPoint
[0].y
= m_vRclPaint
.yTop
- (vY
+ vHeight
);
675 vPoint
[1].x
= vX
+ vWidth
;
676 vPoint
[1].y
= m_vRclPaint
.yTop
- vY
;
677 ::GpiMove(m_hPS
, &vPoint
[0]);
678 lColor
= m_brush
.GetColour().GetPixel();
679 lBorderColor
= m_pen
.GetColour().GetPixel();
680 if (m_brush
.GetStyle() == wxTRANSPARENT
)
682 if(lColor
== lBorderColor
|| nIsTRANSPARENT
)
684 lControl
= DRO_OUTLINEFILL
; //DRO_FILL;
685 if(m_brush
.GetStyle() == wxTRANSPARENT
)
686 lControl
= DRO_OUTLINE
;
688 ::GpiSetColor(m_hPS
, lColor
);
689 ::GpiBox( m_hPS
// handle to a presentation space
690 ,lControl
// draw the box outline ? or ?
691 ,&vPoint
[1] // address of the corner
692 ,0L // horizontal corner radius
693 ,0L // vertical corner radius
698 lControl
= DRO_OUTLINE
;
712 vPoint
[0].x
= vX
+ 1;
713 vPoint
[0].y
= m_vRclPaint
.yTop
- (vY
+ vHeight
) + 1;
714 vPoint
[1].x
= vX
+ vWidth
- 2;
715 vPoint
[1].y
= m_vRclPaint
.yTop
- (vY
+ 2);
716 ::GpiMove(m_hPS
, &vPoint
[0]);
724 } // end of wxDC::DoDrawRectangle
726 void wxDC::DoDrawRoundedRectangle(
738 vPoint
[0].y
= YLOG2DEV(vY
) - vHeight
;
739 vPoint
[1].x
= vX
+ vWidth
;
741 ::GpiMove(m_hPS
, &vPoint
[0]);
743 lControl
= DRO_OUTLINEFILL
; //DRO_FILL;
744 if (m_brush
.GetStyle() == wxTRANSPARENT
)
745 lControl
= DRO_OUTLINE
;
746 ::GpiBox( m_hPS
// handle to a presentation space
747 ,DRO_OUTLINE
// draw the box outline ? or ?
748 ,&vPoint
[1] // address of the corner
749 ,(LONG
)dRadius
// horizontal corner radius
750 ,(LONG
)dRadius
// vertical corner radius
752 } // end of wxDC::DoDrawRoundedRectangle
754 // Draw Ellipse within box (x,y) - (x+width, y+height)
755 void wxDC::DoDrawEllipse(
762 POINTL vPtlPos
; // Structure for current position
763 FIXED vFxMult
; // Multiplier for ellipse
764 ARCPARAMS vArcp
; // Structure for arc parameters
767 vArcp
.lQ
= vHeight
/2;
770 ::GpiSetArcParams( m_hPS
772 ); // Sets parameters to default
773 vPtlPos
.x
= vX
+ vWidth
/2; // Loads x-coordinate
774 vPtlPos
.y
= vY
+ vHeight
/2; // Loads y-coordinate
777 ); // Sets current position
778 vFxMult
= MAKEFIXED(1, 0); /* Sets multiplier */
781 // DRO_FILL, DRO_OTLINEFILL - where to get
786 ); // Draws full arc with center at current position
787 } // end of wxDC::DoDrawEllipse
789 void wxDC::DoDrawEllipticArc(
798 POINTL vPtlPos
; // Structure for current position
799 FIXED vFxMult
; // Multiplier for ellipse
800 ARCPARAMS vArcp
; // Structure for arc parameters
802 FIXED vFSweepa
; // Start angle, sweep angle
807 dFractPart
= modf(dSa
,&dIntPart
);
808 vFSa
= MAKEFIXED((int)dIntPart
, (int)(dFractPart
* 0xffff) );
809 dFractPart
= modf(dEa
- dSa
, &dIntPart
);
810 vFSweepa
= MAKEFIXED((int)dIntPart
, (int)(dFractPart
* 0xffff) );
813 // Ellipse main axis (r,q), (p,s) with center at (0,0)
816 vArcp
.lQ
= vHeight
/2;
819 ::GpiSetArcParams(m_hPS
, &vArcp
); // Sets parameters to default
820 vPtlPos
.x
= vX
+ vWidth
/2 * (1. + cos(DegToRad(dSa
))); // Loads x-coordinate
821 vPtlPos
.y
= vY
+ vHeight
/2 * (1. + sin(DegToRad(dSa
))); // Loads y-coordinate
822 ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position
825 // May be not to the center ?
827 vPtlPos
.x
= vX
+ vWidth
/2 ; // Loads x-coordinate
828 vPtlPos
.y
= vY
+ vHeight
/2; // Loads y-coordinate
829 vFxMult
= MAKEFIXED(1, 0); // Sets multiplier
832 // DRO_FILL, DRO_OTLINEFILL - where to get
834 ::GpiPartialArc( m_hPS
840 } // end of wxDC::DoDrawEllipticArc
842 void wxDC::DoDrawIcon(
848 wxCHECK_RET( rIcon
.Ok(), wxT("invalid icon in DrawIcon") );
850 ::WinDrawPointer( GetHPS()
853 ,(HPOINTER
)GetHiconOf(rIcon
)
856 } // end of wxDC::DoDrawIcon
858 void wxDC::DoDrawBitmap(
865 POINTL vPoint
= {vX
, vY
};
867 ::WinDrawBitmap( GetHPS()
868 ,(HBITMAP
)GetHbitmapOf(rBmp
)
875 } // end of wxDC::DoDrawBitmap
877 void wxDC::DoDrawText(
878 const wxString
& rsText
889 void wxDC::DrawAnyText(
890 const wxString
& rsText
895 int nOldBackground
= 0;
900 // prepare for drawing the text
904 // Set text color attributes
906 if (m_textForegroundColour
.Ok())
909 ,(int)m_textForegroundColour
.GetPixel()
913 if (m_textBackgroundColour
.Ok())
915 nOldBackground
= SetTextBkColor( m_hPS
916 ,(int)m_textBackgroundColour
.GetPixel()
925 lHits
= ::GpiCharStringAt( m_hPS
932 wxLogLastError(wxT("TextOut"));
936 // Restore the old parameters (text foreground colour may be left because
937 // it never is set to anything else, but background should remain
938 // transparent even if we just drew an opaque string)
940 if (m_textBackgroundColour
.Ok())
941 SetTextBkColor( m_hPS
949 void wxDC::DoDrawRotatedText(
950 const wxString
& rsText
968 DoDrawText(text, x, y);
973 wxFillLogFont(&lf, &m_font);
975 // GDI wants the angle in tenth of degree
976 long angle10 = (long)(angle * 10);
977 lf.lfEscapement = angle10;
978 lf. lfOrientation = angle10;
980 HFONT hfont = ::CreateFontIndirect(&lf);
983 wxLogLastError("CreateFont");
987 HFONT hfontOld = ::SelectObject(GetHdc(), hfont);
989 DrawAnyText(text, x, y);
991 (void)::SelectObject(GetHdc(), hfontOld);
994 // call the bounding box by adding all four vertices of the rectangle
995 // containing the text to it (simpler and probably not slower than
996 // determining which of them is really topmost/leftmost/...)
998 GetTextExtent(text, &w, &h);
1000 double rad = DegToRad(angle);
1002 // "upper left" and "upper right"
1003 CalcBoundingBox(x, y);
1004 CalcBoundingBox(x + w*cos(rad), y - h*sin(rad));
1005 CalcBoundingBox(x + h*sin(rad), y + h*cos(rad));
1007 // "bottom left" and "bottom right"
1008 x += (wxCoord)(h*sin(rad));
1009 y += (wxCoord)(h*cos(rad));
1010 CalcBoundingBox(x, y);
1011 CalcBoundingBox(x + h*sin(rad), y + h*cos(rad));
1016 // ---------------------------------------------------------------------------
1018 // ---------------------------------------------------------------------------
1020 void wxDC::SetPalette(const wxPalette
& palette
)
1030 // Set the old object temporarily, in case the assignment deletes an object
1031 // that's not yet selected out.
1043 m_font
.SetPS(m_hPS
); // this will realize the font
1047 HFONT hFont
= m_font
.GetResourceHandle();
1048 if (hFont
== (HFONT
) NULL
)
1050 wxLogDebug(wxT("::SelectObject failed in wxDC::SetFont."));
1053 m_hOldFont
= (WXHFONT
) hFont
;
1055 } // end of wxDC::SetFont
1061 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1077 m_pen
.SetPS((HPS
)m_hOldPen
);
1084 if (m_pen
.GetResourceHandle())
1088 m_hOldPen
= m_pen
.GetPS();
1093 void wxDC::SetBrush(
1094 const wxBrush
& rBrush
1097 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1099 if (m_brush
== rBrush
)
1113 m_brush
.SetPS((HPS
)m_hOldBrush
);
1120 if (m_brush
.GetResourceHandle())
1122 m_brush
.SetPS(m_hPS
);
1124 m_hOldBrush
= m_brush
.GetPS();
1127 } // end of wxDC::SetBrush
1129 void wxDC::SetBackground(const wxBrush
& brush
)
1134 void wxDC::SetBackgroundMode(
1138 m_backgroundMode
= nMode
;
1141 void wxDC::SetLogicalFunction(int function
)
1146 void wxDC::SetRop(WXHDC dc
)
1148 if (!dc
|| m_logicalFunction
< 0)
1152 // These may be wrong
1153 switch (m_logicalFunction
)
1155 // TODO: Figure this stuff out
1156 // case wxXOR: c_rop = R2_XORPEN; break;
1157 // case wxXOR: c_rop = R2_NOTXORPEN; break;
1158 // case wxINVERT: c_rop = R2_NOT; break;
1159 // case wxOR_REVERSE: c_rop = R2_MERGEPENNOT; break;
1160 // case wxAND_REVERSE: c_rop = R2_MASKPENNOT; break;
1161 // case wxCLEAR: c_rop = R2_WHITE; break;
1162 // case wxSET: c_rop = R2_BLACK; break;
1163 // case wxSRC_INVERT: c_rop = R2_NOTCOPYPEN; break;
1164 // case wxOR_INVERT: c_rop = R2_MERGENOTPEN; break;
1165 // case wxAND: c_rop = R2_MASKPEN; break;
1166 // case wxOR: c_rop = R2_MERGEPEN; break;
1167 // case wxAND_INVERT: c_rop = R2_MASKNOTPEN; break;
1172 // c_rop = R2_COPYPEN;
1175 // SetROP2((HDC) dc, c_rop);
1178 bool wxDC::StartDoc(const wxString
& message
)
1180 // We might be previewing, so return TRUE to let it continue.
1188 void wxDC::StartPage()
1192 void wxDC::EndPage()
1196 // ---------------------------------------------------------------------------
1198 // ---------------------------------------------------------------------------
1200 wxCoord
wxDC::GetCharHeight() const
1202 FONTMETRICS vFM
; // metrics structure
1204 ::GpiQueryFontMetrics( m_hPS
1205 ,sizeof(FONTMETRICS
)
1208 return YDEV2LOGREL(vFM
.lXHeight
);
1211 wxCoord
wxDC::GetCharWidth() const
1213 FONTMETRICS vFM
; // metrics structure
1215 ::GpiQueryFontMetrics( m_hPS
1216 ,sizeof(FONTMETRICS
)
1219 return XDEV2LOGREL(vFM
.lAveCharWidth
);
1222 void wxDC::DoGetTextExtent(
1223 const wxString
& rsString
1226 , wxCoord
* pvDescent
1227 , wxCoord
* pvExternalLeading
1231 POINTL avPoint
[TXTBOX_COUNT
];
1236 FONTMETRICS vFM
; // metrics structure
1239 ERRORID vErrorCode
; // last error id code
1240 wxFont
* pFontToUse
= (wxFont
*)pTheFont
;
1242 char zMsg
[128]; // DEBUG
1246 pFontToUse
= (wxFont
*)&m_font
;
1247 l
= rsString
.length();
1248 pStr
= (PCH
) rsString
.c_str();
1251 // In world coordinates.
1253 bRc
= ::GpiQueryTextBox( m_hPS
1256 ,TXTBOX_COUNT
// return maximum information
1257 ,avPoint
// array of coordinates points
1261 vErrorCode
= ::WinGetLastError(wxGetInstance());
1262 sError
= wxPMErrorToStr(vErrorCode
);
1264 sprintf(zMsg
, "GpiQueryTextBox for %s: failed with Error: %x - %s", pStr
, vErrorCode
, sError
.c_str());
1265 (void)wxMessageBox( "wxWindows Menu sample"
1271 vPtMin
.x
= avPoint
[0].x
;
1272 vPtMax
.x
= avPoint
[0].x
;
1273 vPtMin
.y
= avPoint
[0].y
;
1274 vPtMax
.y
= avPoint
[0].y
;
1275 for (i
= 1; i
< 4; i
++)
1277 if(vPtMin
.x
> avPoint
[i
].x
) vPtMin
.x
= avPoint
[i
].x
;
1278 if(vPtMin
.y
> avPoint
[i
].y
) vPtMin
.y
= avPoint
[i
].y
;
1279 if(vPtMax
.x
< avPoint
[i
].x
) vPtMax
.x
= avPoint
[i
].x
;
1280 if(vPtMax
.y
< avPoint
[i
].y
) vPtMax
.y
= avPoint
[i
].y
;
1282 ::GpiQueryFontMetrics( m_hPS
1283 ,sizeof(FONTMETRICS
)
1288 *pvX
= (wxCoord
)(vPtMax
.x
- vPtMin
.x
+ 1);
1290 *pvY
= (wxCoord
)(vPtMax
.y
- vPtMin
.y
+ 1);
1292 *pvDescent
= vFM
.lMaxDescender
;
1293 if (pvExternalLeading
)
1294 *pvExternalLeading
= vFM
.lExternalLeading
;
1297 void wxDC::SetMapMode( int mode
)
1302 void wxDC::SetUserScale(double x
, double y
)
1307 SetMapMode(m_mappingMode
);
1310 void wxDC::SetAxisOrientation(bool xLeftRight
, bool yBottomUp
)
1312 m_signX
= xLeftRight
? 1 : -1;
1313 m_signY
= yBottomUp
? -1 : 1;
1315 SetMapMode(m_mappingMode
);
1318 void wxDC::SetSystemScale(double x
, double y
)
1323 SetMapMode(m_mappingMode
);
1326 void wxDC::SetLogicalOrigin( wxCoord x
, wxCoord y
)
1331 void wxDC::SetDeviceOrigin(
1338 m_deviceOriginX
= x
;
1339 m_deviceOriginY
= y
;
1340 ::GpiQueryPageViewport( m_hPS
1347 ::GpiSetPageViewport( m_hPS
1352 // ---------------------------------------------------------------------------
1353 // coordinates transformations
1354 // ---------------------------------------------------------------------------
1356 wxCoord
wxDCBase::DeviceToLogicalX(wxCoord x
) const
1358 return (wxCoord
) (((x
) - m_deviceOriginX
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
) - m_logicalOriginX
);
1361 wxCoord
wxDCBase::DeviceToLogicalXRel(wxCoord x
) const
1363 return (wxCoord
) ((x
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
));
1366 wxCoord
wxDCBase::DeviceToLogicalY(wxCoord y
) const
1368 return (wxCoord
) (((y
) - m_deviceOriginY
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
) - m_logicalOriginY
);
1371 wxCoord
wxDCBase::DeviceToLogicalYRel(wxCoord y
) const
1373 return (wxCoord
) ((y
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
));
1376 wxCoord
wxDCBase::LogicalToDeviceX(wxCoord x
) const
1378 return (wxCoord
) ((x
- m_logicalOriginX
)*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
+ m_deviceOriginX
);
1381 wxCoord
wxDCBase::LogicalToDeviceXRel(wxCoord x
) const
1383 return (wxCoord
) (x
*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
);
1386 wxCoord
wxDCBase::LogicalToDeviceY(wxCoord y
) const
1388 return (wxCoord
) ((y
- m_logicalOriginY
)*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
+ m_deviceOriginY
);
1391 wxCoord
wxDCBase::LogicalToDeviceYRel(wxCoord y
) const
1393 return (wxCoord
) (y
*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
);
1396 // ---------------------------------------------------------------------------
1398 // ---------------------------------------------------------------------------
1412 wxMask
* pMask
= NULL
;
1414 COLORREF vOldTextColor
;
1415 COLORREF vOldBackground
= ::GpiQueryBackColor(m_hPS
);
1419 const wxBitmap
& rBmp
= pSource
->m_vSelectedBitmap
;
1421 pMask
= rBmp
.GetMask();
1422 if (!(rBmp
.Ok() && pMask
&& pMask
->GetMaskBitmap()))
1428 ::GpiQueryAttrs( m_hPS
1433 vOldTextColor
= (COLORREF
)vCbnd
.lColor
;
1435 if (m_textForegroundColour
.Ok())
1437 vCbnd
.lColor
= (LONG
)m_textForegroundColour
.GetPixel();
1438 ::GpiSetAttrs( m_hPS
// presentation-space handle
1439 ,PRIM_CHAR
// Char primitive.
1440 ,CBB_COLOR
// sets color.
1442 ,&vCbnd
// buffer for attributes.
1445 if (m_textBackgroundColour
.Ok())
1447 ::GpiSetBackColor(m_hPS
, (LONG
)m_textBackgroundColour
.GetPixel());
1450 LONG lRop
= ROP_SRCCOPY
;
1454 case wxXOR
: lRop
= ROP_SRCINVERT
; break;
1455 case wxINVERT
: lRop
= ROP_DSTINVERT
; break;
1456 case wxOR_REVERSE
: lRop
= 0x00DD0228; break;
1457 case wxAND_REVERSE
: lRop
= ROP_SRCERASE
; break;
1458 case wxCLEAR
: lRop
= ROP_ZERO
; break;
1459 case wxSET
: lRop
= ROP_ONE
; break;
1460 case wxOR_INVERT
: lRop
= ROP_MERGEPAINT
; break;
1461 case wxAND
: lRop
= ROP_SRCAND
; break;
1462 case wxOR
: lRop
= ROP_SRCPAINT
; break;
1463 case wxEQUIV
: lRop
= 0x00990066; break;
1464 case wxNAND
: lRop
= 0x007700E6; break;
1465 case wxAND_INVERT
: lRop
= 0x00220326; break;
1466 case wxCOPY
: lRop
= ROP_SRCCOPY
; break;
1467 case wxNO_OP
: lRop
= ROP_NOTSRCERASE
; break;
1468 case wxSRC_INVERT
: lRop
= ROP_SRCINVERT
; break;
1469 case wxNOR
: lRop
= ROP_NOTSRCCOPY
; break;
1471 wxFAIL_MSG( wxT("unsupported logical function") );
1480 // Blit bitmap with mask
1484 // Create a temp buffer bitmap and DCs/PSs to access it and the mask
1490 DEVOPENSTRUC vDOP
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1491 BITMAPINFOHEADER2 vBmpHdr
;
1492 SIZEL vSize
= {0, 0};
1495 hDCMask
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDOP
, NULLHANDLE
);
1496 hDCBuffer
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDOP
, NULLHANDLE
);
1497 hPSMask
= ::GpiCreatePS(vHabmain
, hDCMask
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
1498 hPSBuffer
= ::GpiCreatePS(vHabmain
, hDCBuffer
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
1500 memset(&vBmpHdr
, 0, sizeof(BITMAPINFOHEADER2
));
1501 vBmpHdr
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1502 vBmpHdr
.cx
= vWidth
;
1503 vBmpHdr
.cy
= vHeight
;
1504 vBmpHdr
.cPlanes
= 1;
1505 vBmpHdr
.cBitCount
= 24;
1507 HBITMAP hBufBitmap
= ::GpiCreateBitmap(GetHPS(), &vBmpHdr
, 0L, NULL
, NULL
);
1508 POINTL aPoint1
[4] = { 0, 0
1511 ,vXdest
+ vWidth
, vYdest
+ vHeight
1513 POINTL aPoint2
[4] = { 0, 0
1516 ,vXsrc
+ vWidth
, vYsrc
+ vHeight
1518 POINTL aPoint3
[4] = { vXdest
, vYdest
1519 ,vXdest
+ vWidth
, vYdest
+ vHeight
1521 ,vXsrc
+ vWidth
, vYsrc
+ vHeight
1523 POINTL aPoint4
[4] = { vXdest
, vYdest
1524 ,vXdest
+ vWidth
, vYdest
+ vHeight
1528 ::GpiSetBitmap(hPSMask
, (HBITMAP
) pMask
->GetMaskBitmap());
1529 ::GpiSetBitmap(hPSBuffer
, (HBITMAP
) hBufBitmap
);
1532 // Copy dest to buffer
1534 rc
= ::GpiBitBlt( hPSBuffer
1541 if (rc
== GPI_ERROR
)
1543 wxLogLastError(wxT("BitBlt"));
1547 // Copy src to buffer using selected raster op
1549 rc
= ::GpiBitBlt( hPSBuffer
1556 if (rc
== GPI_ERROR
)
1558 wxLogLastError(wxT("BitBlt"));
1562 // Set masked area in buffer to BLACK (pixel value 0)
1564 COLORREF vPrevBkCol
= ::GpiQueryBackColor(GetHPS());
1565 COLORREF vPrevCol
= ::GpiQueryColor(GetHPS());
1567 ::GpiSetBackColor(GetHPS(), OS2RGB(255, 255, 255));
1568 ::GpiSetColor(GetHPS(), OS2RGB(0, 0, 0));
1570 rc
= ::GpiBitBlt( hPSBuffer
1577 if (rc
== GPI_ERROR
)
1579 wxLogLastError(wxT("BitBlt"));
1583 // Set unmasked area in dest to BLACK
1585 ::GpiSetBackColor(GetHPS(), OS2RGB(0, 0, 0));
1586 ::GpiSetColor(GetHPS(), OS2RGB(255, 255, 255));
1587 rc
= ::GpiBitBlt( GetHPS()
1594 if (rc
== GPI_ERROR
)
1596 wxLogLastError(wxT("BitBlt"));
1600 // Restore colours to original values
1602 ::GpiSetBackColor(GetHPS(), vPrevBkCol
);
1603 ::GpiSetColor(GetHPS(), vPrevCol
);
1606 // OR buffer to dest
1608 rc
= ::GpiBitBlt( GetHPS()
1615 if (rc
== GPI_ERROR
)
1618 wxLogLastError(wxT("BitBlt"));
1622 // Tidy up temporary DCs and bitmap
1624 ::GpiSetBitmap(hPSMask
, NULLHANDLE
);
1625 ::GpiSetBitmap(hPSBuffer
, NULLHANDLE
);
1626 ::GpiDestroyPS(hPSMask
);
1627 ::GpiDestroyPS(hPSBuffer
);
1628 ::DevCloseDC(hDCMask
);
1629 ::DevCloseDC(hDCBuffer
);
1630 ::GpiDeleteBitmap(hBufBitmap
);
1633 else // no mask, just BitBlt() it
1635 POINTL aPoint
[4] = { vXdest
, vYdest
1636 ,vXdest
+ vWidth
, vYdest
+ vHeight
1638 ,vXsrc
+ vWidth
, vYsrc
+ vHeight
1641 bSuccess
= (::GpiBitBlt( m_hPS
1650 wxLogLastError(wxT("BitBlt"));
1653 vCbnd
.lColor
= (LONG
)vOldTextColor
;
1654 ::GpiSetAttrs( m_hPS
// presentation-space handle
1655 ,PRIM_CHAR
// Char primitive.
1656 ,CBB_COLOR
// sets color.
1658 ,&vCbnd
// buffer for attributes.
1660 ::GpiSetBackColor(m_hPS
, (LONG
)vOldBackground
);
1664 void wxDC::DoGetSize( int* width
, int* height
) const
1669 void wxDC::DoGetSizeMM( int* width
, int* height
) const
1674 wxSize
wxDC::GetPPI() const
1679 return (wxSize(x
,y
));
1682 void wxDC::SetLogicalScale( double x
, double y
)
1687 #if WXWIN_COMPATIBILITY
1688 void wxDC::DoGetTextExtent(const wxString
& string
, float *x
, float *y
,
1689 float *descent
, float *externalLeading
,
1690 wxFont
*theFont
, bool use16bit
) const
1692 wxCoord x1
, y1
, descent1
, externalLeading1
;
1693 GetTextExtent(string
, & x1
, & y1
, & descent1
, & externalLeading1
, theFont
, use16bit
);
1696 *descent
= descent1
;
1697 if (externalLeading
)
1698 *externalLeading
= externalLeading1
;