Scott
Scott

Reputation: 103

How do I write an image into an SVG file using cairo?

I have some code that looks like this:

cairo_surface_t * surface = cairo_svg_surface_create("0.svg", 512, 512);
cairo_t * context = cairo_create(surface);

int * data = new int[512*512];

// fill the data...

cairo_surface_t * image_surface = 
    cairo_image_surface_for_data(data, 512, 512, 512*4);
cairo_set_source_surface(context, image_surface, 0, 0);
cairo_paint(context);

// do some other drawing ...

cairo_surface_flush(surface);
cairo_surface_finish(surface);
cairo_surface_destroy(surface);
cairo_destroy(context);

However, the svg always appears corrupted. The image is not properly written, and all drawing commands following do not work. Changing the surface type to PS, ie:

cairo_surface_t * surface = cairo_ps_surface_create("0.ps", 512, 512);

produces a perfectly correct PS document. Any help fixing the SVG would be appreciated.

EDIT: Forgot to provide version info. Cairo 1.10.2 as given by cairo_version_string(). g++ 4.52 Running on Ubuntu 11.04

EDIT(2): Ok, I have traced this down to PNG problems with cairo and discovered that cairo_surface_write_to_png does not behave as expected either. Both this function and attempting to embed an image in an SVG cause "out of memory errors", and I still don't know why.

Upvotes: 10

Views: 3404

Answers (3)

luser droog
luser droog

Reputation: 19494

I cannot find cairo_image_surface_for_data in the Cairo documentation. Did you mean cairo_image_surface_create_for_data? If so, you need to use cairo_format_stride_for_width to calculate the array size, and the bitmap data needs to be in the format Cairo expects. Since both of your outputs are corrupted, this strongly suggests that the problem is with the input.

Upvotes: 0

robermorales
robermorales

Reputation: 3488

Perhaps publishing the resulting plain SVG can help.

Upvotes: 0

Seth
Seth

Reputation: 2667

Looks like you may have forgotten to specify the SVG version as:

cairo_svg_surface_restrict_to_version (surface, CAIRO_SVG_VERSION_1_2);

You can do this immediately after creating the surface.

Upvotes: 2

Related Questions