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.

392 lines
14 KiB

16 years ago
16 years ago
16 years ago
17 years ago
17 years ago
17 years ago
17 years ago
17 years ago
  1. /************************************************************/
  2. /* print_board_functions.cpp: some functions to plot boards */
  3. /************************************************************/
  4. #include "fctsys.h"
  5. #include "gr_basic.h"
  6. #include "common.h"
  7. #include "class_drawpanel.h"
  8. #include "pcbnew.h"
  9. #include "wxPcbStruct.h"
  10. #include "class_board_design_settings.h"
  11. #include "pcbplot.h"
  12. #include "printout_controler.h"
  13. #include "colors_selection.h"
  14. #include "protos.h"
  15. static void Print_Module( WinEDA_DrawPanel* aPanel, wxDC* aDC, MODULE* aModule,
  16. int aDraw_mode, int aMasklayer,
  17. PRINT_PARAMETERS::DrillShapeOptT aDrillShapeOpt );
  18. /** Function WinEDA_ModuleEditFrame::PrintPage
  19. * Used to print the board (on printer, or when creating SVF files).
  20. * Print the board, but only layers allowed by aPrintMaskLayer
  21. * @param aDC = the print device context
  22. * @param aPrint_Sheet_Ref = true to print frame references
  23. * @param aPrint_Sheet_Ref = a 32 bits mask: bit n = 1 -> layer n is printed
  24. * @param aPrintMirrorMode = true to plot mirrored
  25. * @param aData = a pointer to an optional data (NULL if not used)
  26. */
  27. void WinEDA_ModuleEditFrame::PrintPage( wxDC* aDC,
  28. bool aPrint_Sheet_Ref,
  29. int aPrintMaskLayer,
  30. bool aPrintMirrorMode,
  31. void * aData)
  32. {
  33. MODULE* Module;
  34. int drawmode = GR_COPY;
  35. DISPLAY_OPTIONS save_opt;
  36. BOARD* Pcb = GetBoard();
  37. int defaultPenSize = 50;
  38. PRINT_PARAMETERS * printParameters = (PRINT_PARAMETERS*) aData; // can be null
  39. PRINT_PARAMETERS::DrillShapeOptT drillShapeOpt = PRINT_PARAMETERS::FULL_DRILL_SHAPE;
  40. if( printParameters )
  41. defaultPenSize = printParameters->m_PenDefaultSize;
  42. save_opt = DisplayOpt;
  43. DisplayOpt.ContrastModeDisplay = false;
  44. DisplayOpt.DisplayPadFill = true;
  45. DisplayOpt.DisplayViaFill = true;
  46. m_DisplayPadFill = DisplayOpt.DisplayPadFill;
  47. m_DisplayViaFill = DisplayOpt.DisplayViaFill;
  48. m_DisplayPadNum = DisplayOpt.DisplayPadNum = false;
  49. bool nctmp = GetBoard()->IsElementVisible(NO_CONNECTS_VISIBLE);
  50. GetBoard()->SetElementVisibility(NO_CONNECTS_VISIBLE, false);
  51. DisplayOpt.DisplayPadIsol = false;
  52. DisplayOpt.DisplayModEdge = FILLED;
  53. DisplayOpt.DisplayModText = FILLED;
  54. m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill = FILLED;
  55. DisplayOpt.ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE;
  56. DisplayOpt.DisplayDrawItems = FILLED;
  57. DisplayOpt.DisplayZonesMode = 0;
  58. DisplayOpt.DisplayNetNamesMode = 0;
  59. DrawPanel->m_PrintIsMirrored = aPrintMirrorMode;
  60. // The OR mode is used in color mode, but be aware the backgroud *must be
  61. // BLACK. In the print page dialog, we first print in BLACK, and after
  62. // reprint in color, on the black "local" backgroud, in OR mode the black
  63. // print is not made before, only a white page is printed
  64. if( GetGRForceBlackPenState() == false )
  65. drawmode = GR_OR;
  66. // Draw footprints, this is done at last in order to print the pad holes in
  67. // white (or g_DrawBgColor) after the tracks and zones
  68. Module = (MODULE*) Pcb->m_Modules;
  69. int tmp = D_PAD::m_PadSketchModePenSize;
  70. D_PAD::m_PadSketchModePenSize = defaultPenSize;
  71. for( ; Module != NULL; Module = Module->Next() )
  72. {
  73. Print_Module( DrawPanel, aDC, Module, drawmode, aPrintMaskLayer, drillShapeOpt );
  74. }
  75. D_PAD::m_PadSketchModePenSize = tmp;
  76. if( aPrint_Sheet_Ref )
  77. TraceWorkSheet( aDC, GetScreen(), defaultPenSize );
  78. DrawPanel->m_PrintIsMirrored = false;
  79. DisplayOpt = save_opt;
  80. m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill;
  81. m_DisplayPadFill = DisplayOpt.DisplayPadFill;
  82. m_DisplayViaFill = DisplayOpt.DisplayViaFill;
  83. m_DisplayPadNum = DisplayOpt.DisplayPadNum;
  84. GetBoard()->SetElementVisibility(NO_CONNECTS_VISIBLE, nctmp);
  85. }
  86. /** WinEDA_PcbFrame::Function PrintPage
  87. * Used to print the board (on printer, or when creating SVF files).
  88. * Print the board, but only layers allowed by aPrintMaskLayer
  89. * @param aDC = the print device context
  90. * @param aPrint_Sheet_Ref = true to print frame references
  91. * @param aPrint_Sheet_Ref = a 32 bits mask: bit n = 1 -> layer n is printed
  92. * @param aPrintMirrorMode = true to plot mirrored
  93. * @param aData = a pointer to an optional data (NULL if not used)
  94. */
  95. void WinEDA_PcbFrame::PrintPage( wxDC* aDC,
  96. bool aPrint_Sheet_Ref,
  97. int aPrintMaskLayer,
  98. bool aPrintMirrorMode,
  99. void * aData)
  100. {
  101. MODULE* Module;
  102. int drawmode = GR_COPY;
  103. DISPLAY_OPTIONS save_opt;
  104. TRACK* pt_piste;
  105. BOARD* Pcb = GetBoard();
  106. int defaultPenSize = 50;
  107. bool onePagePerLayer = false;
  108. PRINT_PARAMETERS * printParameters = (PRINT_PARAMETERS*) aData; // can be null
  109. if( printParameters && printParameters->m_OptionPrintPage == 0 )
  110. onePagePerLayer = true;
  111. PRINT_PARAMETERS::DrillShapeOptT drillShapeOpt = PRINT_PARAMETERS::FULL_DRILL_SHAPE;
  112. if( printParameters )
  113. {
  114. drillShapeOpt = printParameters->m_DrillShapeOpt;
  115. defaultPenSize = printParameters->m_PenDefaultSize;
  116. }
  117. save_opt = DisplayOpt;
  118. int activeLayer = GetScreen()->m_Active_Layer;
  119. DisplayOpt.ContrastModeDisplay = false;
  120. DisplayOpt.DisplayPadFill = true;
  121. DisplayOpt.DisplayViaFill = true;
  122. if( (aPrintMaskLayer & ALL_CU_LAYERS) == 0 )
  123. {
  124. if( onePagePerLayer )
  125. { // We can print mask layers (solder mask and solder paste) with the actual pad sizes
  126. // To do that, we must set ContrastModeDisplay to true and set the GetScreen()->m_Active_Layer
  127. // to the current printed layer
  128. DisplayOpt.ContrastModeDisplay = true;
  129. DisplayOpt.DisplayPadFill = true;
  130. // Calculate the active layer number to print from its mask layer:
  131. GetScreen()->m_Active_Layer = 0;
  132. for(int kk = 0; kk < 32; kk ++ )
  133. {
  134. if( ((1 << kk) & aPrintMaskLayer) != 0 )
  135. {
  136. GetScreen()->m_Active_Layer = kk;
  137. break;
  138. }
  139. }
  140. // pads on Silkscreen layer are usually plot in sketch mode:
  141. if( (GetScreen()->m_Active_Layer == SILKSCREEN_N_BACK) ||
  142. (GetScreen()->m_Active_Layer == SILKSCREEN_N_FRONT) )
  143. DisplayOpt.DisplayPadFill = false;
  144. }
  145. else
  146. {
  147. DisplayOpt.DisplayPadFill = false;
  148. }
  149. }
  150. m_DisplayPadFill = DisplayOpt.DisplayPadFill;
  151. m_DisplayViaFill = DisplayOpt.DisplayViaFill;
  152. m_DisplayPadNum = DisplayOpt.DisplayPadNum = false;
  153. bool nctmp = GetBoard()->IsElementVisible(NO_CONNECTS_VISIBLE);
  154. GetBoard()->SetElementVisibility(NO_CONNECTS_VISIBLE, false);
  155. DisplayOpt.DisplayPadIsol = false;
  156. DisplayOpt.DisplayModEdge = FILLED;
  157. DisplayOpt.DisplayModText = FILLED;
  158. m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill = FILLED;
  159. DisplayOpt.ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE;
  160. DisplayOpt.DisplayDrawItems = FILLED;
  161. DisplayOpt.DisplayZonesMode = 0;
  162. DisplayOpt.DisplayNetNamesMode = 0;
  163. DrawPanel->m_PrintIsMirrored = aPrintMirrorMode;
  164. // The OR mode is used in color mode, but be aware the backgroud *must be
  165. // BLACK. In the print page dialog, we first print in BLACK, and after
  166. // reprint in color, on the black "local" backgroud, in OR mode the black
  167. // print is not made before, only a white page is printed
  168. if( GetGRForceBlackPenState() == false )
  169. drawmode = GR_OR;
  170. /* Print the pcb graphic items (texts, ...) */
  171. GRSetDrawMode( aDC, drawmode );
  172. for( BOARD_ITEM* item = Pcb->m_Drawings; item; item = item->Next() )
  173. {
  174. switch( item->Type() )
  175. {
  176. case TYPE_DRAWSEGMENT:
  177. case TYPE_COTATION:
  178. case TYPE_TEXTE:
  179. case TYPE_MIRE:
  180. if( ( ( 1 << item->GetLayer() ) & aPrintMaskLayer ) == 0 )
  181. break;
  182. item->Draw( DrawPanel, aDC, drawmode );
  183. break;
  184. case TYPE_MARKER_PCB:
  185. default:
  186. break;
  187. }
  188. }
  189. /* Print tracks */
  190. pt_piste = Pcb->m_Track;
  191. for( ; pt_piste != NULL; pt_piste = pt_piste->Next() )
  192. {
  193. if( ( aPrintMaskLayer & pt_piste->ReturnMaskLayer() ) == 0 )
  194. continue;
  195. if( pt_piste->Type() == TYPE_VIA ) /* VIA encountered. */
  196. {
  197. int rayon = pt_piste->m_Width >> 1;
  198. int color = g_ColorsSettings.GetItemColor(VIAS_VISIBLE+pt_piste->m_Shape);
  199. GRSetDrawMode( aDC, drawmode );
  200. GRFilledCircle( &DrawPanel->m_ClipBox, aDC,
  201. pt_piste->m_Start.x,
  202. pt_piste->m_Start.y,
  203. rayon,
  204. 0, color, color );
  205. }
  206. else
  207. pt_piste->Draw( DrawPanel, aDC, drawmode );
  208. }
  209. pt_piste = Pcb->m_Zone;
  210. for( ; pt_piste != NULL; pt_piste = pt_piste->Next() )
  211. {
  212. if( ( aPrintMaskLayer & pt_piste->ReturnMaskLayer() ) == 0 )
  213. continue;
  214. pt_piste->Draw( DrawPanel, aDC, drawmode );
  215. }
  216. /* Draw filled areas (i.e. zones) */
  217. for( int ii = 0; ii < Pcb->GetAreaCount(); ii++ )
  218. {
  219. ZONE_CONTAINER* zone = Pcb->GetArea( ii );
  220. if( ( aPrintMaskLayer & ( 1 << zone->GetLayer() ) ) == 0 )
  221. continue;
  222. zone->DrawFilledArea( DrawPanel, aDC, drawmode );
  223. }
  224. // Draw footprints, this is done at last in order to print the pad holes in
  225. // white (or g_DrawBgColor) after the tracks and zones
  226. Module = (MODULE*) Pcb->m_Modules;
  227. int tmp = D_PAD::m_PadSketchModePenSize;
  228. D_PAD::m_PadSketchModePenSize = defaultPenSize;
  229. for( ; Module != NULL; Module = Module->Next() )
  230. {
  231. Print_Module( DrawPanel, aDC, Module, drawmode, aPrintMaskLayer, drillShapeOpt );
  232. }
  233. D_PAD::m_PadSketchModePenSize = tmp;
  234. /* Print via holes in bg color: Not sure it is good for buried or blind
  235. * vias */
  236. if( drillShapeOpt != PRINT_PARAMETERS::NO_DRILL_SHAPE )
  237. {
  238. pt_piste = Pcb->m_Track;
  239. int color = g_DrawBgColor;
  240. bool blackpenstate = GetGRForceBlackPenState();
  241. GRForceBlackPen( false );
  242. GRSetDrawMode( aDC, GR_COPY );
  243. for( ; pt_piste != NULL; pt_piste = pt_piste->Next() )
  244. {
  245. if( ( aPrintMaskLayer & pt_piste->ReturnMaskLayer() ) == 0 )
  246. continue;
  247. if( pt_piste->Type() == TYPE_VIA ) /* VIA encountered. */
  248. {
  249. int diameter;
  250. if( drillShapeOpt == PRINT_PARAMETERS::SMALL_DRILL_SHAPE )
  251. diameter = min( SMALL_DRILL, pt_piste->GetDrillValue());
  252. else
  253. diameter = pt_piste->GetDrillValue();
  254. GRFilledCircle( &DrawPanel->m_ClipBox, aDC,
  255. pt_piste->m_Start.x, pt_piste->m_Start.y,
  256. diameter/2,
  257. 0, color, color );
  258. }
  259. }
  260. GRForceBlackPen( blackpenstate );
  261. }
  262. if( aPrint_Sheet_Ref )
  263. TraceWorkSheet( aDC, GetScreen(), defaultPenSize );
  264. DrawPanel->m_PrintIsMirrored = false;
  265. DisplayOpt = save_opt;
  266. GetScreen()->m_Active_Layer = activeLayer;
  267. m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill;
  268. m_DisplayPadFill = DisplayOpt.DisplayPadFill;
  269. m_DisplayViaFill = DisplayOpt.DisplayViaFill;
  270. m_DisplayPadNum = DisplayOpt.DisplayPadNum;
  271. GetBoard()->SetElementVisibility(NO_CONNECTS_VISIBLE, nctmp);
  272. }
  273. static void Print_Module( WinEDA_DrawPanel* aPanel, wxDC* aDC, MODULE* aModule,
  274. int aDraw_mode, int aMasklayer,
  275. PRINT_PARAMETERS::DrillShapeOptT aDrillShapeOpt )
  276. {
  277. D_PAD* pt_pad;
  278. EDA_BaseStruct* PtStruct;
  279. TEXTE_MODULE* TextMod;
  280. int mlayer;
  281. /* Print pads */
  282. pt_pad = aModule->m_Pads;
  283. for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
  284. {
  285. if( (pt_pad->m_Masque_Layer & aMasklayer ) == 0 )
  286. continue;
  287. // Manage hole according to the print drill option
  288. wxSize drill_tmp = pt_pad->m_Drill;
  289. switch ( aDrillShapeOpt )
  290. {
  291. case PRINT_PARAMETERS::NO_DRILL_SHAPE:
  292. pt_pad->m_Drill = wxSize(0,0);
  293. break;
  294. case PRINT_PARAMETERS::SMALL_DRILL_SHAPE:
  295. pt_pad->m_Drill.x = MIN(SMALL_DRILL,pt_pad->m_Drill.x);
  296. pt_pad->m_Drill.y = MIN(SMALL_DRILL,pt_pad->m_Drill.y);
  297. break;
  298. case PRINT_PARAMETERS::FULL_DRILL_SHAPE:
  299. // Do nothing
  300. break;
  301. }
  302. pt_pad->Draw( aPanel, aDC, aDraw_mode );
  303. pt_pad->m_Drill = drill_tmp;
  304. }
  305. /* Print footprint graphic shapes */
  306. PtStruct = aModule->m_Drawings;
  307. mlayer = g_TabOneLayerMask[aModule->GetLayer()];
  308. if( aModule->GetLayer() == LAYER_N_BACK )
  309. mlayer = SILKSCREEN_LAYER_BACK;
  310. else if( aModule->GetLayer() == LAYER_N_FRONT )
  311. mlayer = SILKSCREEN_LAYER_FRONT;
  312. if( mlayer & aMasklayer )
  313. {
  314. if( !aModule->m_Reference->m_NoShow )
  315. aModule->m_Reference->Draw( aPanel, aDC, aDraw_mode );
  316. if( !aModule->m_Value->m_NoShow )
  317. aModule->m_Value->Draw( aPanel, aDC, aDraw_mode );
  318. }
  319. for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
  320. {
  321. switch( PtStruct->Type() )
  322. {
  323. case TYPE_TEXTE_MODULE:
  324. if( (mlayer & aMasklayer ) == 0 )
  325. break;
  326. TextMod = (TEXTE_MODULE*) PtStruct;
  327. TextMod->Draw( aPanel, aDC, aDraw_mode );
  328. break;
  329. case TYPE_EDGE_MODULE:
  330. {
  331. EDGE_MODULE* edge = (EDGE_MODULE*) PtStruct;
  332. if( ( g_TabOneLayerMask[edge->GetLayer()] & aMasklayer ) == 0 )
  333. break;
  334. edge->Draw( aPanel, aDC, aDraw_mode );
  335. break;
  336. }
  337. default:
  338. break;
  339. }
  340. }
  341. }