File fretsonfire-1.3.110-font-revert.patch of Package fretsonfire
--- src/Font.py
+++ src/Font.py
@@ -21,26 +21,22 @@
#####################################################################
import pygame
-import numpy
from OpenGL.GL import *
import sys
-from Texture import Texture, TextureAtlas, TextureAtlasFullException
+from Texture import Texture
class Font:
"""A texture-mapped font."""
def __init__(self, fileName, size, bold = False, italic = False, underline = False, outline = True,
scale = 1.0, reversed = False, systemFont = False):
pygame.font.init()
- self.size = size
- self.scale = scale
- self.glyphCache = {}
- self.glyphSizeCache = {}
- self.outline = outline
- self.glyphTextures = []
- self.reversed = reversed
- self.stringCache = {}
- self.stringCacheLimit = 256
+ self.size = size
+ self.scale = scale
+ self.glyphCache = {}
+ self.glyphSizeCache = {}
+ self.outline = outline
+ self.reversed = reversed
# Try loading a system font first if one was requested
self.font = None
if systemFont and sys.platform != "win32":
@@ -91,71 +87,11 @@ class Font:
"""
texture.setFilter(GL_LINEAR, GL_LINEAR)
texture.setRepeat(GL_CLAMP, GL_CLAMP)
- self.glyphCache[character] = (texture, (0.0, 0.0, texture.size[0], texture.size[1]))
+ self.glyphCache[character] = texture
s = .75 * self.getHeight() / float(texture.pixelSize[0])
self.glyphSizeCache[character] = (texture.pixelSize[0] * s, texture.pixelSize[1] * s)
- def _renderString(self, text, pos, direction, scale):
- if not text:
- return
-
- if not (text, scale) in self.stringCache:
- currentTexture = None
- #x, y = pos[0], pos[1]
- x, y = 0.0, 0.0
- vertices = numpy.empty((4 * len(text), 2), numpy.float32)
- texCoords = numpy.empty((4 * len(text), 2), numpy.float32)
- vertexCount = 0
- cacheEntry = []
-
- for i, ch in enumerate(text):
- g, coordinates = self.getGlyph(ch)
- w, h = self.getStringSize(ch, scale = scale)
- tx1, ty1, tx2, ty2 = coordinates
-
- # Set the initial texture
- if currentTexture is None:
- currentTexture = g
-
- # If the texture changed, flush the geometry
- if currentTexture != g:
- cacheEntry.append((currentTexture, vertexCount, numpy.array(vertices[:vertexCount]), numpy.array(texCoords[:vertexCount])))
- currentTexture = g
- vertexCount = 0
-
- vertices[vertexCount + 0] = (x, y)
- vertices[vertexCount + 1] = (x + w, y)
- vertices[vertexCount + 2] = (x + w, y + h)
- vertices[vertexCount + 3] = (x, y + h)
- texCoords[vertexCount + 0] = (tx1, ty2)
- texCoords[vertexCount + 1] = (tx2, ty2)
- texCoords[vertexCount + 2] = (tx2, ty1)
- texCoords[vertexCount + 3] = (tx1, ty1)
- vertexCount += 4
-
- x += w * direction[0]
- y += w * direction[1]
- cacheEntry.append((currentTexture, vertexCount, vertices[:vertexCount], texCoords[:vertexCount]))
-
- # Don't store very short strings
- if len(text) > 5:
- # Limit the cache size
- if len(self.stringCache) > self.stringCacheLimit:
- del self.stringCache[self.stringCache.keys()[0]]
- self.stringCache[(text, scale)] = cacheEntry
- else:
- cacheEntry = self.stringCache[(text, scale)]
-
- glPushMatrix()
- glTranslatef(pos[0], pos[1], 0)
- for texture, vertexCount, vertices, texCoords in cacheEntry:
- texture.bind()
- glVertexPointer(2, GL_FLOAT, 0, vertices)
- glTexCoordPointer(2, GL_FLOAT, 0, texCoords)
- glDrawArrays(GL_QUADS, 0, vertexCount)
- glPopMatrix()
-
- def render(self, text, pos = (0, 0), direction = (1, 0), scale = 0.002):
+ def render(self, text, pos = (0, 0), direction = (1, 0, 0), scale = 0.002):
"""
Draw some text.
@@ -169,43 +105,75 @@ class Font:
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
scale *= self.scale
-
+ glPushMatrix()
+ glTranslatef(pos[0], pos[1], 0)
+
if self.reversed:
text = "".join(reversed(text))
if self.outline:
glPushAttrib(GL_CURRENT_BIT)
- glColor4f(0, 0, 0, glGetFloatv(GL_CURRENT_COLOR)[3])
- self._renderString(text, (pos[0] + 0.003, pos[1] + 0.003), direction, scale)
+ glPushMatrix()
+ glColor4f(0, 0, 0, .25 * glGetDoublev(GL_CURRENT_COLOR)[3])
+ for ch in text:
+ g = self.getGlyph(ch)
+ w, h = self.getStringSize(ch, scale = scale)
+ tw, th = g.size
+
+ glVertexPointerf([(0.0, 0.0, 0.0), (w, 0.0, 0.0), (0.0, h, 0.0), (w, h, 0.0)])
+ glTexCoordPointerf([(0.0, th), (tw, th), (0.0, 0.0), (tw, 0.0)])
+
+ g.bind()
+
+ blur = 2 * 0.002
+ for offset in [(-.7, -.7), (0, -1), (.7, -.7), (-1, 0), (1, 0), (-.7, .7), (0, 1), (.7, .7)]:
+ glPushMatrix()
+ glTranslatef( blur * offset[0], blur * offset[1], 0)
+ glDrawElementsui(GL_TRIANGLE_STRIP, [0, 1, 2, 3])
+ glPopMatrix()
+
+ glTranslatef(w * direction[0],
+ w * direction[1],
+ w * direction[2])
+
glPopAttrib()
+ glPopMatrix()
+
+ for ch in text:
+ g = self.getGlyph(ch)
+ w, h = self.getStringSize(ch, scale = scale)
+ tw, th = g.size
+
+ glVertexPointerf([(0.0, 0.0, 0.0), (w, 0.0, 0.0), (0.0, h, 0.0), (w, h, 0.0)])
+ glTexCoordPointerf([(0.0, th), (tw, th), (0.0, 0.0), (tw, 0.0)])
+
+ g.bind()
+ glDrawElementsui(GL_TRIANGLE_STRIP, [0, 1, 2, 3])
+
+ glTranslatef(w * direction[0],
+ w * direction[1],
+ w * direction[2])
+
+ glPopMatrix()
- self._renderString(text, pos, direction, scale)
-
glDisableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_TEXTURE_COORD_ARRAY)
glDisable(GL_TEXTURE_2D)
- def _allocateGlyphTexture(self):
- t = TextureAtlas(size = glGetInteger(GL_MAX_TEXTURE_SIZE))
- t.texture.setFilter(GL_LINEAR, GL_LINEAR)
- t.texture.setRepeat(GL_CLAMP, GL_CLAMP)
- self.glyphTextures.append(t)
- return t
-
def getGlyph(self, ch):
"""
- Get a (L{Texture}, coordinate tuple) pair for a given character.
+ Get the L{Texture} for a given character.
@param ch: Character
- @return: (L{Texture} instance, coordinate tuple)
+ @return: L{Texture} instance
"""
try:
return self.glyphCache[ch]
except KeyError:
s = self.font.render(ch, True, (255, 255, 255))
- # Draw outlines
"""
+ # Draw outlines
import Image, ImageFilter
srcImg = Image.fromstring("RGBA", s.get_size(), pygame.image.tostring(s, "RGBA"))
img = Image.fromstring("RGBA", s.get_size(), pygame.image.tostring(s, "RGBA"))
@@ -222,19 +190,11 @@ class Font:
img.putpixel((x, y), (0, 0, 0, a / n))
s = pygame.image.fromstring(img.tostring(), s.get_size(), "RGBA")
"""
-
- if not self.glyphTextures:
- texture = self._allocateGlyphTexture()
- else:
- texture = self.glyphTextures[-1]
-
- # Insert the texture into the glyph cache
- try:
- coordinates = texture.add(s)
- except TextureAtlasFullException:
- # Try again with a fresh atlas
- texture = self._allocateGlyphTexture()
- return self.getGlyph(ch)
-
- self.glyphCache[ch] = (texture, coordinates)
- return (texture, coordinates)
+
+ t = Texture()
+ t.setFilter(GL_LINEAR, GL_LINEAR)
+ t.setRepeat(GL_CLAMP, GL_CLAMP)
+ t.loadSurface(s, alphaChannel = True)
+ del s
+ self.glyphCache[ch] = t
+ return t