diff options
author | Thomas White <taw@bitwiz.me.uk> | 2018-10-28 00:03:51 +0200 |
---|---|---|
committer | Thomas White <taw@bitwiz.me.uk> | 2018-10-28 00:03:51 +0200 |
commit | 8e05062ad3b94068825a1f80eb362aa3d3e9098f (patch) | |
tree | 77944d65437fa57755a7bc8bc16fd3e2c5b43f17 /src | |
parent | 791ee4e65f3ec7ef470302e4381baefb431fb56d (diff) | |
parent | 21418cfb52b87a32cfdc9bb14be83b85a8e70281 (diff) |
Merge branch 'json-stylesheets'
Diffstat (limited to 'src')
-rw-r--r-- | src/colloquium.c | 6 | ||||
-rw-r--r-- | src/colloquium.h | 1 | ||||
-rw-r--r-- | src/debugger.c | 23 | ||||
-rw-r--r-- | src/frame.c | 212 | ||||
-rw-r--r-- | src/frame.h | 27 | ||||
-rw-r--r-- | src/narrative_window.c | 102 | ||||
-rw-r--r-- | src/presentation.c | 136 | ||||
-rw-r--r-- | src/presentation.h | 5 | ||||
-rw-r--r-- | src/print.c | 12 | ||||
-rw-r--r-- | src/render.c | 28 | ||||
-rw-r--r-- | src/render.h | 4 | ||||
-rw-r--r-- | src/sc_editor.c | 28 | ||||
-rw-r--r-- | src/sc_editor.h | 11 | ||||
-rw-r--r-- | src/sc_interp.c | 727 | ||||
-rw-r--r-- | src/sc_interp.h | 29 | ||||
-rw-r--r-- | src/sc_parse.c | 92 | ||||
-rw-r--r-- | src/sc_parse.h | 7 | ||||
-rw-r--r-- | src/slide_window.c | 2 | ||||
-rw-r--r-- | src/slide_window.h | 1 | ||||
-rw-r--r-- | src/stylesheet.c | 234 | ||||
-rw-r--r-- | src/stylesheet.h | 48 | ||||
-rw-r--r-- | src/stylesheet_editor.c | 594 | ||||
-rw-r--r-- | src/stylesheet_editor.h | 29 | ||||
-rw-r--r-- | src/utils.c | 92 | ||||
-rw-r--r-- | src/utils.h | 3 |
25 files changed, 915 insertions, 1538 deletions
diff --git a/src/colloquium.c b/src/colloquium.c index 66e3dcb..a8da4d9 100644 --- a/src/colloquium.c +++ b/src/colloquium.c @@ -320,12 +320,6 @@ int colloquium_get_hidepointer(Colloquium *app) } -GtkBuilder *colloquium_get_uibuilder(Colloquium *app) -{ - return app->builder; -} - - static void colloquium_startup(GApplication *papp) { Colloquium *app = COLLOQUIUM(papp); diff --git a/src/colloquium.h b/src/colloquium.h index 4c8133f..89f600f 100644 --- a/src/colloquium.h +++ b/src/colloquium.h @@ -38,7 +38,6 @@ typedef struct _colloquium Colloquium; extern const char *colloquium_get_imagestore(Colloquium *app); extern int colloquium_get_hidepointer(Colloquium *app); -extern GtkBuilder *colloquium_get_uibuilder(Colloquium *app); extern void open_about_dialog(GtkWidget *parent); diff --git a/src/debugger.c b/src/debugger.c index edb79e1..12ef9d8 100644 --- a/src/debugger.c +++ b/src/debugger.c @@ -109,25 +109,17 @@ static void debug_text_para(Paragraph *para, cairo_t *cr, double *ypos, for ( i=0; i<nrun; i++ ) { SCBlock *scblock; - SCBlock *rscblock; - if ( para_debug_run_info(para, i, &scblock, &rscblock) ) { + if ( para_debug_run_info(para, i, &scblock) ) { /* Failed to get debug info for paragraph */ plot_text(cr, ypos, fontdesc, _("Error")); } else { - - if ( scblock != rscblock ) { - snprintf(tmp, 255, " Run %i: SCBlock %p / %p", i, - scblock, rscblock); - } else { - snprintf(tmp, 255, " Run %i: SCBlock %p", i, - scblock); - } + snprintf(tmp, 255, " Run %i: SCBlock %p", i, scblock); plot_text(cr, ypos, fontdesc, tmp); - } } - snprintf(tmp, 255, "Newline at end: %p", get_newline_at_end(para)); + snprintf(tmp, 255, "Newline at end: %p", + para_debug_get_newline_at_end(para)); plot_text(cr, ypos, fontdesc, tmp); } @@ -161,17 +153,12 @@ static gboolean dbg_draw_sig(GtkWidget *da, cairo_t *cr, struct debugwindow *dbg enum para_type t = para_type(dbgw->fr->paras[i]); SCBlock *scblock = para_scblock(dbgw->fr->paras[i]); - SCBlock *rscblock = para_rscblock(dbgw->fr->paras[i]); plot_hr(cr, &ypos, width); snprintf(tmp, 255, "Paragraph %i: type %s", i, str_type(t)); plot_text(cr, &ypos, fontdesc, tmp); - if ( scblock == rscblock ) { - snprintf(tmp, 255, "SCBlock %p", scblock); - } else { - snprintf(tmp, 255, "SCBlock %p / %p", scblock, rscblock); - } + snprintf(tmp, 255, "SCBlock %p", scblock); plot_text(cr, &ypos, fontdesc, tmp); if ( t == PARA_TYPE_TEXT ) { diff --git a/src/frame.c b/src/frame.c index d4a5637..2926d4e 100644 --- a/src/frame.c +++ b/src/frame.c @@ -39,7 +39,6 @@ struct text_run { SCBlock *scblock; /* If macro, this is \macro */ - SCBlock *rscblock; /* The block with the actual text */ PangoFontDescription *fontdesc; double col[4]; }; @@ -61,7 +60,6 @@ struct _paragraph /* For anything other than PARA_TYPE_TEXT * (for text paragraphs, these things are in the runs) */ SCBlock *scblock; - SCBlock *rscblock; /* For PARA_TYPE_IMAGE */ char *filename; @@ -186,7 +184,7 @@ struct frame *add_subframe(struct frame *fr) } -void show_hierarchy(struct frame *fr, const char *t) +void show_frame_hierarchy(struct frame *fr, const char *t) { int i; char tn[1024]; @@ -197,65 +195,12 @@ void show_hierarchy(struct frame *fr, const char *t) printf(_("%s%p (%.2f x %.2f)\n"), t, fr, fr->w, fr->h); for ( i=0; i<fr->num_children; i++ ) { - show_hierarchy(fr->children[i], tn); + show_frame_hierarchy(fr->children[i], tn); } } -static struct frame *find_parent(struct frame *fr, struct frame *search) -{ - int i; - - for ( i=0; i<fr->num_children; i++ ) { - if ( fr->children[i] == search ) { - return fr; - } - } - - for ( i=0; i<fr->num_children; i++ ) { - struct frame *tt; - tt = find_parent(fr->children[i], search); - if ( tt != NULL ) return tt; - } - - return NULL; -} - - -void delete_subframe(struct frame *top, struct frame *fr) -{ - struct frame *parent; - int i, idx, found; - - parent = find_parent(top, fr); - if ( parent == NULL ) { - fprintf(stderr, _("Couldn't find parent when deleting frame.\n")); - return; - } - - found = 0; - for ( i=0; i<parent->num_children; i++ ) { - if ( parent->children[i] == fr ) { - idx = i; - found = 1; - break; - } - } - - if ( !found ) { - fprintf(stderr, _("Couldn't find child when deleting frame.\n")); - return; - } - - for ( i=idx; i<parent->num_children-1; i++ ) { - parent->children[i] = parent->children[i+1]; - } - - parent->num_children--; -} - - struct frame *find_frame_with_scblocks(struct frame *fr, SCBlock *scblocks) { int i; @@ -279,17 +224,17 @@ static size_t run_text_len(const struct text_run *run) return 0; } - if ( run->rscblock == NULL ) { - fprintf(stderr, _("NULL rscblock in run_text_len\n")); + if ( run->scblock == NULL ) { + fprintf(stderr, _("NULL scblock in run_text_len\n")); return 0; } - if ( sc_block_contents(run->rscblock) == NULL ) { - fprintf(stderr, _("NULL rscblock contents in run_text_len\n")); + if ( sc_block_contents(run->scblock) == NULL ) { + fprintf(stderr, _("NULL scblock contents in run_text_len\n")); return 0; } - return strlen(sc_block_contents(run->rscblock)); + return strlen(sc_block_contents(run->scblock)); } @@ -340,7 +285,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].rscblock); + run_text = sc_block_contents(para->runs[i].scblock); run_len = strlen(run_text); attr = pango_attr_font_desc_new(para->runs[i].fontdesc); @@ -384,19 +329,25 @@ void wrap_paragraph(Paragraph *para, PangoContext *pc, double w, para->height = pango_units_to_double(rect.height); } -SCBlock *get_newline_at_end(Paragraph *para) +static SCBlock *get_newline_at_end(Paragraph *para) { return para->newline_at_end; } +SCBlock *para_debug_get_newline_at_end(Paragraph *para) +{ + return get_newline_at_end(para); +} + + void set_newline_at_end(Paragraph *para, SCBlock *bl) { para->newline_at_end = bl; } -void add_run(Paragraph *para, SCBlock *scblock, SCBlock *rscblock, +void add_run(Paragraph *para, SCBlock *scblock, PangoFontDescription *fdesc, double col[4]) { struct text_run *runs_new; @@ -410,7 +361,6 @@ void add_run(Paragraph *para, SCBlock *scblock, SCBlock *rscblock, para->runs = runs_new; para->runs[para->n_runs].scblock = scblock; - para->runs[para->n_runs].rscblock = rscblock; 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]; @@ -421,7 +371,7 @@ void add_run(Paragraph *para, SCBlock *scblock, SCBlock *rscblock, } -Paragraph *create_paragraph(struct frame *fr, SCBlock *bl, SCBlock *rbl) +Paragraph *create_paragraph(struct frame *fr, SCBlock *bl) { Paragraph **paras_new; Paragraph *pnew; @@ -439,7 +389,6 @@ Paragraph *create_paragraph(struct frame *fr, SCBlock *bl, SCBlock *rbl) * However, this can easily be changed */ pnew->type = PARA_TYPE_TEXT; pnew->scblock = bl; - pnew->rscblock = rbl; pnew->n_runs = 0; pnew->runs = NULL; pnew->layout = NULL; @@ -481,8 +430,7 @@ Paragraph *insert_paragraph(struct frame *fr, int pos) } -Paragraph *add_callback_para(struct frame *fr, SCBlock *bl, SCBlock *rbl, - double w, double h, +Paragraph *add_callback_para(struct frame *fr, SCBlock *bl, double w, double h, SCCallbackDrawFunc draw_func, SCCallbackClickFunc click_func, void *bvp, void *vp) @@ -492,7 +440,7 @@ Paragraph *add_callback_para(struct frame *fr, SCBlock *bl, SCBlock *rbl, if ( (fr->n_paras > 0) && (fr->paras[fr->n_paras-1]->empty) ) { pnew = fr->paras[fr->n_paras-1]; } else { - pnew = create_paragraph(fr, bl, rbl); + pnew = create_paragraph(fr, bl); if ( pnew == NULL ) { fprintf(stderr, _("Failed to add callback paragraph\n")); return NULL; @@ -501,7 +449,6 @@ Paragraph *add_callback_para(struct frame *fr, SCBlock *bl, SCBlock *rbl, pnew->type = PARA_TYPE_CALLBACK; pnew->scblock = bl; - pnew->rscblock = rbl; pnew->cb_w = w; pnew->cb_h = h; pnew->draw_func = draw_func; @@ -515,7 +462,7 @@ Paragraph *add_callback_para(struct frame *fr, SCBlock *bl, SCBlock *rbl, } -void add_image_para(struct frame *fr, SCBlock *scblock, SCBlock *rscblock, +void add_image_para(struct frame *fr, SCBlock *scblock, const char *filename, ImageStore *is, double w, double h, int editable) { @@ -530,7 +477,7 @@ void add_image_para(struct frame *fr, SCBlock *scblock, SCBlock *rscblock, if ( (fr->n_paras > 0) && (fr->paras[fr->n_paras-1]->empty) ) { pnew = fr->paras[fr->n_paras-1]; } else { - pnew = create_paragraph(fr, scblock, rscblock); + pnew = create_paragraph(fr, scblock); if ( pnew == NULL ) { fprintf(stderr, _("Failed to add image paragraph\n")); return; @@ -545,7 +492,6 @@ void add_image_para(struct frame *fr, SCBlock *scblock, SCBlock *rscblock, pnew->type = PARA_TYPE_IMAGE; pnew->scblock = scblock; - pnew->rscblock = rscblock; pnew->filename = strdup(filename); pnew->image_w = w; pnew->image_h = h; @@ -662,7 +608,7 @@ void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is) } -size_t end_offset_of_para(struct frame *fr, int pn) +static size_t end_offset_of_para(struct frame *fr, int pn) { int i; size_t total = 0; @@ -726,11 +672,6 @@ void ensure_run(struct frame *fr, struct edit_pos cpos) if ( para->type != PARA_TYPE_TEXT ) return; - if ( para->scblock != para->rscblock ) { - fprintf(stderr, _("Need to add run, but paragraph not editable\n")); - return; - } - if ( para->scblock != NULL ) { bl = sc_block_prepend(para->scblock, fr->scblocks); @@ -745,13 +686,12 @@ void ensure_run(struct frame *fr, struct edit_pos cpos) /* If the paragraph's SCBlock is NULL, it means this paragraph * is right at the end of the document. The last thing in the * document is something like \newpara. */ - bl = sc_block_append_end(fr->scblocks, NULL, NULL, strdup("")); + bl = sc_block_append_inside(fr->scblocks, NULL, NULL, strdup("")); } para->scblock = bl; - para->rscblock = bl; - add_run(para, bl, bl, fr->fontdesc, fr->col); + add_run(para, bl, fr->fontdesc, fr->col); wrap_paragraph(para, NULL, fr->w - fr->pad_l - fr->pad_r, 0, 0); } @@ -907,11 +847,6 @@ void cursor_moveh(struct frame *fr, struct edit_pos *cp, signed int dir) } -void cursor_movev(struct frame *fr, struct edit_pos *cp, signed int dir) -{ -} - - void check_callback_click(struct frame *fr, int para) { Paragraph *p = fr->paras[para]; @@ -987,7 +922,7 @@ size_t pos_trail_to_offset(Paragraph *para, size_t offs, int trail) return 0; } - if ( sc_block_contents(run->rscblock) == NULL ) { + if ( sc_block_contents(run->scblock) == NULL ) { fprintf(stderr, _("pos_trail_to_offset: No contents " "(%p name=%s, options=%s)\n"), run->scblock, sc_block_name(run->scblock), @@ -996,7 +931,7 @@ size_t pos_trail_to_offset(Paragraph *para, size_t offs, int trail) } /* Get the text for the run */ - run_text = sc_block_contents(run->rscblock); + run_text = sc_block_contents(run->scblock); /* Turn the paragraph offset into a run offset */ para_offset_of_run = get_paragraph_offset(para, nrun); @@ -1035,11 +970,6 @@ int position_editable(struct frame *fr, struct edit_pos cp) para = fr->paras[cp.para]; - if ( para->scblock != para->rscblock ) { - fprintf(stderr, _("Paragraph is not editable.\n")); - return 0; - } - if ( para->type != PARA_TYPE_TEXT ) { fprintf(stderr, _("Paragraph is not text.\n")); return 0; @@ -1052,7 +982,7 @@ int position_editable(struct frame *fr, struct edit_pos cp) return 0; } - return (para->runs[run].scblock == para->runs[run].rscblock); + return 1; } @@ -1074,33 +1004,11 @@ void insert_text_in_paragraph(Paragraph *para, size_t offs, const char *t) size_t run_offs; run = ¶->runs[nrun]; run_offs = offs - get_paragraph_offset(para, nrun); - sc_insert_text(run->rscblock, run_offs, t); + sc_insert_text(run->scblock, run_offs, t); } } -static SCBlock *pos_to_rscblock(struct frame *fr, struct edit_pos p) -{ - int run; - size_t paraoffs; - Paragraph *para; - - para = fr->paras[p.para]; - - if ( para->type != PARA_TYPE_TEXT ) { - return NULL; - } - - paraoffs = pos_trail_to_offset(para, p.pos, p.trail); - - run = which_run(para, paraoffs); - assert(run < para->n_runs); - - return para->runs[run].rscblock; -} - - - static SCBlock *pos_to_scblock(struct frame *fr, struct edit_pos p, enum para_type *type) { @@ -1192,17 +1100,9 @@ static Paragraph *scan_runs_for_scblock(struct frame *fr, int pn1, int pn2, *run = 0; return fr->paras[i]; } - if ( fr->paras[i]->rscblock == bl ) { - *run = 0; - return fr->paras[i]; - } /* Check all runs */ for ( j=0; j<fr->paras[i]->n_runs; j++ ) { - if ( fr->paras[i]->runs[j].rscblock == bl ) { - *run = j; - return fr->paras[i]; - } if ( fr->paras[i]->runs[j].scblock == bl ) { *run = j; return fr->paras[i]; @@ -1440,7 +1340,6 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po { int i; SCBlock *p1scblock, *p2scblock; - SCBlock *p1rscblock, *p2rscblock; enum para_type type1, type2; size_t p2offs; SCBlock *scblock; @@ -1467,8 +1366,6 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po /* Find SC positions for start and end */ p1scblock = pos_to_scblock(fr, p1, &type1); p2scblock = pos_to_scblock(fr, p2, &type2); - p1rscblock = pos_to_rscblock(fr, p1); - p2rscblock = pos_to_rscblock(fr, p2); p2offs = pos_to_offset(fr, p2); wrap_end = p2.para; @@ -1512,9 +1409,9 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po printf(" offs %li\n", (long int)p1offs); if ( p1offs != 0 ) { printf("Partial delete\n"); - printf("contents '%s'\n", sc_block_contents(p1rscblock)); + printf("contents '%s'\n", sc_block_contents(p1scblock)); printf("from offs %li\n", (long int)p1offs); - scblock_delete_text(p1rscblock, p1offs, -1); + scblock_delete_text(p1scblock, p1offs, -1); } else { printf("Deleting the whole text SCBlock\n"); sc_block_delete(&fr->scblocks, p1scblock); @@ -1564,8 +1461,8 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po if ( type2 == PARA_TYPE_TEXT ) { size_t len; printf(" offs %li\n", (long int)p2offs); - if ( sc_block_contents(p2rscblock) != NULL ) { - len = strlen(sc_block_contents(p2rscblock)); + if ( sc_block_contents(p2scblock) != NULL ) { + len = strlen(sc_block_contents(p2scblock)); } else { len = 0; } @@ -1580,9 +1477,9 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po NULL); } else if ( p2offs > 0 ) { printf("Partial delete\n"); - printf("contents '%s'\n", sc_block_contents(p2rscblock)); + printf("contents '%s'\n", sc_block_contents(p2scblock)); printf("up to offs %li\n", (long int)p2offs); - scblock_delete_text(p2rscblock, 0, p2offs); + scblock_delete_text(p2scblock, 0, p2offs); } /* else do nothing */ } else { printf("Deleting the whole non-text SCBlock\n"); @@ -1610,10 +1507,10 @@ void show_para(Paragraph *p) printf(_("%i runs:\n"), p->n_runs); for ( i=0; i<p->n_runs; i++ ) { - printf(_(" Run %2i: SCBlock %p/%p %s '%s'\n"), - i, p->runs[i].scblock, p->runs[i].rscblock, + printf(_(" Run %2i: SCBlock %p %s '%s'\n"), + i, p->runs[i].scblock, pango_font_description_to_string(p->runs[i].fontdesc), - sc_block_contents(p->runs[i].rscblock)); + sc_block_contents(p->runs[i].scblock)); } } else if ( p->type == PARA_TYPE_IMAGE ) { @@ -1695,9 +1592,8 @@ 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, end, fr->fontdesc, fr->col); + add_run(pnew, end, fr->fontdesc, fr->col); pnew->scblock = end; - pnew->rscblock = end; wrap_paragraph(pnew, pc, fr->w - fr->pad_l - fr->pad_r, 0, 0); @@ -1710,12 +1606,11 @@ static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos, /* Split the run (and SCBlock) into two */ double col[4] = {0,0,0,0}; struct text_run *rn; - int macro = 0; printf("Splitting run %i. Before:\n", run); show_para(para); - add_run(para, NULL, NULL, NULL, col); + add_run(para, NULL, NULL, col); /* -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)); @@ -1723,19 +1618,7 @@ static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos, rr = ¶->runs[run]; /* Because add_run realloced the runs */ rn = ¶->runs[run+1]; - if ( rr->rscblock != rr->scblock) { - macro = 1; - } - - rn->rscblock = sc_block_split(rr->rscblock, run_offs); - - if ( !macro ) { - /* Literal text block */ - rn->scblock = rn->rscblock; - } else { - /* Macro block */ - rn->scblock = rr->scblock; - } + rn->scblock = sc_block_split(rr->scblock, run_offs); rn->fontdesc = pango_font_description_copy(rr->fontdesc); rn->col[0] = rr->col[0]; @@ -1752,11 +1635,10 @@ 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, NULL, col); + add_run(pnew, NULL, NULL, col); pnew->runs[pnew->n_runs-1] = para->runs[i]; } pnew->scblock = pnew->runs[0].scblock; - pnew->rscblock = pnew->runs[0].rscblock; /* Truncate the first paragraph at the appropriate position */ para->n_runs = run+1; @@ -1768,7 +1650,7 @@ static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos, show_para(pnew); /* Add a \newpara after the end of the first paragraph's SC */ - nnp = sc_block_append(rr->rscblock, strdup("newpara"), NULL, NULL, NULL); + nnp = sc_block_append(rr->scblock, strdup("newpara"), NULL, NULL, NULL); set_newline_at_end(pnew, get_newline_at_end(para)); set_newline_at_end(para, nnp); @@ -1853,12 +1735,6 @@ SCBlock *para_scblock(Paragraph *para) } -SCBlock *para_rscblock(Paragraph *para) -{ - return para->rscblock; -} - - enum para_type para_type(Paragraph *para) { return para->type; @@ -1872,13 +1748,11 @@ int para_debug_num_runs(Paragraph *para) } -int para_debug_run_info(Paragraph *para, int i, SCBlock **scblock, - SCBlock **rscblock) +int para_debug_run_info(Paragraph *para, int i, SCBlock **scblock) { if ( para->type != PARA_TYPE_TEXT ) return 1; if ( i >= para->n_runs ) return 1; *scblock = para->runs[i].scblock; - *rscblock = para->runs[i].rscblock; return 0; } diff --git a/src/frame.h b/src/frame.h index b50cfaf..f52c6e6 100644 --- a/src/frame.h +++ b/src/frame.h @@ -42,8 +42,7 @@ typedef enum { GRAD_NONE, GRAD_HORIZ, - GRAD_VERT, - GRAD_NOBG + GRAD_VERT } GradientType; enum para_type @@ -115,8 +114,6 @@ struct frame extern struct frame *frame_new(void); extern void frame_free(struct frame *fr); extern struct frame *add_subframe(struct frame *fr); -extern void show_hierarchy(struct frame *fr, const char *t); -extern void delete_subframe(struct frame *top, struct frame *fr); extern struct frame *find_frame_with_scblocks(struct frame *top, SCBlock *scblocks); @@ -130,32 +127,27 @@ extern void set_para_alignment(Paragraph *para, PangoAlignment align); extern double paragraph_height(Paragraph *para); extern void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is); -extern SCBlock *get_newline_at_end(Paragraph *para); extern void set_newline_at_end(Paragraph *para, SCBlock *bl); -extern void check_run(struct frame *fr, int pn); extern void show_edit_pos(struct edit_pos a); -extern void add_run(Paragraph *para, SCBlock *scblock, SCBlock *rscblock, +extern void add_run(Paragraph *para, SCBlock *scblock, PangoFontDescription *fdesc, double col[4]); extern Paragraph *insert_paragraph(struct frame *fr, int pos); extern Paragraph *add_callback_para(struct frame *fr, SCBlock *scblock, - SCBlock *rscblock, double w, double h, SCCallbackDrawFunc draw_func, SCCallbackClickFunc click_func, void *bvp, void *vp); extern void add_image_para(struct frame *fr, SCBlock *scblock, - SCBlock *rscblock, const char *filename, + const char *filename, ImageStore *is, double w, double h, int editable); extern void wrap_paragraph(Paragraph *para, PangoContext *pc, double w, size_t sel_start, size_t sel_end); -extern size_t end_offset_of_para(struct frame *fr, int pn); - extern int find_cursor(struct frame *fr, double x, double y, struct edit_pos *pos); @@ -175,8 +167,6 @@ extern int get_cursor_pos(struct frame *fr, int cursor_para, int cursor_pos, extern void cursor_moveh(struct frame *fr, struct edit_pos *cp, signed int dir); -extern void cursor_movev(struct frame *fr, struct edit_pos *cp, signed int dir); - extern void check_callback_click(struct frame *fr, int para); extern size_t pos_trail_to_offset(Paragraph *para, size_t offs, int trail); @@ -187,25 +177,24 @@ extern void insert_text_in_paragraph(Paragraph *para, size_t offs, extern void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_pos p2, double wrap_w); -extern size_t delete_text_in_paragraph(struct frame *fr, int npara, size_t offs0, ssize_t offs2); - extern SCBlock *split_paragraph(struct frame *fr, int pn, size_t pos, PangoContext *pc); extern SCBlock *block_at_cursor(struct frame *fr, int para, size_t pos); +extern void show_frame_hierarchy(struct frame *fr, const char *t); + extern int get_sc_pos(struct frame *fr, int pn, size_t pos, SCBlock **bl, size_t *ppos); extern void *get_para_bvp(Paragraph *para); -extern Paragraph *create_paragraph(struct frame *fr, SCBlock *bl, SCBlock *rbl); +extern Paragraph *create_paragraph(struct frame *fr, SCBlock *bl); extern enum para_type para_type(Paragraph *para); extern SCBlock *para_scblock(Paragraph *para); -extern SCBlock *para_rscblock(Paragraph *para); +extern SCBlock *para_debug_get_newline_at_end(Paragraph *para); extern int para_debug_num_runs(Paragraph *para); -extern int para_debug_run_info(Paragraph *para, int i, SCBlock **scblock, - SCBlock **rscblock); +extern int para_debug_run_info(Paragraph *para, int i, SCBlock **scblock); #endif /* FRAME_H */ diff --git a/src/narrative_window.c b/src/narrative_window.c index e549fc1..b287f61 100644 --- a/src/narrative_window.c +++ b/src/narrative_window.c @@ -185,105 +185,31 @@ static void delete_slide_sig(GSimpleAction *action, GVariant *parameter, } -static struct template_id *get_templates(SCBlock *ss, int *n) -{ - struct template_id *list; - SCInterpreter *scin; - - scin = sc_interp_new(NULL, NULL, NULL, NULL); - sc_interp_run_stylesheet(scin, ss); /* ss == NULL is OK */ - list = sc_interp_get_templates(scin, n); - sc_interp_destroy(scin); - return list; -} - - -static void update_template_menus(NarrativeWindow *nw) -{ - struct template_id *templates; - int i, n_templates; - - templates = get_templates(nw->p->stylesheet, &n_templates); - - for ( i=0; i<n_templates; i++ ) { - free(templates[i].name); - free(templates[i].friendlyname); - sc_block_free(templates[i].scblock); - } - - free(templates); -} - - -static SCBlock *get_slide_template(SCBlock *ss) -{ - struct template_id *templates; - int i, n_templates; - SCBlock *ret = NULL; - - templates = get_templates(ss, &n_templates); - - for ( i=0; i<n_templates; i++ ) { - if ( strcmp(templates[i].name, "slide") == 0 ) { - ret = templates[i].scblock; - } else { - sc_block_free(templates[i].scblock); - } - free(templates[i].name); - free(templates[i].friendlyname); - } - free(templates); - - /* No template? */ - if ( ret == NULL ) { - ret = sc_parse("\\slide{}"); - } - - return ret; /* NB this is a copy of the one owned by the interpreter */ -} - - static gint load_ss_response_sig(GtkWidget *d, gint response, NarrativeWindow *nw) { if ( response == GTK_RESPONSE_ACCEPT ) { - char *filename; - char *stext; - - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d)); - printf("Loading %s\n",filename); + GFile *file; + Stylesheet *new_ss; - stext = load_everything(filename); - if ( stext != NULL ) { + file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(d)); - SCBlock *bl; - SCBlock *ss; - bl = sc_parse(stext); - free(stext); - ss = find_stylesheet(bl); + new_ss = stylesheet_load(file); + if ( new_ss != NULL ) { - if ( ss != NULL ) { + stylesheet_free(nw->p->stylesheet); + nw->p->stylesheet = new_ss; + sc_editor_set_stylesheet(nw->sceditor, new_ss); - /* Substitute the style sheet in - * presentation Storycode */ - replace_stylesheet(nw->p, ss); + /* Full rerender */ + sc_editor_set_scblock(nw->sceditor, nw->dummy_top); - sc_editor_set_stylesheet(nw->sceditor, ss); - - /* Full rerender, first block may have - * changed */ - sc_editor_set_scblock(nw->sceditor, - nw->dummy_top); - - } else { - fprintf(stderr, _("Not a style sheet\n")); - } } else { fprintf(stderr, _("Failed to load\n")); } - g_free(filename); + g_object_unref(file); } @@ -351,9 +277,8 @@ static void add_slide_sig(GSimpleAction *action, GVariant *parameter, /* Split the current paragraph */ nsblock = split_paragraph_at_cursor(nw->sceditor); - /* Get the template */ - templ = get_slide_template(nw->p->stylesheet); /* our copy */ - show_sc_blocks(templ); + /* FIXME: Template from JSON */ + templ = sc_parse("\\slide{}"); /* Link the new SCBlock in */ if ( nsblock != NULL ) { @@ -886,7 +811,6 @@ NarrativeWindow *narrative_window_new(struct presentation *p, GApplication *papp "win.last"); update_toolbar(nw); - update_template_menus(nw); scroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), diff --git a/src/presentation.c b/src/presentation.c index b8b4589..eab0f5a 100644 --- a/src/presentation.c +++ b/src/presentation.c @@ -67,6 +67,59 @@ char *get_titlebar_string(struct presentation *p) } +static void find_and_load_stylesheet(struct presentation *p, GFile *file) +{ + GFile *ssfile; + GFile *parent; + gchar *ssuri; + + if ( file != NULL ) { + + /* First choice: /same/directory/<presentation>.ss */ + ssuri = g_file_get_uri(file); + if ( ssuri != NULL ) { + size_t l = strlen(ssuri); + if ( ssuri[l-3] == '.' && ssuri[l-2] == 's' && ssuri[l-1] =='c' ) { + ssuri[l-1] = 's'; + ssfile = g_file_new_for_uri(ssuri); + p->stylesheet = stylesheet_load(ssfile); + g_object_unref(ssfile); + g_free(ssuri); + } + } + + /* Second choice: /same/directory/stylesheet.ss */ + if ( p->stylesheet == NULL ) { + parent = g_file_get_parent(file); + if ( parent != NULL ) { + ssfile = g_file_get_child(parent, "stylesheet.ss"); + if ( ssfile != NULL ) { + p->stylesheet = stylesheet_load(ssfile); + g_object_unref(ssfile); + } + } + } + + } + + /* Third choice: <cwd>/stylesheet.ss */ + if ( p->stylesheet == NULL ) { + ssfile = g_file_new_for_path("./stylesheet.ss"); + p->stylesheet = stylesheet_load(ssfile); + g_object_unref(ssfile); + } + + /* Fourth choice: internal default stylesheet */ + if ( p->stylesheet == NULL ) { + ssfile = g_file_new_for_uri("resource:///uk/me/bitwiz/Colloquium/default.ss"); + p->stylesheet = stylesheet_load(ssfile); + g_object_unref(ssfile); + } + + /* Last resort is NULL stylesheet and SCInterpreter's defaults */ +} + + struct presentation *new_presentation(const char *imagestore) { struct presentation *new; @@ -89,6 +142,8 @@ struct presentation *new_presentation(const char *imagestore) new->lang = pango_language_get_default(); + find_and_load_stylesheet(new, NULL); + return new; } @@ -226,75 +281,17 @@ SCBlock *prev_slide(struct presentation *p, SCBlock *sl) } -int replace_stylesheet(struct presentation *p, SCBlock *ss) -{ - /* Create style sheet from union of old and new, - * preferring items from the new one */ - - /* If there was no stylesheet before, add a dummy one */ - if ( p->stylesheet == NULL ) { - p->stylesheet = sc_block_append_end(p->scblocks, - "stylesheet", NULL, NULL); - } - - /* Cut the old stylesheet out of the presentation, - * and put in the new one */ - sc_block_substitute(&p->scblocks, p->stylesheet, ss); - p->stylesheet = ss; - - return 0; -} - - -SCBlock *find_stylesheet(SCBlock *bl) -{ - while ( bl != NULL ) { - - const char *name = sc_block_name(bl); - - if ( (name != NULL) && (strcmp(name, "stylesheet") == 0) ) { - return bl; - } - - bl = sc_block_next(bl); - - } - - return NULL; -} - - -static void install_stylesheet(struct presentation *p) -{ - if ( p->stylesheet != NULL ) { - fprintf(stderr, _("Duplicate style sheet!\n")); - return; - } - - p->stylesheet = find_stylesheet(p->scblocks); - - if ( p->stylesheet == NULL ) { - fprintf(stderr, _("No style sheet.\n")); - } -} - - static void set_slide_size_from_stylesheet(struct presentation *p) { - SCInterpreter *scin; - double w, h; - int r; - - if ( p->stylesheet == NULL ) return; - - scin = sc_interp_new(NULL, NULL, NULL, NULL); - sc_interp_run_stylesheet(scin, p->stylesheet); /* ss == NULL is OK */ - r = sc_interp_get_slide_size(scin, &w, &h); - sc_interp_destroy(scin); - - if ( r == 0 ) { - p->slide_width = w; - p->slide_height = h; + char *result; + + result = stylesheet_lookup(p->stylesheet, "$.slide", "size"); + if ( result != NULL ) { + float v[2]; + if ( parse_double(result, v) == 0 ) { + p->slide_width = v[0]; + p->slide_height = v[1]; + } } } @@ -324,7 +321,10 @@ int load_presentation(struct presentation *p, GFile *file) return r; /* Error */ } - install_stylesheet(p); + p->stylesheet = NULL; + + find_and_load_stylesheet(p, file); + set_slide_size_from_stylesheet(p); assert(p->uri == NULL); diff --git a/src/presentation.h b/src/presentation.h index ed8a188..ea3780e 100644 --- a/src/presentation.h +++ b/src/presentation.h @@ -34,6 +34,7 @@ struct presentation; #include "slideshow.h" #include "narrative_window.h" #include "slide_window.h" +#include "stylesheet.h" struct menu_pl; @@ -56,15 +57,13 @@ struct presentation double slide_width; double slide_height; - SCBlock *stylesheet; SCBlock *scblocks; + Stylesheet *stylesheet; }; extern struct presentation *new_presentation(const char *imagestore); -extern SCBlock *find_stylesheet(SCBlock *bl); -extern int replace_stylesheet(struct presentation *p, SCBlock *ss); extern void free_presentation(struct presentation *p); extern char *get_titlebar_string(struct presentation *p); diff --git a/src/print.c b/src/print.c index c50a3c5..43c967e 100644 --- a/src/print.c +++ b/src/print.c @@ -54,9 +54,6 @@ struct print_stuff struct frame *top; int start_paras[256]; int slide_number; - - ImageStore *is; - const char *storename; }; @@ -194,13 +191,11 @@ static void begin_narrative_print(GtkPrintOperation *op, GtkPrintContext *ctx, sc_callback_list_add_callback(cbl, "slide", print_create_thumbnail, print_render_thumbnail, NULL, ps); - ps->is = imagestore_new(ps->storename); - pc = gtk_print_context_create_pango_context(ctx); dummy_top = sc_block_new_parent(ps->p->scblocks, "presentation"); ps->top = interp_and_shape(dummy_top, ps->p->stylesheet, cbl, - ps->is, 0, pc, + ps->p->is, 0, pc, gtk_print_context_get_width(ctx), gtk_print_context_get_height(ctx), ps->p->lang); @@ -242,7 +237,10 @@ static void print_narrative(GtkPrintOperation *op, GtkPrintContext *ctx, h += paragraph_height(ps->top->paras[i]); if ( h > page_height ) return; - render_paragraph(cr, ps->top->paras[i], ps->is); + cairo_save(cr); + render_paragraph(cr, ps->top->paras[i], ps->p->is); + cairo_restore(cr); + cairo_translate(cr, 0.0, paragraph_height(ps->top->paras[i])); } diff --git a/src/render.c b/src/render.c index 580a4cd..f9f4cca 100644 --- a/src/render.c +++ b/src/render.c @@ -48,8 +48,6 @@ static void do_background(cairo_t *cr, struct frame *fr) { cairo_pattern_t *patt = NULL; - if ( fr->grad == GRAD_NOBG ) return; /* Should not end up here */ - cairo_new_path(cr); cairo_rectangle(cr, 0.0, 0.0, fr->w, fr->h); @@ -86,9 +84,6 @@ static void do_background(cairo_t *cr, struct frame *fr) cairo_set_source(cr, patt); break; - case GRAD_NOBG: - break; - } cairo_fill(cr); @@ -176,14 +171,14 @@ int recursive_wrap(struct frame *fr, PangoContext *pc) } -struct frame *interp_and_shape(SCBlock *scblocks, SCBlock *stylesheet, +struct frame *interp_and_shape(SCBlock *scblocks, Stylesheet *stylesheet, SCCallbackList *cbl, ImageStore *is, int slide_number, PangoContext *pc, double w, double h, PangoLanguage *lang) { SCInterpreter *scin; - char snum[64]; +// char snum[64]; struct frame *top; top = frame_new(); @@ -203,12 +198,13 @@ struct frame *interp_and_shape(SCBlock *scblocks, SCBlock *stylesheet, sc_interp_set_callbacks(scin, cbl); - snprintf(snum, 63, "%i", slide_number); - add_macro(scin, "slidenumber", snum); - - if ( stylesheet != NULL ) { - sc_interp_run_stylesheet(scin, stylesheet); - } + /* 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); +// } top->fontdesc = pango_font_description_copy(sc_interp_get_fontdesc(scin)); top->col[0] = sc_interp_get_fgcol(scin)[0]; @@ -216,7 +212,7 @@ struct frame *interp_and_shape(SCBlock *scblocks, SCBlock *stylesheet, top->col[2] = sc_interp_get_fgcol(scin)[2]; top->col[3] = sc_interp_get_fgcol(scin)[3]; - sc_interp_add_block(scin, scblocks); + sc_interp_add_block(scin, scblocks, stylesheet); sc_interp_destroy(scin); @@ -226,7 +222,7 @@ struct frame *interp_and_shape(SCBlock *scblocks, SCBlock *stylesheet, static struct frame *render_sc_with_context(SCBlock *scblocks, cairo_t *cr, double log_w, double log_h, - SCBlock *stylesheet, SCCallbackList *cbl, + Stylesheet *stylesheet, SCCallbackList *cbl, ImageStore *is, int slide_number, PangoLanguage *lang, PangoContext *pc) @@ -250,7 +246,7 @@ static struct frame *render_sc_with_context(SCBlock *scblocks, cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h, double log_w, double log_h, - SCBlock *stylesheet, SCCallbackList *cbl, + Stylesheet *stylesheet, SCCallbackList *cbl, ImageStore *is, int slide_number, struct frame **ptop, PangoLanguage *lang) diff --git a/src/render.h b/src/render.h index aadb033..0cfae26 100644 --- a/src/render.h +++ b/src/render.h @@ -35,7 +35,7 @@ /* Convienience function to run the entire pipeline */ extern cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h, double log_w, double log_h, - SCBlock *stylesheet, SCCallbackList *cbl, + Stylesheet *stylesheet, SCCallbackList *cbl, ImageStore *is, int slide_number, struct frame **ptop, PangoLanguage *lang); @@ -44,7 +44,7 @@ extern cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h, * Needs to be followed by: wrap_contents() (recursively) * recursive_draw() */ -extern struct frame *interp_and_shape(SCBlock *scblocks, SCBlock *stylesheet, +extern struct frame *interp_and_shape(SCBlock *scblocks, Stylesheet *stylesheet, SCCallbackList *cbl, ImageStore *is, int slide_number, PangoContext *pc, diff --git a/src/sc_editor.c b/src/sc_editor.c index 999f919..e95beb4 100644 --- a/src/sc_editor.c +++ b/src/sc_editor.c @@ -384,7 +384,7 @@ void sc_editor_ensure_cursor(SCEditor *e) } -void sc_editor_remove_cursor(SCEditor *e) +static void sc_editor_remove_cursor(SCEditor *e) { e->cursor_frame = NULL; e->cpos.para = 0; @@ -999,7 +999,7 @@ static void insert_text(char *t, SCEditor *e) fprintf(stderr, _("Failed to insert paragraph\n")); return; } - add_run(pnew, ad, ad, e->cursor_frame->fontdesc, + add_run(pnew, ad, e->cursor_frame->fontdesc, e->cursor_frame->col); 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, scblocks, fr->fontdesc, fr->col); + add_run(para, scblocks, fr->fontdesc, fr->col); wrap_paragraph(para, pc, fr->w - fr->pad_l - fr->pad_r, 0, 0); } @@ -1979,30 +1979,12 @@ void sc_editor_set_scblock(SCEditor *e, SCBlock *scblocks) } -SCBlock *sc_editor_get_scblock(SCEditor *e) -{ - return e->scblocks; -} - - static void update_size_request(SCEditor *e) { gtk_widget_set_size_request(GTK_WIDGET(e), 0, e->h + 2.0*e->min_border); } -void sc_editor_set_size(SCEditor *e, int w, int h) -{ - e->w = w; - e->h = h; - update_size_request(e); - if ( gtk_widget_get_mapped(GTK_WIDGET(e)) ) { - full_rerender(e); - sc_editor_redraw(e); - } -} - - void sc_editor_set_logical_size(SCEditor *e, double w, double h) { e->log_w = w; @@ -2033,7 +2015,7 @@ void sc_editor_set_top_frame_editable(SCEditor *e, int top_frame_editable) } -void sc_editor_set_stylesheet(SCEditor *e, SCBlock *stylesheet) +void sc_editor_set_stylesheet(SCEditor *e, Stylesheet *stylesheet) { e->stylesheet = stylesheet; } @@ -2125,7 +2107,7 @@ void sc_editor_set_imagestore(SCEditor *e, ImageStore *is) } -SCEditor *sc_editor_new(SCBlock *scblocks, SCBlock *stylesheet, +SCEditor *sc_editor_new(SCBlock *scblocks, Stylesheet *stylesheet, PangoLanguage *lang, const char *storename) { SCEditor *sceditor; diff --git a/src/sc_editor.h b/src/sc_editor.h index adbbaf2..d3c111b 100644 --- a/src/sc_editor.h +++ b/src/sc_editor.h @@ -32,6 +32,7 @@ #include "frame.h" #include "sc_interp.h" +#include "stylesheet.h" struct presentation; @@ -94,7 +95,7 @@ struct _sceditor double log_w; /* Size of surface in "SC units" */ double log_h; SCBlock *scblocks; - SCBlock *stylesheet; + Stylesheet *stylesheet; ImageStore *is; SCCallbackList *cbl; struct frame *top; @@ -168,12 +169,9 @@ typedef struct _sceditor SCEditor; typedef struct _sceditorclass SCEditorClass; extern void sc_editor_set_scblock(SCEditor *e, SCBlock *scblocks); -extern void sc_editor_set_stylesheet(SCEditor *e, SCBlock *stylesheet); -extern SCBlock *sc_editor_get_scblock(SCEditor *e); -extern GtkWidget *sc_editor_get_widget(SCEditor *e); -extern SCEditor *sc_editor_new(SCBlock *scblocks, SCBlock *stylesheet, +extern void sc_editor_set_stylesheet(SCEditor *e, Stylesheet *stylesheet); +extern SCEditor *sc_editor_new(SCBlock *scblocks, Stylesheet *stylesheet, PangoLanguage *lang, const char *storename); -extern void sc_editor_set_size(SCEditor *e, int w, int h); extern void sc_editor_set_logical_size(SCEditor *e, double w, double h); extern void sc_editor_set_flow(SCEditor *e, int flow); extern void sc_editor_set_scale(SCEditor *e, int scale); @@ -188,7 +186,6 @@ extern void sc_editor_paste(SCEditor *e); extern void sc_editor_add_storycode(SCEditor *e, const char *sc); extern void sc_editor_copy_selected_frame(SCEditor *e); extern void sc_editor_delete_selected_frame(SCEditor *e); -extern void sc_editor_remove_cursor(SCEditor *e); extern void sc_editor_ensure_cursor(SCEditor *e); extern SCBlock *split_paragraph_at_cursor(SCEditor *e); diff --git a/src/sc_interp.c b/src/sc_interp.c index dea8446..7bbfeeb 100644 --- a/src/sc_interp.c +++ b/src/sc_interp.c @@ -38,21 +38,6 @@ #include "utils.h" -struct macro -{ - char *name; - SCBlock *bl; - struct macro *prev; /* Previous declaration, or NULL */ -}; - - -struct template -{ - char *name; - SCBlock *bl; -}; - - struct sc_state { PangoFontDescription *fontdesc; @@ -71,25 +56,8 @@ struct sc_state double slide_height; struct frame *fr; /* The current frame */ - - int n_macros; - int max_macros; - struct macro *macros; /* Contents need to be copied on push */ - - int n_styles; - int max_styles; - struct macro *styles; /* Contents need to be copied on push */ - - int n_templates; - int max_templates; - struct template *templates; - - SCBlock *macro_contents; /* If running a macro, the child block of the caller */ - SCBlock *macro_real_block; /* If running a macro, the block which called the macro */ - int macro_editable; /* If running a macro, whether this bit can be edited or not */ }; - struct _scinterp { PangoContext *pc; @@ -118,6 +86,17 @@ struct _sccallbacklist }; +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; @@ -242,12 +221,6 @@ static int check_callback(SCInterpreter *scin, SCBlock *bl) double w, h; int r; void *bvp; - SCBlock *rbl; - - rbl = bl; - if ( sc_interp_get_macro_real_block(scin) != NULL ) { - bl = sc_interp_get_macro_real_block(scin); - } if ( strcmp(cbl->names[i], name) != 0 ) continue; r = cbl->box_funcs[i](scin, bl, &w, &h, &bvp, cbl->vps[i]); @@ -255,7 +228,7 @@ static int check_callback(SCInterpreter *scin, SCBlock *bl) struct sc_state *st = &scin->state[scin->j]; Paragraph *pnew; pnew = add_callback_para(sc_interp_get_frame(scin), - bl, rbl, w, h, + bl, w, h, cbl->draw_funcs[i], cbl->click_funcs[i], bvp, cbl->vps[i]); @@ -293,41 +266,6 @@ double *sc_interp_get_fgcol(SCInterpreter *scin) } -double *sc_interp_get_bgcol(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - return st->bgcol; -} - - -double *sc_interp_get_bgcol2(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - return st->bgcol2; -} - - -GradientType sc_interp_get_bggrad(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - return st->bggrad; -} - - -int sc_interp_get_ascent(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - return st->ascent; -} - - -int sc_interp_get_height(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - return st->height; -} - - static void set_frame_default_style(struct frame *fr, SCInterpreter *scin) { if ( fr == NULL ) return; @@ -526,38 +464,22 @@ static void set_bggrad(SCInterpreter *scin, const char *options, { struct sc_state *st = &scin->state[scin->j]; GdkRGBA col1, col2; - char *n2; - char *optcopy = strdup(options); - if ( options == NULL ) { - fprintf(stderr, _("Invalid bg gradient spec '%s'\n"), options); - return; - } - - n2 = strchr(optcopy, ','); - if ( n2 == NULL ) { - fprintf(stderr, _("Invalid bg gradient spec '%s'\n"), options); - return; - } + if ( parse_colour_duo(options, &col1, &col2) == 0 ) { - n2[0] = '\0'; + st->bgcol[0] = col1.red; + st->bgcol[1] = col1.green; + st->bgcol[2] = col1.blue; + st->bgcol[3] = col1.alpha; - gdk_rgba_parse(&col1, optcopy); - gdk_rgba_parse(&col2, &n2[1]); + st->bgcol2[0] = col2.red; + st->bgcol2[1] = col2.green; + st->bgcol2[2] = col2.blue; + st->bgcol2[3] = col2.alpha; - st->bgcol[0] = col1.red; - st->bgcol[1] = col1.green; - st->bgcol[2] = col1.blue; - st->bgcol[3] = col1.alpha; + st->bggrad = grad; - st->bgcol2[0] = col2.red; - st->bgcol2[1] = col2.green; - st->bgcol2[2] = col2.blue; - st->bgcol2[3] = col2.alpha; - - st->bggrad = grad; - - free(optcopy); + } } @@ -611,13 +533,6 @@ struct frame *sc_interp_get_frame(SCInterpreter *scin) } -SCBlock *sc_interp_get_macro_real_block(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - return st->macro_real_block; -} - - static void set_frame(SCInterpreter *scin, struct frame *fr) { struct sc_state *st = &scin->state[scin->j]; @@ -649,33 +564,6 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang, scin->cbl = NULL; st = &scin->state[0]; - st->n_macros = 0; - st->max_macros = 16; - st->macros = malloc(16*sizeof(struct macro)); - if ( st->macros == NULL ) { - free(scin->state); - free(scin); - return NULL; - } - st->n_styles = 0; - st->max_styles = 16; - st->styles = malloc(16*sizeof(struct macro)); - if ( st->styles == NULL ) { - free(scin->state); - free(scin); - return NULL; - } - st->n_templates = 0; - st->max_templates = 16; - st->templates = malloc(16*sizeof(struct template)); - if ( st->templates == NULL ) { - free(scin->state); - free(scin); - return NULL; - } - st->macro_contents = NULL; - st->macro_real_block = NULL; - st->macro_editable = 0; st->fr = NULL; st->paraspace[0] = 0.0; st->paraspace[1] = 0.0; @@ -696,7 +584,7 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang, st->bgcol2[1] = 1.0; st->bgcol2[2] = 1.0; st->bgcol2[3] = 1.0; - st->bggrad = GRAD_NOBG; + st->bggrad = GRAD_NONE; scin->lang = lang; /* The "ultimate" default font */ @@ -713,8 +601,6 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang, void sc_interp_destroy(SCInterpreter *scin) { - /* FIXME: Free all templates and macros */ - /* Empty the stack */ while ( scin->j > 0 ) { sc_interp_restore(scin); @@ -729,34 +615,6 @@ void sc_interp_destroy(SCInterpreter *scin) } -static int parse_double(const char *a, float v[2]) -{ - int nn; - - nn = sscanf(a, "%fx%f", &v[0], &v[1]); - if ( nn != 2 ) { - fprintf(stderr, _("Invalid size '%s'\n"), a); - return 1; - } - - return 0; -} - - -static int parse_tuple(const char *a, float v[4]) -{ - int nn; - - nn = sscanf(a, "%f,%f,%f,%f", &v[0], &v[1], &v[2], &v[3]); - if ( nn != 4 ) { - fprintf(stderr, _("Invalid tuple '%s'\n"), a); - return 1; - } - - return 0; -} - - static void set_padding(struct frame *fr, const char *opts) { float p[4]; @@ -788,19 +646,6 @@ static void set_paraspace(SCInterpreter *scin, const char *opts) } -static void set_slide_size(SCInterpreter *scin, const char *opts) -{ - float p[2]; - struct sc_state *st = &scin->state[scin->j]; - - if ( parse_double(opts, p) ) return; - - st->slide_width = p[0]; - st->slide_height = p[1]; - st->have_size = 1; -} - - void update_geom(struct frame *fr) { char geom[256]; @@ -1015,24 +860,17 @@ static void maybe_recurse_before(SCInterpreter *scin, SCBlock *child) } -static void maybe_recurse_after(SCInterpreter *scin, SCBlock *child) +static void maybe_recurse_after(SCInterpreter *scin, SCBlock *child, + Stylesheet *ss) { if ( child == NULL ) return; - sc_interp_add_blocks(scin, child); + sc_interp_add_blocks(scin, child, ss); sc_interp_restore(scin); } -static int in_macro(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - if ( st->macro_contents == NULL ) return 0; - return 1; -} - - -static void add_newpara(struct frame *fr, SCBlock *bl, SCBlock *mrb) +static void add_newpara(struct frame *fr, SCBlock *bl) { Paragraph *last_para; @@ -1043,7 +881,7 @@ static void add_newpara(struct frame *fr, SCBlock *bl, SCBlock *mrb) /* 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 */ - create_paragraph(fr, sc_block_next(mrb), sc_block_next(bl)); + create_paragraph(fr, sc_block_next(bl)); } @@ -1055,7 +893,6 @@ static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl, PangoFontDescription *fontdesc; double *col; struct sc_state *st = &scin->state[scin->j]; - SCBlock *rbl; Paragraph *para; /* Empty block? */ @@ -1064,47 +901,113 @@ static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl, fontdesc = sc_interp_get_fontdesc(scin); col = sc_interp_get_fgcol(scin); - rbl = bl; - if ( st->macro_real_block != NULL ) { - bl = st->macro_real_block; - } - 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, rbl); + para = create_paragraph(fr, bl); } set_para_alignment(para, st->alignment); - add_run(para, bl, rbl, fontdesc, col); + add_run(para, bl, fontdesc, col); set_para_spacing(para, st->paraspace); return 0; } -void sc_interp_run_style(SCInterpreter *scin, const char *sname) +static void apply_style(SCInterpreter *scin, Stylesheet *ss, const char *path) { - int i; - struct sc_state *st = &scin->state[scin->j]; + char *result; - for ( i=0; i<st->n_styles; i++ ) { - if ( strcmp(sname, st->styles[i].name) == 0 ) { - sc_interp_add_blocks(scin, st->styles[i].bl); - return; + 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); + } + } + + update_bg(scin); +} + + +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)); + fr->scblocks = bl; + fr->resizable = 1; + if ( fr == NULL ) { + fprintf(stderr, _("Failed to add frame.\n")); + return; + } + + /* 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) +static int check_outputs(SCBlock *bl, SCInterpreter *scin, Stylesheet *ss) { const char *name = sc_block_name(bl); const char *options = sc_block_options(bl); - SCBlock *child = sc_block_child(bl); - struct sc_state *st = &scin->state[scin->j]; if ( name == NULL ) { add_text(sc_interp_get_frame(scin), @@ -1116,11 +1019,7 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin) if ( parse_image_options(options, sc_interp_get_frame(scin), &w, &h, &filename) == 0 ) { - SCBlock *rbl = bl; - if ( st->macro_real_block != NULL ) { - bl = st->macro_real_block; - } - add_image_para(sc_interp_get_frame(scin), bl, rbl, + add_image_para(sc_interp_get_frame(scin), bl, filename, scin->is, w, h, 1); free(filename); } else { @@ -1129,38 +1028,20 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin) } } else if ( strcmp(name, "f")==0 ) { + output_frame(scin, bl, ss, "$.slide.frame"); - struct frame *fr; + } else if ( strcmp(name, "slidetitle")==0 ) { + output_frame(scin, bl, ss, "$.slide.slidetitle"); - fr = add_subframe(sc_interp_get_frame(scin)); - fr->scblocks = bl; - if ( in_macro(scin) ) { - fr->resizable = 0; - } else { - fr->resizable = 1; - } - if ( fr == NULL ) { - fprintf(stderr, _("Failed to add frame.\n")); - return 1; - } - - set_frame_default_style(fr, scin); + } else if ( strcmp(name, "prestitle")==0 ) { + output_frame(scin, bl, ss, "$.slide.prestitle"); - parse_frame_options(fr, sc_interp_get_frame(scin), options); - - maybe_recurse_before(scin, child); - set_frame(scin, fr); - sc_interp_run_style(scin, "frame"); - maybe_recurse_after(scin, child); + } else if ( strcmp(name, "author")==0 ) { + output_frame(scin, bl, ss, "$.slide.author"); } else if ( strcmp(name, "newpara")==0 ) { - struct frame *fr = sc_interp_get_frame(scin); - SCBlock *rbl = bl; - if ( st->macro_real_block != NULL ) { - bl = st->macro_real_block; - } - add_newpara(fr, bl, rbl); + add_newpara(fr, bl); } else { return 0; @@ -1170,68 +1051,7 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin) } -static int check_macro(const char *name, SCInterpreter *scin) -{ - int i; - struct sc_state *st = &scin->state[scin->j]; - - if ( name == NULL ) return 0; - - for ( i=0; i<st->n_macros; i++ ) { - if ( strcmp(st->macros[i].name, name) == 0 ) { - return 1; - } - } - - return 0; -} - - -static void exec_macro(SCBlock *bl, SCInterpreter *scin, SCBlock *child) -{ - struct sc_state *st = &scin->state[scin->j]; - int i; - const char *name; - - name = sc_block_name(bl); - for ( i=0; i<st->n_macros; i++ ) { - if ( strcmp(st->macros[i].name, name) == 0 ) { - sc_interp_save(scin); - scin->state[scin->j].macro_real_block = bl; - scin->state[scin->j].macro_contents = child; - sc_interp_add_blocks(scin, scin->state[scin->j].macros[i].bl); - sc_interp_restore(scin); - break; /* Stop iterating, because "st" is now invalid */ - } - } -} - - -static void run_macro_contents(SCInterpreter *scin) -{ - struct sc_state *st = &scin->state[scin->j]; - SCBlock *contents = st->macro_contents; - - sc_interp_save(scin); - scin->state[scin->j].macro_real_block = NULL; - sc_interp_add_blocks(scin, contents); - sc_interp_restore(scin); -} - - -static void run_editable(SCInterpreter *scin, SCBlock *contents) -{ - //struct sc_state *st = &scin->state[scin->j]; - - sc_interp_save(scin); - //scin->state[scin->j].macro_real_block = NULL; - scin->state[scin->j].macro_editable = 1; - sc_interp_add_blocks(scin, contents); - sc_interp_restore(scin); -} - - -int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl) +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); @@ -1241,16 +1061,11 @@ int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl) //show_sc_blocks(bl); //printf("<------------\n"); - if ( check_macro(name, scin) ) { - sc_interp_save(scin); - exec_macro(bl, scin, child); - sc_interp_restore(scin); - - } else if ( check_callback(scin, bl) ) { + 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) ) { + && check_outputs(bl, scin, ss) ) { /* Block handled as output thing */ } else if ( name == NULL ) { @@ -1258,95 +1073,86 @@ int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl) } else if ( strcmp(name, "presentation") == 0 ) { maybe_recurse_before(scin, child); - sc_interp_run_style(scin, "narrative"); - maybe_recurse_after(scin, child); - - } else if ( strcmp(name, "stylesheet") == 0 ) { - /* Ignore (see sc_interp_run_stylesheet) */ + apply_style(scin, ss, "$.narrative"); + maybe_recurse_after(scin, child, ss); } else if ( strcmp(name, "slide") == 0 ) { maybe_recurse_before(scin, child); - sc_interp_run_style(scin, "slide"); - maybe_recurse_after(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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); - - } else if ( strcmp(name, "contents") == 0 ) { - run_macro_contents(scin); - - } else if ( strcmp(name, "editable") == 0 ) { - run_editable(scin, child); + 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); + maybe_recurse_after(scin, child, ss); } else if ( strcmp(name, "bgcol") == 0 ) { maybe_recurse_before(scin, child); set_bgcol(scin, options); update_bg(scin); - maybe_recurse_after(scin, child); + maybe_recurse_after(scin, child, ss); } else if ( strcmp(name, "bggradh") == 0 ) { maybe_recurse_before(scin, child); set_bggrad(scin, options, GRAD_HORIZ); update_bg(scin); - maybe_recurse_after(scin, child); + maybe_recurse_after(scin, child, ss); } else if ( strcmp(name, "bggradv") == 0 ) { maybe_recurse_before(scin, child); set_bggrad(scin, options, GRAD_VERT); update_bg(scin); - maybe_recurse_after(scin, child); + maybe_recurse_after(scin, child, ss); } else if ( strcmp(name, "paraspace") == 0 ) { maybe_recurse_before(scin, child); set_paraspace(scin, options); - maybe_recurse_after(scin, child); + maybe_recurse_after(scin, child, ss); } else { @@ -1358,252 +1164,3 @@ int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl) return 0; } - -int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl) -{ - while ( bl != NULL ) { - if ( sc_interp_add_block(scin, bl) ) return 1; - bl = sc_block_next(bl); - } - - return 0; -} - - -static int try_add_style(SCInterpreter *scin, const char *options, SCBlock *bl) -{ - struct sc_state *st = &scin->state[scin->j]; - char *nn; - char *comma; - int i; - - nn = strdup(options); - comma = strchr(nn, ','); - if ( comma != NULL ) { - comma[0] = '\0'; - } - - for ( i=0; i<st->n_styles; i++ ) { - if ( strcmp(st->styles[i].name, nn) == 0 ) { - st->styles[i].name = nn; - st->styles[i].bl = bl; - st->styles[i].prev = NULL; /* FIXME: Stacking */ - return 0; - } - } - - if ( st->max_styles == st->n_styles ) { - - struct macro *styles_new; - - styles_new = realloc(st->styles, sizeof(struct macro) - * (st->max_styles+16)); - if ( styles_new == NULL ) { - fprintf(stderr, _("Failed to add style.\n")); - return 1; - } - - st->styles = styles_new; - st->max_styles += 16; - - } - - i = st->n_styles++; - - st->styles[i].name = nn; - st->styles[i].bl = bl; - st->styles[i].prev = NULL; /* FIXME: Stacking */ - - return 0; -} - - -static int try_add_macro(SCInterpreter *scin, const char *options, SCBlock *bl) -{ - struct sc_state *st = &scin->state[scin->j]; - char *nn; - char *comma; - int i; - - nn = strdup(options); - comma = strchr(nn, ','); - if ( comma != NULL ) { - comma[0] = '\0'; - } - - for ( i=0; i<st->n_macros; i++ ) { - if ( strcmp(st->macros[i].name, nn) == 0 ) { - st->macros[i].name = nn; - st->macros[i].bl = bl; - st->macros[i].prev = NULL; /* FIXME: Stacking */ - return 0; - } - } - - if ( st->max_macros == st->n_macros ) { - - struct macro *macros_new; - - macros_new = realloc(st->macros, sizeof(struct macro) - * (st->max_macros+16)); - if ( macros_new == NULL ) { - fprintf(stderr, _("Failed to add macro.\n")); - return 1; - } - - st->macros = macros_new; - st->max_macros += 16; - - } - - i = st->n_macros++; - - st->macros[i].name = nn; - st->macros[i].bl = bl; - st->macros[i].prev = NULL; /* FIXME: Stacking */ - - return 0; -} - - -static int try_add_template(SCInterpreter *scin, const char *options, SCBlock *bl) -{ - struct sc_state *st = &scin->state[scin->j]; - char *nn; - char *comma; - int i; - - nn = strdup(options); - comma = strchr(nn, ','); - if ( comma != NULL ) { - comma[0] = '\0'; - } - - for ( i=0; i<st->n_templates; i++ ) { - if ( strcmp(st->templates[i].name, nn) == 0 ) { - fprintf(stderr, _("Duplicate template '%s'\n"), nn); - return 0; - } - } - - if ( st->max_templates == st->n_templates ) { - - struct template *templates_new; - - templates_new = realloc(st->templates, sizeof(struct template) - * (st->max_templates+16)); - if ( templates_new == NULL ) { - fprintf(stderr, _("Failed to add templates\n")); - return 1; - } - - st->templates = templates_new; - st->max_templates += 16; - - } - - i = st->n_templates++; - - st->templates[i].name = nn; - st->templates[i].bl = bl; - - return 0; -} - -void add_macro(SCInterpreter *scin, const char *mname, const char *contents) -{ - SCBlock *bl = sc_parse(contents); - try_add_macro(scin, mname, bl); -} - - -void sc_interp_run_stylesheet(SCInterpreter *scin, SCBlock *bl) -{ - if ( bl == NULL ) return; - - if ( strcmp(sc_block_name(bl), "stylesheet") != 0 ) { - fprintf(stderr, _("Style sheet isn't a style sheet.\n")); - return; - } - - bl = sc_block_child(bl); - - while ( bl != NULL ) { - - const char *name = sc_block_name(bl); - const char *options = sc_block_options(bl); - - if ( name == NULL ) { - - /* Do nothing */ - - } else if ( strcmp(name, "def") == 0 ) { - try_add_macro(scin, options, sc_block_child(bl)); - - } else if ( strcmp(name, "ss") == 0 ) { /* Backward compatibility */ - try_add_macro(scin, options, sc_block_child(bl)); - - } else if ( strcmp(name, "style") == 0 ) { - try_add_style(scin, options, sc_block_child(bl)); - - } else if ( strcmp(name, "template") == 0 ) { - try_add_template(scin, options, sc_block_child(bl)); - - } else if ( strcmp(name, "font") == 0 ) { - set_font(scin, options); - - } else if ( strcmp(name, "fgcol") == 0 ) { - set_colour(scin, options); - - } else if ( strcmp(name, "bgcol") == 0 ) { - set_bgcol(scin, options); - update_bg(scin); - - } else if ( strcmp(name, "bggradh") == 0 ) { - set_bggrad(scin, options, GRAD_HORIZ); - update_bg(scin); - - } else if ( strcmp(name, "bggradv") == 0 ) { - set_bggrad(scin, options, GRAD_VERT); - update_bg(scin); - - } else if ( strcmp(name, "paraspace") == 0 ) { - set_paraspace(scin, options); - - } else if ( strcmp(name, "slidesize") == 0 ) { - set_slide_size(scin, options); - - } - - bl = sc_block_next(bl); - - } -} - - -int sc_interp_get_slide_size(SCInterpreter *scin, double *w, double *h) -{ - if ( !scin->state->have_size ) return 1; - *w = scin->state->slide_width; - *h = scin->state->slide_height; - return 0; -} - - -struct template_id *sc_interp_get_templates(SCInterpreter *scin, int *np) -{ - struct template_id *list; - int i; - - list = malloc(sizeof(struct template_id)*scin->state->n_templates); - if ( list == NULL ) return NULL; - - for ( i=0; i<scin->state->n_templates; i++ ) { - list[i].name = strdup(scin->state->templates[i].name); - list[i].friendlyname = strdup(scin->state->templates[i].name); - list[i].scblock = sc_block_copy(scin->state->templates[i].bl); - } - - *np = scin->state->n_templates; - return list; -} diff --git a/src/sc_interp.h b/src/sc_interp.h index 7b00aaa..418d6a6 100644 --- a/src/sc_interp.h +++ b/src/sc_interp.h @@ -41,6 +41,7 @@ typedef int (*SCCallbackClickFunc)(double x, double y, void *, void *); #include "frame.h" #include "imagestore.h" +#include "stylesheet.h" extern SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang, ImageStore *is, struct frame *top); @@ -49,13 +50,7 @@ extern void sc_interp_destroy(SCInterpreter *scin); extern void sc_interp_save(SCInterpreter *scin); extern void sc_interp_restore(SCInterpreter *scin); -extern int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl); -extern int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl); - -extern void sc_interp_run_stylesheet(SCInterpreter *scin, SCBlock *bl); -extern void sc_interp_run_style(SCInterpreter *scin, const char *sname); -extern void add_macro(SCInterpreter *scin, const char *mname, - const char *contents); +extern int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss); /* Callback lists */ @@ -73,28 +68,8 @@ extern struct frame *sc_interp_get_frame(SCInterpreter *scin); extern PangoFont *sc_interp_get_font(SCInterpreter *scin); extern PangoFontDescription *sc_interp_get_fontdesc(SCInterpreter *scin); extern double *sc_interp_get_fgcol(SCInterpreter *scin); -extern double *sc_interp_get_bgcol(SCInterpreter *scin); -extern double *sc_interp_get_bgcol2(SCInterpreter *scin); -extern GradientType sc_interp_get_bggrad(SCInterpreter *scin); - -extern int sc_interp_get_slide_size(SCInterpreter *scin, double *w, double *h); -extern SCBlock *sc_interp_get_macro_real_block(SCInterpreter *scin); - -extern int sc_interp_get_ascent(SCInterpreter *scin); -extern int sc_interp_get_height(SCInterpreter *scin); extern void update_geom(struct frame *fr); -struct template_id -{ - char *name; - char *friendlyname; - SCBlock *scblock; -}; - -extern struct template_id *sc_interp_get_templates(SCInterpreter *scin, - int *np); - - #endif /* SC_INTERP_H */ diff --git a/src/sc_parse.c b/src/sc_parse.c index b66dc1f..e8904a0 100644 --- a/src/sc_parse.c +++ b/src/sc_parse.c @@ -264,26 +264,8 @@ static SCBlock *sc_find_parent(SCBlock *top, SCBlock *find) } -void sc_block_substitute(SCBlock **top, SCBlock *old, SCBlock *new) -{ - if ( old == NULL ) { - fprintf(stderr, _("Substituting nothing!\n")); - return; - } - - if ( old == *top ) { - /* It is the first block */ - new->next = old->next; - *top = new; - } else { - sc_block_unlink(top, old); - sc_block_append_p(*top, new); - } -} - - /* Unlink "deleteme", which is somewhere under "top" */ -int sc_block_unlink(SCBlock **top, SCBlock *deleteme) +static int sc_block_unlink(SCBlock **top, SCBlock *deleteme) { SCBlock *parent = sc_find_parent(*top, deleteme); if ( parent == NULL ) { @@ -413,36 +395,6 @@ char *serialise_sc_block(const SCBlock *bl) } -/* Serialise an entire chain of blocks */ -char *serialise_sc_block_chain(const SCBlock *bl) -{ - char *a = strdup(""); - size_t len = 1; - - if ( a == NULL ) return NULL; - - while ( bl != NULL ) { - - char *c = serialise_sc_block(bl); - if ( c == NULL ) { - free(a); - return NULL; - } - - len += strlen(c); - a = realloc(a, len); - if ( a == NULL ) return NULL; - strcat(a, c); - free(c); - - bl = bl->next; - - } - - return a; -} - - int save_sc_block(GOutputStream *fh, const SCBlock *bl) { while ( bl != NULL ) { @@ -770,17 +722,6 @@ void sc_block_set_contents(SCBlock *bl, char *con) } -SCBlock *find_last_child(SCBlock *bl) -{ - if ( bl == NULL ) return NULL; - if ( bl->child == NULL ) return NULL; - - bl = bl->child; - while ( bl->next != NULL ) bl = bl->next; - return bl; -} - - void sc_insert_text(SCBlock *b1, size_t o1, const char *t) { if ( b1->contents == NULL ) { @@ -850,37 +791,6 @@ size_t scblock_delete_text(SCBlock *b, ssize_t o1, ssize_t o2) } -/* Create a deep copy of "bl", including all its children */ -SCBlock *sc_block_copy(const SCBlock *bl) -{ - SCBlock *copy; - SCBlock *first_copy; - - first_copy = sc_block_new(); - - copy = first_copy; - do { - - if ( bl->name != NULL ) copy->name = strdup(bl->name); - if ( bl->options != NULL ) copy->options = strdup(bl->options); - if ( bl->contents != NULL ) copy->contents = strdup(bl->contents); - if ( bl->child != NULL ) copy->child = sc_block_copy(bl->child); - - bl = bl->next; - - if ( bl != NULL ) { - SCBlock *nn; - nn = sc_block_new(); - copy->next = nn; - copy = nn; - } - - } while ( bl != NULL ); - - return first_copy; -} - - static char *s_strdup(const char *a) { if ( a == NULL ) return NULL; diff --git a/src/sc_parse.h b/src/sc_parse.h index 9277ee6..17ce2dd 100644 --- a/src/sc_parse.h +++ b/src/sc_parse.h @@ -37,14 +37,11 @@ extern SCBlock *sc_parse(const char *sc); extern SCBlock *sc_block_new(void); extern void sc_block_free(SCBlock *bl); -extern SCBlock *sc_block_copy(const SCBlock *bl); - extern SCBlock *sc_block_next(const SCBlock *bl); extern SCBlock *sc_block_child(const SCBlock *bl); extern const char *sc_block_name(const SCBlock *bl); extern const char *sc_block_options(const SCBlock *bl); extern const char *sc_block_contents(const SCBlock *bl); -extern void sc_block_substitute(SCBlock **top, SCBlock *old, SCBlock *new); extern SCBlock *sc_block_append(SCBlock *bl, char *name, char *opt, char *contents, @@ -68,9 +65,6 @@ extern SCBlock *sc_block_insert_after(SCBlock *afterme, char *name, char *opt, char *contents); extern int sc_block_delete(SCBlock **top, SCBlock *deleteme); -extern int sc_block_unlink(SCBlock **top, SCBlock *deleteme); - -extern SCBlock *find_last_child(SCBlock *bl); extern void sc_block_set_name(SCBlock *bl, char *nam); @@ -84,7 +78,6 @@ extern void show_sc_blocks(const SCBlock *bl); extern void show_sc_block(const SCBlock *bl, const char *prefix); extern char *serialise_sc_block(const SCBlock *bl); -extern char *serialise_sc_block_chain(const SCBlock *bl); extern int save_sc_block(GOutputStream *fh, const SCBlock *bl); extern size_t scblock_delete_text(SCBlock *b, ssize_t o1, ssize_t o2); diff --git a/src/slide_window.c b/src/slide_window.c index b010d1b..e23a3d7 100644 --- a/src/slide_window.c +++ b/src/slide_window.c @@ -109,7 +109,7 @@ static void delete_frame_sig(GSimpleAction *action, GVariant *parameter, /* Change the editor's slide to "np" */ -void change_edit_slide(SlideWindow *sw, SCBlock *np) +static void change_edit_slide(SlideWindow *sw, SCBlock *np) { sc_editor_set_slidenum(sw->sceditor, slide_number(sw->p, np)); diff --git a/src/slide_window.h b/src/slide_window.h index 77de920..b1d39a8 100644 --- a/src/slide_window.h +++ b/src/slide_window.h @@ -31,6 +31,5 @@ typedef struct _slidewindow SlideWindow; extern SlideWindow *slide_window_open(struct presentation *p, SCBlock *scblocks, GApplication *app); -extern void change_edit_slide(SlideWindow *sw, SCBlock *np); #endif /* SLIDEWINDOW_H */ diff --git a/src/stylesheet.c b/src/stylesheet.c new file mode 100644 index 0000000..96172a4 --- /dev/null +++ b/src/stylesheet.c @@ -0,0 +1,234 @@ +/* + * stylesheet.c + * + * Copyright © 2013-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 <json-glib/json-glib.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <gio/gio.h> +#include <gdk/gdk.h> + +#include "stylesheet.h" +#include "utils.h" + + +struct _stylesheet { + JsonNode *root; +}; + + +static int find_comma(const char *a) +{ + int i = 0; + int in_brackets = 0; + size_t len = strlen(a); + + do { + if ( (a[i] == ',') && !in_brackets ) return i; + if ( a[i] == '(' ) in_brackets++; + if ( a[i] == ')' ) in_brackets--; + i++; + } while ( i < len ); + return 0; +} + + +int parse_colour_duo(const char *a, GdkRGBA *col1, GdkRGBA *col2) +{ + char *acopy; + int cpos; + + acopy = strdup(a); + if ( acopy == NULL ) return 1; + + cpos = find_comma(acopy); + if ( cpos == 0 ) { + fprintf(stderr, _("Invalid bg gradient spec '%s'\n"), a); + return 1; + } + + acopy[cpos] = '\0'; + + if ( gdk_rgba_parse(col1, acopy) != TRUE ) { + fprintf(stderr, _("Failed to parse colour: %s\n"), acopy); + } + if ( gdk_rgba_parse(col2, &acopy[cpos+1]) != TRUE ) { + fprintf(stderr, _("Failed to parse colour: %s\n"), &acopy[cpos+1]); + } + + free(acopy); + return 0; +} + + +Stylesheet *stylesheet_load(GFile *file) +{ + JsonParser *parser; + gboolean r; + GError *err = NULL; + Stylesheet *ss; + char *everything; + gsize len; + + printf("Trying stylesheet '%s'\n", g_file_get_uri(file)); + + ss = calloc(1, sizeof(Stylesheet)); + if ( ss == NULL ) return NULL; + + parser = json_parser_new(); + + if ( !g_file_load_contents(file, NULL, &everything, &len, NULL, NULL) ) { + fprintf(stderr, _("Failed to load stylesheet '%s'\n"), + g_file_get_uri(file)); + return NULL; + } + + r = json_parser_load_from_data(parser, everything, len, &err); + if ( r == FALSE ) { + fprintf(stderr, "Failed to load style sheet: '%s'\n", err->message); + return NULL; + } + + ss->root = json_parser_steal_root(parser); + g_object_unref(parser); + + return ss; +} + + +static JsonObject *find_stylesheet_object(Stylesheet *ss, const char *path, + JsonNode **freeme) +{ + JsonNode *node; + JsonObject *obj; + JsonArray *array; + GError *err = NULL; + + node = json_path_query(path, ss->root, &err); + array = json_node_get_array(node); + + if ( json_array_get_length(array) != 1 ) { + json_node_unref(node); + fprintf(stderr, "More than one result in SS lookup (%s)!\n", path); + return NULL; + } + + obj = json_array_get_object_element(array, 0); + if ( obj == NULL ) { + printf("%s not a JSON object\n", path); + json_node_unref(node); + return NULL; + } + + *freeme = node; + return obj; +} + + +char *stylesheet_lookup(Stylesheet *ss, const char *path, const char *key) +{ + JsonObject *obj; + char *ret = NULL; + JsonNode *node = NULL; + + if ( ss == NULL ) { + fprintf(stderr, _("No stylesheet!\n")); + return NULL; + } + + obj = find_stylesheet_object(ss, path, &node); + + if ( json_object_has_member(obj, key) ) { + + const gchar *v; + v = json_object_get_string_member(obj, key); + if ( v != NULL ) { + ret = strdup(v); + } else { + fprintf(stderr, "Error retrieving %s.%s\n", path, key); + } + + } /* else not found, too bad */ + + if ( node != NULL ) json_node_unref(node); + return ret; +} + + +int stylesheet_set(Stylesheet *ss, const char *path, const char *key, + const char *new_val) +{ + JsonObject *obj; + JsonNode *node = NULL; + int r = 1; + + if ( ss == NULL ) { + fprintf(stderr, _("No stylesheet!\n")); + return 1; + } + + obj = find_stylesheet_object(ss, path, &node); + if ( obj != NULL ) { + json_object_set_string_member(obj, key, new_val); + r = 0; + } /* else most likely the object (e.g. "$.slide", "$.slide.frame", + * "$.narrative" etc doesn't exist */ + + if ( node != NULL ) json_node_unref(node); + return r; +} + + +int stylesheet_delete(Stylesheet *ss, const char *path, const char *key) +{ + JsonObject *obj; + JsonNode *node = NULL; + int r = 1; + + if ( ss == NULL ) { + fprintf(stderr, _("No stylesheet!\n")); + return 1; + } + + obj = find_stylesheet_object(ss, path, &node); + if ( obj != NULL ) { + json_object_remove_member(obj, key); + r = 0; + } /* else most likely the object (e.g. "$.slide", "$.slide.frame", + * "$.narrative" etc doesn't exist */ + + if ( node != NULL ) json_node_unref(node); + return r; +} + + +void stylesheet_free(Stylesheet *ss) +{ + g_object_unref(ss->root); + free(ss); +} + diff --git a/src/stylesheet.h b/src/stylesheet.h new file mode 100644 index 0000000..c24c62c --- /dev/null +++ b/src/stylesheet.h @@ -0,0 +1,48 @@ +/* + * stylesheet.h + * + * Copyright © 2013-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/>. + * + */ + +#ifndef STYLESHEET_H +#define STYLESHEET_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gio/gio.h> +#include <gdk/gdk.h> + +typedef struct _stylesheet Stylesheet; + +extern Stylesheet *stylesheet_load(GFile *file); + +extern int parse_colour_duo(const char *a, GdkRGBA *col1, GdkRGBA *col2); + +extern char *stylesheet_lookup(Stylesheet *ss, const char *path, const char *key); + +extern int stylesheet_set(Stylesheet *ss, const char *path, const char *key, + const char *new_val); + +extern int stylesheet_delete(Stylesheet *ss, const char *path, const char *key); + +extern void stylesheet_free(Stylesheet *ss); + +#endif /* STYLESHEET_H */ diff --git a/src/stylesheet_editor.c b/src/stylesheet_editor.c index 66e8afa..8100472 100644 --- a/src/stylesheet_editor.c +++ b/src/stylesheet_editor.c @@ -33,12 +33,13 @@ #include "stylesheet_editor.h" #include "presentation.h" #include "sc_interp.h" +#include "stylesheet.h" +#include "utils.h" G_DEFINE_TYPE_WITH_CODE(StylesheetEditor, stylesheet_editor, GTK_TYPE_DIALOG, NULL) -static void set_values_from_presentation(StylesheetEditor *se); struct _sspriv { @@ -46,175 +47,247 @@ struct _sspriv }; -static SCBlock *find_block(SCBlock *bl, const char *find) +static void set_font_from_ss(Stylesheet *ss, const char *path, GtkWidget *w) { - while ( bl != NULL ) { - - const char *name = sc_block_name(bl); - if ( (name != NULL) && (strcmp(name, find)==0) ) { - return bl; - } - - bl = sc_block_next(bl); - + char *result = stylesheet_lookup(ss, path, "font"); + if ( result != NULL ) { + gtk_font_button_set_font_name(GTK_FONT_BUTTON(w), result); } - - return NULL; } -static void find_replace(SCBlock *parent, const char *find, const char *seti) +static void set_col_from_ss(Stylesheet *ss, const char *path, GtkWidget *w) { - SCBlock *bl = find_block(sc_block_child(parent), find); - - if ( bl != NULL ) { + char *result = stylesheet_lookup(ss, path, "fgcol"); + if ( result != NULL ) { + GdkRGBA rgba; + if ( gdk_rgba_parse(&rgba, result) == TRUE ) { + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(w), &rgba); + } + } +} - printf("replacing '%s' with '%s'\n", sc_block_options(bl), seti); - sc_block_set_options(bl, strdup(seti)); +static void set_vals_from_ss(Stylesheet *ss, const char *path, const char *key, + GtkWidget *wl, GtkWidget *wr, + GtkWidget *wt, GtkWidget *wb) +{ + char *result = stylesheet_lookup(ss, path, key); + if ( result != NULL ) { + float v[4]; + if ( parse_tuple(result, v) == 0 ) { + gtk_spin_button_set_value(GTK_SPIN_BUTTON(wl), v[0]); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(wr), v[1]); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(wt), v[2]); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(wb), v[3]); + } else { + fprintf(stderr, _("Failed to parse quad: %s\n"), result); + } } else { - - /* Block not found -> create it */ - sc_block_append_inside(parent, strdup(find), strdup(seti), NULL); - + printf("Not found %s\n", path); } } -static SCBlock *find_or_create_style(struct presentation *p, const char *style_name) +static void set_size_from_ss(Stylesheet *ss, const char *path, + GtkWidget *ww, GtkWidget *wh) { - SCBlock *bl; - const char *name; - - /* If no stylesheet yet, create one now */ - if ( p->stylesheet == NULL ) { - p->stylesheet = sc_parse("\\stylesheet"); - if ( p->stylesheet == NULL ) { - fprintf(stderr, "WARNING: Couldn't create stylesheet\n"); - return NULL; + char *result = stylesheet_lookup(ss, path, "size"); + if ( result != NULL ) { + float v[2]; + if ( parse_double(result, v) == 0 ) { + gtk_spin_button_set_value(GTK_SPIN_BUTTON(ww), v[0]); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(wh), v[1]); + } else { + fprintf(stderr, _("Failed to parse double: %s\n"), result); } - sc_block_append_p(p->stylesheet, p->scblocks); - p->scblocks = p->stylesheet; + } else { + printf("Not found %s\n", path); } - bl = p->stylesheet; +} - name = sc_block_name(bl); - if ( (name != NULL) && (strcmp(name, "stylesheet")==0) ) { - bl = sc_block_child(bl); +static void set_bg_from_ss(Stylesheet *ss, const char *path, GtkWidget *wcol, + GtkWidget *wcol2, GtkWidget *wgrad) +{ + char *result; + int found = 0; + + result = stylesheet_lookup(ss, path, "bgcol"); + if ( result != NULL ) { + GdkRGBA rgba; + found = 1; + if ( gdk_rgba_parse(&rgba, result) == TRUE ) { + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol), &rgba); + gtk_combo_box_set_active_id(GTK_COMBO_BOX(wgrad), "flat"); + gtk_widget_set_sensitive(wcol, TRUE); + gtk_widget_set_sensitive(wcol2, FALSE); + } else { + fprintf(stderr, _("Failed to parse colour: %s\n"), result); + } } - while ( bl != NULL ) { - - const char *name = sc_block_name(bl); - const char *options = sc_block_options(bl); - if ( (name != NULL) && (strcmp(name, "style")==0) - && (strcmp(options, style_name)==0) ) - { - return bl; + result = stylesheet_lookup(ss, path, "bggradv"); + if ( result != NULL ) { + GdkRGBA rgba1, rgba2; + found = 1; + if ( parse_colour_duo(result, &rgba1, &rgba2) == 0 ) { + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol), &rgba1); + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol2), &rgba2); + gtk_combo_box_set_active_id(GTK_COMBO_BOX(wgrad), "vert"); + gtk_widget_set_sensitive(wcol, TRUE); + gtk_widget_set_sensitive(wcol2, TRUE); } + } - bl = sc_block_next(bl); + result = stylesheet_lookup(ss, path, "bggradh"); + if ( result != NULL ) { + GdkRGBA rgba1, rgba2; + found = 1; + if ( parse_colour_duo(result, &rgba1, &rgba2) == 0 ) { + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol), &rgba1); + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol2), &rgba2); + gtk_combo_box_set_active_id(GTK_COMBO_BOX(wgrad), "horiz"); + gtk_widget_set_sensitive(wcol, TRUE); + gtk_widget_set_sensitive(wcol2, TRUE); + } + } + if ( !found ) { + GdkRGBA rgba; + rgba.red = 1.0; + rgba.green = 1.0; + rgba.blue = 1.0; + rgba.alpha = 0.0; + gtk_combo_box_set_active_id(GTK_COMBO_BOX(wgrad), "flat"); + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol), &rgba); + gtk_widget_set_sensitive(wcol, TRUE); + gtk_widget_set_sensitive(wcol2, FALSE); } +} - /* Not found -> add style */ - return sc_block_append_inside(p->stylesheet, strdup("style"), - strdup(style_name), NULL); + +static void set_values_from_presentation(StylesheetEditor *se) +{ + Stylesheet *ss = se->priv->p->stylesheet; + + /* Narrative */ + set_font_from_ss(ss, "$.narrative", se->narrative_style_font); + set_col_from_ss(ss, "$.narrative", se->narrative_style_fgcol); + set_bg_from_ss(ss, "$.narrative", se->narrative_style_bgcol, + se->narrative_style_bgcol2, + se->narrative_style_bggrad); + set_vals_from_ss(ss, "$.narrative", "pad", se->narrative_style_padding_l, + se->narrative_style_padding_r, + se->narrative_style_padding_t, + se->narrative_style_padding_b); + set_vals_from_ss(ss, "$.narrative", "paraspace", se->narrative_style_paraspace_l, + se->narrative_style_paraspace_r, + se->narrative_style_paraspace_t, + se->narrative_style_paraspace_b); + + /* Slides */ + set_size_from_ss(ss, "$.slide", se->slide_size_w, se->slide_size_h); + set_bg_from_ss(ss, "$.slide", se->slide_style_bgcol, + se->slide_style_bgcol2, + se->slide_style_bggrad); + + + /* Frames */ + set_font_from_ss(ss, "$.slide.frame", se->frame_style_font); + set_col_from_ss(ss, "$.slide.frame", se->frame_style_fgcol); + set_bg_from_ss(ss, "$.slide.frame", se->frame_style_bgcol, + se->frame_style_bgcol2, + se->frame_style_bggrad); + set_vals_from_ss(ss, "$.slide.frame", "pad", se->frame_style_padding_l, + se->frame_style_padding_r, + se->frame_style_padding_t, + se->frame_style_padding_b); + set_vals_from_ss(ss, "$.slide.frame", "paraspace", se->frame_style_paraspace_l, + se->frame_style_paraspace_r, + se->frame_style_paraspace_t, + se->frame_style_paraspace_b); } -static void set_ss(struct presentation *p, const char *style_name, - const char *find, const char *seti) +static GradientType id_to_gradtype(const gchar *id) { - SCBlock *bl = find_or_create_style(p, style_name); - if ( bl == NULL ) { - fprintf(stderr, "WARNING: Couldn't find style\n"); - return; - } - find_replace(bl, find, seti); + assert(id != NULL); + if ( strcmp(id, "flat") == 0 ) return GRAD_NONE; + if ( strcmp(id, "horiz") == 0 ) return GRAD_HORIZ; + if ( strcmp(id, "vert") == 0 ) return GRAD_VERT; + return GRAD_NONE; } -static void set_ss_bg_block(SCBlock *bl, GradientType bggrad, - GdkRGBA col1, GdkRGBA col2) +static void update_bg(struct presentation *p, const char *style_name, + GtkWidget *bggradw, GtkWidget *col1w, GtkWidget*col2w) { - char tmp[64]; + GradientType g; + const gchar *id; + GdkRGBA rgba; + gchar *col1; + gchar *col2; + gchar *gradient; - switch ( bggrad ) { + id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(bggradw)); + g = id_to_gradtype(id); - case GRAD_NONE : - sc_block_set_name(bl, strdup("bgcol")); - snprintf(tmp, 63, "#%.2x%.2x%.2x", - (int)(col1.red*255), (int)(col1.green*255), (int)(col1.blue*255)); - sc_block_set_options(bl, strdup(tmp)); - break; + gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(col1w), &rgba); + if ( rgba.alpha < 0.000001 ) rgba.alpha = 0.0; + col1 = gdk_rgba_to_string(&rgba); - case GRAD_VERT : - sc_block_set_name(bl, strdup("bggradv")); - snprintf(tmp, 63, "#%.2x%.2x%.2x,#%.2x%.2x%.2x", - (int)(col1.red*255), (int)(col1.green*255), (int)(col1.blue*255), - (int)(col2.red*255), (int)(col2.green*255), (int)(col2.blue*255)); - sc_block_set_options(bl, strdup(tmp)); + gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(col2w), &rgba); + col2 = gdk_rgba_to_string(&rgba); + + gradient = g_strconcat(col1, ",", col2, NULL); + + switch ( g ) { + + case GRAD_NONE : + stylesheet_set(p->stylesheet, style_name, "bgcol", + col1); + stylesheet_delete(p->stylesheet, style_name, "bggradv"); + stylesheet_delete(p->stylesheet, style_name, "bggradh"); break; case GRAD_HORIZ : - sc_block_set_name(bl, strdup("bggradh")); - snprintf(tmp, 63, "#%.2x%.2x%.2x,#%.2x%.2x%.2x", - (int)(col1.red*255), (int)(col1.green*255), (int)(col1.blue*255), - (int)(col2.red*255), (int)(col2.green*255), (int)(col2.blue*255)); - sc_block_set_options(bl, strdup(tmp)); + stylesheet_set(p->stylesheet, style_name, "bggradh", + gradient); + stylesheet_delete(p->stylesheet, style_name, "bggradv"); + stylesheet_delete(p->stylesheet, style_name, "bgcol"); break; - case GRAD_NOBG : - printf("no bg\n"); - sc_block_set_name(bl, NULL); - sc_block_set_options(bl, NULL); - sc_block_set_contents(bl, NULL); + case GRAD_VERT : + stylesheet_set(p->stylesheet, style_name, "bggradv", + gradient); + stylesheet_delete(p->stylesheet, style_name, "bggradh"); + stylesheet_delete(p->stylesheet, style_name, "bgcol"); break; } -} - - -static int try_set_block(SCBlock **parent, const char *name, - GradientType bggrad, GdkRGBA col1, GdkRGBA col2) -{ - SCBlock *ibl; - - ibl = find_block(sc_block_child(*parent), name); - if ( ibl != NULL ) { - if ( bggrad != GRAD_NOBG ) { - set_ss_bg_block(ibl, bggrad, col1, col2); - return 1; - } else { - sc_block_delete(parent, ibl); - return 1; - } - } - return 0; + g_free(gradient); + g_free(col1); + g_free(col2); } -static void update_bg(struct presentation *p, const char *style_name, - GradientType bggrad, GdkRGBA col1, GdkRGBA col2) +static void update_spacing(struct presentation *p, const char *style_name, + const char *key, GtkWidget *wl, GtkWidget *wr, + GtkWidget *wt, GtkWidget *wb) { - int done; - SCBlock *bl; + int v[4]; + char tmp[256]; - bl = find_or_create_style(p, style_name); - if ( bl == NULL ) { - fprintf(stderr, "WARNING: Couldn't find style\n"); - return; - } + v[0] = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wl)); + v[1] = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wr)); + v[2] = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wt)); + v[3] = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wb)); - /* FIXME: What if there are two of these? */ - done = try_set_block(&bl, "bgcol", bggrad, col1, col2); - if ( !done ) done = try_set_block(&bl, "bggradv", bggrad, col1, col2); - if ( !done ) done = try_set_block(&bl, "bggradh", bggrad, col1, col2); - if ( !done && bggrad != GRAD_NOBG ) { - SCBlock *ibl = sc_block_append_inside(bl, NULL, NULL, NULL); - set_ss_bg_block(ibl, bggrad, col1, col2); + if ( snprintf(tmp, 256, "%i,%i,%i,%i", v[0], v[1], v[2], v[3]) >= 256 ) { + fprintf(stderr, _("Spacing too long\n")); + } else { + stylesheet_set(p->stylesheet, style_name, key, tmp); } } @@ -225,23 +298,13 @@ static void revert_sig(GtkButton *button, StylesheetEditor *widget) } -static GradientType id_to_gradtype(const gchar *id) -{ - assert(id != NULL); - if ( strcmp(id, "flat") == 0 ) return GRAD_NONE; - if ( strcmp(id, "horiz") == 0 ) return GRAD_HORIZ; - if ( strcmp(id, "vert") == 0 ) return GRAD_VERT; - if ( strcmp(id, "none") == 0 ) return GRAD_NOBG; - return GRAD_NONE; -} - - static void set_font(GtkFontButton *widget, StylesheetEditor *se, const char *style_name) { const gchar *font; font = gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget)); - set_ss(se->priv->p, style_name, "font", font); + + stylesheet_set(se->priv->p->stylesheet, style_name, "font", font); set_values_from_presentation(se); g_signal_emit_by_name(se, "changed"); } @@ -254,7 +317,7 @@ static void set_col(GtkColorButton *widget, StylesheetEditor *se, gchar *col; gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), &rgba); col = gdk_rgba_to_string(&rgba); - set_ss(se->priv->p, style_name, col_name, col); + stylesheet_set(se->priv->p->stylesheet, style_name, "fgcol", col); g_free(col); set_values_from_presentation(se); g_signal_emit_by_name(se, "changed"); @@ -263,135 +326,125 @@ static void set_col(GtkColorButton *widget, StylesheetEditor *se, static void narrative_font_sig(GtkFontButton *widget, StylesheetEditor *se) { - set_font(widget, se, "narrative"); + set_font(widget, se, "$.narrative"); } static void narrative_fgcol_sig(GtkColorButton *widget, StylesheetEditor *se) { - set_col(widget, se, "narrative", "fgcol"); + set_col(widget, se, "$.narrative", "fgcol"); } -static void narrative_bgcol_sig(GtkColorButton *widget, StylesheetEditor *se) +static void narrative_bg_sig(GtkColorButton *widget, StylesheetEditor *se) { - gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), - &se->narrative_bgcol); - update_bg(se->priv->p, "narrative", se->narrative_bggrad, - se->narrative_bgcol, se->narrative_bgcol2); - + update_bg(se->priv->p, "$.narrative", + se->narrative_style_bggrad, + se->narrative_style_bgcol, + se->narrative_style_bgcol2); set_values_from_presentation(se); g_signal_emit_by_name(se, "changed"); } -static void narrative_bgcol2_sig(GtkColorButton *widget, StylesheetEditor *se) +static void slide_size_sig(GtkSpinButton *widget, StylesheetEditor *se) { - gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), - &se->narrative_bgcol2); - update_bg(se->priv->p, "narrative", se->narrative_bggrad, - se->narrative_bgcol, se->narrative_bgcol2); - - set_values_from_presentation(se); - g_signal_emit_by_name(se, "changed"); -} + int w, h; + char tmp[256]; + w = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(se->slide_size_w)); + h = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(se->slide_size_h)); -static void narrative_bggrad_sig(GtkComboBox *widget, StylesheetEditor *se) -{ - const gchar *id; - id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget)); - se->narrative_bggrad = id_to_gradtype(id); - update_bg(se->priv->p, "narrative", se->narrative_bggrad, - se->narrative_bgcol, se->narrative_bgcol2); + if ( snprintf(tmp, 256, "%ix%i", w, h) >= 256 ) { + fprintf(stderr, _("Slide size too long\n")); + } else { + stylesheet_set(se->priv->p->stylesheet, "$.slide", "size", tmp); + se->priv->p->slide_width = w; + se->priv->p->slide_height = h; + } set_values_from_presentation(se); g_signal_emit_by_name(se, "changed"); } -static void slide_bgcol_sig(GtkColorButton *widget, StylesheetEditor *se) +static void slide_bg_sig(GtkColorButton *widget, StylesheetEditor *se) { - gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), - &se->slide_bgcol); - update_bg(se->priv->p, "slide", se->slide_bggrad, - se->slide_bgcol, se->slide_bgcol2); - + update_bg(se->priv->p, "$.slide", + se->slide_style_bggrad, + se->slide_style_bgcol, + se->slide_style_bgcol2); set_values_from_presentation(se); g_signal_emit_by_name(se, "changed"); } -static void slide_bgcol2_sig(GtkColorButton *widget, StylesheetEditor *se) +static void frame_font_sig(GtkFontButton *widget, StylesheetEditor *se) { - gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), - &se->slide_bgcol2); - update_bg(se->priv->p, "slide", se->slide_bggrad, - se->slide_bgcol, se->slide_bgcol2); - - set_values_from_presentation(se); - g_signal_emit_by_name(se, "changed"); + set_font(widget, se, "$.slide.frame"); } -static void slide_bggrad_sig(GtkComboBox *widget, StylesheetEditor *se) +static void frame_fgcol_sig(GtkColorButton *widget, StylesheetEditor *se) { - const gchar *id; - - id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget)); - se->slide_bggrad = id_to_gradtype(id); - update_bg(se->priv->p, "slide", se->slide_bggrad, - se->slide_bgcol, se->slide_bgcol2); - - set_values_from_presentation(se); - g_signal_emit_by_name(se, "changed"); + set_col(widget, se, "$.slide.frame", "fgcol"); } -static void frame_font_sig(GtkFontButton *widget, StylesheetEditor *se) +static void frame_bg_sig(GtkColorButton *widget, StylesheetEditor *se) { - set_font(widget, se, "frame"); + update_bg(se->priv->p, "$.slide.frame", + se->frame_style_bggrad, + se->frame_style_bgcol, + se->frame_style_bgcol2); + set_values_from_presentation(se); + g_signal_emit_by_name(se, "changed"); } -static void frame_fgcol_sig(GtkColorButton *widget, StylesheetEditor *se) +static void frame_padding_sig(GtkSpinButton *widget, StylesheetEditor *se) { - set_col(widget, se, "frame", "fgcol"); + update_spacing(se->priv->p, "$.slide.frame", "pad", + se->frame_style_padding_l, + se->frame_style_padding_r, + se->frame_style_padding_t, + se->frame_style_padding_b); + set_values_from_presentation(se); + g_signal_emit_by_name(se, "changed"); } -static void frame_bgcol_sig(GtkColorButton *widget, StylesheetEditor *se) +static void frame_paraspace_sig(GtkSpinButton *widget, StylesheetEditor *se) { - gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), - &se->frame_bgcol); - update_bg(se->priv->p, "frame", se->frame_bggrad, - se->frame_bgcol, se->frame_bgcol2); - + update_spacing(se->priv->p, "$.slide.frame", "paraspace", + se->frame_style_paraspace_l, + se->frame_style_paraspace_r, + se->frame_style_paraspace_t, + se->frame_style_paraspace_b); set_values_from_presentation(se); g_signal_emit_by_name(se, "changed"); } -static void frame_bgcol2_sig(GtkColorButton *widget, StylesheetEditor *se) +static void narrative_padding_sig(GtkSpinButton *widget, StylesheetEditor *se) { - gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), - &se->frame_bgcol); - update_bg(se->priv->p, "frame", se->frame_bggrad, - se->frame_bgcol, se->frame_bgcol2); - + update_spacing(se->priv->p, "$.narrative", "pad", + se->narrative_style_padding_l, + se->narrative_style_padding_r, + se->narrative_style_padding_t, + se->narrative_style_padding_b); set_values_from_presentation(se); g_signal_emit_by_name(se, "changed"); } -static void frame_bggrad_sig(GtkComboBox *widget, StylesheetEditor *se) +static void narrative_paraspace_sig(GtkSpinButton *widget, StylesheetEditor *se) { - const gchar *id; - id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget)); - se->frame_bggrad = id_to_gradtype(id); - update_bg(se->priv->p, "frame", se->frame_bggrad, - se->frame_bgcol, se->frame_bgcol2); - + update_spacing(se->priv->p, "$.narrative", "paraspace", + se->narrative_style_paraspace_l, + se->narrative_style_paraspace_r, + se->narrative_style_paraspace_t, + se->narrative_style_paraspace_b); set_values_from_presentation(se); g_signal_emit_by_name(se, "changed"); } @@ -423,21 +476,39 @@ void stylesheet_editor_class_init(StylesheetEditorClass *klass) /* Narrative style */ SE_BIND_CHILD(narrative_style_font, narrative_font_sig); SE_BIND_CHILD(narrative_style_fgcol, narrative_fgcol_sig); - SE_BIND_CHILD(narrative_style_bgcol, narrative_bgcol_sig); - SE_BIND_CHILD(narrative_style_bgcol2, narrative_bgcol2_sig); - SE_BIND_CHILD(narrative_style_bggrad, narrative_bggrad_sig); + SE_BIND_CHILD(narrative_style_bgcol, narrative_bg_sig); + SE_BIND_CHILD(narrative_style_bgcol2, narrative_bg_sig); + SE_BIND_CHILD(narrative_style_bggrad, narrative_bg_sig); + SE_BIND_CHILD(narrative_style_paraspace_l, narrative_paraspace_sig); + SE_BIND_CHILD(narrative_style_paraspace_r, narrative_paraspace_sig); + SE_BIND_CHILD(narrative_style_paraspace_t, narrative_paraspace_sig); + SE_BIND_CHILD(narrative_style_paraspace_b, narrative_paraspace_sig); + SE_BIND_CHILD(narrative_style_padding_l, narrative_padding_sig); + SE_BIND_CHILD(narrative_style_padding_r, narrative_padding_sig); + SE_BIND_CHILD(narrative_style_padding_t, narrative_padding_sig); + SE_BIND_CHILD(narrative_style_padding_b, narrative_padding_sig); /* Slide style */ - SE_BIND_CHILD(slide_style_bgcol, slide_bgcol_sig); - SE_BIND_CHILD(slide_style_bgcol2, slide_bgcol2_sig); - SE_BIND_CHILD(slide_style_bggrad, slide_bggrad_sig); + SE_BIND_CHILD(slide_size_w, slide_size_sig); + SE_BIND_CHILD(slide_size_h, slide_size_sig); + SE_BIND_CHILD(slide_style_bgcol, slide_bg_sig); + SE_BIND_CHILD(slide_style_bgcol2, slide_bg_sig); + SE_BIND_CHILD(slide_style_bggrad, slide_bg_sig); /* Slide->frame style */ SE_BIND_CHILD(frame_style_font, frame_font_sig); SE_BIND_CHILD(frame_style_fgcol, frame_fgcol_sig); - SE_BIND_CHILD(frame_style_bgcol, frame_bgcol_sig); - SE_BIND_CHILD(frame_style_bgcol2, frame_bgcol2_sig); - SE_BIND_CHILD(frame_style_bggrad, frame_bggrad_sig); + SE_BIND_CHILD(frame_style_bgcol, frame_bg_sig); + SE_BIND_CHILD(frame_style_bgcol2, frame_bg_sig); + SE_BIND_CHILD(frame_style_bggrad, frame_bg_sig); + SE_BIND_CHILD(frame_style_paraspace_l, frame_paraspace_sig); + SE_BIND_CHILD(frame_style_paraspace_r, frame_paraspace_sig); + SE_BIND_CHILD(frame_style_paraspace_t, frame_paraspace_sig); + SE_BIND_CHILD(frame_style_paraspace_b, frame_paraspace_sig); + SE_BIND_CHILD(frame_style_padding_l, frame_padding_sig); + SE_BIND_CHILD(frame_style_padding_r, frame_padding_sig); + SE_BIND_CHILD(frame_style_padding_t, frame_padding_sig); + SE_BIND_CHILD(frame_style_padding_b, frame_padding_sig); gtk_widget_class_bind_template_callback(widget_class, revert_sig); @@ -446,103 +517,6 @@ void stylesheet_editor_class_init(StylesheetEditorClass *klass) } -static void set_from_interp_col(double *col, GtkWidget *w) -{ - GdkRGBA rgba; - - rgba.red = col[0]; - rgba.green = col[1]; - rgba.blue = col[2]; - rgba.alpha = col[3]; - gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(w), &rgba); -} - - -static void set_from_interp_bggrad(SCInterpreter *scin, GtkWidget *w) -{ - GradientType grad; - const gchar *id; - - grad = sc_interp_get_bggrad(scin); - - switch ( grad ) { - case GRAD_NONE : id = "flat"; break; - case GRAD_HORIZ : id = "horiz"; break; - case GRAD_VERT : id = "vert"; break; - case GRAD_NOBG : id = "none"; break; - default : id = NULL; break; - } - - gtk_combo_box_set_active_id(GTK_COMBO_BOX(w), id); -} - - -static void set_from_interp_font(SCInterpreter *scin, GtkWidget *w) -{ - char *fontname; - PangoFontDescription *fontdesc; - - fontdesc = sc_interp_get_fontdesc(scin); - fontname = pango_font_description_to_string(fontdesc); - gtk_font_button_set_font_name(GTK_FONT_BUTTON(w), fontname); - g_free(fontname); -} - - -static void set_values_from_presentation(StylesheetEditor *se) -{ - SCInterpreter *scin; - PangoContext *pc; - - pc = gdk_pango_context_get(); - - scin = sc_interp_new(pc, NULL, NULL, NULL); - sc_interp_run_stylesheet(scin, se->priv->p->stylesheet); /* NULL stylesheet is OK */ - - /* Narrative style */ - sc_interp_save(scin); - sc_interp_run_style(scin, "narrative"); - set_from_interp_font(scin, se->narrative_style_font); - set_from_interp_col(sc_interp_get_fgcol(scin), se->narrative_style_fgcol); - set_from_interp_col(sc_interp_get_bgcol(scin), se->narrative_style_bgcol); - gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(se->narrative_style_bgcol), - &se->narrative_bgcol); - set_from_interp_col(sc_interp_get_bgcol2(scin), se->narrative_style_bgcol2); - gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(se->narrative_style_bgcol2), - &se->narrative_bgcol2); - set_from_interp_bggrad(scin, se->narrative_style_bggrad); - sc_interp_restore(scin); - - /* Slide style */ - sc_interp_save(scin); - sc_interp_run_style(scin, "slide"); - set_from_interp_col(sc_interp_get_bgcol(scin), se->slide_style_bgcol); - gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(se->slide_style_bgcol), - &se->slide_bgcol); - set_from_interp_col(sc_interp_get_bgcol2(scin), se->slide_style_bgcol2); - gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(se->slide_style_bgcol2), - &se->slide_bgcol2); - set_from_interp_bggrad(scin, se->slide_style_bggrad); - sc_interp_restore(scin); - - /* Slide->Frame style */ - sc_interp_save(scin); - sc_interp_run_style(scin, "frame"); - set_from_interp_font(scin, se->frame_style_font); - set_from_interp_col(sc_interp_get_fgcol(scin), se->frame_style_fgcol); - set_from_interp_col(sc_interp_get_bgcol(scin), se->frame_style_bgcol); - gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(se->frame_style_bgcol), - &se->frame_bgcol); - set_from_interp_col(sc_interp_get_bgcol2(scin), se->frame_style_bgcol2); - gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(se->frame_style_bgcol2), - &se->frame_bgcol2); - set_from_interp_bggrad(scin, se->frame_style_bggrad); - sc_interp_restore(scin); - - sc_interp_destroy(scin); -} - - StylesheetEditor *stylesheet_editor_new(struct presentation *p) { StylesheetEditor *se; diff --git a/src/stylesheet_editor.h b/src/stylesheet_editor.h index 480bd8a..22856da 100644 --- a/src/stylesheet_editor.h +++ b/src/stylesheet_editor.h @@ -63,6 +63,16 @@ struct _stylesheeteditor GtkWidget *narrative_style_bgcol; GtkWidget *narrative_style_bgcol2; GtkWidget *narrative_style_bggrad; + GtkWidget *narrative_style_paraspace_l; + GtkWidget *narrative_style_paraspace_r; + GtkWidget *narrative_style_paraspace_t; + GtkWidget *narrative_style_paraspace_b; + GtkWidget *narrative_style_padding_l; + GtkWidget *narrative_style_padding_r; + GtkWidget *narrative_style_padding_t; + GtkWidget *narrative_style_padding_b; + GtkWidget *slide_size_w; + GtkWidget *slide_size_h; GtkWidget *slide_style_bgcol; GtkWidget *slide_style_bgcol2; GtkWidget *slide_style_bggrad; @@ -71,20 +81,17 @@ struct _stylesheeteditor GtkWidget *frame_style_bgcol; GtkWidget *frame_style_bgcol2; GtkWidget *frame_style_bggrad; + GtkWidget *frame_style_paraspace_l; + GtkWidget *frame_style_paraspace_r; + GtkWidget *frame_style_paraspace_t; + GtkWidget *frame_style_paraspace_b; + GtkWidget *frame_style_padding_l; + GtkWidget *frame_style_padding_r; + GtkWidget *frame_style_padding_t; + GtkWidget *frame_style_padding_b; StylesheetEditorPrivate *priv; - - GdkRGBA narrative_bgcol; - GdkRGBA narrative_bgcol2; - GradientType narrative_bggrad; - GdkRGBA slide_bgcol; - GdkRGBA slide_bgcol2; - GradientType slide_bggrad; - GdkRGBA frame_bgcol; - GdkRGBA frame_bgcol2; - GradientType frame_bggrad; }; - struct _stylesheeteditorclass { GtkDialogClass parent_class; diff --git a/src/utils.c b/src/utils.c index 9033466..277b3f1 100644 --- a/src/utils.c +++ b/src/utils.c @@ -54,90 +54,30 @@ int safe_strcmp(const char *a, const char *b) } -static char *fgets_long(FILE *fh, size_t *lp) +int parse_double(const char *a, float v[2]) { - char *line; - size_t la; - size_t l = 0; - - la = 1024; - line = malloc(la); - if ( line == NULL ) return NULL; - - do { - - int r; - - r = fgetc(fh); - if ( r == EOF ) { - if ( l == 0 ) { - free(line); - *lp = 0; - return NULL; - } else { - line[l++] = '\0'; - *lp = l; - return line; - } - } - - line[l++] = r; - - if ( r == '\n' ) { - line[l++] = '\0'; - *lp = l; - return line; - } - - if ( l == la ) { + int nn; - char *ln; - - la += 1024; - ln = realloc(line, la); - if ( ln == NULL ) { - free(line); - *lp = 0; - return NULL; - } - - line = ln; - - } + nn = sscanf(a, "%fx%f", &v[0], &v[1]); + if ( nn != 2 ) { + fprintf(stderr, _("Invalid size '%s'\n"), a); + return 1; + } - } while ( 1 ); + return 0; } -char *load_everything(const char *filename) +int parse_tuple(const char *a, float v[4]) { - FILE *fh; - size_t el = 1; - char *everything = strdup(""); - - fh = fopen(filename, "r"); - if ( fh == NULL ) return NULL; - - while ( !feof(fh) ) { - - size_t len = 0; - char *line = fgets_long(fh, &len); - - if ( line != NULL ) { - - everything = realloc(everything, el+len); - if ( everything == NULL ) { - fprintf(stderr, _("Failed to allocate memory\n")); - return NULL; - } - el += len; - - strcat(everything, line); - } + int nn; + nn = sscanf(a, "%f,%f,%f,%f", &v[0], &v[1], &v[2], &v[3]); + if ( nn != 4 ) { + fprintf(stderr, _("Invalid tuple '%s'\n"), a); + return 1; } - fclose(fh); - - return everything; + return 0; } + diff --git a/src/utils.h b/src/utils.h index bfc04c2..fc843c3 100644 --- a/src/utils.h +++ b/src/utils.h @@ -30,7 +30,8 @@ extern void chomp(char *s); extern int safe_strcmp(const char *a, const char *b); -extern char *load_everything(const char *filename); +extern int parse_double(const char *a, float v[2]); +extern int parse_tuple(const char *a, float v[4]); #include <libintl.h> #define _(x) gettext(x) |