00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "render.h"
00021 #ifndef WIN32
00022 #include <unistd.h>
00023 #endif
00024 #include <sys/stat.h>
00025
00026
00027 #define NONE 0
00028 #define NODE 1
00029 #define EDGE 2
00030 #define CLST 3
00031
00032
00033
00034 static int onetime = TRUE;
00035
00036 static char **U_lib;
00037
00038 typedef struct grcontext_t {
00039 char *color, *font;
00040 double size;
00041 } grcontext_t;
00042
00043 #define STACKSIZE 32
00044 static grcontext_t S[STACKSIZE];
00045 static int SP = 0;
00046
00047 static void mp_reset(void)
00048 {
00049 onetime = TRUE;
00050 }
00051
00052 static void
00053 mp_begin_job(FILE * ofp, graph_t * g, char **lib, char *user, char *info[],
00054 point pages)
00055 {
00056
00057
00058 U_lib = lib;
00059
00060
00061
00062 fprintf(Output_file, "%%--- graphviz MetaPost input\n");
00063 fprintf(Output_file, "%% Created by program: %s version %s (%s)\n",
00064 info[0], info[1], info[2]);
00065 fprintf(Output_file, "%% For user: %s\n", user);
00066 fprintf(Output_file, "%% Title: %s\n", g->name);
00067 fprintf(Output_file,
00068 "%% Put this between beginfig and endfig. See 1st_read.mp.\n");
00069 fprintf(Output_file, "%% \n");
00070 }
00071
00072 static void mp_end_job(void)
00073 {
00074 fprintf(Output_file, "%% End of graphviz MetaPost input\n");
00075 fprintf(Output_file, "%% \n");
00076 }
00077
00078 static void mp_comment(char *str)
00079 {
00080 fprintf(Output_file, "%% %s\n", str);
00081 }
00082
00083 static void mp_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb)
00084 {
00085
00086 static char *mp_lib[] = {0};
00087 if (onetime) {
00088 fprintf(Output_file, "%% BoundingBox: %d %d %d %d\n",
00089 bb.LL.x, bb.LL.y, bb.UR.x + 1, bb.UR.y + 1);
00090 cat_libfile(Output_file,U_lib,mp_lib);
00091 onetime = FALSE;
00092 }
00093 }
00094
00095 static void
00096 mp_begin_page(graph_t * g, point page, double scale, int rot, point offset)
00097 {
00098 assert(SP == 0);
00099 S[SP].font = "";
00100 S[SP].color = "black";
00101 S[SP].size = 0.0;
00102 }
00103
00104 static void mp_begin_context(void)
00105 {
00106 if (SP == STACKSIZE - 1)
00107 agerr(AGWARN, "mpgen stack overflow\n");
00108 else {
00109 SP++;
00110 S[SP] = S[SP - 1];
00111 }
00112 }
00113
00114 static void mp_end_context(void)
00115 {
00116 if (SP == 0)
00117 agerr(AGWARN, "mpgen stack underflow\n");
00118 else
00119 SP--;
00120 }
00121
00122 static void mp_set_font(char *name, double size)
00123 {
00124 if (strcmp(S[SP].font, name) || (size != S[SP].size)) {
00125 fprintf(Output_file, "%% GV set font: %.2f /%s ignored\n", size,
00126 name);
00127 S[SP].font = name;
00128 S[SP].size = size;
00129 }
00130 }
00131
00132 static void mp_set_color(char *name)
00133 {
00134 static char *op[] = { "graph", "node", "edge", "sethsb" };
00135 gvcolor_t color;
00136
00137 if (strcmp(name, S[SP].color)) {
00138 colorxlate(name, &color, HSVA_DOUBLE);
00139 fprintf(Output_file, "%% GV set color: %.3f %.3f %.3f %scolor\n",
00140 color.u.HSVA[0], color.u.HSVA[1], color.u.HSVA[2], op[Obj]);
00141 }
00142 S[SP].color = name;
00143 }
00144
00145 static void mp_set_style(char **s)
00146 {
00147 char *line, *p;
00148
00149 while ((p = line = *s++)) {
00150 while (*p)
00151 p++;
00152 p++;
00153 while (*p) {
00154 fprintf(Output_file, "%% GV set style: %s \n", p);
00155 while (*p)
00156 p++;
00157 p++;
00158 }
00159 fprintf(Output_file, "%% GV set style:: %s\n", line);
00160 }
00161 }
00162
00163 static char *mp_string(char *s)
00164 {
00165 static char *buf = NULL;
00166 static int bufsize = 0;
00167 int pos = 0;
00168 char *p;
00169
00170 if (!buf) {
00171 bufsize = 64;
00172 buf = N_GNEW(bufsize, char);
00173 }
00174
00175 p = buf;
00176 while (*s) {
00177 if (pos > (bufsize - 8)) {
00178 bufsize *= 2;
00179 buf = grealloc(buf, bufsize);
00180 p = buf + pos;
00181 }
00182 if ((*s == LPAREN) || (*s == RPAREN)) {
00183 *p++ = '\\';
00184 pos++;
00185 }
00186 *p++ = *s++;
00187 pos++;
00188 }
00189 *p = '\0';
00190 return buf;
00191 }
00192
00193 static void mp_textpara(point p, textpara_t * para)
00194 {
00195 fprintf(Output_file, "label(btex %s etex,(%dbp,%dbp)) withcolor %s;\n",
00196 mp_string(para->str), p.x, p.y, S[SP].color);
00197 }
00198
00199 static void
00200 mp_bezier(point * A, int n, int arrow_at_start, int arrow_at_end, int filled)
00201 {
00202 int j;
00203 if (arrow_at_start || arrow_at_end)
00204 agerr(AGERR, "mp_bezier illegal arrow args\n");
00205 fprintf(Output_file, "draw (%dbp,%dbp) ", A[0].x, A[0].y);
00206 for (j = 1; j < n; j += 3)
00207 fprintf(Output_file,
00208 "\n ..controls (%dbp,%dbp) and (%dbp,%dbp).. (%dbp,%dbp)",
00209 A[j].x, A[j].y, A[j + 1].x, A[j + 1].y, A[j + 2].x,
00210 A[j + 2].y);
00211 fprintf(Output_file, " withcolor %s;\n", S[SP].color);
00212 }
00213
00214 static void mp_polygon(point * A, int n, int filled)
00215 {
00216 int j;
00217 if (filled) {
00218 fprintf(Output_file, " fill (%dbp,%dbp)", A[0].x, A[0].y);
00219 for (j = 1; j < n; j++)
00220 fprintf(Output_file, "\n --(%dbp,%dbp)", A[j].x, A[j].y);
00221 fprintf(Output_file, "\n --cycle withcolor %s;\n", S[SP].color);
00222 }
00223 fprintf(Output_file, "draw (%dbp,%dbp) ", A[0].x, A[0].y);
00224 for (j = 1; j < n; j++)
00225 fprintf(Output_file, "\n --(%dbp,%dbp)", A[j].x, A[j].y);
00226 fprintf(Output_file, "\n --cycle withcolor %s;\n", S[SP].color);
00227 }
00228
00229 static void mp_ellipse(point p, int rx, int ry, int filled)
00230 {
00231 if (filled)
00232 fprintf(Output_file,
00233 " fill fullcircle xscaled %dbp yscaled %dbp shifted (%dbp,%dbp) withcolor %s;\n",
00234 2 * rx, 2 * ry, p.x, p.y, S[SP].color);
00235 fprintf(Output_file,
00236 "draw fullcircle xscaled %dbp yscaled %dbp shifted (%dbp,%dbp);\n",
00237 2 * rx, 2 * ry, p.x, p.y);
00238 }
00239
00240 static void mp_polyline(point * A, int n)
00241 {
00242 int j;
00243
00244 fprintf(Output_file, "draw (%dbp,%dbp) ", A[0].x, A[0].y);
00245 for (j = 1; j < n; j++)
00246 fprintf(Output_file, "\n --(%dbp,%dbp)", A[j].x, A[j].y);
00247 fprintf(Output_file, " withcolor %s;\n", S[SP].color);
00248 }
00249
00250 static void mp_usershape(usershape_t *us, boxf b, point *A, int n, boolean filled)
00251 {
00252 int j;
00253 fprintf(Output_file, "%%GV USER SHAPE [ ");
00254 for (j = 0; j < n; j++)
00255 fprintf(Output_file, "%d %d ", A[j].x, A[j].y);
00256 fprintf(Output_file, "%d %d ", A[0].x, A[0].y);
00257 fprintf(Output_file, "] %d %s %s ignored\n", n,
00258 (filled ? "true" : "false"), us->name);
00259 }
00260
00261 codegen_t MP_CodeGen = {
00262 mp_reset,
00263 mp_begin_job, mp_end_job,
00264 mp_begin_graph, 0,
00265 mp_begin_page, 0,
00266 0, 0,
00267 0, 0,
00268 0, 0,
00269 0, 0,
00270 0, 0,
00271 0, 0,
00272 mp_begin_context, mp_end_context,
00273 0, 0,
00274 mp_set_font, mp_textpara,
00275 mp_set_color, mp_set_color, mp_set_style,
00276 mp_ellipse, mp_polygon,
00277 mp_bezier, mp_polyline,
00278 0,
00279 mp_comment,
00280 mp_usershape
00281 };