⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qfontdatabase_x11.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    int weight_value = FC_WEIGHT_BLACK;    if (request.weight == 0)        weight_value = FC_WEIGHT_MEDIUM;    else if (request.weight < (QFont::Light + QFont::Normal) / 2)        weight_value = FC_WEIGHT_LIGHT;    else if (request.weight < (QFont::Normal + QFont::DemiBold) / 2)        weight_value = FC_WEIGHT_MEDIUM;    else if (request.weight < (QFont::DemiBold + QFont::Bold) / 2)        weight_value = FC_WEIGHT_DEMIBOLD;    else if (request.weight < (QFont::Bold + QFont::Black) / 2)        weight_value = FC_WEIGHT_BOLD;    FcPatternAddInteger(pattern, FC_WEIGHT, weight_value);    int slant_value = FC_SLANT_ROMAN;    if (request.style == QFont::StyleItalic)        slant_value = FC_SLANT_ITALIC;    else if (request.style == QFont::StyleOblique)        slant_value = FC_SLANT_OBLIQUE;    FcPatternAddInteger(pattern, FC_SLANT, slant_value);    double size_value = request.pixelSize;    FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value);    int stretch = request.stretch;    if (!stretch)        stretch = 100;    FcPatternAddInteger(pattern, FC_WIDTH, stretch);    if (QX11Info::appDepth(fp->screen) <= 8) {        // can't do antialiasing on 8bpp        FcPatternAddBool(pattern, FC_ANTIALIAS, false);    } else if (request.styleStrategy & (QFont::PreferAntialias|QFont::NoAntialias)) {        FcPatternAddBool(pattern, FC_ANTIALIAS,                         !(request.styleStrategy & QFont::NoAntialias));    }    if (script != QUnicodeTables::Common) {        Q_ASSERT(script < QUnicodeTables::ScriptCount);        FcLangSet *ls = FcLangSetCreate();        FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);        FcPatternAddLangSet(pattern, FC_LANG, ls);        FcLangSetDestroy(ls);    }}static bool preferScalable(const QFontDef &request){    return request.styleStrategy & (QFont::PreferOutline|QFont::ForceOutline|QFont::PreferQuality|QFont::PreferAntialias);}static FcPattern *getFcPattern(const QFontPrivate *fp, int script, const QFontDef &request){    if (!X11->has_fontconfig)        return 0;    FcPattern *pattern = FcPatternCreate();    if (!pattern)        return 0;    FcValue value;    value.type = FcTypeString;    QtFontDesc desc;    QStringList families_and_foundries = familyList(request);    for (int i = 0; i < families_and_foundries.size(); ++i) {        QString family, foundry;        parseFontName(families_and_foundries.at(i), foundry, family);        if (!family.isEmpty()) {            QByteArray cs = family.toUtf8();            value.u.s = (const FcChar8 *)cs.data();            FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);        }        if (i == 0) {            ::match(script, request, family, foundry, -1, &desc);            if (!foundry.isEmpty()) {                QByteArray cs = foundry.toUtf8();                value.u.s = (const FcChar8 *)cs.data();                FcPatternAddWeak(pattern, FC_FOUNDRY, value, FcTrue);            }        }    }    const char *stylehint = styleHint(request);    if (stylehint) {        value.u.s = (const FcChar8 *)stylehint;        FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);    }    if (!request.ignorePitch) {        char pitch_value = FC_PROPORTIONAL;        if (request.fixedPitch || (desc.family && desc.family->fixedPitch))            pitch_value = FC_MONO;        FcPatternAddInteger(pattern, FC_SPACING, pitch_value);    }    FcPatternAddBool(pattern, FC_OUTLINE, !(request.styleStrategy & QFont::PreferBitmap));    if (::preferScalable(request) || (desc.style && desc.style->smoothScalable))        FcPatternAddBool(pattern, FC_SCALABLE, true);    addPatternProps(pattern, fp, script, request);    FcDefaultSubstitute(pattern);    FcConfigSubstitute(0, pattern, FcMatchPattern);    FcConfigSubstitute(0, pattern, FcMatchFont);    // these should only get added to the pattern _after_ substitution    // append the default fallback font for the specified script    extern QString qt_fallback_font_family(int);    QString fallback = qt_fallback_font_family(script);    if (!fallback.isEmpty()) {        QByteArray cs = fallback.toUtf8();        value.u.s = (const FcChar8 *)cs.data();        FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);    }    // add the default family    QString defaultFamily = QApplication::font().family();    QByteArray cs = defaultFamily.toUtf8();    value.u.s = (const FcChar8 *)cs.data();    FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);    // add QFont::defaultFamily() to the list, for compatibility with    // previous versions    defaultFamily = QApplication::font().defaultFamily();    cs = defaultFamily.toUtf8();    value.u.s = (const FcChar8 *)cs.data();    FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);    // this small hack changes all weak bindings into strong ones    FcPattern *p = FcPatternDuplicate(pattern);    FcPatternDestroy(pattern);    return p;}static void FcFontSetRemove(FcFontSet *fs, int at){    Q_ASSERT(at < fs->nfont);    FcPatternDestroy(fs->fonts[at]);    int len = (--fs->nfont - at) * sizeof(FcPattern *);;    if (len > 0)        memmove(fs->fonts + at, fs->fonts + at + 1, len);}static QFontEngine *loadFc(const QFontPrivate *fp, int script, const QFontDef &request){    FM_DEBUG("===================== loadFc: script=%d family='%s'\n", script, request.family.toLatin1().data());    FcPattern *pattern = getFcPattern(fp, script, request);    FcBool forceScalable = request.styleStrategy & QFont::ForceOutline;#ifdef FONT_MATCH_DEBUG    FM_DEBUG("\n\nfinal FcPattern contains:\n");    FcPatternPrint(pattern);#endif    FcResult result;    FcFontSet *fs = FcFontSort(0, pattern, FcTrue, 0, &result);#ifdef FONT_MATCH_DEBUG    FM_DEBUG("first font in fontset:\n");    FcPatternPrint(fs->fonts[0]);#endif    FcPatternDestroy(pattern);    if (!fs)        return 0;    // remove fonts if they are not scalable (and should be)    if (forceScalable) {        for (int i = 0; i < fs->nfont; ++i) {            FcPattern *font = fs->fonts[i];            FcResult res;            FcBool scalable;            res = FcPatternGetBool(font, FC_SCALABLE, 0, &scalable);            if (res != FcResultMatch || !scalable) {                FcFontSetRemove(fs, i);#ifdef FONT_MATCH_DEBUG                FM_DEBUG("removing pattern:");                FcPatternPrint(font);#endif                --i; // go back one            }        }    }    FM_DEBUG("final pattern contains %d fonts\n", fs->nfont);    QFontEngine *fe = 0;    if (script != QUnicodeTables::Common) {        // load a single font for the script        for (int i = 0; !fe && i < fs->nfont; ++i) {            FcChar8 *fam;            FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &fam);            FM_DEBUG("==== trying %s\n", fam);            // skip font if it doesn't support the language we want            if (specialChars[script]) {                // need to check the charset, as the langset doesn't work for these scripts                FcCharSet *cs;                if (FcPatternGetCharSet(fs->fonts[i], FC_CHARSET, 0, &cs) != FcResultMatch)                    continue;                if (!FcCharSetHasChar(cs, specialChars[script]))                    continue;            } else {                FcLangSet *langSet = 0;                if (FcPatternGetLangSet(fs->fonts[i], FC_LANG, 0, &langSet) != FcResultMatch)                    continue;                if (FcLangSetHasLang(langSet, (const FcChar8*)specialLanguages[script]) != FcLangEqual)                    continue;            }            FM_DEBUG("passes charset test\n");            FcPattern *pattern = FcPatternDuplicate(fs->fonts[i]);            // add properties back in as the font selected from the            // list doesn't contain them.            addPatternProps(pattern, fp, script, request);            FcConfigSubstitute(0, pattern, FcMatchPattern);            FcDefaultSubstitute(pattern);            FcResult res;            FcPattern *match = FcFontMatch(0, pattern, &res);            QFontEngineFT *engine = new QFontEngineFT(match, qt_FcPatternToQFontDef(match, request), fp->screen);            if (engine->invalid()) {                FM_DEBUG("   --> invalid!\n");                delete engine;            } else if (scriptRequiresOpenType(script)) {                QOpenType *ot = engine->openType();                if (!ot || !ot->supportsScript(script)) {                    FM_DEBUG("  OpenType support missing for script\n");                    delete engine;                } else {                    fe = engine;                }            } else {                fe = engine;            }        }        FM_DEBUG("engine for script %d is %s\n", script, fe ? fe->fontDef.family.toLatin1().data(): "(null)");    } else if (fs->nfont) {        // create a multi engine for the fontset fontconfig gave us        FcFontSet *fontSet = FcFontSetCreate();        for (int i = 0; i < fs->nfont; ++i) {            FcPattern *pattern = FcPatternDuplicate(fs->fonts[i]);            // add properties back in as the font selected from the            // list doesn't contain them.            addPatternProps(pattern, fp, script, request);            FcFontSetAdd(fontSet, pattern);        }        fe = new QFontEngineMultiFT(fontSet, fp->screen, request);    }    FcFontSetDestroy(fs);    return fe;}#endif // QT_NO_FONTCONFIGstatic QFontEngine *loadRaw(const QFontPrivate *fp, const QFontDef &request){    Q_ASSERT(fp && fp->rawMode);    QByteArray xlfd = request.family.toLatin1();    FM_DEBUG("Loading XLFD (rawmode) '%s'", xlfd.data());    QFontEngine *fe;    XFontStruct *xfs;    if (!(xfs = XLoadQueryFont(QX11Info::display(), xlfd.data())))        return 0;    fe = new QFontEngineXLFD(xfs, xlfd, 0);    if (! qt_fillFontDef(xfs, &fe->fontDef, fp->dpi) &&        ! qt_fillFontDef(xlfd, &fe->fontDef, fp->dpi))        fe->fontDef = QFontDef();    return fe;}QFontEngine *QFontDatabase::loadXlfd(int screen, int script, const QFontDef &request, int force_encoding_id){    QtFontDesc desc;    FM_DEBUG() << "---> loadXlfd: request is" << request.family;    QStringList families_and_foundries = ::familyList(request);    const char *stylehint = styleHint(request);    if (stylehint)        families_and_foundries << QString::fromLatin1(stylehint);    families_and_foundries << QString();    FM_DEBUG() << "loadXlfd: list is" << families_and_foundries;    for (int i = 0; i < families_and_foundries.size(); ++i) {        QString family, foundry;        ::parseFontName(families_and_foundries.at(i), foundry, family);        FM_DEBUG("loadXlfd: >>>>>>>>>>>>>>trying to match '%s' encoding=%d", family.toLatin1().data(), force_encoding_id);        ::match(script, request, family, foundry, force_encoding_id, &desc);        if (desc.family)            break;    }    QFontEngine *fe = 0;    if (force_encoding_id != -1 || script != QUnicodeTables::Common) {        if (desc.family) {            int px = desc.size->pixelSize;            if (desc.style->smoothScalable && px == SMOOTH_SCALABLE)                px = request.pixelSize;            else if (desc.style->bitmapScalable && px == 0)                px = request.pixelSize;            QByteArray xlfd("-");            xlfd += desc.foundry->name.isEmpty() ? QByteArray("*") : desc.foundry->name.toLatin1();            xlfd += "-";            xlfd += desc.family->name.isEmpty() ? QByteArray("*") : desc.family->name.toLatin1();            xlfd += "-";            xlfd += desc.style->weightName ? desc.style->weightName : "*";            xlfd += "-";            xlfd += (desc.style->key.style == QFont::StyleItalic                     ? "i"                     : (desc.style->key.style == QFont::StyleOblique ? "o" : "r"));            xlfd += "-";            xlfd += desc.style->setwidthName ? desc.style->setwidthName : "*";            // ### handle add-style            xlfd += "-*-";            xlfd += QByteArray::number(px);            xlfd += "-";            xlfd += QByteArray::number(desc.encoding->xpoint);            xlfd += "-";            xlfd += QByteArray::number(desc.encoding->xres);            xlfd += "-";            xlfd += QByteArray::number(desc.encoding->yres);            xlfd += "-";            xlfd += desc.encoding->pitch;            xlfd += "-";            xlfd += QByteArray::number(desc.encoding->avgwidth);            xlfd += "-";            xlfd += xlfd_for_id(desc.encoding->encoding);            FM_DEBUG("    using XLFD: %s\n", xlfd.data());            const int mib = xlfd_encoding[desc.encoding->encoding].mib;            XFontStruct *xfs;            if ((xfs = XLoadQueryFont(QX11Info::display(), xlfd))) {                fe = new QFontEngineXLFD(xfs, xlfd, mib);                const int dpi = QX11Info::appDpiY();                if (!qt_fillFontDef(xfs, &fe->fontDef, dpi)                    && !qt_fillFontDef(xlfd, &fe->fontDef, dpi)) {                    initFontDef(desc, request, &fe->fontDef);                }            }        }        if (!fe) {            fe = new QFontEngineBox(request.pixelSize);            fe->fontDef = QFontDef();        }    } else {        QList<int> encodings;        if (desc.encoding)            encodings.append(int(desc.encoding->encoding));        if (desc.size) {            // append all other encodings for the matched font            for (int i = 0; i < desc.size->count; ++i) {                QtFontEncoding *e = desc.size->encodings + i;                if (e == desc.encoding)                    continue;                encodings.append(int(e->encoding));            }        }        // fill in the missing encodings        const XlfdEncoding *enc = xlfd_encoding;        for (; enc->name; ++enc) {            if (!encodings.contains(enc->id))                encodings.append(enc->id);        }#if defined(FONT_MATCH_DEBUG)        FM_DEBUG("    using MultiXLFD, encodings:");        for (int i = 0; i < encodings.size(); ++i) {            const int id = encodings.at(i);            FM_DEBUG("      %2d: %s", xlfd_encoding[id].id, xlfd_encoding[id].name);        }#endif        fe = new QFontEngineMultiXLFD(request, encodings, screen);    }    return fe;}/*! \internal  Loads a QFontEngine for the specified \a script that matches the  QFontDef \e request member variable.*/void QFontDatabase::load(const QFontPrivate *d, int script){    Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount);    if (!privateDb()->count)        initializeDb();    // normalize the request to get better caching    QFontDef req = d->request;    if (req.pixelSize <= 0)        req.pixelSize = qRound(qt_pixelSize(req.pointSize, d->dpi));    req.pointSize = 0;    if (req.weight == 0)        req.weight = QFont::Normal;    if (req.stretch == 0)        req.stretch = 100;    QFontCache::Key key(req, d->rawMode ? QUnicodeTables::Common : script, d->screen);    if (!d->engineData)        getEngineData(d, key);    // the cached engineData could have already loaded the engine we want    if (d->engineData->engines[script])        return;    // set it to the actual pointsize, so QFontInfo will do the right thing    req.pointSize = qt_pointSize(req.pixelSize, d->dpi);    QFontEngine *fe = QFontCache::instance->findEngine(key);    if (!fe) {        if (qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) {            fe = new QTestFontEngine(req.pixelSize);            fe->fontDef = req;        } else if (d->rawMode) {            fe = loadRaw(d, req);        } else#ifndef QT_NO_FONTCONFIG            if (X11->has_fontconfig) {                fe = loadFc(d, script, req);            } else#endif                {                    fe = loadXlfd(d->screen, script, req);                }        if (!fe) {            fe = new QFontEngineBox(req.pixelSize);            fe->fontDef = QFontDef();        }    }    d->engineData->engines[script] = fe;    fe->ref.ref();    QFontCache::instance->insertEngine(key, fe);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -