libgeda

s_cue.c

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines