Fixed ordering of the application of the styles
[rodin/chimara.git] / libchimara / style.c
index f31f2d660943d0d04b455e0e8b38cce8ea7b33c5..9fc6b1e499fe38a907b182f9988c08fce0515221 100644 (file)
@@ -38,7 +38,7 @@ glk_set_style(glui32 styl)
        glk_set_style_stream(glk_data->current_stream, styl);
 }
 
-#define NUM_STYLES 13
+/* The first 11 tag names must correspond to the first 11 glk tag names as defined below */
 static const gchar* TAG_NAMES[] = {
        "normal",
        "emphasized",
@@ -52,9 +52,11 @@ static const gchar* TAG_NAMES[] = {
        "user1",
        "user2",
        "hyperlink",
-       "pager"
+       "pager",
+       "default"
 };
 
+/* The first 11 glk tag names must correspond to the first 11 tag names as defined above */
 static const gchar* GLK_TAG_NAMES[] = {
        "glk-normal",
        "glk-emphasized",
@@ -69,11 +71,17 @@ static const gchar* GLK_TAG_NAMES[] = {
        "glk-user2"
 };
 
+const gchar**
+style_get_tag_names()
+{
+       return TAG_NAMES;
+}
+
 /* Internal function: mapping from style enum to tag name */
-static gchar*
+static const gchar*
 get_tag_name(glui32 style)
 {
-       if(style >= NUM_STYLES) {
+       if(style >= CHIMARA_NUM_STYLES) {
                WARNING("Unsupported style");
                return "normal";
        } else {
@@ -82,7 +90,7 @@ get_tag_name(glui32 style)
 }
 
 /* Internal function: mapping from glk style enum to tag name */
-static gchar*
+static const gchar*
 get_glk_tag_name(glui32 style)
 {
        if(style >= style_NUMSTYLES) {
@@ -106,8 +114,8 @@ glk_set_style_stream(strid_t str, glui32 styl) {
                return;
 
        flush_window_buffer(str->window);
-       str->style = get_tag_name(styl);
-       str->glk_style = get_glk_tag_name(styl);
+       str->style = (gchar*) get_tag_name(styl);
+       str->glk_style = (gchar*) get_glk_tag_name(styl);
 }
 
 /* Internal function: call this to initialize the layout of the 'more' prompt. */
@@ -233,12 +241,17 @@ style_init(ChimaraGlk *glk)
        PangoFontDescription *monospace_font_desc = pango_font_description_from_string("Monospace");
        
        /* Initialise the default styles for a text grid */
-       tag = gtk_text_tag_new("normal");
+       tag = gtk_text_tag_new("default");
        g_object_set(tag, "font-desc", monospace_font_desc, NULL);
+       g_hash_table_insert(default_text_grid_styles, "default", tag);
+
+       tag = gtk_text_tag_new("normal");
+       //g_object_set(tag, "font-desc", monospace_font_desc, NULL);
        g_hash_table_insert(default_text_grid_styles, "normal", tag);
 
        tag = gtk_text_tag_new("emphasized");
-       g_object_set(tag, "font-desc", monospace_font_desc, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL);
+       //g_object_set(tag, "font-desc", monospace_font_desc, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL);
+       g_object_set(tag, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL);
        g_hash_table_insert(default_text_grid_styles, "emphasized", tag);
 
        tag = gtk_text_tag_new("preformatted");
@@ -246,35 +259,40 @@ style_init(ChimaraGlk *glk)
        g_hash_table_insert(default_text_grid_styles, "preformatted", tag);
 
        tag = gtk_text_tag_new("header");
-       g_object_set(tag, "font-desc", monospace_font_desc, "weight", PANGO_WEIGHT_BOLD, NULL);
+       //g_object_set(tag, "font-desc", monospace_font_desc, "weight", PANGO_WEIGHT_BOLD, NULL);
+       g_object_set(tag, "weight", PANGO_WEIGHT_BOLD, NULL);
        g_hash_table_insert(default_text_grid_styles, "header", tag);
 
        tag = gtk_text_tag_new("subheader");
-       g_object_set(tag, "font-desc", monospace_font_desc, "weight", PANGO_WEIGHT_BOLD, NULL);
+       //g_object_set(tag, "font-desc", monospace_font_desc, "weight", PANGO_WEIGHT_BOLD, NULL);
+       g_object_set(tag, "weight", PANGO_WEIGHT_BOLD, NULL);
        g_hash_table_insert(default_text_grid_styles, "subheader", tag);
 
        tag = gtk_text_tag_new("alert");
-       g_object_set(tag, "font-desc", monospace_font_desc, "foreground", "#aa0000", "weight", PANGO_WEIGHT_BOLD, NULL);
+       //g_object_set(tag, "font-desc", monospace_font_desc, "foreground", "#aa0000", "weight", PANGO_WEIGHT_BOLD, NULL);
+       g_object_set(tag, "foreground", "#aa0000", "weight", PANGO_WEIGHT_BOLD, NULL);
        g_hash_table_insert(default_text_grid_styles, "alert", tag);
 
        tag = gtk_text_tag_new("note");
-       g_object_set(tag, "font-desc", monospace_font_desc, "foreground", "#aaaa00", "weight", PANGO_WEIGHT_BOLD, NULL);
+       //g_object_set(tag, "font-desc", monospace_font_desc, "foreground", "#aaaa00", "weight", PANGO_WEIGHT_BOLD, NULL);
+       g_object_set(tag, "foreground", "#aaaa00", "weight", PANGO_WEIGHT_BOLD, NULL);
        g_hash_table_insert(default_text_grid_styles, "note", tag);
 
        tag = gtk_text_tag_new("block-quote");
-       g_object_set(tag, "font-desc", monospace_font_desc, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL);
+       //g_object_set(tag, "font-desc", monospace_font_desc, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL);
+       g_object_set(tag, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL);
        g_hash_table_insert(default_text_grid_styles, "block-quote", tag);
 
        tag = gtk_text_tag_new("input");
-       g_object_set(tag, "font-desc", monospace_font_desc, NULL);
+       //g_object_set(tag, "font-desc", monospace_font_desc, NULL);
        g_hash_table_insert(default_text_grid_styles, "input", tag);
 
        tag = gtk_text_tag_new("user1");
-       g_object_set(tag, "font-desc", monospace_font_desc, NULL);
+       //g_object_set(tag, "font-desc", monospace_font_desc, NULL);
        g_hash_table_insert(default_text_grid_styles, "user1", tag);
 
        tag = gtk_text_tag_new("user2");
-       g_object_set(tag, "font-desc", monospace_font_desc, NULL);
+       //g_object_set(tag, "font-desc", monospace_font_desc, NULL);
        g_hash_table_insert(default_text_grid_styles, "user2", tag);
 
        tag = gtk_text_tag_new("hyperlink");
@@ -282,12 +300,17 @@ style_init(ChimaraGlk *glk)
        g_hash_table_insert(default_text_grid_styles, "hyperlink", tag);
 
        /* Initialise the default styles for a text buffer */
-       tag = gtk_text_tag_new("normal");
+       tag = gtk_text_tag_new("default");
        g_object_set(tag, "font-desc", default_font_desc, NULL);
+       g_hash_table_insert(default_text_buffer_styles, "default", tag);
+
+       tag = gtk_text_tag_new("normal");
+       //g_object_set(tag, "font-desc", default_font_desc, NULL);
        g_hash_table_insert(default_text_buffer_styles, "normal", tag);
 
        tag = gtk_text_tag_new("emphasized");
-       g_object_set(tag, "font-desc", default_font_desc, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL);
+       //g_object_set(tag, "font-desc", default_font_desc, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL);
+       g_object_set(tag, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL);
        g_hash_table_insert(default_text_buffer_styles, "emphasized", tag);
 
        tag = gtk_text_tag_new("preformatted");
@@ -295,39 +318,45 @@ style_init(ChimaraGlk *glk)
        g_hash_table_insert(default_text_buffer_styles, "preformatted", tag);
 
        tag = gtk_text_tag_new("header");
-       g_object_set(tag, "font-desc", default_font_desc, "size-points", 18.0, "weight", PANGO_WEIGHT_BOLD, NULL);
+       //g_object_set(tag, "font-desc", default_font_desc, "size-points", 18.0, "weight", PANGO_WEIGHT_BOLD, NULL);
+       g_object_set(tag, "size-points", 18.0, "weight", PANGO_WEIGHT_BOLD, NULL);
        g_hash_table_insert(default_text_buffer_styles, "header", tag);
 
        tag = gtk_text_tag_new("subheader");
-       g_object_set(tag, "font-desc", default_font_desc, "size-points", 14.0, "weight", PANGO_WEIGHT_BOLD, NULL);
+       //g_object_set(tag, "font-desc", default_font_desc, "size-points", 14.0, "weight", PANGO_WEIGHT_BOLD, NULL);
+       g_object_set(tag, "size-points", 14.0, "weight", PANGO_WEIGHT_BOLD, NULL);
        g_hash_table_insert(default_text_buffer_styles, "subheader", tag);
 
        tag = gtk_text_tag_new("alert");
-       g_object_set(tag, "font-desc", default_font_desc, "foreground", "#aa0000", "weight", PANGO_WEIGHT_BOLD, NULL);
+       //g_object_set(tag, "font-desc", default_font_desc, "foreground", "#aa0000", "weight", PANGO_WEIGHT_BOLD, NULL);
+       g_object_set(tag, "foreground", "#aa0000", "weight", PANGO_WEIGHT_BOLD, NULL);
        g_hash_table_insert(default_text_buffer_styles, "alert", tag);
 
        tag = gtk_text_tag_new("note");
-       g_object_set(tag, "font-desc", default_font_desc, "foreground", "#aaaa00", "weight", PANGO_WEIGHT_BOLD, NULL);
+       //g_object_set(tag, "font-desc", default_font_desc, "foreground", "#aaaa00", "weight", PANGO_WEIGHT_BOLD, NULL);
+       g_object_set(tag, "foreground", "#aaaa00", "weight", PANGO_WEIGHT_BOLD, NULL);
        g_hash_table_insert(default_text_buffer_styles, "note", tag);
 
        tag = gtk_text_tag_new("block-quote");
-       g_object_set(tag, "font-desc", default_font_desc, "justification", GTK_JUSTIFY_CENTER, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL);
+       //g_object_set(tag, "font-desc", default_font_desc, "justification", GTK_JUSTIFY_CENTER, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL);
+       g_object_set(tag, "justification", GTK_JUSTIFY_CENTER, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL);
        g_hash_table_insert(default_text_buffer_styles, "block-quote", tag);
 
        tag = gtk_text_tag_new("input");
-       g_object_set(tag, "font-desc", default_font_desc, NULL);
+       //g_object_set(tag, "font-desc", default_font_desc, NULL);
        g_hash_table_insert(default_text_buffer_styles, "input", tag);
 
        tag = gtk_text_tag_new("user1");
-       g_object_set(tag, "font-desc", default_font_desc, NULL);
+       //g_object_set(tag, "font-desc", default_font_desc, NULL);
        g_hash_table_insert(default_text_buffer_styles, "user1", tag);
 
        tag = gtk_text_tag_new("user2");
-       g_object_set(tag, "font-desc", default_font_desc, NULL);
+       //g_object_set(tag, "font-desc", default_font_desc, NULL);
        g_hash_table_insert(default_text_buffer_styles, "user2", tag);
 
        tag = gtk_text_tag_new("hyperlink");
-       g_object_set(tag, "font-desc", default_font_desc, "foreground", "#0000ff", "underline", PANGO_UNDERLINE_SINGLE, "underline-set", TRUE, NULL);
+       //g_object_set(tag, "font-desc", default_font_desc, "foreground", "#0000ff", "underline", PANGO_UNDERLINE_SINGLE, "underline-set", TRUE, NULL);
+       g_object_set(tag, "foreground", "#0000ff", "underline", PANGO_UNDERLINE_SINGLE, "underline-set", TRUE, NULL);
        g_hash_table_insert(default_text_buffer_styles, "hyperlink", tag);
 
        GtkTextTag *pager_tag = gtk_text_tag_new("pager");
@@ -441,29 +470,38 @@ style_accept_style_selector(GScanner *scanner, ChimaraGlk *glk)
 
        field = g_strdup(value.v_identifier);
 
-       if( !style_accept(scanner, '.') )
-               return FALSE;
+       /* Parse the tag name to change */
+       if( g_scanner_peek_next_token(scanner) == '{') {
+               style_accept(scanner, '{');
+               if( !strcmp(field, "buffer") )
+                       current_tag = g_hash_table_lookup(priv->styles->text_buffer, "default");
+               else
+                       current_tag = g_hash_table_lookup(priv->styles->text_grid, "default");
+       } else {
+               if( !style_accept(scanner, '.') )
+                       return FALSE;
 
-       token = g_scanner_get_next_token(scanner);
-       value = g_scanner_cur_value(scanner);
+               token = g_scanner_get_next_token(scanner);
+               value = g_scanner_cur_value(scanner);
 
-       if(token != G_TOKEN_IDENTIFIER) {
-               g_scanner_error(scanner, "CSS Error: style selector expected");
-               return FALSE;
-       }
+               if(token != G_TOKEN_IDENTIFIER) {
+                       g_scanner_error(scanner, "CSS Error: style selector expected");
+                       return FALSE;
+               }
 
-       if( !strcmp(field, "buffer") )
-               current_tag = g_hash_table_lookup(priv->styles->text_buffer, value.v_identifier);
-       else
-               current_tag = g_hash_table_lookup(priv->styles->text_grid, value.v_identifier);
+               if( !strcmp(field, "buffer") )
+                       current_tag = g_hash_table_lookup(priv->styles->text_buffer, value.v_identifier);
+               else
+                       current_tag = g_hash_table_lookup(priv->styles->text_grid, value.v_identifier);
 
-       if(current_tag == NULL) {
-               g_scanner_error(scanner, "CSS Error: invalid style identifier");
-               return FALSE;
-       }
+               if(current_tag == NULL) {
+                       g_scanner_error(scanner, "CSS Error: invalid style identifier");
+                       return FALSE;
+               }
 
-       if( !style_accept(scanner, '{') )
-               return FALSE;
+               if( !style_accept(scanner, '{') )
+                       return FALSE;
+       }
 
        while( g_scanner_peek_next_token(scanner) != '}') {
                if( !style_accept_style_hint(scanner, current_tag) )
@@ -907,12 +945,16 @@ glk_stylehint_clear(glui32 wintype, glui32 styl, glui32 hint)
 
        switch(wintype) {
        case wintype_TextBuffer:
-               tag = g_hash_table_lookup( glk_data->styles->text_buffer, get_glk_tag_name(styl) );
-               glk_stylehint_set( wintype, styl, hint, query_tag(tag, wintype, hint) );
+               tag = g_hash_table_lookup( glk_data->glk_styles->text_buffer, get_glk_tag_name(styl) );
+               if(tag) {
+                       glk_stylehint_set( wintype, styl, hint, query_tag(tag, wintype, hint) );
+               }
                break;
        case wintype_TextGrid:
-               tag = g_hash_table_lookup( glk_data->styles->text_grid, get_glk_tag_name(styl) );
-               glk_stylehint_set( wintype, styl, hint, query_tag(tag, wintype, hint) );
+               tag = g_hash_table_lookup( glk_data->glk_styles->text_grid, get_glk_tag_name(styl) );
+               if(tag) {
+                       glk_stylehint_set( wintype, styl, hint, query_tag(tag, wintype, hint) );
+               }
        default:
                return;
        }
@@ -1116,3 +1158,13 @@ text_tag_to_attr_list(GtkTextTag *tag, PangoAttrList *list)
                );
        }
 }
+
+/* Update pager and reverse video tags */
+void
+style_update(ChimaraGlk *glk)
+{
+       CHIMARA_GLK_USE_PRIVATE(glk, priv);
+
+       GtkTextTag *pager_tag = GTK_TEXT_TAG( g_hash_table_lookup(priv->styles->text_buffer, "pager") );
+       text_tag_to_attr_list(pager_tag, priv->pager_attr_list);
+}