mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
Painter: Working on subpixel rendering
git-svn-id: svn://ultimatepp.org/upp/trunk@885 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
6189510565
commit
bc032c21d3
11 changed files with 115 additions and 86 deletions
|
|
@ -259,7 +259,6 @@ protected:
|
|||
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);
|
||||
|
||||
|
|
@ -300,10 +299,10 @@ public:
|
|||
int cliplevel;
|
||||
bool hasclip;
|
||||
bool mask;
|
||||
bool noaa;
|
||||
};
|
||||
|
||||
ImageBuffer& ib;
|
||||
int quality;
|
||||
Buffer<int16> subpixel;
|
||||
int render_cx;
|
||||
|
||||
|
|
@ -313,7 +312,6 @@ public:
|
|||
Vector< Buffer<ClipLine> > clip;
|
||||
Array< ImageBuffer > mask;
|
||||
|
||||
|
||||
Image gradient;
|
||||
RGBA gradient1, gradient2;
|
||||
int gradientn;
|
||||
|
|
@ -343,5 +341,5 @@ public:
|
|||
void FinishMask();
|
||||
|
||||
public:
|
||||
BufferPainter(ImageBuffer& ib, bool subpixel = false);
|
||||
BufferPainter(ImageBuffer& ib, int quality = 0);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -73,13 +73,6 @@ void BufferPainter::DashOp(const Vector<double>& dash, double start)
|
|||
}
|
||||
}
|
||||
|
||||
void BufferPainter::NoAAOp(bool noaa)
|
||||
{
|
||||
pathattr.noaa = noaa;
|
||||
if(IsNull(current))
|
||||
attr.noaa = noaa;
|
||||
}
|
||||
|
||||
void BufferPainter::ColorStop0(Attr& a, double pos, const RGBA& color)
|
||||
{
|
||||
pos = minmax(pos, 0.0, 1.0);
|
||||
|
|
@ -105,14 +98,15 @@ void BufferPainter::ClearStopsOp()
|
|||
}
|
||||
}
|
||||
|
||||
BufferPainter::BufferPainter(ImageBuffer& ib, bool subpixel_)
|
||||
BufferPainter::BufferPainter(ImageBuffer& ib, int quality_)
|
||||
: ib(ib),
|
||||
rasterizer(subpixel_ ? 3 * ib.GetWidth() : ib.GetWidth(), ib.GetHeight())
|
||||
quality(quality_),
|
||||
rasterizer(quality_ == QUALITY_SUBPIXEL ? 3 * ib.GetWidth() : ib.GetWidth(), ib.GetHeight())
|
||||
{
|
||||
ClearPath();
|
||||
|
||||
render_cx = ib.GetWidth();
|
||||
if(subpixel_) {
|
||||
if(quality == QUALITY_SUBPIXEL) {
|
||||
render_cx *= 3;
|
||||
subpixel.Alloc(render_cx + 30);
|
||||
}
|
||||
|
|
@ -127,7 +121,6 @@ BufferPainter::BufferPainter(ImageBuffer& ib, bool subpixel_)
|
|||
attr.dash_start = 0.0;
|
||||
attr.opacity = 1.0;
|
||||
attr.mask = false;
|
||||
attr.noaa = false;
|
||||
pathattr = attr;
|
||||
|
||||
gradientn = Null;
|
||||
|
|
|
|||
|
|
@ -3,23 +3,8 @@
|
|||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void SolidFiller::Start(int minx, int maxx)
|
||||
void FillRGBA(RGBA *t, RGBA c, int len)
|
||||
{
|
||||
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;
|
||||
|
|
@ -45,6 +30,26 @@ void SolidFiller::Render(int val, int len)
|
|||
case 2: t[1] = c;
|
||||
case 1: t[0] = c;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
FillRGBA(t, c, len);
|
||||
t += len;
|
||||
}
|
||||
else {
|
||||
|
|
@ -62,12 +67,16 @@ void SolidFiller::Render(int val, int len)
|
|||
void SubpixelFiller::Start(int minx, int maxx)
|
||||
{
|
||||
x = minx / 3;
|
||||
if(x > 0) {
|
||||
begin = sbuffer;
|
||||
x--;
|
||||
}
|
||||
else
|
||||
begin = sbuffer + 3;
|
||||
t += x;
|
||||
v = sbuffer;
|
||||
int n = minx % 3 + 3;
|
||||
while(n--)
|
||||
*v++ = 0;
|
||||
v[0] = v[1] = v[2] = v[3] = v[4] = 0;
|
||||
sbuffer[0] = sbuffer[1] = sbuffer[2] = sbuffer[3] =
|
||||
sbuffer[4] = sbuffer[5] = sbuffer[6] = sbuffer[7] = 0;
|
||||
v = sbuffer + 3 + minx % 3;
|
||||
if(ss) {
|
||||
int xx = maxx / 3;
|
||||
ss->Get(buffer, x, y, xx - x + 2);
|
||||
|
|
@ -75,9 +84,10 @@ void SubpixelFiller::Start(int minx, int maxx)
|
|||
}
|
||||
}
|
||||
|
||||
void SubpixelFiller::Render(int val)
|
||||
void SubpixelFiller::Render(int val) // Optimize: Render0
|
||||
{
|
||||
int h = (7282 * val) >> 16;
|
||||
#if 1
|
||||
int h = val / 9;
|
||||
int h2 = h + h;
|
||||
v[-2] += h;
|
||||
v[-1] += h2;
|
||||
|
|
@ -85,22 +95,65 @@ void SubpixelFiller::Render(int val)
|
|||
v[1] += h2;
|
||||
v[2] += h;
|
||||
v[3] = 0;
|
||||
#else
|
||||
int h = val / 3;
|
||||
v[-1] += h;
|
||||
v[0] += val - h - h;
|
||||
v[1] += h;
|
||||
v[2] = 0;
|
||||
#endif
|
||||
v++;
|
||||
x++;
|
||||
}
|
||||
|
||||
void SubpixelFiller::Render(int val, int len)
|
||||
{
|
||||
/* if(len > 9) {
|
||||
int q = (3333333 - x) % 3;
|
||||
len -= q;
|
||||
while(q--)
|
||||
Render(val);
|
||||
int16 *h = v;
|
||||
Render(val);
|
||||
Render(val);
|
||||
Render(val);
|
||||
v = h;
|
||||
End();
|
||||
q = len / 3 - 1;
|
||||
len -= q * 3;
|
||||
RGBA *e = t + q;
|
||||
while(t < e)
|
||||
AlphaBlendCover8(*t++, ss ? Mul8(*s++, alpha) : color, val);
|
||||
v = sbuffer + 3;
|
||||
v[-2] = v[-1] = v[0] = v[1] = v[2] = 0;
|
||||
x = 0;
|
||||
}*/
|
||||
while(len--)
|
||||
Render(val);
|
||||
}
|
||||
|
||||
void SubpixelFiller::End()
|
||||
{
|
||||
int16 *q = sbuffer + 3;
|
||||
int n = (3333333 - (v - begin)) % 3;
|
||||
while(n--)
|
||||
Render(0);
|
||||
int16 *q = begin;
|
||||
while(q < v) {
|
||||
RGBA c = ss ? Mul8(*s++, alpha) : color;
|
||||
int a, alpha;
|
||||
/* if(c.a == 255) {
|
||||
alpha = 256 - q[0];
|
||||
t->r = (c.r * q[0] >> 8) + (alpha * t->r >> 8);
|
||||
alpha = 256 - q[1];
|
||||
t->g = (c.g * q[1] >> 8) + (alpha * t->g >> 8);
|
||||
alpha = 256 - q[2];
|
||||
t->b = (c.b * q[2] >> 8) + (alpha * t->b >> 8);
|
||||
a = (q[0] + q[1] + q[2]) / 3;
|
||||
a = c.a * (q[0] + q[1] + q[2]) / 3 >> 8;
|
||||
alpha = 256 - (a + (a >> 7));
|
||||
t->a = a + (alpha * t->a >> 8);
|
||||
}
|
||||
else {*/
|
||||
a = c.a * q[0] >> 8;
|
||||
alpha = 256 - (a + (a >> 7));
|
||||
t->r = (c.r * q[0] >> 8) + (alpha * t->r >> 8);
|
||||
|
|
@ -113,6 +166,7 @@ void SubpixelFiller::End()
|
|||
a = c.a * (q[0] + q[1] + q[2]) / 3 >> 8;
|
||||
alpha = 256 - (a + (a >> 7));
|
||||
t->a = a + (alpha * t->a >> 8);
|
||||
// }
|
||||
t++;
|
||||
q += 3;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ struct SpanFiller : Rasterizer::Filler {
|
|||
|
||||
struct SubpixelFiller : Rasterizer::Filler {
|
||||
int16 *sbuffer;
|
||||
int16 *begin;
|
||||
RGBA *t;
|
||||
int16 *v;
|
||||
RGBA *s;
|
||||
|
|
|
|||
|
|
@ -218,9 +218,6 @@ void Painter::Paint(const Painting& pic)
|
|||
DashOp(dash, r);
|
||||
}
|
||||
break;
|
||||
case PAINTING_NOAA:
|
||||
NoAAOp(ss.Get());
|
||||
break;
|
||||
case PAINTING_TRANSFORM:
|
||||
sGet(m, ss);
|
||||
TransformOp(m);
|
||||
|
|
@ -240,8 +237,7 @@ void Painter::Paint(const Painting& pic)
|
|||
|
||||
void PaintImageBufferPaintingFn(ImageBuffer& ib, const Painting& p, Size sz, Point pos, bool noaa)
|
||||
{
|
||||
BufferPainter sw(ib);
|
||||
sw.NoAA(noaa);
|
||||
BufferPainter sw(ib, noaa ? QUALITY_NOAA : QUALITY_ANTIALIASED);
|
||||
Sizef psz = p.GetSize();
|
||||
sw.Translate(-pos.x, -pos.y);
|
||||
sw.Scale(sz.cx / psz.cx, sz.cy / psz.cy);
|
||||
|
|
@ -250,8 +246,7 @@ void PaintImageBufferPaintingFn(ImageBuffer& ib, const Painting& p, Size sz, Poi
|
|||
|
||||
void PaintImageBufferDrawingFn(ImageBuffer& ib, const Drawing& iw, bool noaa)
|
||||
{
|
||||
BufferPainter sw(ib);
|
||||
sw.NoAA(noaa);
|
||||
BufferPainter sw(ib, noaa ? QUALITY_NOAA : QUALITY_ANTIALIASED);
|
||||
Sizef sz = ib.GetSize();
|
||||
Size isz = iw.GetSize();
|
||||
sw.Scale(sz.cx / isz.cx, sz.cy / isz.cy);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,10 @@ enum {
|
|||
GRADIENT_PAD = 0,
|
||||
GRADIENT_REPEAT = 1,
|
||||
GRADIENT_REFLECT = 2,
|
||||
|
||||
QUALITY_NOAA = 0,
|
||||
QUALITY_ANTIALIASED = 1,
|
||||
QUALITY_SUBPIXEL = 2,
|
||||
};
|
||||
|
||||
class Painter : public Draw {
|
||||
|
|
@ -133,7 +137,6 @@ protected:
|
|||
virtual void MiterLimitOp(double l) = 0;
|
||||
virtual void EvenOddOp(bool evenodd) = 0;
|
||||
virtual void DashOp(const Vector<double>& dash, double start = 0) = 0;
|
||||
virtual void NoAAOp(bool noaa) = 0;
|
||||
|
||||
virtual void TransformOp(const Xform2D& m) = 0;
|
||||
|
||||
|
|
@ -290,7 +293,6 @@ public:
|
|||
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 = true);
|
||||
|
||||
Painter& Transform(const Xform2D& m);
|
||||
Painter& Translate(double x, double y);
|
||||
|
|
|
|||
|
|
@ -192,12 +192,6 @@ inline Painter& Painter::Dash(const Vector<double>& dash, double start)
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline Painter& Painter::NoAA(bool noaa)
|
||||
{
|
||||
NoAAOp(noaa);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Painter& Painter::Transform(const Xform2D& m)
|
||||
{
|
||||
TransformOp(m);
|
||||
|
|
|
|||
|
|
@ -235,12 +235,6 @@ void PaintingPainter::DashOp(const Vector<double>& dash, double start)
|
|||
Putf(start);
|
||||
}
|
||||
|
||||
void PaintingPainter::NoAAOp(bool noaa)
|
||||
{
|
||||
Put(PAINTING_NOAA);
|
||||
Put(noaa);
|
||||
}
|
||||
|
||||
void PaintingPainter::TransformOp(const Xform2D& m)
|
||||
{
|
||||
Put(PAINTING_TRANSFORM);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ enum {
|
|||
PAINTING_MITERLIMIT,
|
||||
PAINTING_EVENODD,
|
||||
PAINTING_DASH,
|
||||
PAINTING_NOAA,
|
||||
|
||||
PAINTING_TRANSFORM,
|
||||
PAINTING_BEGIN,
|
||||
|
|
@ -113,7 +112,6 @@ protected:
|
|||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ Buffer<ClipLine> BufferPainter::RenderPath(double width, SpanSource *ss, const R
|
|||
rg = &solid_filler;
|
||||
}
|
||||
}
|
||||
if(pathattr.noaa) {
|
||||
if(quality == QUALITY_NOAA) {
|
||||
noaa_filler.Set(rg);
|
||||
rg = &noaa_filler;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#define _Painter_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#include "CtrlLib/init"
|
||||
#define BLITZ_INDEX__ F41D82715284B94932890A06EF04E4CA5
|
||||
#define BLITZ_INDEX__ F135B9991BD270784ACE22BD4FFB4267E
|
||||
#include "PaintPainting.icpp"
|
||||
#undef BLITZ_INDEX__
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue