Have an outline of text in Pygame

walid :

So I have this function in which it puts text on the screen:

def text_speech(font : str ,size : int,text : str,color,x,y, bold : bool):
    SCREEN = width, height = 900, 600
    font = pygame.font.Font(font,size)
    font.set_bold(bold)
    text = font.render(text, True, color)
    textRect = text.get_rect()
    textRect.center = (x,y)
    screen.blit(text,textRect)

If I do this:

screen.fill((0,0,0))
text_speed('arialnarrow.ttf', 40, 'Hello', (255,255,255), (width/2), (height/2), False)

It generates the world 'Hello' on a black screen with white text. Is it possible that if the user hovers their mouse over this, it creates a red (255,0,0) outline?

Rabbid76 :

To accomplish an outline you have to blit the multiple times. Render the text in the outline color (red):

outlineSurf = font.render(text, True, (255, 0, 0))
outlineSize = outlineSurf.get_size()

Create a surface which is grater than the text surface. The width and the height have to be increased by the doubled outline thickness:

textSurf = pygame.Surface((outlineSize[0] + outline*2, outlineSize[1] + 2*outline))
textRect = textSurf.get_rect()

Blit the outline surface 8 times on the text surface, shifted by the outline thickness (horizontal, vertical and diagonal:

offsets = [(ox, oy) 
    for ox in range(-outline, 2*outline, outline)
    for oy in range(-outline, 2*outline, outline)
    if ox != 0 or ox != 0]
for ox, oy in offsets:   
    px, py = textRect.center
    textSurf.blit(outlineSurf, outlineSurf.get_rect(center = (px+ox, py+oy))) 

Render the text with the text color and convert the surface to a per pixel alpha format (convert_alpha):

innerText = font.render(text, True, color).convert_alpha()

Blit the text in the middle of textSurf:

textSurf.blit(innerText, innerText.get_rect(center = textRect.center)) 

Blit textSurf onto the window:

textRect.center = (x,y)
screen.blit(textSurf, textRect)

See the example:

import pygame
import pygame.font

pygame.init()

width, height = 400, 300
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
textRect = pygame.Rect(0, 0, 0, 0)

def text_speech(font : str, size : int, text : str, color, x, y, bold : bool, outline: int):
    global textRect 
    # font = pygame.font.Font(font,size)
    font = pygame.font.SysFont(None, size)
    font.set_bold(True)
    if outline > 0:
        outlineSurf = font.render(text, True, (255, 0, 0))
        outlineSize = outlineSurf.get_size()
        textSurf = pygame.Surface((outlineSize[0] + outline*2, outlineSize[1] + 2*outline))
        textRect = textSurf.get_rect()
        offsets = [(ox, oy) 
            for ox in range(-outline, 2*outline, outline)
            for oy in range(-outline, 2*outline, outline)
            if ox != 0 or ox != 0]
        for ox, oy in offsets:   
            px, py = textRect.center
            textSurf.blit(outlineSurf, outlineSurf.get_rect(center = (px+ox, py+oy))) 
        innerText = font.render(text, True, color).convert_alpha()
        textSurf.blit(innerText, innerText.get_rect(center = textRect.center)) 
    else:
        textSurf = font.render(text, True, color)
        textRect = textSurf.get_rect()    

    textRect.center = (x,y)
    screen.blit(textSurf, textRect)

run = True
while run:
    clock.tick(60)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    hover = textRect.collidepoint(pygame.mouse.get_pos())
    outlineSize = 3 if hover else 0 

    screen.fill((0,0,0))
    text_speech('arialnarrow.ttf', 40, 'Hello', (255,255,255), (width/2), (height/2), False, outlineSize)
    pygame.display.flip()

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=394950&siteId=1