From 5c994f892a094f60753c557d9fccd45d6d5394ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Wed, 19 Jun 2019 19:21:20 +0200 Subject: [PATCH] Issue #19: Implement CairoRenderer as GObject --- .../output-renderers/cairo-renderer.h | 29 +++++-- output-renderers/cairo-renderer.c | 81 +++++++++++++++++-- 2 files changed, 97 insertions(+), 13 deletions(-) diff --git a/include/gds-render/output-renderers/cairo-renderer.h b/include/gds-render/output-renderers/cairo-renderer.h index 072ebf2..35afefd 100644 --- a/include/gds-render/output-renderers/cairo-renderer.h +++ b/include/gds-render/output-renderers/cairo-renderer.h @@ -26,23 +26,36 @@ #include #include +#include +#include -/** @addtogroup Cairo-Renderer +G_BEGIN_DECLS + +/** @addtogroup CairoRenderer * @{ */ +G_DECLARE_FINAL_TYPE(CairoRenderer, cairo_renderer, GDS_RENDER, CAIRO_RENDERER, GdsOutputRenderer) + +#define GDS_RENDER_TYPE_CAIRO_RENDERER (cairo_renderer_get_type()) + #define MAX_LAYERS (300) /**< \brief Maximum layer count the output renderer can process. Typically GDS only specifies up to 255 layers.*/ /** - * @brief Render \p cell to a PDF file specified by \p pdf_file - * @param cell Toplevel cell to @ref Cairo-Renderer - * @param layer_infos List of layer information. Specifies color and layer stacking - * @param pdf_file PDF output file. Set to NULL if no PDF file has to be generated - * @param svg_file SVG output file. Set to NULL if no SVG file has to be generated - * @param scale Scale the output image down by \p scale + * @brief Create new CairoRenderer for SVG output + * @return New object */ -void cairo_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, char *pdf_file, char *svg_file, double scale); +CairoRenderer *cairo_renderer_new_svg(); + + +/** + * @brief Create new CairoRenderer for PDF output + * @return New object + */ +CairoRenderer *cairo_renderer_new_pdf(); /** @} */ +G_END_DECLS + #endif /* _CAIRO_OUTPUT_H_ */ diff --git a/output-renderers/cairo-renderer.c b/output-renderers/cairo-renderer.c index a7de78b..e845014 100644 --- a/output-renderers/cairo-renderer.c +++ b/output-renderers/cairo-renderer.c @@ -22,7 +22,7 @@ * @author Mario Hüttel */ -/** @addtogroup Cairo-Renderer +/** @addtogroup CairoRenderer * @{ */ @@ -36,6 +36,13 @@ #include #include +struct _CairoRenderer { + GdsOutputRenderer parent; + gboolean svg; /**< @brief TRUE: SVG output, FALSE: PDF output */ +}; + +G_DEFINE_TYPE(CairoRenderer, cairo_renderer, GDS_RENDER_TYPE_OUTPUT_RENDERER) + /** * @brief The cairo_layer struct * Each rendered layer is represented by this struct. @@ -181,7 +188,17 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl } -void cairo_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, char *pdf_file, char *svg_file, double scale) +/** + * @brief Render \p cell to a PDF file specified by \p pdf_file + * @param cell Toplevel cell to @ref Cairo-Renderer + * @param layer_infos List of layer information. Specifies color and layer stacking + * @param pdf_file PDF output file. Set to NULL if no PDF file has to be generated + * @param svg_file SVG output file. Set to NULL if no SVG file has to be generated + * @param scale Scale the output image down by \p scale + * @return Error + */ +static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, const char *pdf_file, + const char *svg_file, double scale) { cairo_surface_t *pdf_surface = NULL, *svg_surface = NULL; cairo_t *pdf_cr = NULL, *svg_cr = NULL; @@ -196,7 +213,7 @@ void cairo_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, if (pdf_file == NULL && svg_file == NULL) { /* No output specified */ - return; + return -1; } /* Fork to a new child process. This ensures the memory leaks (see issue #16) in Cairo don't @@ -332,10 +349,64 @@ ret_clear_layers: exit(0); /* Fork didn't work. Just return here */ - return; + return 0; ret_parent: waitpid(process_id, NULL, 0); - return; + return 0; +} + +static void cairo_renderer_init(CairoRenderer *self) +{ + /* PDF default */ + self->svg = FALSE; +} + +static int cairo_renderer_render_output(GdsOutputRenderer *renderer, + struct gds_cell *cell, + GList *layer_infos, + const char *output_file, + double scale) +{ + CairoRenderer *c_renderer = GDS_RENDER_CAIRO_RENDERER(renderer); + const char *pdf_file = NULL; + const char *svg_file = NULL; + + if (!c_renderer) + return -2000; + + if (c_renderer->svg == TRUE) + svg_file = output_file; + else + pdf_file = output_file; + + return cairo_renderer_render_cell_to_vector_file(cell, layer_infos, pdf_file, svg_file, scale); +} + +static void cairo_renderer_class_init(CairoRendererClass *klass) +{ + GdsOutputRendererClass *renderer_class = GDS_RENDER_OUTPUT_RENDERER_CLASS(klass); + + renderer_class->render_output = cairo_renderer_render_output; +} + +CairoRenderer *cairo_renderer_new_pdf() +{ + CairoRenderer *renderer; + + renderer = GDS_RENDER_CAIRO_RENDERER(g_object_new(GDS_RENDER_TYPE_CAIRO_RENDERER, NULL)); + renderer->svg = FALSE; + + return renderer; +} + +CairoRenderer *cairo_renderer_new_svg() +{ + CairoRenderer *renderer; + + renderer = GDS_RENDER_CAIRO_RENDERER(g_object_new(GDS_RENDER_TYPE_CAIRO_RENDERER, NULL)); + renderer->svg = TRUE; + + return renderer; } /** @} */