summaryrefslogtreecommitdiff
path: root/support/hptomf/hptomf.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/hptomf/hptomf.c
Initial commit
Diffstat (limited to 'support/hptomf/hptomf.c')
-rw-r--r--support/hptomf/hptomf.c380
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");
+}