#if wxTEST_GRAPHICS
#include "wx/graphics.h"
#if wxUSE_GRAPHICS_CONTEXT == 0
-#error wxUSE_GRAPHICS_CONTEXT must be defined to 1 for testing
+#undef wxTEST_GRAPHICS
+#define wxTEST_GRAPHICS 0
#endif
#else
#undef wxUSE_GRAPHICS_CONTEXT
Show_Brushes,
Show_Polygons,
Show_Mask,
+ Show_Mask_Stretch,
Show_Ops,
Show_Regions,
Show_Circles,
Show_Splines,
#if wxUSE_GRAPHICS_CONTEXT
Show_Alpha,
+ Show_Graphics,
#endif
Show_Gradient,
Show_Max
#endif
protected:
+ enum DrawMode
+ {
+ Draw_Normal,
+ Draw_Stretch
+ };
+
void DrawTestLines( int x, int y, int width, wxDC &dc );
void DrawTestPoly(wxDC& dc);
void DrawTestBrushes(wxDC& dc);
void DrawText(wxDC& dc);
- void DrawImages(wxDC& dc);
+ void DrawImages(wxDC& dc, DrawMode mode);
void DrawWithLogicalOps(wxDC& dc);
#if wxUSE_GRAPHICS_CONTEXT
void DrawAlpha(wxDC& dc);
+ void DrawGraphics(wxGraphicsContext* gc);
#endif
void DrawRegions(wxDC& dc);
void DrawCircles(wxDC& dc);
File_ShowBrushes,
File_ShowPolygons,
File_ShowMask,
+ File_ShowMaskStretch,
File_ShowOps,
File_ShowRegions,
File_ShowCircles,
File_ShowSplines,
#if wxUSE_GRAPHICS_CONTEXT
File_ShowAlpha,
+ File_ShowGraphics,
#endif
File_ShowGradients,
MenuShow_Last = File_ShowGradients,
wxPathList pathList;
pathList.Add(_T("."));
pathList.Add(_T(".."));
+ pathList.Add(_T("../.."));
wxString path = pathList.FindValidPath(_T("pat4.bmp"));
if ( !path )
// `Main program' equivalent: the program execution "starts" here
bool MyApp::OnInit()
{
+ if ( !wxApp::OnInit() )
+ return false;
+
// Create the main application window
MyFrame *frame = new MyFrame(_T("Drawing sample"),
wxPoint(50, 50), wxSize(550, 340));
dc.DrawText( _T("This is Swiss 18pt text."), 110, 40 );
- long length;
- long height;
- long descent;
+ wxCoord length;
+ wxCoord height;
+ wxCoord descent;
dc.GetTextExtent( _T("This is Swiss 18pt text."), &length, &height, &descent );
text.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length, height, descent );
dc.DrawText( text, 110, 80 );
{ wxT("wxXOR"), wxXOR },
};
-void MyCanvas::DrawImages(wxDC& dc)
+void MyCanvas::DrawImages(wxDC& dc, DrawMode mode)
{
dc.DrawText(_T("original image"), 0, 0);
dc.DrawBitmap(*gs_bmpNoMask, 0, 20, 0);
dc.DrawText(rasterOperations[n].name, x, y - 20);
memDC.SelectObject(*gs_bmpWithColMask);
- dc.Blit(x, y, cx, cy, &memDC, 0, 0, rasterOperations[n].rop, true);
+ if ( mode == Draw_Stretch )
+ {
+ dc.StretchBlit(x, y, cx, cy, &memDC, 0, 0, cx/2, cy/2,
+ rasterOperations[n].rop, true);
+ }
+ else
+ {
+ dc.Blit(x, y, cx, cy, &memDC, 0, 0, rasterOperations[n].rop, true);
+ }
}
}
}
#if wxUSE_GRAPHICS_CONTEXT
+#ifdef __WXGTK20__
+void MyCanvas::DrawAlpha(wxDC& no_dc)
+#else
void MyCanvas::DrawAlpha(wxDC& dc)
+#endif
{
+#ifdef __WXGTK__
+ wxGCDC dc( this );
+ PrepareDC( dc );
+#endif
+
wxDouble margin = 20 ;
wxDouble width = 180 ;
wxDouble radius = 30 ;
-
+
dc.SetPen( wxPen( wxColour( 128, 0, 0, 255 ),12, wxSOLID));
dc.SetBrush( wxBrush( wxColour( 255, 0, 0, 255),wxSOLID));
-
+
wxRect r(margin,margin+width*0.66,width,width) ;
-
+
dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
-
+
dc.SetPen( wxPen( wxColour( 0, 0, 128, 255 ),12, wxSOLID));
dc.SetBrush( wxBrush( wxColour( 0, 0, 255, 255),wxSOLID));
-
+
r.Offset( width * 0.8 , - width * 0.66 ) ;
-
+
dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
-
+
dc.SetPen( wxPen( wxColour( 128, 128, 0, 255 ),12, wxSOLID));
dc.SetBrush( wxBrush( wxColour( 192, 192, 0, 255),wxSOLID));
r.Offset( width * 0.8 , width *0.5 ) ;
-
+
dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ;
-
+
dc.SetPen( *wxTRANSPARENT_PEN ) ;
dc.SetBrush( wxBrush( wxColour(255,255,128,128) ) );
dc.DrawRoundedRectangle( 0 , margin + width / 2 , width * 3 , 100 , radius) ;
+
+ dc.SetTextForeground( wxColour(255,255,0,128) );
+ dc.SetFont( wxFont( 40, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL ) );
+ dc.DrawText( wxT("Hello!"), 120, 80 );
}
#endif
+#if wxUSE_GRAPHICS_CONTEXT
+
+const int BASE = 80.0;
+const int BASE2 = BASE/2;
+const int BASE4 = BASE/4;
+
+static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
+
+
+// modeled along Robin Dunn's GraphicsContext.py sample
+
+void MyCanvas::DrawGraphics(wxGraphicsContext* gc)
+{
+ wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ gc->SetFont(font,*wxBLACK);
+
+ // make a path that contains a circle and some lines, centered at 0,0
+ wxGraphicsPath path = gc->CreatePath() ;
+ path.AddCircle( 0, 0, BASE2 );
+ path.MoveToPoint(0, -BASE2);
+ path.AddLineToPoint(0, BASE2);
+ path.MoveToPoint(-BASE2, 0);
+ path.AddLineToPoint(BASE2, 0);
+ path.CloseSubpath();
+ path.AddRectangle(-BASE4, -BASE4/2, BASE2, BASE4);
+
+ // Now use that path to demonstrate various capbilites of the grpahics context
+ gc->PushState(); // save current translation/scale/other state
+ gc->Translate(60, 75); // reposition the context origin
+
+ gc->SetPen(wxPen("navy", 1));
+ gc->SetBrush(wxBrush("pink"));
+
+ for( int i = 0 ; i < 3 ; ++i )
+ {
+ wxString label;
+ switch( i )
+ {
+ case 0 :
+ label = "StrokePath";
+ break;
+ case 1 :
+ label = "FillPath";
+ break;
+ case 2 :
+ label = "DrawPath";
+ break;
+ }
+ wxDouble w, h;
+ gc->GetTextExtent(label, &w, &h, NULL, NULL);
+ gc->DrawText(label, -w/2, -BASE2-h-4);
+ switch( i )
+ {
+ case 0 :
+ gc->StrokePath(path);
+ break;
+ case 1 :
+ gc->FillPath(path);
+ break;
+ case 2 :
+ gc->DrawPath(path);
+ break;
+ }
+ gc->Translate(2*BASE, 0);
+ }
+
+ gc->PopState(); // restore saved state
+ gc->PushState(); // save it again
+ gc->Translate(60, 200); // offset to the lower part of the window
+
+ gc->DrawText("Scale", 0, -BASE2);
+ gc->Translate(0, 20);
+
+ gc->SetBrush(wxBrush(wxColour(178, 34, 34, 128)));// 128 == half transparent
+ for( int i = 0 ; i < 8 ; ++i )
+ {
+ gc->Scale(1.08, 1.08); // increase scale by 8%
+ gc->Translate(5,5);
+ gc->DrawPath(path);
+ }
+
+ gc->PopState(); // restore saved state
+ gc->PushState(); // save it again
+ gc->Translate(400, 200);
+
+ gc->DrawText("Rotate", 0, -BASE2);
+
+ // Move the origin over to the next location
+ gc->Translate(0, 75);
+
+ // draw our path again, rotating it about the central point,
+ // and changing colors as we go
+ for ( int angle = 0 ; angle < 360 ; angle += 30 )
+ {
+ gc->PushState(); // save this new current state so we can
+ // pop back to it at the end of the loop
+ wxImage::RGBValue val = wxImage::HSVtoRGB(wxImage::HSVValue(float(angle)/360, 1, 1));
+ gc->SetBrush(wxBrush(wxColour(val.red, val.green, val.blue, 64)));
+ gc->SetPen(wxPen(wxColour(val.red, val.green, val.blue, 128)));
+
+ // use translate to artfully reposition each drawn path
+ gc->Translate(1.5 * BASE2 * cos(DegToRad(angle)),
+ 1.5 * BASE2 * sin(DegToRad(angle)));
+
+ // use Rotate to rotate the path
+ gc->Rotate(DegToRad(angle));
+
+ // now draw it
+ gc->DrawPath(path);
+ gc->PopState();
+ }
+ gc->PopState();
+}
+#endif
+
void MyCanvas::DrawCircles(wxDC& dc)
{
int x = 100,
dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
-
+
// same as above, just transparent brush
-
+
dc.SetPen( *wxRED_PEN );
dc.SetBrush( *wxTRANSPARENT_BRUSH );
dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
-
+
}
void MyCanvas::DrawSplines(wxDC& dc)
void MyCanvas::DrawGradients(wxDC& dc)
{
+ static const int TEXT_HEIGHT = 15;
+
// LHS: linear
- wxRect r(10, 10, 100, 100);
+ wxRect r(10, 10, 50, 50);
+ dc.DrawText(_T("wxRIGHT"), r.x, r.y);
+ r.Offset(0, TEXT_HEIGHT);
dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxRIGHT);
- r.Offset(0, 110);
+ r.Offset(0, r.height + 10);
+ dc.DrawText(_T("wxLEFT"), r.x, r.y);
+ r.Offset(0, TEXT_HEIGHT);
dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxLEFT);
- r.Offset(0, 110);
+ r.Offset(0, r.height + 10);
+ dc.DrawText(_T("wxDOWN"), r.x, r.y);
+ r.Offset(0, TEXT_HEIGHT);
dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxDOWN);
- r.Offset(0, 110);
+ r.Offset(0, r.height + 10);
+ dc.DrawText(_T("wxUP"), r.x, r.y);
+ r.Offset(0, TEXT_HEIGHT);
dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxUP);
// RHS: concentric
- r = wxRect(200, 10, 100, 100);
+ r = wxRect(200, 10, 50, 50);
+ dc.DrawText(_T("Blue inside"), r.x, r.y);
+ r.Offset(0, TEXT_HEIGHT);
dc.GradientFillConcentric(r, *wxBLUE, *wxWHITE);
- r.Offset(0, 110);
+ r.Offset(0, r.height + 10);
+ dc.DrawText(_T("White inside"), r.x, r.y);
+ r.Offset(0, TEXT_HEIGHT);
dc.GradientFillConcentric(r, *wxWHITE, *wxBLUE);
- r.Offset(0, 110);
+ r.Offset(0, r.height + 10);
+ dc.DrawText(_T("Blue in top left corner"), r.x, r.y);
+ r.Offset(0, TEXT_HEIGHT);
dc.GradientFillConcentric(r, *wxBLUE, *wxWHITE, wxPoint(0, 0));
- r.Offset(0, 110);
- dc.GradientFillConcentric(r, *wxBLUE, *wxWHITE, wxPoint(100, 100));
+ r.Offset(0, r.height + 10);
+ dc.DrawText(_T("Blue in bottom right corner"), r.x, r.y);
+ r.Offset(0, TEXT_HEIGHT);
+ dc.GradientFillConcentric(r, *wxBLUE, *wxWHITE, wxPoint(r.width, r.height));
+
+ // check that the area filled by the gradient is exactly the interior of
+ // the rectangle
+ r.x = 350;
+ r.y = 30;
+ dc.DrawText("The interior should be filled but", r.x, r.y);
+ r.y += 15;
+ dc.DrawText(" the red border should remain visible:", r.x, r.y);
+ r.y += 15;
+
+ r.width =
+ r.height = 50;
+ wxRect r2 = r;
+ r2.x += 60;
+ wxRect r3 = r;
+ r3.y += 60;
+ wxRect r4 = r2;
+ r4.y += 60;
+ dc.SetPen(wxPen(wxColour(255, 0, 0)));
+ dc.DrawRectangle(r);
+ r.Deflate(1);
+ dc.GradientFillLinear(r, wxColour(0,255,0), wxColour(0,0,0), wxNORTH);
+ dc.DrawRectangle(r2);
+ r2.Deflate(1);
+ dc.GradientFillLinear(r2, wxColour(0,0,0), wxColour(0,255,0), wxSOUTH);
+ dc.DrawRectangle(r3);
+ r3.Deflate(1);
+ dc.GradientFillLinear(r3, wxColour(0,255,0), wxColour(0,0,0), wxEAST);
+ dc.DrawRectangle(r4);
+ r4.Deflate(1);
+ dc.GradientFillLinear(r4, wxColour(0,0,0), wxColour(0,255,0), wxWEST);
}
void MyCanvas::DrawRegions(wxDC& dc)
break;
case Show_Mask:
- DrawImages(dc);
+ DrawImages(dc, Draw_Normal);
+ break;
+
+ case Show_Mask_Stretch:
+ DrawImages(dc, Draw_Stretch);
break;
case Show_Ops:
DrawWithLogicalOps(dc);
break;
-
+
#if wxUSE_GRAPHICS_CONTEXT
case Show_Alpha:
DrawAlpha(dc);
break;
+ case Show_Graphics:
+ DrawGraphics(gdc.GetGraphicsContext());
+ break;
#endif
case Show_Gradient:
menuFile->Append(File_ShowBrushes, _T("&Brushes screen\tF4"));
menuFile->Append(File_ShowPolygons, _T("&Polygons screen\tF5"));
menuFile->Append(File_ShowMask, _T("&Mask screen\tF6"));
+ menuFile->Append(File_ShowMaskStretch, _T("1/&2 scaled mask\tShift-F6"));
menuFile->Append(File_ShowOps, _T("&ROP screen\tF7"));
menuFile->Append(File_ShowRegions, _T("Re&gions screen\tF8"));
menuFile->Append(File_ShowCircles, _T("&Circles screen\tF9"));
#endif
menuFile->Append(File_ShowSplines, _T("&Splines screen\tF11"));
menuFile->Append(File_ShowGradients, _T("&Gradients screen\tF12"));
+#if wxUSE_GRAPHICS_CONTEXT
+ menuFile->Append(File_ShowGraphics, _T("&Graphics screen\tF13"));
+#endif
menuFile->AppendSeparator();
menuFile->AppendCheckItem(File_Clip, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing"));
#if wxUSE_GRAPHICS_CONTEXT