// ### 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;
}
Пример #2
0
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;
}
Пример #3
0
// ### 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;
}
Пример #4
0
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;
        }
    }
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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));
        }
    }