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

📄 qfontengine_ft.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        QFreetypeFace::addBitmapToPath(face->glyph, p, path);    else        QFreetypeFace::addGlyphToPath(face, face->glyph, p, path, face->units_per_EM << 6, face->units_per_EM << 6);    FT_Set_Transform(face, &freetype->matrix, 0);    unlockFace();}static 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::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::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);    }}void QFontEngineFT::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs,                                    QPainterPath *path, QTextItem::RenderFlags){    FT_Face face = lockFace(Unscaled);    for (int gl = 0; gl < numGlyphs; gl++) {        FT_UInt glyph = glyphs[gl];        FT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP);        FT_GlyphSlot g = face->glyph;        if (g->format != FT_GLYPH_FORMAT_OUTLINE)            continue;        QFreetypeFace::addGlyphToPath(face, g, positions[gl], path, xsize, ysize);    }    unlockFace();}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 = QChar::mirroredChar(uc);            glyphs[glyph_pos].glyph = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;            if ( !glyphs[glyph_pos].glyph ) {                glyph_t glyph;#if !defined(QT_NO_FONTCONFIG)                if (FcCharSetHasChar(freetype->charset, uc)) {#else                if (false) {#endif                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 = QChar::mirroredChar(uc);            glyphs[glyph_pos].glyph = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;            if (!glyphs[glyph_pos].glyph#if !defined(QT_NO_FONTCONFIG)                && FcCharSetHasChar(freetype->charset, uc)#endif                ) {            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;    if (flags & QTextEngine::GlyphIndicesOnly)        return true;    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 = defaultGlyphSet.glyph_data.value(glyphs[i].glyph);            if (g) {                glyphs[i].advance.x = QFixed::fromFixed(g->linearAdvance);            } else {                if (!face)                    face = lockFace();                g = loadGlyph(glyphs[i].glyph);                glyphs[i].advance.x = QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10);            }            glyphs[i].advance.y = 0;        }    } else {        for (int i = 0; i < len; i++) {            Glyph *g = defaultGlyphSet.glyph_data.value(glyphs[i].glyph);            if (g) {                glyphs[i].advance.x = QFixed(g->advance);            } else {                if (!face)                    face = lockFace();                g = loadGlyph(glyphs[i].glyph);                glyphs[i].advance.x = 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;    // initialize with line height, we get the same behaviour on all platforms    overall.y = -ascent();    overall.height = ascent() + descent() + 1;    QFixed ymax = 0;    QFixed xmax = 0;    for (int i = 0; i < numGlyphs; i++) {        Glyph *g = defaultGlyphSet.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 = qMax(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 = defaultGlyphSet.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;}QImage QFontEngineFT::alphaMapForGlyph(glyph_t g){    lockFace();    GlyphFormat glyph_format = antialias ? Format_A8 : Format_Mono;    Glyph *glyph = loadGlyph(g, glyph_format);    if (!glyph) {        unlockFace();        return QFontEngine::alphaMapForGlyph(g);    }    const int pitch = antialias ? (glyph->width + 3) & ~3 : ((glyph->width + 31)/32) * 4;    QImage img(glyph->width, glyph->height, antialias ? QImage::Format_Indexed8 : QImage::Format_Mono);    if (antialias) {        QVector<QRgb> colors(256);        for (int i=0; i<256; ++i)            colors[i] = qRgba(0, 0, 0, i);        img.setColorTable(colors);    } else {        QVector<QRgb> colors(2);        colors[0] = qRgba(0, 0, 0, 0);        colors[1] = qRgba(0, 0, 0, 255);        img.setColorTable(colors);    }    Q_ASSERT(img.bytesPerLine() == pitch);    if (glyph->width) {        for (int y = 0; y < glyph->height; ++y)            memcpy(img.scanLine(y), &glyph->data[y * pitch], pitch);    }    unlockFace();    return img;}void QFontEngineFT::removeGlyphFromCache(glyph_t glyph){    delete defaultGlyphSet.glyph_data.take(glyph);}int QFontEngineFT::glyphCount() const{    int count = 0;    FT_Face face = lockFace();    if (face) {        count = face->num_glyphs;        unlockFace();    }    return count;}FT_Face QFontEngineFT::lockFace(Scaling scale) const{    freetype->lock();    FT_Face face = freetype->face;    if (scale == Unscaled) {        FT_Set_Char_Size(face, face->units_per_EM << 6, face->units_per_EM << 6, 0, 0);        freetype->xsize = face->units_per_EM << 6;        freetype->ysize = face->units_per_EM << 6;    } else if (freetype->xsize != xsize || freetype->ysize != ysize) {        FT_Set_Char_Size(face, xsize, ysize, 0, 0);        freetype->xsize = xsize;        freetype->ysize = ysize;    }    if (freetype->matrix.xx != matrix.xx ||        freetype->matrix.yy != matrix.yy ||        freetype->matrix.xy != matrix.xy ||        freetype->matrix.yx != matrix.yx) {        freetype->matrix = matrix;        FT_Set_Transform(face, &freetype->matrix, 0);    }    return face;}void QFontEngineFT::unlockFace() const{    freetype->unlock();}FT_Face QFontEngineFT::non_locked_face() const{    return freetype->face;}QFontEngineFT::QGlyphSet::QGlyphSet()    : id(0){    transformationMatrix.xx = 0x10000;    transformationMatrix.yy = 0x10000;    transformationMatrix.xy = 0;    transformationMatrix.yx = 0;}QFontEngineFT::QGlyphSet::~QGlyphSet(){    qDeleteAll(glyph_data);}unsigned long QFontEngineFT::allocateServerGlyphSet(){    return 0;}void QFontEngineFT::freeServerGlyphSet(unsigned long id){    Q_UNUSED(id);}#endif // QT_NO_FREETYPE

⌨️ 快捷键说明

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