gvlayout.c 2.9 KB

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