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 The 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, see <https://www.gnu.org/licenses/>.
19 */
20
21#include "altium_props_utils.h"
22
23#include <limits>
24#include <sstream>
25#include <math/util.h>
26
27#include <wx/crt.h>
28#include <wx/log.h>
29#include <wx/translation.h>
30
31
32int32_t ALTIUM_PROPS_UTILS::ConvertToKicadUnit( const double aValue )
33{
34 constexpr double int_limit = ( std::numeric_limits<int>::max() - 10 ) / 2.54;
35
36 int32_t iu = KiROUND( std::clamp( aValue, -int_limit, int_limit ) * 2.54 );
37
38 // Altium's internal precision is 0.1uinch. KiCad's is 1nm. Round to nearest 10nm to clean
39 // up most rounding errors. This allows lossless conversion of increments of 0.05mils and
40 // 0.01um.
41 return KiROUND( (double) iu / 10.0 ) * 10;
42}
43
44
45int ALTIUM_PROPS_UTILS::ReadInt( const std::map<wxString, wxString>& aProps, const wxString& aKey,
46 int aDefault )
47{
48 const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
49 return value == aProps.end() ? aDefault : wxAtoi( value->second );
50}
51
52
53double ALTIUM_PROPS_UTILS::ReadDouble( const std::map<wxString, wxString>& aProps,
54 const wxString& aKey, double aDefault )
55{
56 const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
57
58 if( value == aProps.end() )
59 return aDefault;
60
61 // Locale independent str -> double conversation
62 std::istringstream istr( (const char*) value->second.mb_str() );
63 istr.imbue( std::locale::classic() );
64
65 double doubleValue;
66 istr >> doubleValue;
67 return doubleValue;
68}
69
70
71bool ALTIUM_PROPS_UTILS::ReadBool( const std::map<wxString, wxString>& aProps, const wxString& aKey,
72 bool aDefault )
73{
74 const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
75
76 if( value == aProps.end() )
77 return aDefault;
78 else
79 return value->second == "T" || value->second == "TRUE";
80}
81
82
83int32_t ALTIUM_PROPS_UTILS::ReadKicadUnit( const std::map<wxString, wxString>& aProps,
84 const wxString& aKey, const wxString& aDefault )
85{
86 const wxString& value = ReadString( aProps, aKey, aDefault );
87
88 wxString prefix;
89
90 if( !value.EndsWith( "mil", &prefix ) )
91 {
92 wxLogTrace( "ALTIUM", wxT( "Unit '%s' does not end with 'mil'." ), value );
93 return 0;
94 }
95
96 prefix.StartsWith( "+", &prefix );
97
98 double mils;
99
100 if( !prefix.ToCDouble( &mils ) )
101 {
102 wxLogTrace( "ALTIUM", wxT( "Cannot convert '%s' to double." ), prefix );
103 return 0;
104 }
105
106 return ConvertToKicadUnit( mils * 10000 );
107}
108
109
110wxString ALTIUM_PROPS_UTILS::ReadString( const std::map<wxString, wxString>& aProps,
111 const wxString& aKey, const wxString& aDefault )
112{
113 const auto& utf8Value = aProps.find( wxString( "%UTF8%" ) + aKey );
114
115 if( utf8Value != aProps.end() )
116 return utf8Value->second;
117
118 const auto& value = aProps.find( aKey );
119
120 if( value != aProps.end() )
121 return value->second;
122
123 return aDefault;
124}
125
126
127wxString ALTIUM_PROPS_UTILS::ReadUnicodeString( const std::map<wxString, wxString>& aProps,
128 const wxString& aKey, const wxString& aDefault )
129{
130 const auto& unicodeFlag = aProps.find( wxS( "UNICODE" ) );
131
132 if( unicodeFlag != aProps.end() && unicodeFlag->second.Contains( wxS( "EXISTS" ) ) )
133 {
134 const auto& unicodeValue = aProps.find( wxString( "UNICODE__" ) + aKey );
135
136 if( unicodeValue != aProps.end() )
137 {
138 wxArrayString arr = wxSplit( unicodeValue->second, ',', '\0' );
139 wxString out;
140
141 for( wxString part : arr )
142 out += wxString( wchar_t( wxAtoi( part ) ) );
143
144 return out;
145 }
146 }
147
148 return ReadString( aProps, aKey, aDefault );
149}
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
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)