diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/hptomf/hptomf.c |
Initial commit
Diffstat (limited to 'support/hptomf/hptomf.c')
-rw-r--r-- | support/hptomf/hptomf.c | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/support/hptomf/hptomf.c b/support/hptomf/hptomf.c new file mode 100644 index 0000000000..fc9c9ee753 --- /dev/null +++ b/support/hptomf/hptomf.c @@ -0,0 +1,380 @@ +/*-------------------------------------------------------------------------*/ +/* */ +/* 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 <stdio.h> + +#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"); +} |