]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/dc.cpp
1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "dc.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
27 #include "wx/dialog.h"
31 #include "wx/dcprint.h"
32 #include "wx/msw/private.h"
38 #if USE_COMMON_DIALOGS
58 #if !USE_SHARED_LIBRARY
59 IMPLEMENT_ABSTRACT_CLASS(wxDC
, wxObject
)
62 // Declarations local to this file
64 #define YSCALE(y) (yorigin - (y))
66 // #define wx_round(a) (int)((a)+.5)
68 // Default constructor
71 // Stop internal GDI objects being found and pointers kept
72 // after these objects have been deleted.
73 // No - it's OK; these lists won't return them
74 // because their 'visible' status will be FALSE.
76 wxTheFontList->RemoveFont(&m_font);
77 wxThePenList->RemovePen(&m_pen);
78 wxTheBrushList->RemoveBrush(&m_brush);
79 wxTheBrushList->RemoveBrush(&m_backgroundBrush);
82 m_minX
= 0; m_minY
= 0; m_maxX
= 0; m_maxY
= 0;
84 m_autoSetting
= TRUE
;
88 // m_selectedBitmap = NULL;
101 m_minX
= 0; m_minY
= 0; m_maxX
= 0; m_maxY
= 0;
103 m_logicalOriginX
= 0;
104 m_logicalOriginY
= 0;
107 m_logicalScaleX
= 1.0;
108 m_logicalScaleY
= 1.0;
111 m_systemScaleX
= 1.0;
112 m_systemScaleY
= 1.0;
113 m_mappingMode
= MM_TEXT
;
114 // m_dontDelete = FALSE;
119 m_windowExtX
= VIEWPORT_EXTENT
;
120 m_windowExtY
= VIEWPORT_EXTENT
;
121 m_logicalFunction
= -1;
123 m_backgroundBrush
= *wxWHITE_BRUSH
;
124 // m_backgroundBrush.UseResource();
126 m_textForegroundColour
= *wxBLACK
;
127 m_textBackgroundColour
= *wxWHITE
;
129 m_colour
= wxColourDisplay();
138 SelectOldObjects(m_hDC
);
140 if ( m_canvas
== NULL
)
141 ::DeleteDC((HDC
)m_hDC
);
143 ::ReleaseDC((HWND
)m_canvas
->GetHWND(), (HDC
)m_hDC
);
150 SelectOldObjects(m_hDC);
151 ::DeleteDC((HDC) m_hDC);
156 // This will select current objects out of the DC,
157 // which is what you have to do before deleting the
159 void wxDC::SelectOldObjects(WXHDC dc
)
162 wxDebugMsg("wxDC::SelectOldObjects %X\n", this);
169 wxDebugMsg("wxDC::SelectOldObjects: Selecting old HBITMAP %X\n", m_oldBitmap
);
171 ::SelectObject((HDC
) dc
, (HBITMAP
) m_oldBitmap
);
172 if (m_selectedBitmap
.Ok())
174 m_selectedBitmap
.SetSelectedInto(NULL
);
181 wxDebugMsg("wxDC::SelectOldObjects: Selecting old HPEN %X\n", m_oldPen
);
183 ::SelectObject((HDC
) dc
, (HPEN
) m_oldPen
);
189 wxDebugMsg("wxDC::SelectOldObjects: Selecting old HBRUSH %X\n", m_oldBrush
);
191 ::SelectObject((HDC
) dc
, (HBRUSH
) m_oldBrush
);
197 wxDebugMsg("wxDC::SelectOldObjects: Selecting old HFONT %X\n", m_oldFont
);
199 ::SelectObject((HDC
) dc
, (HFONT
) m_oldFont
);
205 wxDebugMsg("wxDC::SelectOldObjects: Selecting old HPALETTE %X\n", m_oldPalette
);
207 ::SelectPalette((HDC
) dc
, (HPALETTE
) m_oldPalette
, TRUE
);
210 wxDebugMsg("wxDC::SelectOldObjects: Done.\n");
216 m_font.ReleaseResource();
218 m_pen.ReleaseResource();
220 m_brush.ReleaseResource();
221 if (m_backgroundBrush.Ok())
222 m_backgroundBrush.ReleaseResource();
225 m_brush
= wxNullBrush
;
227 m_palette
= wxNullPalette
;
229 m_backgroundBrush
= wxNullBrush
;
230 m_selectedBitmap
= wxNullBitmap
;
233 void wxDC::SetClippingRegion(long cx
, long cy
, long cw
, long ch
)
238 m_clipX2
= (int)(cx
+ cw
);
239 m_clipY2
= (int)(cy
+ ch
);
243 DoClipping((WXHDC
) m_hDC
);
248 void wxDC::DoClipping(WXHDC dc
)
250 if (m_clipping
&& dc
)
252 IntersectClipRect((HDC
) dc
, XLOG2DEV(m_clipX1
), YLOG2DEV(m_clipY1
),
253 XLOG2DEV(m_clipX2
), YLOG2DEV(m_clipY2
));
259 m_canvas
->CalcScrolledPosition(0, 0, &x_off
, &y_off
);
261 // HRGN rgn = CreateRectRgn(XLOG2DEV(m_clipX1 + x_off), YLOG2DEV(m_clipY1 + y_off),
262 // XLOG2DEV(m_clipX2 + x_off), YLOG2DEV(m_clipY2 + y_off));
264 // SelectClipRgn(dc, rgn);
265 // DeleteObject(rgn);
266 IntersectClipRect((HDC
) dc
, XLOG2DEV(m_clipX1
+ x_off
), YLOG2DEV(m_clipY1
+ y_off
),
267 XLOG2DEV(m_clipX2
+ x_off
), YLOG2DEV(m_clipY2
+ y_off
));
272 void wxDC::DestroyClippingRegion(void)
276 if (m_clipping
&& m_hDC
)
278 // SelectClipRgn(dc, NULL);
279 HRGN rgn
= CreateRectRgn(0, 0, 32000, 32000);
281 wxDebugMsg("wxDC::DestroyClippingRegion: Selecting HRGN %X\n", rgn
);
283 SelectClipRgn((HDC
) m_hDC
, rgn
);
285 wxDebugMsg("wxDC::DestroyClippingRegion: Deleting HRGN %X\n", rgn
);
294 bool wxDC::CanDrawBitmap(void) const
299 bool wxDC::CanGetTextExtent(void) const
301 // What sort of display is it?
302 int technology
= ::GetDeviceCaps((HDC
) m_hDC
, TECHNOLOGY
);
306 if (technology
!= DT_RASDISPLAY
&& technology
!= DT_RASPRINTER
)
313 void wxDC::SetPalette(const wxPalette
& palette
)
317 m_palette
= m_palette
;
321 // Setting a NULL colourmap is a way of restoring
322 // the original colourmap
325 ::SelectPalette((HDC
) m_hDC
, (HPALETTE
) m_oldPalette
, TRUE
);
327 wxDebugMsg("wxDC::SetPalette: set old palette %X\n", m_oldPalette
);
335 if (m_palette
.Ok() && m_palette
.GetHPALETTE())
337 HPALETTE oldPal
= ::SelectPalette((HDC
) m_hDC
, (HPALETTE
) m_palette
.GetHPALETTE(), TRUE
);
339 m_oldPalette
= (WXHPALETTE
) oldPal
;
342 wxDebugMsg("wxDC::SetPalette %X: selected palette %X\n", this, m_palette
.GetHPALETTE());
344 wxDebugMsg("wxDC::SetPalette: oldPal was palette %X\n", oldPal
);
346 wxDebugMsg("wxDC::SetPalette: m_oldPalette is palette %X\n", m_oldPalette
);
348 ::RealizePalette((HDC
) m_hDC
);
354 void wxDC::Clear(void)
360 GetClientRect((HWND
) m_canvas
->GetHWND(), &rect
);
361 else if (m_selectedBitmap
.Ok())
363 rect
.left
= 0; rect
.top
= 0;
364 rect
.right
= m_selectedBitmap
.GetWidth();
365 rect
.bottom
= m_selectedBitmap
.GetHeight();
367 (void) ::SetMapMode((HDC
) m_hDC
, MM_TEXT
);
369 DWORD colour
= GetBkColor((HDC
) m_hDC
);
370 HBRUSH brush
= CreateSolidBrush(colour
);
371 FillRect((HDC
) m_hDC
, &rect
, brush
);
374 ::SetMapMode((HDC
) m_hDC
, MM_ANISOTROPIC
);
375 ::SetViewportExtEx((HDC
) m_hDC
, VIEWPORT_EXTENT
, VIEWPORT_EXTENT
, NULL
);
376 ::SetWindowExtEx((HDC
) m_hDC
, m_windowExtX
, m_windowExtY
, NULL
);
377 ::SetViewportOrgEx((HDC
) m_hDC
, (int)m_deviceOriginX
, (int)m_deviceOriginY
, NULL
);
378 ::SetWindowOrgEx((HDC
) m_hDC
, (int)m_logicalOriginX
, (int)m_logicalOriginY
, NULL
);
383 void wxDC::FloodFill(long x
, long y
, wxColour
*col
, int style
)
388 if (m_brush
.Ok() && m_autoSetting
)
392 // m_canvas->CalcScrolledPosition((int)x, (int)y, &xx, &yy);
396 (void)ExtFloodFill((HDC
) m_hDC
, XLOG2DEV(x
), YLOG2DEV(y
),
398 style
==wxFLOOD_SURFACE
?
399 FLOODFILLSURFACE
:FLOODFILLBORDER
404 CalcBoundingBox(x
, y
);
407 bool wxDC::GetPixel(long x
, long y
, wxColour
*col
) const
409 // added by steve 29.12.94 (copied from DrawPoint)
410 // returns TRUE for pixels in the color of the current pen
411 // and FALSE for all other pixels colors
412 // if col is non-NULL return the color of the pixel
417 m_canvas->CalcScrolledPosition((int)x, (int)y, &xx1, &yy1);
420 // get the color of the pixel
421 COLORREF pixelcolor
= ::GetPixel((HDC
) m_hDC
, XLOG2DEV(x
), YLOG2DEV(y
));
422 // get the color of the pen
423 COLORREF pencolor
= 0x00ffffff;
426 pencolor
= m_pen
.GetColour().GetPixel() ;
429 // return the color of the pixel
431 col
->Set(GetRValue(pixelcolor
),GetGValue(pixelcolor
),GetBValue(pixelcolor
));
433 // check, if color of the pixels is the same as the color
434 // of the current pen
435 return(pixelcolor
==pencolor
);
438 void wxDC::CrossHair(long x
, long y
)
440 if (m_pen
.Ok() && m_autoSetting
)
443 // We suppose that our screen is 2000x2000 max.
458 m_canvas->CalcScrolledPosition(x1, y1, &xx1, &yy1);
459 m_canvas->CalcScrolledPosition(x2, y2, &xx2, &yy2);
460 m_canvas->CalcScrolledPosition(x, y, &xx, &yy);
466 (void)MoveToEx((HDC
) m_hDC
, XLOG2DEV(x1
), YLOG2DEV(y
), NULL
);
467 (void)LineTo((HDC
) m_hDC
, XLOG2DEV(x2
), YLOG2DEV(y
));
469 (void)MoveToEx((HDC
) m_hDC
, XLOG2DEV(x
), YLOG2DEV(y1
), NULL
);
470 (void)LineTo((HDC
) m_hDC
, XLOG2DEV(x
), YLOG2DEV(y2
));
474 CalcBoundingBox(x1
, y1
);
475 CalcBoundingBox(x2
, y2
);
478 void wxDC::DrawLine(long x1
, long y1
, long x2
, long y2
)
480 // BUGBUG - is this necessary? YES YES YES YEs Yes yes ye....
481 if (m_pen
.Ok() && m_autoSetting
)
490 m_canvas->CalcScrolledPosition((int)x1, (int)y1, &xx1, &yy1);
491 m_canvas->CalcScrolledPosition((int)x2, (int)y2, &xx2, &yy2);
497 (void)MoveToEx((HDC
) m_hDC
, XLOG2DEV(x1
), YLOG2DEV(y1
), NULL
);
498 (void)LineTo((HDC
) m_hDC
, XLOG2DEV(x2
), YLOG2DEV(y2
));
500 /* MATTHEW: [6] New normalization */
501 #if WX_STANDARD_GRAPHICS
502 (void)LineTo((HDC
) m_hDC
, XLOG2DEV(x2
) + 1, YLOG2DEV(y2
));
507 CalcBoundingBox(x1
, y1
);
508 CalcBoundingBox(x2
, y2
);
511 void wxDC::DrawArc(long x1
,long y1
,long x2
,long y2
,double xc
,double yc
)
524 double radius
= (double)sqrt(dx
*dx
+dy
*dy
) ;;
525 if (x1
==x2
&& x2
==y2
)
527 DrawEllipse(xc
,yc
,(double)(radius
*2.0),(double)(radius
*2)) ;
531 // BUGBUG - is this necessary?
532 if (m_pen
.Ok() && m_autoSetting
)
538 m_canvas->CalcScrolledPosition((int)x1, (int)y1, &xx1, &yy1);
539 m_canvas->CalcScrolledPosition((int)x2, (int)y2, &xx2, &yy2);
540 m_canvas->CalcScrolledPosition((int)xc, (int)yc, &xxc, &yyc);
546 long xx1
= XLOG2DEV(x1
) ;
547 long yy1
= YLOG2DEV(y1
) ;
548 long xx2
= XLOG2DEV(x2
) ;
549 long yy2
= YLOG2DEV(y2
) ;
550 long xxc
= XLOG2DEV(xc
) ;
551 long yyc
= YLOG2DEV(yc
) ;
552 long ray
= (long) sqrt(double((xxc
-xx1
)*(xxc
-xx1
)+(yyc
-yy1
)*(yyc
-yy1
))) ;
554 (void)MoveToEx((HDC
) m_hDC
, (int) xx1
, (int) yy1
, NULL
);
555 long xxx1
= (long) (xxc
-ray
);
556 long yyy1
= (long) (yyc
-ray
);
557 long xxx2
= (long) (xxc
+ray
);
558 long yyy2
= (long) (yyc
+ray
);
559 if (m_brush
.Ok() && m_brush
.GetStyle() !=wxTRANSPARENT
)
561 // BUGBUG - is this necessary?
562 if (m_brush
.GetStyle()!=wxTRANSPARENT
&&m_autoSetting
)
564 Pie((HDC
) m_hDC
,xxx1
,yyy1
,xxx2
,yyy2
,
568 Arc((HDC
) m_hDC
,xxx1
,yyy1
,xxx2
,yyy2
,
573 CalcBoundingBox((xc
-radius
), (yc
-radius
));
574 CalcBoundingBox((xc
+radius
), (yc
+radius
));
577 void wxDC::DrawEllipticArc(long WXUNUSED(x
),long WXUNUSED(y
),long WXUNUSED(w
),long WXUNUSED(h
),double WXUNUSED(sa
),double WXUNUSED(ea
))
582 void wxDC::DrawPoint(long x
, long y
)
584 // BUGBUG - is this necessary?
585 if (m_pen
.Ok() && m_autoSetting
)
592 m_canvas->CalcScrolledPosition((int)x, (int)y, &xx1, &yy1);
597 COLORREF color
= 0x00ffffff;
600 // m_pen.RealizeResource();
601 color
= m_pen
.GetColour().GetPixel() ;
605 color = RGB(m_pen->GetColour().Red(),
606 m_pen->GetColour().Green(),
607 m_pen->GetColour().Blue());
610 SetPixel((HDC
) m_hDC
, XLOG2DEV(x
), YLOG2DEV(y
), color
);
614 CalcBoundingBox(x
, y
);
617 void wxDC::DrawPolygon(int n
, wxPoint points
[], long xoffset
, long yoffset
,int fillStyle
)
619 // BUGBUG - is this necessary?
620 if (m_pen
.Ok() && m_autoSetting
)
627 m_canvas->CalcScrolledPosition(0, 0, &xoffset1, &yoffset1);
629 xoffset1 += (int)xoffset; yoffset1 += (int)yoffset;
634 POINT
*cpoints
= new POINT
[n
];
636 for (i
= 0; i
< n
; i
++)
638 cpoints
[i
].x
= (int)(XLOG2DEV(points
[i
].x
));
639 cpoints
[i
].y
= (int)(YLOG2DEV(points
[i
].y
));
641 CalcBoundingBox(points
[i
].x
, points
[i
].y
);
644 int prev
= SetPolyFillMode((HDC
) m_hDC
,fillStyle
==wxODDEVEN_RULE
?ALTERNATE
:WINDING
) ;
645 (void)Polygon((HDC
) m_hDC
, cpoints
, n
);
646 SetPolyFillMode((HDC
) m_hDC
,prev
) ;
653 void wxDC::DrawLines(int n
, wxPoint points
[], long xoffset
, long yoffset
)
655 // BUGBUG - is this necessary?
656 if (m_pen
.Ok() && m_autoSetting
)
665 m_canvas->CalcScrolledPosition(0, 0, &xoffset1, &yoffset1);
667 xoffset1 += (int)xoffset; yoffset1 += (int)yoffset;
672 POINT
*cpoints
= new POINT
[n
];
674 for (i
= 0; i
< n
; i
++)
676 cpoints
[i
].x
= (int)(XLOG2DEV(points
[i
].x
));
677 cpoints
[i
].y
= (int)(YLOG2DEV(points
[i
].y
));
679 CalcBoundingBox(points
[i
].x
, points
[i
].y
);
682 (void)Polyline((HDC
) m_hDC
, cpoints
, n
);
689 void wxDC::DrawRectangle(long x
, long y
, long width
, long height
)
691 // BUGBUG - is this necessary?
692 if (m_pen
.Ok() && m_autoSetting
)
698 int x2 = (int)(x+width);
699 int y2 = (int)(y+height);
703 m_canvas->CalcScrolledPosition((int)x, (int)y, &x1, &y1);
704 m_canvas->CalcScrolledPosition((int)(x+width), (int)(y+height), &x2, &y2);
708 long y2
= y
+ height
;
712 /* MATTHEW: [6] new normalization */
713 #if WX_STANDARD_GRAPHICS
714 bool do_brush
, do_pen
;
716 do_brush
= m_brush
.Ok() && m_brush
.GetStyle() != wxTRANSPARENT
;
717 do_pen
= m_pen
.Ok() && m_pen
.GetStyle() != wxTRANSPARENT
;
720 HPEN orig_pen
= NULL
;
722 if (do_pen
|| !m_pen
.Ok())
723 orig_pen
= ::SelectObject((HDC
) m_hDC
, ::GetStockObject(NULL_PEN
));
725 (void)Rectangle((HDC
) m_hDC
, XLOG2DEV(x
), YLOG2DEV(y
),
726 XLOG2DEV(x2
) + 1, YLOG2DEV(y2
) + 1);
728 if (do_pen
|| !m_pen
.Ok())
729 ::SelectObject((HDC
) m_hDC
, orig_pen
);
732 HBRUSH orig_brush
= NULL
;
734 if (do_brush
|| !m_brush
.Ok())
735 orig_brush
= ::SelectObject((HDC
) m_hDC
, ::GetStockObject(NULL_BRUSH
));
737 (void)Rectangle((HDC
) m_hDC
, XLOG2DEV(x
), YLOG2DEV(y
),
738 XLOG2DEV(x2
), YLOG2DEV(y2
));
740 if (do_brush
|| !m_brush
.Ok())
741 ::SelectObject((HDC
) m_hDC
, orig_brush
);
744 (void)Rectangle((HDC
) m_hDC
, XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x2
), YLOG2DEV(y2
));
747 CalcBoundingBox(x
, y
);
748 CalcBoundingBox(x2
, y2
);
753 void wxDC::DrawRoundedRectangle(long x
, long y
, long width
, long height
, double radius
)
755 // BUGBUG - is this necessary?
756 if (m_pen
.Ok() && m_autoSetting
)
759 // Now, a negative radius value is interpreted to mean
760 // 'the proportion of the smallest X or Y dimension'
764 double smallest
= 0.0;
769 radius
= (- radius
* smallest
);
778 m_canvas->CalcScrolledPosition((int)x, (int)y, &x1, &y1);
779 m_canvas->CalcScrolledPosition((int)(x+width), (int)(y+height), &x2, &y2);
784 long y2
= (y
+height
);
788 (void)RoundRect((HDC
) m_hDC
, XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x2
),
789 YLOG2DEV(y2
), 2*XLOG2DEV(radius
), 2*YLOG2DEV(radius
));
791 CalcBoundingBox(x
, y
);
792 CalcBoundingBox(x2
, y2
);
797 void wxDC::DrawEllipse(long x
, long y
, long width
, long height
)
799 // BUGBUG - is this necessary?
800 if (m_pen
.Ok() && m_autoSetting
)
809 m_canvas->CalcScrolledPosition((int)x, (int)y, &x1, &y1);
810 m_canvas->CalcScrolledPosition((int)(x+width), (int)(y+height), &x2, &y2);
815 long y2
= (y
+height
);
819 (void)Ellipse((HDC
) m_hDC
, XLOG2DEV(x
), YLOG2DEV(y
), XLOG2DEV(x2
), YLOG2DEV(y2
));
823 CalcBoundingBox(x
, y
);
824 CalcBoundingBox(x2
, y2
);
827 void wxDC::DrawIcon(const wxIcon
& icon
, long x
, long y
)
834 m_canvas->CalcScrolledPosition(int)x, (int)y, &x1, &y1);
839 ::DrawIcon((HDC
) m_hDC
, XLOG2DEV(x
), YLOG2DEV(y
), (HICON
) icon
.GetHICON());
840 CalcBoundingBox(x
, y
);
841 CalcBoundingBox(x
+icon
.GetWidth(), y
+icon
.GetHeight());
846 void wxDC::SetFont(const wxFont
& the_font
)
848 // Release the current font from servitude (decrements the usage count)
850 // m_font.ReleaseResource();
859 ::SelectObject((HDC
) m_hDC
, (HFONT
) m_oldFont
);
863 if (m_font
.Ok() && m_font
.GetResourceHandle())
866 wxDebugMsg("wxDC::SetFont: Selecting HFONT %X\n", m_font
.GetResourceHandle());
868 HFONT f
= (HFONT
) ::SelectObject((HDC
) m_hDC
, (HFONT
) m_font
.GetResourceHandle());
870 m_oldFont
= (WXHFONT
) f
;
875 void wxDC::SetPen(const wxPen
& pen
)
880 // m_pen.ReleaseResource();
887 ::SelectObject((HDC
) m_hDC
, (HPEN
) m_oldPen
);
893 // m_pen.UseResource();
894 // m_pen.RealizeResource();
895 if (m_pen
.GetResourceHandle())
897 HPEN p
= (HPEN
) ::SelectObject((HDC
) m_hDC
, (HPEN
)m_pen
.GetResourceHandle()) ;
899 m_oldPen
= (WXHPEN
) p
;
906 void wxDC::SetBrush(const wxBrush
& brush
)
911 // m_brush.ReleaseResource();
918 ::SelectObject((HDC
) m_hDC
, (HBRUSH
) m_oldBrush
);
924 // m_brush.UseResource();
925 // m_brush.RealizeResource();
927 if (m_brush
.GetResourceHandle())
930 b
= ::SelectObject((HDC
) m_hDC
, (HBRUSH
)m_brush
.GetResourceHandle()) ;
932 m_oldBrush
= (WXHBRUSH
) b
;
938 void wxDC::DrawText(const wxString
& text
, long x
, long y
, bool use16bit
)
945 m_canvas->CalcScrolledPosition((int)x, (int)y, &xx1, &yy1);
950 if (m_font
.Ok() && m_font
.GetResourceHandle())
953 wxDebugMsg("wxDC::DrawText: Selecting HFONT %X\n", m_font
.GetResourceHandle());
955 HFONT f
= ::SelectObject((HDC
) m_hDC
, (HFONT
) m_font
.GetResourceHandle());
957 m_oldFont
= (WXHFONT
) f
;
960 if (m_textForegroundColour
.Ok())
961 SetTextColor((HDC
) m_hDC
, m_textForegroundColour
.GetPixel() ) ;
963 DWORD old_background
;
964 if (m_textBackgroundColour
.Ok())
966 old_background
= SetBkColor((HDC
) m_hDC
, m_textBackgroundColour
.GetPixel() ) ;
969 if (m_backgroundMode
== wxTRANSPARENT
)
970 SetBkMode((HDC
) m_hDC
, TRANSPARENT
);
972 SetBkMode((HDC
) m_hDC
, OPAQUE
);
974 (void)TextOut((HDC
) m_hDC
, XLOG2DEV(x
), YLOG2DEV(y
), (char *) (const char *)text
, strlen((const char *)text
));
976 if (m_textBackgroundColour
.Ok())
977 (void)SetBkColor((HDC
) m_hDC
, old_background
);
979 CalcBoundingBox(x
, y
);
982 GetTextExtent(text
, &w
, &h
);
983 CalcBoundingBox((x
+ w
), (y
+ h
));
988 void wxDC::SetBackground(const wxBrush
& brush
)
990 // if (m_backgroundBrush.Ok())
991 // m_backgroundBrush.ReleaseResource();
993 m_backgroundBrush
= brush
;
995 if (!m_backgroundBrush
.Ok())
998 // m_backgroundBrush.UseResource();
999 // m_backgroundBrush.RealizeResource() ;
1003 bool customColours
= TRUE
;
1004 // If we haven't specified wxUSER_COLOURS, don't allow the panel/dialog box to
1005 // change background colours from the control-panel specified colours.
1006 if (m_canvas
->IsKindOf(CLASSINFO(wxWindow
)) && ((m_canvas
->GetWindowStyleFlag() & wxUSER_COLOURS
) != wxUSER_COLOURS
))
1007 customColours
= FALSE
;
1011 // HBRUSH br = (m_backgroundBrush.GetStyle()==wxTRANSPARENT) ?
1012 // GetStockObject(NULL_BRUSH) : (HBRUSH) m_backgroundBrush.GetResourceHandle();
1013 if (m_backgroundBrush
.GetStyle()==wxTRANSPARENT
)
1015 m_canvas
->m_backgroundTransparent
= TRUE
;
1019 m_canvas
->SetBackgroundColour(m_backgroundBrush
.GetColour());
1020 m_canvas
->m_backgroundTransparent
= FALSE
;
1026 COLORREF new_color
= m_backgroundBrush
.GetColour().GetPixel() ;
1028 (void)SetBkColor((HDC
) m_hDC
, new_color
);
1034 void wxDC::SetBackgroundMode(int mode
)
1036 m_backgroundMode
= mode
;
1040 if (m_backgroundMode
== wxTRANSPARENT
)
1041 ::SetBkMode((HDC
) m_hDC
, TRANSPARENT
);
1043 ::SetBkMode((HDC
) m_hDC
, OPAQUE
);
1048 void wxDC::SetLogicalFunction(int function
)
1050 m_logicalFunction
= function
;
1054 SetRop((WXHDC
) m_hDC
);
1059 void wxDC::SetRop(WXHDC dc
)
1061 if (!dc
|| m_logicalFunction
< 0)
1065 // These may be wrong
1066 switch (m_logicalFunction
)
1068 // case wxXOR: c_rop = R2_XORPEN; break;
1069 case wxXOR
: c_rop
= R2_NOTXORPEN
; break;
1070 case wxINVERT
: c_rop
= R2_NOT
; break;
1071 case wxOR_REVERSE
: c_rop
= R2_MERGEPENNOT
; break;
1072 case wxAND_REVERSE
: c_rop
= R2_MASKPENNOT
; break;
1073 case wxCLEAR
: c_rop
= R2_WHITE
; break;
1074 case wxSET
: c_rop
= R2_BLACK
; break;
1075 case wxSRC_INVERT
: c_rop
= R2_NOTCOPYPEN
; break;
1076 case wxOR_INVERT
: c_rop
= R2_MERGENOTPEN
; break;
1077 case wxAND
: c_rop
= R2_MASKPEN
; break;
1078 case wxOR
: c_rop
= R2_MERGEPEN
; break;
1079 case wxAND_INVERT
: c_rop
= R2_MASKNOTPEN
; break;
1084 c_rop
= R2_COPYPEN
; break;
1086 SetROP2((HDC
) dc
, c_rop
);
1089 bool wxDC::StartDoc(const wxString
& message
)
1091 if (!this->IsKindOf(CLASSINFO(wxPrinterDC
)))
1097 docinfo
.cbSize
= sizeof(DOCINFO
);
1098 docinfo
.lpszDocName
= (const char *)message
;
1099 docinfo
.lpszOutput
= (const char *)m_filename
;
1100 #if defined(__WIN95__)
1101 docinfo
.lpszDatatype
= NULL
;
1105 if (m_hDC
) flag
= (SP_ERROR
!=
1107 ::StartDoc((HDC
) m_hDC
, &docinfo
));
1110 ::StartDocW((HDC
) m_hDC
, &docinfo
));
1112 ::StartDocA((HDC
) m_hDC
, &docinfo
));
1121 void wxDC::EndDoc(void)
1123 if (!this->IsKindOf(CLASSINFO(wxPrinterDC
)))
1125 if (m_hDC
) ::EndDoc((HDC
) m_hDC
);
1128 void wxDC::StartPage(void)
1130 if (!this->IsKindOf(CLASSINFO(wxPrinterDC
)))
1133 ::StartPage((HDC
) m_hDC
);
1136 void wxDC::EndPage(void)
1138 if (!this->IsKindOf(CLASSINFO(wxPrinterDC
)))
1141 ::EndPage((HDC
) m_hDC
);
1144 long wxDC::GetCharHeight(void) const
1146 TEXTMETRIC lpTextMetric
;
1148 GetTextMetrics((HDC
) m_hDC
, &lpTextMetric
);
1150 return YDEV2LOGREL(lpTextMetric
.tmHeight
);
1153 long wxDC::GetCharWidth(void) const
1155 TEXTMETRIC lpTextMetric
;
1157 GetTextMetrics((HDC
) m_hDC
, &lpTextMetric
);
1159 return XDEV2LOGREL(lpTextMetric
.tmAveCharWidth
);
1162 void wxDC::GetTextExtent(const wxString
& string
, long *x
, long *y
,
1163 long *descent
, long *externalLeading
, wxFont
*theFont
, bool use16bit
) const
1165 wxFont
*fontToUse
= (wxFont
*) theFont
;
1167 fontToUse
= (wxFont
*) &m_font
;
1172 GetTextExtentPoint((HDC
) m_hDC
, (char *)(const char *) string
, strlen((char *)(const char *) string
), &sizeRect
);
1173 GetTextMetrics((HDC
) m_hDC
, &tm
);
1175 *x
= XDEV2LOGREL(sizeRect
.cx
);
1176 *y
= YDEV2LOGREL(sizeRect
.cy
);
1177 if (descent
) *descent
= tm
.tmDescent
;
1178 if (externalLeading
) *externalLeading
= tm
.tmExternalLeading
;
1181 void wxDC::SetMapMode(int mode
)
1183 m_mappingMode
= mode
;
1185 int pixel_width
= 0;
1186 int pixel_height
= 0;
1192 pixel_width
= GetDeviceCaps((HDC
) m_hDC
, HORZRES
);
1193 pixel_height
= GetDeviceCaps((HDC
) m_hDC
, VERTRES
);
1194 mm_width
= GetDeviceCaps((HDC
) m_hDC
, HORZSIZE
);
1195 mm_height
= GetDeviceCaps((HDC
) m_hDC
, VERTSIZE
);
1197 if ((pixel_width
== 0) || (pixel_height
== 0) || (mm_width
== 0) || (mm_height
== 0))
1199 // if (!m_hDC && m_canvas)
1200 // m_canvas->ReleaseHDC() ;
1204 double mm2pixelsX
= pixel_width
/mm_width
;
1205 double mm2pixelsY
= pixel_height
/mm_height
;
1211 m_logicalScaleX
= (twips2mm
* mm2pixelsX
);
1212 m_logicalScaleY
= (twips2mm
* mm2pixelsY
);
1217 m_logicalScaleX
= (pt2mm
* mm2pixelsX
);
1218 m_logicalScaleY
= (pt2mm
* mm2pixelsY
);
1223 m_logicalScaleX
= mm2pixelsX
;
1224 m_logicalScaleY
= mm2pixelsY
;
1229 m_logicalScaleX
= (mm2pixelsX
/10.0);
1230 m_logicalScaleY
= (mm2pixelsY
/10.0);
1236 m_logicalScaleX
= 1.0;
1237 m_logicalScaleY
= 1.0;
1242 if (::GetMapMode((HDC
) m_hDC
) != MM_ANISOTROPIC
)
1243 ::SetMapMode((HDC
) m_hDC
, MM_ANISOTROPIC
);
1245 SetViewportExtEx((HDC
) m_hDC
, VIEWPORT_EXTENT
, VIEWPORT_EXTENT
, NULL
);
1246 m_windowExtX
= (int)MS_XDEV2LOGREL(VIEWPORT_EXTENT
);
1247 m_windowExtY
= (int)MS_YDEV2LOGREL(VIEWPORT_EXTENT
);
1248 ::SetWindowExtEx((HDC
) m_hDC
, m_windowExtX
, m_windowExtY
, NULL
);
1249 ::SetViewportOrgEx((HDC
) m_hDC
, (int)m_deviceOriginX
, (int)m_deviceOriginY
, NULL
);
1250 ::SetWindowOrgEx((HDC
) m_hDC
, (int)m_logicalOriginX
, (int)m_logicalOriginY
, NULL
);
1255 void wxDC::SetUserScale(double x
, double y
)
1260 SetMapMode(m_mappingMode
);
1263 void wxDC::SetSystemScale(double x
, double y
)
1268 SetMapMode(m_mappingMode
);
1271 void wxDC::SetLogicalOrigin(long x
, long y
)
1273 m_logicalOriginX
= x
;
1274 m_logicalOriginY
= y
;
1278 ::SetWindowOrgEx((HDC
) m_hDC
, (int)m_logicalOriginX
, (int)m_logicalOriginY
, NULL
);
1283 void wxDC::SetDeviceOrigin(long x
, long y
)
1285 m_deviceOriginX
= x
;
1286 m_deviceOriginY
= y
;
1290 ::SetViewportOrgEx((HDC
) m_hDC
, (int)m_deviceOriginX
, (int)m_deviceOriginY
, NULL
);
1295 long wxDC::DeviceToLogicalX(long x
) const
1297 return (long) (((x
) - m_deviceOriginX
)/(m_logicalScaleX
*m_userScaleX
*m_systemScaleX
) - m_logicalOriginX
) ;
1300 long wxDC::DeviceToLogicalXRel(long x
) const
1302 return (long) ((x
)/(m_logicalScaleX
*m_userScaleX
*m_systemScaleX
)) ;
1305 long wxDC::DeviceToLogicalY(long y
) const
1307 return (long) (((y
) - m_deviceOriginY
)/(m_logicalScaleY
*m_userScaleY
*m_systemScaleY
) - m_logicalOriginY
) ;
1310 long wxDC::DeviceToLogicalYRel(long y
) const
1312 return (long) ((y
)/(m_logicalScaleY
*m_userScaleY
*m_systemScaleY
)) ;
1315 long wxDC::LogicalToDeviceX(long x
) const
1317 return (long) (floor((x
) - m_logicalOriginX
)*m_logicalScaleX
*m_userScaleX
*m_systemScaleX
+ m_deviceOriginX
) ;
1320 long wxDC::LogicalToDeviceXRel(long x
) const
1322 return (long) (floor(x
)*m_logicalScaleX
*m_userScaleX
*m_systemScaleX
) ;
1325 long wxDC::LogicalToDeviceY(long y
) const
1327 return (long) (floor((y
) - m_logicalOriginY
)*m_logicalScaleY
*m_userScaleY
*m_systemScaleY
+ m_deviceOriginY
);
1330 long wxDC::LogicalToDeviceYRel(long y
) const
1332 return (long) (floor(y
)*m_logicalScaleY
*m_userScaleY
*m_systemScaleY
) ;
1335 // This group of functions may not do any conversion
1336 // if m_scaleGDI is TRUE, since the HDC does the
1337 // conversion automatically.
1339 long wxDC::ImplDeviceToLogicalX(long x
) const
1341 // return (m_scaleGDI ? x : DeviceToLogicalX(x));
1345 long wxDC::ImplDeviceToLogicalY(long y
) const
1347 // return (m_scaleGDI ? y : DeviceToLogicalY(y));
1351 long wxDC::ImplDeviceToLogicalXRel(long x
) const
1353 // return (m_scaleGDI ? x : DeviceToLogicalXRel(x));
1357 long wxDC::ImplDeviceToLogicalYRel(long y
) const
1359 // return (m_scaleGDI ? y : DeviceToLogicalYRel(y));
1363 long wxDC::ImplLogicalToDeviceX(long x
) const
1365 // return (m_scaleGDI ? (floor(double(x))) : LogicalToDeviceX(x));
1369 long wxDC::ImplLogicalToDeviceY(long y
) const
1371 // return (m_scaleGDI ? (floor(double(y))) : LogicalToDeviceY(y));
1375 long wxDC::ImplLogicalToDeviceXRel(long x
) const
1377 // return (m_scaleGDI ? (floor(double(x))) : LogicalToDeviceXRel(x));
1381 long wxDC::ImplLogicalToDeviceYRel(long y
) const
1383 // return (m_scaleGDI ? (floor(double(y))) : LogicalToDeviceYRel(y));
1387 bool wxDC::Blit(long xdest
, long ydest
, long width
, long height
,
1388 wxDC
*source
, long xsrc
, long ysrc
, int rop
, bool useMask
)
1391 source
->BeginDrawing();
1393 long xdest1
= xdest
;
1394 long ydest1
= ydest
;
1398 DWORD dwRop
= rop
== wxCOPY
? SRCCOPY
:
1399 rop
== wxCLEAR
? WHITENESS
:
1400 rop
== wxSET
? BLACKNESS
:
1401 rop
== wxINVERT
? DSTINVERT
:
1402 rop
== wxAND
? MERGECOPY
:
1403 rop
== wxOR
? MERGEPAINT
:
1404 rop
== wxSRC_INVERT
? NOTSRCCOPY
:
1405 rop
== wxXOR
? SRCINVERT
:
1406 rop
== wxOR_REVERSE
? MERGEPAINT
:
1407 rop
== wxAND_REVERSE
? SRCERASE
:
1408 rop
== wxSRC_OR
? SRCPAINT
:
1409 rop
== wxSRC_AND
? SRCAND
:
1413 if (useMask
&& source
->m_selectedBitmap
.Ok() && source
->m_selectedBitmap
.GetMask())
1417 // Not implemented under Win95 (or maybe a specific device?)
1418 if (MaskBlt((HDC
) m_hDC
, xdest1
, ydest1
, (int)width
, (int)height
,
1419 (HDC
) source
->m_hDC
, xsrc1
, ysrc1
, (HBITMAP
) source
->m_selectedBitmap
.GetMask()->GetMaskBitmap(),
1429 HDC dc_mask
= CreateCompatibleDC((HDC
) source
->m_hDC
);
1430 ::SelectObject(dc_mask
, (HBITMAP
) source
->m_selectedBitmap
.GetMask()->GetMaskBitmap());
1431 success
= (BitBlt((HDC
) m_hDC
, xdest1
, ydest1
, (int)width
, (int)height
,
1432 dc_mask
, xsrc1
, ysrc1
, 0x00220326 /* NOTSRCAND */) != 0);
1433 success
= (BitBlt((HDC
) m_hDC
, xdest1
, ydest1
, (int)width
, (int)height
,
1434 (HDC
) source
->m_hDC
, xsrc1
, ysrc1
, SRCPAINT
) != 0);
1435 ::SelectObject(dc_mask
, 0);
1436 ::DeleteDC(dc_mask
);
1438 // New code from Chris Breeze, 8/5/98
1440 // create a temp buffer bitmap and DCs to access it and the mask
1441 HDC dc_mask
= ::CreateCompatibleDC((HDC
) source
->m_hDC
);
1442 HDC dc_buffer
= ::CreateCompatibleDC((HDC
) m_hDC
);
1443 HBITMAP buffer_bmap
= ::CreateCompatibleBitmap((HDC
) m_hDC
, width
, height
);
1444 ::SelectObject(dc_mask
, (HBITMAP
) source
->m_selectedBitmap
.GetMask()->GetMaskBitmap());
1445 ::SelectObject(dc_buffer
, buffer_bmap
);
1447 // copy dest to buffer
1448 ::BitBlt(dc_buffer
, 0, 0, (int)width
, (int)height
,
1449 (HDC
) m_hDC
, xdest1
, ydest1
, SRCCOPY
);
1451 // copy src to buffer using selected raster op
1452 ::BitBlt(dc_buffer
, 0, 0, (int)width
, (int)height
,
1453 (HDC
) source
->m_hDC
, xsrc1
, ysrc1
, dwRop
);
1455 // set masked area in buffer to BLACK (pixel value 0)
1456 COLORREF prevBkCol
= ::SetBkColor((HDC
) m_hDC
, RGB(255, 255, 255));
1457 COLORREF prevCol
= ::SetTextColor((HDC
) m_hDC
, RGB(0, 0, 0));
1458 ::BitBlt(dc_buffer
, 0, 0, (int)width
, (int)height
,
1459 dc_mask
, xsrc1
, ysrc1
, SRCAND
);
1461 // set unmasked area in dest to BLACK
1462 ::SetBkColor((HDC
) m_hDC
, RGB(0, 0, 0));
1463 ::SetTextColor((HDC
) m_hDC
, RGB(255, 255, 255));
1464 ::BitBlt((HDC
) m_hDC
, xdest1
, ydest1
, (int)width
, (int)height
,
1465 dc_mask
, xsrc1
, ysrc1
, SRCAND
);
1466 ::SetBkColor((HDC
) m_hDC
, prevBkCol
); // restore colours to original values
1467 ::SetTextColor((HDC
) m_hDC
, prevCol
);
1469 // OR buffer to dest
1470 success
= (::BitBlt((HDC
) m_hDC
, xdest1
, ydest1
, (int)width
, (int)height
,
1471 dc_buffer
, 0, 0, SRCPAINT
) != 0);
1473 // tidy up temporary DCs and bitmap
1474 ::SelectObject(dc_mask
, 0);
1475 ::DeleteDC(dc_mask
);
1476 ::SelectObject(dc_buffer
, 0);
1477 ::DeleteDC(dc_buffer
);
1478 ::DeleteObject(buffer_bmap
);
1483 success
= (BitBlt((HDC
) m_hDC
, xdest1
, ydest1
, (int)width
, (int)height
, (HDC
) source
->m_hDC
,
1484 xsrc1
, ysrc1
, dwRop
) != 0);
1486 source
->EndDrawing();
1492 void wxDC::GetSize(int* width
, int* height
) const
1494 long w
=::GetDeviceCaps((HDC
) m_hDC
,HORZRES
);
1495 long h
=::GetDeviceCaps((HDC
) m_hDC
,VERTRES
);
1500 void wxDC::GetSizeMM(long *width
, long *height
) const
1502 long w
=::GetDeviceCaps((HDC
) m_hDC
,HORZSIZE
);
1503 long h
=::GetDeviceCaps((HDC
) m_hDC
,VERTSIZE
);
1509 # if USE_XFIG_SPLINE_CODE
1510 # include "../common/xfspline.inc"
1512 # include "../common/wxspline.inc"
1514 #endif // USE_SPLINES
1516 void wxDC::DrawPolygon(wxList
*list
, long xoffset
, long yoffset
,int fillStyle
)
1518 int n
= list
->Number();
1519 wxPoint
*points
= new wxPoint
[n
];
1522 for(wxNode
*node
= list
->First(); node
; node
= node
->Next()) {
1523 wxPoint
*point
= (wxPoint
*)node
->Data();
1524 points
[i
].x
= point
->x
;
1525 points
[i
++].y
= point
->y
;
1527 DrawPolygon(n
, points
, xoffset
, yoffset
,fillStyle
);
1531 void wxDC::DrawLines(wxList
*list
, long xoffset
, long yoffset
)
1533 int n
= list
->Number();
1534 wxPoint
*points
= new wxPoint
[n
];
1537 for(wxNode
*node
= list
->First(); node
; node
= node
->Next()) {
1538 wxPoint
*point
= (wxPoint
*)node
->Data();
1539 points
[i
].x
= point
->x
;
1540 points
[i
++].y
= point
->y
;
1542 DrawLines(n
, points
, xoffset
, yoffset
);
1546 void wxDC::SetTextForeground(const wxColour
& colour
)
1548 m_textForegroundColour
= colour
;
1551 void wxDC::SetTextBackground(const wxColour
& colour
)
1553 m_textBackgroundColour
= colour
;
1557 // Make a 3-point spline
1558 void wxDC::DrawSpline(long x1
, long y1
, long x2
, long y2
, long x3
, long y3
)
1560 wxList
*point_list
= new wxList
;
1562 wxPoint
*point1
= new wxPoint
;
1563 point1
->x
= x1
; point1
->y
= y1
;
1564 point_list
->Append((wxObject
*)point1
);
1566 wxPoint
*point2
= new wxPoint
;
1567 point2
->x
= x2
; point2
->y
= y2
;
1568 point_list
->Append((wxObject
*)point2
);
1570 wxPoint
*point3
= new wxPoint
;
1571 point3
->x
= x3
; point3
->y
= y3
;
1572 point_list
->Append((wxObject
*)point3
);
1574 DrawSpline(point_list
);
1576 for(wxNode
*node
= point_list
->First(); node
; node
= node
->Next()) {
1577 wxPoint
*p
= (wxPoint
*)node
->Data();
1582 wxSpline spline(point_list);
1584 wx_draw_open_spline(this, &spline);
1585 spline.DeletePoints();
1590 // For use by wxWindows only, unless custom units are required.
1591 void wxDC::SetLogicalScale(double x
, double y
)
1593 m_logicalScaleX
= x
;
1594 m_logicalScaleY
= y
;
1597 void wxDC::CalcBoundingBox(long x
, long y
)
1599 if (x
< m_minX
) m_minX
= x
;
1600 if (y
< m_minY
) m_minY
= y
;
1601 if (x
> m_maxX
) m_maxX
= x
;
1602 if (y
> m_maxY
) m_maxY
= y
;
1605 void wxDC::GetClippingBox(long *x
,long *y
,long *w
,long *h
) const
1611 *w
= (m_clipX2
- m_clipX1
) ;
1612 *h
= (m_clipY2
- m_clipY1
) ;
1615 *x
= *y
= *w
= *h
= 0 ;
1618 #if WXWIN_COMPATIBILITY
1619 void wxDC::GetTextExtent(const wxString
& string
, float *x
, float *y
,
1620 float *descent
, float *externalLeading
,
1621 wxFont
*theFont
, bool use16bit
) const
1623 long x1
, y1
, descent1
, externalLeading1
;
1624 GetTextExtent(string
, & x1
, & y1
, & descent1
, & externalLeading1
, theFont
, use16bit
);
1627 *descent
= descent1
;
1628 if (externalLeading
)
1629 *externalLeading
= externalLeading1
;