Anonymous avatar Anonymous committed 3c17be2

#53 fixed color red green and blue components for hsl and hsla values (still minor rounding issues)

Comments (0)

Files changed (3)

src/cssutils/css/value.py

 from cssutils.prodparser import *
 import cssutils
 from cssutils.helper import normalize, pushtoken
+import colorsys
 import math
 import re
 import xml.dom
                 if len(v) == 4:
                     # HASH #rgb
                     rgba = (int(2*v[1], 16),
-                            int(2*v[1], 16),
-                            int(2*v[1], 16), 
+                            int(2*v[2], 16),
+                            int(2*v[3], 16), 
                             1.0)
                 else:
                     # HASH #rrggbb
                             1.0)
                     
             elif u'FUNCTION' == t:
-                functiontype, rgba, check = None, [], u''
+                functiontype, raw, check = None, [], u''
+                HSL = False
+                
                 for item in seq:
                     try:
                         type_ = item.value.type
                         # type of function, e.g. rgb(
                         if item.type == 'FUNCTION':
                             functiontype = item.value
+                            HSL = functiontype in (u'hsl(', u'hsla(')
                         continue
 
                     # save components                    
                     if type_ == Value.NUMBER:
-                        rgba.append(item.value.value)
+                        raw.append(item.value.value)
                         check += u'N'
                     elif type_ == Value.PERCENTAGE:
-                        rgba.append(int(255 * item.value.value / 100))
+                        if HSL:
+                            # save as percentage fraction
+                            raw.append(item.value.value / 100.0)
+                        else:
+                            # save as real value of percentage of 255
+                            raw.append(int(255 * item.value.value / 100))
                         check += u'P'
                         
+                if HSL:
+                    # convert to rgb
+                    # h is 360 based (circle)
+                    h, s, l = raw[0] / 360.0, raw[1], raw[2]
+                    # ORDER h l s !!!
+                    r, g, b = colorsys.hls_to_rgb(h, l, s)
+                    # back to 255 based
+                    rgba = [int(round(r*255)), 
+                            int(round(g*255)), 
+                            int(round(b*255))]
+                    
+                    if len(raw) > 3:
+                        rgba.append(raw[3])
+                        
+                else:
+                    # rgb, rgba
+                    rgba = raw
+
+                if len(rgba) < 4:
+                    rgba.append(1.0)
+                    
                 # validate
                 checks = {u'rgb(': ('NNN', 'PPP'),
                          u'rgba(': ('NNNN', 'PPPN'),
                     self._log.error(u'ColorValue has invalid %s) parameters: '
                                     u'%s (N=Number, P=Percentage)' % 
                                     (functiontype, check))
-                    
-                if len(rgba) < 4:
-                    rgba.append(1.0)
             
             self._colorType = t
             self._red, self._green, self._blue, self._alpha = tuple(rgba)
                                                  parent=parent
                                                  )
                                          )
-                )
+                )

src/tests/test_value.py

              u'hsla(1%,2%,3, 0.0)': xml.dom.SyntaxErr,
         }
         self.r = cssutils.css.ColorValue()
-        self.do_raise_r(tests)           
+        self.do_raise_r(tests) 
+
+    def test_rgb(self):
+        "ColorValue.red .green .blue"
+        tests = {
+            (u'#0A0AD2', 'rgb(10, 10, 210)' ): (10, 10, 210, 1.0),
+            # TODO: Fix rounding?
+            (u'hsl(240, 91%, 43%)', ): (10, 10, 209, 1.0),
+            (u'#ff8800', u'#f80', 
+             'rgb(255, 136, 0)', 'rgba(255, 136, 0, 1.0)'): (255, 136, 0, 1.0),
+            (u'red', u'#ff0000', u'#f00', 
+             u'hsl(0, 100%, 50%)', u'hsla(0, 100%, 50%, 1.0)'): 
+                (255, 0, 0, 1.0),
+            (u'lime', u'#00ff00', u'#0f0', u'hsl(120, 100%, 50%)'): 
+                (0, 255, 0, 1.0),
+            (u'rgba(255, 127, 0, .1)', u'rgba(100%, 50%, 0%, .1)'): 
+                (255, 127, 0, 0.1),
+            (u'transparent', u'rgba(0, 0, 0, 0)'): (0, 0, 0, 0),
+        }
+        for colors, rgba in tests.items():
+            for color in colors:
+                c = cssutils.css.ColorValue(color);
+                self.assertEquals(c.red, rgba[0])         
+                self.assertEquals(c.green, rgba[1])         
+                self.assertEquals(c.blue, rgba[2])         
+                self.assertEquals(c.alpha, rgba[3])
 
 
 class URIValueTestCase(basetest.BaseTestCase):
                 # returns list of tuples
                 return [('TYPE', v, 0, 0) for v in valuelist]
 
+
 if 1:
-    b = cssutils.util.Base()
-    tokens = maketokens(list('];x'))
-    ts = b._tokensupto2(tokens, (0,'[', 0, 0))
-    print ts
-    sys.exit(1)
+   
+    def hsl2rgb(h, s, l): 
+       
+        def hue2rgb(m1, m2, h): 
+           if h<0: h += 1 #PUT h+1 IN h
+           if h>1: h -= 1 #PUT h-1 IN h
+           if h*6<1: return m1+(m2-m1)*6*h
+           if h*2<1: return m2
+           if h*3<2: return m1+(m2-m1)*((2.0/3.0)-h)*6
+           return m1
+       
+        if l<=0.5: 
+            m2 = l*(s+1)
+        else: 
+            m2 = l+s-l*s
+           
+        m1 = l*2-m2
+        r = hue2rgb(m1, m2, h+(1.0/3.0))
+        g = hue2rgb(m1, m2, h)
+        b = hue2rgb(m1, m2, h-(1.0/3.0)) 
+        return r, g, b
     
-    #issue 50
-    #s = cssutils.parseString('[a]{color: green}')
-    s = cssutils.parseFile('sheets/acid2.css')
-    print s
-    print s.cssText
+    
 
+    #print '=', hsl2rgb(0.5, 1.0, 0.5)
+    cc = 'hsla(120, 100%, 50%, 1.0)'
+    print cc
+    c = cssutils.css.ColorValue(cc)
+    print 'rgb', c.red, c.green, c.blue
+        
+#    import colorsys
+#    raw = [0, 100, 50] 
+#    
+#    def frac(x, base):
+#        return (x) / float(base)
+#    
+#    print 'raw=', raw
+#    h, s, l = (frac(raw[0], 255), 
+#               frac(raw[1], 100), 
+#               frac(raw[2], 100))
+#    print 'hsl=', h, s, l
+#    r, g, b = colorsys.hls_to_rgb(h, l, s) # ORDER h l s !!!
+#    print 'rgb=', r, g, b
+#    rgba = [int(r*255), int(g*255), int(b*255)]
+#    print rgba
+    sys.exit(0)
+
+if 1:
+    #cssutils.ser.prefs.indentClosingBrace = False
+    css = '''
+    @media all {x {left: 0}}
+    
+    a {
+    outline: red;
+    }'''
+    print cssutils.parseString(css).cssText
+    sys.exit(0)
+    
 
 
 if 1:
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.