]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/dc.cpp
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
);
1345 POINTL aPoint
[4] = { vXdest
, vYdest
1346 ,vXdest
+ vWidth
, vYdest
+ vHeight
1348 ,vXsrc
+ vWidth
, vYsrc
+ vHeight
1353 const wxBitmap
& rBmp
= pSource
->m_vSelectedBitmap
;
1355 pMask
= rBmp
.GetMask();
1356 if (!(rBmp
.Ok() && pMask
&& pMask
->GetMaskBitmap()))
1362 ::GpiQueryAttrs( m_hPS
1367 vOldTextColor
= (COLORREF
)vCbnd
.lColor
;
1369 if (m_textForegroundColour
.Ok())
1371 vCbnd
.lColor
= (LONG
)m_textForegroundColour
.GetPixel();
1372 ::GpiSetAttrs( m_hPS
// presentation-space handle
1373 ,PRIM_CHAR
// Char primitive.
1374 ,CBB_COLOR
// sets color.
1376 ,&vCbnd
// buffer for attributes.
1379 if (m_textBackgroundColour
.Ok())
1381 ::GpiSetBackColor(m_hPS
, (LONG
)m_textBackgroundColour
.GetPixel());
1384 LONG lRop
= ROP_SRCCOPY
;
1388 case wxXOR
: lRop
= ROP_SRCINVERT
; break;
1389 case wxINVERT
: lRop
= ROP_DSTINVERT
; break;
1390 case wxOR_REVERSE
: lRop
= 0x00DD0228; break;
1391 case wxAND_REVERSE
: lRop
= ROP_SRCERASE
; break;
1392 case wxCLEAR
: lRop
= ROP_ZERO
; break;
1393 case wxSET
: lRop
= ROP_ONE
; break;
1394 case wxOR_INVERT
: lRop
= ROP_MERGEPAINT
; break;
1395 case wxAND
: lRop
= ROP_SRCAND
; break;
1396 case wxOR
: lRop
= ROP_SRCPAINT
; break;
1397 case wxEQUIV
: lRop
= 0x00990066; break;
1398 case wxNAND
: lRop
= 0x007700E6; break;
1399 case wxAND_INVERT
: lRop
= 0x00220326; break;
1400 case wxCOPY
: lRop
= ROP_SRCCOPY
; break;
1401 case wxNO_OP
: lRop
= ROP_NOTSRCERASE
; break;
1402 case wxSRC_INVERT
: lRop
= ROP_SRCINVERT
; break;
1403 case wxNOR
: lRop
= ROP_NOTSRCCOPY
; break;
1405 wxFAIL_MSG( wxT("unsupported logical function") );
1414 // Blit bitmap with mask
1418 // Create a temp buffer bitmap and DCs to access it and the mask
1420 HDC dc_mask
= ::CreateCompatibleDC(GetHdcOf(*source
));
1421 HDC dc_buffer
= ::CreateCompatibleDC(GetHdc());
1422 HBITMAP buffer_bmap
= ::CreateCompatibleBitmap(GetHdc(), width
, height
);
1423 ::SelectObject(dc_mask
, (HBITMAP
) mask
->GetMaskBitmap());
1424 ::SelectObject(dc_buffer
, buffer_bmap
);
1426 // copy dest to buffer
1427 if ( !::BitBlt(dc_buffer
, 0, 0, (int)width
, (int)height
,
1428 GetHdc(), xdest
, ydest
, SRCCOPY
) )
1430 wxLogLastError(wxT("BitBlt"));
1433 // copy src to buffer using selected raster op
1434 if ( !::BitBlt(dc_buffer
, 0, 0, (int)width
, (int)height
,
1435 GetHdcOf(*source
), xsrc
, ysrc
, dwRop
) )
1437 wxLogLastError(wxT("BitBlt"));
1440 // set masked area in buffer to BLACK (pixel value 0)
1441 COLORREF prevBkCol
= ::SetBkColor(GetHdc(), RGB(255, 255, 255));
1442 COLORREF prevCol
= ::SetTextColor(GetHdc(), RGB(0, 0, 0));
1443 if ( !::BitBlt(dc_buffer
, 0, 0, (int)width
, (int)height
,
1444 dc_mask
, xsrc
, ysrc
, SRCAND
) )
1446 wxLogLastError(wxT("BitBlt"));
1449 // set unmasked area in dest to BLACK
1450 ::SetBkColor(GetHdc(), RGB(0, 0, 0));
1451 ::SetTextColor(GetHdc(), RGB(255, 255, 255));
1452 if ( !::BitBlt(GetHdc(), xdest
, ydest
, (int)width
, (int)height
,
1453 dc_mask
, xsrc
, ysrc
, SRCAND
) )
1455 wxLogLastError(wxT("BitBlt"));
1457 ::SetBkColor(GetHdc(), prevBkCol
); // restore colours to original values
1458 ::SetTextColor(GetHdc(), prevCol
);
1460 // OR buffer to dest
1461 success
= ::BitBlt(GetHdc(), xdest
, ydest
,
1462 (int)width
, (int)height
,
1463 dc_buffer
, 0, 0, SRCPAINT
) != 0;
1466 wxLogLastError(wxT("BitBlt"));
1469 // tidy up temporary DCs and bitmap
1470 ::SelectObject(dc_mask
, 0);
1471 ::DeleteDC(dc_mask
);
1472 ::SelectObject(dc_buffer
, 0);
1473 ::DeleteDC(dc_buffer
);
1474 ::DeleteObject(buffer_bmap
);
1478 // else // no mask, just BitBlt() it
1480 bSuccess
= (::GpiBitBlt( m_hPS
1489 wxLogLastError(wxT("BitBlt"));
1492 vCbnd
.lColor
= (LONG
)vOldTextColor
;
1493 ::GpiSetAttrs( m_hPS
// presentation-space handle
1494 ,PRIM_CHAR
// Char primitive.
1495 ,CBB_COLOR
// sets color.
1497 ,&vCbnd
// buffer for attributes.
1499 ::GpiSetBackColor(m_hPS
, (LONG
)vOldBackground
);
1503 void wxDC::DoGetSize( int* width
, int* height
) const
1508 void wxDC::DoGetSizeMM( int* width
, int* height
) const
1513 wxSize
wxDC::GetPPI() const
1518 return (wxSize(x
,y
));
1521 void wxDC::SetLogicalScale( double x
, double y
)
1526 #if WXWIN_COMPATIBILITY
1527 void wxDC::DoGetTextExtent(const wxString
& string
, float *x
, float *y
,
1528 float *descent
, float *externalLeading
,
1529 wxFont
*theFont
, bool use16bit
) const
1531 wxCoord x1
, y1
, descent1
, externalLeading1
;
1532 GetTextExtent(string
, & x1
, & y1
, & descent1
, & externalLeading1
, theFont
, use16bit
);
1535 *descent
= descent1
;
1536 if (externalLeading
)
1537 *externalLeading
= externalLeading1
;