units: Move common units and add tests

Centralizing duplicate code from Eeschema and pcbnew and adding unit
tests
This commit is contained in:
Seth Hillbrand 2019-01-07 21:42:50 -08:00
parent 31ab4e6c9a
commit 90ad240660
14 changed files with 384 additions and 450 deletions

View File

@ -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() );
}

View File

@ -35,7 +35,7 @@
#include <class_drawpanel.h> // EDA_DRAW_PANEL
#include <basic_gal.h>
#include <unit_format.h>
#include <base_units.h>
#include <convert_to_biu.h>
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" );

View File

@ -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() );
}

View File

@ -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

View File

@ -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 <string>
#include <math/vector2d.h>
#include <common.h>
#include <convert_to_biu.h>
//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_

View File

@ -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;
/**

View File

@ -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 <class_board_item.h>
#define FMT_IU BOARD_ITEM::FormatInternalUnits
#define FMT_ANGLE BOARD_ITEM::FormatAngle
#elif defined( EESCHEMA )
#include <sch_item_struct.h>
#define FMT_IU SCH_ITEM::FormatInternalUnits
#define FMT_ANGLE SCH_ITEM::FormatAngle
#elif defined( GERBVIEW )
#elif defined( PL_EDITOR )
#include <base_units.h>
#define FMT_IU Double2Str
#else
#error "Cannot resolve units formatting due to no definition of EESCHEMA or PCBNEW."
#endif
#endif /* UNIT_FORMAT_H */

View File

@ -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 );

View File

@ -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

View File

@ -35,7 +35,6 @@
#include <pcbnew.h>
#include <pcb_base_frame.h>
#include <base_units.h>
#include <unit_format.h>
#include <board_commit.h>
#include <bitmaps.h>
@ -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

View File

@ -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" );

View File

@ -33,11 +33,6 @@
#include <class_board.h>
#include <netclass.h>
/// 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...
}

View File

@ -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
)

View File

@ -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 <boost/test/unit_test.hpp>
#include <boost/test/test_case_template.hpp>
#include <base_units.h>
#include <algorithm>
#include <iostream>
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<int>::min(),
std::numeric_limits<int>::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()