return Ok;
}
-static void linegradient_init_transform(GpLineGradient *line)
+static GpStatus create_line_brush(const GpRectF *rect, ARGB startcolor, ARGB endcolor,
+ GpWrapMode wrap, GpLineGradient **line)
+{
+ *line = heap_alloc_zero(sizeof(GpLineGradient));
+ if(!*line) return OutOfMemory;
+
+ (*line)->brush.bt = BrushTypeLinearGradient;
+ (*line)->startcolor = startcolor;
+ (*line)->endcolor = endcolor;
+ (*line)->wrap = wrap;
+ (*line)->gamma = FALSE;
+ (*line)->rect = *rect;
+ (*line)->blendcount = 1;
+ (*line)->blendfac = heap_alloc_zero(sizeof(REAL));
+ (*line)->blendpos = heap_alloc_zero(sizeof(REAL));
+
+ if (!(*line)->blendfac || !(*line)->blendpos)
+ {
+ heap_free((*line)->blendfac);
+ heap_free((*line)->blendpos);
+ heap_free(*line);
+ *line = NULL;
+ return OutOfMemory;
+ }
+
+ (*line)->blendfac[0] = 1.0f;
+ (*line)->blendpos[0] = 1.0f;
+
+ (*line)->pblendcolor = NULL;
+ (*line)->pblendpos = NULL;
+ (*line)->pblendcount = 0;
+
+ GdipSetMatrixElements(&(*line)->transform, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
+
+ return Ok;
+}
+
+static void linegradient_init_transform(const GpPointF *startpoint, const GpPointF *endpoint, GpLineGradient *line)
{
float trans_x = line->rect.X + (line->rect.Width / 2.f);
float trans_y = line->rect.Y + (line->rect.Height / 2.f);
- float dx = line->endpoint.X - line->startpoint.X;
- float dy = line->endpoint.Y - line->startpoint.Y;
+ float dx = endpoint->X - startpoint->X;
+ float dy = endpoint->Y - startpoint->Y;
float t_cos, t_sin, w_ratio, h_ratio;
float h;
GpMatrix rot;
GDIPCONST GpPointF* endpoint, ARGB startcolor, ARGB endcolor,
GpWrapMode wrap, GpLineGradient **line)
{
+ GpStatus stat;
+ GpRectF rect;
+
TRACE("(%s, %s, %x, %x, %d, %p)\n", debugstr_pointf(startpoint),
debugstr_pointf(endpoint), startcolor, endcolor, wrap, line);
if (startpoint->X == endpoint->X && startpoint->Y == endpoint->Y)
return OutOfMemory;
- *line = heap_alloc_zero(sizeof(GpLineGradient));
- if(!*line) return OutOfMemory;
+ rect.X = startpoint->X < endpoint->X ? startpoint->X : endpoint->X;
+ rect.Y = startpoint->Y < endpoint->Y ? startpoint->Y : endpoint->Y;
+ rect.Width = fabs(startpoint->X - endpoint->X);
+ rect.Height = fabs(startpoint->Y - endpoint->Y);
- (*line)->brush.bt = BrushTypeLinearGradient;
-
- (*line)->startpoint.X = startpoint->X;
- (*line)->startpoint.Y = startpoint->Y;
- (*line)->endpoint.X = endpoint->X;
- (*line)->endpoint.Y = endpoint->Y;
- (*line)->startcolor = startcolor;
- (*line)->endcolor = endcolor;
- (*line)->wrap = wrap;
- (*line)->gamma = FALSE;
-
- (*line)->rect.X = (startpoint->X < endpoint->X ? startpoint->X: endpoint->X);
- (*line)->rect.Y = (startpoint->Y < endpoint->Y ? startpoint->Y: endpoint->Y);
- (*line)->rect.Width = fabs(startpoint->X - endpoint->X);
- (*line)->rect.Height = fabs(startpoint->Y - endpoint->Y);
-
- if ((*line)->rect.Width == 0)
- {
- (*line)->rect.X -= (*line)->rect.Height / 2.0f;
- (*line)->rect.Width = (*line)->rect.Height;
- }
- else if ((*line)->rect.Height == 0)
+ if (rect.Width == 0.0f)
{
- (*line)->rect.Y -= (*line)->rect.Width / 2.0f;
- (*line)->rect.Height = (*line)->rect.Width;
+ rect.X -= rect.Height / 2.0f;
+ rect.Width = rect.Height;
}
-
- (*line)->blendcount = 1;
- (*line)->blendfac = heap_alloc_zero(sizeof(REAL));
- (*line)->blendpos = heap_alloc_zero(sizeof(REAL));
-
- if (!(*line)->blendfac || !(*line)->blendpos)
+ else if (rect.Height == 0.0f)
{
- heap_free((*line)->blendfac);
- heap_free((*line)->blendpos);
- heap_free(*line);
- *line = NULL;
- return OutOfMemory;
+ rect.Y -= rect.Width / 2.0f;
+ rect.Height = rect.Width;
}
- (*line)->blendfac[0] = 1.0f;
- (*line)->blendpos[0] = 1.0f;
-
- (*line)->pblendcolor = NULL;
- (*line)->pblendpos = NULL;
- (*line)->pblendcount = 0;
+ stat = create_line_brush(&rect, startcolor, endcolor, wrap, line);
+ if (stat != Ok)
+ return stat;
- linegradient_init_transform(*line);
+ linegradient_init_transform(startpoint, endpoint, *line);
TRACE("<-- %p\n", *line);
ARGB startcolor, ARGB endcolor, LinearGradientMode mode, GpWrapMode wrap,
GpLineGradient **line)
{
- GpPointF start, end;
- float far_x, angle;
- GpStatus stat;
+ float angle;
TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode,
wrap, line);
switch (mode)
{
+ case LinearGradientModeHorizontal:
+ angle = 0.0f;
+ break;
case LinearGradientModeVertical:
angle = 90.0f;
break;
case LinearGradientModeBackwardDiagonal:
angle = 135.0f;
break;
- case LinearGradientModeHorizontal:
- far_x = rect->X + rect->Width;
-
- start.X = min(rect->X, far_x);
- start.Y = rect->Y;
- end.X = max(rect->X, far_x);
- end.Y = rect->Y;
- stat = GdipCreateLineBrush(&start, &end, startcolor, endcolor, wrap, line);
- if (stat == Ok)
- (*line)->rect = *rect;
- return stat;
default:
return InvalidParameter;
}
far_x = rect->X + rect->Width;
far_y = rect->Y + rect->Height;
- if (sin_cos_angle >= 0)
+ if (angle == 0.0f)
+ {
+ start.X = min(rect->X, far_x);
+ start.Y = rect->Y;
+ end.X = max(rect->X, far_x);
+ end.Y = rect->Y;
+ }
+ else if (sin_cos_angle >= 0)
{
start.X = min(rect->X, far_x);
start.Y = min(rect->Y, far_y);
end.Y = max(rect->Y, far_y);
}
- stat = GdipCreateLineBrush(&start, &end, startcolor, endcolor, wrap, line);
+ stat = create_line_brush(rect, startcolor, endcolor, wrap, line);
+ if (stat != Ok || angle == 0.0f)
+ return stat;
- if (stat == Ok)
+ if (sin_cos_angle >= 0)
{
- if (sin_cos_angle >= 0)
- {
- exofs = rect->Height * sin_cos_angle + rect->Width * cos_angle * cos_angle;
- eyofs = rect->Height * sin_angle * sin_angle + rect->Width * sin_cos_angle;
- }
- else
- {
- exofs = rect->Width * sin_angle * sin_angle + rect->Height * sin_cos_angle;
- eyofs = -rect->Width * sin_cos_angle + rect->Height * sin_angle * sin_angle;
- }
-
- if (sin_angle >= 0)
- {
- (*line)->endpoint.X = rect->X + exofs;
- (*line)->endpoint.Y = rect->Y + eyofs;
- }
- else
- {
- (*line)->endpoint.X = (*line)->startpoint.X;
- (*line)->endpoint.Y = (*line)->startpoint.Y;
- (*line)->startpoint.X = rect->X + exofs;
- (*line)->startpoint.Y = rect->Y + eyofs;
- }
+ exofs = rect->Height * sin_cos_angle + rect->Width * cos_angle * cos_angle;
+ eyofs = rect->Height * sin_angle * sin_angle + rect->Width * sin_cos_angle;
+ }
+ else
+ {
+ exofs = rect->Width * sin_angle * sin_angle + rect->Height * sin_cos_angle;
+ eyofs = -rect->Width * sin_cos_angle + rect->Height * sin_angle * sin_angle;
+ }
- linegradient_init_transform(*line);
+ if (sin_angle >= 0)
+ {
+ end.X = rect->X + exofs;
+ end.Y = rect->Y + eyofs;
+ }
+ else
+ {
+ end.X = start.X;
+ end.Y = start.Y;
+ start.X = rect->X + exofs;
+ start.Y = rect->Y + eyofs;
}
+ linegradient_init_transform(&start, &end, *line);
+
return stat;
}