123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- /*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: Details at https://graphviz.org
- *************************************************************************/
- /*
- * layout engine wrapper
- *
- */
- #include "config.h"
- #include <common/const.h>
- #include <gvc/gvplugin_layout.h>
- #include <gvc/gvcint.h>
- #include <cgraph/cgraph.h>
- #include <gvc/gvcproc.h>
- #include <gvc/gvc.h>
- #include <stdbool.h>
- #include <stddef.h>
- extern void graph_init(Agraph_t *g, bool use_rankdir);
- extern void graph_cleanup(Agraph_t *g);
- extern void gv_fixLocale (int set);
- int gvlayout_select(GVC_t * gvc, const char *layout)
- {
- gvplugin_available_t *plugin;
- gvplugin_installed_t *typeptr;
- plugin = gvplugin_load(gvc, API_layout, layout, NULL);
- if (plugin) {
- typeptr = plugin->typeptr;
- gvc->layout.type = typeptr->type;
- gvc->layout.engine = typeptr->engine;
- gvc->layout.id = typeptr->id;
- gvc->layout.features = typeptr->features;
- return GVRENDER_PLUGIN; /* FIXME - need better return code */
- }
- return NO_SUPPORT;
- }
- /* gvLayoutJobs:
- * Layout input graph g based on layout engine attached to gvc.
- * Check that the root graph has been initialized. If not, initialize it.
- * Return 0 on success.
- */
- int gvLayoutJobs(GVC_t * gvc, Agraph_t * g)
- {
- gvlayout_engine_t *gvle;
- char *p;
- int rc;
- agbindrec(g, "Agraphinfo_t", sizeof(Agraphinfo_t), true);
- GD_gvc(g) = gvc;
- if (g != agroot(g)) {
- agbindrec(agroot(g), "Agraphinfo_t", sizeof(Agraphinfo_t), true);
- GD_gvc(agroot(g)) = gvc;
- }
- if ((p = agget(g, "layout"))) {
- gvc->layout.engine = NULL;
- rc = gvlayout_select(gvc, p);
- if (rc == NO_SUPPORT) {
- agerrorf("Layout type: \"%s\" not recognized. Use one of:%s\n",
- p, gvplugin_list(gvc, API_layout, p));
- return -1;
- }
- }
- gvle = gvc->layout.engine;
- if (! gvle)
- return -1;
- gv_fixLocale (1);
- graph_init(g, !!(gvc->layout.features->flags & LAYOUT_USES_RANKDIR));
- GD_drawing(agroot(g)) = GD_drawing(g);
- if (gvle && gvle->layout) {
- gvle->layout(g);
- if (gvle->cleanup)
- GD_cleanup(g) = gvle->cleanup;
- }
- gv_fixLocale (0);
- return 0;
- }
- bool gvLayoutDone(Agraph_t * g)
- {
- return LAYOUT_DONE(g);
- }
- /* gvFreeLayout:
- * Free layout resources.
- * First, if the graph has a layout-specific cleanup function attached,
- * use it and reset.
- * Then do the general graph cleanup.
- */
- int gvFreeLayout(GVC_t * gvc, Agraph_t * g)
- {
- (void)gvc;
- /* skip if no Agraphinfo_t yet */
- if (! agbindrec(g, "Agraphinfo_t", 0, true))
- return 0;
- if (GD_cleanup(g)) {
- (GD_cleanup(g))(g);
- GD_cleanup(g) = NULL;
- }
-
- graph_cleanup(g);
- return 0;
- }
|