static bool pdf_render_document_to_file(SPDocument *doc, gchar const *filename, unsigned int level, bool texttopath, bool omittext, bool filtertobitmap, int resolution, const gchar * const exportId, bool exportDrawing, bool exportCanvas, float bleedmargin_px) { doc->ensureUpToDate(); /* Start */ SPItem *base = NULL; bool pageBoundingBox = TRUE; if (exportId && strcmp(exportId, "")) { // we want to export the given item only base = SP_ITEM(doc->getObjectById(exportId)); pageBoundingBox = exportCanvas; } else { // we want to export the entire document from root base = doc->getRoot(); pageBoundingBox = !exportDrawing; } if (!base) { return false; } /* Create new arena */ Inkscape::Drawing drawing; drawing.setExact(true); unsigned dkey = SPItem::display_key_new(1); base->invoke_show(drawing, dkey, SP_ITEM_SHOW_DISPLAY); /* Create renderer and context */ CairoRenderer *renderer = new CairoRenderer(); CairoRenderContext *ctx = renderer->createContext(); ctx->setPDFLevel(level); ctx->setTextToPath(texttopath); ctx->setOmitText(omittext); ctx->setFilterToBitmap(filtertobitmap); ctx->setBitmapResolution(resolution); bool ret = ctx->setPdfTarget (filename); if(ret) { /* Render document */ ret = renderer->setupDocument(ctx, doc, pageBoundingBox, bleedmargin_px, base); if (ret) { renderer->renderItem(ctx, base); ret = ctx->finish(); } } base->invoke_hide(dkey); renderer->destroyContext(ctx); delete renderer; return ret; }
ExportResult sp_export_png_file(SPDocument *doc, gchar const *filename, Geom::Rect const &area, unsigned long width, unsigned long height, double xdpi, double ydpi, unsigned long bgcolor, unsigned (*status)(float, void *), void *data, bool force_overwrite, GSList *items_only) { g_return_val_if_fail(doc != NULL, EXPORT_ERROR); g_return_val_if_fail(filename != NULL, EXPORT_ERROR); g_return_val_if_fail(width >= 1, EXPORT_ERROR); g_return_val_if_fail(height >= 1, EXPORT_ERROR); g_return_val_if_fail(!area.hasZeroArea(), EXPORT_ERROR); if (!force_overwrite && !sp_ui_overwrite_file(filename)) { // aborted overwrite return EXPORT_ABORTED; } doc->ensureUpToDate(); /* Calculate translation by transforming to document coordinates (flipping Y)*/ Geom::Point translation = Geom::Point(-area[Geom::X][0], area[Geom::Y][1] - doc->getHeight().value("px")); /* This calculation is only valid when assumed that (x0,y0)= area.corner(0) and (x1,y1) = area.corner(2) * 1) a[0] * x0 + a[2] * y1 + a[4] = 0.0 * 2) a[1] * x0 + a[3] * y1 + a[5] = 0.0 * 3) a[0] * x1 + a[2] * y1 + a[4] = width * 4) a[1] * x0 + a[3] * y0 + a[5] = height * 5) a[1] = 0.0; * 6) a[2] = 0.0; * * (1,3) a[0] * x1 - a[0] * x0 = width * a[0] = width / (x1 - x0) * (2,4) a[3] * y0 - a[3] * y1 = height * a[3] = height / (y0 - y1) * (1) a[4] = -a[0] * x0 * (2) a[5] = -a[3] * y1 */ Geom::Affine const affine(Geom::Translate(translation) * Geom::Scale(width / area.width(), height / area.height())); //SP_PRINT_MATRIX("SVG2PNG", &affine); struct SPEBP ebp; ebp.width = width; ebp.height = height; ebp.background = bgcolor; /* Create new drawing */ Inkscape::Drawing drawing; drawing.setExact(true); // export with maximum blur rendering quality unsigned const dkey = SPItem::display_key_new(1); // Create ArenaItems and set transform drawing.setRoot(doc->getRoot()->invoke_show(drawing, dkey, SP_ITEM_SHOW_DISPLAY)); drawing.root()->setTransform(affine); ebp.drawing = &drawing; // We show all and then hide all items we don't want, instead of showing only requested items, // because that would not work if the shown item references something in defs if (items_only) { hide_other_items_recursively(doc->getRoot(), items_only, dkey); } ebp.status = status; ebp.data = data; bool write_status = false;; ebp.sheight = 64; ebp.px = g_try_new(guchar, 4 * ebp.sheight * width); if (ebp.px) { write_status = sp_png_write_rgba_striped(doc, filename, width, height, xdpi, ydpi, sp_export_get_rows, &ebp); g_free(ebp.px); } // Hide items, this releases arenaitem doc->getRoot()->invoke_hide(dkey); return write_status ? EXPORT_OK : EXPORT_ERROR; }