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

📄 qfontengine_qpf.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** 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 "qfontengine_qpf_p.h"#include "private/qpaintengine_raster_p.h"#include <QtCore/qlibraryinfo.h>#include <QtCore/qfileinfo.h>#include <QtCore/qfile.h>#include <QtCore/qdir.h>#include <QtCore/qbuffer.h>#if !defined(QT_NO_FREETYPE)#include "private/qfontengine_ft_p.h"#include "qopentype_p.h"#endif// 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_QWS_QPF#include "qpfutil.cpp"#if defined(Q_WS_QWS)#include "private/qwscommand_qws_p.h"#include "qwsdisplay_qws.h"#include "qabstractfontengine_p.h"#endif#include "qplatformdefs.h"#ifdef QT_LSB#include <dlfcn.h>#  ifdef QT_NO_MREMAP#    undef QT_NO_MREMAP#  endif#  define MREMAP_MAYMOVE 1#  define RTLD_DEFAULT   ((void *) 0)// LSB doesn't standardize mremap - resolve it dynamically at runtimestatic void *mremap (void *__addr, size_t __old_len, size_t __new_len, int __flags){    typedef void *(*RemapAddress)(void*, size_t, size_t, int, ...);    static RemapAddress remapAddr = 0;    if (!remapAddr) {        *(void **)(&remapAddr) = ::dlsym(RTLD_DEFAULT, "mremap");        if (!remapAddr)            qFatal("Unable to call mremap");    }    return remapAddr(__addr, __old_len, __new_len, __flags);}#endif//#define DEBUG_HEADER//#define DEBUG_FONTENGINE#if defined(DEBUG_HEADER)# define DEBUG_VERIFY qDebug#else# define DEBUG_VERIFY if (0) qDebug#endif#define READ_VERIFY(type, variable) \    if (tagPtr + sizeof(type) > endPtr) { \        DEBUG_VERIFY() << "read verify failed in line" << __LINE__; \        return 0; \    } \    variable = qFromBigEndian<type>(tagPtr); \    DEBUG_VERIFY() << "read value" << variable << "of type " #type; \    tagPtr += sizeof(type)template <typename T>T readValue(const uchar *&data){    T value = qFromBigEndian<T>(data);    data += sizeof(T);    return value;}#define VERIFY(condition) \    if (!(condition)) { \        DEBUG_VERIFY() << "condition " #condition " failed in line" << __LINE__; \        return 0; \    }#define VERIFY_TAG(condition) \    if (!(condition)) { \        DEBUG_VERIFY() << "verifying tag condition " #condition " failed in line" << __LINE__ << "with tag" << tag; \        return 0; \    }static inline const uchar *verifyTag(const uchar *tagPtr, const uchar *endPtr){    quint16 tag, length;    READ_VERIFY(quint16, tag);    READ_VERIFY(quint16, length);    if (tag == QFontEngineQPF::Tag_EndOfHeader)        return endPtr;    if (tag < QFontEngineQPF::NumTags) {        switch (tagTypes[tag]) {            case QFontEngineQPF::BitFieldType:            case QFontEngineQPF::StringType:                // can't do anything...                break;            case QFontEngineQPF::UInt32Type:                VERIFY_TAG(length == sizeof(quint32));                break;            case QFontEngineQPF::FixedType:                VERIFY_TAG(length == sizeof(quint32));                break;            case QFontEngineQPF::UInt8Type:                VERIFY_TAG(length == sizeof(quint8));                break;        }#if defined(DEBUG_HEADER)        if (length == 1)            qDebug() << "tag data" << hex << *tagPtr;        else if (length == 4)            qDebug() << "tag data" << hex << tagPtr[0] << tagPtr[1] << tagPtr[2] << tagPtr[3];#endif    }    return tagPtr + length;}const QFontEngineQPF::Glyph *QFontEngineQPF::findGlyph(glyph_t g) const{    if (!g || g >= glyphMapEntries)        return 0;    const quint32 *gmapPtr = reinterpret_cast<const quint32 *>(fontData + glyphMapOffset);    quint32 glyphPos = qFromBigEndian<quint32>(gmapPtr[g]);    if (glyphPos > glyphDataSize) {        if (glyphPos == 0xffffffff)            return 0;#if defined(DEBUG_FONTENGINE)        qDebug() << "glyph" << g << "outside of glyphData, remapping font file";#endif#ifndef QT_NO_FREETYPE        const_cast<QFontEngineQPF *>(this)->remapFontData();#endif        if (glyphPos > glyphDataSize)            return 0;    }    return reinterpret_cast<const Glyph *>(fontData + glyphDataOffset + glyphPos);}bool QFontEngineQPF::verifyHeader(const uchar *data, int size){    VERIFY(size >= int(sizeof(Header)));    const Header *header = reinterpret_cast<const Header *>(data);    if (header->magic[0] != 'Q'        || header->magic[1] != 'P'        || header->magic[2] != 'F'        || header->magic[3] != '2')        return false;    VERIFY(header->majorVersion <= CurrentMajorVersion);    const quint16 dataSize = qFromBigEndian<quint16>(header->dataSize);    VERIFY(size >= int(sizeof(Header)) + dataSize);    const uchar *tagPtr = data + sizeof(Header);    const uchar *tagEndPtr = tagPtr + dataSize;    while (tagPtr < tagEndPtr - 3) {        tagPtr = verifyTag(tagPtr, tagEndPtr);        VERIFY(tagPtr);    }    VERIFY(tagPtr <= tagEndPtr);    return true;}QVariant QFontEngineQPF::extractHeaderField(const uchar *data, HeaderTag requestedTag){    const Header *header = reinterpret_cast<const Header *>(data);    const uchar *tagPtr = data + sizeof(Header);    const uchar *endPtr = tagPtr + qFromBigEndian<quint16>(header->dataSize);    while (tagPtr < endPtr - 3) {        quint16 tag = readValue<quint16>(tagPtr);        quint16 length = readValue<quint16>(tagPtr);        if (tag == requestedTag) {            switch (tagTypes[requestedTag]) {                case StringType:                    return QVariant(QString::fromUtf8(reinterpret_cast<const char *>(tagPtr), length));                case UInt32Type:                    return QVariant(readValue<quint32>(tagPtr));                case UInt8Type:                    return QVariant(uint(*tagPtr));                case FixedType:                    return QVariant(QFixed::fromFixed(readValue<quint32>(tagPtr)).toReal());                case BitFieldType:                    return QVariant(QByteArray(reinterpret_cast<const char *>(tagPtr), length));            }            return QVariant();        } else if (tag == Tag_EndOfHeader) {            break;        }        tagPtr += length;    }    return QVariant();}#endif // QT_NO_QWS_QPFQString qws_fontCacheDir(){    static QString dir;    if (!dir.isEmpty())        return dir;#if defined(Q_WS_QWS)    extern QString qws_dataDir();    dir = qws_dataDir();#else    dir = QDir::tempPath();#endif    dir.append(QLatin1String("/fonts/"));    QDir qd(dir);    if (!qd.exists() && !qd.mkpath(dir))        dir = QDir::tempPath();    return dir;}#ifndef QT_NO_QWS_QPFQList<QByteArray> QFontEngineQPF::cleanUpAfterClientCrash(const QList<int> &crashedClientIds){    QList<QByteArray> removedFonts;    QDir dir(qws_fontCacheDir(), QLatin1String("*.qsf"));    for (int i = 0; i < int(dir.count()); ++i) {        const QByteArray fileName = QFile::encodeName(dir.absoluteFilePath(dir[i]));        int fd = ::open(fileName.constData(), O_RDONLY);        if (fd >= 0) {            void *header = ::mmap(0, sizeof(QFontEngineQPF::Header), PROT_READ, MAP_SHARED, fd, 0);            if (header && header != MAP_FAILED) {                quint32 lockValue = reinterpret_cast<QFontEngineQPF::Header *>(header)->lock;                if (lockValue && crashedClientIds.contains(lockValue)) {                    removedFonts.append(fileName);                    QFile::remove(QFile::decodeName(fileName));                }                ::munmap(header, sizeof(QFontEngineQPF::Header));            }            ::close(fd);        }    }    if (!removedFonts.isEmpty())        qDebug() << "list of corrupted and removed fonts:" << removedFonts;    return removedFonts;}static inline unsigned int getChar(const QChar *str, int &i, const int len){    unsigned int uc = str[i].unicode();    if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {        uint low = str[i+1].unicode();       if (low >= 0xdc00 && low < 0xe000) {            uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;            ++i;        }    }    return uc;}QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEngine *fontEngine)    : fd(fileDescriptor), renderingFontEngine(fontEngine){    fontData = 0;    dataSize = 0;    fontDef = def;    cache_cost = 100;    freetype = 0;    _openType = 0;    externalCMap = 0;    cmapOffset = 0;    cmapSize = 0;    glyphMapOffset = 0;    glyphMapEntries = 0;    glyphDataOffset = 0;    glyphDataSize = 0;    kerning_pairs_loaded = false;    readOnly = true;#if defined(DEBUG_FONTENGINE)    qDebug() << "QFontEngineQPF::QFontEngineQPF( fd =" << fd << ", renderingFontEngine =" << renderingFontEngine << ")";#endif    if (fd < 0) {        if (!renderingFontEngine)            return;        fileName = fontDef.family.toLower() + QLatin1String("_")                   + QString::number(fontDef.pixelSize)                   + QLatin1String("_") + QString::number(fontDef.weight)                   + (fontDef.style != QFont::StyleNormal ?                      QLatin1String("_italic") : QLatin1String(""))                   + QLatin1String(".qsf");        fileName.replace(QLatin1Char(' '), QLatin1Char('_'));        fileName.prepend(qws_fontCacheDir());        const QByteArray encodedName = QFile::encodeName(fileName);        if (::access(encodedName, F_OK) == 0) {#if defined(DEBUG_FONTENGINE)            qDebug() << "found existing qpf:" << fileName;#endif            if (::access(encodedName, W_OK | R_OK) == 0)                fd = ::open(encodedName, O_RDWR);            else if (::access(encodedName, R_OK) == 0)                fd = ::open(encodedName, O_RDONLY);        } else {#if defined(DEBUG_FONTENGINE)            qDebug() << "creating qpf on the fly:" << fileName;#endif            if (::access(QFile::encodeName(qws_fontCacheDir()), W_OK) == 0) {                fd = ::open(encodedName, O_RDWR | O_EXCL | O_CREAT, 0644);                QBuffer buffer;                buffer.open(QIODevice::ReadWrite);                QPFGenerator generator(&buffer, renderingFontEngine);                generator.generate();                buffer.close();                const QByteArray &data = buffer.data();                ::write(fd, data.constData(), data.size());            }        }    }    QT_STATBUF st;    if (QT_FSTAT(fd, &st)) {#if defined(DEBUG_FONTENGINE)        qDebug() << "stat failed!";#endif        return;    }    dataSize = st.st_size;    fontData = (const uchar *)::mmap(0, st.st_size, PROT_READ | (renderingFontEngine ? PROT_WRITE : 0), MAP_SHARED, fd, 0);

⌨️ 快捷键说明

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