GME
13
|
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