roc/fonts.py
cecilkorik ab901dc58f Added platform specific architecture and cleaned up some of the platform
specific hacks in video.py
Added a config file (settings.cfg)
Added functionality for saving last used window position!
Added displaylists to models.py
Broke fonts (temporarily)
2011-10-23 01:42:40 -06:00

158 lines
No EOL
4.1 KiB
Python

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 render
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