You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

679 lines
21 KiB

  1. /****************************************************/
  2. /* Edition des pistes */
  3. /* Routines de duplication et deplacement de pistes */
  4. /****************************************************/
  5. #include "fctsys.h"
  6. #include "gr_basic.h"
  7. #include "common.h"
  8. #include "pcbnew.h"
  9. #include "autorout.h"
  10. #include "drag.h"
  11. #include "protos.h"
  12. /* Routines externes */
  13. static void Show_MoveTrack( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
  14. static void Exit_MoveTrack( WinEDA_DrawPanel* Panel, wxDC* DC );
  15. #if 0
  16. /* Routines Locales */
  17. static void Duplic_Track( COMMAND* Cmd );
  18. static void Place_Dupl_Route( COMMAND* Cmd );
  19. #endif
  20. /* variables locales */
  21. static wxPoint PosInit, LastPos;
  22. static TRACK* NewTrack; /* Nouvelle piste creee ou piste deplacee */
  23. static int NbPtNewTrack;
  24. static int Old_HightLigth_NetCode;
  25. static bool Old_HightLigt_Status;
  26. /**************************************************************/
  27. static void Exit_MoveTrack( WinEDA_DrawPanel* Panel, wxDC* DC )
  28. /***************************************************************/
  29. /* routine d'annulation de la commande drag, copy ou move track si une piste est en cours
  30. * de tracage, ou de sortie de l'application EDITRACK.
  31. * Appel par la touche ESC
  32. */
  33. {
  34. TRACK* NextS;
  35. int ii;
  36. /* Effacement du trace en cours */
  37. wxPoint oldpos = Panel->GetScreen()->m_Curseur;
  38. Panel->GetScreen()->m_Curseur = PosInit;
  39. Panel->ManageCurseur( Panel, DC, TRUE );
  40. Panel->GetScreen()->m_Curseur = oldpos;
  41. g_HightLigt_Status = FALSE;
  42. ( (WinEDA_PcbFrame*) Panel->m_Parent )->DrawHightLight( DC, g_HightLigth_NetCode );
  43. if( NewTrack )
  44. {
  45. if( NewTrack->m_Flags & IS_NEW )
  46. {
  47. for( ii = 0; ii < NbPtNewTrack; ii++, NewTrack = NextS )
  48. {
  49. if( NewTrack == NULL )
  50. break;
  51. NextS = (TRACK*) NewTrack->Pnext;
  52. delete NewTrack;
  53. }
  54. }
  55. else /* Move : remise en ancienne position */
  56. {
  57. TRACK* Track = NewTrack;
  58. int dx = LastPos.x - PosInit.x;
  59. int dy = LastPos.y - PosInit.y;
  60. for( ii = 0; ii < NbPtNewTrack; ii++, Track = (TRACK*) Track->Pnext )
  61. {
  62. if( Track == NULL )
  63. break;
  64. Track->m_Start.x -= dx;
  65. Track->m_Start.y -= dy;
  66. Track->m_End.x -= dx;
  67. Track->m_End.y -= dy;
  68. Track->m_Flags = 0;
  69. }
  70. Trace_Une_Piste( Panel, DC, NewTrack, NbPtNewTrack, GR_OR );
  71. }
  72. NewTrack = NULL;
  73. }
  74. Panel->ManageCurseur = NULL;
  75. Panel->ForceCloseManageCurseur = NULL;
  76. Panel->SetCurItem( NULL );
  77. // Panel->m_Parent->EraseMsgBox(); SeCurItem() does this
  78. /* Annulation deplacement et Redessin des segments dragges */
  79. DRAG_SEGM* pt_drag = g_DragSegmentList;
  80. for( ; pt_drag != NULL; pt_drag = pt_drag->Pnext )
  81. {
  82. TRACK* Track = pt_drag->m_Segm;
  83. pt_drag->SetInitialValues();
  84. Track->SetState( EDIT, OFF );
  85. Track->ClearFlags();
  86. Track->Draw( Panel, DC, GR_OR );
  87. }
  88. g_HightLigth_NetCode = Old_HightLigth_NetCode;
  89. g_HightLigt_Status = Old_HightLigt_Status;
  90. if( g_HightLigt_Status )
  91. ( (WinEDA_PcbFrame*) Panel->m_Parent )->DrawHightLight( DC, g_HightLigth_NetCode );
  92. EraseDragListe();
  93. }
  94. /*************************************************************************/
  95. static void Show_MoveTrack( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
  96. /*************************************************************************/
  97. /* redessin du contour de la piste lors des deplacements de la souris */
  98. {
  99. int ii, dx, dy;
  100. TRACK* Track;
  101. BASE_SCREEN* screen = panel->GetScreen();
  102. int track_fill_copy = DisplayOpt.DisplayPcbTrackFill;
  103. DisplayOpt.DisplayPcbTrackFill = SKETCH;
  104. erase = TRUE;
  105. /* efface ancienne position si elle a ete deja dessinee */
  106. if( erase )
  107. {
  108. if( NewTrack )
  109. Trace_Une_Piste( panel, DC, NewTrack, NbPtNewTrack, GR_XOR );
  110. }
  111. /* mise a jour des coordonnees des segments de la piste */
  112. wxPoint Pos = screen->m_Curseur;
  113. dx = Pos.x - LastPos.x;
  114. dy = Pos.y - LastPos.y;
  115. LastPos = Pos;
  116. ii = NbPtNewTrack, Track = NewTrack;
  117. for( ; ii > 0; ii--, Track = Track->Next() )
  118. {
  119. if( Track->m_Flags & STARTPOINT )
  120. {
  121. Track->m_Start.x += dx; Track->m_Start.y += dy;
  122. }
  123. if( Track->m_Flags & ENDPOINT )
  124. {
  125. Track->m_End.x += dx; Track->m_End.y += dy;
  126. }
  127. }
  128. /* dessin de la nouvelle piste */
  129. Trace_Une_Piste( panel, DC, NewTrack, NbPtNewTrack, GR_XOR );
  130. /* Tracage des segments dragges */
  131. DRAG_SEGM* pt_drag = g_DragSegmentList;
  132. for( ; pt_drag != NULL; pt_drag = pt_drag->Pnext )
  133. {
  134. Track = pt_drag->m_Segm;
  135. if( erase )
  136. Track->Draw( panel, DC, GR_XOR );
  137. if( Track->m_Flags & STARTPOINT )
  138. {
  139. Track->m_Start.x += dx; Track->m_Start.y += dy;
  140. }
  141. if( Track->m_Flags & ENDPOINT )
  142. {
  143. Track->m_End.x += dx; Track->m_End.y += dy;
  144. }
  145. Track->Draw( panel, DC, GR_XOR );
  146. }
  147. DisplayOpt.DisplayPcbTrackFill = track_fill_copy;
  148. }
  149. /***********************************************************************************/
  150. void WinEDA_PcbFrame::Start_MoveOneTrackSegment( TRACK* track, wxDC* DC, bool Drag )
  151. /***********************************************************************************/
  152. {
  153. /* Change hight light net: the new one will be hightlighted */
  154. Old_HightLigt_Status = g_HightLigt_Status;
  155. Old_HightLigth_NetCode = g_HightLigth_NetCode;
  156. if( g_HightLigt_Status )
  157. Hight_Light( DC );
  158. if( Drag && track->Type() == TYPEVIA )
  159. {
  160. track->m_Flags = IS_DRAGGED | STARTPOINT | ENDPOINT;
  161. Collect_TrackSegmentsToDrag( DrawPanel, DC, track->m_Start,
  162. track->ReturnMaskLayer(), track->GetNet() );
  163. NewTrack = track;
  164. NbPtNewTrack = 1;
  165. PosInit = track->m_Start;
  166. }
  167. else
  168. {
  169. int diag = track->IsPointOnEnds( GetScreen()->m_Curseur, -1 );
  170. wxPoint pos = (diag & STARTPOINT) ? track->m_Start : track->m_End;
  171. Collect_TrackSegmentsToDrag( DrawPanel, DC, pos,
  172. track->ReturnMaskLayer(), track->GetNet() );
  173. track->m_Flags |= IS_DRAGGED;
  174. NewTrack = NULL;
  175. NbPtNewTrack = 0;
  176. PosInit = pos;
  177. }
  178. LastPos = PosInit;
  179. DrawPanel->ManageCurseur = Show_MoveTrack;
  180. DrawPanel->ForceCloseManageCurseur = Exit_MoveTrack;
  181. g_HightLigth_NetCode = track->GetNet();
  182. g_HightLigt_Status = TRUE;
  183. DrawHightLight( DC, g_HightLigth_NetCode );
  184. DrawPanel->ManageCurseur( DrawPanel, DC, TRUE );
  185. }
  186. /**********************************************************************/
  187. bool WinEDA_PcbFrame::PlaceDraggedTrackSegment( TRACK* Track, wxDC* DC )
  188. /**********************************************************************/
  189. /* Place a dragged track segment or via */
  190. {
  191. int errdrc;
  192. DRAG_SEGM* pt_drag;
  193. if( Track == NULL )
  194. return FALSE;
  195. // DRC control:
  196. if( Drc_On )
  197. {
  198. errdrc = Drc( this, DC, Track, m_Pcb->m_Track, 1 );
  199. if( errdrc == BAD_DRC )
  200. return FALSE;
  201. /* Tracage des segments dragges */
  202. pt_drag = g_DragSegmentList;
  203. for( ; pt_drag; pt_drag = pt_drag->Pnext )
  204. {
  205. errdrc = Drc( this, DC, pt_drag->m_Segm, m_Pcb->m_Track, 1 );
  206. if( errdrc == BAD_DRC )
  207. return FALSE;
  208. }
  209. }
  210. // DRC Ok: place track segments
  211. Track->ClearFlags();
  212. Track->Draw( DrawPanel, DC, GR_OR );
  213. /* Tracage des segments dragges */
  214. pt_drag = g_DragSegmentList;
  215. for( ; pt_drag; pt_drag = pt_drag->Pnext )
  216. {
  217. Track = pt_drag->m_Segm;
  218. Track->SetState( EDIT, OFF );
  219. Track->ClearFlags();
  220. Track->Draw( DrawPanel, DC, GR_OR );
  221. }
  222. EraseDragListe();
  223. GetScreen()->SetModify();
  224. DrawPanel->ManageCurseur = NULL;
  225. DrawPanel->ForceCloseManageCurseur = NULL;
  226. return TRUE;
  227. }
  228. #if 0
  229. /***********************************************/
  230. void WinEDA_PcbFrame::Place_Dupl_Route( Track* Track, wxDC* DC )
  231. /******************************************/
  232. /*
  233. * Routine de placement d'une piste (succession de segments)
  234. */
  235. {
  236. D_PAD* pt_pad;
  237. TRACK* pt_track, * Track, * pt_classe, * NextS;
  238. int masquelayer;
  239. EDA_BaseStruct* LockPoint;
  240. int ii, old_net_code, new_net_code, DRC_error = 0;
  241. wxDC* DC = Cmd->DC;
  242. ActiveDrawPanel->ManageCurseur = NULL;
  243. if( NewTrack == NULL )
  244. return;
  245. old_net_code = NewTrack->net_code;
  246. /* Placement du flag BUSY de la piste originelle, qui ne doit
  247. * pas etre vue dans les recherches de raccordement suivantes */
  248. ii = NbPtNewTrack; pt_track = NewTrack;
  249. for( ; ii > 0; ii--, pt_track = (TRACK*) pt_track->Pnext )
  250. {
  251. pt_track->SetState( BUSY, ON );
  252. }
  253. /* Detection du nouveau net_code */
  254. ii = NbPtNewTrack; pt_track = NewTrack;
  255. for( ; ii > 0; ii--, pt_track = (TRACK*) pt_track->Pnext )
  256. {
  257. pt_track->net_code = 0;
  258. }
  259. new_net_code = 0;
  260. ii = 0; pt_track = NewTrack;
  261. for( ; ii < NbPtNewTrack; ii++, pt_track = (TRACK*) pt_track->Pnext )
  262. {
  263. /* Localisation de la pastille ou segment en debut de segment: */
  264. masquelayer = tab_layer[pt_track->Layer];
  265. LockPoint = LocateLockPoint( pt_track->m_Start.x, pt_track->m_Start.y, masquelayer );
  266. if( LockPoint )
  267. {
  268. if( LockPoint->Type() == TYPEPAD )
  269. {
  270. pt_pad = (D_PAD*) LockPoint;
  271. new_net_code = pt_pad->net_code;
  272. if( new_net_code > 0 )
  273. break;
  274. }
  275. else /* debut de piste sur un segment de piste */
  276. {
  277. Track = (TRACK*) LockPoint;
  278. new_net_code = Track->net_code;
  279. if( new_net_code > 0 )
  280. break;
  281. }
  282. }
  283. LockPoint = LocateLockPoint( pt_track->m_End.x, pt_track->m_End.y, masquelayer );
  284. if( LockPoint )
  285. {
  286. if( LockPoint->Type() == TYPEPAD )
  287. {
  288. pt_pad = (D_PAD*) LockPoint;
  289. new_net_code = pt_pad->net_code;
  290. if( new_net_code > 0 )
  291. break;
  292. }
  293. else /* debut de piste sur un segment de piste */
  294. {
  295. Track = (TRACK*) LockPoint;
  296. new_net_code = Track->net_code;
  297. if( new_net_code > 0 )
  298. break;
  299. }
  300. }
  301. }
  302. /* Mise a jour du nouveau net code de la piste */
  303. ii = 0; pt_track = NewTrack;
  304. for( ; ii < NbPtNewTrack; ii++, pt_track = (TRACK*) pt_track->Pnext )
  305. {
  306. pt_track->net_code = new_net_code;
  307. }
  308. /* Controle DRC de la nouvelle piste */
  309. ii = 0; pt_track = NewTrack;
  310. for( ; ii < NbPtNewTrack; ii++, pt_track = pt_track->Next() )
  311. {
  312. if( Drc_On == RUN )
  313. if( drc( DC, pt_track, pt_pcb->Track, 1 ) == BAD_DRC )
  314. {
  315. if( confirmation( " Erreur DRC, Place piste:" ) == YES )
  316. continue;
  317. else
  318. {
  319. DRC_error = 1; break;
  320. }
  321. }
  322. }
  323. if( DRC_error == 0 )
  324. {
  325. if( FlagState == MOVE_ROUTE )
  326. {
  327. /* copie nouvelle piste */
  328. pt_track = NewTrack;
  329. NewTrack = pt_track->Copy( NbPtNewTrack );
  330. /* effacement ancienne ( chainage et liens mauvais */
  331. ii = NbPtNewTrack;
  332. for( ; ii > 0; ii--, pt_track = NextS )
  333. {
  334. NextS = (TRACK*) pt_track->Pnext;
  335. pt_track ->DeleteStructure();
  336. }
  337. test_1_net_connexion( DC, old_net_code );
  338. }
  339. pt_classe = NewTrack->GetBestInsertPoint();
  340. NewTrack->Insert( pt_classe );
  341. Trace_Une_Piste( DC, NewTrack, NbPtNewTrack, GR_OR );
  342. /* Mise a jour des connexions sur pads et sur pistes */
  343. ii = 0; pt_track = NewTrack;
  344. for( ; ii < NbPtNewTrack; ii++, pt_track = NextS )
  345. {
  346. NextS = (TRACK*) pt_track->Pnext;
  347. pt_track->SetState( BEGIN_ONPAD | END_ONPAD, OFF );
  348. masquelayer = tab_layer[pt_track->Layer];
  349. /* Localisation de la pastille ou segment sur debut segment: */
  350. LockPoint = LocateLockPoint( pt_track->m_Start.x, pt_track->m_Start.y, masquelayer );
  351. if( LockPoint )
  352. {
  353. pt_track->start = LockPoint;
  354. if( LockPoint->Type() == TYPEPAD )
  355. { /* fin de piste sur un pad */
  356. pt_pad = (D_PAD*) LockPoint;
  357. pt_track->SetState( BEGIN_ONPAD, ON );
  358. }
  359. else /* debut de piste sur un segment de piste */
  360. {
  361. Track = (TRACK*) LockPoint;
  362. CreateLockPoint( &pt_track->m_Start.x, &pt_track->m_Start.y, Track, pt_track );
  363. }
  364. }
  365. /* Localisation de la pastille ou segment sur fin de segment: */
  366. LockPoint = LocateLockPoint( pt_track->m_End.x, pt_track->m_End.y, masquelayer );
  367. if( LockPoint )
  368. {
  369. pt_track->end = LockPoint;
  370. if( LockPoint->Type() == TYPEPAD )
  371. { /* fin de piste sur un pad */
  372. pt_pad = (D_PAD*) LockPoint;
  373. pt_track->SetState( END_ONPAD, ON );
  374. }
  375. else /* debut de piste sur un segment de piste */
  376. {
  377. Track = (TRACK*) LockPoint;
  378. CreateLockPoint( &pt_track->m_Start.x, &pt_track->m_Start.y, Track, pt_track );
  379. }
  380. }
  381. }
  382. /* Suppression du flag BUSY */
  383. ii = NbPtNewTrack; pt_track = NewTrack;
  384. for( ; ii > 0; ii--, pt_track = (TRACK*) pt_track->Pnext )
  385. {
  386. pt_track->SetState( BUSY, OFF );
  387. }
  388. test_1_net_connexion( DC, new_net_code );
  389. ActiveScreen->SetModify();
  390. }
  391. else /* Erreur DRC: Annulation commande */
  392. {
  393. DisplayOpt.DisplayPcbTrackFill = SKETCH;
  394. Trace_Une_Piste( DC, NewTrack, NbPtNewTrack, GR_XOR );
  395. DisplayOpt.DisplayPcbTrackFill = Track_fill_copy;
  396. if( FlagState == MOVE_ROUTE )
  397. { /* Remise en position de la piste deplacee */
  398. Track = NewTrack;
  399. PosInitX -= Track->m_Start.x; PosInitY -= Track->m_Start.y;
  400. for( ii = 0; ii < NbPtNewTrack; ii++, Track = (TRACK*) Track->Pnext )
  401. {
  402. if( Track == NULL )
  403. break;
  404. Track->m_Start.x += PosInitX; Track->m_Start.y += PosInitY;
  405. Track->m_End.x += PosInitX; Track->m_End.y += PosInitY;
  406. Track->SetState( BUSY, OFF );
  407. }
  408. Trace_Une_Piste( DC, NewTrack, NbPtNewTrack, GR_OR );
  409. }
  410. if( FlagState == COPY_ROUTE )
  411. { /* Suppression copie */
  412. for( ii = 0; ii < NbPtNewTrack; NewTrack = NextS )
  413. {
  414. if( NewTrack == NULL )
  415. break;
  416. NextS = (TRACK*) NewTrack->Pnext;
  417. delete NewTrack;
  418. }
  419. }
  420. }
  421. NewTrack = NULL;
  422. m_Pcb->Display_Infos( Cmd );
  423. if( Etat_Surbrillance )
  424. Hight_Light( DC );
  425. }
  426. /************************************************/
  427. void WinEDA_PcbFrame::Start_CopieMove_Route( TRACK* track, wxDC* DC, bool Drag )
  428. /************************************************/
  429. /* Routine permettant la recopie d'une piste (suite de segments) deja tracee
  430. */
  431. {
  432. int ii;
  433. TRACK* pt_segm, * pt_track;
  434. int masquelayer = tab_layer[ActiveScreen->Active_Layer];
  435. wxDC* DC = Cmd->DC;
  436. if( NewTrack )
  437. return;
  438. FlagState = (int) Cmd->Menu->param_inf;
  439. /* Recherche de la piste sur la couche active (non zone) */
  440. for( pt_segm = pt_pcb->Track; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext )
  441. {
  442. pt_segm = Locate_Pistes( pt_segm, masquelayer, CURSEUR_OFF_GRILLE );
  443. if( pt_segm == NULL )
  444. break;
  445. break;
  446. }
  447. if( pt_segm != NULL )
  448. {
  449. if( FlagState == COPY_ROUTE )
  450. pt_track = Marque_Une_Piste( DC, pt_segm, &NbPtNewTrack, 0 );
  451. else
  452. pt_track = Marque_Une_Piste( DC, pt_segm, &NbPtNewTrack, GR_XOR );
  453. if( NbPtNewTrack ) /* Il y a NbPtNewTrack segments de piste a traiter */
  454. {
  455. /* effacement du flag BUSY de la piste originelle */
  456. ii = NbPtNewTrack; pt_segm = pt_track;
  457. for( ; ii > 0; ii--, pt_segm = (TRACK*) pt_segm->Pnext )
  458. {
  459. pt_segm->SetState( BUSY, OFF );
  460. }
  461. if( FlagState == COPY_ROUTE )
  462. NewTrack = pt_track->Copy( NbPtNewTrack );
  463. else
  464. NewTrack = pt_track;
  465. Affiche_Infos_Piste( Cmd, pt_track );
  466. startX = ActiveScreen->Curseur_X;
  467. startY = ActiveScreen->Curseur_Y;
  468. Place_Dupl_Route_Item.State = WAIT;
  469. ActiveDrawPanel->ManageCurseur = Show_Move_Piste;
  470. DisplayOpt.DisplayPcbTrackFill = SKETCH;
  471. Trace_Une_Piste( DC, NewTrack, NbPtNewTrack, GR_XOR );
  472. DisplayOpt.DisplayPcbTrackFill = Track_fill_copy;
  473. PosInitX = NewTrack->m_Start.x; PosInitY = NewTrack->m_Start.y;
  474. }
  475. }
  476. }
  477. #endif
  478. /************************************************************************/
  479. EDA_BaseStruct* LocateLockPoint( BOARD* Pcb, wxPoint pos, int LayerMask )
  480. /************************************************************************/
  481. /* Routine trouvant le point " d'accrochage " d'une extremite de piste.
  482. * Ce point peut etre un PAD ou un autre segment de piste
  483. * Retourne:
  484. * - pointeur sur ce PAD ou:
  485. * - pointeur sur le segment ou:
  486. * - NULL
  487. * Parametres d'appel:
  488. * coord pX, pY du point tst
  489. * masque des couches a tester
  490. */
  491. {
  492. D_PAD* pt_pad;
  493. TRACK* ptsegm;
  494. MODULE* Module;
  495. /* detection du point type PAD */
  496. pt_pad = NULL;
  497. Module = Pcb->m_Modules;
  498. for( ; Module != NULL; Module = (MODULE*) Module->Pnext )
  499. {
  500. pt_pad = Locate_Pads( Module, pos, LayerMask );
  501. if( pt_pad )
  502. return pt_pad;
  503. }
  504. /* ici aucun pad n'a ete localise: detection d'un segment de piste */
  505. ptsegm = Fast_Locate_Piste( Pcb->m_Track, NULL, pos, LayerMask );
  506. if( ptsegm == NULL )
  507. ptsegm = Locate_Pistes( Pcb->m_Track, pos, LayerMask );
  508. return ptsegm;
  509. }
  510. /******************************************************************************/
  511. TRACK* CreateLockPoint( int* pX, int* pY, TRACK* ptsegm, TRACK* refsegm )
  512. /******************************************************************************/
  513. /* Routine de creation d'un point intermediaire sur un segment
  514. * le segment ptsegm est casse en 2 segments se raccordant au point pX, pY
  515. * retourne:
  516. * NULL si pas de nouveau point ( c.a.d si pX, pY correspondait deja
  517. * a une extremite ou:
  518. * pointeur sur le segment cree
  519. * si refsegm != NULL refsegm est pointeur sur le segment incident,
  520. * et le point cree est l'intersection des 2 axes des segments ptsegm et
  521. * refsegm
  522. * retourne la valeur exacte de pX et pY
  523. * Si ptsegm pointe sur une via:
  524. * retourne la valeur exacte de pX et pY et ptsegm,
  525. * mais ne cree pas de point supplementaire
  526. *
  527. */
  528. {
  529. int cX, cY;
  530. int dx, dy; /* Coord de l'extremite du segm ptsegm / origine */
  531. int ox, oy, fx, fy; /* coord de refsegm / origine de prsegm */
  532. TRACK* NewTrack;
  533. if( (ptsegm->m_Start.x == *pX) && (ptsegm->m_Start.y == *pY) )
  534. return NULL;
  535. if( (ptsegm->m_End.x == *pX) && (ptsegm->m_End.y == *pY) )
  536. return NULL;
  537. /* le point n'est pas sur une extremite de piste */
  538. if( ptsegm->Type() == TYPEVIA )
  539. {
  540. *pX = ptsegm->m_Start.x; *pY = ptsegm->m_Start.y;
  541. return ptsegm;
  542. }
  543. /* calcul des coord vraies du point intermediaire dans le repere d'origine
  544. * = origine de ptsegm */
  545. cX = *pX - ptsegm->m_Start.x;
  546. cY = *pY - ptsegm->m_Start.y;
  547. dx = ptsegm->m_End.x - ptsegm->m_Start.x;
  548. dy = ptsegm->m_End.y - ptsegm->m_Start.y;
  549. // ***** A COMPLETER : non utilise
  550. if( refsegm )
  551. {
  552. ox = refsegm->m_Start.x - ptsegm->m_Start.x;
  553. oy = refsegm->m_Start.y - ptsegm->m_Start.y;
  554. fx = refsegm->m_End.x - ptsegm->m_Start.x;
  555. fy = refsegm->m_End.y - ptsegm->m_Start.y;
  556. }
  557. /* pour que le point soit sur le segment ptsegm: cY/cX = dy/dx */
  558. if( dx == 0 )
  559. cX = 0;/* segm horizontal */
  560. else
  561. cY = (cX * dy) / dx;
  562. /* creation du point intermediaire ( c'est a dire creation d'un nouveau
  563. * segment, debutant au point intermediaire */
  564. cX += ptsegm->m_Start.x; cY += ptsegm->m_Start.y;
  565. NewTrack = ptsegm->Copy();
  566. NewTrack->Insert( NULL, ptsegm );
  567. /* correction du pointeur de fin du nouveau segment */
  568. NewTrack->end = ptsegm->end;
  569. /* le segment primitif finit au nouveau point : */
  570. ptsegm->m_End.x = cX; ptsegm->m_End.y = cY;
  571. ptsegm->SetState( END_ONPAD, OFF );
  572. /* le nouveau segment debute au nouveau point : */
  573. ptsegm = NewTrack;;
  574. ptsegm->m_Start.x = cX; ptsegm->m_Start.y = cY;
  575. ptsegm->SetState( BEGIN_ONPAD, OFF );
  576. *pX = cX; *pY = cY;
  577. return ptsegm;
  578. }