mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
Subpixel rendering finished
git-svn-id: svn://ultimatepp.org/upp/trunk@890 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
d2b3357930
commit
33078261ff
7 changed files with 76 additions and 60 deletions
|
|
@ -6,6 +6,7 @@ static void sQuadratic(LinearPathConsumer& t, const Pointf& p1, const Pointf& p2
|
|||
double qt, int lvl)
|
||||
{
|
||||
if(lvl < 16) {
|
||||
PAINTER_TIMING("Quadratic approximation");
|
||||
Pointf d = p3 - p1;
|
||||
double q = Squared(d);
|
||||
if(q > 1e-30) {
|
||||
|
|
@ -36,6 +37,7 @@ static void sCubic(LinearPathConsumer& t,
|
|||
double qt, int lvl)
|
||||
{
|
||||
if(lvl < 16) {
|
||||
PAINTER_TIMING("Cubic approximation");
|
||||
Pointf d = p4 - p1;
|
||||
double q = d.x * d.x + d.y * d.y;
|
||||
if(q >= 1e-30) {
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ void SolidFiller::Render(int val, int len)
|
|||
|
||||
void SubpixelFiller::Start(int minx, int maxx)
|
||||
{
|
||||
x = minx / 3;
|
||||
int x = minx / 3;
|
||||
if(x > 0) {
|
||||
begin = sbuffer;
|
||||
x--;
|
||||
|
|
@ -77,7 +77,6 @@ void SubpixelFiller::Start(int minx, int maxx)
|
|||
sbuffer[0] = sbuffer[1] = sbuffer[2] = sbuffer[3] =
|
||||
sbuffer[4] = sbuffer[5] = sbuffer[6] = sbuffer[7] = 0;
|
||||
v = sbuffer + 3 + minx % 3;
|
||||
end = v + maxx + 1;
|
||||
if(ss) {
|
||||
int xx = maxx / 3;
|
||||
ss->Get(buffer, x, y, xx - x + 2);
|
||||
|
|
@ -85,9 +84,9 @@ void SubpixelFiller::Start(int minx, int maxx)
|
|||
}
|
||||
}
|
||||
|
||||
void SubpixelFiller::Render(int val) // Optimize: Render0
|
||||
inline
|
||||
void SubpixelFiller::Render0(int val)
|
||||
{
|
||||
#if 1
|
||||
int h = val / 9;
|
||||
int h2 = h + h;
|
||||
v[-2] += h;
|
||||
|
|
@ -96,86 +95,95 @@ void SubpixelFiller::Render(int val) // Optimize: Render0
|
|||
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)
|
||||
{
|
||||
Render0(val);
|
||||
}
|
||||
|
||||
void SubpixelFiller::Render(int val, int len)
|
||||
{
|
||||
/* if(len > 9) {
|
||||
int q = (3333333 - x) % 3;
|
||||
len -= q;
|
||||
if(len > 9) {
|
||||
Render(val);
|
||||
Render(val);
|
||||
int q = (3333333 - (v - begin)) % 3;
|
||||
len -= q + 2;
|
||||
while(q--)
|
||||
Render(val);
|
||||
int16 *h = v;
|
||||
int l = v - begin;
|
||||
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;
|
||||
}*/
|
||||
Write(l / 3);
|
||||
l = len / 3;
|
||||
len -= 3 * l;
|
||||
RGBA *e = min(t + l, end);
|
||||
if(val == 256)
|
||||
if(!ss && color.a == 255) {
|
||||
FillRGBA(t, color, e - t);
|
||||
t = e;
|
||||
}
|
||||
else
|
||||
while(t < e)
|
||||
AlphaBlend(*t++, ss ? Mul8(*s++, alpha) : color);
|
||||
else
|
||||
while(t < e)
|
||||
AlphaBlendCover8(*t++, ss ? Mul8(*s++, alpha) : color, val);
|
||||
v = begin = sbuffer + 3;
|
||||
int h = val / 9;
|
||||
v[0] = h + h + h;
|
||||
v[1] = h;
|
||||
v[2] = 0;
|
||||
}
|
||||
while(len--)
|
||||
Render(val);
|
||||
}
|
||||
|
||||
void SubpixelFiller::End()
|
||||
void SubpixelFiller::Write(int len)
|
||||
{
|
||||
// int n = (3333333 - (v - begin)) % 3;
|
||||
// while(n--)
|
||||
if(v < end)
|
||||
Render(0);
|
||||
if(v < end)
|
||||
Render(0);
|
||||
RGBA *e = min(t + len, end);
|
||||
int16 *q = begin;
|
||||
while(q < v) {
|
||||
while(t < e) {
|
||||
RGBA c = ss ? Mul8(*s++, alpha) : color;
|
||||
int a, alpha;
|
||||
/* if(c.a == 255) {
|
||||
if(c.a == 255) {
|
||||
alpha = 256 - q[0];
|
||||
t->r = (c.r * q[0] >> 8) + (alpha * t->r >> 8);
|
||||
t->r = (c.r * q[0] + alpha * t->r) >> 8;
|
||||
alpha = 256 - q[1];
|
||||
t->g = (c.g * q[1] >> 8) + (alpha * t->g >> 8);
|
||||
t->g = (c.g * q[1] + alpha * t->g) >> 8;
|
||||
alpha = 256 - q[2];
|
||||
t->b = (c.b * q[2] >> 8) + (alpha * t->b >> 8);
|
||||
t->b = (c.b * q[2] + alpha * t->b) >> 8;
|
||||
a = (q[0] + q[1] + q[2]) / 3;
|
||||
alpha = 256 - a;
|
||||
t->a = (a * 255 + alpha * t->a) >> 8;
|
||||
}
|
||||
else {
|
||||
a = c.a * q[0] >> 8;
|
||||
alpha = 256 - (a + (a >> 7));
|
||||
t->r = (c.r * q[0] + alpha * t->r) >> 8;
|
||||
a = c.a * q[1] >> 8;
|
||||
alpha = 256 - (a + (a >> 7));
|
||||
t->g = (c.g * q[1] + alpha * t->g) >> 8;
|
||||
a = c.a * q[2] >> 8;
|
||||
alpha = 256 - (a + (a >> 7));
|
||||
t->b = (c.b * q[2] + alpha * t->b) >> 8;
|
||||
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);
|
||||
a = c.a * q[1] >> 8;
|
||||
alpha = 256 - (a + (a >> 7));
|
||||
t->g = (c.g * q[1] >> 8) + (alpha * t->g >> 8);
|
||||
a = c.a * q[2] >> 8;
|
||||
alpha = 256 - (a + (a >> 7));
|
||||
t->b = (c.b * q[2] >> 8) + (alpha * t->b >> 8);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void SubpixelFiller::End()
|
||||
{
|
||||
Render(0);
|
||||
Render(0);
|
||||
Write((v - begin) / 3);
|
||||
}
|
||||
|
||||
void SpanFiller::Start(int minx, int maxx)
|
||||
{
|
||||
t += minx;
|
||||
|
|
|
|||
|
|
@ -24,15 +24,18 @@ struct SpanFiller : Rasterizer::Filler {
|
|||
|
||||
struct SubpixelFiller : Rasterizer::Filler {
|
||||
int16 *sbuffer;
|
||||
int16 *begin, *end;
|
||||
RGBA *t;
|
||||
int16 *begin;
|
||||
RGBA *t, *end;
|
||||
int16 *v;
|
||||
RGBA *s;
|
||||
RGBA color;
|
||||
SpanSource *ss;
|
||||
int alpha;
|
||||
RGBA *buffer;
|
||||
int x, y;
|
||||
int y;
|
||||
|
||||
void Write(int len);
|
||||
void Render0(int val);
|
||||
|
||||
void Start(int minx, int maxx);
|
||||
void Render(int val);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ inline double fx_to_dbl(const FIXED& p) {
|
|||
|
||||
void RenderCharPath(const char* gbuf, unsigned total_size, Painter& sw, double xx, double yy)
|
||||
{
|
||||
PAINTER_TIMING("RenderCharPath");
|
||||
const char* cur_glyph = gbuf;
|
||||
const char* end_glyph = gbuf + total_size;
|
||||
|
||||
|
|
@ -99,7 +100,7 @@ void Painter::CharacterOp(const Pointf& p, int ch, Font fnt)
|
|||
String s;
|
||||
INTERLOCKED {
|
||||
static LRUCache<String, FontChar> cache;
|
||||
cache.Shrink(100000);
|
||||
cache.Shrink(500000);
|
||||
sMakeCharOutline h;
|
||||
h.fc.fnt = fnt;
|
||||
h.fc.chr = ch;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <Draw/Draw.h>
|
||||
|
||||
#define PAINTER_TIMING(x) //RTIMING(x)
|
||||
#define PAINTER_TIMING(x) // RTIMING(x)
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ struct Xform2D {
|
|||
static Xform2D Scale(double sx, double sy);
|
||||
static Xform2D Scale(double scale);
|
||||
static Xform2D Rotation(double fi);
|
||||
static Xform2D Sheer(double fi);
|
||||
static Xform2D Sheer(double fi);
|
||||
|
||||
Xform2D();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ Buffer<ClipLine> BufferPainter::RenderPath(double width, SpanSource *ss, const R
|
|||
g->End();
|
||||
for(int y = rasterizer.MinY(); y <= rasterizer.MaxY(); y++) {
|
||||
solid_filler.t = subpixel_filler.t = span_filler.t = ib[y];
|
||||
subpixel_filler.end = subpixel_filler.t + ib.GetWidth();
|
||||
span_filler.y = subpixel_filler.y = y;
|
||||
Rasterizer::Filler *rf = rg;
|
||||
if(clip.GetCount()) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ NAMESPACE_UPP
|
|||
|
||||
Pointf Xform2D::Transform(const Pointf& f) const
|
||||
{
|
||||
PAINTER_TIMING("Transform");
|
||||
return Pointf(f.x * x.x + f.y * x.y + t.x, f.x * y.x + f.y * y.y + t.y);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue