diff --git a/uppsrc/Painter/Fillers.cpp b/uppsrc/Painter/Fillers.cpp index 713cddf25..338cd8198 100644 --- a/uppsrc/Painter/Fillers.cpp +++ b/uppsrc/Painter/Fillers.cpp @@ -128,10 +128,9 @@ void SubpixelFiller::Render(int val) v++; } -void SubpixelFiller::RenderN(int val, int n) +void SubpixelFiller::RenderN(int val, int h, int n) { int16 *w = v; - int h = val / 9; int h2 = h + h; int hv2 = val - h2 - h2; int h3 = h2 + h; @@ -214,11 +213,12 @@ void SubpixelFiller::RenderN(int val, int n) void SubpixelFiller::Render(int val, int len) { + int h = val / 9; if(len > 6) { int q = (3333333 - (v + 2 - begin)) % 3; len -= q + 2; int l = v + 2 + q - begin; - RenderN(val, q + 4); + RenderN(val, h, q + 4); Write(l / 3); l = len / 3; len -= 3 * l; @@ -235,12 +235,11 @@ void SubpixelFiller::Render(int val, int len) 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; } - RenderN(val, len); + RenderN(val, h, len); } void SubpixelFiller::Write(int len) @@ -249,30 +248,23 @@ void SubpixelFiller::Write(int len) int16 *q = begin; while(t < e) { RGBA c = ss ? Mul8(*s++, alpha) : color; - int a, alpha; + int a; if(t->a != 255) AlphaBlendCover8(*t, c, (q[0] + q[1] + q[2]) / 3); - else { + else 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); + t->r = (c.r * q[0] >> 8) + ((257 - q[0]) * t->r >> 8); + t->g = (c.g * q[1] >> 8) + ((257 - q[1]) * t->g >> 8); + t->b = (c.b * q[2] >> 8) + ((257 - q[2]) * t->b >> 8); } else { a = c.a * q[0] >> 8; - alpha = 256 - a - (a >> 7); - t->r = (c.r * q[0] >> 8) + (alpha * t->r >> 8); + t->r = (c.r * q[0] >> 8) + ((256 - a - (a >> 7)) * 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); + t->g = (c.g * q[1] >> 8) + ((256 - a - (a >> 7)) * 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); + t->b = (c.b * q[2] >> 8) + ((256 - a - (a >> 7)) * t->b >> 8); } - } t++; q += 3; } diff --git a/uppsrc/Painter/Fillers.h b/uppsrc/Painter/Fillers.h index 09e640250..43fc96bed 100644 --- a/uppsrc/Painter/Fillers.h +++ b/uppsrc/Painter/Fillers.h @@ -35,7 +35,7 @@ struct SubpixelFiller : Rasterizer::Filler { int y; void Write(int len); - void RenderN(int val, int n); + void RenderN(int val, int h, int n); void Render2(int val); void Render1(int val); diff --git a/uppsrc/Painter/FontWin32.cpp b/uppsrc/Painter/FontWin32.cpp index 0292a500c..cfa6ff1fb 100644 --- a/uppsrc/Painter/FontWin32.cpp +++ b/uppsrc/Painter/FontWin32.cpp @@ -21,39 +21,38 @@ NAMESPACE_UPP #ifdef PLATFORM_WIN32 -inline double fx_to_dbl(const FIXED& p) { +double fx_to_dbl(const FIXED& p) { return double(p.value) + double(p.fract) * (1.0 / 65536.0); } +Pointf fx_to_dbl(const Pointf& pp, const POINTFX& p) { + return Pointf(pp.x + fx_to_dbl(p.x), pp.y - fx_to_dbl(p.y)); +} + 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; - + Pointf pp(xx, yy); while(cur_glyph < end_glyph) { const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph; const char* end_poly = cur_glyph + th->cb; const char* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER); - sw.Move(xx + fx_to_dbl(th->pfxStart.x), yy - fx_to_dbl(th->pfxStart.y)); + sw.Move(fx_to_dbl(pp, th->pfxStart)); while(cur_poly < end_poly) { const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly; if (pc->wType == TT_PRIM_LINE) for(int i = 0; i < pc->cpfx; i++) - sw.Line(xx + fx_to_dbl(pc->apfx[i].x), yy - fx_to_dbl(pc->apfx[i].y)); - if (pc->wType == TT_PRIM_QSPLINE) { - int u; - for (u = 0; u < pc->cpfx - 1; u++) { // Walk through points in spline - POINTFX pnt_b = pc->apfx[u]; // B is always the current point - POINTFX pnt_c = pc->apfx[u+1]; - if (u < pc->cpfx - 2) { // If not on last spline, compute C - *(int*)&pnt_c.x = (*(int*)&pnt_b.x + *(int*)&pnt_c.x) / 2; - *(int*)&pnt_c.y = (*(int*)&pnt_b.y + *(int*)&pnt_c.y) / 2; - } - sw.Quadratic(xx + fx_to_dbl(pnt_b.x), yy - fx_to_dbl(pnt_b.y), - xx + fx_to_dbl(pnt_c.x), yy - fx_to_dbl(pnt_c.y)); + sw.Line(fx_to_dbl(pp, pc->apfx[i])); + if (pc->wType == TT_PRIM_QSPLINE) + for(int u = 0; u < pc->cpfx - 1; u++) { + Pointf b = fx_to_dbl(pp, pc->apfx[u]); + Pointf c = fx_to_dbl(pp, pc->apfx[u + 1]); + if (u < pc->cpfx - 2) + c = Mid(b, c); + sw.Quadratic(b, c); } - } cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx; } sw.Close(); diff --git a/uppsrc/Painter/Painter.upp b/uppsrc/Painter/Painter.upp index 483f97be2..45918d46a 100644 --- a/uppsrc/Painter/Painter.upp +++ b/uppsrc/Painter/Painter.upp @@ -34,7 +34,8 @@ file Image.cpp optimize_speed, Mask.cpp optimize_speed, Gradient.cpp optimize_speed, - RadialGradient.cpp optimize_speed; + RadialGradient.cpp optimize_speed, + srcimp.tpp; mainconfig "" = "GUI"; diff --git a/uppsrc/Painter/init b/uppsrc/Painter/init index 77e82d94b..78c03394f 100644 --- a/uppsrc/Painter/init +++ b/uppsrc/Painter/init @@ -2,7 +2,7 @@ #define _Painter_icpp_init_stub #include "Core/init" #include "CtrlLib/init" -#define BLITZ_INDEX__ F135B9991BD270784ACE22BD4FFB4267E +#define BLITZ_INDEX__ F1F279540D3FE6AF9024371A0E93C1FBB #include "PaintPainting.icpp" #undef BLITZ_INDEX__ #endif diff --git a/uppsrc/Painter/srcimp.tpp/SubpixelFiller$en-us.tpp b/uppsrc/Painter/srcimp.tpp/SubpixelFiller$en-us.tpp new file mode 100644 index 000000000..7e2547b6c --- /dev/null +++ b/uppsrc/Painter/srcimp.tpp/SubpixelFiller$en-us.tpp @@ -0,0 +1,17 @@ +topic ""; +[ $$0,0#00000000000000000000000000000000:Default] +[H6;0 $$1,0#05600065144404261032431302351956:begin] +[i448;a25;kKO9;2 $$2,0#37138531426314131252341829483370:codeitem] +[l288;2 $$3,0#27521748481378242620020725143825:desc] +[0 $$4,0#96390100711032703541132217272105:end] +[{_}%EN-US +[s1;%- &] +[s2;:SubpixelFiller`:`:Write`(int`):%- [@(0.0.255) void]_[* Write]([@(0.0.255) int]_[*@3 len]) +&] +[s3; This function flushes the content of filtered subpixel buffer.&] +[s0; Important note: due to rounding errors during filtering, sometimes +the subpixel value can be 257. This is remedied by using 257 +instead of 256 in the pixel blending command.&] +[s0; &] +[s4; &] +[s0; ] \ No newline at end of file