aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.me.uk>2018-11-04 21:28:54 +0100
committerThomas White <taw@bitwiz.me.uk>2018-11-04 21:28:54 +0100
commitc22018024f483e1a087a972cc2e297d42d4b0e98 (patch)
treeb59b522b6b8a3f527280f048db48cb93eb65f178 /src
parent0f1f30d27a87232cfecd6ed0c68b91c96561ce87 (diff)
Restore \slidenumber
Diffstat (limited to 'src')
-rw-r--r--src/frame.c53
-rw-r--r--src/frame.h3
-rw-r--r--src/render.c11
-rw-r--r--src/sc_editor.c4
-rw-r--r--src/sc_interp.c54
-rw-r--r--src/sc_interp.h5
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(&para->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(&para->runs[run+2], &para->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();