diff options
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qfont.cpp | 14 | ||||
-rw-r--r-- | src/gui/text/qfont_p.h | 2 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase_win.cpp | 12 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase_x11.cpp | 14 | ||||
-rw-r--r-- | src/gui/text/qfontengine_ft.cpp | 10 | ||||
-rw-r--r-- | src/gui/text/qfontengine_mac.mm | 2 | ||||
-rw-r--r-- | src/gui/text/qfontengine_qpf.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qfontengine_win.cpp | 12 | ||||
-rw-r--r-- | src/gui/text/qfontinfo.h | 3 | ||||
-rw-r--r-- | src/gui/text/qfontmetrics.cpp | 49 | ||||
-rw-r--r-- | src/gui/text/qfontmetrics.h | 5 | ||||
-rw-r--r-- | src/gui/text/qtextcontrol.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 45 | ||||
-rw-r--r-- | src/gui/text/qtextdocument.h | 3 | ||||
-rw-r--r-- | src/gui/text/qtextdocument_p.h | 3 | ||||
-rw-r--r-- | src/gui/text/qtextdocumentlayout.cpp | 5 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 22 | ||||
-rw-r--r-- | src/gui/text/qtextengine_mac.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextengine_p.h | 17 | ||||
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 76 | ||||
-rw-r--r-- | src/gui/text/qtextlayout.h | 4 | ||||
-rw-r--r-- | src/gui/text/text.pri | 1 |
23 files changed, 213 insertions, 94 deletions
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 1285935..447087c 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2324,22 +2324,22 @@ QDataStream &operator>>(QDataStream &s, QFont &font) */ QFontInfo::QFontInfo(const QFont &font) : d(font.d.data()) -{ d->ref.ref(); } +{ +} /*! Constructs a copy of \a fi. */ QFontInfo::QFontInfo(const QFontInfo &fi) - : d(fi.d) -{ d->ref.ref(); } + : d(fi.d.data()) +{ +} /*! Destroys the font info object. */ QFontInfo::~QFontInfo() { - if (!d->ref.deref()) - delete d; } /*! @@ -2347,7 +2347,7 @@ QFontInfo::~QFontInfo() */ QFontInfo &QFontInfo::operator=(const QFontInfo &fi) { - qAtomicAssign(d, fi.d); + d = fi.d.data(); return *this; } @@ -2632,7 +2632,7 @@ QFontCache::~QFontCache() while (it != end) { if (--it.value().data->cache_count == 0) { if (it.value().data->ref == 0) { - FC_DEBUG("QFontCache::~QFontCache: deleting engine %p key=(%d / %g %d %d %d %d)", + FC_DEBUG("QFontCache::~QFontCache: deleting engine %p key=(%d / %g %g %d %d %d)", it.value().data, it.key().script, it.key().def.pointSize, it.key().def.pixelSize, it.key().def.weight, it.key().def.style, it.key().def.fixedPitch); diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index d74f0b4..144a82d 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -86,7 +86,7 @@ struct QFontDef #endif // Q_WS_X11 qreal pointSize; - int pixelSize; + qreal pixelSize; uint styleStrategy : 16; uint styleHint : 8; diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 738e36a..fb8444e 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -1331,7 +1331,7 @@ static void match(int script, const QFontDef &request, " family: %s [%s], script: %d\n" " weight: %d, style: %d\n" " stretch: %d\n" - " pixelSize: %d\n" + " pixelSize: %g\n" " pitch: %c", family_name.isEmpty() ? "-- first in script --" : family_name.toLatin1().constData(), foundry_name.isEmpty() ? "-- any --" : foundry_name.toLatin1().constData(), diff --git a/src/gui/text/qfontdatabase_win.cpp b/src/gui/text/qfontdatabase_win.cpp index ae26dab..6cde9ed 100644 --- a/src/gui/text/qfontdatabase_win.cpp +++ b/src/gui/text/qfontdatabase_win.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qt_windows.h" +#include <qmath.h> #include <private/qapplication_p.h> #include "qfont_p.h" #include "qfontengine_p.h" @@ -670,7 +671,7 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ break; } - lf.lfHeight = -request.pixelSize; + lf.lfHeight = -qRound(request.pixelSize); lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfOrientation = 0; @@ -899,7 +900,6 @@ static QFontEngine *loadWin(const QFontPrivate *d, int script, const QFontDef &r return fe; } - void QFontDatabase::load(const QFontPrivate *d, int script) { // sanity checks @@ -910,8 +910,9 @@ void QFontDatabase::load(const QFontPrivate *d, int script) // normalize the request to get better caching QFontDef req = d->request; if (req.pixelSize <= 0) - req.pixelSize = qMax(1, qRound(req.pointSize * d->dpi / 72.)); - req.pointSize = 0; + req.pixelSize = qreal((req.pointSize * d->dpi) / 72.); + if (req.pixelSize < 1) + req.pixelSize = 1; if (req.weight == 0) req.weight = QFont::Normal; if (req.stretch == 0) @@ -928,7 +929,8 @@ void QFontDatabase::load(const QFontPrivate *d, int script) QFontEngine *fe = QFontCache::instance()->findEngine(key); // set it to the actual pointsize, so QFontInfo will do the right thing - req.pointSize = req.pixelSize*72./d->dpi; + if (req.pointSize < 0) + req.pointSize = req.pixelSize*72./d->dpi; if (!fe) { if (qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) { diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp index 27ff003..f184811 100644 --- a/src/gui/text/qfontdatabase_x11.cpp +++ b/src/gui/text/qfontdatabase_x11.cpp @@ -51,6 +51,7 @@ #include <qfile.h> #include <qtemporaryfile.h> #include <qabstractfileengine.h> +#include <qmath.h> #include <ctype.h> #include <stdlib.h> @@ -757,7 +758,7 @@ QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &request) double size; if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &size) == FcResultMatch) - fontDef.pixelSize = qRound(size); + fontDef.pixelSize = size; else fontDef.pixelSize = 12; @@ -1455,7 +1456,7 @@ void qt_addPatternProps(FcPattern *pattern, int screen, int script, const QFontD slant_value = FC_SLANT_OBLIQUE; FcPatternAddInteger(pattern, FC_SLANT, slant_value); - double size_value = qMax(1, request.pixelSize); + double size_value = qMax(qreal(1.), request.pixelSize); FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value); int stretch = request.stretch; @@ -1893,8 +1894,9 @@ void QFontDatabase::load(const QFontPrivate *d, int script) // normalize the request to get better caching QFontDef req = d->request; if (req.pixelSize <= 0) - req.pixelSize = qRound(qt_pixelSize(req.pointSize, d->dpi)); - req.pointSize = 0; + req.pixelSize = floor(qt_pixelSize(req.pointSize, d->dpi) * 100 + 0.5) / 100; + if (req.pixelSize < 1) + req.pixelSize = 1; if (req.weight == 0) req.weight = QFont::Normal; if (req.stretch == 0) @@ -1909,7 +1911,9 @@ void QFontDatabase::load(const QFontPrivate *d, int script) return; // set it to the actual pointsize, so QFontInfo will do the right thing - req.pointSize = qt_pointSize(req.pixelSize, d->dpi); + if (req.pointSize < 0) + req.pointSize = qt_pointSize(req.pixelSize, d->dpi); + QFontEngine *fe = QFontCache::instance()->findEngine(key); diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 3da1593..4041717 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -327,7 +327,7 @@ void QFreetypeFace::release(const QFontEngine::FaceId &face_id) void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing) { - *ysize = fontDef.pixelSize << 6; + *ysize = qRound(fontDef.pixelSize * 64); *xsize = *ysize * fontDef.stretch / 100; *outline_drawing = false; @@ -387,7 +387,9 @@ QFontEngine::Properties QFreetypeFace::properties() const p.descent = QFixed::fromFixed(-face->size->metrics.descender); p.leading = QFixed::fromFixed(face->size->metrics.height - face->size->metrics.ascender + face->size->metrics.descender); p.emSquare = face->size->metrics.y_ppem; - p.boundingBox = QRectF(-p.ascent.toReal(), 0, (p.ascent + p.descent).toReal(), face->size->metrics.max_advance/64.); +// p.boundingBox = QRectF(-p.ascent.toReal(), 0, (p.ascent + p.descent).toReal(), face->size->metrics.max_advance/64.); + p.boundingBox = QRectF(0, -p.ascent.toReal(), + face->size->metrics.max_advance/64, (p.ascent + p.descent).toReal() ); } p.italicAngle = 0; p.capHeight = p.ascent; @@ -709,6 +711,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format) hbFace = freetype->hbFace; metrics = face->size->metrics; + #if defined(Q_WS_QWS) /* TrueType fonts with embedded bitmaps may have a bitmap font specific @@ -1219,7 +1222,8 @@ QFixed QFontEngineFT::ascent() const QFixed QFontEngineFT::descent() const { - return QFixed::fromFixed(-metrics.descender); + // subtract a pixel to work around QFontMetrics's built-in + 1 + return QFixed::fromFixed(-metrics.descender - 64); } QFixed QFontEngineFT::leading() const diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 8ce437d..a4e7c04 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -546,7 +546,7 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1); if (synthesisFlags & QFontEngine::SynthesizedItalic) - cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0)); + cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); for (int i = 0; i < nGlyphs; ++i) { diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp index ef3f2ae..94974fc 100644 --- a/src/gui/text/qfontengine_qpf.cpp +++ b/src/gui/text/qfontengine_qpf.cpp @@ -819,7 +819,7 @@ FT_Face QFontEngineQPF::lockFace() const FT_Face face = freetype->face; // ### not perfect - const int ysize = fontDef.pixelSize << 6; + const int ysize = qRound(fontDef.pixelSize * qreal(64)); const int xsize = ysize; if (freetype->xsize != xsize || freetype->ysize != ysize) { diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index d781c70..6c367ab 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -208,7 +208,7 @@ void QFontEngineWin::getCMap() unitsPerEm = otm->otmEMSquare; x_height = (int)otm->otmsXHeight; loadKerningPairs(designToDevice); - _faceId.filename = (char *)otm + (int)otm->otmpFullName; + _faceId.filename = QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpFullName)).toLatin1(); lineWidth = otm->otmsUnderscoreSize; fsType = otm->otmfsType; free(otm); @@ -577,7 +577,9 @@ QFixed QFontEngineWin::ascent() const QFixed QFontEngineWin::descent() const { - return tm.tmDescent; + // ### we substract 1 to even out the historical +1 in QFontMetrics's + // ### height=asc+desc+1 equation. Fix in Qt5. + return tm.tmDescent - 1; } QFixed QFontEngineWin::leading() const @@ -985,8 +987,8 @@ QFontEngine::Properties QFontEngineWin::properties() const Properties p; p.emSquare = unitsPerEm; p.italicAngle = otm->otmItalicAngle; - p.postscriptName = (char *)otm + (int)otm->otmpFamilyName; - p.postscriptName += (char *)otm + (int)otm->otmpStyleName; + p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpFamilyName)).toLatin1(); + p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpStyleName)).toLatin1(); #ifndef QT_NO_PRINTER p.postscriptName = QPdf::stripSpecialCharacters(p.postscriptName); #endif @@ -1108,7 +1110,7 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin ih + 2 * margin + 4, QNativeImage::systemFormat(), !qt_cleartype_enabled); - /*If cleartype is enabled we use the standard system format even on Windows CE + /*If cleartype is enabled we use the standard system format even on Windows CE and not the special textbuffer format we have to use if cleartype is disabled*/ ni->image.fill(0xffffffff); diff --git a/src/gui/text/qfontinfo.h b/src/gui/text/qfontinfo.h index 335d761..0998949 100644 --- a/src/gui/text/qfontinfo.h +++ b/src/gui/text/qfontinfo.h @@ -43,6 +43,7 @@ #define QFONTINFO_H #include <QtGui/qfont.h> +#include <QtCore/qsharedpointer.h> QT_BEGIN_HEADER @@ -77,7 +78,7 @@ public: bool exactMatch() const; private: - QFontPrivate *d; + QExplicitlySharedDataPointer<QFontPrivate> d; }; QT_END_NAMESPACE diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index ce122aa..b8c1b33 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -165,7 +165,6 @@ extern int qt_defaultDpi(); QFontMetrics::QFontMetrics(const QFont &font) : d(font.d.data()) { - d->ref.ref(); } /*! @@ -196,7 +195,6 @@ QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice) d->screen = screen; } else { d = font.d.data(); - d->ref.ref(); } } @@ -205,8 +203,9 @@ QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice) Constructs a copy of \a fm. */ QFontMetrics::QFontMetrics(const QFontMetrics &fm) - : d(fm.d) -{ d->ref.ref(); } + : d(fm.d.data()) +{ +} /*! Destroys the font metrics object and frees all allocated @@ -214,8 +213,6 @@ QFontMetrics::QFontMetrics(const QFontMetrics &fm) */ QFontMetrics::~QFontMetrics() { - if (!d->ref.deref()) - delete d; } /*! @@ -223,7 +220,7 @@ QFontMetrics::~QFontMetrics() */ QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm) { - qAtomicAssign(d, fm.d); + d = fm.d.data(); return *this; } @@ -536,7 +533,7 @@ int QFontMetrics::width(const QString &text, int len) const if (len == 0) return 0; - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; return qRound(layout.width(0, len)); } @@ -612,7 +609,7 @@ int QFontMetrics::charWidth(const QString &text, int pos) const int from = qMax(0, pos - 8); int to = qMin(text.length(), pos + 8); QString cstr = QString::fromRawData(text.unicode() + from, to - from); - QTextEngine layout(cstr, d); + QTextEngine layout(cstr, d.data()); layout.ignoreBidi = true; layout.itemize(); width = qRound(layout.width(pos-from, 1)); @@ -661,7 +658,7 @@ QRect QFontMetrics::boundingRect(const QString &text) const if (text.length() == 0) return QRect(); - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.boundingBox(0, text.length()); @@ -770,7 +767,7 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te QRectF rb; QRectF rr(rect); - qt_format_text(QFont(d), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, + qt_format_text(QFont(d.data()), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, tabArrayLen, 0); return rb.toAlignedRect(); @@ -831,7 +828,7 @@ QRect QFontMetrics::tightBoundingRect(const QString &text) const if (text.length() == 0) return QRect(); - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.tightBoundingBox(0, text.length()); @@ -876,7 +873,7 @@ QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, in } _text = _text.mid(posA); } - QStackTextEngine engine(_text, QFont(d)); + QStackTextEngine engine(_text, QFont(d.data())); return engine.elidedText(mode, width, flags); } @@ -989,9 +986,8 @@ int QFontMetrics::lineWidth() const from the given \a fontMetrics object. */ QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics) - : d(fontMetrics.d) + : d(fontMetrics.d.data()) { - d->ref.ref(); } /*! @@ -1001,7 +997,7 @@ QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics) */ QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other) { - qAtomicAssign(d, other.d); + d = other.d.data(); return *this; } @@ -1021,7 +1017,6 @@ QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other) QFontMetricsF::QFontMetricsF(const QFont &font) : d(font.d.data()) { - d->ref.ref(); } /*! @@ -1052,7 +1047,6 @@ QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice) d->screen = screen; } else { d = font.d.data(); - d->ref.ref(); } } @@ -1061,8 +1055,9 @@ QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice) Constructs a copy of \a fm. */ QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm) - : d(fm.d) -{ d->ref.ref(); } + : d(fm.d.data()) +{ +} /*! Destroys the font metrics object and frees all allocated @@ -1070,8 +1065,6 @@ QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm) */ QFontMetricsF::~QFontMetricsF() { - if (!d->ref.deref()) - delete d; } /*! @@ -1079,7 +1072,7 @@ QFontMetricsF::~QFontMetricsF() */ QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm) { - qAtomicAssign(d, fm.d); + d = fm.d.data(); return *this; } @@ -1374,7 +1367,7 @@ qreal QFontMetricsF::rightBearing(QChar ch) const */ qreal QFontMetricsF::width(const QString &text) const { - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); return layout.width(0, text.length()).toReal(); @@ -1451,7 +1444,7 @@ QRectF QFontMetricsF::boundingRect(const QString &text) const if (len == 0) return QRectF(); - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.boundingBox(0, len); @@ -1559,7 +1552,7 @@ QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString& tabArrayLen++; QRectF rb; - qt_format_text(QFont(d), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, + qt_format_text(QFont(d.data()), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, tabArrayLen, 0); return rb; } @@ -1624,7 +1617,7 @@ QRectF QFontMetricsF::tightBoundingRect(const QString &text) const if (text.length() == 0) return QRect(); - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.tightBoundingBox(0, text.length()); @@ -1649,7 +1642,7 @@ QRectF QFontMetricsF::tightBoundingRect(const QString &text) const */ QString QFontMetricsF::elidedText(const QString &text, Qt::TextElideMode mode, qreal width, int flags) const { - QStackTextEngine engine(text, QFont(d)); + QStackTextEngine engine(text, QFont(d.data())); return engine.elidedText(mode, QFixed::fromReal(width), flags); } diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h index 1147e3a..23200c5 100644 --- a/src/gui/text/qfontmetrics.h +++ b/src/gui/text/qfontmetrics.h @@ -43,6 +43,7 @@ #define QFONTMETRICS_H #include <QtGui/qfont.h> +#include <QtCore/qsharedpointer.h> #ifndef QT_INCLUDE_COMPAT #include <QtCore/qrect.h> #endif @@ -131,7 +132,7 @@ private: friend class QFontMetricsF; friend class QStackTextEngine; - QFontPrivate *d; + QExplicitlySharedDataPointer<QFontPrivate> d; }; @@ -187,7 +188,7 @@ public: inline bool operator !=(const QFontMetricsF &other) const { return !operator==(other); } private: - QFontPrivate *d; + QExplicitlySharedDataPointer<QFontPrivate> d; }; QT_END_NAMESPACE diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index ee8b751..3f6545c 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1619,9 +1619,11 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF if (cursor.position() != oldCursorPos) emit q->cursorPositionChanged(); _q_updateCurrentCharFormatAndSelection(); +#ifndef QT_NO_IM if (QInputContext *ic = inputContext()) { ic->update(); } +#endif //QT_NO_IM } else { //emit q->visibilityRequest(QRectF(mousePos, QSizeF(1, 1))); if (cursor.position() != oldCursorPos) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index a8956b8..1aad385 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -140,7 +140,7 @@ bool Qt::mightBeRichText(const QString& text) /*! Converts the plain text string \a plain to a HTML string with - HTML metacharacters \c{<}, \c{>}, and \c{&} replaced by HTML + HTML metacharacters \c{<}, \c{>}, \c{&}, and \c{"} replaced by HTML entities. Example: @@ -162,6 +162,8 @@ QString Qt::escape(const QString& plain) rich += QLatin1String(">"); else if (plain.at(i) == QLatin1Char('&')) rich += QLatin1String("&"); + else if (plain.at(i) == QLatin1Char('"')) + rich += QLatin1String("""); else rich += plain.at(i); } @@ -956,6 +958,8 @@ QString QTextDocument::defaultStyleSheet() const /*! Returns true if undo is available; otherwise returns false. + + \sa isRedoAvailable(), availableUndoSteps() */ bool QTextDocument::isUndoAvailable() const { @@ -965,6 +969,8 @@ bool QTextDocument::isUndoAvailable() const /*! Returns true if redo is available; otherwise returns false. + + \sa isUndoAvailable(), availableRedoSteps() */ bool QTextDocument::isRedoAvailable() const { @@ -972,6 +978,29 @@ bool QTextDocument::isRedoAvailable() const return d->isRedoAvailable(); } +/*! \since 4.6 + + Returns the number of available undo steps. + + \sa isUndoAvailable() +*/ +int QTextDocument::availableUndoSteps() const +{ + Q_D(const QTextDocument); + return d->availableUndoSteps(); +} + +/*! \since 4.6 + + Returns the number of available redo steps. + + \sa isRedoAvailable() +*/ +int QTextDocument::availableRedoSteps() const +{ + Q_D(const QTextDocument); + return d->availableRedoSteps(); +} /*! \since 4.4 @@ -2038,7 +2067,7 @@ void QTextHtmlExporter::emitAttribute(const char *attribute, const QString &valu html += QLatin1Char(' '); html += QLatin1String(attribute); html += QLatin1String("=\""); - html += value; + html += Qt::escape(value); html += QLatin1Char('"'); } @@ -2302,12 +2331,12 @@ void QTextHtmlExporter::emitFontFamily(const QString &family) { html += QLatin1String(" font-family:"); - QLatin1Char quote('\''); - if (family.contains(quote)) - quote = QLatin1Char('\"'); + QLatin1String quote("\'"); + if (family.contains(QLatin1Char('\''))) + quote = QLatin1String("""); html += quote; - html += family; + html += Qt::escape(family); html += quote; html += QLatin1Char(';'); } @@ -2341,13 +2370,13 @@ void QTextHtmlExporter::emitFragment(const QTextFragment &fragment) const QString name = format.anchorName(); if (!name.isEmpty()) { html += QLatin1String("<a name=\""); - html += name; + html += Qt::escape(name); html += QLatin1String("\"></a>"); } const QString href = format.anchorHref(); if (!href.isEmpty()) { html += QLatin1String("<a href=\""); - html += href; + html += Qt::escape(href); html += QLatin1String("\">"); closeAnchor = true; } diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h index e52716a..d217a4d 100644 --- a/src/gui/text/qtextdocument.h +++ b/src/gui/text/qtextdocument.h @@ -142,6 +142,9 @@ public: bool isUndoAvailable() const; bool isRedoAvailable() const; + int availableUndoSteps() const; + int availableRedoSteps() const; + int revision() const; void setDocumentLayout(QAbstractTextDocumentLayout *layout); diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h index ce25c57..c10855b 100644 --- a/src/gui/text/qtextdocument_p.h +++ b/src/gui/text/qtextdocument_p.h @@ -212,6 +212,9 @@ public: inline bool isUndoAvailable() const { return undoEnabled && undoState > 0; } inline bool isRedoAvailable() const { return undoEnabled && undoState < undoStack.size(); } + inline int availableUndoSteps() const { return undoEnabled ? undoState : 0; } + inline int availableRedoSteps() const { return undoEnabled ? qMax(undoStack.size() - undoState - 1, 0) : 0; } + inline QString buffer() const { return text; } QString plainText() const; inline int length() const { return fragments.length(); } diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index de83d39..73434b1 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -1437,7 +1437,9 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p option.setTextDirection(dir); layout.setTextOption(option); layout.beginLayout(); - layout.createLine(); + QTextLine line = layout.createLine(); + if (line.isValid()) + line.setLeadingIncluded(true); layout.endLayout(); layout.draw(painter, QPointF(r.left(), pos.y())); break; @@ -2579,6 +2581,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi QTextLine line = tl->createLine(); if (!line.isValid()) break; + line.setLeadingIncluded(true); QFixed left, right; floatMargins(layoutStruct->y, layoutStruct, &left, &right); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 81c9142..a91408f 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1042,7 +1042,7 @@ void QTextEngine::shapeTextWithCE(int item) const QScriptItem &si = layoutData->items[item]; si.glyph_data_offset = layoutData->used; - QFontEngine *fe = fontEngine(si, &si.ascent, &si.descent); + QFontEngine *fe = fontEngine(si, &si.ascent, &si.descent, &si.leading); QTextEngine::ShaperFlags flags; if (si.analysis.bidiLevel % 2) @@ -1119,7 +1119,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const si.glyph_data_offset = layoutData->used; - QFontEngine *font = fontEngine(si, &si.ascent, &si.descent); + QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading); bool kerningEnabled = this->font(si).d->kerning; @@ -1350,8 +1350,11 @@ void QTextEngine::shape(int item) const layoutData->items[item].position + block.position(), format); } } else if (layoutData->items[item].analysis.flags == QScriptAnalysis::Tab) { - // set up at least the ascent/descent of the script item for the tab - fontEngine(layoutData->items[item], &layoutData->items[item].ascent, &layoutData->items[item].descent); + // set up at least the ascent/descent/leading of the script item for the tab + fontEngine(layoutData->items[item], + &layoutData->items[item].ascent, + &layoutData->items[item].descent, + &layoutData->items[item].leading); } else { shapeText(item); } @@ -1737,7 +1740,7 @@ QFont QTextEngine::font(const QScriptItem &si) const return font; } -QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFixed *descent) const +QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFixed *descent, QFixed *leading) const { QFontEngine *engine = 0; QFontEngine *scaledEngine = 0; @@ -1777,6 +1780,7 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix if (ascent) { *ascent = engine->ascent(); *descent = engine->descent(); + *leading = engine->leading(); } if (scaledEngine) @@ -2009,8 +2013,12 @@ void QScriptLine::setDefaultHeight(QTextEngine *eng) e = eng->fnt.d->engineForScript(QUnicodeTables::Common); } - ascent = qMax(ascent, e->ascent()); - descent = qMax(descent, e->descent()); + QFixed other_ascent = e->ascent(); + QFixed other_descent = e->descent(); + QFixed other_leading = e->leading(); + leading = qMax(leading + ascent, other_leading + other_ascent) - qMax(ascent, other_ascent); + ascent = qMax(ascent, other_ascent); + descent = qMax(descent, other_descent); } QTextEngine::LayoutData::LayoutData() diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp index e101830..eeccc72 100644 --- a/src/gui/text/qtextengine_mac.cpp +++ b/src/gui/text/qtextengine_mac.cpp @@ -557,7 +557,7 @@ void QTextEngine::shapeTextMac(int item) const si.glyph_data_offset = layoutData->used; - QFontEngine *font = fontEngine(si, &si.ascent, &si.descent); + QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading); if (font->type() != QFontEngine::Multi) { shapeTextWithHarfbuzz(item); return; diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 85c6928..a1d363b 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -345,11 +345,11 @@ struct Q_AUTOTEST_EXPORT QScriptItem { inline QScriptItem() : position(0), - num_glyphs(0), descent(-1), ascent(-1), width(-1), + num_glyphs(0), descent(-1), ascent(-1), leading(-1), width(-1), glyph_data_offset(0) {} inline QScriptItem(int p, const QScriptAnalysis &a) : position(p), analysis(a), - num_glyphs(0), descent(-1), ascent(-1), width(-1), + num_glyphs(0), descent(-1), ascent(-1), leading(-1), width(-1), glyph_data_offset(0) {} int position; @@ -357,6 +357,7 @@ struct Q_AUTOTEST_EXPORT QScriptItem unsigned short num_glyphs; QFixed descent; QFixed ascent; + QFixed leading; QFixed width; int glyph_data_offset; QFixed height() const { return ascent + descent + 1; } @@ -373,9 +374,10 @@ struct Q_AUTOTEST_EXPORT QScriptLine QScriptLine() : from(0), length(0), justified(0), gridfitted(0), - hasTrailingSpaces(0) {} + hasTrailingSpaces(0), leadingIncluded(0) {} QFixed descent; QFixed ascent; + QFixed leading; QFixed x; QFixed y; QFixed width; @@ -385,7 +387,11 @@ struct Q_AUTOTEST_EXPORT QScriptLine mutable uint justified : 1; mutable uint gridfitted : 1; uint hasTrailingSpaces : 1; - QFixed height() const { return ascent + descent + 1; } + uint leadingIncluded : 1; + QFixed height() const { return ascent + descent + 1 + + (leadingIncluded? qMax(QFixed(),leading) : QFixed()); } + QFixed base() const { return ascent + + (leadingIncluded ? qMax(QFixed(),leading) : QFixed()); } void setDefaultHeight(QTextEngine *eng); void operator+=(const QScriptLine &other); }; @@ -394,6 +400,7 @@ Q_DECLARE_TYPEINFO(QScriptLine, Q_PRIMITIVE_TYPE); inline void QScriptLine::operator+=(const QScriptLine &other) { + leading= qMax(leading + ascent, other.leading + other.ascent) - qMax(ascent, other.ascent); descent = qMax(descent, other.descent); ascent = qMax(ascent, other.ascent); textWidth += other.textWidth; @@ -476,7 +483,7 @@ public: return end - si->position; } - QFontEngine *fontEngine(const QScriptItem &si, QFixed *ascent = 0, QFixed *descent = 0) const; + QFontEngine *fontEngine(const QScriptItem &si, QFixed *ascent = 0, QFixed *descent = 0, QFixed *leading = 0) const; QFont font(const QScriptItem &si) const; inline QFont font() const { return fnt; } diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index c5f0e35..4600a29 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -860,7 +860,7 @@ QRectF QTextLayout::boundingRect() const ymin = qMin(ymin, si.y); xmax = qMax(xmax, si.x+qMax(si.width, si.textWidth)); // ### shouldn't the ascent be used in ymin??? - ymax = qMax(ymax, si.y+si.ascent+si.descent+1); + ymax = qMax(ymax, si.y+si.height()); } return QRectF(xmin.toReal(), ymin.toReal(), (xmax-xmin).toReal(), (ymax-ymin).toReal()); } @@ -1071,10 +1071,10 @@ static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPo QTextLineItemIterator iterator(eng, lineNumber, pos, selection); - const QFixed y = QFixed::fromReal(pos.y()) + line.y + line.ascent; + + const qreal selectionY = pos.y() + line.y.toReal(); const qreal lineHeight = line.height().toReal(); - const qreal selectionY = (y - line.ascent).toReal(); QFixed lastSelectionX = iterator.x; QFixed lastSelectionWidth; @@ -1334,23 +1334,23 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition const qreal x = position.x() + l.cursorToX(cursorPosition); int itm = d->findItem(cursorPosition - 1); - QFixed ascent = sl.ascent; + QFixed base = sl.base(); QFixed descent = sl.descent; bool rightToLeft = (d->option.textDirection() == Qt::RightToLeft); if (itm >= 0) { const QScriptItem &si = d->layoutData->items.at(itm); if (si.ascent > 0) - ascent = si.ascent; + base = si.ascent; if (si.descent > 0) descent = si.descent; rightToLeft = si.analysis.bidiLevel % 2; } - qreal y = position.y() + (sl.y + sl.ascent - ascent).toReal(); + qreal y = position.y() + (sl.y + sl.base() - base).toReal(); bool toggleAntialiasing = !(p->renderHints() & QPainter::Antialiasing) && (p->transform().type() > QTransform::TxTranslate); if (toggleAntialiasing) p->setRenderHint(QPainter::Antialiasing); - p->fillRect(QRectF(x, y, qreal(width), (ascent + descent).toReal()), p->pen().brush()); + p->fillRect(QRectF(x, y, qreal(width), (base + descent + 1).toReal()), p->pen().brush()); if (toggleAntialiasing) p->setRenderHint(QPainter::Antialiasing, false); if (d->layoutData->hasBidi) { @@ -1500,9 +1500,11 @@ qreal QTextLine::descent() const } /*! - Returns the line's height. This is equal to ascent() + descent() + 1. + Returns the line's height. This is equal to ascent() + descent() + 1 + if leading is not included. If leading is included, this equals to + ascent() + descent() + leading() + 1. - \sa ascent() descent() + \sa ascent() descent() leading() setLeadingIncluded() */ qreal QTextLine::height() const { @@ -1510,6 +1512,51 @@ qreal QTextLine::height() const } /*! + \since 4.6 + + Returns the line's leading. + + \sa ascent() descent() height() +*/ +qreal QTextLine::leading() const +{ + return eng->lines[i].leading.toReal(); +} + +/*! \since 4.6 + + Includes positive leading into the line's height if \a included is true; + otherwise does not include leading. + + By default, leading is not included. + + Note that negative leading is ignored, it must be handled + in the code using the text lines by letting the lines overlap. + + \sa leadingIncluded() + +*/ +void QTextLine::setLeadingIncluded(bool included) +{ + eng->lines[i].leadingIncluded= included; + +} + +/*! \since 4.6 + + Returns true if positive leading is included into the line's height; otherwise returns false. + + By default, leading is not included. + + \sa setLeadingIncluded() +*/ +bool QTextLine::leadingIncluded() const +{ + return eng->lines[i].leadingIncluded; +} + + +/*! Returns the width of the line that is occupied by text. This is always \<= to width(), and is the minimum width that could be used by layout() without changing the line break position. @@ -1712,6 +1759,9 @@ void QTextLine::layout_helper(int maxGlyphs) } const QScriptItem ¤t = eng->layoutData->items[item]; + lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent, + current.leading + current.ascent) - qMax(lbh.tmpData.ascent, + current.ascent); lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent); lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent); @@ -2042,7 +2092,9 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR QTextLineItemIterator iterator(eng, i, pos, selection); - const QFixed y = QFixed::fromReal(pos.y()) + line.y + line.ascent; + QFixed lineBase = line.base(); + + const QFixed y = QFixed::fromReal(pos.y()) + line.y + lineBase; bool suppressColors = (eng->option.flags() & QTextOption::SuppressColors); while (!iterator.atEnd()) { @@ -2065,7 +2117,7 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR if (selection) format.merge(selection->format); - setPenAndDrawBackground(p, pen, format, QRectF(iterator.x.toReal(), (y - line.ascent).toReal(), + setPenAndDrawBackground(p, pen, format, QRectF(iterator.x.toReal(), (y - lineBase).toReal(), iterator.itemWidth.toReal(), line.height().toReal())); QTextCharFormat::VerticalAlignment valign = format.verticalAlignment(); @@ -2086,7 +2138,7 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR if (si.analysis.flags == QScriptAnalysis::Object && eng->block.docHandle()) { QFixed itemY = y - si.ascent; if (format.verticalAlignment() == QTextCharFormat::AlignTop) { - itemY = y - line.ascent; + itemY = y - lineBase; } QRectF itemRect(iterator.x.toReal(), itemY.toReal(), iterator.itemWidth.toReal(), si.height().toReal()); diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h index 90afac8..9f170f5 100644 --- a/src/gui/text/qtextlayout.h +++ b/src/gui/text/qtextlayout.h @@ -196,6 +196,10 @@ public: qreal ascent() const; qreal descent() const; qreal height() const; + qreal leading() const; + + void setLeadingIncluded(bool included); + bool leadingIncluded() const; qreal naturalTextWidth() const; QRectF naturalTextRect() const; diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index b28ecd7..b7615a4 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -78,6 +78,7 @@ win32 { unix:x11 { HEADERS += \ text/qfontengine_x11_p.h \ + text/qfontdatabase_x11.cpp \ text/qfontengine_ft_p.h SOURCES += \ text/qfont_x11.cpp \ |