KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pads_unit_converter.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "pads_unit_converter.h"
21
22#include <cmath>
23
31
32
34{
35 m_unitType = aUnitType;
37}
38
39
41{
42 m_basicUnitsMode = aEnabled;
44}
45
46
48{
49 m_basicUnitsScale = aScale;
50
53}
54
55
56bool PADS_UNIT_CONVERTER::ParseFileHeader( const std::string& aHeader )
57{
58 // Look for BASIC indicator in header like "!PADS-POWERPCB-V9.0-BASIC!"
59 if( aHeader.find( "BASIC" ) != std::string::npos ||
60 aHeader.find( "basic" ) != std::string::npos )
61 {
62 SetBasicUnitsMode( true );
63 return true;
64 }
65
66 // Look for explicit unit type indicators
67 if( aHeader.find( "MILS" ) != std::string::npos ||
68 aHeader.find( "mils" ) != std::string::npos )
69 {
70 SetBasicUnitsMode( false );
72 return true;
73 }
74
75 if( aHeader.find( "METRIC" ) != std::string::npos ||
76 aHeader.find( "metric" ) != std::string::npos )
77 {
78 SetBasicUnitsMode( false );
80 return true;
81 }
82
83 if( aHeader.find( "INCHES" ) != std::string::npos ||
84 aHeader.find( "inches" ) != std::string::npos )
85 {
86 SetBasicUnitsMode( false );
88 return true;
89 }
90
91 return false;
92}
93
94
95std::optional<PADS_UNIT_TYPE> PADS_UNIT_CONVERTER::ParseUnitCode( const std::string& aUnitCode )
96{
97 if( aUnitCode.empty() )
98 return std::nullopt;
99
100 // "M" and "D" (default) both mean MILS
101 if( aUnitCode == "M" || aUnitCode == "m" || aUnitCode == "D" || aUnitCode == "d" ||
102 aUnitCode == "MILS" || aUnitCode == "mils" || aUnitCode == "MIL" || aUnitCode == "mil" )
103 {
105 }
106
107 // "MM" means METRIC (millimeters)
108 if( aUnitCode == "MM" || aUnitCode == "mm" ||
109 aUnitCode == "METRIC" || aUnitCode == "metric" )
110 {
112 }
113
114 // "I" means INCHES
115 if( aUnitCode == "I" || aUnitCode == "i" ||
116 aUnitCode == "INCHES" || aUnitCode == "inches" || aUnitCode == "INCH" || aUnitCode == "inch" )
117 {
119 }
120
121 // "N" means no override
122 if( aUnitCode == "N" || aUnitCode == "n" )
123 return std::nullopt;
124
125 return std::nullopt;
126}
127
128
129bool PADS_UNIT_CONVERTER::PushUnitOverride( const std::string& aUnitCode )
130{
131 std::optional<PADS_UNIT_TYPE> unitType = ParseUnitCode( aUnitCode );
132
133 if( !unitType.has_value() )
134 return false;
135
136 m_unitOverrideStack.push_back( *unitType );
138 return true;
139}
140
141
143{
144 if( !m_unitOverrideStack.empty() )
145 {
146 m_unitOverrideStack.pop_back();
148 }
149}
150
151
153{
154 if( m_basicUnitsMode )
155 {
157 return;
158 }
159
160 // Use override if present, otherwise use base unit type
161 PADS_UNIT_TYPE effectiveType = m_unitOverrideStack.empty()
162 ? m_unitType
163 : m_unitOverrideStack.back();
164
165 switch( effectiveType )
166 {
169 break;
170
173 break;
174
177 break;
178 }
179}
180
181
182int64_t PADS_UNIT_CONVERTER::ToNanometers( double aValue ) const
183{
184 return static_cast<int64_t>( std::round( aValue * m_scaleFactor ) );
185}
186
187
188int64_t PADS_UNIT_CONVERTER::ToNanometersSize( double aValue ) const
189{
190 return static_cast<int64_t>( std::round( aValue * m_scaleFactor ) );
191}
static constexpr double MILS_TO_NM
static constexpr double INCHES_TO_NM
std::vector< PADS_UNIT_TYPE > m_unitOverrideStack
void SetBaseUnits(PADS_UNIT_TYPE aUnitType)
Set the base units for conversion.
bool PushUnitOverride(const std::string &aUnitCode)
Push a unit override onto the stack.
static constexpr double BASIC_TO_NM
void SetBasicUnitsMode(bool aEnabled)
Enable or disable BASIC units mode.
int64_t ToNanometersSize(double aValue) const
Convert a size value to nanometers.
bool ParseFileHeader(const std::string &aHeader)
Parse a PADS file header string and configure units accordingly.
static std::optional< PADS_UNIT_TYPE > ParseUnitCode(const std::string &aUnitCode)
Parse a PADS unit code and return the corresponding unit type.
static constexpr double MM_TO_NM
void SetBasicUnitsScale(double aScale)
Set a custom scale for BASIC units.
void PopUnitOverride()
Pop the most recent unit override from the stack.
int64_t ToNanometers(double aValue) const
Convert a coordinate value to nanometers.
PADS_UNIT_TYPE
Unit types supported by PADS file formats.
@ MILS
Thousandths of an inch (1 mil = 0.001 inch)
@ METRIC
Millimeters.