Issue #19: Implement CairoRenderer as GObject

This commit is contained in:
Mario Hüttel 2019-06-19 19:21:20 +02:00
parent 96f1347b2c
commit 5c994f892a
2 changed files with 97 additions and 13 deletions

View File

@ -26,23 +26,36 @@
#include <gds-render/gds-utils/gds-types.h>
#include <gds-render/layer/layer-info.h>
#include <gds-render/output-renderers/gds-output-renderer.h>
#include <glib-object.h>
/** @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_ */

View File

@ -22,7 +22,7 @@
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/** @addtogroup Cairo-Renderer
/** @addtogroup CairoRenderer
* @{
*/
@ -36,6 +36,13 @@
#include <sys/wait.h>
#include <unistd.h>
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;
}
/** @} */