#include "ScanLine.h" Image PaintLion(Size sz); struct App : TopWindow { double x1, y1, x2, y2, x3, y3; Pointf p1, p2, p3, p4; String Text() { return Format("r.Move(%f, %f);\nr.Line(%f, %f);\nr.Line(%f, %f);\nr.Line(%f, %f);\n", x1, y1, x2, y2, x3, y3, x1, y1); } virtual void LeftDown(Point p, dword keyflags) { (keyflags & K_ALT ? p4 : p1) = p; Refresh(); } virtual void RightDown(Point p, dword) { p2 = p; Refresh(); } virtual void MouseMove(Point p, dword keyflags) { p2 = p; Refresh(); } virtual Image CursorImage(Point p, dword keyflags) { return Image::Cross(); } virtual void Paint(Draw& w); App() { p1 = p4 = Pointf(100, 100); p2 = Pointf(200, 100); p3 = Pointf(150, 200); } }; #if 1 void App::Paint(Draw& w) { Size sz = GetSize(); ImageBuffer ib(sz.cx, sz.cy); Rasterizer r(sz.cx, sz.cy); Fill(~ib, White(), ib.GetLength()); Stroker s(20, 4, 0.3, LINECAP_BUTT, LINEJOIN_MITER); Vector dash; dash << 4 << 2; Dasher d(20, dash, GetMousePos().y); d|s|r; d.Move(p1); d.Line(p2); d.Line(p3); d.Line(p4); d.End(); Render(ib, r, Black(), false); w.DrawImage(0, 0, ib); } #else struct LineTarget : VertexTarget { Draw& w; Pointf p; virtual void Line(const Pointf& p1) { w.DrawLine(p.x, p.y, p1.x, p1.y); p = p1; } virtual void Move(const Pointf& p1) { p = p1; } virtual void End() {} LineTarget(Draw& w) : w(w) {} }; void App::Paint(Draw& w) { w.DrawRect(GetSize(), White()); LineTarget ltg(w); Stroker s(20, 4, 0.3, LINECAP_ROUND, LINEJOIN_ROUND); s|ltg; s.Move(p1); s.Line(p2); // s.Line(p3); // s.Line(p4); s.End(); } #endif void Test(const Xform2D& m) { DDUMP(m.Transform(Pointf(0, 1))); DDUMP(m.Transform(Pointf(1, 1))); DDUMP(m.Transform(Pointf(1, 0))); } GUI_APP_MAIN { DDUMP(Xform2D::Identity().IsRegular()); DDUMP((Xform2D::Identity() * Xform2D::Translation(20, 20)).IsRegular()); DDUMP((Xform2D::Identity() * Xform2D::Translation(20, 20)).GetScale()); DDUMP((Xform2D::Identity() * Xform2D::Scale(20)).IsRegular()); DDUMP((Xform2D::Identity() * Xform2D::Scale(20)).GetScale()); DDUMP((Xform2D::Identity() * Xform2D::Scale(20, 10)).IsRegular()); DDUMP((Xform2D::Identity() * Xform2D::Rotation(0.7)).IsRegular()); DDUMP((Xform2D::Identity() * Xform2D::Rotation(0.7)).GetScale()); DDUMP((Xform2D::Identity() * Xform2D::Rotation(0.7) * Xform2D::Scale(20)).IsRegular()); DDUMP((Xform2D::Identity() * Xform2D::Sheer(0.3)).IsRegular()); Test((Xform2D::Identity() * Xform2D::Sheer(0.3))); DDUMP((Xform2D::Identity() * Xform2D::Rotation(0.7) * Xform2D::Scale(20) * Xform2D::Sheer(0.1)).IsRegular()); DDUMP((Xform2D::Identity() * Xform2D::Rotation(0.7) * Xform2D::Scale(20) * Xform2D::Sheer(0.1)).GetScale()); DDUMP((Xform2D::Identity() * Xform2D::Rotation(0.7) * Xform2D::Scale(20, 1)).IsRegular()); DDUMP((Xform2D::Identity() * Xform2D::Rotation(0.7) * Xform2D::Scale(20, 1)).IsRegular()); Xform2D m = (Xform2D::Identity() * Xform2D::Rotation(0.7) * Xform2D::Scale(20) * Xform2D::Sheer(0.1)); DDUMP(m.Transform(Pointf(100, 100))); DDUMP(Inverse(m).Transform(m.Transform(Pointf(100, 100)))); return; #ifdef _DEBUG App().Run(); #else _DEBUG Size sz(800, 600); int time; int time0 = GetTickCount(); int n = 0; for(;;) { time = GetTickCount(); if(time - time0 > 1000) break; PAINTER_TIMING("All"); PaintLion(sz); n++; } PromptOK("Benchmark: " + AsString(double(time - time0) / n) + " ms, " + AsString(n) + " times"); #endif #if 0 ScanLine a, b, c; static byte line1[] = { 1, 50, 100, 128, 128, 128, 128, 128, 100, 50, 1 }; a = Pack(0, line1, __countof(line1)); DUMP(a); for(int i = 0; i < 16; i++) { b = Pack(i, line1, __countof(line1)); DUMP(b); DUMP(And(a, b)); DUMP(And(b, a)); } int x = 0; b = Pack(3, line1, __countof(line1)); for(int i = 0; i < 10000000; i++) { RTIMING("And"); x += And(a, b).x; } #endif }