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

📄 qfontengine.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    painter->save();    painter->setBrush(Qt::NoBrush);    QPen pen = painter->pen();    pen.setWidthF(lineThickness().toReal());    painter->setPen(pen);    for (int k = 0; k < positions.size(); k++)        painter->drawRect(QRectF(positions[k].toPointF(), s));    painter->restore();}#endifglyph_metrics_t QFontEngineBox::boundingBox(glyph_t){    return glyph_metrics_t(0, _size, _size, _size, _size, 0);}QFixed QFontEngineBox::ascent() const{    return _size;}QFixed QFontEngineBox::descent() const{    return 0;}QFixed QFontEngineBox::leading() const{    QFixed l = _size * QFixed::fromReal(0.15);    return l.ceil();}qreal QFontEngineBox::maxCharWidth() const{    return _size;}#ifdef Q_WS_X11int QFontEngineBox::cmap() const{    return -1;}#endifconst char *QFontEngineBox::name() const{    return "null";}bool QFontEngineBox::canRender(const QChar *, int){    return true;}QFontEngine::Type QFontEngineBox::type() const{    return Box;}// ------------------------------------------------------------------// Multi engine// ------------------------------------------------------------------static inline uchar highByte(glyph_t glyph){ return glyph >> 24; }// strip high byte from glyphstatic inline glyph_t stripped(glyph_t glyph){ return glyph & 0x00ffffff; }QFontEngineMulti::QFontEngineMulti(int engineCount){    engines.fill(0, engineCount);    cache_cost = 0;}QFontEngineMulti::~QFontEngineMulti(){    for (int i = 0; i < engines.size(); ++i) {        QFontEngine *fontEngine = engines.at(i);        if (fontEngine) {            fontEngine->ref.deref();            if (fontEngine->cache_count == 0 && fontEngine->ref == 0)                delete fontEngine;        }    }}bool QFontEngineMulti::stringToCMap(const QChar *str, int len,                                    QGlyphLayout *glyphs, int *nglyphs,                                    QTextEngine::ShaperFlags flags) const{    int ng = *nglyphs;    if (!engine(0)->stringToCMap(str, len, glyphs, &ng, flags))        return false;    int glyph_pos = 0;    for (int i = 0; i < len; ++i) {        bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1                          && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);        if (glyphs[glyph_pos].glyph == 0) {            QGlyphLayout tmp = glyphs[glyph_pos];            for (int x = 1; x < engines.size(); ++x) {                QFontEngine *engine = engines.at(x);                if (!engine) {                    const_cast<QFontEngineMulti *>(this)->loadEngine(x);                    engine = engines.at(x);                }                Q_ASSERT(engine != 0);                if (engine->type() == Box)                    continue;                glyphs[glyph_pos].advance = glyphs[glyph_pos].offset = QFixedPoint();                int num = 2;                engine->stringToCMap(str + i, surrogate ? 2 : 1, glyphs + glyph_pos, &num, flags);                Q_ASSERT(num == 1); // surrogates only give 1 glyph                if (glyphs[glyph_pos].glyph) {                    // set the high byte to indicate which engine the glyph came from                    glyphs[glyph_pos].glyph |= (x << 24);                    break;                }            }            // ensure we use metrics from the 1st font when we use the fallback image.            if (!glyphs[glyph_pos].glyph)                glyphs[glyph_pos] = tmp;        }        if (surrogate)            ++i;        ++glyph_pos;    }    *nglyphs = ng;    return true;}glyph_metrics_t QFontEngineMulti::boundingBox(const QGlyphLayout *glyphs_const, int numGlyphs){    if (numGlyphs <= 0)        return glyph_metrics_t();    glyph_metrics_t overall;    QGlyphLayout *glyphs = const_cast<QGlyphLayout *>(glyphs_const);    int which = highByte(glyphs[0].glyph);    int start = 0;    int end, i;    for (end = 0; end < numGlyphs; ++end) {        const int e = highByte(glyphs[end].glyph);        if (e == which)            continue;        // set the high byte to zero        for (i = start; i < end; ++i)            glyphs[i].glyph = stripped(glyphs[i].glyph);        // merge the bounding box for this run        const glyph_metrics_t gm = engine(which)->boundingBox(glyphs + start, end - start);        overall.x = qMin(overall.x, gm.x);        overall.y = qMin(overall.y, gm.y);        overall.width = overall.xoff + gm.width;        overall.height = qMax(overall.height + overall.y, gm.height + gm.y) -                         qMin(overall.y, gm.y);        overall.xoff += gm.xoff;        overall.yoff += gm.yoff;        // reset the high byte for all glyphs        const int hi = which << 24;        for (i = start; i < end; ++i)            glyphs[i].glyph = hi | glyphs[i].glyph;        // change engine        start = end;        which = e;    }    // set the high byte to zero    for (i = start; i < end; ++i)        glyphs[i].glyph = stripped(glyphs[i].glyph);    // merge the bounding box for this run    const glyph_metrics_t gm = engine(which)->boundingBox(glyphs + start, end - start);    overall.x = qMin(overall.x, gm.x);    overall.y = qMin(overall.y, gm.y);    overall.width = overall.xoff + gm.width;    overall.height = qMax(overall.height + overall.y, gm.height + gm.y) -                     qMin(overall.y, gm.y);    overall.xoff += gm.xoff;    overall.yoff += gm.yoff;    // reset the high byte for all glyphs    const int hi = which << 24;    for (i = start; i < end; ++i)        glyphs[i].glyph = hi | glyphs[i].glyph;    return overall;}void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout *glyphs_const, int numGlyphs,                                        QPainterPath *path, QTextItem::RenderFlags flags){    if (numGlyphs <= 0)        return;    QGlyphLayout *glyphs = const_cast<QGlyphLayout *>(glyphs_const);    int which = highByte(glyphs[0].glyph);    int start = 0;    int end, i;    if (flags & QTextItem::RightToLeft) {        for (int gl = 0; gl < numGlyphs; gl++) {            x += glyphs[gl].advance.x.toReal();            y += glyphs[gl].advance.y.toReal();        }    }    for (end = 0; end < numGlyphs; ++end) {        const int e = highByte(glyphs[end].glyph);        if (e == which)            continue;        if (flags & QTextItem::RightToLeft) {            for (i = start; i < end; ++i) {                x -= glyphs[i].advance.x.toReal();                y -= glyphs[i].advance.y.toReal();            }        }        // set the high byte to zero        for (i = start; i < end; ++i)            glyphs[i].glyph = stripped(glyphs[i].glyph);        engine(which)->addOutlineToPath(x, y, glyphs + start, end - start, path, flags);        // reset the high byte for all glyphs and update x and y        const int hi = which << 24;        for (i = start; i < end; ++i)            glyphs[i].glyph = hi | glyphs[i].glyph;        if (!(flags & QTextItem::RightToLeft)) {            for (i = start; i < end; ++i) {                x += glyphs[i].advance.x.toReal();                y += glyphs[i].advance.y.toReal();            }        }        // change engine        start = end;        which = e;    }    if (flags & QTextItem::RightToLeft) {        for (i = start; i < end; ++i) {            x -= glyphs[i].advance.x.toReal();            y -= glyphs[i].advance.y.toReal();        }    }    // set the high byte to zero    for (i = start; i < end; ++i)        glyphs[i].glyph = stripped(glyphs[i].glyph);    engine(which)->addOutlineToPath(x, y, glyphs + start, end - start, path, flags);    // reset the high byte for all glyphs    const int hi = which << 24;    for (i = start; i < end; ++i)        glyphs[i].glyph = hi | glyphs[i].glyph;}void QFontEngineMulti::recalcAdvances(int numGlyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const{    if (numGlyphs <= 0)        return;    int which = highByte(glyphs[0].glyph);    int start = 0;    int end, i;    for (end = 0; end < numGlyphs; ++end) {        const int e = highByte(glyphs[end].glyph);        if (e == which)            continue;        // set the high byte to zero        for (i = start; i < end; ++i)            glyphs[i].glyph = stripped(glyphs[i].glyph);        engine(which)->recalcAdvances(end - start, glyphs + start, flags);        // reset the high byte for all glyphs and update x and y        const int hi = which << 24;        for (i = start; i < end; ++i)            glyphs[i].glyph = hi | glyphs[i].glyph;        // change engine        start = end;        which = e;    }    // set the high byte to zero    for (i = start; i < end; ++i)        glyphs[i].glyph = stripped(glyphs[i].glyph);    engine(which)->recalcAdvances(end - start, glyphs + start, flags);    // reset the high byte for all glyphs    const int hi = which << 24;    for (i = start; i < end; ++i)        glyphs[i].glyph = hi | glyphs[i].glyph;}void QFontEngineMulti::doKerning(int numGlyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const{    if (numGlyphs <= 0)        return;    int which = highByte(glyphs[0].glyph);    int start = 0;    int end, i;    for (end = 0; end < numGlyphs; ++end) {        const int e = highByte(glyphs[end].glyph);        if (e == which)            continue;        // set the high byte to zero        for (i = start; i < end; ++i)            glyphs[i].glyph = stripped(glyphs[i].glyph);        engine(which)->doKerning(end - start, glyphs + start, flags);        // reset the high byte for all glyphs and update x and y        const int hi = which << 24;        for (i = start; i < end; ++i)            glyphs[i].glyph = hi | glyphs[i].glyph;        // change engine        start = end;        which = e;    }    // set the high byte to zero    for (i = start; i < end; ++i)        glyphs[i].glyph = stripped(glyphs[i].glyph);    engine(which)->doKerning(end - start, glyphs + start, flags);    // reset the high byte for all glyphs    const int hi = which << 24;    for (i = start; i < end; ++i)        glyphs[i].glyph = hi | glyphs[i].glyph;}glyph_metrics_t QFontEngineMulti::boundingBox(glyph_t glyph){    const int which = highByte(glyph);    Q_ASSERT(which < engines.size());    return engine(which)->boundingBox(stripped(glyph));}QFixed QFontEngineMulti::ascent() const{ return engine(0)->ascent(); }QFixed QFontEngineMulti::descent() const{ return engine(0)->descent(); }QFixed QFontEngineMulti::leading() const{    return engine(0)->leading();}QFixed QFontEngineMulti::xHeight() const{    return engine(0)->xHeight();}QFixed QFontEngineMulti::averageCharWidth() const{    return engine(0)->averageCharWidth();}QFixed QFontEngineMulti::lineThickness() const{    return engine(0)->lineThickness();}QFixed QFontEngineMulti::underlinePosition() const{    return engine(0)->underlinePosition();}qreal QFontEngineMulti::maxCharWidth() const{    return engine(0)->maxCharWidth();}qreal QFontEngineMulti::minLeftBearing() const{    return engine(0)->minLeftBearing();}qreal QFontEngineMulti::minRightBearing() const{    return engine(0)->minRightBearing();}bool QFontEngineMulti::canRender(const QChar *string, int len){    if (engine(0)->canRender(string, len))        return true;    QVarLengthArray<QGlyphLayout, 256> glyphs(len);    int nglyphs = len;    if (stringToCMap(string, len, glyphs.data(), &nglyphs, QTextEngine::GlyphIndicesOnly) == false) {        glyphs.resize(nglyphs);        stringToCMap(string, len, glyphs.data(), &nglyphs, QTextEngine::GlyphIndicesOnly);    }    bool allExist = true;    for (int i = 0; i < nglyphs; i++) {        if (!glyphs[i].glyph) {            allExist = false;            break;        }    }    return allExist;}QFontEngine *QFontEngineMulti::engine(int at) const{    Q_ASSERT(at < engines.size());    return engines.at(at);}

⌨️ 快捷键说明

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