]> git.saurik.com Git - wxWidgets.git/blobdiff - utils/ogl/src/basic2.cpp
Added SetFont to most controls and controls sample
[wxWidgets.git] / utils / ogl / src / basic2.cpp
index bff1defda1166be69f1919d3b5825ac0357fa606..2c9c7c9b2cdef90c7430c2b83082df17b5b9850e 100644 (file)
@@ -67,6 +67,8 @@ wxPolygonShape::wxPolygonShape()
 
 void wxPolygonShape::Create(wxList *the_points)
 {
+  ClearPoints();
+
   m_originalPoints = the_points;
 
   // Duplicate the list of points
@@ -87,6 +89,11 @@ void wxPolygonShape::Create(wxList *the_points)
 }
 
 wxPolygonShape::~wxPolygonShape()
+{
+    ClearPoints();
+}
+
+void wxPolygonShape::ClearPoints()
 {
   if (m_points)
   {
@@ -99,6 +106,7 @@ wxPolygonShape::~wxPolygonShape()
       node = m_points->First();
     }
     delete m_points;
+    m_points = NULL;
   }
   if (m_originalPoints)
   {
@@ -111,12 +119,13 @@ wxPolygonShape::~wxPolygonShape()
       node = m_originalPoints->First();
     }
     delete m_originalPoints;
+    m_originalPoints = NULL;
   }
 }
 
 
 // Width and height. Centre of object is centre of box.
