replacement of floating point ops with fixed point
authorTomas Frydrych <tf@openedhand.com>
Tue, 16 Jan 2007 10:39:18 +0000 (10:39 +0000)
committerTomas Frydrych <tf@openedhand.com>
Tue, 16 Jan 2007 10:39:18 +0000 (10:39 +0000)
ChangeLog
clutter/clutter-behaviour-path.c
clutter/clutter-color.c
clutter/clutter-color.h
clutter/clutter-fixed.c
clutter/clutter-fixed.h

index b102ea6..f88f959 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,9 @@
 2007-01-16  Tomas Frydrych  <tf@openedhand.com>
        
        * clutter/clutter-fixed.h:
-       Added integer ClutterAngle type, protype of clutter_angle_sin and
-       convenience macros clutter_fixed_cos and clutter_angle_cos
+       Added integer ClutterAngle type, protype of clutter_angle_sin,
+       convenience macros clutter_fixed_cos and clutter_angle_cos, plus
+       other convenience macros for commonly used constants and ops.
        * clutter/clutter-fixed.c: 
        (clutter_fixed_sin):
        Fixed to work for negative angles.
        * clutter/clutter-alpha.c: 
        (clutter_sin_func, clutter_sin_inc_func):
        Changed to use clutter_angle_sin function.
+       * clutter-behavior-path.c:
+       replaced floating point with fixed point operations
+       * clutter/clutter-color.c: 
+       * clutter/clutter-color.h:
+       Added (clutter_color_shadex), replaced floating point operations
+       with fixed point
        
 2007-01-15  Tomas Frydrych  <tf@openedhand.com>
        
index 01d20f8..a7c1b11 100644 (file)
@@ -180,11 +180,10 @@ static inline void
 interpolate (const ClutterKnot *begin, 
             const ClutterKnot *end, 
             ClutterKnot       *out,
-            double             t)
+            ClutterFixed       t)
 {
-  /* FIXME: fixed point */
-  out->x = begin->x + t * (end->x - begin->x);
-  out->y = begin->y + t * (end->y - begin->y);
+  out->x = begin->x + CLUTTER_FIXED_INT (t * (end->x - begin->x));
+  out->y = begin->y + CLUTTER_FIXED_INT (t * (end->y - begin->y));
 }
 
 static gint
