Issue #19: Move LaTeX Renderer to GObject

This commit is contained in:
Mario Hüttel 2019-06-18 21:46:43 +02:00
parent d9282d8e5a
commit 2d2ca67c48
2 changed files with 136 additions and 24 deletions

View File

@ -23,34 +23,36 @@
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
#ifndef __LATEX_OUTPUT_H__
#define __LATEX_OUTPUT_H__
/**
* @addtogroup LaTeX-Renderer
* @{
*/
#include <glib.h>
#include <stdio.h>
#ifndef _LATEX_OUTPUT_H_
#define _LATEX_OUTPUT_H_
#include "gds-render/layer/layer-info.h"
#include <gds-render/output-renderers/gds-output-renderer.h>
#include <gds-render/gds-utils/gds-types.h>
#define LATEX_LINE_BUFFER_KB (10) /**< @brief Buffer for LaTeX Code line in KiB */
G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE(LatexRenderer, latex_renderer, GDS_RENDER, LATEX_RENDERER, GdsOutputRenderer)
#define GDS_RENDERER_TYPE_LATEX_RENDERER (latex_renderer_get_type())
/**
* @brief Render \p cell to LateX/TikZ code
* @param cell Cell to render
* @param layer_infos Layer information
* @param tex_file Already opened file to write data in
* @param scale Scale image down by this value
* @param create_pdf_layers Optional content groups used
* @param standalone_document document can be compiled standalone
* @brief Buffer for LaTeX Code line in KiB
*/
void latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, double scale,
gboolean create_pdf_layers, gboolean standalone_document);
#define LATEX_LINE_BUFFER_KB (10)
/**
* @brief Create new LatexRenderer object
* @return New object
*/
LatexRenderer *latex_renderer_new();
G_END_DECLS
#endif /* _LATEX_OUTPUT_H_ */
/** @} */
#endif /* __LATEX_OUTPUT_H__ */

View File

@ -24,15 +24,33 @@
*/
#include <math.h>
#include <stdio.h>
#include <gds-render/output-renderers/latex-output.h>
#include <gdk/gdk.h>
#include <gds-render/layer/layer-info.h>
/**
* @addtogroup LaTeX-Renderer
* @addtogroup LatexRenderer
* @{
*/
/** @brief Writes a GString \p buffer to the fixed file tex_file */
struct _LatexRenderer {
GdsOutputRenderer parent;
gboolean tex_standalone;
gboolean pdf_layers;
};
G_DEFINE_TYPE(LatexRenderer, latex_renderer, GDS_RENDER_TYPE_OUTPUT_RENDERER)
enum {
PROP_STANDALONE = 1,
PROP_PDF_LAYERS,
N_PROPERTIES
};
/**
* @brief Writes a GString \p buffer to the fixed file tex_file
* @note This is a convinience macro. Do not use this anywhere else. It might change behavior in futurtre releases
*/
#define WRITEOUT_BUFFER(buff) fwrite((buff)->str, sizeof(char), (buff)->len, tex_file)
/**
@ -249,14 +267,14 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
}
void latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, double scale,
static int latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, double scale,
gboolean create_pdf_layers, gboolean standalone_document)
{
GString *working_line;
if (!tex_file || !layer_infos || !cell)
return;
return -1;
/* 10 kB Line working buffer should be enough */
working_line = g_string_new_len(NULL, LATEX_LINE_BUFFER_KB*1024);
@ -298,6 +316,98 @@ void latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *
fflush(tex_file);
g_string_free(working_line, TRUE);
return 0;
}
static int latex_renderer_render_output(GdsOutputRenderer *renderer,
struct gds_cell *cell,
GList *layer_infos,
const char *output_file,
double scale)
{
LatexRenderer *l_renderer = GDS_RENDER_LATEX_RENDERER(renderer);
FILE *tex_file;
int ret = -2;
tex_file = fopen(output_file, "w");
if (tex_file) {
ret = latex_render_cell_to_code(cell, layer_infos, tex_file, scale,
l_renderer->pdf_layers, l_renderer->tex_standalone);
fclose(tex_file);
}
return ret;
}
static void latex_renderer_init(LatexRenderer *self)
{
self->pdf_layers = FALSE;
self->tex_standalone = FALSE;
}
static void latex_renderer_get_property(GObject *obj, guint property_id, GValue *value, GParamSpec *pspec)
{
LatexRenderer *self = GDS_RENDER_LATEX_RENDERER(obj);
switch (property_id) {
case PROP_STANDALONE:
g_value_set_boolean(value, self->tex_standalone);
break;
case PROP_PDF_LAYERS:
g_value_set_boolean(value, self->pdf_layers);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
break;
}
}
static void latex_renderer_set_property(GObject *obj, guint property_id, const GValue *value, GParamSpec *pspec)
{
LatexRenderer *self = GDS_RENDER_LATEX_RENDERER(obj);
switch (property_id) {
case PROP_STANDALONE:
self->tex_standalone = g_value_get_boolean(value);
break;
case PROP_PDF_LAYERS:
self->pdf_layers = g_value_get_boolean(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
break;
}
}
static GParamSpec *latex_renderer_properties[N_PROPERTIES] = {NULL};
static void latex_renderer_class_init(LatexRendererClass *klass)
{
GdsOutputRendererClass *render_class = GDS_RENDER_OUTPUT_RENDERER_CLASS(klass);
GObjectClass *oclass = G_OBJECT_CLASS(klass);
/* Overwrite virtual function */
render_class->render_output = latex_renderer_render_output;
/* Property stuff */
oclass->get_property = latex_renderer_get_property;
oclass->set_property = latex_renderer_set_property;
latex_renderer_properties[PROP_STANDALONE] =
g_param_spec_boolean("standalone",
"Standalone TeX file",
"Generate a standalone LaTeX file.",
FALSE,
G_PARAM_READWRITE);
latex_renderer_properties[PROP_PDF_LAYERS] =
g_param_spec_boolean("pdf-layers",
"PDF OCR layers",
"Generate OCR layers",
FALSE,
G_PARAM_READWRITE);
g_object_class_install_properties(oclass, N_PROPERTIES, latex_renderer_properties);
}
/** @} */