diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 1afecf8e36..e6717f5164 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -156,7 +156,6 @@ set(PCBNEW_CLASS_SRCS gen_modules_placefile.cpp gendrill_Excellon_writer.cpp globaleditpad.cpp - gpcb_exchange.cpp highlight.cpp hotkeys.cpp hotkeys_board_editor.cpp diff --git a/pcbnew/gpcb_exchange.cpp b/pcbnew/gpcb_exchange.cpp deleted file mode 100644 index 0f3dea142d..0000000000 --- a/pcbnew/gpcb_exchange.cpp +++ /dev/null @@ -1,662 +0,0 @@ -/** - * @file gpcb_exchange.cpp - * @brief Import functions to import footprints from a gpcb (Newlib) library. - */ - -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - - -/* 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. - * MX MY The location of the element�s mark. This is the reference point for placing the element and its pins and pads. - * 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. - * TScale Size of the text, as a percentage of the �default� size of of the font (the default font is about 40 mils high). Default is 100 (40 mils). - * 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) - * ( Note: Pad is a SMD Pad in Pcbnew, and Pin is a through hole Pad in Pcbnew ) - * 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. - */ -bool MODULE::Read_GPCB_Descr( const wxString& CmpFullFileName ) -{ - #define TEXT_DEFAULT_SIZE (40*IU_PER_MILS) - #define OLD_GPCB_UNIT_CONV IU_PER_MILS - #define NEW_GPCB_UNIT_CONV (0.01*IU_PER_MILS) - - FILE* cmpfile; - double conv_unit = NEW_GPCB_UNIT_CONV; // GPCB unit = 0.01 mils and Pcbnew 0.1 - - // Old version unit = 1 mil, so conv_unit is 10 or 0.1 - bool success = true; - char* line; - long ibuf[100]; - EDGE_MODULE* drawSeg; - D_PAD* pad; - wxArrayString params; - int iprmcnt, icnt_max, iflgidx; - - if( ( cmpfile = wxFopen( CmpFullFileName, wxT( "rt" ) ) ) == NULL ) - return false; - - FILE_LINE_READER fileReader( cmpfile, CmpFullFileName ); - - FILTER_READER reader( fileReader ); - - reader.ReadLine(); - - line = reader.Line(); - - params.Clear(); - Extract_Parameters( params, line ); - - 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++; - - 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, - * text_direction, text_scale, text_flags] - */ - - // Read flags (unused) - iprmcnt++; - - // Read description - iprmcnt++; - m_Doc = params[iprmcnt]; - - // Read pcb-name (reference ) - iprmcnt++; - m_Reference->m_Text = params[iprmcnt]; - - // Read value - iprmcnt++; - m_Value->m_Text = params[iprmcnt]; - - // Read other infos - 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 - iprmcnt++; - for( int ii = 0; ii < 20; ii++ ) - ibuf[ii] = 0; - - for( int ii = 0; ii <= 8; ii++, iprmcnt++ ) // upt to 6 params + terminal char. - { - if( iprmcnt >= icnt_max ) - { - success = false; - break; - } - else - { - if( params[iprmcnt] == wxT( ")" ) || - params[iprmcnt] == wxT( "]" ) ) - { // Terminal character found - if( ii <= 5 ) // no module position - idx = 0; - break; - } - params[iprmcnt].ToLong( &ibuf[ii] ); - } - } - wxPoint pos; - pos.x = KiROUND( ibuf[idx] * conv_unit ); - pos.y = KiROUND( ibuf[idx+1] * conv_unit ); - m_Reference->SetPos( pos ); - m_Reference->SetPos0( pos ); - m_Reference->SetOrientation( ibuf[idx+2] ? 900 : 0 ); - - // Calculate size: default is 40 mils - // 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; - - tsize = std::max( (int)(5 * IU_PER_MILS), tsize ); // Ensure a minimal size = 5 mils - m_Reference->SetSize( wxSize( tsize, tsize ) ); - m_Reference->m_Thickness = thickness; - m_Value->SetOrientation( m_Reference->GetOrientation() ); - m_Value->SetSize( m_Reference->GetSize() ); - m_Value->m_Thickness = m_Reference->m_Thickness; - pos.y += tsize + thickness; - m_Value->SetPos( pos ); - m_Value->SetPos0( pos ); - - while( reader.ReadLine() ) - { - line = reader.Line(); - params.Clear(); - Extract_Parameters( params, line ); - - 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] - wxPoint start0; - wxPoint end0; - int width; - - int* list[5] = { - &start0.x, &start0.y, - &end0.x, &end0.y, - &width - }; - - for( unsigned ii = 0; ii < 5; ii++ ) - { - long dim; - - if( ii < (params.GetCount() - 2) ) - { - if( params[ii + 2].ToLong( &dim ) ) - *list[ii] = KiROUND( dim * conv_unit ); - } - } - - 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 ); - - continue; - } - - if( params[0].CmpNoCase( wxT( "ElementArc" ) ) == 0 ) // Arc descr - { // format: ElementArc [X Y Width Height StartAngle DeltaAngle Thickness] - // Pcbnew does know ellipse so we must have Width = Height - drawSeg = new EDGE_MODULE( this ); - drawSeg->SetLayer( SILKSCREEN_N_FRONT ); - drawSeg->SetShape( S_ARC ); - - m_Drawings.PushBack( drawSeg ); - - 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; - } - - // for and arc: ibuf[3] = ibuf[4]. Pcbnew does not know ellipses - int radius = (ibuf[2] + ibuf[3]) / 4; - - wxPoint centre; - centre.x = KiROUND( ibuf[0] * conv_unit ); - centre.y = KiROUND( ibuf[1] * conv_unit ); - - drawSeg->SetStart0( centre ); - - double start_angle = ibuf[4] * 10; // Pcbnew uses 0.1 degrees as units - start_angle -= 1800; // Use normal X axis as reference - - drawSeg->SetAngle( ibuf[5] * 10 ); // Angle value is clockwise in gpcb and Pcbnew - - drawSeg->SetEnd0( wxPoint( KiROUND( radius * conv_unit ), 0 ) ); - - // Calculate start point coordinate of arc - wxPoint arcStart( drawSeg->GetEnd0() ); - RotatePoint( &arcStart, -start_angle ); - drawSeg->SetEnd0( centre + arcStart ); - - drawSeg->SetWidth( KiROUND( ibuf[6] * conv_unit ) ); - drawSeg->SetDrawCoord(); - continue; - } - - if( params[0].CmpNoCase( wxT( "Pad" ) ) == 0 ) // Pad with no hole (smd pad) - { - // format: Pad [x1 y1 x2 y2 thickness clearance mask "name" "pad_number" flags] - pad = new D_PAD( this ); - pad->SetShape( PAD_RECT ); - pad->SetAttribute( PAD_SMD ); - pad->SetLayerMask( LAYER_FRONT | SOLDERMASK_LAYER_FRONT | SOLDERPASTE_LAYER_FRONT ); - - // Set shape from flags - iflgidx = params.GetCount() - 2; - - if( TestFlags( params[iflgidx], 0x0080, wxT( "onsolder" ) ) ) - pad->SetLayerMask( LAYER_BACK | SOLDERMASK_LAYER_BACK | SOLDERPASTE_LAYER_BACK ); - - for( unsigned ii = 0; ii < 5; ii++ ) - { - if( ii < params.GetCount() - 2 ) - { - long dim; - - if( params[ii + 2].ToLong( &dim ) ) - ibuf[ii] = KiROUND( dim * conv_unit ); - } - else - { - ibuf[ii] = 0; - } - } - - // Read name: - // Currently unused - - // Read pad number: - if( params[1] == wxT( "(" ) ) - { - pad->SetPadName( params[8] ); - } - else - { - pad->SetPadName( params[10] ); - } - // 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]; - - double angle = atan2( (double)delta.y, (double)delta.x ); - - // Negate angle (due to Y reversed axis) and convert it to internal units - angle = - angle * 1800.0 / M_PI; - pad->SetOrientation( KiROUND( angle ) ); - - wxPoint padPos( (ibuf[0] + ibuf[2]) / 2, (ibuf[1] + ibuf[3]) / 2 ); - - pad->SetSize( wxSize( - KiROUND( hypot( (double)delta.x, (double)delta.y ) ) + ibuf[4], - ibuf[4] ) ); - - padPos += m_Pos; - pad->SetPos0( padPos ); - pad->SetPosition( padPos ); - - if( !TestFlags( params[iflgidx], 0x0100, wxT( "square" ) ) ) - { - if( pad->GetSize().x == pad->GetSize().y ) - pad->SetShape( PAD_ROUND ); - else - pad->SetShape( PAD_OVAL ); - } - - m_Pads.PushBack( pad ); - continue; - } - - if( params[0].CmpNoCase( wxT( "Pin" ) ) == 0 ) // Pad with hole (trough pad) - { - // 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 | - SILKSCREEN_LAYER_FRONT | - SOLDERMASK_LAYER_FRONT | - SOLDERMASK_LAYER_BACK ); - - iflgidx = params.GetCount() - 2; - - if( TestFlags( params[iflgidx], 0x0100, wxT( "square" ) ) ) - pad->SetShape( PAD_RECT ); - - for( unsigned ii = 0; ii < 6; ii++ ) - { - if( ii < params.GetCount() - 2 ) - { - long dim; - if( params[ii + 2].ToLong( &dim ) ) - ibuf[ii] = KiROUND( dim * conv_unit ); - } - else - { - ibuf[ii] = 0; - } - } - - // Read name: - // Currently unused - - // Read pad number: - if( params[1] == wxT( "(" ) ) - { - pad->SetPadName( params[7] ); - } - else - { - pad->SetPadName( params[9] ); - } - - 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 ) ); - - padPos += m_Pos; - - pad->SetPos0( padPos ); - pad->SetPosition( padPos ); - - if( pad->GetShape() == PAD_ROUND && pad->GetSize().x != pad->GetSize().y ) - pad->SetShape( PAD_OVAL ); - - m_Pads.PushBack( pad ); - continue; - } - } - - if( m_Value->m_Text.IsEmpty() ) - m_Value->m_Text = wxT( "Val**" ); - - if( m_Reference->m_Text.IsEmpty() ) - { - wxFileName filename( CmpFullFileName ); - m_Reference->m_Text = filename.GetName(); - } - - // Recalculate the bounding box - CalculateBoundingBox(); - return success; -} - - -/* Read a text line and extract params and tokens. - * special chars are: - * [ ] ( ) Begin and end of parameter list and units indicator - * " 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 ] - */ -static void Extract_Parameters( wxArrayString& param_list, char* text ) -{ - char key; - 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++; - - if( key == '"' ) - { - param_list.Add( tmp ); - tmp.Clear(); - break; - } - else - { - tmp.Append( key ); - } - } - - break; - - default: - tmp.Append( key ); - break; - } - } -} - - -/** - * Function TestFlags - * 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 - * 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 - * @return true if found - */ -bool TestFlags( const wxString& flg_string, long flg_mask, const wxChar* flg_name ) -{ - wxString strnumber; - - if( flg_string.StartsWith( wxT( "0x" ), &strnumber ) - || flg_string.StartsWith( wxT( "0X" ), &strnumber ) ) - { - long lflags; - - if( strnumber.ToLong( &lflags, 16 ) ) - if( lflags & flg_mask ) - return true; - } - else if( flg_string.Contains( flg_name ) ) - { - return true; - } - - return false; -}