1/* $Id$ $Revision$ */
2/* vim:set shiftwidth=4 ts=8: */
3
4/*************************************************************************
5 * Copyright (c) 2011 AT&T Intellectual Property
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *
11 * Contributors: See CVS logs. Details at http://www.graphviz.org/
12 *************************************************************************/
13
14/*
15 * layout engine wrapper
16 *
17 */
18
19#include "config.h"
20
21#include "const.h"
22#include "gvplugin_layout.h"
23#include "gvcint.h"
24#include "cgraph.h"
25#include "gvcproc.h"
26#include "gvc.h"
27
28extern void graph_init(Agraph_t *g, boolean use_rankdir);
29extern void graph_cleanup(Agraph_t *g);
30extern void gv_fixLocale (int set);
31extern void gv_initShapes (void);
32
33int gvlayout_select(GVC_t * gvc, const char *layout)
34{
35 gvplugin_available_t *plugin;
36 gvplugin_installed_t *typeptr;
37
38 plugin = gvplugin_load(gvc, API_layout, layout);
39 if (plugin) {
40 typeptr = plugin->typeptr;
41 gvc->layout.type = typeptr->type;
42 gvc->layout.engine = (gvlayout_engine_t *) (typeptr->engine);
43 gvc->layout.id = typeptr->id;
44 gvc->layout.features = (gvlayout_features_t *) (typeptr->features);
45 return GVRENDER_PLUGIN; /* FIXME - need better return code */
46 }
47 return NO_SUPPORT;
48}
49
50/* gvLayoutJobs:
51 * Layout input graph g based on layout engine attached to gvc.
52 * Check that the root graph has been initialized. If not, initialize it.
53 * Return 0 on success.
54 */
55int gvLayoutJobs(GVC_t * gvc, Agraph_t * g)
56{
57 gvlayout_engine_t *gvle;
58 char *p;
59 int rc;
60
61 agbindrec(g, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
62 GD_gvc(g) = gvc;
63 if (g != agroot(g))
64 GD_gvc(agroot(g)) = gvc;
65
66 if ((p = agget(g, "layout"))) {
67 gvc->layout.engine = NULL;
68 rc = gvlayout_select(gvc, p);
69 if (rc == NO_SUPPORT) {
70 agerr (AGERR, "Layout type: \"%s\" not recognized. Use one of:%s\n",
71 p, gvplugin_list(gvc, API_layout, p));
72 return -1;
73 }
74 }
75
76 gvle = gvc->layout.engine;
77 if (! gvle)
78 return -1;
79
80 gv_fixLocale (1);
81 graph_init(g, gvc->layout.features->flags & LAYOUT_USES_RANKDIR);
82 GD_drawing(agroot(g)) = GD_drawing(g);
83 gv_initShapes ();
84 if (gvle && gvle->layout) {
85 gvle->layout(g);
86
87
88 if (gvle->cleanup)
89 GD_cleanup(g) = gvle->cleanup;
90 }
91 gv_fixLocale (0);
92 return 0;
93}
94
95/* gvFreeLayout:
96 * Free layout resources.
97 * First, if the graph has a layout-specific cleanup function attached,
98 * use it and reset.
99 * Then, if the root graph has not been cleaned up, clean it up and reset.
100 * Only the root graph has GD_drawing non-null.
101 */
102int gvFreeLayout(GVC_t * gvc, Agraph_t * g)
103{
104 /* skip if no Agraphinfo_t yet */
105 if (! agbindrec(g, "Agraphinfo_t", 0, TRUE))
106 return 0;
107
108 if (GD_cleanup(g)) {
109 (GD_cleanup(g))(g);
110 GD_cleanup(g) = NULL;
111 }
112
113 if (GD_drawing(g)) {
114 graph_cleanup(g);
115 }
116 return 0;
117}
118