Как узнать максимальный размер шрифта текста который может поместиться в прямоугольник (Pygame)?
Я хочу сделать кнопку на pygame. Мне известны её ширина и длина, а также количество символов в тексте. Кнопка состоит из прямоугольника и текста в нём. Форматирование текста: идеально посередине %. Для этого мне нужно определить: какой максимальный размер шрифта может поместиться в прямоугольнике.
% = одно и то же значение для промежутка между верхом поверхности текста и верхом кнопки (аналогично с низом), для промежутка между левым краем поверхности текста и левым краем кнопки (аналогично с правым). Эти промежутки не обязательно равны.
class button:
def init(self, width, height, text):
self.rect = pygame.Rect(0, 0, width, height)
self.text_surface = pygame.font.SysFont('consolas', ТУТ РАЗМЕР ШРИФТА).render(text, False, (0, 0, 0))
def draw(self):
pg.draw.rect(win, (255, 255, 255), self.rect)
## Второй аргумент функции blit отвечает за "идеально посередине"
win.blit(self.text_surface, ((self.rect[2] - self.text_surface.get_rect()[2]) // 2, (self.rect[3] - self.text_surface.get_rect()[3]) // 2)
Если всё ещё не понятно (что скорее всего правда), то, коротко, проблема в том что я хочу отрисовать текст посередине и в границах кнопки а если сделать его слишком большим или слишком маленьким, то текст будет выходить за рамки
Ответы (1 шт):
Возможно, код слишком громоздкий, но он рабочий. Размер учитывается и по вертикали и по горизонтали.
def get_diff(font_name,standart_size,ind=0):
'''
Функция получает разницу в пикселях, достаточной для изменения размера шрифта на 1 пункт в нужном измерении
ind=0 - по оси x
ind=1 - по оси y
'''
x=pygame.font.SysFont(font_name, standart_size).render(".", False, (0, 0, 0)).get_size()[ind]
y=x
newSize,i=0,0
while y==x:
newSize=standart_size+i
y=pygame.font.SysFont(font_name, newSize).render(".", False, (0, 0, 0)).get_size()[ind]
i+=1
return newSize-standart_size
class button:
def __init__(self, width, height, text,font_name="consolas",stpos=[0,0]):
self.rect = pygame.Rect(0, 0, width, height)
self.stpos=stpos
# Получение стандартных размеров для буквы, конкретного шрифта
width_simb,height_simb=pygame.font.SysFont(font_name, 10).render(".", False, (0, 0, 0)).get_size()
diff_x,diff_y=get_diff(font_name,10),get_diff(font_name,10,ind=1)
#Максимальное увеличение надписи для упаковки
size=(width//diff_x)
self.text_surface = pygame.font.SysFont(font_name, size).render(text, False, (255,255,255))
surf_size=self.text_surface.get_size()
#"Упаковка" надписи в вертикальные границы
if self.text_surface.get_height()>height:
while surf_size[1]>height:
self.text_surface = pygame.font.SysFont(font_name, size).render(text, False, (255,255,255))
surf_size=self.text_surface.get_size()
size-=1
#"Упаковка" надписи в горизонтальные границы
if self.text_surface.get_width()>width:
while surf_size[0]>width:
self.text_surface = pygame.font.SysFont(font_name, size).render(text, False, (255,255,255))
surf_size=self.text_surface.get_size()
size-=1
'''
После упаковки может остаться 2 пикселя до границы кнопки
Примечание: для шрифта "consolas" упаковка не требуется
'''
def draw(self):
'''
Добавлен параметр self.stpos для стартовой позиции
'''
pygame.draw.rect(win, (0, 0, 255), [self.stpos[0],self.stpos[1],self.rect.width,self.rect.height])
win.blit(self.text_surface, (self.stpos[0]+(self.rect[2] - self.text_surface.get_rect()[2]) // 2, self.stpos[1]+(self.rect[3] - self.text_surface.get_rect()[3]) // 2))