Graphviz  2.29.20120524.0446
lib/gvc/gvlayout.c
Go to the documentation of this file.
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 /*
00015  *  layout engine wrapper
00016  *
00017  */
00018 
00019 #ifdef HAVE_CONFIG_H
00020 #include "config.h"
00021 #endif
00022 
00023 #include "const.h"
00024 #include "gvplugin_layout.h"
00025 #include "gvcint.h"
00026 #if WITH_CGRAPH
00027 #include "cgraph.h"
00028 #else
00029 #include "graph.h"
00030 #endif
00031 #include "gvcproc.h"
00032 #include "gvc.h"
00033 
00034 extern void graph_init(Agraph_t *g, boolean use_rankdir);
00035 extern void graph_cleanup(Agraph_t *g);
00036 extern void gv_fixLocale (int set);
00037 
00038 int gvlayout_select(GVC_t * gvc, const char *layout)
00039 {
00040     gvplugin_available_t *plugin;
00041     gvplugin_installed_t *typeptr;
00042 
00043     plugin = gvplugin_load(gvc, API_layout, layout);
00044     if (plugin) {
00045         typeptr = plugin->typeptr;
00046         gvc->layout.type = typeptr->type;
00047         gvc->layout.engine = (gvlayout_engine_t *) (typeptr->engine);
00048         gvc->layout.id = typeptr->id;
00049         gvc->layout.features = (gvlayout_features_t *) (typeptr->features);
00050         return GVRENDER_PLUGIN;  /* FIXME - need better return code */
00051     }
00052     return NO_SUPPORT;
00053 }
00054 
00055 /* gvLayoutJobs:
00056  * Layout input graph g based on layout engine attached to gvc.
00057  * Check that the root graph has been initialized. If not, initialize it.
00058  * Return 0 on success.
00059  */
00060 int gvLayoutJobs(GVC_t * gvc, Agraph_t * g)
00061 {
00062     gvlayout_engine_t *gvle;
00063     char *p;
00064     int rc;
00065 
00066 #ifdef WITH_CGRAPH
00067     agbindrec(g, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
00068 #endif
00069     GD_gvc(g) = gvc;
00070     if (g != agroot(g))
00071         GD_gvc(agroot(g)) = gvc;
00072 
00073     if ((p = agget(g, "layout"))) {
00074         rc = gvlayout_select(gvc, p);
00075         if (rc == NO_SUPPORT) {
00076             agerr (AGERR, "Layout type: \"%s\" not recognized. Use one of:%s\n",
00077                 p, gvplugin_list(gvc, API_layout, p));
00078             return -1;
00079         }
00080     }
00081 
00082     gvle = gvc->layout.engine;
00083     if (! gvle)
00084         return -1;
00085 
00086     gv_fixLocale (1);
00087     graph_init(g, gvc->layout.features->flags & LAYOUT_USES_RANKDIR);
00088     GD_drawing(agroot(g)) = GD_drawing(g);
00089     if (gvle && gvle->layout) {
00090         gvle->layout(g);
00091 
00092 
00093         if (gvle->cleanup)
00094             GD_cleanup(g) = gvle->cleanup;
00095     }
00096     gv_fixLocale (0);
00097     return 0;
00098 }
00099 
00100 /* gvFreeLayout:
00101  * Free layout resources.
00102  * First, if the graph has a layout-specific cleanup function attached,
00103  * use it and reset.
00104  * Then, if the root graph has not been cleaned up, clean it up and reset.
00105  * Only the root graph has GD_drawing non-null.
00106  */
00107 int gvFreeLayout(GVC_t * gvc, Agraph_t * g)
00108 {
00109 #ifdef WITH_CGRAPH
00110     /* skip if no Agraphinfo_t yet */
00111     if (! agbindrec(g, "Agraphinfo_t", 0, TRUE))
00112             return 0;
00113 #endif
00114 
00115     if (GD_cleanup(g)) {
00116         (GD_cleanup(g))(g);
00117         GD_cleanup(g) = NULL;
00118     }
00119     
00120     if (GD_drawing(g)) {
00121         graph_cleanup(g);
00122         GD_drawing(g) = NULL;
00123         GD_drawing(g->root) = NULL;
00124     }
00125     return 0;
00126 }