34#include <glib/gi18n.h>
66 if (layers[i].cr == NULL)
68 cairo_restore(layers[i].cr);
89 cairo_t *temp_layer_cr;
92 temp_layer_cr = layers[i].
cr;
93 if (temp_layer_cr == NULL)
97 cairo_save(temp_layer_cr);
98 cairo_translate(temp_layer_cr, (
double)origin->
x/scale, (
double)origin->
y/scale);
99 cairo_rotate(temp_layer_cr, M_PI*rotation/180.0);
100 cairo_scale(temp_layer_cr, magnification,
101 (flipping == TRUE ? -magnification : magnification));
113 GList *instance_list;
123 for (instance_list = cell->
child_cells; instance_list != NULL; instance_list = instance_list->next) {
125 temp_cell = cell_instance->
cell_ref;
126 if (temp_cell != NULL) {
131 cell_instance->
angle,
139 for (gfx_list = cell->
graphic_objs; gfx_list != NULL; gfx_list = gfx_list->next) {
155 cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT);
158 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
161 cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
166 for (vertex_list = gfx->
vertices; vertex_list != NULL; vertex_list = vertex_list->next) {
167 vertex = (
struct gds_point *)vertex_list->data;
170 if (vertex_list->prev == NULL)
171 cairo_move_to(cr, vertex->
x/scale, vertex->
y/scale);
173 cairo_line_to(cr, vertex->
x/scale, vertex->
y/scale);
184 cairo_set_line_width(cr, 0.1/scale);
185 cairo_close_path(cr);
186 cairo_stroke_preserve(cr);
207 unsigned int buff_cnt = 0;
209 while ((cnt = read(fd, &c, 1)) == 1) {
210 if (buff_cnt < (buff_size-1)) {
211 buff[buff_cnt++] = c;
220 return (
int)buff_cnt;
236 const char *pdf_file,
237 const char *svg_file,
240 cairo_surface_t *pdf_surface = NULL, *svg_surface = NULL;
241 cairo_t *pdf_cr = NULL, *svg_cr = NULL;
247 double rec_x0, rec_y0, rec_width, rec_height;
248 double xmin = INT32_MAX, xmax = INT32_MIN, ymin = INT32_MAX, ymax = INT32_MIN;
251 char receive_message[200];
253 if (pdf_file == NULL && svg_file == NULL) {
259 if (pipe(comm_pipe) == -1)
269 if (process_id < 0) {
271 fprintf(stderr, _(
"Fatal error: Cairo Renderer: Could not spawn child process!"));
273 }
else if (process_id > 0) {
297 layers[i].
rec = NULL;
301 for (info_list = layer_infos; info_list != NULL; info_list = g_list_next(info_list)) {
308 lay = &(layers[(
unsigned int)linfo->
layer]);
310 lay->
rec = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA,
312 lay->
cr = cairo_create(layers[(
unsigned int)linfo->
layer].
rec);
313 cairo_scale(lay->
cr, 1, -1);
314 cairo_set_source_rgb(lay->
cr, linfo->
color.red, linfo->
color.green, linfo->
color.blue);
316 printf(
"Layer number (%d) too high!\n", linfo->
layer);
317 goto ret_clear_layers;
321 dprintf(comm_pipe[1],
"Rendering layers\n");
325 for (info_list = layer_infos; info_list != NULL; info_list = g_list_next(info_list)) {
329 printf(_(
"Layer number too high / outside of spec.\n"));
337 cairo_recording_surface_ink_extents(layers[linfo->
layer].
rec, &rec_x0, &rec_y0,
338 &rec_width, &rec_height);
339 dprintf(comm_pipe[1], _(
"Size of layer %d%s%s%s: <%lf x %lf> @ (%lf | %lf)\n"),
341 (linfo->
name && linfo->
name[0] ?
" (" :
""),
343 (linfo->
name && linfo->
name[0] ?
")" :
""),
344 rec_width, rec_height, rec_x0, rec_y0);
347 xmin =
MIN(xmin, rec_x0);
348 xmax =
MAX(xmax, rec_x0);
349 ymin =
MIN(ymin, rec_y0);
350 ymax =
MAX(ymax, rec_y0);
351 xmin =
MIN(xmin, rec_x0+rec_width);
352 xmax =
MAX(xmax, rec_x0+rec_width);
353 ymin =
MIN(ymin, rec_y0+rec_height);
354 ymax =
MAX(ymax, rec_y0+rec_height);
361 pdf_surface = cairo_pdf_surface_create(pdf_file, xmax-xmin, ymax-ymin);
362 pdf_cr = cairo_create(pdf_surface);
366 svg_surface = cairo_svg_surface_create(svg_file, xmax-xmin, ymax-ymin);
367 svg_cr = cairo_create(svg_surface);
371 for (info_list = layer_infos; info_list != NULL; info_list = g_list_next(info_list)) {
375 printf(_(
"Layer outside of spec.\n"));
382 dprintf(comm_pipe[1], _(
"Exporting layer %d to file\n"), linfo->
layer);
384 if (pdf_file && pdf_cr) {
385 cairo_set_source_surface(pdf_cr, layers[linfo->
layer].
rec, -xmin, -ymin);
386 cairo_paint_with_alpha(pdf_cr, linfo->
color.alpha);
389 if (svg_file && svg_cr) {
390 cairo_set_source_surface(svg_cr, layers[linfo->
layer].
rec, -xmin, -ymin);
391 cairo_paint_with_alpha(svg_cr, linfo->
color.alpha);
396 cairo_show_page(pdf_cr);
397 cairo_destroy(pdf_cr);
398 cairo_surface_destroy(pdf_surface);
402 cairo_show_page(svg_cr);
403 cairo_destroy(svg_cr);
404 cairo_surface_destroy(svg_surface);
411 cairo_destroy(lay->
cr);
412 cairo_surface_destroy(lay->
rec);
417 printf(_(
"Cairo export finished. It might still be buggy!\n"));
425 while (
read_line_from_fd(comm_pipe[0], receive_message,
sizeof(receive_message)) > 0) {
427 for (i = 0; receive_message[i] !=
'\0'; i++) {
428 if (receive_message[i] ==
'\n')
429 receive_message[i] =
' ';
436 waitpid(process_id, NULL, 0);
452 CairoRenderer *c_renderer = GDS_RENDER_CAIRO_RENDERER(renderer);
453 const char *pdf_file = NULL;
454 const char *svg_file = NULL;
455 LayerSettings *settings;
456 GList *layer_infos = NULL;
457 const char *output_file;
470 if (c_renderer->svg == TRUE)
471 svg_file = output_file;
473 pdf_file = output_file;
479 g_object_unref(settings);
486 GdsOutputRendererClass *renderer_class = GDS_RENDER_OUTPUT_RENDERER_CLASS(klass);
493 CairoRenderer *renderer;
496 renderer->svg = FALSE;
503 CairoRenderer *renderer;
506 renderer->svg = TRUE;
Header File for Cairo output renderer.
static int cairo_renderer_render_output(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale)
static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, double scale)
render_cell Render a cell with its sub-cells
static void revert_inherited_transform(struct cairo_layer *layers)
Revert the last transformation on all layers.
static int read_line_from_fd(int fd, char *buff, size_t buff_size)
Read a line from a file descriptor.
static void cairo_renderer_class_init(CairoRendererClass *klass)
#define GDS_RENDER_TYPE_CAIRO_RENDERER
CairoRenderer * cairo_renderer_new_pdf()
Create new CairoRenderer for PDF output.
static void apply_inherited_transform_to_all_layers(struct cairo_layer *layers, const struct gds_point *origin, double magnification, gboolean flipping, double rotation, double scale)
Applies transformation to all layers.
static void cairo_renderer_init(CairoRenderer *self)
#define MAX_LAYERS
Maximum layer count the output renderer can process. Typically GDS only specifies up to 255 layers.
static int cairo_renderer_render_cell_to_vector_file(GdsOutputRenderer *renderer, struct gds_cell *cell, GList *layer_infos, const char *pdf_file, const char *svg_file, double scale)
Render cell to a PDF file specified by pdf_file.
CairoRenderer * cairo_renderer_new_svg()
Create new CairoRenderer for SVG output.
@ GRAPHIC_POLYGON
An arbitrary polygon.
@ GRAPHIC_PATH
Path. Esentially a line.
@ GRAPHIC_BOX
A rectangle.
const char * gds_output_renderer_get_output_file(GdsOutputRenderer *renderer)
Convenience function for getting the "output-file" property.
void gds_output_renderer_update_async_progress(GdsOutputRenderer *renderer, const char *status)
This function emits the 'progress-changed' in the thread/context that triggered an asynchronous rende...
LayerSettings * gds_output_renderer_get_and_ref_layer_settings(GdsOutputRenderer *renderer)
Get layer settings.
#define GDS_RENDER_TYPE_OUTPUT_RENDERER
#define MIN(a, b)
Return smaller number.
#define MAX(a, b)
Return bigger number.
GList * layer_settings_get_layer_info_list(LayerSettings *settings)
Get a GList with layer_info structs.
gboolean svg
TRUE: SVG output, FALSE: PDF output.
The cairo_layer struct Each rendered layer is represented by this struct.
cairo_surface_t * rec
Recording surface to hold the layer.
struct layer_info * linfo
Reference to layer information.
cairo_t * cr
cairo context for layer
This represents an instanc of a cell inside another cell.
int flipped
Mirrored on x-axis before rotation.
double angle
Angle of rotation (counter clockwise) in degrees.
double magnification
magnification
struct gds_cell * cell_ref
Referenced gds_cell structure.
struct gds_point origin
Origin.
A Cell inside a gds_library.
GList * child_cells
List of gds_cell_instance elements.
GList * graphic_objs
List of gds_graphics.
enum graphics_type gfx_type
Type of graphic.
enum path_type path_render_type
Line cap.
int width_absolute
Width. Not used for objects other than paths.
int16_t layer
Layer the graphic object is on.
GList * vertices
List of gds_point.
A point in the 2D plane. Sometimes referred to as vertex.
int render
true: Render to output
GdkRGBA color
RGBA color used to render this layer.