Frame option processing
authorThomas White <taw@bitwiz.org.uk>
Mon, 27 May 2013 07:29:00 +0000 (09:29 +0200)
committerThomas White <taw@bitwiz.org.uk>
Mon, 27 May 2013 07:29:00 +0000 (09:29 +0200)
Makefile.am
src/default_stylesheet.sty
src/frame.c
src/frame.h
src/presentation.c
src/stylesheet.c
src/stylesheet.h
tests/render_test_sc1.c

index 9171abb..f44b437 100644 (file)
@@ -38,8 +38,10 @@ noinst_PROGRAMS = tests/render_test tests/render_test_sc1
 TESTS = tests/render_test tests/render_test_sc1
 
 tests_render_test_SOURCES = tests/render_test.c src/render.c src/frame.c \
-                            src/wrap.c src/storycode.c src/imagestore.c
+                            src/wrap.c src/storycode.c src/imagestore.c \
+                            src/stylesheet.c src/loadsave.c
 
 tests_render_test_sc1_SOURCES = tests/render_test_sc1.c src/storycode.c \
                                 src/render.c src/frame.c src/wrap.c \
-                                src/imagestore.c
+                                src/imagestore.c src/stylesheet.c \
+                                src/loadsave.c
index 001b212..bdeffc4 100644 (file)
@@ -13,7 +13,7 @@ pad_l = 0.00
 pad_r = 0.00
 pad_t = 0.00
 pad_b = 0.00
-w = "1.00 fr"
+w = "1.00 f"
 h = "100.00 u"
 x = 0.0
 y = 300.0
@@ -29,7 +29,7 @@ pad_l = 20.00
 pad_r = 20.00
 pad_t = 20.00
 pad_b = 20.00
-w = "1.00 fr"
+w = "1.00 f"
 h = "100.00 u"
 x = 0.0
 y = 0.0
@@ -45,7 +45,7 @@ pad_l = 20.00
 pad_r = 20.00
 pad_t = 20.00
 pad_b = 20.00
-w = "1.00 fr"
+w = "1.00 f"
 h = "100.00 u"
 x = 0.0
 y = 0.0
@@ -61,8 +61,8 @@ pad_l = 20.00
 pad_r = 20.00
 pad_t = 20.00
 pad_b = 20.00
-w = "1.00 fr"
-h = "1.00 fr"
+w = "1.00 f"
+h = "1.00 f"
 x = 0.0
 y = 0.0
 prologue = "\bgcol{#ffffff}\fgcol{#000000}\font[Sans 24]"
index e25b64f..4c23efd 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "storycode.h"
 #include "frame.h"
+#include "stylesheet.h"
 
 
 static int alloc_ro(struct frame *fr)
@@ -86,10 +87,20 @@ struct frame *add_subframe(struct frame *fr)
 }
 
 
-static void parse_option(struct frame *fr, const char *opt)
+static LengthUnits get_units(const char *t)
 {
-       printf("Option '%s'\n", opt);
+       size_t len = strlen(t);
 
+       if ( t[len-1] == 'f' ) return UNITS_FRAC;
+       if ( t[len-1] == 'u' ) return UNITS_SLIDE;
+
+       fprintf(stderr, "Invalid units in '%s'\n", t);
+       return UNITS_SLIDE;
+}
+
+
+static void parse_option(struct frame *fr, const char *opt, StyleSheet *ss)
+{
        if ( (index(opt, 'x') != NULL) && (index(opt, '+') != NULL)
          && (index(opt, '+') != rindex(opt, '+')) )
        {
@@ -97,6 +108,7 @@ static void parse_option(struct frame *fr, const char *opt)
                char *h;
                char *x;
                char *y;
+               char *check;
 
                /* Looks like a dimension/position thing */
                w = strdup(opt);
@@ -117,26 +129,68 @@ static void parse_option(struct frame *fr, const char *opt)
                }
                y[0] = '\0';  y++;
 
-               printf("'%s' x '%s' + '%s' + '%s'\n", w, h, x, y);
-               /* FIXME: Parse length/unit couples */
-               /* FIXME: Turn x and y into numbers */
+               fr->lop.w = strtod(w, &check);
+               if ( check == w ) {
+                       fprintf(stderr, "Invalid option '%s'\n", opt);
+                       return;
+               }
+               fr->lop.w_units = get_units(w);
+
+               fr->lop.h = strtod(h, &check);
+               if ( check == h ) {
+                       fprintf(stderr, "Invalid option '%s'\n", opt);
+                       return;
+               }
+               fr->lop.h_units = get_units(h);
+
+               fr->lop.x = strtod(x, &check);
+               if ( check == x ) {
+                       fprintf(stderr, "Invalid option '%s'\n", opt);
+                       return;
+               }
+               fr->lop.y = strtod(y, &check);
+               if ( check == y ) {
+                       fprintf(stderr, "Invalid option '%s'\n", opt);
+                       return;
+               }
 
-               free(w);
        }
 
