]> git.saurik.com Git - wxWidgets.git/blobdiff - src/ogl/basic2.cpp
Removed OGL prior to re-adding; some Watcom corrections
[wxWidgets.git] / src / ogl / basic2.cpp
diff --git a/src/ogl/basic2.cpp b/src/ogl/basic2.cpp
deleted file mode 100644 (file)
index 7a65d70..0000000
+++ /dev/null
@@ -1,1902 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        basic2.cpp
-// Purpose:     Basic OGL classes (2)
-// Author:      Julian Smart
-// Modified by:
-// Created:     12/07/98
-// RCS-ID:      $Id$
-// Copyright:   (c) Julian Smart
-// Licence:    wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
-
-#ifdef __GNUG__
-#pragma implementation "basicp.h"
-#endif
-
-// For compilers that support precompilation, includes "wx.h".
-#include <wx/wxprec.h>
-
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
-#ifndef WX_PRECOMP
-#include <wx/wx.h>
-#endif
-
-#include <wx/wxexpr.h>
-
-#if wxUSE_IOSTREAMH
-#include <iostream.h>
-#else
-#include <iostream>
-#endif
-
-#include <stdio.h>
-#include <ctype.h>
-#include <math.h>
-
-#include <wx/ogl/basic.h>
-#include <wx/ogl/basicp.h>
-#include <wx/ogl/composit.h>
-#include <wx/ogl/lines.h>
-#include <wx/ogl/canvas.h>
-#include <wx/ogl/divided.h>
-#include <wx/ogl/misc.h>
-
-// Control point types
-// Rectangle and most other shapes
-#define CONTROL_POINT_VERTICAL   1
-#define CONTROL_POINT_HORIZONTAL 2
-#define CONTROL_POINT_DIAGONAL   3
-
-// Line
-#define CONTROL_POINT_ENDPOINT_TO 4
-#define CONTROL_POINT_ENDPOINT_FROM 5
-#define CONTROL_POINT_LINE       6
-
-// Two stage construction: need to call Create
-IMPLEMENT_DYNAMIC_CLASS(wxPolygonShape, wxShape)
-
-wxPolygonShape::wxPolygonShape()
-{
-  m_points = NULL;
-  m_originalPoints = NULL;
-}
-
-void wxPolygonShape::Create(wxList *the_points)
-{
-  ClearPoints();
-
-  m_originalPoints = the_points;
-
-  // Duplicate the list of points
-  m_points = new wxList;
-
-  wxNode *node = the_points->First();
-  while (node)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    wxRealPoint *new_point = new wxRealPoint(point->x, point->y);
-    m_points->Append((wxObject*) new_point);
-    node = node->Next();
-  }
-  CalculateBoundingBox();
-  m_originalWidth = m_boundWidth;
-  m_originalHeight = m_boundHeight;
-  SetDefaultRegionSize();
-}
-
-wxPolygonShape::~wxPolygonShape()
-{
-    ClearPoints();
-}
-
-void wxPolygonShape::ClearPoints()
-{
-  if (m_points)
-  {
-    wxNode *node = m_points->First();
-    while (node)
-    {
-      wxRealPoint *point = (wxRealPoint *)node->Data();
-      delete point;
-      delete node;
-      node = m_points->First();
-    }
-    delete m_points;
-    m_points = NULL;
-  }
-  if (m_originalPoints)
-  {
-    wxNode *node = m_originalPoints->First();
-    while (node)
-    {
-      wxRealPoint *point = (wxRealPoint *)node->Data();
-      delete point;
-      delete node;
-      node = m_originalPoints->First();
-    }
-    delete m_originalPoints;
-    m_originalPoints = NULL;
-  }
-}
-
-
-// Width and height. Centre of object is centre of box.
-void wxPolygonShape::GetBoundingBoxMin(double *width, double *height)
-{
-  *width = m_boundWidth;
-  *height = m_boundHeight;
-}
-
-void wxPolygonShape::CalculateBoundingBox()
-{
-  // Calculate bounding box at construction (and presumably resize) time
-  double left = 10000;
-  double right = -10000;
-  double top = 10000;
-  double bottom = -10000;
-
-  wxNode *node = m_points->First();
-  while (node)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    if (point->x < left) left = point->x;
-    if (point->x > right) right = point->x;
-
-    if (point->y < top) top = point->y;
-    if (point->y > bottom) bottom = point->y;
-
-    node = node->Next();
-  }
-  m_boundWidth = right - left;
-  m_boundHeight = bottom - top;
-}
-
-// Recalculates the centre of the polygon, and
-// readjusts the point offsets accordingly.
-// Necessary since the centre of the polygon
-// is expected to be the real centre of the bounding
-// box.
-void wxPolygonShape::CalculatePolygonCentre()
-{
-  double left = 10000;
-  double right = -10000;
-  double top = 10000;
-  double bottom = -10000;
-
-  wxNode *node = m_points->First();
-  while (node)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    if (point->x < left) left = point->x;
-    if (point->x > right) right = point->x;
-
-    if (point->y < top) top = point->y;
-    if (point->y > bottom) bottom = point->y;
-
-    node = node->Next();
-  }
-  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)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    point->x -= newCentreX;
-    point->y -= newCentreY;
-    node = node->Next();
-  }
-  m_xpos += newCentreX;
-  m_ypos += newCentreY;
-}
-
-bool PolylineHitTest(double n, double xvec[], double yvec[],
-                           double x1, double y1, double x2, double y2)
-{
-  bool isAHit = FALSE;
-  int i;
-  double lastx = xvec[0];
-  double lasty = yvec[0];
-
-  double min_ratio = 1.0;
-  double line_ratio;
-  double other_ratio;
-
-//  char buf[300];
-  for (i = 1; i < n; i++)
-  {
-    oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[i], yvec[i],
-                            &line_ratio, &other_ratio);
-    if (line_ratio != 1.0)
-      isAHit = TRUE;
-//    sprintf(buf, "Line ratio = %.2f, other ratio = %.2f\n", line_ratio, other_ratio);
-//    ClipsErrorFunction(buf);
-    lastx = xvec[i];
-    lasty = yvec[i];
-
-    if (line_ratio < min_ratio)
-      min_ratio = line_ratio;
-  }
-
-  // Do last (implicit) line if last and first doubles are not identical
-  if (!(xvec[0] == lastx && yvec[0] == lasty))
-  {
-    oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[0], yvec[0],
-                            &line_ratio, &other_ratio);
-    if (line_ratio != 1.0)
-      isAHit = TRUE;
-//    sprintf(buf, "Line ratio = %.2f, other ratio = %.2f\n", line_ratio, other_ratio);
-//    ClipsErrorFunction(buf);
-
-    if (line_ratio < min_ratio)
-      min_ratio = line_ratio;
-  }
-//  ClipsErrorFunction("\n");
-  return isAHit;
-}
-
-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.
-  double endPointsX[4];
-  double endPointsY[4];
-  // North
-  endPointsX[0] = x;
-  endPointsY[0] = (double)(y - 1000.0);
-  // East
-  endPointsX[1] = (double)(x + 1000.0);
-  endPointsY[1] = y;
-  // South
-  endPointsX[2] = x;
-  endPointsY[2] = (double)(y + 1000.0);
-  // West
-  endPointsX[3] = (double)(x - 1000.0);
-  endPointsY[3] = y;
-
-  // Store polygon points in an array
-  int np = m_points->Number();
-  double *xpoints = new double[np];
-  double *ypoints = new double[np];
-  wxNode *node = m_points->First();
-  int i = 0;
-  while (node)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    xpoints[i] = point->x + m_xpos;
-    ypoints[i] = point->y + m_ypos;
-    node = node->Next();
-    i ++;
-  }
-
-  // We assume it's inside the polygon UNLESS one or more
-  // lines don't hit the outline.
-  bool isContained = TRUE;
-
-  int noPoints = 4;
-  for (i = 0; i < noPoints; i++)
-  {
-    if (!PolylineHitTest(np, xpoints, ypoints, x, y, endPointsX[i], endPointsY[i]))
-      isContained = FALSE;
-  }
-/*
-  if (isContained)
-    ClipsErrorFunction("It's a hit!\n");
-  else
-    ClipsErrorFunction("No hit.\n");
-*/
-  delete[] xpoints;
-  delete[] ypoints;
-
-  if (!isContained)
-    return FALSE;
-
-  int nearest_attachment = 0;
-
-  // If a hit, check the attachment points within the object.
-  int n = GetNumberOfAttachments();
-  double nearest = 999999.0;
-
-  for (i = 0; i < n; i++)
-  {
-    double xp, yp;
-    if (GetAttachmentPositionEdge(i, &xp, &yp))
-    {
-      double l = (double)sqrt(((xp - x) * (xp - x)) +
-                 ((yp - y) * (yp - y)));
-      if (l < nearest)
-      {
-        nearest = l;
-        nearest_attachment = i;
-      }
-    }
-  }
-  *attachment = nearest_attachment;
-  *distance = nearest;
-  return TRUE;
-}
-
-// 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(double new_width, double new_height, bool recursive)
-{
-  SetAttachmentSize(new_width, new_height);
-
-  // Multiply all points by proportion of new size to old size
-  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();
-  while (node && original_node)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    wxRealPoint *original_point = (wxRealPoint *)original_node->Data();
-
-    point->x = (original_point->x * x_proportion);
-    point->y = (original_point->y * y_proportion);
-
-    node = node->Next();
-    original_node = original_node->Next();
-  }
-
-//  CalculateBoundingBox();
-  m_boundWidth = (double)fabs(new_width);
-  m_boundHeight = (double)fabs(new_height);
-  SetDefaultRegionSize();
-}
-
-// Make the original points the same as the working points
-void wxPolygonShape::UpdateOriginalPoints()
-{
-  if (!m_originalPoints) m_originalPoints = new wxList;
-  wxNode *original_node = m_originalPoints->First();
-  while (original_node)
-  {
-    wxNode *next_node = original_node->Next();
-    wxRealPoint *original_point = (wxRealPoint *)original_node->Data();
-    delete original_point;
-    delete original_node;
-
-    original_node = next_node;
-  }
-
-  wxNode *node = m_points->First();
-  while (node)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    wxRealPoint *original_point = new wxRealPoint(point->x, point->y);
-    m_originalPoints->Append((wxObject*) original_point);
-
-    node = node->Next();
-  }
-  CalculateBoundingBox();
-  m_originalWidth = m_boundWidth;
-  m_originalHeight = m_boundHeight;
-}
-
-void wxPolygonShape::AddPolygonPoint(int pos)
-{
-  wxNode *node = m_points->Nth(pos);
-  if (!node) node = m_points->First();
-  wxRealPoint *firstPoint = (wxRealPoint *)node->Data();
-
-  wxNode *node2 = m_points->Nth(pos + 1);
-  if (!node2) node2 = m_points->First();
-  wxRealPoint *secondPoint = (wxRealPoint *)node2->Data();
-
-  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))
-    m_points->Append((wxObject*) point);
-  else
-    m_points->Insert(node2, (wxObject*) point);
-
-  UpdateOriginalPoints();
-
-  if (m_selected)
-  {
-    DeleteControlPoints();
-    MakeControlPoints();
-  }
-}
-
-void wxPolygonShape::DeletePolygonPoint(int pos)
-{
-  wxNode *node = m_points->Nth(pos);
-  if (node)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    delete point;
-    delete node;
-    UpdateOriginalPoints();
-    if (m_selected)
-    {
-      DeleteControlPoints();
-      MakeControlPoints();
-    }
-  }
-}
-
-// Assume (x1, y1) is centre of box (most generally, line end at box)
-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 --
-  // oglFindEndForPolyline can't cope with this (the arrow
-  // gets drawn to the wrong place).
-  if ((m_attachmentMode == ATTACHMENT_MODE_NONE) && (x1 == x2))
-  {
-    // Look for the point we'd be connecting to. This is
-    // a heuristic...
-    wxNode *node = m_points->First();
-    while (node)
-    {
-      wxRealPoint *point = (wxRealPoint *)node->Data();
-      if (point->x == 0.0)
-      {
-        if ((y2 > y1) && (point->y > 0.0))
-        {
-          *x3 = point->x + m_xpos;
-          *y3 = point->y + m_ypos;
-          return TRUE;
-        }
-        else if ((y2 < y1) && (point->y < 0.0))
-        {
-          *x3 = point->x + m_xpos;
-          *y3 = point->y + m_ypos;
-          return TRUE;
-        }
-      }
-      node = node->Next();
-    }
-  }
-
-  double *xpoints = new double[n];
-  double *ypoints = new double[n];
-
-  wxNode *node = m_points->First();
-  int i = 0;
-  while (node)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    xpoints[i] = point->x + m_xpos;
-    ypoints[i] = point->y + m_ypos;
-    node = node->Next();
-    i ++;
-  }
-
-  oglFindEndForPolyline(n, xpoints, ypoints,
-                        x1, y1, x2, y2, x3, y3);
-
-  delete[] xpoints;
-  delete[] ypoints;
-
-  return TRUE;
-}
-
-void wxPolygonShape::OnDraw(wxDC& dc)
-{
-    int n = m_points->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 = WXROUND(point->x);
-      intPoints[i].y = WXROUND(point->y);
-    }
-
-    if (m_shadowMode != SHADOW_NONE)
-    {
-      if (m_shadowBrush)
-        dc.SetBrush(* m_shadowBrush);
-      dc.SetPen(* g_oglTransparentPen);
-
-      dc.DrawPolygon(n, intPoints, WXROUND(m_xpos + m_shadowOffsetX), WXROUND(m_ypos + m_shadowOffsetY));
-    }
-
-    if (m_pen)
-    {
-      if (m_pen->GetWidth() == 0)
-        dc.SetPen(* g_oglTransparentPen);
-      else
-        dc.SetPen(* m_pen);
-    }
-    if (m_brush)
-      dc.SetBrush(* m_brush);
-    dc.DrawPolygon(n, intPoints, WXROUND(m_xpos), WXROUND(m_ypos));
-
-    delete[] intPoints;
-}
-
-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_originalPoints->Number();
-  wxPoint *intPoints = new wxPoint[n];
-  int i;
-  for (i = 0; i < n; i++)
-  {
-    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, WXROUND(x), WXROUND(y));
-  delete[] intPoints;
-}
-
-// Make as many control points as there are vertices.
-void wxPolygonShape::MakeControlPoints()
-{
-  wxNode *node = m_points->First();
-  while (node)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    wxPolygonControlPoint *control = new wxPolygonControlPoint(m_canvas, this, CONTROL_POINT_SIZE,
-      point, point->x, point->y);
-    m_canvas->AddShape(control);
-    m_controlPoints.Append(control);
-    node = node->Next();
-  }
-}
-
-void wxPolygonShape::ResetControlPoints()
-{
-  wxNode *node = m_points->First();
-  wxNode *controlPointNode = m_controlPoints.First();
-  while (node && controlPointNode)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    wxPolygonControlPoint *controlPoint = (wxPolygonControlPoint *)controlPointNode->Data();
-
-    controlPoint->m_xoffset = point->x;
-    controlPoint->m_yoffset = point->y;
-    controlPoint->m_polygonVertex = point;
-
-    node = node->Next();
-    controlPointNode = controlPointNode->Next();
-  }
-}
-
-
-#ifdef PROLOGIO
-void wxPolygonShape::WriteAttributes(wxExpr *clause)
-{
-  wxShape::WriteAttributes(clause);
-
-  clause->AddAttributeValue("x", m_xpos);
-  clause->AddAttributeValue("y", m_ypos);
-
-  // Make a list of lists for the coordinates
-  wxExpr *list = new wxExpr(wxExprList);
-  wxNode *node = m_points->First();
-  while (node)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    wxExpr *point_list = new wxExpr(wxExprList);
-    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);
-
-    node = node->Next();
-  }
-  clause->AddAttributeValue("points", list);
-
-  // Save the original (unscaled) points
-  list = new wxExpr(wxExprList);
-  node = m_originalPoints->First();
-  while (node)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    wxExpr *point_list = new wxExpr(wxExprList);
-    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);
-
-    node = node->Next();
-  }
-  clause->AddAttributeValue("m_originalPoints", list);
-}
-
-void wxPolygonShape::ReadAttributes(wxExpr *clause)
-{
-  wxShape::ReadAttributes(clause);
-
-  // Read a list of lists
-  m_points = new wxList;
-  m_originalPoints = new wxList;
-
-  wxExpr *points_list = NULL;
-  clause->AssignAttributeValue("points", &points_list);
-
-  // If no points_list, don't crash!! Assume a diamond instead.
-  double the_height = 100.0;
-  double the_width = 100.0;
-  if (!points_list)
-  {
-    wxRealPoint *point = new wxRealPoint(0.0, (-the_height/2));
-    m_points->Append((wxObject*) point);
-
-    point = new wxRealPoint((the_width/2), 0.0);
-    m_points->Append((wxObject*) point);
-
-    point = new wxRealPoint(0.0, (the_height/2));
-    m_points->Append((wxObject*) point);
-
-    point = new wxRealPoint((-the_width/2), 0.0);
-    m_points->Append((wxObject*) point);
-
-    point = new wxRealPoint(0.0, (-the_height/2));
-    m_points->Append((wxObject*) point);
-  }
-  else
-  {
-    wxExpr *node = points_list->value.first;
-
-    while (node)
-    {
-      wxExpr *xexpr = node->value.first;
-      long x = xexpr->IntegerValue();
-
-      wxExpr *yexpr = xexpr->next;
-      long y = yexpr->IntegerValue();
-
-      wxRealPoint *point = new wxRealPoint((double)x, (double)y);
-      m_points->Append((wxObject*) point);
-
-      node = node->next;
-    }
-  }
-
-  points_list = NULL;
-  clause->AssignAttributeValue("m_originalPoints", &points_list);
-
-  // If no points_list, don't crash!! Assume a diamond instead.
-  if (!points_list)
-  {
-    wxRealPoint *point = new wxRealPoint(0.0, (-the_height/2));
-    m_originalPoints->Append((wxObject*) point);
-
-    point = new wxRealPoint((the_width/2), 0.0);
-    m_originalPoints->Append((wxObject*) point);
-
-    point = new wxRealPoint(0.0, (the_height/2));
-    m_originalPoints->Append((wxObject*) point);
-
-    point = new wxRealPoint((-the_width/2), 0.0);
-    m_originalPoints->Append((wxObject*) point);
-
-    point = new wxRealPoint(0.0, (-the_height/2));
-    m_originalPoints->Append((wxObject*) point);
-
-    m_originalWidth = the_width;
-    m_originalHeight = the_height;
-  }
-  else
-  {
-    wxExpr *node = points_list->value.first;
-    double min_x = 1000;
-    double min_y = 1000;
-    double max_x = -1000;
-    double max_y = -1000;
-    while (node)
-    {
-      wxExpr *xexpr = node->value.first;
-      long x = xexpr->IntegerValue();
-
-      wxExpr *yexpr = xexpr->next;
-      long y = yexpr->IntegerValue();
-
-      wxRealPoint *point = new wxRealPoint((double)x, (double)y);
-      m_originalPoints->Append((wxObject*) point);
-
-      if (x < min_x)
-        min_x = (double)x;
-      if (y < min_y)
-        min_y = (double)y;
-      if (x > max_x)
-        max_x = (double)x;
-      if (y > max_y)
-        max_y = (double)y;
-
-      node = node->next;
-    }
-    m_originalWidth = max_x - min_x;
-    m_originalHeight = max_y - min_y;
-  }
-
-  CalculateBoundingBox();
-}
-#endif
-
-void wxPolygonShape::Copy(wxShape& copy)
-{
-  wxShape::Copy(copy);
-
-  wxASSERT( copy.IsKindOf(CLASSINFO(wxPolygonShape)) );
-
-  wxPolygonShape& polyCopy = (wxPolygonShape&) copy;
-
-  polyCopy.ClearPoints();
-
-  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);
-    polyCopy.m_points->Append((wxObject*) new_point);
-    node = node->Next();
-  }
-  node = m_originalPoints->First();
-  while (node)
-  {
-    wxRealPoint *point = (wxRealPoint *)node->Data();
-    wxRealPoint *new_point = new wxRealPoint(point->x, point->y);
-    polyCopy.m_originalPoints->Append((wxObject*) new_point);
-    node = node->Next();
-  }
-  polyCopy.m_boundWidth = m_boundWidth;
-  polyCopy.m_boundHeight = m_boundHeight;
-  polyCopy.m_originalWidth = m_originalWidth;
-  polyCopy.m_originalHeight = m_originalHeight;
-}
-
-int wxPolygonShape::GetNumberOfAttachments() const
-{
-  int maxN = (m_points ? (m_points->Number() - 1) : 0);
-  wxNode *node = m_attachmentPoints.First();
-  while (node)
-  {
-    wxAttachmentPoint *point = (wxAttachmentPoint *)node->Data();
-    if (point->m_id > maxN)
-      maxN = point->m_id;
-    node = node->Next();
-  }
-  return maxN+1;;
-}
-
-bool wxPolygonShape::GetAttachmentPosition(int attachment, double *x, double *y,
-                                         int nth, int no_arcs, wxLineShape *line)
-{
-  if ((m_attachmentMode == ATTACHMENT_MODE_EDGE) && m_points && attachment < m_points->Number())
-  {
-    wxRealPoint *point = (wxRealPoint *)m_points->Nth(attachment)->Data();
-    *x = point->x + m_xpos;
-    *y = point->y + m_ypos;
-    return TRUE;
-  }
-  else
-  { return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line); }
-}
-
-bool wxPolygonShape::AttachmentIsValid(int attachment)
-{
-  if (!m_points)
-    return FALSE;
-
-  if ((attachment >= 0) && (attachment < m_points->Number()))
-    return TRUE;
-
-  wxNode *node = m_attachmentPoints.First();
-  while (node)
-  {
-    wxAttachmentPoint *point = (wxAttachmentPoint *)node->Data();
-    if (point->m_id == attachment)
-      return TRUE;
-    node = node->Next();
-  }
-  return FALSE;
-}
-
-// Rotate about the given axis by the given amount in radians
-void wxPolygonShape::Rotate(double x, double y, double theta)
-{
-    double actualTheta = theta-m_rotation;
-
-    // Rotate attachment points
-    double sinTheta = (double)sin(actualTheta);
-    double cosTheta = (double)cos(actualTheta);
-    wxNode *node = m_attachmentPoints.First();
-    while (node)
-    {
-        wxAttachmentPoint *point = (wxAttachmentPoint *)node->Data();
-        double x1 = point->m_x;
-        double y1 = point->m_y;
-        point->m_x = x1*cosTheta - y1*sinTheta + x*(1.0 - cosTheta) + y*sinTheta;
-        point->m_y = x1*sinTheta + y1*cosTheta + y*(1.0 - cosTheta) + x*sinTheta;
-        node = node->Next();
-    }
-
-    node = m_points->First();
-    while (node)
-    {
-        wxRealPoint *point = (wxRealPoint *)node->Data();
-        double x1 = point->x;
-        double y1 = point->y;
-        point->x = x1*cosTheta - y1*sinTheta + x*(1.0 - cosTheta) + y*sinTheta;
-        point->y = x1*sinTheta + y1*cosTheta + y*(1.0 - cosTheta) + x*sinTheta;
-        node = node->Next();
-    }
-    node = m_originalPoints->First();
-    while (node)
-    {
-        wxRealPoint *point = (wxRealPoint *)node->Data();
-        double x1 = point->x;
-        double y1 = point->y;
-        point->x = x1*cosTheta - y1*sinTheta + x*(1.0 - cosTheta) + y*sinTheta;
-        point->y = x1*sinTheta + y1*cosTheta + y*(1.0 - cosTheta) + x*sinTheta;
-        node = node->Next();
-    }
-
-    m_rotation = theta;
-
-    CalculatePolygonCentre();
-    CalculateBoundingBox();
-    ResetControlPoints();
-}
-
-// Rectangle object
-
-IMPLEMENT_DYNAMIC_CLASS(wxRectangleShape, wxShape)
-
-wxRectangleShape::wxRectangleShape(double w, double h)
-{
-  m_width = w; m_height = h; m_cornerRadius = 0.0;
-  SetDefaultRegionSize();
-}
-
-void wxRectangleShape::OnDraw(wxDC& dc)
-{
-    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(* g_oglTransparentPen);
-
-      if (m_cornerRadius != 0.0)
-        dc.DrawRoundedRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY),
-                                 WXROUND(m_width), WXROUND(m_height), m_cornerRadius);
-      else
-        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(* g_oglTransparentPen);
-      else
-        dc.SetPen(* m_pen);
-    }
-    if (m_brush)
-      dc.SetBrush(* m_brush);
-
-    if (m_cornerRadius != 0.0)
-      dc.DrawRoundedRectangle(WXROUND(x1), WXROUND(y1), WXROUND(m_width), WXROUND(m_height), m_cornerRadius);
-    else
-      dc.DrawRectangle(WXROUND(x1), WXROUND(y1), WXROUND(m_width), WXROUND(m_height));
-}
-
-void wxRectangleShape::GetBoundingBoxMin(double *the_width, double *the_height)
-{
-  *the_width = m_width;
-  *the_height = m_height;
-}
-
-void wxRectangleShape::SetSize(double x, double y, bool recursive)
-{
-  SetAttachmentSize(x, y);
-  m_width = (double)wxMax(x, 1.0);
-  m_height = (double)wxMax(y, 1.0);
-  SetDefaultRegionSize();
-}
-
-void wxRectangleShape::SetCornerRadius(double rad)
-{
-  m_cornerRadius = rad;
-}
-
-// Assume (x1, y1) is centre of box (most generally, line end at box)
-bool wxRectangleShape::GetPerimeterPoint(double x1, double y1,
-                                     double x2, double y2,
-                                     double *x3, double *y3)
-{
-  double bound_x, bound_y;
-  GetBoundingBoxMax(&bound_x, &bound_y);
-  oglFindEndForBox(bound_x, bound_y, m_xpos, m_ypos, x2, y2, x3, y3);
-
-  return TRUE;
-}
-
-#ifdef PROLOGIO
-void wxRectangleShape::WriteAttributes(wxExpr *clause)
-{
-  wxShape::WriteAttributes(clause);
-  clause->AddAttributeValue("x", m_xpos);
-  clause->AddAttributeValue("y", m_ypos);
-
-  clause->AddAttributeValue("width", m_width);
-  clause->AddAttributeValue("height", m_height);
-  if (m_cornerRadius != 0.0)
-    clause->AddAttributeValue("corner", m_cornerRadius);
-}
-
-void wxRectangleShape::ReadAttributes(wxExpr *clause)
-{
-  wxShape::ReadAttributes(clause);
-  clause->AssignAttributeValue("width", &m_width);
-  clause->AssignAttributeValue("height", &m_height);
-  clause->AssignAttributeValue("corner", &m_cornerRadius);
-
-  // In case we're reading an old file, set the region's size
-  if (m_regions.Number() == 1)
-  {
-    wxShapeRegion *region = (wxShapeRegion *)m_regions.First()->Data();
-    region->SetSize(m_width, m_height);
-  }
-}
-#endif
-
-void wxRectangleShape::Copy(wxShape& copy)
-{
-  wxShape::Copy(copy);
-
-  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() const
-{
-  return wxShape::GetNumberOfAttachments();
-}
-
-
-// There are 4 attachment points on a rectangle - 0 = top, 1 = right, 2 = bottom,
-// 3 = left.
-bool wxRectangleShape::GetAttachmentPosition(int attachment, double *x, double *y,
-                                         int nth, int no_arcs, wxLineShape *line)
-{
-    return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line);
-}
-
-// Text object (no box)
-
-IMPLEMENT_DYNAMIC_CLASS(wxTextShape, wxRectangleShape)
-
-wxTextShape::wxTextShape(double width, double height):
-  wxRectangleShape(width, height)
-{
-}
-
-void wxTextShape::OnDraw(wxDC& dc)
-{
-}
-
-void wxTextShape::Copy(wxShape& copy)
-{
-  wxRectangleShape::Copy(copy);
-}
-
-#ifdef PROLOGIO
-void wxTextShape::WriteAttributes(wxExpr *clause)
-{
-  wxRectangleShape::WriteAttributes(clause);
-}
-#endif
-
-// Ellipse object
-
-IMPLEMENT_DYNAMIC_CLASS(wxEllipseShape, wxShape)
-
-wxEllipseShape::wxEllipseShape(double w, double h)
-{
-  m_width = w; m_height = h;
-  SetDefaultRegionSize();
-}
-
-void wxEllipseShape::GetBoundingBoxMin(double *w, double *h)
-{
-  *w = m_width; *h = m_height;
-}
-
-bool wxEllipseShape::GetPerimeterPoint(double x1, double y1,
-                                      double x2, double y2,
-                                      double *x3, double *y3)
-{
-  double bound_x, bound_y;
-  GetBoundingBoxMax(&bound_x, &bound_y);
-
-//  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;
-}
-
-void wxEllipseShape::OnDraw(wxDC& dc)
-{
-    if (m_shadowMode != SHADOW_NONE)
-    {
-      if (m_shadowBrush)
-        dc.SetBrush(* m_shadowBrush);
-      dc.SetPen(* g_oglTransparentPen);
-      dc.DrawEllipse((long) ((m_xpos - GetWidth()/2) + m_shadowOffsetX),
-                      (long) ((m_ypos - GetHeight()/2) + m_shadowOffsetY),
-                      (long) GetWidth(), (long) GetHeight());
-    }
-
-    if (m_pen)
-    {
-      if (m_pen->GetWidth() == 0)
-        dc.SetPen(* g_oglTransparentPen);
-      else
-        dc.SetPen(* m_pen);
-    }
-    if (m_brush)
-      dc.SetBrush(* m_brush);
-    dc.DrawEllipse((long) (m_xpos - GetWidth()/2), (long) (m_ypos - GetHeight()/2), (long) GetWidth(), (long) GetHeight());
-}
-
-void wxEllipseShape::SetSize(double x, double y, bool recursive)
-{
-  SetAttachmentSize(x, y);
-  m_width = x;
-  m_height = y;
-  SetDefaultRegionSize();
-}
-
-#ifdef PROLOGIO
-void wxEllipseShape::WriteAttributes(wxExpr *clause)
-{
-  wxShape::WriteAttributes(clause);
-  clause->AddAttributeValue("x", m_xpos);
-  clause->AddAttributeValue("y", m_ypos);
-
-  clause->AddAttributeValue("width", m_width);
-  clause->AddAttributeValue("height", m_height);
-}
-
-void wxEllipseShape::ReadAttributes(wxExpr *clause)
-{
-  wxShape::ReadAttributes(clause);
-  clause->AssignAttributeValue("width", &m_width);
-  clause->AssignAttributeValue("height", &m_height);
-
-  // In case we're reading an old file, set the region's size
-  if (m_regions.Number() == 1)
-  {
-    wxShapeRegion *region = (wxShapeRegion *)m_regions.First()->Data();
-    region->SetSize(m_width, m_height);
-  }
-}
-#endif
-
-void wxEllipseShape::Copy(wxShape& copy)
-{
-  wxShape::Copy(copy);
-
-  wxASSERT( copy.IsKindOf(CLASSINFO(wxEllipseShape)) );
-
-  wxEllipseShape& ellipseCopy = (wxEllipseShape&) copy;
-
-  ellipseCopy.m_width = m_width;
-  ellipseCopy.m_height = m_height;
-}
-
-int wxEllipseShape::GetNumberOfAttachments() const
-{
-  return wxShape::GetNumberOfAttachments();
-}
-
-// There are 4 attachment points on an ellipse - 0 = top, 1 = right, 2 = bottom,
-// 3 = left.
-bool wxEllipseShape::GetAttachmentPosition(int attachment, double *x, double *y,
-                                         int nth, int no_arcs, wxLineShape *line)
-{
-  if (m_attachmentMode == ATTACHMENT_MODE_BRANCHING)
-    return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line);
-
-  if (m_attachmentMode != ATTACHMENT_MODE_NONE)
-  {
-    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);
-
-    int physicalAttachment = LogicalToPhysicalAttachment(attachment);
-
-    switch (physicalAttachment)
-    {
-      case 0:
-      {
-        if (m_spaceAttachments)
-          *x = left + (nth + 1)*m_width/(no_arcs + 1);
-        else *x = m_xpos;
-        *y = top;
-        // 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.
-        oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, *x, (double)(m_ypos-m_height-500), *x, m_ypos, x, y);
-        break;
-      }
-      case 1:
-      {
-        *x = right;
-        if (m_spaceAttachments)
-          *y = bottom + (nth + 1)*m_height/(no_arcs + 1);
-        else *y = m_ypos;
-        oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, (double)(m_xpos+m_width+500), *y, m_xpos, *y, x, y);
-        break;
-      }
-      case 2:
-      {
-        if (m_spaceAttachments)
-          *x = left + (nth + 1)*m_width/(no_arcs + 1);
-        else *x = m_xpos;
-        *y = bottom;
-        oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, *x, (double)(m_ypos+m_height+500), *x, m_ypos, x, y);
-        break;
-      }
-      case 3:
-      {
-        *x = left;
-        if (m_spaceAttachments)
-          *y = bottom + (nth + 1)*m_height/(no_arcs + 1);
-        else *y = m_ypos;
-        oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, (double)(m_xpos-m_width-500), *y, m_xpos, *y, x, y);
-        break;
-      }
-      default:
-      {
-        return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line);
-        break;
-      }
-    }
-    return TRUE;
-  }
-  else
-  { *x = m_xpos; *y = m_ypos; return TRUE; }
-}
-
-
-// Circle object
-IMPLEMENT_DYNAMIC_CLASS(wxCircleShape, wxEllipseShape)
-
-wxCircleShape::wxCircleShape(double diameter):wxEllipseShape(diameter, diameter)
-{
-    SetMaintainAspectRatio(TRUE);
-}
-
-void wxCircleShape::Copy(wxShape& copy)
-{
-  wxEllipseShape::Copy(copy);
-}
-
-bool wxCircleShape::GetPerimeterPoint(double x1, double y1,
-                                      double x2, double y2,
-                                      double *x3, double *y3)
-{
-  oglFindEndForCircle(m_width/2,
-                      m_xpos, m_ypos,  // Centre of circle
-                      x2, y2,  // Other end of line
-                      x3, y3);
-
-  return TRUE;
-}
-
-// Control points
-
-double wxControlPoint::sm_controlPointDragStartX = 0.0;
-double wxControlPoint::sm_controlPointDragStartY = 0.0;
-double wxControlPoint::sm_controlPointDragStartWidth = 0.0;
-double wxControlPoint::sm_controlPointDragStartHeight = 0.0;
-double wxControlPoint::sm_controlPointDragEndWidth = 0.0;
-double wxControlPoint::sm_controlPointDragEndHeight = 0.0;
-double wxControlPoint::sm_controlPointDragPosX = 0.0;
-double wxControlPoint::sm_controlPointDragPosY = 0.0;
-
-IMPLEMENT_DYNAMIC_CLASS(wxControlPoint, wxRectangleShape)
-
-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(g_oglBlackForegroundPen);
-  SetBrush(wxBLACK_BRUSH);
-  m_oldCursor = NULL;
-  m_visible = TRUE;
-  m_eraseObject = TRUE;
-}
-
-wxControlPoint::~wxControlPoint()
-{
-}
-
-// Don't even attempt to draw any text - waste of time!
-void wxControlPoint::OnDrawContents(wxDC& dc)
-{
-}
-
-void wxControlPoint::OnDraw(wxDC& dc)
-{
-  m_xpos = m_shape->GetX() + m_xoffset;
-  m_ypos = m_shape->GetY() + m_yoffset;
-  wxRectangleShape::OnDraw(dc);
-}
-
-void wxControlPoint::OnErase(wxDC& dc)
-{
-  wxRectangleShape::OnErase(dc);
-}
-
-// Implement resizing of canvas object
-void wxControlPoint::OnDragLeft(bool draw, double x, double y, int keys, int attachment)
-{
-    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() const
-{
-  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);
-
-  dc.SetLogicalFunction(OGLRBLF);
-
-  wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
-  dc.SetPen(dottedPen);
-  dc.SetBrush((* wxTRANSPARENT_BRUSH));
-
-  if (this->GetCentreResize())
-  {
-    // Maintain the same centre point.
-    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 (pt->m_type == CONTROL_POINT_HORIZONTAL)
-    {
-        if (GetMaintainAspectRatio())
-        {
-            new_height = bound_y*(new_width/bound_x);
-        }
-        else
-            new_height = bound_y;
-    }
-    else if (pt->m_type == CONTROL_POINT_VERTICAL)
-    {
-        if (GetMaintainAspectRatio())
-        {
-            new_width = bound_x*(new_height/bound_y);
-        }
-        else
-            new_width = bound_x;
-    }
-    else if (pt->m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT))
-      new_height = bound_y*(new_width/bound_x);
-
-    if (this->GetFixedWidth())
-      new_width = bound_x;
-
-    if (this->GetFixedHeight())
-      new_height = bound_y;
-
-    pt->sm_controlPointDragEndWidth = new_width;
-    pt->sm_controlPointDragEndHeight = new_height;
-
-    this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(),
-                                new_width, new_height);
-  }
-  else
-  {
-    // Don't maintain the same centre point!
-    double newX1 = wxMin(pt->sm_controlPointDragStartX, x);
-    double newY1 = wxMin(pt->sm_controlPointDragStartY, y);
-    double newX2 = wxMax(pt->sm_controlPointDragStartX, x);
-    double newY2 = wxMax(pt->sm_controlPointDragStartY, y);
-    if (pt->m_type == CONTROL_POINT_HORIZONTAL)
-    {
-      newY1 = pt->sm_controlPointDragStartY;
-      newY2 = newY1 + pt->sm_controlPointDragStartHeight;
-    }
-    else if (pt->m_type == CONTROL_POINT_VERTICAL)
-    {
-      newX1 = pt->sm_controlPointDragStartX;
-      newX2 = newX1 + pt->sm_controlPointDragStartWidth;
-    }
-    else if (pt->m_type == CONTROL_POINT_DIAGONAL && ((keys & KEY_SHIFT) || GetMaintainAspectRatio()))
-    {
-      double newH = (double)((newX2 - newX1)*(pt->sm_controlPointDragStartHeight/pt->sm_controlPointDragStartWidth));
-      if (GetY() > pt->sm_controlPointDragStartY)
-        newY2 = (double)(newY1 + newH);
-      else
-        newY1 = (double)(newY2 - newH);
-    }
-    double newWidth = (double)(newX2 - newX1);
-    double newHeight = (double)(newY2 - newY1);
-
-    if (pt->m_type == CONTROL_POINT_VERTICAL && GetMaintainAspectRatio())
-    {
-        newWidth = bound_x * (newHeight/bound_y) ;
-    }
-
-    if (pt->m_type == CONTROL_POINT_HORIZONTAL && GetMaintainAspectRatio())
-    {
-        newHeight = bound_y * (newWidth/bound_x) ;
-    }
-
-    pt->sm_controlPointDragPosX = (double)(newX1 + (newWidth/2.0));
-    pt->sm_controlPointDragPosY = (double)(newY1 + (newHeight/2.0));
-    if (this->GetFixedWidth())
-      newWidth = bound_x;
-
-    if (this->GetFixedHeight())
-      newHeight = bound_y;
-
-    pt->sm_controlPointDragEndWidth = newWidth;
-    pt->sm_controlPointDragEndHeight = newHeight;
-    this->GetEventHandler()->OnDrawOutline(dc, pt->sm_controlPointDragPosX, pt->sm_controlPointDragPosY, newWidth, newHeight);
-  }
-}
-
-void wxShape::OnSizingBeginDragLeft(wxControlPoint* pt, double x, double y, int keys, int attachment)
-{
-  m_canvas->CaptureMouse();
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-/*
-  if (pt->m_eraseObject)
-    this->Erase(dc);
-*/
-
-  dc.SetLogicalFunction(OGLRBLF);
-
-  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 (pt->GetX() < this->GetX())
-    pt->sm_controlPointDragStartX = (double)(this->GetX() + (bound_x/2.0));
-  else
-    pt->sm_controlPointDragStartX = (double)(this->GetX() - (bound_x/2.0));
-
-  if (pt->GetY() < this->GetY())
-    pt->sm_controlPointDragStartY = (double)(this->GetY() + (bound_y/2.0));
-  else
-    pt->sm_controlPointDragStartY = (double)(this->GetY() - (bound_y/2.0));
-
-  if (pt->m_type == CONTROL_POINT_HORIZONTAL)
-    pt->sm_controlPointDragStartY = (double)(this->GetY() - (bound_y/2.0));
-  else if (pt->m_type == CONTROL_POINT_VERTICAL)
-    pt->sm_controlPointDragStartX = (double)(this->GetX() - (bound_x/2.0));
-
-  // We may require the old width and height.
-  pt->sm_controlPointDragStartWidth = bound_x;
-  pt->sm_controlPointDragStartHeight = bound_y;
-
-  wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
-  dc.SetPen(dottedPen);
-  dc.SetBrush((* wxTRANSPARENT_BRUSH));
-
-  if (this->GetCentreResize())
-  {
-    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 (pt->m_type == CONTROL_POINT_HORIZONTAL)
-    {
-        if (GetMaintainAspectRatio())
-        {
-            new_height = bound_y*(new_width/bound_x);
-        }
-        else
-            new_height = bound_y;
-    }
-    else if (pt->m_type == CONTROL_POINT_VERTICAL)
-    {
-        if (GetMaintainAspectRatio())
-        {
-            new_width = bound_x*(new_height/bound_y);
-        }
-        else
-            new_width = bound_x;
-    }
-    else if (pt->m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT))
-      new_height = bound_y*(new_width/bound_x);
-
-    if (this->GetFixedWidth())
-      new_width = bound_x;
-
-    if (this->GetFixedHeight())
-      new_height = bound_y;
-
-    pt->sm_controlPointDragEndWidth = new_width;
-    pt->sm_controlPointDragEndHeight = new_height;
-    this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(),
-                                new_width, new_height);
-  }
-  else
-  {
-    // Don't maintain the same centre point!
-    double newX1 = wxMin(pt->sm_controlPointDragStartX, x);
-    double newY1 = wxMin(pt->sm_controlPointDragStartY, y);
-    double newX2 = wxMax(pt->sm_controlPointDragStartX, x);
-    double newY2 = wxMax(pt->sm_controlPointDragStartY, y);
-    if (pt->m_type == CONTROL_POINT_HORIZONTAL)
-    {
-      newY1 = pt->sm_controlPointDragStartY;
-      newY2 = newY1 + pt->sm_controlPointDragStartHeight;
-    }
-    else if (pt->m_type == CONTROL_POINT_VERTICAL)
-    {
-      newX1 = pt->sm_controlPointDragStartX;
-      newX2 = newX1 + pt->sm_controlPointDragStartWidth;
-    }
-    else if (pt->m_type == CONTROL_POINT_DIAGONAL && ((keys & KEY_SHIFT) || GetMaintainAspectRatio()))
-    {
-      double newH = (double)((newX2 - newX1)*(pt->sm_controlPointDragStartHeight/pt->sm_controlPointDragStartWidth));
-      if (pt->GetY() > pt->sm_controlPointDragStartY)
-        newY2 = (double)(newY1 + newH);
-      else
-        newY1 = (double)(newY2 - newH);
-    }
-    double newWidth = (double)(newX2 - newX1);
-    double newHeight = (double)(newY2 - newY1);
-
-    if (pt->m_type == CONTROL_POINT_VERTICAL && GetMaintainAspectRatio())
-    {
-        newWidth = bound_x * (newHeight/bound_y) ;
-    }
-
-    if (pt->m_type == CONTROL_POINT_HORIZONTAL && GetMaintainAspectRatio())
-    {
-        newHeight = bound_y * (newWidth/bound_x) ;
-    }
-
-    pt->sm_controlPointDragPosX = (double)(newX1 + (newWidth/2.0));
-    pt->sm_controlPointDragPosY = (double)(newY1 + (newHeight/2.0));
-    if (this->GetFixedWidth())
-      newWidth = bound_x;
-
-    if (this->GetFixedHeight())
-      newHeight = bound_y;
-
-    pt->sm_controlPointDragEndWidth = newWidth;
-    pt->sm_controlPointDragEndHeight = newHeight;
-    this->GetEventHandler()->OnDrawOutline(dc, pt->sm_controlPointDragPosX, pt->sm_controlPointDragPosY, newWidth, newHeight);
-  }
-}
-
-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);
-  this->Recompute();
-  this->ResetControlPoints();
-
-  this->Erase(dc);
-/*
-  if (!pt->m_eraseObject)
-    this->Show(FALSE);
-*/
-
-  this->SetSize(pt->sm_controlPointDragEndWidth, pt->sm_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 = this;
-  wxShapeCanvas *theCanvas = m_canvas;
-  bool eraseIt = pt->m_eraseObject;
-
-  if (theObject->GetCentreResize())
-    theObject->Move(dc, theObject->GetX(), theObject->GetY());
-  else
-    theObject->Move(dc, pt->sm_controlPointDragPosX, pt->sm_controlPointDragPosY);
-
-/*
-  if (!eraseIt)
-    theObject->Show(TRUE);
-*/
-
-  // Recursively redraw links if we have a composite.
-  if (theObject->GetChildren().Number() > 0)
-    theObject->DrawLinks(dc, -1, TRUE);
-
-  double width, height;
-  theObject->GetBoundingBoxMax(&width, &height);
-  theObject->GetEventHandler()->OnEndSize(width, height);
-
-  if (!theCanvas->GetQuickEditMode() && eraseIt) theCanvas->Redraw(dc);
-}
-
-
-
-// Polygon control points
-
-IMPLEMENT_DYNAMIC_CLASS(wxPolygonControlPoint, wxControlPoint)
-
-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, 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);
-
-  dc.SetLogicalFunction(OGLRBLF);
-
-  wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
-  dc.SetPen(dottedPen);
-  dc.SetBrush((* wxTRANSPARENT_BRUSH));
-
-  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
-    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
-  {
-    ppt->CalculateNewSize(x, y);
-  }
-
-  this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(),
-       ppt->GetNewSize().x, ppt->GetNewSize().y);
-}
-
-void wxPolygonShape::OnSizingBeginDragLeft(wxControlPoint* pt, double x, double y, int keys, int attachment)
-{
-  wxPolygonControlPoint* ppt = (wxPolygonControlPoint*) pt;
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  this->Erase(dc);
-
-  dc.SetLogicalFunction(OGLRBLF);
-
-  double bound_x;
-  double bound_y;
-  this->GetBoundingBoxMin(&bound_x, &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 (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 (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
-    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
-  {
-    ppt->CalculateNewSize(x, y);
-  }
-
-  this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(),
-       ppt->GetNewSize().x, ppt->GetNewSize().y);
-
-  m_canvas->CaptureMouse();
-}
-
-void wxPolygonShape::OnSizingEndDragLeft(wxControlPoint* pt, double x, double y, int keys, int attachment)
-{
-  wxPolygonControlPoint* ppt = (wxPolygonControlPoint*) pt;
-
-  wxClientDC dc(GetCanvas());
-  GetCanvas()->PrepareDC(dc);
-
-  m_canvas->ReleaseMouse();
-  dc.SetLogicalFunction(wxCOPY);
-
-  // If we're changing shape, must reset the original points
-  if (keys & KEY_CTRL)
-  {
-    ((wxPolygonShape *)this)->CalculateBoundingBox();
-    ((wxPolygonShape *)this)->UpdateOriginalPoints();
-  }
-  else
-  {
-    SetSize(ppt->GetNewSize().x, ppt->GetNewSize().y);
-  }
-
-  ((wxPolygonShape *)this)->CalculateBoundingBox();
-  ((wxPolygonShape *)this)->CalculatePolygonCentre();
-
-  this->Recompute();
-  this->ResetControlPoints();
-  this->Move(dc, this->GetX(), this->GetY());
-  if (!m_canvas->GetQuickEditMode()) m_canvas->Redraw(dc);
-}
-
-/*
- * Object region
- *
- */
-IMPLEMENT_DYNAMIC_CLASS(wxShapeRegion, wxObject)
-
-wxShapeRegion::wxShapeRegion()
-{
-  m_regionText = "";
-  m_font = g_oglNormalFont;
-  m_minHeight = 5.0;
-  m_minWidth = 5.0;
-  m_width = 0.0;
-  m_height = 0.0;
-  m_x = 0.0;
-  m_y = 0.0;
-
-  m_regionProportionX = -1.0;
-  m_regionProportionY = -1.0;
-  m_formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT;
-  m_regionName = "";
-  m_textColour = "BLACK";
-  m_penColour = "BLACK";
-  m_penStyle = wxSOLID;
-  m_actualColourObject = NULL;
-  m_actualPenObject = NULL;
-}
-
-wxShapeRegion::wxShapeRegion(wxShapeRegion& region)
-{
-  m_regionText = region.m_regionText;
-  m_regionName = region.m_regionName;
-  m_textColour = region.m_textColour;
-
-  m_font = region.m_font;
-  m_minHeight = region.m_minHeight;
-  m_minWidth = region.m_minWidth;
-  m_width = region.m_width;
-  m_height = region.m_height;
-  m_x = region.m_x;
-  m_y = region.m_y;
-
-  m_regionProportionX = region.m_regionProportionX;
-  m_regionProportionY = region.m_regionProportionY;
-  m_formatMode = region.m_formatMode;
-  m_actualColourObject = NULL;
-  m_actualPenObject = NULL;
-  m_penStyle = region.m_penStyle;
-  m_penColour = region.m_penColour;
-
-  ClearText();
-  wxNode *node = region.m_formattedText.First();
-  while (node)
-  {
-    wxShapeTextLine *line = (wxShapeTextLine *)node->Data();
-    wxShapeTextLine *new_line =
-      new wxShapeTextLine(line->GetX(), line->GetY(), line->GetText());
-    m_formattedText.Append(new_line);
-    node = node->Next();
-  }
-}
-
-wxShapeRegion::~wxShapeRegion()
-{
-  ClearText();
-}
-
-void wxShapeRegion::ClearText()
-{
-  wxNode *node = m_formattedText.First();
-  while (node)
-  {
-    wxShapeTextLine *line = (wxShapeTextLine *)node->Data();
-    wxNode *next = node->Next();
-    delete line;
-    delete node;
-    node = next;
-  }
-}
-
-void wxShapeRegion::SetFont(wxFont *f)
-{
-  m_font = f;
-}
-
-void wxShapeRegion::SetMinSize(double w, double h)
-{
-  m_minWidth = w;
-  m_minHeight = h;
-}
-
-void wxShapeRegion::SetSize(double w, double h)
-{
-  m_width = w;
-  m_height = h;
-}
-
-void wxShapeRegion::SetPosition(double xp, double yp)
-{
-  m_x = xp;
-  m_y = yp;
-}
-
-void wxShapeRegion::SetProportions(double xp, double yp)
-{
-  m_regionProportionX = xp;
-  m_regionProportionY = yp;
-}
-
-void wxShapeRegion::SetFormatMode(int mode)
-{
-  m_formatMode = mode;
-}
-
-void wxShapeRegion::SetColour(const wxString& col)
-{
-  m_textColour = col;
-  m_actualColourObject = NULL;
-}
-
-wxColour *wxShapeRegion::GetActualColourObject()
-{
-  if (!m_actualColourObject)
-    m_actualColourObject = wxTheColourDatabase->FindColour(GetColour());
-  if (!m_actualColourObject)
-    m_actualColourObject = wxBLACK;
-  return m_actualColourObject;
-}
-
-void wxShapeRegion::SetPenColour(const wxString& col)
-{
-  m_penColour = col;
-  m_actualPenObject = NULL;
-}
-
-// Returns NULL if the pen is invisible
-// (different to pen being transparent; indicates that
-// region boundary should not be drawn.)
-wxPen *wxShapeRegion::GetActualPen()
-{
-  if (m_actualPenObject)
-    return m_actualPenObject;
-
-  if (!m_penColour) return NULL;
-  if (m_penColour == "Invisible")
-    return NULL;
-  m_actualPenObject = wxThePenList->FindOrCreatePen(m_penColour, 1, m_penStyle);
-  return m_actualPenObject;
-}
-
-