📄 pangox-fontmap.c
字号:
False); XGetWindowProperty (display, DefaultRootWindow (display), coverage_win_atom, 0, 4, False, XA_WINDOW, &type, &format, &n_items, &bytes_after, &data); if (type == XA_WINDOW) { if (format == 32 && n_items == 1 && bytes_after == 0) retval = *(Atom *)data; XFree (data); } old_handler= XSetErrorHandler (ignore_error); if (XGetWindowProperty (display, retval, coverage_win_atom, 0, 4, False, XA_WINDOW, &type, &format, &n_items, &bytes_after, &data) == Success && type == XA_WINDOW) { if (format != 32 || n_items != 1 || bytes_after != 0 || *(Atom *)data != retval) retval = None; XFree (data); } else retval = None; XSync (display, False); XSetErrorHandler (old_handler); return retval;}/* Find or create the persistent window for caching font coverage * information. * * To assure atomic creation, we first look for the window, then if we * don't find it, grab the server, look for it again, and then if that * still didn't find it, create it and ungrab. */static Windowpango_x_get_coverage_win (PangoXFontMap *xfontmap){ if (!xfontmap->coverage_win) xfontmap->coverage_win = pango_x_real_get_coverage_win (xfontmap->display); if (!xfontmap->coverage_win) { Display *persistant_display; persistant_display = XOpenDisplay (DisplayString (xfontmap->display)); if (!persistant_display) { g_warning ("Cannot create or retrieve display for font coverage cache"); return None; } XGrabServer (persistant_display); xfontmap->coverage_win = pango_x_real_get_coverage_win (xfontmap->display); if (!xfontmap->coverage_win) { XSetWindowAttributes attr; attr.override_redirect = True; XSetCloseDownMode (persistant_display, RetainPermanent); xfontmap->coverage_win = XCreateWindow (persistant_display, DefaultRootWindow (persistant_display), -100, -100, 10, 10, 0, 0, InputOnly, CopyFromParent, CWOverrideRedirect, &attr); XChangeProperty (persistant_display, DefaultRootWindow (persistant_display), XInternAtom (persistant_display, "PANGO_COVERAGE_WIN", FALSE), XA_WINDOW, 32, PropModeReplace, (guchar *)&xfontmap->coverage_win, 1); XChangeProperty (persistant_display, xfontmap->coverage_win, XInternAtom (persistant_display, "PANGO_COVERAGE_WIN", FALSE), XA_WINDOW, 32, PropModeReplace, (guchar *)&xfontmap->coverage_win, 1); } XUngrabServer (persistant_display); XSync (persistant_display, False); XCloseDisplay (persistant_display); } return xfontmap->coverage_win;}/* Find the cached value for the coverage map on the * coverage cache window, if it exists. *atom is set * to the interned value of str for later use in storing * the property if the lookup fails */static PangoCoverage *pango_x_get_cached_coverage (PangoXFontMap *xfontmap, const char *str, Atom *atom){ int (*old_handler) (Display *, XErrorEvent *); Window coverage_win; PangoCoverage *result = NULL; Atom type; int format; int tries = 5; gulong n_items; gulong bytes_after; guchar *data; *atom = XInternAtom (xfontmap->display, str, False); while (tries--) { coverage_win = pango_x_get_coverage_win (xfontmap); if (!coverage_win) return NULL; old_handler= XSetErrorHandler (ignore_error); if (XGetWindowProperty (xfontmap->display, coverage_win, *atom, 0, G_MAXLONG, False, XA_STRING, &type, &format, &n_items, &bytes_after, &data) == Success && type == XA_STRING) { if (format == 8 && bytes_after == 0) result = pango_coverage_from_bytes (data, n_items); XSetErrorHandler (old_handler); XFree (data); break; } else { /* Window disappeared out from under us */ XSetErrorHandler (old_handler); xfontmap->coverage_win = None; } } return result;}/* Store the given coverage map on the coverage cache window. * atom is the intern'ed value of the string that identifies * the cache entry. */static voidpango_x_store_cached_coverage (PangoXFontMap *xfontmap, Atom atom, PangoCoverage *coverage){ int (*old_handler) (Display *, XErrorEvent *); guchar *bytes; gint size; int tries = 5; pango_coverage_to_bytes (coverage, &bytes, &size); while (tries--) { Window coverage_win = pango_x_get_coverage_win (xfontmap); if (!coverage_win) break; old_handler = XSetErrorHandler (ignore_error); error_occurred = False; XChangeProperty (xfontmap->display, coverage_win, atom, XA_STRING, 8, PropModeReplace, bytes, size); XSync (xfontmap->display, False); XSetErrorHandler (old_handler); if (!error_occurred) break; else { /* Window disappeared out from under us */ XSetErrorHandler (old_handler); xfontmap->coverage_win = None; } } g_free (bytes);}static voidpango_x_font_map_read_alias_file (PangoXFontMap *xfontmap, const char *filename){ FILE *infile; char **xlfds; int lineno = 0; int i; PangoXFace *xface = NULL; infile = fopen (filename, "r"); if (infile) { GString *line_buf = g_string_new (NULL); GString *tmp_buf = g_string_new (NULL); gint lines_read; while ((lines_read = pango_read_line (infile, line_buf))) { PangoXFamily *font_family; PangoStyle style; PangoVariant variant; PangoWeight weight; PangoStretch stretch; const char *p = line_buf->str; lineno += lines_read; if (!pango_skip_space (&p)) continue; if (!pango_scan_string (&p, tmp_buf)) goto error; xface = g_object_new (PANGO_X_TYPE_FACE, NULL); xface->xlfd = NULL; xface->description = pango_font_description_new (); g_string_ascii_down (tmp_buf); pango_font_description_set_family (xface->description, tmp_buf->str); if (!pango_scan_string (&p, tmp_buf)) goto error; if (!pango_parse_style (tmp_buf->str, &style, TRUE)) goto error; pango_font_description_set_style (xface->description, style); if (!pango_scan_string (&p, tmp_buf)) goto error; if (!pango_parse_variant (tmp_buf->str, &variant, TRUE)) goto error; pango_font_description_set_variant (xface->description, variant); if (!pango_scan_string (&p, tmp_buf)) goto error; if (!pango_parse_weight (tmp_buf->str, &weight, TRUE)) goto error; pango_font_description_set_weight (xface->description, weight); if (!pango_scan_string (&p, tmp_buf)) goto error; if (!pango_parse_stretch (tmp_buf->str, &stretch, TRUE)) goto error; pango_font_description_set_stretch (xface->description, stretch); if (!pango_scan_string (&p, tmp_buf)) goto error; /* Remove excess whitespace and check for complete fields */ xlfds = g_strsplit (tmp_buf->str, ",", -1); for (i=0; xlfds[i]; i++) { char *trimmed = pango_trim_string (xlfds[i]); g_free (xlfds[i]); xlfds[i] = trimmed; if (!pango_x_is_xlfd_font_name (xlfds[i])) { g_warning ("XLFD '%s' must be complete (14 fields)", xlfds[i]); g_strfreev (xlfds); goto error; } } xface->xlfd = g_strjoinv (",", xlfds); g_strfreev (xlfds); /* Insert the font entry into our structures */ font_family = pango_x_get_font_family (xfontmap, pango_font_description_get_family (xface->description)); font_family->font_entries = g_slist_prepend (font_family->font_entries, xface); xfontmap->n_fonts++; /* Save space by consolidating duplicated string */ pango_font_description_set_family_static (xface->description, font_family->family_name); xface->cached_fonts = NULL; xface->coverage = NULL; } if (ferror (infile)) g_warning ("Error reading '%s': %s", filename, g_strerror(errno)); goto out; error: if (xface) { g_free (xface->xlfd); if (xface->description) pango_font_description_free (xface->description); g_free (xface); } g_warning ("Error parsing line %d of alias file '%s'", lineno, filename); out: g_string_free (tmp_buf, TRUE); g_string_free (line_buf, TRUE); fclose (infile); }}static voidpango_x_font_map_read_aliases (PangoXFontMap *xfontmap){ char **files; char *files_str = pango_config_key_get ("PangoX/AliasFiles"); int n; if (!files_str) files_str = g_strdup ("~/.pangox_aliases:" SYSCONFDIR "/pango/pangox.aliases"); files = pango_split_file_list (files_str); n = 0; while (files[n]) n++; while (n-- > 0) pango_x_font_map_read_alias_file (xfontmap, files[n]); g_strfreev (files); g_free (files_str);}/* * Returns %TRUE if the fontname is a valid XLFD. * (It just checks if the number of dashes is 14, and that each * field < XLFD_MAX_FIELD_LEN characters long - that's not in the XLFD but it * makes it easier for me). */static gbooleanpango_x_is_xlfd_font_name (const char *fontname){ int i = 0; int field_len = 0; while (*fontname) { if (*fontname++ == '-') { if (field_len > XLFD_MAX_FIELD_LEN) return FALSE; field_len = 0; i++; } else field_len++; } return (i == 14) ? TRUE : FALSE;}static intpango_x_get_size (PangoXFontMap *xfontmap, const char *fontname){ char size_buffer[XLFD_MAX_FIELD_LEN]; int size; if (!pango_x_get_xlfd_field (fontname, XLFD_PIXELS, size_buffer)) return -1; size = atoi (size_buffer); if (size != 0) { return (int)(0.5 + size * xfontmap->resolution); } else { /* We use the trick that scaled bitmaps have a non-zero RESOLUTION_X, while * actual scaleable fonts have a zero RESOLUTION_X */ if (!pango_x_get_xlfd_field (fontname, XLFD_RESOLUTION_X, size_buffer)) return -1; if (atoi (size_buffer) == 0) return 0; else return -1; }}static char *pango_x_get_identifier (const char *fontname){ const char *p = fontname; const char *start; int n_dashes = 0; while (n_dashes < 2) { if (*p == '-') n_dashes++; p++; } start = p; while (n_dashes < 6) { if (*p == '-') n_dashes++; p++; } return g_strndup (start, (p - 1 - start));}/* * This fills the buffer with the specified field from the X Logical Font * Description name, and returns it. If fontname is %NULL or the field is * longer than XFLD_MAX_FIELD_LEN it returns %NULL. * Note: For the charset field, we also return the encoding, e.g. 'iso8859-1'. */static char*pango_x_get_xlfd_field (const char *fontname, FontField field_num, char *buffer){ const char *t1, *t2; char *p; int countdown, len, num_dashes; if (!fontname) return NULL; /* we assume this is a valid fontname...that is, it has 14 fields */ countdown = field_num; t1 = fontname; while (*t1 && (countdown >= 0)) if (*t1++ == '-') countdown--; num_dashes = (field_num == XLFD_CHARSET) ? 2 : 1; for (t2 = t1; *t2; t2++) { if (*t2 == '-' && --num_dashes == 0) break; } if (t1 != t2) { /* Check we don't overflow the buffer */ len = (long) t2 - (long) t1; if (len > XLFD_MAX_FIELD_LEN - 1) return NULL; strncpy (buffer, t1, len); buffer[len] = 0; /* Convert to lower case. */ for (p = buffer; *p; p++) *p = g_ascii_tolower (*p); } else strcpy(buffer, "(nil)"); return buffer;}/* This inserts the given fontname into the FontInfo table. If a FontInfo already exists with the same family and foundry, then the fontname is added to the FontInfos list of fontnames, else a new FontInfo is created and inserted in alphabetical order in the table. */static voidpango_x_insert_font (PangoXFontMap *xfontmap, const char *fontname){ PangoFontDescription *description; char *family_name; PangoStyle style; PangoVariant variant; PangoWeight weight; PangoStretch stretch; char family_buffer[XLFD_MAX_FIELD_LEN]; char weight_buffer[XLFD_MAX_FIELD_LEN]; char slant_buffer[XLFD_MAX_FIELD_LEN]; char set_width_buffer[XLFD_MAX_FIELD_LEN]; GSList *tmp_list; PangoXFamily *font_family; PangoXFace *xface; PangoXSizeInfo *size_info; char *identifier; unsigned int i; /* First insert the XLFD into the list of XLFDs for the "identifier" - which * is the 2-4th fields of the XLFD */ identifier = pango_x_get_identifier (fontname); size_info = g_hash_table_lookup (xfontmap->size_infos, identifier); if (!size_info) { size_info = g_new (PangoXSizeInfo, 1); size_info->identifier = identifier; size_info->xlfds = NULL; g_hash_table_insert (xfontmap->size_infos, identifier, size_info); } else g_free (identifier); size_info->xlfds = g_slist_prepend (size_info->xlfds, g_strdup (fontname)); /* Convert the XLFD into a PangoFontDescription */ family_name = pango_x_get_xlfd_field (fontname, XLFD_FAMILY, family_buffer); if (!family_name) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -