diff --git a/common/libeval/numeric_evaluator.cpp b/common/libeval/numeric_evaluator.cpp index ab25728d53..78631d0d8e 100644 --- a/common/libeval/numeric_evaluator.cpp +++ b/common/libeval/numeric_evaluator.cpp @@ -279,7 +279,7 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken() }; // Lamda: Get unit for current token. - // Valid units are ", in, mm, mil and thou. Returns Unit::Invalid otherwise. + // Valid units are ", in, um, cm, mm, mil and thou. Returns Unit::Invalid otherwise. auto checkUnit = [&]( double* siScaler ) -> Unit { @@ -302,6 +302,15 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken() return Unit::Degrees; } + // Ideally we should also handle the unicode characters that can be used for micro, + // but unicode handling in this tokenizer doesn't work. + // (e.g. add support for μm (µ is MICRO SIGN), µm (µ is GREEK SMALL LETTER MU) later) + if( sizeLeft >= 2 && ch == 'u' && cptr[ 1 ] == 'm' && !isalnum( cptr[ 2 ] ) ) + { + m_token.pos += 2; + return Unit::UM; + } + if( sizeLeft >= 2 && ch == 'm' && cptr[ 1 ] == 'm' && !isalnum( cptr[ 2 ] ) ) { m_token.pos += 2; @@ -387,6 +396,7 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken() { case Unit::Inch: retval.value.dValue = 25.4; break; case Unit::Mil: retval.value.dValue = 25.4 / 1000.0; break; + case Unit::UM: retval.value.dValue = 1 / 1000.0; break; case Unit::MM: retval.value.dValue = 1.0; break; case Unit::CM: retval.value.dValue = 10.0; break; default: @@ -397,22 +407,24 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken() { switch( convertFrom ) { - case Unit::Inch: retval.value.dValue = 1.0; break; - case Unit::Mil: retval.value.dValue = 1.0 / 1000.0; break; - case Unit::MM: retval.value.dValue = 1.0 / 25.4; break; - case Unit::CM: retval.value.dValue = 1.0 / 2.54; break; + case Unit::Inch: retval.value.dValue = 1.0; break; + case Unit::Mil: retval.value.dValue = 1.0 / 1000.0; break; + case Unit::UM: retval.value.dValue = 1.0 / 25400.0; break; + case Unit::MM: retval.value.dValue = 1.0 / 25.4; break; + case Unit::CM: retval.value.dValue = 1.0 / 2.54; break; default: - case Unit::Invalid: break; + case Unit::Invalid: break; } } else if( m_defaultUnits == Unit::Mil ) { switch( convertFrom ) { - case Unit::Inch: retval.value.dValue = 1.0 * 1000.0; break; - case Unit::Mil: retval.value.dValue = 1.0; break; - case Unit::MM: retval.value.dValue = 1000.0 / 25.4; break; - case Unit::CM: retval.value.dValue = 1000.0 / 2.54; break; + case Unit::Inch: retval.value.dValue = 1.0 * 1000.0; break; + case Unit::Mil: retval.value.dValue = 1.0; break; + case Unit::UM: retval.value.dValue = 1.0 / 25.4; break; + case Unit::MM: retval.value.dValue = 1000.0 / 25.4; break; + case Unit::CM: retval.value.dValue = 1000.0 / 2.54; break; default: case Unit::Invalid: break; } diff --git a/common/preview_items/preview_utils.cpp b/common/preview_items/preview_utils.cpp index 92118651d7..27db8097eb 100644 --- a/common/preview_items/preview_utils.cpp +++ b/common/preview_items/preview_utils.cpp @@ -45,7 +45,7 @@ wxString KIGFX::PREVIEW::DimensionLabel( const wxString& prefix, double aVal, // nanometre switch( aUnits ) { - case EDA_UNITS::MICROMETRES: fmtStr = wxT( "%.1f" ); break; // 0.1um + case EDA_UNITS::MICROMETRES: fmtStr = wxT( "%.0f" ); break; // 1um case EDA_UNITS::MILLIMETRES: fmtStr = wxT( "%.3f" ); break; // 1um case EDA_UNITS::CENTIMETRES: fmtStr = wxT( "%.4f" ); break; // 1um case EDA_UNITS::MILS: fmtStr = wxT( "%.1f" ); break; // 0.1mil diff --git a/include/libeval/numeric_evaluator.h b/include/libeval/numeric_evaluator.h index 1ef999b6e8..23cd15a86b 100644 --- a/include/libeval/numeric_evaluator.h +++ b/include/libeval/numeric_evaluator.h @@ -92,7 +92,7 @@ namespace numEval class NUMERIC_EVALUATOR { - enum class Unit { Invalid, MM, CM, Inch, Mil, Degrees, SI }; + enum class Unit { Invalid, UM, MM, CM, Inch, Mil, Degrees, SI }; public: NUMERIC_EVALUATOR( EDA_UNITS aUnits ); diff --git a/qa/tests/common/libeval/test_numeric_evaluator.cpp b/qa/tests/common/libeval/test_numeric_evaluator.cpp index 1da6518420..9787337963 100644 --- a/qa/tests/common/libeval/test_numeric_evaluator.cpp +++ b/qa/tests/common/libeval/test_numeric_evaluator.cpp @@ -148,6 +148,13 @@ static const std::vector eval_cases_valid = { { "x = 1; 1 + x", "2" }, // Multiple set vars { "x = 1; y = 2; 10 + x - y", "9" }, + + // Unicode units - these currently fail +// { wxT( "1um" ), "0.001" }, // GREEK SMALL LETTER MU +// { wxT( "1µm" ), "0.001" }, // GREEK SMALL LETTER MU +// { wxT( "1 µm" ), "0.001" }, // GREEK SMALL LETTER MU +// { wxT( "1µm" ), "0.001" }, // MICRO SIGN +// { wxT( "1 µm" ), "0.001" }, // MICRO SIGN }; @@ -175,6 +182,31 @@ BOOST_AUTO_TEST_CASE( Results ) } } + +/** + * Test unicode parsing of the degree symbol + */ +BOOST_AUTO_TEST_CASE( UnicodeDegree ) +{ + wxString degreeInput = wxT( "1\u00B0" ); + + // Set to degrees and make ready for input + m_eval.SetDefaultUnits( EDA_UNITS::DEGREES ); + m_eval.Clear(); + + m_eval.Process( degreeInput ); + + // These are all valid + BOOST_CHECK_EQUAL( m_eval.IsValid(), true ); + +// Currently disabled since the parser doesn't parse the unicode correctly + //BOOST_CHECK_EQUAL( m_eval.Result(), degreeInput ); + + // Does original text still match? + BOOST_CHECK_EQUAL( m_eval.OriginalText(), degreeInput ); +} + + struct EVAL_INVALID_CASE { wxString input;