Painter: SVG related issues

git-svn-id: svn://ultimatepp.org/upp/trunk@7988 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2014-12-21 19:08:48 +00:00
parent 42eb0f3997
commit 83efc68a28
10 changed files with 136 additions and 21 deletions

View file

@ -229,6 +229,8 @@ protected:
virtual void FillOp(const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style);
virtual void FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2,
const Xform2D& transsrc, int style);
virtual void StrokeOp(double width, const RGBA& rgba);
virtual void StrokeOp(double width, const Image& image, const Xform2D& transsrc,
@ -242,6 +244,9 @@ protected:
virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style);
virtual void StrokeOp(double width, const Pointf& f,
const RGBA& color1, const RGBA& color2,
const Xform2D& transsrc, int style);
virtual void ClipOp();
@ -351,7 +356,10 @@ private:
void RenderImage(double width, const Image& image, const Xform2D& transsrc,
dword flags);
void RenderRadial(double width, const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2, int style);
const Pointf& c, double r, const RGBA& color2,
const Xform2D& m, int style);
void RenderRadial(double width, const Pointf& f, const RGBA& color1, const RGBA& color2,
const Xform2D& transsrc, int style);
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);

View file

@ -48,7 +48,7 @@ void BufferPainter::FillOp(const Pointf& p1, const RGBA& color1, const Pointf& p
{
Gradient(color1, color2, p1, p2);
Fill(gradient, p1, p2,
FILL_VPAD |
FILL_VPAD | (style & FILL_FAST) |
(style == GRADIENT_PAD ? FILL_HPAD : style == GRADIENT_REPEAT
? FILL_HREPEAT : FILL_HREFLECT));
}
@ -56,8 +56,8 @@ void BufferPainter::FillOp(const Pointf& p1, const RGBA& color1, const Pointf& p
void BufferPainter::FillOp(const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style)
{
MakeGradient(color1, color2, 500);
Fill(gradient, transsrc * Xform2D::Scale(1.0 / 500),
FILL_VPAD |
Fill(gradient, Xform2D::Scale(1.0 / 500) * transsrc,
FILL_VPAD | (style & FILL_FAST) |
(style == GRADIENT_PAD ? FILL_HPAD : style == GRADIENT_REPEAT
? FILL_HREPEAT : FILL_HREFLECT));
}
@ -66,7 +66,7 @@ void BufferPainter::StrokeOp(double width, const Pointf& p1, const RGBA& color1,
{
Gradient(color1, color2, p1, p2);
Stroke(width, gradient, p1, p2,
FILL_VPAD |
FILL_VPAD | (style & FILL_FAST) |
(style == GRADIENT_PAD ? FILL_HPAD : style == GRADIENT_REPEAT
? FILL_HREPEAT : FILL_HREFLECT));
}
@ -74,8 +74,8 @@ void BufferPainter::StrokeOp(double width, const Pointf& p1, const RGBA& color1,
void BufferPainter::StrokeOp(double width, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style)
{
MakeGradient(color1, color2, 500);
Stroke(width, gradient, transsrc * Xform2D::Scale(1.0 / 500),
FILL_VPAD |
Stroke(width, gradient, Xform2D::Scale(1.0 / 500) * transsrc,
FILL_VPAD | (style & FILL_FAST) |
(style == GRADIENT_PAD ? FILL_HPAD : style == GRADIENT_REPEAT
? FILL_HREPEAT : FILL_HREFLECT));
}

View file

@ -34,14 +34,15 @@ Image DownScale(const Image& img, int nx, int ny)
ASSERT(nx > 0 && ny > 0);
Size ssz = img.GetSize();
Size tsz = Size((ssz.cx + nx - 1) / nx, (ssz.cy + ny - 1) / ny);
int div = nx * ny;
Buffer<RGBAV> b(tsz.cx);
ImageBuffer ib(tsz);
RGBA *it = ~ib;
int scx0 = ssz.cx / nx * nx;
Buffer<int> div(tsz.cx);
for(int yy = 0; yy < ssz.cy; yy += ny) {
for(int i = 0; i < tsz.cx; i++)
b[i].Clear();
memset(div, 0, tsz.cx * sizeof(int));
for(int yi = 0; yi < ny; yi++) {
int y = yy + yi;
if(y < ssz.cy) {
@ -49,18 +50,25 @@ Image DownScale(const Image& img, int nx, int ny)
const RGBA *e = s + scx0;
const RGBA *e2 = s + ssz.cx;
RGBAV *t = ~b;
int *dv = div;
while(s < e) {
for(int n = nx; n--;)
for(int n = nx; n--;) {
t->Put(*s++);
(*dv)++;
}
t++;
dv++;
}
while(s < e2)
while(s < e2) {
t->Put(*s++);
(*dv)++;
}
}
}
const RGBAV *s = ~b;
const int *dv = div;
for(int x = 0; x < tsz.cx; x++)
*it++ = (s++)->Get(div);
*it++ = (s++)->Get(*dv++);
}
return ib;
}

View file

@ -123,6 +123,14 @@ void Painter::Paint(const Painting& pic)
f = ss.Get();
FillOp(c, c1, m, f);
break;
case PAINTING_FILL_RADIAL_X:
sGet(p1, ss);
sGet(c, ss);
sGet(c1, ss);
sGet(m, ss);
f = ss.Get();
FillOp(p1, c, c1, m, f);
break;
case PAINTING_FILL_RADIAL:
sGet(p, ss);
sGet(c, ss);
@ -166,6 +174,16 @@ void Painter::Paint(const Painting& pic)
FillOp(c, c1, m, f);
StrokeOp(w, c, c1, m, f);
break;
case PAINTING_STROKE_RADIAL_X:
sGet(w, ss);
sGet(p1, ss);
sGet(c, ss);
sGet(c1, ss);
sGet(m, ss);
f = ss.Get();
FillOp(c, c1, m, f);
StrokeOp(w, p1, c, c1, m, f);
break;
case PAINTING_STROKE_RADIAL:
sGet(w, ss);
sGet(p, ss);

View file

@ -383,6 +383,18 @@ Painter& Painter::Fill(double x, double y, const RGBA& color1, double r, const R
return Fill(Pointf(x, y), color1, r, color2, style);
}
Painter& Painter::Fill(const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style)
{
FillOp(f, color1, color2, transsrc, style);
return *this;
}
Painter& Painter::Stroke(double width, const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style)
{
StrokeOp(width, f, color1, color2, transsrc, style);
return *this;
}
Painter& Painter::Translate(double x, double y)
{
Transform(Xform2D::Translation(x, y));
@ -534,13 +546,18 @@ Painter& Painter::Rectangle(double x, double y, double cx, double cy)
Painter& Painter::RoundedRectangle(double x, double y, double cx, double cy, double r)
{
ASSERT(r >= 0);
return RoundedRectangle(x, y, cx, cy, r, r);
}
Painter& Painter::RoundedRectangle(double x, double y, double cx, double cy, double rx, double ry)
{
ASSERT(rx >= 0 && ry >= 0);
if (cx < 0) { x += cx; cx = -cx;}
if (cy < 0) { y += cy; cy = -cy;}
Move(x + r, y).Arc(x + r, y + r, r, r, -M_PI / 2, -M_PI / 2)
.Line(x, y + cy - r).Arc(x + r, y + cy - r, r, r, M_PI, -M_PI / 2)
.Line(x + cx - r, y + cy).Arc(x + cx - r, y + cy - r, r, r, M_PI / 2, -M_PI / 2)
.Line(x + cx, y + r).Arc(x + cx - r, y + r, r, r, 0, -M_PI / 2).Line(x + r, y);
Move(x + rx, y).Arc(x + rx, y + ry, rx, ry, -M_PI / 2, -M_PI / 2)
.Line(x, y + cy - ry).Arc(x + rx, y + cy - ry, rx, ry, M_PI, -M_PI / 2)
.Line(x + cx - rx, y + cy).Arc(x + cx - rx, y + cy - ry, rx, ry, M_PI / 2, -M_PI / 2)
.Line(x + cx, y + ry).Arc(x + cx - rx, y + ry, rx, ry, 0, -M_PI / 2).Line(x + rx, y);
return *this;
}
@ -570,11 +587,13 @@ void NilPainter::FillOp(const Image& image, const Xform2D& transsrc, dword flags
void NilPainter::FillOp(const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) {}
void NilPainter::FillOp(const Pointf& p1, const RGBA& color1, const Pointf& p2, const RGBA& color2, int style) {}
void NilPainter::FillOp(const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style) {}
void NilPainter::FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) {}
void NilPainter::StrokeOp(double width, const RGBA& rgba) {}
void NilPainter::StrokeOp(double width, const Image& image, const Xform2D& transsrc, dword flags) {}
void NilPainter::StrokeOp(double width, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) {}
void NilPainter::StrokeOp(double width, const Pointf& p1, const RGBA& color1, const Pointf& p2, const RGBA& color2, int style) {}
void NilPainter::StrokeOp(double width, const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style) {}
void NilPainter::StrokeOp(double width, const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) {}
void NilPainter::ClipOp() {}
void NilPainter::CharacterOp(const Pointf& p, int ch, Font fnt) {}
void NilPainter::TextOp(const Pointf& p, const wchar *text, Font fnt, int n, double *dx) {}

View file

@ -109,6 +109,8 @@ protected:
int style) = 0;
virtual void FillOp(const RGBA& color1, const RGBA& color2, const Xform2D& transsrc,
int style) = 0;
virtual void FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2,
const Xform2D& transsrc, int style) = 0;
virtual void StrokeOp(double width, const RGBA& rgba) = 0;
virtual void StrokeOp(double width, const Image& image, const Xform2D& transsrc,
@ -121,6 +123,9 @@ protected:
virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style) = 0;
virtual void StrokeOp(double width, const Pointf& f,
const RGBA& color1, const RGBA& color2,
const Xform2D& transsrc, int style) = 0;
virtual void ClipOp() = 0;
@ -251,6 +256,8 @@ public:
double r, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Fill(double x, double y, const RGBA& color1,
double r, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Fill(const Pointf& f, const RGBA& color1, const RGBA& color2,
const Xform2D& transsrc, int style = GRADIENT_PAD);
Painter& Stroke(double width, const RGBA& color);
Painter& Stroke(double width, const Image& image, const Xform2D& transsrc, dword flags = 0);
@ -272,6 +279,9 @@ public:
double r, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Stroke(double width, double x, double y, const RGBA& color1,
double r, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Stroke(double width, const Pointf& f,
const RGBA& color1, const RGBA& color2,
const Xform2D& transsrc, int style = GRADIENT_PAD);
Painter& Clip();
@ -314,6 +324,7 @@ public:
Painter& Rectangle(double x, double y, double cx, double cy);
Painter& RoundedRectangle(double x, double y, double cx, double cy, double r);
Painter& RoundedRectangle(double x, double y, double cx, double cy, double r1, double r2);
Painter& Ellipse(double x, double y, double rx, double ry);
Painter& Circle(double x, double y, double r);
@ -378,6 +389,8 @@ protected:
virtual void FillOp(const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style);
virtual void FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2,
const Xform2D& transsrc, int style);
virtual void StrokeOp(double width, const RGBA& rgba);
virtual void StrokeOp(double width, const Image& image, const Xform2D& transsrc,
@ -391,6 +404,9 @@ protected:
virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style);
virtual void StrokeOp(double width, const Pointf& f,
const RGBA& color1, const RGBA& color2,
const Xform2D& transsrc, int style);
virtual void ClipOp();

View file

@ -111,6 +111,29 @@ void PaintingPainter::FillOp(const RGBA& color1, const RGBA& color2, const Xform
Put(style);
}
void PaintingPainter::FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style)
{
Put(PAINTING_FILL_RADIAL_X);
Putf(f);
Put(color1);
Put(color2);
Putf(transsrc);
Put(style);
}
void PaintingPainter::StrokeOp(double width, const Pointf& f, const RGBA& color1,
const RGBA& color2, const Xform2D& transsrc, int style)
{
Put(PAINTING_FILL_RADIAL_X);
Putf(width);
Putf(f);
Put(color1);
Put(color2);
Putf(transsrc);
Put(style);
}
void PaintingPainter::FillOp(const Pointf& f, const RGBA& color1,
const Pointf& p, double r, const RGBA& color2, int style)
{

View file

@ -54,6 +54,9 @@ enum {
PAINTING_FILL_GRADIENT_X,
PAINTING_STROKE_GRADIENT_X,
PAINTING_FILL_RADIAL_X,
PAINTING_STROKE_RADIAL_X,
};
class PaintingPainter : public Painter {
@ -94,6 +97,8 @@ protected:
virtual void FillOp(const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style);
virtual void FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2,
const Xform2D& transsrc, int style);
virtual void StrokeOp(double width, const RGBA& rgba);
virtual void StrokeOp(double width, const Image& image, const Xform2D& transsrc,
@ -106,6 +111,9 @@ protected:
virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style);
virtual void StrokeOp(double width, const Pointf& f,
const RGBA& color1, const RGBA& color2,
const Xform2D& transsrc, int style);
virtual void ClipOp();

View file

@ -55,10 +55,10 @@ struct PainterRadialSpan : SpanSource {
};
void BufferPainter::RenderRadial(double width, const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2, int style)
const Pointf& c, double r, const RGBA& color2,
const Xform2D& m, int style)
{
PainterRadialSpan sg;
Xform2D m = pathattr.mtx;
sg.interpolator.Set(Inverse(m));
sg.style = style;
sg.Set(c.x, c.y, r, f.x, f.y);
@ -69,12 +69,28 @@ void BufferPainter::RenderRadial(double width, const Pointf& f, const RGBA& colo
void BufferPainter::FillOp(const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style)
{
RenderRadial(-1, f, color1, c, r, color2, style);
RenderRadial(-1, f, color1, c, r, color2, pathattr.mtx, style);
}
void BufferPainter::StrokeOp(double width, const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style)
{
RenderRadial(width, f, color1, c, r, color2, style);
RenderRadial(width, f, color1, c, r, color2, pathattr.mtx, style);
}
void BufferPainter::RenderRadial(double width, const Pointf& f, const RGBA& color1,
const RGBA& color2, const Xform2D& transsrc, int style)
{
RenderRadial(width, f, color1, Pointf(0, 0), 1, color2, transsrc * pathattr.mtx, style);
}
void BufferPainter::FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style)
{
RenderRadial(-1, f, color1, color2, transsrc, style);
}
void BufferPainter::StrokeOp(double width, const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style)
{
RenderRadial(width, f, color1, color2, transsrc, style);
}
END_UPP_NAMESPACE

View file

@ -51,7 +51,6 @@ Xform2D operator*(const Xform2D& a, const Xform2D& b)
Xform2D Xform2D::Translation(double x, double y)
{
Xform2D m;
m.x.x = m.y.y = 1;
m.t = Pointf(x, y);
return m;
}