static void GetTkFontAttributes( XftFont *ftFont, TkFontAttributes *faPtr) { const char *family = "Unknown"; const char *const *familyPtr = &family; int weight, slant, size, pxsize; double ptsize; (void) XftPatternGetString(ftFont->pattern, XFT_FAMILY, 0, familyPtr); if (XftPatternGetDouble(ftFont->pattern, XFT_SIZE, 0, &ptsize) == XftResultMatch) { size = (int) ptsize; } else if (XftPatternGetInteger(ftFont->pattern, XFT_PIXEL_SIZE, 0, &pxsize) == XftResultMatch) { size = -pxsize; } else { size = 12; } if (XftPatternGetInteger(ftFont->pattern, XFT_WEIGHT, 0, &weight) != XftResultMatch) { weight = XFT_WEIGHT_MEDIUM; } if (XftPatternGetInteger(ftFont->pattern, XFT_SLANT, 0, &slant) != XftResultMatch) { slant = XFT_SLANT_ROMAN; } #if DEBUG_FONTSEL printf("family %s size %d weight %d slant %d\n", family, size, weight, slant); #endif /* DEBUG_FONTSEL */ faPtr->family = Tk_GetUid(family); faPtr->size = size; faPtr->weight = (weight > XFT_WEIGHT_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL; faPtr->slant = (slant > XFT_SLANT_ROMAN) ? TK_FS_ITALIC : TK_FS_ROMAN; faPtr->underline = 0; faPtr->overstrike = 0; }
JBoolean JXFontManager::GetFontSizes ( const JCharacter* name, JSize* minSize, JSize* maxSize, JArray<JSize>* sizeList ) const { *minSize = *maxSize = 0; sizeList->RemoveAll(); sizeList->SetCompareFunction(JCompareSizes); sizeList->SetSortOrder(JOrderedSetT::kSortAscending); #ifdef _J_USE_XFT XftFontSet* fs = XftListFonts(*itsDisplay, DefaultScreen((Display*)*itsDisplay), XFT_FAMILY, XftTypeString, name, 0, XFT_SIZE, 0); if (fs->nfont == 0) { *minSize = 8; *maxSize = 24; XftFontSetDestroy(fs); return kJTrue; } for (int i=0; i<fs->nfont; i++) { double raw_size; if (XftPatternGetDouble(fs->fonts[i], XFT_SIZE, 0, &raw_size) == XftResultMatch) { JSize fontSize = static_cast<JSize>(raw_size); if (sizeList->IsEmpty()) { *minSize = *maxSize = fontSize; } JBoolean isDuplicate; const JIndex index = sizeList->GetInsertionSortIndex(fontSize, &isDuplicate); if (!isDuplicate) { sizeList->InsertElementAtIndex(index, fontSize); if (fontSize < *minSize) { *minSize = fontSize; } else if (fontSize > *maxSize) { *maxSize = fontSize; } } } } // Look for scalable if ((*minSize == 0) && (*maxSize == 0)) { *minSize = 8; *maxSize = 24; XftFontSetDestroy(fs); return kJTrue; } XftFontSetDestroy(fs); #else JString xFontName, charSet; if (!ConvertToXFontName(name, &xFontName, &charSet)) { charSet = "*-*"; } // check for rescalable font JString regexStr = "-*-" + xFontName + "-*-*-*-*-*-0-75-75-*-*-" + charSet; int nameCount; char** nameList = XListFonts(*itsDisplay, regexStr, INT_MAX, &nameCount); if (nameList != NULL) { *minSize = 8; *maxSize = 24; XFreeFontNames(nameList); return kJTrue; } // get list of available sizes regexStr = "-*-" + xFontName + "-*-*-*-*-*-*-75-75-*-*-" + charSet; nameList = XListFonts(*itsDisplay, regexStr, INT_MAX, &nameCount); if (nameList == NULL) { return kJFalse; } JSize fontSize; for (int i=0; i<nameCount; i++) { const std::string s(nameList[i], strlen(nameList[i])); std::istringstream input(s); input.ignore(); // initial dash JIgnoreUntil(input, '-'); // foundry name JIgnoreUntil(input, '-'); // font name JIgnoreUntil(input, '-'); // medium/bold JIgnoreUntil(input, '-'); // roman/oblique/italic JIgnoreUntil(input, '-'); // character spacing input.ignore(); // extra dash JIgnoreUntil(input, '-'); // pixel height input >> fontSize; // 10*(point size) if (fontSize < 10) { continue; // we already checked for rescalable version } fontSize /= 10; if (sizeList->IsEmpty()) { *minSize = *maxSize = fontSize; } JBoolean isDuplicate; const JIndex index = sizeList->GetInsertionSortIndex(fontSize, &isDuplicate); if (!isDuplicate) { sizeList->InsertElementAtIndex(index, fontSize); if (fontSize < *minSize) { *minSize = fontSize; } else if (fontSize > *maxSize) { *maxSize = fontSize; } } } XFreeFontNames(nameList); #endif return JNegate( sizeList->IsEmpty() ); }
static XftFont *gui_find_font(winlist_t *win, FcChar32 ucs4) { unsigned int i; int weight, slant, scalable; double font_size; FcFontSet *fontset; XftFont *font = NULL; /* 缺字列表有這個字,那就不用再找啦 */ if (FcCharSetHasChar(gui->missing_chars, ucs4)) { return NULL; } /* 找出 Cache 相符的字型 */ for (i=0 ; i < gui->num_fonts ; i++) { XftPatternGetDouble(gui->xftfonts[i]->pattern, XFT_PIXEL_SIZE, 0, &font_size); if ((int)font_size == win->font_size && FcCharSetHasChar(gui->xftfonts[i]->charset, ucs4)) { return gui->xftfonts[i]; } } /* 列出所有可能的字型 */ FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_CHARSET, NULL); /* 只要標準、非斜體、可縮放字型即可 */ FcPattern *listpat = FcPatternBuild(NULL, FC_SLANT, FcTypeInteger, FC_SLANT_ROMAN, FC_SCALABLE, FcTypeBool, FcTrue, NULL); fontset = FcFontList(NULL, listpat, os); FcPatternDestroy(listpat); FcObjectSetDestroy(os); for (i=0; i< fontset->nfont; i++) { FcPattern *pat = fontset->fonts[i]; FcCharSet *fcs = NULL; if (FcPatternGetCharSet(pat, FC_CHARSET, 0, &fcs) != FcResultMatch) continue; if (!FcCharSetHasChar(fcs, ucs4)) continue; FcResult res; FcPattern *mpat = FcFontMatch(0, pat, &res); if (!mpat) continue; XftPatternAddDouble(mpat, XFT_PIXEL_SIZE, (double)win->font_size); XftFont *chkfont = XftFontOpenPattern(gui->display, mpat); if (chkfont) { gui->num_fonts ++; gui->xftfonts = (XftFont **)oxim_realloc(gui->xftfonts, gui->num_fonts * sizeof(XftFont *)); if (!gui->xftfonts) { FcPatternDestroy(mpat); continue; } gui->xftfonts[gui->num_fonts - 1] = chkfont; font = chkfont; break; } else { FcPatternDestroy(mpat); } } FcFontSetDestroy(fontset); if (!font) FcCharSetAddChar(gui->missing_chars, ucs4); return font; }
XFontStruct* XftCoreOpen (Display *dpy, XftPattern *pattern) { XftCoreFont *cf; char *xlfd; char *xlfd_pixel = 0; char *i, *o; int d; Bool scalable; double pixel_size; int pixel_int; XFontStruct *ret; #if 0 printf ("Core "); XftPatternPrint (pattern); #endif if (XftPatternGetString (pattern, XFT_XLFD, 0, &xlfd) != XftResultMatch) return 0; if (XftPatternGetBool (pattern, XFT_SCALABLE, 0, &scalable) != XftResultMatch) return 0; if (scalable) { if (XftPatternGetDouble (pattern, XFT_PIXEL_SIZE, 0, &pixel_size) != XftResultMatch) return 0; pixel_int = (int) (pixel_size + 0.5); if (pixel_int) { xlfd_pixel = (char *) malloc (strlen (xlfd) + 32); i = xlfd; o = xlfd_pixel; d = 0; while (d != 7 && *i) { if ((*o++ = *i++) == '-') d++; } if (*i) { sprintf (o, "%d", pixel_int); o += strlen (o); while (*i != '-') ++i; } while ((*o++ = *i++)); #if 0 printf ("original %s sized %s\n", xlfd, xlfd_pixel); #endif xlfd = xlfd_pixel; } } for (cf = _XftCoreFonts; cf; cf = cf->next) { if (cf->display == dpy && !_XftStrCmpIgnoreCase (cf->xlfd, xlfd)) { cf->ref++; if (_XftFontDebug () & XFT_DBG_REF) { printf ("Xlfd \"%s\" matches existing font (%d)\n", xlfd, cf->ref); } break; } } if (!cf) { ret = XLoadQueryFont (dpy, xlfd); if (!ret) return 0; cf = (XftCoreFont *) malloc (sizeof (XftCoreFont) + strlen (xlfd) + 1); if (!cf) { XFreeFont (dpy, ret); return 0; } if (_XftFontDebug () & XFT_DBG_REF) printf ("Xlfd \"%s\" matches new font\n", xlfd); cf->next = _XftCoreFonts; _XftCoreFonts = cf; cf->ref = 1; cf->font = ret; cf->xlfd = (char *) (cf + 1); strcpy (cf->xlfd, xlfd); } if (xlfd_pixel) free (xlfd_pixel); return cf->font; }