📄 qfontengine_x11.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qbitmap.h"// #define FONTENGINE_DEBUG#include <qbytearray.h>#include <qdebug.h>#include <qtextcodec.h>#include "qfontdatabase.h"#include "qpaintdevice.h"#include "qpainter.h"#include "qvarlengtharray.h"#include "qwidget.h"#include "qsettings.h"#include "qfile.h"#include <private/qpaintengine_x11_p.h>#include "qfont.h"#include "qfont_p.h"#include "qfontengine_p.h"#include <qhash.h>#include <private/qpainter_p.h>#include <private/qunicodetables_p.h>#include <private/qt_x11_p.h>#include "qx11info_x11.h"#include "qfontengine_x11_p.h"#include <limits.h>// ------------------------------------------------------------------// 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(QLatin1String("/etc/X11/fs/config")); if (!f.exists()) f.setFileName(QLatin1String("/usr/X11R6/lib/X11/fs/config")); if (!f.exists()) f.setFileName(QLatin1String("/usr/X11/lib/X11/fs/config")); if (f.exists()) { f.open(QIODevice::ReadOnly); while (f.error()==QFile::NoError && !finished) { QString fs = QString::fromLocal8Bit(f.readLine(1024)); fs=fs.trimmed(); if (fs.left(9)==QLatin1String("catalogue") && fs.contains(QLatin1Char('='))) { fs = fs.mid(fs.indexOf(QLatin1Char('=')) + 1).trimmed(); bool end = false; while (f.error()==QFile::NoError && !end) { if (fs[int(fs.length())-1] == QLatin1Char(',')) fs = fs.left(fs.length()-1); else end = true; fs = fs.left(fs.indexOf(QLatin1String(":unscaled"))); if (fs[0] != QLatin1Char('#')) fontpath += fs; fs = QLatin1String(f.readLine(1024)); fs = fs.trimmed(); if (fs.isEmpty()) end = true; } finished = true; } } f.close(); } xfsconfig_read = true; } else { QString fs = QString::fromLocal8Bit(font_path[i]); fontpath += fs.left(fs.indexOf(QLatin1String(":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) != QLatin1String("/")) 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) + QLatin1String("/fonts.scale"); else fontmapname = (*it) + QLatin1String("/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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -