From 1dbe178f5ea44a13cdb5134817c0de4e1bbd0ea1 Mon Sep 17 00:00:00 2001 From: Misha Koshelev Date: Tue, 19 Jun 2007 01:44:26 -0500 Subject: [PATCH] gdi32: Fix ArcTo to use proper starting and ending points. --- dlls/gdi32/painting.c | 52 +++++++++++++++++++++++++++-------------- dlls/gdi32/tests/path.c | 4 ++-- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/dlls/gdi32/painting.c b/dlls/gdi32/painting.c index ba7f4519398..807fee414aa 100644 --- a/dlls/gdi32/painting.c +++ b/dlls/gdi32/painting.c @@ -118,28 +118,44 @@ BOOL WINAPI ArcTo( HDC hdc, if(!dc) return FALSE; if(dc->funcs->pArcTo) - { result = dc->funcs->pArcTo( dc->physDev, left, top, right, bottom, xstart, ystart, xend, yend ); - GDI_ReleaseObj( hdc ); - return result; + else + { + double width = fabs(right-left), + height = fabs(bottom-top), + xradius = width/2, + yradius = height/2, + xcenter = right > left ? left+xradius : right+xradius, + ycenter = bottom > top ? top+yradius : bottom+yradius; + /* + * Else emulate it. + * According to the documentation, a line is drawn from the current + * position to the starting point of the arc. + */ + double angle = atan2( + ((ystart-ycenter)/height), + ((xstart-xcenter)/width)); + LineTo(hdc, GDI_ROUND(xcenter+(cos(angle)*xradius)), + GDI_ROUND(ycenter+(sin(angle)*yradius))); + /* + * Then the arc is drawn. + */ + result = Arc(hdc, left, top, right, bottom, xstart, ystart, xend, yend); + /* + * If no error occurred, the current position is moved to the ending + * point of the arc. + */ + if (result) + { + angle = atan2( + ((yend-ycenter)/height), + ((xend-xcenter)/width)); + MoveToEx(hdc, GDI_ROUND(xcenter+(cos(angle)*xradius)), + GDI_ROUND(ycenter+(sin(angle)*yradius)), NULL); + } } GDI_ReleaseObj( hdc ); - /* - * Else emulate it. - * According to the documentation, a line is drawn from the current - * position to the starting point of the arc. - */ - LineTo(hdc, xstart, ystart); - /* - * Then the arc is drawn. - */ - result = Arc(hdc, left, top, right, bottom, xstart, ystart, xend, yend); - /* - * If no error occurred, the current position is moved to the ending - * point of the arc. - */ - if (result) MoveToEx(hdc, xend, yend, NULL); return result; } diff --git a/dlls/gdi32/tests/path.c b/dlls/gdi32/tests/path.c index a9fab4b28b6..bd7c12c7c04 100644 --- a/dlls/gdi32/tests/path.c +++ b/dlls/gdi32/tests/path.c @@ -193,7 +193,7 @@ static void ok_path(HDC hdc, const path_test_t *expected, int expected_size, BOO static const path_test_t arcto_path[] = { {0, 0, PT_MOVETO, 0, 0}, /* 0 */ - {229, 215, PT_LINETO, 0, 1}, /* 1 */ + {229, 215, PT_LINETO, 0, 0}, /* 1 */ {248, 205, PT_BEZIERTO, 1, 0}, /* 2 */ {273, 200, PT_BEZIERTO, 0, 0}, /* 3 */ {300, 200, PT_BEZIERTO, 0, 0}, /* 4 */ @@ -203,7 +203,7 @@ static const path_test_t arcto_path[] = { {399, 263, PT_BEZIERTO, 0, 0}, /* 8 */ {389, 275, PT_BEZIERTO, 0, 0}, /* 9 */ {370, 285, PT_BEZIERTO, 0, 0}, /* 10 */ - {363, 277, PT_LINETO, 1, 1}, /* 11 */ + {363, 277, PT_LINETO, 1, 0}, /* 11 */ {380, 270, PT_BEZIERTO, 1, 0}, /* 12 */ {389, 260, PT_BEZIERTO, 0, 0}, /* 13 */ {389, 250, PT_BEZIERTO, 0, 0}, /* 14 */