📄 qfontdatabase_x11.cpp
字号:
isZero(tokens[PointSize]) && isZero(tokens[AverageWidth]));}static inline bool isSmoothlyScalable(char **tokens){ return (isZero(tokens[ResolutionX]) && isZero(tokens[ResolutionY]));}static inline bool isFixedPitch(char **tokens){ return (tokens[Spacing][0] == 'm' || tokens[Spacing][0] == 'c' || tokens[Spacing][0] == 'M' || tokens[Spacing][0] == 'C');}/* Fills in a font definition (QFontDef) from an XLFD (X Logical Font Description). Returns true if the the given xlfd is valid.*/bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi){ char *tokens[NFontFields]; QByteArray buffer = xlfd; if (! parseXFontName(buffer.data(), tokens)) return false; capitalize(tokens[Family]); capitalize(tokens[Foundry]); fd->family = QString::fromLatin1(tokens[Family]); QString foundry = QString::fromLatin1(tokens[Foundry]); if (! foundry.isEmpty() && foundry != QString::fromLatin1("*")) fd->family += QString::fromLatin1(" [") + foundry + QString::fromLatin1("]"); if (qstrlen(tokens[AddStyle]) > 0) fd->addStyle = QString::fromLatin1(tokens[AddStyle]); else fd->addStyle.clear(); fd->pointSize = atoi(tokens[PointSize])/10.; fd->styleHint = QFont::AnyStyle; // ### any until we match families char slant = tolower((uchar) tokens[Slant][0]); fd->style = (slant == 'o' ? QFont::StyleOblique : (slant == 'i' ? QFont::StyleItalic : QFont::StyleNormal)); char fixed = tolower((uchar) tokens[Spacing][0]); fd->fixedPitch = (fixed == 'm' || fixed == 'c'); fd->weight = getFontWeight(tokens[Weight]); int r = atoi(tokens[ResolutionY]); fd->pixelSize = atoi(tokens[PixelSize]); // not "0" or "*", or required DPI if (r && fd->pixelSize && r != dpi) { // calculate actual pointsize for display DPI fd->pointSize = qt_pointSize(fd->pixelSize, dpi); } else if (fd->pixelSize == 0 && fd->pointSize) { // calculate pixel size from pointsize/dpi fd->pixelSize = qRound(qt_pixelSize(fd->pointSize, dpi)); } return true;}/* Fills in a font definition (QFontDef) from the font properties in an XFontStruct. Returns true if the QFontDef could be filled with properties from the XFontStruct.*/static bool qt_fillFontDef(XFontStruct *fs, QFontDef *fd, int dpi){ unsigned long value; if (!fs || !XGetFontProperty(fs, XA_FONT, &value)) return false; char *n = XGetAtomName(QX11Info::display(), value); QByteArray xlfd(n); if (n) XFree(n); return qt_fillFontDef(xlfd.toLower(), fd, dpi);}static QtFontStyle::Key getStyle(char ** tokens){ QtFontStyle::Key key; char slant0 = tolower((uchar) tokens[Slant][0]); if (slant0 == 'r') { if (tokens[Slant][1]) { char slant1 = tolower((uchar) tokens[Slant][1]); if (slant1 == 'o') key.style = QFont::StyleOblique; else if (slant1 == 'i') key.style = QFont::StyleItalic; } } else if (slant0 == 'o') key.style = QFont::StyleOblique; else if (slant0 == 'i') key.style = QFont::StyleItalic; key.weight = getFontWeight(tokens[Weight]); if (qstrcmp(tokens[Width], "normal") == 0) { key.stretch = 100; } else if (qstrcmp(tokens[Width], "semi condensed") == 0 || qstrcmp(tokens[Width], "semicondensed") == 0) { key.stretch = 90; } else if (qstrcmp(tokens[Width], "condensed") == 0) { key.stretch = 80; } else if (qstrcmp(tokens[Width], "narrow") == 0) { key.stretch = 60; } return key;}static bool xlfdsFullyLoaded = false;static unsigned char encodingLoaded[numEncodings];static void loadXlfds(const char *reqFamily, int encoding_id){ QFontDatabasePrivate *db = privateDb(); QtFontFamily *fontFamily = reqFamily ? db->family(reqFamily) : 0; // make sure we don't load twice if ((encoding_id == -1 && xlfdsFullyLoaded) || (encoding_id != -1 && encodingLoaded[encoding_id])) return; if (fontFamily && fontFamily->xlfdLoaded) return; int fontCount; // force the X server to give us XLFDs QByteArray xlfd_pattern("-*-"); xlfd_pattern += (reqFamily && reqFamily[0] != '\0') ? reqFamily : "*"; xlfd_pattern += "-*-*-*-*-*-*-*-*-*-*-"; xlfd_pattern += xlfd_for_id(encoding_id); char **fontList = XListFonts(QX11Info::display(), xlfd_pattern, 0xffff, &fontCount); // qDebug("requesting xlfd='%s', got %d fonts", xlfd_pattern.data(), fontCount); char *tokens[NFontFields]; for(int i = 0 ; i < fontCount ; i++) { if (! parseXFontName(fontList[i], tokens)) continue; // get the encoding_id for this xlfd. we need to do this // here, since we can pass -1 to this function to do full // database population *(tokens[CharsetEncoding] - 1) = '-'; int encoding_id = qt_xlfd_encoding_id(tokens[CharsetRegistry]); if (encoding_id == -1) continue; char *familyName = tokens[Family]; capitalize(familyName); char *foundryName = tokens[Foundry]; capitalize(foundryName); QtFontStyle::Key styleKey = getStyle(tokens); bool smooth_scalable = false; bool bitmap_scalable = false; if (isScalable(tokens)) { if (isSmoothlyScalable(tokens)) smooth_scalable = true; else bitmap_scalable = true; } uint pixelSize = atoi(tokens[PixelSize]); uint xpointSize = atoi(tokens[PointSize]); uint xres = atoi(tokens[ResolutionX]); uint yres = atoi(tokens[ResolutionY]); uint avgwidth = atoi(tokens[AverageWidth]); bool fixedPitch = isFixedPitch(tokens); if (avgwidth == 0 && pixelSize != 0) { /* Ignore bitmap scalable fonts that are automatically generated by some X servers. We know they are bitmap scalable because even though they have a specified pixel size, the average width is zero. */ continue; } QtFontFamily *family = fontFamily ? fontFamily : db->family(familyName, true); family->fontFileIndex = -1; QtFontFoundry *foundry = family->foundry(foundryName, true); QtFontStyle *style = foundry->style(styleKey, true); delete [] style->weightName; style->weightName = qstrdup(tokens[Weight]); delete [] style->setwidthName; style->setwidthName = qstrdup(tokens[Width]); if (smooth_scalable) { style->smoothScalable = true; style->bitmapScalable = false; pixelSize = SMOOTH_SCALABLE; } if (!style->smoothScalable && bitmap_scalable) style->bitmapScalable = true; if (!fixedPitch) family->fixedPitch = false; QtFontSize *size = style->pixelSize(pixelSize, true); QtFontEncoding *enc = size->encodingID(encoding_id, xpointSize, xres, yres, avgwidth, true); enc->pitch = *tokens[Spacing]; if (!enc->pitch) enc->pitch = '*'; for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) { if (writingSystems_for_xlfd_encoding[encoding_id][i]) family->writingSystems[i] = QtFontFamily::Supported; else family->writingSystems[i] |= QtFontFamily::UnsupportedXLFD; } } if (!reqFamily) { // mark encoding as loaded if (encoding_id == -1) xlfdsFullyLoaded = true; else encodingLoaded[encoding_id] = true; } XFreeFontNames(fontList);}#ifndef QT_NO_FONTCONFIG#ifndef FC_WIDTH#define FC_WIDTH "width"#endifstatic int getFCWeight(int fc_weight){ int qtweight = QFont::Black; if (fc_weight <= (FC_WEIGHT_LIGHT + FC_WEIGHT_MEDIUM) / 2) qtweight = QFont::Light; else if (fc_weight <= (FC_WEIGHT_MEDIUM + FC_WEIGHT_DEMIBOLD) / 2) qtweight = QFont::Normal; else if (fc_weight <= (FC_WEIGHT_DEMIBOLD + FC_WEIGHT_BOLD) / 2) qtweight = QFont::DemiBold; else if (fc_weight <= (FC_WEIGHT_BOLD + FC_WEIGHT_BLACK) / 2) qtweight = QFont::Bold; return qtweight;}QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &request){ QFontDef fontDef; FcChar8 *value = 0; if (FcPatternGetString(pattern, FC_FAMILY, 0, &value) == FcResultMatch) { fontDef.family = QString::fromUtf8(reinterpret_cast<const char *>(value)); fontDef.family.replace('-', ' '); fontDef.family.replace("/", ""); } double dpi; if (FcPatternGetDouble(pattern, FC_DPI, 0, &dpi) != FcResultMatch) dpi = QX11Info::appDpiY(); double size; if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &size) == FcResultMatch) fontDef.pixelSize = qRound(size); else fontDef.pixelSize = 12; fontDef.pointSize = qt_pointSize(fontDef.pixelSize, qRound(dpi)); /* ### fontDef.styleStrategy fontDef.styleHint */ int weight; if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight) != FcResultMatch) weight = FC_WEIGHT_MEDIUM; fontDef.weight = getFCWeight(weight); int slant; if (FcPatternGetInteger(pattern, FC_SLANT, 0, &slant) != FcResultMatch) slant = FC_SLANT_ROMAN; fontDef.style = (slant == FC_SLANT_ITALIC) ? QFont::StyleItalic : ((slant == FC_SLANT_OBLIQUE) ? QFont::StyleOblique : QFont::StyleNormal); FcBool scalable; if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &scalable) != FcResultMatch) scalable = false; if (scalable) { fontDef.stretch = request.stretch; fontDef.style = request.style; } else { int width; if (FcPatternGetInteger(pattern, FC_WIDTH, 0, &width) == FcResultMatch) fontDef.stretch = width; else fontDef.stretch = 100; } int spacing; if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing) == FcResultMatch) { fontDef.fixedPitch = (spacing >= FC_MONO); fontDef.ignorePitch = false; } else { fontDef.ignorePitch = true; } return fontDef;}static const char *specialLanguages[] = { "en", "he", "ar", "syr", "div", "hi", "bn", "pa", "gu", "or", "ta", "te", "kn", "ml", "si", "th", "lo", "bo", "my", "ko", "km"};enum { SpecialLanguageCount = sizeof(specialLanguages) / sizeof(const char *) };// this could become a list of all languages used for each writing// system, instead of using the single most common language.static const char *languageForWritingSystem[] = { 0, // Any "en", // Latin "el", // Greek "ru", // Cyrillic "hy", // Armenian "he", // Hebrew "ar", // Arabic "syr", // Syriac "div", // Thaana "hi", // Devanagari "bn", // Bengali "pa", // Gurmukhi "gu", // Gujarati "or", // Oriya "ta", // Tamil "te", // Telugu "kn", // Kannada "ml", // Malayalam "si", // Sinhala "th", // Thai "lo", // Lao "bo", // Tibetan "my", // Myanmar "ka", // Georgian "km", // Khmer "zh-cn", // SimplifiedChinese "zh-tw", // TraditionalChinese "ja", // Japanese "ko", // Korean "vi" // Vietnamese};enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };// Unfortunately FontConfig doesn't know about some languages. We have to test these through the// charset. The lists below contain the systems where we need to do this.static const ushort sampleCharForWritingSystem[] = { 0, // Any 0, // Latin 0, // Greek 0, // Cyrillic 0, // Armenian 0, // Hebrew 0, // Arabic 0, // Syriac 0, // Thaana 0, // Devanagari 0, // Bengali 0, // Gurmukhi 0, // Gujarati 0, // Oriya 0, // Tamil 0xc15, // Telugu 0xc95, // Kannada 0xd15, // Malayalam 0xd9a, // Sinhala 0, // Thai 0, // Lao 0, // Tibetan 0x1000, // Myanmar 0, // Georgian 0, // Khmer 0, // SimplifiedChinese 0, // TraditionalChinese 0, // Japanese 0, // Korean 0 // Vietnamese};enum { SampleCharCount = sizeof(sampleCharForWritingSystem) / sizeof(ushort) };static ushort specialChars[] = { 0, // English 0, // Hebrew 0, // Arabic 0, // Syriac 0, // Thaana 0, // Devanagari 0, // Bengali 0, // Gurmukhi 0, // Gujarati 0, // Oriya 0, // Tamil 0xc15, // Telugu 0xc95, // Kannada 0xd15, // Malayalam
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -