diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gtkext/easygtk.c | 117 | ||||
-rw-r--r-- | src/gtkext/easygtk.h | 5 |
2 files changed, 122 insertions, 0 deletions
diff --git a/src/gtkext/easygtk.c b/src/gtkext/easygtk.c index 6e42556..3a17a72 100644 --- a/src/gtkext/easygtk.c +++ b/src/gtkext/easygtk.c @@ -25,6 +25,7 @@ #include <assert.h> +#include <stdint.h> #include "support.h" @@ -757,9 +758,125 @@ GtkWidget *qck_create_menu_separator(void) +/****************************************************************************** +* * +* Paramètres : class = classe de style à appliquer. * +* background = indique la nature de la couleur à relever. * +* color = couleur associée au style indiqué. [OUT] * +* * +* Description : Identifie la couleur de base associée à un style GTK. * +* * +* Retour : Bilan présumé de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool get_color_from_style(const char *class, bool background, GdkRGBA *color) +{ + bool result; /* Bilan à retourner */ + GtkWidget *area; /* Composant pour le contexte */ + GtkStyleContext *context; /* Contexte de style GTK */ + cairo_surface_t *surface; /* Surface de dessin temporaire*/ + cairo_t *cr; /* Pinceau pour le dessin */ + uint32_t *pixel; /* Valeurs pour un pixel choisi*/ + int a; /* Valeur du canal alpha */ + int r; /* Valeur du canal rouge */ + int g; /* Valeur du canal vert */ + int b; /* Valeur du canal bleu */ + + result = false; + + /* Mise en place de l'environnement */ + + area = gtk_drawing_area_new(); + g_object_ref_sink(G_OBJECT(area)); + + context = gtk_widget_get_style_context (area); + + surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 20, 20); + + if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) + goto empty_surface; + + cr = cairo_create(surface); + + if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) + goto bad_cairo; + + /* Dessin */ + + gtk_style_context_add_class(context, class); + + if (background) + gtk_render_background(context, cr, 0, 0, 20, 20); + else + gtk_render_line(context, cr, -0.5, -0.5, 19.5, 19.5); + cairo_surface_flush(surface); + /* Récupération du pixel (0 ; 0) */ + pixel = (uint32_t *)cairo_image_surface_get_data(surface); + + /* Récupération des valeurs de couleur */ + + a = (*pixel & 0xff000000) >> 24; + r = (*pixel & 0x00ff0000) >> 16; + g = (*pixel & 0x0000ff00) >> 8; + b = (*pixel & 0x000000ff); + + if (a == 0) + { + r = 0; + g = 0; + b = 0; + + } + else + { + /** + * Utilisation de la méthode employée dans la fonction + * _cairo_image_analyze_color() de cairo-image-surface.c. + * + * La documentation pour CAIRO_FORMAT_ARGB32 précise en effet : + * + * """ + * each pixel is a 32-bit quantity, with alpha in the upper 8 bits, + * then red, then green, then blue. The 32-bit quantities are + * native-endian. Pre-multiplied alpha is used. (That is, 50% + * transparent red is 0x80800000, not 0x80ff0000.) + * """ + */ + + r = (r * 255 + a / 2) / a; + g = (g * 255 + a / 2) / a; + b = (b * 255 + a / 2) / a; + + } + + color->alpha = (1.0 * a) / 0xff; + color->red = (1.0 * r) / 0xff; + color->green = (1.0 * g) / 0xff; + color->blue = (1.0 * b) / 0xff; + + result = true; + + /* Renvoi des conclusions */ + + bad_cairo: + + cairo_destroy(cr); + + empty_surface: + + cairo_surface_destroy(surface); + + g_object_unref(G_OBJECT(area)); + + return result; + +} /****************************************************************************** diff --git a/src/gtkext/easygtk.h b/src/gtkext/easygtk.h index f8c2212..f181d43 100644 --- a/src/gtkext/easygtk.h +++ b/src/gtkext/easygtk.h @@ -25,6 +25,7 @@ #define _GTKEXT_EASYGTK_H +#include <stdbool.h> #include <gtk/gtk.h> @@ -92,6 +93,10 @@ GtkWidget *qck_create_menu_separator(void); + +/* Identifie la couleur de base associée à un style GTK. */ +bool get_color_from_style(const char *, bool, GdkRGBA *); + /* Détermine l'indice d'un composant dans un conteneur GTK. */ gint find_contained_child_index(GtkContainer *, GtkWidget *); |