HFONT QFont::handle() const { QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); if (engine->type() == QFontEngine::Multi) engine = static_cast<QFontEngineMulti *>(engine)->engine(0); if (engine->type() == QFontEngine::Win) return static_cast<QFontEngineWin *>(engine)->hfont; return 0; }
Qt::HANDLE QFont::handle() const { QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); if (engine->type() == QFontEngine::Multi) engine = static_cast<QFontEngineMulti *>(engine)->engine(0); if (engine->type() == QFontEngine::XLFD) return static_cast<QFontEngineXLFD *>(engine)->fontStruct()->fid; return 0; }
QString QFont::rawName() const { QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); Q_ASSERT(engine != 0); if (engine->type() == QFontEngine::Multi) engine = static_cast<QFontEngineMulti *>(engine)->engine(0); if (engine->type() == QFontEngine::XLFD) return QString::fromLatin1(engine->name()); return QString(); }
FT_Face QFont::freetypeFace() const { #ifndef QT_NO_FREETYPE QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); if (engine->type() == QFontEngine::Multi) engine = static_cast<QFontEngineMulti *>(engine)->engine(0); if (engine->type() == QFontEngine::Freetype) { const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine); return ft->non_locked_face(); } #endif return 0; }
Qt::HANDLE qt_xft_handle(const QFont &font) { QFontEngine *engine = font.d->engineForScript( QFontPrivate::defaultScript ); if (!engine->type() == QFontEngine::Xft) return 0; return (long)static_cast<QFontEngineXft *>(engine)->font(); }
static QFontEngine *loadEngine(int script, const QFontDef &request, QtFontFamily *family, QtFontFoundry *foundry, QtFontStyle *style, QtFontSize *size) { QFontEngine *engine = loadSingleEngine(script, request, foundry, style, size); //make sure that the db has all fallback families if (engine && engine->type() != QFontEngine::Multi && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol ) { if (family && !family->askedForFallback) { QFont::Style fontStyle = QFont::Style(style->key.style); QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint); if (styleHint == QFont::AnyStyle && request.fixedPitch) styleHint = QFont::TypeWriter; family->fallbackFamilies = fallbackFamilies(family->name,fontStyle,styleHint,QUnicodeTables::Script(script)); family->askedForFallback = true; } QStringList fallbacks = privateDb()->fallbackFamilies; if (family && !family->fallbackFamilies.isEmpty()) fallbacks = family->fallbackFamilies; engine = new QFontEngineMultiQPA(engine, script, fallbacks); // Cache Multi font engine as well in case we got the FT single // font engine when we are actually looking for a Multi one QFontCache::Key key(request, script, 1); QFontCache::instance()->instance()->insertEngine(key, engine); } return engine; }
// Returns an ATSUFonFamilyRef Qt::HANDLE QFont::handle() const { #if 0 QFontEngine *fe = d->engineForScript(QUnicodeTables::Common); if (fe && fe->type() == QFontEngine::Mac) return (Qt::HANDLE)static_cast<QFontEngineMacMulti*>(fe)->fontFamilyRef(); #endif return 0; }
// Returns an ATSUFonFamilyRef Qt::HANDLE QFont::handle() const { #ifdef QT_MAC_USE_COCOA QFontEngine *fe = d->engineForScript(QUnicodeTables::Common); if (fe && fe->type() == QFontEngine::Multi) return (Qt::HANDLE)static_cast<QCoreTextFontEngineMulti*>(fe)->macFontID(); #endif return 0; }
void QGLContext::generateFontDisplayLists( const QFont & fnt, int listBase ) { QFont f(fnt); QFontEngine *engine = f.d->engineForScript(QFont::Latin); #ifndef QT_NO_XFTFREETYPE if(engine->type() == QFontEngine::Xft) { qgl_use_font((QFontEngineXft *) engine, 0, 256, listBase); return; } #endif // glXUseXFont() only works with XLFD font structures and a few GL // drivers crash if 0 is passed as the font handle f.setStyleStrategy(QFont::OpenGLCompatible); if (f.handle() && (engine->type() == QFontEngine::XLFD || engine->type() == QFontEngine::LatinXLFD)) { glXUseXFont((Font) f.handle(), 0, 256, listBase); } }
void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase) { QFont f(fnt); QFontEngine *engine = f.d->engineForScript(QUnicodeTables::Common); if (engine->type() == QFontEngine::Multi) engine = static_cast<QFontEngineMulti *>(engine)->engine(0); #ifndef QT_NO_FONTCONFIG if(engine->type() == QFontEngine::Freetype) { qgl_use_font(static_cast<QFontEngineFT *>(engine), 0, 256, listBase); return; } #endif // glXUseXFont() only works with XLFD font structures and a few GL // drivers crash if 0 is passed as the font handle f.setStyleStrategy(QFont::OpenGLCompatible); if (f.handle() && engine->type() == QFontEngine::XLFD) glXUseXFont(static_cast<Font>(f.handle()), 0, 256, listBase); }
QByteArray QPF::generate(const QFont &font, int options, const QList<CharacterRange> &ranges, QString *originalFontFile) { QTextEngine engine("Test", font); engine.itemize(); engine.shape(0); QFontEngine *fontEngine = engine.fontEngine(engine.layoutData->items[0]); if (fontEngine->type() == QFontEngine::Multi) fontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(0); if (originalFontFile) *originalFontFile = QFile::decodeName(fontEngine->faceId().filename); return generate(fontEngine, options, ranges); }
/*! Returns the window system handle to the font, for low-level access. Using this function is \e not portable. */ Qt::HANDLE QFont::handle() const { QFontEngine *engine = d->engineForScript( QFontPrivate::defaultScript ); #ifdef QT_CHECK_STATE Q_ASSERT( engine != 0 ); #endif // QT_CHECK_STATE switch ( engine->type() ) { case QFontEngine::XLFD: return ((QFontEngineXLFD *) engine)->handle(); case QFontEngine::LatinXLFD: return ((QFontEngineLatinXLFD *) engine)->handle(); default: break; } return 0; }
/*! Returns an ATSUFontID */ quint32 QFont::macFontID() const // ### need 64-bit version { #ifdef QT_MAC_USE_COCOA return 0; #elif 1 QFontEngine *fe = d->engineForScript(QUnicodeTables::Common); if (fe && fe->type() == QFontEngine::Multi) return static_cast<QFontEngineMacMulti*>(fe)->macFontID(); #else Str255 name; if(FMGetFontFamilyName((FMFontFamily)((UInt32)handle()), name) == noErr) { short fnum; GetFNum(name, &fnum); return fnum; } #endif return 0; }
/*! Fetches the physical representation based on a \a font query. The physical font returned is the font that will be preferred by Qt in order to display text in the selected \a writingSystem. \warning This function is potentially expensive and should not be called in performance sensitive code. */ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem) { QRawFont rawFont; QFontPrivate *font_d = QFontPrivate::get(font); int script = qt_script_for_writing_system(writingSystem); QFontEngine *fe = font_d->engineForScript(script); if (fe != 0 && fe->type() == QFontEngine::Multi) { QFontEngineMulti *multiEngine = static_cast<QFontEngineMulti *>(fe); fe = multiEngine->engine(0); Q_ASSERT(fe); } if (fe != 0) { rawFont.d.data()->setFontEngine(fe); rawFont.d.data()->hintingPreference = font.hintingPreference(); } return rawFont; }
/*! \internal Returns a QFontEngine for the specified \a script that matches the QFontDef \e request member variable. */ void QFontPrivate::load( QFont::Script script ) { // NOTE: the X11 and Windows implementations of this function are // identical... if you change one, change both. #ifdef QT_CHECK_STATE // sanity checks if (!QFontCache::instance) qWarning("Must construct a QApplication before a QFont"); Q_ASSERT( script >= 0 && script < QFont::LastPrivateScript ); #endif // QT_CHECK_STATE QFontDef req = request; req.pixelSize = qRound(pixelSize(req, paintdevice, screen)); req.pointSize = 0; if ( ! engineData ) { QFontCache::Key key( req, QFont::NoScript, screen, paintdevice ); // look for the requested font in the engine data cache engineData = QFontCache::instance->findEngineData( key ); if ( ! engineData ) { // create a new one engineData = new QFontEngineData; QFontCache::instance->insertEngineData( key, engineData ); } else { engineData->ref(); } } // the cached engineData could have already loaded the engine we want if ( engineData->engines[script] ) return; // load the font QFontEngine *engine = 0; // double scale = 1.0; // ### TODO: fix the scale calculations // list of families to try QStringList family_list; if (!req.family.isEmpty()) { family_list = QStringList::split( ',', req.family ); // append the substitute list for each family in family_list QStringList subs_list; QStringList::ConstIterator it = family_list.begin(), end = family_list.end(); for ( ; it != end; ++it ) subs_list += QFont::substitutes( *it ); family_list += subs_list; #ifndef QT_XFT2 // with Xft2, we want to use fontconfig to determine better fallbacks, // otherwise we might run into trouble with default fonts as "serif" // append the default fallback font for the specified script QString fallback = qt_fallback_font_family( script ); if ( ! fallback.isEmpty() && ! family_list.contains( fallback ) ) family_list << fallback; // add the default family QString defaultFamily = QApplication::font().family(); if ( ! family_list.contains( defaultFamily ) ) family_list << defaultFamily; // add QFont::defaultFamily() to the list, for compatibility with // previous versions family_list << QApplication::font().defaultFamily(); #endif // QT_XFT2 } // null family means find the first font matching the specified script family_list << QString::null; QStringList::ConstIterator it = family_list.begin(), end = family_list.end(); for ( ; ! engine && it != end; ++it ) { req.family = *it; engine = QFontDatabase::findFont( script, this, req ); if ( engine ) { if ( engine->type() != QFontEngine::Box ) break; if ( ! req.family.isEmpty() ) engine = 0; continue; } } engine->ref(); engineData->engines[script] = engine; }
void QTextEngine::shapeTextMac(int item) const { QScriptItem &si = layoutData->items[item]; si.glyph_data_offset = layoutData->used; QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading); if (font->type() != QFontEngine::Multi) { shapeTextWithHarfbuzz(item); return; } #ifndef QT_MAC_USE_COCOA QFontEngineMacMulti *fe = static_cast<QFontEngineMacMulti *>(font); #else QCoreTextFontEngineMulti *fe = static_cast<QCoreTextFontEngineMulti *>(font); #endif QTextEngine::ShaperFlags flags; if (si.analysis.bidiLevel % 2) flags |= RightToLeft; if (option.useDesignMetrics()) flags |= DesignMetrics; attributes(); // pre-initialize char attributes const int len = length(item); int num_glyphs = length(item); const QChar *str = layoutData->string.unicode() + si.position; ushort upperCased[256]; if (si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase || si.analysis.flags == QScriptAnalysis::Lowercase) { ushort *uc = upperCased; if (len > 256) uc = new ushort[len]; for (int i = 0; i < len; ++i) { if(si.analysis.flags == QScriptAnalysis::Lowercase) uc[i] = str[i].toLower().unicode(); else uc[i] = str[i].toUpper().unicode(); } str = reinterpret_cast<const QChar *>(uc); } ensureSpace(num_glyphs); num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used; QGlyphLayout g = availableGlyphs(&si); g.numGlyphs = num_glyphs; unsigned short *log_clusters = logClusters(&si); bool stringToCMapFailed = false; if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) { ensureSpace(num_glyphs); stringToCMapFailed = fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes()); } if (!stringToCMapFailed) { heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs); si.num_glyphs = num_glyphs; layoutData->used += si.num_glyphs; QGlyphLayout g = shapedGlyphs(&si); if (si.analysis.script == QUnicodeTables::Arabic) { QVarLengthArray<QArabicProperties> props(len + 2); QArabicProperties *properties = props.data(); int f = si.position; int l = len; if (f > 0) { --f; ++l; ++properties; } if (f + l < layoutData->string.length()) { ++l; } qt_getArabicProperties((const unsigned short *)(layoutData->string.unicode()+f), l, props.data()); unsigned short *log_clusters = logClusters(&si); for (int i = 0; i < len; ++i) { int gpos = log_clusters[i]; g.attributes[gpos].justification = properties[i].justification; } } } const ushort *uc = reinterpret_cast<const ushort *>(str); if ((si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase || si.analysis.flags == QScriptAnalysis::Lowercase) && uc != upperCased) delete [] uc; }
void QFontDatabase::load(const QFontPrivate *d, int script) { // sanity checks if(!QFontCache::instance) qWarning("QFont: Must construct a QApplication before a QFont"); Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount); Q_UNUSED(script); QFontDef req = d->request; req.pixelSize = qt_mac_pixelsize(req, d->dpi); // set the point size to 0 to get better caching req.pointSize = 0; QFontCache::Key key = QFontCache::Key(req, QUnicodeTables::Common, d->screen); if(!(d->engineData = QFontCache::instance->findEngineData(key))) { d->engineData = new QFontEngineData; QFontCache::instance->insertEngineData(key, d->engineData); } else { d->engineData->ref.ref(); } if(d->engineData->engine) // already loaded return; // set it to the actual pointsize, so QFontInfo will do the right thing req.pointSize = qRound(qt_mac_pointsize(d->request, d->dpi)); QFontEngine *e = QFontCache::instance->findEngine(key); if(!e && qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) { e = new QTestFontEngine(req.pixelSize); e->fontDef = req; } if(e) { Q_ASSERT(e->type() == QFontEngine::Multi || e->type() == QFontEngine::TestFontEngine); e->ref.ref(); d->engineData->engine = e; return; // the font info and fontdef should already be filled } //find the font QStringList family_list = req.family.split(QLatin1Char(',')); // append the substitute list for each family in family_list { QStringList subs_list; for(QStringList::ConstIterator it = family_list.begin(); it != family_list.end(); ++it) subs_list += QFont::substitutes(*it); family_list += subs_list; } const char *stylehint = styleHint(req); if (stylehint) family_list << QLatin1String(stylehint); // add QFont::defaultFamily() to the list, for compatibility with // previous versions family_list << QApplication::font().defaultFamily(); ATSFontFamilyRef familyRef = 0; ATSFontRef fontRef = 0; QFontDatabasePrivate *db = privateDb(); if (!db->count) initializeDb(); for(int i = 0; i < family_list.size(); ++i) { for (int k = 0; k < db->count; ++k) { if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) { QByteArray family_name = db->families[k]->name.toUtf8(); familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); if (familyRef) { fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault); goto FamilyFound; } } } } FamilyFound: //fill in the engine's font definition QFontDef fontDef = d->request; //copy.. if(fontDef.pointSize < 0) fontDef.pointSize = qt_mac_pointsize(fontDef, d->dpi); else fontDef.pixelSize = qt_mac_pixelsize(fontDef, d->dpi); #if 0 ItemCount name_count; if(ATSUCountFontNames(fontID, &name_count) == noErr && name_count) { ItemCount actualName_size; if(ATSUGetIndFontName(fontID, 0, 0, 0, &actualName_size, 0, 0, 0, 0) == noErr && actualName_size) { QByteArray actualName(actualName_size); if(ATSUGetIndFontName(fontID, 0, actualName_size, actualName.data(), &actualName_size, 0, 0, 0, 0) == noErr && actualName_size) fontDef.family = QString::fromUtf8(actualName); } } #else { QCFString actualName; if(ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr) fontDef.family = actualName; } #endif QFontEngine *engine = new QFontEngineMacMulti(familyRef, fontRef, fontDef, d->kerning); d->engineData->engine = engine; engine->ref.ref(); //a ref for the engineData->engine QFontCache::instance->insertEngine(key, engine); }
/*! \internal */ QFontEngine * QFontDatabase::findFont(int script, const QFontPrivate *fp, const QFontDef &request, bool multi) { QMutexLocker locker(fontDatabaseMutex()); const int force_encoding_id = -1; if (!privateDb()->count) initializeDb(); QFontEngine *engine; QFontCache::Key key(request, script, multi ? 1 : 0); engine = QFontCache::instance()->findEngine(key); if (engine) { FM_DEBUG("Cache hit level 1"); return engine; } QString family_name, foundry_name; parseFontName(request.family, foundry_name, family_name); if (qt_enable_test_font && request.family == QLatin1String("__Qt__Box__Engine__")) { engine =new QTestFontEngine(request.pixelSize); engine->fontDef = request; } QtFontDesc desc; match(script, request, family_name, foundry_name, force_encoding_id, &desc); if (desc.family != 0 && desc.foundry != 0 && desc.style != 0) { engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size); } else { FM_DEBUG(" NO MATCH FOUND\n"); } if (engine && engine->type() != QFontEngine::TestFontEngine) { initFontDef(desc, request, &engine->fontDef); if (fp) { QFontDef def = request; if (def.family.isEmpty()) { def.family = fp->request.family; def.family = def.family.left(def.family.indexOf(QLatin1Char(','))); } } } if (!engine) { if (!request.family.isEmpty()) { QStringList fallbacks = fallbackFamilies(request.family,QFont::Style(request.style),QFont::StyleHint(request.styleHint),QUnicodeTables::Script(script)); for (int i = 0; !engine && i < fallbacks.size(); i++) { QFontDef def = request; def.family = fallbacks.at(i); QFontCache::Key key(def, script, multi ? 1 : 0); engine = QFontCache::instance()->findEngine(key); if (!engine) { QtFontDesc desc; match(script, def, def.family, QLatin1String(""), 0, &desc); if (desc.family == 0 && desc.foundry == 0 && desc.style == 0) { continue; } engine = loadEngine(script, def, desc.family, desc.foundry, desc.style, desc.size); if (engine) { initFontDef(desc, def, &engine->fontDef); } } } } if (!engine) engine = new QFontEngineBox(request.pixelSize); FM_DEBUG("returning box engine"); } if (fp && fp->dpi > 0) { engine->fontDef.pointSize = qreal(double((engine->fontDef.pixelSize * 72) / fp->dpi)); } else { engine->fontDef.pointSize = request.pointSize; } return engine; }
void QFontDatabase::load(const QFontPrivate *d, int script) { QFontDef req = d->request; if (req.pixelSize == -1) { req.pixelSize = floor(((req.pointSize * d->dpi) / 72) * 100 + 0.5) / 100; req.pixelSize = qRound(req.pixelSize); } if (req.pointSize < 0) req.pointSize = req.pixelSize*72.0/d->dpi; if (req.weight == 0) req.weight = QFont::Normal; if (req.stretch == 0) req.stretch = 100; QFontCache::Key key(req, script); if (!d->engineData) getEngineData(d, key); // the cached engineData could have already loaded the engine we want if (d->engineData->engines[script]) return; QFontEngine *fe = QFontCache::instance()->findEngine(key); // list of families to try QStringList family_list; if (!req.family.isEmpty()) { family_list = familyList(req); // add the default family QString defaultFamily = QApplication::font().family(); if (! family_list.contains(defaultFamily)) family_list << defaultFamily; } // null family means find the first font matching the specified script family_list << QString(); QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd(); for (; !fe && it != end; ++it) { req.family = *it; fe = QFontDatabase::findFont(script, d, req); if (fe && (fe->type()==QFontEngine::Box) && !req.family.isEmpty()) fe = 0; } if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) { for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) { if (!d->engineData->engines[i]) { d->engineData->engines[i] = fe; fe->ref.ref(); } } } else { d->engineData->engines[script] = fe; fe->ref.ref(); } }