-       /* FIXME: Handle styles */
+       if ( strncmp(opt, "style=", 6) == 0 ) {
+               char *s;
+               int sn;
+               char *check;
+
+               if ( opt[strlen(opt)-1] == '*' ) {
+                       fr->lop_from_style = 1;
+               } else {
+                       fr->lop_from_style = 0;
+               }
+
+               s = index(opt, '=');
+               s++;
+               sn = strtol(s, &check, 10);
+               if ( check == s ) {
+                       fprintf(stderr, "Invalid style number '%s'\n", opt);
+                       return;
+               }
+
+               fr->style = lookup_style(ss, sn);
+               if ( fr->style == NULL ) {
+                       fprintf(stderr, "Invalid style number '%s'\n", opt);
+                       return;
+               }
+       }
 }
 
 
-static void parse_options(struct frame *fr, const char *opth)
+static void parse_options(struct frame *fr, const char *opth, StyleSheet *ss)
 {
        int i;
        size_t len;
        size_t start;
        char *opt = strdup(opth);
 
-       printf("Processing options '%s'\n", opt);
-
        len = strlen(opt);
        start = 0;
 
@@ -145,22 +199,21 @@ static void parse_options(struct frame *fr, const char *opth)
                /* FIXME: comma might be escaped or quoted */
                if ( opt[i] == ',' ) {
                        opt[i] = '\0';
-                       parse_option(fr, opt+start);
+                       parse_option(fr, opt+start, ss);
                        start = i+1;
                }
 
        }
 
        if ( start != len ) {
-               parse_option(fr, opt+start);
+               parse_option(fr, opt+start, ss);
        }
 
        free(opt);
-       printf("Done.\n");
 }
 
 
