Author: ArcRiley
Date: 2008-02-17 08:26:06 -0500 (Sun, 17 Feb 2008)
New Revision: 921

Modified:
   trunk/pysoy/src/colors/Color.pxi
Log:
Numerous enhancements to soy.colors.Color :
 * will no longer perform math on alpha when it's == 1.0 (blending disabled)
 * will no longer return the alpha value when it's == 1.0 from .hex and .floats
 * will compress hex from 24/32 bits to 12/16 when it can, ie, #ff0022 -> #f02
 * shortened formatting and reduced conditionals through slice trickery
 * str() now formatted which [1:-1] could generate an identical Color



Modified: trunk/pysoy/src/colors/Color.pxi
===================================================================
--- trunk/pysoy/src/colors/Color.pxi    2008-02-17 09:06:00 UTC (rev 920)
+++ trunk/pysoy/src/colors/Color.pxi    2008-02-17 13:26:06 UTC (rev 921)
@@ -77,56 +77,71 @@
 
   def __div__(self, value) :
     if type(value) == int or type(value) == float :
-      return Color(( (<Color> self)._r / value, (<Color> self)._g / value,
-                     (<Color> self)._b / value, (<Color> self)._a / value ))
+      return Color( ((<Color> self)._r / value, (<Color> self)._g / value,
+                     (<Color> self)._b / value, (<Color> self)._a / value)
+                    [:(3,4)[(<Color> self)._a !=1.0]] )
     elif isinstance(value, Color) :
-      return Color(( (<Color> self)._r / (<Color> value)._r,
+      return Color( ((<Color> self)._r / (<Color> value)._r,
                      (<Color> self)._g / (<Color> value)._g,
                      (<Color> self)._b / (<Color> value)._b,
-                     (<Color> self)._a / (<Color> value)._a ))
+                     (<Color> self)._a / (<Color> value)._a )
+                    [:(3,4)[(<Color> self)._a !=1.0 or \
+                            (<Color> value)._a!=1.0]] )
     else :
       raise TypeError('can only divide Color by a Color, int, or float')
 
   def __mul__(self, value) :
     if type(value) == int or type(value) == float :
-      return Color(( (<Color> self)._r * value, (<Color> self)._g * value,
-                     (<Color> self)._b * value, (<Color> self)._a * value ))
+      return Color( ((<Color> self)._r * value, (<Color> self)._g * value,
+                     (<Color> self)._b * value, (<Color> self)._a * value)
+                    [:(3,4)[(<Color> self)._a !=1.0]] )
     elif isinstance(value, Color) :
-      return Color(( (<Color> self)._r * (<Color> value)._r,
+      return Color( ((<Color> self)._r * (<Color> value)._r,
                      (<Color> self)._g * (<Color> value)._g,
                      (<Color> self)._b * (<Color> value)._b,
-                     (<Color> self)._a * (<Color> value)._a ))
+                     (<Color> self)._a * (<Color> value)._a)
+                    [:(3,4)[(<Color> self)._a !=1.0 or \
+                            (<Color> value)._a!=1.0]] )
     else :
       raise TypeError('can only multiply Color by a Color, int, or float')
 
   def __add__(self, value) :
     if type(value) == int or type(value) == float :
-      return Color(( (<Color> self)._r + value, (<Color> self)._g + value,
-                     (<Color> self)._b + value, (<Color> self)._a + value ))
+      return Color( ((<Color> self)._r + value, (<Color> self)._g + value,
+                     (<Color> self)._b + value, (<Color> self)._a + value)
+                    [:(3,4)[(<Color> self)._a !=1.0]] )
     elif isinstance(value, Color) :
-      return Color(( (<Color> self)._r + (<Color> value)._r,
+      return Color( ((<Color> self)._r + (<Color> value)._r,
                      (<Color> self)._g + (<Color> value)._g,
                      (<Color> self)._b + (<Color> value)._b,
-                     (<Color> self)._a + (<Color> value)._a ))
+                     (<Color> self)._a + (<Color> value)._a)
+                    [:(3,4)[(<Color> self)._a !=1.0 or \
+                            (<Color> value)._a!=1.0]] )
     else :
       raise TypeError('can only add Color with a Color, int, or float')
    
   def __sub__(self, value) :
     if type(value) == int or type(value) == float :
-      return Color(( (<Color> self)._r - value, (<Color> self)._g - value,
-                     (<Color> self)._b - value, (<Color> self)._a - value ))
+      return Color( ((<Color> self)._r - value, (<Color> self)._g - value,
+                     (<Color> self)._b - value, (<Color> self)._a - value)
+                    [:(3,4)[(<Color> self)._a !=1.0]] )
     elif isinstance(value, Color) :
-      return Color(( (<Color> self)._r - (<Color> value)._r,
+      return Color( ((<Color> self)._r - (<Color> value)._r,
                      (<Color> self)._g - (<Color> value)._g,
                      (<Color> self)._b - (<Color> value)._b,
-                     (<Color> self)._a - (<Color> value)._a ))
+                     (<Color> self)._a - (<Color> value)._a)
+                    [:(3,4)[(<Color> self)._a !=1.0 or \
+                            (<Color> value)._a!=1.0]] )
     else :
       raise TypeError('can only subtract Color by a Color, int, or float')
 
   def __repr__(self) :
-    return '<Color %s>' % (self.hex)
+    return '<%s>' % self.__str__()
 
+  def __str__(self) :
+    return 'soy.colors.Color %s' % self.hex
 
+
   cdef void _getRGBA(self, float* ret) :
     ret[0] = self._r
     ret[1] = self._g
@@ -143,49 +158,69 @@
     def __get__(self) :
       cdef float _top
       cdef float _bottom
-      
+      #
+      # Find the highest number of all the channels
       _top = self._r
       if self._g > _top :
         _top = self._g
       if self._b > _top :
         _top = self._b
-      if self._a > _top :
+      if self._a != 1.0 and self._a > _top :
         _top = self._a
-        
+      #  
       _bottom = self._r
       if self._g < _bottom :
         _bottom = self._g
       if self._b < _bottom :
         _bottom = self._b
-      if self._a < _bottom :
+      if self._a != 1.0 and self._a < _bottom :
         _bottom = self._a
-        
+      #        
+      # Test the highest and lowest values and, when the color is complex,
+      # calculate it as a complex statement which could be processed to 
+      # generate the same color.  Only include an alpha channel when != 1.0.
+      #
       if _top < 0 :
         if _top < 1.0 :
-          return '#%.2x%.2x%.2x%.2x * %.2f' % (self._a*255/_bottom,
-                                               self._r*255/_bottom,
-                                               self._g*255/_bottom,
-                                               self._b*255/_bottom,
-                                               _bottom)
+          chans = (self._a*255/_bottom, self._r*255/_bottom,
+                   self._g*255/_bottom, self._b*255/_bottom) [self._a==1.0:]
+          multi = _bottom
         else :
-          return '#%.2x%.2x%.2x%.2x * %.2f' % (self._a*255*_bottom,
-                                               self._r*255*_bottom,
-                                               self._g*255*_bottom,
-                                               self._b*255*_bottom,
-                                               _bottom)
-      if _bottom < 0 :
-        return '#%.2x%.2x%.2x%.2x' % (self._a*255-_bottom,self._r*255-_bottom,
-                                      self._g*255-_bottom,self._b*255-_bottom)
-      
-      if _top > 1.0 :
-        return '#%.2x%.2x%.2x%.2x * %.2f' % (self._a*255/_top,self._r*255/_top,
-                                             self._g*255/_top,self._b*255/_top,
-                                             _top)
+          chans = (self._a*255*_bottom, self._r*255*_bottom,
+                   self._g*255*_bottom, self._b*255*_bottom) [self._a==1.0:]
+          multi = _bottom
+      elif _bottom < 0 :
+        # This is not correct
+        chans = (self._a*255-_bottom, self._r*255-_bottom,
+                 self._g*255-_bottom, self._b*255-_bottom) [self._a==1.0:]
+        multi = 1.0
+      elif _top > 1.0 :
+        chans = (self._a*255/_top, self._r*255/_top,
+                 self._g*255/_top, self._b*255/_top) [self._a==1.0:]
+        multi = _top
       else :
-        return '#%.2x%.2x%.2x%.2x' % (self._a*255,self._r*255,
-                                      self._g*255,self._b*255)
+        chans = (self._a*255, self._r*255,
+                 self._g*255, self._b*255) [self._a==1.0:]
+        multi = 1.0
+      #
+      # The following code contains some Python trickery, abusing slice to
+      # get around having to use five times more conditional statements.
+      #
+      # I apologise in advance for those who may later have to parse this
+      # and am providing a comment for each line to make your task easier.
+      #
+      # First, we turn chans, the tuple, into chans, the hex string
+      chans = '%.2x' * len(chans) % chans
+      #
+      # Check if we can compress this string to 12/16 bit, ie, #fff vs #ffffff
+      chans = chans[::(chans[::2]==chans[1::2])+1]
+      #
+      # Format a string multi when float multi is != 1.0, else multi = ''
+      multi = ('*%.2f'%multi, '')[multi==1.0]
+      #
+      # Finally, return the compiled string
+      return "('#%s')%s" % (chans, multi) 
 
-
   property floats :
     '''Color floats
     
@@ -193,6 +228,4 @@
     (r, g, b, a)
     '''
     def __get__(self) :
-      return (self._r, self._g, self._b, self._a)
-  
-
+      return (self._r, self._g, self._b, self._a) [:(self._a!=1.0)+3]

_______________________________________________
PySoy-SVN mailing list
PySoy-SVN@pysoy.org
http://www.pysoy.org/mailman/listinfo/pysoy-svn

Reply via email to