263 |
263 |
264 friend QDataStream &operator<<(QDataStream &, const QTextFormat &); |
264 friend QDataStream &operator<<(QDataStream &, const QTextFormat &); |
265 friend QDataStream &operator>>(QDataStream &, QTextFormat &); |
265 friend QDataStream &operator>>(QDataStream &, QTextFormat &); |
266 }; |
266 }; |
267 |
267 |
268 static uint variantHash(const QVariant &variant) |
268 // this is only safe if sizeof(int) == sizeof(float) |
269 { |
269 static inline uint hash(float d) |
270 switch (variant.userType()) { |
270 { |
|
271 return reinterpret_cast<uint&>(d); |
|
272 } |
|
273 |
|
274 static inline uint hash(const QColor &color) |
|
275 { |
|
276 return (color.isValid()) ? color.rgba() : 0x234109; |
|
277 } |
|
278 |
|
279 static inline uint hash(const QPen &pen) |
|
280 { |
|
281 return hash(pen.color()) + hash(pen.widthF()); |
|
282 } |
|
283 |
|
284 static inline uint hash(const QBrush &brush) |
|
285 { |
|
286 return hash(brush.color()) + (brush.style() << 3); |
|
287 } |
|
288 |
|
289 static inline uint variantHash(const QVariant &variant) |
|
290 { |
|
291 // simple and fast hash functions to differentiate between type and value |
|
292 switch (variant.userType()) { // sorted by occurrence frequency |
|
293 case QVariant::String: return qHash(variant.toString()); |
|
294 case QVariant::Double: return hash(variant.toDouble()); |
|
295 case QVariant::Int: return 0x811890 + variant.toInt(); |
|
296 case QVariant::Brush: |
|
297 return 0x01010101 + hash(qvariant_cast<QBrush>(variant)); |
|
298 case QVariant::Bool: return 0x371818 + variant.toBool(); |
|
299 case QVariant::Pen: return 0x02020202 + hash(qvariant_cast<QPen>(variant)); |
|
300 case QVariant::List: |
|
301 return 0x8377 + qvariant_cast<QVariantList>(variant).count(); |
|
302 case QVariant::Color: return hash(qvariant_cast<QColor>(variant)); |
|
303 case QVariant::TextLength: |
|
304 return 0x377 + hash(qvariant_cast<QTextLength>(variant).rawValue()); |
|
305 case QMetaType::Float: return hash(variant.toFloat()); |
271 case QVariant::Invalid: return 0; |
306 case QVariant::Invalid: return 0; |
272 case QVariant::Bool: return variant.toBool(); |
|
273 case QVariant::Int: return variant.toInt(); |
|
274 case QMetaType::Float: return static_cast<int>(variant.toFloat()); |
|
275 case QVariant::Double: return static_cast<int>(variant.toDouble()); |
|
276 case QVariant::String: return qHash(variant.toString()); |
|
277 case QVariant::Color: return qHash(qvariant_cast<QColor>(variant).rgb()); |
|
278 default: break; |
307 default: break; |
279 } |
308 } |
280 return qHash(variant.typeName()); |
309 return qHash(variant.typeName()); |
|
310 } |
|
311 |
|
312 static inline int getHash(const QTextFormatPrivate *d, int format) |
|
313 { |
|
314 return (d ? d->hash() : 0) + format; |
281 } |
315 } |
282 |
316 |
283 uint QTextFormatPrivate::recalcHash() const |
317 uint QTextFormatPrivate::recalcHash() const |
284 { |
318 { |
285 hashValue = 0; |
319 hashValue = 0; |
3031 { |
3065 { |
3032 } |
3066 } |
3033 |
3067 |
3034 int QTextFormatCollection::indexForFormat(const QTextFormat &format) |
3068 int QTextFormatCollection::indexForFormat(const QTextFormat &format) |
3035 { |
3069 { |
3036 uint hash = format.d ? format.d->hash() : 0; |
3070 uint hash = getHash(format.d, format.format_type); |
3037 if (hashes.contains(hash)) { |
3071 QMultiHash<uint, int>::const_iterator i = hashes.find(hash); |
3038 for (int i = 0; i < formats.size(); ++i) { |
3072 while (i != hashes.end() && i.key() == hash) { |
3039 if (formats.at(i) == format) |
3073 if (formats.value(i.value()) == format) { |
3040 return i; |
3074 return i.value(); |
3041 } |
3075 } |
|
3076 ++i; |
3042 } |
3077 } |
|
3078 |
3043 int idx = formats.size(); |
3079 int idx = formats.size(); |
3044 formats.append(format); |
3080 formats.append(format); |
3045 |
3081 |
3046 QT_TRY{ |
3082 QT_TRY{ |
3047 QTextFormat &f = formats.last(); |
3083 QTextFormat &f = formats.last(); |
3048 if (!f.d) |
3084 if (!f.d) |
3049 f.d = new QTextFormatPrivate; |
3085 f.d = new QTextFormatPrivate; |
3050 f.d->resolveFont(defaultFnt); |
3086 f.d->resolveFont(defaultFnt); |
3051 |
3087 |
3052 hashes.insert(hash); |
3088 hashes.insert(hash, idx); |
3053 |
3089 |
3054 } QT_CATCH(...) { |
3090 } QT_CATCH(...) { |
3055 formats.pop_back(); |
3091 formats.pop_back(); |
3056 QT_RETHROW; |
3092 QT_RETHROW; |
3057 } |
3093 } |
3058 return idx; |
3094 return idx; |
3059 } |
3095 } |
3060 |
3096 |
3061 bool QTextFormatCollection::hasFormatCached(const QTextFormat &format) const |
3097 bool QTextFormatCollection::hasFormatCached(const QTextFormat &format) const |
3062 { |
3098 { |
3063 uint hash = format.d ? format.d->hash() : 0; |
3099 uint hash = getHash(format.d, format.format_type); |
3064 if (hashes.contains(hash)) { |
3100 QMultiHash<uint, int>::const_iterator i = hashes.find(hash); |
3065 for (int i = 0; i < formats.size(); ++i) |
3101 while (i != hashes.end() && i.key() == hash) { |
3066 if (formats.at(i) == format) |
3102 if (formats.value(i.value()) == format) { |
3067 return true; |
3103 return true; |
|
3104 } |
|
3105 ++i; |
3068 } |
3106 } |
3069 return false; |
3107 return false; |
3070 } |
3108 } |
3071 |
3109 |
3072 QTextFormat QTextFormatCollection::objectFormat(int objectIndex) const |
3110 QTextFormat QTextFormatCollection::objectFormat(int objectIndex) const |