diff options
Diffstat (limited to 'src/sc_interp.c')
-rw-r--r-- | src/sc_interp.c | 1148 |
1 files changed, 0 insertions, 1148 deletions
diff --git a/src/sc_interp.c b/src/sc_interp.c deleted file mode 100644 index 07f09a5..0000000 --- a/src/sc_interp.c +++ /dev/null @@ -1,1148 +0,0 @@ -/* - * sc_interp.c - * - * Copyright © 2014-2018 Thomas White <taw@bitwiz.org.uk> - * - * This file is part of Colloquium. - * - * Colloquium is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <pango/pangocairo.h> -#include <gdk/gdk.h> - -#include "imagestore.h" -#include "sc_parse.h" -#include "sc_interp.h" -#include "presentation.h" -#include "utils.h" - - -struct sc_state -{ - PangoFontDescription *fontdesc; - PangoFont *font; - PangoAlignment alignment; - double col[4]; - int ascent; - int height; - float paraspace[4]; - char *constants[NUM_SC_CONSTANTS]; - - struct frame *fr; /* The current frame */ -}; - -struct _scinterp -{ - PangoContext *pc; - PangoLanguage *lang; - ImageStore *is; - - struct slide_constants *s_constants; - struct presentation_constants *p_constants; - - struct sc_state *state; - int j; /* Index of the current state */ - int max_state; - - SCCallbackList *cbl; -}; - -struct _sccallbacklist -{ - int n_callbacks; - int max_callbacks; - char **names; - SCCallbackBoxFunc *box_funcs; - SCCallbackDrawFunc *draw_funcs; - SCCallbackClickFunc *click_funcs; - void **vps; -}; - - -static int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss) -{ - while ( bl != NULL ) { - if ( sc_interp_add_block(scin, bl, ss) ) return 1; - bl = sc_block_next(bl); - } - - return 0; -} - - -SCCallbackList *sc_callback_list_new() -{ - SCCallbackList *cbl; - - cbl = malloc(sizeof(struct _sccallbacklist)); - if ( cbl == NULL ) return NULL; - - cbl->names = calloc(8, sizeof(char *)); - if ( cbl->names == NULL ) { - free(cbl); - return NULL; - } - - cbl->box_funcs = calloc(8, sizeof(cbl->box_funcs[0])); - if ( cbl->box_funcs == NULL ) { - free(cbl->names); - free(cbl); - return NULL; - } - - cbl->draw_funcs = calloc(8, sizeof(cbl->draw_funcs[0])); - if ( cbl->draw_funcs == NULL ) { - free(cbl->box_funcs); - free(cbl->names); - free(cbl); - return NULL; - } - - cbl->click_funcs = calloc(8, sizeof(cbl->click_funcs[0])); - if ( cbl->click_funcs == NULL ) { - free(cbl->draw_funcs); - free(cbl->box_funcs); - free(cbl->names); - free(cbl); - return NULL; - } - - cbl->vps = calloc(8, sizeof(cbl->vps[0])); - if ( cbl->vps == NULL ) { - free(cbl->click_funcs); - free(cbl->draw_funcs); - free(cbl->box_funcs); - free(cbl->names); - free(cbl); - return NULL; - } - - cbl->max_callbacks = 8; - cbl->n_callbacks = 0; - - return cbl; -} - - -void sc_callback_list_free(SCCallbackList *cbl) -{ - int i; - - if ( cbl == NULL ) return; - - for ( i=0; i<cbl->n_callbacks; i++ ) { - free(cbl->names[i]); - } - - free(cbl->names); - free(cbl->box_funcs); - free(cbl->draw_funcs); - free(cbl->vps); - free(cbl); - -} - - -void sc_callback_list_add_callback(SCCallbackList *cbl, const char *name, - SCCallbackBoxFunc box_func, - SCCallbackDrawFunc draw_func, - SCCallbackClickFunc click_func, - void *vp) -{ - if ( cbl->n_callbacks == cbl->max_callbacks ) { - - SCCallbackBoxFunc *box_funcs_new; - SCCallbackDrawFunc *draw_funcs_new; - SCCallbackClickFunc *click_funcs_new; - char **names_new; - void **vps_new; - int mcn = cbl->max_callbacks + 8; - - names_new = realloc(cbl->names, mcn*sizeof(char *)); - box_funcs_new = realloc(cbl->box_funcs, - mcn*sizeof(SCCallbackBoxFunc)); - draw_funcs_new = realloc(cbl->draw_funcs, - mcn*sizeof(SCCallbackDrawFunc)); - click_funcs_new = realloc(cbl->click_funcs, - mcn*sizeof(SCCallbackClickFunc)); - vps_new = realloc(cbl->vps, mcn*sizeof(void *)); - - if ( (names_new == NULL) || (box_funcs_new == NULL) - || (vps_new == NULL) || (draw_funcs_new == NULL) - || (click_funcs_new == NULL) ) { - fprintf(stderr, "Failed to grow callback list\n"); - return; - } - - cbl->names = names_new; - cbl->box_funcs = box_funcs_new; - cbl->draw_funcs = draw_funcs_new; - cbl->click_funcs = click_funcs_new; - cbl->vps = vps_new; - cbl->max_callbacks = mcn; - - } - - cbl->names[cbl->n_callbacks] = strdup(name); - cbl->box_funcs[cbl->n_callbacks] = box_func; - cbl->draw_funcs[cbl->n_callbacks] = draw_func; - cbl->click_funcs[cbl->n_callbacks] = click_func; - cbl->vps[cbl->n_callbacks] = vp; - cbl->n_callbacks++; -} - - -void sc_interp_set_callbacks(SCInterpreter *scin, SCCallbackList *cbl) -{ - if ( scin->cbl != NULL ) { - fprintf(stderr, "WARNING: Interpreter already has a callback " - "list.\n"); - } - scin->cbl = cbl; -} - - -static int check_callback(SCInterpreter *scin, SCBlock *bl) -{ - int i; - const char *name = sc_block_name(bl); - SCCallbackList *cbl = scin->cbl; - - /* No callback list -> easy */ - if ( cbl == NULL ) return 0; - - /* No name -> definitely not a callback */ - if ( name == NULL ) return 0; - - for ( i=0; i<cbl->n_callbacks; i++ ) { - - double w, h; - int r; - void *bvp; - - if ( strcmp(cbl->names[i], name) != 0 ) continue; - r = cbl->box_funcs[i](scin, bl, &w, &h, &bvp, cbl->vps[i]); - if ( r ) { - struct sc_state *st = &scin->state[scin->j]; - Paragraph *pnew; - pnew = add_callback_para(sc_interp_get_frame(scin), - bl, w, h, - cbl->draw_funcs[i], - cbl->click_funcs[i], - bvp, cbl->vps[i]); - if ( pnew != NULL ) { - set_para_spacing(pnew, st->paraspace); - } - - } - return 1; - - } - - return 0; -} - - -PangoFontDescription *sc_interp_get_fontdesc(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - return st->fontdesc; -} - - -double *sc_interp_get_fgcol(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - return st->col; -} - - -static void set_frame_default_style(struct frame *fr, SCInterpreter *scin) -{ - if ( fr == NULL ) return; - - if ( fr->fontdesc != NULL ) { - pango_font_description_free(fr->fontdesc); - } - fr->fontdesc = pango_font_description_copy(sc_interp_get_fontdesc(scin)); - fr->col[0] = sc_interp_get_fgcol(scin)[0]; - fr->col[1] = sc_interp_get_fgcol(scin)[1]; - fr->col[2] = sc_interp_get_fgcol(scin)[2]; - fr->col[3] = sc_interp_get_fgcol(scin)[3]; -} - - -static void update_font(SCInterpreter *scin) -{ - PangoFontMetrics *metrics; - struct sc_state *st = &scin->state[scin->j]; - - if ( scin->pc == NULL ) return; - - st->font = pango_font_map_load_font(pango_context_get_font_map(scin->pc), - scin->pc, st->fontdesc); - if ( st->font == NULL ) { - char *f = pango_font_description_to_string(st->fontdesc); - fprintf(stderr, "Couldn't load font '%s' (font map %p, pc %p)\n", - f, pango_context_get_font_map(scin->pc), scin->pc); - g_free(f); - return; - } - - /* FIXME: Language for box */ - metrics = pango_font_get_metrics(st->font, NULL); - st->ascent = pango_font_metrics_get_ascent(metrics); - st->height = st->ascent + pango_font_metrics_get_descent(metrics); - pango_font_metrics_unref(metrics); - set_frame_default_style(sc_interp_get_frame(scin), scin); -} - - -static void set_font(SCInterpreter *scin, const char *font_name) -{ - struct sc_state *st = &scin->state[scin->j]; - - st->fontdesc = pango_font_description_from_string(font_name); - if ( st->fontdesc == NULL ) { - fprintf(stderr, "Couldn't describe font.\n"); - return; - } - - update_font(scin); -} - - -static void copy_top_fontdesc(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - - /* If this is the first stack frame, don't even check */ - if ( scin->j == 0 ) return; - - /* If the fontdesc at the top of the stack is the same as the one - * below, make a copy because we're about to do something to it (which - * should not affect the next level up). */ - if ( st->fontdesc == scin->state[scin->j-1].fontdesc ) { - st->fontdesc = pango_font_description_copy(st->fontdesc); - } -} - - -static void set_fontsize(SCInterpreter *scin, const char *size_str) -{ - struct sc_state *st = &scin->state[scin->j]; - int size; - char *end; - - if ( size_str[0] == '\0' ) return; - - size = strtoul(size_str, &end, 10); - if ( end[0] != '\0' ) { - fprintf(stderr, _("Invalid font size '%s'\n"), size_str); - return; - } - - copy_top_fontdesc(scin); - pango_font_description_set_size(st->fontdesc, size*PANGO_SCALE); - update_font(scin); -} - - -static void set_bold(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - copy_top_fontdesc(scin); - pango_font_description_set_weight(st->fontdesc, PANGO_WEIGHT_BOLD); - update_font(scin); -} - - -static void set_oblique(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - copy_top_fontdesc(scin); - pango_font_description_set_style(st->fontdesc, PANGO_STYLE_OBLIQUE); - update_font(scin); -} - - -static void set_italic(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - copy_top_fontdesc(scin); - pango_font_description_set_style(st->fontdesc, PANGO_STYLE_ITALIC); - update_font(scin); -} - - -static void set_alignment(SCInterpreter *scin, PangoAlignment align) -{ - struct sc_state *st = &scin->state[scin->j]; - st->alignment = align; -} - - -/* 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_state *st = &scin->state[scin->j]; - - if ( colour == NULL ) { - printf(_("Invalid colour\n")); - st->col[0] = 0.0; - st->col[1] = 0.0; - st->col[2] = 0.0; - st->col[3] = 1.0; - return; - } - - gdk_rgba_parse(&col, colour); - - st->col[0] = col.red; - st->col[1] = col.green; - st->col[2] = col.blue; - st->col[3] = col.alpha; - set_frame_default_style(sc_interp_get_frame(scin), scin); -} - - -static void set_bgcol(SCInterpreter *scin, const char *colour) -{ - GdkRGBA col; - struct frame *fr = sc_interp_get_frame(scin); - - if ( fr == NULL ) return; - - if ( colour == NULL ) { - printf(_("Invalid colour\n")); - return; - } - - gdk_rgba_parse(&col, colour); - - fr->bgcol[0] = col.red; - fr->bgcol[1] = col.green; - fr->bgcol[2] = col.blue; - fr->bgcol[3] = col.alpha; - fr->grad = GRAD_NONE; -} - - -static void set_bggrad(SCInterpreter *scin, const char *options, - GradientType grad) -{ - struct frame *fr = sc_interp_get_frame(scin); - GdkRGBA col1, col2; - - if ( fr == NULL ) return; - - if ( options == NULL ) { - printf(_("Invalid colour\n")); - return; - } - - if ( parse_colour_duo(options, &col1, &col2) == 0 ) { - - fr->bgcol[0] = col1.red; - fr->bgcol[1] = col1.green; - fr->bgcol[2] = col1.blue; - fr->bgcol[3] = col1.alpha; - - fr->bgcol2[0] = col2.red; - fr->bgcol2[1] = col2.green; - fr->bgcol2[2] = col2.blue; - fr->bgcol2[3] = col2.alpha; - - fr->grad = grad; - - } -} - - -static char *get_constant(SCInterpreter *scin, unsigned int constant) -{ - struct sc_state *st = &scin->state[scin->j]; - if ( constant >= NUM_SC_CONSTANTS ) return NULL; - return st->constants[constant]; -} - - -void sc_interp_set_constant(SCInterpreter *scin, unsigned int constant, - const char *val) -{ - struct sc_state *st = &scin->state[scin->j]; - if ( constant >= NUM_SC_CONSTANTS ) return; - if ( val == NULL ) return; - st->constants[constant] = strdup(val); -} - - -void sc_interp_save(SCInterpreter *scin) -{ - if ( scin->j+1 == scin->max_state ) { - - struct sc_state *stack_new; - - stack_new = realloc(scin->state, sizeof(struct sc_state) - * (scin->max_state+8)); - if ( stack_new == NULL ) { - fprintf(stderr, "Failed to add to stack.\n"); - return; - } - - scin->state = stack_new; - scin->max_state += 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. */ - scin->state[scin->j+1] = scin->state[scin->j]; - - scin->j++; -} - - -void sc_interp_restore(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - - if ( scin->j > 0 ) { - - int i; - - if ( st->fontdesc != scin->state[scin->j-1].fontdesc ) - { - pango_font_description_free(st->fontdesc); - } /* else the font is the same as the previous one, and we - * don't need to free it just yet */ - - for ( i=0; i<NUM_SC_CONSTANTS; i++ ) { - if ( st->constants[i] != scin->state[scin->j-1].constants[i] ) { - free(st->constants[i]); - } /* same logic as above */ - } - } - - scin->j--; -} - - -struct frame *sc_interp_get_frame(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - return st->fr; -} - - -static void set_frame(SCInterpreter *scin, struct frame *fr) -{ - struct sc_state *st = &scin->state[scin->j]; - st->fr = fr; -} - - -SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang, - ImageStore *is, struct frame *top) -{ - SCInterpreter *scin; - struct sc_state *st; - int i; - - scin = malloc(sizeof(SCInterpreter)); - if ( scin == NULL ) return NULL; - - scin->state = malloc(8*sizeof(struct sc_state)); - if ( scin->state == NULL ) { - free(scin); - return NULL; - } - scin->j = 0; - scin->max_state = 8; - - scin->pc = pc; - scin->is = is; - scin->s_constants = NULL; - scin->p_constants = NULL; - scin->cbl = NULL; - scin->lang = lang; - - /* Initial state */ - st = &scin->state[0]; - st->fr = NULL; - st->paraspace[0] = 0.0; - st->paraspace[1] = 0.0; - st->paraspace[2] = 0.0; - st->paraspace[3] = 0.0; - st->fontdesc = NULL; - st->col[0] = 0.0; - st->col[1] = 0.0; - st->col[2] = 0.0; - st->col[3] = 1.0; - st->alignment = PANGO_ALIGN_LEFT; - for ( i=0; i<NUM_SC_CONSTANTS; i++ ) { - st->constants[i] = NULL; - } - - /* The "ultimate" default font */ - if ( scin->pc != NULL ) { - set_frame(scin, top); - set_font(scin, "Cantarell Regular 14"); - set_colour(scin, "#000000"); - } - - return scin; -} - - -void sc_interp_destroy(SCInterpreter *scin) -{ - /* Empty the stack */ - while ( scin->j > 0 ) { - sc_interp_restore(scin); - } - - if ( scin->state[0].fontdesc != NULL ) { - pango_font_description_free(scin->state[0].fontdesc); - } - - free(scin->state); - free(scin); -} - - -static void set_padding(struct frame *fr, const char *opts) -{ - float p[4]; - - if ( parse_tuple(opts, p) ) return; - - if ( fr == NULL ) return; - - fr->pad_l = p[0]; - fr->pad_r = p[1]; - fr->pad_t = p[2]; - fr->pad_b = p[3]; -} - - -static void set_paraspace(SCInterpreter *scin, const char *opts) -{ - float p[4]; - struct sc_state *st = &scin->state[scin->j]; - - if ( parse_tuple(opts, p) ) return; - - st->paraspace[0] = p[0]; - st->paraspace[1] = p[1]; - st->paraspace[2] = p[2]; - st->paraspace[3] = p[3]; - - set_para_spacing(last_para(sc_interp_get_frame(scin)), p); -} - - -void update_geom(struct frame *fr) -{ - char geom[256]; - snprintf(geom, 255, "%.1fux%.1fu+%.1f+%.1f", - fr->w, fr->h, fr->x, fr->y); - - /* FIXME: What if there are other options? */ - sc_block_set_options(fr->scblocks, strdup(geom)); -} - - -static int calculate_dims(const char *opt, struct frame *parent, - double *wp, double *hp, double *xp, double *yp) -{ - LengthUnits h_units, w_units; - - if ( parse_dims(opt, wp, hp, &w_units, &h_units, xp, yp) ) { - return 1; - } - - if ( w_units == UNITS_FRAC ) { - if ( parent != NULL ) { - double pw = parent->w; - pw -= parent->pad_l; - pw -= parent->pad_r; - *wp = pw * *wp; - } else { - *wp = -1.0; - } - - } - if ( h_units == UNITS_FRAC ) { - if ( parent != NULL ) { - double ph = parent->h; - ph -= parent->pad_t; - ph -= parent->pad_b; - *hp = ph * *hp; - } else { - *hp = -1.0; - } - } - - return 0; -} - - -static int parse_frame_option(const char *opt, struct frame *fr, - struct frame *parent) -{ - if ( (index(opt, 'x') != NULL) && (index(opt, '+') != NULL) - && (index(opt, '+') != rindex(opt, '+')) ) { - return calculate_dims(opt, parent, &fr->w, &fr->h, &fr->x, &fr->y); - } - - fprintf(stderr, _("Unrecognised frame option '%s'\n"), opt); - - return 1; -} - - -static int parse_frame_options(struct frame *fr, struct frame *parent, - const char *opth) -{ - int i; - size_t len; - size_t start; - char *opt; - - if ( opth == NULL ) return 1; - - opt = strdup(opth); - - len = strlen(opt); - start = 0; - - for ( i=0; i<len; i++ ) { - - /* FIXME: comma might be escaped or quoted */ - if ( opt[i] == ',' ) { - opt[i] = '\0'; - if ( parse_frame_option(opt+start, fr, parent) ) { - return 1; - } - start = i+1; - } - - } - - if ( start != len ) { - if ( parse_frame_option(opt+start, fr, parent) ) return 1; - } - - free(opt); - - return 0; -} - - -static int parse_image_option(const char *opt, struct frame *parent, - double *wp, double *hp, char **filenamep) -{ - if ( (index(opt, 'x') != NULL) && (index(opt, '+') != NULL) - && (index(opt, '+') != rindex(opt, '+')) ) { - double dum; - return calculate_dims(opt, NULL, wp, hp, &dum, &dum); - } - - if ( strncmp(opt, "filename=\"", 10) == 0 ) { - char *fn; - fn = strdup(opt+10); - if ( fn[strlen(fn)-1] != '\"' ) { - fprintf(stderr, "Unterminated filename?\n"); - free(fn); - return 1; - } - fn[strlen(fn)-1] = '\0'; - *filenamep = fn; - return 0; - } - - fprintf(stderr, _("Unrecognised image option '%s'\n"), opt); - - return 1; -} - - -static int parse_image_options(const char *opth, struct frame *parent, - double *wp, double *hp, char **filenamep) -{ - int i; - size_t len; - size_t start; - char *opt; - - if ( opth == NULL ) return 1; - - opt = strdup(opth); - - len = strlen(opt); - start = 0; - - for ( i=0; i<len; i++ ) { - - /* FIXME: comma might be escaped or quoted */ - if ( opt[i] == ',' ) { - opt[i] = '\0'; - if ( parse_image_option(opt+start, parent, - wp, hp, filenamep) ) return 1; - start = i+1; - } - - } - - if ( start != len ) { - if ( parse_image_option(opt+start, parent, - wp, hp, filenamep) ) return 1; - } - - free(opt); - - return 0; -} - - -static void maybe_recurse_before(SCInterpreter *scin, SCBlock *child) -{ - if ( child == NULL ) return; - - sc_interp_save(scin); -} - - -static void maybe_recurse_after(SCInterpreter *scin, SCBlock *child, - Stylesheet *ss) -{ - if ( child == NULL ) return; - - sc_interp_add_blocks(scin, child, ss); - sc_interp_restore(scin); -} - - -static void add_newpara(SCBlock *bl, SCInterpreter *scin) -{ - Paragraph *last_para; - Paragraph *para; - struct sc_state *st = &scin->state[scin->j]; - struct frame *fr = sc_interp_get_frame(scin); - - if ( fr->paras == NULL ) return; - last_para = fr->paras[fr->n_paras-1]; - - set_newline_at_end(last_para, bl); - - /* The block after the \newpara will always be the first one of the - * next paragraph, by definition, even if it's \f or another \newpara */ - para = create_paragraph(fr, sc_block_next(bl)); - set_para_alignment(para, st->alignment); - set_para_spacing(para, st->paraspace); -} - - -/* Add the SCBlock to the text in 'frame', at the end */ -static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl, - PangoLanguage *lang, int editable, SCInterpreter *scin, - const char *real_text) -{ - const char *text = sc_block_contents(bl); - PangoFontDescription *fontdesc; - double *col; - struct sc_state *st = &scin->state[scin->j]; - Paragraph *para; - - /* Empty block? */ - if ( text == NULL && real_text == NULL ) return 1; - - fontdesc = sc_interp_get_fontdesc(scin); - col = sc_interp_get_fgcol(scin); - - para = last_para(fr); - if ( (para == NULL) || (para_type(para) != PARA_TYPE_TEXT) ) { - /* Last paragraph is not text. - * or: no paragraphs yet. - * Either way: Create the first one */ - para = create_paragraph(fr, bl); - } - - set_para_alignment(para, st->alignment); - add_run(para, bl, fontdesc, col, real_text); - set_para_spacing(para, st->paraspace); - - return 0; -} - - -static void apply_style(SCInterpreter *scin, Stylesheet *ss, const char *path) -{ - char *result; - - if ( ss == NULL ) return; - - /* Font */ - result = stylesheet_lookup(ss, path, "font"); - if ( result != NULL ) set_font(scin, result); - - /* Foreground colour */ - result = stylesheet_lookup(ss, path, "fgcol"); - if ( result != NULL ) set_colour(scin, result); - - /* Background (vertical gradient) */ - result = stylesheet_lookup(ss, path, "bggradv"); - if ( result != NULL ) set_bggrad(scin, result, GRAD_VERT); - - /* Background (horizontal gradient) */ - result = stylesheet_lookup(ss, path, "bggradh"); - if ( result != NULL ) set_bggrad(scin, result, GRAD_HORIZ); - - /* Background (solid colour) */ - result = stylesheet_lookup(ss, path, "bgcol"); - if ( result != NULL ) set_bgcol(scin, result); - - /* Padding */ - result = stylesheet_lookup(ss, path, "pad"); - if ( result != NULL ) set_padding(sc_interp_get_frame(scin), result); - - /* Paragraph spacing */ - result = stylesheet_lookup(ss, path, "paraspace"); - if ( result != NULL ) set_paraspace(scin, result); - - /* Alignment */ - result = stylesheet_lookup(ss, path, "alignment"); - if ( result != NULL ) { - if ( strcmp(result, "center") == 0 ) { - set_alignment(scin, PANGO_ALIGN_CENTER); - } - if ( strcmp(result, "left") == 0 ) { - set_alignment(scin, PANGO_ALIGN_LEFT); - } - if ( strcmp(result, "right") == 0 ) { - set_alignment(scin, PANGO_ALIGN_RIGHT); - } - } -} - - -static void output_frame(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss, - const char *stylename) -{ - struct frame *fr; - SCBlock *child = sc_block_child(bl); - const char *options = sc_block_options(bl); - char *result; - - fr = add_subframe(sc_interp_get_frame(scin)); - if ( fr == NULL ) { - fprintf(stderr, _("Failed to add frame.\n")); - return; - } - - fr->scblocks = bl; - fr->resizable = 1; - - /* Lowest priority: current state of interpreter */ - set_frame_default_style(fr, scin); - - /* Next priority: geometry from stylesheet */ - result = stylesheet_lookup(ss, stylename, "geometry"); - if ( result != NULL ) { - parse_frame_options(fr, sc_interp_get_frame(scin), result); - } - - /* Highest priority: parameters to \f (or \slidetitle etc) */ - parse_frame_options(fr, sc_interp_get_frame(scin), options); - - maybe_recurse_before(scin, child); - set_frame(scin, fr); - apply_style(scin, ss, stylename); - maybe_recurse_after(scin, child, ss); -} - - -static int check_outputs(SCBlock *bl, SCInterpreter *scin, Stylesheet *ss) -{ - const char *name = sc_block_name(bl); - const char *options = sc_block_options(bl); - - if ( name == NULL ) { - add_text(sc_interp_get_frame(scin), - scin->pc, bl, scin->lang, 1, scin, NULL); - - } else if ( strcmp(name, "image")==0 ) { - double w, h; - char *filename; - if ( parse_image_options(options, sc_interp_get_frame(scin), - &w, &h, &filename) == 0 ) - { - add_image_para(sc_interp_get_frame(scin), bl, - filename, scin->is, w, h, 1); - free(filename); - } else { - fprintf(stderr, _("Invalid image options '%s'\n"), - options); - } - - } else if ( strcmp(name, "f")==0 ) { - output_frame(scin, bl, ss, "$.slide.frame"); - - } else if ( strcmp(name, "slidetitle")==0 ) { - output_frame(scin, bl, ss, "$.slide.slidetitle"); - - } else if ( strcmp(name, "prestitle")==0 ) { - output_frame(scin, bl, ss, "$.slide.prestitle"); - - } else if ( strcmp(name, "author")==0 ) { - output_frame(scin, bl, ss, "$.slide.author"); - - } else if ( strcmp(name, "footer")==0 ) { - output_frame(scin, bl, ss, "$.slide.footer"); - - } else if ( strcmp(name, "newpara")==0 ) { - add_newpara(bl, scin); - - } else if ( strcmp(name, "slidenumber")==0 ) { - char *con = get_constant(scin, SCCONST_SLIDENUMBER); - if ( con != NULL ) { - add_text(sc_interp_get_frame(scin), scin->pc, bl, - scin->lang, 1, scin, con); - } - - } else { - return 0; - } - - return 1; /* handled */ -} - - -int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss) -{ - const char *name = sc_block_name(bl); - const char *options = sc_block_options(bl); - SCBlock *child = sc_block_child(bl); - - //printf("Running this --------->\n"); - //show_sc_blocks(bl); - //printf("<------------\n"); - - if ( check_callback(scin, bl) ) { - /* Handled in check_callback, don't do anything else */ - - } else if ((sc_interp_get_frame(scin) != NULL) - && check_outputs(bl, scin, ss) ) { - /* Block handled as output thing */ - - } else if ( name == NULL ) { - /* Dummy to ensure name != NULL below */ - - } else if ( strcmp(name, "presentation") == 0 ) { - maybe_recurse_before(scin, child); - apply_style(scin, ss, "$.narrative"); - maybe_recurse_after(scin, child, ss); - - } else if ( strcmp(name, "slide") == 0 ) { - maybe_recurse_before(scin, child); - apply_style(scin, ss, "$.slide"); - maybe_recurse_after(scin, child, ss); - - } else if ( strcmp(name, "font") == 0 ) { - maybe_recurse_before(scin, child); - set_font(scin, options); - maybe_recurse_after(scin, child, ss); - - } else if ( strcmp(name, "fontsize") == 0 ) { - maybe_recurse_before(scin, child); - set_fontsize(scin, options); - maybe_recurse_after(scin, child, ss); - - } else if ( strcmp(name, "bold") == 0 ) { - maybe_recurse_before(scin, child); - set_bold(scin); - maybe_recurse_after(scin, child, ss); - - } else if ( strcmp(name, "oblique") == 0 ) { - maybe_recurse_before(scin, child); - set_oblique(scin); - maybe_recurse_after(scin, child, ss); - - } else if ( strcmp(name, "italic") == 0 ) { - maybe_recurse_before(scin, child); - set_italic(scin); - maybe_recurse_after(scin, child, ss); - - } else if ( strcmp(name, "lalign") == 0 ) { - maybe_recurse_before(scin, child); - set_alignment(scin, PANGO_ALIGN_LEFT); - maybe_recurse_after(scin, child, ss); - - } else if ( strcmp(name, "ralign") == 0 ) { - maybe_recurse_before(scin, child); - set_alignment(scin, PANGO_ALIGN_RIGHT); - maybe_recurse_after(scin, child, ss); - - } else if ( strcmp(name, "center") == 0 ) { - maybe_recurse_before(scin, child); - set_alignment(scin, PANGO_ALIGN_CENTER); - maybe_recurse_after(scin, child, ss); - - } else if ( strcmp(name, "fgcol") == 0 ) { - maybe_recurse_before(scin, child); - set_colour(scin, options); - maybe_recurse_after(scin, child, ss); - - } else if ( strcmp(name, "pad") == 0 ) { - maybe_recurse_before(scin, child); - set_padding(sc_interp_get_frame(scin), options); - maybe_recurse_after(scin, child, ss); - - } else if ( strcmp(name, "bgcol") == 0 ) { - set_bgcol(scin, options); - - } else if ( strcmp(name, "bggradh") == 0 ) { - set_bggrad(scin, options, GRAD_HORIZ); - - } else if ( strcmp(name, "bggradv") == 0 ) { - set_bggrad(scin, options, GRAD_VERT); - - } else if ( strcmp(name, "paraspace") == 0 ) { - maybe_recurse_before(scin, child); - set_paraspace(scin, options); - maybe_recurse_after(scin, child, ss); - - } else { - - fprintf(stderr, "Don't know what to do with this:\n"); - show_sc_block(bl, ""); - - } - - return 0; -} - |