diff options
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 14 | ||||
-rw-r--r-- | src/gui/text/qfontengine.cpp | 120 | ||||
-rw-r--r-- | src/gui/text/qfontengine_mac.mm | 8 | ||||
-rw-r--r-- | src/gui/text/qfontengine_p.h | 16 | ||||
-rw-r--r-- | src/gui/text/qfontengineglyphcache_p.h | 7 | ||||
-rw-r--r-- | src/gui/text/qtextcontrol.cpp | 6 | ||||
-rw-r--r-- | src/gui/text/qtextcursor.cpp | 55 | ||||
-rw-r--r-- | src/gui/text/qtextodfwriter.cpp | 13 |
8 files changed, 88 insertions, 151 deletions
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 7e93aa0..e9c7b89 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -1482,13 +1482,13 @@ QString QFontDatabase::styleString(const QFontInfo &fontInfo) and style will look attractive. If the font family is available from two or more foundries the - foundry name is included in the family name, e.g. "Helvetica - [Adobe]" and "Helvetica [Cronyx]". When you specify a family you - can either use the old hyphenated Qt 2.x "foundry-family" format, - e.g. "Cronyx-Helvetica", or the new bracketed Qt 3.x "family - [foundry]" format e.g. "Helvetica [Cronyx]". If the family has a - foundry it is always returned, e.g. by families(), using the - bracketed format. + foundry name is included in the family name; for example: + "Helvetica [Adobe]" and "Helvetica [Cronyx]". When you specify a + family, you can either use the old hyphenated "foundry-family" + format or the bracketed "family [foundry]" format; for example: + "Cronyx-Helvetica" or "Helvetica [Cronyx]". If the family has a + foundry it is always returned using the bracketed format, as is + the case with the value returned by families(). The font() function returns a QFont given a family, style and point size. diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 27fc3c1..d364025 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -185,22 +185,11 @@ QFontEngine::QFontEngine() QFontEngine::~QFontEngine() { - for (GlyphPointerHash::const_iterator it = m_glyphPointerHash.constBegin(), - end = m_glyphPointerHash.constEnd(); it != end; ++it) { - for (QList<QFontEngineGlyphCache*>::const_iterator it2 = it.value().constBegin(), - end2 = it.value().constEnd(); it2 != end2; ++it2) { - delete *it2; - } - } - m_glyphPointerHash.clear(); - for (GlyphIntHash::const_iterator it = m_glyphIntHash.constBegin(), - end = m_glyphIntHash.constEnd(); it != end; ++it) { - for (QList<QFontEngineGlyphCache*>::const_iterator it2 = it.value().constBegin(), - end2 = it.value().constEnd(); it2 != end2; ++it2) { - delete *it2; - } + for (QLinkedList<GlyphCacheEntry>::const_iterator it = m_glyphCaches.constBegin(), + end = m_glyphCaches.constEnd(); it != end; ++it) { + delete it->cache; } - m_glyphIntHash.clear(); + m_glyphCaches.clear(); qHBFreeFace(hbFace); } @@ -713,103 +702,30 @@ QByteArray QFontEngine::getSfntTable(uint tag) const return table; } -void QFontEngine::expireGlyphCache() -{ - if (m_glyphCacheQueue.count() > 10) { // hold only 10 caches in memory. - QFontEngineGlyphCache *old = m_glyphCacheQueue.takeFirst(); - // remove the value from either of our hashes - for (GlyphPointerHash::iterator i = m_glyphPointerHash.begin(); i != m_glyphPointerHash.end(); ++i) { - QList<QFontEngineGlyphCache *> list = i.value(); - if (list.removeAll(old)) { - if (list.isEmpty()) - m_glyphPointerHash.remove(i.key()); - else - m_glyphPointerHash.insert(i.key(), list); - break; - } - } - for (GlyphIntHash::iterator i = m_glyphIntHash.begin(); i != m_glyphIntHash.end(); ++i) { - QList<QFontEngineGlyphCache *> list = i.value(); - if (list.removeAll(old)) { - if (list.isEmpty()) - m_glyphIntHash.remove(i.key()); - else - m_glyphIntHash.insert(i.key(), list); - break; - } - } - delete old; - } -} - void QFontEngine::setGlyphCache(void *key, QFontEngineGlyphCache *data) { Q_ASSERT(data); - QList<QFontEngineGlyphCache*> items = m_glyphPointerHash.value(key); - - for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) { - QFontEngineGlyphCache *c = *it; - if (qtransform_equals_no_translate(c->m_transform, data->m_transform)) { - if (c == data) - return; - items.removeAll(c); - delete c; - break; - } - } - items.append(data); - m_glyphPointerHash.insert(key, items); - m_glyphCacheQueue.append(data); - expireGlyphCache(); -} + GlyphCacheEntry entry = { key, data }; + if (m_glyphCaches.contains(entry)) + return; -void QFontEngine::setGlyphCache(QFontEngineGlyphCache::Type key, QFontEngineGlyphCache *data) -{ - Q_ASSERT(data); - QList<QFontEngineGlyphCache*> items = m_glyphIntHash.value(key); - - for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) { - QFontEngineGlyphCache *c = *it; - if (qtransform_equals_no_translate(c->m_transform, data->m_transform)) { - if (c == data) - return; - items.removeAll(c); - delete c; - break; - } - } - items.append(data); - m_glyphIntHash.insert(key, items); + // Limit the glyph caches to 4. This covers all 90 degree rotations and limits + // memory use when there is continous or random rotation + if (m_glyphCaches.size() == 4) + delete m_glyphCaches.takeLast().cache; - m_glyphCacheQueue.append(data); - expireGlyphCache(); -} + m_glyphCaches.push_front(entry); -QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, const QTransform &transform) const -{ - QList<QFontEngineGlyphCache*> items = m_glyphPointerHash.value(key); - - for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) { - QFontEngineGlyphCache *c = *it; - if (qtransform_equals_no_translate(c->m_transform, transform)) { - m_glyphCacheQueue.removeAll(c); // last used, move it up - m_glyphCacheQueue.append(c); - return c; - } - } - return 0; } -QFontEngineGlyphCache *QFontEngine::glyphCache(QFontEngineGlyphCache::Type key, const QTransform &transform) const +QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const { - QList<QFontEngineGlyphCache*> items = m_glyphIntHash.value(key); - - for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) { - QFontEngineGlyphCache *c = *it; - if (qtransform_equals_no_translate(c->m_transform, transform)) { - m_glyphCacheQueue.removeAll(c); // last used, move it up - m_glyphCacheQueue.append(c); + for (QLinkedList<GlyphCacheEntry>::const_iterator it = m_glyphCaches.constBegin(), end = m_glyphCaches.constEnd(); it != end; ++it) { + QFontEngineGlyphCache *c = it->cache; + if (key == it->context + && type == c->cacheType() + && qtransform_equals_no_translate(c->m_transform, transform)) { return c; } } diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index a4e7c04..a75d70f 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -404,7 +404,9 @@ QFixed QCoreTextFontEngine::ascent() const } QFixed QCoreTextFontEngine::descent() const { - return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil(); + // subtract a pixel to even out the historical +1 in QFontMetrics::height(). + // Fix in Qt 5. + return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil() - 1; } QFixed QCoreTextFontEngine::leading() const { @@ -1406,7 +1408,9 @@ QFixed QFontEngineMac::ascent() const QFixed QFontEngineMac::descent() const { - return m_descent; + // subtract a pixel to even out the historical +1 in QFontMetrics::height(). + // Fix in Qt 5. + return m_descent - 1; } QFixed QFontEngineMac::leading() const diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 728c344..a9883b4 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -56,6 +56,7 @@ #include "QtCore/qglobal.h" #include "QtCore/qatomic.h" #include <QtCore/qvarlengtharray.h> +#include <QtCore/QLinkedList> #include "private/qtextengine_p.h" #include "private/qfont_p.h" @@ -219,9 +220,7 @@ public: virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints); void setGlyphCache(void *key, QFontEngineGlyphCache *data); - void setGlyphCache(QFontEngineGlyphCache::Type key, QFontEngineGlyphCache *data); - QFontEngineGlyphCache *glyphCache(void *key, const QTransform &transform) const; - QFontEngineGlyphCache *glyphCache(QFontEngineGlyphCache::Type key, const QTransform &transform) const; + QFontEngineGlyphCache *glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const; static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize); static quint32 getTrueTypeGlyphIndex(const uchar *cmap, uint unicode); @@ -254,12 +253,13 @@ protected: static const QVector<QRgb> &grayPalette(); private: - /// remove old entries from the glyph cache. Helper method for the setGlyphCache ones. - void expireGlyphCache(); + struct GlyphCacheEntry { + void *context; + QFontEngineGlyphCache *cache; + bool operator==(const GlyphCacheEntry &other) { return context == other.context && cache == other.cache; } + }; - GlyphPointerHash m_glyphPointerHash; - GlyphIntHash m_glyphIntHash; - mutable QList<QFontEngineGlyphCache*> m_glyphCacheQueue; + mutable QLinkedList<GlyphCacheEntry> m_glyphCaches; }; inline bool operator ==(const QFontEngine::FaceId &f1, const QFontEngine::FaceId &f2) diff --git a/src/gui/text/qfontengineglyphcache_p.h b/src/gui/text/qfontengineglyphcache_p.h index e04f4ac..c6112ba 100644 --- a/src/gui/text/qfontengineglyphcache_p.h +++ b/src/gui/text/qfontengineglyphcache_p.h @@ -75,17 +75,20 @@ QT_BEGIN_NAMESPACE class QFontEngineGlyphCache { public: - QFontEngineGlyphCache(const QTransform &matrix) : m_transform(matrix) { } - enum Type { Raster_RGBMask, Raster_A8, Raster_Mono }; + QFontEngineGlyphCache(const QTransform &matrix, Type type) : m_transform(matrix), m_type(type) { } + virtual ~QFontEngineGlyphCache() { } + Type cacheType() const { return m_type; } + QTransform m_transform; + QFontEngineGlyphCache::Type m_type; }; typedef QHash<void *, QList<QFontEngineGlyphCache *> > GlyphPointerHash; typedef QHash<int, QList<QFontEngineGlyphCache *> > GlyphIntHash; diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index f96f66b..f523226 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1938,7 +1938,11 @@ void QTextControlPrivate::focusEvent(QFocusEvent *e) emit q->updateRequest(q->selectionRect()); if (e->gotFocus()) { #ifdef QT_KEYPAD_NAVIGATION - if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && e->reason() == Qt::PopupFocusReason)) { + if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason +#ifdef Q_OS_SYMBIAN + || e->reason() == Qt::ActiveWindowFocusReason +#endif + ))) { #endif cursorOn = (interactionFlags & Qt::TextSelectableByKeyboard); if (interactionFlags & Qt::TextEditable) { diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index ce62834..f1dbf23 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -862,27 +862,28 @@ QTextLayout *QTextCursorPrivate::blockLayout(QTextBlock &block) const{ \ingroup richtext-processing \ingroup shared - - Text cursors are objects that are used to access and modify the contents - and underlying structure of text documents via a programming interface - that mimics the behavior of a cursor in a text editor. QTextCursor contains - information about both the cursor's position within a QTextDocument and any - selection that it has made. + Text cursors are objects that are used to access and modify the + contents and underlying structure of text documents via a + programming interface that mimics the behavior of a cursor in a + text editor. QTextCursor contains information about both the + cursor's position within a QTextDocument and any selection that it + has made. QTextCursor is modeled on the way a text cursor behaves in a text - editor, providing a programmatic means of performing standard actions - through the user interface. A document can be thought of as a - single string of characters with the cursor's position() being \e - between any two characters (or at the very beginning or very end - of the document). Documents can also contain tables, lists, - images, and other objects in addition to text but, from the developer's - point of view, the document can be treated as one long string. - Some portions of that string can be considered to lie within particular - blocks (e.g. paragraphs), or within a table's cell, or a list's item, - or other structural elements. When we refer to "current character" we - mean the character immediately after the cursor position() in the - document; similarly the "current block" is the block that contains the - cursor position(). + editor, providing a programmatic means of performing standard + actions through the user interface. A document can be thought of + as a single string of characters. The cursor's current position() + then is always either \e between two consecutive characters in the + string, or else \e before the very first character or \e after the + very last character in the string. Documents can also contain + tables, lists, images, and other objects in addition to text but, + from the developer's point of view, the document can be treated as + one long string. Some portions of that string can be considered + to lie within particular blocks (e.g. paragraphs), or within a + table's cell, or a list's item, or other structural elements. When + we refer to "current character" we mean the character immediately + \e before the cursor position() in the document. Similarly, the + "current block" is the block that contains the cursor position(). A QTextCursor also has an anchor() position. The text that is between the anchor() and the position() is the selection. If @@ -940,11 +941,12 @@ QTextLayout *QTextCursorPrivate::blockLayout(QTextBlock &block) const{ undo/redo) using beginEditBlock() and endEditBlock(). Cursor movements are limited to valid cursor positions. In Latin - writing this is usually after every character in the text. In some - other writing systems cursor movements are limited to "clusters" - (e.g. a syllable in Devanagari, or a base letter plus diacritics). - Functions such as movePosition() and deleteChar() limit cursor - movement to these valid positions. + writing this is between any two consecutive characters in the + text, before the first character, or after the last character. In + some other writing systems cursor movements are limited to + "clusters" (e.g. a syllable in Devanagari, or a base letter plus + diacritics). Functions such as movePosition() and deleteChar() + limit cursor movement to these valid positions. \sa \link richtext.html Rich Text Processing\endlink @@ -1739,8 +1741,9 @@ void QTextCursor::mergeBlockCharFormat(const QTextCharFormat &modifier) } /*! - Returns the format of the character immediately before the cursor position(). If the cursor is - positioned at the beginning of a text block that is not empty then the format of the character + Returns the format of the character immediately before the cursor + position(). If the cursor is positioned at the beginning of a text + block that is not empty then the format of the character immediately after the cursor is returned. \sa insertText(), blockFormat() diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index 1bd4dd6..dcc2e7d 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -484,6 +484,10 @@ void QTextOdfWriter::writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat if (format.pageBreakPolicy() & QTextFormat::PageBreak_AlwaysAfter) writer.writeAttribute(foNS, QString::fromLatin1("break-after"), QString::fromLatin1("page")); } + if (format.hasProperty(QTextFormat::BackgroundBrush)) { + QBrush brush = format.background(); + writer.writeAttribute(foNS, QString::fromLatin1("background-color"), brush.color().name()); + } if (format.hasProperty(QTextFormat::BlockNonBreakableLines)) writer.writeAttribute(foNS, QString::fromLatin1("keep-together"), format.nonBreakableLines() ? QString::fromLatin1("true") : QString::fromLatin1("false")); @@ -552,8 +556,8 @@ void QTextOdfWriter::writeCharacterFormat(QXmlStreamWriter &writer, QTextCharFor } if (format.hasProperty(QTextFormat::FontLetterSpacing)) writer.writeAttribute(foNS, QString::fromLatin1("letter-spacing"), pixelToPoint(format.fontLetterSpacing())); - if (format.hasProperty(QTextFormat::FontWordSpacing)) - writer.writeAttribute(foNS, QString::fromLatin1("word-spacing"), pixelToPoint(format.fontWordSpacing())); + if (format.hasProperty(QTextFormat::FontWordSpacing) && format.fontWordSpacing() != 0) + writer.writeAttribute(foNS, QString::fromLatin1("word-spacing"), pixelToPoint(format.fontWordSpacing())); if (format.hasProperty(QTextFormat::FontUnderline)) writer.writeAttribute(styleNS, QString::fromLatin1("text-underline-type"), format.fontUnderline() ? QString::fromLatin1("single") : QString::fromLatin1("none")); @@ -610,9 +614,12 @@ void QTextOdfWriter::writeCharacterFormat(QXmlStreamWriter &writer, QTextCharFor } if (format.hasProperty(QTextFormat::ForegroundBrush)) { QBrush brush = format.foreground(); - // TODO writer.writeAttribute(foNS, QString::fromLatin1("color"), brush.color().name()); } + if (format.hasProperty(QTextFormat::BackgroundBrush)) { + QBrush brush = format.background(); + writer.writeAttribute(foNS, QString::fromLatin1("background-color"), brush.color().name()); + } writer.writeEndElement(); // style } |