[dasher] CDasherScreen::DrawCircle: tidy params (as DrawRect), implement for MacOS/iPhone



commit 615e0f0b9b120e5c3b947432aed05bea08d206be
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Thu Dec 2 13:04:43 2010 +0000

    CDasherScreen::DrawCircle: tidy params (as DrawRect), implement for MacOS/iPhone
    
    i.e. remove bFill (fill iff iFillColour!=-1), outline if iLineWidth>0.
    MacOS/iPhone OpenGL uses repeated rotation to make GL_TRIANGLE_FAN/GL_LINE_LOOP,
    w/ points memo'd in case same radius (always for CircleStart - the only client!)

 Src/DasherCore/CircleStartHandler.cpp      |    8 ++--
 Src/DasherCore/DasherScreen.h              |    6 ++-
 Src/Gtk2/Canvas.cpp                        |   22 +++++-----
 Src/Gtk2/Canvas.h                          |    2 +-
 Src/Gtk2/CanvasExperimental.cpp            |    6 +-
 Src/Gtk2/CanvasExperimental.h              |    2 +-
 Src/MacOSX/COSXDasherScreen.h              |    2 +-
 Src/MacOSX/COSXDasherScreen.mm             |    4 +-
 Src/MacOSX/DasherViewAqua.h                |    2 +-
 Src/MacOSX/DasherViewAqua.mm               |   15 ++++---
 Src/MacOSX/DasherViewCocoa.h               |    2 +-
 Src/MacOSX/DasherViewOpenGL.h              |    6 ++-
 Src/MacOSX/DasherViewOpenGL.mm             |   64 ++++++++++++++++++++++------
 Src/Win32/Widgets/Screen.h                 |    2 +-
 Src/Win32/Widgets/Screen.inl               |    8 ++--
 Src/iPhone/Classes/CDasherScreenBridge.h   |    2 +-
 Src/iPhone/Classes/CDasherScreenBridge.mm  |    4 +-
 Src/iPhone/Classes/DasherScreenCallbacks.h |    2 +-
 Src/iPhone/Classes/EAGLView.h              |    6 +++
 Src/iPhone/Classes/EAGLView.mm             |   52 ++++++++++++++++++++++-
 20 files changed, 159 insertions(+), 58 deletions(-)
---
diff --git a/Src/DasherCore/CircleStartHandler.cpp b/Src/DasherCore/CircleStartHandler.cpp
index 3155d13..c202c70 100644
--- a/Src/DasherCore/CircleStartHandler.cpp
+++ b/Src/DasherCore/CircleStartHandler.cpp
@@ -55,13 +55,13 @@ bool CCircleStartHandler::DecorateView(CDasherView *pView) {
   }
 
   if((m_iStatus == 0) || (m_iStatus == 2))
-    pView->Screen()->DrawCircle(iCX, iCY, m_iScreenRadius, 2, 242, 1, true);
+    pView->Screen()->DrawCircle(iCX, iCY, m_iScreenRadius, 242, 2, 1);
   else if((m_iStatus == 1) || (m_iStatus == 3))
-    pView->Screen()->DrawCircle(iCX, iCY, m_iScreenRadius, 240, 0, 1, false);
+    pView->Screen()->DrawCircle(iCX, iCY, m_iScreenRadius, -1, 240, 1);
   else if(m_iStatus == 5)
-    pView->Screen()->DrawCircle(iCX, iCY, m_iScreenRadius, 2, 241, 1, true);
+    pView->Screen()->DrawCircle(iCX, iCY, m_iScreenRadius, 241, 2, 1);
   else
-    pView->Screen()->DrawCircle(iCX, iCY, m_iScreenRadius, 240, 0, 3, false);
+    pView->Screen()->DrawCircle(iCX, iCY, m_iScreenRadius, -1, 240, 3);
 
   return true;
 }
diff --git a/Src/DasherCore/DasherScreen.h b/Src/DasherCore/DasherScreen.h
index 6a0e3e1..95f4140 100644
--- a/Src/DasherCore/DasherScreen.h
+++ b/Src/DasherCore/DasherScreen.h
@@ -75,7 +75,11 @@ public:
   /// \param iThickness Line thickness for outline; <1 for no outline
   virtual void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Colour, int iOutlineColour, int iThickness) = 0;
 
-  virtual void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill) = 0;
+  ///Draw a circle, potentially filled and/or outlined
+  /// \param iFillColour colour in which to fill; -1 for no fill
+  /// \param iLineColour colour to draw outline; -1 = use default
+  /// \param iLineWidth line width for outline; <1 for no outline
+  virtual void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iFillColour, int iLineColour, int iLineWidth) = 0;
 
   /// Draw a line of fixed colour (usually black). Intended for static UI elements such as a cross-hair
   /// Draw a line between each of the points in the array
diff --git a/Src/Gtk2/Canvas.cpp b/Src/Gtk2/Canvas.cpp
index d692127..bcb194e 100644
--- a/Src/Gtk2/Canvas.cpp
+++ b/Src/Gtk2/Canvas.cpp
@@ -260,12 +260,9 @@ void CCanvas::DrawRectangle(screenint x1, screenint y1, screenint x2, screenint
   END_DRAWING;
 }
 
-void CCanvas::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill) {
+void CCanvas::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iFillColour, int iLineColour, int iThickness) {
 #if WITH_CAIRO
 #else
-  if(iThickness == 1) // This is to make it work propely on Windows
-    iThickness = 0; 
-
   GdkGC *graphics_context;
   GdkColormap *colormap;
 
@@ -275,7 +272,7 @@ void CCanvas::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour
 
   BEGIN_DRAWING;
 
-  if(bFill) {
+  if(iFillColour!=-1) {
     SET_COLOR(iFillColour);
 #if WITH_CAIRO
     cairo_arc(cr, iCX, iCY, iR, 0, 2*M_PI);
@@ -285,15 +282,18 @@ void CCanvas::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour
 #endif
   }
 
-  SET_COLOR(iColour);
+  if (iThickness>0) {
+    SET_COLOR(iLineColour);
 #if WITH_CAIRO
-  cairo_set_line_width(cr, iThickness);
-  cairo_arc(cr, iCX, iCY, iR, 0, 2*M_PI);
-  cairo_stroke(cr);
+    cairo_set_line_width(cr, iThickness);
+    cairo_arc(cr, iCX, iCY, iR, 0, 2*M_PI);
+    cairo_stroke(cr);
 #else
-  gdk_gc_set_line_attributes(graphics_context, iThickness, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND );
-  gdk_draw_arc(m_pOffscreenBuffer, graphics_context, false, iCX - iR, iCY - iR, 2*iR, 2*iR, 0, 23040);
+    //note fiddle on iThickness, allegedly "to make it work on Windows"(?)...
+    gdk_gc_set_line_attributes(graphics_context, iThickness==1 ? 0 : iThickness, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND );
+    gdk_draw_arc(m_pOffscreenBuffer, graphics_context, false, iCX - iR, iCY - iR, 2*iR, 2*iR, 0, 23040);
 #endif
+  }
 
   END_DRAWING;
 }
diff --git a/Src/Gtk2/Canvas.h b/Src/Gtk2/Canvas.h
index 47ea95e..7669ee9 100644
--- a/Src/Gtk2/Canvas.h
+++ b/Src/Gtk2/Canvas.h
@@ -149,7 +149,7 @@ public:
   ///
   void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, int iThickness);
 
-  void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill);
+  void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iFillColour, int iLineColour, int iThickness);
 
   ///
   /// Send a marker to indicate phases of the redraw process. This is
diff --git a/Src/Gtk2/CanvasExperimental.cpp b/Src/Gtk2/CanvasExperimental.cpp
index 74b0ee4..580fda2 100644
--- a/Src/Gtk2/CanvasExperimental.cpp
+++ b/Src/Gtk2/CanvasExperimental.cpp
@@ -472,12 +472,12 @@ void CCanvas::CircleFill(int xCenter,int yCenter,int radius,int Colour)
 	    HVThinLine(xCenter+y,yCenter-x,xCenter+y,yCenter+x,Colour);
       }
 }
