/** * Sets "inverse" mode on the <code>UBiDi</code> object. * * @param pTransform Pointer to the <code>UBiDiTransform</code> structure. * @param pErrorCode Pointer to the error code value. * * @return Whether or not this function modifies the text. Besides the return * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>. */ static UBool action_setInverse(UBiDiTransform *pTransform, UErrorCode *pErrorCode) { ubidi_setInverse(pTransform->pBidi, TRUE); ubidi_setReorderingMode(pTransform->pBidi, UBIDI_REORDER_INVERSE_LIKE_DIRECT); return FALSE; }
/** * Sets "runs only" reordering mode indicating a Logical LTR <-> Logical RTL * transformation. * * @param pTransform Pointer to the <code>UBiDiTransform</code> structure. * @param pErrorCode Pointer to the error code value. * * @return Whether or not this function modifies the text. Besides the return * value, the caller should also check <code>U_SUCCESS(*pErrorCode)</code>. */ static UBool action_setRunsOnly(UBiDiTransform *pTransform, UErrorCode *pErrorCode) { (void)pErrorCode; ubidi_setReorderingMode(pTransform->pBidi, UBIDI_REORDER_RUNS_ONLY); return FALSE; }
OSMAND_CORE_API QString OSMAND_CORE_CALL OsmAnd::ICU::convertToVisualOrder(const QString& input) { QString output; const auto len = input.length(); UErrorCode icuError = U_ZERO_ERROR; bool ok = true; // Allocate ICU BiDi context const auto pContext = ubidi_openSized(len, 0, &icuError); if(pContext == nullptr || !U_SUCCESS(icuError)) { LogPrintf(LogSeverityLevel::Error, "ICU error: %d", icuError); return input; } // Configure context to reorder from logical to visual ubidi_setReorderingMode(pContext, UBIDI_REORDER_DEFAULT); // Set data ubidi_setPara(pContext, reinterpret_cast<const UChar*>(input.unicode()), len, UBIDI_DEFAULT_RTL, nullptr, &icuError); ok = U_SUCCESS(icuError); if(ok) { QVector<UChar> reordered(len); ubidi_writeReordered(pContext, reordered.data(), len, UBIDI_DO_MIRRORING | UBIDI_REMOVE_BIDI_CONTROLS, &icuError); ok = U_SUCCESS(icuError); if(ok) { QVector<UChar> reshaped(len); const auto newLen = u_shapeArabic(reordered.constData(), len, reshaped.data(), len, U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_LETTERS_SHAPE | U_SHAPE_LENGTH_FIXED_SPACES_AT_END, &icuError); ok = U_SUCCESS(icuError); if(ok) { output = qMove(QString(reinterpret_cast<const QChar*>(reshaped.constData()), newLen)); } } } // Release context ubidi_close(pContext); if(!ok) { LogPrintf(LogSeverityLevel::Error, "ICU error: %d", icuError); return input; } return output; }