From 62d8ccbbc4ee420fddac55db2ac8c235572b8344 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Mon, 6 Apr 2009 14:58:12 +0000 Subject: [PATCH] - include/crt/math.h: float type math functions are not c++ specific, they are especially needed in the c language - move code accordingly - dll/win32/gdiplus: sync with current wine, correct sqrtf usage svn path=/trunk/; revision=40394 --- reactos/dll/win32/gdiplus/graphics.c | 192 +++++++++++++++++++++-- reactos/dll/win32/gdiplus/graphicspath.c | 2 +- reactos/dll/win32/gdiplus/image.c | 10 ++ reactos/include/crt/math.h | 5 +- 4 files changed, 196 insertions(+), 13 deletions(-) diff --git a/reactos/dll/win32/gdiplus/graphics.c b/reactos/dll/win32/gdiplus/graphics.c index f76e43c797c..2a98ee51b1b 100644 --- a/reactos/dll/win32/gdiplus/graphics.c +++ b/reactos/dll/win32/gdiplus/graphics.c @@ -172,6 +172,164 @@ static void transform_and_round_points(GpGraphics *graphics, POINT *pti, } } +static ARGB blend_colors(ARGB start, ARGB end, int current, int total) +{ + ARGB result=0; + ARGB i; + for (i=0xff; i<=0xff0000; i = i << 8) + result |= (((start&i)*(total - current)+(end&i)*(current))/total)&i; + return result; +} + +static void brush_fill_path(GpGraphics *graphics, GpBrush* brush) +{ + switch (brush->bt) + { + case BrushTypeLinearGradient: + { + GpLineGradient *line = (GpLineGradient*)brush; + RECT rc; + int num_steps = 255; + + 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)); + + /* 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); + + 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 width; + COLORREF col; + HBRUSH hbrush, hprevbrush; + int i; + + if (endpointsi[1].x > endpointsi[0].x) + endborderx = rc.right; + else + endborderx = rc.left; + + 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; + 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; istartcolor, line->endcolor, i, num_steps); + int ofs = width * i / num_steps; + col = ARGB2COLORREF(argb); + hbrush = CreateSolidBrush(col); + hprevbrush = SelectObject(graphics->hdc, hbrush); + poly[2].x = startx + ofs; + poly[3].x = startbottomx + ofs; + 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 height; + COLORREF col; + HBRUSH hbrush, hprevbrush; + int i; + + if (endpointsi[1].y > endpointsi[0].y) + endbordery = rc.bottom; + else + endbordery = rc.top; + + 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); + + 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; istartcolor, line->endcolor, i, num_steps); + int ofs = height * i / num_steps; + col = ARGB2COLORREF(argb); + hbrush = CreateSolidBrush(col); + hprevbrush = SelectObject(graphics->hdc, hbrush); + poly[2].y = starty + ofs; + poly[3].y = startrighty + ofs; + 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 */ + } + break; + } + default: + SelectObject(graphics->hdc, brush->gdibrush); + FillPath(graphics->hdc); + break; + } +} + /* GdipDrawPie/GdipFillPie helper function */ static void draw_pie(GpGraphics *graphics, REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle) @@ -1853,20 +2011,35 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string rectcpy[3].Y = rectcpy[2].Y = rect->Y + rect->Height; transform_and_round_points(graphics, corners, rectcpy, 4); - if(roundr(rect->Width) == 0 && roundr(rect->Height) == 0){ - rel_width = rel_height = 1.0; - nwidth = nheight = INT_MAX; + if (roundr(rect->Width) == 0) + { + rel_width = 1.0; + nwidth = INT_MAX; } - else{ + else + { rel_width = sqrt((corners[1].x - corners[0].x) * (corners[1].x - corners[0].x) + (corners[1].y - corners[0].y) * (corners[1].y - corners[0].y)) / rect->Width; + nwidth = roundr(rel_width * rect->Width); + } + + if (roundr(rect->Height) == 0) + { + rel_height = 1.0; + nheight = INT_MAX; + } + else + { rel_height = sqrt((corners[2].x - corners[1].x) * (corners[2].x - corners[1].x) + (corners[2].y - corners[1].y) * (corners[2].y - corners[1].y)) / rect->Height; - - nwidth = roundr(rel_width * rect->Width); nheight = roundr(rel_height * rect->Height); + } + + if (roundr(rect->Width) != 0 && roundr(rect->Height) != 0) + { + /* FIXME: If only the width or only the height is 0, we should probably still clip */ rgn = CreatePolygonRgn(corners, 4, ALTERNATE); SelectClipRgn(graphics->hdc, rgn); } @@ -1894,7 +2067,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string DeleteObject(SelectObject(graphics->hdc, CreateFontIndirectW(&lfw))); for(i = 0, j = 0; i < length; i++){ - if(!isprint(string[i]) && (string[i] != '\n')) + if(!isprintW(string[i]) && (string[i] != '\n')) continue; stringdup[j] = string[i]; @@ -2086,7 +2259,6 @@ GpStatus WINGDIPAPI GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *p save_state = SaveDC(graphics->hdc); EndPath(graphics->hdc); - SelectObject(graphics->hdc, brush->gdibrush); SetPolyFillMode(graphics->hdc, (path->fill == FillModeAlternate ? ALTERNATE : WINDING)); @@ -2098,7 +2270,7 @@ GpStatus WINGDIPAPI GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *p goto end; EndPath(graphics->hdc); - FillPath(graphics->hdc); + brush_fill_path(graphics, brush); retval = Ok; @@ -2749,7 +2921,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics, nwidth = nheight = INT_MAX; for(i = 0, j = 0; i < length; i++){ - if(!isprint(string[i]) && (string[i] != '\n')) + if(!isprintW(string[i]) && (string[i] != '\n')) continue; stringdup[j] = string[i]; diff --git a/reactos/dll/win32/gdiplus/graphicspath.c b/reactos/dll/win32/gdiplus/graphicspath.c index 6a4c99d4c2c..ca33082731e 100644 --- a/reactos/dll/win32/gdiplus/graphicspath.c +++ b/reactos/dll/win32/gdiplus/graphicspath.c @@ -147,7 +147,7 @@ static BOOL flatten_bezier(path_list_node_t *start, REAL x2, REAL y2, REAL x3, R /* check flatness as a half of distance between middle point and a linearized path */ if(fabs(((pt.Y - pt_st.Y)*mp[2].X + (pt_st.X - pt.X)*mp[2].Y + (pt_st.Y*pt.X - pt_st.X*pt.Y))) <= - (0.5 * flatness*sqrt((powf(pt.Y - pt_st.Y, 2.0) + powf(pt_st.X - pt.X, 2.0))))){ + (0.5 * flatness*sqrtf((powf(pt.Y - pt_st.Y, 2.0) + powf(pt_st.X - pt.X, 2.0))))){ return TRUE; } else diff --git a/reactos/dll/win32/gdiplus/image.c b/reactos/dll/win32/gdiplus/image.c index a229f8b637d..8a4dcc27389 100644 --- a/reactos/dll/win32/gdiplus/image.c +++ b/reactos/dll/win32/gdiplus/image.c @@ -249,6 +249,14 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap, return Ok; } +GpStatus WINGDIPAPI GdipCloneBitmapAreaI(INT x, INT y, INT width, INT height, + PixelFormat format, GpBitmap* srcBitmap, GpBitmap** dstBitmap) +{ + FIXME("(%i,%i,%i,%i,%i,%p,%p)\n", x, y, width, height, format, srcBitmap, dstBitmap); + + return NotImplemented; +} + GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage) { IStream* stream; @@ -549,6 +557,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride, ERR("could not make stream\n"); GdipFree(*bitmap); GdipFree(buff); + *bitmap = NULL; return GenericError; } @@ -558,6 +567,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride, IStream_Release(stream); GdipFree(*bitmap); GdipFree(buff); + *bitmap = NULL; return GenericError; } diff --git a/reactos/include/crt/math.h b/reactos/include/crt/math.h index 2647b032159..6fa5a43d5d5 100644 --- a/reactos/include/crt/math.h +++ b/reactos/include/crt/math.h @@ -189,6 +189,9 @@ extern "C" { return res; } __CRT_INLINE float __cdecl ldexpf (float x, int expn) { return (float) ldexp (x, expn); } +#endif +#endif + #ifndef __x86_64 __CRT_INLINE float acosf(float _X) { return ((float)acos((double)_X)); } __CRT_INLINE float asinf(float _X) { return ((float)asin((double)_X)); } @@ -214,8 +217,6 @@ extern "C" { __CRT_INLINE float tanf(float _X) { return ((float)tan((double)_X)); } __CRT_INLINE float tanhf(float _X) { return ((float)tanh((double)_X)); } #endif -#endif -#endif #ifndef NO_OLDNAMES #define DOMAIN _DOMAIN