📄 qfontdatabase_qws.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 "qdir.h"#include "qscreen_qws.h" //so we can check for rotation#include "qwindowsystem_qws.h"#include "qlibraryinfo.h"#include "qabstractfileengine.h"#include <QtCore/qsettings.h>#if !defined(QT_NO_FREETYPE)#include "qfontengine_ft_p.h"#include <ft2build.h>#include FT_FREETYPE_H#include FT_TRUETYPE_TABLES_H#endif#include "qfontengine_qpf_p.h"#include "private/qfactoryloader_p.h"#include "qabstractfontengine_qws.h"#include "qabstractfontengine_p.h"#include <qdatetime.h>// for mmap#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/mman.h>#include <fcntl.h>#include <errno.h>#ifndef QT_NO_LIBRARYQ_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QFontEngineFactoryInterface_iid, QCoreApplication::libraryPaths(), QLatin1String("/fontengines"), Qt::CaseInsensitive))#endifconst quint8 DatabaseVersion = 4;void QFontDatabasePrivate::addFont(const QString &familyname, const char *foundryname, int weight, bool italic, int pixelSize, const QByteArray &file, int fileIndex, bool antialiased, const QList<QFontDatabase::WritingSystem> &writingSystems){// qDebug() << "Adding font" << familyname << weight << italic << pixelSize << file << fileIndex << antialiased; QtFontStyle::Key styleKey; styleKey.style = italic ? QFont::StyleItalic : QFont::StyleNormal; styleKey.weight = weight; styleKey.stretch = 100; QtFontFamily *f = family(familyname, true); if (writingSystems.isEmpty()) { for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) { f->writingSystems[ws] = QtFontFamily::Supported; } f->bogusWritingSystems = true; } else { for (int i = 0; i < writingSystems.count(); ++i) { f->writingSystems[writingSystems.at(i)] = QtFontFamily::Supported; } } QtFontFoundry *foundry = f->foundry(QString::fromLatin1(foundryname), true); QtFontStyle *style = foundry->style(styleKey, true); style->smoothScalable = (pixelSize == 0); style->antialiased = antialiased; QtFontSize *size = style->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true); size->fileName = file; size->fileIndex = fileIndex; if (stream) { *stream << familyname << foundry->name << weight << quint8(italic) << pixelSize << file << fileIndex << quint8(antialiased); *stream << quint8(writingSystems.count()); for (int i = 0; i < writingSystems.count(); ++i) *stream << quint8(writingSystems.at(i)); }}#ifndef QT_NO_QWS_QPF2void QFontDatabasePrivate::addQPF2File(const QByteArray &file){ struct stat st; if (stat(file.constData(), &st)) return; int f = ::open(file, O_RDONLY); if (f < 0) return; const uchar *data = (const uchar *)mmap(0, st.st_size, PROT_READ, MAP_SHARED, f, 0); if (data && data != (const uchar *)MAP_FAILED) { if (QFontEngineQPF::verifyHeader(data, st.st_size)) { QString fontName = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_FontName).toString(); int pixelSize = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_PixelSize).toInt(); QVariant weight = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_Weight); QVariant style = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_Style); QByteArray writingSystemBits = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_WritingSystems).toByteArray(); if (!fontName.isEmpty() && pixelSize) { int fontWeight = 50; if (weight.type() == QVariant::Int) fontWeight = weight.toInt(); else if (weight.type() == QVariant::UInt) fontWeight = (int)weight.toUInt(); bool italic = static_cast<QFont::Style>(style.toInt()) & QFont::StyleItalic; QList<QFontDatabase::WritingSystem> writingSystems; for (int i = 0; i < writingSystemBits.count(); ++i) { uchar currentByte = writingSystemBits.at(i); for (int j = 0; j < 8; ++j) { if (currentByte & 1) writingSystems << QFontDatabase::WritingSystem(i * 8 + j); currentByte >>= 1; } } addFont(fontName, /*foundry*/ "prerendered", fontWeight, italic, pixelSize, file, /*fileIndex*/ 0, /*antialiased*/ true, writingSystems); } } else { qDebug() << "header verification of QPF2 font" << file << "failed. maybe it is corrupt?"; } munmap((void *)data, st.st_size); } ::close(f);}#endif#ifndef QT_NO_FREETYPEQStringList QFontDatabasePrivate::addTTFile(const QByteArray &file, const QByteArray &fontData){ QStringList families; extern FT_Library qt_getFreetype(); FT_Library library = qt_getFreetype(); int index = 0; int numFaces = 0; 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, index, &face); } if (error != FT_Err_Ok) { qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error; break; } numFaces = face->num_faces; int weight = QFont::Normal; bool italic = face->style_flags & FT_STYLE_FLAG_ITALIC; if (face->style_flags & FT_STYLE_FLAG_BOLD) weight = QFont::Bold; QList<QFontDatabase::WritingSystem> 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.append(QFontDatabase::Symbol); break; } } if (writingSystems.isEmpty()) { 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); //for (int i = 0; i < writingSystems.count(); ++i) // qDebug() << QFontDatabase::writingSystemName(writingSystems.at(i)); } } QString family = QString::fromAscii(face->family_name); families.append(family); addFont(family, /*foundry*/ "", weight, italic, /*pixelsize*/ 0, file, index, /*antialias*/ true, writingSystems); FT_Done_Face(face); ++index; } while (index < numFaces); return families;}#endifstatic void registerFont(QFontDatabasePrivate::ApplicationFont *fnt);extern QString qws_fontCacheDir();bool QFontDatabasePrivate::loadFromCache(const QString &fontPath){ const bool weAreTheServer = QWSServer::instance(); QString fontDirFile = fontPath + QLatin1String("/fontdir"); QFile binaryDb(qws_fontCacheDir() + QLatin1String("/fontdb")); if (weAreTheServer) { QDateTime dbTimeStamp = QFileInfo(binaryDb.fileName()).lastModified(); QDateTime fontPathTimeStamp = QFileInfo(fontPath).lastModified(); if (dbTimeStamp < fontPathTimeStamp) return false; // let the caller create the cache if (QFile::exists(fontDirFile)) { QDateTime fontDirTimeStamp = QFileInfo(fontDirFile).lastModified(); if (dbTimeStamp < fontDirTimeStamp) return false; } } if (!binaryDb.open(QIODevice::ReadOnly)) { if (weAreTheServer) return false; // let the caller create the cache qFatal("QFontDatabase::loadFromCache: Could not open font database cache!"); } QDataStream stream(&binaryDb); quint8 version = 0; quint8 dataStreamVersion = 0; stream >> version >> dataStreamVersion; if (version != DatabaseVersion || dataStreamVersion != stream.version()) { if (weAreTheServer) return false; // let the caller create the cache qFatal("QFontDatabase::loadFromCache: Wrong version of the font database cache detected. Found %d/%d expected %d/%d", version, dataStreamVersion, DatabaseVersion, stream.version()); } QString originalFontPath; stream >> originalFontPath; if (originalFontPath != fontPath) { if (weAreTheServer) return false; // let the caller create the cache qFatal("QFontDatabase::loadFromCache: Font path doesn't match. Found %s in database, expected %s", qPrintable(originalFontPath), qPrintable(fontPath)); } QString familyname; stream >> familyname; //qDebug() << "populating database from" << binaryDb.fileName(); while (!familyname.isEmpty() && !stream.atEnd()) { QString foundryname; int weight; quint8 italic; int pixelSize; QByteArray file; int fileIndex; quint8 antialiased; quint8 writingSystemCount; QList<QFontDatabase::WritingSystem> writingSystems; stream >> foundryname >> weight >> italic >> pixelSize >> file >> fileIndex >> antialiased >> writingSystemCount; for (quint8 i = 0; i < writingSystemCount; ++i) { quint8 ws; stream >> ws; writingSystems.append(QFontDatabase::WritingSystem(ws)); } addFont(familyname, foundryname.toLatin1().constData(), weight, italic, pixelSize, file, fileIndex, antialiased, writingSystems); stream >> familyname; } stream >> fallbackFamilies; //qDebug() << "fallback families from cache:" << fallbackFamilies; return true;}/*! \internal*/static QString qwsFontPath(){ QString fontpath = QString::fromLocal8Bit(qgetenv("QT_QWS_FONTDIR")); if (fontpath.isEmpty()) {#ifndef QT_NO_SETTINGS fontpath = QLibraryInfo::location(QLibraryInfo::LibrariesPath); fontpath += QLatin1String("/fonts");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -