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

📄 qfontengine_qpf.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    Q_ASSERT(freetype);    freetype->lock();    FT_Face face = freetype->face;    // ### not perfect    const int ysize = fontDef.pixelSize << 6;    const int xsize = ysize;    if (freetype->xsize != xsize || freetype->ysize != ysize) {        FT_Set_Char_Size(face, xsize, ysize, 0, 0);        freetype->xsize = xsize;        freetype->ysize = ysize;    }    FT_Matrix identityMatrix;    identityMatrix.xx = 0x10000;    identityMatrix.yy = 0x10000;    identityMatrix.xy = 0;    identityMatrix.yx = 0;    if (freetype->matrix.xx != identityMatrix.xx ||        freetype->matrix.yy != identityMatrix.yy ||        freetype->matrix.xy != identityMatrix.xy ||        freetype->matrix.yx != identityMatrix.yx) {        freetype->matrix = identityMatrix;        FT_Set_Transform(face, &freetype->matrix, 0);    }    return face;}void QFontEngineQPF::unlockFace() const{    freetype->unlock();}QOpenType *QFontEngineQPF::openType() const{    if (!freetype)        return 0;    if (_openType)         return _openType;    FT_Face face = lockFace();    if (!face || !FT_IS_SFNT(face)) {        unlockFace();        return 0;    }    _openType = new QOpenType(const_cast<QFontEngineQPF *>(this), face);    unlockFace();    return _openType;}void QFontEngineQPF::doKerning(int num_glyphs, QGlyphLayout *g, QTextEngine::ShaperFlags flags) const{    if (!kerning_pairs_loaded) {        kerning_pairs_loaded = true;        if (freetype && freetype->face->size->metrics.x_ppem != 0) {            lockFace();            QFixed scalingFactor(freetype->face->units_per_EM/freetype->face->size->metrics.x_ppem);            unlockFace();            const_cast<QFontEngineQPF *>(this)->loadKerningPairs(scalingFactor);        }    }    QFontEngine::doKerning(num_glyphs, g, flags);}void QFontEngineQPF::ensureGlyphsLoaded(const QGlyphLayout *glyphs, int len){    if (readOnly)        return;    bool locked = false;    for (int i = 0; i < len; ++i) {        if (!glyphs[i].glyph)            continue;        const Glyph *g = findGlyph(glyphs[i].glyph);        if (g)            continue;        if (!locked) {            if (!lockFile())                return;            locked = true;            g = findGlyph(glyphs[i].glyph);            if (g)                continue;        }        loadGlyph(glyphs[i].glyph);    }    if (locked) {        unlockFile();#if defined(DEBUG_FONTENGINE)        qDebug() << "Finished rendering glyphs\n";#endif    }}void QFontEngineQPF::loadGlyph(glyph_t glyph){    quint32 glyphPos = ~0;    if (!renderingFontEngine)        return;    QImage img = renderingFontEngine->alphaMapForGlyph(glyph).convertToFormat(QImage::Format_Indexed8);    glyph_metrics_t metrics = renderingFontEngine->boundingBox(glyph);    renderingFontEngine->removeGlyphFromCache(glyph);    off_t oldSize = ::lseek(fd, 0, SEEK_END);    if (oldSize == (off_t)-1)        return;    Glyph g;    g.width = img.width();    g.height = img.height();    g.bytesPerLine = img.bytesPerLine();    g.x = qRound(metrics.x);    g.y = qRound(metrics.y);    g.advance = qRound(metrics.xoff);    ::write(fd, &g, sizeof(g));    ::write(fd, img.bits(), img.numBytes());    glyphPos = oldSize - glyphDataOffset;#if 0 && defined(DEBUG_FONTENGINE)    qDebug() << "glyphPos for new glyph" << glyph << "is" << glyphPos << "oldSize" << oldSize << "glyphDataOffset" << glyphDataOffset;#endif    quint32 *gmap = (quint32 *)(fontData + glyphMapOffset);    gmap[glyph] = qToBigEndian(glyphPos);    glyphDataSize = glyphPos + sizeof(g) + img.numBytes();    quint32 *blockSizePtr = (quint32 *)(fontData + glyphDataOffset - 4);    *blockSizePtr = qToBigEndian(glyphDataSize);}bool QFontEngineQPF::lockFile(){    // #### this does not handle the case when the process holding the    // lock hangs for some reason    struct flock lock;    lock.l_type = F_WRLCK;    lock.l_whence = SEEK_SET;    lock.l_start = 0;    lock.l_len = 0; // lock the whole file    while (fcntl(fd, F_SETLKW, &lock) != 0) {        if (errno == EINTR)            continue;        perror("locking qpf");        return false;    }    Header *header = (Header *)fontData;    if (header->lock) {        lock.l_type = F_UNLCK;        if (fcntl(fd, F_SETLK, &lock) != 0)            perror("unlocking possibly corrupt qpf");        return false;    }#if defined(Q_WS_QWS)    extern int qws_client_id;    // qws_client_id == 0 means we're the server. in this case we just    // set the id to 1    header->lock = qws_client_id ? qws_client_id : 1;#else    header->lock = 1;#endif    return true;}void QFontEngineQPF::unlockFile(){    ((Header *)fontData)->lock = 0;    struct flock lock;    lock.l_type = F_UNLCK;    lock.l_whence = SEEK_SET;    lock.l_start = 0;    lock.l_len = 0; // lock the whole file    if (fcntl(fd, F_SETLK, &lock) != 0) {        perror("unlocking qpf");    }    remapFontData();}void QFontEngineQPF::remapFontData(){    off_t newFileSize = ::lseek(fd, 0, SEEK_END);    if (newFileSize == (off_t)-1) {#ifdef DEBUG_FONTENGINE        perror("QFontEngineQPF::remapFontData: lseek failed");#endif        fontData = 0;        return;    }#ifndef QT_NO_MREMAP    fontData = static_cast<uchar *>(::mremap(const_cast<uchar *>(fontData), dataSize, newFileSize, MREMAP_MAYMOVE));    if (!fontData || fontData == (const uchar *)MAP_FAILED) {#  if defined(DEBUG_FONTENGINE)        perror("QFontEngineQPF::remapFontData(): mremap failed");#  endif        fontData = 0;    }    if (!fontData)#endif // QT_NO_MREMAP    {        int status = ::munmap((void *)fontData, dataSize);        if (status != 0)            qErrnoWarning(status, "QFontEngineQPF::remapFomrData: munmap failed!");        fontData = (const uchar *)::mmap(0, newFileSize, PROT_READ | (renderingFontEngine ? PROT_WRITE : 0),                                         MAP_SHARED, fd, 0);        if (!fontData || fontData == (const uchar *)MAP_FAILED) {#  if defined(DEBUG_FONTENGINE)            perror("mmap failed");#  endif            fontData = 0;            return;        }    }    dataSize = newFileSize;    glyphDataSize = newFileSize - glyphDataOffset;#if defined(DEBUG_FONTENGINE)    qDebug() << "remapped the font file to" << newFileSize << "bytes";#endif}#endif // QT_NO_FREETYPEvoid QPFGenerator::generate(){    writeHeader();    writeGMap();    writeBlock(QFontEngineQPF::GlyphBlock, QByteArray());    dev->seek(4); // position of header.lock    writeUInt32(0);}void QPFGenerator::writeHeader(){    QFontEngineQPF::Header header;    header.magic[0] = 'Q';    header.magic[1] = 'P';    header.magic[2] = 'F';    header.magic[3] = '2';    header.lock = 1;    header.majorVersion = QFontEngineQPF::CurrentMajorVersion;    header.minorVersion = QFontEngineQPF::CurrentMinorVersion;    header.dataSize = 0;    dev->write((const char *)&header, sizeof(header));    writeTaggedString(QFontEngineQPF::Tag_FontName, fe->fontDef.family.toUtf8());    QFontEngine::FaceId face = fe->faceId();    writeTaggedString(QFontEngineQPF::Tag_FileName, face.filename);    writeTaggedUInt32(QFontEngineQPF::Tag_FileIndex, face.index);    {        const QByteArray head = fe->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd'));        const quint32 revision = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(head.constData()) + 4);        writeTaggedUInt32(QFontEngineQPF::Tag_FontRevision, revision);    }    writeTaggedQFixed(QFontEngineQPF::Tag_Ascent, fe->ascent());    writeTaggedQFixed(QFontEngineQPF::Tag_Descent, fe->descent());    writeTaggedQFixed(QFontEngineQPF::Tag_Leading, fe->leading());    writeTaggedQFixed(QFontEngineQPF::Tag_XHeight, fe->xHeight());    writeTaggedQFixed(QFontEngineQPF::Tag_AverageCharWidth, fe->averageCharWidth());    writeTaggedQFixed(QFontEngineQPF::Tag_MaxCharWidth, QFixed::fromReal(fe->maxCharWidth()));    writeTaggedQFixed(QFontEngineQPF::Tag_LineThickness, fe->lineThickness());    writeTaggedQFixed(QFontEngineQPF::Tag_MinLeftBearing, QFixed::fromReal(fe->minLeftBearing()));    writeTaggedQFixed(QFontEngineQPF::Tag_MinRightBearing, QFixed::fromReal(fe->minRightBearing()));    writeTaggedQFixed(QFontEngineQPF::Tag_UnderlinePosition, fe->underlinePosition());    writeTaggedUInt8(QFontEngineQPF::Tag_PixelSize, fe->fontDef.pixelSize);    writeTaggedUInt8(QFontEngineQPF::Tag_Weight, fe->fontDef.weight);    writeTaggedUInt8(QFontEngineQPF::Tag_Style, fe->fontDef.style);    writeTaggedUInt8(QFontEngineQPF::Tag_GlyphFormat, QFontEngineQPF::AlphamapGlyphs);    writeTaggedString(QFontEngineQPF::Tag_EndOfHeader, QByteArray());    align4();    const quint64 size = dev->pos();    header.dataSize = qToBigEndian<quint16>(size - sizeof(header));    dev->seek(0);    dev->write((const char *)&header, sizeof(header));    dev->seek(size);}void QPFGenerator::writeGMap(){    const quint16 glyphCount = fe->glyphCount();    writeUInt16(QFontEngineQPF::GMapBlock);    writeUInt16(0); // padding    writeUInt32(glyphCount * 4);    QByteArray &buffer = dev->buffer();    const int numBytes = glyphCount * sizeof(quint32);    qint64 pos = buffer.size();    buffer.resize(pos + numBytes);    qMemSet(buffer.data() + pos, 0xff, numBytes);    dev->seek(pos + numBytes);}void QPFGenerator::writeBlock(QFontEngineQPF::BlockTag tag, const QByteArray &data){    writeUInt16(tag);    writeUInt16(0); // padding    const int padSize = ((data.size() + 3) / 4) * 4 - data.size();    writeUInt32(data.size() + padSize);    dev->write(data);    for (int i = 0; i < padSize; ++i)        writeUInt8(0);}void QPFGenerator::writeTaggedString(QFontEngineQPF::HeaderTag tag, const QByteArray &string){    writeUInt16(tag);    writeUInt16(string.length());    dev->write(string);}void QPFGenerator::writeTaggedUInt32(QFontEngineQPF::HeaderTag tag, quint32 value){    writeUInt16(tag);    writeUInt16(sizeof(value));    writeUInt32(value);}void QPFGenerator::writeTaggedUInt8(QFontEngineQPF::HeaderTag tag, quint8 value){    writeUInt16(tag);    writeUInt16(sizeof(value));    writeUInt8(value);}void QPFGenerator::writeTaggedQFixed(QFontEngineQPF::HeaderTag tag, QFixed value){    writeUInt16(tag);    writeUInt16(sizeof(quint32));    writeUInt32(value.value());}#endif // QT_NO_QWS_QPFQFontEngineMultiQWS::QFontEngineMultiQWS(QFontEngine *fe, int _script, const QStringList &fallbacks)    : QFontEngineMulti(fallbacks.size() + 1),      fallbackFamilies(fallbacks), script(_script){    engines[0] = fe;    fe->ref.ref();    fontDef = engines[0]->fontDef;}void QFontEngineMultiQWS::loadEngine(int at){    Q_ASSERT(at < engines.size());    Q_ASSERT(engines.at(at) == 0);    QFontDef request = fontDef;    request.styleStrategy |= QFont::NoFontMerging;    request.family = fallbackFamilies.at(at-1);    engines[at] = QFontDatabase::findFont(script,                                          /*fontprivate*/0,                                          request);    Q_ASSERT(engines[at]);    engines[at]->ref.ref();    engines[at]->fontDef = request;}void QFontEngineMultiQWS::draw(QPaintEngine */*p*/, qreal /*x*/, qreal /*y*/, const QTextItemInt &/*si*/){    qFatal("QFontEngineMultiQWS::draw should never be called!");}

⌨️ 快捷键说明

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