Code

Stop background rendering once crash handler is triggered.
[inkscape.git] / src / widgets / sp-color-wheel.cpp
index 9038b6d38013d4fe2880b196411b3ebaf916557f..25cfb8dbd3791e1bc032b97fc5f21dc5ca1d4b9d 100644 (file)
@@ -6,6 +6,7 @@
  * Authors:
  *   Lauris Kaplinski <lauris@kaplinski.com>
  *   Jon A. Cruz <jon@joncruz.org>
+ *   John Bintz <jcoswell@coswellproductions.org>
  *
  * Copyright (C) 2001-2002 Lauris Kaplinski
  * Copyright (C) 2003-2004 Authors
  * This code is in public domain
  */
 
+#include <cstring>
+#include <string>
+
 #include <gtk/gtksignal.h>
 #include "sp-color-wheel.h"
 
 #include "libnr/nr-rotate-ops.h"
+#include <2geom/transforms.h>
 
 #define WHEEL_SIZE 96
 
@@ -25,6 +30,9 @@ enum {
     LAST_SIGNAL
 };
 
+#define noDUMP_CHANGE_INFO
+#define FOO_NAME(x) g_type_name( G_TYPE_FROM_INSTANCE(x) )
+
 static void sp_color_wheel_class_init (SPColorWheelClass *klass);
 static void sp_color_wheel_init (SPColorWheel *wheel);
 static void sp_color_wheel_destroy (GtkObject *object);
@@ -65,20 +73,23 @@ get_time (void)
 }
 */
 
-GtkType
-sp_color_wheel_get_type (void)
+GType sp_color_wheel_get_type(void)
 {
-    static GtkType type = 0;
+    static GType type = 0;
     if (!type) {
-        GtkTypeInfo info = {
-            "SPColorWheel",
-            sizeof (SPColorWheel),
-            sizeof (SPColorWheelClass),
-            (GtkClassInitFunc) sp_color_wheel_class_init,
-            (GtkObjectInitFunc) sp_color_wheel_init,
-            NULL, NULL, NULL
+        GTypeInfo info = {
+            sizeof(SPColorWheelClass),
+            0, // base_init
+            0, // base_finalize
+            (GClassInitFunc)sp_color_wheel_class_init,
+            0, // class_finalize
+            0, // class_data
+            sizeof(SPColorWheel),
+            0, // n_preallocs
+            (GInstanceInitFunc)sp_color_wheel_init,
+            0 // value_table
         };
-        type = gtk_type_unique (GTK_TYPE_WIDGET, &info);
+        type = g_type_register_static(GTK_TYPE_WIDGET, "SPColorWheel", &info, static_cast<GTypeFlags>(0));
     }
     return type;
 }
@@ -185,11 +196,14 @@ void sp_color_wheel_get_color( SPColorWheel *wheel, SPColor* color )
         rgb[i] = (rgb[i] * wheel->_sat) + (wheel->_value * (1.0 - wheel->_sat));
     }
 
-    sp_color_set_rgb_float (color, rgb[0], rgb[1], rgb[2]);
+    color->set( rgb[0], rgb[1], rgb[2] );
 }
 
 void sp_color_wheel_set_color( SPColorWheel *wheel, const SPColor* color )
 {
+#ifdef DUMP_CHANGE_INFO
+    g_message("sp_color_wheel_set_color( wheel=%p, %f, %f, %f)", wheel, color->v.c[0], color->v.c[1], color->v.c[2] );
+#endif
     g_return_if_fail (SP_IS_COLOR_WHEEL (wheel));
     g_return_if_fail (wheel != NULL);
     g_return_if_fail (color != NULL);
@@ -366,6 +380,15 @@ sp_color_wheel_button_press (GtkWidget *widget, GdkEventButton *event)
             gtk_widget_grab_focus( widget );
 
             wheel->dragging = TRUE;
+#ifdef DUMP_CHANGE_INFO
+            {
+                SPColor color;
+                sp_color_wheel_get_color( wheel, &color );
+                g_message( "%s:%d: About to signal %s to color %08x in %s", __FILE__, __LINE__,
+                           "CHANGED",
+                           color.toRGBA32( 0 ), FOO_NAME(wheel));
+            }
+#endif
             gtk_signal_emit (GTK_OBJECT (wheel), wheel_signals[CHANGED]);
             gdk_pointer_grab (widget->window, FALSE,
                               (GdkEventMask)(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK),
@@ -387,6 +410,15 @@ sp_color_wheel_button_release (GtkWidget *widget, GdkEventButton *event)
         gdk_pointer_ungrab (event->time);
         wheel->dragging = FALSE;
 
+#ifdef DUMP_CHANGE_INFO
+        {
+            SPColor color;
+            sp_color_wheel_get_color( wheel, &color );
+            g_message( "%s:%d: About to signal %s to color %08x in %s", __FILE__, __LINE__,
+                       "CHANGED",
+                       color.toRGBA32( 0 ), FOO_NAME(wheel));
+        }
+#endif
         gtk_signal_emit (GTK_OBJECT (wheel), wheel_signals[CHANGED]);
     }
 
@@ -413,6 +445,15 @@ sp_color_wheel_motion_notify (GtkWidget *widget, GdkEventMotion *event)
             sp_color_wheel_process_in_triangle( wheel, event->x, event->y );
         }
 
