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