26 #ifdef G4VIS_BUILD_OPENGL_DRIVER
27 #define G4VIS_BUILD_OPENGL_GL2PS
29 #ifdef G4VIS_BUILD_OI_DRIVER
30 #define G4VIS_BUILD_OPENGL_GL2PS
33 #ifdef G4VIS_BUILD_OPENGL_GL2PS
74 #include <sys/types.h>
79 #define GL2PS_HAVE_ZLIB
82 #if defined(GL2PS_HAVE_LIBPNG)
95 #define GL2PS_EPSILON 5.0e-3F
96 #define GL2PS_ZSCALE 1000.0F
97 #define GL2PS_ZOFFSET 5.0e-2F
98 #define GL2PS_ZOFFSET_LARGE 20.0F
99 #define GL2PS_ZERO(arg) (std::fabs(arg) < 1.e-20)
103 #define GL2PS_NO_TYPE -1
105 #define GL2PS_POINT 2
107 #define GL2PS_QUADRANGLE 4
108 #define GL2PS_TRIANGLE 5
109 #define GL2PS_PIXMAP 6
110 #define GL2PS_IMAGEMAP 7
111 #define GL2PS_IMAGEMAP_WRITTEN 8
112 #define GL2PS_IMAGEMAP_VISIBLE 9
113 #define GL2PS_SPECIAL 10
117 #define GL2PS_COINCIDENT 1
118 #define GL2PS_IN_FRONT_OF 2
119 #define GL2PS_IN_BACK_OF 3
120 #define GL2PS_SPANNING 4
124 #define GL2PS_POINT_COINCIDENT 0
125 #define GL2PS_POINT_INFRONT 1
126 #define GL2PS_POINT_BACK 2
130 #define GL2PS_BEGIN_OFFSET_TOKEN 1
131 #define GL2PS_END_OFFSET_TOKEN 2
132 #define GL2PS_BEGIN_BOUNDARY_TOKEN 3
133 #define GL2PS_END_BOUNDARY_TOKEN 4
134 #define GL2PS_BEGIN_STIPPLE_TOKEN 5
135 #define GL2PS_END_STIPPLE_TOKEN 6
136 #define GL2PS_POINT_SIZE_TOKEN 7
137 #define GL2PS_LINE_WIDTH_TOKEN 8
138 #define GL2PS_BEGIN_BLEND_TOKEN 9
139 #define GL2PS_END_BLEND_TOKEN 10
140 #define GL2PS_SRC_BLEND_TOKEN 11
141 #define GL2PS_DST_BLEND_TOKEN 12
142 #define GL2PS_IMAGEMAP_TOKEN 13
143 #define GL2PS_DRAW_PIXELS_TOKEN 14
144 #define GL2PS_TEXT_TOKEN 15
151 T_ALPHA_LESS_1 = 1<<3,
153 } GL2PS_TRIANGLE_PROPERTY;
155 typedef GLfloat GL2PSxyz[3];
156 typedef GLfloat GL2PSplane[4];
158 typedef struct _GL2PSbsptree2d GL2PSbsptree2d;
160 struct _GL2PSbsptree2d {
162 GL2PSbsptree2d *front, *back;
166 GLint
nmax, size, incr,
n;
170 typedef struct _GL2PSbsptree GL2PSbsptree;
172 struct _GL2PSbsptree {
174 GL2PSlist *primitives;
175 GL2PSbsptree *front, *back;
184 GL2PSvertex vertex[3];
190 char *str, *fontname;
198 GLsizei
width, height;
206 typedef struct _GL2PSimagemap GL2PSimagemap;
208 struct _GL2PSimagemap {
214 GLshort type, numverts;
216 char boundary, offset, culled;
227 #if defined(GL2PS_HAVE_ZLIB)
228 Bytef *dest, *src, *start;
237 int gsno, fontno, imno, shno, maskshno, trgroupno;
238 int gsobjno, fontobjno, imobjno, shobjno, maskshobjno, trgroupobjno;
243 GLint format,
sort, options, colorsize, colormode, buffersize;
244 char *
title, *producer, *filename;
245 GLboolean boundary, blending;
246 GLfloat *feedback, offset[2], lastlinewidth;
247 GLint viewport[4], blendfunc[2], lastfactor;
248 GL2PSrgba *colormap, lastrgba, threshold, bgcolor;
249 GLushort lastpattern;
250 GL2PSvertex lastvertex;
251 GL2PSlist *primitives, *auxprimitives;
260 GLboolean zerosurfacearea;
261 GL2PSbsptree2d *imagetree;
262 GL2PSprimitive *primitivetoadd;
266 GL2PSlist *pdfprimlist, *pdfgrouplist;
272 int trgroupobjects_stack;
277 GL2PSimagemap *imagemap_head;
278 GL2PSimagemap *imagemap_tail;
284 void (*beginViewport)(GLint viewport[4]);
285 GLint (*endViewport)(
void);
288 const char *file_extension;
289 const char *description;
295 static GL2PScontext *
gl2ps = NULL;
307 static void gl2psMsg(GLint level,
const char *fmt, ...)
313 case GL2PS_INFO : fprintf(stderr,
"GL2PS info: ");
break;
314 case GL2PS_WARNING : fprintf(stderr,
"GL2PS warning: ");
break;
315 case GL2PS_ERROR : fprintf(stderr,
"GL2PS error: ");
break;
318 vfprintf(stderr, fmt, args);
320 fprintf(stderr,
"\n");
329 if(!size)
return NULL;
340 if(!size)
return NULL;
341 ptr = realloc(ptr, size);
358 size_t size =
sizeof(
unsigned long);
359 for(i = 1; i <= bytes; ++i){
360 fputc(0xff & (data >> (size-i) * 8),
gl2ps->stream);
367 #if defined(GL2PS_HAVE_ZLIB)
372 gl2ps->compress->src = NULL;
373 gl2ps->compress->start = NULL;
374 gl2ps->compress->dest = NULL;
375 gl2ps->compress->srcLen = 0;
376 gl2ps->compress->destLen = 0;
385 gl2ps->compress->src = NULL;
386 gl2ps->compress->start = NULL;
387 gl2ps->compress->dest = NULL;
388 gl2ps->compress->srcLen = 0;
389 gl2ps->compress->destLen = 0;
396 if(!
gl2ps->compress || !srcsize)
399 gl2ps->compress->srcLen = srcsize;
400 gl2ps->compress->destLen = (
int)ceil(1.001 *
gl2ps->compress->srcLen + 12);
402 gl2ps->compress->start =
gl2ps->compress->src;
410 if(!
gl2ps->compress || !srcsize)
413 if(srcsize < gl2ps->
compress->srcLen)
414 return gl2ps->compress->start;
416 gl2ps->compress->srcLen = srcsize;
417 gl2ps->compress->destLen = (
int)ceil(1.001 *
gl2ps->compress->srcLen + 12);
419 gl2ps->compress->srcLen);
420 gl2ps->compress->start =
gl2ps->compress->src;
422 gl2ps->compress->destLen);
424 return gl2ps->compress->start;
430 size_t size =
sizeof(
unsigned long);
431 for(i = 1; i <= bytes; ++i){
432 *
gl2ps->compress->src = (
Bytef)(0xff & (data >> (size-i) * 8));
433 ++
gl2ps->compress->src;
443 gl2ps->compress->start,
gl2ps->compress->srcLen);
453 #if defined(GL2PS_HAVE_ZLIB)
454 unsigned int oldsize = 0;
455 static char buf[1000];
458 ret = vsprintf(buf, fmt, args);
460 oldsize =
gl2ps->compress->srcLen;
462 memcpy(
gl2ps->compress->start+oldsize, buf, ret);
468 ret = vfprintf(
gl2ps->stream, fmt, args);
470 #if defined(GL2PS_HAVE_ZLIB)
478 #if defined(GL2PS_HAVE_ZLIB)
479 char tmp[10] = {
'\x1f',
'\x8b',
489 fwrite(tmp, 10, 1,
gl2ps->stream);
496 #if defined(GL2PS_HAVE_ZLIB)
508 if(
gl2ps->compress->dest[1] & (1<<5)){
512 fwrite(
gl2ps->compress->dest+n,
gl2ps->compress->destLen-(n+4),
516 for(n = 0; n < 4; ++
n){
517 tmp[
n] = (char)(crc & 0xff);
520 len =
gl2ps->compress->srcLen;
521 for(n = 4; n < 8; ++
n){
522 tmp[
n] = (char)(len & 0xff);
525 fwrite(tmp, 8, 1,
gl2ps->stream);
529 gl2ps->compress = NULL;
545 list->array = (
char*)
gl2psMalloc(list->nmax * list->size);
549 list->nmax = ((n - 1) / list->incr + 1) * list->incr;
551 list->nmax * list->size);
561 if(incr <= 0) incr = 1;
593 memcpy(&list->array[(list->n - 1) * list->size], data, list->size);
609 if((index < 0) || (index >= list->n)){
613 return &list->array[index * list->size];
617 int (*fcmp)(
const void *
a,
const void *
b))
621 qsort(list->array, list->n, list->size, fcmp);
624 static void gl2psListAction(GL2PSlist *list,
void (*action)(
void *data))
642 #if defined(GL2PS_HAVE_LIBPNG)
644 static void gl2psListRead(GL2PSlist *list,
int index,
void *data)
646 if((index < 0) || (index >= list->n))
648 memcpy(data, &list->array[index * list->size], list->size);
653 static const char cb64[] =
654 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
656 out[0] = cb64[ in[0] >> 2 ];
657 out[1] = cb64[ ((in[0] & 0x03) << 4) | ((
in[1] & 0xf0) >> 4) ];
658 out[2] = (len > 1) ? cb64[ ((
in[1] & 0x0f) << 2) | ((
in[2] & 0xc0) >> 6) ] :
'=';
659 out[3] = (len > 2) ? cb64[
in[2] & 0x3f ] :
'=';
664 unsigned char *
buffer,
in[3], out[4];
667 n = list->n * list->size;
668 buffer = (
unsigned char*)
gl2psMalloc(n *
sizeof(
unsigned char));
669 memcpy(buffer, list->array, n *
sizeof(
unsigned char));
675 for(i = 0; i < 3; i++) {
677 in[i] = buffer[
index];
687 for(i = 0; i < 4; i++)
700 if(!GL2PS_ZERO(rgba1[0] - rgba2[0]) ||
701 !GL2PS_ZERO(rgba1[1] - rgba2[1]) ||
702 !GL2PS_ZERO(rgba1[2] - rgba2[2]))
711 for(i = 1; i < prim->numverts; i++){
724 if(n < 2)
return GL_TRUE;
726 for(i = 1; i <
n; i++){
727 if(std::fabs(rgba[0][0] - rgba[i][0]) > threshold[0] ||
728 std::fabs(rgba[0][1] - rgba[i][1]) > threshold[1] ||
729 std::fabs(rgba[0][2] - rgba[i][2]) > threshold[2])
739 for(i = 0; i < 3; ++i){
740 gl2ps->lastrgba[i] = rgba[i];
744 static GLfloat
gl2psGetRGB(GL2PSimage *im, GLuint
x, GLuint
y,
745 GLfloat *
red, GLfloat *green, GLfloat *
blue)
748 GLsizei
width = im->width;
749 GLsizei height = im->height;
750 GLfloat *pixels = im->pixels;
756 pimag = pixels + 4 * (width * (height - 1 -
y) + x);
760 pimag = pixels + 3 * (width * (height - 1 -
y) + x);
763 *
red = *pimag; pimag++;
764 *green = *pimag; pimag++;
765 *
blue = *pimag; pimag++;
767 return (im->format == GL_RGBA) ? *pimag : 1.0F;
775 GL2PSimage *image = (GL2PSimage*)
gl2psMalloc(
sizeof(GL2PSimage));
777 image->width = im->width;
778 image->height = im->height;
779 image->format = im->format;
780 image->type = im->type;
782 switch(image->format){
784 size = image->height * image->width * 4 *
sizeof(GLfloat);
788 size = image->height * image->width * 3 *
sizeof(GLfloat);
793 memcpy(image->pixels, im->pixels, size);
806 #if defined(GL2PS_HAVE_LIBPNG)
808 #if !defined(png_jmpbuf)
809 # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
812 static void gl2psUserWritePNG(png_structp png_ptr, png_bytep data, png_size_t length)
815 GL2PSlist *png = (GL2PSlist*)png_get_io_ptr(png_ptr);
816 for(i = 0; i < length; i++)
828 unsigned char *row_data;
832 if(!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))
835 if(!(info_ptr = png_create_info_struct(png_ptr))){
836 png_destroy_write_struct(&png_ptr, NULL);
840 if(setjmp(png_jmpbuf(png_ptr))) {
841 png_destroy_write_struct(&png_ptr, &info_ptr);
847 png_set_IHDR(png_ptr, info_ptr, pixmap->width, pixmap->height, 8,
848 PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
849 PNG_FILTER_TYPE_BASE);
850 png_write_info(png_ptr, info_ptr);
852 row_data = (
unsigned char*)
gl2psMalloc(3 * pixmap->width *
sizeof(
unsigned char));
853 for(row = 0; row < pixmap->height; row++){
854 for(col = 0; col < pixmap->width; col++){
856 row_data[3*
col] = (
unsigned char)(255. * dr);
857 row_data[3*col+1] = (
unsigned char)(255. * dg);
858 row_data[3*col+2] = (
unsigned char)(255. * db);
860 png_write_row(png_ptr, (png_bytep)row_data);
864 png_write_end(png_ptr, info_ptr);
865 png_destroy_write_struct(&png_ptr, &info_ptr);
872 static GLint
gl2psAddText(GLint type,
const char *str,
const char *fontname,
873 GLshort fontsize, GLint alignment, GLfloat angle)
876 GL2PSprimitive *prim;
883 glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
886 glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
888 prim = (GL2PSprimitive*)
gl2psMalloc(
sizeof(GL2PSprimitive));
892 prim->verts = (GL2PSvertex*)
gl2psMalloc(
sizeof(GL2PSvertex));
893 prim->verts[0].xyz[0] = pos[0];
894 prim->verts[0].xyz[1] = pos[1];
895 prim->verts[0].xyz[2] = pos[2];
901 glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba);
902 prim->data.text = (GL2PSstring*)
gl2psMalloc(
sizeof(GL2PSstring));
903 prim->data.text->str = (
char*)
gl2psMalloc((strlen(str)+1)*
sizeof(
char));
904 strcpy(prim->data.text->str, str);
905 prim->data.text->fontname = (
char*)
gl2psMalloc((strlen(fontname)+1)*
sizeof(char));
906 strcpy(prim->data.text->fontname, fontname);
907 prim->data.text->fontsize = fontsize;
908 prim->data.text->alignment = alignment;
909 prim->data.text->angle = angle;
912 glPassThrough(GL2PS_TEXT_TOKEN);
919 GL2PSstring *text = (GL2PSstring*)
gl2psMalloc(
sizeof(GL2PSstring));
920 text->str = (
char*)
gl2psMalloc((strlen(t->str)+1)*
sizeof(
char));
921 strcpy(text->str, t->str);
922 text->fontname = (
char*)
gl2psMalloc((strlen(t->fontname)+1)*
sizeof(char));
923 strcpy(text->fontname, t->fontname);
924 text->fontsize = t->fontsize;
925 text->alignment = t->alignment;
926 text->angle = t->angle;
947 if( (sfactor == GL_SRC_ALPHA && dfactor == GL_ONE_MINUS_SRC_ALPHA) ||
948 (sfactor == GL_ONE && dfactor == GL_ZERO) )
968 switch(
gl2ps->blendfunc[0]){
981 t->prop = T_VAR_COLOR;
998 if(!GL2PS_ZERO(t->vertex[0].rgba[3] - t->vertex[1].rgba[3]) ||
999 !GL2PS_ZERO(t->vertex[1].rgba[3] - t->vertex[2].rgba[3])){
1000 t->prop |= T_VAR_ALPHA;
1003 if(t->vertex[0].rgba[3] < 1)
1004 t->prop |= T_ALPHA_LESS_1;
1006 t->prop |= T_ALPHA_1;
1011 GLboolean assignprops)
1013 t->vertex[0] = p->verts[0];
1014 t->vertex[1] = p->verts[1];
1015 t->vertex[2] = p->verts[2];
1016 if(GL_TRUE == assignprops)
1023 GL2PSvertex vertex = { {-1.0F, -1.0F, -1.0F}, {-1.0F, -1.0F, -1.0F, -1.0F} };
1024 for(i = 0; i < 3; i++)
1025 t->vertex[i] = vertex;
1026 t->prop = T_UNDEFINED;
1033 GL2PSprimitive *prim;
1040 prim = (GL2PSprimitive*)
gl2psMalloc(
sizeof(GL2PSprimitive));
1042 prim->type = p->type;
1043 prim->numverts = p->numverts;
1044 prim->boundary = p->boundary;
1045 prim->offset = p->offset;
1046 prim->pattern = p->pattern;
1047 prim->factor = p->factor;
1048 prim->culled = p->culled;
1049 prim->width = p->width;
1050 prim->verts = (GL2PSvertex*)
gl2psMalloc(p->numverts*
sizeof(GL2PSvertex));
1051 memcpy(prim->verts, p->verts, p->numverts *
sizeof(GL2PSvertex));
1058 case GL2PS_SPECIAL :
1070 if(!GL2PS_ZERO(p1[0] - p2[0]) ||
1071 !GL2PS_ZERO(p1[1] - p2[1]) ||
1072 !GL2PS_ZERO(p1[2] - p2[2]))
1085 return (plane[0] * point[0] +
1086 plane[1] * point[1] +
1087 plane[2] * point[2] +
1091 static GLfloat
gl2psPsca(GLfloat *a, GLfloat *b)
1093 return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
1096 static void gl2psPvec(GLfloat *a, GLfloat *b, GLfloat *
c)
1098 c[0] = a[1]*b[2] - a[2]*b[1];
1099 c[1] = a[2]*b[0] - a[0]*b[2];
1100 c[2] = a[0]*b[1] - a[1]*b[0];
1105 return (GLfloat)sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
1127 static void gl2psGetPlane(GL2PSprimitive *prim, GL2PSplane plane)
1129 GL2PSxyz v = {0.0F, 0.0F, 0.0F}, w = {0.0F, 0.0F, 0.0F};
1132 case GL2PS_TRIANGLE :
1133 case GL2PS_QUADRANGLE :
1134 v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0];
1135 v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1];
1136 v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2];
1137 w[0] = prim->verts[2].xyz[0] - prim->verts[0].xyz[0];
1138 w[1] = prim->verts[2].xyz[1] - prim->verts[0].xyz[1];
1139 w[2] = prim->verts[2].xyz[2] - prim->verts[0].xyz[2];
1140 if((GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])) ||
1141 (GL2PS_ZERO(w[0]) && GL2PS_ZERO(w[1]) && GL2PS_ZERO(w[2]))){
1142 plane[0] = plane[1] = 0.0F;
1144 plane[3] = -prim->verts[0].xyz[2];
1149 - plane[0] * prim->verts[0].xyz[0]
1150 - plane[1] * prim->verts[0].xyz[1]
1151 - plane[2] * prim->verts[0].xyz[2];
1155 v[0] = prim->verts[1].xyz[0] - prim->verts[0].xyz[0];
1156 v[1] = prim->verts[1].xyz[1] - prim->verts[0].xyz[1];
1157 v[2] = prim->verts[1].xyz[2] - prim->verts[0].xyz[2];
1158 if(GL2PS_ZERO(v[0]) && GL2PS_ZERO(v[1]) && GL2PS_ZERO(v[2])){
1159 plane[0] = plane[1] = 0.0F;
1161 plane[3] = -prim->verts[0].xyz[2];
1164 if(GL2PS_ZERO(v[0])) w[0] = 1.0F;
1165 else if(GL2PS_ZERO(v[1])) w[1] = 1.0F;
1169 - plane[0] * prim->verts[0].xyz[0]
1170 - plane[1] * prim->verts[0].xyz[1]
1171 - plane[2] * prim->verts[0].xyz[2];
1177 case GL2PS_SPECIAL :
1178 case GL2PS_IMAGEMAP:
1179 plane[0] = plane[1] = 0.0F;
1181 plane[3] = -prim->verts[0].xyz[2];
1185 plane[0] = plane[1] = plane[3] = 0.0F;
1191 static void gl2psCutEdge(GL2PSvertex *a, GL2PSvertex *b, GL2PSplane plane,
1197 v[0] = b->xyz[0] - a->xyz[0];
1198 v[1] = b->xyz[1] - a->xyz[1];
1199 v[2] = b->xyz[2] - a->xyz[2];
1201 if(!GL2PS_ZERO(psca =
gl2psPsca(plane, v)))
1206 c->xyz[0] = a->xyz[0] + v[0] * sect;
1207 c->xyz[1] = a->xyz[1] + v[1] * sect;
1208 c->xyz[2] = a->xyz[2] + v[2] * sect;
1210 c->rgba[0] = (1 - sect) * a->rgba[0] + sect * b->rgba[0];
1211 c->rgba[1] = (1 - sect) * a->rgba[1] + sect * b->rgba[1];
1212 c->rgba[2] = (1 - sect) * a->rgba[2] + sect * b->rgba[2];
1213 c->rgba[3] = (1 - sect) * a->rgba[3] + sect * b->rgba[3];
1217 GL2PSprimitive *child, GLshort numverts,
1218 GLshort *index0, GLshort *index1)
1222 if(parent->type == GL2PS_IMAGEMAP){
1223 child->type = GL2PS_IMAGEMAP;
1224 child->data.image = parent->data.image;
1232 case 1 : child->type = GL2PS_POINT;
break;
1233 case 2 : child->type = GL2PS_LINE;
break;
1234 case 3 : child->type = GL2PS_TRIANGLE;
break;
1235 case 4 : child->type = GL2PS_QUADRANGLE;
break;
1236 default: child->type = GL2PS_NO_TYPE;
break;
1240 child->boundary = 0;
1241 child->culled = parent->culled;
1242 child->offset = parent->offset;
1243 child->pattern = parent->pattern;
1244 child->factor = parent->factor;
1245 child->width = parent->width;
1246 child->numverts = numverts;
1247 child->verts = (GL2PSvertex*)
gl2psMalloc(numverts *
sizeof(GL2PSvertex));
1249 for(i = 0; i < numverts; i++){
1251 child->verts[i] = parent->verts[index0[i]];
1254 gl2psCutEdge(&parent->verts[index0[i]], &parent->verts[index1[i]],
1255 plane, &child->verts[i]);
1260 static void gl2psAddIndex(GLshort *index0, GLshort *index1, GLshort *nb,
1261 GLshort i, GLshort j)
1265 for(k = 0; k < *nb; k++){
1266 if((index0[k] == i && index1[k] == j) ||
1267 (index1[k] == i && index0[k] == j))
return;
1276 return (i < num - 1) ? i + 1 : 0;
1281 GLint type = GL2PS_COINCIDENT;
1285 for(i = 0; i < prim->numverts; i++){
1289 if(prim->numverts < 2){
1293 for(i = 0; i < prim->numverts; i++){
1295 if(d[j] > GL2PS_EPSILON){
1296 if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF;
1297 else if(type != GL2PS_IN_BACK_OF)
return 1;
1298 if(d[i] < -GL2PS_EPSILON)
return 1;
1300 else if(d[j] < -GL2PS_EPSILON){
1301 if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF;
1302 else if(type != GL2PS_IN_FRONT_OF)
return 1;
1303 if(d[i] > GL2PS_EPSILON)
return 1;
1311 GL2PSprimitive **front, GL2PSprimitive **back)
1313 GLshort i, j, in = 0, out = 0, in0[5], in1[5], out0[5], out1[5];
1317 type = GL2PS_COINCIDENT;
1319 for(i = 0; i < prim->numverts; i++){
1325 if(d[0] > GL2PS_EPSILON) type = GL2PS_IN_BACK_OF;
1326 else if(d[0] < -GL2PS_EPSILON) type = GL2PS_IN_FRONT_OF;
1327 else type = GL2PS_COINCIDENT;
1330 for(i = 0; i < prim->numverts; i++){
1332 if(d[j] > GL2PS_EPSILON){
1333 if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF;
1334 else if(type != GL2PS_IN_BACK_OF) type = GL2PS_SPANNING;
1335 if(d[i] < -GL2PS_EPSILON){
1338 type = GL2PS_SPANNING;
1342 else if(d[j] < -GL2PS_EPSILON){
1343 if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF;
1344 else if(type != GL2PS_IN_FRONT_OF) type = GL2PS_SPANNING;
1345 if(d[i] > GL2PS_EPSILON){
1348 type = GL2PS_SPANNING;
1360 if(type == GL2PS_SPANNING){
1361 *back = (GL2PSprimitive*)
gl2psMalloc(
sizeof(GL2PSprimitive));
1362 *front = (GL2PSprimitive*)
gl2psMalloc(
sizeof(GL2PSprimitive));
1371 GL2PSprimitive **
t1, GL2PSprimitive **
t2)
1373 *t1 = (GL2PSprimitive*)
gl2psMalloc(
sizeof(GL2PSprimitive));
1374 *t2 = (GL2PSprimitive*)
gl2psMalloc(
sizeof(GL2PSprimitive));
1375 (*t1)->type = (*t2)->type = GL2PS_TRIANGLE;
1376 (*t1)->numverts = (*t2)->numverts = 3;
1377 (*t1)->culled = (*t2)->culled = quad->culled;
1378 (*t1)->offset = (*t2)->offset = quad->offset;
1379 (*t1)->pattern = (*t2)->pattern = quad->pattern;
1380 (*t1)->factor = (*t2)->factor = quad->factor;
1381 (*t1)->width = (*t2)->width = quad->width;
1382 (*t1)->verts = (GL2PSvertex*)
gl2psMalloc(3 *
sizeof(GL2PSvertex));
1383 (*t2)->verts = (GL2PSvertex*)
gl2psMalloc(3 *
sizeof(GL2PSvertex));
1384 (*t1)->verts[0] = quad->verts[0];
1385 (*t1)->verts[1] = quad->verts[1];
1386 (*t1)->verts[2] = quad->verts[2];
1387 (*t1)->boundary = ((quad->boundary & 1) ? 1 : 0) | ((quad->boundary & 2) ? 2 : 0);
1388 (*t2)->verts[0] = quad->verts[0];
1389 (*t2)->verts[1] = quad->verts[2];
1390 (*t2)->verts[2] = quad->verts[3];
1391 (*t2)->boundary = ((quad->boundary & 4) ? 2 : 0) | ((quad->boundary & 4) ? 2 : 0);
1396 GL2PSprimitive *q, *w;
1397 GLfloat dq = 0.0F, dw = 0.0F, diff;
1400 q = *(GL2PSprimitive**)a;
1401 w = *(GL2PSprimitive**)b;
1403 for(i = 0; i < q->numverts; i++){
1404 dq += q->verts[i].xyz[2];
1406 dq /= (GLfloat)q->numverts;
1408 for(i = 0; i < w->numverts; i++){
1409 dw += w->verts[i].xyz[2];
1411 dw /= (GLfloat)w->numverts;
1427 GL2PSprimitive *q, *w;
1429 q = *(GL2PSprimitive**)a;
1430 w = *(GL2PSprimitive**)b;
1431 return (q->type < w->type ? 1 : -1);
1434 static GLint
gl2psFindRoot(GL2PSlist *primitives, GL2PSprimitive **root)
1436 GLint i, j, count, best = 1000000, index = 0;
1437 GL2PSprimitive *prim1, *prim2;
1450 if(maxp >
gl2ps->maxbestroot){
1451 maxp =
gl2ps->maxbestroot;
1453 for(i = 0; i < maxp; i++){
1462 if(count > best)
break;
1468 if(!count)
return index;
1481 GL2PSimagemap *next;
1482 while(list != NULL){
1495 q = *(GL2PSprimitive**)data;
1497 if(q->type == GL2PS_TEXT || q->type == GL2PS_SPECIAL){
1500 else if(q->type == GL2PS_PIXMAP){
1508 GL2PSprimitive *
t1, *
t2;
1510 if(prim->type != GL2PS_QUADRANGLE){
1526 if((*tree)->primitives){
1538 if(f1 > f2)
return GL_TRUE;
1539 else return GL_FALSE;
1542 static GLboolean
gl2psLess(GLfloat f1, GLfloat f2)
1544 if(f1 < f2)
return GL_TRUE;
1545 else return GL_FALSE;
1550 GL2PSprimitive *prim, *frontprim = NULL, *backprim = NULL;
1551 GL2PSlist *frontlist, *backlist;
1568 case GL2PS_COINCIDENT:
1571 case GL2PS_IN_BACK_OF:
1574 case GL2PS_IN_FRONT_OF:
1577 case GL2PS_SPANNING:
1592 tree->front = (GL2PSbsptree*)
gl2psMalloc(
sizeof(GL2PSbsptree));
1601 tree->back = (GL2PSbsptree*)
gl2psMalloc(
sizeof(GL2PSbsptree));
1612 GLboolean (*compare)(GLfloat f1, GLfloat f2),
1613 void (*action)(
void *data),
int inverse)
1621 if(GL_TRUE == compare(result, epsilon)){
1631 else if(GL_TRUE == compare(-epsilon, result)){
1649 GL2PSprimitive *prim;
1650 GLfloat minZ, maxZ, rangeZ, scaleZ;
1651 GLfloat factor, units, area, dZ, dZdX, dZdY, maxdZ;
1659 minZ = maxZ = prim->verts[0].xyz[2];
1660 for(i = 1; i < prim->numverts; i++){
1661 if(prim->verts[i].xyz[2] < minZ) minZ = prim->verts[i].xyz[2];
1662 if(prim->verts[i].xyz[2] > maxZ) maxZ = prim->verts[i].xyz[2];
1666 for(j = 0; j < prim->numverts; j++){
1667 if(prim->verts[j].xyz[2] < minZ) minZ = prim->verts[j].xyz[2];
1668 if(prim->verts[j].xyz[2] > maxZ) maxZ = prim->verts[j].xyz[2];
1671 rangeZ = (maxZ - minZ);
1675 scaleZ = GL2PS_ZERO(rangeZ) ? GL2PS_ZSCALE : (GL2PS_ZSCALE / rangeZ);
1677 if(scaleZ > 100000.F) scaleZ = 100000.F;
1682 for(j = 0; j < prim->numverts; j++){
1683 prim->verts[j].xyz[2] = (prim->verts[j].xyz[2] - minZ) * scaleZ;
1686 (prim->type == GL2PS_LINE)){
1688 prim->verts[0].xyz[2] -= GL2PS_ZOFFSET_LARGE;
1689 prim->verts[1].xyz[2] -= GL2PS_ZOFFSET_LARGE;
1692 prim->verts[0].xyz[2] -= GL2PS_ZOFFSET;
1693 prim->verts[1].xyz[2] -= GL2PS_ZOFFSET;
1696 else if(prim->offset && (prim->type == GL2PS_TRIANGLE)){
1697 factor =
gl2ps->offset[0];
1698 units =
gl2ps->offset[1];
1700 (prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) *
1701 (prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) -
1702 (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) *
1703 (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]);
1704 if(!GL2PS_ZERO(area)){
1706 ((prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) *
1707 (prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) -
1708 (prim->verts[1].xyz[1] - prim->verts[0].xyz[1]) *
1709 (prim->verts[2].xyz[2] - prim->verts[1].xyz[2])) / area;
1711 ((prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) *
1712 (prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) -
1713 (prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) *
1714 (prim->verts[1].xyz[2] - prim->verts[0].xyz[2])) / area;
1715 maxdZ = (GLfloat)sqrt(dZdX * dZdX + dZdY * dZdY);
1720 dZ = factor * maxdZ + units;
1721 prim->verts[0].xyz[2] += dZ;
1722 prim->verts[1].xyz[2] += dZ;
1723 prim->verts[2].xyz[2] += dZ;
1738 plane[0] = b[1] - a[1];
1739 plane[1] = a[0] - b[0];
1740 n = (GLfloat)sqrt(plane[0]*plane[0] + plane[1]*plane[1]);
1745 plane[3] = -plane[0]*a[0]-plane[1]*a[1];
1771 if(pt_dis > GL2PS_EPSILON)
return GL2PS_POINT_INFRONT;
1772 else if(pt_dis < -GL2PS_EPSILON)
return GL2PS_POINT_BACK;
1773 else return GL2PS_POINT_COINCIDENT;
1777 GL2PSbsptree2d **tree)
1782 GL2PSbsptree2d *head = NULL, *cur = NULL;
1784 if((*tree == NULL) && (prim->numverts > 2)){
1789 head = (GL2PSbsptree2d*)
gl2psMalloc(
sizeof(GL2PSbsptree2d));
1790 for(i = 0; i < prim->numverts-1; i++){
1792 prim->verts[i+1].xyz,
1794 if(prim->numverts-i > 3){
1808 for(i = 2+offset; i < prim->numverts; i++){
1810 if(ret != GL2PS_POINT_COINCIDENT)
break;
1813 case GL2PS_POINT_INFRONT :
1815 for(i = 1+offset; i < prim->numverts-1; i++){
1816 if(cur->front == NULL){
1817 cur->front = (GL2PSbsptree2d*)
gl2psMalloc(
sizeof(GL2PSbsptree2d));
1820 prim->verts[i+1].xyz,
1821 cur->front->plane)){
1827 if(cur->front == NULL){
1828 cur->front = (GL2PSbsptree2d*)
gl2psMalloc(
sizeof(GL2PSbsptree2d));
1831 prim->verts[offset].xyz,
1832 cur->front->plane)){
1833 cur->front->front = NULL;
1834 cur->front->back = NULL;
1841 case GL2PS_POINT_BACK :
1842 for(i = 0; i < 4; i++){
1843 head->plane[i] = -head->plane[i];
1846 for(i = 1+offset; i < prim->numverts-1; i++){
1847 if(cur->front == NULL){
1848 cur->front = (GL2PSbsptree2d*)
gl2psMalloc(
sizeof(GL2PSbsptree2d));
1852 cur->front->plane)){
1858 if(cur->front == NULL){
1859 cur->front = (GL2PSbsptree2d*)
gl2psMalloc(
sizeof(GL2PSbsptree2d));
1863 cur->front->plane)){
1864 cur->front->front = NULL;
1865 cur->front->back = NULL;
1886 for(i = 1; i < prim->numverts; i++){
1888 if(pos == (GL2PS_POINT_INFRONT | GL2PS_POINT_BACK))
return GL2PS_SPANNING;
1890 if(pos & GL2PS_POINT_INFRONT)
return GL2PS_IN_FRONT_OF;
1891 else if(pos & GL2PS_POINT_BACK)
return GL2PS_IN_BACK_OF;
1892 else return GL2PS_COINCIDENT;
1900 GL2PSprimitive *child = (GL2PSprimitive*)
gl2psMalloc(
sizeof(GL2PSprimitive));
1902 if(parent->type == GL2PS_IMAGEMAP){
1903 child->type = GL2PS_IMAGEMAP;
1904 child->data.image = parent->data.image;
1908 case 1 : child->type = GL2PS_POINT;
break;
1909 case 2 : child->type = GL2PS_LINE;
break;
1910 case 3 : child->type = GL2PS_TRIANGLE;
break;
1911 case 4 : child->type = GL2PS_QUADRANGLE;
break;
1912 default: child->type = GL2PS_NO_TYPE;
break;
1915 child->boundary = 0;
1916 child->culled = parent->culled;
1917 child->offset = parent->offset;
1918 child->pattern = parent->pattern;
1919 child->factor = parent->factor;
1920 child->width = parent->width;
1921 child->numverts = numverts;
1922 child->verts = (GL2PSvertex*)
gl2psMalloc(numverts *
sizeof(GL2PSvertex));
1923 for(i = 0; i < numverts; i++){
1924 child->verts[i] = vertx[i];
1931 GL2PSprimitive **front,
1932 GL2PSprimitive **back)
1939 GLint cur = -1, prev = -1, i, v1 = 0, v2 = 0, flag = 1, prev0 = -1;
1942 GL2PSvertex *front_list = NULL, *back_list = NULL;
1945 GLshort front_count = 0, back_count = 0;
1947 for(i = 0; i <= prim->numverts; i++){
1949 if(v1 == prim->numverts){
1950 if(prim->numverts < 3)
break;
1952 v2 = prim->numverts - 1;
1961 if(((prev == -1) || (prev == cur) || (prev == 0) || (cur == 0)) &&
1962 (i < prim->numverts)){
1963 if(cur == GL2PS_POINT_INFRONT){
1966 sizeof(GL2PSvertex)*front_count);
1967 front_list[front_count-1] = prim->verts[v1];
1969 else if(cur == GL2PS_POINT_BACK){
1972 sizeof(GL2PSvertex)*back_count);
1973 back_list[back_count-1] = prim->verts[v1];
1978 sizeof(GL2PSvertex)*front_count);
1979 front_list[front_count-1] = prim->verts[v1];
1982 sizeof(GL2PSvertex)*back_count);
1983 back_list[back_count-1] = prim->verts[v1];
1987 else if((prev != cur) && (cur != 0) && (prev != 0)){
1994 sizeof(GL2PSvertex)*front_count);
1996 plane, &front_list[front_count-1]);
1999 sizeof(GL2PSvertex)*back_count);
2000 back_list[back_count-1] = front_list[front_count-1];
2014 GL2PSprimitive *frontprim = NULL, *backprim = NULL;
2019 if(prim->type == GL2PS_PIXMAP ||
2020 prim->type == GL2PS_TEXT ||
2021 prim->type == GL2PS_SPECIAL){
2026 if((prim->type != GL2PS_IMAGEMAP) && (GL_FALSE ==
gl2ps->zerosurfacearea)){
2034 case GL2PS_IN_FRONT_OF:
2037 case GL2PS_SPANNING:
2040 if((*tree)->front != NULL){
2050 case GL2PS_COINCIDENT:
2051 if((*tree)->back != NULL){
2052 gl2ps->zerosurfacearea = GL_TRUE;
2054 gl2ps->zerosurfacearea = GL_FALSE;
2057 if((*tree)->front != NULL){
2058 gl2ps->zerosurfacearea = GL_TRUE;
2060 gl2ps->zerosurfacearea = GL_FALSE;
2063 if(prim->type == GL2PS_LINE)
return 1;
2072 GL2PSprimitive *prim = *(GL2PSprimitive **)data;
2073 gl2ps->primitivetoadd = prim;
2074 if(prim->type == GL2PS_IMAGEMAP && prim->data.image->format == GL2PS_IMAGEMAP_VISIBLE){
2080 else if(prim->type == GL2PS_IMAGEMAP){
2081 prim->data.image->format = GL2PS_IMAGEMAP_VISIBLE;
2093 c[0] = c[1] = c[2] = 0.0F;
2094 for(i = 0; i < prim->numverts; i++){
2095 c[0] += prim->verts[i].xyz[0];
2096 c[1] += prim->verts[i].xyz[1];
2098 c[0] /= prim->numverts;
2099 c[1] /= prim->numverts;
2101 for(i = 0; i < prim->numverts; i++){
2102 if(prim->boundary & (GLint)pow(2., i)){
2103 b = (GL2PSprimitive*)
gl2psMalloc(
sizeof(GL2PSprimitive));
2104 b->type = GL2PS_LINE;
2105 b->offset = prim->offset;
2106 b->pattern = prim->pattern;
2107 b->factor = prim->factor;
2108 b->culled = prim->culled;
2109 b->width = prim->width;
2112 b->verts = (GL2PSvertex*)
gl2psMalloc(2 *
sizeof(GL2PSvertex));
2115 v[0] = c[0] - prim->verts[i].xyz[0];
2116 v[1] = c[1] - prim->verts[i].xyz[1];
2121 b->verts[0].xyz[0] = prim->verts[i].xyz[0] +0.1*v[0];
2122 b->verts[0].xyz[1] = prim->verts[i].xyz[1] +0.1*v[1];
2123 b->verts[0].xyz[2] = prim->verts[i].xyz[2];
2124 v[0] = c[0] - prim->verts[
gl2psGetIndex(i, prim->numverts)].xyz[0];
2125 v[1] = c[1] - prim->verts[
gl2psGetIndex(i, prim->numverts)].xyz[1];
2129 b->verts[1].xyz[0] = prim->verts[
gl2psGetIndex(i, prim->numverts)].xyz[0] +0.1*v[0];
2130 b->verts[1].xyz[1] = prim->verts[
gl2psGetIndex(i, prim->numverts)].xyz[1] +0.1*v[1];
2131 b->verts[1].xyz[2] = prim->verts[
gl2psGetIndex(i, prim->numverts)].xyz[2];
2133 b->verts[0].xyz[0] = prim->verts[i].xyz[0];
2134 b->verts[0].xyz[1] = prim->verts[i].xyz[1];
2135 b->verts[0].xyz[2] = prim->verts[i].xyz[2];
2136 b->verts[1].xyz[0] = prim->verts[
gl2psGetIndex(i, prim->numverts)].xyz[0];
2137 b->verts[1].xyz[1] = prim->verts[
gl2psGetIndex(i, prim->numverts)].xyz[1];
2138 b->verts[1].xyz[2] = prim->verts[
gl2psGetIndex(i, prim->numverts)].xyz[2];
2141 b->verts[0].rgba[0] = 0.0F;
2142 b->verts[0].rgba[1] = 0.0F;
2143 b->verts[0].rgba[2] = 0.0F;
2144 b->verts[0].rgba[3] = 0.0F;
2145 b->verts[1].rgba[0] = 0.0F;
2146 b->verts[1].rgba[1] = 0.0F;
2147 b->verts[1].rgba[2] = 0.0F;
2148 b->verts[1].rgba[3] = 0.0F;
2158 GL2PSprimitive *prim;
2176 GL2PSvertex *verts, GLint offset,
2177 GLushort pattern, GLint factor,
2178 GLfloat width,
char boundary)
2180 GL2PSprimitive *prim;
2182 prim = (GL2PSprimitive*)
gl2psMalloc(
sizeof(GL2PSprimitive));
2184 prim->numverts = numverts;
2185 prim->verts = (GL2PSvertex*)
gl2psMalloc(numverts *
sizeof(GL2PSvertex));
2186 memcpy(prim->verts, verts, numverts *
sizeof(GL2PSvertex));
2187 prim->boundary = boundary;
2188 prim->offset = offset;
2189 prim->pattern = pattern;
2190 prim->factor = factor;
2191 prim->width = width;
2208 if(
gl2ps->colormode == GL_COLOR_INDEX &&
gl2ps->colorsize > 0){
2209 i = (GLint)(p[3] + 0.5);
2210 v->rgba[0] =
gl2ps->colormap[i][0];
2211 v->rgba[1] =
gl2ps->colormap[i][1];
2212 v->rgba[2] =
gl2ps->colormap[i][2];
2213 v->rgba[3] =
gl2ps->colormap[i][3];
2228 GLushort pattern = 0;
2230 GLint i, sizeoffloat, count,
v, vtot, offset = 0, factor = 0, auxindex = 0;
2231 GLfloat lwidth = 1.0F, psize = 1.0F;
2233 GL2PSvertex vertices[3];
2234 GL2PSprimitive *prim;
2235 GL2PSimagemap *node;
2237 current =
gl2ps->feedback;
2238 boundary =
gl2ps->boundary = GL_FALSE;
2242 if(GL_TRUE == boundary)
gl2ps->boundary = GL_TRUE;
2244 switch((GLint)*current){
2245 case GL_POINT_TOKEN :
2252 pattern, factor, psize, 0);
2254 case GL_LINE_TOKEN :
2255 case GL_LINE_RESET_TOKEN :
2265 pattern, factor, lwidth, 0);
2267 case GL_POLYGON_TOKEN :
2268 count = (GLint)current[1];
2272 while(count > 0 && used > 0){
2280 if(GL_TRUE == boundary){
2281 if(!count && vtot == 2) flag = 1|2|4;
2282 else if(!count) flag = 2|4;
2283 else if(vtot == 2) flag = 1|2;
2289 pattern, factor, 1, flag);
2290 vertices[1] = vertices[2];
2296 case GL_BITMAP_TOKEN :
2297 case GL_DRAW_PIXEL_TOKEN :
2298 case GL_COPY_PIXEL_TOKEN :
2305 case GL_PASS_THROUGH_TOKEN :
2306 switch((GLint)current[1]){
2307 case GL2PS_BEGIN_OFFSET_TOKEN : offset = 1;
break;
2308 case GL2PS_END_OFFSET_TOKEN : offset = 0;
break;
2309 case GL2PS_BEGIN_BOUNDARY_TOKEN : boundary = GL_TRUE;
break;
2310 case GL2PS_END_BOUNDARY_TOKEN : boundary = GL_FALSE;
break;
2311 case GL2PS_END_STIPPLE_TOKEN : pattern = factor = 0;
break;
2312 case GL2PS_BEGIN_BLEND_TOKEN :
gl2ps->blending = GL_TRUE;
break;
2313 case GL2PS_END_BLEND_TOKEN :
gl2ps->blending = GL_FALSE;
break;
2314 case GL2PS_BEGIN_STIPPLE_TOKEN :
2317 pattern = (GLushort)current[1];
2320 factor = (GLint)current[1];
2322 case GL2PS_SRC_BLEND_TOKEN :
2325 gl2ps->blendfunc[0] = (GLint)current[1];
2327 case GL2PS_DST_BLEND_TOKEN :
2330 gl2ps->blendfunc[1] = (GLint)current[1];
2332 case GL2PS_POINT_SIZE_TOKEN :
2337 case GL2PS_LINE_WIDTH_TOKEN :
2340 lwidth = current[1];
2342 case GL2PS_IMAGEMAP_TOKEN :
2343 prim = (GL2PSprimitive *)
gl2psMalloc(
sizeof(GL2PSprimitive));
2344 prim->type = GL2PS_IMAGEMAP;
2347 prim->verts = (GL2PSvertex *)
gl2psMalloc(4 *
sizeof(GL2PSvertex));
2354 node = (GL2PSimagemap*)
gl2psMalloc(
sizeof(GL2PSimagemap));
2355 node->image = (GL2PSimage*)
gl2psMalloc(
sizeof(GL2PSimage));
2356 node->image->type = 0;
2357 node->image->format = 0;
2360 if(
gl2ps->imagemap_head == NULL)
2361 gl2ps->imagemap_head = node;
2363 gl2ps->imagemap_tail->next = node;
2364 gl2ps->imagemap_tail = node;
2365 prim->data.image = node->image;
2367 current += 2; used -= 2;
2369 current += i; used -= i;
2371 node->image->width = (GLint)current[2];
2372 current += 2; used -= 2;
2373 node->image->height = (GLint)current[2];
2374 prim->verts[0].xyz[0] = prim->verts[0].xyz[0] - (
int)(node->image->width / 2) + 0.5F;
2375 prim->verts[0].xyz[1] = prim->verts[0].xyz[1] - (
int)(node->image->height / 2) + 0.5F;
2376 for(i = 1; i < 4; i++){
2377 for(v = 0; v < 3; v++){
2378 prim->verts[i].xyz[
v] = prim->verts[0].xyz[
v];
2379 prim->verts[i].rgba[
v] = prim->verts[0].rgba[
v];
2381 prim->verts[i].rgba[
v] = prim->verts[0].rgba[
v];
2383 prim->verts[1].xyz[0] = prim->verts[1].xyz[0] + node->image->width;
2384 prim->verts[2].xyz[0] = prim->verts[1].xyz[0];
2385 prim->verts[2].xyz[1] = prim->verts[2].xyz[1] + node->image->height;
2386 prim->verts[3].xyz[1] = prim->verts[2].xyz[1];
2388 sizeoffloat =
sizeof(GLfloat);
2389 v = 2 * sizeoffloat;
2390 vtot = node->image->height + node->image->height *
2391 ((node->image->width - 1) / 8);
2392 node->image->pixels = (GLfloat*)
gl2psMalloc(v + vtot);
2393 node->image->pixels[0] = prim->verts[0].xyz[0];
2394 node->image->pixels[1] = prim->verts[0].xyz[1];
2396 for(i = 0; i < vtot; i += sizeoffloat){
2397 current += 2; used -= 2;
2399 memcpy(&(((
char*)(node->image->pixels))[i +
v]), &(current[2]), sizeoffloat);
2401 memcpy(&(((
char*)(node->image->pixels))[i + v]), &(current[2]), vtot - i);
2406 case GL2PS_DRAW_PIXELS_TOKEN :
2407 case GL2PS_TEXT_TOKEN :
2437 unsigned char h = byte / 16;
2438 unsigned char l = byte % 16;
2444 GLuint nbhex, nbyte, nrgb, nbits;
2445 GLuint row,
col, ibyte, icase;
2446 GLfloat dr, dg, db, fgrey;
2447 unsigned char red = 0, green = 0,
blue = 0,
b, grey;
2448 GLuint width = (GLuint)im->width;
2449 GLuint height = (GLuint)im->height;
2456 if((width <= 0) || (height <= 0))
return;
2465 gl2psPrintf(
"[ %d 0 0 -%d 0 %d ]\n", width, height, height);
2466 gl2psPrintf(
"{ currentfile picstr readhexstring pop }\n");
2468 for(row = 0; row < height; row++){
2469 for(col = 0; col < width; col++){
2471 fgrey = (0.30F * dr + 0.59F * dg + 0.11F * db);
2472 grey = (
unsigned char)(255. * fgrey);
2477 nbhex = width * height * 2;
2482 nbits = nrgb * nbit;
2484 if((nbyte * 8) != nbits) nbyte++;
2487 gl2psPrintf(
"[ %d 0 0 -%d 0 %d ]\n", width, height, height);
2488 gl2psPrintf(
"{ currentfile rgbstr readhexstring pop }\n");
2491 for(row = 0; row < height; row++){
2495 for(ibyte = 0; ibyte < nbyte; ibyte++){
2504 red = (
unsigned char)(3. * dr);
2505 green = (
unsigned char)(3. * dg);
2506 blue = (
unsigned char)(3. * db);
2517 red = (
unsigned char)(3. * dr);
2518 green = (
unsigned char)(3. * dg);
2519 blue = (
unsigned char)(3. * db);
2525 else if(icase == 2) {
2535 red = (
unsigned char)(3. * dr);
2536 green = (
unsigned char)(3. * dg);
2537 blue = (
unsigned char)(3. * db);
2544 else if(icase == 3) {
2553 red = (
unsigned char)(3. * dr);
2554 green = (
unsigned char)(3. * dg);
2555 blue = (
unsigned char)(3. * db);
2569 nbits = nrgb * nbit;
2571 if((nbyte * 8) != nbits) nbyte++;
2574 gl2psPrintf(
"[ %d 0 0 -%d 0 %d ]\n", width, height, height);
2575 gl2psPrintf(
"{ currentfile rgbstr readhexstring pop }\n");
2578 for(row = 0; row < height; row++){
2581 for(ibyte = 0; ibyte < nbyte; ibyte++){
2590 red = (
unsigned char)(15. * dr);
2591 green = (
unsigned char)(15. * dg);
2595 else if(icase == 2) {
2596 blue = (
unsigned char)(15. * db);
2604 red = (
unsigned char)(15. * dr);
2608 else if(icase == 3) {
2609 green = (
unsigned char)(15. * dg);
2610 blue = (
unsigned char)(15. * db);
2622 gl2psPrintf(
"[ %d 0 0 -%d 0 %d ]\n", width, height, height);
2623 gl2psPrintf(
"{ currentfile rgbstr readhexstring pop }\n");
2626 for(row = 0; row < height; row++){
2627 for(col = 0; col < width; col++){
2629 red = (
unsigned char)(255. * dr);
2631 green = (
unsigned char)(255. * dg);
2633 blue = (
unsigned char)(255. * db);
2644 GLsizei width, GLsizei height,
2645 const unsigned char *imagemap){
2648 if((width <= 0) || (height <= 0))
return;
2650 size = height + height * (width - 1) / 8;
2654 gl2psPrintf(
"%d %d scale\n%d %d\ntrue\n", width, height,width, height);
2655 gl2psPrintf(
"[ %d 0 0 -%d 0 %d ] {<", width, height);
2656 for(i = 0; i < size; i++){
2682 "%%%%Creator: GL2PS %d.%d.%d%s, %s\n"
2684 "%%%%CreationDate:\n"
2685 "%%%%LanguageLevel: 3\n"
2686 "%%%%DocumentData: Clean7Bit\n"
2694 "%%%%DocumentMedia: Default %d %d 0 () ()\n",
2697 (
int)
gl2ps->viewport[2],
2699 (
int)
gl2ps->viewport[3]);
2703 "%%%%EndComments\n",
2705 (
int)
gl2ps->viewport[0],
2707 (
int)
gl2ps->viewport[1],
2709 (
int)
gl2ps->viewport[2],
2711 (
int)
gl2ps->viewport[3]);
2727 "/gl2psdict 64 dict def gl2psdict begin\n"
2728 "0 setlinecap 0 setlinejoin\n"
2729 "/tryPS3shading %s def %% set to false to force subdivision\n"
2730 "/rThreshold %g def %% red component subdivision threshold\n"
2731 "/gThreshold %g def %% green component subdivision threshold\n"
2732 "/bThreshold %g def %% blue component subdivision threshold\n",
2737 "/C { setrgbcolor } BD\n"
2738 "/G { 0.082 mul exch 0.6094 mul add exch 0.3086 mul add neg 1.0 add setgray } BD\n"
2739 "/W { setlinewidth } BD\n");
2741 gl2psPrintf(
"/FC { findfont exch /SH exch def SH scalefont setfont } BD\n"
2742 "/SW { dup stringwidth pop } BD\n"
2743 "/S { FC moveto show } BD\n"
2744 "/SBC{ FC moveto SW -2 div 0 rmoveto show } BD\n"
2745 "/SBR{ FC moveto SW neg 0 rmoveto show } BD\n"
2746 "/SCL{ FC moveto 0 SH -2 div rmoveto show } BD\n"
2747 "/SCC{ FC moveto SW -2 div SH -2 div rmoveto show } BD\n"
2748 "/SCR{ FC moveto SW neg SH -2 div rmoveto show } BD\n"
2749 "/STL{ FC moveto 0 SH neg rmoveto show } BD\n"
2750 "/STC{ FC moveto SW -2 div SH neg rmoveto show } BD\n"
2751 "/STR{ FC moveto SW neg SH neg rmoveto show } BD\n");
2756 "/SR { gsave FCT moveto rotate show grestore } BD\n"
2757 "/SBCR{ gsave FCT moveto rotate SW -2 div 0 rmoveto show grestore } BD\n"
2758 "/SBRR{ gsave FCT moveto rotate SW neg 0 rmoveto show grestore } BD\n"
2759 "/SCLR{ gsave FCT moveto rotate 0 SH -2 div rmoveto show grestore} BD\n");
2760 gl2psPrintf(
"/SCCR{ gsave FCT moveto rotate SW -2 div SH -2 div rmoveto show grestore} BD\n"
2761 "/SCRR{ gsave FCT moveto rotate SW neg SH -2 div rmoveto show grestore} BD\n"
2762 "/STLR{ gsave FCT moveto rotate 0 SH neg rmoveto show grestore } BD\n"
2763 "/STCR{ gsave FCT moveto rotate SW -2 div SH neg rmoveto show grestore } BD\n"
2764 "/STRR{ gsave FCT moveto rotate SW neg SH neg rmoveto show grestore } BD\n");
2766 gl2psPrintf(
"/P { newpath 0.0 360.0 arc closepath fill } BD\n"
2767 "/LS { newpath moveto } BD\n"
2768 "/L { lineto } BD\n"
2769 "/LE { lineto stroke } BD\n"
2770 "/T { newpath moveto lineto lineto closepath fill } BD\n");
2776 " /b1 exch def /g1 exch def /r1 exch def /y1 exch def /x1 exch def\n"
2777 " /b2 exch def /g2 exch def /r2 exch def /y2 exch def /x2 exch def\n"
2778 " /b3 exch def /g3 exch def /r3 exch def /y3 exch def /x3 exch def\n"
2779 " gsave << /ShadingType 4 /ColorSpace [/DeviceRGB]\n"
2780 " /DataSource [ 0 x1 y1 r1 g1 b1 0 x2 y2 r2 g2 b2 0 x3 y3 r3 g3 b3 ] >>\n"
2781 " shfill grestore } BD\n");
2787 "/Tm { 3 -1 roll 8 -1 roll 13 -1 roll add add 3 div\n"
2789 " 3 -1 roll 7 -1 roll 11 -1 roll add add 3 div\n"
2791 " 3 -1 roll 6 -1 roll 9 -1 roll add add 3 div"
2801 " 4 index 15 index add 0.5 mul\n"
2802 " 4 index 15 index add 0.5 mul\n"
2803 " 4 index 15 index add 0.5 mul\n"
2804 " 4 index 15 index add 0.5 mul\n"
2805 " 4 index 15 index add 0.5 mul\n"
2806 " 5 copy 5 copy 25 15 roll\n");
2811 " 9 index 30 index add 0.5 mul\n"
2812 " 9 index 30 index add 0.5 mul\n"
2813 " 9 index 30 index add 0.5 mul\n"
2814 " 9 index 30 index add 0.5 mul\n"
2815 " 5 copy 5 copy 35 5 roll 25 5 roll 15 5 roll\n");
2820 " 4 index 10 index add 0.5 mul\n"
2821 " 4 index 10 index add 0.5 mul\n"
2822 " 4 index 10 index add 0.5 mul\n"
2823 " 4 index 10 index add 0.5 mul\n"
2824 " 5 copy 5 copy 40 5 roll 25 5 roll 15 5 roll 25 5 roll\n");
2828 gl2psPrintf(
" STnoshfill STnoshfill STnoshfill STnoshfill } BD\n");
2835 " 2 index 8 index sub abs rThreshold gt\n"
2837 " { 1 index 7 index sub abs gThreshold gt\n"
2839 " { dup 6 index sub abs bThreshold gt\n"
2841 " { 2 index 13 index sub abs rThreshold gt\n"
2843 " { 1 index 12 index sub abs gThreshold gt\n"
2845 " { dup 11 index sub abs bThreshold gt\n"
2847 " { 7 index 13 index sub abs rThreshold gt\n");
2849 " { 6 index 12 index sub abs gThreshold gt\n"
2851 " { 5 index 11 index sub abs bThreshold gt\n"
2866 " { /ST { STshfill } BD }\n"
2867 " { /ST { STnoshfill } BD }\n"
2869 "{ /ST { STnoshfill } BD }\n"
2875 "/DeviceRGB setcolorspace\n"
2879 "%%%%BeginPageSetup\n");
2883 (
int)
gl2ps->viewport[3]);
2893 "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
2896 (
int)
gl2ps->viewport[0], (
int)
gl2ps->viewport[1], (
int)
gl2ps->viewport[2],
2897 (
int)
gl2ps->viewport[1], (
int)
gl2ps->viewport[2], (
int)
gl2ps->viewport[3],
2898 (
int)
gl2ps->viewport[0], (
int)
gl2ps->viewport[3]);
2906 gl2psPrintf(
"%g %g %g C\n", rgba[0], rgba[1], rgba[2]);
2918 if(
gl2ps->lastvertex.rgba[0] >= 0.){
2920 for(i = 0; i < 3; i++)
2921 gl2ps->lastvertex.xyz[i] = -1.;
2922 for(i = 0; i < 4; i++)
2923 gl2ps->lastvertex.rgba[i] = -1.;
2928 int *nb,
int array[10])
2931 int on[8] = {0, 0, 0, 0, 0, 0, 0, 0};
2932 int off[8] = {0, 0, 0, 0, 0, 0, 0, 0};
2936 for(n = 15; n >= 0; n--){
2937 tmp[
n] = (char)(pattern & 0x01);
2942 for(i = 0; i < 8; i++){
2943 while(n < 16 && !tmp[n]){ off[i]++; n++; }
2944 while(n < 16 && tmp[n]){ on[i]++; n++; }
2945 if(n >= 15){ i++;
break; }
2954 for(n = i - 1; n >= 0; n--){
2955 array[(*nb)++] = factor * on[
n];
2956 array[(*nb)++] = factor * off[
n];
2957 if(*nb == 10)
break;
2963 int len = 0, i,
n, array[10];
2965 if(pattern ==
gl2ps->lastpattern && factor ==
gl2ps->lastfactor)
2968 gl2ps->lastpattern = pattern;
2969 gl2ps->lastfactor = factor;
2971 if(!pattern || !factor){
2978 for(i = 0; i <
n; i++){
2991 GL2PSprimitive *prim;
2993 prim = *(GL2PSprimitive**)data;
3008 prim->verts[0].xyz[0], prim->verts[0].xyz[1], 0.5 * prim->width);
3013 gl2ps->lastlinewidth != prim->width ||
3014 gl2ps->lastpattern != prim->pattern ||
3015 gl2ps->lastfactor != prim->factor){
3028 if(
gl2ps->lastlinewidth != prim->width){
3029 gl2ps->lastlinewidth = prim->width;
3034 gl2psPrintf(
"%g %g %s\n", prim->verts[0].xyz[0], prim->verts[0].xyz[1],
3035 newline ?
"LS" :
"L");
3036 gl2ps->lastvertex = prim->verts[1];
3038 case GL2PS_TRIANGLE :
3041 gl2psPrintf(
"%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g ST\n",
3042 prim->verts[2].xyz[0], prim->verts[2].xyz[1],
3043 prim->verts[2].rgba[0], prim->verts[2].rgba[1],
3044 prim->verts[2].rgba[2], prim->verts[1].xyz[0],
3045 prim->verts[1].xyz[1], prim->verts[1].rgba[0],
3046 prim->verts[1].rgba[1], prim->verts[1].rgba[2],
3047 prim->verts[0].xyz[0], prim->verts[0].xyz[1],
3048 prim->verts[0].rgba[0], prim->verts[0].rgba[1],
3049 prim->verts[0].rgba[2]);
3054 prim->verts[2].xyz[0], prim->verts[2].xyz[1],
3055 prim->verts[1].xyz[0], prim->verts[1].xyz[1],
3056 prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
3059 case GL2PS_QUADRANGLE :
3066 case GL2PS_IMAGEMAP :
3067 if(prim->data.image->type != GL2PS_IMAGEMAP_WRITTEN){
3070 prim->data.image->pixels[1],
3071 prim->data.image->width, prim->data.image->height,
3072 (
const unsigned char*)(&(prim->data.image->pixels[2])));
3073 prim->data.image->type = GL2PS_IMAGEMAP_WRITTEN;
3079 if(prim->data.text->angle)
3082 prim->verts[0].xyz[0], prim->verts[0].xyz[1],
3083 prim->data.text->fontsize, prim->data.text->fontname);
3084 switch(prim->data.text->alignment){
3086 gl2psPrintf(prim->data.text->angle ?
"SCCR\n" :
"SCC\n");
3089 gl2psPrintf(prim->data.text->angle ?
"SCLR\n" :
"SCL\n");
3092 gl2psPrintf(prim->data.text->angle ?
"SCRR\n" :
"SCR\n");
3095 gl2psPrintf(prim->data.text->angle ?
"SBCR\n" :
"SBC\n");
3098 gl2psPrintf(prim->data.text->angle ?
"SBRR\n" :
"SBR\n");
3101 gl2psPrintf(prim->data.text->angle ?
"STCR\n" :
"STC\n");
3104 gl2psPrintf(prim->data.text->angle ?
"STLR\n" :
"STL\n");
3107 gl2psPrintf(prim->data.text->angle ?
"STRR\n" :
"STR\n");
3111 gl2psPrintf(prim->data.text->angle ?
"SR\n" :
"S\n");
3115 case GL2PS_SPECIAL :
3118 if(prim->data.text->alignment ==
GL2PS_PS ||
3119 prim->data.text->alignment ==
GL2PS_EPS)
3144 int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3];
3146 glRenderMode(GL_FEEDBACK);
3150 gl2ps->header = GL_FALSE;
3157 if(
gl2ps->colormode == GL_RGBA ||
gl2ps->colorsize == 0){
3158 glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
3161 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
3168 "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
3170 rgba[0], rgba[1], rgba[2],
3171 x, y, x+w, y, x+w, y+h, x, y+h);
3174 gl2psPrintf(
"newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
3176 x, y, x+w, y, x+w, y+h, x, y+h);
3197 static GL2PSbackend gl2psPS = {
3208 static GL2PSbackend gl2psEPS = {
3216 "Encapsulated Postscript"
3231 if(
gl2ps->filename && strlen(
gl2ps->filename) < 256){
3232 for(i = strlen(
gl2ps->filename)-1; i >= 0; i--){
3233 if(
gl2ps->filename[i] ==
'.'){
3234 strncpy(name,
gl2ps->filename, i);
3239 if(i <= 0) strcpy(name,
gl2ps->filename);
3242 strcpy(name,
"untitled");
3247 fprintf(
gl2ps->stream,
3249 "%% Creator: GL2PS %d.%d.%d%s, %s\n"
3251 "%% CreationDate:\n",
3256 fprintf(
gl2ps->stream,
3257 "\\setlength{\\unitlength}{1pt}\n"
3258 "\\begin{picture}(0,0)\n"
3259 "\\includegraphics{%s}\n"
3260 "\\end{picture}%%\n"
3261 "%s\\begin{picture}(%d,%d)(0,0)\n",
3263 (
int)
gl2ps->viewport[2], (
int)
gl2ps->viewport[3]);
3268 GL2PSprimitive *prim;
3270 prim = *(GL2PSprimitive**)data;
3274 fprintf(
gl2ps->stream,
"\\fontsize{%d}{0}\n\\selectfont",
3275 prim->data.text->fontsize);
3276 fprintf(
gl2ps->stream,
"\\put(%g,%g){\\makebox(0,0)",
3277 prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
3278 switch(prim->data.text->alignment){
3280 fprintf(
gl2ps->stream,
"{");
3283 fprintf(
gl2ps->stream,
"[l]{");
3286 fprintf(
gl2ps->stream,
"[r]{");
3289 fprintf(
gl2ps->stream,
"[b]{");
3292 fprintf(
gl2ps->stream,
"[br]{");
3295 fprintf(
gl2ps->stream,
"[t]{");
3298 fprintf(
gl2ps->stream,
"[tl]{");
3301 fprintf(
gl2ps->stream,
"[tr]{");
3305 fprintf(
gl2ps->stream,
"[bl]{");
3308 if(prim->data.text->angle)
3309 fprintf(
gl2ps->stream,
"\\rotatebox{%g}{", prim->data.text->angle);
3310 fprintf(
gl2ps->stream,
"\\textcolor[rgb]{%g,%g,%g}{{%s}}",
3311 prim->verts[0].rgba[0], prim->verts[0].rgba[1], prim->verts[0].rgba[2],
3312 prim->data.text->str);
3313 if(prim->data.text->angle)
3314 fprintf(
gl2ps->stream,
"}");
3315 fprintf(
gl2ps->stream,
"}}\n");
3317 case GL2PS_SPECIAL :
3320 if (prim->data.text->alignment ==
GL2PS_TEX)
3321 fprintf(
gl2ps->stream,
"%s\n", prim->data.text->str);
3330 fprintf(
gl2ps->stream,
"\\end{picture}%s\n",
3336 glRenderMode(GL_FEEDBACK);
3340 gl2ps->header = GL_FALSE;
3355 static GL2PSbackend gl2psTEX = {
3374 #if defined(GL2PS_HAVE_ZLIB)
3376 return fprintf(
gl2ps->stream,
"/Filter [/FlateDecode]\n");
3387 for(i = 0; i < 3; ++i){
3388 if(GL2PS_ZERO(rgba[i]))
3390 else if(rgba[i] < 1
e-4 || rgba[i] > 1e6)
3403 for(i = 0; i < 3; ++i){
3404 if(GL2PS_ZERO(rgba[i]))
3406 else if(rgba[i] < 1
e-4 || rgba[i] > 1e6)
3419 else if(lw < 1e-4 || lw > 1e6)
3425 static void gl2psPutPDFText(GL2PSstring *text,
int cnt, GLfloat x, GLfloat y)
3427 GLfloat
rad, crad, srad;
3429 if(text->angle == 0.0F){
3436 cnt, text->fontsize, x, y, text->str);
3439 rad =
M_PI * text->angle / 180.0F;
3440 srad = (GLfloat)sin(rad);
3441 crad = (GLfloat)cos(rad);
3445 "%f %f %f %f %f %f Tm\n"
3448 cnt, text->fontsize, crad, srad, -srad, crad, x, y, text->str);
3452 static void gl2psPutPDFImage(GL2PSimage *image,
int cnt, GLfloat x, GLfloat y)
3456 "%d 0 0 %d %f %f cm\n"
3459 (
int)image->width, (
int)image->height, x, y, cnt);
3464 gl2ps->objects_stack = 7 + 1;
3465 gl2ps->extgs_stack = 0;
3466 gl2ps->font_stack = 0;
3467 gl2ps->im_stack = 0;
3468 gl2ps->trgroupobjects_stack = 0;
3469 gl2ps->shader_stack = 0;
3470 gl2ps->mshader_stack = 0;
3478 gro->ptrlist = NULL;
3479 gro->fontno = gro->gsno = gro->imno = gro->maskshno = gro->shno
3480 = gro->trgroupno = gro->fontobjno = gro->imobjno = gro->shobjno
3481 = gro->maskshobjno = gro->gsobjno = gro->trgroupobjno = -1;
3489 GL2PSprimitive *p = NULL;
3491 int lasttype = GL2PS_NO_TYPE;
3492 GL2PSrgba lastrgba = {-1.0F, -1.0F, -1.0F, -1.0F};
3493 GLushort lastpattern = 0;
3494 GLint lastfactor = 0;
3495 GLfloat lastwidth = 1;
3496 GL2PStriangle lastt, tmpt;
3497 int lastTriangleWasNotSimpleWithSameColor = 0;
3499 if(!
gl2ps->pdfprimlist)
3511 gro.imno =
gl2ps->im_stack++;
3518 gro.fontno =
gl2ps->font_stack++;
3523 if(lasttype != p->type || lastwidth != p->width ||
3524 lastpattern != p->pattern || lastfactor != p->factor ||
3534 lastpattern = p->pattern;
3535 lastfactor = p->factor;
3536 lastwidth = p->width;
3537 lastrgba[0] = p->verts[0].rgba[0];
3538 lastrgba[1] = p->verts[0].rgba[1];
3539 lastrgba[2] = p->verts[0].rgba[2];
3542 if(lasttype != p->type || lastwidth != p->width ||
3552 lastwidth = p->width;
3553 lastrgba[0] = p->verts[0].rgba[0];
3554 lastrgba[1] = p->verts[0].rgba[1];
3555 lastrgba[2] = p->verts[0].rgba[2];
3557 case GL2PS_TRIANGLE:
3559 lastTriangleWasNotSimpleWithSameColor =
3560 !(tmpt.prop & T_CONST_COLOR && tmpt.prop & T_ALPHA_1) ||
3562 if(lasttype == p->type && tmpt.prop == lastt.prop &&
3563 lastTriangleWasNotSimpleWithSameColor){
3585 GL2PSprimitive *prim = NULL;
3595 if(prim->type != GL2PS_TRIANGLE)
3600 if(t.prop & T_CONST_COLOR && t.prop & T_ALPHA_LESS_1){
3601 gro->gsno =
gl2ps->extgs_stack++;
3602 gro->gsobjno =
gl2ps->objects_stack ++;
3604 else if(t.prop & T_CONST_COLOR && t.prop & T_VAR_ALPHA){
3605 gro->gsno =
gl2ps->extgs_stack++;
3606 gro->gsobjno =
gl2ps->objects_stack++;
3607 gro->trgroupno =
gl2ps->trgroupobjects_stack++;
3608 gro->trgroupobjno =
gl2ps->objects_stack++;
3609 gro->maskshno =
gl2ps->mshader_stack++;
3610 gro->maskshobjno =
gl2ps->objects_stack++;
3612 else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_1){
3613 gro->shno =
gl2ps->shader_stack++;
3614 gro->shobjno =
gl2ps->objects_stack++;
3616 else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_LESS_1){
3617 gro->gsno =
gl2ps->extgs_stack++;
3618 gro->gsobjno =
gl2ps->objects_stack++;
3619 gro->shno =
gl2ps->shader_stack++;
3620 gro->shobjno =
gl2ps->objects_stack++;
3622 else if(t.prop & T_VAR_COLOR && t.prop & T_VAR_ALPHA){
3623 gro->gsno =
gl2ps->extgs_stack++;
3624 gro->gsobjno =
gl2ps->objects_stack++;
3625 gro->shno =
gl2ps->shader_stack++;
3626 gro->shobjno =
gl2ps->objects_stack++;
3627 gro->trgroupno =
gl2ps->trgroupobjects_stack++;
3628 gro->trgroupobjno =
gl2ps->objects_stack++;
3629 gro->maskshno =
gl2ps->mshader_stack++;
3630 gro->maskshobjno =
gl2ps->objects_stack++;
3639 GL2PSprimitive *prim = NULL, *prev = NULL;
3643 if(!
gl2ps->pdfgrouplist)
3660 for(j = 0; j <= lastel; ++j){
3662 gl2ps->streamlength +=
3664 prim->verts[0].xyz[0], prim->verts[0].xyz[1],
3665 prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
3678 gl2ps->streamlength +=
3680 prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
3682 for(j = 1; j <= lastel; ++j){
3689 gl2ps->streamlength +=
3691 prev->verts[1].xyz[0], prev->verts[1].xyz[1]);
3692 gl2ps->streamlength +=
3694 prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
3699 gl2ps->streamlength +=
3701 prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
3705 gl2ps->streamlength +=
3707 prim->verts[1].xyz[0], prim->verts[1].xyz[1]);
3710 case GL2PS_TRIANGLE:
3715 if(t.prop & T_CONST_COLOR && t.prop & T_ALPHA_1){
3717 for(j = 0; j <= lastel; ++j){
3725 t.vertex[0].xyz[0], t.vertex[0].xyz[1],
3726 t.vertex[1].xyz[0], t.vertex[1].xyz[1],
3727 t.vertex[2].xyz[0], t.vertex[2].xyz[1]);
3732 else if(t.prop & T_CONST_COLOR && t.prop & T_ALPHA_LESS_1){
3737 for(j = 0; j <= lastel; ++j){
3745 t.vertex[0].xyz[0], t.vertex[0].xyz[1],
3746 t.vertex[1].xyz[0], t.vertex[1].xyz[1],
3747 t.vertex[2].xyz[0], t.vertex[2].xyz[1]);
3754 else if(t.prop & T_CONST_COLOR && t.prop & T_VAR_ALPHA){
3758 gro->gsno, gro->trgroupno);
3760 for(j = 0; j <= lastel; ++j){
3768 t.vertex[0].xyz[0], t.vertex[0].xyz[1],
3769 t.vertex[1].xyz[0], t.vertex[1].xyz[1],
3770 t.vertex[2].xyz[0], t.vertex[2].xyz[1]);
3776 else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_1){
3782 else if(t.prop & T_VAR_COLOR && t.prop & T_ALPHA_LESS_1){
3787 gro->gsno, gro->shno);
3792 else if(t.prop & T_VAR_COLOR && t.prop & T_VAR_ALPHA){
3798 gro->gsno, gro->trgroupno, gro->shno);
3802 for(j = 0; j <= lastel; ++j){
3805 prim->verts[0].xyz[1]);
3809 for(j = 0; j <= lastel; ++j){
3813 prim->verts[0].xyz[1]);
3830 offs += fprintf(
gl2ps->stream,
3837 offs += fprintf(
gl2ps->stream,
"/GS%d %d 0 R\n", gro->gsno, gro->gsobjno);
3839 offs += fprintf(
gl2ps->stream,
">>\n");
3851 offs += fprintf(
gl2ps->stream,
3857 offs += fprintf(
gl2ps->stream,
"/Sh%d %d 0 R\n", gro->shno, gro->shobjno);
3858 if(gro->maskshno >= 0)
3859 offs += fprintf(
gl2ps->stream,
"/TrSh%d %d 0 R\n", gro->maskshno, gro->maskshobjno);
3861 offs += fprintf(
gl2ps->stream,
">>\n");
3870 GL2PSprimitive *p = NULL;
3874 offs += fprintf(
gl2ps->stream,
3885 gro->imobjno =
gl2ps->objects_stack++;
3886 if(GL_RGBA == p->data.image->format)
3887 gl2ps->objects_stack++;
3888 offs += fprintf(
gl2ps->stream,
"/Im%d %d 0 R\n", gro->imno, gro->imobjno);
3889 case GL2PS_TRIANGLE:
3890 if(gro->trgroupno >=0)
3891 offs += fprintf(
gl2ps->stream,
"/TrG%d %d 0 R\n", gro->trgroupno, gro->trgroupobjno);
3897 offs += fprintf(
gl2ps->stream,
">>\n");
3909 offs += fprintf(
gl2ps->stream,
"/Font\n<<\n");
3915 gro->fontobjno =
gl2ps->objects_stack++;
3916 offs += fprintf(
gl2ps->stream,
"/F%d %d 0 R\n", gro->fontno, gro->fontobjno);
3918 offs += fprintf(
gl2ps->stream,
">>\n");
3926 GL2PSpdfgroup *gro = NULL;
3928 if(!
gl2ps->pdfgrouplist)
3937 gl2ps->pdfgrouplist = NULL;
3949 newtime = gmtime(&now);
3951 offs = fprintf(
gl2ps->stream,
3955 "/Creator (GL2PS %d.%d.%d%s, %s)\n"
3962 offs += fprintf(
gl2ps->stream,
3968 offs += fprintf(
gl2ps->stream,
3979 return fprintf(
gl2ps->stream,
3990 return fprintf(
gl2ps->stream,
4006 offs += fprintf(
gl2ps->stream,
4009 "/Length 5 0 R\n" );
4011 offs += fprintf(
gl2ps->stream,
4028 (
int)
gl2ps->viewport[0], (
int)
gl2ps->viewport[1],
4029 (
int)
gl2ps->viewport[2], (
int)
gl2ps->viewport[3]);
4045 #if defined(GL2PS_HAVE_ZLIB)
4050 gl2ps->xreflist[0] = 0;
4051 offs += fprintf(
gl2ps->stream,
"%%PDF-1.4\n");
4052 gl2ps->xreflist[1] = offs;
4055 gl2ps->xreflist[2] = offs;
4058 gl2ps->xreflist[3] = offs;
4061 gl2ps->xreflist[4] = offs;
4064 gl2ps->xreflist[5] = offs;
4072 GL2PSprimitive *prim = *(GL2PSprimitive**)data;
4087 #if defined(GL2PS_HAVE_ZLIB)
4092 fwrite(
gl2ps->compress->dest,
gl2ps->compress->destLen, 1,
gl2ps->stream);
4093 gl2ps->streamlength +=
gl2ps->compress->destLen;
4095 offs +=
gl2ps->streamlength;
4100 offs += fprintf(
gl2ps->stream,
4110 return fprintf(
gl2ps->stream,
4124 offs = fprintf(
gl2ps->stream,
4129 "/MediaBox [%d %d %d %d]\n",
4130 (
int)
gl2ps->viewport[0], (
int)
gl2ps->viewport[1],
4131 (
int)
gl2ps->viewport[2], (
int)
gl2ps->viewport[3]);
4134 offs += fprintf(
gl2ps->stream,
"/Rotate -90\n");
4136 offs += fprintf(
gl2ps->stream,
4140 "/ProcSet [/PDF /Text /ImageB /ImageC] %%/ImageI\n");
4164 offs += fprintf(
gl2ps->stream,
4175 return fprintf(
gl2ps->stream,
4178 "/Type /ExtGState\n"
4194 size_t (*action)(
unsigned long data,
4196 GLfloat dx, GLfloat dy,
4197 GLfloat xmin, GLfloat ymin)
4206 if(
sizeof(
unsigned long) == 8) dmax = dmax - 2048.;
4208 offs += (*action)(edgeflag, 1);
4213 if(GL2PS_ZERO(dx * dy)){
4214 offs += (*action)(0, 4);
4215 offs += (*action)(0, 4);
4218 diff = (vertex->xyz[0] - xmin) / dx;
4223 imap = (
unsigned long)(diff * dmax);
4224 offs += (*action)(imap, 4);
4226 diff = (vertex->xyz[1] - ymin) / dy;
4231 imap = (
unsigned long)(diff * dmax);
4232 offs += (*action)(imap, 4);
4241 size_t (*action)(
unsigned long data,
4249 if(
sizeof(
unsigned long) == 8) dmax = dmax - 2048.;
4251 imap = (
unsigned long)((vertex->rgba[0]) * dmax);
4252 offs += (*action)(imap, 1);
4254 imap = (
unsigned long)((vertex->rgba[1]) * dmax);
4255 offs += (*action)(imap, 1);
4257 imap = (
unsigned long)((vertex->rgba[2]) * dmax);
4258 offs += (*action)(imap, 1);
4266 size_t (*action)(
unsigned long data,
4275 if(
sizeof(
unsigned long) == 8) dmax = dmax - 2048.;
4277 if(sigbyte != 8 && sigbyte != 16)
4282 imap = (
unsigned long)((vertex->rgba[3]) * dmax);
4284 offs += (*action)(imap, sigbyte);
4292 GLfloat dx, GLfloat dy,
4293 GLfloat xmin, GLfloat ymin,
4294 size_t (*action)(
unsigned long data,
4301 if(gray && gray != 8 && gray != 16)
4304 for(i = 0; i < 3; ++i){
4306 dx, dy, xmin, ymin);
4308 v = triangle->vertex[i];
4320 GLfloat *ymin, GLfloat *ymax,
4321 GL2PStriangle *triangles,
int cnt)
4325 *xmin = triangles[0].vertex[0].xyz[0];
4326 *xmax = triangles[0].vertex[0].xyz[0];
4327 *ymin = triangles[0].vertex[0].xyz[1];
4328 *ymax = triangles[0].vertex[0].xyz[1];
4330 for(i = 0; i < cnt; ++i){
4331 for(j = 0; j < 3; ++j){
4332 if(*xmin > triangles[i].vertex[j].xyz[0])
4333 *xmin = triangles[i].vertex[j].xyz[0];
4334 if(*xmax < triangles[i].vertex[j].xyz[0])
4335 *xmax = triangles[i].vertex[j].xyz[0];
4336 if(*ymin > triangles[i].vertex[j].xyz[1])
4337 *ymin = triangles[i].vertex[j].xyz[1];
4338 if(*ymax < triangles[i].vertex[j].xyz[1])
4339 *ymax = triangles[i].vertex[j].xyz[1];
4352 int i, offs = 0, vertexbytes, done = 0;
4353 GLfloat xmin, xmax, ymin, ymax;
4357 vertexbytes = 1+4+4+1+1+1;
4360 vertexbytes = 1+4+4+1;
4363 vertexbytes = 1+4+4+2;
4367 vertexbytes = 1+4+4+1;
4373 offs += fprintf(
gl2ps->stream,
4378 "/BitsPerCoordinate 32 "
4379 "/BitsPerComponent %d "
4381 "/Decode [%f %f %f %f 0 1 %s] ",
4383 (gray) ?
"/DeviceGray" :
"/DeviceRGB",
4385 xmin, xmax, ymin, ymax,
4386 (gray) ?
"" :
"0 1 0 1");
4388 #if defined(GL2PS_HAVE_ZLIB)
4392 for(i = 0; i < size; ++i)
4394 xmax-xmin, ymax-ymin, xmin, ymin,
4399 offs += fprintf(
gl2ps->stream,
4403 (
int)
gl2ps->compress->destLen);
4404 offs +=
gl2ps->compress->destLen * fwrite(
gl2ps->compress->dest,
4405 gl2ps->compress->destLen,
4416 offs += fprintf(
gl2ps->stream,
4420 vertexbytes * 3 * size);
4421 for(i = 0; i < size; ++i)
4423 xmax-xmin, ymax-ymin, xmin, ymin,
4427 offs += fprintf(
gl2ps->stream,
4440 offs += fprintf(
gl2ps->stream,
4445 "/BBox [ %d %d %d %d ]\n"
4446 "/Group \n<<\n/S /Transparency /CS /DeviceRGB\n"
4449 (
int)
gl2ps->viewport[0], (
int)
gl2ps->viewport[1],
4450 (
int)
gl2ps->viewport[2], (
int)
gl2ps->viewport[3]);
4453 ? strlen(
"/TrSh sh\n") + (
int)log10((
double)childobj)+1
4454 : strlen(
"/TrSh0 sh\n");
4456 offs += fprintf(
gl2ps->stream,
4461 offs += fprintf(
gl2ps->stream,
4464 offs += fprintf(
gl2ps->stream,
4479 offs += fprintf(
gl2ps->stream,
4484 offs += fprintf(
gl2ps->stream,
4485 "/SMask << /S /Alpha /G %d 0 R >> ",
4488 offs += fprintf(
gl2ps->stream,
4500 offs += fprintf(
gl2ps->stream,
4513 size_t (*action)(
unsigned long data,
4520 if(im->format != GL_RGBA && gray)
4523 if(gray && gray != 8 && gray != 16)
4528 shift = (
sizeof(
unsigned long) - 1) * 8;
4530 for(y = 0; y < im->height; ++
y){
4531 for(x = 0; x < im->width; ++
x){
4533 if(im->format == GL_RGBA && gray){
4534 (*action)((
unsigned long)(a * 255) << shift,
gray);
4537 (*action)((
unsigned long)(r * 255) << shift, 1);
4538 (*action)((
unsigned long)(g * 255) << shift, 1);
4539 (*action)((
unsigned long)(b * 255) << shift, 1);
4545 case 0:
return 3 * im->width * im->height;
4546 case 1:
return im->width * im->height;
4547 case 2:
return 2 * im->width * im->height;
4548 default:
return 3 * im->width * im->height;
4554 int offs = 0, done = 0, sigbytes = 3;
4556 if(gray && gray !=8 && gray != 16)
4560 sigbytes = gray / 8;
4562 offs += fprintf(
gl2ps->stream,
4570 "/BitsPerComponent 8\n",
4572 (
int)im->width, (
int)im->height,
4573 (gray) ?
"/DeviceGray" :
"/DeviceRGB" );
4574 if(GL_RGBA == im->format && gray == 0){
4575 offs += fprintf(
gl2ps->stream,
4580 #if defined(GL2PS_HAVE_ZLIB)
4588 offs += fprintf(
gl2ps->stream,
4592 (
int)
gl2ps->compress->destLen);
4593 offs +=
gl2ps->compress->destLen * fwrite(
gl2ps->compress->dest,
gl2ps->compress->destLen,
4604 offs += fprintf(
gl2ps->stream,
4608 (
int)(im->width * im->height * sigbytes));
4612 offs += fprintf(
gl2ps->stream,
4623 offs += fprintf(
gl2ps->stream,
4630 "/Encoding /MacRomanEncoding\n"
4633 obj, fontnumber, s->fontname);
4642 GL2PSprimitive *p = NULL;
4644 int offs = entryoffs;
4645 GL2PStriangle *triangles;
4648 if(!
gl2ps->pdfgrouplist)
4661 case GL2PS_TRIANGLE:
4663 triangles = (GL2PStriangle*)
gl2psMalloc(
sizeof(GL2PStriangle) * size);
4664 for(j = 0; j < size; ++j){
4668 if(triangles[0].prop & T_VAR_COLOR){
4669 gl2ps->xreflist[gro->shobjno] = offs;
4672 if(triangles[0].prop & T_ALPHA_LESS_1){
4673 gl2ps->xreflist[gro->gsobjno] = offs;
4676 if(triangles[0].prop & T_VAR_ALPHA){
4677 gl2ps->xreflist[gro->gsobjno] = offs;
4679 gl2ps->xreflist[gro->trgroupobjno] = offs;
4681 gl2ps->xreflist[gro->maskshobjno] = offs;
4687 gl2ps->xreflist[gro->imobjno] = offs;
4689 if(p->data.image->format == GL_RGBA){
4690 gl2ps->xreflist[gro->imobjno+1] = offs;
4695 gl2ps->xreflist[gro->fontobjno] = offs;
4698 case GL2PS_SPECIAL :
4701 if(p->data.text->alignment ==
GL2PS_PDF)
4702 offs += fprintf(
gl2ps->stream,
"%s\n", p->data.text->str);
4722 offs =
gl2ps->xreflist[5] +
gl2ps->streamlength;
4724 gl2ps->xreflist[5] = offs;
4727 gl2ps->xreflist[6] = offs;
4728 gl2ps->streamlength = 0;
4733 sizeof(
int) * (
gl2ps->objects_stack + 1));
4734 gl2ps->xreflist[7] = offs;
4737 gl2ps->xreflist[8] = offs;
4744 fprintf(
gl2ps->stream,
4747 "%010d 65535 f \n",
gl2ps->objects_stack, 0);
4749 for(i = 1; i <
gl2ps->objects_stack; ++i)
4750 fprintf(
gl2ps->stream,
"%010d 00000 n \n",
gl2ps->xreflist[i]);
4752 fprintf(
gl2ps->stream,
4769 #if defined(GL2PS_HAVE_ZLIB)
4773 gl2ps->compress = NULL;
4785 int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3];
4787 glRenderMode(GL_FEEDBACK);
4791 gl2ps->header = GL_FALSE;
4797 if(
gl2ps->colormode == GL_RGBA ||
gl2ps->colorsize == 0){
4798 glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
4801 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
4820 gl2ps->streamlength += offs;
4838 static GL2PSbackend gl2psPDF = {
4846 "Portable Document Format"
4860 for(i = 0; i <
n; i++){
4861 xyz[i][0] = verts[i].xyz[0];
4862 xyz[i][1] =
gl2ps->viewport[3] - verts[i].xyz[1];
4864 for(j = 0; j < 4; j++)
4865 rgba[i][j] = verts[i].rgba[j];
4871 int r = (
int)(255. * rgba[0]);
4872 int g = (
int)(255. * rgba[1]);
4873 int b = (
int)(255. * rgba[2]);
4874 int rc = (r < 0) ? 0 : (r > 255) ? 255 : r;
4875 int gc = (g < 0) ? 0 : (g > 255) ? 255 : g;
4876 int bc = (b < 0) ? 0 : (b > 255) ? 255 : b;
4877 sprintf(str,
"#%2.2x%2.2x%2.2x", rc, gc, bc);
4882 int x,
y, width, height;
4890 y = (
int)
gl2ps->viewport[0];
4892 height = (
int)
gl2ps->viewport[2];
4896 y = (
int)
gl2ps->viewport[1];
4898 height = (
int)
gl2ps->viewport[3];
4904 gl2psPrintf(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
4905 gl2psPrintf(
"<svg xmlns=\"http://www.w3.org/2000/svg\"\n");
4906 gl2psPrintf(
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
4907 " width=\"%dpx\" height=\"%dpx\" viewBox=\"%d %d %d %d\">\n",
4908 width, height, x, y, width, height);
4922 gl2psPrintf(
"<polygon fill=\"%s\" points=\"%d,%d %d,%d %d,%d %d,%d\"/>\n", col,
4923 (
int)
gl2ps->viewport[0], (
int)
gl2ps->viewport[1],
4924 (
int)
gl2ps->viewport[2], (
int)
gl2ps->viewport[1],
4925 (
int)
gl2ps->viewport[2], (
int)
gl2ps->viewport[3],
4926 (
int)
gl2ps->viewport[0], (
int)
gl2ps->viewport[3]);
4930 gl2psPrintf(
"<g shape-rendering=\"crispEdges\">\n");
4947 if(rgba[0][3] < 1.0F)
gl2psPrintf(
"fill-opacity=\"%g\" ", rgba[0][3]);
4948 gl2psPrintf(
"points=\"%g,%g %g,%g %g,%g\"/>\n", xyz[0][0], xyz[0][1],
4949 xyz[1][0], xyz[1][1], xyz[2][0], xyz[2][1]);
4953 for(i = 0; i < 3; i++){
4954 xyz2[0][i] = xyz[0][i];
4955 xyz2[1][i] = 0.5F * (xyz[0][i] + xyz[1][i]);
4956 xyz2[2][i] = 0.5F * (xyz[0][i] + xyz[2][i]);
4958 for(i = 0; i < 4; i++){
4959 rgba2[0][i] = rgba[0][i];
4960 rgba2[1][i] = 0.5F * (rgba[0][i] + rgba[1][i]);
4961 rgba2[2][i] = 0.5F * (rgba[0][i] + rgba[2][i]);
4964 for(i = 0; i < 3; i++){
4965 xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[1][i]);
4966 xyz2[1][i] = xyz[1][i];
4967 xyz2[2][i] = 0.5F * (xyz[1][i] + xyz[2][i]);
4969 for(i = 0; i < 4; i++){
4970 rgba2[0][i] = 0.5F * (rgba[0][i] + rgba[1][i]);
4971 rgba2[1][i] = rgba[1][i];
4972 rgba2[2][i] = 0.5F * (rgba[1][i] + rgba[2][i]);
4975 for(i = 0; i < 3; i++){
4976 xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[2][i]);
4977 xyz2[1][i] = xyz[2][i];
4978 xyz2[2][i] = 0.5F * (xyz[1][i] + xyz[2][i]);
4980 for(i = 0; i < 4; i++){
4981 rgba2[0][i] = 0.5F * (rgba[0][i] + rgba[2][i]);
4982 rgba2[1][i] = rgba[2][i];
4983 rgba2[2][i] = 0.5F * (rgba[1][i] + rgba[2][i]);
4986 for(i = 0; i < 3; i++){
4987 xyz2[0][i] = 0.5F * (xyz[0][i] + xyz[1][i]);
4988 xyz2[1][i] = 0.5F * (xyz[1][i] + xyz[2][i]);
4989 xyz2[2][i] = 0.5F * (xyz[0][i] + xyz[2][i]);
4991 for(i = 0; i < 4; i++){
4992 rgba2[0][i] = 0.5F * (rgba[0][i] + rgba[1][i]);
4993 rgba2[1][i] = 0.5F * (rgba[1][i] + rgba[2][i]);
4994 rgba2[2][i] = 0.5F * (rgba[0][i] + rgba[2][i]);
5002 int i,
n, array[10];
5004 if(!pattern || !factor)
return;
5008 for(i = 0; i <
n; i++){
5018 if(
gl2ps->lastvertex.rgba[0] >= 0.){
5020 gl2ps->viewport[3] -
gl2ps->lastvertex.xyz[1]);
5021 for(i = 0; i < 3; i++)
5022 gl2ps->lastvertex.xyz[i] = -1.;
5023 for(i = 0; i < 4; i++)
5024 gl2ps->lastvertex.rgba[i] = -1.;
5028 #if defined(GL2PS_HAVE_LIBPNG)
5034 #if defined(GL2PS_HAVE_LIBPNG)
5046 sizeof(
unsigned char));
5049 gl2psPrintf(
"<image x=\"%g\" y=\"%g\" width=\"%d\" height=\"%d\"\n",
5050 x, y - pixmap->height, pixmap->width, pixmap->height);
5051 gl2psPrintf(
"xlink:href=\"data:image/png;base64,");
5060 "order to embed images in SVG streams");
5066 GL2PSprimitive *prim;
5072 prim = *(GL2PSprimitive**)data;
5087 if(rgba[0][3] < 1.0F)
gl2psPrintf(
"fill-opacity=\"%g\" ", rgba[0][3]);
5089 xyz[0][0], xyz[0][1], 0.5 * prim->width);
5094 gl2ps->lastlinewidth != prim->width ||
5095 gl2ps->lastpattern != prim->pattern ||
5096 gl2ps->lastfactor != prim->factor){
5107 gl2ps->lastvertex = prim->verts[1];
5109 gl2ps->lastlinewidth = prim->width;
5110 gl2ps->lastpattern = prim->pattern;
5111 gl2ps->lastfactor = prim->factor;
5114 gl2psPrintf(
"<polyline fill=\"none\" stroke=\"%s\" stroke-width=\"%g\" ",
5116 if(rgba[0][3] < 1.0F)
gl2psPrintf(
"stroke-opacity=\"%g\" ", rgba[0][3]);
5118 gl2psPrintf(
"points=\"%g,%g ", xyz[0][0], xyz[0][1]);
5124 case GL2PS_TRIANGLE :
5127 case GL2PS_QUADRANGLE :
5135 gl2psPrintf(
"<text fill=\"%s\" x=\"%g\" y=\"%g\" font-size=\"%d\" ",
5136 col, xyz[0][0], xyz[0][1], prim->data.text->fontsize);
5137 if(prim->data.text->angle)
5139 -prim->data.text->angle, xyz[0][0], xyz[0][1]);
5140 if(!strcmp(prim->data.text->fontname,
"Times-Roman"))
5142 else if(!strcmp(prim->data.text->fontname,
"Times-Bold"))
5143 gl2psPrintf(
"font-family=\"Times\" font-weight=\"bold\">");
5144 else if(!strcmp(prim->data.text->fontname,
"Times-Italic"))
5145 gl2psPrintf(
"font-family=\"Times\" font-style=\"italic\">");
5146 else if(!strcmp(prim->data.text->fontname,
"Times-BoldItalic"))
5147 gl2psPrintf(
"font-family=\"Times\" font-style=\"italic\" font-weight=\"bold\">");
5148 else if(!strcmp(prim->data.text->fontname,
"Helvetica-Bold"))
5149 gl2psPrintf(
"font-family=\"Helvetica\" font-weight=\"bold\">");
5150 else if(!strcmp(prim->data.text->fontname,
"Helvetica-Oblique"))
5151 gl2psPrintf(
"font-family=\"Helvetica\" font-style=\"oblique\">");
5152 else if(!strcmp(prim->data.text->fontname,
"Helvetica-BoldOblique"))
5153 gl2psPrintf(
"font-family=\"Helvetica\" font-style=\"oblique\" font-weight=\"bold\">");
5154 else if(!strcmp(prim->data.text->fontname,
"Courier-Bold"))
5155 gl2psPrintf(
"font-family=\"Courier\" font-weight=\"bold\">");
5156 else if(!strcmp(prim->data.text->fontname,
"Courier-Oblique"))
5157 gl2psPrintf(
"font-family=\"Courier\" font-style=\"oblique\">");
5158 else if(!strcmp(prim->data.text->fontname,
"Courier-BoldOblique"))
5159 gl2psPrintf(
"font-family=\"Courier\" font-style=\"oblique\" font-weight=\"bold\">");
5161 gl2psPrintf(
"font-family=\"%s\">", prim->data.text->fontname);
5164 case GL2PS_SPECIAL :
5167 if(prim->data.text->alignment ==
GL2PS_SVG)
5188 int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3];
5190 glRenderMode(GL_FEEDBACK);
5194 gl2ps->header = GL_FALSE;
5198 if(
gl2ps->colormode == GL_RGBA ||
gl2ps->colorsize == 0){
5199 glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
5202 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
5209 gl2psPrintf(
"<polygon fill=\"%s\" points=\"%d,%d %d,%d %d,%d %d,%d\"/>\n", col,
5210 x,
gl2ps->viewport[3] - y,
5211 x + w,
gl2ps->viewport[3] - y,
5212 x + w,
gl2ps->viewport[3] - (y + h),
5213 x,
gl2ps->viewport[3] - (y + h));
5216 gl2psPrintf(
"<clipPath id=\"cp%d%d%d%d\">\n", x, y, w, h);
5217 gl2psPrintf(
" <polygon points=\"%d,%d %d,%d %d,%d %d,%d\"/>\n",
5218 x,
gl2ps->viewport[3] - y,
5219 x + w,
gl2ps->viewport[3] - y,
5220 x + w,
gl2ps->viewport[3] - (y + h),
5221 x,
gl2ps->viewport[3] - (y + h));
5223 gl2psPrintf(
"<g clip-path=\"url(#cp%d%d%d%d)\">\n", x, y, w, h);
5243 static GL2PSbackend gl2psSVG = {
5251 "Scalable Vector Graphics"
5264 fprintf(
gl2ps->stream,
"\\color[rgb]{%f,%f,%f}\n", rgba[0], rgba[1], rgba[2]);
5274 fprintf(
gl2ps->stream,
5276 "%% Creator: GL2PS %d.%d.%d%s, %s\n"
5278 "%% CreationDate:\n",
5283 fprintf(
gl2ps->stream,
"\\begin{pgfpicture}\n");
5286 fprintf(
gl2ps->stream,
5287 "\\pgfpathrectanglecorners{"
5288 "\\pgfpoint{%dpt}{%dpt}}{\\pgfpoint{%dpt}{%dpt}}\n"
5289 "\\pgfusepath{fill}\n",
5290 (
int)
gl2ps->viewport[0], (
int)
gl2ps->viewport[1],
5291 (
int)
gl2ps->viewport[2], (
int)
gl2ps->viewport[3]);
5297 int i,
n, array[10];
5299 if(pattern ==
gl2ps->lastpattern && factor ==
gl2ps->lastfactor)
5302 gl2ps->lastpattern = pattern;
5303 gl2ps->lastfactor = factor;
5305 if(!pattern || !factor){
5307 fprintf(
gl2ps->stream,
"\\pgfsetdash{}{0pt}\n");
5311 fprintf(
gl2ps->stream,
"\\pgfsetdash{");
5312 for(i = 0; i <
n; i++) fprintf(
gl2ps->stream,
"{%dpt}", array[i]);
5313 fprintf(
gl2ps->stream,
"}{0pt}\n");
5329 default :
return "south west";
5335 GL2PSprimitive *prim;
5337 prim = *(GL2PSprimitive**)data;
5343 fprintf(
gl2ps->stream,
5344 "\\pgfpathrectangle{\\pgfpoint{%fpt}{%fpt}}"
5345 "{\\pgfpoint{%fpt}{%fpt}}\n\\pgfusepath{fill}\n",
5346 prim->verts[0].xyz[0]-0.5*prim->width,
5347 prim->verts[0].xyz[1]-0.5*prim->width,
5348 prim->width,prim->width);
5352 if(
gl2ps->lastlinewidth != prim->width){
5353 gl2ps->lastlinewidth = prim->width;
5354 fprintf(
gl2ps->stream,
"\\pgfsetlinewidth{%fpt}\n",
gl2ps->lastlinewidth);
5357 fprintf(
gl2ps->stream,
5358 "\\pgfpathmoveto{\\pgfpoint{%fpt}{%fpt}}\n"
5359 "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n"
5360 "\\pgfusepath{stroke}\n",
5361 prim->verts[1].xyz[0], prim->verts[1].xyz[1],
5362 prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
5364 case GL2PS_TRIANGLE :
5365 if(
gl2ps->lastlinewidth != 0){
5366 gl2ps->lastlinewidth = 0;
5367 fprintf(
gl2ps->stream,
"\\pgfsetlinewidth{0.01pt}\n");
5370 fprintf(
gl2ps->stream,
5371 "\\pgfpathmoveto{\\pgfpoint{%fpt}{%fpt}}\n"
5372 "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n"
5373 "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n"
5375 "\\pgfusepath{fill,stroke}\n",
5376 prim->verts[2].xyz[0], prim->verts[2].xyz[1],
5377 prim->verts[1].xyz[0], prim->verts[1].xyz[1],
5378 prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
5381 fprintf(
gl2ps->stream,
"{\n\\pgftransformshift{\\pgfpoint{%fpt}{%fpt}}\n",
5382 prim->verts[0].xyz[0], prim->verts[0].xyz[1]);
5384 if(prim->data.text->angle)
5385 fprintf(
gl2ps->stream,
"\\pgftransformrotate{%f}{", prim->data.text->angle);
5387 fprintf(
gl2ps->stream,
"\\pgfnode{rectangle}{%s}{\\fontsize{%d}{0}\\selectfont",
5389 prim->data.text->fontsize);
5391 fprintf(
gl2ps->stream,
"\\textcolor[rgb]{%g,%g,%g}{{%s}}",
5392 prim->verts[0].rgba[0], prim->verts[0].rgba[1],
5393 prim->verts[0].rgba[2], prim->data.text->str);
5395 fprintf(
gl2ps->stream,
"}{}{\\pgfusepath{discard}}}\n");
5397 case GL2PS_SPECIAL :
5400 if (prim->data.text->alignment ==
GL2PS_PGF)
5401 fprintf(
gl2ps->stream,
"%s\n", prim->data.text->str);
5410 fprintf(
gl2ps->stream,
"\\end{pgfpicture}\n");
5417 int x = viewport[0], y = viewport[1], w = viewport[2], h = viewport[3];
5419 glRenderMode(GL_FEEDBACK);
5423 gl2ps->header = GL_FALSE;
5426 fprintf(
gl2ps->stream,
"\\begin{pgfscope}\n");
5428 if(
gl2ps->colormode == GL_RGBA ||
gl2ps->colorsize == 0){
5429 glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
5432 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
5439 fprintf(
gl2ps->stream,
5440 "\\pgfpathrectangle{\\pgfpoint{%dpt}{%dpt}}"
5441 "{\\pgfpoint{%dpt}{%dpt}}\n"
5442 "\\pgfusepath{fill}\n",
5446 fprintf(
gl2ps->stream,
5447 "\\pgfpathrectangle{\\pgfpoint{%dpt}{%dpt}}"
5448 "{\\pgfpoint{%dpt}{%dpt}}\n"
5449 "\\pgfusepath{clip}\n",
5457 fprintf(
gl2ps->stream,
"\\end{pgfscope}\n");
5467 static GL2PSbackend gl2psPGF = {
5475 "PGF Latex Graphics"
5487 static GL2PSbackend *gl2psbackends[] = {
5498 GL2PSprimitive *prim;
5501 prim = *(GL2PSprimitive**)data;
5503 for(i = 0; i < prim->numverts; i++){
5504 if(prim->verts[i].xyz[0] <
gl2ps->viewport[0])
5505 gl2ps->viewport[0] = (GLint)prim->verts[i].xyz[0];
5506 if(prim->verts[i].xyz[0] >
gl2ps->viewport[2])
5507 gl2ps->viewport[2] = (GLint)(prim->verts[i].xyz[0] + 0.5F);
5508 if(prim->verts[i].xyz[1] <
gl2ps->viewport[1])
5509 gl2ps->viewport[1] = (GLint)prim->verts[i].xyz[1];
5510 if(prim->verts[i].xyz[1] >
gl2ps->viewport[3])
5511 gl2ps->viewport[3] = (GLint)(prim->verts[i].xyz[1] + 0.5F);
5518 GL2PSxyz eye = {0.0F, 0.0F, 100.0F * GL2PS_ZSCALE};
5521 used = glRenderMode(GL_RENDER);
5536 gl2ps->viewport[0] =
gl2ps->viewport[1] = 100000;
5537 gl2ps->viewport[2] =
gl2ps->viewport[3] = -100000;
5540 (gl2psbackends[
gl2ps->format]->printHeader)();
5541 gl2ps->header = GL_FALSE;
5549 switch(
gl2ps->sort){
5568 root = (GL2PSbsptree*)
gl2psMalloc(
sizeof(GL2PSbsptree));
5577 gl2psbackends[
gl2ps->format]->printPrimitive, 0);
5584 gl2psbackends[
gl2ps->format]->printFinalPrimitive();
5596 GLint viewport[4], GLint format, GLint
sort,
5597 GLint options, GLint colormode,
5599 GLint nr, GLint ng, GLint nb, GLint buffersize,
5600 FILE *stream,
const char *filename)
5612 if(format >= 0 && format < (GLint)(
sizeof(gl2psbackends) /
sizeof(gl2psbackends[0]))){
5613 gl2ps->format = format;
5636 gl2ps->stream = stream;
5645 gl2ps->header = GL_TRUE;
5646 gl2ps->maxbestroot = 10;
5647 gl2ps->options = options;
5648 gl2ps->compress = NULL;
5649 gl2ps->imagemap_head = NULL;
5650 gl2ps->imagemap_tail = NULL;
5653 glGetIntegerv(GL_VIEWPORT,
gl2ps->viewport);
5656 for(i = 0; i < 4; i++){
5657 gl2ps->viewport[i] = viewport[i];
5661 if(!
gl2ps->viewport[2] || !
gl2ps->viewport[3]){
5670 gl2ps->threshold[0] = nr ? 1.0F / (GLfloat)nr : 0.064F;
5671 gl2ps->threshold[1] = ng ? 1.0F / (GLfloat)ng : 0.034F;
5672 gl2ps->threshold[2] = nb ? 1.0F / (GLfloat)nb : 0.100F;
5673 gl2ps->colormode = colormode;
5674 gl2ps->buffersize = buffersize > 0 ? buffersize : 2048 * 2048;
5675 for(i = 0; i < 3; i++){
5676 gl2ps->lastvertex.xyz[i] = -1.0F;
5678 for(i = 0; i < 4; i++){
5679 gl2ps->lastvertex.rgba[i] = -1.0F;
5680 gl2ps->lastrgba[i] = -1.0F;
5682 gl2ps->lastlinewidth = -1.0F;
5683 gl2ps->lastpattern = 0;
5684 gl2ps->lastfactor = 0;
5685 gl2ps->imagetree = NULL;
5686 gl2ps->primitivetoadd = NULL;
5687 gl2ps->zerosurfacearea = GL_FALSE;
5688 gl2ps->pdfprimlist = NULL;
5689 gl2ps->pdfgrouplist = NULL;
5690 gl2ps->xreflist = NULL;
5695 glGetIntegerv(GL_BLEND_SRC, &
gl2ps->blendfunc[0]);
5696 glGetIntegerv(GL_BLEND_DST, &
gl2ps->blendfunc[1]);
5698 if(
gl2ps->colormode == GL_RGBA){
5699 gl2ps->colorsize = 0;
5700 gl2ps->colormap = NULL;
5701 glGetFloatv(GL_COLOR_CLEAR_VALUE,
gl2ps->bgcolor);
5703 else if(
gl2ps->colormode == GL_COLOR_INDEX){
5704 if(!colorsize || !colormap){
5710 gl2ps->colorsize = colorsize;
5713 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &index);
5717 gl2ps->bgcolor[3] = 1.0F;
5728 gl2ps->title[0] =
'\0';
5732 strcpy(
gl2ps->title, title);
5737 gl2ps->producer[0] =
'\0';
5741 strcpy(
gl2ps->producer, producer);
5746 gl2ps->filename[0] =
'\0';
5750 strcpy(
gl2ps->filename, filename);
5756 glFeedbackBuffer(
gl2ps->buffersize, GL_3D_COLOR,
gl2ps->feedback);
5757 glRenderMode(GL_FEEDBACK);
5771 (gl2psbackends[
gl2ps->format]->printFooter)();
5773 fflush(
gl2ps->stream);
5793 (gl2psbackends[
gl2ps->format]->beginViewport)(viewport);
5804 res = (gl2psbackends[
gl2ps->format]->endViewport)();
5807 gl2ps->lastlinewidth = -1.0F;
5813 GLshort fontsize, GLint alignment, GLfloat angle)
5815 return gl2psAddText(GL2PS_TEXT, str, fontname, fontsize, alignment, angle);
5825 return gl2psAddText(GL2PS_SPECIAL, str,
"", 0, format, 0.0F);
5829 GLint xorig, GLint yorig,
5830 GLenum format, GLenum type,
5834 GLfloat pos[4], *piv;
5835 GL2PSprimitive *prim;
5840 if((width <= 0) || (height <= 0))
return GL2PS_ERROR;
5844 if((format != GL_RGB && format != GL_RGBA) || type != GL_FLOAT){
5846 "GL_RGB/GL_RGBA, GL_FLOAT pixels");
5850 glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
5853 glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
5855 prim = (GL2PSprimitive*)
gl2psMalloc(
sizeof(GL2PSprimitive));
5856 prim->type = GL2PS_PIXMAP;
5859 prim->verts = (GL2PSvertex*)
gl2psMalloc(
sizeof(GL2PSvertex));
5860 prim->verts[0].xyz[0] = pos[0] + xorig;
5861 prim->verts[0].xyz[1] = pos[1] + yorig;
5862 prim->verts[0].xyz[2] = pos[2];
5868 glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba);
5869 prim->data.image = (GL2PSimage*)
gl2psMalloc(
sizeof(GL2PSimage));
5870 prim->data.image->width = width;
5871 prim->data.image->height = height;
5872 prim->data.image->format = format;
5873 prim->data.image->type = type;
5879 prim->data.image->format = GL_RGB;
5880 size = height * width * 3;
5881 prim->data.image->pixels = (GLfloat*)
gl2psMalloc(size *
sizeof(GLfloat));
5882 piv = (GLfloat*)pixels;
5883 for(i = 0; i < size; ++i, ++piv){
5884 prim->data.image->pixels[i] = *piv;
5890 size = height * width * 4;
5891 prim->data.image->pixels = (GLfloat*)
gl2psMalloc(size *
sizeof(GLfloat));
5892 memcpy(prim->data.image->pixels, pixels, size *
sizeof(GLfloat));
5897 size = height * width * 3;
5898 prim->data.image->pixels = (GLfloat*)
gl2psMalloc(size *
sizeof(GLfloat));
5899 memcpy(prim->data.image->pixels, pixels, size *
sizeof(GLfloat));
5904 glPassThrough(GL2PS_DRAW_PIXELS_TOKEN);
5911 const unsigned char *imagemap){
5913 int sizeoffloat =
sizeof(GLfloat);
5917 if((width <= 0) || (height <= 0))
return GL2PS_ERROR;
5919 size = height + height * ((width - 1) / 8);
5920 glPassThrough(GL2PS_IMAGEMAP_TOKEN);
5922 glVertex3f(position[0], position[1],position[2]);
5924 glPassThrough((GLfloat)width);
5925 glPassThrough((GLfloat)height);
5926 for(i = 0; i < size; i += sizeoffloat){
5927 float *
value = (
float*)imagemap;
5928 glPassThrough(*value);
5929 imagemap += sizeoffloat;
5942 glPassThrough(GL2PS_BEGIN_OFFSET_TOKEN);
5943 glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &
gl2ps->offset[0]);
5944 glGetFloatv(GL_POLYGON_OFFSET_UNITS, &
gl2ps->offset[1]);
5947 glPassThrough(GL2PS_BEGIN_BOUNDARY_TOKEN);
5950 glPassThrough(GL2PS_BEGIN_STIPPLE_TOKEN);
5951 glGetIntegerv(GL_LINE_STIPPLE_PATTERN, &tmp);
5952 glPassThrough((GLfloat)tmp);
5953 glGetIntegerv(GL_LINE_STIPPLE_REPEAT, &tmp);
5954 glPassThrough((GLfloat)tmp);
5957 glPassThrough(GL2PS_BEGIN_BLEND_TOKEN);
5973 glPassThrough(GL2PS_END_OFFSET_TOKEN);
5976 glPassThrough(GL2PS_END_BOUNDARY_TOKEN);
5979 glPassThrough(GL2PS_END_STIPPLE_TOKEN);
5982 glPassThrough(GL2PS_END_BLEND_TOKEN);
5996 glPassThrough(GL2PS_POINT_SIZE_TOKEN);
5997 glPassThrough(value);
6006 glPassThrough(GL2PS_LINE_WIDTH_TOKEN);
6007 glPassThrough(value);
6019 glPassThrough(GL2PS_SRC_BLEND_TOKEN);
6020 glPassThrough((GLfloat)sfactor);
6021 glPassThrough(GL2PS_DST_BLEND_TOKEN);
6022 glPassThrough((GLfloat)dfactor);
6031 gl2ps->options = options;
6043 *options =
gl2ps->options;
6050 if(format >= 0 && format < (GLint)(
sizeof(gl2psbackends) /
sizeof(gl2psbackends[0])))
6051 return gl2psbackends[format]->file_extension;
6053 return "Unknown format";
6058 if(format >= 0 && format < (GLint)(
sizeof(gl2psbackends) /
sizeof(gl2psbackends[0])))
6059 return gl2psbackends[format]->description;
6061 return "Unknown format";