Author: gschneider
Date: Mon Apr 6 18:58:12 2009
New Revision: 40394
URL:
http://svn.reactos.org/svn/reactos?rev=40394&view=rev
Log:
- 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
Modified:
trunk/reactos/dll/win32/gdiplus/graphics.c
trunk/reactos/dll/win32/gdiplus/graphicspath.c
trunk/reactos/dll/win32/gdiplus/image.c
trunk/reactos/include/crt/math.h
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] Mon Apr 6 18:58:12 2009
@@ -172,6 +172,164 @@
}
}
+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; i<num_steps; i++)
+ {
+ ARGB argb = blend_colors(line->startcolor, 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; i<num_steps; i++)
+ {
+ ARGB argb = blend_colors(line->startcolor, 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 @@
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;
- }
- else{
+ if (roundr(rect->Width) == 0)
+ {
+ rel_width = 1.0;
+ nwidth = INT_MAX;
+ }
+ 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 @@
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 @@
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 @@
goto end;
EndPath(graphics->hdc);
- FillPath(graphics->hdc);
+ brush_fill_path(graphics, brush);
retval = Ok;
@@ -2749,7 +2921,7 @@
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];
Modified: trunk/reactos/dll/win32/gdiplus/graphicspath.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/graphics…
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/graphicspath.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/graphicspath.c [iso-8859-1] Mon Apr 6 18:58:12 2009
@@ -147,7 +147,7 @@
/* 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
Modified: trunk/reactos/dll/win32/gdiplus/image.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/image.c?…
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/image.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/image.c [iso-8859-1] Mon Apr 6 18:58:12 2009
@@ -249,6 +249,14 @@
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 @@
ERR("could not make stream\n");
GdipFree(*bitmap);
GdipFree(buff);
+ *bitmap = NULL;
return GenericError;
}
@@ -558,6 +567,7 @@
IStream_Release(stream);
GdipFree(*bitmap);
GdipFree(buff);
+ *bitmap = NULL;
return GenericError;
}
Modified: trunk/reactos/include/crt/math.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/crt/math.h?rev=403…
==============================================================================
--- trunk/reactos/include/crt/math.h [iso-8859-1] (original)
+++ trunk/reactos/include/crt/math.h [iso-8859-1] Mon Apr 6 18:58:12 2009
@@ -189,6 +189,9 @@
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 @@
__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