Mercurial > octave
comparison src/gl2ps.c @ 9950:7dedfd70dd9f
image printing for fltk backend
author | Shai Ayal <shaiay@users.sourceforge.net> |
---|---|
date | Wed, 09 Dec 2009 15:49:00 -0500 |
parents | 2d6a5af744b6 |
children | 89f13bc14494 |
comparison
equal
deleted
inserted
replaced
9949:a6308dcad5ac | 9950:7dedfd70dd9f |
---|---|
165 GLsizei width, height; | 165 GLsizei width, height; |
166 /* Note: for an imagemap, 'type' indicates if it has already been | 166 /* Note: for an imagemap, 'type' indicates if it has already been |
167 written to the file or not, and 'format' indicates if it is | 167 written to the file or not, and 'format' indicates if it is |
168 visible or not */ | 168 visible or not */ |
169 GLenum format, type; | 169 GLenum format, type; |
170 GLfloat zoom_x, zoom_y; | |
170 GLfloat *pixels; | 171 GLfloat *pixels; |
171 } GL2PSimage; | 172 } GL2PSimage; |
172 | 173 |
173 typedef struct _GL2PSimagemap GL2PSimagemap; | 174 typedef struct _GL2PSimagemap GL2PSimagemap; |
174 | 175 |
291 | 292 |
292 static void *gl2psMalloc(size_t size) | 293 static void *gl2psMalloc(size_t size) |
293 { | 294 { |
294 void *ptr; | 295 void *ptr; |
295 | 296 |
296 if(!size) return(NULL); | 297 if(!size) return NULL; |
297 ptr = malloc(size); | 298 ptr = malloc(size); |
298 if(!ptr){ | 299 if(!ptr){ |
299 gl2psMsg(GL2PS_ERROR, "Couldn't allocate requested memory"); | 300 gl2psMsg(GL2PS_ERROR, "Couldn't allocate requested memory"); |
300 exit(1); | 301 return NULL; |
301 } | 302 } |
302 return(ptr); | 303 return ptr; |
303 } | 304 } |
304 | 305 |
305 static void *gl2psRealloc(void *ptr, size_t size) | 306 static void *gl2psRealloc(void *ptr, size_t size) |
306 { | 307 { |
307 if(!size) return(NULL); | 308 if(!size) return NULL; |
308 ptr = realloc(ptr, size); | 309 ptr = realloc(ptr, size); |
309 if(!ptr){ | 310 if(!ptr){ |
310 gl2psMsg(GL2PS_ERROR, "Couldn't reallocate requested memory"); | 311 gl2psMsg(GL2PS_ERROR, "Couldn't reallocate requested memory"); |
311 exit(1); | 312 return NULL; |
312 } | 313 } |
313 return(ptr); | 314 return ptr; |
314 } | 315 } |
315 | 316 |
316 static void gl2psFree(void *ptr) | 317 static void gl2psFree(void *ptr) |
317 { | 318 { |
318 if(!ptr) return; | 319 if(!ptr) return; |
531 list->incr = incr; | 532 list->incr = incr; |
532 list->size = size; | 533 list->size = size; |
533 list->n = 0; | 534 list->n = 0; |
534 list->array = NULL; | 535 list->array = NULL; |
535 gl2psListRealloc(list, n); | 536 gl2psListRealloc(list, n); |
536 return(list); | 537 return list; |
537 } | 538 } |
538 | 539 |
539 static void gl2psListReset(GL2PSlist *list) | 540 static void gl2psListReset(GL2PSlist *list) |
540 { | 541 { |
541 if(!list) return; | 542 if(!list) return; |
562 | 563 |
563 static int gl2psListNbr(GL2PSlist *list) | 564 static int gl2psListNbr(GL2PSlist *list) |
564 { | 565 { |
565 if(!list) | 566 if(!list) |
566 return 0; | 567 return 0; |
567 return(list->n); | 568 return list->n; |
568 } | 569 } |
569 | 570 |
570 static void *gl2psListPointer(GL2PSlist *list, GLint index) | 571 static void *gl2psListPointer(GL2PSlist *list, GLint index) |
571 { | 572 { |
572 if(!list){ | 573 if(!list){ |
575 } | 576 } |
576 if((index < 0) || (index >= list->n)){ | 577 if((index < 0) || (index >= list->n)){ |
577 gl2psMsg(GL2PS_ERROR, "Wrong list index in gl2psListPointer"); | 578 gl2psMsg(GL2PS_ERROR, "Wrong list index in gl2psListPointer"); |
578 return NULL; | 579 return NULL; |
579 } | 580 } |
580 return(&list->array[index * list->size]); | 581 return &list->array[index * list->size]; |
581 } | 582 } |
582 | 583 |
583 static void gl2psListSort(GL2PSlist *list, | 584 static void gl2psListSort(GL2PSlist *list, |
584 int (*fcmp)(const void *a, const void *b)) | 585 int (*fcmp)(const void *a, const void *b)) |
585 { | 586 { |
743 | 744 |
744 image->width = im->width; | 745 image->width = im->width; |
745 image->height = im->height; | 746 image->height = im->height; |
746 image->format = im->format; | 747 image->format = im->format; |
747 image->type = im->type; | 748 image->type = im->type; |
749 image->zoom_x = im->zoom_x; | |
750 image->zoom_y = im->zoom_y; | |
748 | 751 |
749 switch(image->format){ | 752 switch(image->format){ |
750 case GL_RGBA: | 753 case GL_RGBA: |
751 size = image->height * image->width * 4 * sizeof(GLfloat); | 754 size = image->height * image->width * 4 * sizeof(GLfloat); |
752 break; | 755 break; |
1047 * | 1050 * |
1048 *********************************************************************/ | 1051 *********************************************************************/ |
1049 | 1052 |
1050 static GLfloat gl2psComparePointPlane(GL2PSxyz point, GL2PSplane plane) | 1053 static GLfloat gl2psComparePointPlane(GL2PSxyz point, GL2PSplane plane) |
1051 { | 1054 { |
1052 return(plane[0] * point[0] + | 1055 return (plane[0] * point[0] + |
1053 plane[1] * point[1] + | 1056 plane[1] * point[1] + |
1054 plane[2] * point[2] + | 1057 plane[2] * point[2] + |
1055 plane[3]); | 1058 plane[3]); |
1056 } | 1059 } |
1057 | 1060 |
1058 static GLfloat gl2psPsca(GLfloat *a, GLfloat *b) | 1061 static GLfloat gl2psPsca(GLfloat *a, GLfloat *b) |
1059 { | 1062 { |
1060 return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2]); | 1063 return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]); |
1061 } | 1064 } |
1062 | 1065 |
1063 static void gl2psPvec(GLfloat *a, GLfloat *b, GLfloat *c) | 1066 static void gl2psPvec(GLfloat *a, GLfloat *b, GLfloat *c) |
1064 { | 1067 { |
1065 c[0] = a[1]*b[2] - a[2]*b[1]; | 1068 c[0] = a[1]*b[2] - a[2]*b[1]; |
1393 { | 1396 { |
1394 GL2PSprimitive *q, *w; | 1397 GL2PSprimitive *q, *w; |
1395 | 1398 |
1396 q = *(GL2PSprimitive**)a; | 1399 q = *(GL2PSprimitive**)a; |
1397 w = *(GL2PSprimitive**)b; | 1400 w = *(GL2PSprimitive**)b; |
1398 return(q->type < w->type ? 1 : -1); | 1401 return (q->type < w->type ? 1 : -1); |
1399 } | 1402 } |
1400 | 1403 |
1401 static GLint gl2psFindRoot(GL2PSlist *primitives, GL2PSprimitive **root) | 1404 static GLint gl2psFindRoot(GL2PSlist *primitives, GL2PSprimitive **root) |
1402 { | 1405 { |
1403 GLint i, j, count, best = 1000000, index = 0; | 1406 GLint i, j, count, best = 1000000, index = 0; |
2320 | 2323 |
2321 node = (GL2PSimagemap*)gl2psMalloc(sizeof(GL2PSimagemap)); | 2324 node = (GL2PSimagemap*)gl2psMalloc(sizeof(GL2PSimagemap)); |
2322 node->image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage)); | 2325 node->image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage)); |
2323 node->image->type = 0; | 2326 node->image->type = 0; |
2324 node->image->format = 0; | 2327 node->image->format = 0; |
2328 node->image->zoom_x = 1.0F; | |
2329 node->image->zoom_y = 1.0F; | |
2325 node->next = NULL; | 2330 node->next = NULL; |
2326 | 2331 |
2327 if(gl2ps->imagemap_head == NULL) | 2332 if(gl2ps->imagemap_head == NULL) |
2328 gl2ps->imagemap_head = node; | 2333 gl2ps->imagemap_head = node; |
2329 else | 2334 else |
2422 | 2427 |
2423 if((width <= 0) || (height <= 0)) return; | 2428 if((width <= 0) || (height <= 0)) return; |
2424 | 2429 |
2425 gl2psPrintf("gsave\n"); | 2430 gl2psPrintf("gsave\n"); |
2426 gl2psPrintf("%.2f %.2f translate\n", x, y); | 2431 gl2psPrintf("%.2f %.2f translate\n", x, y); |
2427 gl2psPrintf("%d %d scale\n", width, height); | 2432 gl2psPrintf("%.2f %.2f scale\n", width * im->zoom_x, height * im->zoom_y); |
2428 | 2433 |
2429 if(greyscale){ /* greyscale */ | 2434 if(greyscale){ /* greyscale */ |
2430 gl2psPrintf("/picstr %d string def\n", width); | 2435 gl2psPrintf("/picstr %d string def\n", width); |
2431 gl2psPrintf("%d %d %d\n", width, height, 8); | 2436 gl2psPrintf("%d %d %d\n", width, height, 8); |
2432 gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); | 2437 gl2psPrintf("[ %d 0 0 -%d 0 %d ]\n", width, height, height); |
3389 return gl2psPrintf("%g w\n", lw); | 3394 return gl2psPrintf("%g w\n", lw); |
3390 } | 3395 } |
3391 | 3396 |
3392 static void gl2psPutPDFText(GL2PSstring *text, int cnt, GLfloat x, GLfloat y) | 3397 static void gl2psPutPDFText(GL2PSstring *text, int cnt, GLfloat x, GLfloat y) |
3393 { | 3398 { |
3394 gl2ps->streamlength += | 3399 GLfloat rad, crad, srad; |
3395 gl2psPrintf("BT\n" | 3400 |
3396 "/F%d %d Tf\n" | 3401 if(text->angle == 0.0F){ |
3397 "%f %f Td\n" | 3402 gl2ps->streamlength += gl2psPrintf |
3398 "(%s) Tj\n" | 3403 ("BT\n" |
3399 "ET\n", | 3404 "/F%d %d Tf\n" |
3400 cnt, text->fontsize, x, y, text->str); | 3405 "%f %f Td\n" |
3406 "(%s) Tj\n" | |
3407 "ET\n", | |
3408 cnt, text->fontsize, x, y, text->str); | |
3409 } | |
3410 else{ | |
3411 rad = (GLfloat)M_PI * text->angle / 180.0F; | |
3412 srad = (GLfloat)sin(rad); | |
3413 crad = (GLfloat)cos(rad); | |
3414 gl2ps->streamlength += gl2psPrintf | |
3415 ("BT\n" | |
3416 "/F%d %d Tf\n" | |
3417 "%f %f %f %f %f %f Tm\n" | |
3418 "(%s) Tj\n" | |
3419 "ET\n", | |
3420 cnt, text->fontsize, crad, srad, -srad, crad, x, y, text->str); | |
3421 } | |
3401 } | 3422 } |
3402 | 3423 |
3403 static void gl2psPutPDFImage(GL2PSimage *image, int cnt, GLfloat x, GLfloat y) | 3424 static void gl2psPutPDFImage(GL2PSimage *image, int cnt, GLfloat x, GLfloat y) |
3404 { | 3425 { |
3405 gl2ps->streamlength += | 3426 gl2ps->streamlength += gl2psPrintf |
3406 gl2psPrintf("q\n" | 3427 ("q\n" |
3407 "%d 0 0 %d %f %f cm\n" | 3428 "%d 0 0 %d %f %f cm\n" |
3408 "/Im%d Do\n" | 3429 "/Im%d Do\n" |
3409 "Q\n", | 3430 "Q\n", |
3410 (int)image->width, (int)image->height, x, y, cnt); | 3431 (int)image->width, (int)image->height, x, y, cnt); |
3411 } | 3432 } |
3412 | 3433 |
3413 static void gl2psPDFstacksInit(void) | 3434 static void gl2psPDFstacksInit(void) |
3414 { | 3435 { |
3415 gl2ps->objects_stack = 7 /* FIXED_XREF_ENTRIES */ + 1; | 3436 gl2ps->objects_stack = 7 /* FIXED_XREF_ENTRIES */ + 1; |
4469 static int gl2psPrintPDFPixmapStreamData(GL2PSimage *im, | 4490 static int gl2psPrintPDFPixmapStreamData(GL2PSimage *im, |
4470 size_t (*action)(unsigned long data, | 4491 size_t (*action)(unsigned long data, |
4471 size_t size), | 4492 size_t size), |
4472 int gray) | 4493 int gray) |
4473 { | 4494 { |
4474 int x, y; | 4495 int x, y, shift; |
4475 GLfloat r, g, b, a; | 4496 GLfloat r, g, b, a; |
4476 | 4497 |
4477 if(im->format != GL_RGBA && gray) | 4498 if(im->format != GL_RGBA && gray) |
4478 return 0; | 4499 return 0; |
4479 | 4500 |
4480 if(gray && gray !=8 && gray != 16) | 4501 if(gray && gray != 8 && gray != 16) |
4481 gray = 8; | 4502 gray = 8; |
4482 | 4503 |
4483 gray /= 8; | 4504 gray /= 8; |
4484 | 4505 |
4506 shift = (sizeof(unsigned long) - 1) * 8; | |
4507 | |
4485 for(y = 0; y < im->height; ++y){ | 4508 for(y = 0; y < im->height; ++y){ |
4486 for(x = 0; x < im->width; ++x){ | 4509 for(x = 0; x < im->width; ++x){ |
4487 a = gl2psGetRGB(im, x, y, &r, &g, &b); | 4510 a = gl2psGetRGB(im, x, y, &r, &g, &b); |
4488 if(im->format == GL_RGBA && gray){ | 4511 if(im->format == GL_RGBA && gray){ |
4489 (*action)((unsigned long)(a*255) << 24, gray); | 4512 (*action)((unsigned long)(a * 255) << shift, gray); |
4490 } | 4513 } |
4491 else{ | 4514 else{ |
4492 (*action)((unsigned long)(r*255) << 24, 1); | 4515 (*action)((unsigned long)(r * 255) << shift, 1); |
4493 (*action)((unsigned long)(g*255) << 24, 1); | 4516 (*action)((unsigned long)(g * 255) << shift, 1); |
4494 (*action)((unsigned long)(b*255) << 24, 1); | 4517 (*action)((unsigned long)(b * 255) << shift, 1); |
4495 } | 4518 } |
4496 } | 4519 } |
4497 } | 4520 } |
4498 | 4521 |
4499 switch(gray){ | 4522 switch(gray){ |
5780 GLint xorig, GLint yorig, | 5803 GLint xorig, GLint yorig, |
5781 GLenum format, GLenum type, | 5804 GLenum format, GLenum type, |
5782 const void *pixels) | 5805 const void *pixels) |
5783 { | 5806 { |
5784 int size, i; | 5807 int size, i; |
5785 GLfloat pos[4], *piv; | 5808 GLfloat pos[4], *piv, zoom_x, zoom_y; |
5786 GL2PSprimitive *prim; | 5809 GL2PSprimitive *prim; |
5787 GLboolean valid; | 5810 GLboolean valid; |
5788 | 5811 |
5789 if(!gl2ps || !pixels) return GL2PS_UNINITIALIZED; | 5812 if(!gl2ps || !pixels) return GL2PS_UNINITIALIZED; |
5790 | 5813 |
5800 | 5823 |
5801 glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid); | 5824 glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid); |
5802 if(GL_FALSE == valid) return GL2PS_SUCCESS; /* the primitive is culled */ | 5825 if(GL_FALSE == valid) return GL2PS_SUCCESS; /* the primitive is culled */ |
5803 | 5826 |
5804 glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); | 5827 glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); |
5828 glGetFloatv(GL_ZOOM_X, &zoom_x); | |
5829 glGetFloatv(GL_ZOOM_Y, &zoom_y); | |
5805 | 5830 |
5806 prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); | 5831 prim = (GL2PSprimitive*)gl2psMalloc(sizeof(GL2PSprimitive)); |
5807 prim->type = GL2PS_PIXMAP; | 5832 prim->type = GL2PS_PIXMAP; |
5808 prim->boundary = 0; | 5833 prim->boundary = 0; |
5809 prim->numverts = 1; | 5834 prim->numverts = 1; |
5818 prim->width = 1; | 5843 prim->width = 1; |
5819 glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba); | 5844 glGetFloatv(GL_CURRENT_RASTER_COLOR, prim->verts[0].rgba); |
5820 prim->data.image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage)); | 5845 prim->data.image = (GL2PSimage*)gl2psMalloc(sizeof(GL2PSimage)); |
5821 prim->data.image->width = width; | 5846 prim->data.image->width = width; |
5822 prim->data.image->height = height; | 5847 prim->data.image->height = height; |
5848 prim->data.image->zoom_x = zoom_x; | |
5849 prim->data.image->zoom_y = zoom_y; | |
5823 prim->data.image->format = format; | 5850 prim->data.image->format = format; |
5824 prim->data.image->type = type; | 5851 prim->data.image->type = type; |
5825 | 5852 |
5826 switch(format){ | 5853 switch(format){ |
5827 case GL_RGBA: | 5854 case GL_RGBA: |
5831 size = height * width * 3; | 5858 size = height * width * 3; |
5832 prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat)); | 5859 prim->data.image->pixels = (GLfloat*)gl2psMalloc(size * sizeof(GLfloat)); |
5833 piv = (GLfloat*)pixels; | 5860 piv = (GLfloat*)pixels; |
5834 for(i = 0; i < size; ++i, ++piv){ | 5861 for(i = 0; i < size; ++i, ++piv){ |
5835 prim->data.image->pixels[i] = *piv; | 5862 prim->data.image->pixels[i] = *piv; |
5836 if(!((i+1)%3)) | 5863 if(!((i + 1) % 3)) |
5837 ++piv; | 5864 ++piv; |
5838 } | 5865 } |
5839 } | 5866 } |
5840 else{ | 5867 else{ |
5841 size = height * width * 4; | 5868 size = height * width * 4; |