static XftFont * GetFont( UnixFtFont *fontPtr, FcChar32 ucs4) { int i; if (ucs4) { for (i = 0; i < fontPtr->nfaces; i++) { FcCharSet *charset = fontPtr->faces[i].charset; if (charset && FcCharSetHasChar(charset, ucs4)) { break; } } if (i == fontPtr->nfaces) { i = 0; } } else { i = 0; } if (!fontPtr->faces[i].ftFont) { FcPattern *pat = FcFontRenderPrepare(0, fontPtr->pattern, fontPtr->faces[i].source); fontPtr->faces[i].ftFont = XftFontOpenPattern(fontPtr->display, pat); } return fontPtr->faces[i].ftFont; }
//========================================= // setText //----------------------------------------- XImage* setText (Display* dpy,int screen,char* text, int* x, int* y) { Window root = RootWindow ( dpy,screen ); int DWidth = DisplayWidth ( dpy,screen ); int DHeight = DisplayHeight ( dpy,screen ); XftPattern *pattern = NULL; XftFont* FTfont = NULL; XftDraw* FTdraw = NULL; XftColor* FTcolor = NULL; XImage* Image = NULL; XGlyphInfo FTinfo; XColor color; XGCValues values; int XTwidth; int XTheight; int x1,y1; pattern = XftNameParse (XFTFONT); pattern = XftFontMatch (dpy,screen,pattern,NULL); FTfont = XftFontOpenPattern (dpy, pattern); XftTextExtentsUtf8 ( dpy,FTfont,text,strlen(text),&FTinfo ); XTwidth = FTinfo.xOff; XTheight= FTfont->height + 20; FTdraw = XftDrawCreate ( dpy, root, DefaultVisual(dpy,screen),DefaultColormap(dpy,screen) ); FTcolor = (XftColor*)malloc(sizeof(XftColor)); color.red = 255 << 8; color.green = 255 << 8; color.blue = 255 << 8; XAllocColor (dpy,DefaultColormap(dpy,screen),&color); XSetForeground(dpy,DefaultGC (dpy,screen),color.pixel); XGetGCValues ( dpy, DefaultGC (dpy,screen), GCForeground | GCBackground, &values ); FTcolor->color.red = color.red; FTcolor->color.green = color.green; FTcolor->color.blue = color.blue; FTcolor->color.alpha = 0xffff; x1 = (int)((DWidth / 2) - (XTwidth / 2)); y1 = (int)((DHeight / 2) - (XTheight / 2)); XftDrawStringUtf8 ( FTdraw, FTcolor,FTfont,x1,y1,text,strlen(text) ); XFlush (dpy); y1 = (int)((DHeight / 2) - XTheight); Image = XGetImage( dpy,root,x1,y1,XTwidth,XTheight,AllPlanes,XYPixmap ); *x = x1; *y = y1; return (Image); }
/* This function is an implementation detail. Library users should use * drw_font_create instead. */ static Fnt * drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) { Fnt *font; if (!(fontname || fontpattern)) die("No font specified.\n"); if (!(font = (Fnt *)calloc(1, sizeof(Fnt)))) return NULL; if (fontname) { /* Using the pattern found at font->xfont->pattern does not yield same * the same substitution results as using the pattern returned by * FcNameParse; using the latter results in the desired fallback * behaviour whereas the former just results in * missing-character-rectangles being drawn, at least with some fonts. */ if (!(font->xfont = XftFontOpenName(drw->dpy, drw->screen, fontname)) || !(font->pattern = FcNameParse((FcChar8 *) fontname))) { if (font->xfont) { XftFontClose(drw->dpy, font->xfont); font->xfont = NULL; } fprintf(stderr, "error, cannot load font: '%s'\n", fontname); } } else if (fontpattern) { if (!(font->xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { fprintf(stderr, "error, cannot load font pattern.\n"); } else { font->pattern = NULL; } } if (!font->xfont) { free(font); return NULL; } font->ascent = font->xfont->ascent; font->descent = font->xfont->descent; font->h = font->ascent + font->descent; font->dpy = drw->dpy; return font; }
static XftFont * GetFont( UnixFtFont *fontPtr, FcChar32 ucs4) { int i; if (ucs4) { for (i = 0; i < fontPtr->nfaces; i++) { FcCharSet *charset = fontPtr->faces[i].charset; if (charset && FcCharSetHasChar(charset, ucs4)) { break; } } if (i == fontPtr->nfaces) { i = 0; } } else { i = 0; } if (!fontPtr->faces[i].ftFont) { FcPattern *pat = FcFontRenderPrepare(0, fontPtr->pattern, fontPtr->faces[i].source); XftFont *ftFont = XftFontOpenPattern(fontPtr->display, pat); if (!ftFont) { /* * The previous call to XftFontOpenPattern() should not fail, * but sometimes does anyway. Usual cause appears to be * a misconfigured fontconfig installation; see [Bug 1090382]. * Try a fallback: */ ftFont = XftFontOpen(fontPtr->display, fontPtr->screen, FC_FAMILY, FcTypeString, "sans", FC_SIZE, FcTypeDouble, 12.0, NULL); } if (!ftFont) { /* * The previous call should definitely not fail. * Impossible to proceed at this point. */ Tcl_Panic("Cannot find a usable font."); } fontPtr->faces[i].ftFont = ftFont; } return fontPtr->faces[i].ftFont; }
static XftFont* open_pattern(FcPattern* pattern, Antialiasing antialiasing, Hinting hinting) { #ifdef FC_HINT_STYLE static const int hintstyles[] = { FC_HINT_NONE, FC_HINT_SLIGHT, FC_HINT_MEDIUM, FC_HINT_FULL }; #endif /* FC_HINT_STYLE */ FcPattern* res_pattern; FcResult result; XftFont* font; Display* xdisplay = gdk_x11_get_default_xdisplay(); int screen = gdk_x11_get_default_screen(); res_pattern = XftFontMatch(xdisplay, screen, pattern, &result); if (res_pattern == NULL) { return NULL; } FcPatternDel(res_pattern, FC_HINTING); FcPatternAddBool(res_pattern, FC_HINTING, hinting != HINT_NONE); #ifdef FC_HINT_STYLE FcPatternDel(res_pattern, FC_HINT_STYLE); FcPatternAddInteger(res_pattern, FC_HINT_STYLE, hintstyles[hinting]); #endif /* FC_HINT_STYLE */ FcPatternDel(res_pattern, FC_ANTIALIAS); FcPatternAddBool(res_pattern, FC_ANTIALIAS, antialiasing != ANTIALIAS_NONE); FcPatternDel(res_pattern, FC_RGBA); FcPatternAddInteger(res_pattern, FC_RGBA, antialiasing == ANTIALIAS_RGBA ? FC_RGBA_RGB : FC_RGBA_NONE); FcPatternDel(res_pattern, FC_DPI); FcPatternAddInteger(res_pattern, FC_DPI, 96); font = XftFontOpenPattern(xdisplay, res_pattern); if (!font) { FcPatternDestroy(res_pattern); } return font; }
//========================================= // XFontSetup //----------------------------------------- XTFont XFontSetup (XInit xi,char *text) { // ... // Open the defined XFTFONT and calculate the // pixel width and height needed for text with the // given font // --- XftPattern *pattern; XGlyphInfo FTinfo; XTFont xt; pattern = XftNameParse (XFTFONT); pattern = XftFontMatch (xi.dpy,xi.DScreen,pattern,NULL); xt.FTfont = XftFontOpenPattern (xi.dpy, pattern); XftTextExtentsUtf8 ( xi.dpy,xt.FTfont,text,strlen(text),&FTinfo ); xt.XTheight = xt.FTfont->height; xt.XTwidth = FTinfo.xOff; return(xt); }
static inline XftFont * get_font(Display *xdisplay, FT_Face face, gint size, FcCharSet *charset) { FcPattern *pattern; XftFont *font; int screen = DefaultScreen (xdisplay); pattern = FcPatternBuild(NULL, FC_FT_FACE, FcTypeFTFace, face, FC_PIXEL_SIZE, FcTypeDouble, (double)size, NULL); if (charset) FcPatternAddCharSet (pattern, "charset", charset); FcConfigSubstitute (NULL, pattern, FcMatchPattern); XftDefaultSubstitute (xdisplay, screen, pattern); font = XftFontOpenPattern(xdisplay, pattern); return font; }
static XftFont* getfont(XftFont **font, uint32_t ch) { XftFont *first = font[0]; if(!FcCharSetHasChar(charset, ch)) { return first; } while(*font) { if(XftGlyphExists(display, *font, ch)) { return *font; } font++; } FcResult result; int i; for(i = 0; i != fs->nfont; i++) { FcCharSet *cs; result = FcPatternGetCharSet(fs->fonts[i], FC_CHARSET, 0, &cs); if(FcCharSetHasChar(cs, ch)) { FcPattern *p = FcPatternDuplicate(fs->fonts[i]), *pp; double size; if(!FcPatternGetDouble(first->pattern, FC_PIXEL_SIZE, 0, &size)) { FcPatternAddDouble(p, FC_PIXEL_SIZE, size); } pp = XftFontMatch(display, screen, p, &result); *font = XftFontOpenPattern(display, pp); FcPatternDestroy(p); return *font; } } //should never happen return first; }
void load_font(FcChar8 *font_str) { FcPattern *pattern, *match; FcResult result; if (font_str[0] == '-') pattern = XftXlfdParse(font_str, False, False); else pattern = FcNameParse((FcChar8 *) font_str); if (!pattern) die("Failed to get font pattern"); match = FcFontMatch(NULL, pattern, &result); if (!match) die("Failed to get font match"); if (!(font = XftFontOpenPattern(display, match))) { FcPatternDestroy(match); die("Failed to open font"); } ascent = font->ascent; descent = font->descent; }
static Lisp_Object xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size) { FcResult result; Display *display = FRAME_X_DISPLAY (f); Lisp_Object val, filename, idx, font_object; FcPattern *pat = NULL, *match; struct xftfont_info *xftfont_info = NULL; struct font *font; double size = 0; XftFont *xftfont = NULL; int spacing; char name[256]; int len, i; XGlyphInfo extents; FT_Face ft_face; FcMatrix *matrix; val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX)); if (! CONSP (val)) return Qnil; val = XCDR (val); filename = XCAR (val); idx = XCDR (val); size = XINT (AREF (entity, FONT_SIZE_INDEX)); if (size == 0) size = pixel_size; pat = FcPatternCreate (); FcPatternAddInteger (pat, FC_WEIGHT, FONT_WEIGHT_NUMERIC (entity)); i = FONT_SLANT_NUMERIC (entity) - 100; if (i < 0) i = 0; FcPatternAddInteger (pat, FC_SLANT, i); FcPatternAddInteger (pat, FC_WIDTH, FONT_WIDTH_NUMERIC (entity)); FcPatternAddDouble (pat, FC_PIXEL_SIZE, pixel_size); val = AREF (entity, FONT_FAMILY_INDEX); if (! NILP (val)) FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) SDATA (SYMBOL_NAME (val))); val = AREF (entity, FONT_FOUNDRY_INDEX); if (! NILP (val)) FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) SDATA (SYMBOL_NAME (val))); val = AREF (entity, FONT_SPACING_INDEX); if (! NILP (val)) FcPatternAddInteger (pat, FC_SPACING, XINT (val)); val = AREF (entity, FONT_DPI_INDEX); if (! NILP (val)) { double dbl = XINT (val); FcPatternAddDouble (pat, FC_DPI, dbl); } val = AREF (entity, FONT_AVGWIDTH_INDEX); if (INTEGERP (val) && XINT (val) == 0) FcPatternAddBool (pat, FC_SCALABLE, FcTrue); /* This is necessary to identify the exact font (e.g. 10x20.pcf.gz over 10x20-ISO8859-1.pcf.gz). */ FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity)); xftfont_add_rendering_parameters (pat, entity); FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename)); FcPatternAddInteger (pat, FC_INDEX, XINT (idx)); block_input (); /* Make sure that the Xrender extension is added before the Xft one. Otherwise, the close-display hook set by Xft is called after the one for Xrender, and the former tries to re-add the latter. This results in inconsistency of internal states and leads to X protocol error when one reconnects to the same X server. (Bug#1696) */ { int event_base, error_base; XRenderQueryExtension (display, &event_base, &error_base); } /* Substitute in values from X resources and XftDefaultSet. */ XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat); match = XftFontMatch (display, FRAME_X_SCREEN_NUMBER (f), pat, &result); xftfont_fix_match (pat, match); FcPatternDestroy (pat); xftfont = XftFontOpenPattern (display, match); if (!xftfont) { unblock_input (); XftPatternDestroy (match); return Qnil; } ft_face = XftLockFace (xftfont); unblock_input (); /* We should not destroy PAT here because it is kept in XFTFONT and destroyed automatically when XFTFONT is closed. */ font_object = font_make_object (VECSIZE (struct xftfont_info), entity, size); ASET (font_object, FONT_TYPE_INDEX, Qxft); len = font_unparse_xlfd (entity, size, name, 256); if (len > 0) ASET (font_object, FONT_NAME_INDEX, make_string (name, len)); len = font_unparse_fcname (entity, size, name, 256); if (len > 0) ASET (font_object, FONT_FULLNAME_INDEX, make_string (name, len)); else ASET (font_object, FONT_FULLNAME_INDEX, AREF (font_object, FONT_NAME_INDEX)); ASET (font_object, FONT_FILE_INDEX, filename); ASET (font_object, FONT_FORMAT_INDEX, ftfont_font_format (xftfont->pattern, filename)); font = XFONT_OBJECT (font_object); font->pixel_size = size; font->driver = &xftfont_driver; font->encoding_charset = font->repertory_charset = -1; xftfont_info = (struct xftfont_info *) font; xftfont_info->display = display; xftfont_info->xftfont = xftfont; /* This means that there's no need of transformation. */ xftfont_info->matrix.xx = 0; if (FcPatternGetMatrix (xftfont->pattern, FC_MATRIX, 0, &matrix) == FcResultMatch) { xftfont_info->matrix.xx = 0x10000L * matrix->xx; xftfont_info->matrix.yy = 0x10000L * matrix->yy; xftfont_info->matrix.xy = 0x10000L * matrix->xy; xftfont_info->matrix.yx = 0x10000L * matrix->yx; } if (INTEGERP (AREF (entity, FONT_SPACING_INDEX))) spacing = XINT (AREF (entity, FONT_SPACING_INDEX)); else spacing = FC_PROPORTIONAL; if (! ascii_printable[0]) { int ch; for (ch = 0; ch < 95; ch++) ascii_printable[ch] = ' ' + ch; } block_input (); /* Unfortunately Xft doesn't provide a way to get minimum char width. So, we set min_width to space_width. */ if (spacing != FC_PROPORTIONAL #ifdef FC_DUAL && spacing != FC_DUAL #endif /* FC_DUAL */ ) { font->min_width = font->max_width = font->average_width = font->space_width = xftfont->max_advance_width; XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents); } else { XftTextExtents8 (display, xftfont, ascii_printable, 1, &extents); font->min_width = font->max_width = font->space_width = extents.xOff; if (font->space_width <= 0) /* dirty workaround */ font->space_width = pixel_size; XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents); font->average_width = (font->space_width + extents.xOff) / 95; } unblock_input (); font->ascent = xftfont->ascent; font->descent = xftfont->descent; if (pixel_size >= 5) { /* The above condition is a dirty workaround because XftTextExtents8 behaves strangely for some fonts (e.g. "Dejavu Sans Mono") when pixel_size is less than 5. */ if (font->ascent < extents.y) font->ascent = extents.y; if (font->descent < extents.height - extents.y) font->descent = extents.height - extents.y; } font->height = font->ascent + font->descent; if (XINT (AREF (entity, FONT_SIZE_INDEX)) == 0) { int upEM = ft_face->units_per_EM; font->underline_position = -ft_face->underline_position * size / upEM; font->underline_thickness = ft_face->underline_thickness * size / upEM; if (font->underline_thickness > 2) font->underline_position -= font->underline_thickness / 2; } else { font->underline_position = -1; font->underline_thickness = 0; } #ifdef HAVE_LIBOTF xftfont_info->maybe_otf = (ft_face->face_flags & FT_FACE_FLAG_SFNT) != 0; xftfont_info->otf = NULL; #endif /* HAVE_LIBOTF */ xftfont_info->ft_size = ft_face->size; font->baseline_offset = 0; font->relative_compose = 0; font->default_ascent = 0; font->vertical_centering = 0; #ifdef FT_BDF_H if (! (ft_face->face_flags & FT_FACE_FLAG_SFNT)) { BDF_PropertyRec rec; if (FT_Get_BDF_Property (ft_face, "_MULE_BASELINE_OFFSET", &rec) == 0 && rec.type == BDF_PROPERTY_TYPE_INTEGER) font->baseline_offset = rec.u.integer; if (FT_Get_BDF_Property (ft_face, "_MULE_RELATIVE_COMPOSE", &rec) == 0 && rec.type == BDF_PROPERTY_TYPE_INTEGER) font->relative_compose = rec.u.integer; if (FT_Get_BDF_Property (ft_face, "_MULE_DEFAULT_ASCENT", &rec) == 0 && rec.type == BDF_PROPERTY_TYPE_INTEGER) font->default_ascent = rec.u.integer; } #endif return font_object; }
TGlyphInfo *glyph_cache_get_info(TGlyphCache *cache, gunichar glyph) { TGlyphInfo *gfi; XftFont *xftfont; PangoFont *font; PangoGlyph pglyph; PangoRectangle ink, logical; gint ascent, descent; gint x_offset; gint nominal_width; double scale_y, scale_x; if (!cache->hash) return NULL; gfi = g_hash_table_lookup(cache->hash, GINT_TO_POINTER(glyph)); if (gfi) return gfi; font = pango_fontset_get_font(cache->font_set, glyph); pglyph = pango_fc_font_get_glyph(PANGO_FC_FONT(font), glyph); if (!pglyph) { fprintf (stderr, "Error: Unable to find glyph %d.\n", glyph); if (!pglyph) pglyph = pango_fc_font_get_glyph(PANGO_FC_FONT(font), glyph); if (!pglyph) pglyph = PANGO_GET_UNKNOWN_GLYPH (glyph); if (!pglyph) return NULL; } pango_font_get_glyph_extents(font, pglyph, &ink, &logical); ascent = PANGO_ASCENT(logical); descent = PANGO_DESCENT(logical); xftfont = pango_xft_font_get_font(font); x_offset = 0; nominal_width = cache->width; if (g_unichar_iswide(glyph)) nominal_width *= 2; scale_x = scale_y = 1.0; if (logical.width > nominal_width) { if (logical.width) scale_x = (double)nominal_width / (double)logical.width; else scale_x = 1.0; } if (logical.height != cache->height) { double scale; if (ascent) { scale_y = (double)cache->ascent / (double)ascent; } else { scale_y = 1.0; } if (descent) { scale = (double)cache->descent / (double)descent; if (scale < scale_y) scale_y = scale; } } if (scale_x >= 1.0) { scale_x = 1.0; x_offset += (nominal_width - logical.width) / 2; } if (scale_x < 1.0 || scale_y != 1.0) { FcBool scalable; FcPatternGetBool(xftfont->pattern, FC_SCALABLE, 0, &scalable); if (!scalable) { /* Bah. Need better handling of non-scalable fonts */ if (scale_x < 1.0) scale_x = 1.0; scale_y = 1.0; } else if (scale_x < 1.0 || scale_y != 1.0) { FcPattern *pattern; FcMatrix mat; pattern = FcPatternDuplicate(xftfont->pattern); FcMatrixInit (&mat); FcMatrixScale(&mat, scale_x, scale_y); FcPatternDel (pattern, FC_MATRIX); FcPatternAddMatrix(pattern, FC_MATRIX, &mat); xftfont = XftFontOpenPattern( GDK_DISPLAY_XDISPLAY(cache->display), pattern ); } ascent = ascent * scale_y; } g_object_unref(font); // gfi = calloc(sizeof(TGlyphInfo), 1); gfi = g_slice_new(TGlyphInfo); gfi->font = xftfont; gfi->x_offset = PANGO_PIXELS(x_offset); gfi->y_offset = cache->ascent + (cache->ascent - ascent); gfi->y_offset = PANGO_PIXELS(gfi->y_offset); g_hash_table_insert(cache->hash, GINT_TO_POINTER(glyph), gfi); return gfi; }
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; }
static XftFont * GetFont( UnixFtFont *fontPtr, FcChar32 ucs4, double angle) { int i; if (ucs4) { for (i = 0; i < fontPtr->nfaces; i++) { FcCharSet *charset = fontPtr->faces[i].charset; if (charset && FcCharSetHasChar(charset, ucs4)) { break; } } if (i == fontPtr->nfaces) { i = 0; } } else { i = 0; } if ((angle == 0.0 && !fontPtr->faces[i].ft0Font) || (angle != 0.0 && (!fontPtr->faces[i].ftFont || fontPtr->faces[i].angle != angle))){ FcPattern *pat = FcFontRenderPrepare(0, fontPtr->pattern, fontPtr->faces[i].source); double s = sin(angle*PI/180.0), c = cos(angle*PI/180.0); FcMatrix mat; XftFont *ftFont; /* * Initialize the matrix manually so this can compile with HP-UX cc * (which does not allow non-constant structure initializers). [Bug * 2978410] */ mat.xx = mat.yy = c; mat.xy = -(mat.yx = s); if (angle != 0.0) { FcPatternAddMatrix(pat, FC_MATRIX, &mat); } ftFont = XftFontOpenPattern(fontPtr->display, pat); if (!ftFont) { /* * The previous call to XftFontOpenPattern() should not fail, but * sometimes does anyway. Usual cause appears to be a * misconfigured fontconfig installation; see [Bug 1090382]. Try a * fallback: */ ftFont = XftFontOpen(fontPtr->display, fontPtr->screen, FC_FAMILY, FcTypeString, "sans", FC_SIZE, FcTypeDouble, 12.0, FC_MATRIX, FcTypeMatrix, &mat, NULL); } if (!ftFont) { /* * The previous call should definitely not fail. Impossible to * proceed at this point. */ Tcl_Panic("Cannot find a usable font"); } if (angle == 0.0) { fontPtr->faces[i].ft0Font = ftFont; } else { if (fontPtr->faces[i].ftFont) { XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont); } fontPtr->faces[i].ftFont = ftFont; fontPtr->faces[i].angle = angle; } } return (angle==0.0? fontPtr->faces[i].ft0Font : fontPtr->faces[i].ftFont); }
Menu::Menu(WindowManager *manager, XEvent *e) : m_items(0), m_nItems(0), m_nHidden(0), m_hasSubmenus(False), m_windowManager(manager), m_event(e) { if (!m_initialised) { XGCValues *values; XSetWindowAttributes *attr; m_menuGC = (GC *) malloc(m_windowManager->screensTotal() * sizeof(GC)); m_window = (Window *) malloc(m_windowManager->screensTotal() * sizeof(Window)); #ifdef CONFIG_USE_XFT char *fi = strdup(CONFIG_MENU_FONT); char *ffi = fi, *tokstr = fi; while ((fi = strtok(tokstr, ","))) { fprintf(stderr, "fi = \"%s\"\n", fi); tokstr = 0; FcPattern *pattern = FcPatternCreate(); FcPatternAddString(pattern, FC_FAMILY, (FcChar8 *)fi); FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); #ifndef FC_WEIGHT_REGULAR #define FC_WEIGHT_REGULAR FC_WEIGHT_MEDIUM #endif FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR); FcPatternAddInteger(pattern, FC_PIXEL_SIZE, CONFIG_MENU_FONT_SIZE); FcConfigSubstitute(FcConfigGetCurrent(), pattern, FcMatchPattern); FcResult result = FcResultMatch; FcPattern *match = FcFontMatch(FcConfigGetCurrent(), pattern, &result); FcPatternDestroy(pattern); if (!match || result != FcResultMatch) { if (match) FcPatternDestroy(match); continue; } m_font = XftFontOpenPattern(display(), match); if (m_font) break; FcPatternDestroy(match); } free(ffi); if (!m_font) { m_windowManager->fatal("couldn't load menu Xft font"); } m_xftColour = (XftColor *) malloc(m_windowManager->screensTotal() * sizeof(XftColor)); m_xftDraw = (XftDraw **) malloc(m_windowManager->screensTotal() * sizeof(XftDraw *)); #else m_font = (XFontStruct **) malloc(m_windowManager->screensTotal() * sizeof(XFontStruct *)); #endif values = (XGCValues *) malloc(m_windowManager->screensTotal() * sizeof(XGCValues)); attr = (XSetWindowAttributes *) malloc(m_windowManager->screensTotal() * sizeof(XSetWindowAttributes)); for (int i = 0; i < m_windowManager->screensTotal(); i++) { m_foreground = m_windowManager->allocateColour (i, CONFIG_MENU_FOREGROUND, "menu foreground"); m_background = m_windowManager->allocateColour (i, CONFIG_MENU_BACKGROUND, "menu background"); m_border = m_windowManager->allocateColour (i, CONFIG_MENU_BORDERS, "menu border"); #ifndef CONFIG_USE_XFT char **ml; int mc; char *ds; m_fontset = XCreateFontSet(display(), CONFIG_NICE_MENU_FONT, &ml, &mc, &ds); if (!m_fontset) m_fontset = XCreateFontSet(display(), CONFIG_NASTY_FONT, &ml, &mc, &ds); if (m_fontset) { XFontStruct **fs_list; XFontsOfFontSet(m_fontset, &fs_list, &ml); m_font[i] = fs_list[0]; } else { m_font[i] = NULL; } #define XDrawString(t,u,v,w,x,y,z) XmbDrawString(t,u,m_fontset,v,w,x,y,z) if (!m_font[i]) m_windowManager->fatal("couldn't load menu font\n"); #endif values[i].background = m_background; values[i].foreground = m_foreground ^ m_background; values[i].function = GXxor; values[i].line_width = 0; values[i].subwindow_mode = IncludeInferiors; #ifndef CONFIG_USE_XFT values[i].font = m_font[i]->fid; #endif m_menuGC[i] = XCreateGC (display(), m_windowManager->mroot(i), GCForeground | GCBackground | GCFunction | GCLineWidth | GCSubwindowMode, &values[i]); #ifndef CONFIG_USE_XFT XChangeGC(display(), Border::drawGC(m_windowManager, i), GCFont, &values[i]); #endif m_window[i] = XCreateSimpleWindow (display(), m_windowManager->mroot(i), 0, 0, 1, 1, 1, m_border, m_background); #if ( CONFIG_USE_PIXMAPS != False ) && ( CONFIG_USE_PIXMAP_MENUS != False ) attr[i].background_pixmap = Border::backgroundPixmap(manager); #endif attr[i].save_under = (DoesSaveUnders(ScreenOfDisplay(display(), i)) ? True : False); #if ( CONFIG_USE_PIXMAPS != False ) && ( CONFIG_USE_PIXMAP_MENUS != False ) XChangeWindowAttributes (display(), m_window[i], CWBackPixmap, &attr[i]); #endif XChangeWindowAttributes (display(), m_window[i], CWSaveUnder, &attr[i]); #ifdef CONFIG_USE_XFT XftColorAllocName (display(), XDefaultVisual(display(), i), XDefaultColormap(display(), i), CONFIG_MENU_FOREGROUND, &m_xftColour[i]); m_xftDraw[i] = XftDrawCreate(display(), m_window[i], XDefaultVisual(display(), i), XDefaultColormap(display(), i)); #endif } m_initialised = True; } }