+#ifdef DUMP_CHANGE_INFO
+        {
+            SPColor color;
+            sp_color_wheel_get_color( wheel, &color );
+            g_message( "%s:%d: About to signal %s to color %08x in %s", __FILE__, __LINE__,
+                       "CHANGED",
+                       color.toRGBA32( 0 ), FOO_NAME(wheel));
+        }
+#endif
         gtk_signal_emit (GTK_OBJECT (wheel), wheel_signals[CHANGED]);
     }
 
@@ -476,6 +517,15 @@ static void sp_color_wheel_set_sv( SPColorWheel *wheel, gdouble sat, gdouble val
 
         wheel->_spotValue = ( (0.299 * rgb[0]) + (0.587 * rgb[1]) + (0.114 * rgb[2]) );
 
+#ifdef DUMP_CHANGE_INFO
+        {
+            SPColor color;
+            sp_color_wheel_get_color( wheel, &color );
+            g_message( "%s:%d: About to signal %s to color %08x in %s", __FILE__, __LINE__,
+                       "CHANGED",
+                       color.toRGBA32( 0 ), FOO_NAME(wheel));
+        }
+#endif
         gtk_signal_emit (GTK_OBJECT (wheel), wheel_signals[CHANGED]);
     }
     gtk_widget_queue_draw (GTK_WIDGET (wheel));
@@ -554,6 +604,9 @@ typedef struct {
     gfloat y;
 } PointF;
 
