diff options
Diffstat (limited to 'src/gui/text/qfont.cpp')
-rw-r--r-- | src/gui/text/qfont.cpp | 102 |
1 files changed, 42 insertions, 60 deletions
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 7e94c1ea74..fa9bb709c9 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -275,8 +275,8 @@ QFontPrivate::QFontPrivate(const QFontPrivate &other) QFontPrivate::~QFontPrivate() { - if (engineData) - engineData->ref.deref(); + if (engineData && !engineData->ref.deref()) + delete engineData; engineData = 0; if (scFont && scFont != this) scFont->ref.deref(); @@ -298,7 +298,8 @@ QFontEngine *QFontPrivate::engineForScript(int script) const script = QUnicodeTables::Common; if (engineData && engineData->fontCache != QFontCache::instance()) { // throw out engineData that came from a different thread - engineData->ref.deref(); + if (!engineData->ref.deref()) + delete engineData; engineData = 0; } if (!engineData || !QT_FONT_ENGINE_FROM_DATA(engineData, script)) @@ -417,13 +418,13 @@ QFontEngineData::~QFontEngineData() { #if !defined(Q_WS_MAC) for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) { - if (engines[i]) - engines[i]->ref.deref(); + if (engines[i] && !engines[i]->ref.deref()) + delete engines[i]; engines[i] = 0; } #else - if (engine) - engine->ref.deref(); + if (engine && !engine->ref.deref()) + delete engine; engine = 0; #endif // Q_WS_X11 || Q_WS_WIN || Q_WS_MAC } @@ -770,8 +771,8 @@ QFont::QFont(QFontPrivate *data) void QFont::detach() { if (d->ref == 1) { - if (d->engineData) - d->engineData->ref.deref(); + if (d->engineData && !d->engineData->ref.deref()) + delete d->engineData; d->engineData = 0; if (d->scFont && d->scFont != d.data()) d->scFont->ref.deref(); @@ -2819,7 +2820,7 @@ QFontCache::~QFontCache() EngineDataCache::ConstIterator it = engineDataCache.constBegin(), end = engineDataCache.constEnd(); while (it != end) { - if (it.value()->ref == 0) + if (it.value()->ref.deref() == 0) delete it.value(); else FC_DEBUG("QFontCache::~QFontCache: engineData %p still has refcount %d", @@ -2827,24 +2828,6 @@ QFontCache::~QFontCache() ++it; } } - EngineCache::ConstIterator it = engineCache.constBegin(), - end = engineCache.constEnd(); - 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 %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); - - delete it.value().data; - } else { - FC_DEBUG("QFontCache::~QFontCache: engine = %p still has refcount %d", - it.value().data, int(it.value().data->ref)); - } - } - ++it; - } } void QFontCache::clear() @@ -2856,16 +2839,14 @@ void QFontCache::clear() QFontEngineData *data = it.value(); #if !defined(Q_WS_MAC) for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) { - if (data->engines[i]) { - data->engines[i]->ref.deref(); - data->engines[i] = 0; - } + if (data->engines[i] && !data->engines[i]->ref.deref()) + delete data->engines[i]; + data->engines[i] = 0; } #else - if (data->engine) { - data->engine->ref.deref(); - data->engine = 0; - } + if (data->engine && !data->engine->ref.deref()) + delete data->engine; + data->engine = 0; #endif ++it; } @@ -2873,15 +2854,7 @@ void QFontCache::clear() for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end(); it != end; ++it) { - if (it->data->ref == 0) { - delete it->data; - it->data = 0; - } - } - - for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end(); - it != end; ++it) { - if (it->data && it->data->ref == 0) { + if (it->data->ref.deref() == 0) { delete it->data; it->data = 0; } @@ -2916,6 +2889,8 @@ void QFontCache::insertEngineData(const Key &key, QFontEngineData *engineData) { FC_DEBUG("QFontCache: inserting new engine data %p", engineData); + Q_ASSERT(!engineDataCache.contains(key)); + engineData->ref.ref(); // the cache has a reference engineDataCache.insert(key, engineData); increaseCost(sizeof(QFontEngineData)); } @@ -2946,6 +2921,11 @@ void QFontCache::insertEngine(const Key &key, QFontEngine *engine) Engine data(engine); data.timestamp = ++current_timestamp; + QFontEngine *oldEngine = engineCache.value(key).data; + engine->ref.ref(); // the cache has a reference + if (oldEngine && !oldEngine->ref.deref()) + delete oldEngine; + engineCache.insert(key, data); // only increase the cost if this is the first time we insert the engine @@ -3005,12 +2985,11 @@ void QFontCache::cleanupPrinterFonts() continue; } - if(it.value()->ref != 0) { - for(int i = 0; i < QUnicodeTables::ScriptCount; ++i) { - if(it.value()->engines[i]) { - it.value()->engines[i]->ref.deref(); - it.value()->engines[i] = 0; - } + if (it.value()->ref > 1) { + for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) { + if (it.value()->engines[i] && !it.value()->engines[i]->ref.deref()) + delete it.value()->engines[i]; + it.value()->engines[i] = 0; } ++it; } else { @@ -3021,7 +3000,8 @@ void QFontCache::cleanupPrinterFonts() FC_DEBUG(" %p", rem.value()); - delete rem.value(); + if (!rem.value()->ref.deref()) + delete rem.value(); engineDataCache.erase(rem); } } @@ -3030,7 +3010,7 @@ void QFontCache::cleanupPrinterFonts() EngineCache::Iterator it = engineCache.begin(), end = engineCache.end(); while(it != end) { - if (it.value().data->ref != 0 || it.key().screen == 0) { + if (it.value().data->ref != 1 || it.key().screen == 0) { ++it; continue; } @@ -3044,7 +3024,8 @@ void QFontCache::cleanupPrinterFonts() FC_DEBUG(" DELETE: last occurrence in cache"); decreaseCost(it.value().data->cache_cost); - delete it.value().data; + if (!it.value().data->ref.deref()) + delete it.value().data; } engineCache.erase(it++); @@ -3093,7 +3074,7 @@ void QFontCache::timerEvent(QTimerEvent *) # endif // Q_WS_X11 || Q_WS_WIN #endif // QFONTCACHE_DEBUG - if (it.value()->ref != 0) + if (it.value()->ref > 1) in_use_cost += engine_data_cost; } } @@ -3109,7 +3090,7 @@ void QFontCache::timerEvent(QTimerEvent *) int(it.value().data->ref), it.value().data->cache_count, it.value().data->cache_cost); - if (it.value().data->ref != 0) + if (it.value().data->ref > 1) in_use_cost += it.value().data->cache_cost / it.value().data->cache_count; } @@ -3159,7 +3140,7 @@ void QFontCache::timerEvent(QTimerEvent *) EngineDataCache::Iterator it = engineDataCache.begin(), end = engineDataCache.end(); while (it != end) { - if (it.value()->ref != 0) { + if (it.value()->ref > 1) { ++it; continue; } @@ -3187,7 +3168,7 @@ void QFontCache::timerEvent(QTimerEvent *) uint least_popular = ~0u; for (; it != end; ++it) { - if (it.value().data->ref != 0) + if (it.value().data->ref > 1) continue; if (it.value().timestamp < oldest && @@ -3200,7 +3181,7 @@ void QFontCache::timerEvent(QTimerEvent *) FC_DEBUG(" oldest %u least popular %u", oldest, least_popular); for (it = engineCache.begin(); it != end; ++it) { - if (it.value().data->ref == 0 && + if (it.value().data->ref == 1 && it.value().timestamp == oldest && it.value().hits == least_popular) break; @@ -3216,7 +3197,8 @@ void QFontCache::timerEvent(QTimerEvent *) FC_DEBUG(" DELETE: last occurrence in cache"); decreaseCost(it.value().data->cache_cost); - delete it.value().data; + if (!it.value().data->ref.deref()) + delete it.value().data; } else { /* this particular font engine is in the cache multiple |