Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Font.set_linesize() (TTF 2.24.0 feature) #3282

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

itzpr3d4t0r
Copy link
Member

We've long had the ability to get the line size with get_linesize(), but we've never had the ability to set the spacing between lines when rendering multiline text. Thanks to SDL_TTF 2.24.0 this PR adds the functionality.

@itzpr3d4t0r itzpr3d4t0r added New API This pull request may need extra debate as it adds a new class or function to pygame font pygame.font labels Jan 5, 2025
@itzpr3d4t0r itzpr3d4t0r requested a review from a team as a code owner January 5, 2025 13:04
@itzpr3d4t0r itzpr3d4t0r marked this pull request as draft January 7, 2025 18:15
@Starbuck5
Copy link
Member

Starbuck5 commented Jan 28, 2025

@itzpr3d4t0r I believe your tests are failing here because it runs the test suite over font as well as ftfont, and ftfont doesn't support this feature. Some other font tests specifically exclude themselves from running on ftfont.

@itzpr3d4t0r itzpr3d4t0r marked this pull request as ready for review February 15, 2025 21:48
Copy link
Member

@damusss damusss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As much as I don't like set_/get_ methods, get_linesize was already there, so not adding it would be rather weird (we can have just properties with pygame 3, I guess!). And Font.linesize can be added by another PR, too, so this LGTM, thanks for adding it :)

Set the height in pixels for a line of text with the font. When rendering
multiple lines of text this refers to the amount of space between lines.

.. ## Font.set_linesize ##
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a "new in version" entry

return NULL;

if (linesize < 0)
return RAISE(PyExc_ValueError, "linesize must be >= 0");
Copy link
Member

@Starbuck5 Starbuck5 Feb 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does SDL_ttf do if this isn't true? Also could be good to specify in the docs that this needs to be a positive number including zero.


#if SDL_TTF_VERSION_ATLEAST(2, 24, 0)
TTF_Font *font = PyFont_AsFont(self);
int linesize = PyLong_AsLong(arg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried passing a float in and got a deprecation error:

C:\Users\charl\Desktop\test.py:31: DeprecationWarning: an integer is required (got type float).  Implicit conversion to integers using __int__ is deprecated, and may be removed in a future version of Python.
  font.set_linesize(0.11)

@Starbuck5
Copy link
Member

This will be a great feature to get in! Left a few small notes / a question.

Wrote a sample program to test around with:

import pygame

pygame.init()
screen = pygame.display.set_mode((680, 420))
clock = pygame.time.Clock()
running = True

font = pygame.font.SysFont("Arial", 32)

def generate_text():
    return font.render(
        "Hello world\nThis is an example of\nmultiline text\nusing different spacings.",
        True,
        "black",
    )

text = generate_text()

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
            font.set_linesize(font.get_linesize() + 5)
            print(font.get_linesize())
            text = generate_text()

        if event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN:
            font.set_linesize(font.get_linesize() - 5)
            print(font.get_linesize())
            text = generate_text()

    screen.fill("purple")

    for i in range(4):
        pygame.draw.rect(
            screen,
            "orangered" if i % 2 else "lightblue",
            [0, i * font.get_linesize(), 300, font.get_linesize()],
        )

    screen.blit(text)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
font pygame.font New API This pull request may need extra debate as it adds a new class or function to pygame
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants