Misha Koshelev : gdi32: Fix ArcTo to use proper starting and ending points.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Jun 19 06:42:38 CDT 2007


Module: wine
Branch: master
Commit: 1dbe178f5ea44a13cdb5134817c0de4e1bbd0ea1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1dbe178f5ea44a13cdb5134817c0de4e1bbd0ea1

Author: Misha Koshelev <mk144210 at bcm.edu>
Date:   Tue Jun 19 01:44:26 2007 -0500

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 ba7f451..807fee4 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 a9fab4b..bd7c12c 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 */




More information about the wine-cvs mailing list