-void wxPolygonShape::GetBoundingBoxMin(float *width, float *height)
+void wxPolygonShape::GetBoundingBoxMin(double *width, double *height)
 {
   *width = m_boundWidth;
   *height = m_boundHeight;
@@ -125,10 +134,10 @@ void wxPolygonShape::GetBoundingBoxMin(float *width, float *height)
 void wxPolygonShape::CalculateBoundingBox()
 {
   // Calculate bounding box at construction (and presumably resize) time
-  float left = 10000;
-  float right = -10000;
-  float top = 10000;
-  float bottom = -10000;
+  double left = 10000;
+  double right = -10000;
+  double top = 10000;
+  double bottom = -10000;
 
   wxNode *node = m_points->First();
   while (node)
@@ -153,10 +162,10 @@ void wxPolygonShape::CalculateBoundingBox()
 // box.
 void wxPolygonShape::CalculatePolygonCentre()
 {
-  float left = 10000;
-  float right = -10000;
-  float top = 10000;
-  float bottom = -10000;
+  double left = 10000;
+  double right = -10000;
+  double top = 10000;
+  double bottom = -10000;
 
   wxNode *node = m_points->First();
   while (node)
@@ -170,11 +179,11 @@ void wxPolygonShape::CalculatePolygonCentre()
 
     node = node->Next();
   }
-  float bwidth = right - left;
-  float bheight = bottom - top;
-  
-  float newCentreX = (float)(left + (bwidth/2.0));
-  float newCentreY = (float)(top + (bheight/2.0));
+  double bwidth = right - left;
+  double bheight = bottom - top;
+
+  double newCentreX = (double)(left + (bwidth/2.0));
+  double newCentreY = (double)(top + (bheight/2.0));
 
   node = m_points->First();
   while (node)
@@ -188,22 +197,22 @@ void wxPolygonShape::CalculatePolygonCentre()
   m_ypos += newCentreY;
 }
 
-bool PolylineHitTest(float n, float xvec[], float yvec[],
-                           float x1, float y1, float x2, float y2)
+bool PolylineHitTest(double n, double xvec[], double yvec[],
+                           double x1, double y1, double x2, double y2)
 {
   bool isAHit = FALSE;
   int i;
-  float lastx = xvec[0];
-  float lasty = yvec[0];
+  double lastx = xvec[0];
+  double lasty = yvec[0];
 
-  float min_ratio = 1.0;
-  float line_ratio;
-  float other_ratio;
+  double min_ratio = 1.0;
+  double line_ratio;
+  double other_ratio;
 
 //  char buf[300];
   for (i = 1; i < n; i++)
   {
-    check_line_intersection(x1, y1, x2, y2, lastx, lasty, xvec[i], yvec[i],
+    oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[i], yvec[i],
                             &line_ratio, &other_ratio);
     if (line_ratio != 1.0)
       isAHit = TRUE;
@@ -216,10 +225,10 @@ bool PolylineHitTest(float n, float xvec[], float yvec[],
       min_ratio = line_ratio;
   }
 
-  // Do last (implicit) line if last and first floats are not identical
+  // Do last (implicit) line if last and first doubles are not identical
   if (!(xvec[0] == lastx && yvec[0] == lasty))
   {
-    check_line_intersection(x1, y1, x2, y2, lastx, lasty, xvec[0], yvec[0],
+    oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[0], yvec[0],
                             &line_ratio, &other_ratio);
     if (line_ratio != 1.0)
       isAHit = TRUE;
@@ -233,30 +242,30 @@ bool PolylineHitTest(float n, float xvec[], float yvec[],
   return isAHit;
 }
 
-bool wxPolygonShape::HitTest(float x, float y, int *attachment, float *distance)
+bool wxPolygonShape::HitTest(double x, double y, int *attachment, double *distance)
 {
   // Imagine four lines radiating from this point. If all of these lines hit the polygon,
   // we're inside it, otherwise we're not. Obviously we'd need more radiating lines
   // to be sure of correct results for very strange (concave) shapes.
-  float endPointsX[4];
-  float endPointsY[4];
+  double endPointsX[4];
+  double endPointsY[4];
   // North
   endPointsX[0] = x;
-  endPointsY[0] = (float)(y - 1000.0);
+  endPointsY[0] = (double)(y - 1000.0);
   // East
-  endPointsX[1] = (float)(x + 1000.0);
+  endPointsX[1] = (double)(x + 1000.0);
   endPointsY[1] = y;
   // South
   endPointsX[2] = x;
-  endPointsY[2] = (float)(y + 1000.0);
+  endPointsY[2] = (double)(y + 1000.0);
   // West
-  endPointsX[3] = (float)(x - 1000.0);
+  endPointsX[3] = (double)(x - 1000.0);
   endPointsY[3] = y;
 
   // Store polygon points in an array
   int np = m_points->Number();
-  float *xpoints = new float[np];
-  float *ypoints = new float[np];
+  double *xpoints = new double[np];
+  double *ypoints = new double[np];
   wxNode *node = m_points->First();
   int i = 0;
   while (node)
@@ -294,14 +303,14 @@ bool wxPolygonShape::HitTest(float x, float y, int *attachment, float *distance)
 
   // If a hit, check the attachment points within the object.
   int n = GetNumberOfAttachments();
-  float nearest = 999999.0;
+  double nearest = 999999.0;
 
   for (i = 0; i < n; i++)
   {
-    float xp, yp;
+    double xp, yp;
     if (GetAttachmentPosition(i, &xp, &yp))
     {
-      float l = (float)sqrt(((xp - x) * (xp - x)) +
+      double l = (double)sqrt(((xp - x) * (xp - x)) +
                  ((yp - y) * (yp - y)));
       if (l < nearest)
       {
@@ -317,13 +326,13 @@ bool wxPolygonShape::HitTest(float x, float y, int *attachment, float *distance)
 
 // Really need to be able to reset the shape! Otherwise, if the
 // points ever go to zero, we've lost it, and can't resize.
-void wxPolygonShape::SetSize(float new_width, float new_height, bool recursive)
+void wxPolygonShape::SetSize(double new_width, double new_height, bool recursive)
 {
   SetAttachmentSize(new_width, new_height);
   
   // Multiply all points by proportion of new size to old size
-  float x_proportion = (float)(fabs(new_width/m_originalWidth));
-  float y_proportion = (float)(fabs(new_height/m_originalHeight));
+  double x_proportion = (double)(fabs(new_width/m_originalWidth));
+  double y_proportion = (double)(fabs(new_height/m_originalHeight));
 
   wxNode *node = m_points->First();
   wxNode *original_node = m_originalPoints->First();
@@ -340,8 +349,8 @@ void wxPolygonShape::SetSize(float new_width, float new_height, bool recursive)
   }
 
 //  CalculateBoundingBox();
-  m_boundWidth = (float)fabs(new_width);
-  m_boundHeight = (float)fabs(new_height);
+  m_boundWidth = (double)fabs(new_width);
+  m_boundHeight = (double)fabs(new_height);
   SetDefaultRegionSize();
 }
 
@@ -384,8 +393,8 @@ void wxPolygonShape::AddPolygonPoint(int pos)
   if (!node2) node2 = m_points->First();
   wxRealPoint *secondPoint = (wxRealPoint *)node2->Data();
 
-  float x = (float)((secondPoint->x - firstPoint->x)/2.0 + firstPoint->x);
-  float y = (float)((secondPoint->y - firstPoint->y)/2.0 + firstPoint->y);
+  double x = (double)((secondPoint->x - firstPoint->x)/2.0 + firstPoint->x);
+  double y = (double)((secondPoint->y - firstPoint->y)/2.0 + firstPoint->y);
   wxRealPoint *point = new wxRealPoint(x, y);
 
   if (pos >= (m_points->Number() - 1))
@@ -420,15 +429,15 @@ void wxPolygonShape::DeletePolygonPoint(int pos)
 }
 
 // Assume (x1, y1) is centre of box (most generally, line end at box)
-bool wxPolygonShape::GetPerimeterPoint(float x1, float y1,
-                                     float x2, float y2,
-                                     float *x3, float *y3)
+bool wxPolygonShape::GetPerimeterPoint(double x1, double y1,
+                                     double x2, double y2,
+                                     double *x3, double *y3)
 {
   int n = m_points->Number();
 
   // First check for situation where the line is vertical,
   // and we would want to connect to a point on that vertical --
-  // find_end_for_polyline can't cope with this (the arrow
+  // oglFindEndForPolyline can't cope with this (the arrow
   // gets drawn to the wrong place).
   if ((!m_attachmentMode) && (x1 == x2))
   {
@@ -457,8 +466,8 @@ bool wxPolygonShape::GetPerimeterPoint(float x1, float y1,
     }
   }
   
-  float *xpoints = new float[n];
-  float *ypoints = new float[n];
+  double *xpoints = new double[n];
+  double *ypoints = new double[n];
 
   wxNode *node = m_points->First();
   int i = 0;
@@ -470,17 +479,12 @@ bool wxPolygonShape::GetPerimeterPoint(float x1, float y1,
     node = node->Next();
     i ++;
   }
-/*
-  wxRealPoint *point = (wxRealPoint *)m_points->First()->Data();
-  xpoints[i] = point->x + m_xpos;
-  ypoints[i] = point->y + m_ypos;
-*/
 
-  find_end_for_polyline(n, xpoints, ypoints, 
+  oglFindEndForPolyline(n, xpoints, ypoints, 
                         x1, y1, x2, y2, x3, y3);
 
-  delete xpoints;
-  delete ypoints;
+  delete[] xpoints;
+  delete[] ypoints;
 
   return TRUE;
 }
@@ -493,48 +497,51 @@ void wxPolygonShape::OnDraw(wxDC& dc)
     for (i = 0; i < n; i++)
     {
       wxRealPoint* point = (wxRealPoint*) m_points->Nth(i)->Data();
-      intPoints[i].x = (int) point->x;
-      intPoints[i].y = (int) point->y;
+      intPoints[i].x = WXROUND(point->x);
+      intPoints[i].y = WXROUND(point->y);
     }
 
     if (m_shadowMode != SHADOW_NONE)
     {
       if (m_shadowBrush)
         dc.SetBrush(m_shadowBrush);
-      dc.SetPen(transparent_pen);
+      dc.SetPen(g_oglTransparentPen);
 
-      dc.DrawPolygon(n, intPoints, m_xpos + m_shadowOffsetX, m_ypos + m_shadowOffsetY);
+      dc.DrawPolygon(n, intPoints, WXROUND(m_xpos + m_shadowOffsetX), WXROUND(m_ypos + m_shadowOffsetY));
     }
 
     if (m_pen)
     {
       if (m_pen->GetWidth() == 0)
-        dc.SetPen(transparent_pen);
+        dc.SetPen(g_oglTransparentPen);
       else
         dc.SetPen(m_pen);
     }
     if (m_brush)
       dc.SetBrush(m_brush);
-    dc.DrawPolygon(n, intPoints, m_xpos, m_ypos);
+    dc.DrawPolygon(n, intPoints, WXROUND(m_xpos), WXROUND(m_ypos));
 
     delete[] intPoints;
 }
 
-void wxPolygonShape::OnDrawOutline(wxDC& dc, float x, float y, float w, float h)
+void wxPolygonShape::OnDrawOutline(wxDC& dc, double x, double y, double w, double h)
 {
   dc.SetBrush(wxTRANSPARENT_BRUSH);
+  // Multiply all points by proportion of new size to old size
+  double x_proportion = (double)(fabs(w/m_originalWidth));
+  double y_proportion = (double)(fabs(h/m_originalHeight));
 
-  int n = m_points->Number();
+  int n = m_originalPoints->Number();
   wxPoint *intPoints = new wxPoint[n];
   int i;
   for (i = 0; i < n; i++)
   {
-    wxRealPoint* point = (wxRealPoint*) m_points->Nth(i)->Data();
-    intPoints[i].x = (int) point->x;
-    intPoints[i].y = (int) point->y;
+    wxRealPoint* point = (wxRealPoint*) m_originalPoints->Nth(i)->Data();
+    intPoints[i].x = WXROUND(x_proportion * point->x);
+    intPoints[i].y = WXROUND(y_proportion * point->y);
   }
-  dc.DrawPolygon(n, intPoints, x, y);
-//  wxShape::OnDrawOutline(x, y, w, h);
+  dc.DrawPolygon(n, intPoints, WXROUND(x), WXROUND(y));
+  delete[] intPoints;
 }
 
 // Make as many control points as there are vertices.
@@ -552,19 +559,19 @@ void wxPolygonShape::MakeControlPoints()
   }
 
 /*
-  float maxX, maxY, minX, minY;
+  double maxX, maxY, minX, minY;
 
   GetBoundingBoxMax(&maxX, &maxY);
   GetBoundingBoxMin(&minX, &minY);
 
-  float widthMin = (float)(minX + CONTROL_POINT_SIZE + 2);
-  float heightMin = (float)(minY + CONTROL_POINT_SIZE + 2);
+  double widthMin = (double)(minX + CONTROL_POINT_SIZE + 2);
+  double heightMin = (double)(minY + CONTROL_POINT_SIZE + 2);
 
   // Offsets from main object
-  float top = (float)(- (heightMin / 2.0));
-  float bottom = (float)(heightMin / 2.0 + (maxY - minY));
-  float left = (float)(- (widthMin / 2.0));
-  float right = (float)(widthMin / 2.0 + (maxX - minX));
+  double top = (double)(- (heightMin / 2.0));
+  double bottom = (double)(heightMin / 2.0 + (maxY - minY));
+  double left = (double)(- (widthMin / 2.0));
+  double right = (double)(widthMin / 2.0 + (maxX - minX));
 
   wxControlPoint *control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, left, top, 
                                            CONTROL_POINT_DIAGONAL);
@@ -629,19 +636,19 @@ void wxPolygonShape::ResetControlPoints()
   if (m_controlPoints.Number() < 1)
     return;
 
-  float maxX, maxY, minX, minY;
+  double maxX, maxY, minX, minY;
 
   GetBoundingBoxMax(&maxX, &maxY);
   GetBoundingBoxMin(&minX, &minY);
 
-  float widthMin = (float)(minX + CONTROL_POINT_SIZE + 2);
-  float heightMin = (float)(minY + CONTROL_POINT_SIZE + 2);
+  double widthMin = (double)(minX + CONTROL_POINT_SIZE + 2);
+  double heightMin = (double)(minY + CONTROL_POINT_SIZE + 2);
 
   // Offsets from main object
-  float top = (float)(- (heightMin / 2.0));
-  float bottom = (float)(heightMin / 2.0 + (maxY - minY));
-  float left = (float)(- (widthMin / 2.0));
-  float right = (float)(widthMin / 2.0 + (maxX - minX));
+  double top = (double)(- (heightMin / 2.0));
+  double bottom = (double)(heightMin / 2.0 + (maxY - minY));
+  double left = (double)(- (widthMin / 2.0));
+  double right = (double)(widthMin / 2.0 + (maxX - minX));
 
   wxNode *node = m_controlPoints.First();
   wxControlPoint *control = (wxControlPoint *)node->Data();
@@ -686,8 +693,8 @@ void wxPolygonShape::WritePrologAttributes(wxExpr *clause)
   {
     wxRealPoint *point = (wxRealPoint *)node->Data();
     wxExpr *point_list = new wxExpr(PrologList);
-    wxExpr *x_expr = new wxExpr((float)point->x);
-    wxExpr *y_expr = new wxExpr((float)point->y);
+    wxExpr *x_expr = new wxExpr((double)point->x);
+    wxExpr *y_expr = new wxExpr((double)point->y);
 
     point_list->Append(x_expr);
     point_list->Append(y_expr);
@@ -704,8 +711,8 @@ void wxPolygonShape::WritePrologAttributes(wxExpr *clause)
   {
     wxRealPoint *point = (wxRealPoint *)node->Data();
     wxExpr *point_list = new wxExpr(PrologList);
-    wxExpr *x_expr = new wxExpr((float) point->x);
-    wxExpr *y_expr = new wxExpr((float) point->y);
+    wxExpr *x_expr = new wxExpr((double) point->x);
+    wxExpr *y_expr = new wxExpr((double) point->y);
     point_list->Append(x_expr);
     point_list->Append(y_expr);
     list->Append(point_list);
@@ -727,8 +734,8 @@ void wxPolygonShape::ReadPrologAttributes(wxExpr *clause)
   clause->AssignAttributeValue("points", &points_list);
 
   // If no points_list, don't crash!! Assume a diamond instead.
-  float the_height = 100.0;
-  float the_width = 100.0;
+  double the_height = 100.0;
+  double the_width = 100.0;
   if (!points_list)
   {
     wxRealPoint *point = new wxRealPoint(0.0, (-the_height/2));
@@ -758,7 +765,7 @@ void wxPolygonShape::ReadPrologAttributes(wxExpr *clause)
       wxExpr *yexpr = xexpr->next;
       long y = yexpr->IntegerValue();
 
-      wxRealPoint *point = new wxRealPoint((float)x, (float)y);
+      wxRealPoint *point = new wxRealPoint((double)x, (double)y);
       m_points->Append((wxObject*) point);
 
       node = node->next;
@@ -792,10 +799,10 @@ void wxPolygonShape::ReadPrologAttributes(wxExpr *clause)
   else
   {
     wxExpr *node = points_list->value.first;
-    float min_x = 1000;
-    float min_y = 1000;
-    float max_x = -1000;
-    float max_y = -1000;
+    double min_x = 1000;
+    double min_y = 1000;
+    double max_x = -1000;
+    double max_y = -1000;
     while (node)
     {
       wxExpr *xexpr = node->value.first;
@@ -804,17 +811,17 @@ void wxPolygonShape::ReadPrologAttributes(wxExpr *clause)
       wxExpr *yexpr = xexpr->next;
       long y = yexpr->IntegerValue();
 
-      wxRealPoint *point = new wxRealPoint((float)x, (float)y);
+      wxRealPoint *point = new wxRealPoint((double)x, (double)y);
       m_originalPoints->Append((wxObject*) point);
 
       if (x < min_x)
-        min_x = (float)x;
+        min_x = (double)x;
       if (y < min_y)
-        min_y = (float)y;
+        min_y = (double)y;
       if (x > max_x)
-        max_x = (float)x;
+        max_x = (double)x;
       if (y > max_y)
-        max_y = (float)y;
+        max_y = (double)y;
 
       node = node->next;
     }
@@ -826,26 +833,25 @@ void wxPolygonShape::ReadPrologAttributes(wxExpr *clause)
 }
 #endif
 
-void wxPolygonShape::Copy(wxPolygonShape& copy)
+void wxPolygonShape::Copy(wxShape& copy)
 {
   wxShape::Copy(copy);
 
-  if (copy.m_points)
-    delete copy.m_points;
+  wxASSERT( copy.IsKindOf(CLASSINFO(wxPolygonShape)) );
 
-  copy.m_points = new wxList;
+  wxPolygonShape& polyCopy = (wxPolygonShape&) copy;
 
-  if (copy.m_originalPoints)
-    delete copy.m_originalPoints;
+  polyCopy.ClearPoints();
 
-  copy.m_originalPoints = new wxList;
+  polyCopy.m_points = new wxList;
+  polyCopy.m_originalPoints = new wxList;
 
   wxNode *node = m_points->First();
   while (node)
   {
     wxRealPoint *point = (wxRealPoint *)node->Data();
     wxRealPoint *new_point = new wxRealPoint(point->x, point->y);
-    copy.m_points->Append((wxObject*) new_point);
+    polyCopy.m_points->Append((wxObject*) new_point);
     node = node->Next();
   }
   node = m_originalPoints->First();
@@ -853,20 +859,13 @@ void wxPolygonShape::Copy(wxPolygonShape& copy)
   {
     wxRealPoint *point = (wxRealPoint *)node->Data();
     wxRealPoint *new_point = new wxRealPoint(point->x, point->y);
-    copy.m_originalPoints->Append((wxObject*) new_point);
+    polyCopy.m_originalPoints->Append((wxObject*) new_point);
     node = node->Next();
   }
-  copy.m_boundWidth = m_boundWidth;
-  copy.m_boundHeight = m_boundHeight;
-  copy.m_originalWidth = m_originalWidth;
-  copy.m_originalHeight = m_originalHeight;
-}
-
-wxShape *wxPolygonShape::PrivateCopy()
-{
-  wxPolygonShape *obj = new wxPolygonShape;
-  Copy(*obj);
-  return obj;
+  polyCopy.m_boundWidth = m_boundWidth;
+  polyCopy.m_boundHeight = m_boundHeight;
+  polyCopy.m_originalWidth = m_originalWidth;
+  polyCopy.m_originalHeight = m_originalHeight;
 }
 
 int wxPolygonShape::GetNumberOfAttachments()
@@ -883,7 +882,7 @@ int wxPolygonShape::GetNumberOfAttachments()
   return maxN+1;;
 }
 
-bool wxPolygonShape::GetAttachmentPosition(int attachment, float *x, float *y,
+bool wxPolygonShape::GetAttachmentPosition(int attachment, double *x, double *y,
                                          int nth, int no_arcs, wxLineShape *line)
 {
   if (m_attachmentMode && m_points && attachment < m_points->Number())
@@ -920,7 +919,7 @@ bool wxPolygonShape::AttachmentIsValid(int attachment)
 
 IMPLEMENT_DYNAMIC_CLASS(wxRectangleShape, wxShape)
 
-wxRectangleShape::wxRectangleShape(float w, float h)
+wxRectangleShape::wxRectangleShape(double w, double h)
 {
   m_width = w; m_height = h; m_cornerRadius = 0.0;
   SetDefaultRegionSize();
@@ -928,26 +927,26 @@ wxRectangleShape::wxRectangleShape(float w, float h)
 
 void wxRectangleShape::OnDraw(wxDC& dc)
 {
-    float x1 = (float)(m_xpos - m_width/2.0);
-    float y1 = (float)(m_ypos - m_height/2.0);
+    double x1 = (double)(m_xpos - m_width/2.0);
+    double y1 = (double)(m_ypos - m_height/2.0);
 
     if (m_shadowMode != SHADOW_NONE)
     {
       if (m_shadowBrush)
         dc.SetBrush(m_shadowBrush);
-      dc.SetPen(transparent_pen);
+      dc.SetPen(g_oglTransparentPen);
 
       if (m_cornerRadius != 0.0)
-        dc.DrawRoundedRectangle(x1 + m_shadowOffsetX, y1 + m_shadowOffsetY,
-                                 m_width, m_height, m_cornerRadius);
+        dc.DrawRoundedRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY),
+                                 WXROUND(m_width), WXROUND(m_height), m_cornerRadius);
       else
-        dc.DrawRectangle(x1 + m_shadowOffsetX, y1 + m_shadowOffsetY, m_width, m_height);
+        dc.DrawRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY), WXROUND(m_width), WXROUND(m_height));
     }
 
     if (m_pen)
     {
       if (m_pen->GetWidth() == 0)
-        dc.SetPen(transparent_pen);
+        dc.SetPen(g_oglTransparentPen);
       else
         dc.SetPen(m_pen);
     }
@@ -955,38 +954,38 @@ void wxRectangleShape::OnDraw(wxDC& dc)
       dc.SetBrush(m_brush);
 
     if (m_cornerRadius != 0.0)
-      dc.DrawRoundedRectangle(x1, y1, m_width, m_height, m_cornerRadius);
+      dc.DrawRoundedRectangle(WXROUND(x1), WXROUND(y1), WXROUND(m_width), WXROUND(m_height), m_cornerRadius);
     else
-      dc.DrawRectangle(x1, y1, m_width, m_height);
+      dc.DrawRectangle(WXROUND(x1), WXROUND(y1), WXROUND(m_width), WXROUND(m_height));
 }
 
-void wxRectangleShape::GetBoundingBoxMin(float *the_width, float *the_height)
+void wxRectangleShape::GetBoundingBoxMin(double *the_width, double *the_height)
 {
   *the_width = m_width;
   *the_height = m_height;
 }
 
-void wxRectangleShape::SetSize(float x, float y, bool recursive)
+void wxRectangleShape::SetSize(double x, double y, bool recursive)
 {
   SetAttachmentSize(x, y);
-  m_width = (float)wxMax(x, 1.0);
-  m_height = (float)wxMax(y, 1.0);
+  m_width = (double)wxMax(x, 1.0);
+  m_height = (double)wxMax(y, 1.0);
   SetDefaultRegionSize();
 }
 
-void wxRectangleShape::SetCornerRadius(float rad)
+void wxRectangleShape::SetCornerRadius(double rad)
 {
   m_cornerRadius = rad;
 }
 
 // Assume (x1, y1) is centre of box (most generally, line end at box)
-bool wxRectangleShape::GetPerimeterPoint(float x1, float y1,
-                                     float x2, float y2,
-                                     float *x3, float *y3)
+bool wxRectangleShape::GetPerimeterPoint(double x1, double y1,
+                                     double x2, double y2,
+                                     double *x3, double *y3)
 {
-  float bound_x, bound_y;
+  double bound_x, bound_y;
   GetBoundingBoxMax(&bound_x, &bound_y);
-  find_end_for_box(bound_x, bound_y, m_xpos, m_ypos, x2, y2, x3, y3);
+  oglFindEndForBox(bound_x, bound_y, m_xpos, m_ypos, x2, y2, x3, y3);
 
   return TRUE;
 }
@@ -1020,41 +1019,82 @@ void wxRectangleShape::ReadPrologAttributes(wxExpr *clause)
 }
 #endif
 
-void wxRectangleShape::Copy(wxRectangleShape& copy)
+void wxRectangleShape::Copy(wxShape& copy)
 {
   wxShape::Copy(copy);
-  copy.m_width = m_width;
-  copy.m_height = m_height;
-  copy.m_cornerRadius = m_cornerRadius;
-}
 
-wxShape *wxRectangleShape::PrivateCopy()
-{
-  wxRectangleShape *obj = new wxRectangleShape(0.0, 0.0);
-  Copy(*obj);
-  return obj;
-}
+  wxASSERT( copy.IsKindOf(CLASSINFO(wxRectangleShape)) );
 
+  wxRectangleShape& rectCopy = (wxRectangleShape&) copy;
+  rectCopy.m_width = m_width;
+  rectCopy.m_height = m_height;
+  rectCopy.m_cornerRadius = m_cornerRadius;
+}
 
 int wxRectangleShape::GetNumberOfAttachments()
 {
   return wxShape::GetNumberOfAttachments();
 }
 
+
 // There are 4 attachment points on a rectangle - 0 = top, 1 = right, 2 = bottom,
 // 3 = left.
-bool wxRectangleShape::GetAttachmentPosition(int attachment, float *x, float *y,
+bool wxRectangleShape::GetAttachmentPosition(int attachment, double *x, double *y,
                                          int nth, int no_arcs, wxLineShape *line)
 {
   if (m_attachmentMode)
   {
-    float top = (float)(m_ypos + m_height/2.0);
-    float bottom = (float)(m_ypos - m_height/2.0);
-    float left = (float)(m_xpos - m_width/2.0);
-    float right = (float)(m_xpos + m_width/2.0);
+    double top = (double)(m_ypos + m_height/2.0);
+    double bottom = (double)(m_ypos - m_height/2.0);
+    double left = (double)(m_xpos - m_width/2.0);
+    double right = (double)(m_xpos + m_width/2.0);
 
     bool isEnd = (line && line->IsEnd(this));
 
+    // Simplified code
+    switch (attachment)
+    {
+      case 0:
+      {
+        wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, bottom), wxRealPoint(right, bottom),
+            nth, no_arcs, line);
+
+        *x = pt.x; *y = pt.y;
+        break;
+      }
+      case 1:
+      {
+        wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(right, bottom), wxRealPoint(right, top),
+            nth, no_arcs, line);
+
+        *x = pt.x; *y = pt.y;
+        break;
+      }
+      case 2:
+      {
+        wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, top), wxRealPoint(right, top),
+            nth, no_arcs, line);
+
+        *x = pt.x; *y = pt.y;
+        break;
+      }
+      case 3:
+      {
+        wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, bottom), wxRealPoint(left, top),
+            nth, no_arcs, line);
+
+        *x = pt.x; *y = pt.y;
+        break;
+      }
+      default:
+      {
+        return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line);
+        break;
+      }
+    }
+
+    // Old code
+#if 0
     switch (attachment)
     {
       case 0:
@@ -1152,6 +1192,7 @@ bool wxRectangleShape::GetAttachmentPosition(int attachment, float *x, float *y,
         break;
       }
     }
+#endif
     return TRUE;
   }
   else
@@ -1162,7 +1203,7 @@ bool wxRectangleShape::GetAttachmentPosition(int attachment, float *x, float *y,
 
 IMPLEMENT_DYNAMIC_CLASS(wxTextShape, wxRectangleShape)
 
-wxTextShape::wxTextShape(float width, float height):
+wxTextShape::wxTextShape(double width, double height):
   wxRectangleShape(width, height)
 {
 }
@@ -1171,14 +1212,7 @@ void wxTextShape::OnDraw(wxDC& dc)
 {
 }
 
-wxShape *wxTextShape::PrivateCopy()
-{
-  wxTextShape *obj = new wxTextShape(0.0, 0.0);
-  Copy(*obj);
-  return obj;
-}
-
-void wxTextShape::Copy(wxTextShape& copy)
+void wxTextShape::Copy(wxShape& copy)
 {
   wxRectangleShape::Copy(copy);
 }
@@ -1194,26 +1228,26 @@ void wxTextShape::WritePrologAttributes(wxExpr *clause)
 
 IMPLEMENT_DYNAMIC_CLASS(wxEllipseShape, wxShape)
 
-wxEllipseShape::wxEllipseShape(float w, float h)
+wxEllipseShape::wxEllipseShape(double w, double h)
 {
   m_width = w; m_height = h;
   SetDefaultRegionSize();
 }
 
-void wxEllipseShape::GetBoundingBoxMin(float *w, float *h)
+void wxEllipseShape::GetBoundingBoxMin(double *w, double *h)
 {
   *w = m_width; *h = m_height;
 }
 
-bool wxEllipseShape::GetPerimeterPoint(float x1, float y1,
-                                      float x2, float y2,
-                                      float *x3, float *y3)
+bool wxEllipseShape::GetPerimeterPoint(double x1, double y1,
+                                      double x2, double y2,
+                                      double *x3, double *y3)
 {
-  float bound_x, bound_y;
+  double bound_x, bound_y;
   GetBoundingBoxMax(&bound_x, &bound_y);
 
-//  find_end_for_box(bound_x, bound_y, m_xpos, m_ypos, x2, y2, x3, y3);
-  draw_arc_to_ellipse(m_xpos, m_ypos, bound_x, bound_y, x2, y2, x1, y1, x3, y3);
+//  oglFindEndForBox(bound_x, bound_y, m_xpos, m_ypos, x2, y2, x3, y3);
+  oglDrawArcToEllipse(m_xpos, m_ypos, bound_x, bound_y, x2, y2, x1, y1, x3, y3);
 
   return TRUE;
 }
@@ -1224,7 +1258,7 @@ void wxEllipseShape::OnDraw(wxDC& dc)
     {
       if (m_shadowBrush)
         dc.SetBrush(m_shadowBrush);
-      dc.SetPen(transparent_pen);
+      dc.SetPen(g_oglTransparentPen);
       dc.DrawEllipse((m_xpos - GetWidth()/2) + m_shadowOffsetX,
                       (m_ypos - GetHeight()/2) + m_shadowOffsetY,
                       GetWidth(), GetHeight());
@@ -1233,7 +1267,7 @@ void wxEllipseShape::OnDraw(wxDC& dc)
     if (m_pen)
     {
       if (m_pen->GetWidth() == 0)
-        dc.SetPen(transparent_pen);
+        dc.SetPen(g_oglTransparentPen);
       else
         dc.SetPen(m_pen);
     }
@@ -1242,7 +1276,7 @@ void wxEllipseShape::OnDraw(wxDC& dc)
     dc.DrawEllipse((m_xpos - GetWidth()/2), (m_ypos - GetHeight()/2), GetWidth(), GetHeight());
 }
 
-void wxEllipseShape::SetSize(float x, float y, bool recursive)
+void wxEllipseShape::SetSize(double x, double y, bool recursive)
 {
   SetAttachmentSize(x, y);
   m_width = x;
@@ -1276,19 +1310,16 @@ void wxEllipseShape::ReadPrologAttributes(wxExpr *clause)
 }
 #endif
 
-void wxEllipseShape::Copy(wxEllipseShape& copy)
+void wxEllipseShape::Copy(wxShape& copy)
 {
   wxShape::Copy(copy);
 
-  copy.m_width = m_width;
-  copy.m_height = m_height;
-}
+  wxASSERT( copy.IsKindOf(CLASSINFO(wxEllipseShape)) );
 
-wxShape *wxEllipseShape::PrivateCopy()
-{
-  wxEllipseShape *obj = new wxEllipseShape(0.0, 0.0);
-  Copy(*obj);
-  return obj;
+  wxEllipseShape& ellipseCopy = (wxEllipseShape&) copy;
+
+  ellipseCopy.m_width = m_width;
+  ellipseCopy.m_height = m_height;
 }
 
 int wxEllipseShape::GetNumberOfAttachments()
@@ -1298,15 +1329,15 @@ int wxEllipseShape::GetNumberOfAttachments()
 
 // There are 4 attachment points on an ellipse - 0 = top, 1 = right, 2 = bottom,
 // 3 = left.
-bool wxEllipseShape::GetAttachmentPosition(int attachment, float *x, float *y,
+bool wxEllipseShape::GetAttachmentPosition(int attachment, double *x, double *y,
                                          int nth, int no_arcs, wxLineShape *line)
 {
   if (m_attachmentMode)
   {
-    float top = (float)(m_ypos + m_height/2.0);
-    float bottom = (float)(m_ypos - m_height/2.0);
-    float left = (float)(m_xpos - m_width/2.0);
-    float right = (float)(m_xpos + m_width/2.0);
+    double top = (double)(m_ypos + m_height/2.0);
+    double bottom = (double)(m_ypos - m_height/2.0);
+    double left = (double)(m_xpos - m_width/2.0);
+    double right = (double)(m_xpos + m_width/2.0);
     switch (attachment)
     {
       case 0:
@@ -1318,7 +1349,7 @@ bool wxEllipseShape::GetAttachmentPosition(int attachment, float *x, float *y,
         // We now have the point on the bounding box: but get the point on the ellipse
         // by imagining a vertical line from (*x, m_ypos - m_height- 500) to (*x, m_ypos) intersecting
         // the ellipse.
-        draw_arc_to_ellipse(m_xpos, m_ypos, m_width, m_height, *x, (float)(m_ypos-m_height-500), *x, m_ypos, x, y);
+        oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, *x, (double)(m_ypos-m_height-500), *x, m_ypos, x, y);
         break;
       }
       case 1:
@@ -1327,7 +1358,7 @@ bool wxEllipseShape::GetAttachmentPosition(int attachment, float *x, float *y,
         if (m_spaceAttachments)
           *y = bottom + (nth + 1)*m_height/(no_arcs + 1);
         else *y = m_ypos;
-        draw_arc_to_ellipse(m_xpos, m_ypos, m_width, m_height, (float)(m_xpos+m_width+500), *y, m_xpos, *y, x, y);
+        oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, (double)(m_xpos+m_width+500), *y, m_xpos, *y, x, y);
         break;
       }
       case 2:
@@ -1336,7 +1367,7 @@ bool wxEllipseShape::GetAttachmentPosition(int attachment, float *x, float *y,
           *x = left + (nth + 1)*m_width/(no_arcs + 1);
         else *x = m_xpos;
         *y = bottom;
-        draw_arc_to_ellipse(m_xpos, m_ypos, m_width, m_height, *x, (float)(m_ypos+m_height+500), *x, m_ypos, x, y);
+        oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, *x, (double)(m_ypos+m_height+500), *x, m_ypos, x, y);
         break;
       }
       case 3:
@@ -1345,7 +1376,7 @@ bool wxEllipseShape::GetAttachmentPosition(int attachment, float *x, float *y,
         if (m_spaceAttachments)
           *y = bottom + (nth + 1)*m_height/(no_arcs + 1);
         else *y = m_ypos;
-        draw_arc_to_ellipse(m_xpos, m_ypos, m_width, m_height, (float)(m_xpos-m_width-500), *y, m_xpos, *y, x, y);
+        oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, (double)(m_xpos-m_width-500), *y, m_xpos, *y, x, y);
         break;
       }
       default:
@@ -1364,27 +1395,20 @@ bool wxEllipseShape::GetAttachmentPosition(int attachment, float *x, float *y,
 // Circle object
 IMPLEMENT_DYNAMIC_CLASS(wxCircleShape, wxEllipseShape)
 
-wxCircleShape::wxCircleShape(float diameter):wxEllipseShape(diameter, diameter)
-{
-}
-
-wxShape *wxCircleShape::PrivateCopy()
+wxCircleShape::wxCircleShape(double diameter):wxEllipseShape(diameter, diameter)
 {
-  wxCircleShape *obj = new wxCircleShape(0.0);
-  Copy(*obj);
-  return obj;
 }
 
-void wxCircleShape::Copy(wxCircleShape& copy)
+void wxCircleShape::Copy(wxShape& copy)
 {
   wxEllipseShape::Copy(copy);
 }
 
-bool wxCircleShape::GetPerimeterPoint(float x1, float y1,
-                                      float x2, float y2,
-                                      float *x3, float *y3)
+bool wxCircleShape::GetPerimeterPoint(double x1, double y1,
+                                      double x2, double y2,
+                                      double *x3, double *y3)
 {
-  find_end_for_circle(m_width/2, 
+  oglFindEndForCircle(m_width/2, 
                       m_xpos, m_ypos,  // Centre of circle
                       x2, y2,  // Other end of line
                       x3, y3);
@@ -1394,16 +1418,25 @@ bool wxCircleShape::GetPerimeterPoint(float x1, float y1,
 
 // Control points
 
+double wxControlPoint::controlPointDragStartX = 0.0;
+double wxControlPoint::controlPointDragStartY = 0.0;
+double wxControlPoint::controlPointDragStartWidth = 0.0;
+double wxControlPoint::controlPointDragStartHeight = 0.0;
+double wxControlPoint::controlPointDragEndWidth = 0.0;
+double wxControlPoint::controlPointDragEndHeight = 0.0;
+double wxControlPoint::controlPointDragPosX = 0.0;
+double wxControlPoint::controlPointDragPosY = 0.0;
+
 IMPLEMENT_DYNAMIC_CLASS(wxControlPoint, wxRectangleShape)
 
-wxControlPoint::wxControlPoint(wxShapeCanvas *theCanvas, wxShape *object, float size, float the_xoffset, float the_yoffset, int the_type):wxRectangleShape(size, size)
+wxControlPoint::wxControlPoint(wxShapeCanvas *theCanvas, wxShape *object, double size, double the_xoffset, double the_yoffset, int the_type):wxRectangleShape(size, size)
 {
   m_canvas = theCanvas;
   m_shape = object;
   m_xoffset = the_xoffset;
   m_yoffset = the_yoffset;
   m_type = the_type;
-  SetPen(black_foreground_pen);
+  SetPen(g_oglBlackForegroundPen);
   SetBrush(wxBLACK_BRUSH);
   m_oldCursor = NULL;
   m_visible = TRUE;
@@ -1431,25 +1464,41 @@ void wxControlPoint::OnErase(wxDC& dc)
   wxRectangleShape::OnErase(dc);
 }
 
-/*
- * Store original top-left, bottom-right coordinates
- * in case we're doing non-vertical resizing.
- */
-static float controlPointDragStartX = 0.0;
-static float controlPointDragStartY = 0.0;
-static float controlPointDragStartWidth = 0.0;
-static float controlPointDragStartHeight = 0.0;
-static float controlPointDragEndWidth = 0.0;
-static float controlPointDragEndHeight = 0.0;
-static float controlPointDragPosX = 0.0;
-static float controlPointDragPosY = 0.0;
-
 // Implement resizing of canvas object
-void wxControlPoint::OnDragLeft(bool draw, float x, float y, int keys, int attachment)
+void wxControlPoint::OnDragLeft(bool draw, double x, double y, int keys, int attachment)
 {
-  float bound_x;
-  float bound_y;
-  m_shape->GetBoundingBoxMin(&bound_x, &bound_y);
+    m_shape->GetEventHandler()->OnSizingDragLeft(this, draw, x, y, keys, attachment);
+}
+
+void wxControlPoint::OnBeginDragLeft(double x, double y, int keys, int attachment)
+{
+    m_shape->GetEventHandler()->OnSizingBeginDragLeft(this, x, y, keys, attachment);
+}
+
+void wxControlPoint::OnEndDragLeft(double x, double y, int keys, int attachment)
+{
+    m_shape->GetEventHandler()->OnSizingEndDragLeft(this, x, y, keys, attachment);
+}
+
+int wxControlPoint::GetNumberOfAttachments()
+{
+  return 1;
+}
+
+bool wxControlPoint::GetAttachmentPosition(int attachment, double *x, double *y,
+                                         int nth, int no_arcs, wxLineShape *line)
+{
+  *x = m_xpos; *y = m_ypos;
+  return TRUE;
+}
+
+// Control points ('handles') redirect control to the actual shape, to make it easier
+// to override sizing behaviour.
+void wxShape::OnSizingDragLeft(wxControlPoint* pt, bool draw, double x, double y, int keys, int attachment)
+{
+  double bound_x;
+  double bound_y;
+  this->GetBoundingBoxMin(&bound_x, &bound_y);
 
   wxClientDC dc(GetCanvas());
   GetCanvas()->PrepareDC(dc);
@@ -1460,225 +1509,207 @@ void wxControlPoint::OnDragLeft(bool draw, float x, float y, int keys, int attac
   dc.SetPen(dottedPen);
   dc.SetBrush((* wxTRANSPARENT_BRUSH));
 
-  if (m_shape->GetCentreResize())
+  if (this->GetCentreResize())
   {
     // Maintain the same centre point.
-    float new_width = (float)(2.0*fabs(x - m_shape->GetX()));
-    float new_height = (float)(2.0*fabs(y - m_shape->GetY()));
+    double new_width = (double)(2.0*fabs(x - this->GetX()));
+    double new_height = (double)(2.0*fabs(y - this->GetY()));
 
     // Constrain sizing according to what control point you're dragging
-    if (m_type == CONTROL_POINT_HORIZONTAL)
+    if (pt->m_type == CONTROL_POINT_HORIZONTAL)
       new_height = bound_y;
-    else if (m_type == CONTROL_POINT_VERTICAL)
+    else if (pt->m_type == CONTROL_POINT_VERTICAL)
       new_width = bound_x;
-    else if (m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT))
+    else if (pt->m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT))
       new_height = bound_y*(new_width/bound_x);
 
-//    m_shape->OnBeginSize(m_shape->m_fixedWidth ? bound_x : new_width,
-//                               m_shape->m_fixedHeight ? bound_y : new_height);
-
-//    m_shape->SetSize(m_shape->m_fixedWidth ? bound_x : new_width,
-//                           m_shape->m_fixedHeight ? bound_y : new_height);
-    if (m_shape->GetFixedWidth())
+    if (this->GetFixedWidth())
       new_width = bound_x;
       
-    if (m_shape->GetFixedHeight())
+    if (this->GetFixedHeight())
       new_height = bound_y;
 
-    controlPointDragEndWidth = new_width;
-    controlPointDragEndHeight = new_height;
+    pt->controlPointDragEndWidth = new_width;
+    pt->controlPointDragEndHeight = new_height;
 
-    m_shape->GetEventHandler()->OnDrawOutline(dc, m_shape->GetX(), m_shape->GetY(),
+    this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(),
                                 new_width, new_height);
   }
   else
   {
     // Don't maintain the same centre point!
-    float newX1 = wxMin(controlPointDragStartX, x);
-    float newY1 = wxMin(controlPointDragStartY, y);
-    float newX2 = wxMax(controlPointDragStartX, x);
-    float newY2 = wxMax(controlPointDragStartY, y);
-    if (m_type == CONTROL_POINT_HORIZONTAL)
+    double newX1 = wxMin(pt->controlPointDragStartX, x);
+    double newY1 = wxMin(pt->controlPointDragStartY, y);
+    double newX2 = wxMax(pt->controlPointDragStartX, x);
+    double newY2 = wxMax(pt->controlPointDragStartY, y);
+    if (pt->m_type == CONTROL_POINT_HORIZONTAL)
     {
-      newY1 = controlPointDragStartY;
-      newY2 = newY1 + controlPointDragStartHeight;
+      newY1 = pt->controlPointDragStartY;
+      newY2 = newY1 + pt->controlPointDragStartHeight;
     }
-    else if (m_type == CONTROL_POINT_VERTICAL)
+    else if (pt->m_type == CONTROL_POINT_VERTICAL)
     {
-      newX1 = controlPointDragStartX;
-      newX2 = newX1 + controlPointDragStartWidth;
+      newX1 = pt->controlPointDragStartX;
+      newX2 = newX1 + pt->controlPointDragStartWidth;
     }
-    else if (m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT))
+    else if (pt->m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT))
     {
-      float newH = (float)((newX2 - newX1)*(controlPointDragStartHeight/controlPointDragStartWidth));
-      if (GetY() > controlPointDragStartY)
-        newY2 = (float)(newY1 + newH);
+      double newH = (double)((newX2 - newX1)*(pt->controlPointDragStartHeight/pt->controlPointDragStartWidth));
+      if (GetY() > pt->controlPointDragStartY)
+        newY2 = (double)(newY1 + newH);
       else
-        newY1 = (float)(newY2 - newH);
+        newY1 = (double)(newY2 - newH);
     }
-    float newWidth = (float)(newX2 - newX1);
-    float newHeight = (float)(newY2 - newY1);
+    double newWidth = (double)(newX2 - newX1);
+    double newHeight = (double)(newY2 - newY1);
 
-//    m_shape->OnBeginSize(newWidth,
-//                               newHeight);
-    
-//    m_shape->SetSize(newWidth,
-//                           newHeight);
-    controlPointDragPosX = (float)(newX1 + (newWidth/2.0));
-    controlPointDragPosY = (float)(newY1 + (newHeight/2.0));
-    if (m_shape->GetFixedWidth())
+    pt->controlPointDragPosX = (double)(newX1 + (newWidth/2.0));
+    pt->controlPointDragPosY = (double)(newY1 + (newHeight/2.0));
+    if (this->GetFixedWidth())
       newWidth = bound_x;
      
-    if (m_shape->GetFixedHeight())
+    if (this->GetFixedHeight())
       newHeight = bound_y;
 
-    controlPointDragEndWidth = newWidth;
-    controlPointDragEndHeight = newHeight;
-    m_shape->GetEventHandler()->OnDrawOutline(dc, controlPointDragPosX, controlPointDragPosY, newWidth, newHeight);
+    pt->controlPointDragEndWidth = newWidth;
+    pt->controlPointDragEndHeight = newHeight;
+    this->GetEventHandler()->OnDrawOutline(dc, pt->controlPointDragPosX, pt->controlPointDragPosY, newWidth, newHeight);
   }
 }
 
-void wxControlPoint::OnBeginDragLeft(float x, float y, int keys, int attachment)
+void wxShape::OnSizingBeginDragLeft(wxControlPoint* pt, double x, double y, int keys, int attachment)
 {
   m_canvas->CaptureMouse();
 
   wxClientDC dc(GetCanvas());
   GetCanvas()->PrepareDC(dc);
 
-  if (m_eraseObject)
-    m_shape->Erase(dc);
+  if (pt->m_eraseObject)
+    this->Erase(dc);
 
   dc.SetLogicalFunction(wxXOR);
 
-  float bound_x;
-  float bound_y;
-  m_shape->GetBoundingBoxMin(&bound_x, &bound_y);
+  double bound_x;
+  double bound_y;
+  this->GetBoundingBoxMin(&bound_x, &bound_y);
 
   // Choose the 'opposite corner' of the object as the stationary
   // point in case this is non-centring resizing.
-  if (GetX() < m_shape->GetX())
-    controlPointDragStartX = (float)(m_shape->GetX() + (bound_x/2.0));
+  if (pt->GetX() < this->GetX())
+    pt->controlPointDragStartX = (double)(this->GetX() + (bound_x/2.0));
   else
-    controlPointDragStartX = (float)(m_shape->GetX() - (bound_x/2.0));
+    pt->controlPointDragStartX = (double)(this->GetX() - (bound_x/2.0));
 
-  if (GetY() < m_shape->GetY())
-    controlPointDragStartY = (float)(m_shape->GetY() + (bound_y/2.0));
+  if (pt->GetY() < this->GetY())
+    pt->controlPointDragStartY = (double)(this->GetY() + (bound_y/2.0));
   else
-    controlPointDragStartY = (float)(m_shape->GetY() - (bound_y/2.0));
+    pt->controlPointDragStartY = (double)(this->GetY() - (bound_y/2.0));
 
-  if (m_type == CONTROL_POINT_HORIZONTAL)
-    controlPointDragStartY = (float)(m_shape->GetY() - (bound_y/2.0));
-  else if (m_type == CONTROL_POINT_VERTICAL)
-    controlPointDragStartX = (float)(m_shape->GetX() - (bound_x/2.0));
+  if (pt->m_type == CONTROL_POINT_HORIZONTAL)
+    pt->controlPointDragStartY = (double)(this->GetY() - (bound_y/2.0));
+  else if (pt->m_type == CONTROL_POINT_VERTICAL)
+    pt->controlPointDragStartX = (double)(this->GetX() - (bound_x/2.0));
 
   // We may require the old width and height.
-  controlPointDragStartWidth = bound_x;
-  controlPointDragStartHeight = bound_y;
+  pt->controlPointDragStartWidth = bound_x;
+  pt->controlPointDragStartHeight = bound_y;
 
   wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
   dc.SetPen(dottedPen);
   dc.SetBrush((* wxTRANSPARENT_BRUSH));
 
-  if (m_shape->GetCentreResize())
+  if (this->GetCentreResize())
   {
-    float new_width = (float)(2.0*fabs(x - m_shape->GetX()));
-    float new_height = (float)(2.0*fabs(y - m_shape->GetY()));
+    double new_width = (double)(2.0*fabs(x - this->GetX()));
+    double new_height = (double)(2.0*fabs(y - this->GetY()));
 
     // Constrain sizing according to what control point you're dragging
-    if (m_type == CONTROL_POINT_HORIZONTAL)
+    if (pt->m_type == CONTROL_POINT_HORIZONTAL)
       new_height = bound_y;
-    else if (m_type == CONTROL_POINT_VERTICAL)
+    else if (pt->m_type == CONTROL_POINT_VERTICAL)
       new_width = bound_x;
-    else if (m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT))
+    else if (pt->m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT))
       new_height = bound_y*(new_width/bound_x);
 
-    // Non-recursive SetSize for speed
-//    m_shape->SetSize(new_width, new_height, FALSE);
-
-    if (m_shape->GetFixedWidth())
+    if (this->GetFixedWidth())
       new_width = bound_x;
       
-    if (m_shape->GetFixedHeight())
+    if (this->GetFixedHeight())
       new_height = bound_y;
 
-    controlPointDragEndWidth = new_width;
-    controlPointDragEndHeight = new_height;
-    m_shape->GetEventHandler()->OnDrawOutline(dc, m_shape->GetX(), m_shape->GetY(),
+    pt->controlPointDragEndWidth = new_width;
+    pt->controlPointDragEndHeight = new_height;
+    this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(),
                                 new_width, new_height);
   }
   else
   {
     // Don't maintain the same centre point!
-    float newX1 = wxMin(controlPointDragStartX, x);
-    float newY1 = wxMin(controlPointDragStartY, y);
-    float newX2 = wxMax(controlPointDragStartX, x);
-    float newY2 = wxMax(controlPointDragStartY, y);
-    if (m_type == CONTROL_POINT_HORIZONTAL)
+    double newX1 = wxMin(pt->controlPointDragStartX, x);
+    double newY1 = wxMin(pt->controlPointDragStartY, y);
+    double newX2 = wxMax(pt->controlPointDragStartX, x);
+    double newY2 = wxMax(pt->controlPointDragStartY, y);
+    if (pt->m_type == CONTROL_POINT_HORIZONTAL)
     {
-      newY1 = controlPointDragStartY;
-      newY2 = newY1 + controlPointDragStartHeight;
+      newY1 = pt->controlPointDragStartY;
+      newY2 = newY1 + pt->controlPointDragStartHeight;
     }
-    else if (m_type == CONTROL_POINT_VERTICAL)
+    else if (pt->m_type == CONTROL_POINT_VERTICAL)
     {
-      newX1 = controlPointDragStartX;
-      newX2 = newX1 + controlPointDragStartWidth;
+      newX1 = pt->controlPointDragStartX;
+      newX2 = newX1 + pt->controlPointDragStartWidth;
     }
-    else if (m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT))
+    else if (pt->m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT))
     {
-      float newH = (float)((newX2 - newX1)*(controlPointDragStartHeight/controlPointDragStartWidth));
-      if (GetY() > controlPointDragStartY)
-        newY2 = (float)(newY1 + newH);
+      double newH = (double)((newX2 - newX1)*(pt->controlPointDragStartHeight/pt->controlPointDragStartWidth));
+      if (pt->GetY() > pt->controlPointDragStartY)
+        newY2 = (double)(newY1 + newH);
       else
-        newY1 = (float)(newY2 - newH);
+        newY1 = (double)(newY2 - newH);
     }
-    float newWidth = (float)(newX2 - newX1);
-    float newHeight = (float)(newY2 - newY1);
+    double newWidth = (double)(newX2 - newX1);
+    double newHeight = (double)(newY2 - newY1);
 
-//    m_shape->OnBeginSize(newWidth,
-//                               newHeight);
-    
-//    m_shape->SetSize(newWidth,
-//                           newHeight);
-    controlPointDragPosX = (float)(newX1 + (newWidth/2.0));
-    controlPointDragPosY = (float)(newY1 + (newHeight/2.0));
-    if (m_shape->GetFixedWidth())
+    pt->controlPointDragPosX = (double)(newX1 + (newWidth/2.0));
+    pt->controlPointDragPosY = (double)(newY1 + (newHeight/2.0));
+    if (this->GetFixedWidth())
       newWidth = bound_x;
 
-    if (m_shape->GetFixedHeight())
+    if (this->GetFixedHeight())
       newHeight = bound_y;
 
-    controlPointDragEndWidth = newWidth;
-    controlPointDragEndHeight = newHeight;
-    m_shape->GetEventHandler()->OnDrawOutline(dc, controlPointDragPosX, controlPointDragPosY, newWidth, newHeight);
+    pt->controlPointDragEndWidth = newWidth;
+    pt->controlPointDragEndHeight = newHeight;
+    this->GetEventHandler()->OnDrawOutline(dc, pt->controlPointDragPosX, pt->controlPointDragPosY, newWidth, newHeight);
   }
 }
 
