📄 qfontengine_x11.cpp
字号:
} 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 + -