Compare commits

...

2 Commits

3 changed files with 148 additions and 25 deletions

View File

@ -23,34 +23,36 @@
* @author Mario Hüttel <mario.huettel@gmx.net> * @author Mario Hüttel <mario.huettel@gmx.net>
*/ */
#ifndef __LATEX_OUTPUT_H__
#define __LATEX_OUTPUT_H__
/** /**
* @addtogroup LaTeX-Renderer * @addtogroup LaTeX-Renderer
* @{ * @{
*/ */
#include <glib.h> #ifndef _LATEX_OUTPUT_H_
#include <stdio.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> #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 * @brief Buffer for LaTeX Code line in KiB
* @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
*/ */
void latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, double scale, #define LATEX_LINE_BUFFER_KB (10)
gboolean create_pdf_layers, gboolean standalone_document);
/**
* @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

@ -139,6 +139,16 @@ static void external_renderer_set_property(GObject *obj, guint property_id, cons
} }
} }
static void external_renderer_dispose(ExternalRenderer *self)
{
if (self->shared_object_path) {
g_free(self->shared_object_path);
self->shared_object_path = NULL;
}
G_OBJECT_CLASS(external_renderer_parent_class)->dispose(G_OBJECT(self));
}
static GParamSpec *external_renderer_properties[N_PROPERTIES] = {NULL}; static GParamSpec *external_renderer_properties[N_PROPERTIES] = {NULL};
static void external_renderer_class_init(ExternalRendererClass *klass) static void external_renderer_class_init(ExternalRendererClass *klass)
@ -152,9 +162,10 @@ static void external_renderer_class_init(ExternalRendererClass *klass)
/* Override virtual function */ /* Override virtual function */
inherited_parent_class->render_output = external_renderer_render_output; inherited_parent_class->render_output = external_renderer_render_output;
/* Setup property callbacks */ /* Setup Gobject callbacks */
oclass->set_property = external_renderer_set_property; oclass->set_property = external_renderer_set_property;
oclass->get_property = external_renderer_get_property; oclass->get_property = external_renderer_get_property;
oclass->dispose = external_renderer_dispose;
/* Setup properties */ /* Setup properties */
external_renderer_properties[PROP_SO_PATH] = external_renderer_properties[PROP_SO_PATH] =

View File

@ -24,15 +24,33 @@
*/ */
#include <math.h> #include <math.h>
#include <stdio.h>
#include <gds-render/output-renderers/latex-output.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) #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) gboolean create_pdf_layers, gboolean standalone_document)
{ {
GString *working_line; GString *working_line;
if (!tex_file || !layer_infos || !cell) if (!tex_file || !layer_infos || !cell)
return; return -1;
/* 10 kB Line working buffer should be enough */ /* 10 kB Line working buffer should be enough */
working_line = g_string_new_len(NULL, LATEX_LINE_BUFFER_KB*1024); 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); fflush(tex_file);
g_string_free(working_line, TRUE); 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);
} }
/** @} */ /** @} */