ultimatepp/uppsrc/Painter/PaintPainting.icpp
cxl 30b677638f SvgArc support
git-svn-id: svn://ultimatepp.org/upp/trunk@863 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2009-02-14 20:21:26 +00:00

270 lines
5.4 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;
}
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;
bool large, sweep;
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_SVGARC:
case PAINTING_SVGARC_REL:
sGet(p1, ss);
sGet(r, ss);
sGet(large, ss);
sGet(sweep, ss);
sGet(p, ss);
SvgArcOp(p1, r, large, sweep, p, 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