diff options
author | Tim Janik <timj@gtk.org> | 2000-05-12 15:25:50 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 2000-05-12 15:25:50 +0000 |
commit | 9595c55184932c11e60e840f10f63d73748e3237 (patch) | |
tree | caed3814dcd026830b9cf2c7ff0ee1f5feb48f25 /gtk/gtkhsv.c | |
parent | 5ef1e2e970e949e65ed76656fbe9b1ea4a22fbe3 (diff) | |
download | gtk+-9595c55184932c11e60e840f10f63d73748e3237.tar.gz |
documented necessary changes for 1.4 transition.
Fri May 12 17:13:32 2000 Tim Janik <timj@gtk.org>
* docs/Changes-1.4.txt: documented necessary changes for 1.4 transition.
* gtk/gtktext.c: made the adjustments no-construct args, simply
provide default adjustments.
(gtk_text_destroy): release adjustments.
* gtk/gtkprogressbar.c (gtk_progress_bar_class_init): made the
adjustment argument non-construct.
* gtk/gtkprogress.c (gtk_progress_destroy): release adjustment here,
instead of in finalize.
(gtk_progress_get_text_from_value):
(gtk_progress_get_current_text):
(gtk_progress_set_value):
(gtk_progress_get_percentage_from_value):
(gtk_progress_get_current_percentage):
(gtk_progress_set_percentage):
(gtk_progress_configure): ensure an adjustment is present.
Thu May 11 01:24:08 2000 Tim Janik <timj@gtk.org>
* gtk/gtkcolorsel.[hc]:
* gtk/gtkcolorseldialog.[hc]:
* gtk/gtkhsv.[hc]: major code cleanups, destroy handlers need to chain
their parent implementation, use bit fields for boolean values, don't
create unused widgets, usage of glib types, braces go on their own
lines, function argument alignment, #include directives etc. etc. etc..
* gtk/Makefile.am (gtk_public_h_sources): install gtkhsv.h.
Wed May 10 23:29:52 2000 Tim Janik <timj@gtk.org>
* gtk/gtktoolbar.c (gtk_toolbar_destroy): don't unref a NULL tooltips.
* gtk/gtkfilesel.c (gtk_file_selection_destroy): don't free a cmpl_state
of NULL.
* gtk/gtkcombo.c (gtk_combo_item_destroy): don#t keep references
to freed data.
(gtk_combo_destroy): don't keep a pointer to a destroyed window.
* gtk/gtkmenu.c (gtk_menu_init): reset the menu's toplevel pointer
to NULL when the toplevel is getting destroyed.
(gtk_menu_set_tearoff_state): same here for the tearoff_window.
(gtk_menu_destroy):
(gtk_menu_init): store the information of whether we have to
readd the initial child ref_count during destruction in a new
GtkMenu field needs_destruction_ref_count.
* gtk/gtkviewport.c: SHAME! ok this one is tricky, so i note it
here, those reading: learn from my mistake! ;)
in order for set_?adjustment to support a default adjustemnt if
invoked with an adjustment pointer of NULL, the code read (pseudo):
if (v->adjustment) unref (v->adjustment);
if (!adjustment) adjustment = adjustment_new ();
if (v->adjustment != adjustment) v->adjustment = ref (adjustment);
now imagine the first unref to actually free the old adjustment and
adjustment_new() creating a new adjustment from the very same memory
portion. here, the latter comparision will unintendedly fail, and
all hell breaks loose.
(gtk_viewport_set_hadjustment):
(gtk_viewport_set_vadjustment): reset viewport->?adjustment to NULL
after unreferencing it.
* gtk/gtkcontainer.[hc]: removed toplevel registration
functions: gtk_container_register_toplevel(),
gtk_container_unregister_toplevel() and
gtk_container_get_toplevels() which had wrong semantics
anyways: it didn't reference and copy the list.
* gtk/gtkwindow.c: we take over the container toplevel registration
bussiness now. windows are registered across multiple destructions,
untill they are finalized. the initial implicit reference count
users are holding on windows is removed with the first destruction
though.
(gtk_window_init): ref & sink and set has_user_ref_count, got
rid of gtk_container_register_toplevel() call. add window to
toplevel_list.
(gtk_window_destroy): unref the window if has_user_ref_count
is still set, got rid of call to
gtk_container_unregister_toplevel().
(gtk_window_finalize): remove window from toplevel list.
(gtk_window_list_toplevels): new function to return a newly
created list with referenced toplevels.
(gtk_window_read_rcfiles): use gtk_window_list_toplevels().
* gtk/gtkhscale.c (gtk_hscale_class_init): made the GtkRange
adjustment a non-construct arg.
* gtk/gtkvscale.c (gtk_vscale_class_init): likewise.
* gtk/gtkhscrollbar.c (gtk_vscrollbar_class_init): likewise.
* gtk/gtkvscrollbar.c (gtk_vscrollbar_class_init): likewise.
* gtk/gtkrange.c: added some realized checks.
(gtk_range_destroy): get rid of the h/v adjustments in the
destroy handler instead of finalize. remove timer.
(gtk_range_get_adjustment): demand create adjustment.
* gtk/gtkviewport.c: made h/v adjustment non-construct args.
we simply create them on demand now and get rid of them in
the destroy handler.
(gtk_viewport_destroy): get rid of the h/v adjustments in the
destroy handler instead of finalize.
(gtk_viewport_get_hadjustment):
(gtk_viewport_get_vadjustment):
(gtk_viewport_size_allocate): demand create h/v adjustment
if required.
* gtk/gtkwidget.c (gtk_widget_finalize): duplicate part of the
gtk_widget_real_destroy () functionality.
(gtk_widget_real_destroy): reinitialize with a new style, instead
of setting widget->style to NULL.
Fri May 5 13:02:09 2000 Tim Janik <timj@gtk.org>
* gtk/gtkcalendar.c:
* gtk/gtkbutton.c: ported _get_type() implementation over to
GType, either to preserve memchunks allocation facilities,
or because Gtk+ 1.0 GtkTypeInfo was still being used.
* gtk/gtkobject.[hc]: derive from GObject. ported various functions
over. prepare for ::destroy to be emitted multiple times.
removed reference tracer magic. chain into GObjectClass.shutdown()
to emit ::destroy signal.
* gtk/gtksignal.c: removed assumptions about GTK_TYPE_OBJECT being
fundamental.
* gtk/gtkmain.c: removed gtk_object_post_arg_parsing_init()
cludge.
* gtk/gtksocket.c:
* gtk/gtkplug.c:
* gtk/gtklayout.c:
* gtk/gtklabel.c:
* gtk/gtkargcollector.c:
* gtk/gtkarg.c: various fixups to work with GTK_TYPE_OBJECT
not being a fundamental anymore, and to work with the new
type system (nuked fundamental type varargs clutter).
* gtk/*.c: install finalize handlers in the GObjectClass
part of the class structure.
changed direct GTK_OBJECT()->klass accesses to
GTK_*_GET_CLASS().
changed direct object_class->type accesses to GTK_CLASS_TYPE().
* gtktypeutils.[hc]: use the reserved fundamental ids provided by
GType. made most of the GTK_*() type macros and Gtk* typedefs
simple wrappers around macros and types provided by GType.
most notably, a significant portion of the old API vanished:
GTK_TYPE_MAKE(),
GTK_TYPE_SEQNO(),
GTK_TYPE_FLAT_FIRST, GTK_TYPE_FLAT_LAST,
GTK_TYPE_STRUCTURED_FIRST, GTK_TYPE_STRUCTURED_LAST,
GTK_TYPE_ARGS,
GTK_TYPE_CALLBACK,
GTK_TYPE_C_CALLBACK,
GTK_TYPE_FOREIGN,
GtkTypeQuery,
gtk_type_query(),
gtk_type_set_varargs_type(),
gtk_type_get_varargs_type(),
gtk_type_check_object_cast(),
gtk_type_check_class_cast(),
gtk_type_describe_tree(),
gtk_type_describe_heritage(),
gtk_type_free(),
gtk_type_children_types(),
gtk_type_set_chunk_alloc(),
gtk_type_register_enum(),
gtk_type_register_flags(),
gtk_type_parent_class().
replacements, where available are described in ../docs/Changes-1.4.txt.
implemented compatibility functions for the remaining API.
* configure.in: depend on glib 1.3.1, use gobject module.
Diffstat (limited to 'gtk/gtkhsv.c')
-rw-r--r-- | gtk/gtkhsv.c | 2243 |
1 files changed, 1174 insertions, 1069 deletions
diff --git a/gtk/gtkhsv.c b/gtk/gtkhsv.c index 568a140892..8ca57b66f7 100644 --- a/gtk/gtkhsv.c +++ b/gtk/gtkhsv.c @@ -26,7 +26,12 @@ #include "gtksignal.h" #include "gtkhsv.h" - +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ /* Default width/height */ #define DEFAULT_SIZE 100 @@ -34,34 +39,33 @@ /* Default ring width */ #define DEFAULT_RING_WIDTH 10 - /* Dragging modes */ typedef enum { - DRAG_NONE, - DRAG_H, - DRAG_SV + DRAG_NONE, + DRAG_H, + DRAG_SV } DragMode; /* Private part of the GtkHSV structure */ typedef struct { - /* Color value */ - double h; - double s; - double v; - - /* Size and ring width */ - int size; - int ring_width; - - /* Window for capturing events */ - GdkWindow *window; - - /* GC for drawing */ - GdkGC *gc; - - /* Dragging mode */ - DragMode mode; + /* Color value */ + double h; + double s; + double v; + + /* Size and ring width */ + int size; + int ring_width; + + /* Window for capturing events */ + GdkWindow *window; + + /* GC for drawing */ + GdkGC *gc; + + /* Dragging mode */ + DragMode mode; } HSVPrivate; @@ -69,30 +73,33 @@ typedef struct { /* Signal IDs */ enum { - CHANGED, - LAST_SIGNAL + CHANGED, + LAST_SIGNAL }; -static void gtk_hsv_class_init (GtkHSVClass *class); -static void gtk_hsv_init (GtkHSV *hsv); -static void gtk_hsv_destroy (GtkObject *object); - -static void gtk_hsv_map (GtkWidget *widget); -static void gtk_hsv_unmap (GtkWidget *widget); -static void gtk_hsv_realize (GtkWidget *widget); -static void gtk_hsv_unrealize (GtkWidget *widget); -static void gtk_hsv_size_request (GtkWidget *widget, GtkRequisition *requisition); -static void gtk_hsv_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -static gint gtk_hsv_button_press (GtkWidget *widget, GdkEventButton *event); -static gint gtk_hsv_button_release (GtkWidget *widget, GdkEventButton *event); -static gint gtk_hsv_motion (GtkWidget *widget, GdkEventMotion *event); -static gint gtk_hsv_expose (GtkWidget *widget, GdkEventExpose *event); +static void gtk_hsv_class_init (GtkHSVClass *class); +static void gtk_hsv_init (GtkHSV *hsv); +static void gtk_hsv_destroy (GtkObject *object); +static void gtk_hsv_map (GtkWidget *widget); +static void gtk_hsv_unmap (GtkWidget *widget); +static void gtk_hsv_realize (GtkWidget *widget); +static void gtk_hsv_unrealize (GtkWidget *widget); +static void gtk_hsv_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static void gtk_hsv_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static gint gtk_hsv_button_press (GtkWidget *widget, + GdkEventButton *event); +static gint gtk_hsv_button_release (GtkWidget *widget, + GdkEventButton *event); +static gint gtk_hsv_motion (GtkWidget *widget, + GdkEventMotion *event); +static gint gtk_hsv_expose (GtkWidget *widget, + GdkEventExpose *event); static guint hsv_signals[LAST_SIGNAL]; - static GtkWidgetClass *parent_class; - /** * gtk_hsv_get_type: @@ -106,241 +113,239 @@ static GtkWidgetClass *parent_class; GtkType gtk_hsv_get_type (void) { - static GtkType hsv_type = 0; - - if (!hsv_type) { - static const GtkTypeInfo hsv_info = { - "GtkHSV", - sizeof (GtkHSV), - sizeof (GtkHSVClass), - (GtkClassInitFunc) gtk_hsv_class_init, - (GtkObjectInitFunc) gtk_hsv_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - hsv_type = gtk_type_unique (gtk_widget_get_type (), &hsv_info); - } - - return hsv_type; + static GtkType hsv_type = 0; + + if (!hsv_type) { + static const GtkTypeInfo hsv_info = { + "GtkHSV", + sizeof (GtkHSV), + sizeof (GtkHSVClass), + (GtkClassInitFunc) gtk_hsv_class_init, + (GtkObjectInitFunc) gtk_hsv_init, + NULL, /* reserved_1 */ + NULL, /* reserved_2 */ + (GtkClassInitFunc) NULL + }; + + hsv_type = gtk_type_unique (GTK_TYPE_WIDGET, &hsv_info); + } + + return hsv_type; } /* Class initialization function for the HSV color selector */ static void gtk_hsv_class_init (GtkHSVClass *class) { - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - - parent_class = gtk_type_class (gtk_widget_get_type ()); - - hsv_signals[CHANGED] = - gtk_signal_new ("changed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (GtkHSVClass, changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, hsv_signals, LAST_SIGNAL); - - object_class->destroy = gtk_hsv_destroy; - - widget_class->map = gtk_hsv_map; - widget_class->unmap = gtk_hsv_unmap; - widget_class->realize = gtk_hsv_realize; - widget_class->unrealize = gtk_hsv_unrealize; - widget_class->size_request = gtk_hsv_size_request; - widget_class->size_allocate = gtk_hsv_size_allocate; - widget_class->button_press_event = gtk_hsv_button_press; - widget_class->button_release_event = gtk_hsv_button_release; - widget_class->motion_notify_event = gtk_hsv_motion; - widget_class->expose_event = gtk_hsv_expose; + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + + object_class = (GtkObjectClass *) class; + widget_class = (GtkWidgetClass *) class; + + parent_class = gtk_type_class (GTK_TYPE_WIDGET); + + hsv_signals[CHANGED] = + gtk_signal_new ("changed", + GTK_RUN_FIRST, + GTK_CLASS_TYPE (object_class), + GTK_SIGNAL_OFFSET (GtkHSVClass, changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + gtk_object_class_add_signals (object_class, hsv_signals, LAST_SIGNAL); + + object_class->destroy = gtk_hsv_destroy; + + widget_class->map = gtk_hsv_map; + widget_class->unmap = gtk_hsv_unmap; + widget_class->realize = gtk_hsv_realize; + widget_class->unrealize = gtk_hsv_unrealize; + widget_class->size_request = gtk_hsv_size_request; + widget_class->size_allocate = gtk_hsv_size_allocate; + widget_class->button_press_event = gtk_hsv_button_press; + widget_class->button_release_event = gtk_hsv_button_release; + widget_class->motion_notify_event = gtk_hsv_motion; + widget_class->expose_event = gtk_hsv_expose; } /* Object initialization function for the HSV color selector */ static void gtk_hsv_init (GtkHSV *hsv) { - HSVPrivate *priv; - - priv = g_new0 (HSVPrivate, 1); - hsv->priv = priv; - - GTK_WIDGET_SET_FLAGS (hsv, GTK_NO_WINDOW); - - priv->h = 0.0; - priv->s = 0.0; - priv->v = 0.0; - - priv->size = DEFAULT_SIZE; - priv->ring_width = DEFAULT_RING_WIDTH; + HSVPrivate *priv; + + priv = g_new0 (HSVPrivate, 1); + hsv->priv = priv; + + GTK_WIDGET_SET_FLAGS (hsv, GTK_NO_WINDOW); + + priv->h = 0.0; + priv->s = 0.0; + priv->v = 0.0; + + priv->size = DEFAULT_SIZE; + priv->ring_width = DEFAULT_RING_WIDTH; } /* Destroy handler for the HSV color selector */ static void gtk_hsv_destroy (GtkObject *object) { - GtkHSV *hsv; - HSVPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_HSV (object)); - - hsv = GTK_HSV (object); - priv = hsv->priv; - - g_free (priv); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + GtkHSV *hsv; + + g_return_if_fail (GTK_IS_HSV (object)); + + hsv = GTK_HSV (object); + + if (hsv->priv) + { + g_free (hsv->priv); + hsv->priv = NULL; + } + + GTK_OBJECT_CLASS (parent_class)->destroy (object); } - - /* Default signal handlers */ /* Map handler for the HSV color selector */ static void gtk_hsv_map (GtkWidget *widget) { - GtkHSV *hsv; - HSVPrivate *priv; - - hsv = GTK_HSV (widget); - priv = hsv->priv; - - if (GTK_WIDGET_MAPPED (widget)) - return; - - GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); - - gdk_window_show (priv->window); + GtkHSV *hsv; + HSVPrivate *priv; + + hsv = GTK_HSV (widget); + priv = hsv->priv; + + if (GTK_WIDGET_MAPPED (widget)) + return; + + GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); + + gdk_window_show (priv->window); } /* Unmap handler for the HSV color selector */ static void gtk_hsv_unmap (GtkWidget *widget) { - GtkHSV *hsv; - HSVPrivate *priv; - - hsv = GTK_HSV (widget); - priv = hsv->priv; - - if (!GTK_WIDGET_MAPPED (widget)) - return; - - GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); - - gdk_window_hide (priv->window); + GtkHSV *hsv; + HSVPrivate *priv; + + hsv = GTK_HSV (widget); + priv = hsv->priv; + + if (!GTK_WIDGET_MAPPED (widget)) + return; + + GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); + + gdk_window_hide (priv->window); } /* Realize handler for the HSV color selector */ static void gtk_hsv_realize (GtkWidget *widget) { - GtkHSV *hsv; - HSVPrivate *priv; - GdkWindowAttr attr; - int attr_mask; - GdkWindow *parent_window; - - hsv = GTK_HSV (widget); - priv = hsv->priv; - - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - - /* Create window */ - - attr.window_type = GDK_WINDOW_CHILD; - attr.x = widget->allocation.x; - attr.y = widget->allocation.y; - attr.width = widget->allocation.width; - attr.height = widget->allocation.height; - attr.wclass = GDK_INPUT_ONLY; - attr.event_mask = gtk_widget_get_events (widget); - attr.event_mask |= (GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_POINTER_MOTION_MASK); - - attr_mask = GDK_WA_X | GDK_WA_Y; - - parent_window = gtk_widget_get_parent_window (widget); - - widget->window = parent_window; - gdk_window_ref (widget->window); - - priv->window = gdk_window_new (parent_window, &attr, attr_mask); - gdk_window_set_user_data (priv->window, hsv); - - widget->style = gtk_style_attach (widget->style, widget->window); - - /* Create GC */ - - priv->gc = gdk_gc_new (parent_window); + GtkHSV *hsv; + HSVPrivate *priv; + GdkWindowAttr attr; + int attr_mask; + GdkWindow *parent_window; + + hsv = GTK_HSV (widget); + priv = hsv->priv; + + GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); + + /* Create window */ + + attr.window_type = GDK_WINDOW_CHILD; + attr.x = widget->allocation.x; + attr.y = widget->allocation.y; + attr.width = widget->allocation.width; + attr.height = widget->allocation.height; + attr.wclass = GDK_INPUT_ONLY; + attr.event_mask = gtk_widget_get_events (widget); + attr.event_mask |= (GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_POINTER_MOTION_MASK); + + attr_mask = GDK_WA_X | GDK_WA_Y; + + parent_window = gtk_widget_get_parent_window (widget); + + widget->window = parent_window; + gdk_window_ref (widget->window); + + priv->window = gdk_window_new (parent_window, &attr, attr_mask); + gdk_window_set_user_data (priv->window, hsv); + + widget->style = gtk_style_attach (widget->style, widget->window); + + /* Create GC */ + + priv->gc = gdk_gc_new (parent_window); } /* Unrealize handler for the HSV color selector */ static void gtk_hsv_unrealize (GtkWidget *widget) { - GtkHSV *hsv; - HSVPrivate *priv; - - hsv = GTK_HSV (widget); - priv = hsv->priv; - - gdk_window_set_user_data (priv->window, NULL); - gdk_window_destroy (priv->window); - priv->window = NULL; - - gdk_gc_unref (priv->gc); - priv->gc = NULL; - - if (GTK_WIDGET_CLASS (parent_class)->unrealize) - (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); + GtkHSV *hsv; + HSVPrivate *priv; + + hsv = GTK_HSV (widget); + priv = hsv->priv; + + gdk_window_set_user_data (priv->window, NULL); + gdk_window_destroy (priv->window); + priv->window = NULL; + + gdk_gc_unref (priv->gc); + priv->gc = NULL; + + if (GTK_WIDGET_CLASS (parent_class)->unrealize) + GTK_WIDGET_CLASS (parent_class)->unrealize (widget); } /* Size_request handler for the HSV color selector */ static void -gtk_hsv_size_request (GtkWidget *widget, GtkRequisition *requisition) +gtk_hsv_size_request (GtkWidget *widget, + GtkRequisition *requisition) { - GtkHSV *hsv; - HSVPrivate *priv; - - hsv = GTK_HSV (widget); - priv = hsv->priv; - - requisition->width = priv->size; - requisition->height = priv->size; + GtkHSV *hsv; + HSVPrivate *priv; + + hsv = GTK_HSV (widget); + priv = hsv->priv; + + requisition->width = priv->size; + requisition->height = priv->size; } /* Size_allocate handler for the HSV color selector */ static void -gtk_hsv_size_allocate (GtkWidget *widget, GtkAllocation *allocation) +gtk_hsv_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) { - GtkHSV *hsv; - HSVPrivate *priv; - - hsv = GTK_HSV (widget); - priv = hsv->priv; - - widget->allocation = *allocation; - - if (GTK_WIDGET_REALIZED (widget)) - gdk_window_move_resize (priv->window, - allocation->x, - allocation->y, - allocation->width, - allocation->height); + GtkHSV *hsv; + HSVPrivate *priv; + + hsv = GTK_HSV (widget); + priv = hsv->priv; + + widget->allocation = *allocation; + + if (GTK_WIDGET_REALIZED (widget)) + gdk_window_move_resize (priv->window, + allocation->x, + allocation->y, + allocation->width, + allocation->height); } - /* Utility functions */ @@ -348,588 +353,647 @@ gtk_hsv_size_allocate (GtkWidget *widget, GtkAllocation *allocation) /* Converts from HSV to RGB */ static void -hsv_to_rgb (double *h, double *s, double *v) +hsv_to_rgb (gdouble *h, + gdouble *s, + gdouble *v) { - double hue, saturation, value; - double f, p, q, t; - - if (*s == 0.0) { - *h = *v; - *s = *v; - *v = *v; /* heh */ - } else { - hue = *h * 6.0; - saturation = *s; - value = *v; - - if (hue == 6.0) - hue = 0.0; - - f = hue - (int) hue; - p = value * (1.0 - saturation); - q = value * (1.0 - saturation * f); - t = value * (1.0 - saturation * (1.0 - f)); - - switch ((int) hue) { - case 0: - *h = value; - *s = t; - *v = p; - break; - - case 1: - *h = q; - *s = value; - *v = p; - break; - - case 2: - *h = p; - *s = value; - *v = t; - break; - - case 3: - *h = p; - *s = q; - *v = value; - break; - - case 4: - *h = t; - *s = p; - *v = value; - break; - - case 5: - *h = value; - *s = p; - *v = q; - break; - - default: - g_assert_not_reached (); - } + gdouble hue, saturation, value; + gdouble f, p, q, t; + + if (*s == 0.0) + { + *h = *v; + *s = *v; + *v = *v; /* heh */ + } + else + { + hue = *h * 6.0; + saturation = *s; + value = *v; + + if (hue == 6.0) + hue = 0.0; + + f = hue - (int) hue; + p = value * (1.0 - saturation); + q = value * (1.0 - saturation * f); + t = value * (1.0 - saturation * (1.0 - f)); + + switch ((int) hue) + { + case 0: + *h = value; + *s = t; + *v = p; + break; + + case 1: + *h = q; + *s = value; + *v = p; + break; + + case 2: + *h = p; + *s = value; + *v = t; + break; + + case 3: + *h = p; + *s = q; + *v = value; + break; + + case 4: + *h = t; + *s = p; + *v = value; + break; + + case 5: + *h = value; + *s = p; + *v = q; + break; + + default: + g_assert_not_reached (); } + } } /* Converts from RGB to HSV */ static void -rgb_to_hsv (double *r, double *g, double *b) +rgb_to_hsv (gdouble *r, + gdouble *g, + gdouble *b) { - double red, green, blue; - double h, s, v; - double min, max; - double delta; - - red = *r; - green = *g; - blue = *b; - - h = 0.0; - - if (red > green) { - if (red > blue) - max = red; - else - max = blue; - - if (green < blue) - min = green; - else - min = blue; - } else { - if (green > blue) - max = green; - else - max = blue; - - if (red < blue) - min = red; - else - min = blue; - } - - v = max; - - if (max != 0.0) - s = (max - min) / max; - else - s = 0.0; - - if (s == 0.0) - h = 0.0; - else { - delta = max - min; - - if (red == max) - h = (green - blue) / delta; - else if (green == max) - h = 2 + (blue - red) / delta; - else if (blue == max) - h = 4 + (red - green) / delta; - - h /= 6.0; - - if (h < 0.0) - h += 1.0; - else if (h > 1.0) - h -= 1.0; - } - - *r = h; - *g = s; - *b = v; + gdouble red, green, blue; + gdouble h, s, v; + gdouble min, max; + gdouble delta; + + red = *r; + green = *g; + blue = *b; + + h = 0.0; + + if (red > green) + { + if (red > blue) + max = red; + else + max = blue; + + if (green < blue) + min = green; + else + min = blue; + } + else + { + if (green > blue) + max = green; + else + max = blue; + + if (red < blue) + min = red; + else + min = blue; + } + + v = max; + + if (max != 0.0) + s = (max - min) / max; + else + s = 0.0; + + if (s == 0.0) + h = 0.0; + else + { + delta = max - min; + + if (red == max) + h = (green - blue) / delta; + else if (green == max) + h = 2 + (blue - red) / delta; + else if (blue == max) + h = 4 + (red - green) / delta; + + h /= 6.0; + + if (h < 0.0) + h += 1.0; + else if (h > 1.0) + h -= 1.0; + } + + *r = h; + *g = s; + *b = v; } /* Computes the vertices of the saturation/value triangle */ static void -compute_triangle (GtkHSV *hsv, int *hx, int *hy, int *sx, int *sy, int *vx, int *vy) +compute_triangle (GtkHSV *hsv, + gint *hx, + gint *hy, + gint *sx, + gint *sy, + gint *vx, + gint *vy) { - HSVPrivate *priv; - double center; - double inner, outer; - double angle; - - priv = hsv->priv; - - center = priv->size / 2.0; - outer = priv->size / 2.0; - inner = outer - priv->ring_width; - angle = priv->h * 2.0 * M_PI; - - *hx = floor (center + cos (angle) * inner + 0.5); - *hy = floor (center - sin (angle) * inner + 0.5); - *sx = floor (center + cos (angle + 2.0 * M_PI / 3.0) * inner + 0.5); - *sy = floor (center - sin (angle + 2.0 * M_PI / 3.0) * inner + 0.5); - *vx = floor (center + cos (angle + 4.0 * M_PI / 3.0) * inner + 0.5); - *vy = floor (center - sin (angle + 4.0 * M_PI / 3.0) * inner + 0.5); + HSVPrivate *priv; + gdouble center; + gdouble inner, outer; + gdouble angle; + + priv = hsv->priv; + + center = priv->size / 2.0; + outer = priv->size / 2.0; + inner = outer - priv->ring_width; + angle = priv->h * 2.0 * M_PI; + + *hx = floor (center + cos (angle) * inner + 0.5); + *hy = floor (center - sin (angle) * inner + 0.5); + *sx = floor (center + cos (angle + 2.0 * M_PI / 3.0) * inner + 0.5); + *sy = floor (center - sin (angle + 2.0 * M_PI / 3.0) * inner + 0.5); + *vx = floor (center + cos (angle + 4.0 * M_PI / 3.0) * inner + 0.5); + *vy = floor (center - sin (angle + 4.0 * M_PI / 3.0) * inner + 0.5); } /* Computes whether a point is inside the hue ring */ static gboolean -is_in_ring (GtkHSV *hsv, double x, double y) +is_in_ring (GtkHSV *hsv, + gdouble x, + gdouble y) { - HSVPrivate *priv; - double dx, dy, dist; - double center, inner, outer; - - priv = hsv->priv; - - center = priv->size / 2.0; - outer = priv->size / 2.0; - inner = outer - priv->ring_width; - - dx = x - center; - dy = center - y; - dist = dx * dx + dy * dy; - - return (dist >= inner * inner && dist <= outer * outer); + HSVPrivate *priv; + gdouble dx, dy, dist; + gdouble center, inner, outer; + + priv = hsv->priv; + + center = priv->size / 2.0; + outer = priv->size / 2.0; + inner = outer - priv->ring_width; + + dx = x - center; + dy = center - y; + dist = dx * dx + dy * dy; + + return (dist >= inner * inner && dist <= outer * outer); } /* Computes a saturation/value pair based on the mouse coordinates */ static void -compute_sv (GtkHSV *hsv, double x, double y, double *s, double *v) +compute_sv (GtkHSV *hsv, + gdouble x, + gdouble y, + gdouble *s, + gdouble *v) { - HSVPrivate *priv; - int ihx, ihy, isx, isy, ivx, ivy; - double hx, hy, sx, sy, vx, vy; - double center; - - priv = hsv->priv; - - compute_triangle (hsv, &ihx, &ihy, &isx, &isy, &ivx, &ivy); - center = priv->size / 2.0; - hx = ihx - center; - hy = center - ihy; - sx = isx - center; - sy = center - isy; - vx = ivx - center; - vy = center - ivy; - x -= center; - y = center - y; - - if (vx * (x - sx) + vy * (y - sy) < 0.0) { - *s = 1.0; - *v = (((x - sx) * (hx - sx) + (y - sy) * (hy-sy)) - / ((hx - sx) * (hx - sx) + (hy - sy) * (hy - sy))); - - if (*v < 0.0) - *v = 0.0; - else if (*v > 1.0) - *v = 1.0; - } else if (hx * (x - sx) + hy * (y - sy) < 0.0) { - *s = 0.0; - *v = (((x - sx) * (vx - sx) + (y - sy) * (vy - sy)) - / ((vx - sx) * (vx - sx) + (vy - sy) * (vy - sy))); - - if (*v < 0.0) - *v = 0.0; - else if (*v > 1.0) - *v = 1.0; - } else if (sx * (x - hx) + sy * (y - hy) < 0.0) { - *v = 1.0; - *s = (((x - vx) * (hx - vx) + (y - vy) * (hy - vy)) / - ((hx - vx) * (hx - vx) + (hy - vy) * (hy - vy))); - - if (*s < 0.0) - *s = 0.0; - else if (*s > 1.0) - *s = 1.0; - } else { - *v = (((x - sx) * (hy - vy) - (y - sy) * (hx - vx)) - / ((vx - sx) * (hy - vy) - (vy - sy) * (hx - vx))); - - if (*v<= 0.0) { - *v = 0.0; - *s = 0.0; - } else { - if (*v > 1.0) - *v = 1.0; - - *s = (y - sy - *v * (vy - sy)) / (*v * (hy - vy)); - if (*s < 0.0) - *s = 0.0; - else if (*s > 1.0) - *s = 1.0; - } + HSVPrivate *priv; + int ihx, ihy, isx, isy, ivx, ivy; + double hx, hy, sx, sy, vx, vy; + double center; + + priv = hsv->priv; + + compute_triangle (hsv, &ihx, &ihy, &isx, &isy, &ivx, &ivy); + center = priv->size / 2.0; + hx = ihx - center; + hy = center - ihy; + sx = isx - center; + sy = center - isy; + vx = ivx - center; + vy = center - ivy; + x -= center; + y = center - y; + + if (vx * (x - sx) + vy * (y - sy) < 0.0) + { + *s = 1.0; + *v = (((x - sx) * (hx - sx) + (y - sy) * (hy-sy)) + / ((hx - sx) * (hx - sx) + (hy - sy) * (hy - sy))); + + if (*v < 0.0) + *v = 0.0; + else if (*v > 1.0) + *v = 1.0; + } + else if (hx * (x - sx) + hy * (y - sy) < 0.0) + { + *s = 0.0; + *v = (((x - sx) * (vx - sx) + (y - sy) * (vy - sy)) + / ((vx - sx) * (vx - sx) + (vy - sy) * (vy - sy))); + + if (*v < 0.0) + *v = 0.0; + else if (*v > 1.0) + *v = 1.0; + } + else if (sx * (x - hx) + sy * (y - hy) < 0.0) + { + *v = 1.0; + *s = (((x - vx) * (hx - vx) + (y - vy) * (hy - vy)) / + ((hx - vx) * (hx - vx) + (hy - vy) * (hy - vy))); + + if (*s < 0.0) + *s = 0.0; + else if (*s > 1.0) + *s = 1.0; + } + else + { + *v = (((x - sx) * (hy - vy) - (y - sy) * (hx - vx)) + / ((vx - sx) * (hy - vy) - (vy - sy) * (hx - vx))); + + if (*v<= 0.0) + { + *v = 0.0; + *s = 0.0; + } + else + { + if (*v > 1.0) + *v = 1.0; + + *s = (y - sy - *v * (vy - sy)) / (*v * (hy - vy)); + if (*s < 0.0) + *s = 0.0; + else if (*s > 1.0) + *s = 1.0; } + } } /* Computes whether a point is inside the saturation/value triangle */ static gboolean -is_in_triangle (GtkHSV *hsv, double x, double y) +is_in_triangle (GtkHSV *hsv, + gdouble x, + gdouble y) { - int hx, hy, sx, sy, vx, vy; - double det, s, v; - - compute_triangle (hsv, &hx, &hy, &sx, &sy, &vx, &vy); - - det = (vx - sx) * (hy - sy) - (vy - sy) * (hx - sx); - - s = ((x - sx) * (hy - sy) - (y - sy) * (hx - sx)) / det; - v = ((vx - sx) * (y - sy) - (vy - sy) * (x - sx)) / det; - - return (s >= 0.0 && v >= 0.0 && s + v <= 1.0); + int hx, hy, sx, sy, vx, vy; + double det, s, v; + + compute_triangle (hsv, &hx, &hy, &sx, &sy, &vx, &vy); + + det = (vx - sx) * (hy - sy) - (vy - sy) * (hx - sx); + + s = ((x - sx) * (hy - sy) - (y - sy) * (hx - sx)) / det; + v = ((vx - sx) * (y - sy) - (vy - sy) * (x - sx)) / det; + + return (s >= 0.0 && v >= 0.0 && s + v <= 1.0); } /* Computes a value based on the mouse coordinates */ static double -compute_v (GtkHSV *hsv, double x, double y) +compute_v (GtkHSV *hsv, + gdouble x, + gdouble y) { - HSVPrivate *priv; - double center; - double dx, dy; - double angle; - - priv = hsv->priv; - - center = priv->size / 2.0; - dx = x - center; - dy = center - y; - - angle = atan2 (dy, dx); - if (angle < 0.0) - angle += 2.0 * M_PI; - - return angle / (2.0 * M_PI); + HSVPrivate *priv; + double center; + double dx, dy; + double angle; + + priv = hsv->priv; + + center = priv->size / 2.0; + dx = x - center; + dy = center - y; + + angle = atan2 (dy, dx); + if (angle < 0.0) + angle += 2.0 * M_PI; + + return angle / (2.0 * M_PI); } - - /* Event handlers */ static void -set_cross_grab (GtkHSV *hsv, guint32 time) +set_cross_grab (GtkHSV *hsv, + guint32 time) { - HSVPrivate *priv; - GdkCursor *cursor; - - priv = hsv->priv; - - cursor = gdk_cursor_new (GDK_CROSSHAIR); - gdk_pointer_grab (priv->window, FALSE, - (GDK_POINTER_MOTION_MASK - | GDK_POINTER_MOTION_HINT_MASK - | GDK_BUTTON_RELEASE_MASK), - NULL, - cursor, - time); - gdk_cursor_destroy (cursor); - + HSVPrivate *priv; + GdkCursor *cursor; + + priv = hsv->priv; + + cursor = gdk_cursor_new (GDK_CROSSHAIR); + gdk_pointer_grab (priv->window, FALSE, + (GDK_POINTER_MOTION_MASK + | GDK_POINTER_MOTION_HINT_MASK + | GDK_BUTTON_RELEASE_MASK), + NULL, + cursor, + time); + gdk_cursor_destroy (cursor); } /* Button_press_event handler for the HSV color selector */ static gint -gtk_hsv_button_press (GtkWidget *widget, GdkEventButton *event) +gtk_hsv_button_press (GtkWidget *widget, + GdkEventButton *event) { - GtkHSV *hsv; - HSVPrivate *priv; - double x, y; - - hsv = GTK_HSV (widget); - priv = hsv->priv; - - if (priv->mode != DRAG_NONE || event->button != 1) - return FALSE; - - x = event->x; - y = event->y; - - if (is_in_ring (hsv, x, y)) { - priv->mode = DRAG_H; - set_cross_grab (hsv, event->time); - - gtk_hsv_set_color (hsv, - compute_v (hsv, x, y), - priv->s, - priv->v); - - return TRUE; - } - - if (is_in_triangle (hsv, x, y)) { - double s, v; - - priv->mode = DRAG_SV; - set_cross_grab (hsv, event->time); - - compute_sv (hsv, x, y, &s, &v); - gtk_hsv_set_color (hsv, priv->h, s, v); - return TRUE; - } - - return FALSE; + GtkHSV *hsv; + HSVPrivate *priv; + double x, y; + + hsv = GTK_HSV (widget); + priv = hsv->priv; + + if (priv->mode != DRAG_NONE || event->button != 1) + return FALSE; + + x = event->x; + y = event->y; + + if (is_in_ring (hsv, x, y)) + { + priv->mode = DRAG_H; + set_cross_grab (hsv, event->time); + + gtk_hsv_set_color (hsv, + compute_v (hsv, x, y), + priv->s, + priv->v); + + return TRUE; + } + + if (is_in_triangle (hsv, x, y)) + { + gdouble s, v; + + priv->mode = DRAG_SV; + set_cross_grab (hsv, event->time); + + compute_sv (hsv, x, y, &s, &v); + gtk_hsv_set_color (hsv, priv->h, s, v); + return TRUE; + } + + return FALSE; } /* Button_release_event handler for the HSV color selector */ static gint -gtk_hsv_button_release (GtkWidget *widget, GdkEventButton *event) +gtk_hsv_button_release (GtkWidget *widget, + GdkEventButton *event) { - GtkHSV *hsv; - HSVPrivate *priv; - DragMode mode; - double x, y; - - hsv = GTK_HSV (widget); - priv = hsv->priv; - - if (priv->mode == DRAG_NONE || event->button != 1) - return FALSE; - - /* Set the drag mode to DRAG_NONE so that signal handlers for "catched" - * can see that this is the final color state. - */ - - mode = priv->mode; - priv->mode = DRAG_NONE; - - x = event->x; - y = event->y; - - if (mode == DRAG_H) - gtk_hsv_set_color (hsv, compute_v (hsv, x, y), priv->s, priv->v); - else if (mode == DRAG_SV) { - double s, v; - - compute_sv (hsv, x, y, &s, &v); - gtk_hsv_set_color (hsv, priv->h, s, v); - } else - g_assert_not_reached (); - - gdk_pointer_ungrab (event->time); - - return TRUE; + GtkHSV *hsv; + HSVPrivate *priv; + DragMode mode; + gdouble x, y; + + hsv = GTK_HSV (widget); + priv = hsv->priv; + + if (priv->mode == DRAG_NONE || event->button != 1) + return FALSE; + + /* Set the drag mode to DRAG_NONE so that signal handlers for "catched" + * can see that this is the final color state. + */ + + mode = priv->mode; + priv->mode = DRAG_NONE; + + x = event->x; + y = event->y; + + if (mode == DRAG_H) + gtk_hsv_set_color (hsv, compute_v (hsv, x, y), priv->s, priv->v); + else if (mode == DRAG_SV) { + double s, v; + + compute_sv (hsv, x, y, &s, &v); + gtk_hsv_set_color (hsv, priv->h, s, v); + } else + g_assert_not_reached (); + + gdk_pointer_ungrab (event->time); + + return TRUE; } /* Motion_notify_event handler for the HSV color selector */ static gint -gtk_hsv_motion (GtkWidget *widget, GdkEventMotion *event) +gtk_hsv_motion (GtkWidget *widget, + GdkEventMotion *event) { - GtkHSV *hsv; - HSVPrivate *priv; - double x, y; - gint ix, iy; - GdkModifierType mods; - - hsv = GTK_HSV (widget); - priv = hsv->priv; - - if (priv->mode == DRAG_NONE) - return FALSE; - - if (event->is_hint) { - gdk_window_get_pointer (priv->window, &ix, &iy, &mods); - x = ix; - y = iy; - } else { - x = event->x; - y = event->y; - } - - if (priv->mode == DRAG_H) { - gtk_hsv_set_color (hsv, compute_v (hsv, x, y), priv->s, priv->v); - return TRUE; - } else if (priv->mode == DRAG_SV) { - double s, v; - - compute_sv (hsv, x, y, &s, &v); - gtk_hsv_set_color (hsv, priv->h, s, v); - return TRUE; - } - - g_assert_not_reached (); - return FALSE; + GtkHSV *hsv; + HSVPrivate *priv; + double x, y; + gint ix, iy; + GdkModifierType mods; + + hsv = GTK_HSV (widget); + priv = hsv->priv; + + if (priv->mode == DRAG_NONE) + return FALSE; + + if (event->is_hint) + { + gdk_window_get_pointer (priv->window, &ix, &iy, &mods); + x = ix; + y = iy; + } + else + { + x = event->x; + y = event->y; + } + + if (priv->mode == DRAG_H) + { + gtk_hsv_set_color (hsv, compute_v (hsv, x, y), priv->s, priv->v); + return TRUE; + } + else if (priv->mode == DRAG_SV) + { + double s, v; + + compute_sv (hsv, x, y, &s, &v); + gtk_hsv_set_color (hsv, priv->h, s, v); + return TRUE; + } + + g_assert_not_reached (); + return FALSE; } - /* Redrawing */ /* Paints the hue ring */ static void -paint_ring (GtkHSV *hsv, GdkDrawable *drawable, int x, int y, int width, int height) +paint_ring (GtkHSV *hsv, + GdkDrawable *drawable, + gint x, + gint y, + gint width, + gint height) { - HSVPrivate *priv; - int xx, yy; - double dx, dy, dist; - double center; - double inner, outer; - guchar *buf, *p; - double angle; - double hue; - double r, g, b; - GdkBitmap *mask; - GdkGC *gc; - GdkColor color; - - priv = hsv->priv; - - center = priv->size / 2.0; - - outer = priv->size / 2.0; - inner = outer - priv->ring_width; - - /* Paint the ring */ - - buf = g_new (guchar, width * height * 3); - - for (yy = 0; yy < height; yy++) { - p = buf + yy * width * 3; - - dy = -(yy + y - center); - - for (xx = 0; xx < width; xx++) { - dx = xx + x - center; - - dist = dx * dx + dy * dy; - if (dist < (inner * inner) || dist > (outer * outer)) { - *p++ = 0; - *p++ = 0; - *p++ = 0; - continue; - } - - angle = atan2 (dy, dx); - if (angle < 0.0) - angle += 2.0 * M_PI; - - hue = angle / (2.0 * M_PI); - - r = hue; - g = 1.0; - b = 1.0; - hsv_to_rgb (&r, &g, &b); - - *p++ = floor (r * 255 + 0.5); - *p++ = floor (g * 255 + 0.5); - *p++ = floor (b * 255 + 0.5); - } + HSVPrivate *priv; + int xx, yy; + gdouble dx, dy, dist; + gdouble center; + gdouble inner, outer; + guchar *buf, *p; + gdouble angle; + gdouble hue; + gdouble r, g, b; + GdkBitmap *mask; + GdkGC *gc; + GdkColor color; + + priv = hsv->priv; + + center = priv->size / 2.0; + + outer = priv->size / 2.0; + inner = outer - priv->ring_width; + + /* Paint the ring */ + + buf = g_new (guchar, width * height * 3); + + for (yy = 0; yy < height; yy++) + { + p = buf + yy * width * 3; + + dy = -(yy + y - center); + + for (xx = 0; xx < width; xx++) + { + dx = xx + x - center; + + dist = dx * dx + dy * dy; + if (dist < (inner * inner) || dist > (outer * outer)) + { + *p++ = 0; + *p++ = 0; + *p++ = 0; + continue; + } + + angle = atan2 (dy, dx); + if (angle < 0.0) + angle += 2.0 * M_PI; + + hue = angle / (2.0 * M_PI); + + r = hue; + g = 1.0; + b = 1.0; + hsv_to_rgb (&r, &g, &b); + + *p++ = floor (r * 255 + 0.5); + *p++ = floor (g * 255 + 0.5); + *p++ = floor (b * 255 + 0.5); } - - /* Create clipping mask */ - - mask = gdk_pixmap_new (NULL, width, height, 1); - gc = gdk_gc_new (mask); - - color.pixel = 0; - gdk_gc_set_foreground (gc, &color); - gdk_draw_rectangle (mask, gc, TRUE, - 0, 0, width, height); - - - color.pixel = 1; - gdk_gc_set_foreground (gc, &color); - gdk_draw_arc (mask, gc, TRUE, - -x, -y, - priv->size - 1, priv->size - 1, - 0, 360 * 64); - - color.pixel = 0; - gdk_gc_set_foreground (gc, &color); - gdk_draw_arc (mask, gc, TRUE, - -x + priv->ring_width - 1, -y + priv->ring_width - 1, - priv->size - 2 * priv->ring_width + 1, priv->size - 2 * priv->ring_width + 1, - 0, 360 * 64); - - gdk_gc_unref (gc); - - gdk_gc_set_clip_mask (priv->gc, mask); - gdk_gc_set_clip_origin (priv->gc, 0, 0); - - /* Draw ring */ - - gdk_draw_rgb_image_dithalign (drawable, priv->gc, 0, 0, width, height, - GDK_RGB_DITHER_MAX, - buf, - width * 3, - x, y); - - /* Draw value marker */ - - r = priv->h; - g = 1.0; - b = 1.0; - hsv_to_rgb (&r, &g, &b); - - if (INTENSITY (r, g, b) > 0.5) - gdk_rgb_gc_set_foreground (priv->gc, 0x000000); - else - gdk_rgb_gc_set_foreground (priv->gc, 0xffffff); - - gdk_draw_line (drawable, priv->gc, - -x + center, -y + center, - -x + center + cos (priv->h * 2.0 * M_PI) * center, - -y + center - sin (priv->h * 2.0 * M_PI) * center); - - gdk_gc_set_clip_mask (priv->gc, NULL); - gdk_bitmap_unref (mask); - - g_free (buf); - - /* Draw ring outline */ - - gdk_rgb_gc_set_foreground (priv->gc, 0x000000); - - gdk_draw_arc (drawable, priv->gc, FALSE, - -x, -y, - priv->size - 1, priv->size - 1, - 0, 360 * 64); - gdk_draw_arc (drawable, priv->gc, FALSE, - -x + priv->ring_width - 1, -y + priv->ring_width - 1, - priv->size - 2 * priv->ring_width + 1, priv->size - 2 * priv->ring_width + 1, - 0, 360 * 64); + } + + /* Create clipping mask */ + + mask = gdk_pixmap_new (NULL, width, height, 1); + gc = gdk_gc_new (mask); + + color.pixel = 0; + gdk_gc_set_foreground (gc, &color); + gdk_draw_rectangle (mask, gc, TRUE, + 0, 0, width, height); + + + color.pixel = 1; + gdk_gc_set_foreground (gc, &color); + gdk_draw_arc (mask, gc, TRUE, + -x, -y, + priv->size - 1, priv->size - 1, + 0, 360 * 64); + + color.pixel = 0; + gdk_gc_set_foreground (gc, &color); + gdk_draw_arc (mask, gc, TRUE, + -x + priv->ring_width - 1, -y + priv->ring_width - 1, + priv->size - 2 * priv->ring_width + 1, priv->size - 2 * priv->ring_width + 1, + 0, 360 * 64); + + gdk_gc_unref (gc); + + gdk_gc_set_clip_mask (priv->gc, mask); + gdk_gc_set_clip_origin (priv->gc, 0, 0); + + /* Draw ring */ + + gdk_draw_rgb_image_dithalign (drawable, priv->gc, 0, 0, width, height, + GDK_RGB_DITHER_MAX, + buf, + width * 3, + x, y); + + /* Draw value marker */ + + r = priv->h; + g = 1.0; + b = 1.0; + hsv_to_rgb (&r, &g, &b); + + if (INTENSITY (r, g, b) > 0.5) + gdk_rgb_gc_set_foreground (priv->gc, 0x000000); + else + gdk_rgb_gc_set_foreground (priv->gc, 0xffffff); + + gdk_draw_line (drawable, priv->gc, + -x + center, -y + center, + -x + center + cos (priv->h * 2.0 * M_PI) * center, + -y + center - sin (priv->h * 2.0 * M_PI) * center); + + gdk_gc_set_clip_mask (priv->gc, NULL); + gdk_bitmap_unref (mask); + + g_free (buf); + + /* Draw ring outline */ + + gdk_rgb_gc_set_foreground (priv->gc, 0x000000); + + gdk_draw_arc (drawable, priv->gc, FALSE, + -x, -y, + priv->size - 1, priv->size - 1, + 0, 360 * 64); + gdk_draw_arc (drawable, priv->gc, FALSE, + -x + priv->ring_width - 1, -y + priv->ring_width - 1, + priv->size - 2 * priv->ring_width + 1, priv->size - 2 * priv->ring_width + 1, + 0, 360 * 64); } /* Converts an HSV triplet to an integer RGB triplet */ static void -get_color (double h, double s, double v, int *r, int *g, int *b) +get_color (gdouble h, + gdouble s, + gdouble v, + gint *r, + gint *g, + gint *b) { - hsv_to_rgb (&h, &s, &v); - - *r = floor (h * 255 + 0.5); - *g = floor (s * 255 + 0.5); - *b = floor (v * 255 + 0.5); + hsv_to_rgb (&h, &s, &v); + + *r = floor (h * 255 + 0.5); + *g = floor (s * 255 + 0.5); + *b = floor (v * 255 + 0.5); } #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t)) @@ -940,250 +1004,273 @@ get_color (double h, double s, double v, int *r, int *g, int *b) /* Paints the HSV triangle */ static void -paint_triangle (GtkHSV *hsv, GdkDrawable *drawable, int x, int y, int width, int height) +paint_triangle (GtkHSV *hsv, + GdkDrawable *drawable, + gint x, + gint y, + gint width, + gint height) { - HSVPrivate *priv; - int hx, hy, sx, sy, vx, vy; /* HSV vertices */ - int x1, y1, r1, g1, b1; /* First vertex in scanline order */ - int x2, y2, r2, g2, b2; /* Second vertex */ - int x3, y3, r3, g3, b3; /* Third vertex */ - int t; - guchar *buf, *p; - int xl, xr, rl, rr, gl, gr, bl, br; /* Scanline data */ - int xx, yy; - GdkBitmap *mask; - GdkGC *gc; - GdkColor color; - GdkPoint points[3]; - double r, g, b; - - priv = hsv->priv; - - /* Compute triangle's vertices */ - - compute_triangle (hsv, &hx, &hy, &sx, &sy, &vx, &vy); - - x1 = hx; - y1 = hy; - get_color (priv->h, 1.0, 1.0, &r1, &g1, &b1); - - x2 = sx; - y2 = sy; - get_color (priv->h, 1.0, 0.0, &r2, &g2, &b2); - - x3 = vx; - y3 = vy; - get_color (priv->h, 0.0, 1.0, &r3, &g3, &b3); - - if (y2 > y3) { - SWAP (x2, x3, t); - SWAP (y2, y3, t); - SWAP (r2, r3, t); - SWAP (g2, g3, t); - SWAP (b2, b3, t); - } - - if (y1 > y3) { - SWAP (x1, x3, t); - SWAP (y1, y3, t); - SWAP (r1, r3, t); - SWAP (g1, g3, t); - SWAP (b1, b3, t); - } - - if (y1 > y2) { - SWAP (x1, x2, t); - SWAP (y1, y2, t); - SWAP (r1, r2, t); - SWAP (g1, g2, t); - SWAP (b1, b2, t); - } - - /* Shade the triangle */ - - buf = g_new (guchar, width * height * 3); - - for (yy = 0; yy < height; yy++) { - p = buf + yy * width * 3; - - if (yy + y < y1 || yy + y > y3) - for (xx = 0; xx < width; xx++) { - *p++ = 0; - *p++ = 0; - *p++ = 0; - } - else { - if (yy + y < y2) { - xl = LERP (x1, x2, y1, y2, yy + y); - - rl = LERP (r1, r2, y1, y2, yy + y); - gl = LERP (g1, g2, y1, y2, yy + y); - bl = LERP (b1, b2, y1, y2, yy + y); - } else { - xl = LERP (x2, x3, y2, y3, yy + y); - - rl = LERP (r2, r3, y2, y3, yy + y); - gl = LERP (g2, g3, y2, y3, yy + y); - bl = LERP (b2, b3, y2, y3, yy + y); - } - - xr = LERP (x1, x3, y1, y3, yy + y); - - rr = LERP (r1, r3, y1, y3, yy + y); - gr = LERP (g1, g3, y1, y3, yy + y); - br = LERP (b1, b3, y1, y3, yy + y); - - if (xl > xr) { - SWAP (xl, xr, t); - SWAP (rl, rr, t); - SWAP (gl, gr, t); - SWAP (bl, br, t); - } - - for (xx = 0; xx < width; xx++) { - if (xx + x < xl || xx + x > xr) { - *p++ = 0; - *p++ = 0; - *p++ = 0; - } else { - *p++ = LERP (rl, rr, xl, xr, xx + x); - *p++ = LERP (gl, gr, xl, xr, xx + x); - *p++ = LERP (bl, br, xl, xr, xx + x); - } - } - } - } - - /* Create clipping mask */ - - mask = gdk_pixmap_new (NULL, width, height, 1); - gc = gdk_gc_new (mask); - - color.pixel = 0; - gdk_gc_set_foreground (gc, &color); - gdk_draw_rectangle (mask, gc, TRUE, - 0, 0, width, height); - - color.pixel = 1; - gdk_gc_set_foreground (gc, &color); - - points[0].x = x1 - x; - points[0].y = y1 - y; - points[1].x = x2 - x; - points[1].y = y2 - y; - points[2].x = x3 - x; - points[2].y = y3 - y; - gdk_draw_polygon (mask, gc, TRUE, points, 3); - - gdk_gc_unref (gc); - - gdk_gc_set_clip_mask (priv->gc, mask); - gdk_gc_set_clip_origin (priv->gc, 0, 0); - - /* Draw triangle */ - - gdk_draw_rgb_image_dithalign (drawable, priv->gc, 0, 0, width, height, - GDK_RGB_DITHER_MAX, - buf, - width * 3, - x, y); - - gdk_gc_set_clip_mask (priv->gc, NULL); - gdk_bitmap_unref (mask); - - g_free (buf); - - /* Draw triangle outline */ - - gdk_rgb_gc_set_foreground (priv->gc, 0x000000); - - gdk_draw_polygon (drawable, priv->gc, FALSE, points, 3); - - /* Draw value marker */ - - xx = floor (sx + (vx - sx) * priv->v + (hx - vx) * priv->s * priv->v + 0.5); - yy = floor (sy + (vy - sy) * priv->v + (hy - vy) * priv->s * priv->v + 0.5); - - r = priv->h; - g = priv->s; - b = priv->v; - hsv_to_rgb (&r, &g, &b); - - if (INTENSITY (r, g, b) > 0.5) - gdk_rgb_gc_set_foreground (priv->gc, 0x000000); + HSVPrivate *priv; + gint hx, hy, sx, sy, vx, vy; /* HSV vertices */ + gint x1, y1, r1, g1, b1; /* First vertex in scanline order */ + gint x2, y2, r2, g2, b2; /* Second vertex */ + gint x3, y3, r3, g3, b3; /* Third vertex */ + gint t; + guchar *buf, *p; + gint xl, xr, rl, rr, gl, gr, bl, br; /* Scanline data */ + gint xx, yy; + GdkBitmap *mask; + GdkGC *gc; + GdkColor color; + GdkPoint points[3]; + gdouble r, g, b; + + priv = hsv->priv; + + /* Compute triangle's vertices */ + + compute_triangle (hsv, &hx, &hy, &sx, &sy, &vx, &vy); + + x1 = hx; + y1 = hy; + get_color (priv->h, 1.0, 1.0, &r1, &g1, &b1); + + x2 = sx; + y2 = sy; + get_color (priv->h, 1.0, 0.0, &r2, &g2, &b2); + + x3 = vx; + y3 = vy; + get_color (priv->h, 0.0, 1.0, &r3, &g3, &b3); + + if (y2 > y3) + { + SWAP (x2, x3, t); + SWAP (y2, y3, t); + SWAP (r2, r3, t); + SWAP (g2, g3, t); + SWAP (b2, b3, t); + } + + if (y1 > y3) + { + SWAP (x1, x3, t); + SWAP (y1, y3, t); + SWAP (r1, r3, t); + SWAP (g1, g3, t); + SWAP (b1, b3, t); + } + + if (y1 > y2) + { + SWAP (x1, x2, t); + SWAP (y1, y2, t); + SWAP (r1, r2, t); + SWAP (g1, g2, t); + SWAP (b1, b2, t); + } + + /* Shade the triangle */ + + buf = g_new (guchar, width * height * 3); + + for (yy = 0; yy < height; yy++) + { + p = buf + yy * width * 3; + + if (yy + y < y1 || yy + y > y3) + for (xx = 0; xx < width; xx++) + { + *p++ = 0; + *p++ = 0; + *p++ = 0; + } + else { + if (yy + y < y2) + { + xl = LERP (x1, x2, y1, y2, yy + y); + + rl = LERP (r1, r2, y1, y2, yy + y); + gl = LERP (g1, g2, y1, y2, yy + y); + bl = LERP (b1, b2, y1, y2, yy + y); + } else - gdk_rgb_gc_set_foreground (priv->gc, 0xffffff); - - gdk_draw_arc (drawable, priv->gc, FALSE, - xx - 3, yy - 3, - 6, 6, - 0, 360 * 64); - gdk_draw_arc (drawable, priv->gc, FALSE, - xx - 2, yy - 2, - 4, 4, - 0, 360 * 64); + { + xl = LERP (x2, x3, y2, y3, yy + y); + + rl = LERP (r2, r3, y2, y3, yy + y); + gl = LERP (g2, g3, y2, y3, yy + y); + bl = LERP (b2, b3, y2, y3, yy + y); + } + + xr = LERP (x1, x3, y1, y3, yy + y); + + rr = LERP (r1, r3, y1, y3, yy + y); + gr = LERP (g1, g3, y1, y3, yy + y); + br = LERP (b1, b3, y1, y3, yy + y); + + if (xl > xr) + { + SWAP (xl, xr, t); + SWAP (rl, rr, t); + SWAP (gl, gr, t); + SWAP (bl, br, t); + } + + for (xx = 0; xx < width; xx++) + { + if (xx + x < xl || xx + x > xr) + { + *p++ = 0; + *p++ = 0; + *p++ = 0; + } + else + { + *p++ = LERP (rl, rr, xl, xr, xx + x); + *p++ = LERP (gl, gr, xl, xr, xx + x); + *p++ = LERP (bl, br, xl, xr, xx + x); + } + } + } + } + + /* Create clipping mask */ + + mask = gdk_pixmap_new (NULL, width, height, 1); + gc = gdk_gc_new (mask); + + color.pixel = 0; + gdk_gc_set_foreground (gc, &color); + gdk_draw_rectangle (mask, gc, TRUE, + 0, 0, width, height); + + color.pixel = 1; + gdk_gc_set_foreground (gc, &color); + + points[0].x = x1 - x; + points[0].y = y1 - y; + points[1].x = x2 - x; + points[1].y = y2 - y; + points[2].x = x3 - x; + points[2].y = y3 - y; + gdk_draw_polygon (mask, gc, TRUE, points, 3); + + gdk_gc_unref (gc); + + gdk_gc_set_clip_mask (priv->gc, mask); + gdk_gc_set_clip_origin (priv->gc, 0, 0); + + /* Draw triangle */ + + gdk_draw_rgb_image_dithalign (drawable, priv->gc, 0, 0, width, height, + GDK_RGB_DITHER_MAX, + buf, + width * 3, + x, y); + + gdk_gc_set_clip_mask (priv->gc, NULL); + gdk_bitmap_unref (mask); + + g_free (buf); + + /* Draw triangle outline */ + + gdk_rgb_gc_set_foreground (priv->gc, 0x000000); + + gdk_draw_polygon (drawable, priv->gc, FALSE, points, 3); + + /* Draw value marker */ + + xx = floor (sx + (vx - sx) * priv->v + (hx - vx) * priv->s * priv->v + 0.5); + yy = floor (sy + (vy - sy) * priv->v + (hy - vy) * priv->s * priv->v + 0.5); + + r = priv->h; + g = priv->s; + b = priv->v; + hsv_to_rgb (&r, &g, &b); + + if (INTENSITY (r, g, b) > 0.5) + gdk_rgb_gc_set_foreground (priv->gc, 0x000000); + else + gdk_rgb_gc_set_foreground (priv->gc, 0xffffff); + + gdk_draw_arc (drawable, priv->gc, FALSE, + xx - 3, yy - 3, + 6, 6, + 0, 360 * 64); + gdk_draw_arc (drawable, priv->gc, FALSE, + xx - 2, yy - 2, + 4, 4, + 0, 360 * 64); } /* Paints the contents of the HSV color selector */ static void -paint (GtkHSV *hsv, GdkDrawable *drawable, int x, int y, int width, int height) +paint (GtkHSV *hsv, + GdkDrawable *drawable, + gint x, + gint y, + gint width, + gint height) { - paint_ring (hsv, drawable, x, y, width, height); - paint_triangle (hsv, drawable, x, y, width, height); + paint_ring (hsv, drawable, x, y, width, height); + paint_triangle (hsv, drawable, x, y, width, height); } /* Expose_event handler for the HSV color selector */ static gint -gtk_hsv_expose (GtkWidget *widget, GdkEventExpose *event) +gtk_hsv_expose (GtkWidget *widget, + GdkEventExpose *event) { - GtkHSV *hsv; - HSVPrivate *priv; - GdkRectangle rect, dest; - GdkPixmap *pixmap; - - hsv = GTK_HSV (widget); - priv = hsv->priv; - - if (!(GTK_WIDGET_DRAWABLE (widget) && event->window == widget->window)) - return FALSE; - - rect.x = widget->allocation.x; - rect.y = widget->allocation.y; - rect.width = widget->allocation.width; - rect.height = widget->allocation.height; - - if (!gdk_rectangle_intersect (&event->area, &rect, &dest)) - return FALSE; - - pixmap = gdk_pixmap_new (widget->window, dest.width, dest.height, - gtk_widget_get_visual (widget)->depth); - - rect = dest; - rect.x = 0; - rect.y = 0; - - gdk_draw_rectangle (pixmap, - widget->style->bg_gc[GTK_WIDGET_STATE (widget)], - TRUE, - 0, 0, dest.width, dest.height); - paint (hsv, pixmap, - dest.x - widget->allocation.x, dest.y - widget->allocation.y, - dest.width, dest.height); - - gdk_draw_pixmap (widget->window, - priv->gc, - pixmap, - 0, 0, - dest.x, - dest.y, - event->area.width, event->area.height); - - gdk_pixmap_unref (pixmap); - - return FALSE; + GtkHSV *hsv; + HSVPrivate *priv; + GdkRectangle rect, dest; + GdkPixmap *pixmap; + + hsv = GTK_HSV (widget); + priv = hsv->priv; + + if (!(GTK_WIDGET_DRAWABLE (widget) && event->window == widget->window)) + return FALSE; + + rect.x = widget->allocation.x; + rect.y = widget->allocation.y; + rect.width = widget->allocation.width; + rect.height = widget->allocation.height; + + if (!gdk_rectangle_intersect (&event->area, &rect, &dest)) + return FALSE; + + pixmap = gdk_pixmap_new (widget->window, dest.width, dest.height, + gtk_widget_get_visual (widget)->depth); + + rect = dest; + rect.x = 0; + rect.y = 0; + + gdk_draw_rectangle (pixmap, + widget->style->bg_gc[GTK_WIDGET_STATE (widget)], + TRUE, + 0, 0, dest.width, dest.height); + paint (hsv, pixmap, + dest.x - widget->allocation.x, dest.y - widget->allocation.y, + dest.width, dest.height); + + gdk_draw_pixmap (widget->window, + priv->gc, + pixmap, + 0, 0, + dest.x, + dest.y, + event->area.width, event->area.height); + + gdk_pixmap_unref (pixmap); + + return FALSE; } - /** * gtk_hsv_new: @@ -1193,10 +1280,10 @@ gtk_hsv_expose (GtkWidget *widget, GdkEventExpose *event) * * Return value: A newly-created HSV color selector. **/ -GtkWidget * +GtkWidget* gtk_hsv_new (void) { - return GTK_WIDGET (gtk_type_new (gtk_hsv_get_type ())); + return GTK_WIDGET (gtk_type_new (GTK_TYPE_HSV)); } /** @@ -1210,25 +1297,28 @@ gtk_hsv_new (void) * be in the [0.0, 1.0] range. **/ void -gtk_hsv_set_color (GtkHSV *hsv, double h, double s, double v) +gtk_hsv_set_color (GtkHSV *hsv, + gdouble h, + gdouble s, + gdouble v) { - HSVPrivate *priv; - - g_return_if_fail (hsv != NULL); - g_return_if_fail (GTK_IS_HSV (hsv)); - g_return_if_fail (h >= 0.0 && h <= 1.0); - g_return_if_fail (s >= 0.0 && s <= 1.0); - g_return_if_fail (v >= 0.0 && v <= 1.0); - - priv = hsv->priv; - - priv->h = h; - priv->s = s; - priv->v = v; - - gtk_signal_emit (GTK_OBJECT (hsv), hsv_signals[CHANGED]); - - gtk_widget_queue_draw (GTK_WIDGET (hsv)); + HSVPrivate *priv; + + g_return_if_fail (hsv != NULL); + g_return_if_fail (GTK_IS_HSV (hsv)); + g_return_if_fail (h >= 0.0 && h <= 1.0); + g_return_if_fail (s >= 0.0 && s <= 1.0); + g_return_if_fail (v >= 0.0 && v <= 1.0); + + priv = hsv->priv; + + priv->h = h; + priv->s = s; + priv->v = v; + + gtk_signal_emit (GTK_OBJECT (hsv), hsv_signals[CHANGED]); + + gtk_widget_queue_draw (GTK_WIDGET (hsv)); } /** @@ -1244,21 +1334,21 @@ gtk_hsv_set_color (GtkHSV *hsv, double h, double s, double v) void gtk_hsv_get_color (GtkHSV *hsv, double *h, double *s, double *v) { - HSVPrivate *priv; - - g_return_if_fail (hsv != NULL); - g_return_if_fail (GTK_IS_HSV (hsv)); - - priv = hsv->priv; - - if (h) - *h = priv->h; - - if (s) - *s = priv->s; - - if (v) - *v = priv->v; + HSVPrivate *priv; + + g_return_if_fail (hsv != NULL); + g_return_if_fail (GTK_IS_HSV (hsv)); + + priv = hsv->priv; + + if (h) + *h = priv->h; + + if (s) + *s = priv->s; + + if (v) + *v = priv->v; } /** @@ -1270,28 +1360,30 @@ gtk_hsv_get_color (GtkHSV *hsv, double *h, double *s, double *v) * Sets the size and ring width of an HSV color selector. **/ void -gtk_hsv_set_metrics (GtkHSV *hsv, int size, int ring_width) +gtk_hsv_set_metrics (GtkHSV *hsv, + gint size, + gint ring_width) { - HSVPrivate *priv; - int same_size; - - g_return_if_fail (hsv != NULL); - g_return_if_fail (GTK_IS_HSV (hsv)); - g_return_if_fail (size > 0); - g_return_if_fail (ring_width > 0); - g_return_if_fail (2 * ring_width + 1 <= size); - - priv = hsv->priv; - - same_size = (priv->size == size); - - priv->size = size; - priv->ring_width = ring_width; - - if (same_size) - gtk_widget_queue_draw (GTK_WIDGET (hsv)); - else - gtk_widget_queue_resize (GTK_WIDGET (hsv)); + HSVPrivate *priv; + int same_size; + + g_return_if_fail (hsv != NULL); + g_return_if_fail (GTK_IS_HSV (hsv)); + g_return_if_fail (size > 0); + g_return_if_fail (ring_width > 0); + g_return_if_fail (2 * ring_width + 1 <= size); + + priv = hsv->priv; + + same_size = (priv->size == size); + + priv->size = size; + priv->ring_width = ring_width; + + if (same_size) + gtk_widget_queue_draw (GTK_WIDGET (hsv)); + else + gtk_widget_queue_resize (GTK_WIDGET (hsv)); } /** @@ -1303,20 +1395,22 @@ gtk_hsv_set_metrics (GtkHSV *hsv, int size, int ring_width) * Queries the size and ring width of an HSV color selector. **/ void -gtk_hsv_get_metrics (GtkHSV *hsv, int *size, int *ring_width) +gtk_hsv_get_metrics (GtkHSV *hsv, + gint *size, + gint *ring_width) { - HSVPrivate *priv; - - g_return_if_fail (hsv != NULL); - g_return_if_fail (GTK_IS_HSV (hsv)); - - priv = hsv->priv; - - if (size) - *size = priv->size; - - if (ring_width) - *ring_width = priv->ring_width; + HSVPrivate *priv; + + g_return_if_fail (hsv != NULL); + g_return_if_fail (GTK_IS_HSV (hsv)); + + priv = hsv->priv; + + if (size) + *size = priv->size; + + if (ring_width) + *ring_width = priv->ring_width; } /** @@ -1335,13 +1429,14 @@ gtk_hsv_get_metrics (GtkHSV *hsv, int *size, int *ring_width) gboolean gtk_hsv_is_adjusting (GtkHSV *hsv) { - HSVPrivate *priv; - - g_return_val_if_fail (hsv != NULL, FALSE); - g_return_val_if_fail (GTK_IS_HSV (hsv), FALSE); - - priv = hsv->priv; - return (priv->mode != DRAG_NONE); + HSVPrivate *priv; + + g_return_val_if_fail (hsv != NULL, FALSE); + g_return_val_if_fail (GTK_IS_HSV (hsv), FALSE); + + priv = hsv->priv; + + return priv->mode != DRAG_NONE; } /** @@ -1357,22 +1452,27 @@ gtk_hsv_is_adjusting (GtkHSV *hsv) * [0.0, 1.0] range; output values will be in the same range. **/ void -gtk_hsv_to_rgb (double h, double s, double v, double *r, double *g, double *b) +gtk_hsv_to_rgb (gdouble h, + gdouble s, + gdouble v, + gdouble *r, + gdouble *g, + gdouble *b) { - g_return_if_fail (h >= 0.0 && h <= 1.0); - g_return_if_fail (s >= 0.0 && s <= 1.0); - g_return_if_fail (v >= 0.0 && v <= 1.0); - - hsv_to_rgb (&h, &s, &v); - - if (r) - *r = h; - - if (g) - *g = s; - - if (b) - *b = v; + g_return_if_fail (h >= 0.0 && h <= 1.0); + g_return_if_fail (s >= 0.0 && s <= 1.0); + g_return_if_fail (v >= 0.0 && v <= 1.0); + + hsv_to_rgb (&h, &s, &v); + + if (r) + *r = h; + + if (g) + *g = s; + + if (b) + *b = v; } /** @@ -1388,20 +1488,25 @@ gtk_hsv_to_rgb (double h, double s, double v, double *r, double *g, double *b) * [0.0, 1.0] range; output values will be in the same range. **/ void -gtk_rgb_to_hsv (double r, double g, double b, double *h, double *s, double *v) +gtk_rgb_to_hsv (gdouble r, + gdouble g, + gdouble b, + gdouble *h, + gdouble *s, + gdouble *v) { - g_return_if_fail (r >= 0.0 && r <= 1.0); - g_return_if_fail (g >= 0.0 && g <= 1.0); - g_return_if_fail (b >= 0.0 && b <= 1.0); - - rgb_to_hsv (&r, &g, &b); - - if (h) - *h = r; - - if (s) - *s = g; - - if (v) - *v = b; + g_return_if_fail (r >= 0.0 && r <= 1.0); + g_return_if_fail (g >= 0.0 && g <= 1.0); + g_return_if_fail (b >= 0.0 && b <= 1.0); + + rgb_to_hsv (&r, &g, &b); + + if (h) + *h = r; + + if (s) + *s = g; + + if (v) + *v = b; } |