29#include <wx/translation.h>
34 int len = aText.length();
37 while( --len > 0 && aText[len] ==
'0' )
40 if( len >= 0 && ( aText[len] ==
'.' || aText[len] ==
',' ) )
43 aText = aText.RemoveLast( removeLast );
78 return KiROUND( aVal * 1000. / 25.4 );
84 return KiROUND( aVal * 25.4 / 1000. );
90 wxString buf( aTextValue.Strip( wxString::both ) );
91 unsigned brk_point = 0;
93 while( brk_point < buf.Len() )
95 wxChar c = buf[brk_point];
97 if( !( ( c >=
'0' && c <=
'9' ) || ( c ==
'.' ) || ( c ==
',' ) || ( c ==
'-' )
105 wxString unit( buf.Mid( brk_point ).Trim(
false ).Left( 2 ).Lower() );
108 if( unit == wxT(
"um" ) || unit == wxT(
"\u00B5m" ) || unit == wxT(
"\u03BCm" ) )
110 else if( unit == wxT(
"mm" ) )
112 if( unit == wxT(
"cm" ) )
114 else if( unit == wxT(
"mi" ) || unit == wxT(
"th" ) )
116 else if( unit == wxT(
"in" ) || unit == wxT(
"\"" ) )
118 else if( unit == wxT(
"de" ) || unit == wxT(
"ra" ) )
120 else if( unit == wxT(
"fs" ) )
122 else if( unit == wxT(
"ps" ) )
124 wxString timeUnit( buf.Mid( brk_point ).Trim(
false ).Left( 5 ).Lower() );
126 if( timeUnit == wxT(
"ps" ) )
128 else if( timeUnit == wxT(
"ps/in" ) )
130 else if( timeUnit == wxT(
"ps/cm" ) )
132 else if( timeUnit == wxT(
"ps/mm" ) )
182 return GetText( aUnits, aType ).Trim(
false );
188 std::string temp = fmt::format(
"{:.10g}", aAngle.
AsDegrees() );
198 double engUnits = aValue;
202 if( engUnits != 0.0 && fabs( engUnits ) <= 0.0001 )
204 buf = fmt::format(
"{:.10f}", engUnits );
207 while( !buf.empty() && buf[buf.size() - 1] ==
'0' )
214 if( buf[buf.size() - 1] ==
'.' )
221 buf = fmt::format(
"{:.10g}", engUnits );
250bool EDA_UNIT_UTILS::ParseInternalUnits(
const std::string& aInput,
const EDA_IU_SCALE& aIuScale,
255 if( std::from_chars( aInput.data(), aInput.data() + aInput.size(), value ).ec != std::errc() )
263bool EDA_UNIT_UTILS::ParseInternalUnits(
const std::string& aInput,
const EDA_IU_SCALE& aIuScale,
266 size_t pos = aInput.find(
' ' );
268 if( pos == std::string::npos )
271 std::string first = aInput.substr( 0, pos );
272 std::string second = aInput.substr( pos + 1 );
276 if( !ParseInternalUnits( first, aIuScale, vec.
x ) )
279 if( !ParseInternalUnits( second, aIuScale, vec.
y ) )
290#define IU_TO_MM( x, scale ) ( x / scale.IU_PER_MM )
291#define IU_TO_IN( x, scale ) ( x / scale.IU_PER_MILS / 1000 )
292#define IU_TO_MILS( x, scale ) ( x / scale.IU_PER_MILS )
293#define IU_TO_PS( x, scale ) ( x / scale.IU_PER_PS )
294#define IU_TO_PS_PER_MM( x, scale ) ( x / scale.IU_PER_PS_PER_MM )
295#define MM_TO_IU( x, scale ) ( x * scale.IU_PER_MM )
296#define IN_TO_IU( x, scale ) ( x * scale.IU_PER_MILS * 1000 )
297#define MILS_TO_IU( x, scale ) ( x * scale.IU_PER_MILS )
298#define PS_TO_IU( x, scale ) ( x * scale.IU_PER_PS )
299#define PS_PER_MM_TO_IU( x, scale ) ( x * scale.IU_PER_PS_PER_MM )
318 default:
return aValue;
324 double aValue,
bool aAddUnitsText,
327 double value_to_print = aValue;
333 value_to_print =
ToUserUnit( aIuScale, aUnits, value_to_print );
337 value_to_print =
ToUserUnit( aIuScale, aUnits, value_to_print );
341 value_to_print =
ToUserUnit( aIuScale, aUnits, value_to_print );
348 value_to_print =
ToUserUnit( aIuScale, aUnits, value_to_print );
352 value_to_print =
ToUserUnit( aIuScale, aUnits, value_to_print );
356 const wxChar* format =
nullptr;
360 case EDA_UNITS::MILS: format = is_eeschema ? wxT(
"%.3f" ) : wxT(
"%.5f" );
break;
361 case EDA_UNITS::INCH: format = is_eeschema ? wxT(
"%.6f" ) : wxT(
"%.8f" );
break;
366 default: format = wxT(
"%.10f" );
break;
370 text.Printf( format, value_to_print );
373 if( value_to_print != 0.0 && (
text == wxS(
"0" ) ||
text == wxS(
"-0" ) ) )
375 text.Printf( wxS(
"%.10f" ), value_to_print );
399 long long int aValue,
410 return wxString::Format( wxT(
"%.1f°" ), aValue.
AsDegrees() );
412 return wxString::Format( wxT(
"%.1f" ), aValue.
AsDegrees() );
418 double aValue,
bool aAddUnitsText,
422 const wxChar* format;
423 double value = aValue;
430 value =
ToUserUnit( aIuScale, aUnits, value );
435 value =
ToUserUnit( aIuScale, aUnits, value );
440 value =
ToUserUnit( aIuScale, aUnits, value );
447 value =
ToUserUnit( aIuScale, aUnits, value );
451 value =
ToUserUnit( aIuScale, aUnits, value );
458 case EDA_UNITS::UM: format = short_form ? wxT(
"%.0f" ) : wxT(
"%.1f" );
break;
459 case EDA_UNITS::MM: format = short_form ? wxT(
"%.3f" ) : wxT(
"%.4f" );
break;
460 case EDA_UNITS::CM: format = short_form ? wxT(
"%.3f" ) : wxT(
"%.5f" );
break;
461 case EDA_UNITS::MILS: format = short_form ? wxT(
"%.0f" ) : wxT(
"%.2f" );
break;
462 case EDA_UNITS::INCH: format = short_form ? wxT(
"%.3f" ) : wxT(
"%.4f" );
break;
472 text.Printf( format, value );
478 bool showsOnlyZeros =
true;
481 for(
auto ch :
text )
483 if( ch >=
'1' && ch <=
'9' )
485 showsOnlyZeros =
false;
492 text.Printf( wxT(
"%.3e" ), value );
499 struct lconv* lc = localeconv();
500 int length = (int)
text.Length();
502 if( length > 4 &&
text[length - 4] == *lc->decimal_point &&
text[length - 1] ==
'0' )
519 if( aValue.
HasMin() && aValue.
Min() > 0 )
572 const struct lconv* lc = localeconv();
574 wxChar decimal_point = lc->decimal_point[0];
575 wxString buf( aTextValue.Strip( wxString::both ) );
578 buf.Replace( wxT(
"." ), wxString( decimal_point, 1 ) );
579 buf.Replace( wxT(
"," ), wxString( decimal_point, 1 ) );
582 unsigned brk_point = 0;
584 while( brk_point < buf.Len() )
586 wxChar ch = buf[brk_point];
588 if( !( ( ch >=
'0' && ch <=
'9' ) || ( ch == decimal_point ) || ( ch ==
'-' )
598 buf.Left( brk_point ).ToDouble( &dtmp );
610 const struct lconv* lc = localeconv();
612 wxChar decimal_point = lc->decimal_point[0];
613 wxString buf( aTextValue.Strip( wxString::both ) );
616 buf.Replace( wxT(
"." ), wxString( decimal_point, 1 ) );
617 buf.Replace( wxT(
"," ), wxString( decimal_point, 1 ) );
620 unsigned brk_point = 0;
622 while( brk_point < buf.Len() )
624 wxChar ch = buf[brk_point];
626 if( !( (ch >=
'0' && ch <=
'9') || (ch == decimal_point) || (ch ==
'-') || (ch ==
'+') ) )
633 buf.Left( brk_point ).ToDouble( &dtmp );
636 wxString unit( buf.Mid( brk_point ).Trim(
false ).Left( 2 ).Lower() );
645 if( unit == wxT(
"um" ) || unit == wxT(
"\u00B5m" ) || unit == wxT(
"\u03BCm" ) )
649 else if( unit == wxT(
"mm" ) )
653 else if( unit == wxT(
"cm" ) )
657 else if( unit == wxT(
"mi" ) || unit == wxT(
"th" ) )
661 else if( unit == wxT(
"in" ) || unit == wxT(
"\"" ) )
665 else if( unit == wxT(
"oz" ) )
673 if( unit == wxT(
"ra" ) )
674 dtmp *= 180.0f /
M_PI;
680 wxString timeUnit( buf.Mid( brk_point ).Trim(
false ).Left( 5 ).Lower() );
682 if( timeUnit == wxT(
"fs" ) )
684 if( timeUnit == wxT(
"ps" ) )
686 else if( timeUnit == wxT(
"ps/in" ) )
688 else if( timeUnit == wxT(
"ps/cm" ) )
690 else if( timeUnit == wxT(
"ps/mm" ) )
725 double& aDoubleValue )
730 const struct lconv* lc = localeconv();
732 wxChar decimal_point = lc->decimal_point[0];
733 wxString buf( aTextValue.Strip( wxString::both ) );
736 buf.Replace( wxT(
"." ), wxString( decimal_point, 1 ) );
737 buf.Replace( wxT(
"," ), wxString( decimal_point, 1 ) );
740 unsigned brk_point = 0;
742 while( brk_point < buf.Len() )
744 wxChar ch = buf[brk_point];
746 if( !( (ch >=
'0' && ch <=
'9') || (ch == decimal_point) || (ch ==
'-') || (ch ==
'+') ) )
756 buf.Left( brk_point ).ToDouble( &dtmp );
759 wxString unit( buf.Mid( brk_point ).Strip( wxString::both ).Lower() );
763 if( unit == wxT(
"um" ) || unit == wxT(
"\u00B5m" ) || unit == wxT(
"\u03BCm" ) )
767 else if( unit == wxT(
"mm" ) )
771 else if( unit == wxT(
"cm" ) )
775 else if( unit == wxT(
"mil" ) || unit == wxT(
"mils" ) || unit == wxT(
"thou" ) )
779 else if( unit == wxT(
"in" ) || unit == wxT(
"\"" ) )
783 else if( unit == wxT(
"oz" ) )
788 else if( unit == wxT(
"ra" ) )
790 dtmp *= 180.0f /
M_PI;
792 else if( unit == wxT(
"fs" ) )
796 else if( unit == wxT(
"ps" ) )
800 else if( unit == wxT(
"ps/in" ) )
804 else if( unit == wxT(
"ps/cm" ) )
808 else if( unit == wxT(
"ps/mm" ) )
constexpr double SCH_IU_PER_MM
Schematic internal units 1=100nm.
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
#define IU_TO_IN(x, scale)
#define IU_TO_PS_PER_MM(x, scale)
#define IN_TO_IU(x, scale)
#define IU_TO_MILS(x, scale)
#define IU_TO_PS(x, scale)
#define MM_TO_IU(x, scale)
#define PS_TO_IU(x, scale)
#define PS_PER_MM_TO_IU(x, scale)
#define IU_TO_MM(x, scale)
#define MILS_TO_IU(x, scale)
static void removeTrailingZeros(wxString &aText)
EDA_DATA_TYPE
The type of unit.
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
#define UNIMPLEMENTED_FOR(type)
KICOMMON_API wxString MessageTextFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A helper to convert the double length aValue to a string in inches, millimeters, or unscaled units.
KICOMMON_API double FromUserUnit(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnit, double aValue)
Return in internal units the value aValue given in a real unit such as "in", "mm",...
KICOMMON_API long long int ValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Convert aTextValue in aUnits to internal units used by the application.
KICOMMON_API wxString StringFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Return the string from aValue according to aUnits (inch, mm ...) for display.
KICOMMON_API wxString MessageTextFromMinOptMax(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const MINOPTMAX< int > &aValue)
KICOMMON_API double DoubleValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Convert aTextValue to a double.
KICOMMON_API double ToUserUnit(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnit, double aValue)
Convert aValue in internal units to the appropriate user units defined by aUnit.
KICOMMON_API wxString GetText(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
KICOMMON_API bool FetchUnitsFromString(const wxString &aTextValue, EDA_UNITS &aUnits)
Write any unit info found in the string to aUnits.
KICOMMON_API bool IsImperialUnit(EDA_UNITS aUnit)
KICOMMON_API bool IsMetricUnit(EDA_UNITS aUnit)
KICOMMON_API double GetScaleForInternalUnitType(const EDA_IU_SCALE &aIuScale, EDA_DATA_TYPE aDataType)
Returns the scaling parameter for the given units data type.
KICOMMON_API wxString GetLabel(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
KICOMMON_API int Mm2mils(double aVal)
Convert mm to mils.
KICOMMON_API std::string FormatAngle(const EDA_ANGLE &aAngle)
Convert aAngle from board units to a string appropriate for writing to file.
KICOMMON_API std::string FormatInternalUnits(const EDA_IU_SCALE &aIuScale, int aValue, EDA_DATA_TYPE aDataType=EDA_DATA_TYPE::DISTANCE)
Converts aValue from internal units to a string appropriate for writing to file.
KICOMMON_API int Mils2mm(double aVal)
Convert mils to mm.
const double IU_PER_PS
Internal time units are attoseconds.
const double IU_PER_PS_PER_MM
Internal delay units are attoseconds/mm.
VECTOR2< int32_t > VECTOR2I