Painter20 dasher

git-svn-id: svn://ultimatepp.org/upp/trunk@840 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2009-02-07 13:35:31 +00:00
parent 68c2a1caaa
commit 068030de69
13 changed files with 231 additions and 505 deletions

View file

@ -40,16 +40,16 @@ GUI_APP_MAIN
for(int i = 0; i < 10; i++) {
int a, b;
do {
a = Random(35) + 1;
b = Random(35) + 1;
a = Random(50) + 1;
b = Random(50) + 1;
}
while(a + b < 0 || a + b > 20);
while(a + b < 0 || a + b > 50);
r.DrawText(10, 10 + isz.cy * 2 * i, Format("%d + %d = ", a, b), fnt);
do {
a = Random(35) + 1;
b = Random(35) + 1;
a = Random(50) + 1;
b = Random(50) + 1;
}
while(a - b < 0);
while(a - b < 1);
r.DrawText(2000, 10 + isz.cy * 2 * i, Format("%d - %d = ", a, b), fnt);
}
Perform(r);

View file

@ -0,0 +1,62 @@
#include "ScanLine.h"
void Dasher::Put(const Pointf& p)
{
if(flag)
PutLine(p);
else
PutMove(p);
}
void Dasher::Move(const Pointf& p)
{
PutMove(p);
p0 = p;
}
void Dasher::Line(const Pointf& p)
{
if(pattern.GetCount() == 0) {
PutLine(p);
return;
}
Pointf v = p - p0;
double len = Length(v);
double pos = 0;
while(pos + rem < len) {
pos += rem;
Put(pos / len * v + p0);
flag = !flag;
rem = pattern[patterni];
patterni = (patterni + 1) % pattern.GetCount();
}
rem -= len - pos;
Put(p);
p0 = p;
}
Dasher::Dasher(double width, const Vector<double>& p, double distance)
{
pattern.SetCount(p.GetCount());
double sum = 0;
for(int i = 0; i < p.GetCount(); i++)
sum += (pattern[i] = p[i] * width);
if(sum == 0) {
pattern.Clear();
return;
}
distance -= int(distance / sum) * sum;
patterni = 0;
flag = false;
for(;;) {
rem = pattern[patterni];
patterni = (patterni + 1) % pattern.GetCount();
flag = !flag;
if(rem > distance) {
rem -= distance;
break;
}
distance -= rem;
}
p0 = Pointf(0, 0);
}

View file

@ -185,12 +185,12 @@ Image PaintLion(Size sz)
}
static Vector<ColorPolygon> l = Lion();
Rasterizer r(sz.cx, sz.cy);
static Rasterizer r(sz.cx, sz.cy);
for(int i = 0; i < l.GetCount(); i++) {
Vector<Pointf>& p = l[i].point;
r.Move(p[0].x, p[0].y);
r.Move(p[0]);
for(int j = 1; j < p.GetCount(); j++)
r.Line(p[j].x, p[j].y);
r.Line(p[j]);
Render(ib, r, l[i].color, false);
r.Reset();
}

View file