+/**
+ * Render the provided color wheel information as a triangle.
+ */
 static void sp_color_wheel_render_triangle (SPColorWheel *wheel)
 {
     if ( wheel->_image )
@@ -660,126 +713,54 @@ static void sp_color_wheel_render_triangle (SPColorWheel *wheel)
             VERT_COPY(S, A);
             VERT_COPY(E, A);
 
+            int runs = 1; int fill_mode = 0;
+
             if ( dx1 == 0 )
             {
-                VERT_COPY(E,B);
-                for(;pointS.y <= pointC.y; pointS.y++,pointE.y++)
-                {
-                    if (pointE.x-pointS.x > 0)
-                    {
-                        dr=(rgbE[0]-rgbS[0])/(pointE.x-pointS.x);
-                        dg=(rgbE[1]-rgbS[1])/(pointE.x-pointS.x);
-                        db=(rgbE[2]-rgbS[2])/(pointE.x-pointS.x);
-                    }
-                    else
-                    {
-                        dr=dg=db=0;
-                    }
-                    VERT_COPY(P,S);
-                    dst = wheel->_triImage + (static_cast<gint>(pointP.y) * rowStride);
-                    dst += static_cast<gint>(pointP.x) * 3;
-                    for(;pointP.x < pointE.x;pointP.x++)
-                    {
-                        //putpixel(P);
-                        dst[0] = SP_COLOR_F_TO_U(rgbP[0]);
-                        dst[1] = SP_COLOR_F_TO_U(rgbP[1]);
-                        dst[2] = SP_COLOR_F_TO_U(rgbP[2]);
-                        dst += 3;
-                        rgbP[0]+=dr; rgbP[1]+=dg; rgbP[2]+=db;
-                    }
-                    pointS.x+=dx2; rgbS[0]+=dr2; rgbS[1]+=dg2; rgbS[2]+=db2;
-                    pointE.x+=dx3; rgbE[0]+=dr3; rgbE[1]+=dg3; rgbE[2]+=db3;
-                }
+                fill_mode = 0;
             }
-            else if (dx1 > dx2)
+            else if ( dx1 > dx2 )
             {
-                for(;pointS.y <= pointB.y; pointS.y++,pointE.y++)
-                {
-                    if (pointE.x-pointS.x > 0)
-                    {
-                        dr=(rgbE[0]-rgbS[0])/(pointE.x-pointS.x);
-                        dg=(rgbE[1]-rgbS[1])/(pointE.x-pointS.x);
-                        db=(rgbE[2]-rgbS[2])/(pointE.x-pointS.x);
-                    }
-                    else
-                    {
-                        dr=dg=db=0;
-                    }
-                    VERT_COPY(P,S);
-                    dst = wheel->_triImage + (static_cast<gint>(pointP.y) * rowStride);
-                    dst += static_cast<gint>(pointP.x) * 3;
-                    for(;pointP.x < pointE.x;pointP.x++)
-                    {
-                        //putpixel(P);
-                        dst[0] = SP_COLOR_F_TO_U(rgbP[0]);
-                        dst[1] = SP_COLOR_F_TO_U(rgbP[1]);
-                        dst[2] = SP_COLOR_F_TO_U(rgbP[2]);
-                        dst += 3;
-                        rgbP[0]+=dr; rgbP[1]+=dg; rgbP[2]+=db;
-                    }
-                    pointS.x+=dx2; rgbS[0]+=dr2; rgbS[1]+=dg2; rgbS[2]+=db2;
-                    pointE.x+=dx1; rgbE[0]+=dr1; rgbE[1]+=dg1; rgbE[2]+=db1;
-                }
-                VERT_COPY(E,B);
-                for(;pointS.y <= pointC.y; pointS.y++,pointE.y++)
-                {
-                    if (pointE.x-pointS.x > 0)
-                    {
-                        dr=(rgbE[0]-rgbS[0])/(pointE.x-pointS.x);
-                        dg=(rgbE[1]-rgbS[1])/(pointE.x-pointS.x);
-                        db=(rgbE[2]-rgbS[2])/(pointE.x-pointS.x);
-                    }
-                    else
-                    {
-                        dr=dg=db=0;
-                    }
-                    VERT_COPY(P,S);
-                    dst = wheel->_triImage + (static_cast<gint>(pointP.y) * rowStride);
-                    dst += static_cast<gint>(pointP.x) * 3;
-                    for(;pointP.x < pointE.x;pointP.x++)
-                    {
-                        //putpixel(P);
-                        dst[0] = SP_COLOR_F_TO_U(rgbP[0]);
-                        dst[1] = SP_COLOR_F_TO_U(rgbP[1]);
-                        dst[2] = SP_COLOR_F_TO_U(rgbP[2]);
-                        dst += 3;
-                        rgbP[0]+=dr; rgbP[1]+=dg; rgbP[2]+=db;
-                    }
-                    pointS.x+=dx2; rgbS[0]+=dr2; rgbS[1]+=dg2; rgbS[2]+=db2;
-                    pointE.x+=dx3; rgbE[0]+=dr3; rgbE[1]+=dg3; rgbE[2]+=db3;
-                }
+                fill_mode = 1; runs = 2;
             }
             else if ( dx1 )
             {
-                for(;pointS.y <= pointB.y; pointS.y++,pointE.y++)
+                fill_mode = 2; runs = 2;
+            }
+
+            gfloat targetY = 0;
+            int fill_direction_mode = 0;
+
+            for (int current_run = 0; current_run < runs; current_run++)
+            {
+                targetY = pointC.y;
+                switch (fill_mode)
                 {
-                    if (pointE.x-pointS.x > 0)
-                    {
-                        dr=(rgbE[0]-rgbS[0])/(pointE.x-pointS.x);
-                        dg=(rgbE[1]-rgbS[1])/(pointE.x-pointS.x);
-                        db=(rgbE[2]-rgbS[2])/(pointE.x-pointS.x);
-                    }
-                    else
-                    {
-                        dr=dg=db=0;
-                    }
-                    VERT_COPY(P,S);
-                    dst = wheel->_triImage + (static_cast<gint>(pointP.y) * rowStride);
-                    dst += static_cast<gint>(pointP.x) * 3;
-                    for(;pointP.x < pointE.x;pointP.x++)
-                    {
-                        //putpixel(P);
-                        dst[0] = SP_COLOR_F_TO_U(rgbP[0]);
-                        dst[1] = SP_COLOR_F_TO_U(rgbP[1]);
-                        dst[2] = SP_COLOR_F_TO_U(rgbP[2]);
-                        dst += 3;
-                        rgbP[0]+=dr; rgbP[1]+=dg; rgbP[2]+=db;
-                    }
-                    pointS.x+=dx1; rgbS[0]+=dr1; rgbS[1]+=dg1; rgbS[2]+=db1;
-                    pointE.x+=dx2; rgbE[0]+=dr2; rgbE[1]+=dg2; rgbE[2]+=db2;
+                    case 0:
+                        VERT_COPY(E,B);
+                        fill_direction_mode = 0;
+                        break;
+                    case 1:
+                        if (current_run == 0) {
+                            targetY = pointB.y;
+                            fill_direction_mode = 1;
+                        } else {
+                            VERT_COPY(E,B);
+                            fill_direction_mode = 0;
+                        }
+                        break;
+                    case 2:
+                        if (current_run == 0) {
+                            targetY = pointB.y;
+                            fill_direction_mode = 2;
+                        } else {
+                            VERT_COPY(S,B);
+                            fill_direction_mode = 3;
+                        }
+                        break;
                 }
-                VERT_COPY(S,B);
-                for(;pointS.y <= pointC.y; pointS.y++,pointE.y++)
+
+                for(;pointS.y <= targetY; pointS.y++,pointE.y++)
                 {
                     if (pointE.x-pointS.x > 0)
                     {
@@ -803,11 +784,29 @@ static void sp_color_wheel_render_triangle (SPColorWheel *wheel)
                         dst += 3;
                         rgbP[0]+=dr; rgbP[1]+=dg; rgbP[2]+=db;
                     }
-                    pointS.x+=dx3; rgbS[0]+=dr3; rgbS[1]+=dg3; rgbS[2]+=db3;
-                    pointE.x+=dx2; rgbE[0]+=dr2; rgbE[1]+=dg2; rgbE[2]+=db2;
+
+                    switch (fill_direction_mode) {
+                        case 0:
+                            pointS.x+=dx2; rgbS[0]+=dr2; rgbS[1]+=dg2; rgbS[2]+=db2;
+                            pointE.x+=dx3; rgbE[0]+=dr3; rgbE[1]+=dg3; rgbE[2]+=db3;
+                            break;
+                        case 1:
+                            pointS.x+=dx2; rgbS[0]+=dr2; rgbS[1]+=dg2; rgbS[2]+=db2;
+                            pointE.x+=dx1; rgbE[0]+=dr1; rgbE[1]+=dg1; rgbE[2]+=db1;
+                            break;
+                        case 2:
+                            pointS.x+=dx1; rgbS[0]+=dr1; rgbS[1]+=dg1; rgbS[2]+=db1;
+                            pointE.x+=dx2; rgbE[0]+=dr2; rgbE[1]+=dg2; rgbE[2]+=db2;
+                            break;
+                        case 3:
+                            pointS.x+=dx3; rgbS[0]+=dr3; rgbS[1]+=dg3; rgbS[2]+=db3;
+                            pointE.x+=dx2; rgbE[0]+=dr2; rgbE[1]+=dg2; rgbE[2]+=db2;
+                            break;
+                    }
                 }
             }
 
+
 // End of Gouraud fill  ============================================================
 
             wheel->_triDirty = FALSE;
@@ -1133,17 +1132,17 @@ static void sp_color_wheel_process_in_triangle( SPColorWheel *wheel, gdouble x,
 {
 // njh: dot(rot90(B-C), x) = saturation
 // njh: dot(B-C, x) = value
-    NR::Point delta( x - (((gdouble)(wheel->_triPoints[1].x + wheel->_triPoints[2].x)) / 2.0),
+    Geom::Point delta( x - (((gdouble)(wheel->_triPoints[1].x + wheel->_triPoints[2].x)) / 2.0),
                      y - (((gdouble)(wheel->_triPoints[1].y + wheel->_triPoints[2].y)) / 2.0) );
 
     gdouble rot = (M_PI * 2 * wheel->_hue );
 
-    NR::Point result = delta * NR::rotate(rot);
+    Geom::Point result = delta * Geom::Rotate(rot);
 
-    gdouble sat = CLAMP( result[NR::X] / (wheel->_inner * 1.5), 0.0, 1.0 );
+    gdouble sat = CLAMP( result[Geom::X] / (wheel->_inner * 1.5), 0.0, 1.0 );
 
     gdouble halfHeight = (wheel->_inner * sin(M_PI/3.0)) * (1.0 - sat);
-    gdouble value = CLAMP( ((result[NR::Y]+ halfHeight) / (2.0*halfHeight)), 0.0, 1.0 );
+    gdouble value = CLAMP( ((result[Geom::Y]+ halfHeight) / (2.0*halfHeight)), 0.0, 1.0 );
 
     wheel->_triDirty = TRUE;
 
@@ -1160,4 +1159,4 @@ static void sp_color_wheel_process_in_triangle( SPColorWheel *wheel, gdouble x,
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :