GME  13
AutoRouterPort.cpp
Go to the documentation of this file.
00001 // AutoRouterPort.cpp : Implementation of CAutoRouterPort
00002 #include "stdafx.h"
00003 #include "AutoRouterPort.h"
00004 #include "AutoRouterBox.h"
00005 
00006 
00007 CAutoRouterPort::CAutoRouterPort():     owner(NULL),
00008                                                                         limitedDirections( false),
00009                                                                         rect(0,0,0,0),
00010                                                                         attributes(ARPORT_Default)
00011 {
00012         CalculateSelfPoints();
00013 }
00014 
00015 CAutoRouterPort::~CAutoRouterPort()
00016 {
00017         this->SetOwner(NULL);
00018 }
00019 
00020 // Private methods
00021 
00022 // --- Data
00023 
00024 void CAutoRouterPort::CalculateSelfPoints()
00025 {
00026         selfpoints[0].x = rect.left;
00027         selfpoints[0].y = rect.top;
00028 
00029         selfpoints[1].x = rect.right - 1;
00030         selfpoints[1].y = rect.top;
00031 
00032         selfpoints[2].x = rect.right - 1;
00033         selfpoints[2].y = rect.bottom - 1;
00034 
00035         selfpoints[3].x = rect.left;
00036         selfpoints[3].y = rect.bottom - 1;
00037 }
00038 
00039 CAutoRouterBox* CAutoRouterPort::GetOwner(void) const
00040 {
00041         return owner;
00042 }
00043 
00044 bool CAutoRouterPort::HasOwner(void) const
00045 {
00046         return owner != NULL;
00047 }
00048 
00049 void CAutoRouterPort::SetOwner(CAutoRouterBox* box)
00050 {
00051         owner = box;
00052 }
00053 
00054 CRect CAutoRouterPort::GetRect(void) const
00055 {
00056         return rect;
00057 }
00058 
00059 bool CAutoRouterPort::IsRectEmpty(void) const
00060 {
00061         return rect.IsRectEmpty() == TRUE;
00062 }
00063 
00064 CPoint CAutoRouterPort::GetCenter(void) const
00065 {
00066         return rect.CenterPoint();
00067 }
00068 
00069 void CAutoRouterPort::SetRect(const CRect& r)
00070 {
00071         ASSERT( r.Width() >= 3 && r.Height() >= 3 );
00072 
00073         rect = r;
00074         CalculateSelfPoints();
00075 }
00076 
00077 void CAutoRouterPort::ShiftBy(const CPoint& offset)
00078 {
00079         ASSERT( !rect.IsRectEmpty() );
00080 
00081         rect += offset;
00082 
00083         CalculateSelfPoints();
00084 }
00085 
00086 CPoint* CAutoRouterPort::GetSelfPoints(void) const
00087 {
00088         return (CPoint*)selfpoints;
00089 }
00090 
00091 long CAutoRouterPort::GetAttributes(void) const
00092 {
00093         return attributes;
00094 }
00095 
00096 void CAutoRouterPort::SetAttributes(long attr)
00097 {
00098         attributes = (unsigned int)attr;
00099 }
00100 
00101 bool CAutoRouterPort::IsConnectToCenter(void) const
00102 {
00103         return ((attributes & ARPORT_ConnectToCenter) != 0);
00104 }
00105 
00106 bool CAutoRouterPort::HasLimitedDirs(void) const
00107 {
00108         return limitedDirections;
00109 }
00110 
00111 void CAutoRouterPort::SetLimitedDirs(bool ltd)
00112 {
00113         limitedDirections = ltd;
00114 }
00115 
00116 bool CAutoRouterPort::IsPortAt(const CPoint& point, long nearness) const
00117 {
00118         return IsPointIn(point, rect, nearness);
00119 }
00120 
00121 bool CAutoRouterPort::IsPortClip(const CRect& r) const
00122 {
00123         return IsRectClip(rect, r);
00124 }
00125 
00126 bool CAutoRouterPort::IsPortIn(const CRect& r) const
00127 {
00128         return IsRectIn(rect, r);
00129 }
00130 
00131 RoutingDirection CAutoRouterPort::OnWhichEdge(const CPoint& p) const
00132 {
00133         return ::OnWhichEdge(rect, p);
00134 }
00135 
00136 bool CAutoRouterPort::CanHaveStartEndPointOn(RoutingDirection dir, bool isStart) const
00137 {
00138         int d = (int) dir;
00139         ASSERT( 0 <= d && d <= 3 );
00140 
00141         if( isStart )
00142                 d += 4;
00143 
00144         return ((attributes & (1 << d)) != 0);
00145 }
00146 
00147 bool CAutoRouterPort::CanHaveStartEndPoint(bool isStart) const
00148 {
00149         return ((attributes & (isStart ? ARPORT_StartOnAll : ARPORT_EndOnAll)) != 0);
00150 }
00151 
00152 bool CAutoRouterPort::CanHaveStartEndPointHorizontal(bool ishorizontal) const
00153 {
00154         return ((attributes & (ishorizontal ? ARPORT_StartEndHorizontal : ARPORT_StartEndVertical)) != 0);
00155 }
00156 
00157 RoutingDirection CAutoRouterPort::GetStartEndDirTo(const CPoint& point, bool isStart, RoutingDirection notthis) const
00158 {
00159         ASSERT( !rect.IsRectEmpty() );
00160 
00161         CSize offset = point - rect.CenterPoint();
00162 
00163         bool canHave = false;
00164 
00165         RoutingDirection dir1 = GetMajorDir(offset);
00166 
00167         if (dir1 != notthis && CanHaveStartEndPointOn(dir1, isStart))
00168                 return dir1;
00169 
00170         RoutingDirection dir2 = GetMinorDir(offset);
00171 
00172         if (dir2 != notthis && CanHaveStartEndPointOn(dir2, isStart))
00173                 return dir2;
00174 
00175         RoutingDirection dir3 = ReverseDir(dir2);
00176 
00177         if (dir3 != notthis && CanHaveStartEndPointOn(dir3, isStart))
00178                 return dir3;
00179 
00180         RoutingDirection dir4 = ReverseDir(dir1);
00181 
00182         if (dir4 != notthis && CanHaveStartEndPointOn(dir4, isStart))
00183                 return dir4;
00184 
00185         if (CanHaveStartEndPointOn(dir1, isStart))
00186                 return dir1;
00187 
00188         if (CanHaveStartEndPointOn(dir2, isStart))
00189                 return dir2;
00190 
00191         if (CanHaveStartEndPointOn(dir3, isStart))
00192                 return dir3;
00193 
00194         if (CanHaveStartEndPointOn(dir4, isStart))
00195                 return dir4;
00196 
00197         return Dir_Top;
00198 }
00199 
00200 bool CAutoRouterPort::CanCreateStartEndPointAt(const CPoint& point, bool isStart, long nearness) const
00201 {
00202         return CanHaveStartEndPoint(isStart) && IsPointIn(point, rect, nearness);
00203 }
00204 
00205 CPoint CAutoRouterPort::CreateStartEndPointAt(const CPoint& p, bool isStart) const
00206 {
00207         ASSERT( !rect.IsRectEmpty() );
00208 
00209         CPoint point = p;
00210 
00211         RoutingDirection dir = Dir_None;
00212 
00213         CArFindNearestLine nearest(point);
00214 
00215         VARIANT_BOOL canHave = VARIANT_FALSE;
00216 
00217         if (CanHaveStartEndPointOn(Dir_Top, isStart) && nearest.HLine(rect.left, rect.right - 1, rect.top))
00218                 dir = Dir_Top;
00219 
00220         if (CanHaveStartEndPointOn(Dir_Right, isStart) && nearest.VLine(rect.top, rect.bottom - 1, rect.right - 1))
00221                 dir = Dir_Right;
00222 
00223         if (CanHaveStartEndPointOn(Dir_Bottom, isStart) && nearest.HLine(rect.left, rect.right - 1, rect.bottom - 1))
00224                 dir = Dir_Bottom;
00225 
00226         if (CanHaveStartEndPointOn(Dir_Left, isStart) && nearest.VLine(rect.top, rect.bottom - 1, rect.left))
00227                 dir = Dir_Left;
00228 
00229         ASSERT( IsRightAngle(dir) );
00230 
00231         if (IsConnectToCenter())
00232                 return CreateStartEndPointOn(dir);
00233 
00234         if( point.x < rect.left )
00235                 point.x = rect.left;
00236         else if( rect.right <= point.x )
00237                 point.x = rect.right - 1;
00238 
00239         if( point.y < rect.top )
00240                 point.y = rect.top;
00241         else if( rect.bottom <= point.y )
00242                 point.y = rect.bottom - 1;
00243 
00244         switch(dir)
00245         {
00246         case Dir_Top:
00247                 point.y = rect.top;
00248                 break;
00249 
00250         case Dir_Right:
00251                 point.x = rect.right - 1;
00252                 break;
00253 
00254         case Dir_Bottom:
00255                 point.y = rect.bottom - 1;
00256                 break;
00257 
00258         case Dir_Left:
00259                 point.x = rect.left;
00260                 break;
00261         }
00262 
00263         return point;
00264 }
00265 
00266 static inline LONG RoundToHalfGrid(LONG left, LONG right)
00267 {
00268         return ((right + left) / 2) / GME_GRID_SIZE * GME_GRID_SIZE + (GME_GRID_SIZE / 2);
00269 }
00270 
00271 CPoint CAutoRouterPort::CreateStartEndPointOn(RoutingDirection dir) const
00272 {
00273         ASSERT( !rect.IsRectEmpty() );
00274         ASSERT( IsRightAngle(dir) );
00275 
00276         switch( dir )
00277         {
00278         case Dir_Top:
00279                 return CPoint(RoundToHalfGrid(rect.left, rect.right), rect.top);
00280 
00281         case Dir_Bottom:
00282                 return CPoint(RoundToHalfGrid(rect.left, rect.right), rect.bottom - 1);
00283 
00284         case Dir_Left:
00285                 return CPoint(rect.left, RoundToHalfGrid(rect.top, rect.bottom));
00286         }
00287 
00288         return CPoint(rect.right - 1, RoundToHalfGrid(rect.top, rect.bottom));
00289 }
00290 
00291 CPoint CAutoRouterPort::CreateStartEndPointTo(const CPoint& point, bool isStart) const
00292 {
00293         RoutingDirection dir = GetStartEndDirTo(point, isStart, Dir_None);
00294         return CreateStartEndPointOn(dir);
00295 }
00296 
00297 #ifdef _DEBUG
00298 void CAutoRouterPort::AssertValid() const
00299 {
00300 }
00301 
00302 void CAutoRouterPort::AssertValidStartEndPoint(const CPoint& point, RoutingDirection dir, bool isStart)
00303 {
00304         ASSERT( !rect.IsRectEmpty() );
00305 
00306         RoutingDirection comDir = OnWhichEdge(point);
00307         if( dir == Dir_None )
00308         {
00309                 dir = comDir;
00310                 ASSERT( IsRightAngle(dir) );
00311         }
00312         else
00313         {
00314                 ASSERT( dir == comDir );
00315         }
00316 
00317         ASSERT( CanHaveStartEndPointOn(dir, isStart) );
00318 }
00319 #endif