-void CCanvas::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill) {
+void CCanvas::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iFillColour, int iLineColour, int iThickness) {
 
 
-  if (bFill)
+  if (iFillColour!=-1)
 	CircleFill(iCX,iCY,iR,iFillColour);
-  CircleMidpoint(iCX,iCY,iR,iColour,iThickness);
+  if (iThickness>0) CircleMidpoint(iCX,iCY,iR,iColour,iThickness);
 }
 bool CCanvas::HorizontalIntersectionPoint(int h,int a,int b,int x0,int y0,int x1,int y1, int *p)
 {
diff --git a/Src/Gtk2/CanvasExperimental.h b/Src/Gtk2/CanvasExperimental.h
index d1b6f6e..bf39c9d 100644
--- a/Src/Gtk2/CanvasExperimental.h
+++ b/Src/Gtk2/CanvasExperimental.h
@@ -118,7 +118,7 @@ public:
   ///
   void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, int iThickness);
 
-  void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill);
+  void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iFillColour, int iLineColour, int iThickness);
 
   ///
   /// Send a marker to indicate phases of the redraw process. This is
diff --git a/Src/MacOSX/COSXDasherScreen.h b/Src/MacOSX/COSXDasherScreen.h
index c8cf4e7..6c3b76a 100644
--- a/Src/MacOSX/COSXDasherScreen.h
+++ b/Src/MacOSX/COSXDasherScreen.h
@@ -99,7 +99,7 @@ public:
   ///
   void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, int iThickness);
   
-  void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill);
+  void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iFillColour, int iLineColour, int iThickness);
   
   ///
   /// Send a marker to indicate phases of the redraw process. This is
diff --git a/Src/MacOSX/COSXDasherScreen.mm b/Src/MacOSX/COSXDasherScreen.mm
index 0517af8..d028953 100644
--- a/Src/MacOSX/COSXDasherScreen.mm
+++ b/Src/MacOSX/COSXDasherScreen.mm
@@ -33,9 +33,9 @@ void COSXDasherScreen::DrawRectangle(int x1, int y1, int x2, int y2, int Color,
   [dasherView rectangleCallbackX1:x1 y1:y1 x2:x2 y2:y2 fillColorIndex:Color outlineColorIndex:(iOutlineColour==-1 ? 3 : iOutlineColour) lineWidth:iThickness];
 }
 
