[mapnik-vector-tile] 04/06: Update clipper to r496-mapnik.

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Sat Oct 3 10:01:08 UTC 2015


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository mapnik-vector-tile.

commit 717dd91e229664a3fccdc4bb447b0a244205255e
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Sat Oct 3 11:00:26 2015 +0200

    Update clipper to r496-mapnik.
---
 debian/changelog   |   1 +
 debian/clipper.cpp | 563 +++++++++++++++++++++++++++++------------------------
 debian/clipper.hpp |  46 ++---
 3 files changed, 331 insertions(+), 279 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index c354974..2da5401 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,7 @@
 mapnik-vector-tile (0.11.0+dfsg-1) UNRELEASED; urgency=medium
 
   * New upstream release.
+  * Update clipper to r496-mapnik.
 
  -- Bas Couwenberg <sebastic at debian.org>  Sat, 03 Oct 2015 10:58:35 +0200
 
diff --git a/debian/clipper.cpp b/debian/clipper.cpp
index da47cb6..8658562 100644
--- a/debian/clipper.cpp
+++ b/debian/clipper.cpp
@@ -1,8 +1,8 @@
 /*******************************************************************************
 *                                                                              *
 * Author    :  Angus Johnson                                                   *
-* Version   :  6.2.9                                                           *
-* Date      :  16 February 2015                                                *
+* Version   :  6.4.0                                                           *
+* Date      :  2 July 2015                                                     *
 * Website   :  http://www.angusj.com                                           *
 * Copyright :  Angus Johnson 2010-2015                                         *
 *                                                                              *
@@ -66,12 +66,11 @@ static int const Skip = -2;        //edge that would otherwise close a path
 
 struct TEdge {
   IntPoint Bot;
-  IntPoint Curr;
+  IntPoint Curr; //current (updated for every new scanbeam)
   IntPoint Top;
-  IntPoint Delta;
   double Dx;
   PolyType PolyTyp;
-  EdgeSide Side;
+  EdgeSide Side; //side only refers to current side of solution poly
   int WindDelta; //1 or -1 depending on winding direction
   int WindCnt;
   int WindCnt2; //winding count of the opposite polytype
@@ -99,6 +98,8 @@ struct LocalMinimum {
 
 struct OutPt;
 
+//OutRec: contains a path in the clipping solution. Edges in the AEL will
+//carry a pointer to an OutRec when they are part of the clipping solution.
 struct OutRec {
   int       Idx;
   bool      IsHole;
@@ -403,19 +404,25 @@ double Area(const Path &poly)
 }
 //------------------------------------------------------------------------------
 
-double Area(const OutRec &outRec)
+double Area(const OutPt *op)
 {
-  OutPt *op = outRec.Pts;
+  const OutPt *startOp = op;
   if (!op) return 0;
   double a = 0;
   do {
     a +=  (double)(op->Prev->Pt.x + op->Pt.x) * (double)(op->Prev->Pt.y - op->Pt.y);
     op = op->Next;
-  } while (op != outRec.Pts);
+  } while (op != startOp);
   return a * 0.5;
 }
 //------------------------------------------------------------------------------
 
+double Area(const OutRec &outRec)
+{
+  return Area(outRec.Pts);
+}
+//------------------------------------------------------------------------------
+
 bool PointIsVertex(const IntPoint &Pt, OutPt *pp)
 {
   OutPt *pp2 = pp;
@@ -536,10 +543,12 @@ bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
 {
 #ifndef use_int32
   if (UseFullInt64Range)
-    return Int128Mul(e1.Delta.y, e2.Delta.x) == Int128Mul(e1.Delta.x, e2.Delta.y);
+    return Int128Mul(e1.Top.y - e1.Bot.y, e2.Top.x - e2.Bot.x) == 
+    Int128Mul(e1.Top.x - e1.Bot.x, e2.Top.y - e2.Bot.y);
   else 
 #endif
-    return e1.Delta.y * e2.Delta.x == e1.Delta.x * e2.Delta.y;
+    return (e1.Top.y - e1.Bot.y) * (e2.Top.x - e2.Bot.x) == 
+    (e1.Top.x - e1.Bot.x) * (e2.Top.y - e2.Bot.y);
 }
 //------------------------------------------------------------------------------
 
@@ -569,7 +578,7 @@ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
 
 inline bool IsHorizontal(TEdge &e)
 {
-  return e.Delta.y == 0;
+  return e.Dx == HORIZONTAL;
 }
 //------------------------------------------------------------------------------
 
@@ -582,11 +591,9 @@ inline double GetDx(const IntPoint pt1, const IntPoint pt2)
 
 inline void SetDx(TEdge &e)
 {
-  e.Delta.x = (e.Top.x - e.Bot.x);
-  e.Delta.y = (e.Top.y - e.Bot.y);
-
-  if (e.Delta.y == 0) e.Dx = HORIZONTAL;
-  else e.Dx = (double)(e.Delta.x) / e.Delta.y;
+  cInt dy  = (e.Top.y - e.Bot.y);
+  if (dy == 0) e.Dx = HORIZONTAL;
+  else e.Dx = (double)(e.Top.x - e.Bot.x) / dy;
 }
 //---------------------------------------------------------------------------
 
@@ -626,7 +633,7 @@ void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
     ip.x = TopX(Edge1, ip.y);
     return;
   }
-  else if (Edge1.Delta.x == 0)
+  else if (Edge1.Dx == 0)
   {
     ip.x = Edge1.Bot.x;
     if (IsHorizontal(Edge2))
@@ -637,7 +644,7 @@ void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
       ip.y = Round(ip.x / Edge2.Dx + b2);
     }
   }
-  else if (Edge2.Delta.x == 0)
+  else if (Edge2.Dx == 0)
   {
     ip.x = Edge2.Bot.x;
     if (IsHorizontal(Edge1))
@@ -804,7 +811,12 @@ bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2)
   p = btmPt2->Next;
   while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next;
   double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt));
-  return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n);
+
+  if (std::max(dx1p, dx1n) == std::max(dx2p, dx2n) &&
+    std::min(dx1p, dx1n) == std::min(dx2p, dx2n))
+      return Area(btmPt1) > 0; //if otherwise identical use orientation
+  else
+    return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n);
 }
 //------------------------------------------------------------------------------
 
@@ -1191,8 +1203,6 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
       locMin.RightBound = E->Prev;
       leftBoundIsForward = true; //Q.nextInLML = Q.next
     }
-    locMin.LeftBound->Side = esLeft;
-    locMin.RightBound->Side = esRight;
 
     if (!Closed) locMin.LeftBound->WindDelta = 0;
     else if (locMin.LeftBound->Next == locMin.RightBound)
@@ -1231,8 +1241,6 @@ void ClipperBase::Clear()
   DisposeLocalMinimaList();
   for (EdgeList::size_type i = 0; i < m_edges.size(); ++i)
   {
-    //for each edge array in turn, find the first used edge and 
-    //check for and remove any hiddenPts in each edge in the array.
     TEdge* edges = m_edges[i];
     delete [] edges;
   }
@@ -1248,9 +1256,11 @@ void ClipperBase::Reset()
   if (m_CurrentLM == m_MinimaList.end()) return; //ie nothing to process
   std::stable_sort(m_MinimaList.begin(), m_MinimaList.end(), LocMinSorter());
 
+  m_Scanbeam = ScanbeamList(); //clears/resets priority_queue
   //reset all edges ...
   for (MinimaList::iterator lm = m_MinimaList.begin(); lm != m_MinimaList.end(); ++lm)
   {
+    InsertScanbeam(lm->y);
     TEdge* e = lm->LeftBound;
     if (e)
     {
@@ -1267,6 +1277,8 @@ void ClipperBase::Reset()
       e->OutIdx = Unassigned;
     }
   }
+  m_ActiveEdges = 0;
+  m_CurrentLM = m_MinimaList.begin();
 }
 //------------------------------------------------------------------------------
 
@@ -1277,10 +1289,12 @@ void ClipperBase::DisposeLocalMinimaList()
 }
 //------------------------------------------------------------------------------
 
-void ClipperBase::PopLocalMinima()
+bool ClipperBase::PopLocalMinima(cInt Y, const LocalMinimum *&locMin)
 {
-  if (m_CurrentLM == m_MinimaList.end()) return;
+  if (m_CurrentLM == m_MinimaList.end() || (*m_CurrentLM).y != Y) return false;
+  locMin = &(*m_CurrentLM);
   ++m_CurrentLM;
+  return true;
 }
 //------------------------------------------------------------------------------
 
@@ -1299,6 +1313,7 @@ IntRect ClipperBase::GetBounds()
   result.bottom = lm->LeftBound->Bot.y;
   while (lm != m_MinimaList.end())
   {
+    //todo - needs fixing for open paths
     result.bottom = std::max(result.bottom, lm->LeftBound->Bot.y);
     TEdge* e = lm->LeftBound;
     for (;;) {
@@ -1321,6 +1336,142 @@ IntRect ClipperBase::GetBounds()
   }
   return result;
 }
+//------------------------------------------------------------------------------
+
+void ClipperBase::InsertScanbeam(const cInt Y)
+{
+  m_Scanbeam.push(Y);
+}
+//------------------------------------------------------------------------------
+
+bool ClipperBase::PopScanbeam(cInt &Y)
+{
+  if (m_Scanbeam.empty()) return false;
+  Y = m_Scanbeam.top();
+  m_Scanbeam.pop();
+  while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) { m_Scanbeam.pop(); } // Pop duplicates.
+  return true;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::DisposeAllOutRecs(){
+  for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
+    DisposeOutRec(i);
+  m_PolyOuts.clear();
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::DisposeOutRec(PolyOutList::size_type index)
+{
+  OutRec *outRec = m_PolyOuts[index];
+  if (outRec->Pts) DisposeOutPts(outRec->Pts);
+  delete outRec;
+  m_PolyOuts[index] = 0;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::DeleteFromAEL(TEdge *e)
+{
+  TEdge* AelPrev = e->PrevInAEL;
+  TEdge* AelNext = e->NextInAEL;
+  if (!AelPrev &&  !AelNext && (e != m_ActiveEdges)) return; //already deleted
+  if (AelPrev) AelPrev->NextInAEL = AelNext;
+  else m_ActiveEdges = AelNext;
+  if (AelNext) AelNext->PrevInAEL = AelPrev;
+  e->NextInAEL = 0;
+  e->PrevInAEL = 0;
+}
+//------------------------------------------------------------------------------
+
+OutRec* ClipperBase::CreateOutRec()
+{
+  OutRec* result = new OutRec;
+  result->IsHole = false;
+  result->IsOpen = false;
+  result->FirstLeft = 0;
+  result->Pts = 0;
+  result->BottomPt = 0;
+  result->PolyNd = 0;
+  m_PolyOuts.push_back(result);
+  result->Idx = (int)m_PolyOuts.size() - 1;
+  return result;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2)
+{
+  //check that one or other edge hasn't already been removed from AEL ...
+  if (Edge1->NextInAEL == Edge1->PrevInAEL ||
+    Edge2->NextInAEL == Edge2->PrevInAEL) return;
+
+  if (Edge1->NextInAEL == Edge2)
+  {
+    TEdge* Next = Edge2->NextInAEL;
+    if (Next) Next->PrevInAEL = Edge1;
+    TEdge* Prev = Edge1->PrevInAEL;
+    if (Prev) Prev->NextInAEL = Edge2;
+    Edge2->PrevInAEL = Prev;
+    Edge2->NextInAEL = Edge1;
+    Edge1->PrevInAEL = Edge2;
+    Edge1->NextInAEL = Next;
+  }
+  else if (Edge2->NextInAEL == Edge1)
+  {
+    TEdge* Next = Edge1->NextInAEL;
+    if (Next) Next->PrevInAEL = Edge2;
+    TEdge* Prev = Edge2->PrevInAEL;
+    if (Prev) Prev->NextInAEL = Edge1;
+    Edge1->PrevInAEL = Prev;
+    Edge1->NextInAEL = Edge2;
+    Edge2->PrevInAEL = Edge1;
+    Edge2->NextInAEL = Next;
+  }
+  else
+  {
+    TEdge* Next = Edge1->NextInAEL;
+    TEdge* Prev = Edge1->PrevInAEL;
+    Edge1->NextInAEL = Edge2->NextInAEL;
+    if (Edge1->NextInAEL) Edge1->NextInAEL->PrevInAEL = Edge1;
+    Edge1->PrevInAEL = Edge2->PrevInAEL;
+    if (Edge1->PrevInAEL) Edge1->PrevInAEL->NextInAEL = Edge1;
+    Edge2->NextInAEL = Next;
+    if (Edge2->NextInAEL) Edge2->NextInAEL->PrevInAEL = Edge2;
+    Edge2->PrevInAEL = Prev;
+    if (Edge2->PrevInAEL) Edge2->PrevInAEL->NextInAEL = Edge2;
+  }
+
+  if (!Edge1->PrevInAEL) m_ActiveEdges = Edge1;
+  else if (!Edge2->PrevInAEL) m_ActiveEdges = Edge2;
+}
+//------------------------------------------------------------------------------
+
+void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e)
+{
+  if (!e->NextInLML) 
+    throw clipperException("UpdateEdgeIntoAEL: invalid call");
+
+  e->NextInLML->OutIdx = e->OutIdx;
+  TEdge* AelPrev = e->PrevInAEL;
+  TEdge* AelNext = e->NextInAEL;
+  if (AelPrev) AelPrev->NextInAEL = e->NextInLML;
+  else m_ActiveEdges = e->NextInLML;
+  if (AelNext) AelNext->PrevInAEL = e->NextInLML;
+  e->NextInLML->Side = e->Side;
+  e->NextInLML->WindDelta = e->WindDelta;
+  e->NextInLML->WindCnt = e->WindCnt;
+  e->NextInLML->WindCnt2 = e->WindCnt2;
+  e = e->NextInLML;
+  e->Curr = e->Bot;
+  e->PrevInAEL = AelPrev;
+  e->NextInAEL = AelNext;
+  if (!IsHorizontal(*e)) InsertScanbeam(e->Top.y);
+}
+//------------------------------------------------------------------------------
+
+bool ClipperBase::LocalMinimaPending()
+{
+  return (m_CurrentLM != m_MinimaList.end());
+}
 
 //------------------------------------------------------------------------------
 // TClipper methods ...
@@ -1328,8 +1479,6 @@ IntRect ClipperBase::GetBounds()
 
 Clipper::Clipper(int initOptions) : ClipperBase() //constructor
 {
-  m_ActiveEdges = 0;
-  m_SortedEdges = 0;
   m_ExecuteLocked = false;
   m_UseFullRange = false;
   m_ReverseOutput = ((initOptions & ioReverseSolution) != 0);
@@ -1342,12 +1491,6 @@ Clipper::Clipper(int initOptions) : ClipperBase() //constructor
 }
 //------------------------------------------------------------------------------
 
-Clipper::~Clipper() //destructor
-{
-  Clear();
-}
-//------------------------------------------------------------------------------
-
 #ifdef use_xyz  
 void Clipper::ZFillFunction(ZFillCallback zFillFunc)
 {  
@@ -1356,18 +1499,6 @@ void Clipper::ZFillFunction(ZFillCallback zFillFunc)
 //------------------------------------------------------------------------------
 #endif
 
-void Clipper::Reset()
-{
-  ClipperBase::Reset();
-  m_Scanbeam = ScanbeamList();
-  m_Maxima = MaximaList();
-  m_ActiveEdges = 0;
-  m_SortedEdges = 0;
-  for (MinimaList::iterator lm = m_MinimaList.begin(); lm != m_MinimaList.end(); ++lm)
-    InsertScanbeam(lm->y);
-}
-//------------------------------------------------------------------------------
-
 bool Clipper::Execute(ClipType clipType, Paths &solution, PolyFillType fillType)
 {
     return Execute(clipType, solution, fillType, fillType);
@@ -1437,19 +1568,26 @@ bool Clipper::ExecuteInternal()
   bool succeeded = true;
   try {
     Reset();
-    if (m_CurrentLM == m_MinimaList.end()) return true;
-    cInt botY = PopScanbeam();
-    do {
-      InsertLocalMinimaIntoAEL(botY);
+    m_Maxima = MaximaList();
+    m_SortedEdges = 0;
+
+    succeeded = true;
+    cInt botY, topY;
+    if (!PopScanbeam(botY)) return false;
+    InsertLocalMinimaIntoAEL(botY);
+    while (PopScanbeam(topY) || LocalMinimaPending())
+    {
       ProcessHorizontals();
-	  ClearGhostJoins();
-	  if (m_Scanbeam.empty()) break;
-      cInt topY = PopScanbeam();
-      succeeded = ProcessIntersections(topY);
-      if (!succeeded) break;
+	    ClearGhostJoins();
+      if (!ProcessIntersections(topY))
+      {
+        succeeded = false;
+        break;
+      }
       ProcessEdgesAtTopOfScanbeam(topY);
       botY = topY;
-    } while (!m_Scanbeam.empty() || m_CurrentLM != m_MinimaList.end());
+      InsertLocalMinimaIntoAEL(botY);
+    }
   }
   catch(std::exception const&) 
   {
@@ -1489,37 +1627,6 @@ bool Clipper::ExecuteInternal()
 }
 //------------------------------------------------------------------------------
 
-void Clipper::InsertScanbeam(const cInt Y)
-{
-    m_Scanbeam.push(Y);
-}
-//------------------------------------------------------------------------------
-
-cInt Clipper::PopScanbeam()
-{
-    const cInt Y = m_Scanbeam.top();
-    m_Scanbeam.pop();
-    while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) { m_Scanbeam.pop(); } // Pop duplicates.
-    return Y;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::DisposeAllOutRecs(){
-  for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
-    DisposeOutRec(i);
-  m_PolyOuts.clear();
-}
-//------------------------------------------------------------------------------
-
-void Clipper::DisposeOutRec(PolyOutList::size_type index)
-{
-  OutRec *outRec = m_PolyOuts[index];
-  if (outRec->Pts) DisposeOutPts(outRec->Pts);
-  delete outRec;
-  m_PolyOuts[index] = 0;
-}
-//------------------------------------------------------------------------------
-
 void Clipper::SetWindingCount(TEdge &edge)
 {
   TEdge *e = edge.PrevInAEL;
@@ -1527,7 +1634,13 @@ void Clipper::SetWindingCount(TEdge &edge)
   while (e  && ((e->PolyTyp != edge.PolyTyp) || (e->WindDelta == 0))) e = e->PrevInAEL;
   if (!e)
   {
-    edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta);
+    if (edge.WindDelta == 0)
+    {
+      PolyFillType pft = (edge.PolyTyp == ptSubject ? m_SubjFillType : m_ClipFillType);
+      edge.WindCnt = (pft == pftNegative ? -1 : 1);
+    }
+    else
+      edge.WindCnt = edge.WindDelta;
     edge.WindCnt2 = 0;
     e = m_ActiveEdges; //ie get ready to calc WindCnt2
   }   
@@ -1759,13 +1872,16 @@ OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
         prevE = e->PrevInAEL;
   }
 
-  if (prevE && prevE->OutIdx >= 0 &&
-      (TopX(*prevE, Pt.y) == TopX(*e, Pt.y)) &&
-      SlopesEqual(*e, *prevE, m_UseFullRange) &&
-      (e->WindDelta != 0) && (prevE->WindDelta != 0))
+  if (prevE && prevE->OutIdx >= 0)
   {
-    OutPt* outPt = AddOutPt(prevE, Pt);
-    AddJoin(result, outPt, e->Top);
+    cInt xPrev = TopX(*prevE, Pt.y);
+    cInt xE = TopX(*e, Pt.y);
+    if (xPrev == xE && (e->WindDelta != 0) && (prevE->WindDelta != 0) &&
+      SlopesEqual(IntPoint(xPrev, Pt.y), prevE->Top, IntPoint(xE, Pt.y), e->Top, m_UseFullRange))
+    {
+      OutPt* outPt = AddOutPt(prevE, Pt);
+      AddJoin(result, outPt, e->Top);
+    }
   }
   return result;
 }
@@ -1807,6 +1923,15 @@ void Clipper::AddEdgeToSEL(TEdge *edge)
 }
 //------------------------------------------------------------------------------
 
+bool Clipper::PopEdgeFromSEL(TEdge *&edge)
+{
+  if (!m_SortedEdges) return false;
+  edge = m_SortedEdges;
+  DeleteFromSEL(m_SortedEdges);
+  return true;
+}
+//------------------------------------------------------------------------------
+
 void Clipper::CopyAELToSEL()
 {
   TEdge* e = m_ActiveEdges;
@@ -1858,11 +1983,12 @@ void Clipper::AddGhostJoin(OutPt *op, const IntPoint OffPt)
 
 void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
 {
-  while (m_CurrentLM != m_MinimaList.end() && (m_CurrentLM->y == botY))
+  const LocalMinimum *lm;
+  while (PopLocalMinima(botY, lm))
   {
-    TEdge* lb = m_CurrentLM->LeftBound;
-    TEdge* rb = m_CurrentLM->RightBound;
-    PopLocalMinima();
+    TEdge* lb = lm->LeftBound;
+    TEdge* rb = lm->RightBound;
+    
     OutPt *Op1 = 0;
     if (!lb)
     {
@@ -1894,15 +2020,20 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
 
      if (rb)
      {
-       if(IsHorizontal(*rb)) AddEdgeToSEL(rb);
-       else InsertScanbeam( rb->Top.y );
+		 if (IsHorizontal(*rb))
+		 {
+			 AddEdgeToSEL(rb);
+			 if (rb->NextInLML) 
+				 InsertScanbeam(rb->NextInLML->Top.y);
+		 }
+		 else InsertScanbeam( rb->Top.y );
      }
 
     if (!lb || !rb) continue;
 
     //if any output polygons share an edge, they'll need joining later ...
     if (Op1 && IsHorizontal(*rb) && 
-      m_GhostJoins.size() > 0 && (rb->WindDelta != 0))
+      !m_GhostJoins.empty() && (rb->WindDelta != 0))
     {
       for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i)
       {
@@ -1917,7 +2048,7 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
     if (lb->OutIdx >= 0 && lb->PrevInAEL && 
       lb->PrevInAEL->Curr.x == lb->Bot.x &&
       lb->PrevInAEL->OutIdx >= 0 &&
-      SlopesEqual(*lb->PrevInAEL, *lb, m_UseFullRange) &&
+      SlopesEqual(lb->PrevInAEL->Bot, lb->PrevInAEL->Top, lb->Curr, lb->Top, m_UseFullRange) &&
       (lb->WindDelta != 0) && (lb->PrevInAEL->WindDelta != 0))
     {
         OutPt *Op2 = AddOutPt(lb->PrevInAEL, lb->Bot);
@@ -1928,7 +2059,7 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
     {
 
       if (rb->OutIdx >= 0 && rb->PrevInAEL->OutIdx >= 0 &&
-        SlopesEqual(*rb->PrevInAEL, *rb, m_UseFullRange) &&
+        SlopesEqual(rb->PrevInAEL->Curr, rb->PrevInAEL->Top, rb->Curr, rb->Top, m_UseFullRange) &&
         (rb->WindDelta != 0) && (rb->PrevInAEL->WindDelta != 0))
       {
           OutPt *Op2 = AddOutPt(rb->PrevInAEL, rb->Bot);
@@ -1952,19 +2083,6 @@ void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
 }
 //------------------------------------------------------------------------------
 
-void Clipper::DeleteFromAEL(TEdge *e)
-{
-  TEdge* AelPrev = e->PrevInAEL;
-  TEdge* AelNext = e->NextInAEL;
-  if(  !AelPrev &&  !AelNext && (e != m_ActiveEdges) ) return; //already deleted
-  if( AelPrev ) AelPrev->NextInAEL = AelNext;
-  else m_ActiveEdges = AelNext;
-  if( AelNext ) AelNext->PrevInAEL = AelPrev;
-  e->NextInAEL = 0;
-  e->PrevInAEL = 0;
-}
-//------------------------------------------------------------------------------
-
 void Clipper::DeleteFromSEL(TEdge *e)
 {
   TEdge* SelPrev = e->PrevInSEL;
@@ -2188,19 +2306,27 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &Pt)
 
 void Clipper::SetHoleState(TEdge *e, OutRec *outrec)
 {
-  bool IsHole = false;
   TEdge *e2 = e->PrevInAEL;
+  TEdge *eTmp = 0;
   while (e2)
   {
     if (e2->OutIdx >= 0 && e2->WindDelta != 0)
     {
-      IsHole = !IsHole;
-      if (! outrec->FirstLeft)
-        outrec->FirstLeft = m_PolyOuts[e2->OutIdx];
+      if (!eTmp) eTmp = e2;
+      else if (eTmp->OutIdx == e2->OutIdx) eTmp = 0;        
     }
     e2 = e2->PrevInAEL;
   }
-  if (IsHole) outrec->IsHole = true;
+  if (!eTmp)
+  {
+    outrec->FirstLeft = 0;
+    outrec->IsHole = false;
+  }
+  else
+  {
+    outrec->FirstLeft = m_PolyOuts[eTmp->OutIdx];
+    outrec->IsHole = !outrec->FirstLeft->IsHole;
+  }
 }
 //------------------------------------------------------------------------------
 
@@ -2224,7 +2350,7 @@ OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2)
 }
 //------------------------------------------------------------------------------
 
-bool Param1RightOfParam2(OutRec* outRec1, OutRec* outRec2)
+bool OutRec1RightOfOutRec2(OutRec* outRec1, OutRec* outRec2)
 {
   do
   {
@@ -2251,9 +2377,9 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
   OutRec *outRec2 = m_PolyOuts[e2->OutIdx];
 
   OutRec *holeStateRec;
-  if (Param1RightOfParam2(outRec1, outRec2)) 
+  if (OutRec1RightOfOutRec2(outRec1, outRec2))
     holeStateRec = outRec2;
-  else if (Param1RightOfParam2(outRec2, outRec1)) 
+  else if (OutRec1RightOfOutRec2(outRec2, outRec1))
     holeStateRec = outRec1;
   else 
     holeStateRec = GetLowermostRec(outRec1, outRec2);
@@ -2266,7 +2392,6 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
   OutPt* p2_lft = outRec2->Pts;
   OutPt* p2_rt = p2_lft->Prev;
 
-  EdgeSide Side;
   //join e2 poly onto e1 poly and delete pointers to e2 ...
   if(  e1->Side == esLeft )
   {
@@ -2288,7 +2413,6 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
       p1_rt->Next = p2_lft;
       outRec1->Pts = p2_lft;
     }
-    Side = esLeft;
   } else
   {
     if(  e2->Side == esRight )
@@ -2307,7 +2431,6 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
       p1_lft->Prev = p2_rt;
       p2_rt->Next = p1_lft;
     }
-    Side = esRight;
   }
 
   outRec1->BottomPt = 0;
@@ -2333,7 +2456,7 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
     if( e->OutIdx == ObsoleteIdx )
     {
       e->OutIdx = OKIdx;
-      e->Side = Side;
+      e->Side = e1->Side;
       break;
     }
     e = e->NextInAEL;
@@ -2343,21 +2466,6 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
 }
 //------------------------------------------------------------------------------
 
-OutRec* Clipper::CreateOutRec()
-{
-  OutRec* result = new OutRec;
-  result->IsHole = false;
-  result->IsOpen = false;
-  result->FirstLeft = 0;
-  result->Pts = 0;
-  result->BottomPt = 0;
-  result->PolyNd = 0;
-  m_PolyOuts.push_back(result);
-  result->Idx = (int)m_PolyOuts.size()-1;
-  return result;
-}
-//------------------------------------------------------------------------------
-
 OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
 {
   if(  e->OutIdx < 0 )
@@ -2409,13 +2517,9 @@ OutPt* Clipper::GetLastOutPt(TEdge *e)
 
 void Clipper::ProcessHorizontals()
 {
-  TEdge* horzEdge = m_SortedEdges;
-  while(horzEdge)
-  {
-    DeleteFromSEL(horzEdge);
+  TEdge* horzEdge;
+  while (PopEdgeFromSEL(horzEdge))
     ProcessHorizontal(horzEdge);
-    horzEdge = m_SortedEdges;
-  }
 }
 //------------------------------------------------------------------------------
 
@@ -2439,64 +2543,21 @@ inline bool IsIntermediate(TEdge *e, const cInt Y)
 
 TEdge *GetMaximaPair(TEdge *e)
 {
-  TEdge* result = 0;
   if ((e->Next->Top == e->Top) && !e->Next->NextInLML)
-    result = e->Next;
+    return e->Next;
   else if ((e->Prev->Top == e->Top) && !e->Prev->NextInLML)
-    result = e->Prev;
-
-  if (result && (result->OutIdx == Skip ||
-    //result is false if both NextInAEL & PrevInAEL are nil & not horizontal ...
-    (result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result))))
-      return 0;
-  return result;
+    return e->Prev;
+  else return 0;
 }
 //------------------------------------------------------------------------------
 
-void Clipper::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2)
+TEdge *GetMaximaPairEx(TEdge *e)
 {
-  //check that one or other edge hasn't already been removed from AEL ...
-  if (Edge1->NextInAEL == Edge1->PrevInAEL || 
-    Edge2->NextInAEL == Edge2->PrevInAEL) return;
-
-  if(  Edge1->NextInAEL == Edge2 )
-  {
-    TEdge* Next = Edge2->NextInAEL;
-    if( Next ) Next->PrevInAEL = Edge1;
-    TEdge* Prev = Edge1->PrevInAEL;
-    if( Prev ) Prev->NextInAEL = Edge2;
-    Edge2->PrevInAEL = Prev;
-    Edge2->NextInAEL = Edge1;
-    Edge1->PrevInAEL = Edge2;
-    Edge1->NextInAEL = Next;
-  }
-  else if(  Edge2->NextInAEL == Edge1 )
-  {
-    TEdge* Next = Edge1->NextInAEL;
-    if( Next ) Next->PrevInAEL = Edge2;
-    TEdge* Prev = Edge2->PrevInAEL;
-    if( Prev ) Prev->NextInAEL = Edge1;
-    Edge1->PrevInAEL = Prev;
-    Edge1->NextInAEL = Edge2;
-    Edge2->PrevInAEL = Edge1;
-    Edge2->NextInAEL = Next;
-  }
-  else
-  {
-    TEdge* Next = Edge1->NextInAEL;
-    TEdge* Prev = Edge1->PrevInAEL;
-    Edge1->NextInAEL = Edge2->NextInAEL;
-    if( Edge1->NextInAEL ) Edge1->NextInAEL->PrevInAEL = Edge1;
-    Edge1->PrevInAEL = Edge2->PrevInAEL;
-    if( Edge1->PrevInAEL ) Edge1->PrevInAEL->NextInAEL = Edge1;
-    Edge2->NextInAEL = Next;
-    if( Edge2->NextInAEL ) Edge2->NextInAEL->PrevInAEL = Edge2;
-    Edge2->PrevInAEL = Prev;
-    if( Edge2->PrevInAEL ) Edge2->PrevInAEL->NextInAEL = Edge2;
-  }
-
-  if( !Edge1->PrevInAEL ) m_ActiveEdges = Edge1;
-  else if( !Edge2->PrevInAEL ) m_ActiveEdges = Edge2;
+  //as GetMaximaPair() but returns 0 if MaxPair isn't in AEL (unless it's horizontal)
+  TEdge* result = GetMaximaPair(e);
+  if (result && (result->OutIdx == Skip ||
+    (result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result)))) return 0;
+  return result;
 }
 //------------------------------------------------------------------------------
 
@@ -2582,7 +2643,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
 {
   Direction dir;
   cInt horzLeft, horzRight;
-  bool IsOpen = (horzEdge->OutIdx >= 0 && m_PolyOuts[horzEdge->OutIdx]->IsOpen);
+  bool IsOpen = (horzEdge->WindDelta == 0);
 
   GetHorzDirection(*horzEdge, dir, horzLeft, horzRight);
 
@@ -2594,7 +2655,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
 
   MaximaList::const_iterator maxIt;
   MaximaList::const_reverse_iterator maxRit;
-  if (m_Maxima.size() > 0)
+  if (!m_Maxima.empty())
   {
       //get the first maxima in range (X) ...
       if (dir == dLeftToRight)
@@ -2626,7 +2687,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
         //this code block inserts extra coords into horizontal edges (in output
         //polygons) whereever maxima touch these horizontal edges. This helps
         //'simplifying' polygons (ie if the Simplify property is set).
-        if (m_Maxima.size() > 0)
+        if (!m_Maxima.empty())
         {
             if (dir == dLeftToRight)
             {
@@ -2765,29 +2826,6 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
 }
 //------------------------------------------------------------------------------
 
-void Clipper::UpdateEdgeIntoAEL(TEdge *&e)
-{
-  if( !e->NextInLML )
-    throw clipperException("UpdateEdgeIntoAEL: invalid call");
-
-  e->NextInLML->OutIdx = e->OutIdx;
-  TEdge* AelPrev = e->PrevInAEL;
-  TEdge* AelNext = e->NextInAEL;
-  if (AelPrev) AelPrev->NextInAEL = e->NextInLML;
-  else m_ActiveEdges = e->NextInLML;
-  if (AelNext) AelNext->PrevInAEL = e->NextInLML;
-  e->NextInLML->Side = e->Side;
-  e->NextInLML->WindDelta = e->WindDelta;
-  e->NextInLML->WindCnt = e->WindCnt;
-  e->NextInLML->WindCnt2 = e->WindCnt2;
-  e = e->NextInLML;
-  e->Curr = e->Bot;
-  e->PrevInAEL = AelPrev;
-  e->NextInAEL = AelNext;
-  if (!IsHorizontal(*e)) InsertScanbeam(e->Top.y);
-}
-//------------------------------------------------------------------------------
-
 bool Clipper::ProcessIntersections(const cInt topY)
 {
   if( !m_ActiveEdges ) return true;
@@ -2845,6 +2883,7 @@ void Clipper::BuildIntersectList(const cInt topY)
       if(e->Curr.x > eNext->Curr.x)
       {
         IntersectPoint(*e, *eNext, Pt);
+        if (Pt.y < topY) Pt = IntPoint(TopX(*e, topY), topY);
         IntersectNode * newNode = new IntersectNode;
         newNode->Edge1 = e;
         newNode->Edge2 = eNext;
@@ -2919,7 +2958,7 @@ bool Clipper::FixupIntersectionOrder()
 
 void Clipper::DoMaxima(TEdge *e)
 {
-  TEdge* eMaxPair = GetMaximaPair(e);
+  TEdge* eMaxPair = GetMaximaPairEx(e);
   if (!eMaxPair)
   {
     if (e->OutIdx >= 0)
@@ -2980,7 +3019,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
 
     if(IsMaximaEdge)
     {
-      TEdge* eMaxPair = GetMaximaPair(e);
+      TEdge* eMaxPair = GetMaximaPairEx(e);
       IsMaximaEdge = (!eMaxPair || !IsHorizontal(*eMaxPair));
     }
 
@@ -3052,7 +3091,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
       if (ePrev && ePrev->Curr.x == e->Bot.x &&
         ePrev->Curr.y == e->Bot.y && op &&
         ePrev->OutIdx >= 0 && ePrev->Curr.y > ePrev->Top.y &&
-        SlopesEqual(*e, *ePrev, m_UseFullRange) &&
+        SlopesEqual(e->Curr, e->Top, ePrev->Curr, ePrev->Top, m_UseFullRange) &&
         (e->WindDelta != 0) && (ePrev->WindDelta != 0))
       {
         OutPt* op2 = AddOutPt(ePrev, e->Bot);
@@ -3061,7 +3100,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
       else if (eNext && eNext->Curr.x == e->Bot.x &&
         eNext->Curr.y == e->Bot.y && op &&
         eNext->OutIdx >= 0 && eNext->Curr.y > eNext->Top.y &&
-        SlopesEqual(*e, *eNext, m_UseFullRange) &&
+        SlopesEqual(e->Curr, e->Top, eNext->Curr, eNext->Top, m_UseFullRange) &&
         (e->WindDelta != 0) && (eNext->WindDelta != 0))
       {
         OutPt* op2 = AddOutPt(eNext, e->Bot);
@@ -3588,9 +3627,8 @@ void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec)
   for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
   {
     OutRec* outRec = m_PolyOuts[i];
-    if (!outRec->Pts || !outRec->FirstLeft) continue;
     OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
-    if (firstLeft == OldOutRec)
+    if (outRec->Pts  && firstLeft == OldOutRec)
     {
       if (Poly2ContainsPoly1(outRec->Pts, NewOutRec->Pts))
         outRec->FirstLeft = NewOutRec;
@@ -3599,13 +3637,40 @@ void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec)
 }
 //----------------------------------------------------------------------
 
-void Clipper::FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec)
-{ 
+void Clipper::FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec)
+{
+  //A polygon has split into two such that one is now the inner of the other.
+  //It's possible that these polygons now wrap around other polygons, so check
+  //every polygon that's also contained by OuterOutRec's FirstLeft container
+  //(including 0) to see if they've become inner to the new inner polygon ...
+  OutRec* orfl = OuterOutRec->FirstLeft;
+  for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
+  {
+    OutRec* outRec = m_PolyOuts[i];
+
+    if (!outRec->Pts || outRec == OuterOutRec || outRec == InnerOutRec)
+      continue;
+    OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
+    if (firstLeft != orfl && firstLeft != InnerOutRec && firstLeft != OuterOutRec)
+      continue;
+    if (Poly2ContainsPoly1(outRec->Pts, InnerOutRec->Pts))
+      outRec->FirstLeft = InnerOutRec;
+    else if (Poly2ContainsPoly1(outRec->Pts, OuterOutRec->Pts))
+      outRec->FirstLeft = OuterOutRec;
+    else if (outRec->FirstLeft == InnerOutRec || outRec->FirstLeft == OuterOutRec)
+      outRec->FirstLeft = orfl;
+  }
+}
+//----------------------------------------------------------------------
+void Clipper::FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec)
+{
   //reassigns FirstLeft WITHOUT testing if NewOutRec contains the polygon
   for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
   {
     OutRec* outRec = m_PolyOuts[i];
-    if (outRec->FirstLeft == OldOutRec) outRec->FirstLeft = NewOutRec;
+    OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
+    if (outRec->Pts && outRec->FirstLeft == OldOutRec)
+      outRec->FirstLeft = NewOutRec;
   }
 }
 //----------------------------------------------------------------------
@@ -3626,8 +3691,8 @@ void Clipper::JoinCommonEdges()
     //before calling JoinPoints() ...
     OutRec *holeStateRec;
     if (outRec1 == outRec2) holeStateRec = outRec1;
-    else if (Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2;
-    else if (Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1;
+    else if (OutRec1RightOfOutRec2(outRec1, outRec2)) holeStateRec = outRec2;
+    else if (OutRec1RightOfOutRec2(outRec2, outRec1)) holeStateRec = outRec1;
     else holeStateRec = GetLowermostRec(outRec1, outRec2);
 
     if (!JoinPoints(join, outRec1, outRec2)) continue;
@@ -3644,25 +3709,12 @@ void Clipper::JoinCommonEdges()
       //update all OutRec2.Pts Idx's ...
       UpdateOutPtIdxs(*outRec2);
 
-      //We now need to check every OutRec.FirstLeft pointer. If it points
-      //to OutRec1 it may need to point to OutRec2 instead ...
-      if (m_UsingPolyTree)
-        for (PolyOutList::size_type j = 0; j < m_PolyOuts.size() - 1; j++)
-        {
-          OutRec* oRec = m_PolyOuts[j];
-          if (!oRec->Pts || ParseFirstLeft(oRec->FirstLeft) != outRec1 ||
-            oRec->IsHole == outRec1->IsHole) continue;
-          if (Poly2ContainsPoly1(oRec->Pts, join->OutPt2))
-            oRec->FirstLeft = outRec2;
-        }
-
       if (Poly2ContainsPoly1(outRec2->Pts, outRec1->Pts))
       {
-        //outRec2 is contained by outRec1 ...
+        //outRec1 contains outRec2 ...
         outRec2->IsHole = !outRec1->IsHole;
         outRec2->FirstLeft = outRec1;
 
-        //fixup FirstLeft pointers that may need reassigning to OutRec1
         if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1);
 
         if ((outRec2->IsHole ^ m_ReverseOutput) == (Area(*outRec2) > 0))
@@ -3670,13 +3722,12 @@ void Clipper::JoinCommonEdges()
             
       } else if (Poly2ContainsPoly1(outRec1->Pts, outRec2->Pts))
       {
-        //outRec1 is contained by outRec2 ...
+        //outRec2 contains outRec1 ...
         outRec2->IsHole = outRec1->IsHole;
         outRec1->IsHole = !outRec2->IsHole;
         outRec2->FirstLeft = outRec1->FirstLeft;
         outRec1->FirstLeft = outRec2;
 
-        //fixup FirstLeft pointers that may need reassigning to OutRec1
         if (m_UsingPolyTree) FixupFirstLefts2(outRec1, outRec2);
 
         if ((outRec1->IsHole ^ m_ReverseOutput) == (Area(*outRec1) > 0))
@@ -3705,8 +3756,7 @@ void Clipper::JoinCommonEdges()
         outRec1->FirstLeft = outRec2->FirstLeft;
       outRec2->FirstLeft = outRec1;
 
-      //fixup FirstLeft pointers that may need reassigning to OutRec1
-      if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1);
+      if (m_UsingPolyTree) FixupFirstLefts3(outRec2, outRec1);
     }
   }
 }
@@ -3858,7 +3908,7 @@ void ClipperOffset::Execute(Paths& solution, double delta)
     clpr.AddPath(outer, ptSubject, true);
     clpr.ReverseSolution(true);
     clpr.Execute(ctUnion, solution, pftNegative, pftNegative);
-    if (solution.size() > 0) solution.erase(solution.begin());
+    if (!solution.empty()) solution.erase(solution.begin());
   }
 }
 //------------------------------------------------------------------------------
@@ -4404,6 +4454,7 @@ void CleanPolygon(Path& poly, double distance)
 
 void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance)
 {
+  out_polys.resize(in_polys.size());
   for (Paths::size_type i = 0; i < in_polys.size(); ++i)
     CleanPolygon(in_polys[i], out_polys[i], distance);
 }
diff --git a/debian/clipper.hpp b/debian/clipper.hpp
index 41fd305..7831b0b 100644
--- a/debian/clipper.hpp
+++ b/debian/clipper.hpp
@@ -1,8 +1,8 @@
 /*******************************************************************************
 *                                                                              *
 * Author    :  Angus Johnson                                                   *
-* Version   :  6.2.9                                                           *
-* Date      :  16 February 2015                                                *
+* Version   :  6.4.0                                                           *
+* Date      :  2 July 2015                                                     *
 * Website   :  http://www.angusj.com                                           *
 * Copyright :  Angus Johnson 2010-2015                                         *
 *                                                                              *
@@ -251,7 +251,7 @@ class ClipperBase
 public:
   ClipperBase();
   virtual ~ClipperBase();
-  bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
+  virtual bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
   bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
   virtual void Clear();
   IntRect GetBounds();
@@ -260,11 +260,18 @@ public:
 protected:
   void DisposeLocalMinimaList();
   TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
-  void PopLocalMinima();
   virtual void Reset();
   TEdge* ProcessBound(TEdge* E, bool IsClockwise);
-  TEdge* DescendToMin(TEdge *&E);
-  void AscendToMax(TEdge *&E, bool Appending, bool IsClosed);
+  void InsertScanbeam(const cInt Y);
+  bool PopScanbeam(cInt &Y);
+  bool LocalMinimaPending();
+  bool PopLocalMinima(cInt Y, const LocalMinimum *&locMin);
+  OutRec* CreateOutRec();
+  void DisposeAllOutRecs();
+  void DisposeOutRec(PolyOutList::size_type index);
+  void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
+  void DeleteFromAEL(TEdge *e);
+  void UpdateEdgeIntoAEL(TEdge *&e);
 
   typedef std::vector<LocalMinimum> MinimaList;
   MinimaList::iterator m_CurrentLM;
@@ -272,8 +279,13 @@ protected:
 
   bool              m_UseFullRange;
   EdgeList          m_edges;
-  bool             m_PreserveCollinear;
-  bool             m_HasOpenPaths;
+  bool              m_PreserveCollinear;
+  bool              m_HasOpenPaths;
+  PolyOutList       m_PolyOuts;
+  TEdge           *m_ActiveEdges;
+
+  typedef std::priority_queue<cInt> ScanbeamList;
+  ScanbeamList     m_Scanbeam;
 };
 //------------------------------------------------------------------------------
 
@@ -281,7 +293,6 @@ class Clipper : public virtual ClipperBase
 {
 public:
   Clipper(int initOptions = 0);
-  ~Clipper();
   bool Execute(ClipType clipType,
       Paths &solution,
       PolyFillType fillType = pftEvenOdd);
@@ -305,19 +316,14 @@ public:
   void ZFillFunction(ZFillCallback zFillFunc);
 #endif
 protected:
-  void Reset();
   virtual bool ExecuteInternal();
 private:
-  PolyOutList      m_PolyOuts;
   JoinList         m_Joins;
   JoinList         m_GhostJoins;
   IntersectList    m_IntersectList;
   ClipType         m_ClipType;
-  typedef std::priority_queue<cInt> ScanbeamList;
-  ScanbeamList     m_Scanbeam;
   typedef std::list<cInt> MaximaList;
   MaximaList       m_Maxima;
-  TEdge           *m_ActiveEdges;
   TEdge           *m_SortedEdges;
   bool             m_ExecuteLocked;
   PolyFillType     m_ClipFillType;
@@ -331,19 +337,15 @@ private:
   void SetWindingCount(TEdge& edge);
   bool IsEvenOddFillType(const TEdge& edge) const;
   bool IsEvenOddAltFillType(const TEdge& edge) const;
-  void InsertScanbeam(const cInt Y);
-  cInt PopScanbeam();
   void InsertLocalMinimaIntoAEL(const cInt botY);
   void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge);
   void AddEdgeToSEL(TEdge *edge);
+  bool PopEdgeFromSEL(TEdge *&edge);
   void CopyAELToSEL();
   void DeleteFromSEL(TEdge *e);
-  void DeleteFromAEL(TEdge *e);
-  void UpdateEdgeIntoAEL(TEdge *&e);
   void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
   bool IsContributing(const TEdge& edge) const;
   bool IsTopHorz(const cInt XPos);
-  void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
   void DoMaxima(TEdge *e);
   void ProcessHorizontals();
   void ProcessHorizontal(TEdge *horzEdge);
@@ -352,11 +354,8 @@ private:
   OutRec* GetOutRec(int idx);
   void AppendPolygon(TEdge *e1, TEdge *e2);
   void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
-  OutRec* CreateOutRec();
   OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
   OutPt* GetLastOutPt(TEdge *e);
-  void DisposeAllOutRecs();
-  void DisposeOutRec(PolyOutList::size_type index);
   bool ProcessIntersections(const cInt topY);
   void BuildIntersectList(const cInt topY);
   void ProcessIntersectList();
@@ -379,7 +378,8 @@ private:
   void JoinCommonEdges();
   void DoSimplePolygons();
   void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
-  void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec);
+  void FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec);
+  void FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec);
 #ifdef use_xyz
   void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
 #endif

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/mapnik-vector-tile.git



More information about the Pkg-grass-devel mailing list