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

📄 qfontengine_x11.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    }    Glyph *g = new Glyph;    g->linearAdvance = slot->linearHoriAdvance >> 10;    g->width = TRUNC(right - left);    g->height = TRUNC(top - bottom);    g->x = TRUNC(left);    g->y = TRUNC(top);    g->advance = TRUNC(ROUND(slot->advance.x));    g->format = add_to_glyphset ? Format_None : format;    g->data = buffer;    // make sure we delete the old cached glyph    delete glyph_data.value(glyph);    glyph_data[glyph] = g;    return g;}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;}bool QFontEngineFT::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,                                 QTextEngine::ShaperFlags flags) const{    if (*nglyphs < len) {        *nglyphs = len;        return false;    }    bool mirrored = flags & QTextEngine::RightToLeft;    int glyph_pos = 0;    if (freetype->symbol_map) {        FT_Face face = freetype->face;        for ( int i = 0; i < len; ++i ) {            unsigned int uc = getChar(str, i, len);            if (mirrored)                uc = QUnicodeTables::mirroredChar(uc);            glyphs[glyph_pos].glyph = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;            if ( !glyphs[glyph_pos].glyph ) {                glyph_t glyph;                if (FcCharSetHasChar(freetype->charset, uc)) {                redo0:                    glyph = FT_Get_Char_Index(face, uc);                    if (!glyph && (uc == 0xa0 || uc == 0x9)) {                        uc = 0x20;                        goto redo0;                    }                } else {                    FT_Set_Charmap(face, freetype->symbol_map);                    glyph = FT_Get_Char_Index(face, uc);                    FT_Set_Charmap(face, freetype->unicode_map);                }                glyphs[glyph_pos].glyph = glyph;                if (uc < QFreetypeFace::cmapCacheSize)                    freetype->cmapCache[uc] = glyph;            }            ++glyph_pos;        }    } else {        FT_Face face = freetype->face;        for (int i = 0; i < len; ++i) {            unsigned int uc = getChar(str, i, len);            if (mirrored)                uc = QUnicodeTables::mirroredChar(uc);            glyphs[glyph_pos].glyph = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;            if (!glyphs[glyph_pos].glyph && FcCharSetHasChar(freetype->charset, uc)) {            redo:                glyph_t glyph = FT_Get_Char_Index(face, uc);                if (!glyph && (uc == 0xa0 || uc == 0x9)) {                    uc = 0x20;                    goto redo;                }                glyphs[glyph_pos].glyph = glyph;                if (uc < QFreetypeFace::cmapCacheSize)                    freetype->cmapCache[uc] = glyph;            }            ++glyph_pos;        }    }    *nglyphs = glyph_pos;    recalcAdvances(*nglyphs, glyphs, flags);    return true;}void QFontEngineFT::recalcAdvances(int len, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const{    FT_Face face = 0;    if (flags & QTextEngine::DesignMetrics) {        for (int i = 0; i < len; i++) {            Glyph *g = glyph_data.value(glyphs[i].glyph);            if (!g) {                if (!face)                    face = lockFace();                g = loadGlyph(glyphs[i].glyph);            }            // for uncachable glyph, get advance from glyphslot            glyphs[i].advance.x = QFixed::fromFixed(g ? g->linearAdvance : (face->glyph->linearHoriAdvance >> 10));            glyphs[i].advance.y = 0;        }    } else {        for (int i = 0; i < len; i++) {            Glyph *g = glyph_data.value(glyphs[i].glyph);            if (!g) {                if (!face)                    face = lockFace();                g = loadGlyph(glyphs[i].glyph);            }            // for uncachable glyph, get advance from glyphslot            glyphs[i].advance.x = g ? QFixed(g->advance) : QFixed::fromFixed(face->glyph->metrics.horiAdvance);            glyphs[i].advance.y = 0;        }    }    if (face)        unlockFace();}glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout *glyphs, int numGlyphs){    FT_Face face = 0;    glyph_metrics_t overall;    QFixed ymax = 0;    QFixed xmax = 0;    for (int i = 0; i < numGlyphs; i++) {        Glyph *g = glyph_data.value(glyphs[i].glyph);        if (!g) {            if (!face)                face = lockFace();            g = loadGlyph(glyphs[i].glyph);        }        if (g) {            QFixed x = overall.xoff + glyphs[i].offset.x + g->x;            QFixed y = overall.yoff + glyphs[i].offset.y - g->y;            overall.x = qMin(overall.x, x);            overall.y = qMin(overall.y, y);            xmax = qMax(xmax, x + g->width);            ymax = qMax(ymax, y + g->height);            overall.xoff += qRound(g->advance);        } else {            int left  = FLOOR(face->glyph->metrics.horiBearingX);            int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width);            int top    = CEIL(face->glyph->metrics.horiBearingY);            int bottom = FLOOR(face->glyph->metrics.horiBearingY - face->glyph->metrics.height);            QFixed x = overall.xoff + glyphs[i].offset.x - (-TRUNC(left));            QFixed y = overall.yoff + glyphs[i].offset.y - TRUNC(top);            overall.x = qMin(overall.x, x);            overall.y = qMin(overall.y, y);            xmax = qMax(xmax, x + TRUNC(right - left));            ymax = qMax(ymax, y + TRUNC(top - bottom));            overall.xoff += qRound(TRUNC(ROUND(face->glyph->advance.x)));        }    }    overall.height = ymax - overall.y;    overall.width = xmax - overall.x;    if (face)        unlockFace();    return overall;}glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph){    FT_Face face = 0;    glyph_metrics_t overall;    Glyph *g = glyph_data.value(glyph);    if (!g) {        face = lockFace();        g = loadGlyph(glyph);    }    if (g) {        overall.x = g->x;        overall.y = -g->y;        overall.width = g->width;        overall.height = g->height;        overall.xoff = g->advance;    } else {        int left  = FLOOR(face->glyph->metrics.horiBearingX);        int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width);        int top    = CEIL(face->glyph->metrics.horiBearingY);        int bottom = FLOOR(face->glyph->metrics.horiBearingY - face->glyph->metrics.height);        overall.width = TRUNC(right-left);        overall.height = TRUNC(top-bottom);        overall.x = TRUNC(left);        overall.y = -TRUNC(top);        overall.xoff = TRUNC(ROUND(face->glyph->advance.x));    }    if (face)        unlockFace();    return overall;}bool QFontEngineFT::canRender(const QChar *string, int len){    FT_Face face = freetype->face;#if 0    if (_cmap != -1) {        lockFace();        for ( int i = 0; i < len; i++ ) {            unsigned int uc = getChar(string, i, len);            if (!FcCharSetHasChar (_font->charset, uc) && getAdobeCharIndex(face, _cmap, uc) == 0) {                allExist = false;                break;            }        }        unlockFace();    } else#endif    {        for ( int i = 0; i < len; i++ ) {            unsigned int uc = getChar(string, i, len);            if (!FT_Get_Char_Index(face, uc))                    return false;        }    }    return true;}void QFontEngineFT::doKerning(int num_glyphs, QGlyphLayout *g, QTextEngine::ShaperFlags flags) const{    if (!FT_HAS_KERNING(freetype->face))        return;    FT_Face face = lockFace();    uint f = (flags == QTextEngine::DesignMetrics ? FT_KERNING_UNFITTED : FT_KERNING_DEFAULT);    for (int i = 0; i < num_glyphs-1; ++i) {        FT_Vector kerning;        FT_Get_Kerning(face, g[i].glyph, g[i+1].glyph, f, &kerning);        g[i].advance.x += QFixed::fromFixed(kerning.x);        g[i].advance.y += QFixed::fromFixed(kerning.y);    }    unlockFace();}void QFontEngineFT::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs,                                    QPainterPath *path, QTextItem::RenderFlags){    FT_Face face = lockFace();    for (int gl = 0; gl < numGlyphs; gl++) {        FT_UInt glyph = glyphs[gl];        FT_Load_Glyph(face, glyph, FT_LOAD_NO_HINTING|FT_LOAD_NO_BITMAP);        FT_GlyphSlot g = face->glyph;        if (g->format != FT_GLYPH_FORMAT_OUTLINE)            continue;        addGlyphToPath(g, positions[gl], path);    }    unlockFace();}void QFontEngineFT::addOutlineToPath(qreal x, qreal y, const QGlyphLayout *glyphs, int numGlyphs, QPainterPath *path, QTextItem::RenderFlags flags){    if (FT_IS_SCALABLE(freetype->face)) {        QFontEngine::addOutlineToPath(x, y, glyphs, numGlyphs, path, flags);    } else {        addBitmapFontToPath(x, y, glyphs, numGlyphs, path, flags);    }}QFixed QFontEngineFT::ascent() const{    return QFixed::fromFixed(metrics.ascender);}QFixed QFontEngineFT::descent() const{    return QFixed::fromFixed(-metrics.descender + (1<<6));}QFixed QFontEngineFT::leading() const{    return QFixed::fromFixed(metrics.height - metrics.ascender + metrics.descender);}QFixed QFontEngineFT::xHeight() const{    TT_PCLT *pct = (TT_PCLT *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_pclt);    if (pct && pct->xHeight) {        return QFixed(pct->xHeight*freetype->face->size->metrics.y_ppem)/freetype->face->units_per_EM;    }    return QFontEngine::xHeight();}qreal QFontEngineFT::maxCharWidth() const{    return metrics.max_advance >> 6;}static const ushort char_table[] = {        40,        67,        70,        75,        86,        88,        89,        91,        102,        114,        124,        127,        205,        645,        884,        922,        1070,        12386};static const int char_table_entries = sizeof(char_table)/sizeof(ushort);qreal QFontEngineFT::minLeftBearing() const{    if (lbearing == SHRT_MIN)        (void) minRightBearing(); // calculates both    return lbearing.toReal();}qreal QFontEngineFT::minRightBearing() const{    if (rbearing == SHRT_MIN) {        lbearing = rbearing = 0;        const QChar *ch = (const QChar *)char_table;        QGlyphLayout glyphs[char_table_entries];        int ng = char_table_entries;        stringToCMap(ch, char_table_entries, glyphs, &ng, 0);        while (--ng) {            if (glyphs[ng].glyph) {                glyph_metrics_t gi = ((QFontEngineFT *)this)->boundingBox(glyphs[ng].glyph);                lbearing = qMin(lbearing, gi.x);                rbearing = qMin(rbearing, (gi.xoff - gi.x - gi.width));            }        }    }    return rbearing.toReal();}QFixed QFontEngineFT::lineThickness() const{    return line_thickness;}QFixed QFontEngineFT::underlinePosition() const{    return underline_position;}QFontEngine::FaceId QFontEngineFT::faceId() const{    return face_id;}QFontEngine::Properties QFontEngineFT::properties() const{    Properties p = freetype->properties();    if (p.postscriptName.isEmpty()) {        p.postscriptName = fontDef.family.toUtf8();        p.postscriptName.replace(" ", "");    }    return freetype->properties();}void QFontEngineFT::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics){    FT_Face face = lockFace();    FT_Set_Transform(face, 0, 0);    FT_Load_Glyph(face, glyph, FT_LOAD_NO_HINTING|FT_LOAD_NO_BITMAP|FT_LOAD_NO_SCALE);    int left  = face->glyph->metrics.horiBearingX;    int right = face->glyph->metrics.horiBearingX + face->glyph->metrics.width;    int top    = face->glyph->metrics.horiBearingY;    int bottom = face->glyph->metrics.horiBearingY - face->glyph->metrics.height;    QFixedPoint p;    p.x = 0;    p.y = 0;    if (!FT_IS_SCALABLE(freetype->face)) {        metrics->width = QFixed::fromFixed(right-left);        metrics->height = QFixed::fromFixed(top-b

⌨️ 快捷键说明

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