KiCad PCB EDA Suite
eeschema.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
5  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@verizon.net>
6  * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <fctsys.h>
27 #include <pgm_base.h>
28 #include <kiface_i.h>
29 #include <confirm.h>
30 #include <gestfich.h>
31 #include <eda_dde.h>
32 #include <sch_edit_frame.h>
33 #include <lib_edit_frame.h>
34 #include <viewlib_frame.h>
35 #include <general.h>
36 #include <class_libentry.h>
37 #include <transform.h>
38 #include <symbol_lib_table.h>
41 #include <kiway.h>
42 #include <sim/sim_plot_frame.h>
43 #include <sexpr/sexpr.h>
44 #include <sexpr/sexpr_parser.h>
45 
46 // The main sheet of the project
48 
49 // a transform matrix, to display components in lib editor
51 
52 
53 namespace SCH {
54 
55 static struct IFACE : public KIFACE_I
56 {
57  // Of course all are virtual overloads, implementations of the KIFACE.
58 
59  IFACE( const char* aName, KIWAY::FACE_T aType ) :
60  KIFACE_I( aName, aType )
61  {}
62 
63  bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) override;
64 
65  void OnKifaceEnd() override;
66 
67  wxWindow* CreateWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 ) override
68  {
69  switch( aClassId )
70  {
71  case FRAME_SCH:
72  {
73  SCH_EDIT_FRAME* frame = new SCH_EDIT_FRAME( aKiway, aParent );
74 
75  if( Kiface().IsSingle() )
76  {
77  // only run this under single_top, not under a project manager.
79  }
80 
81  return frame;
82  }
83 
85  {
86  LIB_EDIT_FRAME* frame = new LIB_EDIT_FRAME( aKiway, aParent );
87  return frame;
88  }
89 
90 #ifdef KICAD_SPICE
91  case FRAME_SIMULATOR:
92  {
93  SIM_PLOT_FRAME* frame = new SIM_PLOT_FRAME( aKiway, aParent );
94  return frame;
95  }
96 #endif
97  case FRAME_SCH_VIEWER:
99  {
100  LIB_VIEW_FRAME* frame = new LIB_VIEW_FRAME( aKiway, aParent, FRAME_T( aClassId ) );
101  return frame;
102  }
103 
105  InvokeSchEditSymbolLibTable( aKiway, aParent );
106  // Dialog has completed; nothing to return.
107  return nullptr;
108 
109  default:
110  return NULL;
111  }
112  }
113 
122  void* IfaceOrAddress( int aDataId ) override
123  {
124  return NULL;
125  }
126 
133  void SaveFileAs( const wxString& aProjectBasePath, const wxString& aProjectName,
134  const wxString& aNewProjectBasePath, const wxString& aNewProjectName,
135  const wxString& aSrcFilePath, wxString& aErrors ) override;
136 
137 } kiface( "eeschema", KIWAY::FACE_SCH );
138 
139 } // namespace
140 
141 using namespace SCH;
142 
144 
145 
146 KIFACE_I& Kiface() { return kiface; }
147 
148 
149 // KIFACE_GETTER's actual spelling is a substitution macro found in kiway.h.
150 // KIFACE_GETTER will not have name mangling due to declaration in kiway.h.
151 MY_API( KIFACE* ) KIFACE_GETTER( int* aKIFACEversion, int aKiwayVersion, PGM_BASE* aProgram )
152 {
153  process = aProgram;
154  return &kiface;
155 }
156 
157 
159 {
160  wxASSERT( process ); // KIFACE_GETTER has already been called.
161  return *process;
162 }
163 
164 
166 
168 {
169  unsigned layer = ( aLayer );
170  wxASSERT( layer < arrayDim( s_layerColor ) );
171  return s_layerColor[layer];
172 }
173 
174 void SetLayerColor( COLOR4D aColor, SCH_LAYER_ID aLayer )
175 {
176  // Do not allow non-background layers to be completely white.
177  // This ensures the BW printing recognizes that the colors should be printed black.
178  if( aColor == COLOR4D::WHITE && aLayer != LAYER_SCHEMATIC_BACKGROUND )
179  aColor.Darken( 0.01 );
180 
181  unsigned layer = aLayer;
182  wxASSERT( layer < arrayDim( s_layerColor ) );
183  s_layerColor[layer] = aColor;
184 }
185 
186 
188 {
189  static PARAM_CFG_ARRAY ca;
190 
191  if( !ca.size() )
192  {
193  // These are KIFACE specific, they need to be loaded once when the
194  // eeschema KIFACE comes in.
195 
196 #define CLR(x, y, z)\
197  ca.push_back( new PARAM_CFG_SETCOLOR( true, wxT( x ),\
198  &s_layerColor[( y )], z ) );
199 
200  CLR( "Color4DWireEx", LAYER_WIRE, COLOR4D( GREEN ) )
201  CLR( "Color4DBusEx", LAYER_BUS, COLOR4D( BLUE ) )
202  CLR( "Color4DConnEx", LAYER_JUNCTION, COLOR4D( GREEN ) )
203  CLR( "Color4DLLabelEx", LAYER_LOCLABEL, COLOR4D( BLACK ) )
204  CLR( "Color4DHLabelEx", LAYER_HIERLABEL, COLOR4D( BROWN ) )
205  CLR( "Color4DGLabelEx", LAYER_GLOBLABEL, COLOR4D( RED ) )
206  CLR( "Color4DPinNumEx", LAYER_PINNUM, COLOR4D( RED ) )
207  CLR( "Color4DPinNameEx", LAYER_PINNAM, COLOR4D( CYAN ) )
208  CLR( "Color4DFieldEx", LAYER_FIELDS, COLOR4D( MAGENTA ) )
209  CLR( "Color4DReferenceEx", LAYER_REFERENCEPART, COLOR4D( CYAN ) )
210  CLR( "Color4DValueEx", LAYER_VALUEPART, COLOR4D( CYAN ) )
211  CLR( "Color4DNoteEx", LAYER_NOTES, COLOR4D( LIGHTBLUE ) )
212  CLR( "Color4DBodyEx", LAYER_DEVICE, COLOR4D( RED ) )
213  CLR( "Color4DBodyBgEx", LAYER_DEVICE_BACKGROUND, COLOR4D( LIGHTYELLOW ) )
214  CLR( "Color4DNetNameEx", LAYER_NETNAM, COLOR4D( DARKGRAY ) )
215  CLR( "Color4DPinEx", LAYER_PIN, COLOR4D( RED ) )
216  CLR( "Color4DSheetEx", LAYER_SHEET, COLOR4D( MAGENTA ) )
217  CLR( "Color4DSheetFileNameEx", LAYER_SHEETFILENAME, COLOR4D( BROWN ) )
218  CLR( "Color4DSheetNameEx", LAYER_SHEETNAME, COLOR4D( CYAN ) )
219  CLR( "Color4DSheetLabelEx", LAYER_SHEETLABEL, COLOR4D( BROWN ) )
220  CLR( "Color4DNoConnectEx", LAYER_NOCONNECT, COLOR4D( BLUE ) )
221  CLR( "Color4DErcWEx", LAYER_ERC_WARN, COLOR4D( GREEN ).WithAlpha(0.8 ) )
222  CLR( "Color4DErcEEx", LAYER_ERC_ERR, COLOR4D( RED ).WithAlpha(0.8 ) )
223  CLR( "Color4DGridEx", LAYER_SCHEMATIC_GRID, COLOR4D( DARKGRAY ) )
224  CLR( "Color4DBgCanvasEx", LAYER_SCHEMATIC_BACKGROUND, COLOR4D( WHITE ) )
225  CLR( "Color4DCursorEx", LAYER_SCHEMATIC_CURSOR, COLOR4D( BLACK ) )
226  CLR( "Color4DBrightenedEx", LAYER_BRIGHTENED, COLOR4D( PUREMAGENTA ) )
227  CLR( "Color4DHiddenEx", LAYER_HIDDEN, COLOR4D( LIGHTGRAY ) )
228  CLR( "Color4DWorksheetEx", LAYER_WORKSHEET, COLOR4D( RED ) )
229 // Macs look better with a lighter shadow
230 #ifdef __WXMAC__
231  CLR( "Color4DShadowEx", LAYER_SELECTION_SHADOWS, COLOR4D( .78, .92, 1.0, 0.8 ) )
232 #else
233  CLR( "Color4DShadowEx", LAYER_SELECTION_SHADOWS, COLOR4D( .4, .7, 1.0, 0.8 ) )
234 #endif
235  }
236 
237  return ca;
238 }
239 
240 
241 bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
242 {
243  // This is process-level-initialization, not project-level-initialization of the DSO.
244  // Do nothing in here pertinent to a project!
245 
246  start_common( aCtlBits );
247 
248  // Give a default colour for all layers (actual color will be initialized by config)
249  for( SCH_LAYER_ID ii = SCH_LAYER_ID_START; ii < SCH_LAYER_ID_END; ++ii )
250  SetLayerColor( COLOR4D( DARKGRAY ), ii );
251 
254 
256 
258 
259  if( !fn.FileExists() )
260  {
261  DIALOG_GLOBAL_SYM_LIB_TABLE_CONFIG fpDialog( NULL );
262 
263  fpDialog.ShowModal();
264  }
265  else
266  {
267  try
268  {
269  // The global table is not related to a specific project. All projects
270  // will use the same global table. So the KIFACE::OnKifaceStart() contract
271  // of avoiding anything project specific is not violated here.
273  return false;
274  }
275  catch( const IO_ERROR& ioe )
276  {
277  // if we are here, a incorrect global symbol library table was found.
278  // Incorrect global symbol library table is not a fatal error:
279  // the user just has to edit the (partially) loaded table.
280  wxString msg = _(
281  "An error occurred attempting to load the global symbol library table.\n"
282  "Please edit this global symbol library table in Preferences menu."
283  );
284 
285  DisplayErrorMessage( NULL, msg, ioe.What() );
286  }
287  }
288 
289  return true;
290 }
291 
292 
294 {
296  end_common();
297 }
298 
299 static void traverseSEXPR( SEXPR::SEXPR* aNode,
300  const std::function<void( SEXPR::SEXPR* )>& aVisitor )
301 {
302  aVisitor( aNode );
303 
304  if( aNode->IsList() )
305  {
306  for( unsigned i = 0; i < aNode->GetNumberOfChildren(); i++ )
307  traverseSEXPR( aNode->GetChild( i ), aVisitor );
308  }
309 }
310 
311 
312 void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aProjectName,
313  const wxString& aNewProjectBasePath, const wxString& aNewProjectName,
314  const wxString& aSrcFilePath, wxString& aErrors )
315 {
316  wxFileName destFile( aSrcFilePath );
317  wxString destPath = destFile.GetPath();
318  wxString ext = destFile.GetExt();
319 
320  if( destPath.StartsWith( aProjectBasePath ) )
321  {
322  destPath.Replace( aProjectBasePath, aNewProjectBasePath, false );
323  destFile.SetPath( destPath );
324  }
325 
326  if( ext == "sch" || ext == "sch-bak" )
327  {
328  if( destFile.GetName() == aProjectName )
329  destFile.SetName( aNewProjectName );
330 
331  // Sheet paths when auto-generated are relative to the root, so those will stay
332  // pointing to whatever they were pointing at.
333  // The author can create their own absolute and relative sheet paths. Absolute
334  // sheet paths aren't an issue, and relative ones will continue to work as long
335  // as the author didn't include any '..'s. If they did, it's still not clear
336  // whether they should be adjusted or not (as the author may be duplicating an
337  // entire tree with several projects within it), so we leave this as an exercise
338  // to the author.
339 
340  CopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
341  }
342  else if( ext == "sym" )
343  {
344  // Symbols are not project-specific. Keep their source names.
345  CopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
346  }
347  else if( ext == "lib" )
348  {
349  if( destFile.GetName() == aProjectName )
350  destFile.SetName( aNewProjectName );
351  else if( destFile.GetName() == aProjectName + "-cache" )
352  destFile.SetName( aNewProjectName + "-cache" );
353  else if( destFile.GetName() == aProjectName + "-rescue" )
354  destFile.SetName( aNewProjectName + "-rescue" );
355 
356  CopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
357  }
358  else if( ext == "net" )
359  {
360  bool success = false;
361 
362  if( destFile.GetName() == aProjectName )
363  destFile.SetName( aNewProjectName );
364 
365  try
366  {
367  SEXPR::PARSER parser;
368  std::unique_ptr<SEXPR::SEXPR> sexpr( parser.ParseFromFile( TO_UTF8( aSrcFilePath ) ) );
369 
370  traverseSEXPR( sexpr.get(), [&]( SEXPR::SEXPR* node )
371  {
372  if( node->IsList() && node->GetNumberOfChildren() > 1
373  && node->GetChild( 0 )->IsSymbol()
374  && node->GetChild( 0 )->GetSymbol() == "source" )
375  {
376  auto pathNode = dynamic_cast<SEXPR::SEXPR_STRING*>( node->GetChild( 1 ) );
377  auto symNode = dynamic_cast<SEXPR::SEXPR_SYMBOL*>( node->GetChild( 1 ) );
378  wxString path;
379 
380  if( pathNode )
381  path = pathNode->m_value;
382  else if( symNode )
383  path = symNode->m_value;
384 
385  if( path == aProjectName + ".sch" )
386  path = aNewProjectName + ".sch";
387  else if( path == aProjectBasePath + "/" + aProjectName + ".sch" )
388  path = aNewProjectBasePath + "/" + aNewProjectName + ".sch";
389  else if( path.StartsWith( aProjectBasePath ) )
390  path.Replace( aProjectBasePath, aNewProjectBasePath, false );
391 
392  if( pathNode )
393  pathNode->m_value = path;
394  else if( symNode )
395  symNode->m_value = path;
396  }
397  } );
398 
399  wxFile destNetList( destFile.GetFullPath(), wxFile::write );
400 
401  if( destNetList.IsOpened() )
402  success = destNetList.Write( sexpr->AsString( 0 ) );
403 
404  // wxFile dtor will close the file
405  }
406  catch( ... )
407  {
408  success = false;
409  }
410 
411  if( !success )
412  {
413  wxString msg;
414 
415  if( !aErrors.empty() )
416  aErrors += "\n";
417 
418  msg.Printf( _( "Cannot copy file \"%s\"." ), destFile.GetFullPath() );
419  aErrors += msg;
420  }
421  }
422  else if( destFile.GetName() == "sym-lib-table" )
423  {
424  SYMBOL_LIB_TABLE symbolLibTable;
425  symbolLibTable.Load( aSrcFilePath );
426 
427  for( unsigned i = 0; i < symbolLibTable.GetCount(); i++ )
428  {
429  LIB_TABLE_ROW& row = symbolLibTable.At( i );
430  wxString uri = row.GetFullURI();
431 
432  uri.Replace( "/" + aProjectName + "-cache.lib", "/" + aNewProjectName + "-cache.lib" );
433  uri.Replace( "/" + aProjectName + "-rescue.lib", "/" + aNewProjectName + "-rescue.lib" );
434  uri.Replace( "/" + aProjectName + ".lib", "/" + aNewProjectName + ".lib" );
435 
436  row.SetFullURI( uri );
437  }
438 
439  try
440  {
441  symbolLibTable.Save( destFile.GetFullPath() );
442  }
443  catch( ... )
444  {
445  wxString msg;
446 
447  if( !aErrors.empty() )
448  aErrors += "\n";
449 
450  msg.Printf( _( "Cannot copy file \"%s\"." ), destFile.GetFullPath() );
451  aErrors += msg;
452  }
453  }
454  else
455  {
456  wxFAIL_MSG( "Unexpected filetype for Eeschema::SaveFileAs()" );
457  }
458 }
459 
static void traverseSEXPR(SEXPR::SEXPR *aNode, const std::function< void(SEXPR::SEXPR *)> &aVisitor)
Definition: eeschema.cpp:299
Definition: colors.h:57
SCH::IFACE KIFACE_I kiface("eeschema", KIWAY::FACE_SCH)
static SYMBOL_LIB_TABLE & GetGlobalLibTable()
A list of parameters type.
Class KIFACE_I is a KIFACE (I)mplementation, with some features useful for DSOs which implement a KIF...
Definition: kiface_i.h:37
DDE server & client.
bool start_common(int aCtlBits)
Common things to do for a top program module, during OnKifaceStart().
Definition: kiface_i.cpp:90
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
void SetLayerColor(COLOR4D aColor, SCH_LAYER_ID aLayer)
Definition: eeschema.cpp:174
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:249
This file is part of the common library TODO brief description.
This file is part of the common library.
int aKiwayVersion
Definition: eeschema.cpp:151
void OnKifaceEnd() override
Function OnKifaceEnd is called just once just before the DSO is to be unloaded.
Definition: eeschema.cpp:293
Class PGM_BASE keeps program (whole process) data for KiCad programs.
Definition: pgm_base.h:156
FRAME_T
Enum FRAME_T is the set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition: frame_type.h:34
unsigned GetCount() const
Get the number of rows contained in the table.
Definition: colors.h:61
wxWindow * CreateWindow(wxWindow *aParent, int aClassId, KIWAY *aKiway, int aCtlBits=0) override
Function CreateWindow creates a wxWindow for the current project.
Definition: eeschema.cpp:67
void * IfaceOrAddress(int aDataId) override
Function IfaceOrAddress return a pointer to the requested object.
Definition: eeschema.cpp:122
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
void InvokeSchEditSymbolLibTable(KIWAY *aKiway, wxWindow *aParent)
void CopyFile(const wxString &aSrcPath, const wxString &aDestPath, wxString &aErrors)
Function CopyFile.
Definition: gestfich.cpp:358
IFACE(const char *aName, KIWAY::FACE_T aType)
Definition: eeschema.cpp:59
Schematic editor (Eeschema) main window.
COLOR4D GetLayerColor(SCH_LAYER_ID aLayer)
Definition: eeschema.cpp:167
Symbol library viewer main window.
Definition: viewlib_frame.h:42
int PGM_BASE * aProgram
Definition: eeschema.cpp:152
#define CLR(x, y, z)
const wxString GetFullURI(bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:48
Class for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
static bool LoadGlobalTable(SYMBOL_LIB_TABLE &aTable)
Load the global symbol library table into aTable.
#define KICAD_SCH_PORT_SERVICE_NUMBER
Definition: eda_dde.h:42
bool OnKifaceStart(PGM_BASE *aProgram, int aCtlBits) override
Function OnKifaceStart is called just once shortly after the DSO is loaded.
Definition: eeschema.cpp:241
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:47
bool IsSingle() const
Function IsSingle is this KIFACE_I running under single_top?
Definition: kiface_i.h:115
static COLOR4D s_layerColor[LAYER_ID_COUNT]
Definition: eeschema.cpp:165
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
Definition: eeschema.cpp:53
KIFACE * KIFACE_GETTER(int *aKIFACEversion, int aKIWAYversion, PGM_BASE *aProgram)
No name mangling. Each KIFACE (DSO/DLL) will implement this once.
void end_common()
Common things to do for a top program module, during OnKifaceEnd();.
Definition: kiface_i.cpp:100
void SaveFileAs(const wxString &aProjectBasePath, const wxString &aProjectName, const wxString &aNewProjectBasePath, const wxString &aNewProjectName, const wxString &aSrcFilePath, wxString &aErrors) override
Function SaveFileAs Saving a file under a different name is delegated to the various KIFACEs because ...
Definition: eeschema.cpp:312
Class LIB_PIN definition.
static PARAM_CFG_ARRAY & cfg_params()
Definition: eeschema.cpp:187
Definition: colors.h:59
Class KIWAY is a minimalistic software bus for communications between various DLLs/DSOs (DSOs) within...
Definition: kiway.h:274
Subclass of SIM_PLOT_FRAME_BASE, which is generated by wxFormBuilder.
Definition: colors.h:60
SCH_LAYER_ID
Eeschema drawing layers.
void Load(const wxString &aFileName)
Load the library table using the path defined by aFileName aFallBackTable.
#define _(s)
#define LAYER_ID_COUNT
Must update this if you add any enums after GerbView!
Implementing SIM_PLOT_FRAME_BASE.
FACE_T
Known KIFACE implementations.
Definition: kiway.h:280
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:209
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Definition: macros.h:108
eeschema DSO
Definition: kiway.h:282
void wxConfigSaveSetups(wxConfigBase *aCfg, const PARAM_CFG_ARRAY &aList)
Function wxConfigSaveSetups writes aList of PARAM_CFG_ARRAY elements to save configuration values to ...
The symbol library editor main window.
void SetFullURI(const wxString &aFullURI)
Change the full URI for the library.
Definition: colors.h:58
see class PGM_BASE
TRANSFORM DefaultTransform
Definition: eeschema.cpp:50
LIB_TABLE_ROW & At(unsigned aIndex)
Get the 'n'th LIB_TABLE_ROW object.
MY_API(KIFACE *) KIFACE_GETTER(int *aKIFACEversion
COLOR4D & Darken(double aFactor)
Function Darken Makes the color darker by a given factor.
Definition: color4d.h:163
size_t i
Definition: json11.cpp:649
Class KIFACE is used by a participant in the KIWAY alchemy.
Definition: kiway.h:151
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
static PGM_BASE * process
Definition: eeschema.cpp:143
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: eeschema.cpp:146
Definition: colors.h:49
void CreateServer(int service, bool local=true)
Definition: eda_dde.cpp:49
Definition: colors.h:45
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: eeschema.cpp:158
void wxConfigLoadSetups(wxConfigBase *aCfg, const PARAM_CFG_ARRAY &aList)
Function wxConfigLoadSetups uses aList of PARAM_CFG_ARRAY elements to load configuration values from ...
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:76
static wxString GetGlobalTableFileName()
Fetch the global symbol library table file name.
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
Definition: colors.h:62