@@ -272,10 +271,9 @@ path_alpha_to_position (ClutterBehaviourPath *behave,
           if (offset >= dist && offset < (dist + dist_to_next))
             {
              ClutterKnot new;
-             double t;
+             ClutterFixed t;
            
-             /* FIXME: Use fixed */
-             t = (double) (offset - dist) / dist_to_next;
+             t = CLUTTER_INT_TO_FIXED (offset - dist) / dist_to_next;
 
               interpolate (knot, next, &new, t);
 
index 535b6fa..0056918 100644 (file)
@@ -107,7 +107,8 @@ void
 clutter_color_lighten (const ClutterColor *src,
                       ClutterColor       *dest)
 {
-  clutter_color_shade (src, dest, 1.3);
+  /* 0x14ccd is ClutterFixed for 1.3 */
+  clutter_color_shade (src, dest, 0x14ccd);
 }
 
 /**
@@ -122,7 +123,8 @@ void
 clutter_color_darken (const ClutterColor *src,
                      ClutterColor       *dest)
 {
-  clutter_color_shade (src, dest, 0.7);
+  /* 0xb333 is ClutterFixed for 0.7 */
+  clutter_color_shade (src, dest, 0xb333);
 }
 
 /**
@@ -140,15 +142,15 @@ clutter_color_to_hls (const ClutterColor *src,
                      guint8             *luminance,
                      guint8             *saturation)
 {
-  gdouble red, green, blue;
-  gdouble min, max, delta;
-  gdouble h, l, s;
+  ClutterFixed red, green, blue;
+  ClutterFixed min, max, delta;
+  ClutterFixed h, l, s;
   
   g_return_if_fail (src != NULL);
 
-  red = src->red / 255.0;
-  green = src->green / 255.0;
-  blue = src->blue / 255.0;
+  red   = CLUTTER_INT_TO_FIXED (src->red)   / 255;
+  green = CLUTTER_INT_TO_FIXED (src->green) / 255;
+  blue  = CLUTTER_INT_TO_FIXED (src->blue)  / 255;
 
   if (red > green)
     {
@@ -181,32 +183,32 @@ clutter_color_to_hls (const ClutterColor *src,
 
   if (max != min)
     {
-      if (l <= 0.5)
-       s = (max - min) / (max + min);
+      if (l <= CFX_ONE/2)
+       s = CFX_DIV ((max - min), (max + min));
       else
-       s = (max - min) / (2 - max - min);
+       s = CFX_DIV ((max - min), (2 - max - min));
 
       delta = max - min;
       if (red == max)
-       h = (green - blue) / delta;
+       h = CFX_DIV ((green - blue), delta);
       else if (green == max)
-       h = 2 + (blue - red) / delta;
+       h = CLUTTER_INT_TO_FIXED (2) + CFX_DIV ((blue - red), delta);
       else if (blue == max)
-       h = 4 + (red - green) / delta;
+       h = CLUTTER_INT_TO_FIXED (4) + CFX_DIV ((red - green), delta);
 
       h *= 60;
-      if (h < 0.0)
-       h += 360;
+      if (h < 0)
+       h += CLUTTER_INT_TO_FIXED (360);
     }
 
   if (hue)
-    *hue = (guint8) (h * 255);
+    *hue = (guint8) CFX_INT (h * 255);
 
   if (luminance)
-    *luminance = (guint8) (l * 255);
+    *luminance = (guint8) CFX_INT (l * 255);
 
   if (saturation)
-    *saturation = (guint8) (s * 255);
+    *saturation = (guint8) CFX_INT (s * 255);
 }
 
 /**
@@ -219,79 +221,81 @@ clutter_color_to_hls (const ClutterColor *src,
  * Converts a color expressed in HLS (hue, luminance and saturation)
  * values into a #ClutterColor.
  */
+
 void
 clutter_color_from_hls (ClutterColor *dest,
                        guint8        hue,
                        guint8        luminance,
                        guint8        saturation)
 {
-  gdouble h, l, s;
-  gdouble m1, m2;
+  ClutterFixed h, l, s;
+  ClutterFixed m1, m2;
   
   g_return_if_fail (dest != NULL);
 
-  l = (gdouble) luminance / 255.0;
-  s = (gdouble) saturation / 255.0;
+  l = CLUTTER_INT_TO_FIXED (luminance)  / 255;
+  s = CLUTTER_INT_TO_FIXED (saturation) / 255;
 
-  if (l <= 0.5)
-    m2 = l * (1 - s);
+  if (l <= CFX_ONE/2)
+    m2 = CFX_MUL (l, (CFX_ONE - s));
   else
-    m2 = l + s - l * s;
+    m2 = l + s - CFX_MUL (l,s);
 
   m1 = 2 * l - m2;
 
   if (s == 0)
     {
-      dest->red = (guint8) l * 255;
-      dest->green = (guint8) l * 255;
-      dest->blue = (guint8) l * 255;
+      dest->red   = (guint8) CFX_INT (l * 255);
+      dest->green = (guint8) CFX_INT (l * 255);
+      dest->blue  = (guint8) CFX_INT (l * 255);
     }
   else
     {
-      h = ((gdouble) hue / 255.0) + 120;
-      while (h > 360)
-       h -= 360;
+      h = (CLUTTER_INT_TO_FIXED (hue)/ 255) + CFX_120;
+      while (h > CFX_360)
+       h -= CFX_360;
       while (h < 0)
-       h += 360;
-
-      if (h < 60)
-       dest->red = (guint8) (m1 + (m2 - m1) * h / 60) * 255;
-      else if (h < 180)
-       dest->red = (guint8) m2 * 255;
-      else if (h < 240)
-       dest->red = (guint8) (m1 + (m2 - m1) * (240 - h) / 60) * 255;
+       h += CFX_360;
+
+      if (h < CFX_60)
+       dest->red = (guint8) CFX_INT((m1 + CFX_MUL((m2-m1), h) / 60) * 255);
+      else if (h < CFX_180)
+       dest->red = (guint8) CFX_INT (m2 * 255);
+      else if (h < CFX_240)
+       dest->red = (guint8)CFX_INT((m1+CFX_MUL((m2-m1),(CFX_240-h))/60)*255);
       else
-       dest->red = (guint8) m1 * 255;
+       dest->red = (guint8) CFX_INT (m1 * 255);
 
-      h = (gdouble) hue / 255.0;
-      while (h > 360)
-       h -= 360;
+      h = CLUTTER_INT_TO_FIXED (hue) / 255;
+      while (h > CFX_360)
+       h -= CFX_360;
       while (h < 0)
-       h += 360;
-
-      if (h < 60)
-       dest->green = (guint8) (m1 + (m2 - m1) * h / 60) * 255;
-      else if (h < 180)
-        dest->green = (guint8) m2 * 255;
-      else if (h < 240)
-       dest->green = (guint8) (m1 + (m2 - m1) * (240 - h) / 60) * 255;
+       h += CFX_360;
+
+      if (h < CFX_60)
+       dest->green = (guint8)CFX_INT((m1 + CFX_MUL((m2 - m1), h) / 60) * 255);
+      else if (h < CFX_180)
+        dest->green = (guint8) CFX_INT (m2 * 255);
+      else if (h < CFX_240)
+       dest->green =
+           (guint8) CFX_INT((m1 + CFX_MUL ((m2-m1), (CFX_240-h)) / 60) * 255);
       else
-       dest->green = (guint8) m1 * 255;
+       dest->green = (guint8) CFX_INT (m1 * 255);
 
-      h = ((gdouble) hue / 255.0) - 120;
-      while (h > 360)
-       h -= 360;
+      h = (CLUTTER_INT_TO_FIXED (hue) / 255) - CFX_120;
+      while (h > CFX_360)
+       h -= CFX_360;
       while (h < 0)
-       h += 360;
-
-      if (h < 60)
-       dest->blue = (guint8) (m1 + (m2 - m1) * h / 60) * 255;
-      else if (h < 180)
-       dest->blue = (guint8) m2 * 255;
-      else if (h < 240)
-       dest->blue = (guint8) (m1 + (m2 - m1) * (240 - h) / 60) * 255;
+       h += CFX_360;
+
+      if (h < CFX_60)
+       dest->blue = (guint8) CFX_INT ((m1 + CFX_MUL ((m2-m1), h) / 60) * 255);
+      else if (h < CFX_180)
+       dest->blue = (guint8) CFX_INT (m2 * 255);
+      else if (h < CFX_240)
+       dest->blue = (guint8)CFX_INT((m1+CFX_MUL((m2-m1),(CFX_240-h))/60)*255);
       else
-       dest->blue = (guint8) m1 * 255;
+       dest->blue = (guint8) CFX_INT(m1 * 255);
     }
 }
 
@@ -307,35 +311,50 @@ clutter_color_from_hls (ClutterColor *dest,
 void
 clutter_color_shade (const ClutterColor *src,
                     ClutterColor       *dest,
-                    gdouble             shade)
+                    gdouble            shade)
+{
+    clutter_color_shadex (src, dest, CLUTTER_FLOAT_TO_FIXED (shade));
+}
+
+/**
+ * clutter_color_shade:
+ * @src: a #ClutterColor
+ * @dest: return location for the shaded color
+ * @shade: #ClutterFixed the shade factor to apply
+ * 
+ * Shades @src by the factor of @shade and saves the modified
+ * color into @dest.
+ */
+void
+clutter_color_shadex (const ClutterColor *src,
+                     ClutterColor       *dest,
+                     ClutterFixed        shade)
 {
   guint8 h, l, s;
-  gdouble h1, l1, s1;
+  ClutterFixed l1, s1;
 
   g_return_if_fail (src != NULL);
   g_return_if_fail (dest != NULL);
   
   clutter_color_to_hls (src, &h, &l, &s);
 
-  h1 = (gdouble) h / 255.0;
-  l1 = (gdouble) l / 255.0;
-  s1 = (gdouble) s / 255.0;
-  
-  l1 *= shade;
-  if (l1 > 1.0)
-    l1 = 1.0;
-  else if (l1 < 0.0)
-    l1 = 0.0;
+  l1 = CLUTTER_INT_TO_FIXED (l) / 255;
+  s1 = CLUTTER_INT_TO_FIXED (s) / 255;
+
+  l1 = CFX_MUL (l1, shade);
+  if (l1 > CFX_ONE)
+    l1 = CFX_ONE;
+  else if (l1 < 0)
+    l1 = 0;
+
+  s1 = CFX_MUL (s1, shade);
+  if (s1 > CFX_ONE)
+    s1 = CFX_ONE;
+  else if (s1 < 0)
+    s1 = 0;
   
-  s1 *= shade;
-  if (s1 > 1.0)
-    s1 = 1.0;
-  else if (s1 < 0.0)
-    s1 = 0.0;
-
-  h = (guint8) h1 * 255;
-  l = (guint8) l1 * 255;
-  s = (guint8) s1 * 255;
+  l = (guint8) CFX_INT (l1 * 255);
+  s = (guint8) CFX_INT (s1 * 255);
 
   clutter_color_from_hls (dest, h, l, s);
 }
index 7a64b43..9fdc848 100644 (file)
@@ -67,6 +67,9 @@ void          clutter_color_darken     (const ClutterColor *src,
 void          clutter_color_shade      (const ClutterColor *src,
                                         ClutterColor       *dest,
                                         gdouble             shade);
+void          clutter_color_shadex      (const ClutterColor *src,
+                                        ClutterColor       *dest,
+                                        ClutterFixed        shade);
 
 void          clutter_color_to_hls     (const ClutterColor *src,
                                         guint8             *hue,
index a59fe28..02c7236 100644 (file)
@@ -177,7 +177,7 @@ clutter_fixed_sin (ClutterFixed angle)
  *
  * Fast fixed point implementation of sine function.
  *
- * ClutterAngle is an integer such that that 1024 represents
+ * ClutterAngle is an integer such that 1024 represents
  * full circle.
  * 
  * Return value: sine value (as fixed point).
index 91e7aeb..565cde5 100644 (file)
@@ -37,12 +37,22 @@ typedef gint32 ClutterAngle;    /* angle such that 1024 == 2*PI */
 #define CFX_ONE    (1 << CFX_Q)        /* 1 */
 #define CFX_MAX    0x7fffffff
 #define CFX_MIN    0x80000000
+
+/*
+ * some commonly used constants
+ */
 #define CFX_PI     0x0003243f
 #define CFX_2PI    0x0006487f
 #define CFX_PI_2   0x00019220   /* pi/2 */
 #define CFX_PI_4   0x0000c910   /* pi/4 */
 #define CFX_PI8192 0x6487ed51   /* pi * 0x2000, to improve precision */    
 
+#define CFX_360 CLUTTER_INT_TO_FIXED (360)
+#define CFX_240 CLUTTER_INT_TO_FIXED (240)
+#define CFX_180 CLUTTER_INT_TO_FIXED (180)
+#define CFX_120 CLUTTER_INT_TO_FIXED (120)
+#define CFX_60  CLUTTER_INT_TO_FIXED (60)
+
 #define CLUTTER_FIXED_TO_FLOAT(x) ((float)((int)(x)/65536.0))
 
 #define CLUTTER_FIXED_TO_DOUBLE(x) ((double)((int)(x)/65536.0))
@@ -68,6 +78,11 @@ typedef gint32 ClutterAngle;    /* angle such that 1024 == 2*PI */
 
 #define CLUTTER_FIXED_DIV(x,y) ((((x) << 8)/(y)) << 8)
 
+/* some handy short aliases to avoid exessively long lines */
+#define CFX_INT CLUTTER_FIXED_INT
+#define CFX_MUL CLUTTER_FIXED_MUL
+#define CFX_DIV CLUTTER_FIXED_DIV
+
 /* Fixed point math routines */
 ClutterFixed clutter_fixed_sin (ClutterFixed anx);
 ClutterFixed clutter_angle_sin (ClutterAngle angle);