-void wxControlPoint::OnEndDragLeft(float x, float y, int keys, int attachment)
+void wxShape::OnSizingEndDragLeft(wxControlPoint* pt, double x, double y, int keys, int attachment)
 {
   wxClientDC dc(GetCanvas());
   GetCanvas()->PrepareDC(dc);
 
   m_canvas->ReleaseMouse();
   dc.SetLogicalFunction(wxCOPY);
-  m_shape->Recompute();
-  m_shape->ResetControlPoints();
+  this->Recompute();
+  this->ResetControlPoints();
 
-  if (!m_eraseObject)
-    m_shape->Show(FALSE);
+  if (!pt->m_eraseObject)
+    this->Show(FALSE);
 
-  m_shape->SetSize(controlPointDragEndWidth, controlPointDragEndHeight);
+  this->SetSize(pt->controlPointDragEndWidth, pt->controlPointDragEndHeight);
 
   // The next operation could destroy this control point (it does for label objects,
   // via formatting the text), so save all values we're going to use, or
   // we'll be accessing garbage.
-  wxShape *theObject = m_shape;
+  wxShape *theObject = this;
   wxShapeCanvas *theCanvas = m_canvas;
-  bool eraseIt = m_eraseObject;
+  bool eraseIt = pt->m_eraseObject;
 
   if (theObject->GetCentreResize())
     theObject->Move(dc, theObject->GetX(), theObject->GetY());
   else
-    theObject->Move(dc, controlPointDragPosX, controlPointDragPosY);
+    theObject->Move(dc, pt->controlPointDragPosX, pt->controlPointDragPosY);
 
   if (!eraseIt)
     theObject->Show(TRUE);
@@ -1687,44 +1718,68 @@ void wxControlPoint::OnEndDragLeft(float x, float y, int keys, int attachment)
   if (theObject->GetChildren().Number() > 0)
     theObject->DrawLinks(dc, -1, TRUE);
     
-  float width, height;
+  double width, height;
   theObject->GetBoundingBoxMax(&width, &height);
   theObject->GetEventHandler()->OnEndSize(width, height);
 
   if (!theCanvas->GetQuickEditMode() && eraseIt) theCanvas->Redraw(dc);
 }
 
