bzm3r
bzm3r

Reputation: 4596

Pyglet: why does the text in my example become fuzzy when I resize the window?

In the following toy example, I have a text layout in a resize-able window. When the window is re-sized, the text becomes fuzzy for some resolutions (give it a try). Why is that?

import pyglet

width, height = 500, 500
window = pyglet.window.Window(width, height, resizable=True)

batch = pyglet.graphics.Batch()

document = pyglet.text.document.FormattedDocument()
document.insert_text(0, 'Hello world!', attributes=dict(font_name='Arial', font_size=12, color=(255, 255, 255, 255)))
layout = pyglet.text.layout.IncrementalTextLayout(document, width, height, multiline=True, batch=batch)

# for drawing graphics
pyglet.gl.glLineWidth(3)
outline = batch.add(4, pyglet.gl.GL_LINE_LOOP, None, ('v2f', (0, 0, width, 0, width, height, 0, height)), ('c4B', (255, 0, 0, 0)*4))


@window.event
def on_resize(width, height):
    document.delete_text(0, len(document.text))
    document.insert_text(0, "Layout has been resized to {}x{}".format(0.9*width, 0.9*height))
    layout.width = 0.9*width
    layout.height = 0.9*height
    layout.x = (width - layout.width)*0.5
    layout.y = (height - layout.height)*0.5
    outline.vertices = (layout.x, layout.y, layout.width + layout.x, layout.y, layout.width + layout.x, layout.height + layout.y, layout.x, layout.height + layout.y)

@window.event
def on_draw():
    window.clear()
    batch.draw()

pyglet.app.run()

Upvotes: 1

Views: 554

Answers (2)

Gábor Fekete
Gábor Fekete

Reputation: 1358

I had the same problem and I made it work like this:

You will need a wrapper class which will have the on_resize event handler. Also it needs the parent window.

class Label(pyglet.text.Label):
    def __init__(self, window,**kwargs):
        self.window = window
        self.window.push_handlers(self)
        self.init_settings = dict()
        for k,v in kwargs.items():
            if callable(v):
                kwargs[k] = v(self.window)
                self.init_settings[k] = v
        super().__init__(**kwargs)

    def on_resize(self, width, height):
        for k,v in self.init_settings.items():
            setattr(self,k,v(self.window))

Usage: Each property you need to update on resizing the window will be a lambda function. Here you should write the initial values of the label with the initial window sizes.

class WindowSubclass(pyglet.window.Window):
    def __init__(self,*args,**kwargs):
        self.initial_size = self.width,self.height
        self.label = Label(window=self,
                            text='PAUSED',
                            multiline=False,
                            font_name='Times New Roman',
                            bold=True,
                            font_size=lambda win:24*win.height/win.initial_height,
                            width=lambda win:win.width/4,
                            x=lambda win:win.width/2,
                            y=lambda win:win.height/2,
                            color=(255, 255, 255, 255),
                            anchor_x='center', anchor_y='center')

Upvotes: 0

bzm3r
bzm3r

Reputation: 4596

Things start to become wonky because the layout is being given decimal width and height. Fixing that removes the fuzzy text issues:

import pyglet

width, height = 500, 500
window = pyglet.window.Window(width, height, resizable=True)

batch = pyglet.graphics.Batch()

document = pyglet.text.document.FormattedDocument()
document.insert_text(0, 'Hello world!', attributes=dict(font_name='Arial', font_size=12, color=(255, 255, 255, 255)))
layout = pyglet.text.layout.IncrementalTextLayout(document, width, height, multiline=True, batch=batch)

# for drawing graphics
pyglet.gl.glLineWidth(3)
outline = batch.add(4, pyglet.gl.GL_LINE_LOOP, None, ('v2f', (0, 0, width, 0, width, height, 0, height)), ('c4B', (255, 0, 0, 0)*4))


@window.event
def on_resize(width, height):
    width, height = int(width), int(height)
    window.set_size(width, height)
    layout_width, layout_height = int(0.9*width), int(0.9*height)
    document.delete_text(0, len(document.text))
    document.insert_text(0, "Layout has been resized to {}x{}".format(layout_width, layout_height))
    layout.width, layout.height = layout_width, layout_height
    layout.x = int((width - layout_width)*0.5)
    layout.y = int((height - layout_height)*0.5)
    outline.vertices = (layout.x, layout.y, layout.width + layout.x, layout.y, layout.width + layout.x, layout.height + layout.y, layout.x, layout.height + layout.y)

@window.event
def on_draw():
    window.clear()
    batch.draw()

pyglet.app.run()

Upvotes: 1

Related Questions