# UNDF: UNDF-2026-000001210 --- a/core/document_p.h +++ b/core/document_p.h @@ -334,6 +334,7 @@ public: QPointer m_fontThread; bool m_fontsCached; QSet m_documentInfoAskedKeys; DocumentInfo m_documentInfo; FontInfo::List m_fontsCache; + QSet m_fontsCacheKeys; // O(1) dedup set parallel to m_fontsCache QSet m_views; --- a/core/document.cpp +++ b/core/document.cpp @@ -1562,9 +1562,16 @@ void DocumentPrivate::fontReadingGotFont(const Okular::FontInfo &font) { - // Try to avoid duplicate fonts - if (m_fontsCache.indexOf(font) == -1) { + // Try to avoid duplicate fonts — O(1) lookup via parallel key set + // Previously: m_fontsCache.indexOf(font) which is O(F) per call, O(F^2) total. + // Fix: build a composite key from all equality fields and use QSet for O(1) dedup. + const QString key = font.name() + + QLatin1Char('|') + font.substituteName() + + QLatin1Char('|') + QString::number(static_cast(font.type())) + + QLatin1Char('|') + QString::number(static_cast(font.embedType())) + + QLatin1Char('|') + font.file() + + QLatin1Char('|') + (font.canBeExtracted() ? QLatin1Char('1') : QLatin1Char('0')); + if (!m_fontsCacheKeys.contains(key)) { + m_fontsCacheKeys.insert(key); m_fontsCache.append(font); Q_EMIT m_parent->gotFont(font); } }