Example #1
0
static void initWritingSystems(QtFontFamily *family, ATSFontRef atsFont)
{
    ByteCount length = 0;
    if (ATSFontGetTable(atsFont, MAKE_TAG('O', 'S', '/', '2'), 0, 0, 0, &length) != noErr)
        return;
    QVarLengthArray<uchar> os2Table(length);
    if (length < 86
        || ATSFontGetTable(atsFont, MAKE_TAG('O', 'S', '/', '2'), 0, length, os2Table.data(), &length) != noErr)
        return;

    quint32 unicodeRange[4] = {
        qFromBigEndian<quint32>(os2Table.data() + 42),
        qFromBigEndian<quint32>(os2Table.data() + 46),
        qFromBigEndian<quint32>(os2Table.data() + 50),
        qFromBigEndian<quint32>(os2Table.data() + 54)
    };
    quint32 codePageRange[2] = { qFromBigEndian<quint32>(os2Table.data() + 78), qFromBigEndian<quint32>(os2Table.data() + 82) };
    QList<QFontDatabase::WritingSystem> systems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
#if 0
    QCFString name;
    ATSFontGetName(atsFont, kATSOptionFlagsDefault, &name);
    qDebug() << systems.count() << "writing systems for" << QString(name);
qDebug() << "first char" << hex << unicodeRange[0];
    for (int i = 0; i < systems.count(); ++i)
        qDebug() << QFontDatabase::writingSystemName(systems.at(i));
#endif
    for (int i = 0; i < systems.count(); ++i)
        family->writingSystems[systems.at(i)] = QtFontFamily::Supported;
}
Example #2
0
static QByteArray getWritingSystems(QFontEngine *fontEngine)
{
    QByteArray os2Table = fontEngine->getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
    if (os2Table.isEmpty())
        return QByteArray();

    const uchar *data = reinterpret_cast<const uchar *>(os2Table.constData());

    quint32 unicodeRange[4] = {
        qFromBigEndian<quint32>(data + 42),
        qFromBigEndian<quint32>(data + 46),
        qFromBigEndian<quint32>(data + 50),
        qFromBigEndian<quint32>(data + 54)
    };
    quint32 codePageRange[2] = { qFromBigEndian<quint32>(data + 78), qFromBigEndian<quint32>(data + 82) };
    QList<QFontDatabase::WritingSystem> systems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);

    QByteArray bitField((QFontDatabase::WritingSystemsCount + 7) / 8, 0);

    for (int i = 0; i < systems.count(); ++i) {
        int bitPos = systems.at(i);
        bitField[bitPos / 8] = bitField.at(bitPos / 8) | (1 << (bitPos % 8));
    }

    return bitField;
}
Example #3
0
QStringList QBasicUnixFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file)
{
    extern FT_Library qt_getFreetype();
    FT_Library library = qt_getFreetype();

    int index = 0;
    int numFaces = 0;
    QStringList families;
    do {
        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 failed with index" << index << ":" << hex << error;
            break;
        }
        numFaces = face->num_faces;

        QFont::Weight weight = QFont::Normal;

        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);
        }

        QString family = QString::fromAscii(face->family_name);
        if(family.isEmpty())
            family = QString::fromLocal8Bit(file);
        FontFile *fontFile = new FontFile;
        fontFile->fileName = file;
        fontFile->indexValue = index;

        QFont::Stretch stretch = QFont::Unstretched;
        registerFont(family,"",weight,style,stretch,true,true,0,writingSystems,fontFile);

        families.append(family);

        FT_Done_Face(face);
        ++index;
    } while (index < numFaces);
    return families;
}
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
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;
        if (weight < 400)
            styleKey.weight = QFont::Light;
        else if (weight < 600)
            styleKey.weight = QFont::Normal;
        else if (weight < 700)
            styleKey.weight = QFont::DemiBold;
        else if (weight < 800)
            styleKey.weight = QFont::Bold;
        else
            styleKey.weight = QFont::Black;

        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, 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, 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, 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, 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 = determineWritingSystemsFromTrueTypeBits(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;
        }
    }
}