summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-04-11 14:36:55 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-04-11 14:36:55 +0200
commit98d3e40fb7c88b670a93e73dace2d0f05a5f903c (patch)
treeb1292124a86c219fb434db4ec28e8f805ff52287 /src/gui/text
parenta74e4b85be83e2da47f4a1d8fcf0e78079335b80 (diff)
parentbab494e4d046f5617d19f5fec35eeff94377c51f (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.cpp5
-rw-r--r--src/gui/text/qharfbuzzng.cpp8
-rw-r--r--src/gui/text/qtextengine.cpp53
-rw-r--r--src/gui/text/qtextimagehandler.cpp42
-rw-r--r--src/gui/text/qtextlayout.cpp5
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) {