Commit 8d4a9b51 authored by dickelbeck's avatar dickelbeck

gerbview polygon erasures added, comment tweaks

parent 0d790e57
...@@ -13,8 +13,10 @@ email address. ...@@ -13,8 +13,10 @@ email address.
polygon code to use wxPoints since that is what the underlying wxWidgets polygon code to use wxPoints since that is what the underlying wxWidgets
API uses. API uses.
++gerbview ++gerbview
More work on drawing polygons, erasure still work in progress. Will * More work on drawing polygons, erasure of polygons completed.
probably switch to ZONEs from SEG_ZONEs for polygons. * Added full support for aperture macro 6, MOIRE.
* Example 2 in RS274xrevd_e.pdf almost draws properly now. Need ARC support
in polygons, and need polygon aperture type support to complete.
2008-Dec-28 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> 2008-Dec-28 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
......
...@@ -38,6 +38,10 @@ asked by: Dick Hollenbeck ...@@ -38,6 +38,10 @@ asked by: Dick Hollenbeck
4) Expose layer name editing in pcbnew (anyone), should dove tail with net 4) Expose layer name editing in pcbnew (anyone), should dove tail with net
class editor from a UI perspective. class editor from a UI perspective.
** Should probably switch gerbview to use ZONE instead of SEGZONE for polygons.
** Need to add ARC support to gerber polygons.
** Need to add polygon aperture type. Then example 2 in RS274xrevd_e.pdf will draw properly.
2008-Feb-8 Assigned To: dick 2008-Feb-8 Assigned To: dick
asked by: dick asked by: dick
......
...@@ -311,8 +311,7 @@ void BASE_SCREEN::AddGrid( const GRID_TYPE& grid ) ...@@ -311,8 +311,7 @@ void BASE_SCREEN::AddGrid( const GRID_TYPE& grid )
} }
} }
wxLogDebug( wxT( "Adding grid ID %d size( %d, %d ) to grid list." ), // wxLogDebug( wxT( "Adding grid ID %d size( %d, %d ) to grid list." ), grid.m_Id, grid.m_Size.x, grid.m_Size.y );
grid.m_Id, grid.m_Size.x, grid.m_Size.y );
m_GridList.Add( grid ); m_GridList.Add( grid );
} }
......
...@@ -108,8 +108,9 @@ class D_CODE; ...@@ -108,8 +108,9 @@ class D_CODE;
/** /**
* Class DCODE_PARAM * Class DCODE_PARAM
* holds a parameter for a DCODE or an "aperture macro" as defined within standard RS274X. * holds a parameter for a DCODE or an "aperture macro" as defined within standard RS274X.
* The \a value field can be either a constant or a place holder for a DCODE * The \a value field can be a constant, i.e. "immediate" parameter or it may not be used
* parameter. * if this param is going to defer to the referencing aperture macro. In that case, the
* \a index field is an index into the aperture macro's paramters.
*/ */
class DCODE_PARAM class DCODE_PARAM
{ {
...@@ -145,7 +146,7 @@ public: ...@@ -145,7 +146,7 @@ public:
private: private:
int index; ///< if -1, then \a value field is an immediate value, else this is an index into parent's D_CODE.m_am_params. int index; ///< if -1, then \a value field is an immediate value, else this is an index into parent's D_CODE.m_am_params.
double value; ///< if IsImmediate()==true then the value, else not used. double value; ///< if IsImmediate()==true then use the value, else not used.
}; };
...@@ -378,8 +379,8 @@ public: ...@@ -378,8 +379,8 @@ public:
char*& text, int D_commande ); char*& text, int D_commande );
/** /**
* size of single line of a text line from a gerber file. * size of single line of a text from a gerber file.
* warning: some files can have very long lines, so the buffer must be large * warning: some files can have very long lines, so the buffer must be large.
*/ */
#define GERBER_BUFZ 4000 #define GERBER_BUFZ 4000
......
...@@ -238,43 +238,31 @@ static void fillLineTRACK( TRACK* aTrack, int Dcode_index, int aLayer, ...@@ -238,43 +238,31 @@ static void fillLineTRACK( TRACK* aTrack, int Dcode_index, int aLayer,
} }
#if 0 // @todo get it into the doxygen function comment for fillArcTRACK below
/*****************************************************************/
static void Append_1_SEG_ARC_GERBER( int Dcode_index,
WinEDA_GerberFrame* frame, wxDC* DC,
const wxPoint& startpoint, const wxPoint& endpoint,
const wxPoint& rel_center, int largeur,
bool trigo_sens, bool multiquadrant, bool isDark )
/*****************************************************************/
/*
* Creates an arc:
* if multiquadrant == true : arc can be 0 to 360 degres
* and rel_center is the center coordiante relative to startpoint.
*
* if multiquadrant == false arc can be only 0 to 90 deg,
* and only in the same quadrant :
* absolute angle 0 to 90 (quadrant 1) or
* absolute angle 90 to 180 (quadrant 2) or
* absolute angle 180 to 270 (quadrant 3) or
* absolute angle 270 to 0 (quadrant 4)
* rel_center is the center coordiante relative to startpoint,
* given in ABSOLUE VALUE and the signe of values x et y de rel_center
* must be calculated from the previously given constraint: arc only in the same quadrant
*/
#endif
/** /**
* Function fillArcTRACK * Function fillArcTRACK
* initializes a given TRACK so that it can draw an arc G code. * initializes a given TRACK so that it can draw an arc G code.
* * <p>
* @param aTrack The TRACK to fill in. * if multiquadrant == true : arc can be 0 to 360 degres
* @param Dcode_index The DCODE value, like D14 * and \a rel_center is the center coordiante relative to startpoint.
* @param aLayer The layer index to set into the TRACK * <p>
* @param aPos The center point of the flash * if multiquadrant == false arc can be only 0 to 90 deg,
* and only in the same quadrant :
* <ul>
* <li> absolute angle 0 to 90 (quadrant 1) or
* <li> absolute angle 90 to 180 (quadrant 2) or
* <li> absolute angle 180 to 270 (quadrant 3) or
* <li> absolute angle 270 to 0 (quadrant 4)
* </ul><p>
* @param aTrack is the TRACK to fill in.
* @param Dcode_index is the DCODE value, like D14
* @param aLayer is the layer index to set into the TRACK
* @param aStart is the starting point
* @param aEnd is the ending point
* @param rel_center is the center coordiante relative to startpoint,
* given in ABSOLUE VALUE and the signe of values x et y de rel_center
* must be calculated from the previously given constraint: arc only in the same quadrant.
* @param aDiameter The diameter of the round flash * @param aDiameter The diameter of the round flash
* @param aWidth is the pen width.
* @param isDark True if flash is positive and should use a drawing * @param isDark True if flash is positive and should use a drawing
* color other than the background color, else use the background color * color other than the background color, else use the background color
* when drawing so that an erasure happens. * when drawing so that an erasure happens.
...@@ -682,8 +670,9 @@ int GERBER::ReturnDCodeNumber( char*& Text ) ...@@ -682,8 +670,9 @@ int GERBER::ReturnDCodeNumber( char*& Text )
/******************************************************************/ /******************************************************************/
bool GERBER::Execute_G_Command( char*& text, int G_commande ) bool GERBER::Execute_G_Command( char*& text, int G_commande )
/******************************************************************/ /******************************************************************/
{ {
D(printf( "%22s: G_CODE<%d>\n", __func__, G_commande );)
switch( G_commande ) switch( G_commande )
{ {
case GC_PHOTO_MODE: // can starts a D03 flash command: redundant, can be safely ignored case GC_PHOTO_MODE: // can starts a D03 flash command: redundant, can be safely ignored
...@@ -858,6 +847,8 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC, ...@@ -858,6 +847,8 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC,
D_CODE* tool = NULL; D_CODE* tool = NULL;
wxString msg; wxString msg;
D(printf( "%22s: D_CODE<%d>\n", __func__, D_commande );)
if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command
{ {
if( D_commande > (MAX_TOOLS - 1) ) if( D_commande > (MAX_TOOLS - 1) )
...@@ -890,15 +881,15 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC, ...@@ -890,15 +881,15 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC,
edge_poly->SetLayer( activeLayer ); edge_poly->SetLayer( activeLayer );
edge_poly->m_Width = 1; edge_poly->m_Width = 1;
edge_poly->m_Start = m_PreviousPos; edge_poly->m_Start = m_PreviousPos;
NEGATE( edge_poly->m_Start.y ); NEGATE( edge_poly->m_Start.y );
edge_poly->m_End = m_CurrentPos; edge_poly->m_End = m_CurrentPos;
NEGATE( edge_poly->m_End.y ); NEGATE( edge_poly->m_End.y );
edge_poly->SetNet( m_PolygonFillModeState ); edge_poly->SetNet( m_PolygonFillModeState );
// the first track of each polygon has a netcode of zero, otherwise one. // the first track of each polygon has a netcode of zero, otherwise one.
// set the erasure flag in that special track, if a negative polygon. // set the erasure flag in that special track, if a negative polygon.
if( !m_PolygonFillModeState ) if( !m_PolygonFillModeState )
...@@ -907,7 +898,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC, ...@@ -907,7 +898,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC,
edge_poly->m_Flags |= DRAW_ERASED; edge_poly->m_Flags |= DRAW_ERASED;
D(printf("\nm_Flags=0x%08X\n", edge_poly->m_Flags );) D(printf("\nm_Flags=0x%08X\n", edge_poly->m_Flags );)
} }
m_PreviousPos = m_CurrentPos; m_PreviousPos = m_CurrentPos;
m_PolygonFillModeState = 1; m_PolygonFillModeState = 1;
break; break;
......
...@@ -47,7 +47,7 @@ enum RS274X_PARAMETERS ...@@ -47,7 +47,7 @@ enum RS274X_PARAMETERS
/** /**
* Function ReadXCommand * Function ReadXCommand
* reads int two bytes of data and assembles them into an int with the first * reads in two bytes of data and assembles them into an int with the first
* byte in the sequence put into the most significant part of a 16 bit value * byte in the sequence put into the most significant part of a 16 bit value
* and the second byte put into the least significant part of the 16 bit value. * and the second byte put into the least significant part of the 16 bit value.
* @param text A reference to a pointer to read bytes from and to advance as they are read. * @param text A reference to a pointer to read bytes from and to advance as they are read.
...@@ -177,7 +177,7 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t ...@@ -177,7 +177,7 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
double fcoord; double fcoord;
double conv_scale = m_GerbMetric ? PCB_INTERNAL_UNIT / 25.4 : PCB_INTERNAL_UNIT; double conv_scale = m_GerbMetric ? PCB_INTERNAL_UNIT / 25.4 : PCB_INTERNAL_UNIT;
//D(printf( "%s: Command <%c%c>\n", __func__, (command >> 8) & 0xFF, command & 0xFF );) D(printf( "%22s: Command <%c%c>\n", __func__, (command >> 8) & 0xFF, command & 0xFF );)
switch( command ) switch( command )
{ {
...@@ -311,28 +311,18 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t ...@@ -311,28 +311,18 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
case IMAGE_POLARITY: case IMAGE_POLARITY:
if( strnicmp( text, "NEG", 3 ) == 0 ) if( strnicmp( text, "NEG", 3 ) == 0 )
{ m_ImageNegative = true;
D(printf("%s: m_ImageNegative=true\n", __func__);)
m_ImageNegative = TRUE;
}
else else
{ m_ImageNegative = false;
D(printf("%s: m_ImageNegative=false\n", __func__);) D(printf("%22s: IMAGE_POLARITY m_ImageNegative=%s\n", __func__, m_ImageNegative ? "true" : "false");)
m_ImageNegative = FALSE;
}
break; break;
case LAYER_POLARITY: case LAYER_POLARITY:
if( *text == 'C' ) if( *text == 'C' )
{ m_LayerNegative = true;
D(printf("%s: m_LayerNegative=true\n", __func__);)
m_LayerNegative = TRUE;
}
else else
{ m_LayerNegative = false;
D(printf("%s: m_LayerNegative=false\n", __func__);) D(printf("%22s: LAYER_POLARITY m_LayerNegative=%s\n", __func__, m_LayerNegative ? "true" : "false");)
m_LayerNegative = FALSE;
}
break; break;
case INCLUDE_FILE: case INCLUDE_FILE:
...@@ -366,7 +356,6 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t ...@@ -366,7 +356,6 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
break; break;
case AP_DEFINITION: case AP_DEFINITION:
// input example: %ADD30R,0.081800X0.101500*% // input example: %ADD30R,0.081800X0.101500*%
// at this point, text points to 2nd 'D' // at this point, text points to 2nd 'D'
...@@ -501,9 +490,6 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t ...@@ -501,9 +490,6 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
} }
dcode->m_Shape = APT_MACRO; dcode->m_Shape = APT_MACRO;
D(printf("pam has %d parameters\n", pam->primitives.size() );)
dcode->SetMacro( (APERTURE_MACRO*) pam ); dcode->SetMacro( (APERTURE_MACRO*) pam );
} }
break; break;
......
...@@ -28,37 +28,37 @@ void WinEDA_DrawPanel::PrintPage( wxDC* DC, bool Print_Sheet_Ref, int printmaskl ...@@ -28,37 +28,37 @@ void WinEDA_DrawPanel::PrintPage( wxDC* DC, bool Print_Sheet_Ref, int printmaskl
/* Draw gerbview layers, for printing /* Draw gerbview layers, for printing
*/ */
{ {
DISPLAY_OPTIONS save_opt; DISPLAY_OPTIONS save_opt;
int DisplayPolygonsModeImg; int DisplayPolygonsModeImg;
save_opt = DisplayOpt; save_opt = DisplayOpt;
if( printmasklayer & ALL_CU_LAYERS ) if( printmasklayer & ALL_CU_LAYERS )
DisplayOpt.DisplayPadFill = FILLED; DisplayOpt.DisplayPadFill = FILLED;
else else
DisplayOpt.DisplayPadFill = SKETCH; DisplayOpt.DisplayPadFill = SKETCH;
DisplayOpt.DisplayPadNum = 0; DisplayOpt.DisplayPadNum = 0;
DisplayOpt.DisplayPadNoConn = 0; DisplayOpt.DisplayPadNoConn = 0;
DisplayOpt.DisplayPadIsol = 0; DisplayOpt.DisplayPadIsol = 0;
DisplayOpt.DisplayModEdge = FILLED; DisplayOpt.DisplayModEdge = FILLED;
DisplayOpt.DisplayModText = FILLED; DisplayOpt.DisplayModText = FILLED;
DisplayOpt.DisplayPcbTrackFill = FILLED; DisplayOpt.DisplayPcbTrackFill = FILLED;
DisplayOpt.DisplayTrackIsol = 0; DisplayOpt.DisplayTrackIsol = 0;
DisplayOpt.DisplayDrawItems = FILLED; DisplayOpt.DisplayDrawItems = FILLED;
DisplayOpt.DisplayZonesMode = 0; DisplayOpt.DisplayZonesMode = 0;
DisplayPolygonsModeImg = g_DisplayPolygonsModeSketch; DisplayPolygonsModeImg = g_DisplayPolygonsModeSketch;
g_DisplayPolygonsModeSketch = 0; g_DisplayPolygonsModeSketch = 0;
m_PrintIsMirrored = aPrintMirrorMode; m_PrintIsMirrored = aPrintMirrorMode;
( (WinEDA_GerberFrame*) m_Parent )->Trace_Gerber( DC, GR_COPY, printmasklayer ); ( (WinEDA_GerberFrame*) m_Parent )->Trace_Gerber( DC, GR_COPY, printmasklayer );
if( Print_Sheet_Ref ) if( Print_Sheet_Ref )
m_Parent->TraceWorkSheet( DC, GetScreen(), 0 ); m_Parent->TraceWorkSheet( DC, GetScreen(), 0 );
m_PrintIsMirrored = false; m_PrintIsMirrored = false;
DisplayOpt = save_opt; DisplayOpt = save_opt;
g_DisplayPolygonsModeSketch = DisplayPolygonsModeImg; g_DisplayPolygonsModeSketch = DisplayPolygonsModeImg;
} }
...@@ -69,31 +69,31 @@ void WinEDA_GerberFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg ) ...@@ -69,31 +69,31 @@ void WinEDA_GerberFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg )
/* Trace le PCB, et les elements complementaires ( axes, grille .. ) /* Trace le PCB, et les elements complementaires ( axes, grille .. )
*/ */
{ {
PCB_SCREEN* screen = (PCB_SCREEN*)GetScreen(); PCB_SCREEN* screen = (PCB_SCREEN*)GetScreen();
if( !m_Pcb ) if( !m_Pcb )
return; return;
ActiveScreen = screen; ActiveScreen = screen;
GRSetDrawMode( DC, GR_COPY ); GRSetDrawMode( DC, GR_COPY );
if( EraseBg ) if( EraseBg )
DrawPanel->EraseScreen( DC ); DrawPanel->EraseScreen( DC );
DrawPanel->DrawBackGround( DC ); DrawPanel->DrawBackGround( DC );
Trace_Gerber( DC, GR_COPY, -1 ); Trace_Gerber( DC, GR_COPY, -1 );
TraceWorkSheet( DC, screen, 0 ); TraceWorkSheet( DC, screen, 0 );
Affiche_Status_Box(); Affiche_Status_Box();
if( DrawPanel->ManageCurseur ) if( DrawPanel->ManageCurseur )
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE ); DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
DrawPanel->Trace_Curseur( DC ); DrawPanel->Trace_Curseur( DC );
} }
/********************************************************************/ /********************************************************************/
void BOARD::Draw( WinEDA_DrawPanel* aPanel, wxDC* DC, void BOARD::Draw( WinEDA_DrawPanel* aPanel, wxDC* DC,
int aDrawMode, const wxPoint& offset ) int aDrawMode, const wxPoint& offset )
/********************************************************************/ /********************************************************************/
/* Redraw the BOARD items but not cursors, axis or grid */ /* Redraw the BOARD items but not cursors, axis or grid */
// @todo: replace WinEDA_GerberFrame::Trace_Gerber() by this function // @todo: replace WinEDA_GerberFrame::Trace_Gerber() by this function
...@@ -110,72 +110,77 @@ void WinEDA_GerberFrame::Trace_Gerber( wxDC* DC, int draw_mode, int printmasklay ...@@ -110,72 +110,77 @@ void WinEDA_GerberFrame::Trace_Gerber( wxDC* DC, int draw_mode, int printmasklay
* @param printmasklayer = mask for allowed layer (=-1 to draw all layers) * @param printmasklayer = mask for allowed layer (=-1 to draw all layers)
*/ */
{ {
if( !m_Pcb ) if( !m_Pcb )
return; return;
bool erase; bool erase;
int Color;
// Draw filled polygons bool filled;
std::vector<wxPoint> coords;
// Draw filled polygons
std::vector<wxPoint> points;
// minimize reallocations of the vector's internal array by starting with a good sized one. // minimize reallocations of the vector's internal array by starting with a good sized one.
coords.reserve(20000); points.reserve(10000);
for( TRACK* track = m_Pcb->m_Zone; track; track = track->Next() ) for( TRACK* track = m_Pcb->m_Zone; track; track = track->Next() )
{ {
if( !(track->ReturnMaskLayer() & printmasklayer) ) if( !(track->ReturnMaskLayer() & printmasklayer) )
continue; continue;
if( track->GetNet() == 0 ) // StartPoint if( track->GetNet() == 0 ) // StartPoint
{ {
if( coords.size() ) // we have found a new polygon: Draw the old polygon if( points.size() ) // we have found a new polygon: Draw the old polygon
{ {
int Color;
int filled;
if( erase ) if( erase )
{ {
D(printf("erase\n");)
Color = g_DrawBgColor; Color = g_DrawBgColor;
filled = true; filled = true;
} }
else else
{ {
D(printf("NO erase\n");)
Color = g_DesignSettings.m_LayerColor[track->GetLayer()]; Color = g_DesignSettings.m_LayerColor[track->GetLayer()];
filled = (g_DisplayPolygonsModeSketch == 0) ? 1 : 0; filled = (g_DisplayPolygonsModeSketch == 0);
} }
GRClosedPoly( &DrawPanel->m_ClipBox, DC, coords.size(), &coords[0], GRClosedPoly( &DrawPanel->m_ClipBox, DC, points.size(), &points[0],
filled, Color, Color ); filled, Color, Color );
} }
erase = ( track->m_Flags & DRAW_ERASED ) ? true : false; erase = ( track->m_Flags & DRAW_ERASED );
coords.clear(); points.clear();
coords.push_back( track->m_Start ); points.push_back( track->m_Start );
coords.push_back( track->m_End ); points.push_back( track->m_End );
} }
else else
{ {
coords.push_back( track->m_End ); points.push_back( track->m_End );
} }
if( track->Next() == NULL ) // Last point if( track->Next() == NULL ) // Last point
{ {
int Color = g_DesignSettings.m_LayerColor[track->GetLayer()]; if( erase )
int filled = (g_DisplayPolygonsModeSketch == 0) ? 1 : 0; {
Color = g_DrawBgColor;
GRClosedPoly( &DrawPanel->m_ClipBox, DC, coords.size(), &coords[0], filled = true;
filled, Color, Color ); }
} else
} {
Color = g_DesignSettings.m_LayerColor[track->GetLayer()];
// Draw tracks and flashes down here. This will probably not be a final solution to drawing order issues filled = (g_DisplayPolygonsModeSketch == 0);
Draw_Track_Buffer( DrawPanel, DC, m_Pcb, draw_mode, printmasklayer ); }
if( DisplayOpt.DisplayPadNum ) GRClosedPoly( &DrawPanel->m_ClipBox, DC, points.size(), &points[0],
Affiche_DCodes_Pistes( DrawPanel, DC, m_Pcb, GR_COPY ); filled, Color, Color );
}
GetScreen()->ClrRefreshReq(); }
// Draw tracks and flashes down here. This will probably not be a final solution to drawing order issues
Draw_Track_Buffer( DrawPanel, DC, m_Pcb, draw_mode, printmasklayer );
if( DisplayOpt.DisplayPadNum )
Affiche_DCodes_Pistes( DrawPanel, DC, m_Pcb, GR_COPY );
GetScreen()->ClrRefreshReq();
} }
...@@ -140,7 +140,7 @@ void GRClosedPoly(EDA_Rect * ClipBox, wxDC* aDC, int aPointCount, wxPoint aPoint ...@@ -140,7 +140,7 @@ void GRClosedPoly(EDA_Rect * ClipBox, wxDC* aDC, int aPointCount, wxPoint aPoint
* @param aDC the device context into which drawing should occur. * @param aDC the device context into which drawing should occur.
* @param x The x coordinate in user space of the center of the circle. * @param x The x coordinate in user space of the center of the circle.
* @param x The y coordinate in user space of the center of the circle. * @param x The y coordinate in user space of the center of the circle.
* @param aRadius is the radis of the circle. * @param aRadius is the radius of the circle.
* @param aColor is an index into our color table of RGB colors. * @param aColor is an index into our color table of RGB colors.
* @see EDA_Colors and colors.h * @see EDA_Colors and colors.h
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment