From 90ad2406607606187b2d2eb629ce764dbb46d965 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Mon, 7 Jan 2019 21:42:50 -0800 Subject: [PATCH] units: Move common units and add tests Centralizing duplicate code from Eeschema and pcbnew and adding unit tests --- common/base_units.cpp | 62 +++++ common/eda_text.cpp | 10 +- eeschema/sch_item_struct.cpp | 47 ---- eeschema/sch_item_struct.h | 25 -- include/base_units.h | 36 ++- include/class_board_item.h | 28 --- include/unit_format.h | 44 ---- pcbnew/class_board.cpp | 16 +- pcbnew/class_board_item.cpp | 109 -------- pcbnew/dialogs/dialog_pad_properties.cpp | 3 +- pcbnew/kicad_plugin.cpp | 303 +++++++++++------------ pcbnew/netclass.cpp | 23 +- qa/common/CMakeLists.txt | 50 ++-- qa/common/test_format_units.cpp | 78 ++++++ 14 files changed, 384 insertions(+), 450 deletions(-) delete mode 100644 include/unit_format.h create mode 100644 qa/common/test_format_units.cpp diff --git a/common/base_units.cpp b/common/base_units.cpp index 0caff81370..7857f2f176 100644 --- a/common/base_units.cpp +++ b/common/base_units.cpp @@ -453,3 +453,65 @@ wxString GetAbbreviatedUnitsLabel( EDA_UNITS_T aUnit, bool aUseMils ) } } + +std::string FormatInternalUnits( int aValue ) +{ + char buf[50]; + double engUnits = aValue; + int len; + +#ifndef EESCHEMA + engUnits /= IU_PER_MM; +#endif + + if( engUnits != 0.0 && fabs( engUnits ) <= 0.0001 ) + { + len = snprintf( buf, sizeof(buf), "%.10f", engUnits ); + + while( --len > 0 && buf[len] == '0' ) + buf[len] = '\0'; + +#ifndef EESCHEMA + if( buf[len] == '.' ) + buf[len] = '\0'; + else +#endif + ++len; + } + else + { + len = snprintf( buf, sizeof(buf), "%.10g", engUnits ); + } + + return std::string( buf, len ); +} + + +std::string FormatAngle( double aAngle ) +{ + char temp[50]; + int len; + + len = snprintf( temp, sizeof(temp), "%.10g", aAngle / 10.0 ); + + return std::string( temp, len ); +} + + +std::string FormatInternalUnits( const wxPoint& aPoint ) +{ + return FormatInternalUnits( aPoint.x ) + " " + FormatInternalUnits( aPoint.y ); +} + + +std::string FormatInternalUnits( const VECTOR2I& aPoint ) +{ + return FormatInternalUnits( aPoint.x ) + " " + FormatInternalUnits( aPoint.y ); +} + + +std::string FormatInternalUnits( const wxSize& aSize ) +{ + return FormatInternalUnits( aSize.GetWidth() ) + " " + FormatInternalUnits( aSize.GetHeight() ); +} + diff --git a/common/eda_text.cpp b/common/eda_text.cpp index c5effab570..9968ffb25f 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -35,7 +35,7 @@ #include // EDA_DRAW_PANEL #include -#include +#include #include EDA_TEXT::EDA_TEXT( const wxString& text ) : @@ -416,7 +416,7 @@ bool EDA_TEXT::IsDefaultFormatting() const void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const { #ifndef GERBVIEW // Gerbview does not use EDA_TEXT::Format - // and does not define FMT_IU, used here + // and does not define FormatInternalUnits, used here // however this function should exist aFormatter->Print( aNestLevel + 1, "(effects" ); @@ -425,11 +425,11 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl aFormatter->Print( 0, " (font" ); aFormatter->Print( 0, " (size %s %s)", - FMT_IU( GetTextHeight() ).c_str(), - FMT_IU( GetTextWidth() ).c_str() ); + FormatInternalUnits( GetTextHeight() ).c_str(), + FormatInternalUnits( GetTextWidth() ).c_str() ); if( GetThickness() ) - aFormatter->Print( 0, " (thickness %s)", FMT_IU( GetThickness() ).c_str() ); + aFormatter->Print( 0, " (thickness %s)", FormatInternalUnits( GetThickness() ).c_str() ); if( IsBold() ) aFormatter->Print( 0, " bold" ); diff --git a/eeschema/sch_item_struct.cpp b/eeschema/sch_item_struct.cpp index 6a42e5b1a8..d0a31c364d 100644 --- a/eeschema/sch_item_struct.cpp +++ b/eeschema/sch_item_struct.cpp @@ -102,50 +102,3 @@ void SCH_ITEM::Plot( PLOTTER* aPlotter ) { wxFAIL_MSG( wxT( "Plot() method not implemented for class " ) + GetClass() ); } - - -std::string SCH_ITEM::FormatInternalUnits( int aValue ) -{ - char buf[50]; - double engUnits = aValue; - int len; - - if( engUnits != 0.0 && fabs( engUnits ) <= 0.0001 ) - { - len = snprintf( buf, sizeof(buf), "%.10f", engUnits ); - - while( --len > 0 && buf[len] == '0' ) - buf[len] = '\0'; - - ++len; - } - else - { - len = snprintf( buf, sizeof(buf), "%.10g", engUnits ); - } - - return std::string( buf, len ); -} - - -std::string SCH_ITEM::FormatAngle( double aAngle ) -{ - char temp[50]; - int len; - - len = snprintf( temp, sizeof(temp), "%.10g", aAngle / 10.0 ); - - return std::string( temp, len ); -} - - -std::string SCH_ITEM::FormatInternalUnits( const wxPoint& aPoint ) -{ - return FormatInternalUnits( aPoint.x ) + " " + FormatInternalUnits( aPoint.y ); -} - - -std::string SCH_ITEM::FormatInternalUnits( const wxSize& aSize ) -{ - return FormatInternalUnits( aSize.GetWidth() ) + " " + FormatInternalUnits( aSize.GetHeight() ); -} diff --git a/eeschema/sch_item_struct.h b/eeschema/sch_item_struct.h index 94fa464d71..b8ca4c923a 100644 --- a/eeschema/sch_item_struct.h +++ b/eeschema/sch_item_struct.h @@ -380,31 +380,6 @@ public: virtual bool operator <( const SCH_ITEM& aItem ) const; - /** - * Function FormatInternalUnits - * converts \a aValue from schematic internal units to a string appropriate for writing - * to file. - * - * @param aValue A coordinate value to convert. - * @return A std::string object containing the converted value. - */ - static std::string FormatInternalUnits( int aValue ); - - /** - * Function FormatAngle - * converts \a aAngle from board units to a string appropriate for writing to file. - * - * @note Internal angles for board items can be either degrees or tenths of degree - * on how KiCad is built. - * @param aAngle A angle value to convert. - * @return A std::string object containing the converted angle. - */ - static std::string FormatAngle( double aAngle ); - - static std::string FormatInternalUnits( const wxPoint& aPoint ); - - static std::string FormatInternalUnits( const wxSize& aSize ); - private: /** * Function doIsConnected diff --git a/include/base_units.h b/include/base_units.h index 20450115c6..ead4ef00f8 100644 --- a/include/base_units.h +++ b/include/base_units.h @@ -2,8 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2012 CERN - * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. - * + * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -33,10 +32,13 @@ #ifndef _BASE_UNITS_H_ #define _BASE_UNITS_H_ +#include +#include #include #include +//TODO: Abstract Base Units to a single class /** * Used for holding indeterminate values, such as with multiple selections @@ -176,5 +178,35 @@ void FetchUnitsFromString( const wxString& aTextValue, EDA_UNITS_T& aUnits, bool */ wxString GetAbbreviatedUnitsLabel( EDA_UNITS_T aUnit, bool aUseMils = false ); +/** + * Function FormatInternalUnits + * converts \a aValue from internal units to a string appropriate for writing + * to file. + * + * @note Internal units for board items can be either deci-mils or nanometers depending + * on how KiCad is built. + * + * @param aValue A coordinate value to convert. + * @return A std::string object containing the converted value. + */ +std::string FormatInternalUnits( int aValue ); + +/** + * Function FormatAngle + * converts \a aAngle from board units to a string appropriate for writing to file. + * + * @note Internal angles for board items can be either degrees or tenths of degree + * on how KiCad is built. + * @param aAngle A angle value to convert. + * @return A std::string object containing the converted angle. + */ +std::string FormatAngle( double aAngle ); + +std::string FormatInternalUnits( const wxPoint& aPoint ); + +std::string FormatInternalUnits( const wxSize& aSize ); + +std::string FormatInternalUnits( const VECTOR2I& aPoint ); + #endif // _BASE_UNITS_H_ diff --git a/include/class_board_item.h b/include/class_board_item.h index 53ee8e6345..92b01463ac 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -308,34 +308,6 @@ public: } - /** - * Function FormatInternalUnits - * converts \a aValue from board internal units to a string appropriate for writing to file. - * - * @note Internal units for board items can be either deci-mils or nanometers depending - * on how KiCad is build. - * @param aValue A coordinate value to convert. - * @return A std::string object containing the converted value. - */ - static std::string FormatInternalUnits( int aValue ); - - /** - * Function FormatAngle - * converts \a aAngle from board units to a string appropriate for writing to file. - * - * @note Internal angles for board items can be either degrees or tenths of degree - * on how KiCad is built. - * @param aAngle A angle value to convert. - * @return A std::string object containing the converted angle. - */ - static std::string FormatAngle( double aAngle ); - - static std::string FormatInternalUnits( const wxPoint& aPoint ); - - static std::string FormatInternalUnits( const VECTOR2I& aPoint ); - - static std::string FormatInternalUnits( const wxSize& aSize ); - virtual void ViewGetLayers( int aLayers[], int& aCount ) const override; /** diff --git a/include/unit_format.h b/include/unit_format.h deleted file mode 100644 index 4cf5c71728..0000000000 --- a/include/unit_format.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2017 KiCad Developers, see change_log.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 - */ - -#ifndef UNIT_FORMAT_H -#define UNIT_FORMAT_H - -// Conversion to application internal units defined at build time. -#if defined( PCBNEW ) - #include - #define FMT_IU BOARD_ITEM::FormatInternalUnits - #define FMT_ANGLE BOARD_ITEM::FormatAngle -#elif defined( EESCHEMA ) - #include - #define FMT_IU SCH_ITEM::FormatInternalUnits - #define FMT_ANGLE SCH_ITEM::FormatAngle -#elif defined( GERBVIEW ) -#elif defined( PL_EDITOR ) - #include - #define FMT_IU Double2Str -#else -#error "Cannot resolve units formatting due to no definition of EESCHEMA or PCBNEW." -#endif - -#endif /* UNIT_FORMAT_H */ diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 1f5d2b6ceb..87e604c6f7 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -340,9 +340,9 @@ static void checkConnectedTo( BOARD* aBoard, TRACKS* aList, const TRACKS& aTrack { std::string m = StrPrintf( "intervening pad at:(xy %s) between start:(xy %s) and goal:(xy %s)", - BOARD_ITEM::FormatInternalUnits( next ).c_str(), - BOARD_ITEM::FormatInternalUnits( aStart ).c_str(), - BOARD_ITEM::FormatInternalUnits( aGoal ).c_str() + FormatInternalUnits( next ).c_str(), + FormatInternalUnits( aStart ).c_str(), + FormatInternalUnits( aGoal ).c_str() ); THROW_IO_ERROR( m ); } @@ -354,7 +354,7 @@ static void checkConnectedTo( BOARD* aBoard, TRACKS* aList, const TRACKS& aTrack std::string m = StrPrintf( "found %d tracks intersecting at (xy %s), exactly 2 would be acceptable.", track_count + aList->size() == 1 ? 1 : 0, - BOARD_ITEM::FormatInternalUnits( next ).c_str() + FormatInternalUnits( next ).c_str() ); THROW_IO_ERROR( m ); } @@ -367,8 +367,8 @@ static void checkConnectedTo( BOARD* aBoard, TRACKS* aList, const TRACKS& aTrack std::string m = StrPrintf( "not enough tracks connecting start:(xy %s) and goal:(xy %s).", - BOARD_ITEM::FormatInternalUnits( aStart ).c_str(), - BOARD_ITEM::FormatInternalUnits( aGoal ).c_str() + FormatInternalUnits( aStart ).c_str(), + FormatInternalUnits( aGoal ).c_str() ); THROW_IO_ERROR( m ); } @@ -412,8 +412,8 @@ TRACKS BOARD::TracksInNetBetweenPoints( const wxPoint& aStartPos, const wxPoint& wxString m = wxString::Format( "no clean path connecting start:(xy %s) with goal:(xy %s)", - BOARD_ITEM::FormatInternalUnits( aStartPos ).c_str(), - BOARD_ITEM::FormatInternalUnits( aGoalPos ).c_str() + FormatInternalUnits( aStartPos ).c_str(), + FormatInternalUnits( aGoalPos ).c_str() ); THROW_IO_ERROR( m + per_path_problem_text ); diff --git a/pcbnew/class_board_item.cpp b/pcbnew/class_board_item.cpp index e1ad270924..b9190edc8f 100644 --- a/pcbnew/class_board_item.cpp +++ b/pcbnew/class_board_item.cpp @@ -87,115 +87,6 @@ wxString BOARD_ITEM::GetLayerName() const } -std::string BOARD_ITEM::FormatInternalUnits( int aValue ) -{ -#if 1 - - char buf[50]; - int len; - double mm = aValue / IU_PER_MM; - - if( mm != 0.0 && fabs( mm ) <= 0.0001 ) - { - len = sprintf( buf, "%.10f", mm ); - - while( --len > 0 && buf[len] == '0' ) - buf[len] = '\0'; - - if( buf[len] == '.' ) - buf[len] = '\0'; - else - ++len; - } - else - { - len = sprintf( buf, "%.10g", mm ); - } - - return std::string( buf, len ); - -#else - - // Assume aValue is in nanometers, and that we want the result in millimeters, - // and that int is 32 bits wide. Then perform an alternative algorithm. - // Can be used to verify that the above algorithm is correctly generating text. - // Convert aValue into an integer string, then insert a decimal point manually. - // Results are the same as above general purpose algorithm. - - wxASSERT( sizeof(int) == 4 ); - - if( aValue == 0 ) - return std::string( 1, '0' ); - else - { - char buf[50]; - int len = sprintf( buf, aValue > 0 ? "%06d" : "%07d", aValue ); // optionally pad w/leading zeros - - std::string ret( buf, len ); - - std::string::iterator it = ret.end() - 1; // last byte - - // insert '.' at 6 positions from end, dividing by 10e6 (a million), nm => mm - std::string::iterator decpoint = ret.end() - 6; - - // truncate trailing zeros, up to decimal point position - for( ; *it=='0' && it >= decpoint; --it ) - ret.erase( it ); // does not invalidate iterators it or decpoint - - if( it >= decpoint ) - { - ret.insert( decpoint, '.' ); - - // decpoint is invalidated here, after insert() - -#if 1 // want a leading zero when decimal point is in first position? - if( ret[0] == '.' ) - { - // insert leading zero ahead of decimal point. - ret.insert( ret.begin(), '0' ); - } - else if( ret[0]=='-' && ret[1]=='.' ) - { - ret.insert( ret.begin() + 1, '0' ); - } -#endif - } - - return ret; - } - -#endif -} - - -std::string BOARD_ITEM::FormatAngle( double aAngle ) -{ - char temp[50]; - - int len = snprintf( temp, sizeof(temp), "%.10g", aAngle / 10.0 ); - - return std::string( temp, len ); -} - - -std::string BOARD_ITEM::FormatInternalUnits( const wxPoint& aPoint ) -{ - return FormatInternalUnits( aPoint.x ) + " " + FormatInternalUnits( aPoint.y ); -} - - -std::string BOARD_ITEM::FormatInternalUnits( const VECTOR2I& aPoint ) -{ - return FormatInternalUnits( aPoint.x ) + " " + FormatInternalUnits( aPoint.y ); -} - - -std::string BOARD_ITEM::FormatInternalUnits( const wxSize& aSize ) -{ - return FormatInternalUnits( aSize.GetWidth() ) + " " + FormatInternalUnits( aSize.GetHeight() ); -} - - void BOARD_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const { // Basic fallback diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp index c2bd7eeb27..9ca1cd7467 100644 --- a/pcbnew/dialogs/dialog_pad_properties.cpp +++ b/pcbnew/dialogs/dialog_pad_properties.cpp @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -798,7 +797,7 @@ void DIALOG_PAD_PROPERTIES::displayPrimitivesList() bs_info[0] = _( "Arc" ); bs_info[1] = _( "center " ) + formatCoord( m_units, primitive.m_Start );// Center bs_info[2] = _( "start " ) + formatCoord( m_units, primitive.m_End ); // Start point - bs_info[3] = wxString::Format( _( "angle %s" ), FMT_ANGLE( primitive.m_ArcAngle ) ); + bs_info[3] = wxString::Format( _( "angle %s" ), FormatAngle( primitive.m_ArcAngle ) ); break; case S_CIRCLE: // ring or circle diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 2c40cd6681..df0ec7a155 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -54,9 +54,6 @@ using namespace PCB_KEYS_T; -#define FMT_IU BOARD_ITEM::FormatInternalUnits -#define FMT_ANGLE BOARD_ITEM::FormatAngle - ///> Removes empty nets (i.e. with node count equal zero) from net classes void filterNetClass( const BOARD& aBoard, NETCLASS& aNetClass ) @@ -477,109 +474,109 @@ void PCB_IO::formatSetup( BOARD* aBoard, int aNestLevel ) const // Save current default track width, for compatibility with older Pcbnew version; m_out->Print( aNestLevel+1, "(last_trace_width %s)\n", - FMT_IU( dsnSettings.GetCurrentTrackWidth() ).c_str() ); + FormatInternalUnits( dsnSettings.GetCurrentTrackWidth() ).c_str() ); // Save custom tracks width list (the first is not saved here: this is the netclass value for( unsigned ii = 1; ii < dsnSettings.m_TrackWidthList.size(); ii++ ) m_out->Print( aNestLevel+1, "(user_trace_width %s)\n", - FMT_IU( dsnSettings.m_TrackWidthList[ii] ).c_str() ); + FormatInternalUnits( dsnSettings.m_TrackWidthList[ii] ).c_str() ); m_out->Print( aNestLevel+1, "(trace_clearance %s)\n", - FMT_IU( dsnSettings.GetDefault()->GetClearance() ).c_str() ); + FormatInternalUnits( dsnSettings.GetDefault()->GetClearance() ).c_str() ); // ZONE_SETTINGS m_out->Print( aNestLevel+1, "(zone_clearance %s)\n", - FMT_IU( aBoard->GetZoneSettings().m_ZoneClearance ).c_str() ); + FormatInternalUnits( aBoard->GetZoneSettings().m_ZoneClearance ).c_str() ); m_out->Print( aNestLevel+1, "(zone_45_only %s)\n", aBoard->GetZoneSettings().m_Zone_45_Only ? "yes" : "no" ); m_out->Print( aNestLevel+1, "(trace_min %s)\n", - FMT_IU( dsnSettings.m_TrackMinWidth ).c_str() ); + FormatInternalUnits( dsnSettings.m_TrackMinWidth ).c_str() ); // Save current default via size, for compatibility with older Pcbnew version; m_out->Print( aNestLevel+1, "(via_size %s)\n", - FMT_IU( dsnSettings.GetDefault()->GetViaDiameter() ).c_str() ); + FormatInternalUnits( dsnSettings.GetDefault()->GetViaDiameter() ).c_str() ); m_out->Print( aNestLevel+1, "(via_drill %s)\n", - FMT_IU( dsnSettings.GetDefault()->GetViaDrill() ).c_str() ); + FormatInternalUnits( dsnSettings.GetDefault()->GetViaDrill() ).c_str() ); m_out->Print( aNestLevel+1, "(via_min_size %s)\n", - FMT_IU( dsnSettings.m_ViasMinSize ).c_str() ); + FormatInternalUnits( dsnSettings.m_ViasMinSize ).c_str() ); m_out->Print( aNestLevel+1, "(via_min_drill %s)\n", - FMT_IU( dsnSettings.m_ViasMinDrill ).c_str() ); + FormatInternalUnits( dsnSettings.m_ViasMinDrill ).c_str() ); // Save custom vias diameters list (the first is not saved here: this is // the netclass value for( unsigned ii = 1; ii < dsnSettings.m_ViasDimensionsList.size(); ii++ ) m_out->Print( aNestLevel+1, "(user_via %s %s)\n", - FMT_IU( dsnSettings.m_ViasDimensionsList[ii].m_Diameter ).c_str(), - FMT_IU( dsnSettings.m_ViasDimensionsList[ii].m_Drill ).c_str() ); + FormatInternalUnits( dsnSettings.m_ViasDimensionsList[ii].m_Diameter ).c_str(), + FormatInternalUnits( dsnSettings.m_ViasDimensionsList[ii].m_Drill ).c_str() ); // for old versions compatibility: if( dsnSettings.m_BlindBuriedViaAllowed ) m_out->Print( aNestLevel+1, "(blind_buried_vias_allowed yes)\n" ); m_out->Print( aNestLevel+1, "(uvia_size %s)\n", - FMT_IU( dsnSettings.GetDefault()->GetuViaDiameter() ).c_str() ); + FormatInternalUnits( dsnSettings.GetDefault()->GetuViaDiameter() ).c_str() ); m_out->Print( aNestLevel+1, "(uvia_drill %s)\n", - FMT_IU( dsnSettings.GetDefault()->GetuViaDrill() ).c_str() ); + FormatInternalUnits( dsnSettings.GetDefault()->GetuViaDrill() ).c_str() ); m_out->Print( aNestLevel+1, "(uvias_allowed %s)\n", ( dsnSettings.m_MicroViasAllowed ) ? "yes" : "no" ); m_out->Print( aNestLevel+1, "(uvia_min_size %s)\n", - FMT_IU( dsnSettings.m_MicroViasMinSize ).c_str() ); + FormatInternalUnits( dsnSettings.m_MicroViasMinSize ).c_str() ); m_out->Print( aNestLevel+1, "(uvia_min_drill %s)\n", - FMT_IU( dsnSettings.m_MicroViasMinDrill ).c_str() ); + FormatInternalUnits( dsnSettings.m_MicroViasMinDrill ).c_str() ); // 6.0 TODO: are we going to update the tokens we save these under? // 6.0 TODO: need to save the LAYER_CLASS_OTHERS stuff // 6.0 TODO: need to save the TextItalic and TextUpright settings m_out->Print( aNestLevel+1, "(edge_width %s)\n", - FMT_IU( dsnSettings.m_LineThickness[ LAYER_CLASS_EDGES ] ).c_str() ); + FormatInternalUnits( dsnSettings.m_LineThickness[ LAYER_CLASS_EDGES ] ).c_str() ); m_out->Print( aNestLevel+1, "(segment_width %s)\n", - FMT_IU( dsnSettings.m_LineThickness[ LAYER_CLASS_COPPER ] ).c_str() ); + FormatInternalUnits( dsnSettings.m_LineThickness[ LAYER_CLASS_COPPER ] ).c_str() ); m_out->Print( aNestLevel+1, "(pcb_text_width %s)\n", - FMT_IU( dsnSettings.m_TextThickness[ LAYER_CLASS_COPPER ] ).c_str() ); + FormatInternalUnits( dsnSettings.m_TextThickness[ LAYER_CLASS_COPPER ] ).c_str() ); m_out->Print( aNestLevel+1, "(pcb_text_size %s %s)\n", - FMT_IU( dsnSettings.m_TextSize[ LAYER_CLASS_COPPER ].x ).c_str(), - FMT_IU( dsnSettings.m_TextSize[ LAYER_CLASS_COPPER ].y ).c_str() ); + FormatInternalUnits( dsnSettings.m_TextSize[ LAYER_CLASS_COPPER ].x ).c_str(), + FormatInternalUnits( dsnSettings.m_TextSize[ LAYER_CLASS_COPPER ].y ).c_str() ); m_out->Print( aNestLevel+1, "(mod_edge_width %s)\n", - FMT_IU( dsnSettings.m_LineThickness[ LAYER_CLASS_SILK ] ).c_str() ); + FormatInternalUnits( dsnSettings.m_LineThickness[ LAYER_CLASS_SILK ] ).c_str() ); m_out->Print( aNestLevel+1, "(mod_text_size %s %s)\n", - FMT_IU( dsnSettings.m_TextSize[ LAYER_CLASS_SILK ].x ).c_str(), - FMT_IU( dsnSettings.m_TextSize[ LAYER_CLASS_SILK ].y ).c_str() ); + FormatInternalUnits( dsnSettings.m_TextSize[ LAYER_CLASS_SILK ].x ).c_str(), + FormatInternalUnits( dsnSettings.m_TextSize[ LAYER_CLASS_SILK ].y ).c_str() ); m_out->Print( aNestLevel+1, "(mod_text_width %s)\n", - FMT_IU( dsnSettings.m_TextThickness[ LAYER_CLASS_SILK ] ).c_str() ); + FormatInternalUnits( dsnSettings.m_TextThickness[ LAYER_CLASS_SILK ] ).c_str() ); m_out->Print( aNestLevel+1, "(pad_size %s %s)\n", - FMT_IU( dsnSettings.m_Pad_Master.GetSize().x ).c_str(), - FMT_IU( dsnSettings.m_Pad_Master.GetSize().y ).c_str() ); + FormatInternalUnits( dsnSettings.m_Pad_Master.GetSize().x ).c_str(), + FormatInternalUnits( dsnSettings.m_Pad_Master.GetSize().y ).c_str() ); m_out->Print( aNestLevel+1, "(pad_drill %s)\n", - FMT_IU( dsnSettings.m_Pad_Master.GetDrillSize().x ).c_str() ); + FormatInternalUnits( dsnSettings.m_Pad_Master.GetDrillSize().x ).c_str() ); m_out->Print( aNestLevel+1, "(pad_to_mask_clearance %s)\n", - FMT_IU( dsnSettings.m_SolderMaskMargin ).c_str() ); + FormatInternalUnits( dsnSettings.m_SolderMaskMargin ).c_str() ); if( dsnSettings.m_SolderMaskMinWidth ) m_out->Print( aNestLevel+1, "(solder_mask_min_width %s)\n", - FMT_IU( dsnSettings.m_SolderMaskMinWidth ).c_str() ); + FormatInternalUnits( dsnSettings.m_SolderMaskMinWidth ).c_str() ); if( dsnSettings.m_SolderPasteMargin != 0 ) m_out->Print( aNestLevel+1, "(pad_to_paste_clearance %s)\n", - FMT_IU( dsnSettings.m_SolderPasteMargin ).c_str() ); + FormatInternalUnits( dsnSettings.m_SolderPasteMargin ).c_str() ); if( dsnSettings.m_SolderPasteMarginRatio != 0 ) m_out->Print( aNestLevel+1, "(pad_to_paste_clearance_ratio %s)\n", Double2Str( dsnSettings.m_SolderPasteMarginRatio ).c_str() ); m_out->Print( aNestLevel+1, "(aux_axis_origin %s %s)\n", - FMT_IU( aBoard->GetAuxOrigin().x ).c_str(), - FMT_IU( aBoard->GetAuxOrigin().y ).c_str() ); + FormatInternalUnits( aBoard->GetAuxOrigin().x ).c_str(), + FormatInternalUnits( aBoard->GetAuxOrigin().y ).c_str() ); if( aBoard->GetGridOrigin().x || aBoard->GetGridOrigin().y ) m_out->Print( aNestLevel+1, "(grid_origin %s %s)\n", - FMT_IU( aBoard->GetGridOrigin().x ).c_str(), - FMT_IU( aBoard->GetGridOrigin().y ).c_str() ); + FormatInternalUnits( aBoard->GetGridOrigin().x ).c_str(), + FormatInternalUnits( aBoard->GetGridOrigin().y ).c_str() ); m_out->Print( aNestLevel+1, "(visible_elements %X)\n", dsnSettings.GetVisibleElements() ); @@ -598,7 +595,7 @@ void PCB_IO::formatGeneral( BOARD* aBoard, int aNestLevel ) const m_out->Print( aNestLevel, "(general\n" ); // Write Bounding box info m_out->Print( aNestLevel+1, "(thickness %s)\n", - FMT_IU( dsnSettings.GetBoardThickness() ).c_str() ); + FormatInternalUnits( dsnSettings.GetBoardThickness() ).c_str() ); m_out->Print( aNestLevel+1, "(drawings %d)\n", aBoard->Drawings().Size() ); m_out->Print( aNestLevel+1, "(tracks %d)\n", aBoard->GetNumSegmTrack() ); @@ -754,8 +751,8 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const void PCB_IO::format( DIMENSION* aDimension, int aNestLevel ) const { m_out->Print( aNestLevel, "(dimension %s (width %s)", - FMT_IU( aDimension->GetValue() ).c_str(), - FMT_IU( aDimension->GetWidth() ).c_str() ); + FormatInternalUnits( aDimension->GetValue() ).c_str(), + FormatInternalUnits( aDimension->GetWidth() ).c_str() ); formatLayer( aDimension ); @@ -767,46 +764,46 @@ void PCB_IO::format( DIMENSION* aDimension, int aNestLevel ) const Format( &aDimension->Text(), aNestLevel+1 ); m_out->Print( aNestLevel+1, "(feature1 (pts (xy %s %s) (xy %s %s)))\n", - FMT_IU( aDimension->m_featureLineDO.x ).c_str(), - FMT_IU( aDimension->m_featureLineDO.y ).c_str(), - FMT_IU( aDimension->m_featureLineDF.x ).c_str(), - FMT_IU( aDimension->m_featureLineDF.y ).c_str() ); + FormatInternalUnits( aDimension->m_featureLineDO.x ).c_str(), + FormatInternalUnits( aDimension->m_featureLineDO.y ).c_str(), + FormatInternalUnits( aDimension->m_featureLineDF.x ).c_str(), + FormatInternalUnits( aDimension->m_featureLineDF.y ).c_str() ); m_out->Print( aNestLevel+1, "(feature2 (pts (xy %s %s) (xy %s %s)))\n", - FMT_IU( aDimension->m_featureLineGO.x ).c_str(), - FMT_IU( aDimension->m_featureLineGO.y ).c_str(), - FMT_IU( aDimension->m_featureLineGF.x ).c_str(), - FMT_IU( aDimension->m_featureLineGF.y ).c_str() ); + FormatInternalUnits( aDimension->m_featureLineGO.x ).c_str(), + FormatInternalUnits( aDimension->m_featureLineGO.y ).c_str(), + FormatInternalUnits( aDimension->m_featureLineGF.x ).c_str(), + FormatInternalUnits( aDimension->m_featureLineGF.y ).c_str() ); m_out->Print( aNestLevel+1, "(crossbar (pts (xy %s %s) (xy %s %s)))\n", - FMT_IU( aDimension->m_crossBarO.x ).c_str(), - FMT_IU( aDimension->m_crossBarO.y ).c_str(), - FMT_IU( aDimension->m_crossBarF.x ).c_str(), - FMT_IU( aDimension->m_crossBarF.y ).c_str() ); + FormatInternalUnits( aDimension->m_crossBarO.x ).c_str(), + FormatInternalUnits( aDimension->m_crossBarO.y ).c_str(), + FormatInternalUnits( aDimension->m_crossBarF.x ).c_str(), + FormatInternalUnits( aDimension->m_crossBarF.y ).c_str() ); m_out->Print( aNestLevel+1, "(arrow1a (pts (xy %s %s) (xy %s %s)))\n", - FMT_IU( aDimension->m_crossBarF.x ).c_str(), - FMT_IU( aDimension->m_crossBarF.y ).c_str(), - FMT_IU( aDimension->m_arrowD1F.x ).c_str(), - FMT_IU( aDimension->m_arrowD1F.y ).c_str() ); + FormatInternalUnits( aDimension->m_crossBarF.x ).c_str(), + FormatInternalUnits( aDimension->m_crossBarF.y ).c_str(), + FormatInternalUnits( aDimension->m_arrowD1F.x ).c_str(), + FormatInternalUnits( aDimension->m_arrowD1F.y ).c_str() ); m_out->Print( aNestLevel+1, "(arrow1b (pts (xy %s %s) (xy %s %s)))\n", - FMT_IU( aDimension->m_crossBarF.x ).c_str(), - FMT_IU( aDimension->m_crossBarF.y ).c_str(), - FMT_IU( aDimension->m_arrowD2F.x ).c_str(), - FMT_IU( aDimension->m_arrowD2F.y ).c_str() ); + FormatInternalUnits( aDimension->m_crossBarF.x ).c_str(), + FormatInternalUnits( aDimension->m_crossBarF.y ).c_str(), + FormatInternalUnits( aDimension->m_arrowD2F.x ).c_str(), + FormatInternalUnits( aDimension->m_arrowD2F.y ).c_str() ); m_out->Print( aNestLevel+1, "(arrow2a (pts (xy %s %s) (xy %s %s)))\n", - FMT_IU( aDimension->m_crossBarO.x ).c_str(), - FMT_IU( aDimension->m_crossBarO.y ).c_str(), - FMT_IU( aDimension->m_arrowG1F.x ).c_str(), - FMT_IU( aDimension->m_arrowG1F.y ).c_str() ); + FormatInternalUnits( aDimension->m_crossBarO.x ).c_str(), + FormatInternalUnits( aDimension->m_crossBarO.y ).c_str(), + FormatInternalUnits( aDimension->m_arrowG1F.x ).c_str(), + FormatInternalUnits( aDimension->m_arrowG1F.y ).c_str() ); m_out->Print( aNestLevel+1, "(arrow2b (pts (xy %s %s) (xy %s %s)))\n", - FMT_IU( aDimension->m_crossBarO.x ).c_str(), - FMT_IU( aDimension->m_crossBarO.y ).c_str(), - FMT_IU( aDimension->m_arrowG2F.x ).c_str(), - FMT_IU( aDimension->m_arrowG2F.y ).c_str() ); + FormatInternalUnits( aDimension->m_crossBarO.x ).c_str(), + FormatInternalUnits( aDimension->m_crossBarO.y ).c_str(), + FormatInternalUnits( aDimension->m_arrowG2F.x ).c_str(), + FormatInternalUnits( aDimension->m_arrowG2F.y ).c_str() ); m_out->Print( aNestLevel, ")\n" ); } @@ -818,25 +815,25 @@ void PCB_IO::format( DRAWSEGMENT* aSegment, int aNestLevel ) const { case S_SEGMENT: // Line m_out->Print( aNestLevel, "(gr_line (start %s) (end %s)", - FMT_IU( aSegment->GetStart() ).c_str(), - FMT_IU( aSegment->GetEnd() ).c_str() ); + FormatInternalUnits( aSegment->GetStart() ).c_str(), + FormatInternalUnits( aSegment->GetEnd() ).c_str() ); if( aSegment->GetAngle() != 0.0 ) - m_out->Print( 0, " (angle %s)", FMT_ANGLE( aSegment->GetAngle() ).c_str() ); + m_out->Print( 0, " (angle %s)", FormatAngle( aSegment->GetAngle() ).c_str() ); break; case S_CIRCLE: // Circle m_out->Print( aNestLevel, "(gr_circle (center %s) (end %s)", - FMT_IU( aSegment->GetStart() ).c_str(), - FMT_IU( aSegment->GetEnd() ).c_str() ); + FormatInternalUnits( aSegment->GetStart() ).c_str(), + FormatInternalUnits( aSegment->GetEnd() ).c_str() ); break; case S_ARC: // Arc m_out->Print( aNestLevel, "(gr_arc (start %s) (end %s) (angle %s)", - FMT_IU( aSegment->GetStart() ).c_str(), - FMT_IU( aSegment->GetEnd() ).c_str(), - FMT_ANGLE( aSegment->GetAngle() ).c_str() ); + FormatInternalUnits( aSegment->GetStart() ).c_str(), + FormatInternalUnits( aSegment->GetEnd() ).c_str(), + FormatAngle( aSegment->GetAngle() ).c_str() ); break; case S_POLYGON: // Polygon @@ -850,7 +847,7 @@ void PCB_IO::format( DRAWSEGMENT* aSegment, int aNestLevel ) const for( int ii = 0; ii < pointsCount; ++ii ) { - m_out->Print( 0, " (xy %s)", FMT_IU( outline.CPoint( ii ) ).c_str() ); + m_out->Print( 0, " (xy %s)", FormatInternalUnits( outline.CPoint( ii ) ).c_str() ); } m_out->Print( 0, ")" ); @@ -865,10 +862,10 @@ void PCB_IO::format( DRAWSEGMENT* aSegment, int aNestLevel ) const case S_CURVE: // Bezier curve m_out->Print( aNestLevel, "(gr_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))", - FMT_IU( aSegment->GetStart() ).c_str(), - FMT_IU( aSegment->GetBezControl1() ).c_str(), - FMT_IU( aSegment->GetBezControl2() ).c_str(), - FMT_IU( aSegment->GetEnd() ).c_str() ); + FormatInternalUnits( aSegment->GetStart() ).c_str(), + FormatInternalUnits( aSegment->GetBezControl1() ).c_str(), + FormatInternalUnits( aSegment->GetBezControl2() ).c_str(), + FormatInternalUnits( aSegment->GetEnd() ).c_str() ); break; default: @@ -878,7 +875,7 @@ void PCB_IO::format( DRAWSEGMENT* aSegment, int aNestLevel ) const formatLayer( aSegment ); - m_out->Print( 0, " (width %s)", FMT_IU( aSegment->GetWidth() ).c_str() ); + m_out->Print( 0, " (width %s)", FormatInternalUnits( aSegment->GetWidth() ).c_str() ); if( aSegment->GetTimeStamp() ) m_out->Print( 0, " (tstamp %lX)", (unsigned long)aSegment->GetTimeStamp() ); @@ -896,21 +893,21 @@ void PCB_IO::format( EDGE_MODULE* aModuleDrawing, int aNestLevel ) const { case S_SEGMENT: // Line m_out->Print( aNestLevel, "(fp_line (start %s) (end %s)", - FMT_IU( aModuleDrawing->GetStart0() ).c_str(), - FMT_IU( aModuleDrawing->GetEnd0() ).c_str() ); + FormatInternalUnits( aModuleDrawing->GetStart0() ).c_str(), + FormatInternalUnits( aModuleDrawing->GetEnd0() ).c_str() ); break; case S_CIRCLE: // Circle m_out->Print( aNestLevel, "(fp_circle (center %s) (end %s)", - FMT_IU( aModuleDrawing->GetStart0() ).c_str(), - FMT_IU( aModuleDrawing->GetEnd0() ).c_str() ); + FormatInternalUnits( aModuleDrawing->GetStart0() ).c_str(), + FormatInternalUnits( aModuleDrawing->GetEnd0() ).c_str() ); break; case S_ARC: // Arc m_out->Print( aNestLevel, "(fp_arc (start %s) (end %s) (angle %s)", - FMT_IU( aModuleDrawing->GetStart0() ).c_str(), - FMT_IU( aModuleDrawing->GetEnd0() ).c_str(), - FMT_ANGLE( aModuleDrawing->GetAngle() ).c_str() ); + FormatInternalUnits( aModuleDrawing->GetStart0() ).c_str(), + FormatInternalUnits( aModuleDrawing->GetEnd0() ).c_str(), + FormatAngle( aModuleDrawing->GetAngle() ).c_str() ); break; case S_POLYGON: // Polygonal segment @@ -933,7 +930,7 @@ void PCB_IO::format( EDGE_MODULE* aModuleDrawing, int aNestLevel ) const } m_out->Print( nestLevel, "%s(xy %s)", - nestLevel ? "" : " ", FMT_IU( outline.CPoint( ii ) ).c_str() ); + nestLevel ? "" : " ", FormatInternalUnits( outline.CPoint( ii ) ).c_str() ); } m_out->Print( 0, ")" ); @@ -947,10 +944,10 @@ void PCB_IO::format( EDGE_MODULE* aModuleDrawing, int aNestLevel ) const case S_CURVE: // Bezier curve m_out->Print( aNestLevel, "(fp_curve (pts (xy %s) (xy %s) (xy %s) (xy %s))", - FMT_IU( aModuleDrawing->GetStart0() ).c_str(), - FMT_IU( aModuleDrawing->GetBezier0_C1() ).c_str(), - FMT_IU( aModuleDrawing->GetBezier0_C2() ).c_str(), - FMT_IU( aModuleDrawing->GetEnd0() ).c_str() ); + FormatInternalUnits( aModuleDrawing->GetStart0() ).c_str(), + FormatInternalUnits( aModuleDrawing->GetBezier0_C1() ).c_str(), + FormatInternalUnits( aModuleDrawing->GetBezier0_C2() ).c_str(), + FormatInternalUnits( aModuleDrawing->GetEnd0() ).c_str() ); break; default: @@ -960,7 +957,7 @@ void PCB_IO::format( EDGE_MODULE* aModuleDrawing, int aNestLevel ) const formatLayer( aModuleDrawing ); - m_out->Print( 0, " (width %s)", FMT_IU( aModuleDrawing->GetWidth() ).c_str() ); + m_out->Print( 0, " (width %s)", FormatInternalUnits( aModuleDrawing->GetWidth() ).c_str() ); m_out->Print( 0, ")\n" ); } @@ -970,11 +967,11 @@ void PCB_IO::format( PCB_TARGET* aTarget, int aNestLevel ) const { m_out->Print( aNestLevel, "(target %s (at %s) (size %s)", ( aTarget->GetShape() ) ? "x" : "plus", - FMT_IU( aTarget->GetPosition() ).c_str(), - FMT_IU( aTarget->GetSize() ).c_str() ); + FormatInternalUnits( aTarget->GetPosition() ).c_str(), + FormatInternalUnits( aTarget->GetSize() ).c_str() ); if( aTarget->GetWidth() != 0 ) - m_out->Print( 0, " (width %s)", FMT_IU( aTarget->GetWidth() ).c_str() ); + m_out->Print( 0, " (width %s)", FormatInternalUnits( aTarget->GetWidth() ).c_str() ); formatLayer( aTarget ); @@ -1022,10 +1019,10 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const if( !( m_ctl & CTL_OMIT_AT ) ) { - m_out->Print( aNestLevel+1, "(at %s", FMT_IU( aModule->GetPosition() ).c_str() ); + m_out->Print( aNestLevel+1, "(at %s", FormatInternalUnits( aModule->GetPosition() ).c_str() ); if( aModule->GetOrientation() != 0.0 ) - m_out->Print( 0, " %s", FMT_ANGLE( aModule->GetOrientation() ).c_str() ); + m_out->Print( 0, " %s", FormatAngle( aModule->GetOrientation() ).c_str() ); m_out->Print( 0, ")\n" ); } @@ -1050,11 +1047,11 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const if( aModule->GetLocalSolderMaskMargin() != 0 ) m_out->Print( aNestLevel+1, "(solder_mask_margin %s)\n", - FMT_IU( aModule->GetLocalSolderMaskMargin() ).c_str() ); + FormatInternalUnits( aModule->GetLocalSolderMaskMargin() ).c_str() ); if( aModule->GetLocalSolderPasteMargin() != 0 ) m_out->Print( aNestLevel+1, "(solder_paste_margin %s)\n", - FMT_IU( aModule->GetLocalSolderPasteMargin() ).c_str() ); + FormatInternalUnits( aModule->GetLocalSolderPasteMargin() ).c_str() ); if( aModule->GetLocalSolderPasteMarginRatio() != 0 ) m_out->Print( aNestLevel+1, "(solder_paste_ratio %s)\n", @@ -1062,18 +1059,18 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const if( aModule->GetLocalClearance() != 0 ) m_out->Print( aNestLevel+1, "(clearance %s)\n", - FMT_IU( aModule->GetLocalClearance() ).c_str() ); + FormatInternalUnits( aModule->GetLocalClearance() ).c_str() ); if( aModule->GetZoneConnection() != PAD_ZONE_CONN_INHERITED ) m_out->Print( aNestLevel+1, "(zone_connect %d)\n", aModule->GetZoneConnection() ); if( aModule->GetThermalWidth() != 0 ) m_out->Print( aNestLevel+1, "(thermal_width %s)\n", - FMT_IU( aModule->GetThermalWidth() ).c_str() ); + FormatInternalUnits( aModule->GetThermalWidth() ).c_str() ); if( aModule->GetThermalGap() != 0 ) m_out->Print( aNestLevel+1, "(thermal_gap %s)\n", - FMT_IU( aModule->GetThermalGap() ).c_str() ); + FormatInternalUnits( aModule->GetThermalGap() ).c_str() ); // Attributes if( aModule->GetAttributes() != MOD_DEFAULT ) @@ -1278,16 +1275,16 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const m_out->Print( aNestLevel, "(pad %s %s %s", m_out->Quotew( aPad->GetName() ).c_str(), type, shape ); - m_out->Print( 0, " (at %s", FMT_IU( aPad->GetPos0() ).c_str() ); + m_out->Print( 0, " (at %s", FormatInternalUnits( aPad->GetPos0() ).c_str() ); if( aPad->GetOrientation() != 0.0 ) - m_out->Print( 0, " %s", FMT_ANGLE( aPad->GetOrientation() ).c_str() ); + m_out->Print( 0, " %s", FormatAngle( aPad->GetOrientation() ).c_str() ); m_out->Print( 0, ")" ); - m_out->Print( 0, " (size %s)", FMT_IU( aPad->GetSize() ).c_str() ); + m_out->Print( 0, " (size %s)", FormatInternalUnits( aPad->GetSize() ).c_str() ); if( (aPad->GetDelta().GetWidth()) != 0 || (aPad->GetDelta().GetHeight() != 0 ) ) - m_out->Print( 0, " (rect_delta %s )", FMT_IU( aPad->GetDelta() ).c_str() ); + m_out->Print( 0, " (rect_delta %s )", FormatInternalUnits( aPad->GetDelta() ).c_str() ); wxSize sz = aPad->GetDrillSize(); wxPoint shapeoffset = aPad->GetOffset(); @@ -1301,13 +1298,13 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const m_out->Print( 0, " oval" ); if( sz.GetWidth() > 0 ) - m_out->Print( 0, " %s", FMT_IU( sz.GetWidth() ).c_str() ); + m_out->Print( 0, " %s", FormatInternalUnits( sz.GetWidth() ).c_str() ); if( sz.GetHeight() > 0 && sz.GetWidth() != sz.GetHeight() ) - m_out->Print( 0, " %s", FMT_IU( sz.GetHeight() ).c_str() ); + m_out->Print( 0, " %s", FormatInternalUnits( sz.GetHeight() ).c_str() ); if( (shapeoffset.x != 0) || (shapeoffset.y != 0) ) - m_out->Print( 0, " (offset %s)", FMT_IU( aPad->GetOffset() ).c_str() ); + m_out->Print( 0, " (offset %s)", FormatInternalUnits( aPad->GetOffset() ).c_str() ); m_out->Print( 0, ")" ); } @@ -1329,31 +1326,31 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const m_out->Quotew( aPad->GetNetname() ).c_str() ); if( aPad->GetPadToDieLength() != 0 ) - StrPrintf( &output, " (die_length %s)", FMT_IU( aPad->GetPadToDieLength() ).c_str() ); + StrPrintf( &output, " (die_length %s)", FormatInternalUnits( aPad->GetPadToDieLength() ).c_str() ); if( aPad->GetLocalSolderMaskMargin() != 0 ) StrPrintf( &output, " (solder_mask_margin %s)", - FMT_IU( aPad->GetLocalSolderMaskMargin() ).c_str() ); + FormatInternalUnits( aPad->GetLocalSolderMaskMargin() ).c_str() ); if( aPad->GetLocalSolderPasteMargin() != 0 ) StrPrintf( &output, " (solder_paste_margin %s)", - FMT_IU( aPad->GetLocalSolderPasteMargin() ).c_str() ); + FormatInternalUnits( aPad->GetLocalSolderPasteMargin() ).c_str() ); if( aPad->GetLocalSolderPasteMarginRatio() != 0 ) StrPrintf( &output, " (solder_paste_margin_ratio %s)", Double2Str( aPad->GetLocalSolderPasteMarginRatio() ).c_str() ); if( aPad->GetLocalClearance() != 0 ) - StrPrintf( &output, " (clearance %s)", FMT_IU( aPad->GetLocalClearance() ).c_str() ); + StrPrintf( &output, " (clearance %s)", FormatInternalUnits( aPad->GetLocalClearance() ).c_str() ); if( aPad->GetZoneConnection() != PAD_ZONE_CONN_INHERITED ) StrPrintf( &output, " (zone_connect %d)", aPad->GetZoneConnection() ); if( aPad->GetThermalWidth() != 0 ) - StrPrintf( &output, " (thermal_width %s)", FMT_IU( aPad->GetThermalWidth() ).c_str() ); + StrPrintf( &output, " (thermal_width %s)", FormatInternalUnits( aPad->GetThermalWidth() ).c_str() ); if( aPad->GetThermalGap() != 0 ) - StrPrintf( &output, " (thermal_gap %s)", FMT_IU( aPad->GetThermalGap() ).c_str() ); + StrPrintf( &output, " (thermal_gap %s)", FormatInternalUnits( aPad->GetThermalGap() ).c_str() ); if( output.size() ) { @@ -1400,25 +1397,25 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const { case S_SEGMENT: // usual segment : line with rounded ends m_out->Print( nested_level, "(gr_line (start %s) (end %s) (width %s))", - FMT_IU( primitive.m_Start ).c_str(), - FMT_IU( primitive.m_End ).c_str(), - FMT_IU( primitive.m_Thickness ).c_str() ); + FormatInternalUnits( primitive.m_Start ).c_str(), + FormatInternalUnits( primitive.m_End ).c_str(), + FormatInternalUnits( primitive.m_Thickness ).c_str() ); break; case S_ARC: // Arc with rounded ends m_out->Print( nested_level, "(gr_arc (start %s) (end %s) (angle %s) (width %s))", - FMT_IU( primitive.m_Start ).c_str(), - FMT_IU( primitive.m_End ).c_str(), - FMT_ANGLE( primitive.m_ArcAngle ).c_str(), - FMT_IU( primitive.m_Thickness ).c_str() ); + FormatInternalUnits( primitive.m_Start ).c_str(), + FormatInternalUnits( primitive.m_End ).c_str(), + FormatAngle( primitive.m_ArcAngle ).c_str(), + FormatInternalUnits( primitive.m_Thickness ).c_str() ); break; case S_CIRCLE: // ring or circle (circle if width == 0 m_out->Print( nested_level, "(gr_circle (center %s) (end %s %s) (width %s))", - FMT_IU( primitive.m_Start ).c_str(), - FMT_IU( primitive.m_Start.x + primitive.m_Radius ).c_str(), - FMT_IU( primitive.m_Start.y ).c_str(), - FMT_IU( primitive.m_Thickness ).c_str() ); + FormatInternalUnits( primitive.m_Start ).c_str(), + FormatInternalUnits( primitive.m_Start.x + primitive.m_Radius ).c_str(), + FormatInternalUnits( primitive.m_Start.y ).c_str(), + FormatInternalUnits( primitive.m_Thickness ).c_str() ); break; case S_POLYGON: // polygon @@ -1436,10 +1433,10 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const { if( newLine == 0 ) m_out->Print( nested_level+1, " (xy %s)", - FMT_IU( wxPoint( poly[ii].x, poly[ii].y ) ).c_str() ); + FormatInternalUnits( wxPoint( poly[ii].x, poly[ii].y ) ).c_str() ); else m_out->Print( 0, " (xy %s)", - FMT_IU( wxPoint( poly[ii].x, poly[ii].y ) ).c_str() ); + FormatInternalUnits( wxPoint( poly[ii].x, poly[ii].y ) ).c_str() ); if( ++newLine > 4 ) { @@ -1448,7 +1445,7 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const } } - m_out->Print( 0, ") (width %s))", FMT_IU( primitive.m_Thickness ).c_str() ); + m_out->Print( 0, ") (width %s))", FormatInternalUnits( primitive.m_Thickness ).c_str() ); } break; @@ -1469,10 +1466,10 @@ void PCB_IO::format( TEXTE_PCB* aText, int aNestLevel ) const { m_out->Print( aNestLevel, "(gr_text %s (at %s", m_out->Quotew( aText->GetText() ).c_str(), - FMT_IU( aText->GetTextPos() ).c_str() ); + FormatInternalUnits( aText->GetTextPos() ).c_str() ); if( aText->GetTextAngle() != 0.0 ) - m_out->Print( 0, " %s", FMT_ANGLE( aText->GetTextAngle() ).c_str() ); + m_out->Print( 0, " %s", FormatAngle( aText->GetTextAngle() ).c_str() ); m_out->Print( 0, ")" ); @@ -1503,7 +1500,7 @@ void PCB_IO::format( TEXTE_MODULE* aText, int aNestLevel ) const m_out->Print( aNestLevel, "(fp_text %s %s (at %s", m_out->Quotew( type ).c_str(), m_out->Quotew( aText->GetText() ).c_str(), - FMT_IU( aText->GetPos0() ).c_str() ); + FormatInternalUnits( aText->GetPos0() ).c_str() ); // Due to Pcbnew history, fp_text angle is saved as an absolute on screen angle, // but internally the angle is held relative to its parent footprint. parent @@ -1530,7 +1527,7 @@ void PCB_IO::format( TEXTE_MODULE* aText, int aNestLevel ) const } if( orient != 0.0 ) - m_out->Print( 0, " %s", FMT_ANGLE( orient ).c_str() ); + m_out->Print( 0, " %s", FormatAngle( orient ).c_str() ); if( !aText->IsKeepUpright() ) m_out->Print( 0, " unlocked" ); @@ -1583,11 +1580,11 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const } m_out->Print( 0, " (at %s) (size %s)", - FMT_IU( aTrack->GetStart() ).c_str(), - FMT_IU( aTrack->GetWidth() ).c_str() ); + FormatInternalUnits( aTrack->GetStart() ).c_str(), + FormatInternalUnits( aTrack->GetWidth() ).c_str() ); if( via->GetDrill() != UNDEFINED_DRILL_DIAMETER ) - m_out->Print( 0, " (drill %s)", FMT_IU( via->GetDrill() ).c_str() ); + m_out->Print( 0, " (drill %s)", FormatInternalUnits( via->GetDrill() ).c_str() ); m_out->Print( 0, " (layers %s %s)", m_out->Quotew( m_board->GetLayerName( layer1 ) ).c_str(), @@ -1596,8 +1593,8 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const else { m_out->Print( aNestLevel, "(segment (start %s) (end %s) (width %s)", - FMT_IU( aTrack->GetStart() ).c_str(), FMT_IU( aTrack->GetEnd() ).c_str(), - FMT_IU( aTrack->GetWidth() ).c_str() ); + FormatInternalUnits( aTrack->GetStart() ).c_str(), FormatInternalUnits( aTrack->GetEnd() ).c_str(), + FormatInternalUnits( aTrack->GetWidth() ).c_str() ); m_out->Print( 0, " (layer %s)", m_out->Quotew( aTrack->GetLayerName() ).c_str() ); } @@ -1647,7 +1644,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const } m_out->Print( 0, " (hatch %s %s)\n", hatch.c_str(), - FMT_IU( aZone->GetHatchPitch() ).c_str() ); + FormatInternalUnits( aZone->GetHatchPitch() ).c_str() ); if( aZone->GetPriority() > 0 ) m_out->Print( aNestLevel+1, "(priority %d)\n", aZone->GetPriority() ); @@ -1674,10 +1671,10 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const } m_out->Print( 0, " (clearance %s))\n", - FMT_IU( aZone->GetZoneClearance() ).c_str() ); + FormatInternalUnits( aZone->GetZoneClearance() ).c_str() ); m_out->Print( aNestLevel+1, "(min_thickness %s)\n", - FMT_IU( aZone->GetMinThickness() ).c_str() ); + FormatInternalUnits( aZone->GetMinThickness() ).c_str() ); if( aZone->GetIsKeepout() ) { @@ -1699,8 +1696,8 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const m_out->Print( 0, " (arc_segments %d) (thermal_gap %s) (thermal_bridge_width %s)", aZone->GetArcSegmentCount(), - FMT_IU( aZone->GetThermalReliefGap() ).c_str(), - FMT_IU( aZone->GetThermalReliefCopperBridge() ).c_str() ); + FormatInternalUnits( aZone->GetThermalReliefGap() ).c_str(), + FormatInternalUnits( aZone->GetThermalReliefCopperBridge() ).c_str() ); if( aZone->GetCornerSmoothingType() != ZONE_SETTINGS::SMOOTHING_NONE ) { @@ -1724,7 +1721,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const if( aZone->GetCornerRadius() != 0 ) m_out->Print( 0, " (radius %s)", - FMT_IU( aZone->GetCornerRadius() ).c_str() ); + FormatInternalUnits( aZone->GetCornerRadius() ).c_str() ); } m_out->Print( 0, ")\n" ); @@ -1749,10 +1746,10 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const if( newLine == 0 ) m_out->Print( aNestLevel+3, "(xy %s %s)", - FMT_IU( iterator->x ).c_str(), FMT_IU( iterator->y ).c_str() ); + FormatInternalUnits( iterator->x ).c_str(), FormatInternalUnits( iterator->y ).c_str() ); else m_out->Print( 0, " (xy %s %s)", - FMT_IU( iterator->x ).c_str(), FMT_IU( iterator->y ).c_str() ); + FormatInternalUnits( iterator->x ).c_str(), FormatInternalUnits( iterator->y ).c_str() ); if( newLine < 4 ) { @@ -1804,10 +1801,10 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const if( newLine == 0 ) m_out->Print( aNestLevel+3, "(xy %s %s)", - FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() ); + FormatInternalUnits( it->x ).c_str(), FormatInternalUnits( it->y ).c_str() ); else m_out->Print( 0, " (xy %s %s)", - FMT_IU( it->x ) .c_str(), FMT_IU( it->y ).c_str() ); + FormatInternalUnits( it->x ) .c_str(), FormatInternalUnits( it->y ).c_str() ); if( newLine < 4 ) { @@ -1846,8 +1843,8 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const for( ZONE_SEGMENT_FILL::const_iterator it = segs.begin(); it != segs.end(); ++it ) { m_out->Print( aNestLevel+2, "(pts (xy %s) (xy %s))\n", - FMT_IU( wxPoint( it->A ) ).c_str(), - FMT_IU( wxPoint( it->B ) ).c_str() ); + FormatInternalUnits( wxPoint( it->A ) ).c_str(), + FormatInternalUnits( wxPoint( it->B ) ).c_str() ); } m_out->Print( aNestLevel+1, ")\n" ); diff --git a/pcbnew/netclass.cpp b/pcbnew/netclass.cpp index 10d2b49478..71c3e72833 100644 --- a/pcbnew/netclass.cpp +++ b/pcbnew/netclass.cpp @@ -33,11 +33,6 @@ #include #include -/// Abbrevation for fomatting internal units to a string. -#define FMT_IU BOARD_ITEM::FormatInternalUnits -#define FMT_ANGLE BOARD_ITEM::FormatAngle - - // This will get mapped to "kicad_default" in the specctra_export. const char NETCLASS::Default[] = "Default"; @@ -261,22 +256,24 @@ void NETCLASS::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl aFormatter->Quotew( GetName() ).c_str(), aFormatter->Quotew( GetDescription() ).c_str() ); - aFormatter->Print( aNestLevel+1, "(clearance %s)\n", FMT_IU( GetClearance() ).c_str() ); - aFormatter->Print( aNestLevel+1, "(trace_width %s)\n", FMT_IU( GetTrackWidth() ).c_str() ); + aFormatter->Print( aNestLevel+1, "(clearance %s)\n", FormatInternalUnits( GetClearance() ).c_str() ); + aFormatter->Print( aNestLevel+1, "(trace_width %s)\n", FormatInternalUnits( GetTrackWidth() ).c_str() ); - aFormatter->Print( aNestLevel+1, "(via_dia %s)\n", FMT_IU( GetViaDiameter() ).c_str() ); - aFormatter->Print( aNestLevel+1, "(via_drill %s)\n", FMT_IU( GetViaDrill() ).c_str() ); + aFormatter->Print( aNestLevel+1, "(via_dia %s)\n", FormatInternalUnits( GetViaDiameter() ).c_str() ); + aFormatter->Print( aNestLevel+1, "(via_drill %s)\n", FormatInternalUnits( GetViaDrill() ).c_str() ); - aFormatter->Print( aNestLevel+1, "(uvia_dia %s)\n", FMT_IU( GetuViaDiameter() ).c_str() ); - aFormatter->Print( aNestLevel+1, "(uvia_drill %s)\n", FMT_IU( GetuViaDrill() ).c_str() ); + aFormatter->Print( aNestLevel+1, "(uvia_dia %s)\n", FormatInternalUnits( GetuViaDiameter() ).c_str() ); + aFormatter->Print( aNestLevel+1, "(uvia_drill %s)\n", FormatInternalUnits( GetuViaDrill() ).c_str() ); // Save the diff_pair_gap and diff_pair_width values only if not the default, to avoid unnecessary // incompatibility with previous Pcbnew versions. if( ( DEFAULT_DIFF_PAIR_WIDTH != GetDiffPairWidth() ) || ( DEFAULT_DIFF_PAIR_GAP != GetDiffPairGap() ) ) { - aFormatter->Print( aNestLevel+1, "(diff_pair_width %s)\n", FMT_IU( GetDiffPairWidth() ).c_str() ); - aFormatter->Print( aNestLevel+1, "(diff_pair_gap %s)\n", FMT_IU( GetDiffPairGap() ).c_str() ); + aFormatter->Print( aNestLevel+1, "(diff_pair_width %s)\n", + FormatInternalUnits( GetDiffPairWidth() ).c_str() ); + aFormatter->Print( aNestLevel+1, "(diff_pair_gap %s)\n", + FormatInternalUnits( GetDiffPairGap() ).c_str() ); // 6.0 TODO: figure out what to do with DiffPairViaGap... } diff --git a/qa/common/CMakeLists.txt b/qa/common/CMakeLists.txt index 7ea7084f52..84921c26b9 100644 --- a/qa/common/CMakeLists.txt +++ b/qa/common/CMakeLists.txt @@ -21,7 +21,7 @@ find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc REQUIRED ) -add_executable( qa_common +set( common_srcs # This is needed for the global mock objects common_mocks.cpp @@ -30,6 +30,7 @@ add_executable( qa_common # stuff from common due to...units? ../../common/eda_text.cpp + ../../common/base_units.cpp # stuff from common which is needed...why? ../../common/colors.cpp @@ -39,6 +40,7 @@ add_executable( qa_common test_hotkey_store.cpp test_title_block.cpp test_utf8.cpp + test_format_units.cpp libeval/test_numeric_evaluator.cpp @@ -47,14 +49,7 @@ add_executable( qa_common view/test_zoom_controller.cpp ) -include_directories( - ${CMAKE_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/polygon - ${INC_AFTER} -) - -target_link_libraries( qa_common +set( common_libs common legacy_gal polygon @@ -65,11 +60,38 @@ target_link_libraries( qa_common ${wxWidgets_LIBRARIES} ) -# we need to pretend to be something to appease the units code -target_compile_definitions( qa_common - PRIVATE GERBVIEW + +# Use code with GERBVIEW defines in place (primarily IU difference) +add_executable( qa_common_gerbview ${common_srcs} ) +target_link_libraries( qa_common_gerbview ${common_libs} ) +target_compile_definitions( qa_common_gerbview PRIVATE GERBVIEW ) + +# Use code with PCBNEW defines in place +add_executable( qa_common_pcbnew ${common_srcs} ) +target_link_libraries( qa_common_pcbnew ${common_libs} ) +target_compile_definitions( qa_common_pcbnew PRIVATE PCBNEW ) + +# Use code with EESCHEMA defines in place +add_executable( qa_common_eeschema ${common_srcs} ) +target_link_libraries( qa_common_eeschema ${common_libs} ) +target_compile_definitions( qa_common_eeschema PRIVATE EESCHEMA ) + +include_directories( + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/pcbnew + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/polygon + ${INC_AFTER} ) -add_test( NAME common - COMMAND qa_common +add_test( NAME common_gerbview + COMMAND qa_common_gerbview +) + +add_test( NAME common_pcbnew + COMMAND qa_common_pcbnew +) + +add_test( NAME common_eeschema + COMMAND qa_common_eeschema ) \ No newline at end of file diff --git a/qa/common/test_format_units.cpp b/qa/common/test_format_units.cpp new file mode 100644 index 0000000000..9ffc1008cb --- /dev/null +++ b/qa/common/test_format_units.cpp @@ -0,0 +1,78 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2019 KiCad Developers, see CHANGELOG.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 + +struct UnitFixture +{ +}; + + +/** + * Declares a struct as the Boost test fixture. + */ +BOOST_FIXTURE_TEST_SUITE( UnitConversion, UnitFixture ) + + +/** + * Check formatting the point + */ +BOOST_AUTO_TEST_CASE( wxPointUnitFormat ) +{ + std::string str = FormatInternalUnits( wxPoint( 123456, 52525252 ) ); + std::string strZero = FormatInternalUnits( wxPoint( 0, 0 ) ); + std::string strNeg = FormatInternalUnits( wxPoint( -123456, -52525252 ) ); + std::string strOddNeg = FormatInternalUnits( wxPoint( -350000, -0 ) ); + + std::string strMax = FormatInternalUnits( wxPoint( std::numeric_limits::min(), + std::numeric_limits::max() ) ); + + BOOST_CHECK_EQUAL( strZero, "0 0" ); + +#ifdef EESCHEMA + BOOST_CHECK_EQUAL( str, "123456 52525252" ); + BOOST_CHECK_EQUAL( strNeg, "-123456 -52525252" ); + BOOST_CHECK_EQUAL( strMax, "-2147483648 2147483647" ); + BOOST_CHECK_EQUAL( strOddNeg, "-350000 0" ); +#elif GERBVIEW + BOOST_CHECK_EQUAL( str, "1.23456 525.25252" ); + BOOST_CHECK_EQUAL( strNeg, "-1.23456 -525.25252" ); + BOOST_CHECK_EQUAL( strMax, "-21474.83648 21474.83647" ); + BOOST_CHECK_EQUAL( strOddNeg, "-3.5 0" ); +#elif PCBNEW + BOOST_CHECK_EQUAL( str, "0.123456 52.525252" ); + BOOST_CHECK_EQUAL( strNeg, "-0.123456 -52.525252" ); + BOOST_CHECK_EQUAL( strMax, "-2147.483648 2147.483647" ); + BOOST_CHECK_EQUAL( strOddNeg, "-0.35 0" ); +#endif + +} + + +BOOST_AUTO_TEST_SUITE_END()