-int wxControlPoint::GetNumberOfAttachments()
-{
-  return 1;
-}
-
-bool wxControlPoint::GetAttachmentPosition(int attachment, float *x, float *y,
-                                         int nth, int no_arcs, wxLineShape *line)
-{
-  *x = m_xpos; *y = m_ypos;
-  return TRUE;
-}
 
 
 // Polygon control points
 
 IMPLEMENT_DYNAMIC_CLASS(wxPolygonControlPoint, wxControlPoint)
 
-wxPolygonControlPoint::wxPolygonControlPoint(wxShapeCanvas *theCanvas, wxShape *object, float size,
-  wxRealPoint *vertex, float the_xoffset, float the_yoffset):
+wxPolygonControlPoint::wxPolygonControlPoint(wxShapeCanvas *theCanvas, wxShape *object, double size,
+  wxRealPoint *vertex, double the_xoffset, double the_yoffset):
   wxControlPoint(theCanvas, object, size, the_xoffset, the_yoffset, 0)
 {
   m_polygonVertex = vertex;
+  m_originalDistance = 0.0;
 }
 
 wxPolygonControlPoint::~wxPolygonControlPoint()
 {
 }
 
+// Calculate what new size would be, at end of resize
+void wxPolygonControlPoint::CalculateNewSize(double x, double y)
+{
+  double bound_x;
+  double bound_y;
+  GetShape()->GetBoundingBoxMin(&bound_x, &bound_y);
+
+  double dist = (double)sqrt((x - m_shape->GetX())*(x - m_shape->GetX()) +
+                    (y - m_shape->GetY())*(y - m_shape->GetY()));
+
+  m_newSize.x = (double)(dist/this->m_originalDistance)*this->m_originalSize.x;
+  m_newSize.y = (double)(dist/this->m_originalDistance)*this->m_originalSize.y;
+}
+
+
 // Implement resizing polygon or moving the vertex.
-void wxPolygonControlPoint::OnDragLeft(bool draw, float x, float y, int keys, int attachment)
+void wxPolygonControlPoint::OnDragLeft(bool draw, double x, double y, int keys, int attachment)
+{
+    m_shape->GetEventHandler()->OnSizingDragLeft(this, draw, x, y, keys, attachment);
+}
+
+void wxPolygonControlPoint::OnBeginDragLeft(double x, double y, int keys, int attachment)
 {
+    m_shape->GetEventHandler()->OnSizingBeginDragLeft(this, x, y, keys, attachment);
+}
+
+void wxPolygonControlPoint::OnEndDragLeft(double x, double y, int keys, int attachment)
+{
+    m_shape->GetEventHandler()->OnSizingEndDragLeft(this, x, y, keys, attachment);
+}
+
+// Control points ('handles') redirect control to the actual shape, to make it easier
+// to override sizing behaviour.
+void wxPolygonShape::OnSizingDragLeft(wxControlPoint* pt, bool draw, double x, double y, int keys, int attachment)
+{
+  wxPolygonControlPoint* ppt = (wxPolygonControlPoint*) pt;
+
   wxClientDC dc(GetCanvas());
   GetCanvas()->PrepareDC(dc);
 
@@ -1734,97 +1789,87 @@ void wxPolygonControlPoint::OnDragLeft(bool draw, float x, float y, int keys, in
   dc.SetPen(dottedPen);
   dc.SetBrush((* wxTRANSPARENT_BRUSH));
 
-  float bound_x;
-  float bound_y;
-  m_shape->GetBoundingBoxMin(&bound_x, &bound_y);
-/*
-  float new_width = (float)(2.0*fabs(x - m_shape->GetX()));
-  float new_height = (float)(2.0*fabs(y - m_shape->GetY()));
-*/
-  float dist = (float)sqrt((x - m_shape->GetX())*(x - m_shape->GetX()) +
-                    (y - m_shape->GetY())*(y - m_shape->GetY()));
-
-  if (keys & KEY_CTRL)
+  if (0) // keys & KEY_CTRL)
   {
+    // TODO: mend this code. Currently we rely on altering the
+    // actual points, but we should assume we're not, as per
+    // the normal sizing case.
     m_canvas->Snap(&x, &y);
 
     // Move point
-    m_polygonVertex->x = x - m_shape->GetX();
-    m_polygonVertex->y = y - m_shape->GetY();
-    m_xpos = x;
-    m_xpos = y;
-    ((wxPolygonShape *)m_shape)->CalculateBoundingBox();
-    ((wxPolygonShape *)m_shape)->CalculatePolygonCentre();
+    ppt->m_polygonVertex->x = x - this->GetX();
+    ppt->m_polygonVertex->y = y - this->GetY();
+    ppt->SetX(x);
+    ppt->SetY(y);
+    ((wxPolygonShape *)this)->CalculateBoundingBox();
+    ((wxPolygonShape *)this)->CalculatePolygonCentre();
   }
   else
   {
-    float new_width = (float)(dist/m_originalDistance)*m_originalSize.x;
-    float new_height = (float)(dist/m_originalDistance)*m_originalSize.y;
-
-    // Non-recursive SetSize for speed
-    m_shape->SetSize(new_width, new_height, FALSE);
+    ppt->CalculateNewSize(x, y);
   }
-  float w, h;
-  m_shape->GetBoundingBoxMax(&w, &h);
-  m_shape->GetEventHandler()->OnDrawOutline(dc, m_shape->GetX(), m_shape->GetY(), w, h);
+
+  this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(),
+       ppt->GetNewSize().x, ppt->GetNewSize().y);
 }
 
