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
)
38 // wxWindows uses the Microsoft convention that the origin is the UPPER left.
39 // Native OS/2 however in the GPI and PM define the origin as the LOWER left.
40 // In order to map OS/2 GPI/PM y coordinates to wxWindows coordinates we must
41 // perform the following transformation:
43 // Parent object height: POBJHEIGHT
44 // Desried origin: WXORIGINY
45 // Object to place's height: OBJHEIGHT
47 // To get the OS2 position from the wxWindows one:
49 // OS2Y = POBJHEIGHT - (WXORIGINY + OBJHEIGHT)
51 // For OS/2 wxDC's we will always determine m_vRclPaint as the size of the
52 // OS/2 Presentation Space associated with the device context. y is the
53 // desired application's y coordinate of the origin in wxWindows space.
54 // objy is the height of the object we are going to draw.
56 #define OS2Y(y, objy) ((m_vRclPaint.yTop - m_vRclPaint.yBottom) - (y + objy))
58 // ---------------------------------------------------------------------------
60 // ---------------------------------------------------------------------------
62 static const int VIEWPORT_EXTENT
= 1000;
64 static const int MM_POINTS
= 9;
65 static const int MM_METRIC
= 10;
67 // usually this is defined in math.h
69 static const double M_PI
= 3.14159265358979323846;
72 // ---------------------------------------------------------------------------
74 // ---------------------------------------------------------------------------
76 // convert degrees to radians
77 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
81 , int nForegroundColour
86 vCbnd
.lColor
= nForegroundColour
;
87 ::GpiSetAttrs( hPS
// presentation-space handle
88 ,PRIM_CHAR
// Char primitive.
89 ,CBB_COLOR
// sets color.
91 ,&vCbnd
// buffer for attributes.
102 ::GpiQueryAttrs( hPS
// presentation-space handle
103 ,PRIM_CHAR
// Char primitive.
104 ,CBB_BACK_COLOR
// Background color.
105 ,&vCbnd
// buffer for attributes.
107 return vCbnd
.lBackColor
;
113 , int nBackgroundColour
119 rc
= QueryTextBkColor(hPS
);
121 vCbnd
.lBackColor
= nBackgroundColour
;
122 ::GpiSetAttrs(hPS
, // presentation-space handle
123 PRIM_CHAR
, // Char primitive.
124 CBB_BACK_COLOR
, // sets color.
126 &vCbnd
// buffer for attributes.
133 , int nBackgroundMode
136 if(nBackgroundMode
== wxTRANSPARENT
)
141 // the background of the primitive takes over whatever is underneath.
148 // ===========================================================================
150 // ===========================================================================
152 // ---------------------------------------------------------------------------
154 // ---------------------------------------------------------------------------
172 m_bIsPaintTime
= FALSE
; // True at Paint Time
174 vColor
.InitFromName("BLACK");
175 m_pen
.SetColour(vColor
);
177 m_brush
.SetColour(vColor
);
178 } // end of wxDC::wxDC
184 SelectOldObjects(m_hDC
);
186 // if we own the HDC, we delete it, otherwise we just release it
192 ::GpiAssociate(m_hPS
, NULLHANDLE
);
193 ::GpiDestroyPS(m_hPS
);
196 ::DevCloseDC((HDC
)m_hDC
);
201 // Just Dissacociate, not destroy if we don't own the DC
205 ::GpiAssociate(m_hPS
, NULLHANDLE
);
209 } // end of wxDC::~wxDC
211 // This will select current objects out of the DC,
212 // which is what you have to do before deleting the
214 void wxDC::SelectOldObjects(
222 ::GpiSetBitmap(hPS
, (HBITMAP
) m_hOldBitmap
);
223 if (m_vSelectedBitmap
.Ok())
225 m_vSelectedBitmap
.SetSelectedInto(NULL
);
230 // OS/2 has no other native GDI objects to set in a PS/DC like windows
238 m_brush
= wxNullBrush
;
240 m_palette
= wxNullPalette
;
242 m_backgroundBrush
= wxNullBrush
;
243 m_vSelectedBitmap
= wxNullBitmap
;
244 } // end of wxDC::SelectOldObjects
246 // ---------------------------------------------------------------------------
248 // ---------------------------------------------------------------------------
250 #define DO_SET_CLIPPING_BOX() \
254 ::GpiQueryClipBox(m_hPS, &rect); \
256 m_clipX1 = (wxCoord) XDEV2LOG(rect.xLeft); \
257 m_clipY1 = (wxCoord) YDEV2LOG(rect.yTop); \
258 m_clipX2 = (wxCoord) XDEV2LOG(rect.xRight); \
259 m_clipY2 = (wxCoord) YDEV2LOG(rect.yBottom); \
262 void wxDC::DoSetClippingRegion(
271 vY
= OS2Y(vY
,vHeight
);
274 vRect
.yTop
= vY
+ vHeight
;
275 vRect
.xRight
= vX
+ vWidth
;
277 ::GpiIntersectClipRectangle(m_hPS
, &vRect
);
278 DO_SET_CLIPPING_BOX()
279 } // end of wxDC::DoSetClippingRegion
281 void wxDC::DoSetClippingRegionAsRegion(
282 const wxRegion
& rRegion
285 wxCHECK_RET(rRegion
.GetHRGN(), wxT("invalid clipping region"));
289 ::GpiSetClipRegion( m_hPS
290 ,(HRGN
)rRegion
.GetHRGN()
293 DO_SET_CLIPPING_BOX()
294 } // end of wxDC::DoSetClippingRegionAsRegion
296 void wxDC::DestroyClippingRegion(void)
298 if (m_clipping
&& m_hPS
)
303 // TODO: this should restore the previous clipped region
304 // so that OnPaint processing works correctly, and
305 // the update doesn't get destroyed after the first
306 // DestroyClippingRegion
307 vRect
.xLeft
= XLOG2DEV(0);
308 vRect
.yTop
= YLOG2DEV(32000);
309 vRect
.xRight
= XLOG2DEV(32000);
310 vRect
.yBottom
= YLOG2DEV(0);
312 HRGN hRgn
= ::GpiCreateRegion(m_hPS
, 1, &vRect
);
314 ::GpiSetClipRegion(m_hPS
, hRgn
, &hRgnOld
);
317 } // end of wxDC::DestroyClippingRegion
319 // ---------------------------------------------------------------------------
320 // query capabilities
321 // ---------------------------------------------------------------------------
323 bool wxDC::CanDrawBitmap() const
328 bool wxDC::CanGetTextExtent() const
330 LONG lTechnology
= 0L;
332 ::DevQueryCaps(GetHDC(), CAPS_TECHNOLOGY
, 1L, &lTechnology
);
333 return (lTechnology
== CAPS_TECH_RASTER_DISPLAY
) || (lTechnology
== CAPS_TECH_RASTER_PRINTER
);
334 } // end of wxDC::CanGetTextExtent
336 int wxDC::GetDepth() const
338 LONG lArray
[CAPS_COLOR_BITCOUNT
];
341 if(::DevQueryCaps( GetHDC()
347 nBitsPerPixel
= (int)lArray
[CAPS_COLOR_BITCOUNT
];
349 return nBitsPerPixel
;
350 } // end of wxDC::GetDepth
352 // ---------------------------------------------------------------------------
354 // ---------------------------------------------------------------------------
359 } // end of wxDC::Clear
361 void wxDC::DoFloodFill(
364 , const wxColour
& rCol
372 vPtlPos
.x
= vX
; // Loads x-coordinate
373 vPtlPos
.y
= OS2Y(vY
,0); // Loads y-coordinate
374 ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position
375 lColor
= rCol
.GetPixel();
376 lOptions
= FF_BOUNDARY
;
377 if(wxFLOOD_SURFACE
== nStyle
)
378 lOptions
= FF_SURFACE
;
380 ::GpiFloodFill(m_hPS
, lOptions
, lColor
);
381 } // end of wxDC::DoFloodFill
383 bool wxDC::DoGetPixel(
393 vPoint
.y
= OS2Y(vY
,0);
394 lColor
= ::GpiSetPel(m_hPS
, &vPoint
);
397 // Get the color of the pen
399 LONG lPencolor
= 0x00ffffff;
403 lPencolor
= m_pen
.GetColour().GetPixel();
407 // return the color of the pixel
410 pCol
->Set( GetRValue(lColor
)
414 return(lColor
== lPencolor
);
415 } // end of wxDC::DoGetPixel
417 void wxDC::DoCrossHair(
424 wxCoord vX1
= vX
- VIEWPORT_EXTENT
;
425 wxCoord vY1
= vY
- VIEWPORT_EXTENT
;
426 wxCoord vX2
= vX
+ VIEWPORT_EXTENT
;
427 wxCoord vY2
= vY
+ VIEWPORT_EXTENT
;
436 ::GpiMove(m_hPS
, &vPoint
[0]);
437 ::GpiLine(m_hPS
, &vPoint
[1]);
445 ::GpiMove(m_hPS
, &vPoint
[2]);
446 ::GpiLine(m_hPS
, &vPoint
[3]);
447 CalcBoundingBox(vX1
, vY1
);
448 CalcBoundingBox(vX2
, vY2
);
449 } // end of wxDC::DoCrossHair
451 void wxDC::DoDrawLine(
467 ::GpiMove(m_hPS
, &vPoint
[0]);
468 ::GpiLine(m_hPS
, &vPoint
[1]);
469 CalcBoundingBox(vX1
, vY1
);
470 CalcBoundingBox(vX2
, vY2
);
471 } // end of wxDC::DoDrawLine
473 //////////////////////////////////////////////////////////////////////////////
474 // Draws an arc of a circle, centred on (xc, yc), with starting point (x1, y1)
475 // and ending at (x2, y2). The current pen is used for the outline and the
476 // current brush for filling the shape. The arc is drawn in an anticlockwise
477 // direction from the start point to the end point.
478 //////////////////////////////////////////////////////////////////////////////
479 void wxDC::DoDrawArc(
489 POINTL vPtlArc
[2]; // Structure for current position
498 ARCPARAMS vArcp
; // Structure for arc parameters
500 if((vX1
== vXc
&& vY1
== vXc
) || (vX2
== vXc
&& vY2
== vXc
))
501 return; // Draw point ??
502 dRadius
= 0.5 * ( hypot( (double)(vY1
- vYc
)
505 hypot( (double)(vY2
- vYc
)
510 dAngl1
= atan2( (double)(vY1
- vYc
)
513 dAngl2
= atan2( (double)(vY2
- vYc
)
520 // GpiPointArc can't draw full arc
522 if(dAngl2
== dAngl1
|| (vX1
== vX2
&& vY1
== vY2
) )
527 dAnglmid
= (dAngl1
+ dAngl2
)/2. + M_PI
;
528 vXm
= vXc
+ dRadius
* cos(dAnglmid
);
529 vYm
= vYc
+ dRadius
* sin(dAnglmid
);
544 dAnglmid
= (dAngl1
+ dAngl2
)/2.;
545 vXm
= vXc
+ dRadius
* cos(dAnglmid
);
546 vYm
= vYc
+ dRadius
* sin(dAnglmid
);
549 // Ellipse main axis (r,q), (p,s) with center at (0,0) */
555 ::GpiSetArcParams(m_hPS
, &vArcp
); // Sets parameters to default
557 vPtlPos
.x
= vX1
; // Loads x-coordinate
558 vPtlPos
.y
= vY1
; // Loads y-coordinate
559 ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position
564 ::GpiPointArc(m_hPS
, vPtlArc
); // Draws the arc
565 CalcBoundingBox( (vXc
- dRadius
)
568 CalcBoundingBox( (vXc
+ dRadius
)
571 } // end of wxDC::DoDrawArc
573 void wxDC::DoDrawCheckMark(
582 vY1
= OS2Y(vY1
,vHeight
);
586 vPoint
[1].x
= vX1
+ vWidth
;
587 vPoint
[1].y
= vY1
+ vHeight
;
589 ::GpiMove(m_hPS
, &vPoint
[0]);
590 ::GpiBox( m_hPS
// handle to a presentation space
591 ,DRO_OUTLINE
// draw the box outline ? or ?
592 ,&vPoint
[1] // address of the corner
593 ,0L // horizontal corner radius
594 ,0L // vertical corner radius
596 if(vWidth
> 4 && vHeight
> 4)
600 vPoint
[0].x
+= 2; vPoint
[0].y
+= 2;
601 vPoint
[1].x
-= 2; vPoint
[1].y
-= 2;
602 ::GpiMove(m_hPS
, &vPoint
[0]);
603 ::GpiLine(m_hPS
, &vPoint
[1]);
605 vPoint
[0].x
= vPoint
[1].x
;
607 ::GpiMove(m_hPS
, &vPoint
[0]);
608 ::GpiLine(m_hPS
, &vPoint
[1]);
614 wxCoord vX2
= vX1
+ vWidth
;
615 wxCoord vY2
= vY1
+ vHeight
;
620 } // end of wxDC::DoDrawCheckMark
622 void wxDC::DoDrawPoint(
628 COLORREF vColor
= 0x00ffffff;
632 vColor
= m_pen
.GetColour().GetPixel();
634 ::GpiSetColor(m_hPS
, vColor
);
636 vPoint
.y
= OS2Y(vY
,0);
637 ::GpiSetPel(m_hPS
, &vPoint
);
641 } // end of wxDC::DoDrawPoint
643 void wxDC::DoDrawPolygon(
651 ULONG ulCount
= 1; // Number of polygons.
652 POLYGON vPlgn
; // polygon.
653 ULONG flOptions
= 0L; // Drawing options.
655 //////////////////////////////////////////////////////////////////////////////
656 // This contains fields of option bits... to draw boundary lines as well as
657 // the area interior.
659 // Drawing boundary lines:
660 // POLYGON_NOBOUNDARY Does not draw boundary lines.
661 // POLYGON_BOUNDARY Draws boundary lines (the default).
663 // Construction of the area interior:
664 // POLYGON_ALTERNATE Constructs interior in alternate mode
666 // POLYGON_WINDING Constructs interior in winding mode.
667 //////////////////////////////////////////////////////////////////////////////
669 ULONG flModel
= 0L; // Drawing model.
671 //////////////////////////////////////////////////////////////////////////////
673 // POLYGON_INCL Fill is inclusive of bottom right (the default).
674 // POLYGON_EXCL Fill is exclusive of bottom right.
675 // This is provided to aid migration from other graphics models.
676 //////////////////////////////////////////////////////////////////////////////
678 LONG lHits
= 0L; // Correlation/error indicator.
681 int nIsTRANSPARENT
= 0;
682 LONG lBorderColor
= 0L;
685 lBorderColor
= m_pen
.GetColour().GetPixel();
686 lColor
= m_brush
.GetColour().GetPixel();
687 if(m_brush
.GetStyle() == wxTRANSPARENT
)
691 vPlgn
.aPointl
= (POINTL
*) calloc( n
+ 1
693 ); // well, new will call malloc
695 for(i
= 0; i
< n
; i
++)
697 vPlgn
.aPointl
[i
].x
= vPoints
[i
].x
; // +xoffset;
698 vPlgn
.aPointl
[i
].y
= OS2Y(vPoints
[i
].y
,0); // +yoffset;
700 flModel
= POLYGON_BOUNDARY
;
701 if(nFillStyle
== wxWINDING_RULE
)
702 flModel
|= POLYGON_WINDING
;
704 flModel
|= POLYGON_ALTERNATE
;
707 vPoint
.y
= OS2Y(vYoffset
,0);
709 ::GpiSetColor(m_hPS
, lBorderColor
);
710 ::GpiMove(m_hPS
, &vPoint
);
711 lHits
= ::GpiPolygons(m_hPS
, ulCount
, &vPlgn
, flOptions
, flModel
);
713 } // end of wxDC::DoDrawPolygon
715 void wxDC::DoDrawLines(
724 if (vXoffset
!= 0L || vXoffset
!= 0L)
728 vPoint
.x
= vPoints
[0].x
+ vXoffset
;
729 vPoint
.y
= OS2Y(vPoints
[0].y
+ vYoffset
,0);
730 ::GpiMove(m_hPS
, &vPoint
);
732 LONG lBorderColor
= m_pen
.GetColour().GetPixel();
734 ::GpiSetColor(m_hPS
, lBorderColor
);
735 for(i
= 1; i
< n
; i
++)
737 vPoint
.x
= vPoints
[i
].x
+ vXoffset
;
738 vPoint
.y
= OS2Y(vPoints
[i
].y
+ vYoffset
,0);
739 ::GpiLine(m_hPS
, &vPoint
);
746 CalcBoundingBox( vPoints
[i
].x
749 vPoint
.x
= vPoints
[0].x
;
750 vPoint
.y
= OS2Y(vPoints
[0].y
,0);
751 ::GpiMove(m_hPS
, &vPoint
);
753 for (i
= 0; i
< n
; i
++)
755 CalcBoundingBox( vPoints
[i
].x
758 vPoint
.x
= vPoints
[i
].x
;
759 vPoint
.y
= OS2Y(vPoints
[i
].y
,0);
760 ::GpiLine(m_hPS
, &vPoint
);
763 } // end of wxDC::DoDrawLines
765 void wxDC::DoDrawRectangle(
776 int nIsTRANSPARENT
= 0;
778 vY
= OS2Y(vY
,vHeight
);
780 wxCoord vX2
= vX
+ vWidth
;
781 wxCoord vY2
= vY
+ vHeight
;
785 vPoint
[1].x
= vX
+ vWidth
;
786 vPoint
[1].y
= vY
+ vHeight
;
787 ::GpiMove(m_hPS
, &vPoint
[0]);
788 lColor
= m_brush
.GetColour().GetPixel();
789 lBorderColor
= m_pen
.GetColour().GetPixel();
790 if (m_brush
.GetStyle() == wxTRANSPARENT
)
792 if(lColor
== lBorderColor
|| nIsTRANSPARENT
)
794 lControl
= DRO_OUTLINEFILL
; //DRO_FILL;
795 if(m_brush
.GetStyle() == wxTRANSPARENT
)
796 lControl
= DRO_OUTLINE
;
798 ::GpiSetColor(m_hPS
, lColor
);
799 ::GpiBox( m_hPS
// handle to a presentation space
800 ,lControl
// draw the box outline ? or ?
801 ,&vPoint
[1] // address of the corner
802 ,0L // horizontal corner radius
803 ,0L // vertical corner radius
808 lControl
= DRO_OUTLINE
;
822 vPoint
[0].x
= vX
+ 1;
823 vPoint
[0].y
= vY
+ 1;
824 vPoint
[1].x
= vX
+ vWidth
- 2;
825 vPoint
[1].y
= vY
+ vHeight
- 2;
826 ::GpiMove(m_hPS
, &vPoint
[0]);
834 CalcBoundingBox(vX
, vY
);
835 CalcBoundingBox(vX2
, vY2
);
836 } // end of wxDC::DoDrawRectangle
838 void wxDC::DoDrawRoundedRectangle(
849 vY
= OS2Y(vY
,vHeight
);
851 wxCoord vX2
= (vX
+ vWidth
);
852 wxCoord vY2
= (vY
+ vHeight
);
855 vPoint
[0].y
= YLOG2DEV(vY
) - vHeight
;
856 vPoint
[1].x
= vX
+ vWidth
;
858 ::GpiMove(m_hPS
, &vPoint
[0]);
860 lControl
= DRO_OUTLINEFILL
; //DRO_FILL;
861 if (m_brush
.GetStyle() == wxTRANSPARENT
)
862 lControl
= DRO_OUTLINE
;
863 ::GpiBox( m_hPS
// handle to a presentation space
864 ,DRO_OUTLINE
// draw the box outline ? or ?
865 ,&vPoint
[1] // address of the corner
866 ,(LONG
)dRadius
// horizontal corner radius
867 ,(LONG
)dRadius
// vertical corner radius
869 CalcBoundingBox(vX
, vY
);
870 CalcBoundingBox(vX2
, vY2
);
871 } // end of wxDC::DoDrawRoundedRectangle
873 // Draw Ellipse within box (x,y) - (x+width, y+height)
874 void wxDC::DoDrawEllipse(
881 POINTL vPtlPos
; // Structure for current position
882 FIXED vFxMult
; // Multiplier for ellipse
883 ARCPARAMS vArcp
; // Structure for arc parameters
885 vY
= OS2Y(vY
,vHeight
);
888 vArcp
.lQ
= vHeight
/2;
891 ::GpiSetArcParams( m_hPS
893 ); // Sets parameters to default
894 vPtlPos
.x
= vX
+ vWidth
/2; // Loads x-coordinate
895 vPtlPos
.y
= vY
+ vHeight
/2; // Loads y-coordinate
898 ); // Sets current position
899 vFxMult
= MAKEFIXED(1, 0); /* Sets multiplier */
902 // DRO_FILL, DRO_OTLINEFILL - where to get
907 ); // Draws full arc with center at current position
909 wxCoord vX2
= (vX
+ vWidth
);
910 wxCoord vY2
= (vY
+ vHeight
);
912 CalcBoundingBox(vX
, vY
);
913 CalcBoundingBox(vX2
, vY2
);
914 } // end of wxDC::DoDrawEllipse
916 void wxDC::DoDrawEllipticArc(
925 POINTL vPtlPos
; // Structure for current position
926 FIXED vFxMult
; // Multiplier for ellipse
927 ARCPARAMS vArcp
; // Structure for arc parameters
929 FIXED vFSweepa
; // Start angle, sweep angle
934 vY
= OS2Y(vY
,vHeight
);
936 dFractPart
= modf(dSa
,&dIntPart
);
937 vFSa
= MAKEFIXED((int)dIntPart
, (int)(dFractPart
* 0xffff) );
938 dFractPart
= modf(dEa
- dSa
, &dIntPart
);
939 vFSweepa
= MAKEFIXED((int)dIntPart
, (int)(dFractPart
* 0xffff) );
942 // Ellipse main axis (r,q), (p,s) with center at (0,0)
945 vArcp
.lQ
= vHeight
/2;
948 ::GpiSetArcParams(m_hPS
, &vArcp
); // Sets parameters to default
949 vPtlPos
.x
= vX
+ vWidth
/2 * (1. + cos(DegToRad(dSa
))); // Loads x-coordinate
950 vPtlPos
.y
= vY
+ vHeight
/2 * (1. + sin(DegToRad(dSa
))); // Loads y-coordinate
951 ::GpiMove(m_hPS
, &vPtlPos
); // Sets current position
954 // May be not to the center ?
956 vPtlPos
.x
= vX
+ vWidth
/2 ; // Loads x-coordinate
957 vPtlPos
.y
= vY
+ vHeight
/2; // Loads y-coordinate
958 vFxMult
= MAKEFIXED(1, 0); // Sets multiplier
961 // DRO_FILL, DRO_OTLINEFILL - where to get
963 ::GpiPartialArc( m_hPS
969 wxCoord vX2
= (vX
+ vWidth
);
970 wxCoord vY2
= (vY
+ vHeight
);
972 CalcBoundingBox(vX
, vY
);
973 CalcBoundingBox(vX2
, vY2
);
974 } // end of wxDC::DoDrawEllipticArc
976 void wxDC::DoDrawIcon(
982 vY
= OS2Y(vY
,rIcon
.GetHeight());
983 wxCHECK_RET( rIcon
.Ok(), wxT("invalid icon in DrawIcon") );
985 ::WinDrawPointer( GetHPS()
988 ,(HPOINTER
)GetHiconOf(rIcon
)
991 CalcBoundingBox(vX
, vY
);
992 CalcBoundingBox(vX
+ rIcon
.GetWidth(), vY
+ rIcon
.GetHeight());
993 } // end of wxDC::DoDrawIcon
995 void wxDC::DoDrawBitmap(
1002 POINTL vPoint
= {vX
, vY
};
1004 ::WinDrawBitmap( GetHPS()
1005 ,(HBITMAP
)GetHbitmapOf(rBmp
)
1012 } // end of wxDC::DoDrawBitmap
1014 void wxDC::DoDrawText(
1015 const wxString
& rsText
1028 CalcBoundingBox(vX
, vY
);
1029 GetTextExtent(rsText
, &vWidth
, &vHeight
);
1030 CalcBoundingBox((vX
+ vWidth
), (vY
+ vHeight
));
1031 } // end of wxDC::DoDrawText
1033 void wxDC::DrawAnyText(
1034 const wxString
& rsText
1039 int nOldBackground
= 0;
1046 // prepare for drawing the text
1050 // Set text color attributes
1052 if (m_textForegroundColour
.Ok())
1055 ,(int)m_textForegroundColour
.GetPixel()
1059 if (m_textBackgroundColour
.Ok())
1061 nOldBackground
= SetTextBkColor( m_hPS
1062 ,(int)m_textBackgroundColour
.GetPixel()
1068 GetTextExtent( rsText
1073 vPtlStart
.y
= OS2Y(vY
,vTextY
);
1075 lHits
= ::GpiCharStringAt( m_hPS
1078 ,(PCH
)rsText
.c_str()
1080 if (lHits
!= GPI_OK
)
1082 wxLogLastError(wxT("TextOut"));
1086 // Restore the old parameters (text foreground colour may be left because
1087 // it never is set to anything else, but background should remain
1088 // transparent even if we just drew an opaque string)
1090 if (m_textBackgroundColour
.Ok())
1091 SetTextBkColor( m_hPS
1099 void wxDC::DoDrawRotatedText(
1100 const wxString
& rsText
1118 DoDrawText(text, x, y);
1123 wxFillLogFont(&lf, &m_font);
1125 // GDI wants the angle in tenth of degree
1126 long angle10 = (long)(angle * 10);
1127 lf.lfEscapement = angle10;
1128 lf. lfOrientation = angle10;
1130 HFONT hfont = ::CreateFontIndirect(&lf);
1133 wxLogLastError("CreateFont");
1137 HFONT hfontOld = ::SelectObject(GetHdc(), hfont);
1139 DrawAnyText(text, x, y);
1141 (void)::SelectObject(GetHdc(), hfontOld);
1144 // call the bounding box by adding all four vertices of the rectangle
1145 // containing the text to it (simpler and probably not slower than
1146 // determining which of them is really topmost/leftmost/...)
1148 GetTextExtent(text, &w, &h);
1150 double rad = DegToRad(angle);
1152 // "upper left" and "upper right"
1153 CalcBoundingBox(x, y);
1154 CalcBoundingBox(x + w*cos(rad), y - h*sin(rad));
1155 CalcBoundingBox(x + h*sin(rad), y + h*cos(rad));
1157 // "bottom left" and "bottom right"
1158 x += (wxCoord)(h*sin(rad));
1159 y += (wxCoord)(h*cos(rad));
1160 CalcBoundingBox(x, y);
1161 CalcBoundingBox(x + h*sin(rad), y + h*cos(rad));
1166 // ---------------------------------------------------------------------------
1168 // ---------------------------------------------------------------------------
1170 void wxDC::SetPalette(
1171 const wxPalette
& rPalette
1178 m_palette
= rPalette
;
1186 HPALETTE hOldPal
= ::GpiSelectPalette((HDC
) m_hPS
, (HPALETTE
) m_palette
.GetHPALETTE());
1188 m_hOldPalette
= (WXHPALETTE
)hOldPal
;
1189 } // end of wxDC::SetPalette
1196 // Set the old object temporarily, in case the assignment deletes an object
1197 // that's not yet selected out.
1209 m_font
.SetPS(m_hPS
); // this will realize the font
1213 HFONT hFont
= m_font
.GetResourceHandle();
1214 if (hFont
== (HFONT
) NULL
)
1216 wxLogDebug(wxT("::SelectObject failed in wxDC::SetFont."));
1219 m_hOldFont
= (WXHFONT
) hFont
;
1221 } // end of wxDC::SetFont
1227 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1243 m_pen
.SetPS((HPS
)m_hOldPen
);
1250 if (m_pen
.GetResourceHandle())
1254 m_hOldPen
= m_pen
.GetPS();
1259 void wxDC::SetBrush(
1260 const wxBrush
& rBrush
1263 wxCHECK_RET( Ok(), wxT("invalid window dc") );
1269 if (m_brush
== rBrush
)
1279 m_brush
.SetPS((HPS
)m_hOldBrush
);
1286 if (m_brush
.GetResourceHandle())
1288 m_brush
.SetPS(m_hPS
);
1290 m_hOldBrush
= (WXHWND
)m_brush
.GetPS();
1293 } // end of wxDC::SetBrush
1295 void wxDC::SetBackground(
1296 const wxBrush
& rBrush
1299 m_backgroundBrush
= rBrush
;
1300 if (!m_backgroundBrush
.Ok())
1304 bool bCustomColours
= TRUE
;
1307 // If we haven't specified wxUSER_COLOURS, don't allow the panel/dialog box to
1308 // change background colours from the control-panel specified colours.
1310 if (m_pCanvas
->IsKindOf(CLASSINFO(wxWindow
)) &&
1311 ((m_pCanvas
->GetWindowStyleFlag() & wxUSER_COLOURS
) != wxUSER_COLOURS
))
1312 bCustomColours
= FALSE
;
1315 if (m_backgroundBrush
.GetStyle()==wxTRANSPARENT
)
1317 m_pCanvas
->SetTransparent(TRUE
);
1322 // Setting the background brush of a DC
1323 // doesn't affect the window background colour. However,
1324 // I'm leaving in the transparency setting because it's needed by
1325 // various controls (e.g. wxStaticText) to determine whether to draw
1326 // transparently or not. TODO: maybe this should be a new function
1327 // wxWindow::SetTransparency(). Should that apply to the child itself, or the
1329 // m_canvas->SetBackgroundColour(m_backgroundBrush.GetColour());
1331 m_pCanvas
->SetTransparent(FALSE
);
1335 COLORREF vNewColor
= m_backgroundBrush
.GetColour().GetPixel();
1336 (void)::GpiSetBackColor((HPS
)m_hPS
, (LONG
)vNewColor
);
1337 } // end of wxDC::SetBackground
1339 void wxDC::SetBackgroundMode(
1343 m_backgroundMode
= nMode
;
1344 } // end of wxDC::SetBackgroundMode
1346 void wxDC::SetLogicalFunction(
1350 m_logicalFunction
= nFunction
;
1351 SetRop((WXHDC
)m_hDC
);
1352 } // wxDC::SetLogicalFunction
1358 if (!hDC
|| m_logicalFunction
< 0)
1362 switch (m_logicalFunction
)
1373 lCRop
= FM_MERGESRCNOT
;
1377 lCRop
= FM_NOTMASKSRC
;
1389 lCRop
= FM_MERGENOTSRC
;
1393 lCRop
= FM_MERGESRCNOT
;
1405 lCRop
= FM_SUBTRACT
;
1412 lCRop
= FM_OVERPAINT
;
1415 ::GpiSetMix((HPS
)hDC
, lCRop
);
1416 } // end of wxDC::SetRop
1418 bool wxDC::StartDoc(
1419 const wxString
& rsMessage
1422 // We might be previewing, so return TRUE to let it continue.
1424 } // end of wxDC::StartDoc
1428 } // end of wxDC::EndDoc
1430 void wxDC::StartPage()
1432 } // end of wxDC::StartPage
1434 void wxDC::EndPage()
1436 } // end of wxDC::EndPage
1438 // ---------------------------------------------------------------------------
1440 // ---------------------------------------------------------------------------
1442 wxCoord
wxDC::GetCharHeight() const
1444 FONTMETRICS vFM
; // metrics structure
1446 ::GpiQueryFontMetrics( m_hPS
1447 ,sizeof(FONTMETRICS
)
1450 return YDEV2LOGREL(vFM
.lXHeight
);
1453 wxCoord
wxDC::GetCharWidth() const
1455 FONTMETRICS vFM
; // metrics structure
1457 ::GpiQueryFontMetrics( m_hPS
1458 ,sizeof(FONTMETRICS
)
1461 return XDEV2LOGREL(vFM
.lAveCharWidth
);
1464 void wxDC::DoGetTextExtent(
1465 const wxString
& rsString
1468 , wxCoord
* pvDescent
1469 , wxCoord
* pvExternalLeading
1473 POINTL avPoint
[TXTBOX_COUNT
];
1478 FONTMETRICS vFM
; // metrics structure
1481 ERRORID vErrorCode
; // last error id code
1482 wxFont
* pFontToUse
= (wxFont
*)pTheFont
;
1484 char zMsg
[128]; // DEBUG
1488 pFontToUse
= (wxFont
*)&m_font
;
1489 l
= rsString
.length();
1490 pStr
= (PCH
) rsString
.c_str();
1493 // In world coordinates.
1495 bRc
= ::GpiQueryTextBox( m_hPS
1498 ,TXTBOX_COUNT
// return maximum information
1499 ,avPoint
// array of coordinates points
1503 vErrorCode
= ::WinGetLastError(wxGetInstance());
1504 sError
= wxPMErrorToStr(vErrorCode
);
1506 sprintf(zMsg
, "GpiQueryTextBox for %s: failed with Error: %x - %s", pStr
, vErrorCode
, sError
.c_str());
1507 (void)wxMessageBox( "wxWindows Menu sample"
1513 vPtMin
.x
= avPoint
[0].x
;
1514 vPtMax
.x
= avPoint
[0].x
;
1515 vPtMin
.y
= avPoint
[0].y
;
1516 vPtMax
.y
= avPoint
[0].y
;
1517 for (i
= 1; i
< 4; i
++)
1519 if(vPtMin
.x
> avPoint
[i
].x
) vPtMin
.x
= avPoint
[i
].x
;
1520 if(vPtMin
.y
> avPoint
[i
].y
) vPtMin
.y
= avPoint
[i
].y
;
1521 if(vPtMax
.x
< avPoint
[i
].x
) vPtMax
.x
= avPoint
[i
].x
;
1522 if(vPtMax
.y
< avPoint
[i
].y
) vPtMax
.y
= avPoint
[i
].y
;
1524 ::GpiQueryFontMetrics( m_hPS
1525 ,sizeof(FONTMETRICS
)
1530 *pvX
= (wxCoord
)(vPtMax
.x
- vPtMin
.x
+ 1);
1532 *pvY
= (wxCoord
)(vPtMax
.y
- vPtMin
.y
+ 1);
1534 *pvDescent
= vFM
.lMaxDescender
;
1535 if (pvExternalLeading
)
1536 *pvExternalLeading
= vFM
.lExternalLeading
;
1539 void wxDC::SetMapMode(
1543 int nPixelWidth
= 0;
1544 int nPixelHeight
= 0;
1547 LONG lArray
[CAPS_VERTICAL_RESOLUTION
];
1549 m_mappingMode
= nMode
;
1551 if(::DevQueryCaps( m_hDC
1553 ,CAPS_VERTICAL_RESOLUTION
1560 nPixelWidth
= lArray
[CAPS_WIDTH
];
1561 nPixelHeight
= lArray
[CAPS_HEIGHT
];
1562 lHorzRes
= lArray
[CAPS_HORIZONTAL_RESOLUTION
]; // returns pel/meter
1563 lVertRes
= lArray
[CAPS_VERTICAL_RESOLUTION
]; // returns pel/meter
1564 nMmWidth
= (lHorzRes
/1000) * nPixelWidth
;
1565 nMmWidth
= (lVertRes
/1000) * nPixelHeight
;
1567 if ((nPixelWidth
== 0) || (nPixelHeight
== 0) || (nMmWidth
== 0) || (nMmHeight
== 0))
1572 double dMm2pixelsX
= nPixelWidth
/nMmWidth
;
1573 double dMm2pixelsY
= nPixelHeight
/nMmHeight
;
1578 m_logicalScaleX
= (twips2mm
* dMm2pixelsX
);
1579 m_logicalScaleY
= (twips2mm
* dMm2pixelsY
);
1583 m_logicalScaleX
= (pt2mm
* dMm2pixelsX
);
1584 m_logicalScaleY
= (pt2mm
* dMm2pixelsY
);
1588 m_logicalScaleX
= dMm2pixelsX
;
1589 m_logicalScaleY
= dMm2pixelsY
;
1593 m_logicalScaleX
= (dMm2pixelsX
/10.0);
1594 m_logicalScaleY
= (dMm2pixelsY
/10.0);
1599 m_logicalScaleX
= 1.0;
1600 m_logicalScaleY
= 1.0;
1606 ulOptions
= ::GpiQueryPS(m_hPS
, &vSize
);
1607 if (!ulOptions
& PU_ARBITRARY
)
1609 ulOptions
= PU_ARBITRARY
| GPIF_DEFAULT
;
1610 ::GpiSetPS(m_hPS
, &vSize
, ulOptions
);
1612 m_nWindowExtX
= (int)MS_XDEV2LOGREL(VIEWPORT_EXTENT
);
1613 m_nWindowExtY
= (int)MS_YDEV2LOGREL(VIEWPORT_EXTENT
);
1615 }; // end of wxDC::SetMapMode
1617 void wxDC::SetUserScale(
1625 SetMapMode(m_mappingMode
);
1626 } // end of wxDC::SetUserScale
1628 void wxDC::SetAxisOrientation(
1633 m_signX
= bXLeftRight
? 1 : -1;
1634 m_signY
= bYBottomUp
? -1 : 1;
1636 SetMapMode(m_mappingMode
);
1637 } // end of wxDC::SetAxisOrientation
1639 void wxDC::SetSystemScale(
1647 SetMapMode(m_mappingMode
);
1648 } // end of wxDC::SetSystemScale
1650 void wxDC::SetLogicalOrigin(
1657 ::GpiQueryPageViewport( m_hPS
1664 ::GpiSetPageViewport( m_hPS
1667 }; // end of wxDC::SetLogicalOrigin
1669 void wxDC::SetDeviceOrigin(
1676 m_deviceOriginX
= vX
;
1677 m_deviceOriginY
= vY
;
1678 ::GpiQueryPageViewport( m_hPS
1683 vRect
.yBottom
-= vY
;
1685 ::GpiSetPageViewport( m_hPS
1688 }; // end of wxDC::SetDeviceOrigin
1690 // ---------------------------------------------------------------------------
1691 // coordinates transformations
1692 // ---------------------------------------------------------------------------
1694 wxCoord
wxDCBase::DeviceToLogicalX(wxCoord x
) const
1696 return (wxCoord
) (((x
) - m_deviceOriginX
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
) - m_logicalOriginX
);
1699 wxCoord
wxDCBase::DeviceToLogicalXRel(wxCoord x
) const
1701 return (wxCoord
) ((x
)/(m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
));
1704 wxCoord
wxDCBase::DeviceToLogicalY(wxCoord y
) const
1706 return (wxCoord
) (((y
) - m_deviceOriginY
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
) - m_logicalOriginY
);
1709 wxCoord
wxDCBase::DeviceToLogicalYRel(wxCoord y
) const
1711 return (wxCoord
) ((y
)/(m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
));
1714 wxCoord
wxDCBase::LogicalToDeviceX(wxCoord x
) const
1716 return (wxCoord
) ((x
- m_logicalOriginX
)*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
+ m_deviceOriginX
);
1719 wxCoord
wxDCBase::LogicalToDeviceXRel(wxCoord x
) const
1721 return (wxCoord
) (x
*m_logicalScaleX
*m_userScaleX
*m_signX
*m_scaleX
);
1724 wxCoord
wxDCBase::LogicalToDeviceY(wxCoord y
) const
1726 return (wxCoord
) ((y
- m_logicalOriginY
)*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
+ m_deviceOriginY
);
1729 wxCoord
wxDCBase::LogicalToDeviceYRel(wxCoord y
) const
1731 return (wxCoord
) (y
*m_logicalScaleY
*m_userScaleY
*m_signY
*m_scaleY
);
1734 // ---------------------------------------------------------------------------
1736 // ---------------------------------------------------------------------------
1750 wxMask
* pMask
= NULL
;
1752 COLORREF vOldTextColor
;
1753 COLORREF vOldBackground
= ::GpiQueryBackColor(m_hPS
);
1757 const wxBitmap
& rBmp
= pSource
->m_vSelectedBitmap
;
1759 pMask
= rBmp
.GetMask();
1760 if (!(rBmp
.Ok() && pMask
&& pMask
->GetMaskBitmap()))
1766 ::GpiQueryAttrs( m_hPS
1771 vOldTextColor
= (COLORREF
)vCbnd
.lColor
;
1773 if (m_textForegroundColour
.Ok())
1775 vCbnd
.lColor
= (LONG
)m_textForegroundColour
.GetPixel();
1776 ::GpiSetAttrs( m_hPS
// presentation-space handle
1777 ,PRIM_CHAR
// Char primitive.
1778 ,CBB_COLOR
// sets color.
1780 ,&vCbnd
// buffer for attributes.
1783 if (m_textBackgroundColour
.Ok())
1785 ::GpiSetBackColor(m_hPS
, (LONG
)m_textBackgroundColour
.GetPixel());
1788 LONG lRop
= ROP_SRCCOPY
;
1792 case wxXOR
: lRop
= ROP_SRCINVERT
; break;
1793 case wxINVERT
: lRop
= ROP_DSTINVERT
; break;
1794 case wxOR_REVERSE
: lRop
= 0x00DD0228; break;
1795 case wxAND_REVERSE
: lRop
= ROP_SRCERASE
; break;
1796 case wxCLEAR
: lRop
= ROP_ZERO
; break;
1797 case wxSET
: lRop
= ROP_ONE
; break;
1798 case wxOR_INVERT
: lRop
= ROP_MERGEPAINT
; break;
1799 case wxAND
: lRop
= ROP_SRCAND
; break;
1800 case wxOR
: lRop
= ROP_SRCPAINT
; break;
1801 case wxEQUIV
: lRop
= 0x00990066; break;
1802 case wxNAND
: lRop
= 0x007700E6; break;
1803 case wxAND_INVERT
: lRop
= 0x00220326; break;
1804 case wxCOPY
: lRop
= ROP_SRCCOPY
; break;
1805 case wxNO_OP
: lRop
= ROP_NOTSRCERASE
; break;
1806 case wxSRC_INVERT
: lRop
= ROP_SRCINVERT
; break;
1807 case wxNOR
: lRop
= ROP_NOTSRCCOPY
; break;
1809 wxFAIL_MSG( wxT("unsupported logical function") );
1818 // Blit bitmap with mask
1822 // Create a temp buffer bitmap and DCs/PSs to access it and the mask
1828 DEVOPENSTRUC vDOP
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1829 BITMAPINFOHEADER2 vBmpHdr
;
1830 SIZEL vSize
= {0, 0};
1833 hDCMask
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDOP
, NULLHANDLE
);
1834 hDCBuffer
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDOP
, NULLHANDLE
);
1835 hPSMask
= ::GpiCreatePS(vHabmain
, hDCMask
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
1836 hPSBuffer
= ::GpiCreatePS(vHabmain
, hDCBuffer
, &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
1838 memset(&vBmpHdr
, 0, sizeof(BITMAPINFOHEADER2
));
1839 vBmpHdr
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1840 vBmpHdr
.cx
= vWidth
;
1841 vBmpHdr
.cy
= vHeight
;
1842 vBmpHdr
.cPlanes
= 1;
1843 vBmpHdr
.cBitCount
= 24;
1845 HBITMAP hBufBitmap
= ::GpiCreateBitmap(GetHPS(), &vBmpHdr
, 0L, NULL
, NULL
);
1846 POINTL aPoint1
[4] = { 0, 0
1849 ,vXdest
+ vWidth
, vYdest
+ vHeight
1851 POINTL aPoint2
[4] = { 0, 0
1854 ,vXsrc
+ vWidth
, vYsrc
+ vHeight
1856 POINTL aPoint3
[4] = { vXdest
, vYdest
1857 ,vXdest
+ vWidth
, vYdest
+ vHeight
1859 ,vXsrc
+ vWidth
, vYsrc
+ vHeight
1861 POINTL aPoint4
[4] = { vXdest
, vYdest
1862 ,vXdest
+ vWidth
, vYdest
+ vHeight
1866 ::GpiSetBitmap(hPSMask
, (HBITMAP
) pMask
->GetMaskBitmap());
1867 ::GpiSetBitmap(hPSBuffer
, (HBITMAP
) hBufBitmap
);
1870 // Copy dest to buffer
1872 rc
= ::GpiBitBlt( hPSBuffer
1879 if (rc
== GPI_ERROR
)
1881 wxLogLastError(wxT("BitBlt"));
1885 // Copy src to buffer using selected raster op
1887 rc
= ::GpiBitBlt( hPSBuffer
1894 if (rc
== GPI_ERROR
)
1896 wxLogLastError(wxT("BitBlt"));
1900 // Set masked area in buffer to BLACK (pixel value 0)
1902 COLORREF vPrevBkCol
= ::GpiQueryBackColor(GetHPS());
1903 COLORREF vPrevCol
= ::GpiQueryColor(GetHPS());
1905 ::GpiSetBackColor(GetHPS(), OS2RGB(255, 255, 255));
1906 ::GpiSetColor(GetHPS(), OS2RGB(0, 0, 0));
1908 rc
= ::GpiBitBlt( hPSBuffer
1915 if (rc
== GPI_ERROR
)
1917 wxLogLastError(wxT("BitBlt"));
1921 // Set unmasked area in dest to BLACK
1923 ::GpiSetBackColor(GetHPS(), OS2RGB(0, 0, 0));
1924 ::GpiSetColor(GetHPS(), OS2RGB(255, 255, 255));
1925 rc
= ::GpiBitBlt( GetHPS()
1932 if (rc
== GPI_ERROR
)
1934 wxLogLastError(wxT("BitBlt"));
1938 // Restore colours to original values
1940 ::GpiSetBackColor(GetHPS(), vPrevBkCol
);
1941 ::GpiSetColor(GetHPS(), vPrevCol
);
1944 // OR buffer to dest
1946 rc
= ::GpiBitBlt( GetHPS()
1953 if (rc
== GPI_ERROR
)
1956 wxLogLastError(wxT("BitBlt"));
1960 // Tidy up temporary DCs and bitmap
1962 ::GpiSetBitmap(hPSMask
, NULLHANDLE
);
1963 ::GpiSetBitmap(hPSBuffer
, NULLHANDLE
);
1964 ::GpiDestroyPS(hPSMask
);
1965 ::GpiDestroyPS(hPSBuffer
);
1966 ::DevCloseDC(hDCMask
);
1967 ::DevCloseDC(hDCBuffer
);
1968 ::GpiDeleteBitmap(hBufBitmap
);
1971 else // no mask, just BitBlt() it
1973 POINTL aPoint
[4] = { vXdest
, vYdest
1974 ,vXdest
+ vWidth
, vYdest
+ vHeight
1976 ,vXsrc
+ vWidth
, vYsrc
+ vHeight
1979 bSuccess
= (::GpiBitBlt( m_hPS
1988 wxLogLastError(wxT("BitBlt"));
1991 vCbnd
.lColor
= (LONG
)vOldTextColor
;
1992 ::GpiSetAttrs( m_hPS
// presentation-space handle
1993 ,PRIM_CHAR
// Char primitive.
1994 ,CBB_COLOR
// sets color.
1996 ,&vCbnd
// buffer for attributes.
1998 ::GpiSetBackColor(m_hPS
, (LONG
)vOldBackground
);
2002 void wxDC::DoGetSize(
2007 LONG lArray
[CAPS_HEIGHT
];
2009 if(::DevQueryCaps( m_hDC
2015 *pnWidth
= lArray
[CAPS_WIDTH
];
2016 *pnHeight
= lArray
[CAPS_HEIGHT
];
2018 }; // end of wxDC::DoGetSize(
2020 void wxDC::DoGetSizeMM(
2025 LONG lArray
[CAPS_VERTICAL_RESOLUTION
];
2027 if(::DevQueryCaps( m_hDC
2029 ,CAPS_VERTICAL_RESOLUTION
2038 nWidth
= lArray
[CAPS_WIDTH
];
2039 nHeight
= lArray
[CAPS_HEIGHT
];
2040 nHorzRes
= lArray
[CAPS_HORIZONTAL_RESOLUTION
]; // returns pel/meter
2041 nVertRes
= lArray
[CAPS_VERTICAL_RESOLUTION
]; // returns pel/meter
2042 nWidth
= (nHorzRes
/1000) * nWidth
;
2043 nHeight
= (nVertRes
/1000) * nHeight
;
2045 }; // end of wxDC::DoGetSizeMM
2047 wxSize
wxDC::GetPPI() const
2049 LONG lArray
[CAPS_VERTICAL_RESOLUTION
];
2053 if(::DevQueryCaps( m_hDC
2055 ,CAPS_VERTICAL_RESOLUTION
2064 nPelWidth
= lArray
[CAPS_WIDTH
];
2065 nPelHeight
= lArray
[CAPS_HEIGHT
];
2066 nHorzRes
= lArray
[CAPS_HORIZONTAL_RESOLUTION
]; // returns pel/meter
2067 nVertRes
= lArray
[CAPS_VERTICAL_RESOLUTION
]; // returns pel/meter
2068 nWidth
= (nHorzRes
/39.3) * nPelWidth
;
2069 nHeight
= (nVertRes
/39.3) * nPelHeight
;
2071 return (wxSize(nWidth
,nHeight
));
2072 } // end of wxDC::GetPPI
2074 void wxDC::SetLogicalScale(
2079 m_logicalScaleX
= dX
;
2080 m_logicalScaleY
= dY
;
2081 }; // end of wxDC::SetLogicalScale
2083 #if WXWIN_COMPATIBILITY
2084 void wxDC::DoGetTextExtent(const wxString
& string
, float *x
, float *y
,
2085 float *descent
, float *externalLeading
,
2086 wxFont
*theFont
, bool use16bit
) const
2088 wxCoord x1
, y1
, descent1
, externalLeading1
;
2089 GetTextExtent(string
, & x1
, & y1
, & descent1
, & externalLeading1
, theFont
, use16bit
);
2092 *descent
= descent1
;
2093 if (externalLeading
)
2094 *externalLeading
= externalLeading1
;