void EDA_DRAW_FRAME::LoadSettings( wxConfigBase* aCfg ) { EDA_BASE_FRAME::LoadSettings( aCfg ); wxString baseCfgName = ConfigBaseName(); bool btmp; if( aCfg->Read( baseCfgName + ShowGridEntryKeyword, &btmp ) ) SetGridVisibility( btmp ); // Read grid color: COLOR4D wtmp = COLOR4D::UNSPECIFIED; if( wtmp.SetFromWxString( aCfg->Read( baseCfgName + GridColorEntryKeyword, wxT( "NONE" ) ) ) ) SetGridColor( wtmp ); aCfg->Read( baseCfgName + LastGridSizeIdKeyword, &m_LastGridSizeId, 0L ); // m_LastGridSizeId is an offset, expected to be >= 0 if( m_LastGridSizeId < 0 ) m_LastGridSizeId = 0; m_UndoRedoCountMax = aCfg->Read( baseCfgName + MaxUndoItemsEntry, long( DEFAULT_MAX_UNDO_ITEMS ) ); aCfg->Read( baseCfgName + FirstRunShownKeyword, &m_firstRunDialogSetting, 0L ); m_galDisplayOptions->ReadConfig( aCfg, baseCfgName + GalDisplayOptionsKeyword ); }
void LIB_VIEW_FRAME::LoadSettings( wxConfigBase* aCfg ) { EDA_DRAW_FRAME::LoadSettings( aCfg ); // Fetch grid settings from Symbol Editor wxString symbolEditor = LIB_EDIT_FRAME_NAME; bool btmp; COLOR4D wtmp; if( aCfg->Read( symbolEditor + ShowGridEntryKeyword, &btmp ) ) SetGridVisibility( btmp ); if( wtmp.SetFromWxString( aCfg->Read( symbolEditor + GridColorEntryKeyword, wxT( "NONE" ) ) ) ) SetGridColor( wtmp ); // Grid shape, etc. GetGalDisplayOptions().ReadAppConfig( *aCfg, symbolEditor ); aCfg->Read( LIBLIST_WIDTH_KEY, &m_libListWidth, 150 ); aCfg->Read( CMPLIST_WIDTH_KEY, &m_cmpListWidth, 150 ); m_showPinElectricalTypeName = aCfg->Read( CMPVIEW_SHOW_PINELECTRICALTYPE_KEY, true ); // Set parameters to a reasonable value. if( m_libListWidth > m_FrameSize.x/2 ) m_libListWidth = m_FrameSize.x/2; if( m_cmpListWidth > m_FrameSize.x/2 ) m_cmpListWidth = m_FrameSize.x/2; }
void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const { aGal->SetIsStroke( true ); aGal->SetIsFill( false ); aGal->SetLineWidth( 1.0 ); RENDER_SETTINGS* rs = m_view->GetPainter()->GetSettings(); COLOR4D color = rs->GetColor( NULL, ITEM_GAL_LAYER( RATSNEST_VISIBLE ) ); int highlightedNet = rs->GetHighlightNetCode(); for( int i = 1; i < m_data->GetNetCount(); ++i ) { RN_NET& net = m_data->GetNet( i ); if( !net.IsVisible() ) continue; // Set brighter color for the temporary ratsnest aGal->SetStrokeColor( color.Brightened( 0.8 ) ); // Draw the "dynamic" ratsnest (i.e. for objects that may be currently being moved) BOOST_FOREACH( const RN_NODE_PTR& node, net.GetSimpleNodes() ) { RN_NODE_PTR dest = net.GetClosestNode( node, WITHOUT_FLAG() && DIFFERENT_TAG( RN_NODE::TAG_UNCONNECTED ) ); if( dest ) { VECTOR2D origin( node->GetX(), node->GetY() ); VECTOR2D end( dest->GetX(), dest->GetY() ); aGal->DrawLine( origin, end ); // Avoid duplicate destinations for ratsnest lines by storing already used nodes net.AddBlockedNode( dest ); } } // Draw the "static" ratsnest if( i != highlightedNet ) aGal->SetStrokeColor( color ); // using the default ratsnest color for not highlighted const std::vector<RN_EDGE_MST_PTR>* edges = net.GetUnconnected(); if( edges == NULL ) continue; BOOST_FOREACH( const RN_EDGE_MST_PTR& edge, *edges ) { const RN_NODE_PTR& sourceNode = edge->GetSourceNode(); const RN_NODE_PTR& targetNode = edge->GetTargetNode(); VECTOR2D source( sourceNode->GetX(), sourceNode->GetY() ); VECTOR2D target( targetNode->GetX(), targetNode->GetY() ); aGal->DrawLine( source, target ); } } }
void SELECT_COPPER_LAYERS_PAIR_DIALOG::buildList() { m_leftGridLayers->SetColSize( COLOR_COLNUM, 20 ); m_rightGridLayers->SetColSize( COLOR_COLNUM, 20 ); // Select a not show cell, to avoid a wrong cell selection for user int row = 0; wxString layername; for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder(); ui_seq; ++ui_seq ) { LAYER_ID layerid = *ui_seq; if( !IsCopperLayer( layerid ) ) break; COLOR4D color = GetLayerColor( layerid ); layername = GetLayerName( layerid ); if( row ) m_leftGridLayers->AppendRows( 1 ); m_leftGridLayers->SetCellBackgroundColour( row, COLOR_COLNUM, color.ToColour() ); m_leftGridLayers->SetCellValue( row, LAYERNAME_COLNUM, layername ); m_layersId.push_back( layerid ); if( m_frontLayer == layerid ) { SetGridCursor( m_leftGridLayers, row, true ); m_leftRowSelected = row; } if( row ) m_rightGridLayers->AppendRows( 1 ); m_rightGridLayers->SetCellBackgroundColour ( row, COLOR_COLNUM, color.ToColour() ); m_rightGridLayers->SetCellValue( row, LAYERNAME_COLNUM, layername ); if( m_backLayer == layerid ) { SetGridCursor( m_rightGridLayers, row, true ); m_rightRowSelected = row; } row++; } m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM); m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM); m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM); m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM); }
void PCB_RENDER_SETTINGS::ImportLegacyColors( const COLORS_DESIGN_SETTINGS* aSettings ) { // Init board layers colors: for( int i = 0; i < PCB_LAYER_ID_COUNT; i++ ) { m_layerColors[i] = aSettings->GetLayerColor( i ); // Guard: if the alpah channel is too small, the layer is not visible. // clamp it to 0.2 if( m_layerColors[i].a < 0.2 ) m_layerColors[i].a = 0.2; } // Init specific graphic layers colors: for( int i = GAL_LAYER_ID_START; i < GAL_LAYER_ID_END; i++ ) m_layerColors[i] = aSettings->GetItemColor( i ); // Default colors for specific layers (not really board layers). m_layerColors[LAYER_VIAS_HOLES] = COLOR4D( 0.5, 0.4, 0.0, 0.8 ); m_layerColors[LAYER_PADS_PLATEDHOLES] = aSettings->GetItemColor( LAYER_PCB_BACKGROUND ); m_layerColors[LAYER_PADS_NETNAMES] = COLOR4D( 1.0, 1.0, 1.0, 0.9 ); m_layerColors[LAYER_PAD_FR_NETNAMES] = COLOR4D( 1.0, 1.0, 1.0, 0.9 ); m_layerColors[LAYER_PAD_BK_NETNAMES] = COLOR4D( 1.0, 1.0, 1.0, 0.9 ); m_layerColors[LAYER_DRC] = COLOR4D( 1.0, 0.0, 0.0, 0.8 ); // LAYER_PADS_TH, LAYER_NON_PLATEDHOLES, LAYER_ANCHOR ,LAYER_RATSNEST, // LAYER_VIA_THROUGH, LAYER_VIA_BBLIND, LAYER_VIA_MICROVIA // are initialized from aSettings // These colors are not actually used. Set just in case... m_layerColors[LAYER_MOD_TEXT_FR] = m_layerColors[F_SilkS]; m_layerColors[LAYER_MOD_TEXT_BK] = m_layerColors[B_SilkS]; // Netnames for copper layers for( LSEQ cu = LSET::AllCuMask().CuStack(); cu; ++cu ) { const COLOR4D lightLabel( 0.8, 0.8, 0.8, 0.7 ); const COLOR4D darkLabel = lightLabel.Inverted(); PCB_LAYER_ID layer = *cu; if( m_layerColors[layer].GetBrightness() > 0.5 ) m_layerColors[GetNetnameLayer( layer )] = darkLabel; else m_layerColors[GetNetnameLayer( layer )] = lightLabel; } SetBackgroundColor ( aSettings->GetItemColor( LAYER_PCB_BACKGROUND ) ); update(); }
void DrawGraphicHaloText( EDA_RECT* aClipBox, wxDC * aDC, const wxPoint &aPos, const COLOR4D aBgColor, COLOR4D aColor1, COLOR4D aColor2, const wxString &aText, double aOrient, const wxSize &aSize, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, bool aBold, void (*aCallback)( int x0, int y0, int xf, int yf ), PLOTTER * aPlotter ) { // Swap color if contrast would be better // TODO: Maybe calculate contrast some way other than brightness if( aBgColor.GetBrightness() > 0.5 ) { COLOR4D c = aColor1; aColor1 = aColor2; aColor2 = c; } // Draw the background DrawGraphicText( aClipBox, aDC, aPos, aColor1, aText, aOrient, aSize, aH_justify, aV_justify, aWidth, aItalic, aBold, aCallback, aPlotter ); // Draw the text DrawGraphicText( aClipBox, aDC, aPos, aColor2, aText, aOrient, aSize, aH_justify, aV_justify, aWidth/4, aItalic, aBold, aCallback, aPlotter ); }
void WIDGET_EESCHEMA_COLOR_CONFIG::SetColor( wxCommandEvent& event ) { wxBitmapButton* button = (wxBitmapButton*) event.GetEventObject(); wxCHECK_RET( button != NULL, wxT( "Color button event object is NULL." ) ); COLORBUTTON* colorButton = (COLORBUTTON*) button->GetClientData(); wxCHECK_RET( colorButton != NULL, wxT( "Client data not set for color button." ) ); wxColourData colourData; colourData.SetColour( currentColors[ colorButton->m_Layer ].ToColour() ); wxColourDialog *dialog = new wxColourDialog( this, &colourData ); COLOR4D newColor = COLOR4D::UNSPECIFIED; if( dialog->ShowModal() == wxID_OK ) { newColor = COLOR4D( dialog->GetColourData().GetColour() ); } if( newColor == COLOR4D::UNSPECIFIED || currentColors[ colorButton->m_Layer ] == newColor ) return; currentColors[ colorButton->m_Layer ] = newColor; wxMemoryDC iconDC; wxBitmap bitmap = button->GetBitmapLabel(); iconDC.SelectObject( bitmap ); iconDC.SetPen( *wxBLACK_PEN ); wxBrush brush; brush.SetColour( newColor.ToColour() ); brush.SetStyle( wxBRUSHSTYLE_SOLID ); iconDC.SetBrush( brush ); iconDC.DrawRectangle( 0, 0, BUTT_SIZE_X, BUTT_SIZE_Y ); button->SetBitmapLabel( bitmap ); button->Refresh(); Refresh( false ); }
void SELECT_COPPER_LAYERS_PAIR_DIALOG::SetGridCursor( wxGrid* aGrid, int aRow, bool aEnable ) { if( aEnable ) { LAYER_ID layerid = m_layersId[aRow]; COLOR4D color = GetLayerColor( layerid ); aGrid->SetCellValue( aRow, SELECT_COLNUM, wxT("X") ); aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM, color.ToColour() ); aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM ); } else { aGrid->SetCellValue( aRow, SELECT_COLNUM, wxEmptyString ); aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM, aGrid->GetDefaultCellBackgroundColour() ); aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM ); } }
void EDA_DRAW_FRAME::LoadSettings( wxConfigBase* aCfg ) { EDA_BASE_FRAME::LoadSettings( aCfg ); wxString baseCfgName = ConfigBaseName(); wxConfigBase* cmnCfg = Pgm().CommonSettings(); // Read units used in dialogs and toolbars EDA_UNITS_T unitsTmp; if( aCfg->Read( baseCfgName + UserUnitsEntryKeyword, (int*) &unitsTmp ) ) SetUserUnits( unitsTmp ); else SetUserUnits( MILLIMETRES ); // Read show/hide grid entry bool btmp; if( aCfg->Read( baseCfgName + ShowGridEntryKeyword, &btmp ) ) SetGridVisibility( btmp ); // Read grid color: COLOR4D wtmp = COLOR4D::UNSPECIFIED; if( wtmp.SetFromWxString( aCfg->Read( baseCfgName + GridColorEntryKeyword, wxT( "NONE" ) ) ) ) SetGridColor( wtmp ); aCfg->Read( baseCfgName + LastGridSizeIdKeyword, &m_LastGridSizeId, 0L ); // m_LastGridSizeId is an offset, expected to be >= 0 if( m_LastGridSizeId < 0 ) m_LastGridSizeId = 0; m_UndoRedoCountMax = aCfg->Read( baseCfgName + MaxUndoItemsEntry, long( DEFAULT_MAX_UNDO_ITEMS ) ); aCfg->Read( baseCfgName + FirstRunShownKeyword, &m_firstRunDialogSetting, 0L ); m_galDisplayOptions.ReadConfig( *cmnCfg, *aCfg, baseCfgName, this ); }
void EDA_DRAW_PANEL::ReDraw( wxDC* DC, bool erasebg ) { BASE_SCREEN* Screen = GetScreen(); if( Screen == NULL ) return; COLOR4D bgColor = GetParent()->GetDrawBgColor(); // TODO(JE): Is this correct? if( bgColor.GetBrightness() > 0.5 ) { g_XorMode = GR_NXOR; g_GhostColor = BLACK; } else { g_XorMode = GR_XOR; g_GhostColor = WHITE; } GRResetPenAndBrush( DC ); DC->SetBackground( wxBrush( bgColor.ToColour() ) ); DC->SetBackgroundMode( wxSOLID ); if( erasebg ) EraseScreen( DC ); GetParent()->RedrawActiveWindow( DC, erasebg ); // Verfies that the clipping is working correctly. If these two sets of numbers are // not the same or really close. The clipping algorithms are broken. wxLogTrace( kicadTraceCoords, wxT( "Clip box: (%d, %d, %d, %d), Draw extents (%d, %d, %d, %d)" ), m_ClipBox.GetX(), m_ClipBox.GetY(), m_ClipBox.GetRight(), m_ClipBox.GetBottom(), DC->MinX(), DC->MinY(), DC->MaxX(), DC->MaxY() ); }
void EDA_DRAW_PANEL::DrawCrossHair( wxDC* aDC, COLOR4D aColor ) { if( m_cursorLevel != 0 || aDC == NULL || !m_showCrossHair ) return; wxPoint cursor = GetParent()->GetCrossHairPosition(); #ifdef USE_WX_GRAPHICS_CONTEXT // Normally cursor color is set to white, so when it is xored with white // background, it is painted black effectively. wxGraphicsContext does not have // xor operation, so we need to invert the color manually. aColor.Invert(); #else GRSetDrawMode( aDC, GR_XOR ); #endif if( GetParent()->GetGalDisplayOptions().m_fullscreenCursor ) { wxSize clientSize = GetClientSize(); // Y axis wxPoint lineStart( cursor.x, aDC->DeviceToLogicalY( 0 ) ); wxPoint lineEnd( cursor.x, aDC->DeviceToLogicalY( clientSize.y ) ); GRLine( &m_ClipBox, aDC, lineStart, lineEnd, 0, aColor ); // X axis lineStart = wxPoint( aDC->DeviceToLogicalX( 0 ), cursor.y ); lineEnd = wxPoint( aDC->DeviceToLogicalX( clientSize.x ), cursor.y ); GRLine( &m_ClipBox, aDC, lineStart, lineEnd, 0, aColor ); } else { int len = aDC->DeviceToLogicalXRel( CURSOR_SIZE ); GRLine( &m_ClipBox, aDC, cursor.x - len, cursor.y, cursor.x + len, cursor.y, 0, aColor ); GRLine( &m_ClipBox, aDC, cursor.x, cursor.y - len, cursor.x, cursor.y + len, 0, aColor ); } }
EDA_COLOR_T COLOR4D::GetNearestLegacyColor( const COLOR4D &aColor ) { // Cache layer implemented here, because all callers are using wxColour static std::map< unsigned int, unsigned int > nearestCache; static double hues[NBCOLORS]; static double values[NBCOLORS]; unsigned int colorInt = aColor.ToU32(); auto search = nearestCache.find( colorInt ); if( search != nearestCache.end() ) return static_cast<EDA_COLOR_T>( search->second ); // First use ColorFindNearest to check for exact matches EDA_COLOR_T nearest = ColorFindNearest( aColor.r * 255.0, aColor.g * 255.0, aColor.b * 255.0 ); if( COLOR4D( nearest ) == aColor ) { nearestCache.insert( std::pair< unsigned int, unsigned int >( colorInt, static_cast<unsigned int>( nearest ) ) ); return nearest; } // If not, use hue and value to match. // Hue will be NAN for grayscale colors. // The legacy color palette is a grid across hue and value. // We can exploit that to find a good match -- hue is most apparent to the user. // So, first we determine the closest hue match, and then the closest value from that // "grid row" in the legacy palette. double h, s, v; aColor.ToHSV( h, s, v ); double minDist = 360.0; double legacyHue = 0.0; if( std::isnan( h ) ) { legacyHue = NAN; } else { for( EDA_COLOR_T candidate = ::BLACK; candidate < NBCOLORS; candidate = NextColor( candidate ) ) { double ch; if( hues[candidate] == 0.0 && values[candidate] == 0.0 ) { COLOR4D candidate4d( candidate ); double cs, cv; candidate4d.ToHSV( ch, cs, cv ); values[candidate] = cv; // Set the hue to non-zero for black so that we won't do this more than once hues[candidate] = ( cv == 0.0 ) ? 1.0 : ch; } else { ch = hues[candidate]; } if( fabs( ch - h ) < minDist ) { minDist = fabs( ch - h ); legacyHue = ch; } } } // Now we have the desired hue; let's find the nearest value minDist = 1.0; for( EDA_COLOR_T candidate = ::BLACK; candidate < NBCOLORS; candidate = NextColor( candidate ) ) { // If the target hue is NAN, we didn't extract the value for any colors above if( std::isnan( legacyHue ) ) { double ch, cs, cv; COLOR4D candidate4d( candidate ); candidate4d.ToHSV( ch, cs, cv ); values[candidate] = cv; hues[candidate] = ( cv == 0.0 ) ? 1.0 : ch; } if( ( std::isnan( legacyHue ) != std::isnan( hues[candidate] ) ) || hues[candidate] != legacyHue ) continue; if( fabs( values[candidate] - v ) < minDist ) { minDist = fabs( values[candidate] - v ); nearest = candidate; } } nearestCache.insert( std::pair< unsigned int, unsigned int >( colorInt, static_cast<unsigned int>( nearest ) ) ); return nearest; }
void WIDGET_EESCHEMA_COLOR_CONFIG::CreateControls() { wxStaticText* label; int buttonId = 1800; m_mainBoxSizer = new wxBoxSizer( wxHORIZONTAL ); SetSizer( m_mainBoxSizer ); BUTTONINDEX* groups = buttonGroups; wxBoxSizer* columnBoxSizer = NULL; while( groups->m_Buttons != NULL ) { COLORBUTTON* buttons = groups->m_Buttons; columnBoxSizer = new wxBoxSizer( wxVERTICAL ); m_mainBoxSizer->Add( columnBoxSizer, 1, wxALIGN_TOP | wxLEFT | wxTOP, 5 ); wxBoxSizer* rowBoxSizer = new wxBoxSizer( wxHORIZONTAL ); columnBoxSizer->Add( rowBoxSizer, 0, wxGROW | wxLEFT | wxRIGHT | wxBOTTOM, 5 ); // Add a text string to identify the column of color select buttons. label = new wxStaticText( this, wxID_ANY, groups->m_Name ); // Make the column label font bold. wxFont font( label->GetFont() ); font.SetWeight( wxFONTWEIGHT_BOLD ); label->SetFont( font ); rowBoxSizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 ); while( buttons->m_Layer >= 0 ) { rowBoxSizer = new wxBoxSizer( wxHORIZONTAL ); columnBoxSizer->Add( rowBoxSizer, 0, wxGROW | wxALL, 0 ); COLOR4D color = GetLayerColor( LAYERSCH_ID( buttons->m_Layer ) ); currentColors[ buttons->m_Layer ] = color; wxMemoryDC iconDC; wxBitmap bitmap( BUTT_SIZE_X, BUTT_SIZE_Y ); iconDC.SelectObject( bitmap ); iconDC.SetPen( *wxBLACK_PEN ); wxBrush brush; brush.SetColour( color.ToColour() ); brush.SetStyle( wxBRUSHSTYLE_SOLID ); iconDC.SetBrush( brush ); iconDC.DrawRectangle( 0, 0, BUTT_SIZE_X, BUTT_SIZE_Y ); wxBitmapButton* bitmapButton = new wxBitmapButton( this, buttonId, bitmap, wxDefaultPosition, wxSize( BUTT_SIZE_X+8, BUTT_SIZE_Y+6 ) ); bitmapButton->SetClientData( (void*) buttons ); rowBoxSizer->Add( bitmapButton, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM, 5 ); label = new wxStaticText( this, wxID_ANY, wxGetTranslation( buttons->m_Name ) ); rowBoxSizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM, 5 ); buttonId += 1; buttons++; } groups++; } COLOR4D bgColor = GetDrawFrame()->GetDrawBgColor(); wxMemoryDC iconDC; wxBitmap bitmap( BUTT_SIZE_X, BUTT_SIZE_Y ); iconDC.SelectObject( bitmap ); iconDC.SetPen( *wxBLACK_PEN ); wxBrush brush; brush.SetColour( bgColor.ToColour() ); brush.SetStyle( wxBRUSHSTYLE_SOLID ); iconDC.SetBrush( brush ); iconDC.DrawRectangle( 0, 0, BUTT_SIZE_X, BUTT_SIZE_Y ); buttonId++; wxBitmapButton* selBgColorBtn = new wxBitmapButton( this, buttonId, bitmap, wxDefaultPosition, wxSize( BUTT_SIZE_X + 8, BUTT_SIZE_Y + 6 ) ); selBgColorBtn->SetClientData( (void*) &bgColorButton ); Connect( 1800, buttonId, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIDGET_EESCHEMA_COLOR_CONFIG::SetColor ) ); wxStaticText* bgColorLabel = new wxStaticText( this, wxID_ANY, _( "Background Color" ) ); wxFont font( bgColorLabel->GetFont() ); font.SetWeight( wxFONTWEIGHT_BOLD ); bgColorLabel->SetFont( font ); if( columnBoxSizer ) { // Add a spacer to improve appearance. columnBoxSizer->AddSpacer( 5 ); columnBoxSizer->Add( bgColorLabel, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 ); columnBoxSizer->Add( selBgColorBtn, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM, 5 ); } currentColors[ LAYER_BACKGROUND ] = bgColor; // Dialog now needs to be resized, but the associated command is found elsewhere. }
void GERBER_DRAW_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode, const wxPoint& aOffset, GBR_DISPLAY_OPTIONS* aDrawOptions ) { // used when a D_CODE is not found. default D_CODE to draw a flashed item static D_CODE dummyD_CODE( 0 ); bool isFilled; int radius; int halfPenWidth; static bool show_err; D_CODE* d_codeDescr = GetDcodeDescr(); if( d_codeDescr == NULL ) d_codeDescr = &dummyD_CODE; COLOR4D color = m_GerberImageFile->GetPositiveDrawColor(); if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) ) color.SetToLegacyHighlightColor(); /* 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_GerberImageFile->m_ImageNegative); if( !isDark ) { // draw in background color ("negative" color) color = aDrawOptions->m_NegativeDrawColor; } GRSetDrawMode( aDC, aDrawMode ); isFilled = aDrawOptions->m_DisplayLinesFill; switch( m_Shape ) { case GBR_POLYGON: isFilled = aDrawOptions->m_DisplayPolygonsFill; 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 = aDrawOptions->m_DisplayFlashedItemsFill; d_codeDescr->DrawFlashedShape( this, aPanel->GetClipBox(), aDC, 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_Polygon.OutlineCount() == 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 ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset ) { 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; COLOR4D color = brd->GetLayerColor( m_Layer ); if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) ) return; GRSetDrawMode( DC, aDrawMode ); if( displ_opts->m_ContrastModeDisplay ) { if( !IsOnLayer( curr_layer ) ) color = COLOR4D( DARKDARKGRAY ); } if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) ) color.SetToLegacyHighlightColor(); color.a = 0.588; 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 ); } } }
void VIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, const wxPoint& aOffset ) { wxCHECK_RET( panel != NULL, wxT( "VIA::Draw panel cannot be NULL." ) ); int radius; PCB_LAYER_ID 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(); auto displ_opts = (PCB_DISPLAY_OPTIONS*)( frame->GetDisplayOptions() ); if( displ_opts->m_DisplayViaFill == FILLED ) fillvia = 1; GRSetDrawMode( aDC, aDrawMode ); BOARD * brd = GetBoard(); COLOR4D color = frame->Settings().Colors().GetItemColor( LAYER_VIAS + GetViaType() ); if( brd->IsElementVisible( LAYER_VIAS + GetViaType() ) == false && !( aDrawMode & GR_HIGHLIGHT ) ) return; // Only draw the via if at least one of the layers it crosses is being displayed if( !( brd->GetVisibleLayers() & GetLayerSet() ).any() ) return; if( displ_opts->m_ContrastModeDisplay ) { if( !IsOnLayer( curr_layer ) ) color = COLOR4D( DARKDARKGRAY ); } if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) ) color.SetToLegacyHighlightColor(); color.a = 0.588; 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 ); } 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 ); // Draw hole if the radius is > 1pixel. if( aDC->LogicalToDeviceXRel( drill_radius ) > 1 ) 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( displ_opts, 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( B_Cu ) ) { 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; PCB_LAYER_ID layer_top, layer_bottom; 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( displ_opts->m_DisplayNetNamesMode == 0 || displ_opts->m_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->GetClipBox(); 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 ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset ) { if( !DC ) return; wxPoint seg_start, seg_end; LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; BOARD* brd = GetBoard(); COLOR4D color = brd->GetLayerColor( m_Layer ); if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) ) return; GRSetDrawMode( DC, aDrawMode ); DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions(); if( displ_opts->m_ContrastModeDisplay ) { if( !IsOnLayer( curr_layer ) ) color = COLOR4D( DARKDARKGRAY ); } if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) ) color.SetToLegacyHighlightColor(); color.a = 0.588; // 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 PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) { VECTOR2D size; VECTOR2D position( aPad->GetPosition() ); PAD_SHAPE_T shape; double m, n; double orientation = aPad->GetOrientation(); wxString buffer; // Draw description layer if( IsNetnameLayer( aLayer ) ) { // Is anything that we can display enabled? if( m_pcbSettings.m_netNamesOnPads || m_pcbSettings.m_padNumbers ) { // Min char count to calculate string size const int MIN_CHAR_COUNT = 3; bool displayNetname = ( m_pcbSettings.m_netNamesOnPads && !aPad->GetNetname().empty() ); VECTOR2D padsize = VECTOR2D( aPad->GetSize() ); double maxSize = PCB_RENDER_SETTINGS::MAX_FONT_SIZE; double size = padsize.y; // Keep the size ratio for the font, but make it smaller if( padsize.x < padsize.y ) { orientation += 900.0; size = padsize.x; EXCHG( padsize.x, padsize.y ); } else if( padsize.x == padsize.y ) { // If the text is displayed on a symmetrical pad, do not rotate it orientation = 0.0; } // Font size limits if( size > maxSize ) size = maxSize; m_gal->Save(); m_gal->Translate( position ); // do not display descriptions upside down NORMALIZE_ANGLE_90( orientation ); m_gal->Rotate( -orientation * M_PI / 1800.0 ); // Default font settings m_gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_CENTER ); m_gal->SetVerticalJustify( GR_TEXT_VJUSTIFY_CENTER ); m_gal->SetBold( false ); m_gal->SetItalic( false ); m_gal->SetMirrored( false ); // Set a proper color for the label const COLOR4D& color = m_pcbSettings.GetColor( aPad, aPad->GetLayer() ); COLOR4D labelColor = m_pcbSettings.GetColor( NULL, aLayer ); if( color.GetBrightness() > 0.5 ) m_gal->SetStrokeColor( labelColor.Inverted() ); else m_gal->SetStrokeColor( labelColor ); VECTOR2D textpos( 0.0, 0.0); // Divide the space, to display both pad numbers and netnames // and set the Y text position to display 2 lines if( displayNetname && m_pcbSettings.m_padNumbers ) { size = size / 2.0; textpos.y = size / 2.0; } if( displayNetname ) { // calculate the size of net name text: double tsize = padsize.x / aPad->GetShortNetname().Length(); tsize = std::min( tsize, size ); // Use a smaller text size to handle interline, pen size.. tsize *= 0.7; VECTOR2D namesize( tsize, tsize ); m_gal->SetGlyphSize( namesize ); m_gal->SetLineWidth( namesize.x / 12.0 ); m_gal->StrokeText( aPad->GetShortNetname(), textpos, 0.0 ); } if( m_pcbSettings.m_padNumbers ) { textpos.y = -textpos.y; aPad->StringPadName( buffer ); int len = buffer.Length(); double tsize = padsize.x / std::max( len, MIN_CHAR_COUNT ); tsize = std::min( tsize, size ); // Use a smaller text size to handle interline, pen size.. tsize *= 0.7; tsize = std::min( tsize, size ); VECTOR2D numsize( tsize, tsize ); m_gal->SetGlyphSize( numsize ); m_gal->SetLineWidth( numsize.x / 12.0 ); m_gal->StrokeText( aPad->GetPadName(), textpos, 0.0 ); } m_gal->Restore(); } return; } // Pad drawing const COLOR4D& color = m_pcbSettings.GetColor( aPad, aLayer ); if( m_pcbSettings.m_sketchMode[PADS_VISIBLE] ) { // Outline mode m_gal->SetIsFill( false ); m_gal->SetIsStroke( true ); m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); m_gal->SetStrokeColor( color ); } else { // Filled mode m_gal->SetIsFill( true ); m_gal->SetIsStroke( false ); m_gal->SetFillColor( color ); } m_gal->Save(); m_gal->Translate( VECTOR2D( aPad->GetPosition() ) ); m_gal->Rotate( -aPad->GetOrientation() * M_PI / 1800.0 ); // Choose drawing settings depending on if we are drawing a pad itself or a hole if( aLayer == ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ) ) { // Drawing hole: has same shape as PAD_CIRCLE or PAD_OVAL size = VECTOR2D( aPad->GetDrillSize() ) / 2.0; shape = aPad->GetDrillShape() == PAD_DRILL_OBLONG ? PAD_OVAL : PAD_CIRCLE; } else if( aLayer == SOLDERMASK_N_FRONT || aLayer == SOLDERMASK_N_BACK ) { // Drawing soldermask int soldermaskMargin = aPad->GetSolderMaskMargin(); m_gal->Translate( VECTOR2D( aPad->GetOffset() ) ); size = VECTOR2D( aPad->GetSize().x / 2.0 + soldermaskMargin, aPad->GetSize().y / 2.0 + soldermaskMargin ); shape = aPad->GetShape(); } else if( aLayer == SOLDERPASTE_N_FRONT || aLayer == SOLDERPASTE_N_BACK ) { // Drawing solderpaste int solderpasteMargin = aPad->GetLocalSolderPasteMargin(); m_gal->Translate( VECTOR2D( aPad->GetOffset() ) ); size = VECTOR2D( aPad->GetSize().x / 2.0 + solderpasteMargin, aPad->GetSize().y / 2.0 + solderpasteMargin ); shape = aPad->GetShape(); } else { // Drawing every kind of pad m_gal->Translate( VECTOR2D( aPad->GetOffset() ) ); size = VECTOR2D( aPad->GetSize() ) / 2.0; shape = aPad->GetShape(); } switch( shape ) { case PAD_OVAL: if( size.y >= size.x ) { m = ( size.y - size.x ); n = size.x; if( m_pcbSettings.m_sketchMode[PADS_VISIBLE] ) { // Outline mode m_gal->DrawArc( VECTOR2D( 0, -m ), n, -M_PI, 0 ); m_gal->DrawArc( VECTOR2D( 0, m ), n, M_PI, 0 ); m_gal->DrawLine( VECTOR2D( -n, -m ), VECTOR2D( -n, m ) ); m_gal->DrawLine( VECTOR2D( n, -m ), VECTOR2D( n, m ) ); } else { // Filled mode m_gal->DrawCircle( VECTOR2D( 0, -m ), n ); m_gal->DrawCircle( VECTOR2D( 0, m ), n ); m_gal->DrawRectangle( VECTOR2D( -n, -m ), VECTOR2D( n, m ) ); } } else { m = ( size.x - size.y ); n = size.y; if( m_pcbSettings.m_sketchMode[PADS_VISIBLE] ) { // Outline mode m_gal->DrawArc( VECTOR2D( -m, 0 ), n, M_PI / 2, 3 * M_PI / 2 ); m_gal->DrawArc( VECTOR2D( m, 0 ), n, M_PI / 2, -M_PI / 2 ); m_gal->DrawLine( VECTOR2D( -m, -n ), VECTOR2D( m, -n ) ); m_gal->DrawLine( VECTOR2D( -m, n ), VECTOR2D( m, n ) ); } else { // Filled mode m_gal->DrawCircle( VECTOR2D( -m, 0 ), n ); m_gal->DrawCircle( VECTOR2D( m, 0 ), n ); m_gal->DrawRectangle( VECTOR2D( -m, -n ), VECTOR2D( m, n ) ); } } break; case PAD_RECT: m_gal->DrawRectangle( VECTOR2D( -size.x, -size.y ), VECTOR2D( size.x, size.y ) ); break; case PAD_TRAPEZOID: { std::deque<VECTOR2D> pointList; wxPoint corners[4]; VECTOR2D padSize = VECTOR2D( aPad->GetSize().x, aPad->GetSize().y ) / 2; VECTOR2D deltaPadSize = size - padSize; // = solder[Paste/Mask]Margin or 0 aPad->BuildPadPolygon( corners, wxSize( deltaPadSize.x, deltaPadSize.y ), 0.0 ); pointList.push_back( VECTOR2D( corners[0] ) ); pointList.push_back( VECTOR2D( corners[1] ) ); pointList.push_back( VECTOR2D( corners[2] ) ); pointList.push_back( VECTOR2D( corners[3] ) ); if( m_pcbSettings.m_sketchMode[PADS_VISIBLE] ) { // Add the beginning point to close the outline pointList.push_back( pointList.front() ); m_gal->DrawPolyline( pointList ); } else { m_gal->DrawPolygon( pointList ); } } break; case PAD_CIRCLE: m_gal->DrawCircle( VECTOR2D( 0.0, 0.0 ), size.x ); break; } m_gal->Restore(); }
void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) { VECTOR2D start( aTrack->GetStart() ); VECTOR2D end( aTrack->GetEnd() ); int width = aTrack->GetWidth(); if( m_pcbSettings.m_netNamesOnTracks && IsNetnameLayer( aLayer ) ) { // If there is a net name - display it on the track if( aTrack->GetNetCode() > NETINFO_LIST::UNCONNECTED ) { VECTOR2D line = ( end - start ); double length = line.EuclideanNorm(); // Check if the track is long enough to have a netname displayed if( length < 10 * width ) return; const wxString& netName = aTrack->GetShortNetname(); VECTOR2D textPosition = start + line / 2.0; // center of the track double textOrientation = -atan( line.y / line.x ); double textSize = std::min( static_cast<double>( width ), length / netName.length() ); // Set a proper color for the label const COLOR4D& color = m_pcbSettings.GetColor( aTrack, aTrack->GetLayer() ); COLOR4D labelColor = m_pcbSettings.GetColor( NULL, aLayer ); if( color.GetBrightness() > 0.5 ) m_gal->SetStrokeColor( labelColor.Inverted() ); else m_gal->SetStrokeColor( labelColor ); m_gal->SetLineWidth( width / 10.0 ); m_gal->SetBold( false ); m_gal->SetItalic( false ); m_gal->SetMirrored( false ); m_gal->SetGlyphSize( VECTOR2D( textSize * 0.7, textSize * 0.7 ) ); m_gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_CENTER ); m_gal->SetVerticalJustify( GR_TEXT_VJUSTIFY_CENTER ); m_gal->StrokeText( netName, textPosition, textOrientation ); } } else if( IsCopperLayer( aLayer ) ) { // Draw a regular track const COLOR4D& color = m_pcbSettings.GetColor( aTrack, aLayer ); m_gal->SetStrokeColor( color ); m_gal->SetIsStroke( true ); if( m_pcbSettings.m_sketchMode[TRACKS_VISIBLE] ) { // Outline mode m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); m_gal->SetIsFill( false ); } else { // Filled mode m_gal->SetFillColor( color ); m_gal->SetIsFill( true ); } m_gal->DrawSegment( start, end, width ); } }
void WIDGET_EESCHEMA_COLOR_CONFIG::CreateControls() { wxStaticText* label; int buttonId = 1800; m_mainBoxSizer = new wxBoxSizer( wxHORIZONTAL ); SetSizer( m_mainBoxSizer ); BUTTONINDEX* groups = buttonGroups; wxBoxSizer* columnBoxSizer = NULL; while( groups->m_Buttons != NULL ) { COLORBUTTON* buttons = groups->m_Buttons; columnBoxSizer = new wxBoxSizer( wxVERTICAL ); m_mainBoxSizer->Add( columnBoxSizer, 1, wxALIGN_TOP | wxLEFT, 5 ); wxBoxSizer* rowBoxSizer = new wxBoxSizer( wxHORIZONTAL ); columnBoxSizer->Add( rowBoxSizer, 0, wxGROW | wxLEFT | wxRIGHT | wxBOTTOM, 5 ); // Add a text string to identify the column of color select buttons. label = new wxStaticText( this, wxID_ANY, groups->m_Name ); // Make the column label font bold. wxFont font( label->GetFont() ); font.SetWeight( wxFONTWEIGHT_BOLD ); label->SetFont( font ); rowBoxSizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 ); while( buttons->m_Layer >= 0 ) { rowBoxSizer = new wxBoxSizer( wxHORIZONTAL ); columnBoxSizer->Add( rowBoxSizer, 0, wxGROW | wxALL, 0 ); COLOR4D color = GetLayerColor( SCH_LAYER_ID( buttons->m_Layer ) ); currentColors[ buttons->m_Layer ] = color; wxMemoryDC iconDC; wxBitmap bitmap( m_butt_size_pix ); iconDC.SelectObject( bitmap ); iconDC.SetPen( *wxBLACK_PEN ); wxBrush brush; brush.SetColour( color.ToColour() ); brush.SetStyle( wxBRUSHSTYLE_SOLID ); iconDC.SetBrush( brush ); iconDC.DrawRectangle( 0, 0, m_butt_size_pix.x, m_butt_size_pix.y ); wxBitmapButton* bitmapButton = new wxBitmapButton( this, buttonId, bitmap, wxDefaultPosition, m_butt_size_pix + m_butt_border_pix + wxSize( 1, 1 ) ); bitmapButton->SetClientData( (void*) buttons ); rowBoxSizer->Add( bitmapButton, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM, 5 ); label = new wxStaticText( this, wxID_ANY, wxGetTranslation( buttons->m_Name ) ); rowBoxSizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM, 5 ); buttonId += 1; buttons++; } groups++; } Connect( 1800, buttonId, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIDGET_EESCHEMA_COLOR_CONFIG::SetColor ) ); // Dialog now needs to be resized, but the associated command is found elsewhere. }
void PCB_ONE_LAYER_SELECTOR::buildList() { // Hide layerid column which is used only to know the layer id // not to be shown in dialogs m_leftGridLayers->SetColSize( COLOR_COLNUM, 20 ); m_rightGridLayers->SetColSize( COLOR_COLNUM, 20 ); int left_row = 0; int right_row = 0; wxString layername; for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder(); ui_seq; ++ui_seq ) { LAYER_ID layerid = *ui_seq; if( m_notAllowedLayersMask[layerid] ) continue; COLOR4D color = GetLayerColor( layerid ); layername = GetLayerName( layerid ); if( IsCopperLayer( layerid ) ) { if( left_row ) m_leftGridLayers->AppendRows( 1 ); m_leftGridLayers->SetCellBackgroundColour ( left_row, COLOR_COLNUM, color.ToColour() ); m_leftGridLayers->SetCellValue( left_row, LAYERNAME_COLNUM, layername ); if( m_layerSelected == layerid ) { m_leftGridLayers->SetCellValue( left_row, SELECT_COLNUM, wxT("X") ); m_leftGridLayers->SetCellBackgroundColour ( left_row, SELECT_COLNUM, color.ToColour() ); m_leftGridLayers->SetGridCursor( left_row, LAYERNAME_COLNUM ); } m_layersIdLeftColumn.push_back( layerid ); left_row++; } else { if( right_row ) m_rightGridLayers->AppendRows( 1 ); m_rightGridLayers->SetCellBackgroundColour ( right_row, COLOR_COLNUM, color.ToColour() ); m_rightGridLayers->SetCellValue( right_row, LAYERNAME_COLNUM, layername ); if( m_layerSelected == layerid ) { m_rightGridLayers->SetCellValue( right_row, SELECT_COLNUM, wxT("X") ); m_rightGridLayers->SetCellBackgroundColour ( right_row, SELECT_COLNUM, color.ToColour() ); m_rightGridLayers->SetGridCursor( right_row, LAYERNAME_COLNUM ); } m_layersIdRightColumn.push_back( layerid ); right_row++; } } // Show only populated lists: if( left_row <= 0 ) m_leftGridLayers->Show( false ); if( right_row <= 0 ) m_rightGridLayers->Show( false ); m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM); m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM); m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM); m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM); }