Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - PythonFanboy

Pages: [1]
1
I'm writting a simple bitmap font renderer in pySFML and wanted to ask is there a better and faster way to approach this problem. Don't really know if my approach is optimal.

I'm using VertexArray (http://www.python-sfml.org/api/graphics.html#id22) and create a quad for each character in a string. Each quad has appropriate texture coordinates applied.

Example font (PNG file):

Font rendering code:

import sfml


class BitmapFont(object):
    '''
    Loads a bitmap font.
    `chars` is string with all characters available in the font file, example: '+0123456789x'.
    `widths` is mapping between characters and character width in pixels.
    '''

    def __init__(self, path, chars, widths, colors=1, kerning=0):
        self.texture = sfml.Texture.from_file(path)
        self.colors = colors
        self.height = self.texture.height / self.colors
        self.chars = chars
        self.kerning = kerning
        self.widths = widths

        self.glyphs = []
        y = 0
        for color in range(self.colors):
            x = 0
            self.glyphs.append({})
            for char in self.chars:
                glyph_pos = x, y
                glyph_size = self.widths[char], self.height
                glyph = sfml.Rectangle(glyph_pos, glyph_size)
                self.glyphs[color][char] = glyph
                x += glyph.width
            y += self.height


class BitmapText(sfml.TransformableDrawable):
    '''Used to render text with `BitmapFonts`.'''

    def __init__(self, string='', font=None, color=0, align='left', position=(0, 0)):
        super().__init__()
        self.vertices = sfml.VertexArray(sfml.PrimitiveType.QUADS, 4)
        self.font = font
        self.color = color
        self._string = ''
        self.string = string
        self.position = position

    @property
    def string(self):
        return self._string

    @string.setter
    def string(self, value):
        '''Calculates new vertices each time string has changed.'''
        # This function is slowest and probably can be optimized.

        if value == self._string:
            return
        if len(value) != len(self._string):
            self.vertices.resize(4 * len(value))
        self._string = value
        x = 0
        y = 0
        vertices = self.vertices
        glyphs = self.font.glyphs[self.color]
        for i, char in enumerate(self._string):
            glyph = glyphs[char]
            p = i * 4
            vertices[p + 0].position = x, y
            vertices[p + 1].position = x + glyph.width, y
            vertices[p + 2].position = x + glyph.width, y + glyph.height
            vertices[p + 3].position = x, y + glyph.height
            vertices[p + 0].tex_coords = glyph.left, glyph.top
            vertices[p + 1].tex_coords = glyph.right, glyph.top
            vertices[p + 2].tex_coords = glyph.right, glyph.bottom
            vertices[p + 3].tex_coords = glyph.left, glyph.bottom
            x += glyph.width + self.font.kerning

    def draw(self, target, states):
        '''Draws whole string using texture from a font.'''
        states.texture = self.font.texture
        states.transform = self.transform
        target.draw(self.vertices, states)
 

Simple example usage with benchmark (FPS counter) is attached.

I'm using Python 3.3, pySFML 1.3, SFML 2.0 and Windows.

Note, that I've asked same question on StackOverflow, but nobody replied, so I've decided here would be a better place to ask.

2
Python / [Solved] Sprite.position.x/y read-only? Yes :(
« on: November 02, 2013, 09:17:34 pm »
I can't move a sprite, changes to Sprite.position.x/y are ignored. I'm doing something wrong or this is a bug in pySFML?

In [1]: import sfml

In [2]: texture = sfml.Texture.from_file('fire.png')

In [3]: sprite = sfml.Sprite(texture)

In [4]: sprite.position
Out[4]: sf.Vector2(0.0x, 0.0y)

In [5]: sprite.position.x = 300  # Doesn't work?

In [6]: sprite.position
Out[6]: sf.Vector2(0.0x, 0.0y)

I'm using Python 3.3, SFML 2.0 and pySFML 1.3.

Pages: [1]