119 #if defined ( PLD_png ) || defined ( PLD_jpeg ) || defined ( PLD_gif )
134 #if defined ( PLD_png )
135 "png:PNG file:0:gd:39:png\n"
137 #if defined ( PLD_jpeg )
138 "jpeg:JPEG file:0:gd:40:jpeg\n"
140 #if defined ( PLD_gif )
141 "gif:GIF file:0:gd:47:gif\n"
146 #ifdef PL_HAVE_FREETYPE
147 #define SMOOTH_LINES_OK
151 #ifdef PL_HAVE_FREETYPE
186 #ifdef PL_HAVE_FREETYPE
188 static void plD_pixel_gd(
PLStream *
pls,
short x,
short y );
190 static void plD_set_pixel_gd(
PLStream *
pls,
short x,
short y,
PLINT colour );
198 static int NCOLOURS = gdMaxColors;
208 #define use_experimental_hidden_line_hack
221 #ifndef max_number_of_grey_levels_used_in_text_smoothing
222 #define max_number_of_grey_levels_used_in_text_smoothing 64
227 #ifndef gdImagePalettePixel
228 #define gdImagePalettePixel( im, x, y ) ( im )->pixels[( y )][( x )]
232 int plToGdAlpha(
PLFLT a )
234 int tmp = (int) ( ( 1.0 - a ) * gdAlphaMax );
258 unsigned char TRY_BLENDED_ANTIALIASING;
263 unsigned char smooth;
268 void plD_line_png(
PLStream *,
short,
short,
short,
short );
269 void plD_polyline_png(
PLStream *,
short *,
short *,
PLINT );
285 #ifndef ENABLE_DYNDRIVERS
307 #ifndef ENABLE_DYNDRIVERS
329 #ifndef ENABLE_DYNDRIVERS
361 static int optimise = 0;
362 static int black15 = 0;
363 static int red15 = 0;
365 static int truecolour = 0;
366 static int palette = 0;
367 static int smooth_line = 0;
369 #ifdef PL_HAVE_FREETYPE
370 static int freetype = 1;
371 static int smooth_text = 1;
375 DrvOpt gd_options[] = { {
"optimise",
DRV_INT, &optimise,
"Optimise PNG palette when possible" },
376 {
"def_black15",
DRV_INT, &black15,
"Define idx 15 as black. If the background is \"whiteish\" (from \"-bg\" option), force index 15 (traditionally white) to be \"black\"" },
377 {
"swp_red15",
DRV_INT, &red15,
"Swap index 1 (usually red) and 1 (usually white); always done after \"black15\"; quite useful for quick changes to web pages" },
379 {
"8bit",
DRV_INT, &palette,
"Palette (8 bit) mode" },
380 {
"24bit",
DRV_INT, &truecolour,
"Truecolor (24 bit) mode" },
381 {
"smoothlines",
DRV_INT, &smooth_line,
"Turn line Anti Aliasing on (1) or off (0)" },
383 #ifdef PL_HAVE_FREETYPE
384 {
"text",
DRV_INT, &freetype,
"Use driver text (FreeType)" },
385 {
"smooth",
DRV_INT, &smooth_text,
"Turn text smoothing on (1) or off (0)" },
387 { NULL,
DRV_INT, NULL, NULL } };
393 free( (
void *)
pls->
dev );
395 pls->
dev = calloc( 1, (
size_t)
sizeof ( png_Dev ) );
397 plexit(
"plD_init_png_Dev: Out of memory." );
399 dev = (png_Dev *)
pls->
dev;
408 dev->black15 = black15;
410 dev->optimise = optimise;
414 dev->palette = palette;
415 dev->truecolour = truecolour;
419 if ( ( dev->truecolour > 0 ) && ( dev->palette > 0 ) )
420 plwarn(
"Selecting both \"truecolor\" AND \"palette\" driver options is contradictory, so\nI will just use my best judgment.\n" );
421 else if ( dev->truecolour > 0 )
423 else if ( ( dev->truecolour == 0 ) && ( dev->palette == 0 ) && ( (
pls->
ncol1 +
pls->
ncol0 ) > NCOLOURS ) )
428 if ( ( dev->palette == 0 ) && ( dev->optimise == 0 ) && ( smooth_line == 1 ) )
433 #ifdef PL_HAVE_FREETYPE
445 init_freetype_lv1(
pls );
446 FT = (FT_Data *)
pls->
FT;
447 FT->want_smooth_text = smooth_text > 0 ? 1 : 0;
448 if ( ( dev->optimise == 0 ) && ( dev->palette == 0 ) && ( smooth_text != 0 ) )
450 FT->BLENDED_ANTIALIASING = 1;
484 plD_init_png_Dev(
pls );
485 dev = (png_Dev *)
pls->
dev;
508 #ifdef use_experimental_hidden_line_hack
510 if ( dev->pngx > dev->pngy )
527 plP_setphy( 0, dev->scale * dev->pngx, 0, dev->scale * dev->pngy );
529 #ifdef PL_HAVE_FREETYPE
532 init_freetype_lv2(
pls );
556 static int black15 = 0;
557 static int red15 = 0;
558 #ifdef PL_HAVE_FREETYPE
559 static int freetype = 1;
560 static int smooth_text = 0;
564 DrvOpt gd_options[] = { {
"def_black15",
DRV_INT, &black15,
"Define idx 15 as black. If the background is \"whiteish\" (from \"-bg\" option), force index 15 (traditionally white) to be \"black\"" },
565 {
"swp_red15",
DRV_INT, &red15,
"Swap index 1 (usually red) and 1 (usually white); always done after \"black15\"; quite useful for quick changes to web pages" },
566 #ifdef PL_HAVE_FREETYPE
567 {
"text",
DRV_INT, &freetype,
"Use driver text (FreeType)" },
568 {
"smooth",
DRV_INT, &smooth_text,
"Turn text smoothing on (1) or off (0)" },
570 { NULL,
DRV_INT, NULL, NULL } };
576 free( (
void *)
pls->
dev );
578 pls->
dev = calloc( 1, (
size_t)
sizeof ( png_Dev ) );
580 plexit(
"plD_init_gif_Dev: Out of memory." );
582 dev = (png_Dev *)
pls->
dev;
590 dev->black15 = black15;
597 #ifdef PL_HAVE_FREETYPE
603 init_freetype_lv1(
pls );
604 FT = (FT_Data *)
pls->
FT;
606 FT->want_smooth_text = smooth_text > 0 ? 1 : 0;
638 plD_init_gif_Dev(
pls );
639 dev = (png_Dev *)
pls->
dev;
662 #ifdef use_experimental_hidden_line_hack
664 if ( dev->pngx > dev->pngy )
682 plP_setphy( 0, dev->scale * dev->pngx, 0, dev->scale * dev->pngy );
684 #ifdef PL_HAVE_FREETYPE
687 init_freetype_lv2(
pls );
702 plD_line_png(
PLStream *
pls,
short x1a,
short y1a,
short x2a,
short y2a )
704 png_Dev *dev = (png_Dev *)
pls->
dev;
705 int x1 = x1a / dev->scale, y1 = y1a / dev->scale, x2 = x2a / dev->scale, y2 = y2a / dev->scale;
709 #ifdef SMOOTH_LINES_OK
710 if ( dev->smooth == 1 )
712 gdImageSetAntiAliased( dev->im_out, dev->colour );
713 gdImageLine( dev->im_out, x1, y1, x2, y2, gdAntiAliased );
717 gdImageLine( dev->im_out, x1, y1, x2, y2, dev->colour );
720 gdImageLine( dev->im_out, x1, y1, x2, y2, dev->colour );
735 for ( i = 0; i < npts - 1; i++ )
736 plD_line_png(
pls, xa[i], ya[i], xa[i + 1], ya[i + 1] );
749 png_Dev *dev = (png_Dev *)
pls->
dev;
752 gdPoint *points = NULL;
757 points = malloc( (
size_t)
pls->
dev_npts * sizeof ( gdPoint ) );
761 points[i].x =
pls->
dev_x[i] / dev->scale;
762 points[i].y = dev->pngy - (
pls->
dev_y[i] / dev->scale );
765 #ifdef SMOOTH_LINES_OK
766 if ( dev->smooth == 1 )
768 gdImageSetAntiAliased( dev->im_out, dev->colour );
769 gdImageFilledPolygon( dev->im_out, points,
pls->
dev_npts, gdAntiAliased );
773 gdImageFilledPolygon( dev->im_out, points,
pls->
dev_npts, dev->colour );
776 gdImageFilledPolygon( dev->im_out, points,
pls->
dev_npts, dev->colour );
792 int ncol0 =
pls->
ncol0, total_colours;
794 png_Dev *dev = (png_Dev *)
pls->
dev;
795 PLFLT tmp_colour_pos;
802 if ( dev->im_out != NULL )
804 for ( i = 0; i < 256; i++ )
806 gdImageColorDeallocate( dev->im_out, i );
810 if ( ncol0 > NCOLOURS / 2 )
812 plwarn(
"Too many colours in cmap0." );
813 ncol0 = NCOLOURS / 2;
819 total_colours = ncol0 + ncol1;
821 if ( total_colours > NCOLOURS )
823 total_colours = NCOLOURS;
824 ncol1 = total_colours - ncol0;
828 plexit(
"Problem setting colourmap in PNG or JPEG driver." );
839 if ( ( ncol0 > 0 ) && ( dev->im_out != NULL ) )
841 for ( i = 0; i < ncol0; i++ )
844 gdImageColorAllocateAlpha( dev->im_out,
848 gdImageColorAllocate( dev->im_out,
858 if ( ( ncol1 > 0 ) && ( dev->im_out != NULL ) )
860 for ( i = 0; i < ncol1; i++ )
862 if ( ncol1 < pls->ncol1 )
872 tmp_colour_pos = i > 0 ?
pls->
ncol1 * ( (
PLFLT) i / ncol1 ) : 0;
882 gdImageColorAllocateAlpha( dev->im_out,
883 cmap1col.
r, cmap1col.
g, cmap1col.
b,
884 plToGdAlpha( cmap1col.
a ) );
886 gdImageColorAllocate( dev->im_out,
887 cmap1col.
r, cmap1col.
g, cmap1col.
b );
905 png_Dev *dev = (png_Dev *)
pls->
dev;
906 PLFLT tmp_colour_pos;
916 gdImageSetThickness( dev->im_out,
pls->
width );
924 ( gdImageTrueColor( dev->im_out ) ) )
926 if ( ( dev->totcol < NCOLOURS ) ||
927 ( gdImageTrueColor( dev->im_out ) ) )
931 temp_col = gdImageColorAllocateAlpha( dev->im_out,
pls->
curcolor.
r,
935 temp_col = gdImageColorAllocate( dev->im_out,
pls->
curcolor.
r,
939 if ( gdImageTrueColor( dev->im_out ) )
940 dev->colour = temp_col;
943 dev->colour = dev->totcol;
957 if ( dev->totcol < NCOLOURS )
960 gdImageColorAllocateAlpha( dev->im_out,
pls->
curcolor.
r,
967 dev->colour = dev->totcol;
976 if ( !gdImageTrueColor( dev->im_out ) )
986 dev->colour =
pls->
ncol0 + (int) tmp_colour_pos;
1011 if ( ( dev->im_out != NULL ) && !gdImageTrueColor( dev->im_out ) )
1046 #ifdef PL_HAVE_FREETYPE
1048 plD_render_freetype_text(
pls, (
EscText *) ptr );
1075 dev = (png_Dev *)
pls->
dev;
1082 plD_black15_gd(
pls );
1084 plD_red15_gd(
pls );
1087 if ( ( ( ( ( dev->truecolour > 0 ) && ( dev->palette > 0 ) ) ||
1088 ( ( dev->truecolour == 0 ) && ( dev->palette == 0 ) ) ) &&
1090 ( ( ( dev->palette > 0 ) && ( dev->truecolour == 0 ) ) ) )
1145 #ifdef PL_HAVE_FREETYPE
1148 plD_FreeType_Destroy(
pls );
1254 png_Dev *dev = (png_Dev *)
pls->
dev;
1258 bbuf = calloc( 256, (
size_t) 1 );
1260 plexit(
"plD_gd_optimise: Out of memory." );
1266 bbuf[gdImagePalettePixel( dev->im_out, i, j )] = 1;
1270 for ( i = 0; i < 256; i++ )
1273 gdImageColorDeallocate( dev->im_out, i );
1290 png_Dev *dev = (png_Dev *)
pls->
dev;
1292 int png_compression;
1293 void *im_ptr = NULL;
1298 if ( dev->optimise )
1301 if ( ( ( ( ( dev->truecolour > 0 ) && ( dev->palette > 0 ) ) ||
1302 ( ( dev->truecolour == 0 ) && ( dev->palette == 0 ) ) ) &&
1304 ( ( ( dev->palette > 0 ) && ( dev->truecolour == 0 ) ) ) )
1307 plD_gd_optimise(
pls );
1332 png_compression = ( png_compression > 9 ) ? ( png_compression / 10 ) : png_compression;
1333 im_ptr = gdImagePngPtrEx( dev->im_out, &im_size, png_compression );
1335 im_ptr = gdImagePngPtr( dev->im_out, &im_size );
1339 nwrite = fwrite( im_ptr,
sizeof (
char ), im_size,
pls->
OutFile );
1340 if ( nwrite != im_size )
1341 plabort(
"gd driver: Error writing png file" );
1345 gdImageDestroy( dev->im_out );
1352 #ifdef PL_HAVE_FREETYPE
1361 void plD_pixel_gd(
PLStream *
pls,
short x,
short y )
1363 png_Dev *dev = (png_Dev *)
pls->
dev;
1365 gdImageSetPixel( dev->im_out, x, y, dev->colour );
1377 png_Dev *dev = (png_Dev *)
pls->
dev;
1381 G = GetGValue( colour );
1382 R = GetRValue( colour );
1383 B = GetBValue( colour );
1385 Colour = gdImageColorResolve( dev->im_out, R, G, B );
1386 gdImageSetPixel( dev->im_out, x, y, Colour );
1399 png_Dev *dev = (png_Dev *)
pls->
dev;
1401 unsigned char R, G, B;
1403 colour = gdImageGetTrueColorPixel( dev->im_out, x, y );
1405 R = gdTrueColorGetRed( colour );
1406 G = gdTrueColorGetGreen( colour );
1407 B = gdTrueColorGetBlue( colour );
1409 colour = RGB( R, G, B );
1427 plD_FreeType_init(
pls );
1429 FT = (FT_Data *)
pls->
FT;
1430 FT->pixel = (plD_pixel_fp) plD_pixel_gd;
1431 FT->read_pixel = (plD_read_pixel_fp) plD_read_pixel_gd;
1432 FT->set_pixel = (plD_set_pixel_fp) plD_set_pixel_gd;
1462 png_Dev *dev = (png_Dev *)
pls->
dev;
1463 FT_Data *FT = (FT_Data *)
pls->
FT;
1465 FT->scale = dev->scale;
1466 FT->ymax = dev->pngy;
1468 FT->smooth_text = 0;
1470 if ( ( FT->want_smooth_text == 1 ) && ( FT->BLENDED_ANTIALIASING == 0 ) )
1474 FT->ncol0_width = FT->ncol0_xtra / (
pls->
ncol0 - 1 );
1475 if ( FT->ncol0_width > 4 )
1477 if ( FT->ncol0_width > max_number_of_grey_levels_used_in_text_smoothing )
1478 FT->ncol0_width = max_number_of_grey_levels_used_in_text_smoothing;
1489 pl_set_extended_cmap0(
pls, FT->ncol0_width, FT->ncol0_org );
1492 FT->smooth_text = 1;
1495 plwarn(
"Insufficient colour slots available in CMAP0 to do text smoothing." );
1497 else if ( ( FT->want_smooth_text == 1 ) && ( FT->BLENDED_ANTIALIASING == 1 ) )
1499 FT->smooth_text = 1;
1516 png_Dev *dev = (png_Dev *)
pls->
dev;
1518 void *im_ptr = NULL;
1520 int jpeg_compression;
1528 jpeg_compression = 90;
1536 im_ptr = gdImageJpegPtr( dev->im_out, &im_size, jpeg_compression );
1539 nwrite = fwrite( im_ptr,
sizeof (
char ), im_size,
pls->
OutFile );
1540 if ( nwrite != im_size )
1541 plabort(
"gd driver: Error writing png file" );
1545 gdImageDestroy( dev->im_out );
1562 png_Dev *dev = (png_Dev *)
pls->
dev;
1564 void *im_ptr = NULL;
1573 im_ptr = gdImageGifPtr( dev->im_out, &im_size );
1576 nwrite = fwrite( im_ptr,
sizeof (
char ), im_size,
pls->
OutFile );
1577 if ( nwrite != im_size )
1578 plabort(
"gd driver: Error writing png file" );
1582 gdImageDestroy( dev->im_out );