diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index c330a42e4..ccbdfc5e5 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -131,24 +131,6 @@ bool TextField::ContentView::insertTextAtLocation(const char * text, char * loca *overridenByteLocation = overridenByte; m_currentDraftTextLength += textLength; - // Remove the \n code points - UTF8Decoder decoder(s_draftTextBuffer); - const char * codePointPointer = decoder.stringPosition(); - CodePoint codePoint = decoder.nextCodePoint(); - assert(!codePoint.isCombining()); - while (codePoint != UCodePointNull) { - assert(codePointPointer < s_draftTextBuffer + m_draftTextBufferSize); - if (codePoint == '\n') { - assert(UTF8Decoder::CharSizeOfCodePoint('\n') == 1); - strlcpy(const_cast(codePointPointer), codePointPointer + 1, (s_draftTextBuffer + m_draftTextBufferSize) - codePointPointer); - // Put the decoder to the code point replacing \n - decoder.setPosition(codePointPointer); - } else { - codePointPointer = decoder.stringPosition(); - } - codePoint = decoder.nextCodePoint(); - } - reloadRectFromPosition(m_horizontalAlignment == 0.0f ? location : s_draftTextBuffer); return true; } @@ -508,8 +490,10 @@ bool TextField::handleEventWithText(const char * eventText, bool indentation, bo // Remove the Empty code points constexpr int bufferSize = TextField::maxBufferSize(); char buffer[bufferSize]; - UTF8Helper::CopyAndRemoveCodePoint(buffer, bufferSize, eventText, UCodePointEmpty); - + { + CodePoint c[] = {UCodePointEmpty, '\n'}; + UTF8Helper::CopyAndRemoveCodePoints(buffer, bufferSize, eventText, c, 2); + } // Replace System parentheses (used to keep layout tree structure) by normal parentheses Poincare::SerializationHelper::ReplaceSystemParenthesesByUserParentheses(buffer); diff --git a/ion/include/ion/unicode/utf8_helper.h b/ion/include/ion/unicode/utf8_helper.h index 2c90d7096..d38d3117d 100644 --- a/ion/include/ion/unicode/utf8_helper.h +++ b/ion/include/ion/unicode/utf8_helper.h @@ -20,10 +20,9 @@ bool HasCodePoint(const char * s, CodePoint c); * stopping at the null-terminating char or the start of string. */ const char * NotCodePointSearch(const char * s, CodePoint c, bool goingLeft = false, const char * initialPosition = nullptr); -/* Copy src into dst while removing all code points c. Also update an index - * that should be lower if code points where removed before it. Ensure null- +/* Copy src into dst while removing all code points in codePoints. Ensure null- * termination of dst. */ -void CopyAndRemoveCodePoint(char * dst, size_t dstSize, const char * src, CodePoint c); +void CopyAndRemoveCodePoints(char * dst, size_t dstSize, const char * src, CodePoint * codePoints, int numberOfCodePoints); /* Remove all code points c. and update an index that should be lower if code * points where removed before it. Ensure null-termination of dst. */ diff --git a/ion/src/shared/unicode/utf8_helper.cpp b/ion/src/shared/unicode/utf8_helper.cpp index 76a3fbd72..9facb69a7 100644 --- a/ion/src/shared/unicode/utf8_helper.cpp +++ b/ion/src/shared/unicode/utf8_helper.cpp @@ -94,21 +94,27 @@ const char * NotCodePointSearch(const char * s, CodePoint c, bool goingLeft, con return codePointPointer; } -void CopyAndRemoveCodePoint(char * dst, size_t dstSize, const char * src, CodePoint c) { +void CopyAndRemoveCodePoints(char * dst, size_t dstSize, const char * src, CodePoint * codePoints, int numberOfCodePoints) { if (dstSize <= 0) { return; } + assert(numberOfCodePoints >= 1); UTF8Decoder decoder(src); const char * currentPointer = src; CodePoint codePoint = decoder.nextCodePoint(); const char * nextPointer = decoder.stringPosition(); size_t bufferIndex = 0; - size_t codePointCharSize = UTF8Decoder::CharSizeOfCodePoint(c); - (void)codePointCharSize; // Silence compilation warning about unused variable. // Remove CodePoint c while (codePoint != UCodePointNull && bufferIndex < dstSize) { - if (codePoint != c) { + bool remove = false; + for (int i = 0; i < numberOfCodePoints; i++) { + if (codePoint == codePoints[i]) { + remove = true; + break; + } + } + if (!remove) { size_t copySize = nextPointer - currentPointer; if (copySize > dstSize - 1 - bufferIndex) { // Copying the current code point to the buffer would overflow the buffer diff --git a/ion/test/utf8_helper.cpp b/ion/test/utf8_helper.cpp index cd1d1f36b..39be3b366 100644 --- a/ion/test/utf8_helper.cpp +++ b/ion/test/utf8_helper.cpp @@ -45,10 +45,10 @@ QUIZ_CASE(ion_utf8_helper_not_code_point_search) { assert_not_code_point_searched_is(s, UCodePointGreekSmallLetterPi, true, s+5, s+2); } -void assert_copy_and_remove_code_point_gives(char * dst, size_t dstSize, const char * src, CodePoint c, const char * result) { +void assert_copy_and_remove_code_points_gives(char * dst, size_t dstSize, const char * src, CodePoint * c, int numberOfCodePoints, const char * result) { size_t resultLen = strlen(result); quiz_assert(dstSize >= resultLen + 1); - UTF8Helper::CopyAndRemoveCodePoint(dst, dstSize, src, c); + UTF8Helper::CopyAndRemoveCodePoints(dst, dstSize, src, c, numberOfCodePoints); for (size_t i = 0; i <= resultLen; i++) { quiz_assert(dst[i] == result[i]); } @@ -59,49 +59,54 @@ QUIZ_CASE(ion_utf8_copy_and_remove_code_point) { char buffer[bufferSize]; const char * s = "12345"; - CodePoint c = '1'; + CodePoint c1[] = {'1'}; const char * result = "2345"; - assert_copy_and_remove_code_point_gives(buffer, bufferSize, s, c, result); + assert_copy_and_remove_code_points_gives(buffer, bufferSize, s, c1, 1, result); s = "12345"; - c = '2'; + CodePoint c2[] = {'2'}; result = "1345"; - assert_copy_and_remove_code_point_gives(buffer, bufferSize, s, c, result); + assert_copy_and_remove_code_points_gives(buffer, bufferSize, s, c2, 1, result); s = "2123224252"; - c = '2'; + CodePoint c3[] = {'2'}; result = "1345"; - assert_copy_and_remove_code_point_gives(buffer, bufferSize, s, c, result); + assert_copy_and_remove_code_points_gives(buffer, bufferSize, s, c3, 1, result); s = "12345"; - c = '6'; + CodePoint c4[] = {'6'}; result = "12345"; - assert_copy_and_remove_code_point_gives(buffer, bufferSize, s, c, result); + assert_copy_and_remove_code_points_gives(buffer, bufferSize, s, c4, 1, result); s = "12ᴇ4"; - c = UCodePointLatinLetterSmallCapitalE; + CodePoint c5[] = {UCodePointLatinLetterSmallCapitalE}; result = "124"; - assert_copy_and_remove_code_point_gives(buffer, bufferSize, s, c, result); + assert_copy_and_remove_code_points_gives(buffer, bufferSize, s, c5, 1, result); s = "12ᴇᴇᴇ4"; - c = UCodePointLatinLetterSmallCapitalE; + CodePoint c6[] = {UCodePointLatinLetterSmallCapitalE}; result = "124"; - assert_copy_and_remove_code_point_gives(buffer, bufferSize, s, c, result); + assert_copy_and_remove_code_points_gives(buffer, bufferSize, s, c6, 1, result); // The buffer size is to small to hold s s = "1234ᴇ"; - c = '5'; + CodePoint c7[] = {'5'}; result = "1234"; // "1234ᴇ" size is 7 - assert_copy_and_remove_code_point_gives(buffer, 6, s, c, result); - assert_copy_and_remove_code_point_gives(buffer, 7, s, c, result); + assert_copy_and_remove_code_points_gives(buffer, 6, s, c7, 1, result); + assert_copy_and_remove_code_points_gives(buffer, 7, s, c7, 1, result); result = "1234ᴇ"; - assert_copy_and_remove_code_point_gives(buffer, 8, s, c, result); + assert_copy_and_remove_code_points_gives(buffer, 8, s, c7, 1, result); s = "1234ᴇ"; - c = '4'; + CodePoint c8[] = {'4'}; result = "123ᴇ"; - assert_copy_and_remove_code_point_gives(buffer, 7, s, c, result); + assert_copy_and_remove_code_points_gives(buffer, 7, s, c8, 1, result); + // Remove several code points + s = "1234ᴇ3"; + CodePoint c9[] = {'4', UCodePointLatinLetterSmallCapitalE}; + result = "1233"; + assert_copy_and_remove_code_points_gives(buffer, bufferSize, s, c9, 2, result); } void assert_remove_code_point_gives(char * buffer, CodePoint c, const char * * indexToUpdate, const char * stoppingPosition, const char * indexToUpdateResult, const char * result) {