1 /* Dia -- a diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * export_png.c: export a diagram to a PNG file.
5 * Copyright (C) 2000 James Henstridge
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #if defined(HAVE_LIBPNG) && defined(HAVE_LIBART)
31 #include "render_libart.h"
35 /* the dots per centimetre to render this diagram at */
36 /* this matches the setting `100%' setting in dia. */
39 /* the height of the band to use when rendering. Smaller bands mean
40 * rendering is slower, but less memory is used. Setting this to G_MAXINT
41 * should get the renderer to use one pass. */
42 #define BAND_HEIGHT 50
45 export_png(DiagramData
*data
, const gchar
*filename
,
46 const gchar
*diafilename
, void* user_data
)
48 Rectangle
*ext
= &data
->extents
;
50 RendererLibart
*renderer
;
51 guint32 width
, height
, band
, row
, i
;
60 width
= (guint32
) ((ext
->right
- ext
->left
) * DPCM
* data
->paper
.scaling
);
61 height
= (guint32
) ((ext
->bottom
- ext
->top
) * DPCM
* data
->paper
.scaling
);
63 /* we render in bands to try to keep memory consumption down ... */
64 band
= MIN(height
, BAND_HEIGHT
);
65 band_height
= (real
)band
/ (DPCM
* data
->paper
.scaling
);
67 /* create a fake ddisp to keep the renderer happy */
68 ddisp
= g_new0(DDisplay
, 1);
69 ddisp
->zoom_factor
= DPCM
* data
->paper
.scaling
;
70 ddisp
->visible
= *ext
;
71 ddisp
->visible
.bottom
= MIN(ddisp
->visible
.bottom
,
72 ddisp
->visible
.top
+ band_height
);
73 renderer
= new_libart_renderer(ddisp
, 0);
74 libart_renderer_set_size(renderer
, NULL
, width
, band
);
75 ddisp
->renderer
= (Renderer
*)renderer
;
77 fp
= fopen(filename
, "wb");
79 message_error(_("Couldn't open: '%s' for writing.\n"), filename
);
83 png
= png_create_write_struct(PNG_LIBPNG_VER_STRING
,
87 message_error(_("Could not create PNG write structure"));
91 /* allocate/initialise the image information data */
92 info
= png_create_info_struct(png
);
95 png_destroy_write_struct(&png
, (png_infopp
)NULL
);
96 message_error(_("Could not create PNG header info structure"));
100 /* set error handling ... */
101 if (setjmp(png
->jmpbuf
)) {
103 png_destroy_write_struct(&png
, (png_infopp
)NULL
);
104 message_error(_("Error occurred while writing PNG"));
107 /* the compiler said band may be clobbered by setjmp, so we set it again
109 band
= MIN(height
, BAND_HEIGHT
);
111 png_init_io(png
, fp
);
114 png_set_IHDR(png
, info
, width
, height
, 8,
115 PNG_COLOR_TYPE_RGB
, PNG_INTERLACE_NONE
,
116 PNG_COMPRESSION_TYPE_BASE
, PNG_FILTER_TYPE_BASE
);
120 png_set_sBIT(png
, info
, &sig_bit
);
122 png_write_info(png
, info
);
123 png_set_shift(png
, &sig_bit
);
124 png_set_packing(png
);
126 row_ptr
= g_new(png_bytep
, band
);
128 for (row
= 0; row
< height
; row
+= band
) {
130 for (i
= 0; i
< width
*band
; i
++) {
131 renderer
->rgb_buffer
[3*i
] = 0xff * data
->bg_color
.red
;
132 renderer
->rgb_buffer
[3*i
+1] = 0xff * data
->bg_color
.green
;
133 renderer
->rgb_buffer
[3*i
+2] = 0xff * data
->bg_color
.blue
;
135 data_render(data
, (Renderer
*)renderer
, &ddisp
->visible
, NULL
,NULL
);
136 /* write rows to png file */
137 for (i
= 0; i
< band
; i
++)
138 row_ptr
[i
] = renderer
->rgb_buffer
+ 3 * i
* width
;
139 png_write_rows(png
, row_ptr
, MIN(band
, height
- row
));
141 ddisp
->visible
.top
+= band_height
;
142 ddisp
->visible
.bottom
+= band_height
;
145 png_write_end(png
, info
);
146 png_destroy_write_struct(&png
, (png_infopp
)NULL
);
150 destroy_libart_renderer(renderer
);
155 static const gchar
*extensions
[] = { "png", NULL
};
156 DiaExportFilter png_export_filter
= {
157 N_("Portable Network Graphics"),