| 1 | /* $Id:  */ | 
|---|
| 2 | /* vim:set shiftwidth=8 ts=8: */ | 
|---|
| 3 |  | 
|---|
| 4 | /********************************************************** | 
|---|
| 5 | *            Copyright (c) 2011 Andy Jeutter              * | 
|---|
| 6 | *            AKA HallerHarry at gmx.de                    * | 
|---|
| 7 | *            All rights reserved.                         * | 
|---|
| 8 | **********************************************************/ | 
|---|
| 9 |  | 
|---|
| 10 | /************************************************************************* | 
|---|
| 11 | * This program and the accompanying materials | 
|---|
| 12 | * are made available under the terms of the Eclipse Public License v1.0 | 
|---|
| 13 | * which accompanies this distribution, and is available at | 
|---|
| 14 | * http://www.eclipse.org/legal/epl-v10.html | 
|---|
| 15 | * | 
|---|
| 16 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ | 
|---|
| 17 | *************************************************************************/ | 
|---|
| 18 |  | 
|---|
| 19 | #define _GNU_SOURCE | 
|---|
| 20 | #include "config.h" | 
|---|
| 21 |  | 
|---|
| 22 | #include <stdarg.h> | 
|---|
| 23 | #include <stdlib.h> | 
|---|
| 24 | #include <string.h> | 
|---|
| 25 | #include <ctype.h> | 
|---|
| 26 | #include <errno.h> | 
|---|
| 27 |  | 
|---|
| 28 | #include "macros.h" | 
|---|
| 29 | #include "const.h" | 
|---|
| 30 |  | 
|---|
| 31 | #include "gvplugin_render.h" | 
|---|
| 32 | #include "gvplugin_device.h" | 
|---|
| 33 | #include "gvio.h" | 
|---|
| 34 | #include "gvcint.h" | 
|---|
| 35 |  | 
|---|
| 36 | #define POV_VERSION \ | 
|---|
| 37 | "#version 3.6;\n" | 
|---|
| 38 |  | 
|---|
| 39 | #define POV_GLOBALS \ | 
|---|
| 40 | "global_settings { assumed_gamma 1.0 }\n" | 
|---|
| 41 |  | 
|---|
| 42 | #define POV_DEFAULT \ | 
|---|
| 43 | "#default { finish { ambient 0.1 diffuse 0.9 } }\n" | 
|---|
| 44 |  | 
|---|
| 45 | #define POV_INCLUDE \ | 
|---|
| 46 | "#include \"colors.inc\"\n"\ | 
|---|
| 47 | "#include \"textures.inc\"\n"\ | 
|---|
| 48 | "#include \"shapes.inc\"\n" | 
|---|
| 49 |  | 
|---|
| 50 | #define POV_LIGHT \ | 
|---|
| 51 | "light_source { <1500,3000,-2500> color White }\n" | 
|---|
| 52 |  | 
|---|
| 53 | #define POV_CAMERA \ | 
|---|
| 54 | "camera { location <%.3f , %.3f , %.3f>\n"\ | 
|---|
| 55 | "         look_at  <%.3f , %.3f , %.3f>\n"\ | 
|---|
| 56 | "         right x * image_width / image_height\n"\ | 
|---|
| 57 | "         angle %.3f\n"\ | 
|---|
| 58 | "}\n" | 
|---|
| 59 |  | 
|---|
| 60 | #define POV_SKY_AND_GND \ | 
|---|
| 61 | "//sky\n"\ | 
|---|
| 62 | "plane { <0, 1, 0>, 1 hollow\n"\ | 
|---|
| 63 | "    texture {\n"\ | 
|---|
| 64 | "        pigment { bozo turbulence 0.95\n"\ | 
|---|
| 65 | "            color_map {\n"\ | 
|---|
| 66 | "                [0.00 rgb <0.05, 0.20, 0.50>]\n"\ | 
|---|
| 67 | "                [0.50 rgb <0.05, 0.20, 0.50>]\n"\ | 
|---|
| 68 | "                [0.75 rgb <1.00, 1.00, 1.00>]\n"\ | 
|---|
| 69 | "                [0.75 rgb <0.25, 0.25, 0.25>]\n"\ | 
|---|
| 70 | "                [1.00 rgb <0.50, 0.50, 0.50>]\n"\ | 
|---|
| 71 | "            }\n"\ | 
|---|
| 72 | "            scale <1.00, 1.00, 1.50> * 2.50\n"\ | 
|---|
| 73 | "            translate <0.00, 0.00, 0.00>\n"\ | 
|---|
| 74 | "        }\n"\ | 
|---|
| 75 | "        finish { ambient 1 diffuse 0 }\n"\ | 
|---|
| 76 | "    }\n"\ | 
|---|
| 77 | "    scale 10000\n"\ | 
|---|
| 78 | "}\n"\ | 
|---|
| 79 | "//mist\n"\ | 
|---|
| 80 | "fog { fog_type 2\n"\ | 
|---|
| 81 | "    distance 50\n"\ | 
|---|
| 82 | "    color rgb <1.00, 1.00, 1.00> * 0.75\n"\ | 
|---|
| 83 | "    fog_offset 0.10\n"\ | 
|---|
| 84 | "    fog_alt 1.50\n"\ | 
|---|
| 85 | "    turbulence 1.75\n"\ | 
|---|
| 86 | "}\n"\ | 
|---|
| 87 | "//gnd\n"\ | 
|---|
| 88 | "plane { <0.00, 1.00, 0.00>, 0\n"\ | 
|---|
| 89 | "    texture {\n"\ | 
|---|
| 90 | "        pigment{ color rgb <0.25, 0.45, 0.00> }\n"\ | 
|---|
| 91 | "        normal { bumps 0.75 scale 0.01 }\n"\ | 
|---|
| 92 | "        finish { phong 0.10 }\n"\ | 
|---|
| 93 | "    }\n"\ | 
|---|
| 94 | "}\n" | 
|---|
| 95 |  | 
|---|
| 96 | #define POV_BOX \ | 
|---|
| 97 | "box { <%.3f, %.3f, %.3f>, <%.3f, %.3f, %.3f>\n" | 
|---|
| 98 |  | 
|---|
| 99 | #define POV_SCALE1 \ | 
|---|
| 100 | "scale %.3f\n" | 
|---|
| 101 |  | 
|---|
| 102 | #define POV_SCALE3 \ | 
|---|
| 103 | "scale    "POV_VECTOR3"\n" | 
|---|
| 104 |  | 
|---|
| 105 | #define POV_ROTATE \ | 
|---|
| 106 | "rotate   "POV_VECTOR3"\n" | 
|---|
| 107 |  | 
|---|
| 108 | #define POV_TRANSLATE \ | 
|---|
| 109 | "translate"POV_VECTOR3"\n" | 
|---|
| 110 |  | 
|---|
| 111 | #define END \ | 
|---|
| 112 | "}\n" | 
|---|
| 113 |  | 
|---|
| 114 | #define POV_TORUS \ | 
|---|
| 115 | "torus { %.3f, %.3f\n" | 
|---|
| 116 |  | 
|---|
| 117 | #define POV_SPHERE_SWEEP \ | 
|---|
| 118 | "sphere_sweep {\n"\ | 
|---|
| 119 | "    %s\n"\ | 
|---|
| 120 | "    %d,\n" | 
|---|
| 121 |  | 
|---|
| 122 | #define POV_SPHERE \ | 
|---|
| 123 | "sphere {"POV_VECTOR3", 1.0\n"	// center, radius | 
|---|
| 124 |  | 
|---|
| 125 | #define POV_TEXT \ | 
|---|
| 126 | "text {\n"\ | 
|---|
| 127 | "    ttf \"%s\",\n"\ | 
|---|
| 128 | "    \"%s\", %.3f, %.3f\n" | 
|---|
| 129 |  | 
|---|
| 130 | #define POV_DECLARE \ | 
|---|
| 131 | "#declare %s = %s;\n" | 
|---|
| 132 |  | 
|---|
| 133 | #define POV_OBJECT \ | 
|---|
| 134 | "object { %s }\n" | 
|---|
| 135 |  | 
|---|
| 136 | #define POV_VERBATIM \ | 
|---|
| 137 | "%s\n" | 
|---|
| 138 |  | 
|---|
| 139 | #define POV_DEBUG \ | 
|---|
| 140 | "#debug %s\n" | 
|---|
| 141 |  | 
|---|
| 142 | #define POV_POLYGON \ | 
|---|
| 143 | "polygon { %d,\n" | 
|---|
| 144 |  | 
|---|
| 145 | #define POV_VECTOR3 \ | 
|---|
| 146 | "<%9.3f, %9.3f, %9.3f>" | 
|---|
| 147 |  | 
|---|
| 148 | #define POV_PIGMENT_COLOR \ | 
|---|
| 149 | "pigment { color %s }\n" | 
|---|
| 150 |  | 
|---|
| 151 | #define POV_COLOR_NAME \ | 
|---|
| 152 | "%s transmit %.3f" | 
|---|
| 153 |  | 
|---|
| 154 | #define POV_COLOR_RGB \ | 
|---|
| 155 | "rgb"POV_VECTOR3" transmit %.3f" | 
|---|
| 156 |  | 
|---|
| 157 | //colors are taken from /usr/share/povray-3.6/include/colors.inc | 
|---|
| 158 | //list must be LANG_C sorted (all lower case) | 
|---|
| 159 | #define POV_COLORS \ | 
|---|
| 160 | "aquamarine",\ | 
|---|
| 161 | "bakerschoc",\ | 
|---|
| 162 | "black",\ | 
|---|
| 163 | "blue",\ | 
|---|
| 164 | "blueviolet",\ | 
|---|
| 165 | "brass",\ | 
|---|
| 166 | "brightgold",\ | 
|---|
| 167 | "bronze",\ | 
|---|
| 168 | "bronze2",\ | 
|---|
| 169 | "brown",\ | 
|---|
| 170 | "cadetblue",\ | 
|---|
| 171 | "clear",\ | 
|---|
| 172 | "coolcopper",\ | 
|---|
| 173 | "copper",\ | 
|---|
| 174 | "coral",\ | 
|---|
| 175 | "cornflowerblue",\ | 
|---|
| 176 | "cyan",\ | 
|---|
| 177 | "darkbrown",\ | 
|---|
| 178 | "darkgreen",\ | 
|---|
| 179 | "darkolivegreen",\ | 
|---|
| 180 | "darkorchid",\ | 
|---|
| 181 | "darkpurple",\ | 
|---|
| 182 | "darkslateblue",\ | 
|---|
| 183 | "darkslategray",\ | 
|---|
| 184 | "darkslategrey",\ | 
|---|
| 185 | "darktan",\ | 
|---|
| 186 | "darkturquoise",\ | 
|---|
| 187 | "darkwood",\ | 
|---|
| 188 | "dkgreencopper",\ | 
|---|
| 189 | "dustyrose",\ | 
|---|
| 190 | "feldspar",\ | 
|---|
| 191 | "firebrick",\ | 
|---|
| 192 | "flesh",\ | 
|---|
| 193 | "forestgreen",\ | 
|---|
| 194 | "gold",\ | 
|---|
| 195 | "goldenrod",\ | 
|---|
| 196 | "gray05",\ | 
|---|
| 197 | "gray10",\ | 
|---|
| 198 | "gray15",\ | 
|---|
| 199 | "gray20",\ | 
|---|
| 200 | "gray25",\ | 
|---|
| 201 | "gray30",\ | 
|---|
| 202 | "gray35",\ | 
|---|
| 203 | "gray40",\ | 
|---|
| 204 | "gray45",\ | 
|---|
| 205 | "gray50",\ | 
|---|
| 206 | "gray55",\ | 
|---|
| 207 | "gray60",\ | 
|---|
| 208 | "gray65",\ | 
|---|
| 209 | "gray70",\ | 
|---|
| 210 | "gray75",\ | 
|---|
| 211 | "gray80",\ | 
|---|
| 212 | "gray85",\ | 
|---|
| 213 | "gray90",\ | 
|---|
| 214 | "gray95",\ | 
|---|
| 215 | "green",\ | 
|---|
| 216 | "greencopper",\ | 
|---|
| 217 | "greenyellow",\ | 
|---|
| 218 | "huntersgreen",\ | 
|---|
| 219 | "indianred",\ | 
|---|
| 220 | "khaki",\ | 
|---|
| 221 | "lightblue",\ | 
|---|
| 222 | "light_purple",\ | 
|---|
| 223 | "lightsteelblue",\ | 
|---|
| 224 | "lightwood",\ | 
|---|
| 225 | "limegreen",\ | 
|---|
| 226 | "magenta",\ | 
|---|
| 227 | "mandarinorange",\ | 
|---|
| 228 | "maroon",\ | 
|---|
| 229 | "mediumaquamarine",\ | 
|---|
| 230 | "mediumblue",\ | 
|---|
| 231 | "mediumforestgreen",\ | 
|---|
| 232 | "mediumgoldenrod",\ | 
|---|
| 233 | "mediumorchid",\ | 
|---|
| 234 | "mediumseagreen",\ | 
|---|
| 235 | "mediumslateblue",\ | 
|---|
| 236 | "mediumspringgreen",\ | 
|---|
| 237 | "mediumturquoise",\ | 
|---|
| 238 | "mediumvioletred",\ | 
|---|
| 239 | "mediumwood",\ | 
|---|
| 240 | "med_purple",\ | 
|---|
| 241 | "mica",\ | 
|---|
| 242 | "midnightblue",\ | 
|---|
| 243 | "navy",\ | 
|---|
| 244 | "navyblue",\ | 
|---|
| 245 | "neonblue",\ | 
|---|
| 246 | "neonpink",\ | 
|---|
| 247 | "newmidnightblue",\ | 
|---|
| 248 | "newtan",\ | 
|---|
| 249 | "oldgold",\ | 
|---|
| 250 | "orange",\ | 
|---|
| 251 | "orangered",\ | 
|---|
| 252 | "orchid",\ | 
|---|
| 253 | "palegreen",\ | 
|---|
| 254 | "pink",\ | 
|---|
| 255 | "plum",\ | 
|---|
| 256 | "quartz",\ | 
|---|
| 257 | "red",\ | 
|---|
| 258 | "richblue",\ | 
|---|
| 259 | "salmon",\ | 
|---|
| 260 | "scarlet",\ | 
|---|
| 261 | "seagreen",\ | 
|---|
| 262 | "semiSweetChoc",\ | 
|---|
| 263 | "sienna",\ | 
|---|
| 264 | "silver",\ | 
|---|
| 265 | "skyblue",\ | 
|---|
| 266 | "slateblue",\ | 
|---|
| 267 | "spicypink",\ | 
|---|
| 268 | "springgreen",\ | 
|---|
| 269 | "steelblue",\ | 
|---|
| 270 | "summersky",\ | 
|---|
| 271 | "tan",\ | 
|---|
| 272 | "thistle",\ | 
|---|
| 273 | "turquoise",\ | 
|---|
| 274 | "verydarkbrown",\ | 
|---|
| 275 | "very_light_purple",\ | 
|---|
| 276 | "violet",\ | 
|---|
| 277 | "violetred",\ | 
|---|
| 278 | "wheat",\ | 
|---|
| 279 | "white",\ | 
|---|
| 280 | "yellow",\ | 
|---|
| 281 | "yellowgreen" | 
|---|
| 282 |  | 
|---|
| 283 | #define GV_OBJ_EXT(type, obj, name) \ | 
|---|
| 284 | do { \ | 
|---|
| 285 | char debug_str[256]; \ | 
|---|
| 286 | gvprintf(job, POV_DECLARE, type, obj); \ | 
|---|
| 287 | gvprintf(job, POV_OBJECT, type); \ | 
|---|
| 288 | gvprintf(job, POV_DECLARE, "Min", "min_extent("type")"); \ | 
|---|
| 289 | gvprintf(job, POV_DECLARE, "Max", "max_extent("type")"); \ | 
|---|
| 290 | snprintf(debug_str, 256,  \ | 
|---|
| 291 | "concat(\"Dim = \" , vstr(3, Max - Min, \", \", 0, 3)," \ | 
|---|
| 292 | " \" "type": %s\", \"\\n\")", name); \ | 
|---|
| 293 | gvprintf(job, POV_DEBUG, debug_str); \ | 
|---|
| 294 | } while (0) | 
|---|
| 295 |  | 
|---|
| 296 | /* | 
|---|
| 297 | //png, gif, NO jpg! | 
|---|
| 298 | pigment | 
|---|
| 299 | { image_map | 
|---|
| 300 | { gif "image.gif" | 
|---|
| 301 | map_type 1 | 
|---|
| 302 | } | 
|---|
| 303 | } | 
|---|
| 304 | */ | 
|---|
| 305 |  | 
|---|
| 306 | /* | 
|---|
| 307 | #declare Sphere = | 
|---|
| 308 | sphere { | 
|---|
| 309 | <0,0,0>, 1 | 
|---|
| 310 | pigment { rgb <1,0,0> } | 
|---|
| 311 | } | 
|---|
| 312 | #declare Min = min_extent ( Sphere ); | 
|---|
| 313 | #declare Max = max_extent ( Sphere ); | 
|---|
| 314 | object { Sphere } | 
|---|
| 315 | box { | 
|---|
| 316 | Min, Max | 
|---|
| 317 | pigment { rgbf <1,1,1,0.5> } | 
|---|
| 318 | scale<20,20,20> | 
|---|
| 319 | } | 
|---|
| 320 | */ | 
|---|
| 321 |  | 
|---|
| 322 | /* | 
|---|
| 323 | STRING functions | 
|---|
| 324 |  | 
|---|
| 325 | str( float , min_len , digits_after_dot ) | 
|---|
| 326 | concat( STRING , STRING , [STRING ,...]) | 
|---|
| 327 | chr( INT ) | 
|---|
| 328 | substr( STRING , INT , INT ) | 
|---|
| 329 | strupr( STRING ) | 
|---|
| 330 | strlwr( STRING ) | 
|---|
| 331 | vstr( vec_dimension , vec, sep_str, min_len, digits_after_dot ) | 
|---|
| 332 |  | 
|---|
| 333 | examples: | 
|---|
| 334 | #debug vstr(3, Min, ", ", 0, 3) | 
|---|
| 335 | #debug "\n*****************\n" | 
|---|
| 336 | #debug concat ( "Max =", vstr(3, Max, ", ", 0, 3), chr(13), chr(10) ) | 
|---|
| 337 | */ | 
|---|
| 338 |  | 
|---|
| 339 |  | 
|---|
| 340 | #define DPI 72.0 | 
|---|
| 341 | #define RENDERER_COLOR_TYPE RGBA_BYTE | 
|---|
| 342 | typedef enum { FORMAT_POV, } format_type; | 
|---|
| 343 |  | 
|---|
| 344 | //#define DEBUG | 
|---|
| 345 |  | 
|---|
| 346 | //TODO: check why this dot file does not work (90 rotated) | 
|---|
| 347 | //   /usr/share/graphviz/graphs/directed/NaN.gv | 
|---|
| 348 | //TODO: add Texttures | 
|---|
| 349 | //TODO: check how we can receive attributes from dot file | 
|---|
| 350 | //   if we can't receive attributes set defaults in pov include file | 
|---|
| 351 | //   - put #include "graph-scheme-fancy.inc" in pov file | 
|---|
| 352 | //   - run povray with +L`pwd` | 
|---|
| 353 | //   - put e.g. #declare mycolor = Gold; in graph-scheme-fancy.inc | 
|---|
| 354 | //   - use textures and color: pigment { color mycolor transmit 0.000 } | 
|---|
| 355 | //TODO: idea, put the whole graph in a declare= and then | 
|---|
| 356 | //   print it with something along the line: | 
|---|
| 357 | //   object{ graph translate{page->translation, ...} rotate{page->rotation, ...} } | 
|---|
| 358 |  | 
|---|
| 359 | static char *pov_knowncolors[] = { POV_COLORS }; | 
|---|
| 360 |  | 
|---|
| 361 | static float layerz = 0; | 
|---|
| 362 | static float z = 0; | 
|---|
| 363 |  | 
|---|
| 364 | char *el(GVJ_t* job, char *template, ...) | 
|---|
| 365 | { | 
|---|
| 366 | #if defined(HAVE_VASPRINTF) | 
|---|
| 367 | char *str; | 
|---|
| 368 | va_list arglist; | 
|---|
| 369 |  | 
|---|
| 370 | va_start(arglist, template); | 
|---|
| 371 | vasprintf(&str, template, arglist); | 
|---|
| 372 | va_end(arglist); | 
|---|
| 373 |  | 
|---|
| 374 | return str; | 
|---|
| 375 | #elif defined(HAVE_VSNPRINTF) | 
|---|
| 376 | char buf[BUFSIZ]; | 
|---|
| 377 | int len; | 
|---|
| 378 | char *str; | 
|---|
| 379 | va_list arglist; | 
|---|
| 380 |  | 
|---|
| 381 | va_start(arglist, template); | 
|---|
| 382 | len = vsnprintf((char *)buf, BUFSIZ, template, arglist); | 
|---|
| 383 | if (len < 0) { | 
|---|
| 384 | job->common->errorfn( "pov renderer:el - %s\n", strerror(errno)); | 
|---|
| 385 | str = strdup ( ""); | 
|---|
| 386 | } | 
|---|
| 387 | else if (len >= BUFSIZ) { | 
|---|
| 388 | str = malloc (len+1); | 
|---|
| 389 | va_end(arglist); | 
|---|
| 390 | va_start(arglist, template); | 
|---|
| 391 | len = vsprintf(str, template, arglist); | 
|---|
| 392 | } | 
|---|
| 393 | else { | 
|---|
| 394 | str = strdup (buf); | 
|---|
| 395 | } | 
|---|
| 396 | va_end(arglist); | 
|---|
| 397 |  | 
|---|
| 398 | return str; | 
|---|
| 399 | #else | 
|---|
| 400 | /* Dummy function that will never be used */ | 
|---|
| 401 | return strdup( ""); | 
|---|
| 402 | #endif | 
|---|
| 403 | } | 
|---|
| 404 |  | 
|---|
| 405 | static char *pov_color_as_str(GVJ_t * job, gvcolor_t color, float transparency) | 
|---|
| 406 | { | 
|---|
| 407 | char *pov, *c = NULL; | 
|---|
| 408 | switch (color.type) { | 
|---|
| 409 | case COLOR_STRING: | 
|---|
| 410 | #ifdef DEBUG | 
|---|
| 411 | gvprintf(job, "// type = %d, color = %s\n", color.type, color.u.string); | 
|---|
| 412 | #endif | 
|---|
| 413 | if (!strcmp(color.u.string, "red")) | 
|---|
| 414 | c = el(job, POV_COLOR_NAME, "Red", transparency); | 
|---|
| 415 | else if (!strcmp(color.u.string, "green")) | 
|---|
| 416 | c = el(job, POV_COLOR_NAME, "Green", transparency); | 
|---|
| 417 | else if (!strcmp(color.u.string, "blue")) | 
|---|
| 418 | c = el(job, POV_COLOR_NAME, "Blue", transparency); | 
|---|
| 419 | else | 
|---|
| 420 | c = el(job, POV_COLOR_NAME, color.u.string, transparency); | 
|---|
| 421 | break; | 
|---|
| 422 | case RENDERER_COLOR_TYPE: | 
|---|
| 423 | #ifdef DEBUG | 
|---|
| 424 | gvprintf(job, "// type = %d, color = %d, %d, %d\n", | 
|---|
| 425 | color.type, color.u.rgba[0], color.u.rgba[1], | 
|---|
| 426 | color.u.rgba[2]); | 
|---|
| 427 | #endif | 
|---|
| 428 | c = el(job, POV_COLOR_RGB, | 
|---|
| 429 | color.u.rgba[0] / 256.0, color.u.rgba[1] / 256.0, | 
|---|
| 430 | color.u.rgba[2] / 256.0, transparency); | 
|---|
| 431 | break; | 
|---|
| 432 | default: | 
|---|
| 433 | fprintf(stderr, | 
|---|
| 434 | "oops, internal error: unhandled color type=%d %s\n", | 
|---|
| 435 | color.type, color.u.string); | 
|---|
| 436 | assert(0);	//oops, wrong type set in gvrender_features_t? | 
|---|
| 437 | } | 
|---|
| 438 | pov = el(job, POV_PIGMENT_COLOR, c); | 
|---|
| 439 | free(c); | 
|---|
| 440 | return pov; | 
|---|
| 441 | } | 
|---|
| 442 |  | 
|---|
| 443 | static void (GVJ_t * job, char *str) | 
|---|
| 444 | { | 
|---|
| 445 | gvprintf(job, "//*** comment: %s\n", str); | 
|---|
| 446 | } | 
|---|
| 447 |  | 
|---|
| 448 | static void pov_begin_job(GVJ_t * job) | 
|---|
| 449 | { | 
|---|
| 450 | gvputs(job, POV_VERSION); | 
|---|
| 451 | gvputs(job, POV_GLOBALS); | 
|---|
| 452 | gvputs(job, POV_DEFAULT); | 
|---|
| 453 | gvputs(job, POV_INCLUDE); | 
|---|
| 454 | gvprintf(job, POV_DECLARE, "black", "Black"); | 
|---|
| 455 | gvprintf(job, POV_DECLARE, "white", "White"); | 
|---|
| 456 | } | 
|---|
| 457 |  | 
|---|
| 458 | static void pov_begin_graph(GVJ_t * job) | 
|---|
| 459 | { | 
|---|
| 460 | float x, y, d, px, py; | 
|---|
| 461 |  | 
|---|
| 462 | gvprintf(job, "//*** begin_graph %s\n", agnameof(job->obj->u.g)); | 
|---|
| 463 | #ifdef DEBUG | 
|---|
| 464 | gvprintf(job, "// graph_index = %d, pages = %d, layer = %d/%d\n", | 
|---|
| 465 | job->graph_index, job->numPages, job->layerNum, | 
|---|
| 466 | job->numLayers); | 
|---|
| 467 | gvprintf(job, "// pagesArraySize.x,y = %d,%d\n", job->pagesArraySize.x, | 
|---|
| 468 | job->pagesArraySize.y); | 
|---|
| 469 | gvprintf(job, "// pagesArrayFirst.x,y = %d,%d\n", | 
|---|
| 470 | job->pagesArrayFirst.x, job->pagesArrayFirst.y); | 
|---|
| 471 | gvprintf(job, "// pagesArrayElem.x,y = %d,%d\n", job->pagesArrayElem.x, | 
|---|
| 472 | job->pagesArrayElem.y); | 
|---|
| 473 | gvprintf(job, "// bb.LL,UR = %.3f,%.3f, %.3f,%.3f\n", job->bb.LL.x, | 
|---|
| 474 | job->bb.LL.y, job->bb.UR.x, job->bb.UR.y); | 
|---|
| 475 | gvprintf(job, "// pageBox in graph LL,UR = %.3f,%.3f, %.3f,%.3f\n", | 
|---|
| 476 | job->pageBox.LL.x, job->pageBox.LL.y, job->pageBox.UR.x, | 
|---|
| 477 | job->pageBox.UR.y); | 
|---|
| 478 | gvprintf(job, "// pageSize.x,y = %.3f,%.3f\n", job->pageSize.x, | 
|---|
| 479 | job->pageSize.y); | 
|---|
| 480 | gvprintf(job, "// focus.x,y = %.3f,%.3f\n", job->focus.x, job->focus.y); | 
|---|
| 481 | gvprintf(job, "// zoom = %.3f, rotation = %d\n", job->zoom, | 
|---|
| 482 | (float)job->rotation); | 
|---|
| 483 | gvprintf(job, "// view port.x,y = %.3f,%.3f\n", job->view.x, | 
|---|
| 484 | job->view.y); | 
|---|
| 485 | gvprintf(job, "// canvasBox LL,UR = %.3f,%.3f, %.3f,%.3f\n", | 
|---|
| 486 | job->canvasBox.LL.x, job->canvasBox.LL.y, job->canvasBox.UR.x, | 
|---|
| 487 | job->canvasBox.UR.y); | 
|---|
| 488 | gvprintf(job, "// pageBoundingBox LL,UR = %d,%d, %d,%d\n", | 
|---|
| 489 | job->pageBoundingBox.LL.x, job->pageBoundingBox.LL.y, | 
|---|
| 490 | job->pageBoundingBox.UR.x, job->pageBoundingBox.UR.y); | 
|---|
| 491 | gvprintf(job, "// boundingBox (all pages) LL,UR = %d,%d, %d,%d\n", | 
|---|
| 492 | job->boundingBox.LL.x, job->boundingBox.LL.y, | 
|---|
| 493 | job->boundingBox.UR.x, job->boundingBox.UR.y); | 
|---|
| 494 | gvprintf(job, "// scale.x,y = %.3f,%.3f\n", job->scale.x, job->scale.y); | 
|---|
| 495 | gvprintf(job, "// translation.x,y = %.3f,%.3f\n", job->translation.x, | 
|---|
| 496 | job->translation.y); | 
|---|
| 497 | gvprintf(job, "// devscale.x,y = %.3f,%.3f\n", job->devscale.x, | 
|---|
| 498 | job->devscale.y); | 
|---|
| 499 | gvprintf(job, "// verbose = %d\n", job->common->verbose); | 
|---|
| 500 | gvprintf(job, "// cmd = %s\n", job->common->cmdname); | 
|---|
| 501 | gvprintf(job, "// info = %s, %s, %s\n", job->common->info[0], | 
|---|
| 502 | job->common->info[1], job->common->info[2]); | 
|---|
| 503 | #endif | 
|---|
| 504 |  | 
|---|
| 505 | //setup scene | 
|---|
| 506 | x = job->view.x / 2.0 * job->scale.x; | 
|---|
| 507 | y = job->view.y / 2.0 * job->scale.y; | 
|---|
| 508 | d = -500; | 
|---|
| 509 | px = atanf(x / fabsf(d)) * 180 / M_PI * 2; | 
|---|
| 510 | py = atanf(y / fabsf(d)) * 180 / M_PI * 2; | 
|---|
| 511 | gvprintf(job, POV_CAMERA, x, y, d, x, y, 0.0, | 
|---|
| 512 | (px > py ? px : py) * 1.2); | 
|---|
| 513 | gvputs(job, POV_SKY_AND_GND); | 
|---|
| 514 | gvputs(job, POV_LIGHT); | 
|---|
| 515 | } | 
|---|
| 516 |  | 
|---|
| 517 | static void pov_end_graph(GVJ_t * job) | 
|---|
| 518 | { | 
|---|
| 519 | gvputs(job, "//*** end_graph\n"); | 
|---|
| 520 | } | 
|---|
| 521 |  | 
|---|
| 522 | static void pov_begin_layer(GVJ_t * job, char *layername, int layerNum, int numLayers) | 
|---|
| 523 | { | 
|---|
| 524 | gvprintf(job, "//*** begin_layer: %s, %d/%d\n", layername, layerNum, | 
|---|
| 525 | numLayers); | 
|---|
| 526 | layerz = layerNum * -10; | 
|---|
| 527 | } | 
|---|
| 528 |  | 
|---|
| 529 | static void pov_end_layer(GVJ_t * job) | 
|---|
| 530 | { | 
|---|
| 531 | gvputs(job, "//*** end_layer\n"); | 
|---|
| 532 | } | 
|---|
| 533 |  | 
|---|
| 534 | static void pov_begin_page(GVJ_t * job) | 
|---|
| 535 | { | 
|---|
| 536 | gvputs(job, "//*** begin_page\n"); | 
|---|
| 537 | } | 
|---|
| 538 |  | 
|---|
| 539 | static void pov_end_page(GVJ_t * job) | 
|---|
| 540 | { | 
|---|
| 541 | gvputs(job, "//*** end_page\n"); | 
|---|
| 542 | } | 
|---|
| 543 |  | 
|---|
| 544 | static void pov_begin_cluster(GVJ_t * job) | 
|---|
| 545 | { | 
|---|
| 546 | gvputs(job, "//*** begin_cluster\n"); | 
|---|
| 547 | layerz -= 2; | 
|---|
| 548 | } | 
|---|
| 549 |  | 
|---|
| 550 | static void pov_end_cluster(GVJ_t * job) | 
|---|
| 551 | { | 
|---|
| 552 | gvputs(job, "//*** end_cluster\n"); | 
|---|
| 553 | } | 
|---|
| 554 |  | 
|---|
| 555 | static void pov_begin_node(GVJ_t * job) | 
|---|
| 556 | { | 
|---|
| 557 | gvprintf(job, "//*** begin_node: %s\n", agnameof(job->obj->u.n)); | 
|---|
| 558 | } | 
|---|
| 559 |  | 
|---|
| 560 | static void pov_end_node(GVJ_t * job) | 
|---|
| 561 | { | 
|---|
| 562 | gvputs(job, "//*** end_node\n"); | 
|---|
| 563 | } | 
|---|
| 564 |  | 
|---|
| 565 | static void pov_begin_edge(GVJ_t * job) | 
|---|
| 566 | { | 
|---|
| 567 | gvputs(job, "//*** begin_edge\n"); | 
|---|
| 568 | layerz -= 5; | 
|---|
| 569 | #ifdef DEBUG | 
|---|
| 570 | gvprintf(job, "// layerz = %.3f\n", layerz); | 
|---|
| 571 | #endif | 
|---|
| 572 | } | 
|---|
| 573 |  | 
|---|
| 574 | static void pov_end_edge(GVJ_t * job) | 
|---|
| 575 | { | 
|---|
| 576 | gvputs(job, "//*** end_edge\n"); | 
|---|
| 577 | layerz += 5; | 
|---|
| 578 | #ifdef DEBUG | 
|---|
| 579 | gvprintf(job, "// layerz = %.3f\n", layerz); | 
|---|
| 580 | #endif | 
|---|
| 581 | } | 
|---|
| 582 |  | 
|---|
| 583 | static void pov_textspan(GVJ_t * job, pointf c, textspan_t * span) | 
|---|
| 584 | { | 
|---|
| 585 | double x, y; | 
|---|
| 586 | char *pov, *s, *r, *t, *p; | 
|---|
| 587 |  | 
|---|
| 588 | gvprintf(job, "//*** textspan: %s, fontsize = %.3f, fontname = %s\n", | 
|---|
| 589 | span->str, span->font->size, span->font->name); | 
|---|
| 590 | z = layerz - 9; | 
|---|
| 591 |  | 
|---|
| 592 | #ifdef DEBUG | 
|---|
| 593 | if (span->font->postscript_alias) | 
|---|
| 594 | gvputs(job, "// Warning: postscript_alias not handled!\n"); | 
|---|
| 595 | #endif | 
|---|
| 596 |  | 
|---|
| 597 | //handle text justification | 
|---|
| 598 | switch (span->just) { | 
|---|
| 599 | case 'l':		//left justified | 
|---|
| 600 | break; | 
|---|
| 601 | case 'r':		//right justified | 
|---|
| 602 | c.x = c.x - span->size.x; | 
|---|
| 603 | break; | 
|---|
| 604 | default: | 
|---|
| 605 | case 'n':		//centered | 
|---|
| 606 | c.x = c.x - span->size.x / 2.0; | 
|---|
| 607 | break; | 
|---|
| 608 | } | 
|---|
| 609 |  | 
|---|
| 610 | x = (c.x + job->translation.x) * job->scale.x; | 
|---|
| 611 | y = (c.y + job->translation.y) * job->scale.y; | 
|---|
| 612 |  | 
|---|
| 613 | s = el(job, POV_SCALE1, span->font->size * job->scale.x); | 
|---|
| 614 | r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation); | 
|---|
| 615 | t = el(job, POV_TRANSLATE, x, y, z); | 
|---|
| 616 | p = pov_color_as_str(job, job->obj->pencolor, 0.0); | 
|---|
| 617 |  | 
|---|
| 618 | //pov bundled fonts: timrom.ttf, cyrvetic.ttf | 
|---|
| 619 | pov = el(job, POV_TEXT "    %s    %s    %s    %s    %s"END, | 
|---|
| 620 | span->font->name, 0.25, 0.0,	//font, depth (0.5 ... 2.0), offset | 
|---|
| 621 | span->str, "    no_shadow\n", s, r, t, p); | 
|---|
| 622 |  | 
|---|
| 623 | #ifdef DEBUG | 
|---|
| 624 | GV_OBJ_EXT( "Text", pov, span->str); | 
|---|
| 625 | gvprintf(job, "sphere{<0, 0, 0>, 2\ntranslate<%f, %f, %f>\n" | 
|---|
| 626 | "pigment{color Red}\nno_shadow\n}\n", x, y, z - 1); | 
|---|
| 627 | #else | 
|---|
| 628 | gvputs(job, pov); | 
|---|
| 629 | #endif | 
|---|
| 630 |  | 
|---|
| 631 | free(pov); | 
|---|
| 632 | free(r); | 
|---|
| 633 | free(p); | 
|---|
| 634 | free(t); | 
|---|
| 635 | free(s); | 
|---|
| 636 | } | 
|---|
| 637 |  | 
|---|
| 638 | static void pov_ellipse(GVJ_t * job, pointf * A, int filled) | 
|---|
| 639 | { | 
|---|
| 640 | char *pov, *s, *r, *t, *p; | 
|---|
| 641 | float cx, cy, rx, ry, w; | 
|---|
| 642 |  | 
|---|
| 643 | gvputs(job, "//*** ellipse\n"); | 
|---|
| 644 | z = layerz - 6; | 
|---|
| 645 |  | 
|---|
| 646 | // A[0] center, A[1] corner of ellipse | 
|---|
| 647 | cx = (A[0].x + job->translation.x) * job->scale.x; | 
|---|
| 648 | cy = (A[0].y + job->translation.y) * job->scale.y; | 
|---|
| 649 | rx = (A[1].x - A[0].x) * job->scale.x; | 
|---|
| 650 | ry = (A[1].y - A[0].y) * job->scale.y; | 
|---|
| 651 | w = job->obj->penwidth / (rx + ry) / 2.0 * 5; | 
|---|
| 652 |  | 
|---|
| 653 | //draw rim (torus) | 
|---|
| 654 | s = el(job, POV_SCALE3, rx, (rx + ry) / 4.0, ry); | 
|---|
| 655 | r = el(job, POV_ROTATE, 90.0, 0.0, (float)job->rotation); | 
|---|
| 656 | t = el(job, POV_TRANSLATE, cx, cy, z); | 
|---|
| 657 | p = pov_color_as_str(job, job->obj->pencolor, 0.0); | 
|---|
| 658 |  | 
|---|
| 659 | pov = el(job, POV_TORUS "    %s    %s    %s    %s"END, 1.0, w,	//radius, size of ring | 
|---|
| 660 | s, r, t, p); | 
|---|
| 661 |  | 
|---|
| 662 | #ifdef DEBUG | 
|---|
| 663 | GV_OBJ_EXT( "Torus", pov, ""); | 
|---|
| 664 | gvprintf(job, "sphere{<0, 0, 0>, 2\ntranslate<%f, %f, %f>\n" | 
|---|
| 665 | "pigment{color Green}\nno_shadow\n}\n", cx, cy, z - 1); | 
|---|
| 666 | #else | 
|---|
| 667 | gvputs(job, pov); | 
|---|
| 668 | #endif | 
|---|
| 669 |  | 
|---|
| 670 | free(s); | 
|---|
| 671 | free(r); | 
|---|
| 672 | free(t); | 
|---|
| 673 | free(p); | 
|---|
| 674 | free(pov); | 
|---|
| 675 |  | 
|---|
| 676 | //backgroud of ellipse if filled | 
|---|
| 677 | if (filled) { | 
|---|
| 678 | s = el(job, POV_SCALE3, rx, ry, 1.0); | 
|---|
| 679 | r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation); | 
|---|
| 680 | t = el(job, POV_TRANSLATE, cx, cy, z); | 
|---|
| 681 | p = pov_color_as_str(job, job->obj->fillcolor, 0.0); | 
|---|
| 682 |  | 
|---|
| 683 | pov = el(job, POV_SPHERE "    %s    %s    %s    %s"END, | 
|---|
| 684 | 0.0, 0.0, 0.0, s, r, t, p); | 
|---|
| 685 |  | 
|---|
| 686 | gvputs(job, pov); | 
|---|
| 687 |  | 
|---|
| 688 | free(s); | 
|---|
| 689 | free(r); | 
|---|
| 690 | free(t); | 
|---|
| 691 | free(p); | 
|---|
| 692 | free(pov); | 
|---|
| 693 | } | 
|---|
| 694 | } | 
|---|
| 695 |  | 
|---|
| 696 | static void pov_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start, | 
|---|
| 697 | int arrow_at_end, int filled) | 
|---|
| 698 | { | 
|---|
| 699 | int i; | 
|---|
| 700 | char *v, *x; | 
|---|
| 701 | char *pov, *s, *r, *t, *p; | 
|---|
| 702 |  | 
|---|
| 703 | gvputs(job, "//*** bezier\n"); | 
|---|
| 704 | z = layerz - 4; | 
|---|
| 705 |  | 
|---|
| 706 | s = el(job, POV_SCALE3, job->scale.x, job->scale.y, 1.0); | 
|---|
| 707 | r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation); | 
|---|
| 708 | t = el(job, POV_TRANSLATE, 0.0, 0.0, z - 2); | 
|---|
| 709 | p = pov_color_as_str(job, job->obj->fillcolor, 0.0); | 
|---|
| 710 |  | 
|---|
| 711 | pov = el(job, POV_SPHERE_SWEEP, "b_spline", n + 2); | 
|---|
| 712 |  | 
|---|
| 713 | for (i = 0; i < n; i++) { | 
|---|
| 714 | v = el(job, POV_VECTOR3 ", %.3f\n", A[i].x + job->translation.x, A[i].y + job->translation.y, 0.0, job->obj->penwidth);	//z coordinate, thickness | 
|---|
| 715 | x = el(job, "%s    %s", pov, v);	//catenate pov & vector v | 
|---|
| 716 | free(v); | 
|---|
| 717 | free(pov); | 
|---|
| 718 | pov = x; | 
|---|
| 719 |  | 
|---|
| 720 | //TODO: we currently just use the start and end points of the curve as | 
|---|
| 721 | //control points but we should use center of nodes | 
|---|
| 722 | if (i == 0 || i == n - 1) { | 
|---|
| 723 | v = el(job, POV_VECTOR3 ", %.3f\n", A[i].x + job->translation.x, A[i].y + job->translation.y, 0.0, job->obj->penwidth);	//z coordinate, thickness | 
|---|
| 724 | x = el(job, "%s    %s", pov, v);	//catenate pov & vector v | 
|---|
| 725 | free(v); | 
|---|
| 726 | free(pov); | 
|---|
| 727 | pov = x; | 
|---|
| 728 | } | 
|---|
| 729 | #ifdef DEBUG | 
|---|
| 730 | gvprintf(job, "sphere{<0, 0, 0>, 2\ntranslate<%f, %f, %f>\n" | 
|---|
| 731 | "pigment{color Yellow}\nno_shadow\n}\n", | 
|---|
| 732 | (A[i].x + job->translation.x) * job->scale.x, | 
|---|
| 733 | (A[i].y + job->translation.y) * job->scale.y, z - 2); | 
|---|
| 734 | #endif | 
|---|
| 735 | } | 
|---|
| 736 | x = el(job, "        tolerance 0.01\n    %s    %s    %s    %s"END, s, r, t, | 
|---|
| 737 | p); | 
|---|
| 738 | pov = el(job, "%s%s", pov, x);	//catenate pov & end str | 
|---|
| 739 | free(x); | 
|---|
| 740 |  | 
|---|
| 741 | gvputs(job, pov); | 
|---|
| 742 |  | 
|---|
| 743 | free(s); | 
|---|
| 744 | free(r); | 
|---|
| 745 | free(t); | 
|---|
| 746 | free(p); | 
|---|
| 747 | free(pov); | 
|---|
| 748 | } | 
|---|
| 749 |  | 
|---|
| 750 | static void pov_polygon(GVJ_t * job, pointf * A, int n, int filled) | 
|---|
| 751 | { | 
|---|
| 752 | char *pov, *s, *r, *t, *p, *v, *x; | 
|---|
| 753 | int i; | 
|---|
| 754 |  | 
|---|
| 755 | gvputs(job, "//*** polygon\n"); | 
|---|
| 756 | z = layerz - 2; | 
|---|
| 757 |  | 
|---|
| 758 | s = el(job, POV_SCALE3, job->scale.x, job->scale.y, 1.0); | 
|---|
| 759 | r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation); | 
|---|
| 760 | t = el(job, POV_TRANSLATE, 0.0, 0.0, z - 2); | 
|---|
| 761 | p = pov_color_as_str(job, job->obj->pencolor, 0.0); | 
|---|
| 762 |  | 
|---|
| 763 | pov = el(job, POV_SPHERE_SWEEP, "linear_spline", n + 1); | 
|---|
| 764 |  | 
|---|
| 765 | for (i = 0; i < n; i++) { | 
|---|
| 766 | v = el(job, POV_VECTOR3 ", %.3f\n", A[i].x + job->translation.x, A[i].y + job->translation.y, 0.0, job->obj->penwidth);	//z coordinate, thickness | 
|---|
| 767 | x = el(job, "%s    %s", pov, v);	//catenate pov & vector v | 
|---|
| 768 | free(v); | 
|---|
| 769 | free(pov); | 
|---|
| 770 | pov = x; | 
|---|
| 771 | } | 
|---|
| 772 |  | 
|---|
| 773 | //close polygon, add starting point as final point^ | 
|---|
| 774 | v = el(job, POV_VECTOR3 ", %.3f\n", A[0].x + job->translation.x, A[0].y + job->translation.y, 0.0, job->obj->penwidth);	//z coordinate, thickness | 
|---|
| 775 |  | 
|---|
| 776 | x = el(job, "%s    %s", pov, v);	//catenate pov & vector v | 
|---|
| 777 | free(v); | 
|---|
| 778 | free(pov); | 
|---|
| 779 | pov = x; | 
|---|
| 780 |  | 
|---|
| 781 | x = el(job, "    tolerance 0.1\n    %s    %s    %s    %s"END, s, r, t, p); | 
|---|
| 782 | pov = el(job, "%s%s", pov, x);	//catenate pov & end str | 
|---|
| 783 | free(x); | 
|---|
| 784 |  | 
|---|
| 785 | gvputs(job, pov); | 
|---|
| 786 |  | 
|---|
| 787 | free(s); | 
|---|
| 788 | free(r); | 
|---|
| 789 | free(t); | 
|---|
| 790 | free(p); | 
|---|
| 791 | free(pov); | 
|---|
| 792 |  | 
|---|
| 793 | //create fill background | 
|---|
| 794 | if (filled) { | 
|---|
| 795 | s = el(job, POV_SCALE3, job->scale.x, job->scale.y, 1.0); | 
|---|
| 796 | r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation); | 
|---|
| 797 | t = el(job, POV_TRANSLATE, 0.0, 0.0, z - 2); | 
|---|
| 798 | p = pov_color_as_str(job, job->obj->fillcolor, 0.25); | 
|---|
| 799 |  | 
|---|
| 800 | pov = el(job, POV_POLYGON, n); | 
|---|
| 801 |  | 
|---|
| 802 | for (i = 0; i < n; i++) { | 
|---|
| 803 | //create on z = 0 plane, then translate to real z pos | 
|---|
| 804 | v = el(job, POV_VECTOR3, | 
|---|
| 805 | A[i].x + job->translation.x, | 
|---|
| 806 | A[i].y + job->translation.y, 0.0); | 
|---|
| 807 | x = el(job, "%s\n    %s", pov, v);	//catenate pov & vector v | 
|---|
| 808 | free(v); | 
|---|
| 809 | free(pov); | 
|---|
| 810 | pov = x; | 
|---|
| 811 | } | 
|---|
| 812 | x = el(job, "\n    %s    %s    %s    %s"END, s, r, t, p); | 
|---|
| 813 | pov = el(job, "%s%s", pov, x);	//catenate pov & end str | 
|---|
| 814 | free(x); | 
|---|
| 815 |  | 
|---|
| 816 | gvputs(job, pov); | 
|---|
| 817 |  | 
|---|
| 818 | free(s); | 
|---|
| 819 | free(r); | 
|---|
| 820 | free(t); | 
|---|
| 821 | free(p); | 
|---|
| 822 | free(pov); | 
|---|
| 823 | } | 
|---|
| 824 | } | 
|---|
| 825 |  | 
|---|
| 826 | static void pov_polyline(GVJ_t * job, pointf * A, int n) | 
|---|
| 827 | { | 
|---|
| 828 | char *pov, *s, *r, *t, *p, *v, *x; | 
|---|
| 829 | int i; | 
|---|
| 830 |  | 
|---|
| 831 | gvputs(job, "//*** polyline\n"); | 
|---|
| 832 | z = layerz - 6; | 
|---|
| 833 |  | 
|---|
| 834 | s = el(job, POV_SCALE3, job->scale.x, job->scale.y, 1.0); | 
|---|
| 835 | r = el(job, POV_ROTATE, 0.0, 0.0, (float)job->rotation); | 
|---|
| 836 | t = el(job, POV_TRANSLATE, 0.0, 0.0, z); | 
|---|
| 837 | p = pov_color_as_str(job, job->obj->pencolor, 0.0); | 
|---|
| 838 |  | 
|---|
| 839 | pov = el(job, POV_SPHERE_SWEEP, "linear_spline", n); | 
|---|
| 840 |  | 
|---|
| 841 | for (i = 0; i < n; i++) { | 
|---|
| 842 | v = el(job, POV_VECTOR3 ", %.3f\n", A[i].x + job->translation.x, A[i].y + job->translation.y, 0.0, job->obj->penwidth);	//z coordinate, thickness | 
|---|
| 843 | x = el(job, "%s    %s", pov, v);	//catenate pov & vector v | 
|---|
| 844 | free(v); | 
|---|
| 845 | free(pov); | 
|---|
| 846 | pov = x; | 
|---|
| 847 | } | 
|---|
| 848 |  | 
|---|
| 849 | x = el(job, "    tolerance 0.01\n    %s    %s    %s    %s"END, s, r, t, p); | 
|---|
| 850 | pov = el(job, "%s%s", pov, x);	//catenate pov & end str | 
|---|
| 851 | free(x); | 
|---|
| 852 |  | 
|---|
| 853 | gvputs(job, pov); | 
|---|
| 854 |  | 
|---|
| 855 | free(s); | 
|---|
| 856 | free(r); | 
|---|
| 857 | free(t); | 
|---|
| 858 | free(p); | 
|---|
| 859 | free(pov); | 
|---|
| 860 | } | 
|---|
| 861 |  | 
|---|
| 862 | gvrender_engine_t pov_engine = { | 
|---|
| 863 | pov_begin_job, | 
|---|
| 864 | 0,			/* pov_end_job */ | 
|---|
| 865 | pov_begin_graph, | 
|---|
| 866 | pov_end_graph, | 
|---|
| 867 | pov_begin_layer, | 
|---|
| 868 | pov_end_layer, | 
|---|
| 869 | pov_begin_page, | 
|---|
| 870 | pov_end_page, | 
|---|
| 871 | pov_begin_cluster, | 
|---|
| 872 | pov_end_cluster, | 
|---|
| 873 | 0,			/* pov_begin_nodes */ | 
|---|
| 874 | 0,			/* pov_end_nodes */ | 
|---|
| 875 | 0,			/* pov_begin_edges */ | 
|---|
| 876 | 0,			/* pov_end_edges */ | 
|---|
| 877 | pov_begin_node, | 
|---|
| 878 | pov_end_node, | 
|---|
| 879 | pov_begin_edge, | 
|---|
| 880 | pov_end_edge, | 
|---|
| 881 | 0,			/* pov_begin_anchor */ | 
|---|
| 882 | 0,			/* pov_end_anchor */ | 
|---|
| 883 | 0,			/* pov_begin_label */ | 
|---|
| 884 | 0,			/* pov_end_label */ | 
|---|
| 885 | pov_textspan, | 
|---|
| 886 | 0,			/* pov_resolve_color */ | 
|---|
| 887 | pov_ellipse, | 
|---|
| 888 | pov_polygon, | 
|---|
| 889 | pov_bezier, | 
|---|
| 890 | pov_polyline, | 
|---|
| 891 | pov_comment, | 
|---|
| 892 | 0,			/* pov_library_shape */ | 
|---|
| 893 | }; | 
|---|
| 894 |  | 
|---|
| 895 | gvrender_features_t render_features_pov = { | 
|---|
| 896 | /* flags */ | 
|---|
| 897 | GVDEVICE_DOES_LAYERS | 
|---|
| 898 | | GVRENDER_DOES_MAP_RECTANGLE | 
|---|
| 899 | | GVRENDER_DOES_MAP_CIRCLE | 
|---|
| 900 | | GVRENDER_DOES_MAP_POLYGON | 
|---|
| 901 | | GVRENDER_DOES_MAP_ELLIPSE | 
|---|
| 902 | | GVRENDER_DOES_MAP_BSPLINE | 
|---|
| 903 | | GVRENDER_NO_WHITE_BG | 
|---|
| 904 | | GVRENDER_DOES_TRANSFORM | 
|---|
| 905 | | GVRENDER_DOES_Z | GVRENDER_DOES_MAP_BSPLINE, | 
|---|
| 906 | 4.0,			/* default pad - graph units */ | 
|---|
| 907 | pov_knowncolors,	/* knowncolors */ | 
|---|
| 908 | sizeof(pov_knowncolors) / sizeof(char *),	/* strings in knowncolors */ | 
|---|
| 909 | RENDERER_COLOR_TYPE	/* set renderer color type */ | 
|---|
| 910 | }; | 
|---|
| 911 |  | 
|---|
| 912 | gvdevice_features_t device_features_pov = { | 
|---|
| 913 | GVDEVICE_DOES_TRUECOLOR,	/* flags */ | 
|---|
| 914 | {0.0, 0.0},		/* default margin - points */ | 
|---|
| 915 | {0.0, 0.0},		/* default page width, height - points */ | 
|---|
| 916 | {DPI, DPI},		/* default dpi */ | 
|---|
| 917 | }; | 
|---|
| 918 |  | 
|---|
| 919 | gvplugin_installed_t gvrender_pov_types[] = { | 
|---|
| 920 | #ifdef HAVE_VSNPRINTF | 
|---|
| 921 | {FORMAT_POV, "pov", 1, &pov_engine, &render_features_pov}, | 
|---|
| 922 | #endif | 
|---|
| 923 | {0, NULL, 0, NULL, NULL} | 
|---|
| 924 | }; | 
|---|
| 925 |  | 
|---|
| 926 | gvplugin_installed_t gvdevice_pov_types[] = { | 
|---|
| 927 | #ifdef HAVE_VSNPRINTF | 
|---|
| 928 | {FORMAT_POV, "pov:pov", 1, NULL, &device_features_pov}, | 
|---|
| 929 | #endif | 
|---|
| 930 | {0, NULL, 0, NULL, NULL} | 
|---|
| 931 | }; | 
|---|
| 932 |  | 
|---|
| 933 |  | 
|---|