mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
Painter 2.0 developing
git-svn-id: svn://ultimatepp.org/upp/trunk@850 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
64ac4f9174
commit
288562a8bb
26 changed files with 422 additions and 164 deletions
|
|
@ -5,13 +5,13 @@ NAMESPACE_UPP
|
|||
static void sQuadratic(LinearPathConsumer& t, const Pointf& p1, const Pointf& p2, const Pointf& p3,
|
||||
double qt, int lvl)
|
||||
{
|
||||
if(lvl < 32) {
|
||||
if(lvl < 16) {
|
||||
Pointf d = p3 - p1;
|
||||
double q = d.x * d.x + d.y * d.y;
|
||||
double q = Squared(d);
|
||||
if(q > 1e-30) {
|
||||
Pointf pd = p2 - p1;
|
||||
double u = (pd.x * d.x + pd.y * d.y) / q;
|
||||
if(u <= 0 || u >= 1 || SquareDist(u * d, d) > qt) {
|
||||
if(u <= 0 || u >= 1 || SquaredDistance(u * d, pd) > qt) {
|
||||
Pointf p12 = Mid(p1, p2);
|
||||
Pointf p23 = Mid(p2, p3);
|
||||
Pointf div = Mid(p12, p23);
|
||||
|
|
@ -35,7 +35,7 @@ static void sCubic(LinearPathConsumer& t,
|
|||
const Pointf& p1, const Pointf& p2, const Pointf& p3, const Pointf& p4,
|
||||
double qt, int lvl)
|
||||
{
|
||||
if(lvl < 32) {
|
||||
if(lvl < 16) {
|
||||
Pointf d = p4 - p1;
|
||||
double q = d.x * d.x + d.y * d.y;
|
||||
if(q >= 1e-30) {
|
||||
|
|
@ -44,7 +44,7 @@ static void sCubic(LinearPathConsumer& t,
|
|||
double u1 = (d2.x * d.x + d2.y * d.y) / q;
|
||||
double u2 = (d3.x * d.x + d3.y * d.y) / q;
|
||||
if(u1 <= 0 || u1 >= 1 || u2 <= 0 || u2 >= 1 ||
|
||||
SquareDist(u1 * d, d2) > qt || SquareDist(u2 * d, d3) > qt) {
|
||||
SquaredDistance(u1 * d, d2) > qt || SquaredDistance(u2 * d, d3) > qt) {
|
||||
Pointf p12 = Mid(p1, p2);
|
||||
Pointf p23 = Mid(p2, p3);
|
||||
Pointf p34 = Mid(p3, p4);
|
||||
|
|
@ -69,4 +69,21 @@ void ApproximateCubic(LinearPathConsumer& t,
|
|||
t.Line(p4);
|
||||
}
|
||||
|
||||
void ApproximateArc(LinearPathConsumer& t, const Pointf& c, const Pointf& r,
|
||||
double angle, double sweep, double tolerance)
|
||||
{
|
||||
while(angle + sweep < 0)
|
||||
angle += 2000 * M_PI;
|
||||
double fid = acos(1 - tolerance / max(r.x, r.y));
|
||||
if(abs(sweep / fid) > 1000)
|
||||
fid = sweep / 1000;
|
||||
double a = angle;
|
||||
double e = angle + sweep;
|
||||
while(fid > 0 ? a < e : a > e) {
|
||||
t.Line(Polar(a) * r + c);
|
||||
a += fid;
|
||||
}
|
||||
t.Line(Polar(angle + sweep) * r + c);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
double SquareDist(const Pointf& p1, const Pointf& p2);
|
||||
Pointf Mid(const Pointf& a, const Pointf& b);
|
||||
Pointf Ortogonal(const Pointf& p);
|
||||
double SquareLength(const Pointf& p);
|
||||
Pointf Orthogonal(const Pointf& p);
|
||||
double Squared(const Pointf& p);
|
||||
double Length(const Pointf& p);
|
||||
double Bearing(const Pointf& p);
|
||||
double Distance(const Pointf& p1, const Pointf& p2);
|
||||
double SquareDistance(const Pointf& p1, const Pointf& p2);
|
||||
Pointf PolarPointf(double a);
|
||||
double SquaredDistance(const Pointf& p1, const Pointf& p2);
|
||||
Pointf Polar(double a);
|
||||
Pointf Polar(const Pointf& p, double r, double a);
|
||||
|
||||
struct LinearPathConsumer {
|
||||
|
|
@ -21,6 +20,8 @@ void ApproximateQuadratic(LinearPathConsumer& t,
|
|||
void ApproximateCubic(LinearPathConsumer& t,
|
||||
const Pointf& x0, const Pointf& x1, const Pointf& x2, const Pointf& x,
|
||||
double tolerance);
|
||||
void ApproximateArc(LinearPathConsumer& t, const Pointf& p, const Pointf& r,
|
||||
double angle, double sweep, double tolerance);
|
||||
|
||||
struct LinearPathFilter : LinearPathConsumer {
|
||||
virtual void End();
|
||||
|
|
@ -205,9 +206,10 @@ class LinearInterpolator {
|
|||
Dda2 ddax, dday;
|
||||
|
||||
public:
|
||||
void Begin(int x, int y, int len);
|
||||
void Get(int& x, int& y);
|
||||
void Set(const Xform2D& m) { xform = m; }
|
||||
void Set(const Xform2D& m) { xform = m; }
|
||||
|
||||
void Begin(int x, int y, int len);
|
||||
Point Get();
|
||||
};
|
||||
|
||||
class BufferPainter : public Painter {
|
||||
|
|
@ -220,7 +222,9 @@ protected:
|
|||
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 CloseOp();
|
||||
virtual void DivOp();
|
||||
|
||||
virtual void FillOp(const RGBA& color);
|
||||
virtual void FillOp(const Image& image, const Xform2D& transsrc, dword flags);
|
||||
|
|
@ -259,7 +263,7 @@ protected:
|
|||
|
||||
public:
|
||||
enum {
|
||||
MOVE, LINE, QUADRATIC, CUBIC, ARC
|
||||
MOVE, LINE, QUADRATIC, CUBIC, ARC, DIV
|
||||
};
|
||||
struct LinearData {
|
||||
Pointf p;
|
||||
|
|
@ -271,8 +275,10 @@ public:
|
|||
Pointf p2;
|
||||
};
|
||||
struct ArcData : LinearData {
|
||||
double cx, cy;
|
||||
double angle1, angle2;
|
||||
Pointf r;
|
||||
double angle, sweep;
|
||||
|
||||
Pointf EndPoint() const;
|
||||
};
|
||||
struct Path {
|
||||
Vector<byte> type;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ Image BufferPainter::GetGradient(const RGBA& color1, const RGBA& color2, const P
|
|||
|
||||
void BufferPainter::FillOp(const Pointf& p1, const RGBA& color1, const Pointf& p2, const RGBA& color2, int style)
|
||||
{
|
||||
Fill(GetGradient(color1, color2, p1, p2), p1.x, p1.y, p2.x, p2.y,
|
||||
Fill(GetGradient(color1, color2, p1, p2), p1, p2,
|
||||
FILL_VPAD | FILL_FAST |
|
||||
(style == GRADIENT_PAD ? FILL_HPAD : style == GRADIENT_REPEAT
|
||||
? FILL_HREPEAT : FILL_HREFLECT));
|
||||
|
|
@ -49,7 +49,7 @@ void BufferPainter::FillOp(const Pointf& p1, const RGBA& color1, const Pointf& p
|
|||
|
||||
void BufferPainter::StrokeOp(double width, const Pointf& p1, const RGBA& color1, const Pointf& p2, const RGBA& color2, int style)
|
||||
{
|
||||
Stroke(width, GetGradient(color1, color2, p1, p2), p1.x, p1.y, p2.x, p2.y,
|
||||
Stroke(width, GetGradient(color1, color2, p1, p2), p1, p2,
|
||||
FILL_VPAD | FILL_FAST |
|
||||
(style == GRADIENT_PAD ? FILL_HPAD : style == GRADIENT_REPEAT
|
||||
? FILL_HREPEAT : FILL_HREFLECT));
|
||||
|
|
|
|||
|
|
@ -132,8 +132,8 @@ struct PainterImageSpan : SpanSource {
|
|||
cy = image.GetHeight();
|
||||
maxx = cx - 1;
|
||||
maxy = cy - 1;
|
||||
ax = 6000000 / cx * cx;
|
||||
ay = 6000000 / cy * cy;
|
||||
ax = 6000000 / cx * cx * 2;
|
||||
ay = 6000000 / cy * cy * 2;
|
||||
}
|
||||
|
||||
RGBA Pixel(int x, int y) { return image[y][x]; }
|
||||
|
|
@ -163,45 +163,43 @@ struct PainterImageSpan : SpanSource {
|
|||
interpolator.Begin(x, y, len);
|
||||
fixed = hstyle && vstyle;
|
||||
while(len--) {
|
||||
int x_hr;
|
||||
int y_hr;
|
||||
interpolator.Get(x_hr, y_hr);
|
||||
x_hr -= 128;
|
||||
y_hr -= 128;
|
||||
int x_lr = x_hr >> 8;
|
||||
int y_lr = y_hr >> 8;
|
||||
Point h = interpolator.Get();
|
||||
// h -= 128;
|
||||
Point l = h >> 8;
|
||||
if(hstyle == FILL_HREPEAT)
|
||||
x_lr = (x_lr + ax) % cx;
|
||||
l.x = (l.x + ax) % cx;
|
||||
if(vstyle == FILL_VREPEAT)
|
||||
y_lr = (y_lr + ay) % cy;
|
||||
l.y = (l.y + ay) % cy;
|
||||
if(fast) {
|
||||
if(x_lr > 0 && x_lr < maxx && y_lr > 0 && y_lr < maxy)
|
||||
*span = Pixel(x_lr, y_lr);
|
||||
if(l.x > 0 && l.x < maxx && l.y > 0 && l.y < maxy)
|
||||
*span = Pixel(l.x, l.y);
|
||||
else
|
||||
if(style == 0 && (x_lr < -1 || x_lr > cx || y_lr < -1 || y_lr > cy))
|
||||
if(style == 0 && (l.x < -1 || l.x > cx || l.y < -1 || l.y > cy))
|
||||
*span = RGBAZero();
|
||||
else
|
||||
*span = GetPixel(x_lr, y_lr);
|
||||
*span = GetPixel(l.x, l.y);
|
||||
}
|
||||
else {
|
||||
RGBAV v;
|
||||
v.Set(256 * 256 / 2);
|
||||
x_hr &= 255;
|
||||
y_hr &= 255;
|
||||
if(x_lr > 0 && x_lr < maxx && y_lr > 0 && y_lr < maxy) {
|
||||
v.Put((256 - x_hr) * (256 - y_hr), Pixel(x_lr, y_lr));
|
||||
v.Put(x_hr * (256 - y_hr), Pixel(x_lr + 1, y_lr));
|
||||
v.Put((256 - x_hr) * y_hr, Pixel(x_lr, y_lr + 1));
|
||||
v.Put(x_hr * y_hr, Pixel(x_lr + 1, y_lr + 1));
|
||||
v.Set(0);
|
||||
// v.Set(256 * 256 / 2);
|
||||
h.x &= 255;
|
||||
h.y &= 255;
|
||||
Point u = -h + 256;
|
||||
if(l.x > 0 && l.x < maxx && l.y > 0 && l.y < maxy) {
|
||||
v.Put(u.x * u.y, Pixel(l.x, l.y));
|
||||
v.Put(h.x * u.y, Pixel(l.x + 1, l.y));
|
||||
v.Put(u.x * h.y, Pixel(l.x, l.y + 1));
|
||||
v.Put(h.x * h.y, Pixel(l.x + 1, l.y + 1));
|
||||
}
|
||||
else
|
||||
if(style == 0 && (x_lr < -1 || x_lr > cx || y_lr < -1 || y_lr > cy))
|
||||
if(style == 0 && (l.x < -1 || l.x > cx || l.y < -1 || l.y > cy))
|
||||
v.Set(0);
|
||||
else {
|
||||
v.Put((256 - x_hr) * (256 - y_hr), GetPixel(x_lr, y_lr));
|
||||
v.Put(x_hr * (256 - y_hr), GetPixel(x_lr + 1, y_lr));
|
||||
v.Put((256 - x_hr) * y_hr, GetPixel(x_lr, y_lr + 1));
|
||||
v.Put(x_hr * y_hr, GetPixel(x_lr + 1, y_lr + 1));
|
||||
v.Put(u.x * u.y, GetPixel(l.x, l.y));
|
||||
v.Put(h.x * u.y, GetPixel(l.x + 1, l.y));
|
||||
v.Put(u.x * h.y, GetPixel(l.x, l.y + 1));
|
||||
v.Put(h.x * h.y, GetPixel(l.x + 1, l.y + 1));
|
||||
}
|
||||
span->r = byte(v.r >> 16);
|
||||
span->g = byte(v.g >> 16);
|
||||
|
|
|
|||
|
|
@ -31,16 +31,15 @@ int LinearInterpolator::Dda2::Get()
|
|||
|
||||
void LinearInterpolator::Begin(int x, int y, int len)
|
||||
{
|
||||
Pointf p1 = xform.Transform(Pointf(x, y) + 0.5);
|
||||
Pointf p2 = xform.Transform(Pointf(x + len, y) + 0.5);
|
||||
Pointf p1 = xform.Transform(Pointf(x, y)/* + 0.5*/);
|
||||
Pointf p2 = xform.Transform(Pointf(x + len, y)/* + 0.5*/);
|
||||
ddax.Set(Q8(p1.x), Q8(p2.x), len);
|
||||
dday.Set(Q8(p1.y), Q8(p2.y), len);
|
||||
}
|
||||
|
||||
void LinearInterpolator::Get(int& x, int& y)
|
||||
Point LinearInterpolator::Get()
|
||||
{
|
||||
x = ddax.Get();
|
||||
y = dday.Get();
|
||||
return Point(ddax.Get(), dday.Get());
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -12,19 +12,19 @@ Pointf Mid(const Pointf& a, const Pointf& b)
|
|||
return (a + b) / 2;
|
||||
}
|
||||
|
||||
Pointf Ortogonal(const Pointf& p)
|
||||
Pointf Orthogonal(const Pointf& p)
|
||||
{
|
||||
return Pointf(-p.y, p.x);
|
||||
}
|
||||
|
||||
double SquareLength(const Pointf& p)
|
||||
double Squared(const Pointf& p)
|
||||
{
|
||||
return p.x * p.x + p.y * p.y;
|
||||
}
|
||||
|
||||
double Length(const Pointf& p)
|
||||
{
|
||||
return sqrt(SquareLength(p));
|
||||
return sqrt(Squared(p));
|
||||
}
|
||||
|
||||
double Bearing(const Pointf& p)
|
||||
|
|
@ -37,19 +37,19 @@ double Distance(const Pointf& p1, const Pointf& p2)
|
|||
return Length(p1 - p2);
|
||||
}
|
||||
|
||||
double SquareDistance(const Pointf& p1, const Pointf& p2)
|
||||
double SquaredDistance(const Pointf& p1, const Pointf& p2)
|
||||
{
|
||||
return SquareLength(p1 - p2);
|
||||
return Squared(p1 - p2);
|
||||
}
|
||||
|
||||
Pointf PolarPointf(double a)
|
||||
Pointf Polar(double a)
|
||||
{
|
||||
return Pointf(cos(a), sin(a));
|
||||
}
|
||||
|
||||
Pointf Polar(const Pointf& p, double r, double a)
|
||||
{
|
||||
return p + r * PolarPointf(a);
|
||||
return p + r * Polar(a);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ NAMESPACE_UPP
|
|||
|
||||
Painter& Painter::Move(const Pointf& p)
|
||||
{
|
||||
MoveOp(p, false);
|
||||
Move(p, false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Painter& Painter::Line(const Pointf& p)
|
||||
{
|
||||
LineOp(p, false);
|
||||
Line(p, false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -182,6 +182,77 @@ Painter& Painter::RelCubic(double x2, double y2, double x, double y)
|
|||
return *this;
|
||||
}
|
||||
|
||||
Painter& Painter::Arc(const Pointf& c, double rx, double ry, double angle, double sweep, bool rel)
|
||||
{
|
||||
return Arc(c, Pointf(rx, ry), angle, sweep, rel);
|
||||
}
|
||||
|
||||
Painter& Painter::Arc(const Pointf& c, double r, double angle, double sweep, bool rel)
|
||||
{
|
||||
return Arc(c, Pointf(r, r), angle, sweep, rel);
|
||||
}
|
||||
|
||||
Painter& Painter::Arc(double x, double y, double rx, double ry, double angle, double sweep, bool rel)
|
||||
{
|
||||
return Arc(Pointf(x, y), rx, ry, angle, sweep, rel);
|
||||
}
|
||||
|
||||
Painter& Painter::Arc(double x, double y, double r, double angle, double sweep, bool rel)
|
||||
{
|
||||
return Arc(Pointf(x, y), r, angle, sweep, rel);
|
||||
}
|
||||
|
||||
Painter& Painter::Arc(const Pointf& c, const Pointf& r, double angle, double sweep)
|
||||
{
|
||||
return Arc(c, r, angle, sweep, false);
|
||||
}
|
||||
|
||||
Painter& Painter::Arc(const Pointf& c, double rx, double ry, double angle, double sweep)
|
||||
{
|
||||
return Arc(c, rx, ry, angle, sweep, false);
|
||||
}
|
||||
|
||||
Painter& Painter::Arc(const Pointf& c, double r, double angle, double sweep)
|
||||
{
|
||||
return Arc(c, r, angle, sweep, false);
|
||||
}
|
||||
|
||||
Painter& Painter::Arc(double x, double y, double rx, double ry, double angle, double sweep)
|
||||
{
|
||||
return Arc(x, y, rx, ry, angle, sweep, false);
|
||||
}
|
||||
|
||||
Painter& Painter::Arc(double x, double y, double r, double angle, double sweep)
|
||||
{
|
||||
return Arc(x, y, r, angle, sweep, false);
|
||||
}
|
||||
|
||||
|
||||
Painter& Painter::RelArc(const Pointf& c, const Pointf& r, double angle, double sweep)
|
||||
{
|
||||
return Arc(c, r, angle, sweep, true);
|
||||
}
|
||||
|
||||
Painter& Painter::RelArc(const Pointf& c, double rx, double ry, double angle, double sweep)
|
||||
{
|
||||
return Arc(c, rx, ry, angle, sweep, true);
|
||||
}
|
||||
|
||||
Painter& Painter::RelArc(const Pointf& c, double r, double angle, double sweep)
|
||||
{
|
||||
return Arc(c, r, angle, sweep, true);
|
||||
}
|
||||
|
||||
Painter& Painter::RelArc(double x, double y, double rx, double ry, double angle, double sweep)
|
||||
{
|
||||
return Arc(x, y, rx, ry, angle, sweep, true);
|
||||
}
|
||||
|
||||
Painter& Painter::RelArc(double x, double y, double r, double angle, double sweep)
|
||||
{
|
||||
return Arc(x, y, r, angle, sweep, true);
|
||||
}
|
||||
|
||||
Xform2D GetLineSzXform(const Pointf& p1, const Pointf& p2, const Sizef& sz)
|
||||
{
|
||||
Xform2D m = Xform2D::Scale(Distance(p1, p2) / sz.cx);
|
||||
|
|
@ -293,12 +364,17 @@ Painter& Painter::Dash(const char *dash, double start)
|
|||
|
||||
Painter& Painter::Rectangle(double x, double y, double cx, double cy)
|
||||
{
|
||||
Move(x, y);
|
||||
Line(x + cx, y);
|
||||
Line(x + cx, y + cy);
|
||||
Line(x, y + cy);
|
||||
Close();
|
||||
return *this;
|
||||
return Move(x, y).RelLine(cx, 0).RelLine(0, cy).RelLine(-cx, 0).Close();
|
||||
}
|
||||
|
||||
Painter& Painter::Ellipse(double x, double y, double rx, double ry)
|
||||
{
|
||||
return Move(x + rx, y).Arc(x, y, rx, ry, 0, 2 * M_PI).Close();
|
||||
}
|
||||
|
||||
Painter& Painter::Circle(double x, double y, double r)
|
||||
{
|
||||
return Ellipse(x, y, r, r);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -68,7 +68,9 @@ protected:
|
|||
virtual void QuadraticOp(const Pointf& p, bool rel) = 0;
|
||||
virtual void CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel) = 0;
|
||||
virtual void CubicOp(const Pointf& p2, const Pointf& p, bool rel) = 0;
|
||||
virtual void ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel) = 0;
|
||||
virtual void CloseOp() = 0;
|
||||
virtual void DivOp() = 0;
|
||||
|
||||
virtual void FillOp(const RGBA& color) = 0;
|
||||
virtual void FillOp(const Image& image, const Xform2D& transsrc, dword flags) = 0;
|
||||
|
|
@ -115,48 +117,63 @@ public:
|
|||
void Clear(const RGBA& color);
|
||||
|
||||
Painter& Move(const Pointf& p, bool rel);
|
||||
Painter& Line(const Pointf& p, bool rel);
|
||||
Painter& Quadratic(const Pointf& p1, const Pointf& p, bool rel);
|
||||
Painter& Quadratic(const Pointf& p, bool rel);
|
||||
Painter& Cubic(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel);
|
||||
Painter& Cubic(const Pointf& p2, const Pointf& p, bool rel);
|
||||
|
||||
Painter& Move(const Pointf& p);
|
||||
Painter& Move(double x, double y, bool rel);
|
||||
Painter& Move(double x, double y);
|
||||
Painter& RelMove(const Pointf& p);
|
||||
Painter& RelMove(double x, double y);
|
||||
|
||||
Painter& Line(const Pointf& p, bool rel);
|
||||
Painter& Line(const Pointf& p);
|
||||
Painter& Line(double x, double y, bool rel);
|
||||
Painter& Line(double x, double y);
|
||||
Painter& RelLine(const Pointf& p);
|
||||
Painter& RelLine(double x, double y);
|
||||
|
||||
Painter& Quadratic(const Pointf& p1, const Pointf& p, bool rel);
|
||||
Painter& Quadratic(const Pointf& p1, const Pointf& p);
|
||||
Painter& Quadratic(const Pointf& p);
|
||||
Painter& Cubic(const Pointf& p1, const Pointf& p2, const Pointf& p);
|
||||
Painter& Cubic(const Pointf& p2, const Pointf& p);
|
||||
|
||||
Painter& RelMove(const Pointf& p);
|
||||
Painter& RelLine(const Pointf& p);
|
||||
Painter& RelQuadratic(const Pointf& p1, const Pointf& p);
|
||||
Painter& RelQuadratic(const Pointf& p);
|
||||
Painter& RelCubic(const Pointf& p1, const Pointf& p2, const Pointf& p);
|
||||
Painter& RelCubic(const Pointf& p2, const Pointf& p);
|
||||
|
||||
Painter& Move(double x, double y, bool rel);
|
||||
Painter& Line(double x, double y, bool rel);
|
||||
Painter& Quadratic(double x1, double y1, double x, double y, bool rel);
|
||||
Painter& Quadratic(double x, double y, bool rel);
|
||||
Painter& Cubic(double x1, double y1, double x2, double y2, double x, double y, bool rel);
|
||||
Painter& Cubic(double x2, double y2, double x, double y, bool rel);
|
||||
|
||||
Painter& Move(double x, double y);
|
||||
Painter& Line(double x, double y);
|
||||
Painter& Quadratic(double x1, double y1, double x, double y, bool rel);
|
||||
Painter& Quadratic(const Pointf& p, bool rel);
|
||||
Painter& Quadratic(double x1, double y1, double x, double y);
|
||||
Painter& Quadratic(double x, double y);
|
||||
Painter& Cubic(double x1, double y1, double x2, double y2, double x, double y);
|
||||
Painter& Cubic(double x2, double y2, double x, double y);
|
||||
|
||||
Painter& RelMove(double x, double y);
|
||||
Painter& RelLine(double x, double y);
|
||||
Painter& RelQuadratic(const Pointf& p1, const Pointf& p);
|
||||
Painter& RelQuadratic(double x1, double y1, double x, double y);
|
||||
Painter& RelQuadratic(double x, double y);
|
||||
Painter& RelQuadratic(const Pointf& p);
|
||||
|
||||
Painter& Cubic(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel);
|
||||
Painter& Cubic(const Pointf& p2, const Pointf& p, bool rel);
|
||||
Painter& Cubic(const Pointf& p1, const Pointf& p2, const Pointf& p);
|
||||
Painter& Cubic(const Pointf& p2, const Pointf& p);
|
||||
Painter& Cubic(double x1, double y1, double x2, double y2, double x, double y, bool rel);
|
||||
Painter& Cubic(double x2, double y2, double x, double y, bool rel);
|
||||
Painter& Cubic(double x1, double y1, double x2, double y2, double x, double y);
|
||||
Painter& Cubic(double x2, double y2, double x, double y);
|
||||
Painter& RelCubic(const Pointf& p1, const Pointf& p2, const Pointf& p);
|
||||
Painter& RelCubic(const Pointf& p2, const Pointf& p);
|
||||
Painter& RelCubic(double x1, double y1, double x2, double y2, double x, double y);
|
||||
Painter& RelCubic(double x2, double y2, double x, double y);
|
||||
|
||||
Painter& Arc(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel);
|
||||
Painter& Arc(const Pointf& c, double rx, double ry, double angle, double sweep, bool rel);
|
||||
Painter& Arc(const Pointf& c, double r, double angle, double sweep, bool rel);
|
||||
Painter& Arc(double x, double y, double rx, double ry, double angle, double sweep, bool rel);
|
||||
Painter& Arc(double x, double y, double r, double angle, double sweep, bool rel);
|
||||
Painter& Arc(const Pointf& c, const Pointf& r, double angle, double sweep);
|
||||
Painter& Arc(const Pointf& c, double rx, double ry, double angle, double sweep);
|
||||
Painter& Arc(const Pointf& c, double r, double angle, double sweep);
|
||||
Painter& Arc(double x, double y, double rx, double ry, double angle, double sweep);
|
||||
Painter& Arc(double x, double y, double r, double angle, double sweep);
|
||||
Painter& RelArc(const Pointf& c, const Pointf& r, double angle, double sweep);
|
||||
Painter& RelArc(const Pointf& c, double rx, double ry, double angle, double sweep);
|
||||
Painter& RelArc(const Pointf& c, double r, double angle, double sweep);
|
||||
Painter& RelArc(double x, double y, double rx, double ry, double angle, double sweep);
|
||||
Painter& RelArc(double x, double y, double r, double angle, double sweep);
|
||||
|
||||
Painter& Close();
|
||||
Painter& Div();
|
||||
|
||||
Painter& Path(CParser& p);
|
||||
Painter& Path(const char *path);
|
||||
|
|
@ -213,7 +230,7 @@ public:
|
|||
Painter& LineCap(int linecap);
|
||||
Painter& LineJoin(int linejoin);
|
||||
Painter& MiterLimit(double l);
|
||||
Painter& EvenOdd(bool evenodd);
|
||||
Painter& EvenOdd(bool evenodd = true);
|
||||
Painter& Dash(const Vector<double>& dash, double start);
|
||||
Painter& Dash(const char *dash, double start = 0);
|
||||
Painter& NoAA(bool noaa);
|
||||
|
|
@ -225,6 +242,8 @@ public:
|
|||
Painter& Scale(double scale);
|
||||
|
||||
Painter& Rectangle(double x, double y, double cx, double cy);
|
||||
Painter& Ellipse(double x, double y, double rx, double ry);
|
||||
Painter& Circle(double x, double y, double r);
|
||||
};
|
||||
|
||||
#include "Painter.hpp"
|
||||
|
|
|
|||
|
|
@ -46,6 +46,13 @@ Painter& Painter::Cubic(const Pointf& p2, const Pointf& p, bool rel)
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
Painter& Painter::Arc(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel)
|
||||
{
|
||||
ArcOp(c, r, angle, sweep, rel);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
Painter& Painter::Close()
|
||||
{
|
||||
|
|
@ -53,6 +60,13 @@ Painter& Painter::Close()
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
Painter& Painter::Div()
|
||||
{
|
||||
DivOp();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
Painter& Painter::Fill(const RGBA& color)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ file
|
|||
Painter.hpp,
|
||||
Painter.cpp,
|
||||
PainterPath.cpp,
|
||||
FontWin32.cpp,
|
||||
FontX11.cpp,
|
||||
FontWin32.cpp optimize_speed,
|
||||
FontX11.cpp optimize_speed,
|
||||
Text.cpp,
|
||||
BufferPainter.h,
|
||||
Math.cpp,
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ void BufferPainter::ClearPath()
|
|||
Pointf BufferPainter::PathPoint(const Pointf& p, bool rel)
|
||||
{
|
||||
Pointf r;
|
||||
r.x = IsNull(p.x) ? current.x : rel ? p.x + current.x : r.x;
|
||||
r.y = IsNull(p.y) ? current.y : rel ? p.y + current.y : r.y;
|
||||
r.x = IsNull(p.x) ? current.x : rel ? p.x + current.x : p.x;
|
||||
r.y = IsNull(p.y) ? current.y : rel ? p.y + current.y : p.y;
|
||||
if(IsNull(current)) {
|
||||
ClearPath();
|
||||
pathrect.left = pathrect.right = r.x;
|
||||
|
|
@ -27,7 +27,7 @@ Pointf BufferPainter::PathPoint(const Pointf& p, bool rel)
|
|||
pathrect.right = max(pathrect.right, r.x);
|
||||
pathrect.bottom = max(pathrect.bottom, r.y);
|
||||
}
|
||||
return p;
|
||||
return r;
|
||||
}
|
||||
|
||||
Pointf BufferPainter::EndPoint(const Pointf& p, bool rel)
|
||||
|
|
@ -87,6 +87,24 @@ void BufferPainter::CubicOp(const Pointf& p2, const Pointf& p, bool rel)
|
|||
CubicOp(2 * current - ccontrol, p2, p, rel);
|
||||
}
|
||||
|
||||
Pointf BufferPainter::ArcData::EndPoint() const
|
||||
{
|
||||
return r * Polar(angle + sweep) + p;
|
||||
}
|
||||
|
||||
void BufferPainter::ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel)
|
||||
{
|
||||
DoMove0();
|
||||
ArcData& m = PathAdd<ArcData>(ARC);
|
||||
m.p = PathPoint(c, rel);
|
||||
m.r = r;
|
||||
m.angle = angle;
|
||||
m.sweep = sweep;
|
||||
PathPoint(c + r, rel);
|
||||
PathPoint(c - r, rel);
|
||||
current = m.EndPoint();
|
||||
}
|
||||
|
||||
void BufferPainter::CloseOp()
|
||||
{
|
||||
if(!IsNull(move) && current != move) {
|
||||
|
|
@ -95,4 +113,10 @@ void BufferPainter::CloseOp()
|
|||
}
|
||||
}
|
||||
|
||||
void BufferPainter::DivOp()
|
||||
{
|
||||
CloseOp();
|
||||
path.type.Add(DIV);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -162,12 +162,12 @@ struct PainterRadialSpan : SpanSource {
|
|||
interpolator.Begin(x, y, len);
|
||||
RGBA *span = (RGBA *)_span;
|
||||
while(len--) {
|
||||
interpolator.Get(x, y);
|
||||
Point p = interpolator.Get();
|
||||
int h;
|
||||
if(focus) {
|
||||
const double q256 = 1 / 256.0;
|
||||
double dx = q256 * x - cx - fx;
|
||||
double dy = q256 * y - cy - fy;
|
||||
double dx = q256 * p.x - cx - fx;
|
||||
double dy = q256 * p.y - cy - fy;
|
||||
if(dx == 0 && dy == 0)
|
||||
h = 0;
|
||||
else {
|
||||
|
|
@ -178,9 +178,8 @@ struct PainterRadialSpan : SpanSource {
|
|||
}
|
||||
}
|
||||
else {
|
||||
x >>= 2;
|
||||
y >>= 2;
|
||||
int dc = Upp::fastint_sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy));
|
||||
p >>= 2;
|
||||
int dc = Upp::fastint_sqrt((p.x - cx) * (p.x - cx) + (p.y - cy) * (p.y - cy));
|
||||
h = 2047 * dc / r;
|
||||
}
|
||||
if(style == GRADIENT_REPEAT)
|
||||
|
|
|
|||
|
|
@ -39,52 +39,62 @@ void BufferPainter::RenderPath(double width, SpanSource *ss, const RGBA& color)
|
|||
if(!ss)
|
||||
c = Mul8(color, opacity);
|
||||
Pointf pos = Pointf(0, 0);
|
||||
{
|
||||
PAINTER_TIMING("Pipeline");
|
||||
for(int i = 0; i < path.type.GetCount(); i++) {
|
||||
switch(path.type[i]) {
|
||||
case MOVE: {
|
||||
const LinearData *d = (LinearData *)data;
|
||||
data += sizeof(LinearData);
|
||||
g->Move(pos = d->p);
|
||||
int i = 0;
|
||||
for(;;) {
|
||||
if(i >= path.type.GetCount() || path.type[i] == DIV) {
|
||||
g->End();
|
||||
if(ss) {
|
||||
if(!span)
|
||||
span.Alloc(ib.GetWidth() + 1);
|
||||
Render(ib, rasterizer, ss, span, opacity, evenodd);
|
||||
}
|
||||
else
|
||||
Render(ib, rasterizer, c, evenodd);
|
||||
rasterizer.Reset();
|
||||
if(i >= path.type.GetCount())
|
||||
break;
|
||||
}
|
||||
case LINE: {
|
||||
const LinearData *d = (LinearData *)data;
|
||||
data += sizeof(LinearData);
|
||||
g->Line(pos = d->p);
|
||||
break;
|
||||
}
|
||||
case QUADRATIC: {
|
||||
const QuadraticData *d = (QuadraticData *)data;
|
||||
data += sizeof(QuadraticData);
|
||||
ApproximateQuadratic(*g, pos, d->p1, d->p, pathattr.tolerance);
|
||||
pos = d->p;
|
||||
break;
|
||||
}
|
||||
case CUBIC: {
|
||||
const CubicData *d = (CubicData *)data;
|
||||
data += sizeof(CubicData);
|
||||
ApproximateCubic(*g, pos, d->p1, d->p2, d->p, pathattr.tolerance);
|
||||
pos = d->p;
|
||||
break;
|
||||
}
|
||||
case ARC:
|
||||
default:
|
||||
NEVER();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
switch(path.type[i]) {
|
||||
case MOVE: {
|
||||
const LinearData *d = (LinearData *)data;
|
||||
data += sizeof(LinearData);
|
||||
g->Move(pos = d->p);
|
||||
break;
|
||||
}
|
||||
case LINE: {
|
||||
const LinearData *d = (LinearData *)data;
|
||||
data += sizeof(LinearData);
|
||||
g->Line(pos = d->p);
|
||||
break;
|
||||
}
|
||||
case QUADRATIC: {
|
||||
const QuadraticData *d = (QuadraticData *)data;
|
||||
data += sizeof(QuadraticData);
|
||||
ApproximateQuadratic(*g, pos, d->p1, d->p, pathattr.tolerance);
|
||||
pos = d->p;
|
||||
break;
|
||||
}
|
||||
case CUBIC: {
|
||||
const CubicData *d = (CubicData *)data;
|
||||
data += sizeof(CubicData);
|
||||
ApproximateCubic(*g, pos, d->p1, d->p2, d->p, pathattr.tolerance);
|
||||
pos = d->p;
|
||||
break;
|
||||
}
|
||||
case ARC: {
|
||||
const ArcData *d = (ArcData *)data;
|
||||
data += sizeof(ArcData);
|
||||
ApproximateArc(*g, d->p, d->r, d->angle, d->sweep, pathattr.tolerance);
|
||||
pos = d->EndPoint();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NEVER();
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
g->End();
|
||||
if(ss) {
|
||||
if(!span)
|
||||
span.Alloc(ib.GetWidth() + 1);
|
||||
Render(ib, rasterizer, ss, span, opacity, evenodd);
|
||||
}
|
||||
else
|
||||
Render(ib, rasterizer, c, evenodd);
|
||||
rasterizer.Reset();
|
||||
current = Null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ void SpanFiller::Render(int val, int len)
|
|||
{
|
||||
if(val == 0) {
|
||||
t += len;
|
||||
s += len;
|
||||
return;
|
||||
}
|
||||
const RGBA *e = t + len;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ void Stroker::Line(const Pointf& p3)
|
|||
return;
|
||||
p2 = p3;
|
||||
v1 = v;
|
||||
o1 = Ortogonal(v1) * w2 / l;
|
||||
o1 = Orthogonal(v1) * w2 / l;
|
||||
a1 = p1 + o1;
|
||||
b1 = p1 - o1;
|
||||
if(IsNull(p0)) {
|
||||
|
|
@ -66,7 +66,7 @@ void Stroker::Line(const Pointf& p3)
|
|||
double l = Length(v2);
|
||||
if(l < 1e-30)
|
||||
return;
|
||||
Pointf o2 = Ortogonal(v2) * w2 / l;
|
||||
Pointf o2 = Orthogonal(v2) * w2 / l;
|
||||
Pointf a2 = p2 + o2;
|
||||
Pointf b2 = p2 - o2;
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ void Stroker::Line(const Pointf& p3)
|
|||
if(d > 1e-30) {
|
||||
Pointf ts = a1 + v1 * (v2.y * (a1.x - a2.x) - v2.x * (a1.y - a2.y)) / d;
|
||||
PutMove(a1);
|
||||
if(linejoin != LINEJOIN_MITER || SquareDistance(ts, p2) > qmiter) {
|
||||
if(linejoin != LINEJOIN_MITER || SquaredDistance(ts, p2) > qmiter) {
|
||||
PutLine(a1 + v1);
|
||||
if(linejoin == LINEJOIN_ROUND)
|
||||
Round(p2, o1, o2, w2);
|
||||
|
|
@ -91,7 +91,7 @@ void Stroker::Line(const Pointf& p3)
|
|||
if(d < -1e-30) {
|
||||
Pointf ts = b2 + v2 * (v1.y * (a2.x - a1.x) - v1.x * (a2.y - a1.y)) / d;
|
||||
PutMove(b2);
|
||||
if(linejoin != LINEJOIN_MITER || SquareDistance(ts, p2) > qmiter) {
|
||||
if(linejoin != LINEJOIN_MITER || SquaredDistance(ts, p2) > qmiter) {
|
||||
if(linejoin == LINEJOIN_ROUND)
|
||||
Round(p2, -o2, -o1, w2);
|
||||
PutLine(b1 + v1);
|
||||
|
|
@ -127,7 +127,7 @@ void Stroker::Cap(const Pointf& p, const Pointf& v, const Pointf& o,
|
|||
{
|
||||
PutMove(a);
|
||||
if(linecap == LINECAP_SQUARE) {
|
||||
Pointf nv = Ortogonal(o);
|
||||
Pointf nv = Orthogonal(o);
|
||||
PutLine(a + nv);
|
||||
PutLine(b + nv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ void Painter::TextOp(double x, double y, const wchar *text, Font fnt, int n, dou
|
|||
while(n) {
|
||||
int ch = *text++;
|
||||
Character(x, y, ch, fnt);
|
||||
Div();
|
||||
if(dx)
|
||||
x += *dx++;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ Xform2D Xform2D::Rotation(double fi)
|
|||
double sinf = sin(fi);
|
||||
Xform2D m;
|
||||
m.x.x = cosf;
|
||||
m.x.y = sinf;
|
||||
m.y.x = -sinf;
|
||||
m.x.y = -sinf;
|
||||
m.y.x = sinf;
|
||||
m.y.y = cosf;
|
||||
m.t.x = m.t.y = 0;
|
||||
return m;
|
||||
|
|
|
|||
11
uppdev/PainterExamples/Arc.cpp
Normal file
11
uppdev/PainterExamples/Arc.cpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include "Examples.h"
|
||||
|
||||
void Arc(Painter& sw)
|
||||
{
|
||||
sw.Move(400, 200).Arc(400, 200, 200, 100, 0.0, M_PI).Stroke(4, Blue());
|
||||
sw.Move(400, 400).Arc(400, 400, 100, 100, 0.0, M_PI / 3).Fill(LtCyan()).Stroke(2, Black());
|
||||
}
|
||||
|
||||
INITBLOCK {
|
||||
RegisterExample("Arc example", Arc);
|
||||
}
|
||||
47
uppdev/PainterExamples/Big.cpp
Normal file
47
uppdev/PainterExamples/Big.cpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#include "Examples.h"
|
||||
|
||||
void Big(Painter& sw)
|
||||
{
|
||||
int n = 0;
|
||||
double sgn = 1;
|
||||
for(int r = 400; r > 5; r -= 3) {
|
||||
for(int i = 0; i < 400; i++) {
|
||||
Pointf p = Polar(sgn * i * M_2PI / 400) * r + Pointf(400, 400);
|
||||
if(i)
|
||||
sw.Line(p);
|
||||
else
|
||||
sw.Move(p);
|
||||
sw.Line(Polar(sgn * (i * M_2PI / 400 + M_2PI / 800)) * (r - 6) + Pointf(400, 400));
|
||||
n += 2;
|
||||
}
|
||||
sw.Close();
|
||||
sgn = -sgn;
|
||||
}
|
||||
sw.Fill(Black());
|
||||
sw.Text(0, 0, "Elements: " + AsString(n), Arial(20)).Fill(Blue());
|
||||
}
|
||||
|
||||
void BigStroke(Painter& sw)
|
||||
{
|
||||
int n = 0;
|
||||
double r = 400;
|
||||
int i = 0;
|
||||
while(r > 5) {
|
||||
Pointf p = Polar(i * M_2PI / 400) * r + Pointf(400, 400);
|
||||
if(i)
|
||||
sw.Line(p);
|
||||
else
|
||||
sw.Move(p);
|
||||
sw.Line(Polar((i * M_2PI / 400 + M_2PI / 800)) * (r - 3) + Pointf(400, 400));
|
||||
n += 2;
|
||||
r = r - 0.01;
|
||||
i++;
|
||||
}
|
||||
sw.Stroke(1, Black());
|
||||
sw.Text(0, 0, "Elements: " + AsString(n), Arial(20)).Fill(Blue());
|
||||
}
|
||||
|
||||
INITBLOCK {
|
||||
RegisterExample("Really Big Polygon", Big);
|
||||
RegisterExample("Really Big Stroke", BigStroke);
|
||||
}
|
||||
17
uppdev/PainterExamples/Div.cpp
Normal file
17
uppdev/PainterExamples/Div.cpp
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#include "Examples.h"
|
||||
|
||||
void Div(Painter& sw)
|
||||
{
|
||||
sw.Character(100, 100, 'O', Arial(100))
|
||||
.Character(100, 150, 'O', Arial(100))
|
||||
.Fill(Black());
|
||||
sw.Translate(200, 0);
|
||||
sw.Character(100, 100, 'O', Arial(100))
|
||||
.Div()
|
||||
.Character(100, 150, 'O', Arial(100))
|
||||
.Fill(Black());
|
||||
}
|
||||
|
||||
INITBLOCK {
|
||||
RegisterExample("Div", Div);
|
||||
}
|
||||
|
|
@ -43,6 +43,13 @@ void ImagePad(Painter& sw)
|
|||
.Stroke(2, Black());
|
||||
}
|
||||
|
||||
void ImagePadFast(Painter& sw)
|
||||
{
|
||||
sw.Rectangle(10, 10, 1000, 600)
|
||||
.Fill(TestImg::test(), 100, 100, 500, 100, FILL_PAD|FILL_FAST)
|
||||
.Stroke(2, Black());
|
||||
}
|
||||
|
||||
void ImageRepeat(Painter& sw)
|
||||
{
|
||||
sw.Rectangle(10, 10, 1000, 600)
|
||||
|
|
@ -55,6 +62,7 @@ INITBLOCK {
|
|||
RegisterExample("Image fill exact fast", ImageExactFast);
|
||||
RegisterExample("Image fill reflect", ImageReflect);
|
||||
RegisterExample("Image fill pad", ImagePad);
|
||||
RegisterExample("Image fill pad fast", ImagePadFast);
|
||||
RegisterExample("Image fill repeat", ImageRepeat);
|
||||
RegisterExample("Image vpad&hreflect", ImageVPadHReflect);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,13 +20,16 @@ file
|
|||
TextFillSolid.cpp,
|
||||
TextFillGradient.cpp,
|
||||
TextStrokeGradient.cpp,
|
||||
Div.cpp,
|
||||
MaskBlending.cpp,
|
||||
RadialMaskBlending.cpp,
|
||||
RichText.cpp,
|
||||
Stroke.cpp,
|
||||
Dash.cpp,
|
||||
Path.cpp,
|
||||
Arc.cpp,
|
||||
ThinLine.cpp,
|
||||
Big.cpp,
|
||||
Examples.lay,
|
||||
Test.iml;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ void DoRect(Painter &sw, double size, bool image)
|
|||
|
||||
sw.Begin();
|
||||
sw.Translate(0, size);
|
||||
sw.Rotate(-M_PI/4.0);
|
||||
sw.Rotate(M_PI/4.0);
|
||||
DoRect(sw, size / M_SQRT2, image);
|
||||
sw.End();
|
||||
|
||||
sw.Begin();
|
||||
sw.Translate(size / 2, 1.5 * size);
|
||||
sw.Rotate(M_PI/4.0);
|
||||
sw.Rotate(-M_PI/4.0);
|
||||
DoRect(sw, size / M_SQRT2, image);
|
||||
sw.End();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#include "Examples.h"
|
||||
|
||||
#if 0
|
||||
|
||||
void Radial(Painter& sw)
|
||||
{
|
||||
sw.Circle(400.5, 400.5, 200)
|
||||
|
|
@ -12,5 +10,3 @@ void Radial(Painter& sw)
|
|||
INITBLOCK {
|
||||
RegisterExample("Radial gradient", Radial);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,7 +6,18 @@ void TextFillGradient(Painter& sw)
|
|||
Font fnt = Arial(100).Bold().Italic();
|
||||
Size tsz = GetTextSize(txt, fnt);
|
||||
sw.Text(100, 100, txt, fnt)
|
||||
.Fill(100, 100, Blue(), 100 + tsz.cx, 100 + tsz.cy, LtRed());
|
||||
.Fill(100, 100, Blue(), 100 + tsz.cx, 100/* + tsz.cy*/, LtRed());
|
||||
sw.Translate(0, 200);
|
||||
sw.Rectangle(100, 100, tsz.cx, tsz.cy)
|
||||
.Stroke(1, Blue())
|
||||
.Fill(TestImg::test(), 100, 100, 100 + tsz.cx, 100 + tsz.cy);
|
||||
sw.Move(100, 300).RelLine(tsz.cx + 50, 0).RelLine(-30, tsz.cy).RelLine(-tsz.cx / 2, 0)
|
||||
.Fill(100, 300, Blue(), 100 + tsz.cx, 300/* + tsz.cy*/, LtRed())
|
||||
// .Fill(TestImg::test(), 100, 300, 100 + tsz.cx, 300 + tsz.cy)
|
||||
.Stroke(1, Blue());
|
||||
/* sw.Text(100, 100, txt, fnt)
|
||||
.Fill(TestImg::test(), 100, 100, 100 + tsz.cx, 100 + tsz.cy)
|
||||
.Stroke(1, Black());*/
|
||||
}
|
||||
|
||||
INITBLOCK {
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ App::App() {
|
|||
ctrl.print <<= THISBACK(Print);
|
||||
Reset();
|
||||
LoadFromFile(*this);
|
||||
Title("Painter 2.0");
|
||||
}
|
||||
|
||||
App::~App()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue