1 /*
2  * Author:      William Chia-Wei Cheng (bill.cheng@acm.org)
3  *
4  * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5  *
6  * This file may be distributed under the terms of the Q Public License
7  * as defined by Trolltech AS of Norway and appearing in the file
8  * LICENSE.QPL included in the packaging of this file.
9  *
10  * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11  * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  * @(#)$Header: /mm2/home/cvs/bc-src/tgif/tgif.c,v 1.17 2011/05/16 16:22:00 william Exp $
19  */
20 
21 #define _INCLUDE_FROM_TGIF_C_
22 
23 #include "tgifdefs.h"
24 
25 #include "color.e"
26 #include "dialog.e"
27 #include "exec.e"
28 #include "file.e"
29 #include "font.e"
30 #include "grid.e"
31 #include "mainloop.e"
32 #include "msg.e"
33 #include "names.e"
34 #include "obj.e"
35 #include "page.e"
36 #include "raster.e"
37 #include "setup.e"
38 #include "strtbl.e"
39 #include "tangram2.e"
40 #include "util.e"
41 #include "version.e"
42 
43 /*
44  * extern int	malloc_debug ARGS_DECL((int));
45  */
46 
47 int	lastFile=TRUE;
48 
49 short pDrawFontAsc[] = {
50     8, 10, 12, 14, 17, 22,
51     8, 10, 12, 14, 17, 22,
52     8, 10, 12, 14, 17, 23,
53     8, 10, 12, 14, 17, 22,
54     8,  9, 11, 13, 15, 19,
55     7,  9, 11, 12, 15, 20,
56     7,  9, 11, 13, 15, 19,
57     7,  9, 11, 12, 15, 20,
58     9, 11, 12, 14, 18, 24,
59     9, 11, 12, 14, 17, 24,
60     9, 11, 12, 14, 17, 24,
61     9, 11, 12, 14, 17, 24,
62     8, 11, 12, 14, 18, 23,
63     8, 11, 12, 15, 18, 24,
64     8, 11, 12, 14, 16, 23,
65     8, 11, 12, 14, 16, 24,
66     8, 10, 12, 14, 18, 24,
67     9, 14, 15, 18, 23, 30,
68    10, 14, 16, 17, 23, 30,
69     9, 13, 15, 17, 22, 30,
70     9, 13, 15, 18, 22, 30,
71     9, 12, 14, 15, 19, 26,
72     9, 12, 14, 15, 21, 26,
73     9, 12, 14, 15, 19, 26,
74     9, 12, 14, 15, 20, 26,
75    11, 14, 16, 18, 24, 31,
76    11, 14, 16, 18, 24, 31,
77    11, 14, 16, 18, 24, 31,
78    11, 14, 16, 18, 24, 31,
79    11, 14, 16, 19, 24, 32,
80    11, 15, 16, 19, 24, 33,
81    11, 14, 16, 18, 23, 32,
82    11, 15, 16, 19, 24, 32,
83    11, 12, 13, 14, 19, 27
84 };
85 short pDrawFontDes[] = {
86     2,  3,  3,  4,  4,  6,
87     2,  3,  3,  4,  4,  6,
88     2,  3,  3,  4,  5,  6,
89     2,  3,  3,  3,  4,  6,
90     2,  2,  3,  3,  4,  5,
91     2,  2,  3,  4,  5,  5,
92     2,  2,  3,  3,  4,  5,
93     2,  2,  3,  4,  5,  5,
94     2,  2,  3,  3,  4,  5,
95     2,  2,  3,  3,  5,  5,
96     2,  2,  3,  3,  5,  5,
97     2,  2,  3,  3,  5,  5,
98     2,  2,  3,  3,  4,  5,
99     2,  2,  3,  3,  4,  5,
100     2,  2,  3,  3,  6,  5,
101     2,  2,  3,  3,  6,  5,
102     3,  4,  4,  6,  7,  8,
103     3,  3,  4,  4,  6,  7,
104     3,  3,  4,  4,  6,  7,
105     3,  4,  4,  5,  6,  7,
106     3,  3,  4,  4,  6,  7,
107     2,  3,  3,  4,  5,  6,
108     2,  4,  3,  5,  5,  7,
109     2,  3,  4,  4,  5,  6,
110     2,  4,  4,  5,  5,  7,
111     2,  3,  4,  4,  5,  7,
112     2,  3,  4,  5,  5,  7,
113     2,  3,  4,  5,  5,  7,
114     2,  3,  4,  5,  5,  7,
115     2,  3,  3,  4,  5,  7,
116     2,  3,  3,  4,  5,  7,
117     2,  3,  3,  4,  5,  7,
118     2,  3,  3,  4,  5,  7,
119     4,  3,  4,  5,  5,  7
120 };
121 
122 static
SetProgramName(FileName)123 void SetProgramName(FileName)
124    char *FileName;
125 {
126    char *c_ptr=UtilStrRChr(FileName, DIR_SEP);
127 
128    if (c_ptr != NULL && *(++c_ptr) != '\0') {
129       UtilStrCpyN(progName, sizeof(progName), c_ptr);
130    } else {
131       UtilStrCpyN(progName, sizeof(progName), TOOL_NAME);
132       UtilStrLower(progName);
133    }
134 }
135 
136 static
PrTgifLoad(FileName)137 int PrTgifLoad(FileName)
138    char *FileName;
139 {
140    struct ObjRec *obj_ptr=NULL;
141    char full_name[MAXPATHLENGTH+1], gzipped_fname[MAXPATHLENGTH+1];
142    char tmp_filename[MAXPATHLENGTH+1], tmp_filefullpath[MAXPATHLENGTH+1];
143    int read_status, obj_file=TRUE;
144    FILE *fp=NULL;
145    int tmp_linenum=0, gzipped=FALSE;
146 
147    if (strcmp(FileName, "-") == 0) {
148       return TRUE;
149    }
150    *gzipped_fname = '\0';
151    if (FileNameHasExtension(FileName, OBJ_FILE_TYPE, &gzipped, NULL)) {
152       if (gzipped) {
153          if (cmdLineOpenDisplay) {
154             char *tmp_fname=NULL;
155 
156             if ((tmp_fname=GunzipFileIntoTemp(FileName)) == NULL) {
157                return FALSE;
158             } else {
159                strcpy(gzipped_fname, FileName);
160                strcpy(full_name, tmp_fname);
161                free(tmp_fname);
162             }
163          } else {
164             fprintf(stderr, TgLoadString(STID_TOOL_DONT_KNOW_HOW_RUN_GUNZIP),
165                   TOOL_NAME);
166             fprintf(stderr, "\n");
167             fprintf(stderr, "%s\n",
168                   TgLoadString(STID_SPECIFY_DISPLAY_ON_CMD_LINE));
169             return FALSE;
170          }
171       } else {
172          strcpy(full_name, FileName);
173       }
174    } else if (FileNameHasExtension(FileName, SYM_FILE_TYPE, NULL, NULL)) {
175       strcpy(full_name, FileName);
176       obj_file = FALSE;
177    } else if (FileNameHasExtension(FileName, PIN_FILE_TYPE, NULL, NULL)) {
178       strcpy(full_name, FileName);
179       obj_file = FALSE;
180    } else {
181       sprintf(full_name, "%s.%s", FileName, OBJ_FILE_EXT);
182    }
183    if ((fp=fopen(full_name, "r")) == NULL) {
184       fprintf(stderr, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_READING),
185             full_name);
186       fprintf(stderr, "\n");
187       if (*gzipped_fname != '\0') unlink(full_name);
188       return FALSE;
189    }
190 
191    strcpy(tmp_filefullpath, scanFileFullPath);
192    strcpy(tmp_filename, scanFileName);
193    tmp_linenum = scanLineNum;
194    UtilStrCpyN(scanFileFullPath, sizeof(scanFileFullPath), full_name);
195    strcpy(scanFileName, full_name);
196    scanLineNum = 0;
197 
198    if (!(PRTGIF && cmdLineStdOut)) {
199       if (!cmdLineQuiet) {
200          fprintf(stderr, TgLoadCachedString(CSTID_READING_FILE_DOTS),
201                full_name);
202          fprintf(stderr, "\n");
203       }
204    }
205    readingPageNum = loadedCurPageNum = 0;
206    foundGoodStateObject = FALSE;
207    while ((read_status=ReadObj(fp, &obj_ptr)) == TRUE) {
208       if (obj_ptr != NULL) {
209          AdjForOldVersion(obj_ptr);
210          AddObj(NULL, topObj, obj_ptr);
211       }
212    }
213 
214    strcpy(scanFileFullPath, tmp_filefullpath);
215    strcpy(scanFileName, tmp_filename);
216    scanLineNum = tmp_linenum;
217 
218    fclose(fp);
219 
220    if (read_status == INVALID) {
221       fprintf(stderr, TgLoadString(STID_FILE_VER_ABORT_TOOL),
222             fileVersion, TOOL_NAME, TOOL_NAME, homePageURL);
223       if (*gzipped_fname != '\0') unlink(full_name);
224       return FALSE;
225    }
226    if (*gzipped_fname != '\0') {
227       unlink(full_name);
228       strcpy(full_name, gzipped_fname);
229    }
230    if (cmdLineOpenDisplay || *cmdLineGenParser != '\0') {
231       char file_path[MAXPATHLENGTH+1];
232 
233       if (*full_name == DIR_SEP) {
234          strcpy(file_path, full_name);
235       } else {
236          sprintf(file_path, "%s%c%s", curDir, DIR_SEP, full_name);
237       }
238       curFileDefined = TRUE;
239       if (obj_file) {
240          SetCurDir(file_path);
241          *curSymDir = '\0';
242       } else {
243          SetCurSymDir(file_path);
244       }
245    }
246    if (cmdLineHasPageNum) {
247       if (cmdLinePageNum > lastPageNum) {
248          if (lastPageNum == 1) {
249             fprintf(stderr, TgLoadString(STID_FILE_SKIP_CONTAINS_ONE_PAGE),
250                   FileName);
251          } else {
252             fprintf(stderr, TgLoadString(STID_FILE_SKIP_CONTAINS_NUM_PAGE),
253                   FileName, lastPageNum);
254          }
255          fprintf(stderr, "\n");
256          return FALSE;
257       }
258       GotoPageNum(cmdLinePageNum);
259    }
260    if (cmdLineColor && colorMenuItems == NULL) {
261       fprintf(stderr, TgLoadString(STID_FILE_NOT_CONTAIN_COLOR_ABORT),
262             TOOL_NAME);
263       fprintf(stderr, "\n");
264       return FALSE;
265    }
266    if (loadedCurPageNum > 0 && curPage != NULL && lastPageNum > 1) {
267       /*
268        * Well, it should go to loadedCurPageNum because it was the page
269        * at which the file was saved.  But we go to lastPageNum to stay
270        * compatible with Tangram-II since it was expected for tgif to
271        * behave this way.
272        */
273       GotoPageNum(lastPageNum);
274    }
275    return TRUE;
276 }
277 
278 static
PrTgifDump(inbuf,tile_page_err_msg_id)279 void PrTgifDump(inbuf, tile_page_err_msg_id)
280    char *inbuf;
281    int tile_page_err_msg_id;
282 {
283    if (inbuf != NULL && strcmp(inbuf, "-") != 0) {
284       UtilStrCpyN(cmdLineOpenFile, sizeof(cmdLineOpenFile), inbuf);
285    }
286    if (cmdLineNoShowPageInEPS) showPageInEPS = FALSE;
287    if (*cmdLineFileToExec != '\0') {
288       if (!cmdLineQuiet) {
289          fprintf(stderr, TgLoadString(STID_EXECUTING_GIVEN_SCRIPT),
290                cmdLineFileToExec);
291          fprintf(stderr, "\n");
292       }
293       StartExecCmdsFromFile();
294    } else {
295       colorDump = cmdLineColor;
296       if (cmdLineOpenDisplay) {
297          whereToPrint = cmdLineWhereToPrint;
298       }
299       if (cmdLineOneFilePerPage) {
300          if (pageLayoutMode == PAGE_TILE) {
301             fprintf(stderr, "%s\n", TgLoadString(tile_page_err_msg_id));
302          } else {
303             if (cmdLineHasPageNum) {
304                sprintf(cmdLinePageNumStr, "%1d", cmdLinePageNum);
305                GotoPageNum(cmdLinePageNum);
306                if (inbuf != NULL) Dump(inbuf);
307             } else {
308                cmdLineHasPageNum = TRUE;
309                for (cmdLinePageNum=1; cmdLinePageNum <= lastPageNum;
310                      cmdLinePageNum++) {
311                   sprintf(cmdLinePageNumStr, "%1d", cmdLinePageNum);
312                   GotoPageNum(cmdLinePageNum);
313                   if (inbuf != NULL) Dump(inbuf);
314                }
315                cmdLineHasPageNum = FALSE;
316             }
317          }
318       } else {
319          if (inbuf != NULL) Dump(inbuf);
320       }
321    }
322    *cmdLineOpenFile = '\0';
323    DelAllObj();
324    if (cmdLineColor) CleanUpColors();
325    if (cmdLineOpenDisplay) {
326       CleanUp();
327    }
328 }
329 
330 static
DoPrTgif(argc,argv,from_prtgif)331 void DoPrTgif(argc, argv, from_prtgif)
332    int argc, from_prtgif;
333    char *argv[];
334 {
335    char inbuf[MAXSTRING+1];
336    int len, argc_to_be;
337 
338    *scanFileFullPath = *scanFileName = '\0';
339    scanLineNum = 0;
340 
341    if ((argc_to_be=ProcessPrTgifOptions(argc, argv, from_prtgif)) == INVALID) {
342       return;
343    }
344    while (argc > argc_to_be) {
345       argc--; argv++;
346    }
347    InitPaperSize();
348    InitTmpDir();
349    InitPatFill();
350    if (PRTGIF && !cmdLineOpenDisplay) {
351       InitDontReencode(NULL);
352       InitPSFontCharSubs();
353    }
354    if (*cmdLineGenParser != '\0') {
355       if (cmdLineTgrm2) {
356          InitNames();
357       }
358    }
359    if (argc <= 0) {
360       if (cmdLineStdOut) {
361          fprintf(stderr, "\n%s\n",
362                TgLoadString(STID_SPEC_FILE_WHEN_STDOUT_USED));
363          return;
364       } else if (strcmp(cmdLineFileToExec, "-") == 0) {
365          if (cmdLineOpenDisplay) {
366             JustInit(NULL, NULL);
367             Init2PatFill();
368          }
369          PrTgifDump(NULL, STID_CANT_ONEFPPAGE_IN_TILED_PAGE);
370       } else {
371          sprintf(gszMsgBox, TgLoadString(STID_TOOL_FILE_NAME_TO_PRINT),
372                TOOL_NAME);
373          fprintf(stderr, "\n%s> ", gszMsgBox);
374          fflush(stderr);
375          while (fgets(inbuf, MAXSTRING, stdin) != NULL) {
376             len = strlen(inbuf);
377             if (len > 0) {
378                if (inbuf[--len] == '\n') inbuf[len] = '\0';
379                if (*cmdLineGenParser != '\0') {
380                   if (cmdLineTgrm2) {
381                      if (PrTgifLoad(inbuf)) {
382                         Tangram2GenerateChain(cmdLineGenParser);
383                         DelAllObj();
384                      } else {
385                         fprintf(stderr, "\n");
386                      }
387                   }
388                } else if (cmdLineDumpURL) {
389                   UrlDump(inbuf);
390                } else if (cmdLineDosEpsFilter) {
391                   UtilStrCpyN(cmdLineOpenFile, sizeof(cmdLineOpenFile), inbuf);
392                   DosEpsFilter(inbuf);
393                } else {
394                   if (cmdLineOpenDisplay) {
395                      JustInit(NULL, NULL);
396                   }
397                   if (PrTgifLoad(inbuf)) {
398                      PrTgifDump(inbuf, STID_CANT_ONEFPPAGE_IN_TILED_PAGE);
399                   } else {
400                      fprintf(stderr, "\n");
401                   }
402                }
403             }
404             sprintf(gszMsgBox, TgLoadString(STID_TOOL_FILE_NAME_TO_PRINT),
405                   TOOL_NAME);
406             fprintf(stderr, "\n%s> ", gszMsgBox);
407             fflush(stderr);
408          }
409          fprintf(stderr, "\n");
410          fflush(stderr);
411       }
412    } else {
413       if (cmdLineStdOut && argc > 2) {
414          fprintf(stderr, "\n%s\n",
415                TgLoadString(STID_ONE_FILE_ONLY_WITH_STDOUT));
416          return;
417       }
418       for ( ; argc > 0; argc--, argv++) {
419          lastFile = (argc == 1);
420          if (*cmdLineGenParser != '\0') {
421             if (cmdLineTgrm2) {
422                if (PrTgifLoad(*argv)) {
423                   Tangram2GenerateChain(cmdLineGenParser);
424                   DelAllObj();
425                } else {
426                   fprintf(stderr, "\n");
427                }
428             }
429          } else if (cmdLineDumpURL) {
430             UrlDump(*argv);
431             if (argc > 1) {
432                fprintf(stderr, "%s\n",
433                      TgLoadString(STID_ONE_FILE_ONLY_RAW_PLUS_H));
434             }
435             break;
436          } else if (cmdLineDosEpsFilter) {
437             UtilStrCpyN(cmdLineOpenFile, sizeof(cmdLineOpenFile), *argv);
438             DosEpsFilter(*argv);
439             if (argc > 1) {
440                fprintf(stderr, "%s\n",
441                      TgLoadString(STID_ONE_FILE_ONLY_DOSEPSFILTER));
442             }
443             break;
444          } else {
445             if (cmdLineOpenDisplay) {
446                JustInit(NULL, NULL);
447             }
448             if (PrTgifLoad(*argv)) {
449                PrTgifDump(*argv, STID_CANT_PRTGIF_OFPP_TILED_PAGE);
450             } else {
451                fprintf(stderr, "\n");
452             }
453          }
454       }
455    }
456    if (PRTGIF && !cmdLineOpenDisplay) CleanUpFonts();
457    CleanUpPage();
458    CleanUpResiduals();
459    CleanUpPatFill();
460    CleanUpStrTable();
461 }
462 
463 /*
464  * static
465  * void Prompt2 (PromptStr, OpName, FileName)
466  *    char	* PromptStr, * OpName, * FileName;
467  * {
468  *    char	inbuf[80];
469  *
470  *    printf (PromptStr);
471  *    fgets (inbuf, 80, stdin);
472  *    sscanf (inbuf, "%s%s", OpName, FileName);
473  * }
474  *
475  * static
476  * void Prompt3 (PromptStr, AttrName, ColorName, ValName)
477  *    char	* PromptStr, * AttrName, * ColorName, * ValName;
478  * {
479  *    char	inbuf[80];
480  *
481  *    printf (PromptStr);
482  *    fgets (inbuf, 80, stdin);
483  *    sscanf (inbuf, "%s%s%s", AttrName, ColorName, ValName);
484  * }
485  */
486 
487 static
DoTgif(argc,argv)488 void DoTgif(argc, argv)
489    int argc;
490    char *argv[];
491    /* All these strangeness with strings are related to */
492    /*    Prolog's foreign function interface. */
493 {
494 /*
495  * register int i;
496  */
497    char op_name[80], file_name[(MAXPATHLENGTH<<1)+1];
498    char *sp[6], *func_strp;
499 /*
500  * char	color_name[80], val_name[80];
501  * char	attr_name[80], speed_name[80], id_name[80];
502  */
503 
504    if (!ProcessTgifOptions(argc, argv, file_name, sizeof(file_name))) return;
505 
506    if (file_name[0] == '\0') {
507       /* do not translate -- program constants */
508       MainLoop("init", "", &func_strp,
509             &sp[0], &sp[1], &sp[2], &sp[3], &sp[4], &sp[5]);
510    } else {
511       /* do not translate -- program constants */
512       MainLoop("init", file_name, &func_strp,
513             &sp[0], &sp[1], &sp[2], &sp[3], &sp[4], &sp[5]);
514    }
515 /*
516  * for (i = 0; i < 6; i++)
517  *    if (strcmp (sp[i], "") != 0)
518  *       printf ("%s ", sp[i]);
519  *    else
520  *       break;
521  * printf ("\n");
522  */
523 
524    while (TRUE) {
525       char s[80];
526 
527       strcpy(s, func_strp);
528       s[4] = '\0';
529 
530       DeallocStrings(&func_strp,&sp[0],&sp[1],&sp[2],&sp[3],&sp[4],&sp[5]);
531 
532       /* do not translate -- program constants */
533       if (strcmp(s, "Quit") == 0) {
534          *file_name = '\0';
535          MainLoop("quit", file_name, &func_strp,
536                &sp[0], &sp[1], &sp[2], &sp[3], &sp[4], &sp[5]);
537          DeallocStrings(&func_strp,&sp[0],&sp[1],&sp[2],&sp[3],&sp[4],&sp[5]);
538          break;
539       }
540 
541       Msg(TgLoadCachedString(CSTID_RETURNED_FROM_BASIC_DRIVER));
542 /*
543  *    Prompt2("Input an operation and a sub command.\n",op_name,file_name);
544  *
545  *    if (strcmp(op_name, "animate") == 0)
546  *    {
547  *       Prompt3("Input poly_id, speed, color.\n", id_name, speed_name,
548  *             color_name);
549  *       Animate(file_name, id_name, speed_name, color_name, &func_strp);
550  *       printf("Animate RETURNs --> %s %s %s\n", func_strp, sp[0], sp[1]);
551  *    }
552  *    if (strcmp(op_name, "upd_attr_val") == 0)
553  *    {
554  *       Prompt3("Input attrname, color and value.\n", attr_name, color_name,
555  *             val_name);
556  *       UpdAttrVal(file_name, attr_name, color_name, val_name, &func_strp);
557  *       printf("UpdAttrVal RETURNs --> %s %s %s\n", func_strp, sp[0], sp[1]);
558  *    }
559  */
560       *op_name = *file_name = '\0';
561       MainLoop(op_name, file_name, &func_strp,
562             &sp[0], &sp[1], &sp[2], &sp[3], &sp[4], &sp[5]);
563 /*
564  *    printf("RETURN --> %s ", func_strp);
565  *    for (i = 0; i < 6; i++)
566  *       if (strcmp(sp[i], "") != 0)
567  *          printf("%s ", sp[i]);
568  *       else
569  *          break;
570  *    printf("\n");
571  */
572    }
573 }
574 
main(argc,argv)575 int main(argc, argv)
576    int argc;
577    char *argv[];
578 {
579    register int i, from_prtgif;
580 
581    origArgC = argc;
582    origArgV = argv;
583 
584    PRTGIF = FALSE;
585    from_prtgif = FALSE;
586    SetProgramName(*argv);
587    for (i = 1; i < argc; i++) {
588       /* do not translate -- program constants */
589       if (strcmp(argv[i], "-prtgif")==0) {
590          PRTGIF = TRUE;
591          from_prtgif = TRUE;
592          break;
593       } else if ((strcmp(argv[i], "-print")==0) ||
594             (strcmp(argv[i], "-PRINT")==0)) {
595          PRTGIF = TRUE;
596          break;
597       }
598    }
599 /*
600  * malloc_debug (1);
601  */
602    if (PRTGIF) {
603       DoPrTgif(argc, argv, from_prtgif);
604    } else {
605       DoTgif(argc, argv);
606    }
607    return 0;
608 }
609