summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@trolltech.com>2009-11-16 08:41:37 (GMT)
committerOlivier Goffart <ogoffart@trolltech.com>2009-11-16 08:41:50 (GMT)
commitaa482dcbde0089fe32ca59e39f17e5e44fd8b244 (patch)
treeab780e2f6ac7197fc67440c2b7fb9328dbebd4f7 /src/gui/text
parent4712a3a1ff6192f716d4f6894c6e69386ae55411 (diff)
parentb2d5f886b36b4f4d317024db7cfd6668e2895cd4 (diff)
downloadQt-aa482dcbde0089fe32ca59e39f17e5e44fd8b244.zip
Qt-aa482dcbde0089fe32ca59e39f17e5e44fd8b244.tar.gz
Qt-aa482dcbde0089fe32ca59e39f17e5e44fd8b244.tar.bz2
Merge commit oslo-staging-2/4.6 into upstream/4.6
Diffstat (limited to 'src/gui/text')
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.h1
-rw-r--r--src/gui/text/qfontengine_ft.cpp3
-rw-r--r--src/gui/text/qtextcontrol.cpp37
-rw-r--r--src/gui/text/qtextcontrol_p.h4
-rw-r--r--src/gui/text/qtextcontrol_p_p.h1
-rw-r--r--src/gui/text/qtextdocument.cpp4
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp4
-rw-r--r--src/gui/text/qtextformat.cpp76
-rw-r--r--src/gui/text/qtextformat_p.h4
9 files changed, 102 insertions, 32 deletions
diff --git a/src/gui/text/qabstracttextdocumentlayout.h b/src/gui/text/qabstracttextdocumentlayout.h
index 2f8a746..438b291 100644
--- a/src/gui/text/qabstracttextdocumentlayout.h
+++ b/src/gui/text/qabstracttextdocumentlayout.h
@@ -122,6 +122,7 @@ protected:
QTextCharFormat format(int pos);
private:
+ friend class QTextControl;
friend class QTextDocument;
friend class QTextDocumentPrivate;
friend class QTextEngine;
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 4041717..293eac7 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -755,9 +755,8 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph
load_flags = FT_LOAD_NO_BITMAP;
// apply our matrix to this, but note that the metrics will not be affected by this.
- FT_Matrix matrix = freetype->matrix;
FT_Face face = lockFace();
- matrix = this->matrix;
+ FT_Matrix matrix = this->matrix;
FT_Matrix_Multiply(&set->transformationMatrix, &matrix);
FT_Set_Transform(face, &matrix, 0);
freetype->matrix = matrix;
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index 2bfe33c..be79773 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -55,6 +55,7 @@
#include <qstyle.h>
#include <qtimer.h>
#include "private/qtextdocumentlayout_p.h"
+#include "private/qabstracttextdocumentlayout_p.h"
#include "private/qtextedit_p.h"
#include "qtextdocument.h"
#include "private/qtextdocument_p.h"
@@ -126,6 +127,7 @@ QTextControlPrivate::QTextControlPrivate()
#endif
isEnabled(true),
hadSelectionOnMousePress(false),
+ ignoreUnusedNavigationEvents(false),
openExternalLinks(false)
{}
@@ -264,19 +266,25 @@ bool QTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e)
cursor.setVisualNavigation(visualNavigation);
q->ensureCursorVisible();
+ bool ignoreNavigationEvents = ignoreUnusedNavigationEvents;
+ bool isNavigationEvent = e->key() == Qt::Key_Up || e->key() == Qt::Key_Down;
+
+#ifdef QT_KEYPAD_NAVIGATION
+ ignoreNavigationEvents = ignoreNavigationEvents || QApplication::keypadNavigationEnabled();
+ isNavigationEvent = isNavigationEvent ||
+ (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
+ && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right));
+#else
+ isNavigationEvent = isNavigationEvent || e->key() == Qt::Key_Left || e->key() == Qt::Key_Right;
+#endif
+
if (moved) {
if (cursor.position() != oldCursorPos)
emit q->cursorPositionChanged();
emit q->microFocusChanged();
- }
-#ifdef QT_KEYPAD_NAVIGATION
- else if (QApplication::keypadNavigationEnabled()
- && ((e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)
- || QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
- && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))) {
+ } else if (ignoreNavigationEvents && isNavigationEvent) {
return false;
}
-#endif
selectionChanged(/*forceEmitSelectionChanged =*/(mode == QTextCursor::KeepAnchor));
@@ -2263,6 +2271,18 @@ bool QTextControl::openExternalLinks() const
return d->openExternalLinks;
}
+bool QTextControl::ignoreUnusedNavigationEvents() const
+{
+ Q_D(const QTextControl);
+ return d->ignoreUnusedNavigationEvents;
+}
+
+void QTextControl::setIgnoreUnusedNavigationEvents(bool ignore)
+{
+ Q_D(QTextControl);
+ d->ignoreUnusedNavigationEvents = ignore;
+}
+
void QTextControl::moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode)
{
Q_D(QTextControl);
@@ -2319,6 +2339,9 @@ void QTextControl::print(QPrinter *printer) const
tempDoc->setUseDesignMetrics(doc->useDesignMetrics());
QTextCursor(tempDoc).insertFragment(d->cursor.selection());
doc = tempDoc;
+
+ // copy the custom object handlers
+ doc->documentLayout()->d_func()->handlers = d->doc->documentLayout()->d_func()->handlers;
}
doc->print(printer);
delete tempDoc;
diff --git a/src/gui/text/qtextcontrol_p.h b/src/gui/text/qtextcontrol_p.h
index 263af31..bc8e063 100644
--- a/src/gui/text/qtextcontrol_p.h
+++ b/src/gui/text/qtextcontrol_p.h
@@ -95,6 +95,7 @@ class Q_GUI_EXPORT QTextControl : public QObject
Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
Q_PROPERTY(bool openExternalLinks READ openExternalLinks WRITE setOpenExternalLinks)
+ Q_PROPERTY(bool ignoreUnusedNavigationEvents READ ignoreUnusedNavigationEvents WRITE setIgnoreUnusedNavigationEvents)
public:
explicit QTextControl(QObject *parent = 0);
explicit QTextControl(const QString &text, QObject *parent = 0);
@@ -163,6 +164,9 @@ public:
void setOpenExternalLinks(bool open);
bool openExternalLinks() const;
+ void setIgnoreUnusedNavigationEvents(bool ignore);
+ bool ignoreUnusedNavigationEvents() const;
+
void moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
bool canPaste() const;
diff --git a/src/gui/text/qtextcontrol_p_p.h b/src/gui/text/qtextcontrol_p_p.h
index 66459f6..c230512 100644
--- a/src/gui/text/qtextcontrol_p_p.h
+++ b/src/gui/text/qtextcontrol_p_p.h
@@ -206,6 +206,7 @@ public:
QString anchorOnMousePress;
bool hadSelectionOnMousePress;
+ bool ignoreUnusedNavigationEvents;
bool openExternalLinks;
QString linkToCopy;
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 1aad385..048325c 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -64,6 +64,7 @@
#include "qtextdocument_p.h"
#include <private/qprinter_p.h>
+#include <private/qabstracttextdocumentlayout_p.h>
#include <limits.h>
@@ -1722,6 +1723,9 @@ void QTextDocument::print(QPrinter *printer) const
QAbstractTextDocumentLayout *layout = doc->documentLayout();
layout->setPaintDevice(p.device());
+ // copy the custom object handlers
+ layout->d_func()->handlers = documentLayout()->d_func()->handlers;
+
int dpiy = p.device()->logicalDpiY();
int margin = 0;
if (printer->fullPage() && !printer->d_func()->hasCustomPageMargins) {
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index 73434b1..2604879 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -1448,13 +1448,13 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
painter->fillRect(r, brush);
break;
case QTextListFormat::ListCircle:
- painter->drawEllipse(r);
+ painter->setPen(QPen(brush, 0));
+ painter->drawEllipse(r.translated(0.5, 0.5)); // pixel align for sharper rendering
break;
case QTextListFormat::ListDisc:
painter->setBrush(brush);
painter->setPen(Qt::NoPen);
painter->drawEllipse(r);
- painter->setBrush(Qt::NoBrush);
break;
case QTextListFormat::ListStyleUndefined:
break;
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index d05d9e5..deda39f 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -265,21 +265,55 @@ private:
friend QDataStream &operator>>(QDataStream &, QTextFormat &);
};
-static uint variantHash(const QVariant &variant)
+// this is only safe if sizeof(int) == sizeof(float)
+static inline uint hash(float d)
{
- switch (variant.userType()) {
- case QVariant::Invalid: return 0;
- case QVariant::Bool: return variant.toBool();
- case QVariant::Int: return variant.toInt();
- case QMetaType::Float: return static_cast<int>(variant.toFloat());
- case QVariant::Double: return static_cast<int>(variant.toDouble());
+ return reinterpret_cast<uint&>(d);
+}
+
+static inline uint hash(const QColor &color)
+{
+ return (color.isValid()) ? color.rgba() : 0x234109;
+}
+
+static inline uint hash(const QPen &pen)
+{
+ return hash(pen.color()) + hash(pen.widthF());
+}
+
+static inline uint hash(const QBrush &brush)
+{
+ return hash(brush.color()) + (brush.style() << 3);
+}
+
+static inline uint variantHash(const QVariant &variant)
+{
+ // simple and fast hash functions to differentiate between type and value
+ switch (variant.userType()) { // sorted by occurrence frequency
case QVariant::String: return qHash(variant.toString());
- case QVariant::Color: return qHash(qvariant_cast<QColor>(variant).rgb());
+ case QVariant::Double: return hash(variant.toDouble());
+ case QVariant::Int: return 0x811890 + variant.toInt();
+ case QVariant::Brush:
+ return 0x01010101 + hash(qvariant_cast<QBrush>(variant));
+ case QVariant::Bool: return 0x371818 + variant.toBool();
+ case QVariant::Pen: return 0x02020202 + hash(qvariant_cast<QPen>(variant));
+ case QVariant::List:
+ return 0x8377 + qvariant_cast<QVariantList>(variant).count();
+ case QVariant::Color: return hash(qvariant_cast<QColor>(variant));
+ case QVariant::TextLength:
+ return 0x377 + hash(qvariant_cast<QTextLength>(variant).rawValue());
+ case QMetaType::Float: return hash(variant.toFloat());
+ case QVariant::Invalid: return 0;
default: break;
}
return qHash(variant.typeName());
}
+static inline int getHash(const QTextFormatPrivate *d, int format)
+{
+ return (d ? d->hash() : 0) + format;
+}
+
uint QTextFormatPrivate::recalcHash() const
{
hashValue = 0;
@@ -3033,13 +3067,15 @@ QTextFormatCollection::~QTextFormatCollection()
int QTextFormatCollection::indexForFormat(const QTextFormat &format)
{
- uint hash = format.d ? format.d->hash() : 0;
- if (hashes.contains(hash)) {
- for (int i = 0; i < formats.size(); ++i) {
- if (formats.at(i) == format)
- return i;
+ uint hash = getHash(format.d, format.format_type);
+ QMultiHash<uint, int>::const_iterator i = hashes.find(hash);
+ while (i != hashes.end() && i.key() == hash) {
+ if (formats.value(i.value()) == format) {
+ return i.value();
}
+ ++i;
}
+
int idx = formats.size();
formats.append(format);
@@ -3049,7 +3085,7 @@ int QTextFormatCollection::indexForFormat(const QTextFormat &format)
f.d = new QTextFormatPrivate;
f.d->resolveFont(defaultFnt);
- hashes.insert(hash);
+ hashes.insert(hash, idx);
} QT_CATCH(...) {
formats.pop_back();
@@ -3060,11 +3096,13 @@ int QTextFormatCollection::indexForFormat(const QTextFormat &format)
bool QTextFormatCollection::hasFormatCached(const QTextFormat &format) const
{
- uint hash = format.d ? format.d->hash() : 0;
- if (hashes.contains(hash)) {
- for (int i = 0; i < formats.size(); ++i)
- if (formats.at(i) == format)
- return true;
+ uint hash = getHash(format.d, format.format_type);
+ QMultiHash<uint, int>::const_iterator i = hashes.find(hash);
+ while (i != hashes.end() && i.key() == hash) {
+ if (formats.value(i.value()) == format) {
+ return true;
+ }
+ ++i;
}
return false;
}
diff --git a/src/gui/text/qtextformat_p.h b/src/gui/text/qtextformat_p.h
index c796343..73ca0ce 100644
--- a/src/gui/text/qtextformat_p.h
+++ b/src/gui/text/qtextformat_p.h
@@ -55,7 +55,7 @@
#include "QtGui/qtextformat.h"
#include "QtCore/qvector.h"
-#include "QtCore/qset.h"
+#include "QtCore/qhash.h"
QT_BEGIN_NAMESPACE
@@ -97,7 +97,7 @@ public:
FormatVector formats;
QVector<qint32> objFormats;
- QSet<uint> hashes;
+ QMultiHash<uint,int> hashes;
inline QFont defaultFont() const { return defaultFnt; }
void setDefaultFont(const QFont &f);