Graphviz  2.29.20120524.0446
lib/gvc/gvc.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 #ifdef HAVE_CONFIG_H
00015 #include "config.h"
00016 #endif
00017 
00018 #include "gvc.h"
00019 #include "const.h"
00020 #include "gvcjob.h"
00021 #include "gvcint.h"
00022 #include "gvcproc.h"
00023 #include "gvconfig.h"
00024 #include "gvio.h"
00025 #ifdef WITH_CGRAPH
00026 #include <stdlib.h>
00027 #endif
00028 
00029 #ifdef WIN32 /*dependencies*/
00030 #ifdef WITH_CGRAPH
00031     #pragma comment( lib, "cgraph.lib" )
00032 #else
00033     #pragma comment( lib, "graph.lib" )
00034 #endif
00035     #pragma comment( lib, "cdt.lib" )
00036     #pragma comment( lib, "ltdl.lib" )
00037     #pragma comment( lib, "xml2.lib" )
00038     #pragma comment( lib, "expat.lib" )
00039     #pragma comment( lib, "zdll.lib" )
00040 #endif
00041 
00042 
00043 GVC_t *gvContext(void)
00044 {
00045     GVC_t *gvc;
00046 
00047 #ifndef WITH_CGRAPH
00048     aginit();
00049     agnodeattr(NULL, "label", NODENAME_ESC);
00050 #else
00051     agattr(NULL, AGNODE, "label", NODENAME_ESC);
00052 #endif
00053     /* default to no builtins, demand loading enabled */
00054     gvc = gvNEWcontext(NULL, TRUE);
00055     gvconfig(gvc, FALSE); /* configure for available plugins */
00056     return gvc;
00057 }
00058 
00059 GVC_t *gvContextPlugins(const lt_symlist_t *builtins, int demand_loading)
00060 {
00061     GVC_t *gvc;
00062 
00063 #ifndef WITH_CGRAPH
00064     aginit();
00065     agnodeattr(NULL, "label", NODENAME_ESC);
00066 #else
00067     agattr(NULL, AGNODE, "label", NODENAME_ESC);
00068 #endif
00069     gvc = gvNEWcontext(builtins, demand_loading);
00070     gvconfig(gvc, FALSE); /* configure for available plugins */
00071     return gvc;
00072 }
00073 
00074 
00075 
00076 /* gvLayout:
00077  * Selects layout based on engine and binds it to gvc;
00078  * does the layout and sets the graph's bbox.
00079  * Return 0 on success.
00080  */
00081 int gvLayout(GVC_t *gvc, graph_t *g, const char *engine)
00082 {
00083     char buf[256];
00084     int rc;
00085 
00086     rc = gvlayout_select(gvc, engine);
00087     if (rc == NO_SUPPORT) {
00088         agerr (AGERR, "Layout type: \"%s\" not recognized. Use one of:%s\n",
00089                 engine, gvplugin_list(gvc, API_layout, engine));
00090         return -1;
00091     }
00092 
00093     gvLayoutJobs(gvc, g);
00094 
00095 /* set bb attribute for basic layout.
00096  * doesn't yet include margins, scaling or page sizes because
00097  * those depend on the renderer being used. */
00098     if (GD_drawing(g)->landscape)
00099         sprintf(buf, "%d %d %d %d",
00100                 ROUND(GD_bb(g).LL.y), ROUND(GD_bb(g).LL.x),
00101                 ROUND(GD_bb(g).UR.y), ROUND(GD_bb(g).UR.x));
00102     else
00103         sprintf(buf, "%d %d %d %d",
00104                 ROUND(GD_bb(g).LL.x), ROUND(GD_bb(g).LL.y),
00105                 ROUND(GD_bb(g).UR.x), ROUND(GD_bb(g).UR.y));
00106     agsafeset(g, "bb", buf, "");
00107 
00108     return 0;
00109 }
00110 
00111 /* Render layout in a specified format to an open FILE */
00112 int gvRender(GVC_t *gvc, graph_t *g, const char *format, FILE *out)
00113 {
00114     int rc;
00115     GVJ_t *job;
00116 
00117     g = g->root;
00118 
00119     /* create a job for the required format */
00120     rc = gvjobs_output_langname(gvc, format);
00121     job = gvc->job;
00122     if (rc == NO_SUPPORT) {
00123         agerr (AGERR, "Format: \"%s\" not recognized. Use one of:%s\n",
00124                 format, gvplugin_list(gvc, API_device, format));
00125         return -1;
00126     }
00127 
00128     job->output_lang = gvrender_select(job, job->output_langname);
00129     if (!GD_drawing(g) && !(job->flags & LAYOUT_NOT_REQUIRED)) {
00130         fprintf(stderr, "Layout was not done\n");
00131         return -1;
00132     }
00133     job->output_file = out;
00134     if (out == NULL)
00135         job->flags |= OUTPUT_NOT_REQUIRED;
00136     rc = gvRenderJobs(gvc, g);
00137     gvrender_end_job(job);
00138     gvjobs_delete(gvc);
00139 
00140     return rc;
00141 }
00142 
00143 /* Render layout in a specified format to an open FILE */
00144 int gvRenderFilename(GVC_t *gvc, graph_t *g, const char *format, const char *filename)
00145 {
00146     int rc;
00147     GVJ_t *job;
00148 
00149     g = g->root;
00150 
00151     /* create a job for the required format */
00152     rc = gvjobs_output_langname(gvc, format);
00153     job = gvc->job;
00154     if (rc == NO_SUPPORT) {
00155         agerr(AGERR, "Format: \"%s\" not recognized. Use one of:%s\n",
00156                 format, gvplugin_list(gvc, API_device, format));
00157         return -1;
00158     }
00159 
00160     job->output_lang = gvrender_select(job, job->output_langname);
00161     if (!GD_drawing(g) && !(job->flags & LAYOUT_NOT_REQUIRED)) {
00162         fprintf(stderr, "Layout was not done\n");
00163         return -1;
00164     }
00165     gvjobs_output_filename(gvc, filename);
00166     rc = gvRenderJobs(gvc, g);
00167     gvrender_end_job(job);
00168     gvdevice_finalize(job);
00169     gvjobs_delete(gvc);
00170 
00171     return rc;
00172 }
00173 
00174 /* Render layout in a specified format to an external context */
00175 int gvRenderContext(GVC_t *gvc, graph_t *g, const char *format, void *context)
00176 {
00177     int rc;
00178     GVJ_t *job;
00179         
00180     g = g->root;
00181         
00182     /* create a job for the required format */
00183     rc = gvjobs_output_langname(gvc, format);
00184     job = gvc->job;
00185     if (rc == NO_SUPPORT) {
00186                 agerr(AGERR, "Format: \"%s\" not recognized. Use one of:%s\n",
00187                           format, gvplugin_list(gvc, API_device, format));
00188                 return -1;
00189     }
00190         
00191     job->output_lang = gvrender_select(job, job->output_langname);
00192     if (!GD_drawing(g) && !(job->flags & LAYOUT_NOT_REQUIRED)) {
00193                 fprintf(stderr, "Layout was not done\n");
00194                 return -1;
00195     }
00196         
00197     job->context = context;
00198     job->external_context = TRUE;
00199         
00200     rc = gvRenderJobs(gvc, g);
00201     gvrender_end_job(job);
00202     gvdevice_finalize(job);
00203     gvjobs_delete(gvc);
00204         
00205     return rc;
00206 }
00207 
00208 /* Render layout in a specified format to a malloc'ed string */
00209 int gvRenderData(GVC_t *gvc, graph_t *g, const char *format, char **result, unsigned int *length)
00210 {
00211     int rc;
00212     GVJ_t *job;
00213 
00214     g = g->root;
00215 
00216     /* create a job for the required format */
00217     rc = gvjobs_output_langname(gvc, format);
00218     job = gvc->job;
00219     if (rc == NO_SUPPORT) {
00220         agerr(AGERR, "Format: \"%s\" not recognized. Use one of:%s\n",
00221                 format, gvplugin_list(gvc, API_device, format));
00222         return -1;
00223     }
00224 
00225     job->output_lang = gvrender_select(job, job->output_langname);
00226     if (!GD_drawing(g) && !(job->flags & LAYOUT_NOT_REQUIRED)) {
00227         fprintf(stderr, "Layout was not done\n");
00228         return -1;
00229     }
00230 
00231 /* page size on Linux, Mac OS X and Windows */
00232 #define OUTPUT_DATA_INITIAL_ALLOCATION 4096
00233 
00234     if(!result || !(*result = malloc(OUTPUT_DATA_INITIAL_ALLOCATION))) {
00235         agerr(AGERR, "failure malloc'ing for result string");
00236         return -1;
00237     }
00238 
00239     job->output_data = *result;
00240     job->output_data_allocated = OUTPUT_DATA_INITIAL_ALLOCATION;
00241     job->output_data_position = 0;
00242 
00243     rc = gvRenderJobs(gvc, g);
00244     gvrender_end_job(job);
00245 
00246     if (rc == 0) {
00247         *result = job->output_data;
00248         *length = job->output_data_position;
00249     }
00250     gvjobs_delete(gvc);
00251 
00252     return rc;
00253 }
00254 
00255 
00256 void gvAddLibrary(GVC_t *gvc, gvplugin_library_t *lib)
00257 {
00258     gvconfig_plugin_install_from_library(gvc, NULL, lib);
00259 }
00260 
00261 char **gvcInfo(GVC_t* gvc) { return gvc->common.info; }
00262 char *gvcVersion(GVC_t* gvc) { return gvc->common.info[1]; }
00263 char *gvcBuildDate(GVC_t* gvc) { return gvc->common.info[2]; }