@@ -681,44 +681,59 @@ def arrow(x, y, width, **kwargs):
681
681
glVertex2f (x , y )
682
682
glEnd ()
683
683
684
+ def gcd (a , b ):
685
+ return gcd (b , a % b ) if b else a
686
+
687
+ _stars = {} #TODO: LRU?
684
688
def star (x , y , points = 20 , outer = 100 , inner = 50 , ** kwargs ):
685
689
""" Draws a star with the given points, outer radius and inner radius.
686
690
The current stroke, strokewidth and fill color are applied.
687
691
"""
688
- radii = [outer , inner ] * int (points + 1 ); radii .pop () # which radius?
689
- f = pi / points
690
- v = [(x + r * sin (i * f ), y + r * cos (i * f )) for i , r in enumerate (radii )]
691
-
692
692
if kwargs .get ("draw" , True ):
693
- fill , stroke , strokewidth , strokestyle = color_mixin (** kwargs )
694
-
695
- if fill is not None :
696
- glColor4f (fill [0 ], fill [1 ], fill [2 ], fill [3 ] * _alpha )
697
-
698
- glBegin (GL_TRIANGLE_FAN )
699
- glVertex2f (x , y )
700
- for (vx , vy ) in v :
701
- glVertex2f (vx , vy )
702
- glEnd ()
703
-
704
- if stroke is not None and 0 < strokewidth :
705
- glLineWidth (strokewidth )
706
- if strokestyle != _strokestyle :
707
- glLineDash (strokestyle )
708
- glColor4f (stroke [0 ], stroke [1 ], stroke [2 ], stroke [3 ] * _alpha )
693
+ scale = gcd (inner , outer )
694
+ iscale = inner / scale
695
+ oscale = outer / scale
696
+ cached = _stars .get ((points , iscale , oscale ), [])
697
+ if not cached :
698
+ radii = [oscale , iscale ] * int (points + 1 ); radii .pop () # which radius?
699
+ f = pi / points
700
+ v = [(r * sin (i * f ), r * cos (i * f )) for i , r in enumerate (radii )]
701
+ cached .append (precompile (lambda :(
702
+ glBegin (GL_TRIANGLE_FAN ),
703
+ glVertex2f (0 , 0 ),
704
+ [glVertex2f (vx , vy ) for (vx , vy ) in v ],
705
+ glEnd ()
706
+ )))
707
+ cached .append (precompile (lambda :(
708
+ glBegin (GL_LINE_LOOP ),
709
+ [glVertex2f (vx , vy ) for (vx , vy ) in v ],
710
+ glEnd ()
711
+ )))
712
+ _stars [(points , iscale , oscale )] = cached
709
713
710
- glBegin (GL_LINE_LOOP )
711
- for (vx , vy ) in v :
712
- glVertex2f (vx , vy )
713
- glEnd ()
714
+ fill , stroke , strokewidth , strokestyle = color_mixin (** kwargs )
715
+ for i , clr in enumerate ((fill , stroke )):
716
+ if clr is not None and (i == 0 or strokewidth > 0 ):
717
+ if i == 1 :
718
+ glLineWidth (strokewidth )
719
+ if strokestyle != _strokestyle :
720
+ glLineDash (strokestyle )
721
+ glColor4f (clr [0 ], clr [1 ], clr [2 ], clr [3 ] * _alpha )
722
+ glPushMatrix ()
723
+ glTranslatef (x , y , 0 )
724
+ glScalef (scale , scale , 1 )
725
+ glCallList (cached [i ])
726
+ glPopMatrix ()
714
727
else :
715
728
# For whatever reason, the original api specified that you
716
- # can get the path to the star. This is about 20x slower,
729
+ # can get the path to the star. This is about 30x slower,
717
730
# but I'm keeping it here for backwards compatibility.
718
731
p = BezierPath (** kwargs )
719
732
p .moveto (x , y + outer )
720
- for (vx , vy ) in v :
721
- p .lineto (vx , vy )
733
+ for i in range (0 , int (2 * points )+ 1 ):
734
+ r = (outer , inner )[i % 2 ]
735
+ a = pi * i / points
736
+ p .lineto (x + r * sin (a ), y + r * cos (a ))
722
737
p .closepath ()
723
738
return p
724
739
@@ -1486,7 +1501,8 @@ def texture(img, data=None):
1486
1501
return _texture_cache [img ]
1487
1502
# Image file path, load it, cache it, return texture.
1488
1503
if isinstance (img , basestring ):
1489
- try : cache (img , pyglet .image .load (img ).get_texture ())
1504
+ try :
1505
+ cache (img , pyglet .image .load (img ).get_texture ())
1490
1506
except IOError :
1491
1507
raise ImageError , "can't load image from %s" % repr (img )
1492
1508
return _texture_cache [img ]
0 commit comments