@ -1,20 +1,20 @@
#include "ScanLine.h"
void Painter::Move(Pointf p)
void BufferPainter::Move(Pointf p)
{
Segment& m = PathAdd<Segment>();
m.kind = MOVE;
m.p = p;
}
void Painter::Line(Pointf p)
void BufferPainter::Line(Pointf p)
{
Segment& m = PathAdd<Segment>();
m.kind = LINE;
m.p = p;
}
void Painter::Quadratic(Pointf p1, Pointf p)
void BufferPainter::Quadratic(Pointf p1, Pointf p)
{
QuadraticSegment& m = PathAdd<QuadraticSegment>();
m.kind = QUADRATIC;
@ -22,7 +22,7 @@ void Painter::Quadratic(Pointf p1, Pointf p)
m.p1 = p1;
}
void Painter::Cubic(Pointf p1, Pointf p2, Pointf p)
void BufferPainter::Cubic(Pointf p1, Pointf p2, Pointf p)
{
CubicSegment& m = PathAdd<CubicSegment>();
m.kind = QUADRATIC;

View file

@ -1,12 +1,10 @@
#include "ScanLine.h"
#ifdef RASTERIZER2
#define LLOG(x) // LOG(x)
void Rasterizer::Init()
{
x1 = y1 = 0;
p0 = Pointf(0, 0);
min_y = INT_MAX;
max_y = INT_MIN;
}
@ -157,9 +155,33 @@ inline void Rasterizer::RenderHLine(int ey, int x1, int y1, int x2, int y2)
void Rasterizer::LineRaw(int x1, int y1, int x2, int y2)
{
// PAINTER_TIMING("LineRaw");
PAINTER_TIMING("LineRaw");
LLOG("Rasterizer::LineRaw " << x1 / 256.0 << ':' << y1 / 256.0
<< " - " << x2 / 256.0 << ':' << y2 / 256.0);
int ex1 = x1 >> 8;
int ex2 = x2 >> 8;
int ey1 = y1 >> 8;
int ey2 = y2 >> 8;
ASSERT(ey1 >= 0 && ey1 <= sz.cy && ey2 >= 0 && ey2 <= sz.cy);
if(ey1 < min_y) {
if(ey1 < 0) return;
min_y = ey1;
}
if(ey1 > max_y) {
if(ey1 > sz.cy) return;
max_y = min(ey1, sz.cy - 1);
}
if(ey2 < min_y) {
if(ey2 < 0) return;
min_y = ey2;
}
if(ey2 > max_y) {
if(ey2 > sz.cy) return;
max_y = min(ey2, sz.cy - 1);
}
enum dx_limit_e { dx_limit = 16384 << 8 };
int dx = x2 - x1;
if(dx >= dx_limit || dx <= -dx_limit) {
@ -170,24 +192,14 @@ void Rasterizer::LineRaw(int x1, int y1, int x2, int y2)
return;
}
int dy = y2 - y1;
int ex1 = x1 >> 8;
int ex2 = x2 >> 8;
int ey1 = y1 >> 8;
int ey2 = y2 >> 8;
int fy1 = y1 & 255;
int fy2 = y2 & 255;
ASSERT(ey1 >= 0 && ey1 <= sz.cy && ey2 >= 0 && ey2 <= sz.cy);
Cell *c;
int x_from, x_to;
int p, rem, mod, lift, delta, first, incr;
if(ey1 < min_y) min_y = ey1;
if(ey1 > max_y) max_y = min(ey1, sz.cy - 1);
if(ey2 < min_y) min_y = ey2;
if(ey2 > max_y) max_y = min(ey2, sz.cy - 1);
if(ey1 == ey2) {
RenderHLine(ey1, x1, fy1, x2, fy2);
return;
@ -310,5 +322,3 @@ void Rasterizer::Render(int y, Target& g, bool evenodd)
}
}
}
#endif

View file

@ -1,47 +0,0 @@
class Rasterizer {
struct Cell : MoveableWithSwap<Cell> {
int16 x;
int16 cover;
int area;
bool operator<(const Cell& b) const { return x < b.x; }
};
Rectf cliprect;
double x1, y1;
Buffer< Vector<Cell> > cell;
int xmax, ymax;
int min_y;
int max_y;
Size sz;
void Init();
Cell *AddCells(int y, int n);
void RenderHLine(int ey, int x1, int y1, int x2, int y2);
void LineClip(double x1, double y1, double x2, double y2);
int CvX(double x);
int CvY(double y);
void CvLine(double x1, double y1, double x2, double y2);
bool BeginRender(int y, const Cell *&c, const Cell *&e);
public:
struct Target {
virtual void Start(int x, int len) = 0;
virtual void Render(int val) = 0;
virtual void Render(int val, int len) = 0;
};
void LineRaw(int x1, int y1, int x2, int y2);
void SetClip(const Rectf& rect);
void Move(double x, double y);
void Line(double x, double y);
int MinY() const { return min_y; }
int MaxY() const { return max_y; }
void Render(int y, Target& g, bool evenodd);
void Reset();
Rasterizer(int cx, int cy);
};

