void QFontEngineWin::getCMap()
{
    ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE);
    HDC hdc = shared_dc();
    SelectObject(hdc, hfont);
    bool symb = false;
    if (ttf) {
        cmapTable = getSfntTable(qbswap<quint32>(MAKE_TAG('c', 'm', 'a', 'p')));
        int size = 0;
        cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()),
                       cmapTable.size(), &symb, &size);
    }
    if (!cmap) {
        ttf = false;
        symb = false;
    }
    symbol = symb;
    designToDevice = 1;
    _faceId.index = 0;
    if(cmap) {
        OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
        designToDevice = QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight);
        unitsPerEm = otm->otmEMSquare;
        x_height = (int)otm->otmsXHeight;
        loadKerningPairs(designToDevice);
        _faceId.filename = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFullName)).toLatin1();
        lineWidth = otm->otmsUnderscoreSize;
        fsType = otm->otmfsType;
        free(otm);
    } else {
        unitsPerEm = tm.tmHeight;
    }
}
const unsigned char *QFontEngineS60Extensions::cmap() const
{
    if (!m_cmap) {
        m_cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
        int size = 0;
        m_cmap = QFontEngineS60::getCMap(reinterpret_cast<const uchar *>(m_cmapTable.constData()), m_cmapTable.size(), &m_symbolCMap, &size);
    }
    return m_cmap;
}
Exemple #3
0
const uchar *QSymbianTypeFaceExtras::cmap() const
{
    if (m_cmapTable.isNull()) {
        const QByteArray cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
        int size = 0;
        const uchar *cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>
                (cmapTable.constData()), cmapTable.size(), &m_symbolCMap, &size);
        m_cmapTable = QByteArray(reinterpret_cast<const char *>(cmap), size);
    }
    return reinterpret_cast<const uchar *>(m_cmapTable.constData());
}
bool QFontEngineMac::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
{
    if (flags & QTextEngine::GlyphIndicesOnly) {
        if (!cmap) {
            cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
            int size = 0;
            cmap = getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()), cmapTable.size(), &symbolCMap, &size);
            if (!cmap)
                return false;
        }
        if (symbolCMap) {
            for (int i = 0; i < len; ++i) {
                unsigned int uc = getChar(str, i, len);
                glyphs->glyph = getTrueTypeGlyphIndex(cmap, uc);
                if(!glyphs->glyph && uc < 0x100)
                    glyphs->glyph = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
                glyphs++;
            }
        } else {
            for (int i = 0; i < len; ++i) {
                unsigned int uc = getChar(str, i, len);
                glyphs->glyph = getTrueTypeGlyphIndex(cmap, uc);
                glyphs++;
            }
        }

        *nglyphs = len;
        return true;
    }
    if (!multiEngine)
        return false;

    const bool kashidaRequest = (len == 1 && *str == QChar(0x640));
    if (kashidaRequest && kashidaGlyph.glyph != 0) {
        *glyphs = kashidaGlyph;
        *nglyphs = 1;
        return true;
    }

    bool result = multiEngine->stringToCMap(str, len, glyphs, nglyphs, flags);

    if (result && kashidaRequest) {
        kashidaGlyph = *glyphs;
    }

    return result;
}
Exemple #5
0
QFixed QSymbianTypeFaceExtras::unitsPerEm() const
{
    if (m_unitsPerEm.value() != 0)
        return m_unitsPerEm;
    const QByteArray head = getSfntTable(MAKE_TAG('h', 'e', 'a', 'd'));
    const int unitsPerEmOffset = 18;
    if (head.size() > unitsPerEmOffset + sizeof(quint16)) {
        const uchar* tableData = reinterpret_cast<const uchar*>(head.constData());
        const uchar* unitsPerEm = tableData + unitsPerEmOffset;
        m_unitsPerEm = qFromBigEndian<quint16>(unitsPerEm);
    } else {
        // Bitmap font? Corrupt font?
        // We return -1 and let the QFontEngineS60 return the pixel size.
        m_unitsPerEm = -1;
    }
    return m_unitsPerEm;
}
Exemple #6
0
void QWindowsFontEngine::getCMap()
{
    ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE) || hasCMapTable();

    cffTable = hasCFFTable();

    HDC hdc = m_fontEngineData->hdc;
    SelectObject(hdc, hfont);
    bool symb = false;
    if (ttf) {
        cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
        cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()),
                       cmapTable.size(), &symb, &cmapSize);
    }
    if (!cmap) {
        ttf = false;
        symb = false;
    }
    symbol = symb;
    designToDevice = 1;
    _faceId.index = 0;
    if(cmap) {
        OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
        unitsPerEm = int(otm->otmEMSquare);
        const QFixed unitsPerEmF(unitsPerEm);
        designToDevice = unitsPerEmF / QFixed::fromReal(fontDef.pixelSize);
        x_height = int(otm->otmsXHeight);
        loadKerningPairs(designToDevice);
        _faceId.filename = QFile::encodeName(stringFromOutLineTextMetric(otm, otm->otmpFullName));
        lineWidth = otm->otmsUnderscoreSize;
        fsType = otm->otmfsType;
        free(otm);

    } else {
        unitsPerEm = tm.tmHeight;
    }
}
QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEngine *fontEngine)
    : fd(fileDescriptor), renderingFontEngine(fontEngine)
{
    fontData = 0;
    dataSize = 0;
    fontDef = def;
    cache_cost = 100;
    freetype = 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);
    if (!fontData || fontData == (const uchar *)MAP_FAILED) {
#if defined(DEBUG_FONTENGINE)
        perror("mmap failed");
#endif
        fontData = 0;
        return;
    }

    if (!verifyHeader(fontData, st.st_size)) {
#if defined(DEBUG_FONTENGINE)
        qDebug() << "verifyHeader failed!";
#endif
        return;
    }

    const Header *header = reinterpret_cast<const Header *>(fontData);

    readOnly = (header->lock == 0xffffffff);

    const uchar *data = fontData + sizeof(Header) + qFromBigEndian<quint16>(header->dataSize);
    const uchar *endPtr = fontData + dataSize;
    while (data <= endPtr - 8) {
        quint16 blockTag = readValue<quint16>(data);
        data += 2; // skip padding
        quint32 blockSize = readValue<quint32>(data);

        if (blockTag == CMapBlock) {
            cmapOffset = data - fontData;
            cmapSize = blockSize;
        } else if (blockTag == GMapBlock) {
            glyphMapOffset = data - fontData;
            glyphMapEntries = blockSize / 4;
        } else if (blockTag == GlyphBlock) {
            glyphDataOffset = data - fontData;
            glyphDataSize = blockSize;
        }

        data += blockSize;
    }

    face_id.filename = QFile::encodeName(extractHeaderField(fontData, Tag_FileName).toString());
    face_id.index = extractHeaderField(fontData, Tag_FileIndex).toInt();
