summaryrefslogtreecommitdiffstats
path: root/src/corelib/text/qtextboundaryfinder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/text/qtextboundaryfinder.cpp')
-rw-r--r--src/corelib/text/qtextboundaryfinder.cpp234
1 files changed, 91 insertions, 143 deletions
diff --git a/src/corelib/text/qtextboundaryfinder.cpp b/src/corelib/text/qtextboundaryfinder.cpp
index fdbb7f0176..21d4c5153e 100644
--- a/src/corelib/text/qtextboundaryfinder.cpp
+++ b/src/corelib/text/qtextboundaryfinder.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtCore/qtextboundaryfinder.h>
#include <QtCore/qvarlengtharray.h>
@@ -43,18 +7,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 +20,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.size(), attributes, options);
}
/*!
@@ -81,8 +37,8 @@ static void init(QTextBoundaryFinder::BoundaryType type, const QChar *chars, int
QTextBoundaryFinder allows to find Unicode text boundaries in a
string, accordingly to the Unicode text boundary specification (see
- \l{http://www.unicode.org/reports/tr14/}{Unicode Standard Annex #14} and
- \l{http://www.unicode.org/reports/tr29/}{Unicode Standard Annex #29}).
+ \l{https://www.unicode.org/reports/tr14/}{Unicode Standard Annex #14} and
+ \l{https://www.unicode.org/reports/tr29/}{Unicode Standard Annex #29}).
QTextBoundaryFinder can operate on a QString in four possible
modes depending on the value of \a BoundaryType.
@@ -93,17 +49,17 @@ static void init(QTextBoundaryFinder::BoundaryType type, const QChar *chars, int
for example form one grapheme cluster as the user thinks of them
as one character, yet it is in this case represented by two
unicode code points
- (see \l{http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries}).
+ (see \l{https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries}).
Word boundaries are there to locate the start and end of what a
language considers to be a word
- (see \l{http://www.unicode.org/reports/tr29/#Word_Boundaries}).
+ (see \l{https://www.unicode.org/reports/tr29/#Word_Boundaries}).
Line break boundaries give possible places where a line break
might happen and sentence boundaries will show the beginning and
end of whole sentences
- (see \l{http://www.unicode.org/reports/tr29/#Sentence_Boundaries} and
- \l{http://www.unicode.org/reports/tr14/}).
+ (see \l{https://www.unicode.org/reports/tr29/#Sentence_Boundaries} and
+ \l{https://www.unicode.org/reports/tr14/}).
The first position in a string is always a valid boundary and
refers to the position before the first character. The last
@@ -131,11 +87,11 @@ static void init(QTextBoundaryFinder::BoundaryType type, const QChar *chars, int
Such a break opportunity might also be an item boundary
(either StartOfItem, EndOfItem, or combination of both),
a mandatory line break, or a soft hyphen.
- \value StartOfItem Since 5.0. The boundary finder is at the start of
+ \value [since 5.0] StartOfItem The boundary finder is at the start of
a grapheme, a word, a sentence, or a line.
- \value EndOfItem Since 5.0. The boundary finder is at the end of
+ \value [since 5.0] EndOfItem The boundary finder is at the end of
a grapheme, a word, a sentence, or a line.
- \value MandatoryBreak Since 5.0. The boundary finder is at the end of line
+ \value [since 5.0] MandatoryBreak The boundary finder is at the end of line
(can occur for a Line boundary type only).
\value SoftHyphen The boundary finder is at the soft hyphen
(can occur for a Line boundary type only).
@@ -145,11 +101,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 +111,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 +131,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 +162,8 @@ QTextBoundaryFinder &QTextBoundaryFinder::operator=(const QTextBoundaryFinder &o
QTextBoundaryFinder::~QTextBoundaryFinder()
{
Q_UNUSED(unused);
- if (freePrivate)
- free(d);
+ if (freeBuffer)
+ free(attributes);
}
/*!
@@ -223,52 +172,51 @@ QTextBoundaryFinder::~QTextBoundaryFinder()
QTextBoundaryFinder::QTextBoundaryFinder(BoundaryType type, const QString &string)
: t(type)
, s(string)
- , chars(string.unicode())
- , length(string.length())
- , pos(0)
- , freePrivate(true)
- , d(nullptr)
+ , sv(s)
+ , freeBuffer(true)
{
- 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
data required (bufferSize >= length + 1), it will use this
instead of allocating its own buffer.
- \warning QTextBoundaryFinder does not create a copy of \a chars. It is the
+ \warning QTextBoundaryFinder does not create a copy of \a string. It is the
application programmer's responsibility to ensure the array is allocated for
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)
- , pos(0)
- , freePrivate(true)
- , d(nullptr)
+ , sv(string)
+ , freeBuffer(true)
{
- 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 && bufferSize / int(sizeof(QCharAttributes)) >= sv.size() + 1) {
+ 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 +237,7 @@ void QTextBoundaryFinder::toStart()
*/
void QTextBoundaryFinder::toEnd()
{
- pos = length;
+ pos = sv.size();
}
/*!
@@ -300,7 +248,7 @@ void QTextBoundaryFinder::toEnd()
\sa setPosition()
*/
-int QTextBoundaryFinder::position() const
+qsizetype QTextBoundaryFinder::position() const
{
return pos;
}
@@ -314,9 +262,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 +283,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 +294,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 +304,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 +329,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 +339,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 +364,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 +387,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 +415,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 +427,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;
}
}