showfont.c revision 0ed7c580
1/* 2 * Copyright 1990 Network Computing Devices; 3 * Portions Copyright 1987 by Digital Equipment Corporation 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and 6 * its documentation for any purpose is hereby granted without fee, provided 7 * that the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the names of Network Computing Devices or Digital 10 * not be used in advertising or publicity pertaining to distribution 11 * of the software without specific, written prior permission. 12 * 13 * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH 14 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETWORK COMPUTING DEVICES 16 * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 17 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 18 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 19 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 20 * THIS SOFTWARE. 21 */ 22/* 23 24Copyright (c) 1987 X Consortium 25 26Permission is hereby granted, free of charge, to any person obtaining 27a copy of this software and associated documentation files (the 28"Software"), to deal in the Software without restriction, including 29without limitation the rights to use, copy, modify, merge, publish, 30distribute, sublicense, and/or sell copies of the Software, and to 31permit persons to whom the Software is furnished to do so, subject to 32the following conditions: 33 34The above copyright notice and this permission notice shall be included 35in all copies or substantial portions of the Software. 36 37THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 38OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 39MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 40IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR 41OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 42ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 43OTHER DEALINGS IN THE SOFTWARE. 44 45Except as contained in this notice, the name of the X Consortium shall 46not be used in advertising or otherwise to promote the sale, use or 47other dealings in this Software without prior written authorization 48from the X Consortium. 49 50*/ 51 52#ifdef HAVE_CONFIG_H 53# include "config.h" 54#endif 55 56#include <stdio.h> 57#include <stdlib.h> 58#include <string.h> 59#include <ctype.h> 60#include <X11/fonts/FSlib.h> 61 62/* 63 * the equivalent of showsnf 64 */ 65 66#define GLWIDTHBYTESPADDED(bits,nbytes) \ 67 ((nbytes) == 1 ? (((bits)+7)>>3) /* pad to 1 byte */ \ 68 :(nbytes) == 2 ? ((((bits)+15)>>3)&~1) /* pad to 2 bytes */ \ 69 :(nbytes) == 4 ? ((((bits)+31)>>3)&~3) /* pad to 4 bytes */ \ 70 :(nbytes) == 8 ? ((((bits)+63)>>3)&~7) /* pad to 8 bytes */ \ 71 : 0) 72 73static int byteorder = MSBFirst; /* -LSB or -MSB */ 74static int bitorder = MSBFirst; /* -lsb or -msb */ 75static int bitmap_pad = 0; /* -bitmap_pad: ImageRect bitmap format */ 76static int scan_pad = 8; /* -pad: ScanlinePad */ 77static int scan_unit = 8; /* -unit: ScanlineUnit */ 78static int first_ch = 0; /* -start: first character*/ 79static int end_ch = ~0; /* -end: end character */ 80static const char *ProgramName; 81static Bool no_props = False; /* -noprops: don't show font properties */ 82static Bool extents_only = False; /* -extents_only */ 83 84static FSServer *svr; 85 86/* set from bitmap_pad to ImageRectMin, ImageMaxWidth, or ImageMax */ 87static int bitmap_format; 88 89static FSBitmapFormat 90make_format(void) 91{ 92 FSBitmapFormat format; 93 94 format = 0; 95 /* set up format */ 96 switch (scan_pad) { 97 case 8: 98 format |= BitmapFormatScanlinePad8; 99 break; 100 case 16: 101 format |= BitmapFormatScanlinePad16; 102 break; 103 case 32: 104 format |= BitmapFormatScanlinePad32; 105 break; 106 case 64: 107 format |= BitmapFormatScanlinePad64; 108 break; 109 default: 110 fprintf(stderr, "bogus scanline pad value: %d\n", scan_pad); 111 break; 112 } 113 switch (scan_unit) { 114 case 8: 115 format |= BitmapFormatScanlineUnit8; 116 break; 117 case 16: 118 format |= BitmapFormatScanlineUnit16; 119 break; 120 case 32: 121 format |= BitmapFormatScanlineUnit32; 122 break; 123 case 64: 124 format |= BitmapFormatScanlineUnit64; 125 break; 126 default: 127 fprintf(stderr, "bogus scanline unit value: %d\n", scan_unit); 128 break; 129 } 130 switch (bitmap_pad) { 131 case 0: 132 bitmap_format = BitmapFormatImageRectMin; 133 break; 134 case 1: 135 bitmap_format = BitmapFormatImageRectMaxWidth; 136 break; 137 case 2: 138 bitmap_format = BitmapFormatImageRectMax; 139 break; 140 default: 141 fprintf(stderr, "bogus bitmap pad value: %d\n", bitmap_pad); 142 break; 143 } 144 format |= bitmap_format; 145 146 format |= (bitorder == MSBFirst) ? BitmapFormatBitOrderMSB : 147 BitmapFormatBitOrderLSB; 148 format |= (byteorder == MSBFirst) ? BitmapFormatByteOrderMSB : 149 BitmapFormatByteOrderLSB; 150 151 return format; 152} 153 154static void 155show_char_info(FSXCharInfo *ci) 156{ 157 printf("Left: %-3d Right: %-3d Ascent: %-3d Descent: %-3d Width: %d\n", 158 ci->left, ci->right, ci->ascent, ci->descent, ci->width); 159} 160 161static void 162show_glyphs( 163 Font fid, 164 FSXFontInfoHeader *hdr, 165 Bool show_all, 166 FSChar2b first, 167 FSChar2b last) 168{ 169 FSXCharInfo *extents; 170 int err, 171 ch, 172 start; 173 int offset = 0; 174 unsigned char *glyphs; 175 FSOffset *offsets; 176 int scanpad; 177 int r, 178 b; 179 FSBitmapFormat format; 180 FSChar2b chars[2]; 181 int num_chars; 182 int row, 183 col, 184 temp_ch; 185 186 if (show_all) { 187 num_chars = 0; 188 } else { 189 chars[0] = first; 190 chars[1] = last; 191 num_chars = 2; 192 } 193 FSQueryXExtents16(svr, fid, True, chars, num_chars, &extents); 194 195 if (!extents_only) { 196 format = make_format(); 197 err = FSQueryXBitmaps16(svr, fid, format, True, chars, num_chars, 198 &offsets, &glyphs); 199 200 if (err != FSSuccess) { 201 fprintf(stderr, "QueryGlyphs failed\n"); 202 exit(1); 203 } 204 } 205 206 scanpad = scan_pad >> 3; 207 208 for (row = (int)first.high; row <= (int)last.high; row++) { 209 start = first.low + (row << 8); 210 for (col = (int)first.low; col <= (int)last.low; col++) { 211 int bottom, 212 bpr, 213 charwidth; 214 215 ch = ((row - (int)first.high) 216 * ((int)last.low - (int)first.low + 1)) 217 + (col - (int)first.low); 218 temp_ch = start + (col - (int)first.low); 219 printf("char #%d", temp_ch); 220 if ((temp_ch >= 0) && (temp_ch <= 127) && isprint(temp_ch)) 221 printf(" '%c'\n", (char) (temp_ch)); 222 else 223 printf(" 0x%04x\n", temp_ch); 224 show_char_info(&extents[ch]); 225 if (extents_only) 226 continue; 227 if (offset != offsets[ch].position) 228 fprintf(stderr, "offset mismatch: expected %d, got %d\n", 229 offset, offsets[ch].position); 230 switch (bitmap_format) { 231 case BitmapFormatImageRectMin: 232 bottom = extents[ch].descent + extents[ch].ascent; 233 charwidth = extents[ch].right - extents[ch].left; 234 break; 235 case BitmapFormatImageRectMaxWidth: 236 bottom = extents[ch].descent + extents[ch].ascent; 237 charwidth = hdr->max_bounds.right - hdr->min_bounds.left; 238 break; 239 case BitmapFormatImageRectMax: 240 bottom = hdr->max_bounds.ascent + 241 hdr->max_bounds.descent; 242 charwidth = hdr->max_bounds.right - hdr->min_bounds.left; 243 break; 244 default: 245 bottom = 0; 246 charwidth = 0; 247 } 248 249 if (extents[ch].left == 0 && 250 extents[ch].right == 0 && 251 extents[ch].width == 0 && 252 extents[ch].ascent == 0 && 253 extents[ch].descent == 0) { 254 printf ("Nonexistent character\n"); 255 continue; 256 } 257 bpr = GLWIDTHBYTESPADDED(charwidth, scanpad); 258 if (offsets[ch].length != bottom * bpr) { 259 fprintf (stderr, 260 "length mismatch: expected %d (%dx%d), got %d\n", 261 bottom * bpr, bpr, bottom, offsets[ch].length); 262 } 263 offset = offsets[ch].position; 264 for (r = 0; r < bottom; r++) { 265 unsigned char *rowp = glyphs + offset; 266 267 for (b = 0; b < charwidth; b++) { 268 putchar((rowp[b >> 3] & 269 (1 << (7 - (b & 7)))) ? '#' : '-'); 270 } 271 putchar('\n'); 272 offset += bpr; 273 } 274 } 275 } 276 FSFree((char *) extents); 277 if (!extents_only) { 278 FSFree((char *) offsets); 279 FSFree((char *) glyphs); 280 } 281} 282 283static void 284show_props( 285 FSPropInfo *pi, 286 FSPropOffset *po, 287 unsigned char *pd) 288{ 289 int i; 290 char buf[512]; 291 int num_props; 292 293 num_props = pi->num_offsets; 294 for (i = 0; i < num_props; i++, po++) { 295 strncpy(buf, (char *) (pd + po->name.position), po->name.length); 296 buf[po->name.length] = '\0'; 297 printf("%s\t", buf); 298 switch (po->type) { 299 case PropTypeString: 300 strncpy(buf, (char *)(pd + po->value.position), po->value.length); 301 buf[po->value.length] = '\0'; 302 printf("%s\n", buf); 303 break; 304 case PropTypeUnsigned: 305 printf("%lu\n", (unsigned long) po->value.position); 306 break; 307 case PropTypeSigned: 308 printf("%ld\n", (long) po->value.position); 309 break; 310 default: 311 fprintf(stderr, "bogus property\n"); 312 break; 313 } 314 } 315} 316 317static void 318show_info( 319 Font fid, 320 FSXFontInfoHeader *hdr, 321 FSChar2b *first, 322 FSChar2b *last) 323{ 324 FSPropInfo pi; 325 FSPropOffset *po; 326 unsigned char *pd; 327 328 FSQueryXInfo(svr, fid, hdr, &pi, &po, &pd); 329 printf("Direction: %s\n", (hdr->draw_direction == LeftToRightDrawDirection) 330 ? "Left to Right" : "Right to Left"); 331 *first = hdr->char_range.min_char; 332 *last = hdr->char_range.max_char; 333 printf("Range: %d to %d\n", 334 first->low + (first->high << 8), 335 last->low + (last->high << 8)); 336 if (hdr->flags & FontInfoAllCharsExist) 337 printf("All chars exist\n"); 338 printf("Default char: %d\n", 339 hdr->default_char.low + (hdr->default_char.high << 8)); 340 printf("Min bounds: \n"); 341 show_char_info(&hdr->min_bounds); 342 printf("Max bounds: \n"); 343 show_char_info(&hdr->max_bounds); 344 printf("Font Ascent: %d Font Descent: %d\n", 345 hdr->font_ascent, hdr->font_descent); 346 347 if (!no_props) 348 show_props(&pi, po, pd); 349 FSFree((char *) po); 350 FSFree((char *) pd); 351} 352 353static void 354usage(const char *msg) 355{ 356 if (msg) 357 fprintf(stderr, "%s: %s\n", ProgramName, msg); 358 fprintf(stderr, 359 "Usage: %s [-server servername] [-extents_only] [-noprops]\n" 360 " [-lsb] [-msb] [-LSB] [-MSB] [-unit #] [-pad #] [-bitmap_pad value]\n" 361 " [-start first_char] [-end last_char] -fn fontname\n" 362 " or: %s -version\n", 363 ProgramName, ProgramName); 364 exit(1); 365} 366 367int 368main(int argc, char **argv) 369{ 370 const char *servername = "localhost:7100"; /* -server: font server name */ 371 char *fontname = NULL; /* -fn: font name */ 372 int i; 373 Font fid, 374 dummy; 375 FSBitmapFormat format; 376 FSBitmapFormatMask fmask; 377 FSChar2b first, 378 last; 379 FSXFontInfoHeader hdr; 380 Bool show_all = True; 381 382 ProgramName = argv[0]; 383 384 for (i = 1; i < argc; i++) { 385 if (!strncmp(argv[i], "-se", 3)) { 386 if (++i < argc) 387 servername = argv[i]; 388 else 389 usage("-server requires an argument"); 390 } else if (!strncmp(argv[i], "-ext", 4)) { 391 extents_only = True; 392 } else if (!strncmp(argv[i], "-noprops", 7)) { 393 no_props = True; 394 } else if (!strncmp(argv[i], "-lsb", 4)) { 395 bitorder = LSBFirst; 396 } else if (!strncmp(argv[i], "-msb", 4)) { 397 bitorder = MSBFirst; 398 } else if (!strncmp(argv[i], "-LSB", 4)) { 399 byteorder = LSBFirst; 400 } else if (!strncmp(argv[i], "-MSB", 4)) { 401 byteorder = MSBFirst; 402 } else if (!strncmp(argv[i], "-p", 2)) { 403 if (++i < argc) 404 scan_pad = atoi(argv[i]); 405 else 406 usage("-pad requires an argument"); 407 } else if (!strncmp(argv[i], "-u", 2)) { 408 if (++i < argc) 409 scan_unit = atoi(argv[i]); 410 else 411 usage("-unit requires an argument"); 412 } else if (!strncmp(argv[i], "-b", 2)) { 413 if (++i < argc) 414 bitmap_pad = atoi(argv[i]); 415 else 416 usage("-bitmap_pad requires an argument"); 417 } else if (!strncmp(argv[i], "-st", 3)) { 418 if (++i < argc) 419 first_ch = atoi(argv[i]); 420 else 421 usage("-start requires an argument"); 422 } else if (!strncmp(argv[i], "-e", 2)) { 423 if (++i < argc) 424 end_ch = atoi(argv[i]); 425 else 426 usage("-end requires an argument"); 427 } else if (!strncmp(argv[i], "-f", 2)) { 428 if (++i < argc) 429 fontname = argv[i]; 430 else 431 usage("-fn requires an argument"); 432 } else if (!strcmp(argv[i], "-version")) { 433 puts(PACKAGE_STRING); 434 exit(0); 435 } else { 436 char msg[128]; 437 snprintf(msg, sizeof(msg), "unrecognized argument: %s", argv[i]); 438 usage(msg); 439 } 440 } 441 if (fontname == NULL) 442 usage("no fontname specified"); 443 444 if (first_ch != 0 && end_ch != ~0 && end_ch < first_ch) { 445 fprintf(stderr, 446 "bad character range -- end (%d) is less than start (%d)\n", 447 end_ch, first_ch); 448 exit(1); 449 } 450 if ((svr = FSOpenServer(servername)) == NULL) { 451 if(FSServerName(servername) != NULL) 452 fprintf(stderr, "can't open server \"%s\"\n", FSServerName(servername)); 453 else 454 fprintf(stderr, "can't open server \"\"\n"); 455 exit(1); 456 } 457 format = make_format(); 458 fmask = (BitmapFormatMaskByte | BitmapFormatMaskBit | 459 BitmapFormatMaskImageRectangle | BitmapFormatMaskScanLinePad | 460 BitmapFormatMaskScanLineUnit); 461 fid = FSOpenBitmapFont(svr, format, fmask, fontname, &dummy); 462 if (fid) { 463 printf("opened font %s\n", fontname); 464 show_info(fid, &hdr, &first, &last); 465 if (first_ch != 0 && 466 ((unsigned)first_ch >= (first.low + (first.high << 8)))) { 467 first.low = first_ch & 0xff; 468 first.high = first_ch >> 8; 469 show_all = False; 470 } 471 if (end_ch != ~0 && 472 ((unsigned)end_ch <= (last.low + (last.high << 8)))) { 473 last.low = end_ch & 0xff; 474 last.high = end_ch >> 8; 475 show_all = False; 476 } 477 /* make sure the range is legal */ 478 if ((first.high > last.high) || (first.high == last.high && 479 first.low > last.low)) { 480 last = first; 481 fprintf(stderr, 482 "adjusting range -- specifed first char is after end\n"); 483 } 484 show_glyphs(fid, &hdr, show_all, first, last); 485 FSCloseFont(svr, fid); 486 } else { 487 fprintf(stderr, "couldn't get font %s\n", fontname); 488 FSCloseServer(svr); 489 exit(1); 490 } 491 FSCloseServer(svr); 492 exit(0); 493} 494