00001 #include <stdio.h>
00002 #include <stdarg.h>
00003 #include <string.h>
00004 #include <math.h>
00005
00006 #include "potracelib.h"
00007 #include "curve.h"
00008 #include "main.h"
00009 #include "backend_hpgl.h"
00010 #include "lists.h"
00011 #include "auxiliary.h"
00012
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #endif
00016
00017
00018
00019
00020
00021 static inline point_t unit(dpoint_t p) {
00022 point_t q;
00023
00024 q.x = (long)(floor(p.x*info.unit+.5));
00025 q.y = (long)(floor(p.y*info.unit+.5));
00026 return q;
00027 }
00028
00029 static point_t cur;
00030 static char lastop = 0;
00031 static int column = 0;
00032 static int newline = 1;
00033
00034 static void shiptoken(FILE *fout, char *token) {
00035 int c = strlen(token);
00036 if (!newline && column+c+1 > 75) {
00037
00038 column = 0;
00039 newline = 1;
00040 } else if (!newline) {
00041
00042 column++;
00043 }
00044 fprintf(fout, "%s", token);
00045 column += c;
00046 newline = 0;
00047 }
00048
00049 static void ship(FILE *fout, char *fmt, ...) {
00050 va_list args;
00051 static char buf[4096];
00052
00053
00054
00055 char *p, *q;
00056
00057 va_start(args, fmt);
00058 vsprintf(buf, fmt, args);
00059 buf[4095] = 0;
00060 va_end(args);
00061
00062 p = buf;
00063 while ((q = strchr(p, ' ')) != NULL) {
00064 *q = 0;
00065 shiptoken(fout, p);
00066 p = q+1;
00067 }
00068 shiptoken(fout, p);
00069 }
00070
00071 static void hpgl_moveto(FILE *fout, dpoint_t p) {
00072 cur = unit(p);
00073
00074 ship(fout, "PU;PA%ld,%ld;", cur.x, cur.y);
00075 lastop = 'M';
00076 }
00077
00078 static void hpgl_rmoveto(FILE *fout, dpoint_t p) {
00079 point_t q;
00080
00081 q = unit(p);
00082 ship(fout, "PU;PR%ld,%ld;", q.x-cur.x, q.y-cur.y);
00083 cur = q;
00084 lastop = 'm';
00085 }
00086
00087 static void hpgl_lineto(FILE *fout, dpoint_t p) {
00088 point_t q;
00089
00090 q = unit(p);
00091
00092 if (lastop != 'l') {
00093 ship(fout, "PR;PD%ld,%ld", q.x-cur.x, q.y-cur.y);
00094 } else {
00095 ship(fout, ",%ld,%ld", q.x-cur.x, q.y-cur.y);
00096 }
00097 cur = q;
00098 lastop = 'l';
00099 }
00100
00101
00102 static int hpgl_draw_path(FILE *fout, point_t *pt, int n, int abs, int subpoly) {
00103 int i;
00104 point_t cur, prev;
00105
00106 if (subpoly == 1) {
00107 ship(fout, ";PM1;");
00108
00109 }
00110
00111 if (abs) {
00112 cur = prev = pt[n-1];
00113 hpgl_moveto(fout, dpoint(cur));
00114 for (i=0; i<n; i++) {
00115 if (pt[i].x != cur.x && pt[i].y != cur.y) {
00116 cur = prev;
00117 hpgl_lineto(fout, dpoint(cur));
00118 }
00119 prev = pt[i];
00120 }
00121 hpgl_lineto(fout, dpoint(pt[n-1]));
00122 } else {
00123 cur = prev = pt[0];
00124 hpgl_rmoveto(fout, dpoint(cur));
00125 for (i=n-1; i>=0; i--) {
00126 if (pt[i].x != cur.x && pt[i].y != cur.y) {
00127 cur = prev;
00128 hpgl_lineto(fout, dpoint(cur));
00129 }
00130 prev = pt[i];
00131 }
00132 hpgl_lineto(fout, dpoint(pt[0]));
00133 }
00134 newline = 1;
00135
00136 return 0;
00137 }
00138
00139 static void write_paths_transparent(FILE *fout, potrace_path_t *tree) {
00140 potrace_path_t *p, *q;
00141 int c;
00142
00143 for (p=tree; p; p=p->sibling) {
00144 c = fprintf(fout, "PM0;");
00145 column = c;
00146 newline = 1;
00147 lastop = 0;
00148
00149 hpgl_draw_path(fout, p->priv->pt, p->priv->len, 1, 0);
00150
00151 for (q=p->childlist; q; q=q->sibling) {
00152
00153 hpgl_draw_path(fout, q->priv->pt, q->priv->len, 0, 1);
00154
00155 }
00156 fprintf(fout, ";PM2;FP;EP;\n");
00157
00158 for (q=p->childlist; q; q=q->sibling) {
00159 write_paths_transparent(fout, q->childlist);
00160 }
00161 }
00162 }
00163
00164 static void write_paths_opaque(FILE *fout, potrace_path_t *tree) {
00165 return write_paths_transparent(fout, tree);
00166 }
00167
00168
00169
00170
00171
00172 int page_hpgl(FILE *fout, potrace_path_t *plist, imginfo_t *imginfo) {
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 fprintf(fout, "IN;\n");
00211
00212 if (info.opaque) {
00213 write_paths_opaque(fout, plist);
00214 } else {
00215 write_paths_transparent(fout, plist);
00216 }
00217
00218
00219
00220
00221 fflush(fout);
00222
00223 return 0;
00224 }
00225