Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/pgu/fonts.py
blob: ab6f73d6c77edc9ce1428139278c7d8311079276 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""Some handy font-like objects.

<p>please note that this file is alpha, and is subject to modification in
future versions of pgu!</p>
"""

print 'pgu.fonts','This module is alpha, and is subject to change.'

import pygame
from pygame.locals import *

class TileFont:
    """Creates an instance of the TileFont class.  Interface compatible with pygame.Font
    
    <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
    fonts with stylized coloring.</p>
    
    <pre>TileFont(fname,size,hints,scale=None,sensitive=False)</pre>
    
    <dl>
    <dt>size <dd>the dimensions of the characters
    <dt>hints <dd>a string of hints "abcdefg..."
    <dt>scale <dd>size to scale font to
    <dt>sensitive <dd>case sensitivity
    </dl>
    """

    def __init__(self,fname,size,hints,scale=None,sensitive=False):
        
        self.image = pygame.image.load(fname)
        
        w,h = self.image.get_width(),self.image.get_height()
        tw,th = size
        if not scale: scale = size
        self._size = size
        self.scale = scale
        
        self.chars = {}
        x,y = 0,0
        self.sensitive = sensitive
        if not self.sensitive: hints = hints.lower()
        for c in hints:
            if c not in ('\r','\n','\t'):
                img = self.image.subsurface(x,y,tw,th)
                self.chars[c] = img
                x += tw
                if x >= w: x,y = 0,y+th
                
        self.colors = {}
                
    def size(self,text):
        tw,th = self.scale
        return len(text)*tw,th
        
    def render(self,text,antialias=0,color=(255,255,255),background=None):
        size = self.size(text)
        scale = self.scale
        tw,th = self._size
        if background == None:
            s = pygame.Surface(size).convert_alpha()
            s.fill((0,0,0,0))
        else:
            s = pygame.Surface(size).convert()
            s.fill(background)
            
        if not self.sensitive: text = text.lower()
        
        if color not in self.colors: self.colors[color] = {}
        colored = self.colors[color]
        
        x,y = 0,0
        for c in text:
            if c in self.chars:
                if c not in colored:
                    img = self.chars[c].convert_alpha()
                    for yy in xrange(0,th):
                        for xx in xrange(0,tw):
                            r,g,b,a = img.get_at((xx,yy))
                            if a > 128:
                                img.set_at((xx,yy),color)
                    colored[c] = img
                img = colored[c]
                if scale != (tw,th): img = pygame.transform.scale(img,scale)
                s.blit(img,(x,y))
            x += scale[0]
        return s
        
        
class BorderFont: 
    """a decorator for normal fonts, adds a border. Interface compatible with pygame.Font.
    
    <pre>BorderFont(font,size=1,color=(0,0,0))</pre>
    
    <dl>
    <dt>size <dd>width of border; defaults 0
    <dt>color <dd>color of border; default (0,0,0)
    </dl>
    """
    def __init__(self,font,size=1,color=(0,0,0)):
        
        self.font = font
        self._size = size
        self.color = color
                
    def size(self,text):
        w,h = self.font.size(text)
        s = self._size
        return w+s*2,h+s*2
        
    def render(self,text,antialias=0,color=(255,255,255),background=None):
        size = self.size(text)
        
        if background == None:
            s = pygame.Surface(size).convert_alpha()
            s.fill((0,0,0,0))
        else:
            s = pygame.Surface(size).convert()
            s.fill(background)
            
        bg = self.font.render(text,antialias,self.color)
        fg = self.font.render(text,antialias,color)
        
        si = self._size
        dirs = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
        for dx,dy in dirs: s.blit(bg,(si+dx*si,si+dy*si))
        s.blit(fg,(si,si))

        return s