mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-18 06:06:01 -06:00
Painter 2.0 FINISHED!
git-svn-id: svn://ultimatepp.org/upp/trunk@854 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
c9f4311517
commit
034c443223
27 changed files with 1562 additions and 615 deletions
|
|
@ -177,32 +177,11 @@ struct SpanSource {
|
|||
virtual void Get(RGBA *span, int x, int y, unsigned len) = 0;
|
||||
};
|
||||
|
||||
struct SolidFiller : Rasterizer::Filler {
|
||||
RGBA *t;
|
||||
RGBA c;
|
||||
|
||||
void Start(int minx, int maxx) { t += minx; }
|
||||
void Render(int val) { AlphaBlendCover8(*t++, c, val); }
|
||||
void Render(int val, int len);
|
||||
};
|
||||
|
||||
struct SpanFiller : Rasterizer::Filler {
|
||||
RGBA *t;
|
||||
const RGBA *s;
|
||||
int y;
|
||||
RGBA *buffer;
|
||||
SpanSource *ss;
|
||||
int alpha;
|
||||
|
||||
void Start(int minx, int maxx);
|
||||
void Render(int val);
|
||||
void Render(int val, int len);
|
||||
};
|
||||
|
||||
class ClipLine {
|
||||
class ClipLine : NoCopy {
|
||||
byte *data;
|
||||
|
||||
public:
|
||||
void Clear() { if(!IsFull()) delete[] data; data = NULL; }
|
||||
void Set(const byte *s, int len) { data = new byte[len]; memcpy(data, s, len); }
|
||||
void SetFull() { ASSERT(!data); data = (byte *)1; }
|
||||
|
||||
|
|
@ -211,52 +190,7 @@ public:
|
|||
operator const byte*() const { return data; }
|
||||
|
||||
ClipLine() { data = NULL; }
|
||||
~ClipLine() { if(!IsFull()) delete[] data; }
|
||||
};
|
||||
|
||||
struct ClipFiller : Rasterizer::Filler {
|
||||
Buffer<byte> buffer;
|
||||
byte *t;
|
||||
int x;
|
||||
int cx;
|
||||
int last;
|
||||
byte *lastn;
|
||||
bool empty;
|
||||
bool full;
|
||||
|
||||
void Span(int c, int len);
|
||||
|
||||
virtual void Render(int val);
|
||||
virtual void Render(int val, int len);
|
||||
virtual void Start(int x, int len);
|
||||
|
||||
void Clear();
|
||||
void Finish(ClipLine& cl);
|
||||
|
||||
ClipFiller(int cx);
|
||||
};
|
||||
|
||||
struct MaskFillerFilter : Rasterizer::Filler {
|
||||
Rasterizer::Filler *t;
|
||||
const byte *mask;
|
||||
int empty;
|
||||
int full;
|
||||
|
||||
void Start(int minx, int maxx);
|
||||
void Render(int val, int len);
|
||||
void Render(int val);
|
||||
|
||||
void Set(Rasterizer::Filler *f, const byte *m) { t = f; mask = m; empty = full = 0; }
|
||||
};
|
||||
|
||||
struct NoAAFillerFilter : Rasterizer::Filler {
|
||||
Rasterizer::Filler *t;
|
||||
|
||||
void Start(int minx, int maxx);
|
||||
void Render(int val, int len);
|
||||
void Render(int val);
|
||||
|
||||
void Set(Rasterizer::Filler *f) { t = f; }
|
||||
~ClipLine() { Clear(); }
|
||||
};
|
||||
|
||||
Image MipMap(const Image& img);
|
||||
|
|
@ -331,6 +265,8 @@ protected:
|
|||
virtual void BeginOp();
|
||||
virtual void EndOp();
|
||||
|
||||
virtual void BeginMaskOp();
|
||||
|
||||
public:
|
||||
enum {
|
||||
MOVE, LINE, QUADRATIC, CUBIC, ARC, DIV
|
||||
|
|
@ -372,12 +308,14 @@ public:
|
|||
bool noaa;
|
||||
};
|
||||
|
||||
ImageBuffer& ib;
|
||||
ImageBuffer& ib;
|
||||
|
||||
Attr attr;
|
||||
Attr pathattr;
|
||||
Array<Attr> attrstack;
|
||||
Vector< Buffer<ClipLine> > clip;
|
||||
Array< ImageBuffer > mask;
|
||||
|
||||
|
||||
Image gradient;
|
||||
RGBA gradient1, gradient2;
|
||||
|
|
@ -405,6 +343,7 @@ public:
|
|||
void MakeGradient(RGBA color1, RGBA color2, int cx);
|
||||
void Gradient(const RGBA& color1, const RGBA& color2, const Pointf& p1, const Pointf& p2);
|
||||
void ColorStop0(Attr& a, double pos, const RGBA& color);
|
||||
void FinishMask();
|
||||
|
||||
public:
|
||||
BufferPainter(ImageBuffer& ib);
|
||||
|
|
|
|||
|
|
@ -17,10 +17,8 @@ void BufferPainter::EndOp()
|
|||
pathattr = attr = attrstack.Top();
|
||||
attrstack.Drop();
|
||||
clip.SetCount(attr.cliplevel);
|
||||
#if 0
|
||||
if(attr.mask)
|
||||
FinishMask();
|
||||
#endif
|
||||
}
|
||||
|
||||
void BufferPainter::TransformOp(const Xform2D& m)
|
||||
|
|
|
|||
137
uppdev/Painter/DrawOp.cpp
Normal file
137
uppdev/Painter/DrawOp.cpp
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
#include "Painter.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void Painter::OffsetOp(Point p)
|
||||
{
|
||||
Begin();
|
||||
Translate(p.x, p.y);
|
||||
}
|
||||
|
||||
void Painter::RectPath(int x, int y, int cx, int cy)
|
||||
{
|
||||
Move(x, y).Line(x + cx, y).Line(x + cx, y + cy).Line(x, y + cy).Close();
|
||||
}
|
||||
|
||||
void Painter::RectPath(const Rect& r)
|
||||
{
|
||||
RectPath(r.left, r.top, r.GetWidth(), r.GetHeight());
|
||||
}
|
||||
|
||||
bool Painter::ClipOp(const Rect& r)
|
||||
{
|
||||
Begin();
|
||||
RectPath(r);
|
||||
Clip();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Painter::ClipoffOp(const Rect& r)
|
||||
{
|
||||
Begin();
|
||||
RectPath(r);
|
||||
Clip();
|
||||
Translate(r.left, r.top);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Painter::ExcludeClipOp(const Rect& r)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Painter::IntersectClipOp(const Rect& r)
|
||||
{
|
||||
return true;
|
||||
RectPath(r);
|
||||
Clip();
|
||||
return true;
|
||||
}
|
||||
|
||||
Rect Painter::GetClipOp() const
|
||||
{
|
||||
return Rect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
bool Painter::IsPaintingOp(const Rect& r) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Painter::DrawRectOp(int x, int y, int cx, int cy, Color color)
|
||||
{
|
||||
RectPath(x, y, cx, cy);
|
||||
Fill(color);
|
||||
}
|
||||
|
||||
void Painter::DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color)
|
||||
{
|
||||
// Color and src support!!!
|
||||
RectPath(x, y, cx, cy);
|
||||
Fill(img, Xform2D::Translation(x, y));
|
||||
}
|
||||
|
||||
void Painter::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color)
|
||||
{
|
||||
double h = width / 2;
|
||||
Move(x1 + h, y1 + h);
|
||||
Line(x2 + h, y2 + h);
|
||||
Stroke(max(width, 0), color);
|
||||
}
|
||||
|
||||
void Painter::DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts,
|
||||
int count_count, int width, Color color, Color doxor)
|
||||
{
|
||||
}
|
||||
|
||||
void Painter::DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count,
|
||||
const int *subpolygon_counts, int scc, const int *disjunct_polygon_counts,
|
||||
int dpcc, Color color, int width, Color outline, uint64 pattern, Color doxor)
|
||||
{
|
||||
}
|
||||
|
||||
void Painter::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color)
|
||||
{
|
||||
}
|
||||
|
||||
void Painter::DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor)
|
||||
{
|
||||
Sizef sz = r.GetSize();
|
||||
Ellipse(r.left + sz.cx / 2, r.top + sz.cy / 2, sz.cx / 2, sz.cy / 2);
|
||||
Fill(color);
|
||||
Stroke(max(pen, 0), pencolor);
|
||||
}
|
||||
|
||||
void Painter::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx)
|
||||
{
|
||||
Begin();
|
||||
EvenOdd(true);
|
||||
if(angle)
|
||||
Rotate(angle * M_2PI / 36000);
|
||||
if(n < 0)
|
||||
n = wstrlen(text);
|
||||
double *ddx = NULL;
|
||||
Buffer<double> h;
|
||||
if(dx) {
|
||||
h.Alloc(n);
|
||||
ddx = h;
|
||||
for(int i = 0; i < n; i++)
|
||||
ddx[i] = dx[i];
|
||||
}
|
||||
Text(x, y, text, font, n, ddx);
|
||||
Fill(ink);
|
||||
End();
|
||||
}
|
||||
|
||||
void Painter::DrawPaintingOp(const Rect& target, const Painting& p)
|
||||
{
|
||||
Size sz = target.GetSize();
|
||||
Sizef psz = p.GetSize();
|
||||
Begin();
|
||||
Translate(target.left, target.top);
|
||||
Scale(sz.cx / psz.cx, sz.cy / psz.cy);
|
||||
Paint(p);
|
||||
End();
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
#include "Painter.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void SolidFiller::Render(int val, int len)
|
||||
{
|
||||
if(val == 0) {
|
||||
t += len;
|
||||
return;
|
||||
}
|
||||
if(((val - 256) | (c.a - 255)) == 0) {
|
||||
while(len >= 16) {
|
||||
t[0] = c; t[1] = c; t[2] = c; t[3] = c;
|
||||
t[4] = c; t[5] = c; t[6] = c; t[7] = c;
|
||||
t[8] = c; t[9] = c; t[10] = c; t[11] = c;
|
||||
t[12] = c; t[13] = c; t[14] = c; t[15] = c;
|
||||
t += 16;
|
||||
len -= 16;
|
||||
}
|
||||
switch(len) {
|
||||
case 15: t[14] = c;
|
||||
case 14: t[13] = c;
|
||||
case 13: t[12] = c;
|
||||
case 12: t[11] = c;
|
||||
case 11: t[10] = c;
|
||||
case 10: t[9] = c;
|
||||
case 9: t[8] = c;
|
||||
case 8: t[7] = c;
|
||||
case 7: t[6] = c;
|
||||
case 6: t[5] = c;
|
||||
case 5: t[4] = c;
|
||||
case 4: t[3] = c;
|
||||
case 3: t[2] = c;
|
||||
case 2: t[1] = c;
|
||||
case 1: t[0] = c;
|
||||
}
|
||||
t += len;
|
||||
}
|
||||
else {
|
||||
RGBA c1;
|
||||
if(val != 256)
|
||||
c1 = Mul8(c, val);
|
||||
else
|
||||
c1 = c;
|
||||
RGBA *e = t + len;
|
||||
while(t < e)
|
||||
AlphaBlend(*t++, c1);
|
||||
}
|
||||
}
|
||||
|
||||
void Render(ImageBuffer& ib, Rasterizer& r, const RGBA& color, bool evenodd)
|
||||
{
|
||||
Size sz = ib.GetSize();
|
||||
SolidFiller f;
|
||||
f.c = color;
|
||||
for(int y = r.MinY(); y <= r.MaxY(); y++) {
|
||||
f.t = ib[y];
|
||||
r.Render(y, f, evenodd);
|
||||
}
|
||||
r.Reset();
|
||||
}
|
||||
|
||||
void SpanFiller::Start(int minx, int maxx)
|
||||
{
|
||||
t += minx;
|
||||
ss->Get(buffer, minx, y, maxx - minx + 1);
|
||||
s = buffer;
|
||||
}
|
||||
|
||||
void SpanFiller::Render(int val)
|
||||
{
|
||||
if(alpha != 256)
|
||||
val = alpha * val >> 8;
|
||||
AlphaBlendCover8(*t++, *s++, val);
|
||||
}
|
||||
|
||||
void SpanFiller::Render(int val, int len)
|
||||
{
|
||||
if(val == 0) {
|
||||
t += len;
|
||||
s += len;
|
||||
return;
|
||||
}
|
||||
const RGBA *e = t + len;
|
||||
if(alpha != 256)
|
||||
val = alpha * val >> 8;
|
||||
if(val == 256)
|
||||
while(t < e) {
|
||||
if(s->a == 255)
|
||||
*t++ = *s++;
|
||||
else
|
||||
AlphaBlend(*t++, *s++);
|
||||
}
|
||||
else
|
||||
while(t < e)
|
||||
AlphaBlendCover8(*t++, *s++, val);
|
||||
}
|
||||
|
||||
void NoAAFillerFilter::Start(int minx, int maxx)
|
||||
{
|
||||
t->Start(minx, maxx);
|
||||
}
|
||||
|
||||
void NoAAFillerFilter::Render(int val, int len)
|
||||
{
|
||||
t->Render(val < 128 ? 0 : 256, len);
|
||||
}
|
||||
|
||||
void NoAAFillerFilter::Render(int val)
|
||||
{
|
||||
t->Render(val < 128 ? 0 : 256);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
272
uppdev/Painter/Fillers.cpp
Normal file
272
uppdev/Painter/Fillers.cpp
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
#include "Painter.h"
|
||||
#include "Fillers.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void SolidFiller::Start(int minx, int maxx)
|
||||
{
|
||||
t += minx;
|
||||
}
|
||||
|
||||
void SolidFiller::Render(int val)
|
||||
{
|
||||
AlphaBlendCover8(*t++, c, val);
|
||||
}
|
||||
|
||||
void SolidFiller::Render(int val, int len)
|
||||
{
|
||||
if(val == 0) {
|
||||
t += len;
|
||||
return;
|
||||
}
|
||||
if(((val - 256) | (c.a - 255)) == 0) {
|
||||
while(len >= 16) {
|
||||
t[0] = c; t[1] = c; t[2] = c; t[3] = c;
|
||||
t[4] = c; t[5] = c; t[6] = c; t[7] = c;
|
||||
t[8] = c; t[9] = c; t[10] = c; t[11] = c;
|
||||
t[12] = c; t[13] = c; t[14] = c; t[15] = c;
|
||||
t += 16;
|
||||
len -= 16;
|
||||
}
|
||||
switch(len) {
|
||||
case 15: t[14] = c;
|
||||
case 14: t[13] = c;
|
||||
case 13: t[12] = c;
|
||||
case 12: t[11] = c;
|
||||
case 11: t[10] = c;
|
||||
case 10: t[9] = c;
|
||||
case 9: t[8] = c;
|
||||
case 8: t[7] = c;
|
||||
case 7: t[6] = c;
|
||||
case 6: t[5] = c;
|
||||
case 5: t[4] = c;
|
||||
case 4: t[3] = c;
|
||||
case 3: t[2] = c;
|
||||
case 2: t[1] = c;
|
||||
case 1: t[0] = c;
|
||||
}
|
||||
t += len;
|
||||
}
|
||||
else {
|
||||
RGBA c1;
|
||||
if(val != 256)
|
||||
c1 = Mul8(c, val);
|
||||
else
|
||||
c1 = c;
|
||||
RGBA *e = t + len;
|
||||
while(t < e)
|
||||
AlphaBlend(*t++, c1);
|
||||
}
|
||||
}
|
||||
|
||||
void SpanFiller::Start(int minx, int maxx)
|
||||
{
|
||||
t += minx;
|
||||
ss->Get(buffer, minx, y, maxx - minx + 1);
|
||||
s = buffer;
|
||||
}
|
||||
|
||||
void SpanFiller::Render(int val)
|
||||
{
|
||||
if(alpha != 256)
|
||||
val = alpha * val >> 8;
|
||||
AlphaBlendCover8(*t++, *s++, val);
|
||||
}
|
||||
|
||||
void SpanFiller::Render(int val, int len)
|
||||
{
|
||||
if(val == 0) {
|
||||
t += len;
|
||||
s += len;
|
||||
return;
|
||||
}
|
||||
const RGBA *e = t + len;
|
||||
if(alpha != 256)
|
||||
val = alpha * val >> 8;
|
||||
if(val == 256)
|
||||
while(t < e) {
|
||||
if(s->a == 255)
|
||||
*t++ = *s++;
|
||||
else
|
||||
AlphaBlend(*t++, *s++);
|
||||
}
|
||||
else
|
||||
while(t < e)
|
||||
AlphaBlendCover8(*t++, *s++, val);
|
||||
}
|
||||
|
||||
ClipFiller::ClipFiller(int _cx)
|
||||
{
|
||||
cx = _cx;
|
||||
buffer.Alloc(2 * cx);
|
||||
}
|
||||
|
||||
void ClipFiller::Clear()
|
||||
{
|
||||
t = ~buffer;
|
||||
x = 0;
|
||||
empty = true;
|
||||
full = true;
|
||||
last = -1;
|
||||
}
|
||||
|
||||
void ClipFiller::Start(int xmin, int xmax)
|
||||
{
|
||||
Render(0, xmin);
|
||||
}
|
||||
|
||||
void ClipFiller::Span(int val, int len)
|
||||
{
|
||||
int v = val >> 1;
|
||||
if(last == val) {
|
||||
int n = min(v + 128 - *lastn - 1, len);
|
||||
*lastn += n;
|
||||
len -= n;
|
||||
}
|
||||
last = -1;
|
||||
while(len > 128) {
|
||||
int n = min(len, 128);
|
||||
*t++ = 0;
|
||||
*t++ = v + n - 1;
|
||||
len -= n;
|
||||
}
|
||||
if(len) {
|
||||
*t++ = 0;
|
||||
last = val;
|
||||
lastn = t;
|
||||
*t++ = v + len - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ClipFiller::Render(int val, int len)
|
||||
{
|
||||
if(val == 256) {
|
||||
Span(256, len);
|
||||
empty = false;
|
||||
}
|
||||
else {
|
||||
full = false;
|
||||
if(val == 0)
|
||||
Span(0, len);
|
||||
else {
|
||||
memset(t, val, len);
|
||||
t += len;
|
||||
empty = false;
|
||||
last = -1;
|
||||
}
|
||||
}
|
||||
x += len;
|
||||
}
|
||||
|
||||
void ClipFiller::Render(int val)
|
||||
{
|
||||
Render(val, 1);
|
||||
}
|
||||
|
||||
void ClipFiller::Finish(ClipLine& cl)
|
||||
{
|
||||
if(empty)
|
||||
return;
|
||||
while(x < cx) {
|
||||
int n = min(cx - x, 128);
|
||||
*t++ = 0;
|
||||
*t++ = n - 1;
|
||||
x += n;
|
||||
full = false;
|
||||
}
|
||||
if(full)
|
||||
cl.SetFull();
|
||||
else
|
||||
cl.Set(~buffer, t - ~buffer);
|
||||
}
|
||||
|
||||
void MaskFillerFilter::Render(int val)
|
||||
{
|
||||
for(;;) {
|
||||
if(empty) {
|
||||
t->Render(0);
|
||||
empty--;
|
||||
return;
|
||||
}
|
||||
if(full) {
|
||||
t->Render(val);
|
||||
full--;
|
||||
return;
|
||||
}
|
||||
byte m = *mask++;
|
||||
if(m) {
|
||||
t->Render(val * m >> 8);
|
||||
return;
|
||||
}
|
||||
m = *mask++;
|
||||
if(m < 128)
|
||||
empty = m + 1;
|
||||
else
|
||||
full = m - 128 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void MaskFillerFilter::Render(int val, int len)
|
||||
{
|
||||
while(len)
|
||||
if(empty) {
|
||||
int n = min(len, empty);
|
||||
t->Render(0, n);
|
||||
empty -= n;
|
||||
len -= n;
|
||||
}
|
||||
else
|
||||
if(full) {
|
||||
int n = min(len, full);
|
||||
t->Render(val, n);
|
||||
full -= n;
|
||||
len -= n;
|
||||
}
|
||||
else {
|
||||
byte m = *mask++;
|
||||
if(m) {
|
||||
t->Render(val * m >> 8);
|
||||
len--;
|
||||
}
|
||||
else {
|
||||
m = *mask++;
|
||||
if(m < 128)
|
||||
empty = m + 1;
|
||||
else
|
||||
full = m - 128 + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct NilFiller : Rasterizer::Filler {
|
||||
void Start(int minx, int maxx) {}
|
||||
void Render(int val, int len) {}
|
||||
void Render(int val) {}
|
||||
};
|
||||
|
||||
void MaskFillerFilter::Start(int minx, int maxx)
|
||||
{
|
||||
t->Start(minx, maxx);
|
||||
Rasterizer::Filler *h = t;
|
||||
NilFiller nil;
|
||||
t = &nil;
|
||||
Render(0, minx);
|
||||
t = h;
|
||||
}
|
||||
|
||||
void NoAAFillerFilter::Start(int minx, int maxx)
|
||||
{
|
||||
t->Start(minx, maxx);
|
||||
}
|
||||
|
||||
void NoAAFillerFilter::Render(int val, int len)
|
||||
{
|
||||
t->Render(val < 128 ? 0 : 256, len);
|
||||
}
|
||||
|
||||
void NoAAFillerFilter::Render(int val)
|
||||
{
|
||||
t->Render(val < 128 ? 0 : 256);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
70
uppdev/Painter/Fillers.h
Normal file
70
uppdev/Painter/Fillers.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
NAMESPACE_UPP
|
||||
|
||||
struct SolidFiller : Rasterizer::Filler {
|
||||
RGBA *t;
|
||||
RGBA c;
|
||||
|
||||
void Start(int minx, int maxx);
|
||||
void Render(int val);
|
||||
void Render(int val, int len);
|
||||
};
|
||||
|
||||
struct SpanFiller : Rasterizer::Filler {
|
||||
RGBA *t;
|
||||
const RGBA *s;
|
||||
int y;
|
||||
RGBA *buffer;
|
||||
SpanSource *ss;
|
||||
int alpha;
|
||||
|
||||
void Start(int minx, int maxx);
|
||||
void Render(int val);
|
||||
void Render(int val, int len);
|
||||
};
|
||||
|
||||
struct ClipFiller : Rasterizer::Filler {
|
||||
Buffer<byte> buffer;
|
||||
byte *t;
|
||||
int x;
|
||||
int cx;
|
||||
int last;
|
||||
byte *lastn;
|
||||
bool empty;
|
||||
bool full;
|
||||
|
||||
void Span(int c, int len);
|
||||
|
||||
virtual void Render(int val);
|
||||
virtual void Render(int val, int len);
|
||||
virtual void Start(int x, int len);
|
||||
|
||||
void Clear();
|
||||
void Finish(ClipLine& cl);
|
||||
|
||||
ClipFiller(int cx);
|
||||
};
|
||||
|
||||
struct MaskFillerFilter : Rasterizer::Filler {
|
||||
Rasterizer::Filler *t;
|
||||
const byte *mask;
|
||||
int empty;
|
||||
int full;
|
||||
|
||||
void Start(int minx, int maxx);
|
||||
void Render(int val, int len);
|
||||
void Render(int val);
|
||||
|
||||
void Set(Rasterizer::Filler *f, const byte *m) { t = f; mask = m; empty = full = 0; }
|
||||
};
|
||||
|
||||
struct NoAAFillerFilter : Rasterizer::Filler {
|
||||
Rasterizer::Filler *t;
|
||||
|
||||
void Start(int minx, int maxx);
|
||||
void Render(int val, int len);
|
||||
void Render(int val);
|
||||
|
||||
void Set(Rasterizer::Filler *f) { t = f; }
|
||||
};
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
@ -93,7 +93,7 @@ struct sMakeCharOutline : LRUCache<String, FontChar>::Maker {
|
|||
}
|
||||
};
|
||||
|
||||
void Painter::CharacterOp(double x, double y, int ch, Font fnt)
|
||||
void Painter::CharacterOp(const Pointf& p, int ch, Font fnt)
|
||||
{
|
||||
PAINTER_TIMING("CharacterOp");
|
||||
String s;
|
||||
|
|
@ -105,7 +105,7 @@ void Painter::CharacterOp(double x, double y, int ch, Font fnt)
|
|||
h.fc.chr = ch;
|
||||
s = cache.Get(h);
|
||||
}
|
||||
RenderCharPath(s, s.GetLength(), *this, x, y + fnt.Info().GetAscent());
|
||||
RenderCharPath(s, s.GetLength(), *this, p.x, p.y + fnt.Info().GetAscent());
|
||||
EvenOdd(true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,152 +1,152 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all coM_PIes.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Recycled for U++ by Miroslav Fidler 2008
|
||||
|
||||
#include "Painter.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
|
||||
static inline double ft_dbl(int p)
|
||||
{
|
||||
return double(p) / 64.0;
|
||||
}
|
||||
|
||||
bool RenderOutline(const FT_Outline& outline, Painter& path, double xx, double yy)
|
||||
{
|
||||
FT_Vector v_last;
|
||||
FT_Vector v_control;
|
||||
FT_Vector v_start;
|
||||
double x1, y1, x2, y2, x3, y3;
|
||||
FT_Vector* point;
|
||||
FT_Vector* limit;
|
||||
char* tags;
|
||||
int n; // index of contour in outline
|
||||
char tag; // current point's state
|
||||
int first = 0; // index of first point in contour
|
||||
for(n = 0; n < outline.n_contours; n++) {
|
||||
int last = outline.contours[n];
|
||||
limit = outline.points + last;
|
||||
v_start = outline.points[first];
|
||||
v_last = outline.points[last];
|
||||
v_control = v_start;
|
||||
point = outline.points + first;
|
||||
tags = outline.tags + first;
|
||||
tag = FT_CURVE_TAG(tags[0]);
|
||||
if(tag == FT_CURVE_TAG_CUBIC) return false;
|
||||
if(tag == FT_CURVE_TAG_CONIC) {
|
||||
if(FT_CURVE_TAG(outline.tags[last]) == FT_CURVE_TAG_ON) {
|
||||
// start at last point if it is on the curve
|
||||
v_start = v_last;
|
||||
limit--;
|
||||
}
|
||||
else {
|
||||
// if both first and last points are conic,
|
||||
// start at their middle and record its position
|
||||
// for closure
|
||||
v_start.x = (v_start.x + v_last.x) / 2;
|
||||
v_start.y = (v_start.y + v_last.y) / 2;
|
||||
v_last = v_start;
|
||||
}
|
||||
point--;
|
||||
tags--;
|
||||
}
|
||||
path.Move(ft_dbl(v_start.x) + xx, -ft_dbl(v_start.y) + yy);
|
||||
while(point < limit) {
|
||||
point++;
|
||||
tags++;
|
||||
|
||||
tag = FT_CURVE_TAG(tags[0]);
|
||||
switch(tag) {
|
||||
case FT_CURVE_TAG_ON:
|
||||
path.Line(ft_dbl(point->x) + xx, -ft_dbl(point->y) + yy);
|
||||
continue;
|
||||
case FT_CURVE_TAG_CONIC:
|
||||
v_control.x = point->x;
|
||||
v_control.y = point->y;
|
||||
Do_Conic:
|
||||
if(point < limit) {
|
||||
FT_Vector vec;
|
||||
FT_Vector v_middle;
|
||||
point++;
|
||||
tags++;
|
||||
tag = FT_CURVE_TAG(tags[0]);
|
||||
vec.x = point->x;
|
||||
vec.y = point->y;
|
||||
if(tag == FT_CURVE_TAG_ON) {
|
||||
path.Quadratic(ft_dbl(v_control.x) + xx, -ft_dbl(v_control.y) + yy,
|
||||
ft_dbl(vec.x) + xx, -ft_dbl(vec.y) + yy);
|
||||
continue;
|
||||
}
|
||||
if(tag != FT_CURVE_TAG_CONIC) return false;
|
||||
v_middle.x = (v_control.x + vec.x) / 2;
|
||||
v_middle.y = (v_control.y + vec.y) / 2;
|
||||
path.Quadratic(ft_dbl(v_control.x) + xx, -ft_dbl(v_control.y) + yy,
|
||||
ft_dbl(v_middle.x) + xx, -ft_dbl(v_middle.y) + yy);
|
||||
v_control = vec;
|
||||
goto Do_Conic;
|
||||
}
|
||||
path.Quadratic(ft_dbl(v_control.x) + xx, -ft_dbl(v_control.y) + yy,
|
||||
ft_dbl(v_start.x) + xx, -ft_dbl(v_start.y) + yy);
|
||||
goto Close;
|
||||
|
||||
default:
|
||||
FT_Vector vec1, vec2;
|
||||
if(point + 1 > limit || FT_CURVE_TAG(tags[1]) != FT_CURVE_TAG_CUBIC)
|
||||
return false;
|
||||
vec1.x = point[0].x;
|
||||
vec1.y = point[0].y;
|
||||
vec2.x = point[1].x;
|
||||
vec2.y = point[1].y;
|
||||
point += 2;
|
||||
tags += 2;
|
||||
if(point <= limit) {
|
||||
FT_Vector vec;
|
||||
vec.x = point->x;
|
||||
vec.y = point->y;
|
||||
path.Cubic(ft_dbl(vec1.x) + xx, -ft_dbl(vec1.y) + yy,
|
||||
ft_dbl(vec2.x) + xx, -ft_dbl(vec2.y) + yy,
|
||||
ft_dbl(vec.x) + xx, -ft_dbl(vec.y) + yy);
|
||||
continue;
|
||||
}
|
||||
path.Cubic(ft_dbl(vec1.x) + xx, -ft_dbl(vec1.y) + yy,
|
||||
ft_dbl(vec2.x) + xx, -ft_dbl(vec2.y) + yy,
|
||||
ft_dbl(v_start.x) + xx, -ft_dbl(v_start.y) + yy);
|
||||
goto Close;
|
||||
}
|
||||
}
|
||||
Close:
|
||||
path.Close();
|
||||
first = last + 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Painter::CharacterOp(double x, double y, int ch, Font fnt)
|
||||
{
|
||||
PAINTER_TIMING("CharacterOp");
|
||||
FontInfo fi = fnt.Info();
|
||||
FT_Face face = XftLockFace(fi.GetXftFont());
|
||||
int glyph_index = FT_Get_Char_Index(face, ch);
|
||||
if(FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT) == 0)
|
||||
RenderOutline(face->glyph->outline, *this, x, y + fnt.Info().GetAscent());
|
||||
XftUnlockFace(fi.GetXftFont());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-Grain Geometry - Version 2.4
|
||||
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all coM_PIes.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Contact: mcseem@antigrain.com
|
||||
// mcseemagg@yahoo.com
|
||||
// http://www.antigrain.com
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Recycled for U++ by Miroslav Fidler 2008
|
||||
|
||||
#include "Painter.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
|
||||
static inline double ft_dbl(int p)
|
||||
{
|
||||
return double(p) / 64.0;
|
||||
}
|
||||
|
||||
bool RenderOutline(const FT_Outline& outline, Painter& path, double xx, double yy)
|
||||
{
|
||||
FT_Vector v_last;
|
||||
FT_Vector v_control;
|
||||
FT_Vector v_start;
|
||||
double x1, y1, x2, y2, x3, y3;
|
||||
FT_Vector* point;
|
||||
FT_Vector* limit;
|
||||
char* tags;
|
||||
int n; // index of contour in outline
|
||||
char tag; // current point's state
|
||||
int first = 0; // index of first point in contour
|
||||
for(n = 0; n < outline.n_contours; n++) {
|
||||
int last = outline.contours[n];
|
||||
limit = outline.points + last;
|
||||
v_start = outline.points[first];
|
||||
v_last = outline.points[last];
|
||||
v_control = v_start;
|
||||
point = outline.points + first;
|
||||
tags = outline.tags + first;
|
||||
tag = FT_CURVE_TAG(tags[0]);
|
||||
if(tag == FT_CURVE_TAG_CUBIC) return false;
|
||||
if(tag == FT_CURVE_TAG_CONIC) {
|
||||
if(FT_CURVE_TAG(outline.tags[last]) == FT_CURVE_TAG_ON) {
|
||||
// start at last point if it is on the curve
|
||||
v_start = v_last;
|
||||
limit--;
|
||||
}
|
||||
else {
|
||||
// if both first and last points are conic,
|
||||
// start at their middle and record its position
|
||||
// for closure
|
||||
v_start.x = (v_start.x + v_last.x) / 2;
|
||||
v_start.y = (v_start.y + v_last.y) / 2;
|
||||
v_last = v_start;
|
||||
}
|
||||
point--;
|
||||
tags--;
|
||||
}
|
||||
path.Move(ft_dbl(v_start.x) + xx, -ft_dbl(v_start.y) + yy);
|
||||
while(point < limit) {
|
||||
point++;
|
||||
tags++;
|
||||
|
||||
tag = FT_CURVE_TAG(tags[0]);
|
||||
switch(tag) {
|
||||
case FT_CURVE_TAG_ON:
|
||||
path.Line(ft_dbl(point->x) + xx, -ft_dbl(point->y) + yy);
|
||||
continue;
|
||||
case FT_CURVE_TAG_CONIC:
|
||||
v_control.x = point->x;
|
||||
v_control.y = point->y;
|
||||
Do_Conic:
|
||||
if(point < limit) {
|
||||
FT_Vector vec;
|
||||
FT_Vector v_middle;
|
||||
point++;
|
||||
tags++;
|
||||
tag = FT_CURVE_TAG(tags[0]);
|
||||
vec.x = point->x;
|
||||
vec.y = point->y;
|
||||
if(tag == FT_CURVE_TAG_ON) {
|
||||
path.Quadratic(ft_dbl(v_control.x) + xx, -ft_dbl(v_control.y) + yy,
|
||||
ft_dbl(vec.x) + xx, -ft_dbl(vec.y) + yy);
|
||||
continue;
|
||||
}
|
||||
if(tag != FT_CURVE_TAG_CONIC) return false;
|
||||
v_middle.x = (v_control.x + vec.x) / 2;
|
||||
v_middle.y = (v_control.y + vec.y) / 2;
|
||||
path.Quadratic(ft_dbl(v_control.x) + xx, -ft_dbl(v_control.y) + yy,
|
||||
ft_dbl(v_middle.x) + xx, -ft_dbl(v_middle.y) + yy);
|
||||
v_control = vec;
|
||||
goto Do_Conic;
|
||||
}
|
||||
path.Quadratic(ft_dbl(v_control.x) + xx, -ft_dbl(v_control.y) + yy,
|
||||
ft_dbl(v_start.x) + xx, -ft_dbl(v_start.y) + yy);
|
||||
goto Close;
|
||||
|
||||
default:
|
||||
FT_Vector vec1, vec2;
|
||||
if(point + 1 > limit || FT_CURVE_TAG(tags[1]) != FT_CURVE_TAG_CUBIC)
|
||||
return false;
|
||||
vec1.x = point[0].x;
|
||||
vec1.y = point[0].y;
|
||||
vec2.x = point[1].x;
|
||||
vec2.y = point[1].y;
|
||||
point += 2;
|
||||
tags += 2;
|
||||
if(point <= limit) {
|
||||
FT_Vector vec;
|
||||
vec.x = point->x;
|
||||
vec.y = point->y;
|
||||
path.Cubic(ft_dbl(vec1.x) + xx, -ft_dbl(vec1.y) + yy,
|
||||
ft_dbl(vec2.x) + xx, -ft_dbl(vec2.y) + yy,
|
||||
ft_dbl(vec.x) + xx, -ft_dbl(vec.y) + yy);
|
||||
continue;
|
||||
}
|
||||
path.Cubic(ft_dbl(vec1.x) + xx, -ft_dbl(vec1.y) + yy,
|
||||
ft_dbl(vec2.x) + xx, -ft_dbl(vec2.y) + yy,
|
||||
ft_dbl(v_start.x) + xx, -ft_dbl(v_start.y) + yy);
|
||||
goto Close;
|
||||
}
|
||||
}
|
||||
Close:
|
||||
path.Close();
|
||||
first = last + 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Painter::CharacterOp(const Pointf& p, int ch, Font fnt)
|
||||
{
|
||||
PAINTER_TIMING("CharacterOp");
|
||||
FontInfo fi = fnt.Info();
|
||||
FT_Face face = XftLockFace(fi.GetXftFont());
|
||||
int glyph_index = FT_Get_Char_Index(face, ch);
|
||||
if(FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT) == 0)
|
||||
RenderOutline(face->glyph->outline, *this, p.x, p.y + fnt.Info().GetAscent());
|
||||
XftUnlockFace(fi.GetXftFont());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -2,164 +2,81 @@
|
|||
|
||||
NAMESPACE_UPP
|
||||
|
||||
ClipFiller::ClipFiller(int _cx)
|
||||
void BufferPainter::BeginMaskOp()
|
||||
{
|
||||
cx = _cx;
|
||||
buffer.Alloc(2 * cx + 2);
|
||||
attr.mask = true;
|
||||
Size sz = ib.GetSize();
|
||||
mask.Add() = ib;
|
||||
ib.Create(sz);
|
||||
Clear(RGBAZero());
|
||||
Begin();
|
||||
}
|
||||
|
||||
void ClipFiller::Clear()
|
||||
static inline byte *sSpan(byte *t, int c, int& len)
|
||||
{
|
||||
t = ~buffer;
|
||||
x = 0;
|
||||
empty = true;
|
||||
full = true;
|
||||
last = -1;
|
||||
}
|
||||
|
||||
void ClipFiller::Start(int xmin, int xmax)
|
||||
{
|
||||
Render(0, xmin);
|
||||
}
|
||||
|
||||
void ClipFiller::Span(int val, int len)
|
||||
{
|
||||
int v = val >> 1;
|
||||
if(last == val) {
|
||||
int n = min(v + 128 - *lastn - 1, len);
|
||||
*lastn += n;
|
||||
len -= n;
|
||||
}
|
||||
last = -1;
|
||||
while(len > 128) {
|
||||
int n = min(len, 128);
|
||||
*t++ = 0;
|
||||
*t++ = v + n - 1;
|
||||
*t++ = c + n - 1;
|
||||
len -= n;
|
||||
}
|
||||
if(len) {
|
||||
*t++ = 0;
|
||||
last = val;
|
||||
lastn = t;
|
||||
*t++ = v + len - 1;
|
||||
*t++ = c + len - 1;
|
||||
len = 0;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
void ClipFiller::Render(int val, int len)
|
||||
void BufferPainter::FinishMask()
|
||||
{
|
||||
if(val == 256) {
|
||||
Span(256, len);
|
||||
empty = false;
|
||||
Buffer<byte> wb(2 * ib.GetWidth());
|
||||
bool creating = false;
|
||||
if(!attr.hasclip) {
|
||||
clip.Add().Alloc(ib.GetHeight());
|
||||
attr.hasclip = true;
|
||||
attr.cliplevel = clip.GetCount();
|
||||
creating = true;
|
||||
}
|
||||
else {
|
||||
full = false;
|
||||
if(val == 0)
|
||||
Span(0, len);
|
||||
else {
|
||||
memset(t, val, len);
|
||||
t += len;
|
||||
empty = false;
|
||||
last = -1;
|
||||
}
|
||||
}
|
||||
x += len;
|
||||
}
|
||||
|
||||
void ClipFiller::Render(int val)
|
||||
{
|
||||
Render(val, 1);
|
||||
}
|
||||
|
||||
void ClipFiller::Finish(ClipLine& cl)
|
||||
{
|
||||
if(empty)
|
||||
return;
|
||||
while(x < cx) {
|
||||
int n = min(cx - x, 128);
|
||||
*t++ = 0;
|
||||
*t++ = n - 1;
|
||||
x += n;
|
||||
full = false;
|
||||
}
|
||||
if(full)
|
||||
cl.SetFull();
|
||||
else
|
||||
cl.Set(~buffer, t - ~buffer);
|
||||
}
|
||||
|
||||
void MaskFillerFilter::Render(int val)
|
||||
{
|
||||
for(;;) {
|
||||
if(empty) {
|
||||
t->Render(0);
|
||||
empty--;
|
||||
return;
|
||||
}
|
||||
if(full) {
|
||||
t->Render(val);
|
||||
full--;
|
||||
return;
|
||||
}
|
||||
byte m = *mask++;
|
||||
if(m) {
|
||||
t->Render(val * m >> 8);
|
||||
return;
|
||||
}
|
||||
m = *mask++;
|
||||
if(m < 128)
|
||||
empty = m + 1;
|
||||
else
|
||||
full = m - 128 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void MaskFillerFilter::Render(int val, int len)
|
||||
{
|
||||
while(len)
|
||||
if(empty) {
|
||||
int n = min(len, empty);
|
||||
t->Render(0, n);
|
||||
empty -= n;
|
||||
len -= n;
|
||||
}
|
||||
else
|
||||
if(full) {
|
||||
int n = min(len, full);
|
||||
t->Render(val, n);
|
||||
full -= n;
|
||||
len -= n;
|
||||
}
|
||||
else {
|
||||
byte m = *mask++;
|
||||
if(m) {
|
||||
int r = val * m >> 8;
|
||||
t->Render(r);
|
||||
len--;
|
||||
}
|
||||
else {
|
||||
m = *mask++;
|
||||
if(m < 128)
|
||||
empty = m + 1;
|
||||
Buffer<ClipLine>& cl = clip.Top();
|
||||
for(int y = 0; y < ib.GetHeight(); y++)
|
||||
if(creating || !cl[y].IsEmpty()) {
|
||||
bool full = true;
|
||||
bool empty = true;
|
||||
int c0 = 0;
|
||||
int c256 = 0;
|
||||
const RGBA *s = ib[y];
|
||||
const RGBA *e = ib[y] + ib.GetWidth();
|
||||
byte *t = wb;
|
||||
while(s < e) {
|
||||
int val = s->a * (56 * s->r + 183 * s->g + 20 * s->b) >> 16;
|
||||
if(val == 0) {
|
||||
if(c256) t = sSpan(t, 128, c256);
|
||||
c0++;
|
||||
full = false;
|
||||
}
|
||||
else
|
||||
full = m - 128 + 1;
|
||||
if(val == 256) {
|
||||
if(c0) t = sSpan(t, 0, c0);
|
||||
c256++;
|
||||
empty = false;
|
||||
}
|
||||
else {
|
||||
if(c256) t = sSpan(t, 128, c256);
|
||||
if(c0) t = sSpan(t, 0, c0);
|
||||
*t++ = val;
|
||||
full = empty = false;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
if(c256) t = sSpan(t, 128, c256);
|
||||
if(c0) t = sSpan(t, 0, c0);
|
||||
cl[y].Clear();
|
||||
cl[y].Set(~wb, t - ~wb);
|
||||
}
|
||||
}
|
||||
|
||||
struct NilFiller : Rasterizer::Filler {
|
||||
void Start(int minx, int maxx) {}
|
||||
void Render(int val, int len) {}
|
||||
void Render(int val) {}
|
||||
};
|
||||
|
||||
void MaskFillerFilter::Start(int minx, int maxx)
|
||||
{
|
||||
t->Start(minx, maxx);
|
||||
Rasterizer::Filler *h = t;
|
||||
NilFiller nil;
|
||||
t = &nil;
|
||||
Render(0, minx);
|
||||
t = h;
|
||||
ib = mask.Top();
|
||||
mask.Drop();
|
||||
attr.mask = false;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
260
uppdev/Painter/PaintPainting.icpp
Normal file
260
uppdev/Painter/PaintPainting.icpp
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
#include "Painter.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
template <class T>
|
||||
void sGet(T& r, StringStream& ss)
|
||||
{
|
||||
ss.Get(&r, sizeof(T));
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
T sGet(StringStream& ss)
|
||||
{
|
||||
T r;
|
||||
ss.Get(&r, sizeof(T));
|
||||
return r;
|
||||
}
|
||||
|
||||
void Painter::Paint(const Painting& pic)
|
||||
{
|
||||
StringStream ss(pic.cmd);
|
||||
Pointf p, p1, p2;
|
||||
RGBA c, c1;
|
||||
Value v;
|
||||
int f, ch, n, hasdx;
|
||||
Xform2D m;
|
||||
double r, w;
|
||||
Font fnt;
|
||||
int ii = 0;
|
||||
for(;;) {
|
||||
int cmd = ss.Get();
|
||||
if(cmd < 0)
|
||||
return;
|
||||
bool rel = cmd & 1;
|
||||
switch(cmd) {
|
||||
case PAINTING_CLEAR:
|
||||
ClearOp(sGet<RGBA>(ss));
|
||||
break;
|
||||
case PAINTING_MOVE:
|
||||
case PAINTING_MOVE_REL:
|
||||
sGet(p, ss);
|
||||
MoveOp(p, rel);
|
||||
break;
|
||||
case PAINTING_LINE:
|
||||
case PAINTING_LINE_REL:
|
||||
sGet(p, ss);
|
||||
LineOp(p, rel);
|
||||
break;
|
||||
case PAINTING_QUADRATIC:
|
||||
case PAINTING_QUADRATIC_REL:
|
||||
sGet(p1, ss);
|
||||
sGet(p, ss);
|
||||
QuadraticOp(p1, p, rel);
|
||||
break;
|
||||
case PAINTING_QUADRATIC_S:
|
||||
case PAINTING_QUADRATIC_S_REL:
|
||||
sGet(p, ss);
|
||||
QuadraticOp(p, rel);
|
||||
break;
|
||||
case PAINTING_CUBIC:
|
||||
case PAINTING_CUBIC_REL:
|
||||
sGet(p1, ss);
|
||||
sGet(p2, ss);
|
||||
sGet(p, ss);
|
||||
CubicOp(p1, p2, p, rel);
|
||||
break;
|
||||
case PAINTING_CUBIC_S:
|
||||
case PAINTING_CUBIC_S_REL:
|
||||
sGet(p2, ss);
|
||||
sGet(p, ss);
|
||||
CubicOp(p2, p, rel);
|
||||
break;
|
||||
case PAINTING_ARC:
|
||||
case PAINTING_ARC_REL:
|
||||
sGet(p, ss);
|
||||
sGet(p1, ss);
|
||||
sGet(r, ss);
|
||||
sGet(w, ss);
|
||||
ArcOp(p, p1, r, w, rel);
|
||||
break;
|
||||
case PAINTING_CLOSE:
|
||||
CloseOp();
|
||||
break;
|
||||
case PAINTING_DIV:
|
||||
DivOp();
|
||||
break;
|
||||
case PAINTING_FILL_SOLID:
|
||||
FillOp(sGet<RGBA>(ss));
|
||||
break;
|
||||
case PAINTING_FILL_IMAGE:
|
||||
sGet(m, ss);
|
||||
f = ss.Get();
|
||||
if(ii >= pic.data.GetCount())
|
||||
return;
|
||||
v = pic.data[ii++];
|
||||
if(!v.Is<Image>())
|
||||
return;
|
||||
FillOp((Image)v, m, f);
|
||||
break;
|
||||
case PAINTING_FILL_GRADIENT:
|
||||
sGet(p, ss);
|
||||
sGet(c, ss);
|
||||
sGet(p1, ss);
|
||||
sGet(c1, ss);
|
||||
f = ss.Get();
|
||||
FillOp(p, c, p1, c1, f);
|
||||
break;
|
||||
case PAINTING_FILL_RADIAL:
|
||||
sGet(p, ss);
|
||||
sGet(c, ss);
|
||||
sGet(p1, ss);
|
||||
sGet(r, ss);
|
||||
sGet(c1, ss);
|
||||
f = ss.Get();
|
||||
FillOp(p, c, p1, r, c1, f);
|
||||
break;
|
||||
case PAINTING_STROKE_SOLID:
|
||||
sGet(w, ss);
|
||||
sGet(c, ss);
|
||||
StrokeOp(w, c);
|
||||
break;
|
||||
case PAINTING_STROKE_IMAGE:
|
||||
sGet(w, ss);
|
||||
sGet(m, ss);
|
||||
f = ss.Get();
|
||||
if(ii >= pic.data.GetCount())
|
||||
return;
|
||||
v = pic.data[ii++];
|
||||
if(!v.Is<Image>())
|
||||
return;
|
||||
StrokeOp(w, (Image)v, m, f);
|
||||
break;
|
||||
case PAINTING_STROKE_GRADIENT:
|
||||
sGet(w, ss);
|
||||
sGet(p, ss);
|
||||
sGet(c, ss);
|
||||
sGet(p1, ss);
|
||||
sGet(c1, ss);
|
||||
f = ss.Get();
|
||||
StrokeOp(w, p, c, p1, c1, f);
|
||||
break;
|
||||
case PAINTING_STROKE_RADIAL:
|
||||
sGet(w, ss);
|
||||
sGet(p, ss);
|
||||
sGet(c, ss);
|
||||
sGet(p1, ss);
|
||||
sGet(r, ss);
|
||||
sGet(c1, ss);
|
||||
f = ss.Get();
|
||||
StrokeOp(w, p, c, p1, r, c1, f);
|
||||
break;
|
||||
case PAINTING_CLIP:
|
||||
ClipOp();
|
||||
break;
|
||||
case PAINTING_CHARACTER:
|
||||
sGet(p, ss);
|
||||
ch = ss.Get32();
|
||||
sGet(fnt, ss);
|
||||
CharacterOp(p, ch, fnt);
|
||||
break;
|
||||
case PAINTING_TEXT:
|
||||
{
|
||||
sGet(p, ss);
|
||||
n = ss.Get32();
|
||||
hasdx = ss.Get();
|
||||
sGet(fnt, ss);
|
||||
Buffer<wchar> txt(n);
|
||||
Buffer<double> dx(hasdx * n);
|
||||
for(int i = 0; i < n; i++) {
|
||||
txt[i] = ss.Get32();
|
||||
if(hasdx)
|
||||
sGet(dx[i], ss);
|
||||
}
|
||||
TextOp(p, txt, fnt, n, hasdx ? ~dx : NULL);
|
||||
}
|
||||
break;
|
||||
case PAINTING_COLORSTOP:
|
||||
sGet(r, ss);
|
||||
sGet(c, ss);
|
||||
ColorStopOp(r, c);
|
||||
break;
|
||||
case PAINTING_CLEARSTOPS:
|
||||
ClearStopsOp();
|
||||
break;
|
||||
case PAINTING_OPACITY:
|
||||
OpacityOp(sGet<double>(ss));
|
||||
break;
|
||||
case PAINTING_LINECAP:
|
||||
LineCapOp(ss.Get());
|
||||
break;
|
||||
case PAINTING_LINEJOIN:
|
||||
LineJoinOp(ss.Get());
|
||||
break;
|
||||
case PAINTING_MITERLIMIT:
|
||||
MiterLimitOp(ss.Get());
|
||||
break;
|
||||
case PAINTING_EVENODD:
|
||||
EvenOddOp(ss.Get());
|
||||
break;
|
||||
case PAINTING_DASH:
|
||||
{
|
||||
n = ss.Get32();
|
||||
Vector<double> dash;
|
||||
for(int i = 0; i < n; i++)
|
||||
dash.Add(sGet<double>(ss));
|
||||
r = sGet<double>(ss);
|
||||
DashOp(dash, r);
|
||||
}
|
||||
break;
|
||||
case PAINTING_NOAA:
|
||||
NoAAOp(ss.Get());
|
||||
break;
|
||||
case PAINTING_TRANSFORM:
|
||||
sGet(m, ss);
|
||||
TransformOp(m);
|
||||
break;
|
||||
case PAINTING_BEGIN:
|
||||
BeginOp();
|
||||
break;
|
||||
case PAINTING_END:
|
||||
EndOp();
|
||||
break;
|
||||
case PAINTING_BEGINMASK:
|
||||
BeginMaskOp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PaintImageBufferPaintingFn(ImageBuffer& ib, const Painting& p, Size sz, Point pos, bool noaa)
|
||||
{
|
||||
BufferPainter sw(ib);
|
||||
sw.NoAA(noaa);
|
||||
Sizef psz = p.GetSize();
|
||||
sw.Translate(-pos.x, -pos.y);
|
||||
sw.Scale(sz.cx / psz.cx, sz.cy / psz.cy);
|
||||
sw.Paint(p);
|
||||
}
|
||||
|
||||
void PaintImageBufferDrawingFn(ImageBuffer& ib, const Drawing& iw, bool noaa)
|
||||
{
|
||||
BufferPainter sw(ib);
|
||||
sw.NoAA(noaa);
|
||||
Sizef sz = ib.GetSize();
|
||||
Size isz = iw.GetSize();
|
||||
sw.Scale(sz.cx / isz.cx, sz.cy / isz.cy);
|
||||
sw.DrawDrawing(0, 0, isz.cx, isz.cy, iw);
|
||||
}
|
||||
|
||||
void RegisterPaintingFns__(void (*ig)(ImageBuffer& ib, const Painting& pw, Size sz, Point pos, bool noaa),
|
||||
void (*iw)(ImageBuffer& ib, const Drawing& p, bool noaa));
|
||||
|
||||
|
||||
INITBLOCK
|
||||
{
|
||||
RegisterPaintingFns__(PaintImageBufferPaintingFn, PaintImageBufferDrawingFn);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
@ -362,6 +362,64 @@ Painter& Painter::Dash(const char *dash, double start)
|
|||
return *this;
|
||||
}
|
||||
|
||||
Painter& Painter::Character(double x, double y, int ch, Font fnt)
|
||||
{
|
||||
return Character(Pointf(x, y), ch, fnt);
|
||||
}
|
||||
|
||||
void Painter::TextOp(const Pointf& p, const wchar *text, Font fnt, int n, double *dx)
|
||||
{
|
||||
FontInfo fi = fnt.Info();
|
||||
double x = p.x;
|
||||
while(n) {
|
||||
int ch = *text++;
|
||||
Character(x, p.y, ch, fnt);
|
||||
Div();
|
||||
if(dx)
|
||||
x += *dx++;
|
||||
else
|
||||
x += fi[ch];
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
Painter& Painter::Text(double x, double y, const wchar *text, Font fnt, int n, double *dx)
|
||||
{
|
||||
return Text(Pointf(x, y), text, fnt, n < 0 ? wstrlen(text) : n, dx);
|
||||
}
|
||||
|
||||
Painter& Painter::Text(const Pointf& p, const WString& s, Font fnt, double *dx)
|
||||
{
|
||||
return Text(p, ~s, fnt, s.GetLength(), dx);
|
||||
}
|
||||
|
||||
Painter& Painter::Text(double x, double y, const WString& s, Font fnt, double *dx)
|
||||
{
|
||||
return Text(Pointf(x, y), s, fnt, dx);
|
||||
}
|
||||
|
||||
Painter& Painter::Text(const Pointf& p, const String& s, Font fnt, double *dx)
|
||||
{
|
||||
return Text(p, s.ToWString(), fnt, dx);
|
||||
}
|
||||
|
||||
Painter& Painter::Text(double x, double y, const String& s, Font fnt, double *dx)
|
||||
{
|
||||
return Text(Pointf(x, y), s, fnt, dx);
|
||||
}
|
||||
|
||||
Painter& Painter::Text(const Pointf& p, const char *text, Font fnt, int n, double *dx)
|
||||
{
|
||||
if(n < 0)
|
||||
n = strlen(text);
|
||||
return Text(p, ToUnicode(text, n, CHARSET_DEFAULT), fnt, n, dx);
|
||||
}
|
||||
|
||||
Painter& Painter::Text(double x, double y, const char *text, Font fnt, int n, double *dx)
|
||||
{
|
||||
return Text(Pointf(x, y), text, fnt, n, dx);
|
||||
}
|
||||
|
||||
Painter& Painter::Rectangle(double x, double y, double cx, double cy)
|
||||
{
|
||||
return Move(x, y).RelLine(cx, 0).RelLine(0, cy).RelLine(-cx, 0).Close();
|
||||
|
|
|
|||
|
|
@ -58,7 +58,31 @@ enum {
|
|||
GRADIENT_REFLECT = 2,
|
||||
};
|
||||
|
||||
class Painter {
|
||||
class Painter : public Draw {
|
||||
public:
|
||||
void OffsetOp(Point p);
|
||||
void RectPath(int x, int y, int cx, int cy);
|
||||
void RectPath(const Rect& r);
|
||||
bool ClipOp(const Rect& r);
|
||||
bool ClipoffOp(const Rect& r);
|
||||
bool ExcludeClipOp(const Rect& r);
|
||||
bool IntersectClipOp(const Rect& r);
|
||||
Rect GetClipOp() const;
|
||||
bool IsPaintingOp(const Rect& r) const;
|
||||
void DrawRectOp(int x, int y, int cx, int cy, Color color);
|
||||
void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color);
|
||||
void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color);
|
||||
void DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts,
|
||||
int count_count, int width, Color color, Color doxor);
|
||||
void DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count,
|
||||
const int *subpolygon_counts, int scc,
|
||||
const int *disjunct_polygon_counts, int dpcc, Color color,
|
||||
int width, Color outline, uint64 pattern, Color doxor);
|
||||
void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color);
|
||||
void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor);
|
||||
void DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx);
|
||||
void DrawPaintingOp(const Rect& target, const Painting& p);
|
||||
|
||||
protected:
|
||||
virtual void ClearOp(const RGBA& color) = 0;
|
||||
|
||||
|
|
@ -93,8 +117,9 @@ protected:
|
|||
|
||||
virtual void ClipOp() = 0;
|
||||
|
||||
virtual void CharacterOp(double x, double y, int ch, Font fnt);
|
||||
virtual void TextOp(double x, double y, const wchar *text, Font fnt, int n = -1, double *dx = NULL);
|
||||
virtual void CharacterOp(const Pointf& p, int ch, Font fnt);
|
||||
virtual void TextOp(const Pointf& p, const wchar *text, Font fnt, int n = -1,
|
||||
double *dx = NULL);
|
||||
|
||||
virtual void ColorStopOp(double pos, const RGBA& color) = 0;
|
||||
virtual void ClearStopsOp() = 0;
|
||||
|
|
@ -112,6 +137,8 @@ protected:
|
|||
virtual void BeginOp() = 0;
|
||||
virtual void EndOp() = 0;
|
||||
|
||||
virtual void BeginMaskOp() = 0;
|
||||
|
||||
protected:
|
||||
Pointf ReadPoint(CParser& p);
|
||||
|
||||
|
|
@ -219,15 +246,22 @@ public:
|
|||
|
||||
Painter& Clip();
|
||||
|
||||
Painter& Character(const Pointf& p, int ch, Font fnt);
|
||||
Painter& Character(double x, double y, int ch, Font fnt);
|
||||
Painter& Text(const Pointf& p, const wchar *text, Font fnt, int n = -1, double *dx = NULL);
|
||||
Painter& Text(double x, double y, const wchar *text, Font fnt, int n = -1, double *dx = NULL);
|
||||
Painter& Text(const Pointf& p, const WString& s, Font fnt, double *dx = NULL);
|
||||
Painter& Text(double x, double y, const WString& s, Font fnt, double *dx = NULL);
|
||||
Painter& Text(const Pointf& p, const String& s, Font fnt, double *dx = NULL);
|
||||
Painter& Text(double x, double y, const String& s, Font fnt, double *dx = NULL);
|
||||
Painter& Text(const Pointf& p, const char *text, Font fnt, int n = -1, double *dx = NULL);
|
||||
Painter& Text(double x, double y, const char *text, Font fnt, int n = -1, double *dx = NULL);
|
||||
|
||||
void Begin();
|
||||
void End();
|
||||
|
||||
void BeginMask();
|
||||
|
||||
Painter& ColorStop(double pos, const RGBA& color);
|
||||
Painter& ClearStops();
|
||||
Painter& Opacity(double o);
|
||||
|
|
@ -245,12 +279,15 @@ public:
|
|||
Painter& Scale(double scalex, double scaley);
|
||||
Painter& Scale(double scale);
|
||||
|
||||
void Paint(const Painting& p);
|
||||
|
||||
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"
|
||||
#include "Painting.h"
|
||||
#include "BufferPainter.h"
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -206,3 +206,21 @@ inline void Painter::End()
|
|||
{
|
||||
EndOp();
|
||||
}
|
||||
|
||||
inline void Painter::BeginMask()
|
||||
{
|
||||
BeginMaskOp();
|
||||
}
|
||||
|
||||
inline Painter& Painter::Character(const Pointf& p, int ch, Font fnt)
|
||||
{
|
||||
CharacterOp(p, ch, fnt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
Painter& Painter::Text(const Pointf& p, const wchar *text, Font fnt, int n, double *dx)
|
||||
{
|
||||
TextOp(p, text, fnt, n, dx);
|
||||
return *this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@ file
|
|||
PainterPath.cpp,
|
||||
FontWin32.cpp optimize_speed,
|
||||
FontX11.cpp optimize_speed,
|
||||
Text.cpp,
|
||||
DrawOp.cpp,
|
||||
Painting.h,
|
||||
Painting.cpp,
|
||||
PaintPainting.icpp,
|
||||
BufferPainter.h,
|
||||
Math.cpp,
|
||||
Xform2D.cpp,
|
||||
|
|
@ -20,12 +23,13 @@ file
|
|||
Interpolator.cpp optimize_speed,
|
||||
Rasterizer.cpp optimize_speed,
|
||||
RasterizerClip.cpp optimize_speed,
|
||||
Filler.cpp optimize_speed,
|
||||
Mask.cpp,
|
||||
Path.cpp optimize_speed,
|
||||
Context.cpp,
|
||||
Fillers.h,
|
||||
Fillers.cpp optimize_speed,
|
||||
Render.cpp optimize_speed,
|
||||
Image.cpp optimize_speed,
|
||||
Mask.cpp optimize_speed,
|
||||
Gradient.cpp optimize_speed,
|
||||
RadialGradient.cpp optimize_speed;
|
||||
|
||||
|
|
|
|||
276
uppdev/Painter/Painting.cpp
Normal file
276
uppdev/Painter/Painting.cpp
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
#include "Painter.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void PaintingPainter::ClearOp(const RGBA& color)
|
||||
{
|
||||
Put(PAINTING_CLEAR);
|
||||
Put(color);
|
||||
}
|
||||
|
||||
void PaintingPainter::MoveOp(const Pointf& p, bool rel)
|
||||
{
|
||||
Put(PAINTING_MOVE + rel);
|
||||
Putf(p);
|
||||
}
|
||||
|
||||
void PaintingPainter::LineOp(const Pointf& p, bool rel)
|
||||
{
|
||||
Put(PAINTING_LINE + rel);
|
||||
Putf(p);
|
||||
}
|
||||
|
||||
void PaintingPainter::QuadraticOp(const Pointf& p1, const Pointf& p, bool rel)
|
||||
{
|
||||
Put(PAINTING_QUADRATIC + rel);
|
||||
Putf(p1);
|
||||
Putf(p);
|
||||
}
|
||||
|
||||
void PaintingPainter::QuadraticOp(const Pointf& p, bool rel)
|
||||
{
|
||||
Put(PAINTING_QUADRATIC_S + rel);
|
||||
Putf(p);
|
||||
}
|
||||
|
||||
void PaintingPainter::CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel)
|
||||
{
|
||||
Put(PAINTING_CUBIC + rel);
|
||||
Putf(p1);
|
||||
Putf(p2);
|
||||
Putf(p);
|
||||
}
|
||||
|
||||
void PaintingPainter::CubicOp(const Pointf& p2, const Pointf& p, bool rel)
|
||||
{
|
||||
Put(PAINTING_CUBIC_S + rel);
|
||||
Putf(p2);
|
||||
Putf(p);
|
||||
}
|
||||
|
||||
void PaintingPainter::ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel)
|
||||
{
|
||||
Put(PAINTING_ARC + rel);
|
||||
Putf(c);
|
||||
Putf(r);
|
||||
Putf(angle);
|
||||
Putf(sweep);
|
||||
}
|
||||
|
||||
void PaintingPainter::CloseOp()
|
||||
{
|
||||
Put(PAINTING_CLOSE);
|
||||
}
|
||||
|
||||
void PaintingPainter::DivOp()
|
||||
{
|
||||
Put(PAINTING_DIV);
|
||||
}
|
||||
|
||||
void PaintingPainter::FillOp(const RGBA& color)
|
||||
{
|
||||
Put(PAINTING_FILL_SOLID);
|
||||
Put(color);
|
||||
}
|
||||
|
||||
void PaintingPainter::FillOp(const Image& image, const Xform2D& transsrc, dword flags)
|
||||
{
|
||||
Put(PAINTING_FILL_IMAGE);
|
||||
Putf(transsrc);
|
||||
Put(flags);
|
||||
data.Add(image);
|
||||
}
|
||||
|
||||
void PaintingPainter::FillOp(const Pointf& p1, const RGBA& color1, const Pointf& p2,
|
||||
const RGBA& color2, int style)
|
||||
{
|
||||
Put(PAINTING_FILL_GRADIENT);
|
||||
Putf(p1);
|
||||
Put(color1);
|
||||
Putf(p2);
|
||||
Put(color2);
|
||||
Put(style);
|
||||
}
|
||||
|
||||
void PaintingPainter::FillOp(const Pointf& f, const RGBA& color1,
|
||||
const Pointf& p, double r, const RGBA& color2, int style)
|
||||
{
|
||||
Put(PAINTING_FILL_RADIAL);
|
||||
Putf(f);
|
||||
Put(color1);
|
||||
Putf(p);
|
||||
Putf(r);
|
||||
Put(color2);
|
||||
Put(style);
|
||||
}
|
||||
|
||||
void PaintingPainter::StrokeOp(double width, const RGBA& color)
|
||||
{
|
||||
Put(PAINTING_STROKE_SOLID);
|
||||
Putf(width);
|
||||
Put(color);
|
||||
}
|
||||
|
||||
void PaintingPainter::StrokeOp(double width, const Image& image,
|
||||
const Xform2D& transsrc, dword flags)
|
||||
{
|
||||
Put(PAINTING_STROKE_IMAGE);
|
||||
Putf(width);
|
||||
Putf(transsrc);
|
||||
Put(flags);
|
||||
data.Add(image);
|
||||
}
|
||||
|
||||
void PaintingPainter::StrokeOp(double width, const Pointf& p1, const RGBA& color1,
|
||||
const Pointf& p2, const RGBA& color2, int style)
|
||||
{
|
||||
Put(PAINTING_STROKE_GRADIENT);
|
||||
Putf(width);
|
||||
Putf(p1);
|
||||
Put(color1);
|
||||
Putf(p2);
|
||||
Put(color2);
|
||||
Put(style);
|
||||
}
|
||||
|
||||
void PaintingPainter::StrokeOp(double width, const Pointf& f,
|
||||
const RGBA& color1, const Pointf& p, double r,
|
||||
const RGBA& color2, int style)
|
||||
{
|
||||
Put(PAINTING_STROKE_RADIAL);
|
||||
Putf(width);
|
||||
Putf(f);
|
||||
Put(color1);
|
||||
Putf(p);
|
||||
Putf(r);
|
||||
Put(color2);
|
||||
Put(style);
|
||||
}
|
||||
|
||||
void PaintingPainter::ClipOp()
|
||||
{
|
||||
Put(PAINTING_CLIP);
|
||||
}
|
||||
|
||||
void PaintingPainter::CharacterOp(const Pointf& p, int ch, Font fnt)
|
||||
{
|
||||
Put(PAINTING_CHARACTER);
|
||||
Putf(p);
|
||||
Put32(ch);
|
||||
Put(fnt);
|
||||
}
|
||||
|
||||
void PaintingPainter::TextOp(const Pointf& p, const wchar *text, Font fnt, int n, double *dx)
|
||||
{
|
||||
Put(PAINTING_TEXT);
|
||||
Putf(p);
|
||||
Put32(n);
|
||||
Put((bool)dx);
|
||||
Put(fnt);
|
||||
for(int i = 0; i < n; i++) {
|
||||
Put32(text[i]);
|
||||
if(dx)
|
||||
Putf(dx[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void PaintingPainter::ColorStopOp(double pos, const RGBA& color)
|
||||
{
|
||||
Put(PAINTING_COLORSTOP);
|
||||
Putf(pos);
|
||||
Put(color);
|
||||
}
|
||||
|
||||
void PaintingPainter::ClearStopsOp()
|
||||
{
|
||||
Put(PAINTING_CLEARSTOPS);
|
||||
}
|
||||
|
||||
void PaintingPainter::OpacityOp(double o)
|
||||
{
|
||||
Put(PAINTING_OPACITY);
|
||||
Putf(o);
|
||||
}
|
||||
|
||||
void PaintingPainter::LineCapOp(int linecap)
|
||||
{
|
||||
Put(PAINTING_LINECAP);
|
||||
Put(linecap);
|
||||
}
|
||||
|
||||
void PaintingPainter::LineJoinOp(int linejoin)
|
||||
{
|
||||
Put(PAINTING_LINEJOIN);
|
||||
Put(linejoin);
|
||||
}
|
||||
|
||||
void PaintingPainter::MiterLimitOp(double l)
|
||||
{
|
||||
Put(PAINTING_MITERLIMIT);
|
||||
Putf(l);
|
||||
}
|
||||
|
||||
void PaintingPainter::EvenOddOp(bool evenodd)
|
||||
{
|
||||
Put(PAINTING_EVENODD);
|
||||
Put(evenodd);
|
||||
}
|
||||
|
||||
void PaintingPainter::DashOp(const Vector<double>& dash, double start)
|
||||
{
|
||||
Put(PAINTING_DASH);
|
||||
Put32(dash.GetCount());
|
||||
for(int i = 0; i < dash.GetCount(); i++)
|
||||
Putf(dash[i]);
|
||||
Putf(start);
|
||||
}
|
||||
|
||||
void PaintingPainter::NoAAOp(bool noaa)
|
||||
{
|
||||
Put(PAINTING_NOAA);
|
||||
Put(noaa);
|
||||
}
|
||||
|
||||
void PaintingPainter::TransformOp(const Xform2D& m)
|
||||
{
|
||||
Put(PAINTING_TRANSFORM);
|
||||
Putf(m);
|
||||
}
|
||||
|
||||
void PaintingPainter::BeginOp()
|
||||
{
|
||||
Put(PAINTING_BEGIN);
|
||||
}
|
||||
|
||||
void PaintingPainter::EndOp()
|
||||
{
|
||||
Put(PAINTING_END);
|
||||
}
|
||||
|
||||
void PaintingPainter::BeginMaskOp()
|
||||
{
|
||||
Put(PAINTING_BEGINMASK);
|
||||
}
|
||||
|
||||
Painting PaintingPainter::GetResult()
|
||||
{
|
||||
Painting p;
|
||||
p.cmd = cmd.GetResult();
|
||||
p.data = data;
|
||||
p.size = size;
|
||||
return p;
|
||||
}
|
||||
|
||||
void PaintingPainter::Create(double cx, double cy)
|
||||
{
|
||||
cmd.Create();
|
||||
size.cx = cx;
|
||||
size.cy = cy;
|
||||
}
|
||||
|
||||
void PaintingPainter::Create(Sizef sz)
|
||||
{
|
||||
Create(sz.cx, sz.cy);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
133
uppdev/Painter/Painting.h
Normal file
133
uppdev/Painter/Painting.h
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
enum {
|
||||
PAINTING_CLEAR,
|
||||
|
||||
PAINTING_MOVE = 4,
|
||||
PAINTING_MOVE_REL,
|
||||
PAINTING_LINE,
|
||||
PAINTING_LINE_REL,
|
||||
PAINTING_QUADRATIC,
|
||||
PAINTING_QUADRATIC_REL,
|
||||
PAINTING_QUADRATIC_S,
|
||||
PAINTING_QUADRATIC_S_REL,
|
||||
PAINTING_CUBIC,
|
||||
PAINTING_CUBIC_REL,
|
||||
PAINTING_CUBIC_S,
|
||||
PAINTING_CUBIC_S_REL,
|
||||
PAINTING_ARC,
|
||||
PAINTING_ARC_REL,
|
||||
PAINTING_CLOSE,
|
||||
PAINTING_DIV,
|
||||
|
||||
PAINTING_FILL_SOLID,
|
||||
PAINTING_FILL_IMAGE,
|
||||
PAINTING_FILL_GRADIENT,
|
||||
PAINTING_FILL_RADIAL,
|
||||
|
||||
PAINTING_STROKE_SOLID,
|
||||
PAINTING_STROKE_IMAGE,
|
||||
PAINTING_STROKE_GRADIENT,
|
||||
PAINTING_STROKE_RADIAL,
|
||||
|
||||
PAINTING_CLIP,
|
||||
|
||||
PAINTING_CHARACTER,
|
||||
PAINTING_TEXT,
|
||||
|
||||
PAINTING_COLORSTOP,
|
||||
PAINTING_CLEARSTOPS,
|
||||
PAINTING_OPACITY,
|
||||
PAINTING_LINECAP,
|
||||
PAINTING_LINEJOIN,
|
||||
PAINTING_MITERLIMIT,
|
||||
PAINTING_EVENODD,
|
||||
PAINTING_DASH,
|
||||
PAINTING_NOAA,
|
||||
|
||||
PAINTING_TRANSFORM,
|
||||
PAINTING_BEGIN,
|
||||
PAINTING_END,
|
||||
PAINTING_BEGINMASK,
|
||||
};
|
||||
|
||||
class PaintingPainter : public Painter {
|
||||
StringStream cmd;
|
||||
ValueArray data;
|
||||
Sizef size;
|
||||
|
||||
void Put(int c) { cmd.Put(c); }
|
||||
void Put32(int c) { cmd.Put32(c); }
|
||||
void Put(const RGBA& c) { cmd.Put(&c, sizeof(RGBA)); }
|
||||
void Putf(const double& d) { cmd.Put(&d, sizeof(double)); }
|
||||
void Putf(const Pointf& p) { cmd.Put(&p, sizeof(p)); }
|
||||
void Putf(const Xform2D& m) { cmd.Put(&m, sizeof(m)); }
|
||||
void Put(const Font& f) { cmd.Put(&f, sizeof(Font)); }
|
||||
|
||||
protected:
|
||||
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 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 CharacterOp(const Pointf& p, int ch, Font fnt);
|
||||
virtual void TextOp(const Pointf& p, const wchar *text, Font fnt, int n = -1,
|
||||
double *dx = NULL);
|
||||
|
||||
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 NoAAOp(bool noaa);
|
||||
|
||||
virtual void TransformOp(const Xform2D& m);
|
||||
|
||||
virtual void BeginOp();
|
||||
virtual void EndOp();
|
||||
|
||||
virtual void BeginMaskOp();
|
||||
|
||||
public:
|
||||
Painting GetResult();
|
||||
operator Painting() { return GetResult(); }
|
||||
|
||||
void Create(double cx, double cy);
|
||||
void Create(Sizef sz);
|
||||
|
||||
Sizef GetSize() const { return size; }
|
||||
|
||||
PaintingPainter() {}
|
||||
PaintingPainter(double cx, double cy) { Create(cx, cy); }
|
||||
PaintingPainter(Sizef sz) { Create(sz); }
|
||||
};
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
#include "Painter.h"
|
||||
|
||||
// The genesis of this code can be dated back to LibART
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "Painter.h"
|
||||
#include "Fillers.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
#include "Painter.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void Painter::TextOp(double x, double y, const wchar *text, Font fnt, int n, double *dx)
|
||||
{
|
||||
FontInfo fi = fnt.Info();
|
||||
if(n < 0)
|
||||
n = wstrlen(text);
|
||||
while(n) {
|
||||
int ch = *text++;
|
||||
Character(x, y, ch, fnt);
|
||||
Div();
|
||||
if(dx)
|
||||
x += *dx++;
|
||||
else
|
||||
x += fi[ch];
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
Painter& Painter::Character(double x, double y, int ch, Font fnt)
|
||||
{
|
||||
CharacterOp(x, y, ch, fnt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Painter& Painter::Text(double x, double y, const wchar *text, Font fnt, int n, double *dx)
|
||||
{
|
||||
TextOp(x, y, text, fnt, n, dx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Painter& Painter::Text(double x, double y, const WString& s, Font fnt, double *dx)
|
||||
{
|
||||
Text(x, y, s, fnt, s.GetLength(), dx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Painter& Painter::Text(double x, double y, const String& s, Font fnt, double *dx)
|
||||
{
|
||||
Text(x, y, s.ToWString(), fnt, dx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Painter& Painter::Text(double x, double y, const char *text, Font fnt, int n, double *dx)
|
||||
{
|
||||
Text(x, y, ToUnicode(text, n < 0 ? strlen(text) : n, CHARSET_DEFAULT), fnt, dx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
@ -2,4 +2,7 @@
|
|||
#define _Painter_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#include "CtrlLib/init"
|
||||
#define BLITZ_INDEX__ F8939D4A0BC2FDAEDB6EE5CF1693AFE34
|
||||
#include "PaintPainting.icpp"
|
||||
#undef BLITZ_INDEX__
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "Examples.h"
|
||||
|
||||
|
||||
#ifndef _DEBUG
|
||||
|
||||
void Big(Painter& sw)
|
||||
{
|
||||
int n = 0;
|
||||
|
|
@ -45,3 +47,5 @@ INITBLOCK {
|
|||
RegisterExample("Really Big Polygon", Big);
|
||||
RegisterExample("Really Big Stroke", BigStroke);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -23,7 +23,7 @@ struct App : TopWindow {
|
|||
FrameBottom< WithCtrlLayout<StaticRect> > ctrl;
|
||||
|
||||
typedef App CLASSNAME;
|
||||
|
||||
|
||||
void DoPaint0(Painter& sw);
|
||||
void DoPaint(Painter& sw);
|
||||
void Print();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#include "Examples.h"
|
||||
|
||||
#if 0
|
||||
|
||||
void MaskBlending(Painter& sw)
|
||||
{
|
||||
const char *txt = "This is just a test of alpha mask blending";
|
||||
|
|
@ -25,5 +23,3 @@ void MaskBlending(Painter& sw)
|
|||
INITBLOCK {
|
||||
RegisterExample("Blending using alpha mask", MaskBlending);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#include "Examples.h"
|
||||
|
||||
#if 0
|
||||
|
||||
void RadialMaskBlending(Painter& sw)
|
||||
{
|
||||
const char *txt = "This is just a test of radial mask blending";
|
||||
|
|
@ -31,5 +29,3 @@ void RadialMaskBlending(Painter& sw)
|
|||
INITBLOCK {
|
||||
RegisterExample("Blending using radial alpha mask", RadialMaskBlending);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#include "Examples.h"
|
||||
|
||||
#if 0
|
||||
|
||||
void RichTextExample(Painter& sw)
|
||||
{
|
||||
const char *qtf =
|
||||
|
|
@ -79,5 +77,3 @@ INITBLOCK
|
|||
{
|
||||
RegisterExample("RichText", RichTextExample);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -40,26 +40,22 @@ void App::DoPaint0(Painter& sw)
|
|||
|
||||
void App::DoPaint(Painter& sw)
|
||||
{
|
||||
#if 0
|
||||
if(ctrl.painting) {
|
||||
PaintingPainter h(2000, 2000);
|
||||
DoPaint0(h);
|
||||
sw.Paint(h);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
DoPaint0(sw);
|
||||
}
|
||||
|
||||
void App::Print()
|
||||
{
|
||||
#if 0
|
||||
PaintingPainter sw(1000, 1000);
|
||||
DoPaint(sw);
|
||||
PrinterJob pb;
|
||||
if(pb.Execute())
|
||||
pb.GetDraw().DrawPainting(0, 0, 4000, 4000, sw);
|
||||
#endif
|
||||
}
|
||||
|
||||
void App::Benchmark()
|
||||
|
|
|
|||
|
|
@ -1,60 +1,60 @@
|
|||
description "PNG image file format U++ encapsulation";
|
||||
|
||||
uses
|
||||
Core,
|
||||
Draw;
|
||||
|
||||
library(!WIN32) png;
|
||||
|
||||
options
|
||||
-DPNG_NO_READ_SHIFT,
|
||||
-DPNG_NO_READ_SWAP,
|
||||
-DPNG_NO_READ_INVERT,
|
||||
-DPNG_NO_READ_DITHER,
|
||||
-DPNG_NO_READ_BACKGROUND,
|
||||
-DPNG_NO_READ_GAMMA,
|
||||
-DPNG_NO_READ_SWAP_ALPHA,
|
||||
-DPNG_NO_READ_INVERT_ALPHA,
|
||||
-DPNG_NO_READ_STRIP_ALPHA,
|
||||
-DPNG_NO_READ_USER_TRANSFORM,
|
||||
-DPNG_NO_READ_RGB_TO_GRAY,
|
||||
-DPNG_NO_PROGRESSIVE_READ,
|
||||
-DPNG_NO_READ_COMPOSITE_NODIV,
|
||||
-DPNG_NO_MNG_FEATURES,
|
||||
-DPNG_NO_READ_EMPTY_PLTE,
|
||||
-DPNG_NO_WRITE_SHIFT,
|
||||
-DPNG_NO_WRITE_PACK,
|
||||
-DPNG_NO_WRITE_SWAP,
|
||||
-DPNG_NO_WRITE_PACKSWAP,
|
||||
-DPNG_NO_WRITE_INVERT,
|
||||
-DPNG_NO_WRITE_FILLER,
|
||||
-DPNG_NO_WRITE_SWAP_ALPHA,
|
||||
-DPNG_NO_WRITE_INVERT_ALPHA,
|
||||
-DPNG_NO_USER_TRANSFORM_PTR,
|
||||
-DPNG_NO_WRITE_EMPTY_PLTE,
|
||||
-DPNG_NO_EASY_ACCESS,
|
||||
-DPNG_NO_READ_bKGD,
|
||||
-DPNG_NO_READ_cHRM,
|
||||
-DPNG_NO_READ_gAMA,
|
||||
-DPNG_NO_READ_iCCP,
|
||||
-DPNG_NO_READ_oFFs,
|
||||
-DPNG_NO_READ_pCAL,
|
||||
-DPNG_NO_READ_sCAL,
|
||||
-DPNG_NO_READ_sBIT,
|
||||
-DPNG_NO_READ_sPLT,
|
||||
-DPNG_NO_READ_sRGB,
|
||||
-DPNG_NO_READ_tIME,
|
||||
-DPNG_NO_READ_zTXt,
|
||||
-DPNG_NO_READ_OPT_PLTE,
|
||||
-DPNG_NO_INFO_IMAGE;
|
||||
|
||||
options(MSC8ARM) "-D_WIN32_WCE -DARM -D_ARM_ -DUNDER_CE -DUNICODE -D_UNICODE";
|
||||
|
||||
file
|
||||
png.h,
|
||||
pnglib.c,
|
||||
pngupp.cpp,
|
||||
pngreg.icpp,
|
||||
Info readonly separator,
|
||||
Copying;
|
||||
|
||||
description "PNG image file format U++ encapsulation";
|
||||
|
||||
uses
|
||||
Core,
|
||||
Draw;
|
||||
|
||||
library(!WIN32) png;
|
||||
|
||||
options
|
||||
-DPNG_NO_READ_SHIFT,
|
||||
-DPNG_NO_READ_SWAP,
|
||||
-DPNG_NO_READ_INVERT,
|
||||
-DPNG_NO_READ_DITHER,
|
||||
-DPNG_NO_READ_BACKGROUND,
|
||||
-DPNG_NO_READ_GAMMA,
|
||||
-DPNG_NO_READ_SWAP_ALPHA,
|
||||
-DPNG_NO_READ_INVERT_ALPHA,
|
||||
-DPNG_NO_READ_STRIP_ALPHA,
|
||||
-DPNG_NO_READ_USER_TRANSFORM,
|
||||
-DPNG_NO_READ_RGB_TO_GRAY,
|
||||
-DPNG_NO_PROGRESSIVE_READ,
|
||||
-DPNG_NO_READ_COMPOSITE_NODIV,
|
||||
-DPNG_NO_MNG_FEATURES,
|
||||
-DPNG_NO_READ_EMPTY_PLTE,
|
||||
-DPNG_NO_WRITE_SHIFT,
|
||||
-DPNG_NO_WRITE_PACK,
|
||||
-DPNG_NO_WRITE_SWAP,
|
||||
-DPNG_NO_WRITE_PACKSWAP,
|
||||
-DPNG_NO_WRITE_INVERT,
|
||||
-DPNG_NO_WRITE_FILLER,
|
||||
-DPNG_NO_WRITE_SWAP_ALPHA,
|
||||
-DPNG_NO_WRITE_INVERT_ALPHA,
|
||||
-DPNG_NO_USER_TRANSFORM_PTR,
|
||||
-DPNG_NO_WRITE_EMPTY_PLTE,
|
||||
-DPNG_NO_EASY_ACCESS,
|
||||
-DPNG_NO_READ_bKGD,
|
||||
-DPNG_NO_READ_cHRM,
|
||||
-DPNG_NO_READ_gAMA,
|
||||
-DPNG_NO_READ_iCCP,
|
||||
-DPNG_NO_READ_oFFs,
|
||||
-DPNG_NO_READ_pCAL,
|
||||
-DPNG_NO_READ_sCAL,
|
||||
-DPNG_NO_READ_sBIT,
|
||||
-DPNG_NO_READ_sPLT,
|
||||
-DPNG_NO_READ_sRGB,
|
||||
-DPNG_NO_READ_tIME,
|
||||
-DPNG_NO_READ_zTXt,
|
||||
-DPNG_NO_READ_OPT_PLTE,
|
||||
-DPNG_NO_INFO_IMAGE;
|
||||
|
||||
options(MSC8ARM) "-D_WIN32_WCE -DARM -D_ARM_ -DUNDER_CE -DUNICODE -D_UNICODE";
|
||||
|
||||
file
|
||||
png.h,
|
||||
pnglib.c,
|
||||
pngupp.cpp,
|
||||
pngreg.icpp,
|
||||
Info readonly separator,
|
||||
Copying;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue