text: #include <CtrlLib/CtrlLib.h>
  #include <Painter/Painter.h>
  
  using namespace Upp;
  
  struct Test : Painter {
  	Pointf current;
  
  	virtual void   ClearOp(const RGBA& color) {}
  
  	virtual void   MoveOp(const Pointf& p, bool rel);
  	virtual void   LineOp(const Pointf& p, bool rel);
  	virtual void   QuadraticOp(const Pointf& p1, const Pointf& p, bool rel);
  	virtual void   QuadraticOp(const Pointf& p, bool rel) {}
  	virtual void   CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel) {}
  	virtual void   CubicOp(const Pointf& p2, const Pointf& p, bool rel) {}
  	virtual void   ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel) {}
  	virtual void   SvgArcOp(const Pointf& r, double xangle, bool large, bool sweep,
  	                        const Pointf& p, bool rel) {}
  	virtual void   CloseOp() {}
  	virtual void   DivOp() {}
  
  	virtual void   FillOp(const RGBA& color) {}
  	virtual void   FillOp(const Image& image, const Xform2D& transsrc, dword flags) {}
  	virtual void   FillOp(const Pointf& p1, const RGBA& color1,
  	                      const Pointf& p2, const RGBA& color2,
  	                      int style) {}
  	virtual void   FillOp(const Pointf& f, const RGBA& color1, 
  	                      const Pointf& c, double r, const RGBA& color2,
  	                      int style) {}
  
  	virtual void   StrokeOp(double width, const RGBA& rgba) {}
  	virtual void   StrokeOp(double width, const Image& image, const Xform2D& transsrc,
  	                        dword flags) {}
  	virtual void   StrokeOp(double width, const Pointf& p1, const RGBA& color1,
  	                        const Pointf& p2, const RGBA& color2,
  	                        int style) {}
  	virtual void   StrokeOp(double width, const Pointf& f, const RGBA& color1, 
  	                        const Pointf& c, double r, const RGBA& color2,
  	                        int style) {}
  
  	virtual void   ClipOp() {}
  
  
  	virtual void   ColorStopOp(double pos, const RGBA& color) {}
  	virtual void   ClearStopsOp() {}
  	
  	virtual void   OpacityOp(double o) {}
  	virtual void   LineCapOp(int linecap) {}
  	virtual void   LineJoinOp(int linejoin) {}
  	virtual void   MiterLimitOp(double l) {}
  	virtual void   EvenOddOp(bool evenodd) {}
  	virtual void   DashOp(const Vector<double>& dash, double start) {}
  
  	virtual void   TransformOp(const Xform2D& m) {}
  
  	virtual void   BeginOp() {}
  	virtual void   EndOp() {}
  
  	virtual void   BeginMaskOp() {}
  };
  
  int quad;
  int move;
  int line;
  int aline;
  int amove;
  
  struct TestConsumer : LinearPathConsumer {
  	virtual void Line(const Pointf& p) { LOG("Line " << p); aline++; }
  	virtual void Move(const Pointf& p) { LOG("Move " << p); amove++; }
  };
  
  void Test::MoveOp(const Pointf& p, bool rel)
  {
  	LOG("MoveOp " << p);
  	move++;
  	current = p;
  }
  
  void Test::LineOp(const Pointf& p, bool rel)
  {
  	LOG("LineOp " << p);
  	line++;
  	current = p;
  }
  
  void Test::QuadraticOp(const Pointf& p1, const Pointf& p, bool rel)
  {
  	LOG("QuadraticOp " << p1 << ' ' << p);
  	quad++;
  	ApproximateQuadratic(TestConsumer(), current, p1, p, 0.3);
  	current = p;
  }
  
  GUI_APP_MAIN
  {
  	Test test;
  	test.Character(0, 0, 'Q', Roman(20).Italic());
  	DDUMP(quad);
  	DDUMP(move);
  	DDUMP(line);
  	DDUMP(aline);
  	DDUMP(amove);
  }
  