39#include <glibmm/convert.h>
55 std::optional<Colors::Color> background;
58 unsigned (*status)(float,
void *);
74 PngTextList() : count(0), textItems(nullptr) {}
77 void add(gchar
const*
key, gchar
const* text);
78 gint getCount() {
return count;}
79 png_text* getPtext() {
return textItems;}
86PngTextList::~PngTextList() {
87 for (gint i = 0; i < count; i++) {
88 if (textItems[i].
key) {
89 g_free(textItems[i].
key);
91 if (textItems[i].text) {
92 g_free(textItems[i].text);
97void PngTextList::add(gchar
const*
key, gchar
const* text)
103 png_text* tmp = (count > 0) ? g_try_renew(png_text, textItems, count + 1): g_try_new(png_text, 1);
108 png_text*
item = &(textItems[count - 1]);
109 item->compression = PNG_TEXT_COMPRESSION_NONE;
111 item->text = g_strdup(text);
112 item->text_length = 0;
113#ifdef PNG_iTXt_SUPPORTED
114 item->itxt_length = 0;
116 item->lang_key =
nullptr;
119 g_warning(
"Unable to allocate array for %d PNG text data.", count);
132 gchar
const *filename,
unsigned long int width,
unsigned long int height,
double xdpi,
double ydpi,
133 int (* get_rows)(guchar
const **rows,
void **to_free,
int row,
int num_rows,
void *
data,
int color_type,
int bit_depth),
134 void *
data,
bool interlace,
int color_type,
int bit_depth,
int zlib)
136 g_return_val_if_fail(filename !=
nullptr,
false);
137 g_return_val_if_fail(
data !=
nullptr,
false);
139 struct SPEBP *ebp = (
struct SPEBP *)
data;
150 if(fp ==
nullptr)
return false;
158 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
nullptr,
nullptr,
nullptr);
160 if (png_ptr ==
nullptr) {
166 info_ptr = png_create_info_struct(png_ptr);
167 if (info_ptr ==
nullptr) {
169 png_destroy_write_struct(&png_ptr,
nullptr);
176 if (setjmp(png_jmpbuf(png_ptr))) {
179 png_destroy_write_struct(&png_ptr, &info_ptr);
184 png_init_io(png_ptr, fp);
195 png_set_compression_level(png_ptr, zlib);
197 png_set_IHDR(png_ptr, info_ptr,
202 interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE,
203 PNG_COMPRESSION_TYPE_BASE,
204 PNG_FILTER_TYPE_BASE);
206 if ((color_type&2) && bit_depth == 16) {
214 png_set_sBIT(png_ptr, info_ptr, &sig_bit);
217 PngTextList textList;
219 textList.add(
"Software",
"www.inkscape.org");
221 const gchar* pngToDc[] = {
"Title",
"title",
223 "Description",
"description",
225 "Creation Time",
"date",
231 for (
size_t i = 0; i < G_N_ELEMENTS(pngToDc); i += 2) {
236 textList.add(pngToDc[i],
data);
239 g_warning(
"Unable to find entity [%s]", pngToDc[i + 1]);
246 if (license->
name && license->
uri) {
247 gchar* tmp = g_strdup_printf(
"%s %s", license->
name, license->
uri);
248 textList.add(
"Copyright", tmp);
250 }
else if (license->
name) {
251 textList.add(
"Copyright", license->
name);
252 }
else if (license->
uri) {
253 textList.add(
"Copyright", license->
uri);
257 if (textList.getCount() > 0) {
258 png_set_text(png_ptr, info_ptr, textList.getPtext(), textList.getCount());
264 if(xdpi < 0.0254 ) xdpi = 0.0255;
265 if(ydpi < 0.0254 ) ydpi = 0.0255;
267 png_set_pHYs(png_ptr, info_ptr,
unsigned(xdpi / 0.0254 ),
unsigned(ydpi / 0.0254 ), PNG_RESOLUTION_METER);
270 png_write_info(png_ptr, info_ptr);
289 png_bytep* row_pointers =
new png_bytep[ebp->sheight];
290 int number_of_passes = interlace ? png_set_interlace_handling(png_ptr) : 1;
292 for(
int i=0;i<number_of_passes; ++i){
294 while (r <
static_cast<png_uint_32
>(
height)) {
296 int n = get_rows((
unsigned char const **) row_pointers, &to_free, r,
height-r,
data, color_type, bit_depth);
298 png_write_rows(png_ptr, row_pointers, n);
304 delete[] row_pointers;
311 png_write_end(png_ptr, info_ptr);
316 png_destroy_write_struct(&png_ptr, &info_ptr);
332 struct SPEBP *ebp = (
struct SPEBP *)
data;
335 if (!ebp->status((
float) row / ebp->height, ebp->data))
return 0;
337 if (!ebp->background) {
341 num_rows =
MIN(num_rows,
static_cast<int>(ebp->sheight));
342 num_rows =
MIN(num_rows,
static_cast<int>(ebp->height - row));
351 ebp->drawing->update(bbox);
353 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, ebp->width);
354 unsigned char *px = g_new(guchar, num_rows *
stride);
357 px, CAIRO_FORMAT_ARGB32, ebp->width, num_rows,
stride);
365 ebp->drawing->render(dc, bbox, 0);
366 cairo_surface_destroy(s);
373 const guchar* new_data =
pixbuf_to_png(rows, px, num_rows, ebp->width,
stride, color_type, bit_depth);
374 *to_free = (
void*) new_data;
381 double x0,
double y0,
double x1,
double y1,
382 unsigned long int width,
unsigned long int height,
double xdpi,
double ydpi,
383 Colors::Color
const &bgcolor,
384 unsigned int (*status) (
float,
void *),
385 void *
data,
bool force_overwrite,
386 const std::vector<SPItem const *> &items_only,
bool interlace,
int color_type,
int bit_depth,
int zlib,
int antialiasing)
389 width,
height, xdpi, ydpi, bgcolor, status,
data, force_overwrite, items_only, interlace, color_type, bit_depth, zlib, antialiasing);
400 unsigned long width,
unsigned long height,
double xdpi,
double ydpi,
401 Colors::Color
const &bgcolor,
402 unsigned (*status)(
float,
void *),
403 void *
data,
bool force_overwrite,
404 const std::vector<SPItem const *> &items_only,
bool interlace,
int color_type,
int bit_depth,
int zlib,
int antialiasing)
407 g_return_val_if_fail(filename !=
nullptr,
EXPORT_ERROR);
445 ebp.background = bgcolor;
455 ebp.drawing = &drawing;
459 if (!items_only.empty()) {
466 bool write_status =
false;;
469 ebp.px = g_try_new(guchar, 4 * ebp.sheight *
width);
472 write_status =
sp_png_write_rgba_striped(doc, filename,
width,
height, xdpi, ydpi,
sp_export_get_rows, &ebp, interlace, color_type, bit_depth, zlib);
const guchar * pixbuf_to_png(guchar const **rows, guchar *px, int num_rows, int num_cols, int stride, int color_type, int bit_depth)
Converts a pixbuf to a PNG data structure.
void convert_pixels_argb32_to_pixbuf(guchar *data, int w, int h, int stride, guint32 bgcolor)
Convert pixel data from ARGB to GdkPixbuf format.
Cairo integration helpers.
3x3 matrix representing an affine transformation.
Axis aligned, non-empty, generic rectangle.
static CRect from_xywh(C x, C y, C w, C h)
Create rectangle from origin and dimensions.
C height() const
Get the vertical extent of the rectangle.
C width() const
Get the horizontal extent of the rectangle.
CPoint min() const
Get the corner of the rectangle with smallest coordinate values.
Two-dimensional point that doubles as a vector.
Axis aligned, non-empty rectangle.
bool hasZeroArea(Coord eps=EPSILON) const
Check whether the rectangle has zero area up to specified tolerance.
Minimal wrapper over Cairo.
void setSource(cairo_pattern_t *source)
void paint(double alpha=1.0)
void setOperator(cairo_operator_t op)
void setTransform(Geom::Affine const &trans)
void setRoot(DrawingItem *root)
void setAntialiasingOverride(std::optional< Antialiasing > antialiasing_override)
Typed SVG document implementation.
SPRoot * getRoot()
Returns our SPRoot.
int ensureUpToDate(unsigned int object_modified_tag=0)
Repeatedly works on getting the document updated, since sometimes it takes more than one pass to get ...
Inkscape::DrawingItem * invoke_show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags)
void invoke_hide(unsigned int key)
static unsigned int display_key_new(unsigned numkeys)
Allocates unique integer keys.
void invoke_hide_except(unsigned key, const std::vector< SPItem const * > &to_keep)
Invoke hide on all non-group items, except for the list of items to keep.
Cairo drawing context with Inkscape extensions.
struct _cairo_surface cairo_surface_t
bool sp_ui_overwrite_file(std::string const &filename)
If necessary, ask the user if a file may be overwritten.
void dump_fopen_call(char const *utf8name, char const *id)
FILE * fopen_utf8name(char const *utf8name, char const *mode)
Open a file with g_fopen().
static cairo_user_data_key_t key
static int sp_export_get_rows(guchar const **rows, void **to_free, int row, int num_rows, void *data, int color_type, int bit_depth)
static bool sp_png_write_rgba_striped(SPDocument *doc, gchar const *filename, unsigned long int width, unsigned long int height, double xdpi, double ydpi, int(*get_rows)(guchar const **rows, void **to_free, int row, int num_rows, void *data, int color_type, int bit_depth), void *data, bool interlace, int color_type, int bit_depth, int zlib)
Write to PNG.
ExportResult sp_export_png_file(SPDocument *doc, gchar const *filename, double x0, double y0, double x1, double y1, unsigned long int width, unsigned long int height, double xdpi, double ydpi, Colors::Color const &bgcolor, unsigned int(*status)(float, void *), void *data, bool force_overwrite, const std::vector< SPItem const * > &items_only, bool interlace, int color_type, int bit_depth, int zlib, int antialiasing)
struct rdf_work_entity_t * rdf_find_entity(gchar const *name)
Retrieves a known RDF/Work entity by name.
struct rdf_license_t * rdf_get_license(SPDocument *document, bool read_only)
Attempts to match and retrieve a known RDF/License from the document XML.
const gchar * rdf_get_work_entity(SPDocument const *doc, struct rdf_work_entity_t *entity)
Retrieves a known RDF/Work entity's contents from the document XML by name.
Some things pertinent to all visible shapes: SPItem, SPItemView, SPItemCtx.
SPRoot: SVG <svg> implementation.
Holds license name and RDF information.
Holds known RDF/Work tags.