retrait TODO.
[minwii.git] / src / pgu / fonts.py
1 """Some handy font-like objects.
2
3 <p>please note that this file is alpha, and is subject to modification in
4 future versions of pgu!</p>
5 """
6
7 print 'pgu.fonts','This module is alpha, and is subject to change.'
8
9 import pygame
10 from pygame.locals import *
11
12 class TileFont:
13 """Creates an instance of the TileFont class. Interface compatible with pygame.Font
14
15 <p>TileFonts are fonts that are stored in a tiled image. Where the image opaque, it assumed that the font is visible. Font color is changed automatically, so it does not work with
16 fonts with stylized coloring.</p>
17
18 <pre>TileFont(fname,size,hints,scale=None,sensitive=False)</pre>
19
20 <dl>
21 <dt>size <dd>the dimensions of the characters
22 <dt>hints <dd>a string of hints "abcdefg..."
23 <dt>scale <dd>size to scale font to
24 <dt>sensitive <dd>case sensitivity
25 </dl>
26 """
27
28 def __init__(self,fname,size,hints,scale=None,sensitive=False):
29
30 self.image = pygame.image.load(fname)
31
32 w,h = self.image.get_width(),self.image.get_height()
33 tw,th = size
34 if not scale: scale = size
35 self._size = size
36 self.scale = scale
37
38 self.chars = {}
39 x,y = 0,0
40 self.sensitive = sensitive
41 if not self.sensitive: hints = hints.lower()
42 for c in hints:
43 if c not in ('\r','\n','\t'):
44 img = self.image.subsurface(x,y,tw,th)
45 self.chars[c] = img
46 x += tw
47 if x >= w: x,y = 0,y+th
48
49 self.colors = {}
50
51 def size(self,text):
52 tw,th = self.scale
53 return len(text)*tw,th
54
55 def render(self,text,antialias=0,color=(255,255,255),background=None):
56 size = self.size(text)
57 scale = self.scale
58 tw,th = self._size
59 if background == None:
60 s = pygame.Surface(size).convert_alpha()
61 s.fill((0,0,0,0))
62 else:
63 s = pygame.Surface(size).convert()
64 s.fill(background)
65
66 if not self.sensitive: text = text.lower()
67
68 if color not in self.colors: self.colors[color] = {}
69 colored = self.colors[color]
70
71 x,y = 0,0
72 for c in text:
73 if c in self.chars:
74 if c not in colored:
75 img = self.chars[c].convert_alpha()
76 for yy in xrange(0,th):
77 for xx in xrange(0,tw):
78 r,g,b,a = img.get_at((xx,yy))
79 if a > 128:
80 img.set_at((xx,yy),color)
81 colored[c] = img
82 img = colored[c]
83 if scale != (tw,th): img = pygame.transform.scale(img,scale)
84 s.blit(img,(x,y))
85 x += scale[0]
86 return s
87
88
89 class BorderFont:
90 """a decorator for normal fonts, adds a border. Interface compatible with pygame.Font.
91
92 <pre>BorderFont(font,size=1,color=(0,0,0))</pre>
93
94 <dl>
95 <dt>size <dd>width of border; defaults 0
96 <dt>color <dd>color of border; default (0,0,0)
97 </dl>
98 """
99 def __init__(self,font,size=1,color=(0,0,0)):
100
101 self.font = font
102 self._size = size
103 self.color = color
104
105 def size(self,text):
106 w,h = self.font.size(text)
107 s = self._size
108 return w+s*2,h+s*2
109
110 def render(self,text,antialias=0,color=(255,255,255),background=None):
111 size = self.size(text)
112
113 if background == None:
114 s = pygame.Surface(size).convert_alpha()
115 s.fill((0,0,0,0))
116 else:
117 s = pygame.Surface(size).convert()
118 s.fill(background)
119
120 bg = self.font.render(text,antialias,self.color)
121 fg = self.font.render(text,antialias,color)
122
123 si = self._size
124 dirs = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
125 for dx,dy in dirs: s.blit(bg,(si+dx*si,si+dy*si))
126 s.blit(fg,(si,si))
127
128 return s
129
130