diff options
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/freetype/qfontengine_ft.cpp | 6 | ||||
-rw-r--r-- | src/gui/text/qcssparser.cpp | 4 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 4 | ||||
-rw-r--r-- | src/gui/text/qfontmetrics.cpp | 18 | ||||
-rw-r--r-- | src/gui/text/qtextdocumentwriter.cpp | 5 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 27 | ||||
-rw-r--r-- | src/gui/text/qtexthtmlparser.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 10 |
8 files changed, 50 insertions, 26 deletions
diff --git a/src/gui/text/freetype/qfontengine_ft.cpp b/src/gui/text/freetype/qfontengine_ft.cpp index 42cf147901..59300b6eca 100644 --- a/src/gui/text/freetype/qfontengine_ft.cpp +++ b/src/gui/text/freetype/qfontengine_ft.cpp @@ -1078,7 +1078,11 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, renderMode = FT_RENDER_MODE_MONO; break; case Format_A32: - Q_ASSERT(hsubpixel || vfactor != 1); + if (!hsubpixel && vfactor == 1) { + qWarning("Format_A32 requested, but subpixel layout is unknown."); + return nullptr; + } + renderMode = hsubpixel ? FT_RENDER_MODE_LCD : FT_RENDER_MODE_LCD_V; break; case Format_A8: diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 9670568792..417587fab0 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -1143,14 +1143,14 @@ static bool setFontSizeFromValue(QCss::Value value, QFont *font, int *fontSizeAd s.chop(2); value.variant = s; if (value.variant.convert(QMetaType::fromType<qreal>())) { - font->setPointSizeF(value.variant.toReal()); + font->setPointSizeF(qBound(qreal(0), value.variant.toReal(), qreal(1 << 24) - 1)); valid = true; } } else if (s.endsWith(QLatin1String("px"), Qt::CaseInsensitive)) { s.chop(2); value.variant = s; if (value.variant.convert(QMetaType::fromType<int>())) { - font->setPixelSize(value.variant.toInt()); + font->setPixelSize(qBound(0, value.variant.toInt(), (1 << 24) - 1)); valid = true; } } diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index cf2573c984..203230636b 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -304,10 +304,12 @@ void QFontDatabasePrivate::invalidate() emit static_cast<QGuiApplication *>(QCoreApplication::instance())->fontDatabaseChanged(); } -QtFontFamily *QFontDatabasePrivate::family(const QString &f, FamilyRequestFlags flags) +QtFontFamily *QFontDatabasePrivate::family(const QString &family, FamilyRequestFlags flags) { QtFontFamily *fam = nullptr; + const QString f = family.trimmed(); + int low = 0; int high = count; int pos = count / 2; diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 341fd2a0e7..42c17ced58 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -261,9 +261,8 @@ bool QFontMetrics::operator ==(const QFontMetrics &other) const The ascent of a font is the distance from the baseline to the highest position characters extend to. In practice, some font designers break this rule, e.g. when they put more than one accent - on top of a character, or to accommodate an unusual character in - an exotic language, so it is possible (though rare) that this - value will be too small. + on top of a character, or to accommodate a certain character, so it + is possible (though rare) that this value will be too small. \sa descent() */ @@ -298,8 +297,8 @@ int QFontMetrics::capHeight() const The descent is the distance from the base line to the lowest point characters extend to. In practice, some font designers break this rule, - e.g. to accommodate an unusual character in an exotic language, so - it is possible (though rare) that this value will be too small. + e.g. to accommodate a certain character, so it is possible (though + rare) that this value will be too small. \sa ascent() */ @@ -1075,9 +1074,8 @@ bool QFontMetricsF::operator ==(const QFontMetricsF &other) const The ascent of a font is the distance from the baseline to the highest position characters extend to. In practice, some font designers break this rule, e.g. when they put more than one accent - on top of a character, or to accommodate an unusual character in - an exotic language, so it is possible (though rare) that this - value will be too small. + on top of a character, or to accommodate a certain character, so + it is possible (though rare) that this value will be too small. \sa descent() */ @@ -1113,8 +1111,8 @@ qreal QFontMetricsF::capHeight() const The descent is the distance from the base line to the lowest point characters extend to. (Note that this is different from X, which adds 1 pixel.) In practice, some font designers break this rule, - e.g. to accommodate an unusual character in an exotic language, so - it is possible (though rare) that this value will be too small. + e.g. to accommodate a certain character, so it is possible (though + rare) that this value will be too small. \sa ascent() */ diff --git a/src/gui/text/qtextdocumentwriter.cpp b/src/gui/text/qtextdocumentwriter.cpp index 31dfb9436f..74db049aa6 100644 --- a/src/gui/text/qtextdocumentwriter.cpp +++ b/src/gui/text/qtextdocumentwriter.cpp @@ -182,7 +182,7 @@ QByteArray QTextDocumentWriter::format () const unchanged. If the device is not already open, QTextDocumentWriter will attempt to - open the device in \l QIODevice::WriteOnly mode by calling open(). + open the device in \l {QIODeviceBase::}{WriteOnly} mode by calling open(). \note This will not work for certain devices, such as QProcess, QTcpSocket and QUdpSocket, where some configuration is required before @@ -211,7 +211,8 @@ QIODevice *QTextDocumentWriter::device () const /*! Sets the name of the file to be written to \a fileName. Internally, QTextDocumentWriter will create a QFile and open it in \l - QIODevice::WriteOnly mode, and use this file when writing the document. + {QIODeviceBase::}{WriteOnly} mode, and use this file when writing the + document. \sa fileName(), setDevice() */ diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index d3a28d8d02..94c0addeaa 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -258,7 +258,7 @@ struct QBidiAlgorithm { for (int i = 0; i < length; ++i) { int pos = i; char32_t uc = text[i].unicode(); - if (QChar::isHighSurrogate(uc) && i < length - 1) { + if (QChar::isHighSurrogate(uc) && i < length - 1 && text[i + 1].isLowSurrogate()) { ++i; analysis[i].bidiDirection = QChar::DirNSM; uc = QChar::surrogateToUcs4(ushort(uc), text[i].unicode()); @@ -1373,9 +1373,15 @@ static void applyVisibilityRules(ushort ucs, QGlyphLayout *glyphs, uint glyphPos if (!fontEngine->symbol) { // U+00AD [SOFT HYPHEN] is a default ignorable codepoint, // so we replace its glyph and metrics with ones for - // U+002D [HYPHEN-MINUS] and make it visible if it appears at line-break + // U+002D [HYPHEN-MINUS] or U+2010 [HYPHEN] and make + // it visible if it appears at line-break const uint engineIndex = glyphs->glyphs[glyphPosition] & 0xff000000; - glyphs->glyphs[glyphPosition] = fontEngine->glyphIndex('-'); + glyph_t glyph = fontEngine->glyphIndex(0x002d); + if (glyph == 0) + glyph = fontEngine->glyphIndex(0x2010); + if (glyph == 0) + glyph = fontEngine->glyphIndex(0x00ad); + glyphs->glyphs[glyphPosition] = glyph; if (Q_LIKELY(glyphs->glyphs[glyphPosition] != 0)) { glyphs->glyphs[glyphPosition] |= engineIndex; QGlyphLayout tmp = glyphs->mid(glyphPosition, 1); @@ -1546,12 +1552,21 @@ void QTextEngine::shapeText(int item) const si.num_glyphs = glyph_pos; } + if (Q_UNLIKELY(si.num_glyphs == 0)) { - Q_UNREACHABLE(); // ### report shaping errors somehow + if (Q_UNLIKELY(!ensureSpace(si.glyph_data_offset + 1))) { + qWarning() << "Unable to allocate space for place-holder glyph"; + return; + } + + si.num_glyphs = 1; + + // Overwrite with 0 token to indicate failure + QGlyphLayout g = availableGlyphs(&si); + g.glyphs[0] = 0; return; } - layoutData->used += si.num_glyphs; QGlyphLayout glyphs = shapedGlyphs(&si); diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 996980b764..2772f8bdc3 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -1671,7 +1671,7 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes) node->tableCellRowSpan = qMax(1, node->tableCellRowSpan); } else if (key == QLatin1String("colspan")) { if (setIntAttribute(&node->tableCellColSpan, value)) - node->tableCellColSpan = qMax(1, node->tableCellColSpan); + node->tableCellColSpan = qBound(1, node->tableCellColSpan, 20480); } break; case Html_table: diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index d303219bb9..c1a27b2556 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -820,6 +820,10 @@ QTextLine QTextLayout::createLine() int l = d->lines.size(); if (l && d->lines.at(l-1).length < 0) { QTextLine(l-1, d).setNumColumns(INT_MAX); + if (d->maxWidth > QFIXED_MAX / 2) { + qWarning("QTextLayout: text too long, truncated."); + return QTextLine(); + } } int from = l > 0 ? d->lines.at(l-1).from + d->lines.at(l-1).length + d->lines.at(l-1).trailingSpaces : 0; int strlen = d->layoutData->string.length(); @@ -1295,13 +1299,13 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition bool rightToLeft = d->isRightToLeft(); if (itm >= 0) { const QScriptItem &si = d->layoutData->items.at(itm); - if (si.ascent > 0) + if (si.ascent >= 0) base = si.ascent; - if (si.descent > 0) + if (si.descent >= 0) descent = si.descent; rightToLeft = si.analysis.bidiLevel % 2; } - qreal y = position.y() + (sl.y + sl.base() - base).toReal(); + qreal y = position.y() + (sl.y + sl.base() + sl.descent - base - descent).toReal(); bool toggleAntialiasing = !(p->renderHints() & QPainter::Antialiasing) && (p->transform().type() > QTransform::TxTranslate); if (toggleAntialiasing) |