View file

@ -1,281 +0,0 @@
#include "ScanLine.h"
#ifdef RASTERIZER3
void Rasterizer::Init()
{
x1 = y1 = 0;
min_y = INT_MAX;
max_y = INT_MIN;
}
void Rasterizer::Reset()
{
PAINTER_TIMING("Rasterizer::Reset");
Init();
for(int i = 0; i < sz.cy; i++)
cell[i].SetCount(0);
}
void Rasterizer::SetClip(const Rectf& rect)
{
cliprect = rect & Sizef(sz);
}
Rasterizer::Rasterizer(int cx, int cy)
{
sz.cx = cx;
sz.cy = cy;
cell.Alloc(sz.cy);
ymax = (sz.cy << 8) - 1;
xmax = (sz.cx << 8) - 1;
cliprect = Sizef(sz);
Reset();
}
inline dword *Rasterizer::AddCells(int y, int n)
{
Vector<dword>& v = cell[y];
if(v.GetCount() == 0) {
v.Reserve(16);
v.SetCount(n);
return &v[0];
}
y = v.GetCount();
v.SetCount(y + n);
return &v[y];
}
inline void Rasterizer::RenderHLine(int ey, int x1, int y1, int x2, int y2)
{
int ex1 = x1 >> 8;
int ex2 = x2 >> 8;
int fx1 = x1 & 255;
int fx2 = x2 & 255;
dword *c;
if(y1 == y2)
return;
int dy = y2 - y1;
if(ex1 == ex2) {
*AddCells(ey, 1) = Cell(ex1, fx1 + fx2, dy);
return;
}
int dx = x2 - x1;
if(dx < 0) {
int p = fx1 * dy;
dx = -dx;
int delta = p / dx;
int mod = p % dx;
if(mod < 0) {
delta--;
mod += dx;
}
c = AddCells(ey, abs(ex2 - ex1) + 1);
*c++ = Cell(ex1, fx1, delta);
ex1--;
y1 += delta;
if(ex1 != ex2) {
p = (y2 - y1 + delta) * 256;
int lift = p / dx;
int rem = p % dx;
if (rem < 0) {
lift--;
rem += dx;
}
mod -= dx;
while(ex1 != ex2) {
delta = lift;
mod += rem;
if(mod >= 0) {
mod -= dx;
delta++;
}
*c++ = Cell(ex1, 256, delta);
y1 += delta;
ex1--;
}
}
*c++ = Cell(ex2, fx2 + 256, y2 - y1);
}
else {
int p = (256 - fx1) * dy;
int delta = p / dx;
int mod = p % dx;
if(mod < 0) {
delta--;
mod += dx;
}
c = AddCells(ey, abs(ex2 - ex1) + 1);
*c++ = Cell(ex1, fx1 + 256, delta);
ex1++;
y1 += delta;
if(ex1 != ex2) {
p = (y2 - y1 + delta) * 256;
int lift = p / dx;
int rem = p % dx;
if (rem < 0) {
lift--;
rem += dx;
}
mod -= dx;
while(ex1 != ex2) {
delta = lift;
mod += rem;
if(mod >= 0) {
mod -= dx;
delta++;
}
*c++ = Cell(ex1, 256, delta);
y1 += delta;
ex1++;
}
}
*c++ = Cell(ex2, fx2, y2 - y1);
}
}
void Rasterizer::LineRaw(int x1, int y1, int x2, int y2)
{
// PAINTER_TIMING("LineRaw");
enum dx_limit_e { dx_limit = 16384 << 8 };
int dx = x2 - x1;
if(dx >= dx_limit || dx <= -dx_limit) {
int cx = (x1 + x2) >> 1;
int cy = (y1 + y2) >> 1;
LineRaw(x1, y1, cx, cy);
LineRaw(cx, cy, x2, y2);
return;
}
int dy = y2 - y1;
int ex1 = x1 >> 8;
int ex2 = x2 >> 8;
int ey1 = y1 >> 8;
int ey2 = y2 >> 8;
int fy1 = y1 & 255;
int fy2 = y2 & 255;
ASSERT(ey1 >= 0 && ey1 < sz.cy && ey2 >= 0 && ey2 < sz.cy);
int x_from, x_to;
int p, rem, mod, lift, delta, first, incr;
if(ey1 < min_y) min_y = ey1;
if(ey1 > max_y && ey1 < sz.cy) max_y = ey1;
if(ey2 < min_y) min_y = ey2;
if(ey2 > max_y && ey2 < sz.cy) max_y = ey2;
if(ey1 == ey2) {
RenderHLine(ey1, x1, fy1, x2, fy2);
return;
}
incr = 1;
if(dx == 0) {
int ex = x1 >> 8;
int two_fx = (x1 - (ex << 8)) << 1;
first = 256;
if(dy < 0) {
first = 0;
incr = -1;
}
x_from = x1;
delta = first - fy1;
*AddCells(ey1, 1) = Cell(ex1, two_fx, delta);
ey1 += incr;
delta = first + first - 256;
while(ey1 != ey2) {
*AddCells(ey1, 1) = Cell(ex1, two_fx, delta);
ey1 += incr;
}
delta = fy2 - 256 + first;
*AddCells(ey1, 1) = Cell(ex1, two_fx, delta);
return;
}
p = (256 - fy1) * dx;
first = 256;
if(dy < 0) {
p = fy1 * dx;
first = 0;
incr = -1;
dy = -dy;
}
delta = p / dy;
mod = p % dy;
if(mod < 0) {
delta--;
mod += dy;
}
x_from = x1 + delta;
RenderHLine(ey1, x1, fy1, x_from, first);
ey1 += incr;
if(ey1 != ey2) {
p = dx << 8;
lift = p / dy;
rem = p % dy;
if(rem < 0) {
lift--;
rem += dy;
}
mod -= dy;
while(ey1 != ey2) {
delta = lift;
mod += rem;
if(mod >= 0) {
mod -= dy;
delta++;
}
x_to = x_from + delta;
RenderHLine(ey1, x_from, 256 - first, x_to, first);
x_from = x_to;
ey1 += incr;
}
}
RenderHLine(ey1, x_from, 256 - first, x2, fy2);
}
inline unsigned Alpha(int area)
{
int cover = area >> 9;
if(cover < 0) cover = -cover;
/* if(evenodd) {
cover &= 511;
if(cover > 256)
cover = 512 - cover;
}*/
return cover;
}
void Rasterizer::Render(int y, Target& g)
{
PAINTER_TIMING("Render");
const dword *c, *e;
if(y < min_y || y > max_y) return;
Vector<dword>& cl = cell[y];
if(cl.GetCount() == 0) return;
Sort(cl);
c = cl;
e = cl.End();
g.Start(GetX(*c), GetX(*(e - 1)));
int cover = 0;
while(c < e) {
int x = GetX(*c);
int cv = GetC(*c);
DDUMP(cv);
int area = GetW(*c) * cv;
cover += cv;
c++;
while(c < e && GetX(*c) == x) {
int cv = GetC(*c);
area += GetW(*c) * cv;
cover += cv;
c++;
}
if(area) {
g.Render(Alpha((cover << (8 + 1)) - area));
x++;
}
if(c < e && GetX(*c) > x)
g.Render(Alpha(cover << (8 + 1)), GetX(*c) - x);
}
}
#endif

