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

📄 qfontengine.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    QPainter p(&im);    p.setRenderHint(QPainter::Antialiasing);    addGlyphsToPath(&glyph, &pt, 1, &path, 0);    p.setPen(Qt::NoPen);    p.setBrush(Qt::black);    p.drawPath(path);    p.end();    QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);    QVector<QRgb> colors(256);    for (int i=0; i<256; ++i)        colors[i] = qRgba(0, 0, 0, i);    indexed.setColorTable(colors);    for (int y=0; y<im.height(); ++y) {        uchar *dst = (uchar *) indexed.scanLine(y);        uint *src = (uint *) im.scanLine(y);        for (int x=0; x<im.width(); ++x)            dst[x] = qAlpha(src[x]);    }    return indexed;}void QFontEngine::removeGlyphFromCache(glyph_t){}QFontEngine::Properties QFontEngine::properties() const{    Properties p;#ifndef QT_NO_PRINTER    QByteArray psname = QPdf::stripSpecialCharacters(fontDef.family.toUtf8());#else    QByteArray psname = fontDef.family.toUtf8();#endif    psname += '-';    psname += QByteArray::number(fontDef.style);    psname += '-';    psname += QByteArray::number(fontDef.weight);    p.postscriptName = psname;    p.ascent = ascent();    p.descent = descent();    p.leading = leading();    p.emSquare = p.ascent;    p.boundingBox = QRectF(0, -p.ascent.toReal(), maxCharWidth(), (p.ascent + p.descent).toReal());    p.italicAngle = 0;    p.capHeight = p.ascent;    p.lineWidth = lineThickness();    return p;}void QFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics){    *metrics = boundingBox(glyph);    QFixedPoint p;    p.x = 0;    p.y = 0;    addGlyphsToPath(&glyph, &p, 1, path, QFlag(0));}#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS)static inline QFixed kerning(int left, int right, const QFontEngine::KernPair *pairs, int numPairs){    uint left_right = (left << 16) + right;    left = 0, right = numPairs - 1;    while (left <= right) {        int middle = left + ( ( right - left ) >> 1 );	if(pairs[middle].left_right == left_right)            return pairs[middle].adjust;        if (pairs[middle].left_right < left_right)            left = middle + 1;        else            right = middle - 1;    }    return 0;}void QFontEngine::doKerning(int num_glyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const{    int numPairs = kerning_pairs.size();    if(!numPairs)        return;    const KernPair *pairs = kerning_pairs.constData();    if(flags & QTextEngine::DesignMetrics) {        for(int i = 0; i < num_glyphs - 1; ++i)            glyphs[i].advance.x += kerning(glyphs[i].glyph, glyphs[i+1].glyph , pairs, numPairs);    } else {        for(int i = 0; i < num_glyphs - 1; ++i)            glyphs[i].advance.x += qRound(kerning(glyphs[i].glyph, glyphs[i+1].glyph , pairs, numPairs));    }}static inline bool operator<(const QFontEngine::KernPair &p1, const QFontEngine::KernPair &p2){    return p1.left_right < p2.left_right;}void QFontEngine::loadKerningPairs(QFixed scalingFactor){    kerning_pairs.clear();    QByteArray tab = getSfntTable(MAKE_TAG('k', 'e', 'r', 'n'));    if (tab.isEmpty())        return;    const uchar *table = reinterpret_cast<const uchar *>(tab.constData());    unsigned short version = qFromBigEndian<quint16>(table);    if (version != 0) {//        qDebug("wrong version");       return;    }    unsigned short numTables = qFromBigEndian<quint16>(table + 2);    {        int offset = 4;        for(int i = 0; i < numTables; ++i) {            if (offset + 6 > tab.size()) {//                qDebug("offset out of bounds");                goto end;            }            const uchar *header = table + offset;            ushort version = qFromBigEndian<quint16>(header);            ushort length = qFromBigEndian<quint16>(header+2);            ushort coverage = qFromBigEndian<quint16>(header+4);//            qDebug("subtable: version=%d, coverage=%x",version, coverage);            if(version == 0 && coverage == 0x0001) {                if (offset + length > tab.size()) {//                    qDebug("length ouf ot bounds");                    goto end;                }                const uchar *data = table + offset + 6;                ushort nPairs = qFromBigEndian<quint16>(data);                if(nPairs * 6 + 8 > length - 6) {//                    qDebug("corrupt table!");                    // corrupt table                    goto end;                }                int off = 8;                for(int i = 0; i < nPairs; ++i) {                    QFontEngine::KernPair p;                    p.left_right = (((uint)qFromBigEndian<quint16>(data+off)) << 16) + qFromBigEndian<quint16>(data+off+2);                    p.adjust = QFixed(((int)(short)qFromBigEndian<quint16>(data+off+4))) / scalingFactor;                    kerning_pairs.append(p);                    off += 6;                }            }            offset += length;        }    }end:    qSort(kerning_pairs);//    for (int i = 0; i < kerning_pairs.count(); ++i)//        qDebug() << "i" << i << "left_right" << hex << kerning_pairs.at(i).left_right;}#elsevoid QFontEngine::doKerning(int, QGlyphLayout *, QTextEngine::ShaperFlags) const{}#endifint QFontEngine::glyphCount() const{    QByteArray maxpTable = getSfntTable(MAKE_TAG('m', 'a', 'x', 'p'));    if (maxpTable.size() < 6)        return 0;    return qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(maxpTable.constData() + 4));}const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize){    const uchar *header = table;    if (tableSize < 4)        return 0;    const uchar *endPtr = table + tableSize;    // version check    if (qFromBigEndian<quint16>(header) != 0)        return 0;    unsigned short numTables = qFromBigEndian<quint16>(header + 2);    const uchar *maps = table + 4;    if (maps + 8 * numTables > endPtr)        return 0;    int tableToUse = -1;    int score = 0;    for (int n = 0; n < numTables; ++n) {        const quint16 platformId = qFromBigEndian<quint16>(maps + 8 * n);        const quint16 platformSpecificId = qFromBigEndian<quint16>(maps + 8 * n + 2);        switch (platformId) {        case 0: // Unicode            if (score < 4 &&                (platformSpecificId == 0 ||                 platformSpecificId == 2 ||                 platformSpecificId == 3)) {                tableToUse = n;                score = 4;            } else if (score < 3 && platformSpecificId == 1) {                tableToUse = n;                score = 3;	    }            break;        case 1: // Apple            if (score < 2 && platformSpecificId == 0) { // Apple Roman                tableToUse = n;                score = 2;            }            break;        case 3: // Microsoft            switch (platformSpecificId) {            case 0:                if (score < 1) {                    tableToUse = n;                    score = 1;                }                break;            case 1:                if (score < 5) {                    tableToUse = n;                    score = 5;                }                break;            case 0xa:                if (score < 6) {                    tableToUse = n;                    score = 6;                }                break;            default:                break;            }        default:            break;        }    }    if(tableToUse < 0)        return 0;    *isSymbolFont = (score == 1);    unsigned int unicode_table = qFromBigEndian<quint32>(maps + 8*tableToUse + 4);    if (!unicode_table || unicode_table + 8 > tableSize)        return 0;    // get the header of the unicode table    header = table + unicode_table;    unsigned short format = qFromBigEndian<quint16>(header);    unsigned int length;    if(format < 8)        length = qFromBigEndian<quint16>(header + 2);    else        length = qFromBigEndian<quint32>(header + 4);    if (table + unicode_table + length > endPtr)        return 0;    *cmapSize = length;    return table + unicode_table;}quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode){    unsigned short format = qFromBigEndian<quint16>(cmap);    if (format == 0) {        if (unicode < 256)            return (int) *(cmap+6+unicode);    } else if (format == 4) {        /* some fonts come with invalid cmap tables, where the last segment           specified end = start = rangeoffset = 0xffff, delta = 0x0001           Since 0xffff is never a valid Unicode char anyway, we just get rid of the issue           by returning 0 for 0xffff        */        if(unicode >= 0xffff)            return 0;        quint16 segCountX2 = qFromBigEndian<quint16>(cmap + 6);        const unsigned char *ends = cmap + 14;        quint16 endIndex = 0;        int i = 0;        for (; i < segCountX2/2 && (endIndex = qFromBigEndian<quint16>(ends + 2*i)) < unicode; i++);        const unsigned char *idx = ends + segCountX2 + 2 + 2*i;        quint16 startIndex = qFromBigEndian<quint16>(idx);        if (startIndex > unicode)            return 0;        idx += segCountX2;        qint16 idDelta = (qint16)qFromBigEndian<quint16>(idx);        idx += segCountX2;        quint16 idRangeoffset_t = (quint16)qFromBigEndian<quint16>(idx);        quint16 glyphIndex;        if (idRangeoffset_t) {            quint16 id = qFromBigEndian<quint16>(idRangeoffset_t + 2*(unicode - startIndex) + idx);            if (id)                glyphIndex = (idDelta + id) % 0x10000;            else                glyphIndex = 0;        } else {            glyphIndex = (idDelta + unicode) % 0x10000;        }        return glyphIndex;    } else if (format == 12) {        quint32 nGroups = qFromBigEndian<quint32>(cmap + 12);        cmap += 16; // move to start of groups        int left = 0, right = nGroups - 1;        while (left <= right) {            int middle = left + ( ( right - left ) >> 1 );            quint32 startCharCode = qFromBigEndian<quint32>(cmap + 12*middle);            if(unicode < startCharCode)                right = middle - 1;            else {                quint32 endCharCode = qFromBigEndian<quint32>(cmap + 12*middle + 4);                if(unicode <= endCharCode)                    return qFromBigEndian<quint32>(cmap + 12*middle + 8) + unicode - startCharCode;                left = middle + 1;            }        }    } else {        qDebug("cmap table of format %d not implemented", format);    }    return 0;}// ------------------------------------------------------------------// The box font engine// ------------------------------------------------------------------#ifdef Q_WS_WIN#include "qt_windows.h"#endifQFontEngineBox::QFontEngineBox(int size)    : _size(size){    cache_cost = sizeof(QFontEngineBox);#ifdef Q_WS_WIN#ifndef Q_OS_TEMP    hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);#endif    stockFont = true;    ttf = false;    cmap = 0;    script_cache = 0;#endif}QFontEngineBox::~QFontEngineBox(){}bool QFontEngineBox::stringToCMap(const QChar *, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags) const{    if (*nglyphs < len) {        *nglyphs = len;        return false;    }    for (int i = 0; i < len; i++) {        glyphs[i].glyph = 0;        glyphs[i].advance.x = _size;        glyphs[i].advance.y = 0;    }    *nglyphs = len;    return true;}void QFontEngineBox::addOutlineToPath(qreal x, qreal y, const QGlyphLayout *glyphs, int numGlyphs, QPainterPath *path, QTextItem::RenderFlags flags){    if (!numGlyphs)        return;    QVarLengthArray<QFixedPoint> positions;    QVarLengthArray<glyph_t> positioned_glyphs;    QTransform matrix;    matrix.translate(x, y);    getGlyphPositions(glyphs, numGlyphs, matrix, flags, positioned_glyphs, positions);    addGlyphsToPath(positioned_glyphs.data(), positions.data(), positioned_glyphs.size(), path, flags);    int size = qRound(ascent());    QSize s(size - 3, size - 3);    for (int k = 0; k < positions.size(); k++)        path->addRect(QRectF(positions[k].toPointF(), s));}glyph_metrics_t QFontEngineBox::boundingBox(const QGlyphLayout *, int numGlyphs){    glyph_metrics_t overall;    overall.width = _size*numGlyphs;    overall.height = _size;    overall.xoff = overall.width;    return overall;}#if defined(Q_WS_QWS)void QFontEngineBox::draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &ti){    if (!ti.num_glyphs)        return;    int size = qRound(ascent());    QSize s(size - 3, size - 3);    QVarLengthArray<QFixedPoint> positions;    QVarLengthArray<glyph_t> glyphs;    QTransform matrix;    matrix.translate(x, y - size);    ti.fontEngine->getGlyphPositions(ti.glyphs, ti.num_glyphs, matrix, ti.flags, glyphs, positions);    if (glyphs.size() == 0)        return;    QPainter *painter = p->painter();

⌨️ 快捷键说明

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