surface_test.py 98 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538
  1. import os
  2. import unittest
  3. from pygame.tests import test_utils
  4. from pygame.tests.test_utils import (
  5. example_path, AssertRaisesRegexMixin, SurfaceSubclass)
  6. try:
  7. from pygame.tests.test_utils.arrinter import *
  8. except (ImportError, NameError):
  9. pass
  10. import pygame
  11. from pygame.locals import *
  12. from pygame.compat import xrange_, as_bytes, as_unicode
  13. from pygame.bufferproxy import BufferProxy
  14. import platform
  15. import gc
  16. import weakref
  17. import ctypes
  18. IS_PYPY = 'PyPy' == platform.python_implementation()
  19. def intify(i):
  20. """If i is a long, cast to an int while preserving the bits"""
  21. if 0x80000000 & i:
  22. return int((0xFFFFFFFF & i))
  23. return i
  24. def longify(i):
  25. """If i is an int, cast to a long while preserving the bits"""
  26. if i < 0:
  27. return 0xFFFFFFFF & i
  28. return long(i)
  29. class SurfaceTypeTest(AssertRaisesRegexMixin, unittest.TestCase):
  30. def test_surface__pixel_format_as_surface_subclass(self):
  31. """Ensure a subclassed surface can be used for pixel format
  32. when creating a new surface."""
  33. expected_depth = 16
  34. expected_flags = SRCALPHA
  35. expected_size = (13, 37)
  36. depth_surface = SurfaceSubclass((11, 21), expected_flags,
  37. expected_depth)
  38. surface = pygame.Surface(expected_size, 0, depth_surface)
  39. self.assertIsNot(surface, depth_surface)
  40. self.assertIsInstance(surface, pygame.Surface)
  41. self.assertNotIsInstance(surface, SurfaceSubclass)
  42. self.assertEqual(surface.get_size(), expected_size)
  43. self.assertEqual(surface.get_flags(), expected_flags)
  44. self.assertEqual(surface.get_bitsize(), expected_depth)
  45. def test_set_clip( self ):
  46. """ see if surface.set_clip(None) works correctly.
  47. """
  48. s = pygame.Surface((800, 600))
  49. r = pygame.Rect(10, 10, 10, 10)
  50. s.set_clip(r)
  51. r.move_ip(10, 0)
  52. s.set_clip(None)
  53. res = s.get_clip()
  54. # this was garbled before.
  55. self.assertEqual(res[0], 0)
  56. self.assertEqual(res[2], 800)
  57. def test_print(self):
  58. surf = pygame.Surface((70,70), 0, 32)
  59. self.assertEqual(repr(surf), '<Surface(70x70x32 SW)>')
  60. def test_keyword_arguments(self):
  61. surf = pygame.Surface((70,70), flags=SRCALPHA, depth=32)
  62. self.assertEqual(surf.get_flags() & SRCALPHA, SRCALPHA)
  63. self.assertEqual(surf.get_bitsize(), 32)
  64. # sanity check to make sure the check below is valid
  65. surf_16 = pygame.Surface((70,70), 0, 16)
  66. self.assertEqual(surf_16.get_bytesize(), 2)
  67. # try again with an argument list
  68. surf_16 = pygame.Surface((70,70), depth=16)
  69. self.assertEqual(surf_16.get_bytesize(), 2)
  70. def test_set_at(self):
  71. #24bit surfaces
  72. s = pygame.Surface( (100, 100), 0, 24)
  73. s.fill((0,0,0))
  74. # set it with a tuple.
  75. s.set_at((0,0), (10,10,10, 255))
  76. r = s.get_at((0,0))
  77. self.assertIsInstance(r, pygame.Color)
  78. self.assertEqual(r, (10,10,10, 255))
  79. # try setting a color with a single integer.
  80. s.fill((0,0,0,255))
  81. s.set_at ((10, 1), 0x0000FF)
  82. r = s.get_at((10,1))
  83. self.assertEqual(r, (0,0,255, 255))
  84. def test_SRCALPHA(self):
  85. # has the flag been passed in ok?
  86. surf = pygame.Surface((70,70), SRCALPHA, 32)
  87. self.assertEqual(surf.get_flags() & SRCALPHA, SRCALPHA)
  88. #24bit surfaces can not have SRCALPHA.
  89. self.assertRaises(ValueError, pygame.Surface, (100, 100), pygame.SRCALPHA, 24)
  90. # if we have a 32 bit surface, the SRCALPHA should have worked too.
  91. surf2 = pygame.Surface((70,70), SRCALPHA)
  92. if surf2.get_bitsize() == 32:
  93. self.assertEqual(surf2.get_flags() & SRCALPHA, SRCALPHA)
  94. def test_masks(self):
  95. def make_surf(bpp, flags, masks):
  96. pygame.Surface((10, 10), flags, bpp, masks)
  97. # With some masks SDL_CreateRGBSurface does not work properly.
  98. masks = (0xFF000000, 0xFF0000, 0xFF00, 0)
  99. self.assertEqual(make_surf(32, 0, masks), None)
  100. # For 24 and 32 bit surfaces Pygame assumes no losses.
  101. masks = (0x7F0000, 0xFF00, 0xFF, 0)
  102. self.assertRaises(ValueError, make_surf, 24, 0, masks)
  103. self.assertRaises(ValueError, make_surf, 32, 0, masks)
  104. # What contiguous bits in a mask.
  105. masks = (0x6F0000, 0xFF00, 0xFF, 0)
  106. self.assertRaises(ValueError, make_surf, 32, 0, masks)
  107. def test_get_bounding_rect (self):
  108. surf = pygame.Surface ((70, 70), SRCALPHA, 32)
  109. surf.fill((0,0,0,0))
  110. bound_rect = surf.get_bounding_rect()
  111. self.assertEqual(bound_rect.width, 0)
  112. self.assertEqual(bound_rect.height, 0)
  113. surf.set_at((30,30),(255,255,255,1))
  114. bound_rect = surf.get_bounding_rect()
  115. self.assertEqual(bound_rect.left, 30)
  116. self.assertEqual(bound_rect.top, 30)
  117. self.assertEqual(bound_rect.width, 1)
  118. self.assertEqual(bound_rect.height, 1)
  119. surf.set_at((29,29),(255,255,255,1))
  120. bound_rect = surf.get_bounding_rect()
  121. self.assertEqual(bound_rect.left, 29)
  122. self.assertEqual(bound_rect.top, 29)
  123. self.assertEqual(bound_rect.width, 2)
  124. self.assertEqual(bound_rect.height, 2)
  125. surf = pygame.Surface ((70, 70), 0, 24)
  126. surf.fill((0,0,0))
  127. bound_rect = surf.get_bounding_rect()
  128. self.assertEqual(bound_rect.width, surf.get_width())
  129. self.assertEqual(bound_rect.height, surf.get_height())
  130. surf.set_colorkey((0,0,0))
  131. bound_rect = surf.get_bounding_rect()
  132. self.assertEqual(bound_rect.width, 0)
  133. self.assertEqual(bound_rect.height, 0)
  134. surf.set_at((30,30),(255,255,255))
  135. bound_rect = surf.get_bounding_rect()
  136. self.assertEqual(bound_rect.left, 30)
  137. self.assertEqual(bound_rect.top, 30)
  138. self.assertEqual(bound_rect.width, 1)
  139. self.assertEqual(bound_rect.height, 1)
  140. surf.set_at((60,60),(255,255,255))
  141. bound_rect = surf.get_bounding_rect()
  142. self.assertEqual(bound_rect.left, 30)
  143. self.assertEqual(bound_rect.top, 30)
  144. self.assertEqual(bound_rect.width, 31)
  145. self.assertEqual(bound_rect.height, 31)
  146. # Issue #180
  147. pygame.display.init()
  148. try:
  149. surf = pygame.Surface((4, 1), 0, 8)
  150. surf.fill((255, 255, 255))
  151. surf.get_bounding_rect() # Segfault.
  152. finally:
  153. pygame.display.quit()
  154. def test_copy(self):
  155. """Ensure a surface can be copied."""
  156. color = (25, 25, 25, 25)
  157. s1 = pygame.Surface((32,32), pygame.SRCALPHA, 32)
  158. s1.fill(color)
  159. s2 = s1.copy()
  160. s1rect = s1.get_rect()
  161. s2rect = s2.get_rect()
  162. self.assertEqual(s1rect.size, s2rect.size)
  163. self.assertEqual(s2.get_at((10,10)), color)
  164. def test_fill(self):
  165. """Ensure a surface can be filled."""
  166. color = (25, 25, 25, 25)
  167. fill_rect = pygame.Rect(0, 0, 16, 16)
  168. s1 = pygame.Surface((32,32), pygame.SRCALPHA, 32)
  169. s1.fill(color, fill_rect)
  170. for pt in test_utils.rect_area_pts(fill_rect):
  171. self.assertEqual(s1.get_at(pt), color)
  172. for pt in test_utils.rect_outer_bounds(fill_rect):
  173. self.assertNotEqual(s1.get_at(pt), color)
  174. def test_fill_negative_coordinates(self):
  175. # negative coordinates should be clipped by fill, and not draw outside the surface.
  176. color = (25, 25, 25, 25)
  177. color2 = (20, 20, 20, 25)
  178. fill_rect = pygame.Rect(-10, -10, 16, 16)
  179. s1 = pygame.Surface((32,32), pygame.SRCALPHA, 32)
  180. r1 = s1.fill(color, fill_rect)
  181. c = s1.get_at((0,0))
  182. self.assertEqual(c, color)
  183. # make subsurface in the middle to test it doesn't over write.
  184. s2 = s1.subsurface((5, 5, 5, 5))
  185. r2 = s2.fill(color2, (-3, -3, 5, 5))
  186. c2 = s1.get_at((4,4))
  187. self.assertEqual(c, color)
  188. # rect returns the area we actually fill.
  189. r3 = s2.fill(color2, (-30, -30, 5, 5))
  190. # since we are using negative coords, it should be an zero sized rect.
  191. self.assertEqual(tuple(r3), (0, 0, 0, 0))
  192. def test_fill_keyword_args(self):
  193. """Ensure fill() accepts keyword arguments."""
  194. color = (1, 2, 3, 255)
  195. area = (1, 1, 2, 2)
  196. s1 = pygame.Surface((4, 4), 0, 32)
  197. s1.fill(special_flags=pygame.BLEND_ADD, color=color, rect=area)
  198. self.assertEqual(s1.get_at((0, 0)), (0, 0, 0, 255))
  199. self.assertEqual(s1.get_at((1, 1)), color)
  200. ########################################################################
  201. def test_get_alpha(self):
  202. """Ensure a surface's alpha value can be retrieved."""
  203. s1 = pygame.Surface((32,32), pygame.SRCALPHA, 32)
  204. self.assertEqual(s1.get_alpha(), 255)
  205. for alpha in (0, 32, 127, 255):
  206. s1.set_alpha(alpha)
  207. for t in range(4):
  208. s1.set_alpha(s1.get_alpha())
  209. self.assertEqual(s1.get_alpha(), alpha)
  210. ########################################################################
  211. def test_get_bytesize(self):
  212. """Ensure a surface's bit and byte sizes can be retrieved."""
  213. depth = 32
  214. depth_bytes = 4
  215. s1 = pygame.Surface((32, 32), pygame.SRCALPHA, depth)
  216. self.assertEqual(s1.get_bytesize(), depth_bytes)
  217. self.assertEqual(s1.get_bitsize(), depth)
  218. ########################################################################
  219. def test_get_flags(self):
  220. """Ensure a surface's flags can be retrieved."""
  221. s1 = pygame.Surface((32,32), pygame.SRCALPHA, 32)
  222. self.assertEqual(s1.get_flags(), pygame.SRCALPHA)
  223. ########################################################################
  224. def test_get_parent(self):
  225. """Ensure a surface's parent can be retrieved."""
  226. parent = pygame.Surface((16, 16))
  227. child = parent.subsurface((0,0,5,5))
  228. self.assertIs(child.get_parent(), parent)
  229. ########################################################################
  230. def test_get_rect(self):
  231. """Ensure a surface's rect can be retrieved."""
  232. size = (16, 16)
  233. surf = pygame.Surface(size)
  234. rect = surf.get_rect()
  235. self.assertEqual(rect.size, size)
  236. ########################################################################
  237. def test_get_width__size_and_height(self):
  238. """Ensure a surface's size, width and height can be retrieved."""
  239. for w in xrange_(0, 255, 32):
  240. for h in xrange_(0, 127, 15):
  241. s = pygame.Surface((w, h))
  242. self.assertEqual(s.get_width(), w)
  243. self.assertEqual(s.get_height(), h)
  244. self.assertEqual(s.get_size(), (w, h))
  245. def test_get_view(self):
  246. """Ensure a buffer view of the surface's pixels can be retrieved."""
  247. # Check that BufferProxys are returned when array depth is supported,
  248. # ValueErrors returned otherwise.
  249. Error = ValueError
  250. s = pygame.Surface((5, 7), 0, 8)
  251. v2 = s.get_view('2')
  252. self.assertRaises(Error, s.get_view, '0')
  253. self.assertRaises(Error, s.get_view, '1')
  254. self.assertIsInstance(v2, BufferProxy)
  255. self.assertRaises(Error, s.get_view, '3')
  256. s = pygame.Surface((8, 7), 0, 8)
  257. length = s.get_bytesize() * s.get_width() * s.get_height()
  258. v0 = s.get_view('0')
  259. v1 = s.get_view('1')
  260. self.assertIsInstance(v0, BufferProxy)
  261. self.assertEqual(v0.length, length)
  262. self.assertIsInstance(v1, BufferProxy)
  263. self.assertEqual(v1.length, length)
  264. s = pygame.Surface((5, 7), 0, 16)
  265. v2 = s.get_view('2')
  266. self.assertRaises(Error, s.get_view, '0')
  267. self.assertRaises(Error, s.get_view, '1')
  268. self.assertIsInstance(v2, BufferProxy)
  269. self.assertRaises(Error, s.get_view, '3')
  270. s = pygame.Surface((8, 7), 0, 16)
  271. length = s.get_bytesize() * s.get_width() * s.get_height()
  272. v0 = s.get_view('0')
  273. v1 = s.get_view('1')
  274. self.assertIsInstance(v0, BufferProxy)
  275. self.assertEqual(v0.length, length)
  276. self.assertIsInstance(v1, BufferProxy)
  277. self.assertEqual(v1.length, length)
  278. s = pygame.Surface((5, 7), pygame.SRCALPHA, 16)
  279. v2 = s.get_view('2')
  280. self.assertIsInstance(v2, BufferProxy)
  281. self.assertRaises(Error, s.get_view, '3')
  282. s = pygame.Surface((5, 7), 0, 24)
  283. v2 = s.get_view('2')
  284. v3 = s.get_view('3')
  285. self.assertRaises(Error, s.get_view, '0')
  286. self.assertRaises(Error, s.get_view, '1')
  287. self.assertIsInstance(v2, BufferProxy)
  288. self.assertIsInstance(v3, BufferProxy)
  289. s = pygame.Surface((8, 7), 0, 24)
  290. length = s.get_bytesize() * s.get_width() * s.get_height()
  291. v0 = s.get_view('0')
  292. v1 = s.get_view('1')
  293. self.assertIsInstance(v0, BufferProxy)
  294. self.assertEqual(v0.length, length)
  295. self.assertIsInstance(v1, BufferProxy)
  296. self.assertEqual(v1.length, length)
  297. s = pygame.Surface((5, 7), 0, 32)
  298. length = s.get_bytesize() * s.get_width() * s.get_height()
  299. v0 = s.get_view('0')
  300. v1 = s.get_view('1')
  301. v2 = s.get_view('2')
  302. v3 = s.get_view('3')
  303. self.assertIsInstance(v0, BufferProxy)
  304. self.assertEqual(v0.length, length)
  305. self.assertIsInstance(v1, BufferProxy)
  306. self.assertEqual(v1.length, length)
  307. self.assertIsInstance(v2, BufferProxy)
  308. self.assertIsInstance(v3, BufferProxy)
  309. s2 = s.subsurface((0, 0, 4, 7))
  310. self.assertRaises(Error, s2.get_view, '0')
  311. self.assertRaises(Error, s2.get_view, '1')
  312. s2 = None
  313. s = pygame.Surface((5, 7), pygame.SRCALPHA, 32)
  314. for kind in ('2', '3', 'a', 'A', 'r', 'R', 'g', 'G', 'b', 'B'):
  315. self.assertIsInstance(s.get_view(kind), BufferProxy)
  316. # Check default argument value: '2'
  317. s = pygame.Surface((2, 4), 0, 32)
  318. v = s.get_view()
  319. if not IS_PYPY:
  320. ai = ArrayInterface(v)
  321. self.assertEqual(ai.nd, 2)
  322. # Check locking.
  323. s = pygame.Surface((2, 4), 0, 32)
  324. self.assertFalse(s.get_locked())
  325. v = s.get_view('2')
  326. self.assertFalse(s.get_locked())
  327. c = v.__array_interface__
  328. self.assertTrue(s.get_locked())
  329. c = None
  330. gc.collect()
  331. self.assertTrue(s.get_locked())
  332. v = None
  333. gc.collect()
  334. self.assertFalse(s.get_locked())
  335. # Check invalid view kind values.
  336. s = pygame.Surface((2, 4), pygame.SRCALPHA, 32)
  337. self.assertRaises(TypeError, s.get_view, '')
  338. self.assertRaises(TypeError, s.get_view, '9')
  339. self.assertRaises(TypeError, s.get_view, 'RGBA')
  340. self.assertRaises(TypeError, s.get_view, 2)
  341. # Both unicode and bytes strings are allowed for kind.
  342. s = pygame.Surface((2, 4), 0, 32)
  343. s.get_view(as_unicode('2'))
  344. s.get_view(as_bytes('2'))
  345. # Garbage collection
  346. s = pygame.Surface((2, 4), 0, 32)
  347. weak_s = weakref.ref(s)
  348. v = s.get_view('3')
  349. weak_v = weakref.ref(v)
  350. gc.collect()
  351. self.assertTrue(weak_s() is s)
  352. self.assertTrue(weak_v() is v)
  353. del v
  354. gc.collect()
  355. self.assertTrue(weak_s() is s)
  356. self.assertTrue(weak_v() is None)
  357. del s
  358. gc.collect()
  359. self.assertTrue(weak_s() is None)
  360. def test_get_buffer(self):
  361. # Check that get_buffer works for all pixel sizes and for a subsurface.
  362. # Check for all pixel sizes
  363. for bitsize in [8, 16, 24, 32]:
  364. s = pygame.Surface((5, 7), 0, bitsize)
  365. length = s.get_pitch() * s.get_height()
  366. v = s.get_buffer()
  367. self.assertIsInstance(v, BufferProxy)
  368. self.assertEqual(v.length, length)
  369. self.assertEqual(repr(v), "<BufferProxy(" + str(length) + ")>")
  370. # Check for a subsurface (not contiguous)
  371. s = pygame.Surface((7, 10), 0, 32)
  372. s2 = s.subsurface((1, 2, 5, 7))
  373. length = s2.get_pitch() * s2.get_height()
  374. v = s2.get_buffer()
  375. self.assertIsInstance(v, BufferProxy)
  376. self.assertEqual(v.length, length)
  377. # Check locking.
  378. s = pygame.Surface((2, 4), 0, 32)
  379. v = s.get_buffer()
  380. self.assertTrue(s.get_locked())
  381. v = None
  382. gc.collect()
  383. self.assertFalse(s.get_locked())
  384. OLDBUF = hasattr(pygame.bufferproxy, 'get_segcount')
  385. @unittest.skipIf(not OLDBUF, 'old buffer not available')
  386. def test_get_buffer_oldbuf(self):
  387. from pygame.bufferproxy import get_segcount, get_write_buffer
  388. s = pygame.Surface((2, 4), pygame.SRCALPHA, 32)
  389. v = s.get_buffer()
  390. segcount, buflen = get_segcount(v)
  391. self.assertEqual(segcount, 1)
  392. self.assertEqual(buflen, s.get_pitch() * s.get_height())
  393. seglen, segaddr = get_write_buffer(v, 0)
  394. self.assertEqual(segaddr, s._pixels_address)
  395. self.assertEqual(seglen, buflen)
  396. @unittest.skipIf(not OLDBUF, 'old buffer not available')
  397. def test_get_view_oldbuf(self):
  398. from pygame.bufferproxy import get_segcount, get_write_buffer
  399. s = pygame.Surface((2, 4), pygame.SRCALPHA, 32)
  400. v = s.get_view('1')
  401. segcount, buflen = get_segcount(v)
  402. self.assertEqual(segcount, 8)
  403. self.assertEqual(buflen, s.get_pitch() * s.get_height())
  404. seglen, segaddr = get_write_buffer(v, 7)
  405. self.assertEqual(segaddr, s._pixels_address + s.get_bytesize() * 7)
  406. self.assertEqual(seglen, s.get_bytesize())
  407. def test_set_colorkey(self):
  408. # __doc__ (as of 2008-06-25) for pygame.surface.Surface.set_colorkey:
  409. # Surface.set_colorkey(Color, flags=0): return None
  410. # Surface.set_colorkey(None): return None
  411. # Set the transparent colorkey
  412. s = pygame.Surface((16,16), pygame.SRCALPHA, 32)
  413. colorkeys = ((20,189,20, 255),(128,50,50,255), (23, 21, 255,255))
  414. for colorkey in colorkeys:
  415. s.set_colorkey(colorkey)
  416. for t in range(4):
  417. s.set_colorkey(s.get_colorkey())
  418. self.assertEqual(s.get_colorkey(), colorkey)
  419. def test_set_masks(self):
  420. s = pygame.Surface((32,32))
  421. r,g,b,a = s.get_masks()
  422. s.set_masks((b,g,r,a))
  423. r2,g2,b2,a2 = s.get_masks()
  424. self.assertEqual((r,g,b,a), (b2,g2,r2,a2))
  425. def test_set_shifts(self):
  426. s = pygame.Surface((32,32))
  427. r,g,b,a = s.get_shifts()
  428. s.set_shifts((b,g,r,a))
  429. r2,g2,b2,a2 = s.get_shifts()
  430. self.assertEqual((r,g,b,a), (b2,g2,r2,a2))
  431. def test_blit_keyword_args(self):
  432. color = (1, 2, 3, 255)
  433. s1 = pygame.Surface((4, 4), 0, 32)
  434. s2 = pygame.Surface((2, 2), 0, 32)
  435. s2.fill((1, 2, 3))
  436. s1.blit(special_flags=BLEND_ADD, source=s2,
  437. dest=(1, 1), area=s2.get_rect())
  438. self.assertEqual(s1.get_at((0, 0)), (0, 0, 0, 255))
  439. self.assertEqual(s1.get_at((1, 1)), color)
  440. def todo_test_blit(self):
  441. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.blit:
  442. # Surface.blit(source, dest, area=None, special_flags = 0): return Rect
  443. # draw one image onto another
  444. #
  445. # Draws a source Surface onto this Surface. The draw can be positioned
  446. # with the dest argument. Dest can either be pair of coordinates
  447. # representing the upper left corner of the source. A Rect can also be
  448. # passed as the destination and the topleft corner of the rectangle
  449. # will be used as the position for the blit. The size of the
  450. # destination rectangle does not effect the blit.
  451. #
  452. # An optional area rectangle can be passed as well. This represents a
  453. # smaller portion of the source Surface to draw.
  454. #
  455. # An optional special flags is for passing in new in 1.8.0: BLEND_ADD,
  456. # BLEND_SUB, BLEND_MULT, BLEND_MIN, BLEND_MAX new in 1.8.1:
  457. # BLEND_RGBA_ADD, BLEND_RGBA_SUB, BLEND_RGBA_MULT, BLEND_RGBA_MIN,
  458. # BLEND_RGBA_MAX BLEND_RGB_ADD, BLEND_RGB_SUB, BLEND_RGB_MULT,
  459. # BLEND_RGB_MIN, BLEND_RGB_MAX With other special blitting flags
  460. # perhaps added in the future.
  461. #
  462. # The return rectangle is the area of the affected pixels, excluding
  463. # any pixels outside the destination Surface, or outside the clipping
  464. # area.
  465. #
  466. # Pixel alphas will be ignored when blitting to an 8 bit Surface.
  467. # special_flags new in pygame 1.8.
  468. self.fail()
  469. def test_blit__SRCALPHA_opaque_source(self):
  470. src = pygame.Surface( (256,256), SRCALPHA ,32)
  471. dst = src.copy()
  472. for i, j in test_utils.rect_area_pts(src.get_rect()):
  473. dst.set_at( (i,j), (i,0,0,j) )
  474. src.set_at( (i,j), (0,i,0,255) )
  475. dst.blit(src, (0,0))
  476. for pt in test_utils.rect_area_pts(src.get_rect()):
  477. self.assertEqual(dst.get_at(pt)[1], src.get_at(pt)[1])
  478. def todo_test_blit__blit_to_self(self): #TODO
  479. src = pygame.Surface( (256,256), SRCALPHA, 32)
  480. rect = src.get_rect()
  481. for pt, color in test_utils.gradient(rect.width, rect.height):
  482. src.set_at(pt, color)
  483. src.blit(src, (0, 0))
  484. def todo_test_blit__SRCALPHA_to_SRCALPHA_non_zero(self): #TODO
  485. # " There is no unit test for blitting a SRCALPHA source with non-zero
  486. # alpha to a SRCALPHA destination with non-zero alpha " LL
  487. w,h = size = 32,32
  488. s = pygame.Surface(size, pygame.SRCALPHA, 32)
  489. s2 = s.copy()
  490. s.fill((32,32,32,111))
  491. s2.fill((32,32,32,31))
  492. s.blit(s2, (0,0))
  493. # TODO:
  494. # what is the correct behaviour ?? should it blend? what algorithm?
  495. self.assertEqual(s.get_at((0,0)), (32,32,32,31))
  496. def test_blit__SRCALPHA32_to_8(self):
  497. # Bug: fatal
  498. # SDL_DisplayConvert segfaults when video is uninitialized.
  499. target = pygame.Surface((11, 8), 0, 8)
  500. color = target.get_palette_at(2)
  501. source = pygame.Surface((1, 1), pygame.SRCALPHA, 32)
  502. source.set_at((0, 0), color)
  503. target.blit(source, (0, 0))
  504. @unittest.skipIf(os.environ.get('SDL_VIDEODRIVER') == 'dummy',
  505. 'requires a non-"dummy" SDL_VIDEODRIVER')
  506. def test_image_convert_bug_131(self):
  507. # Bitbucket bug #131: Unable to Surface.convert(32) some 1-bit images.
  508. # https://bitbucket.org/pygame/pygame/issue/131/unable-to-surfaceconvert-32-some-1-bit
  509. pygame.display.init()
  510. try:
  511. pygame.display.set_mode((640,480))
  512. im = pygame.image.load(example_path(
  513. os.path.join("data", "city.png")))
  514. im2 = pygame.image.load(example_path(
  515. os.path.join("data", "brick.png")))
  516. self.assertEqual(im.get_palette(),
  517. ((0, 0, 0, 255), (255, 255, 255, 255)))
  518. self.assertEqual(im2.get_palette(),
  519. ((0, 0, 0, 255), (0, 0, 0, 255)))
  520. self.assertEqual(repr(im.convert(32)), '<Surface(24x24x32 SW)>')
  521. self.assertEqual(repr(im2.convert(32)), '<Surface(469x137x32 SW)>')
  522. # Ensure a palette format to palette format works.
  523. im3 = im.convert(8)
  524. self.assertEqual(repr(im3), '<Surface(24x24x8 SW)>')
  525. self.assertEqual(im3.get_palette(), im.get_palette())
  526. finally:
  527. pygame.display.quit()
  528. def test_convert_init(self):
  529. """ Ensure initialization exceptions are raised
  530. for surf.convert()."""
  531. pygame.display.quit()
  532. surf = pygame.Surface((1, 1))
  533. self.assertRaisesRegex(pygame.error, 'display initialized',
  534. surf.convert)
  535. pygame.display.init()
  536. try:
  537. if os.environ.get('SDL_VIDEODRIVER') != 'dummy':
  538. try:
  539. surf.convert(32)
  540. surf.convert(pygame.Surface((1, 1)))
  541. except pygame.error:
  542. self.fail("convert() should not raise an exception here.")
  543. self.assertRaisesRegex(pygame.error, 'No video mode',
  544. surf.convert)
  545. pygame.display.set_mode((640,480))
  546. try:
  547. surf.convert()
  548. except pygame.error:
  549. self.fail("convert() should not raise an exception here.")
  550. finally:
  551. pygame.display.quit()
  552. def test_convert_alpha_init(self):
  553. """ Ensure initialization exceptions are raised
  554. for surf.convert_alpha()."""
  555. pygame.display.quit()
  556. surf = pygame.Surface((1, 1))
  557. self.assertRaisesRegex(pygame.error, 'display initialized',
  558. surf.convert_alpha)
  559. pygame.display.init()
  560. try:
  561. self.assertRaisesRegex(pygame.error, 'No video mode',
  562. surf.convert_alpha)
  563. pygame.display.set_mode((640,480))
  564. try:
  565. surf.convert_alpha()
  566. except pygame.error:
  567. self.fail("convert_alpha() should not raise an exception here.")
  568. finally:
  569. pygame.display.quit()
  570. def todo_test_convert(self):
  571. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.convert:
  572. # Surface.convert(Surface): return Surface
  573. # Surface.convert(depth, flags=0): return Surface
  574. # Surface.convert(masks, flags=0): return Surface
  575. # Surface.convert(): return Surface
  576. # change the pixel format of an image
  577. #
  578. # Creates a new copy of the Surface with the pixel format changed. The
  579. # new pixel format can be determined from another existing Surface.
  580. # Otherwise depth, flags, and masks arguments can be used, similar to
  581. # the pygame.Surface() call.
  582. #
  583. # If no arguments are passed the new Surface will have the same pixel
  584. # format as the display Surface. This is always the fastest format for
  585. # blitting. It is a good idea to convert all Surfaces before they are
  586. # blitted many times.
  587. #
  588. # The converted Surface will have no pixel alphas. They will be
  589. # stripped if the original had them. See Surface.convert_alpha() for
  590. # preserving or creating per-pixel alphas.
  591. #
  592. self.fail()
  593. def test_convert__pixel_format_as_surface_subclass(self):
  594. """Ensure convert accepts a Surface subclass argument."""
  595. expected_size = (23, 17)
  596. convert_surface = SurfaceSubclass(expected_size, 0, 32)
  597. depth_surface = SurfaceSubclass((31, 61), 0, 32)
  598. pygame.display.init()
  599. try:
  600. surface = convert_surface.convert(depth_surface)
  601. self.assertIsNot(surface, depth_surface)
  602. self.assertIsNot(surface, convert_surface)
  603. self.assertIsInstance(surface, pygame.Surface)
  604. self.assertIsInstance(surface, SurfaceSubclass)
  605. self.assertEqual(surface.get_size(), expected_size)
  606. finally:
  607. pygame.display.quit()
  608. def todo_test_convert_alpha(self):
  609. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.convert_alpha:
  610. # Surface.convert_alpha(Surface): return Surface
  611. # Surface.convert_alpha(): return Surface
  612. # change the pixel format of an image including per pixel alphas
  613. #
  614. # Creates a new copy of the surface with the desired pixel format. The
  615. # new surface will be in a format suited for quick blitting to the
  616. # given format with per pixel alpha. If no surface is given, the new
  617. # surface will be optimized for blitting to the current display.
  618. #
  619. # Unlike the Surface.convert() method, the pixel format for the new
  620. # image will not be exactly the same as the requested source, but it
  621. # will be optimized for fast alpha blitting to the destination.
  622. #
  623. self.fail()
  624. def test_convert_alpha__pixel_format_as_surface_subclass(self):
  625. """Ensure convert_alpha accepts a Surface subclass argument."""
  626. expected_size = (23, 17)
  627. convert_surface = SurfaceSubclass(expected_size, SRCALPHA, 32)
  628. depth_surface = SurfaceSubclass((31, 57), SRCALPHA, 32)
  629. pygame.display.init()
  630. try:
  631. pygame.display.set_mode((60, 60))
  632. # This is accepted as an argument, but its values are ignored.
  633. # See issue #599.
  634. surface = convert_surface.convert_alpha(depth_surface)
  635. self.assertIsNot(surface, depth_surface)
  636. self.assertIsNot(surface, convert_surface)
  637. self.assertIsInstance(surface, pygame.Surface)
  638. self.assertIsInstance(surface, SurfaceSubclass)
  639. self.assertEqual(surface.get_size(), expected_size)
  640. finally:
  641. pygame.display.quit()
  642. def todo_test_get_abs_offset(self):
  643. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.get_abs_offset:
  644. # Surface.get_abs_offset(): return (x, y)
  645. # find the absolute position of a child subsurface inside its top level parent
  646. #
  647. # Get the offset position of a child subsurface inside of its top
  648. # level parent Surface. If the Surface is not a subsurface this will
  649. # return (0, 0).
  650. #
  651. self.fail()
  652. def todo_test_get_abs_parent(self):
  653. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.get_abs_parent:
  654. # Surface.get_abs_parent(): return Surface
  655. # find the top level parent of a subsurface
  656. #
  657. # Returns the parent Surface of a subsurface. If this is not a
  658. # subsurface then this surface will be returned.
  659. #
  660. self.fail()
  661. def test_get_at(self):
  662. surf = pygame.Surface((2, 2), 0, 24)
  663. c00 = pygame.Color(1, 2, 3)
  664. c01 = pygame.Color(5, 10, 15)
  665. c10 = pygame.Color(100, 50, 0)
  666. c11 = pygame.Color(4, 5, 6)
  667. surf.set_at((0, 0), c00)
  668. surf.set_at((0, 1), c01)
  669. surf.set_at((1, 0), c10)
  670. surf.set_at((1, 1), c11)
  671. c = surf.get_at((0, 0))
  672. self.assertIsInstance(c, pygame.Color)
  673. self.assertEqual(c, c00)
  674. self.assertEqual(surf.get_at((0, 1)), c01)
  675. self.assertEqual(surf.get_at((1, 0)), c10)
  676. self.assertEqual(surf.get_at((1, 1)), c11)
  677. for p in [(-1, 0), (0, -1), (2, 0), (0, 2)]:
  678. self.assertRaises(IndexError, surf.get_at, p)
  679. def test_get_at_mapped(self):
  680. color = pygame.Color(10, 20, 30)
  681. for bitsize in [8, 16, 24, 32]:
  682. surf = pygame.Surface((2, 2), 0, bitsize)
  683. surf.fill(color)
  684. pixel = surf.get_at_mapped((0, 0))
  685. self.assertEqual(pixel, surf.map_rgb(color),
  686. "%i != %i, bitsize: %i" %
  687. (pixel, surf.map_rgb(color), bitsize))
  688. def todo_test_get_bitsize(self):
  689. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.get_bitsize:
  690. # Surface.get_bitsize(): return int
  691. # get the bit depth of the Surface pixel format
  692. #
  693. # Returns the number of bits used to represent each pixel. This value
  694. # may not exactly fill the number of bytes used per pixel. For example
  695. # a 15 bit Surface still requires a full 2 bytes.
  696. #
  697. self.fail()
  698. def todo_test_get_clip(self):
  699. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.get_clip:
  700. # Surface.get_clip(): return Rect
  701. # get the current clipping area of the Surface
  702. #
  703. # Return a rectangle of the current clipping area. The Surface will
  704. # always return a valid rectangle that will never be outside the
  705. # bounds of the image. If the Surface has had None set for the
  706. # clipping area, the Surface will return a rectangle with the full
  707. # area of the Surface.
  708. #
  709. self.fail()
  710. def todo_test_get_colorkey(self):
  711. surf = pygame.surface((2, 2), 0, 24)
  712. self.assertIsNone(surf.get_colorykey())
  713. colorkey = pygame.Color(20, 40, 60)
  714. surf.set_colorkey(colorkey)
  715. ck = surf.get_colorkey()
  716. self.assertIsInstance(ck, pygame.Color)
  717. self.assertEqual(ck, colorkey)
  718. def todo_test_get_height(self):
  719. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.get_height:
  720. # Surface.get_height(): return height
  721. # get the height of the Surface
  722. #
  723. # Return the height of the Surface in pixels.
  724. self.fail()
  725. def todo_test_get_locked(self):
  726. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.get_locked:
  727. # Surface.get_locked(): return bool
  728. # test if the Surface is current locked
  729. #
  730. # Returns True when the Surface is locked. It doesn't matter how many
  731. # times the Surface is locked.
  732. #
  733. self.fail()
  734. def todo_test_get_locks(self):
  735. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.get_locks:
  736. # Surface.get_locks(): return tuple
  737. # Gets the locks for the Surface
  738. #
  739. # Returns the currently existing locks for the Surface.
  740. self.fail()
  741. def todo_test_get_losses(self):
  742. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.get_losses:
  743. # Surface.get_losses(): return (R, G, B, A)
  744. # the significant bits used to convert between a color and a mapped integer
  745. #
  746. # Return the least significant number of bits stripped from each color
  747. # in a mapped integer.
  748. #
  749. # This value is not needed for normal Pygame usage.
  750. self.fail()
  751. def todo_test_get_masks(self):
  752. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.get_masks:
  753. # Surface.get_masks(): return (R, G, B, A)
  754. # the bitmasks needed to convert between a color and a mapped integer
  755. #
  756. # Returns the bitmasks used to isolate each color in a mapped integer.
  757. # This value is not needed for normal Pygame usage.
  758. self.fail()
  759. def todo_test_get_offset(self):
  760. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.get_offset:
  761. # Surface.get_offset(): return (x, y)
  762. # find the position of a child subsurface inside a parent
  763. #
  764. # Get the offset position of a child subsurface inside of a parent. If
  765. # the Surface is not a subsurface this will return (0, 0).
  766. #
  767. self.fail()
  768. def test_get_palette(self):
  769. pygame.display.init()
  770. try:
  771. palette = [Color(i, i, i) for i in range(256)]
  772. pygame.display.set_mode((100, 50))
  773. surf = pygame.Surface((2, 2), 0, 8)
  774. surf.set_palette(palette)
  775. palette2 = surf.get_palette()
  776. r,g,b = palette2[0]
  777. self.assertEqual(len(palette2), len(palette))
  778. for c2, c in zip(palette2, palette):
  779. self.assertEqual(c2, c)
  780. for c in palette2:
  781. self.assertIsInstance(c, pygame.Color)
  782. finally:
  783. pygame.display.quit()
  784. def test_get_palette_at(self):
  785. # See also test_get_palette
  786. pygame.display.init()
  787. try:
  788. pygame.display.set_mode((100, 50))
  789. surf = pygame.Surface((2, 2), 0, 8)
  790. color = pygame.Color(1, 2, 3, 255)
  791. surf.set_palette_at(0, color)
  792. color2 = surf.get_palette_at(0)
  793. self.assertIsInstance(color2, pygame.Color)
  794. self.assertEqual(color2, color)
  795. self.assertRaises(IndexError, surf.get_palette_at, -1)
  796. self.assertRaises(IndexError, surf.get_palette_at, 256)
  797. finally:
  798. pygame.display.quit()
  799. def todo_test_get_pitch(self):
  800. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.get_pitch:
  801. # Surface.get_pitch(): return int
  802. # get the number of bytes used per Surface row
  803. #
  804. # Return the number of bytes separating each row in the Surface.
  805. # Surfaces in video memory are not always linearly packed. Subsurfaces
  806. # will also have a larger pitch than their real width.
  807. #
  808. # This value is not needed for normal Pygame usage.
  809. self.fail()
  810. def todo_test_get_shifts(self):
  811. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.get_shifts:
  812. # Surface.get_shifts(): return (R, G, B, A)
  813. # the bit shifts needed to convert between a color and a mapped integer
  814. #
  815. # Returns the pixel shifts need to convert between each color and a
  816. # mapped integer.
  817. #
  818. # This value is not needed for normal Pygame usage.
  819. self.fail()
  820. def todo_test_get_size(self):
  821. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.get_size:
  822. # Surface.get_size(): return (width, height)
  823. # get the dimensions of the Surface
  824. #
  825. # Return the width and height of the Surface in pixels.
  826. self.fail()
  827. def todo_test_lock(self):
  828. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.lock:
  829. # Surface.lock(): return None
  830. # lock the Surface memory for pixel access
  831. #
  832. # Lock the pixel data of a Surface for access. On accelerated
  833. # Surfaces, the pixel data may be stored in volatile video memory or
  834. # nonlinear compressed forms. When a Surface is locked the pixel
  835. # memory becomes available to access by regular software. Code that
  836. # reads or writes pixel values will need the Surface to be locked.
  837. #
  838. # Surfaces should not remain locked for more than necessary. A locked
  839. # Surface can often not be displayed or managed by Pygame.
  840. #
  841. # Not all Surfaces require locking. The Surface.mustlock() method can
  842. # determine if it is actually required. There is no performance
  843. # penalty for locking and unlocking a Surface that does not need it.
  844. #
  845. # All pygame functions will automatically lock and unlock the Surface
  846. # data as needed. If a section of code is going to make calls that
  847. # will repeatedly lock and unlock the Surface many times, it can be
  848. # helpful to wrap the block inside a lock and unlock pair.
  849. #
  850. # It is safe to nest locking and unlocking calls. The surface will
  851. # only be unlocked after the final lock is released.
  852. #
  853. self.fail()
  854. def test_map_rgb(self):
  855. color = Color(0, 128, 255, 64)
  856. surf = pygame.Surface((5, 5), SRCALPHA, 32)
  857. c = surf.map_rgb(color)
  858. self.assertEqual(surf.unmap_rgb(c), color)
  859. self.assertEqual(surf.get_at((0, 0)), (0, 0, 0, 0))
  860. surf.fill(c)
  861. self.assertEqual(surf.get_at((0, 0)), color)
  862. surf.fill((0, 0, 0, 0))
  863. self.assertEqual(surf.get_at((0, 0)), (0, 0, 0, 0))
  864. surf.set_at((0, 0), c)
  865. self.assertEqual(surf.get_at((0, 0)), color)
  866. def todo_test_mustlock(self):
  867. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.mustlock:
  868. # Surface.mustlock(): return bool
  869. # test if the Surface requires locking
  870. #
  871. # Returns True if the Surface is required to be locked to access pixel
  872. # data. Usually pure software Surfaces do not require locking. This
  873. # method is rarely needed, since it is safe and quickest to just lock
  874. # all Surfaces as needed.
  875. #
  876. # All pygame functions will automatically lock and unlock the Surface
  877. # data as needed. If a section of code is going to make calls that
  878. # will repeatedly lock and unlock the Surface many times, it can be
  879. # helpful to wrap the block inside a lock and unlock pair.
  880. #
  881. self.fail()
  882. def test_set_alpha_none(self):
  883. """surf.set_alpha(None) disables blending"""
  884. s = pygame.Surface((1,1), SRCALPHA, 32)
  885. s.fill((0, 255, 0, 128))
  886. s.set_alpha(None)
  887. self.assertEqual(None, s.get_alpha())
  888. s2 = pygame.Surface((1,1), SRCALPHA, 32)
  889. s2.fill((255, 0, 0, 255))
  890. s2.blit(s, (0, 0))
  891. self.assertEqual(s2.get_at((0, 0))[0], 0, "the red component should be 0")
  892. def test_set_alpha_value(self):
  893. """surf.set_alpha(x), where x != None, enables blending"""
  894. s = pygame.Surface((1,1), SRCALPHA, 32)
  895. s.fill((0, 255, 0, 128))
  896. s.set_alpha(255)
  897. s2 = pygame.Surface((1,1), SRCALPHA, 32)
  898. s2.fill((255, 0, 0, 255))
  899. s2.blit(s, (0, 0))
  900. self.assertGreater(s2.get_at((0, 0))[0], 0, "the red component should be above 0")
  901. def test_palette_colorkey(self):
  902. """ test bug discovered by robertpfeiffer
  903. https://github.com/pygame/pygame/issues/721
  904. """
  905. surf = pygame.image.load(example_path(os.path.join("data", "alien2.png")))
  906. key = surf.get_colorkey()
  907. self.assertEqual(surf.get_palette()[surf.map_rgb(key)], key)
  908. def test_palette_colorkey_set_px(self):
  909. surf = pygame.image.load(example_path(os.path.join("data", "alien2.png")))
  910. key = surf.get_colorkey()
  911. surf.set_at((0, 0), key)
  912. self.assertEqual(surf.get_at((0, 0)), key)
  913. def test_palette_colorkey_fill(self):
  914. surf = pygame.image.load(example_path(os.path.join("data", "alien2.png")))
  915. key = surf.get_colorkey()
  916. surf.fill(key)
  917. self.assertEqual(surf.get_at((0, 0)), key)
  918. def test_set_palette(self):
  919. palette = [pygame.Color(i, i, i) for i in range(256)]
  920. palette[10] = tuple(palette[10]) # 4 element tuple
  921. palette[11] = tuple(palette[11])[0:3] # 3 element tuple
  922. surf = pygame.Surface((2, 2), 0, 8)
  923. pygame.display.init()
  924. try:
  925. pygame.display.set_mode((100, 50))
  926. surf.set_palette(palette)
  927. for i in range(256):
  928. self.assertEqual(surf.map_rgb(palette[i]), i,
  929. "palette color %i" % (i,))
  930. c = palette[i]
  931. surf.fill(c)
  932. self.assertEqual(surf.get_at((0, 0)), c,
  933. "palette color %i" % (i,))
  934. for i in range(10):
  935. palette[i] = pygame.Color(255 - i, 0, 0)
  936. surf.set_palette(palette[0:10])
  937. for i in range(256):
  938. self.assertEqual(surf.map_rgb(palette[i]), i,
  939. "palette color %i" % (i,))
  940. c = palette[i]
  941. surf.fill(c)
  942. self.assertEqual(surf.get_at((0, 0)), c,
  943. "palette color %i" % (i,))
  944. self.assertRaises(ValueError, surf.set_palette,
  945. [Color(1, 2, 3, 254)])
  946. self.assertRaises(ValueError, surf.set_palette,
  947. (1, 2, 3, 254))
  948. finally:
  949. pygame.display.quit()
  950. def test_set_palette__fail(self):
  951. pygame.init()
  952. palette = 256 * [(10, 20, 30)]
  953. surf = pygame.Surface((2, 2), 0, 32)
  954. self.assertRaises(pygame.error, surf.set_palette, palette)
  955. pygame.quit()
  956. def test_set_palette_at(self):
  957. pygame.display.init()
  958. try:
  959. pygame.display.set_mode((100, 50))
  960. surf = pygame.Surface((2, 2), 0, 8)
  961. original = surf.get_palette_at(10)
  962. replacement = Color(1, 1, 1, 255)
  963. if replacement == original:
  964. replacement = Color(2, 2, 2, 255)
  965. surf.set_palette_at(10, replacement)
  966. self.assertEqual(surf.get_palette_at(10), replacement)
  967. next = tuple(original)
  968. surf.set_palette_at(10, next)
  969. self.assertEqual(surf.get_palette_at(10), next)
  970. next = tuple(original)[0:3]
  971. surf.set_palette_at(10, next)
  972. self.assertEqual(surf.get_palette_at(10), next)
  973. self.assertRaises(IndexError,
  974. surf.set_palette_at,
  975. 256, replacement)
  976. self.assertRaises(IndexError,
  977. surf.set_palette_at,
  978. -1, replacement)
  979. finally:
  980. pygame.display.quit()
  981. def test_subsurface(self):
  982. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.subsurface:
  983. # Surface.subsurface(Rect): return Surface
  984. # create a new surface that references its parent
  985. #
  986. # Returns a new Surface that shares its pixels with its new parent.
  987. # The new Surface is considered a child of the original. Modifications
  988. # to either Surface pixels will effect each other. Surface information
  989. # like clipping area and color keys are unique to each Surface.
  990. #
  991. # The new Surface will inherit the palette, color key, and alpha
  992. # settings from its parent.
  993. #
  994. # It is possible to have any number of subsurfaces and subsubsurfaces
  995. # on the parent. It is also possible to subsurface the display Surface
  996. # if the display mode is not hardware accelerated.
  997. #
  998. # See the Surface.get_offset(), Surface.get_parent() to learn more
  999. # about the state of a subsurface.
  1000. #
  1001. surf = pygame.Surface((16, 16))
  1002. s = surf.subsurface(0,0,1,1)
  1003. s = surf.subsurface((0,0,1,1))
  1004. #s = surf.subsurface((0,0,1,1), 1)
  1005. # This form is not acceptable.
  1006. #s = surf.subsurface(0,0,10,10, 1)
  1007. self.assertRaises(ValueError, surf.subsurface, (0,0,1,1,666))
  1008. self.assertEqual(s.get_shifts(), surf.get_shifts())
  1009. self.assertEqual(s.get_masks(), surf.get_masks())
  1010. self.assertEqual(s.get_losses(), surf.get_losses())
  1011. # Issue 2 at Bitbucket.org/pygame/pygame
  1012. surf = pygame.Surface.__new__(pygame.Surface)
  1013. self.assertRaises(pygame.error, surf.subsurface, (0, 0, 0, 0))
  1014. def todo_test_unlock(self):
  1015. # __doc__ (as of 2008-08-02) for pygame.surface.Surface.unlock:
  1016. # Surface.unlock(): return None
  1017. # unlock the Surface memory from pixel access
  1018. #
  1019. # Unlock the Surface pixel data after it has been locked. The unlocked
  1020. # Surface can once again be drawn and managed by Pygame. See the
  1021. # Surface.lock() documentation for more details.
  1022. #
  1023. # All pygame functions will automatically lock and unlock the Surface
  1024. # data as needed. If a section of code is going to make calls that
  1025. # will repeatedly lock and unlock the Surface many times, it can be
  1026. # helpful to wrap the block inside a lock and unlock pair.
  1027. #
  1028. # It is safe to nest locking and unlocking calls. The surface will
  1029. # only be unlocked after the final lock is released.
  1030. #
  1031. self.fail()
  1032. def test_unmap_rgb(self):
  1033. # Special case, 8 bit-per-pixel surface (has a palette).
  1034. surf = pygame.Surface((2, 2), 0, 8)
  1035. c = (1, 1, 1) # Unlikely to be in a default palette.
  1036. i = 67
  1037. pygame.display.init()
  1038. try:
  1039. pygame.display.set_mode((100, 50))
  1040. surf.set_palette_at(i, c)
  1041. unmapped_c = surf.unmap_rgb(i)
  1042. self.assertEqual(unmapped_c, c)
  1043. # Confirm it is a Color instance
  1044. self.assertIsInstance(unmapped_c, pygame.Color)
  1045. finally:
  1046. pygame.display.quit()
  1047. # Remaining, non-pallete, cases.
  1048. c = (128, 64, 12, 255)
  1049. formats = [(0, 16), (0, 24), (0, 32),
  1050. (SRCALPHA, 16), (SRCALPHA, 32)]
  1051. for flags, bitsize in formats:
  1052. surf = pygame.Surface((2, 2), flags, bitsize)
  1053. unmapped_c = surf.unmap_rgb(surf.map_rgb(c))
  1054. surf.fill(c)
  1055. comparison_c = surf.get_at((0, 0))
  1056. self.assertEqual(unmapped_c, comparison_c,
  1057. "%s != %s, flags: %i, bitsize: %i" %
  1058. (unmapped_c, comparison_c, flags, bitsize))
  1059. # Confirm it is a Color instance
  1060. self.assertIsInstance(unmapped_c, pygame.Color)
  1061. def test_scroll(self):
  1062. scrolls = [(8, 2, 3),
  1063. (16, 2, 3),
  1064. (24, 2, 3),
  1065. (32, 2, 3),
  1066. (32, -1, -3),
  1067. (32, 0, 0),
  1068. (32, 11, 0),
  1069. (32, 0, 11),
  1070. (32, -11, 0),
  1071. (32, 0, -11),
  1072. (32, -11, 2),
  1073. (32, 2, -11)]
  1074. for bitsize, dx, dy in scrolls:
  1075. surf = pygame.Surface((10, 10), 0, bitsize)
  1076. surf.fill((255, 0, 0))
  1077. surf.fill((0, 255, 0), (2, 2, 2, 2,))
  1078. comp = surf.copy()
  1079. comp.blit(surf, (dx, dy))
  1080. surf.scroll(dx, dy)
  1081. w, h = surf.get_size()
  1082. for x in range(w):
  1083. for y in range(h):
  1084. self.assertEqual(surf.get_at((x, y)),
  1085. comp.get_at((x, y)),
  1086. "%s != %s, bpp:, %i, x: %i, y: %i" %
  1087. (surf.get_at((x, y)),
  1088. comp.get_at((x, y)),
  1089. bitsize, dx, dy))
  1090. # Confirm clip rect containment
  1091. surf = pygame.Surface((20, 13), 0, 32)
  1092. surf.fill((255, 0, 0))
  1093. surf.fill((0, 255, 0), (7, 1, 6, 6))
  1094. comp = surf.copy()
  1095. clip = Rect(3, 1, 8, 14)
  1096. surf.set_clip(clip)
  1097. comp.set_clip(clip)
  1098. comp.blit(surf, (clip.x + 2, clip.y + 3), surf.get_clip())
  1099. surf.scroll(2, 3)
  1100. w, h = surf.get_size()
  1101. for x in range(w):
  1102. for y in range(h):
  1103. self.assertEqual(surf.get_at((x, y)),
  1104. comp.get_at((x, y)))
  1105. # Confirm keyword arguments and per-pixel alpha
  1106. spot_color = (0, 255, 0, 128)
  1107. surf = pygame.Surface((4, 4), pygame.SRCALPHA, 32)
  1108. surf.fill((255, 0, 0, 255))
  1109. surf.set_at((1, 1), spot_color)
  1110. surf.scroll(dx=1)
  1111. self.assertEqual(surf.get_at((2, 1)), spot_color)
  1112. surf.scroll(dy=1)
  1113. self.assertEqual(surf.get_at((2, 2)), spot_color)
  1114. surf.scroll(dy=1, dx=1)
  1115. self.assertEqual(surf.get_at((3, 3)), spot_color)
  1116. surf.scroll(dx=-3, dy=-3)
  1117. self.assertEqual(surf.get_at((0, 0)), spot_color)
  1118. class SurfaceSubtypeTest(unittest.TestCase):
  1119. """Issue #280: Methods that return a new Surface preserve subclasses"""
  1120. def setUp(self):
  1121. pygame.display.init()
  1122. def tearDown(self):
  1123. pygame.display.quit()
  1124. def test_copy(self):
  1125. """Ensure method copy() preserves the surface's class
  1126. When Surface is subclassed, the inherited copy() method will return
  1127. instances of the subclass. Non Surface fields are uncopied, however.
  1128. This includes instance attributes.
  1129. """
  1130. expected_size = (32, 32)
  1131. ms1 = SurfaceSubclass(expected_size, SRCALPHA, 32)
  1132. ms2 = ms1.copy()
  1133. self.assertIsNot(ms1, ms2)
  1134. self.assertIsInstance(ms1, pygame.Surface)
  1135. self.assertIsInstance(ms2, pygame.Surface)
  1136. self.assertIsInstance(ms1, SurfaceSubclass)
  1137. self.assertIsInstance(ms2, SurfaceSubclass)
  1138. self.assertTrue(ms1.test_attribute)
  1139. self.assertRaises(AttributeError, getattr, ms2, "test_attribute")
  1140. self.assertEqual(ms2.get_size(), expected_size)
  1141. def test_convert(self):
  1142. """Ensure method convert() preserves the surface's class
  1143. When Surface is subclassed, the inherited convert() method will return
  1144. instances of the subclass. Non Surface fields are omitted, however.
  1145. This includes instance attributes.
  1146. """
  1147. expected_size = (32, 32)
  1148. ms1 = SurfaceSubclass(expected_size, 0, 24)
  1149. ms2 = ms1.convert(24)
  1150. self.assertIsNot(ms1, ms2)
  1151. self.assertIsInstance(ms1, pygame.Surface)
  1152. self.assertIsInstance(ms2, pygame.Surface)
  1153. self.assertIsInstance(ms1, SurfaceSubclass)
  1154. self.assertIsInstance(ms2, SurfaceSubclass)
  1155. self.assertTrue(ms1.test_attribute)
  1156. self.assertRaises(AttributeError, getattr, ms2, "test_attribute")
  1157. self.assertEqual(ms2.get_size(), expected_size)
  1158. def test_convert_alpha(self):
  1159. """Ensure method convert_alpha() preserves the surface's class
  1160. When Surface is subclassed, the inherited convert_alpha() method will
  1161. return instances of the subclass. Non Surface fields are omitted,
  1162. however. This includes instance attributes.
  1163. """
  1164. pygame.display.set_mode((40, 40))
  1165. expected_size = (32, 32)
  1166. s = pygame.Surface(expected_size, SRCALPHA, 16)
  1167. ms1 = SurfaceSubclass(expected_size, SRCALPHA, 32)
  1168. ms2 = ms1.convert_alpha(s)
  1169. self.assertIsNot(ms1, ms2)
  1170. self.assertIsInstance(ms1, pygame.Surface)
  1171. self.assertIsInstance(ms2, pygame.Surface)
  1172. self.assertIsInstance(ms1, SurfaceSubclass)
  1173. self.assertIsInstance(ms2, SurfaceSubclass)
  1174. self.assertTrue(ms1.test_attribute)
  1175. self.assertRaises(AttributeError, getattr, ms2, "test_attribute")
  1176. self.assertEqual(ms2.get_size(), expected_size)
  1177. def test_subsurface(self):
  1178. """Ensure method subsurface() preserves the surface's class
  1179. When Surface is subclassed, the inherited subsurface() method will
  1180. return instances of the subclass. Non Surface fields are uncopied,
  1181. however. This includes instance attributes.
  1182. """
  1183. expected_size = (10, 12)
  1184. ms1 = SurfaceSubclass((32, 32), SRCALPHA, 32)
  1185. ms2 = ms1.subsurface((4, 5), expected_size)
  1186. self.assertIsNot(ms1, ms2)
  1187. self.assertIsInstance(ms1, pygame.Surface)
  1188. self.assertIsInstance(ms2, pygame.Surface)
  1189. self.assertIsInstance(ms1, SurfaceSubclass)
  1190. self.assertIsInstance(ms2, SurfaceSubclass)
  1191. self.assertTrue(ms1.test_attribute)
  1192. self.assertRaises(AttributeError, getattr, ms2, "test_attribute")
  1193. self.assertEqual(ms2.get_size(), expected_size)
  1194. class SurfaceGetBufferTest(unittest.TestCase):
  1195. # These tests requires ctypes. They are disabled if ctypes
  1196. # is not installed.
  1197. #
  1198. try:
  1199. ArrayInterface
  1200. except NameError:
  1201. __tags__ = ('ignore', 'subprocess_ignore')
  1202. lilendian = pygame.get_sdl_byteorder() == pygame.LIL_ENDIAN
  1203. def _check_interface_2D(self, s):
  1204. s_w, s_h = s.get_size()
  1205. s_bytesize = s.get_bytesize();
  1206. s_pitch = s.get_pitch()
  1207. s_pixels = s._pixels_address
  1208. # check the array interface structure fields.
  1209. v = s.get_view('2')
  1210. if not IS_PYPY:
  1211. flags = PAI_ALIGNED | PAI_NOTSWAPPED | PAI_WRITEABLE
  1212. if (s.get_pitch() == s_w * s_bytesize):
  1213. flags |= PAI_FORTRAN
  1214. inter = ArrayInterface(v)
  1215. self.assertEqual(inter.two, 2)
  1216. self.assertEqual(inter.nd, 2)
  1217. self.assertEqual(inter.typekind, 'u')
  1218. self.assertEqual(inter.itemsize, s_bytesize)
  1219. self.assertEqual(inter.shape[0], s_w)
  1220. self.assertEqual(inter.shape[1], s_h)
  1221. self.assertEqual(inter.strides[0], s_bytesize)
  1222. self.assertEqual(inter.strides[1], s_pitch)
  1223. self.assertEqual(inter.flags, flags)
  1224. self.assertEqual(inter.data, s_pixels);
  1225. def _check_interface_3D(self, s):
  1226. s_w, s_h = s.get_size()
  1227. s_bytesize = s.get_bytesize();
  1228. s_pitch = s.get_pitch()
  1229. s_pixels = s._pixels_address
  1230. s_shifts = list(s.get_shifts())
  1231. # Check for RGB or BGR surface.
  1232. if s_shifts[0:3] == [0, 8, 16]:
  1233. if self.lilendian:
  1234. # RGB
  1235. offset = 0
  1236. step = 1
  1237. else:
  1238. # BGR
  1239. offset = s_bytesize - 1
  1240. step = -1
  1241. elif s_shifts[0:3] == [8, 16, 24]:
  1242. if self.lilendian:
  1243. # xRGB
  1244. offset = 1
  1245. step = 1
  1246. else:
  1247. # BGRx
  1248. offset = s_bytesize - 2
  1249. step = -1
  1250. elif s_shifts[0:3] == [16, 8, 0]:
  1251. if self.lilendian:
  1252. # BGR
  1253. offset = 2
  1254. step = -1
  1255. else:
  1256. # RGB
  1257. offset = s_bytesize - 3
  1258. step = 1
  1259. elif s_shifts[0:3] == [24, 16, 8]:
  1260. if self.lilendian:
  1261. # BGRx
  1262. offset = 2
  1263. step = -1
  1264. else:
  1265. # RGBx
  1266. offset = s_bytesize - 4
  1267. step = -1
  1268. else:
  1269. return
  1270. # check the array interface structure fields.
  1271. v = s.get_view('3')
  1272. if not IS_PYPY:
  1273. inter = ArrayInterface(v)
  1274. flags = PAI_ALIGNED | PAI_NOTSWAPPED | PAI_WRITEABLE
  1275. self.assertEqual(inter.two, 2)
  1276. self.assertEqual(inter.nd, 3)
  1277. self.assertEqual(inter.typekind, 'u')
  1278. self.assertEqual(inter.itemsize, 1)
  1279. self.assertEqual(inter.shape[0], s_w)
  1280. self.assertEqual(inter.shape[1], s_h)
  1281. self.assertEqual(inter.shape[2], 3)
  1282. self.assertEqual(inter.strides[0], s_bytesize)
  1283. self.assertEqual(inter.strides[1], s_pitch)
  1284. self.assertEqual(inter.strides[2], step)
  1285. self.assertEqual(inter.flags, flags)
  1286. self.assertEqual(inter.data, s_pixels + offset);
  1287. def _check_interface_rgba(self, s, plane):
  1288. s_w, s_h = s.get_size()
  1289. s_bytesize = s.get_bytesize();
  1290. s_pitch = s.get_pitch()
  1291. s_pixels = s._pixels_address
  1292. s_shifts = s.get_shifts()
  1293. s_masks = s.get_masks()
  1294. # Find the color plane position within the pixel.
  1295. if not s_masks[plane]:
  1296. return
  1297. alpha_shift = s_shifts[plane]
  1298. offset = alpha_shift // 8
  1299. if not self.lilendian:
  1300. offset = s_bytesize - offset - 1
  1301. # check the array interface structure fields.
  1302. v = s.get_view('rgba'[plane])
  1303. if not IS_PYPY:
  1304. inter = ArrayInterface(v)
  1305. flags = PAI_ALIGNED | PAI_NOTSWAPPED | PAI_WRITEABLE
  1306. self.assertEqual(inter.two, 2)
  1307. self.assertEqual(inter.nd, 2)
  1308. self.assertEqual(inter.typekind, 'u')
  1309. self.assertEqual(inter.itemsize, 1)
  1310. self.assertEqual(inter.shape[0], s_w)
  1311. self.assertEqual(inter.shape[1], s_h)
  1312. self.assertEqual(inter.strides[0], s_bytesize)
  1313. self.assertEqual(inter.strides[1], s_pitch)
  1314. self.assertEqual(inter.flags, flags)
  1315. self.assertEqual(inter.data, s_pixels + offset);
  1316. def test_array_interface(self):
  1317. self._check_interface_2D(pygame.Surface((5, 7), 0, 8))
  1318. self._check_interface_2D(pygame.Surface((5, 7), 0, 16))
  1319. self._check_interface_2D(pygame.Surface((5, 7), pygame.SRCALPHA, 16))
  1320. self._check_interface_3D(pygame.Surface((5, 7), 0, 24))
  1321. self._check_interface_3D(pygame.Surface((8, 4), 0, 24)) # No gaps
  1322. self._check_interface_2D(pygame.Surface((5, 7), 0, 32))
  1323. self._check_interface_3D(pygame.Surface((5, 7), 0, 32))
  1324. self._check_interface_2D(pygame.Surface((5, 7), pygame.SRCALPHA, 32))
  1325. self._check_interface_3D(pygame.Surface((5, 7), pygame.SRCALPHA, 32))
  1326. def test_array_interface_masks(self):
  1327. """Test non-default color byte orders on 3D views"""
  1328. sz = (5, 7)
  1329. # Reversed RGB byte order
  1330. s = pygame.Surface(sz, 0, 32)
  1331. s_masks = list(s.get_masks())
  1332. masks = [0xff, 0xff00, 0xff0000]
  1333. if s_masks[0:3] == masks or s_masks[0:3] == masks[::-1]:
  1334. masks = s_masks[2::-1] + s_masks[3:4]
  1335. self._check_interface_3D(pygame.Surface(sz, 0, 32, masks))
  1336. s = pygame.Surface(sz, 0, 24)
  1337. s_masks = list(s.get_masks())
  1338. masks = [0xff, 0xff00, 0xff0000]
  1339. if s_masks[0:3] == masks or s_masks[0:3] == masks[::-1]:
  1340. masks = s_masks[2::-1] + s_masks[3:4]
  1341. self._check_interface_3D(pygame.Surface(sz, 0, 24, masks))
  1342. masks = [0xff00, 0xff0000, 0xff000000, 0]
  1343. self._check_interface_3D(pygame.Surface(sz, 0, 32, masks))
  1344. # Unsupported RGB byte orders
  1345. if pygame.get_sdl_version()[0] == 1:
  1346. # Invalid mask values with SDL2
  1347. masks = [0xff00, 0xff, 0xff0000, 0]
  1348. self.assertRaises(ValueError,
  1349. pygame.Surface(sz, 0, 24, masks).get_view, '3')
  1350. def test_array_interface_alpha(self):
  1351. for shifts in [[0, 8, 16, 24], [8, 16, 24, 0],
  1352. [24, 16, 8, 0], [16, 8, 0, 24]]:
  1353. masks = [0xff << s for s in shifts]
  1354. s = pygame.Surface((4, 2), pygame.SRCALPHA, 32, masks)
  1355. self._check_interface_rgba(s, 3)
  1356. def test_array_interface_rgb(self):
  1357. for shifts in [[0, 8, 16, 24], [8, 16, 24, 0],
  1358. [24, 16, 8, 0], [16, 8, 0, 24]]:
  1359. masks = [0xff << s for s in shifts]
  1360. masks[3] = 0
  1361. for plane in range(3):
  1362. s = pygame.Surface((4, 2), 0, 24)
  1363. self._check_interface_rgba(s, plane)
  1364. s = pygame.Surface((4, 2), 0, 32)
  1365. self._check_interface_rgba(s, plane)
  1366. @unittest.skipIf(not pygame.HAVE_NEWBUF, 'newbuf not implemented')
  1367. def test_newbuf_PyBUF_flags_bytes(self):
  1368. from pygame.tests.test_utils import buftools
  1369. Importer = buftools.Importer
  1370. s = pygame.Surface((10, 6), 0, 32)
  1371. a = s.get_buffer()
  1372. b = Importer(a, buftools.PyBUF_SIMPLE)
  1373. self.assertEqual(b.ndim, 0)
  1374. self.assertTrue(b.format is None)
  1375. self.assertEqual(b.len, a.length)
  1376. self.assertEqual(b.itemsize, 1)
  1377. self.assertTrue(b.shape is None)
  1378. self.assertTrue(b.strides is None)
  1379. self.assertTrue(b.suboffsets is None)
  1380. self.assertFalse(b.readonly)
  1381. self.assertEqual(b.buf, s._pixels_address)
  1382. b = Importer(a, buftools.PyBUF_WRITABLE)
  1383. self.assertEqual(b.ndim, 0)
  1384. self.assertTrue(b.format is None)
  1385. self.assertFalse(b.readonly)
  1386. b = Importer(a, buftools.PyBUF_FORMAT)
  1387. self.assertEqual(b.ndim, 0)
  1388. self.assertEqual(b.format, 'B')
  1389. b = Importer(a, buftools.PyBUF_ND)
  1390. self.assertEqual(b.ndim, 1)
  1391. self.assertTrue(b.format is None)
  1392. self.assertEqual(b.len, a.length)
  1393. self.assertEqual(b.itemsize, 1)
  1394. self.assertEqual(b.shape, (a.length,))
  1395. self.assertTrue(b.strides is None)
  1396. self.assertTrue(b.suboffsets is None)
  1397. self.assertFalse(b.readonly)
  1398. self.assertEqual(b.buf, s._pixels_address)
  1399. b = Importer(a, buftools.PyBUF_STRIDES)
  1400. self.assertEqual(b.ndim, 1)
  1401. self.assertTrue(b.format is None)
  1402. self.assertEqual(b.strides, (1,))
  1403. s2 = s.subsurface((1, 1, 7, 4)) # Not contiguous
  1404. a = s2.get_buffer()
  1405. b = Importer(a, buftools.PyBUF_SIMPLE)
  1406. self.assertEqual(b.ndim, 0)
  1407. self.assertTrue(b.format is None)
  1408. self.assertEqual(b.len, a.length)
  1409. self.assertEqual(b.itemsize, 1)
  1410. self.assertTrue(b.shape is None)
  1411. self.assertTrue(b.strides is None)
  1412. self.assertTrue(b.suboffsets is None)
  1413. self.assertFalse(b.readonly)
  1414. self.assertEqual(b.buf, s2._pixels_address)
  1415. b = Importer(a, buftools.PyBUF_C_CONTIGUOUS)
  1416. self.assertEqual(b.ndim, 1)
  1417. self.assertEqual(b.strides, (1,))
  1418. b = Importer(a, buftools.PyBUF_F_CONTIGUOUS)
  1419. self.assertEqual(b.ndim, 1)
  1420. self.assertEqual(b.strides, (1,))
  1421. b = Importer(a, buftools.PyBUF_ANY_CONTIGUOUS)
  1422. self.assertEqual(b.ndim, 1)
  1423. self.assertEqual(b.strides, (1,))
  1424. @unittest.skipIf(not pygame.HAVE_NEWBUF, 'newbuf not implemented')
  1425. def test_newbuf_PyBUF_flags_0D(self):
  1426. # This is the same handler as used by get_buffer(), so just
  1427. # confirm that it succeeds for one case.
  1428. from pygame.tests.test_utils import buftools
  1429. Importer = buftools.Importer
  1430. s = pygame.Surface((10, 6), 0, 32)
  1431. a = s.get_view('0')
  1432. b = Importer(a, buftools.PyBUF_SIMPLE)
  1433. self.assertEqual(b.ndim, 0)
  1434. self.assertTrue(b.format is None)
  1435. self.assertEqual(b.len, a.length)
  1436. self.assertEqual(b.itemsize, 1)
  1437. self.assertTrue(b.shape is None)
  1438. self.assertTrue(b.strides is None)
  1439. self.assertTrue(b.suboffsets is None)
  1440. self.assertFalse(b.readonly)
  1441. self.assertEqual(b.buf, s._pixels_address)
  1442. @unittest.skipIf(not pygame.HAVE_NEWBUF, 'newbuf not implemented')
  1443. def test_newbuf_PyBUF_flags_1D(self):
  1444. from pygame.tests.test_utils import buftools
  1445. Importer = buftools.Importer
  1446. s = pygame.Surface((10, 6), 0, 32)
  1447. a = s.get_view('1')
  1448. b = Importer(a, buftools.PyBUF_SIMPLE)
  1449. self.assertEqual(b.ndim, 0)
  1450. self.assertTrue(b.format is None)
  1451. self.assertEqual(b.len, a.length)
  1452. self.assertEqual(b.itemsize, s.get_bytesize())
  1453. self.assertTrue(b.shape is None)
  1454. self.assertTrue(b.strides is None)
  1455. self.assertTrue(b.suboffsets is None)
  1456. self.assertFalse(b.readonly)
  1457. self.assertEqual(b.buf, s._pixels_address)
  1458. b = Importer(a, buftools.PyBUF_WRITABLE)
  1459. self.assertEqual(b.ndim, 0)
  1460. self.assertTrue(b.format is None)
  1461. self.assertFalse(b.readonly)
  1462. b = Importer(a, buftools.PyBUF_FORMAT)
  1463. self.assertEqual(b.ndim, 0)
  1464. self.assertEqual(b.format, '=I')
  1465. b = Importer(a, buftools.PyBUF_ND)
  1466. self.assertEqual(b.ndim, 1)
  1467. self.assertTrue(b.format is None)
  1468. self.assertEqual(b.len, a.length)
  1469. self.assertEqual(b.itemsize, s.get_bytesize())
  1470. self.assertEqual(b.shape, (s.get_width() * s.get_height(),))
  1471. self.assertTrue(b.strides is None)
  1472. self.assertTrue(b.suboffsets is None)
  1473. self.assertFalse(b.readonly)
  1474. self.assertEqual(b.buf, s._pixels_address)
  1475. b = Importer(a, buftools.PyBUF_STRIDES)
  1476. self.assertEqual(b.ndim, 1)
  1477. self.assertTrue(b.format is None)
  1478. self.assertEqual(b.strides, (s.get_bytesize(),))
  1479. @unittest.skipIf(not pygame.HAVE_NEWBUF, 'newbuf not implemented')
  1480. def test_newbuf_PyBUF_flags_2D(self):
  1481. from pygame.tests.test_utils import buftools
  1482. Importer = buftools.Importer
  1483. s = pygame.Surface((10, 6), 0, 32)
  1484. a = s.get_view('2')
  1485. # Non dimensional requests, no PyDEF_ND, are handled by the
  1486. # 1D surface buffer code, so only need to confirm a success.
  1487. b = Importer(a, buftools.PyBUF_SIMPLE)
  1488. self.assertEqual(b.ndim, 0)
  1489. self.assertTrue(b.format is None)
  1490. self.assertEqual(b.len, a.length)
  1491. self.assertEqual(b.itemsize, s.get_bytesize())
  1492. self.assertTrue(b.shape is None)
  1493. self.assertTrue(b.strides is None)
  1494. self.assertTrue(b.suboffsets is None)
  1495. self.assertFalse(b.readonly)
  1496. self.assertEqual(b.buf, s._pixels_address)
  1497. # Uniquely 2D
  1498. b = Importer(a, buftools.PyBUF_STRIDES)
  1499. self.assertEqual(b.ndim, 2)
  1500. self.assertTrue(b.format is None)
  1501. self.assertEqual(b.len, a.length)
  1502. self.assertEqual(b.itemsize, s.get_bytesize())
  1503. self.assertEqual(b.shape, s.get_size())
  1504. self.assertEqual(b.strides, (s.get_bytesize(), s.get_pitch()))
  1505. self.assertTrue(b.suboffsets is None)
  1506. self.assertFalse(b.readonly)
  1507. self.assertEqual(b.buf, s._pixels_address)
  1508. b = Importer(a, buftools.PyBUF_RECORDS_RO)
  1509. self.assertEqual(b.ndim, 2)
  1510. self.assertEqual(b.format, '=I')
  1511. self.assertEqual(b.strides, (s.get_bytesize(), s.get_pitch()))
  1512. b = Importer(a, buftools.PyBUF_RECORDS)
  1513. self.assertEqual(b.ndim, 2)
  1514. self.assertEqual(b.format, '=I')
  1515. self.assertEqual(b.strides, (s.get_bytesize(), s.get_pitch()))
  1516. b = Importer(a, buftools.PyBUF_F_CONTIGUOUS)
  1517. self.assertEqual(b.ndim, 2)
  1518. self.assertEqual(b.format, None)
  1519. self.assertEqual(b.strides, (s.get_bytesize(), s.get_pitch()))
  1520. b = Importer(a, buftools.PyBUF_ANY_CONTIGUOUS)
  1521. self.assertEqual(b.ndim, 2)
  1522. self.assertEqual(b.format, None)
  1523. self.assertEqual(b.strides, (s.get_bytesize(), s.get_pitch()))
  1524. self.assertRaises(BufferError, Importer, a, buftools.PyBUF_ND)
  1525. self.assertRaises(BufferError, Importer, a,
  1526. buftools.PyBUF_C_CONTIGUOUS)
  1527. s2 = s.subsurface((1, 1, 7, 4)) # Not contiguous
  1528. a = s2.get_view('2')
  1529. b = Importer(a, buftools.PyBUF_STRIDES)
  1530. self.assertEqual(b.ndim, 2)
  1531. self.assertTrue(b.format is None)
  1532. self.assertEqual(b.len, a.length)
  1533. self.assertEqual(b.itemsize, s2.get_bytesize())
  1534. self.assertEqual(b.shape, s2.get_size())
  1535. self.assertEqual(b.strides, (s2.get_bytesize(), s.get_pitch()))
  1536. self.assertTrue(b.suboffsets is None)
  1537. self.assertFalse(b.readonly)
  1538. self.assertEqual(b.buf, s2._pixels_address)
  1539. b = Importer(a, buftools.PyBUF_RECORDS)
  1540. self.assertEqual(b.ndim, 2)
  1541. self.assertEqual(b.format, '=I')
  1542. self.assertRaises(BufferError, Importer, a, buftools.PyBUF_SIMPLE)
  1543. self.assertRaises(BufferError, Importer, a, buftools.PyBUF_FORMAT)
  1544. self.assertRaises(BufferError, Importer, a,
  1545. buftools.PyBUF_WRITABLE)
  1546. self.assertRaises(BufferError, Importer, a, buftools.PyBUF_ND)
  1547. self.assertRaises(BufferError, Importer, a,
  1548. buftools.PyBUF_C_CONTIGUOUS)
  1549. self.assertRaises(BufferError, Importer, a,
  1550. buftools.PyBUF_F_CONTIGUOUS)
  1551. self.assertRaises(BufferError, Importer, a,
  1552. buftools.PyBUF_ANY_CONTIGUOUS)
  1553. @unittest.skipIf(not pygame.HAVE_NEWBUF, 'newbuf not implemented')
  1554. def test_newbuf_PyBUF_flags_3D(self):
  1555. from pygame.tests.test_utils import buftools
  1556. Importer = buftools.Importer
  1557. s = pygame.Surface((12, 6), 0, 24)
  1558. rmask, gmask, bmask, amask = s.get_masks()
  1559. if self.lilendian:
  1560. if rmask == 0x0000ff:
  1561. color_step = 1
  1562. addr_offset = 0
  1563. else:
  1564. color_step = -1
  1565. addr_offset = 2
  1566. else:
  1567. if (rmask == 0xff0000):
  1568. color_step = 1
  1569. addr_offset = 0
  1570. else:
  1571. color_step = -1
  1572. addr_offset = 2
  1573. a = s.get_view('3')
  1574. b = Importer(a, buftools.PyBUF_STRIDES)
  1575. w, h = s.get_size()
  1576. shape = w, h, 3
  1577. strides = 3, s.get_pitch(), color_step
  1578. self.assertEqual(b.ndim, 3)
  1579. self.assertTrue(b.format is None)
  1580. self.assertEqual(b.len, a.length)
  1581. self.assertEqual(b.itemsize, 1)
  1582. self.assertEqual(b.shape, shape)
  1583. self.assertEqual(b.strides, strides)
  1584. self.assertTrue(b.suboffsets is None)
  1585. self.assertFalse(b.readonly)
  1586. self.assertEqual(b.buf, s._pixels_address + addr_offset)
  1587. b = Importer(a, buftools.PyBUF_RECORDS_RO)
  1588. self.assertEqual(b.ndim, 3)
  1589. self.assertEqual(b.format, 'B')
  1590. self.assertEqual(b.strides, strides)
  1591. b = Importer(a, buftools.PyBUF_RECORDS)
  1592. self.assertEqual(b.ndim, 3)
  1593. self.assertEqual(b.format, 'B')
  1594. self.assertEqual(b.strides, strides)
  1595. self.assertRaises(BufferError, Importer, a, buftools.PyBUF_SIMPLE)
  1596. self.assertRaises(BufferError, Importer, a, buftools.PyBUF_FORMAT)
  1597. self.assertRaises(BufferError, Importer, a, buftools.PyBUF_WRITABLE)
  1598. self.assertRaises(BufferError, Importer, a, buftools.PyBUF_ND)
  1599. self.assertRaises(BufferError, Importer, a,
  1600. buftools.PyBUF_C_CONTIGUOUS)
  1601. self.assertRaises(BufferError, Importer, a,
  1602. buftools.PyBUF_F_CONTIGUOUS)
  1603. self.assertRaises(BufferError, Importer, a,
  1604. buftools.PyBUF_ANY_CONTIGUOUS)
  1605. @unittest.skipIf(not pygame.HAVE_NEWBUF, 'newbuf not implemented')
  1606. def test_newbuf_PyBUF_flags_rgba(self):
  1607. # All color plane views are handled by the same routine,
  1608. # so only one plane need be checked.
  1609. from pygame.tests.test_utils import buftools
  1610. Importer = buftools.Importer
  1611. s = pygame.Surface((12, 6), 0, 24)
  1612. rmask, gmask, bmask, amask = s.get_masks()
  1613. if self.lilendian:
  1614. if rmask == 0x0000ff:
  1615. addr_offset = 0
  1616. else:
  1617. addr_offset = 2
  1618. else:
  1619. if rmask == 0xff0000:
  1620. addr_offset = 0
  1621. else:
  1622. addr_offset = 2
  1623. a = s.get_view('R')
  1624. b = Importer(a, buftools.PyBUF_STRIDES)
  1625. w, h = s.get_size()
  1626. shape = w, h
  1627. strides = s.get_bytesize(), s.get_pitch()
  1628. self.assertEqual(b.ndim, 2)
  1629. self.assertTrue(b.format is None)
  1630. self.assertEqual(b.len, a.length)
  1631. self.assertEqual(b.itemsize, 1)
  1632. self.assertEqual(b.shape, shape)
  1633. self.assertEqual(b.strides, strides)
  1634. self.assertTrue(b.suboffsets is None)
  1635. self.assertFalse(b.readonly)
  1636. self.assertEqual(b.buf, s._pixels_address + addr_offset)
  1637. b = Importer(a, buftools.PyBUF_RECORDS_RO)
  1638. self.assertEqual(b.ndim, 2)
  1639. self.assertEqual(b.format, 'B')
  1640. self.assertEqual(b.strides, strides)
  1641. b = Importer(a, buftools.PyBUF_RECORDS)
  1642. self.assertEqual(b.ndim, 2)
  1643. self.assertEqual(b.format, 'B')
  1644. self.assertEqual(b.strides, strides)
  1645. self.assertRaises(BufferError, Importer, a, buftools.PyBUF_SIMPLE)
  1646. self.assertRaises(BufferError, Importer, a, buftools.PyBUF_FORMAT)
  1647. self.assertRaises(BufferError, Importer, a, buftools.PyBUF_WRITABLE)
  1648. self.assertRaises(BufferError, Importer, a, buftools.PyBUF_ND)
  1649. self.assertRaises(BufferError, Importer, a,
  1650. buftools.PyBUF_C_CONTIGUOUS)
  1651. self.assertRaises(BufferError, Importer, a,
  1652. buftools.PyBUF_F_CONTIGUOUS)
  1653. self.assertRaises(BufferError, Importer, a,
  1654. buftools.PyBUF_ANY_CONTIGUOUS)
  1655. class SurfaceBlendTest(unittest.TestCase):
  1656. def setUp(self):
  1657. # Needed for 8 bits-per-pixel color palette surface tests.
  1658. pygame.display.init()
  1659. def tearDown(self):
  1660. pygame.display.quit()
  1661. _test_palette = [(0, 0, 0, 255),
  1662. (10, 30, 60, 0),
  1663. (25, 75, 100, 128),
  1664. (200, 150, 100, 200),
  1665. (0, 100, 200, 255)]
  1666. surf_size = (10, 12)
  1667. _test_points = [((0, 0), 1), ((4, 5), 1), ((9, 0), 2),
  1668. ((5, 5), 2), ((0, 11), 3), ((4, 6), 3),
  1669. ((9, 11), 4), ((5, 6), 4)]
  1670. def _make_surface(self, bitsize, srcalpha=False, palette=None):
  1671. if palette is None:
  1672. palette = self._test_palette
  1673. flags = 0
  1674. if srcalpha:
  1675. flags |= SRCALPHA
  1676. surf = pygame.Surface(self.surf_size, flags, bitsize)
  1677. if bitsize == 8:
  1678. surf.set_palette([c[:3] for c in palette])
  1679. return surf
  1680. def _fill_surface(self, surf, palette=None):
  1681. if palette is None:
  1682. palette = self._test_palette
  1683. surf.fill(palette[1], (0, 0, 5, 6))
  1684. surf.fill(palette[2], (5, 0, 5, 6))
  1685. surf.fill(palette[3], (0, 6, 5, 6))
  1686. surf.fill(palette[4], (5, 6, 5, 6))
  1687. def _make_src_surface(self, bitsize, srcalpha=False, palette=None):
  1688. surf = self._make_surface(bitsize, srcalpha, palette)
  1689. self._fill_surface(surf, palette)
  1690. return surf
  1691. def _assert_surface(self, surf, palette=None, msg=""):
  1692. if palette is None:
  1693. palette = self._test_palette
  1694. if surf.get_bitsize() == 16:
  1695. palette = [surf.unmap_rgb(surf.map_rgb(c)) for c in palette]
  1696. for posn, i in self._test_points:
  1697. self.assertEqual(surf.get_at(posn), palette[i],
  1698. "%s != %s: flags: %i, bpp: %i, posn: %s%s" %
  1699. (surf.get_at(posn),
  1700. palette[i], surf.get_flags(),
  1701. surf.get_bitsize(), posn, msg))
  1702. def test_blit_blend(self):
  1703. sources = [self._make_src_surface(8),
  1704. self._make_src_surface(16),
  1705. self._make_src_surface(16, srcalpha=True),
  1706. self._make_src_surface(24),
  1707. self._make_src_surface(32),
  1708. self._make_src_surface(32, srcalpha=True)]
  1709. destinations = [self._make_surface(8),
  1710. self._make_surface(16),
  1711. self._make_surface(16, srcalpha=True),
  1712. self._make_surface(24),
  1713. self._make_surface(32),
  1714. self._make_surface(32, srcalpha=True)]
  1715. blend = [('BLEND_ADD', (0, 25, 100, 255),
  1716. lambda a, b: min(a + b, 255)),
  1717. ('BLEND_SUB', (100, 25, 0, 100),
  1718. lambda a, b: max(a - b, 0)),
  1719. ('BLEND_MULT', (100, 200, 0, 0),
  1720. lambda a, b: (a * b) // 256),
  1721. ('BLEND_MIN', (255, 0, 0, 255), min),
  1722. ('BLEND_MAX', (0, 255, 0, 255), max)]
  1723. for src in sources:
  1724. src_palette = [src.unmap_rgb(src.map_rgb(c))
  1725. for c in self._test_palette]
  1726. for dst in destinations:
  1727. for blend_name, dst_color, op in blend:
  1728. dc = dst.unmap_rgb(dst.map_rgb(dst_color))
  1729. p = []
  1730. for sc in src_palette:
  1731. c = [op(dc[i], sc[i]) for i in range(3)]
  1732. if dst.get_masks()[3]:
  1733. c.append(dc[3])
  1734. else:
  1735. c.append(255)
  1736. c = dst.unmap_rgb(dst.map_rgb(c))
  1737. p.append(c)
  1738. dst.fill(dst_color)
  1739. dst.blit(src,
  1740. (0, 0),
  1741. special_flags=getattr(pygame, blend_name))
  1742. self._assert_surface(dst, p,
  1743. (", op: %s, src bpp: %i"
  1744. ", src flags: %i" %
  1745. (blend_name,
  1746. src.get_bitsize(),
  1747. src.get_flags())))
  1748. src = self._make_src_surface(32)
  1749. masks = src.get_masks()
  1750. dst = pygame.Surface(src.get_size(), 0, 32,
  1751. [masks[2], masks[1], masks[0], masks[3]])
  1752. for blend_name, dst_color, op in blend:
  1753. p = []
  1754. for src_color in self._test_palette:
  1755. c = [op(dst_color[i], src_color[i]) for i in range(3)]
  1756. c.append(255)
  1757. p.append(tuple(c))
  1758. dst.fill(dst_color)
  1759. dst.blit(src,
  1760. (0, 0),
  1761. special_flags=getattr(pygame, blend_name))
  1762. self._assert_surface(dst, p, ", %s" % blend_name)
  1763. # Blend blits are special cased for 32 to 32 bit surfaces.
  1764. #
  1765. # Confirm that it works when the rgb bytes are not the
  1766. # least significant bytes.
  1767. pat = self._make_src_surface(32)
  1768. masks = pat.get_masks()
  1769. if min(masks) == intify(0xFF000000):
  1770. masks = [longify(m) >> 8 for m in masks]
  1771. else:
  1772. masks = [intify(m << 8) for m in masks]
  1773. src = pygame.Surface(pat.get_size(), 0, 32, masks)
  1774. self._fill_surface(src)
  1775. dst = pygame.Surface(src.get_size(), 0, 32, masks)
  1776. for blend_name, dst_color, op in blend:
  1777. p = []
  1778. for src_color in self._test_palette:
  1779. c = [op(dst_color[i], src_color[i]) for i in range(3)]
  1780. c.append(255)
  1781. p.append(tuple(c))
  1782. dst.fill(dst_color)
  1783. dst.blit(src,
  1784. (0, 0),
  1785. special_flags=getattr(pygame, blend_name))
  1786. self._assert_surface(dst, p, ", %s" % blend_name)
  1787. def test_blit_blend_rgba(self):
  1788. sources = [self._make_src_surface(8),
  1789. self._make_src_surface(16),
  1790. self._make_src_surface(16, srcalpha=True),
  1791. self._make_src_surface(24),
  1792. self._make_src_surface(32),
  1793. self._make_src_surface(32, srcalpha=True)]
  1794. destinations = [self._make_surface(8),
  1795. self._make_surface(16),
  1796. self._make_surface(16, srcalpha=True),
  1797. self._make_surface(24),
  1798. self._make_surface(32),
  1799. self._make_surface(32, srcalpha=True)]
  1800. blend = [('BLEND_RGBA_ADD', (0, 25, 100, 255),
  1801. lambda a, b: min(a + b, 255)),
  1802. ('BLEND_RGBA_SUB', (0, 25, 100, 255),
  1803. lambda a, b: max(a - b, 0)),
  1804. ('BLEND_RGBA_MULT', (0, 7, 100, 255),
  1805. lambda a, b: (a * b) // 256),
  1806. ('BLEND_RGBA_MIN', (0, 255, 0, 255), min),
  1807. ('BLEND_RGBA_MAX', (0, 255, 0, 255), max)]
  1808. for src in sources:
  1809. src_palette = [src.unmap_rgb(src.map_rgb(c))
  1810. for c in self._test_palette]
  1811. for dst in destinations:
  1812. for blend_name, dst_color, op in blend:
  1813. dc = dst.unmap_rgb(dst.map_rgb(dst_color))
  1814. p = []
  1815. for sc in src_palette:
  1816. c = [op(dc[i], sc[i]) for i in range(4)]
  1817. if not dst.get_masks()[3]:
  1818. c[3] = 255
  1819. c = dst.unmap_rgb(dst.map_rgb(c))
  1820. p.append(c)
  1821. dst.fill(dst_color)
  1822. dst.blit(src,
  1823. (0, 0),
  1824. special_flags=getattr(pygame, blend_name))
  1825. self._assert_surface(dst, p,
  1826. (", op: %s, src bpp: %i"
  1827. ", src flags: %i" %
  1828. (blend_name,
  1829. src.get_bitsize(),
  1830. src.get_flags())))
  1831. # Blend blits are special cased for 32 to 32 bit surfaces
  1832. # with per-pixel alpha.
  1833. #
  1834. # Confirm the general case is used instead when the formats differ.
  1835. src = self._make_src_surface(32, srcalpha=True)
  1836. masks = src.get_masks()
  1837. dst = pygame.Surface(src.get_size(), SRCALPHA, 32,
  1838. (masks[2], masks[1], masks[0], masks[3]))
  1839. for blend_name, dst_color, op in blend:
  1840. p = [tuple([op(dst_color[i], src_color[i]) for i in range(4)])
  1841. for src_color in self._test_palette]
  1842. dst.fill(dst_color)
  1843. dst.blit(src,
  1844. (0, 0),
  1845. special_flags=getattr(pygame, blend_name))
  1846. self._assert_surface(dst, p, ", %s" % blend_name)
  1847. # Confirm this special case handles subsurfaces.
  1848. src = pygame.Surface((8, 10), SRCALPHA, 32)
  1849. dst = pygame.Surface((8, 10), SRCALPHA, 32)
  1850. tst = pygame.Surface((8, 10), SRCALPHA, 32)
  1851. src.fill((1, 2, 3, 4))
  1852. dst.fill((40, 30, 20, 10))
  1853. subsrc = src.subsurface((2, 3, 4, 4))
  1854. subdst = dst.subsurface((2, 3, 4, 4))
  1855. subdst.blit(subsrc, (0, 0), special_flags=BLEND_RGBA_ADD)
  1856. tst.fill((40, 30, 20, 10))
  1857. tst.fill((41, 32, 23, 14), (2, 3, 4, 4))
  1858. for x in range(8):
  1859. for y in range(10):
  1860. self.assertEqual(dst.get_at((x, y)), tst.get_at((x, y)),
  1861. "%s != %s at (%i, %i)" %
  1862. (dst.get_at((x, y)), tst.get_at((x, y)),
  1863. x, y))
  1864. def test_blit_blend_big_rect(self):
  1865. """ test that an oversized rect works ok.
  1866. """
  1867. color = (1, 2, 3, 255)
  1868. area = (1, 1, 30, 30)
  1869. s1 = pygame.Surface((4, 4), 0, 32)
  1870. r = s1.fill(special_flags=pygame.BLEND_ADD, color=color, rect=area)
  1871. self.assertEqual(pygame.Rect((1, 1, 3, 3)), r)
  1872. self.assertEqual(s1.get_at((0, 0)), (0, 0, 0, 255))
  1873. self.assertEqual(s1.get_at((1, 1)), color)
  1874. black = pygame.Color("black")
  1875. red = pygame.Color("red")
  1876. self.assertNotEqual(black, red)
  1877. surf = pygame.Surface((10, 10), 0, 32)
  1878. surf.fill(black)
  1879. subsurf = surf.subsurface(pygame.Rect(0, 1, 10, 8))
  1880. self.assertEqual(surf.get_at((0, 0)), black)
  1881. self.assertEqual(surf.get_at((0, 9)), black)
  1882. subsurf.fill(red, (0, -1, 10, 1), pygame.BLEND_RGB_ADD)
  1883. self.assertEqual(surf.get_at((0, 0)), black)
  1884. self.assertEqual(surf.get_at((0, 9)), black)
  1885. subsurf.fill(red, (0, 8, 10, 1), pygame.BLEND_RGB_ADD)
  1886. self.assertEqual(surf.get_at((0, 0)), black)
  1887. self.assertEqual(surf.get_at((0, 9)), black)
  1888. def test_GET_PIXELVALS(self):
  1889. # surface.h GET_PIXELVALS bug regarding whether of not
  1890. # a surface has per-pixel alpha. Looking at the Amask
  1891. # is not enough. The surface's SRCALPHA flag must also
  1892. # be considered. Fix rev. 1923.
  1893. src = self._make_surface(32, srcalpha=True)
  1894. src.fill((0, 0, 0, 128))
  1895. src.set_alpha(None) # Clear SRCALPHA flag.
  1896. dst = self._make_surface(32, srcalpha=True)
  1897. dst.blit(src, (0, 0), special_flags=BLEND_RGBA_ADD)
  1898. self.assertEqual(dst.get_at((0, 0)), (0, 0, 0, 255))
  1899. def test_fill_blend(self):
  1900. destinations = [self._make_surface(8),
  1901. self._make_surface(16),
  1902. self._make_surface(16, srcalpha=True),
  1903. self._make_surface(24),
  1904. self._make_surface(32),
  1905. self._make_surface(32, srcalpha=True)]
  1906. blend = [('BLEND_ADD', (0, 25, 100, 255),
  1907. lambda a, b: min(a + b, 255)),
  1908. ('BLEND_SUB', (0, 25, 100, 255),
  1909. lambda a, b: max(a - b, 0)),
  1910. ('BLEND_MULT', (0, 7, 100, 255),
  1911. lambda a, b: (a * b) // 256),
  1912. ('BLEND_MIN', (0, 255, 0, 255), min),
  1913. ('BLEND_MAX', (0, 255, 0, 255), max)]
  1914. for dst in destinations:
  1915. dst_palette = [dst.unmap_rgb(dst.map_rgb(c))
  1916. for c in self._test_palette]
  1917. for blend_name, fill_color, op in blend:
  1918. fc = dst.unmap_rgb(dst.map_rgb(fill_color))
  1919. self._fill_surface(dst)
  1920. p = []
  1921. for dc in dst_palette:
  1922. c = [op(dc[i], fc[i]) for i in range(3)]
  1923. if dst.get_masks()[3]:
  1924. c.append(dc[3])
  1925. else:
  1926. c.append(255)
  1927. c = dst.unmap_rgb(dst.map_rgb(c))
  1928. p.append(c)
  1929. dst.fill(fill_color, special_flags=getattr(pygame, blend_name))
  1930. self._assert_surface(dst, p, ", %s" % blend_name)
  1931. def test_fill_blend_rgba(self):
  1932. destinations = [self._make_surface(8),
  1933. self._make_surface(16),
  1934. self._make_surface(16, srcalpha=True),
  1935. self._make_surface(24),
  1936. self._make_surface(32),
  1937. self._make_surface(32, srcalpha=True)]
  1938. blend = [('BLEND_RGBA_ADD', (0, 25, 100, 255),
  1939. lambda a, b: min(a + b, 255)),
  1940. ('BLEND_RGBA_SUB', (0, 25, 100, 255),
  1941. lambda a, b: max(a - b, 0)),
  1942. ('BLEND_RGBA_MULT', (0, 7, 100, 255),
  1943. lambda a, b: (a * b) // 256),
  1944. ('BLEND_RGBA_MIN', (0, 255, 0, 255), min),
  1945. ('BLEND_RGBA_MAX', (0, 255, 0, 255), max)]
  1946. for dst in destinations:
  1947. dst_palette = [dst.unmap_rgb(dst.map_rgb(c))
  1948. for c in self._test_palette]
  1949. for blend_name, fill_color, op in blend:
  1950. fc = dst.unmap_rgb(dst.map_rgb(fill_color))
  1951. self._fill_surface(dst)
  1952. p = []
  1953. for dc in dst_palette:
  1954. c = [op(dc[i], fc[i]) for i in range(4)]
  1955. if not dst.get_masks()[3]:
  1956. c[3] = 255
  1957. c = dst.unmap_rgb(dst.map_rgb(c))
  1958. p.append(c)
  1959. dst.fill(fill_color, special_flags=getattr(pygame, blend_name))
  1960. self._assert_surface(dst, p, ", %s" % blend_name)
  1961. class SurfaceSelfBlitTest(unittest.TestCase):
  1962. """Blit to self tests.
  1963. This test case is in response to MotherHamster Bugzilla Bug 19.
  1964. """
  1965. def setUp(self):
  1966. # Needed for 8 bits-per-pixel color palette surface tests.
  1967. pygame.display.init()
  1968. def tearDown(self):
  1969. pygame.display.quit()
  1970. _test_palette = [(0, 0, 0, 255),
  1971. (255, 0, 0, 0),
  1972. (0, 255, 0, 255)]
  1973. surf_size = (9, 6)
  1974. def _fill_surface(self, surf, palette=None):
  1975. if palette is None:
  1976. palette = self._test_palette
  1977. surf.fill(palette[1])
  1978. surf.fill(palette[2], (1, 2, 1, 2))
  1979. def _make_surface(self, bitsize, srcalpha=False, palette=None):
  1980. if palette is None:
  1981. palette = self._test_palette
  1982. flags = 0
  1983. if srcalpha:
  1984. flags |= SRCALPHA
  1985. surf = pygame.Surface(self.surf_size, flags, bitsize)
  1986. if bitsize == 8:
  1987. surf.set_palette([c[:3] for c in palette])
  1988. self._fill_surface(surf, palette)
  1989. return surf
  1990. def _assert_same(self, a, b):
  1991. w, h = a.get_size()
  1992. for x in range(w):
  1993. for y in range(h):
  1994. self.assertEqual(a.get_at((x, y)), b.get_at((x, y)),
  1995. ("%s != %s, bpp: %i" %
  1996. (a.get_at((x, y)), b.get_at((x, y)),
  1997. a.get_bitsize())))
  1998. def test_overlap_check(self):
  1999. # Ensure overlapping blits are properly detected. There are two
  2000. # places where this is done, within SoftBlitPyGame() in alphablit.c
  2001. # and PySurface_Blit() in surface.c. SoftBlitPyGame should catch the
  2002. # per-pixel alpha surface, PySurface_Blit the colorkey and blanket
  2003. # alpha surface. per-pixel alpha and blanket alpha self blits are
  2004. # not properly handled by SDL 1.2.13, so Pygame does them.
  2005. bgc = (0, 0, 0, 255)
  2006. rectc_left = (128, 64, 32, 255)
  2007. rectc_right = (255, 255, 255, 255)
  2008. colors = [(255, 255, 255, 255), (128, 64, 32, 255)]
  2009. overlaps = [(0, 0, 1, 0, (50, 0)),
  2010. (0, 0, 49, 1, (98, 2)),
  2011. (0, 0, 49, 49, (98, 98)),
  2012. (49, 0, 0, 1, (0, 2)),
  2013. (49, 0, 0, 49, (0, 98))]
  2014. surfs = [pygame.Surface((100, 100), SRCALPHA, 32)]
  2015. surf = pygame.Surface((100, 100), 0, 32)
  2016. surf.set_alpha(255)
  2017. surfs.append(surf)
  2018. surf = pygame.Surface((100, 100), 0, 32)
  2019. surf.set_colorkey((0, 1, 0))
  2020. surfs.append(surf)
  2021. for surf in surfs:
  2022. for s_x, s_y, d_x, d_y, test_posn in overlaps:
  2023. surf.fill(bgc)
  2024. surf.fill(rectc_right, (25, 0, 25, 50))
  2025. surf.fill(rectc_left, (0, 0, 25, 50))
  2026. surf.blit(surf, (d_x, d_y), (s_x, s_y, 50, 50))
  2027. self.assertEqual(surf.get_at(test_posn), rectc_right)
  2028. # https://github.com/pygame/pygame/issues/370#issuecomment-364625291
  2029. @unittest.skipIf('ppc64le' in platform.uname(), 'known ppc64le issue')
  2030. def test_colorkey(self):
  2031. # Check a workaround for an SDL 1.2.13 surface self-blit problem
  2032. # (MotherHamster Bugzilla bug 19).
  2033. pygame.display.set_mode((100, 50)) # Needed for 8bit surface
  2034. bitsizes = [8, 16, 24, 32]
  2035. for bitsize in bitsizes:
  2036. surf = self._make_surface(bitsize)
  2037. surf.set_colorkey(self._test_palette[1])
  2038. surf.blit(surf, (3, 0))
  2039. p = []
  2040. for c in self._test_palette:
  2041. c = surf.unmap_rgb(surf.map_rgb(c))
  2042. p.append(c)
  2043. p[1] = (p[1][0], p[1][1], p[1][2], 0)
  2044. tmp = self._make_surface(32, srcalpha=True, palette=p)
  2045. tmp.blit(tmp, (3, 0))
  2046. tmp.set_alpha(None)
  2047. comp = self._make_surface(bitsize)
  2048. comp.blit(tmp, (0, 0))
  2049. self._assert_same(surf, comp)
  2050. # https://github.com/pygame/pygame/issues/370#issuecomment-364625291
  2051. @unittest.skipIf('ppc64le' in platform.uname(), 'known ppc64le issue')
  2052. def test_blanket_alpha(self):
  2053. # Check a workaround for an SDL 1.2.13 surface self-blit problem
  2054. # (MotherHamster Bugzilla bug 19).
  2055. pygame.display.set_mode((100, 50)) # Needed for 8bit surface
  2056. bitsizes = [8, 16, 24, 32]
  2057. for bitsize in bitsizes:
  2058. surf = self._make_surface(bitsize)
  2059. surf.set_alpha(128)
  2060. surf.blit(surf, (3, 0))
  2061. p = []
  2062. for c in self._test_palette:
  2063. c = surf.unmap_rgb(surf.map_rgb(c))
  2064. p.append((c[0], c[1], c[2], 128))
  2065. tmp = self._make_surface(32, srcalpha=True, palette=p)
  2066. tmp.blit(tmp, (3, 0))
  2067. tmp.set_alpha(None)
  2068. comp = self._make_surface(bitsize)
  2069. comp.blit(tmp, (0, 0))
  2070. self._assert_same(surf, comp)
  2071. def test_pixel_alpha(self):
  2072. bitsizes = [16, 32]
  2073. for bitsize in bitsizes:
  2074. surf = self._make_surface(bitsize, srcalpha=True)
  2075. comp = self._make_surface(bitsize, srcalpha=True)
  2076. comp.blit(surf, (3, 0))
  2077. surf.blit(surf, (3, 0))
  2078. self._assert_same(surf, comp)
  2079. def test_blend(self):
  2080. bitsizes = [8, 16, 24, 32]
  2081. blends = ['BLEND_ADD',
  2082. 'BLEND_SUB',
  2083. 'BLEND_MULT',
  2084. 'BLEND_MIN',
  2085. 'BLEND_MAX']
  2086. for bitsize in bitsizes:
  2087. surf = self._make_surface(bitsize)
  2088. comp = self._make_surface(bitsize)
  2089. for blend in blends:
  2090. self._fill_surface(surf)
  2091. self._fill_surface(comp)
  2092. comp.blit(surf, (3, 0),
  2093. special_flags=getattr(pygame, blend))
  2094. surf.blit(surf, (3, 0),
  2095. special_flags=getattr(pygame, blend))
  2096. self._assert_same(surf, comp)
  2097. def test_blend_rgba(self):
  2098. bitsizes = [16, 32]
  2099. blends = ['BLEND_RGBA_ADD',
  2100. 'BLEND_RGBA_SUB',
  2101. 'BLEND_RGBA_MULT',
  2102. 'BLEND_RGBA_MIN',
  2103. 'BLEND_RGBA_MAX']
  2104. for bitsize in bitsizes:
  2105. surf = self._make_surface(bitsize, srcalpha=True)
  2106. comp = self._make_surface(bitsize, srcalpha=True)
  2107. for blend in blends:
  2108. self._fill_surface(surf)
  2109. self._fill_surface(comp)
  2110. comp.blit(surf, (3, 0),
  2111. special_flags=getattr(pygame, blend))
  2112. surf.blit(surf, (3, 0),
  2113. special_flags=getattr(pygame, blend))
  2114. self._assert_same(surf, comp)
  2115. def test_subsurface(self):
  2116. # Blitting a surface to its subsurface is allowed.
  2117. surf = self._make_surface(32, srcalpha=True)
  2118. comp = surf.copy()
  2119. comp.blit(surf, (3, 0))
  2120. sub = surf.subsurface((3, 0, 6, 6))
  2121. sub.blit(surf, (0, 0))
  2122. del sub
  2123. self._assert_same(surf, comp)
  2124. # Blitting a subsurface to its owner is forbidden because of
  2125. # lock conficts. This limitation allows the overlap check
  2126. # in PySurface_Blit of alphablit.c to be simplified.
  2127. def do_blit(d, s):
  2128. d.blit(s, (0, 0))
  2129. sub = surf.subsurface((1, 1, 2, 2))
  2130. self.assertRaises(pygame.error, do_blit, surf, sub)
  2131. def test_copy_alpha(self):
  2132. """issue 581: alpha of surface copy with SRCALPHA is set to 0."""
  2133. surf = pygame.Surface((16, 16), pygame.SRCALPHA, 32)
  2134. self.assertEqual(surf.get_alpha(), 255)
  2135. surf2 = surf.copy()
  2136. self.assertEqual(surf2.get_alpha(), 255)
  2137. class SurfaceFillTest(unittest.TestCase):
  2138. def setUp(self):
  2139. pygame.display.init()
  2140. def tearDown(self):
  2141. pygame.display.quit()
  2142. def test_fill(self):
  2143. screen = pygame.display.set_mode((640, 480))
  2144. # Green and blue test pattern
  2145. screen.fill((0, 255, 0), (0, 0, 320, 240))
  2146. screen.fill((0, 255, 0), (320, 240, 320, 240))
  2147. screen.fill((0, 0, 255), (320, 0, 320, 240))
  2148. screen.fill((0, 0, 255), (0, 240, 320, 240))
  2149. # Now apply a clip rect, such that only the left side of the
  2150. # screen should be effected by blit opperations.
  2151. screen.set_clip((0, 0, 320, 480))
  2152. # Test fills with each special flag, and additionaly without any.
  2153. screen.fill((255, 0, 0, 127), (160, 0, 320, 30), 0)
  2154. screen.fill((255, 0, 0, 127), (160, 30, 320, 30), pygame.BLEND_ADD)
  2155. screen.fill((0, 127, 127, 127), (160, 60, 320, 30), pygame.BLEND_SUB)
  2156. screen.fill((0, 63, 63, 127), (160, 90, 320, 30), pygame.BLEND_MULT)
  2157. screen.fill((0, 127, 127, 127), (160, 120, 320, 30), pygame.BLEND_MIN)
  2158. screen.fill((127, 0, 0, 127), (160, 150, 320, 30), pygame.BLEND_MAX)
  2159. screen.fill((255, 0, 0, 127), (160, 180, 320, 30), pygame.BLEND_RGBA_ADD)
  2160. screen.fill((0, 127, 127, 127), (160, 210, 320, 30), pygame.BLEND_RGBA_SUB)
  2161. screen.fill((0, 63, 63, 127), (160, 240, 320, 30), pygame.BLEND_RGBA_MULT)
  2162. screen.fill((0, 127, 127, 127), (160, 270, 320, 30), pygame.BLEND_RGBA_MIN)
  2163. screen.fill((127, 0, 0, 127), (160, 300, 320, 30), pygame.BLEND_RGBA_MAX)
  2164. screen.fill((255, 0, 0, 127), (160, 330, 320, 30), pygame.BLEND_RGB_ADD)
  2165. screen.fill((0, 127, 127, 127), (160, 360, 320, 30), pygame.BLEND_RGB_SUB)
  2166. screen.fill((0, 63, 63, 127), (160, 390, 320, 30), pygame.BLEND_RGB_MULT)
  2167. screen.fill((0, 127, 127, 127), (160, 420, 320, 30), pygame.BLEND_RGB_MIN)
  2168. screen.fill((255, 0, 0, 127), (160, 450, 320, 30), pygame.BLEND_RGB_MAX)
  2169. # Update the display so we can see the results
  2170. pygame.display.flip()
  2171. # Compare colors on both sides of window
  2172. for y in range(5, 480, 10):
  2173. self.assertEqual(screen.get_at((10, y)), screen.get_at((330, 480 - y)))
  2174. if __name__ == '__main__':
  2175. unittest.main()