-static int recursive_unpack(struct frame *fr, const char *sc)
+static int recursive_unpack(struct frame *fr, const char *sc, StyleSheet *ss)
 {
        SCBlockList *bl;
        SCBlockListIterator *iter;
@@ -176,10 +229,10 @@ static int recursive_unpack(struct frame *fr, const char *sc)
                struct frame *sfr;
 
                sfr = add_subframe(fr);
-               parse_options(sfr, b->options);
+               parse_options(sfr, b->options, ss);
 
                sfr->sc = remove_blocks(b->contents, "f");
-               if ( recursive_unpack(sfr, b->contents) ) {
+               if ( recursive_unpack(sfr, b->contents, ss) ) {
                        sc_block_list_free(bl);
                        return 1;
                }
@@ -191,7 +244,7 @@ static int recursive_unpack(struct frame *fr, const char *sc)
 
 
 /* Unpack level 2 StoryCode (content + subframes) into frames */
-struct frame *sc_unpack(const char *sc)
+struct frame *sc_unpack(const char *sc, StyleSheet *ss)
 {
        struct frame *fr;
 
@@ -199,7 +252,7 @@ struct frame *sc_unpack(const char *sc)
        if ( fr == NULL ) return NULL;
 
        fr->sc = remove_blocks(sc, "f");
-       if ( recursive_unpack(fr, sc) ) {
+       if ( recursive_unpack(fr, sc, ss) ) {
                return NULL;
        }
 
index 4762b77..c760162 100644 (file)
@@ -30,6 +30,8 @@
 #include <pango/pango.h>
 #include <cairo.h>
 
+typedef struct _stylesheet StyleSheet;
+
 
 typedef enum
 {
@@ -114,7 +116,7 @@ struct frame
 
 extern struct frame *frame_new(void);
 extern struct frame *add_subframe(struct frame *fr);
-extern struct frame *sc_unpack(const char *sc);
+extern struct frame *sc_unpack(const char *sc, StyleSheet *ss);
 extern void show_hierarchy(struct frame *fr, const char *t);
 
 #endif /* FRAME_H */
index c6a4cf7..35b2d8f 100644 (file)
@@ -265,6 +265,29 @@ static char *maybe_star(int i)
 }
 
 
+static char *frame_options_string(struct frame *fr, StyleSheet *ss)
+{
+       char *opt;
+
+       opt = malloc(64);
+       if ( opt == NULL ) return NULL;
+
+       snprintf(opt, 31, "style=%i%s",
+                style_number(ss, fr->style), maybe_star(fr->lop_from_style));
+
+       if ( !fr->lop_from_style ) {
+               char tmp[32];
+               snprintf(tmp, 31, ",%.1f%sx%.1f%s+%.1f+%.1f",
+                                fr->lop.w, units(fr->lop.w_units),
+                                fr->lop.h, units(fr->lop.h_units),
+                                fr->lop.x, fr->lop.y);
+               strcat(opt, tmp);
+       }
+
+       return opt;
+}
+
+
 static char *packed_sc(struct frame *fr, StyleSheet *ss)
 {
        char *sc;
@@ -286,22 +309,16 @@ static char *packed_sc(struct frame *fr, StyleSheet *ss)
                char *ch_sc;
                char *scn;
                size_t ch_len;
+               char *frame_opts;
 
                ch_sc = packed_sc(fr->children[i], ss);
                ch_len = strlen(ch_sc);
 
+               frame_opts = frame_options_string(fr->children[i], ss);
+
                len += ch_len + 64;
                scn = malloc(len + ch_len);
-               snprintf(scn, len,
-                        "%s\\f[%.1f%sx%.1f%s+%.1f+%.1f,style=%i%s]{%s}", sc,
-                        fr->children[i]->lop.w,
-                        units(fr->children[i]->lop.w_units),
-                        fr->children[i]->lop.h,
-                        units(fr->children[i]->lop.h_units),
-                        fr->children[i]->lop.x, fr->children[i]->lop.y,
-                        style_number(ss, fr->children[i]->style),
-                        maybe_star(fr->children[i]->lop_from_style),
-                        ch_sc);
+               snprintf(scn, len, "%s\\f[%s]{%s}", sc, frame_opts, ch_sc);
                free(ch_sc);
                free(sc);
                sc = scn;
@@ -383,7 +400,7 @@ static struct slide *tree_to_slide(struct presentation *p, struct ds_node *root)
        s->parent = p;
 
        get_field_s(root, "sc", &sc);
-       s->top = sc_unpack(sc);
+       s->top = sc_unpack(sc, p->ss);
        free(sc);
 
        return s;
index f4b7c39..18a55b2 100644 (file)
@@ -81,6 +81,14 @@ struct style *new_style(StyleSheet *ss, const char *name)
 }
 
 
+struct style *lookup_style(StyleSheet *ss, int n)
+{
+       if ( n < 0 ) return NULL;
+       if ( n >= ss->n_styles ) return NULL;
+       return ss->styles[n];
+}
+
+
 void free_stylesheet(StyleSheet *ss)
 {
        int i;
@@ -152,7 +160,7 @@ static void get_field_f_units(struct ds_node *root, const char *key,
                return;
        }
 
-       if ( strcmp(u, "fr") == 0 ) *units = UNITS_FRAC;
+       if ( strcmp(u, "f") == 0 ) *units = UNITS_FRAC;
        else if ( strcmp(u, "u") == 0 ) *units = UNITS_SLIDE;
        else {
                fprintf(stderr, "Invalid unit '%s'\n", u);
@@ -353,7 +361,7 @@ const char *units(LengthUnits un)
 {
        switch ( un ) {
                case UNITS_SLIDE : return "u";
-               case UNITS_FRAC : return "fr";
+               case UNITS_FRAC : return "f";
        }
        return "annoyingly unspecified units";
 }
index b7dc210..cea714b 100644 (file)
@@ -64,6 +64,7 @@ extern StyleSheet *default_stylesheet(void);
 
 extern struct style *new_style(StyleSheet *ss, const char *name);
 extern struct style *default_style(StyleSheet *ss);
+extern struct style *lookup_style(StyleSheet *ss, int n);
 
 extern struct slide_template *new_template(StyleSheet *ss, const char *name);
 extern void add_to_template(struct slide_template *t, struct style *sty);
index e1b6f00..843ac2b 100644 (file)
@@ -76,7 +76,7 @@ int main(int argc, char *argv[])
 
        gtk_init(&argc, &argv);
 
-       fr = sc_unpack("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. \\f{\\bgcol{#ff00ff}Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros.} Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.");
+       fr = sc_unpack("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. \\f{\\bgcol{#ff00ff}Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros.} Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.", NULL);
 
        if ( fr == NULL ) {
                fprintf(stderr, "sc_unpack() failed.\n");