Geant4 Cross Reference |
1 #ifndef tools_gl2ps 2 #define tools_gl2ps 3 4 // This version of gl2ps-1.4.2 contains four m 5 // - it is pure header. 6 // - the code had been "namespace protected" b 7 // gl2ps_<xxx> to tools_gl2ps_<xxx> 8 // and : 9 // GL2PS_<xxx> to TOOLS_GL2PS_<xxx> 10 // - the code had been made thread safe by avo 11 // static singleton gl2ps context object. Wi 12 // create yourself a context, and pass it as 13 // tools_gl2ps functions that you want to us 14 // .... 15 // #include <tools/gl2ps> 16 // .... 17 // tools_GL2PScontext* gl2ps_context = too 18 // .... 19 // tools_gl2psBeginPage(gl2ps_context,...) 20 // ... 21 // tools_gl2psEndPage(gl2ps_context); 22 // .... 23 // tools_gl2psDeleteContext(gl2ps_context) 24 // .... 25 // - it does not call directly OpenGL function 26 // glIsEnabled,glBegin,glEnd,glGetFloatv,g 27 // glGetIntegerv,glRenderMode,glFeedbackBu 28 // but pointer to functions with the same si 29 // use tools_gl2ps in a non OpenGL context, 30 // by using tools_gl2psAddPolyPrimitive. If 31 // got by using the OpenGL FEEDBACK mode (th 32 // to declare the OpenGL upper functions on 33 // .... 34 // #include <tools/gl2ps> 35 // .... 36 // #include <GL/gl.h> 37 // .... 38 // tools_GL2PScontext* gl2ps_context = too 39 // ... 40 // tools_gl2ps_gl_funcs_t _funcs = { 41 // glIsEnabled, 42 // glBegin, 43 // glEnd, 44 // glGetFloatv, 45 // glVertex3f, 46 // glGetBooleanv, 47 // glGetIntegerv, 48 // glRenderMode, 49 // glFeedbackBuffer, 50 // glPassThrough 51 // }; 52 // tools_gl2ps_set_gl_funcs(gl2ps_context, 53 // ... 54 // 55 // Guy Barrand. 15/March/2022 56 // 57 58 /* 59 * GL2PS, an OpenGL to PostScript Printing Lib 60 * Copyright (C) 1999-2020 C. Geuzaine 61 * 62 * This program is free software; you can redi 63 * modify it under the terms of either: 64 * 65 * a) the GNU Library General Public License a 66 * Software Foundation, either version 2 of th 67 * option) any later version; or 68 * 69 * b) the GL2PS License as published by Christ 70 * version 2 of the License, or (at your optio 71 * 72 * This program is distributed in the hope tha 73 * WITHOUT ANY WARRANTY; without even the impl 74 * MERCHANTABILITY or FITNESS FOR A PARTICULAR 75 * the GNU Library General Public License or t 76 * more details. 77 * 78 * You should have received a copy of the GNU 79 * License along with this library in the file 80 * if not, write to the Free Software Foundati 81 * Street, Fifth Floor, Boston, MA 02110-1301, 82 * 83 * You should have received a copy of the GL2P 84 * library in the file named "COPYING.GL2PS"; 85 * to provide one. 86 * 87 * For the latest info about gl2ps and a full 88 * see http://www.geuz.org/gl2ps/. 89 * 90 * Please report all bugs and problems to <gl2 91 */ 92 93 #include "gl2ps_def.h" 94 95 #include <stdlib.h> 96 #include <stdio.h> 97 98 #include <math.h> 99 #include <string.h> 100 #include <sys/types.h> 101 #include <stdarg.h> 102 #include <time.h> 103 #include <float.h> 104 105 #if defined(TOOLS_GL2PS_HAVE_ZLIB) 106 #include <zlib.h> 107 #endif 108 109 #if defined(TOOLS_GL2PS_HAVE_LIBPNG) 110 #include <png.h> 111 #endif 112 113 /********************************************* 114 * 115 * Private definitions, data structures and pr 116 * 117 ********************************************* 118 119 /* Magic numbers (assuming that the order of m 120 coordinates is 10^3) */ 121 122 #define TOOLS_GL2PS_EPSILON 5.0e-3F 123 #define TOOLS_GL2PS_ZSCALE 1000.0F 124 #define TOOLS_GL2PS_ZOFFSET 5.0e-2F 125 #define TOOLS_GL2PS_ZOFFSET_LARGE 20.0F 126 #define TOOLS_GL2PS_ZERO(arg) (fabs(arg) < 127 128 /* BSP tree primitive comparison */ 129 130 #define TOOLS_GL2PS_COINCIDENT 1 131 #define TOOLS_GL2PS_IN_FRONT_OF 2 132 #define TOOLS_GL2PS_IN_BACK_OF 3 133 #define TOOLS_GL2PS_SPANNING 4 134 135 /* 2D BSP tree primitive comparison */ 136 137 #define TOOLS_GL2PS_POINT_COINCIDENT 0 138 #define TOOLS_GL2PS_POINT_INFRONT 1 139 #define TOOLS_GL2PS_POINT_BACK 2 140 141 /* Internal feedback buffer pass-through token 142 143 #define TOOLS_GL2PS_BEGIN_OFFSET_TOKEN 1 144 #define TOOLS_GL2PS_END_OFFSET_TOKEN 2 145 #define TOOLS_GL2PS_BEGIN_BOUNDARY_TOKEN 3 146 #define TOOLS_GL2PS_END_BOUNDARY_TOKEN 4 147 #define TOOLS_GL2PS_BEGIN_STIPPLE_TOKEN 5 148 #define TOOLS_GL2PS_END_STIPPLE_TOKEN 6 149 #define TOOLS_GL2PS_POINT_SIZE_TOKEN 7 150 #define TOOLS_GL2PS_LINE_CAP_TOKEN 8 151 #define TOOLS_GL2PS_LINE_JOIN_TOKEN 9 152 #define TOOLS_GL2PS_LINE_WIDTH_TOKEN 10 153 #define TOOLS_GL2PS_BEGIN_BLEND_TOKEN 11 154 #define TOOLS_GL2PS_END_BLEND_TOKEN 12 155 #define TOOLS_GL2PS_SRC_BLEND_TOKEN 13 156 #define TOOLS_GL2PS_DST_BLEND_TOKEN 14 157 #define TOOLS_GL2PS_IMAGEMAP_TOKEN 15 158 #define TOOLS_GL2PS_DRAW_PIXELS_TOKEN 16 159 #define TOOLS_GL2PS_TEXT_TOKEN 17 160 161 typedef enum { 162 T_UNDEFINED = -1, 163 T_CONST_COLOR = 1, 164 T_VAR_COLOR = 1<<1, 165 T_ALPHA_1 = 1<<2, 166 T_ALPHA_LESS_1 = 1<<3, 167 T_VAR_ALPHA = 1<<4 168 } TOOLS_GL2PS_TRIANGLE_PROPERTY; 169 170 typedef tools_GLfloat tools_GL2PSplane[4]; 171 172 typedef struct tools_GL2PSbsptree2d_ tools_GL2 173 174 struct tools_GL2PSbsptree2d_ { 175 tools_GL2PSplane plane; 176 tools_GL2PSbsptree2d *front, *back; 177 }; 178 179 typedef struct { 180 tools_GLint nmax, size, incr, n; 181 char *array; 182 } tools_GL2PSlist; 183 184 typedef struct tools_GL2PSbsptree_ tools_GL2PS 185 186 struct tools_GL2PSbsptree_ { 187 tools_GL2PSplane plane; 188 tools_GL2PSlist *primitives; 189 tools_GL2PSbsptree *front, *back; 190 }; 191 192 typedef struct { 193 tools_GL2PSvertex vertex[3]; 194 int prop; 195 } tools_GL2PStriangle; 196 197 typedef struct { 198 tools_GLshort fontsize; 199 char *str, *fontname; 200 /* Note: for a 'special' string, 'alignment' 201 (PostScript, PDF, etc.) of the special st 202 tools_GLint alignment; 203 tools_GLfloat angle; 204 } tools_GL2PSstring; 205 206 typedef struct { 207 tools_GLsizei width, height; 208 /* Note: for an imagemap, 'type' indicates i 209 written to the file or not, and 'format' 210 visible or not */ 211 tools_GLenum format, type; 212 tools_GLfloat zoom_x, zoom_y; 213 tools_GLfloat *pixels; 214 } tools_GL2PSimage; 215 216 typedef struct tools_GL2PSimagemap_ tools_GL2P 217 218 struct tools_GL2PSimagemap_ { 219 tools_GL2PSimage *image; 220 tools_GL2PSimagemap *next; 221 }; 222 223 typedef struct { 224 tools_GLshort type, numverts; 225 tools_GLushort pattern; 226 char boundary, offset, culled; 227 tools_GLint factor, linecap, linejoin, sorti 228 tools_GLfloat width, ofactor, ounits; 229 tools_GL2PSvertex *verts; 230 union { 231 tools_GL2PSstring *text; 232 tools_GL2PSimage *image; 233 } data; 234 } tools_GL2PSprimitive; 235 236 typedef struct { 237 #if defined(TOOLS_GL2PS_HAVE_ZLIB) 238 Bytef *dest, *src, *start; 239 uLongf destLen, srcLen; 240 #else 241 int dummy; 242 #endif 243 } tools_GL2PScompress; 244 245 typedef struct{ 246 tools_GL2PSlist* ptrlist; 247 int gsno, fontno, imno, shno, maskshno, trgr 248 int gsobjno, fontobjno, imobjno, shobjno, ma 249 } tools_GL2PSpdfgroup; 250 251 typedef struct tools_GL2PScontextRec { 252 /* General */ 253 tools_GLint format, sort, options, colorsize 254 tools_GLint lastlinecap, lastlinejoin; 255 char *title, *producer, *filename; 256 tools_GLboolean boundary, blending; 257 tools_GLfloat *feedback, lastlinewidth; 258 tools_GLint viewport[4], blendfunc[2], lastf 259 tools_GL2PSrgba *colormap, lastrgba, thresho 260 tools_GLushort lastpattern; 261 tools_GL2PSvertex lastvertex; 262 tools_GL2PSlist *primitives, *auxprimitives; 263 FILE *stream; 264 tools_GL2PScompress *compress; 265 tools_GLboolean header; 266 tools_GL2PSvertex rasterpos; 267 tools_GLboolean forcerasterpos; 268 269 /* BSP-specific */ 270 tools_GLint maxbestroot; 271 272 /* Occlusion culling-specific */ 273 tools_GLboolean zerosurfacearea; 274 tools_GL2PSbsptree2d *imagetree; 275 tools_GL2PSprimitive *primitivetoadd; 276 277 /* PDF-specific */ 278 int streamlength; 279 tools_GL2PSlist *pdfprimlist, *pdfgrouplist; 280 int *xreflist; 281 int objects_stack; /* available objects */ 282 int extgs_stack; /* graphics state object nu 283 int font_stack; /* font object number */ 284 int im_stack; /* image object number */ 285 int trgroupobjects_stack; /* xobject numbers 286 int shader_stack; /* shader object numbers * 287 int mshader_stack; /* mask shader object num 288 289 /* for image map list */ 290 tools_GL2PSimagemap *imagemap_head; 291 tools_GL2PSimagemap *imagemap_tail; 292 293 /* for TEX scaling */ 294 tools_GLfloat tex_scaling; 295 296 /*G.Barrand : OpenGL functions:*/ 297 tools_gl2ps_gl_funcs_t m_gl_funcs; 298 } tools_GL2PScontext; 299 300 typedef struct { 301 void (*printHeader)(tools_GL2PScontext*); 302 void (*printFooter)(tools_GL2PScontext*); 303 void (*beginViewport)(tools_GL2PScontext*,t 304 tools_GLint (*endViewport)(tools_GL2PScontex 305 void (*printPrimitive)(tools_GL2PScontext*, 306 void (*printFinalPrimitive)(tools_GL2PScont 307 const char *file_extension; 308 const char *description; 309 } tools_GL2PSbackend; 310 311 /* The gl2ps context. gl2ps is not thread safe 312 local GL2PScontext during tools_gl2psBeginP 313 314 //static GL2PScontext *gl2ps = NULL; 315 316 /* Need to forward-declare this one */ 317 318 inline tools_GLint tools_gl2psPrintPrimitives( 319 320 /********************************************* 321 * 322 * Utility routines 323 * 324 ********************************************* 325 326 inline void tools_gl2psMsg(tools_GLint level, 327 { 328 va_list args; 329 330 /*if(!(gl2ps->options & TOOLS_GL2PS_SILENT))*/ 331 switch(level){ 332 case TOOLS_GL2PS_INFO : fprintf(stderr, "G 333 case TOOLS_GL2PS_WARNING : fprintf(stderr, 334 case TOOLS_GL2PS_ERROR : fprintf(stderr, " 335 } 336 va_start(args, fmt); 337 vfprintf(stderr, fmt, args); 338 va_end(args); 339 fprintf(stderr, "\n"); 340 } 341 /* if(level == TOOLS_GL2PS_ERROR) exit(1); * 342 } 343 344 inline void *tools_gl2psMalloc(size_t size) 345 { 346 void *ptr; 347 348 if(!size) return NULL; 349 ptr = malloc(size); 350 if(!ptr){ 351 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Couldn' 352 return NULL; 353 } 354 return ptr; 355 } 356 357 inline void *tools_gl2psRealloc(void *ptr, siz 358 { 359 void *orig = ptr; 360 if(!size) return NULL; 361 ptr = realloc(orig, size); 362 if(!ptr){ 363 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Couldn' 364 free(orig); 365 return NULL; 366 } 367 return ptr; 368 } 369 370 inline void tools_gl2psFree(void *ptr) 371 { 372 if(!ptr) return; 373 free(ptr); 374 } 375 376 /*G.Barrand: begin*/ 377 inline tools_GLboolean tools_dummy_glIsEnabled 378 inline void tools_dummy_glBegin 379 /*printf("debug : tools_dummy_glBegin.\n");* 380 } 381 inline void tools_dummy_glEnd 382 inline void tools_dummy_glGetFloatv 383 inline void tools_dummy_glVertex3f 384 inline void tools_dummy_glGetBooleanv 385 inline void tools_dummy_glGetIntegerv 386 inline tools_GLint tools_dummy_glRenderMod 387 /*printf("debug : tools_dummy_glRenderMode.\ 388 return 0; 389 } 390 inline void tools_dummy_glFeedbackBuffer 391 inline void tools_dummy_glPassThrough 392 393 inline tools_GL2PScontext* tools_gl2psCreateCo 394 tools_GL2PScontext* gl2ps = (tools_GL2PScont 395 if(!gl2ps) return 0; 396 397 gl2ps->format = 0; 398 gl2ps->sort = 0; 399 gl2ps->options = 0; 400 gl2ps->colorsize = 0; 401 gl2ps->colormode = 0; 402 gl2ps->buffersize = 0; 403 gl2ps->lastlinecap = 0; 404 gl2ps->lastlinejoin = 0; 405 gl2ps->title = NULL; 406 gl2ps->producer = NULL; 407 gl2ps->filename = NULL; 408 gl2ps->boundary = TOOLS_GL_FALSE; 409 gl2ps->blending = TOOLS_GL_FALSE; 410 gl2ps->feedback = NULL; 411 gl2ps->lastlinewidth = 0; 412 gl2ps->viewport[0] = 0; 413 gl2ps->viewport[1] = 0; 414 gl2ps->viewport[2] = 0; 415 gl2ps->viewport[3] = 0; 416 417 gl2ps->blendfunc[0] = 0; 418 gl2ps->blendfunc[1] = 0; 419 420 gl2ps->lastfactor = 0; 421 gl2ps->colormap = NULL; 422 gl2ps->lastrgba[0] = 0; 423 gl2ps->lastrgba[1] = 0; 424 gl2ps->lastrgba[2] = 0; 425 gl2ps->lastrgba[3] = 0; 426 gl2ps->threshold[0] = 0; 427 gl2ps->threshold[1] = 0; 428 gl2ps->threshold[2] = 0; 429 gl2ps->threshold[3] = 0; 430 gl2ps->bgcolor[0] = 0; 431 gl2ps->bgcolor[1] = 0; 432 gl2ps->bgcolor[2] = 0; 433 gl2ps->bgcolor[3] = 0; 434 435 gl2ps->lastpattern = 0; 436 gl2ps->lastvertex.xyz[0] = 0; 437 gl2ps->lastvertex.xyz[1] = 0; 438 gl2ps->lastvertex.xyz[2] = 0; 439 gl2ps->lastvertex.rgba[0] = 0; 440 gl2ps->lastvertex.rgba[1] = 0; 441 gl2ps->lastvertex.rgba[2] = 0; 442 gl2ps->lastvertex.rgba[3] = 0; 443 444 gl2ps->primitives = NULL; 445 gl2ps->auxprimitives = NULL; 446 gl2ps->stream = NULL; 447 gl2ps->compress = NULL; 448 gl2ps->header = TOOLS_GL_FALSE; 449 gl2ps->rasterpos.xyz[0] = 0; 450 gl2ps->rasterpos.xyz[1] = 0; 451 gl2ps->rasterpos.xyz[2] = 0; 452 gl2ps->rasterpos.rgba[0] = 0; 453 gl2ps->rasterpos.rgba[1] = 0; 454 gl2ps->rasterpos.rgba[2] = 0; 455 gl2ps->rasterpos.rgba[3] = 0; 456 457 gl2ps->forcerasterpos = TOOLS_GL_FALSE; 458 gl2ps->maxbestroot = 0; 459 gl2ps->zerosurfacearea = TOOLS_GL_FALSE; 460 gl2ps->imagetree = NULL; 461 gl2ps->primitivetoadd = NULL; 462 463 gl2ps->streamlength = 0; 464 gl2ps->pdfprimlist = NULL; 465 gl2ps->pdfgrouplist = NULL; 466 gl2ps->xreflist = NULL; 467 468 gl2ps->objects_stack = 0; 469 gl2ps->extgs_stack = 0; 470 gl2ps->font_stack = 0; 471 gl2ps->im_stack = 0; 472 gl2ps->trgroupobjects_stack = 0; 473 gl2ps->shader_stack = 0; 474 gl2ps->mshader_stack = 0; 475 gl2ps->imagemap_head = NULL; 476 gl2ps->imagemap_tail = NULL; 477 478 gl2ps->m_gl_funcs.m_glIsEnabled = tools_dumm 479 gl2ps->m_gl_funcs.m_glBegin = tools_dummy_gl 480 gl2ps->m_gl_funcs.m_glEnd = tools_dummy_glEn 481 gl2ps->m_gl_funcs.m_glGetFloatv = tools_dumm 482 gl2ps->m_gl_funcs.m_glVertex3f = tools_dummy 483 gl2ps->m_gl_funcs.m_glGetBooleanv = tools_du 484 gl2ps->m_gl_funcs.m_glGetIntegerv = tools_du 485 gl2ps->m_gl_funcs.m_glRenderMode = tools_dum 486 gl2ps->m_gl_funcs.m_glFeedbackBuffer = tools 487 gl2ps->m_gl_funcs.m_glPassThrough = tools_du 488 489 return gl2ps; 490 } 491 inline void tools_gl2psDeleteContext(tools_GL2 492 tools_gl2psFree(a_context); 493 } 494 495 inline void tools_gl2ps_set_gl_funcs(tools_GL2 496 gl2ps->m_gl_funcs.m_glIsEnabled = a_funcs->m 497 gl2ps->m_gl_funcs.m_glBegin = a_funcs->m_glB 498 gl2ps->m_gl_funcs.m_glEnd = a_funcs->m_glEnd 499 gl2ps->m_gl_funcs.m_glGetFloatv = a_funcs->m 500 gl2ps->m_gl_funcs.m_glVertex3f = a_funcs->m_ 501 gl2ps->m_gl_funcs.m_glGetBooleanv = a_funcs- 502 gl2ps->m_gl_funcs.m_glGetIntegerv = a_funcs- 503 gl2ps->m_gl_funcs.m_glRenderMode = a_funcs-> 504 gl2ps->m_gl_funcs.m_glFeedbackBuffer = a_fun 505 gl2ps->m_gl_funcs.m_glPassThrough = a_funcs- 506 } 507 508 inline void tools_gl2ps_reset_gl_funcs(tools_G 509 gl2ps->m_gl_funcs.m_glIsEnabled = tools_dumm 510 gl2ps->m_gl_funcs.m_glBegin = tools_dummy_gl 511 gl2ps->m_gl_funcs.m_glEnd = tools_dummy_glEn 512 gl2ps->m_gl_funcs.m_glGetFloatv = tools_dumm 513 gl2ps->m_gl_funcs.m_glVertex3f = tools_dummy 514 gl2ps->m_gl_funcs.m_glGetBooleanv = tools_du 515 gl2ps->m_gl_funcs.m_glGetIntegerv = tools_du 516 gl2ps->m_gl_funcs.m_glRenderMode = tools_dum 517 gl2ps->m_gl_funcs.m_glFeedbackBuffer = tools 518 gl2ps->m_gl_funcs.m_glPassThrough = tools_du 519 } 520 521 #define tools_glIsEnabled gl2ps->m_gl_fun 522 #define tools_glBegin gl2ps->m_gl_fun 523 #define tools_glEnd gl2ps->m_gl_fun 524 #define tools_glGetFloatv gl2ps->m_gl_fun 525 #define tools_glVertex3f gl2ps->m_gl_fun 526 #define tools_glGetBooleanv gl2ps->m_gl_fun 527 #define tools_glGetIntegerv gl2ps->m_gl_fun 528 #define tools_glRenderMode gl2ps->m_gl_fun 529 #define tools_glFeedbackBuffer gl2ps->m_gl_fun 530 #define tools_glPassThrough gl2ps->m_gl_fun 531 532 /*G.Barrand: end*/ 533 534 inline int tools_gl2psWriteBigEndian(tools_GL2 535 { 536 int i; 537 int size = sizeof(unsigned long); 538 for(i = 1; i <= bytes; ++i){ 539 fputc(0xff & (data >> (size - i) * 8), gl2 540 } 541 return bytes; 542 } 543 544 /* zlib compression helper routines */ 545 546 #if defined(TOOLS_GL2PS_HAVE_ZLIB) 547 548 inline void tools_gl2psSetupCompress(tools_GL2 549 { 550 gl2ps->compress = (tools_GL2PScompress*)tool 551 gl2ps->compress->src = NULL; 552 gl2ps->compress->start = NULL; 553 gl2ps->compress->dest = NULL; 554 gl2ps->compress->srcLen = 0; 555 gl2ps->compress->destLen = 0; 556 } 557 558 inline void tools_gl2psFreeCompress(tools_GL2P 559 { 560 if(!gl2ps->compress) 561 return; 562 tools_gl2psFree(gl2ps->compress->start); 563 tools_gl2psFree(gl2ps->compress->dest); 564 gl2ps->compress->src = NULL; 565 gl2ps->compress->start = NULL; 566 gl2ps->compress->dest = NULL; 567 gl2ps->compress->srcLen = 0; 568 gl2ps->compress->destLen = 0; 569 } 570 571 inline int tools_gl2psAllocCompress(tools_GL2P 572 { 573 tools_gl2psFreeCompress(gl2ps); 574 575 if(!gl2ps->compress || !srcsize) 576 return TOOLS_GL2PS_ERROR; 577 578 gl2ps->compress->srcLen = srcsize; 579 gl2ps->compress->destLen = (int)ceil(1.001 * 580 gl2ps->compress->src = (Bytef*)tools_gl2psMa 581 gl2ps->compress->start = gl2ps->compress->sr 582 gl2ps->compress->dest = (Bytef*)tools_gl2psM 583 584 return TOOLS_GL2PS_SUCCESS; 585 } 586 587 inline void *tools_gl2psReallocCompress(tools_ 588 { 589 if(!gl2ps->compress || !srcsize) 590 return NULL; 591 592 if(srcsize < gl2ps->compress->srcLen) 593 return gl2ps->compress->start; 594 595 gl2ps->compress->srcLen = srcsize; 596 gl2ps->compress->destLen = (int)ceil(1.001 * 597 gl2ps->compress->src = (Bytef*)tools_gl2psRe 598 599 gl2ps->compress->start = gl2ps->compress->sr 600 gl2ps->compress->dest = (Bytef*)tools_gl2psR 601 602 603 return gl2ps->compress->start; 604 } 605 606 inline int tools_gl2psWriteBigEndianCompress(t 607 { 608 int i; 609 int size = sizeof(unsigned long); 610 for(i = 1; i <= bytes; ++i){ 611 *gl2ps->compress->src = (Bytef)(0xff & (da 612 ++gl2ps->compress->src; 613 } 614 return bytes; 615 } 616 617 inline int tools_gl2psDeflate(tools_GL2PSconte 618 { 619 /* For compatibility with older zlib version 620 instead of compress2(..., Z_BEST_COMPRESS 621 return compress(gl2ps->compress->dest, &gl2p 622 gl2ps->compress->start, gl2p 623 } 624 625 #endif 626 627 inline int tools_gl2psPrintf(tools_GL2PScontex 628 { 629 int ret; 630 va_list args; 631 632 #if defined(TOOLS_GL2PS_HAVE_ZLIB) 633 //static char buf[1024]; //G.Barrand: avoid th 634 //char *bufptr = buf; 635 //tools_GLboolean freebuf = TOOLS_GL_FALSE; 636 char* bufptr = (char *)tools_gl2psMalloc(102 637 tools_GLboolean freebuf = TOOLS_GL_TRUE; 638 unsigned int oldsize = 0; 639 #if !defined(TOOLS_GL2PS_HAVE_NO_VSNPRINTF) 640 /* Try writing the string to a 1024 byte buf 641 keep trying larger sizes until it does. * 642 //int bufsize = sizeof(buf); 643 int bufsize = 1024; 644 #endif 645 if(gl2ps->options & TOOLS_GL2PS_COMPRESS){ 646 va_start(args, fmt); 647 #if defined(TOOLS_GL2PS_HAVE_NO_VSNPRINTF) 648 ret = vsprintf(buf, fmt, args); 649 #else 650 ret = vsnprintf(bufptr, bufsize, fmt, args 651 #endif 652 va_end(args); 653 #if !defined(TOOLS_GL2PS_HAVE_NO_VSNPRINTF) 654 while(ret >= (bufsize - 1) || ret < 0){ 655 /* Too big. Allocate a new buffer. */ 656 bufsize *= 2; 657 if(freebuf == TOOLS_GL_TRUE) tools_gl2ps 658 bufptr = (char *)tools_gl2psMalloc(bufsi 659 freebuf = TOOLS_GL_TRUE; 660 va_start(args, fmt); 661 ret = vsnprintf(bufptr, bufsize, fmt, ar 662 va_end(args); 663 } 664 #endif 665 oldsize = gl2ps->compress->srcLen; 666 gl2ps->compress->start = (Bytef*)tools_gl2 667 memcpy(gl2ps->compress->start + oldsize, b 668 if(freebuf == TOOLS_GL_TRUE) tools_gl2psFr 669 ret = 0; 670 } 671 else{ 672 #endif 673 va_start(args, fmt); 674 ret = vfprintf(gl2ps->stream, fmt, args); 675 va_end(args); 676 #if defined(TOOLS_GL2PS_HAVE_ZLIB) 677 } 678 #endif 679 return ret; 680 } 681 682 inline void tools_gl2psPrintGzipHeader(tools_G 683 { 684 #if defined(TOOLS_GL2PS_HAVE_ZLIB) 685 char tmp[10] = {'\x1f', '\x8b', /* magic num 686 8, /* compression method: Z_ 687 0, /* flags */ 688 0, 0, 0, 0, /* time */ 689 2, /* extra flags: max compr 690 '\x03'}; /* OS code: 0x03 (U 691 692 if(gl2ps->options & TOOLS_GL2PS_COMPRESS){ 693 tools_gl2psSetupCompress(gl2ps); 694 /* add the gzip file header */ 695 fwrite(tmp, 10, 1, gl2ps->stream); 696 } 697 #endif 698 (void)gl2ps; 699 } 700 701 inline void tools_gl2psPrintGzipFooter(tools_G 702 { 703 #if defined(TOOLS_GL2PS_HAVE_ZLIB) 704 int n; 705 uLong crc, len; 706 char tmp[8]; 707 708 if(gl2ps->options & TOOLS_GL2PS_COMPRESS){ 709 if(Z_OK != tools_gl2psDeflate(gl2ps)){ 710 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Zlib 711 } 712 else{ 713 /* determine the length of the header in 714 n = 2; /* CMF+FLG */ 715 if(gl2ps->compress->dest[1] & (1<<5)){ 716 n += 4; /* DICTID */ 717 } 718 /* write the data, without the zlib head 719 fwrite(gl2ps->compress->dest+n, gl2ps->c 720 1, gl2ps->stream); 721 /* add the gzip file footer */ 722 crc = crc32(0L, gl2ps->compress->start, 723 for(n = 0; n < 4; ++n){ 724 tmp[n] = (char)(crc & 0xff); 725 crc >>= 8; 726 } 727 len = gl2ps->compress->srcLen; 728 for(n = 4; n < 8; ++n){ 729 tmp[n] = (char)(len & 0xff); 730 len >>= 8; 731 } 732 fwrite(tmp, 8, 1, gl2ps->stream); 733 } 734 tools_gl2psFreeCompress(gl2ps); 735 tools_gl2psFree(gl2ps->compress); 736 gl2ps->compress = NULL; 737 } 738 #endif 739 (void)gl2ps; 740 } 741 742 /* The list handling routines */ 743 744 inline void tools_gl2psListRealloc(tools_GL2PS 745 { 746 if(!list){ 747 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Cannot 748 return; 749 } 750 if(n <= 0) return; 751 if(!list->array){ 752 list->nmax = n; 753 list->array = (char*)tools_gl2psMalloc(lis 754 } 755 else{ 756 if(n > list->nmax){ 757 list->nmax = ((n - 1) / list->incr + 1) 758 list->array = (char*)tools_gl2psRealloc( 759 list-> 760 } 761 } 762 } 763 764 inline tools_GL2PSlist *tools_gl2psListCreate( 765 { 766 tools_GL2PSlist *list; 767 768 if(n < 0) n = 0; 769 if(incr <= 0) incr = 1; 770 list = (tools_GL2PSlist*)tools_gl2psMalloc(s 771 list->nmax = 0; 772 list->incr = incr; 773 list->size = size; 774 list->n = 0; 775 list->array = NULL; 776 tools_gl2psListRealloc(list, n); 777 return list; 778 } 779 780 inline void tools_gl2psListReset(tools_GL2PSli 781 { 782 if(!list) return; 783 list->n = 0; 784 } 785 786 inline void tools_gl2psListDelete(tools_GL2PSl 787 { 788 if(!list) return; 789 tools_gl2psFree(list->array); 790 tools_gl2psFree(list); 791 } 792 793 inline void tools_gl2psListAdd(tools_GL2PSlist 794 { 795 if(!list){ 796 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Cannot 797 return; 798 } 799 list->n++; 800 tools_gl2psListRealloc(list, list->n); 801 memcpy(&list->array[(list->n - 1) * list->si 802 } 803 804 inline int tools_gl2psListNbr(tools_GL2PSlist 805 { 806 if(!list) 807 return 0; 808 return list->n; 809 } 810 811 inline void *tools_gl2psListPointer(tools_GL2P 812 { 813 if(!list){ 814 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Cannot 815 return NULL; 816 } 817 if((idx < 0) || (idx >= list->n)){ 818 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Wrong l 819 return NULL; 820 } 821 return &list->array[idx * list->size]; 822 } 823 824 //G.Barrand: begin: 825 inline bool tools_gl2psPortableSort(void* a_it 826 // We observed that qsort on macOS/clang, L 827 // does not produce the same output list for 828 // "Same objects" are put correctly contiguo 829 // according the platform. In case of gl2ps, 830 // primitives in the output file which are n 831 // Then, we let the possibility to use a por 832 // give the same sorted list, and then the s 833 if(a_nitem<=1) return true; 834 if(!a_item_size) return true; 835 void* tmp = ::malloc(a_item_size); 836 if(!tmp) return false; 837 char* p = (char*)a_items; 838 size_t i,j; 839 char* a = p;char* b; 840 for(i=0;i<a_nitem;i++,a+=a_item_size) { 841 b = p+a_item_size*(i+1); 842 for(j=i+1;j<a_nitem;j++,b+=a_item_size) { 843 if(a_cmp(b,a)>=0) continue; //b>=a 844 ::memcpy(tmp,a,a_item_size); 845 ::memcpy(a,b,a_item_size); 846 ::memcpy(b,tmp,a_item_size); 847 } 848 } 849 ::free(tmp); 850 return true; 851 } 852 //G.Barrand: end. 853 854 inline void tools_gl2psListSort(tools_GL2PScon 855 tools_GL2PSlis 856 int (*fcmp)(co 857 { 858 if(!list) return; 859 if(gl2ps->options & TOOLS_GL2PS_PORTABLE_SOR 860 tools_gl2psPortableSort(list->array, list- 861 } else { 862 ::qsort(list->array, list->n, list->size, 863 } 864 } 865 866 /* Must be a list of tools_GL2PSprimitives. */ 867 inline void tools_gl2psListAssignSortIds(tools 868 { 869 tools_GLint i; 870 for(i = 0; i < tools_gl2psListNbr(list); i++ 871 (*(tools_GL2PSprimitive**)tools_gl2psListP 872 } 873 } 874 875 inline void tools_gl2psListAction(tools_GL2PSl 876 { 877 tools_GLint i; 878 879 for(i = 0; i < tools_gl2psListNbr(list); i++ 880 (*action)(tools_gl2psListPointer(list, i)) 881 } 882 } 883 884 inline void tools_gl2psListActionInverse(tools 885 { 886 tools_GLint i; 887 888 for(i = tools_gl2psListNbr(list); i > 0; i-- 889 (*action)(tools_gl2psListPointer(list, i-1 890 } 891 } 892 893 inline void tools_gl2psListActionContext(tools 894 { 895 tools_GLint i; 896 897 for(i = 0; i < tools_gl2psListNbr(list); i++ 898 (*action)(gl2ps, tools_gl2psListPointer(li 899 } 900 } 901 902 inline void tools_gl2psListActionInverseContex 903 { 904 tools_GLint i; 905 906 for(i = tools_gl2psListNbr(list); i > 0; i-- 907 (*action)(gl2ps, tools_gl2psListPointer(li 908 } 909 } 910 911 #if defined(TOOLS_GL2PS_HAVE_LIBPNG) 912 913 inline void tools_gl2psListRead(tools_GL2PSlis 914 { 915 if((index < 0) || (index >= list->n)) 916 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Wrong l 917 memcpy(data, &list->array[index * list->size 918 } 919 920 inline void tools_gl2psEncodeBase64Block(unsig 921 { 922 static const char cb64[] = 923 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmno 924 925 out[0] = cb64[ in[0] >> 2 ]; 926 out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[ 927 out[2] = (len > 1) ? cb64[ ((in[1] & 0x0f) < 928 out[3] = (len > 2) ? cb64[ in[2] & 0x3f ] : 929 } 930 931 inline void tools_gl2psListEncodeBase64(tools_ 932 { 933 unsigned char *buffer, in[3], out[4]; 934 int i, n, index, len; 935 936 n = list->n * list->size; 937 buffer = (unsigned char*)tools_gl2psMalloc(n 938 memcpy(buffer, list->array, n * sizeof(unsig 939 tools_gl2psListReset(list); 940 941 index = 0; 942 while(index < n) { 943 len = 0; 944 for(i = 0; i < 3; i++) { 945 if(index < n){ 946 in[i] = buffer[index]; 947 len++; 948 } 949 else{ 950 in[i] = 0; 951 } 952 index++; 953 } 954 if(len) { 955 tools_gl2psEncodeBase64Block(in, out, le 956 for(i = 0; i < 4; i++) 957 tools_gl2psListAdd(list, &out[i]); 958 } 959 } 960 tools_gl2psFree(buffer); 961 } 962 963 #endif 964 965 /* Helpers for rgba colors */ 966 967 inline tools_GLboolean tools_gl2psSameColor(to 968 { 969 if(!TOOLS_GL2PS_ZERO(rgba1[0] - rgba2[0]) || 970 !TOOLS_GL2PS_ZERO(rgba1[1] - rgba2[1]) || 971 !TOOLS_GL2PS_ZERO(rgba1[2] - rgba2[2])) 972 return TOOLS_GL_FALSE; 973 return TOOLS_GL_TRUE; 974 } 975 976 inline tools_GLboolean tools_gl2psVertsSameCol 977 { 978 int i; 979 980 for(i = 1; i < prim->numverts; i++){ 981 if(!tools_gl2psSameColor(prim->verts[0].rg 982 return TOOLS_GL_FALSE; 983 } 984 } 985 return TOOLS_GL_TRUE; 986 } 987 988 inline tools_GLboolean tools_gl2psSameColorThr 989 tools 990 { 991 int i; 992 993 if(n < 2) return TOOLS_GL_TRUE; 994 995 for(i = 1; i < n; i++){ 996 if(fabs(rgba[0][0] - rgba[i][0]) > thresho 997 fabs(rgba[0][1] - rgba[i][1]) > thresho 998 fabs(rgba[0][2] - rgba[i][2]) > thresho 999 return TOOLS_GL_FALSE; 1000 } 1001 1002 return TOOLS_GL_TRUE; 1003 } 1004 1005 inline void tools_gl2psSetLastColor(tools_GL2 1006 { 1007 int i; 1008 for(i = 0; i < 3; ++i){ 1009 gl2ps->lastrgba[i] = rgba[i]; 1010 } 1011 } 1012 1013 inline tools_GLfloat tools_gl2psGetRGB(tools_ 1014 tools_GLfloat *red 1015 { 1016 1017 tools_GLsizei width = im->width; 1018 tools_GLsizei height = im->height; 1019 tools_GLfloat *pixels = im->pixels; 1020 tools_GLfloat *pimag; 1021 1022 /* OpenGL image is from down to up, PS imag 1023 switch(im->format){ 1024 case TOOLS_GL_RGBA: 1025 pimag = pixels + 4 * (width * (height - 1 1026 break; 1027 case TOOLS_GL_RGB: 1028 default: 1029 pimag = pixels + 3 * (width * (height - 1 1030 break; 1031 } 1032 *red = *pimag; pimag++; 1033 *green = *pimag; pimag++; 1034 *blue = *pimag; pimag++; 1035 1036 return (im->format == TOOLS_GL_RGBA) ? *pim 1037 } 1038 1039 /* Helper routines for pixmaps */ 1040 1041 inline tools_GL2PSimage *tools_gl2psCopyPixma 1042 { 1043 int size; 1044 tools_GL2PSimage *image = (tools_GL2PSimage 1045 1046 image->width = im->width; 1047 image->height = im->height; 1048 image->format = im->format; 1049 image->type = im->type; 1050 image->zoom_x = im->zoom_x; 1051 image->zoom_y = im->zoom_y; 1052 1053 switch(image->format){ 1054 case TOOLS_GL_RGBA: 1055 size = image->height * image->width * 4 * 1056 break; 1057 case TOOLS_GL_RGB: 1058 default: 1059 size = image->height * image->width * 3 * 1060 break; 1061 } 1062 1063 image->pixels = (tools_GLfloat*)tools_gl2ps 1064 memcpy(image->pixels, im->pixels, size); 1065 1066 return image; 1067 } 1068 1069 inline void tools_gl2psFreePixmap(tools_GL2PS 1070 { 1071 if(!im) 1072 return; 1073 tools_gl2psFree(im->pixels); 1074 tools_gl2psFree(im); 1075 } 1076 1077 #if defined(TOOLS_GL2PS_HAVE_LIBPNG) 1078 1079 #if !defined(png_jmpbuf) 1080 # define png_jmpbuf(png_ptr) ((png_ptr)->jmp 1081 #endif 1082 1083 inline void tools_gl2psUserWritePNG(png_struc 1084 { 1085 unsigned int i; 1086 tools_GL2PSlist *png = (tools_GL2PSlist*)pn 1087 for(i = 0; i < length; i++) 1088 tools_gl2psListAdd(png, &data[i]); 1089 } 1090 1091 inline void tools_gl2psUserFlushPNG(png_struc 1092 { 1093 (void) png_ptr; /* not used */ 1094 } 1095 1096 inline void tools_gl2psConvertPixmapToPNG(too 1097 { 1098 png_structp png_ptr; 1099 png_infop info_ptr; 1100 unsigned char *row_data; 1101 tools_GLfloat dr, dg, db; 1102 int row, col; 1103 1104 if(!(png_ptr = png_create_write_struct(PNG_ 1105 return; 1106 1107 if(!(info_ptr = png_create_info_struct(png_ 1108 png_destroy_write_struct(&png_ptr, NULL); 1109 return; 1110 } 1111 1112 if(setjmp(png_jmpbuf(png_ptr))) { 1113 png_destroy_write_struct(&png_ptr, &info_ 1114 return; 1115 } 1116 1117 png_set_write_fn(png_ptr, (void *)png, tool 1118 png_set_compression_level(png_ptr, Z_DEFAUL 1119 png_set_IHDR(png_ptr, info_ptr, pixmap->wid 1120 PNG_COLOR_TYPE_RGB, PNG_INTERL 1121 PNG_FILTER_TYPE_BASE); 1122 png_write_info(png_ptr, info_ptr); 1123 1124 row_data = (unsigned char*)tools_gl2psMallo 1125 for(row = 0; row < pixmap->height; row++){ 1126 for(col = 0; col < pixmap->width; col++){ 1127 tools_gl2psGetRGB(pixmap, col, row, &dr 1128 row_data[3*col] = (unsigned char)(255. 1129 row_data[3*col+1] = (unsigned char)(255 1130 row_data[3*col+2] = (unsigned char)(255 1131 } 1132 png_write_row(png_ptr, (png_bytep)row_dat 1133 } 1134 tools_gl2psFree(row_data); 1135 1136 png_write_end(png_ptr, info_ptr); 1137 png_destroy_write_struct(&png_ptr, &info_pt 1138 } 1139 1140 #endif 1141 1142 /* Helper routines for text strings */ 1143 1144 inline tools_GLint tools_gl2psAddText(tools_G 1145 tools_GLshort fonts 1146 tools_GL2PSrgba col 1147 tools_GLfloat blx, 1148 { 1149 tools_GLfloat pos[4]; 1150 tools_GL2PSprimitive *prim; 1151 tools_GLboolean valid; 1152 1153 if(/*!gl2ps ||*/ !str || !fontname) return 1154 1155 if(gl2ps->options & TOOLS_GL2PS_NO_TEXT) re 1156 1157 if (gl2ps->forcerasterpos) { 1158 pos[0] = gl2ps->rasterpos.xyz[0]; 1159 pos[1] = gl2ps->rasterpos.xyz[1]; 1160 pos[2] = gl2ps->rasterpos.xyz[2]; 1161 pos[3] = 1.f; 1162 } 1163 else { 1164 tools_glGetBooleanv(TOOLS_GL_CURRENT_RAST 1165 if(TOOLS_GL_FALSE == valid) return TOOLS_ 1166 tools_glGetFloatv(TOOLS_GL_CURRENT_RASTER 1167 } 1168 1169 prim = (tools_GL2PSprimitive*)tools_gl2psMa 1170 prim->type = (tools_GLshort)type; 1171 prim->boundary = 0; 1172 prim->numverts = setblpos ? 2 : 1; 1173 prim->verts = (tools_GL2PSvertex*)tools_gl2 1174 prim->verts[0].xyz[0] = pos[0]; 1175 prim->verts[0].xyz[1] = pos[1]; 1176 prim->verts[0].xyz[2] = pos[2]; 1177 if (setblpos) { 1178 prim->verts[1].xyz[0] = blx; 1179 prim->verts[1].xyz[1] = bly; 1180 prim->verts[1].xyz[2] = 0; 1181 } 1182 prim->culled = 0; 1183 prim->offset = 0; 1184 prim->ofactor = 0.0; 1185 prim->ounits = 0.0; 1186 prim->pattern = 0; 1187 prim->factor = 0; 1188 prim->width = 1; 1189 prim->linecap = 0; 1190 prim->linejoin = 0; 1191 1192 if (color) { 1193 memcpy(prim->verts[0].rgba, color, 4 * si 1194 } 1195 else { 1196 if (gl2ps->forcerasterpos) { 1197 prim->verts[0].rgba[0] = gl2ps->rasterp 1198 prim->verts[0].rgba[1] = gl2ps->rasterp 1199 prim->verts[0].rgba[2] = gl2ps->rasterp 1200 prim->verts[0].rgba[3] = gl2ps->rasterp 1201 } 1202 else { 1203 tools_glGetFloatv(TOOLS_GL_CURRENT_RAST 1204 } 1205 } 1206 prim->data.text = (tools_GL2PSstring*)tools 1207 prim->data.text->str = (char*)tools_gl2psMa 1208 strcpy(prim->data.text->str, str); 1209 prim->data.text->fontname = (char*)tools_gl 1210 strcpy(prim->data.text->fontname, fontname) 1211 prim->data.text->fontsize = fontsize; 1212 prim->data.text->alignment = alignment; 1213 prim->data.text->angle = angle; 1214 1215 gl2ps->forcerasterpos = TOOLS_GL_FALSE; 1216 1217 /* If no OpenGL context, just add directly 1218 if (gl2ps->options & TOOLS_GL2PS_NO_OPENGL_ 1219 tools_gl2psListAdd(gl2ps->primitives, &pr 1220 } 1221 else { 1222 tools_gl2psListAdd(gl2ps->auxprimitives, 1223 tools_glPassThrough(TOOLS_GL2PS_TEXT_TOKE 1224 } 1225 1226 return TOOLS_GL2PS_SUCCESS; 1227 } 1228 1229 inline tools_GL2PSstring *tools_gl2psCopyText 1230 { 1231 tools_GL2PSstring *text = (tools_GL2PSstrin 1232 text->str = (char*)tools_gl2psMalloc((strle 1233 strcpy(text->str, t->str); 1234 text->fontname = (char*)tools_gl2psMalloc(( 1235 strcpy(text->fontname, t->fontname); 1236 text->fontsize = t->fontsize; 1237 text->alignment = t->alignment; 1238 text->angle = t->angle; 1239 1240 return text; 1241 } 1242 1243 inline void tools_gl2psFreeText(tools_GL2PSst 1244 { 1245 if(!text) 1246 return; 1247 tools_gl2psFree(text->str); 1248 tools_gl2psFree(text->fontname); 1249 tools_gl2psFree(text); 1250 } 1251 1252 /* Helpers for blending modes */ 1253 1254 inline tools_GLboolean tools_gl2psSupportedBl 1255 { 1256 /* returns TRUE if gl2ps supports the argum 1257 blending modes have been implemented so 1258 1259 if( (sfactor == TOOLS_GL_SRC_ALPHA && dfact 1260 (sfactor == TOOLS_GL_ONE && dfactor == 1261 return TOOLS_GL_TRUE; 1262 return TOOLS_GL_FALSE; 1263 } 1264 1265 inline void tools_gl2psAdaptVertexForBlending 1266 { 1267 /* Transforms vertex depending on the actua 1268 currently the vertex v is considered as 1269 alpha value is changed to 1.0 if source 1270 active. This might be extended in the fu 1271 1272 if(!v /* || !gl2ps*/) 1273 return; 1274 1275 if(gl2ps->options & TOOLS_GL2PS_NO_BLENDING 1276 v->rgba[3] = 1.0F; 1277 return; 1278 } 1279 1280 switch(gl2ps->blendfunc[0]){ 1281 case TOOLS_GL_ONE: 1282 v->rgba[3] = 1.0F; 1283 break; 1284 default: 1285 break; 1286 } 1287 } 1288 1289 inline void tools_gl2psAssignTriangleProperti 1290 { 1291 /* int i; */ 1292 1293 t->prop = T_VAR_COLOR; 1294 1295 /* Uncommenting the following lines activat 1296 grained distinction between triangle typ 1297 a remarkable amount of PDF handling code 1298 on it if activated */ 1299 /* 1300 t->prop = T_CONST_COLOR; 1301 for(i = 0; i < 3; ++i){ 1302 if(!TOOLS_GL2PS_ZERO(t->vertex[0].rgba[i] 1303 !TOOLS_GL2PS_ZERO(t->vertex[1].rgba[i] 1304 t->prop = T_VAR_COLOR; 1305 break; 1306 } 1307 } 1308 */ 1309 1310 if(!TOOLS_GL2PS_ZERO(t->vertex[0].rgba[3] - 1311 !TOOLS_GL2PS_ZERO(t->vertex[1].rgba[3] - 1312 t->prop |= T_VAR_ALPHA; 1313 } 1314 else{ 1315 if(t->vertex[0].rgba[3] < 1) 1316 t->prop |= T_ALPHA_LESS_1; 1317 else 1318 t->prop |= T_ALPHA_1; 1319 } 1320 } 1321 1322 inline void tools_gl2psFillTriangleFromPrimit 1323 to 1324 { 1325 t->vertex[0] = p->verts[0]; 1326 t->vertex[1] = p->verts[1]; 1327 t->vertex[2] = p->verts[2]; 1328 if(TOOLS_GL_TRUE == assignprops) 1329 tools_gl2psAssignTriangleProperties(t); 1330 } 1331 1332 inline void tools_gl2psInitTriangle(tools_GL2 1333 { 1334 int i; 1335 tools_GL2PSvertex vertex = { {-1.0F, -1.0F, 1336 for(i = 0; i < 3; i++) 1337 t->vertex[i] = vertex; 1338 t->prop = T_UNDEFINED; 1339 } 1340 1341 /* Miscellaneous helper routines */ 1342 1343 inline void tools_gl2psResetLineProperties(to 1344 { 1345 gl2ps->lastlinewidth = 0.; 1346 gl2ps->lastlinecap = gl2ps->lastlinejoin = 1347 } 1348 1349 inline tools_GL2PSprimitive *tools_gl2psCopyP 1350 { 1351 tools_GL2PSprimitive *prim; 1352 1353 if(!p){ 1354 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Trying 1355 return NULL; 1356 } 1357 1358 prim = (tools_GL2PSprimitive*)tools_gl2psMa 1359 1360 prim->type = p->type; 1361 prim->numverts = p->numverts; 1362 prim->boundary = p->boundary; 1363 prim->offset = p->offset; 1364 prim->ofactor = p->ofactor; 1365 prim->ounits = p->ounits; 1366 prim->pattern = p->pattern; 1367 prim->factor = p->factor; 1368 prim->culled = p->culled; 1369 prim->width = p->width; 1370 prim->linecap = p->linecap; 1371 prim->linejoin = p->linejoin; 1372 prim->verts = (tools_GL2PSvertex*)tools_gl2 1373 memcpy(prim->verts, p->verts, p->numverts * 1374 1375 switch(prim->type){ 1376 case TOOLS_GL2PS_PIXMAP : 1377 prim->data.image = tools_gl2psCopyPixmap( 1378 break; 1379 case TOOLS_GL2PS_TEXT : 1380 case TOOLS_GL2PS_SPECIAL : 1381 prim->data.text = tools_gl2psCopyText(p-> 1382 break; 1383 default: 1384 break; 1385 } 1386 1387 return prim; 1388 } 1389 1390 inline tools_GLboolean tools_gl2psSamePositio 1391 { 1392 if(!TOOLS_GL2PS_ZERO(p1[0] - p2[0]) || 1393 !TOOLS_GL2PS_ZERO(p1[1] - p2[1]) || 1394 !TOOLS_GL2PS_ZERO(p1[2] - p2[2])) 1395 return TOOLS_GL_FALSE; 1396 return TOOLS_GL_TRUE; 1397 } 1398 1399 /******************************************** 1400 * 1401 * 3D sorting routines 1402 * 1403 ******************************************** 1404 1405 inline tools_GLfloat tools_gl2psComparePointP 1406 { 1407 return (plane[0] * point[0] + 1408 plane[1] * point[1] + 1409 plane[2] * point[2] + 1410 plane[3]); 1411 } 1412 1413 inline tools_GLfloat tools_gl2psPsca(tools_GL 1414 { 1415 return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]); 1416 } 1417 1418 inline void tools_gl2psPvec(tools_GLfloat *a, 1419 { 1420 c[0] = a[1]*b[2] - a[2]*b[1]; 1421 c[1] = a[2]*b[0] - a[0]*b[2]; 1422 c[2] = a[0]*b[1] - a[1]*b[0]; 1423 } 1424 1425 inline tools_GLfloat tools_gl2psNorm(tools_GL 1426 { 1427 return (tools_GLfloat)sqrt(a[0]*a[0] + a[1] 1428 } 1429 1430 inline void tools_gl2psGetNormal(tools_GLfloa 1431 { 1432 tools_GLfloat norm; 1433 1434 tools_gl2psPvec(a, b, c); 1435 if(!TOOLS_GL2PS_ZERO(norm = tools_gl2psNorm 1436 c[0] = c[0] / norm; 1437 c[1] = c[1] / norm; 1438 c[2] = c[2] / norm; 1439 } 1440 else{ 1441 /* The plane is still wrong despite our t 1442 Let's return a dummy value for now (th 1443 do more intelligent tests in GetPlane) 1444 c[0] = c[1] = 0.0F; 1445 c[2] = 1.0F; 1446 } 1447 } 1448 1449 inline void tools_gl2psGetPlane(tools_GL2PSpr 1450 { 1451 tools_GL2PSxyz v = {0.0F, 0.0F, 0.0F}, w = 1452 1453 switch(prim->type){ 1454 case TOOLS_GL2PS_TRIANGLE : 1455 case TOOLS_GL2PS_QUADRANGLE : 1456 v[0] = prim->verts[1].xyz[0] - prim->vert 1457 v[1] = prim->verts[1].xyz[1] - prim->vert 1458 v[2] = prim->verts[1].xyz[2] - prim->vert 1459 w[0] = prim->verts[2].xyz[0] - prim->vert 1460 w[1] = prim->verts[2].xyz[1] - prim->vert 1461 w[2] = prim->verts[2].xyz[2] - prim->vert 1462 if((TOOLS_GL2PS_ZERO(v[0]) && TOOLS_GL2PS 1463 (TOOLS_GL2PS_ZERO(w[0]) && TOOLS_GL2PS 1464 plane[0] = plane[1] = 0.0F; 1465 plane[2] = 1.0F; 1466 plane[3] = -prim->verts[0].xyz[2]; 1467 } 1468 else{ 1469 tools_gl2psGetNormal(v, w, plane); 1470 plane[3] = 1471 - plane[0] * prim->verts[0].xyz[0] 1472 - plane[1] * prim->verts[0].xyz[1] 1473 - plane[2] * prim->verts[0].xyz[2]; 1474 } 1475 break; 1476 case TOOLS_GL2PS_LINE : 1477 v[0] = prim->verts[1].xyz[0] - prim->vert 1478 v[1] = prim->verts[1].xyz[1] - prim->vert 1479 v[2] = prim->verts[1].xyz[2] - prim->vert 1480 if(TOOLS_GL2PS_ZERO(v[0]) && TOOLS_GL2PS_ 1481 plane[0] = plane[1] = 0.0F; 1482 plane[2] = 1.0F; 1483 plane[3] = -prim->verts[0].xyz[2]; 1484 } 1485 else{ 1486 if(TOOLS_GL2PS_ZERO(v[0])) w[0] = 1487 else if(TOOLS_GL2PS_ZERO(v[1])) w[1] = 1488 else w[2] = 1.0F; 1489 tools_gl2psGetNormal(v, w, plane); 1490 plane[3] = 1491 - plane[0] * prim->verts[0].xyz[0] 1492 - plane[1] * prim->verts[0].xyz[1] 1493 - plane[2] * prim->verts[0].xyz[2]; 1494 } 1495 break; 1496 case TOOLS_GL2PS_POINT : 1497 case TOOLS_GL2PS_PIXMAP : 1498 case TOOLS_GL2PS_TEXT : 1499 case TOOLS_GL2PS_SPECIAL : 1500 case TOOLS_GL2PS_IMAGEMAP: 1501 plane[0] = plane[1] = 0.0F; 1502 plane[2] = 1.0F; 1503 plane[3] = -prim->verts[0].xyz[2]; 1504 break; 1505 default : 1506 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Unknow 1507 plane[0] = plane[1] = plane[3] = 0.0F; 1508 plane[2] = 1.0F; 1509 break; 1510 } 1511 } 1512 1513 inline void tools_gl2psCutEdge(tools_GL2PSver 1514 tools_GL2PSvertex *c 1515 { 1516 tools_GL2PSxyz v; 1517 tools_GLfloat sect, psca; 1518 1519 v[0] = b->xyz[0] - a->xyz[0]; 1520 v[1] = b->xyz[1] - a->xyz[1]; 1521 v[2] = b->xyz[2] - a->xyz[2]; 1522 1523 if(!TOOLS_GL2PS_ZERO(psca = tools_gl2psPsca 1524 sect = -tools_gl2psComparePointPlane(a->x 1525 else 1526 sect = 0.0F; 1527 1528 c->xyz[0] = a->xyz[0] + v[0] * sect; 1529 c->xyz[1] = a->xyz[1] + v[1] * sect; 1530 c->xyz[2] = a->xyz[2] + v[2] * sect; 1531 1532 c->rgba[0] = (1 - sect) * a->rgba[0] + sect 1533 c->rgba[1] = (1 - sect) * a->rgba[1] + sect 1534 c->rgba[2] = (1 - sect) * a->rgba[2] + sect 1535 c->rgba[3] = (1 - sect) * a->rgba[3] + sect 1536 } 1537 1538 inline void tools_gl2psCreateSplitPrimitive(t 1539 tools_G 1540 tools_G 1541 { 1542 tools_GLshort i; 1543 1544 if(parent->type == TOOLS_GL2PS_IMAGEMAP){ 1545 child->type = TOOLS_GL2PS_IMAGEMAP; 1546 child->data.image = parent->data.image; 1547 } 1548 else{ 1549 if(numverts > 4){ 1550 tools_gl2psMsg(TOOLS_GL2PS_WARNING, "%d 1551 numverts = 4; 1552 } 1553 switch(numverts){ 1554 case 1 : child->type = TOOLS_GL2PS_POINT; 1555 case 2 : child->type = TOOLS_GL2PS_LINE; 1556 case 3 : child->type = TOOLS_GL2PS_TRIANG 1557 case 4 : child->type = TOOLS_GL2PS_QUADRA 1558 default: child->type = TOOLS_GL2PS_NO_TYP 1559 } 1560 } 1561 1562 child->boundary = 0; /* FIXME: not done! */ 1563 child->culled = parent->culled; 1564 child->offset = parent->offset; 1565 child->ofactor = parent->ofactor; 1566 child->ounits = parent->ounits; 1567 child->pattern = parent->pattern; 1568 child->factor = parent->factor; 1569 child->width = parent->width; 1570 child->linecap = parent->linecap; 1571 child->linejoin = parent->linejoin; 1572 child->numverts = numverts; 1573 child->verts = (tools_GL2PSvertex*)tools_gl 1574 1575 for(i = 0; i < numverts; i++){ 1576 if(index1[i] < 0){ 1577 child->verts[i] = parent->verts[index0[ 1578 } 1579 else{ 1580 tools_gl2psCutEdge(&parent->verts[index 1581 plane, &child->verts[i]); 1582 } 1583 } 1584 } 1585 1586 inline void tools_gl2psAddIndex(tools_GLshort 1587 tools_GLshort i, to 1588 { 1589 tools_GLint k; 1590 1591 for(k = 0; k < *nb; k++){ 1592 if((index0[k] == i && index1[k] == j) || 1593 (index1[k] == i && index0[k] == j)) re 1594 } 1595 index0[*nb] = i; 1596 index1[*nb] = j; 1597 (*nb)++; 1598 } 1599 1600 inline tools_GLshort tools_gl2psGetIndex(tool 1601 { 1602 return (i < num - 1) ? i + 1 : 0; 1603 } 1604 1605 inline tools_GLint tools_gl2psTestSplitPrimit 1606 { 1607 tools_GLint type = TOOLS_GL2PS_COINCIDENT; 1608 tools_GLshort i, j; 1609 tools_GLfloat d[5]; 1610 1611 for(i = 0; i < prim->numverts; i++){ 1612 d[i] = tools_gl2psComparePointPlane(prim- 1613 } 1614 1615 if(prim->numverts < 2){ 1616 return 0; 1617 } 1618 else{ 1619 for(i = 0; i < prim->numverts; i++){ 1620 j = tools_gl2psGetIndex(i, prim->numver 1621 if(d[j] > TOOLS_GL2PS_EPSILON){ 1622 if(type == TOOLS_GL2PS_COINCIDENT) 1623 else if(type != TOOLS_GL2PS_IN_BACK_O 1624 if(d[i] < -TOOLS_GL2PS_EPSILON) 1625 } 1626 else if(d[j] < -TOOLS_GL2PS_EPSILON){ 1627 if(type == TOOLS_GL2PS_COINCIDENT) 1628 else if(type != TOOLS_GL2PS_IN_FRONT_ 1629 if(d[i] > TOOLS_GL2PS_EPSILON) 1630 } 1631 } 1632 } 1633 return 0; 1634 } 1635 1636 inline tools_GLint tools_gl2psSplitPrimitive( 1637 tools_GL2PSp 1638 { 1639 tools_GLshort i, j, in = 0, out = 0, in0[5] 1640 tools_GLint type; 1641 tools_GLfloat d[5] = {0.0}; 1642 1643 type = TOOLS_GL2PS_COINCIDENT; 1644 1645 for(i = 0; i < prim->numverts; i++){ 1646 d[i] = tools_gl2psComparePointPlane(prim- 1647 } 1648 1649 switch(prim->type){ 1650 case TOOLS_GL2PS_POINT : 1651 if(d[0] > TOOLS_GL2PS_EPSILON) type 1652 else if(d[0] < -TOOLS_GL2PS_EPSILON) type 1653 else type = TOO 1654 break; 1655 default : 1656 for(i = 0; i < prim->numverts; i++){ 1657 j = tools_gl2psGetIndex(i, prim->numver 1658 if(d[j] > TOOLS_GL2PS_EPSILON){ 1659 if(type == TOOLS_GL2PS_COINCIDENT) 1660 else if(type != TOOLS_GL2PS_IN_BACK_O 1661 if(d[i] < -TOOLS_GL2PS_EPSILON){ 1662 tools_gl2psAddIndex(in0, in1, &in, 1663 tools_gl2psAddIndex(out0, out1, &ou 1664 type = TOOLS_GL2PS_SPANNING; 1665 } 1666 tools_gl2psAddIndex(out0, out1, &out, 1667 } 1668 else if(d[j] < -TOOLS_GL2PS_EPSILON){ 1669 if(type == TOOLS_GL2PS_COINCIDENT) 1670 else if(type != TOOLS_GL2PS_IN_FRONT_ 1671 if(d[i] > TOOLS_GL2PS_EPSILON){ 1672 tools_gl2psAddIndex(in0, in1, &in, 1673 tools_gl2psAddIndex(out0, out1, &ou 1674 type = TOOLS_GL2PS_SPANNING; 1675 } 1676 tools_gl2psAddIndex(in0, in1, &in, j, 1677 } 1678 else{ 1679 tools_gl2psAddIndex(in0, in1, &in, j, 1680 tools_gl2psAddIndex(out0, out1, &out, 1681 } 1682 } 1683 break; 1684 } 1685 1686 if(type == TOOLS_GL2PS_SPANNING){ 1687 *back = (tools_GL2PSprimitive*)tools_gl2p 1688 *front = (tools_GL2PSprimitive*)tools_gl2 1689 tools_gl2psCreateSplitPrimitive(prim, pla 1690 tools_gl2psCreateSplitPrimitive(prim, pla 1691 } 1692 1693 return type; 1694 } 1695 1696 inline void tools_gl2psDivideQuad(tools_GL2PS 1697 tools_GL2PSprimit 1698 { 1699 *t1 = (tools_GL2PSprimitive*)tools_gl2psMal 1700 *t2 = (tools_GL2PSprimitive*)tools_gl2psMal 1701 (*t1)->type = (*t2)->type = TOOLS_GL2PS_TRI 1702 (*t1)->numverts = (*t2)->numverts = 3; 1703 (*t1)->culled = (*t2)->culled = quad->culle 1704 (*t1)->offset = (*t2)->offset = quad->offse 1705 (*t1)->ofactor = (*t2)->ofactor = quad->ofa 1706 (*t1)->ounits = (*t2)->ounits = quad->ounit 1707 (*t1)->pattern = (*t2)->pattern = quad->pat 1708 (*t1)->factor = (*t2)->factor = quad->facto 1709 (*t1)->width = (*t2)->width = quad->width; 1710 (*t1)->linecap = (*t2)->linecap = quad->lin 1711 (*t1)->linejoin = (*t2)->linejoin = quad->l 1712 (*t1)->verts = (tools_GL2PSvertex*)tools_gl 1713 (*t2)->verts = (tools_GL2PSvertex*)tools_gl 1714 (*t1)->verts[0] = quad->verts[0]; 1715 (*t1)->verts[1] = quad->verts[1]; 1716 (*t1)->verts[2] = quad->verts[2]; 1717 (*t1)->boundary = ((quad->boundary & 1) ? 1 1718 (*t2)->verts[0] = quad->verts[0]; 1719 (*t2)->verts[1] = quad->verts[2]; 1720 (*t2)->verts[2] = quad->verts[3]; 1721 (*t2)->boundary = ((quad->boundary & 4) ? 2 1722 } 1723 1724 inline int tools_gl2psCompareDepth(const void 1725 { 1726 const tools_GL2PSprimitive *q, *w; 1727 tools_GLfloat dq = 0.0F, dw = 0.0F, diff; 1728 int i; 1729 1730 q = *(const tools_GL2PSprimitive* const*)a; 1731 w = *(const tools_GL2PSprimitive* const*)b; 1732 1733 for(i = 0; i < q->numverts; i++){ 1734 dq += q->verts[i].xyz[2]; 1735 } 1736 dq /= (tools_GLfloat)q->numverts; 1737 1738 for(i = 0; i < w->numverts; i++){ 1739 dw += w->verts[i].xyz[2]; 1740 } 1741 dw /= (tools_GLfloat)w->numverts; 1742 1743 diff = dq - dw; 1744 if(diff > 0.){ 1745 return -1; 1746 } 1747 else if(diff < 0.){ 1748 return 1; 1749 } 1750 else{ 1751 /* Ensure that initial ordering is preser 1752 if(q->sortid==w->sortid) return 0; //G.B 1753 return q->sortid < w->sortid ? -1 : 1; 1754 } 1755 } 1756 1757 inline int tools_gl2psTrianglesFirst(const vo 1758 { 1759 const tools_GL2PSprimitive *q, *w; 1760 1761 q = *(const tools_GL2PSprimitive* const*)a; 1762 w = *(const tools_GL2PSprimitive* const*)b; 1763 if(q->type==w->type) return 0; //G.Barrand 1764 return (q->type < w->type ? 1 : -1); 1765 } 1766 1767 inline tools_GLint tools_gl2psFindRoot(tools_ 1768 { 1769 tools_GLint i, j, count, best = 1000000, id 1770 tools_GL2PSprimitive *prim1, *prim2; 1771 tools_GL2PSplane plane; 1772 tools_GLint maxp; 1773 1774 if(!tools_gl2psListNbr(primitives)){ 1775 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Cannot 1776 *root = 0; /*G.Barrand: to quiet gcc.*/ 1777 return 0; 1778 } 1779 1780 *root = *(tools_GL2PSprimitive**)tools_gl2p 1781 1782 if(gl2ps->options & TOOLS_GL2PS_BEST_ROOT){ 1783 maxp = tools_gl2psListNbr(primitives); 1784 if(maxp > gl2ps->maxbestroot){ 1785 maxp = gl2ps->maxbestroot; 1786 } 1787 for(i = 0; i < maxp; i++){ 1788 prim1 = *(tools_GL2PSprimitive**)tools_ 1789 tools_gl2psGetPlane(prim1, plane); 1790 count = 0; 1791 for(j = 0; j < tools_gl2psListNbr(primi 1792 if(j != i){ 1793 prim2 = *(tools_GL2PSprimitive**)to 1794 count += tools_gl2psTestSplitPrimit 1795 } 1796 if(count > best) break; 1797 } 1798 if(count < best){ 1799 best = count; 1800 idx = i; 1801 *root = prim1; 1802 if(!count) return idx; 1803 } 1804 } 1805 /* if(index) tools_gl2psMsg(TOOLS_GL2PS_I 1806 return idx; 1807 } 1808 else{ 1809 return 0; 1810 } 1811 } 1812 1813 inline void tools_gl2psFreeImagemap(tools_GL2 1814 { 1815 tools_GL2PSimagemap *next; 1816 while(list != NULL){ 1817 next = list->next; 1818 tools_gl2psFree(list->image->pixels); 1819 tools_gl2psFree(list->image); 1820 tools_gl2psFree(list); 1821 list = next; 1822 } 1823 } 1824 1825 inline void tools_gl2psFreePrimitive(void *da 1826 { 1827 tools_GL2PSprimitive *q; 1828 1829 q = *(tools_GL2PSprimitive**)data; 1830 tools_gl2psFree(q->verts); 1831 if(q->type == TOOLS_GL2PS_TEXT || q->type = 1832 tools_gl2psFreeText(q->data.text); 1833 } 1834 else if(q->type == TOOLS_GL2PS_PIXMAP){ 1835 tools_gl2psFreePixmap(q->data.image); 1836 } 1837 tools_gl2psFree(q); 1838 } 1839 1840 inline void tools_gl2psAddPrimitiveInList(too 1841 { 1842 tools_GL2PSprimitive *t1, *t2; 1843 1844 if(prim->type != TOOLS_GL2PS_QUADRANGLE){ 1845 tools_gl2psListAdd(list, &prim); 1846 } 1847 else{ 1848 tools_gl2psDivideQuad(prim, &t1, &t2); 1849 tools_gl2psListAdd(list, &t1); 1850 tools_gl2psListAdd(list, &t2); 1851 tools_gl2psFreePrimitive(&prim); 1852 } 1853 1854 } 1855 1856 inline void tools_gl2psFreeBspTree(tools_GL2P 1857 { 1858 if(*tree){ 1859 if((*tree)->back) tools_gl2psFreeBspTree( 1860 if((*tree)->primitives){ 1861 tools_gl2psListAction((*tree)->primitiv 1862 tools_gl2psListDelete((*tree)->primitiv 1863 } 1864 if((*tree)->front) tools_gl2psFreeBspTree 1865 tools_gl2psFree(*tree); 1866 *tree = NULL; 1867 } 1868 } 1869 1870 inline tools_GLboolean tools_gl2psGreater(too 1871 { 1872 if(f1 > f2) return TOOLS_GL_TRUE; 1873 else return TOOLS_GL_FALSE; 1874 } 1875 1876 inline tools_GLboolean tools_gl2psLess(tools_ 1877 { 1878 if(f1 < f2) return TOOLS_GL_TRUE; 1879 else return TOOLS_GL_FALSE; 1880 } 1881 1882 inline void tools_gl2psBuildBspTree(tools_GL2 1883 { 1884 tools_GL2PSprimitive *prim = NULL, *frontpr 1885 tools_GL2PSlist *frontlist, *backlist; 1886 tools_GLint i, idx; 1887 1888 tree->front = NULL; 1889 tree->back = NULL; 1890 tree->primitives = tools_gl2psListCreate(1, 1891 idx = tools_gl2psFindRoot(gl2ps, primitives 1892 tools_gl2psGetPlane(prim, tree->plane); 1893 tools_gl2psAddPrimitiveInList(prim, tree->p 1894 1895 frontlist = tools_gl2psListCreate(1, 2, siz 1896 backlist = tools_gl2psListCreate(1, 2, size 1897 1898 for(i = 0; i < tools_gl2psListNbr(primitive 1899 if(i != idx){ 1900 prim = *(tools_GL2PSprimitive**)tools_g 1901 switch(tools_gl2psSplitPrimitive(prim, 1902 case TOOLS_GL2PS_COINCIDENT: 1903 tools_gl2psAddPrimitiveInList(prim, t 1904 break; 1905 case TOOLS_GL2PS_IN_BACK_OF: 1906 tools_gl2psAddPrimitiveInList(prim, b 1907 break; 1908 case TOOLS_GL2PS_IN_FRONT_OF: 1909 tools_gl2psAddPrimitiveInList(prim, f 1910 break; 1911 case TOOLS_GL2PS_SPANNING: 1912 tools_gl2psAddPrimitiveInList(backpri 1913 tools_gl2psAddPrimitiveInList(frontpr 1914 tools_gl2psFreePrimitive(&prim); 1915 break; 1916 } 1917 } 1918 } 1919 1920 if(tools_gl2psListNbr(tree->primitives)){ 1921 tools_gl2psListSort(gl2ps, tree->primitiv 1922 } 1923 1924 if(tools_gl2psListNbr(frontlist)){ 1925 tools_gl2psListSort(gl2ps, frontlist, too 1926 tree->front = (tools_GL2PSbsptree*)tools_ 1927 tools_gl2psBuildBspTree(gl2ps, tree->fron 1928 } 1929 else{ 1930 tools_gl2psListDelete(frontlist); 1931 } 1932 1933 if(tools_gl2psListNbr(backlist)){ 1934 tools_gl2psListSort(gl2ps, backlist, tool 1935 tree->back = (tools_GL2PSbsptree*)tools_g 1936 tools_gl2psBuildBspTree(gl2ps, tree->back 1937 } 1938 else{ 1939 tools_gl2psListDelete(backlist); 1940 } 1941 1942 tools_gl2psListDelete(primitives); 1943 } 1944 1945 inline void tools_gl2psTraverseBspTree(tools_ 1946 tools_GLbool 1947 void (*actio 1948 { 1949 tools_GLfloat result; 1950 1951 if(!tree) return; 1952 1953 result = tools_gl2psComparePointPlane(eye, 1954 1955 if(TOOLS_GL_TRUE == compare(result, epsilon 1956 tools_gl2psTraverseBspTree(gl2ps, tree->b 1957 if(inverse){ 1958 tools_gl2psListActionInverseContext(gl2 1959 } 1960 else{ 1961 tools_gl2psListActionContext(gl2ps, tre 1962 } 1963 tools_gl2psTraverseBspTree(gl2ps, tree->f 1964 } 1965 else if(TOOLS_GL_TRUE == compare(-epsilon, 1966 tools_gl2psTraverseBspTree(gl2ps, tree->f 1967 if(inverse){ 1968 tools_gl2psListActionInverseContext(gl2 1969 } 1970 else{ 1971 tools_gl2psListActionContext(gl2ps, tre 1972 } 1973 tools_gl2psTraverseBspTree(gl2ps, tree->b 1974 } 1975 else{ 1976 tools_gl2psTraverseBspTree(gl2ps, tree->f 1977 tools_gl2psTraverseBspTree(gl2ps, tree->b 1978 } 1979 } 1980 1981 inline void tools_gl2psRescaleAndOffset(tools 1982 { 1983 tools_GL2PSprimitive *prim; 1984 tools_GLfloat minZ, maxZ, rangeZ, scaleZ; 1985 tools_GLfloat factor, units, area, dZ, dZdX 1986 int i, j; 1987 1988 if(!tools_gl2psListNbr(gl2ps->primitives)) 1989 return; 1990 1991 /* get z-buffer range */ 1992 prim = *(tools_GL2PSprimitive**)tools_gl2ps 1993 minZ = maxZ = prim->verts[0].xyz[2]; 1994 for(i = 1; i < prim->numverts; i++){ 1995 if(prim->verts[i].xyz[2] < minZ) minZ = p 1996 if(prim->verts[i].xyz[2] > maxZ) maxZ = p 1997 } 1998 for(i = 1; i < tools_gl2psListNbr(gl2ps->pr 1999 prim = *(tools_GL2PSprimitive**)tools_gl2 2000 for(j = 0; j < prim->numverts; j++){ 2001 if(prim->verts[j].xyz[2] < minZ) minZ = 2002 if(prim->verts[j].xyz[2] > maxZ) maxZ = 2003 } 2004 } 2005 rangeZ = (maxZ - minZ); 2006 2007 /* rescale z-buffer coordinate in [0,TOOLS_ 2008 the same order of magnitude as the x and 2009 scaleZ = TOOLS_GL2PS_ZERO(rangeZ) ? TOOLS_G 2010 /* avoid precision loss (we use floats!) */ 2011 if(scaleZ > 100000.F) scaleZ = 100000.F; 2012 2013 /* apply offsets */ 2014 for(i = 0; i < tools_gl2psListNbr(gl2ps->pr 2015 prim = *(tools_GL2PSprimitive**)tools_gl2 2016 for(j = 0; j < prim->numverts; j++){ 2017 prim->verts[j].xyz[2] = (prim->verts[j] 2018 } 2019 if((gl2ps->options & TOOLS_GL2PS_SIMPLE_L 2020 (prim->type == TOOLS_GL2PS_LINE)){ 2021 if(gl2ps->sort == TOOLS_GL2PS_SIMPLE_SO 2022 prim->verts[0].xyz[2] -= TOOLS_GL2PS_ 2023 prim->verts[1].xyz[2] -= TOOLS_GL2PS_ 2024 } 2025 else{ 2026 prim->verts[0].xyz[2] -= TOOLS_GL2PS_ 2027 prim->verts[1].xyz[2] -= TOOLS_GL2PS_ 2028 } 2029 } 2030 else if(prim->offset && (prim->type == TO 2031 factor = prim->ofactor; 2032 units = prim->ounits; 2033 area = 2034 (prim->verts[1].xyz[0] - prim->verts[ 2035 (prim->verts[2].xyz[1] - prim->verts[ 2036 (prim->verts[2].xyz[0] - prim->verts[ 2037 (prim->verts[1].xyz[1] - prim->verts[ 2038 if(!TOOLS_GL2PS_ZERO(area)){ 2039 dZdX = 2040 ((prim->verts[2].xyz[1] - prim->ver 2041 (prim->verts[1].xyz[2] - prim->ver 2042 (prim->verts[1].xyz[1] - prim->ver 2043 (prim->verts[2].xyz[2] - prim->ver 2044 dZdY = 2045 ((prim->verts[1].xyz[0] - prim->ver 2046 (prim->verts[2].xyz[2] - prim->ver 2047 (prim->verts[2].xyz[0] - prim->ver 2048 (prim->verts[1].xyz[2] - prim->ver 2049 maxdZ = (tools_GLfloat)sqrt(dZdX * dZ 2050 } 2051 else{ 2052 maxdZ = 0.0F; 2053 } 2054 dZ = factor * maxdZ + units; 2055 prim->verts[0].xyz[2] += dZ; 2056 prim->verts[1].xyz[2] += dZ; 2057 prim->verts[2].xyz[2] += dZ; 2058 } 2059 } 2060 } 2061 2062 /******************************************** 2063 * 2064 * 2D sorting routines (for occlusion culling 2065 * 2066 ******************************************** 2067 2068 inline tools_GLint tools_gl2psGetPlaneFromPoi 2069 { 2070 tools_GLfloat n; 2071 2072 plane[0] = b[1] - a[1]; 2073 plane[1] = a[0] - b[0]; 2074 n = (tools_GLfloat)sqrt(plane[0]*plane[0] + 2075 plane[2] = 0.0F; 2076 if(!TOOLS_GL2PS_ZERO(n)){ 2077 plane[0] /= n; 2078 plane[1] /= n; 2079 plane[3] = -plane[0]*a[0]-plane[1]*a[1]; 2080 return 1; 2081 } 2082 else{ 2083 plane[0] = -1.0F; 2084 plane[1] = 0.0F; 2085 plane[3] = a[0]; 2086 return 0; 2087 } 2088 } 2089 2090 inline void tools_gl2psFreeBspImageTree(tools 2091 { 2092 if(*tree){ 2093 if((*tree)->back) tools_gl2psFreeBspImag 2094 if((*tree)->front) tools_gl2psFreeBspImag 2095 tools_gl2psFree(*tree); 2096 *tree = NULL; 2097 } 2098 } 2099 2100 inline tools_GLint tools_gl2psCheckPoint(tool 2101 { 2102 tools_GLfloat pt_dis; 2103 2104 pt_dis = tools_gl2psComparePointPlane(point 2105 if(pt_dis > TOOLS_GL2PS_EPSILON) ret 2106 else if(pt_dis < -TOOLS_GL2PS_EPSILON) ret 2107 else return TO 2108 } 2109 2110 inline void tools_gl2psAddPlanesInBspTreeImag 2111 tool 2112 { 2113 tools_GLint ret = 0; 2114 tools_GLint i; 2115 tools_GLint offset = 0; 2116 tools_GL2PSbsptree2d *head = NULL, *cur = N 2117 2118 if((*tree == NULL) && (prim->numverts > 2)) 2119 /* don't cull if transparent 2120 for(i = 0; i < prim->numverts - 1; i++) 2121 if(prim->verts[i].rgba[3] < 1.0F) retur 2122 */ 2123 head = (tools_GL2PSbsptree2d*)tools_gl2ps 2124 for(i = 0; i < prim->numverts-1; i++){ 2125 if(!tools_gl2psGetPlaneFromPoints(prim- 2126 prim->verts 2127 head->plane 2128 if(prim->numverts-i > 3){ 2129 offset++; 2130 } 2131 else{ 2132 tools_gl2psFree(head); 2133 return; 2134 } 2135 } 2136 else{ 2137 break; 2138 } 2139 } 2140 head->back = NULL; 2141 head->front = NULL; 2142 for(i = 2+offset; i < prim->numverts; i++ 2143 ret = tools_gl2psCheckPoint(prim->verts 2144 if(ret != TOOLS_GL2PS_POINT_COINCIDENT) 2145 } 2146 switch(ret){ 2147 case TOOLS_GL2PS_POINT_INFRONT : 2148 cur = head; 2149 for(i = 1+offset; i < prim->numverts-1; 2150 if(cur->front == NULL){ 2151 cur->front = (tools_GL2PSbsptree2d* 2152 } 2153 if(tools_gl2psGetPlaneFromPoints(prim 2154 prim->vert 2155 cur->front 2156 cur = cur->front; 2157 cur->front = NULL; 2158 cur->back = NULL; 2159 } 2160 } 2161 if(cur->front == NULL){ 2162 cur->front = (tools_GL2PSbsptree2d*)t 2163 } 2164 if(tools_gl2psGetPlaneFromPoints(prim-> 2165 prim->verts[ 2166 cur->front-> 2167 cur->front->front = NULL; 2168 cur->front->back = NULL; 2169 } 2170 else{ 2171 tools_gl2psFree(cur->front); 2172 cur->front = NULL; 2173 } 2174 break; 2175 case TOOLS_GL2PS_POINT_BACK : 2176 for(i = 0; i < 4; i++){ 2177 head->plane[i] = -head->plane[i]; 2178 } 2179 cur = head; 2180 for(i = 1+offset; i < prim->numverts-1; 2181 if(cur->front == NULL){ 2182 cur->front = (tools_GL2PSbsptree2d* 2183 } 2184 if(tools_gl2psGetPlaneFromPoints(prim 2185 prim->vert 2186 cur->front 2187 cur = cur->front; 2188 cur->front = NULL; 2189 cur->back = NULL; 2190 } 2191 } 2192 if(cur->front == NULL){ 2193 cur->front = (tools_GL2PSbsptree2d*)t 2194 } 2195 if(tools_gl2psGetPlaneFromPoints(prim-> 2196 prim->verts[ 2197 cur->front-> 2198 cur->front->front = NULL; 2199 cur->front->back = NULL; 2200 } 2201 else{ 2202 tools_gl2psFree(cur->front); 2203 cur->front = NULL; 2204 } 2205 break; 2206 default: 2207 tools_gl2psFree(head); 2208 return; 2209 } 2210 (*tree) = head; 2211 } 2212 } 2213 2214 inline tools_GLint tools_gl2psCheckPrimitive( 2215 { 2216 tools_GLint i; 2217 tools_GLint pos; 2218 2219 pos = tools_gl2psCheckPoint(prim->verts[0]. 2220 for(i = 1; i < prim->numverts; i++){ 2221 pos |= tools_gl2psCheckPoint(prim->verts[ 2222 if(pos == (TOOLS_GL2PS_POINT_INFRONT | TO 2223 } 2224 if(pos & TOOLS_GL2PS_POINT_INFRONT) retur 2225 else if(pos & TOOLS_GL2PS_POINT_BACK) retur 2226 else return TOOL 2227 } 2228 2229 inline tools_GL2PSprimitive *tools_gl2psCreat 2230 2231 2232 { 2233 tools_GLint i; 2234 tools_GL2PSprimitive *child = (tools_GL2PSp 2235 2236 if(parent->type == TOOLS_GL2PS_IMAGEMAP){ 2237 child->type = TOOLS_GL2PS_IMAGEMAP; 2238 child->data.image = parent->data.image; 2239 } 2240 else { 2241 switch(numverts){ 2242 case 1 : child->type = TOOLS_GL2PS_POINT; 2243 case 2 : child->type = TOOLS_GL2PS_LINE; 2244 case 3 : child->type = TOOLS_GL2PS_TRIANG 2245 case 4 : child->type = TOOLS_GL2PS_QUADRA 2246 default: child->type = TOOLS_GL2PS_NO_TYP 2247 } 2248 } 2249 child->boundary = 0; /* FIXME: not done! */ 2250 child->culled = parent->culled; 2251 child->offset = parent->offset; 2252 child->ofactor = parent->ofactor; 2253 child->ounits = parent->ounits; 2254 child->pattern = parent->pattern; 2255 child->factor = parent->factor; 2256 child->width = parent->width; 2257 child->linecap = parent->linecap; 2258 child->linejoin = parent->linejoin; 2259 child->numverts = numverts; 2260 child->verts = (tools_GL2PSvertex*)tools_gl 2261 for(i = 0; i < numverts; i++){ 2262 child->verts[i] = vertx[i]; 2263 } 2264 return child; 2265 } 2266 2267 inline void tools_gl2psSplitPrimitive2D(tools 2268 tools_GL2PS 2269 tools_GL2PS 2270 tools_GL2PS 2271 { 2272 /* cur will hold the position of the curren 2273 prev will hold the position of the previ 2274 prev0 will hold the position of the vert 2275 v1 and v2 represent the current and prev 2276 flag is set if the current vertex should 2277 tools_GLint cur = -1, prev = -1, i, v1 = 0, 2278 2279 /* list of vertices that will go in front a 2280 tools_GL2PSvertex *front_list = NULL, *back 2281 2282 /* number of vertices in front and back lis 2283 tools_GLshort front_count = 0, back_count = 2284 2285 for(i = 0; i <= prim->numverts; i++){ 2286 v1 = i; 2287 if(v1 == prim->numverts){ 2288 if(prim->numverts < 3) break; 2289 v1 = 0; 2290 v2 = prim->numverts - 1; 2291 cur = prev0; 2292 } 2293 else if(flag){ 2294 cur = tools_gl2psCheckPoint(prim->verts 2295 if(i == 0){ 2296 prev0 = cur; 2297 } 2298 } 2299 if(((prev == -1) || (prev == cur) || (pre 2300 (i < prim->numverts)){ 2301 if(cur == TOOLS_GL2PS_POINT_INFRONT){ 2302 front_count++; 2303 front_list = (tools_GL2PSvertex*)tool 2304 2305 front_list[front_count-1] = prim->ver 2306 } 2307 else if(cur == TOOLS_GL2PS_POINT_BACK){ 2308 back_count++; 2309 back_list = (tools_GL2PSvertex*)tools 2310 2311 back_list[back_count-1] = prim->verts 2312 } 2313 else{ 2314 front_count++; 2315 front_list = (tools_GL2PSvertex*)tool 2316 2317 front_list[front_count-1] = prim->ver 2318 back_count++; 2319 back_list = (tools_GL2PSvertex*)tools 2320 2321 back_list[back_count-1] = prim->verts 2322 } 2323 flag = 1; 2324 } 2325 else if((prev != cur) && (cur != 0) && (p 2326 if(v1 != 0){ 2327 v2 = v1-1; 2328 i--; 2329 } 2330 front_count++; 2331 front_list = (tools_GL2PSvertex*)tools_ 2332 2333 tools_gl2psCutEdge(&prim->verts[v2], &p 2334 plane, &front_list[front_c 2335 back_count++; 2336 back_list = (tools_GL2PSvertex*)tools_g 2337 2338 back_list[back_count-1] = front_list[fr 2339 flag = 0; 2340 } 2341 prev = cur; 2342 } 2343 *front = tools_gl2psCreateSplitPrimitive2D( 2344 *back = tools_gl2psCreateSplitPrimitive2D(p 2345 tools_gl2psFree(front_list); 2346 tools_gl2psFree(back_list); 2347 } 2348 2349 inline tools_GLint tools_gl2psAddInBspImageTr 2350 { 2351 tools_GLint ret = 0; 2352 tools_GL2PSprimitive *frontprim = NULL, *ba 2353 2354 /* FIXME: until we consider the actual exte 2355 pixmaps, never cull them. Otherwise the 2356 culled as soon as the reference point is 2357 if(prim->type == TOOLS_GL2PS_PIXMAP || 2358 prim->type == TOOLS_GL2PS_TEXT || 2359 prim->type == TOOLS_GL2PS_SPECIAL){ 2360 return 1; 2361 } 2362 2363 if(*tree == NULL){ 2364 if((prim->type != TOOLS_GL2PS_IMAGEMAP) & 2365 tools_gl2psAddPlanesInBspTreeImage(gl2p 2366 } 2367 return 1; 2368 } 2369 else{ 2370 switch(tools_gl2psCheckPrimitive(prim, (* 2371 case TOOLS_GL2PS_IN_BACK_OF: return tools 2372 case TOOLS_GL2PS_IN_FRONT_OF: 2373 if((*tree)->front != NULL) return tools 2374 else return 0; 2375 case TOOLS_GL2PS_SPANNING: 2376 tools_gl2psSplitPrimitive2D(prim, (*tre 2377 ret = tools_gl2psAddInBspImageTree(gl2p 2378 if((*tree)->front != NULL){ 2379 if(tools_gl2psAddInBspImageTree(gl2ps 2380 ret = 1; 2381 } 2382 } 2383 tools_gl2psFree(frontprim->verts); 2384 tools_gl2psFree(frontprim); 2385 tools_gl2psFree(backprim->verts); 2386 tools_gl2psFree(backprim); 2387 return ret; 2388 case TOOLS_GL2PS_COINCIDENT: 2389 if((*tree)->back != NULL){ 2390 gl2ps->zerosurfacearea = TOOLS_GL_TRU 2391 ret = tools_gl2psAddInBspImageTree(gl 2392 gl2ps->zerosurfacearea = TOOLS_GL_FAL 2393 if(ret) return ret; 2394 } 2395 if((*tree)->front != NULL){ 2396 gl2ps->zerosurfacearea = TOOLS_GL_TRU 2397 ret = tools_gl2psAddInBspImageTree(gl 2398 gl2ps->zerosurfacearea = TOOLS_GL_FAL 2399 if(ret) return ret; 2400 } 2401 if(prim->type == TOOLS_GL2PS_LINE) retu 2402 else return 0; 2403 } 2404 } 2405 return 0; 2406 } 2407 2408 inline void tools_gl2psAddInImageTree(tools_G 2409 { 2410 tools_GL2PSprimitive *prim = *(tools_GL2PSp 2411 gl2ps->primitivetoadd = prim; 2412 if(prim->type == TOOLS_GL2PS_IMAGEMAP && pr 2413 prim->culled = 1; 2414 } 2415 else if(!tools_gl2psAddInBspImageTree(gl2ps 2416 prim->culled = 1; 2417 } 2418 else if(prim->type == TOOLS_GL2PS_IMAGEMAP) 2419 prim->data.image->format = TOOLS_GL2PS_IM 2420 } 2421 } 2422 2423 /* Boundary construction */ 2424 2425 inline void tools_gl2psAddBoundaryInList(tool 2426 { 2427 tools_GL2PSprimitive *b; 2428 tools_GLshort i; 2429 tools_GL2PSxyz c; 2430 2431 c[0] = c[1] = c[2] = 0.0F; 2432 for(i = 0; i < prim->numverts; i++){ 2433 c[0] += prim->verts[i].xyz[0]; 2434 c[1] += prim->verts[i].xyz[1]; 2435 } 2436 c[0] /= prim->numverts; 2437 c[1] /= prim->numverts; 2438 2439 for(i = 0; i < prim->numverts; i++){ 2440 if(prim->boundary & (tools_GLint)pow(2., 2441 b = (tools_GL2PSprimitive*)tools_gl2psM 2442 b->type = TOOLS_GL2PS_LINE; 2443 b->offset = prim->offset; 2444 b->ofactor = prim->ofactor; 2445 b->ounits = prim->ounits; 2446 b->pattern = prim->pattern; 2447 b->factor = prim->factor; 2448 b->culled = prim->culled; 2449 b->width = prim->width; 2450 b->linecap = prim->linecap; 2451 b->linejoin = prim->linejoin; 2452 b->boundary = 0; 2453 b->numverts = 2; 2454 b->verts = (tools_GL2PSvertex*)tools_gl 2455 2456 #if 0 /* FIXME: need to work on boundary offs 2457 v[0] = c[0] - prim->verts[i].xyz[0]; 2458 v[1] = c[1] - prim->verts[i].xyz[1]; 2459 v[2] = 0.0F; 2460 norm = tools_gl2psNorm(v); 2461 v[0] /= norm; 2462 v[1] /= norm; 2463 b->verts[0].xyz[0] = prim->verts[i].xyz 2464 b->verts[0].xyz[1] = prim->verts[i].xyz 2465 b->verts[0].xyz[2] = prim->verts[i].xyz 2466 v[0] = c[0] - prim->verts[tools_gl2psGe 2467 v[1] = c[1] - prim->verts[tools_gl2psGe 2468 norm = tools_gl2psNorm(v); 2469 v[0] /= norm; 2470 v[1] /= norm; 2471 b->verts[1].xyz[0] = prim->verts[tools_ 2472 b->verts[1].xyz[1] = prim->verts[tools_ 2473 b->verts[1].xyz[2] = prim->verts[tools_ 2474 #else 2475 b->verts[0].xyz[0] = prim->verts[i].xyz 2476 b->verts[0].xyz[1] = prim->verts[i].xyz 2477 b->verts[0].xyz[2] = prim->verts[i].xyz 2478 b->verts[1].xyz[0] = prim->verts[tools_ 2479 b->verts[1].xyz[1] = prim->verts[tools_ 2480 b->verts[1].xyz[2] = prim->verts[tools_ 2481 #endif 2482 2483 b->verts[0].rgba[0] = 0.0F; 2484 b->verts[0].rgba[1] = 0.0F; 2485 b->verts[0].rgba[2] = 0.0F; 2486 b->verts[0].rgba[3] = 0.0F; 2487 b->verts[1].rgba[0] = 0.0F; 2488 b->verts[1].rgba[1] = 0.0F; 2489 b->verts[1].rgba[2] = 0.0F; 2490 b->verts[1].rgba[3] = 0.0F; 2491 tools_gl2psListAdd(list, &b); 2492 } 2493 } 2494 2495 } 2496 2497 inline void tools_gl2psBuildPolygonBoundary(t 2498 { 2499 tools_GLint i; 2500 tools_GL2PSprimitive *prim; 2501 2502 if(!tree) return; 2503 tools_gl2psBuildPolygonBoundary(tree->back) 2504 for(i = 0; i < tools_gl2psListNbr(tree->pri 2505 prim = *(tools_GL2PSprimitive**)tools_gl2 2506 if(prim->boundary) tools_gl2psAddBoundary 2507 } 2508 tools_gl2psBuildPolygonBoundary(tree->front 2509 } 2510 2511 /******************************************** 2512 * 2513 * Feedback buffer parser 2514 * 2515 ******************************************** 2516 2517 TOOLS_GL2PSDLL_API void tools_gl2psAddPolyPri 2518 tools 2519 tools 2520 tools 2521 tools 2522 tools 2523 { 2524 tools_GL2PSprimitive *prim; 2525 2526 prim = (tools_GL2PSprimitive*)tools_gl2psMa 2527 prim->type = type; 2528 prim->numverts = numverts; 2529 prim->verts = (tools_GL2PSvertex*)tools_gl2 2530 memcpy(prim->verts, verts, numverts * sizeo 2531 prim->boundary = boundary; 2532 prim->offset = (char)offset; 2533 prim->ofactor = ofactor; 2534 prim->ounits = ounits; 2535 prim->pattern = pattern; 2536 prim->factor = factor; 2537 prim->width = width; 2538 prim->linecap = linecap; 2539 prim->linejoin = linejoin; 2540 prim->culled = 0; 2541 2542 /* FIXME: here we should have an option to 2543 tris/quads to enhance SIMPLE_SORT */ 2544 2545 tools_gl2psListAdd(gl2ps->primitives, &prim 2546 } 2547 2548 inline tools_GLint tools_gl2psGetVertex(tools 2549 { 2550 tools_GLint i; 2551 2552 v->xyz[0] = p[0]; 2553 v->xyz[1] = p[1]; 2554 v->xyz[2] = p[2]; 2555 2556 if(gl2ps->colormode == TOOLS_GL_COLOR_INDEX 2557 i = (tools_GLint)(p[3] + 0.5); 2558 v->rgba[0] = gl2ps->colormap[i][0]; 2559 v->rgba[1] = gl2ps->colormap[i][1]; 2560 v->rgba[2] = gl2ps->colormap[i][2]; 2561 v->rgba[3] = gl2ps->colormap[i][3]; 2562 return 4; 2563 } 2564 else{ 2565 v->rgba[0] = p[3]; 2566 v->rgba[1] = p[4]; 2567 v->rgba[2] = p[5]; 2568 v->rgba[3] = p[6]; 2569 return 7; 2570 } 2571 } 2572 2573 inline void tools_gl2psParseFeedbackBuffer(to 2574 { 2575 char flag; 2576 tools_GLushort pattern = 0; 2577 tools_GLboolean boundary; 2578 tools_GLint i, sizeoffloat, count, v, vtot, 2579 tools_GLint lcap = 0, ljoin = 0; 2580 tools_GLfloat lwidth = 1.0F, psize = 1.0F, 2581 tools_GLfloat *current; 2582 tools_GL2PSvertex vertices[3]; 2583 tools_GL2PSprimitive *prim; 2584 tools_GL2PSimagemap *node; 2585 2586 current = gl2ps->feedback; 2587 boundary = gl2ps->boundary = TOOLS_GL_FALSE 2588 2589 while(used > 0){ 2590 2591 if(TOOLS_GL_TRUE == boundary) gl2ps->boun 2592 2593 switch((tools_GLint)*current){ 2594 case TOOLS_GL_POINT_TOKEN : 2595 current ++; 2596 used --; 2597 i = tools_gl2psGetVertex(gl2ps, &vertic 2598 current += i; 2599 used -= i; 2600 tools_gl2psAddPolyPrimitive(gl2ps, TOOL 2601 pattern, factor, 2602 break; 2603 case TOOLS_GL_LINE_TOKEN : 2604 case TOOLS_GL_LINE_RESET_TOKEN : 2605 current ++; 2606 used --; 2607 i = tools_gl2psGetVertex(gl2ps, &vertic 2608 current += i; 2609 used -= i; 2610 i = tools_gl2psGetVertex(gl2ps, &vertic 2611 current += i; 2612 used -= i; 2613 tools_gl2psAddPolyPrimitive(gl2ps, TOOL 2614 pattern, factor, 2615 break; 2616 case TOOLS_GL_POLYGON_TOKEN : 2617 count = (tools_GLint)current[1]; 2618 current += 2; 2619 used -= 2; 2620 v = vtot = 0; 2621 while(count > 0 && used > 0){ 2622 i = tools_gl2psGetVertex(gl2ps, &vert 2623 tools_gl2psAdaptVertexForBlending(gl2 2624 current += i; 2625 used -= i; 2626 count --; 2627 vtot++; 2628 if(v == 2){ 2629 if(TOOLS_GL_TRUE == boundary){ 2630 if(!count && vtot == 2) flag = 1| 2631 else if(!count) flag = 2|4; 2632 else if(vtot == 2) flag = 1|2; 2633 else flag = 2; 2634 } 2635 else 2636 flag = 0; 2637 tools_gl2psAddPolyPrimitive(gl2ps, 2638 ounits, patte 2639 flag); 2640 vertices[1] = vertices[2]; 2641 } 2642 else 2643 v ++; 2644 } 2645 break; 2646 case TOOLS_GL_BITMAP_TOKEN : 2647 case TOOLS_GL_DRAW_PIXEL_TOKEN : 2648 case TOOLS_GL_COPY_PIXEL_TOKEN : 2649 current ++; 2650 used --; 2651 i = tools_gl2psGetVertex(gl2ps, &vertic 2652 current += i; 2653 used -= i; 2654 break; 2655 case TOOLS_GL_PASS_THROUGH_TOKEN : 2656 switch((tools_GLint)current[1]){ 2657 case TOOLS_GL2PS_BEGIN_OFFSET_TOKEN : 2658 offset = 1; 2659 current += 2; 2660 used -= 2; 2661 ofactor = current[1]; 2662 current += 2; 2663 used -= 2; 2664 ounits = current[1]; 2665 break; 2666 case TOOLS_GL2PS_END_OFFSET_TOKEN : 2667 offset = 0; 2668 ofactor = 0.0; 2669 ounits = 0.0; 2670 break; 2671 case TOOLS_GL2PS_BEGIN_BOUNDARY_TOKEN : 2672 case TOOLS_GL2PS_END_BOUNDARY_TOKEN : b 2673 case TOOLS_GL2PS_END_STIPPLE_TOKEN : pa 2674 case TOOLS_GL2PS_BEGIN_BLEND_TOKEN : gl 2675 case TOOLS_GL2PS_END_BLEND_TOKEN : gl2p 2676 case TOOLS_GL2PS_BEGIN_STIPPLE_TOKEN : 2677 current += 2; 2678 used -= 2; 2679 pattern = (tools_GLushort)current[1]; 2680 current += 2; 2681 used -= 2; 2682 factor = (tools_GLint)current[1]; 2683 break; 2684 case TOOLS_GL2PS_SRC_BLEND_TOKEN : 2685 current += 2; 2686 used -= 2; 2687 gl2ps->blendfunc[0] = (tools_GLint)cu 2688 break; 2689 case TOOLS_GL2PS_DST_BLEND_TOKEN : 2690 current += 2; 2691 used -= 2; 2692 gl2ps->blendfunc[1] = (tools_GLint)cu 2693 break; 2694 case TOOLS_GL2PS_POINT_SIZE_TOKEN : 2695 current += 2; 2696 used -= 2; 2697 psize = current[1]; 2698 break; 2699 case TOOLS_GL2PS_LINE_CAP_TOKEN : 2700 current += 2; 2701 used -= 2; 2702 lcap = (tools_GLint)current[1]; 2703 break; 2704 case TOOLS_GL2PS_LINE_JOIN_TOKEN : 2705 current += 2; 2706 used -= 2; 2707 ljoin = (tools_GLint)current[1]; 2708 break; 2709 case TOOLS_GL2PS_LINE_WIDTH_TOKEN : 2710 current += 2; 2711 used -= 2; 2712 lwidth = current[1]; 2713 break; 2714 case TOOLS_GL2PS_IMAGEMAP_TOKEN : 2715 prim = (tools_GL2PSprimitive *)tools_ 2716 prim->type = TOOLS_GL2PS_IMAGEMAP; 2717 prim->boundary = 0; 2718 prim->numverts = 4; 2719 prim->verts = (tools_GL2PSvertex *)to 2720 prim->culled = 0; 2721 prim->offset = 0; 2722 prim->ofactor = 0.0; 2723 prim->ounits = 0.0; 2724 prim->pattern = 0; 2725 prim->factor = 0; 2726 prim->width = 1; 2727 2728 node = (tools_GL2PSimagemap*)tools_gl 2729 node->image = (tools_GL2PSimage*)tool 2730 node->image->type = 0; 2731 node->image->format = 0; 2732 node->image->zoom_x = 1.0F; 2733 node->image->zoom_y = 1.0F; 2734 node->next = NULL; 2735 2736 if(gl2ps->imagemap_head == NULL) 2737 gl2ps->imagemap_head = node; 2738 else 2739 gl2ps->imagemap_tail->next = node; 2740 gl2ps->imagemap_tail = node; 2741 prim->data.image = node->image; 2742 2743 current += 2; used -= 2; 2744 i = tools_gl2psGetVertex(gl2ps, &prim 2745 current += i; used -= i; 2746 2747 node->image->width = (tools_GLint)cur 2748 current += 2; used -= 2; 2749 node->image->height = (tools_GLint)cu 2750 prim->verts[0].xyz[0] = prim->verts[0 2751 prim->verts[0].xyz[1] = prim->verts[0 2752 for(i = 1; i < 4; i++){ 2753 for(v = 0; v < 3; v++){ 2754 prim->verts[i].xyz[v] = prim->ver 2755 prim->verts[i].rgba[v] = prim->ve 2756 } 2757 prim->verts[i].rgba[v] = prim->vert 2758 } 2759 prim->verts[1].xyz[0] = prim->verts[1 2760 prim->verts[2].xyz[0] = prim->verts[1 2761 prim->verts[2].xyz[1] = prim->verts[2 2762 prim->verts[3].xyz[1] = prim->verts[2 2763 2764 sizeoffloat = sizeof(tools_GLfloat); 2765 v = 2 * sizeoffloat; 2766 vtot = node->image->height + node->im 2767 ((node->image->width - 1) / 8); 2768 node->image->pixels = (tools_GLfloat* 2769 node->image->pixels[0] = prim->verts[ 2770 node->image->pixels[1] = prim->verts[ 2771 2772 for(i = 0; i < vtot; i += sizeoffloat 2773 current += 2; used -= 2; 2774 if((vtot - i) >= 4) 2775 memcpy(&(((char*)(node->image->pi 2776 else 2777 memcpy(&(((char*)(node->image->pi 2778 } 2779 current++; used--; 2780 tools_gl2psListAdd(gl2ps->primitives, 2781 break; 2782 case TOOLS_GL2PS_DRAW_PIXELS_TOKEN : 2783 case TOOLS_GL2PS_TEXT_TOKEN : 2784 if(auxindex < tools_gl2psListNbr(gl2p 2785 tools_gl2psListAdd(gl2ps->primitive 2786 tools_gl2psListPointer 2787 else 2788 tools_gl2psMsg(TOOLS_GL2PS_ERROR, " 2789 break; 2790 } 2791 current += 2; 2792 used -= 2; 2793 break; 2794 default : 2795 tools_gl2psMsg(TOOLS_GL2PS_WARNING, "Un 2796 current ++; 2797 used --; 2798 break; 2799 } 2800 } 2801 2802 tools_gl2psListReset(gl2ps->auxprimitives); 2803 } 2804 2805 /******************************************** 2806 * 2807 * PostScript routines 2808 * 2809 ******************************************** 2810 2811 inline void tools_gl2psWriteByte(tools_GL2PSc 2812 { 2813 unsigned char h = byte / 16; 2814 unsigned char l = byte % 16; 2815 tools_gl2psPrintf(gl2ps,"%x%x", h, l); 2816 } 2817 2818 inline void tools_gl2psPrintPostScriptPixmap( 2819 { 2820 tools_GLuint nbhex, nbyte, nrgb, nbits; 2821 tools_GLuint row, col, ibyte, icase; 2822 tools_GLfloat dr = 0., dg = 0., db = 0., fg 2823 unsigned char red = 0, green = 0, blue = 0, 2824 tools_GLuint width = (tools_GLuint)im->widt 2825 tools_GLuint height = (tools_GLuint)im->hei 2826 2827 /* FIXME: should we define an option for th 2828 8-bit per component case? */ 2829 /*G.Barrand: have the two below lines in argu 2830 int greyscale = 0; // set to 1 to output gr 2831 int nbit = 8; // number of bits per color c 2832 */ 2833 2834 if((width <= 0) || (height <= 0)) return; 2835 2836 tools_gl2psPrintf(gl2ps,"gsave\n"); 2837 tools_gl2psPrintf(gl2ps,"%.2f %.2f translat 2838 tools_gl2psPrintf(gl2ps,"%.2f %.2f scale\n" 2839 2840 if(greyscale){ /* greyscale */ 2841 tools_gl2psPrintf(gl2ps,"/picstr %d strin 2842 tools_gl2psPrintf(gl2ps,"%d %d %d\n", wid 2843 tools_gl2psPrintf(gl2ps,"[ %d 0 0 -%d 0 % 2844 tools_gl2psPrintf(gl2ps,"{ currentfile pi 2845 tools_gl2psPrintf(gl2ps,"image\n"); 2846 for(row = 0; row < height; row++){ 2847 for(col = 0; col < width; col++){ 2848 tools_gl2psGetRGB(im, col, row, &dr, 2849 fgrey = (0.30F * dr + 0.59F * dg + 0. 2850 grey = (unsigned char)(255. * fgrey); 2851 tools_gl2psWriteByte(gl2ps, grey); 2852 } 2853 tools_gl2psPrintf(gl2ps,"\n"); 2854 } 2855 nbhex = width * height * 2; 2856 tools_gl2psPrintf(gl2ps,"%%%% nbhex digit 2857 } 2858 else if(nbit == 2){ /* color, 2 bits for r 2859 nrgb = width * 3; 2860 nbits = nrgb * nbit; 2861 nbyte = nbits / 8; 2862 if((nbyte * 8) != nbits) nbyte++; 2863 tools_gl2psPrintf(gl2ps,"/rgbstr %d strin 2864 tools_gl2psPrintf(gl2ps,"%d %d %d\n", wid 2865 tools_gl2psPrintf(gl2ps,"[ %d 0 0 -%d 0 % 2866 tools_gl2psPrintf(gl2ps,"{ currentfile rg 2867 tools_gl2psPrintf(gl2ps,"false 3\n"); 2868 tools_gl2psPrintf(gl2ps,"colorimage\n"); 2869 for(row = 0; row < height; row++){ 2870 icase = 1; 2871 col = 0; 2872 b = 0; 2873 for(ibyte = 0; ibyte < nbyte; ibyte++){ 2874 if(icase == 1) { 2875 if(col < width) { 2876 tools_gl2psGetRGB(im, col, row, & 2877 } 2878 else { 2879 dr = dg = db = 0; 2880 } 2881 col++; 2882 red = (unsigned char)(3. * dr); 2883 green = (unsigned char)(3. * dg); 2884 blue = (unsigned char)(3. * db); 2885 b = red; 2886 b = (b<<2) + green; 2887 b = (b<<2) + blue; 2888 if(col < width) { 2889 tools_gl2psGetRGB(im, col, row, & 2890 } 2891 else { 2892 dr = dg = db = 0; 2893 } 2894 col++; 2895 red = (unsigned char)(3. * dr); 2896 green = (unsigned char)(3. * dg); 2897 blue = (unsigned char)(3. * db); 2898 b = (b<<2) + red; 2899 tools_gl2psWriteByte(gl2ps, b); 2900 b = 0; 2901 icase++; 2902 } 2903 else if(icase == 2) { 2904 b = green; 2905 b = (b<<2) + blue; 2906 if(col < width) { 2907 tools_gl2psGetRGB(im, col, row, & 2908 } 2909 else { 2910 dr = dg = db = 0; 2911 } 2912 col++; 2913 red = (unsigned char)(3. * dr); 2914 green = (unsigned char)(3. * dg); 2915 blue = (unsigned char)(3. * db); 2916 b = (b<<2) + red; 2917 b = (b<<2) + green; 2918 tools_gl2psWriteByte(gl2ps, b); 2919 b = 0; 2920 icase++; 2921 } 2922 else if(icase == 3) { 2923 b = blue; 2924 if(col < width) { 2925 tools_gl2psGetRGB(im, col, row, & 2926 } 2927 else { 2928 dr = dg = db = 0; 2929 } 2930 col++; 2931 red = (unsigned char)(3. * dr); 2932 green = (unsigned char)(3. * dg); 2933 blue = (unsigned char)(3. * db); 2934 b = (b<<2) + red; 2935 b = (b<<2) + green; 2936 b = (b<<2) + blue; 2937 tools_gl2psWriteByte(gl2ps, b); 2938 b = 0; 2939 icase = 1; 2940 } 2941 } 2942 tools_gl2psPrintf(gl2ps,"\n"); 2943 } 2944 } 2945 else if(nbit == 4){ /* color, 4 bits for r 2946 nrgb = width * 3; 2947 nbits = nrgb * nbit; 2948 nbyte = nbits / 8; 2949 if((nbyte * 8) != nbits) nbyte++; 2950 tools_gl2psPrintf(gl2ps,"/rgbstr %d strin 2951 tools_gl2psPrintf(gl2ps,"%d %d %d\n", wid 2952 tools_gl2psPrintf(gl2ps,"[ %d 0 0 -%d 0 % 2953 tools_gl2psPrintf(gl2ps,"{ currentfile rg 2954 tools_gl2psPrintf(gl2ps,"false 3\n"); 2955 tools_gl2psPrintf(gl2ps,"colorimage\n"); 2956 for(row = 0; row < height; row++){ 2957 col = 0; 2958 icase = 1; 2959 for(ibyte = 0; ibyte < nbyte; ibyte++){ 2960 if(icase == 1) { 2961 if(col < width) { 2962 tools_gl2psGetRGB(im, col, row, & 2963 } 2964 else { 2965 dr = dg = db = 0; 2966 } 2967 col++; 2968 red = (unsigned char)(15. * dr); 2969 green = (unsigned char)(15. * dg); 2970 tools_gl2psPrintf(gl2ps,"%x%x", red 2971 icase++; 2972 } 2973 else if(icase == 2) { 2974 blue = (unsigned char)(15. * db); 2975 if(col < width) { 2976 tools_gl2psGetRGB(im, col, row, & 2977 } 2978 else { 2979 dr = dg = db = 0; 2980 } 2981 col++; 2982 red = (unsigned char)(15. * dr); 2983 tools_gl2psPrintf(gl2ps,"%x%x", blu 2984 icase++; 2985 } 2986 else if(icase == 3) { 2987 green = (unsigned char)(15. * dg); 2988 blue = (unsigned char)(15. * db); 2989 tools_gl2psPrintf(gl2ps,"%x%x", gre 2990 icase = 1; 2991 } 2992 } 2993 tools_gl2psPrintf(gl2ps,"\n"); 2994 } 2995 } 2996 else{ /* 8 bit for r and g and b */ 2997 nbyte = width * 3; 2998 tools_gl2psPrintf(gl2ps,"/rgbstr %d strin 2999 tools_gl2psPrintf(gl2ps,"%d %d %d\n", wid 3000 tools_gl2psPrintf(gl2ps,"[ %d 0 0 -%d 0 % 3001 tools_gl2psPrintf(gl2ps,"{ currentfile rg 3002 tools_gl2psPrintf(gl2ps,"false 3\n"); 3003 tools_gl2psPrintf(gl2ps,"colorimage\n"); 3004 for(row = 0; row < height; row++){ 3005 for(col = 0; col < width; col++){ 3006 tools_gl2psGetRGB(im, col, row, &dr, 3007 red = (unsigned char)(255. * dr); 3008 tools_gl2psWriteByte(gl2ps, red); 3009 green = (unsigned char)(255. * dg); 3010 tools_gl2psWriteByte(gl2ps, green); 3011 blue = (unsigned char)(255. * db); 3012 tools_gl2psWriteByte(gl2ps, blue); 3013 } 3014 tools_gl2psPrintf(gl2ps,"\n"); 3015 } 3016 } 3017 3018 tools_gl2psPrintf(gl2ps,"grestore\n"); 3019 } 3020 3021 inline void tools_gl2psPrintPostScriptImagema 3022 tool 3023 cons 3024 int i, size; 3025 3026 if((width <= 0) || (height <= 0)) return; 3027 3028 size = height + height * (width - 1) / 8; 3029 3030 tools_gl2psPrintf(gl2ps,"gsave\n"); 3031 tools_gl2psPrintf(gl2ps,"%.2f %.2f translat 3032 tools_gl2psPrintf(gl2ps,"%d %d scale\n%d %d 3033 tools_gl2psPrintf(gl2ps,"[ %d 0 0 -%d 0 %d 3034 for(i = 0; i < size; i++){ 3035 tools_gl2psWriteByte(gl2ps, *imagemap); 3036 imagemap++; 3037 } 3038 tools_gl2psPrintf(gl2ps,">} imagemask\ngres 3039 } 3040 3041 inline void tools_gl2psPrintPostScriptHeader( 3042 { 3043 time_t now; 3044 3045 /* Since compression is not part of the Pos 3046 compressed PostScript files are just gzi 3047 ("ps.gz" or "eps.gz") */ 3048 tools_gl2psPrintGzipHeader(gl2ps); 3049 3050 time(&now); 3051 3052 if(gl2ps->format == TOOLS_GL2PS_PS){ 3053 tools_gl2psPrintf(gl2ps,"%%!PS-Adobe-3.0\ 3054 } 3055 else{ 3056 tools_gl2psPrintf(gl2ps,"%%!PS-Adobe-3.0 3057 } 3058 3059 tools_gl2psPrintf(gl2ps,"%%%%Title: %s\n" 3060 "%%%%Creator: GL2PS %d.%d.%d%s, 3061 "%%%%For: %s\n" 3062 "%%%%CreationDate: %s" 3063 "%%%%LanguageLevel: 3\n" 3064 "%%%%DocumentData: Clean7Bit\n" 3065 "%%%%Pages: 1\n", 3066 gl2ps->title, TOOLS_GL2PS_MAJOR 3067 TOOLS_GL2PS_PATCH_VERSION, TOOL 3068 gl2ps->producer, ctime(&now)); 3069 3070 if(gl2ps->format == TOOLS_GL2PS_PS){ 3071 tools_gl2psPrintf(gl2ps,"%%%%Orientation: 3072 "%%%%DocumentMedia: Default % 3073 (gl2ps->options & TOOLS_GL2PS 3074 (gl2ps->options & TOOLS_GL2PS 3075 (int)gl2ps->viewport[2], 3076 (gl2ps->options & TOOLS_GL2PS 3077 (int)gl2ps->viewport[3]); 3078 } 3079 3080 tools_gl2psPrintf(gl2ps,"%%%%BoundingBox: % 3081 "%%%%EndComments\n", 3082 (gl2ps->options & TOOLS_GL2PS_L 3083 (int)gl2ps->viewport[0], 3084 (gl2ps->options & TOOLS_GL2PS_L 3085 (int)gl2ps->viewport[1], 3086 (gl2ps->options & TOOLS_GL2PS_L 3087 (int)gl2ps->viewport[2], 3088 (gl2ps->options & TOOLS_GL2PS_L 3089 (int)gl2ps->viewport[3]); 3090 3091 /* RGB color: r g b C (replace C by G in ou 3092 Grayscale: r g b G 3093 Font choose: size fontname FC 3094 Text string: (string) x y size fontname 3095 Rotated text string: (string) angle x y 3096 Point primitive: x y size P 3097 Line width: width W 3098 Line start: x y LS 3099 Line joining last point: x y L 3100 Line end: x y LE 3101 Flat-shaded triangle: x3 y3 x2 y2 x1 y1 3102 Smooth-shaded triangle: x3 y3 r3 g3 b3 x 3103 3104 tools_gl2psPrintf(gl2ps,"%%%%BeginProlog\n" 3105 "/gl2psdict 64 dict def gl2psdi 3106 "/tryPS3shading %s def %% set t 3107 "/rThreshold %g def %% red comp 3108 "/gThreshold %g def %% green co 3109 "/bThreshold %g def %% blue com 3110 (gl2ps->options & TOOLS_GL2PS_N 3111 gl2ps->threshold[0], gl2ps->thr 3112 3113 tools_gl2psPrintf(gl2ps,"/BD { bind def } b 3114 "/C { setrgbcolor } BD\n" 3115 "/G { 0.082 mul exch 0.6094 mu 3116 "/W { setlinewidth } BD\n" 3117 "/LC { setlinecap } BD\n" 3118 "/LJ { setlinejoin } BD\n"); 3119 3120 tools_gl2psPrintf(gl2ps,"/FC { findfont exc 3121 "/SW { dup stringwidth pop } BD 3122 "/S { FC moveto show } BD\n" 3123 "/SBC{ FC moveto SW -2 div 0 rm 3124 "/SBR{ FC moveto SW neg 0 rmove 3125 "/SCL{ FC moveto 0 SH -2 div rm 3126 "/SCC{ FC moveto SW -2 div SH - 3127 "/SCR{ FC moveto SW neg SH -2 d 3128 "/STL{ FC moveto 0 SH neg rmove 3129 "/STC{ FC moveto SW -2 div SH n 3130 "/STR{ FC moveto SW neg SH neg 3131 3132 /* rotated text routines: same nameanem wit 3133 3134 tools_gl2psPrintf(gl2ps,"/FCT { FC translat 3135 "/SR { gsave FCT moveto rotate 3136 "/SBCR{ gsave FCT moveto rotate 3137 "/SBRR{ gsave FCT moveto rotate 3138 "/SCLR{ gsave FCT moveto rotate 3139 tools_gl2psPrintf(gl2ps,"/SCCR{ gsave FCT m 3140 "/SCRR{ gsave FCT moveto rotate 3141 "/STLR{ gsave FCT moveto rotate 3142 "/STCR{ gsave FCT moveto rotate 3143 "/STRR{ gsave FCT moveto rotate 3144 3145 tools_gl2psPrintf(gl2ps,"/P { newpath 0.0 3146 "/LS { newpath moveto } BD\n" 3147 "/L { lineto } BD\n" 3148 "/LE { lineto stroke } BD\n" 3149 "/T { newpath moveto lineto li 3150 3151 /* Smooth-shaded triangle with PostScript l 3152 x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r 3153 3154 tools_gl2psPrintf(gl2ps,"/STshfill {\n" 3155 " /b1 exch def /g1 exch de 3156 " /b2 exch def /g2 exch de 3157 " /b3 exch def /g3 exch de 3158 " gsave << /ShadingType 4 3159 " /DataSource [ 0 x1 y1 r1 3160 " shfill grestore } BD\n") 3161 3162 /* Flat-shaded triangle with middle color: 3163 x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r 3164 3165 tools_gl2psPrintf(gl2ps,/* stack : x3 y3 r3 3166 "/Tm { 3 -1 roll 8 -1 roll 13 - 3167 /* stack : x3 y3 g3 b3 x2 y2 g2 3168 " 3 -1 roll 7 -1 roll 11 - 3169 /* stack : x3 y3 b3 x2 y2 b2 x1 3170 " 3 -1 roll 6 -1 roll 9 -1 3171 /* stack : x3 y3 x2 y2 x1 y1 r 3172 " C T } BD\n"); 3173 3174 /* Split triangle in four sub-triangles (at 3175 STnoshfill procedure on each, interpolat 3176 x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r 3177 (in procedure comments key: (Vi) = xi yi 3178 3179 tools_gl2psPrintf(gl2ps,"/STsplit {\n" 3180 " 4 index 15 index add 0.5 3181 " 4 index 15 index add 0.5 3182 " 4 index 15 index add 0.5 3183 " 4 index 15 index add 0.5 3184 " 4 index 15 index add 0.5 3185 " 5 copy 5 copy 25 15 roll 3186 3187 /* at his point, stack = (V3) (V13) (V13) ( 3188 3189 tools_gl2psPrintf(gl2ps," 9 index 30 i 3190 " 9 index 30 index add 0.5 3191 " 9 index 30 index add 0.5 3192 " 9 index 30 index add 0.5 3193 " 9 index 30 index add 0.5 3194 " 5 copy 5 copy 35 5 roll 3195 3196 /* stack = (V3) (V13) (V23) (V13) (V23) (V1 3197 3198 tools_gl2psPrintf(gl2ps," 4 index 10 i 3199 " 4 index 10 index add 0.5 3200 " 4 index 10 index add 0.5 3201 " 4 index 10 index add 0.5 3202 " 4 index 10 index add 0.5 3203 " 5 copy 5 copy 40 5 roll 3204 3205 /* stack = (V3) (V13) (V23) (V13) (V12) (V2 3206 3207 tools_gl2psPrintf(gl2ps," STnoshfill S 3208 3209 /* Gouraud shaded triangle using recursive 3210 between corner colors does not exceed th 3211 x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r 3212 3213 tools_gl2psPrintf(gl2ps,"/STnoshfill {\n" 3214 " 2 index 8 index sub abs 3215 " { STsplit }\n" 3216 " { 1 index 7 index sub ab 3217 " { STsplit }\n" 3218 " { dup 6 index sub abs 3219 " { STsplit }\n" 3220 " { 2 index 13 index s 3221 " { STsplit }\n" 3222 " { 1 index 12 index 3223 " { STsplit }\n" 3224 " { dup 11 index s 3225 " { STsplit }\n" 3226 " { 7 index 13 i 3227 tools_gl2psPrintf(gl2ps," 3228 " { 6 index 12 3229 " { STsplit 3230 " { 5 index 3231 " { STspli 3232 " { Tm }\n 3233 " ifelse } 3234 " ifelse }\n 3235 " ifelse }\n" 3236 " ifelse }\n" 3237 " ifelse }\n" 3238 " ifelse }\n" 3239 " ifelse }\n" 3240 " ifelse }\n" 3241 " ifelse } BD\n"); 3242 3243 tools_gl2psPrintf(gl2ps,"tryPS3shading\n" 3244 "{ /shfill where\n" 3245 " { /ST { STshfill } BD }\n" 3246 " { /ST { STnoshfill } BD }\n" 3247 " ifelse }\n" 3248 "{ /ST { STnoshfill } BD }\n" 3249 "ifelse\n"); 3250 3251 tools_gl2psPrintf(gl2ps,"end\n" 3252 "%%%%EndProlog\n" 3253 "%%%%BeginSetup\n" 3254 "/DeviceRGB setcolorspace\n" 3255 "gl2psdict begin\n" 3256 "%%%%EndSetup\n" 3257 "%%%%Page: 1 1\n" 3258 "%%%%BeginPageSetup\n"); 3259 3260 if(gl2ps->options & TOOLS_GL2PS_LANDSCAPE){ 3261 tools_gl2psPrintf(gl2ps,"%d 0 translate 9 3262 (int)gl2ps->viewport[3]); 3263 } 3264 3265 tools_gl2psPrintf(gl2ps,"%%%%EndPageSetup\n 3266 "mark\n" 3267 "gsave\n" 3268 "1.0 1.0 scale\n"); 3269 3270 if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR 3271 tools_gl2psPrintf(gl2ps,"%g %g %g C\n" 3272 "newpath %d %d moveto %d %d l 3273 "closepath fill\n", 3274 gl2ps->bgcolor[0], gl2ps->bgc 3275 (int)gl2ps->viewport[0], (int 3276 (int)gl2ps->viewport[1], (int 3277 (int)gl2ps->viewport[0], (int 3278 } 3279 } 3280 3281 inline void tools_gl2psPrintPostScriptColor(t 3282 { 3283 if(!tools_gl2psSameColor(gl2ps->lastrgba, r 3284 tools_gl2psSetLastColor(gl2ps, rgba); 3285 tools_gl2psPrintf(gl2ps,"%g %g %g C\n", r 3286 } 3287 } 3288 3289 inline void tools_gl2psResetPostScriptColor(t 3290 { 3291 gl2ps->lastrgba[0] = gl2ps->lastrgba[1] = g 3292 } 3293 3294 inline void tools_gl2psEndPostScriptLine(tool 3295 { 3296 int i; 3297 if(gl2ps->lastvertex.rgba[0] >= 0.){ 3298 tools_gl2psPrintf(gl2ps,"%g %g LE\n", gl2 3299 for(i = 0; i < 3; i++) 3300 gl2ps->lastvertex.xyz[i] = -1.; 3301 for(i = 0; i < 4; i++) 3302 gl2ps->lastvertex.rgba[i] = -1.; 3303 } 3304 } 3305 3306 inline void tools_gl2psParseStipplePattern(to 3307 int *nb, 3308 { 3309 int i, n; 3310 int on[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 3311 int off[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 3312 char tmp[16]; 3313 3314 /* extract the 16 bits from the OpenGL stip 3315 for(n = 15; n >= 0; n--){ 3316 tmp[n] = (char)(pattern & 0x01); 3317 pattern >>= 1; 3318 } 3319 /* compute the on/off pixel sequence */ 3320 n = 0; 3321 for(i = 0; i < 8; i++){ 3322 while(n < 16 && !tmp[n]){ off[i]++; n++; 3323 while(n < 16 && tmp[n]){ on[i]++; n++; } 3324 if(n >= 15){ i++; break; } 3325 } 3326 3327 /* store the on/off array from right to lef 3328 pixels. The PostScript specification all 3329 elements in the on/off array, so we limi 3330 couples (our longest possible array is t 3331 on2 off2 on1 off1 on0 off0]) */ 3332 *nb = 0; 3333 for(n = i - 1; n >= 0; n--){ 3334 array[(*nb)++] = factor * on[n]; 3335 array[(*nb)++] = factor * off[n]; 3336 if(*nb == 10) break; 3337 } 3338 } 3339 3340 inline int tools_gl2psPrintPostScriptDash(too 3341 { 3342 int len = 0, i, n, array[10]; 3343 3344 if(pattern == gl2ps->lastpattern && factor 3345 return 0; 3346 3347 gl2ps->lastpattern = pattern; 3348 gl2ps->lastfactor = factor; 3349 3350 if(!pattern || !factor){ 3351 /* solid line */ 3352 len += tools_gl2psPrintf(gl2ps,"[] 0 %s\n 3353 } 3354 else{ 3355 tools_gl2psParseStipplePattern(pattern, f 3356 len += tools_gl2psPrintf(gl2ps,"["); 3357 for(i = 0; i < n; i++){ 3358 if(i) len += tools_gl2psPrintf(gl2ps," 3359 len += tools_gl2psPrintf(gl2ps,"%d", ar 3360 } 3361 len += tools_gl2psPrintf(gl2ps,"] 0 %s\n" 3362 } 3363 3364 return len; 3365 } 3366 3367 inline void tools_gl2psPrintPostScriptPrimiti 3368 { 3369 int newline; 3370 tools_GL2PSprimitive *prim; 3371 3372 prim = *(tools_GL2PSprimitive**)data; 3373 3374 if((gl2ps->options & TOOLS_GL2PS_OCCLUSION_ 3375 3376 /* Every effort is made to draw lines as co 3377 using a single PostScript path): this is 3378 line joins and to not restart the stippl 3379 segment. So if the primitive to print is 3380 finish the current line (if any): */ 3381 if(prim->type != TOOLS_GL2PS_LINE) tools_gl 3382 3383 switch(prim->type){ 3384 case TOOLS_GL2PS_POINT : 3385 tools_gl2psPrintPostScriptColor(gl2ps, pr 3386 tools_gl2psPrintf(gl2ps,"%g %g %g P\n", 3387 prim->verts[0].xyz[0], prim-> 3388 break; 3389 case TOOLS_GL2PS_LINE : 3390 if(!tools_gl2psSamePosition(gl2ps->lastve 3391 !tools_gl2psSameColor(gl2ps->lastrgba, 3392 gl2ps->lastlinewidth != prim->width || 3393 gl2ps->lastlinecap != prim->linecap || 3394 gl2ps->lastlinejoin != prim->linejoin 3395 gl2ps->lastpattern != prim->pattern || 3396 gl2ps->lastfactor != prim->factor){ 3397 /* End the current line if the new segm 3398 the last one ended, or if the color, 3399 stippling have changed (multi-stroki 3400 colors is necessary until we use /sh 3401 unfortunately this means that at the 3402 line stippling for smooth-shaded lin 3403 tools_gl2psEndPostScriptLine(gl2ps); 3404 newline = 1; 3405 } 3406 else{ 3407 newline = 0; 3408 } 3409 if(gl2ps->lastlinewidth != prim->width){ 3410 gl2ps->lastlinewidth = prim->width; 3411 tools_gl2psPrintf(gl2ps,"%g W\n", gl2ps 3412 } 3413 if(gl2ps->lastlinecap != prim->linecap){ 3414 gl2ps->lastlinecap = prim->linecap; 3415 tools_gl2psPrintf(gl2ps,"%d LC\n", gl2p 3416 } 3417 if(gl2ps->lastlinejoin != prim->linejoin) 3418 gl2ps->lastlinejoin = prim->linejoin; 3419 tools_gl2psPrintf(gl2ps,"%d LJ\n", gl2p 3420 } 3421 tools_gl2psPrintPostScriptDash(gl2ps, pri 3422 tools_gl2psPrintPostScriptColor(gl2ps, pr 3423 tools_gl2psPrintf(gl2ps,"%g %g %s\n", pri 3424 newline ? "LS" : "L"); 3425 gl2ps->lastvertex = prim->verts[1]; 3426 break; 3427 case TOOLS_GL2PS_TRIANGLE : 3428 if(!tools_gl2psVertsSameColor(prim)){ 3429 tools_gl2psResetPostScriptColor(gl2ps); 3430 tools_gl2psPrintf(gl2ps,"%g %g %g %g %g 3431 prim->verts[2].xyz[0], prim 3432 prim->verts[2].rgba[0], pri 3433 prim->verts[2].rgba[2], pri 3434 prim->verts[1].xyz[1], prim 3435 prim->verts[1].rgba[1], pri 3436 prim->verts[0].xyz[0], prim 3437 prim->verts[0].rgba[0], pri 3438 prim->verts[0].rgba[2]); 3439 } 3440 else{ 3441 tools_gl2psPrintPostScriptColor(gl2ps, 3442 tools_gl2psPrintf(gl2ps,"%g %g %g %g %g 3443 prim->verts[2].xyz[0], prim 3444 prim->verts[1].xyz[0], prim 3445 prim->verts[0].xyz[0], prim 3446 } 3447 break; 3448 case TOOLS_GL2PS_QUADRANGLE : 3449 tools_gl2psMsg(TOOLS_GL2PS_WARNING, "Ther 3450 break; 3451 case TOOLS_GL2PS_PIXMAP : 3452 tools_gl2psPrintPostScriptPixmap(gl2ps, p 3453 prim->data.ima 3454 break; 3455 case TOOLS_GL2PS_IMAGEMAP : 3456 if(prim->data.image->type != TOOLS_GL2PS_ 3457 tools_gl2psPrintPostScriptColor(gl2ps, 3458 tools_gl2psPrintPostScriptImagemap(gl2p 3459 prim->data 3460 prim->data 3461 (const uns 3462 prim->data.image->type = TOOLS_GL2PS_IM 3463 } 3464 break; 3465 case TOOLS_GL2PS_TEXT : 3466 tools_gl2psPrintPostScriptColor(gl2ps, pr 3467 tools_gl2psPrintf(gl2ps,"(%s) ", prim->da 3468 if(prim->data.text->angle) 3469 tools_gl2psPrintf(gl2ps,"%g ", prim->da 3470 tools_gl2psPrintf(gl2ps,"%g %g %d /%s ", 3471 prim->verts[0].xyz[0], prim-> 3472 prim->data.text->fontsize, pr 3473 switch(prim->data.text->alignment){ 3474 case TOOLS_GL2PS_TEXT_C: 3475 tools_gl2psPrintf(gl2ps, prim->data.tex 3476 break; 3477 case TOOLS_GL2PS_TEXT_CL: 3478 tools_gl2psPrintf(gl2ps, prim->data.tex 3479 break; 3480 case TOOLS_GL2PS_TEXT_CR: 3481 tools_gl2psPrintf(gl2ps, prim->data.tex 3482 break; 3483 case TOOLS_GL2PS_TEXT_B: 3484 tools_gl2psPrintf(gl2ps, prim->data.tex 3485 break; 3486 case TOOLS_GL2PS_TEXT_BR: 3487 tools_gl2psPrintf(gl2ps, prim->data.tex 3488 break; 3489 case TOOLS_GL2PS_TEXT_T: 3490 tools_gl2psPrintf(gl2ps, prim->data.tex 3491 break; 3492 case TOOLS_GL2PS_TEXT_TL: 3493 tools_gl2psPrintf(gl2ps, prim->data.tex 3494 break; 3495 case TOOLS_GL2PS_TEXT_TR: 3496 tools_gl2psPrintf(gl2ps, prim->data.tex 3497 break; 3498 case TOOLS_GL2PS_TEXT_BL: 3499 default: 3500 tools_gl2psPrintf(gl2ps, prim->data.tex 3501 break; 3502 } 3503 break; 3504 case TOOLS_GL2PS_SPECIAL : 3505 /* alignment contains the format for whic 3506 is intended */ 3507 if(prim->data.text->alignment == TOOLS_GL 3508 prim->data.text->alignment == TOOLS_GL 3509 tools_gl2psPrintf(gl2ps,"%s\n", prim->d 3510 break; 3511 default : 3512 break; 3513 } 3514 } 3515 3516 inline void tools_gl2psPrintPostScriptFooter( 3517 { 3518 tools_gl2psPrintf(gl2ps,"grestore\n" 3519 "showpage\n" 3520 "cleartomark\n" 3521 "%%%%PageTrailer\n" 3522 "%%%%Trailer\n" 3523 "end\n" 3524 "%%%%EOF\n"); 3525 3526 tools_gl2psPrintGzipFooter(gl2ps); 3527 } 3528 3529 inline void tools_gl2psPrintPostScriptBeginVi 3530 { 3531 tools_GLint idx; 3532 tools_GLfloat rgba[4]; 3533 int x = viewport[0], y = viewport[1], w = v 3534 3535 tools_glRenderMode(TOOLS_GL_FEEDBACK); 3536 3537 if(gl2ps->header){ 3538 tools_gl2psPrintPostScriptHeader(gl2ps); 3539 gl2ps->header = TOOLS_GL_FALSE; 3540 } 3541 3542 tools_gl2psResetPostScriptColor(gl2ps); 3543 tools_gl2psResetLineProperties(gl2ps); 3544 3545 tools_gl2psPrintf(gl2ps,"gsave\n" 3546 "1.0 1.0 scale\n"); 3547 3548 if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR 3549 if(gl2ps->colormode == TOOLS_GL_RGBA || g 3550 tools_glGetFloatv(TOOLS_GL_COLOR_CLEAR_ 3551 } 3552 else{ 3553 tools_glGetIntegerv(TOOLS_GL_INDEX_CLEA 3554 rgba[0] = gl2ps->colormap[idx][0]; 3555 rgba[1] = gl2ps->colormap[idx][1]; 3556 rgba[2] = gl2ps->colormap[idx][2]; 3557 rgba[3] = 1.0F; 3558 } 3559 tools_gl2psPrintf(gl2ps,"%g %g %g C\n" 3560 "newpath %d %d moveto %d %d l 3561 "closepath fill\n", 3562 rgba[0], rgba[1], rgba[2], 3563 x, y, x+w, y, x+w, y+h, x, y+ 3564 } 3565 3566 tools_gl2psPrintf(gl2ps,"newpath %d %d move 3567 "closepath clip\n", 3568 x, y, x+w, y, x+w, y+h, x, y+h) 3569 3570 } 3571 3572 inline tools_GLint tools_gl2psPrintPostScript 3573 { 3574 tools_GLint res; 3575 3576 res = tools_gl2psPrintPrimitives(gl2ps); 3577 tools_gl2psPrintf(gl2ps,"grestore\n"); 3578 return res; 3579 } 3580 3581 inline void tools_gl2psPrintPostScriptFinalPr 3582 { 3583 /* End any remaining line, if any */ 3584 tools_gl2psEndPostScriptLine(gl2ps); 3585 } 3586 3587 /* definition of the PostScript and Encapsula 3588 3589 static const tools_GL2PSbackend tools_gl2psPS 3590 tools_gl2psPrintPostScriptHeader, 3591 tools_gl2psPrintPostScriptFooter, 3592 tools_gl2psPrintPostScriptBeginViewport, 3593 tools_gl2psPrintPostScriptEndViewport, 3594 tools_gl2psPrintPostScriptPrimitive, 3595 tools_gl2psPrintPostScriptFinalPrimitive, 3596 "ps", 3597 "Postscript" 3598 }; 3599 3600 static const tools_GL2PSbackend tools_gl2psEP 3601 tools_gl2psPrintPostScriptHeader, 3602 tools_gl2psPrintPostScriptFooter, 3603 tools_gl2psPrintPostScriptBeginViewport, 3604 tools_gl2psPrintPostScriptEndViewport, 3605 tools_gl2psPrintPostScriptPrimitive, 3606 tools_gl2psPrintPostScriptFinalPrimitive, 3607 "eps", 3608 "Encapsulated Postscript" 3609 }; 3610 3611 /******************************************** 3612 * 3613 * LaTeX routines 3614 * 3615 ******************************************** 3616 3617 inline void tools_gl2psPrintTeXHeader(tools_G 3618 { 3619 char name[256]; 3620 time_t now; 3621 int i; 3622 tools_GLfloat _s; 3623 3624 if(gl2ps->filename && strlen(gl2ps->filenam 3625 for(i = (int)strlen(gl2ps->filename) - 1; 3626 if(gl2ps->filename[i] == '.'){ 3627 strncpy(name, gl2ps->filename, i); 3628 name[i] = '\0'; 3629 break; 3630 } 3631 } 3632 if(i <= 0) strcpy(name, gl2ps->filename); 3633 } 3634 else{ 3635 strcpy(name, "untitled"); 3636 } 3637 3638 time(&now); 3639 3640 fprintf(gl2ps->stream, 3641 "%% Title: %s\n" 3642 "%% Creator: GL2PS %d.%d.%d%s, %s\n 3643 "%% For: %s\n" 3644 "%% CreationDate: %s", 3645 gl2ps->title, TOOLS_GL2PS_MAJOR_VER 3646 TOOLS_GL2PS_PATCH_VERSION, TOOLS_GL 3647 gl2ps->producer, ctime(&now)); 3648 3649 _s = gl2ps->tex_scaling; 3650 if(_s <= 0.) _s = 1.; 3651 fprintf(gl2ps->stream, 3652 "\\setlength{\\unitlength}{%gpt}\n" 3653 "\\begin{picture}(0,0)\n" 3654 "\\includegraphics[scale=%g]{%s}\n" 3655 "\\end{picture}%%\n" 3656 "%s\\begin{picture}(%d,%d)(0,0)\n", 3657 _s, _s, name, 3658 (gl2ps->options & TOOLS_GL2PS_LANDS 3659 (int)(gl2ps->viewport[2]), (int)(gl 3660 } 3661 3662 inline void tools_gl2psPrintTeXPrimitive(tool 3663 { 3664 tools_GL2PSprimitive *prim; 3665 3666 prim = *(tools_GL2PSprimitive**)data; 3667 3668 switch(prim->type){ 3669 case TOOLS_GL2PS_TEXT : 3670 if(!(gl2ps->options & TOOLS_GL2PS_NO_TEX_ 3671 fprintf(gl2ps->stream, "\\fontsize{%d}{ 3672 prim->data.text->fontsize); 3673 fprintf(gl2ps->stream, "\\put(%g,%g)", 3674 prim->verts[0].xyz[0], 3675 prim->verts[0].xyz[1]); 3676 if(prim->data.text->angle) 3677 fprintf(gl2ps->stream, "{\\rotatebox{%g 3678 fprintf(gl2ps->stream, "{\\makebox(0,0)") 3679 switch(prim->data.text->alignment){ 3680 case TOOLS_GL2PS_TEXT_C: 3681 fprintf(gl2ps->stream, "{"); 3682 break; 3683 case TOOLS_GL2PS_TEXT_CL: 3684 fprintf(gl2ps->stream, "[l]{"); 3685 break; 3686 case TOOLS_GL2PS_TEXT_CR: 3687 fprintf(gl2ps->stream, "[r]{"); 3688 break; 3689 case TOOLS_GL2PS_TEXT_B: 3690 fprintf(gl2ps->stream, "[b]{"); 3691 break; 3692 case TOOLS_GL2PS_TEXT_BR: 3693 fprintf(gl2ps->stream, "[br]{"); 3694 break; 3695 case TOOLS_GL2PS_TEXT_T: 3696 fprintf(gl2ps->stream, "[t]{"); 3697 break; 3698 case TOOLS_GL2PS_TEXT_TL: 3699 fprintf(gl2ps->stream, "[tl]{"); 3700 break; 3701 case TOOLS_GL2PS_TEXT_TR: 3702 fprintf(gl2ps->stream, "[tr]{"); 3703 break; 3704 case TOOLS_GL2PS_TEXT_BL: 3705 default: 3706 fprintf(gl2ps->stream, "[bl]{"); 3707 break; 3708 } 3709 fprintf(gl2ps->stream, "\\textcolor[rgb]{ 3710 prim->verts[0].rgba[0], prim->ver 3711 prim->data.text->str); 3712 if(prim->data.text->angle) 3713 fprintf(gl2ps->stream, "}"); 3714 fprintf(gl2ps->stream, "}}\n"); 3715 break; 3716 case TOOLS_GL2PS_SPECIAL : 3717 /* alignment contains the format for whic 3718 is intended */ 3719 if (prim->data.text->alignment == TOOLS_G 3720 fprintf(gl2ps->stream, "%s\n", prim->da 3721 break; 3722 default : 3723 break; 3724 } 3725 } 3726 3727 inline void tools_gl2psPrintTeXFooter(tools_G 3728 { 3729 fprintf(gl2ps->stream, "\\end{picture}%s\n" 3730 (gl2ps->options & TOOLS_GL2PS_LANDS 3731 } 3732 3733 inline void tools_gl2psPrintTeXBeginViewport( 3734 { 3735 (void) viewport; /* not used */ 3736 tools_glRenderMode(TOOLS_GL_FEEDBACK); 3737 3738 tools_gl2psResetLineProperties(gl2ps); 3739 3740 if(gl2ps->header){ 3741 tools_gl2psPrintTeXHeader(gl2ps); 3742 gl2ps->header = TOOLS_GL_FALSE; 3743 } 3744 } 3745 3746 inline tools_GLint tools_gl2psPrintTeXEndView 3747 { 3748 return tools_gl2psPrintPrimitives(gl2ps); 3749 } 3750 3751 inline void tools_gl2psPrintTeXFinalPrimitive 3752 { 3753 } 3754 3755 /* definition of the LaTeX backend */ 3756 3757 static const tools_GL2PSbackend tools_gl2psTE 3758 tools_gl2psPrintTeXHeader, 3759 tools_gl2psPrintTeXFooter, 3760 tools_gl2psPrintTeXBeginViewport, 3761 tools_gl2psPrintTeXEndViewport, 3762 tools_gl2psPrintTeXPrimitive, 3763 tools_gl2psPrintTeXFinalPrimitive, 3764 "tex", 3765 "LaTeX text" 3766 }; 3767 3768 /******************************************** 3769 * 3770 * PDF routines 3771 * 3772 ******************************************** 3773 3774 inline int tools_gl2psPrintPDFCompressorType( 3775 { 3776 #if defined(TOOLS_GL2PS_HAVE_ZLIB) 3777 if(gl2ps->options & TOOLS_GL2PS_COMPRESS){ 3778 return fprintf(gl2ps->stream, "/Filter [/ 3779 } 3780 #endif 3781 (void)gl2ps; 3782 return 0; 3783 } 3784 3785 inline int tools_gl2psPrintPDFStrokeColor(too 3786 { 3787 int i, offs = 0; 3788 3789 tools_gl2psSetLastColor(gl2ps, rgba); 3790 for(i = 0; i < 3; ++i){ 3791 if(TOOLS_GL2PS_ZERO(rgba[i])) 3792 offs += tools_gl2psPrintf(gl2ps,"%.0f " 3793 else if(rgba[i] < 1e-4 || rgba[i] > 1e6) 3794 offs += tools_gl2psPrintf(gl2ps,"%f ", 3795 else 3796 offs += tools_gl2psPrintf(gl2ps,"%g ", 3797 } 3798 offs += tools_gl2psPrintf(gl2ps,"RG\n"); 3799 return offs; 3800 } 3801 3802 inline int tools_gl2psPrintPDFFillColor(tools 3803 { 3804 int i, offs = 0; 3805 3806 for(i = 0; i < 3; ++i){ 3807 if(TOOLS_GL2PS_ZERO(rgba[i])) 3808 offs += tools_gl2psPrintf(gl2ps,"%.0f " 3809 else if(rgba[i] < 1e-4 || rgba[i] > 1e6) 3810 offs += tools_gl2psPrintf(gl2ps,"%f ", 3811 else 3812 offs += tools_gl2psPrintf(gl2ps,"%g ", 3813 } 3814 offs += tools_gl2psPrintf(gl2ps,"rg\n"); 3815 return offs; 3816 } 3817 3818 inline int tools_gl2psPrintPDFLineWidth(tools 3819 { 3820 if(TOOLS_GL2PS_ZERO(lw)) 3821 return tools_gl2psPrintf(gl2ps,"%.0f w\n" 3822 else if(lw < 1e-4 || lw > 1e6) /* avoid %e 3823 return tools_gl2psPrintf(gl2ps,"%f w\n", 3824 else 3825 return tools_gl2psPrintf(gl2ps,"%g w\n", 3826 } 3827 3828 inline int tools_gl2psPrintPDFLineCap(tools_G 3829 { 3830 if(gl2ps->lastlinecap == lc) 3831 return 0; 3832 else 3833 return tools_gl2psPrintf(gl2ps,"%d J\n", 3834 } 3835 3836 inline int tools_gl2psPrintPDFLineJoin(tools_ 3837 { 3838 if(gl2ps->lastlinejoin == lj) 3839 return 0; 3840 else 3841 return tools_gl2psPrintf(gl2ps,"%d j\n", 3842 } 3843 3844 inline void tools_gl2psPutPDFText(tools_GL2PS 3845 { 3846 tools_GLfloat _rad, crad, srad; 3847 3848 if(text->angle == 0.0F){ 3849 gl2ps->streamlength += tools_gl2psPrintf 3850 (gl2ps, "BT\n" 3851 "/F%d %d Tf\n" 3852 "%f %f Td\n" 3853 "(%s) Tj\n" 3854 "ET\n", 3855 cnt, text->fontsize, x, y, text->str); 3856 } 3857 else{ 3858 _rad = (tools_GLfloat)(3.141593F * text-> 3859 srad = (tools_GLfloat)sin(_rad); 3860 crad = (tools_GLfloat)cos(_rad); 3861 gl2ps->streamlength += tools_gl2psPrintf 3862 (gl2ps, "BT\n" 3863 "/F%d %d Tf\n" 3864 "%f %f %f %f %f %f Tm\n" 3865 "(%s) Tj\n" 3866 "ET\n", 3867 cnt, text->fontsize, crad, srad, -srad 3868 } 3869 } 3870 3871 /* 3872 This is used for producing aligned text in 3873 aligned text, (xbl, ybl) is the bottom left 3874 around (x, y).*/ 3875 inline void tools_gl2psPutPDFTextBL(tools_GL2 3876 tools_GLfloat x 3877 { 3878 if(text->angle == 0.0F){ 3879 gl2ps->streamlength += tools_gl2psPrintf 3880 (gl2ps, "BT\n" 3881 "/F%d %d Tf\n" 3882 "%f %f Td\n" 3883 "(%s) Tj\n" 3884 "ET\n", 3885 cnt, text->fontsize, xbl, ybl, text->s 3886 } 3887 else{ 3888 tools_GLfloat a, ca, sa; 3889 tools_GLfloat pi = 3.141593F; 3890 tools_GLfloat i = atan2(y - ybl, x - xbl) 3891 tools_GLfloat r = sqrt((y - ybl) * (y - y 3892 3893 a = (tools_GLfloat)(pi * text->angle / 18 3894 sa = (tools_GLfloat)sin(a); 3895 ca = (tools_GLfloat)cos(a); 3896 gl2ps->streamlength += tools_gl2psPrintf 3897 (gl2ps, "BT\n" 3898 "/F%d %d Tf\n" 3899 "%f %f %f %f %f %f Tm\n" 3900 "(%s) Tj\n" 3901 "ET\n", 3902 cnt, text->fontsize, 3903 ca, sa, -sa, ca, 3904 xbl + r * (cos(i) - cos(i + a)), ybl + 3905 } 3906 } 3907 3908 inline void tools_gl2psPutPDFSpecial(tools_GL 3909 { 3910 gl2ps->streamlength += tools_gl2psPrintf(gl 3911 gl2ps->streamlength += tools_gl2psPrintf(gl 3912 } 3913 3914 inline void tools_gl2psPutPDFImage(tools_GL2P 3915 { 3916 gl2ps->streamlength += tools_gl2psPrintf 3917 (gl2ps, "q\n" 3918 "%d 0 0 %d %f %f cm\n" 3919 "/Im%d Do\n" 3920 "Q\n", 3921 (int)(image->zoom_x * image->width), (in 3922 x, y, cnt); 3923 } 3924 3925 inline void tools_gl2psPDFstacksInit(tools_GL 3926 { 3927 gl2ps->objects_stack = 7 /* FIXED_XREF_ENTR 3928 gl2ps->extgs_stack = 0; 3929 gl2ps->font_stack = 0; 3930 gl2ps->im_stack = 0; 3931 gl2ps->trgroupobjects_stack = 0; 3932 gl2ps->shader_stack = 0; 3933 gl2ps->mshader_stack = 0; 3934 } 3935 3936 inline void tools_gl2psPDFgroupObjectInit(too 3937 { 3938 if(!gro) 3939 return; 3940 3941 gro->ptrlist = NULL; 3942 gro->fontno = gro->gsno = gro->imno = gro-> 3943 = gro->trgroupno = gro->fontobjno = gro-> 3944 = gro->maskshobjno = gro->gsobjno = gro-> 3945 } 3946 3947 /* Build up group objects and assign name and 3948 3949 inline void tools_gl2psPDFgroupListInit(tools 3950 { 3951 int i; 3952 tools_GL2PSprimitive *p = NULL; 3953 tools_GL2PSpdfgroup gro; 3954 int lasttype = TOOLS_GL2PS_NO_TYPE; 3955 tools_GL2PSrgba lastrgba = {-1.0F, -1.0F, - 3956 tools_GLushort lastpattern = 0; 3957 tools_GLint lastfactor = 0; 3958 tools_GLfloat lastwidth = 1; 3959 tools_GLint lastlinecap = 0; 3960 tools_GLint lastlinejoin = 0; 3961 tools_GL2PStriangle lastt, tmpt; 3962 int lastTriangleWasNotSimpleWithSameColor = 3963 3964 if(!gl2ps->pdfprimlist) 3965 return; 3966 3967 /*G.Barrand: add the below line to quiet Co 3968 in the below TOOLS_GL2PS_LINE, 3969 tools_gl2psPDFgroupObjectInit(&gro); 3970 3971 gl2ps->pdfgrouplist = tools_gl2psListCreate 3972 tools_gl2psInitTriangle(&lastt); 3973 3974 for(i = 0; i < tools_gl2psListNbr(gl2ps->pd 3975 p = *(tools_GL2PSprimitive**)tools_gl2psL 3976 switch(p->type){ 3977 case TOOLS_GL2PS_PIXMAP: 3978 tools_gl2psPDFgroupObjectInit(&gro); 3979 gro.ptrlist = tools_gl2psListCreate(1, 3980 gro.imno = gl2ps->im_stack++; 3981 tools_gl2psListAdd(gro.ptrlist, &p); 3982 tools_gl2psListAdd(gl2ps->pdfgrouplist, 3983 break; 3984 case TOOLS_GL2PS_TEXT: 3985 tools_gl2psPDFgroupObjectInit(&gro); 3986 gro.ptrlist = tools_gl2psListCreate(1, 3987 gro.fontno = gl2ps->font_stack++; 3988 tools_gl2psListAdd(gro.ptrlist, &p); 3989 tools_gl2psListAdd(gl2ps->pdfgrouplist, 3990 break; 3991 case TOOLS_GL2PS_LINE: 3992 if(lasttype != p->type || lastwidth != 3993 lastlinecap != p->linecap || lastlin 3994 lastpattern != p->pattern || lastfac 3995 !tools_gl2psSameColor(p->verts[0].rg 3996 tools_gl2psPDFgroupObjectInit(&gro); 3997 gro.ptrlist = tools_gl2psListCreate(1 3998 tools_gl2psListAdd(gro.ptrlist, &p); 3999 tools_gl2psListAdd(gl2ps->pdfgrouplis 4000 } 4001 else{ 4002 tools_gl2psListAdd(gro.ptrlist, &p); 4003 } 4004 lastpattern = p->pattern; 4005 lastfactor = p->factor; 4006 lastwidth = p->width; 4007 lastlinecap = p->linecap; 4008 lastlinejoin = p->linejoin; 4009 lastrgba[0] = p->verts[0].rgba[0]; 4010 lastrgba[1] = p->verts[0].rgba[1]; 4011 lastrgba[2] = p->verts[0].rgba[2]; 4012 break; 4013 case TOOLS_GL2PS_POINT: 4014 if(lasttype != p->type || lastwidth != 4015 !tools_gl2psSameColor(p->verts[0].rg 4016 tools_gl2psPDFgroupObjectInit(&gro); 4017 gro.ptrlist = tools_gl2psListCreate(1 4018 tools_gl2psListAdd(gro.ptrlist, &p); 4019 tools_gl2psListAdd(gl2ps->pdfgrouplis 4020 } 4021 else{ 4022 tools_gl2psListAdd(gro.ptrlist, &p); 4023 } 4024 lastwidth = p->width; 4025 lastrgba[0] = p->verts[0].rgba[0]; 4026 lastrgba[1] = p->verts[0].rgba[1]; 4027 lastrgba[2] = p->verts[0].rgba[2]; 4028 break; 4029 case TOOLS_GL2PS_TRIANGLE: 4030 tools_gl2psFillTriangleFromPrimitive(&t 4031 lastTriangleWasNotSimpleWithSameColor = 4032 !(tmpt.prop & T_CONST_COLOR && tmpt.p 4033 !tools_gl2psSameColor(tmpt.vertex[0]. 4034 if(lasttype == p->type && tmpt.prop == 4035 lastTriangleWasNotSimpleWithSameColo 4036 /* TODO Check here for last alpha */ 4037 tools_gl2psListAdd(gro.ptrlist, &p); 4038 } 4039 else{ 4040 tools_gl2psPDFgroupObjectInit(&gro); 4041 gro.ptrlist = tools_gl2psListCreate(1 4042 tools_gl2psListAdd(gro.ptrlist, &p); 4043 tools_gl2psListAdd(gl2ps->pdfgrouplis 4044 } 4045 lastt = tmpt; 4046 break; 4047 case TOOLS_GL2PS_SPECIAL: 4048 tools_gl2psPDFgroupObjectInit(&gro); 4049 gro.ptrlist = tools_gl2psListCreate(1, 4050 tools_gl2psListAdd(gro.ptrlist, &p); 4051 tools_gl2psListAdd(gl2ps->pdfgrouplist, 4052 break; 4053 default: 4054 break; 4055 } 4056 lasttype = p->type; 4057 } 4058 } 4059 4060 inline void tools_gl2psSortOutTrianglePDFgrou 4061 { 4062 tools_GL2PStriangle t; 4063 tools_GL2PSprimitive *prim = NULL; 4064 4065 if(!gro) 4066 return; 4067 4068 if(!tools_gl2psListNbr(gro->ptrlist)) 4069 return; 4070 4071 prim = *(tools_GL2PSprimitive**)tools_gl2ps 4072 4073 if(prim->type != TOOLS_GL2PS_TRIANGLE) 4074 return; 4075 4076 tools_gl2psFillTriangleFromPrimitive(&t, pr 4077 4078 if(t.prop & T_CONST_COLOR && t.prop & T_ALP 4079 gro->gsno = gl2ps->extgs_stack++; 4080 gro->gsobjno = gl2ps->objects_stack ++; 4081 } 4082 else if(t.prop & T_CONST_COLOR && t.prop & 4083 gro->gsno = gl2ps->extgs_stack++; 4084 gro->gsobjno = gl2ps->objects_stack++; 4085 gro->trgroupno = gl2ps->trgroupobjects_st 4086 gro->trgroupobjno = gl2ps->objects_stack+ 4087 gro->maskshno = gl2ps->mshader_stack++; 4088 gro->maskshobjno = gl2ps->objects_stack++ 4089 } 4090 else if(t.prop & T_VAR_COLOR && t.prop & T_ 4091 gro->shno = gl2ps->shader_stack++; 4092 gro->shobjno = gl2ps->objects_stack++; 4093 } 4094 else if(t.prop & T_VAR_COLOR && t.prop & T_ 4095 gro->gsno = gl2ps->extgs_stack++; 4096 gro->gsobjno = gl2ps->objects_stack++; 4097 gro->shno = gl2ps->shader_stack++; 4098 gro->shobjno = gl2ps->objects_stack++; 4099 } 4100 else if(t.prop & T_VAR_COLOR && t.prop & T_ 4101 gro->gsno = gl2ps->extgs_stack++; 4102 gro->gsobjno = gl2ps->objects_stack++; 4103 gro->shno = gl2ps->shader_stack++; 4104 gro->shobjno = gl2ps->objects_stack++; 4105 gro->trgroupno = gl2ps->trgroupobjects_st 4106 gro->trgroupobjno = gl2ps->objects_stack+ 4107 gro->maskshno = gl2ps->mshader_stack++; 4108 gro->maskshobjno = gl2ps->objects_stack++ 4109 } 4110 } 4111 4112 /* Main stream data */ 4113 4114 inline void tools_gl2psPDFgroupListWriteMainS 4115 { 4116 int i, j, lastel, count; 4117 tools_GL2PSprimitive *prim = NULL, *prev = 4118 tools_GL2PSpdfgroup *gro; 4119 tools_GL2PStriangle t; 4120 4121 if(!gl2ps->pdfgrouplist) 4122 return; 4123 4124 count = tools_gl2psListNbr(gl2ps->pdfgroupl 4125 4126 for(i = 0; i < count; ++i){ 4127 gro = (tools_GL2PSpdfgroup*)tools_gl2psLi 4128 4129 lastel = tools_gl2psListNbr(gro->ptrlist) 4130 if(lastel < 0) 4131 continue; 4132 4133 prim = *(tools_GL2PSprimitive**)tools_gl2 4134 4135 switch(prim->type){ 4136 case TOOLS_GL2PS_POINT: 4137 gl2ps->streamlength += tools_gl2psPrint 4138 gl2ps->streamlength += tools_gl2psPrint 4139 gl2ps->streamlength += tools_gl2psPrint 4140 for(j = 0; j <= lastel; ++j){ 4141 prim = *(tools_GL2PSprimitive**)tools 4142 gl2ps->streamlength += 4143 tools_gl2psPrintf(gl2ps,"%f %f m %f 4144 prim->verts[0].xyz[0], 4145 prim->verts[0].xyz[0], 4146 } 4147 gl2ps->streamlength += tools_gl2psPrint 4148 gl2ps->streamlength += tools_gl2psPrint 4149 break; 4150 case TOOLS_GL2PS_LINE: 4151 /* We try to use as few paths as possib 4152 order to get nice stippling even whe 4153 are smaller than the stipple */ 4154 gl2ps->streamlength += tools_gl2psPrint 4155 gl2ps->streamlength += tools_gl2psPrint 4156 gl2ps->streamlength += tools_gl2psPrint 4157 gl2ps->streamlength += tools_gl2psPrint 4158 gl2ps->streamlength += tools_gl2psPrint 4159 /* start new path */ 4160 gl2ps->streamlength += 4161 tools_gl2psPrintf(gl2ps,"%f %f m\n", 4162 prim->verts[0].xyz[0], pr 4163 4164 for(j = 1; j <= lastel; ++j){ 4165 prev = prim; 4166 prim = *(tools_GL2PSprimitive**)tools 4167 if(!tools_gl2psSamePosition(prim->ver 4168 /* the starting point of the new se 4169 end point of the previous line, 4170 path and start a new one */ 4171 gl2ps->streamlength += 4172 tools_gl2psPrintf(gl2ps,"%f %f l\ 4173 prev->verts[1].xyz[0] 4174 gl2ps->streamlength += 4175 tools_gl2psPrintf(gl2ps,"%f %f m\ 4176 prim->verts[0].xyz[0] 4177 } 4178 else{ 4179 /* the two segements are connected, 4180 current path */ 4181 gl2ps->streamlength += 4182 tools_gl2psPrintf(gl2ps,"%f %f l\ 4183 prim->verts[0].xyz[0] 4184 } 4185 } 4186 /* end last path */ 4187 gl2ps->streamlength += 4188 tools_gl2psPrintf(gl2ps,"%f %f l\n", 4189 prim->verts[1].xyz[0], pr 4190 gl2ps->streamlength += tools_gl2psPrint 4191 break; 4192 case TOOLS_GL2PS_TRIANGLE: 4193 tools_gl2psFillTriangleFromPrimitive(&t 4194 tools_gl2psSortOutTrianglePDFgroup(gl2p 4195 4196 /* No alpha and const color: Simple PDF 4197 if(t.prop & T_CONST_COLOR && t.prop & T 4198 gl2ps->streamlength += tools_gl2psPri 4199 for(j = 0; j <= lastel; ++j){ 4200 prim = *(tools_GL2PSprimitive**)too 4201 tools_gl2psFillTriangleFromPrimitiv 4202 gl2ps->streamlength 4203 += tools_gl2psPrintf(gl2ps,"%f %f 4204 "%f %f l\n" 4205 "%f %f l\n" 4206 "h f\n", 4207 t.vertex[0].xyz[0] 4208 t.vertex[1].xyz[0] 4209 t.vertex[2].xyz[0] 4210 } 4211 } 4212 /* Const alpha < 1 and const color: Sim 4213 and an extra extended Graphics State 4214 else if(t.prop & T_CONST_COLOR && t.pro 4215 gl2ps->streamlength += tools_gl2psPri 4216 "/ 4217 gr 4218 gl2ps->streamlength += tools_gl2psPri 4219 for(j = 0; j <= lastel; ++j){ 4220 prim = *(tools_GL2PSprimitive**)too 4221 tools_gl2psFillTriangleFromPrimitiv 4222 gl2ps->streamlength 4223 += tools_gl2psPrintf(gl2ps,"%f %f 4224 "%f %f l\n" 4225 "%f %f l\n" 4226 "h f\n", 4227 t.vertex[0].xyz[0] 4228 t.vertex[1].xyz[0] 4229 t.vertex[2].xyz[0] 4230 } 4231 gl2ps->streamlength += tools_gl2psPri 4232 } 4233 /* Variable alpha and const color: Simp 4234 and an extra extended Graphics State 4235 object for the alpha mask */ 4236 else if(t.prop & T_CONST_COLOR && t.pro 4237 gl2ps->streamlength += tools_gl2psPri 4238 "/ 4239 "/ 4240 gr 4241 gl2ps->streamlength += tools_gl2psPri 4242 for(j = 0; j <= lastel; ++j){ 4243 prim = *(tools_GL2PSprimitive**)too 4244 tools_gl2psFillTriangleFromPrimitiv 4245 gl2ps->streamlength 4246 += tools_gl2psPrintf(gl2ps,"%f %f 4247 "%f %f l\n" 4248 "%f %f l\n" 4249 "h f\n", 4250 t.vertex[0].xyz[0] 4251 t.vertex[1].xyz[0] 4252 t.vertex[2].xyz[0] 4253 } 4254 gl2ps->streamlength += tools_gl2psPri 4255 } 4256 /* Variable color and no alpha: Shader 4257 triangle(s) */ 4258 else if(t.prop & T_VAR_COLOR && t.prop 4259 gl2ps->streamlength += tools_gl2psPri 4260 } 4261 /* Variable color and const alpha < 1: 4262 colored triangle(s) and an extra ext 4263 for the alpha const */ 4264 else if(t.prop & T_VAR_COLOR && t.prop 4265 gl2ps->streamlength += tools_gl2psPri 4266 "/ 4267 "/ 4268 "Q 4269 gr 4270 } 4271 /* Variable alpha and color: Shader Obj 4272 triangle(s) and an extra extended Gr 4273 + Xobject + Shader object for the al 4274 else if(t.prop & T_VAR_COLOR && t.prop 4275 gl2ps->streamlength += tools_gl2psPri 4276 "/ 4277 "/ 4278 "/ 4279 "Q 4280 gr 4281 } 4282 break; 4283 case TOOLS_GL2PS_PIXMAP: 4284 for(j = 0; j <= lastel; ++j){ 4285 prim = *(tools_GL2PSprimitive**)tools 4286 tools_gl2psPutPDFImage(gl2ps, prim->d 4287 prim->verts[0].xyz[1 4288 } 4289 break; 4290 case TOOLS_GL2PS_TEXT: 4291 for(j = 0; j <= lastel; ++j){ 4292 prim = *(tools_GL2PSprimitive**)tools 4293 gl2ps->streamlength += tools_gl2psPri 4294 if (prim->numverts == 2) { 4295 tools_gl2psPutPDFTextBL(gl2ps, prim 4296 prim->verts[0].xy 4297 prim->verts[1].xy 4298 prim->verts[1].xy 4299 } 4300 else { 4301 tools_gl2psPutPDFText(gl2ps, prim-> 4302 prim->verts[0].xyz[ 4303 } 4304 } 4305 break; 4306 case TOOLS_GL2PS_SPECIAL: 4307 lastel = tools_gl2psListNbr(gro->ptrlis 4308 if(lastel < 0) 4309 continue; 4310 4311 for(j = 0; j <= lastel; ++j){ 4312 prim = *(tools_GL2PSprimitive**)tools 4313 tools_gl2psPutPDFSpecial(gl2ps, i, j, 4314 } 4315 default: 4316 break; 4317 } 4318 } 4319 } 4320 4321 /* Graphics State names */ 4322 4323 inline int tools_gl2psPDFgroupListWriteGState 4324 { 4325 tools_GL2PSpdfgroup *gro; 4326 int offs = 0; 4327 int i; 4328 4329 offs += fprintf(gl2ps->stream, 4330 "/ExtGState\n" 4331 "<<\n" 4332 "/GSa 7 0 R\n"); 4333 for(i = 0; i < tools_gl2psListNbr(gl2ps->pd 4334 gro = (tools_GL2PSpdfgroup*)tools_gl2psLi 4335 if(gro->gsno >= 0) 4336 offs += fprintf(gl2ps->stream, "/GS%d % 4337 } 4338 offs += fprintf(gl2ps->stream, ">>\n"); 4339 return offs; 4340 } 4341 4342 /* Main Shader names */ 4343 4344 inline int tools_gl2psPDFgroupListWriteShader 4345 { 4346 tools_GL2PSpdfgroup *gro; 4347 int offs = 0; 4348 int i; 4349 4350 offs += fprintf(gl2ps->stream, 4351 "/Shading\n" 4352 "<<\n"); 4353 for(i = 0; i < tools_gl2psListNbr(gl2ps->pd 4354 gro = (tools_GL2PSpdfgroup*)tools_gl2psLi 4355 if(gro->shno >= 0) 4356 offs += fprintf(gl2ps->stream, "/Sh%d % 4357 if(gro->maskshno >= 0) 4358 offs += fprintf(gl2ps->stream, "/TrSh%d 4359 } 4360 offs += fprintf(gl2ps->stream,">>\n"); 4361 return offs; 4362 } 4363 4364 /* Images & Mask Shader XObject names */ 4365 inline int tools_gl2psPDFgroupListWriteXObjec 4366 { 4367 int i; 4368 tools_GL2PSprimitive *p = NULL; 4369 tools_GL2PSpdfgroup *gro; 4370 int offs = 0; 4371 4372 offs += fprintf(gl2ps->stream, 4373 "/XObject\n" 4374 "<<\n"); 4375 4376 for(i = 0; i < tools_gl2psListNbr(gl2ps->pd 4377 gro = (tools_GL2PSpdfgroup*)tools_gl2psLi 4378 if(!tools_gl2psListNbr(gro->ptrlist)) 4379 continue; 4380 p = *(tools_GL2PSprimitive**)tools_gl2psL 4381 switch(p->type){ 4382 case TOOLS_GL2PS_PIXMAP: 4383 gro->imobjno = gl2ps->objects_stack++; 4384 if(TOOLS_GL_RGBA == p->data.image->form 4385 gl2ps->objects_stack++; 4386 offs += fprintf(gl2ps->stream, "/Im%d % 4387 break; /*G.Barrand : add this break.*/ 4388 case TOOLS_GL2PS_TRIANGLE: 4389 if(gro->trgroupno >=0) 4390 offs += fprintf(gl2ps->stream, "/TrG% 4391 break; 4392 default: 4393 break; 4394 } 4395 } 4396 offs += fprintf(gl2ps->stream,">>\n"); 4397 return offs; 4398 } 4399 4400 /* Font names */ 4401 4402 inline int tools_gl2psPDFgroupListWriteFontRe 4403 { 4404 int i; 4405 tools_GL2PSpdfgroup *gro; 4406 int offs = 0; 4407 4408 offs += fprintf(gl2ps->stream, "/Font\n<<\n 4409 4410 for(i = 0; i < tools_gl2psListNbr(gl2ps->pd 4411 gro = (tools_GL2PSpdfgroup*)tools_gl2psLi 4412 if(gro->fontno < 0) 4413 continue; 4414 gro->fontobjno = gl2ps->objects_stack++; 4415 offs += fprintf(gl2ps->stream, "/F%d %d 0 4416 } 4417 offs += fprintf(gl2ps->stream, ">>\n"); 4418 4419 return offs; 4420 } 4421 4422 inline void tools_gl2psPDFgroupListDelete(too 4423 { 4424 int i; 4425 tools_GL2PSpdfgroup *gro = NULL; 4426 4427 if(!gl2ps->pdfgrouplist) 4428 return; 4429 4430 for(i = 0; i < tools_gl2psListNbr(gl2ps->pd 4431 gro = (tools_GL2PSpdfgroup*)tools_gl2psLi 4432 tools_gl2psListDelete(gro->ptrlist); 4433 } 4434 4435 tools_gl2psListDelete(gl2ps->pdfgrouplist); 4436 gl2ps->pdfgrouplist = NULL; 4437 } 4438 4439 /* Print 1st PDF object - file info */ 4440 4441 inline int tools_gl2psPrintPDFInfo(tools_GL2P 4442 { 4443 int offs; 4444 time_t now; 4445 struct tm *newtime; 4446 4447 time(&now); 4448 newtime = gmtime(&now); 4449 4450 offs = fprintf(gl2ps->stream, 4451 "1 0 obj\n" 4452 "<<\n" 4453 "/Title (%s)\n" 4454 "/Creator (GL2PS %d.%d.%d%s, 4455 "/Producer (%s)\n", 4456 gl2ps->title, TOOLS_GL2PS_MA 4457 TOOLS_GL2PS_PATCH_VERSION, T 4458 gl2ps->producer); 4459 4460 if(!newtime){ 4461 offs += fprintf(gl2ps->stream, 4462 ">>\n" 4463 "endobj\n"); 4464 return offs; 4465 } 4466 4467 offs += fprintf(gl2ps->stream, 4468 "/CreationDate (D:%d%02d%02 4469 ">>\n" 4470 "endobj\n", 4471 newtime->tm_year+1900, 4472 newtime->tm_mon+1, 4473 newtime->tm_mday, 4474 newtime->tm_hour, 4475 newtime->tm_min, 4476 newtime->tm_sec); 4477 return offs; 4478 } 4479 4480 /* Create catalog and page structure - 2nd an 4481 4482 inline int tools_gl2psPrintPDFCatalog(tools_G 4483 { 4484 return fprintf(gl2ps->stream, 4485 "2 0 obj\n" 4486 "<<\n" 4487 "/Type /Catalog\n" 4488 "/Pages 3 0 R\n" 4489 ">>\n" 4490 "endobj\n"); 4491 } 4492 4493 inline int tools_gl2psPrintPDFPages(tools_GL2 4494 { 4495 return fprintf(gl2ps->stream, 4496 "3 0 obj\n" 4497 "<<\n" 4498 "/Type /Pages\n" 4499 "/Kids [6 0 R]\n" 4500 "/Count 1\n" 4501 ">>\n" 4502 "endobj\n"); 4503 } 4504 4505 /* Open stream for data - graphical objects, 4506 4507 inline int tools_gl2psOpenPDFDataStream(tools 4508 { 4509 int offs = 0; 4510 4511 offs += fprintf(gl2ps->stream, 4512 "4 0 obj\n" 4513 "<<\n" 4514 "/Length 5 0 R\n" ); 4515 offs += tools_gl2psPrintPDFCompressorType(g 4516 offs += fprintf(gl2ps->stream, 4517 ">>\n" 4518 "stream\n"); 4519 return offs; 4520 } 4521 4522 /* Stream setup - Graphics state, fill backgr 4523 4524 inline int tools_gl2psOpenPDFDataStreamWriteP 4525 { 4526 int offs; 4527 4528 offs = tools_gl2psPrintf(gl2ps,"/GSa gs\n") 4529 4530 if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR 4531 offs += tools_gl2psPrintPDFFillColor(gl2p 4532 offs += tools_gl2psPrintf(gl2ps,"%d %d %d 4533 (int)gl2ps->viewport[ 4534 (int)gl2ps->viewport[ 4535 offs += tools_gl2psPrintf(gl2ps,"f\n"); 4536 } 4537 return offs; 4538 } 4539 4540 /* Use the functions above to create the firs 4541 4542 inline void tools_gl2psPrintPDFHeader(tools_G 4543 { 4544 int offs = 0; 4545 gl2ps->pdfprimlist = tools_gl2psListCreate( 4546 tools_gl2psPDFstacksInit(gl2ps); 4547 4548 gl2ps->xreflist = (int*)tools_gl2psMalloc(s 4549 4550 #if defined(TOOLS_GL2PS_HAVE_ZLIB) 4551 if(gl2ps->options & TOOLS_GL2PS_COMPRESS){ 4552 tools_gl2psSetupCompress(gl2ps); 4553 } 4554 #endif 4555 gl2ps->xreflist[0] = 0; 4556 offs += fprintf(gl2ps->stream, "%%PDF-1.4\n 4557 gl2ps->xreflist[1] = offs; 4558 4559 offs += tools_gl2psPrintPDFInfo(gl2ps); 4560 gl2ps->xreflist[2] = offs; 4561 4562 offs += tools_gl2psPrintPDFCatalog(gl2ps); 4563 gl2ps->xreflist[3] = offs; 4564 4565 offs += tools_gl2psPrintPDFPages(gl2ps); 4566 gl2ps->xreflist[4] = offs; 4567 4568 offs += tools_gl2psOpenPDFDataStream(gl2ps) 4569 gl2ps->xreflist[5] = offs; /* finished in t 4570 gl2ps->streamlength = tools_gl2psOpenPDFDat 4571 } 4572 4573 /* The central primitive drawing */ 4574 4575 inline void tools_gl2psPrintPDFPrimitive(tool 4576 { 4577 tools_GL2PSprimitive *prim = *(tools_GL2PSp 4578 4579 if((gl2ps->options & TOOLS_GL2PS_OCCLUSION_ 4580 return; 4581 4582 prim = tools_gl2psCopyPrimitive(prim); /* d 4583 tools_gl2psListAdd(gl2ps->pdfprimlist, &pri 4584 } 4585 4586 /* close stream and ... */ 4587 4588 inline int tools_gl2psClosePDFDataStream(tool 4589 { 4590 int offs = 0; 4591 4592 #if defined(TOOLS_GL2PS_HAVE_ZLIB) 4593 if(gl2ps->options & TOOLS_GL2PS_COMPRESS){ 4594 if(Z_OK != tools_gl2psDeflate(gl2ps)) 4595 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Zlib 4596 else 4597 fwrite(gl2ps->compress->dest, gl2ps->co 4598 gl2ps->streamlength += gl2ps->compress->d 4599 4600 offs += gl2ps->streamlength; 4601 tools_gl2psFreeCompress(gl2ps); 4602 } 4603 #endif 4604 4605 offs += fprintf(gl2ps->stream, 4606 "endstream\n" 4607 "endobj\n"); 4608 return offs; 4609 } 4610 4611 /* ... write the now known length object */ 4612 4613 inline int tools_gl2psPrintPDFDataStreamLengt 4614 { 4615 return fprintf(gl2ps->stream, 4616 "5 0 obj\n" 4617 "%d\n" 4618 "endobj\n", val); 4619 } 4620 4621 /* Put the info created before in PDF objects 4622 4623 inline int tools_gl2psPrintPDFOpenPage(tools_ 4624 { 4625 int offs; 4626 4627 /* Write fixed part */ 4628 4629 offs = fprintf(gl2ps->stream, 4630 "6 0 obj\n" 4631 "<<\n" 4632 "/Type /Page\n" 4633 "/Parent 3 0 R\n" 4634 "/MediaBox [%d %d %d %d]\n", 4635 (int)gl2ps->viewport[0], (in 4636 (int)gl2ps->viewport[2], (in 4637 4638 if(gl2ps->options & TOOLS_GL2PS_LANDSCAPE) 4639 offs += fprintf(gl2ps->stream, "/Rotate - 4640 4641 offs += fprintf(gl2ps->stream, 4642 "/Contents 4 0 R\n" 4643 "/Resources\n" 4644 "<<\n" 4645 "/ProcSet [/PDF /Text /Imag 4646 4647 return offs; 4648 4649 /* End fixed part, proceeds in tools_gl2psP 4650 } 4651 4652 inline int tools_gl2psPDFgroupListWriteVariab 4653 { 4654 int offs = 0; 4655 4656 /* a) Graphics States for shader alpha mask 4657 offs += tools_gl2psPDFgroupListWriteGStateR 4658 4659 /* b) Shader and shader masks */ 4660 offs += tools_gl2psPDFgroupListWriteShaderR 4661 4662 /* c) XObjects (Images & Shader Masks) */ 4663 offs += tools_gl2psPDFgroupListWriteXObject 4664 4665 /* d) Fonts */ 4666 offs += tools_gl2psPDFgroupListWriteFontRes 4667 4668 /* End resources and page */ 4669 offs += fprintf(gl2ps->stream, 4670 ">>\n" 4671 ">>\n" 4672 "endobj\n"); 4673 return offs; 4674 } 4675 4676 /* Standard Graphics State */ 4677 4678 inline int tools_gl2psPrintPDFGSObject(tools_ 4679 { 4680 return fprintf(gl2ps->stream, 4681 "7 0 obj\n" 4682 "<<\n" 4683 "/Type /ExtGState\n" 4684 "/SA false\n" 4685 "/SM 0.02\n" 4686 "/OP false\n" 4687 "/op false\n" 4688 "/OPM 0\n" 4689 "/BG2 /Default\n" 4690 "/UCR2 /Default\n" 4691 "/TR2 /Default\n" 4692 ">>\n" 4693 "endobj\n"); 4694 } 4695 4696 /* Put vertex' edge flag (8bit) and coordinat 4697 4698 inline int tools_gl2psPrintPDFShaderStreamDat 4699 4700 4701 4702 { 4703 int offs = 0; 4704 unsigned long imap; 4705 tools_GLfloat diff; 4706 //double dmax = ~1UL; 4707 double dmax = (double)~1UL; //G.Barrand : c 4708 char edgeflag = 0; 4709 4710 /* FIXME: temp bux fix for 64 bit archs: */ 4711 if(sizeof(unsigned long) == 8) dmax = dmax 4712 4713 offs += (*action)(gl2ps, edgeflag, 1); 4714 4715 /* The Shader stream in PDF requires to be 4716 order */ 4717 4718 if(TOOLS_GL2PS_ZERO(dx * dy)){ 4719 offs += (*action)(gl2ps, 0, 4); 4720 offs += (*action)(gl2ps, 0, 4); 4721 } 4722 else{ 4723 diff = (vertex->xyz[0] - xmin) / dx; 4724 if(diff > 1) 4725 diff = 1.0F; 4726 else if(diff < 0) 4727 diff = 0.0F; 4728 imap = (unsigned long)(diff * dmax); 4729 offs += (*action)(gl2ps, imap, 4); 4730 4731 diff = (vertex->xyz[1] - ymin) / dy; 4732 if(diff > 1) 4733 diff = 1.0F; 4734 else if(diff < 0) 4735 diff = 0.0F; 4736 imap = (unsigned long)(diff * dmax); 4737 offs += (*action)(gl2ps, imap, 4); 4738 } 4739 4740 return offs; 4741 } 4742 4743 /* Put vertex' rgb value (8bit for every comp 4744 4745 inline int tools_gl2psPrintPDFShaderStreamDat 4746 i 4747 { 4748 int offs = 0; 4749 unsigned long imap; 4750 //double dmax = ~1UL; 4751 double dmax = (double)~1UL; //G.Barrand : c 4752 4753 /* FIXME: temp bux fix for 64 bit archs: */ 4754 if(sizeof(unsigned long) == 8) dmax = dmax 4755 4756 imap = (unsigned long)((vertex->rgba[0]) * 4757 offs += (*action)(gl2ps, imap, 1); 4758 4759 imap = (unsigned long)((vertex->rgba[1]) * 4760 offs += (*action)(gl2ps, imap, 1); 4761 4762 imap = (unsigned long)((vertex->rgba[2]) * 4763 offs += (*action)(gl2ps, imap, 1); 4764 4765 return offs; 4766 } 4767 4768 /* Put vertex' alpha (8/16bit) in shader stre 4769 4770 inline int tools_gl2psPrintPDFShaderStreamDat 4771 4772 4773 { 4774 int offs = 0; 4775 unsigned long imap; 4776 //double dmax = ~1UL; 4777 double dmax = (double)~1UL; //G.Barrand : c 4778 4779 /* FIXME: temp bux fix for 64 bit archs: */ 4780 if(sizeof(unsigned long) == 8) dmax = dmax 4781 4782 if(sigbyte != 8 && sigbyte != 16) 4783 sigbyte = 8; 4784 4785 sigbyte /= 8; 4786 4787 imap = (unsigned long)((vertex->rgba[3]) * 4788 4789 offs += (*action)(gl2ps, imap, sigbyte); 4790 4791 return offs; 4792 } 4793 4794 /* Put a triangles raw data in shader stream 4795 4796 inline int tools_gl2psPrintPDFShaderStreamDat 4797 tool 4798 tool 4799 int 4800 int 4801 { 4802 int i, offs = 0; 4803 tools_GL2PSvertex v; 4804 4805 if(a_gray && a_gray != 8 && a_gray != 16) 4806 a_gray = 8; 4807 4808 for(i = 0; i < 3; ++i){ 4809 offs += tools_gl2psPrintPDFShaderStreamDa 4810 4811 if(a_gray){ 4812 v = triangle->vertex[i]; 4813 offs += tools_gl2psPrintPDFShaderStream 4814 } 4815 else{ 4816 offs += tools_gl2psPrintPDFShaderStream 4817 } 4818 } 4819 4820 return offs; 4821 } 4822 4823 inline void tools_gl2psPDFRectHull(tools_GLfl 4824 tools_GLfloat *y 4825 tools_GL2PStrian 4826 { 4827 int i, j; 4828 4829 *xmin = triangles[0].vertex[0].xyz[0]; 4830 *xmax = triangles[0].vertex[0].xyz[0]; 4831 *ymin = triangles[0].vertex[0].xyz[1]; 4832 *ymax = triangles[0].vertex[0].xyz[1]; 4833 4834 for(i = 0; i < cnt; ++i){ 4835 for(j = 0; j < 3; ++j){ 4836 if(*xmin > triangles[i].vertex[j].xyz[0 4837 *xmin = triangles[i].vertex[j].xyz[0] 4838 if(*xmax < triangles[i].vertex[j].xyz[0 4839 *xmax = triangles[i].vertex[j].xyz[0] 4840 if(*ymin > triangles[i].vertex[j].xyz[1 4841 *ymin = triangles[i].vertex[j].xyz[1] 4842 if(*ymax < triangles[i].vertex[j].xyz[1 4843 *ymax = triangles[i].vertex[j].xyz[1] 4844 } 4845 } 4846 } 4847 4848 /* Writes shaded triangle 4849 gray == 0 means write RGB triangles 4850 gray == 8 8bit-grayscale (for 4851 gray == 16 16bit-grayscale (for 4852 4853 inline int tools_gl2psPrintPDFShader(tools_GL 4854 int size, int 4855 { 4856 int i, offs = 0, vertexbytes, done = 0; 4857 tools_GLfloat xmin, xmax, ymin, ymax; 4858 4859 switch(a_gray){ 4860 case 0: 4861 vertexbytes = 1+4+4+1+1+1; 4862 break; 4863 case 8: 4864 vertexbytes = 1+4+4+1; 4865 break; 4866 case 16: 4867 vertexbytes = 1+4+4+2; 4868 break; 4869 default: 4870 a_gray = 8; 4871 vertexbytes = 1+4+4+1; 4872 break; 4873 } 4874 4875 tools_gl2psPDFRectHull(&xmin, &xmax, &ymin, 4876 4877 offs += fprintf(gl2ps->stream, 4878 "%d 0 obj\n" 4879 "<< " 4880 "/ShadingType 4 " 4881 "/ColorSpace %s " 4882 "/BitsPerCoordinate 32 " 4883 "/BitsPerComponent %d " 4884 "/BitsPerFlag 8 " 4885 "/Decode [%f %f %f %f 0 1 % 4886 obj, 4887 (a_gray) ? "/DeviceGray" : 4888 (a_gray) ? a_gray : 8, 4889 xmin, xmax, ymin, ymax, 4890 (a_gray) ? "" : "0 1 0 1"); 4891 4892 #if defined(TOOLS_GL2PS_HAVE_ZLIB) 4893 if(gl2ps->options & TOOLS_GL2PS_COMPRESS){ 4894 tools_gl2psAllocCompress(gl2ps,vertexbyte 4895 4896 for(i = 0; i < size; ++i) 4897 tools_gl2psPrintPDFShaderStreamData(gl2 4898 xmax-xmin 4899 tools_gl2 4900 4901 if(Z_OK == tools_gl2psDeflate(gl2ps) && 2 4902 offs += tools_gl2psPrintPDFCompressorTy 4903 offs += fprintf(gl2ps->stream, 4904 "/Length %d " 4905 ">>\n" 4906 "stream\n", 4907 (int)gl2ps->compress->d 4908 offs += gl2ps->compress->destLen * fwri 4909 4910 4911 done = 1; 4912 } 4913 tools_gl2psFreeCompress(gl2ps); 4914 } 4915 #endif 4916 4917 if(!done){ 4918 /* no compression, or too long after comp 4919 -> write non-compressed entry */ 4920 offs += fprintf(gl2ps->stream, 4921 "/Length %d " 4922 ">>\n" 4923 "stream\n", 4924 vertexbytes * 3 * size); 4925 for(i = 0; i < size; ++i) 4926 offs += tools_gl2psPrintPDFShaderStream 4927 x 4928 t 4929 } 4930 4931 offs += fprintf(gl2ps->stream, 4932 "\nendstream\n" 4933 "endobj\n"); 4934 4935 return offs; 4936 } 4937 4938 /* Writes a XObject for a shaded triangle mas 4939 4940 inline int tools_gl2psPrintPDFShaderMask(tool 4941 { 4942 int offs = 0, len; 4943 4944 offs += fprintf(gl2ps->stream, 4945 "%d 0 obj\n" 4946 "<<\n" 4947 "/Type /XObject\n" 4948 "/Subtype /Form\n" 4949 "/BBox [ %d %d %d %d ]\n" 4950 "/Group \n<<\n/S /Transpare 4951 ">>\n", 4952 obj, 4953 (int)gl2ps->viewport[0], (i 4954 (int)gl2ps->viewport[2], (i 4955 4956 len = (childobj>0) 4957 ? (int)strlen("/TrSh sh\n") + (int)log10( 4958 : (int)strlen("/TrSh0 sh\n"); 4959 4960 offs += fprintf(gl2ps->stream, 4961 "/Length %d\n" 4962 ">>\n" 4963 "stream\n", 4964 len); 4965 offs += fprintf(gl2ps->stream, 4966 "/TrSh%d sh\n", 4967 childobj); 4968 offs += fprintf(gl2ps->stream, 4969 "endstream\n" 4970 "endobj\n"); 4971 4972 return offs; 4973 } 4974 4975 /* Writes a Extended graphics state for a sha 4976 simplealpha ist true the childobj argument 4977 statement will be written instead */ 4978 4979 inline int tools_gl2psPrintPDFShaderExtGS(too 4980 { 4981 int offs = 0; 4982 4983 offs += fprintf(gl2ps->stream, 4984 "%d 0 obj\n" 4985 "<<\n", 4986 obj); 4987 4988 offs += fprintf(gl2ps->stream, 4989 "/SMask << /S /Alpha /G %d 4990 childobj); 4991 4992 offs += fprintf(gl2ps->stream, 4993 ">>\n" 4994 "endobj\n"); 4995 return offs; 4996 } 4997 4998 /* a simple graphics state */ 4999 5000 inline int tools_gl2psPrintPDFShaderSimpleExt 5001 { 5002 int offs = 0; 5003 5004 offs += fprintf(gl2ps->stream, 5005 "%d 0 obj\n" 5006 "<<\n" 5007 "/ca %g" 5008 ">>\n" 5009 "endobj\n", 5010 obj, alpha); 5011 return offs; 5012 } 5013 5014 /* Similar groups of functions for pixmaps an 5015 5016 inline int tools_gl2psPrintPDFPixmapStreamDat 5017 int 5018 int 5019 { 5020 int x, y, shift; 5021 tools_GLfloat _r, _g, _b, _a; 5022 5023 if(im->format != TOOLS_GL_RGBA && a_gray) 5024 return 0; 5025 5026 if(a_gray && a_gray != 8 && a_gray != 16) 5027 a_gray = 8; 5028 5029 a_gray /= 8; 5030 5031 shift = (sizeof(unsigned long) - 1) * 8; 5032 5033 for(y = 0; y < im->height; ++y){ 5034 for(x = 0; x < im->width; ++x){ 5035 _a = tools_gl2psGetRGB(im, x, y, &_r, & 5036 if(im->format == TOOLS_GL_RGBA && a_gra 5037 (*action)(gl2ps, (unsigned long)(_a * 5038 } 5039 else{ 5040 (*action)(gl2ps, (unsigned long)(_r * 5041 (*action)(gl2ps, (unsigned long)(_g * 5042 (*action)(gl2ps, (unsigned long)(_b * 5043 } 5044 } 5045 } 5046 5047 switch(a_gray){ 5048 case 0: return 3 * im->width * im->height; 5049 case 1: return im->width * im->height; 5050 case 2: return 2 * im->width * im->height; 5051 default: return 3 * im->width * im->height; 5052 } 5053 } 5054 5055 inline int tools_gl2psPrintPDFPixmap(tools_GL 5056 { 5057 int offs = 0, done = 0, sigbytes = 3; 5058 5059 if(a_gray && a_gray !=8 && a_gray != 16) 5060 a_gray = 8; 5061 5062 if(a_gray) 5063 sigbytes = a_gray / 8; 5064 5065 offs += fprintf(gl2ps->stream, 5066 "%d 0 obj\n" 5067 "<<\n" 5068 "/Type /XObject\n" 5069 "/Subtype /Image\n" 5070 "/Width %d\n" 5071 "/Height %d\n" 5072 "/ColorSpace %s \n" 5073 "/BitsPerComponent 8\n", 5074 obj, 5075 (int)im->width, (int)im->he 5076 (a_gray) ? "/DeviceGray" : 5077 if(TOOLS_GL_RGBA == im->format && a_gray == 5078 offs += fprintf(gl2ps->stream, 5079 "/SMask %d 0 R\n", 5080 childobj); 5081 } 5082 5083 #if defined(TOOLS_GL2PS_HAVE_ZLIB) 5084 if(gl2ps->options & TOOLS_GL2PS_COMPRESS){ 5085 tools_gl2psAllocCompress(gl2ps,(int)(im-> 5086 5087 tools_gl2psPrintPDFPixmapStreamData(gl2ps 5088 5089 if(Z_OK == tools_gl2psDeflate(gl2ps) && 2 5090 offs += tools_gl2psPrintPDFCompressorTy 5091 offs += fprintf(gl2ps->stream, 5092 "/Length %d " 5093 ">>\n" 5094 "stream\n", 5095 (int)gl2ps->compress->d 5096 offs += gl2ps->compress->destLen * fwri 5097 5098 done = 1; 5099 } 5100 tools_gl2psFreeCompress(gl2ps); 5101 } 5102 #endif 5103 5104 if(!done){ 5105 /* no compression, or too long after comp 5106 -> write non-compressed entry */ 5107 offs += fprintf(gl2ps->stream, 5108 "/Length %d " 5109 ">>\n" 5110 "stream\n", 5111 (int)(im->width * im->hei 5112 offs += tools_gl2psPrintPDFPixmapStreamDa 5113 } 5114 5115 offs += fprintf(gl2ps->stream, 5116 "\nendstream\n" 5117 "endobj\n"); 5118 5119 return offs; 5120 } 5121 5122 inline int tools_gl2psPrintPDFText(tools_GL2P 5123 { 5124 int offs = 0; 5125 5126 offs += fprintf(gl2ps->stream, 5127 "%d 0 obj\n" 5128 "<<\n" 5129 "/Type /Font\n" 5130 "/Subtype /Type1\n" 5131 "/Name /F%d\n" 5132 "/BaseFont /%s\n" 5133 "/Encoding /MacRomanEncodin 5134 ">>\n" 5135 "endobj\n", 5136 obj, fontnumber, a_s->fontn 5137 return offs; 5138 } 5139 5140 /* Write the physical objects */ 5141 5142 inline int tools_gl2psPDFgroupListWriteObject 5143 { 5144 int i,j; 5145 tools_GL2PSprimitive *p = NULL; 5146 tools_GL2PSpdfgroup *gro; 5147 int offs = entryoffs; 5148 tools_GL2PStriangle *triangles; 5149 int size = 0; 5150 5151 if(!gl2ps->pdfgrouplist) 5152 return offs; 5153 5154 for(i = 0; i < tools_gl2psListNbr(gl2ps->pd 5155 gro = (tools_GL2PSpdfgroup*)tools_gl2psLi 5156 if(!tools_gl2psListNbr(gro->ptrlist)) 5157 continue; 5158 p = *(tools_GL2PSprimitive**)tools_gl2psL 5159 switch(p->type){ 5160 case TOOLS_GL2PS_POINT: 5161 break; 5162 case TOOLS_GL2PS_LINE: 5163 break; 5164 case TOOLS_GL2PS_TRIANGLE: 5165 size = tools_gl2psListNbr(gro->ptrlist) 5166 triangles = (tools_GL2PStriangle*)tools 5167 for(j = 0; j < size; ++j){ 5168 p = *(tools_GL2PSprimitive**)tools_gl 5169 tools_gl2psFillTriangleFromPrimitive( 5170 } 5171 if(triangles[0].prop & T_VAR_COLOR){ 5172 gl2ps->xreflist[gro->shobjno] = offs; 5173 offs += tools_gl2psPrintPDFShader(gl2 5174 } 5175 if(triangles[0].prop & T_ALPHA_LESS_1){ 5176 gl2ps->xreflist[gro->gsobjno] = offs; 5177 offs += tools_gl2psPrintPDFShaderSimp 5178 } 5179 if(triangles[0].prop & T_VAR_ALPHA){ 5180 gl2ps->xreflist[gro->gsobjno] = offs; 5181 offs += tools_gl2psPrintPDFShaderExtG 5182 gl2ps->xreflist[gro->trgroupobjno] = 5183 offs += tools_gl2psPrintPDFShaderMask 5184 gl2ps->xreflist[gro->maskshobjno] = o 5185 offs += tools_gl2psPrintPDFShader(gl2 5186 } 5187 tools_gl2psFree(triangles); 5188 break; 5189 case TOOLS_GL2PS_PIXMAP: 5190 gl2ps->xreflist[gro->imobjno] = offs; 5191 offs += tools_gl2psPrintPDFPixmap(gl2ps 5192 if(p->data.image->format == TOOLS_GL_RG 5193 gl2ps->xreflist[gro->imobjno+1] = off 5194 offs += tools_gl2psPrintPDFPixmap(gl2 5195 } 5196 break; 5197 case TOOLS_GL2PS_TEXT: 5198 gl2ps->xreflist[gro->fontobjno] = offs; 5199 offs += tools_gl2psPrintPDFText(gl2ps, 5200 break; 5201 case TOOLS_GL2PS_SPECIAL : 5202 /* alignment contains the format for wh 5203 is intended */ 5204 if(p->data.text->alignment == TOOLS_GL2 5205 offs += fprintf(gl2ps->stream, "%s\n" 5206 break; 5207 default: 5208 break; 5209 } 5210 } 5211 return offs; 5212 } 5213 5214 /* All variable data has been written at this 5215 functioninality has been gathered, so we c 5216 with cross reference table and trailer */ 5217 5218 inline void tools_gl2psPrintPDFFooter(tools_G 5219 { 5220 int i, offs; 5221 5222 tools_gl2psPDFgroupListInit(gl2ps); 5223 tools_gl2psPDFgroupListWriteMainStream(gl2p 5224 5225 offs = gl2ps->xreflist[5] + gl2ps->streamle 5226 offs += tools_gl2psClosePDFDataStream(gl2ps 5227 gl2ps->xreflist[5] = offs; 5228 5229 offs += tools_gl2psPrintPDFDataStreamLength 5230 gl2ps->xreflist[6] = offs; 5231 gl2ps->streamlength = 0; 5232 5233 offs += tools_gl2psPrintPDFOpenPage(gl2ps); 5234 offs += tools_gl2psPDFgroupListWriteVariabl 5235 gl2ps->xreflist = (int*)tools_gl2psRealloc( 5236 sizeof 5237 gl2ps->xreflist[7] = offs; 5238 5239 offs += tools_gl2psPrintPDFGSObject(gl2ps); 5240 gl2ps->xreflist[8] = offs; 5241 5242 gl2ps->xreflist[gl2ps->objects_stack] = 5243 tools_gl2psPDFgroupListWriteObjects(gl2ps 5244 5245 /* Start cross reference table. The file ha 5246 binary mode to preserve the 20 digit str 5247 fprintf(gl2ps->stream, 5248 "xref\n" 5249 "0 %d\n" 5250 "%010d 65535 f \n", gl2ps->objects_ 5251 5252 for(i = 1; i < gl2ps->objects_stack; ++i) 5253 fprintf(gl2ps->stream, "%010d 00000 n \n" 5254 5255 fprintf(gl2ps->stream, 5256 "trailer\n" 5257 "<<\n" 5258 "/Size %d\n" 5259 "/Info 1 0 R\n" 5260 "/Root 2 0 R\n" 5261 ">>\n" 5262 "startxref\n%d\n" 5263 "%%%%EOF\n", 5264 gl2ps->objects_stack, gl2ps->xrefli 5265 5266 /* Free auxiliary lists and arrays */ 5267 tools_gl2psFree(gl2ps->xreflist); 5268 tools_gl2psListAction(gl2ps->pdfprimlist, t 5269 tools_gl2psListDelete(gl2ps->pdfprimlist); 5270 tools_gl2psPDFgroupListDelete(gl2ps); 5271 5272 #if defined(TOOLS_GL2PS_HAVE_ZLIB) 5273 if(gl2ps->options & TOOLS_GL2PS_COMPRESS){ 5274 tools_gl2psFreeCompress(gl2ps); 5275 tools_gl2psFree(gl2ps->compress); 5276 gl2ps->compress = NULL; 5277 } 5278 #endif 5279 } 5280 5281 /* PDF begin viewport */ 5282 5283 inline void tools_gl2psPrintPDFBeginViewport( 5284 { 5285 int offs = 0; 5286 tools_GLint idx; 5287 tools_GLfloat rgba[4]; 5288 int x = viewport[0], y = viewport[1], w = v 5289 5290 tools_glRenderMode(TOOLS_GL_FEEDBACK); 5291 5292 tools_gl2psResetLineProperties(gl2ps); 5293 5294 if(gl2ps->header){ 5295 tools_gl2psPrintPDFHeader(gl2ps); 5296 gl2ps->header = TOOLS_GL_FALSE; 5297 } 5298 5299 offs += tools_gl2psPrintf(gl2ps,"q\n"); 5300 5301 if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR 5302 if(gl2ps->colormode == TOOLS_GL_RGBA || g 5303 tools_glGetFloatv(TOOLS_GL_COLOR_CLEAR_ 5304 } 5305 else{ 5306 tools_glGetIntegerv(TOOLS_GL_INDEX_CLEA 5307 rgba[0] = gl2ps->colormap[idx][0]; 5308 rgba[1] = gl2ps->colormap[idx][1]; 5309 rgba[2] = gl2ps->colormap[idx][2]; 5310 rgba[3] = 1.0F; 5311 } 5312 offs += tools_gl2psPrintPDFFillColor(gl2p 5313 offs += tools_gl2psPrintf(gl2ps,"%d %d %d 5314 "W\n" 5315 "f\n", 5316 x, y, w, h); 5317 } 5318 else{ 5319 offs += tools_gl2psPrintf(gl2ps,"%d %d %d 5320 "W\n" 5321 "n\n", 5322 x, y, w, h); 5323 } 5324 5325 gl2ps->streamlength += offs; 5326 } 5327 5328 inline tools_GLint tools_gl2psPrintPDFEndView 5329 { 5330 tools_GLint res; 5331 5332 res = tools_gl2psPrintPrimitives(gl2ps); 5333 gl2ps->streamlength += tools_gl2psPrintf(gl 5334 return res; 5335 } 5336 5337 inline void tools_gl2psPrintPDFFinalPrimitive 5338 { 5339 } 5340 5341 /* definition of the PDF backend */ 5342 5343 static const tools_GL2PSbackend tools_gl2psPD 5344 tools_gl2psPrintPDFHeader, 5345 tools_gl2psPrintPDFFooter, 5346 tools_gl2psPrintPDFBeginViewport, 5347 tools_gl2psPrintPDFEndViewport, 5348 tools_gl2psPrintPDFPrimitive, 5349 tools_gl2psPrintPDFFinalPrimitive, 5350 "pdf", 5351 "Portable Document Format" 5352 }; 5353 5354 /******************************************** 5355 * 5356 * SVG routines 5357 * 5358 ******************************************** 5359 5360 inline void tools_gl2psSVGGetCoordsAndColors( 5361 tools_ 5362 { 5363 int i, j; 5364 5365 for(i = 0; i < n; i++){ 5366 xyz[i][0] = verts[i].xyz[0]; 5367 xyz[i][1] = gl2ps->viewport[3] - verts[i] 5368 xyz[i][2] = 0.0F; 5369 for(j = 0; j < 4; j++) 5370 rgba[i][j] = verts[i].rgba[j]; 5371 } 5372 } 5373 5374 #include <sstream> //G.Barrand 5375 #include <iomanip> //G.Barrand 5376 5377 inline void tools_gl2psSVGGetColorString(tool 5378 { 5379 int _r = (int)(255. * rgba[0]); 5380 int _g = (int)(255. * rgba[1]); 5381 int _b = (int)(255. * rgba[2]); 5382 int rc = (_r < 0) ? 0 : (_r > 255) ? 255 : 5383 int gc = (_g < 0) ? 0 : (_g > 255) ? 255 : 5384 int bc = (_b < 0) ? 0 : (_b > 255) ? 255 : 5385 //sprintf(str, "#%2.2x%2.2x%2.2x", rc, gc, bc 5386 //G.Barrand:begin: 5387 std::ostringstream oss; 5388 oss << "#"; 5389 oss << std::setw(2) << std::setfill('0') << 5390 oss << std::setw(2) << std::setfill('0') << 5391 oss << std::setw(2) << std::setfill('0') << 5392 strcpy(str,oss.str().c_str()); 5393 //G.Barrand:end. 5394 } 5395 5396 inline void tools_gl2psPrintSVGHeader(tools_G 5397 { 5398 int x, y, width, height; 5399 char col[32]; 5400 time_t now; 5401 5402 time(&now); 5403 5404 if (gl2ps->options & TOOLS_GL2PS_LANDSCAPE) 5405 x = (int)gl2ps->viewport[1]; 5406 y = (int)gl2ps->viewport[0]; 5407 width = (int)gl2ps->viewport[3]; 5408 height = (int)gl2ps->viewport[2]; 5409 } 5410 else{ 5411 x = (int)gl2ps->viewport[0]; 5412 y = (int)gl2ps->viewport[1]; 5413 width = (int)gl2ps->viewport[2]; 5414 height = (int)gl2ps->viewport[3]; 5415 } 5416 5417 /* Compressed SVG files (.svgz) are simply 5418 tools_gl2psPrintGzipHeader(gl2ps); 5419 5420 tools_gl2psPrintf(gl2ps,"<?xml version=\"1. 5421 tools_gl2psPrintf(gl2ps,"<svg xmlns=\"http: 5422 tools_gl2psPrintf(gl2ps," xmlns:xlink=\ 5423 " width=\"%dpt\" height=\"% 5424 width, height, x, y, width, hei 5425 tools_gl2psPrintf(gl2ps,"<title>%s</title>\ 5426 tools_gl2psPrintf(gl2ps,"<desc>\n"); 5427 tools_gl2psPrintf(gl2ps,"Creator: GL2PS %d. 5428 "For: %s\n" 5429 "CreationDate: %s", 5430 TOOLS_GL2PS_MAJOR_VERSION, TOOL 5431 TOOLS_GL2PS_EXTRA_VERSION, TOOL 5432 tools_gl2psPrintf(gl2ps,"</desc>\n"); 5433 tools_gl2psPrintf(gl2ps,"<defs>\n"); 5434 tools_gl2psPrintf(gl2ps,"</defs>\n"); 5435 5436 if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR 5437 tools_gl2psSVGGetColorString(gl2ps->bgcol 5438 tools_gl2psPrintf(gl2ps,"<polygon fill=\" 5439 (int)gl2ps->viewport[0], (int 5440 (int)gl2ps->viewport[2], (int 5441 (int)gl2ps->viewport[2], (int 5442 (int)gl2ps->viewport[0], (int 5443 } 5444 5445 /* group all the primitives and disable ant 5446 tools_gl2psPrintf(gl2ps,"<g>\n"); 5447 } 5448 5449 inline void tools_gl2psPrintSVGSmoothTriangle 5450 { 5451 int i; 5452 tools_GL2PSxyz xyz2[3]; 5453 tools_GL2PSrgba rgba2[3]; 5454 char col[32]; 5455 5456 /* Apparently there is no easy way to do Go 5457 without explicitly pre-defining gradient 5458 recursive subdivision */ 5459 5460 if(tools_gl2psSameColorThreshold(3, rgba, g 5461 tools_gl2psSVGGetColorString(rgba[0], col 5462 tools_gl2psPrintf(gl2ps,"<polygon fill=\" 5463 if(rgba[0][3] < 1.0F) tools_gl2psPrintf(g 5464 tools_gl2psPrintf(gl2ps,"shape-rendering= 5465 tools_gl2psPrintf(gl2ps,"points=\"%g,%g % 5466 xyz[1][0], xyz[1][1], xyz[2][ 5467 } 5468 else{ 5469 /* subdivide into 4 subtriangles */ 5470 for(i = 0; i < 3; i++){ 5471 xyz2[0][i] = xyz[0][i]; 5472 xyz2[1][i] = 0.5F * (xyz[0][i] + xyz[1] 5473 xyz2[2][i] = 0.5F * (xyz[0][i] + xyz[2] 5474 } 5475 for(i = 0; i < 4; i++){ 5476 rgba2[0][i] = rgba[0][i]; 5477 rgba2[1][i] = 0.5F * (rgba[0][i] + rgba 5478 rgba2[2][i] = 0.5F * (rgba[0][i] + rgba 5479 } 5480 tools_gl2psPrintSVGSmoothTriangle(gl2ps, 5481 for(i = 0; i < 3; i++){ 5482 xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[1] 5483 xyz2[1][i] = xyz[1][i]; 5484 xyz2[2][i] = 0.5F * (xyz[1][i] + xyz[2] 5485 } 5486 for(i = 0; i < 4; i++){ 5487 rgba2[0][i] = 0.5F * (rgba[0][i] + rgba 5488 rgba2[1][i] = rgba[1][i]; 5489 rgba2[2][i] = 0.5F * (rgba[1][i] + rgba 5490 } 5491 tools_gl2psPrintSVGSmoothTriangle(gl2ps, 5492 for(i = 0; i < 3; i++){ 5493 xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[2] 5494 xyz2[1][i] = xyz[2][i]; 5495 xyz2[2][i] = 0.5F * (xyz[1][i] + xyz[2] 5496 } 5497 for(i = 0; i < 4; i++){ 5498 rgba2[0][i] = 0.5F * (rgba[0][i] + rgba 5499 rgba2[1][i] = rgba[2][i]; 5500 rgba2[2][i] = 0.5F * (rgba[1][i] + rgba 5501 } 5502 tools_gl2psPrintSVGSmoothTriangle(gl2ps, 5503 for(i = 0; i < 3; i++){ 5504 xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[1] 5505 xyz2[1][i] = 0.5F * (xyz[1][i] + xyz[2] 5506 xyz2[2][i] = 0.5F * (xyz[0][i] + xyz[2] 5507 } 5508 for(i = 0; i < 4; i++){ 5509 rgba2[0][i] = 0.5F * (rgba[0][i] + rgba 5510 rgba2[1][i] = 0.5F * (rgba[1][i] + rgba 5511 rgba2[2][i] = 0.5F * (rgba[0][i] + rgba 5512 } 5513 tools_gl2psPrintSVGSmoothTriangle(gl2ps, 5514 } 5515 } 5516 5517 inline void tools_gl2psPrintSVGDash(tools_GL2 5518 { 5519 int i, n, array[10]; 5520 5521 if(!pattern || !factor) return; /* solid li 5522 5523 tools_gl2psParseStipplePattern(pattern, fac 5524 tools_gl2psPrintf(gl2ps,"stroke-dasharray=\ 5525 for(i = 0; i < n; i++){ 5526 if(i) tools_gl2psPrintf(gl2ps,","); 5527 tools_gl2psPrintf(gl2ps,"%d", array[i]); 5528 } 5529 tools_gl2psPrintf(gl2ps,"\" "); 5530 } 5531 5532 inline void tools_gl2psEndSVGLine(tools_GL2PS 5533 { 5534 int i; 5535 if(gl2ps->lastvertex.rgba[0] >= 0.){ 5536 tools_gl2psPrintf(gl2ps,"%g,%g\"/>\n", gl 5537 gl2ps->viewport[3] - gl2ps->l 5538 for(i = 0; i < 3; i++) 5539 gl2ps->lastvertex.xyz[i] = -1.; 5540 for(i = 0; i < 4; i++) 5541 gl2ps->lastvertex.rgba[i] = -1.; 5542 } 5543 } 5544 5545 inline void tools_gl2psPrintSVGPixmap(tools_G 5546 { 5547 #if defined(TOOLS_GL2PS_HAVE_LIBPNG) 5548 tools_GL2PSlist *png; 5549 unsigned char c; 5550 int i; 5551 5552 /* The only image types supported by the SV 5553 and SVG. Here we choose PNG, and since w 5554 directly in the SVG stream (and not link 5555 file), we need to encode the pixmap into 5556 encode it into base64. */ 5557 5558 png = tools_gl2psListCreate(pixmap->width * 5559 sizeof(unsigned char) 5560 tools_gl2psConvertPixmapToPNG(pixmap, png); 5561 tools_gl2psListEncodeBase64(png); 5562 5563 /* Use "transform" attribute to scale and t 5564 the coordinates origin (0,0) */ 5565 y -= pixmap->zoom_y * (tools_GLfloat)pixmap 5566 tools_gl2psPrintf(gl2ps,"<image x=\"%g\" y= 5567 0., 0., pixmap->width, pixmap-> 5568 tools_gl2psPrintf(gl2ps,"transform=\"matrix 5569 pixmap->zoom_x, pixmap->zoom_y, 5570 tools_gl2psPrintf(gl2ps,"xlink:href=\"data: 5571 for(i = 0; i < tools_gl2psListNbr(png); i++ 5572 tools_gl2psListRead(png, i, &c); 5573 tools_gl2psPrintf(gl2ps,"%c", c); 5574 } 5575 tools_gl2psPrintf(gl2ps,"\"/>\n"); 5576 tools_gl2psListDelete(png); 5577 #else 5578 (void) x; (void) y; (void) pixmap; /* not 5579 tools_gl2psMsg(TOOLS_GL2PS_WARNING, "GL2PS 5580 "order to embed images in SVG stre 5581 #endif 5582 (void)gl2ps; 5583 } 5584 5585 inline void tools_gl2psPrintSVGPrimitive(tool 5586 { 5587 tools_GL2PSprimitive *prim; 5588 tools_GL2PSxyz xyz[4]; 5589 tools_GL2PSrgba rgba[4]; 5590 char col[32]; 5591 char lcap[7], ljoin[7]; 5592 int newline; 5593 5594 prim = *(tools_GL2PSprimitive**)data; 5595 5596 if((gl2ps->options & TOOLS_GL2PS_OCCLUSION_ 5597 5598 /* We try to draw connected lines as a sing 5599 joins and correct stippling. So if the p 5600 a line we must first finish the current 5601 if(prim->type != TOOLS_GL2PS_LINE) tools_gl 5602 5603 tools_gl2psSVGGetCoordsAndColors(gl2ps, pri 5604 5605 switch(prim->type){ 5606 case TOOLS_GL2PS_POINT : 5607 tools_gl2psSVGGetColorString(rgba[0], col 5608 tools_gl2psPrintf(gl2ps,"<circle fill=\"% 5609 if(rgba[0][3] < 1.0F) tools_gl2psPrintf(g 5610 tools_gl2psPrintf(gl2ps,"cx=\"%g\" cy=\"% 5611 xyz[0][0], xyz[0][1], 0.5 * p 5612 break; 5613 case TOOLS_GL2PS_LINE : 5614 if(!tools_gl2psSamePosition(gl2ps->lastve 5615 !tools_gl2psSameColor(gl2ps->lastrgba, 5616 gl2ps->lastlinewidth != prim->width || 5617 gl2ps->lastlinecap != prim->linecap || 5618 gl2ps->lastlinejoin != prim->linejoin 5619 gl2ps->lastpattern != prim->pattern || 5620 gl2ps->lastfactor != prim->factor){ 5621 /* End the current line if the new segm 5622 the last one ended, or if the color, 5623 stippling have changed (we will need 5624 gradients for smooth-shaded lines) * 5625 tools_gl2psEndSVGLine(gl2ps); 5626 newline = 1; 5627 } 5628 else{ 5629 newline = 0; 5630 } 5631 gl2ps->lastvertex = prim->verts[1]; 5632 tools_gl2psSetLastColor(gl2ps, prim->vert 5633 gl2ps->lastlinewidth = prim->width; 5634 gl2ps->lastlinecap = prim->linecap; 5635 gl2ps->lastlinejoin = prim->linejoin; 5636 gl2ps->lastpattern = prim->pattern; 5637 gl2ps->lastfactor = prim->factor; 5638 if(newline){ 5639 tools_gl2psSVGGetColorString(rgba[0], c 5640 tools_gl2psPrintf(gl2ps,"<polyline fill 5641 col, prim->width); 5642 switch (prim->linecap){ 5643 case TOOLS_GL2PS_LINE_CAP_BUTT: 5644 //sprintf (lcap, "%s", "butt"); //G.Ba 5645 strcpy (lcap, "butt"); //G.Ba 5646 break; 5647 case TOOLS_GL2PS_LINE_CAP_ROUND: 5648 //sprintf (lcap, "%s", "round"); //G.Ba 5649 strcpy (lcap, "round"); //G.Ba 5650 break; 5651 case TOOLS_GL2PS_LINE_CAP_SQUARE: 5652 //sprintf (lcap, "%s", "square"); //G.B 5653 strcpy (lcap, "square"); //G.B 5654 break; 5655 default: /*G.Barrand : to quiet Coverit 5656 //sprintf (lcap, "%s", "butt"); //G.B 5657 strcpy (lcap, "butt"); //G.B 5658 break; 5659 } 5660 switch (prim->linejoin){ 5661 case TOOLS_GL2PS_LINE_JOIN_MITER: 5662 //sprintf (ljoin, "%s", "miter"); //G. 5663 strcpy (ljoin, "miter"); //G. 5664 break; 5665 case TOOLS_GL2PS_LINE_JOIN_ROUND: 5666 //sprintf (ljoin, "%s", "round"); //G. 5667 strcpy (ljoin, "round"); //G. 5668 break; 5669 case TOOLS_GL2PS_LINE_JOIN_BEVEL: 5670 //sprintf (ljoin, "%s", "bevel"); //G. 5671 strcpy (ljoin, "bevel"); //G. 5672 break; 5673 default: /*G.Barrand : to quiet Coverit 5674 //sprintf (ljoin, "%s", "miter"); //G. 5675 strcpy (ljoin, "miter"); //G. 5676 break; 5677 } 5678 tools_gl2psPrintf(gl2ps,"stroke-linecap 5679 lcap, ljoin); 5680 if(rgba[0][3] < 1.0F) tools_gl2psPrintf 5681 tools_gl2psPrintSVGDash(gl2ps, prim->pa 5682 tools_gl2psPrintf(gl2ps,"points=\"%g,%g 5683 } 5684 else{ 5685 tools_gl2psPrintf(gl2ps,"%g,%g ", xyz[0 5686 } 5687 break; 5688 case TOOLS_GL2PS_TRIANGLE : 5689 tools_gl2psPrintSVGSmoothTriangle(gl2ps, 5690 break; 5691 case TOOLS_GL2PS_QUADRANGLE : 5692 tools_gl2psMsg(TOOLS_GL2PS_WARNING, "Ther 5693 break; 5694 case TOOLS_GL2PS_PIXMAP : 5695 tools_gl2psPrintSVGPixmap(gl2ps,xyz[0][0] 5696 break; 5697 case TOOLS_GL2PS_TEXT : 5698 tools_gl2psSVGGetColorString(prim->verts[ 5699 tools_gl2psPrintf(gl2ps,"<text fill=\"%s\ 5700 col, xyz[0][0], xyz[0][1], pr 5701 if(prim->data.text->angle) 5702 tools_gl2psPrintf(gl2ps,"transform=\"ro 5703 -prim->data.text->angle, xy 5704 switch(prim->data.text->alignment){ 5705 case TOOLS_GL2PS_TEXT_C: 5706 tools_gl2psPrintf(gl2ps,"text-anchor=\" 5707 prim->data.text->fontsize / 5708 break; 5709 case TOOLS_GL2PS_TEXT_CL: 5710 tools_gl2psPrintf(gl2ps,"text-anchor=\" 5711 prim->data.text->fontsize / 5712 break; 5713 case TOOLS_GL2PS_TEXT_CR: 5714 tools_gl2psPrintf(gl2ps,"text-anchor=\" 5715 prim->data.text->fontsize / 5716 break; 5717 case TOOLS_GL2PS_TEXT_B: 5718 tools_gl2psPrintf(gl2ps,"text-anchor=\" 5719 break; 5720 case TOOLS_GL2PS_TEXT_BR: 5721 tools_gl2psPrintf(gl2ps,"text-anchor=\" 5722 break; 5723 case TOOLS_GL2PS_TEXT_T: 5724 tools_gl2psPrintf(gl2ps,"text-anchor=\" 5725 prim->data.text->fontsize); 5726 break; 5727 case TOOLS_GL2PS_TEXT_TL: 5728 tools_gl2psPrintf(gl2ps,"text-anchor=\" 5729 prim->data.text->fontsize); 5730 break; 5731 case TOOLS_GL2PS_TEXT_TR: 5732 tools_gl2psPrintf(gl2ps,"text-anchor=\" 5733 prim->data.text->fontsize); 5734 break; 5735 case TOOLS_GL2PS_TEXT_BL: 5736 default: /* same as TOOLS_GL2PS_TEXT_BL * 5737 tools_gl2psPrintf(gl2ps,"text-anchor=\" 5738 break; 5739 } 5740 if(!strcmp(prim->data.text->fontname, "Ti 5741 tools_gl2psPrintf(gl2ps,"font-family=\" 5742 else if(!strcmp(prim->data.text->fontname 5743 tools_gl2psPrintf(gl2ps,"font-family=\" 5744 else if(!strcmp(prim->data.text->fontname 5745 tools_gl2psPrintf(gl2ps,"font-family=\" 5746 else if(!strcmp(prim->data.text->fontname 5747 tools_gl2psPrintf(gl2ps,"font-family=\" 5748 else if(!strcmp(prim->data.text->fontname 5749 tools_gl2psPrintf(gl2ps,"font-family=\" 5750 else if(!strcmp(prim->data.text->fontname 5751 tools_gl2psPrintf(gl2ps,"font-family=\" 5752 else if(!strcmp(prim->data.text->fontname 5753 tools_gl2psPrintf(gl2ps,"font-family=\" 5754 else if(!strcmp(prim->data.text->fontname 5755 tools_gl2psPrintf(gl2ps,"font-family=\" 5756 else if(!strcmp(prim->data.text->fontname 5757 tools_gl2psPrintf(gl2ps,"font-family=\" 5758 else if(!strcmp(prim->data.text->fontname 5759 tools_gl2psPrintf(gl2ps,"font-family=\" 5760 else 5761 tools_gl2psPrintf(gl2ps,"font-family=\" 5762 tools_gl2psPrintf(gl2ps,"%s</text>\n", pr 5763 break; 5764 case TOOLS_GL2PS_SPECIAL : 5765 /* alignment contains the format for whic 5766 is intended */ 5767 if(prim->data.text->alignment == TOOLS_GL 5768 tools_gl2psPrintf(gl2ps,"%s\n", prim->d 5769 break; 5770 default : 5771 break; 5772 } 5773 } 5774 5775 inline void tools_gl2psPrintSVGFooter(tools_G 5776 { 5777 tools_gl2psPrintf(gl2ps,"</g>\n"); 5778 tools_gl2psPrintf(gl2ps,"</svg>\n"); 5779 5780 tools_gl2psPrintGzipFooter(gl2ps); 5781 } 5782 5783 inline void tools_gl2psPrintSVGBeginViewport( 5784 { 5785 tools_GLint idx; 5786 char col[32]; 5787 tools_GLfloat rgba[4]; 5788 int x = viewport[0], y = viewport[1], w = v 5789 5790 tools_glRenderMode(TOOLS_GL_FEEDBACK); 5791 5792 tools_gl2psResetLineProperties(gl2ps); 5793 5794 if(gl2ps->header){ 5795 tools_gl2psPrintSVGHeader(gl2ps); 5796 gl2ps->header = TOOLS_GL_FALSE; 5797 } 5798 5799 if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR 5800 if(gl2ps->colormode == TOOLS_GL_RGBA || g 5801 tools_glGetFloatv(TOOLS_GL_COLOR_CLEAR_ 5802 } 5803 else{ 5804 tools_glGetIntegerv(TOOLS_GL_INDEX_CLEA 5805 rgba[0] = gl2ps->colormap[idx][0]; 5806 rgba[1] = gl2ps->colormap[idx][1]; 5807 rgba[2] = gl2ps->colormap[idx][2]; 5808 rgba[3] = 1.0F; 5809 } 5810 tools_gl2psSVGGetColorString(rgba, col); 5811 tools_gl2psPrintf(gl2ps,"<polygon fill=\" 5812 x, gl2ps->viewport[3] - y, 5813 x + w, gl2ps->viewport[3] - y 5814 x + w, gl2ps->viewport[3] - ( 5815 x, gl2ps->viewport[3] - (y + 5816 tools_gl2psPrintf(gl2ps,"shape-rendering= 5817 } 5818 5819 tools_gl2psPrintf(gl2ps,"<clipPath id=\"cp% 5820 tools_gl2psPrintf(gl2ps," <polygon points= 5821 x, gl2ps->viewport[3] - y, 5822 x + w, gl2ps->viewport[3] - y, 5823 x + w, gl2ps->viewport[3] - (y 5824 x, gl2ps->viewport[3] - (y + h) 5825 tools_gl2psPrintf(gl2ps,"</clipPath>\n"); 5826 tools_gl2psPrintf(gl2ps,"<g clip-path=\"url 5827 } 5828 5829 inline tools_GLint tools_gl2psPrintSVGEndView 5830 { 5831 tools_GLint res; 5832 5833 res = tools_gl2psPrintPrimitives(gl2ps); 5834 tools_gl2psPrintf(gl2ps,"</g>\n"); 5835 return res; 5836 } 5837 5838 inline void tools_gl2psPrintSVGFinalPrimitive 5839 { 5840 /* End any remaining line, if any */ 5841 tools_gl2psEndSVGLine(gl2ps); 5842 } 5843 5844 /* definition of the SVG backend */ 5845 5846 static const tools_GL2PSbackend tools_gl2psSV 5847 tools_gl2psPrintSVGHeader, 5848 tools_gl2psPrintSVGFooter, 5849 tools_gl2psPrintSVGBeginViewport, 5850 tools_gl2psPrintSVGEndViewport, 5851 tools_gl2psPrintSVGPrimitive, 5852 tools_gl2psPrintSVGFinalPrimitive, 5853 "svg", 5854 "Scalable Vector Graphics" 5855 }; 5856 5857 /******************************************** 5858 * 5859 * PGF routines 5860 * 5861 ******************************************** 5862 5863 inline void tools_gl2psPrintPGFColor(tools_GL 5864 { 5865 if(!tools_gl2psSameColor(gl2ps->lastrgba, r 5866 tools_gl2psSetLastColor(gl2ps, rgba); 5867 fprintf(gl2ps->stream, "\\color[rgb]{%f,% 5868 } 5869 } 5870 5871 inline void tools_gl2psPrintPGFHeader(tools_G 5872 { 5873 time_t now; 5874 5875 time(&now); 5876 5877 fprintf(gl2ps->stream, 5878 "%% Title: %s\n" 5879 "%% Creator: GL2PS %d.%d.%d%s, %s\n 5880 "%% For: %s\n" 5881 "%% CreationDate: %s", 5882 gl2ps->title, TOOLS_GL2PS_MAJOR_VER 5883 TOOLS_GL2PS_PATCH_VERSION, TOOLS_GL 5884 gl2ps->producer, ctime(&now)); 5885 5886 fprintf(gl2ps->stream, "\\begin{pgfpicture} 5887 if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR 5888 tools_gl2psPrintPGFColor(gl2ps, gl2ps->bg 5889 fprintf(gl2ps->stream, 5890 "\\pgfpathrectanglecorners{" 5891 "\\pgfpoint{%dpt}{%dpt}}{\\pgfpoi 5892 "\\pgfusepath{fill}\n", 5893 (int)gl2ps->viewport[0], (int)gl2 5894 (int)gl2ps->viewport[2], (int)gl2 5895 } 5896 } 5897 5898 inline void tools_gl2psPrintPGFDash(tools_GL2 5899 { 5900 int i, n, array[10]; 5901 5902 if(pattern == gl2ps->lastpattern && factor 5903 return; 5904 5905 gl2ps->lastpattern = pattern; 5906 gl2ps->lastfactor = factor; 5907 5908 if(!pattern || !factor){ 5909 /* solid line */ 5910 fprintf(gl2ps->stream, "\\pgfsetdash{}{0p 5911 } 5912 else{ 5913 tools_gl2psParseStipplePattern(pattern, f 5914 fprintf(gl2ps->stream, "\\pgfsetdash{"); 5915 for(i = 0; i < n; i++) fprintf(gl2ps->str 5916 fprintf(gl2ps->stream, "}{0pt}\n"); 5917 } 5918 } 5919 5920 inline const char *tools_gl2psPGFTextAlignmen 5921 { 5922 switch(align){ 5923 case TOOLS_GL2PS_TEXT_C : return "center"; 5924 case TOOLS_GL2PS_TEXT_CL : return "west"; 5925 case TOOLS_GL2PS_TEXT_CR : return "east"; 5926 case TOOLS_GL2PS_TEXT_B : return "south"; 5927 case TOOLS_GL2PS_TEXT_BR : return "south ea 5928 case TOOLS_GL2PS_TEXT_T : return "north"; 5929 case TOOLS_GL2PS_TEXT_TL : return "north we 5930 case TOOLS_GL2PS_TEXT_TR : return "north ea 5931 case TOOLS_GL2PS_TEXT_BL : 5932 default : return "south west"; 5933 } 5934 } 5935 5936 inline void tools_gl2psPrintPGFPrimitive(tool 5937 { 5938 tools_GL2PSprimitive *prim; 5939 5940 prim = *(tools_GL2PSprimitive**)data; 5941 5942 switch(prim->type){ 5943 case TOOLS_GL2PS_POINT : 5944 /* Points in openGL are rectangular */ 5945 tools_gl2psPrintPGFColor(gl2ps, prim->ver 5946 fprintf(gl2ps->stream, 5947 "\\pgfpathrectangle{\\pgfpoint{%f 5948 "{\\pgfpoint{%fpt}{%fpt}}\n\\pgfu 5949 prim->verts[0].xyz[0]-0.5*prim->w 5950 prim->verts[0].xyz[1]-0.5*prim->w 5951 prim->width,prim->width); 5952 break; 5953 case TOOLS_GL2PS_LINE : 5954 tools_gl2psPrintPGFColor(gl2ps, prim->ver 5955 if(gl2ps->lastlinewidth != prim->width){ 5956 gl2ps->lastlinewidth = prim->width; 5957 fprintf(gl2ps->stream, "\\pgfsetlinewid 5958 } 5959 if(gl2ps->lastlinecap != prim->linecap){ 5960 gl2ps->lastlinecap = prim->linecap; 5961 switch (prim->linecap){ 5962 case TOOLS_GL2PS_LINE_CAP_BUTT: 5963 fprintf(gl2ps->stream, "\\pgfset%s\n" 5964 break; 5965 case TOOLS_GL2PS_LINE_CAP_ROUND: 5966 fprintf(gl2ps->stream, "\\pgfset%s\n" 5967 break; 5968 case TOOLS_GL2PS_LINE_CAP_SQUARE: 5969 fprintf(gl2ps->stream, "\\pgfset%s\n" 5970 break; 5971 } 5972 } 5973 if(gl2ps->lastlinejoin != prim->linejoin) 5974 gl2ps->lastlinejoin = prim->linejoin; 5975 switch (prim->linejoin){ 5976 case TOOLS_GL2PS_LINE_JOIN_MITER: 5977 fprintf(gl2ps->stream, "\\pgfset%s\n" 5978 break; 5979 case TOOLS_GL2PS_LINE_JOIN_ROUND: 5980 fprintf(gl2ps->stream, "\\pgfset%s\n" 5981 break; 5982 case TOOLS_GL2PS_LINE_JOIN_BEVEL: 5983 fprintf(gl2ps->stream, "\\pgfset%s\n" 5984 break; 5985 } 5986 } 5987 tools_gl2psPrintPGFDash(gl2ps, prim->patt 5988 fprintf(gl2ps->stream, 5989 "\\pgfpathmoveto{\\pgfpoint{%fpt} 5990 "\\pgflineto{\\pgfpoint{%fpt}{%fp 5991 "\\pgfusepath{stroke}\n", 5992 prim->verts[1].xyz[0], prim->vert 5993 prim->verts[0].xyz[0], prim->vert 5994 break; 5995 case TOOLS_GL2PS_TRIANGLE : 5996 if(gl2ps->lastlinewidth != 0){ 5997 gl2ps->lastlinewidth = 0; 5998 fprintf(gl2ps->stream, "\\pgfsetlinewid 5999 } 6000 if(gl2ps->lastlinecap != prim->linecap){ 6001 gl2ps->lastlinecap = prim->linecap; 6002 switch (prim->linecap){ 6003 case TOOLS_GL2PS_LINE_CAP_BUTT: 6004 fprintf(gl2ps->stream, "\\pgfset%s\n" 6005 break; 6006 case TOOLS_GL2PS_LINE_CAP_ROUND: 6007 fprintf(gl2ps->stream, "\\pgfset%s\n" 6008 break; 6009 case TOOLS_GL2PS_LINE_CAP_SQUARE: 6010 fprintf(gl2ps->stream, "\\pgfset%s\n" 6011 break; 6012 } 6013 } 6014 if(gl2ps->lastlinejoin != prim->linejoin) 6015 gl2ps->lastlinejoin = prim->linejoin; 6016 switch (prim->linejoin){ 6017 case TOOLS_GL2PS_LINE_JOIN_MITER: 6018 fprintf(gl2ps->stream, "\\pgfset%s\n" 6019 break; 6020 case TOOLS_GL2PS_LINE_JOIN_ROUND: 6021 fprintf(gl2ps->stream, "\\pgfset%s\n" 6022 break; 6023 case TOOLS_GL2PS_LINE_JOIN_BEVEL: 6024 fprintf(gl2ps->stream, "\\pgfset%s\n" 6025 break; 6026 } 6027 } 6028 tools_gl2psPrintPGFColor(gl2ps, prim->ver 6029 fprintf(gl2ps->stream, 6030 "\\pgfpathmoveto{\\pgfpoint{%fpt} 6031 "\\pgflineto{\\pgfpoint{%fpt}{%fp 6032 "\\pgflineto{\\pgfpoint{%fpt}{%fp 6033 "\\pgfpathclose\n" 6034 "\\pgfusepath{fill,stroke}\n", 6035 prim->verts[2].xyz[0], prim->vert 6036 prim->verts[1].xyz[0], prim->vert 6037 prim->verts[0].xyz[0], prim->vert 6038 break; 6039 case TOOLS_GL2PS_TEXT : 6040 fprintf(gl2ps->stream, "{\n\\pgftransform 6041 prim->verts[0].xyz[0], prim->vert 6042 6043 if(prim->data.text->angle) 6044 fprintf(gl2ps->stream, "\\pgftransformr 6045 6046 fprintf(gl2ps->stream, "\\pgfnode{rectang 6047 tools_gl2psPGFTextAlignment(prim- 6048 prim->data.text->fontsize); 6049 6050 fprintf(gl2ps->stream, "\\textcolor[rgb]{ 6051 prim->verts[0].rgba[0], prim->ver 6052 prim->verts[0].rgba[2], prim->dat 6053 6054 fprintf(gl2ps->stream, "}{}{\\pgfusepath{ 6055 6056 if(prim->data.text->angle) 6057 fprintf(gl2ps->stream, "}"); 6058 6059 fprintf(gl2ps->stream, "\n}\n"); 6060 break; 6061 case TOOLS_GL2PS_SPECIAL : 6062 /* alignment contains the format for whic 6063 is intended */ 6064 if (prim->data.text->alignment == TOOLS_G 6065 fprintf(gl2ps->stream, "%s\n", prim->da 6066 break; 6067 default : 6068 break; 6069 } 6070 } 6071 6072 inline void tools_gl2psPrintPGFFooter(tools_G 6073 { 6074 fprintf(gl2ps->stream, "\\end{pgfpicture}\n 6075 } 6076 6077 inline void tools_gl2psPrintPGFBeginViewport( 6078 { 6079 tools_GLint idx; 6080 tools_GLfloat rgba[4]; 6081 int x = viewport[0], y = viewport[1], w = v 6082 6083 tools_glRenderMode(TOOLS_GL_FEEDBACK); 6084 6085 tools_gl2psResetLineProperties(gl2ps); 6086 6087 if(gl2ps->header){ 6088 tools_gl2psPrintPGFHeader(gl2ps); 6089 gl2ps->header = TOOLS_GL_FALSE; 6090 } 6091 6092 fprintf(gl2ps->stream, "\\begin{pgfscope}\n 6093 if(gl2ps->options & TOOLS_GL2PS_DRAW_BACKGR 6094 if(gl2ps->colormode == TOOLS_GL_RGBA || g 6095 tools_glGetFloatv(TOOLS_GL_COLOR_CLEAR_ 6096 } 6097 else{ 6098 tools_glGetIntegerv(TOOLS_GL_INDEX_CLEA 6099 rgba[0] = gl2ps->colormap[idx][0]; 6100 rgba[1] = gl2ps->colormap[idx][1]; 6101 rgba[2] = gl2ps->colormap[idx][2]; 6102 rgba[3] = 1.0F; 6103 } 6104 tools_gl2psPrintPGFColor(gl2ps, rgba); 6105 fprintf(gl2ps->stream, 6106 "\\pgfpathrectangle{\\pgfpoint{%d 6107 "{\\pgfpoint{%dpt}{%dpt}}\n" 6108 "\\pgfusepath{fill}\n", 6109 x, y, w, h); 6110 } 6111 6112 fprintf(gl2ps->stream, 6113 "\\pgfpathrectangle{\\pgfpoint{%dpt 6114 "{\\pgfpoint{%dpt}{%dpt}}\n" 6115 "\\pgfusepath{clip}\n", 6116 x, y, w, h); 6117 } 6118 6119 inline tools_GLint tools_gl2psPrintPGFEndView 6120 { 6121 tools_GLint res; 6122 res = tools_gl2psPrintPrimitives(gl2ps); 6123 fprintf(gl2ps->stream, "\\end{pgfscope}\n") 6124 return res; 6125 } 6126 6127 inline void tools_gl2psPrintPGFFinalPrimitive 6128 { 6129 } 6130 6131 /* definition of the PGF backend */ 6132 6133 static const tools_GL2PSbackend tools_gl2psPG 6134 tools_gl2psPrintPGFHeader, 6135 tools_gl2psPrintPGFFooter, 6136 tools_gl2psPrintPGFBeginViewport, 6137 tools_gl2psPrintPGFEndViewport, 6138 tools_gl2psPrintPGFPrimitive, 6139 tools_gl2psPrintPGFFinalPrimitive, 6140 "tex", 6141 "PGF Latex Graphics" 6142 }; 6143 6144 /******************************************** 6145 * 6146 * General primitive printing routine 6147 * 6148 ******************************************** 6149 6150 /* Warning: the ordering of the backends must 6151 #defines in gl2ps.h */ 6152 6153 static const tools_GL2PSbackend *tools_gl2psb 6154 &tools_gl2psPS, /* 0 */ 6155 &tools_gl2psEPS, /* 1 */ 6156 &tools_gl2psTEX, /* 2 */ 6157 &tools_gl2psPDF, /* 3 */ 6158 &tools_gl2psSVG, /* 4 */ 6159 &tools_gl2psPGF /* 5 */ 6160 }; 6161 6162 inline void tools_gl2psComputeTightBoundingBo 6163 { 6164 tools_GL2PSprimitive *prim; 6165 int i; 6166 6167 prim = *(tools_GL2PSprimitive**)data; 6168 6169 for(i = 0; i < prim->numverts; i++){ 6170 if(prim->verts[i].xyz[0] < gl2ps->viewpor 6171 gl2ps->viewport[0] = (tools_GLint)prim- 6172 if(prim->verts[i].xyz[0] > gl2ps->viewpor 6173 gl2ps->viewport[2] = (tools_GLint)(prim 6174 if(prim->verts[i].xyz[1] < gl2ps->viewpor 6175 gl2ps->viewport[1] = (tools_GLint)prim- 6176 if(prim->verts[i].xyz[1] > gl2ps->viewpor 6177 gl2ps->viewport[3] = (tools_GLint)(prim 6178 } 6179 } 6180 6181 inline tools_GLint tools_gl2psPrintPrimitives 6182 { 6183 tools_GL2PSbsptree *root; 6184 tools_GL2PSxyz eye = {0.0F, 0.0F, 100.0F * 6185 tools_GLint used = 0; 6186 6187 if ((gl2ps->options & TOOLS_GL2PS_NO_OPENGL 6188 used = tools_glRenderMode(TOOLS_GL_RENDER 6189 } 6190 6191 if(used < 0){ 6192 tools_gl2psMsg(TOOLS_GL2PS_INFO, "OpenGL 6193 return TOOLS_GL2PS_OVERFLOW; 6194 } 6195 6196 if(used > 0) 6197 tools_gl2psParseFeedbackBuffer(gl2ps, use 6198 6199 tools_gl2psRescaleAndOffset(gl2ps); 6200 6201 if(gl2ps->header){ 6202 if(tools_gl2psListNbr(gl2ps->primitives) 6203 (gl2ps->options & TOOLS_GL2PS_TIGHT_BO 6204 gl2ps->viewport[0] = gl2ps->viewport[1] 6205 gl2ps->viewport[2] = gl2ps->viewport[3] 6206 tools_gl2psListActionContext(gl2ps, gl2 6207 } 6208 (tools_gl2psbackends[gl2ps->format]->prin 6209 gl2ps->header = TOOLS_GL_FALSE; 6210 } 6211 6212 if(!tools_gl2psListNbr(gl2ps->primitives)){ 6213 /* empty feedback buffer and/or nothing e 6214 return TOOLS_GL2PS_NO_FEEDBACK; 6215 } 6216 6217 switch(gl2ps->sort){ 6218 case TOOLS_GL2PS_NO_SORT : 6219 tools_gl2psListActionContext(gl2ps, gl2ps 6220 tools_gl2psListAction(gl2ps->primitives, 6221 /* reset the primitive list, waiting for 6222 tools_gl2psListReset(gl2ps->primitives); 6223 break; 6224 case TOOLS_GL2PS_SIMPLE_SORT : 6225 tools_gl2psListAssignSortIds(gl2ps->primi 6226 tools_gl2psListSort(gl2ps, gl2ps->primiti 6227 if(gl2ps->options & TOOLS_GL2PS_OCCLUSION 6228 tools_gl2psListActionInverseContext(gl2 6229 tools_gl2psFreeBspImageTree(&gl2ps->ima 6230 } 6231 tools_gl2psListActionContext(gl2ps, gl2ps 6232 tools_gl2psListAction(gl2ps->primitives, 6233 /* reset the primitive list, waiting for 6234 tools_gl2psListReset(gl2ps->primitives); 6235 break; 6236 case TOOLS_GL2PS_BSP_SORT : 6237 root = (tools_GL2PSbsptree*)tools_gl2psMa 6238 tools_gl2psBuildBspTree(gl2ps, root, gl2p 6239 if(TOOLS_GL_TRUE == gl2ps->boundary) tool 6240 if(gl2ps->options & TOOLS_GL2PS_OCCLUSION 6241 tools_gl2psTraverseBspTree(gl2ps, root, 6242 tools_gl2psAddInIm 6243 tools_gl2psFreeBspImageTree(&gl2ps->ima 6244 } 6245 tools_gl2psTraverseBspTree(gl2ps, root, e 6246 tools_gl2psbackends[ 6247 tools_gl2psFreeBspTree(&root); 6248 /* reallocate the primitive list (it's be 6249 tools_gl2psBuildBspTree) in case there 6250 gl2ps->primitives = tools_gl2psListCreate 6251 break; 6252 } 6253 tools_gl2psbackends[gl2ps->format]->printFi 6254 6255 return TOOLS_GL2PS_SUCCESS; 6256 } 6257 6258 inline tools_GLboolean tools_gl2psCheckOption 6259 { 6260 if (options & TOOLS_GL2PS_NO_OPENGL_CONTEXT 6261 if (options & TOOLS_GL2PS_DRAW_BACKGROUND 6262 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Opti 6263 "TOOLS_GL2PS_DRAW 6264 return TOOLS_GL_FALSE; 6265 } 6266 if (options & TOOLS_GL2PS_USE_CURRENT_VIE 6267 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Opti 6268 "TOOLS_GL2PS_USE_ 6269 return TOOLS_GL_FALSE; 6270 } 6271 if ((options & TOOLS_GL2PS_NO_BLENDING) = 6272 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Opti 6273 "option TOOLS_GL2 6274 return TOOLS_GL_FALSE; 6275 } 6276 if (colormode != TOOLS_GL_RGBA) { 6277 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Opti 6278 "to be TOOLS_GL_R 6279 return TOOLS_GL_FALSE; 6280 } 6281 } 6282 6283 return TOOLS_GL_TRUE; 6284 } 6285 6286 /******************************************** 6287 * 6288 * Public routines 6289 * 6290 ******************************************** 6291 6292 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psBeg 6293 tools_GLint 6294 tools_GLint 6295 tools_GLint 6296 tools_GLint 6297 FILE *strea 6298 { 6299 tools_GLint idx; 6300 int i; 6301 6302 /*G.Barrand: if(gl2ps){ 6303 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "tools_ 6304 return TOOLS_GL2PS_ERROR; 6305 } 6306 6307 gl2ps = (tools_GL2PScontext*)tools_gl2psMal 6308 */ 6309 6310 /* Validate options */ 6311 if (tools_gl2psCheckOptions(options, colorm 6312 /*tools_gl2psFree(gl2ps); 6313 gl2ps = NULL;*/ 6314 return TOOLS_GL2PS_ERROR; 6315 } 6316 6317 if(format >= 0 && format < (tools_GLint)(si 6318 gl2ps->format = format; 6319 } 6320 else { 6321 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Unknow 6322 /*tools_gl2psFree(gl2ps); 6323 gl2ps = NULL;*/ 6324 return TOOLS_GL2PS_ERROR; 6325 } 6326 6327 switch(sort){ 6328 case TOOLS_GL2PS_NO_SORT : 6329 case TOOLS_GL2PS_SIMPLE_SORT : 6330 case TOOLS_GL2PS_BSP_SORT : 6331 gl2ps->sort = sort; 6332 break; 6333 default : 6334 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Unknow 6335 /*tools_gl2psFree(gl2ps); 6336 gl2ps = NULL;*/ 6337 return TOOLS_GL2PS_ERROR; 6338 } 6339 6340 if(stream){ 6341 gl2ps->stream = stream; 6342 } 6343 else{ 6344 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Bad fi 6345 /*tools_gl2psFree(gl2ps); 6346 gl2ps = NULL;*/ 6347 return TOOLS_GL2PS_ERROR; 6348 } 6349 6350 gl2ps->header = TOOLS_GL_TRUE; 6351 gl2ps->forcerasterpos = TOOLS_GL_FALSE; 6352 gl2ps->maxbestroot = 10; 6353 gl2ps->options = options; 6354 gl2ps->compress = NULL; 6355 gl2ps->imagemap_head = NULL; 6356 gl2ps->imagemap_tail = NULL; 6357 6358 if(gl2ps->options & TOOLS_GL2PS_USE_CURRENT 6359 tools_glGetIntegerv(TOOLS_GL_VIEWPORT, gl 6360 } 6361 else{ 6362 for(i = 0; i < 4; i++){ 6363 gl2ps->viewport[i] = viewport[i]; 6364 } 6365 } 6366 6367 if(!gl2ps->viewport[2] || !gl2ps->viewport[ 6368 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Incorr 6369 gl2ps->viewport[0], gl2ps->viewp 6370 gl2ps->viewport[2], gl2ps->viewp 6371 /*tools_gl2psFree(gl2ps); 6372 gl2ps = NULL;*/ 6373 return TOOLS_GL2PS_ERROR; 6374 } 6375 6376 gl2ps->threshold[0] = nr ? 1.0F / (tools_GL 6377 gl2ps->threshold[1] = ng ? 1.0F / (tools_GL 6378 gl2ps->threshold[2] = nb ? 1.0F / (tools_GL 6379 gl2ps->colormode = colormode; 6380 gl2ps->buffersize = buffersize > 0 ? buffer 6381 for(i = 0; i < 3; i++){ 6382 gl2ps->lastvertex.xyz[i] = -1.0F; 6383 } 6384 for(i = 0; i < 4; i++){ 6385 gl2ps->lastvertex.rgba[i] = -1.0F; 6386 gl2ps->lastrgba[i] = -1.0F; 6387 } 6388 gl2ps->lastlinewidth = -1.0F; 6389 gl2ps->lastlinecap = 0; 6390 gl2ps->lastlinejoin = 0; 6391 gl2ps->lastpattern = 0; 6392 gl2ps->lastfactor = 0; 6393 gl2ps->imagetree = NULL; 6394 gl2ps->primitivetoadd = NULL; 6395 gl2ps->zerosurfacearea = TOOLS_GL_FALSE; 6396 gl2ps->pdfprimlist = NULL; 6397 gl2ps->pdfgrouplist = NULL; 6398 gl2ps->xreflist = NULL; 6399 6400 /* get default blending mode from current O 6401 default for SVG) */ 6402 if ((gl2ps->options & TOOLS_GL2PS_NO_BLENDI 6403 gl2ps->blending = (gl2ps->format == TOOLS 6404 6405 tools_glGetIntegerv(TOOLS_GL_BLEND_SRC, & 6406 tools_glGetIntegerv(TOOLS_GL_BLEND_DST, & 6407 } 6408 else { 6409 gl2ps->blending = TOOLS_GL_FALSE; 6410 } 6411 6412 if(gl2ps->colormode == TOOLS_GL_RGBA){ 6413 gl2ps->colorsize = 0; 6414 gl2ps->colormap = NULL; 6415 if ((gl2ps->options & TOOLS_GL2PS_NO_OPEN 6416 tools_glGetFloatv(TOOLS_GL_COLOR_CLEAR_ 6417 } 6418 } 6419 else if(gl2ps->colormode == TOOLS_GL_COLOR_ 6420 if(!colorsize || !colormap){ 6421 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Miss 6422 /*tools_gl2psFree(gl2ps); 6423 gl2ps = NULL;*/ 6424 return TOOLS_GL2PS_ERROR; 6425 } 6426 gl2ps->colorsize = colorsize; 6427 gl2ps->colormap = (tools_GL2PSrgba*)tools 6428 memcpy(gl2ps->colormap, colormap, gl2ps-> 6429 tools_glGetIntegerv(TOOLS_GL_INDEX_CLEAR_ 6430 gl2ps->bgcolor[0] = gl2ps->colormap[idx][ 6431 gl2ps->bgcolor[1] = gl2ps->colormap[idx][ 6432 gl2ps->bgcolor[2] = gl2ps->colormap[idx][ 6433 gl2ps->bgcolor[3] = 1.0F; 6434 } 6435 else{ 6436 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Unknow 6437 /*tools_gl2psFree(gl2ps); 6438 gl2ps = NULL;*/ 6439 return TOOLS_GL2PS_ERROR; 6440 } 6441 6442 if(!title){ 6443 gl2ps->title = (char*)tools_gl2psMalloc(s 6444 gl2ps->title[0] = '\0'; 6445 } 6446 else{ 6447 gl2ps->title = (char*)tools_gl2psMalloc(( 6448 strcpy(gl2ps->title, title); 6449 } 6450 6451 if(!producer){ 6452 gl2ps->producer = (char*)tools_gl2psMallo 6453 gl2ps->producer[0] = '\0'; 6454 } 6455 else{ 6456 gl2ps->producer = (char*)tools_gl2psMallo 6457 strcpy(gl2ps->producer, producer); 6458 } 6459 6460 if(!filename){ 6461 gl2ps->filename = (char*)tools_gl2psMallo 6462 gl2ps->filename[0] = '\0'; 6463 } 6464 else{ 6465 gl2ps->filename = (char*)tools_gl2psMallo 6466 strcpy(gl2ps->filename, filename); 6467 } 6468 6469 gl2ps->primitives = tools_gl2psListCreate(5 6470 gl2ps->auxprimitives = tools_gl2psListCreat 6471 6472 if ((gl2ps->options & TOOLS_GL2PS_NO_OPENGL 6473 gl2ps->feedback = (tools_GLfloat*)tools_g 6474 tools_glFeedbackBuffer(gl2ps->buffersize, 6475 tools_glRenderMode(TOOLS_GL_FEEDBACK); 6476 } 6477 else { 6478 gl2ps->feedback = NULL; 6479 gl2ps->buffersize = 0; 6480 } 6481 6482 gl2ps->tex_scaling = 1.; 6483 6484 return TOOLS_GL2PS_SUCCESS; 6485 } 6486 6487 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psEnd 6488 { 6489 tools_GLint res; 6490 6491 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED 6492 6493 res = tools_gl2psPrintPrimitives(gl2ps); 6494 6495 if(res != TOOLS_GL2PS_OVERFLOW) 6496 (tools_gl2psbackends[gl2ps->format]->prin 6497 6498 fflush(gl2ps->stream); 6499 6500 tools_gl2psListDelete(gl2ps->primitives); 6501 tools_gl2psListDelete(gl2ps->auxprimitives) 6502 tools_gl2psFreeImagemap(gl2ps->imagemap_hea 6503 tools_gl2psFree(gl2ps->colormap); 6504 tools_gl2psFree(gl2ps->title); 6505 tools_gl2psFree(gl2ps->producer); 6506 tools_gl2psFree(gl2ps->filename); 6507 tools_gl2psFree(gl2ps->feedback); 6508 /*tools_gl2psFree(gl2ps); 6509 gl2ps = NULL;*/ 6510 6511 return res; 6512 } 6513 6514 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psBeg 6515 { 6516 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED 6517 6518 (tools_gl2psbackends[gl2ps->format]->beginV 6519 6520 return TOOLS_GL2PS_SUCCESS; 6521 } 6522 6523 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psEnd 6524 { 6525 tools_GLint res; 6526 6527 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED 6528 6529 res = (tools_gl2psbackends[gl2ps->format]-> 6530 6531 /* reset last used colors, line widths */ 6532 tools_gl2psResetLineProperties(gl2ps); 6533 6534 return res; 6535 } 6536 6537 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psSor 6538 { 6539 tools_GLint res; 6540 6541 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED 6542 6543 switch(mode){ 6544 case TOOLS_GL2PS_NO_SORT : 6545 case TOOLS_GL2PS_SIMPLE_SORT : 6546 case TOOLS_GL2PS_BSP_SORT : 6547 gl2ps->sort = mode; 6548 res = TOOLS_GL2PS_SUCCESS; 6549 break; 6550 default : 6551 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "Unknow 6552 /*tools_gl2psFree(gl2ps); 6553 gl2ps = NULL;*/ 6554 res = TOOLS_GL2PS_ERROR; 6555 } 6556 6557 return res; 6558 } 6559 6560 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psTex 6561 tools_GL 6562 tools_GL 6563 { 6564 return tools_gl2psAddText(gl2ps, TOOLS_GL2P 6565 color, TOOLS_GL_FALSE, 6566 } 6567 6568 /** 6569 * This version of tools_gl2psTextOptColor is 6570 * fact that PDF does not support text alignm 6571 * (blx, bly) represent the bottom left corne 6572 */ 6573 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psTex 6574 tools_ 6575 tools_ 6576 { 6577 return tools_gl2psAddText(gl2ps, TOOLS_GL2P 6578 color, TOOLS_GL_TRUE, b 6579 } 6580 6581 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psTex 6582 tools_GLshort 6583 { 6584 return tools_gl2psAddText(gl2ps, TOOLS_GL2P 6585 } 6586 6587 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psTex 6588 { 6589 return tools_gl2psAddText(gl2ps, TOOLS_GL2P 6590 NULL, TOOLS_GL_FALSE, 0 6591 } 6592 6593 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psSpe 6594 { 6595 return tools_gl2psAddText(gl2ps, TOOLS_GL2P 6596 } 6597 6598 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psSpe 6599 { 6600 return tools_gl2psAddText(gl2ps, TOOLS_GL2P 6601 } 6602 6603 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psDra 6604 tools_GLin 6605 tools_GLen 6606 const void 6607 { 6608 int size, i; 6609 const tools_GLfloat *piv; 6610 tools_GLfloat pos[4], zoom_x, zoom_y; 6611 tools_GL2PSprimitive *prim; 6612 tools_GLboolean valid; 6613 6614 if(/*!gl2ps ||*/ !pixels) return TOOLS_GL2P 6615 6616 if((width <= 0) || (height <= 0)) return TO 6617 6618 if(gl2ps->options & TOOLS_GL2PS_NO_PIXMAP) 6619 6620 if((format != TOOLS_GL_RGB && format != TOO 6621 tools_gl2psMsg(TOOLS_GL2PS_ERROR, "tools_ 6622 "TOOLS_GL_RGB/TOOLS_GL_RGBA, TOO 6623 return TOOLS_GL2PS_ERROR; 6624 } 6625 6626 if (gl2ps->forcerasterpos) { 6627 pos[0] = gl2ps->rasterpos.xyz[0]; 6628 pos[1] = gl2ps->rasterpos.xyz[1]; 6629 pos[2] = gl2ps->rasterpos.xyz[2]; 6630 pos[3] = 1.f; 6631 /* Hardcode zoom factors (for now?) */ 6632 zoom_x = 1.f; 6633 zoom_y = 1.f; 6634 } 6635 else { 6636 tools_glGetBooleanv(TOOLS_GL_CURRENT_RAST 6637 if(TOOLS_GL_FALSE == valid) return TOOLS_ 6638 tools_glGetFloatv(TOOLS_GL_CURRENT_RASTER 6639 tools_glGetFloatv(TOOLS_GL_ZOOM_X, &zoom_ 6640 tools_glGetFloatv(TOOLS_GL_ZOOM_Y, &zoom_ 6641 } 6642 6643 prim = (tools_GL2PSprimitive*)tools_gl2psMa 6644 prim->type = TOOLS_GL2PS_PIXMAP; 6645 prim->boundary = 0; 6646 prim->numverts = 1; 6647 prim->verts = (tools_GL2PSvertex*)tools_gl2 6648 prim->verts[0].xyz[0] = pos[0] + xorig; 6649 prim->verts[0].xyz[1] = pos[1] + yorig; 6650 prim->verts[0].xyz[2] = pos[2]; 6651 prim->culled = 0; 6652 prim->offset = 0; 6653 prim->ofactor = 0.0; 6654 prim->ounits = 0.0; 6655 prim->pattern = 0; 6656 prim->factor = 0; 6657 prim->width = 1; 6658 if (gl2ps->forcerasterpos) { 6659 prim->verts[0].rgba[0] = gl2ps->rasterpos 6660 prim->verts[0].rgba[1] = gl2ps->rasterpos 6661 prim->verts[0].rgba[2] = gl2ps->rasterpos 6662 prim->verts[0].rgba[3] = gl2ps->rasterpos 6663 } 6664 else { 6665 tools_glGetFloatv(TOOLS_GL_CURRENT_RASTER 6666 } 6667 prim->data.image = (tools_GL2PSimage*)tools 6668 prim->data.image->width = width; 6669 prim->data.image->height = height; 6670 prim->data.image->zoom_x = zoom_x; 6671 prim->data.image->zoom_y = zoom_y; 6672 prim->data.image->format = format; 6673 prim->data.image->type = type; 6674 6675 gl2ps->forcerasterpos = TOOLS_GL_FALSE; 6676 6677 switch(format){ 6678 case TOOLS_GL_RGBA: 6679 if(gl2ps->options & TOOLS_GL2PS_NO_BLENDI 6680 /* special case: blending turned off */ 6681 prim->data.image->format = TOOLS_GL_RGB 6682 size = height * width * 3; 6683 prim->data.image->pixels = (tools_GLflo 6684 piv = (const tools_GLfloat*)pixels; 6685 for(i = 0; i < size; ++i, ++piv){ 6686 prim->data.image->pixels[i] = *piv; 6687 if(!((i + 1) % 3)) 6688 ++piv; 6689 } 6690 } 6691 else{ 6692 size = height * width * 4; 6693 prim->data.image->pixels = (tools_GLflo 6694 memcpy(prim->data.image->pixels, pixels 6695 } 6696 break; 6697 case TOOLS_GL_RGB: 6698 default: 6699 size = height * width * 3; 6700 prim->data.image->pixels = (tools_GLfloat 6701 memcpy(prim->data.image->pixels, pixels, 6702 break; 6703 } 6704 6705 /* If no OpenGL context, just add directly 6706 if ((gl2ps->options & TOOLS_GL2PS_NO_OPENGL 6707 tools_gl2psListAdd(gl2ps->auxprimitives, 6708 tools_glPassThrough(TOOLS_GL2PS_DRAW_PIXE 6709 } 6710 else { 6711 tools_gl2psListAdd(gl2ps->primitives, &pr 6712 } 6713 6714 return TOOLS_GL2PS_SUCCESS; 6715 } 6716 6717 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psDra 6718 const to 6719 const un 6720 int size, i; 6721 int sizeoffloat = sizeof(tools_GLfloat); 6722 6723 if(/*!gl2ps ||*/ !imagemap) return TOOLS_GL 6724 6725 if((width <= 0) || (height <= 0)) return TO 6726 6727 size = height + height * ((width - 1) / 8); 6728 tools_glPassThrough(TOOLS_GL2PS_IMAGEMAP_TO 6729 tools_glBegin(TOOLS_GL_POINTS); 6730 tools_glVertex3f(position[0], position[1],p 6731 tools_glEnd(); 6732 tools_glPassThrough((tools_GLfloat)width); 6733 tools_glPassThrough((tools_GLfloat)height); 6734 for(i = 0; i < size; i += sizeoffloat){ 6735 const float *value = (const float*)imagem 6736 tools_glPassThrough(*value); 6737 imagemap += sizeoffloat; 6738 } 6739 return TOOLS_GL2PS_SUCCESS; 6740 } 6741 6742 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psEna 6743 { 6744 tools_GLint tmp; 6745 tools_GLfloat tmp2; 6746 6747 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED 6748 6749 switch(mode){ 6750 case TOOLS_GL2PS_POLYGON_OFFSET_FILL : 6751 tools_glPassThrough(TOOLS_GL2PS_BEGIN_OFF 6752 tools_glGetFloatv(TOOLS_GL_POLYGON_OFFSET 6753 tools_glPassThrough(tmp2); 6754 tools_glGetFloatv(TOOLS_GL_POLYGON_OFFSET 6755 tools_glPassThrough(tmp2); 6756 break; 6757 case TOOLS_GL2PS_POLYGON_BOUNDARY : 6758 tools_glPassThrough(TOOLS_GL2PS_BEGIN_BOU 6759 break; 6760 case TOOLS_GL2PS_LINE_STIPPLE : 6761 tools_glPassThrough(TOOLS_GL2PS_BEGIN_STI 6762 tools_glGetIntegerv(TOOLS_GL_LINE_STIPPLE 6763 tools_glPassThrough((tools_GLfloat)tmp); 6764 tools_glGetIntegerv(TOOLS_GL_LINE_STIPPLE 6765 tools_glPassThrough((tools_GLfloat)tmp); 6766 break; 6767 case TOOLS_GL2PS_BLEND : 6768 tools_glPassThrough(TOOLS_GL2PS_BEGIN_BLE 6769 break; 6770 default : 6771 tools_gl2psMsg(TOOLS_GL2PS_WARNING, "Unkn 6772 return TOOLS_GL2PS_WARNING; 6773 } 6774 6775 return TOOLS_GL2PS_SUCCESS; 6776 } 6777 6778 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psDis 6779 { 6780 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED 6781 6782 switch(mode){ 6783 case TOOLS_GL2PS_POLYGON_OFFSET_FILL : 6784 tools_glPassThrough(TOOLS_GL2PS_END_OFFSE 6785 break; 6786 case TOOLS_GL2PS_POLYGON_BOUNDARY : 6787 tools_glPassThrough(TOOLS_GL2PS_END_BOUND 6788 break; 6789 case TOOLS_GL2PS_LINE_STIPPLE : 6790 tools_glPassThrough(TOOLS_GL2PS_END_STIPP 6791 break; 6792 case TOOLS_GL2PS_BLEND : 6793 tools_glPassThrough(TOOLS_GL2PS_END_BLEND 6794 break; 6795 default : 6796 tools_gl2psMsg(TOOLS_GL2PS_WARNING, "Unkn 6797 return TOOLS_GL2PS_WARNING; 6798 } 6799 6800 return TOOLS_GL2PS_SUCCESS; 6801 } 6802 6803 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psPoi 6804 { 6805 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED 6806 6807 tools_glPassThrough(TOOLS_GL2PS_POINT_SIZE_ 6808 tools_glPassThrough(value); 6809 6810 return TOOLS_GL2PS_SUCCESS; 6811 } 6812 6813 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psLin 6814 { 6815 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED 6816 6817 tools_glPassThrough(TOOLS_GL2PS_LINE_CAP_TO 6818 tools_glPassThrough(value); 6819 6820 return TOOLS_GL2PS_SUCCESS; 6821 } 6822 6823 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psLin 6824 { 6825 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED 6826 6827 tools_glPassThrough(TOOLS_GL2PS_LINE_JOIN_T 6828 tools_glPassThrough((tools_GLfloat)value); 6829 6830 return TOOLS_GL2PS_SUCCESS; 6831 } 6832 6833 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psLin 6834 { 6835 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED 6836 6837 tools_glPassThrough(TOOLS_GL2PS_LINE_WIDTH_ 6838 tools_glPassThrough(value); 6839 6840 return TOOLS_GL2PS_SUCCESS; 6841 } 6842 6843 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psBle 6844 { 6845 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED 6846 6847 if(TOOLS_GL_FALSE == tools_gl2psSupportedBl 6848 return TOOLS_GL2PS_WARNING; 6849 6850 tools_glPassThrough(TOOLS_GL2PS_SRC_BLEND_T 6851 tools_glPassThrough((tools_GLfloat)sfactor) 6852 tools_glPassThrough(TOOLS_GL2PS_DST_BLEND_T 6853 tools_glPassThrough((tools_GLfloat)dfactor) 6854 6855 return TOOLS_GL2PS_SUCCESS; 6856 } 6857 6858 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psSet 6859 { 6860 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED 6861 6862 if(tools_gl2psCheckOptions(options, gl2ps-> 6863 return TOOLS_GL2PS_ERROR; 6864 } 6865 6866 gl2ps->options = options; 6867 6868 return TOOLS_GL2PS_SUCCESS; 6869 } 6870 6871 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psGet 6872 { 6873 /*if(!gl2ps) { 6874 *options = 0; 6875 return TOOLS_GL2PS_UNINITIALIZED; 6876 }*/ 6877 6878 *options = gl2ps->options; 6879 6880 return TOOLS_GL2PS_SUCCESS; 6881 } 6882 6883 TOOLS_GL2PSDLL_API const char *tools_gl2psGet 6884 { 6885 if(format >= 0 && format < (tools_GLint)(si 6886 return tools_gl2psbackends[format]->file_ 6887 else 6888 return "Unknown format"; 6889 } 6890 6891 TOOLS_GL2PSDLL_API const char *tools_gl2psGet 6892 { 6893 if(format >= 0 && format < (tools_GLint)(si 6894 return tools_gl2psbackends[format]->descr 6895 else 6896 return "Unknown format"; 6897 } 6898 6899 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psGet 6900 { 6901 /*if(!gl2ps) { 6902 return TOOLS_GL2PS_UNINITIALIZED; 6903 }*/ 6904 6905 return gl2ps->format; 6906 } 6907 6908 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psFor 6909 { 6910 6911 /*if(!gl2ps) { 6912 return TOOLS_GL2PS_UNINITIALIZED; 6913 }*/ 6914 6915 gl2ps->forcerasterpos = TOOLS_GL_TRUE; 6916 gl2ps->rasterpos.xyz[0] = vert->xyz[0]; 6917 gl2ps->rasterpos.xyz[1] = vert->xyz[1]; 6918 gl2ps->rasterpos.xyz[2] = vert->xyz[2]; 6919 gl2ps->rasterpos.rgba[0] = vert->rgba[0]; 6920 gl2ps->rasterpos.rgba[1] = vert->rgba[1]; 6921 gl2ps->rasterpos.rgba[2] = vert->rgba[2]; 6922 gl2ps->rasterpos.rgba[3] = vert->rgba[3]; 6923 6924 return TOOLS_GL2PS_SUCCESS; 6925 } 6926 6927 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psSet 6928 { 6929 6930 /*if(!gl2ps) { 6931 return TOOLS_GL2PS_UNINITIALIZED; 6932 }*/ 6933 gl2ps->tex_scaling = scaling; 6934 6935 return TOOLS_GL2PS_SUCCESS; 6936 } 6937 6938 TOOLS_GL2PSDLL_API tools_GLint tools_gl2psSet 6939 { 6940 /*if(!gl2ps) return TOOLS_GL2PS_UNINITIALIZED 6941 6942 gl2ps->bgcolor[0] = a_r; 6943 gl2ps->bgcolor[1] = a_g; 6944 gl2ps->bgcolor[2] = a_b; 6945 gl2ps->bgcolor[3] = 1.0F; 6946 6947 return TOOLS_GL2PS_SUCCESS; 6948 } 6949 6950 #undef TOOLS_GL2PS_EPSILON 6951 #undef TOOLS_GL2PS_ZSCALE 6952 #undef TOOLS_GL2PS_ZOFFSET 6953 #undef TOOLS_GL2PS_ZOFFSET_LARGE 6954 #undef TOOLS_GL2PS_ZERO 6955 #undef TOOLS_GL2PS_COINCIDENT 6956 #undef TOOLS_GL2PS_IN_FRONT_OF 6957 #undef TOOLS_GL2PS_IN_BACK_OF 6958 #undef TOOLS_GL2PS_SPANNING 6959 #undef TOOLS_GL2PS_POINT_COINCIDENT 6960 #undef TOOLS_GL2PS_POINT_INFRONT 6961 #undef TOOLS_GL2PS_POINT_BACK 6962 #undef TOOLS_GL2PS_BEGIN_OFFSET_TOKEN 6963 #undef TOOLS_GL2PS_END_OFFSET_TOKEN 6964 #undef TOOLS_GL2PS_BEGIN_BOUNDARY_TOKEN 6965 #undef TOOLS_GL2PS_END_BOUNDARY_TOKEN 6966 #undef TOOLS_GL2PS_BEGIN_STIPPLE_TOKEN 6967 #undef TOOLS_GL2PS_END_STIPPLE_TOKEN 6968 #undef TOOLS_GL2PS_POINT_SIZE_TOKEN 6969 #undef TOOLS_GL2PS_LINE_CAP_TOKEN 6970 #undef TOOLS_GL2PS_LINE_JOIN_TOKEN 6971 #undef TOOLS_GL2PS_LINE_WIDTH_TOKEN 6972 #undef TOOLS_GL2PS_BEGIN_BLEND_TOKEN 6973 #undef TOOLS_GL2PS_END_BLEND_TOKEN 6974 #undef TOOLS_GL2PS_SRC_BLEND_TOKEN 6975 #undef TOOLS_GL2PS_DST_BLEND_TOKEN 6976 #undef TOOLS_GL2PS_IMAGEMAP_TOKEN 6977 #undef TOOLS_GL2PS_DRAW_PIXELS_TOKEN 6978 #undef TOOLS_GL2PS_TEXT_TOKEN 6979 6980 #endif /*tools_gl2ps*/