GME  13
ArEdgeLs.cpp
Go to the documentation of this file.
00001 //COM'd by Tamas (check AutoRouterEdge.cpp)
00002 #include "stdafx.h"
00003 //#include "afxcoll.h"
00004 //#include "afxtempl.h"
00005 //#include "float.h"
00006 //
00007 //#include "ArGraph.h"
00008 //#include "ArEdgeLs.h"
00009 //
00010 //#ifdef _DEBUG
00012 //#endif
00013 //
00014 //#define EDLS_S (ED_SMALLGAP)
00015 //#define EDLS_R (ED_SMALLGAP+1)
00016 //#define EDLS_D (ED_MAXCOORD-ED_MINCOORD)
00017 //
00019 //      In this file every comments refer to the horizontal case, that is, each edge is
00020 //      horizontal.
00021 //*/
00022 //
00024 //      Every SArEdge belongs to an edge of a CArPath, CArBox or CArPort. This edge is
00025 //      Represented by a CArPoint with its next point. The variable 'point' will refer
00026 //      to this CArPoint.
00027 //
00028 //      The coordinates of an edge are 'x1', 'x2' and 'y' where x1/x2 is the x-coordinate
00029 //      of the left/right point, and y is the common y-coordinate of the points.
00030 //
00031 //      The edges are ordered according to their y-coordinates. The first edge has
00032 //      the least y-coordinate (topmost), and its pointer is in 'order_first'.
00033 //      We use the 'order' prefix in the variable names to refer to this order.
00034 //
00035 //      We will walk from top to bottom (from the 'order_first' along the 'order_next').
00036 //      We keep track a "section" of some edges. If we have an infinite horizontal line,
00037 //      then the section consists of those edges that are above the line and not blocked
00038 //      by another edge which is closer to the line. Each edge in the section has
00039 //      a viewable portion from the line (the not blocked portion). The coordinates
00040 //      of this portion are 'section_x1' and 'section_x2'. We have an order of the edges
00041 //      belonging to the current section. The 'section_first' refers to the leftmost
00042 //      edge in the section, while the 'section_next' to the next from left to right.
00043 //
00044 //      We say that the SArEdge E1 "precede" the SArEdge E2 if there is no other SArEdge which
00045 //      totally blocks S1 from S2. So a section consists of the preceding edges of an 
00046 //      infinite edge. We say that E1 is "adjacent" to E2, if E1 is the nearest edge
00047 //      to E2 which precede it. Clearly, every edge has at most one adjacent precedence.
00048 //
00049 //      The edges of any CArBox or CArPort are fixed. We will continually fix the edges
00050 //      of the CArPaths. But first we need some definition.
00051 //
00052 //      We call a set of edges as a "block" if the topmost (first) and bottommost (last)
00053 //      edges of it are fixed while the edges between them are not. Furthermore, every
00054 //      edge is adjacent to     the next one in the order. Every edge in the block has an
00055 //      "index". The index of the first one (topmost) is 0, of the second is 1, and so on.
00056 //      We call the index of the last edge (# of edges - 1) as the index of the entire box.
00057 //      The "depth" of a block is the difference of the y-coordinates of the first and last
00058 //      edges of it. The "goal gap" of the block is the quotient of the depth and index
00059 //      of the block. If the difference of the y-coordinates of the adjacent edges in
00060 //      the block are all equal to the goal gap, then we say that the block is evenly
00061 //      distributed.
00062 //
00063 //      So we search the block which has minimal goal gap. Then if it is not evenly
00064 //      distributed, then we shift the not fixed edges to the desired position. It is
00065 //      not hard to see that if the block has minimal goal gap (among the all
00066 //      possibilities of blocks), then in this way we do not move any edges into boxes.
00067 //      Finally, we set the (inner) edges of the block to be fixed (except the topmost and 
00068 //      bottommost edges, since they are already fixed). And we again begin the search.
00069 //      If every edge is fixed, then we have finished. This is the basic idea. We will
00070 //      refine this algorithm.
00071 //
00072 //      The variables related to the blocks are prefixed by 'block'. Note that the 
00073 //      variables of an edge are refer to that block in which this edge is inner! The
00074 //      'block_oldgap' is the goal gap of the block when it was last evenly distributed.
00075 //
00076 //      The variables 'canstart' and 'canend' means that this egde can start and/or and
00077 //      a block. The top edgeof a box only canend, while a fixed edge of a path can both
00078 //      start and end of a block.
00079 //
00080 //*/
00081 //
00082 //
00084 //
00085 //
00086 //CArEdgeList::CArEdgeList(int h)
00087 //{
00088 //      owner = NULL;
00089 //
00090 //      ishorizontal = (h != 0);
00091 //
00092 //      Con_Order();
00093 //      Con_Section();
00094 //}
00095 //
00096 //CArEdgeList::~CArEdgeList()
00097 //{
00098 //      Des_Order();
00099 //      Des_Section();
00100 //}
00101 //
00103 //
00104 //SArEdge* CArEdgeList::CreateEdge() const
00105 //{
00106 //      SArEdge* edge = new SArEdge;
00107 //      ASSERT( edge != NULL );
00108 //
00109 //      edge->owner = NULL;
00110 //      
00111 //      edge->startpoint_prev = NULL;
00112 //      edge->startpoint = NULL;
00113 //      edge->endpoint = NULL;
00114 //      edge->endpoint_next = NULL;
00115 //
00116 //      edge->position_y =0;
00117 //      edge->position_x1 = 0;
00118 //      edge->position_x2 = 0;
00119 //      edge->bracket_closing = 0;
00120 //      edge->bracket_opening = 0;
00121 //
00122 //      edge->order_prev = NULL;
00123 //      edge->order_next = NULL;
00124 //
00125 //      edge->edge_fixed = 0;
00126 //      edge->edge_canpassed = 0;
00127 //
00128 //      edge->position_y = 0;
00129 //
00130 //      edge->block_prev = NULL;
00131 //      edge->block_next = NULL;
00132 //      edge->block_trace = NULL;
00133 //
00134 //      edge->closest_prev = NULL;
00135 //      edge->closest_next = NULL;
00136 //
00137 //      return edge;
00138 //}
00139 //
00140 //void CArEdgeList::AddEdges(CArPath* path)
00141 //{
00142 //      ASSERT_VALID(path);
00143 //      ASSERT( path->GetOwner() == owner );
00144 //      ASSERT_VALID( path->GetStartPort() );
00145 //      ASSERT_VALID( path->GetEndPort() );
00146 //
00147 //      CPoint* startpoint;
00148 //      CPoint* endpoint;
00149 //
00150 //      POSITION pos = path->GetTailEdgePtrs(startpoint, endpoint);
00151 //      while( pos != NULL )
00152 //      {
00153 //              EArDir dir = GetDir(*endpoint - *startpoint);
00154 //
00155 //#ifdef _DEBUG
00156 //              if( path->IsMoveable() )
00157 //                      ASSERT( IsRightAngle(dir) );
00158 //#endif
00159 //
00160 //              if( IsRightAngle(dir) && IsHorizontal(dir) == ishorizontal )
00161 //              {
00162 //                      SArEdge* edge = CreateEdge();
00163 //
00164 //                      edge->owner = path;
00165 //
00166 //                      edge->startpoint = startpoint;
00167 //                      edge->endpoint = endpoint;
00168 //                      edge->startpoint_prev = path->GetPointBeforeEdge(pos);
00169 //                      edge->endpoint_next = path->GetPointAfterEdge(pos);
00170 //
00171 //                      edge->edge_fixed = path->IsFixed() || 
00172 //                              (edge->startpoint_prev == NULL && path->GetStartPort()->IsConnectToCenter()) ||
00173 //                              (edge->endpoint_next == NULL && path->GetEndPort()->IsConnectToCenter());
00174 //
00175 //                      Position_LoadY(edge);
00176 //                      Position_LoadB(edge);
00177 //                      Insert(edge);
00178 //              }
00179 //
00180 //              path->GetPrevEdgePtrs(pos, startpoint, endpoint);
00181 //      }
00182 //}
00183 //
00184 //SArEdge* CArEdgeList::GetEdge(CPoint* startpoint, CPoint* endpoint) const
00185 //{
00186 //      ASSERT( startpoint != NULL && endpoint != NULL );
00187 //
00188 //      SArEdge* edge = order_first;
00189 //      while( edge != NULL )
00190 //      {
00191 //              if( edge->startpoint == startpoint )
00192 //              {
00193 //                      ASSERT( edge->endpoint == endpoint );
00194 //                      break;
00195 //              }
00196 //
00197 //              edge = edge->order_next;
00198 //      }
00199 //
00200 //      ASSERT( edge != NULL );
00201 //      return edge;
00202 //}
00203 //
00204 //SArEdge* CArEdgeList::GetEdgeAt(CPoint point, int nearness) const
00205 //{
00206 //      SArEdge* edge = order_first;
00207 //      while( edge )
00208 //      {
00209 //              if( IsPointNearLine(point, *edge->startpoint, *edge->endpoint, nearness) )
00210 //                      return edge;
00211 //
00212 //              edge = edge->order_next;
00213 //      }
00214 //
00215 //      return NULL;
00216 //}
00217 //
00218 //#ifdef _DEBUG
00219 //
00220 //void CArEdgeList::AssertValidPathEdges(CArPath* path) const
00221 //{
00222 //      ASSERT( path != NULL );
00223 //      ASSERT( path->GetOwner() == owner );
00224 //
00225 //      CPoint* startpoint;
00226 //      CPoint* endpoint;
00227 //
00228 //      POSITION pos = path->GetTailEdgePtrs(startpoint, endpoint);
00229 //      while( pos != NULL )
00230 //      {
00231 //              EArDir dir = GetDir(*endpoint - *startpoint);
00232 //
00233 //              if( path->IsMoveable() )
00234 //                      ASSERT( IsRightAngle(dir) );
00235 //
00236 //              if( IsRightAngle(dir) && IsHorizontal(dir) == ishorizontal )
00237 //              {
00238 //                      SArEdge* edge = GetEdge(startpoint, endpoint);
00239 //                      ASSERT( edge != NULL );
00240 //
00241 //                      ASSERT( edge->owner == path );
00242 //
00243 //                      ASSERT( edge->startpoint == startpoint );
00244 //                      ASSERT( edge->endpoint == endpoint );
00245 //                      ASSERT( edge->startpoint_prev == path->GetPointBeforeEdge(pos) );
00246 //                      ASSERT( edge->endpoint_next == path->GetPointAfterEdge(pos) );
00247 //              }
00248 //
00249 //              path->GetPrevEdgePtrs(pos, startpoint, endpoint);
00250 //      }
00251 //
00252 //      SArEdge* edge = order_first;
00253 //      while( edge != NULL )
00254 //      {
00255 //              if( edge->owner == path )
00256 //              {
00257 //                      POSITION pos = path->GetEdgePosForStartPoint(edge->startpoint);
00258 //                      ASSERT( pos != NULL );
00259 //                      ASSERT( path->GetStartPoint(pos)== edge->startpoint );
00260 //                      ASSERT( path->GetEndPoint(pos)== edge->endpoint );
00261 //                      ASSERT( path->GetPointBeforeEdge(pos)== edge->startpoint_prev );
00262 //                      ASSERT( path->GetPointAfterEdge(pos)== edge->endpoint_next );
00263 //              }
00264 //
00265 //              edge = edge->order_next;
00266 //      }
00267 //}
00268 //
00269 //#endif
00270 //
00271 //void CArEdgeList::AddEdges(CArPort* port)
00272 //{
00273 //      ASSERT_VALID(port);
00274 //      ASSERT( port->GetOwner()->GetOwner() == owner );
00275 //
00276 //      if( port->IsConnectToCenter() || port->GetOwner()->IsAtomic() )
00277 //              return;
00278 //
00279 //      for(int i = 0; i < 4; i++)
00280 //      {
00281 //              CPoint* startpoint_prev = port->selfpoints + ((i+3)%4);
00282 //              CPoint* startpoint = port->selfpoints + (i);
00283 //              CPoint* endpoint = port->selfpoints + ((i+1)%4);
00284 //              CPoint* endpoint_next = port->selfpoints + ((i+2)%4);
00285 //
00286 //              EArDir dir = GetDir(*endpoint - *startpoint);
00287 //              ASSERT( IsRightAngle(dir) );
00288 //
00289 //              if( IsHorizontal(dir) == ishorizontal && port->CanHaveStartEndPointHorizontal(ishorizontal) )
00290 //              {
00291 //                      SArEdge* edge = CreateEdge();
00292 //
00293 //                      edge->owner = port;
00294 //
00295 //                      edge->startpoint = startpoint;
00296 //                      edge->endpoint = endpoint;
00297 //                      edge->startpoint_prev = startpoint_prev;
00298 //                      edge->endpoint_next = endpoint_next;
00299 //
00300 //                      edge->edge_fixed = 1;
00301 //
00302 //                      Position_LoadY(edge);
00303 //                      Position_LoadB(edge);
00304 //
00305 //                      if( edge->bracket_closing )
00306 //                              edge->position_y += 0.999F;
00307 //
00308 //                      Insert(edge);
00309 //              }
00310 //      }
00311 //}
00312 //
00313 //void CArEdgeList::AddEdges(CArBox* box)
00314 //{
00315 //      ASSERT_VALID(box);
00316 //      ASSERT( box->GetOwner() == owner );
00317 //
00318 //      for(int i = 0; i < 4; i++)
00319 //      {
00320 //              CPoint* startpoint_prev = box->selfpoints + ((i+3)%4);
00321 //              CPoint* startpoint = box->selfpoints + (i);
00322 //              CPoint* endpoint = box->selfpoints + ((i+1)%4);
00323 //              CPoint* endpoint_next = box->selfpoints + ((i+2)%4);
00324 //
00325 //              EArDir dir = GetDir(*endpoint - *startpoint);
00326 //              ASSERT( IsRightAngle(dir) );
00327 //
00328 //              if( IsHorizontal(dir) == ishorizontal )
00329 //              {
00330 //                      SArEdge* edge = CreateEdge();
00331 //
00332 //                      edge->owner = box;
00333 //
00334 //                      edge->startpoint = startpoint;
00335 //                      edge->endpoint = endpoint;
00336 //                      edge->startpoint_prev = startpoint_prev;
00337 //                      edge->endpoint_next = endpoint_next;
00338 //
00339 //                      edge->edge_fixed = 1;
00340 //
00341 //                      Position_LoadY(edge);
00342 //                      Position_LoadB(edge);
00343 //
00344 //                      if( edge->bracket_closing )
00345 //                              edge->position_y += 0.999F;
00346 //              
00347 //                      Insert(edge);
00348 //              }
00349 //      }
00350 //}
00351 //
00352 //void CArEdgeList::AddEdges(CArGraph* graph)
00353 //{
00354 //      ASSERT_VALID(graph);
00355 //      ASSERT( graph == owner );
00356 //
00357 //      for(int i = 0; i < 4; i++)
00358 //      {
00359 //              CPoint* startpoint_prev = graph->selfpoints + ((i+3)%4);
00360 //              CPoint* startpoint = graph->selfpoints + (i);
00361 //              CPoint* endpoint = graph->selfpoints + ((i+1)%4);
00362 //              CPoint* endpoint_next = graph->selfpoints + ((i+2)%4);
00363 //
00364 //              EArDir dir = GetDir(*endpoint - *startpoint);
00365 //              ASSERT( IsRightAngle(dir) );
00366 //
00367 //              if( IsHorizontal(dir) == ishorizontal )
00368 //              {
00369 //                      SArEdge* edge = CreateEdge();
00370 //
00371 //                      edge->owner = graph;
00372 //
00373 //                      edge->startpoint = startpoint;
00374 //                      edge->endpoint = endpoint;
00375 //                      edge->startpoint_prev = startpoint_prev;
00376 //                      edge->endpoint_next = endpoint_next;
00377 //
00378 //                      edge->edge_fixed = 1;
00379 //
00380 //                      Position_LoadY(edge);
00381 //                      Insert(edge);
00382 //              }
00383 //      }
00384 //}
00385 //
00386 //void CArEdgeList::DeleteEdges(CObject* object)
00387 //{
00388 //      ASSERT( object != NULL );
00389 //
00390 //      SArEdge* edge = order_first;
00391 //      while( edge != NULL )
00392 //      {
00393 //              if( edge->owner == object )
00394 //              {
00395 //                      SArEdge* next = edge->order_next;
00396 //                      Delete(edge);
00397 //                      edge = next;
00398 //              }
00399 //              else
00400 //                      edge = edge->order_next;
00401 //      }
00402 //}
00403 //
00404 //void CArEdgeList::DeleteAllEdges()
00405 //{
00406 //      while( order_first )
00407 //              Delete(order_first);
00408 //
00409 //      ASSERT( order_last == NULL );
00410 //}
00411 //
00412 //int CArEdgeList::IsEmpty() const
00413 //{
00414 //      ASSERT( (order_first != NULL) + (order_last != NULL) != 1 );
00415 //
00416 //      return order_first == NULL;
00417 //}
00418 //
00420 //
00421 //long CArEdgeList::Position_GetRealY(const SArEdge* edge) const
00422 //{
00423 //      ASSERT( edge != NULL && edge->startpoint != NULL && edge->endpoint != NULL );
00424 //
00425 //      if( ishorizontal )
00426 //      {
00427 //              ASSERT( edge->startpoint->y == edge->endpoint->y );
00428 //              return edge->startpoint->y;
00429 //      }
00430 //
00431 //      ASSERT( edge->startpoint->x == edge->endpoint->x );
00432 //      return edge->startpoint->x;
00433 //}
00434 //
00435 //void CArEdgeList::Position_SetRealY(SArEdge* edge, long y) const
00436 //{
00437 //      ASSERT( edge != NULL && edge->startpoint != NULL && edge->endpoint != NULL );
00438 //
00439 //      if( ishorizontal )
00440 //      {
00441 //              ASSERT( edge->startpoint->y == edge->endpoint->y );
00442 //              edge->startpoint->y = y;
00443 //              edge->endpoint->y = y;
00444 //      }
00445 //      else
00446 //      {
00447 //              ASSERT( edge->startpoint->x == edge->endpoint->x );
00448 //              edge->startpoint->x = y;
00449 //              edge->endpoint->x = y;
00450 //      }
00451 //}
00452 //
00453 //void CArEdgeList::Position_GetRealX(const SArEdge* edge, long& x1, long& x2) const
00454 //{
00455 //      ASSERT( edge != NULL && edge->startpoint != NULL && edge->endpoint != NULL );
00456 //
00457 //      if( ishorizontal )
00458 //      {
00459 //              ASSERT( edge->startpoint->y == edge->endpoint->y );
00460 //              if( edge->startpoint->x < edge->endpoint->x )
00461 //              {
00462 //                      x1 = edge->startpoint->x;
00463 //                      x2 = edge->endpoint->x;
00464 //              }
00465 //              else
00466 //              {
00467 //                      x1 = edge->endpoint->x;
00468 //                      x2 = edge->startpoint->x;
00469 //              }
00470 //      }
00471 //      else
00472 //      {
00473 //              ASSERT( edge->startpoint->x == edge->endpoint->x );
00474 //              if( edge->startpoint->y < edge->endpoint->y )
00475 //              {
00476 //                      x1 = edge->startpoint->y;
00477 //                      x2 = edge->endpoint->y;
00478 //              }
00479 //              else
00480 //              {
00481 //                      x1 = edge->endpoint->y;
00482 //                      x2 = edge->startpoint->y;
00483 //              }
00484 //      }
00485 //}
00486 //
00487 //void CArEdgeList::Position_GetRealO(const SArEdge* edge, long& o1, long& o2) const
00488 //{
00489 //      ASSERT( edge != NULL && edge->startpoint != NULL && edge->endpoint != NULL );
00490 //
00491 //      if( ishorizontal )
00492 //      {
00493 //              ASSERT( edge->startpoint->y == edge->endpoint->y );
00494 //              if( edge->startpoint->x < edge->endpoint->x )
00495 //              {
00496 //                      o1 = edge->startpoint_prev == NULL ? 0 : edge->startpoint_prev->y - edge->startpoint->y;
00497 //                      o2 = edge->endpoint_next == NULL ? 0 : edge->endpoint_next->y - edge->endpoint->y;
00498 //              }
00499 //              else
00500 //              {
00501 //                      o1 = edge->endpoint_next == NULL ? 0 : edge->endpoint_next->y - edge->endpoint->y;
00502 //                      o2 = edge->startpoint_prev == NULL ? 0 : edge->startpoint_prev->y - edge->startpoint->y;
00503 //              }
00504 //      }
00505 //      else
00506 //      {
00507 //              ASSERT( edge->startpoint->x == edge->endpoint->x );
00508 //              if( edge->startpoint->y < edge->endpoint->y )
00509 //              {
00510 //                      o1 = edge->startpoint_prev == NULL ? 0 : edge->startpoint_prev->x - edge->startpoint->x;
00511 //                      o2 = edge->endpoint_next == NULL ? 0 : edge->endpoint_next->x - edge->endpoint->x;
00512 //              }
00513 //              else
00514 //              {
00515 //                      o1 = edge->endpoint_next == NULL ? 0 : edge->endpoint_next->x - edge->endpoint->x;
00516 //                      o2 = edge->startpoint_prev == NULL ? 0 : edge->startpoint_prev->x - edge->startpoint->x;
00517 //              }
00518 //      }
00519 //}
00520 //
00521 //void CArEdgeList::Position_LoadY(SArEdge* edge) const
00522 //{
00523 //      ASSERT( edge != NULL && edge->order_next == NULL && edge->order_prev == NULL );
00524 //
00525 //      edge->position_y = (float) Position_GetRealY(edge);
00526 //}
00527 //
00528 //void CArEdgeList::Position_LoadB(SArEdge* edge) const
00529 //{
00530 //      ASSERT( edge != NULL );
00531 //
00532 //      edge->bracket_opening = !edge->edge_fixed && Bracket_IsOpening(edge);
00533 //      edge->bracket_closing = !edge->edge_fixed && Bracket_IsClosing(edge);
00534 //}
00535 //
00536 //void CArEdgeList::PositionAll_StoreY() const
00537 //{
00538 //      SArEdge* edge = order_first;
00539 //      while( edge )
00540 //      {
00541 //              Position_SetRealY(edge, (long) edge->position_y);
00542 //
00543 //              edge = edge->order_next;
00544 //      }
00545 //}
00546 //
00547 //void CArEdgeList::PositionAll_LoadX() const
00548 //{
00549 //      SArEdge* edge = order_first;
00550 //      while( edge )
00551 //      {
00552 //              Position_GetRealX(edge, edge->position_x1, edge->position_x2);
00553 //
00554 //              edge = edge->order_next;
00555 //      }
00556 //}
00557 //
00558 //#ifdef _DEBUG
00559 //
00560 //void CArEdgeList::AssertValidPositions() const
00561 //{
00562 //      SArEdge* edge = order_first;
00563 //      while( edge )
00564 //      {
00565 //              long y = Position_GetRealY(edge);
00566 //              ASSERT( edge->position_y - 1 <= y && y <= edge->position_y + 1 );
00567 //
00568 //              if( edge->order_prev )
00569 //              {
00570 //                      ASSERT( edge->order_prev->position_y <= edge->position_y );
00571 //                      ASSERT( Position_GetRealY(edge->order_prev) <= y );
00572 //              }
00573 //
00574 //              if( edge->order_next )
00575 //              {
00576 //                      ASSERT( edge->position_y <= edge->order_next->position_y );
00577 //                      ASSERT( y <= Position_GetRealY(edge->order_next) );
00578 //              }
00579 //
00580 //              edge = edge->order_next;
00581 //      }
00582 //}
00583 //
00584 //#endif
00585 //
00587 //
00588 //void CArEdgeList::Con_Order()
00589 //{
00590 //      order_first = NULL;
00591 //      order_last = NULL;
00592 //}
00593 //
00594 //void CArEdgeList::Des_Order()
00595 //{
00596 //      ASSERT( order_first == NULL && order_last == NULL );
00597 //}
00598 //
00599 //void CArEdgeList::InsertBefore(SArEdge* edge, SArEdge* before)
00600 //{
00601 //      ASSERT( edge != NULL && before != NULL && edge != before );
00602 //      ASSERT( edge->order_next == NULL && edge->order_prev == NULL );
00603 //
00604 //      edge->order_prev = before->order_prev;
00605 //      edge->order_next = before;
00606 //
00607 //      if( before->order_prev )
00608 //      {
00609 //              ASSERT( before->order_prev->order_next == before );
00610 //              before->order_prev->order_next = edge;
00611 //
00612 //              ASSERT( order_first != before );
00613 //      }
00614 //      else
00615 //      {
00616 //              ASSERT( order_first == before );
00617 //              order_first = edge;
00618 //      }
00619 //
00620 //      before->order_prev = edge;
00621 //}
00622 //
00623 //void CArEdgeList::InsertAfter(SArEdge* edge, SArEdge* after)
00624 //{
00625 //      ASSERT( edge != NULL && after != NULL && edge != after );
00626 //      ASSERT( edge->order_next == NULL && edge->order_prev == NULL );
00627 //
00628 //      edge->order_next = after->order_next;
00629 //      edge->order_prev = after;
00630 //
00631 //      if( after->order_next )
00632 //      {
00633 //              ASSERT( after->order_next->order_prev == after );
00634 //              after->order_next->order_prev = edge;
00635 //
00636 //              ASSERT( order_last != after );
00637 //      }
00638 //      else
00639 //      {
00640 //              ASSERT( order_last == after );
00641 //              order_last = edge;
00642 //      }
00643 //
00644 //      after->order_next = edge;
00645 //}
00646 //
00647 //void CArEdgeList::InsertLast(SArEdge* edge)
00648 //{
00649 //      ASSERT( edge != NULL );
00650 //      ASSERT( edge->order_prev == NULL && edge->order_next == NULL );
00651 //
00652 //      edge->order_prev = order_last;
00653 //
00654 //      if( order_last )
00655 //      {
00656 //              ASSERT( order_last->order_next == NULL );
00657 //              ASSERT( order_first != NULL );
00658 //
00659 //              order_last->order_next = edge;
00660 //              order_last = edge;
00661 //      }
00662 //      else
00663 //      {
00664 //              ASSERT( order_first == NULL );
00665 //
00666 //              order_first = edge;
00667 //              order_last = edge;
00668 //      }
00669 //}
00670 //
00671 //void CArEdgeList::Insert(SArEdge* edge)
00672 //{
00673 //      ASSERT( edge != NULL );
00674 //      ASSERT( edge->order_prev == NULL && edge->order_next == NULL );
00675 //
00676 //      float y = edge->position_y;
00677 //      ASSERT( ED_MINCOORD <= y && y <= ED_MAXCOORD );
00678 //
00679 //      SArEdge* insert = order_first;
00680 //      while( insert && insert->position_y < y )
00681 //              insert = insert->order_next;
00682 //
00683 //      if( insert )
00684 //              InsertBefore(edge, insert);
00685 //      else
00686 //              InsertLast(edge);
00687 //}
00688 //
00689 //void CArEdgeList::Remove(SArEdge* edge)
00690 //{
00691 //      ASSERT( edge != NULL );
00692 //
00693 //      if( order_first == edge )
00694 //              order_first = edge->order_next;
00695 //
00696 //      if( edge->order_next )
00697 //              edge->order_next->order_prev = edge->order_prev;
00698 //
00699 //      if( order_last == edge )
00700 //              order_last = edge->order_prev;
00701 //
00702 //      if( edge->order_prev )
00703 //              edge->order_prev->order_next = edge->order_next;
00704 //
00705 //      edge->order_next = NULL;
00706 //      edge->order_prev = NULL;
00707 //}
00708 //
00709 //void CArEdgeList::Delete(SArEdge* edge)
00710 //{
00711 //      ASSERT( edge != NULL );
00712 //
00713 //      Remove(edge);
00714 //      delete edge;
00715 //}
00716 //
00717 //SArEdge* CArEdgeList::SlideButNotPassEdges(SArEdge* edge, float y)
00718 //{
00719 //      ASSERT( edge != NULL );
00720 //      ASSERT( ED_MINCOORD < y && y < ED_MAXCOORD );
00721 //
00722 //#ifdef _DEBUG
00723 //      if( !edge->edge_fixed && ((CArPath*)edge->owner)->IsHighLighted() )
00724 //              ASSERT(true);
00725 //#endif
00726 //
00727 //      float oldy = edge->position_y;
00728 //      ASSERT( ED_MINCOORD < oldy && oldy < ED_MAXCOORD );
00729 //
00730 //      if( oldy == y )
00731 //              return NULL;
00732 //
00733 //      long x1 = edge->position_x1;
00734 //      long x2 = edge->position_x2;
00735 //      SArEdge* ret = NULL;
00736 //
00737 //      SArEdge* insert = edge;
00738 //      if( oldy < y )
00739 //      {
00740 //              while( insert->order_next )
00741 //              {
00742 //                      insert = insert->order_next;
00743 //
00744 //                      if( y < insert->position_y )
00745 //                              break;
00746 //
00747 //                      if( !insert->edge_canpassed && Intersect(x1, x2, insert->position_x1, insert->position_x2 ) )
00748 //                      {
00749 //                              ret = insert;
00750 //                              y = insert->position_y;
00751 //                              break;
00752 //                      }
00753 //              }
00754 //
00755 //              if( edge != insert && insert->order_prev != edge )
00756 //              {
00757 //                      Remove(edge);
00758 //                      InsertBefore(edge, insert);
00759 //              }
00760 //      }
00761 //      else
00762 //      {
00763 //              while( insert->order_prev )
00764 //              {
00765 //                      insert = insert->order_prev;
00766 //
00767 //                      if( y > insert->position_y )
00768 //                              break;
00769 //
00770 //                      if( !insert->edge_canpassed && Intersect(x1, x2, insert->position_x1, insert->position_x2 ) )
00771 //                      {
00772 //                              ret = insert;
00773 //                              y = insert->position_y;
00774 //                              break;
00775 //                      }
00776 //              }
00777 //
00778 //              if( edge != insert && insert->order_next != edge )
00779 //              {
00780 //                      Remove(edge);
00781 //                      InsertAfter(edge, insert);
00782 //              }
00783 //
00784 //      }
00785 //
00786 //#ifdef _DEBUG
00787 //      if( edge->order_next )
00788 //              ASSERT( y <= edge->order_next->position_y );
00789 //
00790 //      if( edge->order_prev )
00791 //              ASSERT( edge->order_prev->position_y <= y );
00792 //#endif
00793 //
00794 //      edge->position_y = y;
00795 //
00796 //      return ret;
00797 //}
00798 //
00799 //#ifdef _DEBUG
00800 //
00801 //void CArEdgeList::AssertValidOrder() const
00802 //{
00803 //      ASSERT( order_first != NULL && order_last != NULL );
00804 //      ASSERT( order_first->order_prev == NULL );
00805 //      ASSERT( order_last->order_next == NULL );
00806 //
00807 //      float y = ED_MINCOORD;
00808 //
00809 //      TRACE("CArEdgeList::AssertValidOrder (horizontal=%d) START\n", ishorizontal);
00810 //
00811 //      SArEdge* edge = order_first;
00812 //      while( edge != order_last )
00813 //      {
00814 //              TRACE("edge=%p, position_y=%f\n", edge, edge->position_y);
00815 //
00816 //              ASSERT( edge != NULL );
00817 //              ASSERT( y <= edge->position_y );
00818 //              ASSERT( edge->order_next->order_prev == edge );
00819 //
00820 //              y = edge->position_y;
00821 //              edge = edge->order_next;
00822 //      }
00823 //
00824 //      TRACE("edge=%p, position_y=%f\n", edge, edge->position_y);
00825 //      TRACE("CArEdgeList::AssertValidOrder (horizontal=%d) END\n", ishorizontal);
00826 //
00827 //      ASSERT( y <= ED_MAXCOORD );
00828 //}
00829 //
00830 //#endif
00831 //
00833 //
00834 //void CArEdgeList::Con_Section()
00835 //{
00836 //      section_first = NULL;
00837 //      section_blocker = NULL;
00838 //      section_ptr2blocked = NULL;
00839 //}
00840 //
00841 //void CArEdgeList::Des_Section()
00842 //{
00843 //      ASSERT( section_blocker == NULL && section_ptr2blocked == NULL );
00844 //}
00845 //
00846 //void CArEdgeList::Section_Reset()
00847 //{
00848 //      ASSERT( section_blocker == NULL && section_ptr2blocked == NULL );
00849 //
00850 //      section_first = NULL;
00851 //}
00852 //
00853 //void CArEdgeList::Section_BeginScan(SArEdge* blocker)
00854 //{
00855 //      ASSERT( section_blocker == NULL && section_ptr2blocked == NULL );
00856 //
00857 //      section_blocker = blocker;
00858 //
00859 //      section_blocker->section_x1 = section_blocker->position_x1;
00860 //      section_blocker->section_x2 = section_blocker->position_x2;
00861 //
00862 //      section_blocker->section_next = NULL;
00863 //      section_blocker->section_down = NULL;
00864 //}
00865 //
00866 //#define section_blocked (*section_ptr2blocked)
00867 //int CArEdgeList::Section_HasBlockedEdge()
00868 //{
00869 //      ASSERT( section_blocker != NULL );
00870 //
00871 //      long b1 = section_blocker->section_x1;
00872 //      long b2 = section_blocker->section_x2;
00873 //      ASSERT( b1 <= b2 );
00874 //
00875 //      if( section_ptr2blocked == NULL )
00876 //      {
00877 //              section_ptr2blocked = &section_first;
00878 //      }
00879 //      else
00880 //      {
00881 //              SArEdge* current_edge = section_blocked;
00882 //
00883 //              ASSERT( current_edge != NULL );
00884 //
00885 //              SArEdge* e = current_edge->section_down;
00886 //              SArEdge* o = NULL;
00887 //
00888 //              long a1 = current_edge->section_x1;
00889 //              long a2 = current_edge->section_x2;
00890 //              ASSERT( a1 <= a2 );
00891 //
00892 //              ASSERT( b1 <= a2 &&  a1 <= b2 );                                                        // not case 1 or 6
00893 //
00894 //              if( a1 < b1 && b2 < a2 )                                                                        // case 3
00895 //              {
00896 //                      section_ptr2blocked = &(current_edge->section_down);
00897 //              }
00898 //              else if( b1 <= a1 && a2 <= b2 )                                                         // case 4
00899 //              {
00900 //                      if( e )
00901 //                      {
00902 //                              while( e->section_next )
00903 //                                      e = e->section_next;
00904 //
00905 //                              e->section_next = current_edge->section_next;
00906 //                              section_blocked = current_edge->section_down;
00907 //                      }
00908 //                      else
00909 //                              section_blocked = current_edge->section_next;
00910 //              }
00911 //              else if( b1 <= a1 && b2 < a2 )                                                          // case 5
00912 //              {
00913 //                      ASSERT( a1 <= b2 );
00914 //
00915 //                      a1 = b2 + 1;
00916 //
00917 //                      while( e && e->section_x1 <= a1 )
00918 //                      {       
00919 //                              ASSERT( e->section_x1 <= e->section_x2 );
00920 //
00921 //                              if( a1 <= e->section_x2 )
00922 //                                      a1 = e->section_x2 + 1;
00923 //
00924 //                              o = e;
00925 //                              e = e->section_next;
00926 //                      }
00927 //
00928 //                      if( o )
00929 //                      {
00930 //                              section_blocked = current_edge->section_down;
00931 //                              o->section_next = current_edge;
00932 //                              current_edge->section_down = e;
00933 //                      }
00934 //
00935 //                      ASSERT( b2 < a1 );
00936 //                      current_edge->section_x1 = a1;
00937 //              }
00938 //              else                                                                                                            // case 2
00939 //              {
00940 //                      ASSERT( a1 < b1 && b1 <= a2 && a2 <= b2 );
00941 //
00942 //                      section_ptr2blocked = &(current_edge->section_down);
00943 //
00944 //                      while( e )
00945 //                      {
00946 //                              o = e;
00947 //                              e = e->section_next;
00948 //
00949 //                              if( o->section_x2 + 1 < b1 && ( e == NULL || o->section_x2 + 1 < e->section_x1 ) )
00950 //                                      section_ptr2blocked = &(o->section_next);
00951 //                      }
00952 //
00953 //                      if( section_blocked )
00954 //                      {
00955 //                              ASSERT( o != NULL );
00956 //                              o->section_next = current_edge->section_next;
00957 //
00958 //                              current_edge->section_x2 = 
00959 //                                      (section_blocked->section_x1 < b1 ? section_blocked->section_x1 : b1) - 1;
00960 //
00961 //                              current_edge->section_next = section_blocked;
00962 //                              section_blocked = NULL;
00963 //                      }
00964 //                      else
00965 //                              current_edge->section_x2 = b1 - 1;
00966 //
00967 //                      section_ptr2blocked = &(current_edge->section_next);
00968 //              }
00969 //      }
00970 //
00971 //      ASSERT( section_ptr2blocked != NULL );
00972 //      while( section_blocked )
00973 //      {
00974 //              long a1 = section_blocked->section_x1;
00975 //              long a2 = section_blocked->section_x2;
00976 //
00977 //              if( a2 < b1 )                                                                                           // case 1
00978 //              {
00979 //                      section_ptr2blocked = &(section_blocked->section_next);
00980 //
00981 //                      ASSERT( section_ptr2blocked != NULL );
00982 //                      continue;
00983 //              }
00984 //              else if( b2 < a1 )                                                                                      // case 6
00985 //                      break;
00986 //              
00987 //              if( a1 < b1 && b2 < a2 )                                                                        // case 3
00988 //              {
00989 //                      long x = b1;
00990 //
00991 //                      SArEdge* e = section_blocked->section_down;
00992 //                      for(;;)
00993 //                      {
00994 //                              if( e == NULL || x < e->section_x1 )
00995 //                                      return 1;
00996 //                              else if( x <= e->section_x2 )
00997 //                              {
00998 //                                      x = e->section_x2 + 1;
00999 //                                      if( b2 < x )
01000 //                                              break;
01001 //                              }
01002 //
01003 //                              e = e->section_next;
01004 //                      }
01005 //
01006 //                      section_ptr2blocked = &(section_blocked->section_down);
01007 //                      continue;
01008 //              }
01009 //
01010 //              return 1;
01011 //      }
01012 //
01013 //      ASSERT( section_blocker->section_next == NULL && section_blocker->section_down == NULL );
01014 //
01015 //      section_blocker->section_next = section_blocked;
01016 //      section_blocked = section_blocker;
01017 //
01018 //      section_blocker = NULL;
01019 //      section_ptr2blocked = NULL;
01020 //
01021 //      return 0;
01022 //}
01023 //#undef section_blocked
01024 //
01025 //SArEdge* CArEdgeList::Section_GetBlockedEdge()
01026 //{
01027 //      ASSERT( section_blocker != NULL && section_ptr2blocked != NULL && *section_ptr2blocked != NULL );
01028 //#ifdef _DEBUG_DEEP
01029 //      AssertValidSection();
01030 //#endif
01031 //
01032 //      return *section_ptr2blocked;
01033 //}
01034 //
01035 //int CArEdgeList::Section_IsImmediate()
01036 //{
01037 //      ASSERT( section_blocker != NULL && section_ptr2blocked != NULL && *section_ptr2blocked != NULL );
01038 //
01039 //      SArEdge* section_blocked = *section_ptr2blocked;
01040 //      SArEdge* e = section_blocked->section_down;
01041 //
01042 //      long a1 = section_blocked->section_x1;
01043 //      long a2 = section_blocked->section_x2;
01044 //      long p1 = section_blocked->position_x1;
01045 //      long p2 = section_blocked->position_x2;
01046 //      long b1 = section_blocker->section_x1;
01047 //      long b2 = section_blocker->section_x2;
01048 //
01049 //      ASSERT( b1 <= a2 && a1 <= b2 );                                                                 // not case 1 or 6
01050 //
01051 //      // NOTE WE CHANGED THE CONDITIONS (A1<=B1 AND B2<=A2)
01052 //      // BECAUSE HERE WE NEED THIS!
01053 //
01054 //      if( a1 <= b1 )
01055 //      {
01056 //              while( e != NULL && e->section_x2 < b1 )
01057 //                      e = e->section_next;
01058 //
01059 //              if( b2 <= a2 )
01060 //                      return e == NULL || b2 < e->section_x1;                                 // case 3
01061 //                      
01062 //              return e == NULL && a2 == p2;                                                           // case 2
01063 //      }
01064 //
01065 //      if( b2 <= a2 )
01066 //              return a1 == p1 && (e == NULL || b2 < e->section_x1);           // case 5
01067 //
01068 //      return e == NULL && a1 == p1 && a2 == p2;                                               // case 4
01069 //}
01070 //
01071 //#ifdef _DEBUG
01072 //
01073 //void CArEdgeList::Section_AssertLevel(SArEdge* level, long x1, long x2) const
01074 //{
01075 //      while( level )
01076 //      {
01077 //              ASSERT( level->position_x1 <= level->section_x1 && level->section_x2 <= level->position_x2 );
01078 //              ASSERT( x1 < level->section_x1 && level->section_x1 <= level->section_x2 && level->section_x2 < x2 );
01079 //              ASSERT( level->section_next == NULL || level->section_x2 < level->section_next->section_x1 );
01080 //
01081 //              Section_AssertLevel(level->section_down, level->section_x1, level->section_x2);
01082 //
01083 //              level = level->section_next;
01084 //      }
01085 //}
01086 //
01087 //void CArEdgeList::AssertValidSection() const
01088 //{
01089 //      Section_AssertLevel(section_first, ED_MINCOORD-1, ED_MAXCOORD+1);
01090 //}
01091 //
01092 //void CArEdgeList::AssertSectionReady() const
01093 //{
01094 //      ASSERT( section_blocker == NULL && section_ptr2blocked == NULL );
01095 //}
01096 //
01097 //#endif
01098 //
01100 //
01101 //int CArEdgeList::Bracket_IsClosing(const SArEdge* edge) const
01102 //{
01103 //      ASSERT( edge != NULL && edge->startpoint != NULL && edge->endpoint != NULL );
01104 //
01105 //      return IsClosingBracket(edge->startpoint_prev, edge->startpoint, edge->endpoint, edge->endpoint_next, ishorizontal);
01106 //}
01107 //
01108 //int CArEdgeList::Bracket_IsOpening(const SArEdge* edge) const
01109 //{
01110 //      ASSERT( edge != NULL && edge->startpoint != NULL && edge->endpoint != NULL );
01111 //
01112 //      return IsOpeningBracket(edge->startpoint_prev, edge->startpoint, edge->endpoint, edge->endpoint_next, ishorizontal);
01113 //}
01114 //
01115 //int CArEdgeList::Bracket_IsSmallGap(const SArEdge* blocked, const SArEdge* blocker) const
01116 //{
01117 //      return Bracket_IsOpening(blocked) || Bracket_IsClosing(blocker);
01118 //}
01119 //
01120 //int CArEdgeList::Bracket_ShouldBeSwitched(const SArEdge* edge, const SArEdge* next) const
01121 //{
01122 //      ASSERT( edge != NULL && next != NULL );
01123 //
01124 //      long ex1, ex2, eo1, eo2;
01125 //      Position_GetRealX(edge, ex1, ex2);
01126 //      Position_GetRealO(edge, eo1, eo2);
01127 //
01128 //      long nx1, nx2, no1, no2;
01129 //      Position_GetRealX(next, nx1, nx2);
01130 //      Position_GetRealO(next, no1, no2);
01131 //
01132 //      int c1, c2;
01133 //
01134 //      if( (nx1 < ex1 && ex1 < nx2 && eo1 > 0 ) || (ex1 < nx1 && nx1 < ex2 && no1 < 0) )
01135 //              c1 = +1;
01136 //      else if( ex1 == nx1 && eo1 == 0 && no1 == 0 )
01137 //              c1 = 0;
01138 //      else
01139 //              c1 = -9;
01140 //
01141 //      if( (nx1 < ex2 && ex2 < nx2 && eo2 > 0 ) || (ex1 < nx2 && nx2 < ex2 && no2 < 0) )
01142 //              c2 = +1;
01143 //      else if( ex2 == nx2 && eo2 == 0 && no2 == 0 )
01144 //              c2 = 0;
01145 //      else
01146 //              c2 = -9;
01147 //
01148 //      return (c1 + c2) > 0;
01149 //}
01150 //
01152 //
01153 //#define FLT_EQU(A,B)  (((A) - 0.1F < (B)) && ((B) < (A) + 0.1F))
01154 //
01155 //#define S EDLS_S
01156 //#define R EDLS_R
01157 //#define D EDLS_D
01158 //
01159 //inline float Block_GetF(float d, int b, int s)
01160 //{
01161 //      float f = d/(b+s);
01162 //
01163 //      if( b == 0 && R <= f )
01164 //              f += (D-R);
01165 //      else if( S < f && s > 0 )
01166 //              f = ((D-S)*d - S*(D-R)*s) / ((D-S)*b + (R-S)*s);
01167 //
01168 //      return f;
01169 //}
01170 //
01171 //inline float Block_GetG(float d, int b, int s)
01172 //{
01173 //      float g = d/(b+s);
01174 //
01175 //      if( S < g && b > 0 )
01176 //              g = ((R-S)*d + S*(D-R)*b) / ((D-S)*b + (R-S)*s);
01177 //
01178 //      return g;
01179 //}
01180 //
01181 //#undef S
01182 //#undef R
01183 //#undef D
01184 //
01185 //int CArEdgeList::Block_PushBackward(SArEdge* blocked, SArEdge* blocker)
01186 //{
01187 //      int modified = 0;
01188 //
01189 //      ASSERT( blocked != NULL && blocker != NULL );
01190 //      ASSERT( blocked->position_y <= blocker->position_y );
01191 //      ASSERT( blocked->block_prev != NULL );
01192 //
01193 //      float f = 0;
01194 //      float g = 0;
01195 //
01196 //      SArEdge* edge = blocked;
01197 //      SArEdge* trace = blocker;
01198 //
01199 //      float d = trace->position_y - edge->position_y;
01200 //      ASSERT( d >= 0 );
01201 //
01202 //      int s = (edge->bracket_opening || trace->bracket_closing);
01203 //      int b = 1 - s;
01204 //
01205 //      for(;;)
01206 //      {
01207 //              edge->block_trace = trace;
01208 //              trace = edge;
01209 //              edge = edge->block_prev;
01210 //
01211 //              if( edge == NULL )
01212 //                      break;
01213 //
01214 //              float d2 = trace->position_y - edge->position_y;
01215 //              ASSERT( d2 >= 0 );
01216 //
01217 //              if( edge->bracket_opening || trace->bracket_closing )
01218 //              {
01219 //                      g = Block_GetG(d,b,s);
01220 //                      if( d2 <= g )
01221 //                      {
01222 //                              f = Block_GetF(d,b,s);
01223 //                              break;
01224 //                      }
01225 //                      s++;
01226 //              }
01227 //              else
01228 //              {
01229 //                      f = Block_GetF(d,b,s);
01230 //                      if( d2 <= f )
01231 //                      {
01232 //                              g = Block_GetG(d,b,s);
01233 //                              break;
01234 //                      }
01235 //                      b++;
01236 //              }
01237 //
01238 //              d += d2;
01239 //      }
01240 //
01241 //      if( b+s > 1 )
01242 //      {
01243 //              if( edge == NULL )
01244 //              {
01245 //                      f = Block_GetF(d,b,s);
01246 //                      g = Block_GetG(d,b,s);
01247 //              }
01248 //
01249 //              ASSERT( FLT_EQU(d, f*b + g*s) );
01250 //
01251 //              edge = trace;
01252 //              ASSERT( edge != NULL && edge != blocked );
01253 //
01254 //              float y = edge->position_y;
01255 //
01256 //              do
01257 //              {
01258 //                      ASSERT( edge != NULL && edge->block_trace != NULL );
01259 //                      trace = edge->block_trace;
01260 //
01261 //                      y += (edge->bracket_opening || trace->bracket_closing) ? g : f;
01262 //
01263 //                      if( y + 0.001F < trace->position_y )
01264 //                      {
01265 //                              modified = 1;
01266 //                              if( SlideButNotPassEdges(trace, y) )
01267 //                                      trace->block_prev = NULL;
01268 //                      }
01269 //
01270 //                      edge = trace;
01271 //              } while( edge != blocked );
01272 //#ifdef _DEBUG
01273 //              y += (edge->bracket_opening || blocker->bracket_closing) ? g : f;
01274 //              ASSERT( FLT_EQU(y, blocker->position_y) );
01275 //#endif
01276 //      }
01277 //
01278 //      return modified;
01279 //}
01280 //
01281 //int CArEdgeList::Block_PushForward(SArEdge* blocked, SArEdge* blocker)
01282 //{
01283 //      int modified = 0;
01284 //
01285 //      ASSERT( blocked != NULL && blocker != NULL );
01286 //      ASSERT( blocked->position_y >= blocker->position_y );
01287 //      ASSERT( blocked->block_next != NULL );
01288 //
01289 //      float f = 0;
01290 //      float g = 0;
01291 //
01292 //      SArEdge* edge = blocked;
01293 //      SArEdge* trace = blocker;
01294 //
01295 //      float d = edge->position_y - trace->position_y;
01296 //      ASSERT( d >= 0 );
01297 //
01298 //      int s = (trace->bracket_opening || edge->bracket_closing);
01299 //      int b = 1 - s;
01300 //
01301 //      for(;;)
01302 //      {
01303 //              edge->block_trace = trace;
01304 //              trace = edge;
01305 //              edge = edge->block_next;
01306 //
01307 //              if( edge == NULL )
01308 //                      break;
01309 //
01310 //              float d2 = edge->position_y - trace->position_y;
01311 //              ASSERT( d2 >= 0 );
01312 //
01313 //              if( trace->bracket_opening || edge->bracket_closing )
01314 //              {
01315 //                      g = Block_GetG(d,b,s);
01316 //                      if( d2 <= g )
01317 //                      {
01318 //                              f = Block_GetF(d,b,s);
01319 //                              break;
01320 //                      }
01321 //                      s++;
01322 //              }
01323 //              else
01324 //              {
01325 //                      f = Block_GetF(d,b,s);
01326 //                      if( d2 <= f )
01327 //                      {
01328 //                              g = Block_GetG(d,b,s);
01329 //                              break;
01330 //                      }
01331 //                      b++;
01332 //              }
01333 //
01334 //              d += d2;
01335 //      }
01336 //
01337 //      if( b+s > 1 )
01338 //      {
01339 //              if( edge == NULL )
01340 //              {
01341 //                      f = Block_GetF(d,b,s);
01342 //                      g = Block_GetG(d,b,s);
01343 //              }
01344 //
01345 //              ASSERT( FLT_EQU(d, f*b + g*s) );
01346 //
01347 //              edge = trace;
01348 //              ASSERT( edge != NULL && edge != blocked );
01349 //
01350 //              float y = edge->position_y;
01351 //
01352 //              do
01353 //              {
01354 //                      ASSERT( edge != NULL && edge->block_trace != NULL );
01355 //                      trace = edge->block_trace;
01356 //
01357 //                      y -= (trace->bracket_opening || edge->bracket_closing) ? g : f;
01358 //
01359 //                      if( trace->position_y < y - 0.001F )
01360 //                      {
01361 //                              modified = 1;
01362 //                              if( SlideButNotPassEdges(trace, y) )
01363 //                                      trace->block_next = NULL;
01364 //                      }
01365 //
01366 //                      edge = trace;
01367 //              } while( edge != blocked );
01368 //#ifdef _DEBUG
01369 //              y -= (blocker->bracket_opening || edge->bracket_closing) ? g : f;
01370 //              ASSERT( FLT_EQU(y, blocker->position_y) );
01371 //#endif
01372 //      }
01373 //
01374 //      return modified;
01375 //}
01376 //
01377 //int CArEdgeList::Block_ScanForward()
01378 //{
01379 //#ifdef _DEBUG_DEEP
01380 //      AssertValidOrder();
01381 //      AssertSectionReady();
01382 //      AssertValidPositions();
01383 //#endif
01384 //
01385 //      PositionAll_LoadX();
01386 //
01387 //      int modified = 0;
01388 //
01389 //      Section_Reset();
01390 //      SArEdge* blocker = order_first;
01391 //      while( blocker )
01392 //      {
01393 //              SArEdge* bmin = NULL;
01394 //              SArEdge* smin = NULL;
01395 //              float bmin_f = ED_MINCOORD - 1;
01396 //              float smin_f = ED_MINCOORD - 1;
01397 //
01398 //              Section_BeginScan(blocker);
01399 //              while( Section_HasBlockedEdge() ) if( Section_IsImmediate() )
01400 //              {
01401 //                      SArEdge* blocked = Section_GetBlockedEdge();
01402 //                      ASSERT( blocked != NULL );
01403 //
01404 //                      if( blocked->block_prev != NULL )
01405 //                              modified |= Block_PushBackward(blocked, blocker);
01406 //
01407 //                      if( !blocker->edge_fixed )
01408 //                      {
01409 //                              if( blocked->bracket_opening || blocker->bracket_closing )
01410 //                              {
01411 //                                      if( smin_f < blocked->position_y )
01412 //                                      {
01413 //                                              smin_f = blocked->position_y;
01414 //                                              smin = blocked;
01415 //                                      }
01416 //                              }
01417 //                              else
01418 //                              {
01419 //                                      if( bmin_f < blocked->position_y )
01420 //                                      {
01421 //                                              bmin_f = blocked->position_y;
01422 //                                              bmin = blocked;
01423 //                                      }
01424 //                              }
01425 //                      }
01426 //              }
01427 //
01428 //              if( bmin )
01429 //              {
01430 //                      if( smin )
01431 //                      {
01432 //                              blocker->closest_prev = smin_f > bmin_f ? smin : bmin;
01433 //
01434 //                              bmin_f = blocker->position_y - bmin_f;
01435 //                              smin_f = Block_GetF(blocker->position_y - smin_f, 0, 1);
01436 //
01437 //                              blocker->block_prev = smin_f < bmin_f ? smin : bmin;
01438 //                      }
01439 //                      else
01440 //                      {
01441 //                              blocker->block_prev = bmin;
01442 //                              blocker->closest_prev = bmin;
01443 //                      }
01444 //              }
01445 //              else
01446 //              {
01447 //                      blocker->block_prev = smin;
01448 //                      blocker->closest_prev = smin;
01449 //              }
01450 //
01451 //#ifdef _DEBUG
01452 //              if( !blocker->edge_fixed && ((CArPath*)blocker->owner)->IsHighLighted() )
01453 //                      break;
01454 //#endif
01455 //
01456 //              blocker = blocker->order_next;
01457 //      }
01458 //
01459 //      PositionAll_StoreY();
01460 //
01461 //#ifdef _DEBUG_DEEP
01462 //      AssertValidOrder();
01463 //      AssertSectionReady();
01464 //      AssertValidPositions();
01465 //#endif
01466 //
01467 //      return modified;
01468 //}
01469 //
01470 //int CArEdgeList::Block_ScanBackward()
01471 //{
01472 //#ifdef _DEBUG_DEEP
01473 //      AssertValidOrder();
01474 //      AssertSectionReady();
01475 //      AssertValidPositions();
01476 //#endif
01477 //
01478 //      PositionAll_LoadX();
01479 //
01480 //      int modified = 0;
01481 //
01482 //      Section_Reset();
01483 //      SArEdge* blocker = order_last;
01484 //      while( blocker )
01485 //      {
01486 //              SArEdge* bmin = NULL;
01487 //              SArEdge* smin = NULL;
01488 //              float bmin_f = ED_MAXCOORD + 1;
01489 //              float smin_f = ED_MAXCOORD + 1;
01490 //
01491 //              Section_BeginScan(blocker);
01492 //              while( Section_HasBlockedEdge() ) if( Section_IsImmediate() )
01493 //              {
01494 //                      SArEdge* blocked = Section_GetBlockedEdge();
01495 //                      ASSERT( blocked != NULL );
01496 //
01497 //                      if( blocked->block_next != NULL )
01498 //                              modified |= Block_PushForward(blocked, blocker);
01499 //
01500 //                      if( !blocker->edge_fixed )
01501 //                      {
01502 //                              if( blocker->bracket_opening || blocked->bracket_closing )
01503 //                              {
01504 //                                      if( smin_f > blocked->position_y )
01505 //                                      {
01506 //                                              smin_f = blocked->position_y;
01507 //                                              smin = blocked;
01508 //                                      }
01509 //                              }
01510 //                              else
01511 //                              {
01512 //                                      if( bmin_f > blocked->position_y )
01513 //                                      {
01514 //                                              bmin_f = blocked->position_y;
01515 //                                              bmin = blocked;
01516 //                                      }
01517 //                              }
01518 //                      }
01519 //              }
01520 //
01521 //              if( bmin )
01522 //              {
01523 //                      if( smin )
01524 //                      {
01525 //                              blocker->closest_next = smin_f < bmin_f ? smin : bmin;
01526 //
01527 //                              bmin_f = bmin_f - blocker->position_y;
01528 //                              smin_f = Block_GetF(smin_f - blocker->position_y, 0, 1);
01529 //
01530 //                              blocker->block_next = smin_f < bmin_f ? smin : bmin;
01531 //                      }
01532 //                      else
01533 //                      {
01534 //                              blocker->block_next = bmin;
01535 //                              blocker->closest_next = bmin;
01536 //                      }
01537 //              }
01538 //              else
01539 //              {
01540 //                      blocker->block_next = smin;
01541 //                      blocker->closest_next = smin;
01542 //              }
01543 //
01544 //#ifdef _DEBUG
01545 //              if( !blocker->edge_fixed && ((CArPath*)blocker->owner)->IsHighLighted() )
01546 //                      break;
01547 //#endif
01548 //
01549 //              blocker = blocker->order_prev;
01550 //      }
01551 //
01552 //      PositionAll_StoreY();
01553 //
01554 //#ifdef _DEBUG_DEEP
01555 //      AssertValidOrder();
01556 //      AssertSectionReady();
01557 //      AssertValidPositions();
01558 //#endif
01559 //
01560 //      return modified;
01561 //}
01562 //
01563 //int CArEdgeList::Block_SwitchWrongs()
01564 //{
01565 //      int was = 0;
01566 //
01567 //      PositionAll_LoadX();
01568 //
01569 //      SArEdge* second = order_first;
01570 //      while( second != NULL )
01571 //      {
01572 //              if( second->closest_prev != NULL && second->closest_prev->closest_next != second &&
01573 //                      second->closest_next != NULL && second->closest_next->closest_prev == second )
01574 //                      
01575 //              {
01576 //                      ASSERT( !second->edge_fixed );
01577 //
01578 //                      SArEdge* edge = second;
01579 //                      SArEdge* next = edge->closest_next;
01580 //
01581 //                      while( next != NULL && edge == next->closest_prev )
01582 //                      {
01583 //                              ASSERT( edge != NULL && !edge->edge_fixed );
01584 //                              ASSERT( next != NULL && !next->edge_fixed );
01585 //
01586 //                              float ey = edge->position_y;
01587 //                              float ny = next->position_y;
01588 //
01589 //                              ASSERT( ey <= ny );
01590 //
01591 //                              if( ey + 1 <= ny && Bracket_ShouldBeSwitched(edge, next) )
01592 //                              {
01593 //                                      was = 1;
01594 //
01595 //                                      ASSERT( !edge->edge_canpassed && !next->edge_canpassed );
01596 //                                      edge->edge_canpassed = 1;
01597 //                                      next->edge_canpassed = 1;
01598 //
01599 //                                      int a = SlideButNotPassEdges(edge, (ny+ey)/2 + 0.001F) != NULL;
01600 //                                      a |= SlideButNotPassEdges(next, (ny+ey)/2 - 0.001F) != NULL;
01601 //
01602 //                                      if( a )
01603 //                                      {
01604 //                                              edge->closest_prev = NULL;
01605 //                                              edge->closest_next = NULL;
01606 //                                              next->closest_prev = NULL;
01607 //                                              next->closest_next = NULL;
01608 //
01609 //                                              edge->edge_canpassed = 0;
01610 //                                              next->edge_canpassed = 0;
01611 //                                              break;
01612 //                                      }
01613 //
01614 //                                      if( edge->closest_prev != NULL && edge->closest_prev->closest_next == edge )
01615 //                                              edge->closest_prev->closest_next = next;
01616 //
01617 //                                      if( next->closest_next != NULL && next->closest_next->closest_prev == next)
01618 //                                              next->closest_next->closest_prev = edge;
01619 //
01620 //                                      edge->closest_next = next->closest_next;
01621 //                                      next->closest_next = edge;
01622 //                                      next->closest_prev = edge->closest_prev;
01623 //                                      edge->closest_prev = next;
01624 //
01625 //                                      edge->edge_canpassed = 0;
01626 //                                      next->edge_canpassed = 0;
01627 //
01628 //                                      ASSERT( !Bracket_ShouldBeSwitched(next, edge) );
01629 //
01630 //                                      if( next->closest_prev != NULL && next->closest_prev->closest_next == next )
01631 //                                              edge = next->closest_prev;
01632 //                                      else
01633 //                                              next = edge->closest_next;
01634 //                              }
01635 //                              else
01636 //                              {
01637 //                                      edge = next;
01638 //                                      next = next->closest_next;
01639 //                              }
01640 //                      }
01641 //              }
01642 //
01643 //              second = second->order_next;
01644 //      }
01645 //
01646 //      if( was )
01647 //              PositionAll_StoreY();
01648 //
01649 //      return was;
01650 //}
01651 //