📄 qfont.cpp
字号:
/*! Destroys the font info object.*/QFontInfo::~QFontInfo(){ if (!d->ref.deref()) delete d;}/*! Assigns the font info in \a fi.*/QFontInfo &QFontInfo::operator=(const QFontInfo &fi){ qAtomicAssign(d, fi.d); return *this;}/*! Returns the family name of the matched window system font. \sa QFont::family()*/QString QFontInfo::family() const{ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); return engine->fontDef.family;}/*! Returns the point size of the matched window system font. \sa pointSizeF() QFont::pointSize()*/int QFontInfo::pointSize() const{ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); return qRound(engine->fontDef.pointSize);}/*! Returns the point size of the matched window system font. \sa QFont::pointSizeF()*/qreal QFontInfo::pointSizeF() const{ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); return engine->fontDef.pointSize;}/*! Returns the pixel size of the matched window system font. \sa QFont::pointSize()*/int QFontInfo::pixelSize() const{ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); return engine->fontDef.pixelSize;}/*! Returns the italic value of the matched window system font. \sa QFont::italic()*/bool QFontInfo::italic() const{ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); return engine->fontDef.style != QFont::StyleNormal;}/*! Returns the style value of the matched window system font. \sa QFont::style()*/QFont::Style QFontInfo::style() const{ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); return (QFont::Style)engine->fontDef.style;}/*! Returns the weight of the matched window system font. \sa QFont::weight(), bold()*/int QFontInfo::weight() const{ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); return engine->fontDef.weight;}/*! \fn bool QFontInfo::bold() const Returns true if weight() would return a value greater than QFont::Normal; otherwise returns false. \sa weight(), QFont::bold()*//*! Returns the underline value of the matched window system font. \sa QFont::underline() \internal Here we read the underline flag directly from the QFont. This is OK for X11 and for Windows because we always get what we want.*/bool QFontInfo::underline() const{ return d->underline;}/*! Returns the overline value of the matched window system font. \sa QFont::overline() \internal Here we read the overline flag directly from the QFont. This is OK for X11 and for Windows because we always get what we want.*/bool QFontInfo::overline() const{ return d->overline;}/*! Returns the strikeout value of the matched window system font. \sa QFont::strikeOut() \internal Here we read the strikeOut flag directly from the QFont. This is OK for X11 and for Windows because we always get what we want.*/bool QFontInfo::strikeOut() const{ return d->strikeOut;}/*! Returns the fixed pitch value of the matched window system font. \sa QFont::fixedPitch()*/bool QFontInfo::fixedPitch() const{ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0);#ifdef Q_OS_MAC if (!engine->fontDef.fixedPitchComputed) { QChar ch[2] = { QLatin1Char('i'), QLatin1Char('m') }; QGlyphLayout g[2]; int l = 2; engine->stringToCMap(ch, 2, g, &l, 0); engine->fontDef.fixedPitch = g[0].advance.x == g[1].advance.x; engine->fontDef.fixedPitchComputed = true; }#endif return engine->fontDef.fixedPitch;}/*! Returns the style of the matched window system font. Currently only returns the style hint set in QFont. \sa QFont::styleHint() QFont::StyleHint*/QFont::StyleHint QFontInfo::styleHint() const{ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); return (QFont::StyleHint) engine->fontDef.styleHint;}/*! Returns true if the font is a raw mode font; otherwise returns false. If it is a raw mode font, all other functions in QFontInfo will return the same values set in the QFont, regardless of the font actually used. \sa QFont::rawMode()*/bool QFontInfo::rawMode() const{ return d->rawMode;}/*! Returns true if the matched window system font is exactly the same as the one specified by the font; otherwise returns false. \sa QFont::exactMatch()*/bool QFontInfo::exactMatch() const{ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); return (d->rawMode ? engine->type() != QFontEngine::Box : d->request.exactMatch(engine->fontDef));}// **********************************************************************// QFontCache// **********************************************************************#ifdef QFONTCACHE_DEBUG// fast timeouts for debuggingstatic const int fast_timeout = 1000; // 1sstatic const int slow_timeout = 5000; // 5s#elsestatic const int fast_timeout = 10000; // 10sstatic const int slow_timeout = 300000; // 5m#endif // QFONTCACHE_DEBUGQFontCache *QFontCache::instance = 0;const uint QFontCache::min_cost = 4*1024; // 4mbQFontCache::QFontCache() : QObject(qApp), total_cost(0), max_cost(min_cost), current_timestamp(0), fast(false), timer_id(-1){ Q_ASSERT(instance == 0); instance = this;}QFontCache::~QFontCache(){ { EngineDataCache::Iterator it = engineDataCache.begin(), end = engineDataCache.end(); while (it != end) { if (it.value()->ref == 0) delete it.value(); else FC_DEBUG("QFontCache::~QFontCache: engineData %p still has refcount %d", it.value(), int(it.value()->ref)); ++it; } } EngineCache::Iterator it = engineCache.begin(), end = engineCache.end(); 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 %d %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; } instance = 0;}void QFontCache::clear(){ { EngineDataCache::Iterator it = engineDataCache.begin(), end = engineDataCache.end(); while (it != end) { 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; } }#else if (data->engine) { data->engine->ref.deref(); data->engine = 0; }#endif ++it; } } 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) { delete it->data; it->data = 0; } } engineCache.clear();}#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_QPF2)void QFontCache::removeEngineForFont(const QByteArray &_fontName){ /* This could be optimized but the code becomes much more complex if we want to handle multi * font engines and it is probably not worth it. Therefore we just clear the entire font cache. */ Q_UNUSED(_fontName); clear();}#endifQFontEngineData *QFontCache::findEngineData(const Key &key) const{ EngineDataCache::ConstIterator it = engineDataCache.find(key), end = engineDataCache.end(); if (it == end) return 0; // found return it.value();}void QFontCache::insertEngineData(const Key &key, QFontEngineData *engineData){ FC_DEBUG("QFontCache: inserting new engine data %p", engineData); engineDataCache.insert(key, engineData); increaseCost(sizeof(QFontEngineData));}QFontEngine *QFontCache::findEngine(const Key &key){ EngineCache::Iterator it = engineCache.find(key), end = engineCache.end(); if (it == end) return 0; // found... update the hitcount and timestamp it.value().hits++; it.value().timestamp = ++current_timestamp; FC_DEBUG("QFontCache: found font engine\n" " %p: timestamp %4u hits %3u ref %2d/%2d, type '%s'", it.value().data, it.value().timestamp, it.value().hits, int(it.value().data->ref), it.value().data->cache_count, it.value().data->name()); return it.value().data;}void QFontCache::insertEngine(const Key &key, QFontEngine *engine){ FC_DEBUG("QFontCache: inserting new engine %p", engine); Engine data(engine); data.timestamp = ++current_timestamp; engineCache.insert(key, data); // only increase the cost if this is the first time we insert the engine if (engine->cache_count == 0) increaseCost(engine->cache_cost); ++engine->cache_count;}void QFontCache::increaseCost(uint cost){ cost = (cost + 512) / 1024; // store cost in kb cost = cost > 0 ? cost : 1; total_cost += cost; FC_DEBUG(" COST: increased %u kb, total_cost %u kb, max_cost %u kb", cost, total_cost, max_cost); if (total_cost > max_cost) { max_cost = total_cost; if (timer_id == -1 || ! fast) { FC_DEBUG(" TIMER: starting fast timer (%d ms)", fast_timeout); if (timer_id != -1) killTimer(timer_id); timer_id = startTimer(fast_timeout); fast = true; } }}void QFontCache::decreaseCost(uint cost){ cost = (cost + 512) / 1024; // cost is stored in kb cost = cost > 0 ? cost : 1; Q_ASSERT(cost <= total_cost); total_cost -= cost; FC_DEBUG(" COST: decreased %u kb, total_cost %u kb, max_cost %u kb", cost, total_cost, max_cost);}#if defined(Q_WS_WIN) || defined (Q_WS_QWS)void QFontCache::cleanupPrinterFonts(){ FC_DEBUG("QFontCache::cleanupPrinterFonts"); { FC_DEBUG(" CLEAN engine data:"); // clean out all unused engine data EngineDataCache::Iterator it = engineDataCache.begin(), end = engineDataCache.end(); while (it != end) { if (it.key().screen == 0) { ++it; 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; } } ++it; } else { EngineDataCache::Iterator rem = it++; decreaseCost(sizeof(QFontEngineData)); FC_DEBUG(" %p", rem.value()); delete rem.value(); engineDataCache.erase(rem); } } } EngineCache::Iterator it = engineCache.begin(), end = engineCache.end(); while(it != end) { if (it.value().data->ref != 0 || it.key().screen == 0) { ++it; continue; } FC_DEBUG(" %p: timestamp %4u hits %2u ref %2d/%2d, type '%s'", it.value().data, it.value().timestamp, it.value().hits, int(it.value().data->ref), it.value().data->cache_count, it.value().data->name()); if (--it.value().data->cache_count == 0) { FC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -