|
Graphviz
2.29.20120524.0446
|
00001 /* $Id$ $Revision$ */ 00002 /* vim:set shiftwidth=4 ts=8: */ 00003 00004 /************************************************************************* 00005 * Copyright (c) 2011 AT&T Intellectual Property 00006 * All rights reserved. This program and the accompanying materials 00007 * are made available under the terms of the Eclipse Public License v1.0 00008 * which accompanies this distribution, and is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * 00011 * Contributors: See CVS logs. Details at http://www.graphviz.org/ 00012 *************************************************************************/ 00013 00014 /* FIXME - incomplete replacement for codegen */ 00015 00016 #ifdef HAVE_CONFIG_H 00017 #include "config.h" 00018 #endif 00019 00020 #include <stdarg.h> 00021 #include <stdlib.h> 00022 #include <string.h> 00023 #include <ctype.h> 00024 00025 #include "macros.h" 00026 #include "const.h" 00027 00028 #include "gvplugin_render.h" 00029 #include "gvplugin_device.h" 00030 #include "gvio.h" 00031 #include "gvcint.h" 00032 00033 typedef enum { FORMAT_DIA, } format_type; 00034 00035 extern char *xml_string(char *str); 00036 00037 /* DIA font modifiers */ 00038 #define REGULAR 0 00039 #define BOLD 1 00040 #define ITALIC 2 00041 00042 /* DIA patterns */ 00043 #define P_SOLID 0 00044 #define P_NONE 15 00045 #define P_DOTTED 4 /* i wasn't sure about this */ 00046 #define P_DASHED 11 /* or this */ 00047 00048 /* DIA bold line constant */ 00049 #define WIDTH_NORMAL 1 00050 #define WIDTH_BOLD 3 00051 00052 #define DIA_RESOLUTION 1.0 00053 #define SCALE (DIA_RESOLUTION/15.0) 00054 00055 static double Scale; 00056 static pointf Offset; 00057 static int Rot; 00058 static box PB; 00059 static int onetime = TRUE; 00060 00061 typedef struct context_t { 00062 char *pencolor, *fillcolor, *fontfam, fontopt, font_was_set; 00063 char pen, fill, penwidth, style_was_set; 00064 double fontsz; 00065 } context_t; 00066 00067 #define MAXNEST 4 00068 static context_t cstk[MAXNEST]; 00069 static int SP; 00070 00071 #define SVG_COLORS_P 0 00072 00073 static int dia_comparestr(const void *s1, const void *s2) 00074 { 00075 return strcmp(*(char **) s1, *(char **) s2); 00076 } 00077 00078 static char *dia_resolve_color(char *name) 00079 { 00080 /* color names from http://www.w3.org/TR/SVG/types.html */ 00081 /* NB. List must be LANG_C sorted */ 00082 static char *svg_known_colors[] = { 00083 "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", 00084 "beige", "bisque", "black", "blanchedalmond", "blue", 00085 "blueviolet", "brown", "burlywood", 00086 "cadetblue", "chartreuse", "chocolate", "coral", 00087 "cornflowerblue", "cornsilk", "crimson", "cyan", 00088 "darkblue", "darkcyan", "darkgoldenrod", "darkgray", 00089 "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", 00090 "darkolivegreen", "darkorange", "darkorchid", "darkred", 00091 "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", 00092 "darkslategrey", "darkturquoise", "darkviolet", "deeppink", 00093 "deepskyblue", "dimgray", "dimgrey", "dodgerblue", 00094 "firebrick", "floralwhite", "forestgreen", "fuchsia", 00095 "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", 00096 "green", "greenyellow", "grey", 00097 "honeydew", "hotpink", "indianred", 00098 "indigo", "ivory", "khaki", 00099 "lavender", "lavenderblush", "lawngreen", "lemonchiffon", 00100 "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", 00101 "lightgray", "lightgreen", "lightgrey", "lightpink", 00102 "lightsalmon", "lightseagreen", "lightskyblue", 00103 "lightslategray", "lightslategrey", "lightsteelblue", 00104 "lightyellow", "lime", "limegreen", "linen", 00105 "magenta", "maroon", "mediumaquamarine", "mediumblue", 00106 "mediumorchid", "mediumpurple", "mediumseagreen", 00107 "mediumslateblue", "mediumspringgreen", "mediumturquoise", 00108 "mediumvioletred", "midnightblue", "mintcream", 00109 "mistyrose", "moccasin", 00110 "navajowhite", "navy", "oldlace", 00111 "olive", "olivedrab", "orange", "orangered", "orchid", 00112 "palegoldenrod", "palegreen", "paleturquoise", 00113 "palevioletred", "papayawhip", "peachpuff", "peru", "pink", 00114 "plum", "powderblue", "purple", 00115 "red", "rosybrown", "royalblue", 00116 "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", 00117 "sienna", "silver", "skyblue", "slateblue", "slategray", 00118 "slategrey", "snow", "springgreen", "steelblue", 00119 "tan", "teal", "thistle", "tomato", "turquoise", 00120 "violet", 00121 "wheat", "white", "whitesmoke", 00122 "yellow", "yellowgreen", 00123 }; 00124 00125 static char buf[SMALLBUF]; 00126 char *tok; 00127 gvcolor_t color; 00128 00129 // tok = canontoken(name); 00130 tok = name; 00131 if (!SVG_COLORS_P || (bsearch(&tok, svg_known_colors, 00132 sizeof(svg_known_colors) / sizeof(char *), 00133 sizeof(char *), dia_comparestr) == NULL)) { 00134 /* if tok was not found in known_colors */ 00135 if (streq(tok, "transparent")) { 00136 tok = "none"; 00137 } else { 00138 // colorxlate(name, &color, RGBA_BYTE); 00139 sprintf(buf, "#%02x%02x%02x", 00140 color.u.rgba[0], color.u.rgba[1], color.u.rgba[2]); 00141 tok = buf; 00142 } 00143 } 00144 return tok; 00145 } 00146 00147 00148 static void dia_reset(void) 00149 { 00150 onetime = TRUE; 00151 } 00152 00153 00154 static void init_dia(void) 00155 { 00156 SP = 0; 00157 cstk[0].pencolor = DEFAULT_COLOR; /* DIA pencolor */ 00158 cstk[0].fillcolor = ""; /* DIA fillcolor */ 00159 cstk[0].fontfam = DEFAULT_FONTNAME; /* font family name */ 00160 cstk[0].fontsz = DEFAULT_FONTSIZE; /* font size */ 00161 cstk[0].fontopt = REGULAR; /* modifier: REGULAR, BOLD or ITALIC */ 00162 cstk[0].pen = P_SOLID; /* pen pattern style, default is solid */ 00163 cstk[0].fill = P_NONE; 00164 cstk[0].penwidth = WIDTH_NORMAL; 00165 } 00166 00167 static pointf dia_pt(pointf p) 00168 { 00169 pointf rv; 00170 00171 if (Rot == 0) { 00172 rv.x = PB.LL.x + p.x * Scale + Offset.x; 00173 rv.y = PB.UR.y - 1 - p.y * Scale - Offset.y; 00174 } else { 00175 rv.x = PB.UR.x - 1 - p.y * Scale - Offset.x; 00176 rv.y = PB.UR.y - 1 - p.x * Scale - Offset.y; 00177 } 00178 return rv; 00179 } 00180 00181 static void dia_style(GVJ_t * job, context_t * cp) 00182 { 00183 if (cp->pencolor != DEFAULT_COLOR) { 00184 gvputs(job, " <dia:attribute name=\"border_color\">\n"); 00185 gvprintf(job, " <dia:color val=\"%s\"/>\n", 00186 dia_resolve_color(cp->pencolor)); 00187 gvputs(job, " </dia:attribute>\n"); 00188 } 00189 if (cp->penwidth != WIDTH_NORMAL) { 00190 gvputs(job, " <dia:attribute name=\"line_width\">\n"); 00191 gvprintf(job, " <dia:real val=\"%g\"/>\n", 00192 Scale * (cp->penwidth)); 00193 gvputs(job, " </dia:attribute>\n"); 00194 } 00195 if (cp->pen == P_DASHED) { 00196 gvputs(job, " <dia:attribute name=\"line_style\">\n"); 00197 gvprintf(job, " <dia:real val=\"%d\"/>\n", 1); 00198 gvputs(job, " </dia:attribute>\n"); 00199 #if 0 00200 } else if (cp->pen == P_DOTTED) { 00201 gvprintf(job, "stroke-dasharray:%s;", sdotarray); 00202 #endif 00203 } 00204 } 00205 00206 static void dia_stylefill(GVJ_t * job, context_t * cp, int filled) 00207 { 00208 if (filled) { 00209 gvputs(job, " <dia:attribute name=\"inner_color\">\n"); 00210 gvprintf(job, " <dia:color val=\"%s\"/>\n", 00211 dia_resolve_color(cp->fillcolor)); 00212 gvputs(job, " </dia:attribute>\n"); 00213 } else { 00214 gvputs(job, " <dia:attribute name=\"show_background\">\n"); 00215 gvprintf(job, " <dia:boolean val=\"%s\"/>\n", "true"); 00216 gvputs(job, " </dia:attribute>\n"); 00217 } 00218 } 00219 00220 static void dia_comment(GVJ_t * job, char *str) 00221 { 00222 gvputs(job, "<!-- "); 00223 gvputs(job, xml_string(str)); 00224 gvputs(job, " -->\n"); 00225 } 00226 00227 static void 00228 dia_begin_job(GVJ_t *job) 00229 { 00230 gvprintf(job, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 00231 } 00232 00233 static void dia_end_job(GVJ_t *job) 00234 { 00235 } 00236 00237 static void dia_begin_graph(GVJ_t * job) 00238 { 00239 gvprintf(job, "<dia:diagram xmlns:dia=\"http://www.lysator.liu.se/~alla/dia/\">\n"); 00240 #if 0 00241 Rootgraph = g; 00242 PB.LL.x = PB.LL.y = 0; 00243 PB.UR.x = (bb.UR.x - bb.LL.x + 2 * GD_drawing(g)->margin.x) * SCALE; 00244 PB.UR.y = (bb.UR.y - bb.LL.y + 2 * GD_drawing(g)->margin.y) * SCALE; 00245 Offset.x = GD_drawing(g)->margin.x * SCALE; 00246 Offset.y = GD_drawing(g)->margin.y * SCALE; 00247 if (onetime) { 00248 init_dia(); 00249 onetime = FALSE; 00250 } 00251 #endif 00252 gvputs(job, " <dia:diagramdata>\n"); 00253 00254 gvputs(job, " <dia:attribute name=\"background\">\n"); 00255 gvputs(job, " <dia:color val=\"#ffffff\"/>\n"); 00256 gvputs(job, " </dia:attribute>\n"); 00257 00258 gvputs(job, " <dia:attribute name=\"paper\">\n"); 00259 gvputs(job, " <dia:composite type=\"paper\">\n"); 00260 gvputs(job, " <dia:attribute name=\"name\">\n"); 00261 gvputs(job, " <dia:string>#A4#</dia:string>\n"); 00262 gvputs(job, " </dia:attribute>\n"); 00263 gvputs(job, " <dia:attribute name=\"tmargin\">\n"); 00264 gvputs(job, " <dia:real val=\"2.8222\"/>\n"); 00265 gvputs(job, " </dia:attribute>\n"); 00266 gvputs(job, " <dia:attribute name=\"bmargin\">\n"); 00267 gvputs(job, " <dia:real val=\"2.8222\"/>\n"); 00268 gvputs(job, " </dia:attribute>\n"); 00269 gvputs(job, " <dia:attribute name=\"lmargin\">\n"); 00270 gvputs(job, " <dia:real val=\"2.8222\"/>\n"); 00271 gvputs(job, " </dia:attribute>\n"); 00272 gvputs(job, " <dia:attribute name=\"rmargin\">\n"); 00273 gvputs(job, " <dia:real val=\"2.8222\"/>\n"); 00274 gvputs(job, " </dia:attribute>\n"); 00275 gvputs(job, " <dia:attribute name=\"is_portrait\">\n"); 00276 gvputs(job, " <dia:boolean val=\"true\"/>\n"); 00277 gvputs(job, " </dia:attribute>\n"); 00278 gvputs(job, " <dia:attribute name=\"scaling\">\n"); 00279 gvputs(job, " <dia:real val=\"1\"/>\n"); 00280 gvputs(job, " </dia:attribute>\n"); 00281 gvputs(job, " <dia:attribute name=\"fitto\">\n"); 00282 gvputs(job, " <dia:boolean val=\"false\"/>\n"); 00283 gvputs(job, " </dia:attribute>\n"); 00284 gvputs(job, " </dia:composite>\n"); 00285 gvputs(job, " </dia:attribute>\n"); 00286 00287 gvputs(job, " <dia:attribute name=\"grid\">\n"); 00288 gvputs(job, " <dia:composite type=\"grid\">\n"); 00289 gvputs(job, " <dia:attribute name=\"width_x\">\n"); 00290 gvputs(job, " <dia:real val=\"1\"/>\n"); 00291 gvputs(job, " </dia:attribute>\n"); 00292 gvputs(job, " <dia:attribute name=\"width_y\">\n"); 00293 gvputs(job, " <dia:real val=\"1\"/>\n"); 00294 gvputs(job, " </dia:attribute>\n"); 00295 gvputs(job, " <dia:attribute name=\"visible_x\">\n"); 00296 gvputs(job, " <dia:int val=\"1\"/>\n"); 00297 gvputs(job, " </dia:attribute>\n"); 00298 gvputs(job, " <dia:attribute name=\"visible_y\">\n"); 00299 gvputs(job, " <dia:int val=\"1\"/>\n"); 00300 gvputs(job, " </dia:attribute>\n"); 00301 gvputs(job, " </dia:composite>\n"); 00302 gvputs(job, " </dia:attribute>\n"); 00303 00304 gvputs(job, " <dia:attribute name=\"guides\">\n"); 00305 gvputs(job, " <dia:composite type=\"guides\">\n"); 00306 gvputs(job, " <dia:attribute name=\"hguides\"/>\n"); 00307 gvputs(job, " <dia:attribute name=\"vguides\"/>\n"); 00308 gvputs(job, " </dia:composite>\n"); 00309 gvputs(job, " </dia:attribute>\n"); 00310 00311 gvputs(job, " </dia:diagramdata>\n"); 00312 } 00313 00314 static void dia_end_graph(GVJ_t * job) 00315 { 00316 gvprintf(job, "</dia:diagram>\n"); 00317 } 00318 00319 static void 00320 dia_begin_page(GVJ_t * job) 00321 { 00322 gvprintf(job, " <dia:layer name=\"Background\" visible=\"true\">\n"); 00323 } 00324 00325 static void dia_end_page(GVJ_t * job) 00326 { 00327 gvputs(job, " </dia:layer>\n"); 00328 } 00329 00330 static void dia_begin_cluster(GVJ_t * job) 00331 { 00332 // obj_state_t *obj = job->obj; 00333 00334 gvprintf(job, " <dia:group>\n"); 00335 } 00336 00337 static void dia_end_cluster(GVJ_t * job) 00338 { 00339 gvprintf(job, " </dia:group>\n"); 00340 } 00341 00342 static void dia_begin_node(GVJ_t * job) 00343 { 00344 gvprintf(job, " <dia:group>\n"); 00345 } 00346 00347 static void dia_end_node(GVJ_t * job) 00348 { 00349 gvprintf(job, " </dia:group>\n"); 00350 } 00351 00352 static void dia_begin_edge(GVJ_t * job) 00353 { 00354 gvprintf(job, " <dia:group>\n"); 00355 } 00356 00357 static void dia_end_edge(GVJ_t * job) 00358 { 00359 gvprintf(job, " </dia:group>\n"); 00360 } 00361 00362 static void dia_begin_context(void) 00363 { 00364 assert(SP + 1 < MAXNEST); 00365 cstk[SP + 1] = cstk[SP]; 00366 SP++; 00367 } 00368 00369 static void dia_end_context(void) 00370 { 00371 int psp = SP - 1; 00372 assert(SP > 0); 00373 /*free(cstk[psp].fontfam); */ 00374 SP = psp; 00375 } 00376 00377 static void dia_set_font(char *name, double size) 00378 { 00379 char *p; 00380 context_t *cp; 00381 00382 cp = &(cstk[SP]); 00383 cp->font_was_set = TRUE; 00384 cp->fontsz = size; 00385 p = strdup(name); 00386 cp->fontfam = p; 00387 } 00388 00389 static void dia_set_pencolor(char *name) 00390 { 00391 cstk[SP].pencolor = name; 00392 } 00393 00394 static void dia_set_fillcolor(char *name) 00395 { 00396 cstk[SP].fillcolor = name; 00397 } 00398 00399 static void dia_set_style(char **s) 00400 { 00401 #if 0 00402 char *line, *p; 00403 context_t *cp; 00404 00405 cp = &(cstk[SP]); 00406 while ((p = line = *s++)) { 00407 if (streq(line, "solid")) 00408 cp->pen = P_SOLID; 00409 else if (streq(line, "dashed")) 00410 cp->pen = P_DASHED; 00411 else if (streq(line, "dotted")) 00412 cp->pen = P_DOTTED; 00413 else if (streq(line, "invis")) 00414 cp->pen = P_NONE; 00415 else if (streq(line, "bold")) 00416 cp->penwidth = WIDTH_BOLD; 00417 else if (streq(line, "setlinewidth")) { 00418 while (*p) 00419 p++; 00420 p++; 00421 cp->penwidth = atol(p); 00422 } else if (streq(line, "filled")) 00423 cp->fill = P_SOLID; 00424 else if (streq(line, "unfilled")) 00425 cp->fill = P_NONE; 00426 else { 00427 agwarn("dia_set_style: unsupported style %s - ignoring\n", 00428 line); 00429 } 00430 cp->style_was_set = TRUE; 00431 } 00432 /* if (cp->style_was_set) dia_style(cp); */ 00433 #endif 00434 } 00435 00436 static void dia_textpara(GVJ_t * job, pointf p, textpara_t * para) 00437 { 00438 obj_state_t *obj = job->obj; 00439 PostscriptAlias *pA; 00440 int anchor; 00441 double size; 00442 char *family=NULL, *weight=NULL, *stretch=NULL, *style=NULL; 00443 00444 switch (para->just) { 00445 case 'l': 00446 anchor = 0; 00447 break; 00448 case 'r': 00449 anchor = 2; 00450 break; 00451 default: 00452 case 'n': 00453 anchor = 1; 00454 break; 00455 } 00456 p.y += para->yoffset_centerline; 00457 00458 pA = para->postscript_alias; 00459 if (pA) { 00460 switch(GD_fontnames(job->gvc->g)) { 00461 case PSFONTS: 00462 family = pA->name; 00463 weight = pA->weight; 00464 style = pA->style; 00465 break; 00466 case SVGFONTS: 00467 family = pA->svg_font_family; 00468 weight = pA->svg_font_weight; 00469 style = pA->svg_font_style; 00470 break; 00471 default: 00472 case NATIVEFONTS: 00473 family = pA->family; 00474 weight = pA->weight; 00475 style = pA->style; 00476 break; 00477 } 00478 stretch = pA->stretch; 00479 #if 0 00480 gvprintf(job, " font-family=\"%s", family); 00481 if (pA->svg_font_family) gvprintf(job, ",%s", pA->svg_font_family); 00482 gvputs(job, "\""); 00483 if (weight) gvprintf(job, " font-weight=\"%s\"", weight); 00484 if (stretch) gvprintf(job, " font-stretch=\"%s\"", stretch); 00485 if (style) gvprintf(job, " font-style=\"%s\"", style); 00486 #endif 00487 } 00488 else 00489 family = para->fontname; 00490 size = para->fontsize; 00491 00492 #if 0 00493 switch (obj->pencolor.type) { 00494 case COLOR_STRING: 00495 if (strcasecmp(obj->pencolor.u.string, "black")) 00496 gvprintf(job, " fill=\"%s\"", obj->pencolor.u.string); 00497 break; 00498 case RGBA_BYTE: 00499 gvprintf(job, " fill=\"#%02x%02x%02x\"", 00500 obj->pencolor.u.rgba[0], obj->pencolor.u.rgba[1], obj->pencolor.u.rgba[2]); 00501 break; 00502 default: 00503 assert(0); /* internal error */ 00504 } 00505 #endif 00506 00507 gvprintf(job, 00508 " <dia:object type=\"Standard - Text\" version=\"0\" id=\"%s\">\n", 00509 "0"); 00510 gvputs(job, " <dia:attribute name=\"text\">\n"); 00511 gvputs(job, " <dia:composite type=\"text\">\n"); 00512 gvputs(job, " <dia:attribute name=\"string\">\n"); 00513 gvputs(job, " <dia:string>#"); 00514 gvputs(job, xml_string(para->str)); 00515 gvputs(job, "#</dia:string>\n"); 00516 gvputs(job, " </dia:attribute>\n"); 00517 gvputs(job, " <dia:attribute name=\"font\">\n"); 00518 gvprintf(job, " <dia:font name=\"%s\"/>\n", family); 00519 gvputs(job, " </dia:attribute>\n"); 00520 gvputs(job, " <dia:attribute name=\"height\">\n"); 00521 gvprintf(job, " <dia:real val=\"%g\"/>\n", size); 00522 gvputs(job, " </dia:attribute>\n"); 00523 gvputs(job, " <dia:attribute name=\"pos\">\n"); 00524 gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", p.x, p.y); 00525 gvputs(job, " </dia:attribute>\n"); 00526 gvputs(job, " <dia:attribute name=\"color\">\n"); 00527 #if 0 00528 gvprintf(job, " <dia:color val=\"%s\"/>\n", 00529 dia_resolve_color(cp->pencolor)); 00530 #else 00531 gvprintf(job, " <dia:color val=\"%s\"/>\n", 00532 "black"); 00533 #endif 00534 gvputs(job, " </dia:attribute>\n"); 00535 gvputs(job, " <dia:attribute name=\"alignment\">\n"); 00536 gvprintf(job, " <dia:enum val=\"%d\"/>\n", anchor); 00537 gvputs(job, " </dia:attribute>\n"); 00538 gvputs(job, " </dia:composite>\n"); 00539 gvputs(job, " </dia:attribute>\n"); 00540 gvputs(job, " <dia:attribute name=\"obj_pos\">\n"); 00541 gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", p.x, p.y); 00542 gvputs(job, " </dia:attribute>\n"); 00543 #if 0 00544 gvputs(job, " <dia:attribute name=\"obj_bb\">\n"); 00545 gvprintf(job, " <dia:rectangle val=\"%g,%g;%g,%g\"/>\n", 00546 p.x - (Scale * (para->width) / 2.), p.y - 0.4, 00547 p.x + (Scale * (para->width) / 2.), p.y + 0.4); 00548 gvputs(job, " </dia:attribute>\n"); 00549 #endif 00550 gvputs(job, " </dia:object>\n"); 00551 } 00552 00553 static void dia_ellipse(GVJ_t * job, pointf *A, int filled) 00554 { 00555 #if 0 00556 pointf cp, rp; 00557 int nodeId; 00558 00559 switch (Obj) { 00560 case NODE: 00561 nodeId = Curnode->id; 00562 break; 00563 default: 00564 nodeId = -1; 00565 break; 00566 } 00567 00568 if (cstk[SP].pen == P_NONE) { 00569 /* its invisible, don't draw */ 00570 return; 00571 } 00572 cp = dia_pt(p); 00573 00574 if (Rot) { 00575 int t; 00576 t = rx; 00577 rx = ry; 00578 ry = t; 00579 } 00580 rp.x = Scale * rx; 00581 rp.y = Scale * ry; 00582 00583 gvprintf(job, 00584 " <dia:object type=\"Standard - Ellipse\" version=\"0\" id=\"%d\">\n", 00585 nodeId); 00586 gvputs(job, " <dia:attribute name=\"elem_corner\">\n"); 00587 gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", cp.x - rp.x, 00588 cp.y - rp.y); 00589 gvputs(job, " </dia:attribute>\n"); 00590 gvputs(job, " <dia:attribute name=\"elem_width\">\n"); 00591 gvprintf(job, " <dia:real val=\"%g\"/>\n", rp.x + rp.x); 00592 gvputs(job, " </dia:attribute>\n"); 00593 gvputs(job, " <dia:attribute name=\"elem_height\">\n"); 00594 gvprintf(job, " <dia:real val=\"%g\"/>\n", rp.y + rp.y); 00595 gvputs(job, " </dia:attribute>\n"); 00596 gvputs(job, " <dia:attribute name=\"obj_pos\">\n"); 00597 gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", cp.x - rp.x, 00598 cp.y - rp.y); 00599 gvputs(job, " </dia:attribute>\n"); 00600 gvputs(job, " <dia:attribute name=\"obj_bb\">\n"); 00601 gvprintf(job, " <dia:rectangle val=\"%g,%g;%g,%g\"/>\n", 00602 cp.x - rp.x - .11, cp.y - rp.y - .11, cp.x + rp.x + .11, 00603 cp.y + rp.y + .11); 00604 gvputs(job, " </dia:attribute>\n"); 00605 dia_style(job, &cstk[SP]); 00606 dia_stylefill(job, &cstk[SP], filled); 00607 gvputs(job, " </dia:object>\n"); 00608 #endif 00609 } 00610 00611 00612 int ellipse_connection(pointf cp, pointf p) 00613 { 00614 int conn = 0; 00615 #if 0 00616 if (cp.x == p.x) { 00617 if (cp.y > p.y) 00618 conn = 1; 00619 else 00620 conn = 6; 00621 } else if (cp.y == p.y) { 00622 if (cp.x > p.x) 00623 conn = 3; 00624 else 00625 conn = 4; 00626 } else if (cp.x < p.x) { 00627 if (cp.y < p.y) 00628 conn = 7; 00629 else 00630 conn = 2; 00631 } else if (cp.x > p.x) { 00632 if (cp.y < p.y) 00633 conn = 5; 00634 else 00635 conn = 0; 00636 } 00637 #endif 00638 return conn; 00639 } 00640 00641 00642 int box_connection(node_t * n, pointf p) 00643 { 00644 int conn = 0; 00645 #if 0 00646 int i = 0, j, sides, conn = 0, peripheries, z; 00647 double xsize, ysize, mindist2 = 0.0, dist2; 00648 polygon_t *poly; 00649 pointf P, *vertices; 00650 static point *A; 00651 static int A_size; 00652 00653 poly = (polygon_t *) ND_shape_info(n); 00654 vertices = poly->vertices; 00655 sides = poly->sides; 00656 peripheries = poly->peripheries; 00657 00658 if (A_size < sides) { 00659 A_size = sides + 5; 00660 A = malloc(A_size*sizeof(pointf)); 00661 } 00662 00663 xsize = ((ND_lw(n) + ND_rw(n)) / POINTS(ND_width(n))) * 16.0; 00664 ysize = ((ND_ht(n)) / POINTS(ND_height(n))) * 16.0; 00665 00666 for (j = 0; j < peripheries; j++) { 00667 for (i = 0; i < sides; i++) { 00668 P = vertices[i + j * sides]; 00669 /* simple rounding produces random results around .5 00670 * this trick should clip off the random part. 00671 * (note xsize/ysize prescaled by 16.0 above) */ 00672 A[i].x = ROUND(P.x * xsize) / 16; 00673 A[i].y = ROUND(P.y * ysize) / 16; 00674 if (sides > 2) { 00675 A[i].x += ND_coord_i(n).x; 00676 A[i].y += ND_coord_i(n).y; 00677 } 00678 } 00679 } 00680 00681 z = 0; 00682 while (z < i) { 00683 dist2 = DIST2(p, dia_pt(A[z])); 00684 if (z == 0) { 00685 mindist2 = dist2; 00686 conn = 0; 00687 } 00688 if (dist2 < mindist2) { 00689 mindist2 = dist2; 00690 conn = 2 * z; 00691 } 00692 z++; 00693 } 00694 00695 z = 0; 00696 while (z < i) { 00697 P.x = (dia_pt(A[z]).x + dia_pt(A[z + 1]).x) / 2; 00698 P.y = (dia_pt(A[z]).y + dia_pt(A[z + 1]).y) / 2; 00699 dist2 = DIST2(p, P); 00700 if (dist2 < mindist2) { 00701 mindist2 = dist2; 00702 conn = 2 * z + 1; 00703 } 00704 z++; 00705 } 00706 #endif 00707 return conn; 00708 } 00709 00710 00711 static void 00712 dia_bezier(GVJ_t *job, pointf * A, int n, int arrow_at_start, int arrow_at_end, int filled) 00713 { 00714 #if 0 00715 int i, conn_h, conn_t; 00716 pointf p, firstp = { 0, 0 }, llp = { 00717 0, 0}, urp = { 00718 0, 0}; 00719 node_t *head, *tail; 00720 char *shape_t; 00721 pointf cp_h, cp_t; 00722 00723 if (cstk[SP].pen == P_NONE) { 00724 /* its invisible, don't draw */ 00725 return; 00726 } 00727 00728 gvprintf(job, 00729 " <dia:object type=\"Standard - BezierLine\" version=\"0\" id=\"%s\">\n", 00730 "00"); 00731 gvputs(job, " <dia:attribute name=\"bez_points\">\n"); 00732 for (i = 0; i < n; i++) { 00733 p = dia_pt(A[i]); 00734 if (!i) 00735 llp = urp = firstp = p; 00736 if (p.x < llp.x || p.y < llp.y) 00737 llp = p; 00738 if (p.x > urp.x || p.y > urp.y) 00739 urp = p; 00740 gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", p.x, p.y); 00741 } 00742 gvputs(job, " </dia:attribute>\n"); 00743 dia_style(job, &cstk[SP]); 00744 gvputs(job, " <dia:attribute name=\"obj_pos\">\n"); 00745 gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", firstp.x, firstp.y); 00746 gvputs(job, " </dia:attribute>\n"); 00747 gvputs(job, " <dia:attribute name=\"obj_bb\">\n"); 00748 gvprintf(job, " <dia:rectangle val=\"%g,%g;%g,%g\"/>\n", 00749 llp.x - .11, llp.y - .11, urp.x + .11, urp.y + .11); 00750 gvputs(job, " </dia:attribute>\n"); 00751 if (!Curedge) return; 00752 00753 conn_h = conn_t = -1; 00754 00755 head = Curedge->head; 00756 tail = Curedge->tail; 00757 00758 shape_t = ND_shape(tail)->name; 00759 00760 /* arrowheads */ 00761 if (arrow_at_start) { 00762 gvputs(job, " <dia:attribute name=\"start_arrow\">\n"); 00763 gvputs(job, " <dia:enum val=\"3\"/>\n"); 00764 gvputs(job, " </dia:attribute>\n"); 00765 gvputs(job, " <dia:attribute name=\"start_arrow_length\">\n"); 00766 gvputs(job, " <dia:real val=\"0.8\"/>\n"); 00767 gvputs(job, " </dia:attribute>\n"); 00768 dia_fputs 00769 (" <dia:attribute name=\"start_arrow_width\">\n"); 00770 gvputs(job, " <dia:real val=\"0.8\"/>\n"); 00771 gvputs(job, " </dia:attribute>\n"); 00772 } 00773 if (arrow_at_end) { 00774 gvputs(job, " <dia:attribute name=\"end_arrow\">\n"); 00775 gvputs(job, " <dia:enum val=\"3\"/>\n"); 00776 gvputs(job, " </dia:attribute>\n"); 00777 gvputs(job, " <dia:attribute name=\"end_arrow_length\">\n"); 00778 gvputs(job, " <dia:real val=\"0.8\"/>\n"); 00779 gvputs(job, " </dia:attribute>\n"); 00780 dia_fputs 00781 (" <dia:attribute name=\"end_arrow_width\">\n"); 00782 gvputs(job, " <dia:real val=\"0.8\"/>\n"); 00783 gvputs(job, " </dia:attribute>\n"); 00784 } 00785 00786 gvputs(job, " <dia:attribute name=\"conn_endpoints\">\n"); 00787 gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", dia_pt(A[0]).x, 00788 dia_pt(A[0]).y); 00789 gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", dia_pt(A[n - 1]).x, 00790 dia_pt(A[n - 1]).y); 00791 gvputs(job, " </dia:attribute>\n"); 00792 gvputs(job, " <dia:connections>\n"); 00793 00794 if ((strcmp(shape_t, "ellipse") == 0) 00795 || (strcmp(shape_t, "circle") == 0) 00796 || (strcmp(shape_t, "doublecircle") == 0)) { 00797 cp_h = dia_pt(ND_coord_i(head)); 00798 if (AG_IS_DIRECTED(Rootgraph)) 00799 conn_h = ellipse_connection(cp_h, dia_pt(A[n - 1])); 00800 else 00801 conn_h = ellipse_connection(cp_h, dia_pt(A[0])); 00802 } else { 00803 if (AG_IS_DIRECTED(Rootgraph)) 00804 conn_h = box_connection(head, dia_pt(A[n - 1])); 00805 else 00806 conn_h = box_connection(head, dia_pt(A[0])); 00807 } 00808 00809 if ((strcmp(shape_t, "ellipse") == 0) 00810 || (strcmp(shape_t, "circle") == 0) 00811 || (strcmp(shape_t, "doublecircle") == 0)) { 00812 cp_t = dia_pt(ND_coord_i(tail)); 00813 if (AG_IS_DIRECTED(Rootgraph)) 00814 conn_t = ellipse_connection(cp_t, dia_pt(A[0])); 00815 else 00816 conn_t = ellipse_connection(cp_t, dia_pt(A[n - 1])); 00817 } else { 00818 if (AG_IS_DIRECTED(Rootgraph)) 00819 conn_t = box_connection(tail, dia_pt(A[0])); 00820 else 00821 conn_t = box_connection(tail, dia_pt(A[n - 1])); 00822 } 00823 00824 if (arrow_at_start) { 00825 gvprintf(job, 00826 " <dia:connection handle=\"0\" to=\"%d\" connection=\"%d\"/>\n", 00827 head->id, conn_h); 00828 gvprintf(job, 00829 " <dia:connection handle=\"%d\" to=\"%d\" connection=\"%d\"/>\n", 00830 (n - 1), tail->id, conn_t); 00831 } else { 00832 gvprintf(job, 00833 " <dia:connection handle=\"0\" to=\"%d\" connection=\"%d\"/>\n", 00834 tail->id, conn_t); 00835 gvprintf(job, 00836 " <dia:connection handle=\"%d\" to=\"%d\" connection=\"%d\"/>\n", 00837 (n - 1), head->id, conn_h); 00838 } 00839 00840 gvputs(job, " </dia:connections>\n"); 00841 gvputs(job, " </dia:object>\n"); 00842 #endif 00843 } 00844 00845 00846 00847 static void dia_polygon(GVJ_t * job, pointf * A, int n, int filled) 00848 { 00849 #if 0 00850 int i; 00851 pointf p, firstp = { 0, 0 }, llp = { 00852 0, 0}, urp = { 00853 0, 0}; 00854 00855 if (cstk[SP].pen == P_NONE) { 00856 /* its invisible, don't draw */ 00857 return; 00858 } 00859 00860 switch (Obj) { 00861 case NODE: 00862 gvprintf(job, 00863 " <dia:object type=\"Standard - Polygon\" version=\"0\" id=\"%d\">\n", 00864 Curnode->id); 00865 break; 00866 case EDGE: 00867 return; 00868 break; 00869 case CLST: 00870 gvprintf(job, 00871 " <dia:object type=\"Standard - Polygon\" version=\"0\" id=\"%s\">\n", 00872 Curgraph->name); 00873 break; 00874 default: 00875 gvprintf(job, 00876 " <dia:object type=\"Standard - Polygon\" version=\"0\" id=\"%s\">\n", 00877 "polygon"); 00878 break; 00879 } 00880 gvputs(job, " <dia:attribute name=\"poly_points\">\n"); 00881 for (i = 0; i < n; i++) { 00882 p = dia_pt(A[i]); 00883 if (!i) 00884 llp = urp = firstp = p; 00885 if (p.x < llp.x || p.y < llp.y) 00886 llp = p; 00887 if (p.x > urp.x || p.y > urp.y) 00888 urp = p; 00889 gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", p.x, p.y); 00890 } 00891 gvputs(job, " </dia:attribute>\n"); 00892 gvputs(job, " <dia:attribute name=\"obj_pos\">\n"); 00893 gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", firstp.x, firstp.y); 00894 gvputs(job, " </dia:attribute>\n"); 00895 gvputs(job, " <dia:attribute name=\"obj_bb\">\n"); 00896 gvprintf(job, " <dia:rectangle val=\"%g,%g;%g,%g\"/>\n", 00897 llp.x - .11, llp.y - .11, urp.x + .11, urp.y + .11); 00898 gvputs(job, " </dia:attribute>\n"); 00899 dia_style(job, &cstk[SP]); 00900 dia_stylefill(job, &cstk[SP], filled); 00901 gvputs(job, " </dia:object>\n"); 00902 #endif 00903 } 00904 00905 static void dia_polyline(GVJ_t * job, pointf * A, int n) 00906 { 00907 #if 0 00908 int i; 00909 pointf p, firstp = { 0, 0 }, llp = { 00910 0, 0}, urp = { 00911 0, 0}; 00912 00913 if (cstk[SP].pen == P_NONE) { 00914 /* its invisible, don't draw */ 00915 return; 00916 } 00917 gvprintf(job, 00918 " <dia:object type=\"Standard - PolyLine\" version=\"0\" id=\"%s\">\n", 00919 "0"); 00920 gvputs(job, " <dia:attribute name=\"poly_points\">\n"); 00921 for (i = 0; i < n; i++) { 00922 p = dia_pt(A[i]); 00923 if (!i) 00924 llp = urp = firstp = p; 00925 if (p.x < llp.x || p.y < llp.y) 00926 llp = p; 00927 if (p.x > urp.x || p.y > urp.y) 00928 urp = p; 00929 gvprintf(job, "<dia:point val=\"%g,%g\"/>\n", p.x, p.y); 00930 } 00931 gvputs(job, " </dia:attribute>\n"); 00932 dia_style(job, &cstk[SP]); 00933 gvputs(job, " <dia:attribute name=\"obj_pos\">\n"); 00934 gvprintf(job, " <dia:point val=\"%g,%g\"/>\n", firstp.x, firstp.y); 00935 gvputs(job, " </dia:attribute>\n"); 00936 gvputs(job, " <dia:attribute name=\"obj_bb\">\n"); 00937 gvprintf(job, " <dia:rectangle val=\"%g,%g;%g,%g\"/>\n", 00938 llp.x - .11, llp.y - .11, urp.x + .11, urp.y + .11); 00939 gvputs(job, " </dia:attribute>\n"); 00940 gvputs(job, " </dia:object>\n"); 00941 #endif 00942 } 00943 00944 gvrender_engine_t dia_engine = { 00945 dia_begin_job, dia_end_job, 00946 dia_begin_graph, dia_end_graph, 00947 0, /* dia_begin_layer */ 0, /* dia_end_layer */ 00948 dia_begin_page, dia_end_page, 00949 dia_begin_cluster, dia_end_cluster, 00950 0, /* dia_begin_nodes */ 0, /* dia_end_nodes */ 00951 0, /* dia_begin_edges */ 0, /* dia_end_edges */ 00952 dia_begin_node, dia_end_node, 00953 dia_begin_edge, dia_end_edge, 00954 0, /* dia_begin_anchor */ 0, /* dia_end_anchor */ 00955 0, /* dia_begin_label */ 0, /* dia_end_label */ 00956 dia_textpara, dia_resolve_color, 00957 dia_ellipse, dia_polygon, 00958 dia_bezier, dia_polyline, 00959 dia_comment, 00960 0, /* dia_library_shape */ 00961 }; 00962 00963 static gvrender_features_t render_features_dia = { 00964 0, /* flags */ 00965 4., /* default pad - graph units */ 00966 NULL, /* knowncolors */ 00967 0, /* sizeof knowncolors */ 00968 HSVA_DOUBLE, /* color_type */ 00969 }; 00970 00971 static gvdevice_features_t device_features_dia = { 00972 GVDEVICE_BINARY_FORMAT 00973 | GVDEVICE_COMPRESSED_FORMAT, /* flags */ 00974 {0.,0.}, /* default margin - points */ 00975 {0.,0.}, /* default page width, height - points */ 00976 {72.,72.}, /* default dpi */ 00977 }; 00978 00979 gvplugin_installed_t gvrender_dia_types[] = { 00980 {FORMAT_DIA, "dia", -1, &dia_engine, &render_features_dia}, 00981 {0, NULL, 0, NULL, NULL} 00982 }; 00983 00984 gvplugin_installed_t gvdevice_dia_types[] = { 00985 {FORMAT_DIA, "dia:dia", -1, NULL, &device_features_dia}, 00986 {0, NULL, 0, NULL, NULL} 00987 }; 00988
1.7.5