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;
312 ptr = realloc(ptr,
size);
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];
432 gl2ps->
compress->start = (Bytef*)gl2psReallocCompress(oldsize +
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)
3928 newtime = gmtime(&
now);
3930 offs = fprintf(gl2ps->
stream,
3934 "/Creator (GL2PS %d.%d.%d%s, %s)\n"
3941 offs += fprintf(gl2ps->
stream,
3947 offs += fprintf(gl2ps->
stream,
3948 "/CreationDate (D:%d%02d%02d%02d%02d%02d)\n"
3951 newtime->tm_year+1900,
3962 static int gl2psPrintPDFCatalog(
void)
3964 return fprintf(gl2ps->
stream,
3973 static int gl2psPrintPDFPages(
void)
3975 return fprintf(gl2ps->
stream,
3987 static int gl2psOpenPDFDataStream(
void)
3991 offs += fprintf(gl2ps->
stream,
3994 "/Length 5 0 R\n" );
3995 offs += gl2psPrintPDFCompressorType();
3996 offs += fprintf(gl2ps->
stream,
4004 static int gl2psOpenPDFDataStreamWritePreface(
void)
4008 offs = gl2psPrintf(
"/GSa gs\n");
4011 offs += gl2psPrintPDFFillColor(gl2ps->
bgcolor);
4012 offs += gl2psPrintf(
"%d %d %d %d re\n",
4015 offs += gl2psPrintf(
"f\n");
4022 static void gl2psPrintPDFHeader(
void)
4026 gl2psPDFstacksInit();
4030 #if defined(GL2PS_HAVE_ZLIB)
4032 gl2psSetupCompress();
4036 offs += fprintf(gl2ps->
stream,
"%%PDF-1.4\n");
4039 offs += gl2psPrintPDFInfo();
4042 offs += gl2psPrintPDFCatalog();
4045 offs += gl2psPrintPDFPages();
4048 offs += gl2psOpenPDFDataStream();
4050 gl2ps->
streamlength = gl2psOpenPDFDataStreamWritePreface();
4055 static void gl2psPrintPDFPrimitive(
void *
data)
4062 prim = gl2psCopyPrimitive(prim);
4068 static int gl2psClosePDFDataStream(
void)
4072 #if defined(GL2PS_HAVE_ZLIB)
4074 if(Z_OK != gl2psDeflate())
4081 gl2psFreeCompress();
4085 offs += fprintf(gl2ps->
stream,
4093 static int gl2psPrintPDFDataStreamLength(
int val)
4095 return fprintf(gl2ps->
stream,
4103 static int gl2psPrintPDFOpenPage(
void)
4109 offs = fprintf(gl2ps->
stream,
4114 "/MediaBox [%d %d %d %d]\n",
4119 offs += fprintf(gl2ps->
stream,
"/Rotate -90\n");
4121 offs += fprintf(gl2ps->
stream,
4125 "/ProcSet [/PDF /Text /ImageB /ImageC] %%/ImageI\n");
4132 static int gl2psPDFgroupListWriteVariableResources(
void)
4137 offs += gl2psPDFgroupListWriteGStateResources();
4140 offs += gl2psPDFgroupListWriteShaderResources();
4143 offs += gl2psPDFgroupListWriteXObjectResources();
4146 offs += gl2psPDFgroupListWriteFontResources();
4149 offs += fprintf(gl2ps->
stream,
4158 static int gl2psPrintPDFGSObject(
void)
4160 return fprintf(gl2ps->
stream,
4163 "/Type /ExtGState\n"
4181 GLfloat
dx, GLfloat
dy,
4187 double dmax =
static_cast<double>(~1UL);
4191 if(
sizeof(
unsigned long) == 8) dmax = dmax - 2048.;
4193 offs += (*action)(edgeflag, 1);
4199 offs += (*action)(0, 4);
4200 offs += (*action)(0, 4);
4208 imap = (
unsigned long)(
diff * dmax);
4209 offs += (*action)(imap, 4);
4216 imap = (
unsigned long)(
diff * dmax);
4217 offs += (*action)(imap, 4);
4231 double dmax =
static_cast<double>(~1UL);
4234 if(
sizeof(
unsigned long) == 8) dmax = dmax - 2048.;
4236 imap = (
unsigned long)((
vertex->rgba[0]) * dmax);
4237 offs += (*action)(imap, 1);
4239 imap = (
unsigned long)((
vertex->rgba[1]) * dmax);
4240 offs += (*action)(imap, 1);
4242 imap = (
unsigned long)((
vertex->rgba[2]) * dmax);
4243 offs += (*action)(imap, 1);
4257 double dmax =
static_cast<double>(~1UL);
4260 if(
sizeof(
unsigned long) == 8) dmax = dmax - 2048.;
4262 if(sigbyte != 8 && sigbyte != 16)
4267 imap = (
unsigned long)((
vertex->rgba[3]) * dmax);
4269 offs += (*action)(imap, sigbyte);
4276 static int gl2psPrintPDFShaderStreamData(
GL2PStriangle *triangle,
4277 GLfloat
dx, GLfloat
dy,
4289 for(
i = 0;
i < 3; ++
i){
4290 offs += gl2psPrintPDFShaderStreamDataCoord(&triangle->
vertex[
i],
action,
4294 offs += gl2psPrintPDFShaderStreamDataAlpha(&
v,
action,
gray);
4297 offs += gl2psPrintPDFShaderStreamDataRGB(&triangle->
vertex[
i],
action);
4304 static void gl2psPDFRectHull(GLfloat *
xmin, GLfloat *
xmax,
4315 for(
i = 0;
i <
cnt; ++
i){
4316 for(j = 0; j < 3; ++j){
4337 int i, offs = 0, vertexbytes, done = 0;
4342 vertexbytes = 1+4+4+1+1+1;
4345 vertexbytes = 1+4+4+1;
4348 vertexbytes = 1+4+4+2;
4352 vertexbytes = 1+4+4+1;
4358 offs += fprintf(gl2ps->
stream,
4363 "/BitsPerCoordinate 32 "
4364 "/BitsPerComponent %d "
4366 "/Decode [%f %f %f %f 0 1 %s] ",
4368 (
gray) ?
"/DeviceGray" :
"/DeviceRGB",
4371 (
gray) ?
"" :
"0 1 0 1");
4373 #if defined(GL2PS_HAVE_ZLIB)
4375 gl2psAllocCompress(vertexbytes *
size * 3);
4378 gl2psPrintPDFShaderStreamData(&triangles[
i],
4380 gl2psWriteBigEndianCompress,
gray);
4382 if(Z_OK == gl2psDeflate() && 23 + gl2ps->
compress->destLen < gl2ps->
compress->srcLen){
4383 offs += gl2psPrintPDFCompressorType();
4384 offs += fprintf(gl2ps->
stream,
4394 gl2psFreeCompress();
4401 offs += fprintf(gl2ps->
stream,
4405 vertexbytes * 3 *
size);
4407 offs += gl2psPrintPDFShaderStreamData(&triangles[
i],
4409 gl2psWriteBigEndian,
gray);
4412 offs += fprintf(gl2ps->
stream,
4421 static int gl2psPrintPDFShaderMask(
int obj,
int childobj)
4425 offs += fprintf(gl2ps->
stream,
4430 "/BBox [ %d %d %d %d ]\n"
4431 "/Group \n<<\n/S /Transparency /CS /DeviceRGB\n"
4438 ? strlen(
"/TrSh sh\n") + (
int)log10((
double)childobj)+1
4439 : strlen(
"/TrSh0 sh\n");
4441 offs += fprintf(gl2ps->
stream,
4446 offs += fprintf(gl2ps->
stream,
4449 offs += fprintf(gl2ps->
stream,
4460 static int gl2psPrintPDFShaderExtGS(
int obj,
int childobj)
4464 offs += fprintf(gl2ps->
stream,
4469 offs += fprintf(gl2ps->
stream,
4470 "/SMask << /S /Alpha /G %d 0 R >> ",
4473 offs += fprintf(gl2ps->
stream,
4481 static int gl2psPrintPDFShaderSimpleExtGS(
int obj, GLfloat alpha)
4485 offs += fprintf(gl2ps->
stream,
4497 static int gl2psPrintPDFPixmapStreamData(
GL2PSimage *
im,
4505 if(
im->format != GL_RGBA &&
gray)
4513 shift = (
sizeof(
unsigned long) - 1) * 8;
4515 for(
y = 0;
y <
im->height; ++
y){
4516 for(
x = 0;
x <
im->width; ++
x){
4517 a = gl2psGetRGB(
im,
x,
y, &
r, &
g, &
b);
4518 if(
im->format == GL_RGBA &&
gray){
4519 (*action)((
unsigned long)(
a * 255) << shift,
gray);
4522 (*action)((
unsigned long)(
r * 255) << shift, 1);
4523 (*action)((
unsigned long)(
g * 255) << shift, 1);
4524 (*action)((
unsigned long)(
b * 255) << shift, 1);
4530 case 0:
return 3 *
im->width *
im->height;
4531 case 1:
return im->width *
im->height;
4532 case 2:
return 2 *
im->width *
im->height;
4533 default:
return 3 *
im->width *
im->height;
4539 int offs = 0, done = 0, sigbytes = 3;
4545 sigbytes =
gray / 8;
4547 offs += fprintf(gl2ps->
stream,
4555 "/BitsPerComponent 8\n",
4557 (
int)
im->width, (
int)
im->height,
4558 (
gray) ?
"/DeviceGray" :
"/DeviceRGB" );
4559 if(GL_RGBA ==
im->format &&
gray == 0){
4560 offs += fprintf(gl2ps->
stream,
4565 #if defined(GL2PS_HAVE_ZLIB)
4567 gl2psAllocCompress((
int)(
im->width *
im->height * sigbytes));
4569 gl2psPrintPDFPixmapStreamData(
im, gl2psWriteBigEndianCompress,
gray);
4571 if(Z_OK == gl2psDeflate() && 23 + gl2ps->
compress->destLen < gl2ps->
compress->srcLen){
4572 offs += gl2psPrintPDFCompressorType();
4573 offs += fprintf(gl2ps->
stream,
4582 gl2psFreeCompress();
4589 offs += fprintf(gl2ps->
stream,
4593 (
int)(
im->width *
im->height * sigbytes));
4594 offs += gl2psPrintPDFPixmapStreamData(
im, gl2psWriteBigEndian,
gray);
4597 offs += fprintf(gl2ps->
stream,
4608 offs += fprintf(gl2ps->
stream,
4615 "/Encoding /MacRomanEncoding\n"
4618 obj, fontnumber,
s->fontname);
4624 static int gl2psPDFgroupListWriteObjects(
int entryoffs)
4629 int offs = entryoffs;
4638 if(!gl2psListNbr(gro->
ptrlist))
4649 for(j = 0; j <
size; ++j){
4651 gl2psFillTriangleFromPrimitive(&triangles[j],
p, GL_TRUE);
4655 offs += gl2psPrintPDFShader(gro->
shobjno, triangles,
size, 0);
4659 offs += gl2psPrintPDFShaderSimpleExtGS(gro->
gsobjno, triangles[0].vertex[0].rgba[3]);
4669 gl2psFree(triangles);
4673 offs += gl2psPrintPDFPixmap(gro->
imobjno, gro->
imobjno+1,
p->data.image, 0);
4674 if(
p->data.image->format == GL_RGBA){
4676 offs += gl2psPrintPDFPixmap(gro->
imobjno+1, -1,
p->data.image, 8);
4687 offs += fprintf(gl2ps->
stream,
"%s\n",
p->data.text->str);
4700 static void gl2psPrintPDFFooter(
void)
4704 gl2psPDFgroupListInit();
4705 gl2psPDFgroupListWriteMainStream();
4708 offs += gl2psClosePDFDataStream();
4711 offs += gl2psPrintPDFDataStreamLength(gl2ps->
streamlength);
4715 offs += gl2psPrintPDFOpenPage();
4716 offs += gl2psPDFgroupListWriteVariableResources();
4721 offs += gl2psPrintPDFGSObject();
4725 gl2psPDFgroupListWriteObjects(gl2ps->
xreflist[8]);
4750 gl2psListAction(gl2ps->
pdfprimlist, gl2psFreePrimitive);
4752 gl2psPDFgroupListDelete();
4754 #if defined(GL2PS_HAVE_ZLIB)
4756 gl2psFreeCompress();
4765 static void gl2psPrintPDFBeginViewport(GLint viewport[4])
4770 int x = viewport[0],
y = viewport[1],
w = viewport[2],
h = viewport[3];
4772 glRenderMode(GL_FEEDBACK);
4775 gl2psPrintPDFHeader();
4776 gl2ps->
header = GL_FALSE;
4779 offs += gl2psPrintf(
"q\n");
4783 glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
4786 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &
index);
4792 offs += gl2psPrintPDFFillColor(rgba);
4793 offs += gl2psPrintf(
"%d %d %d %d re\n"
4799 offs += gl2psPrintf(
"%d %d %d %d re\n"
4808 static GLint gl2psPrintPDFEndViewport(
void)
4812 res = gl2psPrintPrimitives();
4817 static void gl2psPrintPDFFinalPrimitive(
void)
4824 gl2psPrintPDFHeader,
4825 gl2psPrintPDFFooter,
4826 gl2psPrintPDFBeginViewport,
4827 gl2psPrintPDFEndViewport,
4828 gl2psPrintPDFPrimitive,
4829 gl2psPrintPDFFinalPrimitive,
4831 "Portable Document Format"
4840 static void gl2psSVGGetCoordsAndColors(
int n,
GL2PSvertex *verts,
4845 for(
i = 0;
i <
n;
i++){
4849 for(j = 0; j < 4; j++)
4850 rgba[
i][j] = verts[
i].rgba[j];
4854 static void gl2psSVGGetColorString(
GL2PSrgba rgba,
char str[32])
4856 int r = (
int)(255. * rgba[0]);
4857 int g = (
int)(255. * rgba[1]);
4858 int b = (
int)(255. * rgba[2]);
4859 int rc = (
r < 0) ? 0 : (
r > 255) ? 255 :
r;
4860 int gc = (
g < 0) ? 0 : (
g > 255) ? 255 :
g;
4861 int bc = (
b < 0) ? 0 : (
b > 255) ? 255 :
b;
4862 sprintf(
str,
"#%2.2x%2.2x%2.2x", rc, gc, bc);
4865 static void gl2psPrintSVGHeader(
void)
4887 gl2psPrintGzipHeader();
4889 gl2psPrintf(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
4890 gl2psPrintf(
"<svg xmlns=\"http://www.w3.org/2000/svg\"\n");
4891 gl2psPrintf(
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
4892 " width=\"%dpx\" height=\"%dpx\" viewBox=\"%d %d %d %d\">\n",
4894 gl2psPrintf(
"<title>%s</title>\n", gl2ps->
title);
4895 gl2psPrintf(
"<desc>\n");
4896 gl2psPrintf(
"Creator: GL2PS %d.%d.%d%s, %s\n"
4901 gl2psPrintf(
"</desc>\n");
4902 gl2psPrintf(
"<defs>\n");
4903 gl2psPrintf(
"</defs>\n");
4907 gl2psPrintf(
"<polygon fill=\"%s\" points=\"%d,%d %d,%d %d,%d %d,%d\"/>\n",
col,
4915 gl2psPrintf(
"<g shape-rendering=\"crispEdges\">\n");
4929 if(gl2psSameColorThreshold(3, rgba, gl2ps->
threshold)){
4930 gl2psSVGGetColorString(rgba[0],
col);
4931 gl2psPrintf(
"<polygon fill=\"%s\" ",
col);
4932 if(rgba[0][3] < 1.0
F) gl2psPrintf(
"fill-opacity=\"%g\" ", rgba[0][3]);
4933 gl2psPrintf(
"points=\"%g,%g %g,%g %g,%g\"/>\n",
xyz[0][0],
xyz[0][1],
4938 for(
i = 0;
i < 3;
i++){
4939 xyz2[0][
i] =
xyz[0][
i];
4940 xyz2[1][
i] = 0.5F * (
xyz[0][
i] +
xyz[1][
i]);
4941 xyz2[2][
i] = 0.5F * (
xyz[0][
i] +
xyz[2][
i]);
4943 for(
i = 0;
i < 4;
i++){
4944 rgba2[0][
i] = rgba[0][
i];
4945 rgba2[1][
i] = 0.5F * (rgba[0][
i] + rgba[1][
i]);
4946 rgba2[2][
i] = 0.5F * (rgba[0][
i] + rgba[2][
i]);
4948 gl2psPrintSVGSmoothTriangle(xyz2, rgba2);
4949 for(
i = 0;
i < 3;
i++){
4950 xyz2[0][
i] = 0.5F * (
xyz[0][
i] +
xyz[1][
i]);
4951 xyz2[1][
i] =
xyz[1][
i];
4952 xyz2[2][
i] = 0.5F * (
xyz[1][
i] +
xyz[2][
i]);
4954 for(
i = 0;
i < 4;
i++){
4955 rgba2[0][
i] = 0.5F * (rgba[0][
i] + rgba[1][
i]);
4956 rgba2[1][
i] = rgba[1][
i];
4957 rgba2[2][
i] = 0.5F * (rgba[1][
i] + rgba[2][
i]);
4959 gl2psPrintSVGSmoothTriangle(xyz2, rgba2);
4960 for(
i = 0;
i < 3;
i++){
4961 xyz2[0][
i] = 0.5F * (
xyz[0][
i] +
xyz[2][
i]);
4962 xyz2[1][
i] =
xyz[2][
i];
4963 xyz2[2][
i] = 0.5F * (
xyz[1][
i] +
xyz[2][
i]);
4965 for(
i = 0;
i < 4;
i++){
4966 rgba2[0][
i] = 0.5F * (rgba[0][
i] + rgba[2][
i]);
4967 rgba2[1][
i] = rgba[2][
i];
4968 rgba2[2][
i] = 0.5F * (rgba[1][
i] + rgba[2][
i]);
4970 gl2psPrintSVGSmoothTriangle(xyz2, rgba2);
4971 for(
i = 0;
i < 3;
i++){
4972 xyz2[0][
i] = 0.5F * (
xyz[0][
i] +
xyz[1][
i]);
4973 xyz2[1][
i] = 0.5F * (
xyz[1][
i] +
xyz[2][
i]);
4974 xyz2[2][
i] = 0.5F * (
xyz[0][
i] +
xyz[2][
i]);
4976 for(
i = 0;
i < 4;
i++){
4977 rgba2[0][
i] = 0.5F * (rgba[0][
i] + rgba[1][
i]);
4978 rgba2[1][
i] = 0.5F * (rgba[1][
i] + rgba[2][
i]);
4979 rgba2[2][
i] = 0.5F * (rgba[0][
i] + rgba[2][
i]);
4981 gl2psPrintSVGSmoothTriangle(xyz2, rgba2);
4985 static void gl2psPrintSVGDash(GLushort
pattern, GLint factor)
4989 if(!
pattern || !factor)
return;
4992 gl2psPrintf(
"stroke-dasharray=\"");
4993 for(
i = 0;
i <
n;
i++){
4994 if(
i) gl2psPrintf(
",");
4995 gl2psPrintf(
"%d",
array[
i]);
5000 static void gl2psEndSVGLine(
void)
5006 for(
i = 0;
i < 3;
i++)
5008 for(
i = 0;
i < 4;
i++)
5013 static void gl2psPrintSVGPixmap(
5014 #
if defined(GL2PS_HAVE_LIBPNG)
5022 #if defined(GL2PS_HAVE_LIBPNG)
5033 png = gl2psListCreate(pixmap->
width * pixmap->
height * 3, 1000,
5034 sizeof(
unsigned char));
5035 gl2psConvertPixmapToPNG(pixmap, png);
5036 gl2psListEncodeBase64(png);
5037 gl2psPrintf(
"<image x=\"%g\" y=\"%g\" width=\"%d\" height=\"%d\"\n",
5039 gl2psPrintf(
"xlink:href=\"data:image/png;base64,");
5040 for(
i = 0;
i < gl2psListNbr(png);
i++){
5041 gl2psListRead(png,
i, &
c);
5042 gl2psPrintf(
"%c",
c);
5044 gl2psPrintf(
"\"/>\n");
5045 gl2psListDelete(png);
5047 gl2psMsg(
GL2PS_WARNING,
"GL2PS must be compiled with PNG support in "
5048 "order to embed images in SVG streams");
5052 static void gl2psPrintSVGPrimitive(
void *
data)
5073 gl2psSVGGetColorString(rgba[0],
col);
5074 gl2psPrintf(
"<circle fill=\"%s\" ",
col);
5075 if(rgba[0][3] < 1.0
F) gl2psPrintf(
"fill-opacity=\"%g\" ", rgba[0][3]);
5076 gl2psPrintf(
"cx=\"%g\" cy=\"%g\" r=\"%g\"/>\n",
5101 gl2psSVGGetColorString(rgba[0],
col);
5102 gl2psPrintf(
"<polyline fill=\"none\" stroke=\"%s\" stroke-width=\"%g\" ",
5104 if(rgba[0][3] < 1.0
F) gl2psPrintf(
"stroke-opacity=\"%g\" ", rgba[0][3]);
5106 gl2psPrintf(
"points=\"%g,%g ",
xyz[0][0],
xyz[0][1]);
5109 gl2psPrintf(
"%g,%g ",
xyz[0][0],
xyz[0][1]);
5113 gl2psPrintSVGSmoothTriangle(
xyz, rgba);
5116 gl2psMsg(
GL2PS_WARNING,
"There should not be any quad left to print");
5123 gl2psPrintf(
"<text fill=\"%s\" x=\"%g\" y=\"%g\" font-size=\"%d\" ",
5126 gl2psPrintf(
"transform=\"rotate(%g, %g, %g)\" ",
5129 gl2psPrintf(
"font-family=\"Times\">");
5131 gl2psPrintf(
"font-family=\"Times\" font-weight=\"bold\">");
5133 gl2psPrintf(
"font-family=\"Times\" font-style=\"italic\">");
5135 gl2psPrintf(
"font-family=\"Times\" font-style=\"italic\" font-weight=\"bold\">");
5137 gl2psPrintf(
"font-family=\"Helvetica\" font-weight=\"bold\">");
5139 gl2psPrintf(
"font-family=\"Helvetica\" font-style=\"oblique\">");
5141 gl2psPrintf(
"font-family=\"Helvetica\" font-style=\"oblique\" font-weight=\"bold\">");
5143 gl2psPrintf(
"font-family=\"Courier\" font-weight=\"bold\">");
5145 gl2psPrintf(
"font-family=\"Courier\" font-style=\"oblique\">");
5147 gl2psPrintf(
"font-family=\"Courier\" font-style=\"oblique\" font-weight=\"bold\">");
5163 static void gl2psPrintSVGFooter(
void)
5165 gl2psPrintf(
"</g>\n");
5166 gl2psPrintf(
"</svg>\n");
5168 gl2psPrintGzipFooter();
5171 static void gl2psPrintSVGBeginViewport(GLint viewport[4])
5176 int x = viewport[0],
y = viewport[1],
w = viewport[2],
h = viewport[3];
5178 glRenderMode(GL_FEEDBACK);
5181 gl2psPrintSVGHeader();
5182 gl2ps->
header = GL_FALSE;
5187 glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
5190 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &
index);
5196 gl2psSVGGetColorString(rgba,
col);
5197 gl2psPrintf(
"<polygon fill=\"%s\" points=\"%d,%d %d,%d %d,%d %d,%d\"/>\n",
col,
5204 gl2psPrintf(
"<clipPath id=\"cp%d%d%d%d\">\n",
x,
y,
w,
h);
5205 gl2psPrintf(
" <polygon points=\"%d,%d %d,%d %d,%d %d,%d\"/>\n",
5210 gl2psPrintf(
"</clipPath>\n");
5211 gl2psPrintf(
"<g clip-path=\"url(#cp%d%d%d%d)\">\n",
x,
y,
w,
h);
5214 static GLint gl2psPrintSVGEndViewport(
void)
5218 res = gl2psPrintPrimitives();
5219 gl2psPrintf(
"</g>\n");
5223 static void gl2psPrintSVGFinalPrimitive(
void)
5232 gl2psPrintSVGHeader,
5233 gl2psPrintSVGFooter,
5234 gl2psPrintSVGBeginViewport,
5235 gl2psPrintSVGEndViewport,
5236 gl2psPrintSVGPrimitive,
5237 gl2psPrintSVGFinalPrimitive,
5239 "Scalable Vector Graphics"
5248 static void gl2psPrintPGFColor(
GL2PSrgba rgba)
5250 if(!gl2psSameColor(gl2ps->
lastrgba, rgba)){
5251 gl2psSetLastColor(rgba);
5252 fprintf(gl2ps->
stream,
"\\color[rgb]{%f,%f,%f}\n", rgba[0], rgba[1], rgba[2]);
5256 static void gl2psPrintPGFHeader(
void)
5264 "%% Creator: GL2PS %d.%d.%d%s, %s\n"
5266 "%% CreationDate: %s",
5271 fprintf(gl2ps->
stream,
"\\begin{pgfpicture}\n");
5273 gl2psPrintPGFColor(gl2ps->
bgcolor);
5275 "\\pgfpathrectanglecorners{"
5276 "\\pgfpoint{%dpt}{%dpt}}{\\pgfpoint{%dpt}{%dpt}}\n"
5277 "\\pgfusepath{fill}\n",
5283 static void gl2psPrintPGFDash(GLushort
pattern, GLint factor)
5295 fprintf(gl2ps->
stream,
"\\pgfsetdash{}{0pt}\n");
5299 fprintf(gl2ps->
stream,
"\\pgfsetdash{");
5301 fprintf(gl2ps->
stream,
"}{0pt}\n");
5305 static const char *gl2psPGFTextAlignment(
int align)
5317 default :
return "south west";
5321 static void gl2psPrintPGFPrimitive(
void *
data)
5330 gl2psPrintPGFColor(prim->
verts[0].
rgba);
5332 "\\pgfpathrectangle{\\pgfpoint{%fpt}{%fpt}}"
5333 "{\\pgfpoint{%fpt}{%fpt}}\n\\pgfusepath{fill}\n",
5339 gl2psPrintPGFColor(prim->
verts[0].
rgba);
5346 "\\pgfpathmoveto{\\pgfpoint{%fpt}{%fpt}}\n"
5347 "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n"
5348 "\\pgfusepath{stroke}\n",
5355 fprintf(gl2ps->
stream,
"\\pgfsetlinewidth{0.01pt}\n");
5357 gl2psPrintPGFColor(prim->
verts[0].
rgba);
5359 "\\pgfpathmoveto{\\pgfpoint{%fpt}{%fpt}}\n"
5360 "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n"
5361 "\\pgflineto{\\pgfpoint{%fpt}{%fpt}}\n"
5363 "\\pgfusepath{fill,stroke}\n",
5369 fprintf(gl2ps->
stream,
"{\n\\pgftransformshift{\\pgfpoint{%fpt}{%fpt}}\n",
5375 fprintf(gl2ps->
stream,
"\\pgfnode{rectangle}{%s}{\\fontsize{%d}{0}\\selectfont",
5379 fprintf(gl2ps->
stream,
"\\textcolor[rgb]{%g,%g,%g}{{%s}}",
5383 fprintf(gl2ps->
stream,
"}{}{\\pgfusepath{discard}}}\n");
5396 static void gl2psPrintPGFFooter(
void)
5398 fprintf(gl2ps->
stream,
"\\end{pgfpicture}\n");
5401 static void gl2psPrintPGFBeginViewport(GLint viewport[4])
5405 int x = viewport[0],
y = viewport[1],
w = viewport[2],
h = viewport[3];
5407 glRenderMode(GL_FEEDBACK);
5410 gl2psPrintPGFHeader();
5411 gl2ps->
header = GL_FALSE;
5414 fprintf(gl2ps->
stream,
"\\begin{pgfscope}\n");
5417 glGetFloatv(GL_COLOR_CLEAR_VALUE, rgba);
5420 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &
index);
5426 gl2psPrintPGFColor(rgba);
5428 "\\pgfpathrectangle{\\pgfpoint{%dpt}{%dpt}}"
5429 "{\\pgfpoint{%dpt}{%dpt}}\n"
5430 "\\pgfusepath{fill}\n",
5435 "\\pgfpathrectangle{\\pgfpoint{%dpt}{%dpt}}"
5436 "{\\pgfpoint{%dpt}{%dpt}}\n"
5437 "\\pgfusepath{clip}\n",
5441 static GLint gl2psPrintPGFEndViewport(
void)
5444 res = gl2psPrintPrimitives();
5445 fprintf(gl2ps->
stream,
"\\end{pgfscope}\n");
5449 static void gl2psPrintPGFFinalPrimitive(
void)
5456 gl2psPrintPGFHeader,
5457 gl2psPrintPGFFooter,
5458 gl2psPrintPGFBeginViewport,
5459 gl2psPrintPGFEndViewport,
5460 gl2psPrintPGFPrimitive,
5461 gl2psPrintPGFFinalPrimitive,
5463 "PGF Latex Graphics"
5484 static void gl2psComputeTightBoundingBox(
void *
data)
5503 static GLint gl2psPrintPrimitives(
void)
5509 used = glRenderMode(GL_RENDER);
5512 gl2psMsg(
GL2PS_INFO,
"OpenGL feedback buffer overflow");
5517 gl2psParseFeedbackBuffer(
used);
5519 gl2psRescaleAndOffset();
5526 gl2psListAction(gl2ps->
primitives, gl2psComputeTightBoundingBox);
5529 gl2ps->
header = GL_FALSE;
5537 switch(gl2ps->
sort){
5539 gl2psListAction(gl2ps->
primitives, gl2psbackends[gl2ps->
format]->printPrimitive);
5540 gl2psListAction(gl2ps->
primitives, gl2psFreePrimitive);
5545 gl2psListSort(gl2ps->
primitives, gl2psCompareDepth);
5547 gl2psListActionInverse(gl2ps->
primitives, gl2psAddInImageTree);
5548 gl2psFreeBspImageTree(&gl2ps->
imagetree);
5550 gl2psListAction(gl2ps->
primitives, gl2psbackends[gl2ps->
format]->printPrimitive);
5551 gl2psListAction(gl2ps->
primitives, gl2psFreePrimitive);
5558 if(GL_TRUE == gl2ps->
boundary) gl2psBuildPolygonBoundary(
root);
5561 gl2psAddInImageTree, 1);
5562 gl2psFreeBspImageTree(&gl2ps->
imagetree);
5565 gl2psbackends[gl2ps->
format]->printPrimitive, 0);
5566 gl2psFreeBspTree(&
root);
5584 GLint viewport[4], GLint
format, GLint sort,
5585 GLint
options, GLint colormode,
5587 GLint nr, GLint
ng, GLint
nb, GLint buffersize,
5594 gl2psMsg(
GL2PS_ERROR,
"gl2psBeginPage called in wrong program state");
5600 if(
format >= 0 &&
format < (GLint)(
sizeof(gl2psbackends) /
sizeof(gl2psbackends[0]))){
5617 gl2psMsg(
GL2PS_ERROR,
"Unknown sorting algorithm: %d", sort);
5641 glGetIntegerv(GL_VIEWPORT, gl2ps->
viewport);
5644 for(
i = 0;
i < 4;
i++){
5650 gl2psMsg(
GL2PS_ERROR,
"Incorrect viewport (x=%d, y=%d, width=%d, height=%d)",
5658 gl2ps->
threshold[0] = nr ? 1.0F / (GLfloat)nr : 0.064
F;
5662 gl2ps->
buffersize = buffersize > 0 ? buffersize : 2048 * 2048;
5663 for(
i = 0;
i < 3;
i++){
5666 for(
i = 0;
i < 4;
i++){
5683 glGetIntegerv(GL_BLEND_SRC, &gl2ps->
blendfunc[0]);
5684 glGetIntegerv(GL_BLEND_DST, &gl2ps->
blendfunc[1]);
5689 glGetFloatv(GL_COLOR_CLEAR_VALUE, gl2ps->
bgcolor);
5691 else if(gl2ps->
colormode == GL_COLOR_INDEX){
5692 if(!colorsize || !colormap){
5693 gl2psMsg(
GL2PS_ERROR,
"Missing colormap for GL_COLOR_INDEX rendering");
5701 glGetIntegerv(GL_INDEX_CLEAR_VALUE, &
index);
5708 gl2psMsg(
GL2PS_ERROR,
"Unknown color mode in gl2psBeginPage");
5715 gl2ps->
title = (
char*)gl2psMalloc(
sizeof(
char));
5716 gl2ps->
title[0] =
'\0';
5719 gl2ps->
title = (
char*)gl2psMalloc((strlen(
title)+1)*
sizeof(
char));
5724 gl2ps->
producer = (
char*)gl2psMalloc(
sizeof(
char));
5728 gl2ps->
producer = (
char*)gl2psMalloc((strlen(producer)+1)*
sizeof(
char));
5733 gl2ps->
filename = (
char*)gl2psMalloc(
sizeof(
char));
5745 glRenderMode(GL_FEEDBACK);
5756 res = gl2psPrintPrimitives();
5767 gl2psFree(gl2ps->
title);
5817 GLint xorig, GLint yorig,
5822 GLfloat
pos[4], *piv;
5833 gl2psMsg(
GL2PS_ERROR,
"gl2psDrawPixels only implemented for "
5834 "GL_RGB/GL_RGBA, GL_FLOAT pixels");
5838 glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &
valid);
5841 glGetFloatv(GL_CURRENT_RASTER_POSITION,
pos);
5856 glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->
verts[0].
rgba);
5870 piv = (GLfloat*)pixels;
5871 for(
i = 0;
i <
size; ++
i, ++piv){
5898 const GLfloat position[3],
5899 const unsigned char *imagemap){
5901 int sizeoffloat =
sizeof(GLfloat);
5907 size = height + height * ((
width - 1) / 8);
5910 glVertex3f(position[0], position[1],position[2]);
5912 glPassThrough((GLfloat)
width);
5913 glPassThrough((GLfloat)height);
5914 for(
i = 0;
i <
size;
i += sizeoffloat){
5916 const float *
value =
reinterpret_cast<const float*
>(imagemap);
5917 glPassThrough(*
value);
5918 imagemap += sizeoffloat;
5932 glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &gl2ps->
offset[0]);
5933 glGetFloatv(GL_POLYGON_OFFSET_UNITS, &gl2ps->
offset[1]);
5940 glGetIntegerv(GL_LINE_STIPPLE_PATTERN, &
tmp);
5941 glPassThrough((GLfloat)
tmp);
5942 glGetIntegerv(GL_LINE_STIPPLE_REPEAT, &
tmp);
5943 glPassThrough((GLfloat)
tmp);
5986 glPassThrough(
value);
5996 glPassThrough(
value);
6005 if(GL_FALSE == gl2psSupportedBlendMode(sfactor, dfactor))
6009 glPassThrough((GLfloat)sfactor);
6011 glPassThrough((GLfloat)dfactor);
6039 if(
format >= 0 &&
format < (GLint)(
sizeof(gl2psbackends) /
sizeof(gl2psbackends[0])))
6042 return "Unknown format";
6047 if(
format >= 0 &&
format < (GLint)(
sizeof(gl2psbackends) /
sizeof(gl2psbackends[0])))
6050 return "Unknown format";