# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1319539919 0 # Node ID 61d0c5f8464490ac76e5f05af21088477bf51154 # Parent 3cbd8de0b50b109cb53827ef79aba86b3ebf6140 Initial attempt at adding dw_draw_arc() support on all platforms. This code doesn't yet work... will probably require a bunch of fixes... but I wanted to get the code committed while doing research on it. diff -r 3cbd8de0b50b -r 61d0c5f84644 dw.def --- a/dw.def Tue Oct 25 06:21:59 2011 +0000 +++ b/dw.def Tue Oct 25 10:51:59 2011 +0000 @@ -204,6 +204,7 @@ dw_draw_rect @333 dw_draw_text @334 dw_draw_polygon @335 + dw_draw_arc @336 dw_pixmap_bitblt @340 dw_pixmap_new @341 diff -r 3cbd8de0b50b -r 61d0c5f84644 dw.h --- a/dw.h Tue Oct 25 06:21:59 2011 +0000 +++ b/dw.h Tue Oct 25 10:51:59 2011 +0000 @@ -1650,6 +1650,7 @@ void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2); void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height); void API dw_draw_polygon(HWND handle, HPIXMAP pixmap, int fill, int npoints, int *x, int *y); +void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2); void API dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text); void API dw_font_text_extents_get(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height); void API dw_font_set_default(char *fontname); diff -r 3cbd8de0b50b -r 61d0c5f84644 dwtest.c --- a/dwtest.c Tue Oct 25 06:21:59 2011 +0000 +++ b/dwtest.c Tue Oct 25 10:51:59 2011 +0000 @@ -368,6 +368,8 @@ dw_draw_text(window, pixmap, 10, 10, "This should be aligned with the edges."); dw_color_foreground_set(DW_CLR_BLUE); dw_draw_polygon(window, pixmap, TRUE, 7, x, y); + dw_color_foreground_set(DW_CLR_CYAN); + dw_draw_arc(window, pixmap, 0, width - 40, height - 40, width - 40, height - 20, width - 20, height - 40); if(image) { if(image_stretch) diff -r 3cbd8de0b50b -r 61d0c5f84644 dww.def --- a/dww.def Tue Oct 25 06:21:59 2011 +0000 +++ b/dww.def Tue Oct 25 10:51:59 2011 +0000 @@ -201,6 +201,7 @@ dw_draw_rect @333 dw_draw_text @334 dw_draw_polygon @335 + dw_draw_arc @336 dw_pixmap_bitblt @340 dw_pixmap_new @341 diff -r 3cbd8de0b50b -r 61d0c5f84644 gtk/dw.c --- a/gtk/dw.c Tue Oct 25 06:21:59 2011 +0000 +++ b/gtk/dw.c Tue Oct 25 10:51:59 2011 +0000 @@ -28,6 +28,7 @@ #include #include #include +#include #include #ifdef USE_IMLIB #include @@ -8052,6 +8053,76 @@ DW_MUTEX_UNLOCK; } +/* Draw an arc on a window (preferably a render window). + * Parameters: + * handle: Handle to the window. + * pixmap: Handle to the pixmap. (choose only one of these) + * flags: For future use. + * xorigin: X coordinate of center of arc. + * yorigin: Y coordinate of center of arc. + * x1: X coordinate of first segment of arc. + * y1: Y coordinate of first segment of arc. + * x2: X coordinate of second segment of arc. + * y2: Y coordinate of second segment of arc. + */ +void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2) +{ + int _locked_by_me = FALSE; + GdkGC *gc = NULL; +#if GTK_CHECK_VERSION(2,10,0) + cairo_t *cr = NULL; +#endif + double dx = xorigin - x1; + double dy = yorigin - y1; + double r = sqrt(dx*dx + dy*dy); + + DW_MUTEX_LOCK; + if(handle) + gc = _set_colors(handle->window); + else if(pixmap && pixmap->pixmap) + gc = _set_colors(pixmap->pixmap); +#if GTK_CHECK_VERSION(2,10,0) + else if(pixmap && pixmap->image) + cr = cairo_create(pixmap->image); + if(cr) + { + GdkColor *foreground = pthread_getspecific(_dw_fg_color_key); + double a1 = 180/M_PI * arctan((y1-yorigin)/(x1-xorigin)); + double a2 = 180/M_PI * arctan((y2-yorigin)/(x2-xorigin)); + + gdk_cairo_set_source_color (cr, foreground); + cairo_set_line_width(cr, 1); + cairo_arc(cr, xorigin, yorigin, r, a1, a2); + cairo_stroke(cr); + cairo_destroy(cr); + } +#endif + if(gc) + { + double radius1 = 0, radius2 = 0; + int alpha1, alpha2; + + if(x1 == x2 && y1 == y2) + { + radius1 = 0.0; + radius2 = 360.0; + } + else + { + radius1 = (x1 - xorigin == 0) ? (y1 - yc < 0) ? 90.0 : -90.0 : -atan2((double)y1-yc, (double)x1-xc) * RAD2DEG; + radius2 = (x2 - xorigin == 0) ? (y2 - yc < 0) ? 90.0 : -90.0 : -atan2((double)y2-yc, (double)x2-xc) * RAD2DEG; + } + alpha1 = (int)(radius1 * 64.0); + alpha2 = (int)((radius2 - radius1) * 64.0); + while (alpha2 <= 0) alpha2 += 360*64; + while (alpha1 > 360*64) alpha1 -= 360*64; + + gdk_draw_arc(handle ? handle->window : pixmap->pixmap, gc, TRUE, xorigin-r, yorigin-r, 2*r,2*r, alpha1, alpha2); + gdk_gc_unref(gc); + } + DW_MUTEX_UNLOCK; +} + /* Draw text on a window (preferably a render window). * Parameters: * handle: Handle to the window. diff -r 3cbd8de0b50b -r 61d0c5f84644 gtk3/dw.c --- a/gtk3/dw.c Tue Oct 25 06:21:59 2011 +0000 +++ b/gtk3/dw.c Tue Oct 25 10:51:59 2011 +0000 @@ -28,6 +28,7 @@ #include #include #include +#include #include #ifdef USE_GTKMOZEMBED @@ -6922,6 +6923,55 @@ DW_MUTEX_UNLOCK; } +/* Draw an arc on a window (preferably a render window). + * Parameters: + * handle: Handle to the window. + * pixmap: Handle to the pixmap. (choose only one of these) + * flags: For future use. + * xorigin: X coordinate of center of arc. + * yorigin: Y coordinate of center of arc. + * x1: X coordinate of first segment of arc. + * y1: Y coordinate of first segment of arc. + * x2: X coordinate of second segment of arc. + * y2: Y coordinate of second segment of arc. + */ +void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2) +{ + int _locked_by_me = FALSE; + cairo_t *cr = NULL; + + DW_MUTEX_LOCK; + if(handle) + { + GdkWindow *window = gtk_widget_get_window(handle); + /* Safety check for non-existant windows */ + if(!window || !GDK_IS_WINDOW(window)) + { + DW_MUTEX_UNLOCK; + return; + } + cr = gdk_cairo_create(window); + } + else if(pixmap) + cr = cairo_create(pixmap->image); + if(cr) + { + GdkColor *foreground = pthread_getspecific(_dw_fg_color_key); + double dx = xorigin - x1; + double dy = yorigin - y1; + double r = sqrt(dx*dx + dy*dy); + double a1 = 180/M_PI * arctan((y1-yorigin)/(x1-xorigin)); + double a2 = 180/M_PI * arctan((y2-yorigin)/(x2-xorigin)); + + gdk_cairo_set_source_color (cr, foreground); + cairo_set_line_width(cr, 1); + cairo_arc(cr, xorigin, yorigin, r, a1, a2); + cairo_stroke(cr); + cairo_destroy(cr); + } + DW_MUTEX_UNLOCK; +} + /* Draw text on a window (preferably a render window). * Parameters: * handle: Handle to the window. diff -r 3cbd8de0b50b -r 61d0c5f84644 mac/dw.m --- a/mac/dw.m Tue Oct 25 06:21:59 2011 +0000 +++ b/mac/dw.m Tue Oct 25 10:51:59 2011 +0000 @@ -17,6 +17,7 @@ #include #include #include +#include /* Create a define to let us know to include Snow Leopard specific features */ #if defined(MAC_OS_X_VERSION_10_6) && ((defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) || !defined(MAC_OS_X_VERSION_MIN_REQUIRED)) @@ -5226,6 +5227,71 @@ DW_MUTEX_UNLOCK; } +/* Draw an arc on a window (preferably a render window). + * Parameters: + * handle: Handle to the window. + * pixmap: Handle to the pixmap. (choose only one of these) + * flags: For future use. + * xorigin: X coordinate of center of arc. + * yorigin: Y coordinate of center of arc. + * x1: X coordinate of first segment of arc. + * y1: Y coordinate of first segment of arc. + * x2: X coordinate of second segment of arc. + * y2: Y coordinate of second segment of arc. + */ +void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2) +{ + int _locked_by_me = FALSE; + DW_MUTEX_LOCK; + id image = handle; + double r, a1, a2, a; + int x3, y3; + + if(pixmap) + { + image = (id)pixmap->image; + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext + graphicsContextWithGraphicsPort:[[NSGraphicsContext graphicsContextWithBitmapImageRep:image] graphicsPort] flipped:YES]]; + } + else + { + if([image lockFocusIfCanDraw] == NO) + { + DW_MUTEX_UNLOCK; + return; + } + _DWLastDrawable = handle; + } + NSBezierPath* aPath = [NSBezierPath bezierPath]; + [aPath setLineWidth: 0.5]; + NSColor *color = pthread_getspecific(_dw_fg_color_key); + [color set]; + + [aPath moveToPoint:NSMakePoint(x1, y1)]; + /* Calculate the midpoint */ + r = 0.5 * (hypot((double)(y1 - yorigin), (double)(x1 - xorigin)) + + hypot((double)(y2 - yorigin), (double)(x2 - xorigin))); + a1 = atan2((double)(y1 - yorigin), (double)(x1 - xorigin)); + a2 = atan2((double)(y2 - yorigin), (double)(x2 - xorigin)); + if(a2 < a1) + a2 += M_PI * 2; + a = (a1 + a2) / 2.; + /* Prepare to draw */ + [aPath appendBezierPathWithArcFromPoint:NSMakePoint((xorigin + r * cos(a)), (yorigin + r * sin(a))) + toPoint:NSMakePoint(x2, y2) radius:r]; + [aPath stroke]; + if(pixmap) + { + [NSGraphicsContext restoreGraphicsState]; + } + else + { + [image unlockFocus]; + } + DW_MUTEX_UNLOCK; +} + /* * Create a tree object to be packed. * Parameters: diff -r 3cbd8de0b50b -r 61d0c5f84644 os2/dw.c --- a/os2/dw.c Tue Oct 25 06:21:59 2011 +0000 +++ b/os2/dw.c Tue Oct 25 10:51:59 2011 +0000 @@ -28,6 +28,7 @@ #include #include #include +#include #ifndef __EMX__ #include #endif @@ -8659,6 +8660,66 @@ WinReleasePS(hps); } +/* Draw an arc on a window (preferably a render window). + * Parameters: + * handle: Handle to the window. + * pixmap: Handle to the pixmap. (choose only one of these) + * flags: For future use. + * xorigin: X coordinate of center of arc. + * yorigin: Y coordinate of center of arc. + * x1: X coordinate of first segment of arc. + * y1: Y coordinate of first segment of arc. + * x2: X coordinate of second segment of arc. + * y2: Y coordinate of second segment of arc. + */ +void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2) +{ + HPS hps; + int thisheight; + ARCPARAMS ap = { 1, 1, 0, 0 }; + POINTL pts[2]; + double r, a1, a2, a; + int x3, y3; + + if(handle) + { + hps = _set_colors(handle); + thisheight = _get_height(handle); + } + else if(pixmap) + { + hps = _set_hps(pixmap->hps); + thisheight = pixmap->height; + } + else + return; + + /* Setup the arc info on the presentation space */ + GpiSetArcParams(hps, &ap); + pts[0].x = x1; + pts[0].y = thisheight - y1 - 1; + /* Move to the initial position */ + GpiMove(hps, pts); + /* Calculate the midpoint */ + r = 0.5 * (hypot((double)(y1 - yorigin), (double)(x1 - xorigin)) + + hypot((double)(y2 - yorigin), (double)(x2 - xorigin))); + a1 = atan2((double)(y1 - yorigin), (double)(x1 - xorigin)); + a2 = atan2((double)(y2 - yorigin), (double)(x2 - xorigin)); + if(a2 < a1) + a2 += M_PI * 2; + a = (a1 + a2) / 2.; + /* Prepare to draw */ + pts[0].x = (int)(xorigin + r * cos(a)); + pts[0].y = thisheight - (int)(yorigin + r * sin(a)) - 1; + pts[1].x = x2; + pts[1].y = thisheight - y2 - 1; + /* Actually draw the arc */ + GpiPointArc(hps, pts); + + if(!pixmap) + WinReleasePS(hps); +} + /* Call this after drawing to the screen to make sure * anything you have drawn is visible. */ diff -r 3cbd8de0b50b -r 61d0c5f84644 template/dw.c --- a/template/dw.c Tue Oct 25 06:21:59 2011 +0000 +++ b/template/dw.c Tue Oct 25 10:51:59 2011 +0000 @@ -1529,6 +1529,22 @@ { } +/* Draw an arc on a window (preferably a render window). + * Parameters: + * handle: Handle to the window. + * pixmap: Handle to the pixmap. (choose only one of these) + * flags: For future use. + * xorigin: X coordinate of center of arc. + * yorigin: Y coordinate of center of arc. + * x1: X coordinate of first segment of arc. + * y1: Y coordinate of first segment of arc. + * x2: X coordinate of second segment of arc. + * y2: Y coordinate of second segment of arc. + */ +void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2) +{ +} + /* * Create a tree object to be packed. * Parameters: diff -r 3cbd8de0b50b -r 61d0c5f84644 win/dw.c --- a/win/dw.c Tue Oct 25 06:21:59 2011 +0000 +++ b/win/dw.c Tue Oct 25 10:51:59 2011 +0000 @@ -8815,6 +8815,44 @@ ReleaseDC(handle, hdcPaint); } +/* Draw an arc on a window (preferably a render window). + * Parameters: + * handle: Handle to the window. + * pixmap: Handle to the pixmap. (choose only one of these) + * flags: For future use. + * xorigin: X coordinate of center of arc. + * yorigin: Y coordinate of center of arc. + * x1: X coordinate of first segment of arc. + * y1: Y coordinate of first segment of arc. + * x2: X coordinate of second segment of arc. + * y2: Y coordinate of second segment of arc. + */ +void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2) +{ + HDC hdcPaint; + HBRUSH oldBrush; + HPEN oldPen; + double dx = xorigin - x1; + double dy = yorigin - y1; + double r = sqrt(dx*dx + dy*dy); + + if(handle) + hdcPaint = GetDC(handle); + else if(pixmap) + hdcPaint = pixmap->hdc; + else + return; + + oldBrush = SelectObject( hdcPaint, TlsGetValue(_hBrush) ); + oldPen = SelectObject( hdcPaint, TlsGetValue(_hPen) ); + Arc(hdcPaint, xorigin-r, yorigin-r, xorigin+r, yorigin+r, x1, y1, x2, y2); + SelectObject( hdcPaint, oldBrush ); + SelectObject( hdcPaint, oldPen ); + + if(!pixmap) + ReleaseDC(handle, hdcPaint); +} + /* Draw text on a window (preferably a render window). * Parameters: * handle: Handle to the window.