📄 main.c
字号:
int fh = 0, fw = 0; int idx = 0; /* index into rs_font[] */ rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, "rxvt_init_font_x11 \n"));#ifdef XFT_SUPPORT /* Only load fixed font if we use freetype font */ if (ISSET_OPTION(r, Opt_xft) && r->TermWin.xftfont) { rxvt_init_font_fixed (r); return; }#endif r->h->fnum = FONT0_IDX; idx = FNUM2IDX(r->h->fnum); /* OK, now it's time to load the default font */ rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, " load font (%s)\n", r->h->rs[Rs_font+idx])); xfont = XLoadQueryFont (r->Xdisplay, r->h->rs[Rs_font+idx]); if (IS_NULL(xfont)) { /* failed to load font */ rxvt_msg( DBG_ERROR, DBG_MAIN, msg, r->h->rs[Rs_font+idx] ); /* try to load fixed font */ r->h->rs[Rs_font+idx] = "fixed"; rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, " load font (%s)\n", r->h->rs[Rs_font+idx])); xfont = XLoadQueryFont(r->Xdisplay, r->h->rs[Rs_font+idx]); if (IS_NULL(xfont)) { /* still failed to load font */ rxvt_msg( DBG_ERROR, DBG_MAIN, msg, r->h->rs[Rs_font+idx] ); /* cannot load any font, fatal error, abort the program */ goto Abort; } } /* Font loading succeeded */ if (NOT_NULL(xfont)) { r->TermWin.font = xfont; } /* set the font sizes */ fw = rxvt_get_font_widest (r->TermWin.font); fh = r->TermWin.font->ascent + r->TermWin.font->descent;#ifndef NO_LINESPACE fh += r->TermWin.lineSpace;#endif if (fw == r->TermWin.font->min_bounds.width) /* Mono-spaced (fixed width) font */ r->TermWin.propfont &= ~PROPFONT_NORMAL; else /* Proportional font */ r->TermWin.propfont |= PROPFONT_NORMAL;#ifndef NO_BOLDFONT ckfont = !(fw == r->TermWin.fwidth && fh == r->TermWin.fheight);#endif r->TermWin.fwidth = fw; r->TermWin.fheight = fh;#ifdef XFT_SUPPORT r->TermWin.pwidth = fw; r->TermWin.pheight = fh;#endif#ifndef NO_BOLDFONT SET_NULL(bfont); if (ckfont) { /* try to load boldFont, fail silently */ if (NOT_NULL(r->h->rs[Rs_boldFont+idx])) { rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, " load bfont (%s)\n", r->h->rs[Rs_boldFont+idx])); bfont = XLoadQueryFont (r->Xdisplay, r->h->rs[Rs_boldFont+idx]); } if (NOT_NULL(bfont)) { /* Loading bold font succeeded */ fw = rxvt_get_font_widest (bfont); fh = bfont->ascent + bfont->descent;#ifndef NO_LINESPACE fh += r->TermWin.lineSpace;#endif if (fw <= r->TermWin.fwidth && fh <= r->TermWin.fheight) { r->TermWin.bfont = bfont; if (fw == r->TermWin.fwidth) r->TermWin.propfont &= ~PROPFONT_BOLD; else r->TermWin.propfont |= PROPFONT_BOLD; } else { XFreeFont (r->Xdisplay, bfont); } } }#endif /* NO_BOLDFONT */#ifdef MULTICHAR_SET /* load font or substitute */ rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, " load mfont (%s)\n", r->h->rs[Rs_mfont+idx])); xfont = XLoadQueryFont(r->Xdisplay, r->h->rs[Rs_mfont+idx]); if (IS_NULL(xfont)) { char* ptr; /* failed to load font */ rxvt_msg (DBG_ERROR, DBG_MAIN, msg, r->h->rs[Rs_mfont+idx]); ptr = rxvt_fallback_mfont_x11 (r); rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, " load mfont (%s)\n", ptr)); xfont = XLoadQueryFont(r->Xdisplay, ptr); if (NOT_NULL(xfont)) r->h->rs[Rs_mfont+idx] = ptr; else { /* still failed to load font */ rxvt_msg (DBG_ERROR, DBG_MAIN, msg, ptr); /* cannot load any mfont, fatal error, abort the program */ goto Abort; } } if (NOT_NULL(xfont)) { r->TermWin.mfont = xfont; }#endif /* MULTICHAR_SET */ /* Succeeded to load font, return now */ return ;Abort: rxvt_msg (DBG_ERROR, DBG_MAIN, "fatal error, aborting..."); exit(EXIT_FAILURE);}#ifdef XFT_SUPPORT# ifdef MULTICHAR_SET/* * 2006-04-27 gi1242: Stolen from xterm-207. Some fonts (e.g. aquafont) report * their width to be double the actual width (see below). Test for this here. */# define HALF_WIDTH_TEST_STRING "1234567890"/* '1234567890' in Chinese characters in UTF-8 */# define FULL_WIDTH_TEST_STRING "\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89" \ "\xe5\x9b\x9b\xe4\xba\x94" \ "\xef\xa7\x91\xe4\xb8\x83\xe5\x85\xab" \ "\xe4\xb9\x9d\xef\xa6\xb2"/* '1234567890' in Korean script in UTF-8 */# define FULL_WIDTH_TEST_STRING2 "\xec\x9d\xbc\xec\x9d\xb4\xec\x82\xbc" \ "\xec\x82\xac\xec\x98\xa4" \ "\xec\x9c\xa1\xec\xb9\xa0\xed\x8c\x94" \ "\xea\xb5\xac\xec\x98\x81"# define HALF_WIDTH_CHAR1 0x0031 /* 'l' */# define HALF_WIDTH_CHAR2 0x0057 /* 'W' */# define FULL_WIDTH_CHAR1 0x4E00 /* CJK Ideograph 'number one' */# define FULL_WIDTH_CHAR2 0xAC00 /* Korean script syllable 'Ka' *//*INTPROTO*/intisDoubleWidthFont(Display * dpy, XftFont * font){ XGlyphInfo gi1, gi2; FcChar32 c1 = HALF_WIDTH_CHAR1, c2 = HALF_WIDTH_CHAR2; char *fwstr = FULL_WIDTH_TEST_STRING; char *hwstr = HALF_WIDTH_TEST_STRING; /* Some Korean fonts don't have Chinese characters at all. */ if (!XftCharExists(dpy, font, FULL_WIDTH_CHAR1)) { if (!XftCharExists(dpy, font, FULL_WIDTH_CHAR2)) return 0; /* Not a CJK font */ else /* a Korean font without CJK Ideographs */ fwstr = FULL_WIDTH_TEST_STRING2; } XftTextExtents32(dpy, font, &c1, 1, &gi1); XftTextExtents32(dpy, font, &c2, 1, &gi2); if (gi1.xOff != gi2.xOff) /* Not a fixed-width font */ return 0; XftTextExtentsUtf8(dpy, font, (FcChar8 *) hwstr, (int) strlen(hwstr), &gi1); XftTextExtentsUtf8(dpy, font, (FcChar8 *) fwstr, (int) strlen(fwstr), &gi2); /* * fontconfig and Xft prior to 2.2(?) set the width of half-width characters * identical to that of full-width character in CJK double-width (bi-width / * monospace) font even though the former is half as wide as the latter. * This was fixed sometime before the release of fontconfig 2.2 in early * 2003. See * * http://bugzilla.mozilla.org/show_bug.cgi?id=196312 * * In the meantime, we have to check both possibilities. */ return ((2 * gi1.xOff == gi2.xOff) || (gi1.xOff == gi2.xOff));}# endif /*MULTICHAR_SET*//* * Close font f if it is not one of xftfont, xftpfont, xftbfont, xftmfont. *//* INTPROTO */voidxftFreeUnusedFont( rxvt_t *r, XftFont *f){ if( f && f != r->TermWin.xftfont && f != r->TermWin.xftpfont && f != r->TermWin.xftPfont# ifdef MULTICHAR_SET && f != r->TermWin.xftmfont# endif# ifndef NO_BOLDFONT && f != r->TermWin.xftbfont# endif ) XftFontClose( r->Xdisplay, f);}/* EXTPROTO */intrxvt_change_font_xft (rxvt_t* r, const char* fontname){ XftPattern* xp; XftFont *xf, *pxf, *Pxf;# ifdef MULTICHAR_SET XftPattern* mxp; XftFont* mxf;# endif int resize, oldsize = r->TermWin.xftsize; assert (fontname); rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, "rxvt_change_font_xft (%s)\n", fontname)); /* we only accept FONT_CMD now for XFT font ;-) */ if (FONT_CMD != fontname[0]) return 0; if ((char) 0 != fontname[1] && '+' != fontname[1] && '-' != fontname[1] && !isdigit((int) fontname[1])) return 0; if (('+' == fontname[1]) && ((char) 0 == fontname[2])) resize = +1; else if (('-' == fontname[1]) && ((char) 0 == fontname[2])) resize = -1; else resize = atoi (fontname+1); r->TermWin.xftsize += resize; /* adjust for minimal font size */ if (r->TermWin.xftsize < MIN_XFT_FONT_SIZE) r->TermWin.xftsize = MIN_XFT_FONT_SIZE; /* no change of font size */ if (r->TermWin.xftsize == oldsize) return 0; /* Change pfont size and mfont size */ r->TermWin.xftpsize += resize; if (r->TermWin.xftpsize < MIN_XFT_FONT_SIZE) r->TermWin.xftpsize = MIN_XFT_FONT_SIZE;# ifdef MULTICHAR_SET if (r->h->rs[Rs_xftmsz]) { r->TermWin.xftmsize += resize; if (r->TermWin.xftmsize < MIN_XFT_FONT_SIZE) r->TermWin.xftmsize = MIN_XFT_FONT_SIZE; }# endif /* ** Now reload xft font with new size using rxvt_init_font_xft. ** We can reuse it since we have only changed the font size. ** Before doing so, let us backup the old xft info in case ** we cannot load new xft font. In that case, we can still ** fallback to the old font. */ xp = r->TermWin.xftpattern; SET_NULL(r->TermWin.xftpattern); xf = r->TermWin.xftfont; SET_NULL(r->TermWin.xftfont); pxf = r->TermWin.xftpfont; SET_NULL(r->TermWin.xftpfont); Pxf = r->TermWin.xftPfont; SET_NULL(r->TermWin.xftPfont);# ifdef MULTICHAR_SET mxp = r->TermWin.xftmpattern; SET_NULL(r->TermWin.xftmpattern); mxf = r->TermWin.xftmfont; SET_NULL(r->TermWin.xftmfont);# endif if (!rxvt_init_font_xft (r)) { /* fallback to old font */ r->TermWin.xftpattern = xp; r->TermWin.xftfont = xf; r->TermWin.xftpfont = pxf; r->TermWin.xftPfont = Pxf;# ifdef MULTICHAR_SET r->TermWin.xftmpattern = mxp; r->TermWin.xftmfont = mxf;# endif return 0; } /* The old Xft font (if differnt) can now be freed */ xftFreeUnusedFont( r, xf ); if( pxf != xf) xftFreeUnusedFont( r, pxf ); if( Pxf != xf && Pxf != pxf) xftFreeUnusedFont( r, Pxf);#ifdef MULTICHAR_SET if( mxf != xf && mxf != pxf) xftFreeUnusedFont( r, mxf );#endif /* * XXX It is safe now to free old XftPattern, but apparently there is some * problems if we change the font size in reverse direction, e.g., increase * font size then decrease it, or decrease font size then increase it. It * can crash the terminal. * * 12-19-2004: Is it because the pattern is got via XftFontMatch, which * actually returns a *static* pattern that we should not manually destroy? * Anyway, to avoid the crash, let us comment out the XftPatternDestroy * calls below. I hope there is a more clear documentation about these Xft * functions!!! * * 2006-01-27 gi1242: After grepping through the Xft source code, I think I * know the problem. XftFontOpenInfo destroys the font pattern if the * pattern corresponds to an already open font. Thus when we destroy it, * it's a double free leading to a friendly segfault. This is a bug in * Xft. * * To make matters worse, closing previously opened fonts won't work. Xft * caches fonts ... and only closes them when necessary. Thus calling * XftFontClose them won't guarentee the font is actually closed. So untill * the Xft folks fix this, we have to live with a temporary memory leak. */#if 0 rxvt_dbgmsg ((DBG_DEBUG, DBG_MAIN, "Destroy %p, (xftpattern %p, xftmpattern %p)\n", xp, r->TermWin.xftpattern, r->TermWin.xftmpattern))); /* FcPatternPrint (xp); FcPatternPrint (r->TermWin.xftpattern); */ XftPatternDestroy (xp);# ifdef MULTICHAR_SET if (xp != mxp) XftPatternDestroy (mxp);# endif#endif return 1;}#endif /* XFT_SUPPORT *//*----------------------------------------------------------------------*//* rxvt_change_font_x11 () - Switch to a new font *//* * init = 1 - initialize * * fontname == FONT_UP - switch to bigger font * fontname == FONT_DN - switch to smaller font *//* EXTPROTO */intrxvt_change_font_x11 (rxvt_t* r, const char *fontname){ char* msg = "can't load font \"%s\""; XFontStruct* xfont;#ifndef NO_BOLDFONT XFontStruct* bfont; int ckfont;#endif int fh = 0, fw = 0; int idx = 0; /* index into rs_font[] */ assert (fontname); rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, "rxvt_change_font_x11 (%s)\n", fontname)); switch (fontname[0]) { /* special (internal) prefix for font commands */ case FONT_CMD: /* FONT_CMD =='#' */ idx = atoi (fontname + 1); switch (fontname[1]) { case '+': /* corresponds to FONT_UP */ r->h->fnum += (idx ? idx : 1); /* "#+" or "#+3"? */ r->h->fnum %= MAX_NFONTS; break; case '-': /* corresponds to FONT_DN */ r->h->fnum += (idx ? idx : -1); /* "#-" or "#-3"? */ r->h->fnum %= MAX_NFONTS; break; default: /* input is not a logical font number */ if (fontname[1] != '\0' && !isdigit((int) fontname[1])) return 0; /* * input logical font number too big, but don't worry, we * will handle it gracefully ;-) */ r->h->fnum = IDX2FNUM(idx); break; } SET_NULL(fontname); break; default: /* search for existing fontname */ for (idx = 0; idx < MAX_NFONTS; idx++) { if (!STRCMP (r->h->rs[Rs_font+idx], fontname)) { r->h->fnum = IDX2FNUM(idx); SET_NULL(fontname); break; } } break; } /* re-position around the normal font */ if (r->h->fnum < 0) r->h->fnum += (-(r->h->fnum / MAX_NFONTS - 1) * MAX_NFONTS); idx = FNUM2IDX(r->h->fnum); /* ** If fontname != NULL, it's some new font not in the rs_font. ** We try to load it and replace font in rs_font if succeed. */ if (NOT_NULL(fontname)) { xfont = XLoadQueryFont(r->Xdisplay, fontname); if (xfont) { /* load new font succeessfully */ char* ptr = STRDUP (fontname); if (ptr) { if (NOT_NULL(r->h->newfont[idx])) rxvt_free (r->h->newfont[idx]); r->h->newfont[idx] = ptr; r->h->rs[Rs_font+idx] = r->h->newfont[idx]; } else { assert (0); /* shouldn't happen */ } /* Free it by now */ XFreeFont (r->Xdisplay, xfont); } } /* ** OK, now it's time to load font or substitute */ rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, " load font (%s)\n", r->h->rs[Rs_font+idx])); xfont = XLoadQueryFont (r->Xdisplay, r->h->rs[Rs_font+idx]); if (!xfont) { /* failed to load font */ rxvt_msg (DBG_ERROR, DBG_MAIN, msg, r->h->rs[Rs_font+idx]); /* try to load fixed font */ r->h->rs[Rs_font+idx] = "fixed"; rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, " load font (%s)\n", r->h->rs[Rs_font+idx])); xfont = XLoadQueryFont(r->Xdisplay, r->h->rs[Rs_font+idx]); if (!xfont) { /* still failed to load font */ rxvt_msg (DBG_ERROR, DBG_MAIN, msg, r->h->rs[Rs_font+idx]); return 0; } } /* Font loading succeeded */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -