{
switch (brush->bt)
{
- case BrushTypeLinearGradient:
- {
- GpLineGradient *line = (GpLineGradient*)brush;
- RECT rc;
-
- SelectClipPath(graphics->hdc, RGN_AND);
- if (GetClipBox(graphics->hdc, &rc) != NULLREGION)
- {
- GpPointF endpointsf[2];
- POINT endpointsi[2];
- POINT poly[4];
-
- SelectObject(graphics->hdc, GetStockObject(NULL_PEN));
-
- endpointsf[0] = line->startpoint;
- endpointsf[1] = line->endpoint;
- transform_and_round_points(graphics, endpointsi, endpointsf, 2);
-
- if (abs(endpointsi[0].x-endpointsi[1].x) > abs(endpointsi[0].y-endpointsi[1].y))
- {
- /* vertical-ish gradient */
- int startx, endx; /* x co-ordinates of endpoints shifted to intersect the top of the visible rectangle */
- int startbottomx; /* x co-ordinate of start point shifted to intersect the bottom of the visible rectangle */
- int width;
- COLORREF col;
- HBRUSH hbrush, hprevbrush;
- int leftx, rightx; /* x co-ordinates where the leftmost and rightmost gradient lines hit the top of the visible rectangle */
- int x;
- int tilt; /* horizontal distance covered by a gradient line */
-
- startx = roundr((rc.top - endpointsf[0].Y) * (endpointsf[1].Y - endpointsf[0].Y) / (endpointsf[0].X - endpointsf[1].X) + endpointsf[0].X);
- endx = roundr((rc.top - endpointsf[1].Y) * (endpointsf[1].Y - endpointsf[0].Y) / (endpointsf[0].X - endpointsf[1].X) + endpointsf[1].X);
- width = endx - startx;
- startbottomx = roundr((rc.bottom - endpointsf[0].Y) * (endpointsf[1].Y - endpointsf[0].Y) / (endpointsf[0].X - endpointsf[1].X) + endpointsf[0].X);
- tilt = startx - startbottomx;
-
- if (startx >= startbottomx)
- {
- leftx = rc.left;
- rightx = rc.right + tilt;
- }
- else
- {
- leftx = rc.left + tilt;
- rightx = rc.right;
- }
-
- poly[0].y = rc.bottom;
- poly[1].y = rc.top;
- poly[2].y = rc.top;
- poly[3].y = rc.bottom;
-
- for (x=leftx; x<=rightx; x++)
- {
- ARGB argb = blend_line_gradient(line, (x-startx)/(REAL)width);
- col = ARGB2COLORREF(argb);
- hbrush = CreateSolidBrush(col);
- hprevbrush = SelectObject(graphics->hdc, hbrush);
- poly[0].x = x - tilt - 1;
- poly[1].x = x - 1;
- poly[2].x = x;
- poly[3].x = x - tilt;
- Polygon(graphics->hdc, poly, 4);
- SelectObject(graphics->hdc, hprevbrush);
- DeleteObject(hbrush);
- }
- }
- else if (endpointsi[0].y != endpointsi[1].y)
- {
- /* horizontal-ish gradient */
- int starty, endy; /* y co-ordinates of endpoints shifted to intersect the left of the visible rectangle */
- int startrighty; /* y co-ordinate of start point shifted to intersect the right of the visible rectangle */
- int height;
- COLORREF col;
- HBRUSH hbrush, hprevbrush;
- int topy, bottomy; /* y co-ordinates where the topmost and bottommost gradient lines hit the left of the visible rectangle */
- int y;
- int tilt; /* vertical distance covered by a gradient line */
-
- starty = roundr((rc.left - endpointsf[0].X) * (endpointsf[0].X - endpointsf[1].X) / (endpointsf[1].Y - endpointsf[0].Y) + endpointsf[0].Y);
- endy = roundr((rc.left - endpointsf[1].X) * (endpointsf[0].X - endpointsf[1].X) / (endpointsf[1].Y - endpointsf[0].Y) + endpointsf[1].Y);
- height = endy - starty;
- startrighty = roundr((rc.right - endpointsf[0].X) * (endpointsf[0].X - endpointsf[1].X) / (endpointsf[1].Y - endpointsf[0].Y) + endpointsf[0].Y);
- tilt = starty - startrighty;
-
- if (starty >= startrighty)
- {
- topy = rc.top;
- bottomy = rc.bottom + tilt;
- }
- else
- {
- topy = rc.top + tilt;
- bottomy = rc.bottom;
- }
-
- poly[0].x = rc.right;
- poly[1].x = rc.left;
- poly[2].x = rc.left;
- poly[3].x = rc.right;
-
- for (y=topy; y<=bottomy; y++)
- {
- ARGB argb = blend_line_gradient(line, (y-starty)/(REAL)height);
- col = ARGB2COLORREF(argb);
- hbrush = CreateSolidBrush(col);
- hprevbrush = SelectObject(graphics->hdc, hbrush);
- poly[0].y = y - tilt - 1;
- poly[1].y = y - 1;
- poly[2].y = y;
- poly[3].y = y - tilt;
- Polygon(graphics->hdc, poly, 4);
- SelectObject(graphics->hdc, hprevbrush);
- DeleteObject(hbrush);
- }
- }
- /* else startpoint == endpoint */
- }
- break;
- }
case BrushTypeSolidColor:
{
GpSolidFill *fill = (GpSolidFill*)brush;