📄 font.c
字号:
return width;}static int check_font_fixed (void){ int m; char *p; m = get_string_dimensions ("M", 1, 0, 0, 0); for (p = "!MI .1@~"; *p; p++) if (m != get_string_dimensions (p, 1, 0, 0, 0)) return 0; return m;}static void get_font_dimensions (void){ unsigned char *p, q[256]; int i;/* fill an array with graphical characters of the current locale */ for (p = q, i = 1; i < 255; i++) if (isgraph ((unsigned char) i)) *p++ = (unsigned char) i; *p = '\0';/* get the dimensions of the complete character set */ get_string_dimensions ((char *) q, i, &FONT_HEIGHT, &FONT_ASCENT, &FONT_DESCENT);/* create an example sentance */ p = (unsigned char *) TEST_FONT_STRING;/* get the mean font width from the example sentance */ FONT_MEAN_WIDTH = get_string_dimensions ((char *) p, strlen ((char *) p), 0, 0, 0) / strlen ((char *) p); for (i = 255; i >= 0; i--) current_font->per_char_256[i] = FONT_PER_CHAR (i);}/* this tries to keep the array of cached of font widths as small ever needed - i.e. only enlarges on lookups */static void _font_per_char (wchar_t c){ if (!current_font->per_char) { current_font->num_per_char = c + 1; current_font->per_char = CMalloc (current_font->num_per_char * sizeof (fontdim_t)); memset (current_font->per_char, 0xFF, current_font->num_per_char * sizeof (fontdim_t)); } else if (c >= current_font->num_per_char) { long l; fontdim_t *t; l = c + 256; t = CMalloc (l * sizeof (fontdim_t)); memcpy (t, current_font->per_char, current_font->num_per_char * sizeof (fontdim_t)); memset (t + current_font->num_per_char, 0xFF, (l - current_font->num_per_char) * sizeof (fontdim_t)); free (current_font->per_char); current_font->per_char = t; current_font->num_per_char = l; } if (current_font->per_char[c].width == 0xFF) { int d; current_font->per_char[c].width = get_wchar_dimension (c, 0, 0, &d); current_font->per_char[c].descent = (unsigned char) d; if (FIXED_FONT) if ((current_font->per_char[c].width != FIXED_FONT) && current_font->per_char[c].width) FIXED_FONT = 0; }}int font_per_char (wchar_t c){ if ((unsigned long) c > FONT_LAST_UNICHAR) return 0; _font_per_char (c); return current_font->per_char[c].width;}int font_per_char_descent (wchar_t c){ if ((unsigned long) c > FONT_LAST_UNICHAR) return 0; _font_per_char (c); return current_font->per_char[c].descent;}/* seems you cannot draw different fonts in the same GC. this is strange???, so we create a dummy GC for each font */static Window get_dummy_gc (void){ static Window dummy_window = 0; XGCValues gcv; if (!dummy_window) { XSetWindowAttributes xswa; xswa.override_redirect = 1; dummy_window = XCreateWindow (CDisplay, CRoot, 0, 0, 1, 1, 0, CDepth, InputOutput, CVisual, CWOverrideRedirect, &xswa); } gcv.foreground = COLOR_BLACK; if (current_font->font_struct) { gcv.font = current_font->font_struct->fid; CGC = XCreateGC (CDisplay, dummy_window, GCForeground | GCFont, &gcv); } else { CGC = XCreateGC (CDisplay, dummy_window, GCForeground, &gcv); } return dummy_window;}static XFontSet get_font_set (char *name){ XFontSet fontset; char **a = 0; int b; if (!XSupportsLocale ()) fprintf (stderr, "X does not support the locale: %s\n", setlocale (LC_CTYPE, 0)); fontset = XCreateFontSet (CDisplay, name, &a, &b, 0); if (!fontset) return 0; XFreeStringList (a); return fontset;}/* loads a font and sets the current font to it */static struct font_object *load_font (char *name, char *xname){ int aa = 0; struct font_object *n; Window w; char *p; xname = (char *) strdup (xname); if ((p = strchr (xname, '/'))) { aa = 1; if (atoi (p + 1) != 3) { fprintf (stderr, _("%s: cannot load font\n\t%s\n<font-name>/3 is allowed only.\n"), CAppName, xname); free (xname); return 0; } *p = '\0'; } n = CMalloc (sizeof (struct font_object)); memset (n, 0, sizeof (struct font_object)); if (!option_no_font_set) { n->font_set = get_font_set (xname); if (!n->font_set) fprintf (stderr, _("%s: display %s cannot load font\n\t%s\nas a font set - trying raw load.\n"), CAppName, DisplayString (CDisplay), xname);/* font set may have failed only because of an invalid locale, but we try load the font anyway */ } if (!n->font_set && !strchr (xname, ',')) { n->font_struct = XLoadQueryFont (CDisplay, xname); n->free_font_struct = 1; } if (!n->font_struct && !n->font_set) { fprintf (stderr, _("%s: display %s cannot load font\n\t%s\n"), CAppName, DisplayString (CDisplay), xname); free (n); free (xname); return 0; } n->next = all_fonts; current_font = all_fonts = n; n->name = (char *) strdup (name);/* font set may have worked, but if there is only one font, we might as well try use a font struct (which draws faster) */ if (current_font->font_set && !current_font->font_struct) { int i, num_fonts, single_font = 1; XFontStruct **font_struct_list_return = 0; char **font_name_list_return = 0; num_fonts = XFontsOfFontSet (current_font->font_set, &font_struct_list_return, &font_name_list_return);/* check if there is really only one font */ for (i = 1; i < num_fonts; i++) { if (strcmp (font_name_list_return[0], font_name_list_return[1])) { single_font = 0; break; } } if (single_font) { current_font->font_struct = XQueryFont (CDisplay, font_struct_list_return[0]->fid); current_font->free_font_struct = 0; } } if (current_font->font_struct) FONT_ANTIALIASING = aa; w = get_dummy_gc (); if (FONT_USE_FONT_SET) XmbDrawImageString (CDisplay, w, current_font->font_set, CGC, 0, 0, " AZ~", 4); else XDrawImageString (CDisplay, w, CGC, 0, 0, " AZ~", 4); FIXED_FONT = check_font_fixed (); get_font_dimensions ();/* -----> FIXME: yes, you actually HAVE to draw with the GC for the font to stick. can someone tell me what I am doing wrong? */ if (!current_font->font_set)/* font list like rxvt. FIXME: make rxvt and this see same font list */ current_font->font_set = get_font_set ("7x14,6x10,6x13,8x13,9x15"); free (xname); return current_font;}int CPushFont (char *name, char *xname){ struct font_stack *p; struct font_object *f; f = find_font (name); if (f) { f->ref++; } else { f = load_font (name, xname); if (!f) return 1; f->ref = 1; } p = CMalloc (sizeof (struct font_stack)); p->f = f; p->next = font_stack; font_stack = p; current_font = font_stack->f; return 0;}void CPopFont (void){ struct font_stack *p; if (!font_stack) { fprintf (stderr, "Huh\n?"); abort (); } if (!--font_stack->f->ref) { if (font_stack->f->gc) XFreeGC (CDisplay, font_stack->f->gc); if (font_stack->f->font_set) XFreeFontSet (CDisplay, font_stack->f->font_set); if (font_stack->f->font_struct) { XAaFree (font_stack->f->font_struct->fid); if (font_stack->f->free_font_struct) XFreeFont (CDisplay, font_stack->f->font_struct); else XFreeFontInfo (0, font_stack->f->font_struct, 0); } if (font_stack->f->per_char) free (font_stack->f->per_char); free (font_stack->f->name); free (font_stack->f); } p = font_stack->next; if (p) { current_font = p->f; } else { current_font = 0; } free (font_stack); font_stack = p;}void CFreeAllFonts (void){ int i = 0; while (font_stack) { CPopFont (); i++; }}int CIsFixedFont (void){ return FIXED_FONT;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -