| 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 |  | 
|---|
| 28 | extern void graph_init(Agraph_t *g, boolean use_rankdir); | 
|---|
| 29 | extern void graph_cleanup(Agraph_t *g); | 
|---|
| 30 | extern void gv_fixLocale (int set); | 
|---|
| 31 | extern void gv_initShapes (void); | 
|---|
| 32 |  | 
|---|
| 33 | int 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 | */ | 
|---|
| 55 | int 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 | */ | 
|---|
| 102 | int 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 |  | 
|---|