Merge branch 'master' of ssh://git.stderr.nl/projects/chimara/chimara
[projects/chimara/chimara.git] / libchimara / style.c
index cca361ca2dba0ef9cfb54898ca1d0add3d2a0f94..dc0d4bb942acb13d4e73ddbeeca3bac7131e1f4f 100644 (file)
@@ -239,9 +239,6 @@ style_init(ChimaraGlk *glk)
        GHashTable *glk_text_buffer_styles = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_object_unref);
        GtkTextTag *tag;
 
-       PangoFontDescription *default_font_desc = pango_font_description_from_string("Serif");
-       PangoFontDescription *monospace_font_desc = pango_font_description_from_string("Monospace");
-       
        /* Initialise the default styles for a text grid */
        tag = gtk_text_tag_new("default");
        g_object_set(tag, "family", "Monospace", "family-set", TRUE, NULL);
@@ -344,9 +341,6 @@ style_init(ChimaraGlk *glk)
        g_hash_table_insert(default_text_buffer_styles, "pager", pager_tag);
        text_tag_to_attr_list(pager_tag, priv->pager_attr_list);
 
-       pango_font_description_free(default_font_desc);
-       pango_font_description_free(monospace_font_desc);
-       
        priv->styles->text_grid = default_text_grid_styles;
        priv->styles->text_buffer = default_text_buffer_styles;
 
@@ -389,8 +383,6 @@ create_css_file_scanner(void)
 void
 scan_css_file(GScanner *scanner, ChimaraGlk *glk)
 {
-       CHIMARA_GLK_USE_PRIVATE(glk, priv);
-
        while( g_scanner_peek_next_token(scanner) != G_TOKEN_EOF) {
                if( !style_accept_style_selector(scanner, glk) )
                        break;
@@ -399,8 +391,7 @@ scan_css_file(GScanner *scanner, ChimaraGlk *glk)
        g_scanner_destroy(scanner);
 
        /* Update the pager prompt to the new style */
-       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);
+       style_update(glk);
 }
 
 /* Internal function: parses a token */
@@ -1106,21 +1097,45 @@ PangoFontDescription *
 get_current_font(guint32 wintype)
 {
        ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
-       GtkTextTag *tag;
+       GHashTable *styles, *glk_styles;
+       PangoFontDescription *font;
 
        switch(wintype) {
        case wintype_TextGrid:
-               tag = g_hash_table_lookup(glk_data->styles->text_grid, "default");
+               styles = glk_data->styles->text_grid;
+               glk_styles = glk_data->glk_styles->text_grid;
+               font = pango_font_description_from_string("Monospace");
                break;
        case wintype_TextBuffer:
-               tag = g_hash_table_lookup(glk_data->styles->text_buffer, "default");
+               styles = glk_data->styles->text_buffer;
+               glk_styles = glk_data->glk_styles->text_buffer;
+               font = pango_font_description_from_string("Serif");
                break;
        default:
                return NULL;
        }
 
-       PangoFontDescription *font;
-       g_object_get( G_OBJECT(tag), "font-desc", &font, NULL );
+       PangoAttrList *list = pango_attr_list_new();
+
+       text_tag_to_attr_list( g_hash_table_lookup(styles, "default"), list );
+       PangoAttrIterator *it = pango_attr_list_get_iterator(list);
+       pango_attr_iterator_get_font(it, font, NULL, NULL);
+       pango_attr_iterator_destroy(it);
+
+       text_tag_to_attr_list( g_hash_table_lookup(styles, "normal"), list );
+       it = pango_attr_list_get_iterator(list);
+       pango_attr_iterator_get_font(it, font, NULL, NULL);
+       pango_attr_iterator_destroy(it);
+
+       text_tag_to_attr_list( g_hash_table_lookup(glk_styles, "glk-normal"), list );
+       it = pango_attr_list_get_iterator(list);
+       pango_attr_iterator_get_font(it, font, NULL, NULL);
+       pango_attr_iterator_destroy(it);
+
+       /* Make a copy of the family, preventing it's destruction at the end of this function. */
+       pango_font_description_set_family( font, pango_font_description_get_family(font) );
+
+       pango_attr_list_unref(list);
 
        return font;
 }
@@ -1159,7 +1174,8 @@ text_tag_to_attr_list(GtkTextTag *tag, PangoAttrList *list)
        }
 
        /* Font description updates the following properties simultaniously:
-        * family, style, weight, variant, stretch, size
+        * family, style, weight, variant, stretch, size.
+        * FIXME: Except it doesn't really.
         */
        g_object_get(tag, "font-desc", &font_desc, NULL);
        pango_attr_list_insert(
@@ -1256,3 +1272,44 @@ style_stream_colors(strid_t str, GdkColor **foreground, GdkColor **background)
                        g_object_get(str->window->zcolor, "background-gdk", background, NULL);
        }
 }
+
+/* Apply styles to a segment of text in a GtkTextBuffer
+ */
+void
+style_apply(winid_t win, GtkTextIter *start, GtkTextIter *end)
+{
+       GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) );
+       GtkTextTagTable *tags = gtk_text_buffer_get_tag_table(buffer);
+
+       GtkTextTag *default_tag = gtk_text_tag_table_lookup(tags, "default");
+       GtkTextTag *style_tag = gtk_text_tag_table_lookup(tags, win->window_stream->style);
+       GtkTextTag *glk_style_tag = gtk_text_tag_table_lookup(tags, win->window_stream->glk_style);
+
+       // Player's style overrides
+       gtk_text_buffer_apply_tag(buffer, style_tag, start, end);
+
+       // GLK Program's style overrides
+       gtk_text_buffer_apply_tag(buffer, glk_style_tag, start, end);
+
+       // Default style
+       gtk_text_buffer_apply_tag(buffer, default_tag, start, end);
+
+       // Link style overrides
+       if(win->window_stream->hyperlink_mode) {
+               GtkTextTag *link_style_tag = gtk_text_tag_table_lookup(tags, "hyperlink");
+               GtkTextTag *link_tag = win->current_hyperlink->tag;
+               gtk_text_buffer_apply_tag(buffer, link_style_tag, start, end);
+               gtk_text_buffer_apply_tag(buffer, link_tag, start, end);
+       }
+
+       // GLK Program's style overrides using garglk_set_zcolors()
+       if(win->zcolor != NULL) {
+               gtk_text_buffer_apply_tag(buffer, win->zcolor, start, end);
+       }
+
+       // GLK Program's style overrides using garglk_set_reversevideo()
+       if(win->zcolor_reversed != NULL) {
+               gtk_text_buffer_apply_tag(buffer, win->zcolor_reversed, start, end);
+       }
+}
+