src/vflserver.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- main
- startup_license
- run_init
- quit
- cmd_loop
- exec_cmd
- parse_args
- cmd_open1
- cmd_open2
- cmd_close
- cmd_bitmap1
- cmd_bitmap2
- cmd_bitmap_output
- cmd_metric1
- cmd_metric2
- cmd_fontbbx1
- cmd_fontbbx2
- cmd_prop
- cmd_minbbx
- put_fontid
- get_fontid
- cmd_proto
- cmd_sleep
- cmd_version
- cmd_vflib_version
- cmd_debug
- cmd_help
- cmd_help_help
- cmd_help_open1
- cmd_help_open2
- cmd_help_close
- cmd_help_bitmap1
- cmd_help_bitmap2
- cmd_help_metric1
- cmd_help_metric2
- cmd_help_fontbbx1
- cmd_help_fontbbx2
- cmd_help_property
- cmd_help_minbbx
- cmd_help_protocol
- cmd_help_quit
- cmd_help_version
- cmd_help_debug
- cmd_help_sleep
- dump_bitmap_hex
- dump_bitmap_char
- str_toupper
1 /*
2 * vflserver.c - a font server using VFlib
3 * by Hirotsugu Kakugawa
4 *
5 * 4 Nov 1996 First implementation (for VFlib 3.0.0)
6 * 10 Dec 1996 For VFlib 3.1.0. Enhanced HELP.
7 * 13 Dec 1996 Added PROPERTY command.
8 * 20 Dec 1996 Added MINIMIZE-BBX command.
9 * 7 Mar 1997 Added COPYING command
10 * 22 Mar 1997 Upgraded for VFlib 3.2
11 * 4 Aug 1997 Upgraded for VFlib 3.3 (VFlib API is changed.)
12 * 22 Jan 1998 Upgraded for VFlib 3.4 (Protocol 2.0.)
13 * 1 Jun 1998 Changed program names ('vfserver' => 'vflserver')
14 * 22 Jul 1998 Added ! syntax for specifying font id. (e.g., '!1', '!!')
15 * 8 Dec 1999 Added VFLIB-VERSION command (Protocol 2.1.)
16 */
17 /*
18 * Copyright (C) 1996-1999 Hirotsugu Kakugawa.
19 * All rights reserved.
20 *
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2, or (at your option)
24 * any later version.
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 */
35
36
37 /*
38 * Usage: vflserver [-v vflibcap] [-s shrink] [cmd-file ... ]
39 *
40 * Example: ./vflserver -v `pwd`/vflibcap
41 *
42 * Commands:
43 * (Command names are case insensitive; font names are case sensitive.)
44 * OPEN1 font [ point_size [ mag_x mag_y [ dpi_x dpi_y ]]]
45 * OPEN2 font [ pixel_size [ mag_x mag_y ]]
46 * CLOSE font-id
47 * BITMAP1 font-id code_point [ mag_x mag_y ]
48 * BITMAP2 font-id code_point [ mag_x mag_y ]
49 * METRIC1 font-id code_point [ mag_x mag_y ]
50 * METRIC2 font-id code_point [ mag_x mag_y ]
51 * FONTBBX1 font-id [ mag_x mag_y ]
52 * FONTBBX2 font-id [ mag_x mag_y ]
53 * PROPERTY font-id property
54 * MINIMIZE-BBX [flag]
55 * PROTOCOL
56 * QUIT
57 * VERSION
58 * VFLIB-VERSION
59 * DEBUG [category]
60 * SLEEP [sec]
61 * HELP
62 *
63 */
64
65
66 #include "config.h"
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <ctype.h>
70 #ifdef HAVE_UNISTD_H
71 # include <unistd.h>
72 #endif
73 #include "VFlib-3_6.h"
74
75 #define PROTOCOL_VERSION "VFSERVER/2.0"
76
77 #ifndef VERSION
78 # define VERSION "2.1"
79 #endif
80
81 #define MIN_SHRINK 0.05
82 #define MAX_ARGS 8
83 #define MAX_ARG_LEN 80
84 #define FONTID_TABLE_SIZE 4096
85
86
87 static int minimize_bbx_mode = 0;
88 static int dump_bitmap_mode = 0;
89 static int fontid_table[FONTID_TABLE_SIZE];
90 static int fontid_seq;
91
92 static void startup_license(FILE*);
93 static void run_init(char*,double);
94 static void cmd_loop(FILE*,int,double);
95 static int exec_cmd(char*,double);
96 static void quit(void);
97
98 static int parse_args(char**,char*);
99 static void str_toupper(char *s);
100 static void dump_bitmap_hex(VF_BITMAP);
101 static void dump_bitmap_char(VF_BITMAP,double);
102 extern void vf_dump_bitmap(VF_BITMAP);
103
104 static int cmd_open1(char**,int);
105 static int cmd_open2(char**,int);
106 static int cmd_close(char**,int);
107 static int cmd_bitmap1(char**,int,double);
108 static int cmd_bitmap2(char**,int,double);
109 static int cmd_bitmap_output(VF_BITMAP,long,double);
110 static int cmd_metric1(char**,int);
111 static int cmd_metric2(char**,int);
112 static int cmd_fontbbx1(char**,int);
113 static int cmd_fontbbx2(char**,int);
114 static int cmd_prop(char**,int);
115 static int cmd_minbbx(char**,int);
116 static int cmd_proto(char**,int);
117 static int cmd_help(char**,int);
118 static int cmd_debug(char**,int);
119 static int cmd_sleep(char**,int);
120 static int cmd_version(char**,int);
121 static int cmd_vflib_version(char**,int);
122 static void put_fontid(int);
123 static int get_fontid(char*);
124
125
126
127
128 int
129 main(int argc, char **argv)
/* [<][>][^][v][top][bottom][index][help] */
130 {
131 char *vfcap, **drv_list;
132 double shrink;
133 int i, w;
134
135 vfcap = NULL;
136 shrink = -1;
137 minimize_bbx_mode = 0;
138
139 --argc; argv++;
140 while (argc > 0){
141 if ((argc >= 1)
142 && ((strcmp(argv[0], "-h") == 0) || (strcmp(argv[0], "-help") == 0))){
143 printf("VFLSERVER - a VFlib server\n");
144 printf("Usage: vflserver [-v vflibcap] [cmd-file ... ]\n");
145 printf(" Example: ./vflserver -v /usr/local/lib/VFlib3/vflibcap\n");
146 exit(0);
147 } else if ((argc >= 2) && (strcmp(argv[0], "-v") == 0)){
148 --argc; argv++;
149 vfcap = argv[0];
150 --argc; argv++;
151 } else if ((argc >= 2) && (strcmp(argv[0], "-s") == 0)){
152 --argc; argv++;
153 if ((shrink = atof(argv[0])) < MIN_SHRINK)
154 shrink = MIN_SHRINK;
155 --argc; argv++;
156 } else {
157 break;
158 }
159 }
160
161 if ((VF_Init(vfcap, NULL) < 0)
162 || ((drv_list = VF_FontDriverList()) == NULL)){
163 printf("(550 \"vflserver version %s. ", VERSION);
164 printf("based on VFlib %s ", VF_GetVersion());
165 printf("VFlib error %d)\n", vf_error);
166 switch (vf_error){
167 case VF_ERR_INTERNAL:
168 printf("; Internal error.\n"); break;
169 case VF_ERR_NO_MEMORY:
170 printf("; Server runs out of memory.\n"); break;
171 case VF_ERR_NO_VFLIBCAP:
172 printf("; No vflibcap.\n"); break;
173 }
174 fflush(stdout);
175 exit(1);
176 }
177
178 printf("; This is a font server VFLSERVER Version %s\n", VERSION);
179 printf("; (based on VFlib version %s)\n", VF_GetVersion());
180 printf("; Installed font drivers:");
181 w = 9999;
182 for (i = 0; drv_list[i] != NULL; i++){
183 if (w > 50){
184 printf("\n; ");
185 w = 0;
186 }
187 printf("%s ", drv_list[i]);
188 w += strlen(drv_list[i]) + 1;
189 }
190 printf("\n");
191
192 startup_license(stdout);
193
194 printf("; Type `HELP' for description of the protocol.\n\n");
195 printf("(100 \"vflserver ready.\")\n");
196 fflush(stdout);
197 free(drv_list);
198
199 fontid_seq = 0;
200 for (i = 0; i < FONTID_TABLE_SIZE; i++)
201 fontid_table[i] = -1;
202
203 while (argc > 0){
204 run_init(argv[0], shrink);
205 --argc; argv++;
206 }
207
208 cmd_loop(stdin, 0, shrink);
209
210 quit();
211
212 return 0;
213 }
214
215 static void
216 startup_license(FILE *fp)
/* [<][>][^][v][top][bottom][index][help] */
217 {
218 if (fp == NULL)
219 fp = stdout;
220 fprintf(fp,
221 "; Copyright (C) 1996-1999 by Hirotsugu Kakugawa\n"
222 "; All rights reserved.\n"
223 "; This program is distributed in the hope that it will be useful,\n"
224 "; but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
225 "; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
226 "; GNU General Public License for more details.\n");
227 }
228
229
230 static void
231 run_init(char *f, double shrink)
/* [<][>][^][v][top][bottom][index][help] */
232 {
233 FILE *fp;
234
235 if ((fp = fopen(f, "r")) == NULL){
236 fprintf(stderr, "No such file: %s\n", f);
237 } else {
238 cmd_loop(fp, 1, shrink);
239 fclose(fp);
240 }
241 }
242
243 static void
244 quit(void)
/* [<][>][^][v][top][bottom][index][help] */
245 {
246 printf("(100 \"Happy hacking.\")\n");
247 fflush(stdout);
248 }
249
250 static void
251 cmd_loop(FILE *fp, int echo, double shrink)
/* [<][>][^][v][top][bottom][index][help] */
252 {
253 char cmdline[1024];
254 int val;
255
256 val = 0;
257 for (;;){
258 if (fgets(cmdline, sizeof(cmdline), fp) == NULL)
259 break;
260 if (echo == 1)
261 printf("%s", cmdline);
262 if ((val = exec_cmd(cmdline, shrink)) < 0){
263 quit();
264 exit(0);
265 }
266 fflush(stdout);
267 }
268 }
269
270 static int
271 exec_cmd(char *cmdline, double shrink)
/* [<][>][^][v][top][bottom][index][help] */
272 {
273 char cmd[32], *args[MAX_ARGS];
274 int nargs, i, j, iarg, ret;
275
276 ret = 0;
277 iarg = 0;
278 while ((cmdline[iarg] != '\0') && isspace((int)cmdline[iarg]))
279 iarg++;
280 if (cmdline[iarg] == '\0')
281 return ret;
282 j = 0;
283 while ((cmdline[iarg] != '\0') && !isspace((int)cmdline[iarg]))
284 cmd[j++] = cmdline[iarg++];
285 cmd[j] = '\0';
286
287 for (i = 0; cmd[i] != '\0'; i++)
288 cmd[i] = toupper(cmd[i]);
289 nargs = parse_args(args, &cmdline[iarg]);
290
291 if (strcmp(cmd, "QUIT") == 0){
292 ret = -1;
293 } else if (strcmp(cmd, "OPEN1") == 0){
294 cmd_open1(args, nargs);
295 } else if (strcmp(cmd, "OPEN2") == 0){
296 cmd_open2(args, nargs);
297 } else if (strcmp(cmd, "CLOSE") == 0){
298 cmd_close(args, nargs);
299 } else if (strcmp(cmd, "BITMAP1") == 0){
300 cmd_bitmap1(args, nargs, shrink);
301 } else if (strcmp(cmd, "BITMAP2") == 0){
302 cmd_bitmap2(args, nargs, shrink);
303 } else if (strcmp(cmd, "METRIC1") == 0){
304 cmd_metric1(args, nargs);
305 } else if (strcmp(cmd, "METRIC2") == 0){
306 cmd_metric2(args, nargs);
307 } else if (strcmp(cmd, "FONTBBX1") == 0){
308 cmd_fontbbx1(args, nargs);
309 } else if (strcmp(cmd, "FONTBBX2") == 0){
310 cmd_fontbbx2(args, nargs);
311 } else if (strcmp(cmd, "PROPERTY") == 0){
312 cmd_prop(args, nargs);
313 } else if (strcmp(cmd, "PROTOCOL") == 0){
314 cmd_proto(args, nargs);
315 } else if (strcmp(cmd, "MINIMIZE-BBX") == 0){
316 cmd_minbbx(args, nargs);
317 } else if (strcmp(cmd, "COMMENT") == 0){
318 printf("100 Ok.\n");
319 } else if (strcmp(cmd, "DEBUG") == 0){
320 cmd_debug(args, nargs);
321 } else if (strcmp(cmd, "HELP") == 0){
322 cmd_help(args, nargs);
323 } else if (strcmp(cmd, "SLEEP") == 0){
324 cmd_sleep(args, nargs);
325 } else if (strcmp(cmd, "VERSION") == 0){
326 cmd_version(args, nargs);
327 } else if (strcmp(cmd, "VFLIB-VERSION") == 0){
328 cmd_vflib_version(args, nargs);
329 } else {
330 printf("(500 \"Error. Command unknown. (`HELP' for help.)\")\n");
331 }
332 return ret;
333 }
334
335 static int
336 parse_args(char **args, char *cmdline)
/* [<][>][^][v][top][bottom][index][help] */
337 {
338 int argc, idx;
339
340 idx = 0;
341 for (argc = 0; argc < MAX_ARGS-1;){
342 while (isspace((int)cmdline[idx]))
343 idx++;
344 if (cmdline[idx] == '\0')
345 break;
346 args[argc] = &cmdline[idx];
347 argc++;
348 while (!isspace((int)cmdline[idx]) && (cmdline[idx] != '\0'))
349 idx++;
350 if (cmdline[idx] == '\0')
351 break;
352 cmdline[idx++] = '\0';
353 }
354 args[argc] = NULL;
355
356 return argc;
357 }
358
359
360 /* ------------------------------------------------------------- */
361
362 /*
363 * OPEN1 font [ point_size [ mag_x mag_y [ dpi_x dpi_y ]]]
364 */
365 static int
366 cmd_open1(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
367 {
368 int font_id;
369 char *font;
370 double point_size, mag_x, mag_y, dpi_x, dpi_y;
371
372 if ((nargs != 1) && (nargs != 2) && (nargs != 4) && (nargs != 6)){
373 printf("500 What? %s\n",
374 "OPEN1 font [ point_size [ mag_x mag_y [ dpi_x dpi_y ]]]");
375 return -1;
376 }
377
378 font = NULL;
379 point_size = -1;
380 mag_x = 1;
381 mag_y = 1;
382 dpi_x = -1;
383 dpi_y = -1;
384
385 font = args[0];
386 if (nargs >= 2)
387 point_size = atof(args[1]);
388 if (nargs >= 4){
389 mag_x = atof(args[2]);
390 mag_y = atof(args[3]);
391 }
392 if (nargs >= 6){
393 dpi_x = atof(args[4]);
394 dpi_y = atof(args[5]);
395 }
396
397 font_id = VF_OpenFont1(font, dpi_x, dpi_y, point_size, mag_x, mag_y);
398 put_fontid(font_id);
399
400 if (font_id < 0){
401 printf("(551 \"Error. Can't open %s.\")\n", font);
402 return -1;
403 }
404
405 printf("(100 %d \"%s\")\n", font_id, font);
406
407 return 0;
408 }
409
410 /*
411 * OPEN2 font [ pixel_size [ mag_x mag_y ]]
412 */
413 static int
414 cmd_open2(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
415 {
416 int font_id;
417 char *font;
418 int pixel_size;
419 double mag_x, mag_y;
420
421 if ((nargs != 1) && (nargs != 2) && (nargs != 4) ){
422 printf("500 What? %s\n",
423 "OPEN2 font [ pixel_size [ mag_x mag_y ]]");
424 return -1;
425 }
426
427 font = NULL;
428 pixel_size = -1;
429 mag_x = 1;
430 mag_y = 1;
431
432 font = args[0];
433 if (nargs >= 2)
434 sscanf(args[1], "%i", &pixel_size);
435 if (nargs >= 4){
436 mag_x = atof(args[2]);
437 mag_y = atof(args[3]);
438 }
439
440 font_id = VF_OpenFont2(font, pixel_size, mag_x, mag_y);
441 put_fontid(font_id);
442
443 if (font_id < 0){
444 printf("(551 \"Error. Can't open %s.\")\n", font);
445 return -1;
446 }
447
448 printf("(100 %d \"%s\")\n", font_id, font);
449
450 return 0;
451 }
452
453 /*
454 * CLOSE font-id
455 */
456 static int
457 cmd_close(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
458 {
459 int font_id;
460
461 if (nargs != 1){
462 printf("500 What? %s\n", "CLOSE font-id");
463 return -1;
464 }
465
466 font_id = get_fontid(args[0]);
467 VF_CloseFont(font_id);
468
469 printf("(100 %d)\n", font_id);
470 return 0;
471 }
472
473 /*
474 * BITMAP1 font-id code_point [ mag_x mag_y ]
475 */
476 static int
477 cmd_bitmap1(char **args, int nargs, double shrink)
/* [<][>][^][v][top][bottom][index][help] */
478 {
479 int font_id, val;
480 long code_point;
481 double mag_x, mag_y;
482 VF_BITMAP bm, bm1;
483
484 if ((nargs != 2) && (nargs != 3) && (nargs != 4)){
485 printf("(500 \"Error. Usage:%s\")\n",
486 "BITMAP1 font-id char-code [ mag_x mag_y ]");
487 return -1;
488 }
489
490 font_id = -1;
491 code_point = 0;
492 mag_x = 1;
493 mag_y = 1;
494
495 font_id = get_fontid(args[0]);
496 sscanf(args[1], "%li", &code_point);
497 if (nargs == 3){
498 mag_x = mag_y = atof(args[2]);
499 } else if (nargs == 4){
500 mag_x = atof(args[2]);
501 mag_y = atof(args[3]);
502 }
503
504 bm = VF_GetBitmap1(font_id, code_point, mag_x, mag_y);
505
506 if (bm != NULL){
507 if (minimize_bbx_mode == 1){
508 bm1 = VF_MinimizeBitmap(bm);
509 val = cmd_bitmap_output(bm1, code_point, shrink);
510 VF_FreeBitmap(bm1);
511 VF_FreeBitmap(bm);
512 } else {
513 val = cmd_bitmap_output(bm, code_point, shrink);
514 VF_FreeBitmap(bm);
515 }
516 } else {
517 val = cmd_bitmap_output(bm, code_point, shrink);
518 }
519
520 return val;
521 }
522
523 /*
524 * BITMAP2 font-id code_point [ mag_x mag_y ]
525 */
526 static int
527 cmd_bitmap2(char **args, int nargs, double shrink)
/* [<][>][^][v][top][bottom][index][help] */
528 {
529 int font_id, val;
530 long code_point;
531 double mag_x, mag_y;
532 VF_BITMAP bm, bm1;
533
534 if ((nargs != 2) && (nargs != 3) && (nargs != 4)){
535 printf("(500 \"Error. Usage: %s\")\n",
536 "BITMAP2 font-id char-code [ mag_x mag_y ]");
537 return -1;
538 }
539
540 font_id = -1;
541 code_point = 0;
542 mag_x = 1;
543 mag_y = 1;
544
545 font_id = get_fontid(args[0]);
546 sscanf(args[1], "%li", &code_point);
547 if (nargs == 3){
548 mag_x = mag_y = atof(args[2]);
549 } else if (nargs == 4){
550 mag_x = atof(args[2]);
551 mag_y = atof(args[3]);
552 }
553
554 bm = VF_GetBitmap2(font_id, code_point, mag_x, mag_y);
555 if (bm != NULL){
556 if (minimize_bbx_mode == 1){
557 bm1 = VF_MinimizeBitmap(bm);
558 val = cmd_bitmap_output(bm1, code_point, shrink);
559 VF_FreeBitmap(bm1);
560 VF_FreeBitmap(bm);
561 } else {
562 val = cmd_bitmap_output(bm, code_point, shrink);
563 VF_FreeBitmap(bm);
564 }
565 } else {
566 val = cmd_bitmap_output(bm, code_point, shrink);
567 }
568
569 return val;
570 }
571
572 static int
573 cmd_bitmap_output(VF_BITMAP bm, long code_point, double shrink)
/* [<][>][^][v][top][bottom][index][help] */
574 {
575 if (bm == NULL){
576 switch (vf_error){
577 case VF_ERR_ILL_FONTID:
578 printf("(550 \"Error. Illegal font-id.\")\n");
579 break;
580 case VF_ERR_INTERNAL:
581 printf("(550 \"Error. Internal error.\")\n");
582 break;
583 case VF_ERR_NO_MEMORY:
584 printf("(550 \"Error. No memory.\")\n");
585 break;
586 case VF_ERR_ILL_CODE_POINT:
587 printf("(550 \"Error. No such character %ld (0x%04lx).\")\n",
588 code_point, code_point);
589 break;
590 default:
591 printf("(550 \"Error. VFlib error code = %d.\")\n", vf_error);
592 }
593 return -1;
594 }
595
596 printf("(100 %d %d %d %d %d %d\n ",
597 bm->bbx_width, bm->bbx_height,
598 bm->off_x, bm->off_y, bm->mv_x, bm->mv_y);
599 dump_bitmap_hex(bm);
600 if (dump_bitmap_mode == 1)
601 dump_bitmap_char(bm, shrink);
602 printf(")\n");
603 return 0;
604 }
605
606 /*
607 * METRIC1 font-id code_point [ mag_x mag_y ]
608 */
609 static int
610 cmd_metric1(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
611 {
612 int font_id;
613 long code_point;
614 double mag_x, mag_y;
615 VF_METRIC1 met;
616
617 if ((nargs != 2) || (nargs > 4)){
618 printf("(500 \"Error. Usage: %s\")\n",
619 "METRIC1 font-id code_point [ mag_x mag_y ]");
620 return -1;
621 }
622
623 font_id = -1;
624 code_point = 0;
625 mag_x = 1;
626 mag_y = 1;
627
628 font_id = get_fontid(args[0]);
629 sscanf(args[1], "%li", &code_point);
630 if (nargs == 3){
631 mag_x = mag_y = atof(args[2]);
632 } else if (nargs == 4){
633 mag_x = atof(args[2]);
634 mag_y = atof(args[3]);
635 }
636
637 if ((met = VF_GetMetric1(font_id, code_point, NULL, mag_x, mag_y)) == NULL){
638 printf("(550 \"Error. No metric.\")\n");
639 return -1;
640 }
641 printf("(100 %f %f %f %f %f %f)\n",
642 met->bbx_width, met->bbx_height,
643 met->off_x, met->off_y, met->mv_x, met->mv_y);
644 VF_FreeMetric1(met);
645
646 return 0;
647 }
648
649 /*
650 * METRIC2 font-id code_point [ mag_x mag_y ]
651 */
652 static int
653 cmd_metric2(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
654 {
655 int font_id;
656 long code_point;
657 double mag_x, mag_y;
658 VF_METRIC2 met;
659
660 if ((nargs != 2) || (nargs > 4)){
661 printf("500 What? %s\n",
662 "METRIC2 font-id char-code [ mag_x mag_y ]");
663 return -1;
664 }
665
666 font_id = -1;
667 code_point = 0;
668 mag_x = 1;
669 mag_y = 1;
670
671 font_id = get_fontid(args[0]);
672 sscanf(args[1], "%li", &code_point);
673 if (nargs == 3){
674 mag_x = mag_y = atof(args[2]);
675 } else if (nargs == 4){
676 mag_x = atof(args[2]);
677 mag_y = atof(args[3]);
678 }
679
680 if ((met = VF_GetMetric2(font_id, code_point, NULL, mag_x, mag_y)) == NULL){
681 printf("(550 \"Error. No metric.\")\n");
682 return -1;
683 }
684 printf("(100 %d %d %d %d %d %d)\n",
685 met->bbx_width, met->bbx_height,
686 met->off_x, met->off_y, met->mv_x, met->mv_y);
687 VF_FreeMetric2(met);
688
689 return 0;
690 }
691
692 /*
693 * FONTBBX1 font-id [ mag_x mag_y ]
694 */
695 static int
696 cmd_fontbbx1(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
697 {
698 int font_id;
699 double mag_x, mag_y;
700 double w, h, xoff, yoff;
701
702 if ((nargs != 1) || (nargs > 3)){
703 printf("(500 \"Error. Usage: %s\")\n",
704 "FONTBBX1 font-id [ mag_x mag_y ]");
705 return -1;
706 }
707
708 font_id = -1;
709 mag_x = 1;
710 mag_y = 1;
711
712 font_id = get_fontid(args[0]);
713 if (nargs == 2){
714 mag_x = mag_y = atof(args[1]);
715 } else if (nargs == 3){
716 mag_x = atof(args[1]);
717 mag_y = atof(args[2]);
718 }
719
720 if (VF_GetFontBoundingBox1(font_id, mag_x, mag_y,
721 &w, &h, &xoff, &yoff) < 0){
722 printf("(550 \"Error. No font bounding box information.\")\n");
723 return -1;
724 }
725
726 printf("(100 %f %f %f %f)\n", w, h, xoff, yoff);
727 return 0;
728 }
729
730 /*
731 * FONTBBX2 font-id [ mag_x mag_y ]
732 */
733 static int
734 cmd_fontbbx2(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
735 {
736 int font_id;
737 double mag_x, mag_y;
738 int w, h, xoff, yoff;
739
740 if ((nargs != 1) || (nargs > 3)){
741 printf("(500 \"Error. Usage: %s\")\n",
742 "FONTBBX2 font-id [ mag_x mag_y ]");
743 return -1;
744 }
745
746 font_id = -1;
747 mag_x = 1;
748 mag_y = 1;
749
750 font_id = get_fontid(args[0]);
751 if (nargs == 2){
752 mag_x = mag_y = atof(args[1]);
753 } else if (nargs == 3){
754 mag_x = atof(args[1]);
755 mag_y = atof(args[2]);
756 }
757
758 if (VF_GetFontBoundingBox2(font_id, mag_x, mag_y,
759 &w, &h, &xoff, &yoff) < 0){
760 printf("(550 \"Error. No font bounding box information.\")\n");
761 return -1;
762 }
763
764 printf("(100 %d %d %d %d)\n", w, h, xoff, yoff);
765 return 0;
766 }
767
768 /*
769 * PROPERTY font-id property
770 */
771 static int
772 cmd_prop(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
773 {
774 int font_id;
775 char *prop, *value;
776
777 if (nargs != 2){
778 printf("(500 \"Error. Usage: %s\")\n",
779 "PROPERTY font-id property");
780 return -1;
781 }
782
783 font_id = get_fontid(args[0]);
784 prop = args[1];
785
786 if ((value = VF_GetFontProp(font_id, prop)) == NULL){
787 printf("(550 \"Error. No such property: %s\")\n", prop);
788 return -1;
789 }
790
791 printf("(100 \"%s\" \"%s\")\n", prop, value);
792 free(value);
793
794 return 0;
795 }
796
797 /*
798 * MINIMIZE-BBX [flag]
799 */
800 static int
801 cmd_minbbx(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
802 {
803 char *res;
804 int val;
805
806 if (nargs != 1){
807 printf("(500 \"Error. Usage: %s\")\n",
808 "MINIMIZE-BBX [flag]");
809 return -1;
810 }
811
812 res = "100";
813 val = 0;
814
815 str_toupper(args[0]);
816 if ( (strcmp(args[0], "0") == 0)
817 || (strcmp(args[0], "OFF") == 0)
818 || (strcmp(args[0], "NO") == 0)){
819 minimize_bbx_mode = 0;
820 } else if ( (strcmp(args[0], "1") == 0)
821 || (strcmp(args[0], "ON") == 0)
822 || (strcmp(args[0], "YES") == 0)){
823 minimize_bbx_mode = 1;
824 } else {
825 res = "500";
826 val = -1;
827 }
828 printf("(%s \"%s\")\n", res, minimize_bbx_mode?"ON":"OFF");
829
830 return val;
831 }
832
833
834 static void
835 put_fontid(int fontid)
/* [<][>][^][v][top][bottom][index][help] */
836 {
837 if (fontid_seq < FONTID_TABLE_SIZE)
838 fontid_table[fontid_seq++] = fontid;
839 }
840
841 static int
842 get_fontid(char *s)
/* [<][>][^][v][top][bottom][index][help] */
843 {
844 int fontid, h;
845
846 fontid = -1;
847 if (s[0] == '!'){ /* font id by history */
848 if (strcmp(s, "!!") == 0){ /* "!!" : the latest font id */
849 if ((fontid_seq > 0) && (fontid_seq < FONTID_TABLE_SIZE))
850 fontid = fontid_table[fontid_seq-1];
851 } else { /* "!i" : font id for i-th VF_OpenFontX() */
852 sscanf(&s[1], "%i", &h);
853 if ((h >= 0) && (h < FONTID_TABLE_SIZE))
854 fontid = fontid_table[h];
855 }
856 } else { /* font id by number */
857 sscanf(s, "%i", &fontid);
858 }
859
860 return fontid;
861 }
862
863
864
865 /*
866 * PROTOCOL
867 */
868 static int
869 cmd_proto(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
870 {
871 printf("(100 \"%s\")\n", PROTOCOL_VERSION);
872 return 0;
873 }
874
875 /*
876 * SLEEP [sec]
877 */
878 static int
879 cmd_sleep(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
880 {
881 int t;
882
883 t = 1;
884 if (args[0] != NULL){
885 if ((t = atoi(args[0])) < 1)
886 t = 1;
887 }
888 sleep(t);
889 printf("(100 %d)\n", t);
890 return 0;
891 }
892
893 /*
894 * VERSION
895 */
896 static int
897 cmd_version(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
898 {
899 printf("(100 \"%s\")\n", VERSION);
900 return 0;
901 }
902
903 /*
904 * VFlib VERSION
905 */
906 static int
907 cmd_vflib_version(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
908 {
909 printf("(100 \"%s\")\n", VF_GetVersion());
910 return 0;
911 }
912
913 extern void VF_DumpFontTable(void);
914 /*
915 * DEBUG [category]
916 */
917 static int
918 cmd_debug(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
919 {
920 if (args[0] != NULL){
921 str_toupper(args[0]);
922 if (strcmp(args[0], "BITMAP") == 0){
923 dump_bitmap_mode = 1 - dump_bitmap_mode;
924 printf("(100 \"Ascii-art bitmap %s.\")\n",
925 (dump_bitmap_mode==1)?"on":"off");
926 } else if (strcmp(args[0], "DUMPFONTS") == 0){
927 VF_DumpFontTable();
928 } else {
929 printf("(500 \"Error.\")\n");
930 return -1;
931 }
932 } else {
933 printf("(500 \"Error. Debug what? (Type `HELP' for help.)\")\n");
934 }
935 return 0;
936 }
937
938 /*
939 * HELP
940 */
941
942 static void cmd_help_open1(void), cmd_help_open2(void);
943 static void cmd_help_close(void);
944 static void cmd_help_bitmap1(void), cmd_help_bitmap2(void);
945 static void cmd_help_metric1(void), cmd_help_metric2(void);
946 static void cmd_help_fontbbx1(void), cmd_help_fontbbx2(void);
947 static void cmd_help_property(void);
948 static void cmd_help_minbbx(void), cmd_help_protocol(void);
949 static void cmd_help_quit(void), cmd_help_version(void);
950 static void cmd_help_debug(void), cmd_help_sleep(void);
951 static void cmd_help_help(void);
952
953 struct s_help {
954 char *cmd_name;
955 void (*help_func)(void);
956 };
957 static struct s_help helpers[] = {
958 {"OPEN1", cmd_help_open1}, {"OPEN2", cmd_help_open2},
959 {"CLOSE", cmd_help_close},
960 {"BITMAP1", cmd_help_bitmap1}, {"BITMAP2", cmd_help_bitmap2},
961 {"METRIC1", cmd_help_metric1}, {"METRIC2", cmd_help_metric2},
962 {"FONTBBX1", cmd_help_fontbbx1}, {"FONTBBX2", cmd_help_fontbbx2},
963 {"PROPERTY", cmd_help_property}, {"MINIMIZE-BBX", cmd_help_minbbx},
964 {"PROTOCOL", cmd_help_protocol}, {"QUIT", cmd_help_quit},
965 {"VERSION", cmd_help_version}, {"DEBUG", cmd_help_debug},
966 {"HELP", cmd_help_help}, {"SLEEP", cmd_help_sleep}, {"?", cmd_help_help},
967 {NULL, NULL} };
968
969 static int
970 cmd_help(char **args, int nargs)
/* [<][>][^][v][top][bottom][index][help] */
971 {
972
973 if (nargs == 0){
974 printf("; Help keywords:\n");
975 printf("; OPEN1, OPEN2, CLOSE, BITMAP1, BITMAP2, METRIC1, METRIC2\n");
976 printf("; FONTBBX1 FONTBBX2 PROPERTY, MINIMIZE-BBX, PROTOCOL, QUIT\n");
977 printf("; VERSION, DEBUG, HELP, SLEEP\n");
978 printf("; HELP ? --- for more information on command list.\n");
979 printf("; HELP KEY --- help on KEY listed above.\n");
980 printf("; Each command returns result with status value (3 digits) \n");
981 printf("; followed by a command-specific result sequence.\n");
982 printf("(100 \"Ok.\")\n");
983 } else {
984 int i, c;
985 int found;
986
987 for (i = 0; args[0][i] != '\0'; i++)
988 args[0][i] = toupper(args[0][i]);
989 found = 0;
990 c = 0;
991 while (helpers[c].cmd_name != NULL){
992 if (strcmp(helpers[c].cmd_name, args[0]) == 0){
993 found = 1;
994 break;
995 }
996 c++;
997 }
998 if (found == 0){
999 printf("; Unknown help for \"%s\"\n", args[0]);
1000 cmd_help(NULL, 0);
1001 } else {
1002 (*helpers[c].help_func)();
1003 printf("(100 \"Ok.\")\n");
1004 }
1005 }
1006
1007
1008
1009 return 0;
1010 }
1011
1012 static void
1013 cmd_help_help(void)
/* [<][>][^][v][top][bottom][index][help] */
1014 {
1015 printf("; The following commands are recognized.\n");
1016 printf("; OPEN1 font [ point-size [ mag_x mag_y [ dpi_x dpi_y ]]]\n");
1017 printf("; OPEN2 font [ pixel-size [ mag_x mag_y ]]\n");
1018 printf("; CLOSE font-id\n");
1019 printf("; BITMAP1 font-id code_point [ mag_x mag_y ]\n");
1020 printf("; BITMAP2 font-id code_point [ mag_x mag_y ]\n");
1021 printf("; METRIC1 font-id code_point [ mag_x mag_y ]\n");
1022 printf("; METRIC2 font-id code_point [ mag_x mag_y ]\n");
1023 printf("; FONTBBX1 font-id [ mag_x mag_y ]\n");
1024 printf("; FONTBBX2 font-id [ mag_x mag_y ]\n");
1025 printf("; PROPERTY font-id property\n");
1026 printf("; MINIMIZE-BBX [flag]\n");
1027 printf("; PROTOCOL\n");
1028 printf("; QUIT\n");
1029 printf("; VERSION\n");
1030 printf("; DEBUG [category]\n");
1031 printf("; HELP [category]\n");
1032 printf("; SLEEP [sec]\n");
1033 printf("; HELP CMDS --- help on CMDS\n");
1034 printf("; Each command returns result with status value (3 digits) \n");
1035 printf("; followed by a command-specific result sequence.\n");
1036 }
1037
1038 static void
1039 cmd_help_open1(void)
/* [<][>][^][v][top][bottom][index][help] */
1040 {
1041 printf("; OPEN1 font [ point-size [ mag_x mag_y [ dpi_x dpi_y ]]]\n");
1042 printf("; --- Open a font named FONT in mode 1. \n");
1043 printf("; It's parameters are point size (POINT_SIZE),\n");
1044 printf("; magnification factors (MAG_X, MAG_Y), and device \n");
1045 printf("; resolutions in DPI (DPI_X, DPI_Y). If these parameters\n");
1046 printf("; are omitted, default values of the font are used.\n");
1047 printf("; This command returns a font identifier in integer, if\n");
1048 printf("; a requested font is successfully opened.\n");
1049 }
1050 static void
1051 cmd_help_open2(void)
/* [<][>][^][v][top][bottom][index][help] */
1052 {
1053 printf("; OPEN2 font [ pixel-size [ mag_x mag_y ]]\n");
1054 printf("; --- Open a font named FONT in mode 1. \n");
1055 printf("; It's parameters are pixel size (PIXEL_SIZE),\n");
1056 printf("; magnification factors (MAG_X, MAG_Y). If these parameters\n");
1057 printf("; are omitted, default values of the font are used.\n");
1058 printf("; This command returns a font identifier in integer, if\n");
1059 printf("; a requested font is successfully opened.\n");
1060 }
1061 static void
1062 cmd_help_close(void)
/* [<][>][^][v][top][bottom][index][help] */
1063 {
1064 printf("; CLOSE font-id\n");
1065 printf("; --- Close an opened font of FONT_ID.\n");
1066 }
1067 static void
1068 cmd_help_bitmap1(void)
/* [<][>][^][v][top][bottom][index][help] */
1069 {
1070 printf("; BITMAP1 font-id code_point [ mag_x mag_y ]\n");
1071 printf("; --- Get a bitmap of a character CODE_POINT in a FONT_ID.\n");
1072 printf("; FONT_ID must be in mode 1.\n");
1073 printf("; This command returns Bw Bh Rx Ry Mx My BM\n");
1074 printf("; - Bw (width) and Bh (height) form a bounding-box of a bitmap,\n");
1075 printf("; (in pixel).\n");
1076 printf("; - Rx and Ry form a vector from the reference point of \n");
1077 printf("; a bitmap to the upper left corner of a bitmap (in pixel).\n");
1078 printf("; - Mx and My form a vector from the reference point to the next\n");
1079 printf("; next reference point (in pixel).\n");
1080 printf("; - BM is the bitmap, starting from top line of a bitmap to \n");
1081 printf("; the bottom. Each line starts from left to right, 1 bit per\n");
1082 printf("; pixel, padding is 8 pixels. Leftmost pixel in 8 pixel\n");
1083 printf("; packet has 0x80 weight, rightmost one has 0x01.\n");
1084 }
1085 static void
1086 cmd_help_bitmap2(void)
/* [<][>][^][v][top][bottom][index][help] */
1087 {
1088 printf("; BITMAP2 font-id code_point [ mag_x mag_y ]\n");
1089 printf("; --- Get a bitmap of a character CODE_POINT in a FONT_ID.\n");
1090 printf("; FONT_ID must be in mode 2.\n");
1091 printf("; This command returns Bw Bh Rx Ry Mx My BM\n");
1092 printf("; See help on BITMAP1 for return values.\n");
1093 }
1094 static void
1095 cmd_help_metric1(void)
/* [<][>][^][v][top][bottom][index][help] */
1096 {
1097 printf("; METRIC1 font-id code_point [ mag_x mag_y ]\n");
1098 printf("; --- Get a metric of a character CODE_POINT in a FONT_ID.\n");
1099 printf("; FONT_ID must be in mode 1.\n");
1100 printf("; This command returns Bw Bh Rx Ry Mx My\n");
1101 printf("; See help on BITMAP1 for return values, *except* units are\n");
1102 printf("; points.\n");
1103 }
1104 static void
1105 cmd_help_metric2(void)
/* [<][>][^][v][top][bottom][index][help] */
1106 {
1107 printf("; METRIC2 font-id code_point [ mag_x mag_y ]\n");
1108 printf("; --- Get a metric of a character CODE_POINT in a font FONT_ID.\n");
1109 printf("; FONT_ID must be in mode 2.\n");
1110 printf("; This command returns Bw Bh Rx Ry Mx My\n");
1111 printf("; See help on BITMAP1 for return values. (Units are\n");
1112 printf("; pixel.)\n");
1113 }
1114 static void
1115 cmd_help_fontbbx1(void)
/* [<][>][^][v][top][bottom][index][help] */
1116 {
1117 printf("; FONTBBX1 font-id [ mag_x mag_y ]\n");
1118 printf("; --- Get font bounding information of a font FONT_ID.\n");
1119 printf("; FONT_ID must be in mode 1.\n");
1120 printf("; This command returns W H XOFF YOFF\n");
1121 printf("; - W, H are max width, height, respectively.\n");
1122 printf("; - XOFF and YOFF form a max vector from the reference point to\n");
1123 printf("; lower left corner of a bounding box.\n");
1124 printf("; These units are point.\n");
1125 }
1126 static void
1127 cmd_help_fontbbx2(void)
/* [<][>][^][v][top][bottom][index][help] */
1128 {
1129 printf("; FONTBBX2 font-id [ mag_x mag_y ]\n");
1130 printf("; --- Get font bounding information of a font FONT_ID.\n");
1131 printf("; FONT_ID must be in mode 2.\n");
1132 printf("; This command returns W H XOFF YOFF\n");
1133 printf("; - W, H are max width, height, respectively.\n");
1134 printf("; - XOFF and YOFF form a max vector from the reference point to\n");
1135 printf("; lower left corner of a bounding box.\n");
1136 printf("; These units are pixel.\n");
1137 }
1138 static void
1139 cmd_help_property(void)
/* [<][>][^][v][top][bottom][index][help] */
1140 {
1141 printf("; PROPERTY font-id property_name\n");
1142 printf("; --- Get a property value of PROPERTY_NAME of a font FONT_ID.\n");
1143 printf("; This command returns property value in string.\n");
1144 }
1145 static void
1146 cmd_help_minbbx(void)
/* [<][>][^][v][top][bottom][index][help] */
1147 {
1148 printf("; MINIMIZE-BBX [flag]\n");
1149 printf("; --- Followed BITAMAP1 and BITMAP2 commands return `minimized'\n");
1150 printf("; bitmap, in a sense that no smaller bounding box can contain\n");
1151 printf("; all black pixels.\n");
1152 }
1153 static void
1154 cmd_help_protocol(void)
/* [<][>][^][v][top][bottom][index][help] */
1155 {
1156 printf("; PROTOCOL\n");
1157 printf("; --- Return protocol version string.\n");
1158 }
1159 static void
1160 cmd_help_quit(void)
/* [<][>][^][v][top][bottom][index][help] */
1161 {
1162 printf("; QUIT\n");
1163 printf("; --- Quit vflserver.\n");
1164 }
1165 static void
1166 cmd_help_version(void)
/* [<][>][^][v][top][bottom][index][help] */
1167 {
1168 printf("; VERSION\n");
1169 printf("; --- Print version of vflserver.\n");
1170 }
1171 static void
1172 cmd_help_debug(void)
/* [<][>][^][v][top][bottom][index][help] */
1173 {
1174 printf("; DEBUG [category]\n");
1175 printf("; --- Set debug mode on CATEGORY.\n");
1176 printf("; Categories:\n");
1177 printf("; - BITMAP - print obtained bitmaps by BITMAP1 and BITMAP2\n");
1178 printf("; in ASCII art form.\n");
1179 printf("; Currently, only BITMAP is defined for debug category\n");
1180 }
1181 static void
1182 cmd_help_sleep(void)
/* [<][>][^][v][top][bottom][index][help] */
1183 {
1184 printf("; SLEEP [sec]\n");
1185 printf("; --- Sleep for SEC seconds.\n");
1186 }
1187
1188
1189
1190 static void
1191 dump_bitmap_hex(VF_BITMAP bm)
/* [<][>][^][v][top][bottom][index][help] */
1192 {
1193 int x, y, b;
1194 unsigned char *p;
1195
1196 printf("\"");
1197 b = 0;
1198 for (y = 0; y < bm->bbx_height; y++){
1199 p = &bm->bitmap[y * bm->raster];
1200 for (x = 0; x < (bm->bbx_width+7)/8; x++){
1201 printf("%02x", p[x]);
1202 b++;
1203 }
1204 }
1205 printf("\"");
1206 }
1207 static void
1208 dump_bitmap_char(VF_BITMAP bm, double shrink)
/* [<][>][^][v][top][bottom][index][help] */
1209 {
1210 printf("\n\"\n");
1211 vf_dump_bitmap(bm);
1212 printf("\"");
1213 }
1214
1215 static void
1216 str_toupper(char *s)
/* [<][>][^][v][top][bottom][index][help] */
1217 {
1218 while (*s){
1219 *s = toupper(*s);
1220 s++;
1221 }
1222 }
1223
1224
1225 /*EOF*/