diff options
-rw-r--r-- | src/corelib/text/qtextboundaryfinder.cpp | 174 | ||||
-rw-r--r-- | src/corelib/text/qtextboundaryfinder.h | 28 | ||||
-rw-r--r-- | src/corelib/text/qunicodetools.cpp | 170 | ||||
-rw-r--r-- | src/corelib/text/qunicodetools_p.h | 8 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 5 | ||||
-rw-r--r-- | tests/auto/corelib/text/qtextboundaryfinder/tst_qtextboundaryfinder.cpp | 2 |
6 files changed, 187 insertions, 200 deletions
diff --git a/src/corelib/text/qtextboundaryfinder.cpp b/src/corelib/text/qtextboundaryfinder.cpp index fdbb7f0176..dd0b96ed68 100644 --- a/src/corelib/text/qtextboundaryfinder.cpp +++ b/src/corelib/text/qtextboundaryfinder.cpp @@ -43,18 +43,10 @@ QT_BEGIN_NAMESPACE -class QTextBoundaryFinderPrivate +static void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes) { -public: - QCharAttributes attributes[1]; -}; - -static void init(QTextBoundaryFinder::BoundaryType type, const QChar *chars, int length, QCharAttributes *attributes) -{ - const ushort *string = reinterpret_cast<const ushort *>(chars); - QUnicodeTools::ScriptItemArray scriptItems; - QUnicodeTools::initScripts(string, length, &scriptItems); + QUnicodeTools::initScripts(str, &scriptItems); QUnicodeTools::CharAttributeOptions options; switch (type) { @@ -64,7 +56,7 @@ static void init(QTextBoundaryFinder::BoundaryType type, const QChar *chars, int case QTextBoundaryFinder::Line: options |= QUnicodeTools::LineBreaks; break; default: break; } - QUnicodeTools::initCharAttributes(string, length, scriptItems.data(), scriptItems.count(), attributes, options); + QUnicodeTools::initCharAttributes(str, scriptItems.data(), scriptItems.count(), attributes, options); } /*! @@ -145,11 +137,7 @@ static void init(QTextBoundaryFinder::BoundaryType type, const QChar *chars, int Constructs an invalid QTextBoundaryFinder object. */ QTextBoundaryFinder::QTextBoundaryFinder() - : t(Grapheme) - , chars(nullptr) - , length(0) - , freePrivate(true) - , d(nullptr) + : freeBuffer(true) { } @@ -159,17 +147,15 @@ QTextBoundaryFinder::QTextBoundaryFinder() QTextBoundaryFinder::QTextBoundaryFinder(const QTextBoundaryFinder &other) : t(other.t) , s(other.s) - , chars(other.chars) - , length(other.length) + , sv(other.sv) , pos(other.pos) - , freePrivate(true) - , d(nullptr) + , freeBuffer(true) { - if (other.d) { - Q_ASSERT(length > 0); - d = (QTextBoundaryFinderPrivate *) malloc((length + 1) * sizeof(QCharAttributes)); - Q_CHECK_PTR(d); - memcpy(d, other.d, (length + 1) * sizeof(QCharAttributes)); + if (other.attributes) { + Q_ASSERT(sv.size() > 0); + attributes = (QCharAttributes *) malloc((sv.size() + 1) * sizeof(QCharAttributes)); + Q_CHECK_PTR(attributes); + memcpy(attributes, other.attributes, (sv.size() + 1) * sizeof(QCharAttributes)); } } @@ -181,27 +167,26 @@ QTextBoundaryFinder &QTextBoundaryFinder::operator=(const QTextBoundaryFinder &o if (&other == this) return *this; - if (other.d) { - Q_ASSERT(other.length > 0); - uint newCapacity = (other.length + 1) * sizeof(QCharAttributes); - QTextBoundaryFinderPrivate *newD = (QTextBoundaryFinderPrivate *) realloc(freePrivate ? d : nullptr, newCapacity); + if (other.attributes) { + Q_ASSERT(other.sv.size() > 0); + size_t newCapacity = (size_t(other.sv.size()) + 1) * sizeof(QCharAttributes); + QCharAttributes *newD = (QCharAttributes *) realloc(freeBuffer ? attributes : nullptr, newCapacity); Q_CHECK_PTR(newD); - freePrivate = true; - d = newD; + freeBuffer = true; + attributes = newD; } t = other.t; s = other.s; - chars = other.chars; - length = other.length; + sv = other.sv; pos = other.pos; - if (other.d) { - memcpy(d, other.d, (length + 1) * sizeof(QCharAttributes)); + if (other.attributes) { + memcpy(attributes, other.attributes, (sv.size() + 1) * sizeof(QCharAttributes)); } else { - if (freePrivate) - free(d); - d = nullptr; + if (freeBuffer) + free(attributes); + attributes = nullptr; } return *this; @@ -213,8 +198,8 @@ QTextBoundaryFinder &QTextBoundaryFinder::operator=(const QTextBoundaryFinder &o QTextBoundaryFinder::~QTextBoundaryFinder() { Q_UNUSED(unused); - if (freePrivate) - free(d); + if (freeBuffer) + free(attributes); } /*! @@ -223,22 +208,28 @@ QTextBoundaryFinder::~QTextBoundaryFinder() QTextBoundaryFinder::QTextBoundaryFinder(BoundaryType type, const QString &string) : t(type) , s(string) - , chars(string.unicode()) - , length(string.length()) + , sv(s) , pos(0) - , freePrivate(true) - , d(nullptr) + , freeBuffer(true) + , attributes(nullptr) { - if (length > 0) { - d = (QTextBoundaryFinderPrivate *) malloc((length + 1) * sizeof(QCharAttributes)); - Q_CHECK_PTR(d); - init(t, chars, length, d->attributes); + if (sv.size() > 0) { + attributes = (QCharAttributes *) malloc((sv.size() + 1) * sizeof(QCharAttributes)); + Q_CHECK_PTR(attributes); + init(t, sv, attributes); } } /*! - Creates a QTextBoundaryFinder object of \a type operating on \a chars - with \a length. + \fn QTextBoundaryFinder::QTextBoundaryFinder(BoundaryType type, const QChar *chars, qsizetype length, unsigned char *buffer, qsizetype bufferSize) + \overload + + The same as QTextBoundaryFinder(type, QStringView(chars, length), buffer, bufferSize). +*/ + +/*! + Creates a QTextBoundaryFinder object of \a type operating on \a string. + \since 6.0 \a buffer is an optional working buffer of size \a bufferSize you can pass to the QTextBoundaryFinder. If the buffer is large enough to hold the working @@ -250,25 +241,22 @@ QTextBoundaryFinder::QTextBoundaryFinder(BoundaryType type, const QString &strin as long as the QTextBoundaryFinder object stays alive. The same applies to \a buffer. */ -QTextBoundaryFinder::QTextBoundaryFinder(BoundaryType type, const QChar *chars, int length, unsigned char *buffer, int bufferSize) +QTextBoundaryFinder::QTextBoundaryFinder(BoundaryType type, QStringView string, unsigned char *buffer, qsizetype bufferSize) : t(type) - , chars(chars) - , length(length) + , sv(string) , pos(0) - , freePrivate(true) - , d(nullptr) + , freeBuffer(true) + , attributes(nullptr) { - if (!chars) { - length = 0; - } else if (length > 0) { - if (buffer && (uint)bufferSize >= (length + 1) * sizeof(QCharAttributes)) { - d = (QTextBoundaryFinderPrivate *)buffer; - freePrivate = false; + if (!sv.isEmpty()) { + if (buffer && (uint)bufferSize >= (sv.size() + 1) * sizeof(QCharAttributes)) { + attributes = reinterpret_cast<QCharAttributes *>(buffer); + freeBuffer = false; } else { - d = (QTextBoundaryFinderPrivate *) malloc((length + 1) * sizeof(QCharAttributes)); - Q_CHECK_PTR(d); + attributes = (QCharAttributes *) malloc((sv.size() + 1) * sizeof(QCharAttributes)); + Q_CHECK_PTR(attributes); } - init(t, chars, length, d->attributes); + init(t, sv, attributes); } } @@ -289,7 +277,7 @@ void QTextBoundaryFinder::toStart() */ void QTextBoundaryFinder::toEnd() { - pos = length; + pos = sv.size(); } /*! @@ -300,7 +288,7 @@ void QTextBoundaryFinder::toEnd() \sa setPosition() */ -int QTextBoundaryFinder::position() const +qsizetype QTextBoundaryFinder::position() const { return pos; } @@ -314,9 +302,9 @@ int QTextBoundaryFinder::position() const \sa position() */ -void QTextBoundaryFinder::setPosition(int position) +void QTextBoundaryFinder::setPosition(qsizetype position) { - pos = qBound(0, position, length); + pos = qBound(0, position, sv.size()); } /*! \fn QTextBoundaryFinder::BoundaryType QTextBoundaryFinder::type() const @@ -335,9 +323,9 @@ void QTextBoundaryFinder::setPosition(int position) */ QString QTextBoundaryFinder::string() const { - if (chars == s.unicode() && length == s.length()) + if (sv.data() == s.unicode() && sv.size() == s.size()) return s; - return QString(chars, length); + return sv.toString(); } @@ -346,9 +334,9 @@ QString QTextBoundaryFinder::string() const Returns -1 if there is no next boundary. */ -int QTextBoundaryFinder::toNextBoundary() +qsizetype QTextBoundaryFinder::toNextBoundary() { - if (!d || pos < 0 || pos >= length) { + if (!attributes || pos < 0 || pos >= sv.size()) { pos = -1; return pos; } @@ -356,19 +344,19 @@ int QTextBoundaryFinder::toNextBoundary() ++pos; switch(t) { case Grapheme: - while (pos < length && !d->attributes[pos].graphemeBoundary) + while (pos < sv.size() && !attributes[pos].graphemeBoundary) ++pos; break; case Word: - while (pos < length && !d->attributes[pos].wordBreak) + while (pos < sv.size() && !attributes[pos].wordBreak) ++pos; break; case Sentence: - while (pos < length && !d->attributes[pos].sentenceBoundary) + while (pos < sv.size() && !attributes[pos].sentenceBoundary) ++pos; break; case Line: - while (pos < length && !d->attributes[pos].lineBreak) + while (pos < sv.size() && !attributes[pos].lineBreak) ++pos; break; } @@ -381,9 +369,9 @@ int QTextBoundaryFinder::toNextBoundary() Returns -1 if there is no previous boundary. */ -int QTextBoundaryFinder::toPreviousBoundary() +qsizetype QTextBoundaryFinder::toPreviousBoundary() { - if (!d || pos <= 0 || pos > length) { + if (!attributes || pos <= 0 || pos > sv.size()) { pos = -1; return pos; } @@ -391,19 +379,19 @@ int QTextBoundaryFinder::toPreviousBoundary() --pos; switch(t) { case Grapheme: - while (pos > 0 && !d->attributes[pos].graphemeBoundary) + while (pos > 0 && !attributes[pos].graphemeBoundary) --pos; break; case Word: - while (pos > 0 && !d->attributes[pos].wordBreak) + while (pos > 0 && !attributes[pos].wordBreak) --pos; break; case Sentence: - while (pos > 0 && !d->attributes[pos].sentenceBoundary) + while (pos > 0 && !attributes[pos].sentenceBoundary) --pos; break; case Line: - while (pos > 0 && !d->attributes[pos].lineBreak) + while (pos > 0 && !attributes[pos].lineBreak) --pos; break; } @@ -416,19 +404,19 @@ int QTextBoundaryFinder::toPreviousBoundary() */ bool QTextBoundaryFinder::isAtBoundary() const { - if (!d || pos < 0 || pos > length) + if (!attributes || pos < 0 || pos > sv.size()) return false; switch(t) { case Grapheme: - return d->attributes[pos].graphemeBoundary; + return attributes[pos].graphemeBoundary; case Word: - return d->attributes[pos].wordBreak; + return attributes[pos].wordBreak; case Sentence: - return d->attributes[pos].sentenceBoundary; + return attributes[pos].sentenceBoundary; case Line: // ### TR#14 LB2 prohibits break at sot - return d->attributes[pos].lineBreak || pos == 0; + return attributes[pos].lineBreak || pos == 0; } return false; } @@ -439,17 +427,17 @@ bool QTextBoundaryFinder::isAtBoundary() const QTextBoundaryFinder::BoundaryReasons QTextBoundaryFinder::boundaryReasons() const { BoundaryReasons reasons = NotAtBoundary; - if (!d || pos < 0 || pos > length) + if (!attributes || pos < 0 || pos > sv.size()) return reasons; - const QCharAttributes attr = d->attributes[pos]; + const QCharAttributes attr = attributes[pos]; switch (t) { case Grapheme: if (attr.graphemeBoundary) { reasons |= BreakOpportunity | StartOfItem | EndOfItem; if (pos == 0) reasons &= (~EndOfItem); - else if (pos == length) + else if (pos == sv.size()) reasons &= (~StartOfItem); } break; @@ -467,7 +455,7 @@ QTextBoundaryFinder::BoundaryReasons QTextBoundaryFinder::boundaryReasons() cons reasons |= BreakOpportunity | StartOfItem | EndOfItem; if (pos == 0) reasons &= (~EndOfItem); - else if (pos == length) + else if (pos == sv.size()) reasons &= (~StartOfItem); } break; @@ -479,9 +467,9 @@ QTextBoundaryFinder::BoundaryReasons QTextBoundaryFinder::boundaryReasons() cons reasons |= MandatoryBreak | StartOfItem | EndOfItem; if (pos == 0) reasons &= (~EndOfItem); - else if (pos == length) + else if (pos == sv.size()) reasons &= (~StartOfItem); - } else if (pos > 0 && chars[pos - 1].unicode() == QChar::SoftHyphen) { + } else if (pos > 0 && sv[pos - 1].unicode() == QChar::SoftHyphen) { reasons |= SoftHyphen; } } diff --git a/src/corelib/text/qtextboundaryfinder.h b/src/corelib/text/qtextboundaryfinder.h index b1e5008f54..0b1c910728 100644 --- a/src/corelib/text/qtextboundaryfinder.h +++ b/src/corelib/text/qtextboundaryfinder.h @@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE -class QTextBoundaryFinderPrivate; +struct QCharAttributes; class Q_CORE_EXPORT QTextBoundaryFinder { @@ -74,33 +74,35 @@ public: Q_DECLARE_FLAGS( BoundaryReasons, BoundaryReason ) QTextBoundaryFinder(BoundaryType type, const QString &string); - QTextBoundaryFinder(BoundaryType type, const QChar *chars, int length, unsigned char *buffer = nullptr, int bufferSize = 0); + QTextBoundaryFinder(BoundaryType type, const QChar *chars, qsizetype length, unsigned char *buffer = nullptr, qsizetype bufferSize = 0) + : QTextBoundaryFinder(type, QStringView(chars, length), buffer, bufferSize) + {} + QTextBoundaryFinder(BoundaryType type, QStringView str, unsigned char *buffer = nullptr, qsizetype bufferSize = 0); - inline bool isValid() const { return d; } + inline bool isValid() const { return attributes; } inline BoundaryType type() const { return t; } QString string() const; void toStart(); void toEnd(); - int position() const; - void setPosition(int position); + qsizetype position() const; + void setPosition(qsizetype position); - int toNextBoundary(); - int toPreviousBoundary(); + qsizetype toNextBoundary(); + qsizetype toPreviousBoundary(); bool isAtBoundary() const; BoundaryReasons boundaryReasons() const; private: - BoundaryType t; + BoundaryType t = Grapheme; QString s; - const QChar *chars; - int length; - int pos; - uint freePrivate : 1; + QStringView sv; + qsizetype pos; + uint freeBuffer : 1; uint unused : 31; - QTextBoundaryFinderPrivate *d; + QCharAttributes *attributes = nullptr; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QTextBoundaryFinder::BoundaryReasons) diff --git a/src/corelib/text/qunicodetools.cpp b/src/corelib/text/qunicodetools.cpp index 9e56686893..7b69da8c2c 100644 --- a/src/corelib/text/qunicodetools.cpp +++ b/src/corelib/text/qunicodetools.cpp @@ -97,12 +97,12 @@ static const State breakTable[QUnicodeTables::NumGraphemeBreakClasses][QUnicodeT } // namespace GB -static void getGraphemeBreaks(const ushort *string, quint32 len, QCharAttributes *attributes) +static void getGraphemeBreaks(const char16_t *string, qsizetype len, QCharAttributes *attributes) { QUnicodeTables::GraphemeBreakClass lcls = QUnicodeTables::GraphemeBreak_LF; // to meet GB1 GB::State state = GB::Break; // only required to track some of the rules - for (quint32 i = 0; i != len; ++i) { - quint32 pos = i; + for (qsizetype i = 0; i != len; ++i) { + qsizetype pos = i; char32_t ucs4 = string[i]; if (QChar::isHighSurrogate(ucs4) && i + 1 != len) { ushort low = string[i + 1]; @@ -191,15 +191,15 @@ static const uchar breakTable[QUnicodeTables::NumWordBreakClasses][QUnicodeTable } // namespace WB -static void getWordBreaks(const ushort *string, quint32 len, QCharAttributes *attributes) +static void getWordBreaks(const char16_t *string, qsizetype len, QCharAttributes *attributes) { enum WordType { WordTypeNone, WordTypeAlphaNumeric, WordTypeHiraganaKatakana } currentWordType = WordTypeNone; QUnicodeTables::WordBreakClass cls = QUnicodeTables::WordBreak_LF; // to meet WB1 - for (quint32 i = 0; i != len; ++i) { - quint32 pos = i; + for (qsizetype i = 0; i != len; ++i) { + qsizetype pos = i; char32_t ucs4 = string[i]; if (QChar::isHighSurrogate(ucs4) && i + 1 != len) { ushort low = string[i + 1]; @@ -241,7 +241,7 @@ static void getWordBreaks(const ushort *string, quint32 len, QCharAttributes *at break; case WB::Lookup: case WB::LookupW: - for (quint32 lookahead = i + 1; lookahead < len; ++lookahead) { + for (qsizetype lookahead = i + 1; lookahead < len; ++lookahead) { ucs4 = string[lookahead]; if (QChar::isHighSurrogate(ucs4) && lookahead + 1 != len) { ushort low = string[lookahead + 1]; @@ -343,11 +343,11 @@ static const uchar breakTable[BAfter + 1][QUnicodeTables::NumSentenceBreakClasse } // namespace SB -static void getSentenceBreaks(const ushort *string, quint32 len, QCharAttributes *attributes) +static void getSentenceBreaks(const char16_t *string, qsizetype len, QCharAttributes *attributes) { uchar state = SB::BAfter; // to meet SB1 - for (quint32 i = 0; i != len; ++i) { - quint32 pos = i; + for (qsizetype i = 0; i != len; ++i) { + qsizetype pos = i; char32_t ucs4 = string[i]; if (QChar::isHighSurrogate(ucs4) && i + 1 != len) { ushort low = string[i + 1]; @@ -364,7 +364,7 @@ static void getSentenceBreaks(const ushort *string, quint32 len, QCharAttributes state = SB::breakTable[state][ncls]; if (Q_UNLIKELY(state == SB::Lookup)) { // SB8 state = SB::Break; - for (quint32 lookahead = i + 1; lookahead < len; ++lookahead) { + for (qsizetype lookahead = i + 1; lookahead < len; ++lookahead) { ucs4 = string[lookahead]; if (QChar::isHighSurrogate(ucs4) && lookahead + 1 != len) { ushort low = string[lookahead + 1]; @@ -542,15 +542,15 @@ static const uchar breakTable[QUnicodeTables::LineBreak_SA][QUnicodeTables::Line } // namespace LB -static void getLineBreaks(const ushort *string, quint32 len, QCharAttributes *attributes, QUnicodeTools::CharAttributeOptions options) +static void getLineBreaks(const char16_t *string, qsizetype len, QCharAttributes *attributes, QUnicodeTools::CharAttributeOptions options) { - quint32 nestart = 0; + qsizetype nestart = 0; LB::NS::Class nelast = LB::NS::XX; QUnicodeTables::LineBreakClass lcls = QUnicodeTables::LineBreak_LF; // to meet LB10 QUnicodeTables::LineBreakClass cls = lcls; - for (quint32 i = 0; i != len; ++i) { - quint32 pos = i; + for (qsizetype i = 0; i != len; ++i) { + qsizetype pos = i; char32_t ucs4 = string[i]; if (QChar::isHighSurrogate(ucs4) && i + 1 != len) { ushort low = string[i + 1]; @@ -632,7 +632,7 @@ static void getLineBreaks(const ushort *string, quint32 len, QCharAttributes *at switch (LB::NS::actionTable[nelast][necur]) { case LB::NS::Break: // do not change breaks before and after the expression - for (quint32 j = nestart + 1; j < pos; ++j) + for (qsizetype j = nestart + 1; j < pos; ++j) attributes[j].lineBreak = false; Q_FALLTHROUGH(); case LB::NS::None: @@ -697,7 +697,7 @@ static void getLineBreaks(const ushort *string, quint32 len, QCharAttributes *at if (Q_UNLIKELY(LB::NS::actionTable[nelast][LB::NS::XX] == LB::NS::Break)) { // LB25: do not break lines inside numbers - for (quint32 j = nestart + 1; j < len; ++j) + for (qsizetype j = nestart + 1; j < len; ++j) attributes[j].lineBreak = false; } @@ -706,9 +706,9 @@ static void getLineBreaks(const ushort *string, quint32 len, QCharAttributes *at } -static void getWhiteSpaces(const ushort *string, quint32 len, QCharAttributes *attributes) +static void getWhiteSpaces(const char16_t *string, qsizetype len, QCharAttributes *attributes) { - for (quint32 i = 0; i != len; ++i) { + for (qsizetype i = 0; i != len; ++i) { uint ucs4 = string[i]; if (QChar::isHighSurrogate(ucs4) && i + 1 != len) { ushort low = string[i + 1]; @@ -725,7 +725,7 @@ static void getWhiteSpaces(const ushort *string, quint32 len, QCharAttributes *a namespace Tailored { -using CharAttributeFunction = void (*)(QChar::Script script, const ushort *text, uint from, uint len, QCharAttributes *attributes); +using CharAttributeFunction = void (*)(QChar::Script script, const char16_t *text, qsizetype from, qsizetype len, QCharAttributes *attributes); enum Form { @@ -1181,15 +1181,15 @@ static inline Form form(unsigned short uc) { We return syllable boundaries on invalid combinations aswell */ -static int indic_nextSyllableBoundary(QChar::Script script, const ushort *s, int start, int end, bool *invalid) +static qsizetype indic_nextSyllableBoundary(QChar::Script script, const char16_t *s, qsizetype start, qsizetype end, bool *invalid) { *invalid = false; - IDEBUG("indic_nextSyllableBoundary: start=%d, end=%d", start, end); - const ushort *uc = s+start; + IDEBUG("indic_nextSyllableBoundary: start=%d, end=%d", int(start), int(end)); + const char16_t *uc = s+start; - int pos = 0; + qsizetype pos = 0; Form state = form(uc[pos]); - IDEBUG("state[%d]=%d (uc=%4x)", pos, state, uc[pos]); + IDEBUG("state[%d]=%d (uc=%4x)", int(pos), state, uc[pos]); pos++; if (state != Consonant && state != IndependentVowel) { @@ -1200,7 +1200,7 @@ static int indic_nextSyllableBoundary(QChar::Script script, const ushort *s, int while (pos < end - start) { Form newState = form(uc[pos]); - IDEBUG("state[%d]=%d (uc=%4x)", pos, newState, uc[pos]); + IDEBUG("state[%d]=%d (uc=%4x)", int(pos), newState, uc[pos]); switch (newState) { case Control: newState = state; @@ -1285,15 +1285,15 @@ static int indic_nextSyllableBoundary(QChar::Script script, const ushort *s, int return pos+start; } -static void indicAttributes(QChar::Script script, const ushort *text, uint from, uint len, QCharAttributes *attributes) +static void indicAttributes(QChar::Script script, const char16_t *text, qsizetype from, qsizetype len, QCharAttributes *attributes) { - int end = from + len; - const ushort *uc = text + from; + qsizetype end = from + len; + const char16_t *uc = text + from; attributes += from; - uint i = 0; + qsizetype i = 0; while (i < len) { bool invalid; - uint boundary = indic_nextSyllableBoundary(script, text, from+i, end, &invalid) - from; + qsizetype boundary = indic_nextSyllableBoundary(script, text, from+i, end, &invalid) - from; attributes[i].graphemeBoundary = true; if (boundary > len-1) boundary = len; @@ -1339,9 +1339,9 @@ static int init_libthai() { return 0; } -static void to_tis620(const ushort *string, uint len, char *cstr) +static void to_tis620(const char16_t *string, qsizetype len, char *cstr) { - uint i; + qsizetype i; unsigned char *result = (unsigned char *)cstr; for (i = 0; i < len; ++i) { @@ -1359,14 +1359,14 @@ static void to_tis620(const ushort *string, uint len, char *cstr) /* * Thai Attributes: computes Word Break, Word Boundary and Char stop for THAI. */ -static void thaiAssignAttributes(const ushort *string, uint len, QCharAttributes *attributes) +static void thaiAssignAttributes(const char16_t *string, qsizetype len, QCharAttributes *attributes) { char s[128]; char *cstr = s; int *break_positions = nullptr; int brp[128]; int brp_size = 0; - uint numbreaks, i, j, cell_length; + qsizetype numbreaks, i, j, cell_length; struct thcell_t tis_cell; if (!init_libthai()) @@ -1432,10 +1432,10 @@ static void thaiAssignAttributes(const ushort *string, uint len, QCharAttributes free(cstr); } -static void thaiAttributes(QChar::Script script, const ushort *text, uint from, uint len, QCharAttributes *attributes) +static void thaiAttributes(QChar::Script script, const char16_t *text, qsizetype from, qsizetype len, QCharAttributes *attributes) { assert(script == QChar::Script_Thai); - const ushort *uc = text + from; + const char16_t *uc = text + from; attributes += from; Q_UNUSED(script); thaiAssignAttributes(uc, len, attributes); @@ -1505,11 +1505,11 @@ static const unsigned char tibetanForm[0x80] = { #define tibetan_form(c) \ ((c) >= 0x0f40 && (c) < 0x0fc0 ? (TibetanForm)tibetanForm[(c) - 0x0f40] : TibetanOther) -static int tibetan_nextSyllableBoundary(const ushort *s, int start, int end, bool *invalid) +static qsizetype tibetan_nextSyllableBoundary(const char16_t *s, qsizetype start, qsizetype end, bool *invalid) { - const ushort *uc = s + start; + const char16_t *uc = s + start; - int pos = 0; + qsizetype pos = 0; TibetanForm state = tibetan_form(*uc); /* qDebug("state[%d]=%d (uc=%4x)", pos, state, uc[pos]);*/ @@ -1549,16 +1549,16 @@ finish: return start+pos; } -static void tibetanAttributes(QChar::Script script, const ushort *text, uint from, uint len, QCharAttributes *attributes) +static void tibetanAttributes(QChar::Script script, const char16_t *text, qsizetype from, qsizetype len, QCharAttributes *attributes) { - int end = from + len; - const ushort *uc = text + from; - uint i = 0; + qsizetype end = from + len; + const char16_t *uc = text + from; + qsizetype i = 0; Q_UNUSED(script); attributes += from; while (i < len) { bool invalid; - uint boundary = tibetan_nextSyllableBoundary(text, from+i, end, &invalid) - from; + qsizetype boundary = tibetan_nextSyllableBoundary(text, from+i, end, &invalid) - from; attributes[i].graphemeBoundary = true; @@ -1736,11 +1736,11 @@ static const signed char mymrStateTable[][Mymr_CC_COUNT] = // calculate, using the state table, which one is the last character of the syllable // that starts in the starting position. */ -static int myanmar_nextSyllableBoundary(const ushort *s, int start, int end, bool *invalid) +static qsizetype myanmar_nextSyllableBoundary(const char16_t *s, qsizetype start, qsizetype end, bool *invalid) { - const ushort *uc = s + start; + const char16_t *uc = s + start; int state = 0; - int pos = start; + qsizetype pos = start; *invalid = false; while (pos < end) { @@ -1749,7 +1749,7 @@ static int myanmar_nextSyllableBoundary(const ushort *s, int start, int end, boo if (pos == start) *invalid = (bool)(charClass & Mymr_CF_DOTTED_CIRCLE); - MMDEBUG("state[%d]=%d class=%8x (uc=%4x)", pos - start, state, charClass, *uc); + MMDEBUG("state[%d]=%d class=%8x (uc=%4x)", int(pos - start), state, charClass, *uc); if (state < 0) { if (state < -1) @@ -1762,16 +1762,16 @@ static int myanmar_nextSyllableBoundary(const ushort *s, int start, int end, boo return pos; } -static void myanmarAttributes(QChar::Script script, const ushort *text, uint from, uint len, QCharAttributes *attributes) +static void myanmarAttributes(QChar::Script script, const char16_t *text, qsizetype from, qsizetype len, QCharAttributes *attributes) { - int end = from + len; - const ushort *uc = text + from; - uint i = 0; + qsizetype end = from + len; + const char16_t *uc = text + from; + qsizetype i = 0; Q_UNUSED(script); attributes += from; while (i < len) { bool invalid; - uint boundary = myanmar_nextSyllableBoundary(text, from+i, end, &invalid) - from; + qsizetype boundary = myanmar_nextSyllableBoundary(text, from+i, end, &invalid) - from; attributes[i].graphemeBoundary = true; attributes[i].lineBreak = true; @@ -2071,11 +2071,11 @@ static const signed char khmerStateTable[][CC_COUNT] = // calculate, using the state table, which one is the last character of the syllable // that starts in the starting position. */ -static int khmer_nextSyllableBoundary(const ushort *s, int start, int end, bool *invalid) +static qsizetype khmer_nextSyllableBoundary(const char16_t *s, qsizetype start, qsizetype end, bool *invalid) { - const ushort *uc = s + start; + const char16_t *uc = s + start; int state = 0; - int pos = start; + qsizetype pos = start; *invalid = false; while (pos < end) { @@ -2085,7 +2085,7 @@ static int khmer_nextSyllableBoundary(const ushort *s, int start, int end, bool } state = khmerStateTable[state][charClass & CF_CLASS_MASK]; - KHDEBUG("state[%d]=%d class=%8lx (uc=%4x)", pos - start, state, + KHDEBUG("state[%d]=%d class=%8lx (uc=%4x)", int(pos - start), state, charClass, *uc ); if (state < 0) { @@ -2097,16 +2097,16 @@ static int khmer_nextSyllableBoundary(const ushort *s, int start, int end, bool return pos; } -static void khmerAttributes(QChar::Script script, const ushort *text, uint from, uint len, QCharAttributes *attributes) +static void khmerAttributes(QChar::Script script, const char16_t *text, qsizetype from, qsizetype len, QCharAttributes *attributes) { - int end = from + len; - const ushort *uc = text + from; - uint i = 0; + qsizetype end = from + len; + const char16_t *uc = text + from; + qsizetype i = 0; Q_UNUSED(script); attributes += from; while ( i < len ) { bool invalid; - uint boundary = khmer_nextSyllableBoundary( text, from+i, end, &invalid ) - from; + qsizetype boundary = khmer_nextSyllableBoundary( text, from+i, end, &invalid ) - from; attributes[i].graphemeBoundary = true; @@ -2191,52 +2191,52 @@ const CharAttributeFunction charAttributeFunction[] = { khmerAttributes }; -static void getCharAttributes(const ushort *string, uint stringLength, - const QUnicodeTools::ScriptItem *items, uint numItems, +static void getCharAttributes(const char16_t *string, qsizetype stringLength, + const QUnicodeTools::ScriptItem *items, qsizetype numItems, QCharAttributes *attributes) { if (stringLength == 0) return; - for (uint i = 0; i < numItems; ++i) { + for (qsizetype i = 0; i < numItems; ++i) { QChar::Script script = items[i].script; if (script > QChar::Script_Khmer) script = QChar::Script_Common; CharAttributeFunction attributeFunction = charAttributeFunction[script]; if (!attributeFunction) continue; - int end = i < numItems - 1 ? items[i + 1].position : stringLength; + qsizetype end = i < numItems - 1 ? items[i + 1].position : stringLength; attributeFunction(script, string, items[i].position, end - items[i].position, attributes); } } } -Q_CORE_EXPORT void initCharAttributes(const ushort *string, int length, - const ScriptItem *items, int numItems, +Q_CORE_EXPORT void initCharAttributes(QStringView string, + const ScriptItem *items, qsizetype numItems, QCharAttributes *attributes, CharAttributeOptions options) { - if (length <= 0) + if (string.size() <= 0) return; if (!(options & DontClearAttributes)) - ::memset(attributes, 0, (length + 1) * sizeof(QCharAttributes)); + ::memset(attributes, 0, (string.size() + 1) * sizeof(QCharAttributes)); if (options & GraphemeBreaks) - getGraphemeBreaks(string, length, attributes); + getGraphemeBreaks(string.utf16(), string.size(), attributes); if (options & WordBreaks) - getWordBreaks(string, length, attributes); + getWordBreaks(string.utf16(), string.size(), attributes); if (options & SentenceBreaks) - getSentenceBreaks(string, length, attributes); + getSentenceBreaks(string.utf16(), string.size(), attributes); if (options & LineBreaks) - getLineBreaks(string, length, attributes, options); + getLineBreaks(string.utf16(), string.size(), attributes, options); if (options & WhiteSpaces) - getWhiteSpaces(string, length, attributes); + getWhiteSpaces(string.utf16(), string.size(), attributes); if (!qt_initcharattributes_default_algorithm_only) { if (!items || numItems <= 0) return; - Tailored::getCharAttributes(string, length, items, numItems, attributes); + Tailored::getCharAttributes(string.utf16(), string.size(), items, numItems, attributes); } } @@ -2247,16 +2247,16 @@ Q_CORE_EXPORT void initCharAttributes(const ushort *string, int length, // // ---------------------------------------------------------------------------- -Q_CORE_EXPORT void initScripts(const ushort *string, int length, ScriptItemArray *scripts) +Q_CORE_EXPORT void initScripts(QStringView string, ScriptItemArray *scripts) { - int sor = 0; - int eor = 0; + qsizetype sor = 0; + qsizetype eor = 0; QChar::Script script = QChar::Script_Common; - for (int i = 0; i < length; ++i, eor = i) { - char32_t ucs4 = string[i]; - if (QChar::isHighSurrogate(ucs4) && i + 1 < length) { - ushort low = string[i + 1]; + for (qsizetype i = 0; i < string.size(); ++i, eor = i) { + char32_t ucs4 = string[i].unicode(); + if (QChar::isHighSurrogate(ucs4) && i + 1 < string.size()) { + ushort low = string[i + 1].unicode(); if (QChar::isLowSurrogate(low)) { ucs4 = QChar::surrogateToUcs4(ucs4, low); ++i; @@ -2294,7 +2294,7 @@ Q_CORE_EXPORT void initScripts(const ushort *string, int length, ScriptItemArray } Q_ASSERT(script >= QChar::Script_Common); - Q_ASSERT(eor == length); + Q_ASSERT(eor == string.size()); scripts->append(ScriptItem{sor, script}); } diff --git a/src/corelib/text/qunicodetools_p.h b/src/corelib/text/qunicodetools_p.h index 259f3f209e..cecb6defc7 100644 --- a/src/corelib/text/qunicodetools_p.h +++ b/src/corelib/text/qunicodetools_p.h @@ -74,7 +74,7 @@ namespace QUnicodeTools { struct ScriptItem { - int position; + qsizetype position; QChar::Script script; }; @@ -97,12 +97,12 @@ enum CharAttributeOption { Q_DECLARE_FLAGS(CharAttributeOptions, CharAttributeOption) // attributes buffer has to have a length of string length + 1 -Q_CORE_EXPORT void initCharAttributes(const ushort *string, int length, - const ScriptItem *items, int numItems, +Q_CORE_EXPORT void initCharAttributes(QStringView str, + const ScriptItem *items, qsizetype numItems, QCharAttributes *attributes, CharAttributeOptions options); -Q_CORE_EXPORT void initScripts(const ushort *string, int length, ScriptItemArray *scripts); +Q_CORE_EXPORT void initScripts(QStringView str, ScriptItemArray *scripts); } // namespace QUnicodeTools diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 9e104e118e..074771beaa 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1808,8 +1808,7 @@ const QCharAttributes *QTextEngine::attributes() const } QUnicodeTools::initCharAttributes( - reinterpret_cast<const ushort *>(layoutData->string.constData()), - layoutData->string.length(), + layoutData->string, scriptItems.data(), scriptItems.size(), reinterpret_cast<QCharAttributes *>(layoutData->memory), QUnicodeTools::CharAttributeOptions(QUnicodeTools::GraphemeBreaks @@ -1921,7 +1920,7 @@ void QTextEngine::itemize() const { QUnicodeTools::ScriptItemArray scriptItems; - QUnicodeTools::initScripts(string, length, &scriptItems); + QUnicodeTools::initScripts(layoutData->string, &scriptItems); for (int i = 0; i < scriptItems.length(); ++i) { const auto &item = scriptItems.at(i); int end = i < scriptItems.length() - 1 ? scriptItems.at(i + 1).position : length; diff --git a/tests/auto/corelib/text/qtextboundaryfinder/tst_qtextboundaryfinder.cpp b/tests/auto/corelib/text/qtextboundaryfinder/tst_qtextboundaryfinder.cpp index c2cbc6d818..9c212a6a0b 100644 --- a/tests/auto/corelib/text/qtextboundaryfinder/tst_qtextboundaryfinder.cpp +++ b/tests/auto/corelib/text/qtextboundaryfinder/tst_qtextboundaryfinder.cpp @@ -664,8 +664,6 @@ void tst_QTextBoundaryFinder::emptyText_data() QTest::newRow("empty3") << finder; QTest::newRow("empty4") << QTextBoundaryFinder(QTextBoundaryFinder::Word, notEmpty.constData(), 0, 0, 0); QTest::newRow("empty5") << QTextBoundaryFinder(QTextBoundaryFinder::Word, notEmpty.constData(), 0, attrs, 11); - QTest::newRow("invalid1") << QTextBoundaryFinder(QTextBoundaryFinder::Word, 0, 10, 0, 0); - QTest::newRow("invalid2") << QTextBoundaryFinder(QTextBoundaryFinder::Word, 0, 10, attrs, 11); } void tst_QTextBoundaryFinder::emptyText() |