From 10bc0d46600da2d3bd0c0a93ec7c3483d8cee58f Mon Sep 17 00:00:00 2001 From: Doug Lyons Date: Mon, 28 Jul 2025 22:00:35 -0500 Subject: [PATCH] [WIN32K:ENG] Fix triangle gradient fill solid color versus gradient color selection logic (#8269) CORE-13532 * Fix macros VCMPCLR and VCMPCLRS to correctly select between gradient color or solid color triangles. * Remove hack from commit 1c0aedc and replace it with 'if' test before STEPCOL in 'while' test. * Other assorted fixes for FILLLIINE macro starting position to completely fill triangles. * Remove warning/FIXME: about IntEngGradientFillTriangle being broken. * Precede some 'while' loops by 'if' tests to exclude possible loops. --- win32ss/gdi/eng/gradient.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/win32ss/gdi/eng/gradient.c b/win32ss/gdi/eng/gradient.c index 3fb80c19e35..68c45a3fb38 100644 --- a/win32ss/gdi/eng/gradient.c +++ b/win32ss/gdi/eng/gradient.c @@ -18,9 +18,12 @@ const LONG LINC[2] = {-1, 1}; #define VERTEX(n) (pVertex + gt->n) #define COMPAREVERTEX(a, b) ((a)->x == (b)->x && (a)->y == (b)->y) -#define VCMPCLR(a,b,c,color) (a->color != b->color || a->color != c->color) -#define VCMPCLRS(a,b,c) \ - !(!VCMPCLR(a,b,c,Red) || !VCMPCLR(a,b,c,Green) || !VCMPCLR(a,b,c,Blue)) +/* Check if all three vectors have the same color, either R, G, or B */ +#define VCMPCLR(a, b, c, color) (a->color == b->color && a->color == c->color) +/* Check if all three vectors have the same colors for R, G, and B, then + * NOT the result because we want to check for not using solid color logic */ +#define VCMPCLRS(a, b, c) \ + !(VCMPCLR(a, b, c, Red) && VCMPCLR(a, b, c, Green) && VCMPCLR(a, b, c, Blue)) /* Horizontal/Vertical gradients */ #define HVINITCOL(Col, id) \ @@ -225,6 +228,7 @@ IntEngGradientFillRect( #define STEPCOL(a,b,line,col,id) \ ec[line][id] += dc[line][id]; \ + if(dy[line] != 0) \ while(ec[line][id] > 0) \ { \ c[line][id] += ic[line][id]; \ @@ -239,6 +243,7 @@ IntEngGradientFillRect( #define FDOCOL(linefrom,lineto,colid) \ ge[colid] += gd[colid]; \ + if (gx != 0) \ while(ge[colid] > 0) \ { \ gc[colid] += gi[colid]; \ @@ -251,7 +256,8 @@ IntEngGradientFillRect( FINITCOL(linefrom, lineto, 0); \ FINITCOL(linefrom, lineto, 1); \ FINITCOL(linefrom, lineto, 2); \ - for(g = sx[linefrom]; g != sx[lineto]; g += gxi) \ + g_end = sx[lineto] + gxi; \ + for(g = sx[linefrom]; g != g_end; g += gxi) \ { \ if(InY && g >= FillRect.left && g < FillRect.right) \ { \ @@ -284,9 +290,9 @@ IntEngGradientFillRect( #define INITLINE(a,b,line) \ x[line] = a->x; \ - sx[line] = a->x + pptlDitherOrg->x; \ + sx[line] = a->x + pptlDitherOrg->x - 1; \ dx[line] = abs(b->x - a->x); \ - dy[line] = max(abs(b->y - a->y),1); \ + dy[line] = abs(b->y - a->y); \ incx[line] = LINC[b->x > a->x]; \ ex[line] = -(dy[line]>>1); \ destx[line] = b->x @@ -331,7 +337,7 @@ IntEngGradientFillTriangle( LONG x[NLINES], dx[NLINES], dy[NLINES], incx[NLINES], ex[NLINES], destx[NLINES]; LONG c[NLINES][3], dc[NLINES][3], ec[NLINES][3], ic[NLINES][3]; /* colors on lines */ LONG g, gx, gxi, gc[3], gd[3], ge[3], gi[3]; /* colors in triangle */ - LONG sy, y, bt; + LONG sy, y, bt, g_end; v1 = (pVertex + gTriangle->Vertex1); v2 = (pVertex + gTriangle->Vertex2); @@ -355,8 +361,6 @@ IntEngGradientFillTriangle( } DPRINT("Triangle: (%i,%i) (%i,%i) (%i,%i)\n", v1->x, v1->y, v2->x, v2->y, v3->x, v3->y); - /* FIXME: commented out because of an endless loop - fix triangles first */ - DPRINT("FIXME: IntEngGradientFillTriangle is broken\n"); if (!IntEngEnter(&EnterLeave, psoDest, &FillRect, FALSE, &Translate, &psoOutput)) { @@ -396,6 +400,7 @@ IntEngGradientFillTriangle( ENDLINE(v1, v2, 1); GOLINE(v2, v3, 2); + FILLLINE(0, 2); DOLINE(v2, v3, 2); FILLLINE(0, 2); ENDLINE(23, v3, 2);