Port st-theme-context.[ch] to eek-theme-context.[ch].
This commit is contained in:
		@ -47,7 +47,8 @@ libeek_private_headers =			\
 | 
			
		||||
	$(srcdir)/eek-special-keysym-entries.h	\
 | 
			
		||||
	$(srcdir)/eek-unicode-keysym-entries.h	\
 | 
			
		||||
	$(srcdir)/eek-xkeysym-keysym-entries.h	\
 | 
			
		||||
	$(srcdir)/eek-marshalers.h \
 | 
			
		||||
	$(srcdir)/eek-marshalers.h		\
 | 
			
		||||
	$(srcdir)/eek-theme-context.h		\
 | 
			
		||||
	$(srcdir)/eek-theme-node.h
 | 
			
		||||
 | 
			
		||||
libeek_sources =				\
 | 
			
		||||
@ -66,6 +67,7 @@ libeek_sources =				\
 | 
			
		||||
	$(srcdir)/eek-renderer.c		\
 | 
			
		||||
	$(srcdir)/eek-keyboard-drawing.c	\
 | 
			
		||||
	$(srcdir)/eek-theme.c			\
 | 
			
		||||
	$(srcdir)/eek-theme-context.c		\
 | 
			
		||||
	$(srcdir)/eek-theme-node.c
 | 
			
		||||
 | 
			
		||||
libeek_keysym_sources =				\
 | 
			
		||||
 | 
			
		||||
@ -1256,6 +1256,7 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct _CreateThemeNodeData {
 | 
			
		||||
    EekThemeContext *context;
 | 
			
		||||
    EekThemeNode *parent;
 | 
			
		||||
    EekRenderer *renderer;
 | 
			
		||||
};
 | 
			
		||||
@ -1263,7 +1264,7 @@ typedef struct _CreateThemeNodeData CreateThemeNodeData;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
create_theme_node_key_callback (EekElement *element,
 | 
			
		||||
                                    gpointer    user_data)
 | 
			
		||||
                                gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
    CreateThemeNodeData *data = user_data;
 | 
			
		||||
    EekRendererPrivate *priv;
 | 
			
		||||
@ -1271,7 +1272,8 @@ create_theme_node_key_callback (EekElement *element,
 | 
			
		||||
 | 
			
		||||
    priv = EEK_RENDERER_GET_PRIVATE(data->renderer);
 | 
			
		||||
 | 
			
		||||
    theme_node = eek_theme_node_new (data->parent,
 | 
			
		||||
    theme_node = eek_theme_node_new (data->context,
 | 
			
		||||
                                     data->parent,
 | 
			
		||||
                                     priv->theme,
 | 
			
		||||
                                     EEK_TYPE_KEY,
 | 
			
		||||
                                     eek_element_get_name (element),
 | 
			
		||||
@ -1283,7 +1285,8 @@ create_theme_node_key_callback (EekElement *element,
 | 
			
		||||
                            theme_node,
 | 
			
		||||
                            (GDestroyNotify)g_object_unref);
 | 
			
		||||
 | 
			
		||||
    theme_node = eek_theme_node_new (data->parent,
 | 
			
		||||
    theme_node = eek_theme_node_new (data->context,
 | 
			
		||||
                                     data->parent,
 | 
			
		||||
                                     priv->theme,
 | 
			
		||||
                                     EEK_TYPE_KEY,
 | 
			
		||||
                                     eek_element_get_name (element),
 | 
			
		||||
@ -1306,7 +1309,8 @@ create_theme_node_section_callback (EekElement *element,
 | 
			
		||||
 | 
			
		||||
    priv = EEK_RENDERER_GET_PRIVATE(data->renderer);
 | 
			
		||||
 | 
			
		||||
    theme_node = eek_theme_node_new (data->parent,
 | 
			
		||||
    theme_node = eek_theme_node_new (data->context,
 | 
			
		||||
                                     data->parent,
 | 
			
		||||
                                     priv->theme,
 | 
			
		||||
                                     EEK_TYPE_SECTION,
 | 
			
		||||
                                     eek_element_get_name (element),
 | 
			
		||||
@ -1331,6 +1335,7 @@ eek_renderer_set_theme (EekRenderer *renderer,
 | 
			
		||||
                        EekTheme    *theme)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv;
 | 
			
		||||
    EekThemeContext *theme_context;
 | 
			
		||||
    EekThemeNode *theme_node;
 | 
			
		||||
    CreateThemeNodeData data;
 | 
			
		||||
 | 
			
		||||
@ -1344,7 +1349,9 @@ eek_renderer_set_theme (EekRenderer *renderer,
 | 
			
		||||
        g_object_unref (priv->theme);
 | 
			
		||||
    priv->theme = g_object_ref (theme);
 | 
			
		||||
 | 
			
		||||
    theme_node = eek_theme_node_new (NULL,
 | 
			
		||||
    theme_context = eek_theme_context_new ();
 | 
			
		||||
    theme_node = eek_theme_node_new (theme_context,
 | 
			
		||||
                                     NULL,
 | 
			
		||||
                                     priv->theme,
 | 
			
		||||
                                     EEK_TYPE_KEYBOARD,
 | 
			
		||||
                                     "keyboard",
 | 
			
		||||
@ -1356,6 +1363,7 @@ eek_renderer_set_theme (EekRenderer *renderer,
 | 
			
		||||
                            theme_node,
 | 
			
		||||
                            (GDestroyNotify)g_object_unref);
 | 
			
		||||
 | 
			
		||||
    data.context = theme_context;
 | 
			
		||||
    data.parent = theme_node;
 | 
			
		||||
    data.renderer = renderer;
 | 
			
		||||
    eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
#include "eek-theme.h"
 | 
			
		||||
#include "eek-theme-context.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										288
									
								
								eek/eek-theme-context.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										288
									
								
								eek/eek-theme-context.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,288 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * eek-theme-context.c: holds global information about a tree of styled objects
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2009, 2010 Red Hat, Inc.
 | 
			
		||||
 * Copyright 2009 Florian Müllner
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 2.1 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-theme.h"
 | 
			
		||||
#include "eek-theme-context.h"
 | 
			
		||||
 | 
			
		||||
struct _EekThemeContext {
 | 
			
		||||
  GObject parent;
 | 
			
		||||
 | 
			
		||||
  double resolution;
 | 
			
		||||
  PangoFontDescription *font;
 | 
			
		||||
  EekThemeNode *root_node;
 | 
			
		||||
  EekTheme *theme;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekThemeContextClass {
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_RESOLUTION 96.
 | 
			
		||||
#define DEFAULT_FONT "sans-serif 10"
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  CHANGED,
 | 
			
		||||
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekThemeContext, eek_theme_context, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_theme_context_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  EekThemeContext *context = EEK_THEME_CONTEXT (object);
 | 
			
		||||
 | 
			
		||||
  if (context->root_node)
 | 
			
		||||
    g_object_unref (context->root_node);
 | 
			
		||||
  if (context->theme)
 | 
			
		||||
    g_object_unref (context->theme);
 | 
			
		||||
 | 
			
		||||
  pango_font_description_free (context->font);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (eek_theme_context_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_theme_context_class_init (EekThemeContextClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->finalize = eek_theme_context_finalize;
 | 
			
		||||
 | 
			
		||||
  signals[CHANGED] =
 | 
			
		||||
    g_signal_new ("changed",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0, /* no default handler slot */
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_theme_context_init (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  context->resolution = DEFAULT_RESOLUTION;
 | 
			
		||||
  context->font = pango_font_description_from_string (DEFAULT_FONT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_new:
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new theme context.
 | 
			
		||||
 */
 | 
			
		||||
EekThemeContext *
 | 
			
		||||
eek_theme_context_new (void)
 | 
			
		||||
{
 | 
			
		||||
  EekThemeContext *context;
 | 
			
		||||
 | 
			
		||||
  context = g_object_new (EEK_TYPE_THEME_CONTEXT, NULL);
 | 
			
		||||
 | 
			
		||||
  return context;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_theme_context_changed (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  EekThemeNode *old_root = context->root_node;
 | 
			
		||||
  context->root_node = NULL;
 | 
			
		||||
 | 
			
		||||
  g_signal_emit (context, signals[CHANGED], 0);
 | 
			
		||||
 | 
			
		||||
  if (old_root)
 | 
			
		||||
    g_object_unref (old_root);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_set_theme:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the default set of theme stylesheets for the context. This theme will
 | 
			
		||||
 * be used for the root node and for nodes descending from it, unless some other
 | 
			
		||||
 * style is explicitely specified.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_theme_context_set_theme (EekThemeContext          *context,
 | 
			
		||||
                            EekTheme                 *theme)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
			
		||||
  g_return_if_fail (theme == NULL || EEK_IS_THEME (theme));
 | 
			
		||||
 | 
			
		||||
  if (context->theme != theme)
 | 
			
		||||
    {
 | 
			
		||||
      if (context->theme)
 | 
			
		||||
        g_object_unref (context->theme);
 | 
			
		||||
 | 
			
		||||
      context->theme = theme;
 | 
			
		||||
 | 
			
		||||
      if (context->theme)
 | 
			
		||||
        g_object_ref (context->theme);
 | 
			
		||||
 | 
			
		||||
      eek_theme_context_changed (context);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_get_theme:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the default theme for the context. See eek_theme_context_set_theme()
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): the default theme for the context
 | 
			
		||||
 */
 | 
			
		||||
EekTheme *
 | 
			
		||||
eek_theme_context_get_theme (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), NULL);
 | 
			
		||||
 | 
			
		||||
  return context->theme;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_set_resolution:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 * @resolution: resolution of the context (number of pixels in an "inch")
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the resolution of the theme context. This is the scale factor
 | 
			
		||||
 * used to convert between points and the length units pt, in, and cm.
 | 
			
		||||
 * This does not necessarily need to correspond to the actual number
 | 
			
		||||
 * resolution of the device. A value of 72. means that points and
 | 
			
		||||
 * pixels are identical. The default value is 96.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_theme_context_set_resolution (EekThemeContext *context,
 | 
			
		||||
                                 double          resolution)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
			
		||||
 | 
			
		||||
  if (resolution == context->resolution)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  context->resolution = resolution;
 | 
			
		||||
  eek_theme_context_changed (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_set_default_resolution:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the resolution of the theme context to the default value of 96.
 | 
			
		||||
 * See eek_theme_context_set_resolution().
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_theme_context_set_default_resolution (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
			
		||||
 | 
			
		||||
  if (context->resolution == DEFAULT_RESOLUTION)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  context->resolution = DEFAULT_RESOLUTION;
 | 
			
		||||
  eek_theme_context_changed (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_get_resolution:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the current resolution of the theme context.
 | 
			
		||||
 * See eek_theme_context_set_resolution().
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the resolution (in dots-per-"inch")
 | 
			
		||||
 */
 | 
			
		||||
double
 | 
			
		||||
eek_theme_context_get_resolution (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), DEFAULT_RESOLUTION);
 | 
			
		||||
 | 
			
		||||
  return context->resolution;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_set_font:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 * @font: the default font for theme context
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the default font for the theme context. This is the font that
 | 
			
		||||
 * is inherited by the root node of the tree of theme nodes. If the
 | 
			
		||||
 * font is not overriden, then this font will be used. If the font is
 | 
			
		||||
 * partially modified (for example, with 'font-size: 110%', then that
 | 
			
		||||
 * modification is based on this font.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_theme_context_set_font (EekThemeContext             *context,
 | 
			
		||||
                           const PangoFontDescription *font)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
			
		||||
  g_return_if_fail (font != NULL);
 | 
			
		||||
 | 
			
		||||
  if (context->font == font ||
 | 
			
		||||
      pango_font_description_equal (context->font, font))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  pango_font_description_free (context->font);
 | 
			
		||||
  context->font = pango_font_description_copy (font);
 | 
			
		||||
  eek_theme_context_changed (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_get_font:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the default font for the theme context. See eek_theme_context_set_font().
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the default font for the theme context.
 | 
			
		||||
 */
 | 
			
		||||
const PangoFontDescription *
 | 
			
		||||
eek_theme_context_get_font (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), NULL);
 | 
			
		||||
 | 
			
		||||
  return context->font;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_get_root_node:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the root node of the tree of theme style nodes that associated with this
 | 
			
		||||
 * context. For the node tree associated with a stage, this node represents
 | 
			
		||||
 * styles applied to the stage itself.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): the root node of the context's style tree
 | 
			
		||||
 */
 | 
			
		||||
EekThemeNode *
 | 
			
		||||
eek_theme_context_get_root_node (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  if (context->root_node == NULL)
 | 
			
		||||
    context->root_node = eek_theme_node_new (context, NULL, context->theme,
 | 
			
		||||
                                             G_TYPE_NONE, NULL, NULL, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  return context->root_node;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								eek/eek-theme-context.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								eek/eek-theme-context.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,78 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * eek-theme-context.c: holds global information about a tree of styled objects
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2009, 2010 Red Hat, Inc.
 | 
			
		||||
 * Copyright 2009 Florian Müllner
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 2.1 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __EEK_THEME_CONTEXT_H__
 | 
			
		||||
#define __EEK_THEME_CONTEXT_H__
 | 
			
		||||
 | 
			
		||||
#include <pango/pango.h>
 | 
			
		||||
#include "eek-theme-node.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:EekThemeContext
 | 
			
		||||
 * @short_description: holds global information about a tree of styled objects
 | 
			
		||||
 *
 | 
			
		||||
 * #EekThemeContext is responsible for managing information global to
 | 
			
		||||
 * a tree of styled objects, such as the set of stylesheets or the
 | 
			
		||||
 * default font.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef struct _EekThemeContextClass EekThemeContextClass;
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_THEME_CONTEXT             (eek_theme_context_get_type ())
 | 
			
		||||
#define EEK_THEME_CONTEXT(object)          (G_TYPE_CHECK_INSTANCE_CAST ((object), EEK_TYPE_THEME_CONTEXT, EekThemeContext))
 | 
			
		||||
#define EEK_THEME_CONTEXT_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
 | 
			
		||||
#define EEK_IS_THEME_CONTEXT(object)       (G_TYPE_CHECK_INSTANCE_TYPE ((object), EEK_TYPE_THEME_CONTEXT))
 | 
			
		||||
#define EEK_IS_THEME_CONTEXT_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_CONTEXT))
 | 
			
		||||
#define EEK_THEME_CONTEXT_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
 | 
			
		||||
 | 
			
		||||
GType                       eek_theme_context_get_type
 | 
			
		||||
                            (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekThemeContext            *eek_theme_context_new
 | 
			
		||||
                            (void);
 | 
			
		||||
 | 
			
		||||
void                        eek_theme_context_set_theme
 | 
			
		||||
                            (EekThemeContext            *context,
 | 
			
		||||
                             EekTheme                   *theme);
 | 
			
		||||
EekTheme *                  eek_theme_context_get_theme
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
 | 
			
		||||
void                        eek_theme_context_set_resolution
 | 
			
		||||
                            (EekThemeContext            *context,
 | 
			
		||||
                             gdouble                     resolution);
 | 
			
		||||
void                        eek_theme_context_set_default_resolution
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
double                      eek_theme_context_get_resolution
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
void                        eek_theme_context_set_font
 | 
			
		||||
                            (EekThemeContext            *context,
 | 
			
		||||
                             const PangoFontDescription *font);
 | 
			
		||||
const PangoFontDescription *eek_theme_context_get_font
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
 | 
			
		||||
EekThemeNode *              eek_theme_context_get_root_node
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EEK_THEME_CONTEXT_H__ */
 | 
			
		||||
@ -31,15 +31,19 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <libcroco/libcroco.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-theme-context.h"
 | 
			
		||||
#include "eek-theme-node.h"
 | 
			
		||||
#include "eek-theme-private.h"
 | 
			
		||||
 | 
			
		||||
struct _EekThemeNode {
 | 
			
		||||
  GObject parent;
 | 
			
		||||
 | 
			
		||||
  EekThemeContext *context;
 | 
			
		||||
  EekThemeNode *parent_node;
 | 
			
		||||
  EekTheme *theme;
 | 
			
		||||
 | 
			
		||||
  PangoFontDescription *font_desc;
 | 
			
		||||
 | 
			
		||||
  EekGradientType background_gradient_type;
 | 
			
		||||
 | 
			
		||||
  EekColor background_color;
 | 
			
		||||
@ -108,6 +112,12 @@ eek_theme_node_dispose (GObject *gobject)
 | 
			
		||||
{
 | 
			
		||||
  EekThemeNode *node = EEK_THEME_NODE (gobject);
 | 
			
		||||
 | 
			
		||||
  if (node->context)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_unref (node->context);
 | 
			
		||||
      node->context = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (node->theme)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_unref (node->theme);
 | 
			
		||||
@ -146,6 +156,12 @@ eek_theme_node_finalize (GObject *object)
 | 
			
		||||
      cr_declaration_destroy (node->inline_properties);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (node->font_desc)
 | 
			
		||||
    {
 | 
			
		||||
      pango_font_description_free (node->font_desc);
 | 
			
		||||
      node->font_desc = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (eek_theme_node_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -171,20 +187,23 @@ eek_theme_node_finalize (GObject *object)
 | 
			
		||||
 * Return value: (transfer full): the theme node
 | 
			
		||||
 */
 | 
			
		||||
EekThemeNode *
 | 
			
		||||
eek_theme_node_new (EekThemeNode *parent_node,
 | 
			
		||||
                    EekTheme     *theme,
 | 
			
		||||
                    GType         element_type,
 | 
			
		||||
                    const char   *element_id,
 | 
			
		||||
                    const char   *element_class,
 | 
			
		||||
                    const char   *pseudo_class,
 | 
			
		||||
                    const char   *inline_style)
 | 
			
		||||
eek_theme_node_new (EekThemeContext *context,
 | 
			
		||||
                    EekThemeNode    *parent_node,
 | 
			
		||||
                    EekTheme        *theme,
 | 
			
		||||
                    GType            element_type,
 | 
			
		||||
                    const char      *element_id,
 | 
			
		||||
                    const char      *element_class,
 | 
			
		||||
                    const char      *pseudo_class,
 | 
			
		||||
                    const char      *inline_style)
 | 
			
		||||
{
 | 
			
		||||
  EekThemeNode *node;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), NULL);
 | 
			
		||||
  g_return_val_if_fail (parent_node == NULL || EEK_IS_THEME_NODE (parent_node), NULL);
 | 
			
		||||
 | 
			
		||||
  node = g_object_new (EEK_TYPE_THEME_NODE, NULL);
 | 
			
		||||
 | 
			
		||||
  node->context = g_object_ref (context);
 | 
			
		||||
  if (parent_node != NULL)
 | 
			
		||||
    node->parent_node = g_object_ref (parent_node);
 | 
			
		||||
  else
 | 
			
		||||
@ -635,6 +654,15 @@ eek_theme_node_get_double (EekThemeNode *node,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const PangoFontDescription *
 | 
			
		||||
get_parent_font (EekThemeNode *node)
 | 
			
		||||
{
 | 
			
		||||
  if (node->parent_node)
 | 
			
		||||
    return eek_theme_node_get_font (node->parent_node);
 | 
			
		||||
  else
 | 
			
		||||
    return eek_theme_context_get_font (node->context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GetFromTermResult
 | 
			
		||||
get_length_from_term (EekThemeNode *node,
 | 
			
		||||
                      CRTerm      *term,
 | 
			
		||||
@ -750,16 +778,11 @@ get_length_from_term (EekThemeNode *node,
 | 
			
		||||
      *length = num->val * multiplier;
 | 
			
		||||
      break;
 | 
			
		||||
    case POINTS:
 | 
			
		||||
#if 0
 | 
			
		||||
      {
 | 
			
		||||
        double resolution = eek_theme_context_get_resolution (node->context);
 | 
			
		||||
        *length = num->val * multiplier * (resolution / 72.);
 | 
			
		||||
      }
 | 
			
		||||
#else
 | 
			
		||||
      *length = num->val * multiplier;
 | 
			
		||||
#endif
 | 
			
		||||
      break;
 | 
			
		||||
#if 0
 | 
			
		||||
    case FONT_RELATIVE:
 | 
			
		||||
      {
 | 
			
		||||
        const PangoFontDescription *desc;
 | 
			
		||||
@ -783,7 +806,7 @@ get_length_from_term (EekThemeNode *node,
 | 
			
		||||
          }
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      g_assert_not_reached ();
 | 
			
		||||
    }
 | 
			
		||||
@ -1392,3 +1415,455 @@ eek_theme_node_get_background_gradient (EekThemeNode    *node,
 | 
			
		||||
      *end = node->background_gradient_end;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
font_family_from_terms (CRTerm *term,
 | 
			
		||||
                        char  **family)
 | 
			
		||||
{
 | 
			
		||||
  GString *family_string;
 | 
			
		||||
  gboolean result = FALSE;
 | 
			
		||||
  gboolean last_was_quoted = FALSE;
 | 
			
		||||
 | 
			
		||||
  if (!term)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  family_string = g_string_new (NULL);
 | 
			
		||||
 | 
			
		||||
  while (term)
 | 
			
		||||
    {
 | 
			
		||||
      if (term->type != TERM_STRING && term->type != TERM_IDENT)
 | 
			
		||||
        {
 | 
			
		||||
          goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (family_string->len > 0)
 | 
			
		||||
        {
 | 
			
		||||
          if (term->the_operator != COMMA && term->the_operator != NO_OP)
 | 
			
		||||
            goto out;
 | 
			
		||||
          /* Can concatenate two bare words, but not two quoted strings */
 | 
			
		||||
          if ((term->the_operator == NO_OP && last_was_quoted) || term->type == TERM_STRING)
 | 
			
		||||
            goto out;
 | 
			
		||||
 | 
			
		||||
          if (term->the_operator == NO_OP)
 | 
			
		||||
            g_string_append (family_string, " ");
 | 
			
		||||
          else
 | 
			
		||||
            g_string_append (family_string, ", ");
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          if (term->the_operator != NO_OP)
 | 
			
		||||
            goto out;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      g_string_append (family_string, term->content.str->stryng->str);
 | 
			
		||||
 | 
			
		||||
      term = term->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  result = TRUE;
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  if (result)
 | 
			
		||||
    {
 | 
			
		||||
      *family = g_string_free (family_string, FALSE);
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      *family = g_string_free (family_string, TRUE);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* In points */
 | 
			
		||||
static int font_sizes[] = {
 | 
			
		||||
  6 * 1024,   /* xx-small */
 | 
			
		||||
  8 * 1024,   /* x-small */
 | 
			
		||||
  10 * 1024,  /* small */
 | 
			
		||||
  12 * 1024,  /* medium */
 | 
			
		||||
  16 * 1024,  /* large */
 | 
			
		||||
  20 * 1024,  /* x-large */
 | 
			
		||||
  24 * 1024,  /* xx-large */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
font_size_from_term (EekThemeNode *node,
 | 
			
		||||
                     CRTerm      *term,
 | 
			
		||||
                     double      *size)
 | 
			
		||||
{
 | 
			
		||||
  if (term->type == TERM_IDENT)
 | 
			
		||||
    {
 | 
			
		||||
      double resolution = eek_theme_context_get_resolution (node->context);
 | 
			
		||||
      /* We work in integers to avoid double comparisons when converting back
 | 
			
		||||
       * from a size in pixels to a logical size.
 | 
			
		||||
       */
 | 
			
		||||
      int size_points = (int)(0.5 + *size * (72. / resolution));
 | 
			
		||||
 | 
			
		||||
      if (strcmp (term->content.str->stryng->str, "xx-small") == 0)
 | 
			
		||||
        size_points = font_sizes[0];
 | 
			
		||||
      else if (strcmp (term->content.str->stryng->str, "x-small") == 0)
 | 
			
		||||
        size_points = font_sizes[1];
 | 
			
		||||
      else if (strcmp (term->content.str->stryng->str, "small") == 0)
 | 
			
		||||
        size_points = font_sizes[2];
 | 
			
		||||
      else if (strcmp (term->content.str->stryng->str, "medium") == 0)
 | 
			
		||||
        size_points = font_sizes[3];
 | 
			
		||||
      else if (strcmp (term->content.str->stryng->str, "large") == 0)
 | 
			
		||||
        size_points = font_sizes[4];
 | 
			
		||||
      else if (strcmp (term->content.str->stryng->str, "x-large") == 0)
 | 
			
		||||
        size_points = font_sizes[5];
 | 
			
		||||
      else if (strcmp (term->content.str->stryng->str, "xx-large") == 0)
 | 
			
		||||
        size_points = font_sizes[6];
 | 
			
		||||
      else if (strcmp (term->content.str->stryng->str, "smaller") == 0)
 | 
			
		||||
        {
 | 
			
		||||
          /* Find the standard size equal to or smaller than the current size */
 | 
			
		||||
          int i = 0;
 | 
			
		||||
 | 
			
		||||
          while (i <= 6 && font_sizes[i] < size_points)
 | 
			
		||||
            i++;
 | 
			
		||||
 | 
			
		||||
          if (i > 6)
 | 
			
		||||
            {
 | 
			
		||||
              /* original size greater than any standard size */
 | 
			
		||||
              size_points = (int)(0.5 + size_points / 1.2);
 | 
			
		||||
            }
 | 
			
		||||
          else
 | 
			
		||||
            {
 | 
			
		||||
              /* Go one smaller than that, if possible */
 | 
			
		||||
              if (i > 0)
 | 
			
		||||
                i--;
 | 
			
		||||
 | 
			
		||||
              size_points = font_sizes[i];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
      else if (strcmp (term->content.str->stryng->str, "larger") == 0)
 | 
			
		||||
        {
 | 
			
		||||
          /* Find the standard size equal to or larger than the current size */
 | 
			
		||||
          int i = 6;
 | 
			
		||||
 | 
			
		||||
          while (i >= 0 && font_sizes[i] > size_points)
 | 
			
		||||
            i--;
 | 
			
		||||
 | 
			
		||||
          if (i < 0) /* original size smaller than any standard size */
 | 
			
		||||
            i = 0;
 | 
			
		||||
 | 
			
		||||
          /* Go one larger than that, if possible */
 | 
			
		||||
          if (i < 6)
 | 
			
		||||
            i++;
 | 
			
		||||
 | 
			
		||||
          size_points = font_sizes[i];
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      *size = size_points * (resolution / 72.);
 | 
			
		||||
      return TRUE;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  else if (term->type == TERM_NUMBER && term->content.num->type == NUM_PERCENTAGE)
 | 
			
		||||
    {
 | 
			
		||||
      *size *= term->content.num->val / 100.;
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  else if (get_length_from_term (node, term, TRUE, size) == VALUE_FOUND)
 | 
			
		||||
    {
 | 
			
		||||
      /* Convert from pixels to Pango units */
 | 
			
		||||
      *size *= 1024;
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
font_weight_from_term (CRTerm      *term,
 | 
			
		||||
                       PangoWeight *weight,
 | 
			
		||||
                       gboolean    *weight_absolute)
 | 
			
		||||
{
 | 
			
		||||
  if (term->type == TERM_NUMBER)
 | 
			
		||||
    {
 | 
			
		||||
      int weight_int;
 | 
			
		||||
 | 
			
		||||
      /* The spec only allows numeric weights from 100-900, though Pango
 | 
			
		||||
       * will handle any number. We just let anything through.
 | 
			
		||||
       */
 | 
			
		||||
      if (term->content.num->type != NUM_GENERIC)
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
      weight_int = (int)(0.5 + term->content.num->val);
 | 
			
		||||
 | 
			
		||||
      *weight = weight_int;
 | 
			
		||||
      *weight_absolute = TRUE;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  else if (term->type == TERM_IDENT)
 | 
			
		||||
    {
 | 
			
		||||
      /* FIXME: handle INHERIT */
 | 
			
		||||
 | 
			
		||||
      if (strcmp (term->content.str->stryng->str, "bold") == 0)
 | 
			
		||||
        {
 | 
			
		||||
          *weight = PANGO_WEIGHT_BOLD;
 | 
			
		||||
          *weight_absolute = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      else if (strcmp (term->content.str->stryng->str, "normal") == 0)
 | 
			
		||||
        {
 | 
			
		||||
          *weight = PANGO_WEIGHT_NORMAL;
 | 
			
		||||
          *weight_absolute = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      else if (strcmp (term->content.str->stryng->str, "bolder") == 0)
 | 
			
		||||
        {
 | 
			
		||||
          *weight = PANGO_WEIGHT_BOLD;
 | 
			
		||||
          *weight_absolute = FALSE;
 | 
			
		||||
        }
 | 
			
		||||
      else if (strcmp (term->content.str->stryng->str, "lighter") == 0)
 | 
			
		||||
        {
 | 
			
		||||
          *weight = PANGO_WEIGHT_LIGHT;
 | 
			
		||||
          *weight_absolute = FALSE;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
font_style_from_term (CRTerm     *term,
 | 
			
		||||
                      PangoStyle *style)
 | 
			
		||||
{
 | 
			
		||||
  if (term->type != TERM_IDENT)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  /* FIXME: handle INHERIT */
 | 
			
		||||
 | 
			
		||||
  if (strcmp (term->content.str->stryng->str, "normal") == 0)
 | 
			
		||||
    *style = PANGO_STYLE_NORMAL;
 | 
			
		||||
  else if (strcmp (term->content.str->stryng->str, "oblique") == 0)
 | 
			
		||||
    *style = PANGO_STYLE_OBLIQUE;
 | 
			
		||||
  else if (strcmp (term->content.str->stryng->str, "italic") == 0)
 | 
			
		||||
    *style = PANGO_STYLE_ITALIC;
 | 
			
		||||
  else
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
font_variant_from_term (CRTerm       *term,
 | 
			
		||||
                        PangoVariant *variant)
 | 
			
		||||
{
 | 
			
		||||
  if (term->type != TERM_IDENT)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  /* FIXME: handle INHERIT */
 | 
			
		||||
 | 
			
		||||
  if (strcmp (term->content.str->stryng->str, "normal") == 0)
 | 
			
		||||
    *variant = PANGO_VARIANT_NORMAL;
 | 
			
		||||
  else if (strcmp (term->content.str->stryng->str, "small-caps") == 0)
 | 
			
		||||
    *variant = PANGO_VARIANT_SMALL_CAPS;
 | 
			
		||||
  else
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const PangoFontDescription *
 | 
			
		||||
eek_theme_node_get_font (EekThemeNode *node)
 | 
			
		||||
{
 | 
			
		||||
  /* Initialized despite _set flags to suppress compiler warnings */
 | 
			
		||||
  PangoStyle font_style = PANGO_STYLE_NORMAL;
 | 
			
		||||
  gboolean font_style_set = FALSE;
 | 
			
		||||
  PangoVariant variant = PANGO_VARIANT_NORMAL;
 | 
			
		||||
  gboolean variant_set = FALSE;
 | 
			
		||||
  PangoWeight weight = PANGO_WEIGHT_NORMAL;
 | 
			
		||||
  gboolean weight_absolute = TRUE;
 | 
			
		||||
  gboolean weight_set = FALSE;
 | 
			
		||||
  double size = 0.;
 | 
			
		||||
  gboolean size_set = FALSE;
 | 
			
		||||
 | 
			
		||||
  char *family = NULL;
 | 
			
		||||
  double parent_size;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  if (node->font_desc)
 | 
			
		||||
    return node->font_desc;
 | 
			
		||||
 | 
			
		||||
  node->font_desc = pango_font_description_copy (get_parent_font (node));
 | 
			
		||||
  parent_size = pango_font_description_get_size (node->font_desc);
 | 
			
		||||
  if (!pango_font_description_get_size_is_absolute (node->font_desc))
 | 
			
		||||
    {
 | 
			
		||||
      double resolution = eek_theme_context_get_resolution (node->context);
 | 
			
		||||
      parent_size *= (resolution / 72.);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  ensure_properties (node);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < node->n_properties; i++)
 | 
			
		||||
    {
 | 
			
		||||
      CRDeclaration *decl = node->properties[i];
 | 
			
		||||
 | 
			
		||||
      if (strcmp (decl->property->stryng->str, "font") == 0)
 | 
			
		||||
        {
 | 
			
		||||
          PangoStyle tmp_style = PANGO_STYLE_NORMAL;
 | 
			
		||||
          PangoVariant tmp_variant = PANGO_VARIANT_NORMAL;
 | 
			
		||||
          PangoWeight tmp_weight = PANGO_WEIGHT_NORMAL;
 | 
			
		||||
          gboolean tmp_weight_absolute = TRUE;
 | 
			
		||||
          double tmp_size;
 | 
			
		||||
          CRTerm *term = decl->value;
 | 
			
		||||
 | 
			
		||||
          /* A font specification starts with node/variant/weight
 | 
			
		||||
           * in any order. Each is allowed to be specified only once,
 | 
			
		||||
           * but we don't enforce that.
 | 
			
		||||
           */
 | 
			
		||||
          for (; term; term = term->next)
 | 
			
		||||
            {
 | 
			
		||||
              if (font_style_from_term (term, &tmp_style))
 | 
			
		||||
                continue;
 | 
			
		||||
              if (font_variant_from_term (term, &tmp_variant))
 | 
			
		||||
                continue;
 | 
			
		||||
              if (font_weight_from_term (term, &tmp_weight, &tmp_weight_absolute))
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          /* The size is mandatory */
 | 
			
		||||
 | 
			
		||||
          if (term == NULL || term->type != TERM_NUMBER)
 | 
			
		||||
            {
 | 
			
		||||
              g_warning ("Size missing from font property");
 | 
			
		||||
              continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          tmp_size = parent_size;
 | 
			
		||||
          if (!font_size_from_term (node, term, &tmp_size))
 | 
			
		||||
            {
 | 
			
		||||
              g_warning ("Couldn't parse size in font property");
 | 
			
		||||
              continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          term = term->next;
 | 
			
		||||
 | 
			
		||||
          if (term != NULL && term->type && TERM_NUMBER && term->the_operator == DIVIDE)
 | 
			
		||||
            {
 | 
			
		||||
              /* Ignore line-height specification */
 | 
			
		||||
              term = term->next;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          /* the font family is mandatory - it is a comma-separated list of
 | 
			
		||||
           * names.
 | 
			
		||||
           */
 | 
			
		||||
          if (!font_family_from_terms (term, &family))
 | 
			
		||||
            {
 | 
			
		||||
              g_warning ("Couldn't parse family in font property");
 | 
			
		||||
              continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          font_style = tmp_style;
 | 
			
		||||
          font_style_set = TRUE;
 | 
			
		||||
          weight = tmp_weight;
 | 
			
		||||
          weight_absolute = tmp_weight_absolute;
 | 
			
		||||
          weight_set = TRUE;
 | 
			
		||||
          variant = tmp_variant;
 | 
			
		||||
          variant_set = TRUE;
 | 
			
		||||
 | 
			
		||||
          size = tmp_size;
 | 
			
		||||
          size_set = TRUE;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
      else if (strcmp (decl->property->stryng->str, "font-family") == 0)
 | 
			
		||||
        {
 | 
			
		||||
          if (!font_family_from_terms (decl->value, &family))
 | 
			
		||||
            {
 | 
			
		||||
              g_warning ("Couldn't parse family in font property");
 | 
			
		||||
              continue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
      else if (strcmp (decl->property->stryng->str, "font-weight") == 0)
 | 
			
		||||
        {
 | 
			
		||||
          if (decl->value == NULL || decl->value->next != NULL)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
          if (font_weight_from_term (decl->value, &weight, &weight_absolute))
 | 
			
		||||
            weight_set = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      else if (strcmp (decl->property->stryng->str, "font-style") == 0)
 | 
			
		||||
        {
 | 
			
		||||
          if (decl->value == NULL || decl->value->next != NULL)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
          if (font_style_from_term (decl->value, &font_style))
 | 
			
		||||
            font_style_set = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      else if (strcmp (decl->property->stryng->str, "font-variant") == 0)
 | 
			
		||||
        {
 | 
			
		||||
          if (decl->value == NULL || decl->value->next != NULL)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
          if (font_variant_from_term (decl->value, &variant))
 | 
			
		||||
            variant_set = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      else if (strcmp (decl->property->stryng->str, "font-size") == 0)
 | 
			
		||||
        {
 | 
			
		||||
          gdouble tmp_size;
 | 
			
		||||
          if (decl->value == NULL || decl->value->next != NULL)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
          tmp_size = parent_size;
 | 
			
		||||
          if (font_size_from_term (node, decl->value, &tmp_size))
 | 
			
		||||
            {
 | 
			
		||||
              size = tmp_size;
 | 
			
		||||
              size_set = TRUE;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (family)
 | 
			
		||||
    {
 | 
			
		||||
      pango_font_description_set_family (node->font_desc, family);
 | 
			
		||||
      g_free (family);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (size_set)
 | 
			
		||||
    pango_font_description_set_absolute_size (node->font_desc, size);
 | 
			
		||||
 | 
			
		||||
  if (weight_set)
 | 
			
		||||
    {
 | 
			
		||||
      if (!weight_absolute)
 | 
			
		||||
        {
 | 
			
		||||
          /* bolder/lighter are supposed to switch between available styles, but with
 | 
			
		||||
           * font substitution, that gets to be a pretty fuzzy concept. So we use
 | 
			
		||||
           * a fixed step of 200. (The spec says 100, but that might not take us from
 | 
			
		||||
           * normal to bold.
 | 
			
		||||
           */
 | 
			
		||||
 | 
			
		||||
          PangoWeight old_weight = pango_font_description_get_weight (node->font_desc);
 | 
			
		||||
          if (weight == PANGO_WEIGHT_BOLD)
 | 
			
		||||
            weight = old_weight + 200;
 | 
			
		||||
          else
 | 
			
		||||
            weight = old_weight - 200;
 | 
			
		||||
 | 
			
		||||
          if (weight < 100)
 | 
			
		||||
            weight = 100;
 | 
			
		||||
          if (weight > 900)
 | 
			
		||||
            weight = 900;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      pango_font_description_set_weight (node->font_desc, weight);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (font_style_set)
 | 
			
		||||
    pango_font_description_set_style (node->font_desc, font_style);
 | 
			
		||||
  if (variant_set)
 | 
			
		||||
    pango_font_description_set_variant (node->font_desc, variant);
 | 
			
		||||
 | 
			
		||||
  return node->font_desc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@
 | 
			
		||||
#ifndef __EEK_THEME_NODE_H__
 | 
			
		||||
#define __EEK_THEME_NODE_H__
 | 
			
		||||
 | 
			
		||||
#include <pango/pango.h>
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
@ -70,7 +71,8 @@ typedef struct _EekThemeNodePrivate EekThemeNodePrivate;
 | 
			
		||||
GType         eek_theme_node_get_type
 | 
			
		||||
                                 (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekThemeNode *eek_theme_node_new (EekThemeNode               *parent_node,
 | 
			
		||||
EekThemeNode *eek_theme_node_new (EekThemeContext            *context,
 | 
			
		||||
                                  EekThemeNode               *parent_node,
 | 
			
		||||
                                  /* can be null */ EekTheme *theme,
 | 
			
		||||
                                  /* can be null */ GType     element_type,
 | 
			
		||||
                                  const char                 *element_id,
 | 
			
		||||
@ -127,6 +129,13 @@ void          eek_theme_node_get_border_color
 | 
			
		||||
                                  EekSide                     side,
 | 
			
		||||
                                  EekColor                   *color);
 | 
			
		||||
 | 
			
		||||
/* Font rule processing is pretty complicated, so we just hardcode it
 | 
			
		||||
 * under the standard font/font-family/font-size/etc names. This means
 | 
			
		||||
 * you can't have multiple separate styled fonts for a single item,
 | 
			
		||||
 * but that should be OK.
 | 
			
		||||
 */
 | 
			
		||||
const PangoFontDescription *eek_theme_node_get_font (EekThemeNode *node);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EEK_THEME_NODE_H__ */
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-theme-node.h"
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -137,6 +137,7 @@ typedef struct _EekKeyboard EekKeyboard;
 | 
			
		||||
typedef struct _EekSymbol EekSymbol;
 | 
			
		||||
typedef struct _EekKeysym EekKeysym;
 | 
			
		||||
typedef struct _EekTheme EekTheme;
 | 
			
		||||
typedef struct _EekThemeContext EekThemeContext;
 | 
			
		||||
typedef struct _EekThemeNode EekThemeNode;
 | 
			
		||||
 | 
			
		||||
typedef struct _EekSymbolMatrix EekSymbolMatrix;
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user