libgeda
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * libgeda - gEDA's library 00003 * Copyright (C) 1998-2010 Ales Hvezda 00004 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details) 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 #include <config.h> 00021 00022 #include <stdio.h> 00023 #include <ctype.h> 00024 #ifdef HAVE_STDLIB_H 00025 #include <stdlib.h> 00026 #endif 00027 00028 #include <math.h> 00029 00030 #include "libgeda_priv.h" 00031 00032 #ifdef HAVE_LIBDMALLOC 00033 #include <dmalloc.h> 00034 #endif 00035 00041 void s_cue_postscript_fillbox(TOPLEVEL * toplevel, FILE * fp, int x, 00042 int y) 00043 { 00044 int offset; 00045 int offset2; 00046 00047 /* hard coded values */ 00048 offset = CUE_BOX_SIZE; 00049 offset2 = offset*2; 00050 00051 f_print_set_color(toplevel, fp, NET_ENDPOINT_COLOR); 00052 00053 fprintf(fp, "%d %d %d %d fbox\n", 00054 offset2, offset2, x-offset, y-offset); 00055 } 00056 00062 void s_cue_postscript_junction (TOPLEVEL * toplevel, FILE * fp, 00063 int x, int y, int bus_involved) 00064 { 00065 int offset2; 00066 00067 if (bus_involved) { 00068 offset2 = JUNCTION_CUE_SIZE_BUS; 00069 } else { 00070 offset2 = JUNCTION_CUE_SIZE_NET; 00071 } 00072 00073 f_print_set_color(toplevel, fp, JUNCTION_COLOR); 00074 00075 fprintf(fp, "newpath\n"); 00076 fprintf(fp, "%d %d\n", x, y); 00077 fprintf(fp, "%d\n", offset2 / 2); 00078 fprintf(fp, "0 360 arc\n"); 00079 fprintf(fp, "fill\n"); 00080 } 00081 00084 void 00085 s_cue_postscript_arrow (TOPLEVEL *toplevel, FILE *fp, 00086 int x, int y, int dx, int dy) 00087 { 00088 int offset = CUE_BOX_SIZE; 00089 00090 f_print_set_color (toplevel, fp, JUNCTION_COLOR); 00091 00092 fprintf (fp, "gsave\n"); 00093 00094 /* We compute a transformation so that the arrowhead is aligned with 00095 * the net segment. */ 00096 double len = hypot (dx, dy); 00097 if (len != 0) { 00098 double c = dx / len; 00099 double s = dy / len; 00100 fprintf (fp, "[ %.2f %.2f %.2f %.2f %d %d ] concat\n", c, -s, s, c, x, y); 00101 } else { 00102 fprintf (fp, "%d %d translate\n", x, y); /* Translate to centre point of the arrow */ 00103 } 00104 00105 /* Now draw a simple arrowhead */ 00106 fprintf (fp, "newpath\n"); 00107 fprintf (fp, "%d %d moveto\n", -offset, -offset); 00108 fprintf (fp, "%d %d lineto\n", -offset, offset); 00109 fprintf (fp, "%d %d lineto\n", offset, 0); 00110 fprintf (fp, "closepath\n" 00111 "fill\n" 00112 "grestore\n"); 00113 } 00114 00120 void s_cue_output_all (TOPLEVEL * toplevel, const GList *obj_list, FILE * fp, 00121 int type) 00122 { 00123 OBJECT *o_current; 00124 const GList *iter; 00125 00126 iter = obj_list; 00127 while (iter != NULL) { 00128 o_current = (OBJECT *)iter->data; 00129 switch (o_current->type) { 00130 case (OBJ_NET): 00131 case (OBJ_BUS): 00132 case (OBJ_PIN): 00133 s_cue_output_single(toplevel, o_current, fp, type); 00134 break; 00135 00136 case (OBJ_COMPLEX): 00137 case (OBJ_PLACEHOLDER): 00138 s_cue_output_all(toplevel, o_current->complex->prim_objs, fp, 00139 type); 00140 break; 00141 00142 } 00143 iter = g_list_next (iter); 00144 } 00145 } 00146 00152 void s_cue_output_lowlevel(TOPLEVEL * toplevel, OBJECT * object, int whichone, 00153 FILE * fp, int output_type) 00154 { 00155 int x, y; 00156 GList *cl_current; 00157 CONN *conn; 00158 int type, count = 0; 00159 int done = FALSE; 00160 int bus_involved = FALSE; 00161 00162 x = object->line->x[whichone]; 00163 y = object->line->y[whichone]; 00164 00165 type = CONN_ENDPOINT; 00166 00167 if (object->type == OBJ_BUS || 00168 (object->type == OBJ_PIN && object->pin_type == PIN_TYPE_BUS)) 00169 bus_involved = TRUE; 00170 00171 cl_current = object->conn_list; 00172 while (cl_current != NULL && !done) { 00173 conn = (CONN *) cl_current->data; 00174 00175 if (conn->x == x && conn->y == y) { 00176 00177 if (conn->other_object && 00178 (conn->other_object->type == OBJ_BUS || 00179 (conn->other_object->type == OBJ_PIN && 00180 conn->other_object->pin_type == PIN_TYPE_BUS))) 00181 bus_involved=TRUE; 00182 00183 switch (conn->type) { 00184 00185 case (CONN_ENDPOINT): 00186 count++; 00187 break; 00188 00189 case (CONN_MIDPOINT): 00190 type = CONN_MIDPOINT; 00191 done = TRUE; 00192 count = 0; 00193 break; 00194 } 00195 } 00196 00197 cl_current = g_list_next(cl_current); 00198 } 00199 00200 #if DEBUG 00201 printf("type: %d count: %d\n", type, count); 00202 #endif 00203 00204 switch (type) { 00205 00206 case (CONN_ENDPOINT): 00207 if (object->type == OBJ_NET || object->type == OBJ_PIN) { 00208 if (count < 1) { /* Didn't find anything connected there */ 00209 if ((object->type == OBJ_NET) 00210 && o_net_is_fully_connected (toplevel, object)) { 00211 /* Probably connected, so draw friendly arrowhead. The 00212 * additional parameters are needed to allow the arrowhead 00213 * to be pointed in the direction of the net. */ 00214 if (output_type == POSTSCRIPT) { 00215 s_cue_postscript_arrow (toplevel, fp, x, y, 00216 object->line->x[whichone] - object->line->x[!whichone], 00217 object->line->y[whichone] - object->line->y[!whichone]); 00218 } 00219 } else { 00220 s_cue_postscript_fillbox (toplevel, fp, x, y); 00221 } 00222 } else if (count >= 2) { 00223 if (output_type == POSTSCRIPT) 00224 s_cue_postscript_junction (toplevel, fp, x, y, bus_involved); 00225 } 00226 } 00227 break; 00228 00229 case (CONN_MIDPOINT): 00230 if (output_type == POSTSCRIPT) 00231 s_cue_postscript_junction (toplevel, fp, x, y, bus_involved); 00232 break; 00233 } 00234 00235 } 00236 00242 void s_cue_output_lowlevel_midpoints(TOPLEVEL * toplevel, OBJECT * object, 00243 FILE * fp, int output_type) 00244 { 00245 int x, y; 00246 GList *cl_current; 00247 CONN *conn; 00248 int bus_involved = FALSE; 00249 00250 if (object->type == OBJ_BUS) 00251 bus_involved = TRUE; 00252 00253 cl_current = object->conn_list; 00254 while (cl_current != NULL) { 00255 conn = (CONN *) cl_current->data; 00256 00257 switch (conn->type) { 00258 case (CONN_MIDPOINT): 00259 00260 x = conn->x; 00261 y = conn->y; 00262 00263 if (conn->other_object && conn->other_object->type == OBJ_BUS) 00264 bus_involved = TRUE; 00265 00266 if (output_type == POSTSCRIPT) { 00267 s_cue_postscript_junction (toplevel, fp, x, y, bus_involved); 00268 } 00269 break; 00270 } 00271 00272 00273 cl_current = g_list_next(cl_current); 00274 } 00275 } 00276 00290 void s_cue_output_single(TOPLEVEL * toplevel, OBJECT * object, FILE * fp, 00291 int type) 00292 { 00293 g_return_if_fail (object != NULL); 00294 00295 switch (object->type) { 00296 case (OBJ_NET): 00297 s_cue_output_lowlevel(toplevel, object, 0, fp, type); 00298 s_cue_output_lowlevel(toplevel, object, 1, fp, type); 00299 break; 00300 case (OBJ_BUS): 00301 s_cue_output_lowlevel(toplevel, object, 0, fp, type); 00302 s_cue_output_lowlevel(toplevel, object, 1, fp, type); 00303 break; 00304 case (OBJ_PIN): 00305 s_cue_output_lowlevel(toplevel, object, object->whichend, fp, type); 00306 break; 00307 default: 00308 return; 00309 } 00310 s_cue_output_lowlevel_midpoints(toplevel, object, fp, type); 00311 } 00312 00313 00314