📄 qfontengine_x11.cpp
字号:
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; 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); if (!FT_IS_SCALABLE(freetype->face)) 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); freetype->unlock();#endif // QT_NO_FREETYPE}QByteArray 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// ------------------------------------------------------------------static QFontEngine *engineForPattern(FcPattern *pattern, const QFontDef &request, int screen){ FcResult res; FcPattern *match = FcFontMatch(0, pattern, &res); QFontEngineX11FT *engine = new QFontEngineX11FT(match, request, screen); if (!engine->invalid()) return engine; delete engine; QFontEngine *fe = new QFontEngineBox(request.pixelSize); fe->fontDef = request; return fe;}QFontEngineMultiFT::QFontEngineMultiFT(QFontEngine *fe, FcPattern *p, int s, const QFontDef &req) : QFontEngineMulti(2), request(req), pattern(p), fontSet(0), screen(s){ engines[0] = fe; engines.at(0)->ref.ref(); fontDef = engines[0]->fontDef; cache_cost = 100;}QFontEngineMultiFT::~QFontEngineMultiFT(){ FcPatternDestroy(pattern); if (fontSet) FcFontSetDestroy(fontSet);}void QFontEngineMultiFT::loadEngine(int at){ extern void qt_addPatternProps(FcPattern *pattern, int screen, int script, const QFontDef &request); extern QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &); extern FcFontSet *qt_fontSetForPattern(FcPattern *pattern, const QFontDef &request); Q_ASSERT(at > 0); if (!fontSet) { fontSet = qt_fontSetForPattern(pattern, request); engines.resize(fontSet->nfont); } Q_ASSERT(at < engines.size()); Q_ASSERT(engines.at(at) == 0); FcPattern *pattern = FcPatternDuplicate(fontSet->fonts[at]); qt_addPatternProps(pattern, screen, QUnicodeTables::Common, request); QFontDef fontDef = qt_FcPatternToQFontDef(pattern, this->request); // 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); fontEngine = engineForPattern(pattern, request, screen); FcPatternDestroy(pattern); QFontCache::instance->insertEngine(key, fontEngine); } fontEngine->ref.ref(); engines[at] = fontEngine;}// ------------------------------------------------------------------// X11 FT engine// ------------------------------------------------------------------Q_GUI_EXPORT void qt_x11ft_convert_pattern(FcPattern *pattern, QByteArray *file_name, int *index, bool *antialias){ FcChar8 *fileName; FcPatternGetString(pattern, FC_FILE, 0, &fileName); *file_name = (const char *)fileName; if (!FcPatternGetInteger(pattern, FC_INDEX, 0, index)) index = 0; FcBool b; if (FcPatternGetBool(pattern, FC_ANTIALIAS, 0, &b) == FcResultMatch) *antialias = b;}QFontEngineX11FT::QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen) : QFontEngineFT(fd){// FcPatternPrint(pattern); bool antialias = X11->fc_antialias; QByteArray file_name; int face_index; qt_x11ft_convert_pattern(pattern, &file_name, &face_index, &antialias); QFontEngine::FaceId face_id; face_id.filename = file_name; face_id.index = face_index; canUploadGlyphsToServer = true; subpixelType = Subpixel_None; if (antialias) { int subpixel = 0; if (FcPatternGetInteger(pattern, FC_RGBA, 0, &subpixel) == FcResultNoMatch && X11->display) subpixel = X11->screens[screen].subpixel; if (!antialias || subpixel == FC_RGBA_UNKNOWN) subpixel = FC_RGBA_NONE; switch (subpixel) { case FC_RGBA_NONE: subpixelType = Subpixel_None; break; case FC_RGBA_RGB: subpixelType = Subpixel_RGB; break; case FC_RGBA_BGR: subpixelType = Subpixel_BGR; break; case FC_RGBA_VRGB: subpixelType = Subpixel_VRGB; break; case FC_RGBA_VBGR: subpixelType = Subpixel_VBGR; break; default: break; } }#ifdef FC_HINT_STYLE { int hint_style = 0; if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch) hint_style = X11->fc_hint_style; if (hint_style == FC_HINT_NONE) default_load_flags |= FT_LOAD_NO_HINTING; else if (hint_style < FC_HINT_FULL) default_load_flags |= FT_LOAD_TARGET_LIGHT; }#endif#if defined(FC_AUTOHINT) && defined(FT_LOAD_FORCE_AUTOHINT) { bool autohint = false; FcBool b; if (FcPatternGetBool(pattern, FC_AUTOHINT, 0, &b) == FcResultMatch) autohint = b; if (autohint) default_load_flags |= FT_LOAD_FORCE_AUTOHINT; }#endif GlyphFormat defaultFormat = Format_None;#ifndef QT_NO_XRENDER if (X11->use_xrender) { int format = PictStandardA8; if (!antialias) format = PictStandardA1; else if (subpixelType == Subpixel_RGB || subpixelType == Subpixel_BGR || subpixelType == Subpixel_VRGB || subpixelType == Subpixel_VBGR) format = PictStandardARGB32; xglyph_format = format; if (subpixelType != QFontEngineFT::Subpixel_None) defaultFormat = Format_A32; else if (antialias) defaultFormat = Format_A8; else defaultFormat = Format_Mono; }#endif if (!init(face_id, antialias, defaultFormat)) { FcPatternDestroy(pattern); return; } if (!freetype->charset) { FcCharSet *cs; FcPatternGetCharSet (pattern, FC_CHARSET, 0, &cs); freetype->charset = FcCharSetCopy(cs); } FcPatternDestroy(pattern);}QFontEngineX11FT::~QFontEngineX11FT(){ freeGlyphSets();}unsigned long QFontEngineX11FT::allocateServerGlyphSet(){#ifndef QT_NO_XRENDER if (!X11->use_xrender) return 0; return XRenderCreateGlyphSet(X11->display, XRenderFindStandardFormat(X11->display, xglyph_format));#else return 0;#endif}void QFontEngineX11FT::freeServerGlyphSet(unsigned long id){#ifndef QT_NO_XRENDER if (!id) return; XRenderFreeGlyphSet(X11->display, id);#endif}bool QFontEngineX11FT::uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *g, GlyphInfo *info, int glyphDataSize) const{#ifndef QT_NO_XRENDER if (g->format == Format_Mono) { /* * swap bit order around; FreeType is always MSBFirst */ if (BitmapBitOrder(X11->display) != MSBFirst) { unsigned char *line = g->data; int i = glyphDataSize; while (i--) { unsigned char c; c = *line; c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55); c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33); c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f); *line++ = c; } } } ::Glyph xglyph = glyphid; XRenderAddGlyphs (X11->display, set->id, &xglyph, info, 1, (const char *)g->data, glyphDataSize); delete [] g->data; g->data = 0; g->format = Format_None; g->uploadedToServer = true; return true;#else return false;#endif}#endif // QT_NO_FONTCONFIG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -