mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-17 06:06:00 -06:00
Fixed rounding problem in subpixel rendering
git-svn-id: svn://ultimatepp.org/upp/trunk@899 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
daf2cece0d
commit
e16d4ea2da
6 changed files with 48 additions and 39 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
17
uppsrc/Painter/srcimp.tpp/SubpixelFiller$en-us.tpp
Normal file
17
uppsrc/Painter/srcimp.tpp/SubpixelFiller$en-us.tpp
Normal file
|
|
@ -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; ]
|
||||
Loading…
Add table
Add a link
Reference in a new issue