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

📄 qfontengine_x11.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    overall.height = ymax - overall.y;    overall.width = xmax - overall.x;    return overall;}glyph_metrics_t QFontEngineXLFD::boundingBox(glyph_t glyph){    glyph_metrics_t gm;    XCharStruct *xcs = charStruct(_fs, glyph);    if (xcs) {        gm = glyph_metrics_t(xcs->lbearing, -xcs->ascent, xcs->rbearing- xcs->lbearing, xcs->ascent + xcs->descent,                              xcs->width, 0);    } else {        QFixed size = ascent();        gm = glyph_metrics_t(0, size, size, size, size, 0);    }    return gm;}QFixed QFontEngineXLFD::ascent() const{    return _fs->ascent;}QFixed QFontEngineXLFD::descent() const{    return (_fs->descent-1);}QFixed QFontEngineXLFD::leading() const{    QFixed l = QFixed(qMin<int>(_fs->ascent, _fs->max_bounds.ascent)                      + qMin<int>(_fs->descent, _fs->max_bounds.descent)) * QFixed::fromReal(0.15);    return l.ceil();}qreal QFontEngineXLFD::maxCharWidth() const{    return _fs->max_bounds.width;}// Loads the font for the specified scriptstatic inline int maxIndex(XFontStruct *f) {    return (((f->max_byte1 - f->min_byte1) *             (f->max_char_or_byte2 - f->min_char_or_byte2 + 1)) +            f->max_char_or_byte2 - f->min_char_or_byte2);}qreal QFontEngineXLFD::minLeftBearing() const{    if (lbearing == SHRT_MIN) {        if (_fs->per_char) {            XCharStruct *cs = _fs->per_char;            int nc = maxIndex(_fs) + 1;            int mx = cs->lbearing;            for (int c = 1; c < nc; c++) {                // ignore the bearings for characters whose ink is                // completely outside the normal bounding box                if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||                    (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))                    continue;                int nmx = cs[c].lbearing;                if (nmx < mx)                    mx = nmx;            }            ((QFontEngineXLFD *)this)->lbearing = mx;        } else            ((QFontEngineXLFD *)this)->lbearing = _fs->min_bounds.lbearing;    }    return lbearing;}qreal QFontEngineXLFD::minRightBearing() const{    if (rbearing == SHRT_MIN) {        if (_fs->per_char) {            XCharStruct *cs = _fs->per_char;            int nc = maxIndex(_fs) + 1;            int mx = cs->rbearing;            for (int c = 1; c < nc; c++) {                // ignore the bearings for characters whose ink is                // completely outside the normal bounding box                if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||                    (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))                    continue;                int nmx = cs[c].rbearing;                if (nmx < mx)                    mx = nmx;            }            ((QFontEngineXLFD *)this)->rbearing = mx;        } else            ((QFontEngineXLFD *)this)->rbearing = _fs->min_bounds.rbearing;    }    return rbearing;}const char *QFontEngineXLFD::name() const{    return _name;}bool QFontEngineXLFD::canRender(const QChar *string, int len){    QVarLengthArray<QGlyphLayout, 256> glyphs(len);    int nglyphs = len;    if (stringToCMap(string, len, glyphs.data(), &nglyphs, 0) == false) {        glyphs.resize(nglyphs);        stringToCMap(string, len, glyphs.data(), &nglyphs, 0);    }    bool allExist = true;    for (int i = 0; i < nglyphs; i++) {        if (!glyphs[i].glyph || !charStruct(_fs, glyphs[i].glyph)) {            allExist = false;            break;        }    }    return allExist;}void QFontEngineXLFD::addOutlineToPath(qreal x, qreal y, const QGlyphLayout *glyphs, int numGlyphs, QPainterPath *path, QTextItem::RenderFlags flags){    addBitmapFontToPath(x, y, glyphs, numGlyphs, path, flags);}QFontEngine::FaceId QFontEngineXLFD::faceId() const{#ifndef QT_NO_FREETYPE    if (face_id.index == -1) {        face_id = ::fontFile(_name, &freetype, &synth);        if (_codec)            face_id.encoding = _codec->mibEnum();        if (freetype)            const_cast<QFontEngineXLFD *>(this)->fsType = freetype->fsType();    }#endif    return face_id;}QFontEngine::Properties QFontEngineXLFD::properties() const{    if (face_id.index == -1)        (void)faceId();#ifndef QT_NO_FREETYPE    if (freetype)        return freetype->properties();#endif    return Properties();}#ifndef QT_NO_FREETYPEvoid QFontEngineXLFD::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics){    if (face_id.index == -1)        (void)faceId();    if (!freetype)        return;    freetype->lock();    FT_Face face = freetype->face;    FT_Set_Transform(face, 0, 0);    glyph = glyphIndexToFreetypeGlyphIndex(glyph);    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-bottom);        metrics->x = QFixed::fromFixed(left);        metrics->y = QFixed::fromFixed(-top);        metrics->xoff = QFixed::fromFixed(face->glyph->advance.x);        ::addBitmapToPath(face->glyph, p, path);    } else {        metrics->width = right-left;        metrics->height = top-bottom;        metrics->x = left;        metrics->y = -top;        metrics->xoff = face->glyph->advance.x;        ::addGlyphToPath(face->glyph, p, path, true /* no_scale */);    }    FT_Set_Transform(face, &freetype->matrix, 0);    freetype->unlock();}#endif // QT_NO_FREETYPEQByteArray QFontEngineXLFD::getSfntTable(uint tag) const{#ifndef QT_NO_FREETYPE    if (face_id.index == -1)        (void)faceId();    if (!freetype)        return QByteArray();    return freetype->getSfntTable(tag);#else    Q_UNUSED(tag);    return QByteArray();#endif}int QFontEngineXLFD::synthesized() const{    return synth;}#ifndef QT_NO_FREETYPEFT_Face QFontEngineXLFD::non_locked_face() const{    return freetype ? freetype->face : 0;}uint QFontEngineXLFD::toUnicode(glyph_t g) const{    if (_codec) {        QTextCodec::ConverterState state;        state.flags = QTextCodec::ConvertInvalidToNull;        uchar data[2];        int l = 1;        if (g > 255) {            data[0] = (g >> 8);            data[1] = (g & 255);            l = 2;        } else {            data[0] = g;        }        QString s = _codec->toUnicode((char *)data, l, &state);        Q_ASSERT(s.length() == 1);        g = s.at(0).unicode();    }    return g;}glyph_t QFontEngineXLFD::glyphIndexToFreetypeGlyphIndex(glyph_t g) const{    return FT_Get_Char_Index(freetype->face, toUnicode(g));}#endif#ifndef QT_NO_FONTCONFIG// ------------------------------------------------------------------// Multi FT engine// ------------------------------------------------------------------QFontEngineMultiFT::QFontEngineMultiFT(FcFontSet *fs, int s, const QFontDef &request)    : QFontEngineMulti(fs->nfont), fontSet(fs), screen(s){    fontDef = request;    loadEngine(0);    fontDef = engines[0]->fontDef;    cache_cost = 100;}QFontEngineMultiFT::~QFontEngineMultiFT(){    FcFontSetDestroy(fontSet);}void QFontEngineMultiFT::loadEngine(int at){    Q_ASSERT(at < engines.size());    Q_ASSERT(engines.at(at) == 0);    FcPattern *pattern = fontSet->fonts[at];    extern QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &);    QFontDef fontDef = qt_FcPatternToQFontDef(fontSet->fonts[at], this->fontDef);    // note: we use -1 for the script to make sure that we keep real    // FT engines separate from Multi engines in the font cache    QFontCache::Key key(fontDef, -1, screen);    QFontEngine *fontEngine = QFontCache::instance->findEngine(key);    if (!fontEngine) {        FcConfigSubstitute(0, pattern, FcMatchPattern);        FcDefaultSubstitute(pattern);        FcResult res;        FcPattern *match = FcFontMatch(0, pattern, &res);        QFontEngineFT *engine = new QFontEngineFT(match, fontDef, screen);        if (engine->invalid())            delete engine;        else            fontEngine = engine;        if (!fontEngine) {            fontEngine = new QFontEngineBox(fontDef.pixelSize);            fontEngine->fontDef = fontDef;        }        QFontCache::instance->insertEngine(key, fontEngine);    }    fontEngine->ref.ref();    engines[at] = fontEngine;}// ------------------------------------------------------------------// FT font engine// ------------------------------------------------------------------QFontEngineFT::Glyph::~Glyph(){    delete [] data;}static QFontEngine::FaceId face_id(FcPattern *pattern){    char *file_name;    FcPatternGetString(pattern, FC_FILE, 0, (FcChar8 **)&file_name);    int face_index;    if (!FcPatternGetInteger(pattern, FC_INDEX, 0, &face_index))        face_index = 0;    QFontEngine::FaceId face_id;    face_id.filename = file_name;    face_id.index = face_index;    return face_id;}QFontEngineFT::QFontEngineFT(FcPattern *pattern, const QFontDef &fd, int screen){    cache_cost = 100;    fontDef = fd;    _pattern = pattern;    transform = false;    matrix.xx = 0x10000;    matrix.yy = 0x10000;    matrix.xy = 0;    matrix.yx = 0;//     FcPatternPrint(pattern);    antialias = X11->fc_antialias;    FcBool b;    if (FcPatternGetBool(pattern, FC_ANTIALIAS, 0, &b) == FcResultMatch)        antialias = b;    if (FcPatternGetInteger(pattern, FC_RGBA, 0, &subpixel) == FcResultNoMatch)        subpixel = X11->screens[screen].subpixel;    if (!antialias || subpixel == FC_RGBA_UNKNOWN)        subpixel = FC_RGBA_NONE;#ifdef FC_HINT_STYLE    if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)	hint_style = X11->fc_hint_style;#endif    autohint = false;#ifdef FC_AUTOHINT    if (FcPatternGetBool(pattern, FC_AUTOHINT, 0, &b) == FcResultMatch)        autohint = b;#endif    face_id = ::face_id(pattern);    freetype = QFreetypeFace::getFace(face_id);    if (!freetype->charset) {        FcCharSet *cs;        FcPatternGetCharSet (pattern, FC_CHARSET, 0, &cs);        freetype->charset = FcCharSetCopy(cs);    }    lbearing = rbearing = SHRT_MIN;    freetype->computeSize(fontDef, &xsize, &ysize);    outline_drawing = xsize > (64<<6) || ysize > (64<<6);    FT_Face face = lockFace();    //underline metrics    if (FT_IS_SCALABLE(face)) {        line_thickness =  QFixed::fromFixed(FT_MulFix(face->underline_thickness, face->size->metrics.y_scale));        underline_position = QFixed::fromFixed(-FT_MulFix(face->underline_position, face->size->metrics.y_scale));        bool fake_oblique = (fontDef.style != QFont::StyleNormal) && !(face->style_flags & FT_STYLE_FLAG_ITALIC);        if (fake_oblique)            matrix.xy = 0x10000*3/10;        FT_Set_Transform(face, &matrix, 0);        if (fake_oblique)            transform = true;    } else {        // copied from QFontEngineQPF        // ad hoc algorithm        int score = fontDef.weight * fontDef.pixelSize;        line_thickness = score / 700;        // looks better with thicker line for small pointsizes        if (line_thickness < 2 && score >= 1050)            line_thickness = 2;        underline_position =  ((line_thickness * 2) + 3) / 6;    }    if (line_thickness < 1)        line_thickness = 1;

⌨️ 快捷键说明

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