adding fonts and ui elements

This commit is contained in:
cecilkorik 2011-10-21 21:11:42 -06:00
parent 1898b5ce49
commit 14f391013f
20 changed files with 991 additions and 6 deletions

2
.hgignore Normal file
View file

@ -0,0 +1,2 @@
syntax: glob
*.pyc

156
fonts.py Normal file
View file

@ -0,0 +1,156 @@
import os
import pygame
from OpenGL.GL import *
class TextureFile(object):
def __init__(self):
self.id = None
self.filename = None
self.h = None
self.w = None
def load(self, filename):
self.filename = filename
img = files.mgr.png(filename)
texid = glGenTextures(1)
print "Generated texture id %s" % (texid,)
self.id = texid
imgdata = pygame.image.tostring(img, "RGBA")
imgr = img.get_rect()
self.h = imgr.h
self.w = imgr.w
dimension = GL_TEXTURE_2D
glBindTexture(dimension, texid)
glTexImage2D(dimension, 0, GL_RGBA8, imgr.w, imgr.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgdata)
glBindTexture(dimension, 0)
class TexFont(object):
def __init__(self):
self.image = None
self.start = None
self.end = None
self.rows = None
self.cols = None
self.charheight = None
self.charwidth = None
self.texwidth = None
self.texheight = None
self.gltex = None
self.monospace = False
self.charsizes = []
@staticmethod
def new(fontdir, fontname):
tf = TexFont()
tf.load_definition(os.path.join(fontdir, "%s.tfd" % (fontname,)))
tf.load_texture(os.path.join(fontdir, "%s.png" % (fontname,)))
return tf
def mapchar(self, char):
"""
Maps a char to an index.
Takes a character either as ascii ordinal number or as a 1-length string.
Returns the index of that character in this texture font.
If the character is not valid in this texture font, the index number will
instead reference the last character in the font, which is usually a
symbol for unknown characters (either totally blank or a box.)
"""
if isinstance(char, basestring):
char = ord(char)
if char >= self.start and char < self.end:
return self.end - self.start - 1
else:
return char - self.start
def get_coordinates(self, idx):
"""
Maps an index to their x, y coordinates in the texture.
Invalid indexes will be mapped to the last character in the font.
"""
if idx < 0 or idx >= (self.end - self.start):
idx = (self.end - self.start - 1)
xp1 = (idx % self.cols) * self.charwidth
yp1 = (idx // self.cols) * self.charheight
if self.monospace:
xp2 = xp + self.charwidth
yp2 = yp + self.charheight
else:
xp2 = xp + self.charsizes[idx][0]
yp2 = yp + self.charsizes[idx][1]
xtc1 = (float(xp1) + 0.0) / self.texwidth
ytc1 = (float(yp1) + 0.0) / self.texheight
xtc2 = (float(xp2) - 1.0) / self.texwidth
ytc2 = (float(yp2) - 1.0) / self.texheight
return (xtc1, ytc1, xtc2, ytc2)
def load_definition(self, deffile):
"""
Loads a texture font definition (.tfd).
These simple datafiles are generated by fontmaker.py to provide character
spacing information about the associated texture font.
This should be called before load_texture.
"""
dd = open(deffile, 'r')
if dd.readline() != "fontheader\n":
raise ValueError('"%s" is not a font definition file' % (deffile,))
def nextline(dd):
return [int(x) for x in dd.readline().rstrip().split(',')]
self.start, self.end = nextline(dd)
self.charwidth, self.charheight = nextline(dd)
self.cols, self.rows = nextline(dd)
self.texwidth, self.texheight = nextline(dd)
assert dd.readline() == "charsizes\n"
self.charsizes = [None] * (self.end - self.start)
monospace = True
monoheight = True
for i in xrange(0, (self.end - self.start)):
x, y = nextline(dd)
if x != self.charwidth:
monospace = False
if y != self.charheight:
monoheight = False
self.charsizes[i] = (x, y)
"not yet capable of dealing properly with fonts of variable height"
assert monoheight
self.monospace = monospace
def load_texture(self, texfile):
"""
Loads a texture image (.png)
The PNG image should contain 32-bit color with alpha channel. The image
will be loaded as an OpenGL texture.
This function must be called after load_definition.
"""
tf = TextureFile()
tf.load(texfile)
self.gltex = tf
assert self.gltex.w == self.texwidth
assert self.gltex.h == self.texheight

View file

@ -34,14 +34,13 @@ def mainloop():
inputs.keydown(ev.key)
#elif ev.type == VIDEOEXPOSE:
# video.force_redraw()
elif ev.type in (MOUSEBUTTONDOWN, MOUSEBUTTONUP):
pass
if 'exit' in inputs.commands:
if 'exit' in inputs.commandsh:
break
video.predraw()
g_universe.frame()
g_universe.frame(events)
video.next_frame()

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,102 @@
fontheader
32,128
14,9
8,13
128,128
charsizes
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13
8,13

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,102 @@
fontheader
32,128
25,21
9,11
256,256
charsizes
5,24
6,24
7,24
13,24
11,24
17,24
13,24
4,24
7,24
7,24
8,24
11,24
6,24
7,24
6,24
6,24
11,24
12,24
12,24
11,24
12,24
11,24
11,24
11,24
11,24
11,24
6,24
6,24
12,24
11,24
12,24
12,24
20,24
15,24
14,24
14,24
15,24
14,24
12,24
15,24
15,24
6,24
10,24
14,24
12,24
17,24
15,24
16,24
14,24
16,24
14,24
13,24
13,24
15,24
14,24
19,24
14,24
14,24
13,24
6,24
6,24
6,24
9,24
11,24
7,24
11,24
11,24
10,24
11,24
11,24
7,24
11,24
11,24
4,24
5,24
10,24
4,24
16,24
11,24
12,24
11,24
11,24
7,24
11,24
7,24
11,24
10,24
15,24
10,24
10,24
11,24
7,24
6,24
8,24
12,24
6,24

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -0,0 +1,102 @@
fontheader
32,128
49,43
10,11
512,512
charsizes
11,48
12,48
15,48
25,48
23,48
38,48
28,48
8,48
15,48
15,48
16,48
24,48
12,48
13,48
12,48
12,48
24,48
24,48
23,48
24,48
24,48
24,48
24,48
23,48
24,48
24,48
12,48
12,48
24,48
24,48
24,48
24,48
42,48
30,48
27,48
30,48
30,48
28,48
26,48
33,48
30,48
12,48
21,48
28,48
23,48
34,48
30,48
33,48
28,48
33,48
30,48
28,48
26,48
30,48
28,48
40,48
28,48
28,48
26,48
12,48
12,48
12,48
20,48
24,48
14,48
24,48
23,48
21,48
23,48
23,48
13,48
23,48
24,48
10,48
12,48
22,48
10,48
36,48
24,48
22,48
23,48
23,48
15,48
21,48
12,48
24,48
21,48
31,48
21,48
21,48
21,48
14,48
11,48
13,48
25,48
12,48

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,102 @@
fontheader
32,128
11,7
8,13
128,128
charsizes
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,102 @@
fontheader
32,128
12,8
8,12
128,128
charsizes
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11
7,11

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,102 @@
fontheader
32,128
11,7
8,13
128,128
charsizes
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10
6,10

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1,102 @@
fontheader
32,128
16,9
8,14
128,128
charsizes
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15
8,15

93
tools/fontmaker.py Normal file
View file

@ -0,0 +1,93 @@
import os
import pygame
import sys
import math
pygame.init()
pygame.font.init()
assert pygame.font.get_init()
fmod = pygame.font
Font = pygame.font.Font
fontname, fontsize = sys.argv[1:]
if '/' in fontname:
ffile = fontname
fontname = os.path.splitext(os.path.split(fontname)[1])[0].lower()
else:
ffile = fmod.match_font(fontname)
if not ffile:
print "Unable to find font... here is a list of fonts:\n"
for x in sorted(fmod.get_fonts()):
print x
sys.exit(0)
fontsize = int(fontsize)
fontname = "%s%s" % (fontname, fontsize)
f = Font(ffile, fontsize)
start = 32
end = 128
images = []
imsizes = []
maxwidth = 0
maxheight = 0
for char in xrange(start, end):
letter = chr(char)
sz = f.size(letter)
maxwidth = max(maxwidth, sz[0])
maxheight = max(maxheight, sz[1])
im = f.render(letter, True, (255, 255, 255))
images.append(im)
imsizes.append(sz)
print len(images)
maxwidth += 1
maxheight += 1
ratio = float(maxwidth) / float(maxheight)
print "Ratio %s" % (ratio,)
reqwidth = maxwidth * len(images)
ratioheight = int(math.ceil(math.sqrt(len(images) * ratio)))
ratiowidth = int(math.ceil(len(images) / math.sqrt(len(images) * ratio)))
print [ratioheight, ratiowidth]
reqwidth = maxwidth * ratiowidth
reqheight = maxheight * ratioheight
print [reqheight, reqwidth]
texsize = 16
while texsize < reqheight or texsize < reqwidth:
texsize *= 2
print texsize
tex = pygame.Surface((texsize, texsize), pygame.SRCALPHA, 32)
tex.fill((0, 0, 0, 0))
for i, im in enumerate(images):
tex.blit(im, (((i % ratiowidth) * maxwidth), ((i // ratiowidth) * maxheight)))
pygame.image.save(tex, "%s.png" % (fontname,))
datf = open("%s.tfd" % (fontname,), "w")
datf.write("fontheader\n")
datf.write("%s,%s\n" % (start, end))
datf.write("%s,%s\n" % (maxheight, maxwidth))
datf.write("%s,%s\n" % (ratioheight, ratiowidth))
datf.write("%s,%s\n" % (texsize, texsize))
datf.write("charsizes\n")
for i, sz in enumerate(imsizes):
datf.write("%s,%s\n" % (sz[0], sz[1]))
datf.close()

View file

@ -11,7 +11,7 @@ class base_universe(object):
def init(self):
pass
def frame(self):
def frame(self, events):
pass
def update(self):
@ -27,6 +27,6 @@ class tiled_universe(base_universe):
def init(self):
pass
def frame(self):
def frame(self, events):
pass

21
widgets.py Normal file
View file

@ -0,0 +1,21 @@
class BaseWidget(object):
def __init__(self):
pass
class InvisibleWidget(BaseWidget):
pass
class BoxWidget(BaseWidget):
def __init__(self, pos):
self.pos = pos
self.border = None
self.background = None
class Button(BoxWidget):
def __init__(self, pos, label, callback):
BoxWidget.__init__(self, pos)
def