750 lines
27 KiB
Python
750 lines
27 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
from re import T
|
||
|
import sys
|
||
|
import os
|
||
|
import unittest
|
||
|
import pathlib
|
||
|
import platform
|
||
|
|
||
|
import pygame
|
||
|
from pygame import font as pygame_font # So font can be replaced with ftfont
|
||
|
|
||
|
|
||
|
FONTDIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "fixtures", "fonts")
|
||
|
|
||
|
|
||
|
def equal_images(s1, s2):
|
||
|
size = s1.get_size()
|
||
|
if s2.get_size() != size:
|
||
|
return False
|
||
|
w, h = size
|
||
|
for x in range(w):
|
||
|
for y in range(h):
|
||
|
if s1.get_at((x, y)) != s2.get_at((x, y)):
|
||
|
return False
|
||
|
return True
|
||
|
|
||
|
|
||
|
IS_PYPY = "PyPy" == platform.python_implementation()
|
||
|
|
||
|
|
||
|
@unittest.skipIf(IS_PYPY, "pypy skip known failure") # TODO
|
||
|
class FontModuleTest(unittest.TestCase):
|
||
|
def setUp(self):
|
||
|
pygame_font.init()
|
||
|
|
||
|
def tearDown(self):
|
||
|
pygame_font.quit()
|
||
|
|
||
|
def test_get_sdl_ttf_version(self):
|
||
|
def test_ver_tuple(ver):
|
||
|
self.assertIsInstance(ver, tuple)
|
||
|
self.assertEqual(len(ver), 3)
|
||
|
for i in ver:
|
||
|
self.assertIsInstance(i, int)
|
||
|
|
||
|
if pygame_font.__name__ != "pygame.ftfont":
|
||
|
compiled = pygame_font.get_sdl_ttf_version()
|
||
|
linked = pygame_font.get_sdl_ttf_version(linked=True)
|
||
|
|
||
|
test_ver_tuple(compiled)
|
||
|
test_ver_tuple(linked)
|
||
|
|
||
|
self.assertTrue(linked >= compiled)
|
||
|
|
||
|
def test_SysFont(self):
|
||
|
# Can only check that a font object is returned.
|
||
|
fonts = pygame_font.get_fonts()
|
||
|
if "arial" in fonts:
|
||
|
# Try to use arial font if it is there, rather than a random font
|
||
|
# which can be different depending on installed fonts on the system.
|
||
|
font_name = "arial"
|
||
|
else:
|
||
|
font_name = sorted(fonts)[0]
|
||
|
o = pygame_font.SysFont(font_name, 20)
|
||
|
self.assertTrue(isinstance(o, pygame_font.FontType))
|
||
|
o = pygame_font.SysFont(font_name, 20, italic=True)
|
||
|
self.assertTrue(isinstance(o, pygame_font.FontType))
|
||
|
o = pygame_font.SysFont(font_name, 20, bold=True)
|
||
|
self.assertTrue(isinstance(o, pygame_font.FontType))
|
||
|
o = pygame_font.SysFont("thisisnotafont", 20)
|
||
|
self.assertTrue(isinstance(o, pygame_font.FontType))
|
||
|
|
||
|
def test_get_default_font(self):
|
||
|
self.assertEqual(pygame_font.get_default_font(), "freesansbold.ttf")
|
||
|
|
||
|
def test_get_fonts_returns_something(self):
|
||
|
fnts = pygame_font.get_fonts()
|
||
|
self.assertTrue(fnts)
|
||
|
|
||
|
# to test if some files exist...
|
||
|
# def XXtest_has_file_osx_10_5_sdk(self):
|
||
|
# import os
|
||
|
# f = "/Developer/SDKs/MacOSX10.5.sdk/usr/X11/include/ft2build.h"
|
||
|
# self.assertEqual(os.path.exists(f), True)
|
||
|
|
||
|
# def XXtest_has_file_osx_10_4_sdk(self):
|
||
|
# import os
|
||
|
# f = "/Developer/SDKs/MacOSX10.4u.sdk/usr/X11R6/include/ft2build.h"
|
||
|
# self.assertEqual(os.path.exists(f), True)
|
||
|
|
||
|
def test_get_fonts(self):
|
||
|
fnts = pygame_font.get_fonts()
|
||
|
|
||
|
self.assertTrue(fnts, msg=repr(fnts))
|
||
|
|
||
|
for name in fnts:
|
||
|
# note, on ubuntu 2.6 they are all unicode strings.
|
||
|
|
||
|
self.assertTrue(isinstance(name, str), name)
|
||
|
# Font names can be comprised of only numeric characters, so
|
||
|
# just checking name.islower() will not work as expected here.
|
||
|
self.assertFalse(any(c.isupper() for c in name))
|
||
|
self.assertTrue(name.isalnum(), name)
|
||
|
|
||
|
def test_get_init(self):
|
||
|
self.assertTrue(pygame_font.get_init())
|
||
|
pygame_font.quit()
|
||
|
self.assertFalse(pygame_font.get_init())
|
||
|
|
||
|
def test_init(self):
|
||
|
pygame_font.init()
|
||
|
|
||
|
def test_match_font_all_exist(self):
|
||
|
fonts = pygame_font.get_fonts()
|
||
|
|
||
|
# Ensure all listed fonts are in fact available, and the returned file
|
||
|
# name is a full path.
|
||
|
for font in fonts:
|
||
|
path = pygame_font.match_font(font)
|
||
|
self.assertFalse(path is None)
|
||
|
self.assertTrue(os.path.isabs(path) and os.path.isfile(path))
|
||
|
|
||
|
def test_match_font_name(self):
|
||
|
"""That match_font accepts names of various types"""
|
||
|
font = pygame_font.get_fonts()[0]
|
||
|
font_path = pygame_font.match_font(font)
|
||
|
self.assertIsNotNone(font_path)
|
||
|
font_b = font.encode()
|
||
|
not_a_font = "thisisnotafont"
|
||
|
not_a_font_b = b"thisisnotafont"
|
||
|
good_font_names = [
|
||
|
# Check single name bytes.
|
||
|
font_b,
|
||
|
# Check string of comma-separated names.
|
||
|
",".join([not_a_font, font, not_a_font]),
|
||
|
# Check list of names.
|
||
|
[not_a_font, font, not_a_font],
|
||
|
# Check generator:
|
||
|
(name for name in [not_a_font, font, not_a_font]),
|
||
|
# Check comma-separated bytes.
|
||
|
b",".join([not_a_font_b, font_b, not_a_font_b]),
|
||
|
# Check list of bytes.
|
||
|
[not_a_font_b, font_b, not_a_font_b],
|
||
|
# Check mixed list of bytes and string.
|
||
|
[font, not_a_font, font_b, not_a_font_b],
|
||
|
]
|
||
|
for font_name in good_font_names:
|
||
|
self.assertEqual(pygame_font.match_font(font_name), font_path, font_name)
|
||
|
|
||
|
def test_not_match_font_name(self):
|
||
|
"""match_font return None when names of various types do not exist"""
|
||
|
not_a_font = "thisisnotafont"
|
||
|
not_a_font_b = b"thisisnotafont"
|
||
|
bad_font_names = [
|
||
|
not_a_font,
|
||
|
",".join([not_a_font, not_a_font, not_a_font]),
|
||
|
[not_a_font, not_a_font, not_a_font],
|
||
|
(name for name in [not_a_font, not_a_font, not_a_font]),
|
||
|
not_a_font_b,
|
||
|
b",".join([not_a_font_b, not_a_font_b, not_a_font_b]),
|
||
|
[not_a_font_b, not_a_font_b, not_a_font_b],
|
||
|
[not_a_font, not_a_font_b, not_a_font],
|
||
|
]
|
||
|
for font_name in bad_font_names:
|
||
|
self.assertIsNone(pygame_font.match_font(font_name), font_name)
|
||
|
|
||
|
def test_match_font_bold(self):
|
||
|
fonts = pygame_font.get_fonts()
|
||
|
|
||
|
# Look for a bold font.
|
||
|
self.assertTrue(any(pygame_font.match_font(font, bold=True) for font in fonts))
|
||
|
|
||
|
def test_match_font_italic(self):
|
||
|
fonts = pygame_font.get_fonts()
|
||
|
|
||
|
# Look for an italic font.
|
||
|
self.assertTrue(
|
||
|
any(pygame_font.match_font(font, italic=True) for font in fonts)
|
||
|
)
|
||
|
|
||
|
def test_issue_742(self):
|
||
|
"""that the font background does not crash."""
|
||
|
surf = pygame.Surface((320, 240))
|
||
|
font = pygame_font.Font(None, 24)
|
||
|
image = font.render("Test", 0, (255, 255, 255), (0, 0, 0))
|
||
|
self.assertIsNone(image.get_colorkey())
|
||
|
image.set_alpha(255)
|
||
|
surf.blit(image, (0, 0))
|
||
|
|
||
|
# not issue 742, but be sure to test that background color is
|
||
|
# correctly issued on this mode
|
||
|
self.assertEqual(surf.get_at((0, 0)), pygame.Color(0, 0, 0))
|
||
|
|
||
|
def test_issue_font_alphablit(self):
|
||
|
"""Check that blitting anti-aliased text doesn't
|
||
|
change the background blue"""
|
||
|
pygame.display.set_mode((600, 400))
|
||
|
|
||
|
font = pygame_font.Font(None, 24)
|
||
|
|
||
|
(color, text, center, pos) = ((160, 200, 250), "Music", (190, 170), "midright")
|
||
|
img1 = font.render(text, True, color)
|
||
|
|
||
|
img = pygame.Surface(img1.get_size(), depth=32)
|
||
|
pre_blit_corner_pixel = img.get_at((0, 0))
|
||
|
img.blit(img1, (0, 0))
|
||
|
post_blit_corner_pixel = img.get_at((0, 0))
|
||
|
|
||
|
self.assertEqual(pre_blit_corner_pixel, post_blit_corner_pixel)
|
||
|
|
||
|
def test_segfault_after_reinit(self):
|
||
|
"""Reinitialization of font module should not cause
|
||
|
segmentation fault"""
|
||
|
import gc
|
||
|
|
||
|
font = pygame_font.Font(None, 20)
|
||
|
pygame_font.quit()
|
||
|
pygame_font.init()
|
||
|
del font
|
||
|
gc.collect()
|
||
|
|
||
|
def test_quit(self):
|
||
|
pygame_font.quit()
|
||
|
|
||
|
|
||
|
@unittest.skipIf(IS_PYPY, "pypy skip known failure") # TODO
|
||
|
class FontTest(unittest.TestCase):
|
||
|
def setUp(self):
|
||
|
pygame_font.init()
|
||
|
|
||
|
def tearDown(self):
|
||
|
pygame_font.quit()
|
||
|
|
||
|
def test_render_args(self):
|
||
|
screen = pygame.display.set_mode((600, 400))
|
||
|
rect = screen.get_rect()
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
screen.fill((10, 10, 10))
|
||
|
font_surface = f.render(" bar", True, (0, 0, 0), (255, 255, 255))
|
||
|
font_rect = font_surface.get_rect()
|
||
|
font_rect.topleft = rect.topleft
|
||
|
self.assertTrue(font_surface)
|
||
|
screen.blit(font_surface, font_rect, font_rect)
|
||
|
pygame.display.update()
|
||
|
self.assertEqual(tuple(screen.get_at((0, 0)))[:3], (255, 255, 255))
|
||
|
self.assertEqual(tuple(screen.get_at(font_rect.topleft))[:3], (255, 255, 255))
|
||
|
|
||
|
# If we don't have a real display, don't do this test.
|
||
|
# Transparent background doesn't seem to work without a read video card.
|
||
|
if os.environ.get("SDL_VIDEODRIVER") != "dummy":
|
||
|
screen.fill((10, 10, 10))
|
||
|
font_surface = f.render(" bar", True, (0, 0, 0), None)
|
||
|
font_rect = font_surface.get_rect()
|
||
|
font_rect.topleft = rect.topleft
|
||
|
self.assertTrue(font_surface)
|
||
|
screen.blit(font_surface, font_rect, font_rect)
|
||
|
pygame.display.update()
|
||
|
self.assertEqual(tuple(screen.get_at((0, 0)))[:3], (10, 10, 10))
|
||
|
self.assertEqual(tuple(screen.get_at(font_rect.topleft))[:3], (10, 10, 10))
|
||
|
|
||
|
screen.fill((10, 10, 10))
|
||
|
font_surface = f.render(" bar", True, (0, 0, 0))
|
||
|
font_rect = font_surface.get_rect()
|
||
|
font_rect.topleft = rect.topleft
|
||
|
self.assertTrue(font_surface)
|
||
|
screen.blit(font_surface, font_rect, font_rect)
|
||
|
pygame.display.update(rect)
|
||
|
self.assertEqual(tuple(screen.get_at((0, 0)))[:3], (10, 10, 10))
|
||
|
self.assertEqual(tuple(screen.get_at(font_rect.topleft))[:3], (10, 10, 10))
|
||
|
|
||
|
|
||
|
@unittest.skipIf(IS_PYPY, "pypy skip known failure") # TODO
|
||
|
class FontTypeTest(unittest.TestCase):
|
||
|
def setUp(self):
|
||
|
pygame_font.init()
|
||
|
|
||
|
def tearDown(self):
|
||
|
pygame_font.quit()
|
||
|
|
||
|
def test_default_parameters(self):
|
||
|
f = pygame_font.Font()
|
||
|
|
||
|
def test_get_ascent(self):
|
||
|
# Ckecking ascent would need a custom test font to do properly.
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
ascent = f.get_ascent()
|
||
|
self.assertTrue(isinstance(ascent, int))
|
||
|
self.assertTrue(ascent > 0)
|
||
|
s = f.render("X", False, (255, 255, 255))
|
||
|
self.assertTrue(s.get_size()[1] > ascent)
|
||
|
|
||
|
def test_get_descent(self):
|
||
|
# Ckecking descent would need a custom test font to do properly.
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
descent = f.get_descent()
|
||
|
self.assertTrue(isinstance(descent, int))
|
||
|
self.assertTrue(descent < 0)
|
||
|
|
||
|
def test_get_height(self):
|
||
|
# Ckecking height would need a custom test font to do properly.
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
height = f.get_height()
|
||
|
self.assertTrue(isinstance(height, int))
|
||
|
self.assertTrue(height > 0)
|
||
|
s = f.render("X", False, (255, 255, 255))
|
||
|
self.assertTrue(s.get_size()[1] == height)
|
||
|
|
||
|
def test_get_linesize(self):
|
||
|
# Ckecking linesize would need a custom test font to do properly.
|
||
|
# Questions: How do linesize, height and descent relate?
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
linesize = f.get_linesize()
|
||
|
self.assertTrue(isinstance(linesize, int))
|
||
|
self.assertTrue(linesize > 0)
|
||
|
|
||
|
def test_metrics(self):
|
||
|
# Ensure bytes decoding works correctly. Can only compare results
|
||
|
# with unicode for now.
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
um = f.metrics(".")
|
||
|
bm = f.metrics(b".")
|
||
|
|
||
|
self.assertEqual(len(um), 1)
|
||
|
self.assertEqual(len(bm), 1)
|
||
|
self.assertIsNotNone(um[0])
|
||
|
self.assertEqual(um, bm)
|
||
|
|
||
|
u = "\u212A"
|
||
|
b = u.encode("UTF-16")[2:] # Keep byte order consistent. [2:] skips BOM
|
||
|
bm = f.metrics(b)
|
||
|
|
||
|
self.assertEqual(len(bm), 2)
|
||
|
|
||
|
try: # FIXME why do we do this try/except ?
|
||
|
um = f.metrics(u)
|
||
|
except pygame.error:
|
||
|
pass
|
||
|
else:
|
||
|
self.assertEqual(len(um), 1)
|
||
|
self.assertNotEqual(bm[0], um[0])
|
||
|
self.assertNotEqual(bm[1], um[0])
|
||
|
|
||
|
u = "\U00013000"
|
||
|
bm = f.metrics(u)
|
||
|
|
||
|
self.assertEqual(len(bm), 1)
|
||
|
self.assertIsNone(bm[0])
|
||
|
|
||
|
return # unfinished
|
||
|
# The documentation is useless here. How large a list?
|
||
|
# How do list positions relate to character codes?
|
||
|
# What about unicode characters?
|
||
|
|
||
|
# __doc__ (as of 2008-08-02) for pygame_font.Font.metrics:
|
||
|
|
||
|
# Font.metrics(text): return list
|
||
|
# Gets the metrics for each character in the passed string.
|
||
|
#
|
||
|
# The list contains tuples for each character, which contain the
|
||
|
# minimum X offset, the maximum X offset, the minimum Y offset, the
|
||
|
# maximum Y offset and the advance offset (bearing plus width) of the
|
||
|
# character. [(minx, maxx, miny, maxy, advance), (minx, maxx, miny,
|
||
|
# maxy, advance), ...]
|
||
|
|
||
|
self.fail()
|
||
|
|
||
|
def test_render(self):
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
s = f.render("foo", True, [0, 0, 0], [255, 255, 255])
|
||
|
s = f.render("xxx", True, [0, 0, 0], [255, 255, 255])
|
||
|
s = f.render("", True, [0, 0, 0], [255, 255, 255])
|
||
|
s = f.render("foo", False, [0, 0, 0], [255, 255, 255])
|
||
|
s = f.render("xxx", False, [0, 0, 0], [255, 255, 255])
|
||
|
s = f.render("xxx", False, [0, 0, 0])
|
||
|
s = f.render(" ", False, [0, 0, 0])
|
||
|
s = f.render(" ", False, [0, 0, 0], [255, 255, 255])
|
||
|
# null text should be 0 pixel wide.
|
||
|
s = f.render("", False, [0, 0, 0], [255, 255, 255])
|
||
|
self.assertEqual(s.get_size()[0], 0)
|
||
|
# None text should be 0 pixel wide.
|
||
|
s = f.render(None, False, [0, 0, 0], [255, 255, 255])
|
||
|
self.assertEqual(s.get_size()[0], 0)
|
||
|
# Non-text should raise a TypeError.
|
||
|
self.assertRaises(TypeError, f.render, [], False, [0, 0, 0], [255, 255, 255])
|
||
|
self.assertRaises(TypeError, f.render, 1, False, [0, 0, 0], [255, 255, 255])
|
||
|
# is background transparent for antialiasing?
|
||
|
s = f.render(".", True, [255, 255, 255])
|
||
|
self.assertEqual(s.get_at((0, 0))[3], 0)
|
||
|
# is Unicode and bytes encoding correct?
|
||
|
# Cannot really test if the correct characters are rendered, but
|
||
|
# at least can assert the encodings differ.
|
||
|
su = f.render(".", False, [0, 0, 0], [255, 255, 255])
|
||
|
sb = f.render(b".", False, [0, 0, 0], [255, 255, 255])
|
||
|
self.assertTrue(equal_images(su, sb))
|
||
|
u = "\u212A"
|
||
|
b = u.encode("UTF-16")[2:] # Keep byte order consistent. [2:] skips BOM
|
||
|
sb = f.render(b, False, [0, 0, 0], [255, 255, 255])
|
||
|
try: # FIXME why do we do this try/except ?
|
||
|
su = f.render(u, False, [0, 0, 0], [255, 255, 255])
|
||
|
except pygame.error:
|
||
|
pass
|
||
|
else:
|
||
|
self.assertFalse(equal_images(su, sb))
|
||
|
|
||
|
# test for internal null bytes
|
||
|
self.assertRaises(ValueError, f.render, b"ab\x00cd", 0, [0, 0, 0])
|
||
|
self.assertRaises(ValueError, f.render, "ab\x00cd", 0, [0, 0, 0])
|
||
|
|
||
|
def test_render_ucs2_ucs4(self):
|
||
|
"""that it renders without raising if there is a new enough SDL_ttf."""
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
# If the font module is SDL_ttf < 2.0.15 based, then it only supports UCS-2
|
||
|
# it will raise an exception for an out-of-range UCS-4 code point.
|
||
|
if hasattr(pygame_font, "UCS4"):
|
||
|
ucs_2 = "\uFFEE"
|
||
|
s = f.render(ucs_2, False, [0, 0, 0], [255, 255, 255])
|
||
|
ucs_4 = "\U00010000"
|
||
|
s = f.render(ucs_4, False, [0, 0, 0], [255, 255, 255])
|
||
|
|
||
|
def test_set_bold(self):
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
self.assertFalse(f.get_bold())
|
||
|
f.set_bold(True)
|
||
|
self.assertTrue(f.get_bold())
|
||
|
f.set_bold(False)
|
||
|
self.assertFalse(f.get_bold())
|
||
|
|
||
|
def test_set_italic(self):
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
self.assertFalse(f.get_italic())
|
||
|
f.set_italic(True)
|
||
|
self.assertTrue(f.get_italic())
|
||
|
f.set_italic(False)
|
||
|
self.assertFalse(f.get_italic())
|
||
|
|
||
|
def test_set_underline(self):
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
self.assertFalse(f.get_underline())
|
||
|
f.set_underline(True)
|
||
|
self.assertTrue(f.get_underline())
|
||
|
f.set_underline(False)
|
||
|
self.assertFalse(f.get_underline())
|
||
|
|
||
|
def test_set_strikethrough(self):
|
||
|
if pygame_font.__name__ != "pygame.ftfont":
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
self.assertFalse(f.get_strikethrough())
|
||
|
f.set_strikethrough(True)
|
||
|
self.assertTrue(f.get_strikethrough())
|
||
|
f.set_strikethrough(False)
|
||
|
self.assertFalse(f.get_strikethrough())
|
||
|
|
||
|
def test_bold_attr(self):
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
self.assertFalse(f.bold)
|
||
|
f.bold = True
|
||
|
self.assertTrue(f.bold)
|
||
|
f.bold = False
|
||
|
self.assertFalse(f.bold)
|
||
|
|
||
|
def test_set_italic_property(self):
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
self.assertFalse(f.italic)
|
||
|
f.italic = True
|
||
|
self.assertTrue(f.italic)
|
||
|
f.italic = False
|
||
|
self.assertFalse(f.italic)
|
||
|
|
||
|
def test_set_underline_property(self):
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
self.assertFalse(f.underline)
|
||
|
f.underline = True
|
||
|
self.assertTrue(f.underline)
|
||
|
f.underline = False
|
||
|
self.assertFalse(f.underline)
|
||
|
|
||
|
def test_set_strikethrough_property(self):
|
||
|
if pygame_font.__name__ != "pygame.ftfont":
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
self.assertFalse(f.strikethrough)
|
||
|
f.strikethrough = True
|
||
|
self.assertTrue(f.strikethrough)
|
||
|
f.strikethrough = False
|
||
|
self.assertFalse(f.strikethrough)
|
||
|
|
||
|
def test_size(self):
|
||
|
f = pygame_font.Font(None, 20)
|
||
|
text = "Xg"
|
||
|
size = f.size(text)
|
||
|
w, h = size
|
||
|
s = f.render(text, False, (255, 255, 255))
|
||
|
btext = text.encode("ascii")
|
||
|
|
||
|
self.assertIsInstance(w, int)
|
||
|
self.assertIsInstance(h, int)
|
||
|
self.assertEqual(s.get_size(), size)
|
||
|
self.assertEqual(f.size(btext), size)
|
||
|
|
||
|
text = "\u212A"
|
||
|
btext = text.encode("UTF-16")[2:] # Keep the byte order consistent.
|
||
|
bsize = f.size(btext)
|
||
|
size = f.size(text)
|
||
|
|
||
|
self.assertNotEqual(size, bsize)
|
||
|
|
||
|
def test_font_file_not_found(self):
|
||
|
# A per BUG reported by Bo Jangeborg on pygame-user mailing list,
|
||
|
# http://www.mail-archive.com/pygame-users@seul.org/msg11675.html
|
||
|
|
||
|
pygame_font.init()
|
||
|
self.assertRaises(
|
||
|
FileNotFoundError, pygame_font.Font, "some-fictional-font.ttf", 20
|
||
|
)
|
||
|
|
||
|
def test_load_from_file(self):
|
||
|
font_name = pygame_font.get_default_font()
|
||
|
font_path = os.path.join(
|
||
|
os.path.split(pygame.__file__)[0], pygame_font.get_default_font()
|
||
|
)
|
||
|
f = pygame_font.Font(font_path, 20)
|
||
|
|
||
|
def test_load_from_file_default(self):
|
||
|
font_name = pygame_font.get_default_font()
|
||
|
font_path = os.path.join(
|
||
|
os.path.split(pygame.__file__)[0], pygame_font.get_default_font()
|
||
|
)
|
||
|
f = pygame_font.Font(font_path)
|
||
|
|
||
|
def test_load_from_pathlib(self):
|
||
|
font_name = pygame_font.get_default_font()
|
||
|
font_path = os.path.join(
|
||
|
os.path.split(pygame.__file__)[0], pygame_font.get_default_font()
|
||
|
)
|
||
|
f = pygame_font.Font(pathlib.Path(font_path), 20)
|
||
|
f = pygame_font.Font(pathlib.Path(font_path))
|
||
|
|
||
|
def test_load_from_pathlib_default(self):
|
||
|
font_name = pygame_font.get_default_font()
|
||
|
font_path = os.path.join(
|
||
|
os.path.split(pygame.__file__)[0], pygame_font.get_default_font()
|
||
|
)
|
||
|
f = pygame_font.Font(pathlib.Path(font_path))
|
||
|
|
||
|
def test_load_from_file_obj(self):
|
||
|
font_name = pygame_font.get_default_font()
|
||
|
font_path = os.path.join(
|
||
|
os.path.split(pygame.__file__)[0], pygame_font.get_default_font()
|
||
|
)
|
||
|
with open(font_path, "rb") as f:
|
||
|
font = pygame_font.Font(f, 20)
|
||
|
|
||
|
def test_load_from_file_obj_default(self):
|
||
|
font_name = pygame_font.get_default_font()
|
||
|
font_path = os.path.join(
|
||
|
os.path.split(pygame.__file__)[0], pygame_font.get_default_font()
|
||
|
)
|
||
|
with open(font_path, "rb") as f:
|
||
|
font = pygame_font.Font(f)
|
||
|
|
||
|
def test_load_default_font_filename(self):
|
||
|
# In font_init, a special case is when the filename argument is
|
||
|
# identical to the default font file name.
|
||
|
f = pygame_font.Font(pygame_font.get_default_font(), 20)
|
||
|
|
||
|
def test_load_default_font_filename_default(self):
|
||
|
# In font_init, a special case is when the filename argument is
|
||
|
# identical to the default font file name.
|
||
|
f = pygame_font.Font(pygame_font.get_default_font())
|
||
|
|
||
|
def _load_unicode(self, path):
|
||
|
import shutil
|
||
|
|
||
|
fdir = str(FONTDIR)
|
||
|
temp = os.path.join(fdir, path)
|
||
|
pgfont = os.path.join(fdir, "test_sans.ttf")
|
||
|
shutil.copy(pgfont, temp)
|
||
|
try:
|
||
|
with open(temp, "rb") as f:
|
||
|
pass
|
||
|
except FileNotFoundError:
|
||
|
raise unittest.SkipTest("the path cannot be opened")
|
||
|
try:
|
||
|
pygame_font.Font(temp, 20)
|
||
|
finally:
|
||
|
os.remove(temp)
|
||
|
|
||
|
def test_load_from_file_unicode_0(self):
|
||
|
"""ASCII string as a unicode object"""
|
||
|
self._load_unicode("temp_file.ttf")
|
||
|
|
||
|
def test_load_from_file_unicode_1(self):
|
||
|
self._load_unicode("你好.ttf")
|
||
|
|
||
|
def test_load_from_file_bytes(self):
|
||
|
font_path = os.path.join(
|
||
|
os.path.split(pygame.__file__)[0], pygame_font.get_default_font()
|
||
|
)
|
||
|
filesystem_encoding = sys.getfilesystemencoding()
|
||
|
filesystem_errors = "replace" if sys.platform == "win32" else "surrogateescape"
|
||
|
try: # FIXME why do we do this try/except ?
|
||
|
font_path = font_path.decode(filesystem_encoding, filesystem_errors)
|
||
|
except AttributeError:
|
||
|
pass
|
||
|
bfont_path = font_path.encode(filesystem_encoding, filesystem_errors)
|
||
|
f = pygame_font.Font(bfont_path, 20)
|
||
|
|
||
|
def test_issue_3144(self):
|
||
|
fpath = os.path.join(FONTDIR, "PlayfairDisplaySemibold.ttf")
|
||
|
|
||
|
# issue in SDL_ttf 2.0.18 DLL on Windows
|
||
|
# tested to make us aware of any regressions
|
||
|
for size in (60, 40, 10, 20, 70, 45, 50, 10):
|
||
|
font = pygame_font.Font(fpath, size)
|
||
|
font.render("WHERE", True, "black")
|
||
|
|
||
|
def test_font_set_script(self):
|
||
|
if pygame_font.__name__ == "pygame.ftfont":
|
||
|
return # this ain't a pygame.ftfont thing!
|
||
|
|
||
|
font = pygame_font.Font(None, 16)
|
||
|
|
||
|
ttf_version = pygame_font.get_sdl_ttf_version()
|
||
|
if ttf_version >= (2, 20, 0):
|
||
|
self.assertRaises(TypeError, pygame.font.Font.set_script)
|
||
|
self.assertRaises(TypeError, pygame.font.Font.set_script, font)
|
||
|
self.assertRaises(TypeError, pygame.font.Font.set_script, "hey", "Deva")
|
||
|
self.assertRaises(TypeError, font.set_script, 1)
|
||
|
self.assertRaises(TypeError, font.set_script, ["D", "e", "v", "a"])
|
||
|
|
||
|
self.assertRaises(ValueError, font.set_script, "too long by far")
|
||
|
self.assertRaises(ValueError, font.set_script, "")
|
||
|
self.assertRaises(ValueError, font.set_script, "a")
|
||
|
|
||
|
font.set_script("Deva")
|
||
|
else:
|
||
|
self.assertRaises(pygame.error, font.set_script, "Deva")
|
||
|
|
||
|
|
||
|
@unittest.skipIf(IS_PYPY, "pypy skip known failure") # TODO
|
||
|
class VisualTests(unittest.TestCase):
|
||
|
__tags__ = ["interactive"]
|
||
|
|
||
|
screen = None
|
||
|
aborted = False
|
||
|
|
||
|
def setUp(self):
|
||
|
if self.screen is None:
|
||
|
pygame.init()
|
||
|
self.screen = pygame.display.set_mode((600, 200))
|
||
|
self.screen.fill((255, 255, 255))
|
||
|
pygame.display.flip()
|
||
|
self.f = pygame_font.Font(None, 32)
|
||
|
|
||
|
def abort(self):
|
||
|
if self.screen is not None:
|
||
|
pygame.quit()
|
||
|
self.aborted = True
|
||
|
|
||
|
def query(
|
||
|
self,
|
||
|
bold=False,
|
||
|
italic=False,
|
||
|
underline=False,
|
||
|
strikethrough=False,
|
||
|
antialiase=False,
|
||
|
):
|
||
|
if self.aborted:
|
||
|
return False
|
||
|
spacing = 10
|
||
|
offset = 20
|
||
|
y = spacing
|
||
|
f = self.f
|
||
|
screen = self.screen
|
||
|
screen.fill((255, 255, 255))
|
||
|
pygame.display.flip()
|
||
|
if not (bold or italic or underline or strikethrough or antialiase):
|
||
|
text = "normal"
|
||
|
else:
|
||
|
modes = []
|
||
|
if bold:
|
||
|
modes.append("bold")
|
||
|
if italic:
|
||
|
modes.append("italic")
|
||
|
if underline:
|
||
|
modes.append("underlined")
|
||
|
if strikethrough:
|
||
|
modes.append("strikethrough")
|
||
|
if antialiase:
|
||
|
modes.append("antialiased")
|
||
|
text = f"{'-'.join(modes)} (y/n):"
|
||
|
f.set_bold(bold)
|
||
|
f.set_italic(italic)
|
||
|
f.set_underline(underline)
|
||
|
if pygame_font.__name__ != "pygame.ftfont":
|
||
|
f.set_strikethrough(strikethrough)
|
||
|
s = f.render(text, antialiase, (0, 0, 0))
|
||
|
screen.blit(s, (offset, y))
|
||
|
y += s.get_size()[1] + spacing
|
||
|
f.set_bold(False)
|
||
|
f.set_italic(False)
|
||
|
f.set_underline(False)
|
||
|
if pygame_font.__name__ != "pygame.ftfont":
|
||
|
f.set_strikethrough(False)
|
||
|
s = f.render("(some comparison text)", False, (0, 0, 0))
|
||
|
screen.blit(s, (offset, y))
|
||
|
pygame.display.flip()
|
||
|
while True:
|
||
|
for evt in pygame.event.get():
|
||
|
if evt.type == pygame.KEYDOWN:
|
||
|
if evt.key == pygame.K_ESCAPE:
|
||
|
self.abort()
|
||
|
return False
|
||
|
if evt.key == pygame.K_y:
|
||
|
return True
|
||
|
if evt.key == pygame.K_n:
|
||
|
return False
|
||
|
if evt.type == pygame.QUIT:
|
||
|
self.abort()
|
||
|
return False
|
||
|
|
||
|
def test_bold(self):
|
||
|
self.assertTrue(self.query(bold=True))
|
||
|
|
||
|
def test_italic(self):
|
||
|
self.assertTrue(self.query(italic=True))
|
||
|
|
||
|
def test_underline(self):
|
||
|
self.assertTrue(self.query(underline=True))
|
||
|
|
||
|
def test_strikethrough(self):
|
||
|
if pygame_font.__name__ != "pygame.ftfont":
|
||
|
self.assertTrue(self.query(strikethrough=True))
|
||
|
|
||
|
def test_antialiase(self):
|
||
|
self.assertTrue(self.query(antialiase=True))
|
||
|
|
||
|
def test_bold_antialiase(self):
|
||
|
self.assertTrue(self.query(bold=True, antialiase=True))
|
||
|
|
||
|
def test_italic_underline(self):
|
||
|
self.assertTrue(self.query(italic=True, underline=True))
|
||
|
|
||
|
def test_bold_strikethrough(self):
|
||
|
if pygame_font.__name__ != "pygame.ftfont":
|
||
|
self.assertTrue(self.query(bold=True, strikethrough=True))
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
unittest.main()
|