Graphviz  2.41.20170921.2350
gvrender_core_mif.c
Go to the documentation of this file.
1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 /* FIXME - incomplete replacement for codegen */
15 
16 #include "config.h"
17 
18 #include <stdarg.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <ctype.h>
22 
23 #include "macros.h"
24 #include "const.h"
25 
26 #include "gvio.h"
27 #include "gvplugin_render.h"
28 #include "gvplugin_device.h"
29 #include "gvcint.h"
30 
31 typedef enum { FORMAT_MIF, } format_type;
32 
33 /* MIF font modifiers */
34 #define REGULAR 0
35 #define BOLD 1
36 #define ITALIC 2
37 
38 /* MIF patterns */
39 #define P_SOLID 0
40 #define P_NONE 15
41 #define P_DOTTED 4 /* i wasn't sure about this */
42 #define P_DASHED 11 /* or this */
43 
44 /* MIF bold line constant */
45 #define WIDTH_NORMAL 1
46 #define WIDTH_BOLD 3
47 
48 static char *FillStr = "<Fill 3>";
49 static char *NoFillStr = "<Fill 15>";
50 
51 static void mif_ptarray(GVJ_t * job, pointf * A, int n)
52 {
53  int i;
54 
55  gvprintf(job, " <NumPoints %d>\n", n);
56  for (i = 0; i < n; i++)
57  gvprintf(job, " <Point %.2f %.2f>\n", A[i].x, A[i].y);
58 }
59 
60 typedef struct {
61  char *name;
62  int CMYK[4];
63 } mif_color_t;
64 
65 static mif_color_t mif_colors[] = {
66  {"Black", {0, 0, 0, 100}},
67  {"White", {0, 0, 0, 0}},
68  {"Red", {0, 100, 100, 0}},
69  {"Green", {100, 0, 100, 0}},
70  {"Blue", {100, 100, 0, 0}},
71  {"Cyan", {100, 0, 0, 0}},
72  {"Magenta", {0, 100, 0, 0}},
73  {"Yellow", {0, 0, 100, 0}},
74  {"aquamarine", {100, 0, 0, 18}},
75  {"plum", {0, 100, 0, 33}},
76  {"peru", {0, 24, 100, 32}},
77  {"pink", {0, 50, 0, 0}},
78  {"mediumpurple", {10, 100, 0, 0}},
79  {"grey", {0, 0, 0, 50}},
80  {"lightgrey", {0, 0, 0, 25}},
81  {"lightskyblue", {38, 33, 0, 0}},
82  {"lightcoral", {0, 50, 60, 0}},
83  {"yellowgreen", {31, 0, 100, 0}},
84 };
85 
86 static void mif_color(GVJ_t * job, int i)
87 {
88  if (isupper(mif_colors[i].name[0]))
89  gvprintf(job, "<Separation %d>\n", i);
90  else
91  gvprintf(job, "<ObColor `%s'>\n", mif_colors[i].name);
92 }
93 
94 #if 0
95 static void mif_style(GVJ_t * job, int filled)
96 {
97  obj_state_t *obj = job->obj;
98 
99  gvputs(job, "style=\"fill:");
100  if (filled)
101  mif_color(job->obj->fillcolor);
102  else
103  gvputs(job, "none");
104 
105  gvputs(job, ";stroke:");
106 
107 
108 
109  while ((line = *s++)) {
110  if (streq(line, "solid"))
111  pen = P_SOLID;
112  else if (streq(line, "dashed"))
113  pen = P_DASHED;
114  else if (streq(line, "dotted"))
115  pen = P_DOTTED;
116  else if (streq(line, "invis"))
117  pen = P_NONE;
118  else if (streq(line, "bold"))
119  penwidth = WIDTH_BOLD;
120  else if (streq(line, "filled"))
121  fill = P_SOLID;
122  else if (streq(line, "unfilled"))
123  fill = P_NONE;
124  else {
125  agerr(AGERR,
126  "mif_style: unsupported style %s - ignoring\n",
127  line);
128  }
129  }
130 
131  fw = fa = "Regular";
132  switch (cp->fontopt) {
133  case BOLD:
134  fw = "Bold";
135  break;
136  case ITALIC:
137  fa = "Italic";
138  break;
139  }
140  gvprintf(job,
141  "<Font <FFamily `%s'> <FSize %.1f pt> <FWeight %s> <FAngle %s>>\n",
142  cp->fontfam, job->scale.x * cp->fontsz, fw, fa);
143 
144  gvprintf(job, "<Pen %d> <Fill %d> <PenWidth %d>\n",
145  job->pen, job->fill, job->penwidth);
146 }
147 #endif
148 
149 static void mif_comment(GVJ_t * job, char *str)
150 {
151  gvprintf(job, "# %s\n", str);
152 }
153 
154 static void mif_color_declaration(GVJ_t * job, char *str, int CMYK[4])
155 {
156  gvputs(job, " <Color \n");
157  gvprintf(job, " <ColorTag `%s'>\n", str);
158  gvprintf(job, " <ColorCyan %d.000000>\n", CMYK[0]);
159  gvprintf(job, " <ColorMagenta %d.000000>\n", CMYK[1]);
160  gvprintf(job, " <ColorYellow %d.000000>\n", CMYK[2]);
161  gvprintf(job, " <ColorBlack %d.000000>\n", CMYK[3]);
162  if (isupper(str[0])) {
163  gvprintf(job, " <ColorAttribute ColorIs%s>\n", str);
164  gvputs(job, " <ColorAttribute ColorIsReserved>\n");
165  }
166  gvputs(job, " > # end of Color\n");
167 }
168 
169 static void
170 mif_begin_job(GVJ_t * job)
171 {
172  gvprintf(job,
173  "<MIFFile 3.00> # Generated by %s version %s (%s)\n",
174  job->common->info[0], job->common->info[1], job->common->info[2]);
175 }
176 
177 static void mif_end_job(GVJ_t * job)
178 {
179  gvputs(job, "# end of MIFFile\n");
180 }
181 
182 static void mif_begin_graph(GVJ_t * job)
183 {
184  int i;
185 
186  gvprintf(job, "# Title: %s\n", job->obj->u.g->name);
187  gvprintf(job, "# Pages: %d\n",
188  job->pagesArraySize.x * job->pagesArraySize.y);
189  gvputs(job, "<Units Upt>\n");
190  gvputs(job, "<ColorCatalog \n");
191  for (i = 0; i < (sizeof(mif_colors) / sizeof(mif_color_t)); i++)
192  mif_color_declaration(job, mif_colors[i].name, mif_colors[i].CMYK);
193  gvputs(job, "> # end of ColorCatalog\n");
194  gvprintf(job, "<BRect %g %g %g %g>\n",
195  job->canvasBox.LL.x,
196  job->canvasBox.UR.y,
197  job->canvasBox.UR.x - job->canvasBox.LL.x,
198  job->canvasBox.UR.y - job->canvasBox.LL.y);
199 }
200 
201 static void
202 mif_begin_page(GVJ_t *job)
203 {
204  gvprintf(job,
205  " <ArrowStyle <TipAngle 15> <BaseAngle 90> <Length %.1f> <HeadType Filled>>\n",
206  14 * job->scale.x);
207 }
208 
209 static void mif_set_color(GVJ_t * job, char *name)
210 {
211  int i;
212 
213  for (i = 0; i < (sizeof(mif_colors)/sizeof(mif_color_t)); i++) {
214  if (strcasecmp(mif_colors[i].name, name) == 0)
215  mif_color(job, i);
216  }
217  agerr(AGERR, "color %s not supported in MIF\n", name);
218 }
219 
220 static char *mif_string(GVJ_t * job, char *s)
221 {
222  static char *buf = NULL;
223  static int bufsize = 0;
224  int pos = 0;
225  char *p, esc;
226 
227  if (!buf) {
228  bufsize = 64;
229  buf = malloc(bufsize);
230  }
231 
232  p = buf;
233  while (*s) {
234  if (pos > (bufsize - 8)) {
235  bufsize *= 2;
236  buf = realloc(buf, bufsize);
237  p = buf + pos;
238  }
239  esc = 0;
240  switch (*s) {
241  case '\t':
242  esc = 't';
243  break;
244  case '>':
245  case '\'':
246  case '`':
247  case '\\':
248  esc = *s;
249  break;
250  }
251  if (esc) {
252  *p++ = '\\';
253  *p++ = esc;
254  pos += 2;
255  } else {
256  *p++ = *s;
257  pos++;
258  }
259  s++;
260  }
261  *p = '\0';
262  return buf;
263 }
264 
265 static void mif_textpara(GVJ_t * job, pointf p, textpara_t * para)
266 {
267  char *anchor;
268 
269 // p.y -= para->font.size / 2 + 2;
270  switch (para->just) {
271  case 'l':
272  anchor = "Left";
273  break;
274  case 'r':
275  anchor = "Right";
276  break;
277  default:
278  case 'n':
279  anchor = "Center";
280  break;
281  }
282  gvprintf(job,
283  "<TextLine <Angle %d> <TLOrigin %.2f %.2f> <TLAlignment %s>",
284  job->rotation, p.x, p.y, anchor);
285  gvprintf(job, " <String `%s'>>\n", mif_string(job, para->str));
286 }
287 
288 static void mif_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
289  int arrow_at_end, int filled)
290 {
291  gvprintf(job,
292  "<PolyLine <Fill 15> <Smoothed Yes> <HeadCap Square>\n");
293  mif_ptarray(job, A, n);
294  gvputs(job, ">\n");
295 }
296 
297 static void mif_polygon(GVJ_t * job, pointf * A, int n, int filled)
298 {
299  gvprintf(job, "<Polygon %s\n", (filled ? FillStr : NoFillStr));
300  mif_ptarray(job, A, n);
301  gvputs(job, ">\n");
302 }
303 
304 static void mif_ellipse(GVJ_t * job, pointf * A, int filled)
305 {
306  pointf dia;
307 
308  dia.x = (A[1].x - A[0].x) * 2;
309  dia.y = (A[1].y - A[0].y) * 2;
310 
311  gvprintf(job, "<Ellipse %s <BRect %.2f %.2f %.1f %.1f>>\n",
312  filled ? FillStr : NoFillStr,
313  A[1].x - dia.x, A[1].y, dia.x, -dia.y);
314 }
315 
316 static void mif_polyline(GVJ_t * job, pointf * A, int n)
317 {
318  gvputs(job, "<PolyLine <HeadCap Square>\n");
319  mif_ptarray(job, A, n);
320  gvputs(job, ">\n");
321 }
322 
324  mif_begin_job,
325  mif_end_job,
326  mif_begin_graph,
327  0, /* mif_end_graph */
328  0, /* mif_begin_layer */
329  0, /* mif_end_layer */
330  mif_begin_page,
331  0, /* mif_end_page */
332  0, /* mif_begin_cluster */
333  0, /* mif_end_cluster */
334  0, /* mif_begin_nodes */
335  0, /* mif_end_nodes */
336  0, /* mif_begin_edges */
337  0, /* mif_end_edges */
338  0, /* mif_begin_node */
339  0, /* mif_end_node */
340  0, /* mif_begin_edge */
341  0, /* mif_end_edge */
342  0, /* mif_begin_anchor */
343  0, /* mif_end_anchor */
344  0, /* mif_begin_label */
345  0, /* mif_end_label */
346  mif_textpara,
347  0, /* mif_resolve_color */
348  mif_ellipse,
349  mif_polygon,
350  mif_bezier,
351  mif_polyline,
352  mif_comment,
353  0, /* mif_library_shape */
354 };
355 
357  GVRENDER_Y_GOES_DOWN, /* flags */
358  4., /* default pad - graph units */
359  NULL, /* knowncolors */
360  0, /* sizeof knowncolors */
361  CMYK_BYTE, /* color_type */
362 };
363 
364 static gvdevice_features_t device_features_mif = {
365  0, /* flags */
366  {0.,0.}, /* default margin - points */
367  {0.,0.}, /* default page width, height - points */
368  {72.,72.}, /* default dpi */
369 };
370 
372  {FORMAT_MIF, "mif", -1, &mif_engine, &mif_features},
373  {0, NULL, 0, NULL, NULL}
374 };
375 
377  {FORMAT_MIF, "mif:mif", -1, NULL, &device_features_mif},
378  {0, NULL, 0, NULL, NULL}
379 };
Definition: cgraph.h:388
int rotation
Definition: gvcjob.h:328
point pagesArraySize
Definition: gvcjob.h:313
Definition: geom.h:28
#define P_DOTTED
int agerr(agerrlevel_t level, const char *fmt,...)
Definition: agerror.c:141
gvplugin_installed_t gvdevice_mif_types[]
Definition: gvcjob.h:271
int x
Definition: geom.h:26
obj_state_t * obj
Definition: gvcjob.h:278
#define GVRENDER_Y_GOES_DOWN
Definition: gvcjob.h:96
int gvputs(GVJ_t *job, const char *s)
Definition: gvdevice.c:270
#define ITALIC
boxf canvasBox
Definition: gvcjob.h:331
double y
Definition: geom.h:28
#define P_SOLID
gvrender_engine_t mif_engine
#define P_NONE
pointf scale
Definition: gvcjob.h:341
GVCOMMON_t * common
Definition: gvcjob.h:276
char ** info
Definition: gvcommon.h:22
#define P_DASHED
Definition: grammar.c:79
graph_t * g
Definition: gvcjob.h:195
gvplugin_installed_t gvrender_mif_types[]
format_type
#define NULL
Definition: logic.h:39
double x
Definition: geom.h:28
#define WIDTH_BOLD
#define streq(s, t)
Definition: cghdr.h:52
int strcasecmp(const char *s1, const char *s2)
Definition: strcasecmp.c:21
#define BOLD
pointf LL
Definition: geom.h:35
union obj_state_s::@23 u
gvrender_features_t mif_features
agxbuf * str
Definition: htmlparse.c:85
gvcolor_t fillcolor
Definition: gvcjob.h:203
int y
Definition: geom.h:26
pointf UR
Definition: geom.h:35
void gvprintf(GVJ_t *job, const char *format,...)
Definition: gvdevice.c:389