-void COSXDasherScreen::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill) {
+void COSXDasherScreen::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iFillColour, int iLineColour, int iThickness) {
 
-  [dasherView circleCallbackCentrePoint:NSMakePoint(iCX, iCY) radius:iR outlineColorIndex:iColour fillColourIndex:iFillColour shouldFill:bFill lineWidth:iThickness];
+  [dasherView circleCallbackCentrePoint:NSMakePoint(iCX, iCY) radius:iR fillColourIndex:iFillColour outlineColorIndex:(iLineColour==-1 ? 3 : iLineColour) lineWidth:iThickness];
 }
 
 void COSXDasherScreen::Polygon(Dasher::CDasherScreen::point *Points, int Number, int fillColour, int outlineColour, int iWidth) {
diff --git a/Src/MacOSX/DasherViewAqua.h b/Src/MacOSX/DasherViewAqua.h
index 210dbbe..67b4717 100755
--- a/Src/MacOSX/DasherViewAqua.h
+++ b/Src/MacOSX/DasherViewAqua.h
@@ -48,7 +48,7 @@
 - (void)mouseDown:(NSEvent *)e;
 - (void)mouseUp:(NSEvent *)e;
 - (void)keyDown:(NSEvent *)e;
-- (void)circleCallbackCentrePoint:(NSPoint)aCentrePoint radius:(float)aRadius outlineColorIndex:(int)anOutlineColorIndex fillColourIndex:(int)aFillColourIndex shouldFill:(BOOL)shouldFill lineWidth:(int)aLineWidth;
+- (void)circleCallbackCentrePoint:(NSPoint)aCentrePoint radius:(float)aRadius fillColourIndex:(int)aFillColourIndex outlineColorIndex:(int)anOutlineColorIndex lineWidth:(int)aLineWidth;
 - (void)rectangleCallbackX1:(int)x1 y1:(int)y1 x2:(int)x2 y2:(int)y2 fillColorIndex:(int)aFillColorIndex outlineColorIndex:(int)anOutlineColorIndex lineWidth:(int)aLineWidth;
 - (NSSize)textSizeCallbackWithString:(NSString *)aString size:(int)aSize;
 - (void)drawTextCallbackWithString:(NSString *)aString x1:(int)x1 y1:(int)y1 size:(int)aSize colorIndex:(int)aColorIndex;
diff --git a/Src/MacOSX/DasherViewAqua.mm b/Src/MacOSX/DasherViewAqua.mm
index f6ebb20..179e683 100755
--- a/Src/MacOSX/DasherViewAqua.mm
+++ b/Src/MacOSX/DasherViewAqua.mm
@@ -100,17 +100,20 @@
 {
 }
 
-- (void)circleCallbackCentrePoint:(NSPoint)aCentrePoint radius:(float)aRadius outlineColorIndex:(int)anOutlineColorIndex fillColourIndex:(int)aFillColourIndex shouldFill:(BOOL)shouldFill lineWidth:(int)aLineWidth {
+- (void)circleCallbackCentrePoint:(NSPoint)aCentrePoint radius:(float)aRadius fillColourIndex:(int)aFillColour outlineColorIndex:(int)anOutlineColorIndex lineWidth:(int)aLineWidth {
   
   NSBezierPath *bp = [NSBezierPath bezierPathWithOvalInRect:NSMakeRect(aCentrePoint.x - aRadius, aCentrePoint.y - aRadius, 2.0 * aRadius, 2.0 * aRadius)];
+
+  if (aLineWidth>0) {
   
-  [[self colorWithColorIndex:anOutlineColorIndex == -1 ? 3 : anOutlineColorIndex] set];
+    [[self colorWithColorIndex:anOutlineColorIndex] set];
   
-  [NSBezierPath setDefaultLineWidth:aLineWidth];
-  [bp stroke];
+    [NSBezierPath setDefaultLineWidth:aLineWidth];
+    [bp stroke];
+  }
   
-  if (shouldFill) {
-    [[self colorWithColorIndex:aFillColourIndex] set];
+  if (aFillColour!=-1) {
+    [[self colorWithColorIndex:aFillColour] set];
     [bp fill];
   }
 }
diff --git a/Src/MacOSX/DasherViewCocoa.h b/Src/MacOSX/DasherViewCocoa.h
index 5e8d5eb..a3cc539 100644
--- a/Src/MacOSX/DasherViewCocoa.h
+++ b/Src/MacOSX/DasherViewCocoa.h
@@ -18,7 +18,7 @@ class COSXDasherScreen;
 
 - (void)sendMarker:(int)iMarker;
 - (void)displayCallback;
-- (void)circleCallbackCentrePoint:(NSPoint)aCentrePoint radius:(float)aRadius outlineColorIndex:(int)anOutlineColorIndex fillColourIndex:(int)aFillColourIndex shouldFill:(BOOL)shouldFill lineWidth:(int)aLineWidth;
+- (void)circleCallbackCentrePoint:(NSPoint)aCentrePoint radius:(float)aRadius fillColourIndex:(int)aFillColourIndex outlineColorIndex:(int)anOutlineColorIndex lineWidth:(int)aLineWidth;
 - (void)rectangleCallbackX1:(int)x1 y1:(int)y1 x2:(int)x2 y2:(int)y2 fillColorIndex:(int)aFillColorIndex outlineColorIndex:(int)anOutlineColorIndex lineWidth:(int)aLineWidth;
 - (NSSize)textSizeCallbackWithString:(NSString *)aString size:(int)aSize;
 - (void)drawTextCallbackWithString:(NSString *)aString x1:(int)x1 y1:(int)y1 size:(int)aSize colorIndex:(int)aColorIndex;
diff --git a/Src/MacOSX/DasherViewOpenGL.h b/Src/MacOSX/DasherViewOpenGL.h
index f6a23b6..e038c16 100755
--- a/Src/MacOSX/DasherViewOpenGL.h
+++ b/Src/MacOSX/DasherViewOpenGL.h
@@ -51,6 +51,10 @@ typedef struct {
   NSMutableDictionary *_letterDict;
   CKeyboardHelper *_keyboardHelper;
   
+  ///Caches for circleCallbackWithCentrePoint:... (see therein)
+  float circ_rad;
+  GLshort *circ_coords;
+  int circPoints;  
 }
 
 - (void)sendMarker:(int)iMarker;
@@ -62,7 +66,7 @@ typedef struct {
 - (void)mouseUp:(NSEvent *)e;
 - (void)keyDown:(NSEvent *)e;
 - (void)keyUp:(NSEvent *)e;
-- (void)circleCallbackCentrePoint:(NSPoint)aCentrePoint radius:(float)aRadius outlineColorIndex:(int)anOutlineColorIndex fillColourIndex:(int)aFillColourIndex shouldFill:(BOOL)shouldFill lineWidth:(int)aLineWidth;
+- (void)circleCallbackCentrePoint:(NSPoint)aCentrePoint radius:(float)aRadius fillColourIndex:(int)aFillColourIndex outlineColorIndex:(int)anOutlineColorIndex lineWidth:(int)aLineWidth;
 - (void)rectangleCallbackX1:(int)x1 y1:(int)y1 x2:(int)x2 y2:(int)y2 fillColorIndex:(int)aFillColorIndex outlineColorIndex:(int)anOutlineColorIndex lineWidth:(int)aLineWidth;
 - (AlphabetLetter *)letterForString:(NSString *)aString;
 - (NSSize)textSizeCallbackWithString:(NSString *)aString size:(int)aSize;
diff --git a/Src/MacOSX/DasherViewOpenGL.mm b/Src/MacOSX/DasherViewOpenGL.mm
index 49e38ba..61708a6 100755
--- a/Src/MacOSX/DasherViewOpenGL.mm
+++ b/Src/MacOSX/DasherViewOpenGL.mm
@@ -130,20 +130,55 @@
     [dasherApp aquaDasherControl]->KeyUp(get_time(), keyCode);
 }
 
-- (void)circleCallbackCentrePoint:(NSPoint)aCentrePoint radius:(float)aRadius outlineColorIndex:(int)anOutlineColorIndex fillColourIndex:(int)aFillColourIndex shouldFill:(BOOL)shouldFill lineWidth:(int)aLineWidth {
+- (void)circleCallbackCentrePoint:(NSPoint)aCentrePoint radius:(float)aRadius fillColourIndex:(int)aFillColourIndex outlineColorIndex:(int)anOutlineColorIndex lineWidth:(int)aLineWidth {
   
-//  NSBezierPath *bp = [NSBezierPath bezierPathWithOvalInRect:NSMakeRect(aCentrePoint.x - aRadius, aCentrePoint.y - aRadius, 2.0 * aRadius, 2.0 * aRadius)];
-//  
-//  int oci = anOutlineColorIndex == -1 ? 3 : anOutlineColorIndex;
-//  glColor3f(colourTable[oci].r, colourTable[oci].g, colourTable[oci].b);
-//  
-//  [NSBezierPath setDefaultLineWidth:aLineWidth];
-//  [bp stroke];
-//  
-//  if (shouldFill) {
-//    [[self colorWithColorIndex:aFillColourIndex] set];
-//    [bp fill];
-//  }
+  //it's a bit of a hack, but we cache the last-computed set of points round the
+  // as these are the same for all calls with the same radius - and (the hack!) 
+  // that the radius tends to be the same every time (as the only call to CDashe
+  // is from CircleStartHandler!)...
+  if (circ_rad != aRadius) {
+    delete circ_coords;
+    double costh=1.0f - 1.0f/(2.0f*aRadius);
+    double th = acos(costh);
+    int numPoints = circPoints = ceil(M_PI/th/2.0f); //for a quarter-circle
+    double sinth = sin(th),x(aRadius),y(0.0);
+    circ_coords = new GLshort[numPoints*8]; circ_rad = aRadius;
+    circ_coords[0] = x; circ_coords[1] = y;
+    for (int i=1; i<numPoints; i++) {
+      double nx = x*costh - y*sinth;
+      double ny = x*sinth + y*costh;
+      circ_coords[2*i] = nx;
+      circ_coords[2*i+1] = ny;
+      x=nx; y=ny;
+    }
+    for (int i=0; i<numPoints; i++) {
+      circ_coords[2*(i+numPoints)] = -circ_coords[2*i+1];
+      circ_coords[2*(i+numPoints)+1] = circ_coords[2*i];
+      
+      circ_coords[2*(i+numPoints*2)] = -circ_coords[2*i];
+      circ_coords[2*(i+numPoints*2)+1] = -circ_coords[2*i+1];
+      
+      circ_coords[2*(i+numPoints*3)] = circ_coords[2*i+1];
+      circ_coords[2*(i+numPoints*3)+1] = -circ_coords[2*i];
+    }
+  }
+  
+  glDisable(GL_TEXTURE_2D);
+  glEnableClientState(GL_VERTEX_ARRAY);
+  glTranslatef(aCentrePoint.x, aCentrePoint.y, 0.0);
+  if (aFillColourIndex!=-1) {
+    glColor4f(colourTable[aFillColourIndex].r, colourTable[aFillColourIndex].g, colourTable[aFillColourIndex].b, 1.0f);
+    glVertexPointer(2, GL_SHORT, 0, circ_coords);
+    glDrawArrays(GL_TRIANGLE_FAN, 0, circPoints*4);
+  }
+  if (aLineWidth>0) {
+    int oci = anOutlineColorIndex == -1 ? 3 : anOutlineColorIndex;
+    glColor4f(colourTable[oci].r, colourTable[oci].g, colourTable[oci].b, 1.0f);
+    glLineWidth(aLineWidth);
+    glVertexPointer(2, GL_SHORT, 0, circ_coords);
+    glDrawArrays(GL_LINE_LOOP, 0, circPoints*4);
+  }
+  glTranslatef(-aCentrePoint.x, -aCentrePoint.y, 0.0);
 }
 
 
@@ -298,7 +333,8 @@
     glClearColor(1.0, 1.0, 1.0, 1.0);
     glClear(GL_COLOR_BUFFER_BIT);
 	  
-    _keyboardHelper = new CKeyboardHelper();	  
+    _keyboardHelper = new CKeyboardHelper();
+    circ_rad=-1.0f;
   }
   return self;
 }
diff --git a/Src/Win32/Widgets/Screen.h b/Src/Win32/Widgets/Screen.h
index a1d5a0a..8e7e9a3 100644
--- a/Src/Win32/Widgets/Screen.h
+++ b/Src/Win32/Widgets/Screen.h
@@ -55,7 +55,7 @@ public:
 
   ///WHY is this defined like that?
   //void CScreen::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill,int layer=0);
-  void CScreen::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill);
+  void CScreen::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iFillColour, int iLineColour, int iThickness);
 
   // Draw a line of fixed colour (usually black). Intended for static UI elements such as a cross-hair
   //! Draw a line between each of the points in the array