#if !defined(QT_NO_FREETYPE)
    freetype = QFreetypeFace::getFace(face_id);
    if (!freetype) {
        QString newPath =
#ifndef QT_NO_SETTINGS
            QLibraryInfo::location(QLibraryInfo::LibrariesPath) +
#endif
                          QLatin1String("/fonts/") +
                          QFileInfo(QFile::decodeName(face_id.filename)).fileName();
        face_id.filename = QFile::encodeName(newPath);
        freetype = QFreetypeFace::getFace(face_id);
    }
    if (freetype) {
        const quint32 qpfTtfRevision = extractHeaderField(fontData, Tag_FontRevision).toUInt();
        uchar data[4];
        uint length = 4;
        bool ok = freetype->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd'), data, &length);
        if (!ok || length != 4
            || qFromBigEndian<quint32>(data) != qpfTtfRevision) {
            freetype->release(face_id);
            freetype = 0;
        }
    }
    if (!cmapOffset && freetype) {
        freetypeCMapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
        externalCMap = reinterpret_cast<const uchar *>(freetypeCMapTable.constData());
        cmapSize = freetypeCMapTable.size();
    }
#endif

    // get the real cmap
    if (cmapOffset) {
        int tableSize = cmapSize;
        const uchar *cmapPtr = getCMap(fontData + cmapOffset, tableSize, &symbol, &cmapSize);
        if (cmapPtr)
            cmapOffset = cmapPtr - fontData;
        else
            cmapOffset = 0;
    } else if (externalCMap) {
        int tableSize = cmapSize;
        externalCMap = getCMap(externalCMap, tableSize, &symbol, &cmapSize);
    }

    // verify all the positions in the glyphMap
    if (glyphMapOffset) {
        const quint32 *gmapPtr = reinterpret_cast<const quint32 *>(fontData + glyphMapOffset);
        for (uint i = 0; i < glyphMapEntries; ++i) {
            quint32 glyphDataPos = qFromBigEndian<quint32>(gmapPtr[i]);
            if (glyphDataPos == 0xffffffff)
                continue;
            if (glyphDataPos >= glyphDataSize) {
                // error
                glyphMapOffset = 0;
                glyphMapEntries = 0;
                break;
            }
        }
    }

#if defined(DEBUG_FONTENGINE)
    if (!isValid())
        qDebug() << "fontData" <<  fontData << "dataSize" << dataSize
                 << "externalCMap" << externalCMap << "cmapOffset" << cmapOffset
                 << "glyphMapOffset" << glyphMapOffset << "glyphDataOffset" << glyphDataOffset
                 << "fd" << fd << "glyphDataSize" << glyphDataSize;
#endif
#if defined(Q_WS_QWS)
    if (isValid() && renderingFontEngine)
        qt_fbdpy->sendFontCommand(QWSFontCommand::StartedUsingFont, QFile::encodeName(fileName));
#endif
}