Re: Strange bug (?) when painting/cropping recording surface to PDF surface
"Bernhard R. Fischer" <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <[email protected]> |
On 2016-04-10 09:28, Adrian Johnson wrote:
> On 10/04/16 03:25, Bernhard R. Fischer wrote:
>> Hi!
>>
>> _Background_
>> In my project a record all drawing operations to a recording surface.
>> Finally, to output files I create surfaces of specific backends (PNG,
>> PDF, and SVG) and "crop" (the final surface is smaller than the
>> recording source surface), rotate, and paint the recording surface to it.
>>
>>
>> _Strange Behavior_
>> When using PDF as backend, not everything is painted from the source
>> (recording) surface to the PDF surface. On PNG and SVG it works as expected.
>>
>>
>> _Examples_
>> There is a PNG and PDF example to show the behavior. Look at the right
>> lower corner: right of the string "015°30" the short black lines in the
>> axis are missing compared to the PNG.
>> http://www.abenteuerland.at/download/eagle/output.pdf
>> http://www.abenteuerland.at/download/eagle/output.png
>>
>>
>> _Trigger_
>> I observed, that this behavior is triggered as soon as the PDF surface
>> is smaller than the recording surface.
>>
>>
>> _Code Snippet_
>> The following code snippets shows how I create the PDF and PNG surface
>> from the recording surface (sfc_).
>>
>>
>> /* create PDF from sfc_ */
>> sfc = cairo_pdf_surface_create("output.pdf", width*.7, height*1.3);
>> dst = cairo_create(sfc);
>> cairo_rotate(dst, DEG2RAD(15));
>> cairo_set_source_surface(dst, sfc_, 0, 0);
>> cairo_paint(dst);
>> cairo_show_page(dst);
>> cairo_destroy(dst);
>> cairo_surface_destroy(sfc);
>>
>>
>> /* create PNG from sfc_ */
>> sfc = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width*.7,
>> height*1.3);
>> dst = cairo_create(sfc);
>> cairo_rotate(dst, DEG2RAD(15));
>> cairo_set_source_surface(dst, sfc_, 0, 0);
>> cairo_paint(dst);
>> cairo_show_page(dst);
>> cairo_destroy(dst);
>> cairo_surface_write_to_png(sfc, "output.png");
>> cairo_surface_destroy(sfc);
>>
>>
>> Any hints appreciated.
>
> If you can provide a simple test case that reproduces the bug with the
> current version of cairo I can look into it.
>
Hi!
Please find attached a simple test program which demonstrates it.
I tested it on Cairo 1.14.6 and 1.14.0.
Bernhard
--
cairo mailing list
[email protected]
https://lists.cairographics.org/mailman/listinfo/cairo
rec_test.c
(text/x-csrc, 2.1 KB)
/*! Simple example demonstrating that painting to PDF surface from recording
* surface leads to Cairo dropping some elements.
*
* @author Bernhard R. Fischer
*
* Compile with:
* gcc -Wall -lm `pkg-config --cflags --libs cairo` rec_test.c
*/
#include <stdio.h>
#include <math.h>
#include <cairo.h>
#include <cairo-pdf.h>
#define MAXSIZE 800.0
#define PDFSIZEX 500.0
#define PDFSIZEY 800.0
#define RADIUS 200
/*! Draw something to (recording) surface. */
void draw_to_surface(cairo_surface_t *dst)
{
cairo_t *ctx;
double a;
ctx = cairo_create(dst);
// draw rectangle of PDF size
cairo_set_source_rgb(ctx, 0, 1, 0);
cairo_rectangle(ctx, 0, 0, PDFSIZEX, PDFSIZEY);
cairo_stroke(ctx);
// draw a circle with ticks
cairo_set_source_rgb(ctx, 1, 0, 0);
for (a = 0; a < 2 * M_PI; a += M_PI / 90)
{
cairo_move_to(ctx, MAXSIZE / 2 + RADIUS * cos(a), MAXSIZE / 2 + RADIUS * sin(a));
cairo_line_to(ctx, MAXSIZE / 2 + 0.9 * RADIUS * cos(a), MAXSIZE / 2 + 0.9 * RADIUS * sin(a));
cairo_stroke(ctx);
}
cairo_destroy(ctx);
}
/*! Copy (and rotate) one surface to another one. */
void copy_rec_to_surface(cairo_surface_t *src, cairo_surface_t *dst)
{
cairo_t *ctx;
ctx = cairo_create(dst);
cairo_rotate(ctx, 45 * M_PI / 180); // with the rotation the missing elements get visible
cairo_set_source_surface(ctx, src, 0, 0);
cairo_paint(ctx);
cairo_show_page(ctx);
cairo_destroy(ctx);
}
int main(int argc, char **argv)
{
cairo_surface_t *srec, *sfc;
// create recording surface
srec = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA, NULL);
// draw something to surface
draw_to_surface(srec);
// create PDF surface
sfc = cairo_pdf_surface_create("rec_test.pdf", PDFSIZEX, PDFSIZEY);
copy_rec_to_surface(srec, sfc);
cairo_surface_destroy(sfc);
// create image surface
sfc = cairo_image_surface_create(CAIRO_FORMAT_RGB24, PDFSIZEX, PDFSIZEY);
copy_rec_to_surface(srec, sfc);
cairo_surface_write_to_png(sfc, "rec_test.png");
cairo_surface_destroy(sfc);
// finally destroy recording surface
cairo_surface_destroy(srec);
return 0;
}