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(
168 ::GpiSetBitmap(hPS
, (HBITMAP
) m_hOldBitmap
);
169 if (m_vSelectedBitmap
.Ok())
171 m_vSelectedBitmap
.SetSelectedInto(NULL
);
176 // OS/2 has no other native GDI objects to set in a PS/DC like windows
184 m_brush
= wxNullBrush
;
186 m_palette
= wxNullPalette
;
188 m_backgroundBrush
= wxNullBrush
;
189 m_vSelectedBitmap
= wxNullBitmap
;
192 // ---------------------------------------------------------------------------
194 // ---------------------------------------------------------------------------
196 #define DO_SET_CLIPPING_BOX() \
200 ::GpiQueryClipBox(m_hPS, &rect); \
202 m_clipX1 = (wxCoord) XDEV2LOG(rect.xLeft); \
203 m_clipY1 = (wxCoord) YDEV2LOG(rect.yTop); \
204 m_clipX2 = (wxCoord) XDEV2LOG(rect.xRight); \
205 m_clipY2 = (wxCoord) YDEV2LOG(rect.yBottom); \
208 void wxDC::DoSetClippingRegion(
218 vRect
.xLeft
= XLOG2DEV(x
);
219 vRect
.yTop
= YLOG2DEV(m_vRclPaint
.yTop
- y
);
220 vRect
.xRight
= XLOG2DEV(x
+ width
);
221 vRect
.yBottom
= YLOG2DEV(m_vRclPaint
.yTop
- (y
+ height
));
222 ::GpiIntersectClipRectangle(m_hPS
, &vRect
);
223 DO_SET_CLIPPING_BOX()
224 } // end of wxDC::DoSetClippingRegion
226 void wxDC::DoSetClippingRegionAsRegion(
227 const wxRegion
& rRegion
230 wxCHECK_RET(rRegion
.GetHRGN(), wxT("invalid clipping region"));
234 ::GpiSetClipRegion( m_hPS
235 ,(HRGN
)rRegion
.GetHRGN()
238 DO_SET_CLIPPING_BOX()
239 } // end of wxDC::DoSetClippingRegionAsRegion
241 void wxDC::DestroyClippingRegion(void)
243 if (m_clipping
&& m_hPS
)
248 // TODO: this should restore the previous clipped region
249 // so that OnPaint processing works correctly, and
250 // the update doesn't get destroyed after the first
251 // DestroyClippingRegion
252 vRect
.xLeft
= XLOG2DEV(0);
253 vRect
.yTop
= YLOG2DEV(32000);
254 vRect
.xRight
= XLOG2DEV(32000);
255 vRect
.yBottom
= YLOG2DEV(0);
257 HRGN hRgn
= ::GpiCreateRegion(m_hPS
, 1, &vRect
);
259 ::GpiSetClipRegion(m_hPS
, hRgn
, &hRgnOld
);
262 } // end of wxDC::DestroyClippingRegion
264 // ---------------------------------------------------------------------------
265 // query capabilities
266 // ---------------------------------------------------------------------------
268 bool wxDC::CanDrawBitmap() const
273 bool wxDC::CanGetTextExtent() const
275 LONG lTechnology
= 0L;
277 ::DevQueryCaps(GetHDC(), CAPS_TECHNOLOGY
, 1L, &lTechnology
);
278 return (lTechnology
== CAPS_TECH_RASTER_DISPLAY
) || (lTechnology
== CAPS_TECH_RASTER_PRINTER
);
279 } // end of wxDC::CanGetTextExtent
281 int wxDC::GetDepth() const
283 LONG lArray
[CAPS_COLOR_BITCOUNT
];
286 if(::DevQueryCaps( GetHDC()
292 nBitsPerPixel
= (int)lArray
[CAPS_COLOR_BITCOUNT
];
294 return nBitsPerPixel
;
295 } // end of wxDC::GetDepth
297 // ---------------------------------------------------------------------------
299 // ---------------------------------------------------------------------------
306 void wxDC::DoFloodFill(
309 , const wxColour
& rCol
317 vPtlPos
.x
= vX
; // Loads x-coordinate
318 vPtlPos
.y
= vY
; // Loads y-coordinate
319 ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position
320 lColor
= rCol
.GetPixel();
321 lOptions
= FF_BOUNDARY
;
322 if(wxFLOOD_SURFACE
== nStyle
)
323 lOptions
= FF_SURFACE
;
325 ::GpiFloodFill(m_hPS
, lOptions
, lColor
);
328 bool wxDC::DoGetPixel(
339 lColor
= ::GpiSetPel(m_hPS
, &vPoint
);
340 pCol
->Set((unsigned long)lColor
);
347 void wxDC::DoCrossHair(
352 wxCoord vX1
= vX
- VIEWPORT_EXTENT
;
353 wxCoord vY1
= vY
- VIEWPORT_EXTENT
;
354 wxCoord vX2
= vX
+ VIEWPORT_EXTENT
;
355 wxCoord vY2
= vY
+ VIEWPORT_EXTENT
;
359 vPoint
[0].y
= m_vRclPaint
.yTop
- vY
;
362 vPoint
[1].y
= m_vRclPaint
.yTop
- vY
;
364 ::GpiMove(m_hPS
, &vPoint
[0]);
365 ::GpiLine(m_hPS
, &vPoint
[1]);
368 vPoint
[2].y
= m_vRclPaint
.yTop
- vY1
;
371 vPoint
[3].y
= m_vRclPaint
.yTop
- vY2
;
373 ::GpiMove(m_hPS
, &vPoint
[2]);
374 ::GpiLine(m_hPS
, &vPoint
[3]);
375 } // end of wxDC::DoCrossHair
377 void wxDC::DoDrawLine(
387 vPoint
[0].y
= m_vRclPaint
.yTop
- vY1
;
389 vPoint
[1].y
= m_vRclPaint
.yTop
- vY2
;
390 ::GpiMove(m_hPS
, &vPoint
[0]);
391 ::GpiLine(m_hPS
, &vPoint
[1]);
392 } // end of wxDC::DoDrawLine
394 //////////////////////////////////////////////////////////////////////////////
395 // Draws an arc of a circle, centred on (xc, yc), with starting point (x1, y1)
396 // and ending at (x2, y2). The current pen is used for the outline and the
397 // current brush for filling the shape. The arc is drawn in an anticlockwise
398 // direction from the start point to the end point.
399 //////////////////////////////////////////////////////////////////////////////
400 void wxDC::DoDrawArc(
410 POINTL vPtlArc
[2]; // Structure for current position
419 ARCPARAMS vArcp
; // Structure for arc parameters
421 if((vX1
== vXc
&& vY1
== vXc
) || (vX2
== vXc
&& vY2
== vXc
))
422 return; // Draw point ??
423 dRadius
= 0.5 * ( hypot( (double)(vY1
- vYc
)
426 hypot( (double)(vY2
- vYc
)
431 dAngl1
= atan2( (double)(vY1
- vYc
)
434 dAngl2
= atan2( (double)(vY2
- vYc
)
441 // GpiPointArc can't draw full arc
443 if(dAngl2
== dAngl1
|| (vX1
== vX2
&& vY1
== vY2
) )
448 dAnglmid
= (dAngl1
+ dAngl2
)/2. + M_PI
;
449 vXm
= vXc
+ dRadius
* cos(dAnglmid
);
450 vYm
= vYc
+ dRadius
* sin(dAnglmid
);
465 dAnglmid
= (dAngl1
+ dAngl2
)/2.;
466 vXm
= vXc
+ dRadius
* cos(dAnglmid
);
467 vYm
= vYc
+ dRadius
* sin(dAnglmid
);
470 // Ellipse main axis (r,q), (p,s) with center at (0,0) */
476 ::GpiSetArcParams(m_hPS
, &vArcp
); // Sets parameters to default
478 vPtlPos
.x
= vX1
; // Loads x-coordinate
479 vPtlPos
.y
= vY1
; // Loads y-coordinate
480 ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position
485 ::GpiPointArc(m_hPS
, vPtlArc
); // Draws the arc
486 } // end of wxDC::DoDrawArc
488 void wxDC::DoDrawCheckMark(
499 vPoint
[1].x
= vX1
+ vWidth
;
500 vPoint
[1].y
= vY1
+ vHeight
;
502 ::GpiMove(m_hPS
, &vPoint
[0]);
503 ::GpiBox( m_hPS
// handle to a presentation space
504 ,DRO_OUTLINE
// draw the box outline ? or ?
505 ,&vPoint
[1] // address of the corner
506 ,0L // horizontal corner radius
507 ,0L // vertical corner radius
509 if(vWidth
> 4 && vHeight
> 4)
513 vPoint
[0].x
+= 2; vPoint
[0].y
+= 2;
514 vPoint
[1].x
-= 2; vPoint
[1].y
-= 2;
515 ::GpiMove(m_hPS
, &vPoint
[0]);
516 ::GpiLine(m_hPS
, &vPoint
[1]);
518 vPoint
[0].x
= vPoint
[1].x
;
520 ::GpiMove(m_hPS
, &vPoint
[0]);
521 ::GpiLine(m_hPS
, &vPoint
[1]);
523 } // end of wxDC::DoDrawCheckMark
525 void wxDC::DoDrawPoint(
533 vPoint
.y
= m_vRclPaint
.yTop
- vY
;
534 ::GpiSetPel(m_hPS
, &vPoint
);
535 } // end of wxDC::DoDrawPoint
537 void wxDC::DoDrawPolygon(
545 ULONG ulCount
= 1; // Number of polygons.
546 POLYGON vPlgn
; // polygon.
547 ULONG flOptions
= 0L; // Drawing options.
549 //////////////////////////////////////////////////////////////////////////////
550 // This contains fields of option bits... to draw boundary lines as well as
551 // the area interior.
553 // Drawing boundary lines:
554 // POLYGON_NOBOUNDARY Does not draw boundary lines.
555 // POLYGON_BOUNDARY Draws boundary lines (the default).
557 // Construction of the area interior:
558 // POLYGON_ALTERNATE Constructs interior in alternate mode
560 // POLYGON_WINDING Constructs interior in winding mode.
561 //////////////////////////////////////////////////////////////////////////////
563 ULONG flModel
= 0L; // Drawing model.
565 //////////////////////////////////////////////////////////////////////////////
567 // POLYGON_INCL Fill is inclusive of bottom right (the default).
568 // POLYGON_EXCL Fill is exclusive of bottom right.
569 // This is provided to aid migration from other graphics models.
570 //////////////////////////////////////////////////////////////////////////////
572 LONG lHits
= 0L; // Correlation/error indicator.
575 int nIsTRANSPARENT
= 0;
576 LONG lBorderColor
= 0L;
579 lBorderColor
= m_pen
.GetColour().GetPixel();
580 lColor
= m_brush
.GetColour().GetPixel();
581 if(m_brush
.GetStyle() == wxTRANSPARENT
)
585 vPlgn
.aPointl
= (POINTL
*) calloc( n
+ 1
587 ); // well, new will call malloc
589 for(i
= 0; i
< n
; i
++)
591 vPlgn
.aPointl
[i
].x
= vPoints
[i
].x
; // +xoffset;
592 vPlgn
.aPointl
[i
].y
= vPoints
[i
].y
; // +yoffset;
594 flModel
= POLYGON_BOUNDARY
;
595 if(nFillStyle
== wxWINDING_RULE
)
596 flModel
|= POLYGON_WINDING
;
598 flModel
|= POLYGON_ALTERNATE
;
603 ::GpiSetColor(m_hPS
, lBorderColor
);
604 ::GpiMove(m_hPS
, &vPoint
);
605 lHits
= ::GpiPolygons(m_hPS
, ulCount
, &vPlgn
, flOptions
, flModel
);
607 } // end of wxDC::DoDrawPolygon
609 void wxDC::DoDrawLines(
619 vPoint
.x
= vPoints
[0].x
+ vXoffset
;
620 vPoint
.y
= vPoints
[0].y
+ vYoffset
;
621 ::GpiMove(m_hPS
, &vPoint
);
623 LONG lBorderColor
= m_pen
.GetColour().GetPixel();
625 ::GpiSetColor(m_hPS
, lBorderColor
);
626 for(i
= 1; i
< n
; i
++)
628 vPoint
.x
= vPoints
[0].x
+ vXoffset
;
629 vPoint
.y
= vPoints
[0].y
+ vYoffset
;
630 ::GpiLine(m_hPS
, &vPoint
);
632 } // end of wxDC::DoDrawLines
634 void wxDC::DoDrawRectangle(
645 int nIsTRANSPARENT
= 0;
648 vPoint
[0].y
= m_vRclPaint
.yTop
- (vY
+ vHeight
);
649 vPoint
[1].x
= vX
+ vWidth
;
650 vPoint
[1].y
= m_vRclPaint
.yTop
- vY
;
651 ::GpiMove(m_hPS
, &vPoint
[0]);
652 lColor
= m_brush
.GetColour().GetPixel();
653 lBorderColor
= m_pen
.GetColour().GetPixel();
654 if (m_brush
.GetStyle() == wxTRANSPARENT
)
656 if(lColor
== lBorderColor
|| nIsTRANSPARENT
)
658 lControl
= DRO_OUTLINEFILL
; //DRO_FILL;
659 if(m_brush
.GetStyle() == wxTRANSPARENT
)
660 lControl
= DRO_OUTLINE
;
662 ::GpiSetColor(m_hPS
, lColor
);
663 ::GpiBox( m_hPS
// handle to a presentation space
664 ,lControl
// draw the box outline ? or ?
665 ,&vPoint
[1] // address of the corner
666 ,0L // horizontal corner radius
667 ,0L // vertical corner radius
672 lControl
= DRO_OUTLINE
;
686 vPoint
[0].x
= vX
+ 1;
687 vPoint
[0].y
= m_vRclPaint
.yTop
- (vY
+ vHeight
) + 1;
688 vPoint
[1].x
= vX
+ vWidth
- 2;
689 vPoint
[1].y
= m_vRclPaint
.yTop
- (vY
+ 2);
690 ::GpiMove(m_hPS
, &vPoint
[0]);
698 } // end of wxDC::DoDrawRectangle
700 void wxDC::DoDrawRoundedRectangle(
712 vPoint
[0].y
= YLOG2DEV(vY
) - vHeight
;
713 vPoint
[1].x
= vX
+ vWidth
;
715 ::GpiMove(m_hPS
, &vPoint
[0]);
717 lControl
= DRO_OUTLINEFILL
; //DRO_FILL;
718 if (m_brush
.GetStyle() == wxTRANSPARENT
)
719 lControl
= DRO_OUTLINE
;
720 ::GpiBox( m_hPS
// handle to a presentation space
721 ,DRO_OUTLINE
// draw the box outline ? or ?
722 ,&vPoint
[1] // address of the corner
723 ,(LONG
)dRadius
// horizontal corner radius
724 ,(LONG
)dRadius
// vertical corner radius
726 } // end of wxDC::DoDrawRoundedRectangle
728 // Draw Ellipse within box (x,y) - (x+width, y+height)
729 void wxDC::DoDrawEllipse(
736 POINTL vPtlPos
; // Structure for current position
737 FIXED vFxMult
; // Multiplier for ellipse
738 ARCPARAMS vArcp
; // Structure for arc parameters
741 vArcp
.lQ
= vHeight
/2;
744 ::GpiSetArcParams( m_hPS
746 ); // Sets parameters to default
747 vPtlPos
.x
= vX
+ vWidth
/2; // Loads x-coordinate
748 vPtlPos
.y
= vY
+ vHeight
/2; // Loads y-coordinate
751 ); // Sets current position
752 vFxMult
= MAKEFIXED(1, 0); /* Sets multiplier */
755 // DRO_FILL, DRO_OTLINEFILL - where to get
760 ); // Draws full arc with center at current position
761 } // end of wxDC::DoDrawEllipse
763 void wxDC::DoDrawEllipticArc(
772 POINTL vPtlPos
; // Structure for current position
773 FIXED vFxMult
; // Multiplier for ellipse
774 ARCPARAMS vArcp
; // Structure for arc parameters
776 FIXED vFSweepa
; // Start angle, sweep angle
781 dFractPart
= modf(dSa
,&dIntPart
);
782 vFSa
= MAKEFIXED((int)dIntPart
, (int)(dFractPart
* 0xffff) );
783 dFractPart
= modf(dEa
- dSa
, &dIntPart
);
784 vFSweepa
= MAKEFIXED((int)dIntPart
, (int)(dFractPart
* 0xffff) );
787 // Ellipse main axis (r,q), (p,s) with center at (0,0)
790 vArcp
.lQ
= vHeight
/2;
793 ::GpiSetArcParams(m_hPS
, &vArcp
); // Sets parameters to default
794 vPtlPos
.x
= vX
+ vWidth
/2 * (1. + cos(DegToRad(dSa
))); // Loads x-coordinate
795 vPtlPos
.y
= vY
+ vHeight
/2 * (1. + sin(DegToRad(dSa
))); // Loads y-coordinate
796 ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position
799 // May be not to the center ?
801 vPtlPos
.x
= vX
+ vWidth
/2 ; // Loads x-coordinate
802 vPtlPos
.y
= vY
+ vHeight
/2; // Loads y-coordinate
803 vFxMult
= MAKEFIXED(1, 0); // Sets multiplier
806 // DRO_FILL, DRO_OTLINEFILL - where to get
808 ::GpiPartialArc( m_hPS
814 } // end of wxDC::DoDrawEllipticArc
816 void wxDC::DoDrawIcon(
822 wxCHECK_RET( rIcon
.Ok(), wxT("invalid icon in DrawIcon") );
824 ::WinDrawPointer( GetHPS()
827 ,(HPOINTER
)GetHiconOf(rIcon
)
830 } // end of wxDC::DoDrawIcon
832 void wxDC::DoDrawBitmap(
839 POINTL vPoint
= {vX
, vY
};
841 ::WinDrawBitmap( GetHPS()
842 ,(HBITMAP
)GetHbitmapOf(rBmp
)
849 } // end of wxDC::DoDrawBitmap
851 void wxDC::DoDrawText(
852 const wxString
& rsText
863 void wxDC::DrawAnyText(
864 const wxString
& rsText
869 int nOldBackground
= 0;
874 // prepare for drawing the text
878 // Set text color attributes
880 if (m_textForegroundColour
.Ok())
883 ,(int)m_textForegroundColour
.GetPixel()
887 if (m_textBackgroundColour
.Ok())
889 nOldBackground
= SetTextBkColor( m_hPS
890 ,(int)m_textBackgroundColour
.GetPixel()
899 lHits
= ::GpiCharStringAt( m_hPS
906 wxLogLastError(wxT("TextOut"));
910 // Restore the old parameters (text foreground colour may be left because
911 // it never is set to anything else, but background should remain
912 // transparent even if we just drew an opaque string)
914 if (m_textBackgroundColour
.Ok())
915 SetTextBkColor( m_hPS
923 void wxDC::DoDrawRotatedText(
924 const wxString
& rsText
942 DoDrawText(text, x, y);
947 wxFillLogFont(&lf, &m_font);
949 // GDI wants the angle in tenth of degree
950 long angle10 = (long)(angle * 10);
951 lf.lfEscapement = angle10;
952 lf. lfOrientation = angle10;
954 HFONT hfont = ::CreateFontIndirect(&lf);
957 wxLogLastError("CreateFont");
961 HFONT hfontOld = ::SelectObject(GetHdc(), hfont);
963 DrawAnyText(text, x, y);
965 (void)::SelectObject(GetHdc(), hfontOld);
968 // call the bounding box by adding all four vertices of the rectangle
969 // containing the text to it (simpler and probably not slower than
970 // determining which of them is really topmost/leftmost/...)
972 GetTextExtent(text, &w, &h);
974 double rad = DegToRad(angle);
976 // "upper left" and "upper right"
977 CalcBoundingBox(x, y);
978 CalcBoundingBox(x + w*cos(rad), y - h*sin(rad));
979 CalcBoundingBox(x + h*sin(rad), y + h*cos(rad));
981 // "bottom left" and "bottom right"
982 x += (wxCoord)(h*sin(rad));
983 y += (wxCoord)(h*cos(rad));
984 CalcBoundingBox(x, y);
985 CalcBoundingBox(x + h*sin(rad), y + h*cos(rad));
990 // ---------------------------------------------------------------------------
992 // ---------------------------------------------------------------------------
994 void wxDC::SetPalette(const wxPalette
& palette
)
1004 // Set the old object temporarily, in case the assignment deletes an object
1005 // that's not yet selected out.
1017 m_font
.SetPS(m_hPS
); // this will realize the font
1021 HFONT hFont
= m_font
.GetResourceHandle();
1022 if (hFont
== (HFONT
) NULL
)
1024 wxLogDebug(wxT("::SelectObject failed in wxDC::SetFont."));
1027 m_hOldFont
= (WXHFONT
) hFont
;
1029 } // end of wxDC::SetFont
1035 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1051 m_pen
.SetPS((HPS
)m_hOldPen
);
1058 if (m_pen
.GetResourceHandle())
1062 m_hOldPen
= m_pen
.GetPS();
1067 void wxDC::SetBrush(
1068 const wxBrush
& rBrush
1071 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1073 if (m_brush
== rBrush
)
1087 m_brush
.SetPS((HPS
)m_hOldBrush
);
1094 if (m_brush
.GetResourceHandle())
1096 m_brush
.SetPS(m_hPS
);
1098 m_hOldBrush
= m_brush
.GetPS();
1101 } // end of wxDC::SetBrush
1103 void wxDC::SetBackground(const wxBrush
& brush
)
1108 void wxDC::SetBackgroundMode(
1112 m_backgroundMode
= nMode
;
1115 void wxDC::SetLogicalFunction(int function
)
1120 void wxDC::SetRop(WXHDC dc
)
1122 if (!dc
|| m_logicalFunction
< 0)
1126 // These may be wrong
1127 switch (m_logicalFunction
)
1129 // TODO: Figure this stuff out
1130 // case wxXOR: c_rop = R2_XORPEN; break;
1131 // case wxXOR: c_rop = R2_NOTXORPEN; break;
1132 // case wxINVERT: c_rop = R2_NOT; break;
1133 // case wxOR_REVERSE: c_rop = R2_MERGEPENNOT; break;
1134 // case wxAND_REVERSE: c_rop = R2_MASKPENNOT; break;
1135 // case wxCLEAR: c_rop = R2_WHITE; break;
1136 // case wxSET: c_rop = R2_BLACK; break;
1137 // case wxSRC_INVERT: c_rop = R2_NOTCOPYPEN; break;
1138 // case wxOR_INVERT: c_rop = R2_MERGENOTPEN; break;
1139 // case wxAND: c_rop = R2_MASKPEN; break;
1140 // case wxOR: c_rop = R2_MERGEPEN; break;
1141 // case wxAND_INVERT: c_rop = R2_MASKNOTPEN; break;
1146 // c_rop = R2_COPYPEN;
1149 // SetROP2((HDC) dc, c_rop);
1152 bool wxDC::StartDoc(const wxString
& message
)
1154 // We might be previewing, so return TRUE to let it continue.
1162 void wxDC::StartPage()
1166 void wxDC::EndPage()
1170 // ---------------------------------------------------------------------------
1172 // ---------------------------------------------------------------------------
1174 wxCoord
wxDC::GetCharHeight() const
1176 FONTMETRICS vFM
; // metrics structure
1178 ::GpiQueryFontMetrics( m_hPS
1179 ,sizeof(FONTMETRICS
)
1182 return YDEV2LOGREL(vFM
.lXHeight
);
1185 wxCoord
wxDC::GetCharWidth() const
1187 FONTMETRICS vFM
; // metrics structure
1189 ::GpiQueryFontMetrics( m_hPS
1190 ,sizeof(FONTMETRICS
)
1193 return XDEV2LOGREL(vFM
.lAveCharWidth
);
1196 void wxDC::DoGetTextExtent(
1197 const wxString
& rsString
1200 , wxCoord
* pvDescent
1201 , wxCoord
* pvExternalLeading
1205 POINTL avPoint
[TXTBOX_COUNT
];
1210 FONTMETRICS vFM
; // metrics structure
1213 ERRORID vErrorCode
; // last error id code
1214 wxFont
* pFontToUse
= (wxFont
*)pTheFont
;
1216 char zMsg
[128]; // DEBUG
1220 pFontToUse
= (wxFont
*)&m_font
;
1221 l
= rsString
.length();
1222 pStr
= (PCH
) rsString
.c_str();
1225 // In world coordinates.
1227 bRc
= ::GpiQueryTextBox( m_hPS
1230 ,TXTBOX_COUNT
// return maximum information
1231 ,avPoint
// array of coordinates points
1235 vErrorCode
= ::WinGetLastError(wxGetInstance());
1236 sError
= wxPMErrorToStr(vErrorCode
);
1238 sprintf(zMsg
, "GpiQueryTextBox for %s: failed with Error: %x - %s", pStr
, vErrorCode
, sError
.c_str());
1239 (void)wxMessageBox( "wxWindows Menu sample"
1245 vPtMin
.x
= avPoint
[0].x
;
1246 vPtMax
.x
= avPoint
[0].x
;
1247 vPtMin
.y
= avPoint
[0].y
;
1248 vPtMax
.y
= avPoint
[0].y
;
1249 for (i
= 1; i
< 4; i
++)
1251 if(vPtMin
.x
> avPoint
[i
].x
) vPtMin
.x
= avPoint
[i
].x
;
1252 if(vPtMin
.y
> avPoint
[i
].y
) vPtMin
.y
= avPoint
[i
].y
;
1253 if(vPtMax
.x
< avPoint
[i
].x
) vPtMax
.x
= avPoint
[i
].x
;
1254 if(vPtMax
.y
< avPoint
[i
].y
) vPtMax
.y
= avPoint
[i
].y
;
1256 ::GpiQueryFontMetrics( m_hPS
1257 ,sizeof(FONTMETRICS
)
1262 *pvX
= (wxCoord
)(vPtMax
.x
- vPtMin
.x
+ 1);
1264 *pvY
= (wxCoord
)(vPtMax
.y
- vPtMin
.y
+ 1);
1266 *pvDescent
= vFM
.lMaxDescender
;
1267 if (pvExternalLeading
)
1268 *pvExternalLeading
= vFM
.lExternalLeading
;
1271 void wxDC::SetMapMode( int mode
)
1276 void wxDC::SetUserScale(double x
, double y
)
1281 SetMapMode(m_mappingMode
);
1284 void wxDC::SetAxisOrientation(bool xLeftRight
, bool yBottomUp
)
1286 m_signX
= xLeftRight
? 1 : -1;
1287 m_signY
= yBottomUp
? -1 : 1;
1289 SetMapMode(m_mappingMode
);
1292 void wxDC::SetSystemScale(double x
, double y
)
1297 SetMapMode(m_mappingMode
);
1300 void wxDC::SetLogicalOrigin( wxCoord x
, wxCoord y
)
1305 void wxDC::SetDeviceOrigin(
1312 m_deviceOriginX
= x
;
1313 m_deviceOriginY
= y
;
1314 ::GpiQueryPageViewport( m_hPS
1321 ::GpiSetPageViewport( m_hPS
1326 // ---------------------------------------------------------------------------
1327 // coordinates transformations
1328 // ---------------------------------------------------------------------------
1330 wxCoord
wxDCBase::DeviceToLogicalX(wxCoord x
) const
1332 return (wxCoord
) (((x
) - m_deviceOriginX
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
) - m_logicalOriginX
);
1335 wxCoord
wxDCBase::DeviceToLogicalXRel(wxCoord x
) const
1337 return (wxCoord
) ((x
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
));
1340 wxCoord
wxDCBase::DeviceToLogicalY(wxCoord y
) const
1342 return (wxCoord
) (((y
) - m_deviceOriginY
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
) - m_logicalOriginY
);
1345 wxCoord
wxDCBase::DeviceToLogicalYRel(wxCoord y
) const
1347 return (wxCoord
) ((y
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
));
1350 wxCoord
wxDCBase::LogicalToDeviceX(wxCoord x
) const
1352 return (wxCoord
) ((x
- m_logicalOriginX
)*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
+ m_deviceOriginX
);
1355 wxCoord
wxDCBase::LogicalToDeviceXRel(wxCoord x
) const
1357 return (wxCoord
) (x
*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
);
1360 wxCoord
wxDCBase::LogicalToDeviceY(wxCoord y
) const
1362 return (wxCoord
) ((y
- m_logicalOriginY
)*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
+ m_deviceOriginY
);
1365 wxCoord
wxDCBase::LogicalToDeviceYRel(wxCoord y
) const
1367 return (wxCoord
) (y
*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
);
1370 // ---------------------------------------------------------------------------
1372 // ---------------------------------------------------------------------------
1386 wxMask
* pMask
= NULL
;
1388 COLORREF vOldTextColor
;
1389 COLORREF vOldBackground
= ::GpiQueryBackColor(m_hPS
);
1393 const wxBitmap
& rBmp
= pSource
->m_vSelectedBitmap
;
1395 pMask
= rBmp
.GetMask();
1396 if (!(rBmp
.Ok() && pMask
&& pMask
->GetMaskBitmap()))
1402 ::GpiQueryAttrs( m_hPS
1407 vOldTextColor
= (COLORREF
)vCbnd
.lColor
;
1409 if (m_textForegroundColour
.Ok())
1411 vCbnd
.lColor
= (LONG
)m_textForegroundColour
.GetPixel();
1412 ::GpiSetAttrs( m_hPS
// presentation-space handle
1413 ,PRIM_CHAR
// Char primitive.
1414 ,CBB_COLOR
// sets color.
1416 ,&vCbnd
// buffer for attributes.
1419 if (m_textBackgroundColour
.Ok())
1421 ::GpiSetBackColor(m_hPS
, (LONG
)m_textBackgroundColour
.GetPixel());
1424 LONG lRop
= ROP_SRCCOPY
;
1428 case wxXOR
: lRop
= ROP_SRCINVERT
; break;
1429 case wxINVERT
: lRop
= ROP_DSTINVERT
; break;
1430 case wxOR_REVERSE
: lRop
= 0x00DD0228; break;
1431 case wxAND_REVERSE
: lRop
= ROP_SRCERASE
; break;
1432 case wxCLEAR
: lRop
= ROP_ZERO
; break;
1433 case wxSET
: lRop
= ROP_ONE
; break;
1434 case wxOR_INVERT
: lRop
= ROP_MERGEPAINT
; break;
1435 case wxAND
: lRop
= ROP_SRCAND
; break;
1436 case wxOR
: lRop
= ROP_SRCPAINT
; break;
1437 case wxEQUIV
: lRop
= 0x00990066; break;
1438 case wxNAND
: lRop
= 0x007700E6; break;
1439 case wxAND_INVERT
: lRop
= 0x00220326; break;
1440 case wxCOPY
: lRop
= ROP_SRCCOPY
; break;
1441 case wxNO_OP
: lRop
= ROP_NOTSRCERASE
; break;
1442 case wxSRC_INVERT
: lRop
= ROP_SRCINVERT
; break;
1443 case wxNOR
: lRop
= ROP_NOTSRCCOPY
; break;
1445 wxFAIL_MSG( wxT("unsupported logical function") );
1454 // Blit bitmap with mask
1458 // Create a temp buffer bitmap and DCs/PSs to access it and the mask
1464 DEVOPENSTRUC vDOP
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1465 BITMAPINFOHEADER2 vBmpHdr
;
1466 SIZEL vSize
= {0, 0};
1469 hDCMask
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDOP
, NULLHANDLE
);
1470 hDCBuffer
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDOP
, NULLHANDLE
);
1471 hPSMask
= ::GpiCreatePS(vHabmain
, hDCMask
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
1472 hPSBuffer
= ::GpiCreatePS(vHabmain
, hDCBuffer
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
1474 memset(&vBmpHdr
, 0, sizeof(BITMAPINFOHEADER2
));
1475 vBmpHdr
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1476 vBmpHdr
.cx
= vWidth
;
1477 vBmpHdr
.cy
= vHeight
;
1478 vBmpHdr
.cPlanes
= 1;
1479 vBmpHdr
.cBitCount
= 24;
1481 HBITMAP hBufBitmap
= ::GpiCreateBitmap(GetHPS(), &vBmpHdr
, 0L, NULL
, NULL
);
1482 POINTL aPoint1
[4] = { 0, 0
1485 ,vXdest
+ vWidth
, vYdest
+ vHeight
1487 POINTL aPoint2
[4] = { 0, 0
1490 ,vXsrc
+ vWidth
, vYsrc
+ vHeight
1492 POINTL aPoint3
[4] = { vXdest
, vYdest
1493 ,vXdest
+ vWidth
, vYdest
+ vHeight
1495 ,vXsrc
+ vWidth
, vYsrc
+ vHeight
1497 POINTL aPoint4
[4] = { vXdest
, vYdest
1498 ,vXdest
+ vWidth
, vYdest
+ vHeight
1502 ::GpiSetBitmap(hPSMask
, (HBITMAP
) pMask
->GetMaskBitmap());
1503 ::GpiSetBitmap(hPSBuffer
, (HBITMAP
) hBufBitmap
);
1506 // Copy dest to buffer
1508 rc
= ::GpiBitBlt( hPSBuffer
1515 if (rc
== GPI_ERROR
)
1517 wxLogLastError(wxT("BitBlt"));
1521 // Copy src to buffer using selected raster op
1523 rc
= ::GpiBitBlt( hPSBuffer
1530 if (rc
== GPI_ERROR
)
1532 wxLogLastError(wxT("BitBlt"));
1536 // Set masked area in buffer to BLACK (pixel value 0)
1538 COLORREF vPrevBkCol
= ::GpiQueryBackColor(GetHPS());
1539 COLORREF vPrevCol
= ::GpiQueryColor(GetHPS());
1541 ::GpiSetBackColor(GetHPS(), OS2RGB(255, 255, 255));
1542 ::GpiSetColor(GetHPS(), OS2RGB(0, 0, 0));
1544 rc
= ::GpiBitBlt( hPSBuffer
1551 if (rc
== GPI_ERROR
)
1553 wxLogLastError(wxT("BitBlt"));
1557 // Set unmasked area in dest to BLACK
1559 ::GpiSetBackColor(GetHPS(), OS2RGB(0, 0, 0));
1560 ::GpiSetColor(GetHPS(), OS2RGB(255, 255, 255));
1561 rc
= ::GpiBitBlt( GetHPS()
1568 if (rc
== GPI_ERROR
)
1570 wxLogLastError(wxT("BitBlt"));
1574 // Restore colours to original values
1576 ::GpiSetBackColor(GetHPS(), vPrevBkCol
);
1577 ::GpiSetColor(GetHPS(), vPrevCol
);
1580 // OR buffer to dest
1582 rc
= ::GpiBitBlt( GetHPS()
1589 if (rc
== GPI_ERROR
)
1592 wxLogLastError(wxT("BitBlt"));
1596 // Tidy up temporary DCs and bitmap
1598 ::GpiSetBitmap(hPSMask
, NULLHANDLE
);
1599 ::GpiSetBitmap(hPSBuffer
, NULLHANDLE
);
1600 ::GpiDestroyPS(hPSMask
);
1601 ::GpiDestroyPS(hPSBuffer
);
1602 ::DevCloseDC(hDCMask
);
1603 ::DevCloseDC(hDCBuffer
);
1604 ::GpiDeleteBitmap(hBufBitmap
);
1607 else // no mask, just BitBlt() it
1609 POINTL aPoint
[4] = { vXdest
, vYdest
1610 ,vXdest
+ vWidth
, vYdest
+ vHeight
1612 ,vXsrc
+ vWidth
, vYsrc
+ vHeight
1615 bSuccess
= (::GpiBitBlt( m_hPS
1624 wxLogLastError(wxT("BitBlt"));
1627 vCbnd
.lColor
= (LONG
)vOldTextColor
;
1628 ::GpiSetAttrs( m_hPS
// presentation-space handle
1629 ,PRIM_CHAR
// Char primitive.
1630 ,CBB_COLOR
// sets color.
1632 ,&vCbnd
// buffer for attributes.
1634 ::GpiSetBackColor(m_hPS
, (LONG
)vOldBackground
);
1638 void wxDC::DoGetSize( int* width
, int* height
) const
1643 void wxDC::DoGetSizeMM( int* width
, int* height
) const
1648 wxSize
wxDC::GetPPI() const
1653 return (wxSize(x
,y
));
1656 void wxDC::SetLogicalScale( double x
, double y
)
1661 #if WXWIN_COMPATIBILITY
1662 void wxDC::DoGetTextExtent(const wxString
& string
, float *x
, float *y
,
1663 float *descent
, float *externalLeading
,
1664 wxFont
*theFont
, bool use16bit
) const
1666 wxCoord x1
, y1
, descent1
, externalLeading1
;
1667 GetTextExtent(string
, & x1
, & y1
, & descent1
, & externalLeading1
, theFont
, use16bit
);
1670 *descent
= descent1
;
1671 if (externalLeading
)
1672 *externalLeading
= externalLeading1
;