2011-09-23 13:57:12 +00:00
|
|
|
|
/**
|
|
|
|
|
* @file gpcb_exchange.cpp
|
|
|
|
|
* @brief Import functions to import footprints from a gpcb (Newlib) library.
|
|
|
|
|
*/
|
2008-03-10 08:14:20 +00:00
|
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
|
#include <fctsys.h>
|
|
|
|
|
#include <wxstruct.h>
|
|
|
|
|
#include <kicad_string.h>
|
|
|
|
|
#include <trigo.h>
|
|
|
|
|
#include <richio.h>
|
|
|
|
|
#include <filter_reader.h>
|
|
|
|
|
#include <macros.h>
|
|
|
|
|
|
|
|
|
|
#include <class_pad.h>
|
|
|
|
|
#include <class_module.h>
|
|
|
|
|
#include <class_edge_mod.h>
|
|
|
|
|
|
|
|
|
|
#include <pcbnew.h>
|
2011-09-23 13:57:12 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
|
|
|
|
|
/* read parameters from a line, and return all params in a wxArrayString
|
|
|
|
|
* each param is in one wxString, and double quotes removed if exists
|
|
|
|
|
*/
|
|
|
|
|
static void Extract_Parameters( wxArrayString& param_list, char* text );
|
|
|
|
|
static bool TestFlags( const wxString& flg_string, long flg_mask, const wxChar* flg_name );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Function Read_GPCB_Descr
|
|
|
|
|
* Read a footprint description in GPCB (Newlib) format
|
|
|
|
|
* @param CmpFullFileName = Full file name (there is one footprint per file.
|
|
|
|
|
* this is also the footprint name
|
|
|
|
|
* @return bool - true if success reading else false.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* a sample is
|
|
|
|
|
*
|
|
|
|
|
* Element["" "" "" "" 29000 44000 0 0 0 100 ""]
|
|
|
|
|
* (
|
|
|
|
|
* Pad[-5000 0 -4000 0 4999 0 4999 "" "1" "square"]
|
|
|
|
|
* Pad[4000 0 5000 0 4999 0 4999 "" "2" "square,edge2"]
|
|
|
|
|
* ElementLine [8000 3000 1000 3000 199]
|
|
|
|
|
* ElementLine [8000 -3000 8000 3000 199]
|
|
|
|
|
* ElementLine [-8000 3000 -1000 3000 199]
|
|
|
|
|
* ElementLine [-8000 -3000 -1000 -3000 199]
|
|
|
|
|
* ElementLine [8000 -3000 1000 -3000 199]
|
|
|
|
|
* ElementLine [-8000 -3000 -8000 3000 199]
|
|
|
|
|
* )
|
|
|
|
|
*
|
|
|
|
|
* Format
|
|
|
|
|
* Element [SFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TSFlags]
|
|
|
|
|
* Element (NFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TNFlags)
|
|
|
|
|
* Element (NFlags "Desc" "Name" "Value" TX TY TDir TScale TNFlags)
|
|
|
|
|
* Element (NFlags "Desc" "Name" TX TY TDir TScale TNFlags)
|
|
|
|
|
* Element ("Desc" "Name" TX TY TDir TScale TNFlags)
|
|
|
|
|
* (
|
|
|
|
|
* . . . contents . . . *
|
|
|
|
|
* )
|
|
|
|
|
* With:
|
|
|
|
|
* SFlags Symbolic or numeric flags, for the element as a whole.
|
|
|
|
|
* NFlags Numeric flags, for the element as a whole.
|
|
|
|
|
* Desc The description of the element. This is one of the three strings which can be
|
|
|
|
|
* displayed on the screen.
|
|
|
|
|
* Name The name of the element, usually the reference designator.
|
|
|
|
|
* Value The value of the element.
|
2010-11-27 13:09:18 +00:00
|
|
|
|
* MX MY The location of the element<EFBFBD>s mark. This is the reference point for placing the element and its pins and pads.
|
2008-03-10 08:14:20 +00:00
|
|
|
|
* TX TY The upper left corner of the text (one of the three strings).
|
|
|
|
|
* TDir The relative direction of the text. 0 means left to right for an unrotated element, 1 means up, 2 left, 3 down.
|
2010-11-27 13:09:18 +00:00
|
|
|
|
* TScale Size of the text, as a percentage of the <EFBFBD>default<EFBFBD> size of of the font (the default font is about 40 mils high). Default is 100 (40 mils).
|
2008-03-10 08:14:20 +00:00
|
|
|
|
* TSFlags Symbolic or numeric flags, for the text.
|
|
|
|
|
* TNFlags Numeric flags, for the text.
|
|
|
|
|
*
|
|
|
|
|
* Elements may contain pins, pads, element
|
|
|
|
|
*
|
|
|
|
|
* ElementLine [X1 Y1 X2 Y2 Thickness]
|
|
|
|
|
* ElementLine (X1 Y1 X2 Y2 Thickness)
|
|
|
|
|
*
|
|
|
|
|
* ElementArc [X Y Width Height StartAngle DeltaAngle Thickness]
|
|
|
|
|
* ElementArc (X Y Width Height StartAngle DeltaAngle Thickness)
|
|
|
|
|
* (rotation in clockwise)
|
2011-12-03 14:04:17 +00:00
|
|
|
|
* ( Note: Pad is a SMD Pad in Pcbnew, and Pin is a through hole Pad in Pcbnew )
|
2008-03-10 08:14:20 +00:00
|
|
|
|
* Pad [rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" SFlags]
|
|
|
|
|
* Pad (rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" NFlags)
|
|
|
|
|
* Pad (aX1 aY1 aX2 aY2 Thickness "Name" "Number" NFlags)
|
|
|
|
|
* Pad (aX1 aY1 aX2 aY2 Thickness "Name" NFlags)
|
|
|
|
|
*
|
|
|
|
|
* Pin [rX rY Thickness Clearance Mask Drill "Name" "Number" SFlags]
|
|
|
|
|
* Pin (rX rY Thickness Clearance Mask Drill "Name" "Number" NFlags)
|
|
|
|
|
* Pin (aX aY Thickness Drill "Name" "Number" NFlags)
|
|
|
|
|
* Pin (aX aY Thickness Drill "Name" NFlags)
|
|
|
|
|
* Pin (aX aY Thickness "Name" NFlags)
|
|
|
|
|
*
|
|
|
|
|
* Object Flags :
|
|
|
|
|
*
|
|
|
|
|
* Note that object flags can be given numerically (like 0x0147) or symbolically (like
|
|
|
|
|
* "found,showname,square". Some numeric values are reused for different object types.
|
|
|
|
|
* The table below lists the numeric value followed by the symbolic name.
|
|
|
|
|
* 0x0001 pin
|
|
|
|
|
* If set, this object is a pin. This flag is for internal use only.
|
|
|
|
|
* 0x0002 via
|
|
|
|
|
* Likewise, for vias.
|
|
|
|
|
* 0x0004 found
|
|
|
|
|
* If set, this object has been found by FindConnection().
|
|
|
|
|
* 0x0008 hole
|
|
|
|
|
* For pins and vias, this flag means that the pin or via is a hole without a copper
|
|
|
|
|
* annulus.
|
|
|
|
|
* 0x0010 rat
|
|
|
|
|
* If set for a line, indicates that this line is a rat line instead of a copper trace.
|
|
|
|
|
* 0x0010 pininpoly
|
|
|
|
|
* For pins and pads, this flag is used internally to indicate that the pin or pad
|
|
|
|
|
* overlaps a polygon on some layer.
|
|
|
|
|
* 0x0010 clearpoly
|
|
|
|
|
* For polygons, this flag means that pins and vias will normally clear these polygons
|
|
|
|
|
* (thus, thermals are required for electrical connection). When clear, polygons
|
|
|
|
|
* will solidly connect to pins and vias.
|
|
|
|
|
* 0x0010 hidename
|
|
|
|
|
* For elements, when set the name of the element is hidden.
|
|
|
|
|
* 0x0020 showname
|
|
|
|
|
* For elements, when set the names of pins are shown.
|
|
|
|
|
* 0x0020 clearline
|
|
|
|
|
* For lines and arcs, the line/arc will clear polygons instead of connecting to
|
|
|
|
|
* them.
|
|
|
|
|
* 0x0020 fullpoly
|
|
|
|
|
* For polygons, the full polygon is drawn (i.e. all parts instead of only the biggest
|
|
|
|
|
* one).
|
|
|
|
|
* 0x0040 selected
|
|
|
|
|
* Set when the object is selected.
|
|
|
|
|
* 0x0080 onsolder
|
|
|
|
|
* For elements and pads, indicates that they are on the solder side
|
|
|
|
|
* 0x0080 auto
|
|
|
|
|
* For lines and vias, indicates that these were created by the autorouter.
|
|
|
|
|
* 0x0100 square
|
|
|
|
|
* For pins and pads, indicates a square (vs round) pin/pad.
|
|
|
|
|
* 0x0200 rubberend
|
|
|
|
|
* For lines, used internally for rubber band moves.
|
|
|
|
|
* 0x0200 warn
|
|
|
|
|
* For pins, vias, and pads, set to indicate a warning.
|
|
|
|
|
* 0x0400 usetherm
|
|
|
|
|
* Obsolete, indicates that pins/vias should be drawn with thermal fingers.
|
|
|
|
|
* 0x0400 Obsolete, old files used this to indicate lines drawn on silk.
|
|
|
|
|
* 0x0800 octagon
|
|
|
|
|
* Draw pins and vias as octagons.
|
|
|
|
|
* 0x1000 drc
|
|
|
|
|
* Set for objects that fail DRC.
|
|
|
|
|
* 0x2000 lock
|
|
|
|
|
* Set for locked objects.
|
|
|
|
|
* 0x4000 edge2
|
|
|
|
|
* For pads, indicates that the second point is closer to the edge. For pins, indicates
|
|
|
|
|
* that the pin is closer to a horizontal edge and thus pinout text should be vertical.
|
|
|
|
|
* 0x8000 marker
|
|
|
|
|
* Marker used internally to avoid revisiting an object.
|
|
|
|
|
* 0x10000 nopaste
|
|
|
|
|
* For pads, set to prevent a solderpaste stencil opening for the pad. Primarily
|
|
|
|
|
* used for pads used as fiducials.
|
|
|
|
|
*/
|
2011-09-07 19:41:04 +00:00
|
|
|
|
bool MODULE::Read_GPCB_Descr( const wxString& CmpFullFileName )
|
2008-03-10 08:14:20 +00:00
|
|
|
|
{
|
|
|
|
|
#define TEXT_DEFAULT_SIZE 400
|
|
|
|
|
#define OLD_GPCB_UNIT_CONV 10
|
|
|
|
|
#define NEW_GPCB_UNIT_CONV 0.1
|
2011-12-14 04:29:25 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
FILE* cmpfile;
|
2011-09-30 18:15:37 +00:00
|
|
|
|
double conv_unit = NEW_GPCB_UNIT_CONV; // GPCB unit = 0.01 mils and Pcbnew 0.1
|
2011-12-14 04:29:25 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
// Old version unit = 1 mil, so conv_unit is 10 or 0.1
|
|
|
|
|
bool success = true;
|
2011-12-14 04:29:25 +00:00
|
|
|
|
char* line;
|
2008-03-10 08:14:20 +00:00
|
|
|
|
long ibuf[100];
|
2011-12-14 04:29:25 +00:00
|
|
|
|
EDGE_MODULE* drawSeg;
|
2012-02-19 04:02:19 +00:00
|
|
|
|
D_PAD* pad;
|
2008-03-10 08:14:20 +00:00
|
|
|
|
wxArrayString params;
|
|
|
|
|
int iprmcnt, icnt_max, iflgidx;
|
|
|
|
|
|
|
|
|
|
if( ( cmpfile = wxFopen( CmpFullFileName, wxT( "rt" ) ) ) == NULL )
|
|
|
|
|
return false;
|
|
|
|
|
|
2011-01-14 17:43:30 +00:00
|
|
|
|
FILE_LINE_READER fileReader( cmpfile, CmpFullFileName );
|
|
|
|
|
|
|
|
|
|
FILTER_READER reader( fileReader );
|
|
|
|
|
|
|
|
|
|
reader.ReadLine();
|
|
|
|
|
|
2011-12-14 04:29:25 +00:00
|
|
|
|
line = reader.Line();
|
2008-03-10 08:14:20 +00:00
|
|
|
|
|
|
|
|
|
params.Clear();
|
2011-12-14 04:29:25 +00:00
|
|
|
|
Extract_Parameters( params, line );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
|
|
|
|
|
iprmcnt = 0;
|
|
|
|
|
icnt_max = params.GetCount();
|
|
|
|
|
|
|
|
|
|
if( params[iprmcnt].CmpNoCase( wxT( "Element" ) ) != 0 )
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test symbol after "Element": if [ units = 0.01 mils, and if ( units = 1 mil
|
|
|
|
|
iprmcnt++;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
if( params[iprmcnt] == wxT( "(" ) )
|
|
|
|
|
conv_unit = OLD_GPCB_UNIT_CONV;
|
|
|
|
|
|
|
|
|
|
/* Analyse first line :
|
|
|
|
|
* Element [element_flags, description, pcb-name, value, mark_x, mark_y, text_x, text_y,
|
2011-09-07 19:41:04 +00:00
|
|
|
|
* text_direction, text_scale, text_flags]
|
2008-03-10 08:14:20 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// Read flags (unused)
|
|
|
|
|
iprmcnt++;
|
|
|
|
|
|
|
|
|
|
// Read description
|
|
|
|
|
iprmcnt++;
|
|
|
|
|
m_Doc = params[iprmcnt];
|
|
|
|
|
|
2008-03-12 11:49:16 +00:00
|
|
|
|
// Read pcb-name (reference )
|
2008-03-10 08:14:20 +00:00
|
|
|
|
iprmcnt++;
|
2008-03-12 11:49:16 +00:00
|
|
|
|
m_Reference->m_Text = params[iprmcnt];
|
2008-03-10 08:14:20 +00:00
|
|
|
|
|
|
|
|
|
// Read value
|
|
|
|
|
iprmcnt++;
|
|
|
|
|
m_Value->m_Text = params[iprmcnt];
|
|
|
|
|
|
|
|
|
|
// Read other infos
|
2011-12-09 16:17:38 +00:00
|
|
|
|
int idx = 2; // index of the first param of the ref text in ibuf
|
|
|
|
|
// can be 2 ( 0 and 1 = position of module (not handled by Pcbnew)
|
|
|
|
|
// or 0 if no module position
|
2008-03-12 11:49:16 +00:00
|
|
|
|
iprmcnt++;
|
2011-12-09 16:17:38 +00:00
|
|
|
|
for( int ii = 0; ii < 20; ii++ )
|
|
|
|
|
ibuf[ii] = 0;
|
2011-12-14 04:29:25 +00:00
|
|
|
|
|
2011-12-09 16:17:38 +00:00
|
|
|
|
for( int ii = 0; ii <= 8; ii++, iprmcnt++ ) // upt to 6 params + terminal char.
|
2008-03-10 08:14:20 +00:00
|
|
|
|
{
|
2011-12-09 16:17:38 +00:00
|
|
|
|
if( iprmcnt >= icnt_max )
|
2008-03-10 08:14:20 +00:00
|
|
|
|
{
|
|
|
|
|
success = false;
|
2011-12-09 16:17:38 +00:00
|
|
|
|
break;
|
2008-03-10 08:14:20 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2011-09-07 19:41:04 +00:00
|
|
|
|
{
|
2011-12-09 16:17:38 +00:00
|
|
|
|
if( params[iprmcnt] == wxT( ")" ) ||
|
|
|
|
|
params[iprmcnt] == wxT( "]" ) )
|
|
|
|
|
{ // Terminal character found
|
|
|
|
|
if( ii <= 5 ) // no module position
|
|
|
|
|
idx = 0;
|
|
|
|
|
break;
|
2011-12-14 04:29:25 +00:00
|
|
|
|
}
|
2008-03-10 08:14:20 +00:00
|
|
|
|
params[iprmcnt].ToLong( &ibuf[ii] );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
}
|
2008-03-10 08:14:20 +00:00
|
|
|
|
}
|
2011-12-09 16:17:38 +00:00
|
|
|
|
wxPoint pos;
|
// Dick Hollenbeck's KiROUND R&D
// This provides better project control over rounding to int from double
// than wxRound() did. This scheme provides better logging in Debug builds
// and it provides for compile time calculation of constants.
#include <stdio.h>
#include <assert.h>
#include <limits.h>
//-----<KiROUND KIT>------------------------------------------------------------
/**
* KiROUND
* rounds a floating point number to an int using
* "round halfway cases away from zero".
* In Debug build an assert fires if will not fit into an int.
*/
#if defined( DEBUG )
// DEBUG: a macro to capture line and file, then calls this inline
static inline int KiRound( double v, int line, const char* filename )
{
v = v < 0 ? v - 0.5 : v + 0.5;
if( v > INT_MAX + 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n", __FUNCTION__, filename, line, v );
}
else if( v < INT_MIN - 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n", __FUNCTION__, filename, line, v );
}
return int( v );
}
#define KiROUND( v ) KiRound( v, __LINE__, __FILE__ )
#else
// RELEASE: a macro so compile can pre-compute constants.
#define KiROUND( v ) int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 )
#endif
//-----</KiROUND KIT>-----------------------------------------------------------
// Only a macro is compile time calculated, an inline function causes a static constructor
// in a situation like this.
// Therefore the Release build is best done with a MACRO not an inline function.
int Computed = KiROUND( 14.3 * 8 );
int main( int argc, char** argv )
{
for( double d = double(INT_MAX)-1; d < double(INT_MAX)+8; d += 2.0 )
{
int i = KiROUND( d );
printf( "t: %d %.16g\n", i, d );
}
return 0;
}
2012-04-19 06:55:45 +00:00
|
|
|
|
pos.x = KiROUND( ibuf[idx] * conv_unit );
|
|
|
|
|
pos.y = KiROUND( ibuf[idx+1] * conv_unit );
|
2011-12-09 16:17:38 +00:00
|
|
|
|
m_Reference->SetPos( pos );
|
|
|
|
|
m_Reference->SetPos0( pos );
|
2011-12-22 08:07:50 +00:00
|
|
|
|
m_Reference->SetOrientation( ibuf[idx+2] ? 900 : 0 );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
|
|
|
|
|
// Calculate size: default is 40 mils (400 pcb units)
|
2011-12-09 16:17:38 +00:00
|
|
|
|
// real size is: default * ibuf[idx+3] / 100 (size in gpcb is given in percent of default size
|
|
|
|
|
int tsize = ( ibuf[idx+3] * TEXT_DEFAULT_SIZE ) / 100;
|
|
|
|
|
int thickness = m_Reference->m_Size.x / 6;
|
2012-02-19 04:02:19 +00:00
|
|
|
|
|
2011-12-22 08:07:50 +00:00
|
|
|
|
tsize = MAX( 40, tsize );
|
|
|
|
|
m_Reference->SetSize( wxSize( tsize, tsize ) );
|
2011-12-09 16:17:38 +00:00
|
|
|
|
m_Reference->m_Thickness = thickness;
|
2011-12-22 08:07:50 +00:00
|
|
|
|
m_Value->SetOrientation( m_Reference->GetOrientation() );
|
|
|
|
|
m_Value->SetSize( m_Reference->GetSize() );
|
2010-11-27 13:09:18 +00:00
|
|
|
|
m_Value->m_Thickness = m_Reference->m_Thickness;
|
2011-12-09 16:17:38 +00:00
|
|
|
|
pos.y += tsize + thickness;
|
|
|
|
|
m_Value->SetPos( pos );
|
|
|
|
|
m_Value->SetPos0( pos );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
|
2011-01-14 17:43:30 +00:00
|
|
|
|
while( reader.ReadLine() )
|
2008-03-10 08:14:20 +00:00
|
|
|
|
{
|
2011-12-14 04:29:25 +00:00
|
|
|
|
line = reader.Line();
|
2008-03-10 08:14:20 +00:00
|
|
|
|
params.Clear();
|
2011-12-14 04:29:25 +00:00
|
|
|
|
Extract_Parameters( params, line );
|
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
if( params.GetCount() > 3 ) // Test units value for a string line param (more than 3 params : ident [ xx ] )
|
|
|
|
|
{
|
|
|
|
|
if( params[1] == wxT( "(" ) )
|
|
|
|
|
conv_unit = OLD_GPCB_UNIT_CONV;
|
|
|
|
|
else
|
|
|
|
|
conv_unit = NEW_GPCB_UNIT_CONV;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( params[0].CmpNoCase( wxT( "ElementLine" ) ) == 0 ) // line descr
|
|
|
|
|
{ // Format: ElementLine [X1 Y1 X2 Y2 Thickness]
|
2011-12-14 04:29:25 +00:00
|
|
|
|
wxPoint start0;
|
|
|
|
|
wxPoint end0;
|
|
|
|
|
int width;
|
2008-03-10 08:14:20 +00:00
|
|
|
|
|
2011-12-14 04:29:25 +00:00
|
|
|
|
int* list[5] = {
|
|
|
|
|
&start0.x, &start0.y,
|
|
|
|
|
&end0.x, &end0.y,
|
|
|
|
|
&width
|
|
|
|
|
};
|
2008-12-04 04:28:11 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
for( unsigned ii = 0; ii < 5; ii++ )
|
|
|
|
|
{
|
|
|
|
|
long dim;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
if( ii < (params.GetCount() - 2) )
|
|
|
|
|
{
|
|
|
|
|
if( params[ii + 2].ToLong( &dim ) )
|
// Dick Hollenbeck's KiROUND R&D
// This provides better project control over rounding to int from double
// than wxRound() did. This scheme provides better logging in Debug builds
// and it provides for compile time calculation of constants.
#include <stdio.h>
#include <assert.h>
#include <limits.h>
//-----<KiROUND KIT>------------------------------------------------------------
/**
* KiROUND
* rounds a floating point number to an int using
* "round halfway cases away from zero".
* In Debug build an assert fires if will not fit into an int.
*/
#if defined( DEBUG )
// DEBUG: a macro to capture line and file, then calls this inline
static inline int KiRound( double v, int line, const char* filename )
{
v = v < 0 ? v - 0.5 : v + 0.5;
if( v > INT_MAX + 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n", __FUNCTION__, filename, line, v );
}
else if( v < INT_MIN - 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n", __FUNCTION__, filename, line, v );
}
return int( v );
}
#define KiROUND( v ) KiRound( v, __LINE__, __FILE__ )
#else
// RELEASE: a macro so compile can pre-compute constants.
#define KiROUND( v ) int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 )
#endif
//-----</KiROUND KIT>-----------------------------------------------------------
// Only a macro is compile time calculated, an inline function causes a static constructor
// in a situation like this.
// Therefore the Release build is best done with a MACRO not an inline function.
int Computed = KiROUND( 14.3 * 8 );
int main( int argc, char** argv )
{
for( double d = double(INT_MAX)-1; d < double(INT_MAX)+8; d += 2.0 )
{
int i = KiROUND( d );
printf( "t: %d %.16g\n", i, d );
}
return 0;
}
2012-04-19 06:55:45 +00:00
|
|
|
|
*list[ii] = KiROUND( dim * conv_unit );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-14 04:29:25 +00:00
|
|
|
|
drawSeg = new EDGE_MODULE( this );
|
|
|
|
|
drawSeg->SetLayer( SILKSCREEN_N_FRONT );
|
|
|
|
|
drawSeg->SetShape( S_SEGMENT );
|
|
|
|
|
|
|
|
|
|
drawSeg->SetStart0( start0 );
|
|
|
|
|
drawSeg->SetEnd0( end0 );
|
|
|
|
|
drawSeg->SetWidth( width );
|
|
|
|
|
|
|
|
|
|
drawSeg->SetDrawCoord();
|
|
|
|
|
|
|
|
|
|
m_Drawings.PushBack( drawSeg );
|
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( params[0].CmpNoCase( wxT( "ElementArc" ) ) == 0 ) // Arc descr
|
|
|
|
|
{ // format: ElementArc [X Y Width Height StartAngle DeltaAngle Thickness]
|
2011-09-30 18:15:37 +00:00
|
|
|
|
// Pcbnew does know ellipse so we must have Width = Height
|
2011-12-14 04:29:25 +00:00
|
|
|
|
drawSeg = new EDGE_MODULE( this );
|
|
|
|
|
drawSeg->SetLayer( SILKSCREEN_N_FRONT );
|
|
|
|
|
drawSeg->SetShape( S_ARC );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
|
2011-12-14 04:29:25 +00:00
|
|
|
|
m_Drawings.PushBack( drawSeg );
|
2008-12-04 04:28:11 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
for( unsigned ii = 0; ii < 7; ii++ )
|
|
|
|
|
{
|
|
|
|
|
long dim;
|
|
|
|
|
if( ii < (params.GetCount() - 2) )
|
|
|
|
|
{
|
|
|
|
|
if( params[ii + 2].ToLong( &dim ) )
|
|
|
|
|
ibuf[ii] = dim;
|
|
|
|
|
else
|
|
|
|
|
ibuf[ii] = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
ibuf[ii] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-14 04:29:25 +00:00
|
|
|
|
// for and arc: ibuf[3] = ibuf[4]. Pcbnew does not know ellipses
|
|
|
|
|
int radius = (ibuf[2] + ibuf[3]) / 4;
|
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
wxPoint centre;
|
// Dick Hollenbeck's KiROUND R&D
// This provides better project control over rounding to int from double
// than wxRound() did. This scheme provides better logging in Debug builds
// and it provides for compile time calculation of constants.
#include <stdio.h>
#include <assert.h>
#include <limits.h>
//-----<KiROUND KIT>------------------------------------------------------------
/**
* KiROUND
* rounds a floating point number to an int using
* "round halfway cases away from zero".
* In Debug build an assert fires if will not fit into an int.
*/
#if defined( DEBUG )
// DEBUG: a macro to capture line and file, then calls this inline
static inline int KiRound( double v, int line, const char* filename )
{
v = v < 0 ? v - 0.5 : v + 0.5;
if( v > INT_MAX + 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n", __FUNCTION__, filename, line, v );
}
else if( v < INT_MIN - 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n", __FUNCTION__, filename, line, v );
}
return int( v );
}
#define KiROUND( v ) KiRound( v, __LINE__, __FILE__ )
#else
// RELEASE: a macro so compile can pre-compute constants.
#define KiROUND( v ) int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 )
#endif
//-----</KiROUND KIT>-----------------------------------------------------------
// Only a macro is compile time calculated, an inline function causes a static constructor
// in a situation like this.
// Therefore the Release build is best done with a MACRO not an inline function.
int Computed = KiROUND( 14.3 * 8 );
int main( int argc, char** argv )
{
for( double d = double(INT_MAX)-1; d < double(INT_MAX)+8; d += 2.0 )
{
int i = KiROUND( d );
printf( "t: %d %.16g\n", i, d );
}
return 0;
}
2012-04-19 06:55:45 +00:00
|
|
|
|
centre.x = KiROUND( ibuf[0] * conv_unit );
|
|
|
|
|
centre.y = KiROUND( ibuf[1] * conv_unit );
|
2011-12-14 04:29:25 +00:00
|
|
|
|
|
|
|
|
|
drawSeg->SetStart0( centre );
|
|
|
|
|
|
|
|
|
|
double start_angle = ibuf[4] * 10; // Pcbnew uses 0.1 degrees as units
|
2008-03-10 08:14:20 +00:00
|
|
|
|
start_angle -= 1800; // Use normal X axis as reference
|
2011-12-14 04:29:25 +00:00
|
|
|
|
|
|
|
|
|
drawSeg->SetAngle( ibuf[5] * 10 ); // Angle value is clockwise in gpcb and Pcbnew
|
|
|
|
|
|
// Dick Hollenbeck's KiROUND R&D
// This provides better project control over rounding to int from double
// than wxRound() did. This scheme provides better logging in Debug builds
// and it provides for compile time calculation of constants.
#include <stdio.h>
#include <assert.h>
#include <limits.h>
//-----<KiROUND KIT>------------------------------------------------------------
/**
* KiROUND
* rounds a floating point number to an int using
* "round halfway cases away from zero".
* In Debug build an assert fires if will not fit into an int.
*/
#if defined( DEBUG )
// DEBUG: a macro to capture line and file, then calls this inline
static inline int KiRound( double v, int line, const char* filename )
{
v = v < 0 ? v - 0.5 : v + 0.5;
if( v > INT_MAX + 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n", __FUNCTION__, filename, line, v );
}
else if( v < INT_MIN - 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n", __FUNCTION__, filename, line, v );
}
return int( v );
}
#define KiROUND( v ) KiRound( v, __LINE__, __FILE__ )
#else
// RELEASE: a macro so compile can pre-compute constants.
#define KiROUND( v ) int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 )
#endif
//-----</KiROUND KIT>-----------------------------------------------------------
// Only a macro is compile time calculated, an inline function causes a static constructor
// in a situation like this.
// Therefore the Release build is best done with a MACRO not an inline function.
int Computed = KiROUND( 14.3 * 8 );
int main( int argc, char** argv )
{
for( double d = double(INT_MAX)-1; d < double(INT_MAX)+8; d += 2.0 )
{
int i = KiROUND( d );
printf( "t: %d %.16g\n", i, d );
}
return 0;
}
2012-04-19 06:55:45 +00:00
|
|
|
|
drawSeg->SetEnd0( wxPoint( KiROUND( radius * conv_unit ), 0 ) );
|
2011-12-14 04:29:25 +00:00
|
|
|
|
|
|
|
|
|
// Calculate start point coordinate of arc
|
|
|
|
|
wxPoint arcStart( drawSeg->GetEnd0() );
|
|
|
|
|
RotatePoint( &arcStart, -start_angle );
|
|
|
|
|
drawSeg->SetEnd0( centre + arcStart );
|
|
|
|
|
|
// Dick Hollenbeck's KiROUND R&D
// This provides better project control over rounding to int from double
// than wxRound() did. This scheme provides better logging in Debug builds
// and it provides for compile time calculation of constants.
#include <stdio.h>
#include <assert.h>
#include <limits.h>
//-----<KiROUND KIT>------------------------------------------------------------
/**
* KiROUND
* rounds a floating point number to an int using
* "round halfway cases away from zero".
* In Debug build an assert fires if will not fit into an int.
*/
#if defined( DEBUG )
// DEBUG: a macro to capture line and file, then calls this inline
static inline int KiRound( double v, int line, const char* filename )
{
v = v < 0 ? v - 0.5 : v + 0.5;
if( v > INT_MAX + 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n", __FUNCTION__, filename, line, v );
}
else if( v < INT_MIN - 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n", __FUNCTION__, filename, line, v );
}
return int( v );
}
#define KiROUND( v ) KiRound( v, __LINE__, __FILE__ )
#else
// RELEASE: a macro so compile can pre-compute constants.
#define KiROUND( v ) int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 )
#endif
//-----</KiROUND KIT>-----------------------------------------------------------
// Only a macro is compile time calculated, an inline function causes a static constructor
// in a situation like this.
// Therefore the Release build is best done with a MACRO not an inline function.
int Computed = KiROUND( 14.3 * 8 );
int main( int argc, char** argv )
{
for( double d = double(INT_MAX)-1; d < double(INT_MAX)+8; d += 2.0 )
{
int i = KiROUND( d );
printf( "t: %d %.16g\n", i, d );
}
return 0;
}
2012-04-19 06:55:45 +00:00
|
|
|
|
drawSeg->SetWidth( KiROUND( ibuf[6] * conv_unit ) );
|
2011-12-14 04:29:25 +00:00
|
|
|
|
drawSeg->SetDrawCoord();
|
2008-03-10 08:14:20 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( params[0].CmpNoCase( wxT( "Pad" ) ) == 0 ) // Pad with no hole (smd pad)
|
2012-02-19 04:02:19 +00:00
|
|
|
|
{
|
|
|
|
|
// format: Pad [x1 y1 x2 y2 thickness clearance mask "name" "pad_number" flags]
|
|
|
|
|
pad = new D_PAD( this );
|
|
|
|
|
pad->SetShape( PAD_RECT );
|
|
|
|
|
pad->SetLayerMask( LAYER_FRONT | SOLDERMASK_LAYER_FRONT | SOLDERPASTE_LAYER_FRONT );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
|
|
|
|
|
// Set shape from flags
|
|
|
|
|
iflgidx = params.GetCount() - 2;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
if( TestFlags( params[iflgidx], 0x0080, wxT( "onsolder" ) ) )
|
2012-02-19 04:02:19 +00:00
|
|
|
|
pad->SetLayerMask( LAYER_BACK | SOLDERMASK_LAYER_BACK | SOLDERPASTE_LAYER_BACK );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
|
|
|
|
|
for( unsigned ii = 0; ii < 5; ii++ )
|
|
|
|
|
{
|
|
|
|
|
if( ii < params.GetCount() - 2 )
|
|
|
|
|
{
|
|
|
|
|
long dim;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
if( params[ii + 2].ToLong( &dim ) )
|
// Dick Hollenbeck's KiROUND R&D
// This provides better project control over rounding to int from double
// than wxRound() did. This scheme provides better logging in Debug builds
// and it provides for compile time calculation of constants.
#include <stdio.h>
#include <assert.h>
#include <limits.h>
//-----<KiROUND KIT>------------------------------------------------------------
/**
* KiROUND
* rounds a floating point number to an int using
* "round halfway cases away from zero".
* In Debug build an assert fires if will not fit into an int.
*/
#if defined( DEBUG )
// DEBUG: a macro to capture line and file, then calls this inline
static inline int KiRound( double v, int line, const char* filename )
{
v = v < 0 ? v - 0.5 : v + 0.5;
if( v > INT_MAX + 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n", __FUNCTION__, filename, line, v );
}
else if( v < INT_MIN - 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n", __FUNCTION__, filename, line, v );
}
return int( v );
}
#define KiROUND( v ) KiRound( v, __LINE__, __FILE__ )
#else
// RELEASE: a macro so compile can pre-compute constants.
#define KiROUND( v ) int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 )
#endif
//-----</KiROUND KIT>-----------------------------------------------------------
// Only a macro is compile time calculated, an inline function causes a static constructor
// in a situation like this.
// Therefore the Release build is best done with a MACRO not an inline function.
int Computed = KiROUND( 14.3 * 8 );
int main( int argc, char** argv )
{
for( double d = double(INT_MAX)-1; d < double(INT_MAX)+8; d += 2.0 )
{
int i = KiROUND( d );
printf( "t: %d %.16g\n", i, d );
}
return 0;
}
2012-04-19 06:55:45 +00:00
|
|
|
|
ibuf[ii] = KiROUND( dim * conv_unit );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2011-09-07 19:41:04 +00:00
|
|
|
|
{
|
2008-03-10 08:14:20 +00:00
|
|
|
|
ibuf[ii] = 0;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
}
|
2008-03-10 08:14:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Read name:
|
|
|
|
|
// Currently unused
|
|
|
|
|
|
|
|
|
|
// Read pad number:
|
2011-10-13 18:37:43 +00:00
|
|
|
|
if( params[1] == wxT( "(" ) )
|
|
|
|
|
{
|
2012-02-19 04:02:19 +00:00
|
|
|
|
pad->SetPadName( params[8] );
|
2011-10-13 18:37:43 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2008-03-10 08:14:20 +00:00
|
|
|
|
{
|
2012-02-19 04:02:19 +00:00
|
|
|
|
pad->SetPadName( params[10] );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
}
|
2011-12-03 14:04:17 +00:00
|
|
|
|
// Calculate the Pad parameters.
|
|
|
|
|
// In Pcb the shape is a segment
|
|
|
|
|
// ibuf[0], ibuf[1] is the start point of the segment
|
|
|
|
|
// ibuf[2], ibuf[3] is the end point of the segment
|
|
|
|
|
// and me must convert the segment to an oval ( or rectangular) pad
|
|
|
|
|
// Pad pos = middle of the segment
|
|
|
|
|
// Pad Orientation = angle of the segment
|
|
|
|
|
// Pad size = lenght and thickness of the segment
|
|
|
|
|
wxPoint delta;
|
|
|
|
|
delta.x = ibuf[2] - ibuf[0];
|
|
|
|
|
delta.y = ibuf[3] - ibuf[1];
|
2012-02-19 04:02:19 +00:00
|
|
|
|
|
2011-12-03 14:04:17 +00:00
|
|
|
|
double angle = atan2( (double)delta.y, (double)delta.x );
|
2012-02-19 04:02:19 +00:00
|
|
|
|
|
2011-12-03 14:04:17 +00:00
|
|
|
|
// Negate angle (due to Y reversed axis) and convert it to internal units
|
|
|
|
|
angle = - angle * 1800.0 / M_PI;
|
// Dick Hollenbeck's KiROUND R&D
// This provides better project control over rounding to int from double
// than wxRound() did. This scheme provides better logging in Debug builds
// and it provides for compile time calculation of constants.
#include <stdio.h>
#include <assert.h>
#include <limits.h>
//-----<KiROUND KIT>------------------------------------------------------------
/**
* KiROUND
* rounds a floating point number to an int using
* "round halfway cases away from zero".
* In Debug build an assert fires if will not fit into an int.
*/
#if defined( DEBUG )
// DEBUG: a macro to capture line and file, then calls this inline
static inline int KiRound( double v, int line, const char* filename )
{
v = v < 0 ? v - 0.5 : v + 0.5;
if( v > INT_MAX + 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n", __FUNCTION__, filename, line, v );
}
else if( v < INT_MIN - 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n", __FUNCTION__, filename, line, v );
}
return int( v );
}
#define KiROUND( v ) KiRound( v, __LINE__, __FILE__ )
#else
// RELEASE: a macro so compile can pre-compute constants.
#define KiROUND( v ) int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 )
#endif
//-----</KiROUND KIT>-----------------------------------------------------------
// Only a macro is compile time calculated, an inline function causes a static constructor
// in a situation like this.
// Therefore the Release build is best done with a MACRO not an inline function.
int Computed = KiROUND( 14.3 * 8 );
int main( int argc, char** argv )
{
for( double d = double(INT_MAX)-1; d < double(INT_MAX)+8; d += 2.0 )
{
int i = KiROUND( d );
printf( "t: %d %.16g\n", i, d );
}
return 0;
}
2012-04-19 06:55:45 +00:00
|
|
|
|
pad->SetOrientation( KiROUND( angle ) );
|
2012-02-19 04:02:19 +00:00
|
|
|
|
|
|
|
|
|
wxPoint padPos( (ibuf[0] + ibuf[2]) / 2, (ibuf[1] + ibuf[3]) / 2 );
|
|
|
|
|
|
|
|
|
|
pad->SetSize( wxSize(
|
// Dick Hollenbeck's KiROUND R&D
// This provides better project control over rounding to int from double
// than wxRound() did. This scheme provides better logging in Debug builds
// and it provides for compile time calculation of constants.
#include <stdio.h>
#include <assert.h>
#include <limits.h>
//-----<KiROUND KIT>------------------------------------------------------------
/**
* KiROUND
* rounds a floating point number to an int using
* "round halfway cases away from zero".
* In Debug build an assert fires if will not fit into an int.
*/
#if defined( DEBUG )
// DEBUG: a macro to capture line and file, then calls this inline
static inline int KiRound( double v, int line, const char* filename )
{
v = v < 0 ? v - 0.5 : v + 0.5;
if( v > INT_MAX + 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n", __FUNCTION__, filename, line, v );
}
else if( v < INT_MIN - 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n", __FUNCTION__, filename, line, v );
}
return int( v );
}
#define KiROUND( v ) KiRound( v, __LINE__, __FILE__ )
#else
// RELEASE: a macro so compile can pre-compute constants.
#define KiROUND( v ) int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 )
#endif
//-----</KiROUND KIT>-----------------------------------------------------------
// Only a macro is compile time calculated, an inline function causes a static constructor
// in a situation like this.
// Therefore the Release build is best done with a MACRO not an inline function.
int Computed = KiROUND( 14.3 * 8 );
int main( int argc, char** argv )
{
for( double d = double(INT_MAX)-1; d < double(INT_MAX)+8; d += 2.0 )
{
int i = KiROUND( d );
printf( "t: %d %.16g\n", i, d );
}
return 0;
}
2012-04-19 06:55:45 +00:00
|
|
|
|
KiROUND( hypot( (double)delta.x, (double)delta.y ) ) + ibuf[4],
|
2012-02-19 04:02:19 +00:00
|
|
|
|
ibuf[4] ) );
|
|
|
|
|
|
2011-12-22 08:07:50 +00:00
|
|
|
|
padPos += m_Pos;
|
2012-02-19 04:02:19 +00:00
|
|
|
|
pad->SetPos0( padPos );
|
|
|
|
|
pad->SetPosition( padPos );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
if( !TestFlags( params[iflgidx], 0x0100, wxT( "square" ) ) )
|
|
|
|
|
{
|
2012-02-19 04:02:19 +00:00
|
|
|
|
if( pad->GetSize().x == pad->GetSize().y )
|
|
|
|
|
pad->SetShape( PAD_ROUND );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
else
|
2012-02-19 04:02:19 +00:00
|
|
|
|
pad->SetShape( PAD_OVAL );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-19 04:02:19 +00:00
|
|
|
|
m_Pads.PushBack( pad );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( params[0].CmpNoCase( wxT( "Pin" ) ) == 0 ) // Pad with hole (trough pad)
|
2012-02-19 04:02:19 +00:00
|
|
|
|
{
|
|
|
|
|
// format: Pin[x y Thickness Clearance Mask DrillHole Name Number Flags]
|
|
|
|
|
pad = new D_PAD( this );
|
|
|
|
|
pad->SetShape( PAD_ROUND );
|
|
|
|
|
|
|
|
|
|
pad->SetLayerMask( ALL_CU_LAYERS |
|
2009-12-21 18:51:37 +00:00
|
|
|
|
SILKSCREEN_LAYER_FRONT |
|
|
|
|
|
SOLDERMASK_LAYER_FRONT |
|
2012-02-19 04:02:19 +00:00
|
|
|
|
SOLDERMASK_LAYER_BACK );
|
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
iflgidx = params.GetCount() - 2;
|
2008-12-04 04:28:11 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
if( TestFlags( params[iflgidx], 0x0100, wxT( "square" ) ) )
|
2012-02-19 04:02:19 +00:00
|
|
|
|
pad->SetShape( PAD_RECT );
|
2008-12-04 04:28:11 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
for( unsigned ii = 0; ii < 6; ii++ )
|
|
|
|
|
{
|
|
|
|
|
if( ii < params.GetCount() - 2 )
|
|
|
|
|
{
|
|
|
|
|
long dim;
|
|
|
|
|
if( params[ii + 2].ToLong( &dim ) )
|
// Dick Hollenbeck's KiROUND R&D
// This provides better project control over rounding to int from double
// than wxRound() did. This scheme provides better logging in Debug builds
// and it provides for compile time calculation of constants.
#include <stdio.h>
#include <assert.h>
#include <limits.h>
//-----<KiROUND KIT>------------------------------------------------------------
/**
* KiROUND
* rounds a floating point number to an int using
* "round halfway cases away from zero".
* In Debug build an assert fires if will not fit into an int.
*/
#if defined( DEBUG )
// DEBUG: a macro to capture line and file, then calls this inline
static inline int KiRound( double v, int line, const char* filename )
{
v = v < 0 ? v - 0.5 : v + 0.5;
if( v > INT_MAX + 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' > 0 ' for int\n", __FUNCTION__, filename, line, v );
}
else if( v < INT_MIN - 0.5 )
{
printf( "%s: in file %s on line %d, val: %.16g too ' < 0 ' for int\n", __FUNCTION__, filename, line, v );
}
return int( v );
}
#define KiROUND( v ) KiRound( v, __LINE__, __FILE__ )
#else
// RELEASE: a macro so compile can pre-compute constants.
#define KiROUND( v ) int( (v) < 0 ? (v) - 0.5 : (v) + 0.5 )
#endif
//-----</KiROUND KIT>-----------------------------------------------------------
// Only a macro is compile time calculated, an inline function causes a static constructor
// in a situation like this.
// Therefore the Release build is best done with a MACRO not an inline function.
int Computed = KiROUND( 14.3 * 8 );
int main( int argc, char** argv )
{
for( double d = double(INT_MAX)-1; d < double(INT_MAX)+8; d += 2.0 )
{
int i = KiROUND( d );
printf( "t: %d %.16g\n", i, d );
}
return 0;
}
2012-04-19 06:55:45 +00:00
|
|
|
|
ibuf[ii] = KiROUND( dim * conv_unit );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2011-09-07 19:41:04 +00:00
|
|
|
|
{
|
2008-03-10 08:14:20 +00:00
|
|
|
|
ibuf[ii] = 0;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
}
|
2008-03-10 08:14:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Read name:
|
|
|
|
|
// Currently unused
|
|
|
|
|
|
|
|
|
|
// Read pad number:
|
2011-10-13 18:37:43 +00:00
|
|
|
|
if( params[1] == wxT( "(" ) )
|
|
|
|
|
{
|
2012-02-19 04:02:19 +00:00
|
|
|
|
pad->SetPadName( params[7] );
|
2011-10-13 18:37:43 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2008-03-10 08:14:20 +00:00
|
|
|
|
{
|
2012-02-19 04:02:19 +00:00
|
|
|
|
pad->SetPadName( params[9] );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
}
|
2012-02-19 04:02:19 +00:00
|
|
|
|
|
|
|
|
|
wxPoint padPos( ibuf[0], ibuf[1] );
|
|
|
|
|
|
|
|
|
|
pad->SetDrillSize( wxSize( ibuf[5], ibuf[5] ) );
|
|
|
|
|
|
|
|
|
|
int sz = ibuf[3] + pad->GetDrillSize().x;
|
|
|
|
|
|
|
|
|
|
pad->SetSize( wxSize( sz, sz ) );
|
|
|
|
|
|
2011-12-22 08:07:50 +00:00
|
|
|
|
padPos += m_Pos;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
|
2012-02-19 04:02:19 +00:00
|
|
|
|
pad->SetPos0( padPos );
|
|
|
|
|
pad->SetPosition( padPos );
|
|
|
|
|
|
|
|
|
|
if( pad->GetShape() == PAD_ROUND && pad->GetSize().x != pad->GetSize().y )
|
|
|
|
|
pad->SetShape( PAD_OVAL );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
|
2012-02-19 04:02:19 +00:00
|
|
|
|
m_Pads.PushBack( pad );
|
2008-03-10 08:14:20 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( m_Value->m_Text.IsEmpty() )
|
|
|
|
|
m_Value->m_Text = wxT( "Val**" );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
if( m_Reference->m_Text.IsEmpty() )
|
|
|
|
|
{
|
|
|
|
|
wxFileName filename( CmpFullFileName );
|
|
|
|
|
m_Reference->m_Text = filename.GetName();
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-19 04:02:19 +00:00
|
|
|
|
// Recalculate the bounding box
|
2011-09-07 19:41:04 +00:00
|
|
|
|
CalculateBoundingBox();
|
2008-03-10 08:14:20 +00:00
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Read a text line and extract params and tokens.
|
|
|
|
|
* special chars are:
|
2011-09-23 13:57:12 +00:00
|
|
|
|
* [ ] ( ) Begin and end of parameter list and units indicator
|
2008-03-10 08:14:20 +00:00
|
|
|
|
* " is a string delimiter
|
|
|
|
|
* space is the param separator
|
|
|
|
|
* The first word is the keyword
|
|
|
|
|
* the second item is one of ( ot [
|
|
|
|
|
* other are parameters (number or delimited string)
|
|
|
|
|
* last parameter is ) or ]
|
|
|
|
|
*/
|
2011-09-07 19:41:04 +00:00
|
|
|
|
static void Extract_Parameters( wxArrayString& param_list, char* text )
|
2008-03-10 08:14:20 +00:00
|
|
|
|
{
|
2011-09-07 19:41:04 +00:00
|
|
|
|
char key;
|
2008-03-10 08:14:20 +00:00
|
|
|
|
wxString tmp;
|
|
|
|
|
|
|
|
|
|
while( *text != 0 )
|
|
|
|
|
{
|
|
|
|
|
key = *text;
|
|
|
|
|
text++;
|
|
|
|
|
|
|
|
|
|
switch( key )
|
|
|
|
|
{
|
|
|
|
|
case '[':
|
|
|
|
|
case ']':
|
|
|
|
|
case '(':
|
|
|
|
|
case ')':
|
|
|
|
|
if( !tmp.IsEmpty() )
|
|
|
|
|
{
|
|
|
|
|
param_list.Add( tmp );
|
|
|
|
|
tmp.Clear();
|
|
|
|
|
}
|
|
|
|
|
tmp.Append( key );
|
|
|
|
|
param_list.Add( tmp );
|
|
|
|
|
tmp.Clear();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '\n':
|
|
|
|
|
case '\r':
|
|
|
|
|
case '\t':
|
|
|
|
|
case ' ':
|
|
|
|
|
if( !tmp.IsEmpty() )
|
|
|
|
|
{
|
|
|
|
|
param_list.Add( tmp );
|
|
|
|
|
tmp.Clear();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '"':
|
|
|
|
|
while( *text != 0 )
|
|
|
|
|
{
|
|
|
|
|
key = *text;
|
|
|
|
|
text++;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
if( key == '"' )
|
|
|
|
|
{
|
|
|
|
|
param_list.Add( tmp );
|
|
|
|
|
tmp.Clear();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
2011-09-07 19:41:04 +00:00
|
|
|
|
{
|
2008-03-10 08:14:20 +00:00
|
|
|
|
tmp.Append( key );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
}
|
2008-03-10 08:14:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
tmp.Append( key );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2010-11-12 16:36:43 +00:00
|
|
|
|
/**
|
|
|
|
|
* Function TestFlags
|
2008-03-10 08:14:20 +00:00
|
|
|
|
* Test flag flg_mask or flg_name.
|
|
|
|
|
* @param flg_string = flsg list to test: can be a bit field flag or a list name flsg
|
|
|
|
|
* a bit field flag is an hexadecimal value: Ox00020000
|
2010-12-28 11:24:42 +00:00
|
|
|
|
* a list name flag is a string list of flags, comma separated like square,option1
|
|
|
|
|
* @param flg_mask = flag list to test
|
|
|
|
|
* @param flg_name = flag name to find in list
|
2008-03-10 08:14:20 +00:00
|
|
|
|
* @return true if found
|
|
|
|
|
*/
|
2011-09-07 19:41:04 +00:00
|
|
|
|
bool TestFlags( const wxString& flg_string, long flg_mask, const wxChar* flg_name )
|
2008-03-10 08:14:20 +00:00
|
|
|
|
{
|
|
|
|
|
wxString strnumber;
|
|
|
|
|
|
2011-09-07 19:41:04 +00:00
|
|
|
|
if( flg_string.StartsWith( wxT( "0x" ), &strnumber )
|
|
|
|
|
|| flg_string.StartsWith( wxT( "0X" ), &strnumber ) )
|
2008-03-10 08:14:20 +00:00
|
|
|
|
{
|
|
|
|
|
long lflags;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
|
2008-03-10 08:14:20 +00:00
|
|
|
|
if( strnumber.ToLong( &lflags, 16 ) )
|
|
|
|
|
if( lflags & flg_mask )
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else if( flg_string.Contains( flg_name ) )
|
2011-09-07 19:41:04 +00:00
|
|
|
|
{
|
2008-03-10 08:14:20 +00:00
|
|
|
|
return true;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
}
|
2008-03-10 08:14:20 +00:00
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|