Some fixes in Gerber job file:

- Ensure colors use a normalized value (normalized name or RnnGnnBnn notation).
- Better code.
This commit is contained in:
jean-pierre charras 2022-12-06 17:01:25 +01:00
parent 3836ec481f
commit 593dc9e8b6
4 changed files with 82 additions and 35 deletions

View File

@ -653,7 +653,7 @@ void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync )
{
// Note: don't use bm_combo->FindString() because the combo strings are
// translated.
for( int ii = 0; ii < GetStandardColorCount( item->GetType()); ii++ )
for( size_t ii = 0; ii < GetStandardColors( item->GetType() ).size(); ii++ )
{
if( GetStandardColorName( item->GetType(), ii ) == item->GetColor( sub_item ) )
{
@ -908,7 +908,7 @@ BOARD_STACKUP_ROW_UI_ITEM PANEL_SETUP_BOARD_STACKUP::createRowData( int aRow,
else
{
// Note: don't use bm_combo->FindString() because the combo strings are translated.
for( int ii = 0; ii < GetStandardColorCount( item->GetType()); ii++ )
for( size_t ii = 0; ii < GetStandardColors( item->GetType() ).size(); ii++ )
{
if( GetStandardColorName( item->GetType(), ii ) == item->GetColor( aSublayerIdx ) )
{
@ -1339,7 +1339,7 @@ void PANEL_SETUP_BOARD_STACKUP::onColorSelected( wxCommandEvent& event )
int row = item_id - ID_ITEM_COLOR;
BOARD_STACKUP_ITEM* item = m_rowUiItemsList[row].m_Item;
if( idx == GetStandardColorCount( item->GetType()) - 1 ) // Set user color is the last option in list
if( IsCustomColorIdx( item->GetType(), idx ) ) // user color is the last option in list
{
DIALOG_COLOR_PICKER dlg( this, m_rowUiItemsList[row].m_UserColor, true, nullptr,
GetDefaultUserColor( m_rowUiItemsList[row].m_Item->GetType() ) );
@ -1468,7 +1468,7 @@ void PANEL_SETUP_BOARD_STACKUP::onMaterialChange( wxCommandEvent& event )
wxBitmapComboBox* picker = static_cast<wxBitmapComboBox*>( m_rowUiItemsList[row].m_ColorCtrl );
for( int ii = 0; ii < GetStandardColorCount( item->GetType()); ii++ )
for( size_t ii = 0; ii < GetStandardColors( item->GetType() ).size(); ii++ )
{
if( GetStandardColorName( item->GetType(), ii ) == item->GetColor( sub_item ) )
{
@ -1588,7 +1588,7 @@ wxBitmapComboBox* PANEL_SETUP_BOARD_STACKUP::createColorBox( BOARD_STACKUP_ITEM*
BOARD_STACKUP_ITEM_TYPE itemType = aStackupItem ? aStackupItem->GetType()
: BS_ITEM_TYPE_SILKSCREEN;
for( int ii = 0; ii < GetStandardColorCount( itemType ); ii++ )
for( size_t ii = 0; ii < GetStandardColors( itemType ).size(); ii++ )
{
wxString label;
COLOR4D curr_color;

View File

@ -56,7 +56,7 @@ static wxString copperFinishType[] =
// .gbrjob files.
// For other colors (user defined), the defined value is the html color syntax in .kicad_pcb files
// and R<integer>G<integer>B<integer> in .gbrjob file.
static FAB_LAYER_COLOR gbrjobColors[] =
static std::vector<FAB_LAYER_COLOR> gbrjobColors =
{
{ NotSpecifiedPrm(), wxColor( 80, 80, 80 ) }, // Not specified, not in .gbrjob file
{ _HKI( "Green" ), wxColor( 60, 150, 80 ) }, // used in .gbrjob file
@ -70,9 +70,9 @@ static FAB_LAYER_COLOR gbrjobColors[] =
};
// These are used primarily as a source for the 3D renderer. They are not (at present) written
// to the .gbrjob file.
static FAB_LAYER_COLOR dielectricColors[] =
// These are used primarily as a source for the 3D renderer. They are written
// as R<integer>G<integer>B<integer> to the .gbrjob file.
static std::vector<FAB_LAYER_COLOR> dielectricColors =
{
{ NotSpecifiedPrm(), wxColor( 80, 80, 80, 255 ) },
{ _HKI( "FR4 natural" ), wxColor( 109, 116, 75, 212 ) },
@ -94,27 +94,15 @@ wxArrayString GetStandardCopperFinishes( bool aTranslate )
return list;
}
const FAB_LAYER_COLOR* GetStandardColors( BOARD_STACKUP_ITEM_TYPE aType )
std::vector<FAB_LAYER_COLOR> dummy;
const std::vector<FAB_LAYER_COLOR>& GetStandardColors( BOARD_STACKUP_ITEM_TYPE aType )
{
switch( aType )
{
case BS_ITEM_TYPE_SILKSCREEN: return gbrjobColors;
case BS_ITEM_TYPE_SOLDERMASK: return gbrjobColors;
case BS_ITEM_TYPE_DIELECTRIC: return dielectricColors;
default: return nullptr;
}
}
int GetStandardColorCount( BOARD_STACKUP_ITEM_TYPE aType )
{
switch( aType )
{
case BS_ITEM_TYPE_SILKSCREEN: return arrayDim( gbrjobColors );
case BS_ITEM_TYPE_SOLDERMASK: return arrayDim( gbrjobColors );
case BS_ITEM_TYPE_DIELECTRIC: return arrayDim( dielectricColors );
default: return 0;
default: return dummy;
}
}
@ -122,5 +110,33 @@ int GetStandardColorCount( BOARD_STACKUP_ITEM_TYPE aType )
int GetColorUserDefinedListIdx( BOARD_STACKUP_ITEM_TYPE aType )
{
// this is the last item in list
return GetStandardColorCount( aType ) - 1;
return GetStandardColors( aType ).size() - 1;
}
bool IsColorNameNormalized( const wxString& aName )
{
static std::vector<wxString> list =
{
wxT( "Green" ), wxT( "Red" ), wxT( "Blue" ),
wxT( "Black" ), wxT( "White" ), wxT( "Yellow" )
};
for( wxString& candidate : list )
{
if( candidate.CmpNoCase( aName ) == 0 )
return true;
}
return false;
}
const wxString FAB_LAYER_COLOR::GetColorAsString() const
{
if( IsColorNameNormalized( m_colorName ) )
return m_colorName;
return wxString::Format( wxT( "R%dG%dB%d" ),
int( m_color.r*255 ), int( m_color.g*255 ), int( m_color.b*255 ) );
}

View File

@ -93,10 +93,18 @@ public:
return m_color.WithAlpha( 1.0 );
}
/**
* @return a color name acceptable in gerber job file
* one of normalized color name, or the string R<integer>G<integer>B<integer>
* integer is a decimal value from 0 to 255
*/
const wxString GetColorAsString() const;
private:
wxString m_colorName; // the name (in job file) of the color
// User values are the HTML coding #rrggbbaa hexadecimal value.
KIGFX::COLOR4D m_color;
wxString m_colorName; // the name (in job file) of the color
// User values are the HTML encoded "#rrggbbaa"
// RGB hexa value.
KIGFX::COLOR4D m_color;
};
@ -109,12 +117,7 @@ wxArrayString GetStandardCopperFinishes( bool aTranslate );
/**
* @return a list of standard FAB_LAYER_COLOR items for silkscreen and solder mask.
*/
const FAB_LAYER_COLOR* GetStandardColors( BOARD_STACKUP_ITEM_TYPE aType );
/**
* @return the count of colors in ColorStandardList
*/
int GetStandardColorCount( BOARD_STACKUP_ITEM_TYPE aType );
const std::vector<FAB_LAYER_COLOR>& GetStandardColors( BOARD_STACKUP_ITEM_TYPE aType );
/**
* @return the index of the user defined color in ColorStandardList
@ -141,5 +144,11 @@ inline bool IsCustomColorIdx( BOARD_STACKUP_ITEM_TYPE aType, int aIdx )
return aIdx == GetColorUserDefinedListIdx( aType );
}
/**
* @return true if aName is a color name acceptable in gerber job files
* @param aName is a color name like red, blue... (case insensitive)
*/
bool IsColorNameNormalized( const wxString& aName );
#endif // #ifndef STACKUP_PREDEFINED_PRMS_H

View File

@ -660,15 +660,37 @@ void GERBER_JOBFILE_WRITER::addJSONMaterialStackup()
{
wxString colorName = item->GetColor( sub_idx );
if( colorName.StartsWith( wxT( "#" ) ) ) // This is a user defined color.
if( colorName.StartsWith( wxT( "#" ) ) ) // This is a user defined color,
// not in standard color list.
{
// In job file a color can be given by its RGB values (0...255)
// like R<number><G<number>B<number> notation
wxColor color( COLOR4D( colorName ).ToColour() );
colorName.Printf( wxT( "R%dG%dB%d" ),
color.Red(),
color.Green(),
color.Blue() );
}
else
{
const std::vector<FAB_LAYER_COLOR>& color_list =
GetStandardColors( item->GetType() );
// Colors for dielectric use a color list that is mainly not normalized in
// job file names. So if a color is in the dielectric standard color list
// it can be a standard name or not.
// Colors for solder mask and silk screen use a mainly normalized
// color list, but this list can also contain not normalized colors.
// If not normalized, use the R<number><G<number>B<number> notation
for( const FAB_LAYER_COLOR& prm_color : color_list )
{
if( colorName == prm_color.GetName() )
{
colorName = prm_color.GetColorAsString();
break;
}
}
}
layer_json["Color"] = colorName;
}