[dasher] Consolidating graphics primitives



commit 05c8750713b1942f0939260d4a080b75b56886b8
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Fri Nov 13 14:22:05 2009 +0000

    Consolidating graphics primitives
    
    Removed redundant bDrawOutline and bFill parameters from DrawRect routines, as
      can determine from fill color and line thickness parameters;
    also removed DrawPolygon in favour of Polygon, now with same params as DrawRect
      (does filled &/or outlined polygons), added Mac&iPhone OpenGL implementations
    Text drawing methods now take colour param (DelayedDraw always uses 4=black)
      (Implemented on Mac & iPhone w/ OpenGL texture modulation, also on Gtk2)

 Src/DasherCore/ActionButton.cpp            |    2 +-
 Src/DasherCore/DasherScreen.h              |   34 +++++++------------
 Src/DasherCore/DasherView.cpp              |   23 +++----------
 Src/DasherCore/DasherView.h                |   14 +++-----
 Src/DasherCore/DasherViewSquare.cpp        |   14 ++++----
 Src/DasherCore/DelayedDraw.cpp             |    2 +-
 Src/DasherCore/OneButtonDynamicFilter.cpp  |    4 +-
 Src/DasherCore/TwoBoxStartHandler.cpp      |    4 +-
 Src/DasherCore/TwoPushDynamicFilter.cpp    |    2 +-
 Src/Gtk2/Canvas.cpp                        |   48 +++++++++++++++++++--------
 Src/Gtk2/Canvas.h                          |   26 ++++++---------
 Src/Gtk2/CanvasExperimental.h              |   17 +++-------
 Src/MacOSX/AlphabetLetter.h                |    2 +-
 Src/MacOSX/AlphabetLetter.mm               |   25 +++++++++++---
 Src/MacOSX/COSXDasherScreen.h              |   23 +++++---------
 Src/MacOSX/COSXDasherScreen.mm             |   14 +++-----
 Src/MacOSX/DasherViewAqua.h                |    2 +-
 Src/MacOSX/DasherViewAqua.mm               |    6 ++--
 Src/MacOSX/DasherViewCocoa.h               |    3 +-
 Src/MacOSX/DasherViewOpenGL.h              |    3 +-
 Src/MacOSX/DasherViewOpenGL.mm             |   35 ++++++++++++++++++--
 Src/Qt/QtDasherScreen.cc                   |    5 ++-
 Src/Qt/QtDasherScreen.h                    |    2 +-
 Src/iPhone/Classes/AlphabetLetter.mm       |   20 ++++++-----
 Src/iPhone/Classes/CDasherScreenBridge.h   |   10 ++---
 Src/iPhone/Classes/CDasherScreenBridge.mm  |   13 +++----
 Src/iPhone/Classes/DasherScreenCallbacks.h |    4 +-
 Src/iPhone/Classes/EAGLView.mm             |   31 +++++++++++++++---
 28 files changed, 213 insertions(+), 175 deletions(-)
---
diff --git a/Src/DasherCore/ActionButton.cpp b/Src/DasherCore/ActionButton.cpp
index aa77b72..49b5586 100644
--- a/Src/DasherCore/ActionButton.cpp
+++ b/Src/DasherCore/ActionButton.cpp
@@ -19,7 +19,7 @@ void CActionButton::SetPosition(int iX, int iY, int iWidth, int iHeight) {
 
 void CActionButton::Draw(Dasher::CDasherScreen *pScreen, bool bVisible) {
   if(bVisible || m_bAlwaysVisible)
-    pScreen->DrawRectangle(m_iX, m_iY, m_iX + m_iWidth, m_iY + m_iHeight, 1, 2, Dasher::Opts::Nodes1, true, true, 1);
+    pScreen->DrawRectangle(m_iX, m_iY, m_iX + m_iWidth, m_iY + m_iHeight, 1, 2, Dasher::Opts::Nodes1, 1);
 }
 
 bool CActionButton::HandleClickDown(int iTime, int iX, int iY, bool bVisible) {
diff --git a/Src/DasherCore/DasherScreen.h b/Src/DasherCore/DasherScreen.h
index ec494df..afe04a6 100644
--- a/Src/DasherCore/DasherScreen.h
+++ b/Src/DasherCore/DasherScreen.h
@@ -56,7 +56,7 @@ public:
   virtual void TextSize(const std::string & String, screenint * Width, screenint * Height, int Size) = 0;
 
   //! Draw UTF8-encoded string String of size Size positioned at x1 and y1
-  virtual void DrawString(const std::string & String, screenint x1, screenint y1, int Size) = 0;
+  virtual void DrawString(const std::string & String, screenint x1, screenint y1, int Size, int iColor) = 0;
 
   // Send a marker to indicate 'phases' of drawing. 
 
@@ -70,14 +70,12 @@ public:
   /// \param y1 top left corner of rectangle (y coordinate)
   /// \param x2 bottom right of rectangle (x coordinate)
   /// \param y2 bottom right of rectangle (y coordinate)
-  /// \param Color the colour to be used (numeric)
-  /// \param iOutlineColour The colour for the node outlines
+  /// \param Color the colour to be used (numeric), or -1 for no fill
+  /// \param iOutlineColour The colour for the node outlines, or -1 for no outline
   /// \param ColorScheme Which colourscheme is to be used
-  /// \param bDrawOutline Whether to draw an outline or not
-  /// \param bFill Whether to fill or not
-  /// \param iThickness Line thickness for outline
+  /// \param iThickness Line thickness for outline; <1 for no outline
 
-  virtual void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, bool bDrawOutline, bool bFill, int iThickness) = 0;
+  virtual void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, int iThickness) = 0;
 
   virtual void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill) = 0;
 
@@ -103,20 +101,14 @@ public:
 
   virtual void Polyline(point * Points, int Number, int iWidth, int Colour) = 0;
 
-  // Draw a filled polygon - given vertices and color id
-  // This is not (currently) used in standard Dasher. However, it could be very
-  // useful in the future. Please implement unless it will be very difficult,
-  // in which case make this function call Polyline.
-  //! Draw a filled polygon
-  //!
-  //! \param Points array of points defining the edge of the polygon
-  //! \param Number number of points in the array
-  //! \param Color colour of the polygon (numeric)
-  virtual void Polygon(point * Points, int Number, int Color) {
-    Polygon(Points, Number, Color, 1);
-  };
-
-  virtual void Polygon(point * Points, int Number, int Color, int iWidth) = 0;
+  /// Draw a polygon - given vertices and color id
+  ///
+  /// \param Points Vertices of polygon in clockwise order. (No need to repeat the first point at the end)
+  /// \param Number number of points in the array
+  /// \param fillColor colour to fill polygon (numeric); -1 for don't fill
+  /// \param outlineColor colour to draw polygon outline (right the way around, i.e. repeating first point)
+  /// \param lineWidth thickness of outline; 0 or less => don't draw outline.
+  virtual void Polygon(point * Points, int Number, int fillColor, int outlineColor, int lineWidth) = 0;
 
   // Signal the screen when a frame is started and finished
   //! Signal that a frame is being started
diff --git a/Src/DasherCore/DasherView.cpp b/Src/DasherCore/DasherView.cpp
index 654b840..bb20f21 100644
--- a/Src/DasherCore/DasherView.cpp
+++ b/Src/DasherCore/DasherView.cpp
@@ -150,22 +150,9 @@ void CDasherView::DasherPolyarrow(myint *x, myint *y, int n, int iWidth, int iCo
   delete[]ScreenPoints;
 }
 
-// Draw a filled polygon specified in Dasher co-ordinates
-
-void CDasherView::DasherPolygon(myint *x, myint *y, int n, int iColour) {
-
-  CDasherScreen::point * ScreenPoints = new CDasherScreen::point[n];
-
-  for(int i(0); i < n; ++i)
-    Dasher2Screen(x[i], y[i], ScreenPoints[i].x, ScreenPoints[i].y);
-
-  Screen()->Polygon(ScreenPoints, n, iColour);
-  delete[]ScreenPoints;
-}
-
 // Draw a box specified in Dasher co-ordinates
 
-void CDasherView::DasherDrawRectangle(myint iLeft, myint iTop, myint iRight, myint iBottom, const int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, bool bDrawOutline, bool bFill, int iThickness) {
+void CDasherView::DasherDrawRectangle(myint iLeft, myint iTop, myint iRight, myint iBottom, const int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, int iThickness) {
   screenint iScreenLeft;
   screenint iScreenTop;
   screenint iScreenRight;
@@ -174,7 +161,7 @@ void CDasherView::DasherDrawRectangle(myint iLeft, myint iTop, myint iRight, myi
   Dasher2Screen(iLeft, iTop, iScreenLeft, iScreenTop);
   Dasher2Screen(iRight, iBottom, iScreenRight, iScreenBottom);
 
-  Screen()->DrawRectangle(iScreenLeft, iScreenTop, iScreenRight, iScreenBottom, Color, iOutlineColour, ColorScheme, bDrawOutline, bFill, iThickness);
+  Screen()->DrawRectangle(iScreenLeft, iScreenTop, iScreenRight, iScreenBottom, Color, iOutlineColour, ColorScheme, iThickness);
 }
 
 /// Draw a rectangle centred on a given dasher co-ordinate, but with a size specified in screen co-ordinates (used for drawing the mouse blob)
@@ -185,14 +172,14 @@ void CDasherView::DasherDrawCentredRectangle(myint iDasherX, myint iDasherY, scr
 
   Dasher2Screen(iDasherX, iDasherY, iScreenX, iScreenY);
 
-  Screen()->DrawRectangle(iScreenX - iSize, iScreenY - iSize, iScreenX + iSize, iScreenY + iSize, Color, -1, ColorScheme, bDrawOutline, true, 1);
+  Screen()->DrawRectangle(iScreenX - iSize, iScreenY - iSize, iScreenX + iSize, iScreenY + iSize, Color, -1, ColorScheme, bDrawOutline ? 1 : 0);
 }
 
-void CDasherView::DrawText(const std::string & str, myint x, myint y, int Size) {
+void CDasherView::DrawText(const std::string & str, myint x, myint y, int Size, int iColor) {
   screenint X, Y;
   Dasher2Screen(x, y, X, Y);
   
-  Screen()->DrawString(str, X, Y, Size);
+  Screen()->DrawString(str, X, Y, Size, iColor);
 }
 
 
diff --git a/Src/DasherCore/DasherView.h b/Src/DasherCore/DasherView.h
index f0a7065..22e5780 100644
--- a/Src/DasherCore/DasherView.h
+++ b/Src/DasherCore/DasherView.h
@@ -147,16 +147,12 @@ public:
   void DasherPolyarrow(myint * x, myint * y, int n, int iWidth, int iColour, double dArrowSizeFactor = 0.7071);
 
   ///
-  /// Draw a polygon specified in Dasher co-ordinates
-  ///
-
-  void DasherPolygon(myint * x, myint * y, int n, int iColour);
-
-  ///
   /// Draw a rectangle specified in Dasher co-ordinates
+  /// Color of -1 => no fill; any other value => fill in that color
+  /// iOutlineColor of -1 => no outline; any other value => outline in that color, EXCEPT
+  /// Thickness < 1 => no outline.
   ///
-
-  void DasherDrawRectangle(myint iLeft, myint iTop, myint iRight, myint iBottom, const int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme,bool bDrawOutline, bool bFill, int iThickness);
+  void DasherDrawRectangle(myint iLeft, myint iTop, myint iRight, myint iBottom, const int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, int iThickness);
 
   ///
   /// Draw a centred rectangle specified in Dasher co-ordinates (used for mouse cursor)
@@ -164,7 +160,7 @@ public:
 
   void DasherDrawCentredRectangle(myint iDasherX, myint iDasherY, screenint iSize, const int Color, Opts::ColorSchemes ColorScheme, bool bDrawOutline);
 
-  void DrawText(const std::string & str, myint x, myint y, int Size);
+  void DrawText(const std::string & str, myint x, myint y, int Size, int iColor);
   /// Request the Screen to copy its buffer to the Display
   /// \todo Shouldn't be public?
   void Display();
diff --git a/Src/DasherCore/DasherViewSquare.cpp b/Src/DasherCore/DasherViewSquare.cpp
index c9f7a97..86b9493 100644
--- a/Src/DasherCore/DasherViewSquare.cpp
+++ b/Src/DasherCore/DasherViewSquare.cpp
@@ -260,18 +260,18 @@ void CDasherViewSquare::RenderNodes(CDasherNode *pRoot, myint iRootMin, myint iR
   // Blank the region around the root node:
   
   if(iRootMin > iDasherMinY)
-    DasherDrawRectangle(iDasherMaxX, iDasherMinY, iDasherMinX, iRootMin, 0, 0, Nodes1, false,true, 1);
+    DasherDrawRectangle(iDasherMaxX, iDasherMinY, iDasherMinX, iRootMin, 0, -1, Nodes1, 0);
   
   //if(iScreenTop > 0)
   //  Screen()->DrawRectangle(0, 0, Screen()->GetWidth(), iScreenTop, 0, -1, Nodes1, false, true, 1);
 
   if(iRootMax < iDasherMaxY)
-    DasherDrawRectangle(iDasherMaxX, iRootMax, iDasherMinX, iDasherMaxY, 0, 0, Nodes1, false,true, 1);
+    DasherDrawRectangle(iDasherMaxX, iRootMax, iDasherMinX, iDasherMaxY, 0, -1, Nodes1, 0);
 
   //if(iScreenBottom <= Screen()->GetHeight())
   // Screen()->DrawRectangle(0, iScreenBottom, Screen()->GetWidth(), Screen()->GetHeight(), 0, -1, Nodes1, false, true, 1);
 
-  DasherDrawRectangle(0, iDasherMinY, iDasherMinX, iDasherMaxY, 0, 4, Nodes1, false,true, 1);
+  DasherDrawRectangle(0, iDasherMinY, iDasherMinX, iDasherMaxY, 0, -1, Nodes1, 0);
   //  Screen()->DrawRectangle(iScreenRight, std::max(0, (int)iScreenTop),
   //		  Screen()->GetWidth(), std::min(Screen()->GetHeight(), (int)iScreenBottom), 
   //		  0, -1, Nodes1, false, true, 1);
@@ -377,7 +377,7 @@ void CDasherViewSquare::RecursiveRender(CDasherNode *pRender, myint y1, myint y2
   VisibleRegion(iDasherMinX, iDasherMinY, iDasherMaxX, iDasherMaxY);
 
   if(GetLongParameter(LP_TRUNCATION) == 0) {        // Regular squares
-    DasherDrawRectangle(std::min(parent_width,iDasherMaxX), std::max(y1,iDasherMinY), std::min(y2-y1,iDasherMaxX), std::min(y2,iDasherMaxY), parent_color, -1, Nodes1, false, true, 1);
+    DasherDrawRectangle(std::min(parent_width,iDasherMaxX), std::max(y1,iDasherMinY), std::min(y2-y1,iDasherMaxX), std::min(y2,iDasherMaxY), parent_color, -1, Nodes1, 0);
   }
 	
   const std::string &sDisplayText(pRender->GetDisplayInfo()->strDisplayText);
@@ -395,7 +395,7 @@ void CDasherViewSquare::RecursiveRender(CDasherNode *pRender, myint y1, myint y2
 	  //  int iTruncationType(GetLongParameter(LP_TRUNCATIONTYPE));
 	  
 	  if(iTruncation == 0) {        // Regular squares
-		  DasherDrawRectangle(std::min(y2-y1,iDasherMaxX), std::min(y2,iDasherMaxY),0, std::max(y1,iDasherMinY), pRender->GetDisplayInfo()->iColour, -1, Nodes1, false, true, 1);
+      DasherDrawRectangle(std::min(y2-y1,iDasherMaxX), std::min(y2,iDasherMaxY),0, std::max(y1,iDasherMinY), pRender->GetDisplayInfo()->iColour, -1, Nodes1, 0);
 	  }
 	  //also allow it to be expanded, it's big enough.
 	  policy.pushNode(pRender, y1, y2, true, dMaxCost);
@@ -566,7 +566,7 @@ int CDasherViewSquare::RenderNodeOutlineFast(const int Color, myint y1, myint y2
 
   //  std::cout << std::min(iDasherSize,iDasherMaxX) << " " << std::min(y2,iDasherMaxY) << " 0 " << std::max(y1,iDasherMinY) << std::endl;
 
-  DasherDrawRectangle(0, std::min(y1,iDasherMaxY),std::min(iDasherSize,iDasherMaxX), std::max(y2,iDasherMinY), Color, -1, Nodes1, true,false, 1);
+  DasherDrawRectangle(0, std::min(y1,iDasherMaxY),std::min(iDasherSize,iDasherMaxX), std::max(y2,iDasherMinY), -1, Color, Nodes1, 1);
 
 //   // FIXME - get rid of pointless assignment below
 
@@ -631,7 +631,7 @@ int CDasherViewSquare::RenderNodePartFast(const int Color, myint y1, myint y2, i
   //  int iTruncationType(GetLongParameter(LP_TRUNCATIONTYPE));
 
   if(iTruncation == 0) {        // Regular squares
-    DasherDrawRectangle(std::min(iParentWidth,iDasherMaxX), std::min(y2,iDasherMaxY),0, std::max(y1,iDasherMinY), Color, -1, Nodes1, false, true, 1);
+    DasherDrawRectangle(std::min(iParentWidth,iDasherMaxX), std::min(y2,iDasherMaxY),0, std::max(y1,iDasherMinY), Color, -1, Nodes1, 0);
   }
   else {
    
diff --git a/Src/DasherCore/DelayedDraw.cpp b/Src/DasherCore/DelayedDraw.cpp
index a6a5d6a..48e2301 100644
--- a/Src/DasherCore/DelayedDraw.cpp
+++ b/Src/DasherCore/DelayedDraw.cpp
@@ -18,7 +18,7 @@ void CDelayedDraw::Draw(CDasherScreen * screen) {
 
   for(int i = 0; i < iSize; i++) {
     CTextString & draw = m_DrawTextString[i];
-    screen->DrawString(draw.m_String, draw.m_x, draw.m_y, draw.m_iSize);
+    screen->DrawString(draw.m_String, draw.m_x, draw.m_y, draw.m_iSize, 4);
   }
   m_DrawTextString.clear();
 
diff --git a/Src/DasherCore/OneButtonDynamicFilter.cpp b/Src/DasherCore/OneButtonDynamicFilter.cpp
index 69983e5..ed452ca 100644
--- a/Src/DasherCore/OneButtonDynamicFilter.cpp
+++ b/Src/DasherCore/OneButtonDynamicFilter.cpp
@@ -79,7 +79,7 @@ bool COneButtonDynamicFilter::DecorateView(CDasherView *pView) {
     pView->Dasher2Screen(-200, 4096, x2, y2);
   }
 
-  pScreen->DrawRectangle(x1, y1, x2, y2, 1, 1, Opts::ColorSchemes(Opts::Objects), true, false, 2);
+  pScreen->DrawRectangle(x1, y1, x2, y2, -1, 1, Opts::ColorSchemes(Opts::Objects), 2);
     
   if(m_iTarget == 1) {
     pView->Dasher2Screen(-100, 3096, x1, y1);
@@ -90,7 +90,7 @@ bool COneButtonDynamicFilter::DecorateView(CDasherView *pView) {
     pView->Dasher2Screen(-200, 1000, x2, y2);
   }
 
-  pScreen->DrawRectangle(x1, y1, x2, y2, 2, 2, Opts::ColorSchemes(Opts::Objects), true, false, 1);
+  pScreen->DrawRectangle(x1, y1, x2, y2, -1, 2, Opts::ColorSchemes(Opts::Objects), 1);
 
   bool bRV(m_bDecorationChanged);
   m_bDecorationChanged = false;
diff --git a/Src/DasherCore/TwoBoxStartHandler.cpp b/Src/DasherCore/TwoBoxStartHandler.cpp
index 61c7510..4f35d7b 100644
--- a/Src/DasherCore/TwoBoxStartHandler.cpp
+++ b/Src/DasherCore/TwoBoxStartHandler.cpp
@@ -17,11 +17,11 @@ bool CTwoBoxStartHandler::DecorateView(CDasherView *pView) {
 
   switch (iDrawMousePosBox) {
   case 1:
-    pView->Screen()->DrawRectangle(8, iHeight / 2 - iMousePosDist + 50, iWidth-16, iHeight / 2 - iMousePosDist - 50, 0, 119, Opts::Nodes1,true, false, 4);
+    pView->Screen()->DrawRectangle(8, iHeight / 2 - iMousePosDist + 50, iWidth-16, iHeight / 2 - iMousePosDist - 50, -1, 119, Opts::Nodes1, 4);
     return true;
     break;
   case 2:
-    pView->Screen()->DrawRectangle(8, iHeight / 2 + iMousePosDist + 50, iWidth-16, iHeight / 2 + iMousePosDist - 50, 0, 120, Opts::Nodes1,true, false, 4);
+    pView->Screen()->DrawRectangle(8, iHeight / 2 + iMousePosDist + 50, iWidth-16, iHeight / 2 + iMousePosDist - 50, -1, 120, Opts::Nodes1, 4);
     return true;
     break;
   default:
diff --git a/Src/DasherCore/TwoPushDynamicFilter.cpp b/Src/DasherCore/TwoPushDynamicFilter.cpp
index 0db4494..5faef32 100644
--- a/Src/DasherCore/TwoPushDynamicFilter.cpp
+++ b/Src/DasherCore/TwoPushDynamicFilter.cpp
@@ -76,7 +76,7 @@ bool CTwoPushDynamicFilter::DecorateView(CDasherView *pView)
     pView->Dasher2Screen(-100, m_aaiGuideAreas[i][0], x1, y1);
     pView->Dasher2Screen(-1000, m_aaiGuideAreas[i][1], x2, y2);
   
-    pScreen->DrawRectangle(x1, y1, x2, y2, 62/*pale yellow*/, -1, Opts::Nodes1, false, true, 0);
+    pScreen->DrawRectangle(x1, y1, x2, y2, 62/*pale yellow*/, -1, Opts::Nodes1, 0);
   }
 
   //inner guides (red lines)
diff --git a/Src/Gtk2/Canvas.cpp b/Src/Gtk2/Canvas.cpp
index 46da872..51c8950 100644
--- a/Src/Gtk2/Canvas.cpp
+++ b/Src/Gtk2/Canvas.cpp
@@ -185,7 +185,7 @@ void CCanvas::Display() {
   // gtk_main_iteration_do(0);
 }
 
-void CCanvas::DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, bool bDrawOutline, bool bFill, int iThickness) {
+void CCanvas::DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, int iThickness) {
 
   //  std::cout << "Raw Rectangle, (" << x1 << ", " << y1 << ") - (" << x2 << ", " << y2 << ")" << std::endl;
 
@@ -225,18 +225,18 @@ void CCanvas::DrawRectangle(screenint x1, screenint y1, screenint x2, screenint
 
   //  std::cout << bFill << " " << Color << " " << iLeft << " " << iTop << " " << iWidth << " " << iHeight << std::endl;
 
-  if(bFill) {
+  if(Color!=-1) {
     SET_COLOR(Color);
 #if WITH_CAIRO
-    cairo_set_line_width(cr, iThickness);
+    //cairo_set_line_width(cr, iThickness); //outline done below
     cairo_rectangle(cr, iLeft, iTop, iWidth, iHeight);
     cairo_fill(cr);
 #else
     gdk_draw_rectangle(m_pOffscreenBuffer, graphics_context, TRUE, iLeft, iTop, iWidth + 1, iHeight + 1);
 #endif
   }
-  
-  if(bDrawOutline) {
+
+  if(iThickness>0) {
     if( iOutlineColour == -1 )
       SET_COLOR(3);
     else
@@ -296,10 +296,12 @@ void CCanvas::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour
   END_DRAWING;
 }
 
-void CCanvas::Polygon(Dasher::CDasherScreen::point *Points, int Number, int Colour, int iWidth) {
+void CCanvas::Polygon(Dasher::CDasherScreen::point *Points, int Number, int fillColour, int outlineColour, int iWidth) {
 
-  if(iWidth == 1) // This is to make it work properly on Windows
-    iWidth = 0; 
+  //(ACL) commenting out, we now deal with fill & outline separately. However,
+  // TODO: find a windows box on which this actually applies and test it
+  //if(iWidth == 1) // This is to make it work properly on Windows
+  //  iWidth = 0; 
 
 #if WITH_CAIRO
 #else
@@ -311,14 +313,24 @@ void CCanvas::Polygon(Dasher::CDasherScreen::point *Points, int Number, int Colo
 #endif
 
   BEGIN_DRAWING;
-  SET_COLOR(Colour);
 
 #if WITH_CAIRO
  cairo_move_to(cr, Points[0].x, Points[0].y);
   for (int i=1; i < Number; i++)
     cairo_line_to(cr, Points[i].x, Points[i].y);
   cairo_close_path(cr);
-  cairo_fill(cr);
+  if (fillColour!=-1) {
+    SET_COLOR(fillColour);
+    if (iWidth<=0) {
+      cairo_fill(cr); //fill only, no outline
+    } else {
+      cairo_fill_preserve(cr); //leave path defined for cairo_stroke, below
+    }
+  }
+  if (iWidth>0) {
+    SET_COLOR(outlineColour==-1 ? 3 : outlineColour);
+    cairo_stroke(cr);
+  }
 #else
   GdkPoint *gdk_points;
   gdk_points = (GdkPoint *) g_malloc(Number * sizeof(GdkPoint));
@@ -328,8 +340,16 @@ void CCanvas::Polygon(Dasher::CDasherScreen::point *Points, int Number, int Colo
     gdk_points[i].y = Points[i].y;
   }
 
-  gdk_gc_set_line_attributes(graphics_context, iWidth, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND );
-  gdk_draw_polygon(m_pOffscreenBuffer, graphics_context, TRUE, gdk_points, Number);
+  if (fillColour != -1) {
+    SET_COLOR(fillColour);
+    gdk_gc_set_line_attributes(graphics_context, 1, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND );
+    gdk_draw_polygon(m_pOffscreenBuffer, graphics_context, TRUE, gdk_points, Number);
+  }
+  if (iWidth > 0) {
+    SET_COLOR(outlineColour);
+    gdk_gc_set_line_attributes(graphics_context, iWidth, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND );
+    gdk_draw_polygon(m_pOffscreenBuffer, graphics_context, FALSE, gdk_points, Number);
+  }
   g_free(gdk_points);
 #endif
 
@@ -379,7 +399,7 @@ void CCanvas::Polyline(Dasher::CDasherScreen::point *Points, int Number, int iWi
   END_DRAWING;
 }
 
-void CCanvas::DrawString(const std::string &String, screenint x1, screenint y1, int size) {
+void CCanvas::DrawString(const std::string &String, screenint x1, screenint y1, int size, int iColor) {
   
 #if WITH_CAIRO
 #else
@@ -391,7 +411,7 @@ void CCanvas::DrawString(const std::string &String, screenint x1, screenint y1,
 #endif
 
   BEGIN_DRAWING;
-  SET_COLOR(4);
+  SET_COLOR(iColor);
 
 #if WITH_CAIRO
   PangoLayout *pLayout(m_pPangoCache->GetLayout(cr, String, size));
diff --git a/Src/Gtk2/Canvas.h b/Src/Gtk2/Canvas.h
index d0cbb41..c0a3927 100644
--- a/Src/Gtk2/Canvas.h
+++ b/Src/Gtk2/Canvas.h
@@ -134,7 +134,7 @@ public:
   /// \param Size The size at which to render the rectangle (units?)
   ///
 
-  void DrawString(const std::string &String, screenint x1, screenint y1, int Size);
+  void DrawString(const std::string &String, screenint x1, screenint y1, int Size, int iColor);
 
   ///
   /// Draw a rectangle
@@ -142,12 +142,13 @@ public:
   /// \param y1 y coordiate of the top left corner
   /// \param x2 x coordiate of the bottom right corner
   /// \param y2 y coordiate of the bottom right corner
-  /// \param Color Colour to draw the rectangle
+  /// \param Color Colour to fill the rectangle (-1 = don't fill)
   /// \param ColorScheme Which of the alternating colour schemes to use (be more precise)
-  /// \param bDrawOutline Whether or not to draw outlines for the boxes
+  /// \param iOutlineColour Colour to draw the outline
+  /// \param iThickness line width of outline (<=0 = don't outline)
   ///
 
-  void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, bool bDrawOutine, bool bFill, int iThickness);
+  void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, int iThickness);
 
   void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill);
 
@@ -174,20 +175,13 @@ public:
   void Polyline(point * Points, int Number, int iWidth, int Colour);
 
   /// 
-  /// Like polyline, but fill the shape
-  /// \todo See comments for DrawPolygon
+  /// Draw a closed polygon (linking last vertex back to first)
+  /// @param fillColour colour to fill; -1 => don't fill
+  /// @param outlineColour colour to draw outline...
+  /// @param iWidth ...and line thickness; -1 => don't draw outline
   ///
 
-  void Polygon(point *Points, int Number, int Colour, int iWidth);
-
-  ///
-  /// \todo Not implemented
-  /// \todo One of these two routines must be redundant - find out which and kill the other
-  ///
-
-  void DrawPolygon(point *Points, int Number, int Color, Opts::ColorSchemes ColorScheme) {
-    // not implemented 
-  };
+  void Polygon(point *Points, int Number, int fillColour, int outlineColour, int iWidth);
 
   /// 
   /// Blank the diplay
diff --git a/Src/Gtk2/CanvasExperimental.h b/Src/Gtk2/CanvasExperimental.h
index c2dbcd9..c566be8 100644
--- a/Src/Gtk2/CanvasExperimental.h
+++ b/Src/Gtk2/CanvasExperimental.h
@@ -144,20 +144,13 @@ public:
   void Polyline(point * Points, int Number, int iWidth, int Colour);
 
   /// 
-  /// Like polyline, but fill the shape
-  /// \todo See comments for DrawPolygon
+  /// Draw a closed polygon (linking last vertex back to first)
+  /// @param fillColour colour to fill; -1 => don't fill
+  /// @param outlineColour colour to draw outline...
+  /// @param iWidth ...and line thickness; -1 => don't draw outline
   ///
 
-  void Polygon(point *Points, int Number, int Colour, int iWidth);
-
-  ///
-  /// \todo Not implemented
-  /// \todo One of these two routines must be redundant - find out which and kill the other
-  ///
-
-  void DrawPolygon(point *Points, int Number, int Color, Opts::ColorSchemes ColorScheme) {
-    // not implemented 
-  };
+  void Polygon(point *Points, int Number, int fillColour, int outlineColour, int iWidth);
 
   /// 
   /// Blank the diplay
diff --git a/Src/MacOSX/AlphabetLetter.h b/Src/MacOSX/AlphabetLetter.h
index f8328e9..cbe44b4 100755
--- a/Src/MacOSX/AlphabetLetter.h
+++ b/Src/MacOSX/AlphabetLetter.h
@@ -15,7 +15,7 @@
 	GLuint texture;
 	GLfloat texcoords[8];
 }
-
++ (void)initialize;
 - (id)initWithString:(NSString *)string;
 - (void)drawWithSize:(int)aSize x:(int)x y:(int)y r:(float)r g:(float)g b:(float)b;
 - (NSSize)sizeWithSize:(int)aSize;
diff --git a/Src/MacOSX/AlphabetLetter.mm b/Src/MacOSX/AlphabetLetter.mm
index 468ad6a..8d27ec2 100644
--- a/Src/MacOSX/AlphabetLetter.mm
+++ b/Src/MacOSX/AlphabetLetter.mm
@@ -11,6 +11,17 @@
 
 @implementation AlphabetLetter
 
+static NSDictionary *fontAttrs;
+
++(void)initialize {
+  //white text on (default) transparent background means that when we texture
+  //a surface using a colour, the text appears in that colour...
+  fontAttrs = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont systemFontOfSize:36.0],NSFontAttributeName,[NSColor whiteColor],NSForegroundColorAttributeName,nil];
+  //dictionaryWith...: does an autorelease - only "alloc" methods do not.
+  // But we want to keep the fontAttrs indefinitely...
+  [fontAttrs retain];
+}
+
 /*void dump(char *data, int width, int height)
 {
 	static char buf[10240]; buf[0] = 0;
@@ -45,13 +56,15 @@
 		[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:YES]];
 
 		CGContextClearRect(context, CGRectMake(0.0, 0.0, width, height));
-		[string drawAtPoint:NSMakePoint(0.0, 0.0) withAttributes:[NSDictionary dictionaryWithObject:[NSFont systemFontOfSize:36.0] forKey:NSFontAttributeName]];
+		[string drawAtPoint:NSMakePoint(0.0, 0.0) withAttributes:fontAttrs];
 		[NSGraphicsContext setCurrentContext:old];
 
 		glGenTextures(1, &texture);
 		glBindTexture(GL_TEXTURE_2D, texture);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    //...but tell the GL _not_ to interpolate between texels, as that results in a _big_
+    // grey border round each letter (?!)
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 //		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, CGBitmapContextGetData(context));
 
@@ -77,8 +90,10 @@
 	// bind and draw
 	glEnable(GL_TEXTURE_2D);
 	glBindTexture(GL_TEXTURE_2D, texture);
-	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-	glColor4f(r, g, b, 1.0);
+  //"modulate" means to multiply the texture (i.e. 100%=white text, 0%=transparent bagkground)
+  // by the currently selected GL foreground colour
+	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+	glColor4f(r, g, b, 1.0); //so we select the colour we want the text to appear in
 	NSSize sz = [self sizeWithSize:iSize];
 	GLshort coords[8];
 	coords[0] = x; coords[1]=y;
diff --git a/Src/MacOSX/COSXDasherScreen.h b/Src/MacOSX/COSXDasherScreen.h
index c8c0815..0fa3446 100644
--- a/Src/MacOSX/COSXDasherScreen.h
+++ b/Src/MacOSX/COSXDasherScreen.h
@@ -85,7 +85,7 @@ public:
   /// \param Size The size at which to render the rectangle (units?)
   ///
   
-  void DrawString(const std::string &String, screenint x1, screenint y1, int Size);
+  void DrawString(const std::string &String, screenint x1, screenint y1, int Size, int iColour);
   
   ///
   /// Draw a rectangle
@@ -98,7 +98,7 @@ public:
   /// \param bDrawOutline Whether or not to draw outlines for the boxes
   ///
   
-  void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, bool bDrawOutine, bool bFill, int iThickness);
+  void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, int iThickness);
   
   void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill);
   
@@ -125,20 +125,13 @@ public:
   void Polyline(point * Points, int Number, int iWidth, int Colour);
   
   /// 
-  /// Like polyline, but fill the shape
-  /// \todo See comments for DrawPolygon
+  /// Draw a closed polygon (linking last vertex back to first)
+  /// @param fillColour colour to fill; -1 => don't fill
+  /// @param outlineColour colour to draw outline...
+  /// @param iWidth ...and line thickness; -1 => don't draw outline
   ///
-  
-  void Polygon(point *Points, int Number, int Colour, int iWidth);
-  
-  ///
-  /// \todo Not implemented
-  /// \todo One of these two routines must be redundant - find out which and kill the other
-  ///
-  
-  void DrawPolygon(point *Points, int Number, int Color, Opts::ColorSchemes ColorScheme) {
-    // not implemented 
-  };
+
+  void Polygon(point *Points, int Number, int fillColour, int outlineColour, int iWidth);
   
   /// 
   /// Blank the diplay
diff --git a/Src/MacOSX/COSXDasherScreen.mm b/Src/MacOSX/COSXDasherScreen.mm
index 0e9db5d..91d206e 100644
--- a/Src/MacOSX/COSXDasherScreen.mm
+++ b/Src/MacOSX/COSXDasherScreen.mm
@@ -28,9 +28,9 @@ void COSXDasherScreen::Display() {
   [dasherView displayCallback];
 }
 
-void COSXDasherScreen::DrawRectangle(int x1, int y1, int x2, int y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, bool bDrawOutline, bool bFill, int iThickness) {
+void COSXDasherScreen::DrawRectangle(int x1, int y1, int x2, int y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, int iThickness) {
 
-  [dasherView rectangleCallbackX1:x1 y1:y1 x2:x2 y2:y2 fillColorIndex:Color outlineColorIndex:iOutlineColour shouldOutline:bDrawOutline shouldFill:bFill lineWidth:iThickness];
+  [dasherView rectangleCallbackX1:x1 y1:y1 x2:x2 y2:y2 fillColorIndex:Color outlineColorIndex:iOutlineColour lineWidth:iThickness];
 }
 
 void COSXDasherScreen::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill) {
@@ -38,8 +38,7 @@ void COSXDasherScreen::DrawCircle(screenint iCX, screenint iCY, screenint iR, in
   [dasherView circleCallbackCentrePoint:NSMakePoint(iCX, iCY) radius:iR outlineColorIndex:iColour fillColourIndex:iFillColour shouldFill:bFill lineWidth:iThickness];
 }
 
-void COSXDasherScreen::Polygon(Dasher::CDasherScreen::point *Points, int Number, int Colour, int iWidth) {
-  // TODO polygon is not the same as polyline--fix
+void COSXDasherScreen::Polygon(Dasher::CDasherScreen::point *Points, int Number, int fillColour, int outlineColour, int iWidth) {
   NSMutableArray *p = [NSMutableArray arrayWithCapacity:Number];
   int i;
   
@@ -47,8 +46,7 @@ void COSXDasherScreen::Polygon(Dasher::CDasherScreen::point *Points, int Number,
     [p addObject:[NSValue valueWithPoint:NSMakePoint(Points[i].x, Points[i].y)]];
   }
   
-  [dasherView polylineCallbackPoints:p width:iWidth colorIndex:Colour];
-  
+  [dasherView polygonCallbackPoints:p fillColorIndex:fillColour outlineColorIndex:outlineColour lineWidth:iWidth];
 }
 
 void COSXDasherScreen::Polyline(Dasher::CDasherScreen::point *Points, int Number, int iWidth, int Colour) {
@@ -62,9 +60,9 @@ void COSXDasherScreen::Polyline(Dasher::CDasherScreen::point *Points, int Number
   [dasherView polylineCallbackPoints:p width:iWidth colorIndex:Colour];
 }
 
-void COSXDasherScreen::DrawString(const std::string &String, int x1, int y1, int size) {
+void COSXDasherScreen::DrawString(const std::string &String, int x1, int y1, int size, int iColor) {
   // TODO is that hardcoded 4 correct?
-  [dasherView drawTextCallbackWithString:NSStringFromStdString(String) x1:x1 y1:y1 size:size colorIndex:4];
+  [dasherView drawTextCallbackWithString:NSStringFromStdString(String) x1:x1 y1:y1 size:size colorIndex:iColor];
 }
 
 void COSXDasherScreen::TextSize(const std::string &String, int *Width, int *Height, int size) {
diff --git a/Src/MacOSX/DasherViewAqua.h b/Src/MacOSX/DasherViewAqua.h
index 94a30dd..9ebff31 100755
--- a/Src/MacOSX/DasherViewAqua.h
+++ b/Src/MacOSX/DasherViewAqua.h
@@ -49,7 +49,7 @@
 - (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)rectangleCallbackX1:(int)x1 y1:(int)y1 x2:(int)x2 y2:(int)y2 fillColorIndex:(int)aFillColorIndex outlineColorIndex:(int)anOutlineColorIndex shouldOutline:(BOOL)shouldOutline shouldFill:(BOOL)shouldFill 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 colorIndex:(int)aColorIndex;
 - (void)drawTextCallbackWithString:(NSString *)aString x1:(int)x1 y1:(int)y1 size:(int)aSize colorIndex:(int)aColorIndex;
 - (void)polylineCallbackPoints:(NSArray *)points width:(int)aWidth colorIndex:(int)aColorIndex;
diff --git a/Src/MacOSX/DasherViewAqua.mm b/Src/MacOSX/DasherViewAqua.mm
index 0c9967c..f45bce3 100755
--- a/Src/MacOSX/DasherViewAqua.mm
+++ b/Src/MacOSX/DasherViewAqua.mm
@@ -117,7 +117,7 @@
 }
 
 
-- (void)rectangleCallbackX1:(int)x1 y1:(int)y1 x2:(int)x2 y2:(int)y2 fillColorIndex:(int)aFillColorIndex outlineColorIndex:(int)anOutlineColorIndex shouldOutline:(BOOL)shouldOutline shouldFill:(BOOL)shouldFill 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 {
 
   float x, y, width, height;
   
@@ -141,12 +141,12 @@
   
   NSRect r = NSMakeRect(x, y, width, height);
   
-  if (shouldFill) {
+  if (aFillColorIndex!=-1) {
     [[self colorWithColorIndex:aFillColorIndex] set];
     [NSBezierPath fillRect:r];
   }
   
-  if (shouldOutline) {
+  if (aLineWidth>0) {
     [[self colorWithColorIndex:anOutlineColorIndex == -1 ? 3 : anOutlineColorIndex] set];
     
     [NSBezierPath setDefaultLineWidth:aLineWidth];
diff --git a/Src/MacOSX/DasherViewCocoa.h b/Src/MacOSX/DasherViewCocoa.h
index 2b4642f..aca8513 100644
--- a/Src/MacOSX/DasherViewCocoa.h
+++ b/Src/MacOSX/DasherViewCocoa.h
@@ -19,9 +19,10 @@
 - (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)rectangleCallbackX1:(int)x1 y1:(int)y1 x2:(int)x2 y2:(int)y2 fillColorIndex:(int)aFillColorIndex outlineColorIndex:(int)anOutlineColorIndex shouldOutline:(BOOL)shouldOutline shouldFill:(BOOL)shouldFill 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 colorIndex:(int)aColorIndex;
 - (void)drawTextCallbackWithString:(NSString *)aString x1:(int)x1 y1:(int)y1 size:(int)aSize colorIndex:(int)aColorIndex;
+- (void)polygonCallbackPoints:(NSArray *)points fillColorIndex:(int)fColorIndex outlineColorIndex:(int)iColorIndex lineWidth:(int)aWidth;
 - (void)polylineCallbackPoints:(NSArray *)points width:(int)aWidth colorIndex:(int)aColorIndex;
 - (void)finishRealization;
 - (COSXDasherScreen *)aquaDasherScreen;
diff --git a/Src/MacOSX/DasherViewOpenGL.h b/Src/MacOSX/DasherViewOpenGL.h
index 6e58649..8d58522 100755
--- a/Src/MacOSX/DasherViewOpenGL.h
+++ b/Src/MacOSX/DasherViewOpenGL.h
@@ -60,11 +60,12 @@ typedef struct {
 - (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)rectangleCallbackX1:(int)x1 y1:(int)y1 x2:(int)x2 y2:(int)y2 fillColorIndex:(int)aFillColorIndex outlineColorIndex:(int)anOutlineColorIndex shouldOutline:(BOOL)shouldOutline shouldFill:(BOOL)shouldFill 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 colorIndex:(int)aColorIndex;
 - (void)drawTextCallbackWithString:(NSString *)aString x1:(int)x1 y1:(int)y1 size:(int)aSize colorIndex:(int)aColorIndex;
 - (void)colourSchemeCallbackWithColourTable:(colour_t *)aColourTable;
+- (void)polygonCallbackPoints:(NSArray *)points fillColorIndex:(int)fColorIndex outlineColorIndex:(int)iColorIndex lineWidth:(int)aWidth;
 - (void)polylineCallbackPoints:(NSArray *)points width:(int)aWidth colorIndex:(int)aColorIndex;
 - (id)initWithFrame:(NSRect)frame;
 - (void)userDefaultsDidChange:(NSNotification *)aNote;
diff --git a/Src/MacOSX/DasherViewOpenGL.mm b/Src/MacOSX/DasherViewOpenGL.mm
index c331cd6..9d01ccc 100755
--- a/Src/MacOSX/DasherViewOpenGL.mm
+++ b/Src/MacOSX/DasherViewOpenGL.mm
@@ -148,7 +148,7 @@
 }
 
 
-- (void)rectangleCallbackX1:(int)x1 y1:(int)y1 x2:(int)x2 y2:(int)y2 fillColorIndex:(int)aFillColorIndex outlineColorIndex:(int)anOutlineColorIndex shouldOutline:(BOOL)shouldOutline shouldFill:(BOOL)shouldFill 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 {
   
   // don't know if this is needed with opengl...does it cope with wonky coords?
   //  float x, y, width, height;
@@ -172,17 +172,17 @@
   //  }
   glDisable(GL_TEXTURE_2D);
   glEnableClientState(GL_VERTEX_ARRAY);
-  if (shouldFill) {
+  if (aFillColorIndex!=-1) {
     glColor4f(colourTable[aFillColorIndex].r, colourTable[aFillColorIndex].g, colourTable[aFillColorIndex].b, 1.0);
     GLshort coords[8] = {x1,y1, x2,y1, x1,y2, x2,y2};
     glVertexPointer(2, GL_SHORT, 0, coords);
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   }
   
-  if (shouldOutline) {
+  if (aLineWidth>0) {
     int oci = anOutlineColorIndex == -1 ? 3 : anOutlineColorIndex;
     glColor4f(colourTable[oci].r, colourTable[oci].g, colourTable[oci].b, 1.0);
-    glLineWidth(1.0f);
+    glLineWidth(aLineWidth);
     GLshort coords[] = {x1,y1, x2,y1, x2,y2, x1,y2};
     glVertexPointer(2, GL_SHORT, 0, coords);
     glDrawArrays(GL_LINE_LOOP, 0, 4);
@@ -225,6 +225,33 @@
   colourTable = aColourTable;
 }
 
+- (void)polygonCallbackPoints:(NSArray *)points fillColorIndex:(int)fColorIndex outlineColorIndex:(int)iColorIndex lineWidth:(int)iWidth {
+  int len = [points count];
+	if (len < 2) return;
+  //1. fill...
+	glDisable(GL_TEXTURE_2D);
+  if (fColorIndex != -1) {
+    glColor3f(colourTable[fColorIndex].r, colourTable[fColorIndex].g, colourTable[fColorIndex].b);
+	  glBegin(GL_TRIANGLE_FAN);
+    for (int i = 0; i < len; i++)
+    {
+      NSPoint nsp = [[points objectAtIndex:i] pointValue];
+      glVertex2i(nsp.x,nsp.y);
+    }
+    glEnd();
+  }
+  if (iWidth>0) {
+    glColor3f(colourTable[iColorIndex].r,colourTable[iColorIndex].g,colourTable[iColorIndex].b);
+    glLineWidth(iWidth);
+    glBegin(GL_LINE_LOOP);
+    for (int i = 0; i < len; i++)
+    {
+      NSPoint nsp = [[points objectAtIndex:i] pointValue];
+      glVertex2i(nsp.x,nsp.y);
+    }
+    glEnd();
+  }
+}
 
 - (void)polylineCallbackPoints:(NSArray *)points width:(int)aWidth colorIndex:(int)aColorIndex
 {
diff --git a/Src/Qt/QtDasherScreen.cc b/Src/Qt/QtDasherScreen.cc
index 6c8dd8d..1e5e277 100644
--- a/Src/Qt/QtDasherScreen.cc
+++ b/Src/Qt/QtDasherScreen.cc
@@ -143,8 +143,9 @@ void QtDasherScreen::Polyline(point *Points, int Number) const {
   painter->setPen(NoPen);
 }
 
-void QtDasherScreen::DrawPolygon(point *Points, int Number, int Color, Opts::ColorSchemes ColorScheme) const {
-  painter->setBrush(getColor(Color, ColorScheme));
+void QtDasherScreen::Polygon(point *Points, int Number, int fillColor, int outlineColour, int iWidth) const {
+  //TODO, not sure what the deal is with color schemes...we don't have one, what should we do?
+  //painter->setBrush(getColor(fillColor, ColorScheme));
   QPointArray qpa(Number);
   Points_to_QPointArray(Points, Number, qpa);
   painter->drawPolygon(qpa);
diff --git a/Src/Qt/QtDasherScreen.h b/Src/Qt/QtDasherScreen.h
index 5972ee7..a8747ba 100644
--- a/Src/Qt/QtDasherScreen.h
+++ b/Src/Qt/QtDasherScreen.h
@@ -56,7 +56,7 @@ Q_OBJECT public:
   void Polyline(point * Points, int Number, int Color) const {
     Polyline(Points, Number, Color);
   };
-  void DrawPolygon(point * Points, int Number, int Color, Opts::ColorSchemes ColorScheme) const;
+  void Polygon(point * Points, int Number, int fillColor, int outlineColor, int lineWidth) const;
   void SetColourScheme(const Dasher::CCustomColours * scheme) {
   };
 
diff --git a/Src/iPhone/Classes/AlphabetLetter.mm b/Src/iPhone/Classes/AlphabetLetter.mm
index 53e353b..72bd2c2 100644
--- a/Src/iPhone/Classes/AlphabetLetter.mm
+++ b/Src/iPhone/Classes/AlphabetLetter.mm
@@ -60,18 +60,19 @@ void dump(char *data, int width, int height)
 		UIGraphicsPushContext(context);
 
 		CGContextClearRect(context, CGRectMake(0.0, 0.0, width, height));
-		const CGFloat blackComps[] = {0.0, 0.0, 0.0, 1.0};
-		CGColorRef black = CGColorCreate(colorSpace, blackComps);
-		CGContextSetFillColorWithColor(context, black);
-		CGContextSetStrokeColorWithColor(context, black);
+    //white text on transparent background means that when we texture
+    //a surface using a colour, the text appears in that colour...
+		const CGFloat whiteComps[] = {1.0, 1.0, 1.0, 1.0};
+		CGColorRef white = CGColorCreate(colorSpace, whiteComps);
+		CGContextSetFillColorWithColor(context, white);
 		[string drawAtPoint:CGPointMake(0.0, 0.0) withFont:[UIFont systemFontOfSize:36]];
-		CGColorRelease(black);
+		CGColorRelease(white);
 		UIGraphicsPopContext();
 
 		glGenTextures(1, &texture);
 		glBindTexture(GL_TEXTURE_2D, texture);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 //		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, CGBitmapContextGetData(context));
 		//set texture coords for the corners of the part of the texture we actually
@@ -96,8 +97,9 @@ void dump(char *data, int width, int height)
 	// bind and draw
 	glEnable(GL_TEXTURE_2D);
 	glBindTexture(GL_TEXTURE_2D, texture);
-//	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-	glColor4f(r, g, b, 1.0);
+  //combine the texture colour (white, i.e. 100%) with the current foreground colour...
+	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+	glColor4f(r, g, b, 1.0); //....i.e. the colour we want the text to appear in...
 	CGSize sz = [self sizeWithSize:iSize];
 	GLshort coords[8];
 	coords[0] = x; coords[1]=y;
diff --git a/Src/iPhone/Classes/CDasherScreenBridge.h b/Src/iPhone/Classes/CDasherScreenBridge.h
index 5fd5a37..c501040 100644
--- a/Src/iPhone/Classes/CDasherScreenBridge.h
+++ b/Src/iPhone/Classes/CDasherScreenBridge.h
@@ -43,7 +43,7 @@ public:
   /// \param Size The size at which to render the rectangle (units?)
   ///
   
-  void DrawString(const std::string &String, screenint x1, screenint y1, int Size);
+  void DrawString(const std::string &String, screenint x1, screenint y1, int Size, int iColour);
   
   ///
   /// Draw a rectangle
@@ -51,12 +51,11 @@ public:
   /// \param y1 y coordiate of the top left corner
   /// \param x2 x coordiate of the bottom right corner
   /// \param y2 y coordiate of the bottom right corner
-  /// \param Color Colour to draw the rectangle
+  /// \param Color Colour to fill the rectangle
   /// \param ColorScheme Which of the alternating colour schemes to use (be more precise)
-  /// \param bDrawOutline Whether or not to draw outlines for the boxes
   ///
   
-  void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, bool bDrawOutine, bool bFill, int iThickness);
+  void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, int iThickness);
   
   void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill);
   
@@ -84,10 +83,9 @@ public:
   
   /// 
   /// Like polyline, but fill the shape
-  /// \todo See comments for DrawPolygon
   ///
   
-  void Polygon(point *Points, int Number, int Colour, int iWidth);
+  void Polygon(point *Points, int Number, int fillColour, int outlineColor, int iWidth);
     
   /// 
   /// Blank the diplay
diff --git a/Src/iPhone/Classes/CDasherScreenBridge.mm b/Src/iPhone/Classes/CDasherScreenBridge.mm
index 8a2adf3..d61e79c 100644
--- a/Src/iPhone/Classes/CDasherScreenBridge.mm
+++ b/Src/iPhone/Classes/CDasherScreenBridge.mm
@@ -27,9 +27,9 @@ void CDasherScreenBridge::Display() {
   [dasherView displayCallback];
 }
 
-void CDasherScreenBridge::DrawRectangle(int x1, int y1, int x2, int y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, bool bDrawOutline, bool bFill, int iThickness) {
+void CDasherScreenBridge::DrawRectangle(int x1, int y1, int x2, int y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, int iThickness) {
 
-  [dasherView rectangleCallbackX1:x1 y1:y1 x2:x2 y2:y2 fillColorIndex:Color outlineColorIndex:iOutlineColour shouldOutline:bDrawOutline shouldFill:bFill lineWidth:iThickness];
+  [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) {
@@ -37,8 +37,8 @@ void CDasherScreenBridge::DrawCircle(screenint iCX, screenint iCY, screenint iR,
   [dasherView circleCallbackCentrePoint:CGPointMake(iCX, iCY) radius:iR outlineColorIndex:iColour fillColourIndex:iFillColour shouldFill:bFill lineWidth:iThickness];
 }
 
-void CDasherScreenBridge::Polygon(Dasher::CDasherScreen::point *Points, int Number, int Colour, int iWidth) {
-	[dasherView polygonCallback:Number points:Points width:iWidth colourIndex:Colour];
+void CDasherScreenBridge::Polygon(Dasher::CDasherScreen::point *Points, int Number, int fillColour, int outlineColour, int iWidth) {
+	[dasherView polygonCallback:Number points:Points fillColourIndex:fillColour outlineColourIndex:outlineColour width:iWidth];
   
 }
 
@@ -46,9 +46,8 @@ void CDasherScreenBridge::Polyline(Dasher::CDasherScreen::point *Points, int Num
 	[dasherView polylineCallback:Number points:Points width:iWidth colourIndex:Colour];
 }
 
-void CDasherScreenBridge::DrawString(const std::string &String, screenint x1, screenint y1, int size) {
-	//TODO hardcoded colour index 4 ???
-	[dasherView drawTextCallbackWithString:NSStringFromStdString(String) x1:x1 y1:y1 size:size colorIndex:4];
+void CDasherScreenBridge::DrawString(const std::string &String, screenint x1, screenint y1, int size, int iColour) {
+	[dasherView drawTextCallbackWithString:NSStringFromStdString(String) x1:x1 y1:y1 size:size colorIndex:iColour];
 }
 
 void CDasherScreenBridge::TextSize(const std::string &String, screenint *Width, screenint *Height, int size) {
diff --git a/Src/iPhone/Classes/DasherScreenCallbacks.h b/Src/iPhone/Classes/DasherScreenCallbacks.h
index f62bbf2..fbc7163 100644
--- a/Src/iPhone/Classes/DasherScreenCallbacks.h
+++ b/Src/iPhone/Classes/DasherScreenCallbacks.h
@@ -12,13 +12,13 @@ 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 shouldOutline:(BOOL)shouldOutline shouldFill:(BOOL)shouldFill 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;
 -(void)circleCallbackCentrePoint:(CGPoint)aCentrePoint radius:(float)aRadius outlineColorIndex:(int)anOutlineColorIndex fillColourIndex:(int)aFillColourIndex shouldFill:(BOOL)shouldFill 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;
 -(void)polylineCallback:(int)Number points:(Dasher::CDasherScreen::point *)points width:(int)iWidth colourIndex:(int)iColour;
--(void)polygonCallback:(int)Number points:(Dasher::CDasherScreen::point *)points width:(int)iWidth colourIndex:(int)iColour;
+-(void)polygonCallback:(int)Number points:(Dasher::CDasherScreen::point *)points fillColourIndex:(int)iColour outlineColourIndex:(int)iLineColour width:(int)iWidth;
 -(void)blankCallback;
 -(void)displayCallback;
 -(void)setColourSchemeWithColourTable:(colour_t *)colourTable;
diff --git a/Src/iPhone/Classes/EAGLView.mm b/Src/iPhone/Classes/EAGLView.mm
index 1137bec..254a6d7 100644
--- a/Src/iPhone/Classes/EAGLView.mm
+++ b/Src/iPhone/Classes/EAGLView.mm
@@ -258,19 +258,19 @@
     [context presentRenderbuffer:GL_RENDERBUFFER_OES];
 };
 
--(void)rectangleCallbackX1:(int)x1 y1:(int)y1 x2:(int)x2 y2:(int)y2 fillColorIndex:(int)aFillColorIndex outlineColorIndex:(int)anOutlineColorIndex shouldOutline:(BOOL)shouldOutline shouldFill:(BOOL)shouldFill 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 {
 	glDisable(GL_TEXTURE_2D);
 	glEnableClientState(GL_VERTEX_ARRAY);
-	if (shouldFill) {
+	if (aFillColorIndex != -1) {
 		glColor4f(colourTable[aFillColorIndex].r, colourTable[aFillColorIndex].g, colourTable[aFillColorIndex].b, 1.0);
 		GLshort coords[8] = {x1,y1, x2,y1, x1,y2, x2,y2};
 		glVertexPointer(2, GL_SHORT, 0, coords);
 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 	}
-	if (shouldOutline) {
+	if (aLineWidth>0) {
 		int oci = anOutlineColorIndex == -1 ? 3 : anOutlineColorIndex;
 		glColor4f(colourTable[oci].r, colourTable[oci].g, colourTable[oci].b, 1.0);
-		glLineWidth(1.0f);
+		glLineWidth(aLineWidth);
 		GLshort coords[] = {x1,y1, x2,y1, x2,y2,  x1,y2};
 		glVertexPointer(2, GL_SHORT, 0, coords);
 		glDrawArrays(GL_LINE_LOOP, 0, 4);
@@ -318,7 +318,28 @@
 	delete coords;
 }
 
-//-(void)polygonCallback:(int)iNum Points:(Dasher::CDasherScreen::point *)points Width:(int)iWidth ColourIndex:(int)iColour;
+-(void)polygonCallback:(int)iNum points:(Dasher::CDasherScreen::point *)points fillColourIndex:(int)iFillColour outlineColourIndex:(int)iOutlineColour width:(int)iWidth {
+  if (iNum < 2) return;
+  GLshort *coords = new GLshort[iNum*2];
+  for (int i = 0; i<iNum; i++)
+  {
+    coords[2*i] = points[i].x;
+    coords[2*i+1] = points[i].y;
+  }
+  glDisable(GL_TEXTURE_2D);
+  if (iFillColour != -1) {
+    glColor4f(colourTable[iFillColour].r, colourTable[iFillColour].g, colourTable[iFillColour].b, 1.0);
+    glVertexPointer(2, GL_SHORT, 0, coords);
+    glDrawArrays(GL_TRIANGLE_FAN, 0, iNum);
+  }
+  if (iWidth>0) {
+    glColor4f(colourTable[iOutlineColour].r, colourTable[iOutlineColour].g, colourTable[iOutlineColour].b, 1.0);
+    glLineWidth(iWidth);
+    glVertexPointer(2, GL_SHORT, 0, coords);
+    glDrawArrays(GL_LINE_LOOP, 0, iNum);
+  }
+  delete coords;
+}
 
 -(void)setColourSchemeWithColourTable:(colour_t *)aColourTable {
 	if (colourTable != NULL) {



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