Port st-theme-context.[ch] to eek-theme-context.[ch].
This commit is contained in:
@ -48,6 +48,7 @@ libeek_private_headers = \
|
|||||||
$(srcdir)/eek-unicode-keysym-entries.h \
|
$(srcdir)/eek-unicode-keysym-entries.h \
|
||||||
$(srcdir)/eek-xkeysym-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
|
$(srcdir)/eek-theme-node.h
|
||||||
|
|
||||||
libeek_sources = \
|
libeek_sources = \
|
||||||
@ -66,6 +67,7 @@ libeek_sources = \
|
|||||||
$(srcdir)/eek-renderer.c \
|
$(srcdir)/eek-renderer.c \
|
||||||
$(srcdir)/eek-keyboard-drawing.c \
|
$(srcdir)/eek-keyboard-drawing.c \
|
||||||
$(srcdir)/eek-theme.c \
|
$(srcdir)/eek-theme.c \
|
||||||
|
$(srcdir)/eek-theme-context.c \
|
||||||
$(srcdir)/eek-theme-node.c
|
$(srcdir)/eek-theme-node.c
|
||||||
|
|
||||||
libeek_keysym_sources = \
|
libeek_keysym_sources = \
|
||||||
|
|||||||
@ -1256,6 +1256,7 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct _CreateThemeNodeData {
|
struct _CreateThemeNodeData {
|
||||||
|
EekThemeContext *context;
|
||||||
EekThemeNode *parent;
|
EekThemeNode *parent;
|
||||||
EekRenderer *renderer;
|
EekRenderer *renderer;
|
||||||
};
|
};
|
||||||
@ -1271,7 +1272,8 @@ create_theme_node_key_callback (EekElement *element,
|
|||||||
|
|
||||||
priv = EEK_RENDERER_GET_PRIVATE(data->renderer);
|
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,
|
priv->theme,
|
||||||
EEK_TYPE_KEY,
|
EEK_TYPE_KEY,
|
||||||
eek_element_get_name (element),
|
eek_element_get_name (element),
|
||||||
@ -1283,7 +1285,8 @@ create_theme_node_key_callback (EekElement *element,
|
|||||||
theme_node,
|
theme_node,
|
||||||
(GDestroyNotify)g_object_unref);
|
(GDestroyNotify)g_object_unref);
|
||||||
|
|
||||||
theme_node = eek_theme_node_new (data->parent,
|
theme_node = eek_theme_node_new (data->context,
|
||||||
|
data->parent,
|
||||||
priv->theme,
|
priv->theme,
|
||||||
EEK_TYPE_KEY,
|
EEK_TYPE_KEY,
|
||||||
eek_element_get_name (element),
|
eek_element_get_name (element),
|
||||||
@ -1306,7 +1309,8 @@ create_theme_node_section_callback (EekElement *element,
|
|||||||
|
|
||||||
priv = EEK_RENDERER_GET_PRIVATE(data->renderer);
|
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,
|
priv->theme,
|
||||||
EEK_TYPE_SECTION,
|
EEK_TYPE_SECTION,
|
||||||
eek_element_get_name (element),
|
eek_element_get_name (element),
|
||||||
@ -1331,6 +1335,7 @@ eek_renderer_set_theme (EekRenderer *renderer,
|
|||||||
EekTheme *theme)
|
EekTheme *theme)
|
||||||
{
|
{
|
||||||
EekRendererPrivate *priv;
|
EekRendererPrivate *priv;
|
||||||
|
EekThemeContext *theme_context;
|
||||||
EekThemeNode *theme_node;
|
EekThemeNode *theme_node;
|
||||||
CreateThemeNodeData data;
|
CreateThemeNodeData data;
|
||||||
|
|
||||||
@ -1344,7 +1349,9 @@ eek_renderer_set_theme (EekRenderer *renderer,
|
|||||||
g_object_unref (priv->theme);
|
g_object_unref (priv->theme);
|
||||||
priv->theme = g_object_ref (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,
|
priv->theme,
|
||||||
EEK_TYPE_KEYBOARD,
|
EEK_TYPE_KEYBOARD,
|
||||||
"keyboard",
|
"keyboard",
|
||||||
@ -1356,6 +1363,7 @@ eek_renderer_set_theme (EekRenderer *renderer,
|
|||||||
theme_node,
|
theme_node,
|
||||||
(GDestroyNotify)g_object_unref);
|
(GDestroyNotify)g_object_unref);
|
||||||
|
|
||||||
|
data.context = theme_context;
|
||||||
data.parent = theme_node;
|
data.parent = theme_node;
|
||||||
data.renderer = renderer;
|
data.renderer = renderer;
|
||||||
eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
|
eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
#include "eek-keysym.h"
|
#include "eek-keysym.h"
|
||||||
#include "eek-types.h"
|
#include "eek-types.h"
|
||||||
#include "eek-theme.h"
|
#include "eek-theme.h"
|
||||||
|
#include "eek-theme-context.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
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 <string.h>
|
||||||
#include <libcroco/libcroco.h>
|
#include <libcroco/libcroco.h>
|
||||||
|
|
||||||
|
#include "eek-theme-context.h"
|
||||||
#include "eek-theme-node.h"
|
#include "eek-theme-node.h"
|
||||||
#include "eek-theme-private.h"
|
#include "eek-theme-private.h"
|
||||||
|
|
||||||
struct _EekThemeNode {
|
struct _EekThemeNode {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
||||||
|
EekThemeContext *context;
|
||||||
EekThemeNode *parent_node;
|
EekThemeNode *parent_node;
|
||||||
EekTheme *theme;
|
EekTheme *theme;
|
||||||
|
|
||||||
|
PangoFontDescription *font_desc;
|
||||||
|
|
||||||
EekGradientType background_gradient_type;
|
EekGradientType background_gradient_type;
|
||||||
|
|
||||||
EekColor background_color;
|
EekColor background_color;
|
||||||
@ -108,6 +112,12 @@ eek_theme_node_dispose (GObject *gobject)
|
|||||||
{
|
{
|
||||||
EekThemeNode *node = EEK_THEME_NODE (gobject);
|
EekThemeNode *node = EEK_THEME_NODE (gobject);
|
||||||
|
|
||||||
|
if (node->context)
|
||||||
|
{
|
||||||
|
g_object_unref (node->context);
|
||||||
|
node->context = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (node->theme)
|
if (node->theme)
|
||||||
{
|
{
|
||||||
g_object_unref (node->theme);
|
g_object_unref (node->theme);
|
||||||
@ -146,6 +156,12 @@ eek_theme_node_finalize (GObject *object)
|
|||||||
cr_declaration_destroy (node->inline_properties);
|
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);
|
G_OBJECT_CLASS (eek_theme_node_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +187,8 @@ eek_theme_node_finalize (GObject *object)
|
|||||||
* Return value: (transfer full): the theme node
|
* Return value: (transfer full): the theme node
|
||||||
*/
|
*/
|
||||||
EekThemeNode *
|
EekThemeNode *
|
||||||
eek_theme_node_new (EekThemeNode *parent_node,
|
eek_theme_node_new (EekThemeContext *context,
|
||||||
|
EekThemeNode *parent_node,
|
||||||
EekTheme *theme,
|
EekTheme *theme,
|
||||||
GType element_type,
|
GType element_type,
|
||||||
const char *element_id,
|
const char *element_id,
|
||||||
@ -181,10 +198,12 @@ eek_theme_node_new (EekThemeNode *parent_node,
|
|||||||
{
|
{
|
||||||
EekThemeNode *node;
|
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);
|
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 = g_object_new (EEK_TYPE_THEME_NODE, NULL);
|
||||||
|
|
||||||
|
node->context = g_object_ref (context);
|
||||||
if (parent_node != NULL)
|
if (parent_node != NULL)
|
||||||
node->parent_node = g_object_ref (parent_node);
|
node->parent_node = g_object_ref (parent_node);
|
||||||
else
|
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
|
static GetFromTermResult
|
||||||
get_length_from_term (EekThemeNode *node,
|
get_length_from_term (EekThemeNode *node,
|
||||||
CRTerm *term,
|
CRTerm *term,
|
||||||
@ -750,16 +778,11 @@ get_length_from_term (EekThemeNode *node,
|
|||||||
*length = num->val * multiplier;
|
*length = num->val * multiplier;
|
||||||
break;
|
break;
|
||||||
case POINTS:
|
case POINTS:
|
||||||
#if 0
|
|
||||||
{
|
{
|
||||||
double resolution = eek_theme_context_get_resolution (node->context);
|
double resolution = eek_theme_context_get_resolution (node->context);
|
||||||
*length = num->val * multiplier * (resolution / 72.);
|
*length = num->val * multiplier * (resolution / 72.);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
*length = num->val * multiplier;
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
#if 0
|
|
||||||
case FONT_RELATIVE:
|
case FONT_RELATIVE:
|
||||||
{
|
{
|
||||||
const PangoFontDescription *desc;
|
const PangoFontDescription *desc;
|
||||||
@ -783,7 +806,7 @@ get_length_from_term (EekThemeNode *node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
@ -1392,3 +1415,455 @@ eek_theme_node_get_background_gradient (EekThemeNode *node,
|
|||||||
*end = node->background_gradient_end;
|
*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__
|
#ifndef __EEK_THEME_NODE_H__
|
||||||
#define __EEK_THEME_NODE_H__
|
#define __EEK_THEME_NODE_H__
|
||||||
|
|
||||||
|
#include <pango/pango.h>
|
||||||
#include "eek-types.h"
|
#include "eek-types.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
@ -70,7 +71,8 @@ typedef struct _EekThemeNodePrivate EekThemeNodePrivate;
|
|||||||
GType eek_theme_node_get_type
|
GType eek_theme_node_get_type
|
||||||
(void) G_GNUC_CONST;
|
(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 */ EekTheme *theme,
|
||||||
/* can be null */ GType element_type,
|
/* can be null */ GType element_type,
|
||||||
const char *element_id,
|
const char *element_id,
|
||||||
@ -127,6 +129,13 @@ void eek_theme_node_get_border_color
|
|||||||
EekSide side,
|
EekSide side,
|
||||||
EekColor *color);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __EEK_THEME_NODE_H__ */
|
#endif /* __EEK_THEME_NODE_H__ */
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
#include "eek-theme-node.h"
|
#include "eek-types.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|||||||
@ -137,6 +137,7 @@ typedef struct _EekKeyboard EekKeyboard;
|
|||||||
typedef struct _EekSymbol EekSymbol;
|
typedef struct _EekSymbol EekSymbol;
|
||||||
typedef struct _EekKeysym EekKeysym;
|
typedef struct _EekKeysym EekKeysym;
|
||||||
typedef struct _EekTheme EekTheme;
|
typedef struct _EekTheme EekTheme;
|
||||||
|
typedef struct _EekThemeContext EekThemeContext;
|
||||||
typedef struct _EekThemeNode EekThemeNode;
|
typedef struct _EekThemeNode EekThemeNode;
|
||||||
|
|
||||||
typedef struct _EekSymbolMatrix EekSymbolMatrix;
|
typedef struct _EekSymbolMatrix EekSymbolMatrix;
|
||||||
|
|||||||
Reference in New Issue
Block a user