diff --git a/Src/Win32/Widgets/Screen.inl b/Src/Win32/Widgets/Screen.inl
index 1effc28..a30af70 100644
--- a/Src/Win32/Widgets/Screen.inl
+++ b/Src/Win32/Widgets/Screen.inl
@@ -37,11 +37,11 @@ inline void CScreen::DrawRectangle(screenint x1, screenint y1, screenint x2, scr
 
 }
 
-inline void CScreen::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill) {
+inline void CScreen::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iFillColour, int iLineColour, int iThickness) {
   HGDIOBJ hpOld;
   hpOld = (HPEN) SelectObject(m_hDCBuffer, GetPen(iColour, iThickness));
 
-  if(bFill) {
+  if(iFillColour!=-1) {
     HBRUSH hBrush = CScreen::GetBrush(iFillColour);
     HBRUSH hBrushOld;
     hBrushOld = (HBRUSH)SelectObject(m_hDCBuffer, hBrush);
@@ -50,9 +50,9 @@ inline void CScreen::DrawCircle(screenint iCX, screenint iCY, screenint iR, int
 
     SelectObject(m_hDCBuffer, hBrushOld);
   }
-  // TODO: Fix this on wince
+  // TODO: Fix this (?) - looks to take no account of iThickness...and allegedly doesn't work on winCE either!
 #ifndef _WIN32_WCE
-  else
+  if (iThickness>0)
     Arc(m_hDCBuffer, iCX - iR, iCY - iR, iCX + iR, iCY + iR,
                      iCX, iCY - iR, iCX, iCY - iR );
 #endif
diff --git a/Src/iPhone/Classes/CDasherScreenBridge.h b/Src/iPhone/Classes/CDasherScreenBridge.h
index 9f89bd7..5af8df6 100644
--- a/Src/iPhone/Classes/CDasherScreenBridge.h
+++ b/Src/iPhone/Classes/CDasherScreenBridge.h
@@ -59,7 +59,7 @@ public:
   ///
   void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, int iThickness);
   
-  void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill);
+  void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iFillColour, int iLineColour, int iLineWidth);
   
   ///
   /// Send a marker to indicate phases of the redraw process. This is
