/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/common/dcgraph.cpp
ViewVC logotype

Annotation of /trunk/3rdparty/wxWidgets/src/common/dcgraph.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (hide annotations) (download)
Mon Sep 6 11:40:06 2010 UTC (9 years, 9 months ago) by william
File size: 28275 byte(s)
exported r3113 from ./upstream/trunk
1 william 10 /////////////////////////////////////////////////////////////////////////////
2     // Name: src/common/graphcmn.cpp
3     // Purpose: graphics context methods common to all platforms
4     // Author: Stefan Csomor
5     // Modified by:
6     // Created:
7     // RCS-ID: $Id: dcgraph.cpp 53772 2008-05-27 04:57:52Z SC $
8     // Copyright: (c) Stefan Csomor
9     // Licence: wxWindows licence
10     /////////////////////////////////////////////////////////////////////////////
11    
12     // For compilers that support precompilation, includes "wx.h".
13     #include "wx/wxprec.h"
14    
15     #if defined(__BORLANDC__)
16     #pragma hdrstop
17     #endif
18    
19     #if wxUSE_GRAPHICS_CONTEXT
20    
21     #include "wx/graphics.h"
22    
23     #ifndef WX_PRECOMP
24     #include "wx/icon.h"
25     #include "wx/bitmap.h"
26     #include "wx/dcmemory.h"
27     #include "wx/region.h"
28     #endif
29    
30     #ifdef __WXMAC__
31     #include "wx/mac/private.h"
32     #endif
33     //-----------------------------------------------------------------------------
34     // constants
35     //-----------------------------------------------------------------------------
36    
37     static const double RAD2DEG = 180.0 / M_PI;
38    
39     //-----------------------------------------------------------------------------
40     // Local functions
41     //-----------------------------------------------------------------------------
42    
43     static inline double DegToRad(double deg)
44     {
45     return (deg * M_PI) / 180.0;
46     }
47    
48     //-----------------------------------------------------------------------------
49     // wxDC bridge class
50     //-----------------------------------------------------------------------------
51    
52     #ifdef __WXMAC__
53     IMPLEMENT_DYNAMIC_CLASS(wxGCDC, wxDCBase)
54     #else
55     IMPLEMENT_DYNAMIC_CLASS(wxGCDC, wxDC)
56     #endif
57    
58     wxGCDC::wxGCDC()
59     {
60     Init();
61     }
62    
63     void wxGCDC::SetGraphicsContext( wxGraphicsContext* ctx )
64     {
65     delete m_graphicContext;
66     m_graphicContext = ctx;
67     if ( m_graphicContext )
68     {
69     m_matrixOriginal = m_graphicContext->GetTransform();
70     m_ok = true;
71     // apply the stored transformations to the passed in context
72     ComputeScaleAndOrigin();
73     m_graphicContext->SetFont( m_font , m_textForegroundColour );
74     m_graphicContext->SetPen( m_pen );
75     m_graphicContext->SetBrush( m_brush);
76     }
77     }
78    
79     wxGCDC::wxGCDC(const wxWindowDC& dc)
80     {
81     Init();
82     SetGraphicsContext( wxGraphicsContext::Create(dc) );
83     }
84    
85     #ifdef __WXMSW__
86     wxGCDC::wxGCDC(const wxMemoryDC& dc)
87     {
88     Init();
89     SetGraphicsContext( wxGraphicsContext::Create(dc) );
90     }
91     #endif
92    
93     void wxGCDC::Init()
94     {
95     m_ok = false;
96     m_colour = true;
97     m_mm_to_pix_x = mm2pt;
98     m_mm_to_pix_y = mm2pt;
99    
100     m_pen = *wxBLACK_PEN;
101     m_font = *wxNORMAL_FONT;
102     m_brush = *wxWHITE_BRUSH;
103    
104     m_graphicContext = NULL;
105     m_logicalFunctionSupported = true;
106     }
107    
108    
109     wxGCDC::~wxGCDC()
110     {
111     delete m_graphicContext;
112     }
113    
114     void wxGCDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool WXUNUSED(useMask) )
115     {
116     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawBitmap - invalid DC") );
117     wxCHECK_RET( bmp.Ok(), wxT("wxGCDC(cg)::DoDrawBitmap - invalid bitmap") );
118    
119     if ( bmp.GetDepth() == 1 )
120     {
121     m_graphicContext->SetPen(*wxTRANSPARENT_PEN);
122     m_graphicContext->SetBrush( wxBrush( m_textBackgroundColour , wxSOLID ) );
123     m_graphicContext->DrawRectangle( x , y , bmp.GetWidth() , bmp.GetHeight() );
124     m_graphicContext->SetBrush( wxBrush( m_textForegroundColour , wxSOLID ) );
125     m_graphicContext->DrawBitmap( bmp, x , y , bmp.GetWidth() , bmp.GetHeight() );
126     m_graphicContext->SetBrush( m_graphicContext->CreateBrush(m_brush));
127     m_graphicContext->SetPen( m_graphicContext->CreatePen(m_pen));
128     }
129     else
130     m_graphicContext->DrawBitmap( bmp, x , y , bmp.GetWidth() , bmp.GetHeight() );
131     }
132    
133     void wxGCDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y )
134     {
135     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawIcon - invalid DC") );
136     wxCHECK_RET( icon.Ok(), wxT("wxGCDC(cg)::DoDrawIcon - invalid icon") );
137    
138     wxCoord w = icon.GetWidth();
139     wxCoord h = icon.GetHeight();
140    
141     m_graphicContext->DrawIcon( icon , x, y, w, h );
142     }
143    
144     bool wxGCDC::StartDoc( const wxString& WXUNUSED(message) )
145     {
146     return true;
147     }
148    
149     void wxGCDC::EndDoc()
150     {
151     }
152    
153     void wxGCDC::StartPage()
154     {
155     }
156    
157     void wxGCDC::EndPage()
158     {
159     }
160    
161     void wxGCDC::Flush()
162     {
163     #ifdef __WXMAC__
164     CGContextFlush( (CGContextRef) m_graphicContext->GetNativeContext() );
165     #endif
166     }
167    
168     void wxGCDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord w, wxCoord h )
169     {
170     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoSetClippingRegion - invalid DC") );
171    
172     m_graphicContext->Clip( x, y, w, h );
173     if ( m_clipping )
174     {
175     m_clipX1 = wxMax( m_clipX1, x );
176     m_clipY1 = wxMax( m_clipY1, y );
177     m_clipX2 = wxMin( m_clipX2, (x + w) );
178     m_clipY2 = wxMin( m_clipY2, (y + h) );
179     }
180     else
181     {
182     m_clipping = true;
183    
184     m_clipX1 = x;
185     m_clipY1 = y;
186     m_clipX2 = x + w;
187     m_clipY2 = y + h;
188     }
189     }
190    
191     void wxGCDC::DoSetClippingRegionAsRegion( const wxRegion &region )
192     {
193     // region is in device coordinates
194     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoSetClippingRegionAsRegion - invalid DC") );
195    
196     if (region.Empty())
197     {
198     //DestroyClippingRegion();
199     return;
200     }
201    
202     wxRegion logRegion( region );
203     wxCoord x, y, w, h;
204    
205     logRegion.Offset( DeviceToLogicalX(0), DeviceToLogicalY(0) );
206     logRegion.GetBox( x, y, w, h );
207    
208     m_graphicContext->Clip( logRegion );
209     if ( m_clipping )
210     {
211     m_clipX1 = wxMax( m_clipX1, x );
212     m_clipY1 = wxMax( m_clipY1, y );
213     m_clipX2 = wxMin( m_clipX2, (x + w) );
214     m_clipY2 = wxMin( m_clipY2, (y + h) );
215     }
216     else
217     {
218     m_clipping = true;
219    
220     m_clipX1 = x;
221     m_clipY1 = y;
222     m_clipX2 = x + w;
223     m_clipY2 = y + h;
224     }
225     }
226    
227     void wxGCDC::DestroyClippingRegion()
228     {
229     m_graphicContext->ResetClip();
230     // currently the clip eg of a window extends to the area between the scrollbars
231     // so we must explicitely make sure it only covers the area we want it to draw
232     int width, height ;
233     GetSize( &width , &height ) ;
234     m_graphicContext->Clip( DeviceToLogicalX(0) , DeviceToLogicalY(0) , DeviceToLogicalXRel(width), DeviceToLogicalYRel(height) );
235    
236     m_graphicContext->SetPen( m_pen );
237     m_graphicContext->SetBrush( m_brush );
238    
239     m_clipping = false;
240     }
241    
242     void wxGCDC::DoGetSizeMM( int* width, int* height ) const
243     {
244     int w = 0, h = 0;
245    
246     GetSize( &w, &h );
247     if (width)
248     *width = long( double(w) / (m_scaleX * m_mm_to_pix_x) );
249     if (height)
250     *height = long( double(h) / (m_scaleY * m_mm_to_pix_y) );
251     }
252    
253     void wxGCDC::SetTextForeground( const wxColour &col )
254     {
255     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::SetTextForeground - invalid DC") );
256    
257     if ( col != m_textForegroundColour )
258     {
259     m_textForegroundColour = col;
260     m_graphicContext->SetFont( m_font, m_textForegroundColour );
261     }
262     }
263    
264     void wxGCDC::SetTextBackground( const wxColour &col )
265     {
266     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::SetTextBackground - invalid DC") );
267    
268     m_textBackgroundColour = col;
269     }
270    
271     void wxGCDC::SetMapMode( int mode )
272     {
273     switch (mode)
274     {
275     case wxMM_TWIPS:
276     SetLogicalScale( twips2mm * m_mm_to_pix_x, twips2mm * m_mm_to_pix_y );
277     break;
278    
279     case wxMM_POINTS:
280     SetLogicalScale( pt2mm * m_mm_to_pix_x, pt2mm * m_mm_to_pix_y );
281     break;
282    
283     case wxMM_METRIC:
284     SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
285     break;
286    
287     case wxMM_LOMETRIC:
288     SetLogicalScale( m_mm_to_pix_x / 10.0, m_mm_to_pix_y / 10.0 );
289     break;
290    
291     case wxMM_TEXT:
292     default:
293     SetLogicalScale( 1.0, 1.0 );
294     break;
295     }
296    
297     ComputeScaleAndOrigin();
298     }
299    
300     void wxGCDC::SetUserScale( double x, double y )
301     {
302     // allow negative ? -> no
303    
304     m_userScaleX = x;
305     m_userScaleY = y;
306     ComputeScaleAndOrigin();
307     }
308    
309     void wxGCDC::SetLogicalScale( double x, double y )
310     {
311     // allow negative ?
312     m_logicalScaleX = x;
313     m_logicalScaleY = y;
314     ComputeScaleAndOrigin();
315     }
316    
317     void wxGCDC::SetLogicalOrigin( wxCoord x, wxCoord y )
318     {
319     m_logicalOriginX = x * m_signX; // is this still correct ?
320     m_logicalOriginY = y * m_signY;
321     ComputeScaleAndOrigin();
322     }
323    
324     void wxGCDC::SetDeviceOrigin( wxCoord x, wxCoord y )
325     {
326     m_deviceOriginX = x;
327     m_deviceOriginY = y;
328     ComputeScaleAndOrigin();
329     }
330    
331     void wxGCDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
332     {
333     m_signX = (xLeftRight ? 1 : -1);
334     m_signY = (yBottomUp ? -1 : 1);
335     ComputeScaleAndOrigin();
336     }
337    
338     wxSize wxGCDC::GetPPI() const
339     {
340     return wxSize(72, 72);
341     }
342    
343     int wxGCDC::GetDepth() const
344     {
345     return 32;
346     }
347    
348     void wxGCDC::ComputeScaleAndOrigin()
349     {
350     m_scaleX = m_logicalScaleX * m_userScaleX;
351     m_scaleY = m_logicalScaleY * m_userScaleY;
352    
353     if ( m_graphicContext )
354     {
355     m_matrixCurrent = m_graphicContext->CreateMatrix();
356     m_matrixCurrent.Translate( m_deviceOriginX, m_deviceOriginY );
357     m_matrixCurrent.Scale( m_scaleX, m_scaleY );
358     // the logical origin sets the origin to have new coordinates
359     m_matrixCurrent.Translate( -m_logicalOriginX, -m_logicalOriginY );
360    
361     m_graphicContext->SetTransform( m_matrixOriginal );
362     m_graphicContext->ConcatTransform( m_matrixCurrent );
363     }
364     }
365    
366     void wxGCDC::SetPalette( const wxPalette& WXUNUSED(palette) )
367     {
368    
369     }
370    
371     void wxGCDC::SetBackgroundMode( int mode )
372     {
373     m_backgroundMode = mode;
374     }
375    
376     void wxGCDC::SetFont( const wxFont &font )
377     {
378     m_font = font;
379     if ( m_graphicContext )
380     {
381     wxFont f = font;
382     if ( f.Ok() )
383     f.SetPointSize( /*LogicalToDeviceYRel*/(font.GetPointSize()));
384     m_graphicContext->SetFont( f, m_textForegroundColour );
385     }
386     }
387    
388     void wxGCDC::SetPen( const wxPen &pen )
389     {
390     if ( m_pen == pen )
391     return;
392    
393     m_pen = pen;
394     if ( m_graphicContext )
395     {
396     m_graphicContext->SetPen( m_pen );
397     }
398     }
399    
400     void wxGCDC::SetBrush( const wxBrush &brush )
401     {
402     if (m_brush == brush)
403     return;
404    
405     m_brush = brush;
406     if ( m_graphicContext )
407     {
408     m_graphicContext->SetBrush( m_brush );
409     }
410     }
411    
412     void wxGCDC::SetBackground( const wxBrush &brush )
413     {
414     if (m_backgroundBrush == brush)
415     return;
416    
417     m_backgroundBrush = brush;
418     if (!m_backgroundBrush.Ok())
419     return;
420     }
421    
422     void wxGCDC::SetLogicalFunction( int function )
423     {
424     if (m_logicalFunction == function)
425     return;
426    
427     m_logicalFunction = function;
428     if ( m_graphicContext->SetLogicalFunction( function ) )
429     m_logicalFunctionSupported=true;
430     else
431     m_logicalFunctionSupported=false;
432     }
433    
434     bool wxGCDC::DoFloodFill(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
435     const wxColour& WXUNUSED(col), int WXUNUSED(style))
436     {
437     return false;
438     }
439    
440     bool wxGCDC::DoGetPixel( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxColour *WXUNUSED(col) ) const
441     {
442     // wxCHECK_MSG( 0 , false, wxT("wxGCDC(cg)::DoGetPixel - not implemented") );
443     return false;
444     }
445    
446     void wxGCDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 )
447     {
448     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawLine - invalid DC") );
449    
450     if ( !m_logicalFunctionSupported )
451     return;
452    
453     m_graphicContext->StrokeLine(x1,y1,x2,y2);
454    
455     CalcBoundingBox(x1, y1);
456     CalcBoundingBox(x2, y2);
457     }
458    
459     void wxGCDC::DoCrossHair( wxCoord x, wxCoord y )
460     {
461     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoCrossHair - invalid DC") );
462    
463     if ( !m_logicalFunctionSupported )
464     return;
465    
466     int w = 0, h = 0;
467    
468     GetSize( &w, &h );
469    
470     m_graphicContext->StrokeLine(0,y,w,y);
471     m_graphicContext->StrokeLine(x,0,x,h);
472    
473     CalcBoundingBox(0, 0);
474     CalcBoundingBox(0+w, 0+h);
475     }
476    
477     void wxGCDC::DoDrawArc( wxCoord x1, wxCoord y1,
478     wxCoord x2, wxCoord y2,
479     wxCoord xc, wxCoord yc )
480     {
481     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawArc - invalid DC") );
482    
483     if ( !m_logicalFunctionSupported )
484     return;
485    
486     double dx = x1 - xc;
487     double dy = y1 - yc;
488     double radius = sqrt((double)(dx * dx + dy * dy));
489     wxCoord rad = (wxCoord)radius;
490     double sa, ea;
491     if (x1 == x2 && y1 == y2)
492     {
493     sa = 0.0;
494     ea = 360.0;
495     }
496     else if (radius == 0.0)
497     {
498     sa = ea = 0.0;
499     }
500     else
501     {
502     sa = (x1 - xc == 0) ?
503     (y1 - yc < 0) ? 90.0 : -90.0 :
504     -atan2(double(y1 - yc), double(x1 - xc)) * RAD2DEG;
505     ea = (x2 - xc == 0) ?
506     (y2 - yc < 0) ? 90.0 : -90.0 :
507     -atan2(double(y2 - yc), double(x2 - xc)) * RAD2DEG;
508     }
509    
510     bool fill = m_brush.GetStyle() != wxTRANSPARENT;
511    
512     wxGraphicsPath path = m_graphicContext->CreatePath();
513     if ( fill && ((x1!=x2)||(y1!=y2)) )
514     path.MoveToPoint( xc, yc );
515     // since these angles (ea,sa) are measured counter-clockwise, we invert them to
516     // get clockwise angles
517     path.AddArc( xc, yc , rad , DegToRad(-sa) , DegToRad(-ea), false );
518     if ( fill && ((x1!=x2)||(y1!=y2)) )
519     path.AddLineToPoint( xc, yc );
520     m_graphicContext->DrawPath(path);
521     }
522    
523     void wxGCDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h,
524     double sa, double ea )
525     {
526     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawEllipticArc - invalid DC") );
527    
528     if ( !m_logicalFunctionSupported )
529     return;
530    
531     m_graphicContext->PushState();
532     m_graphicContext->Translate(x+w/2.0,y+h/2.0);
533     wxDouble factor = ((wxDouble) w) / h;
534     m_graphicContext->Scale( factor , 1.0);
535    
536     // since these angles (ea,sa) are measured counter-clockwise, we invert them to
537     // get clockwise angles
538     if ( m_brush.GetStyle() != wxTRANSPARENT )
539     {
540     wxGraphicsPath path = m_graphicContext->CreatePath();
541     path.MoveToPoint( 0, 0 );
542     path.AddArc( 0, 0, h/2.0 , DegToRad(-sa) , DegToRad(-ea), sa > ea );
543     path.AddLineToPoint( 0, 0 );
544     m_graphicContext->FillPath( path );
545    
546     path = m_graphicContext->CreatePath();
547     path.AddArc( 0, 0, h/2.0 , DegToRad(-sa) , DegToRad(-ea), sa > ea );
548     m_graphicContext->StrokePath( path );
549     }
550     else
551     {
552     wxGraphicsPath path = m_graphicContext->CreatePath();
553     path.AddArc( 0, 0, h/2.0 , DegToRad(-sa) , DegToRad(-ea), sa > ea );
554     m_graphicContext->DrawPath( path );
555     }
556    
557     m_graphicContext->PopState();
558     }
559    
560     void wxGCDC::DoDrawPoint( wxCoord x, wxCoord y )
561     {
562     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawPoint - invalid DC") );
563    
564     DoDrawLine( x , y , x + 1 , y + 1 );
565     }
566    
567     void wxGCDC::DoDrawLines(int n, wxPoint points[],
568     wxCoord xoffset, wxCoord yoffset)
569     {
570     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawLines - invalid DC") );
571    
572     if ( !m_logicalFunctionSupported )
573     return;
574    
575     wxPoint2DDouble* pointsD = new wxPoint2DDouble[n];
576     for( int i = 0; i < n; ++i)
577     {
578     pointsD[i].m_x = points[i].x + xoffset;
579     pointsD[i].m_y = points[i].y + yoffset;
580     }
581    
582     m_graphicContext->StrokeLines( n , pointsD);
583     delete[] pointsD;
584     }
585    
586     #if wxUSE_SPLINES
587     void wxGCDC::DoDrawSpline(wxList *points)
588     {
589     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawSpline - invalid DC") );
590    
591     if ( !m_logicalFunctionSupported )
592     return;
593    
594     wxGraphicsPath path = m_graphicContext->CreatePath();
595    
596     wxList::compatibility_iterator node = points->GetFirst();
597     if (node == wxList::compatibility_iterator())
598     // empty list
599     return;
600    
601     wxPoint *p = (wxPoint *)node->GetData();
602    
603     wxCoord x1 = p->x;
604     wxCoord y1 = p->y;
605    
606     node = node->GetNext();
607     p = (wxPoint *)node->GetData();
608    
609     wxCoord x2 = p->x;
610     wxCoord y2 = p->y;
611     wxCoord cx1 = ( x1 + x2 ) / 2;
612     wxCoord cy1 = ( y1 + y2 ) / 2;
613    
614     path.MoveToPoint( x1 , y1 );
615     path.AddLineToPoint( cx1 , cy1 );
616     #if !wxUSE_STL
617    
618     while ((node = node->GetNext()) != NULL)
619     #else
620    
621     while ((node = node->GetNext()))
622     #endif // !wxUSE_STL
623    
624     {
625     p = (wxPoint *)node->GetData();
626     x1 = x2;
627     y1 = y2;
628     x2 = p->x;
629     y2 = p->y;
630     wxCoord cx4 = (x1 + x2) / 2;
631     wxCoord cy4 = (y1 + y2) / 2;
632    
633     path.AddQuadCurveToPoint(x1 , y1 ,cx4 , cy4 );
634    
635     cx1 = cx4;
636     cy1 = cy4;
637     }
638    
639     path.AddLineToPoint( x2 , y2 );
640    
641     m_graphicContext->StrokePath( path );
642     }
643     #endif // wxUSE_SPLINES
644    
645     void wxGCDC::DoDrawPolygon( int n, wxPoint points[],
646     wxCoord xoffset, wxCoord yoffset,
647     int fillStyle )
648     {
649     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawPolygon - invalid DC") );
650    
651     if ( n <= 0 || (m_brush.GetStyle() == wxTRANSPARENT && m_pen.GetStyle() == wxTRANSPARENT ) )
652     return;
653     if ( !m_logicalFunctionSupported )
654     return;
655    
656     bool closeIt = false;
657     if (points[n-1] != points[0])
658     closeIt = true;
659    
660     wxPoint2DDouble* pointsD = new wxPoint2DDouble[n+(closeIt?1:0)];
661     for( int i = 0; i < n; ++i)
662     {
663     pointsD[i].m_x = points[i].x + xoffset;
664     pointsD[i].m_y = points[i].y + yoffset;
665     }
666     if ( closeIt )
667     pointsD[n] = pointsD[0];
668    
669     m_graphicContext->DrawLines( n+(closeIt?1:0) , pointsD, fillStyle);
670     delete[] pointsD;
671     }
672    
673     void wxGCDC::DoDrawPolyPolygon(int n,
674     int count[],
675     wxPoint points[],
676     wxCoord xoffset,
677     wxCoord yoffset,
678     int fillStyle)
679     {
680     wxASSERT(n > 1);
681     wxGraphicsPath path = m_graphicContext->CreatePath();
682    
683     int i = 0;
684     for ( int j = 0; j < n; ++j)
685     {
686     wxPoint start = points[i];
687     path.MoveToPoint( start.x+ xoffset, start.y+ yoffset);
688     ++i;
689     int l = count[j];
690     for ( int k = 1; k < l; ++k)
691     {
692     path.AddLineToPoint( points[i].x+ xoffset, points[i].y+ yoffset);
693     ++i;
694     }
695     // close the polygon
696     if ( start != points[i-1])
697     path.AddLineToPoint( start.x+ xoffset, start.y+ yoffset);
698     }
699     m_graphicContext->DrawPath( path , fillStyle);
700     }
701    
702     void wxGCDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
703     {
704     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRectangle - invalid DC") );
705    
706     if ( !m_logicalFunctionSupported )
707     return;
708    
709     // CMB: draw nothing if transformed w or h is 0
710     if (w == 0 || h == 0)
711     return;
712    
713     if ( m_graphicContext->ShouldOffset() )
714     {
715     // if we are offsetting the entire rectangle is moved 0.5, so the
716     // border line gets off by 1
717     w -= 1;
718     h -= 1;
719     }
720     m_graphicContext->DrawRectangle(x,y,w,h);
721     }
722    
723     void wxGCDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y,
724     wxCoord w, wxCoord h,
725     double radius)
726     {
727     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRoundedRectangle - invalid DC") );
728    
729     if ( !m_logicalFunctionSupported )
730     return;
731    
732     if (radius < 0.0)
733     radius = - radius * ((w < h) ? w : h);
734    
735     // CMB: draw nothing if transformed w or h is 0
736     if (w == 0 || h == 0)
737     return;
738    
739     if ( m_graphicContext->ShouldOffset() )
740     {
741     // if we are offsetting the entire rectangle is moved 0.5, so the
742     // border line gets off by 1
743     w -= 1;
744     h -= 1;
745     }
746     m_graphicContext->DrawRoundedRectangle( x,y,w,h,radius);
747     }
748    
749     void wxGCDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
750     {
751     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawEllipse - invalid DC") );
752    
753     if ( !m_logicalFunctionSupported )
754     return;
755    
756     if ( m_graphicContext->ShouldOffset() )
757     {
758     // if we are offsetting the entire rectangle is moved 0.5, so the
759     // border line gets off by 1
760     w -= 1;
761     h -= 1;
762     }
763     m_graphicContext->DrawEllipse(x,y,w,h);
764     }
765    
766     bool wxGCDC::CanDrawBitmap() const
767     {
768     return true;
769     }
770    
771     bool wxGCDC::DoBlit(
772     wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
773     wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool WXUNUSED(useMask),
774     wxCoord xsrcMask, wxCoord ysrcMask )
775     {
776     wxCHECK_MSG( Ok(), false, wxT("wxGCDC(cg)::DoBlit - invalid DC") );
777     wxCHECK_MSG( source->Ok(), false, wxT("wxGCDC(cg)::DoBlit - invalid source DC") );
778    
779     if ( logical_func == wxNO_OP )
780     return true;
781     else if ( !m_graphicContext->SetLogicalFunction( logical_func ) )
782    
783     {
784     wxFAIL_MSG( wxT("Logical function is not supported by the graphics context.") );
785     return false;
786     }
787    
788     if (xsrcMask == -1 && ysrcMask == -1)
789     {
790     xsrcMask = xsrc;
791     ysrcMask = ysrc;
792     }
793    
794     wxRect subrect(source->LogicalToDeviceX(xsrc),
795     source->LogicalToDeviceY(ysrc),
796     source->LogicalToDeviceXRel(width),
797     source->LogicalToDeviceYRel(height));
798    
799     // if needed clip the subrect down to the size of the source DC
800     wxCoord sw, sh;
801     source->GetSize(&sw, &sh);
802     sw = source->LogicalToDeviceXRel(sw);
803     sh = source->LogicalToDeviceYRel(sh);
804     if (subrect.x + subrect.width > sw)
805     subrect.width = sw - subrect.x;
806     if (subrect.y + subrect.height > sh)
807     subrect.height = sh - subrect.y;
808    
809     wxBitmap blit = source->GetAsBitmap( &subrect );
810    
811     if ( blit.Ok() )
812     {
813     m_graphicContext->DrawBitmap( blit, xdest, ydest,
814     wxMin(width, blit.GetWidth()),
815     wxMin(height, blit.GetHeight()));
816     }
817     else
818     {
819     wxFAIL_MSG( wxT("Cannot Blit. Unable to get contents of DC as bitmap.") );
820     return false;
821     }
822    
823     // reset logical function
824     m_graphicContext->SetLogicalFunction( m_logicalFunction );
825    
826     return true;
827     }
828    
829     void wxGCDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
830     double angle)
831     {
832     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRotatedText - invalid DC") );
833    
834     if ( str.length() == 0 )
835     return;
836     if ( !m_logicalFunctionSupported )
837     return;
838    
839     if ( m_backgroundMode == wxTRANSPARENT )
840     m_graphicContext->DrawText( str, x ,y , DegToRad(angle ));
841     else
842     m_graphicContext->DrawText( str, x ,y , DegToRad(angle ), m_graphicContext->CreateBrush( wxBrush(m_textBackgroundColour,wxSOLID) ) );
843     }
844    
845     void wxGCDC::DoDrawText(const wxString& str, wxCoord x, wxCoord y)
846     {
847     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoDrawRotatedText - invalid DC") );
848    
849     if ( str.length() == 0 )
850     return;
851    
852     if ( !m_logicalFunctionSupported )
853     return;
854    
855     if ( m_backgroundMode == wxTRANSPARENT )
856     m_graphicContext->DrawText( str, x ,y);
857     else
858     m_graphicContext->DrawText( str, x ,y , m_graphicContext->CreateBrush( wxBrush(m_textBackgroundColour,wxSOLID) ) );
859     }
860    
861     bool wxGCDC::CanGetTextExtent() const
862     {
863     wxCHECK_MSG( Ok(), false, wxT("wxGCDC(cg)::CanGetTextExtent - invalid DC") );
864    
865     return true;
866     }
867    
868     void wxGCDC::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *height,
869     wxCoord *descent, wxCoord *externalLeading ,
870     wxFont *theFont ) const
871     {
872     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::DoGetTextExtent - invalid DC") );
873    
874     if ( theFont )
875     {
876     m_graphicContext->SetFont( *theFont, m_textForegroundColour );
877     }
878    
879     wxDouble h , d , e , w;
880    
881     m_graphicContext->GetTextExtent( str, &w, &h, &d, &e );
882    
883     if ( height )
884     *height = (wxCoord)(h+0.5);
885     if ( descent )
886     *descent = (wxCoord)(d+0.5);
887     if ( externalLeading )
888     *externalLeading = (wxCoord)(e+0.5);
889     if ( width )
890     *width = (wxCoord)(w+0.5);
891    
892     if ( theFont )
893     {
894     m_graphicContext->SetFont( m_font, m_textForegroundColour );
895     }
896     }
897    
898     bool wxGCDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const
899     {
900     wxCHECK_MSG( Ok(), false, wxT("wxGCDC(cg)::DoGetPartialTextExtents - invalid DC") );
901     widths.Clear();
902     widths.Add(0,text.Length());
903     if ( text.IsEmpty() )
904     return true;
905    
906     wxArrayDouble widthsD;
907    
908     m_graphicContext->GetPartialTextExtents( text, widthsD );
909     for ( size_t i = 0; i < widths.GetCount(); ++i )
910     widths[i] = (wxCoord)(widthsD[i] + 0.5);
911    
912     return true;
913     }
914    
915     wxCoord wxGCDC::GetCharWidth(void) const
916     {
917     wxCoord width;
918     DoGetTextExtent( wxT("g") , &width , NULL , NULL , NULL , NULL );
919    
920     return width;
921     }
922    
923     wxCoord wxGCDC::GetCharHeight(void) const
924     {
925     wxCoord height;
926     DoGetTextExtent( wxT("g") , NULL , &height , NULL , NULL , NULL );
927    
928     return height;
929     }
930    
931     void wxGCDC::Clear(void)
932     {
933     wxCHECK_RET( Ok(), wxT("wxGCDC(cg)::Clear - invalid DC") );
934     // TODO better implementation / incorporate size info into wxGCDC or context
935     m_graphicContext->SetBrush( m_backgroundBrush );
936     wxPen p = *wxTRANSPARENT_PEN;
937     m_graphicContext->SetPen( p );
938     DoDrawRectangle( 0, 0, 32000 , 32000 );
939     m_graphicContext->SetPen( m_pen );
940     m_graphicContext->SetBrush( m_brush );
941     }
942    
943     void wxGCDC::DoGetSize(int *width, int *height) const
944     {
945     *width = 10000;
946     *height = 10000;
947     }
948    
949     void wxGCDC::DoGradientFillLinear(const wxRect& rect,
950     const wxColour& initialColour,
951     const wxColour& destColour,
952     wxDirection nDirection )
953     {
954     wxPoint start;
955     wxPoint end;
956     switch( nDirection)
957     {
958     case wxWEST :
959     start = rect.GetRightBottom();
960     start.x++;
961     end = rect.GetLeftBottom();
962     break;
963     case wxEAST :
964     start = rect.GetLeftBottom();
965     end = rect.GetRightBottom();
966     end.x++;
967     break;
968     case wxNORTH :
969     start = rect.GetLeftBottom();
970     start.y++;
971     end = rect.GetLeftTop();
972     break;
973     case wxSOUTH :
974     start = rect.GetLeftTop();
975     end = rect.GetLeftBottom();
976     end.y++;
977     break;
978     default :
979     break;
980     }
981    
982     if (rect.width == 0 || rect.height == 0)
983     return;
984    
985     m_graphicContext->SetBrush( m_graphicContext->CreateLinearGradientBrush(
986     start.x,start.y,end.x,end.y, initialColour, destColour));
987     m_graphicContext->SetPen(*wxTRANSPARENT_PEN);
988     m_graphicContext->DrawRectangle(rect.x,rect.y,rect.width,rect.height);
989     m_graphicContext->SetPen(m_pen);
990     }
991    
992     void wxGCDC::DoGradientFillConcentric(const wxRect& rect,
993     const wxColour& initialColour,
994     const wxColour& destColour,
995     const wxPoint& circleCenter)
996     {
997     //Radius
998     wxInt32 cx = rect.GetWidth() / 2;
999     wxInt32 cy = rect.GetHeight() / 2;
1000     wxInt32 nRadius;
1001     if (cx < cy)
1002     nRadius = cx;
1003     else
1004     nRadius = cy;
1005    
1006     // make sure the background is filled (todo move into specific platform implementation ?)
1007     m_graphicContext->SetPen(*wxTRANSPARENT_PEN);
1008     m_graphicContext->SetBrush( wxBrush( destColour) );
1009     m_graphicContext->DrawRectangle(rect.x,rect.y,rect.width,rect.height);
1010    
1011     m_graphicContext->SetBrush( m_graphicContext->CreateRadialGradientBrush(
1012     rect.x+circleCenter.x,rect.y+circleCenter.y,
1013     rect.x+circleCenter.x,rect.y+circleCenter.y,
1014     nRadius,initialColour,destColour));
1015    
1016     m_graphicContext->DrawRectangle(rect.x,rect.y,rect.width,rect.height);
1017     m_graphicContext->SetPen(m_pen);
1018     }
1019    
1020     void wxGCDC::DoDrawCheckMark(wxCoord x, wxCoord y,
1021     wxCoord width, wxCoord height)
1022     {
1023     wxDCBase::DoDrawCheckMark(x,y,width,height);
1024     }
1025    
1026     #endif // wxUSE_GRAPHICS_CONTEXT

  ViewVC Help
Powered by ViewVC 1.1.22