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.

1009 lines
32 KiB

18 years ago
18 years ago
18 years ago
18 years ago
17 years ago
  1. /*********************************************************/
  2. /* Routines de trace: fonction communes aux diff formats */
  3. /*********************************************************/
  4. /* Fichier PLOT_RTN.CPP*/
  5. #include "fctsys.h"
  6. #include "common.h"
  7. #include "plot_common.h"
  8. #include "base_struct.h"
  9. #include "drawtxt.h"
  10. #include "confirm.h"
  11. #include "pcbnew.h"
  12. #include "pcbplot.h"
  13. #include "trigo.h"
  14. /* Fonctions locales */
  15. static void Plot_Edges_Modules( BOARD* pcb, int format_plot, int masque_layer );
  16. static void PlotTextModule( TEXTE_MODULE* pt_texte, int format_plot );
  17. /**********************************************************/
  18. void WinEDA_BasePcbFrame::Plot_Serigraphie( int format_plot,
  19. FILE* File, int masque_layer )
  20. /***********************************************************/
  21. /* Genere le trace des couches type serigraphie, en format HPGL ou GERBER*/
  22. {
  23. wxPoint pos, shape_pos;
  24. wxSize size;
  25. bool trace_val, trace_ref;
  26. D_PAD* pt_pad;
  27. TEXTE_MODULE* pt_texte;
  28. EDA_BaseStruct* PtStruct;
  29. wxString msg;
  30. /* Trace du contour du PCB et des Elements du type Drawings Pcb */
  31. PtStruct = m_Pcb->m_Drawings;
  32. for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
  33. {
  34. switch( PtStruct->Type() )
  35. {
  36. case TYPE_DRAWSEGMENT:
  37. PlotDrawSegment( (DRAWSEGMENT*) PtStruct, format_plot, masque_layer );
  38. break;
  39. case TYPE_TEXTE:
  40. PlotTextePcb( (TEXTE_PCB*) PtStruct, format_plot, masque_layer );
  41. break;
  42. case TYPE_COTATION:
  43. PlotCotation( (COTATION*) PtStruct, format_plot, masque_layer );
  44. break;
  45. case TYPE_MIRE:
  46. PlotMirePcb( (MIREPCB*) PtStruct, format_plot, masque_layer );
  47. break;
  48. case TYPE_MARKER:
  49. break;
  50. default:
  51. DisplayError( this, wxT( "Plot_Serigraphie() error: unexpected Type()" ) );
  52. break;
  53. }
  54. }
  55. /* trace des contours des MODULES : */
  56. Plot_Edges_Modules( m_Pcb, format_plot, masque_layer );
  57. /* Trace des MODULES : PADS */
  58. if( PlotPadsOnSilkLayer || Plot_Pads_All_Layers )
  59. {
  60. for( MODULE* Module = m_Pcb->m_Modules; Module; Module = Module->Next() )
  61. {
  62. pt_pad = (D_PAD*) Module->m_Pads;
  63. for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
  64. {
  65. /* Tst si layer OK */
  66. if( (pt_pad->m_Masque_Layer & masque_layer) == 0 )
  67. {
  68. if( !Plot_Pads_All_Layers )
  69. continue;
  70. }
  71. shape_pos = pt_pad->ReturnShapePos();
  72. pos = shape_pos;
  73. size = pt_pad->m_Size;
  74. switch( pt_pad->m_PadShape & 0x7F )
  75. {
  76. case PAD_CIRCLE:
  77. switch( format_plot )
  78. {
  79. case PLOT_FORMAT_GERBER:
  80. PlotCircle( PLOT_FORMAT_GERBER,
  81. g_PlotLine_Width, pos, size.x / 2 );
  82. break;
  83. case PLOT_FORMAT_HPGL:
  84. trace_1_pastille_RONDE_HPGL( pos, size.x, FILAIRE );
  85. break;
  86. case PLOT_FORMAT_POST:
  87. trace_1_pastille_RONDE_POST( pos, size.x, FILAIRE );
  88. break;
  89. }
  90. break;
  91. case PAD_OVAL:
  92. switch( format_plot )
  93. {
  94. case PLOT_FORMAT_GERBER:
  95. trace_1_contour_GERBER( pos, size, wxSize( 0, 0 ),
  96. g_PlotLine_Width,
  97. pt_pad->m_Orient );
  98. break;
  99. case PLOT_FORMAT_HPGL:
  100. trace_1_pastille_OVALE_HPGL( pos, size,
  101. pt_pad->m_Orient, FILAIRE );
  102. break;
  103. case PLOT_FORMAT_POST:
  104. trace_1_pastille_OVALE_POST( pos, size,
  105. pt_pad->m_Orient, FILAIRE );
  106. break;
  107. }
  108. break;
  109. case PAD_TRAPEZOID:
  110. {
  111. wxSize delta;
  112. delta = pt_pad->m_DeltaSize;
  113. switch( format_plot )
  114. {
  115. case PLOT_FORMAT_GERBER:
  116. trace_1_contour_GERBER( pos, size, delta,
  117. g_PlotLine_Width,
  118. (int) pt_pad->m_Orient );
  119. break;
  120. case PLOT_FORMAT_HPGL:
  121. trace_1_pad_TRAPEZE_HPGL( pos, size,
  122. delta, (int) pt_pad->m_Orient,
  123. FILAIRE );
  124. break;
  125. case PLOT_FORMAT_POST:
  126. trace_1_pad_TRAPEZE_POST( pos, size,
  127. delta, (int) pt_pad->m_Orient,
  128. FILAIRE );
  129. break;
  130. }
  131. break;
  132. }
  133. case PAD_RECT:
  134. default:
  135. switch( format_plot )
  136. {
  137. case PLOT_FORMAT_GERBER:
  138. trace_1_contour_GERBER( pos, size, wxSize( 0, 0 ),
  139. g_PlotLine_Width,
  140. (int) pt_pad->m_Orient );
  141. break;
  142. case PLOT_FORMAT_HPGL:
  143. PlotRectangularPad_HPGL( pos, size, pt_pad->m_Orient, FILAIRE );
  144. break;
  145. case PLOT_FORMAT_POST:
  146. trace_1_pad_rectangulaire_POST( pos, size,
  147. (int) pt_pad->m_Orient, FILAIRE );
  148. break;
  149. }
  150. break;
  151. }
  152. }
  153. }
  154. } /* Fin Sequence de trace des Pads */
  155. /* Trace Textes MODULES */
  156. for( MODULE* Module = m_Pcb->m_Modules; Module; Module = Module->Next() )
  157. {
  158. /* Analyse des autorisations de trace pour les textes VALEUR et REF */
  159. trace_val = Sel_Texte_Valeur;
  160. trace_ref = Sel_Texte_Reference; // les 2 autorisations de tracer sont donnees
  161. TEXTE_MODULE* text = Module->m_Reference;
  162. unsigned textLayer = text->GetLayer();
  163. if( textLayer >= 32 )
  164. {
  165. wxString errMsg;
  166. errMsg.Printf(
  167. _( "Your BOARD has a bad layer number of %u for module\n %s's \"reference\" text." ),
  168. textLayer, Module->GetReference().GetData() );
  169. DisplayError( this, errMsg );
  170. goto exit;
  171. }
  172. if( ( (1 << textLayer) & masque_layer ) == 0 )
  173. trace_ref = FALSE;
  174. if( text->m_NoShow && !Sel_Texte_Invisible )
  175. trace_ref = FALSE;
  176. text = Module->m_Value;
  177. textLayer = text->GetLayer();
  178. if( textLayer > 32 )
  179. {
  180. wxString errMsg;
  181. errMsg.Printf(
  182. _( "Your BOARD has a bad layer number of %u for module\n %s's \"value\" text." ),
  183. textLayer, Module->GetReference().GetData() );
  184. DisplayError( this, errMsg );
  185. goto exit;
  186. }
  187. if( ( (1 << textLayer) & masque_layer ) == 0 )
  188. trace_val = FALSE;
  189. if( text->m_NoShow && !Sel_Texte_Invisible )
  190. trace_val = FALSE;
  191. /* Trace effectif des textes */
  192. if( trace_ref )
  193. {
  194. PlotTextModule( Module->m_Reference, format_plot );
  195. }
  196. if( trace_val )
  197. {
  198. PlotTextModule( Module->m_Value, format_plot );
  199. }
  200. pt_texte = (TEXTE_MODULE*) Module->m_Drawings.GetFirst();
  201. for( ; pt_texte != NULL; pt_texte = pt_texte->Next() )
  202. {
  203. if( pt_texte->Type() != TYPE_TEXTE_MODULE )
  204. continue;
  205. if( !Sel_Texte_Divers )
  206. continue;
  207. if( (pt_texte->m_NoShow) && !Sel_Texte_Invisible )
  208. continue;
  209. textLayer = pt_texte->GetLayer();
  210. if( textLayer >= 32 )
  211. {
  212. wxString errMsg;
  213. errMsg.Printf(
  214. _(
  215. "Your BOARD has a bad layer number of %u for module\n %s's \"module text\" text of %s." ),
  216. textLayer, Module->GetReference().GetData(), pt_texte->m_Text.GetData() );
  217. DisplayError( this, errMsg );
  218. goto exit;
  219. }
  220. if( !( (1 << textLayer) & masque_layer ) )
  221. continue;
  222. PlotTextModule( pt_texte, format_plot );
  223. }
  224. }
  225. /* Plot filled ares */
  226. for( int ii = 0; ii < m_Pcb->GetAreaCount(); ii++ )
  227. {
  228. ZONE_CONTAINER* edge_zone = m_Pcb->GetArea( ii );
  229. if( ( ( 1 << edge_zone->GetLayer() ) & masque_layer ) == 0 )
  230. continue;
  231. PlotFilledAreas( edge_zone, format_plot );
  232. }
  233. // Plot segments used to fill zone areas:
  234. for( SEGZONE* seg = m_Pcb->m_Zone; seg != NULL; seg = seg->Next() )
  235. {
  236. if( ( ( 1 << seg->GetLayer() ) & masque_layer ) == 0 )
  237. continue;
  238. switch( format_plot )
  239. {
  240. case PLOT_FORMAT_GERBER:
  241. SelectD_CODE_For_LineDraw( seg->m_Width );
  242. PlotGERBERLine( seg->m_Start, seg->m_End, seg->m_Width );
  243. break;
  244. case PLOT_FORMAT_HPGL:
  245. Plot_Filled_Segment_HPGL( seg->m_Start, seg->m_End, seg->m_Width, FILLED );
  246. break;
  247. case PLOT_FORMAT_POST:
  248. PlotFilledSegmentPS( seg->m_Start, seg->m_End, seg->m_Width );
  249. break;
  250. }
  251. }
  252. exit:
  253. ;
  254. }
  255. /********************************************************************/
  256. static void PlotTextModule( TEXTE_MODULE* pt_texte, int format_plot )
  257. /********************************************************************/
  258. {
  259. wxSize size;
  260. wxPoint pos;
  261. int orient, thickness;
  262. /* calcul des parametres du texte :*/
  263. size = pt_texte->m_Size;
  264. pos = pt_texte->m_Pos;
  265. orient = pt_texte->GetDrawRotation();
  266. thickness = pt_texte->m_Width;
  267. if( g_Plot_Mode == FILAIRE )
  268. thickness = g_PlotLine_Width;
  269. if( pt_texte->m_Mirror )
  270. size.x = -size.x; // Text is mirrored
  271. switch( format_plot )
  272. {
  273. case PLOT_FORMAT_GERBER:
  274. SelectD_CODE_For_LineDraw( thickness );
  275. break;
  276. case PLOT_FORMAT_HPGL:
  277. break;
  278. case PLOT_FORMAT_POST:
  279. SetCurrentLineWidthPS( thickness );
  280. break;
  281. }
  282. PlotGraphicText( format_plot, pos, g_Plot_PS_Negative ? WHITE : BLACK,
  283. pt_texte->m_Text,
  284. orient, size,
  285. pt_texte->m_HJustify, pt_texte->m_VJustify,
  286. thickness, pt_texte->m_Italic, pt_texte->m_Bold );
  287. }
  288. /*******************************************************************************/
  289. void PlotCotation( COTATION* Cotation, int format_plot, int masque_layer )
  290. /*******************************************************************************/
  291. {
  292. DRAWSEGMENT* DrawTmp;
  293. if( (g_TabOneLayerMask[Cotation->GetLayer()] & masque_layer) == 0 )
  294. return;
  295. DrawTmp = new DRAWSEGMENT( NULL );
  296. DrawTmp->m_Width = Cotation->m_Width;
  297. DrawTmp->SetLayer( Cotation->GetLayer() );
  298. PlotTextePcb( Cotation->m_Text, format_plot, masque_layer );
  299. DrawTmp->m_Start.x = Cotation->Barre_ox; DrawTmp->m_Start.y = Cotation->Barre_oy;
  300. DrawTmp->m_End.x = Cotation->Barre_fx; DrawTmp->m_End.y = Cotation->Barre_fy;
  301. PlotDrawSegment( DrawTmp, format_plot, masque_layer );
  302. DrawTmp->m_Start.x = Cotation->TraitG_ox; DrawTmp->m_Start.y = Cotation->TraitG_oy;
  303. DrawTmp->m_End.x = Cotation->TraitG_fx; DrawTmp->m_End.y = Cotation->TraitG_fy;
  304. PlotDrawSegment( DrawTmp, format_plot, masque_layer );
  305. DrawTmp->m_Start.x = Cotation->TraitD_ox; DrawTmp->m_Start.y = Cotation->TraitD_oy;
  306. DrawTmp->m_End.x = Cotation->TraitD_fx; DrawTmp->m_End.y = Cotation->TraitD_fy;
  307. PlotDrawSegment( DrawTmp, format_plot, masque_layer );
  308. DrawTmp->m_Start.x = Cotation->FlecheD1_ox; DrawTmp->m_Start.y = Cotation->FlecheD1_oy;
  309. DrawTmp->m_End.x = Cotation->FlecheD1_fx; DrawTmp->m_End.y = Cotation->FlecheD1_fy;
  310. PlotDrawSegment( DrawTmp, format_plot, masque_layer );
  311. DrawTmp->m_Start.x = Cotation->FlecheD2_ox; DrawTmp->m_Start.y = Cotation->FlecheD2_oy;
  312. DrawTmp->m_End.x = Cotation->FlecheD2_fx; DrawTmp->m_End.y = Cotation->FlecheD2_fy;
  313. PlotDrawSegment( DrawTmp, format_plot, masque_layer );
  314. DrawTmp->m_Start.x = Cotation->FlecheG1_ox; DrawTmp->m_Start.y = Cotation->FlecheG1_oy;
  315. DrawTmp->m_End.x = Cotation->FlecheG1_fx; DrawTmp->m_End.y = Cotation->FlecheG1_fy;
  316. PlotDrawSegment( DrawTmp, format_plot, masque_layer );
  317. DrawTmp->m_Start.x = Cotation->FlecheG2_ox; DrawTmp->m_Start.y = Cotation->FlecheG2_oy;
  318. DrawTmp->m_End.x = Cotation->FlecheG2_fx; DrawTmp->m_End.y = Cotation->FlecheG2_fy;
  319. PlotDrawSegment( DrawTmp, format_plot, masque_layer );
  320. delete DrawTmp;
  321. }
  322. /*****************************************************************/
  323. void PlotMirePcb( MIREPCB* Mire, int format_plot, int masque_layer )
  324. /*****************************************************************/
  325. {
  326. DRAWSEGMENT* DrawTmp;
  327. int dx1, dx2, dy1, dy2, radius;
  328. if( (g_TabOneLayerMask[Mire->GetLayer()] & masque_layer) == 0 )
  329. return;
  330. DrawTmp = new DRAWSEGMENT( NULL );
  331. DrawTmp->m_Width = Mire->m_Width;
  332. DrawTmp->SetLayer( Mire->GetLayer() );
  333. DrawTmp->m_Start.x = Mire->m_Pos.x; DrawTmp->m_Start.y = Mire->m_Pos.y;
  334. DrawTmp->m_End.x = DrawTmp->m_Start.x + (Mire->m_Size / 4);
  335. DrawTmp->m_End.y = DrawTmp->m_Start.y;
  336. DrawTmp->m_Shape = S_CIRCLE;
  337. PlotDrawSegment( DrawTmp, format_plot, masque_layer );
  338. DrawTmp->m_Shape = S_SEGMENT;
  339. /* Trace des 2 traits */
  340. radius = Mire->m_Size / 2;
  341. dx1 = radius, dy1 = 0; dx2 = 0, dy2 = radius;
  342. if( Mire->m_Shape ) /* Forme X */
  343. {
  344. dx1 = dy1 = (radius * 7) / 5;
  345. dx2 = dx1;
  346. dy2 = -dy1;
  347. }
  348. DrawTmp->m_Start.x = Mire->m_Pos.x - dx1; DrawTmp->m_Start.y = Mire->m_Pos.y - dy1;
  349. DrawTmp->m_End.x = Mire->m_Pos.x + dx1; DrawTmp->m_End.y = Mire->m_Pos.y + dy1;
  350. PlotDrawSegment( DrawTmp, format_plot, masque_layer );
  351. DrawTmp->m_Start.x = Mire->m_Pos.x - dx2; DrawTmp->m_Start.y = Mire->m_Pos.y - dy2;
  352. DrawTmp->m_End.x = Mire->m_Pos.x + dx2; DrawTmp->m_End.y = Mire->m_Pos.y + dy2;
  353. PlotDrawSegment( DrawTmp, format_plot, masque_layer );
  354. delete DrawTmp;
  355. }
  356. /**********************************************************************/
  357. void Plot_Edges_Modules( BOARD* pcb, int format_plot, int masque_layer )
  358. /**********************************************************************/
  359. /* Trace les contours des modules */
  360. {
  361. int nb_items; /* Pour affichage activite: nbr modules traites */
  362. wxString msg;
  363. nb_items = 0;
  364. for( MODULE* module = pcb->m_Modules; module; module = module->Next() )
  365. {
  366. EDGE_MODULE* edge = (EDGE_MODULE*) module->m_Drawings.GetFirst();
  367. for( ; edge; edge = edge->Next() )
  368. {
  369. if( edge->Type() != TYPE_EDGE_MODULE )
  370. continue;
  371. if( (g_TabOneLayerMask[edge->GetLayer()] & masque_layer) == 0 )
  372. continue;
  373. Plot_1_EdgeModule( format_plot, edge );
  374. }
  375. /* Affichage du nombre de modules traites */
  376. nb_items++;
  377. msg.Printf( wxT( "%d" ), nb_items );
  378. }
  379. }
  380. /**************************************************************/
  381. void Plot_1_EdgeModule( int format_plot, EDGE_MODULE* PtEdge )
  382. /**************************************************************/
  383. /* Trace les contours des modules */
  384. {
  385. int type_trace; /* forme a tracer (segment, cercle) */
  386. int thickness; /* thickness des segments */
  387. int radius; /* radius des cercles a tracer */
  388. int StAngle, EndAngle;
  389. wxPoint pos, end; /* Coord des segments a tracer */
  390. if( PtEdge->Type() != TYPE_EDGE_MODULE )
  391. return;
  392. type_trace = PtEdge->m_Shape;
  393. thickness = PtEdge->m_Width;
  394. if( g_Plot_Mode == FILAIRE )
  395. {
  396. thickness = g_PlotLine_Width;
  397. wxLogDebug( wxT( "changing edgemodule thickness to g_PlotLine_Width" ) );
  398. }
  399. pos = PtEdge->m_Start;
  400. end = PtEdge->m_End;
  401. switch( type_trace )
  402. {
  403. case S_SEGMENT:
  404. /* segment simple */
  405. switch( format_plot )
  406. {
  407. case PLOT_FORMAT_GERBER:
  408. SelectD_CODE_For_LineDraw( thickness );
  409. PlotGERBERLine( pos, end, thickness );
  410. break;
  411. case PLOT_FORMAT_HPGL:
  412. Plot_Filled_Segment_HPGL( pos, end, thickness, (GRFillMode) g_Plot_Mode );
  413. break;
  414. case PLOT_FORMAT_POST:
  415. PlotFilledSegmentPS( pos, end, thickness );
  416. break;
  417. }
  418. break; /* Fin trace segment simple */
  419. case S_CIRCLE:
  420. radius = (int) hypot( (double) ( end.x - pos.x ), (double) ( end.y - pos.y ) );
  421. PlotCircle( format_plot, thickness, pos, radius );
  422. break;
  423. case S_ARC:
  424. radius = (int) hypot( (double) ( end.x - pos.x ), (double) ( end.y - pos.y ) );
  425. StAngle = ArcTangente( end.y - pos.y, end.x - pos.x );
  426. EndAngle = StAngle + PtEdge->m_Angle;
  427. if( StAngle > EndAngle )
  428. EXCHG( StAngle, EndAngle );
  429. PlotArc( format_plot, pos, StAngle, EndAngle, radius, thickness );
  430. break;
  431. case S_POLYGON:
  432. {
  433. // We must compute true coordinates from m_PolyList
  434. // which are relative to module position, orientation 0
  435. MODULE* Module = NULL;
  436. if( PtEdge->GetParent() && (PtEdge->GetParent()->Type() == TYPE_MODULE) )
  437. Module = (MODULE*) PtEdge->GetParent();
  438. int* ptr_base = (int*) MyMalloc( 2 * PtEdge->m_PolyPoints.size() * sizeof(int) );
  439. int* ptr = ptr_base;
  440. int* source = (int*) &PtEdge->m_PolyPoints[0];
  441. for( unsigned ii = 0; ii < PtEdge->m_PolyPoints.size(); ii++ )
  442. {
  443. int x = *source++;
  444. int y = *source++;
  445. if( Module )
  446. {
  447. RotatePoint( &x, &y, Module->m_Orient );
  448. x += Module->m_Pos.x;
  449. y += Module->m_Pos.y;
  450. }
  451. x += PtEdge->m_Start0.x;
  452. y += PtEdge->m_Start0.y;
  453. *ptr++ = x;
  454. *ptr++ = y;
  455. }
  456. PlotFilledPolygon( format_plot, PtEdge->m_PolyPoints.size(), ptr_base );
  457. free( ptr_base );
  458. }
  459. break;
  460. }
  461. }
  462. /****************************************************************************/
  463. void PlotTextePcb( TEXTE_PCB* pt_texte, int format_plot, int masque_layer )
  464. /****************************************************************************/
  465. /* Trace 1 Texte type PCB , c.a.d autre que les textes sur modules */
  466. {
  467. int orient, thickness;
  468. wxPoint pos;
  469. wxSize size;
  470. if( pt_texte->m_Text.IsEmpty() )
  471. return;
  472. if( (g_TabOneLayerMask[pt_texte->GetLayer()] & masque_layer) == 0 )
  473. return;
  474. /* calcul des parametres du texte :*/
  475. size = pt_texte->m_Size;
  476. pos = pt_texte->m_Pos;
  477. orient = pt_texte->m_Orient;
  478. thickness = pt_texte->m_Width;
  479. if( pt_texte->m_Mirror )
  480. size.x = -size.x;
  481. switch( format_plot )
  482. {
  483. case PLOT_FORMAT_GERBER:
  484. SelectD_CODE_For_LineDraw( thickness );
  485. break;
  486. case PLOT_FORMAT_HPGL:
  487. break;
  488. case PLOT_FORMAT_POST:
  489. SetCurrentLineWidthPS( thickness );
  490. break;
  491. }
  492. if( pt_texte->m_MultilineAllowed )
  493. {
  494. wxArrayString* list = wxStringSplit( pt_texte->m_Text, '\n' );
  495. wxPoint offset;
  496. offset.y = pt_texte->GetInterline();
  497. RotatePoint( &offset, orient );
  498. for( unsigned i = 0; i<list->Count(); i++ )
  499. {
  500. wxString txt = list->Item( i );
  501. PlotGraphicText( format_plot, pos, g_Plot_PS_Negative ? WHITE : BLACK,
  502. txt,
  503. orient, size,
  504. pt_texte->m_HJustify, pt_texte->m_VJustify,
  505. thickness, pt_texte->m_Italic, pt_texte->m_Bold );
  506. pos += offset;
  507. }
  508. delete (list);
  509. }
  510. else
  511. PlotGraphicText( format_plot, pos, g_Plot_PS_Negative ? WHITE : BLACK,
  512. pt_texte->m_Text,
  513. orient, size,
  514. pt_texte->m_HJustify, pt_texte->m_VJustify,
  515. thickness, pt_texte->m_Italic, pt_texte->m_Bold );
  516. }
  517. /*********************************************************/
  518. void PlotFilledAreas( ZONE_CONTAINER* aZone, int aFormat )
  519. /*********************************************************/
  520. /* Plot areas (given by .m_FilledPolysList member) in a zone
  521. */
  522. {
  523. static int* CornersBuffer = NULL;
  524. static unsigned CornersBufferSize = 0;
  525. unsigned imax = aZone->m_FilledPolysList.size();
  526. if( imax == 0 ) // Nothing to draw
  527. return;
  528. // We need a buffer to store corners coordinates:
  529. imax++; // provide room to sore an extra coordinte to close the ploygon
  530. if( CornersBuffer == NULL )
  531. {
  532. CornersBufferSize = imax * 4;
  533. CornersBuffer = (int*) MyMalloc( CornersBufferSize * sizeof(int) );
  534. }
  535. if( (imax * 4) > CornersBufferSize )
  536. {
  537. CornersBufferSize = imax * 4;
  538. CornersBuffer = (int*) realloc( CornersBuffer, CornersBufferSize * sizeof(int) );
  539. }
  540. imax--;
  541. // Plot all filled areas
  542. int corners_count = 0;
  543. for( unsigned ic = 0, ii = 0; ic < imax; ic++ )
  544. {
  545. CPolyPt* corner = &aZone->m_FilledPolysList[ic];
  546. CornersBuffer[ii++] = corner->x;
  547. CornersBuffer[ii++] = corner->y;
  548. corners_count++;
  549. if( corner->end_contour ) // Plot the current filled area outline
  550. {
  551. // First, close the outline
  552. if( CornersBuffer[0] != CornersBuffer[ii - 2] || CornersBuffer[1] !=
  553. CornersBuffer[ii - 1] )
  554. {
  555. CornersBuffer[ii++] = CornersBuffer[0];
  556. CornersBuffer[ii] = CornersBuffer[1];
  557. corners_count++;
  558. }
  559. // Plot the current filled area outline
  560. if( aZone->m_FillMode == 0 ) // We are using solid polygons (if != 0: using segments in m_Zone)
  561. PlotFilledPolygon( aFormat, corners_count, CornersBuffer );
  562. if( aZone->m_ZoneMinThickness > 0 )
  563. PlotPolygon( aFormat, corners_count, CornersBuffer, aZone->m_ZoneMinThickness );
  564. corners_count = 0;
  565. ii = 0;
  566. }
  567. }
  568. }
  569. /******************************************************************************/
  570. void PlotDrawSegment( DRAWSEGMENT* pt_segm, int Format, int masque_layer )
  571. /******************************************************************************/
  572. /* Trace un element du type DRAWSEGMENT draw appartenant
  573. * aux couches specifiees par masque_layer
  574. */
  575. {
  576. wxPoint start, end;
  577. int thickness;
  578. int radius = 0, StAngle = 0, EndAngle = 0;
  579. if( (g_TabOneLayerMask[pt_segm->GetLayer()] & masque_layer) == 0 )
  580. return;
  581. thickness = pt_segm->m_Width;
  582. if( g_Plot_Mode == FILAIRE )
  583. thickness = g_PlotLine_Width;
  584. start = pt_segm->m_Start;
  585. end = pt_segm->m_End;
  586. if( pt_segm->m_Shape == S_CIRCLE )
  587. {
  588. radius = (int) hypot( (double) ( end.x - start.x ), (double) ( end.y - start.y ) );
  589. }
  590. if( pt_segm->m_Shape == S_ARC )
  591. {
  592. radius = (int) hypot( (double) ( end.x - start.x ), (double) ( end.y - start.y ) );
  593. StAngle = ArcTangente( end.y - start.y, end.x - start.x );
  594. EndAngle = StAngle + pt_segm->m_Angle;
  595. if( StAngle > EndAngle )
  596. EXCHG( StAngle, EndAngle );
  597. }
  598. switch( Format )
  599. {
  600. case PLOT_FORMAT_GERBER:
  601. SelectD_CODE_For_LineDraw( thickness );
  602. switch(pt_segm->m_Shape)
  603. {
  604. case S_CIRCLE:
  605. PlotCircle( PLOT_FORMAT_GERBER, thickness, start, radius );
  606. break;
  607. case S_ARC:
  608. PlotArc( PLOT_FORMAT_GERBER, start,
  609. StAngle, EndAngle, radius, thickness );
  610. break;
  611. case S_CURVE:
  612. for (unsigned int i=1; i < pt_segm->m_BezierPoints.size(); i++) {
  613. PlotGERBERLine( pt_segm->m_BezierPoints[i-1], pt_segm->m_BezierPoints[i], thickness);
  614. }
  615. break;
  616. default:
  617. PlotGERBERLine( start, end, thickness );
  618. }
  619. break;
  620. case PLOT_FORMAT_HPGL:
  621. switch(pt_segm->m_Shape)
  622. {
  623. case S_CIRCLE:
  624. PlotCircle( PLOT_FORMAT_HPGL, thickness, start, radius );
  625. break;
  626. case S_ARC:
  627. PlotArc( PLOT_FORMAT_HPGL, start, StAngle, EndAngle, radius, thickness );
  628. break;
  629. case S_CURVE:
  630. for (unsigned int i=1; i < pt_segm->m_BezierPoints.size(); i++) {
  631. Plot_Filled_Segment_HPGL( pt_segm->m_BezierPoints[i-1], pt_segm->m_BezierPoints[i], thickness,(GRFillMode) g_Plot_Mode);
  632. }
  633. break;
  634. default:
  635. Plot_Filled_Segment_HPGL( start, end, thickness, (GRFillMode) g_Plot_Mode );
  636. }
  637. break;
  638. case PLOT_FORMAT_POST:
  639. switch(pt_segm->m_Shape)
  640. {
  641. case S_CIRCLE:
  642. PlotCircle( PLOT_FORMAT_POST, thickness, start, radius );
  643. break;
  644. case S_ARC:
  645. PlotArc( PLOT_FORMAT_POST, start,
  646. StAngle, EndAngle, radius, thickness );
  647. break;
  648. case S_CURVE:
  649. for (unsigned int i=1; i < pt_segm->m_BezierPoints.size(); i++) {
  650. PlotFilledSegmentPS( pt_segm->m_BezierPoints[i-1], pt_segm->m_BezierPoints[i], thickness);
  651. }
  652. break;
  653. default:
  654. PlotFilledSegmentPS( start, end, thickness );
  655. }
  656. break;
  657. }
  658. }
  659. /*****************************************************************************/
  660. void PlotCircle( int format_plot, int thickness, wxPoint centre, int radius )
  661. /*****************************************************************************/
  662. /* routine de trace de 1 cercle de centre cx, cy */
  663. {
  664. switch( format_plot )
  665. {
  666. case PLOT_FORMAT_GERBER:
  667. SelectD_CODE_For_LineDraw( thickness );
  668. PlotCircle_GERBER( centre, radius, thickness );
  669. break;
  670. case PLOT_FORMAT_HPGL:
  671. trace_1_pastille_RONDE_HPGL( centre, radius * 2, FILAIRE );
  672. break;
  673. case PLOT_FORMAT_POST:
  674. PlotCirclePS( centre, radius * 2, false, thickness );
  675. break;
  676. }
  677. }
  678. /**********************************************************************/
  679. void PlotFilledPolygon( int format_plot, int nbpoints, int* coord )
  680. /**********************************************************************/
  681. /* plot a polygon */
  682. {
  683. switch( format_plot )
  684. {
  685. case PLOT_FORMAT_GERBER:
  686. PlotFilledPolygon_GERBER( nbpoints, coord );
  687. break;
  688. case PLOT_FORMAT_HPGL:
  689. PlotPolyHPGL( nbpoints, coord, true );
  690. break;
  691. case PLOT_FORMAT_POST:
  692. PlotPolyPS( nbpoints, coord, true );
  693. break;
  694. }
  695. }
  696. /**********************************************************************/
  697. void PlotPolygon( int format_plot, int nbpoints, int* coord, int width )
  698. /**********************************************************************/
  699. /* plot a non filled polygon
  700. */
  701. {
  702. switch( format_plot )
  703. {
  704. case PLOT_FORMAT_GERBER:
  705. SelectD_CODE_For_LineDraw( width );
  706. PlotPolygon_GERBER( nbpoints, coord, width );
  707. break;
  708. case PLOT_FORMAT_HPGL:
  709. {
  710. // Compute pen_dim (from g_HPGL_Pen_Diam in mils) in pcb units,
  711. // with plot scale (if Scale is 2, pen diametre is always g_HPGL_Pen_Diam
  712. // so apparent pen diam is real pen diam / Scale
  713. int pen_diam = wxRound( (g_HPGL_Pen_Diam * U_PCB) / Scale_X ); // Assume Scale_X # Scale_Y
  714. wxString msg;
  715. if( pen_diam >= width )
  716. PlotPolyHPGL( nbpoints, coord, false, width ); // PlotPolyHPGL does not handle width
  717. else
  718. {
  719. wxPoint start, end;
  720. start.x = *coord++;
  721. start.y = *coord++;
  722. for( int ii = 1; ii < nbpoints; ii++ )
  723. {
  724. end.x = *coord++;
  725. end.y = *coord++;
  726. Plot_Filled_Segment_HPGL( start, end, width, (GRFillMode) g_Plot_Mode );
  727. start = end;
  728. }
  729. }
  730. }
  731. break;
  732. case PLOT_FORMAT_POST:
  733. PlotPolyPS( nbpoints, coord, false, width );
  734. break;
  735. }
  736. }
  737. /************************************************************************/
  738. void PlotArc( int format_plot, wxPoint centre, int start_angle, int end_angle,
  739. int radius, int thickness )
  740. /************************************************************************/
  741. /* Polt 1 arc
  742. * start, end = angles in 1/10 degree for start and stop point
  743. */
  744. {
  745. int ii;
  746. int ox, oy, fx, fy;
  747. int delta; /* increment (en 0.1 degres) angulaire pour trace de cercles */
  748. if( g_Plot_Mode == FILAIRE )
  749. thickness = g_PlotLine_Width;
  750. if( IsPostScript( format_plot ) )
  751. {
  752. PlotArcPS( centre, start_angle, end_angle, radius, false, thickness );
  753. return;
  754. }
  755. // change due to Y axis is negative orientation on screen
  756. start_angle = -start_angle;
  757. end_angle = -end_angle;
  758. EXCHG( start_angle, end_angle );
  759. /* Correction pour petits cercles par rapport a l'thickness du trait */
  760. if( radius < (thickness * 10) )
  761. delta = 225; /* 16 segm pour 360 deg */
  762. if( radius < (thickness * 5) )
  763. delta = 300; /* 12 segm pour 360 deg */
  764. if( start_angle > end_angle )
  765. end_angle += 3600;
  766. ox = radius;
  767. oy = 0;
  768. RotatePoint( &ox, &oy, start_angle );
  769. if( format_plot == PLOT_FORMAT_GERBER )
  770. SelectD_CODE_For_LineDraw( thickness );
  771. delta = 120; /* un cercle sera trace en 3600/delta = 30 segments / cercle*/
  772. for( ii = start_angle + delta; ii < end_angle; ii += delta )
  773. {
  774. fx = radius;
  775. fy = 0;
  776. RotatePoint( &fx, &fy, ii );
  777. switch( format_plot )
  778. {
  779. case PLOT_FORMAT_GERBER:
  780. PlotGERBERLine( wxPoint( centre.x + ox, centre.y + oy ),
  781. wxPoint( centre.x + fx, centre.y + fy ), thickness );
  782. break;
  783. case PLOT_FORMAT_HPGL:
  784. Plot_Filled_Segment_HPGL( wxPoint( centre.x + ox, centre.y + oy ),
  785. wxPoint( centre.x + fx, centre.y + fy ),
  786. thickness, (GRFillMode) g_Plot_Mode );
  787. break;
  788. case PLOT_FORMAT_POST:
  789. break;
  790. }
  791. ox = fx;
  792. oy = fy;
  793. }
  794. fx = radius;
  795. fy = 0;
  796. RotatePoint( &fx, &fy, end_angle );
  797. switch( format_plot )
  798. {
  799. case PLOT_FORMAT_GERBER:
  800. PlotGERBERLine( wxPoint( centre.x + ox, centre.y + oy ),
  801. wxPoint( centre.x + fx, centre.y + fy ), thickness );
  802. break;
  803. case PLOT_FORMAT_HPGL:
  804. Plot_Filled_Segment_HPGL( wxPoint( centre.x + ox, centre.y + oy ),
  805. wxPoint( centre.x + fx, centre.y + fy ),
  806. thickness, (GRFillMode) g_Plot_Mode );
  807. break;
  808. case PLOT_FORMAT_POST:
  809. break;
  810. }
  811. }