void SEGZONE::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, const wxPoint& aOffset ) { DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions(); if( displ_opts->m_DisplayZonesMode != 0 ) return; BOARD * brd = GetBoard( ); EDA_COLOR_T color = brd->GetLayerColor(m_Layer); if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) ) return; #ifdef USE_WX_OVERLAY // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay if( (m_Flags & IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC))) return; #endif if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && displ_opts->m_ContrastModeDisplay ) { LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; if( !IsOnLayer( curr_layer ) ) ColorTurnToDarkDarkGray( &color ); } if( aDrawMode & GR_HIGHLIGHT ) ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) ); ColorApplyHighlightFlag( &color ); SetAlpha( &color, 150 ); GRSetDrawMode( aDC, aDrawMode ); int l_trace = m_Width / 2; if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH ) { GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, 0, color ); return; } if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) { GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color ); } else { GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, m_Start.y + aOffset.y, m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color ); } // No clearance or netnames for zones }
void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset ) { static std::vector <char> CornersTypeBuffer; static std::vector <wxPoint> CornersBuffer; // outline_mode is false to show filled polys, // and true to show polygons outlines only (test and debug purposes) bool outline_mode = DisplayOpt.DisplayZonesMode == 2 ? true : false; if( DC == NULL ) return; if( DisplayOpt.DisplayZonesMode == 1 ) // Do not show filled areas return; if( m_FilledPolysList.GetCornersCount() == 0 ) // Nothing to draw return; BOARD* brd = GetBoard(); LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; EDA_COLOR_T color = brd->GetLayerColor( m_Layer ); if( brd->IsLayerVisible( m_Layer ) == false && ( color & HIGHLIGHT_FLAG ) != HIGHLIGHT_FLAG ) return; GRSetDrawMode( DC, aDrawMode ); if( DisplayOpt.ContrastModeDisplay ) { if( !IsOnLayer( curr_layer ) ) ColorTurnToDarkDarkGray( &color ); } if( aDrawMode & GR_HIGHLIGHT ) ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) ); ColorApplyHighlightFlag( &color ); SetAlpha( &color, 150 ); CornersTypeBuffer.clear(); CornersBuffer.clear(); // Draw all filled areas int imax = m_FilledPolysList.GetCornersCount() - 1; for( int ic = 0; ic <= imax; ic++ ) { const CPolyPt& corner = m_FilledPolysList.GetCorner( ic ); wxPoint coord( corner.x + offset.x, corner.y + offset.y ); CornersBuffer.push_back( coord ); CornersTypeBuffer.push_back( (char) corner.m_utility ); // the last corner of a filled area is found: draw it if( (corner.end_contour) || (ic == imax) ) { /* Draw the current filled area: draw segments outline first * Curiously, draw segments outline first and after draw filled polygons * with outlines thickness = 0 is a faster than * just draw filled polygons but with outlines thickness = m_ZoneMinThickness * So DO NOT use draw filled polygons with outlines having a thickness > 0 * Note: Extra segments ( added to joint holes with external outline) flagged by * m_utility != 0 are not drawn * Note not all polygon libraries provide a flag for these extra-segments, therefore * the m_utility member can be always 0 */ { // Draw outlines: if( (m_ZoneMinThickness > 1) || outline_mode ) { int ilim = CornersBuffer.size() - 1; for( int is = 0, ie = ilim; is <= ilim; ie = is, is++ ) { int x0 = CornersBuffer[is].x; int y0 = CornersBuffer[is].y; int x1 = CornersBuffer[ie].x; int y1 = CornersBuffer[ie].y; // Draw only basic outlines, not extra segments. if( CornersTypeBuffer[ie] == 0 ) { if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) GRCSegm( panel->GetClipBox(), DC, x0, y0, x1, y1, m_ZoneMinThickness, color ); else GRFillCSegm( panel->GetClipBox(), DC, x0, y0, x1, y1, m_ZoneMinThickness, color ); } } } // Draw areas: if( m_FillMode==0 && !outline_mode ) GRPoly( panel->GetClipBox(), DC, CornersBuffer.size(), &CornersBuffer[0], true, 0, color, color ); } CornersTypeBuffer.clear(); CornersBuffer.clear(); } } if( m_FillMode == 1 && !outline_mode ) // filled with segments { for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ ) { wxPoint start = m_FillSegmList[ic].m_Start + offset; wxPoint end = m_FillSegmList[ic].m_End + offset; if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) GRCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y, m_ZoneMinThickness, color ); else GRFillCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y, m_ZoneMinThickness, color ); } } }
void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset ) { if( DC == NULL ) return; wxPoint seg_start, seg_end; LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; BOARD* brd = GetBoard(); EDA_COLOR_T color = brd->GetLayerColor( m_Layer ); if( brd->IsLayerVisible( m_Layer ) == false && ( color & HIGHLIGHT_FLAG ) != HIGHLIGHT_FLAG ) return; GRSetDrawMode( DC, aDrawMode ); if( DisplayOpt.ContrastModeDisplay ) { if( !IsOnLayer( curr_layer ) ) ColorTurnToDarkDarkGray( &color ); } if( aDrawMode & GR_HIGHLIGHT ) ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) ); ColorApplyHighlightFlag( &color ); SetAlpha( &color, 150 ); // draw the lines int i_start_contour = 0; std::vector<wxPoint> lines; lines.reserve( (GetNumCorners() * 2) + 2 ); for( int ic = 0; ic < GetNumCorners(); ic++ ) { seg_start = GetCornerPosition( ic ) + offset; if( !m_Poly->m_CornersList.IsEndContour( ic ) && ic < GetNumCorners() - 1 ) { seg_end = GetCornerPosition( ic + 1 ) + offset; } else { seg_end = GetCornerPosition( i_start_contour ) + offset; i_start_contour = ic + 1; } lines.push_back( seg_start ); lines.push_back( seg_end ); } GRLineArray( panel->GetClipBox(), DC, lines, 0, color ); // draw hatches lines.clear(); lines.reserve( (m_Poly->m_HatchLines.size() * 2) + 2 ); for( unsigned ic = 0; ic < m_Poly->m_HatchLines.size(); ic++ ) { seg_start = m_Poly->m_HatchLines[ic].m_Start + offset; seg_end = m_Poly->m_HatchLines[ic].m_End + offset; lines.push_back( seg_start ); lines.push_back( seg_end ); } GRLineArray( panel->GetClipBox(), DC, lines, 0, color ); }
void GERBER_DRAW_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode, const wxPoint& aOffset ) { // used when a D_CODE is not found. default D_CODE to draw a flashed item static D_CODE dummyD_CODE( 0 ); EDA_COLOR_T color, alt_color; bool isFilled; int radius; int halfPenWidth; static bool show_err; D_CODE* d_codeDescr = GetDcodeDescr(); GERBVIEW_FRAME* gerbFrame = (GERBVIEW_FRAME*) aPanel->GetParent(); if( d_codeDescr == NULL ) d_codeDescr = &dummyD_CODE; if( gerbFrame->IsLayerVisible( GetLayer() ) == false ) return; color = gerbFrame->GetLayerColor( GetLayer() ); if( aDrawMode & GR_HIGHLIGHT ) ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) ); ColorApplyHighlightFlag( &color ); alt_color = gerbFrame->GetNegativeItemsColor(); /* isDark is true if flash is positive and should use a drawing * color other than the background color, else use the background color * when drawing so that an erasure happens. */ bool isDark = !(m_LayerNegative ^ m_imageParams->m_ImageNegative); if( !isDark ) { // draw in background color ("negative" color) EXCHG( color, alt_color ); } GRSetDrawMode( aDC, aDrawMode ); isFilled = gerbFrame->DisplayLinesSolidMode(); switch( m_Shape ) { case GBR_POLYGON: isFilled = gerbFrame->DisplayPolygonsSolidMode(); if( !isDark ) isFilled = true; DrawGbrPoly( aPanel->GetClipBox(), aDC, color, aOffset, isFilled ); break; case GBR_CIRCLE: radius = KiROUND( GetLineLength( m_Start, m_End ) ); halfPenWidth = m_Size.x >> 1; if( !isFilled ) { // draw the border of the pen's path using two circles, each as narrow as possible GRCircle( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ), radius - halfPenWidth, 0, color ); GRCircle( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ), radius + halfPenWidth, 0, color ); } else // Filled mode { GRCircle( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ), radius, m_Size.x, color ); } break; case GBR_ARC: // Currently, arcs plotted with a rectangular aperture are not supported. // a round pen only is expected. #if 0 // for arc debug only GRLine( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ), GetABPosition( m_ArcCentre ), 0, color ); GRLine( aPanel->GetClipBox(), aDC, GetABPosition( m_End ), GetABPosition( m_ArcCentre ), 0, color ); #endif if( !isFilled ) { GRArc1( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ), GetABPosition( m_End ), GetABPosition( m_ArcCentre ), 0, color ); } else { GRArc1( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ), GetABPosition( m_End ), GetABPosition( m_ArcCentre ), m_Size.x, color ); } break; case GBR_SPOT_CIRCLE: case GBR_SPOT_RECT: case GBR_SPOT_OVAL: case GBR_SPOT_POLY: case GBR_SPOT_MACRO: isFilled = gerbFrame->DisplayFlashedItemsSolidMode(); d_codeDescr->DrawFlashedShape( this, aPanel->GetClipBox(), aDC, color, alt_color, m_Start, isFilled ); break; case GBR_SEGMENT: /* Plot a line from m_Start to m_End. * Usually, a round pen is used, but some gerber files use a rectangular pen * In fact, any aperture can be used to plot a line. * currently: only a square pen is handled (I believe using a polygon gives a strange plot). */ if( d_codeDescr->m_Shape == APT_RECT ) { if( m_PolyCorners.size() == 0 ) ConvertSegmentToPolygon( ); DrawGbrPoly( aPanel->GetClipBox(), aDC, color, aOffset, isFilled ); } else { if( !isFilled ) { GRCSegm( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ), GetABPosition( m_End ), m_Size.x, color ); } else { GRFilledSegment( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ), GetABPosition( m_End ), m_Size.x, color ); } } break; default: if( !show_err ) { wxMessageBox( wxT( "Trace_Segment() type error" ) ); show_err = true; } break; } }
void VIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, const wxPoint& aOffset ) { int radius; LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; int fillvia = 0; PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) panel->GetParent(); PCB_SCREEN* screen = frame->GetScreen(); if( frame->m_DisplayViaFill == FILLED ) fillvia = 1; GRSetDrawMode( aDC, aDrawMode ); BOARD * brd = GetBoard( ); EDA_COLOR_T color = brd->GetVisibleElementColor(VIAS_VISIBLE + GetViaType()); if( brd->IsElementVisible( PCB_VISIBLE(VIAS_VISIBLE + GetViaType()) ) == false && ( color & HIGHLIGHT_FLAG ) != HIGHLIGHT_FLAG ) return; if( DisplayOpt.ContrastModeDisplay ) { if( !IsOnLayer( curr_layer ) ) ColorTurnToDarkDarkGray( &color ); } if( aDrawMode & GR_HIGHLIGHT ) ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) ); ColorApplyHighlightFlag( &color ); SetAlpha( &color, 150 ); radius = m_Width >> 1; // for small via size on screen (radius < 4 pixels) draw a simplified shape int radius_in_pixels = aDC->LogicalToDeviceXRel( radius ); bool fast_draw = false; // Vias are drawn as a filled circle or a double circle. The hole will be drawn later int drill_radius = GetDrillValue() / 2; int inner_radius = radius - aDC->DeviceToLogicalXRel( 2 ); if( radius_in_pixels < MIN_VIA_DRAW_SIZE ) { fast_draw = true; fillvia = false; } if( fillvia ) { GRFilledCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius, color ); } else { GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius, 0, color ); if ( fast_draw ) return; GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, inner_radius, 0, color ); } // Draw the via hole if the display option allows it if( DisplayOpt.m_DisplayViaMode != VIA_HOLE_NOT_SHOW ) { // Display all drill holes requested or Display non default holes requested if( (DisplayOpt.m_DisplayViaMode == ALL_VIA_HOLE_SHOW) || ( (drill_radius > 0 ) && !IsDrillDefault() ) ) { if( fillvia ) { bool blackpenstate = false; if( screen->m_IsPrinting ) { blackpenstate = GetGRForceBlackPenState(); GRForceBlackPen( false ); color = WHITE; } else { color = BLACK; // or DARKGRAY; } if( (aDrawMode & GR_XOR) == 0) GRSetDrawMode( aDC, GR_COPY ); if( aDC->LogicalToDeviceXRel( drill_radius ) > MIN_DRAW_WIDTH ) // Draw hole if large enough. GRFilledCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, m_Start.y + aOffset.y, drill_radius, 0, color, color ); if( screen->m_IsPrinting ) GRForceBlackPen( blackpenstate ); } else { if( drill_radius < inner_radius ) // We can show the via hole GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, drill_radius, 0, color ); } } } if( ShowClearance( this ) ) { GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius + GetClearance(), 0, color ); } // for Micro Vias, draw a partial cross : X on component layer, or + on copper layer // (so we can see 2 superimposed microvias ): if( GetViaType() == VIA_MICROVIA ) { int ax, ay, bx, by; if( IsOnLayer( LAYER_N_BACK ) ) { ax = radius; ay = 0; bx = drill_radius; by = 0; } else { ax = ay = (radius * 707) / 1000; bx = by = (drill_radius * 707) / 1000; } /* lines | or \ */ GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - ax, m_Start.y + aOffset.y - ay, m_Start.x + aOffset.x - bx, m_Start.y + aOffset.y - by, 0, color ); GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x + bx, m_Start.y + aOffset.y + by, m_Start.x + aOffset.x + ax, m_Start.y + aOffset.y + ay, 0, color ); // lines - or / GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x + ay, m_Start.y + aOffset.y - ax, m_Start.x + aOffset.x + by, m_Start.y + aOffset.y - bx, 0, color ); GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - by, m_Start.y + aOffset.y + bx, m_Start.x + aOffset.x - ay, m_Start.y + aOffset.y + ax, 0, color ); } // for Buried Vias, draw a partial line : orient depending on layer pair // (so we can see superimposed buried vias ): if( GetViaType() == VIA_BLIND_BURIED ) { int ax = 0, ay = radius, bx = 0, by = drill_radius; LAYER_NUM layer_top, layer_bottom; ( (VIA*) this )->LayerPair( &layer_top, &layer_bottom ); // lines for the top layer RotatePoint( &ax, &ay, layer_top * 3600.0 / brd->GetCopperLayerCount( ) ); RotatePoint( &bx, &by, layer_top * 3600.0 / brd->GetCopperLayerCount( ) ); GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - ax, m_Start.y + aOffset.y - ay, m_Start.x + aOffset.x - bx, m_Start.y + aOffset.y - by, 0, color ); // lines for the bottom layer ax = 0; ay = radius; bx = 0; by = drill_radius; RotatePoint( &ax, &ay, layer_bottom * 3600.0 / brd->GetCopperLayerCount( ) ); RotatePoint( &bx, &by, layer_bottom * 3600.0 / brd->GetCopperLayerCount( ) ); GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - ax, m_Start.y + aOffset.y - ay, m_Start.x + aOffset.x - bx, m_Start.y + aOffset.y - by, 0, color ); } // Display the short netname: if( GetNetCode() == NETINFO_LIST::UNCONNECTED ) return; if( DisplayOpt.DisplayNetNamesMode == 0 || DisplayOpt.DisplayNetNamesMode == 1 ) return; NETINFO_ITEM* net = GetNet(); if( net == NULL ) return; int len = net->GetShortNetname().Len(); if( len > 0 ) { // calculate a good size for the text int tsize = m_Width / len; if( aDC->LogicalToDeviceXRel( tsize ) >= MIN_TEXT_SIZE ) { tsize = (tsize * 7) / 10; // small reduction to give a better look, inside via if( (aDrawMode & GR_XOR) == 0 ) GRSetDrawMode( aDC, GR_COPY ); EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL; DrawGraphicHaloText( clipbox, aDC, m_Start, color, WHITE, BLACK, net->GetShortNetname(), 0, wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false ); } } }
void TRACK::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, const wxPoint& aOffset ) { BOARD * brd = GetBoard( ); EDA_COLOR_T color = brd->GetLayerColor(m_Layer); if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) ) return; #ifdef USE_WX_OVERLAY // If dragged not draw in OnPaint otherwise remains impressed in wxOverlay if( (m_Flags & IS_DRAGGED) && aDC->IsKindOf(wxCLASSINFO(wxPaintDC))) return; #endif if( ( aDrawMode & GR_ALLOW_HIGHCONTRAST ) && DisplayOpt.ContrastModeDisplay ) { LAYER_NUM curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; if( !IsOnLayer( curr_layer ) ) ColorTurnToDarkDarkGray( &color ); } if( aDrawMode & GR_HIGHLIGHT ) ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) ); ColorApplyHighlightFlag( &color ); SetAlpha( &color, 150 ); GRSetDrawMode( aDC, aDrawMode ); int l_trace = m_Width / 2; if( aDC->LogicalToDeviceXRel( l_trace ) <= MIN_DRAW_WIDTH ) { GRLine( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, 0, color ); return; } if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) { GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width, color ); } else { GRFillCSegm( panel->GetClipBox(), aDC, m_Start.x + aOffset.x, m_Start.y + aOffset.y, m_End.x + aOffset.x, m_End.y + aOffset.y, m_Width, color ); } if( panel->GetScreen()->m_IsPrinting ) return; // Show clearance for tracks, not for zone segments if( ShowClearance( this ) ) { GRCSegm( panel->GetClipBox(), aDC, m_Start + aOffset, m_End + aOffset, m_Width + (GetClearance() * 2), color ); } DrawShortNetname( panel, aDC, aDrawMode, color ); }
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 ); }
void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset ) { static std::vector <char> CornersTypeBuffer; static std::vector <wxPoint> CornersBuffer; DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions(); // outline_mode is false to show filled polys, // and true to show polygons outlines only (test and debug purposes) bool outline_mode = displ_opts->m_DisplayZonesMode == 2 ? true : false; if( DC == NULL ) return; if( displ_opts->m_DisplayZonesMode == 1 ) // Do not show filled areas return; if( m_FilledPolysList.IsEmpty() ) // Nothing to draw return; BOARD* brd = GetBoard(); LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; EDA_COLOR_T color = brd->GetLayerColor( m_Layer ); if( brd->IsLayerVisible( m_Layer ) == false && ( color & HIGHLIGHT_FLAG ) != HIGHLIGHT_FLAG ) return; GRSetDrawMode( DC, aDrawMode ); if( displ_opts->m_ContrastModeDisplay ) { if( !IsOnLayer( curr_layer ) ) ColorTurnToDarkDarkGray( &color ); } if( aDrawMode & GR_HIGHLIGHT ) ColorChangeHighlightFlag( &color, !(aDrawMode & GR_AND) ); ColorApplyHighlightFlag( &color ); SetAlpha( &color, 150 ); for ( int ic = 0; ic < m_FilledPolysList.OutlineCount(); ic++ ) { const SHAPE_LINE_CHAIN& path = m_FilledPolysList.COutline( ic ); CornersBuffer.clear(); wxPoint p0; for( int j = 0; j < path.PointCount(); j++ ) { const VECTOR2I& corner = path.CPoint( j ); wxPoint coord( corner.x + offset.x, corner.y + offset.y ); if( j == 0 ) p0 = coord; CornersBuffer.push_back( coord ); } CornersBuffer.push_back( p0 ); // Draw outlines: if( ( m_ZoneMinThickness > 1 ) || outline_mode ) { int ilim = CornersBuffer.size() - 1; for( int is = 0, ie = ilim; is <= ilim; ie = is, is++ ) { int x0 = CornersBuffer[is].x; int y0 = CornersBuffer[is].y; int x1 = CornersBuffer[ie].x; int y1 = CornersBuffer[ie].y; // Draw only basic outlines, not extra segments. if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) GRCSegm( panel->GetClipBox(), DC, x0, y0, x1, y1, m_ZoneMinThickness, color ); else GRFillCSegm( panel->GetClipBox(), DC, x0, y0, x1, y1, m_ZoneMinThickness, color ); } } // Draw areas: if( m_FillMode == 0 && !outline_mode ) GRPoly( panel->GetClipBox(), DC, CornersBuffer.size(), &CornersBuffer[0], true, 0, color, color ); } if( m_FillMode == 1 && !outline_mode ) // filled with segments { for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ ) { wxPoint start = m_FillSegmList[ic].m_Start + offset; wxPoint end = m_FillSegmList[ic].m_End + offset; if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) GRCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y, m_ZoneMinThickness, color ); else GRFillCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y, m_ZoneMinThickness, color ); } } }