[PATCH] gdi32: Improve GdiGradientFill
Hirofumi Katayama
katayama.hirofumi.mz at gmail.com
Sat Feb 21 23:51:58 CST 2009
See attachment.
-------------- next part --------------
From 28b65e323c6a6ff0966d738b2f0c0de0fa222d2c Mon Sep 17 00:00:00 2001
From: Hirofumi Katayama <katayama.hirofumi.mz at gmail.com>
Date: Sat, 21 Feb 2009 20:49:59 +0900
Subject: [PATCH] gdi32: Improve GdiGradientFill
---
dlls/gdi32/painting.c | 608 ++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 496 insertions(+), 112 deletions(-)
diff --git a/dlls/gdi32/painting.c b/dlls/gdi32/painting.c
index c3d8310..3798281 100644
--- a/dlls/gdi32/painting.c
+++ b/dlls/gdi32/painting.c
@@ -1234,152 +1234,536 @@ POINT *GDI_Bezier( const POINT *Points, INT count, INT *nPtsOut )
}
/******************************************************************************
- * GdiGradientFill (GDI32.@)
+ * bayer_dithering
*
- * FIXME: we don't support the Alpha channel properly
+ * FIXME: improve dithering
+ */
+static inline BYTE bayer_dithering(INT x, INT y, BYTE b)
+{
+ static const BYTE bayer_x_16_plus_8[] =
+ {
+ 8, 136, 40, 168,
+ 200, 72, 232, 104,
+ 56, 184, 24, 152,
+ 248, 120, 216, 88,
+ };
+ if (bayer_x_16_plus_8[(y & 3) * 4 + (x & 3)] <= b)
+ return 255;
+ else
+ return 0;
+}
+
+/******************************************************************************
+ * GdiGradientFill (GDI32.@)
*/
BOOL WINAPI GdiGradientFill( HDC hdc, TRIVERTEX *vert_array, ULONG nvert,
void * grad_array, ULONG ngrad, ULONG mode )
{
- unsigned int i;
-
- TRACE("vert_array:0x%08lx nvert:%d grad_array:0x%08lx ngrad:%d\n",
+ ULONG i;
+ BITMAPINFO bi;
+ HBITMAP hbm;
+ LPBYTE pbBits, pb;
+ GRADIENT_RECT *rect;
+ GRADIENT_TRIANGLE *tri;
+ TRIVERTEX *v1, *v2, *v3;
+ COLOR16 r1, g1, b1, a1, r2, g2, b2, a2;
+ COLOR16 dr, dg, db, da;
+ INT dx, dy, x1, y1, x2;
+ INT xMin, yMin, xMax, yMax;
+ INT cx, cy, widthbytes;
+ HDC hdcMem;
+ HGDIOBJ hbmOld;
+ BITMAP bm;
+ BOOL fDithering;
+
+ TRACE("vert_array:0x%08lx nvert:%d grad_array:0x%08lx ngrad:%d\n",
(long)vert_array, nvert, (long)grad_array, ngrad);
+
+ if (nvert == 0 || ngrad == 0)
+ return FALSE;
- switch(mode)
+ xMin = xMax = vert_array[0].x;
+ yMin = yMax = vert_array[0].y;
+ for(i = 1; i < nvert; i++)
+ {
+ if (vert_array[i].x < xMin)
+ xMin = vert_array[i].x;
+ else if (xMax < vert_array[i].x)
+ xMax = vert_array[i].x;
+ if (vert_array[i].y < yMin)
+ yMin = vert_array[i].y;
+ else if (yMax < vert_array[i].y)
+ yMax = vert_array[i].y;
+ }
+ cx = xMax - xMin;
+ cy = yMax - yMin;
+ ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER));
+ bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bi.bmiHeader.biWidth = cx;
+ bi.bmiHeader.biHeight = -cy;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ hbm = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (VOID **)&pbBits,
+ NULL, 0);
+ if (hbm == NULL)
+ return FALSE;
+
+ hdcMem = CreateCompatibleDC(NULL);
+ if (hdcMem == NULL)
+ {
+ DeleteObject(hbm);
+ return FALSE;
+ }
+
+ if (GetObject(GetCurrentObject(hdc, OBJ_BITMAP), sizeof(BITMAP), &bm))
+ fDithering = (bm.bmBitsPixel <= 8);
+ else
+ fDithering = FALSE;
+
+ widthbytes = cx * 4;
+
+ hbmOld = SelectObject(hdcMem, hbm);
+ BitBlt(hdcMem, 0, 0, cx, cy, hdc, xMin, yMin, SRCCOPY);
+
+ switch(mode)
{
case GRADIENT_FILL_RECT_H:
- for(i = 0; i < ngrad; i++)
+ for(i = 0; i < ngrad; i++)
{
- GRADIENT_RECT *rect = ((GRADIENT_RECT *)grad_array) + i;
- TRIVERTEX *v1 = vert_array + rect->UpperLeft;
- TRIVERTEX *v2 = vert_array + rect->LowerRight;
- int y1 = v1->y < v2->y ? v1->y : v2->y;
- int y2 = v2->y > v1->y ? v2->y : v1->y;
- int x, dx;
- if (v1->x > v2->x)
+ rect = (GRADIENT_RECT *)grad_array + i;
+ v1 = vert_array + rect->UpperLeft;
+ v2 = vert_array + rect->LowerRight;
+ if (v1->x > v2->x)
+ { TRIVERTEX *t = v2; v2 = v1; v1 = t; }
+ /* v1->x <= v2->x */
+ dx = v2->x - v1->x; dy = v2->y - v1->y;
+ r1 = v1->Red;
+ g1 = v1->Green;
+ b1 = v1->Blue;
+ a1 = v1->Alpha;
+ if (dx != 0)
+ {
+ dr = (v2->Red - v1->Red) / dx;
+ dg = (v2->Green - v1->Green) / dx;
+ db = (v2->Blue - v1->Blue) / dx;
+ da = (v2->Alpha - v1->Alpha) / dx;
+ }
+ if (dy < 0)
+ {
+ pb = pbBits + (v2->y - yMin) * widthbytes + (v1->x - xMin) * 4;
+ dy = -dy;
+ }
+ else
{
- TRIVERTEX *t = v2;
- v2 = v1;
- v1 = t;
+ pb = pbBits + (v1->y - yMin) * widthbytes + (v1->x - xMin) * 4;
}
- dx = v2->x - v1->x;
- for (x = 0; x < dx; x++)
+ if (fDithering)
{
- POINT pts[2];
- HPEN hPen, hOldPen;
-
- hPen = CreatePen( PS_SOLID, 1, RGB(
- (v1->Red * (dx - x) + v2->Red * x) / dx >> 8,
- (v1->Green * (dx - x) + v2->Green * x) / dx >> 8,
- (v1->Blue * (dx - x) + v2->Blue * x) / dx >> 8));
- hOldPen = SelectObject( hdc, hPen );
- pts[0].x = v1->x + x;
- pts[0].y = y1;
- pts[1].x = v1->x + x;
- pts[1].y = y2;
- Polyline( hdc, &pts[0], 2 );
- DeleteObject( SelectObject(hdc, hOldPen ) );
+ for(x1 = 0; x1 < dx; x1++)
+ {
+ for(y1 = 0; y1 < dy; y1++)
+ {
+ *pb++ = bayer_dithering(x1, y1, b1 >> 8);
+ *pb++ = bayer_dithering(x1, y1, g1 >> 8);
+ *pb++ = bayer_dithering(x1, y1, r1 >> 8);
+ pb++;
+ pb += widthbytes - 4;
+ }
+ r1 += dr;
+ g1 += dg;
+ b1 += db;
+ pb -= dy * widthbytes - 4;
+ }
+ }
+ else
+ {
+ for(x1 = 0; x1 < dx; x1++)
+ {
+ for(y1 = 0; y1 < dy; y1++)
+ {
+ *pb++ = b1 >> 8;
+ *pb++ = g1 >> 8;
+ *pb++ = r1 >> 8;
+ *pb++ = a1 >> 8;
+ pb += widthbytes - 4;
+ }
+ r1 += dr;
+ g1 += dg;
+ b1 += db;
+ a1 += da;
+ pb -= dy * widthbytes - 4;
+ }
}
}
- break;
+ break;
+
case GRADIENT_FILL_RECT_V:
- for(i = 0; i < ngrad; i++)
+ for(i = 0; i < ngrad; i++)
{
- GRADIENT_RECT *rect = ((GRADIENT_RECT *)grad_array) + i;
- TRIVERTEX *v1 = vert_array + rect->UpperLeft;
- TRIVERTEX *v2 = vert_array + rect->LowerRight;
- int x1 = v1->x < v2->x ? v1->x : v2->x;
- int x2 = v2->x > v1->x ? v2->x : v1->x;
- int y, dy;
- if (v1->y > v2->y)
+ rect = (GRADIENT_RECT *)grad_array + i;
+ v1 = vert_array + rect->UpperLeft;
+ v2 = vert_array + rect->LowerRight;
+ if (v1->y > v2->y)
+ { TRIVERTEX *t = v2; v2 = v1; v1 = t; }
+ /* v1->y <= v2->y */
+ dx = v2->x - v1->x; dy = v2->y - v1->y;
+ r1 = v1->Red;
+ g1 = v1->Green;
+ b1 = v1->Blue;
+ a1 = v1->Alpha;
+ if (dy != 0)
+ {
+ dr = (v2->Red - v1->Red) / dy;
+ dg = (v2->Green - v1->Green) / dy;
+ db = (v2->Blue - v1->Blue) / dy;
+ da = (v2->Alpha - v1->Alpha) / dy;
+ }
+ if (dx < 0)
+ {
+ pb = pbBits + (v1->y - yMin) * widthbytes + (v2->x - xMin) * 4;
+ dx = -dx;
+ }
+ else
+ {
+ pb = pbBits + (v1->y - yMin) * widthbytes + (v1->x - xMin) * 4;
+ }
+ if (fDithering)
{
- TRIVERTEX *t = v2;
- v2 = v1;
- v1 = t;
+ for(y1 = 0; y1 < dy; y1++)
+ {
+ for(x1 = 0; x1 < dx; x1++)
+ {
+ *pb++ = bayer_dithering(x1, y1, b1 >> 8);
+ *pb++ = bayer_dithering(x1, y1, g1 >> 8);
+ *pb++ = bayer_dithering(x1, y1, r1 >> 8);
+ pb++;
+ }
+ r1 += dr;
+ g1 += dg;
+ b1 += db;
+ pb -= dx * 4;
+ pb += widthbytes;
+ }
}
- dy = v2->y - v1->y;
- for (y = 0; y < dy; y++)
+ else
{
- POINT pts[2];
- HPEN hPen, hOldPen;
-
- hPen = CreatePen( PS_SOLID, 1, RGB(
- (v1->Red * (dy - y) + v2->Red * y) / dy >> 8,
- (v1->Green * (dy - y) + v2->Green * y) / dy >> 8,
- (v1->Blue * (dy - y) + v2->Blue * y) / dy >> 8));
- hOldPen = SelectObject( hdc, hPen );
- pts[0].x = x1;
- pts[0].y = v1->y + y;
- pts[1].x = x2;
- pts[1].y = v1->y + y;
- Polyline( hdc, &pts[0], 2 );
- DeleteObject( SelectObject(hdc, hOldPen ) );
+ for(y1 = 0; y1 < dy; y1++)
+ {
+ for(x1 = 0; x1 < dx; x1++)
+ {
+ *pb++ = b1 >> 8;
+ *pb++ = g1 >> 8;
+ *pb++ = r1 >> 8;
+ *pb++ = a1 >> 8;
+ }
+ r1 += dr;
+ g1 += dg;
+ b1 += db;
+ a1 += da;
+ pb -= dx * 4;
+ pb += widthbytes;
+ }
}
}
- break;
+ break;
+
case GRADIENT_FILL_TRIANGLE:
- for (i = 0; i < ngrad; i++)
+ for(i = 0; i < ngrad; i++)
{
- GRADIENT_TRIANGLE *tri = ((GRADIENT_TRIANGLE *)grad_array) + i;
- TRIVERTEX *v1 = vert_array + tri->Vertex1;
- TRIVERTEX *v2 = vert_array + tri->Vertex2;
- TRIVERTEX *v3 = vert_array + tri->Vertex3;
- int y, dy;
-
- if (v1->y > v2->y)
- { TRIVERTEX *t = v1; v1 = v2; v2 = t; }
- if (v2->y > v3->y)
+ tri = (GRADIENT_TRIANGLE *)grad_array + i;
+ v1 = vert_array + tri->Vertex1;
+ v2 = vert_array + tri->Vertex2;
+ v3 = vert_array + tri->Vertex3;
+
+ if (v1->y > v2->y)
+ { TRIVERTEX *t = v1; v1 = v2; v2 = t; }
+ if (v2->y > v3->y)
{
- TRIVERTEX *t = v2; v2 = v3; v3 = t;
- if (v1->y > v2->y)
- { t = v1; v1 = v2; v2 = t; }
+ TRIVERTEX *t = v2; v2 = v3; v3 = t;
+ if (v1->y > v2->y)
+ { t = v1; v1 = v2; v2 = t; }
}
- /* v1->y <= v2->y <= v3->y */
+ /* v1->y <= v2->y <= v3->y */
- dy = v3->y - v1->y;
- for (y = 0; y < dy; y++)
+ if (fDithering)
{
- /* v1->y <= y < v3->y */
- TRIVERTEX *v = y < (v2->y - v1->y) ? v1 : v3;
- /* (v->y <= y < v2->y) || (v2->y <= y < v->y) */
- int dy2 = v2->y - v->y;
- int y2 = y + v1->y - v->y;
-
- int x1 = (v3->x * y + v1->x * (dy - y )) / dy;
- int x2 = (v2->x * y2 + v-> x * (dy2 - y2)) / dy2;
- int r1 = (v3->Red * y + v1->Red * (dy - y )) / dy;
- int r2 = (v2->Red * y2 + v-> Red * (dy2 - y2)) / dy2;
- int g1 = (v3->Green * y + v1->Green * (dy - y )) / dy;
- int g2 = (v2->Green * y2 + v-> Green * (dy2 - y2)) / dy2;
- int b1 = (v3->Blue * y + v1->Blue * (dy - y )) / dy;
- int b2 = (v2->Blue * y2 + v-> Blue * (dy2 - y2)) / dy2;
-
- int x;
- if (x1 < x2)
+ for(y1 = v1->y; y1 < v2->y; y1++)
{
- int dx = x2 - x1;
- for (x = 0; x < dx; x++)
- SetPixel (hdc, x + x1, y + v1->y, RGB(
- (r1 * (dx - x) + r2 * x) / dx >> 8,
- (g1 * (dx - x) + g2 * x) / dx >> 8,
- (b1 * (dx - x) + b2 * x) / dx >> 8));
+ if (v2->x < v3->x)
+ {
+ x1 = v1->x + (v2->x - v1->x) * (y1 - v1->y) / (v2->y - v1->y);
+ r1 = v1->Red + (v2->Red - v1->Red) * (y1 - v1->y) / (v2->y - v1->y);
+ g1 = v1->Green + (v2->Green - v1->Green) * (y1 - v1->y) / (v2->y - v1->y);
+ b1 = v1->Blue + (v2->Blue - v1->Blue) * (y1 - v1->y) / (v2->y - v1->y);
+ x2 = v1->x + (v3->x - v1->x) * (y1 - v1->y) / (v3->y - v1->y);
+ r2 = v1->Red + (v3->Red - v1->Red) * (y1 - v1->y) / (v3->y - v1->y);
+ g2 = v1->Green + (v3->Green - v1->Green) * (y1 - v1->y) / (v3->y - v1->y);
+ b2 = v1->Blue + (v3->Blue - v1->Blue) * (y1 - v1->y) / (v3->y - v1->y);
+ dx = x2 - x1;
+ if (dx != 0)
+ {
+ db = (b2 - b1) / dx;
+ dg = (g2 - g1) / dx;
+ dr = (r2 - r1) / dx;
+ }
+ pb = pbBits + (x1 - xMin) * 4 + (y1 - yMin) * widthbytes;
+ for( ; x1 < x2; x1++)
+ {
+ *pb++ = bayer_dithering(x1, y1, b1 >> 8);
+ *pb++ = bayer_dithering(x1, y1, g1 >> 8);
+ *pb++ = bayer_dithering(x1, y1, r1 >> 8);
+ pb++;
+ b1 += db;
+ g1 += dg;
+ r1 += dr;
+ }
+ }
+ else
+ {
+ x1 = v1->x + (v3->x - v1->x) * (y1 - v1->y) / (v3->y - v1->y);
+ r1 = v1->Red + (v3->Red - v1->Red) * (y1 - v1->y) / (v3->y - v1->y);
+ g1 = v1->Green + (v3->Green - v1->Green) * (y1 - v1->y) / (v3->y - v1->y);
+ b1 = v1->Blue + (v3->Blue - v1->Blue) * (y1 - v1->y) / (v3->y - v1->y);
+ x2 = v1->x + (v2->x - v1->x) * (y1 - v1->y) / (v2->y - v1->y);
+ r2 = v1->Red + (v2->Red - v1->Red) * (y1 - v1->y) / (v2->y - v1->y);
+ g2 = v1->Green + (v2->Green - v1->Green) * (y1 - v1->y) / (v2->y - v1->y);
+ b2 = v1->Blue + (v2->Blue - v1->Blue) * (y1 - v1->y) / (v2->y - v1->y);
+ dx = x2 - x1;
+ if (dx != 0)
+ {
+ db = (b2 - b1) / dx;
+ dg = (g2 - g1) / dx;
+ dr = (r2 - r1) / dx;
+ }
+ pb = pbBits + (x1 - xMin) * 4 + (y1 - yMin) * widthbytes;
+ for( ; x1 < x2; x1++)
+ {
+ *pb++ = bayer_dithering(x1, y1, b1 >> 8);
+ *pb++ = bayer_dithering(x1, y1, g1 >> 8);
+ *pb++ = bayer_dithering(x1, y1, r1 >> 8);
+ pb++;
+ b1 += db;
+ g1 += dg;
+ r1 += dr;
+ }
+ }
}
- else
+ for(y1 = v2->y; y1 < v3->y; y1++)
{
- int dx = x1 - x2;
- for (x = 0; x < dx; x++)
- SetPixel (hdc, x + x2, y + v1->y, RGB(
- (r2 * (dx - x) + r1 * x) / dx >> 8,
- (g2 * (dx - x) + g1 * x) / dx >> 8,
- (b2 * (dx - x) + b1 * x) / dx >> 8));
+ if (v2->x < v3->x)
+ {
+ x1 = v2->x + (v3->x - v2->x) * (y1 - v2->y) / (v3->y - v2->y);
+ r1 = v2->Red + (v3->Red - v2->Red) * (y1 - v2->y) / (v3->y - v2->y);
+ g1 = v2->Green + (v3->Green - v2->Green) * (y1 - v2->y) / (v3->y - v2->y);
+ b1 = v2->Blue + (v3->Blue - v2->Blue) * (y1 - v2->y) / (v3->y - v2->y);
+ x2 = v1->x + (v3->x - v1->x) * (y1 - v1->y) / (v3->y - v1->y);
+ r2 = v1->Red + (v3->Red - v1->Red) * (y1 - v1->y) / (v3->y - v1->y);
+ g2 = v1->Green + (v3->Green - v1->Green) * (y1 - v1->y) / (v3->y - v1->y);
+ b2 = v1->Blue + (v3->Blue - v1->Blue) * (y1 - v1->y) / (v3->y - v1->y);
+ dx = x2 - x1;
+ if (dx != 0)
+ {
+ db = (b2 - b1) / dx;
+ dg = (g2 - g1) / dx;
+ dr = (r2 - r1) / dx;
+ }
+ pb = pbBits + (x1 - xMin) * 4 + (y1 - yMin) * widthbytes;
+ for( ; x1 < x2; x1++)
+ {
+ *pb++ = bayer_dithering(x1, y1, b1 >> 8);
+ *pb++ = bayer_dithering(x1, y1, g1 >> 8);
+ *pb++ = bayer_dithering(x1, y1, r1 >> 8);
+ pb++;
+ b1 += db;
+ g1 += dg;
+ r1 += dr;
+ }
+ }
+ else
+ {
+ x1 = v1->x + (v3->x - v1->x) * (y1 - v1->y) / (v3->y - v1->y);
+ r1 = v1->Red + (v3->Red - v1->Red) * (y1 - v1->y) / (v3->y - v1->y);
+ g1 = v1->Green + (v3->Green - v1->Green) * (y1 - v1->y) / (v3->y - v1->y);
+ b1 = v1->Blue + (v3->Blue - v1->Blue) * (y1 - v1->y) / (v3->y - v1->y);
+ x2 = v2->x + (v3->x - v2->x) * (y1 - v2->y) / (v3->y - v2->y);
+ r2 = v2->Red + (v3->Red - v2->Red) * (y1 - v2->y) / (v3->y - v2->y);
+ g2 = v2->Green + (v3->Green - v2->Green) * (y1 - v2->y) / (v3->y - v2->y);
+ b2 = v2->Blue + (v3->Blue - v2->Blue) * (y1 - v2->y) / (v3->y - v2->y);
+ dx = x2 - x1;
+ if (dx != 0)
+ {
+ db = (b2 - b1) / dx;
+ dg = (g2 - g1) / dx;
+ dr = (r2 - r1) / dx;
+ }
+ pb = pbBits + (x1 - xMin) * 4 + (y1 - yMin) * widthbytes;
+ for( ; x1 < x2; x1++)
+ {
+ *pb++ = bayer_dithering(x1, y1, b1 >> 8);
+ *pb++ = bayer_dithering(x1, y1, g1 >> 8);
+ *pb++ = bayer_dithering(x1, y1, r1 >> 8);
+ pb++;
+ b1 += db;
+ g1 += dg;
+ r1 += dr;
+ }
+ }
+ }
+ }
+ else
+ {
+ for(y1 = v1->y; y1 < v2->y; y1++)
+ {
+ if (v2->x < v3->x)
+ {
+ x1 = v1->x + (v2->x - v1->x) * (y1 - v1->y) / (v2->y - v1->y);
+ r1 = v1->Red + (v2->Red - v1->Red) * (y1 - v1->y) / (v2->y - v1->y);
+ g1 = v1->Green + (v2->Green - v1->Green) * (y1 - v1->y) / (v2->y - v1->y);
+ b1 = v1->Blue + (v2->Blue - v1->Blue) * (y1 - v1->y) / (v2->y - v1->y);
+ a1 = v1->Alpha + (v2->Alpha - v1->Alpha) * (y1 - v1->y) / (v2->y - v1->y);
+ x2 = v1->x + (v3->x - v1->x) * (y1 - v1->y) / (v3->y - v1->y);
+ r2 = v1->Red + (v3->Red - v1->Red) * (y1 - v1->y) / (v3->y - v1->y);
+ g2 = v1->Green + (v3->Green - v1->Green) * (y1 - v1->y) / (v3->y - v1->y);
+ b2 = v1->Blue + (v3->Blue - v1->Blue) * (y1 - v1->y) / (v3->y - v1->y);
+ a2 = v1->Alpha + (v3->Alpha - v1->Alpha) * (y1 - v1->y) / (v3->y - v1->y);
+ dx = x2 - x1;
+ if (dx != 0)
+ {
+ db = (b2 - b1) / dx;
+ dg = (g2 - g1) / dx;
+ dr = (r2 - r1) / dx;
+ da = (a2 - a1) / dx;
+ }
+ pb = pbBits + (x1 - xMin) * 4 + (y1 - yMin) * widthbytes;
+ for( ; x1 < x2; x1++)
+ {
+ *pb++ = b1 >> 8;
+ *pb++ = g1 >> 8;
+ *pb++ = r1 >> 8;
+ *pb++ = a1 >> 8;
+ b1 += db;
+ g1 += dg;
+ r1 += dr;
+ a1 += da;
+ }
+ }
+ else
+ {
+ x1 = v1->x + (v3->x - v1->x) * (y1 - v1->y) / (v3->y - v1->y);
+ r1 = v1->Red + (v3->Red - v1->Red) * (y1 - v1->y) / (v3->y - v1->y);
+ g1 = v1->Green + (v3->Green - v1->Green) * (y1 - v1->y) / (v3->y - v1->y);
+ b1 = v1->Blue + (v3->Blue - v1->Blue) * (y1 - v1->y) / (v3->y - v1->y);
+ a1 = v1->Alpha + (v3->Alpha - v1->Alpha) * (y1 - v1->y) / (v3->y - v1->y);
+ x2 = v1->x + (v2->x - v1->x) * (y1 - v1->y) / (v2->y - v1->y);
+ r2 = v1->Red + (v2->Red - v1->Red) * (y1 - v1->y) / (v2->y - v1->y);
+ g2 = v1->Green + (v2->Green - v1->Green) * (y1 - v1->y) / (v2->y - v1->y);
+ b2 = v1->Blue + (v2->Blue - v1->Blue) * (y1 - v1->y) / (v2->y - v1->y);
+ a2 = v1->Alpha + (v2->Alpha - v1->Alpha) * (y1 - v1->y) / (v2->y - v1->y);
+ dx = x2 - x1;
+ if (dx != 0)
+ {
+ db = (b2 - b1) / dx;
+ dg = (g2 - g1) / dx;
+ dr = (r2 - r1) / dx;
+ da = (a2 - a1) / dx;
+ }
+ pb = pbBits + (x1 - xMin) * 4 + (y1 - yMin) * widthbytes;
+ for( ; x1 < x2; x1++)
+ {
+ *pb++ = b1 >> 8;
+ *pb++ = g1 >> 8;
+ *pb++ = r1 >> 8;
+ *pb++ = a1 >> 8;
+ b1 += db;
+ g1 += dg;
+ r1 += dr;
+ a1 += da;
+ }
+ }
+ }
+ for(y1 = v2->y; y1 < v3->y; y1++)
+ {
+ if (v2->x < v3->x)
+ {
+ x1 = v2->x + (v3->x - v2->x) * (y1 - v2->y) / (v3->y - v2->y);
+ r1 = v2->Red + (v3->Red - v2->Red) * (y1 - v2->y) / (v3->y - v2->y);
+ g1 = v2->Green + (v3->Green - v2->Green) * (y1 - v2->y) / (v3->y - v2->y);
+ b1 = v2->Blue + (v3->Blue - v2->Blue) * (y1 - v2->y) / (v3->y - v2->y);
+ a1 = v2->Alpha + (v3->Alpha - v2->Alpha) * (y1 - v2->y) / (v3->y - v2->y);
+ x2 = v1->x + (v3->x - v1->x) * (y1 - v1->y) / (v3->y - v1->y);
+ r2 = v1->Red + (v3->Red - v1->Red) * (y1 - v1->y) / (v3->y - v1->y);
+ g2 = v1->Green + (v3->Green - v1->Green) * (y1 - v1->y) / (v3->y - v1->y);
+ b2 = v1->Blue + (v3->Blue - v1->Blue) * (y1 - v1->y) / (v3->y - v1->y);
+ a2 = v1->Alpha + (v3->Alpha - v1->Alpha) * (y1 - v1->y) / (v3->y - v1->y);
+ dx = x2 - x1;
+ if (dx != 0)
+ {
+ db = (b2 - b1) / dx;
+ dg = (g2 - g1) / dx;
+ dr = (r2 - r1) / dx;
+ da = (a2 - a1) / dx;
+ }
+ pb = pbBits + (x1 - xMin) * 4 + (y1 - yMin) * widthbytes;
+ for( ; x1 < x2; x1++)
+ {
+ *pb++ = b1 >> 8;
+ *pb++ = g1 >> 8;
+ *pb++ = r1 >> 8;
+ *pb++ = a1 >> 8;
+ b1 += db;
+ g1 += dg;
+ r1 += dr;
+ a1 += da;
+ }
+ }
+ else
+ {
+ x1 = v1->x + (v3->x - v1->x) * (y1 - v1->y) / (v3->y - v1->y);
+ r1 = v1->Red + (v3->Red - v1->Red) * (y1 - v1->y) / (v3->y - v1->y);
+ g1 = v1->Green + (v3->Green - v1->Green) * (y1 - v1->y) / (v3->y - v1->y);
+ b1 = v1->Blue + (v3->Blue - v1->Blue) * (y1 - v1->y) / (v3->y - v1->y);
+ a1 = v1->Alpha + (v3->Alpha - v1->Alpha) * (y1 - v1->y) / (v3->y - v1->y);
+ x2 = v2->x + (v3->x - v2->x) * (y1 - v2->y) / (v3->y - v2->y);
+ r2 = v2->Red + (v3->Red - v2->Red) * (y1 - v2->y) / (v3->y - v2->y);
+ g2 = v2->Green + (v3->Green - v2->Green) * (y1 - v2->y) / (v3->y - v2->y);
+ b2 = v2->Blue + (v3->Blue - v2->Blue) * (y1 - v2->y) / (v3->y - v2->y);
+ a2 = v2->Alpha + (v3->Alpha - v2->Alpha) * (y1 - v2->y) / (v3->y - v2->y);
+ dx = x2 - x1;
+ if (dx != 0)
+ {
+ db = (b2 - b1) / dx;
+ dg = (g2 - g1) / dx;
+ dr = (r2 - r1) / dx;
+ da = (a2 - a1) / dx;
+ }
+ pb = pbBits + (x1 - xMin) * 4 + (y1 - yMin) * widthbytes;
+ for( ; x1 < x2; x1++)
+ {
+ *pb++ = b1 >> 8;
+ *pb++ = g1 >> 8;
+ *pb++ = r1 >> 8;
+ *pb++ = a1 >> 8;
+ b1 += db;
+ g1 += dg;
+ r1 += dr;
+ a1 += da;
+ }
+ }
}
}
}
- break;
+ break;
+
default:
- return FALSE;
- }
+ SelectObject(hdcMem, hbmOld);
+ DeleteObject(hbm);
+ DeleteDC(hdcMem);
+ return FALSE;
+ }
- return TRUE;
+ BitBlt(hdc, xMin, yMin, cx, cy, hdcMem, 0, 0, SRCCOPY);
+ SelectObject(hdcMem, hbmOld);
+ DeleteObject(hbm);
+ DeleteDC(hdcMem);
+ return TRUE;
}
--
1.6.1.3
More information about the wine-patches
mailing list