diff --git a/reactos/dll/win32/gdiplus/brush.c b/reactos/dll/win32/gdiplus/brush.c index 8fff98ff304..3395a430665 100644 --- a/reactos/dll/win32/gdiplus/brush.c +++ b/reactos/dll/win32/gdiplus/brush.c @@ -973,7 +973,7 @@ GpStatus WINGDIPAPI GdipGetLineWrapMode(GpLineGradient *brush, GpWrapMode *wrapm { TRACE("(%p, %p)\n", brush, wrapmode); - if(!brush || !wrapmode) + if(!brush || !wrapmode || brush->brush.bt != BrushTypeLinearGradient) return InvalidParameter; *wrapmode = brush->wrap; @@ -986,7 +986,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientBlend(GpPathGradient *brush, REAL *blend, { TRACE("(%p, %p, %p, %d)\n", brush, blend, positions, count); - if(!brush || !blend || !positions || count <= 0) + if(!brush || !blend || !positions || count <= 0 || brush->brush.bt != BrushTypePathGradient) return InvalidParameter; if(count < brush->blendcount) @@ -1004,7 +1004,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientBlendCount(GpPathGradient *brush, INT *co { TRACE("(%p, %p)\n", brush, count); - if(!brush || !count) + if(!brush || !count || brush->brush.bt != BrushTypePathGradient) return InvalidParameter; *count = brush->blendcount; @@ -1017,7 +1017,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientCenterPoint(GpPathGradient *grad, { TRACE("(%p, %p)\n", grad, point); - if(!grad || !point) + if(!grad || !point || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; point->X = grad->center.X; @@ -1052,7 +1052,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientCenterColor(GpPathGradient *grad, { TRACE("(%p,%p)\n", grad, colors); - if (!grad || !colors) + if (!grad || !colors || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; *colors = grad->centercolor; @@ -1065,7 +1065,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientFocusScales(GpPathGradient *grad, { TRACE("(%p, %p, %p)\n", grad, x, y); - if(!grad || !x || !y) + if(!grad || !x || !y || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; *x = grad->focus.X; @@ -1079,7 +1079,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientGammaCorrection(GpPathGradient *grad, { TRACE("(%p, %p)\n", grad, gamma); - if(!grad || !gamma) + if(!grad || !gamma || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; *gamma = grad->gamma; @@ -1104,7 +1104,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient *grad, { TRACE("(%p, %p)\n", grad, count); - if(!grad || !count) + if(!grad || !count || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; *count = grad->path->pathdata.Count; @@ -1118,7 +1118,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect TRACE("(%p, %p)\n", brush, rect); - if(!brush || !rect) + if(!brush || !rect || brush->brush.bt != BrushTypePathGradient) return InvalidParameter; stat = GdipGetPathWorldBounds(brush->path, rect, NULL, NULL); @@ -1154,7 +1154,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorsWithCount(GpPathGradient TRACE("(%p,%p,%p)\n", grad, argb, count); - if(!grad || !argb || !count || (*count < grad->path->pathdata.Count)) + if(!grad || !argb || !count || (*count < grad->path->pathdata.Count) || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; for (i=0; ipath->pathdata.Count; i++) @@ -1174,7 +1174,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientSurroundColorCount(GpPathGradient *brush, { TRACE("(%p, %p)\n", brush, count); - if (!brush || !count) + if (!brush || !count || brush->brush.bt != BrushTypePathGradient) return InvalidParameter; /* Yes, this actually returns the number of points in the path (which is the @@ -1191,7 +1191,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientWrapMode(GpPathGradient *brush, { TRACE("(%p, %p)\n", brush, wrapmode); - if(!brush || !wrapmode) + if(!brush || !wrapmode || brush->brush.bt != BrushTypePathGradient) return InvalidParameter; *wrapmode = brush->wrap; @@ -1302,7 +1302,7 @@ GpStatus WINGDIPAPI GdipSetLineBlend(GpLineGradient *brush, TRACE("(%p, %p, %p, %i)\n", brush, factors, positions, count); - if(!brush || !factors || !positions || count <= 0 || + if(!brush || !factors || !positions || count <= 0 || brush->brush.bt != BrushTypeLinearGradient || (count >= 2 && (positions[0] != 0.0f || positions[count-1] != 1.0f))) return InvalidParameter; @@ -1334,7 +1334,7 @@ GpStatus WINGDIPAPI GdipGetLineBlend(GpLineGradient *brush, REAL *factors, { TRACE("(%p, %p, %p, %i)\n", brush, factors, positions, count); - if (!brush || !factors || !positions || count <= 0) + if (!brush || !factors || !positions || count <= 0 || brush->brush.bt != BrushTypeLinearGradient) return InvalidParameter; if (count < brush->blendcount) @@ -1350,7 +1350,7 @@ GpStatus WINGDIPAPI GdipGetLineBlendCount(GpLineGradient *brush, INT *count) { TRACE("(%p, %p)\n", brush, count); - if (!brush || !count) + if (!brush || !count || brush->brush.bt != BrushTypeLinearGradient) return InvalidParameter; *count = brush->blendcount; @@ -1363,7 +1363,7 @@ GpStatus WINGDIPAPI GdipSetLineGammaCorrection(GpLineGradient *line, { TRACE("(%p, %d)\n", line, usegamma); - if(!line) + if(!line || line->brush.bt != BrushTypeLinearGradient) return InvalidParameter; line->gamma = usegamma; @@ -1385,7 +1385,7 @@ GpStatus WINGDIPAPI GdipSetLineSigmaBlend(GpLineGradient *line, REAL focus, TRACE("(%p, %0.2f, %0.2f)\n", line, focus, scale); - if(!line || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0) + if(!line || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0 || line->brush.bt != BrushTypeLinearGradient) return InvalidParameter; /* we want 2 standard deviations */ @@ -1432,7 +1432,7 @@ GpStatus WINGDIPAPI GdipSetLineWrapMode(GpLineGradient *line, { TRACE("(%p, %d)\n", line, wrap); - if(!line || wrap == WrapModeClamp) + if(!line || wrap == WrapModeClamp || line->brush.bt != BrushTypeLinearGradient) return InvalidParameter; line->wrap = wrap; @@ -1447,7 +1447,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientBlend(GpPathGradient *brush, GDIPCONST RE TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count); - if(!brush || !blend || !pos || count <= 0 || + if(!brush || !blend || !pos || count <= 0 || brush->brush.bt != BrushTypePathGradient || (count >= 2 && (pos[0] != 0.0f || pos[count-1] != 1.0f))) return InvalidParameter; @@ -1483,7 +1483,8 @@ GpStatus WINGDIPAPI GdipSetPathGradientLinearBlend(GpPathGradient *brush, TRACE("(%p,%0.2f,%0.2f)\n", brush, focus, scale); - if (!brush) return InvalidParameter; + if (!brush || brush->brush.bt != BrushTypePathGradient) + return InvalidParameter; if (focus != 0.0) { @@ -1513,7 +1514,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientPresetBlend(GpPathGradient *brush, REAL *new_pos; TRACE("(%p,%p,%p,%i)\n", brush, blend, pos, count); - if (!brush || !blend || !pos || count < 2 || + if (!brush || !blend || !pos || count < 2 || brush->brush.bt != BrushTypePathGradient || pos[0] != 0.0f || pos[count-1] != 1.0f) { return InvalidParameter; @@ -1549,7 +1550,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientPresetBlend(GpPathGradient *brush, if (count < 0) return OutOfMemory; - if (!brush || !blend || !pos || count < 2) + if (!brush || !blend || !pos || count < 2 || brush->brush.bt != BrushTypePathGradient) return InvalidParameter; if (brush->pblendcount == 0) @@ -1573,7 +1574,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientPresetBlendCount(GpPathGradient *brush, { TRACE("(%p,%p)\n", brush, count); - if (!brush || !count) + if (!brush || !count || brush->brush.bt != BrushTypePathGradient) return InvalidParameter; *count = brush->pblendcount; @@ -1586,7 +1587,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientCenterColor(GpPathGradient *grad, { TRACE("(%p, %x)\n", grad, argb); - if(!grad) + if(!grad || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; grad->centercolor = argb; @@ -1598,7 +1599,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientCenterPoint(GpPathGradient *grad, { TRACE("(%p, %s)\n", grad, debugstr_pointf(point)); - if(!grad || !point) + if(!grad || !point || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; grad->center.X = point->X; @@ -1628,7 +1629,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientFocusScales(GpPathGradient *grad, { TRACE("(%p, %.2f, %.2f)\n", grad, x, y); - if(!grad) + if(!grad || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; grad->focus.X = x; @@ -1642,7 +1643,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientGammaCorrection(GpPathGradient *grad, { TRACE("(%p, %d)\n", grad, gamma); - if(!grad) + if(!grad || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; grad->gamma = gamma; @@ -1664,7 +1665,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientSigmaBlend(GpPathGradient *grad, TRACE("(%p,%0.2f,%0.2f)\n", grad, focus, scale); - if(!grad || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0) + if(!grad || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0 || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; /* we want 2 standard deviations */ @@ -1714,7 +1715,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientSurroundColorsWithCount(GpPathGradient TRACE("(%p,%p,%p)\n", grad, argb, count); - if(!grad || !argb || !count || (*count <= 0) || + if(!grad || !argb || !count || (*count <= 0) || grad->brush.bt != BrushTypePathGradient || (*count > grad->path->pathdata.Count)) return InvalidParameter; @@ -1750,7 +1751,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientWrapMode(GpPathGradient *grad, { TRACE("(%p, %d)\n", grad, wrap); - if(!grad) + if(!grad || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; grad->wrap = wrap; @@ -1763,7 +1764,7 @@ GpStatus WINGDIPAPI GdipSetPathGradientTransform(GpPathGradient *grad, { TRACE("(%p,%p)\n", grad, matrix); - if (!grad || !matrix) + if (!grad || !matrix || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; grad->transform = *matrix; @@ -1776,7 +1777,7 @@ GpStatus WINGDIPAPI GdipGetPathGradientTransform(GpPathGradient *grad, { TRACE("(%p,%p)\n", grad, matrix); - if (!grad || !matrix) + if (!grad || !matrix || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; *matrix = grad->transform; @@ -1789,7 +1790,7 @@ GpStatus WINGDIPAPI GdipMultiplyPathGradientTransform(GpPathGradient *grad, { TRACE("(%p,%p,%i)\n", grad, matrix, order); - if (!grad) + if (!grad || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; return GdipMultiplyMatrix(&grad->transform, matrix, order); @@ -1799,7 +1800,7 @@ GpStatus WINGDIPAPI GdipResetPathGradientTransform(GpPathGradient *grad) { TRACE("(%p)\n", grad); - if (!grad) + if (!grad || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; return GdipSetMatrixElements(&grad->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); @@ -1810,7 +1811,7 @@ GpStatus WINGDIPAPI GdipRotatePathGradientTransform(GpPathGradient *grad, { TRACE("(%p,%0.2f,%i)\n", grad, angle, order); - if (!grad) + if (!grad || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; return GdipRotateMatrix(&grad->transform, angle, order); @@ -1821,7 +1822,7 @@ GpStatus WINGDIPAPI GdipScalePathGradientTransform(GpPathGradient *grad, { TRACE("(%p,%0.2f,%0.2f,%i)\n", grad, sx, sy, order); - if (!grad) + if (!grad || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; return GdipScaleMatrix(&grad->transform, sx, sy, order); @@ -1832,7 +1833,7 @@ GpStatus WINGDIPAPI GdipTranslatePathGradientTransform(GpPathGradient *grad, { TRACE("(%p,%0.2f,%0.2f,%i)\n", grad, dx, dy, order); - if (!grad) + if (!grad || grad->brush.bt != BrushTypePathGradient) return InvalidParameter; return GdipTranslateMatrix(&grad->transform, dx, dy, order); @@ -1887,7 +1888,7 @@ GpStatus WINGDIPAPI GdipSetLineColors(GpLineGradient *brush, ARGB color1, { TRACE("(%p, %x, %x)\n", brush, color1, color2); - if(!brush) + if(!brush || brush->brush.bt != BrushTypeLinearGradient) return InvalidParameter; brush->startcolor = color1; @@ -1900,7 +1901,7 @@ GpStatus WINGDIPAPI GdipGetLineColors(GpLineGradient *brush, ARGB *colors) { TRACE("(%p, %p)\n", brush, colors); - if(!brush || !colors) + if(!brush || !colors || brush->brush.bt != BrushTypeLinearGradient) return InvalidParameter; colors[0] = brush->startcolor; @@ -1962,7 +1963,7 @@ GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush, REAL *new_pos; TRACE("(%p,%p,%p,%i)\n", brush, blend, positions, count); - if (!brush || !blend || !positions || count < 2 || + if (!brush || !blend || !positions || count < 2 || brush->brush.bt != BrushTypeLinearGradient || positions[0] != 0.0f || positions[count-1] != 1.0f) { return InvalidParameter; @@ -1993,7 +1994,7 @@ GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush, GpStatus WINGDIPAPI GdipGetLinePresetBlend(GpLineGradient *brush, ARGB *blend, REAL* positions, INT count) { - if (!brush || !blend || !positions || count < 2) + if (!brush || !blend || !positions || count < 2 || brush->brush.bt != BrushTypeLinearGradient) return InvalidParameter; if (brush->pblendcount == 0) @@ -2011,7 +2012,7 @@ GpStatus WINGDIPAPI GdipGetLinePresetBlend(GpLineGradient *brush, GpStatus WINGDIPAPI GdipGetLinePresetBlendCount(GpLineGradient *brush, INT *count) { - if (!brush || !count) + if (!brush || !count || brush->brush.bt != BrushTypeLinearGradient) return InvalidParameter; *count = brush->pblendcount; @@ -2113,7 +2114,7 @@ GpStatus WINGDIPAPI GdipGetLineRect(GpLineGradient *brush, GpRectF *rect) { TRACE("(%p, %p)\n", brush, rect); - if(!brush || !rect) + if(!brush || !rect || brush->brush.bt != BrushTypeLinearGradient) return InvalidParameter; *rect = brush->rect; @@ -2150,7 +2151,7 @@ GpStatus WINGDIPAPI GdipRotateLineTransform(GpLineGradient* brush, TRACE("(%p,%0.2f,%u)\n", brush, angle, order); - if(!brush) + if(!brush || brush->brush.bt != BrushTypeLinearGradient) return InvalidParameter; if(!(calls++)) diff --git a/reactos/dll/win32/gdiplus/font.c b/reactos/dll/win32/gdiplus/font.c index 51d4e41e58a..e8971047359 100644 --- a/reactos/dll/win32/gdiplus/font.c +++ b/reactos/dll/win32/gdiplus/font.c @@ -979,12 +979,12 @@ GpStatus WINGDIPAPI GdipIsStyleAvailable(GDIPCONST GpFontFamily* family, *IsStyleAvailable = FALSE; - hdc = GetDC(0); + hdc = CreateCompatibleDC(0); if(!EnumFontFamiliesW(hdc, family->FamilyName, font_has_style_proc, (LPARAM)style)) *IsStyleAvailable = TRUE; - ReleaseDC(0, hdc); + DeleteDC(hdc); return Ok; } @@ -1276,7 +1276,7 @@ GpStatus WINGDIPAPI GdipPrivateAddMemoryFont(GpFontCollection* fontCollection, HDC hdc; LOGFONTW lfw; - hdc = GetDC(0); + hdc = CreateCompatibleDC(0); lfw.lfCharSet = DEFAULT_CHARSET; lstrcpyW(lfw.lfFaceName, name); @@ -1288,7 +1288,7 @@ GpStatus WINGDIPAPI GdipPrivateAddMemoryFont(GpFontCollection* fontCollection, return OutOfMemory; } - ReleaseDC(0, hdc); + DeleteDC(hdc); } return Ok; } @@ -1403,7 +1403,7 @@ GpStatus WINGDIPAPI GdipNewInstalledFontCollection( HDC hdc; LOGFONTW lfw; - hdc = GetDC(0); + hdc = CreateCompatibleDC(0); lfw.lfCharSet = DEFAULT_CHARSET; lfw.lfFaceName[0] = 0; @@ -1416,7 +1416,7 @@ GpStatus WINGDIPAPI GdipNewInstalledFontCollection( return OutOfMemory; } - ReleaseDC(0, hdc); + DeleteDC(hdc); } *fontCollection = &installedFontCollection; diff --git a/reactos/dll/win32/gdiplus/gdiplus.c b/reactos/dll/win32/gdiplus/gdiplus.c index 1eebacb4e81..57222a4345e 100644 --- a/reactos/dll/win32/gdiplus/gdiplus.c +++ b/reactos/dll/win32/gdiplus/gdiplus.c @@ -442,9 +442,9 @@ void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height, for (x=0; xclip, graphics, hrgn); + return GdipGetRegionHRgn(graphics->clip, NULL, hrgn); } /* Draw non-premultiplied ARGB data to the given graphics object */ @@ -427,8 +415,11 @@ static GpStatus alpha_blend_hdc_pixels(GpGraphics *graphics, INT dst_x, INT dst_ hbitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&temp_bits, NULL, 0); - convert_32bppARGB_to_32bppPARGB(src_width, src_height, temp_bits, - 4 * src_width, src, src_stride); + if (GetDeviceCaps(graphics->hdc, SHADEBLENDCAPS) == SB_NONE) + memcpy(temp_bits, src, src_width * src_height * 4); + else + convert_32bppARGB_to_32bppPARGB(src_width, src_height, temp_bits, + 4 * src_width, src, src_stride); SelectObject(hdc, hbitmap); gdi_alpha_blend(graphics, dst_x, dst_y, src_width, src_height, @@ -446,7 +437,8 @@ static GpStatus alpha_blend_pixels_hrgn(GpGraphics *graphics, INT dst_x, INT dst if (graphics->image && graphics->image->type == ImageTypeBitmap) { - int i, size; + DWORD i; + int size; RGNDATA *rgndata; RECT *rects; HRGN hrgn, visible_rgn; @@ -659,7 +651,8 @@ static int color_is_gray(ARGB color) static void apply_image_attributes(const GpImageAttributes *attributes, LPBYTE data, UINT width, UINT height, INT stride, ColorAdjustType type) { - UINT x, y, i; + UINT x, y; + INT i; if (attributes->colorkeys[type].enabled || attributes->colorkeys[ColorAdjustTypeDefault].enabled) @@ -1471,27 +1464,6 @@ static GpStatus brush_fill_pixels(GpGraphics *graphics, GpBrush *brush, } } -/* GdipDrawPie/GdipFillPie helper function */ -static void draw_pie(GpGraphics *graphics, REAL x, REAL y, REAL width, - REAL height, REAL startAngle, REAL sweepAngle) -{ - GpPointF ptf[4]; - POINT pti[4]; - - ptf[0].X = x; - ptf[0].Y = y; - ptf[1].X = x + width; - ptf[1].Y = y + height; - - deg2xy(startAngle+sweepAngle, x + width / 2.0, y + width / 2.0, &ptf[2].X, &ptf[2].Y); - deg2xy(startAngle, x + width / 2.0, y + width / 2.0, &ptf[3].X, &ptf[3].Y); - - transform_and_round_points(graphics, pti, ptf, 4); - - Pie(graphics->hdc, pti[0].x, pti[0].y, pti[1].x, pti[1].y, pti[2].x, - pti[2].y, pti[3].x, pti[3].y); -} - /* Draws the linecap the specified color and size on the hdc. The linecap is in * direction of the line from x1, y1 to x2, y2 and is anchored on x2, y2. Probably * should not be called on an hdc that has a path you care about. */ @@ -1728,63 +1700,6 @@ static void shorten_line_amt(REAL x1, REAL y1, REAL *x2, REAL *y2, REAL amt) shorten_line_percent(x1, y1, x2, y2, percent); } -/* Draws lines between the given points, and if caps is true then draws an endcap - * at the end of the last line. */ -static GpStatus draw_polyline(GpGraphics *graphics, GpPen *pen, - GDIPCONST GpPointF * pt, INT count, BOOL caps) -{ - POINT *pti = NULL; - GpPointF *ptcopy = NULL; - GpStatus status = GenericError; - - if(!count) - return Ok; - - pti = GdipAlloc(count * sizeof(POINT)); - ptcopy = GdipAlloc(count * sizeof(GpPointF)); - - if(!pti || !ptcopy){ - status = OutOfMemory; - goto end; - } - - memcpy(ptcopy, pt, count * sizeof(GpPointF)); - - if(caps){ - if(pen->endcap == LineCapArrowAnchor) - shorten_line_amt(ptcopy[count-2].X, ptcopy[count-2].Y, - &ptcopy[count-1].X, &ptcopy[count-1].Y, pen->width); - else if((pen->endcap == LineCapCustom) && pen->customend) - shorten_line_amt(ptcopy[count-2].X, ptcopy[count-2].Y, - &ptcopy[count-1].X, &ptcopy[count-1].Y, - pen->customend->inset * pen->width); - - if(pen->startcap == LineCapArrowAnchor) - shorten_line_amt(ptcopy[1].X, ptcopy[1].Y, - &ptcopy[0].X, &ptcopy[0].Y, pen->width); - else if((pen->startcap == LineCapCustom) && pen->customstart) - shorten_line_amt(ptcopy[1].X, ptcopy[1].Y, - &ptcopy[0].X, &ptcopy[0].Y, - pen->customstart->inset * pen->width); - - draw_cap(graphics, get_gdi_brush_color(pen->brush), pen->endcap, pen->width, pen->customend, - pt[count - 2].X, pt[count - 2].Y, pt[count - 1].X, pt[count - 1].Y); - draw_cap(graphics, get_gdi_brush_color(pen->brush), pen->startcap, pen->width, pen->customstart, - pt[1].X, pt[1].Y, pt[0].X, pt[0].Y); - } - - transform_and_round_points(graphics, pti, ptcopy, count); - - if(Polyline(graphics->hdc, pti, count)) - status = Ok; - -end: - GdipFree(pti); - GdipFree(ptcopy); - - return status; -} - /* Conducts a linear search to find the bezier points that will back off * the endpoint of the curve by a distance of amt. Linear search works * better than binary in this case because there are multiple solutions, @@ -1828,66 +1743,6 @@ static void shorten_bezier_amt(GpPointF * pt, REAL amt, BOOL rev) } } -/* Draws bezier curves between given points, and if caps is true then draws an - * endcap at the end of the last line. */ -static GpStatus draw_polybezier(GpGraphics *graphics, GpPen *pen, - GDIPCONST GpPointF * pt, INT count, BOOL caps) -{ - POINT *pti; - GpPointF *ptcopy; - GpStatus status = GenericError; - - if(!count) - return Ok; - - pti = GdipAlloc(count * sizeof(POINT)); - ptcopy = GdipAlloc(count * sizeof(GpPointF)); - - if(!pti || !ptcopy){ - status = OutOfMemory; - goto end; - } - - memcpy(ptcopy, pt, count * sizeof(GpPointF)); - - if(caps){ - if(pen->endcap == LineCapArrowAnchor) - shorten_bezier_amt(&ptcopy[count-4], pen->width, FALSE); - else if((pen->endcap == LineCapCustom) && pen->customend) - shorten_bezier_amt(&ptcopy[count-4], pen->width * pen->customend->inset, - FALSE); - - if(pen->startcap == LineCapArrowAnchor) - shorten_bezier_amt(ptcopy, pen->width, TRUE); - else if((pen->startcap == LineCapCustom) && pen->customstart) - shorten_bezier_amt(ptcopy, pen->width * pen->customstart->inset, TRUE); - - /* the direction of the line cap is parallel to the direction at the - * end of the bezier (which, if it has been shortened, is not the same - * as the direction from pt[count-2] to pt[count-1]) */ - draw_cap(graphics, get_gdi_brush_color(pen->brush), pen->endcap, pen->width, pen->customend, - pt[count - 1].X - (ptcopy[count - 1].X - ptcopy[count - 2].X), - pt[count - 1].Y - (ptcopy[count - 1].Y - ptcopy[count - 2].Y), - pt[count - 1].X, pt[count - 1].Y); - - draw_cap(graphics, get_gdi_brush_color(pen->brush), pen->startcap, pen->width, pen->customstart, - pt[0].X - (ptcopy[0].X - ptcopy[1].X), - pt[0].Y - (ptcopy[0].Y - ptcopy[1].Y), pt[0].X, pt[0].Y); - } - - transform_and_round_points(graphics, pti, ptcopy, count); - - PolyBezier(graphics->hdc, pti, count); - - status = Ok; - -end: - GdipFree(pti); - GdipFree(ptcopy); - - return status; -} - /* Draws a combination of bezier curves and lines between points. */ static GpStatus draw_poly(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF * pt, GDIPCONST BYTE * types, INT count, BOOL caps) @@ -2291,10 +2146,8 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra TRACE("(%p, %p, %p)\n", hdc, hDevice, graphics); - if(hDevice != NULL) { + if(hDevice != NULL) FIXME("Don't know how to handle parameter hDevice\n"); - return NotImplemented; - } if(hdc == NULL) return OutOfMemory; @@ -2359,6 +2212,9 @@ GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics) (*graphics)->hwnd = NULL; (*graphics)->owndc = FALSE; (*graphics)->image = image; + /* We have to store the image type here because the image may be freed + * before GdipDeleteGraphics is called, and metafiles need special treatment. */ + (*graphics)->image_type = image->type; (*graphics)->smoothing = SmoothingModeDefault; (*graphics)->compqual = CompositingQualityDefault; (*graphics)->interpolation = InterpolationModeBilinear; @@ -2553,7 +2409,7 @@ GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics) if(!graphics) return InvalidParameter; if(graphics->busy) return ObjectBusy; - if (graphics->image && graphics->image->type == ImageTypeMetafile) + if (graphics->image && graphics->image_type == ImageTypeMetafile) { stat = METAFILE_GraphicsDeleted((GpMetafile*)graphics->image); if (stat != Ok) @@ -2577,9 +2433,8 @@ GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics) GpStatus WINGDIPAPI GdipDrawArc(GpGraphics *graphics, GpPen *pen, REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle) { - INT save_state, num_pts; - GpPointF points[MAX_ARC_PTS]; - GpStatus retval; + GpStatus status; + GpPath *path; TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n", graphics, pen, x, y, width, height, startAngle, sweepAngle); @@ -2590,21 +2445,15 @@ GpStatus WINGDIPAPI GdipDrawArc(GpGraphics *graphics, GpPen *pen, REAL x, if(graphics->busy) return ObjectBusy; - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } + status = GdipCreatePath(FillModeAlternate, &path); + if (status != Ok) return status; - num_pts = arc2polybezier(points, x, y, width, height, startAngle, sweepAngle); + status = GdipAddPathArc(path, x, y, width, height, startAngle, sweepAngle); + if (status == Ok) + status = GdipDrawPath(graphics, pen, path); - save_state = prepare_dc(graphics, pen); - - retval = draw_polybezier(graphics, pen, points, num_pts, TRUE); - - restore_dc(graphics, save_state); - - return retval; + GdipDeletePath(path); + return status; } GpStatus WINGDIPAPI GdipDrawArcI(GpGraphics *graphics, GpPen *pen, INT x, @@ -2619,9 +2468,7 @@ GpStatus WINGDIPAPI GdipDrawArcI(GpGraphics *graphics, GpPen *pen, INT x, GpStatus WINGDIPAPI GdipDrawBezier(GpGraphics *graphics, GpPen *pen, REAL x1, REAL y1, REAL x2, REAL y2, REAL x3, REAL y3, REAL x4, REAL y4) { - INT save_state; GpPointF pt[4]; - GpStatus retval; TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n", graphics, pen, x1, y1, x2, y2, x3, y3, x4, y4); @@ -2632,12 +2479,6 @@ GpStatus WINGDIPAPI GdipDrawBezier(GpGraphics *graphics, GpPen *pen, REAL x1, if(graphics->busy) return ObjectBusy; - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } - pt[0].X = x1; pt[0].Y = y1; pt[1].X = x2; @@ -2646,61 +2487,23 @@ GpStatus WINGDIPAPI GdipDrawBezier(GpGraphics *graphics, GpPen *pen, REAL x1, pt[2].Y = y3; pt[3].X = x4; pt[3].Y = y4; - - save_state = prepare_dc(graphics, pen); - - retval = draw_polybezier(graphics, pen, pt, 4, TRUE); - - restore_dc(graphics, save_state); - - return retval; + return GdipDrawBeziers(graphics, pen, pt, 4); } GpStatus WINGDIPAPI GdipDrawBezierI(GpGraphics *graphics, GpPen *pen, INT x1, INT y1, INT x2, INT y2, INT x3, INT y3, INT x4, INT y4) { - INT save_state; - GpPointF pt[4]; - GpStatus retval; - TRACE("(%p, %p, %d, %d, %d, %d, %d, %d, %d, %d)\n", graphics, pen, x1, y1, x2, y2, x3, y3, x4, y4); - if(!graphics || !pen) - return InvalidParameter; - - if(graphics->busy) - return ObjectBusy; - - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } - - pt[0].X = x1; - pt[0].Y = y1; - pt[1].X = x2; - pt[1].Y = y2; - pt[2].X = x3; - pt[2].Y = y3; - pt[3].X = x4; - pt[3].Y = y4; - - save_state = prepare_dc(graphics, pen); - - retval = draw_polybezier(graphics, pen, pt, 4, TRUE); - - restore_dc(graphics, save_state); - - return retval; + return GdipDrawBezier(graphics, pen, (REAL)x1, (REAL)y1, (REAL)x2, (REAL)y2, (REAL)x3, (REAL)y3, (REAL)x4, (REAL)y4); } GpStatus WINGDIPAPI GdipDrawBeziers(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points, INT count) { - INT i; - GpStatus ret; + GpStatus status; + GpPath *path; TRACE("(%p, %p, %p, %d)\n", graphics, pen, points, count); @@ -2710,17 +2513,15 @@ GpStatus WINGDIPAPI GdipDrawBeziers(GpGraphics *graphics, GpPen *pen, if(graphics->busy) return ObjectBusy; - for(i = 0; i < floor(count / 4); i++){ - ret = GdipDrawBezier(graphics, pen, - points[4*i].X, points[4*i].Y, - points[4*i + 1].X, points[4*i + 1].Y, - points[4*i + 2].X, points[4*i + 2].Y, - points[4*i + 3].X, points[4*i + 3].Y); - if(ret != Ok) - return ret; - } + status = GdipCreatePath(FillModeAlternate, &path); + if (status != Ok) return status; - return Ok; + status = GdipAddPathBeziers(path, points, count); + if (status == Ok) + status = GdipDrawPath(graphics, pen, path); + + GdipDeletePath(path); + return status; } GpStatus WINGDIPAPI GdipDrawBeziersI(GpGraphics *graphics, GpPen *pen, @@ -2774,7 +2575,7 @@ GpStatus WINGDIPAPI GdipDrawClosedCurve2(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points, INT count, REAL tension) { GpPath *path; - GpStatus stat; + GpStatus status; TRACE("(%p, %p, %p, %d, %.2f)\n", graphics, pen, points, count, tension); @@ -2784,20 +2585,16 @@ GpStatus WINGDIPAPI GdipDrawClosedCurve2(GpGraphics *graphics, GpPen *pen, if(graphics->busy) return ObjectBusy; - if((stat = GdipCreatePath(FillModeAlternate, &path)) != Ok) - return stat; + status = GdipCreatePath(FillModeAlternate, &path); + if (status != Ok) return status; - stat = GdipAddPathClosedCurve2(path, points, count, tension); - if(stat != Ok){ - GdipDeletePath(path); - return stat; - } - - stat = GdipDrawPath(graphics, pen, path); + status = GdipAddPathClosedCurve2(path, points, count, tension); + if (status == Ok) + status = GdipDrawPath(graphics, pen, path); GdipDeletePath(path); - return stat; + return status; } GpStatus WINGDIPAPI GdipDrawClosedCurve2I(GpGraphics *graphics, GpPen *pen, @@ -2867,11 +2664,8 @@ GpStatus WINGDIPAPI GdipDrawCurveI(GpGraphics *graphics, GpPen *pen, GpStatus WINGDIPAPI GdipDrawCurve2(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points, INT count, REAL tension) { - /* PolyBezier expects count*3-2 points. */ - INT i, len_pt = count*3-2, save_state; - GpPointF *pt; - REAL x1, x2, y1, y2; - GpStatus retval; + GpPath *path; + GpStatus status; TRACE("(%p, %p, %p, %d, %.2f)\n", graphics, pen, points, count, tension); @@ -2884,53 +2678,15 @@ GpStatus WINGDIPAPI GdipDrawCurve2(GpGraphics *graphics, GpPen *pen, if(count < 2) return InvalidParameter; - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } + status = GdipCreatePath(FillModeAlternate, &path); + if (status != Ok) return status; - pt = GdipAlloc(len_pt * sizeof(GpPointF)); - if(!pt) - return OutOfMemory; + status = GdipAddPathCurve2(path, points, count, tension); + if (status == Ok) + status = GdipDrawPath(graphics, pen, path); - tension = tension * TENSION_CONST; - - calc_curve_bezier_endp(points[0].X, points[0].Y, points[1].X, points[1].Y, - tension, &x1, &y1); - - pt[0].X = points[0].X; - pt[0].Y = points[0].Y; - pt[1].X = x1; - pt[1].Y = y1; - - for(i = 0; i < count-2; i++){ - calc_curve_bezier(&(points[i]), tension, &x1, &y1, &x2, &y2); - - pt[3*i+2].X = x1; - pt[3*i+2].Y = y1; - pt[3*i+3].X = points[i+1].X; - pt[3*i+3].Y = points[i+1].Y; - pt[3*i+4].X = x2; - pt[3*i+4].Y = y2; - } - - calc_curve_bezier_endp(points[count-1].X, points[count-1].Y, - points[count-2].X, points[count-2].Y, tension, &x1, &y1); - - pt[len_pt-2].X = x1; - pt[len_pt-2].Y = y1; - pt[len_pt-1].X = points[count-1].X; - pt[len_pt-1].Y = points[count-1].Y; - - save_state = prepare_dc(graphics, pen); - - retval = draw_polybezier(graphics, pen, pt, len_pt, TRUE); - - GdipFree(pt); - restore_dc(graphics, save_state); - - return retval; + GdipDeletePath(path); + return status; } GpStatus WINGDIPAPI GdipDrawCurve2I(GpGraphics *graphics, GpPen *pen, @@ -2993,9 +2749,8 @@ GpStatus WINGDIPAPI GdipDrawCurve3I(GpGraphics *graphics, GpPen *pen, GpStatus WINGDIPAPI GdipDrawEllipse(GpGraphics *graphics, GpPen *pen, REAL x, REAL y, REAL width, REAL height) { - INT save_state; - GpPointF ptf[2]; - POINT pti[2]; + GpPath *path; + GpStatus status; TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f)\n", graphics, pen, x, y, width, height); @@ -3005,27 +2760,15 @@ GpStatus WINGDIPAPI GdipDrawEllipse(GpGraphics *graphics, GpPen *pen, REAL x, if(graphics->busy) return ObjectBusy; - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } + status = GdipCreatePath(FillModeAlternate, &path); + if (status != Ok) return status; - ptf[0].X = x; - ptf[0].Y = y; - ptf[1].X = x + width; - ptf[1].Y = y + height; + status = GdipAddPathEllipse(path, x, y, width, height); + if (status == Ok) + status = GdipDrawPath(graphics, pen, path); - save_state = prepare_dc(graphics, pen); - SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH)); - - transform_and_round_points(graphics, pti, ptf, 2); - - Ellipse(graphics->hdc, pti[0].x, pti[0].y, pti[1].x, pti[1].y); - - restore_dc(graphics, save_state); - - return Ok; + GdipDeletePath(path); + return status; } GpStatus WINGDIPAPI GdipDrawEllipseI(GpGraphics *graphics, GpPen *pen, INT x, @@ -3070,6 +2813,8 @@ GpStatus WINGDIPAPI GdipDrawImagePointRect(GpGraphics *graphics, GpImage *image, TRACE("(%p, %p, %f, %f, %f, %f, %f, %f, %d)\n", graphics, image, x, y, srcx, srcy, srcwidth, srcheight, srcUnit); + if (!graphics || !image) return InvalidParameter; + scale_x = units_scale(srcUnit, graphics->unit, graphics->xres); scale_x *= graphics->xres / image->xres; scale_y = units_scale(srcUnit, graphics->unit, graphics->yres); @@ -3542,78 +3287,30 @@ GpStatus WINGDIPAPI GdipDrawImageRectI(GpGraphics *graphics, GpImage *image, GpStatus WINGDIPAPI GdipDrawLine(GpGraphics *graphics, GpPen *pen, REAL x1, REAL y1, REAL x2, REAL y2) { - INT save_state; GpPointF pt[2]; - GpStatus retval; TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f)\n", graphics, pen, x1, y1, x2, y2); - if(!pen || !graphics) - return InvalidParameter; - - if(graphics->busy) - return ObjectBusy; - - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } - pt[0].X = x1; pt[0].Y = y1; pt[1].X = x2; pt[1].Y = y2; - - save_state = prepare_dc(graphics, pen); - - retval = draw_polyline(graphics, pen, pt, 2, TRUE); - - restore_dc(graphics, save_state); - - return retval; + return GdipDrawLines(graphics, pen, pt, 2); } GpStatus WINGDIPAPI GdipDrawLineI(GpGraphics *graphics, GpPen *pen, INT x1, INT y1, INT x2, INT y2) { - INT save_state; - GpPointF pt[2]; - GpStatus retval; - TRACE("(%p, %p, %d, %d, %d, %d)\n", graphics, pen, x1, y1, x2, y2); - if(!pen || !graphics) - return InvalidParameter; - - if(graphics->busy) - return ObjectBusy; - - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } - - pt[0].X = (REAL)x1; - pt[0].Y = (REAL)y1; - pt[1].X = (REAL)x2; - pt[1].Y = (REAL)y2; - - save_state = prepare_dc(graphics, pen); - - retval = draw_polyline(graphics, pen, pt, 2, TRUE); - - restore_dc(graphics, save_state); - - return retval; + return GdipDrawLine(graphics, pen, (REAL)x1, (REAL)y1, (REAL)x2, (REAL)y2); } GpStatus WINGDIPAPI GdipDrawLines(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points, INT count) { - INT save_state; - GpStatus retval; + GpStatus status; + GpPath *path; TRACE("(%p, %p, %p, %d)\n", graphics, pen, points, count); @@ -3623,43 +3320,26 @@ GpStatus WINGDIPAPI GdipDrawLines(GpGraphics *graphics, GpPen *pen, GDIPCONST if(graphics->busy) return ObjectBusy; - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } + status = GdipCreatePath(FillModeAlternate, &path); + if (status != Ok) return status; - save_state = prepare_dc(graphics, pen); + status = GdipAddPathLine2(path, points, count); + if (status == Ok) + status = GdipDrawPath(graphics, pen, path); - retval = draw_polyline(graphics, pen, points, count, TRUE); - - restore_dc(graphics, save_state); - - return retval; + GdipDeletePath(path); + return status; } GpStatus WINGDIPAPI GdipDrawLinesI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points, INT count) { - INT save_state; GpStatus retval; - GpPointF *ptf = NULL; + GpPointF *ptf; int i; TRACE("(%p, %p, %p, %d)\n", graphics, pen, points, count); - if(!pen || !graphics || (count < 2)) - return InvalidParameter; - - if(graphics->busy) - return ObjectBusy; - - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } - ptf = GdipAlloc(count * sizeof(GpPointF)); if(!ptf) return OutOfMemory; @@ -3668,11 +3348,7 @@ GpStatus WINGDIPAPI GdipDrawLinesI(GpGraphics *graphics, GpPen *pen, GDIPCONST ptf[i].Y = (REAL) points[i].Y; } - save_state = prepare_dc(graphics, pen); - - retval = draw_polyline(graphics, pen, ptf, count, TRUE); - - restore_dc(graphics, save_state); + retval = GdipDrawLines(graphics, pen, ptf, count); GdipFree(ptf); return retval; @@ -3710,7 +3386,8 @@ GpStatus WINGDIPAPI GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path) GpStatus WINGDIPAPI GdipDrawPie(GpGraphics *graphics, GpPen *pen, REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle) { - INT save_state; + GpStatus status; + GpPath *path; TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n", graphics, pen, x, y, width, height, startAngle, sweepAngle); @@ -3721,20 +3398,15 @@ GpStatus WINGDIPAPI GdipDrawPie(GpGraphics *graphics, GpPen *pen, REAL x, if(graphics->busy) return ObjectBusy; - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } + status = GdipCreatePath(FillModeAlternate, &path); + if (status != Ok) return status; - save_state = prepare_dc(graphics, pen); - SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH)); + status = GdipAddPathPie(path, x, y, width, height, startAngle, sweepAngle); + if (status == Ok) + status = GdipDrawPath(graphics, pen, path); - draw_pie(graphics, x, y, width, height, startAngle, sweepAngle); - - restore_dc(graphics, save_state); - - return Ok; + GdipDeletePath(path); + return status; } GpStatus WINGDIPAPI GdipDrawPieI(GpGraphics *graphics, GpPen *pen, INT x, @@ -3749,9 +3421,8 @@ GpStatus WINGDIPAPI GdipDrawPieI(GpGraphics *graphics, GpPen *pen, INT x, GpStatus WINGDIPAPI GdipDrawRectangle(GpGraphics *graphics, GpPen *pen, REAL x, REAL y, REAL width, REAL height) { - INT save_state; - GpPointF ptf[4]; - POINT pti[4]; + GpStatus status; + GpPath *path; TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f)\n", graphics, pen, x, y, width, height); @@ -3761,30 +3432,15 @@ GpStatus WINGDIPAPI GdipDrawRectangle(GpGraphics *graphics, GpPen *pen, REAL x, if(graphics->busy) return ObjectBusy; - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } + status = GdipCreatePath(FillModeAlternate, &path); + if (status != Ok) return status; - ptf[0].X = x; - ptf[0].Y = y; - ptf[1].X = x + width; - ptf[1].Y = y; - ptf[2].X = x + width; - ptf[2].Y = y + height; - ptf[3].X = x; - ptf[3].Y = y + height; + status = GdipAddPathRectangle(path, x, y, width, height); + if (status == Ok) + status = GdipDrawPath(graphics, pen, path); - save_state = prepare_dc(graphics, pen); - SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH)); - - transform_and_round_points(graphics, pti, ptf, 4); - Polygon(graphics->hdc, pti, 4); - - restore_dc(graphics, save_state); - - return Ok; + GdipDeletePath(path); + return status; } GpStatus WINGDIPAPI GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x, @@ -3798,9 +3454,8 @@ GpStatus WINGDIPAPI GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x, GpStatus WINGDIPAPI GdipDrawRectangles(GpGraphics *graphics, GpPen *pen, GDIPCONST GpRectF* rects, INT count) { - GpPointF *ptf; - POINT *pti; - INT save_state, i; + GpStatus status; + GpPath *path; TRACE("(%p, %p, %p, %d)\n", graphics, pen, rects, count); @@ -3810,42 +3465,15 @@ GpStatus WINGDIPAPI GdipDrawRectangles(GpGraphics *graphics, GpPen *pen, if(graphics->busy) return ObjectBusy; - if (!graphics->hdc) - { - FIXME("graphics object has no HDC\n"); - return Ok; - } + status = GdipCreatePath(FillModeAlternate, &path); + if (status != Ok) return status; - ptf = GdipAlloc(4 * count * sizeof(GpPointF)); - pti = GdipAlloc(4 * count * sizeof(POINT)); + status = GdipAddPathRectangles(path, rects, count); + if (status == Ok) + status = GdipDrawPath(graphics, pen, path); - if(!ptf || !pti){ - GdipFree(ptf); - GdipFree(pti); - return OutOfMemory; - } - - for(i = 0; i < count; i++){ - ptf[4 * i + 3].X = ptf[4 * i].X = rects[i].X; - ptf[4 * i + 1].Y = ptf[4 * i].Y = rects[i].Y; - ptf[4 * i + 2].X = ptf[4 * i + 1].X = rects[i].X + rects[i].Width; - ptf[4 * i + 3].Y = ptf[4 * i + 2].Y = rects[i].Y + rects[i].Height; - } - - save_state = prepare_dc(graphics, pen); - SelectObject(graphics->hdc, GetStockObject(NULL_BRUSH)); - - transform_and_round_points(graphics, pti, ptf, 4 * count); - - for(i = 0; i < count; i++) - Polygon(graphics->hdc, &pti[4 * i], 4); - - restore_dc(graphics, save_state); - - GdipFree(ptf); - GdipFree(pti); - - return Ok; + GdipDeletePath(path); + return status; } GpStatus WINGDIPAPI GdipDrawRectanglesI(GpGraphics *graphics, GpPen *pen, @@ -3881,7 +3509,7 @@ GpStatus WINGDIPAPI GdipFillClosedCurve2(GpGraphics *graphics, GpBrush *brush, GDIPCONST GpPointF *points, INT count, REAL tension, GpFillMode fill) { GpPath *path; - GpStatus stat; + GpStatus status; TRACE("(%p, %p, %p, %d, %.2f, %d)\n", graphics, brush, points, count, tension, fill); @@ -3895,25 +3523,15 @@ GpStatus WINGDIPAPI GdipFillClosedCurve2(GpGraphics *graphics, GpBrush *brush, if(count == 1) /* Do nothing */ return Ok; - stat = GdipCreatePath(fill, &path); - if(stat != Ok) - return stat; + status = GdipCreatePath(fill, &path); + if (status != Ok) return status; - stat = GdipAddPathClosedCurve2(path, points, count, tension); - if(stat != Ok){ - GdipDeletePath(path); - return stat; - } - - stat = GdipFillPath(graphics, brush, path); - if(stat != Ok){ - GdipDeletePath(path); - return stat; - } + status = GdipAddPathClosedCurve2(path, points, count, tension); + if (status == Ok) + status = GdipFillPath(graphics, brush, path); GdipDeletePath(path); - - return Ok; + return status; } GpStatus WINGDIPAPI GdipFillClosedCurve2I(GpGraphics *graphics, GpBrush *brush, @@ -4234,20 +3852,23 @@ GpStatus WINGDIPAPI GdipFillRectangleI(GpGraphics *graphics, GpBrush *brush, GpStatus WINGDIPAPI GdipFillRectangles(GpGraphics *graphics, GpBrush *brush, GDIPCONST GpRectF *rects, INT count) { - GpStatus ret; - INT i; + GpStatus status; + GpPath *path; TRACE("(%p, %p, %p, %d)\n", graphics, brush, rects, count); if(!rects) return InvalidParameter; - for(i = 0; i < count; i++){ - ret = GdipFillRectangle(graphics, brush, rects[i].X, rects[i].Y, rects[i].Width, rects[i].Height); - if(ret != Ok) return ret; - } + status = GdipCreatePath(FillModeAlternate, &path); + if (status != Ok) return status; - return Ok; + status = GdipAddPathRectangles(path, rects, count); + if (status == Ok) + status = GdipFillPath(graphics, brush, path); + + GdipDeletePath(path); + return status; } GpStatus WINGDIPAPI GdipFillRectanglesI(GpGraphics *graphics, GpBrush *brush, GDIPCONST GpRect *rects, @@ -4814,7 +4435,7 @@ GpStatus WINGDIPAPI GdipIsVisibleRectI(GpGraphics *graphics, INT x, INT y, INT w GpStatus gdip_format_string(HDC hdc, GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font, - GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format, + GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format, int ignore_empty_clip, gdip_format_string_callback callback, void *user_data) { WCHAR* stringdup; @@ -4837,6 +4458,11 @@ GpStatus gdip_format_string(HDC hdc, nwidth = rect->Width; nheight = rect->Height; + if (ignore_empty_clip) + { + if (!nwidth) nwidth = INT_MAX; + if (!nheight) nheight = INT_MAX; + } if (format) hkprefix = format->hkprefix; @@ -5078,21 +4704,8 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics, scaled_rect.X = (layoutRect->X + margin_x) * args.rel_width; scaled_rect.Y = layoutRect->Y * args.rel_height; - if (stringFormat->attr & StringFormatFlagsNoClip) - { - scaled_rect.Width = (REAL)(1 << 23); - scaled_rect.Height = (REAL)(1 << 23); - } - else - { - scaled_rect.Width = layoutRect->Width * args.rel_width; - scaled_rect.Height = layoutRect->Height * args.rel_height; - } - if (scaled_rect.Width >= 0.5) - { - scaled_rect.Width -= margin_x * 2.0 * args.rel_width; - if (scaled_rect.Width < 0.5) return Ok; /* doesn't fit */ - } + scaled_rect.Width = layoutRect->Width * args.rel_width; + scaled_rect.Height = layoutRect->Height * args.rel_height; get_font_hfont(graphics, font, stringFormat, &gdifont, NULL); oldfont = SelectObject(hdc, gdifont); @@ -5107,7 +4720,7 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics, args.regions = regions; stat = gdip_format_string(hdc, string, length, font, &scaled_rect, stringFormat, - measure_ranges_callback, &args); + (stringFormat->attr & StringFormatFlagsNoClip) != 0, measure_ranges_callback, &args); SelectObject(hdc, oldfont); DeleteObject(gdifont); @@ -5167,7 +4780,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics, GpPointF pt[3]; RectF scaled_rect; REAL margin_x; - INT lines, glyphs, format_flags = format ? format->attr : 0; + INT lines, glyphs; TRACE("(%p, %s, %i, %p, %s, %p, %p, %p, %p)\n", graphics, debugstr_wn(string, length), length, font, debugstr_rectf(rect), format, @@ -5209,20 +4822,14 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics, scaled_rect.Y = rect->Y * args.rel_height; scaled_rect.Width = rect->Width * args.rel_width; scaled_rect.Height = rect->Height * args.rel_height; - - if ((format_flags & StringFormatFlagsNoClip) || - scaled_rect.Width >= 1 << 23 || scaled_rect.Width < 0.5) scaled_rect.Width = 1 << 23; - if ((format_flags & StringFormatFlagsNoClip) || - scaled_rect.Height >= 1 << 23 || scaled_rect.Height < 0.5) scaled_rect.Height = 1 << 23; - if (scaled_rect.Width >= 0.5) { scaled_rect.Width -= margin_x * 2.0 * args.rel_width; if (scaled_rect.Width < 0.5) return Ok; /* doesn't fit */ } - if (scaled_rect.Width >= 1 << 23 || scaled_rect.Width < 0.5) scaled_rect.Width = 1 << 23; - if (scaled_rect.Height >= 1 << 23 || scaled_rect.Height < 0.5) scaled_rect.Height = 1 << 23; + if (scaled_rect.Width >= 1 << 23) scaled_rect.Width = 1 << 23; + if (scaled_rect.Height >= 1 << 23) scaled_rect.Height = 1 << 23; get_font_hfont(graphics, font, format, &gdifont, NULL); oldfont = SelectObject(hdc, gdifont); @@ -5237,7 +4844,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics, args.linesfilled = &lines; lines = glyphs = 0; - gdip_format_string(hdc, string, length, font, &scaled_rect, format, + gdip_format_string(hdc, string, length, font, &scaled_rect, format, TRUE, measure_string_callback, &args); if (linesfilled) *linesfilled = lines; @@ -5388,20 +4995,14 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string scaled_rect.Y = 0.0; scaled_rect.Width = rel_width * rect->Width; scaled_rect.Height = rel_height * rect->Height; - - if ((format_flags & StringFormatFlagsNoClip) || - scaled_rect.Width >= 1 << 23 || scaled_rect.Width < 0.5) scaled_rect.Width = 1 << 23; - if ((format_flags & StringFormatFlagsNoClip) || - scaled_rect.Height >= 1 << 23 || scaled_rect.Height < 0.5) scaled_rect.Height = 1 << 23; - if (scaled_rect.Width >= 0.5) { scaled_rect.Width -= margin_x * 2.0 * rel_width; if (scaled_rect.Width < 0.5) return Ok; /* doesn't fit */ } - if (scaled_rect.Width >= 1 << 23 || scaled_rect.Width < 0.5) scaled_rect.Width = 1 << 23; - if (scaled_rect.Height >= 1 << 23 || scaled_rect.Height < 0.5) scaled_rect.Height = 1 << 23; + if (scaled_rect.Width >= 1 << 23) scaled_rect.Width = 1 << 23; + if (scaled_rect.Height >= 1 << 23) scaled_rect.Height = 1 << 23; if (!(format_flags & StringFormatFlagsNoClip) && scaled_rect.Width != 1 << 23 && scaled_rect.Height != 1 << 23) @@ -5426,7 +5027,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string GetTextMetricsW(hdc, &textmetric); args.ascent = textmetric.tmAscent / rel_height; - gdip_format_string(hdc, string, length, font, &scaled_rect, format, + gdip_format_string(hdc, string, length, font, &scaled_rect, format, TRUE, draw_string_callback, &args); DeleteObject(rgn); diff --git a/reactos/dll/win32/gdiplus/graphicspath.c b/reactos/dll/win32/gdiplus/graphicspath.c index bd2f8ca162c..0de0e9e17ac 100644 --- a/reactos/dll/win32/gdiplus/graphicspath.c +++ b/reactos/dll/win32/gdiplus/graphicspath.c @@ -1009,7 +1009,8 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT args.maxY = 0; args.scale = emSize / native_height; args.ascent = textmetric.tmAscent * args.scale; - status = gdip_format_string(dc, string, length, NULL, &scaled_layout_rect, format, format_string_callback, &args); + status = gdip_format_string(dc, string, length, NULL, &scaled_layout_rect, + format, TRUE, format_string_callback, &args); DeleteDC(dc); DeleteObject(hfont); @@ -1702,6 +1703,13 @@ static void add_bevel_point(const GpPointF *endpoint, const GpPointF *nextpoint, REAL distance = pen->width/2.0; REAL bevel_dx, bevel_dy; + if (segment_length == 0.0) + { + *last_point = add_path_list_node(*last_point, endpoint->X, + endpoint->Y, PathPointTypeLine); + return; + } + if (right_side) { bevel_dx = -distance * segment_dy / segment_length; diff --git a/reactos/dll/win32/gdiplus/image.c b/reactos/dll/win32/gdiplus/image.c index c3a46afe510..52d1201f3c9 100644 --- a/reactos/dll/win32/gdiplus/image.c +++ b/reactos/dll/win32/gdiplus/image.c @@ -17,20 +17,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -//#include +#include #include +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + #define NONAMELESSUNION -//#include "windef.h" -//#include "winbase.h" +#include +#include //#include "winuser.h" //#include "wingdi.h" #define COBJMACROS //#include "objbase.h" +#include #include -//#include "ole2.h" #include //#include "wincodec.h" @@ -116,10 +120,9 @@ static INT ipicture_pixel_height(IPicture *pic) IPicture_get_Height(pic, &y); - hdcref = GetDC(0); - + hdcref = CreateCompatibleDC(0); y = MulDiv(y, GetDeviceCaps(hdcref, LOGPIXELSY), INCH_HIMETRIC); - ReleaseDC(0, hdcref); + DeleteDC(hdcref); return y; } @@ -131,11 +134,9 @@ static INT ipicture_pixel_width(IPicture *pic) IPicture_get_Width(pic, &x); - hdcref = GetDC(0); - + hdcref = CreateCompatibleDC(0); x = MulDiv(x, GetDeviceCaps(hdcref, LOGPIXELSX), INCH_HIMETRIC); - - ReleaseDC(0, hdcref); + DeleteDC(hdcref); return x; } @@ -300,7 +301,6 @@ GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y, BYTE r, g, b, a; BYTE index; BYTE *row; - TRACE("%p %d %d %p\n", bitmap, x, y, color); if(!bitmap || !color || x < 0 || y < 0 || x >= bitmap->width || y >= bitmap->height) @@ -370,7 +370,7 @@ static inline UINT get_palette_index(BYTE r, BYTE g, BYTE b, BYTE a, ColorPalett BYTE index = 0; int best_distance = 0x7fff; int distance; - int i; + UINT i; if (!palette) return 0; /* This algorithm scans entire palette, @@ -506,7 +506,6 @@ GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y, { BYTE a, r, g, b; BYTE *row; - TRACE("bitmap:%p, x:%d, y:%d, color:%08x\n", bitmap, x, y, color); if(!bitmap || x < 0 || y < 0 || x >= bitmap->width || y >= bitmap->height) return InvalidParameter; @@ -1600,12 +1599,9 @@ GpStatus WINGDIPAPI GdipConvertToEmfPlus(const GpGraphics* ref, return NotImplemented; } -/* FIXME: this should create a bitmap in the given size with the attributes - * (resolution etc.) of the graphics object */ GpStatus WINGDIPAPI GdipCreateBitmapFromGraphics(INT width, INT height, GpGraphics* target, GpBitmap** bitmap) { - static int calls; GpStatus ret; TRACE("(%d, %d, %p, %p)\n", width, height, target, bitmap); @@ -1613,12 +1609,15 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromGraphics(INT width, INT height, if(!target || !bitmap) return InvalidParameter; - if(!(calls++)) - FIXME("hacked stub\n"); - - ret = GdipCreateBitmapFromScan0(width, height, 0, PixelFormat24bppRGB, + ret = GdipCreateBitmapFromScan0(width, height, 0, PixelFormat32bppPARGB, NULL, bitmap); + if (ret == Ok) + { + GdipGetDpiX(target, &(*bitmap)->image.xres); + GdipGetDpiY(target, &(*bitmap)->image.yres); + } + return ret; } @@ -1628,13 +1627,12 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap) ICONINFO iinfo; BITMAP bm; int ret; - UINT width, height; + UINT width, height, stride; GpRect rect; BitmapData lockeddata; HDC screendc; BOOL has_alpha; int x, y; - BYTE *bits; BITMAPINFOHEADER bih; DWORD *src; BYTE *dst_row; @@ -1654,24 +1652,13 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap) } width = bm.bmWidth; + height = iinfo.hbmColor ? abs(bm.bmHeight) : abs(bm.bmHeight) / 2; + stride = width * 4; - if (iinfo.hbmColor) - height = abs(bm.bmHeight); - else /* combined bitmap + mask */ - height = abs(bm.bmHeight) / 2; - - bits = HeapAlloc(GetProcessHeap(), 0, 4*width*height); - if (!bits) { - DeleteObject(iinfo.hbmColor); - DeleteObject(iinfo.hbmMask); - return OutOfMemory; - } - - stat = GdipCreateBitmapFromScan0(width, height, 0, PixelFormat32bppARGB, NULL, bitmap); + stat = GdipCreateBitmapFromScan0(width, height, stride, PixelFormat32bppARGB, NULL, bitmap); if (stat != Ok) { DeleteObject(iinfo.hbmColor); DeleteObject(iinfo.hbmMask); - HeapFree(GetProcessHeap(), 0, bits); return stat; } @@ -1684,14 +1671,13 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap) if (stat != Ok) { DeleteObject(iinfo.hbmColor); DeleteObject(iinfo.hbmMask); - HeapFree(GetProcessHeap(), 0, bits); GdipDisposeImage((GpImage*)*bitmap); return stat; } bih.biSize = sizeof(bih); bih.biWidth = width; - bih.biHeight = -height; + bih.biHeight = iinfo.hbmColor ? -height: -height * 2; bih.biPlanes = 1; bih.biBitCount = 32; bih.biCompression = BI_RGB; @@ -1701,17 +1687,17 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap) bih.biClrUsed = 0; bih.biClrImportant = 0; - screendc = GetDC(0); + screendc = CreateCompatibleDC(0); if (iinfo.hbmColor) { - GetDIBits(screendc, iinfo.hbmColor, 0, height, bits, (BITMAPINFO*)&bih, DIB_RGB_COLORS); + GetDIBits(screendc, iinfo.hbmColor, 0, height, lockeddata.Scan0, (BITMAPINFO*)&bih, DIB_RGB_COLORS); if (bm.bmBitsPixel == 32) { has_alpha = FALSE; /* If any pixel has a non-zero alpha, ignore hbmMask */ - src = (DWORD*)bits; + src = (DWORD*)lockeddata.Scan0; for (x=0; xEntries[i] = 0xff000000 | entry->peRed << 16 | - entry->peGreen << 8 | entry->peBlue; + palette->Entries[i] = 0xff000000 | entry[i].peRed << 16 | + entry[i].peGreen << 8 | entry[i].peBlue; } retval = GdipSetImagePalette((GpImage*)*bitmap, palette); } - GdipFree(palette_entries); GdipFree(palette); } diff --git a/reactos/dll/win32/gdiplus/metafile.c b/reactos/dll/win32/gdiplus/metafile.c index 88afcfe7387..3004f346859 100644 --- a/reactos/dll/win32/gdiplus/metafile.c +++ b/reactos/dll/win32/gdiplus/metafile.c @@ -410,7 +410,7 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, if (record) { record->iType = recordType; - record->nSize = dataSize; + record->nSize = dataSize + 8; memcpy(record->dParm, data, dataSize); PlayEnhMetaFileRecord(metafile->playback_dc, metafile->handle_table, @@ -536,7 +536,9 @@ GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics, memcpy(real_metafile->playback_points, destPoints, sizeof(PointF) * 3); stat = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, real_metafile->playback_points, 3); - if (stat == Ok && metafile->metafile_type == MetafileTypeEmf) + if (stat == Ok && (metafile->metafile_type == MetafileTypeEmf || + metafile->metafile_type == MetafileTypeWmfPlaceable || + metafile->metafile_type == MetafileTypeWmf)) stat = METAFILE_PlaybackGetDC((GpMetafile*)metafile); if (stat == Ok) diff --git a/reactos/dll/win32/gdiplus/region.c b/reactos/dll/win32/gdiplus/region.c index 3fb306506a6..1d1ea1f0c11 100644 --- a/reactos/dll/win32/gdiplus/region.c +++ b/reactos/dll/win32/gdiplus/region.c @@ -282,7 +282,7 @@ GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region, region_element *left, *right = NULL; GpStatus stat; - TRACE("%p %p %d\n", region, rect, mode); + TRACE("%p %s %d\n", region, debugstr_rectf(rect), mode); if (!(region && rect)) return InvalidParameter; @@ -588,7 +588,7 @@ GpStatus WINGDIPAPI GdipCreateRegionHrgn(HRGN hrgn, GpRegion **region) GpStatus stat; GpPath* path; GpRegion* local; - int i; + DWORD i; TRACE("(%p, %p)\n", hrgn, region); @@ -894,7 +894,7 @@ static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn) if (!graphics) { - new_hdc = GetDC(0); + new_hdc = CreateCompatibleDC(0); if (!new_hdc) return OutOfMemory; @@ -902,13 +902,13 @@ static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn) graphics = new_graphics; if (stat != Ok) { - ReleaseDC(0, new_hdc); + DeleteDC(new_hdc); return stat; } } else if (!graphics->hdc) { - graphics->hdc = new_hdc = GetDC(0); + graphics->hdc = new_hdc = CreateCompatibleDC(0); if (!new_hdc) return OutOfMemory; } @@ -929,7 +929,7 @@ static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn) RestoreDC(graphics->hdc, save_state); if (new_hdc) { - ReleaseDC(0, new_hdc); + DeleteDC(new_hdc); if (new_graphics) GdipDeleteGraphics(new_graphics); else @@ -1467,7 +1467,7 @@ GpStatus WINGDIPAPI GdipGetRegionScansCount(GpRegion *region, UINT *count, GpMat GpStatus WINGDIPAPI GdipGetRegionScansI(GpRegion *region, GpRect *scans, INT *count, GpMatrix *matrix) { GpStatus stat; - INT i; + DWORD i; LPRGNDATA data; RECT *rects; @@ -1501,7 +1501,7 @@ GpStatus WINGDIPAPI GdipGetRegionScansI(GpRegion *region, GpRect *scans, INT *co GpStatus WINGDIPAPI GdipGetRegionScans(GpRegion *region, GpRectF *scans, INT *count, GpMatrix *matrix) { GpStatus stat; - INT i; + DWORD i; LPRGNDATA data; RECT *rects; diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index c6b9d4cd1bf..e7ba7316f86 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -63,7 +63,7 @@ reactos/dll/win32/dciman32 # Synced to Wine-1.5.19 reactos/dll/win32/dwmapi # Synced to Wine-1.5.19 reactos/dll/win32/faultrep # Synced to Wine-1.5.4 reactos/dll/win32/fusion # Synced to Wine-1.5.26 -reactos/dll/win32/gdiplus # Synced to Wine-1.5.4 +reactos/dll/win32/gdiplus # Synced to Wine-1.5.26 reactos/dll/win32/hhctrl.ocx # Synced to Wine-1.5.26 reactos/dll/win32/hlink # Synced to Wine-1.5.4 reactos/dll/win32/hnetcfg # Synced to Wine-1.5.4