diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-04-11 14:36:55 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-04-11 14:36:55 +0200 |
commit | 98d3e40fb7c88b670a93e73dace2d0f05a5f903c (patch) | |
tree | b1292124a86c219fb434db4ec28e8f805ff52287 /src/gui/text | |
parent | a74e4b85be83e2da47f4a1d8fcf0e78079335b80 (diff) | |
parent | bab494e4d046f5617d19f5fec35eeff94377c51f (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Conflicts:
mkspecs/qnx-armv7le-qcc/qplatformdefs.h
src/printsupport/kernel/qcups.cpp
src/widgets/styles/qstyle.h
tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
Change-Id: Ia41e13051169a6d4a8a1267548e7d47b859bb267
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qfontengine.cpp | 5 | ||||
-rw-r--r-- | src/gui/text/qharfbuzzng.cpp | 8 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 53 | ||||
-rw-r--r-- | src/gui/text/qtextimagehandler.cpp | 42 | ||||
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 5 |
5 files changed, 75 insertions, 38 deletions
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index a72ac23418..b2254c4826 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -280,6 +280,7 @@ QFixed QFontEngine::underlinePosition() const void *QFontEngine::harfbuzzFont() const { + Q_ASSERT(type() != QFontEngine::Multi); #ifdef QT_ENABLE_HARFBUZZ_NG if (useHarfbuzzNG) return hb_qt_font_get_for_engine(const_cast<QFontEngine *>(this)); @@ -312,6 +313,7 @@ void *QFontEngine::harfbuzzFont() const void *QFontEngine::harfbuzzFace() const { + Q_ASSERT(type() != QFontEngine::Multi); #ifdef QT_ENABLE_HARFBUZZ_NG if (useHarfbuzzNG) return hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this)); @@ -329,6 +331,9 @@ void *QFontEngine::harfbuzzFace() const bool QFontEngine::supportsScript(QChar::Script script) const { + if (type() <= QFontEngine::Multi) + return true; + // ### TODO: This only works for scripts that require OpenType. More generally // for scripts that do not require OpenType we should just look at the list of // supported writing systems in the font's OS/2 table. diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp index b0bade83ee..e87747fd1b 100644 --- a/src/gui/text/qharfbuzzng.cpp +++ b/src/gui/text/qharfbuzzng.cpp @@ -605,8 +605,6 @@ _hb_qt_reference_table(hb_face_t * /*face*/, hb_tag_t tag, void *user_data) static inline hb_face_t * _hb_qt_face_create(QFontEngine *fe) { - Q_ASSERT(fe); - QFontEngine::FaceData *data = (QFontEngine::FaceData *)malloc(sizeof(QFontEngine::FaceData)); Q_CHECK_PTR(data); data->user_data = fe->faceData.user_data; @@ -633,6 +631,8 @@ _hb_qt_face_release(void *user_data) hb_face_t *hb_qt_face_get_for_engine(QFontEngine *fe) { + Q_ASSERT(fe && fe->type() != QFontEngine::Multi); + if (Q_UNLIKELY(!fe->face_)) { fe->face_ = _hb_qt_face_create(fe); if (Q_UNLIKELY(!fe->face_)) @@ -647,8 +647,6 @@ hb_face_t *hb_qt_face_get_for_engine(QFontEngine *fe) static inline hb_font_t * _hb_qt_font_create(QFontEngine *fe) { - Q_ASSERT(fe); - hb_face_t *face = hb_qt_face_get_for_engine(fe); if (Q_UNLIKELY(!face)) return NULL; @@ -685,6 +683,8 @@ _hb_qt_font_release(void *user_data) hb_font_t *hb_qt_font_get_for_engine(QFontEngine *fe) { + Q_ASSERT(fe && fe->type() != QFontEngine::Multi); + if (Q_UNLIKELY(!fe->font_)) { fe->font_ = _hb_qt_font_create(fe); if (Q_UNLIKELY(!fe->font_)) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 3b079b7ee3..35950c709b 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -3138,11 +3138,12 @@ int QTextEngine::positionInLigature(const QScriptItem *si, int end, int QTextEngine::previousLogicalPosition(int oldPos) const { const QCharAttributes *attrs = attributes(); - if (!attrs || oldPos < 0) + int len = block.isValid() ? block.length() - 1 + : layoutData->string.length(); + Q_ASSERT(len <= layoutData->string.length()); + if (!attrs || oldPos <= 0 || oldPos > len) return oldPos; - if (oldPos <= 0) - return 0; oldPos--; while (oldPos && !attrs[oldPos].graphemeBoundary) oldPos--; @@ -3181,23 +3182,22 @@ int QTextEngine::lineNumberForTextPosition(int pos) void QTextEngine::insertionPointsForLine(int lineNum, QVector<int> &insertionPoints) { QTextLineItemIterator iterator(this, lineNum); - bool rtl = isRightToLeft(); + + insertionPoints.reserve(iterator.line.length); + bool lastLine = lineNum >= lines.size() - 1; while (!iterator.atEnd()) { - iterator.next(); - const QScriptItem *si = &layoutData->items[iterator.item]; - if (si->analysis.bidiLevel % 2) { - int i = iterator.itemEnd - 1, min = iterator.itemStart; - if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd())) - i++; - for (; i >= min; i--) + const QScriptItem &si = iterator.next(); + + int end = iterator.itemEnd; + if (lastLine && iterator.item == iterator.lastItem) + ++end; // the last item in the last line -> insert eol position + if (si.analysis.bidiLevel % 2) { + for (int i = end - 1; i >= iterator.itemStart; --i) insertionPoints.push_back(i); } else { - int i = iterator.itemStart, max = iterator.itemEnd; - if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd())) - max++; - for (; i < max; i++) + for (int i = iterator.itemStart; i < end; ++i) insertionPoints.push_back(i); } } @@ -3225,8 +3225,7 @@ int QTextEngine::beginningOfLine(int lineNum) int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation op) { - if (!layoutData) - itemize(); + itemize(); bool moveRight = (op == QTextCursor::Right); bool alignRight = isRightToLeft(); @@ -3234,7 +3233,8 @@ int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation return moveRight ^ alignRight ? nextLogicalPosition(pos) : previousLogicalPosition(pos); int lineNum = lineNumberForTextPosition(pos); - Q_ASSERT(lineNum >= 0); + if (lineNum < 0) + return pos; QVector<int> insertionPoints; insertionPointsForLine(lineNum, insertionPoints); @@ -3257,6 +3257,8 @@ int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation if (lineNum > 0) return alignRight ? beginningOfLine(lineNum - 1) : endOfLine(lineNum - 1); } + + break; } return pos; @@ -3520,7 +3522,12 @@ QScriptItem &QTextLineItemIterator::next() if (!si->num_glyphs) eng->shape(item); + itemStart = qMax(line.from, si->position); + itemEnd = qMin(lineEnd, si->position + itemLength); + if (si->analysis.flags >= QScriptAnalysis::TabOrObject) { + glyphsStart = 0; + glyphsEnd = 1; itemWidth = si->width; return *si; } @@ -3528,15 +3535,9 @@ QScriptItem &QTextLineItemIterator::next() unsigned short *logClusters = eng->logClusters(si); QGlyphLayout glyphs = eng->shapedGlyphs(si); - itemStart = qMax(line.from, si->position); glyphsStart = logClusters[itemStart - si->position]; - if (lineEnd < si->position + itemLength) { - itemEnd = lineEnd; - glyphsEnd = logClusters[itemEnd-si->position]; - } else { - itemEnd = si->position + itemLength; - glyphsEnd = si->num_glyphs; - } + glyphsEnd = (itemEnd == si->position + itemLength) ? si->num_glyphs : logClusters[itemEnd - si->position]; + // show soft-hyphen at line-break if (si->position + itemLength >= lineEnd && eng->layoutData->string.at(lineEnd - 1).unicode() == QChar::SoftHyphen) diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp index 9704f7a9dc..02a1091506 100644 --- a/src/gui/text/qtextimagehandler.cpp +++ b/src/gui/text/qtextimagehandler.cpp @@ -42,7 +42,7 @@ #include "qtextimagehandler_p.h" -#include <qcoreapplication.h> +#include <qguiapplication.h> #include <qtextformat.h> #include <qpainter.h> #include <qdebug.h> @@ -52,6 +52,21 @@ QT_BEGIN_NAMESPACE +static QString resolve2xFile(const QString &fileName, qreal targetDevicePixelRatio) +{ + if (targetDevicePixelRatio <= 1.0) + return fileName; + + int dotIndex = fileName.lastIndexOf(QLatin1Char('.')); + if (dotIndex != -1) { + QString at2xfileName = fileName; + at2xfileName.insert(dotIndex, QStringLiteral("@2x")); + if (QFile::exists(at2xfileName)) + return at2xfileName; + } + return fileName; +} + static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format) { QPixmap pm; @@ -59,6 +74,8 @@ static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format) QString name = format.name(); if (name.startsWith(QLatin1String(":/"))) // auto-detect resources name.prepend(QLatin1String("qrc")); + QPaintDevice *pdev = doc->documentLayout()->paintDevice(); + name = resolve2xFile(name, pdev ? pdev->devicePixelRatio() : qApp->devicePixelRatio()); QUrl url = QUrl(name); const QVariant data = doc->resource(QTextDocument::ImageResource, url); if (data.type() == QVariant::Pixmap || data.type() == QVariant::Image) { @@ -85,6 +102,9 @@ static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format) doc->addResource(QTextDocument::ImageResource, url, pm); } + if (name.contains(QStringLiteral("@2x"))) + pm.setDevicePixelRatio(2.0); + return pm; } @@ -100,17 +120,20 @@ static QSize getPixmapSize(QTextDocument *doc, const QTextImageFormat &format) QSize size(width, height); if (!hasWidth || !hasHeight) { pm = getPixmap(doc, format); + const int pmWidth = pm.width() / pm.devicePixelRatio(); + const int pmHeight = pm.height() / pm.devicePixelRatio(); + if (!hasWidth) { if (!hasHeight) - size.setWidth(pm.width()); + size.setWidth(pmWidth); else - size.setWidth(qRound(height * (pm.width() / (qreal) pm.height()))); + size.setWidth(qRound(height * (pmWidth / (qreal) pmHeight))); } if (!hasHeight) { if (!hasWidth) - size.setHeight(pm.height()); + size.setHeight(pmHeight); else - size.setHeight(qRound(width * (pm.height() / (qreal) pm.width()))); + size.setHeight(qRound(width * (pmHeight / (qreal) pmWidth))); } } @@ -134,6 +157,8 @@ static QImage getImage(QTextDocument *doc, const QTextImageFormat &format) QString name = format.name(); if (name.startsWith(QLatin1String(":/"))) // auto-detect resources name.prepend(QLatin1String("qrc")); + QPaintDevice *pdev = doc->documentLayout()->paintDevice(); + name = resolve2xFile(name, pdev ? pdev->devicePixelRatio() : qApp->devicePixelRatio()); QUrl url = QUrl(name); const QVariant data = doc->resource(QTextDocument::ImageResource, url); if (data.type() == QVariant::Image) { @@ -159,6 +184,9 @@ static QImage getImage(QTextDocument *doc, const QTextImageFormat &format) doc->addResource(QTextDocument::ImageResource, url, image); } + if (name.contains(QStringLiteral("@2x"))) + image.setDevicePixelRatio(2.0); + return image; } @@ -175,9 +203,9 @@ static QSize getImageSize(QTextDocument *doc, const QTextImageFormat &format) if (!hasWidth || !hasHeight) { image = getImage(doc, format); if (!hasWidth) - size.setWidth(image.width()); + size.setWidth(image.width() / image.devicePixelRatio()); if (!hasHeight) - size.setHeight(image.height()); + size.setHeight(image.height() / image.devicePixelRatio()); } qreal scale = 1.0; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 0c9866c6cf..c3cf2e56bb 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -674,7 +674,10 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const { const QCharAttributes *attributes = d->attributes(); - if (!attributes || oldPos <= 0 || oldPos > d->layoutData->string.length()) + int len = d->block.isValid() ? d->block.length() - 1 + : d->layoutData->string.length(); + Q_ASSERT(len <= d->layoutData->string.length()); + if (!attributes || oldPos <= 0 || oldPos > len) return oldPos; if (mode == SkipCharacters) { |