diff --git a/Src/iPhone/Classes/CDasherScreenBridge.mm b/Src/iPhone/Classes/CDasherScreenBridge.mm
index 86bf200..0423774 100644
--- a/Src/iPhone/Classes/CDasherScreenBridge.mm
+++ b/Src/iPhone/Classes/CDasherScreenBridge.mm
@@ -39,9 +39,9 @@ void CDasherScreenBridge::DrawRectangle(int x1, int y1, int x2, int y2, int Colo
   [dasherView rectangleCallbackX1:x1 y1:y1 x2:x2 y2:y2 fillColorIndex:Color outlineColorIndex:iOutlineColour lineWidth:iThickness];
 }
 
-void CDasherScreenBridge::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill) {
+void CDasherScreenBridge::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iFillColour, int iLineColour, int iLineWidth) {
 
-  [dasherView circleCallbackCentrePoint:CGPointMake(iCX, iCY) radius:iR outlineColorIndex:iColour fillColourIndex:iFillColour shouldFill:bFill lineWidth:iThickness];
+  [dasherView circleCallbackCentrePoint:CGPointMake(iCX, iCY) radius:iR fillColourIndex:iFillColour outlineColorIndex:iLineColour lineWidth:iLineWidth];
 }
 
 void CDasherScreenBridge::Polygon(Dasher::CDasherScreen::point *Points, int Number, int fillColour, int outlineColour, int iWidth) {
diff --git a/Src/iPhone/Classes/DasherScreenCallbacks.h b/Src/iPhone/Classes/DasherScreenCallbacks.h
index 362dd72..a8a5c91 100644
--- a/Src/iPhone/Classes/DasherScreenCallbacks.h
+++ b/Src/iPhone/Classes/DasherScreenCallbacks.h
@@ -13,7 +13,7 @@ typedef struct {
 -(void)blankCallback;
 -(void)displayCallback;
 -(void)rectangleCallbackX1:(int)x1 y1:(int)y1 x2:(int)x2 y2:(int)y2 fillColorIndex:(int)aFillColorIndex outlineColorIndex:(int)anOutlineColorIndex lineWidth:(int)aLineWidth;
--(void)circleCallbackCentrePoint:(CGPoint)aCentrePoint radius:(float)aRadius outlineColorIndex:(int)anOutlineColorIndex fillColourIndex:(int)aFillColourIndex shouldFill:(BOOL)shouldFill lineWidth:(int)aLineWidth;
+-(void)circleCallbackCentrePoint:(CGPoint)aCentrePoint radius:(float)aRadius fillColourIndex:(int)aFillColourIndex outlineColorIndex:(int)anOutlineColorIndex lineWidth:(int)aLineWidth;
 -(CGSize)textSizeCallbackWithString:(NSString *)aString size:(int)aSize;
 -(void)drawTextCallbackWithString:(NSString *)aString x1:(int)x1 y1:(int)y1 size:(int)aSize colorIndex:(int)aColorIndex;
 -(void)sendMarker:(int)iMarker;
diff --git a/Src/iPhone/Classes/EAGLView.h b/Src/iPhone/Classes/EAGLView.h
index 832b0ba..51d1aea 100644
--- a/Src/iPhone/Classes/EAGLView.h
+++ b/Src/iPhone/Classes/EAGLView.h
@@ -39,6 +39,12 @@ Note that setting the view non-opaque will only work if the EAGL surface has an
 	GLfloat texcoords[8];
   
   CGPoint lastTouchCoords;
+  
+  ///Caches for circleCallbackWithCentrePoint:... (see therein)
+  float circ_rad;
+  GLshort *circ_coords;
+  int circPoints;
+  
 }
 
 @property (readonly,assign) CGPoint lastTouchCoords;
diff --git a/Src/iPhone/Classes/EAGLView.mm b/Src/iPhone/Classes/EAGLView.mm
index e8e4a95..c65d774 100644
--- a/Src/iPhone/Classes/EAGLView.mm
+++ b/Src/iPhone/Classes/EAGLView.mm
@@ -41,6 +41,8 @@
     
     if ((self = [super initWithFrame:frame])) {
 		dasherApp = _dasherApp;
+    circ_rad=-1.0f;
+      
         // Get the layer
         CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
         
@@ -272,8 +274,54 @@
 	}
 }
 
