// ### maybe move to qapplication_win QFont qt_LOGFONTtoQFont(LOGFONT& lf, bool /*scale*/) { QString family = QString::fromWCharArray(lf.lfFaceName); QFont qf(family); qf.setItalic(lf.lfItalic); if (lf.lfWeight != FW_DONTCARE) qf.setWeight(weightFromInteger(lf.lfWeight)); int lfh = qAbs(lf.lfHeight); qf.setPointSizeF(lfh * 72.0 / GetDeviceCaps(shared_dc(),LOGPIXELSY)); qf.setUnderline(false); qf.setOverline(false); qf.setStrikeOut(false); return qf; }
QFont QWindowsFontDatabaseFT::LOGFONT_to_QFont(const LOGFONT& logFont, int verticalDPI_In) { if (verticalDPI_In <= 0) verticalDPI_In = verticalDPI(); QFont qFont(QString::fromWCharArray(logFont.lfFaceName)); qFont.setItalic(logFont.lfItalic); if (logFont.lfWeight != FW_DONTCARE) qFont.setWeight(weightFromInteger(logFont.lfWeight)); const qreal logFontHeight = qAbs(logFont.lfHeight); qFont.setPointSizeF(logFontHeight * 72.0 / qreal(verticalDPI_In)); qFont.setUnderline(logFont.lfUnderline); qFont.setOverline(false); qFont.setStrikeOut(logFont.lfStrikeOut); return qFont; }
// ### maybe move to qapplication_win QFont qt_LOGFONTtoQFont(LOGFONT& lf, bool /*scale*/) { QString family = QString::fromWCharArray(lf.lfFaceName); #ifdef QT_ENABLE_FREETYPE_FOR_WIN // Substitute font by myself. // Windows return font family name which should be substituted from SystemParametersInfo(). // If we use GDI's font engine, Windows substitute font family. // If we use FreeType, FreeType don't do that, and we need to substitute font by myself. //std::cout << "family: " << family.toUtf8().data() << std::endl; { HKEY key; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes"), 0, KEY_READ, &key) == ERROR_SUCCESS) { int i = 0; TCHAR buff[MAX_PATH]; DWORD size = sizeof(buff) / sizeof(buff[0]); BYTE data[1024*4]; DWORD dataSize = sizeof(data)/sizeof(data[0]); DWORD type; while (RegEnumValue(key, i++, buff, &size, NULL, &type, data, &dataSize) == ERROR_SUCCESS) { QString subFamily = QString::fromWCharArray(buff); if (family.compare(subFamily) == 0) { if (type == REG_SZ) family = QString::fromWCharArray((WCHAR *)data); break; } size = sizeof(buff) / sizeof(buff[0]); dataSize = sizeof(data)/sizeof(data[0]); } } } //std::cout << "use family: " << family.toUtf8().data() << std::endl; #endif QFont qf(family); qf.setItalic(lf.lfItalic); if (lf.lfWeight != FW_DONTCARE) qf.setWeight(weightFromInteger(lf.lfWeight)); int lfh = qAbs(lf.lfHeight); qf.setPointSizeF(lfh * 72.0 / GetDeviceCaps(shared_dc(),LOGPIXELSY)); qf.setUnderline(false); qf.setOverline(false); qf.setStrikeOut(false); return qf; }
static void addFontToDatabase(QString familyName, const QString &scriptName, TEXTMETRIC *textmetric, const FONTSIGNATURE *signature, int type) { const int script = -1; const QString foundryName; Q_UNUSED(script); bool italic = false; int weight; bool fixed; bool ttf; bool scalable; int size; // QString escript = QString::fromWCharArray(f->elfScript); // qDebug("script=%s", escript.latin1()); NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; italic = tm->tmItalic; weight = tm->tmWeight; // the "@family" fonts are just the same as "family". Ignore them. if (familyName[0] != QLatin1Char('@') && !familyName.startsWith(QLatin1String("WST_"))) { QtFontStyle::Key styleKey; styleKey.style = italic ? QFont::StyleItalic : QFont::StyleNormal; styleKey.weight = weightFromInteger(weight); QtFontFamily *family = privateDb()->family(familyName, true); if(ttf && localizedName(familyName) && family->english_name.isEmpty()) family->english_name = getEnglishName(familyName); QtFontFoundry *foundry = family->foundry(foundryName, true); QtFontStyle *style = foundry->style(styleKey, QString(), true); style->smoothScalable = scalable; style->pixelSize( size, TRUE); // add fonts windows can generate for us: if (styleKey.weight <= QFont::DemiBold) { QtFontStyle::Key key(styleKey); key.weight = QFont::Bold; QtFontStyle *style = foundry->style(key, QString(), true); style->smoothScalable = scalable; style->pixelSize( size, TRUE); } if (styleKey.style != QFont::StyleItalic) { QtFontStyle::Key key(styleKey); key.style = QFont::StyleItalic; QtFontStyle *style = foundry->style(key, QString(), true); style->smoothScalable = scalable; style->pixelSize( size, TRUE); } if (styleKey.weight <= QFont::DemiBold && styleKey.style != QFont::StyleItalic) { QtFontStyle::Key key(styleKey); key.weight = QFont::Bold; key.style = QFont::StyleItalic; QtFontStyle *style = foundry->style(key, QString(), true); style->smoothScalable = scalable; style->pixelSize( size, TRUE); } family->fixedPitch = fixed; if (!family->writingSystemCheck && type & TRUETYPE_FONTTYPE) { quint32 unicodeRange[4] = { signature->fsUsb[0], signature->fsUsb[1], signature->fsUsb[2], signature->fsUsb[3] }; #ifdef Q_WS_WINCE if (signature->fsUsb[0] == 0) { // If the unicode ranges bit mask is zero then // EnumFontFamiliesEx failed to determine it properly. // In this case we just pretend that the font supports all languages. unicodeRange[0] = 0xbfffffff; // second most significant bit must be zero unicodeRange[1] = 0xffffffff; unicodeRange[2] = 0xffffffff; unicodeRange[3] = 0xffffffff; } #endif quint32 codePageRange[2] = { signature->fsCsb[0], signature->fsCsb[1] }; QList<QFontDatabase::WritingSystem> systems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange); for (int i = 0; i < systems.count(); ++i) { QFontDatabase::WritingSystem writingSystem = systems.at(i); // ### Hack to work around problem with Thai text on Windows 7. Segoe UI contains // the symbol for Baht, and Windows thus reports that it supports the Thai script. // Since it's the default UI font on this platform, most widgets will be unable to // display Thai text by default. As a temporary work around, we special case Segoe UI // and remove the Thai script from its list of supported writing systems. if (writingSystem != QFontDatabase::Thai || familyName != QLatin1String("Segoe UI")) family->writingSystems[writingSystem] = QtFontFamily::Supported; } } else if (!family->writingSystemCheck) { //qDebug("family='%s' script=%s", family->name.latin1(), script.latin1()); if (scriptName == QLatin1String("Western") || scriptName == QLatin1String("Baltic") || scriptName == QLatin1String("Central European") || scriptName == QLatin1String("Turkish") || scriptName == QLatin1String("Vietnamese")) family->writingSystems[QFontDatabase::Latin] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Thai")) family->writingSystems[QFontDatabase::Thai] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Symbol") || scriptName == QLatin1String("Other")) family->writingSystems[QFontDatabase::Symbol] = QtFontFamily::Supported; else if (scriptName == QLatin1String("OEM/Dos")) family->writingSystems[QFontDatabase::Latin] = QtFontFamily::Supported; else if (scriptName == QLatin1String("CHINESE_GB2312")) family->writingSystems[QFontDatabase::SimplifiedChinese] = QtFontFamily::Supported; else if (scriptName == QLatin1String("CHINESE_BIG5")) family->writingSystems[QFontDatabase::TraditionalChinese] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Cyrillic")) family->writingSystems[QFontDatabase::Cyrillic] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Hangul")) family->writingSystems[QFontDatabase::Korean] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Hebrew")) family->writingSystems[QFontDatabase::Hebrew] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Greek")) family->writingSystems[QFontDatabase::Greek] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Japanese")) family->writingSystems[QFontDatabase::Japanese] = QtFontFamily::Supported; else if (scriptName == QLatin1String("Arabic")) family->writingSystems[QFontDatabase::Arabic] = QtFontFamily::Supported; } } }
static bool addFontToDatabase(QString familyName, const QString &scriptName, const TEXTMETRIC *textmetric, const FONTSIGNATURE *signature, int type) { // the "@family" fonts are just the same as "family". Ignore them. if (familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QStringLiteral("WST_"))) return false; const int separatorPos = familyName.indexOf("::"); const QString faceName = separatorPos != -1 ? familyName.left(separatorPos) : familyName; const QString fullName = separatorPos != -1 ? familyName.mid(separatorPos + 2) : QString(); static const int SMOOTH_SCALABLE = 0xffff; const QString foundryName; // No such concept. const NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; const bool fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); const bool ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); const bool scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); const int size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; const QFont::Style style = tm->tmItalic ? QFont::StyleItalic : QFont::StyleNormal; const bool antialias = false; const QFont::Weight weight = weightFromInteger(tm->tmWeight); const QFont::Stretch stretch = QFont::Unstretched; if (QWindowsContext::verboseFonts > 2) { QDebug nospace = qDebug().nospace(); nospace << __FUNCTION__ << faceName << fullName << scriptName << "TTF=" << ttf; if (type & DEVICE_FONTTYPE) nospace << " DEVICE"; if (type & RASTER_FONTTYPE) nospace << " RASTER"; if (type & TRUETYPE_FONTTYPE) nospace << " TRUETYPE"; nospace << " scalable=" << scalable << " Size=" << size << " Style=" << style << " Weight=" << weight << " stretch=" << stretch; } /* Fixme: omitted for the moment if(ttf && localizedName(faceName) && family->english_name.isEmpty()) family->english_name = getEnglishName(faceName); */ QSupportedWritingSystems writingSystems; if (type & TRUETYPE_FONTTYPE) { quint32 unicodeRange[4] = { signature->fsUsb[0], signature->fsUsb[1], signature->fsUsb[2], signature->fsUsb[3] }; quint32 codePageRange[2] = { signature->fsCsb[0], signature->fsCsb[1] }; writingSystems = QBasicFontDatabase::determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange); // ### Hack to work around problem with Thai text on Windows 7. Segoe UI contains // the symbol for Baht, and Windows thus reports that it supports the Thai script. // Since it's the default UI font on this platform, most widgets will be unable to // display Thai text by default. As a temporary work around, we special case Segoe UI // and remove the Thai script from its list of supported writing systems. if (writingSystems.supported(QFontDatabase::Thai) && faceName == QStringLiteral("Segoe UI")) writingSystems.setSupported(QFontDatabase::Thai, false); } else { const QFontDatabase::WritingSystem ws = writingSystemFromScript(scriptName); if (ws != QFontDatabase::Any) writingSystems.setSupported(ws); } const QSettings fontRegistry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts", QSettings::NativeFormat); QByteArray value; int index = 0; foreach (const QString &key, fontRegistry.allKeys()) { QString realKey = key; realKey = realKey.replace("(TrueType)", ""); realKey = realKey.trimmed(); QStringList fonts = realKey.split('&'); for (int i = 0; i < fonts.length(); ++i) { const QString font = fonts[i].trimmed(); if (font == faceName || (faceName != fullName && fullName == font)) { value = fontRegistry.value(key).toByteArray(); index = i; break; } } if (!value.isEmpty()) break; } if (value.isEmpty()) return false; if (!QDir::isAbsolutePath(value)) value = qgetenv("windir") + "\\Fonts\\" + value; // Pointer is deleted in QBasicFontDatabase::releaseHandle(void *handle) FontFile *fontFile = new FontFile; fontFile->fileName = value; fontFile->indexValue = index; QPlatformFontDatabase::registerFont(faceName, foundryName, weight, style, stretch, antialias, scalable, size, fixed, writingSystems, fontFile); // add fonts windows can generate for us: if (weight <= QFont::DemiBold) QPlatformFontDatabase::registerFont(faceName, foundryName, QFont::Bold, style, stretch, antialias, scalable, size, fixed, writingSystems, fontFile); if (style != QFont::StyleItalic) QPlatformFontDatabase::registerFont(faceName, foundryName, weight, QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, fontFile); if (weight <= QFont::DemiBold && style != QFont::StyleItalic) QPlatformFontDatabase::registerFont(faceName, foundryName, QFont::Bold, QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, fontFile); return true; }
QStringList QWebOSFontDatabase::addTTFile(QWebOSFontDatabase* qwfdb, const QByteArray &fontData, const QByteArray &file, const QStringList &additionalFamilies) { if (qwfdb && qwfdb->m_debug) qDebug("addTTFile(fontData.size() = %d, file = '%s', additionalFamilies = '%s')", fontData.size(), qPrintable(file), qPrintable(additionalFamilies.join(","))); extern FT_Library qt_getFreetype(); FT_Library library = qt_getFreetype(); int numFaces = 0; int index = 0; QStringList families; FT_Face face; FT_Error error; if (!fontData.isEmpty()) { error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face); } else { error = FT_New_Face(library, file.constData(), index, &face); } if (error != FT_Err_Ok) { qDebug() << "FT_New_Face for " << qPrintable(file) << " failed with index" << index << ":" << hex << error; return families; } numFaces = face->num_faces; if (numFaces > 1) { qWarning() << "numFaces for " << qPrintable(file) << " is " << numFaces << ", expected just 1"; } QFont::Weight weight = QFont::Normal; QFont::Stretch stretch = QFont::Unstretched; QFont::Style style = QFont::StyleNormal; if (face->style_flags & FT_STYLE_FLAG_ITALIC) style = QFont::StyleItalic; if (face->style_flags & FT_STYLE_FLAG_BOLD) weight = QFont::Bold; QSupportedWritingSystems writingSystems; // detect symbol fonts for (int i = 0; i < face->num_charmaps; ++i) { FT_CharMap cm = face->charmaps[i]; if (cm->encoding == ft_encoding_adobe_custom || cm->encoding == ft_encoding_symbol) { writingSystems.setSupported(QFontDatabase::Symbol); break; } } TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2); if (os2) { quint32 unicodeRange[4] = { os2->ulUnicodeRange1, os2->ulUnicodeRange2, os2->ulUnicodeRange3, os2->ulUnicodeRange4 }; quint32 codePageRange[2] = { os2->ulCodePageRange1, os2->ulCodePageRange2 }; writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange); // If the OS2 struct is availabel read the weight from there and convert it // to a QFont::Weight. This fixes OWEBOS-1866 weight = weightFromInteger(os2->usWeightClass); stretch = determineStretchFromTrueTypeWidthClass(os2->usWidthClass); style = determineStyleFromTrueTypeSelection(os2->fsSelection); } QString family = QString::fromAscii(face->family_name); QStringList allFamilies(family); allFamilies << additionalFamilies; for (int i = 0; i < allFamilies.size(); ++i) { FontFile *fontFile = new FontFile; fontFile->fileName = file; fontFile->indexValue = index; fontFile->familyName = allFamilies.at(i); qDebug("registerFont(\"%s\",\"\",%s,%s,%s,true,true,0,\"%s\",fontFile = {fileName = \"%s\", indexValue = %d, familyName = %s})", qPrintable(allFamilies.at(i)), qPrintable(qWeightToQString(weight)), qPrintable(qStyleToQString(style)), qPrintable(qStretchToQString(stretch)), qPrintable(qSupportedWritingSystemsToQString(writingSystems)), qPrintable(fontFile->fileName), fontFile->indexValue, qPrintable(fontFile->familyName)); registerFont(allFamilies.at(i), "", weight, style, stretch, true, true, 0, writingSystems, fontFile); families.append(family); } FT_Done_Face(face); return families; }
static bool addFontToDatabase(QString familyName, const QString &scriptName, const TEXTMETRIC *textmetric, const FONTSIGNATURE *signature, int type) { typedef QPair<QString, QStringList> FontKey; // the "@family" fonts are just the same as "family". Ignore them. if (familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QStringLiteral("WST_"))) return false; const int separatorPos = familyName.indexOf(QStringLiteral("::")); const QString faceName = separatorPos != -1 ? familyName.left(separatorPos) : familyName; const QString fullName = separatorPos != -1 ? familyName.mid(separatorPos + 2) : QString(); static const int SMOOTH_SCALABLE = 0xffff; const QString foundryName; // No such concept. const NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; const bool fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); const bool ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); const bool scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); const int size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; const QFont::Style style = tm->tmItalic ? QFont::StyleItalic : QFont::StyleNormal; const bool antialias = false; const QFont::Weight weight = weightFromInteger(tm->tmWeight); const QFont::Stretch stretch = QFont::Unstretched; #ifndef QT_NO_DEBUG_OUTPUT if (QWindowsContext::verboseFonts > 2) { QDebug nospace = qDebug().nospace(); nospace << __FUNCTION__ << faceName << fullName << scriptName << "TTF=" << ttf; if (type & DEVICE_FONTTYPE) nospace << " DEVICE"; if (type & RASTER_FONTTYPE) nospace << " RASTER"; if (type & TRUETYPE_FONTTYPE) nospace << " TRUETYPE"; nospace << " scalable=" << scalable << " Size=" << size << " Style=" << style << " Weight=" << weight << " stretch=" << stretch; } #endif QString englishName; if (ttf && localizedName(faceName)) englishName = getEnglishName(faceName); QSupportedWritingSystems writingSystems; if (type & TRUETYPE_FONTTYPE) { quint32 unicodeRange[4] = { signature->fsUsb[0], signature->fsUsb[1], signature->fsUsb[2], signature->fsUsb[3] }; quint32 codePageRange[2] = { signature->fsCsb[0], signature->fsCsb[1] }; writingSystems = QBasicFontDatabase::determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange); // ### Hack to work around problem with Thai text on Windows 7. Segoe UI contains // the symbol for Baht, and Windows thus reports that it supports the Thai script. // Since it's the default UI font on this platform, most widgets will be unable to // display Thai text by default. As a temporary work around, we special case Segoe UI // and remove the Thai script from its list of supported writing systems. if (writingSystems.supported(QFontDatabase::Thai) && faceName == QStringLiteral("Segoe UI")) writingSystems.setSupported(QFontDatabase::Thai, false); } else { const QFontDatabase::WritingSystem ws = writingSystemFromScript(scriptName); if (ws != QFontDatabase::Any) writingSystems.setSupported(ws); } #ifndef Q_OS_WINCE const QSettings fontRegistry(QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"), QSettings::NativeFormat); static QVector<FontKey> allFonts; if (allFonts.isEmpty()) { const QStringList allKeys = fontRegistry.allKeys(); allFonts.reserve(allKeys.size()); const QString trueType = QStringLiteral("(TrueType)"); const QRegExp sizeListMatch(QStringLiteral("\\s(\\d+,)+\\d+")); foreach (const QString &key, allKeys) { QString realKey = key; realKey.remove(trueType); realKey.remove(sizeListMatch); QStringList fonts; const QStringList fontNames = realKey.trimmed().split(QLatin1Char('&')); foreach (const QString &fontName, fontNames) fonts.push_back(fontName.trimmed()); allFonts.push_back(FontKey(key, fonts)); } }