Author: dchapyshev Date: Sat May 9 13:26:16 2009 New Revision: 40851
URL: http://svn.reactos.org/svn/reactos?rev=40851&view=rev Log: - Sync gdiplus with Wine 1.1.21
Modified: trunk/reactos/dll/win32/gdiplus/brush.c trunk/reactos/dll/win32/gdiplus/font.c trunk/reactos/dll/win32/gdiplus/gdiplus.spec trunk/reactos/dll/win32/gdiplus/gdiplus_private.h trunk/reactos/dll/win32/gdiplus/graphics.c trunk/reactos/dll/win32/gdiplus/image.c
Modified: trunk/reactos/dll/win32/gdiplus/brush.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/brush.c?r... ============================================================================== --- trunk/reactos/dll/win32/gdiplus/brush.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/gdiplus/brush.c [iso-8859-1] Sat May 9 13:26:16 2009 @@ -34,6 +34,33 @@
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
+/* + Unix stuff + Code from http://www.johndcook.com/blog/2009/01/19/stand-alone-error-function-erf/ +*/ +double erf(double x) +{ + const float a1 = 0.254829592; + const float a2 = -0.284496736; + const float a3 = 1.421413741; + const float a4 = -1.453152027; + const float a5 = 1.061405429; + const float p = 0.3275911; + float t, y, sign; + + /* Save the sign of x */ + sign = 1; + if (x < 0) + sign = -1; + x = abs(x); + + /* A & S 7.1.26 */ + t = 1.0/(1.0 + p*x); + y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x); + + return sign*y; +} + /****************************************************************************** * GdipCloneBrush [GDIPLUS.@] */ @@ -108,14 +135,38 @@
break; } - case BrushTypeLinearGradient: - *clone = GdipAlloc(sizeof(GpLineGradient)); - if(!*clone) return OutOfMemory; - - memcpy(*clone, brush, sizeof(GpLineGradient)); - - (*clone)->gdibrush = CreateSolidBrush((*clone)->lb.lbColor); + case BrushTypeLinearGradient:{ + GpLineGradient *dest, *src; + INT count; + + dest = GdipAlloc(sizeof(GpLineGradient)); + if(!dest) return OutOfMemory; + + src = (GpLineGradient*)brush; + + memcpy(dest, src, sizeof(GpLineGradient)); + + dest->brush.gdibrush = CreateSolidBrush(dest->brush.lb.lbColor); + + count = dest->blendcount; + dest->blendfac = GdipAlloc(count * sizeof(REAL)); + dest->blendpos = GdipAlloc(count * sizeof(REAL)); + + if (!dest->blendfac || !dest->blendpos) + { + GdipFree(dest->blendfac); + GdipFree(dest->blendpos); + DeleteObject(dest->brush.gdibrush); + GdipFree(dest); + return OutOfMemory; + } + + memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL)); + memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL)); + + *clone = &dest->brush; break; + } case BrushTypeTextureFill: *clone = GdipAlloc(sizeof(GpTexture)); if(!*clone) return OutOfMemory; @@ -226,6 +277,28 @@ (*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); + + (*line)->blendcount = 1; + (*line)->blendfac = GdipAlloc(sizeof(REAL)); + (*line)->blendpos = GdipAlloc(sizeof(REAL)); + + if (!(*line)->blendfac || !(*line)->blendpos) + { + GdipFree((*line)->blendfac); + GdipFree((*line)->blendpos); + DeleteObject((*line)->brush.gdibrush); + GdipFree(*line); + *line = NULL; + return OutOfMemory; + } + + (*line)->blendfac[0] = 1.0f; + (*line)->blendpos[0] = 1.0f; + return Ok; }
@@ -255,6 +328,7 @@ GpLineGradient **line) { GpPointF start, end; + GpStatus stat;
TRACE("(%p, %x, %x, %d, %d, %p)\n", rect, startcolor, endcolor, mode, wrap, line); @@ -262,12 +336,42 @@ if(!line || !rect) return InvalidParameter;
- start.X = rect->X; - start.Y = rect->Y; - end.X = rect->X + rect->Width; - end.Y = rect->Y + rect->Height; - - return GdipCreateLineBrush(&start, &end, startcolor, endcolor, wrap, line); + switch (mode) + { + case LinearGradientModeHorizontal: + start.X = rect->X; + start.Y = rect->Y; + end.X = rect->X + rect->Width; + end.Y = rect->Y; + break; + case LinearGradientModeVertical: + start.X = rect->X; + start.Y = rect->Y; + end.X = rect->X; + end.Y = rect->Y + rect->Height; + break; + case LinearGradientModeForwardDiagonal: + start.X = rect->X; + start.Y = rect->Y; + end.X = rect->X + rect->Width; + end.Y = rect->Y + rect->Height; + break; + case LinearGradientModeBackwardDiagonal: + start.X = rect->X + rect->Width; + start.Y = rect->Y; + end.X = rect->X; + end.Y = rect->Y + rect->Height; + break; + default: + return InvalidParameter; + } + + stat = GdipCreateLineBrush(&start, &end, startcolor, endcolor, wrap, line); + + if (stat == Ok) + (*line)->rect = *rect; + + return stat; }
GpStatus WINGDIPAPI GdipCreateLineBrushFromRectI(GDIPCONST GpRect* rect, @@ -765,7 +869,10 @@ GdipFree(((GpPathGradient*) brush)->blendpos); break; case BrushTypeSolidColor: + break; case BrushTypeLinearGradient: + GdipFree(((GpLineGradient*)brush)->blendfac); + GdipFree(((GpLineGradient*)brush)->blendpos); break; case BrushTypeTextureFill: GdipDeleteMatrix(((GpTexture*)brush)->transform); @@ -1071,15 +1178,64 @@ }
GpStatus WINGDIPAPI GdipSetLineBlend(GpLineGradient *brush, - GDIPCONST REAL *blend, GDIPCONST REAL* positions, INT count) -{ - static int calls; - - if(!brush || !blend || !positions || count <= 0) - return InvalidParameter; - - if(!(calls++)) - FIXME("not implemented\n"); + GDIPCONST REAL *factors, GDIPCONST REAL* positions, INT count) +{ + REAL *new_blendfac, *new_blendpos; + + TRACE("(%p, %p, %p, %i)\n", brush, factors, positions, count); + + if(!brush || !factors || !positions || count <= 0 || + (count >= 2 && (positions[0] != 0.0f || positions[count-1] != 1.0f))) + return InvalidParameter; + + new_blendfac = GdipAlloc(count * sizeof(REAL)); + new_blendpos = GdipAlloc(count * sizeof(REAL)); + + if (!new_blendfac || !new_blendpos) + { + GdipFree(new_blendfac); + GdipFree(new_blendpos); + return OutOfMemory; + } + + memcpy(new_blendfac, factors, count * sizeof(REAL)); + memcpy(new_blendpos, positions, count * sizeof(REAL)); + + GdipFree(brush->blendfac); + GdipFree(brush->blendpos); + + brush->blendcount = count; + brush->blendfac = new_blendfac; + brush->blendpos = new_blendpos; + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetLineBlend(GpLineGradient *brush, REAL *factors, + REAL *positions, INT count) +{ + TRACE("(%p, %p, %p, %i)\n", brush, factors, positions, count); + + if (!brush || !factors || !positions || count <= 0) + return InvalidParameter; + + if (count < brush->blendcount) + return InsufficientBuffer; + + memcpy(factors, brush->blendfac, brush->blendcount * sizeof(REAL)); + memcpy(positions, brush->blendpos, brush->blendcount * sizeof(REAL)); + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetLineBlendCount(GpLineGradient *brush, INT *count) +{ + TRACE("(%p, %p)\n", brush, count); + + if (!brush || !count) + return InvalidParameter; + + *count = brush->blendcount;
return Ok; } @@ -1100,15 +1256,57 @@ GpStatus WINGDIPAPI GdipSetLineSigmaBlend(GpLineGradient *line, REAL focus, REAL scale) { - static int calls; + REAL factors[33]; + REAL positions[33]; + int num_points = 0; + int i; + const int precision = 16; + REAL erf_range; /* we use values erf(-erf_range) through erf(+erf_range) */ + REAL min_erf; + REAL scale_erf; + + TRACE("(%p, %0.2f, %0.2f)\n", line, focus, scale);
if(!line || focus < 0.0 || focus > 1.0 || scale < 0.0 || scale > 1.0) return InvalidParameter;
- if(!(calls++)) - FIXME("not implemented\n"); - - return NotImplemented; + /* we want 2 standard deviations */ + erf_range = 2.0 / sqrt(2); + + /* calculate the constants we need to normalize the error function to be + between 0.0 and scale over the range we need */ + min_erf = erf(-erf_range); + scale_erf = scale / (-2.0 * min_erf); + + if (focus != 0.0) + { + positions[0] = 0.0; + factors[0] = 0.0; + for (i=1; i<precision; i++) + { + positions[i] = focus * i / precision; + factors[i] = scale_erf * (erf(2 * erf_range * i / precision - erf_range) - min_erf); + } + num_points += precision; + } + + positions[num_points] = focus; + factors[num_points] = scale; + num_points += 1; + + if (focus != 1.0) + { + for (i=1; i<precision; i++) + { + positions[i+num_points-1] = (focus + ((1.0-focus) * i / precision)); + factors[i+num_points-1] = scale_erf * (erf(erf_range - 2 * erf_range * i / precision) - min_erf); + } + num_points += precision; + positions[num_points-1] = 1.0; + factors[num_points-1] = 0.0; + } + + return GdipSetLineBlend(line, factors, positions, num_points); }
GpStatus WINGDIPAPI GdipSetLineWrapMode(GpLineGradient *line, @@ -1403,11 +1601,7 @@ if(!brush || !rect) return InvalidParameter;
- rect->X = (brush->startpoint.X < brush->endpoint.X ? brush->startpoint.X: brush->endpoint.X); - rect->Y = (brush->startpoint.Y < brush->endpoint.Y ? brush->startpoint.Y: brush->endpoint.Y); - - rect->Width = fabs(brush->startpoint.X - brush->endpoint.X); - rect->Height = fabs(brush->startpoint.Y - brush->endpoint.Y); + *rect = brush->rect;
return Ok; }
Modified: trunk/reactos/dll/win32/gdiplus/font.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/font.c?re... ============================================================================== --- trunk/reactos/dll/win32/gdiplus/font.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/gdiplus/font.c [iso-8859-1] Sat May 9 13:26:16 2009 @@ -35,6 +35,8 @@
static const REAL mm_per_inch = 25.4; static const REAL inch_per_point = 1.0/72.0; + +static GpFontCollection installedFontCollection = {0};
static inline REAL get_dpi (void) { @@ -193,7 +195,7 @@ oldfont = SelectObject(hdc, hfont); GetTextMetricsW(hdc, &textmet);
- (*font)->lfw.lfHeight = -textmet.tmHeight; + (*font)->lfw.lfHeight = -(textmet.tmHeight-textmet.tmInternalLeading); (*font)->lfw.lfWeight = textmet.tmWeight; (*font)->lfw.lfCharSet = textmet.tmCharSet;
@@ -936,5 +938,7 @@ if (!fontCollection) return InvalidParameter;
- return NotImplemented; -} + *fontCollection = &installedFontCollection; + + return Ok; +}
Modified: trunk/reactos/dll/win32/gdiplus/gdiplus.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/gdiplus.s... ============================================================================== --- trunk/reactos/dll/win32/gdiplus/gdiplus.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/gdiplus/gdiplus.spec [iso-8859-1] Sat May 9 13:26:16 2009 @@ -42,7 +42,7 @@ @ stub GdipBitmapGetHistogramSize @ stdcall GdipBitmapGetPixel(ptr long long ptr) @ stdcall GdipBitmapLockBits(ptr ptr long long ptr) -@ stub GdipBitmapSetPixel +@ stdcall GdipBitmapSetPixel(ptr long long long) @ stdcall GdipBitmapSetResolution(ptr long long) @ stdcall GdipBitmapUnlockBits(ptr ptr) @ stdcall GdipClearPathMarkers(ptr) @@ -295,13 +295,13 @@ @ stdcall GdipGetImagePaletteSize(ptr ptr) @ stdcall GdipGetImagePixelFormat(ptr ptr) @ stdcall GdipGetImageRawFormat(ptr ptr) -@ stub GdipGetImageThumbnail +@ stdcall GdipGetImageThumbnail(ptr long long ptr ptr ptr) @ stdcall GdipGetImageType(ptr ptr) @ stdcall GdipGetImageVerticalResolution(ptr ptr) @ stdcall GdipGetImageWidth(ptr ptr) @ stdcall GdipGetInterpolationMode(ptr ptr) -@ stub GdipGetLineBlend -@ stub GdipGetLineBlendCount +@ stdcall GdipGetLineBlend(ptr ptr ptr long) +@ stdcall GdipGetLineBlendCount(ptr ptr) @ stdcall GdipGetLineColors(ptr ptr) @ stdcall GdipGetLineGammaCorrection(ptr ptr) @ stub GdipGetLinePresetBlend @@ -409,7 +409,7 @@ @ stdcall GdipImageGetFrameCount(ptr ptr ptr) @ stdcall GdipImageGetFrameDimensionsCount(ptr ptr) @ stdcall GdipImageGetFrameDimensionsList(ptr ptr long) -@ stub GdipImageRotateFlip +@ stdcall GdipImageRotateFlip(ptr long) @ stdcall GdipImageSelectActiveFrame(ptr ptr long) @ stub GdipImageSetAbort @ stub GdipInitializePalette @@ -582,7 +582,7 @@ @ stdcall GdipSetPenWidth(ptr long) @ stdcall GdipSetPixelOffsetMode(ptr long) @ stdcall GdipSetPropertyItem(ptr ptr) -@ stub GdipSetRenderingOrigin +@ stdcall GdipSetRenderingOrigin(ptr long long) @ stdcall GdipSetSmoothingMode(ptr long) @ stdcall GdipSetSolidFillColor(ptr ptr) @ stdcall GdipSetStringFormatAlign(ptr long)
Modified: trunk/reactos/dll/win32/gdiplus/gdiplus_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/gdiplus_p... ============================================================================== --- trunk/reactos/dll/win32/gdiplus/gdiplus_private.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/gdiplus/gdiplus_private.h [iso-8859-1] Sat May 9 13:26:16 2009 @@ -91,6 +91,7 @@ struct GpGraphics{ HDC hdc; HWND hwnd; + BOOL owndc; SmoothingMode smoothing; CompositingQuality compqual; InterpolationMode interpolation; @@ -142,8 +143,12 @@ GpPointF endpoint; ARGB startcolor; ARGB endcolor; + RectF rect; GpWrapMode wrap; BOOL gamma; + REAL* blendfac; /* blend factors */ + REAL* blendpos; /* blend positions */ + INT blendcount; };
struct GpTexture{
Modified: trunk/reactos/dll/win32/gdiplus/graphics.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/graphics.... ============================================================================== --- trunk/reactos/dll/win32/gdiplus/graphics.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/gdiplus/graphics.c [iso-8859-1] Sat May 9 13:26:16 2009 @@ -172,13 +172,54 @@ } }
-static ARGB blend_colors(ARGB start, ARGB end, int current, int total) +static ARGB blend_colors(ARGB start, ARGB end, REAL position) { ARGB result=0; ARGB i; for (i=0xff; i<=0xff0000; i = i << 8) - result |= (((start&i)*(total - current)+(end&i)*(current))/total)&i; + result |= (int)((start&i)*(1.0f - position)+(end&i)*(position))&i; return result; +} + +static ARGB blend_line_gradient(GpLineGradient* brush, REAL position) +{ + REAL blendfac; + + /* clamp to between 0.0 and 1.0, using the wrap mode */ + if (brush->wrap == WrapModeTile) + { + position = fmodf(position, 1.0f); + if (position < 0.0f) position += 1.0f; + } + else /* WrapModeFlip* */ + { + position = fmodf(position, 2.0f); + if (position < 0.0f) position += 2.0f; + if (position > 1.0f) position = 2.0f - position; + } + + if (brush->blendcount == 1) + blendfac = position; + else + { + int i=1; + REAL left_blendpos, left_blendfac, right_blendpos, right_blendfac; + REAL range; + + /* locate the blend positions surrounding this position */ + while (position > brush->blendpos[i]) + i++; + + /* interpolate between the blend positions */ + left_blendpos = brush->blendpos[i-1]; + left_blendfac = brush->blendfac[i-1]; + right_blendpos = brush->blendpos[i]; + right_blendfac = brush->blendfac[i]; + range = right_blendpos - left_blendpos; + blendfac = (left_blendfac * (right_blendpos - position) + + right_blendfac * (position - left_blendpos)) / range; + } + return blend_colors(brush->startcolor, brush->endcolor, blendfac); }
static void brush_fill_path(GpGraphics *graphics, GpBrush* brush) @@ -189,7 +230,6 @@ { GpLineGradient *line = (GpLineGradient*)brush; RECT rc; - int num_steps = 255;
SelectClipPath(graphics->hdc, RGN_AND); if (GetClipBox(graphics->hdc, &rc) != NULLREGION) @@ -200,9 +240,6 @@
SelectObject(graphics->hdc, GetStockObject(NULL_PEN));
- /* fill with starting color */ - FillRect(graphics->hdc, &rc, brush->gdibrush); - endpointsf[0] = line->startpoint; endpointsf[1] = line->endpoint; transform_and_round_points(graphics, endpointsi, endpointsf, 2); @@ -210,114 +247,100 @@ if (abs(endpointsi[0].x-endpointsi[1].x) > abs(endpointsi[0].y-endpointsi[1].y)) { /* vertical-ish gradient */ - int endborderx; /* vertical rectangle boundary near endpoint */ int startx, endx; /* x co-ordinates of endpoints shifted to intersect the top of the visible rectangle */ - int startbottomx, endbottomx; /* x co-ordinate of endpoints shifted to intersect the bottom 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 i; - - if (endpointsi[1].x > endpointsi[0].x) - endborderx = rc.right; - else - endborderx = rc.left; + 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); - endbottomx = startbottomx+width; - - if (num_steps > abs(width)) num_steps = abs(width); - - poly[0].x = endborderx; + 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].x = endborderx; poly[1].y = rc.top; poly[2].y = rc.top; poly[3].y = rc.bottom;
- for (i=1; i<num_steps; i++) + for (x=leftx; x<=rightx; x++) { - ARGB argb = blend_colors(line->startcolor, line->endcolor, i, num_steps); - int ofs = width * i / num_steps; + ARGB argb = blend_line_gradient(line, (x-startx)/(REAL)width); col = ARGB2COLORREF(argb); hbrush = CreateSolidBrush(col); hprevbrush = SelectObject(graphics->hdc, hbrush); - poly[2].x = startx + ofs; - poly[3].x = startbottomx + ofs; + 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); } - - poly[2].x = endx; - poly[3].x = endbottomx; - - /* draw the ending color */ - col = ARGB2COLORREF(line->endcolor); - hbrush = CreateSolidBrush(col); - hprevbrush = SelectObject(graphics->hdc, hbrush); - Polygon(graphics->hdc, poly, 4); - SelectObject(graphics->hdc, hprevbrush); - DeleteObject(hbrush); } else if (endpointsi[0].y != endpointsi[1].y) { /* horizontal-ish gradient */ - int endbordery; /* horizontal rectangle boundary near endpoint */ int starty, endy; /* y co-ordinates of endpoints shifted to intersect the left of the visible rectangle */ - int startrighty, endrighty; /* y co-ordinate of endpoints shifted to intersect the right 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 i; - - if (endpointsi[1].y > endpointsi[0].y) - endbordery = rc.bottom; - else - endbordery = rc.top; + 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); - endrighty = startrighty+height; - - if (num_steps > abs(height)) num_steps = abs(height); + 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[0].y = endbordery; poly[1].x = rc.left; - poly[1].y = endbordery; poly[2].x = rc.left; poly[3].x = rc.right;
- for (i=1; i<num_steps; i++) + for (y=topy; y<=bottomy; y++) { - ARGB argb = blend_colors(line->startcolor, line->endcolor, i, num_steps); - int ofs = height * i / num_steps; + ARGB argb = blend_line_gradient(line, (y-starty)/(REAL)height); col = ARGB2COLORREF(argb); hbrush = CreateSolidBrush(col); hprevbrush = SelectObject(graphics->hdc, hbrush); - poly[2].y = starty + ofs; - poly[3].y = startrighty + ofs; + 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); } - - poly[2].y = endy; - poly[3].y = endrighty; - - /* draw the ending color */ - col = ARGB2COLORREF(line->endcolor); - hbrush = CreateSolidBrush(col); - hprevbrush = SelectObject(graphics->hdc, hbrush); - Polygon(graphics->hdc, poly, 4); - SelectObject(graphics->hdc, hprevbrush); - DeleteObject(hbrush); } /* else startpoint == endpoint */ } @@ -924,6 +947,7 @@
(*graphics)->hdc = hdc; (*graphics)->hwnd = WindowFromDC(hdc); + (*graphics)->owndc = FALSE; (*graphics)->smoothing = SmoothingModeDefault; (*graphics)->compqual = CompositingQualityDefault; (*graphics)->interpolation = InterpolationModeDefault; @@ -940,13 +964,20 @@ GpStatus WINGDIPAPI GdipCreateFromHWND(HWND hwnd, GpGraphics **graphics) { GpStatus ret; + HDC hdc;
TRACE("(%p, %p)\n", hwnd, graphics);
- if((ret = GdipCreateFromHDC(GetDC(hwnd), graphics)) != Ok) + hdc = GetDC(hwnd); + + if((ret = GdipCreateFromHDC(hdc, graphics)) != Ok) + { + ReleaseDC(hwnd, hdc); return ret; + }
(*graphics)->hwnd = hwnd; + (*graphics)->owndc = TRUE;
return Ok; } @@ -1081,7 +1112,7 @@ if(!graphics) return InvalidParameter; if(graphics->busy) return ObjectBusy;
- if(graphics->hwnd) + if(graphics->owndc) ReleaseDC(graphics->hwnd, graphics->hdc);
GdipDeleteRegion(graphics->clip); @@ -2448,12 +2479,14 @@
save_state = SaveDC(graphics->hdc); EndPath(graphics->hdc); - SelectObject(graphics->hdc, brush->gdibrush); - SelectObject(graphics->hdc, GetStockObject(NULL_PEN));
transform_and_round_points(graphics, pti, ptf, 4);
+ BeginPath(graphics->hdc); Polygon(graphics->hdc, pti, 4); + EndPath(graphics->hdc); + + brush_fill_path(graphics, brush);
RestoreDC(graphics->hdc, save_state);
@@ -3210,6 +3243,18 @@ return Ok; }
+GpStatus WINGDIPAPI GdipSetRenderingOrigin(GpGraphics *graphics, INT x, INT y) +{ + static int calls; + + TRACE("(%p,%i,%i)\n", graphics, x, y); + + if (!(calls++)) + FIXME("not implemented\n"); + + return NotImplemented; +} + GpStatus WINGDIPAPI GdipSetSmoothingMode(GpGraphics *graphics, SmoothingMode mode) { TRACE("(%p, %d)\n", graphics, mode);
Modified: trunk/reactos/dll/win32/gdiplus/image.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/image.c?r... ============================================================================== --- trunk/reactos/dll/win32/gdiplus/image.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/gdiplus/image.c [iso-8859-1] Sat May 9 13:26:16 2009 @@ -83,6 +83,21 @@ FIXME("not implemented\n");
*color = 0xdeadbeef; + + return NotImplemented; +} + +GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y, + ARGB color) +{ + static int calls; + TRACE("bitmap:%p, x:%d, y:%d, color:%08x\n", bitmap, x, y, color); + + if(!bitmap) + return InvalidParameter; + + if(!(calls++)) + FIXME("not implemented\n");
return NotImplemented; } @@ -1648,3 +1663,24 @@
return Ok; } + +/***************************************************************************** + * GdipGetImageThumbnail [GDIPLUS.@] + */ +GpStatus WINGDIPAPI GdipGetImageThumbnail(GpImage *image, UINT width, UINT height, + GpImage **ret_image, GetThumbnailImageAbort cb, + VOID * cb_data) +{ + FIXME("(%p %u %u %p %p %p) stub\n", + image, width, height, ret_image, cb, cb_data); + return NotImplemented; +} + +/***************************************************************************** + * GdipImageRotateFlip [GDIPLUS.@] + */ +GpStatus WINGDIPAPI GdipImageRotateFlip(GpImage *image, RotateFlipType type) +{ + FIXME("(%p %u) stub\n", image, type); + return NotImplemented; +}