mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
258 lines
5.3 KiB
Text
258 lines
5.3 KiB
Text
#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;
|
|
}
|
|
|
|
inline
|
|
Pointf sGetPoint(StringStream& ss)
|
|
{
|
|
Pointf p;
|
|
p.x = sGet<double>(ss);
|
|
p.y = sGet<double>(ss);
|
|
return p;
|
|
}
|
|
|
|
void Painter::Paint(const Painting& pic)
|
|
{
|
|
StringStream ss(pic.cmd);
|
|
Pointf p, p1, p2;
|
|
RGBA c, c1;
|
|
Value v;
|
|
int f, ch, n, hasdx;
|
|
Matrix2D 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:
|
|
Clear(sGet<RGBA>(ss));
|
|
break;
|
|
case PAINTING_MOVE:
|
|
case PAINTING_MOVE_REL:
|
|
p = sGetPoint(ss);
|
|
Move(p.x, p.y, rel);
|
|
break;
|
|
case PAINTING_LINE:
|
|
case PAINTING_LINE_REL:
|
|
p = sGetPoint(ss);
|
|
Line(p.x, p.y, rel);
|
|
break;
|
|
case PAINTING_QUADRATIC:
|
|
case PAINTING_QUADRATIC_REL:
|
|
p1 = sGetPoint(ss);
|
|
p = sGetPoint(ss);
|
|
Quadratic(p1.x, p1.y, p.x, p.y, rel);
|
|
break;
|
|
case PAINTING_QUADRATIC_S:
|
|
case PAINTING_QUADRATIC_S_REL:
|
|
p = sGetPoint(ss);
|
|
Quadratic(p.x, p.y, rel);
|
|
break;
|
|
case PAINTING_CUBIC:
|
|
case PAINTING_CUBIC_REL:
|
|
p1 = sGetPoint(ss);
|
|
p2 = sGetPoint(ss);
|
|
p = sGetPoint(ss);
|
|
Cubic(p1.x, p1.y, p2.x, p2.y, p.x, p.y, rel);
|
|
break;
|
|
case PAINTING_CUBIC_S:
|
|
case PAINTING_CUBIC_S_REL:
|
|
p2 = sGetPoint(ss);
|
|
p = sGetPoint(ss);
|
|
Cubic(p2.x, p2.y, p.x, p.y, rel);
|
|
break;
|
|
case PAINTING_CLOSE:
|
|
Close();
|
|
break;
|
|
case PAINTING_FILL_SOLID:
|
|
Fill(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;
|
|
Fill((Image)v, m, f);
|
|
break;
|
|
case PAINTING_FILL_GRADIENT:
|
|
p = sGetPoint(ss);
|
|
sGet(c, ss);
|
|
p1 = sGetPoint(ss);
|
|
sGet(c1, ss);
|
|
f = ss.Get();
|
|
Fill(p.x, p.y, c, p1.x, p1.y, c1, f);
|
|
break;
|
|
case PAINTING_FILL_RADIAL:
|
|
p = sGetPoint(ss);
|
|
sGet(c, ss);
|
|
p1 = sGetPoint(ss);
|
|
sGet(r, ss);
|
|
sGet(c1, ss);
|
|
f = ss.Get();
|
|
Fill(p.x, p.y, c, p1.x, p1.y, r, c1, f);
|
|
break;
|
|
case PAINTING_STROKE_SOLID:
|
|
sGet(w, ss);
|
|
sGet(c, ss);
|
|
Stroke(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;
|
|
Stroke(w, (Image)v, m, f);
|
|
break;
|
|
case PAINTING_STROKE_GRADIENT:
|
|
sGet(w, ss);
|
|
p = sGetPoint(ss);
|
|
sGet(c, ss);
|
|
p1 = sGetPoint(ss);
|
|
sGet(c1, ss);
|
|
f = ss.Get();
|
|
Stroke(w, p.x, p.y, c, p1.x, p1.y, c1, f);
|
|
break;
|
|
case PAINTING_STROKE_RADIAL:
|
|
sGet(w, ss);
|
|
p = sGetPoint(ss);
|
|
sGet(c, ss);
|
|
p1 = sGetPoint(ss);
|
|
sGet(r, ss);
|
|
sGet(c1, ss);
|
|
f = ss.Get();
|
|
Stroke(w, p.x, p.y, c, p1.x, p1.y, r, c1, f);
|
|
break;
|
|
case PAINTING_CLIP:
|
|
Clip();
|
|
break;
|
|
case PAINTING_CHARACTER:
|
|
p = sGetPoint(ss);
|
|
ch = ss.Get32();
|
|
sGet(fnt, ss);
|
|
Character(p.x, p.y, ch, fnt);
|
|
break;
|
|
case PAINTING_TEXT:
|
|
{
|
|
p = sGetPoint(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);
|
|
}
|
|
Text(p.x, p.y, txt, fnt, n, hasdx ? ~dx : NULL);
|
|
}
|
|
break;
|
|
case PAINTING_COLORSTOP:
|
|
sGet(r, ss);
|
|
sGet(c, ss);
|
|
ColorStop(r, c);
|
|
break;
|
|
case PAINTING_CLEARSTOPS:
|
|
ClearStops();
|
|
break;
|
|
case PAINTING_OPACITY:
|
|
Opacity(sGet<double>(ss));
|
|
break;
|
|
case PAINTING_LINECAP:
|
|
LineCap(ss.Get());
|
|
break;
|
|
case PAINTING_LINEJOIN:
|
|
LineJoin(ss.Get());
|
|
break;
|
|
case PAINTING_MITERLIMIT:
|
|
MiterLimit(ss.Get());
|
|
break;
|
|
case PAINTING_EVENODD:
|
|
EvenOdd(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);
|
|
Dash(dash, r);
|
|
}
|
|
break;
|
|
case PAINTING_NOAA:
|
|
NoAA(ss.Get());
|
|
break;
|
|
case PAINTING_TRANSFORM:
|
|
sGet(m, ss);
|
|
Transform(m);
|
|
break;
|
|
case PAINTING_BEGIN:
|
|
Begin();
|
|
break;
|
|
case PAINTING_END:
|
|
End();
|
|
break;
|
|
case PAINTING_BEGINMASK:
|
|
BeginMask();
|
|
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
|