📄 qfontdatabase_x11.cpp
字号:
}static const char * xlfd_for_id(int id){ // special case: -1 returns the "*-*" encoding, allowing us to do full // database population in a single X server round trip. if (id < 0 || id > numEncodings) return "*-*"; return xlfd_encoding[id].name;}enum XLFDFieldNames { Foundry, Family, Weight, Slant, Width, AddStyle, PixelSize, PointSize, ResolutionX, ResolutionY, Spacing, AverageWidth, CharsetRegistry, CharsetEncoding, NFontFields};// Splits an X font name into fields separated by '-'static bool parseXFontName(char *fontName, char **tokens){ if (! fontName || fontName[0] == '0' || fontName[0] != '-') { tokens[0] = 0; return false; } int i; ++fontName; for (i = 0; i < NFontFields && fontName && fontName[0]; ++i) { tokens[i] = fontName; for (;; ++fontName) { if (*fontName == '-') break; if (! *fontName) { fontName = 0; break; } } if (fontName) *fontName++ = '\0'; } if (i < NFontFields) { for (int j = i ; j < NFontFields; ++j) tokens[j] = 0; return false; } return true;}static inline bool isZero(char *x){ return (x[0] == '0' && x[1] == 0);}static inline bool isScalable(char **tokens){ return (isZero(tokens[PixelSize]) && 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->styleStrategy |= QFont::NoAntialias; 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(QLatin1String(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(QLatin1String(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(QLatin1String(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(QLatin1String(familyName), true); family->fontFileIndex = -1; family->symbol_checked = true; QtFontFoundry *foundry = family->foundry(QLatin1String(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; } } 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; fontDef.styleStrategy = request.styleStrategy; FcChar8 *value = 0; if (FcPatternGetString(pattern, FC_FAMILY, 0, &value) == FcResultMatch) { fontDef.family = QString::fromUtf8(reinterpret_cast<const char *>(value)); fontDef.family.replace(QLatin1Char('-'), QLatin1Char(' ')); fontDef.family.remove(QLatin1Char('/')); } double dpi; if (FcPatternGetDouble(pattern, FC_DPI, 0, &dpi) != FcResultMatch) { if (X11->display) dpi = QX11Info::appDpiY(); else dpi = 96; // #### } 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.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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -