PageRenderTime 104ms CodeModel.GetById 2ms RepoModel.GetById 1ms app.codeStats 0ms

/pygame/tests/font_test.py

https://bitbucket.org/julian_meyer/boxes
Python | 385 lines | 311 code | 45 blank | 29 comment | 16 complexity | 78db96e1feed3bf3702320c14664bb21 MD5 | raw file
  1. import sys
  2. import os
  3. if __name__ == '__main__':
  4. pkg_dir = os.path.split(os.path.abspath(__file__))[0]
  5. parent_dir, pkg_name = os.path.split(pkg_dir)
  6. is_pygame_pkg = (pkg_name == 'tests' and
  7. os.path.split(parent_dir)[1] == 'pygame')
  8. if not is_pygame_pkg:
  9. sys.path.insert(0, parent_dir)
  10. else:
  11. is_pygame_pkg = __name__.startswith('pygame.tests.')
  12. if is_pygame_pkg:
  13. from pygame.tests.test_utils import test_not_implemented, unittest, \
  14. geterror
  15. else:
  16. from test.test_utils import test_not_implemented, unittest, geterror
  17. import pygame
  18. class FontModuleTest( unittest.TestCase ):
  19. def setUp(self):
  20. pygame.font.init()
  21. def tearDown(self):
  22. pygame.font.quit()
  23. def test_SysFont(self):
  24. # Can only check that a font object is returned.
  25. fonts = pygame.font.get_fonts()
  26. o = pygame.font.SysFont(fonts[0], 20)
  27. self.failUnless(isinstance(o, pygame.font.FontType))
  28. o = pygame.font.SysFont(fonts[0], 20, italic=True)
  29. self.failUnless(isinstance(o, pygame.font.FontType))
  30. o = pygame.font.SysFont(fonts[0], 20, bold=True)
  31. self.failUnless(isinstance(o, pygame.font.FontType))
  32. o = pygame.font.SysFont('thisisnotafont', 20)
  33. self.failUnless(isinstance(o, pygame.font.FontType))
  34. def test_get_default_font(self):
  35. self.failUnlessEqual(pygame.font.get_default_font(), 'freesansbold.ttf')
  36. def test_get_fonts_returns_something(self):
  37. fnts = pygame.font.get_fonts()
  38. self.failUnless(fnts)
  39. def test_get_fonts(self):
  40. fnts = pygame.font.get_fonts()
  41. if not fnts:
  42. raise Exception(repr(fnts))
  43. self.failUnless(fnts)
  44. # strange python 2.x bug... if you assign to unicode,
  45. # all sorts of weirdness happens.
  46. if sys.version_info <= (3, 0, 0):
  47. unicod = unicode
  48. else:
  49. unicod = str
  50. for name in fnts:
  51. # note, on ubuntu 2.6 they are all unicode strings.
  52. self.failUnless(isinstance(name, (str, unicod)))
  53. self.failUnless(name.islower(), name)
  54. self.failUnless(name.isalnum(), name)
  55. def test_get_init(self):
  56. self.failUnless(pygame.font.get_init())
  57. pygame.font.quit()
  58. self.failIf(pygame.font.get_init())
  59. def test_init(self):
  60. pygame.font.init()
  61. def test_match_font_all_exist(self):
  62. fonts = pygame.font.get_fonts()
  63. # Ensure all listed fonts are in fact available, and the returned file
  64. # name is a full path.
  65. for font in fonts:
  66. path = pygame.font.match_font(font)
  67. self.failIf(path is None)
  68. self.failUnless(os.path.isabs(path))
  69. def test_match_font_bold(self):
  70. fonts = pygame.font.get_fonts()
  71. # Look for a bold font.
  72. for font in fonts:
  73. if pygame.font.match_font(font, bold=True) is not None:
  74. break
  75. else:
  76. self.fail()
  77. def test_match_font_italic(self):
  78. fonts = pygame.font.get_fonts()
  79. # Look for an italic font.
  80. for font in fonts:
  81. if pygame.font.match_font(font, italic=True) is not None:
  82. break
  83. else:
  84. self.fail()
  85. def test_match_font_comma_separated(self):
  86. fonts = pygame.font.get_fonts()
  87. # Check for not found.
  88. self.failUnless(pygame.font.match_font('thisisnotafont') is None)
  89. # Check comma separated list.
  90. names = ','.join(['thisisnotafont', fonts[-1], 'anothernonfont'])
  91. self.failIf(pygame.font.match_font(names) is None)
  92. names = ','.join(['thisisnotafont1', 'thisisnotafont2', 'thisisnotafont3'])
  93. self.failUnless(pygame.font.match_font(names) is None)
  94. def test_quit(self):
  95. pygame.font.quit()
  96. class FontTypeTest( unittest.TestCase ):
  97. def setUp(self):
  98. pygame.font.init()
  99. def tearDown(self):
  100. pygame.font.quit()
  101. def test_get_ascent(self):
  102. # Ckecking ascent would need a custom test font to do properly.
  103. f = pygame.font.Font(None, 20)
  104. ascent = f.get_ascent()
  105. self.failUnless(isinstance(ascent, int))
  106. self.failUnless(ascent > 0)
  107. s = f.render("X", False, (255, 255, 255))
  108. self.failUnless(s.get_size()[1] > ascent)
  109. def test_get_descent(self):
  110. # Ckecking descent would need a custom test font to do properly.
  111. f = pygame.font.Font(None, 20)
  112. descent = f.get_descent()
  113. self.failUnless(isinstance(descent, int))
  114. self.failUnless(descent < 0)
  115. def test_get_height(self):
  116. # Ckecking height would need a custom test font to do properly.
  117. f = pygame.font.Font(None, 20)
  118. height = f.get_height()
  119. self.failUnless(isinstance(height, int))
  120. self.failUnless(height > 0)
  121. s = f.render("X", False, (255, 255, 255))
  122. self.failUnless(s.get_size()[1] == height)
  123. def test_get_linesize(self):
  124. # Ckecking linesize would need a custom test font to do properly.
  125. # Questions: How do linesize, height and descent relate?
  126. f = pygame.font.Font(None, 20)
  127. linesize = f.get_linesize()
  128. self.failUnless(isinstance(linesize, int))
  129. self.failUnless(linesize > 0)
  130. def todo_test_metrics(self):
  131. # The documentation is useless here. How large a list?
  132. # How do list positions relate to character codes?
  133. # What about unicode characters?
  134. # __doc__ (as of 2008-08-02) for pygame.font.Font.metrics:
  135. # Font.metrics(text): return list
  136. # Gets the metrics for each character in the pased string.
  137. #
  138. # The list contains tuples for each character, which contain the
  139. # minimum X offset, the maximum X offset, the minimum Y offset, the
  140. # maximum Y offset and the advance offset (bearing plus width) of the
  141. # character. [(minx, maxx, miny, maxy, advance), (minx, maxx, miny,
  142. # maxy, advance), ...]
  143. self.fail()
  144. def test_render(self):
  145. """
  146. """
  147. f = pygame.font.Font(None, 20)
  148. s = f.render("foo", True, [0, 0, 0], [255, 255, 255])
  149. s = f.render("xxx", True, [0, 0, 0], [255, 255, 255])
  150. s = f.render("", True, [0, 0, 0], [255, 255, 255])
  151. s = f.render("foo", False, [0, 0, 0], [255, 255, 255])
  152. s = f.render("xxx", False, [0, 0, 0], [255, 255, 255])
  153. s = f.render("xxx", False, [0, 0, 0])
  154. s = f.render(" ", False, [0, 0, 0])
  155. s = f.render(" ", False, [0, 0, 0], [255, 255, 255])
  156. # null text should be 1 pixel wide.
  157. s = f.render("", False, [0, 0, 0], [255, 255, 255])
  158. self.assertEqual(s.get_size()[0], 1)
  159. # is background transparent for antialiasing?
  160. s = f.render(".", True, [255, 255, 255])
  161. self.failUnlessEqual(s.get_at((0, 0))[3], 0)
  162. # __doc__ (as of 2008-08-02) for pygame.font.Font.render:
  163. # Font.render(text, antialias, color, background=None): return Surface
  164. # draw text on a new Surface
  165. #
  166. # This creates a new Surface with the specified text rendered on it.
  167. # Pygame provides no way to directly draw text on an existing Surface:
  168. # instead you must use Font.render() to create an image (Surface) of
  169. # the text, then blit this image onto another Surface.
  170. #
  171. # The text can only be a single line: newline characters are not
  172. # rendered. The antialias argument is a boolean: if true the
  173. # characters will have smooth edges. The color argument is the color
  174. # of the text [e.g.: (0,0,255) for blue]. The optional background
  175. # argument is a color to use for the text background. If no background
  176. # is passed the area outside the text will be transparent.
  177. #
  178. # The Surface returned will be of the dimensions required to hold the
  179. # text. (the same as those returned by Font.size()). If an empty
  180. # string is passed for the text, a blank surface will be returned that
  181. # is one pixel wide and the height of the font.
  182. #
  183. # Depending on the type of background and antialiasing used, this
  184. # returns different types of Surfaces. For performance reasons, it is
  185. # good to know what type of image will be used. If antialiasing is not
  186. # used, the return image will always be an 8bit image with a two color
  187. # palette. If the background is transparent a colorkey will be set.
  188. # Antialiased images are rendered to 24-bit RGB images. If the
  189. # background is transparent a pixel alpha will be included.
  190. #
  191. # Optimization: if you know that the final destination for the text
  192. # (on the screen) will always have a solid background, and the text is
  193. # antialiased, you can improve performance by specifying the
  194. # background color. This will cause the resulting image to maintain
  195. # transparency information by colorkey rather than (much less
  196. # efficient) alpha values.
  197. #
  198. # If you render '\n' a unknown char will be rendered. Usually a
  199. # rectangle. Instead you need to handle new lines yourself.
  200. #
  201. # Font rendering is not thread safe: only a single thread can render
  202. # text any time.
  203. def test_set_bold(self):
  204. f = pygame.font.Font(None, 20)
  205. self.failIf(f.get_bold())
  206. f.set_bold(True)
  207. self.failUnless(f.get_bold())
  208. f.set_bold(False)
  209. self.failIf(f.get_bold())
  210. def test_set_italic(self):
  211. f = pygame.font.Font(None, 20)
  212. self.failIf(f.get_italic())
  213. f.set_italic(True)
  214. self.failUnless(f.get_italic())
  215. f.set_italic(False)
  216. self.failIf(f.get_bold())
  217. def test_set_underline(self):
  218. f = pygame.font.Font(None, 20)
  219. self.failIf(f.get_underline())
  220. f.set_underline(True)
  221. self.failUnless(f.get_underline())
  222. f.set_underline(False)
  223. self.failIf(f.get_underline())
  224. def test_size(self):
  225. f = pygame.font.Font(None, 20)
  226. text = "Xg"
  227. size = f.size(text)
  228. w, h = size
  229. self.failUnless(isinstance(w, int) and isinstance(h, int))
  230. s = f.render(text, False, (255, 255, 255))
  231. self.failUnlessEqual(size, s.get_size())
  232. def test_font_file_not_found(self):
  233. # A per BUG reported by Bo Jangeborg on pygame-user mailing list,
  234. # http://www.mail-archive.com/pygame-users@seul.org/msg11675.html
  235. pygame.font.init()
  236. def fetch():
  237. font = pygame.font.Font('some-fictional-font.ttf', 20)
  238. self.failUnlessRaises(IOError, fetch)
  239. class VisualTests( unittest.TestCase ):
  240. __tags__ = ['interactive']
  241. screen = None
  242. aborted = False
  243. def setUp(self):
  244. if self.screen is None:
  245. pygame.init()
  246. self.screen = pygame.display.set_mode((600, 200))
  247. self.screen.fill((255, 255, 255))
  248. pygame.display.flip()
  249. self.f = pygame.font.Font(None, 32)
  250. def abort(self):
  251. if self.screen is not None:
  252. pygame.quit()
  253. self.aborted = True
  254. def query(self,
  255. bold=False, italic=False, underline=False, antialiase=False):
  256. if self.aborted:
  257. return False
  258. spacing = 10
  259. offset = 20
  260. y = spacing
  261. f = self.f
  262. screen = self.screen
  263. screen.fill((255, 255, 255))
  264. pygame.display.flip()
  265. if not (bold or italic or underline or antialiase):
  266. text = "normal"
  267. else:
  268. modes = []
  269. if bold:
  270. modes.append("bold")
  271. if italic:
  272. modes.append("italic")
  273. if underline:
  274. modes.append("underlined")
  275. if antialiase:
  276. modes.append("antialiased")
  277. text = "%s (y/n):" % ('-'.join(modes),)
  278. f.set_bold(bold)
  279. f.set_italic(italic)
  280. f.set_underline(underline)
  281. s = f.render(text, antialiase, (0, 0, 0))
  282. screen.blit(s, (offset, y))
  283. y += s.get_size()[1] + spacing
  284. f.set_bold(False)
  285. f.set_italic(False)
  286. f.set_underline(False)
  287. s = f.render("(some comparison text)", False, (0, 0, 0))
  288. screen.blit(s, (offset, y))
  289. pygame.display.flip()
  290. while 1:
  291. for evt in pygame.event.get():
  292. if evt.type == pygame.KEYDOWN:
  293. if evt.key == pygame.K_ESCAPE:
  294. self.abort()
  295. return False
  296. if evt.key == pygame.K_y:
  297. return True
  298. if evt.key == pygame.K_n:
  299. return False
  300. if evt.type == pygame.QUIT:
  301. self.abort()
  302. return False
  303. def test_bold(self):
  304. self.failUnless(self.query(bold=True))
  305. def test_italic(self):
  306. self.failUnless(self.query(italic=True))
  307. def test_underline(self):
  308. self.failUnless(self.query(underline=True))
  309. def test_antialiase(self):
  310. self.failUnless(self.query(antialiase=True))
  311. def test_bold_antialiase(self):
  312. self.failUnless(self.query(bold=True, antialiase=True))
  313. def test_italic_underline(self):
  314. self.failUnless(self.query(italic=True, underline=True))
  315. if __name__ == '__main__':
  316. unittest.main()