diff options
author | Roland Mainz <roland.mainz@nrubsig.org> | 2004-10-06 19:29:59 +0000 |
---|---|---|
committer | Roland Mainz <roland.mainz@nrubsig.org> | 2004-10-06 19:29:59 +0000 |
commit | 856414eb1a5a20f379472b9eaa0f114c6c18d806 (patch) | |
tree | 7a0ed184aa288d58a840c1455989f68ff4a06613 | |
parent | 27d3336d79d9915a1b33be561e99bd24c3b474d8 (diff) |
Fix for https://freedesktop.org/bugzilla/show_bug.cgi?id=1518 - Add filter
support to "xlsfonts" that it can filter builtin-, glyph- and/or other
kinds of printer fonts (controlled by the xp-listfonts-modes attribute
as described in the CDE DtPrint and Xprint specifications).
-rw-r--r-- | dsimple.c | 109 | ||||
-rw-r--r-- | dsimple.h | 16 | ||||
-rw-r--r-- | xlsfonts.c | 1098 |
3 files changed, 754 insertions, 469 deletions
@@ -41,6 +41,9 @@ from The Open Group. * Written by Mark Lillibridge. Last updated 7/1/87 */ +#ifdef BUILD_PRINTSUPPORT +#include <X11/XprintUtil/xprintutil.h> +#endif /* BUILD_PRINTSUPPORT */ #include "dsimple.h" /* @@ -55,9 +58,13 @@ from The Open Group. /* This stuff is defined in the calling program by just_display.h */ -char *program_name = "unknown_program"; -Display *dpy; -int screen; +char *program_name = "unknown_program"; +Display *dpy = NULL; +int screen = 0; +Bool printer_output = False; /* Video or printer output ? */ +#ifdef BUILD_PRINTSUPPORT +XPContext pcontext = None; +#endif /* BUILD_PRINTSUPPORT */ static void _bitmap_error(int, char *); @@ -131,6 +138,43 @@ char *Get_Display_Name(pargc, argv) } +#ifdef BUILD_PRINTSUPPORT +/* + * Get_Printer_Name (argc, argv) Look for -printer, -p, + * If found, remove it from command line. Don't go past a lone -. + */ +char *Get_Printer_Name(pargc, argv) + int *pargc; /* MODIFIED */ + char **argv; /* MODIFIED */ +{ + int argc = *pargc; + char **pargv = argv+1; + char *printername = NULL; + int i; + + for (i = 1; i < argc; i++) { + char *arg = argv[i]; + + if (!strcmp (arg, "-printer") || !strcmp (arg, "-p")) { + if (++i >= argc) usage (); + + printername = argv[i]; + *pargc -= 2; + continue; + } + if (!strcmp(arg,"-")) { + while (i<argc) + *pargv++ = argv[i++]; + break; + } + *pargv++ = arg; + } + + *pargv = NULL; + return (printername); +} +#endif /* BUILD_PRINTSUPPORT */ + /* * Open_Display: Routine to open a display with correct error handling. * Does not require dpy or screen defined on entry. @@ -163,8 +207,60 @@ void Setup_Display_And_Screen(argc, argv) int *argc; /* MODIFIED */ char **argv; /* MODIFIED */ { - dpy = Open_Display (Get_Display_Name(argc, argv)); - screen = DefaultScreen(dpy); + char *displayname = NULL, + *printername = NULL; + + displayname = Get_Display_Name(argc, argv); +#ifdef BUILD_PRINTSUPPORT + printername = Get_Printer_Name(argc, argv); + + if (displayname && printername) { + fprintf (stderr, "%s: you cannot specify -printer (-p) and -display (-d) at the same time.\n", + program_name); + usage (); + } + + if (printername) { + printer_output = True; + + if (XpuGetPrinter(printername, &dpy, &pcontext) != 1) { + fprintf(stderr, "%s: Cannot open printer '%s'.\n", program_name, printername); + exit(EXIT_FAILURE); + } + + screen = XScreenNumberOfScreen(XpGetScreenOfContext(dpy, pcontext)); + } + else +#endif /* BUILD_PRINTSUPPORT */ + { + printer_output = False; + + dpy = Open_Display (displayname); + screen = XDefaultScreen(dpy); + } +} + +/* + * Close_Display: Close display + */ +void Close_Display(void) +{ + if (dpy == NULL) + return; + +#ifdef BUILD_PRINTSUPPORT + if (printer_output) { + XpuClosePrinterDisplay(dpy, pcontext); + dpy = NULL; + pcontext = None; + printer_output = False; + } + else +#endif /* BUILD_PRINTSUPPORT */ + { + XCloseDisplay(dpy); + dpy = NULL; + } } @@ -517,5 +613,6 @@ void Fatal_Error(char *msg, ...) vfprintf(stderr, msg, args); va_end(args); fprintf(stderr, "\n"); - exit(1); + Close_Display(); + exit(EXIT_FAILURE); } @@ -39,11 +39,23 @@ from The Open Group. * Send bugs, etc. to chariot@athena.mit.edu. */ + /* Simple helper macros */ +#ifndef MAX +#define MAX(a,b) (((a)>(b))?(a):(b)) +#endif /* MAX */ +#ifndef MIN +#define MIN(a,b) (((a)<(b))?(a):(b)) +#endif /* MIN */ + /* Global variables used by routines in just_display.c */ extern char *program_name; /* Name of this program */ extern Display *dpy; /* The current display */ extern int screen; /* The current screen */ +extern Bool printer_output; /* Video or printer output ? */ +#ifdef BUILD_PRINTSUPPORT +extern XPContext pcontext; /* The current print context */ +#endif /* BUILD_PRINTSUPPORT */ #define INIT_NAME program_name=argv[0] /* use this in main to setup program_name */ @@ -53,8 +65,12 @@ extern int screen; /* The current screen */ char *Malloc(unsigned); char *Realloc(char *, int); char *Get_Display_Name(int *, char **); +#ifdef BUILD_PRINTSUPPORT +char *Get_Printer_Name(int *, char **); +#endif /* BUILD_PRINTSUPPORT */ Display *Open_Display(char *); void Setup_Display_And_Screen(int *, char **); +void Close_Display(void); XFontStruct *Open_Font(char *); void Beep(void); Pixmap ReadBitmapFile(Drawable, char *, int *, int *, int *, int *); @@ -31,407 +31,575 @@ in this Software without prior written authorization from The Open Group. #include <X11/Xos.h> #include <stdio.h> #include <stdlib.h> +#include <limits.h> +#ifdef BUILD_PRINTSUPPORT +#include <X11/XprintUtil/xprintutil.h> +#endif /* BUILD_PRINTSUPPORT */ #include "dsimple.h" -#define N_START 1000 /* Maximum # of fonts to start with */ +#define N_START INT_MAX /* Maximum # of fonts to start with (should + * always be be > 10000 as modern OSes like + * Solaris 8 already have more than 9000 XLFD + * fonts available) */ -int max_output_line_width = 79; -int output_line_padding = 3; -int columns = 0; - -#define L_SHORT 0 -#define L_MEDIUM 1 -#define L_LONG 2 +#define L_SHORT 0 +#define L_MEDIUM 1 +#define L_LONG 2 #define L_VERYLONG 3 -Bool sort_output = True; -Bool open_instead_of_list = False; -int long_list = L_SHORT; -int nnames = N_START; -int font_cnt; -int min_max; +static int max_output_line_width = 79; +static int output_line_padding = 3; +static int columns = 0; + +static Bool sort_output = True; +static Bool open_instead_of_list = False; +static int long_list = L_SHORT; +static int nnames = N_START; +static int font_cnt = 0; +static int min_max; + typedef struct { - char *name; - XFontStruct *info; + char *name; + XFontStruct *info; +#ifdef BUILD_PRINTSUPPORT + char *listfonts_modes; +#endif /* BUILD_PRINTSUPPORT */ } FontList; -FontList *font_list; +static FontList *font_list = NULL; -static void get_list(char *); +/* Local prototypes */ +#ifdef BUILD_PRINTSUPPORT +static Bool IsListfontsModesChangeSupported(char *mode); +static int SetListfontsModes(const char *attrname, Bool enableattr); +#endif /* BUILD_PRINTSUPPORT */ +static void get_list(char *pattern); +static int compare(const void *arg1, const void *arg2); static void show_fonts(void); -static void copy_number(char **, char **, int, int); -static void do_query_font(Display *, char *); -static int compare(const void *, const void *); -#ifndef max -static int max(int, int); -#endif -static int IgnoreError(Display *, XErrorEvent *); -static void PrintProperty(XFontProp *); -static void ComputeFontType(XFontStruct *); -static void print_character_metrics(register XFontStruct *); - - -void -usage() +static void copy_number(char **pp1, char**pp2, int n1, int n2); +static int IgnoreError(Display *disp, XErrorEvent *event); +static void PrintProperty(XFontProp *prop); +static void ComputeFontType(XFontStruct *fs); +static void print_character_metrics(register XFontStruct *info); +static void do_query_font (Display *dpy, char *name); + +void usage(void) +{ + fprintf (stderr, "usage: %s [-options] [-fn pattern]\n", program_name); + fprintf (stderr, "where options include:\n"); + fprintf (stderr, " -l[l[l]] give long info about each font\n"); + fprintf (stderr, " -m give character min and max bounds\n"); + fprintf (stderr, " -C force columns\n"); + fprintf (stderr, " -1 force single column\n"); + fprintf (stderr, " -u keep output unsorted\n"); +#ifdef BUILD_PRINTSUPPORT + fprintf (stderr, " -b list printer builtin fonts (default)\n"); + fprintf (stderr, " -B do not list printer builtin fonts\n"); + fprintf (stderr, " -g list glyph fonts (default)\n"); + fprintf (stderr, " -G do not list glyph fonts\n"); + fprintf (stderr, " -x mode enable listfont mode\n"); + fprintf (stderr, " -X mode disable listfont mode\n"); +#endif /* BUILD_PRINTSUPPORT */ + fprintf (stderr, " -o use OpenFont/QueryFont instead of ListFonts\n"); + fprintf (stderr, " -w width maximum width for multiple columns\n"); + fprintf (stderr, " -n columns number of columns if multi column\n"); + fprintf (stderr, " -display displayname X server to contact\n"); + fprintf (stderr, " -d displayname (alias for -display displayname)\n"); +#ifdef BUILD_PRINTSUPPORT + fprintf (stderr, " -printer printername printer to use\n"); + fprintf (stderr, " -p printername (alias for -p printername)\n"); +#endif /* BUILD_PRINTSUPPORT */ + fprintf (stderr, "\n"); + Close_Display(); + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) { - fprintf (stderr,"usage: %s [-options] [-fn pattern]\n", program_name); - fprintf (stderr, "where options include:\n"); - fprintf (stderr, - " -l[l[l]] give long info about each font\n"); - fprintf (stderr, - " -m give character min and max bounds\n"); - fprintf (stderr, - " -C force columns\n"); - fprintf (stderr, - " -1 force single column\n"); - fprintf (stderr, - " -u keep output unsorted\n"); - fprintf (stderr, - " -o use OpenFont/QueryFont instead of ListFonts\n"); - fprintf (stderr, - " -w width maximum width for multiple columns\n"); - fprintf (stderr, - " -n columns number of columns if multi column\n"); - fprintf (stderr, - " -display displayname X server to contact\n"); - fprintf (stderr, - "\n"); - exit(1); + int argcnt = 0, i; + char *mode; + + INIT_NAME; + + /* Handle command line arguments, open display */ + Setup_Display_And_Screen(&argc, argv); + +#ifdef BUILD_PRINTSUPPORT + if (printer_output) { + /* XListFonts*()/XLoadFont*() honor xp-listfonts-modes only + * if there is an context _SET_ for this display */ + XpSetContext(dpy, pcontext); + } +#endif /* BUILD_PRINTSUPPORT */ + + for (argv++, argc--; argc; argv++, argc--) { + if (argv[0][0] == '-') { + if (argcnt > 0) usage (); + for (i=1; argv[0][i]; i++) + switch(argv[0][i]) { + case 'l': + long_list++; + break; + case 'm': + min_max++; + break; + case 'C': + columns = 0; + break; + case '1': + columns = 1; + break; + case 'f': /* "-fn" */ + if (--argc <= 0) usage (); + if (argv[0][i+1] != 'n') usage (); + argcnt++; + argv++; + get_list(argv[0]); + goto next; + case 'w': + if (--argc <= 0) usage (); + argv++; + max_output_line_width = atoi(argv[0]); + goto next; + case 'n': + if (--argc <= 0) usage (); + argv++; + columns = atoi(argv[0]); + goto next; + case 'o': + open_instead_of_list = True; + break; + case 'u': + sort_output = False; + break; +#ifdef BUILD_PRINTSUPPORT + case 'b': + mode = "xp-list-internal-printer-fonts"; + if (!printer_output) + Fatal_Error("Option '%c' only supported for printers.", argv[0][i]); + if (!IsListfontsModesChangeSupported(mode)) + Fatal_Error("Printer does not support changing '%s'.", mode); + SetListfontsModes(mode, True); + break; + case 'B': + mode = "xp-list-internal-printer-fonts"; + if (!printer_output) + Fatal_Error("Option '%c' only supported for printers.", argv[0][i]); + if (!IsListfontsModesChangeSupported(mode)) + Fatal_Error("Printer does not support changing '%s'.", mode); + SetListfontsModes(mode, False); + break; + case 'g': + mode = "xp-list-glyph-fonts"; + if (!printer_output) + Fatal_Error("Option '%c' only supported for printers.", argv[0][i]); + if (!IsListfontsModesChangeSupported(mode)) + Fatal_Error("Printer does not support changing '%s'.", mode); + SetListfontsModes(mode, True); + break; + case 'G': + mode = "xp-list-glyph-fonts"; + if (!printer_output) + Fatal_Error("Option '%c' only supported for printers.", argv[0][i]); + if (!IsListfontsModesChangeSupported(mode)) + Fatal_Error("Printer does not support changing '%s'.", mode); + SetListfontsModes(mode, False); + break; + case 'x': + if (--argc <= 0) usage (); + argv++; + mode = argv[0]; + if (!printer_output) + Fatal_Error("Option '%c' only supported for printers.", argv[0][i-1]); + if (!IsListfontsModesChangeSupported(mode)) + Fatal_Error("Printer does not support changing '%s'.", mode); + SetListfontsModes(mode, True); + goto next; + case 'X': + if (--argc <= 0) usage (); + argv++; + mode = argv[0]; + if (!printer_output) + Fatal_Error("Option '%c' only supported for printers.", argv[0][i-1]); + if (!IsListfontsModesChangeSupported(mode)) + Fatal_Error("Printer does not support changing '%s'.", mode); + SetListfontsModes(mode, False); + goto next; +#endif /* BUILD_PRINTSUPPORT */ + default: + usage(); + break; + } + if (i == 1) + usage(); + } else { + argcnt++; + get_list(argv[0]); + } + next: ; + } + + if (argcnt == 0) + get_list("*"); + + show_fonts(); + + Close_Display(); + return EXIT_SUCCESS; } -int -main(argc, argv) -int argc; -char **argv; +#ifdef BUILD_PRINTSUPPORT +/* This should be moved to XprintUtils */ +static +Bool IsListfontsModesChangeSupported(char *mode) { - int argcnt = 0, i; - - INIT_NAME; - - /* Handle command line arguments, open display */ - Setup_Display_And_Screen(&argc, argv); - for (argv++, argc--; argc; argv++, argc--) { - if (argv[0][0] == '-') { - if (argcnt > 0) usage (); - for (i=1; argv[0][i]; i++) - switch(argv[0][i]) { - case 'l': - long_list++; - break; - case 'm': - min_max++; - break; - case 'C': - columns = 0; - break; - case '1': - columns = 1; - break; - case 'f': - if (--argc <= 0) usage (); - argcnt++; - argv++; - get_list(argv[0]); - goto next; - case 'w': - if (--argc <= 0) usage (); - argv++; - max_output_line_width = atoi(argv[0]); - goto next; - case 'n': - if (--argc <= 0) usage (); - argv++; - columns = atoi(argv[0]); - goto next; - case 'o': - open_instead_of_list = True; - break; - case 'u': - sort_output = False; - break; - default: - usage(); - break; - } - if (i == 1) - usage(); - } else { - argcnt++; - get_list(argv[0]); - } - next: ; - } - if (argcnt == 0) - get_list("*"); - show_fonts(); - exit(0); + char *value; + Bool isSupported; + + value = XpGetOneAttribute(dpy, pcontext, XPPrinterAttr, "xp-listfonts-modes-supported"); + if (!value) + return False; + + isSupported = (strstr(value, mode) != NULL)?(True):(False); + XFree(value); + + return isSupported; } -void -get_list(pattern) - char *pattern; +/* XXX: This should be moved to XprintUtils (and should have a Document/Page-level + * option and should verify that the matching leven supports xp-listfonts-modes + * changes)*/ +static +int SetListfontsModes(const char *attrname, Bool enableattr) { - int available = nnames+1, - i; - char **fonts; - XFontStruct *info; - - /* Get list of fonts matching pattern */ - for (;;) { - if (open_instead_of_list) { - info = XLoadQueryFont (dpy, pattern); - - if (info) { - fonts = &pattern; - available = 1; - XUnloadFont (dpy, info->fid); - } else { - fonts = NULL; - } - break; - } - - if (long_list == L_MEDIUM) - fonts = XListFontsWithInfo(dpy, - pattern, nnames, &available, &info); - else - fonts = XListFonts(dpy, pattern, nnames, &available); - if (fonts == NULL || available < nnames) - break; - if (long_list == L_MEDIUM) - XFreeFontInfo(fonts, info, available); - else - XFreeFontNames(fonts); - nnames = available * 2; - } - - if (fonts == NULL) { - fprintf(stderr, "%s: pattern \"%s\" unmatched\n", - program_name, pattern); - return; - } - - font_list = (FontList *)Realloc((char *)font_list, - (font_cnt + available) * sizeof(FontList)); - for (i=0; i<available; i++) { - font_list[font_cnt].name = fonts[i]; - if (long_list == L_MEDIUM) - font_list[font_cnt].info = info + i; - else - font_list[font_cnt].info = NULL; - font_cnt++; - } + char *value, + *newvalue; + + value = XpGetOneAttribute(dpy, pcontext, XPDocAttr, "xp-listfonts-modes"); + if (!value) + value = strdup(""); + + /* Set attribute */ + if (enableattr) + { + /* Return success if |attrname| is already set */ + if (strstr(value, attrname) != NULL) + { + XFree(value); + return 1; /* success */ + } + + newvalue = malloc(strlen(value) + strlen(attrname) + 2); + if (!newvalue) + { + XFree(value); + Fatal_Error("SetListfontsModes: No memory."); + } + + sprintf(newvalue, "%s %s", value, attrname); + XpuSetOneAttribute(dpy, pcontext, XPDocAttr, "*xp-listfonts-modes", newvalue, XPAttrMerge); + + free(newvalue); + XFree(value); + return 1; /* success */ + } + else + { + char *s, /* copy string "source" */ + *d; /* copy string "destination" */ + + /* Return success if |attrname| not set */ + d = strstr(value, attrname); + if (d == NULL) + { + XFree(value); + return 1; /* success */ + } + + /* strip |attrname| from |value| */ + s = d+strlen(attrname); + while( (*d++ = *s++) != '\0' ) + ; + + XpuSetOneAttribute(dpy, pcontext, XPDocAttr, "*xp-listfonts-modes", value, XPAttrMerge); + + XFree(value); + return 1; /* success */ + } } +#endif /* BUILD_PRINTSUPPORT */ -static int -compare(arg1, arg2) - const void *arg1; - const void *arg2; +static +void get_list(char *pattern) { - const FontList *f1 = arg1; - const FontList *f2 = arg2; - const char *p1 = f1->name; - const char *p2 = f2->name; - - while (*p1 && *p2 && *p1 == *p2) - p1++, p2++; - return(*p1 - *p2); + int available = nnames+1, + i; + char **fonts; + XFontStruct *info; + + /* Get list of fonts matching pattern */ + for (;;) { + if (open_instead_of_list) { + info = XLoadQueryFont (dpy, pattern); + + if (info) { + fonts = &pattern; + available = 1; + XUnloadFont (dpy, info->fid); + } else { + fonts = NULL; + } + break; + } + + if (long_list == L_MEDIUM) + fonts = XListFontsWithInfo(dpy, pattern, nnames, &available, &info); + else + fonts = XListFonts(dpy, pattern, nnames, &available); + if (fonts == NULL || available < nnames) + break; + if (long_list == L_MEDIUM) + XFreeFontInfo(fonts, info, available); + else + XFreeFontNames(fonts); + nnames = available * 2; + } + + if (fonts == NULL) { + fprintf(stderr, "%s: pattern \"%s\" unmatched\n", + program_name, pattern); + return; + } + + font_list = (FontList *)Realloc((char *)font_list, + (font_cnt + available) * sizeof(FontList)); + for (i=0; i<available; i++) { + font_list[font_cnt].name = fonts[i]; + if (long_list == L_MEDIUM) + font_list[font_cnt].info = info + i; + else + font_list[font_cnt].info = NULL; + +#ifdef BUILD_PRINTSUPPORT + if (printer_output) { + char *listfonts_modes; + + listfonts_modes = XpGetOneAttribute(dpy, pcontext, XPDocAttr, "xp-listfonts-modes"); + + /* Save status of xp-listfonts-modes */ + font_list[font_cnt].listfonts_modes = strdup(listfonts_modes?listfonts_modes:""); + + if (listfonts_modes) + XFree(listfonts_modes); + } + else + { + font_list[font_cnt].listfonts_modes = NULL; + } +#endif /* BUILD_PRINTSUPPORT */ + + font_cnt++; + } } -void -show_fonts() +static +int compare(const void *arg1, const void *arg2) { - int i; - - if (font_cnt == 0) - return; - - /* first sort the output */ - if (sort_output) qsort(font_list, font_cnt, sizeof(FontList), compare); - - if (long_list > L_MEDIUM) { - for (i = 0; i < font_cnt; i++) { - do_query_font (dpy, font_list[i].name); - } - return; - } - - if (long_list == L_MEDIUM) { - XFontStruct *pfi; - char *string; - - printf("DIR "); - printf("MIN "); - printf("MAX "); - printf("EXIST "); - printf("DFLT "); - printf("PROP "); - printf("ASC "); - printf("DESC "); - printf("NAME"); - printf("\n"); - for (i=0; i<font_cnt; i++) { - pfi = font_list[i].info; - if (!pfi) { - fprintf (stderr, - "%s: no font information for font \"%s\".\n", - program_name, - font_list[i].name ? - font_list[i].name : ""); - continue; - } - switch(pfi->direction) { - case FontLeftToRight: string = "-->"; break; - case FontRightToLeft: string = "<--"; break; - default: string = "???"; break; - } - printf("%-4s", string); - if (pfi->min_byte1 == 0 - && pfi->max_byte1 == 0) { - printf(" %3d ", pfi->min_char_or_byte2); - printf(" %3d ", pfi->max_char_or_byte2); - } else { - printf("*%3d ", pfi->min_byte1); - printf("*%3d ", pfi->max_byte1); - } - printf("%5s ", pfi->all_chars_exist ? "all" : "some"); - printf("%4d ", pfi->default_char); - printf("%4d ", pfi->n_properties); - printf("%3d ", pfi->ascent); - printf("%4d ", pfi->descent); - printf("%s\n", font_list[i].name); - if (min_max) { - char min[ BUFSIZ ], - max[ BUFSIZ ]; - char *pmax = max, - *pmin = min; - - strcpy(pmin, " min(l,r,w,a,d) = ("); - strcpy(pmax, " max(l,r,w,a,d) = ("); - pmin += strlen(pmin); - pmax += strlen(pmax); - - copy_number(&pmin, &pmax, - pfi->min_bounds.lbearing, - pfi->max_bounds.lbearing); - *pmin++ = *pmax++ = ','; - copy_number(&pmin, &pmax, - pfi->min_bounds.rbearing, - pfi->max_bounds.rbearing); - *pmin++ = *pmax++ = ','; - copy_number(&pmin, &pmax, - pfi->min_bounds.width, - pfi->max_bounds.width); - *pmin++ = *pmax++ = ','; - copy_number(&pmin, &pmax, - pfi->min_bounds.ascent, - pfi->max_bounds.ascent); - *pmin++ = *pmax++ = ','; - copy_number(&pmin, &pmax, - pfi->min_bounds.descent, - pfi->max_bounds.descent); - *pmin++ = *pmax++ = ')'; - *pmin = *pmax = '\0'; - printf("%s\n", min); - printf("%s\n", max); - } - } - return; - } - - if ((columns == 0 && isatty(1)) || columns > 1) { - int width, - max_width = 0, - lines_per_column, - j, - index; - - for (i=0; i<font_cnt; i++) { - width = strlen(font_list[i].name); - if (width > max_width) - max_width = width; - } - if (max_width == 0) - Fatal_Error("all %d fontnames listed are zero length", - font_cnt); - - if (columns == 0) { - if ((max_width * 2) + output_line_padding > - max_output_line_width) { - columns = 1; - } else { - max_width += output_line_padding; - columns = ((max_output_line_width + - output_line_padding) / max_width); - } - } else { - max_width += output_line_padding; - } - if (columns <= 1) goto single_column; - - if (font_cnt < columns) - columns = font_cnt; - lines_per_column = (font_cnt + columns - 1) / columns; - - for (i=0; i<lines_per_column; i++) { - for (j=0; j<columns; j++) { - index = j * lines_per_column + i; - if (index >= font_cnt) - break; - if (j+1 == columns) - printf("%s", font_list[ index ].name); - else - printf("%-*s", - max_width, - font_list[ index ].name); - } - printf("\n"); - } - return; - } - - single_column: - for (i=0; i<font_cnt; i++) - printf("%s\n", font_list[i].name); + const FontList *f1 = arg1; + const FontList *f2 = arg2; + const char *p1 = f1->name; + const char *p2 = f2->name; + + while (*p1 && *p2 && *p1 == *p2) + p1++, p2++; + return(*p1 - *p2); } -#ifndef max -static int -max(i, j) - int i, j; +static +void show_fonts(void) { - if (i > j) - return (i); - return(j); + int i; + + if (font_cnt == 0) + return; + + /* first sort the output */ + if (sort_output) qsort(font_list, font_cnt, sizeof(FontList), compare); + + if (long_list > L_MEDIUM) { + for (i = 0; i < font_cnt; i++) { +#ifdef BUILD_PRINTSUPPORT + if (printer_output) { + /* Restore saved xp-listfonts-modes status */ + XpuSetOneAttribute(dpy, pcontext, XPDocAttr, "*xp-listfonts-modes", font_list[i].listfonts_modes, XPAttrMerge); + } +#endif /* BUILD_PRINTSUPPORT */ + + do_query_font (dpy, font_list[i].name); + } + return; + } + + if (long_list == L_MEDIUM) { + XFontStruct *pfi; + char *string; + + printf("DIR "); + printf("MIN "); + printf("MAX "); + printf("EXIST "); + printf("DFLT "); + printf("PROP "); + printf("ASC "); + printf("DESC "); + printf("NAME"); + printf("\n"); + for (i=0; i<font_cnt; i++) { + pfi = font_list[i].info; + if (!pfi) { + fprintf(stderr, "%s: no font information for font \"%s\".\n", + program_name, + font_list[i].name ? + font_list[i].name : ""); + continue; + } + switch(pfi->direction) { + case FontLeftToRight: string = "-->"; break; + case FontRightToLeft: string = "<--"; break; + default: string = "???"; break; + } + printf("%-4s", string); + if (pfi->min_byte1 == 0 && + pfi->max_byte1 == 0) { + printf(" %3d ", pfi->min_char_or_byte2); + printf(" %3d ", pfi->max_char_or_byte2); + } else { + printf("*%3d ", pfi->min_byte1); + printf("*%3d ", pfi->max_byte1); + } + printf("%5s ", pfi->all_chars_exist ? "all" : "some"); + printf("%4d ", pfi->default_char); + printf("%4d ", pfi->n_properties); + printf("%3d ", pfi->ascent); + printf("%4d ", pfi->descent); + printf("%s\n", font_list[i].name); + if (min_max) { + char min[ BUFSIZ ], + max[ BUFSIZ ]; + char *pmax = max, + *pmin = min; + + strcpy(pmin, " min(l,r,w,a,d) = ("); + strcpy(pmax, " max(l,r,w,a,d) = ("); + pmin += strlen(pmin); + pmax += strlen(pmax); + + copy_number(&pmin, &pmax, + pfi->min_bounds.lbearing, + pfi->max_bounds.lbearing); + *pmin++ = *pmax++ = ','; + copy_number(&pmin, &pmax, + pfi->min_bounds.rbearing, + pfi->max_bounds.rbearing); + *pmin++ = *pmax++ = ','; + copy_number(&pmin, &pmax, + pfi->min_bounds.width, + pfi->max_bounds.width); + *pmin++ = *pmax++ = ','; + copy_number(&pmin, &pmax, + pfi->min_bounds.ascent, + pfi->max_bounds.ascent); + *pmin++ = *pmax++ = ','; + copy_number(&pmin, &pmax, + pfi->min_bounds.descent, + pfi->max_bounds.descent); + *pmin++ = *pmax++ = ')'; + *pmin = *pmax = '\0'; + printf("%s\n", min); + printf("%s\n", max); + } + } + return; + } + + if ((columns == 0 && isatty(1)) || columns > 1) { + int width, + max_width = 0, + lines_per_column, + j, + index; + + for (i=0; i<font_cnt; i++) { + width = strlen(font_list[i].name); + if (width > max_width) + max_width = width; + } + if (max_width == 0) + Fatal_Error("all %d fontnames listed are zero length", font_cnt); + + if (columns == 0) { + if ((max_width * 2) + output_line_padding > + max_output_line_width) { + columns = 1; + } else { + max_width += output_line_padding; + columns = ((max_output_line_width + + output_line_padding) / max_width); + } + } else { + max_width += output_line_padding; + } + if (columns <= 1) goto single_column; + + if (font_cnt < columns) + columns = font_cnt; + lines_per_column = (font_cnt + columns - 1) / columns; + + for (i=0; i<lines_per_column; i++) { + for (j=0; j<columns; j++) { + index = j * lines_per_column + i; + if (index >= font_cnt) + break; + if (j+1 == columns) + printf("%s", font_list[ index ].name); + else + printf("%-*s", + max_width, + font_list[ index ].name); + } + printf("\n"); + } + return; + } + + single_column: + for (i=0; i<font_cnt; i++) + printf("%s\n", font_list[i].name); } -#endif -void -copy_number(pp1, pp2, n1, n2) - char **pp1, **pp2; - int n1, n2; +static +void copy_number(char **pp1, char**pp2, int n1, int n2) { - char *p1 = *pp1; - char *p2 = *pp2; - int w; - - sprintf(p1, "%d", n1); - sprintf(p2, "%d", n2); - w = max(strlen(p1), strlen(p2)); - sprintf(p1, "%*d", w, n1); - sprintf(p2, "%*d", w, n2); - p1 += strlen(p1); - p2 += strlen(p2); - *pp1 = p1; - *pp2 = p2; + char *p1 = *pp1; + char *p2 = *pp2; + int w; + + sprintf(p1, "%d", n1); + sprintf(p2, "%d", n2); + w = MAX(strlen(p1), strlen(p2)); + sprintf(p1, "%*d", w, n1); + sprintf(p2, "%*d", w, n2); + p1 += strlen(p1); + p2 += strlen(p2); + *pp1 = p1; + *pp2 = p2; } /* ARGSUSED */ -static int IgnoreError(disp, event) - Display *disp; - XErrorEvent *event; +static +int IgnoreError(Display *disp, XErrorEvent *event) { return 0; } @@ -446,8 +614,8 @@ static char *bounds_metrics_fmt = #define PrintBounds(_what,_ptr) \ { register XCharStruct *p = (_ptr); \ - printf (bounds_metrics_fmt, _what, p->width, p->lbearing, \ - p->rbearing, p->ascent, p->descent, p->attributes); } + printf (bounds_metrics_fmt, (_what), p->width, p->lbearing, \ + p->rbearing, p->ascent, p->descent, p->attributes); } static char* stringValued [] = { /* values are atoms */ @@ -474,7 +642,14 @@ static char* stringValued [] = { /* values are atoms */ "RASTERIZER_VERSION", /* other registered font properties (see the X.org Registry, sec. 15) */ + +#ifdef BUILD_PRINTSUPPORT + /* Used by Xprint's Postscript and PDF DDX */ "_ADOBE_POSTSCRIPT_FONTNAME", + + /* Used by Xprint's PCL DDXs */ + "PCL_FONT_NAME", +#endif /* BUILD_PRINTSUPPORT */ /* unregistered font properties */ "CHARSET_COLLECTIONS", @@ -488,8 +663,8 @@ static char* stringValued [] = { /* values are atoms */ NULL }; -static void PrintProperty (prop) - XFontProp *prop; +static +void PrintProperty(XFontProp *prop) { char *atom, *value; char nosuch[40]; @@ -498,9 +673,9 @@ static void PrintProperty (prop) atom = XGetAtomName(dpy, prop->name); if (!atom) { - atom = nosuch; - nosuch[0] = '\0'; - (void)sprintf (atom, "No such atom = %ld", prop->name); + atom = nosuch; + nosuch[0] = '\0'; + (void)sprintf (atom, "No such atom = %ld", prop->name); } printf (" %s", atom); @@ -510,20 +685,20 @@ static void PrintProperty (prop) putchar(' '); for (i = 0; ; i++) { - if (stringValued[i] == NULL) { - printf ("%ld\n", prop->card32); - break; - } - if (strcmp(stringValued[i], atom) == 0) { - value = XGetAtomName(dpy, prop->card32); - if (value == NULL) - printf ("%ld (expected string value)\n", prop->card32); - else { - printf ("%s\n", value); - XFree (value); - } - break; - } + if (stringValued[i] == NULL) { + printf ("%ld\n", prop->card32); + break; + } + if (strcmp(stringValued[i], atom) == 0) { + value = XGetAtomName(dpy, prop->card32); + if (value == NULL) + printf ("%ld (expected string value)\n", prop->card32); + else { + printf ("%s\n", value); + XFree (value); + } + break; + } } if (atom != nosuch) XFree (atom); XSetErrorHandler (oldhandler); @@ -531,8 +706,7 @@ static void PrintProperty (prop) static void -ComputeFontType (fs) - XFontStruct *fs; +ComputeFontType(XFontStruct *fs) { int i; Bool char_cell = True; @@ -542,66 +716,65 @@ ComputeFontType (fs) printf (" font type:\t\t"); if (fs->min_bounds.width != fs->max_bounds.width) { - printf ("Proportional (min and max widths not equal)\n"); - return; + printf ("Proportional (min and max widths not equal)\n"); + return; } if (awatom) { - for (i = 0; i < fs->n_properties; i++) { - if (fs->properties[i].name == awatom && - (fs->max_bounds.width * 10) != fs->properties[i].card32) { - char_cell = False; - reason = "font width not equal to AVERAGE_WIDTH"; - break; - } - } + for (i = 0; i < fs->n_properties; i++) { + if (fs->properties[i].name == awatom && + (fs->max_bounds.width * 10) != fs->properties[i].card32) { + char_cell = False; + reason = "font width not equal to AVERAGE_WIDTH"; + break; + } + } } if (fs->per_char) { - for (i = fs->min_char_or_byte2, cs = fs->per_char; - i <= fs->max_char_or_byte2; i++, cs++) { - if (cs->width == 0) continue; - if (cs->width != fs->max_bounds.width) { - /* this shouldn't happen since we checked above */ - printf ("Proportional (characters not all the same width)\n"); - return; - } - if (char_cell) { - if (cs->width < 0) { - if (!(cs->width <= cs->lbearing && - cs->lbearing <= cs->rbearing && - cs->rbearing <= 0)) { - char_cell = False; - reason = "ink outside bounding box"; - } - } else { - if (!(0 <= cs->lbearing && - cs->lbearing <= cs->rbearing && - cs->rbearing <= cs->width)) { - char_cell = False; - reason = "ink outside bounding box"; - } - } - if (!(cs->ascent <= fs->ascent && - cs->descent <= fs->descent)) { - char_cell = False; - reason = "characters not all same ascent or descent"; - } - } - } + for (i = fs->min_char_or_byte2, cs = fs->per_char; + i <= fs->max_char_or_byte2; i++, cs++) { + if (cs->width == 0) continue; + if (cs->width != fs->max_bounds.width) { + /* this shouldn't happen since we checked above */ + printf ("Proportional (characters not all the same width)\n"); + return; + } + if (char_cell) { + if (cs->width < 0) { + if (!(cs->width <= cs->lbearing && + cs->lbearing <= cs->rbearing && + cs->rbearing <= 0)) { + char_cell = False; + reason = "ink outside bounding box"; + } + } else { + if (!(0 <= cs->lbearing && + cs->lbearing <= cs->rbearing && + cs->rbearing <= cs->width)) { + char_cell = False; + reason = "ink outside bounding box"; + } + } + if (!(cs->ascent <= fs->ascent && + cs->descent <= fs->descent)) { + char_cell = False; + reason = "characters not all same ascent or descent"; + } + } + } } printf ("%s", char_cell ? "Character Cell" : "Monospaced"); if (reason) printf (" (%s)", reason); printf ("\n"); - + return; } static void -print_character_metrics (info) - register XFontStruct *info; +print_character_metrics(register XFontStruct *info) { register XCharStruct *pc = info->per_char; register int i, j; @@ -610,49 +783,46 @@ print_character_metrics (info) printf (" character metrics:\n"); saven = ((info->min_byte1 << 8) | info->min_char_or_byte2); for (j = info->min_byte1; j <= info->max_byte1; j++) { - n = saven; - for (i = info->min_char_or_byte2; i <= info->max_char_or_byte2; i++) { - char *s = XKeysymToString ((KeySym) n); - printf (char_metrics_fmt, j, i, n, pc->width, pc->lbearing, - pc->rbearing, pc->ascent, pc->descent, pc->attributes, - s ? s : "."); - pc++; - n++; - } - saven += 256; + n = saven; + for (i = info->min_char_or_byte2; i <= info->max_char_or_byte2; i++) { + char *s = XKeysymToString ((KeySym) n); + printf (char_metrics_fmt, j, i, n, pc->width, pc->lbearing, + pc->rbearing, pc->ascent, pc->descent, pc->attributes, + s ? s : "."); + pc++; + n++; + } + saven += 256; } } - -void -do_query_font (dpy, name) - Display *dpy; - char *name; +static +void do_query_font (Display *dpy, char *name) { register int i; register XFontStruct *info = XLoadQueryFont (dpy, name); if (!info) { - fprintf (stderr, "%s: unable to get info about font \"%s\"\n", - program_name, name); - return; + fprintf (stderr, "%s: unable to get info about font \"%s\"\n", + program_name, name); + return; } printf ("name: %s\n", name ? name : "(nil)"); printf (" direction:\t\t%s\n", ((info->direction == FontLeftToRight) - ? "left to right" : "right to left")); + ? "left to right" : "right to left")); printf (" indexing:\t\t%s\n", - ((info->min_byte1 == 0 && info->max_byte1 == 0) ? "linear" : - "matrix")); + ((info->min_byte1 == 0 && info->max_byte1 == 0) ? "linear" : + "matrix")); printf (" rows:\t\t\t0x%02x thru 0x%02x (%d thru %d)\n", - info->min_byte1, info->max_byte1, - info->min_byte1, info->max_byte1); + info->min_byte1, info->max_byte1, + info->min_byte1, info->max_byte1); printf (" columns:\t\t0x%02x thru 0x%02x (%d thru %d)\n", - info->min_char_or_byte2, info->max_char_or_byte2, - info->min_char_or_byte2, info->max_char_or_byte2); + info->min_char_or_byte2, info->max_char_or_byte2, + info->min_char_or_byte2, info->max_char_or_byte2); printf (" all chars exist:\t%s\n", - (info->all_chars_exist) ? "yes" : "no"); + (info->all_chars_exist) ? "yes" : "no"); printf (" default char:\t\t0x%04x (%d)\n", - info->default_char, info->default_char); + info->default_char, info->default_char); printf (" ascent:\t\t%d\n", info->ascent); printf (" descent:\t\t%d\n", info->descent); ComputeFontType (info); @@ -660,11 +830,13 @@ do_query_font (dpy, name) PrintBounds ("min", &info->min_bounds); PrintBounds ("max", &info->max_bounds); if (info->per_char && long_list >= L_VERYLONG) - print_character_metrics (info); + print_character_metrics (info); printf (" properties:\t\t%d\n", info->n_properties); for (i = 0; i < info->n_properties; i++) - PrintProperty (&info->properties[i]); + PrintProperty (&info->properties[i]); printf ("\n"); XFreeFontInfo (NULL, info, 1); } + + |