aboutsummaryrefslogtreecommitdiff
path: root/src/sc_interp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sc_interp.c')
-rw-r--r--src/sc_interp.c237
1 files changed, 235 insertions, 2 deletions
diff --git a/src/sc_interp.c b/src/sc_interp.c
index 28182a9..65b113e 100644
--- a/src/sc_interp.c
+++ b/src/sc_interp.c
@@ -28,13 +28,246 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include <pango/pangocairo.h>
+#include <gdk/gdk.h>
#include "sc_parse.h"
#include "sc_interp.h"
+#include "shape.h"
+#include "wrap.h"
struct _scinterp
{
- int dummy;
+ PangoContext *pc;
+ PangoLanguage *lang;
+
+ struct slide_constants *s_constants;
+ struct presentation_constants *p_constants;
+
+ struct sc_font *fontstack;
+ int n_fonts;
+ int max_fonts;
};
-f \ No newline at end of file
+
+static void set_font(SCInterpreter *scin, const char *font_name)
+{
+ PangoFontMetrics *metrics;
+ struct sc_font *scf;
+
+ scf = &scin->fontstack[scin->n_fonts-1];
+
+ scf->fontdesc = pango_font_description_from_string(font_name);
+ if ( scf->fontdesc == NULL ) {
+ fprintf(stderr, "Couldn't describe font.\n");
+ return;
+ }
+ scf->font = pango_font_map_load_font(pango_context_get_font_map(scin->pc),
+ scin->pc, scf->fontdesc);
+ if ( scf->font == NULL ) {
+ fprintf(stderr, "Couldn't load font.\n");
+ return;
+ }
+
+ /* FIXME: Language for box */
+ metrics = pango_font_get_metrics(scf->font, NULL);
+ scf->ascent = pango_font_metrics_get_ascent(metrics);
+ scf->height = scf->ascent + pango_font_metrics_get_descent(metrics);
+ pango_font_metrics_unref(metrics);
+
+ scf->free_font_on_pop = 1;
+}
+
+
+/* This sets the colour for the font at the top of the stack */
+static void set_colour(SCInterpreter *scin, const char *colour)
+{
+ GdkRGBA col;
+ struct sc_font *scf = &scin->fontstack[scin->n_fonts-1];
+
+ if ( colour == NULL ) {
+ printf("Invalid colour\n");
+ scf->col[0] = 0.0;
+ scf->col[1] = 0.0;
+ scf->col[2] = 0.0;
+ scf->col[3] = 1.0;
+ return;
+ }
+
+ gdk_rgba_parse(&col, colour);
+
+ scf->col[0] = col.red;
+ scf->col[1] = col.green;
+ scf->col[2] = col.blue;
+ scf->col[3] = col.alpha;
+}
+
+
+static void copy_top_font(SCInterpreter *scin)
+{
+ if ( scin->n_fonts == scin->max_fonts ) {
+
+ struct sc_font *stack_new;
+
+ stack_new = realloc(scin->fontstack, sizeof(struct sc_font)
+ * ((scin->max_fonts)+8));
+ if ( stack_new == NULL ) {
+ fprintf(stderr, "Failed to push font or colour.\n");
+ return;
+ }
+
+ scin->fontstack = stack_new;
+ scin->max_fonts += 8;
+
+ }
+
+ /* When n_fonts=0, we leave the first font uninitialised. This allows
+ * the stack to be "bootstrapped", but requires the first caller to do
+ * set_font and set_colour straight away. */
+ if ( scin->n_fonts > 0 ) {
+ scin->fontstack[scin->n_fonts] = scin->fontstack[scin->n_fonts-1];
+ }
+
+ /* This is a copy, so don't free it later */
+ scin->fontstack[scin->n_fonts].free_font_on_pop = 0;
+
+ scin->n_fonts++;
+}
+
+
+static void push_font(SCInterpreter *scin, const char *font_name)
+{
+ copy_top_font(scin);
+ set_font(scin, font_name);
+}
+
+
+static void push_colour(SCInterpreter *scin, const char *colour)
+{
+ copy_top_font(scin);
+ set_colour(scin, colour);
+}
+
+
+static void pop_font_or_colour(SCInterpreter *scin)
+{
+ struct sc_font *scf = &scin->fontstack[scin->n_fonts-1];
+
+ if ( scf->free_font_on_pop ) {
+ pango_font_description_free(scf->fontdesc);
+ }
+
+ scin->n_fonts--;
+}
+
+
+SCInterpreter *sc_interp_new()
+{
+ SCInterpreter *scin;
+
+ scin = malloc(sizeof(SCInterpreter));
+ if ( scin == NULL ) return NULL;
+
+ scin->fontstack = NULL;
+ scin->n_fonts = 0;
+ scin->max_fonts = 0;
+
+ scin->pc = NULL;
+ scin->s_constants = NULL;
+ scin->p_constants = NULL;
+
+ /* FIXME: Determine proper language (somehow...) */
+ scin->lang = pango_language_from_string("en_GB");
+
+ /* The "ultimate" default font */
+ push_font(scin, "Sans 12");
+ set_colour(scin, "#000000");
+
+ return scin;
+}
+
+
+void sc_interp_destroy(SCInterpreter *scin)
+{
+ /* Empty the stack */
+ while ( scin->n_fonts > 0 ) {
+ pop_font_or_colour(scin);
+ }
+
+ free(scin);
+}
+
+
+int sc_interp_add_blocks(SCInterpreter *scin, const SCBlock *bl)
+{
+ struct wrap_line *boxes;
+
+ boxes = malloc(sizeof(struct wrap_line));
+ if ( boxes == NULL ) {
+ fprintf(stderr, "Failed to allocate boxes.\n");
+ return 1;
+ }
+ initialise_line(boxes);
+
+ while ( bl != NULL ) {
+
+ const char *name = sc_block_name(bl);
+ const char *contents = sc_block_contents(bl);
+
+ if ( name == NULL ) {
+ split_words(boxes, scin->pc, contents,
+ scin->lang, 1,
+ &scin->fontstack[scin->n_fonts-1]);
+
+#if 0
+ /* FIXME ... ! */
+
+ } else if ( (strcmp(name, "font")==0) && (contents == NULL) ) {
+ set_font(fonts, b->options, pc);
+
+ } else if ( (strcmp(name, "font")==0) && (contents != NULL) ) {
+ push_font(fonts, b->options, pc);
+ run_sc(b->contents, fonts, pc, boxes, lang, offset,
+ editable, fr, slide_constants,
+ presentation_constants);
+ pop_font_or_colour(fonts);
+
+ } else if ( (strcmp(name, "fgcol")==0)
+ && (contents == NULL) ) {
+ set_colour(fonts, b->options);
+
+ } else if ( (strcmp(name, "fgcol")==0) && (contents != NULL) ) {
+ push_colour(fonts, b->options);
+ run_sc(b->contents, fonts, pc, boxes, lang, offset,
+ editable, fr, slide_constants,
+ presentation_constants);
+ pop_font_or_colour(fonts);
+
+ } else if ( (strcmp(name, "image")==0)
+ && (contents != NULL) && (b->options != NULL) ) {
+ int w, h;
+ if ( get_size(b->options, fr, &w, &h) == 0 ) {
+ add_image_box(boxes, b->contents, offset, w, h,
+ editable);
+ }
+
+ } else if ( strcmp(name, "slidenumber")==0) {
+ char *tmp = malloc(64);
+ if ( tmp != NULL ) {
+ snprintf(tmp, 63, "%i",
+ slide_constants->slide_number);
+ add_wrap_box(boxes, tmp, offset,
+ WRAP_SPACE_NONE, pc,
+ &fonts->stack[fonts->n_fonts-1],
+ 0);
+ } /* else go away and sulk about it */
+#endif
+
+ }
+
+ bl = sc_block_next(bl);
+
+ }
+
+ return 0;
+}