/*-------------------------------------------------------------------------*/ /* */ /* HPTOMF : Konvertierung einer HPGL-Datei in eine METAFONT-Datei */ /* (c) D. Donath 1990 */ /* */ /* Das Programm HPTOMF ist "public domain". Der Autor erteilt hiermit */ /* die Erlaubnis, es zusammen mit dem Quelltext HPTOMF.C und der */ /* Dokumentation HPTOMF.DOC weiterzugeben, zu veraendern und auf andere */ /* Rechner zu uebertragen. */ /* Jegliche Garantieansprueche an den Autor sind ausgeschlossen. */ /* */ /* Autor: Dirk Donath */ /* Mitterhoferstr. 8 */ /* 7000 Stuttgart 40 */ /* */ /*-------------------------------------------------------------------------*/ #include #define TRUE 1 #define FALSE 0 void lese_befehl (void); int papr (int absolut); int pupd (int down); int ziffer (char c); void schreiben (int x1,int y1,int x2,int y2); int lesen (int *x1ptr,int *y1ptr,int *x2ptr,int *y2ptr); void ausgabe (void); const char str_ende = 0; int stift_unten = TRUE; int xalt = 0; int yalt = 0; int xmin = 30000; int xmax = 0; int ymin = 30000; int ymax = 0; int zaehler = 0; int laenge = 0; float ysoll; char hpdatei [30]; char mfdatei [30]; char *const tddatei = "HPTOMF.TMP"; char befehl [255]; FILE *hd, *td, *md; /*-------------------------------------------------------------------------*/ /* Beginn des Hauptprogramms */ /*-------------------------------------------------------------------------*/ int main (int argc, char *argv[]) { char c; int i; printf("\nHPTOMF (c) Dirk Donath 1990\n\n"); /* Auswertung der Kommandozeile: */ if (argc != 4) { printf("Aufruf: HPTOMF [HPGL-Datei] [METAFONT-Datei] [Zeichnungshoehe in mm]\n"); return(1); } sscanf(argv[1],"%s",&hpdatei); /* Param. 1 = HPGL-Datei */ sscanf(argv[2],"%s",&mfdatei); /* Param. 2 = METAFONT-Datei */ if (!sscanf(argv[3],"%d",&i)) /* Param. 3 = Zeichnungshoehe */ { printf("- Zeichnungshoehe ungueltig\n"); return(1); } ysoll = (float)i; /* Oeffnen der HPGL-Datei: */ hd = fopen(hpdatei,"r"); if (hd == NULL) { printf("- Fehler beim Oeffnen der HPGL-Datei \"%s\"\n",hpdatei); return(1); } /* Oeffnen der Temporaerdatei: */ td = fopen(tddatei,"wb"); if (td == NULL) { printf("- Fehler beim Erzeugen der Temporaerdatei \"%s\"\n",tddatei); return(1); } printf("- Lese HPGL-Datei \"%s\"\n",hpdatei); /* Befehl bis zum ';' lesen, dann das ';' ueberlesen: */ while (fscanf(hd, "%[^;] %c",&befehl,c) > 0) lese_befehl(); fclose(hd); fclose(td); ausgabe(); return(0); } /*-------------------------------------------------------------------------*/ /* Einen HPGL-Befehl verarbeiten */ /*-------------------------------------------------------------------------*/ void lese_befehl () { int i = 0; int j; /* Unerlaubte Zeichen im String beseitigen: */ while (befehl[i] != str_ende) { if (befehl[i] <= ' ') { j = i; while (befehl[j] != str_ende) { befehl[j] = befehl[j+1]; j++; } } i++; } laenge= i; /* Stringlaenge merken */ /* Befehl analysieren: */ switch (befehl[0]) { case 'P': switch (befehl[1]) { case 'A': if (!papr(TRUE)) return; break; case 'R': if (!papr(FALSE)) return; break; case 'D': if (!pupd(TRUE)) return; break; case 'U': if (!pupd(FALSE)) return; break; default : return; } default : return; } } /*-------------------------------------------------------------------------*/ /* Pruefung, ob ein Zeichen eine Ziffer ist */ /*-------------------------------------------------------------------------*/ int ziffer (char c) { if ((c == '-') || ((c >= '0') && (c <= '9'))) return(TRUE); else return(FALSE); } /*-------------------------------------------------------------------------*/ /* PA- oder PR-Befehl verarbeiten */ /*-------------------------------------------------------------------------*/ int papr (int absolut) /* Der PA- oder PR-Befehl kann aus beliebig vielen x-y-Zahlenpaaren und/oder PU- oder PD-Befehlen bestehen. Die Zahlen sind jeweils durch Komma getrennt. Beispiel: PA PD0,0,80,50,90,20PU140,30PD150,80; */ { int i,j,x,y,zahl,x_erwartet; char k[80]; /* restlichen String auswerten: */ x_erwartet = TRUE; i = 2; while(befehl[i] != str_ende) { if (ziffer(befehl[i])) { /* Ziffer gefunden: Zahl vollstaendig lesen: */ j = 0; loop: k[j] = befehl[i]; if (!(ziffer(befehl[i+1]))) goto endloop; j++; i++; goto loop; endloop: k[j+1] = str_ende; /* k enthaelt jetzt die vollstaendige Zahl */ sscanf(k,"%d",&zahl); if (x_erwartet) /* x-Koordinate erwartet: */ { if (absolut) x = zahl; else x = xalt + zahl; x_erwartet = FALSE; } else /* y-Koordinate erwartet: */ { if (absolut) y = zahl; else y = yalt + zahl; if (stift_unten) schreiben(xalt,yalt,x,y); xalt = x; yalt = y; x_erwartet = TRUE; } } else { if (befehl[i] == 'P') { i++; switch (befehl[i]) { case 'U': stift_unten = FALSE; /* integrierter PU-Befehl */ break; case 'D': stift_unten = TRUE; /* integrierter PD-Befehl */ break; default : return(FALSE); } } else { /* Komma wird ueberlesen, alles andere ist falsch: */ if (befehl[i] != ',') return(FALSE); } } i++; } return(TRUE); } /*-------------------------------------------------------------------------*/ /* PU- oder PD-Befehl verarbeiten */ /*-------------------------------------------------------------------------*/ int pupd (int down) /* Der PU- oder PD-Befehl hat optional ein x-y-Zahlenpaar als Parameter; die Zahlen sind dann durch ein Komma getrennt */ { int x,y; char c; stift_unten = down; if (laenge > 2) /* Koordinaten angegeben */ { if (sscanf(befehl,"%c %c %d %c %d",&c, &c, &x, &c,&y) != 5) return(FALSE); if (stift_unten) schreiben(xalt,yalt,x,y); xalt = x; yalt = y; } return(TRUE); } /*-------------------------------------------------------------------------*/ /* In die Temporaerdatei schreiben */ /*-------------------------------------------------------------------------*/ void schreiben (int x1, int y1, int x2, int y2) { /* Lebenszeichen auf Bildschirm: */ zaehler++; if (zaehler == 10) { putchar('.'); zaehler = 0; } /* Merken von Maximum und Minimum zur spaeteren Skalierung: */ if (x1 < xmin) xmin = x1; if (x1 > xmax) xmax = x1; if (x2 < xmin) xmin = x2; if (x2 > xmax) xmax = x2; if (y1 < ymin) ymin = y1; if (y1 > ymax) ymax = y1; if (y2 < ymin) ymin = y2; if (y2 > ymax) ymax = y2; fwrite(&x1,sizeof(int),1,td); fwrite(&y1,sizeof(int),1,td); fwrite(&x2,sizeof(int),1,td); fwrite(&y2,sizeof(int),1,td); } /*-------------------------------------------------------------------------*/ /* Aus der Temporaerdatei lesen */ /*-------------------------------------------------------------------------*/ int lesen (int *x1ptr, int *y1ptr, int *x2ptr, int *y2ptr) { /* Lebenszeichen auf Bildschirm: */ zaehler++; if (zaehler == 10) { putchar('.'); zaehler = 0; } if (!fread(x1ptr,sizeof(int),1,td)) return(FALSE); if (!fread(y1ptr,sizeof(int),1,td)) return(FALSE); if (!fread(x2ptr,sizeof(int),1,td)) return(FALSE); if (!fread(y2ptr,sizeof(int),1,td)) return(FALSE); return(TRUE); } /*-------------------------------------------------------------------------*/ /* Ausgabe in die METAFONT-Datei */ /*-------------------------------------------------------------------------*/ void ausgabe(void) { int x1,y1,x2,y2; float xmaxmm,x1mm,y1mm,x2mm,y2mm,faktor; /* Ausdehnung der Zeichnung in mm: y-Ausdehnung ist vorgegeben (=ysoll), x-Ausdehnung wird berechnet: */ xmaxmm = ysoll * (float)(xmax-xmin) / (float)(ymax-ymin); printf("\n\n- Schreibe METAFONT-Datei \"%s\"\n",mfdatei); /* Initialisierungsteil der METAFONT-Datei: */ md = fopen(mfdatei, "w"); fprintf(md,"%% METAFONT-Quelltext %s, erzeugt aus %s\n",mfdatei,hpdatei); fprintf(md,"mode_setup;\n"); fprintf(md,"beginchar(\"Z\",%4.3fmm#,%4.3fmm#,0);\n",xmaxmm,ysoll); fprintf(md,"pickup pencircle scaled 0.3mm;\n"); /* Faktor zur Transformation der Koordinaten in Millimeter: */ faktor = ysoll / ((float)(ymax-ymin)); /* Lesen der Temporaerdatei mit den gespeicherten Koordinaten: */ td = fopen(tddatei,"rb"); zaehler = 0; while (lesen(&x1,&y1,&x2,&y2)) { /* Transformation der Koordinaten in Millimeter: */ x1mm = (float)(x1-xmin) * faktor; y1mm = (float)(y1-ymin) * faktor; x2mm = (float)(x2-xmin) * faktor; y2mm = (float)(y2-ymin) * faktor; /* Schreiben in die METAFONT-Datei: */ fprintf(md,"draw (%4.3fmm,%4.3fmm)--(%4.3fmm,%4.3fmm);\n", x1mm,y1mm,x2mm,y2mm); } /* METAFONT-Datei abschliessen: */ fprintf(md,"endchar;\n"); fprintf(md,"end;\n"); fclose(md); /* Temporaerdatei schliessen und loeschen: */ fclose(td); remove(tddatei); printf("\n"); }