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.

498 lines
15 KiB

18 years ago
18 years ago
18 years ago
18 years ago
17 years ago
  1. /****************/
  2. /* tracepcb.cpp */
  3. /****************/
  4. /*
  5. * Redraw the screen.
  6. */
  7. #include "fctsys.h"
  8. #include "gr_basic.h"
  9. #include "common.h"
  10. #include "class_drawpanel.h"
  11. #include "drawtxt.h"
  12. #include "gerbview.h"
  13. #include "pcbplot.h"
  14. #include "protos.h"
  15. #include "class_board_design_settings.h"
  16. #include "colors_selection.h"
  17. /***************/
  18. /* tracepcb.cpp */
  19. /***************/
  20. static void Draw_Track_Buffer( WinEDA_DrawPanel* panel,
  21. wxDC* DC,
  22. BOARD* Pcb,
  23. int drawmode,
  24. int printmasklayer );
  25. static void Affiche_DCodes_Pistes( WinEDA_DrawPanel* panel, wxDC* DC,
  26. BOARD* Pcb, int drawmode );
  27. /** Function PrintPage
  28. * Used to print the board (on printer, or when creating SVF files).
  29. * Print the board, but only layers allowed by aPrintMaskLayer
  30. * @param aDC = the print device context
  31. * @param aPrint_Sheet_Ref = true to print frame references
  32. * @param aPrint_Sheet_Ref = a 32 bits mask: bit n = 1 -> layer n is printed
  33. * @param aPrintMirrorMode = true to plot mirrored
  34. * @param aData = a pointer to an optional data (not used here: can be NULL)
  35. */
  36. void WinEDA_DrawPanel::PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref, int aPrintmasklayer,
  37. bool aPrintMirrorMode, void * aData )
  38. {
  39. DISPLAY_OPTIONS save_opt;
  40. int DisplayPolygonsModeImg;
  41. save_opt = DisplayOpt;
  42. DisplayOpt.DisplayPcbTrackFill = FILLED;
  43. DisplayOpt.ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE;
  44. DisplayOpt.DisplayDrawItems = FILLED;
  45. DisplayOpt.DisplayZonesMode = 0;
  46. DisplayPolygonsModeImg = g_DisplayPolygonsModeSketch;
  47. g_DisplayPolygonsModeSketch = 0;
  48. m_PrintIsMirrored = aPrintMirrorMode;
  49. ( (WinEDA_GerberFrame*) m_Parent )->Trace_Gerber( aDC, GR_COPY, aPrintmasklayer );
  50. if( aPrint_Sheet_Ref )
  51. m_Parent->TraceWorkSheet( aDC, GetScreen(), 0 );
  52. m_PrintIsMirrored = false;
  53. DisplayOpt = save_opt;
  54. g_DisplayPolygonsModeSketch = DisplayPolygonsModeImg;
  55. }
  56. /*******************************************************************/
  57. void WinEDA_GerberFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg )
  58. /*******************************************************************/
  59. /* Redraws the full screen, including axis and grid
  60. */
  61. {
  62. PCB_SCREEN* screen = (PCB_SCREEN*)GetScreen();
  63. if( !GetBoard() )
  64. return;
  65. ActiveScreen = screen;
  66. GRSetDrawMode( DC, GR_COPY );
  67. DrawPanel->DrawBackGround( DC );
  68. Trace_Gerber( DC, GR_COPY, -1 );
  69. TraceWorkSheet( DC, screen, 0 );
  70. if( DrawPanel->ManageCurseur )
  71. DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
  72. DrawPanel->DrawCursor( DC );
  73. }
  74. /********************************************************************/
  75. void BOARD::Draw( WinEDA_DrawPanel* aPanel, wxDC* DC,
  76. int aDrawMode, const wxPoint& offset )
  77. /********************************************************************/
  78. /* Redraw the BOARD items but not cursors, axis or grid */
  79. // @todo: replace WinEDA_GerberFrame::Trace_Gerber() by this function
  80. {
  81. }
  82. /***********************************************************************************/
  83. void WinEDA_GerberFrame::Trace_Gerber( wxDC* DC, int draw_mode, int printmasklayer )
  84. /***********************************************************************************/
  85. /* Trace all elements of PCBs (i.e Spots, filled polygons or lines) on the active screen
  86. * @param DC = current device context
  87. * @param draw_mode = draw mode for the device context (GR_COPY, GR_OR, GR_XOR ..)
  88. * @param printmasklayer = mask for allowed layer (=-1 to draw all layers)
  89. */
  90. {
  91. if( !GetBoard() )
  92. return;
  93. bool erase = false;
  94. int Color;
  95. bool filled;
  96. // Draw filled polygons
  97. std::vector<wxPoint> points;
  98. // minimize reallocations of the vector's internal array by starting with a good sized one.
  99. points.reserve(10000);
  100. int tmp = GetPenMinWidth( );
  101. SetPenMinWidth(0 );
  102. for( TRACK* track = GetBoard()->m_Zone; track; track = track->Next() )
  103. {
  104. if( !(track->ReturnMaskLayer() & printmasklayer) )
  105. continue;
  106. if( GetBoard()->IsLayerVisible( track->GetLayer() ) == false )
  107. continue;
  108. // D(printf("D:%p\n", track );)
  109. if( track->GetNet() == 0 ) // StartPoint
  110. {
  111. if( points.size() ) // we have found a new polygon: Draw the old polygon
  112. {
  113. if( erase )
  114. {
  115. Color = g_DrawBgColor;
  116. filled = true;
  117. }
  118. else
  119. {
  120. Color = g_ColorsSettings.GetLayerColor( track->GetLayer() );
  121. filled = (g_DisplayPolygonsModeSketch == 0);
  122. }
  123. GRClosedPoly( &DrawPanel->m_ClipBox, DC, points.size(), &points[0],
  124. filled, Color, Color );
  125. }
  126. erase = ( track->m_Flags & DRAW_ERASED );
  127. points.clear();
  128. points.push_back( track->m_Start );
  129. points.push_back( track->m_End );
  130. }
  131. else
  132. {
  133. points.push_back( track->m_End );
  134. }
  135. if( track->Next() == NULL ) // Last point
  136. {
  137. if( erase )
  138. {
  139. Color = g_DrawBgColor;
  140. filled = true;
  141. }
  142. else
  143. {
  144. Color = g_ColorsSettings.GetLayerColor( track->GetLayer() );
  145. filled = (g_DisplayPolygonsModeSketch == 0);
  146. }
  147. GRClosedPoly( &DrawPanel->m_ClipBox, DC, points.size(), &points[0],
  148. filled, Color, Color );
  149. }
  150. }
  151. // Draw tracks and flashes down here. This will probably not be a final solution to drawing order issues
  152. Draw_Track_Buffer( DrawPanel, DC, GetBoard(), draw_mode, printmasklayer );
  153. SetPenMinWidth( tmp );
  154. if( IsElementVisible( DCODES_VISIBLE) )
  155. Affiche_DCodes_Pistes( DrawPanel, DC, GetBoard(), GR_COPY );
  156. GetScreen()->ClrRefreshReq();
  157. }
  158. /***************************************************************************************************/
  159. void Draw_Track_Buffer( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb, int draw_mode,
  160. int printmasklayer )
  161. /***************************************************************************************************/
  162. /* Function to draw the tracks (i.e Spots or lines) in gerbview
  163. * Polygons are not handled here (there are in Pcb->m_Zone)
  164. * @param DC = device context to draw
  165. * @param Pcb = Board to draw (only Pcb->m_Track is used)
  166. * @param draw_mode = draw mode for the device context (GR_COPY, GR_OR, GR_XOR ..)
  167. * @param printmasklayer = mask for allowed layer (=-1 to draw all layers)
  168. */
  169. {
  170. int layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
  171. GERBER* gerber = g_GERBER_List[layer];
  172. int dcode_hightlight = 0;
  173. if( gerber )
  174. dcode_hightlight = gerber->m_Selected_Tool;
  175. for( TRACK* track = Pcb->m_Track; track; track = track->Next() )
  176. {
  177. if( !(track->ReturnMaskLayer() & printmasklayer) )
  178. continue;
  179. // D(printf("D:%p\n", track );)
  180. if( dcode_hightlight == track->GetNet() && track->GetLayer()==layer )
  181. Trace_Segment( Pcb, panel, DC, track, draw_mode | GR_SURBRILL );
  182. else
  183. Trace_Segment( Pcb, panel, DC, track, draw_mode );
  184. }
  185. }
  186. #if 1
  187. /***********************************************************************************/
  188. void Trace_Segment( BOARD* aBrd, WinEDA_DrawPanel* panel, wxDC* DC, TRACK* track, int draw_mode )
  189. /***********************************************************************************/
  190. /* Trace 1 segment of track (segment, spot...).
  191. * Parameters :
  192. * Track = a pointer on of the description of the track
  193. * draw_mode = mode ( GR_XOR, GR_OR..)
  194. */
  195. {
  196. int l_piste;
  197. int color;
  198. int fillopt;
  199. int radius;
  200. int halfPenWidth;
  201. static bool show_err;
  202. if( track->m_Flags & DRAW_ERASED ) // draw in background color, used by classs TRACK in gerbview
  203. {
  204. color = g_DrawBgColor;
  205. }
  206. else
  207. {
  208. if( aBrd->IsLayerVisible( track->GetLayer() ) == false )
  209. return;
  210. color = aBrd->GetLayerColor( track->GetLayer() );
  211. if( draw_mode & GR_SURBRILL )
  212. {
  213. if( draw_mode & GR_AND )
  214. color &= ~HIGHT_LIGHT_FLAG;
  215. else
  216. color |= HIGHT_LIGHT_FLAG;
  217. }
  218. if( color & HIGHT_LIGHT_FLAG )
  219. color = ColorRefs[color & MASKCOLOR].m_LightColor;
  220. }
  221. GRSetDrawMode( DC, draw_mode );
  222. fillopt = DisplayOpt.DisplayPcbTrackFill ? FILLED : SKETCH;
  223. switch( track->m_Shape )
  224. {
  225. case S_CIRCLE:
  226. radius = (int) hypot( (double) (track->m_End.x - track->m_Start.x),
  227. (double) (track->m_End.y - track->m_Start.y) );
  228. halfPenWidth = track->m_Width >> 1;
  229. #ifdef USE_WX_ZOOM
  230. if( DC->LogicalToDeviceXRel( halfPenWidth ) < L_MIN_DESSIN )
  231. #else
  232. if( panel->GetScreen()->Scale( halfPenWidth ) < L_MIN_DESSIN )
  233. #endif
  234. {
  235. GRCircle( &panel->m_ClipBox, DC, track->m_Start.x,
  236. track->m_Start.y, radius, 0, color );
  237. }
  238. if( fillopt == SKETCH )
  239. {
  240. // draw the border of the pen's path using two circles, each as narrow as possible
  241. GRCircle( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
  242. radius - halfPenWidth, 0, color );
  243. GRCircle( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
  244. radius + halfPenWidth, 0, color );
  245. }
  246. else
  247. {
  248. GRCircle( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
  249. radius, track->m_Width, color );
  250. }
  251. break;
  252. case S_ARC:
  253. if( fillopt == SKETCH )
  254. {
  255. GRArc1( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
  256. track->m_End.x, track->m_End.y,
  257. track->m_Param, track->GetSubNet(), 0, color );
  258. }
  259. else
  260. {
  261. GRArc1( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
  262. track->m_End.x, track->m_End.y,
  263. track->m_Param, track->GetSubNet(),
  264. track->m_Width, color );
  265. }
  266. break;
  267. case S_SPOT_CIRCLE:
  268. radius = track->m_Width >> 1;
  269. fillopt = DisplayOpt.DisplayPadFill ? FILLED : SKETCH;
  270. #ifdef USE_WX_ZOOM
  271. if( DC->LogicalToDeviceXRel( radius ) < L_MIN_DESSIN )
  272. #else
  273. if( panel->GetScreen()->Scale( radius ) < L_MIN_DESSIN )
  274. #endif
  275. {
  276. GRCircle( &panel->m_ClipBox, DC, track->m_Start.x,
  277. track->m_Start.y, radius, 0, color );
  278. }
  279. else if( fillopt == SKETCH )
  280. {
  281. GRCircle( &panel->m_ClipBox, DC, track->m_Start.x,
  282. track->m_Start.y, radius, 0, color );
  283. }
  284. else
  285. {
  286. GRFilledCircle( &panel->m_ClipBox, DC, track->m_Start.x,
  287. track->m_Start.y, radius, 0, color, color );
  288. }
  289. break;
  290. case S_SPOT_RECT:
  291. case S_RECT:
  292. l_piste = track->m_Width >> 1;
  293. fillopt = DisplayOpt.DisplayPadFill ? FILLED : SKETCH;
  294. #ifdef USE_WX_ZOOM
  295. if( DC->LogicalToDeviceXRel( l_piste ) < L_MIN_DESSIN )
  296. #else
  297. if( panel->GetScreen()->Scale( l_piste ) < L_MIN_DESSIN )
  298. #endif
  299. {
  300. GRLine( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
  301. track->m_End.x, track->m_End.y, 0, color );
  302. }
  303. else if( fillopt == SKETCH )
  304. {
  305. GRRect( &panel->m_ClipBox, DC,
  306. track->m_Start.x - l_piste,
  307. track->m_Start.y - l_piste,
  308. track->m_End.x + l_piste,
  309. track->m_End.y + l_piste,
  310. 0, color );
  311. }
  312. else
  313. {
  314. GRFilledRect( &panel->m_ClipBox, DC,
  315. track->m_Start.x - l_piste,
  316. track->m_Start.y - l_piste,
  317. track->m_End.x + l_piste,
  318. track->m_End.y + l_piste,
  319. 0, color, color );
  320. }
  321. break;
  322. case S_SPOT_OVALE:
  323. fillopt = DisplayOpt.DisplayPadFill ? FILLED : SKETCH;
  324. case S_SEGMENT:
  325. l_piste = track->m_Width >> 1;
  326. #ifdef USE_WX_ZOOM
  327. if( DC->LogicalToDeviceXRel( l_piste ) < L_MIN_DESSIN )
  328. #else
  329. if( panel->GetScreen()->Scale( l_piste ) < L_MIN_DESSIN )
  330. #endif
  331. {
  332. GRLine( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
  333. track->m_End.x, track->m_End.y, 0, color );
  334. break;
  335. }
  336. if( fillopt == SKETCH )
  337. {
  338. GRCSegm( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
  339. track->m_End.x, track->m_End.y, track->m_Width, color );
  340. }
  341. else
  342. {
  343. GRFillCSegm( &panel->m_ClipBox, DC, track->m_Start.x,
  344. track->m_Start.y, track->m_End.x, track->m_End.y,
  345. track->m_Width, color );
  346. }
  347. break;
  348. default:
  349. if( !show_err )
  350. {
  351. wxMessageBox( wxT( "Trace_Segment() type error" ) );
  352. show_err = TRUE;
  353. }
  354. break;
  355. }
  356. }
  357. #endif
  358. /*****************************************************************************************/
  359. void Affiche_DCodes_Pistes( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb, int drawmode )
  360. /*****************************************************************************************/
  361. {
  362. TRACK* track;
  363. wxPoint pos;
  364. int width, orient;
  365. wxString Line;
  366. GRSetDrawMode( DC, drawmode );
  367. track = Pcb->m_Track;
  368. for( ; track != NULL; track = track->Next() )
  369. {
  370. if( Pcb->IsLayerVisible( track->GetLayer() ) == false )
  371. continue;
  372. if( (track->m_Shape == S_ARC)
  373. || (track->m_Shape == S_CIRCLE)
  374. || (track->m_Shape == S_ARC_RECT) )
  375. {
  376. pos.x = track->m_Start.x;
  377. pos.y = track->m_Start.y;
  378. }
  379. else
  380. {
  381. pos.x = (track->m_Start.x + track->m_End.x) / 2;
  382. pos.y = (track->m_Start.y + track->m_End.y) / 2;
  383. }
  384. Line.Printf( wxT( "D%d" ), track->GetNet() );
  385. width = track->m_Width;
  386. orient = TEXT_ORIENT_HORIZ;
  387. if( track->m_Shape >= S_SPOT_CIRCLE ) // forme flash
  388. {
  389. width /= 3;
  390. }
  391. else // lines
  392. {
  393. int dx, dy;
  394. dx = track->m_Start.x - track->m_End.x;
  395. dy = track->m_Start.y - track->m_End.y;
  396. if( abs( dx ) < abs( dy ) )
  397. orient = TEXT_ORIENT_VERT;
  398. width /= 2;
  399. }
  400. int color = g_ColorsSettings.GetItemColor(DCODES_VISIBLE);
  401. DrawGraphicText( panel, DC,
  402. pos, (EDA_Colors) color, Line,
  403. orient, wxSize( width, width ),
  404. GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
  405. 0, false, false, false);
  406. }
  407. }
  408. /* Virtual fonction needed by the PCB_SCREEN class derived from BASE_SCREEN
  409. * this is a virtual pure function in BASE_SCREEN
  410. * do nothing in gerbview
  411. * could be removed later
  412. */
  413. void PCB_SCREEN::ClearUndoORRedoList(UNDO_REDO_CONTAINER&, int )
  414. {
  415. }