-void wxPolygonControlPoint::OnBeginDragLeft(float x, float y, int keys, int attachment)
+void wxPolygonShape::OnSizingBeginDragLeft(wxControlPoint* pt, double x, double y, int keys, int attachment)
 {
+  wxPolygonControlPoint* ppt = (wxPolygonControlPoint*) pt;
+
   wxClientDC dc(GetCanvas());
   GetCanvas()->PrepareDC(dc);
 
-  m_shape->Erase(dc);
+  this->Erase(dc);
 
   dc.SetLogicalFunction(wxXOR);
 
-  float bound_x;
-  float bound_y;
-  m_shape->GetBoundingBoxMin(&bound_x, &bound_y);
-
-  float dist = (float)sqrt((x - m_shape->GetX())*(x - m_shape->GetX()) +
-                    (y - m_shape->GetY())*(y - m_shape->GetY()));
+  double bound_x;
+  double bound_y;
+  this->GetBoundingBoxMin(&bound_x, &bound_y);
 
-  m_originalDistance = dist;
-  m_originalSize.x = bound_x;
-  m_originalSize.y = bound_y;
+  double dist = (double)sqrt((x - this->GetX())*(x - this->GetX()) +
+                    (y - this->GetY())*(y - this->GetY()));
+  ppt->m_originalDistance = dist;
+  ppt->m_originalSize.x = bound_x;
+  ppt->m_originalSize.y = bound_y;
 
-  if (m_originalDistance == 0.0) m_originalDistance = (float) 0.0001;
+  if (ppt->m_originalDistance == 0.0) ppt->m_originalDistance = (double) 0.0001;
 
   wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
   dc.SetPen(dottedPen);
   dc.SetBrush((* wxTRANSPARENT_BRUSH));
 
-  if (keys & KEY_CTRL)
+  if (0) // keys & KEY_CTRL)
   {
+    // TODO: mend this code. Currently we rely on altering the
+    // actual points, but we should assume we're not, as per
+    // the normal sizing case.
     m_canvas->Snap(&x, &y);
 
     // Move point
-    m_polygonVertex->x = x - m_shape->GetX();
-    m_polygonVertex->y = y - m_shape->GetY();
-    m_xpos = x;
-    m_xpos = y;
-    ((wxPolygonShape *)m_shape)->CalculateBoundingBox();
-    ((wxPolygonShape *)m_shape)->CalculatePolygonCentre();
+    ppt->m_polygonVertex->x = x - this->GetX();
+    ppt->m_polygonVertex->y = y - this->GetY();
+    ppt->SetX(x);
+    ppt->SetY(y);
+    ((wxPolygonShape *)this)->CalculateBoundingBox();
+    ((wxPolygonShape *)this)->CalculatePolygonCentre();
   }
   else
   {
-    float new_width = (float)(dist/m_originalDistance)*m_originalSize.x;
-    float new_height = (float)(dist/m_originalDistance)*m_originalSize.y;
-
-    // Non-recursive SetSize for speed
-    m_shape->SetSize(new_width, new_height, FALSE);
+    ppt->CalculateNewSize(x, y);
   }
 
-  float w, h;
-  m_shape->GetBoundingBoxMax(&w, &h);
-  m_shape->GetEventHandler()->OnDrawOutline(dc, m_shape->GetX(), m_shape->GetY(), w, h);
+  this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(),
+       ppt->GetNewSize().x, ppt->GetNewSize().y);
 
   m_canvas->CaptureMouse();
 }
 