View file

@ -1,14 +1,8 @@
#include "ScanLine.h"
void Rasterizer::Move(double x, double y)
{
x1 = x;
y1 = y;
}
inline int Cv(double x)
{
return fround(x * 256);
return int(x * 256 + 0.5);
}
void Rasterizer::CvLine(double x1, double y1, double x2, double y2)
@ -92,10 +86,14 @@ void Rasterizer::LineClip(double x1, double y1, double x2, double y2)
CvLine(x1, y1, x2, y2);
}
void Rasterizer::Line(double x2, double y2)
void Rasterizer::Move(const Pointf& p)
{
p0 = p;
}
void Rasterizer::Line(const Pointf& p)
{
PAINTER_TIMING("Line");
LineClip(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
LineClip(p0.x, p0.y, p.x, p.y);
p0 = p;
}

View file

@ -3,8 +3,6 @@
#include <CtrlLib/CtrlLib.h>
#define RASTERIZER2
using namespace Upp;
#define PAINTER_TIMING(x) // RTIMING(x)
@ -49,22 +47,6 @@ struct ScanLine {
String ToString() const;
};
#ifdef RASTERIZER2
#include "Rasterizer2.h"
#elif defined(RASTERIZER3)
#include "Rasterizer3.h"
#else
#include "Rasterizer.h"
#endif
void Render(ImageBuffer& ib, Rasterizer& r, const RGBA& color, bool evenodd);
double SquareDist(const Pointf& p1, const Pointf& p2);
Pointf Mid(const Pointf& a, const Pointf& b);
Pointf Ortogonal(const Pointf& p);
@ -79,18 +61,20 @@ Pointf Polar(const Pointf& p, double r, double a);
struct VertexTarget {
virtual void Move(const Pointf& p) = 0;
virtual void Line(const Pointf& p) = 0;
virtual void End() = 0;
virtual void End();
};
struct VertexProcessor : VertexTarget {
struct VertexFilter : VertexTarget {
VertexTarget *target;
void PutMove(const Pointf& p) { target->Move(p); }
void PutLine(const Pointf& p) { target->Line(p); }
void PutEnd() { target->End(); }
virtual void End();
void PutMove(const Pointf& p) { target->Move(p); }
void PutLine(const Pointf& p) { target->Line(p); }
void PutEnd() { target->End(); }
VertexProcessor& operator|(VertexProcessor& b) { target = &b; return b; }
void operator|(VertexTarget& b) { target = &b; }
VertexFilter& operator|(VertexFilter& b) { target = &b; return b; }
void operator|(VertexTarget& b) { target = &b; }
};
enum {
@ -103,7 +87,7 @@ enum {
LINEJOIN_BEVEL,
};
class Stroker : public VertexProcessor {
class Stroker : public VertexFilter {
double w2;
double qmiter;
double fid;
@ -127,19 +111,79 @@ public:
Stroker(double width, double miterlimit, double tolerance, int linecap, int linejoin);
};
class Transformer : VertexProcessor {
struct Dasher : public VertexFilter {
Vector<double> pattern;
int patterni;
double rem;
bool flag;
Pointf p0;
void Put(const Pointf& p);
public:
virtual void Move(double x, double y);
virtual void Line(double x, double y);
virtual void End();
virtual void Move(const Pointf& p);
virtual void Line(const Pointf& p);
Dasher(double width, const Vector<double>& pattern, double distance);
};
void ApproximateQuadratic(VertexTarget& t, const Pointf& p1, const Pointf& p2, const Pointf& p3, double tolerance);
void ApproximateCubic(VertexTarget& t, const Pointf& x0, const Pointf& x1, const Pointf& x2, const Pointf& x, double tolerance);
#define Painter NewPainter
class Rasterizer : public VertexTarget {
public:
virtual void Move(const Pointf& p);
virtual void Line(const Pointf& p);
class Painter {
private:
struct Cell : MoveableWithSwap<Cell> {
int16 x;
int16 cover;
int area;
bool operator<(const Cell& b) const { return x < b.x; }
};
Rectf cliprect;
Pointf p0;
Buffer< Vector<Cell> > cell;
int xmax, ymax;
int min_y;
int max_y;
Size sz;
void Init();
Cell *AddCells(int y, int n);
void RenderHLine(int ey, int x1, int y1, int x2, int y2);
void LineClip(double x1, double y1, double x2, double y2);
int CvX(double x);
int CvY(double y);
void CvLine(double x1, double y1, double x2, double y2);
bool BeginRender(int y, const Cell *&c, const Cell *&e);
public:
struct Target {
virtual void Start(int x, int len) = 0;
virtual void Render(int val) = 0;
virtual void Render(int val, int len) = 0;
};
void LineRaw(int x1, int y1, int x2, int y2);
void SetClip(const Rectf& rect);
int MinY() const { return min_y; }
int MaxY() const { return max_y; }
void Render(int y, Target& g, bool evenodd);
void Reset();
Rasterizer(int cx, int cy);
};
void Render(ImageBuffer& ib, Rasterizer& r, const RGBA& color, bool evenodd);
class BufferPainter {
enum {
MOVE, LINE, QUADRATIC, CUBIC
};

View file

@ -9,14 +9,13 @@ file
ScanLineFiller.cpp,
SolidFiller.cpp,
SolidFillerMask.cpp,
Rasterizer2.h,
Rasterizer2.cpp,
Rasterizer3.h,
Rasterizer3.cpp,
RasterizerClip.cpp,
Math.cpp,
Bezier.cpp,
Stroker.cpp,
Dasher.cpp,
Xform.cpp,
Rasterizer.cpp,
RasterizerClip.cpp,
Path.cpp,
help.txt,
Lion.cpp,

View file

@ -1,5 +1,16 @@
#include "ScanLine.h"
#define LLOG(x) LOG(x)
void VertexTarget::End()
{
}
void VertexFilter::End()
{
PutEnd();
}
Stroker::Stroker(double width, double miterlimit, double tolerance, int linecap, int linejoin)
: linecap(linecap),
linejoin(linejoin)
@ -13,6 +24,7 @@ Stroker::Stroker(double width, double miterlimit, double tolerance, int linecap,
void Stroker::Move(const Pointf& p)
{
LLOG("Stroker::Move " << p);
Finish();
p1 = p;
p0 = p2 = Null;
@ -33,16 +45,19 @@ void Stroker::Round(const Pointf& p, const Pointf& v1, const Pointf& v2, double
void Stroker::Line(const Pointf& p3)
{
if(p3 == p2)
return;
LLOG("Stroker::Line " << p3);
if(IsNull(p1)) {
Move(p3);
return;
}
if(IsNull(p2)) {
Pointf v = p3 - p1;
double l = Length(v);
if(l < 1e-30)
return;
p2 = p3;
v1 = p2 - p1;
o1 = Ortogonal(v1) * w2 / Length(v1);
v1 = v;
o1 = Ortogonal(v1) * w2 / l;
a1 = p1 + o1;
b1 = p1 - o1;
if(IsNull(p0)) {
@ -56,7 +71,10 @@ void Stroker::Line(const Pointf& p3)
}
Pointf v2 = p3 - p2;
Pointf o2 = Ortogonal(v2) * w2 / Length(v2);
double l = Length(v2);
if(l < 1e-30)
return;
Pointf o2 = Ortogonal(v2) * w2 / l;
Pointf a2 = p2 + o2;
Pointf b2 = p2 - o2;
@ -128,7 +146,7 @@ void Stroker::Cap(const Pointf& p, const Pointf& v, const Pointf& o,
void Stroker::Finish()
{
if(IsNull(p1) || IsNull(p2))
if(IsNull(p1) || IsNull(p2) || IsNull(p0))
return;
if(p2 == p0)
Line(p0 + v0);
@ -140,11 +158,11 @@ void Stroker::Finish()
Cap(p0, v0, o0, b0, a0);
Cap(p2, -v1, -o1, a1 + v1, b1 + v1);
}
p1 = p2 = Null;
PutEnd();
p0 = p1 = p2 = Null;
}
void Stroker::End()
{
Finish();
PutEnd();
}

View file

@ -0,0 +1,2 @@
#include "ScanLine.h"

View file

@ -2,16 +2,6 @@
Image PaintLion(Size sz);
struct Raget : VertexTarget {
Rasterizer& r;
virtual void Line(Pointf p) { r.Line(p.x, p.y); DUMP(p); }
virtual void Move(Pointf p) { r.Move(p.x, p.y); }
virtual void End() {}
Raget(Rasterizer& r) : r(r) {}
};
struct App : TopWindow {
double x1, y1, x2, y2, x3, y3;
@ -40,58 +30,6 @@ struct App : TopWindow {
virtual void Paint(Draw& w);
virtual void Paint1(Draw& w) {
ImageBuffer ib(600, 600);
Fill(~ib, White(), ib.GetLength());
/* Apply(ib[20], 100, Black(), a);
a.x = 10;
Apply(ib[30], 100, Blue(), a);
for(int i = 0; i < 20; i++) {
b = Pack(i, line1, __countof(line1));
Apply(ib[50 + 2 * i], 100, Black(), And(a, b));
}
*/
Rasterizer r(600, 600);
// r.SetClip(RectfC(100, 100, 200, 200));
#if 0
r.Move(195.000000, 65.000000);
r.Line(0.000000, 0.000000);
r.Line(183.000000, 501.000000);
r.Line(195.000000, 65.000000);
#endif
#if 0
r.Move(x1, y1);
r.Line(x2, y2);
r.Line(x3, y3);
r.Line(x1, y1);
#endif
#if 1
r.Move(200, 300);
// ApproximateQuadratic(q, Pointf(200, 300), Pointf(400, 50), Pointf(600, 300), 0.3);
r.Line(200, 300);
Render(ib, r, Red(), false);
#endif
r.Move(100, 200);
// ApproximateCubic(q, Pointf(100, 200), Pointf(100, 100), Pointf(250, 100), Pointf(250, 200), 2);
r.Line(150, 400);
r.Line(100, 200);
Render(ib, r, Blue(), false);
LOG("---------");
/*
r.Move(200, 300);
Quadratic(q, Pointf(200, 300), Pointf(400, 50), Pointf(600, 300), 10);
r.Line(200, 300);
Render(ib, r, Blue(), false);
*/
w.DrawRect(GetSize(), White());
w.DrawImage(0, 0, ib);
w.DrawText(0, GetSize().cy - 40, Text());
// w.DrawImage(300, 300, PaintLion(GetSize()));
}
App() {
p1 = p4 = Pointf(100, 100);
@ -100,26 +38,6 @@ struct App : TopWindow {
}
};
struct RasterizerTarget : VertexTarget {
Rasterizer& r;
ImageBuffer& ib;
virtual void Line(const Pointf& p)
{
r.Line(p.x, p.y);
}
virtual void Move(const Pointf& p)
{
r.Move(p.x, p.y);
}
virtual void End()
{
Render(ib, r, Black(), false);
}
RasterizerTarget(ImageBuffer& ib, Rasterizer& r) : ib(ib), r(r) {}
};
#if 1
void App::Paint(Draw& w)
{
@ -127,17 +45,21 @@ void App::Paint(Draw& w)
ImageBuffer ib(sz.cx, sz.cy);
Rasterizer r(sz.cx, sz.cy);
Fill(~ib, White(), ib.GetLength());
RasterizerTarget tgt(ib, r);
Stroker s(20, 4, 0.3, LINECAP_ROUND, LINEJOIN_ROUND);
Stroker s(20, 4, 0.3, LINECAP_BUTT, LINEJOIN_MITER);
Vector<double> dash;
dash << 4 << 2;
Dasher d(20, dash, GetMousePos().y);
s|tgt;
d|s|r;
s.Move(p1);
s.Line(p2);
// s.Line(p3);
// s.Line(p4);
s.End();
d.Move(p1);
d.Line(p2);
d.Line(p3);
d.Line(p4);
d.End();
Render(ib, r, Black(), false);
w.DrawImage(0, 0, ib);
}
@ -176,9 +98,8 @@ void App::Paint(Draw& w)
#endif
GUI_APP_MAIN {
App().Run();
#ifdef _DEBUG
// App().Run();
App().Run();
#else _DEBUG
Size sz(800, 600);
int time;