--(void)circleCallbackCentrePoint:(CGPoint)aCentrePoint radius:(float)aRadius outlineColorIndex:(int)anOutlineColorIndex fillColourIndex:(int)aFillColourIndex shouldFill:(BOOL)shouldFill lineWidth:(int)aLineWidth {
-	NSLog(@"Call to EAGLView::circleCallbackCentrePoint - not implemented!\n");
+-(void)circleCallbackCentrePoint:(CGPoint)aCentrePoint radius:(float)aRadius fillColourIndex:(int)aFillColourIndex outlineColorIndex:(int)anOutlineColorIndex lineWidth:(int)aLineWidth {
+  //it's a bit of a hack, but we cache the last-computed set of points round the circle,
+  // as these are the same for all calls with the same radius - and (the hack!) it happens
+  // that the radius tends to be the same every time (as the only call to CDasherScreen::DrawCircle
+  // is from CircleStartHandler!)...
+  if (circ_rad != aRadius) {
+    delete circ_coords;
+    double costh=1.0f - 1.0f/(2.0f*aRadius);
+    double th = acos(costh);
+    int numPoints = circPoints = ceil(M_PI/th/2.0f); //for a quarter-circle
+    double sinth = sin(th),x(aRadius),y(0.0);
+    circ_coords = new GLshort[numPoints*8]; circ_rad = aRadius;
+    circ_coords[0] = x; circ_coords[1] = y;
+    for (int i=1; i<numPoints; i++) {
+      double nx = x*costh - y*sinth;
+      double ny = x*sinth + y*costh;
+      circ_coords[2*i] = nx;
+      circ_coords[2*i+1] = ny;
+      x=nx; y=ny;
+    }
+    for (int i=0; i<numPoints; i++) {
+      circ_coords[2*(i+numPoints)] = -circ_coords[2*i+1];
+      circ_coords[2*(i+numPoints)+1] = circ_coords[2*i];
+      
+      circ_coords[2*(i+numPoints*2)] = -circ_coords[2*i];
+      circ_coords[2*(i+numPoints*2)+1] = -circ_coords[2*i+1];
+      
+      circ_coords[2*(i+numPoints*3)] = circ_coords[2*i+1];
+      circ_coords[2*(i+numPoints*3)+1] = -circ_coords[2*i];
+    }
+  }
+  
+  glDisable(GL_TEXTURE_2D);
+  glEnableClientState(GL_VERTEX_ARRAY);
+  glTranslatef(aCentrePoint.x, aCentrePoint.y, 0.0);
+  if (aFillColourIndex!=-1) {
+    glColor4f(colourTable[aFillColourIndex].r, colourTable[aFillColourIndex].g, colourTable[aFillColourIndex].b, 1.0);
+    glVertexPointer(2, GL_SHORT, 0, circ_coords);
+    glDrawArrays(GL_TRIANGLE_FAN, 0, circPoints*4);
+  }
+  if (aLineWidth>0) {
+    int oci = anOutlineColorIndex == -1 ? 3 : anOutlineColorIndex;
+		glColor4f(colourTable[oci].r, colourTable[oci].g, colourTable[oci].b, 1.0);
+		glLineWidth(aLineWidth);
+		glVertexPointer(2, GL_SHORT, 0, circ_coords);
+		glDrawArrays(GL_LINE_LOOP, 0, circPoints*4);
+  }
+  glTranslatef(-aCentrePoint.x, -aCentrePoint.y, 0.0);
 };
 
 -(CGSize)textSizeCallbackWithString:(NSString *)aString size:(int)aSize {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]