Fix some issues in .gbrjob file.
2 issues are fixed: a missing double quote, and a incorrect handling of unicode chars Fixes: lp:1836448 https://bugs.launchpad.net/kicad/+bug/1836448
This commit is contained in:
parent
be5f3717c7
commit
fc2379ca8a
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2017 Jean-Pierre Charras jp.charras at wanadoo.fr
|
* Copyright (C) 2007-2019 Jean-Pierre Charras jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -89,6 +89,11 @@ private:
|
||||||
REPORTER* m_reporter;
|
REPORTER* m_reporter;
|
||||||
wxFileName m_filename;
|
wxFileName m_filename;
|
||||||
wxArrayString m_GerberFiles; // List of gerber files in job
|
wxArrayString m_GerberFiles; // List of gerber files in job
|
||||||
|
|
||||||
|
// Convert a JSON string, that uses escaped sequence of 4 hexdecimal digits
|
||||||
|
// to encode unicode chars when not ASCII7 codes
|
||||||
|
// json11 converts this sequence to UTF8 string
|
||||||
|
wxString formatStringFromJSON( const std::string& name );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,10 +138,8 @@ bool GERBER_JOBFILE_READER::ReadGerberJobFile()
|
||||||
|
|
||||||
for( auto& entry : json_parser["FilesAttributes"].array_items() )
|
for( auto& entry : json_parser["FilesAttributes"].array_items() )
|
||||||
{
|
{
|
||||||
//wxLogMessage( entry.dump().c_str() );
|
|
||||||
std::string name = entry["Path"].string_value();
|
std::string name = entry["Path"].string_value();
|
||||||
//wxLogMessage( name.c_str() );
|
m_GerberFiles.Add( formatStringFromJSON( name ) );
|
||||||
m_GerberFiles.Add( FormatStringFromGerber( name ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -152,6 +155,18 @@ bool GERBER_JOBFILE_READER::ReadGerberJobFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString GERBER_JOBFILE_READER::formatStringFromJSON( const std::string& name )
|
||||||
|
{
|
||||||
|
// Convert a JSON string, that uses a escaped sequence of 4 hexdecimal digits
|
||||||
|
// to encode unicode chars
|
||||||
|
// Our json11 library returns in this case a UTF8 sequence. Just convert it to
|
||||||
|
// a wxString.
|
||||||
|
wxString wstr = FROM_UTF8( name.c_str() );
|
||||||
|
return wstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool GERBVIEW_FRAME::LoadGerberJobFile( const wxString& aFullFileName )
|
bool GERBVIEW_FRAME::LoadGerberJobFile( const wxString& aFullFileName )
|
||||||
{
|
{
|
||||||
wxFileName filename = aFullFileName;
|
wxFileName filename = aFullFileName;
|
||||||
|
@ -221,5 +236,3 @@ bool GERBVIEW_FRAME::LoadGerberJobFile( const wxString& aFullFileName )
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <layers_id_colors_and_visibility.h>
|
#include <layers_id_colors_and_visibility.h>
|
||||||
#include <board_design_settings.h>
|
#include <board_design_settings.h>
|
||||||
#include <class_board.h>
|
#include <class_board.h>
|
||||||
|
#include <i18n_utility.h> // For _HKI definition
|
||||||
#include "stackup_predefined_prms.h"
|
#include "stackup_predefined_prms.h"
|
||||||
|
|
||||||
// A reasonable thickness for copper layers:
|
// A reasonable thickness for copper layers:
|
||||||
|
@ -310,6 +311,9 @@ bool BOARD_STACKUP::SynchronizeWithBoard( BOARD_DESIGN_SETTINGS* aSettings )
|
||||||
void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings )
|
void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings )
|
||||||
{
|
{
|
||||||
// Creates a default stackup, according to the current BOARD_DESIGN_SETTINGS settings.
|
// Creates a default stackup, according to the current BOARD_DESIGN_SETTINGS settings.
|
||||||
|
// Note: the m_TypeName string is made translatable using _HKI marker, but is not
|
||||||
|
// translated when building the stackup.
|
||||||
|
// It will be used as this in files, and can be translated only in dialog
|
||||||
LSET enabledLayer = aSettings->GetEnabledLayers();
|
LSET enabledLayer = aSettings->GetEnabledLayers();
|
||||||
int copperLayerCount = aSettings->GetCopperLayerCount();
|
int copperLayerCount = aSettings->GetCopperLayerCount();
|
||||||
double diel_thickness = aSettings->GetBoardThickness()
|
double diel_thickness = aSettings->GetBoardThickness()
|
||||||
|
@ -323,7 +327,7 @@ void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings )
|
||||||
{
|
{
|
||||||
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SILKSCREEN );
|
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SILKSCREEN );
|
||||||
item->m_LayerId = F_SilkS;
|
item->m_LayerId = F_SilkS;
|
||||||
item->m_TypeName = _( "Top Silk Screen" );
|
item->m_TypeName = _HKI( "Top Silk Screen" );
|
||||||
Add( item );
|
Add( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +335,7 @@ void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings )
|
||||||
{
|
{
|
||||||
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SOLDERPASTE );
|
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SOLDERPASTE );
|
||||||
item->m_LayerId = F_Paste;
|
item->m_LayerId = F_Paste;
|
||||||
item->m_TypeName = _( "Top Solder Paste" );
|
item->m_TypeName = _HKI( "Top Solder Paste" );
|
||||||
Add( item );
|
Add( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +343,7 @@ void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings )
|
||||||
{
|
{
|
||||||
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SOLDERMASK );
|
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SOLDERMASK );
|
||||||
item->m_LayerId = F_Mask;
|
item->m_LayerId = F_Mask;
|
||||||
item->m_TypeName = _( "Top Solder Mask" );
|
item->m_TypeName = _HKI( "Top Solder Mask" );
|
||||||
Add( item );
|
Add( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,12 +368,12 @@ void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings )
|
||||||
// Display a dielectric default layer name:
|
// Display a dielectric default layer name:
|
||||||
if( (dielectric_idx & 1) == 0 )
|
if( (dielectric_idx & 1) == 0 )
|
||||||
{
|
{
|
||||||
item->m_TypeName = _( "core" );
|
item->m_TypeName = _HKI( "core" );
|
||||||
item->m_Material = "FR4";
|
item->m_Material = "FR4";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->m_TypeName = _( "prepreg" );
|
item->m_TypeName = _HKI( "prepreg" );
|
||||||
item->m_Material = "FR4";
|
item->m_Material = "FR4";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +386,7 @@ void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings )
|
||||||
{
|
{
|
||||||
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SOLDERMASK );
|
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SOLDERMASK );
|
||||||
item->m_LayerId = B_Mask;
|
item->m_LayerId = B_Mask;
|
||||||
item->m_TypeName = _( "Bottom Solder Mask" );
|
item->m_TypeName = _HKI( "Bottom Solder Mask" );
|
||||||
Add( item );
|
Add( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,7 +394,7 @@ void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings )
|
||||||
{
|
{
|
||||||
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SOLDERPASTE );
|
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SOLDERPASTE );
|
||||||
item->m_LayerId = B_Paste;
|
item->m_LayerId = B_Paste;
|
||||||
item->m_TypeName = _( "Bottom Solder Paste" );
|
item->m_TypeName = _HKI( "Bottom Solder Paste" );
|
||||||
Add( item );
|
Add( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +402,7 @@ void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings )
|
||||||
{
|
{
|
||||||
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SILKSCREEN );
|
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SILKSCREEN );
|
||||||
item->m_LayerId = B_SilkS;
|
item->m_LayerId = B_SilkS;
|
||||||
item->m_TypeName = _( "Bottom Silk Screen" );
|
item->m_TypeName = _HKI( "Bottom Silk Screen" );
|
||||||
Add( item );
|
Add( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,25 @@ GERBER_JOBFILE_WRITER::GERBER_JOBFILE_WRITER( BOARD* aPcb, REPORTER* aReporter )
|
||||||
m_indent = 0;
|
m_indent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string GERBER_JOBFILE_WRITER::formatStringFromUTF32( const wxString& aText )
|
||||||
|
{
|
||||||
|
std::string fmt_text; // the text after UTF32 to UTF8 conversion
|
||||||
|
|
||||||
|
for( unsigned long letter: aText )
|
||||||
|
{
|
||||||
|
if( letter >= ' ' && letter <= 0x7F )
|
||||||
|
fmt_text += char( letter );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char buff[10];
|
||||||
|
sprintf( buff, "\\u%4.4lX", letter );
|
||||||
|
fmt_text += buff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
enum ONSIDE GERBER_JOBFILE_WRITER::hasSilkLayers()
|
enum ONSIDE GERBER_JOBFILE_WRITER::hasSilkLayers()
|
||||||
{
|
{
|
||||||
int flag = SIDE_NONE;
|
int flag = SIDE_NONE;
|
||||||
|
@ -249,7 +268,7 @@ void GERBER_JOBFILE_WRITER::addJSONGeneralSpecs()
|
||||||
wxString guid = GbrMakeProjectGUIDfromString( msg );
|
wxString guid = GbrMakeProjectGUIDfromString( msg );
|
||||||
|
|
||||||
// build the <project id> string: this is the board short filename (without ext)
|
// build the <project id> string: this is the board short filename (without ext)
|
||||||
// and all non ASCII chars are replaced by '_'
|
// and all non ASCII chars are replaced by '_', to be compatible with .gbr files.
|
||||||
msg = fn.GetName();
|
msg = fn.GetName();
|
||||||
|
|
||||||
// build the <rec> string. All non ASCII chars and comma are replaced by '_'
|
// build the <rec> string. All non ASCII chars and comma are replaced by '_'
|
||||||
|
@ -421,9 +440,8 @@ void GERBER_JOBFILE_WRITER::addJSONFilesAttributes()
|
||||||
if( !skip_file )
|
if( !skip_file )
|
||||||
{
|
{
|
||||||
// name can contain non ASCII7 chars.
|
// name can contain non ASCII7 chars.
|
||||||
// Only ASCII7 chars are accepted in gerber files. others must be converted to
|
// Ensure the name is JSON compatible.
|
||||||
// a gerber hexa sequence.
|
std::string strname = formatStringFromUTF32( name );
|
||||||
std::string strname = formatStringToGerber( name );
|
|
||||||
|
|
||||||
openBlock();
|
openBlock();
|
||||||
addJSONObject( wxString::Format( "\"Path\": \"%s\",\n", strname.c_str() ) );
|
addJSONObject( wxString::Format( "\"Path\": \"%s\",\n", strname.c_str() ) );
|
||||||
|
@ -604,28 +622,28 @@ void GERBER_JOBFILE_WRITER::addJSONMaterialStackup()
|
||||||
{
|
{
|
||||||
case BS_ITEM_TYPE_COPPER:
|
case BS_ITEM_TYPE_COPPER:
|
||||||
layer_type = "Copper";
|
layer_type = "Copper";
|
||||||
layer_name = formatStringToGerber( m_pcb->GetLayerName( item->m_LayerId ) );
|
layer_name = formatStringFromUTF32( m_pcb->GetLayerName( item->m_LayerId ) );
|
||||||
last_copper_layer = item->m_LayerId;
|
last_copper_layer = item->m_LayerId;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BS_ITEM_TYPE_SILKSCREEN:
|
case BS_ITEM_TYPE_SILKSCREEN:
|
||||||
layer_type = "Legend";
|
layer_type = "Legend";
|
||||||
layer_name = formatStringToGerber( item->m_TypeName );
|
layer_name = formatStringFromUTF32( item->m_TypeName );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BS_ITEM_TYPE_SOLDERMASK:
|
case BS_ITEM_TYPE_SOLDERMASK:
|
||||||
layer_type = "SolderMask";
|
layer_type = "SolderMask";
|
||||||
layer_name = formatStringToGerber( item->m_TypeName );
|
layer_name = formatStringFromUTF32( item->m_TypeName );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BS_ITEM_TYPE_SOLDERPASTE:
|
case BS_ITEM_TYPE_SOLDERPASTE:
|
||||||
layer_type = "SolderPaste";
|
layer_type = "SolderPaste";
|
||||||
layer_name = formatStringToGerber( item->m_TypeName );
|
layer_name = formatStringFromUTF32( item->m_TypeName );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BS_ITEM_TYPE_DIELECTRIC:
|
case BS_ITEM_TYPE_DIELECTRIC:
|
||||||
layer_type = "Dielectric";
|
layer_type = "Dielectric";
|
||||||
layer_name = formatStringToGerber( wxString::Format( "dielectric layer %d (%s)",
|
layer_name = formatStringFromUTF32( wxString::Format( "dielectric layer %d (%s)",
|
||||||
item->m_DielectricLayerId, item->m_TypeName ) );
|
item->m_DielectricLayerId, item->m_TypeName ) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -670,14 +688,16 @@ void GERBER_JOBFILE_WRITER::addJSONMaterialStackup()
|
||||||
if( uptodate ) // We can add the dielectric variant ("core" "prepreg" ...):
|
if( uptodate ) // We can add the dielectric variant ("core" "prepreg" ...):
|
||||||
note << wxString::Format( " \"Type: %s", layer_name.c_str() );
|
note << wxString::Format( " \"Type: %s", layer_name.c_str() );
|
||||||
|
|
||||||
note << wxString::Format( " (from %s to %s)\"\n",
|
note << wxString::Format( " \"(from %s to %s)\"\n",
|
||||||
formatStringToGerber( m_pcb->GetLayerName( last_copper_layer ) ),
|
formatStringFromUTF32( m_pcb->GetLayerName( last_copper_layer ) ),
|
||||||
formatStringToGerber( m_pcb->GetLayerName( next_copper_layer ) ) );
|
formatStringFromUTF32( m_pcb->GetLayerName( next_copper_layer ) ) );
|
||||||
|
|
||||||
addJSONObject( note );
|
addJSONObject( note );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
addJSONObject( wxString::Format( "\"Notes\": \"Layer: %s\",\n", layer_name.c_str() ) );
|
addJSONObject( wxString::Format( "\"Notes\": \"Layer: %s\",\n", layer_name.c_str() ) );
|
||||||
|
}
|
||||||
|
|
||||||
removeJSONSepararator();
|
removeJSONSepararator();
|
||||||
closeBlockWithSep();
|
closeBlockWithSep();
|
||||||
|
|
|
@ -202,6 +202,11 @@ private:
|
||||||
addIndent(); m_JSONbuffer << aParam;
|
addIndent(); m_JSONbuffer << aParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A helper function to convert a wxString ( therefore a Unicode text ) to
|
||||||
|
* a JSON compatible string (a escaped unicode sequence of 4 hexa).
|
||||||
|
*/
|
||||||
|
std::string formatStringFromUTF32( const wxString& aText );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BOARD* m_pcb; // The board
|
BOARD* m_pcb; // The board
|
||||||
REPORTER* m_reporter; // a reporter for messages (can be null)
|
REPORTER* m_reporter; // a reporter for messages (can be null)
|
||||||
|
|
Loading…
Reference in New Issue