diff -r 56cd8111b7f7 -r 41300fa6a67c src/gui/text/qtextformat.cpp --- a/src/gui/text/qtextformat.cpp Tue Jan 26 12:42:25 2010 +0200 +++ b/src/gui/text/qtextformat.cpp Tue Feb 02 00:43:10 2010 +0200 @@ -265,21 +265,55 @@ 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) +{ + return reinterpret_cast(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) { - switch (variant.userType()) { + 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::Double: return hash(variant.toDouble()); + case QVariant::Int: return 0x811890 + variant.toInt(); + case QVariant::Brush: + return 0x01010101 + hash(qvariant_cast(variant)); + case QVariant::Bool: return 0x371818 + variant.toBool(); + case QVariant::Pen: return 0x02020202 + hash(qvariant_cast(variant)); + case QVariant::List: + return 0x8377 + qvariant_cast(variant).count(); + case QVariant::Color: return hash(qvariant_cast(variant)); + case QVariant::TextLength: + return 0x377 + hash(qvariant_cast(variant).rawValue()); + case QMetaType::Float: return hash(variant.toFloat()); case QVariant::Invalid: return 0; - case QVariant::Bool: return variant.toBool(); - case QVariant::Int: return variant.toInt(); - case QMetaType::Float: return static_cast(variant.toFloat()); - case QVariant::Double: return static_cast(variant.toDouble()); - case QVariant::String: return qHash(variant.toString()); - case QVariant::Color: return qHash(qvariant_cast(variant).rgb()); 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 @@ 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::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 @@ f.d = new QTextFormatPrivate; f.d->resolveFont(defaultFnt); - hashes.insert(hash); + hashes.insert(hash, idx); } QT_CATCH(...) { formats.pop_back(); @@ -3060,11 +3096,13 @@ 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::const_iterator i = hashes.find(hash); + while (i != hashes.end() && i.key() == hash) { + if (formats.value(i.value()) == format) { + return true; + } + ++i; } return false; }