📄 main.c
字号:
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); DBG_MSG(2,(stderr, "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; r->TermWin.xftpattern = NULL; xf = r->TermWin.xftfont; r->TermWin.xftfont = NULL; pxf = r->TermWin.xftpfont; r->TermWin.xftpfont = NULL; Pxf = r->TermWin.xftPfont; r->TermWin.xftPfont = NULL;# ifdef MULTICHAR_SET mxp = r->TermWin.xftmpattern; r->TermWin.xftmpattern = NULL; mxf = r->TermWin.xftmfont; r->TermWin.xftmfont = NULL;# 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 DBG_MSG(1, (stderr, "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); DBG_MSG(1,(stderr, "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; } fontname = NULL; 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); fontname = NULL; 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 (NULL != fontname) { xfont = XLoadQueryFont(r->Xdisplay, fontname); if (xfont) { /* load new font succeessfully */ char* ptr = STRDUP (fontname); if (ptr) { if (r->h->newfont[idx] != NULL) 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 */ DBG_MSG(1,(stderr, " 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_print_error(msg, r->h->rs[Rs_font+idx]); /* try to load fixed font */ r->h->rs[Rs_font+idx] = "fixed"; DBG_MSG(1,(stderr, " 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_print_error(msg, r->h->rs[Rs_font+idx]); return 0; } } /* Font loading succeeded */ if (xfont) { /* ** if the previous font exists, replace it with new font. ** otherwise, keep the old font, and do nothing */ if (r->TermWin.font) XFreeFont (r->Xdisplay, r->TermWin.font); 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#ifdef XFT_SUPPORT /* Set font size when XFT is not enabled */ if (!((r->Options & Opt_xft) && r->TermWin.xftfont))#endif {#ifdef XFT_SUPPORT r->TermWin.pwidth = fw; r->TermWin.pheight = fh;#endif r->TermWin.fwidth = fw; r->TermWin.fheight = fh; }#ifndef NO_BOLDFONT bfont = NULL; if (ckfont) { if (r->TermWin.bfont) { XFreeFont (r->Xdisplay, r->TermWin.bfont); r->TermWin.bfont = NULL; } /* try to load boldFont, fail silently */ if (NULL == r->TermWin.bfont && NULL != r->h->rs[Rs_boldFont+idx]) { DBG_MSG(1,(stderr, " load bfont (%s)\n", r->h->rs[Rs_boldFont+idx])); bfont = XLoadQueryFont (r->Xdisplay, r->h->rs[Rs_boldFont+idx]); } if (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_NORMAL; else r->TermWin.propfont |= PROPFONT_NORMAL; } else { XFreeFont (r->Xdisplay, bfont); } } }#endif /* NO_BOLDFONT */#ifdef HAVE_MENUBAR /* * 2006-01-29 gi1242: We should do something to resize the menubar font. * However just changing it in the appropriate GC from here doesn't seem to * work at all. */ /* Resize the menubar font too. Only needed for X11 font. */ if(#ifdef XFT_SUPPORT !(r->Options & Opt_xft) &&#endif r->menuBar.win != None) { DBG_MSG( 3, ( stderr, "Resized menubar font\n")); XSetFont( r->Xdisplay, r->menuBar.gc, r->TermWin.font->fid); }#endif#ifdef MULTICHAR_SET /* load font or substitute */ DBG_MSG(1,(stderr, " load mfont (%s)\n", r->h->rs[Rs_mfont+idx])); xfont = XLoadQueryFont(r->Xdisplay, r->h->rs[Rs_mfont+idx]); if (!xfont) { char* ptr; /* failed to load font */ rxvt_print_error(msg, r->h->rs[Rs_mfont+idx]); /* try to load default font */ ptr = rxvt_fallback_mfont_x11 (r); DBG_MSG(1,(stderr, " load mfont (%s)\n", ptr)); xfont = XLoadQueryFont(r->Xdisplay, ptr); if (xfont) r->h->rs[Rs_mfont+idx] = ptr; else { /* still failed to load font */ rxvt_print_error(msg, ptr); return 0; } } if (xfont) { /* ** if the previous font exists, replace it with new font. ** otherwise, keep the old font, and do nothing */ if (r->TermWin.mfont) XFreeFont (r->Xdisplay, r->TermWin.mfont); r->TermWin.mfont = xfont; }#endif /* MULTICHAR_SET */#ifdef USE_XIM rxvt_IM_change_fontset(r, idx);#endif return 1;}/* INTPROTO */voidrxvt_font_up_down(rxvt_t* r, int n, int direction){ const char *p; int initial, j; for (j = 0; j < n; j++) { initial = r->h->fnum; for (;;) { r->h->fnum += direction; if (r->h->fnum == MAX_NFONTS || r->h->fnum == -1) { r->h->fnum = initial; return; } p = r->h->rs[Rs_font + FNUM2IDX(r->h->fnum)]; if (p != NULL && STRLEN(p) > 1) break; } }}#undef IDX2FNUM#undef FNUM2IDX/* INTPROTO */intrxvt_get_font_widest(XFontStruct *f){ int i, cw, fw = 0; if (f->min_bounds.width == f->max_bounds.width) return f->min_bounds.width; if (f->per_char == NULL) return f->max_bounds.width; for (i = f->max_char_or_byte2 - f->min_char_or_byte2; --i >= 0;) { cw = f->per_char[i].width; MAX_IT(fw, cw); } return fw;}/*----------------------------------------------------------------------*//*----------------------------------------------------------------------*/#ifdef X_HAVE_UTF8_STRING/* INTPROTO */voidrxvt_set_utf8_property (rxvt_t* r, Atom prop, Window win, const char* str){#ifdef HAVE_WCHAR_H# if !defined (OS_FREEBSD) || _FreeBSD_version >= 500000 wchar_t* ws = rxvt_mbstowcs (str); char* s = rxvt_wcstoutf8 (ws); XChangeProperty (r->Xdisplay, win, prop, r->h->xa[XA_UTF8_STRING], 8, PropModeReplace, (unsigned char*) s, STRLEN (s)); free (s); free (ws);# endif /* !defined (OS_FREEBSD) ||... */#endif /* HAVE_WCHAR_H */}#endif /* X_HAVE_UTF8_STRING */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -