KiCad PCB EDA Suite
Loading...
Searching...
No Matches
altium_props_utils.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2019-2020 Thomas Pointhuber <[email protected]>
5 * Copyright (C) 2020-2024 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include "altium_props_utils.h"
26
27#include <limits>
28#include <sstream>
29#include <math/util.h>
30
31#include <wx/crt.h>
32#include <wx/log.h>
33#include <wx/translation.h>
34
35
36int32_t ALTIUM_PROPS_UTILS::ConvertToKicadUnit( const double aValue )
37{
38 constexpr double int_limit = ( std::numeric_limits<int>::max() - 10 ) / 2.54;
39
40 int32_t iu = KiROUND( Clamp<double>( -int_limit, aValue, int_limit ) * 2.54 );
41
42 // Altium's internal precision is 0.1uinch. KiCad's is 1nm. Round to nearest 10nm to clean
43 // up most rounding errors. This allows lossless conversion of increments of 0.05mils and
44 // 0.01um.
45 return KiROUND( (double) iu / 10.0 ) * 10;
46}
47
48
49int ALTIUM_PROPS_UTILS::ReadInt( const std::map<wxString, wxString>& aProps, const wxString& aKey,
50 int aDefault )
51{
52 const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
53 return value == aProps.end() ? aDefault : wxAtoi( value->second );
54}
55
56
57double ALTIUM_PROPS_UTILS::ReadDouble( const std::map<wxString, wxString>& aProps, const wxString& aKey,
58 double aDefault )
59{
60 const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
61
62 if( value == aProps.end() )
63 return aDefault;
64
65 // Locale independent str -> double conversation
66 std::istringstream istr( (const char*) value->second.mb_str() );
67 istr.imbue( std::locale::classic() );
68
69 double doubleValue;
70 istr >> doubleValue;
71 return doubleValue;
72}
73
74
75bool ALTIUM_PROPS_UTILS::ReadBool( const std::map<wxString, wxString>& aProps, const wxString& aKey,
76 bool aDefault )
77{
78 const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
79
80 if( value == aProps.end() )
81 return aDefault;
82 else
83 return value->second == "T" || value->second == "TRUE";
84}
85
86
87int32_t ALTIUM_PROPS_UTILS::ReadKicadUnit( const std::map<wxString, wxString>& aProps,
88 const wxString& aKey, const wxString& aDefault )
89{
90 const wxString& value = ReadString( aProps, aKey, aDefault );
91
92 wxString prefix;
93
94 if( !value.EndsWith( "mil", &prefix ) )
95 {
96 wxLogError( _( "Unit '%s' does not end with 'mil'." ), value );
97 return 0;
98 }
99
100 prefix.StartsWith( "+", &prefix );
101
102 double mils;
103
104 if( !prefix.ToCDouble( &mils ) )
105 {
106 wxLogError( _( "Cannot convert '%s' to double." ), prefix );
107 return 0;
108 }
109
110 return ConvertToKicadUnit( mils * 10000 );
111}
112
113
114wxString ALTIUM_PROPS_UTILS::ReadString( const std::map<wxString, wxString>& aProps,
115 const wxString& aKey, const wxString& aDefault )
116{
117 const auto& utf8Value = aProps.find( wxString( "%UTF8%" ) + aKey );
118
119 if( utf8Value != aProps.end() )
120 return utf8Value->second;
121
122 const auto& value = aProps.find( aKey );
123
124 if( value != aProps.end() )
125 return value->second;
126
127 return aDefault;
128}
129
130
131wxString ALTIUM_PROPS_UTILS::ReadUnicodeString( const std::map<wxString, wxString>& aProps,
132 const wxString& aKey, const wxString& aDefault )
133{
134 const auto& unicodeFlag = aProps.find( wxS( "UNICODE" ) );
135
136 if( unicodeFlag != aProps.end() && unicodeFlag->second.Contains( wxS( "EXISTS" ) ) )
137 {
138 const auto& unicodeValue = aProps.find( wxString( "UNICODE__" ) + aKey );
139
140 if( unicodeValue != aProps.end() )
141 {
142 wxArrayString arr = wxSplit( unicodeValue->second, ',', '\0' );
143 wxString out;
144
145 for( wxString part : arr )
146 out += wxString( wchar_t( wxAtoi( part ) ) );
147
148 return out;
149 }
150 }
151
152 return ReadString( aProps, aKey, aDefault );
153}
static int ReadInt(const std::map< wxString, wxString > &aProps, const wxString &aKey, int aDefault)
static int32_t ReadKicadUnit(const std::map< wxString, wxString > &aProps, const wxString &aKey, const wxString &aDefault)
static bool ReadBool(const std::map< wxString, wxString > &aProps, const wxString &aKey, bool aDefault)
static wxString ReadUnicodeString(const std::map< wxString, wxString > &aProps, const wxString &aKey, const wxString &aDefault)
static wxString ReadString(const std::map< wxString, wxString > &aProps, const wxString &aKey, const wxString &aDefault)
static double ReadDouble(const std::map< wxString, wxString > &aProps, const wxString &aKey, double aDefault)
static int32_t ConvertToKicadUnit(const double aValue)
#define _(s)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:118