|
|
1.1 ! root 1: /* ! 2: * emit pic. ! 3: */ ! 4: ! 5: #include "draw_dag.h" ! 6: #include "dag.h" ! 7: #include "parsedag.h" ! 8: #include "paths.h" ! 9: ! 10: static char* escape(char *s) { ! 11: static char buf[BUFSIZ]; ! 12: char *p = buf; ! 13: while (*s) { ! 14: if (*s == '\"') *p++ = '\\'; ! 15: *p++ = *s++; ! 16: } ! 17: *p = '\0'; ! 18: return buf; ! 19: } ! 20: ! 21: char *expandesc(char*d, int node) { ! 22: static char buf[BUFSIZ]; ! 23: char * p = buf; ! 24: char *printname; ! 25: if (Node[node]->label.type == STRING) ! 26: printname = Node[node]->label.value; ! 27: else ! 28: printname = Node[node]->name; ! 29: ! 30: while (*p = *d) switch(*p) { ! 31: case '\\': ! 32: if (!(*p++ = *++d)) return buf; ! 33: d++; ! 34: break; ! 35: case '$': ! 36: d++; ! 37: int m = 0; ! 38: if (!strncmp(d,"NAMELEN",m=7)) sprintf(p,"%d",strlen(printname)); ! 39: else if (!strncmp(d,"NAME",m=4)) { ! 40: if (Node[node]->pointsize != Default_node.pointsize) ! 41: sprintf(p,"\\s%d\"%s\"\\s0",Node[node]->pointsize, ! 42: escape(printname)); ! 43: else sprintf(p,"\"%s\"",escape(printname)); ! 44: } ! 45: else if (!strncmp(d,"WIDTH",m=5)) sprintf(p,"%f",inchof(Node[node]->xsize)); ! 46: else if (!strncmp(d,"HEIGHT",m=6)) sprintf(p,"%f",inchof(Node[node]->ysize)); ! 47: else {p++; break;} ! 48: while (*p) p++; ! 49: d += m; ! 50: break; ! 51: default: ! 52: p++; d++; break; ! 53: } ! 54: return buf; ! 55: } ! 56: ! 57: char *pic_inkstr(dag_ink_t ink) { ! 58: switch(ink) { ! 59: case solid_ink: return ""; // Sys V pic doesn't like "solid". ! 60: case dashed_ink: return "dashed"; ! 61: case dotted_ink: return "dotted"; ! 62: case invis_ink: return "invis"; ! 63: } ! 64: } ! 65: ! 66: char* find_cip_shape(shape_id_t s) { ! 67: switch (s) { ! 68: case Box: ! 69: case Square: ! 70: return "box wid %f ht %f"; ! 71: case Diamond: ! 72: return "d = %f\ne=%f\nmove down e/2; line up e/2 right d/2 then up e/2 left d/2 then down e/2 left d/2 then down e/2 right d/2"; ! 73: case Circle: ! 74: return "circle rad %f/2"; ! 75: case Doublecircle: ! 76: return "circe rad %f/2; circle rad .9*%f/2 at last circle.c"; ! 77: case User_defined: ! 78: case Ellipse: ! 79: default: ! 80: return "ellipse wid %f ht %f"; ! 81: case Plaintext: ! 82: return "box invis wid %f ht %f"; ! 83: } ! 84: } ! 85: ! 86: void emit_pic_pt(Point p) { ! 87: printf("(%f,%f)",inchof(p.x),inchof(p.y)); ! 88: } ! 89: ! 90: void emit_pic_header() { ! 91: ! 92: static int ordinal = 0; ! 93: double sf = 1.; ! 94: if (User.width <= 0) printf(".PS\n"); // no args ! 95: else { ! 96: sf = min((User.width*Resolution)/Xmax,1.); ! 97: if (User.height <= 0) User.height = (double)Ymax/Resolution; ! 98: else sf = min((User.height*Resolution)/Ymax,sf); ! 99: if (sf == 1.) printf(".PS\n"); ! 100: else { ! 101: User.width = min(User.width,sf*(double)Xmax/Resolution); ! 102: User.height = min(User.height,sf*(double)Ymax/Resolution); ! 103: Default_node.pointsize = (int)(Default_node.pointsize * sf); ! 104: for (int i = 0; i < N; i++) ! 105: Node[i]->pointsize = (int)(Node[i]->pointsize * sf); ! 106: printf(".PS %f %f\n",User.width,User.height); ! 107: } ! 108: } ! 109: ! 110: printf(".lf %d\n",Current_file.line_number + 1); ! 111: printf("arrowht = %f;\n", inchof((int)(Default_node.xsize*.15))); ! 112: printf("arrowwid = %f;\n", inchof((int)(Default_node.xsize*.075))); ! 113: if (!ordinal++ && (Output_type != Cip)) ! 114: cat_libfile(DAGLIB_PIC); ! 115: unsquirrel(); ! 116: } ! 117: ! 118: void emit_pic_node_header() { ! 119: printf(".ps %d\n",Default_node.pointsize); ! 120: } ! 121: ! 122: void emit_pic_edge_header() { ! 123: if (Default_edge.pointsize != Default_node.pointsize) ! 124: printf(".ps\n.ps %d\n",Default_edge.pointsize); ! 125: } ! 126: ! 127: void emit_pic_node(int node) { ! 128: shape_t shape = Node[node]->shape; ! 129: char *printname; ! 130: if (Node[node]->label.type == DESC) printname = ""; ! 131: else if (Node[node]->label.type == STRING) printname = Node[node]->label.value; ! 132: else printname = Node[node]->name; ! 133: ! 134: if (shape.type == DESC) { ! 135: printf("Node%d: [ %s ] with .c at ",node,expandesc(Node[node]->shape.value,node)); ! 136: emit_pic_pt(Node[node]->pos); ! 137: printf(";\n"); ! 138: } ! 139: else { ! 140: if (Output_type == Cip) { ! 141: printf("[ "); ! 142: printf(find_cip_shape(Node[node]->shape.shape_id), ! 143: inchof(Node[node]->xsize),inchof(Node[node]->ysize)); ! 144: printf("] with .c at "); ! 145: emit_pic_pt(Node[node]->pos); ! 146: printf(";\nmove to "); ! 147: emit_pic_pt(Node[node]->pos); ! 148: printf("; \"%s\";\n",escape(printname)); ! 149: } ! 150: else { ! 151: printf("Node%d: %s(\"%s\",%f,%f) at ",node,Node[node]->shape.value, ! 152: escape(printname),inchof(Node[node]->xsize),inchof(Node[node]->ysize)); ! 153: emit_pic_pt(Node[node]->pos); ! 154: printf(";\n"); ! 155: } ! 156: } ! 157: if (Node[node]->label.type == DESC) { ! 158: printf("move to "); ! 159: emit_pic_pt(Node[node]->pos); ! 160: printf("%s;\n",Node[node]->label.value); ! 161: } ! 162: } ! 163: ! 164: void emit_pic_edgelabel(DAG_edge_t *e) { ! 165: if (!e->label.type) return; ! 166: printf("move to "); ! 167: emit_pic_pt(find_edge_midpoint(e)); ! 168: printf("; "); ! 169: if (e->label.type == DESC) printf("%s;\n",e->label.value); ! 170: else printf("\"%s\";\n",escape(e->label.value)); ! 171: } ! 172: ! 173: void emit_pic_edge(int node, DAG_edge_t *e) { ! 174: if (e->ink == invis_ink) return; ! 175: Point intersection; ! 176: int fromnode = node, tonode = e->node; ! 177: intersection = find_nodeport(fromnode,e->top,e->splinept[0]); ! 178: printf("spline %s %s from ",e->flipped?"<-":"->", ! 179: (Output_type != Cip? pic_inkstr(e->ink) : "") ); ! 180: emit_pic_pt(intersection); ! 181: ! 182: for (int i = 1; e->splinept[i+1].x >= 0; i++) { ! 183: printf(" to "); ! 184: emit_pic_pt(e->splinept[i]); ! 185: } ! 186: intersection = find_nodeport(tonode,e->bottom,e->splinept[i]); ! 187: printf(" to "); ! 188: emit_pic_pt(intersection); ! 189: printf(";\n"); ! 190: emit_pic_edgelabel(e); ! 191: } ! 192: ! 193: void emit_pic_trailer() { ! 194: printf(".ps\n.PE\n"); ! 195: printf(".lf %d\n",Current_file.line_number + 1); ! 196: } ! 197: ! 198: void emit_pic() { ! 199: int node; ! 200: DAG_edge_t *e; ! 201: ! 202: emit_pic_header(); ! 203: emit_pic_node_header(); ! 204: for (node = 0; node < N; node++) emit_pic_node(node); ! 205: emit_pic_edge_header(); ! 206: for (node = 0; node < N; node++) ! 207: for (e = Edge[node]; e; e = e->nextof()) ! 208: emit_pic_edge(node,e); ! 209: emit_pic_trailer(); ! 210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.