diff options
-rw-r--r-- | src/frame.c | 53 | ||||
-rw-r--r-- | src/frame.h | 3 | ||||
-rw-r--r-- | src/render.c | 11 | ||||
-rw-r--r-- | src/sc_editor.c | 4 | ||||
-rw-r--r-- | src/sc_interp.c | 54 | ||||
-rw-r--r-- | src/sc_interp.h | 5 |
6 files changed, 104 insertions, 26 deletions
diff --git a/src/frame.c b/src/frame.c index 2f533ff..6f11d34 100644 --- a/src/frame.c +++ b/src/frame.c @@ -38,7 +38,8 @@ struct text_run { - SCBlock *scblock; /* If macro, this is \macro */ + SCBlock *scblock; + char *real_text; /* Usually NULL */ PangoFontDescription *fontdesc; double col[4]; }; @@ -129,6 +130,7 @@ static void free_paragraph(Paragraph *para) for ( i=0; i<para->n_runs; i++ ) { pango_font_description_free(para->runs[i].fontdesc); + free(para->runs[i].real_text); /* free(NULL) is OK */ } free(para->runs); if ( para->layout != NULL ) g_object_unref(para->layout); @@ -211,6 +213,26 @@ struct frame *find_frame_with_scblocks(struct frame *fr, SCBlock *scblocks) } +static const char *text_for_run(const struct text_run *run) +{ + if ( run == NULL ) { + fprintf(stderr, _("NULL run passed to text_for_run\n")); + return 0; + } + + if ( run->scblock == NULL ) { + fprintf(stderr, _("NULL scblock in text_for_run\n")); + return 0; + } + + if ( run->real_text != NULL ) { + return run->real_text; + } + + return sc_block_contents(run->scblock); +} + + static size_t run_text_len(const struct text_run *run) { if ( run == NULL ) { @@ -223,6 +245,10 @@ static size_t run_text_len(const struct text_run *run) return 0; } + if ( run->real_text != NULL ) { + return strlen(run->real_text); + } + if ( sc_block_contents(run->scblock) == NULL ) { fprintf(stderr, _("NULL scblock contents in run_text_len\n")); return 0; @@ -279,7 +305,7 @@ void wrap_paragraph(Paragraph *para, PangoContext *pc, double w, size_t run_len; guint16 r, g, b; - run_text = sc_block_contents(para->runs[i].scblock); + run_text = text_for_run(¶->runs[i]); run_len = strlen(run_text); attr = pango_attr_font_desc_new(para->runs[i].fontdesc); @@ -342,7 +368,7 @@ void set_newline_at_end(Paragraph *para, SCBlock *bl) void add_run(Paragraph *para, SCBlock *scblock, - PangoFontDescription *fdesc, double col[4]) + PangoFontDescription *fdesc, double col[4], const char *real_text) { struct text_run *runs_new; @@ -355,6 +381,11 @@ void add_run(Paragraph *para, SCBlock *scblock, para->runs = runs_new; para->runs[para->n_runs].scblock = scblock; + if ( real_text != NULL ) { + para->runs[para->n_runs].real_text = strdup(real_text); + } else { + para->runs[para->n_runs].real_text = NULL; + } para->runs[para->n_runs].fontdesc = pango_font_description_copy(fdesc); para->runs[para->n_runs].col[0] = col[0]; para->runs[para->n_runs].col[1] = col[1]; @@ -685,7 +716,7 @@ void ensure_run(struct frame *fr, struct edit_pos cpos) } para->scblock = bl; - add_run(para, bl, fr->fontdesc, fr->col); + add_run(para, bl, fr->fontdesc, fr->col, NULL); wrap_paragraph(para, NULL, fr->w - fr->pad_l - fr->pad_r, 0, 0); } @@ -918,7 +949,9 @@ size_t pos_trail_to_offset(Paragraph *para, size_t offs, int trail) return 0; } - if ( sc_block_contents(run->scblock) == NULL ) { + /* Get the text for the run */ + run_text = text_for_run(run); + if ( run_text == NULL ) { fprintf(stderr, _("pos_trail_to_offset: No contents " "(%p name=%s, options=%s)\n"), run->scblock, sc_block_name(run->scblock), @@ -926,8 +959,6 @@ size_t pos_trail_to_offset(Paragraph *para, size_t offs, int trail) return 0; } - /* Get the text for the run */ - run_text = sc_block_contents(run->scblock); /* Turn the paragraph offset into a run offset */ para_offset_of_run = get_paragraph_offset(para, nrun); @@ -978,6 +1009,8 @@ int position_editable(struct frame *fr, struct edit_pos cp) return 0; } + if ( para->runs[run].real_text != NULL ) return 0; + return 1; } @@ -1589,7 +1622,7 @@ static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos, end = sc_block_append(np, NULL, NULL, strdup(""), NULL); pnew->n_runs = 0; - add_run(pnew, end, fr->fontdesc, fr->col); + add_run(pnew, end, fr->fontdesc, fr->col, NULL); pnew->scblock = end; wrap_paragraph(pnew, pc, fr->w - fr->pad_l - fr->pad_r, 0, 0); @@ -1607,7 +1640,7 @@ static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos, printf("Splitting run %i. Before:\n", run); show_para(para); - add_run(para, NULL, NULL, col); + add_run(para, NULL, NULL, col, NULL); /* -2 here because add_run increased para->n_runs by 1 */ memmove(¶->runs[run+2], ¶->runs[run+1], (para->n_runs - run - 2)*sizeof(struct text_run)); @@ -1632,7 +1665,7 @@ static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos, for ( i=run+1; i<para->n_runs; i++ ) { double col[4] = {0,0,0,0}; printf("Moving run %i to pos %i\n", i, pnew->n_runs); - add_run(pnew, NULL, NULL, col); + add_run(pnew, NULL, NULL, col, NULL); pnew->runs[pnew->n_runs-1] = para->runs[i]; } pnew->scblock = pnew->runs[0].scblock; diff --git a/src/frame.h b/src/frame.h index f52c6e6..2a15209 100644 --- a/src/frame.h +++ b/src/frame.h @@ -131,7 +131,8 @@ extern void set_newline_at_end(Paragraph *para, SCBlock *bl); extern void show_edit_pos(struct edit_pos a); extern void add_run(Paragraph *para, SCBlock *scblock, - PangoFontDescription *fdesc, double col[4]); + PangoFontDescription *fdesc, double col[4], + const char *real_text); extern Paragraph *insert_paragraph(struct frame *fr, int pos); diff --git a/src/render.c b/src/render.c index f9f4cca..78c5489 100644 --- a/src/render.c +++ b/src/render.c @@ -178,7 +178,7 @@ struct frame *interp_and_shape(SCBlock *scblocks, Stylesheet *stylesheet, PangoLanguage *lang) { SCInterpreter *scin; -// char snum[64]; + char snum[64]; struct frame *top; top = frame_new(); @@ -198,13 +198,8 @@ struct frame *interp_and_shape(SCBlock *scblocks, Stylesheet *stylesheet, sc_interp_set_callbacks(scin, cbl); - /* FIXME: Set up slide number and style sheet */ -// snprintf(snum, 63, "%i", slide_number); -// add_macro(scin, "slidenumber", snum); -// -// if ( stylesheet != NULL ) { -// sc_interp_run_stylesheet(scin, stylesheet); -// } + snprintf(snum, 63, "%i", slide_number); + sc_interp_set_constant(scin, SCCONST_SLIDENUMBER, snum); top->fontdesc = pango_font_description_copy(sc_interp_get_fontdesc(scin)); top->col[0] = sc_interp_get_fgcol(scin)[0]; diff --git a/src/sc_editor.c b/src/sc_editor.c index 2f272d3..47218d9 100644 --- a/src/sc_editor.c +++ b/src/sc_editor.c @@ -1000,7 +1000,7 @@ static void insert_text(char *t, SCEditor *e) return; } add_run(pnew, ad, e->cursor_frame->fontdesc, - e->cursor_frame->col); + e->cursor_frame->col, NULL); wrap_frame(e->cursor_frame, e->pc); @@ -1222,7 +1222,7 @@ static void check_paragraph(struct frame *fr, PangoContext *pc, } scblocks = sc_block_append(scblocks, NULL, NULL, strdup(""), NULL); - add_run(para, scblocks, fr->fontdesc, fr->col); + add_run(para, scblocks, fr->fontdesc, fr->col, NULL); wrap_paragraph(para, pc, fr->w - fr->pad_l - fr->pad_r, 0, 0); } diff --git a/src/sc_interp.c b/src/sc_interp.c index 1d6cce6..73135af 100644 --- a/src/sc_interp.c +++ b/src/sc_interp.c @@ -47,6 +47,7 @@ struct sc_state int ascent; int height; float paraspace[4]; + char *constants[NUM_SC_CONSTANTS]; struct frame *fr; /* The current frame */ }; @@ -480,6 +481,24 @@ static void set_bggrad(SCInterpreter *scin, const char *options, } +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 ) { @@ -512,11 +531,20 @@ 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--; @@ -542,6 +570,7 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang, { SCInterpreter *scin; struct sc_state *st; + int i; scin = malloc(sizeof(SCInterpreter)); if ( scin == NULL ) return NULL; @@ -559,7 +588,9 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang, 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; @@ -572,7 +603,9 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang, st->col[2] = 0.0; st->col[3] = 1.0; st->alignment = PANGO_ALIGN_LEFT; - scin->lang = lang; + for ( i=0; i<NUM_SC_CONSTANTS; i++ ) { + st->constants[i] = NULL; + } /* The "ultimate" default font */ if ( scin->pc != NULL ) { @@ -873,7 +906,8 @@ static void add_newpara(struct frame *fr, SCBlock *bl) /* 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) + PangoLanguage *lang, int editable, SCInterpreter *scin, + const char *real_text) { const char *text = sc_block_contents(bl); PangoFontDescription *fontdesc; @@ -882,7 +916,7 @@ static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl, Paragraph *para; /* Empty block? */ - if ( text == NULL ) return 1; + if ( text == NULL && real_text == NULL ) return 1; fontdesc = sc_interp_get_fontdesc(scin); col = sc_interp_get_fgcol(scin); @@ -896,7 +930,7 @@ static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl, } set_para_alignment(para, st->alignment); - add_run(para, bl, fontdesc, col); + add_run(para, bl, fontdesc, col, real_text); set_para_spacing(para, st->paraspace); return 0; @@ -996,7 +1030,7 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin, Stylesheet *ss) if ( name == NULL ) { add_text(sc_interp_get_frame(scin), - scin->pc, bl, scin->lang, 1, scin); + scin->pc, bl, scin->lang, 1, scin, NULL); } else if ( strcmp(name, "image")==0 ) { double w, h; @@ -1024,10 +1058,20 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin, Stylesheet *ss) } 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 ) { struct frame *fr = sc_interp_get_frame(scin); add_newpara(fr, bl); + } 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; } diff --git a/src/sc_interp.h b/src/sc_interp.h index 418d6a6..764b532 100644 --- a/src/sc_interp.h +++ b/src/sc_interp.h @@ -31,6 +31,9 @@ struct frame; +#define SCCONST_SLIDENUMBER (0) +#define NUM_SC_CONSTANTS (1) + struct presentation; typedef struct _scinterp SCInterpreter; typedef struct _sccallbacklist SCCallbackList; @@ -52,6 +55,8 @@ extern void sc_interp_restore(SCInterpreter *scin); extern int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss); +extern void sc_interp_set_constant(SCInterpreter *scin, unsigned int constant, + const char *val); /* Callback lists */ extern SCCallbackList *sc_callback_list_new(); |