// Make painting tools once when the program starts void PaintCreate() { // Make color brushes Handle.white = CreateBrush(RGB(255, 255, 255)); Handle.black = CreateBrush(RGB( 0, 0, 0)); Handle.blue = CreateBrush(RGB( 0, 102, 204)); Handle.lightblue = CreateBrush(RGB( 51, 153, 255)); Handle.yellow = CreateBrush(RGB(255, 204, 0)); Handle.lightyellow = CreateBrush(RGB(255, 255, 102)); Handle.green = CreateBrush(RGB(102, 204, 51)); Handle.lightgreen = CreateBrush(RGB(153, 255, 102)); Handle.red = CreateBrush(RGB(255, 102, 51)); Handle.lightred = CreateBrush(RGB(255, 153, 102)); Handle.middle = CreateBrush(ColorMix(GetSysColor(COLOR_3DFACE), 1, GetSysColor(COLOR_3DSHADOW), 1)); // Make fonts Handle.arial = CreateFont(L"Arial", 299); // Biggest size that will still have font smoothing // Make a font based on what the system uses in message boxes NONCLIENTMETRICS info; ZeroMemory(&info, sizeof(info)); info.cbSize = sizeof(info); // Must define _WIN32_WINNT=0x0501 for sizeof(info) to return the size SPI_GETNONCLIENTMETRICS expects SystemParametersInfo( SPI_GETNONCLIENTMETRICS, // System parameter to retrieve sizeof(info), // Size of the structure &info, // Structure to fill with information 0); // Not setting a system parameter Handle.font = CreateFontIndirect(&info.lfMenuFont); if (!Handle.font) Report(L"error createfontindirect"); }
void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event ) { wxPaintDC dc( m_panelShowPad ); PAD_DRAWINFO drawInfo; EDA_COLOR_T color = BLACK; if( m_dummyPad->GetLayerSet()[F_Cu] ) { color = m_board->GetVisibleElementColor( PAD_FR_VISIBLE ); } if( m_dummyPad->GetLayerSet()[B_Cu] ) { color = ColorMix( color, m_board->GetVisibleElementColor( PAD_BK_VISIBLE ) ); } // What could happen: the pad color is *actually* black, or no // copper was selected if( color == BLACK ) color = LIGHTGRAY; drawInfo.m_Color = color; drawInfo.m_HoleColor = DARKGRAY; drawInfo.m_Offset = m_dummyPad->GetPosition(); drawInfo.m_Display_padnum = true; drawInfo.m_Display_netname = true; if( m_dummyPad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED ) drawInfo.m_ShowNotPlatedHole = true; // Shows the local pad clearance drawInfo.m_PadClearance = m_dummyPad->GetLocalClearance(); wxSize dc_size = dc.GetSize(); dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 ); // Calculate a suitable scale to fit the available draw area int dim = m_dummyPad->GetBoundingRadius() *2; // Invalid x size. User could enter zero, or have deleted all text prior to // entering a new value; this is also treated as zero. If dim is left at // zero, the drawing scale is zero and we get a crash. if( dim == 0 ) { // If drill size has been set, use that. Otherwise default to 1mm. dim = m_dummyPad->GetDrillSize().x; if( dim == 0 ) dim = Millimeter2iu( 1.0 ); } if( m_dummyPad->GetLocalClearance() > 0 ) dim += m_dummyPad->GetLocalClearance() * 2; double scale = (double) dc_size.x / dim; // If the pad is a circle, use the x size here instead. int ysize; if( m_dummyPad->GetShape() == PAD_SHAPE_CIRCLE ) ysize = m_dummyPad->GetSize().x; else ysize = m_dummyPad->GetSize().y; dim = ysize + std::abs( m_dummyPad->GetDelta().x ); // Invalid y size. See note about x size above. if( dim == 0 ) { dim = m_dummyPad->GetDrillSize().y; if( dim == 0 ) dim = Millimeter2iu( 0.1 ); } if( m_dummyPad->GetLocalClearance() > 0 ) dim += m_dummyPad->GetLocalClearance() * 2; double altscale = (double) dc_size.y / dim; scale = std::min( scale, altscale ); // Give a margin scale *= 0.7; dc.SetUserScale( scale, scale ); GRResetPenAndBrush( &dc ); m_dummyPad->DrawShape( NULL, &dc, drawInfo ); // Draw X and Y axis. Hhis is particularly useful to show the // reference position of pads with offset and no hole, or custom pad shapes const int linethickness = 0; GRLine( NULL, &dc, -int( dc_size.x/scale ), 0, int( dc_size.x/scale ), 0, linethickness, LIGHTBLUE ); // X axis GRLine( NULL, &dc, 0, -int( dc_size.y/scale ), 0, int( dc_size.y/scale ), linethickness, LIGHTBLUE ); // Y axis event.Skip(); }
void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event ) { wxPaintDC dc( m_panelShowPad ); PAD_DRAWINFO drawInfo; EDA_COLOR_T color = BLACK; if( m_dummyPad->GetLayerSet()[F_Cu] ) { color = m_board->GetVisibleElementColor( PAD_FR_VISIBLE ); } if( m_dummyPad->GetLayerSet()[B_Cu] ) { color = ColorMix( color, m_board->GetVisibleElementColor( PAD_BK_VISIBLE ) ); } // What could happen: the pad color is *actually* black, or no // copper was selected if( color == BLACK ) color = LIGHTGRAY; drawInfo.m_Color = color; drawInfo.m_HoleColor = DARKGRAY; drawInfo.m_Offset = m_dummyPad->GetPosition(); drawInfo.m_Display_padnum = true; drawInfo.m_Display_netname = true; if( m_dummyPad->GetAttribute() == PAD_HOLE_NOT_PLATED ) drawInfo.m_ShowNotPlatedHole = true; // Shows the local pad clearance drawInfo.m_PadClearance = m_dummyPad->GetLocalClearance(); wxSize dc_size = dc.GetSize(); dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 ); // Calculate a suitable scale to fit the available draw area int dim = m_dummyPad->GetSize().x + std::abs( m_dummyPad->GetDelta().y); if( m_dummyPad->GetLocalClearance() > 0 ) dim += m_dummyPad->GetLocalClearance() * 2; double scale = (double) dc_size.x / dim; dim = m_dummyPad->GetSize().y + std::abs( m_dummyPad->GetDelta().x); if( m_dummyPad->GetLocalClearance() > 0 ) dim += m_dummyPad->GetLocalClearance() * 2; double altscale = (double) dc_size.y / dim; scale = std::min( scale, altscale ); // Give a margin scale *= 0.7; dc.SetUserScale( scale, scale ); GRResetPenAndBrush( &dc ); m_dummyPad->DrawShape( NULL, &dc, drawInfo ); // Draw X and Y axis. // this is particularly useful to show the reference position of pads // with offset and no hole GRLine( NULL, &dc, -dim, 0, dim, 0, 0, BLUE ); // X axis GRLine( NULL, &dc, 0, -dim, 0, dim, 0, BLUE ); // Y axis event.Skip(); }
void D_PAD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDraw_mode, const wxPoint& aOffset ) { wxSize mask_margin; // margin (clearance) used for some non copper layers #ifdef SHOW_PADMASK_REAL_SIZE_AND_COLOR int showActualMaskSize = 0; /* Layer number if the actual pad size on mask layer can * be displayed i.e. if only one layer is shown for this pad * and this layer is a mask (solder mask or solder paste */ #endif if( m_Flags & DO_NOT_DRAW ) return; PAD_DRAWINFO drawInfo; drawInfo.m_Offset = aOffset; /* We can show/hide pads from the layer manager. * options are show/hide pads on front and/or back side of the board * For through pads, we hide them only if both sides are hidden. * smd pads on back are hidden for all layers (copper and technical layers) * on back side of the board * smd pads on front are hidden for all layers (copper and technical layers) * on front side of the board * ECO, edge and Draw layers and not considered */ BOARD* brd = GetBoard(); bool frontVisible = brd->IsElementVisible( PCB_VISIBLE( PAD_FR_VISIBLE ) ); bool backVisible = brd->IsElementVisible( PCB_VISIBLE( PAD_BK_VISIBLE ) ); if( !frontVisible && !backVisible ) return; // If pad is only on front side (no layer on back side) // and if hide front side pads is enabled, do not draw if( !frontVisible && !( m_layerMask & LSET::BackMask() ).any() ) return; // If pad is only on back side (no layer on front side) // and if hide back side pads is enabled, do not draw if( !backVisible && !( m_layerMask & LSET::FrontMask() ).any() ) return; PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent(); wxCHECK_RET( frame != NULL, wxT( "Panel has no parent frame window." ) ); DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)frame->GetDisplayOptions(); PCB_SCREEN* screen = frame->GetScreen(); if( displ_opts && displ_opts->m_DisplayPadFill == SKETCH ) drawInfo.m_ShowPadFilled = false; else drawInfo.m_ShowPadFilled = true; EDA_COLOR_T color = BLACK; if( m_layerMask[F_Cu] ) { color = brd->GetVisibleElementColor( PAD_FR_VISIBLE ); } if( m_layerMask[B_Cu] ) { color = ColorMix( color, brd->GetVisibleElementColor( PAD_BK_VISIBLE ) ); } if( color == BLACK ) // Not on a visible copper layer (i.e. still nothing to show) { // If the pad is on only one tech layer, use the layer color else use DARKGRAY LSET mask_non_copper_layers = m_layerMask & ~LSET::AllCuMask(); #ifdef SHOW_PADMASK_REAL_SIZE_AND_COLOR mask_non_copper_layers &= brd->GetVisibleLayers(); #endif LAYER_ID pad_layer = mask_non_copper_layers.ExtractLayer(); switch( (int) pad_layer ) { case UNDEFINED_LAYER: // More than one layer color = DARKGRAY; break; case UNSELECTED_LAYER: // Shouldn't really happen... break; default: color = brd->GetLayerColor( pad_layer ); #ifdef SHOW_PADMASK_REAL_SIZE_AND_COLOR showActualMaskSize = pad_layer; #endif } } // if SMD or connector pad and high contrast mode if( ( aDraw_mode & GR_ALLOW_HIGHCONTRAST ) && ( GetAttribute() == PAD_SMD || GetAttribute() == PAD_CONN ) && displ_opts && displ_opts->m_ContrastModeDisplay ) { // when routing tracks if( frame->GetToolId() == ID_TRACK_BUTT ) { LAYER_ID routeTop = screen->m_Route_Layer_TOP; LAYER_ID routeBot = screen->m_Route_Layer_BOTTOM; // if routing between copper and component layers, // or the current layer is one of said 2 external copper layers, // then highlight only the current layer. if( ( screen->m_Active_Layer == F_Cu || screen->m_Active_Layer == B_Cu ) || ( routeTop==F_Cu && routeBot==B_Cu ) || ( routeTop==B_Cu && routeBot==F_Cu ) ) { if( !IsOnLayer( screen->m_Active_Layer ) ) ColorTurnToDarkDarkGray( &color ); } // else routing between an internal signal layer and some other // layer. Grey out all PAD_SMD pads not on current or the single // selected external layer. else if( !IsOnLayer( screen->m_Active_Layer ) && !IsOnLayer( routeTop ) && !IsOnLayer( routeBot ) ) { ColorTurnToDarkDarkGray( &color ); } } // when not edting tracks, show PAD_SMD components not on active layer // as greyed out else { if( !IsOnLayer( screen->m_Active_Layer ) ) ColorTurnToDarkDarkGray( &color ); } } #ifdef SHOW_PADMASK_REAL_SIZE_AND_COLOR if( showActualMaskSize ) { switch( showActualMaskSize ) { case B_Mask: case F_Mask: mask_margin.x = mask_margin.y = GetSolderMaskMargin(); break; case B_Paste: case F_Paste: mask_margin = GetSolderPasteMargin(); break; default: // Another layer which has no margin to handle break; } } #endif // if Contrast mode is ON and a technical layer active, show pads on this // layer so we can see pads on paste or solder layer and the size of the // mask if( ( aDraw_mode & GR_ALLOW_HIGHCONTRAST ) && displ_opts && displ_opts->m_ContrastModeDisplay && !IsCopperLayer( screen->m_Active_Layer ) ) { if( IsOnLayer( screen->m_Active_Layer ) ) { color = brd->GetLayerColor( screen->m_Active_Layer ); // In high contrast mode, and if the active layer is the mask // layer shows the pad size with the mask clearance switch( screen->m_Active_Layer ) { case B_Mask: case F_Mask: mask_margin.x = mask_margin.y = GetSolderMaskMargin(); break; case B_Paste: case F_Paste: mask_margin = GetSolderPasteMargin(); break; default: break; } } else color = DARKDARKGRAY; } if( aDraw_mode & GR_HIGHLIGHT ) ColorChangeHighlightFlag( &color, !(aDraw_mode & GR_AND) ); ColorApplyHighlightFlag( &color ); bool DisplayIsol = displ_opts && displ_opts->m_DisplayPadIsol; if( !( m_layerMask & LSET::AllCuMask() ).any() ) DisplayIsol = false; if( ( GetAttribute() == PAD_HOLE_NOT_PLATED ) && brd->IsElementVisible( NON_PLATED_VISIBLE ) ) { drawInfo.m_ShowNotPlatedHole = true; drawInfo.m_NPHoleColor = brd->GetVisibleElementColor( NON_PLATED_VISIBLE ); } drawInfo.m_DrawMode = aDraw_mode; drawInfo.m_Color = color; drawInfo.m_DrawPanel = aPanel; drawInfo.m_Mask_margin = mask_margin; drawInfo.m_ShowNCMark = brd->IsElementVisible( PCB_VISIBLE( NO_CONNECTS_VISIBLE ) ); drawInfo.m_IsPrinting = screen->m_IsPrinting; SetAlpha( &color, 170 ); /* Get the pad clearance. This has a meaning only for Pcbnew. * for CvPcb GetClearance() creates debug errors because * there is no net classes so a call to GetClearance() is made only when * needed (never needed in CvPcb) */ drawInfo.m_PadClearance = DisplayIsol ? GetClearance() : 0; // Draw the pad number if( displ_opts && !displ_opts->m_DisplayPadNum ) drawInfo.m_Display_padnum = false; if( displ_opts && (( displ_opts ->m_DisplayNetNamesMode == 0 ) || ( displ_opts->m_DisplayNetNamesMode == 2 )) ) drawInfo.m_Display_netname = false; // Display net names is restricted to pads that are on the active layer // in high contrast mode display if( ( aDraw_mode & GR_ALLOW_HIGHCONTRAST ) && !IsOnLayer( screen->m_Active_Layer ) && displ_opts && displ_opts->m_ContrastModeDisplay ) drawInfo.m_Display_netname = false; DrawShape( aPanel->GetClipBox(), aDC, drawInfo ); }