diff --git a/uppsrc/Painter/Approximate.cpp b/uppsrc/Painter/Approximate.cpp index efa5cbccb..9f30d7f0f 100644 --- a/uppsrc/Painter/Approximate.cpp +++ b/uppsrc/Painter/Approximate.cpp @@ -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) { diff --git a/uppsrc/Painter/Fillers.cpp b/uppsrc/Painter/Fillers.cpp index 7a252cc1b..7eaba7ce4 100644 --- a/uppsrc/Painter/Fillers.cpp +++ b/uppsrc/Painter/Fillers.cpp @@ -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; diff --git a/uppsrc/Painter/Fillers.h b/uppsrc/Painter/Fillers.h index c5268b3b6..1d3215ec9 100644 --- a/uppsrc/Painter/Fillers.h +++ b/uppsrc/Painter/Fillers.h @@ -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); diff --git a/uppsrc/Painter/FontWin32.cpp b/uppsrc/Painter/FontWin32.cpp index 5bf2bb487..0292a500c 100644 --- a/uppsrc/Painter/FontWin32.cpp +++ b/uppsrc/Painter/FontWin32.cpp @@ -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 cache; - cache.Shrink(100000); + cache.Shrink(500000); sMakeCharOutline h; h.fc.fnt = fnt; h.fc.chr = ch; diff --git a/uppsrc/Painter/Painter.h b/uppsrc/Painter/Painter.h index c74f6e08b..6ba6291b8 100644 --- a/uppsrc/Painter/Painter.h +++ b/uppsrc/Painter/Painter.h @@ -3,7 +3,7 @@ #include -#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(); }; diff --git a/uppsrc/Painter/Render.cpp b/uppsrc/Painter/Render.cpp index ee610e4b7..d3c8e1391 100644 --- a/uppsrc/Painter/Render.cpp +++ b/uppsrc/Painter/Render.cpp @@ -89,6 +89,7 @@ Buffer 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()) { diff --git a/uppsrc/Painter/Xform2D.cpp b/uppsrc/Painter/Xform2D.cpp index 4a6e52708..479c3ccdd 100644 --- a/uppsrc/Painter/Xform2D.cpp +++ b/uppsrc/Painter/Xform2D.cpp @@ -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); }