Annotation of researchv9/X11/src/X.V11R1/clients/xfd/xfd.c, revision 1.1.1.1

1.1       root        1: /* Copyright 1987, Massachusetts Institute of Technology */
                      2: 
                      3: /*
                      4:  * xfd: program to display a font for perusal by the user.
                      5:  *
                      6:  * Written by Mark Lillibridge
                      7:  *
                      8:  */
                      9: 
                     10: #include <X11/Xlib.h>
                     11: #include <X11/Xutil.h>
                     12: #include <X11/Xatom.h>
                     13: #include <stdio.h>
                     14: 
                     15: #define BUFFERSIZE 10
                     16: #define VERBOSE_LINES 4         /* Number of lines in verbose display */
                     17: 
                     18: 
                     19:     /* Global variables */
                     20: 
                     21: int space_per_line;             /* How much space to reserve per line */
                     22: int line_offset;                /* Where to start writting (base line) */
                     23: int number_of_lines=1;          /* number of lines in bottom area display */
                     24: int verbose = 0;                /* verbose mode? */
                     25: int box_x = 0;                  /* The size of one box in grid */
                     26: int box_y = 0;
                     27: int x_offset = 0;               /* Point in box to display character from */
                     28: int y_offset = 0;
                     29: int x_boxes = 0;                /* Current size of window in # of boxes */
                     30: int y_boxes = 0;
                     31: int bottom = 0;                 /* Size of grid in pixels */
                     32: int right = 0;
                     33: int first_char = 0;             /* Character # of first character displayed on
                     34:                                   the grid */
                     35: GC body_gc, real_gc;            /* Graphics contexts */
                     36: XFontStruct *real_font;         /* The font we are to display */
                     37: 
                     38: /* Gray pattern for use as background */
                     39: #include "X11/bitmaps/light_gray"
                     40: 
                     41: /* Include routines to handle parsing defaults */
                     42: #define TITLE_DEFAULT "xfd"     /* Our name... */
                     43: #define DEFX_DEFAULT 300        /* Default window pop-up location */
                     44: #define DEFY_DEFAULT 300
                     45: #define RESIZE_X_INC 1          /* We will specify a resize inc later ... */
                     46: #define RESIZE_Y_INC 1
                     47: #define MIN_X_SIZE 1            /* Ditto for minimum window size */
                     48: #define MIN_Y_SIZE 1
                     49: 
                     50: #include "wsimple.h"
                     51: 
                     52: /*
                     53:  * usage: routine to show usage then exit.
                     54:  */
                     55: usage()
                     56: {
                     57:        fprintf(stderr, "%s: usage: %s %s [-v[erbose]] [-gray] [-start <char number>] fontname\n", program_name,
                     58:                program_name, X_USAGE);
                     59:        exit(1);
                     60: }
                     61: 
                     62: 
                     63: /*
                     64:  * The main program:
                     65:  */
                     66: main(argc, argv) 
                     67: 
                     68:      int argc;
                     69:      char **argv;
                     70: {
                     71:        register int i;
                     72:        GC gc;
                     73:        XGCValues gc_init;
                     74:        XEvent event;
                     75:        char *fontname = BODY_FONT_DEFAULT;     /* Display default body font */
                     76:        int gray = 0;                           /* use gray background ? */
                     77:        char buffer[BUFFERSIZE];                /* buffer for XLookupString */
                     78: 
                     79:        INIT_NAME;
                     80: 
                     81:        /* Handle command line arguments, open the display */
                     82:        Get_X_Options(&argc, argv);
                     83:        for (i = 1; i < argc; i++) {
                     84:                if (!strcmp("-", argv[i]))
                     85:                  continue;
                     86:                if (!strcmp("-gray", argv[i])) {
                     87:                  gray = 1;
                     88:                  continue;
                     89:                }                 
                     90:                if (!strcmp("-start", argv[i])) {
                     91:                        if (++i >= argc) usage();
                     92:                        first_char = atoi(argv[i]);
                     93:                        continue;
                     94:                }
                     95:                if (!strcmp("-verbose", argv[i]) || !strcmp("-v", argv[i])) {
                     96:                        verbose = 1;
                     97:                        number_of_lines = VERBOSE_LINES;
                     98:                        continue;
                     99:                }
                    100:                if (argv[i][0] == '-')
                    101:                  usage();
                    102:                fontname = argv[i];
                    103:        } 
                    104: 
                    105:        /* Load in the font to display */
                    106:        real_font = Open_Font(fontname);
                    107: 
                    108:        /* Resolve the X options */
                    109:        Resolve_X_Options();
                    110: 
                    111:        line_offset = 2 + body_font->ascent;
                    112:        space_per_line = body_font->descent + line_offset + 2;
                    113: 
                    114:        /* Get minimun perfered size */
                    115:        Calc_Default_Size();
                    116: 
                    117:        /* Create the window */
                    118:        Create_Default_Window();
                    119:        if (gray)
                    120:          SetBackgroundToBitmap(XCreateBitmapFromData(dpy,
                    121:                                                      wind,
                    122:                                                      light_gray_bits,
                    123:                                                      light_gray_width,
                    124:                                                      light_gray_height),
                    125:                                light_gray_width, light_gray_height);
                    126: 
                    127:        /* Setup graphics contexts */
                    128:        body_gc = Get_Default_GC();   /* This one has body font */
                    129:        real_gc = Get_Default_GC();   /* This one has font to display */
                    130: 
                    131:        gc_init.font = real_font->fid;
                    132:        XChangeGC(dpy, real_gc, GCFont, &gc_init);
                    133: 
                    134:        /* Start main loop by selecting events then mapping window */
                    135:        XSelectInput(dpy, wind, ButtonPressMask|ExposureMask|KeyPressMask);
                    136:        XMapWindow(dpy, wind);
                    137: 
                    138:        /* Main event loop */
                    139:        for (;;) {
                    140:                XNextEvent(dpy, &event);
                    141:                if (event.type == ButtonPress) {
                    142:                        if (event.xbutton.button == 1)
                    143:                          Go_Back();
                    144:                        else if (event.xbutton.button == 2)
                    145:                          Identify_character(event.xbutton.x, event.xbutton.y);
                    146:                        else if (event.xbutton.button == 3)
                    147:                          Go_Forward();
                    148:                } else if (event.type == KeyPress) {
                    149:                        i = XLookupString(&event, buffer, BUFFERSIZE,
                    150:                                          NULL, NULL);
                    151:                        if (i==1 && (buffer[0]=='q' || buffer[0]=='Q' ||
                    152:                                     buffer[0]==' ' || buffer[0]=='\03'))
                    153:                          exit(0);
                    154:                        if (i==1 && buffer[0]=='<') {
                    155:                                minimum_bounds();
                    156:                                continue;
                    157:                        }
                    158:                        if (i==1 && buffer[0]=='>') {
                    159:                                maximum_bounds();
                    160:                                continue;
                    161:                        }
                    162:                        if (i && buffer[0])
                    163:                          Beep();
                    164:                }
                    165:                else if (event.type== GraphicsExpose || event.type == Expose) {
                    166:                 /* Only redisplay if this is the last exposure in a series */
                    167:                        if (!event.xexpose.count)
                    168:                          Display_Contents();
                    169:                 }
                    170:        }
                    171: }
                    172: 
                    173: /*
                    174:  * Calc_Default_Size: This routine calculates the size of a box in the grid
                    175:  * and where to write a character from so that every character will fit
                    176:  * in a box.  The size of an ideal window (16 boxes by 16 boxes with room
                    177:  * for the bottom text) is then calculated.
                    178:  */
                    179: Calc_Default_Size()
                    180: {
                    181:        XCharStruct min_bounds;
                    182:        XCharStruct max_bounds;
                    183: 
                    184:        min_bounds = real_font->min_bounds;
                    185:        max_bounds = real_font->max_bounds;
                    186: 
                    187:        /*
                    188:         * Calculate size of box which will hold 1 character as well
                    189:         * as were to draw it from in the box.
                    190:         */
                    191:        x_offset = y_offset = 0;
                    192:        if (min_bounds.lbearing<0)
                    193:          x_offset = -min_bounds.lbearing;
                    194:        if (max_bounds.ascent>0)
                    195:          y_offset = max_bounds.ascent;
                    196:        if (real_font->ascent > y_offset)
                    197:          y_offset = real_font->ascent;
                    198: 
                    199:        box_x = x_offset;
                    200:        box_y = y_offset;
                    201: 
                    202:        if (max_bounds.rbearing + x_offset > box_x)
                    203:          box_x = max_bounds.rbearing + x_offset;
                    204:        if (x_offset + max_bounds.width > box_x)
                    205:          box_x = x_offset + max_bounds.width;
                    206: 
                    207:        if (max_bounds.descent + y_offset > box_y)
                    208:          box_y = max_bounds.descent + y_offset;
                    209:        if (real_font->descent + y_offset > box_y)
                    210:          box_y = real_font->descent + y_offset;
                    211: 
                    212:        /* Leave room for grid lines & a little space */
                    213:        x_offset += 2; y_offset += 2;
                    214:        box_x += 3;  box_y += 3;
                    215: 
                    216:        if (!geometry) {        /* if user didn't override, use ideal size */
                    217:                size_hints.width = box_x*16+1;
                    218:                size_hints.height = box_y*16 + space_per_line *number_of_lines;
                    219:        }
                    220: 
                    221:        size_hints.width_inc = box_x;
                    222:        size_hints.height_inc = box_y;
                    223: 
                    224:        size_hints.min_width = box_x+1;
                    225:        size_hints.min_height = box_y + space_per_line*number_of_lines;
                    226: }
                    227: 
                    228: char s[4] = { 0, 0, 0, 0 };
                    229: 
                    230: /*
                    231:  * Display_Contents: Routine to (re)display the contents of the window.
                    232:  */
                    233: Display_Contents()
                    234: {
                    235:        int i, x, y;
                    236:        XWindowAttributes wind_info;
                    237: 
                    238:        /* Get the size of the window */
                    239:        if (!XGetWindowAttributes(dpy, wind, &wind_info))
                    240:          Fatal_Error("Can't get window atrributes!");
                    241:        size_hints.width = wind_info.width;
                    242:        size_hints.height = wind_info.height;
                    243: 
                    244:        /* Erase previous contents if any */
                    245:        XClearWindow(dpy, wind);
                    246: 
                    247:        /* Calculate the size of the grid */
                    248:        x_boxes = (size_hints.width-1) / box_x;
                    249:        y_boxes = (size_hints.height - space_per_line * number_of_lines)
                    250:          / box_y;
                    251:        right = x_boxes * box_x;
                    252:        bottom = y_boxes * box_y;
                    253: 
                    254:        /* Draw the grid */
                    255:        for (i = 0; i<=x_boxes; i++)
                    256:          XDrawLine(dpy, wind, body_gc, i*box_x, 0, i*box_x, bottom);
                    257:        for (i = 0; i<=y_boxes; i++)
                    258:          XDrawLine(dpy, wind, body_gc, 0, i*box_y, right, i*box_y);
                    259: 
                    260:        /* Draw one character in every box */
                    261:        for (y=0; y<y_boxes; y++) {
                    262:                for (x=0; x<x_boxes; x++) {
                    263:                        s[0] = (first_char + x + y*x_boxes) / 256;
                    264:                        s[1] = (first_char + x + y*x_boxes) % 256;
                    265:                        XDrawImageString16(dpy, wind, real_gc, x*box_x+x_offset,
                    266:                                     y*box_y+y_offset, (XChar2b *) s, 1);
                    267:                }
                    268:        }
                    269: }
                    270: 
                    271: char short_format[] = " %d. 0x%x";
                    272: char line1_alt[] = " %s bounds:";
                    273: char line1_format[] = " character # = %d. (0x%x):";
                    274: char line2_format[] = " left bearing = %d, right bearing = %d";
                    275: char line3_format[] = " ascent = %d, descent = %d";
                    276: char line4_format[] = " width = %d";
                    277: char buf[80*2];
                    278: 
                    279: /*
                    280:  * Identify_character: Routine to print the number of the character that was
                    281:  * clicked on by the mouse on the bottom line or beep if no character was
                    282:  * clicked on.
                    283:  */
                    284: Identify_character(x, y)
                    285: int x,y;
                    286: {
                    287:        int xbox, ybox;
                    288:        int char_number;
                    289:        XCharStruct char_info;
                    290:        int index, byte1, byte2;
                    291:        char *msg;
                    292: 
                    293:        /* If not in grid, beep */
                    294:        if (x>=right | y>=bottom) {
                    295:                Beep();
                    296:                return;
                    297:        }
                    298: 
                    299:        /* Find out which box clicked in */
                    300:        xbox = x / box_x;
                    301:        ybox = y / box_y;
                    302: 
                    303:        /* Convert that to the character number */
                    304:        char_number = first_char + xbox + ybox * x_boxes;
                    305: 
                    306:        char_info = real_font->max_bounds;
                    307:        index = char_number;
                    308:        if (real_font->per_char) {
                    309:                if (!real_font->min_byte1 && !real_font->max_byte1) {
                    310:                        if (char_number < real_font->min_char_or_byte2 ||
                    311:                            char_number > real_font->max_char_or_byte2)
                    312:                          index = real_font->default_char;
                    313:                        index -= real_font->min_char_or_byte2;
                    314:                } else {
                    315:                        byte2 = index & 0xff;
                    316:                        byte1 = (index>>8) & 0xff;
                    317:                        if (byte1 < real_font->min_byte1 ||
                    318:                            byte1 > real_font->max_byte1 ||
                    319:                            byte2 < real_font->min_char_or_byte2 ||
                    320:                            byte2 > real_font->max_char_or_byte2) {
                    321:                                    byte2 = real_font->default_char & 0xff;
                    322:                                    byte1 = (real_font->default_char>>8)&0xff;
                    323:                            }
                    324:                        byte1 -= real_font->min_byte1;
                    325:                        byte2 -= real_font->min_char_or_byte2;
                    326:                        index = byte1 * (real_font->max_char_or_byte2 -
                    327:                                         real_font->min_char_or_byte2 + 1) +
                    328:                                           byte2;
                    329:                }
                    330:                char_info = real_font->per_char[index];
                    331:        }
                    332: 
                    333:        if (!verbose) {
                    334:                sprintf(buf, short_format, char_number, char_number);
                    335:                put_line(buf, 0);
                    336:        } else {
                    337:                sprintf(buf, line1_format, char_number, char_number);
                    338:                put_line(buf, 0);
                    339: 
                    340:                display_char_info(char_info);
                    341:        }
                    342: }
                    343: 
                    344: /*
                    345:  * maximum_bounds: display info for maximum bounds
                    346:  */
                    347: maximum_bounds()
                    348: {
                    349:        sprintf(buf, line1_alt, "maximum");
                    350:        put_line(buf, 0);
                    351: 
                    352:        display_char_info(real_font->max_bounds);
                    353: }
                    354: 
                    355: 
                    356: /*
                    357:  * minimum_bounds: display info for minimum bounds
                    358:  */
                    359: minimum_bounds()
                    360: {
                    361:        sprintf(buf, line1_alt, "minimum");
                    362:        put_line(buf, 0);
                    363: 
                    364:        display_char_info(real_font->min_bounds);
                    365: }
                    366: 
                    367: /*
                    368:  * display_char_info: routine to display char info on bottom 3 lines
                    369:  */
                    370: display_char_info(char_info)
                    371: XCharStruct char_info;
                    372: {
                    373:        sprintf(buf, line2_format, char_info.lbearing,
                    374:                char_info.rbearing);
                    375:        put_line(buf, 1);
                    376:        
                    377:        sprintf(buf, line3_format, char_info.ascent,
                    378:                char_info.descent);
                    379:        put_line(buf, 2);
                    380: 
                    381:        sprintf(buf, line4_format, char_info.width);
                    382:        put_line(buf, 3);
                    383: }
                    384: 
                    385: /*
                    386:  * Put_line: print a line in bottom area at a given line #
                    387:  */
                    388: put_line(line, n)
                    389:      char *line;
                    390:      int n;
                    391: {
                    392:        strcat(line,"                                                                              ");
                    393:        XDrawImageString(dpy, wind, body_gc, 5, bottom + line_offset +
                    394:                         space_per_line*n, line, 80);
                    395: }
                    396: 
                    397: 
                    398: /*
                    399:  * Go_Back: Routine to page back a gridful of characters.
                    400:  */
                    401: Go_Back()
                    402: {
                    403:        /* If try and page back past first 0th character, beep */
                    404:        if (first_char == 0) {
                    405:                Beep();
                    406:                return;
                    407:        }
                    408: 
                    409:        first_char -= x_boxes*y_boxes;
                    410:        if (first_char<0)
                    411:          first_char = 0;
                    412: 
                    413:        Display_Contents();
                    414: }
                    415: 
                    416: /*
                    417:  * Go_Forward: Routine to page forward a gridful of characters.
                    418:  */
                    419: Go_Forward()
                    420: {
                    421:        first_char += x_boxes*y_boxes;
                    422: 
                    423:        Display_Contents();
                    424: }
                    425: 
                    426: 
                    427: /*
                    428:  * SetBackgroundToBitmap: Set the window's background to a caller supplied 
                    429:  *                        bitmap.
                    430:  */
                    431: SetBackgroundToBitmap(bitmap, width, height)
                    432:      Pixmap bitmap;
                    433:      int width, height;
                    434: {
                    435:        Pixmap pix;
                    436:        GC gc;
                    437:        XGCValues gc_init;
                    438: 
                    439:        gc_init.foreground = foreground;
                    440:        gc_init.background = background;
                    441:        gc = XCreateGC(dpy, RootWindow(dpy, screen),GCForeground|GCBackground,
                    442:                       &gc_init);
                    443: 
                    444:        pix = Bitmap_To_Pixmap(dpy, wind, gc, bitmap, width, height);
                    445: 
                    446:        XSetWindowBackgroundPixmap(dpy, wind, pix);
                    447: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.