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

📄 qfontengine_x11.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            }            if (pixel & (0x80 >> (x & 7))) {                int rx = x;                while (x < w && src[(x+1) >> 3] & (0x80 >> ((x+1) & 7)))                    ++x;                path->addRect(QRectF(cp.x() + rx + TRUNC(slot->metrics.horiBearingX),                                     cp.y() + y - TRUNC(slot->metrics.horiBearingY),                                     x - rx + 1, 1));            }        }        src += slot->bitmap.pitch;    }}#endif // QT_NO_FREETYPE// ------------------------------------------------------------------// Multi XLFD engine// ------------------------------------------------------------------QFontEngineMultiXLFD::QFontEngineMultiXLFD(const QFontDef &r, const QList<int> &l, int s)    : QFontEngineMulti(l.size()), encodings(l), screen(s), request(r){    loadEngine(0);    fontDef = engines[0]->fontDef;}QFontEngineMultiXLFD::~QFontEngineMultiXLFD(){ }void QFontEngineMultiXLFD::loadEngine(int at){    Q_ASSERT(at < engines.size());    Q_ASSERT(engines.at(at) == 0);    const int encoding = encodings.at(at);    QFontEngine *fontEngine = QFontDatabase::loadXlfd(0, QUnicodeTables::Common, request, encoding);    Q_ASSERT(fontEngine != 0);    fontEngine->ref.ref();    engines[at] = fontEngine;}// ------------------------------------------------------------------// Xlfd font engine// ------------------------------------------------------------------#ifndef QT_NO_FREETYPEstatic QStringList *qt_fontpath = 0;static QStringList fontPath(){    if (qt_fontpath)        return *qt_fontpath;    // append qsettings fontpath    QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));    settings.beginGroup(QLatin1String("Qt"));    QStringList fontpath;    int npaths;    char** font_path;    font_path = XGetFontPath(X11->display, &npaths);    bool xfsconfig_read = false;    for (int i=0; i<npaths; i++) {        // If we're using xfs, append font paths from /etc/X11/fs/config        // can't hurt, and chances are we'll get all fonts that way.        if (((font_path[i])[0] != '/') && !xfsconfig_read) {            // We're using xfs -> read its config            bool finished = false;            QFile f("/etc/X11/fs/config");            if (!f.exists())                f.setFileName("/usr/X11R6/lib/X11/fs/config");            if (!f.exists())                f.setFileName("/usr/X11/lib/X11/fs/config");            if (f.exists()) {                f.open(QIODevice::ReadOnly);                while (f.error()==QFile::NoError && !finished) {                    QString fs = f.readLine(1024);                    fs=fs.trimmed();                    if (fs.left(9)=="catalogue" && fs.contains('=')) {                        fs = fs.mid(fs.indexOf('=') + 1).trimmed();                        bool end = false;                        while (f.error()==QFile::NoError && !end) {                            if (fs[int(fs.length())-1] == ',')                                fs = fs.left(fs.length()-1);                            else                                end = true;                            fs = fs.left(fs.indexOf(":unscaled"));                            if (fs[0] != '#')                                fontpath += fs;                            fs = f.readLine(1024);                            fs = fs.trimmed();                            if (fs.isEmpty())                                end = true;                        }                        finished = true;                    }                }                f.close();            }            xfsconfig_read = true;        } else {            QString fs = QString::fromLatin1(font_path[i]);            fontpath += fs.left(fs.indexOf(":unscaled"));        }    }    XFreeFontPath(font_path);    // append qsettings fontpath    QStringList fp = settings.value(QLatin1String("fontPath")).toStringList();    if (!fp.isEmpty())        fontpath += fp;    qt_fontpath = new QStringList(fontpath);    return fontpath;}static QFontEngine::FaceId fontFile(const QByteArray &_xname, QFreetypeFace **freetype, int *synth){    *freetype = 0;    *synth = 0;    QByteArray xname = _xname.toLower();    int pos = 0;    int minus = 0;    while (minus < 5 && (pos = xname.indexOf('-', pos + 1)))        ++minus;    QByteArray searchname = xname.left(pos);    while (minus < 12 && (pos = xname.indexOf('-', pos + 1)))        ++minus;    QByteArray encoding = xname.mid(pos + 1);    //qDebug("xname='%s', searchname='%s', encoding='%s'", xname.data(), searchname.data(), encoding.data());    QStringList fontpath = ::fontPath();    QFontEngine::FaceId face_id;    face_id.index = 0;    QByteArray best_mapping;    for (QStringList::ConstIterator it = fontpath.constBegin(); it != fontpath.constEnd(); ++it) {        if ((*it).left(1) != "/")            continue; // not a path name, a font server        QString fontmapname;        int num = 0;        // search font.dir and font.scale for the right file        while (num < 2) {            if (num == 0)                fontmapname = (*it) + "/fonts.scale";            else                fontmapname = (*it) + "/fonts.dir";            ++num;            //qWarning(fontmapname);            QFile fontmap(fontmapname);            if (!fontmap.open(QIODevice::ReadOnly))                continue;            while (!fontmap.atEnd()) {                QByteArray mapping = fontmap.readLine();                QByteArray lmapping = mapping.toLower();                //qWarning(xfontname);                //qWarning(mapping);                if (!lmapping.contains(searchname))                    continue;                int index = mapping.indexOf(' ');                QByteArray ffn = mapping.mid(0,index);                // remove bitmap formats freetype can't handle                if(ffn.contains(".spd") || ffn.contains(".phont"))                    continue;                bool best_match = false;                if (!best_mapping.isEmpty()) {                    if (lmapping.contains("-0-0-0-0-")) { // scalable font                        best_match = true;                        goto found;                    }                    if (lmapping.contains(encoding) && !best_mapping.toLower().contains(encoding))                        goto found;                    continue;                }            found:                int colon = ffn.lastIndexOf(':');                if (colon != -1) {                    QByteArray s = ffn.left(colon);                    ffn = ffn.mid(colon + 1);                    if (s.contains("ds="))                        *synth |= QFontEngine::SynthesizedBold;                    if (s.contains("ai="))                        *synth |= QFontEngine::SynthesizedItalic;                }                face_id.filename = (*it).toLocal8Bit() + '/' + ffn;                best_mapping = mapping;                if (best_match)                    goto end;            }        }    }end://     qDebug("fontfile for %s is from '%s'\n    got %s synth=%d", xname.data(),//            best_mapping.data(), face_id.filename.data(), *synth);    *freetype = QFreetypeFace::getFace(face_id);    if (!*freetype) {        face_id.index = 0;        face_id.filename = QByteArray();    }    return face_id;}#endif // QT_NO_FREETYPE// defined in qfontdatabase_x11.cppextern int qt_mib_for_xlfd_encoding(const char *encoding);extern int qt_xlfd_encoding_id(const char *encoding);static inline XCharStruct *charStruct(XFontStruct *xfs, uint ch){    XCharStruct *xcs = 0;    unsigned char r = ch>>8;    unsigned char c = ch&0xff;    if (xfs->per_char &&         r >= xfs->min_byte1 &&         r <= xfs->max_byte1 &&         c >= xfs->min_char_or_byte2 &&         c <= xfs->max_char_or_byte2) {        xcs = xfs->per_char + ((r - xfs->min_byte1) *                               (xfs->max_char_or_byte2 -                                xfs->min_char_or_byte2 + 1)) +              (c - xfs->min_char_or_byte2);        if (xcs->width == 0 && xcs->ascent == 0 &&  xcs->descent == 0)            xcs = 0;    }    return xcs;}QFontEngineXLFD::QFontEngineXLFD(XFontStruct *fs, const QByteArray &name, int mib)    : _fs(fs), _name(name), _codec(0), _cmap(mib){    if (_cmap) _codec = QTextCodec::codecForMib(_cmap);    cache_cost = (((fs->max_byte1 - fs->min_byte1) *                   (fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1)) +                  fs->max_char_or_byte2 - fs->min_char_or_byte2);    cache_cost = ((fs->max_bounds.ascent + fs->max_bounds.descent) *                  (fs->max_bounds.width * cache_cost / 8));    lbearing = SHRT_MIN;    rbearing = SHRT_MIN;    face_id.index = -1;    freetype = 0;    synth = 0;}QFontEngineXLFD::~QFontEngineXLFD(){    XFreeFont(QX11Info::display(), _fs);    _fs = 0;#ifndef QT_NO_FREETYPE    if (freetype)        freetype->release(face_id);#endif}bool QFontEngineXLFD::stringToCMap(const QChar *s, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const{    if (*nglyphs < len) {        *nglyphs = len;        return false;    }    // filter out surrogates, we can't handle them anyway with XLFD fonts    QVarLengthArray<ushort> _s(len);    QChar *str = (QChar *)_s.data();    for (int i = 0; i < len; ++i) {        if (i < len - 1            && s[i].unicode() >= 0xd800 && s[i].unicode() < 0xdc00            && s[i+1].unicode() >= 0xdc00 && s[i].unicode() < 0xe000) {            *str = QChar();            ++i;        } else {            *str = s[i];        }        ++str;    }    len = str - (QChar *)_s.data();    str = (QChar *)_s.data();    bool mirrored = flags & QTextEngine::RightToLeft;    if (_codec) {        bool haveNbsp = false;        for (int i = 0; i < len; i++)            if (str[i].unicode() == 0xa0) {                haveNbsp = true;                break;            }        QVarLengthArray<unsigned short> ch(len);        QChar *chars = (QChar *)ch.data();        if (haveNbsp || mirrored) {            for (int i = 0; i < len; i++)                chars[i] = (str[i].unicode() == 0xa0 ? 0x20 :                            (mirrored ? ::mirroredChar(str[i]).unicode() : str[i].unicode()));        } else {            for (int i = 0; i < len; i++)                chars[i] = str[i].unicode();        }        QTextCodec::ConverterState state;        state.flags = QTextCodec::ConvertInvalidToNull;        QByteArray ba = _codec->fromUnicode(chars, len, &state);        if (ba.length() == 2*len) {            // double byte encoding            const uchar *data = (const uchar *)ba.constData();            for (int i = 0; i < len; i++) {                glyphs[i].glyph = ((ushort)data[0] << 8) + data[1];                data += 2;            }        } else {            const uchar *data = (const uchar *)ba.constData();            for (int i = 0; i < len; i++)                glyphs[i].glyph = (ushort)data[i];        }    } else {        QGlyphLayout *g = glyphs + len;        const QChar *c = str + len;        if (mirrored) {            while (c != str)                (--g)->glyph = (--c)->unicode() == 0xa0 ? 0x20 : ::mirroredChar(*c).unicode();        } else {            while (c != str)                (--g)->glyph = (--c)->unicode() == 0xa0 ? 0x20 : c->unicode();        }    }    *nglyphs = len;    QGlyphLayout *g = glyphs + len;    XCharStruct *xcs;    // inlined for better perfomance    if (!_fs->per_char) {        xcs = &_fs->min_bounds;        while (g != glyphs) {            --g;            const unsigned char r = g->glyph >> 8;            const unsigned char c = g->glyph & 0xff;            if (r >= _fs->min_byte1 &&                r <= _fs->max_byte1 &&                c >= _fs->min_char_or_byte2 &&                c <= _fs->max_char_or_byte2) {                g->advance.x = xcs->width;            } else {                g->glyph = 0;            }        }    }    else if (!_fs->max_byte1) {        XCharStruct *base = _fs->per_char - _fs->min_char_or_byte2;        while (g != glyphs) {            unsigned int gl = (--g)->glyph;            xcs = (gl >= _fs->min_char_or_byte2 && gl <= _fs->max_char_or_byte2) ?                  base + gl : 0;            if (!xcs || (!xcs->width && !xcs->ascent && !xcs->descent)) {                g->glyph = 0;            } else {                g->advance.x = xcs->width;            }        }    }    else {        while (g != glyphs) {            xcs = charStruct(_fs, (--g)->glyph);            if (!xcs) {                g->glyph = 0;            } else {                g->advance.x = xcs->width;            }        }    }    return true;}glyph_metrics_t QFontEngineXLFD::boundingBox(const QGlyphLayout *glyphs, int numGlyphs){    int i;    glyph_metrics_t overall;    QFixed ymax;    QFixed xmax;    for (i = 0; i < numGlyphs; i++) {        XCharStruct *xcs = charStruct(_fs, glyphs[i].glyph);        if (xcs) {            QFixed x = overall.xoff + glyphs[i].offset.x + xcs->lbearing;            QFixed y = overall.yoff + glyphs[i].offset.y - xcs->ascent;            overall.x = qMin(overall.x, x);            overall.y = qMin(overall.y, y);            xmax = qMax(xmax, overall.xoff + glyphs[i].offset.x + xcs->rbearing);            ymax = qMax(ymax, y + xcs->ascent + xcs->descent);            overall.xoff += glyphs[i].advance.x;        } else {            QFixed size = _fs->ascent;            overall.x = qMin(overall.x, overall.xoff);            overall.y = qMin(overall.y, overall.yoff - size);            ymax = qMax(ymax, overall.yoff);            overall.xoff += size;            xmax = qMax(xmax, overall.xoff);        }    }

⌨️ 快捷键说明

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