mirror of
https://github.com/reactos/reactos.git
synced 2025-05-23 02:56:09 +00:00
- 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
This commit is contained in:
parent
22e12898e7
commit
62d8ccbbc4
4 changed files with 196 additions and 13 deletions
|
@ -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; 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 */
|
/* GdipDrawPie/GdipFillPie helper function */
|
||||||
static void draw_pie(GpGraphics *graphics, REAL x, REAL y, REAL width,
|
static void draw_pie(GpGraphics *graphics, REAL x, REAL y, REAL width,
|
||||||
REAL height, REAL startAngle, REAL sweepAngle)
|
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;
|
rectcpy[3].Y = rectcpy[2].Y = rect->Y + rect->Height;
|
||||||
transform_and_round_points(graphics, corners, rectcpy, 4);
|
transform_and_round_points(graphics, corners, rectcpy, 4);
|
||||||
|
|
||||||
if(roundr(rect->Width) == 0 && roundr(rect->Height) == 0){
|
if (roundr(rect->Width) == 0)
|
||||||
rel_width = rel_height = 1.0;
|
{
|
||||||
nwidth = nheight = INT_MAX;
|
rel_width = 1.0;
|
||||||
|
nwidth = INT_MAX;
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
rel_width = sqrt((corners[1].x - corners[0].x) * (corners[1].x - corners[0].x) +
|
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))
|
(corners[1].y - corners[0].y) * (corners[1].y - corners[0].y))
|
||||||
/ rect->Width;
|
/ 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) +
|
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))
|
(corners[2].y - corners[1].y) * (corners[2].y - corners[1].y))
|
||||||
/ rect->Height;
|
/ rect->Height;
|
||||||
|
|
||||||
nwidth = roundr(rel_width * rect->Width);
|
|
||||||
nheight = roundr(rel_height * rect->Height);
|
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);
|
rgn = CreatePolygonRgn(corners, 4, ALTERNATE);
|
||||||
SelectClipRgn(graphics->hdc, rgn);
|
SelectClipRgn(graphics->hdc, rgn);
|
||||||
}
|
}
|
||||||
|
@ -1894,7 +2067,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
|
||||||
DeleteObject(SelectObject(graphics->hdc, CreateFontIndirectW(&lfw)));
|
DeleteObject(SelectObject(graphics->hdc, CreateFontIndirectW(&lfw)));
|
||||||
|
|
||||||
for(i = 0, j = 0; i < length; i++){
|
for(i = 0, j = 0; i < length; i++){
|
||||||
if(!isprint(string[i]) && (string[i] != '\n'))
|
if(!isprintW(string[i]) && (string[i] != '\n'))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
stringdup[j] = string[i];
|
stringdup[j] = string[i];
|
||||||
|
@ -2086,7 +2259,6 @@ GpStatus WINGDIPAPI GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *p
|
||||||
|
|
||||||
save_state = SaveDC(graphics->hdc);
|
save_state = SaveDC(graphics->hdc);
|
||||||
EndPath(graphics->hdc);
|
EndPath(graphics->hdc);
|
||||||
SelectObject(graphics->hdc, brush->gdibrush);
|
|
||||||
SetPolyFillMode(graphics->hdc, (path->fill == FillModeAlternate ? ALTERNATE
|
SetPolyFillMode(graphics->hdc, (path->fill == FillModeAlternate ? ALTERNATE
|
||||||
: WINDING));
|
: WINDING));
|
||||||
|
|
||||||
|
@ -2098,7 +2270,7 @@ GpStatus WINGDIPAPI GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *p
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
EndPath(graphics->hdc);
|
EndPath(graphics->hdc);
|
||||||
FillPath(graphics->hdc);
|
brush_fill_path(graphics, brush);
|
||||||
|
|
||||||
retval = Ok;
|
retval = Ok;
|
||||||
|
|
||||||
|
@ -2749,7 +2921,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
|
||||||
nwidth = nheight = INT_MAX;
|
nwidth = nheight = INT_MAX;
|
||||||
|
|
||||||
for(i = 0, j = 0; i < length; i++){
|
for(i = 0, j = 0; i < length; i++){
|
||||||
if(!isprint(string[i]) && (string[i] != '\n'))
|
if(!isprintW(string[i]) && (string[i] != '\n'))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
stringdup[j] = string[i];
|
stringdup[j] = string[i];
|
||||||
|
|
|
@ -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 */
|
/* 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 +
|
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))) <=
|
(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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -249,6 +249,14 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap,
|
||||||
return Ok;
|
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)
|
GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage)
|
||||||
{
|
{
|
||||||
IStream* stream;
|
IStream* stream;
|
||||||
|
@ -549,6 +557,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
|
||||||
ERR("could not make stream\n");
|
ERR("could not make stream\n");
|
||||||
GdipFree(*bitmap);
|
GdipFree(*bitmap);
|
||||||
GdipFree(buff);
|
GdipFree(buff);
|
||||||
|
*bitmap = NULL;
|
||||||
return GenericError;
|
return GenericError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,6 +567,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
|
||||||
IStream_Release(stream);
|
IStream_Release(stream);
|
||||||
GdipFree(*bitmap);
|
GdipFree(*bitmap);
|
||||||
GdipFree(buff);
|
GdipFree(buff);
|
||||||
|
*bitmap = NULL;
|
||||||
return GenericError;
|
return GenericError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,6 +189,9 @@ extern "C" {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
__CRT_INLINE float __cdecl ldexpf (float x, int expn) { return (float) ldexp (x, expn); }
|
__CRT_INLINE float __cdecl ldexpf (float x, int expn) { return (float) ldexp (x, expn); }
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef __x86_64
|
#ifndef __x86_64
|
||||||
__CRT_INLINE float acosf(float _X) { return ((float)acos((double)_X)); }
|
__CRT_INLINE float acosf(float _X) { return ((float)acos((double)_X)); }
|
||||||
__CRT_INLINE float asinf(float _X) { return ((float)asin((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 tanf(float _X) { return ((float)tan((double)_X)); }
|
||||||
__CRT_INLINE float tanhf(float _X) { return ((float)tanh((double)_X)); }
|
__CRT_INLINE float tanhf(float _X) { return ((float)tanh((double)_X)); }
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NO_OLDNAMES
|
#ifndef NO_OLDNAMES
|
||||||
#define DOMAIN _DOMAIN
|
#define DOMAIN _DOMAIN
|
||||||
|
|
Loading…
Reference in a new issue