-void wxPolygonControlPoint::OnEndDragLeft(float x, float y, int keys, int attachment)
+void wxPolygonShape::OnSizingEndDragLeft(wxControlPoint* pt, double x, double y, int keys, int attachment)
 {
+  wxPolygonControlPoint* ppt = (wxPolygonControlPoint*) pt;
+
   wxClientDC dc(GetCanvas());
   GetCanvas()->PrepareDC(dc);
 
@@ -1834,20 +1879,23 @@ void wxPolygonControlPoint::OnEndDragLeft(float x, float y, int keys, int attach
   // If we're changing shape, must reset the original points
   if (keys & KEY_CTRL)
   {
-    ((wxPolygonShape *)m_shape)->CalculateBoundingBox();
-    ((wxPolygonShape *)m_shape)->UpdateOriginalPoints();
+    ((wxPolygonShape *)this)->CalculateBoundingBox();
+    ((wxPolygonShape *)this)->UpdateOriginalPoints();
+  }
+  else
+  {
+    SetSize(ppt->GetNewSize().x, ppt->GetNewSize().y);
   }
 
-  ((wxPolygonShape *)m_shape)->CalculateBoundingBox();
-  ((wxPolygonShape *)m_shape)->CalculatePolygonCentre();
+  ((wxPolygonShape *)this)->CalculateBoundingBox();
+  ((wxPolygonShape *)this)->CalculatePolygonCentre();
 
-  m_shape->Recompute();
-  m_shape->ResetControlPoints();
-  m_shape->Move(dc, m_shape->GetX(), m_shape->GetY());
+  this->Recompute();
+  this->ResetControlPoints();
+  this->Move(dc, this->GetX(), this->GetY());
   if (!m_canvas->GetQuickEditMode()) m_canvas->Redraw(dc);
 }
 
-
 /*
  * Object region
  *
@@ -1933,25 +1981,25 @@ void wxShapeRegion::SetFont(wxFont *f)
   m_font = f;
 }
 
-void wxShapeRegion::SetMinSize(float w, float h)
+void wxShapeRegion::SetMinSize(double w, double h)
 {
   m_minWidth = w;
   m_minHeight = h;
 }
 
-void wxShapeRegion::SetSize(float w, float h)
+void wxShapeRegion::SetSize(double w, double h)
 {
   m_width = w;
   m_height = h;
 }
 
-void wxShapeRegion::SetPosition(float xp, float yp)
+void wxShapeRegion::SetPosition(double xp, double yp)
 {
   m_x = xp;
   m_y = yp;
 }
 
-void wxShapeRegion::SetProportions(float xp, float yp)
+void wxShapeRegion::SetProportions(double xp, double yp)
 {
   m_regionProportionX = xp;
   m_regionProportionY = yp;