44 #include <sys/types.h>
49 #if defined(GL2PS_HAVE_ZLIB)
53 #if defined(GL2PS_HAVE_LIBPNG)
66 #define GL2PS_EPSILON 5.0e-3F
67 #define GL2PS_ZSCALE 1000.0F
68 #define GL2PS_ZOFFSET 5.0e-2F
69 #define GL2PS_ZOFFSET_LARGE 20.0F
70 #define GL2PS_ZERO(arg) (fabs(arg) < 1.e-20)
74 #define GL2PS_NO_TYPE -1
78 #define GL2PS_QUADRANGLE 4
79 #define GL2PS_TRIANGLE 5
80 #define GL2PS_PIXMAP 6
81 #define GL2PS_IMAGEMAP 7
82 #define GL2PS_IMAGEMAP_WRITTEN 8
83 #define GL2PS_IMAGEMAP_VISIBLE 9
84 #define GL2PS_SPECIAL 10
88 #define GL2PS_COINCIDENT 1
89 #define GL2PS_IN_FRONT_OF 2
90 #define GL2PS_IN_BACK_OF 3
91 #define GL2PS_SPANNING 4
95 #define GL2PS_POINT_COINCIDENT 0
96 #define GL2PS_POINT_INFRONT 1
97 #define GL2PS_POINT_BACK 2
101 #define GL2PS_BEGIN_OFFSET_TOKEN 1
102 #define GL2PS_END_OFFSET_TOKEN 2
103 #define GL2PS_BEGIN_BOUNDARY_TOKEN 3
104 #define GL2PS_END_BOUNDARY_TOKEN 4
105 #define GL2PS_BEGIN_STIPPLE_TOKEN 5
106 #define GL2PS_END_STIPPLE_TOKEN 6
107 #define GL2PS_POINT_SIZE_TOKEN 7
108 #define GL2PS_LINE_WIDTH_TOKEN 8
109 #define GL2PS_BEGIN_BLEND_TOKEN 9
110 #define GL2PS_END_BLEND_TOKEN 10
111 #define GL2PS_SRC_BLEND_TOKEN 11
112 #define GL2PS_DST_BLEND_TOKEN 12
113 #define GL2PS_IMAGEMAP_TOKEN 13
114 #define GL2PS_DRAW_PIXELS_TOKEN 14
115 #define GL2PS_TEXT_TOKEN 15
198 #if defined(GL2PS_HAVE_ZLIB)
200 uLongf destLen, srcLen;
217 GLfloat *feedback,
offset[2], lastlinewidth;
218 GLint viewport[4], blendfunc[2], lastfactor;
255 void (*beginViewport)(GLint viewport[4]);
256 GLint (*endViewport)(void);
257 void (*printPrimitive)(
void *
data);
258 void (*printFinalPrimitive)(void);
270 static GLint gl2psPrintPrimitives(
void);
278 static void gl2psMsg(GLint
level,
const char *
fmt, ...)
296 static void *gl2psMalloc(
size_t size)
300 if(!
size)
return NULL;
303 gl2psMsg(
GL2PS_ERROR,
"Couldn't allocate requested memory");
309 static void *gl2psRealloc(
void *
ptr,
size_t size)
311 if(!
size)
return NULL;
314 gl2psMsg(
GL2PS_ERROR,
"Couldn't reallocate requested memory");
320 static void gl2psFree(
void *
ptr)
326 static size_t gl2psWriteBigEndian(
unsigned long data,
size_t bytes)
329 size_t size =
sizeof(
unsigned long);
330 for(
i = 1;
i <= bytes; ++
i){
338 #if defined(GL2PS_HAVE_ZLIB)
340 static void gl2psSetupCompress(
void)
350 static void gl2psFreeCompress(
void)
363 static int gl2psAllocCompress(
unsigned int srcsize)
379 static void *gl2psReallocCompress(
unsigned int srcsize)
384 if(srcsize < gl2ps->
compress->srcLen)
398 static size_t gl2psWriteBigEndianCompress(
unsigned long data,
size_t bytes)
401 size_t size =
sizeof(
unsigned long);
402 for(
i = 1;
i <= bytes; ++
i){
409 static int gl2psDeflate(
void)
419 static int gl2psPrintf(
const char*
fmt, ...)
424 #if defined(GL2PS_HAVE_ZLIB)
425 unsigned int oldsize = 0;
426 static char buf[1000];
429 ret = vsprintf(buf,
fmt,
args);
432 gl2ps->
compress->start = (Bytef*)gl2psReallocCompress(oldsize + ret);
433 memcpy(gl2ps->
compress->start+oldsize, buf, ret);
441 #if defined(GL2PS_HAVE_ZLIB)
447 static void gl2psPrintGzipHeader()
449 #if defined(GL2PS_HAVE_ZLIB)
450 char tmp[10] = {
'\x1f',
'\x8b',
458 gl2psSetupCompress();
465 static void gl2psPrintGzipFooter()
467 #if defined(GL2PS_HAVE_ZLIB)
473 if(Z_OK != gl2psDeflate()){
479 if(gl2ps->
compress->dest[1] & (1<<5)){
487 for(
n = 0;
n < 4; ++
n){
492 for(
n = 4;
n < 8; ++
n){
510 gl2psMsg(
GL2PS_ERROR,
"Cannot reallocate NULL list");
516 list->array = (
char*)gl2psMalloc(
list->nmax *
list->size);
521 list->array = (
char*)gl2psRealloc(
list->array,
527 static GL2PSlist *gl2psListCreate(GLint
n, GLint incr, GLint
size)
532 if(incr <= 0) incr = 1;
539 gl2psListRealloc(
list,
n);
552 gl2psFree(
list->array);
559 gl2psMsg(
GL2PS_ERROR,
"Cannot add into unallocated list");
577 gl2psMsg(
GL2PS_ERROR,
"Cannot point into unallocated list");
581 gl2psMsg(
GL2PS_ERROR,
"Wrong list index in gl2psListPointer");
588 int (*fcmp)(
const void *
a,
const void *
b))
599 for(
i = 0;
i < gl2psListNbr(
list);
i++){
600 (*action)(gl2psListPointer(
list,
i));
608 for(
i = gl2psListNbr(
list);
i > 0;
i--){
609 (*action)(gl2psListPointer(
list,
i-1));
613 #if defined(GL2PS_HAVE_LIBPNG)
618 gl2psMsg(
GL2PS_ERROR,
"Wrong list index in gl2psListRead");
622 static void gl2psEncodeBase64Block(
unsigned char in[3],
unsigned char out[4],
int len)
624 static const char cb64[] =
625 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
627 out[0] = cb64[ in[0] >> 2 ];
628 out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
629 out[2] = (len > 1) ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] :
'=';
630 out[3] = (len > 2) ? cb64[ in[2] & 0x3f ] :
'=';
639 buffer = (
unsigned char*)gl2psMalloc(
n *
sizeof(
unsigned char));
640 memcpy(
buffer,
list->array,
n *
sizeof(
unsigned char));
641 gl2psListReset(
list);
646 for(
i = 0;
i < 3;
i++) {
657 gl2psEncodeBase64Block(in,
out, len);
658 for(
i = 0;
i < 4;
i++)
690 static GLboolean gl2psSameColorThreshold(
int n,
GL2PSrgba rgba[],
695 if(
n < 2)
return GL_TRUE;
697 for(
i = 1;
i <
n;
i++){
698 if(fabs(rgba[0][0] - rgba[
i][0]) >
threshold[0] ||
699 fabs(rgba[0][1] - rgba[
i][1]) >
threshold[1] ||
707 static void gl2psSetLastColor(
GL2PSrgba rgba)
710 for(
i = 0;
i < 3; ++
i){
720 GLsizei height =
im->height;
721 GLfloat *pixels =
im->pixels;
727 pimag = pixels + 4 * (
width * (height - 1 -
y) +
x);
731 pimag = pixels + 3 * (
width * (height - 1 -
y) +
x);
734 *
red = *pimag; pimag++;
735 *
green = *pimag; pimag++;
736 *
blue = *pimag; pimag++;
738 return (
im->format == GL_RGBA) ? *pimag : 1.0F;
753 switch(
image->format){
763 image->pixels = (GLfloat*)gl2psMalloc(
size);
773 gl2psFree(
im->pixels);
777 #if defined(GL2PS_HAVE_LIBPNG)
779 #if !defined(png_jmpbuf)
780 # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
783 static void gl2psUserWritePNG(png_structp png_ptr, png_bytep
data, png_size_t
length)
788 gl2psListAdd(png, &
data[
i]);
791 static void gl2psUserFlushPNG(png_structp )
799 unsigned char *row_data;
803 if(!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))
806 if(!(info_ptr = png_create_info_struct(png_ptr))){
807 png_destroy_write_struct(&png_ptr, NULL);
811 if(setjmp(png_jmpbuf(png_ptr))) {
812 png_destroy_write_struct(&png_ptr, &info_ptr);
816 png_set_write_fn(png_ptr, (
void *)png, gl2psUserWritePNG, gl2psUserFlushPNG);
817 png_set_compression_level(png_ptr, Z_DEFAULT_COMPRESSION);
818 png_set_IHDR(png_ptr, info_ptr, pixmap->
width, pixmap->
height, 8,
819 PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
820 PNG_FILTER_TYPE_BASE);
821 png_write_info(png_ptr, info_ptr);
823 row_data = (
unsigned char*)gl2psMalloc(3 * pixmap->
width *
sizeof(
unsigned char));
827 row_data[3*
col] = (
unsigned char)(255. *
dr);
828 row_data[3*
col+1] = (
unsigned char)(255. *
dg);
829 row_data[3*
col+2] = (
unsigned char)(255. *
db);
831 png_write_row(png_ptr, (png_bytep)row_data);
835 png_write_end(png_ptr, info_ptr);
836 png_destroy_write_struct(&png_ptr, &info_ptr);
843 static GLint gl2psAddText(GLint
type,
const char *
str,
const char *fontname,
854 glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &
valid);
857 glGetFloatv(GL_CURRENT_RASTER_POSITION,
pos);
872 glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->
verts[0].
rgba);
874 prim->
data.
text->
str = (
char*)gl2psMalloc((strlen(
str)+1)*
sizeof(
char));
891 text->str = (
char*)gl2psMalloc((strlen(
t->str)+1)*
sizeof(
char));
892 strcpy(
text->str,
t->str);
893 text->fontname = (
char*)gl2psMalloc((strlen(
t->fontname)+1)*
sizeof(
char));
894 strcpy(
text->fontname,
t->fontname);
895 text->fontsize =
t->fontsize;
896 text->alignment =
t->alignment;
897 text->angle =
t->angle;
906 gl2psFree(
text->str);
907 gl2psFree(
text->fontname);
913 static GLboolean gl2psSupportedBlendMode(GLenum sfactor, GLenum dfactor)
918 if( (sfactor == GL_SRC_ALPHA && dfactor == GL_ONE_MINUS_SRC_ALPHA) ||
919 (sfactor == GL_ONE && dfactor == GL_ZERO) )
969 if(!
GL2PS_ZERO(
t->vertex[0].rgba[3] -
t->vertex[1].rgba[3]) ||
970 !
GL2PS_ZERO(
t->vertex[1].rgba[3] -
t->vertex[2].rgba[3])){
974 if(
t->vertex[0].rgba[3] < 1)
982 GLboolean assignprops)
984 t->vertex[0] =
p->verts[0];
985 t->vertex[1] =
p->verts[1];
986 t->vertex[2] =
p->verts[2];
987 if(GL_TRUE == assignprops)
988 gl2psAssignTriangleProperties(
t);
995 for(
i = 0;
i < 3;
i++)
1007 gl2psMsg(
GL2PS_ERROR,
"Trying to copy an empty primitive");
1013 prim->
type =
p->type;
1026 prim->
data.
image = gl2psCopyPixmap(
p->data.image);
1030 prim->
data.
text = gl2psCopyText(
p->data.text);
1056 return (plane[0] * point[0] +
1057 plane[1] * point[1] +
1058 plane[2] * point[2] +
1062 static GLfloat gl2psPsca(GLfloat *
a, GLfloat *
b)
1064 return (
a[0]*
b[0] +
a[1]*
b[1] +
a[2]*
b[2]);
1067 static void gl2psPvec(GLfloat *
a, GLfloat *
b, GLfloat *
c)
1069 c[0] =
a[1]*
b[2] -
a[2]*
b[1];
1070 c[1] =
a[2]*
b[0] -
a[0]*
b[2];
1071 c[2] =
a[0]*
b[1] -
a[1]*
b[0];
1074 static GLfloat gl2psNorm(GLfloat *
a)
1076 return (GLfloat)sqrt(
a[0]*
a[0] +
a[1]*
a[1] +
a[2]*
a[2]);
1079 static void gl2psGetNormal(GLfloat *
a, GLfloat *
b, GLfloat *
c)
1100 GL2PSxyz v = {0.0F, 0.0F, 0.0F},
w = {0.0F, 0.0F, 0.0F};
1113 plane[0] = plane[1] = 0.0F;
1118 gl2psGetNormal(
v,
w, plane);
1122 - plane[2] * prim->
verts[0].
xyz[2];
1130 plane[0] = plane[1] = 0.0F;
1138 gl2psGetNormal(
v,
w, plane);
1142 - plane[2] * prim->
verts[0].
xyz[2];
1150 plane[0] = plane[1] = 0.0F;
1155 gl2psMsg(
GL2PS_ERROR,
"Unknown primitive type in BSP tree");
1156 plane[0] = plane[1] = plane[3] = 0.0F;
1168 v[0] =
b->xyz[0] -
a->xyz[0];
1169 v[1] =
b->xyz[1] -
a->xyz[1];
1170 v[2] =
b->xyz[2] -
a->xyz[2];
1173 sect = -gl2psComparePointPlane(
a->xyz, plane) / psca;
1177 c->xyz[0] =
a->xyz[0] +
v[0] * sect;
1178 c->xyz[1] =
a->xyz[1] +
v[1] * sect;
1179 c->xyz[2] =
a->xyz[2] +
v[2] * sect;
1181 c->rgba[0] = (1 - sect) *
a->rgba[0] + sect *
b->rgba[0];
1182 c->rgba[1] = (1 - sect) *
a->rgba[1] + sect *
b->rgba[1];
1183 c->rgba[2] = (1 - sect) *
a->rgba[2] + sect *
b->rgba[2];
1184 c->rgba[3] = (1 - sect) *
a->rgba[3] + sect *
b->rgba[3];
1199 gl2psMsg(
GL2PS_WARNING,
"%d vertices in polygon", numverts);
1220 for(
i = 0;
i < numverts;
i++){
1226 plane, &child->
verts[
i]);
1231 static void gl2psAddIndex(GLshort *
index0, GLshort *
index1, GLshort *
nb,
1232 GLshort
i, GLshort j)
1236 for(
k = 0;
k < *
nb;
k++){
1245 static GLshort gl2psGetIndex(GLshort
i, GLshort
num)
1247 return (
i <
num - 1) ?
i + 1 : 0;
1257 d[
i] = gl2psComparePointPlane(prim->
verts[
i].
xyz, plane);
1284 GLshort
i(0), j(0), in = 0,
out = 0, in0[5], in1[5], out0[5], out1[5];
1285 for (
unsigned k=0;
k<5;++
k)
1286 in0[
k]=in1[
k]=out0[
k]=out1[
k]=0;
1293 d[
i] = gl2psComparePointPlane(prim->
verts[
i].
xyz, plane);
1309 gl2psAddIndex(in0, in1, &in,
i, j);
1310 gl2psAddIndex(out0, out1, &
out,
i, j);
1313 gl2psAddIndex(out0, out1, &
out, j, -1);
1319 gl2psAddIndex(in0, in1, &in,
i, j);
1320 gl2psAddIndex(out0, out1, &
out,
i, j);
1323 gl2psAddIndex(in0, in1, &in, j, -1);
1326 gl2psAddIndex(in0, in1, &in, j, -1);
1327 gl2psAddIndex(out0, out1, &
out, j, -1);
1336 gl2psCreateSplitPrimitive(prim, plane, *back,
out, out0, out1);
1337 gl2psCreateSplitPrimitive(prim, plane, *front, in, in0, in1);
1349 (*t1)->numverts = (*t2)->numverts = 3;
1350 (*t1)->culled = (*t2)->culled =
quad->culled;
1351 (*t1)->offset = (*t2)->offset =
quad->offset;
1352 (*t1)->pattern = (*t2)->pattern =
quad->pattern;
1353 (*t1)->factor = (*t2)->factor =
quad->factor;
1354 (*t1)->width = (*t2)->width =
quad->width;
1357 (*t1)->verts[0] =
quad->verts[0];
1358 (*t1)->verts[1] =
quad->verts[1];
1359 (*t1)->verts[2] =
quad->verts[2];
1360 (*t1)->boundary = ((
quad->boundary & 1) ? 1 : 0) | ((
quad->boundary & 2) ? 2 : 0);
1361 (*t2)->verts[0] =
quad->verts[0];
1362 (*t2)->verts[1] =
quad->verts[2];
1363 (*t2)->verts[2] =
quad->verts[3];
1364 (*t2)->boundary = ((
quad->boundary & 4) ? 2 : 0) | ((
quad->boundary & 4) ? 2 : 0);
1367 static int gl2psCompareDepth(
const void *
a,
const void *
b)
1370 GLfloat
dq = 0.0F, dw = 0.0F,
diff;
1376 for(
i = 0;
i <
q->numverts;
i++){
1377 dq +=
q->verts[
i].xyz[2];
1379 dq /= (GLfloat)
q->numverts;
1381 for(
i = 0; i < w->numverts;
i++){
1382 dw +=
w->verts[
i].xyz[2];
1384 dw /= (GLfloat)
w->numverts;
1398 static int gl2psTrianglesFirst(
const void *
a,
const void *
b)
1404 return (
q->type <
w->type ? 1 : -1);
1414 if(!gl2psListNbr(primitives)){
1415 gl2psMsg(
GL2PS_ERROR,
"Cannot fint root in empty primitive list");
1422 maxp = gl2psListNbr(primitives);
1426 for(
i = 0;
i < maxp;
i++){
1428 gl2psGetPlane(prim1, plane);
1430 for(j = 0; j < gl2psListNbr(primitives); j++){
1433 count += gl2psTestSplitPrimitive(prim2, plane);
1455 while(
list != NULL){
1457 gl2psFree(
list->image->pixels);
1458 gl2psFree(
list->image);
1464 static void gl2psFreePrimitive(
void *
data)
1469 gl2psFree(
q->verts);
1471 gl2psFreeText(
q->data.text);
1474 gl2psFreePixmap(
q->data.image);
1484 gl2psListAdd(
list, &prim);
1487 gl2psDivideQuad(prim, &
t1, &
t2);
1490 gl2psFreePrimitive(&prim);
1498 if((*tree)->back) gl2psFreeBspTree(&(*tree)->back);
1499 if((*tree)->primitives){
1500 gl2psListAction((*tree)->primitives, gl2psFreePrimitive);
1501 gl2psListDelete((*tree)->primitives);
1503 if((*tree)->front) gl2psFreeBspTree(&(*tree)->front);
1509 static GLboolean gl2psGreater(GLfloat
f1, GLfloat
f2)
1511 if(
f1 >
f2)
return GL_TRUE;
1512 else return GL_FALSE;
1515 static GLboolean gl2psLess(GLfloat
f1, GLfloat
f2)
1517 if(
f1 <
f2)
return GL_TRUE;
1518 else return GL_FALSE;
1523 GL2PSprimitive *prim =
nullptr, *frontprim =
nullptr, *backprim =
nullptr;
1527 tree->front =
nullptr;
1528 tree->back =
nullptr;
1530 index = gl2psFindRoot(primitives, &prim);
1531 gl2psGetPlane(prim,
tree->plane);
1532 gl2psAddPrimitiveInList(prim,
tree->primitives);
1537 for(
i = 0;
i < gl2psListNbr(primitives);
i++){
1540 switch(gl2psSplitPrimitive(prim,
tree->plane, &frontprim, &backprim)){
1542 gl2psAddPrimitiveInList(prim,
tree->primitives);
1545 gl2psAddPrimitiveInList(prim, backlist);
1548 gl2psAddPrimitiveInList(prim, frontlist);
1551 gl2psAddPrimitiveInList(backprim, backlist);
1552 gl2psAddPrimitiveInList(frontprim, frontlist);
1553 gl2psFreePrimitive(&prim);
1559 if(gl2psListNbr(
tree->primitives)){
1560 gl2psListSort(
tree->primitives, gl2psTrianglesFirst);
1563 if(gl2psListNbr(frontlist)){
1564 gl2psListSort(frontlist, gl2psTrianglesFirst);
1566 gl2psBuildBspTree(
tree->front, frontlist);
1569 gl2psListDelete(frontlist);
1572 if(gl2psListNbr(backlist)){
1573 gl2psListSort(backlist, gl2psTrianglesFirst);
1575 gl2psBuildBspTree(
tree->back, backlist);
1578 gl2psListDelete(backlist);
1581 gl2psListDelete(primitives);
1592 result = gl2psComparePointPlane(eye,
tree->plane);
1597 gl2psListActionInverse(
tree->primitives,
action);
1607 gl2psListActionInverse(
tree->primitives,
action);
1620 static void gl2psRescaleAndOffset()
1623 GLfloat minZ, maxZ, rangeZ, scaleZ;
1624 GLfloat factor,
units,
area, dZ, dZdX, dZdY, maxdZ;
1632 minZ = maxZ = prim->
verts[0].
xyz[2];
1639 for(j = 0; j < prim->
numverts; j++){
1644 rangeZ = (maxZ - minZ);
1650 if(scaleZ > 100000.
F) scaleZ = 100000.F;
1655 for(j = 0; j < prim->
numverts; j++){
1670 factor = gl2ps->
offset[0];
1688 maxdZ = (GLfloat)sqrt(dZdX * dZdX + dZdY * dZdY);
1693 dZ = factor * maxdZ +
units;
1711 plane[0] =
b[1] -
a[1];
1712 plane[1] =
a[0] -
b[0];
1713 n = (GLfloat)sqrt(plane[0]*plane[0] + plane[1]*plane[1]);
1718 plane[3] = -plane[0]*
a[0]-plane[1]*
a[1];
1732 if((*tree)->back) gl2psFreeBspImageTree(&(*tree)->back);
1733 if((*tree)->front) gl2psFreeBspImageTree(&(*tree)->front);
1743 pt_dis = gl2psComparePointPlane(point, plane);
1764 if(!gl2psGetPlaneFromPoints(prim->
verts[
i].
xyz,
1789 if(
cur->front == NULL){
1792 if(gl2psGetPlaneFromPoints(prim->
verts[
i].
xyz,
1794 cur->front->plane)){
1800 if(
cur->front == NULL){
1803 if(gl2psGetPlaneFromPoints(prim->
verts[
i].
xyz,
1805 cur->front->plane)){
1806 cur->front->front = NULL;
1807 cur->front->back = NULL;
1810 gl2psFree(
cur->front);
1815 for(
i = 0;
i < 4;
i++){
1820 if(
cur->front == NULL){
1823 if(gl2psGetPlaneFromPoints(prim->
verts[
i+1].
xyz,
1825 cur->front->plane)){
1831 if(
cur->front == NULL){
1836 cur->front->plane)){
1837 cur->front->front = NULL;
1838 cur->front->back = NULL;
1841 gl2psFree(
cur->front);
1896 for(
i = 0;
i < numverts;
i++){
1912 GLint
cur = -1, prev = -1,
i, v1 = 0,
v2 = 0,
flag = 1, prev0 = -1;
1915 GL2PSvertex *front_list = NULL, *back_list = NULL;
1918 GLshort front_count = 0, back_count = 0;
1929 cur = gl2psCheckPoint(prim->
verts[v1].
xyz, plane);
1934 if(((prev == -1) || (prev ==
cur) || (prev == 0) || (
cur == 0)) &&
1935 (i < prim->numverts)){
1938 front_list = (
GL2PSvertex*)gl2psRealloc(front_list,
1940 front_list[front_count-1] = prim->
verts[v1];
1946 back_list[back_count-1] = prim->
verts[v1];
1950 front_list = (
GL2PSvertex*)gl2psRealloc(front_list,
1952 front_list[front_count-1] = prim->
verts[v1];
1956 back_list[back_count-1] = prim->
verts[v1];
1960 else if((prev !=
cur) && (
cur != 0) && (prev != 0)){
1966 front_list = (
GL2PSvertex*)gl2psRealloc(front_list,
1969 plane, &front_list[front_count-1]);
1973 back_list[back_count-1] = front_list[front_count-1];
1978 *front = gl2psCreateSplitPrimitive2D(prim, front_count, front_list);
1979 *back = gl2psCreateSplitPrimitive2D(prim, back_count, back_list);
1980 gl2psFree(front_list);
1981 gl2psFree(back_list);
2005 switch(gl2psCheckPrimitive(prim, (*tree)->plane)){
2006 case GL2PS_IN_BACK_OF:
return gl2psAddInBspImageTree(prim, &(*tree)->back);
2008 if((*tree)->front != NULL)
return gl2psAddInBspImageTree(prim, &(*tree)->front);
2011 gl2psSplitPrimitive2D(prim, (*tree)->plane, &frontprim, &backprim);
2012 ret = gl2psAddInBspImageTree(backprim, &(*tree)->back);
2013 if((*tree)->front != NULL){
2014 if(gl2psAddInBspImageTree(frontprim, &(*tree)->front)){
2018 gl2psFree(frontprim->
verts);
2019 gl2psFree(frontprim);
2020 gl2psFree(backprim->verts);
2021 gl2psFree(backprim);
2024 if((*tree)->back != NULL){
2026 ret = gl2psAddInBspImageTree(prim, &(*tree)->back);
2030 if((*tree)->front != NULL){
2032 ret = gl2psAddInBspImageTree(prim, &(*tree)->front);
2043 static void gl2psAddInImageTree(
void *
data)
2050 else if(!gl2psAddInBspImageTree(prim, &gl2ps->
imagetree)){
2066 c[0] =
c[1] =
c[2] = 0.0F;
2091 norm = gl2psNorm(
v);
2094 b->verts[0].xyz[0] = prim->
verts[
i].
xyz[0] +0.1*
v[0];
2095 b->verts[0].xyz[1] = prim->
verts[
i].
xyz[1] +0.1*
v[1];
2099 norm = gl2psNorm(
v);
2114 b->verts[0].rgba[0] = 0.0F;
2115 b->verts[0].rgba[1] = 0.0F;
2116 b->verts[0].rgba[2] = 0.0F;
2117 b->verts[0].rgba[3] = 0.0F;
2118 b->verts[1].rgba[0] = 0.0F;
2119 b->verts[1].rgba[1] = 0.0F;
2120 b->verts[1].rgba[2] = 0.0F;
2121 b->verts[1].rgba[3] = 0.0F;
2122 gl2psListAdd(
list, &
b);
2134 gl2psBuildPolygonBoundary(
tree->back);
2135 for(
i = 0;
i < gl2psListNbr(
tree->primitives);
i++){
2137 if(prim->
boundary) gl2psAddBoundaryInList(prim,
tree->primitives);
2139 gl2psBuildPolygonBoundary(
tree->front);
2148 static void gl2psAddPolyPrimitive(GLshort
type, GLshort numverts,
2150 GLushort
pattern, GLint factor,
2151 GLfloat
width,
char boundary)
2182 i = (GLint)(
p[3] + 0.5);
2198 static void gl2psParseFeedbackBuffer(GLint
used)
2203 GLint
i, sizeoffloat,
count,
v, vtot,
offset = 0, factor = 0, auxindex = 0;
2204 GLfloat lwidth = 1.0F, psize = 1.0F;
2211 boundary = gl2ps->
boundary = GL_FALSE;
2215 if(GL_TRUE == boundary) gl2ps->
boundary = GL_TRUE;
2218 case GL_POINT_TOKEN :
2221 i = gl2psGetVertex(&vertices[0],
current);
2224 gl2psAddPolyPrimitive(
GL2PS_POINT, 1, vertices, 0,
2227 case GL_LINE_TOKEN :
2228 case GL_LINE_RESET_TOKEN :
2231 i = gl2psGetVertex(&vertices[0],
current);
2234 i = gl2psGetVertex(&vertices[1],
current);
2237 gl2psAddPolyPrimitive(
GL2PS_LINE, 2, vertices, 0,
2240 case GL_POLYGON_TOKEN :
2246 i = gl2psGetVertex(&vertices[
v],
current);
2247 gl2psAdaptVertexForBlending(&vertices[
v]);
2253 if(GL_TRUE == boundary){
2256 else if(vtot == 2)
flag = 1|2;
2263 vertices[1] = vertices[2];
2269 case GL_BITMAP_TOKEN :
2270 case GL_DRAW_PIXEL_TOKEN :
2271 case GL_COPY_PIXEL_TOKEN :
2274 i = gl2psGetVertex(&vertices[0],
current);
2278 case GL_PASS_THROUGH_TOKEN :
2330 node->image->format = 0;
2349 for(
i = 1;
i < 4;
i++){
2350 for(
v = 0;
v < 3;
v++){
2361 sizeoffloat =
sizeof(GLfloat);
2362 v = 2 * sizeoffloat;
2363 vtot =
node->image->height +
node->image->height *
2364 ((
node->image->width - 1) / 8);
2365 node->image->pixels = (GLfloat*)gl2psMalloc(
v + vtot);
2369 for(
i = 0;
i < vtot;
i += sizeoffloat){
2372 memcpy(&(((
char*)(
node->image->pixels))[
i +
v]), &(
current[2]), sizeoffloat);
2374 memcpy(&(((
char*)(
node->image->pixels))[
i +
v]), &(
current[2]), vtot -
i);
2385 gl2psMsg(
GL2PS_ERROR,
"Wrong number of auxiliary tokens in buffer");
2408 static void gl2psWriteByte(
unsigned char byte)
2410 unsigned char h =
byte / 16;
2411 unsigned char l =
byte % 16;
2412 gl2psPrintf(
"%x%x",
h,
l);
2415 static void gl2psPrintPostScriptPixmap(GLfloat
x, GLfloat
y,
GL2PSimage *
im)
2417 GLuint nbhex, nbyte, nrgb, nbits;
2418 GLuint
row,
col, ibyte, icase;
2419 GLfloat
dr,
dg,
db, fgrey;
2421 GLuint
width = (GLuint)
im->width;
2422 GLuint height = (GLuint)
im->height;
2434 if((
width <= 0) || (height <= 0))
return;
2436 gl2psPrintf(
"gsave\n");
2437 gl2psPrintf(
"%.2f %.2f translate\n",
x,
y);
2438 gl2psPrintf(
"%d %d scale\n",
width, height);
2441 gl2psPrintf(
"/picstr %d string def\n",
width);
2442 gl2psPrintf(
"%d %d %d\n",
width, height, 8);
2443 gl2psPrintf(
"[ %d 0 0 -%d 0 %d ]\n",
width, height, height);
2444 gl2psPrintf(
"{ currentfile picstr readhexstring pop }\n");
2445 gl2psPrintf(
"image\n");
2449 fgrey = (0.30F *
dr + 0.59F *
dg + 0.11F *
db);
2450 grey = (
unsigned char)(255. * fgrey);
2451 gl2psWriteByte(grey);
2455 nbhex =
width * height * 2;
2456 gl2psPrintf(
"%%%% nbhex digit :%d\n", nbhex);
2460 nbits = nrgb * nbit;
2462 if((nbyte * 8) != nbits) nbyte++;
2463 gl2psPrintf(
"/rgbstr %d string def\n", nbyte);
2464 gl2psPrintf(
"%d %d %d\n",
width, height, nbit);
2465 gl2psPrintf(
"[ %d 0 0 -%d 0 %d ]\n",
width, height, height);
2466 gl2psPrintf(
"{ currentfile rgbstr readhexstring pop }\n");
2467 gl2psPrintf(
"false 3\n");
2468 gl2psPrintf(
"colorimage\n");
2473 for(ibyte = 0; ibyte < nbyte; ibyte++){
2503 else if(icase == 2) {
2522 else if(icase == 3) {
2547 nbits = nrgb * nbit;
2549 if((nbyte * 8) != nbits) nbyte++;
2550 gl2psPrintf(
"/rgbstr %d string def\n", nbyte);
2551 gl2psPrintf(
"%d %d %d\n",
width, height, nbit);
2552 gl2psPrintf(
"[ %d 0 0 -%d 0 %d ]\n",
width, height, height);
2553 gl2psPrintf(
"{ currentfile rgbstr readhexstring pop }\n");
2554 gl2psPrintf(
"false 3\n");
2555 gl2psPrintf(
"colorimage\n");
2559 for(ibyte = 0; ibyte < nbyte; ibyte++){
2573 else if(icase == 2) {
2583 gl2psPrintf(
"%x%x",
blue,
red);
2586 else if(icase == 3) {
2598 gl2psPrintf(
"/rgbstr %d string def\n", nbyte);
2599 gl2psPrintf(
"%d %d %d\n",
width, height, 8);
2600 gl2psPrintf(
"[ %d 0 0 -%d 0 %d ]\n",
width, height, height);
2601 gl2psPrintf(
"{ currentfile rgbstr readhexstring pop }\n");
2602 gl2psPrintf(
"false 3\n");
2603 gl2psPrintf(
"colorimage\n");
2608 gl2psWriteByte(
red);
2610 gl2psWriteByte(
green);
2612 gl2psWriteByte(
blue);
2618 gl2psPrintf(
"grestore\n");
2621 static void gl2psPrintPostScriptImagemap(GLfloat
x, GLfloat
y,
2622 GLsizei
width, GLsizei height,
2623 const unsigned char *imagemap){
2626 if((
width <= 0) || (height <= 0))
return;
2628 size = height + height * (
width - 1) / 8;
2630 gl2psPrintf(
"gsave\n");
2631 gl2psPrintf(
"%.2f %.2f translate\n",
x,
y);
2632 gl2psPrintf(
"%d %d scale\n%d %d\ntrue\n",
width, height,
width, height);
2633 gl2psPrintf(
"[ %d 0 0 -%d 0 %d ] {<",
width, height);
2635 gl2psWriteByte(*imagemap);
2638 gl2psPrintf(
">} imagemask\ngrestore\n");
2641 static void gl2psPrintPostScriptHeader(
void)
2648 gl2psPrintGzipHeader();
2653 gl2psPrintf(
"%%!PS-Adobe-3.0\n");
2656 gl2psPrintf(
"%%!PS-Adobe-3.0 EPSF-3.0\n");
2659 gl2psPrintf(
"%%%%Title: %s\n"
2660 "%%%%Creator: GL2PS %d.%d.%d%s, %s\n"
2662 "%%%%CreationDate: %s"
2663 "%%%%LanguageLevel: 3\n"
2664 "%%%%DocumentData: Clean7Bit\n"
2671 gl2psPrintf(
"%%%%Orientation: %s\n"
2672 "%%%%DocumentMedia: Default %d %d 0 () ()\n",
2680 gl2psPrintf(
"%%%%BoundingBox: %d %d %d %d\n"
2681 "%%%%EndComments\n",
2704 gl2psPrintf(
"%%%%BeginProlog\n"
2705 "/gl2psdict 64 dict def gl2psdict begin\n"
2706 "0 setlinecap 0 setlinejoin\n"
2707 "/tryPS3shading %s def %% set to false to force subdivision\n"
2708 "/rThreshold %g def %% red component subdivision threshold\n"
2709 "/gThreshold %g def %% green component subdivision threshold\n"
2710 "/bThreshold %g def %% blue component subdivision threshold\n",
2714 gl2psPrintf(
"/BD { bind def } bind def\n"
2715 "/C { setrgbcolor } BD\n"
2716 "/G { 0.082 mul exch 0.6094 mul add exch 0.3086 mul add neg 1.0 add setgray } BD\n"
2717 "/W { setlinewidth } BD\n");
2719 gl2psPrintf(
"/FC { findfont exch /SH exch def SH scalefont setfont } BD\n"
2720 "/SW { dup stringwidth pop } BD\n"
2721 "/S { FC moveto show } BD\n"
2722 "/SBC{ FC moveto SW -2 div 0 rmoveto show } BD\n"
2723 "/SBR{ FC moveto SW neg 0 rmoveto show } BD\n"
2724 "/SCL{ FC moveto 0 SH -2 div rmoveto show } BD\n"
2725 "/SCC{ FC moveto SW -2 div SH -2 div rmoveto show } BD\n"
2726 "/SCR{ FC moveto SW neg SH -2 div rmoveto show } BD\n"
2727 "/STL{ FC moveto 0 SH neg rmoveto show } BD\n"
2728 "/STC{ FC moveto SW -2 div SH neg rmoveto show } BD\n"
2729 "/STR{ FC moveto SW neg SH neg rmoveto show } BD\n");
2733 gl2psPrintf(
"/FCT { FC translate 0 0 } BD\n"
2734 "/SR { gsave FCT moveto rotate show grestore } BD\n"
2735 "/SBCR{ gsave FCT moveto rotate SW -2 div 0 rmoveto show grestore } BD\n"
2736 "/SBRR{ gsave FCT moveto rotate SW neg 0 rmoveto show grestore } BD\n"
2737 "/SCLR{ gsave FCT moveto rotate 0 SH -2 div rmoveto show grestore} BD\n");
2738 gl2psPrintf(
"/SCCR{ gsave FCT moveto rotate SW -2 div SH -2 div rmoveto show grestore} BD\n"
2739 "/SCRR{ gsave FCT moveto rotate SW neg SH -2 div rmoveto show grestore} BD\n"
2740 "/STLR{ gsave FCT moveto rotate 0 SH neg rmoveto show grestore } BD\n"
2741 "/STCR{ gsave FCT moveto rotate SW -2 div SH neg rmoveto show grestore } BD\n"
2742 "/STRR{ gsave FCT moveto rotate SW neg SH neg rmoveto show grestore } BD\n");
2744 gl2psPrintf(
"/P { newpath 0.0 360.0 arc closepath fill } BD\n"
2745 "/LS { newpath moveto } BD\n"
2746 "/L { lineto } BD\n"
2747 "/LE { lineto stroke } BD\n"
2748 "/T { newpath moveto lineto lineto closepath fill } BD\n");
2753 gl2psPrintf(
"/STshfill {\n"
2754 " /b1 exch def /g1 exch def /r1 exch def /y1 exch def /x1 exch def\n"
2755 " /b2 exch def /g2 exch def /r2 exch def /y2 exch def /x2 exch def\n"
2756 " /b3 exch def /g3 exch def /r3 exch def /y3 exch def /x3 exch def\n"
2757 " gsave << /ShadingType 4 /ColorSpace [/DeviceRGB]\n"
2758 " /DataSource [ 0 x1 y1 r1 g1 b1 0 x2 y2 r2 g2 b2 0 x3 y3 r3 g3 b3 ] >>\n"
2759 " shfill grestore } BD\n");
2765 "/Tm { 3 -1 roll 8 -1 roll 13 -1 roll add add 3 div\n"
2767 " 3 -1 roll 7 -1 roll 11 -1 roll add add 3 div\n"
2769 " 3 -1 roll 6 -1 roll 9 -1 roll add add 3 div"
2778 gl2psPrintf(
"/STsplit {\n"
2779 " 4 index 15 index add 0.5 mul\n"
2780 " 4 index 15 index add 0.5 mul\n"
2781 " 4 index 15 index add 0.5 mul\n"
2782 " 4 index 15 index add 0.5 mul\n"
2783 " 4 index 15 index add 0.5 mul\n"
2784 " 5 copy 5 copy 25 15 roll\n");
2788 gl2psPrintf(
" 9 index 30 index add 0.5 mul\n"
2789 " 9 index 30 index add 0.5 mul\n"
2790 " 9 index 30 index add 0.5 mul\n"
2791 " 9 index 30 index add 0.5 mul\n"
2792 " 9 index 30 index add 0.5 mul\n"
2793 " 5 copy 5 copy 35 5 roll 25 5 roll 15 5 roll\n");
2797 gl2psPrintf(
" 4 index 10 index add 0.5 mul\n"
2798 " 4 index 10 index add 0.5 mul\n"
2799 " 4 index 10 index add 0.5 mul\n"
2800 " 4 index 10 index add 0.5 mul\n"
2801 " 4 index 10 index add 0.5 mul\n"
2802 " 5 copy 5 copy 40 5 roll 25 5 roll 15 5 roll 25 5 roll\n");
2806 gl2psPrintf(
" STnoshfill STnoshfill STnoshfill STnoshfill } BD\n");
2812 gl2psPrintf(
"/STnoshfill {\n"
2813 " 2 index 8 index sub abs rThreshold gt\n"
2815 " { 1 index 7 index sub abs gThreshold gt\n"
2817 " { dup 6 index sub abs bThreshold gt\n"
2819 " { 2 index 13 index sub abs rThreshold gt\n"
2821 " { 1 index 12 index sub abs gThreshold gt\n"
2823 " { dup 11 index sub abs bThreshold gt\n"
2825 " { 7 index 13 index sub abs rThreshold gt\n");
2826 gl2psPrintf(
" { STsplit }\n"
2827 " { 6 index 12 index sub abs gThreshold gt\n"
2829 " { 5 index 11 index sub abs bThreshold gt\n"
2842 gl2psPrintf(
"tryPS3shading\n"
2844 " { /ST { STshfill } BD }\n"
2845 " { /ST { STnoshfill } BD }\n"
2847 "{ /ST { STnoshfill } BD }\n"
2853 "/DeviceRGB setcolorspace\n"
2857 "%%%%BeginPageSetup\n");
2860 gl2psPrintf(
"%d 0 translate 90 rotate\n",
2864 gl2psPrintf(
"%%%%EndPageSetup\n"
2870 gl2psPrintf(
"%g %g %g C\n"
2871 "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
2880 static void gl2psPrintPostScriptColor(
GL2PSrgba rgba)
2882 if(!gl2psSameColor(gl2ps->
lastrgba, rgba)){
2883 gl2psSetLastColor(rgba);
2884 gl2psPrintf(
"%g %g %g C\n", rgba[0], rgba[1], rgba[2]);
2888 static void gl2psResetPostScriptColor(
void)
2893 static void gl2psEndPostScriptLine(
void)
2898 for(
i = 0;
i < 3;
i++)
2900 for(
i = 0;
i < 4;
i++)
2905 static void gl2psParseStipplePattern(GLushort
pattern, GLint factor,
2909 int on[8] = {0, 0, 0, 0, 0, 0, 0, 0};
2910 int off[8] = {0, 0, 0, 0, 0, 0, 0, 0};
2914 for(
n = 15;
n >= 0;
n--){
2920 for(
i = 0;
i < 8;
i++){
2921 while(
n < 16 && !
tmp[
n]){ off[
i]++;
n++; }
2922 while(
n < 16 &&
tmp[
n]){ on[
i]++;
n++; }
2923 if(
n >= 15){
i++;
break; }
2932 for(
n =
i - 1;
n >= 0 && *
nb <= 8;
n--){
2933 array[(*nb)++] = factor * on[
n];
2934 array[(*nb)++] = factor * off[
n];
2938 static int gl2psPrintPostScriptDash(GLushort
pattern, GLint factor,
const char *
str)
2950 len += gl2psPrintf(
"[] 0 %s\n",
str);
2954 len += gl2psPrintf(
"[");
2955 for(
i = 0;
i <
n;
i++){
2956 if(
i) len += gl2psPrintf(
" ");
2957 len += gl2psPrintf(
"%d",
array[
i]);
2959 len += gl2psPrintf(
"] 0 %s\n",
str);
2965 static void gl2psPrintPostScriptPrimitive(
void *
data)
2983 gl2psPrintPostScriptColor(prim->
verts[0].
rgba);
2984 gl2psPrintf(
"%g %g %g P\n",
2999 gl2psEndPostScriptLine();
3009 gl2psPrintPostScriptDash(prim->
pattern, prim->
factor,
"setdash");
3010 gl2psPrintPostScriptColor(prim->
verts[0].
rgba);
3016 if(!gl2psVertsSameColor(prim)){
3017 gl2psResetPostScriptColor();
3018 gl2psPrintf(
"%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g ST\n",
3029 gl2psPrintPostScriptColor(prim->
verts[0].
rgba);
3030 gl2psPrintf(
"%g %g %g %g %g %g T\n",
3037 gl2psMsg(
GL2PS_WARNING,
"There should not be any quad left to print");
3045 gl2psPrintPostScriptColor(prim->
verts[0].
rgba);
3054 gl2psPrintPostScriptColor(prim->
verts[0].
rgba);
3058 gl2psPrintf(
"%g %g %d /%s ",
3104 static void gl2psPrintPostScriptFooter(
void)
3106 gl2psPrintf(
"grestore\n"
3114 gl2psPrintGzipFooter();
3117 static void gl2psPrintPostScriptBeginViewport(GLint viewport[4])
3121 int x = viewport[0],
y = viewport[1],
w = viewport[2],
h = viewport[3];
3123 glRenderMode(GL_FEEDBACK);
3126 gl2psPrintPostScriptHeader();
3127 gl2ps->
header = GL_FALSE;
3130 gl2psPrintf(
"gsave\n"
3135 glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
3138 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &
index);
3144 gl2psPrintf(
"%g %g %g C\n"
3145 "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
3147 rgba[0], rgba[1], rgba[2],
3151 gl2psPrintf(
"newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto\n"
3157 static GLint gl2psPrintPostScriptEndViewport(
void)
3161 res = gl2psPrintPrimitives();
3162 gl2psPrintf(
"grestore\n");
3166 static void gl2psPrintPostScriptFinalPrimitive(
void)
3169 gl2psEndPostScriptLine();
3175 gl2psPrintPostScriptHeader,
3176 gl2psPrintPostScriptFooter,
3177 gl2psPrintPostScriptBeginViewport,
3178 gl2psPrintPostScriptEndViewport,
3179 gl2psPrintPostScriptPrimitive,
3180 gl2psPrintPostScriptFinalPrimitive,
3186 gl2psPrintPostScriptHeader,
3187 gl2psPrintPostScriptFooter,
3188 gl2psPrintPostScriptBeginViewport,
3189 gl2psPrintPostScriptEndViewport,
3190 gl2psPrintPostScriptPrimitive,
3191 gl2psPrintPostScriptFinalPrimitive,
3193 "Encapsulated Postscript"
3202 static void gl2psPrintTeXHeader(
void)
3219 strcpy(
name,
"untitled");
3226 "%% Creator: GL2PS %d.%d.%d%s, %s\n"
3228 "%% CreationDate: %s",
3234 "\\setlength{\\unitlength}{1pt}\n"
3235 "\\begin{picture}(0,0)\n"
3236 "\\includegraphics{%s}\n"
3237 "\\end{picture}%%\n"
3238 "%s\\begin{picture}(%d,%d)(0,0)\n",
3243 static void gl2psPrintTeXPrimitive(
void *
data)
3251 fprintf(gl2ps->
stream,
"\\fontsize{%d}{0}\n\\selectfont",
3253 fprintf(gl2ps->
stream,
"\\put(%g,%g){\\makebox(0,0)",
3257 fprintf(gl2ps->
stream,
"{");
3260 fprintf(gl2ps->
stream,
"[l]{");
3263 fprintf(gl2ps->
stream,
"[r]{");
3266 fprintf(gl2ps->
stream,
"[b]{");
3269 fprintf(gl2ps->
stream,
"[br]{");
3272 fprintf(gl2ps->
stream,
"[t]{");
3275 fprintf(gl2ps->
stream,
"[tl]{");
3278 fprintf(gl2ps->
stream,
"[tr]{");
3282 fprintf(gl2ps->
stream,
"[bl]{");
3287 fprintf(gl2ps->
stream,
"\\textcolor[rgb]{%g,%g,%g}{{%s}}",
3291 fprintf(gl2ps->
stream,
"}");
3292 fprintf(gl2ps->
stream,
"}}\n");
3305 static void gl2psPrintTeXFooter(
void)
3307 fprintf(gl2ps->
stream,
"\\end{picture}%s\n",
3311 static void gl2psPrintTeXBeginViewport(GLint viewport[4])
3314 glRenderMode(GL_FEEDBACK);
3317 gl2psPrintTeXHeader();
3318 gl2ps->
header = GL_FALSE;
3322 static GLint gl2psPrintTeXEndViewport(
void)
3324 return gl2psPrintPrimitives();
3327 static void gl2psPrintTeXFinalPrimitive(
void)
3334 gl2psPrintTeXHeader,
3335 gl2psPrintTeXFooter,
3336 gl2psPrintTeXBeginViewport,
3337 gl2psPrintTeXEndViewport,
3338 gl2psPrintTeXPrimitive,
3339 gl2psPrintTeXFinalPrimitive,
3350 static int gl2psPrintPDFCompressorType(
void)
3352 #if defined(GL2PS_HAVE_ZLIB)
3354 return fprintf(gl2ps->
stream,
"/Filter [/FlateDecode]\n");
3360 static int gl2psPrintPDFStrokeColor(
GL2PSrgba rgba)
3364 gl2psSetLastColor(rgba);
3365 for(
i = 0;
i < 3; ++
i){
3367 offs += gl2psPrintf(
"%.0f ", 0.);
3368 else if(rgba[
i] < 1
e-4 || rgba[
i] > 1e6)
3369 offs += gl2psPrintf(
"%f ", rgba[
i]);
3371 offs += gl2psPrintf(
"%g ", rgba[
i]);
3373 offs += gl2psPrintf(
"RG\n");
3377 static int gl2psPrintPDFFillColor(
GL2PSrgba rgba)
3381 for(
i = 0;
i < 3; ++
i){
3383 offs += gl2psPrintf(
"%.0f ", 0.);
3384 else if(rgba[
i] < 1
e-4 || rgba[
i] > 1e6)
3385 offs += gl2psPrintf(
"%f ", rgba[
i]);
3387 offs += gl2psPrintf(
"%g ", rgba[
i]);
3389 offs += gl2psPrintf(
"rg\n");
3393 static int gl2psPrintPDFLineWidth(GLfloat
lw)
3396 return gl2psPrintf(
"%.0f w\n", 0.);
3397 else if(lw < 1e-4 || lw > 1e6)
3398 return gl2psPrintf(
"%f w\n",
lw);
3400 return gl2psPrintf(
"%g w\n",
lw);
3405 GLfloat
rad, crad, srad;
3407 if(
text->angle == 0.0F){
3418 srad = (GLfloat)
sin(
rad);
3419 crad = (GLfloat)
cos(
rad);
3423 "%f %f %f %f %f %f Tm\n"
3426 cnt,
text->fontsize, crad, srad, -srad, crad,
x,
y,
text->str);
3434 "%d 0 0 %d %f %f cm\n"
3440 static void gl2psPDFstacksInit(
void)
3464 static void gl2psPDFgroupListInit(
void)
3470 GL2PSrgba lastrgba = {-1.0F, -1.0F, -1.0F, -1.0F};
3471 GLushort lastpattern = 0;
3472 GLint lastfactor = 0;
3473 GLfloat lastwidth = 1;
3475 int lastTriangleWasNotSimpleWithSameColor = 0;
3481 gl2psInitTriangle(&lastt);
3487 gl2psPDFgroupObjectInit(&gro);
3494 gl2psPDFgroupObjectInit(&gro);
3501 if(lasttype !=
p->type || lastwidth !=
p->width ||
3502 lastpattern !=
p->pattern || lastfactor !=
p->factor ||
3503 !gl2psSameColor(
p->verts[0].rgba, lastrgba)){
3504 gl2psPDFgroupObjectInit(&gro);
3512 lastpattern =
p->pattern;
3513 lastfactor =
p->factor;
3514 lastwidth =
p->width;
3515 lastrgba[0] =
p->verts[0].rgba[0];
3516 lastrgba[1] =
p->verts[0].rgba[1];
3517 lastrgba[2] =
p->verts[0].rgba[2];
3520 if(lasttype !=
p->type || lastwidth !=
p->width ||
3521 !gl2psSameColor(
p->verts[0].rgba, lastrgba)){
3522 gl2psPDFgroupObjectInit(&gro);
3530 lastwidth =
p->width;
3531 lastrgba[0] =
p->verts[0].rgba[0];
3532 lastrgba[1] =
p->verts[0].rgba[1];
3533 lastrgba[2] =
p->verts[0].rgba[2];
3536 gl2psFillTriangleFromPrimitive(&tmpt,
p, GL_TRUE);
3537 lastTriangleWasNotSimpleWithSameColor =
3540 if(lasttype ==
p->type && tmpt.
prop == lastt.
prop &&
3541 lastTriangleWasNotSimpleWithSameColor){
3546 gl2psPDFgroupObjectInit(&gro);
3560 static void gl2psSortOutTrianglePDFgroup(
GL2PSpdfgroup *gro)
3568 if(!gl2psListNbr(gro->
ptrlist))
3576 gl2psFillTriangleFromPrimitive(&
t, prim, GL_TRUE);
3614 static void gl2psPDFgroupListWriteMainStream(
void)
3627 lastel = gl2psListNbr(gro->
ptrlist) - 1;
3638 for(j = 0; j <= lastel; ++j){
3641 gl2psPrintf(
"%f %f m %f %f l\n",
3657 gl2psPrintf(
"%f %f m\n",
3660 for(j = 1; j <= lastel; ++j){
3663 if(!gl2psSamePosition(prim->
verts[0].
xyz, prev->verts[1].xyz)){
3668 gl2psPrintf(
"%f %f l\n",
3669 prev->verts[1].xyz[0], prev->verts[1].xyz[1]);
3671 gl2psPrintf(
"%f %f m\n",
3678 gl2psPrintf(
"%f %f l\n",
3684 gl2psPrintf(
"%f %f l\n",
3689 gl2psFillTriangleFromPrimitive(&
t, prim, GL_TRUE);
3690 gl2psSortOutTrianglePDFgroup(gro);
3694 gl2ps->
streamlength += gl2psPrintPDFFillColor(
t.vertex[0].rgba);
3695 for(j = 0; j <= lastel; ++j){
3697 gl2psFillTriangleFromPrimitive(&
t, prim, GL_FALSE);
3699 += gl2psPrintf(
"%f %f m\n"
3703 t.vertex[0].xyz[0],
t.vertex[0].xyz[1],
3704 t.vertex[1].xyz[0],
t.vertex[1].xyz[1],
3705 t.vertex[2].xyz[0],
t.vertex[2].xyz[1]);
3715 for(j = 0; j <= lastel; ++j){
3717 gl2psFillTriangleFromPrimitive(&
t, prim, GL_FALSE);
3719 += gl2psPrintf(
"%f %f m\n"
3723 t.vertex[0].xyz[0],
t.vertex[0].xyz[1],
3724 t.vertex[1].xyz[0],
t.vertex[1].xyz[1],
3725 t.vertex[2].xyz[0],
t.vertex[2].xyz[1]);
3738 for(j = 0; j <= lastel; ++j){
3740 gl2psFillTriangleFromPrimitive(&
t, prim, GL_FALSE);
3742 += gl2psPrintf(
"%f %f m\n"
3746 t.vertex[0].xyz[0],
t.vertex[0].xyz[1],
3747 t.vertex[1].xyz[0],
t.vertex[1].xyz[1],
3748 t.vertex[2].xyz[0],
t.vertex[2].xyz[1]);
3780 for(j = 0; j <= lastel; ++j){
3787 for(j = 0; j <= lastel; ++j){
3802 static int gl2psPDFgroupListWriteGStateResources(
void)
3808 offs += fprintf(gl2ps->
stream,
3817 offs += fprintf(gl2ps->
stream,
">>\n");
3823 static int gl2psPDFgroupListWriteShaderResources(
void)
3829 offs += fprintf(gl2ps->
stream,
3839 offs += fprintf(gl2ps->
stream,
">>\n");
3845 static int gl2psPDFgroupListWriteXObjectResources(
void)
3852 offs += fprintf(gl2ps->
stream,
3858 if(!gl2psListNbr(gro->
ptrlist))
3864 if(GL_RGBA ==
p->data.image->format)
3876 offs += fprintf(gl2ps->
stream,
">>\n");
3882 static int gl2psPDFgroupListWriteFontResources(
void)
3888 offs += fprintf(gl2ps->
stream,
"/Font\n<<\n");
3897 offs += fprintf(gl2ps->
stream,
">>\n");
3902 static void gl2psPDFgroupListDelete(
void)
3912 gl2psListDelete(gro->
ptrlist);
3921 static int gl2psPrintPDFInfo(
void)
3929 offs = fprintf(gl2ps->
stream,
3933 "/Creator (GL2PS %d.%d.%d%s, %s)\n"
3939 if(!gmtime_r(&
now, &newtime)){
3940 offs += fprintf(gl2ps->
stream,
3946 offs += fprintf(gl2ps->
stream,
3947 "/CreationDate (D:%d%02d%02d%02d%02d%02d)\n"
3950 newtime.tm_year+1900,
3961 static int gl2psPrintPDFCatalog(
void)
3963 return fprintf(gl2ps->
stream,
3972 static int gl2psPrintPDFPages(
void)
3974 return fprintf(gl2ps->
stream,
3986 static int gl2psOpenPDFDataStream(
void)
3990 offs += fprintf(gl2ps->
stream,
3993 "/Length 5 0 R\n" );
3994 offs += gl2psPrintPDFCompressorType();
3995 offs += fprintf(gl2ps->
stream,
4003 static int gl2psOpenPDFDataStreamWritePreface(
void)
4007 offs = gl2psPrintf(
"/GSa gs\n");
4010 offs += gl2psPrintPDFFillColor(gl2ps->
bgcolor);
4011 offs += gl2psPrintf(
"%d %d %d %d re\n",
4014 offs += gl2psPrintf(
"f\n");
4021 static void gl2psPrintPDFHeader(
void)
4025 gl2psPDFstacksInit();
4029 #if defined(GL2PS_HAVE_ZLIB)
4031 gl2psSetupCompress();
4035 offs += fprintf(gl2ps->
stream,
"%%PDF-1.4\n");
4038 offs += gl2psPrintPDFInfo();
4041 offs += gl2psPrintPDFCatalog();
4044 offs += gl2psPrintPDFPages();
4047 offs += gl2psOpenPDFDataStream();
4049 gl2ps->
streamlength = gl2psOpenPDFDataStreamWritePreface();
4054 static void gl2psPrintPDFPrimitive(
void *
data)
4061 prim = gl2psCopyPrimitive(prim);
4067 static int gl2psClosePDFDataStream(
void)
4071 #if defined(GL2PS_HAVE_ZLIB)
4073 if(Z_OK != gl2psDeflate())
4080 gl2psFreeCompress();
4084 offs += fprintf(gl2ps->
stream,
4092 static int gl2psPrintPDFDataStreamLength(
int val)
4094 return fprintf(gl2ps->
stream,
4102 static int gl2psPrintPDFOpenPage(
void)
4108 offs = fprintf(gl2ps->
stream,
4113 "/MediaBox [%d %d %d %d]\n",
4118 offs += fprintf(gl2ps->
stream,
"/Rotate -90\n");
4120 offs += fprintf(gl2ps->
stream,
4124 "/ProcSet [/PDF /Text /ImageB /ImageC] %%/ImageI\n");
4131 static int gl2psPDFgroupListWriteVariableResources(
void)
4136 offs += gl2psPDFgroupListWriteGStateResources();
4139 offs += gl2psPDFgroupListWriteShaderResources();
4142 offs += gl2psPDFgroupListWriteXObjectResources();
4145 offs += gl2psPDFgroupListWriteFontResources();
4148 offs += fprintf(gl2ps->
stream,
4157 static int gl2psPrintPDFGSObject(
void)
4159 return fprintf(gl2ps->
stream,
4162 "/Type /ExtGState\n"
4180 GLfloat
dx, GLfloat
dy,
4186 double dmax =
static_cast<double>(~1UL);
4190 if(
sizeof(
unsigned long) == 8) dmax = dmax - 2048.;
4192 offs += (*action)(edgeflag, 1);
4198 offs += (*action)(0, 4);
4199 offs += (*action)(0, 4);
4207 imap = (
unsigned long)(
diff * dmax);
4208 offs += (*action)(imap, 4);
4215 imap = (
unsigned long)(
diff * dmax);
4216 offs += (*action)(imap, 4);
4230 double dmax =
static_cast<double>(~1UL);
4233 if(
sizeof(
unsigned long) == 8) dmax = dmax - 2048.;
4235 imap = (
unsigned long)((
vertex->rgba[0]) * dmax);
4236 offs += (*action)(imap, 1);
4238 imap = (
unsigned long)((
vertex->rgba[1]) * dmax);
4239 offs += (*action)(imap, 1);
4241 imap = (
unsigned long)((
vertex->rgba[2]) * dmax);
4242 offs += (*action)(imap, 1);
4256 double dmax =
static_cast<double>(~1UL);
4259 if(
sizeof(
unsigned long) == 8) dmax = dmax - 2048.;
4261 if(sigbyte != 8 && sigbyte != 16)
4266 imap = (
unsigned long)((
vertex->rgba[3]) * dmax);
4268 offs += (*action)(imap, sigbyte);
4275 static int gl2psPrintPDFShaderStreamData(
GL2PStriangle *triangle,
4276 GLfloat
dx, GLfloat
dy,
4288 for(
i = 0;
i < 3; ++
i){
4289 offs += gl2psPrintPDFShaderStreamDataCoord(&triangle->
vertex[
i],
action,
4293 offs += gl2psPrintPDFShaderStreamDataAlpha(&
v,
action,
gray);
4296 offs += gl2psPrintPDFShaderStreamDataRGB(&triangle->
vertex[
i],
action);
4303 static void gl2psPDFRectHull(GLfloat *
xmin, GLfloat *
xmax,
4314 for(
i = 0;
i <
cnt; ++
i){
4315 for(j = 0; j < 3; ++j){
4336 int i, offs = 0, vertexbytes, done = 0;
4341 vertexbytes = 1+4+4+1+1+1;
4344 vertexbytes = 1+4+4+1;
4347 vertexbytes = 1+4+4+2;
4351 vertexbytes = 1+4+4+1;
4357 offs += fprintf(gl2ps->
stream,
4362 "/BitsPerCoordinate 32 "
4363 "/BitsPerComponent %d "
4365 "/Decode [%f %f %f %f 0 1 %s] ",
4367 (
gray) ?
"/DeviceGray" :
"/DeviceRGB",
4370 (
gray) ?
"" :
"0 1 0 1");
4372 #if defined(GL2PS_HAVE_ZLIB)
4374 gl2psAllocCompress(vertexbytes *
size * 3);
4377 gl2psPrintPDFShaderStreamData(&triangles[
i],
4379 gl2psWriteBigEndianCompress,
gray);
4381 if(Z_OK == gl2psDeflate() && 23 + gl2ps->
compress->destLen < gl2ps->
compress->srcLen){
4382 offs += gl2psPrintPDFCompressorType();
4383 offs += fprintf(gl2ps->
stream,
4393 gl2psFreeCompress();
4400 offs += fprintf(gl2ps->
stream,
4404 vertexbytes * 3 *
size);
4406 offs += gl2psPrintPDFShaderStreamData(&triangles[
i],
4408 gl2psWriteBigEndian,
gray);
4411 offs += fprintf(gl2ps->
stream,
4420 static int gl2psPrintPDFShaderMask(
int obj,
int childobj)
4424 offs += fprintf(gl2ps->
stream,
4429 "/BBox [ %d %d %d %d ]\n"
4430 "/Group \n<<\n/S /Transparency /CS /DeviceRGB\n"
4437 ? strlen(
"/TrSh sh\n") + (
int)log10((
double)childobj)+1
4438 : strlen(
"/TrSh0 sh\n");
4440 offs += fprintf(gl2ps->
stream,
4445 offs += fprintf(gl2ps->
stream,
4448 offs += fprintf(gl2ps->
stream,
4459 static int gl2psPrintPDFShaderExtGS(
int obj,
int childobj)
4463 offs += fprintf(gl2ps->
stream,
4468 offs += fprintf(gl2ps->
stream,
4469 "/SMask << /S /Alpha /G %d 0 R >> ",
4472 offs += fprintf(gl2ps->
stream,
4480 static int gl2psPrintPDFShaderSimpleExtGS(
int obj, GLfloat alpha)
4484 offs += fprintf(gl2ps->
stream,
4496 static int gl2psPrintPDFPixmapStreamData(
GL2PSimage *
im,
4504 if(
im->format != GL_RGBA &&
gray)
4512 shift = (
sizeof(
unsigned long) - 1) * 8;
4514 for(
y = 0;
y <
im->height; ++
y){
4515 for(
x = 0;
x <
im->width; ++
x){
4516 a = gl2psGetRGB(
im,
x,
y, &
r, &
g, &
b);
4517 if(
im->format == GL_RGBA &&
gray){
4518 (*action)((
unsigned long)(
a * 255) << shift,
gray);
4521 (*action)((
unsigned long)(
r * 255) << shift, 1);
4522 (*action)((
unsigned long)(
g * 255) << shift, 1);
4523 (*action)((
unsigned long)(
b * 255) << shift, 1);
4529 case 0:
return 3 *
im->width *
im->height;
4530 case 1:
return im->width *
im->height;
4531 case 2:
return 2 *
im->width *
im->height;
4532 default:
return 3 *
im->width *
im->height;
4538 int offs = 0, done = 0, sigbytes = 3;
4544 sigbytes =
gray / 8;
4546 offs += fprintf(gl2ps->
stream,
4554 "/BitsPerComponent 8\n",
4556 (
int)
im->width, (
int)
im->height,
4557 (
gray) ?
"/DeviceGray" :
"/DeviceRGB" );
4558 if(GL_RGBA ==
im->format &&
gray == 0){
4559 offs += fprintf(gl2ps->
stream,
4564 #if defined(GL2PS_HAVE_ZLIB)
4566 gl2psAllocCompress((
int)(
im->width *
im->height * sigbytes));
4568 gl2psPrintPDFPixmapStreamData(
im, gl2psWriteBigEndianCompress,
gray);
4570 if(Z_OK == gl2psDeflate() && 23 + gl2ps->
compress->destLen < gl2ps->
compress->srcLen){
4571 offs += gl2psPrintPDFCompressorType();
4572 offs += fprintf(gl2ps->
stream,
4581 gl2psFreeCompress();
4588 offs += fprintf(gl2ps->
stream,
4592 (
int)(
im->width *
im->height * sigbytes));
4593 offs += gl2psPrintPDFPixmapStreamData(
im, gl2psWriteBigEndian,
gray);
4596 offs += fprintf(gl2ps->
stream,
4607 offs += fprintf(gl2ps->
stream,
4614 "/Encoding /MacRomanEncoding\n"
4617 obj, fontnumber,
s->fontname);
4623 static int gl2psPDFgroupListWriteObjects(
int entryoffs)
4628 int offs = entryoffs;
4637 if(!gl2psListNbr(gro->
ptrlist))
4648 for(j = 0; j <
size; ++j){
4650 gl2psFillTriangleFromPrimitive(&triangles[j],
p, GL_TRUE);
4654 offs += gl2psPrintPDFShader(gro->
shobjno, triangles,
size, 0);
4658 offs += gl2psPrintPDFShaderSimpleExtGS(gro->
gsobjno, triangles[0].vertex[0].rgba[3]);
4668 gl2psFree(triangles);
4672 offs += gl2psPrintPDFPixmap(gro->
imobjno, gro->
imobjno+1,
p->data.image, 0);
4673 if(
p->data.image->format == GL_RGBA){
4675 offs += gl2psPrintPDFPixmap(gro->
imobjno+1, -1,
p->data.image, 8);
4686 offs += fprintf(gl2ps->
stream,
"%s\n",
p->data.text->str);
4699 static void gl2psPrintPDFFooter(
void)
4703 gl2psPDFgroupListInit();
4704 gl2psPDFgroupListWriteMainStream();
4707 offs += gl2psClosePDFDataStream();
4710 offs += gl2psPrintPDFDataStreamLength(gl2ps->
streamlength);
4714 offs += gl2psPrintPDFOpenPage();
4715 offs += gl2psPDFgroupListWriteVariableResources();
4720 offs += gl2psPrintPDFGSObject();
4724 gl2psPDFgroupListWriteObjects(gl2ps->
xreflist[8]);
4749 gl2psListAction(gl2ps->
pdfprimlist, gl2psFreePrimitive);
4751 gl2psPDFgroupListDelete();
4753 #if defined(GL2PS_HAVE_ZLIB)
4755 gl2psFreeCompress();
4764 static void gl2psPrintPDFBeginViewport(GLint viewport[4])
4769 int x = viewport[0],
y = viewport[1],
w = viewport[2],
h = viewport[3];
4771 glRenderMode(GL_FEEDBACK);
4774 gl2psPrintPDFHeader();
4775 gl2ps->
header = GL_FALSE;
4778 offs += gl2psPrintf(
"q\n");
4782 glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
4785 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &
index);
4791 offs += gl2psPrintPDFFillColor(rgba);
4792 offs += gl2psPrintf(
"%d %d %d %d re\n"
4798 offs += gl2psPrintf(
"%d %d %d %d re\n"
4807 static GLint gl2psPrintPDFEndViewport(
void)
4811 res = gl2psPrintPrimitives();
4816 static void gl2psPrintPDFFinalPrimitive(
void)
4823 gl2psPrintPDFHeader,
4824 gl2psPrintPDFFooter,
4825 gl2psPrintPDFBeginViewport,
4826 gl2psPrintPDFEndViewport,
4827 gl2psPrintPDFPrimitive,
4828 gl2psPrintPDFFinalPrimitive,
4830 "Portable Document Format"
4839 static void gl2psSVGGetCoordsAndColors(
int n,
GL2PSvertex *verts,
4844 for(
i = 0;
i <
n;
i++){
4848 for(j = 0; j < 4; j++)
4849 rgba[
i][j] = verts[
i].rgba[j];
4853 static void gl2psSVGGetColorString(
GL2PSrgba rgba,
char str[32])
4855 int r = (
int)(255. * rgba[0]);
4856 int g = (
int)(255. * rgba[1]);
4857 int b = (
int)(255. * rgba[2]);
4858 int rc = (
r < 0) ? 0 : (
r > 255) ? 255 :
r;
4859 int gc = (
g < 0) ? 0 : (
g > 255) ? 255 :
g;
4860 int bc = (
b < 0) ? 0 : (
b > 255) ? 255 :
b;
4861 sprintf(
str,
"#%2.2x%2.2x%2.2x", rc, gc, bc);
4864 static void gl2psPrintSVGHeader(
void)
4886 gl2psPrintGzipHeader();
4888 gl2psPrintf(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
4889 gl2psPrintf(
"<svg xmlns=\"http://www.w3.org/2000/svg\"\n");
4890 gl2psPrintf(
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
4891 " width=\"%dpx\" height=\"%dpx\" viewBox=\"%d %d %d %d\">\n",
4893 gl2psPrintf(
"<title>%s</title>\n", gl2ps->
title);
4894 gl2psPrintf(
"<desc>\n");
4895 gl2psPrintf(
"Creator: GL2PS %d.%d.%d%s, %s\n"
4900 gl2psPrintf(
"</desc>\n");
4901 gl2psPrintf(
"<defs>\n");
4902 gl2psPrintf(
"</defs>\n");
4906 gl2psPrintf(
"<polygon fill=\"%s\" points=\"%d,%d %d,%d %d,%d %d,%d\"/>\n",
col,
4914 gl2psPrintf(
"<g shape-rendering=\"crispEdges\">\n");
4928 if(gl2psSameColorThreshold(3, rgba, gl2ps->
threshold)){
4929 gl2psSVGGetColorString(rgba[0],
col);
4930 gl2psPrintf(
"<polygon fill=\"%s\" ",
col);
4931 if(rgba[0][3] < 1.0
F) gl2psPrintf(
"fill-opacity=\"%g\" ", rgba[0][3]);
4932 gl2psPrintf(
"points=\"%g,%g %g,%g %g,%g\"/>\n",
xyz[0][0],
xyz[0][1],
4937 for(
i = 0;
i < 3;
i++){
4938 xyz2[0][
i] =
xyz[0][
i];
4939 xyz2[1][
i] = 0.5F * (
xyz[0][
i] +
xyz[1][
i]);
4940 xyz2[2][
i] = 0.5F * (
xyz[0][
i] +
xyz[2][
i]);
4942 for(
i = 0;
i < 4;
i++){
4943 rgba2[0][
i] = rgba[0][
i];
4944 rgba2[1][
i] = 0.5F * (rgba[0][
i] + rgba[1][
i]);
4945 rgba2[2][
i] = 0.5F * (rgba[0][
i] + rgba[2][
i]);
4947 gl2psPrintSVGSmoothTriangle(xyz2, rgba2);
4948 for(
i = 0;
i < 3;
i++){
4949 xyz2[0][
i] = 0.5F * (
xyz[0][
i] +
xyz[1][
i]);
4950 xyz2[1][
i] =
xyz[1][
i];
4951 xyz2[2][
i] = 0.5F * (
xyz[1][
i] +
xyz[2][
i]);
4953 for(
i = 0;
i < 4;
i++){
4954 rgba2[0][
i] = 0.5F * (rgba[0][
i] + rgba[1][
i]);
4955 rgba2[1][
i] = rgba[1][
i];
4956 rgba2[2][
i] = 0.5F * (rgba[1][
i] + rgba[2][
i]);
4958 gl2psPrintSVGSmoothTriangle(xyz2, rgba2);
4959 for(
i = 0;
i < 3;
i++){
4960 xyz2[0][
i] = 0.5F * (
xyz[0][
i] +
xyz[2][
i]);
4961 xyz2[1][
i] =
xyz[2][
i];
4962 xyz2[2][
i] = 0.5F * (
xyz[1][
i] +
xyz[2][
i]);
4964 for(
i = 0;
i < 4;
i++){
4965 rgba2[0][
i] = 0.5F * (rgba[0][
i] + rgba[2][
i]);
4966 rgba2[1][
i] = rgba[2][
i];
4967 rgba2[2][
i] = 0.5F * (rgba[1][
i] + rgba[2][
i]);
4969 gl2psPrintSVGSmoothTriangle(xyz2, rgba2);
4970 for(
i = 0;
i < 3;
i++){
4971 xyz2[0][
i] = 0.5F * (
xyz[0][
i] +
xyz[1][
i]);
4972 xyz2[1][
i] = 0.5F * (
xyz[1][
i] +
xyz[2][
i]);
4973 xyz2[2][
i] = 0.5F * (
xyz[0][
i] +
xyz[2][
i]);
4975 for(
i = 0;
i < 4;
i++){
4976 rgba2[0][
i] = 0.5F * (rgba[0][
i] + rgba[1][
i]);
4977 rgba2[1][
i] = 0.5F * (rgba[1][
i] + rgba[2][
i]);
4978 rgba2[2][
i] = 0.5F * (rgba[0][
i] + rgba[2][
i]);
4980 gl2psPrintSVGSmoothTriangle(xyz2, rgba2);
4984 static void gl2psPrintSVGDash(GLushort
pattern, GLint factor)
4988 if(!
pattern || !factor)
return;
4991 gl2psPrintf(
"stroke-dasharray=\"");
4992 for(
i = 0;
i <
n;
i++){
4993 if(
i) gl2psPrintf(
",");
4994 gl2psPrintf(
"%d",
array[
i]);
4999 static void gl2psEndSVGLine(
void)
5005 for(
i = 0;
i < 3;
i++)
5007 for(
i = 0;
i < 4;
i++)
5012 static void gl2psPrintSVGPixmap(
5013 #
if defined(GL2PS_HAVE_LIBPNG)
5021 #if defined(GL2PS_HAVE_LIBPNG)
5032 png = gl2psListCreate(pixmap->
width * pixmap->
height * 3, 1000,
5033 sizeof(
unsigned char));
5034 gl2psConvertPixmapToPNG(pixmap, png);
5035 gl2psListEncodeBase64(png);
5036 gl2psPrintf(
"<image x=\"%g\" y=\"%g\" width=\"%d\" height=\"%d\"\n",
5038 gl2psPrintf(
"xlink:href=\"data:image/png;base64,");
5039 for(
i = 0;
i < gl2psListNbr(png);
i++){
5040 gl2psListRead(png,
i, &
c);
5041 gl2psPrintf(
"%c",
c);
5043 gl2psPrintf(
"\"/>\n");
5044 gl2psListDelete(png);
5046 gl2psMsg(
GL2PS_WARNING,
"GL2PS must be compiled with PNG support in "
5047 "order to embed images in SVG streams");
5051 static void gl2psPrintSVGPrimitive(
void *
data)
5072 gl2psSVGGetColorString(rgba[0],
col);
5073 gl2psPrintf(
"<circle fill=\"%s\" ",
col);
5074 if(rgba[0][3] < 1.0
F) gl2psPrintf(
"fill-opacity=\"%g\" ", rgba[0][3]);
5075 gl2psPrintf(
"cx=\"%g\" cy=\"%g\" r=\"%g\"/>\n",
5100 gl2psSVGGetColorString(rgba[0],
col);
5101 gl2psPrintf(
"<polyline fill=\"none\" stroke=\"%s\" stroke-width=\"%g\" ",
5103 if(rgba[0][3] < 1.0
F) gl2psPrintf(
"stroke-opacity=\"%g\" ", rgba[0][3]);
5105 gl2psPrintf(
"points=\"%g,%g ",
xyz[0][0],
xyz[0][1]);
5108 gl2psPrintf(
"%g,%g ",
xyz[0][0],
xyz[0][1]);
5112 gl2psPrintSVGSmoothTriangle(
xyz, rgba);
5115 gl2psMsg(
GL2PS_WARNING,
"There should not be any quad left to print");
5122 gl2psPrintf(
"<text fill=\"%s\" x=\"%g\" y=\"%g\" font-size=\"%d\" ",
5125 gl2psPrintf(
"transform=\"rotate(%g, %g, %g)\" ",
5128 gl2psPrintf(
"font-family=\"Times\">");
5130 gl2psPrintf(
"font-family=\"Times\" font-weight=\"bold\">");
5132 gl2psPrintf(
"font-family=\"Times\" font-style=\"italic\">");
5134 gl2psPrintf(
"font-family=\"Times\" font-style=\"italic\" font-weight=\"bold\">");
5136 gl2psPrintf(
"font-family=\"Helvetica\" font-weight=\"bold\">");
5138 gl2psPrintf(
"font-family=\"Helvetica\" font-style=\"oblique\">");
5140 gl2psPrintf(
"font-family=\"Helvetica\" font-style=\"oblique\" font-weight=\"bold\">");
5142 gl2psPrintf(
"font-family=\"Courier\" font-weight=\"bold\">");
5144 gl2psPrintf(
"font-family=\"Courier\" font-style=\"oblique\">");
5146 gl2psPrintf(
"font-family=\"Courier\" font-style=\"oblique\" font-weight=\"bold\">");
5162 static void gl2psPrintSVGFooter(
void)
5164 gl2psPrintf(
"</g>\n");
5165 gl2psPrintf(
"</svg>\n");
5167 gl2psPrintGzipFooter();
5170 static void gl2psPrintSVGBeginViewport(GLint viewport[4])
5175 int x = viewport[0],
y = viewport[1],
w = viewport[2],
h = viewport[3];
5177 glRenderMode(GL_FEEDBACK);
5180 gl2psPrintSVGHeader();
5181 gl2ps->
header = GL_FALSE;
5186 glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
5189 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &
index);
5195 gl2psSVGGetColorString(rgba,
col);
5196 gl2psPrintf(
"<polygon fill=\"%s\" points=\"%d,%d %d,%d %d,%d %d,%d\"/>\n",
col,
5203 gl2psPrintf(
"<clipPath id=\"cp%d%d%d%d\">\n",
x,
y,
w,
h);
5204 gl2psPrintf(
" <polygon points=\"%d,%d %d,%d %d,%d %d,%d\"/>\n",
5209 gl2psPrintf(
"</clipPath>\n");
5210 gl2psPrintf(
"<g clip-path=\"url(#cp%d%d%d%d)\">\n",
x,
y,
w,
h);
5213 static GLint gl2psPrintSVGEndViewport(
void)
5217 res = gl2psPrintPrimitives();
5218 gl2psPrintf(
"</g>\n");
5222 static void gl2psPrintSVGFinalPrimitive(
void)
5231 gl2psPrintSVGHeader,
5232 gl2psPrintSVGFooter,
5233 gl2psPrintSVGBeginViewport,
5234 gl2psPrintSVGEndViewport,
5235 gl2psPrintSVGPrimitive,
5236 gl2psPrintSVGFinalPrimitive,
5238 "Scalable Vector Graphics"
5247 static void gl2psPrintPGFColor(
GL2PSrgba rgba)
5249 if(!gl2psSameColor(gl2ps->
lastrgba, rgba)){
5250 gl2psSetLastColor(rgba);
5251 fprintf(gl2ps->
stream,
"\\color[rgb]{%f,%f,%f}\n", rgba[0], rgba[1], rgba[2]);
5255 static void gl2psPrintPGFHeader(
void)
5263 "%% Creator: GL2PS %d.%d.%d%s, %s\n"
5265 "%% CreationDate: %s",
5270 fprintf(gl2ps->
stream,
"\\begin{pgfpicture}\n");
5272 gl2psPrintPGFColor(gl2ps->
bgcolor);
5274 "\\pgfpathrectanglecorners{"
5275 "\\pgfpoint{%dpt}{%dpt}}{\\pgfpoint{%dpt}{%dpt}}\n"
5276 "\\pgfusepath{fill}\n",
5282 static void gl2psPrintPGFDash(GLushort
pattern, GLint factor)
5294 fprintf(gl2ps->
stream,
"\\pgfsetdash{}{0pt}\n");
5298 fprintf(gl2ps->
stream,
"\\pgfsetdash{");
5300 fprintf(gl2ps->
stream,
"}{0pt}\n");
5304 static const char *gl2psPGFTextAlignment(
int align)
5316 default :
return "south west";
5320 static void gl2psPrintPGFPrimitive(
void *
data)
5329 gl2psPrintPGFColor(prim->
verts[0].
rgba);
5331 "\\pgfpathrectangle{\\pgfpoint{%fpt}{%fpt}}"
5332 "{\\pgfpoint{%fpt}{%fpt}}\n\\pgfusepath{fill}\n",
5338 gl2psPrintPGFColor(prim->
verts[0].
rgba);
5345 "\\pgfpathmoveto{\\pgfpoint{%fpt}{%fpt}}\n"
5346 "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n"
5347 "\\pgfusepath{stroke}\n",
5354 fprintf(gl2ps->
stream,
"\\pgfsetlinewidth{0.01pt}\n");
5356 gl2psPrintPGFColor(prim->
verts[0].
rgba);
5358 "\\pgfpathmoveto{\\pgfpoint{%fpt}{%fpt}}\n"
5359 "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n"
5360 "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n"
5362 "\\pgfusepath{fill,stroke}\n",
5368 fprintf(gl2ps->
stream,
"{\n\\pgftransformshift{\\pgfpoint{%fpt}{%fpt}}\n",
5374 fprintf(gl2ps->
stream,
"\\pgfnode{rectangle}{%s}{\\fontsize{%d}{0}\\selectfont",
5378 fprintf(gl2ps->
stream,
"\\textcolor[rgb]{%g,%g,%g}{{%s}}",
5382 fprintf(gl2ps->
stream,
"}{}{\\pgfusepath{discard}}}\n");
5395 static void gl2psPrintPGFFooter(
void)
5397 fprintf(gl2ps->
stream,
"\\end{pgfpicture}\n");
5400 static void gl2psPrintPGFBeginViewport(GLint viewport[4])
5404 int x = viewport[0],
y = viewport[1],
w = viewport[2],
h = viewport[3];
5406 glRenderMode(GL_FEEDBACK);
5409 gl2psPrintPGFHeader();
5410 gl2ps->
header = GL_FALSE;
5413 fprintf(gl2ps->
stream,
"\\begin{pgfscope}\n");
5416 glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
5419 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &
index);
5425 gl2psPrintPGFColor(rgba);
5427 "\\pgfpathrectangle{\\pgfpoint{%dpt}{%dpt}}"
5428 "{\\pgfpoint{%dpt}{%dpt}}\n"
5429 "\\pgfusepath{fill}\n",
5434 "\\pgfpathrectangle{\\pgfpoint{%dpt}{%dpt}}"
5435 "{\\pgfpoint{%dpt}{%dpt}}\n"
5436 "\\pgfusepath{clip}\n",
5440 static GLint gl2psPrintPGFEndViewport(
void)
5443 res = gl2psPrintPrimitives();
5444 fprintf(gl2ps->
stream,
"\\end{pgfscope}\n");
5448 static void gl2psPrintPGFFinalPrimitive(
void)
5455 gl2psPrintPGFHeader,
5456 gl2psPrintPGFFooter,
5457 gl2psPrintPGFBeginViewport,
5458 gl2psPrintPGFEndViewport,
5459 gl2psPrintPGFPrimitive,
5460 gl2psPrintPGFFinalPrimitive,
5462 "PGF Latex Graphics"
5483 static void gl2psComputeTightBoundingBox(
void *
data)
5502 static GLint gl2psPrintPrimitives(
void)
5508 used = glRenderMode(GL_RENDER);
5511 gl2psMsg(
GL2PS_INFO,
"OpenGL feedback buffer overflow");
5516 gl2psParseFeedbackBuffer(
used);
5518 gl2psRescaleAndOffset();
5525 gl2psListAction(gl2ps->
primitives, gl2psComputeTightBoundingBox);
5528 gl2ps->
header = GL_FALSE;
5536 switch(gl2ps->
sort){
5538 gl2psListAction(gl2ps->
primitives, gl2psbackends[gl2ps->
format]->printPrimitive);
5539 gl2psListAction(gl2ps->
primitives, gl2psFreePrimitive);
5544 gl2psListSort(gl2ps->
primitives, gl2psCompareDepth);
5546 gl2psListActionInverse(gl2ps->
primitives, gl2psAddInImageTree);
5547 gl2psFreeBspImageTree(&gl2ps->
imagetree);
5549 gl2psListAction(gl2ps->
primitives, gl2psbackends[gl2ps->
format]->printPrimitive);
5550 gl2psListAction(gl2ps->
primitives, gl2psFreePrimitive);
5557 if(GL_TRUE == gl2ps->
boundary) gl2psBuildPolygonBoundary(
root);
5560 gl2psAddInImageTree, 1);
5561 gl2psFreeBspImageTree(&gl2ps->
imagetree);
5564 gl2psbackends[gl2ps->
format]->printPrimitive, 0);
5565 gl2psFreeBspTree(&
root);
5583 GLint viewport[4], GLint
format, GLint sort,
5584 GLint
options, GLint colormode,
5586 GLint nr, GLint
ng, GLint
nb, GLint buffersize,
5593 gl2psMsg(
GL2PS_ERROR,
"gl2psBeginPage called in wrong program state");
5599 if(
format >= 0 &&
format < (GLint)(
sizeof(gl2psbackends) /
sizeof(gl2psbackends[0]))){
5616 gl2psMsg(
GL2PS_ERROR,
"Unknown sorting algorithm: %d", sort);
5640 glGetIntegerv(GL_VIEWPORT, gl2ps->
viewport);
5643 for(
i = 0;
i < 4;
i++){
5649 gl2psMsg(
GL2PS_ERROR,
"Incorrect viewport (x=%d, y=%d, width=%d, height=%d)",
5657 gl2ps->
threshold[0] = nr ? 1.0F / (GLfloat)nr : 0.064
F;
5661 gl2ps->
buffersize = buffersize > 0 ? buffersize : 2048 * 2048;
5662 for(
i = 0;
i < 3;
i++){
5665 for(
i = 0;
i < 4;
i++){
5682 glGetIntegerv(GL_BLEND_SRC, &gl2ps->
blendfunc[0]);
5683 glGetIntegerv(GL_BLEND_DST, &gl2ps->
blendfunc[1]);
5688 glGetFloatv(GL_COLOR_CLEAR_VALUE, gl2ps->
bgcolor);
5690 else if(gl2ps->
colormode == GL_COLOR_INDEX){
5691 if(!colorsize || !colormap){
5692 gl2psMsg(
GL2PS_ERROR,
"Missing colormap for GL_COLOR_INDEX rendering");
5700 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &
index);
5707 gl2psMsg(
GL2PS_ERROR,
"Unknown color mode in gl2psBeginPage");
5714 gl2ps->
title = (
char*)gl2psMalloc(
sizeof(
char));
5715 gl2ps->
title[0] =
'\0';
5718 gl2ps->
title = (
char*)gl2psMalloc((strlen(
title)+1)*
sizeof(
char));
5723 gl2ps->
producer = (
char*)gl2psMalloc(
sizeof(
char));
5727 gl2ps->
producer = (
char*)gl2psMalloc((strlen(producer)+1)*
sizeof(
char));
5732 gl2ps->
filename = (
char*)gl2psMalloc(
sizeof(
char));
5744 glRenderMode(GL_FEEDBACK);
5755 res = gl2psPrintPrimitives();
5766 gl2psFree(gl2ps->
title);
5816 GLint xorig, GLint yorig,
5821 GLfloat
pos[4], *piv;
5832 gl2psMsg(
GL2PS_ERROR,
"gl2psDrawPixels only implemented for "
5833 "GL_RGB/GL_RGBA, GL_FLOAT pixels");
5837 glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &
valid);
5840 glGetFloatv(GL_CURRENT_RASTER_POSITION,
pos);
5855 glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->
verts[0].
rgba);
5869 piv = (GLfloat*)pixels;
5870 for(
i = 0;
i <
size; ++
i, ++piv){
5897 const GLfloat position[3],
5898 const unsigned char *imagemap){
5900 int sizeoffloat =
sizeof(GLfloat);
5906 size = height + height * ((
width - 1) / 8);
5909 glVertex3f(position[0], position[1],position[2]);
5911 glPassThrough((GLfloat)
width);
5912 glPassThrough((GLfloat)height);
5913 for(
i = 0;
i <
size;
i += sizeoffloat){
5915 const float *
value =
reinterpret_cast<const float*
>(imagemap);
5916 glPassThrough(*
value);
5917 imagemap += sizeoffloat;
5931 glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &gl2ps->
offset[0]);
5932 glGetFloatv(GL_POLYGON_OFFSET_UNITS, &gl2ps->
offset[1]);
5939 glGetIntegerv(GL_LINE_STIPPLE_PATTERN, &
tmp);
5940 glPassThrough((GLfloat)
tmp);
5941 glGetIntegerv(GL_LINE_STIPPLE_REPEAT, &
tmp);
5942 glPassThrough((GLfloat)
tmp);
5985 glPassThrough(
value);
5995 glPassThrough(
value);
6004 if(GL_FALSE == gl2psSupportedBlendMode(sfactor, dfactor))
6008 glPassThrough((GLfloat)sfactor);
6010 glPassThrough((GLfloat)dfactor);
6038 if(
format >= 0 &&
format < (GLint)(
sizeof(gl2psbackends) /
sizeof(gl2psbackends[0])))
6041 return "Unknown format";
6046 if(
format >= 0 &&
format < (GLint)(
sizeof(gl2psbackends) /
sizeof(gl2psbackends[0])))
6049 return "Unknown format";