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.

368 lines
12 KiB

14 years ago
12 years ago
14 years ago
14 years ago
12 years ago
14 years ago
14 years ago
14 years ago
14 years ago
13 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
  1. /**
  2. * @file print_board_functions.cpp
  3. * @brief Functions to print boards.
  4. */
  5. /*
  6. * This program source code file is part of KiCad, a free EDA CAD application.
  7. *
  8. * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License
  12. * as published by the Free Software Foundation; either version 2
  13. * of the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, you may find one here:
  22. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  23. * or you may search the http://www.gnu.org website for the version 2 license,
  24. * or you may write to the Free Software Foundation, Inc.,
  25. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  26. */
  27. #include <fctsys.h>
  28. #include <class_drawpanel.h>
  29. #include <pcb_edit_frame.h>
  30. #include <printout_controler.h>
  31. #include <class_board.h>
  32. #include <class_module.h>
  33. #include <class_edge_mod.h>
  34. #include <class_track.h>
  35. #include <class_zone.h>
  36. #include <pcbnew.h>
  37. #include <pcbplot.h>
  38. #include <footprint_edit_frame.h>
  39. static void Print_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, MODULE* aModule,
  40. GR_DRAWMODE aDraw_mode, LSET aMasklayer,
  41. PRINT_PARAMETERS::DrillShapeOptT aDrillShapeOpt );
  42. void FOOTPRINT_EDIT_FRAME::PrintPage( wxDC* aDC,
  43. LSET aPrintMaskLayer,
  44. bool aPrintMirrorMode,
  45. void * aData)
  46. {
  47. const GR_DRAWMODE drawmode = (GR_DRAWMODE) 0;
  48. int defaultPenSize = Millimeter2iu( 0.2 );
  49. auto displ_opts = (PCB_DISPLAY_OPTIONS*) GetDisplayOptions();
  50. PCB_DISPLAY_OPTIONS save_opt;
  51. PRINT_PARAMETERS * printParameters = (PRINT_PARAMETERS*) aData; // can be null
  52. PRINT_PARAMETERS::DrillShapeOptT drillShapeOpt = PRINT_PARAMETERS::FULL_DRILL_SHAPE;
  53. if( printParameters )
  54. defaultPenSize = printParameters->m_PenDefaultSize;
  55. save_opt = *displ_opts;
  56. displ_opts->m_ContrastModeDisplay = false;
  57. displ_opts->m_DisplayPadFill = true;
  58. displ_opts->m_DisplayViaFill = true;
  59. displ_opts->m_DisplayPadNum = false;
  60. bool nctmp = GetBoard()->IsElementVisible( LAYER_NO_CONNECTS );
  61. GetBoard()->SetElementVisibility( LAYER_NO_CONNECTS, false );
  62. displ_opts->m_DisplayPadIsol = false;
  63. displ_opts->m_DisplayModEdgeFill = FILLED;
  64. displ_opts->m_DisplayModTextFill = FILLED;
  65. displ_opts->m_DisplayPcbTrackFill = true;
  66. displ_opts->m_ShowTrackClearanceMode = PCB_DISPLAY_OPTIONS::DO_NOT_SHOW_CLEARANCE;
  67. displ_opts->m_DisplayDrawItemsFill = FILLED;
  68. displ_opts->m_DisplayZonesMode = 0;
  69. displ_opts->m_DisplayNetNamesMode = 0;
  70. m_canvas->SetPrintMirrored( aPrintMirrorMode );
  71. // Draw footprints, this is done at last in order to print the pad holes in
  72. // white after the tracks and zones
  73. int tmp = D_PAD::m_PadSketchModePenSize;
  74. D_PAD::m_PadSketchModePenSize = defaultPenSize;
  75. wxSize pageSizeIU = GetPageSizeIU() / 2;
  76. wxPoint offset( pageSizeIU.x, pageSizeIU.y );
  77. for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
  78. {
  79. module->Move( offset );
  80. Print_Module( m_canvas, aDC, module, drawmode, aPrintMaskLayer, drillShapeOpt );
  81. module->Move( -offset );
  82. }
  83. D_PAD::m_PadSketchModePenSize = tmp;
  84. m_canvas->SetPrintMirrored( false );
  85. *displ_opts = save_opt;
  86. GetBoard()->SetElementVisibility( LAYER_NO_CONNECTS, nctmp );
  87. }
  88. void PCB_EDIT_FRAME::PrintPage( wxDC* aDC,
  89. LSET aPrintMask,
  90. bool aPrintMirrorMode,
  91. void* aData)
  92. {
  93. const GR_DRAWMODE drawmode = (GR_DRAWMODE) 0;
  94. PCB_DISPLAY_OPTIONS save_opt;
  95. BOARD* Pcb = GetBoard();
  96. int defaultPenSize = Millimeter2iu( 0.2 );
  97. PRINT_PARAMETERS* printParameters = (PRINT_PARAMETERS*) aData; // can be null
  98. auto displ_opts = (PCB_DISPLAY_OPTIONS*) GetDisplayOptions();
  99. PRINT_PARAMETERS::DrillShapeOptT drillShapeOpt = PRINT_PARAMETERS::FULL_DRILL_SHAPE;
  100. if( printParameters )
  101. {
  102. drillShapeOpt = printParameters->m_DrillShapeOpt;
  103. defaultPenSize = printParameters->m_PenDefaultSize;
  104. }
  105. save_opt = *displ_opts;
  106. PCB_LAYER_ID activeLayer = GetScreen()->m_Active_Layer;
  107. displ_opts->m_ContrastModeDisplay = false;
  108. displ_opts->m_DisplayPadFill = true;
  109. displ_opts->m_DisplayViaFill = true;
  110. // Set all board layers as visible, because the print dialog has itself
  111. // a layer selection, that have priority over the layer manager setup
  112. LSET save_visible_brd_layers = Pcb->GetVisibleLayers();
  113. Pcb->SetVisibleLayers( aPrintMask );
  114. int save_visible_brd_elements = Pcb->GetVisibleElements();
  115. Pcb->SetElementVisibility( LAYER_PAD_FR, true );
  116. Pcb->SetElementVisibility( LAYER_PAD_BK, true );
  117. Pcb->SetElementVisibility( LAYER_MOD_TEXT_FR, true );
  118. Pcb->SetElementVisibility( LAYER_MOD_TEXT_BK, true );
  119. PCB_LAYER_ID layer = aPrintMask.ExtractLayer();
  120. // pads on Silkscreen layer are usually printed in sketch mode:
  121. if( layer == B_SilkS || layer == F_SilkS )
  122. displ_opts->m_DisplayPadFill = false;
  123. displ_opts->m_DisplayPadNum = false;
  124. bool nctmp = GetBoard()->IsElementVisible( LAYER_NO_CONNECTS );
  125. GetBoard()->SetElementVisibility( LAYER_NO_CONNECTS, false );
  126. bool anchorsTmp = GetBoard()->IsElementVisible( LAYER_ANCHOR );
  127. GetBoard()->SetElementVisibility( LAYER_ANCHOR, false );
  128. displ_opts->m_DisplayPadIsol = false;
  129. displ_opts->m_DisplayModEdgeFill = FILLED;
  130. displ_opts->m_DisplayModTextFill = FILLED;
  131. displ_opts->m_DisplayPcbTrackFill = true;
  132. displ_opts->m_ShowTrackClearanceMode = PCB_DISPLAY_OPTIONS::DO_NOT_SHOW_CLEARANCE;
  133. displ_opts->m_DisplayDrawItemsFill = FILLED;
  134. displ_opts->m_DisplayZonesMode = 0;
  135. displ_opts->m_DisplayNetNamesMode = 0;
  136. m_canvas->SetPrintMirrored( aPrintMirrorMode );
  137. for( auto item : Pcb->Drawings() )
  138. {
  139. switch( item->Type() )
  140. {
  141. case PCB_LINE_T:
  142. case PCB_DIMENSION_T:
  143. case PCB_TEXT_T:
  144. case PCB_TARGET_T:
  145. if( aPrintMask[item->GetLayer()] )
  146. item->Draw( m_canvas, aDC, drawmode );
  147. break;
  148. case PCB_MARKER_T:
  149. default:
  150. break;
  151. }
  152. }
  153. // Print tracks
  154. for( TRACK* track = Pcb->m_Track; track; track = track->Next() )
  155. {
  156. if( !( aPrintMask & track->GetLayerSet() ).any() )
  157. continue;
  158. if( track->Type() == PCB_VIA_T ) // VIA encountered.
  159. {
  160. int radius = track->GetWidth() / 2;
  161. const VIA* via = static_cast<const VIA*>( track );
  162. COLOR4D color = Settings().Colors().GetItemColor( LAYER_VIAS + via->GetViaType() );
  163. GRFilledCircle( m_canvas->GetClipBox(), aDC,
  164. via->GetStart().x,
  165. via->GetStart().y,
  166. radius,
  167. 0, color, color );
  168. }
  169. else
  170. {
  171. track->Draw( m_canvas, aDC, drawmode );
  172. }
  173. }
  174. // Deprecated: only for compatibility with very old boards
  175. for( TRACK* track = Pcb->m_SegZoneDeprecated; track; track = track->Next() )
  176. {
  177. if( !( aPrintMask & track->GetLayerSet() ).any() )
  178. continue;
  179. track->Draw( m_canvas, aDC, drawmode );
  180. }
  181. // Draw filled areas (i.e. zones)
  182. for( int ii = 0; ii < Pcb->GetAreaCount(); ii++ )
  183. {
  184. ZONE_CONTAINER* zone = Pcb->GetArea( ii );
  185. if( aPrintMask[zone->GetLayer()] )
  186. zone->DrawFilledArea( m_canvas, aDC, drawmode );
  187. }
  188. // Draw footprints, this is done at last in order to print the pad holes in
  189. // white after the tracks and zones
  190. int tmp = D_PAD::m_PadSketchModePenSize;
  191. D_PAD::m_PadSketchModePenSize = defaultPenSize;
  192. for( MODULE* module = (MODULE*) Pcb->m_Modules; module; module = module->Next() )
  193. {
  194. Print_Module( m_canvas, aDC, module, drawmode, aPrintMask, drillShapeOpt );
  195. }
  196. D_PAD::m_PadSketchModePenSize = tmp;
  197. /* Print via holes in bg color: Not sure it is good for buried or blind
  198. * vias */
  199. if( drillShapeOpt != PRINT_PARAMETERS::NO_DRILL_SHAPE )
  200. {
  201. TRACK* track = Pcb->m_Track;
  202. COLOR4D color = COLOR4D::WHITE;
  203. bool blackpenstate = GetGRForceBlackPenState();
  204. GRForceBlackPen( false );
  205. for( ; track; track = track->Next() )
  206. {
  207. if( !( aPrintMask & track->GetLayerSet() ).any() )
  208. continue;
  209. if( track->Type() == PCB_VIA_T ) // VIA encountered.
  210. {
  211. int diameter;
  212. const VIA *via = static_cast<const VIA*>( track );
  213. if( drillShapeOpt == PRINT_PARAMETERS::SMALL_DRILL_SHAPE )
  214. diameter = std::min( SMALL_DRILL, via->GetDrillValue() );
  215. else
  216. diameter = via->GetDrillValue();
  217. GRFilledCircle( m_canvas->GetClipBox(), aDC,
  218. track->GetStart().x, track->GetStart().y,
  219. diameter/2,
  220. 0, color, color );
  221. }
  222. }
  223. GRForceBlackPen( blackpenstate );
  224. }
  225. m_canvas->SetPrintMirrored( false );
  226. // Restore settings:
  227. *displ_opts = save_opt;
  228. Pcb->SetVisibleLayers( save_visible_brd_layers );
  229. Pcb->SetVisibleElements( save_visible_brd_elements );
  230. GetScreen()->m_Active_Layer = activeLayer;
  231. GetBoard()->SetElementVisibility( LAYER_NO_CONNECTS, nctmp );
  232. GetBoard()->SetElementVisibility( LAYER_ANCHOR, anchorsTmp );
  233. }
  234. static void Print_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, MODULE* aModule,
  235. GR_DRAWMODE aDraw_mode, LSET aMask,
  236. PRINT_PARAMETERS::DrillShapeOptT aDrillShapeOpt )
  237. {
  238. // Print pads
  239. for( D_PAD* pad = aModule->PadsList(); pad; pad = pad->Next() )
  240. {
  241. if( !( pad->GetLayerSet() & aMask ).any() )
  242. continue;
  243. // Manage hole according to the print drill option
  244. wxSize drill_tmp = pad->GetDrillSize();
  245. switch( aDrillShapeOpt )
  246. {
  247. case PRINT_PARAMETERS::NO_DRILL_SHAPE:
  248. pad->SetDrillSize( wxSize(0,0) );
  249. break;
  250. case PRINT_PARAMETERS::SMALL_DRILL_SHAPE:
  251. {
  252. wxSize sz( std::min( SMALL_DRILL, pad->GetDrillSize().x ),
  253. std::min( SMALL_DRILL, pad->GetDrillSize().y ) );
  254. pad->SetDrillSize( sz );
  255. }
  256. break;
  257. case PRINT_PARAMETERS::FULL_DRILL_SHAPE:
  258. // Do nothing
  259. break;
  260. }
  261. pad->Draw( aPanel, aDC, aDraw_mode );
  262. pad->SetDrillSize( drill_tmp );
  263. }
  264. if( aModule->Reference().IsVisible() && aMask[aModule->Reference().GetLayer()] )
  265. aModule->Reference().Draw( aPanel, aDC, aDraw_mode );
  266. if( aModule->Value().IsVisible() && aMask[aModule->Value().GetLayer()] )
  267. aModule->Value().Draw( aPanel, aDC, aDraw_mode );
  268. for( EDA_ITEM* item = aModule->GraphicalItemsList(); item; item = item->Next() )
  269. {
  270. switch( item->Type() )
  271. {
  272. case PCB_MODULE_TEXT_T:
  273. {
  274. TEXTE_MODULE* textMod = static_cast<TEXTE_MODULE*>( item );
  275. if( !aMask[textMod->GetLayer()] )
  276. break;
  277. textMod->Draw( aPanel, aDC, aDraw_mode );
  278. break;
  279. }
  280. case PCB_MODULE_EDGE_T:
  281. {
  282. EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( item );
  283. if( !aMask[edge->GetLayer()] )
  284. break;
  285. edge->Draw( aPanel, aDC, aDraw_mode );
  286. }
  287. break;
  288. default:
  289. break;
  290. }
  291. }
  292. }