Пример #1
0
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;
}
Пример #2
0
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;
}