diff options
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qfontengine.cpp | 8 | ||||
-rw-r--r-- | src/gui/text/qfontengine_ft.cpp | 10 | ||||
-rw-r--r-- | src/gui/text/qfontmetrics.cpp | 4 | ||||
-rw-r--r-- | src/gui/text/qfontsubset.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextcursor.cpp | 4 | ||||
-rw-r--r-- | src/gui/text/qtextcursor.h | 5 | ||||
-rw-r--r-- | src/gui/text/qtextcursor_p.h | 2 | ||||
-rw-r--r-- | src/gui/text/qtextdocument_p.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 30 | ||||
-rw-r--r-- | src/gui/text/qtextengine_p.h | 8 | ||||
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 22 |
11 files changed, 62 insertions, 35 deletions
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 8924a7c4ae..7c0492bb1a 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -829,7 +829,7 @@ void QFontEngine::addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &glyp } } } - const uchar *bitmap_data = bitmap.bits(); + const uchar *bitmap_data = bitmap.constBits(); QFixedPoint offset = glyphs.offsets[i]; advanceX += offset.x; advanceY += offset.y; @@ -886,12 +886,12 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, con QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &t) { - QImage alphaMask = alphaMapForGlyph(glyph, t); + const QImage alphaMask = alphaMapForGlyph(glyph, t); QImage rgbMask(alphaMask.width(), alphaMask.height(), QImage::Format_RGB32); for (int y=0; y<alphaMask.height(); ++y) { uint *dst = (uint *) rgbMask.scanLine(y); - uchar *src = (uchar *) alphaMask.scanLine(y); + const uchar *src = alphaMask.constScanLine(y); for (int x=0; x<alphaMask.width(); ++x) { int val = src[x]; dst[x] = qRgb(val, val, val); @@ -979,7 +979,7 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph) for (int y=0; y<im.height(); ++y) { uchar *dst = (uchar *) alphaMap.scanLine(y); - uint *src = (uint *) im.scanLine(y); + const uint *src = reinterpret_cast<const uint *>(im.constScanLine(y)); for (int x=0; x<im.width(); ++x) dst[x] = qAlpha(src[x]); } diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 81657a2702..779333351f 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1261,7 +1261,7 @@ QFixed QFontEngineFT::xHeight() const TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); if (os2 && os2->sxHeight) { lockFace(); - QFixed answer = QFixed(os2->sxHeight*freetype->face->size->metrics.y_ppem)/freetype->face->units_per_EM; + QFixed answer = QFixed(os2->sxHeight * freetype->face->size->metrics.y_ppem) / emSquareSize(); unlockFace(); return answer; } @@ -1273,7 +1273,7 @@ QFixed QFontEngineFT::averageCharWidth() const TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); if (os2 && os2->xAvgCharWidth) { lockFace(); - QFixed answer = QFixed(os2->xAvgCharWidth*freetype->face->size->metrics.x_ppem)/freetype->face->units_per_EM; + QFixed answer = QFixed(os2->xAvgCharWidth * freetype->face->size->metrics.x_ppem) / emSquareSize(); unlockFace(); return answer; } @@ -1301,7 +1301,7 @@ void QFontEngineFT::doKerning(QGlyphLayout *g, QFontEngine::ShaperFlags flags) c kerning_pairs_loaded = true; lockFace(); if (freetype->face->size->metrics.x_ppem != 0) { - QFixed scalingFactor(freetype->face->units_per_EM/freetype->face->size->metrics.x_ppem); + QFixed scalingFactor = emSquareSize() / QFixed(freetype->face->size->metrics.x_ppem); unlockFace(); const_cast<QFontEngineFT *>(this)->loadKerningPairs(scalingFactor); } else { @@ -1725,8 +1725,8 @@ static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEng if (glyph == Q_NULLPTR) return QImage(); - QImage::Format format; - int bytesPerLine; + QImage::Format format = QImage::Format_Invalid; + int bytesPerLine = -1; switch (glyphFormat) { case QFontEngine::Format_Mono: format = QImage::Format_Mono; diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 3bc8288b73..2189923b25 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -795,7 +795,7 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te \li Qt::TextSingleLine ignores newline characters. \li Qt::TextExpandTabs expands tabs (see below) \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. - \li Qt::TextWordBreak breaks the text to fit the rectangle. + \li Qt::TextWordWrap breaks the text to fit the rectangle. \endlist If Qt::TextExpandTabs is set in \a flags, then: if \a tabArray is @@ -1579,7 +1579,7 @@ QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString& \li Qt::TextSingleLine ignores newline characters. \li Qt::TextExpandTabs expands tabs (see below) \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. - \li Qt::TextWordBreak breaks the text to fit the rectangle. + \li Qt::TextWordWrap breaks the text to fit the rectangle. \endlist These flags are defined in the \l{Qt::TextFlag} enum. diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp index 34db39e4a8..a9387e5aa0 100644 --- a/src/gui/text/qfontsubset.cpp +++ b/src/gui/text/qfontsubset.cpp @@ -624,6 +624,7 @@ static QTtfTable generateName(const QVector<QTtfNameRecord> &name); static QTtfTable generateName(const qttf_name_table &name) { QVector<QTtfNameRecord> list; + list.reserve(5); QTtfNameRecord rec; rec.nameId = 0; rec.value = name.copyright; @@ -1061,6 +1062,7 @@ static QVector<QTtfTable> generateGlyphTables(qttf_font_tables &tables, const QV Q_ASSERT(hmtx.data.size() == hs.offset()); QVector<QTtfTable> list; + list.reserve(3); list.append(glyf); list.append(loca); list.append(hmtx); diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 85484b8b03..f824d1b369 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -1078,8 +1078,8 @@ QTextCursor::QTextCursor(const QTextBlock &block) /*! \internal */ -QTextCursor::QTextCursor(QTextDocumentPrivate &p, int pos) - : d(new QTextCursorPrivate(&p)) +QTextCursor::QTextCursor(QTextDocumentPrivate *p, int pos) + : d(new QTextCursorPrivate(p)) { d->adjusted_anchor = d->anchor = d->position = pos; diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index b8fa3145eb..9610e61b39 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -67,6 +67,8 @@ class Q_GUI_EXPORT QTextCursor public: QTextCursor(); explicit QTextCursor(QTextDocument *document); + QTextCursor(QTextDocumentPrivate *p, int pos); + explicit QTextCursor(QTextCursorPrivate *d); explicit QTextCursor(QTextFrame *frame); explicit QTextCursor(const QTextBlock &block); QTextCursor(const QTextCursor &cursor); @@ -225,9 +227,6 @@ public: QTextDocument *document() const; private: - QTextCursor(QTextDocumentPrivate &p, int pos); - explicit QTextCursor(QTextCursorPrivate *d); - QSharedDataPointer<QTextCursorPrivate> d; friend class QTextCursorPrivate; friend class QTextDocumentPrivate; diff --git a/src/gui/text/qtextcursor_p.h b/src/gui/text/qtextcursor_p.h index 5b593b8a9b..84f912a3fa 100644 --- a/src/gui/text/qtextcursor_p.h +++ b/src/gui/text/qtextcursor_p.h @@ -107,7 +107,7 @@ public: void aboutToRemoveCell(int from, int to); static QTextCursor fromPosition(QTextDocumentPrivate *d, int pos) - { return QTextCursor(*d, pos); } + { return QTextCursor(d, pos); } QTextDocumentPrivate *priv; qreal x; diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 5cb9e1bb74..348fa83756 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -1710,7 +1710,7 @@ bool QTextDocumentPrivate::ensureMaximumBlockCount() beginEditBlock(); const int blocksToRemove = blocks.numNodes() - maximumBlockCount; - QTextCursor cursor(*this, 0); + QTextCursor cursor(this, 0); cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, blocksToRemove); unreachableCharacterCount += cursor.selectionEnd() - cursor.selectionStart(); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index b15fc4c047..f5df6fd60b 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1065,7 +1065,7 @@ void QTextEngine::shapeText(int item) const #ifdef QT_ENABLE_HARFBUZZ_NG if (Q_LIKELY(qt_useHarfbuzzNG())) - si.num_glyphs = shapeTextWithHarfbuzzNG(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled); + si.num_glyphs = shapeTextWithHarfbuzzNG(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled, letterSpacing != 0); else #endif si.num_glyphs = shapeTextWithHarfbuzz(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled); @@ -1127,7 +1127,13 @@ QT_BEGIN_INCLUDE_NAMESPACE QT_END_INCLUDE_NAMESPACE -int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const +int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, + const ushort *string, + int itemLength, + QFontEngine *fontEngine, + const QVector<uint> &itemBoundaries, + bool kerningEnabled, + bool hasLetterSpacing) const { uint glyphs_shaped = 0; @@ -1141,7 +1147,8 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st hb_segment_properties_t props = HB_SEGMENT_PROPERTIES_DEFAULT; props.direction = si.analysis.bidiLevel % 2 ? HB_DIRECTION_RTL : HB_DIRECTION_LTR; - props.script = hb_qt_script_to_script(QChar::Script(si.analysis.script)); + QChar::Script script = QChar::Script(si.analysis.script); + props.script = hb_qt_script_to_script(script); // ### props.language = hb_language_get_default_for_script(props.script); for (int k = 0; k < itemBoundaries.size(); k += 3) { @@ -1174,10 +1181,19 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st Q_ASSERT(hb_font); hb_qt_font_set_use_design_metrics(hb_font, option.useDesignMetrics() ? uint(QFontEngine::DesignMetrics) : 0); // ### - const hb_feature_t features[1] = { - { HB_TAG('k','e','r','n'), !!kerningEnabled, 0, uint(-1) } - }; - const int num_features = 1; + // Ligatures are incompatible with custom letter spacing, so when a letter spacing is set, + // we disable them for writing systems where they are purely cosmetic. + bool scriptRequiresOpenType = ((script >= QChar::Script_Syriac && script <= QChar::Script_Sinhala) + || script == QChar::Script_Khmer || script == QChar::Script_Nko); + + bool dontLigate = hasLetterSpacing && !scriptRequiresOpenType; + const hb_feature_t features[5] = { + { HB_TAG('k','e','r','n'), !!kerningEnabled, 0, uint(-1) }, + { HB_TAG('l','i','g','a'), !dontLigate, 0, uint(-1) }, + { HB_TAG('c','l','i','g'), !dontLigate, 0, uint(-1) }, + { HB_TAG('d','l','i','g'), !dontLigate, 0, uint(-1) }, + { HB_TAG('h','l','i','g'), !dontLigate, 0, uint(-1) } }; + const int num_features = dontLigate ? 5 : 1; const char *const *shaper_list = Q_NULLPTR; #if defined(Q_OS_DARWIN) diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 83575af43a..ab08f2d5e5 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -649,7 +649,13 @@ private: void addRequiredBoundaries() const; void shapeText(int item) const; #ifdef QT_ENABLE_HARFBUZZ_NG - int shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const; + int shapeTextWithHarfbuzzNG(const QScriptItem &si, + const ushort *string, + int itemLength, + QFontEngine *fontEngine, + const QVector<uint> &itemBoundaries, + bool kerningEnabled, + bool hasLetterSpacing) const; #endif int shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 1cb42e822b..8902d52b28 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1064,12 +1064,15 @@ QList<QGlyphRun> QTextLayout::glyphRuns(int from, int length) const QVector<quint32> indexes = oldGlyphRun.glyphIndexes(); QVector<QPointF> positions = oldGlyphRun.positions(); + QRectF boundingRect = oldGlyphRun.boundingRect(); indexes += glyphRun.glyphIndexes(); positions += glyphRun.positions(); + boundingRect = boundingRect.united(glyphRun.boundingRect()); oldGlyphRun.setGlyphIndexes(indexes); oldGlyphRun.setPositions(positions); + oldGlyphRun.setBoundingRect(boundingRect); } else { glyphRunHash[key] = glyphRun; } @@ -2144,6 +2147,7 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine, QGlyphRunPrivate *d = QGlyphRunPrivate::get(glyphRun); int rangeStart = textPosition; + logClusters += textPosition; while (*logClusters != glyphsStart && rangeStart < textPosition + textLength) { ++logClusters; ++rangeStart; @@ -2328,16 +2332,16 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const if (mainFontEngine->type() == QFontEngine::Multi) { QFontEngineMulti *multiFontEngine = static_cast<QFontEngineMulti *>(mainFontEngine); - int end = rtl ? glyphLayout.numGlyphs : 0; - int start = rtl ? end : 0; - int which = glyphLayout.glyphs[rtl ? start - 1 : end] >> 24; - for (; (rtl && start > 0) || (!rtl && end < glyphLayout.numGlyphs); + int start = rtl ? glyphLayout.numGlyphs : 0; + int end = start - 1; + int which = glyphLayout.glyphs[rtl ? start - 1 : end + 1] >> 24; + for (; (rtl && start > 0) || (!rtl && end < glyphLayout.numGlyphs - 1); rtl ? --start : ++end) { - const int e = glyphLayout.glyphs[rtl ? start - 1 : end] >> 24; + const int e = glyphLayout.glyphs[rtl ? start - 1 : end + 1] >> 24; if (e == which) continue; - QGlyphLayout subLayout = glyphLayout.mid(start, end - start); + QGlyphLayout subLayout = glyphLayout.mid(start, end - start + 1); multiFontEngine->ensureEngineAt(which); QGlyphRun::GlyphRunFlags subFlags = flags; @@ -2361,13 +2365,13 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const } if (rtl) - end = start; + end = start - 1; else - start = end; + start = end + 1; which = e; } - QGlyphLayout subLayout = glyphLayout.mid(start, end - start); + QGlyphLayout subLayout = glyphLayout.mid(start, end - start + 1); multiFontEngine->ensureEngineAt(which); QGlyphRun::GlyphRunFlags subFlags = flags; |