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;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.