QUnicodeTools: Use thread-safe libthai API
Use th_brk_new()/th_brk_find_breaks() instead of non-thread-safe th_brk(). The new API is available in libthai since version 0.1.25 released on 2016-06-28. [ChangeLog][QtCore] Correct line wrapping of Thai text now requires libthai version 0.1.25 or above. Fixes: QTBUG-105544 Change-Id: I723050bef9f4e6445c946125c74c99e50addadef Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Marc Mutz <marc.mutz@qt.io> (cherry picked from commit 19ca03c21c2cf69fdec4dd8d6a03b92eb96314ca) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
e344e887de
commit
ed739a5c42
@ -1402,11 +1402,19 @@ struct thcell_t {
|
|||||||
unsigned char hilo; /**< upper/lower vowel/diacritic */
|
unsigned char hilo; /**< upper/lower vowel/diacritic */
|
||||||
unsigned char top; /**< top-level mark */
|
unsigned char top; /**< top-level mark */
|
||||||
};
|
};
|
||||||
typedef int (*th_brk_def) (const unsigned char*, int*, size_t);
|
typedef struct _ThBrk ThBrk;
|
||||||
|
typedef ThBrk *(*th_brk_new_def)(const char *);
|
||||||
|
typedef int (*th_brk_find_breaks_def)(ThBrk *, const unsigned char *, int *, size_t);
|
||||||
typedef size_t (*th_next_cell_def) (const unsigned char *, size_t, struct thcell_t *, int);
|
typedef size_t (*th_next_cell_def) (const unsigned char *, size_t, struct thcell_t *, int);
|
||||||
|
|
||||||
|
// Global state for th_brk_find_breaks().
|
||||||
|
// Note: even if signature for th_brk_find_breaks() suggests otherwise, the
|
||||||
|
// state is read-only, and so it is safe to use it from multiple threads after
|
||||||
|
// initialization. This is also stated in the libthai documentation.
|
||||||
|
Q_CONSTINIT static ThBrk *th_state = nullptr;
|
||||||
|
|
||||||
/* libthai related function handles */
|
/* libthai related function handles */
|
||||||
Q_CONSTINIT static th_brk_def th_brk = nullptr;
|
Q_CONSTINIT static th_brk_find_breaks_def th_brk_find_breaks = nullptr;
|
||||||
Q_CONSTINIT static th_next_cell_def th_next_cell = nullptr;
|
Q_CONSTINIT static th_next_cell_def th_next_cell = nullptr;
|
||||||
|
|
||||||
static int init_libthai() {
|
static int init_libthai() {
|
||||||
@ -1416,12 +1424,19 @@ static int init_libthai() {
|
|||||||
if (!initialized.loadAcquire()) {
|
if (!initialized.loadAcquire()) {
|
||||||
const auto locker = std::scoped_lock(mutex);
|
const auto locker = std::scoped_lock(mutex);
|
||||||
if (!initialized.loadAcquire()) {
|
if (!initialized.loadAcquire()) {
|
||||||
th_brk = reinterpret_cast<th_brk_def>(QLibrary::resolve("thai"_L1, LIBTHAI_MAJOR, "th_brk"));
|
th_brk_find_breaks = reinterpret_cast<th_brk_find_breaks_def>(
|
||||||
|
QLibrary::resolve("thai"_L1, LIBTHAI_MAJOR, "th_brk_find_breaks"));
|
||||||
th_next_cell = (th_next_cell_def)QLibrary::resolve("thai"_L1, LIBTHAI_MAJOR, "th_next_cell");
|
th_next_cell = (th_next_cell_def)QLibrary::resolve("thai"_L1, LIBTHAI_MAJOR, "th_next_cell");
|
||||||
|
|
||||||
|
auto th_brk_new = reinterpret_cast<th_brk_new_def>(
|
||||||
|
QLibrary::resolve("thai"_L1, LIBTHAI_MAJOR, "th_brk_new"));
|
||||||
|
if (th_brk_new)
|
||||||
|
th_state = th_brk_new(nullptr);
|
||||||
|
|
||||||
initialized.storeRelease(true);
|
initialized.storeRelease(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (th_brk && th_next_cell)
|
if (th_brk_find_breaks && th_next_cell && th_state)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -1487,7 +1502,8 @@ static void thaiAssignAttributes(const char16_t *string, qsizetype len, QCharAtt
|
|||||||
attributes[0].wordBreak = true;
|
attributes[0].wordBreak = true;
|
||||||
attributes[0].wordStart = true;
|
attributes[0].wordStart = true;
|
||||||
attributes[0].wordEnd = false;
|
attributes[0].wordEnd = false;
|
||||||
numbreaks = th_brk(reinterpret_cast<const unsigned char *>(cstr), break_positions, brp_size);
|
numbreaks = th_brk_find_breaks(th_state, reinterpret_cast<const unsigned char *>(cstr),
|
||||||
|
break_positions, brp_size);
|
||||||
for (i = 0; i < numbreaks; ++i) {
|
for (i = 0; i < numbreaks; ++i) {
|
||||||
attributes[break_positions[i]].wordBreak = true;
|
attributes[break_positions[i]].wordBreak = true;
|
||||||
attributes[break_positions[i]].wordStart = true;
|
attributes[break_positions[i]].wordStart = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user