PySDL2-0.9.3/0000755000000000000000000000000012357043742007435 5ustar PySDL2-0.9.3/doc/0000755000000000000000000000000012357043742010202 5ustar PySDL2-0.9.3/doc/modules/0000755000000000000000000000000012357043742011652 5ustar PySDL2-0.9.3/doc/modules/images/0000755000000000000000000000000012357043742013117 5ustar PySDL2-0.9.3/doc/modules/images/coordinate_rhs.dia0000644000000000000000000000167312260256443016605 0ustar  Xr0+ud! $vN#@jdwox8681N1$#ri9)K4 *$b"?|.bFƒL H+5˔Df ?sA}sxaQ$+{R3E A&t`$|e2YDqai cK~g4<6CC~)u4IQVHNw#JubHek@IԄȘm^$p}CUN NKOK'OK4J)$ᔈUmϓ7x`J%/5(vrcɢ­D4,Xƣ#@_ }RpkL7_ |~c5hCK×x"Pf՘q)&-9'K*K/Ql6/\ZABFR U9ȸ22zޅ=7XMW}M;VsQ!Գ`=ulODioֆ,}mva"Ĉ(Sa빋$ֹw)P=2Yԁ[ͩ#SW[y$nW܉0kdѳZֆ@gi@4,zɴ=,GVGR,/Im*awp\;\CJ&`;P3;vkf#E-鄜Tj5ˆۚ=Gr".x Ɨz@DevX)SB)G0,f cX}nJ<U{n!FD8ńk_{-ΣaCjX$t6'eL1ḯ|WqYi|Jsz:ͩjN l1+&zݜCmOiNtlsjƳ99}xQ^TPySDL2-0.9.3/doc/modules/images/copprocessing.dia0000644000000000000000000000454712260256443016463 0ustar  ]]s8}_AѯOKL2ճ[0S3=oxؔm}%$/Un$t96?G*0##Å,o/bYFjGw7$Ypum&a|obu?+j|i4`&9;&I6J݌gen8kk70=]_sﵻTHUw K6]Utjƞnlׅ&?ZźQ~Ά;W@+A-1֋Sפ9lX8XhX8/(\/)BWn&Flj箯رiuŝ$߹~\ghk[\^Er?}:reo{3_ ޺᧓fq7dUB1Śo,ߦ]S~خdN)nUS22ޥ;Ow{bNy22-=4~%%xotjl3 {`feq8O`&Hv9@d"`QW*qguk|(qW0IٱlvDW>9@@A@$(;dD=%S6QV3\;m;k@;^VU)-xZ G'Rjaߌܕo( dkҶNxsw1ۍ$JC }x(Mc8Re(YwNyV?־ճO"5ZYW(Bݹp]FTJ~q68< |Z̳OG~P:))NuאM ПVqiw{w'$LZK:.nȞ3ЃS{ $qfBh.  I%gqf=\guBkB 0j kXkXcm|.<6H! Ay)C-o:Yw߯w@{gۀ0 w5N8 Ӡ ֭1p.#>)OO DX:) :)NE D`hdS90NAlphvfAØpwpyȈ8@B` @Vcn<3@ ["WBy!@%aTFANDnnұ穯eNh q4F( c!{7bwu4{Ty8猝$DJ fNZ_g9{UhJ\)hޜm~-gէr$J!OxQ wDF9|*!tQޑ}% < sAsq}0\sL/>T'TA)pgi3WQ rBu/p215i;!{ :Nu0 =Tt b@p[ɘ6*R< s߃KG.Th*6Vcٍ wv[rچtceIT -lȝ%FpȮC)ٱ,5 9HF\hs/[P$! H{զ=򺻻tURL[UZRB>1.V3|:&9j[cIL=Si-@$T8y)k`h̦..j;oA]mJz[`&w)4MnFٚ;[sgklݻdOނH ;\2<)3|vj}^զv;\ݭn?eo2rWoPySDL2-0.9.3/doc/modules/images/ebs.dia0000644000000000000000000000345212260256443014350 0ustar  ]Ks6Wp;i;NIG $Ԑm] %$>jo㧧u=8vi4\D.oG߿}Yd+D|LAKb[ɿ$Ȅ7n4PG򳄱؟oB9YX6FY" X{ }Mr1#7dI1%?ECr>74.]oMnSi G(\޽xu)?UF%lMVp!0p06llU\V]|Yu~2D1Ϫ*QPfZY$ p;6NId_k.c; R}fO̕II'=k4ڗ%(x6\Ǥghic4.ˀfJ p1)2[_- zP@{pj>PÊ;bU8!t欭}brFgq`t'NfpgIEg+sZZ߄쐆,ivBVX|ݓxI0rq rh~X_pemsr} xݻ ״&pMAWmQKѾSz/<$*}3G/驚䌋id+96J a5edt(|n^SٌUKlb*(UƸO2NV驁AGd! T&L`6zB3"u\~PQmnSR_Jt{|kLe6wM]VS{{,`:GP5)zWEM9HD@9>֓;S'?{V-;^.dM{ؔv'D6`&8>Ih_tP:}V|3|8Mҁs| H(P8KTI7H(nb.T)BE'PtB E'~:F1Or૧TJacCQ E)RE)/^BVBQ E-PBQ~`ag^԰ s(~n$CmОZX\E3zX:i.x8-6>1x3 =ΔT'ڊ_,JiOe+kQu@C :e8n!S^A:&BY85kpFPEx e~ ~ 3q4oCR [PDj;OH,bS0L5=RCjzH3Gd*G2baOVbglrk'jLk#_֑/[:1tWM6u**|m &v_U, ruGmT\XqaŅV:Pa s-\xʳk o.9"aT<}  vn]]Ů./_XkP֍Y֟' ʒkȳG; "`Z$BvY8 hN1tw 2>т& MTm,ڥ祪CPTE$sMH4I!hġtWAl'#'i(Kh< ?Kw/]k?dԟ asC"NoLūD)"Q)Ǣ Uyua L*2 'Kɍ9aoA"oV"qâKu1+3Ò-,oMCCL/xR5;_4TMdGmVR(f=+э rΒ 87Q \r\:|nrZpitLX(!"U&K~8N:ebۆaסbGY3hkAbЗ]O*d&LIězhczwr^l(mL)C }f6,V͆^mcKdCD'+oiXl*Ûo|"&\ KS~\W K,:8eJ`W P!@hu1T]_ #c 091P X33 T&*cAtwr2ψr a qFRvLͦb'/K*?NĔH6[&X6af׍k6{5`=?}ϣ.){?CZ&&"<@XUN{NCTs|Cy79*d.:R.(Ünȭ8.Lg~qw\./ j8ḽb&nŴ/2">b(p PCelL}4´{%5'oRX!/C -0C # Y`ZA0#H3ݦ5ZcJC%(MCk 1Aj L12UM>6p3ݦ5ZcJ>ض>Zch5]4G, ",2T}bxQ(a<"x3O򩌩1S-|R {GXz}H^(2sc.)7&yj6~97kʎx!z*~T{?ƌ~tiH?etϖU|'{JC,@QzIGP-[ C$DPOvQ r" l;{ L4vmm!)#H> Ia;2#=Iĥ9*2rHV'eK=jbsS'^dd*Ɋ6T~U9QOU=hJ%)l:.3T2gdE0heET,g} ,#B+r 8 g fh#7{FV"NNiݖf6.]S >f]!ڼmh*ak+"KYN9:wɽn6fI"n7㎦hW'NX%6[-96~Βkp΄T嶢>FXHG*"@?*y,B~.qV-VrwisB G۔K&:J)`v *VRWN=zƇl.\{z`_. Usage ----- You can use :mod:`sdl2` in nearly exactly the same way as you would do with the SDL library and C code. .. highlight:: c A brief example in C code:: #include int main(int argc, char *argv[]) { int running; SDL_Window *window; SDL_Surface *windowsurface; SDL_Surface *image; SDL_Event event; SDL_Init(SDL_INIT_VIDEO); window = SDL_CreateWindow("Hello World", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 592, 460, SDL_WINDOW_SHOWN); windowsurface = SDL_GetWindowSurface(window); image = SDL_LoadBMP("exampleimage.bmp"); SDL_BlitSurface(image, NULL, windowsurface, NULL); SDL_UpdateWindowSurface(window); SDL_FreeSurface(image); running = 1; while (running) { while (SDL_PollEvent(&event) != 0) { if (event.type == SDL_QUIT) { running = 0; break; } } } SDL_DestroyWindow(window); SDL_Quit(); return 0; } .. highlight:: python Doing the same in Python: :: import sys import ctypes from sdl2 import * def main(): SDL_Init(SDL_INIT_VIDEO) window = SDL_CreateWindow(b"Hello World", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 592, 460, SDL_WINDOW_SHOWN) windowsurface = SDL_GetWindowSurface(window) image = SDL_LoadBMP(b"exampleimage.bmp") SDL_BlitSurface(image, None, windowsurface, None) SDL_UpdateWindowSurface(window) SDL_FreeSurface(image) running = True event = SDL_Event() while running: while SDL_PollEvent(ctypes.byref(event)) != 0: if event.type == SDL_QUIT: running = False break SDL_DestroyWindow(window) SDL_Quit() return 0 if __name__ == "__main__": sys.exit(run()) You can port code in a straightforward manner from one language to the other, though it is important to know about the limitations and slight differences mentioned below. Also, PySDL2 offers advanced functionality, which also feels more *'pythonic'*, via the :mod:`sdl2.ext` package. Missing interfaces ------------------ The following functions, classes, constants and macros of SDL2 are *not* available within :mod:`sdl2`. * :c:data:`SDL_REVISION` and :c:data:`SDL_REVISION_NUMBER` from ``SDL_revision.h`` * :c:data:`SDL_NAME()` from ``SDL_name.h`` * :c:func:`SDL_MostSignificantBitIndex32` from ``SDL_bits.h`` * Everything from ``SDL_main.h`` * Everything from ``SDL_system.h`` * Everything from ``SDL_assert.h`` * Everything from ``SDL_thread.h`` * Everything from ``SDL_atomic.h`` * Everything from ``SDL_opengl.h`` * Everything from ``SDL_mutex.h`` Additional interfaces --------------------- The following functions, classes, constants and macros are are *not* part of SDL2, but were introduced by :mod:`sdl2`. .. data:: ALL_PIXELFORMATS Tuple containing all SDL2 pixel format constants (SDL_PIXELFORMAT_INDEX1LSB, ..., SDL_PIXELFORMAT_RGB565, ...). .. data:: AUDIO_FORMATS Set containing all SDL2 audio format constants (AUDIO_U8, AUDIO_S8, ... AUDIO_F32LSB, ... ). .. function:: sdl2.rw_from_object(obj : object) -> SDL_RWops Creates a SDL_RWops from any Python object. The Python object must at least support the following methods: read(length) -> data length is the size in bytes to be read. A call to len(data) must return the correct amount of bytes for the data, so that len(data) / [size in bytes for a single element from data] returns the amount of elements. Must raise an error on failure. seek(offset, whence) -> int offset denotes the offset to move the read/write pointer of the object to. whence indicates the movement behaviour and can be one of the following values: * RW_SEEK_SET - move to offset from the start of the file * RW_SEEK_CUR - move by offset from the relative location * RW_SEEK_END - move to offset from the end of the file If it could not move read/write pointer to the desired location, an error must be raised. tell() -> int Must return the current offset. This method must only be provided, if seek() does not return any value. close() -> None Closes the object(or its internal data access methods). Must raise an error on failure. write(data) -> None Writes the passed data(which is a string of bytes) to the object. Must raise an error on failure. .. note:: The write() method is optional and only necessary, if the passed object should be able to write data. The returned :class:`sdl2.SDL_RWops` is a pure Python object and **must not** be freed via :func:`sdl2.SDL_FreeRW()`. PySDL2-0.9.3/doc/modules/sdl2_sdlgfx.rst0000644000000000000000000000101512260256443014611 0ustar .. module:: sdl2.sdlgfx :synopsis: SDL2_gfx library wrapper sdl2.sdlgfx - SDL2_gfx library wrapper ====================================== The :mod:`sdl2.sdlgfx` module is a :mod:`ctypes`-based wrapper around the SDL2_gfx library. It wraps nearly all publicly accessible structures and functions of the SDL2_gfx library to be accessible from Python code. A detailed documentation about the behaviour of the different functions can found on the `SDL2_gfx project website `_. PySDL2-0.9.3/doc/modules/sdl2_sdlimage.rst0000644000000000000000000000105612260256443015114 0ustar .. module:: sdl2.sdlimage :synopsis: SDL2_image library wrapper sdl2.sdlimage - SDL2_image library wrapper ========================================== The :mod:`sdl2.sdlimage` module is a :mod:`ctypes`-based wrapper around the SDL2_image library. It wraps nearly all publicly accessible structures and functions of the SDL2_image library to be accessible from Python code. A detailed documentation about the behaviour of the different functions can found within the `SDL2_image documentation `_. PySDL2-0.9.3/doc/modules/sdl2_sdlmixer.rst0000644000000000000000000000105412260256443015154 0ustar .. module:: sdl2.sdlmixer :synopsis: SDL2_mixer library wrapper sd2.sdlmixer - SDL2_mixer library wrapper ========================================= The :mod:`sdl2.sdlmixer` module is a :mod:`ctypes`-based wrapper around the SDL2_mixer library. It wraps nearly all publicly accessible structures and functions of the SDL2_mixer library to be accessible from Python code. A detailed documentation about the behaviour of the different functions can found within the `SDL2_mixer documentation `_. PySDL2-0.9.3/doc/modules/sdl2_sdlttf.rst0000644000000000000000000000102612260256443014624 0ustar .. module:: sdl2.sdlttf :synopsis: SDL2_ttf library wrapper sd2.sdlttf - SDL2_ttf library wrapper ===================================== The :mod:`sdl2.sdlttf` module is a :mod:`ctypes`-based wrapper around the SDL2_ttf library. It wraps nearly all publicly accessible structures and functions of the SDL2_ttf library to be accessible from Python code. A detailed documentation about the behaviour of the different functions can found within the `SDL2_ttf documentation `_. PySDL2-0.9.3/doc/modules/sdl2ext.rst0000644000000000000000000000156112312631402013757 0ustar .. module:: sdl2.ext :synopsis: Python extensions for SDL2 sdl2.ext - Python extensions for SDL2 ===================================== The :mod:`sdl2.ext` package provides advanced functionality for creating applications using SDL2 and Python. It offers a rich set of modules, classes and functions, such as easy image loading, basic user interface elements, resource management and sprite and (on-screen) scene systems. Learn more about .. toctree:: :maxdepth: 1 sdl2ext_algorithms.rst sdl2ext_array.rst sdl2ext_color.rst sdl2ext_colorpalettes.rst sdl2ext_common.rst sdl2ext_compat.rst sdl2ext_draw.rst sdl2ext_ebs.rst sdl2ext_events.rst sdl2ext_font.rst sdl2ext_gui.rst sdl2ext_image.rst sdl2ext_particles.rst sdl2ext_pixelaccess.rst sdl2ext_resources.rst sdl2ext_sprite.rst sdl2ext_surface.rst sdl2ext_window.rst PySDL2-0.9.3/doc/modules/sdl2ext_algorithms.rst0000644000000000000000000000320712323417722016220 0ustar .. currentmodule:: sdl2.ext Common algorithms ================= .. function:: cohensutherland(left : int, top : int, right : int, \ bottom : int, x1 : int, y1 : int, x2 : int, y2 : int) -> int, int, int, int This implements the Cohen-Sutherland line clipping algorithm. *left*, *top*, *right* and *bottom* denote the clipping area, into which the line defined by *x1*, *y1* (start point) and *x2*, *y2* (end point) will be clipped. If the line does not intersect with the rectangular clipping area, four ``None`` values will be returned as tuple. Otherwise a tuple of the clipped line points will be returned in the form ``(cx1, cy1, cx2, cy2)``. .. function:: liangbarsky(left : int, top : int, right : int, \ bottom : int, x1 : int, y1 : int, x2 : int, y2 : int) -> int, int, int, int This implements the Liang-Barsky line clipping algorithm. *left*, *top*, *right* and *bottom* denote the clipping area, into which the line defined by *x1*, *y1* (start point) and *x2*, *y2* (end point) will be clipped. If the line does not intersect with the rectangular clipping area, four ``None`` values will be returned as tuple. Otherwise a tuple of the clipped line points will be returned in the form ``(cx1, cy1, cx2, cy2)``. .. function:: clipline(left : int, top : int, right : int, \ bottom : int, x1 : int, y1 : int, x2 : int, \ y2 : int[,method=liangbarsky]) -> int, int, int, int Clips a line to a rectangular area. .. function:: point_on_line(p1 : iterable, p2 : iterable, point : iterable) -> bool Checks, if *point*, a two-value tuple, is on the line segment defined by *p1* and *p2*. PySDL2-0.9.3/doc/modules/sdl2ext_array.rst0000644000000000000000000002414312260256443015170 0ustar .. currentmodule:: sdl2.ext Converting sequences ==================== This module provides various functions and classes to access sequences and buffer-style objects in different ways. It also provides conversion routines to improve the interoperability of sequences with :mod:`ctypes` data types. Providing read-write access for sequential data ----------------------------------------------- Two classes allow you to access sequential data in different ways. The :class:`CTypesView` provides byte-wise access to iterable objects and allows you to convert the object representation to matching byte-widths for :mod:`ctypes` or other modules. Depending on the the underlying object and the chosen size of each particular item of the object, the :class:`CTypesView` allows you to operate directly on different representations of the object's contents. :: >>> text = bytearray("Hello, I am a simple ASCII string!") >>> ctview = CTypesView(text, itemsize=1) >>> ctview.view[0] = 0x61 >>> print(text) aello, I am a simple ASCII string!" >>> ctview.to_uint16()[3] = 0x6554 >>> print(text) aello,Te am a simple ASCII string!" The snippet above provides a single-byte sized view on a :func:`bytearray` object. Afterwards, the first item of the view is changed, which causes a change on the :func:`bytearray`, on the first item as well, since both, the :class:`CTypesView` and the :func:`bytearray` provide a byte-wise access to the contents. By using :meth:`CTypesView.to_uint16()`, we change the access representation to a 2-byte unsigned integer :mod:`ctypes` pointer and change the fourth 2-byte value, *I* to something else. :: >>> text = bytearray("Hello, I am a simple ASCII string!") >>> ctview = CTypesView(text, itemsize=2) >>> ctview.view[0] = 0x61 >>> print(text) aello, I am a simple ASCII string!" >>> ctview.to_uint16()[3] = 0x6554 >>> print(text) aello,Te am a simple ASCII string!" If the encapsuled object does not provide a (writable) :func:`buffer` interface, but is iterable, the :class:`CTypesView` will create an internal copy of the object data using Python's :mod:`array` module and perform all operations on that copy. :: >>> mylist = [18, 52, 86, 120, 154, 188, 222, 240] >>> ctview = CTypesView(mylist, itemsize=1, docopy=True) >>> print(ctview.object) array('B', [18, 52, 86, 120, 154, 188, 222, 240]) >>> ctview.view[3] = 0xFF >>> print(mylist) [18, 52, 86, 120, 154, 188, 222, 240] >>> print(ctview.object) array('B', [18, 52, 86, 255, 154, 188, 222, 240]) As for directly accessible objects, you can define your own itemsize to be used. If the iterable does not provide a direct byte access to their contents, this won't have any effect except for resizing the item widths. :: >>> mylist = [18, 52, 86, 120, 154, 188, 222, 240] >>> ctview = CTypesView(mylist, itemsize=4, docopy=True) >>> print(ctview.object) array('I', [18L, 52L, 86L, 120L, 154L, 188L, 222L, 240L]) Accessing data over multiple dimensions --------------------------------------- The second class, :class:`MemoryView` provides an interface to access data over multiple dimensions. You can layout and access a simple byte stream over e.g. two or more axes, providing a greater flexibility for functional operations and complex data. Let's assume, we are reading image data from a file stream into some buffer object and want to access and manipulate the image data. Images feature two axes, one being the width, the other being the height, defining a rectangular graphics area. When we read all data from the file, we have an one-dimensional view of the image graphics. The :class:`MemoryView` allows us to define a two-dimensional view over the image graphics, so that we can operate on both, rows and columns of the image. :: >>> imagedata = bytearray("some 1-byte graphics data") >>> view = MemoryView(imagedata, 1, (5, 5)) >>> print(view) [[s, o, m, e, ], [1, -, b, y, t], [e, , g, r, a], [p, h, i, c, s], [ , d, a, t, a]] >>> for row in view: ... print(row) ... [s, o, m, e, ] [1, -, b, y, t] [e, , g, r, a] [p, h, i, c, s] [ , d, a, t, a] >>> for row in view: ... row[1] = "X" ... print row ... [s, X, m, e, ] [1, X, b, y, t] [e, X, g, r, a] [p, X, i, c, s] [ , X, a, t, a] >>> print(imagedata) sXme 1XbyteXgrapXics Xata On accessing a particular dimension of a :class:`MemoryView`, a new :class:`MemoryView` is created, if it does not access a single element. :: >>> firstrow = view[0] >>> type(firstrow) >>> type(firstrow[0]) A :class:`MemoryView` features, similar to Python's builtin :class:`memoryview`, dimensions and strides, accessible via the :attr:`MemoryView.ndim` and :attr:`MemoryView.strides` attributes. >>> view.ndim 2 >>> view.strides (5, 5) The :attr:`MemoryView.strides`, which have to be passed on creating a new :class:`MemoryView`, define the layout of the data over different dimensions. In the example above, we created a 5x5 two-dimensional view to the image graphics. :: >>> twobytes = MemoryView(imagedata, 2, (5, 1)) >>> print(twobytes) [[sX, me, 1, Xb, yt], [eX, gr, ap, Xi, cs]] Array API --------- .. class:: CTypesView(obj : iterable[, itemsize=1[, docopy=False[, objsize=None]]]) A proxy class for byte-wise accessible data types to be used in ctypes bindings. The CTypesView provides a read-write access to arbitrary objects that are iterable. In case the object does not provide a :func:`buffer()` interface for direct access, the CTypesView can copy the object's contents into an internal buffer, from which data can be retrieved, once the necessary operations have been performed. Depending on the item type stored in the iterable object, you might need to provide a certain *itemsize*, which denotes the size per item in bytes. The *objsize* argument might be necessary of iterables, for which len() does not return the correct amount of objects or is not implemented. .. attribute:: bytesize Returns the length of the encapsuled object in bytes. .. attribute:: is_shared Indicates, if changes on the CTypesView data effect the encapsuled object directly. if not, this means that the object was copied internally and needs to be updated by the user code outside of the CTypesView. .. attribute:: object The encapsuled object. .. attribute:: view Provides a read-write aware view of the encapsuled object data that is suitable for usage from :mod:`ctypes`. .. method:: to_bytes() -> ctypes.POINTER Returns a byte representation of the encapsuled object. The return value allows a direct read-write access to the object data, if it is not copied. The :func:`ctypes.POINTER` points to an array of :class:`ctypes.c_ubyte`. .. method:: to_uint16() -> ctypes.POINTER Returns a 16-bit representation of the encapsuled object. The return value allows a direct read-write access to the object data, if it is not copied. The :func:`ctypes.POINTER` points to an array of :class:`ctypes.c_ushort`. .. method:: to_uint32() -> ctypes.POINTER Returns a 32-bit representation of the encapsuled object. The return value allows a direct read-write access to the object data, if it is not copied. The :func:`ctypes.POINTER` points to an array of :class:`ctypes.c_uint`. .. method:: to_uint64() -> ctypes.POINTER Returns a 64-bit representation of the encapsuled object. The return value allows a direct read-write access to the object data, if it is not copied. The :func:`ctypes.POINTER` points to an array of :class:`ctypes.c_ulonglong`. .. class:: MemoryView(source : object, itemsize : int, strides : tuple[, getfunc=None[, setfunc=None[, srcsize=None]]]) The :class:`MemoryView` provides a read-write access to arbitrary data objects, which can be indexed. *itemsize* denotes the size of a single item. *strides* defines the dimensions and the length (n items * *itemsize*) for each dimension. *getfunc* and *setfunc* are optional parameters to provide specialised read and write access to the underlying *source*. *srcsize* can be used to provide the correct source size, if ``len(source)`` does not return the absolute size of the source object in all dimensions. .. note:: The MemoryView is a pure Python-based implementation and makes heavy use of recursion for multi-dimensional access. If you aim for speed on accessing a n-dimensional object, you want to consider using a specialised library such as numpy. If you need n-dimensional access support, where such a library is not supported, or if you need to provide access to objects, which do not fulfill the requirements of that particular libray, :class:`MemoryView` can act as solid fallback solution. .. attribute:: itemsize The size of a single item in bytes. .. attribute:: ndim The number of dimensions of the :class:`MemoryView`. .. attribute:: size The size in bytes of the underlying source object. .. attribute:: source The underlying data source. .. attribute:: strides A tuple defining the length in bytes for accessing all elements in each dimension of the :class:`MemoryView`. .. function:: to_ctypes(dataseq : iterable, dtype[, mcount=0]) -> array, int Converts an arbitrary sequence to a ctypes array of the specified *dtype* and returns the ctypes array and amount of items as two-value tuple. Raises a :exc:`TypeError`, if one or more elements in the passed sequence do not match the passed *dtype*. .. function:: to_list(dataseq : iterable) -> list Converts a ctypes array to a list. .. function:: to_tuple(dataseq : iterable) -> tuple Converts a ctypes array to a tuple. .. function:: create_array(obj : object, itemsize : int) -> array.array Creates an :class:`array.array` based copy of the passed object. *itemsize* denotes the size in bytes for a single element within *obj*. PySDL2-0.9.3/doc/modules/sdl2ext_color.rst0000644000000000000000000001130312260256443015162 0ustar .. currentmodule:: sdl2.ext Color handling ============== .. class:: Color(r=255, g=255, b=255, a=255) A simple RGBA-based color implementation. The Color class uses a byte-wise representation of the 4 channels red, green, blue and alpha transparency, so that the values range from 0 to 255. It allows basic arithmetic operations, e.g. color addition or subtraction and conversions to other color spaces such as HSV or CMY. .. attribute:: r The red channel value of the Color. .. attribute:: g The green channel value of the Color. .. attribute:: b The blue channel value of the Color. .. attribute:: a The alpha channel value of the Color. .. attribute:: cmy The CMY representation of the Color. The CMY components are in the ranges C = [0, 1], M = [0, 1], Y = [0, 1]. Note that this will not return the absolutely exact CMY values for the set RGB values in all cases. Due to the RGB mapping from 0-255 and the CMY mapping from 0-1 rounding errors may cause the CMY values to differ slightly from what you might expect. .. attribute:: hsla The HSLA representation of the Color. The HSLA components are in the ranges H = [0, 360], S = [0, 100], L = [0, 100], A = [0, 100]. Note that this will not return the absolutely exact HSL values for the set RGB values in all cases. Due to the RGB mapping from 0-255 and the HSL mapping from 0-100 and 0-360 rounding errors may cause the HSL values to differ slightly from what you might expect. .. attribute:: hsva The HSVA representation of the Color. The HSVA components are in the ranges H = [0, 360], S = [0, 100], V = [0, 100], A = [0, 100]. Note that this will not return the absolutely exact HSV values for the set RGB values in all cases. Due to the RGB mapping from 0-255 and the HSV mapping from 0-100 and 0-360 rounding errors may cause the HSV values to differ slightly from what you might expect. .. attribute:: i1i2i3 The I1I2I3 representation of the Color. The I1I2I3 components are in the ranges I1 = [0, 1], I2 = [-0.5, 0.5], I3 = [-0.5, 0.5]. Note that this will not return the absolutely exact I1I2I3 values for the set RGB values in all cases. Due to the RGB mapping from 0-255 and the I1I2I3 from 0-1 rounding errors may cause the I1I2I3 values to differ slightly from what you might expect. .. method:: normalize() -> (float, float, float, float) Returns the normalised RGBA values of the Color as floating point values in the range [0, 1]. .. method:: __add__(self, color) -> Color __sub__(self, color) -> Color __mul__(self, color) -> Color __div__(self, color) -> Color __truediv__(self, color) -> Color __mod__(self, color) -> Color Basic arithmetic functions for :class:`Color` values. The arithmetic operations ``+, -, *, /, %`` are supported by the :class:`Color` class and work on a per-channel basis. This means, that the operation :: color = color1 + color2 is the same as :: color = Color() color.r = min(color1.r + color2.r, 255) color.g = min(color1.g + color2.g, 255) ... The operations guarantee that the channel values stay in the allowed range of [0, 255]. .. function:: argb_to_color(v : int) -> Color ARGB(v : int) -> Color Converts an integer value to a Color, assuming the integer represents a 32-bit ARGB value. .. function:: convert_to_color(v : object) -> Color COLOR(v : object) -> Color Tries to convert the passed value to a Color object. The value can be an arbitrary Python object, which is passed to the different other conversion functions. If one of them succeeds, the Color will be returned to the caller. If none succeeds, a :exc:`ValueError` will be raised. If the color is an integer value, it is assumed to be in ARGB layout. .. function:: rgba_to_color(v : int) -> Color RGBA(v : int) -> Color Converts an integer value to a Color, assuming the integer represents a 32-bit RGBA value. .. function:: is_rgb_color(v : object) -> bool Checks, if the passed value is an item that could be converted to a RGB color. .. function:: is_rgba_color(v : object) -> bool Checks, if the passed value is an item that could be converted to a RGBA color. .. function:: string_to_color(v : string) -> Color Converts a hex color string or color name to a Color value. Supported hex values are: * #RGB * #RGBA * #RRGGBB * #RRGGBBAA * 0xRGB * 0xRGBA * 0xRRGGBB * 0xRRGGBBAA PySDL2-0.9.3/doc/modules/sdl2ext_colorpalettes.rst0000644000000000000000000000242112260256443016725 0ustar .. module:: sdl2.ext.colorpalettes :synopsis: Predefined sets of colors. sdl2.ext.colorpalettes - predefined sets of colors ================================================== Indexed color palettes. Each palette is a tuple of :class:`sdl2.ext.Color` objects. The following palettes are currently available: ================== =================================================== Palette Identifier Description ================== =================================================== MONOPALETTE 1-bit monochrome palette (black and white). GRAY2PALETTE 2-bit grayscale palette with black, white and two shades of gray. GRAY4PALETTE 4-bit grayscale palette with black, white and 14 shades shades of gray. GRAY8PALETTE 8-bit grayscale palette with black, white and 254 shades shades of gray. RGB3PALETTE 3-bit RGB color palette with pure red, green and blue and their complementary colors as well as black and white. CGAPALETTE CGA color palette. EGAPALETTE EGA color palette. VGAPALETTE 8-bit VGA color palette. WEBPALETTE "Safe" web color palette with 225 colors. ================== =================================================== PySDL2-0.9.3/doc/modules/sdl2ext_common.rst0000644000000000000000000000204612260256443015340 0ustar .. currentmodule:: sdl2.ext Initialization routines ======================= TODO API --- .. exception:: SDLError(msg=None) An SDL2 specific :class:`Exception` class. if no *msg* is provided, the message will be set to the value of :func:`sdl2.error.SDL_GetError()` .. function:: init() -> None Initialises the underlying SDL2 video subsystem. Raises a :exc:`SDLError`, if the SDL2 video subsystem could not be initialised. .. function:: quit() -> None Quits the underlying SDL2 video subysystem. If no other SDL2 subsystems are active, this will also call :func:`quit()`, :func:`sdl2.sdlttf.TTF_Quit()` and :func:`sdl2.sdlimage.IMG_Quit()`. .. function:: get_events() -> [SDL_Event, SDL_Event, ...] Gets all SDL events that are currently on the event queue. .. class:: TestEventProcessor() A simple event processor for testing purposes. .. method:: run(window : Window) -> None Starts an event loop without actually processing any event. The method will run endlessly until a ``SDL_QUIT`` event occurs. PySDL2-0.9.3/doc/modules/sdl2ext_compat.rst0000644000000000000000000000464612323145036015336 0ustar .. module:: sdl2.ext.compat :synopsis: Python compatibility helpers. sdl2.ext.compat - Python compatibility helpers ============================================== The :mod:`sdl2.ext.compat` module is for internal purposes of the :mod:`sdl2` package and should not be used outside of the package. Classes, methods and interfaces might change between versions and there is no guarantee of API compatibility on different platforms and python implementations or between releases. .. data:: ISPYTHON2 ``True``, if executed in a Python 2.x compatible interpreter, ``False`` otherwise. .. data:: ISPYTHON3 ``True``, if executed in a Python 3.x compatible interpreter, ``False`` otherwise. .. function:: long([x[, base]]) .. note:: Only defined for Python 3.x, for which it is the same as :func:`int()`. .. function:: unichr(i) .. note:: Only defined for Python 3.x, for which it is the same as :func:`chr()`. .. function:: unicode(string[, encoding[, errors]]) .. note:: Only defined for Python 3.x, for which it is the same as :func:`str()`. .. function:: callable(x) -> bool .. note:: Only defined for Python 3.x, for which it is the same as ``isinstance(x, collections.Callable)`` .. function:: byteify(x : string, enc : string) -> bytes Converts a string to a :func:`bytes` object. .. function:: stringify(x : bytes, enc : string) -> string Converts a :func:`bytes` to a string object. .. function:: isiterable(x) -> bool Shortcut for ``isinstance(x, collections.Iterable)``. .. function:: platform_is_64bit() -> bool Checks, if the interpreter is 64-bit capable. .. decorator:: deprecated A simple decorator to mark functions and methods as deprecated. This will print a deprecation message each time the function or method is invoked. .. function:: deprecation(message : string) -> None Prints a deprecation message using the :func:`warnings.warn()` function. .. exception:: UnsupportedError(obj : object[, msg=None]) Indicates that a certain class, function or behaviour is not supported in the specific execution environment. .. decorator:: experimental A simple decorator to mark functions and methods as experimental. This will print a warning each time the function or method is invoked. .. exception:: ExperimentalWarning(obj : object[, msg=None]) Indicates that a certain class, function or behaviour is in an experimental state. PySDL2-0.9.3/doc/modules/sdl2ext_draw.rst0000644000000000000000000000340412312360676015006 0ustar .. currentmodule:: sdl2.ext 2D drawing routines for software surfaces ========================================= .. note:: The drawing functions within this module are unoptimised and should not be considered fast. If you want improved drawing of 2D primitives, including hardware acceleration, you should use the methods of the :class:`Renderer` instead. .. function:: prepare_color(color : object, target : object) -> int Prepares the passed *color* for a specific *target*. *color* can be any object type that can be processed by :func:`convert_to_color()`. *target* can be any :class:`sdl2.SDL_PixelFormat`, :class:`sdl2.SDL_Surface` or :class:`SoftwareSprite` instance. The returned integer will be a color value matching the target's pixel format. .. function:: fill(target : object, color : object[, area=None]) -> None Fills a certain area on the passed *target* with a *color*. If no *area* is provided, the entire target will be filled with the passed color. If an iterable item is provided as *area* (such as a list or tuple), it will be first checked, if the item denotes a single rectangular area (4 integer values) before assuming it to be a sequence of rectangular areas to fill with the color. *target* can be any :class:`sdl2.SDL_Surface` or :class:`SoftwareSprite` instance. .. function:: line(target : object, color : object[, width=1]) -> None Draws one or multiple lines on the passed *target*. *line* can be a sequence of four integers for a single line in the form ``(x1, y1, x2, y2)`` or a sequence of a multiple of 4 for drawing multiple lines at once, e.g. ``(x1, y1, x2, y2, x3, y3, x4, y4, ...)``. *target* can be any :class:`sdl2.SDL_Surface` or :class:`SoftwareSprite` instance. PySDL2-0.9.3/doc/modules/sdl2ext_ebs.rst0000644000000000000000000003705512260256443014631 0ustar .. currentmodule:: sdl2.ext .. _ref-ebs: Working with component-based entities ===================================== :mod:`sdl2.ext` supports a component oriented programming pattern to separate object instances, carried data and processing logic within applications or games. It uses an entity based approach, in which object instances are unique identifiers, while their data is managed within components, which are stored separately. For each individual component type a processing system will take care of all necessary updates on running the application. Component-based patterns ------------------------ Component-based means that - instead of a traditional OOP approach - object information are split up into separate data bags for reusability and that those data bags are separated from any application logic. Behavioural design ^^^^^^^^^^^^^^^^^^ Imagine a car class in traditional OOP, which might look like :: class Car: def __init__(self): self.color = "red" self.position = 0, 0 self.velocity = 0, 0 self.sprite = get_some_car_image() ... def drive(self, timedelta): self.position[0] = self.velocity[0] * timedelta self.position[1] = self.velocity[1] * timedelta ... def stop(self): self.velocity = 0, 0 ... def render(self, screen): screen.display(self.sprite) mycar = new Car() mycar.color = "green" mycar.velocity = 10, 0 The car features information stored in attributes (``color``, ``position``, ...) and behaviour (application logic, ``drive()``, ``stop()`` ...). A component-based approach aims to split and reduce the car to a set of information and external systems providing the application logic. :: class Car: def __init__(self): self.color = "red" self.position = 0, 0 self.velocity = 0, 0 self.sprite = get_some_car_image() class CarMovement: def drive(self, car, timedelta): car.position[0] = car.velocity[0] * timedelta car.position[1] = car.velocity[1] * timedelta ... def stop(self): car.velocity = 0, 0 class CarRenderer: def render(self, car, screen): screen.display(car.sprite) At this point of time, there is no notable difference between both approaches, except that the latter one adds additional overhead. The benefit comes in, when you * use subclassing in your OOP design * want to change behavioural patterns on a global scale or based on states * want to refactor code logic in central locations * want to cascade application behaviours The initial ``Car`` class from above defines, how it should be displayed on the screen. If you now want to add a feature for rescaling the screen size after the user activates the magnifier mode, you need to refactor the ``Car`` and all other classes that render things on the screen, have to consider all subclasses that override the method and so on. Refactoring the ``CarRenderer`` code by adding a check for the magnifier mode sounds quite simple in contrast to that, not? The same applies to the movement logic - inverting the movement logic requires you to refactor all your classes instead of a single piece of application code. Information design ^^^^^^^^^^^^^^^^^^ Subclassing with traditional OOP for behavioural changes also might bloat your classes with unnecessary information, causing the memory footprint for your application to rise without any need. Let's assume you have a ``Truck`` class that inherits from ``Car``. Let's further assume that all trucks in your application look the same. Why should any of those carry a ``sprite`` or ``color`` attribute? You would need to refactor your ``Car`` class to get rid of those superfluous information, adding another level of subclassing. If at a later point of time you decide to give your trucks different colors, you need to refactor everything again. Wouldn't it be easier to deal with colors, if they are available on the truck and leave them out, if they are not? We initially stated that the component-based approach aims to separate data (information) from code logic. That said, if the truck has a color, we can handle it easily, if it has not, we will do as usual. Also, checking for the color of an object (regardless, if it is a truck, car, aeroplane or death star) allows us to apply the same or similar behaviour for every object. If the information is available, we will process it, if it is not, we will not do anything. All in all ^^^^^^^^^^ Once we split up the previously OOP-style classes into pure data containers and some separate processing code for the behaviour, we are talking about components and (processing) systems. A component is a data container, ideally grouping related information on a granular level, so that it is easy to (re)use. When you combine different components to build your in-application objects and instantiate those, we are talking about entities. .. image:: images/ebs.png *Component* provides information (data bag) *Entity* In-application instance that consists of *component* items *System* Application logic for working with *Entity* items and their *component* data *World* The environment that contains the different *System* instances and all *Entity* items with their *component* data Within a strict COP design, the application logic (ideally) only knows about data to process. It does not know anything about entities or complex classes and only operates on the data. .. image:: images/copprocessing.png To keep things simple, modular and easy to maintain and change, you usually create small processing systems, which perform the necessary operations on the data they shall handle. That said, a ``MovementSystem`` for our car entity would only operate on the position and velocity component of the car entity. It does not know anything about the the car's sprite or sounds that the car makes, since *this is nothing it has to deal with*. To display the car on the screen, a ``RenderingSystem`` might pick up the sprite component of the car, maybe along with the position information (so it knows, where to place the sprite) and render it on the screen. If you want the car to play sounds, you would add an audio playback system, that can perform the task. Afterwards you can add the necessary audio information via a sound component to the car and it will make noise. Component-based design with sdl2.ext ------------------------------------ .. note:: This section will deal with the specialities of COP patterns and provide the bare minimum of information. If you are just starting with such a design, it is recommended to read through the :ref:`pong-tutorial` tutorial. :mod:`sdl2.ext` provides a :class:`World` class in which all other objects will reside. The :class:`World` will maintain both, :class:`Entity` and component items, and allows you to set up the processing logic via the :class:`System` and :class:`Applicator` classes. :: >>> appworld = World() Components can be created from any class that inherits from the :class:`object` type and represent the data bag of information for the entity and application world. Ideally, they should avoid any application logic (except from getter and setter properties). :: class Position2D(object): def __init__(self, x=0, y=0): self.x = x self.y = y :class:`Entity` objects define the in-application objects and only consist of component-based attributes. They also require a :class:`World` at object instantiation time. :: class CarEntity(Entity): def __init__(self, world, x=0, y=0): self.position2d = Position2D(x, y) .. note:: The *world* argument in ``__init__()`` is necessary. It will be passed to the internal ``__new__()`` constructor of the :class:`Entity` and stores a reference to the :class:`World` and also allows the :class:`Entity` to store its information in the :class:`World`. The :class:`Entity` also requries its attributes to be named exactly as their component class name, but in lowercase letters. If you name a component ``MyAbsolutelyAwesomeDataContainer``, an :class:`Entity` will force you to write the following: :: class SomeEntity(Entity): def __init__(self, world): self.myabsolutelyawesomedatacontainer = MyAbsolutelyAwesomeDataContainer() .. note:: This is not entirely true. A reference of the object will be stored on a per-class-in-mro basis. This means that if ``MyAbsolutelyAwesomeDataContainer`` inherits from ``ShortName``, you can also do: :: class SomeEntity(Entity): def __init__(self, world): self.shortname = MyAbsolutelyAwesomeDataContainer() Components should be as atomic as possible and avoid complex inheritance. Since each value of an :class:`Entity` is stored per class in its mro list, components inheriting from the same class(es) will overwrite each other on conflicting classes: :: class Vector(Position2D): def __init__(self, x=0, y=0, z=0): super(Vector, self).__init__(x, y) class SomeEntity(Entity): def __init__(self, world): # This will associate self.position2d with the new Position2D # value, while the previous Vector association is overwritten self.position2d = Position2D(4, 4) # self.vector will also associate a self.position2d attribute # with the Entity, since Vector inherits from Position2D. The # original association will vanish, and each call to # entity.position2d will effectively manipulate the vector! self.vector = Vector(1,2,3) API --- .. class:: Entity(world : World) An entity is a specific object living in the application world. It does not carry any data or application logic, but merely acts as identifier label for data that is maintained in the application world itself. As such, it is a composition of components, which would not exist without the entity identifier. The entity itself is non-existent to the application world as long as it does not carry any data that can be processed by a system within the application world. .. attribute:: id The id of the Entity. Every Entity has a unique id, that is represented by a :class:`uuid.UUID` instance. .. attribute:: world The :class:`World` the entity resides in. .. method:: delete() -> None Deletes the :class:`Entity` from its :class:`World`. This basically calls :meth:`World.delete()` with the :class:`Entity`. .. class:: Applicator() A processing system for combined data sets. The :class:`Applicator` is an enhanced :class:`System` that receives combined data sets based on its set :attr:`System.componenttypes` .. attribute:: is_applicator A boolean flag indicating that this class operates on combined data sets. .. attribute:: componenttypes A tuple of class identifiers that shall be processed by the :class:`Applicator`. .. function:: process(world : World, componentsets : iterable) Processes tuples of component items. *componentsets* will contain object tuples, that match the :attr:`componenttypes` of the :class:`Applicator`. If, for example, the :class:`Applicator` is defined as :: class MyApplicator(Applicator): def __init__(self): self.componenttypes = (Foo, Bar) its process method will receive ``(Foo, Bar)`` tuples :: def process(self, world, componentsets): for foo_item, bar_item in componentsets: ... Additionally, the :class:`Applicator` will not process all possible combinations of valid components, but only those, which are associated with the same :class:`Entity`. That said, an :class:`Entity` *must* contain a ``Foo`` as well as a ``Bar`` component in order to have them both processed by the :class:`Applicator` (while a :class:`System` with the same ``componenttypes`` would pick either of them, depending on their availability). .. class:: System() A processing system within an application world consumes the components of all entities, for which it was set up. At time of processing, the system does not know about any other component type that might be bound to any entity. Also, the processing system does not know about any specific entity, but only is aware of the data carried by all entities. .. attribute:: componenttypes A tuple of class identifiers that shall be processed by the :class:`System` .. method:: process(world : World, components : iterable) Processes component items. This method has to be implemented by inheriting classes. .. class:: World() An application world defines the combination of application data and processing logic and how the data will be processed. As such, it is a container object in which the application is defined. The application world maintains a set of entities and their related components as well as a set of systems that process the data of the entities. Each processing system within the application world only operates on a certain set of components, but not all components of an entity at once. The order in which data is processed depends on the order of the added systems. .. attribute:: systems The processing system objects bound to the world. .. method:: add_system(system : object) Adds a processing system to the world. The system will be added as last item in the processing order. The passed system does not have to inherit from :class:`System`, but must feature a ``componenttypes`` attribute and a ``process()`` method, which match the signatures of the :class:`System` class :: class MySystem(object): def __init__(self): # componenttypes can be any iterable as long as it # contains the classes the system should take care of self.componenttypes = [AClass, AnotherClass, ...] def process(self, world, components): ... If the system shall operate on combined component sets as specified by the :class:`Applicator`, the class instance must contain a ``is_applicator`` property, that evaluates to ``True`` :: class MyApplicator(object): def __init__(self): self.is_applicator = True self.componenttypes = [...] def process(self, world, components): pass The behaviour can be changed at run-time. The ``is_applicator`` attribute is evaluated for every call to :meth:`World.process()`. .. method:: delete(entity : Entity) Removes an :class:`Entity` from the World, including all its component data. .. method:: delete_entities(entities : iterable) Removes a set of :class:`Entity` instances from the World, including all their component data. .. method:: insert_system(index : int, system : System) Adds a processing :class:`System` to the world. The system will be added at the specified position in the processing order. .. method:: get_entities(component : object) -> [Entity, ...] Gets the entities using the passed component. .. note:: This will not perform an identity check on the component but rely on its ``__eq__`` implementation instead. .. method:: process() Processes all component items within their corresponding :class:`System` instances. .. method:: remove_system(system : System) Removes a processing :class:`System` from the world. PySDL2-0.9.3/doc/modules/sdl2ext_events.rst0000644000000000000000000000543012260256443015354 0ustar .. currentmodule:: sdl2.ext General purpose event handling routines ======================================= .. class:: EventHandler(sender) A simple event handling class, which manages callbacks to be executed. The EventHandler does not need to be kept as separate instance, but is mainly intended to be used as attribute in event-aware class objects. :: >>> def myfunc(sender): ... print("event triggered by %s" % sender) ... >>> class MyClass(object): ... def __init__(self): ... self.anevent = EventHandler(self) ... >>> myobj = MyClass() >>> myobj.anevent += myfunc >>> myobj.anevent() event triggered by <__main__.MyClass object at 0x801864e50> .. attribute:: callbacks A list of callbacks currently bound to the :class:`EventHandler`. .. attribute:: sender The responsible object that executes the :class:`EventHandler`. .. method:: add(callback : Callable) Adds a callback to the :class:`EventHandler`. .. method:: remove(callback : Callable) Removes a callback from the :class:`EventHandler`. .. method:: __call__(*args) -> [ ... ] Executes all connected callbacks in the order of addition, passing the :attr:`sender` of the :class:`EventHandler` as first argument and the optional args as second, third, ... argument to them. This will return a list containing the return values of the callbacks in the order of their execution. .. class:: MPEventHandler(sender) An asynchronous event handling class based on :class:`EventHandler`, in which callbacks are executed in parallel. It is the responsibility of the caller code to ensure that every object used maintains a consistent state. The :class:`MPEventHandler` class will not apply any locks, synchronous state changes or anything else to the arguments or callbacks being used. Consider it a "fire-and-forget" event handling strategy. .. note:: The :class:`MPEventHandler` relies on the :mod:`multiprocessing` module. If the module is not available in the target environment, a :exc:`sdl2.ext.compat.UnsupportedError` is raised. Also, please be aware of the restrictions that apply to the :mod:`multiprocessing` module; arguments and callback functions for example have to be pickable, etc. .. method:: __call__(*args) -> AsyncResult Executes all connected callbacks within a :class:`multiprocessing.pool.Pool`, passing the :attr:`sender` as first argument and the optional *args* as second, third, ... argument to them. This will return a :class:`multiprocessing.pool.AsyncResult` containing the return values of the callbacks in the order of their execution. PySDL2-0.9.3/doc/modules/sdl2ext_font.rst0000644000000000000000000000734612260256443015026 0ustar .. currentmodule:: sdl2.ext Text rendering routines ======================= .. class:: BitmapFont(surface : Sprite, size : iterable[, mapping=None) A bitmap graphics to character mapping. The :class:`BitmapFont` class uses an image *surface* to find and render font character glyphs for text. It requires a mapping table, which denotes the characters available on the image. The mapping table is a list of strings, where each string reflects a *line* of characters on the image. Each character within each line has the same size as specified by the size argument. A typical mapping table might look like :: [ '0123456789', 'ABCDEFGHIJ', 'KLMNOPQRST', 'UVWXYZ ', 'abcdefghij', 'klmnopqrst', 'uvwxyz ', ',;.:!?+-()' ] .. attribute:: surface The :class:`sdl2.SDL_Surface` containing the character bitmaps. .. attribute:: offsets A dict containing the character offsets on the :attr:`surface`. .. attribute:: mapping The character mapping table, a list of strings. .. attribute:: size The size of an individual glyph bitmap on the font. .. method:: render(text : string[, bpp=None]) -> Sprite Renders the passed text on a new :class:`Sprite` and returns it. If no explicit *bpp* are provided, the bpp settings of the :attr:`.surface` are used. .. method:: render_on(surface : Sprite, text : string[, \ offset=(0, 0)]) -> (int, int, int, int) Renders a text on the passed sprite, starting at a specific offset. The top-left start position of the text will be the passed *offset* and a 4-value tuple with the changed area will be returned. .. method:: contains(c : string) -> bool Checks, whether a certain character exists in the font. .. method:: can_render(text : string) -> bool Checks, whether all characters in the passed *text* can be rendered. .. class:: FontManager(font_path : str[, alias=None[, size=16[, color=Color(255, 255, 255)[, bg_color=Color(0, 0, 0)]]]]) Manage fonts and rendering of text. One font path must be given to initialise the FontManager. :attr:`default_font` will be set to this font. *size* is the default font size in pixels. *color* and *bg_color* will give the FontManager a default color. .. attribute:: bg_color The :class:`sdl2.ext.Color` to be used as background color. .. attribute:: color The :class:`sdl2.ext.Color` to be used for rendering text. .. attribute:: default_font Returns the name of the current default font being used by the :class:`FontManager`. On assigning :attr:`default_font`, the value must be a loaded font alias. .. attribute:: size The default font size in pixels. .. method:: add(font_path : str[, alias=None[, size=None]]) -> sdl2.sdlttf.TTF_Font Add a font to the :class:`FontManager`. *alias* is by default the font name, any other name can be passed, *size* is the font size in pixels and defaults to :attr:`size`. Returns the font pointer stored in :attr:`fonts`. .. method:: close() Closes all fonts used by the :class:`FontManager`. .. method:: render(text : str[, alias=None[, size=None[, width=None[, color=None[, bg_color=None[, **kwargs]]]]]]) -> sdl2.SDL_Surface Renders text to a surface. This method uses the font designated by the passed *alias* or, if *alias* is omitted, by the set :attr:`default_font`. A *size* can be passed even if the font was not loaded with this size. A *width* can be given for automatic line wrapping. If no *bg_color* or *color* are given, it will default to the FontManager's :attr:`bg_color` and :attr:`color`. PySDL2-0.9.3/doc/modules/sdl2ext_gui.rst0000644000000000000000000002515112260256443014636 0ustar .. currentmodule:: sdl2.ext User interface elements ======================= User interface elements within :mod:`sdl2.ext` are simple :class:`Sprite` objects, which are enhanced by certain input hooks; as such, they are not classes on their own, but implemented as mixins. The user input itself is handled by an :class:`UIProcessor` object, which takes care of delegating input events, such as mouse movements, clicks and keyboard input, to the correct UI element. Depending on the event type (e.g. pressing a mouse button), the UIProcessor will execute its matching method (e.g. ``mousedown()``) with only those UI elements, which support the event type. .. image:: images/uiprocessing.png .. _ui-elem-types: UI element types ---------------- Every :class:`sdl2.ext` UI element is a simple :class:`Sprite` object, to which additional attributes and methods are bound. Every UI element features the following attributes ``element.uitype`` The ``uitype`` attribute can have one of the following values, identifying the UI element: * ``BUTTON`` - a UI element, which can react on mouse input * ``CHECKBUTTON`` - as ``BUTTON``, but it retains its state on clicks * ``TEXTENTRY`` - a UI element that reacts on keyboard input ``element.events`` A dictionary containing the SDL2 event mappings. Each supported SDL2 event (e.g. ``SDL_MOUSEMOTION``) is associated with a bound :class:`EventHandler` acting as callback for user code (e.g. ``mousemotion()``). Depending on the exact type of the element, it will feature additional methods and attributes explained below. Button elements ^^^^^^^^^^^^^^^ ``BUTTON`` UI elements feature a ``state`` attribute, which can be one of the following values. ======== ===================================================================== state Description ======== ===================================================================== RELEASED Indicates that the UI element is not pressed. HOVERED Indicates that the mouse cursor is currently hovering the UI element. PRESSED Indicates that a mouse button is pressed on the UI element. ======== ===================================================================== ``BUTTON`` UI elements react with the following event handlers on events: ``button.motion(event : sdl2.events.SDL_Event)`` An :class:`EventHandler` that is invoked, if the mouse moves around while being over the ``BUTTON``. ``button.pressed(event : sdl2.events.SDL_Event)`` An :class:`EventHandler` that is invoked, if a mouse button is pressed on the ``BUTTON``. ``button.released(event : sdl2.events.SDL_Event)`` An :class:`EventHandler` that is invoked, if a mouse button is released on the ``BUTTON``. ``button.click(event : sdl2.events.SDL_Event)`` An :class:`EventHandler` that is invoked, if a mouse button is pressed and released on the ``BUTTON``. Besides the ``BUTTON`` a special ``CHECKBUTTON`` UI element type exists, which enhances the ``BUTTON`` bindings by an additional ``checked`` attribute. The ``checked`` attribute switches its status (``False`` to ``True`` and ``True`` to ``False``) every time the UI element is clicked. Text input elements ^^^^^^^^^^^^^^^^^^^ ``TEXTENTRY`` elements react on text input, once they are activated. Text being input, once a ``TEXTENTRY`` has been activated, is stored in its ``text`` attribute. The ``TEXTENTRY`` reacts with the following event handlers on events: ``textentry.motion(event : sdl2.events.SDL_Event)`` An :class:`EventHandler` that is invoked, if the mouse moves around while being over the ``TEXTENTRY``. ``textentry.pressed(event : sdl2.events.SDL_Event)`` An :class:`EventHandler` that is invoked, if a mouse button is pressed on the ``TEXTENTRY``. ``textentry.released(event : sdl2.events.SDL_Event)`` An :class:`EventHandler` that is invoked, if a mouse button is released on the ``TEXTENTRY``. ``textentry.keydown(event : sdl2.events.SDL_Event)`` An :class:`EventHandler` that is invoked on pressing a key. ``textentry.keyup(event : sdl2.events.SDL_Event)`` An :class:`EventHandler` that is invoked on releasing a key. ``textentry.input(event : sdl2.events.SDL_Event)`` An :class:`EventHandler` that is invoked on text input events. Text input events are automatically created, once the :class:`UIProcessor` activates a ``TEXTENTRY`` UI element. ``textentry.editing(event : sdl2.events.SDL_Event)`` An :class:`EventHandler` that is invoked on text editing events. Text editing events are automatically created, once the :class:`UIProcessor` activates a ``TEXTENTRY`` UI element. Text editing events are however only raised, if an IME system is involved, which combines glyphs and symbols to characters or word fragments. API --- .. class:: UIFactory(spritefactory : SpriteFactory[, **kwargs]) A factory class for creating UI elements. The :class:`UIFactory` allows you to create UI elements based on the :class:`Sprite` class. To do this, it requires a :class:`SpriteFactory`, which will create the sprites, to which the :class:`UIFactory` then binds the additional methods and attributes. The additional *kwargs* are used as default arguments for creating **sprites** within the factory methods. .. attribute:: default_args A dictionary containing the default arguments to be passed to the sprite creation methods of the bound :class:`SpriteFactory`. .. attribute:: spritefactory The :class:`SpriteFactory` being used for creating new :class:`Sprite` objects. .. method:: create_button(**kwargs) -> Sprite Creates a new button UI element. *kwargs* are the arguments to be passed for the sprite construction and can vary depending on the sprite type. See :meth:`SpriteFactory.create_sprite()` for further details. .. method:: create_check_button(**kwargs) -> Sprite Creates a new checkbutton UI element. *kwargs* are the arguments to be passed for the sprite construction and can vary depending on the sprite type. See :meth:`SpriteFactory.create_sprite()` for further details. .. method:: create_text_entry(**kwargs) -> Sprite Creates a new textentry UI element. *kwargs* are the arguments to be passed for the sprite construction and can vary depending on the sprite type. See :meth:`SpriteFactory.create_sprite()` for further details. .. method:: from_color(color : object , size) -> Sprite Creates a UI element with a specific color. *uitype* must be one of the supported :ref:`ui-elem-types` classifying the type of UI element to be created. .. method:: from_image(uitype : int, fname : str) -> Sprite Creates a UI element from an image file. The image must be loadable via :func:`load_image()`. *uitype* must be one of the supported :ref:`ui-elem-types` classifying the type of UI element to be created. .. method:: from_object(uitype : int, obj: object) -> Sprite Creates a UI element from an object. The object will be passed through :func:`sdl2.rwops_from_object()` in order to try to load image data from it. *uitype* must be one of the supported :ref:`ui-elem-types` classifying the type of UI element to be created. .. method:: from_surface(uitype : int, surface : SDL_Surface[, free=False]) -> Sprite Creates a UI element from the passed :class:`sdl2.surface.SDL_Surface`. If *free* is set to ``True``, the passed *surface* will be freed automatically. *uitype* must be one of the supported :ref:`ui-elem-types` classifying the type of UI element to be created. .. class:: UIProcessor() A processing system for user interface elements and events. .. attribute:: handlers A dict containing the mapping of SDL2 events to the available :class:`EventHandler` bindings of the :class:`UIProcessor`. .. method:: activate(component : object) -> None Activates a UI control to receive text input. .. method:: deactivate(component : object) -> None Deactivate the currently active UI control. .. method:: passevent(component : object, event : SDL_Event) -> None Passes the *event* to a *component* without any additional checks or restrictions. .. method:: mousemotion(component : object, event : SDL_Event) -> None Checks, if the event's motion position is on the *component* and executes the component's event handlers on demand. If the motion event position is not within the area of the *component*, nothing will be done. In case the component is a ``BUTTON``, its :attr:`state` will be adjusted to reflect, if it is currently hovered or not. .. method:: mousedown(component : object, event : SDL_Event) -> None Checks, if the event's button press position is on the *component* and executes the component's event handlers on demand. If the button press position is not within the area of the component, nothing will be done. In case the component is a ``BUTTON``, its :attr:`state` will be adjusted to reflect, if it is currently pressed or not. In case the component is a ``TEXTENTRY`` and the pressed button is the primary mouse button, the component will be marked as the next control to activate for text input. .. method:: mouseup(self, component, event) -> None Checks, if the event's button release position is on the *component* and executes the component's event handlers on demand. If the button release position is not within the area of the component, nothing will be done. In case the component is a ``BUTTON``, its :attr:`state` will be adjusted to reflect, whether it is hovered or not. If the button release followed a button press on the same component and if the button is the primary button, the ``click()`` event handler is invoked, if the component is a ``BUTTON``. .. method:: dispatch(obj : object, event : SDL_Event) -> None Passes an event to the given object. If *obj* is a :class:`World` object, UI relevant components will receive the event, if they support the event type. If *obj* is a single object, ``obj.events`` **must** be a dict consisting of SDL event type identifiers and :class:`EventHandler` instances bound to the object. If *obj* is a iterable, such as a list or set, every item within *obj* **must** feature an ``events`` attribute as described above. .. method:: process(world : World, components : iterable) -> None The :class:`UIProcessor` class does not implement the `process()` method by default. Instead it uses :meth:`dispatch()` to send events around to components. :meth:`process()` does nothing. PySDL2-0.9.3/doc/modules/sdl2ext_image.rst0000644000000000000000000000170512326665315015140 0ustar .. currentmodule:: sdl2.ext Image loaders ============= .. function:: get_image_formats() -> (str, str, ...) Gets the formats supported by PySDL2 in the default installation. .. function:: load_image(fname : str[, enforce=None]) -> sdl2.SDL_Surface Creates a :class:`sdl2.SDL_Surface` from an image file. This function makes use of the `Python Imaging Library `_, if it is available on the target execution environment. The function will try to load the file via :mod:`sdl2` first. If the file could not be loaded, it will try to load it via :mod:`sdl2.sdlimage` and PIL. You can force the function to use only one of them, by passing the *enforce* as either ``"PIL"`` or ``"SDL"``. .. note:: This will call :func:`sdl2.sdlimage.IMG_Init()` implicitly with the default arguments, if the module is available and if :func:`sdl2.SDL_LoadBMP()` failed to load the image. PySDL2-0.9.3/doc/modules/sdl2ext_particles.rst0000644000000000000000000000610212260256443016033 0ustar .. module:: sdl2.ext.particles :synopsis: A simple particle system. sdl2.ext.particles - A simple particle system ============================================= .. class:: ParticleEngine() A simple particle processing system. The :class:`ParticleEngine` takes care of creating, updating and deleting particles via callback functions. It only decreases the life of the particles by itself and marks them as dead, once the particle's life attribute has reached 0 or below. .. attribute:: createfunc Function for creating new particles. The function needs to take two arguments, the ``world`` argument passed to :meth:`process()` and a list of the particles considered dead (:attr:`Particle.life` <= 0). :: def creation_func(world, deadparticles): ... .. attribute:: updatefunc Function for updating existing, living particles. The function needs to take two arguments, the ``world`` argument passed to :meth:`process()` and a :class:`set` of the still living particles. :: def update_func(world, livingparticles): ... .. attribute:: deletefunc Function for deleting dead particles. The function needs to take two arguments, the ``world`` argument passed to :meth:`process()` and a list of the particles considered dead (:attr:`Particle.life` <= 0). :: def deletion_func(world, deadparticles): ... .. method:: process(world : World, components : iterable) -> None Processes all particle components, decreasing their life by 1. Once the life of all particle components has been decreased properly and the particles considered dead (life <= 0) are identified, the creation, update and deletion callbacks are invoked. The creation callback takes the passed world as first and the list of dead particles as second argument. :: def particle_createfunc(world, list_of_dead_ones): ... Afterwards the still living particles are passed to the update callback, which also take the passed world as first and the living particles as set as second argument. :: def particle_updatefunc(world, set_of_living_ones): ... Finally, the dead particles need to be deleted in some way or another, which is done by the deletion callback, taking the passed world as first and the list of dead particles as second argument. :: def particle_deletefunc(world, list_of_dead_ones): ... .. class:: Particle(x, y, life : int) A simple particle component type. It only contains information about a x- and y-coordinate and its current life time. The life time will be decreased by 1, every time the particle is processed by the :class:`ParticleEngine`. .. attribute:: x The x coordinate of the particle. .. attribute:: y The y coordinate of the particle. .. attribute:: life The remaining life time of the particle. .. attribute:: position The x- and y-coordinate of the particle as tuple. PySDL2-0.9.3/doc/modules/sdl2ext_pixelaccess.rst0000644000000000000000000000404012260256443016347 0ustar .. currentmodule:: sdl2.ext 2D and 3D direct pixel access ============================= .. class:: PixelView(source : object) 2D :class:`MemoryView` for :class:`SoftwareSprite` and :class:`sdl2.SDL_surface` pixel access. .. note:: If necessary, the *source* surface will be locked for accessing its pixel data. The lock will be removed once the :class:`PixelView` is garbage-collected or deleted. The :class:`PixelView` uses a y/x-layout. Accessing ``view[N]`` will operate on the Nth row of the underlying surface. To access a specific column within that row, ``view[N][C]`` has to be used. .. note:: :class:`PixelView` is implemented on top of the :class:`MemoryView` class. As such it makes heavy use of recursion to access rows and columns and can be considered as slow in contrast to optimised ndim-array solutions such as :mod:`numpy`. .. function:: pixels2d(source : object) Creates a 2D pixel array, based on ``numpy.ndarray``, from the passed *source*. *source* can be a :class:`SoftwareSprite` or :class:`sdl2.SDL_Surface`. The ``SDL_Surface`` of the *source* will be locked and unlocked automatically. The *source* pixels will be accessed and manipulated directly. .. note:: :func:`pixels2d` is only usable, if the numpy package is available within the target environment. If numpy could not be imported, a :exc:`sdl2.ext.compat.UnsupportedError` will be raised. .. function:: pixels3d(source : object) Creates a 3D pixel array, based on ``numpy.ndarray``, from the passed *source*. *source* can be a :class:`SoftwareSprite` or :class:`sdl2.SDL_Surface`. The ``SDL_Surface`` of the *source* will be locked and unlocked automatically. The *source* pixels will be accessed and manipulated directly. .. note:: :func:`pixels3d` is only usable, if the numpy package is available within the target environment. If numpy could not be imported, a :exc:`sdl2.ext.compat.UnsupportedError` will be raised. PySDL2-0.9.3/doc/modules/sdl2ext_resources.rst0000644000000000000000000001544412260256443016070 0ustar .. currentmodule:: sdl2.ext Resource management =================== Every application usually ships with various resources, such as image and data files, configuration files and so on. Accessing those files in the folder hierarchy or in a bundled format for various platforms can become a complex task. The :class:`Resources` class allows you to manage different application data in a certain directory, providing a dictionary-style access functionality for your in-application resources. Let's assume, your application has the following installation layout :: Application Directory Application.exe Application.conf data/ background.jpg button1.jpg button2.jpg info.dat Within the ``Application.exe`` code, you can - completely system-agnostic - define a new resource that keeps track of all ``data`` items. :: apppath = os.path.dirname(os.path.abspath(__file__)) appresources = Resources(os.path.join(apppath, "data")) # Access some images bgimage = appresources.get("background.jpg") btn1image = appresources.get("button1.jpg") ... To access individual files, you do not need to concat paths the whole time and regardless of the current directory, your application operates on, you can access your resource files at any time through the :class:`Resources` instance, you created initially. The :class:`Resources` class is also able to scan an index archived files, compressed via ZIP or TAR (gzip or bzip2 compression), and subdiectories automatically. :: Application Directory Application.exe Application.conf data/ audio/ example.wav background.jpg button1.jpg button2.jpg graphics.zip [tileset1.bmp tileset2.bmp tileset3.bmp ] info.dat tilesimage = appresources.get("tileset1.bmp") audiofile = appresources.get("example.wav") If you request an indexed file via :meth:`Resources.get`, you will receive a :class:`io.BytesIO` stream, containing the file data, for further processing. .. note:: The scanned files act as keys within the :class:`Resources` class. This means that two files, that have the same name, but are located in different directories, will not be indexed. Only one of them will be accessible through the :class:`Resources` class. API --- .. class:: Resources([path=None[, subdir=None[, excludepattern=None]]]) The Resources class manages a set of file resources and eases accessing them by using relative paths, scanning archives automatically and so on. .. method:: add(filename : string) Adds a file to the resource container. Depending on the file type (determined by the file suffix or name) the file will be automatically scanned (if it is an archive) or checked for availability (if it is a stream or network resource). .. method:: add_archive(filename : string[, typehint="zip"]) Adds an archive file to the resource container. This will scan the passed archive and add its contents to the list of available and accessible resources. .. method:: add_file(filename : string) Adds a file to the resource container. This will only add the passed file and do not scan an archive or check the file for availability. .. method:: get(filename : string) -> BytesIO Gets a specific file from the resource container. Raises a :exc:`KeyError`, if the *filename* could not be found. .. method:: get_filelike(filename : string) -> file object Similar to :meth:`get()`, but tries to return the original file handle, if possible. If the found file is only available within an archive, a :class:`io.BytesIO` instance will be returned. Raises a :exc:`KeyError`, if the *filename* could not be found. .. method:: get_path(filename : string) -> string Gets the path of the passed *filename*. If *filename* is only available within an archive, a string in the form ``filename@archivename`` will be returned. Raises a :exc:`KeyError`, if the *filename* could not be found. .. method:: scan(path : string[, subdir=None[, excludepattern=None]) Scans a path and adds all found files to the resource container. If a file within the path is a supported archive (ZIP or TAR), its contents will be indexed aut added automatically. The method will consider the directory part (``os.path.dirname``) of the provided *path* as path to scan, if the path is not a directory. If *subdir* is provided, it will be appended to the path and used as starting point for adding files to the resource container. *excludepattern* can be a regular expression to skip directories, which match the pattern. .. function:: open_tarfile(archive : string, filename : string \ [, directory=None[, ftype=None]]) -> BytesIO Opens and reads a certain file from a TAR archive. The result is returned as :class:`BytesIO` stream. *filename* can be a relative or absolute path within the TAR archive. The optional *directory* argument can be used to supply a relative directory path, under which *filename* will be searched. *ftype* is used to supply additional compression information, in case the system cannot determine the compression type itself, and can be either **"gz"** for gzip compression or **"bz2"** for bzip2 compression. If the filename could not be found or an error occurred on reading it, ``None`` will be returned. Raises a :exc:`TypeError`, if *archive* is not a valid TAR archive or if *ftype* is not a valid value of ("gz", "bz2"). .. note:: If *ftype* is supplied, the compression mode will be enforced for opening and reading. .. function:: open_url(filename : string[, basepath=None]) -> file object Opens and reads a certain file from a web or remote location. This function utilizes the :mod:`urllib2` module for Python 2.7 and :mod:`urllib` for Python 3.x, which means that it is restricted to the types of remote locations supported by the module. *basepath* can be used to supply an additional location prefix. .. function:: open_zipfile(archive : string, filename : string \ [, directory : string]) -> BytesIO Opens and reads a certain file from a ZIP archive. The result is returned as :class:`BytesIO` stream. *filename* can be a relative or absolute path within the ZIP archive. The optional *directory* argument can be used to supply a relative directory path, under which *filename* will be searched. If the filename could not be found, a :exc:`KeyError` will be raised. Raises a :exc:`TypeError`, if *archive* is not a valid ZIP archive. PySDL2-0.9.3/doc/modules/sdl2ext_sprite.rst0000644000000000000000000003156612326374103015364 0ustar .. currentmodule:: sdl2.ext Sprite, texture and pixel surface routines ========================================== .. data:: TEXTURE Indicates that texture-based rendering or sprite creation is wanted. .. data:: SOFTWARE Indicates that software-based rendering or sprite creation is wanted. .. class:: Sprite() A simple 2D object, implemented as abstract base class. .. attribute:: x The top-left horizontal offset at which the :class:`Sprite` resides. .. attribute:: y The top-left vertical offset at which the :class:`Sprite` resides. .. attribute:: position The top-left position (:attr:`x` and :attr:`y`) as tuple. .. attribute:: size The width and height of the :class:`Sprite` as tuple. .. note:: This is an abstract property and needs to be implemented by inheriting classes. .. attribute:: area The rectangular area occupied by the :class:`Sprite`. .. attribute:: depth The layer depth on which to draw the :class:`Sprite`. :class:`Sprite` objects with higher :attr:`depth` values will be drawn on top of other :class:`Sprite` values by the :class:`SpriteRenderSystem`. .. class:: SoftwareSprite() A simple, visible, pixel-based 2D object, implemented on top of SDL2 software surfaces. .. attribute:: surface The :class:`sdl2.SDL_Surface` containing the pixel data. .. attribute:: size The size of the :class:`SoftwareSprite` as tuple. .. method:: subsprite(area : (int, int, int, int)) -> SoftwareSprite Creates another :class:`SoftwareSprite` from a part of the :class:`SoftwareSprite`. The two sprites share pixel data, so if the parent sprite's surface is not managed by the sprite (``free`` is False), you will need to keep it alive while the subsprite exists. .. class:: TextureSprite() A simple, visible, pixel-based 2D object, implemented on top of SDL2 textures. .. attribute:: size The size of the :class:`TextureSprite` as tuple. .. attribute:: texture The :class:`sdl2.SDL_Texture` containing the texture data. .. class:: SpriteRenderSystem() A rendering system for :class:`Sprite` components. This is a base class for rendering systems capable of drawing and displaying :class:`Sprite` based objects. Inheriting classes need to implement the rendering capability by overriding the render() method. .. attribute:: sortfunc Sort function for the component processing order. The default sort order is based on the depth attribute of every sprite. Lower depth values will cause sprites to be drawn below sprites with higher depth values. If :attr:`sortfunc` shall be overridden, it must match the callback requirements for :func:`sorted()`. .. method:: process(world : World, components : iterable) -> None Renders the passed :class:`Sprite` objects via the :meth:`render()` method. The :class:`Sprite` objects are sorted via :attr:`sortfunc` before they are passed to :meth:`render()`. .. method:: render(sprite : iterable) -> None Renders the :class:`Sprite` objects. .. note:: This is a no-op function and needs to be implemented by inheriting classes. .. class:: SoftwareSpriteRenderSystem(window : object) A rendering system for :class:`SoftwareSprite` components. The :class:`SoftwareSpriteRenderSystem` class uses a :class:`sdl2.SDL_Window` as drawing device to display :class:`SoftwareSprite` surfaces. It uses the internal SDL surface of the *window* as drawing context, so that GL operations, such as texture handling or the usage of SDL renderers is not possible. *window* can be either a :class:`sdl2.ext.Window` or :class:`sdl2.SDL_Window` instance. .. attribute:: window The :class:`sdl2.SDL_Window` that is used as drawing device. .. attribute:: surface The :class:`sdl2.SDL_Surface` that acts as drawing context for :attr:`window`. .. method:: render(sprites : object[, x=None[, y=None]]) -> None Draws the passed *sprites* on the :class:`sdl2.ext.Window` surface. *x* and *y* are optional arguments that can be used as relative drawing location for *sprites*. If set to ``None``, the location information of the *sprites* are used. If set and *sprites* is an iterable, such as a list of :class:`SoftwareSprite` objects, *x* and *y* are relative location values that will be added to each individual sprite's position. If *sprites* is a single :class:`SoftwareSprite`, *x* and *y* denote the absolute position of the :class:`SoftwareSprite`, if set. .. class:: TextureSpriteRenderSystem(target : object) A rendering system for :class:`TextureSprite` components. The :class:`TextureSpriteRenderSystem` class uses a :class:`sdl2.SDL_Renderer` as drawing device to display :class:`Sprite` surfaces. *target* can be a :class:`sdl2.ext.Window`, :class:`sdl2.SDL_Window`, a:class:`sdl2.ext.Renderer` or a :class:`sdl2.SDL_Renderer`. If it is a :class:`sdl2.ext.Window` or :class:`sdl2.SDL_Window` instance, it will try to create a :class:`sdl2.SDL_Renderer` with hardware acceleration for it. .. attribute:: sdlrenderer The :class:`sdl2.SDL_Renderer` that is used as drawing context. .. attribute:: rendertarget The target for which the :attr:`renderer` was created, if any. .. method:: render(sprites : object[, x=None[, y=None]]) -> None Renders the passed *sprites* via the :attr:`renderer`. *x* and *y* are optional arguments that can be used as relative drawing location for *sprites*. If set to ``None``, the location information of the *sprites* are used. If set and *sprites* is an iterable, such as a list of :class:`TextureSprite` objects, *x* and *y* are relative location values that will be added to each individual sprite's position. If *sprites* is a single :class:`TextureSprite`, *x* and *y* denote the absolute position of the :class:`TextureSprite`, if set. .. class:: SpriteFactory(sprite_type=TEXTURE, **kwargs) A factory class for creating :class:`Sprite` objects. The :class:`SpriteFactory` can create :class:`TextureSprite` or :class:`SoftwareSprite` instances, depending on the *sprite_type* being passed to it, which can be ``SOFTWARE`` or ``TEXTURE``. The additional *kwargs* are used as default arguments for creating sprites within the factory methods. .. attribute:: sprite_type The sprite type created by the factory. This will be either ``SOFTWARE`` for :class:`SoftwareSprite` or ``TEXTURE`` for :class:`TextureSprite` objects. .. attribute:: default_args The default arguments to use for creating new sprites. .. method:: create_software_sprite(size, bpp=32, masks=None) -> SoftwareSprite Creates a software sprite. A *size* tuple containing the width and height of the sprite and a *bpp* value, indicating the bits per pixel to be used, need to be provided. .. method:: create_sprite(**kwargs) -> Sprite Creates a :class:`Sprite`. Depending on the :attr:`sprite_type`, this will return a :class:`SoftwareSprite` or :class:`TextureSprite`. *kwargs* are the arguments to be passed for the sprite construction and can vary depending on the sprite type. Usually they have to follow the :meth:`create_software_sprite()` and :meth:`create_texture_sprite()` method signatures. *kwargs* however will be mixed with the set :attr:`default_args` so that one does not necessarily have to provide all arguments, if they are set within the :attr:`default_args`. If *kwargs* and :attr:`default_args` contain the same keys, the key-value pair of *kwargs* is chosen. .. method:: create_sprite_render_system(*args, **kwargs) -> SpriteRenderSystem Creates a new :class:`SpriteRenderSystem`, based on the set :attr:`sprite_type`. If :attr:`sprite_type` is ``TEXTURE``, a :class:`TextureSpriteRenderSystem` is created with the the ``renderer`` from the :attr:`default_args`. Other keyword arguments are ignored in that case. Otherwise a :class:`SoftwareSpriteRenderSystem` is created and *args* and *kwargs* are passed to it. .. method:: create_texture_sprite(renderer : object, size, pformat=sdl2.SDL_PIXELFORMAT_RGBA8888, access=sdl2.SDL_TEXTUREACCESS_STATIC) -> TextureSprite Creates a texture sprite. A *size* tuple containing the width and height of the sprite needs to be provided. :class:`TextureSprite` objects are assumed to be static by default, making it impossible to access their pixel buffer in favour for faster copy operations. If you need to update the pixel data frequently or want to use the texture as target for rendering operations, *access* can be set to the relevant SDL_TEXTUREACCESS_* flag. .. method:: from_color(color : object , size, bpp=32, masks=None) -> Sprite Creates a :class:`Sprite` with a certain color. .. method:: from_image(fname : str) -> Sprite Creates a :class:`Sprite` from an image file. The image must be loadable via :func:`sdl2.ext.load_image()`. .. method:: from_object(obj: object) -> Sprite Creates a :class:`Sprite` from an object. The object will be passed through :func:`sdl2.rwops_from_object()` in order to try to load image data from it. .. method:: from_surface(surface : SDL_Surface[, free=False]) -> Sprite Creates a :class:`Sprite` from the passed :class:`sdl2.SDL_Surface`. If *free* is set to ``True``, the passed *surface* will be freed automatically. .. method:: from_text(text : str[, **kwargs]) -> Sprite Creates a :class:`Sprite` from a string of text. This method requires a :class:`sdl2.ext.FontManager` to be in *kwargs* or :attr:`default_args`. .. class:: Renderer(target : obj[, index=-1[, flags=sdl2.SDL_RENDERER_ACCELERATED]]) A rendering context for windows and sprites that can use hardware or software-accelerated graphics drivers. If target is a :class:`sdl2.ext.Window` or :class:`sdl2.SDL_Window`, *index* and *flags* are passed to the relevant :class:`sdl2.SDL_CreateRenderer()` call. If *target* is a :class:`SoftwareSprite` or :class:`sdl2.SDL_Surface`, the *index* and *flags* arguments are ignored. .. attribute:: renderer The underlying :class:`sdl2.SDL_Renderer`. .. attribute:: rendertarget The target for which the :class:`Renderer` was created. .. attribute:: color The :class:`sdl2.ext.Color` to use for draw and fill operations. .. attribute:: blendmode The blend mode used for drawing operations (fill and line). This can be a value of * ``SDL_BLENDMODE_NONE`` for no blending * ``SDL_BLENDMODE_BLEND`` for alpha blending * ``SDL_BLENDMODE_ADD`` for additive color blending * ``SDL_BLENDMODE_MOD`` for multiplied color blending .. attribute:: scale The horizontal and vertical drawing scale as two-value tuple. .. method:: clear([color=None]) Clears the rendering context with the currently set or passed *color*. .. method:: copy(src : obj[, srcrect=None[, dstrect=None]]) -> None Copies (blits) the passed *src*, which can be a :class:`TextureSprite` or :class:`sdl2.SDL_Texture`, to the target of the :class:`Renderer`. *srcrect* is the source rectangle to be used for clipping portions of *src*. *dstrect* is the destination rectangle. .. method:: draw_line(points : iterable[, color=None]) -> None Draws one or multiple lines on the rendering context. The *line* argument contains the start and end coordinates of the individual lines in the form ``(line1_x1, line1_y1, line1_x2, line1_y2, line2_x1, line2_y1, ...)``. .. method:: draw_point(points : iterable[, color=None]) -> None Draws one or multiple points on the rendering context. The *points* argument contains the x and y values of the points as simple sequence in the form ``(point1_x, point1_y, point2_x, point2_y, ...)``. .. method:: draw_rect(rects : iterable[, color=None]) -> None Draws one or multiple rectangles on the rendering context. *rects* contains sequences of four values denoting the x and y offset and width and height of each individual rectangle in the form ``((x1, y1, w1, h1), (x2, y2, w2, h2), ...)``. .. method:: fill(rects : iterable[, color=None]) -> None Fills one or multiple rectangular areas on the rendering context with the current set or passed *color*. *rects* contains sequences of four values denoting the x and y offset and width and height of each individual rectangle in the form ``((x1, y1, w1, h1), (x2, y2, w2, h2), ...)``. .. method:: present() -> None Refreshes the rendering context, causing changes to the render buffers to be shown. PySDL2-0.9.3/doc/modules/sdl2ext_surface.rst0000644000000000000000000000060312312631402015463 0ustar .. currentmodule:: sdl2.ext Software Surface manipulation ============================= .. function:: subsurface(surface : SDL_Surface, area : (int, int, int, int)) -> SDL_Surface Creates a surface from a part of another surface. The two surfaces share pixel data. .. note:: The newly created surface *must not* be used after its parent has been freed!PySDL2-0.9.3/doc/modules/sdl2ext_window.rst0000644000000000000000000000412512260256443015357 0ustar .. currentmodule:: sdl2.ext Window routines to manage on-screen windows =========================================== .. class:: Window(title : string, size : iterable[, position=None[, flags=None]]) The Window class represents a visible on-screen object with an optional border and *title* text. It represents an area on the screen that can be accessed by the application for displaying graphics and receive and process user input. The position to show the Window at is undefined by default, letting the operating system or window manager pick the best location. The behaviour can be adjusted through the ``DEFAULTPOS`` class variable. :: Window.DEFAULTPOS = (10, 10) The created Window is hidden by default, which can be overridden at the time of creation by providing other SDL window flags through the *flags* parameter. The default flags for creating Window instances can be adjusted through the ``DEFAULTFLAGS`` class variable. :: Window.DEFAULTFLAGS = sdl2.SDL_WINDOW_SHOWN .. attribute:: window The used :class:`sdl2.SDL_Window`. .. attribute:: title The title of the :class:`Window`. .. attribute:: size The size of the :class:`Window`. .. method:: show() -> None Show the :class:`Window` on the display. .. method:: hide() -> None Hide the :class:`Window`. .. method:: maximize() -> None Maximizes the :class:`Window` to the display's dimensions. .. method:: minimize() -> None Minimizes the :class:`Window` to an iconified state in the system tray. .. method:: refresh() -> None Refreshes the entire :class:`Window` surface. .. note:: This only needs to be called, if a SDL_Surface was acquired via :meth:`get_surface()` and is used to display contents. .. method:: get_surface() -> SDL_Surface Gets the :class:`sdl2.SDL_Surface` used by the :class:`Window` to display 2D pixel data. .. note:: Using this method will make the usage of GL operations, such as texture handling or the usage of SDL renderers impossible. PySDL2-0.9.3/doc/tutorial/0000755000000000000000000000000012357043742012045 5ustar PySDL2-0.9.3/doc/tutorial/helloworld.rst0000644000000000000000000001260512312361021014736 0ustar .. _hello_world: Hello World =========== Ahhh, the great tradition of saying "Hello World" in a programming language. To whet your appetite, we will do this with a most simple application, which will display an image. It is not important to understand everything at once, which will be used by the example. Nearly all parts used now are explained in later chapters, so do not hesitate, if the one or other explanation is missing. Importing --------- Let's start with importing some basic modules, which are necessary to display a small nice window and to do some basic drawing within that window. :: import sys import sdl2.ext RESOURCES = sdl2.ext.Resources(__file__, "resources") We need some resources from the ``resources`` folder, so that we have a test image around to display on the window later on. In your own applications, it is unlikely that you will ever need to import them, but we need them here, so we use the :mod:`sdl2.ext.Resources` class to have them available. Window creation and image loading --------------------------------- Any graphical application requires access to the screen, mostly in form of a window, which basically represents a portion of the screen, the application has access to and the application can manipulate. In most cases that portion has a border and title bar around it, allowing the user to move it around on the screen and reorganise everything in a way to fit his needs. Once we have imported all necessary parts, let's create a window to have access to the screen, so we can display the logo and thus represent it to the user. :: sdl2.ext.init() window = sdl2.ext.Window("Hello World!", size=(640, 480)) window.show() factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE) sprite = factory.from_image(RESOURCES.get_path("hello.bmp")) spriterenderer = factory.create_sprite_render_system(window) spriterenderer.render(sprite) First, we initialise the :mod:`sdl2.ext` internals to gain access to the screen and to be able to create windows on top of it. Once done with that, :class:`sdl2.ext.Window` will create the window for us and we supply a title to be shown on the window's border along with its initial size. Since :class:`sdl2.ext.Window` instances are not shown by default, we have to tell the operating system and window manager that there is a new window to display by calling :meth:`sdl2.ext.Window.show()`. Afterwards, we get an image from the resources folder and create a :class:`sdl2.ext.Sprite` from it, which can be easily shown later on. This is done via a :class:`sdl2.ext.SpriteFactory`, since the factory allows us to switch between texture-based, hardware-accelerated, and software-based sprites easily. To display the image, we will use a :class:`sdl2.ext.SpriteRenderSystem`, which supports the sprite type (texture- or software-based) and can copy the image to the window for display. The :class:`sdl2.ext.SpriteRenderSystem` needs to know, where to copy to, thus we have to supply the window as target for copy and display operations. All left to do is to initiate the copy process by calling :class:`sdl2.ext.SpriteRenderSystem.render()` with the image we created earlier. .. tip:: You will notice that the sprite used above will always be drawn at the top-left corner of the :class:`sdl2.ext.Window`. You can change the position of where to draw it by changing its :attr:`sdl2.ext.Sprite.position` value. :: # will cause the renderer to draw the sprite 10px to the right and # 20 px to the bottom sprite.position = 10, 20 # will cause the renderer to draw the sprite 55px to the right and # 10 px to the bottom sprite.position = 55, 10 Experiment with different values to see their effect. Do not forget to do this *before* ``spriterenderer.render(sprite)`` is called. Making the application responsive --------------------------------- We are nearly done now. We have an image to display, we have a window, where the image should be displayed on, so we can execute the written code, not? Well, yes, but the only thing that will happen is that we will notice a short flickering before the application exits. Maybe we can even see the window with the image for a short moment, but that's not what we want, do we? To keep the window on the screen and to make it responsive to user input, such as closing the window, react upon the mouse cursor or key presses, we have to add a so-called event loop. The event loop will deal with certain types of actions happening on the window or while the window is focused by the user and - as long as the event loop is running - will keep the window shown on the screen. :: processor = sdl2.ext.TestEventProcessor() processor.run(window) Since this is a very first tutorial, we keep things simple here and use a dummy class for testing without actually dealing with the event loop magic. By calling :meth:`sdl2.ext.TestEventProcessor.run()`, we implicitly start an event loop, which takes care of the most important parts for us. And here it ends... ------------------- The window is shown, the image is shown, great! All left to do is to clean up everything, once the application finishes. Luckily the :class:`sdl2.ext.TestEventProcessor` knows when the window is closed, so it will exit from the event loop. Once it exits, we should clean up the video internals, we initialised at the beginning. Thus, a final call to :: sdl2.ext.quit() should be made. PySDL2-0.9.3/doc/tutorial/index.rst0000644000000000000000000000107712260256443013710 0ustar Learn to fly - the tutorials ============================ PySDL2 is easy to learn and a powerful multimedia programming framework. It features efficient high- and low-level structures and an excellent object-oriented programming layout. The following tutorials will guide you through your first applications written with PySDL2 and introduces certain parts of the PySDL2 packages to you. They will most likely *not* cover each single part of PySDL2, but instead show you the most noteworthy features. .. toctree:: :maxdepth: 2 helloworld.rst pong.rst pygamers.rst PySDL2-0.9.3/doc/tutorial/pong.rst0000644000000000000000000005356612312361106013545 0ustar .. _pong-tutorial: The Pong Game ============= The following tutorial will show you some capabilities of the component-based approach, PySDL2 features. We will create the basics of a simple Pong game implementation here. The basics of creating a event loop, dealing with user input, moving images around and creating a rendering function are covered in this tutorial. Getting started --------------- We start with creating the window and add a small event loop, so we are able to close the window and exit the game. :: import sys import sdl2 import sdl2.ext def run(): sdl2.ext.init() window = sdl2.ext.Window("The Pong Game", size=(800, 600)) window.show() running = True while running: events = sdl2.ext.get_events() for event in events: if event.type == sdl2.SDL_QUIT: running = False break window.refresh() return 0 if __name__ == "__main__": sys.exit(run()) The import statements, video initialisation and window creation were discussed previously in the :ref:`hello_world` tutorial. We import everything from the :mod:`sdl2` package here, too, to have all SDL2 functions available. Instead of some integrated event processor, a new code fragment is introduced, though. :: running = True while running: events = sdl2.ext.get_events() for event in events: if event.type == sdl2.SDL_QUIT: running = False break window.refresh() The while loop above is the main event loop of our application. It deals with all kinds of input events that can occur when working with the window, such as mouse movements, key strokes, resizing operations and so on. SDL handles a lot for us when it comes to events, so all we need to do is to check, if there are any events, retrieve each event one by one, and handle it, if necessary. For now, we will just handle the ``sdl2.SDL_QUIT`` event, which is raised when the window is about to be closed. In any other case we will just refresh the window's graphics buffer, so it is updated and visible on-screen. Adding the game world --------------------- The window is available and working. Now let's take care of creating the game world, which will manage the player paddles, ball, visible elements and everything else. We are going to use an implementation layout loosely based on a COP [#f1]_ pattern, which separates data structures and functionality from each other. This allows us to change or enhance functional parts easily without having to refactor all classes we are implementing. We start with creating the two player paddles and the rendering engine that will display them. :: [...] WHITE = sdl2.ext.Color(255, 255, 255) class SoftwareRenderer(sdl2.ext.SoftwareSpriteRenderSystem): def __init__(self, window): super(SoftwareRenderer, self).__init__(window) def render(self, components): sdl2.ext.fill(self.surface, sdl2.ext.Color(0, 0, 0)) super(SoftwareRenderer, self).render(components) class Player(sdl2.ext.Entity): def __init__(self, world, sprite, posx=0, posy=0): self.sprite = sprite self.sprite.position = posx, posy def run(): ... world = sdl2.ext.World() spriterenderer = SoftwareRenderer(window) world.add_system(spriterenderer) factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE) sp_paddle1 = factory.from_color(WHITE, size=(20, 100)) sp_paddle2 = factory.from_color(WHITE, size=(20, 100)) player1 = Player(world, sp_paddle1, 0, 250) player2 = Player(world, sp_paddle2, 780, 250) running = True while running: events = sdl2.ext.get_events() for event in events: if event.type == sdl2.SDL_QUIT: running = False break world.process() if __name__ == "__main__": sys.exit(run()) The first thing to do is to enhance the :class:`sdl2.ext.SoftwareSpriteRenderSystem` so that it will paint the whole window screen black on every drawing cycle, before drawing all sprites on the window. Afterwards, the player paddles will be implemented, based on an :class:`sdl2.ext.Entity` data container. The player paddles are simple rectangular sprites that can be positioned anywhere on the window. In the main program function, we put those things together by creating a :class:`sdl2.ext.World`, in which the player paddles and the renderer can live and operate. Within the main event loop, we allow the world to process all attached systems, which causes it to invoke the ``process()`` methods for all :class:`sdl2.ext.System` instances added to it. Moving the ball --------------- We have two static paddles centred vertically on the left and right of our window. The next thing to do is to add a ball that can move around within the window boundaries. :: [...] class MovementSystem(sdl2.ext.Applicator): def __init__(self, minx, miny, maxx, maxy): super(MovementSystem, self).__init__() self.componenttypes = Velocity, sdl2.ext.Sprite self.minx = minx self.miny = miny self.maxx = maxx self.maxy = maxy def process(self, world, componentsets): for velocity, sprite in componentsets: swidth, sheight = sprite.size sprite.x += velocity.vx sprite.y += velocity.vy sprite.x = max(self.minx, sprite.x) sprite.y = max(self.miny, sprite.y) pmaxx = sprite.x + swidth pmaxy = sprite.y + sheight if pmaxx > self.maxx: sprite.x = self.maxx - swidth if pmaxy > self.maxy: sprite.y = self.maxy - sheight class Velocity(object): def __init__(self): super(Velocity, self).__init__() self.vx = 0 self.vy = 0 class Player(sdl2.ext.Entity): def __init__(self, world, posx=0, posy=0): [...] self.velocity = Velocity() class Ball(sdl2.ext.Entity): def __init__(self, world, sprite, posx=0, posy=0): self.sprite = sprite self.sprite.position = posx, posy self.velocity = Velocity() def run(): [...] sp_ball = factory.from_color(WHITE, size=(20, 20)) [...] movement = MovementSystem(0, 0, 800, 600) spriterenderer = SoftwareRenderer(window) world.add_system(movement) world.add_system(spriterenderer) [...] ball = Ball(world, sp_ball, 390, 290) ball.velocity.vx = -3 [...] Two new classes are introduced here, ``Velocity`` and ``MovementSystem``. The ``Velocity`` class is a simple data bag. It does not contain any application logic, but consists of the relevant information to represent the movement in a certain direction. This allows us to mark in-game items as being able to move around. The ``MovementSystem`` in turn takes care of moving the in-game items around by applying the velocity to their current position. Thus, we can simply enable any ``Player`` instance to be movable or not by adding or removing a velocity attribute to them, which is a ``Velocity`` component instance. .. note:: The naming is important here. The EBS implementation as described in :ref:`ref-ebs` requires every in-application or in-game item attribute bound to a :class:`sdl2.ext.Entity` to be the lowercase class name of its related component. :: Player.vel = Velocity(10, 10) for example would raise an exception, since the system expects ``Player.vel`` to be an instance of a ``Vel`` component. The ``MovementSystem`` is a specialised :class:`sdl2.ext.System`, a :class:`sdl2.ext.Applicator`, which can operate on combined sets of data. When the :meth:`sdl2.ext.Applicator.process()` method is called, the passed ``componentsets`` iterable will contain tuples of objects that belong to an instance and feature a certain type. The ``MovementSystem``'s ``process()`` implementation hence will loop over sets of ``Velocity`` and ``Sprite`` instances that belong to the same :class:`sdl2.ext.Entity`. Since we have a ball and two players currently available, it typically would loop over three tuples, two for the individual players and one for the ball. The :class:`sdl2.ext.Applicator` thus enables us to process combined data of our in-game items, without creating complex data structures. .. note:: Only entities that contain *all* attributes (components) are taken into account. If e.g. the ``Ball`` class would not contain a ``Velocity`` component, it would not be processed by the ``MovementSystem``. Why do we use this approach? The :class:`sdl2.ext.Sprite` objects carry a position, which defines the location at which they should be rendered, when processed by the ``SoftwareRenderer``. If they should move around (which is a change in the position), we need to apply the velocity to them. We also define some more things within the ``MovementSystem``, such as a simple boundary check, so that the players and ball cannot leave the visible window area on moving around. Bouncing -------- We have a ball that can move around as well as the general game logic for moving things around. In contrast to a classic OO approach we do not need to implement the movement logic within the ``Ball`` and ``Player`` class individually, since the basic movement is the same for all (yes, you could have solved that with inheriting ``Ball`` and ``Player`` from a ``MovableObject`` class in OO). The ball now moves and stays within the bounds, but once it hits the left side, it will stay there. To make it *bouncy*, we need to add a simple collision system, which causes the ball to change its direction on colliding with the walls or the player paddles. :: [...] class CollisionSystem(sdl2.ext.Applicator): def __init__(self, minx, miny, maxx, maxy): super(CollisionSystem, self).__init__() self.componenttypes = Velocity, sdl2.ext.Sprite self.ball = None self.minx = minx self.miny = miny self.maxx = maxx self.maxy = maxy def _overlap(self, item): pos, sprite = item if sprite == self.ball.sprite: return False left, top, right, bottom = sprite.area bleft, btop, bright, bbottom = self.ball.sprite.area return (bleft < right and bright > left and btop < bottom and bbottom > top) def process(self, world, componentsets): collitems = [comp for comp in componentsets if self._overlap(comp)] if collitems: self.ball.velocity.vx = -self.ball.velocity.vx def run(): [...] world = World() movement = MovementSystem(0, 0, 800, 600) collision = CollisionSystem(0, 0, 800, 600) spriterenderer = SoftwareRenderer(window) world.add_system(movement) world.add_system(collision) world.add_system(spriterenderer) [...] collision.ball = ball running = True while running: events = sdl2.ext.get_events() for event in events: if event.type == sdl2.SDL_QUIT: running = False break sdl2.SDL_Delay(10) world.process() if __name__ == "__main__": sys.exit(run()) The ``CollisionSystem`` only needs to take care of the ball and objects it collides with, since the ball is the only unpredictable object within our game world. The player paddles will only be able to move up and down within the visible window area and we already dealt with that within the ``MovementSystem`` code. Whenever the ball collides with one of the paddles, its movement direction (velocity) should be inverted, so that it *bounces* back. Additionally, we won't run at the full processor speed anymore in the main loop, but instead add a short delay, using the :func:`sdl2.SDL_Delay` function. This reduces the overall load on the CPU and makes the game a bit slower. Reacting on player input ------------------------ We have a moving ball that bounces from side to side. The next step would be to allow moving one of the paddles around, if the player presses a key. The SDL event routines allow us to deal with a huge variety of user and system events that could occur for our application, but right now we are only interested in key strokes for the Up and Down keys to move one of the player paddles up or down. :: [...] def run(): [...] running = True while running: events = sdl2.ext.get_events() for event in events: if event.type == sdl2.SDL_QUIT: running = False break if event.type == sdl2.SDL_KEYDOWN: if event.key.keysym.sym == sdl2.SDLK_UP: player1.velocity.vy = -3 elif event.key.keysym.sym == sdl2.SDLK_DOWN: player1.velocity.vy = 3 elif event.type == sdl2.SDL_KEYUP: if event.key.keysym.sym in (sdl2.SDLK_UP, sdl2.SDLK_DOWN): player1.velocity.vy = 0 sdl2.SDL_Delay(10) world.process() if __name__ == "__main__": sys.exit(run()) Every event that can occur and that is supported by SDL2 can be identified by a static event type code. This allows us to check for a key stroke, mouse button press, and so on. First, we have to check for ``sdl2.SDL_KEYDOWN`` and ``sdl2.SDL_KEYUP`` events, so we can start and stop the paddle movement on demand. Once we identified such events, we need to check, whether the pressed or released key is actually the Up or Down key, so that we do not start or stop moving the paddle, if the user presses R or G or whatever. Whenever the Up or Down key are pressed down, we allow the left player paddle to move by changing its velocity information for the vertical direction. Likewise, if either of those keys is released, we stop moving the paddle. Improved bouncing ----------------- We have a moving paddle and we have a ball that bounces from one side to another, which makes the game ... quite boring. If you played Pong before, you know that most variations of it will cause the ball to bounce in a certain angle, if it collides with a paddle. Most of those implementations achieve this by implementing the paddle collision as if the ball collides with a rounded surface. If it collides with the center of the paddle, it will bounce back straight, if it hits the paddle near the center, it will bounce back with a pointed angle and on the corners of the paddle it will bounce back with some angle close to 90 degrees to its initial movement direction. :: class CollisionSystem(sdl2.ext.Applicator): [...] def process(self, world, componentsets): collitems = [comp for comp in componentsets if self._overlap(comp)] if collitems: self.ball.velocity.vx = -self.ball.velocity.vx sprite = collitems[0][1] ballcentery = self.ball.sprite.y + self.ball.sprite.size[1] // 2 halfheight = sprite.size[1] // 2 stepsize = halfheight // 10 degrees = 0.7 paddlecentery = sprite.y + halfheight if ballcentery < paddlecentery: factor = (paddlecentery - ballcentery) // stepsize self.ball.velocity.vy = -int(round(factor * degrees)) elif ballcentery > paddlecentery: factor = (ballcentery - paddlecentery) // stepsize self.ball.velocity.vy = int(round(factor * degrees)) else: self.ball.velocity.vy = - self.ball.velocity.vy The reworked processing code above simulates a curved paddle by creating segmented areas, which cause the ball to be reflected in different angles. Instead of doing some complex trigonometry to calculate an accurate angle and transform it on a x/y plane, we simply check, where the ball collided with the paddle and adjust the vertical velocity. If the ball now hits a paddle, it can be reflected at different angles, hitting the top and bottom window boundaries... and will stay there. If it hits the window boundaries, it should be reflected, too, but not with a varying angle, but with the exact angle, it hit the boundary with. This means that we just need to invert the vertical velocity, once the ball hits the top or bottom. :: class CollisionSystem(sdl2.ext.Applicator): [...] def process(self, world, componentsets): [...] if (self.ball.sprite.y <= self.miny or self.ball.sprite.y + self.ball.sprite.size[1] >= self.maxy): self.ball.velocity.vy = - self.ball.velocity.vy if (self.ball.sprite.x <= self.minx or self.ball.sprite.x + self.ball.sprite.size[0] >= self.maxx): self.ball.velocity.vx = - self.ball.velocity.vx Creating an enemy ----------------- Now that we can shoot back the ball in different ways, it would be nice to have an opponent to play against. We could enhance the main event loop to recognise two different keys and manipulate the second paddle's velocity for two people playing against each other. We also could create a simple computer-controlled player that tries to hit the ball back to us, which sounds more interesting. :: class TrackingAIController(sdl2.ext.Applicator): def __init__(self, miny, maxy): super(TrackingAIController, self).__init__() self.componenttypes = PlayerData, Velocity, sdl2.ext.Sprite self.miny = miny self.maxy = maxy self.ball = None def process(self, world, componentsets): for pdata, vel, sprite in componentsets: if not pdata.ai: continue centery = sprite.y + sprite.size[1] // 2 if self.ball.velocity.vx < 0: # ball is moving away from the AI if centery < self.maxy // 2: vel.vy = 3 elif centery > self.maxy // 2: vel.vy = -3 else: vel.vy = 0 else: bcentery = self.ball.sprite.y + self.ball.sprite.size[1] // 2 if bcentery < centery: vel.vy = -3 elif bcentery > centery: vel.vy = 3 else: vel.vy = 0 class PlayerData(object): def __init__(self): super(PlayerData, self).__init__() self.ai = False class Player(sdl2.ext.Entity): def __init__(self, world, sprite, posx=0, posy=0, ai=False): self.sprite = sprite self.sprite.position = posx, posy self.velocity = Velocity() self.playerdata = PlayerData() self.playerdata.ai = ai def run(): [...] aicontroller = TrackingAIController(0, 600) world.add_system(aicontroller) world.add_system(movement) world.add_system(collision) world.add_system(spriterenderer) player1 = Player(world, sp_paddle1, 0, 250) player2 = Player(world, sp_paddle2, 780, 250, True) [...] aicontroller.ball = ball [...] We start by creating a component ``PlayerData`` that flags a player as being AI controlled or not. Afterwards, a ``TrackingAIController`` is implemented, which, depending on the information of the ``PlayerData`` component, will move the specific player paddle around by manipulating its velocity information. The AI is pretty simple, just following the ball's vertical movement, trying to hit it at its center, if the ball moves into the direction of the AI-controlled paddle. As soon as the ball moves away from the paddle, the paddle will move back to the vertical center. .. tip:: Add ``True`` as last parameter to the first ``Player()`` constructor to see two AIs playing against each other. Next steps ---------- We created the basics of a Pong game, which can be found in the examples folder. However, there are some more things to do, such as * resetting the ball to the center with a random vertical velocity, if it hits either the left or right window bounds * adding the ability to track the points made by either player, if the ball hit the left or right side * drawing a dashed line in the middle to make the game field look nicer * displaying the points made by each player It is your turn now to implement these features. Go ahead, it is not as complex as it sounds. * you can reset the ball's position in the ``CollisionSystem`` code, by changing the code for the ``minx`` and ``maxx`` test * you could enhance the ``CollisionSystem`` to process ``PlayerData`` components and add the functionality to add points there (or write a small processor that keeps track of the ball only and processes only the ``PlayerData`` and ``video.SoftSprite`` objects of each player for adding points). Alternatively, you could use the :class:`sdl2.ext.EventHandler` class to raise a score count function within the ``CollisionSystem``, if the ball collides with one of the paddles. * write an own render sytem, based on :class:`sdl2.ext.Applicator`, which takes care of position and sprite sets :: StaticRepeatingSprite(Entity): ... self.positions = Positions((400, 0), (400, 60), (400, 120), ...) ... * draw some simple images for 0-9 and render them as sprites, depending on the points a player made. .. rubric:: Footnotes .. [#f1] Component-Oriented Programming PySDL2-0.9.3/doc/tutorial/pygamers.rst0000644000000000000000000003746312312361131014425 0ustar PySDL2 for Pygamers =================== Care to move to a newer SDL with your Pygame knowledge? Then you should know one thing or two about PySDL2 before hacking code, since it is completely different from Pygame. Do not let that fact scare you away, the basics with graphics and sound are still the same (as they are fundamental), but you will not find many similarities to the Pygame API within PySDL2. .. todo:: More details, examples, etc. Technical differences --------------------- Pygame is implemented as a mixture of Python, C and Assembler code, wrapping 3rd party libraries with CPython API interfaces. PySDL2 in contrast is written in pure Python, using :mod:`ctypes` to interface with the C interfaces of 3rd party libraries. API differences --------------- pygame ^^^^^^ ======================= ================================================= pygame sdl2 ======================= ================================================= ``init()`` :func:`sdl2.SDL_init()` where appropriate ``quit()`` :func:`sdl2.SDL_quit()` where appropriate ``error`` No equivalent ``get_error()`` :func:`sdl2.SDL_GetError()` ``set_error()`` :func:`sdl2.SDL_SetError()` ``get_sdl_version()`` :func:`sdl2.SDL_GetVersion()` ``get_sdl_byteorder()`` :data:`sdl2.SDL_BYTEORDER` ``register_quit()`` No equivalent planned ``encode_string()`` No equivalent planned ``encode_file_path()`` No equivalent planned ======================= ================================================= pygame.cdrom ^^^^^^^^^^^^ PySDL2 does not feature any CD-ROM related interfaces. They were removed in SDL2 and PySDL2 does not provide its own facilities. pygame.Color ^^^^^^^^^^^^ You can find a similar class in :class:`sdl2.ext.Color`. It does not feature a ``set_length()`` or ``correct_gamma()`` method, though. pygame.cursors ^^^^^^^^^^^^^^ PySDL2 does not feature any pre-defined cursor settings at the moment. pygame.display ^^^^^^^^^^^^^^ ======================= ================================================= pygame.display sdl2 ======================= ================================================= ``init()`` :func:`sdl2.ext.init()` ``quit()`` :func:`sdl2.ext.quit()` ``get_init()`` :func:`sdl2.SDL_WasInit()` ``set_mode()`` :class:`sdl2.ext.Window` ``get_surface()`` :meth:`sdl2.ext.Window.get_surface()` ``flip()`` :meth:`sdl2.ext.Window.refresh()` ``update()`` :meth:`sdl2.ext.Window.refresh()` ``get_driver()`` :func:`sdl2.SDL_GetCurrentVideoDriver()` ``Info`` No equivalent ``get_wm_info()`` :func:`sdl2.SDL_GetWindowWMInfo()` ``list_modes()`` :func:`sdl2.SDL_GetNumDisplayModes()` ``mode_ok()`` :func:`sdl2.SDL_GetClosestDisplayMode()` ``gl_get_attribute()`` :func:`sdl2.SDL_GL_GetAttribute()` ``gl_set_attribute()`` :func:`sdl2.SDL_GL_SetAttribute()` ``get_active()`` No equivalent ``iconify()`` :meth:`sdl2.ext.Window.minimize()` ``toggle_fullscreen()`` :func:`sdl2.SDL_SetWindowFullscreen()` ``set_gamma()`` :func:`sdl2.SDL_SetWindowBrightness()` ``set_gamma_ramp()`` :func:`sdl2.SDL_SetWindowGammaRamp.()` ``set_icon()`` :func:`sdl2.SDL_SetWindowIcon()` ``set_caption()`` :attr:`sdl2.ext.Window.title` ``get_caption()`` :attr:`sdl2.ext.Window.title` ``set_palette()`` :func:`sdl2.SDL_SetSurfacePalette()` ======================= ================================================= pygame.draw ^^^^^^^^^^^ Drawing primitives can be accessed through either the ``sdl2.SDL_RenderDraw*()`` and ``sdl2.SDL_RenderFill*()`` functions or the more powerful :mod:`sdl2.sdlgfx` module, pygame.event ^^^^^^^^^^^^ ================= ================================================= pygame.event sdl2 ================= ================================================= ``pump()`` :func:`sdl2.SDL_PumpEvents()` ``get()`` :func:`sdl2.SDL_PollEvent()` or :func:`sdl2.ext.get_events()` ``poll()`` :func:`sdl2.SDL_PollEvent()` ``wait()`` :func:`sdl2.SDL_WaitEvent()` ``peek()`` :func:`sdl2.SDL_PeepEvents()` ``clear()`` :func:`sdl2.SDL_FlushEvents()` ``event_name()`` No equivalent ``set_blocked()`` :func:`sdl2.SDL_EventState()` ``get_blocked()`` :func:`sdl2.SDL_EventState()` ``set_allowed()`` :func:`sdl2.SDL_EventState()` ``set_grab()`` :func:`sdl2.SDL_SetWindowGrab()` ``get_grab()`` :func:`sdl2.SDL_GetWindowGrab()` ``post()`` :func:`sdl2.SDL_PeepEvents()` ``Event`` :class:`sdl2.SDL_Event` ================= ================================================= pygame.font ^^^^^^^^^^^ ====================== ================================================= pygame.font sdl2 ====================== ================================================= ``init()`` :func:`sdl2.sdlttf.TTF_Init()` ``quit()`` :func:`sdl2.sdlttf.TTF_Quit()` ``get_init()`` :func:`sdl2.sdlttf.TTF_WasInit()` ``get_default_font()`` No equivalent planned [#f1]_ ``get_fonts()`` No equivalent planned [#f1]_ ``match_font()`` No equivalent planned [#f1]_ ``SysFont`` No equivalent planned [#f1]_ ``Font`` No equivalent planned [#f1]_ ====================== ================================================= pygame.freetype ^^^^^^^^^^^^^^^ PySDL2 does not feature direct FreeType support. pygame.gfxdraw ^^^^^^^^^^^^^^ PySDL2 offers SDL_gfx support through the :mod:`sdl2.sdlgfx` module. pygame.image ^^^^^^^^^^^^ ================== ================================================= pygame.image sdl2 ================== ================================================= ``load()`` :func:`sdl2.sdlimage.IMG_Load()`, :func:`sdl2.ext.load_image()` ``save()`` :func:`sdl2.surface.SDL_SaveBMP()`, :func:`sdl2.sdlimage.IMG_SavePNG()` ``get_extended()`` :func:`sdl2.sdlimage.IMG_isBMP()` et al. ``tostring()`` No equivalent yet ``fromstring()`` No equivalent yet ``frombuffer()`` No equivalent yet ================== ================================================= pygame.joystick ^^^^^^^^^^^^^^^ ================== ======================================================== pygame.joystick sdl2 ================== ======================================================== ``init()`` :func:`sdl2.SDL_Init()` ``quit()`` :func:`sdl2.SDL_Quit()` ``get_init()`` :func:`sdl2.SDL_WasInit()` ``get_count()`` :func:`sdl2.joystick.SDL_NumJoysticks()` ``Joystick()`` :class:`sdl2.joystick.SDL_Joystick` and related functions ================== ======================================================== pygame.key ^^^^^^^^^^ ================== ======================================================== pygame.key sdl2 ================== ======================================================== ``get_focused()`` :func:`sdl2.keyboard.SDL_GetKeyboardFocus()` ``get_pressed()`` :func:`sdl2.keyboard.SDL_GetKeyboardState()` ``get_mods()`` :func:`sdl2.keyboard.SDL_GetModState()` ``set_mods()`` :func:`sdl2.keyboard.SDL_SetModState()` ``set_repeat()`` Based on the OS/WM settings, no equivalent ``get_repeat()`` Based on the OS/WM settings, no equivalent ``name()`` :func:`sdl2.keyboard.SDL_GetKeyName()` ================== ======================================================== pygame.locals ^^^^^^^^^^^^^ Constants in PySDL2 are spread across the different packages and modules, depending on where they originate from. pygame.mixer ^^^^^^^^^^^^ ====================== ==================================================== pygame.mixer sdl2 ====================== ==================================================== ``init()`` :func:`sdl2.sdlmixer.Mix_Init()` ``quit()`` :func:`sdl2.sdlmixer.Mix_Quit()` ``get_init()`` No equivalent planned ``stop()`` :func:`sdl2.sdlmixer.Mix_HaltChannel()`, :func:`sdl2.sdlmixer.Mix_HaltGroup()`, :func:`sdl2.sdlmixer.Mix_HaltMusic()` ``pause()`` :func:`sdl2.sdlmixer.Mix_Pause()`, :func:`sdl2.sdlmixer.Mix_PauseMusic()` ``unpause()`` :func:`sdl2.sdlmixer.Mix_Resume()`, :func:`sdl2.sdlmixer.Mix_ResumeMusic()` ``fadeout()`` :func:`sdl2.sdlmixer.Mix_FadeOutChannel()`, :func:`sdl2.sdlmixer.Mix_FadeOutGroup()`, :func:`sdl2.sdlmixer.Mix_FadeOutMusic()` ``set_num_channels()`` :func:`sdl2.sdlmixer.Mix_AllocateChannels()` ``get_num_channels()`` :func:`sdl2.sdlmixer.Mix_AllocateChannels()` ``set_reserved()`` :func:`sdl2.sdlmixer.Mix_ReserveChannels()` ``find_channel()`` No equivalent planned ``get_busy()`` :func:`sdl2.sdlmixer.Mix_ChannelFinished` ``Sound`` :class:`sdl2.sdlmixer.Mix_Chunk` ``Channel`` No equivalent, use the channel functions instead ====================== ==================================================== pygame.mixer.music ^^^^^^^^^^^^^^^^^^ See `pygame.mixer`_. pygame.mouse ^^^^^^^^^^^^ ================= ==================================================== pygame.mouse sdl2 ================= ==================================================== ``get_pressed()`` :func:`sdl2.mouse.SDL_GetMouseState()` ``get_pos()`` :func:`sdl2.mouse.SDL_GetMouseState()` ``get_rel()`` :func:`sdl2.mouse.SDL_GetRelativeMouseState()` ``set_pos()`` :func:`sdl2.mouse.SDL_WarpMouseInWindow()` ``set_visible()`` :func:`sdl2.mouse.SDL_ShowCursor()` ``get_focused()`` :func:`sdl2.mouse.SDL_GetMouseFocus()` ``set_cursor()`` :func:`sdl2.mouse.SDL_GetCursor()` ``get_cursor()`` :func:`sdl2.mouse.SDL_SetCursor()` ================= ==================================================== pygame.movie ^^^^^^^^^^^^ No such module is planned for PySDL2. pygame.Overlay ^^^^^^^^^^^^^^ You can work with YUV overlays by using the :mod:`sdl2.render` module with :class:`sdl2.render.SDL_Texture` objects. pygame.PixelArray ^^^^^^^^^^^^^^^^^ You can access pixel data of sprites and surfaces directly via the :class:`sdl2.ext.PixelView` class. It does not feature comparison or extractions methods. pygame.Rect ^^^^^^^^^^^ No such functionality is available for PySDL2. Rectangles are represented via :class:`sdl2.rect.SDL_Rect` for low-level SDL2 wrappers or 4-value tuples. pygame.scrap ^^^^^^^^^^^^ PySDL2 offers basic text-based clipboard access via the :mod:`sdl2.clipboard` module. A feature-rich clipboard API as for Pygame does not exist yet. pygame.sndarray ^^^^^^^^^^^^^^^ No such module is available for PySDL2 yet. pygame.sprite ^^^^^^^^^^^^^ PySDL2 uses a different approach of rendering and managing sprite objects via a component-based system and the :class:`sdl2.ext.Sprite` class. A sprite module as for Pygame is not planned. pygame.Surface ^^^^^^^^^^^^^^ ======================= ===================================================== pygame.Surface sdl2 ======================= ===================================================== ``blit()`` :meth:`sdl2.surface.SDL_BlitSurface()`, :class:`sdl2.ext.SpriteRenderSystem` ``convert()`` :func:`sdl2.surface.SDL_ConvertSurface()` ``convert_alpha()`` :func:`sdl2.surface.SDL_ConvertSurface()` ``copy()`` :func:`sdl2.surface.SDL_ConvertSurface()` ``fill()`` :func:`sdl2.surface.SDL_FillRect()`, :func:`sdl2.surface.SDL_FillRects()`, :func:`sdl2.ext.fill()` ``scroll()`` No equivalent planned ``set_colorkey()`` :func:`sdl2.surface.SDL_SetColorKey()` ``get_colorkey()`` :func:`sdl2.surface.SDL_GetColorKey()` ``set_alpha()`` :func:`sdl2.surface.SDL_SetSurfaceAlphaMod()` ``get_alpha()`` :func:`sdl2.surface.SDL_GetSurfaceAlphaMod()` ``lock()`` :func:`sdl2.surface.SDL_LockSurface()` ``unlock()`` :func:`sdl2.surface.SDL_UnlockSurface()` ``mustlock()`` :func:`sdl2.surface.SDL_MUSTLOCK()` ``get_locked()`` :attr:`sdl2.surface.SDL_Surface.locked` ``get_locks()`` No equivalent planned ``get_at()`` Direct access to the pixels for surfaces can be achieved via the :class:`sdl2.ext.PixelView` class ``set_at()`` Direct access to the pixels for surfaces can be achieved via the :class:`sdl2.ext.PixelView` class ``get_at_mapped()`` No equivalent planned ``get_palette()`` via :attr:`sdl2.surface.SDL_Surface.format` and the :attr:`sdl2.pixels.SDL_PixelFormat.palette` attribute ``get_palette_at()`` ``sdl2.pixels.SDL_Palette.colors[offset]`` ``set_palette()`` :func:`sdl2.surface.SDL_SetSurfacePalette()` ``set_palette_at()`` ``sdl2.pixels.SDL_Palette.colors[offset]`` ``map_rgb()`` :func:`sdl2.pixels.SDL_MapRGB()` ``unmap_rgb()`` :func:`sdl2.pixels.SDL_GetRGB()` ``set_clip()`` :func:`sdl2.surface.SDL_SetClipRect()` ``get_clip()`` :func:`sdl2.surface.SDL_GetClipRect()` ``subsurface()`` :func:`sdl2.ext.subsurface()` ``get_parent()`` No equivalent yet ``get_abs_parent()`` As for ``get_parent`` ``get_offset()`` As for ``get_parent`` ``get_abs_offset()`` As for ``get_parent`` ``get_size()`` :attr:`sdl2.ext.Sprite.size`, :attr:`sdl2.surface.SDL_Surface.w`, :attr:`sdl2.surface.SDL_Surface.h` ``get_width()`` ``sdl2.ext.Sprite.size[0]``, :attr:`sdl2.surface.SDL_Surface.w`, ``get_height()`` ``sdl2.ext.Sprite.size[1]``, :attr:`sdl2.surface.SDL_Surface.h` ``get_rect()`` No equivalent planned ``get_bitsize()`` :attr:`sdl2.pixels.SDL_PixelFormat.BitsPerPixel` ``get_bytesize()`` :attr:`sdl2.pixels.SDL_PixelFormat.BytesPerPixel` ``get_flags()`` :attr:`sdl2.surface.SDL_Surface.flags` ``get_pitch()`` :attr:`sdl2.surface.SDL_Surface.pitch` ``get_masks()`` :attr:`sdl2.pixels.SDL_PixelFormat.Rmask`, ... ``get_shifts()`` :attr:`sdl2.pixels.SDL_PixelFormat.Rshift`, ... ``get_losses()`` :attr:`sdl2.pixels.SDL_PixelFormat.Rloss`, ... ``get_bounding_rect()`` No equivalent planned ``get_view()`` :class:`sdl2.ext.PixelView` ``get_buffer()`` :class:`sdl2.ext.PixelView` or :attr:`sdl2.surface.SDL_Surface.pixels` ======================= ===================================================== pygame.surfarray ^^^^^^^^^^^^^^^^ 2D and 3D pixel access can be achieved via the :class:`sdl2.ext.PixelView` class in environments without numpy. Simplified numpy-array creation with direct pixel access (similar to ``pygame.surfarray.pixels2d()`` and ``pygame.surfarray.pixels3d()``) is available via :func:`sdl2.ext.pixels2d()` and :func:`sdl2.ext.pixels3d()`. pygame.time ^^^^^^^^^^^ =============== ================================================= pygame.time sdl2 =============== ================================================= ``get_ticks()`` :func:`sdl2.timer.SDL_GetTicks()` ``wait()`` :func:`sdl2.timer.SDL_Delay()` ``delay()`` :func:`sdl2.timer.SDL_Delay()` ``Clock`` No equivalent planned =============== ================================================= pygame.transform ^^^^^^^^^^^^^^^^ The are no transformation helpers in PySDL2 at moment. Those might be implemented later on via numpy helpers, the Python Imaging Library or other 3rd party packages. pygame.version ^^^^^^^^^^^^^^ =============== ================================================= pygame.version sdl2 =============== ================================================= ``ver`` :attr:`sdl2.__version__` ``vernum`` :attr:`sdl2.version_info` =============== ================================================= .. rubric:: Footnotes .. [#f1] Check https://bitbucket.org/marcusva/python-utils for an easy to use system font detection module PySDL2-0.9.3/doc/Makefile0000644000000000000000000001273612260256443011650 0ustar # Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: @rm -rf $(BUILDDIR)/* @rm -f modules/*~ tutorial/*~ *~ html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PySDL2.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PySDL2.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/PyMule" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PyMule" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." PySDL2-0.9.3/doc/conf.py0000644000000000000000000001771112354723665011516 0ustar # -*- coding: utf-8 -*- # # PySDL2 documentation build configuration file, created by # sphinx-quickstart on Thu Mar 22 07:51:57 2012. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.inheritance_diagram' ] todo_include_todos = True graphviz_output_format = 'png' # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. # source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'PySDL2' copyright = u'2013-2014, Marcus von Appen' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '0.9' # The full version, including alpha/beta/rc tags. release = '0.9.3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: # today = '' # Else, today_fmt is used as the format for a strftime call. # today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. # default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. # add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). # add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. # show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. # html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". # html_title = None # A shorter title for the navigation bar. Default is the same as html_title. # html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. # html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. # html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. # html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. # html_use_smartypants = True # Custom sidebar templates, maps document names to template names. # html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. # html_additional_pages = {} # If false, no module index is generated. # html_domain_indices = True # If false, no index is generated. # html_use_index = True # If true, the index is split into individual pages for each letter. # html_split_index = False # If true, links to the reST sources are added to the pages. # html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. # html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). # html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'PySDL2Doc' # -- Options for LaTeX output -------------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # 'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'PySDL2.tex', u'PySDL2 Documentation', u'Marcus von Appen', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. # latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. # latex_use_parts = False # If true, show page references after internal links. # latex_show_pagerefs = False # If true, show URL addresses after external links. # latex_show_urls = False # Documents to append as an appendix to all manuals. # latex_appendices = [] # If false, no module index is generated. # latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'pysdl2', u'PySDL2 Documentation', [u'Marcus von Appen'], 1) ] # If true, show URL addresses after external links. # man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'PySDL2', u'PySDL2 Documentation', u'Marcus von Appen', 'PySDL2', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. # texinfo_appendices = [] # If false, no module index is generated. # texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. # texinfo_show_urls = 'footnote' # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'http://docs.python.org/': "python.inv"} PySDL2-0.9.3/doc/copying.rst0000644000000000000000000000442212301051273012371 0ustar License ======= :: This software is distributed under the Public Domain. Since it is not enough anymore to tell people: 'hey, just do with it whatever you like to do', you can consider this software being distributed under the CC0 Public Domain Dedication (http://creativecommons.org/publicdomain/zero/1.0/legalcode.txt). In cases, where the law prohibits the recognition of Public Domain software, this software can be licensed under the zlib license as stated below: Copyright (C) 2012-2014 Marcus von Appen This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgement in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Some files are **not** covered by the license above. * For ``examples/resources/tuffy.ttf``, ``examples/resources/tuffy.copy.ttf`` and ``sdl2/test/resources/tuffy.ttf`` the following terms apply: :: We, the copyright holders of this work, hereby release it into the public domain. This applies worldwide. In case this is not legally possible, We grant any entity the right to use this work for any purpose, without any conditions, unless such conditions are required by law. Thatcher Ulrich http://tulrich.com Karoly Barta bartakarcsi@gmail.com Michael Evans http://www.evertype.com * doc/python.inv An inventory index for linking to the proper places in the Python documentation, taken from http://docs.python.org/2/. Its copyright and license information can be found at http://docs.python.org/2/copyright.html and http://docs.python.org/2/license.html. PySDL2-0.9.3/doc/faq.rst0000644000000000000000000000471212312631402011472 0ustar .. _faq: PySDL2 FAQ ========== This is a list of Frequently Asked Questions about PySDL2. If you think, something is missing, please suggest it! On importing... --------------- ... my script fails and complains that a SDL2 library could not be found! Do you have the libraries properly installed? Did you follow the operating system's way of installing or registering libraries? If you placed the libraries in some folder, make sure that the ``PYSDL2_DLL_PATH`` environment variable points to the correct location. ... my script fails complaining that the *found* SDL2 library can't be used! Do you use a 64-bit operating system? Please make sure, that the Python interpreter *and* that the SDL2 libraries are either 64-bit ones *or* 32-bit ones. A 32-bit Python interpreter can't deal with a 64-bit library and vice versa. Using... -------- ... the sdl2 API is weird. Why do you use the SDL\_ prefix all the time? The low-level APIs for SDL2, SDL2\_mixer, SDL2\_ttf, ... shall represent a clean wrapping around the original C API calls. Thus, if you have to search for documentation or want to make a Python to C conversion (or C to Python), most of the code cleanly maps to the original API naming and layout and you do not have to think about whether you had to use SDL\_ or TTF\_ or whatever as prefix or suffix. ... the sdl2 API is does not comply to PEP-8. Please make it PEP-8 compatible. Most of the API is PEP-8 compatible. The low-level bindings to SDL2 and related libraries however use the exact naming (including capital letters) as the functions or structures, they map to. See the previous entry for the reason of that. How do I... ----------- ... save my surfaces as image files? You can use :func:`sdl2.SDL_SaveBMP()` to save them as bitmap files. Other formats are currently unsupported, but might be added to the :mod:`sdl2.ext` package in the future. Font handling... ---------------- ... is too hard. Why can't it work the same way as pygame does? The :mod:`sdl2.sdlttf` API does not know about platform-specific font locations and is unable to resolve font paths based on e.g. the font name or typeface. It's not its job and PySDL2 likewise does not provide such functionality. If you need improved font detection support, you might want to take a look at the sysfont module of the python-utils project, which can be found at https://bitbucket.org/marcusva/python-utils/. PySDL2-0.9.3/doc/index.rst0000644000000000000000000000126212260256443012041 0ustar Welcome to PySDL2's documentation! ================================== PySDL2 is a wrapper around the SDL2 library and as such similar to the discontinued PySDL project. In contrast to PySDL, it has no licensing restrictions, nor does it rely on C code, but uses :mod:`ctypes` instead. Contents ======== .. toctree:: :maxdepth: 2 install.rst integration.rst tutorial/index.rst modules/index.rst faq.rst news.rst Further readings: .. toctree:: :maxdepth: 1 todos.rst copying.rst Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` Documentation TODOs =================== .. todolist:: Last generated on: |today| PySDL2-0.9.3/doc/install.rst0000644000000000000000000000624712264170713012407 0ustar Installing PySDL2 ================= This section provides an overview and guidance for installing PySDL2 on various target platforms. Getting the sources ------------------- You can download the official releases of PySDL2 from https://bitbucket.org/marcusva/py-sdl2/downloads. Download the most recent release, unpack it and make sure that you installed the relevant prerequisites before continuing with the installation. Prerequisites ------------- PySDL2 relies on some 3rd party packages to be fully usable and to provide you full access to all of its features. You must have at least one of the following Python versions installed: * Python 2.7, 3.2+ (http://www.python.org) * PyPy 1.8.0+ (http://www.pypy.org) Other Python versions or Python implementations might work, but are (currently) not officially tested or supported by the PySDL2 distribution. You need to have a working SDL2 library on your target system. You can obtain the source code (to build it yourself) or a prebuilt version at http://www.libsdl.org. PySDL2 also offers support for the following SDL-related libraries: * SDL2_image (http://www.libsdl.org/projects/SDL_image/) * SDL2_mixer (http://www.libsdl.org/projects/SDL_mixer/) * SDL2_ttf (http://www.libsdl.org/projects/SDL_ttf/) * SDL2_gfx (http://www.ferzkopp.net/Software/SDL_gfx-2.0/) Those are optional though and only necessary, if you want to use :mod:`sdl2.sdlimage`, :mod:`sdl2.sdlmixer`, :mod:`sdl2.sdlttf` or :mod:`sdl2.sdlgfx`. Installation ------------ You can either use the python way of installing the package or the make command using the Makefile on POSIX-compatible platforms, such as Linux or BSD, or the make.bat batch file on Windows platforms. Simply type :: python setup.py install for the traditional python way or :: make install for using the Makefile or make.bat. Both will try to perform a default installation with as many features as possible. Trying out ^^^^^^^^^^ You also can test out PySDL2 without actually installing it. You just need to set up your ``PYTHONPATH`` to point to the location of the source distribution package. On Windows-based platforms, you might use something like :: set PYTHONPATH=C:\path\to\pysdl2\:$PYTHONPATH to define the ``PYTHONPATH`` on a command shell. On Linux/Unix, use :: export PYTHONPATH=/path/to/pysdl2:$PYTHONPATH for bourne shell compatibles or :: setenv PYTHONPATH /path/to/pysdl2:$PYTHONPATH for C shell compatibles. You can omit the `:$PYTHONPATH``, if you did not use it so far and if your environment settings do not define it. .. note:: If you are using IronPython, use ``IRONPYTHONPATH`` instead of ``PYTHONPATH``. .. note:: If you did not install SDL2 using the preferred way for your operation system, please read the information about :ref:`importing-pysdl2` in the section :doc:`integration`. Notes on Mercurial usage ^^^^^^^^^^^^^^^^^^^^^^^^ The Mercurial version of PySDL2 is not intended to be used in a production environment. Interfaces may change from one checkin to another, methods, classes or modules can be broken and so on. If you want more reliable code, please refer to the official releases. PySDL2-0.9.3/doc/integration.rst0000644000000000000000000000644312342314547013264 0ustar Integrating PySDL2 ================== PySDL2 consists of two packages, :mod:`sdl2`, which is a plain 1:1 API wrapper around the SDL2 API, and :mod:`sdl2.ext`, which offers enhanced functionality for :mod:`sdl2`. The :mod:`sdl2` package is implemented in a way that shall make it easy for you to integrate and deploy it with your own software projects. You can rely on PySDL2 as third-party package, so that the user needs to install it before he can use your software. Alternatively, you can just copy the whole package into your project to ship it within your own project bundle. .. _importing-pysdl2: Importing --------- The :mod:`sdl2` package relies on an external SDL2 library for creating the wrapper functions. This means that the user needs to have SDL2 installed or that you ship a SDL2 library with your project. If the user has a SDL2 library installed on the target system, the :mod:`ctypes` hooks of :mod:`sdl2` try to find it in the OS-specific standard locations via :func:`ctypes.util.find_library`. If you are going to ship your own SDL2 library with the project or can not rely on the standard mechanism of :mod:`ctypes`, it is also possible to set the environment variable :envvar:`PYSDL2_DLL_PATH`, which shall point to the directory of the SDL2 library or consist of a list of directories, in which the SDL2 libraries can be found. .. note:: :envvar:`PYSDL2_DLL_PATH` is preferred over the standard mechanism. If the module finds a SDL2 library in :envvar:`PYSDL2_DLL_PATH`, it will try to use that one in the first place, before using any SDL2 library installed on the target system. Let's assume, you ship your own library *SDL2.dll* within your project location *fancy_project/third_party*. You can set the environment variable :envvar:`PYSDL2_DLL_PATH` before starting Python. :: # Win32 platforms set PYSDL2_DLL_PATH=C:\path\to\fancy_project\third_party # Unix/Posix-alike environments - bourne shells export PYSDL2_DLL_PATH=/path/to/fancy_project/third_party # Unix/Posix-alike environments - C shells setenv PYSDL2_DLL_PATH /path/to/fancy_project/third_party # Define multiple paths to search for the libraries - Win32 set PYSDL2_DLL_PATH=C:\first\path;C:\second\path You also can set the environment variable within Python using :data:`os.environ`. :: os.environ["PYSDL2_DLL_PATH"] = "C:\\path\\to\\fancy_project\\third_party" os.environ["PYSDL2_DLL_PATH"] = "/path/to/fancy_project/third_party" .. note:: If you aim to integrate :mod:`sdl` directly into your software and do not want or are not allowed to change the environment variables, you can also change the ``os.getenv("PYSDL2_DLL_PATH")`` query within the *sdl2/dll.py* (or *sdl2/sdlimage.py*, *sdl2/sdlttf.py*, *sdl2/sdlgfx.py*) file to point to the directory, in which you keep the DLL. Using different SDL2 versions ----------------------------- PySDL2 tries to provide interfaces to the most recent versions of the SDL2 libraries. Sometimes this means that PySDL2 tries to test for functions that might not be available for your very own project or that are not available on the target system due to an version of the specific library. To check, if the SDL2 libraries do not provide certain functions, you can enable the specific warnings for them. >>> python -W"module"::ImportWarning:sdl2.dll yourfile.py PySDL2-0.9.3/doc/make.bat0000644000000000000000000001225012260256443011604 0ustar @ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Priddle.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Priddle.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) :end PySDL2-0.9.3/doc/news.rst0000644000000000000000000002235612357043445011720 0ustar Release News ============ This describes the latest changes between the PySDL2 releases. 0.9.3 ----- Released on 2014-07-08.. * updated :mod:`sdl2` to include the latest changes of SDL2 (HG) * new :attr:`sdl2.ext.Renderer.scale` attribute, which denotes the horizontal and vertical drawing scale * new :func:`sdl2.ext.point_on_line()` function to test, if a point lies on a line segment * PYSDL2_DLL_PATH can contain multiple paths separated by :attr:`os.pathsep` to search for the libraries now * :func:`sdl2.ext.get_image_formats()` only returns BMP image support now, if SDL2_image and PIL are not found * :func:`sdl2.ext.load_image()` tries to use :func:`sdl2.SDL_LoadBMP()` now, if SDL2_image and PIL are not found * fixed issue #55: :meth:`sdl2.SDL_GameControllerAddMappingsFromFile()` does not raise a TypeError for Python 3.x anymore * fixed issue #56: :meth:`sdl2.ext.Renderer.draw_line()` and :func:`sdl2.ext.Renderer.draw_point()` handle multiple lines (or points) as arguments properly now * fixed issue #57: if SDL2_image is not installed and PIL is used, the loaded pixel buffer of the image file is not referenced anymore after returning from :func:`sdl2.ext.load_image()`, causing random segmentation faults * fixed issue #58: raise a proper error, if :meth:`sdl2.ext.FontManager.render()` could not render a text surface * fixed issue #59: The :attr:`sdl2.ext.TextureSpriteRenderSystem.sdlrenderer` attribute is correctly documented now * fixed a local variable and module name collision in :meth:`sdl2.ext.FontManager.render()` Thanks to Filip M. Nowak for the PYSDL2_DLL_PATH improvement. 0.9.2 ----- Released on 2014-04-13. * fixed issue #32: the line clipping algorithms do not run into precision errors anymore * fixed issue #53 (again): :func:`sdl2.video.SDL_GL_ResetAttributes()` is properly wrapped now to retain backwards compatibility with previous SDL2 releases * fixed issue #54: text input is correctly converted for the text entry component * updated the example BMP files, which could not be loaded properly on some systems with SDL2_image and PIL 0.9.1 ----- Released on 2014-04-05. * fixed issue #50: corrected the :func:`sdl2.ext.load_image()` documentation * fixed issue #52: :meth:`sdl2.ext.Renderer.fill()`, :meth:`sdl2.ext.Renderer.draw_rect()` and :meth:`sdl2.ext.Renderer.draw_point()` convert sequences correctly now * fixed issue #53: provide backwards compatibility for previous SDL2 releases by adding a wrapper func for :func:`sdl2.cpuinfo.SDL_HasAVX()` 0.9.0 ----- Released on 2014-03-23. **IMPORTANT: This release breaks backwards-compatibility. See the notes for the issues #36 and #39.** * updated :mod:`sdl2` to include the latest changes of SDL2 (release 2.0.3) * new :func:`sdl2.ext.subsurface()` function to create subsurfaces from :class:`sdl2.SDL_Surface` objects * new :func:`sdl2.ext.SoftwareSprite.subsprite()` method to create :class:`sdl2.ext.SoftwarSprite` objects sharing pixel data * the unit test runner features a `--logfile` argument now to safe the unit test output to a file * issues #36, #39: the different render classes of sdl2.ext.sprite were renamed * the ``sdl2.ext.RenderContext`` class was renamed to :class:`sdl2.ext.Renderer` to be consistent with with SDL2's naming scheme * ``sdl2.ext.SpriteRenderer`` was renamed to :class:`sdl2.ext.SpriteRenderSystem` * ``sdl2.ext.SoftwareSpriteRenderer`` was renamed to :class:`sdl2.ext.SoftwareSpriteRenderSystem` * ``sdl2.ext.TextureSpriteRenderer`` was renamed to :class:`sdl2.ext.TextureSpriteRenderSystem` * ``sdl2.ext.SpriteFactory.create_sprite_renderer()`` was renamed to :meth:`sdl2.ext.SpriteFactory.create_sprite_render_system()` * fixed :func:`sdl2.audio.SDL_LoadWAV()` macro to provide the correct arguments * fixed issue #44: use a slightly less confusing ``ValueError``, if a renderer argument for the :class:`sdl2.ext.SpriteFactory` is not provided * fixed issue #43: improved the code reference for the improved bouncing section in the docs * fixed issue #40: typo in a ``RuntimeWarning`` message on loading the SDL2 libraries * fixed issue #38: the points arguments of :meth:`sdl2.ext.Renderer.draw_points()` are properly documented now * fixed issue #37: :func:`sdl2.SDL_GetRendererOutputSize()` is now acccessible via a wildcard import * fixed issue #35: download location is now mentioned in the docs * fixed issue #12: remove confusing try/except on import in the examples 0.8.0 ----- Released on 2013-12-30. * updated PD information to include the CC0 dedication, since giving software away is not enough anymore * updated :mod:`sdl2` to include the latest changes of SDL2 (HG) * fixed a wrong C mapping of :func:`sdl2.rwops.SDL_FreeRW()` * fixed various issues within the :class:`sdl2.ext.BitmapFont` class * issue #26: :attr:`sdl2.SDL_AudioSpec.callback` is a :func:`SDL_AudioCallBack` now * issue #30: the SDL_Add/DelHintCallback() unittest works with PyPy now * issue #31: :func:`sdl2.sdlmixer.SDL_MIXER_VERSION()` returns the proper version now Thanks to Sven Eckelmann, Marcel Rodrigues, Michael McCandless, Andreas Schiefer and Franz Schrober for providing fixes and improvements. 0.7.0 ----- Released on 2013-10-27. * updated :mod:`sdl2` to include the latest changes of SDL2 (release 2.0.1) * fixed a bug in :meth:`sdl2.ext.FontManager.render()`, which did not apply the text color correctly * issue #14: improved the error messages on failing DLL imports * issue #19: the :meth:`sdl2.ext.TextureSpriteRenderer.render()` and :meth:`sdl2.ext.SoftwareSpriteRenderer.render()` methods do not misinterpret x and y arguments anymore, if set to 0 * issue #21: :func:`sdl2.ext.load_image()` raises a proper :exc:`UnsupportedError`, if neither SDL_image nor PIL are usable Thanks to Marcel Rodrigues, Roger Flores and otus for providing fixes and improvement ideas. 0.6.0 ----- Released on 2013-09-01. * new :attr:`sdl2.ext.FontManager.size` attribute, which gives a default size to be used for adding fonts or rendering text * updated :mod:`sdl2` to include the latest changes of SDL2 * :meth:`sdl2.ext.RenderContext.copy()` accepts any 4-value sequence as source or destination rectangle now * issue #11: throw an :exc:`ImportError` instead of a :exc:`RuntimeError`, if a third-party DLL could not be imported properly * fixed a bug in the installation code, which caused :mod:`sdl2.examples` not to install the required resources Thanks to Steven Johnson for his enhancements to the FontManager class. Thanks to Marcel Rodrigues for the improvements to RenderContext.copy(). 0.5.0 ----- Released on 2013-08-14. * new :class:`sdl2.ext.FontManager` class, which provides simple TTF font rendering. * new :meth:`sdl2.ext.SpriteFactory.from_text()` method, which creates text sprites * put the SDL2 dll path at the beginning of PATH, if a PYSDL2_DLL_PATH is provided to avoid loading issues for third party DLLs on Win32 platforms * minor documentation fixes Thanks to Dan Gillett for providing the FontManager and from_text() enhancements and his patience regarding all the small change requests. Thanks to Mihail Latyshov for providing fixes to the documentation. 0.4.1 ----- Released on 2013-07-26. * updated :mod:`sdl2` to include the latest changes of SDL2 * improved DLL detection for DLLs not being in a library path * fixed a bug in :meth:`sdl2.ext.RenderContext.draw_rect()` for drawing a single rect * fixed a bug in the :func:`repr` call for :class:`sdl2.ext.SoftwareSprite` * issue #4: fixed a bug in :meth:`sdl2.ext.RenderContext.fill()` for filling a single rect * issue #5: fixed pip installation support * issue #6: fixed a bug in :func:`sdl2.ext.get_events()`, which did not handle more than 10 events in the queue correctly * issue #8: :meth:`sdl2.ext.SpriteFactory.create_texture_sprite` can create sprites to be used as rendering targets now * issue #9: improved error messages on trying to bind non-existent library functions via ctypes * minor documentation fixes Thanks to Steven Johnson, Todd Rovito, Bil Bas and Dan McCombs for providing fixes and improvements. 0.4.0 ----- Released on 2013-06-08. * new :mod:`sdl2.sdlmixer` module, which provides access to the SDL2_mixer library * issue #1: fixed libc loading for cases where libc.so is a ld script * updated :mod:`sdl2` and :mod:`sdl2.sdlimage` to include the latest changes of the libraries, they wrap 0.3.0 ----- Released on 2013-05-07. * new :mod:`sdl2.sdlgfx` module, which provides access to the SDL2_gfx library * new :mod:`sdl2.ext.UIFactory.from_color` method; it creates UI-supportive sprites from a color * fixed color argument bugs in :class:`sdl2.ext.RenderContext` methods * fixed a module namespace issues in :mod:`sdl2.ext.pixelaccess` * :mod:`sdl2.ext.SpriteFactory` methods do not use a default ``size`` argument anymore; it has to provided by the caller 0.2.0 ----- Released on 2013-05-03. * removed sdl2.ext.scene; it now lives in python-utils * fixed :mod:`sdl2.haptic` module usage for Python 3 * fixed :func:`sdl2.SDL_WindowGetData` and :func:`sdl2.SDL_WindowSetData` wrappers * fixed :meth:`sdl2.ext.RenderContext.copy` * fixed :mod:`sdl2.ext.font` module usage for Python 3 * fixed :func:`sdl2.ext.line` * :mod:`sdl2` imports all submodules now * improved documentation 0.1.0 ----- Released on 2013-04-23. * Initial Release PySDL2-0.9.3/doc/todos.rst0000644000000000000000000000011512260256443012056 0ustar Todo list for PySDL2 ==================== General ------- * more unit tests PySDL2-0.9.3/examples/0000755000000000000000000000000012357043742011253 5ustar PySDL2-0.9.3/examples/resources/0000755000000000000000000000000012357043742013265 5ustar PySDL2-0.9.3/examples/resources/button.bmp0000644000000000000000000003531612321677537015316 0ustar BM:6(d2:  fefffffffffefffffffeefeeffffeeffffffffffefffffeefefffeeeffeffffefffffeefeffeefffffefffeefffffffffeffffffffeffffffffffffffffeeffeffffffffffffefffffffffefefeeeffffeefffeeffffefeffffffffffffeeffffeffefeefffffffffffefefffeefffeffffffffffffffefffefffefffeffefffffeffefefffeffeffffffeeeefffffffefeeffeffeff```klkkllllkkllkkllllklklllllllllklkllllkklkllklkkkllkkllkkkkkkklllkklllkkklkkllklklllkllklklklllklllllllkllklkkkklllkkklllkllllllllkllllllklklkklkllklkllklklkllkklkllllkklllllllkklllklklllkllllklllllllkkklklkkkklkllllklllllllllllllllkkklkllkllklkkllklklkkklllllkllklllkkllkkklllkllkllklllllllllkkfff```effrqqqrqqqqqqqrrrrqrrqqqrqqrrqrqqqrqrrrrqqqqqqrqqqqqqqrqrqrrqrqqqrrqqrrqrqrqrqqrqrrqrqqrqrqrrrrrqqqrqqqrqqqrqrqrqrrqrqrqqrrqrrqrqqrqqrqqrqrqqqqqrqrrrqrqqrrrrqrrrrqqqrrrrrqqqqqqqrrqqqqrrqqrqqqqqqqqqrrqrrrrqrrqrqqqrqqrqqrrqqrqrrqqrqqqqrrqqqrqqqrqqqrqrqqqrqqqrrrqrqqrrqqqrrqrrqqqrqqrqqrqqqqrrrklleff```feflllwxwwwwwwxxwwwxwwwwwwwwxwwwwwwxwwwwwwwwwwwwxwwwwwxxxxwwwwwwwwwwwwwwwwwwwwwxwwxwxwwwwwwwwwwwwwwwwwwwwwwwwwwwwxwwwwwwwwwwwwxwwxwwwwwwwwwwwwwwwwwwwwwwwwwwxxwwxwwwwwwwwwwwwxwwwwwwwwwwwwwwwwwwwwwxwwwwwwwxwwwwwwwwwwwwwwwwwwwwwwwxwwwwxwxwwwwxwwwwwxxwwwwwwwwwwwwwwwwwwwwwwwwwwxwwwwxxwwwwwwwwrqrkllfff```ffflkkrqr|}|}}}}}}|}}}}}}}}}}||}|}}}}}}|}||}||}}}|||}|}}}}}}}}||}|}}}}}}}}}|}|}}}}}}}}}|}}}|}}}|}}}}|}}}}}}|}}||}}}}}}}}}}||}}|}}}}}}}}}|}}}|}|}}}}|}|}}}}}}}}}|}}|}}|}}|}|||}}|}}}}|}|}}}}}}}}}}}}}}}|}}}||}}}||}}}}}}|}}}}}}|}}}||}}|}|}}}}|}}}}}}}}}}}}}}}}|}|}}}}}}}}}|}||}|}||}}}}|}|}}}xwwqrqlklfff_``eefkkkrrrwww|}}wwwqqqlkkfff```ffflllqqrwww|}|}}}wwwqrrlklffe```fffllkrqqwww}}}|}}wwwrrqlkkfee```ffeklkqrrwww}}}}}}xwwrqqlllfff```ffellkqqrwww}}}}||wwwqrrklkffe```eeelllrqrwwx}|||}|xwwqrqlllfef```fffkllrrqwwx|}}}}}wwwrrrlllfef```fffkklqqrwww}}}||}wwwqqrkllfff_``eeelllqqqwww}}|}|}wwwqrqllleff```fffllkrqrxww}}|}}}wwwqrqlklfff`_`ffflllqqqwww}}}||}wwwrrqkklfef```fffkllqqqwww}}}}}}wxwqrrlllfff```ffflllqqrwww}}}}}|wxwrqrkllffe```fffkllrqqwww}}}}|}wwwqqrlkkfff`_`ffflllrrqxww|}|}}}wwwqrrlklfee``_eefklkqqqwww}||}}|wwwqqqlllfef```ffflkkqqqwww}||}}}wwwrqqlllfff`_`fffkklqrqwwx}|||}}wwwqrqkllffe```effklkqqrxww}}}}}|wxwqqrllkeff``_feflllqqrwww|}}}||wwwqqqlklfff_``feflllqqrwww}}}}}}wwwqrrklkfff```fffkllqqrwww}}}}}|wwxrrqlllfff```ffflklqqrwww|}}}}|wwxrqrklkfff```ffflllrqrwww}}}}||wwwqqrlllfff```efelkkqqrwxw}}}|}}xwwqqqlllfff``_fffkllrrqwww}|}|}}wwwqrqlklfff```ffflllrqrwww}}}||}wxwrqrkkkfff```effkllrrrwww}}}}}}wwwrrrlklfff```fffklkrrqwxx}}|}}}wwwqrqlllffe_``efelklqrrxww}}|}|}wwwrqqlkkfef```fffllkqqrwww|}}}}|wwwrqqkkkfff_``eefllkqqrwww|}}}}}wwwrrqklkeff```feelllqqrwww}|}}}}wwwqrqlkkfff```fffkklqrrxwx}}||}}wwwqrqklkefe```efekllqqrwww}}|}}}wwwqqqlkkfff```fffkklrqrwww|||}}}wwwqrrlkkfff```ffelkkqrrxww}|}}||xwwrqrkklfff```fefkllrrqwww}}}}||xwwrqrlklfff```fefkllqqqwww|||}|}wxwqqrkklfff```fffkllqqqwxw}}}}||}}}|}}||}|}}}}|}}|}}}}|}}|}}|}}}|||||}|}}}}}}}}}}}}}}}}}}|}}|}}}|}}}}}}|}}}}}}}}}}}}}}|}}}|}|}}|}}}}}}}}}||}}}}}}}}}|}}}||}|}}|}}}|}}}}}}}}|}}}}}}}}||}}}}}||}||||}}}}||}|}}}}}}}}|}|}|||}}|}}}}}}|}}}}}}}}}}|}|}}}}}}}}}|}}|}}}|}}|}}}}||}}}|}}}||||}}}}}|}}}|}}|}}}}||xwwqrqlklffe```ffelllqrrwxwwwwwwwxxwwwwwwwwwwwwxwwwwwwwwwwwwwwwwwwwwxwwxwwwwwwwxxwxwwwwwwwwwwwwwxwwwwwwwwwwwxwxxwwwwwwwwwwxwwwwxwwwwwwwwwxwwwxwwwwwwwwwwwwwwxwwwwwwwxwxwwwxwwwwwwwwwxwwwwwxwwwwxwwxwwwwwwwwwwwwwwwwwwwwxxwwwwwxxwwwwxxwwwwwwwwxwxwwwwwwxwwwwwwwwwwwwwwwwwwwwwwxxwwwwwxwwwwwwwwwwwwwwwxwwx}||xxwrqqlklfff```fefkllqrqqrqqqqqrrrrqqrqrqqqqrqrrrrqrqqrrqrrqqqqqqrqqqqqrqqqqqqrrqqqqrrrrrrqqqrrrrqqqqrqqqrrrqqrqrrrrrrrrrqrqqrqrrrqrqqqqqqrqqrrrrrrqrrqqrrqqrqqqqqqqqqqrrrqqqqrrqrrqqrqrqrqrrqrqqqrrrrrqqqqqrqqqqrqqqrqqrrqqrqrrqrrrrqrrqqqqrqrqrqqqqrqqqrqrqqqqqqrqrqqrrrqrrrqrqrqrqrqrrqqqqqqqqrrqrrqqrqqqwxxrqqklkfff```ffekkllklkklkklkkllkklllllllllkllkklllklllkklkllklllllllllkkkklkkllllllllllkllkllklllllklkllllkkllllkllkkllkllklllllllllklkllkklllkllklllklkllkllkllkllkllkllllllllllllllllkkkkllllkllllklllklllllllllklllkkklkllklkkllkklllkllllkllklllllkklklklkkklllkkkklkklllllkllkllkklllllklklkkklllllkllkrrrlllffe```effffeefefefffeeeeffffffffffeffffeffffeefeffffffffffffefffffffffeffffffffeeffefefefffffeeeffffffffffeeffffffffffffffeefffffffffffffffefffffeeefffffffeeffffffffffffffffffeeffffffffffffffffffeffeffffffffffffffffffffffffeffffefffffffefffffffffffffffeffeffffffeffffffffffeefffffefffffeefffffffffkllfff``_````_`_````````_`````_`_```````_`_```````````````````````_`_``````_``````````````_````````_``````_```````````````_```_`````_``````````````_``````````_``````_``````_````````````````````_````````````_```_`````````_```````````_````_```````````````````````_````````````````````````_`````````_``````effPySDL2-0.9.3/examples/resources/circle.png0000644000000000000000000000054312260256443015233 0ustar PNG  IHDRasBIT|d pHYsiiqtEXtSoftwarewww.inkscape.org<IDAT81jAFh@*!a!]/]RئJ>'>RltKl6qq 3Jw-p|KXحWgjy\Mb*u^U~N S-ê}U%/`<`p$ C0l;;A^[, s{ysXV׏QsDّOmO|v' 4`IENDB`PySDL2-0.9.3/examples/resources/font.bmp0000644000000000000000000076150612260256443014747 0ustar BMF6(E666OOO𬬬XXX<<<ZZZ +++ SSSqqq000jjjLLLOOOMMM """---"""///MMM///NNN''''''JJJ jjj'''LLL---mmmjjjoooooo???]]]999 )))MMM '''JJJ$$$888444:::XXXBBBgggSSS000ooo???WWW777DDDAAA^^^lll>>>###!!!AAA+++!!!XXX999999EEEqqq```111qqqSSSJJJ777@@@  vvvSSS777999666yyy444LLL333VVV***999EEEVVV TTTcccddd!!!///~~~KKKxxx ,,,BBB:::VVVOOO$$$___]]] <<<KKK((([[[CCCbbbWWWEEEzzz)))OOO...DDD555444777 '''lll???GGGhhh///000wwwppp 444777333WWWRRRjjj ]]] BBB!!!ggg&&&(((222MMM:::HHHVVVRRR___RRRTTT UUUQQQooohhhRRRRRR ```ooo)))___ zzzQQQNNN---\\\xxx MMM AAA:::---YYY888VVVXXX)))((( DDDJJJ```ccc '''FFFLLLYYYqqq______```+++ ^^^^^^nnnYYY ***YYY777;;;aaa000 &&&TTT!!!sssGGGmmmfff!!!ȂXXX444 $$$YYYkkk@@@eee111 XXX<<< ...UUU{{{綶vvv'''@@@rrrhhhwwwOOO///qqq^^^ ۷]]]vvv"""oooFFF  >>>999 www888 )))fff|||"""111555###444---LLLXXX"""444222LLL777RRRUUULLLTTTuuuZZZeeeggg555<<<vvvyyy;;; }}}wwwyyyCCCvvvnnn&&&222 XXXkkkKKK777FFFsss===KKKyyyEEExxxsss555RRRWWW !!![[[OOO$$$___OOO'''xxx>>>###vvv뷷fff+++ 888---hhh---...DDD000yyywwwppp VVVJJJ(((***MMMTTT+++]]]+++uuu222MMM:::HHH000EEE```___RRR &&&)))WWWHHH222+++:::\\\xxxfffhhhߜwwwAAAkkk'''FFF///...666444XXX ***  ِLLL PPP+++aaa $$$  333YYYPPP '''@@@&&&&&&mmm///HHHZZZ"""]]]vvvXXXYYYyyyAAAYYY///555)))222KKK@@@'''III:::XXX iiikkk]]] <<<ooo222LLL777RRRnnn"""www888(((///!!!333WWW!!!___[[[bbbgggOOO%%%JJJ&&&vvvnnn&&&===QQQ666|||+++...ZZZtttRRR---VVVggg^^^hhhccc777FFF $$$^^^???NNNooo777'''UUUgggaaa ;;;aaa???cccmmm'''$$$iiiWWW !!![[[VVV^^^~~~000 +++cccnnnZZZ___"""QQQ킂TTT""" 888}}}SSS...---$$$}}}XXXlll{{{@@@FFFFFFfff)))UUU>>>BBBVVVKKK###qqq:::AAA<<<fffNNNQQQ333 ccc666III%%%ʀ+++%%%)))777$$$hhh///&&& ___EEE 888777)))+++{{{nnn"""666((('''---"""rrr___>>>cccccc---[[['''___???yyy]]]ooo```@@@HHH&&&444---888AAA(((aaaUUUfffXXXzzzaaahhh```ccc ---###,,,###---YYY    ;;;aaaȂXXX444   綶vvv&&&***,,,--- HHH222 ۸\\\^^^bbbggg;;;mmm%%% BBBPPP???DDD(((;;;{{{???444&&&sssiii]]],,,~~~KKKDDD$$$===pppHHH999uuuwwwxxxDDDEEESSS---::: :::<<<___]]]222EEE'''kkkKKK888qqqCCCsss555RRRKKK!!!gggCCC999񉉉777 iiiQQQ(((hhh󋋋999```CCCnnn'''%%%iii'''YYY lll'''***qqq777888tttUUULLLMMM;;;888ۂBBBHHHqqq777888tttHHHXXXoooJJJ 999 BBB---UUU555YYYaaaHHHXXX ]]]WWW +++nnn!!!lll ...kkk QQQGGGUUUWWW +++HHHDDDHHHQQQ xxx{{{[[[\\\}}}fffOOO HHH:::GGGQQQ(((%%%FFF /// FFFJJJAAA111eee,,,UUU555vvv===!!!222"""kkk;;;xxx"""{{{|||[[[ {{{~~~ZZZ999IIIeeejjj iiiwwwRRR}}}{{{|||DDDEEEWWW555iiiDDDEEE!!!""" AAA{{{\\\ ccc)))999rrr^^^!!!"""  iii888&&&EEEKKKDDDkkk...ooo111CCCOOOlll  XXX ,,,aaa ???111WWWhhh%%%:::BBB!!!@@@!!!^^^ ZZZNNN $$$ ))){{{dddmmm@@@xxxLLL  $$$ ggg000 )))ddd111<<< CCC///bbb::: 000999```yyy***111zzzNNNRRR{{{ &&&fffggg*** +++CCCkkk888kkkzzz:::DDD kkkwwwIII[[[ooo888^^^<<<$$$^^^444噙///TTT,,,999 ===HHHCCCppp+++666RRROOOHHHttt...NNNBBB;;;sssttt"""UUU!!! eeeccc}}}iiiAAATTTvvvSSSbbb```///??? """mmm%%%}}}UUUEEEOOO[[[EEE ###<<<bbbggg rrrPPPdddGGGKKK///qqqUUUWWW---LLLJJJqqq}}}'''mmmAAA---$$$000111555"""YYYiiiTTTfffbbb333JJJ111PPPօAAA HHH󀀀(((qqq___ۂBBBHHH߇EEE<<>>555222  GGGyyy!!! ~~~999JJJmmm{{{ vvv???AAAEEEiiiZZZ}}}kkkuuu{{{777VVV]]]cccBBBzzz &&&???UUU'''nnn !!! >>> CCC aaa}}}\\\nnnnnnAAACCCOOOlllSSSbbb```!!!DDD+++222PPP///ccc !!!@@@&&&AAAHHHSSSooo DDD  )))''' ---jjj򰰰nnn000ddd XXXCCCCCC### IIIKKK ]]]KKK888XXX  ***ڛ'''666 +++444DDD%%%zzz EEE  (((CCC333'''FFFڝ+++***--- ]]] gggDDDBBBSSSoooIIITTTrrr@@@''' ```FFFAAAMMM WWWJJJ000(((ccc YYYFFF $$$ [[[ooo RRRFFFAAA___QQQiiiCCC /// LLLAAAJJJCCC zzz%%%IIInnn)))444HHH FFF HHHhhhOOOjjjGGG!!!+++ @@@@@@ SSSJJJqqqDDD OOOJJJ]]] $$$ddd [[[OOO@@@ ;;;RRR NNNiiiEEESSSiii###{{{hhh 555III{{{===HHH---aaaقBBBHHH $$$OOOⅅAAAAAA%%%;;;uuu󠠠VVV((()))aaa&&&RRR훛WWW)))  !!!LLLzzz111 FFFIII\\\888aaa...xxxkkk ===444 ZZZ\\\fff&&&vvvXXX~~~@@@DDD???mmm###DDD999'''<<<III~~~III---ccc\\\777 ~~~RRR<<<555777qqqTTTNNN'''!!!666jjjKKKCCCccc{{{>>>ooo}}}tttBBB222zzzDDD+++mmmJJJ===&&& HHH333PPPSSS___OOO...{{{(((;;;###ȯLLL %%% OOOYYYLLL---OOOOOO000qqq $$$[[[OOO666+++~~~ppppppDDDWWWZZZ000<<<tttBBBUUU 444lll###___;;; RRRSSS AAA222oooqqq\\\222'''777XXX...!!!hhh777```+++RRRkkk  rrr444&&&sssiiiLLL;;; OOOkkkggg---___999444)))iiiUUU $$$VVVppp666 &&&[[[ @@@~~~ދJJJ  ***[[[===HHH |||333FFFccc%%% SSS[[[ ...{{{ 555555ZZZ ...ttt111JJJ;;; %%%dddDDD]]]... ttt///"""MMMFFF... UUU\\\yyy---GGG lllGGGJJJ<<>>PPP^^^)))(((NNN666WWWwww,,,wwwMMM;;; @@@kkkGGGccc&&&<<<YYY```&&&CCCYYY""" ttt%%%,,,bbb :::777---((( ~~~XXX333>>> |||))) nnntttfff|||(((666###888}}}ggg{{{"""gggWWW<<<555,,, ===ĐHHHtttnnnrrrooo999CCC888yyy!!!000;;;555...%%%AAAnnn PPP隚hhh,,,hhh oooyyyddd@@@ ,,, uuujjjoooIII>>>XXXQQQ333 &&&???PPP㡡...AAASSS000999WWW'''uuuwww FFF___ |||PPPDDD000Էbbb³&&&bbb```777ttt000777WWWKKKCCCdddeeeRRR:::{{{ggg999!!!{{{GGGhhhzzz;;;222 QQQggg???^^^JJJhhh111"""'''555333LLL...+++pppNNN::: ttt JJJfffrrrKKKCCC|||[[[eee999***~~~NNN444%%% cccbbbUUU666 444eeeaaa)))&&&$$$%%%...III:::HHH555hhh CCCyyy;;;'''xxx"""...dddBBBHHHQQQ %%%bbbuuu... TTT333kkk'''ppp+++  \\\󏏏===CCC{{{/// !!!aaaPySDL2-0.9.3/examples/resources/square.png0000644000000000000000000000042012260256443015264 0ustar PNG  IHDRasRGBIDAT81JD1_ܧ˲O+XxgXZ( ]c3BbL|rs^b9VyvsܤgqicM@pxg[8M+SJCџY$ʶtay(}+fQRJ1Wd|_$I};z-ƀIENDB`PySDL2-0.9.3/examples/resources/star.png0000644000000000000000000000057412260256443014747 0ustar PNG  IHDRsO/sBIT|d pHYs6AtEXtSoftwarewww.inkscape.org<IDAT(1JCQE6vjAP6*rAP+5 D49Oi{ 37SIe8.ee~_N~Ԁ 4nRPk} x^QԾSUj6 \v:o`!E`K)hKEtks^#>S7a$IENDB`PySDL2-0.9.3/examples/resources/testimage.svg0000644000000000000000000014036112260256443015772 0ustar image/svg+xml PySDL2-0.9.3/examples/resources/textentry.bmp0000644000000000000000000003531612321677630016043 0ustar BM:6(d2:  PySDL2-0.9.3/examples/resources/tuffy.ttf0000644000000000000000000052044412260256443015147 0ustar FFTMW6[OS/2' `cmap% (l Jcvt e%feat@gaspglyf aP=<head6hhea T$hmtx+ˑrkern2Q0N4locaܷ%|maxp2x morx;gXname ]P ;postn^Z?propJ'GGJv_< 8x D 8e D @.A33f R PfEd = - Dhg5zhd~$)Z!~Ngbmg(pdppmfqpXpppophpqqKTBX\9X)HydyvyzySdytqyQyyy5\KyZ\My7-XyP(TJL-dr+~X&<TLIb}I((fI`f(xR^D5(xZZp}?5\5(P`TX?VJ1Z+L)mh;m^V1D3&<~yu1.b00/@@ R R R RlSxvyvyzzb 5\5\1f1f1fAl`yyL1\TT ^ ^ ^ ^TVblllxsRff&p&p$pwVx((x(@T@T@TdLdEdLdFyIbjvybvybvybvybvybSdISdISdISdIy*uuI{tqyz$yQwQyQyQyqQyyy$gnl5\f5\f5\f\fMyMyrMy 7-`7-`7-X7-`XfXfX4yxyxyxyxyyf(T^DLxL-dZ-dZ-dZ\^7-`Xf00jZZebbzb8essIR ((~(~p4=Xpnplibf70d:ppbb`Vff(22R^DRYZZZ$999e5\\ebf)7y`99ftff}"LBy%%&bL u?1A8byyygeeeq!LH_5:])NpHyKyxvy-dy5\y{yyn5\nKynXB_JrpNBZ(vpvZoRZi(vpdpZ(J(vR3Z(ZZZ(xv7JZ7_vZv7yopdT6 ~2Q5\Zd2ezyH([(v~N**Ky((s7-7-Zm4 2QZepdee1dyy dddJXJ8J?87-tq>EIyyE:HJ^JCJ\OJXLfqyyyxTyy5\yKydX_Jyby y(yKyd}yjZ\<^b^a(z(zyEbfZ(yeR(J0d5y(}}z 3eaubb(<^e`vH|X(y(z(J(yy(zKyKyJ\<^Jmg7c& /@"9T9Tg~y q>?Zd%dd01D3A0r02:-NF|Pj@<3jB01D3A0r02:-NF|Pj@<3T?T'Z*4B  u@Dd4*~nO$JA+)+L+9"yKyMyN1RH^L^3^A"2502X{D{\{Z{,JJ"JQydyyyyyyRHRRlRy555~e>y&dedBy&z0xxx4444xxxxxxxxxxxxxHH4xZoxxxxxJxxxxx U U HRvy^xxvvm|:nnz@DIb6OOyy\?B?Bhmhm|:|:p_pdpd^^"RR9fd99~zys:fe}}}d }}}}ppLppjpVpopvpTpTpvZZZZZZZZZZL&E(E("*wb>Lk*||www^N"xhtH^==R=d22cl}R`o vyB"4Bt-dNn4q,"O)"&#(TJx____,$ @, $z %(.1qv~_%+;IWcoEMWY[]}   ' 3 : = ? D I O S V [ ^ !!!!!!"!&!.!5!!!!""" " """" "+"4"<"E"H"a"e""""""#!#*%ʧG!Yh P #'.1pvz $*4@VZj HPY[]_    0 9 < ? B G K R V X ] p !!!!!!"!&!.!5!S!!!"""" """" "'"4"<"E"H"`"d""""""# #)%ʧFPha-WSPKJIHb\XVTRPONMLJIHFECB>;65-('&$"! pjc`5430/+)(" @9ߚ^$$e$\#.#    cBCEPK  #%'(..11pqvvz~_  $%"*+$4;&@I.VW8Zc:joDJPRSTVXn EtHMPWYY[[]]_}"58  A D  F  'M 0 3] 9 :a < =c ? ?e B Df G Ii K Ol R Sq V Vs X [t ] ^x p z   !!!!!!!!!!!"!"!&!&!.!.!5!5!S!!!!!!!0""5""6"" 8" " ="">""B""C" " H"'"+I"4"4N"<"<O"E"EP"H"HQ"`"aR"d"eT""V""Y""[""\""]""^# #!`#)#*b%%dFGegi!tPY~hh             !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abUrdeiWxpkvjRGsTUgw6@>Ml|cnCBQ9m}[IJQRMNd:habVyOS]qz!yDXXXX8\(4l <t\  H ` x l @p Ph@lX`$xLxt\(h DhxPh  "|"##|$ $`$%4%&L&'$'D'X(4(P(()*P*++++,,,-..///4/L/d/|///00,0D0\0t0001$1<1T1l11112|222223L4404H4`4x445566606H677D78x8888899|::0:H:`:x:;;,;D;\;t;;;;;<<<4d>|>>>>>? ?$?<?T?l??????@@,@D@AA,AABBB4BLBdB|BCCCDDDDEEE0EHEF0FHF`FFFGG(G@GXGpGH0HHHII,IDI\JKK,KDK\KtKKKKKLMlNNNOXOOPlPPQ Q$Q<QTQlQQQQQQRR,RDR\RtRRRRRSSSxST@U`V<WW(W8XXYZ Z[l\\]^_(_`xa,abcxceefghh|i,j jjkkl4lm0mntoXoppq\rTs0stt`tu(uvvxvwLxlxyz,{{D{||}@}h}}~~t`0hx\Dd< 4PXHXll $T(P|P4,x`$ @lHt $$$d`4Ld((X0LH d8xl@(8LX4p@ňżƸHȠɔtˤ̤ͼΌ\lP,Ҩph 88p$ܴݘݨݸ(d $TpH P@h88xP D08hx|Dp@pPTpttL\tH`x@p|l| ,<L\l ,<L\0`   $ 4 D T d t   d t  T    0   d 40pHH$<T(@P`L\ 8Phx     !"""""#X#$$ $h$% %t%&X&&&&'d($()$)*(*d**++,<,-..l../0001H112<2T2l22223,34`455 5l5566 6@6`6666677(7H7`777778808P8h888899909P9p9999:: :@:`:::::;;0;P;p;;;;<< <@<`<<<<<==(=H=h=====>>0>H>h>>>>?? ?@?`?????@@0@P@p@@@@AA A@A`AxAAAAABB B8BPBhBBBBBCC C@C`CCCCCDD0DPDpDDDDE EHEpEEEEFF0FPFpFFFFGG G@GXGxGGGGHH@HhHHHHHII,IDI\ItIIIIJ0JJKhL\L|LLLLMMM4MPMhMMMMMMNN,NLNdN|NNOXOPPQQ$QDQ\QtQQQQQRR,RSSTT T8TPThTTTTTU<UUUUUUUUUVV$V@VhV|VVVVVVWW8WWWXXY,Yp[]]l]^^@__````blcdeef$fXfglghijkklmxnn0noopq qDr rrss@sst@ttuvxvwLwx xyyyzzLz{ {|P|}$}h}~,~ Dt(<hdPp,htL LL`d@h(x\|DP p@$XXph 4\$P|XT0` <l,<4 ,LlT”TÔ@ĄdŜƀưǔX\Ʉɨʰ ̘̼pXϔ(8|Ѱ|X(\֠LtטTؤL$ܰ݀߸dd0LpT0H`P$pPP|PDpHplhldHpp @     X        t   L  Lx ,h8xDdU./<2<2/<2<23!%!!D $hUDgB #.546324632#"&'&#");'(=@,':?,':"!'77%-?1$,?0% ;&46;2#"&'4&%46;2#"&'&+'"+)"Dv$(v$( 5{!#!#!5!!5!3!3!!!\\Vii#RaaR{{e/8?3.' #5.'7.5467>54&ŁВ}#wKL'D%7$ ӴQ~fL- ;5O-S|k9ԝ]t7.54>32+'n_c[eaw|!Jg[ZL6RY(Ro_t3LLgiv4su]:Hy^P]; #u`lc46;2#"&'&+)"Dv$( ) &5473n{suTIUZ #654'3 tjyTJ]!y7#"'&54?"&5463'&547632763272#'#"'q+& 0*" (*om*( "*0 &+( (#)!)& (( &)!)#( (NB !3!!#!N34̍7Ɏ7g#>%'65"&'&54632>!8H':@,':^%M:?#*gK/% -?1$m3!!m[g>74632#"&'&g@,':?,':^-?1$,?0% T3#3͞d&4>32#"'&732>54'.#"dByo.mܓ."mPI&!kPL(ך|ڈ ڄxpms#73#F\Pm/'6$32!!4>7>54&#"'AxlP/*@:M3C *b`?u4PypG ?"=#-kdV7 GeY3bOO8>#,\ny/^\2*0%96F%q /?32654.+532654&+"'>32#"&q&S9_s=Nba_Py 5{euBN'&TM3}/RhIwK(}pdUI@i^mRM @]GX 3##!;!`^ }ts#V&"'!!632#"&'732654'.\!;1%$^B[# kч.T߄ ' KT7¤?>݉Ţ,'r)4'.#"326632#"&'&54>73oqiEI@! Bse /";N%gu!f~ɛ+3N~N͓*-:snDd Ho7 #!57նPh/@%2654'.#"32654'.#"2#"$'&54>7&'&546Fs`oewU# 3SQ) q" n&oVbqQa -n'l((w͠4,NY9V'0*32654'.#"#"&'&54>32#%qiI@! )PmQ 1A#fv"fɛ2->~pW3Γ,+:rr>mqH'  q#H&  T% 3 PdXBfbb!!!!B  \%# 3#eZ9&6#54>7>54&#"'>324632#"&'&=6(E,|RHV~K`6,@,':?,':-O7<#93(A'|Z|92`aG,W.-?1$,?0% )FV%# &54$32#"&'#"&'&5463232654'.#"32632654'.#"M^7`Ј6Tb-7x(,OzȎv R38f osc.[]uKZmqBTfWRP_]wC@K^89+54'.#32>54'.#"&'!2#2#!?FqK4S}F+ %HU˱vo? WHvK- *KcZ#!7KR,#^ud'!0C9#<9!4Ye:*#u5X^3$$"BWKL5!d)#".54>32.+"3267Lp_wȋa-.awLbN1hhi87#!!2*JcUi0ODOAs[4jTχpzy !!!!!!y0gy !!!!#y0\d-".54>32.#"32>5!5!#P-bwI:jgi99igFvP53#"&'&q o\Fͥ&45}ggGy 33 ##yxϼsy3!!yeݍy 33 3##yϙTT!P\Ly 333#y䝑wPZ\34'.#"32>%4>32#".'&H=^V]\==^U]\>&Z{yƆV'Z{xƆVvmStAPVokRq@MzUeΞc\ltmdʚ`Zkjy 3 4'.+';2+# ,SbΞ BՊΞ#)E?#-(WsB\94'.#"3267'764>32'#".'&PAaVde5=a[6{"Xg ([yb|b=U?ZLnd}b=rjVuAi{mdRvC)"teΞc?hVokRyu54&+ ##;2^R2Sמ3Ʀ"5LF(|wx- 9732654.'.54632.#"#"&-s,G>Y7S,=S73)ps..O8b0JaF@!ۋGWr)L::&+ 1:Ld<êHq|^)C5''& &;FYrBTX!!#!XD7##y3#"$'&5332>5-#zKe9g+rV?~ЇP3#3GBPT 333# #T+P3J 3 3 # #Jjc;˾^)'JLd3 3#LddBX<d!!!!Pliݍ#!!#3u`Z\!31 53#5!`@}5#'#35}VX5!XB獍<.#"'%&'&54767632       TbB )"32654&'254&#"'632#=#"&546ol`{h uEz"NۋgFcgcfm1`+"hm{1Χ">32#".'#&"320Fd>e\..\f>dF-蠠ts-GA#]poŤ`#@E-LlF.#"32>7#"&54>32xF+O6! z6qu(PmTr6)2c#60MZ~Vj=zaI 3#5#".54>3232654&"*we\..\e>dF0stRat`npš]#AG-pbF"!.#"3267#".>32 pLw<[e I }##5354>32.#"3;X`':M+m((9V325332654&"FsM[e<\h-Fd>RZ>.\e>dF0Lstck;Agt8Wu!-E@#@lXpš]#AG-p!#3>32#4.#"qɗ32>32#4.#"V+K3ژ/1L.tm+A+#HnrK/a1&/@$ihs;^dH<gN!#3>32#4.#"qɗ32#".732>54.#"f9kia_Ɍa BoJIoB 7ab7wʗUZyDDyZyuuTN">32#".'#&"320Fd>e\..\f>dF-蠠ts1-GA#]poŤ`#@E-"I? N *3"&=#".54>325332654&"4BEON0d[..\e>dF0Lst=5u͸?V-anpš]#AG-pN&#"#3>32P1>Y{5qR*xw1Yy`HJ:.54672&#" #"&'732654.+ȔQR0 6Pu")( ?"?%6!&ؗ&h\et&G? :Ab;-JG%zOG$  " .0="pCH`U(@-fP+#53533#;#"&5􎎗uFFx-uox13#5#"332>5qɗ=#"332>53L{MՖjg1^R2qɗ&67>7&#"327.'&'&'&Z@T! ,:F'+Z <.<"Y,'F:, (f}w"  P-M+>   " '@W} 33}R=532676=4>7&'&=4'&'.#"5@T! ,:F',Y <.?"Z+'F:, 'i|"  T+Q-9  " %R?3\&>3232>7#"."?%&&800:&-92 *% ?403,'-8 -, ,(  -- 0\I\#5476767676767>7>?>767>767>767654&#"'6763247632#"'&'&4'&'&'&'&#"3276767676%47676767632#"'&'&'&'&n $ lW;/12f VVvQEF,.- | 0.FCX^//!0.GFT^IK-- ! ,+C@ge{zbdBA-,,/?CefzxcbDA-+%cf       W` V(sNN@BYD42-  spOIC<9" P@?UTUrhKJA;9 '(;753&#"327#}k 8]`4cdZPkU~pPRZ< w,9L|M. W_Pz[!&S]jZ`4T''#5332.#"!!!>7!>7j^I: g ^.PF62 ; TBTktFdQ}N! s ' *?w-w132654'.#""'#53&'&547#536253#3# cAKi bALidPP+;yPPy&B>QjK>Qj779F$gQ{77{4B%hWJu!5!3 33!!!#!5!DX1Ϙ7D6ׇLZ#53鏏{z+h,;632#"&'7;26754"#"&'&54>32.+"4'.#";2& ];S Ga - " N[avFF^!Q% Ö0,Wd #pX 7:nxH\S{QL4!4632#"'&'&%4632#"'&'&#8&"28& )8&"28& &8*! '8!&8*! '8!)7(8#"&'&54632&"327%32654'.#"432#"&'&uCSJqyV[;N"L84!.sssu bC\GUy;R8& ,D%o'nŖ2)Ŗ+mm 2"3264'&#"'&547632&'&#"'7632#L0:0(:;Y;:<=V:+0AI\[=54'.#"4>32#".'&%32>54&5.+'32#'# Qlv;DtH Vpu5EtGu?gE& kʡ 3"/0]KRRq -dAR2,JuG$5aZ.(KzH&1^_ftR&߰96}U{8q "N:> ,a)!![)j1=32654'.#"4632#"&'& N4=S N4=Svm^m^3AW?3BXBktY ltY'HPDPB'767632!!5476767676?>?4&#"ʆ JIX&D !.   ( _ !. <&( #5O87:,-0 ,#406 '!"!5<.3S>7327654'&'&'&+5327654&+"'767632#"&'3 < 8&% JT"4"  9:H885##QRtHs+!(!!6($2 > >%%65A1)'&$-rIJXJ<.%632#"'&'&5476L      ufh%#332>53#5#".) $.N5%.u:+'" #J+6L8'@QQ&b9D$yu,23"3"&#.'&54>;0GM*$)A/%=^^A0 s  !!6O2!5!   ,7O1*)b`3neE'{uqJ>54'.'7u' @8*J  "  #8>H 81,1@#73#{a.(:-&327654'&'&#"47632#"'&'& ('4<** ('4<**vLLn_LNl_GF/1"!+,?2"!,+ClKKtYlKL:9Zb;^ #!#^"#"#0 %3##5!335#73##3v^^Wc{a) W6N0BHL%'767632!!5476767676?>?4&#"#73##3N JIX&D !.   ( _ !. <&( #g{a)5O87:,-0 ,#406 '!"!5<. /=GJN732654'&'&'&+5327654&+"'767632#"&'3##5!335#3/ < 9J JT"4"  9:H885##QRtH7^^Wc)s+!(B6($2 > >%%65A1)'&$-rIJXJW6}"{@&$C@&$vRq'A$ RJ'a$ R'j$ R'rf1$ Sg!#!!!!!!53OFF{JxX'z&y&(Cy&(vZ'A( 'j( 7&,CTH&, vhIf'A, 9'jZ, #53!2+324'.+!F}82⛝(,bhE^S5'a+1 \&2C\&2vfs'A2 fJ'a32 f'j2 lJ7,-c,`,9%#7&'&54>3273#"'32>54'&' &#"J|/6[xczaE55\wc5VoYZ=#OIXYZ<)FokRvD2EmtRsB;LzTtod`&O}Txdy&8Cy&8vw'A8 'j8 Ld&<v 2>54'&!3 ##/WlC.E7gc&;b@&(SX>!\]F>32!"'732>54'.+"5;2>54'&#" #67,DXQ'+^eNPj[ ( ?d_?&$*Y)JsO3!  +, 8cF:" ,GnA'h5{ $;`@o;xJ'%#CP7bzY Tb=&DCTb=&DvO^l&AD ^l'ayLD ^l'j^D ^lV'rD T`F`j"32654'.>32!32>7>7#".' #"&'&546326&74'&#"'>32!&'&#"i_"\mf:zd!aV!.'8m'@5$, %'3 ȘWR$ "AP'N& %'"0^t /:X/Zl1$h(Ob4_Y^} - IG]~+&7nk 9 %*% 7035,6+&'f  YsG9BmuV]vF'z F b=&HCzl=&H vcl&A5H l'jH /=3##"'%&'&54767632     11  ;=3#%632#"'&'&5476    11  s# 3##'#31^Vb%3#4632#"'&'&%4632#"'&'&8&"28& )8&"28& 1&8*! '8!&8*! '8!R>32654'.#"#"&'&54324'.''7&#"'6327 Iqg;h9C ݠ)G/30 h8cGY)J7`.2u׆%sjMo$!B&ҸHP$. !(^1dFm'aXQ f<&RCRf=&Rvp&A3R p'a/R p'jR w[#4632#"&'&4632#"&'&!!X@,':?,':@,':?,':[-?1$,?0% 3-?1$,?0% VJ 1 32>54'&'&#"7&'&54>3273#"'ATEj< ZASAh>! s7__1q9_c0DNNVD2?L{LWG+%YwZVKOZuQ\NNx=&XCe=&X*v&A1/X 'jX x?=&\v\,!#3>32#"./4'.#"326/DU4":[^.S6( fD5hU5Jr)54ȢXeZkA,+]Rp3232654&" '2(e*we\..\e>dF0st$#$ Q>& # Rat`npš]#AG-pj##53!2+324'&'&+! |ݝ2KL⚝(ts+ia˥_`F^SooR:327654'&"33##5#"'&'.'&547>32#53MLtuOPPOLL"#2/BPEB.,@ ^f?15 &vttvtsrq˅e*&"  75PTUne`\$ $,%y'q[(b)&qHy.&(b'|Hy'(b'DHy'(bF'HyB&b(b'HdB'*I?'Jd.&*I?'xJd'*I?'dJd?'*I?1'lgJyJB&O+B&K*3!33##!##53!!y88kOO3kf7^ff*!##5353!!67632#4'&'.#"ccPQsRBE02fDF23"[;323276767"'&'&'&'&#"F% # !1 !#B"$B1W  &   /'q,C(3#!![1(j.'S,&F|uq&,uq&LC&;,#13#1!%#"'&'&'&=33276767653٘3rRBE0/fDF23"Yg'ZOy'65"&'&547632%3!! '2(e$#$ Q>& #ݍ&'65"&'&5476323"&'&53 '2(dq$#$ Q>& #. KJY% y'y/'y8O ?37!!g}~eh ~}e?373"&'&5ldqmy  KJY#"y'v1:'vDQ y?'v1?N'BQyB&t1'Qg1'gQn6%276=4'&'.#"#367632#0#6gJIfD*b<`w1yqySBC14$HAAPA/JI!_FL:;B"9HKz\F0!"BGhl:DD< l?N3276=4'&'.#"#367632+6gJIfDF25 PQsRBE02#JA@PAJI!ZKO7;B"$9>IKX1[;CE= \'q2f,&qR\.&2f'R\&2f='jR\"=47676767632!!!!!!#"'&'&'&'&.'&#"327\,+C@ge{'<4_T^xcbDA-+ CX^//!0.GFTfAgehfdRO21'--NK_[lm/ P@?UTUrhKJA;9 'fvFJR2?&'&54767&#"476767632632!32767#"'#"'&'&%!.#" 977115Qc@A47STib^_QO214d::MJEF 4gju|_bef00t pKx<\JO:;#"".={>(#:;[_vychIM)*FF.-KJc 1_QO66&'<7d:;GGMN}~lyP'v5='vUy?P'65r?N' UyPB&5 'hU - 'vl6`H='v#V- B&6`J'V-] Zw732654'&'&'&'&'&'&/&'&'&'&'&'&'&547632&'&#"#"'&6767>54'&'&'7-s#$!*0>8!.+  zyyz(USqs * 5>!'2* $!DEmn|z? ' '(GWr)&+  #$%)+5baUVH98|^$   ($'%j6Z[**ba4 876767654'&'&'7C#'4/""deQ)/ 6P;: '( (  lk\_%44\dt"%!  ? -'$#.1;KL,&,$%z''H&    )ZYCEnC$$`U+"   "8& # -uoX!!!!#!5!!XD7YD#:[4+#53533#3#;#"'&5#53􎎗uFF;<u78gyF'8x'\Xy'qt8x'&q Xy.&8x'vXy'8x0'$Xy&8<'X*y'8f1'QXTB':D1'ZLdB&=<x?'\Ld&<jd'v=Z='v]]d'=Z'b]dB'=Z']5476767632&'&'&#"#,+1/(:'%,m ':1>34#")i 4- ##737676767632&/"3V11)-83A.().\(32@1VA@E50  ('&.\r!!!#!!!!!!53\EQGGWzJ^l7V_!!"327654'&'&6763 !32767#"'&'#"'&'&54762'4'&#"'67632!&'&#"]"|6m PX4= P-R- P`3DU+7D_ ]< "jHMU&;PeC .37",*}9B"## 3"cxDHGI.5)gCbD2:43pNJ <2.GgF I6H-  P'65"&'&54632732654.'.54632.#"#"&~!8H':@,':s,G>Y7S,=S73)ps..O8b0JaF@!ۋ%M:?#*gK/% -?1$Wr)L::&+ 1:Ld<êHq|^)C5''& &;FYrBT`HJQ'65"&'&54632.54672&#" #"&'732654.A!8H':@,':l+ȔQR0 6Pu")( ?"?%6!&ؗ&h\et&G?%M:?#*gK/% -?1$ :Ab;-JG%zOG$  " .0="pCH`U(@-X,$fP+%0 qF676767654'&'&'&#"57>54'&#"'6767632ucm^P/-;&M`_I:D M=<5bdw$"?8Z::!"%.?6&F)Vju0Cr8C$7674654'&'&'&#"5767654'&#"'6767632w& /-; #M`^HGI8FM=<5bdw$"?8Y;:!!&.06%L>6;&(@7  ~YXqd=. 76O)tRSRQmTNM.6 9K90 p\YjxB52654'&#""'&'32767#"&=3676767632pHGm`FGIJzhLL tD>=#Nڋ%!537hjmkߊdgDCEEdgCD653`#hm{"ghkjZxB-7&/054763253#5#"32765&'&#"knf !537X@B`HF=?vF36!=YqtmWFϜ!ORFE`:LN!LZxB-%#"'&'&'&'#36320&'&'&#"32765 w735!#fm=!63Fv?=GH_B?Yv 1FWmsˑL!NL`EFRN7G"'&55476767632#.#"67>7632#4'&#"3276wm##94NHM]LP20 \iB42>QEB., /-dMLtuOPPOutLMvqbTS62  "20>99Xt!'(%< 74LJPTTmecQO^8srstvttveF/'67632#"'&'&'&'732654&#"5VUsTJH86)(;:jh=57)2 z +'+E=<)B`>=74HFRSTML '%(Mõ22ZF<J&'&#"67672>32#"'&''67&'&5476767676323276=&'&#<=E5S.9M + 7"`[\72 TI327654'&"33?#"'&'&'&'&5#"'&'.'&547>32MLtuOPPOLLfk$#$*"("(#"#2/BPEB.,@ ^f?15 &vttvtsrql{ f"  $ 24?C*&"  75PTUne`\$ $,I327654'&"/"#5#"'&'.'&547>3247676767632MLtuOPPOLLkf"#2/BPEB.,@ ^f?15 &#("("*$#vttvtsrqf {*&"  75PTUne`\$ $,S?42 $  bF-.#"!546546767632#"'&'7327676rNIFG4gju_`0112_aaOM42͑hi65PN_j'';7d:;LL{~IJ-,NK]_c!0b`F'96327#"'&'&'&54&='&#"3276767654'&ju_rl# 012_aaOM42$9NIFn FGoK<;! ;LdF6 {~IJ-,NK]_c!005'1hi65PUR>_kJ=%#"&547676?&'&'&54767632.+";#"3267k+fee%;T(*- -3CINcMO)d`:A&H=;IH9/("+(IKg?xf==/1"7* &F33247676767632/" MLtuOPPOutLM#":8JFO[NP21 [i##2/AQEB.,@ ^f>25 &#&%) *$#$kfvttvtsrs bTQ75!"21<99Vv!*&"  75PTUne`\$ $,S?42 #  "f {s?N;K#"'&'&'&'3326=#"'&'.'&547>3253327654'&#"#":8JFO[NP21 [i##2/AQEB.,@ ^f>25 &LMLtuOPPOutLMbTQ75!"21<99Vv!*&"  75PTUne`\$ $,vttvtsrsICE"'&'&'&547676767632&'&#"32767676765!5!+hSV57%&03IHXvIH7e*1.PJ?<)&%&97L.61+ .(tA.0LObekOJKKN48""++UW:*(GAQP&ROR?A  )K.%o93=.6,('"(R102I0+&#"&"'&'.'&'&'&'&'&'&5476=673 3'&'32676750)(5      Rbw67    Y07 3C !1n,"X . B TE %276547#"&#&'&576733C8 $!  _ '*2 o'Oqor 1 !$3%U38i0F,#JN!3##"'&'&'&53327676765$rSBC14fDE27NP4Zx!"BGhl_FL:;B"%8:MPS~9!#5476767632#.#"67632#4'&'.#"#";5LHM^42\hOA PQsRBE02fDF23"1bTQ82 @42<99XtI;b[;46    f  {ZKO7;B"#:AFKX4632#"'&'&33###53y8&!8&!5&8! &8!:4V#533?#"'&'&'&'&5Sfk$#$* )%&${ f"  #!13@=2 3!53#5!7Y]]Sꎎ+.3276?#"';#"'&5/"56767632:%$<2 !""!uFF;<0$! *!#%#+.& u78 !X&1%3"&'&5#"'&'&=476736767'3dq$ -8!<ڗ)-mHS7W'%# KJY#"26P7/&_`;(:+(*(h33276767#"'&'&'&5:' m/"%<&14(,-4 i, #43>ntL 3%3"&'&53!5!#"'&'7327654'&'&'dqT$!/7&}~8%POS_`019 KJY#"9  C.BAHāLK/Q54UVJ;:&'N53323#5#"'&'#"&5332 ,H5ژ ($0tJKm *B+NN1=37N.&϶+! DEih;/6+8$<N63323#5#"'&'#"&5332 ,H5ژ ($0tJKm *B+NN1=37N.&5+! DEih;/6+8$<TNN!#4'&'.#"#3>7676767632>32#"'&'&'72=4'&'&'.#"V ,H5ژ ($0tJKm#&%) *$#$kf *B+#N1=37N.a1*! DEihs?42 #  "f {;/6+8$<g>IN5!#3>32#4'&'&'&#"+6726=sRBC1443CF25 $H?CP@f1Zx!"BGhl_FO7:"!"$9>IPS%A :ED; |!l?N6%330#"'&'&'&5054'&'.#"#367632IJgAPAAH#fDF25 PQsRBE02BB!IJ| 
ZKO7;B"$9>IKX1[;(#:;[_vychIM)*FF.-KJc 1_QO66&'<7d:;GGMN}~l7H$H%#"'&5476763!2#"'&'&'&"2767653367675&'&'&#a ! 3/7`112_a a_210`6/3 !Kx<?8!B& } &A!8?:X>=QSpR$<;^]wϵ[;<?32767653#5#"P1>X>=QSpR$<;^]w3[;<UF*?327676533?#"'&'&'&'&5#"P1>X>9fk  $*!"('#!QSpR$<7bQ{  f    64>\[;<N&#"#367632P1>X>=QSpR*<;^]wg[;<TO.&#"3?#"'&'&'&'&=367632P1>X><fk$#$* )%&#QToR+<:_W}{ f"  # 24?"Z;=V747676767632/"3!5"!*) !*$  kfxt?35   f  {V%3!534#'6767632xtxfk  $*!"('# {  f    65=bN'3276767>54&+ ##;2b@93 bpHG{=5 4[h@3'lQP'bN' 327654&'&'&'&#3+33bDC 35DG|FHpqpu54[4 5'OQlOP'4`THJe&'&'&'&'&547672&#" #"'3?#"'&'&'&'&='7327654'&'&'&>'*2/""deR), 6Qt  112-+$lkXfk$#$*"("(#45[e::"'$#.1;KL,&)$%zNH& !'/6AZY3{ f"  $ 24? C$$00U)" h,476767632&'&'&#"#"&'732765,+1/(:'%,m ':<+(41&;J-m (>34#")i 4-32:' m/"%<&14(,( m+N9(/1V<$,-4 i, #43>. i(*DjVh7H476767632&'&'&#"2632&##"'&'&'&5476767673276=,+1/(:'%,m ':# _p<+(41&;%U+; 5=>K*(vX=>34#")i 4-wHPS2D2#5!326767654'&/5!# &'&54767գ~ $A"!nKIn!"#9D~)1`de014!;[_v\JL=o% 26P &uE/ ,bt2& !5!#"'&'7327654'&'&'KT$!/7&}~8%POS_a035l9  C.BCFāLK/Q54UVH=:&($27F !5!&'#"'&'&5054767632654'&'&'327&'&#"HT$!/7&bCYHVNa(!!5- M9V4019OStWrr "'$l9  C.BAHtCb`gSbL"C: P65 -g IhJ;:&'42$ +*)# .,!&}EDZ|9oo^`aIP9..>96/&'&'&5467676324'&'&#" # &1=(:)%J@>OLXyy$$FER~KM 56 S>..9PIab1/oo9>=.-DE}&!,. #&*+94#"'&'732765/ &'&'&'&53= $2>(;(%L|OLX{y$$S|MM 47 T=-09OIb`^po:=>ZEE|&!--)*+ekF@&'&#"327676767#"'&'&'05<&454767676767632<=EZXRX+'+ z 2)75=hj:/ ()68HJTsUV5)122xt* `nvM(%' LMiD[JA;RFH47=>`\%M_4'&'&'&'&#"3276767676%47676767632#"'&'&'&'&%"'&547>32H 0.FCX^//!0.GFT^IK-- ! ,+C@ge{zbdBA-,,/?CefzxcbDA-+6776Z..,+spOIC<9" P@?UTUrhKJA;9 '(;L756($.!/1ZZxZD>+,V43W-%  eJ'J%#0#"&547676?&'&'&54767632;#"32767654'&#"h%;U(*- -3CINMSH86)(;:=;IH9/("+*fAT(&C3X[ZE=/L/1"7* "J346    f  {x7:('56PQf03) 9K4632#"'&&'#"'&'&'&'&=476763232=&'&#"8&&8&&Hg#("("*$#$5!!5- M9 Y'f); "'$5&8(&8o`^2 $  "/P0P65 PAK {F  47b1 373##3{jgh{RhybF3!!yKFG`?O327654'&"3"'&=#"'&'&'&547>32567676767632/"MLtuOPPOLLBFE4KIebPM.0^f?15 &#("("*$#$kfvttvtsrqV;;:͸w0.1/SV^elne`\$ $,$2 $  "f {}9;!5!54767676? 4'&#"'67632!!#? 74 MK~SHyzXLO|L%): >2$ _(C+*)# .,!&}EDZ|9oo^`aIP9..>S?9>#!5!5/&'&'&5467676324'&'&#" !=_ &1=$:)%J@>OLXyy$$FER~KM 56 ?((?S>..9PIab1/oo9>=.-DE}&!,. #&*+C;327654'&"3!5!!!+5#"'&'.'&547>32MLtuOPPOLL {"#2/BPEB.,@ ^f?15 &vttvtsrqt\*&"  75PTUne`\$ $,tY327654'&"3!#"'&'7327654'&'&/!#5#"'&'.'&547>32MLtuOPPOLL$!/7&}~8%POS_a035T/"#2/BPEB.,@ ^f?15 &vttvtsrq  C.BCFāLK/Q54UVH=:&(9[*&"  75PTUne`\$ $,lR^327654'&"3!5!3676767632!'7+5#"'&'.'&547>32!6=&'&#MLtuOPPOLL'e@'E9M -8!o% 26P2T!8\`4*&"  75PTUne`\$ $,53 ,bf+6T#5353!672&#" #!"'&52767654'&'&'&'&'&'&'&'&547#􎎗BTR), 6Qt  112-+$lkӕ;<A^:"'/&?*2/""_,&)$%zNH& !'/6AZY78q.i)"  $#.1;I8-pfhK@#535335476767632&'&'&#"#"&'732765#;#"'&5􎎗,+1/(:'%,m ':<+(41&;J-m (uFF;<>34#")i 4-32&'&#"67672632#"'&'#"'&53276505&'&#􎎗uF(P:(*48UrUW5<=EZ[7;E?G+ 8!32+67276=4'&'.#"#,+1/(:'%,m ':[rSBC14#JA@PAgJIfDE27V>34#")i 4-Zx!"BGhl >CE= |JI!_FL:;B"%8:MPSO337327654'&'&'&'&'&'&'&'&547672&#" #"'&'45[e::"'/>'*2/""deR), 6Qt  112-+$lk\P'+C$$00U)" $#.1;KL,&)$%zNH& !'/6AZYC9Y 33!!d\ B #333##333#Xrqs\Xrqs\z$ciz%ciyJ!#!#!#!#yўkўkvv%N@6767632#32767676=53#5#"'&'&'&=354#%$#$*"("(# fDF23"PQsRBE00f"  $ 24?09O7;B"#:AFKX`=+[;323276767#"'&'&'&'&#"?F% 8 " !1 !"" "$B  &   p+632#"'&'&54%632#"'&'&54$$;:!  :!  Ax"&54763#"'Q "! "8j632#"'&547&# !. GA/167676763223276?+"'&'&'&#"#1 $&(2 #",, 7  %/#&"AT t'  #! *F  8)q3276?3#"&'&'I Ll;23)6KMbX94"!s;:Z6M)*HH@b^b47632#"/&9>:>> 8 >7=d#47632#"/&%47632#"/&9>9>(:?:>> 8 >7> 8 >7)32765054'&'&#"47632#"'&'&LW(OW(uoFQN"oFRL"TN'! RN#(N/o.0L/o.0jQ$&h?&#5b^47632#"/&9>:>>7 > 8=^#47632#"/&%47632#"/&9>9>(:?:>>7 > 8 >7 > 8x})32765054'&'&#"47632#"'&'&LW(OW(uoFQN"oFRL"TN'! RN#)N/o.0M/o.0J654'&'7^4@DE$I8>G \U)J&'&'&54?^4?D3E$I8>H  \U)bt676730"'&'&=37#;EPB#ECCE#BQ1N&*z Do9(&&(9oD p4u!!]y3 30!0!#y^y32 30!0!#y2>y !##33Zwg>74632#"'&'&g@,' ,'^,@$ , $ eF/'67632#"'&'&'&'732654#"e5VUsTJH86)(;:jh=57)2 z +'+~`27H#`>=74HFRSTML '%(Mö)+eF/B&'&#"327676767#"'&'&5476767676324632#"'&'& 72`~İ+'+ z 2)75=hj:;()68HJTsUV5R@,( ,'H9+)M(%' LMTSRFH47=>`,@$ , $ eF'qRH)676#0#&'0'&47632#"'&'& 0   -&<@+'y)   - 2# +@$ w67632+&'0'&  0 )   Lv&jOH %!!#3#67632+&/&%    0 P)   _w6N4632#"'&'&_@,' ,',@$ , $ v &!!!!!!67632+&/&0g  0 )    &3!3#!#67632+&/&۞k  0  P^)   }3367632+&/&  0  P)   :%Mh4'&'&'&'&#"3276767676%47676767632#"'&'&'&'&67632+&/&H 0.FCX^//!0.GFT^IK-- ! ,+C@ge{zbdBA-,,/?CefzxcbDA-+"  0 spOIC<9" P@?UTUrhKJA;9 '(;4HA<63$$9;JLL,! ,-A?hfzycdX  ,.@C{wBA-+ #>  /-HFT\-,! <  0-GCX^II/0 J 3 3 # #Jjc;˾^)'Jp/367676767653#&'&'&'&'&5!0-H$,8*J.- ! ,/?CeEVJGbDA-+rhLJA;7!Q '=L<'fA\JL=;!"'#632767654'&#" 2327676767654'&'&+"1} g{|!%).')&+//25%%DY 4*\W[@A*#z)2"H (5*73|~$'RT-* :03!% #%54D)h'_<32#4'&'&'&#"sRBC1443CF25 1Zx!"BGhlW_FO7:"!"$9>IPSd'647>7632#"'&'&%!32767676%!&'&'&#"d!!x]\orr.76nnts/"IImO@A#% t!FGkNB@&( כ?>؋̭jiڂOd[dc89Z]hA`bab:9]bf=V233?#"'&'&'&'&5fk$#$* )%&$2{ f"  #!13@Z5 33 ##Z0H0PkJ 3'&#'67676303# Rl^3k$#$, + )%& Þ1 f"  # nvu2#%#3303276767653#5#"'&'&'& '4! ,=;u,<=J+lL8@)&#/(&b8#" R^!374# H86)(1wj74HFRST3tD%27630320#&'&#0#"547676767&'&'&54767#5!#;#"jG`B122vyZF1326767654'&'&#"47676763!# &'&"!nKIn!"A@bd@A48QTj 3 1`de01\JL=Lyo#\32767654'&#"327654'&'&+567>;"##"'&'&'4&46 4*\W[@A*#z))z#*A?\ZY* !1} g{|!%).')&&&)'.)% |{g ~XY1" 8<7632#"'&'&%!32767676%!&'&'&#"d!!x]\orr.76nnts/"IImO@A#% t!FGkNB@&( כ?>؋̭jiڂOd[dc89Z]hA`bab:9]bf=2 #&#'67676303 676767032/"5k$#$, +,J$$J,+ ,$#$k8& f"  08680  "f 6'>p&jJ~t )#&'&54767367654'&~zz/:voTpoSjTppQbؘ|~z֘z /DTpoS(RppQH$H%#"'&54767#5!2#"'&'&'&!"2767653367675&'&'&a ! 3/7`11!/a_210`6/3 !}Kx<?8!B& } &A!8?:<*$#{Q8JI~{#$*lZ_QO6*s$%(%$t)6OQ_ZNO56Qt3654'&'&'&'503;2#&'�#"'&'#( 3MHE!\.+'BI9uZKnyl{%N WRӁ<fM <#t#X5n\t*P47676767632#&'&'&'&'&%4'&'&'&'&#"3276767676\,+C@ge{zbdBA-,,/?CeKSO@bDA-+ 0.FCX^//!0.GFT^IK-- ! gehfdRO21./NLa]ltmbghbiIM0# t -NK_[lmlspOIC<9" P@?UTUrhKJA;9 '(;`y !!!!#y0\tA/"!!#"'&/5327676765#534767>321*+2G+, (67f  (4%L<9%%*+j  =BBMtJadBCB p32NPftK\`JLB [#C!5654/#'67670320!3?0#"'&'&'&'&50547[ CA"!%!  " CA"!%!  ":.%? %&3* d%? %&3* dv1 !'!5  \Ȏ0َ 02VQ'676767632#"'&'&'732767674654'&'#6767&/&'&'&#"#O34?do%IBa\\KI=:HgQT.,(H<@1kKn XMU// oX.iP9ktz[i2134$:=>TRiekRPa32&#"3276<##2/AfNO./^f>2-8ItLMMLtuOP#d*&" 01QSbelne`\+rsvttvTL!#"'&'&/"'67>323276=4'&'.#"#367632#"!i:S*$#$0!F%F%05O8ffDF23"PQsRBE02?42   " !  ,&+PZKO7;B"#:AFKX[;323276=4'3276?&'&#"3,1263BK@*7 SfJLx5i#"!i:S*$#$0!F%F%05O8fD#8> '.+*5;%)6.;Opt:= ,42=v?42   " !  ,&+P ;5 \A>C6W +v#- U#"'&'&5467>767676?6767676767654&#"'676323267 ;y|nmEEB #&2'!CC(* sqSU)yyyz  V)7F-.$ ȎsG`b**[\:b)'H  $^|89HVUab1/1"#2    )#,rW- B]#"'&'&5467>76767&'&=67632326736767676767654&#" ;y|nmEEB #& (NB)yyyz  V)7F-.$ ȎsI1OP0'* sqSUG`b**[\:b)'H"B VUab1/1"#2    )#,rW+WI1  $^|89A%!7!&/'>76763223767676?263632/X2G a 6W& 4 *B@@B* 4 &W6jf  w   >;;>   w  /A%!7!&/'>7676322376767673>3632/nF a 6W&0*B@@B*0&W6R|V&  w   >;;>   w  Z^326767654'&'&#"25/7+"67632 &'&=47676763237:32"!nKIn!"A@bd@A{  f   <64>gLK.1Tjde01`de01#":8JI<  S\JL=73'676767654'&'#.CV*&(.1:C/]35 6 S4RO #"'&';2A@db@A"!nIKn!"VOFJ8:"#10ed`10edjT1.i?42-v_[;::;[_v\JL=`TfMd'647>7632#"'&'&%!32767676%!&'&'&#"d!!x]\orr.76nnts/"IImO@A#% t!FGkNB@&( כ?>؋̭jiڂOd[dc89Z]hA`bab:9]bf=eF4&'&#"!!327676767#"'&'&547676767632<=EZGLGX+'+ z 2)75=hj:;()68HJTsUV5)122x]_vM(%' LMTSRFH47=>`eF4'67632#"'&'&'&'732767!5!&'&#"5VUsTJH86)(;:jh=57)2 z +'+XGLGZE=<)B`>=74HFRSTML '%(Mv_]x22#:!#3676767632#"'&'&/4'&'&#"3276$"#)(7Z[" -+LG`73034C543+,4DFIsCD3 deVgZNPIL64" ZUpBC67`SFGIqs#27676767654'&!3 ##/\GQGR17 "/E62B=YWQNi13>(&TB@.+ d@#"'&'&'&'&547676767632&'&+"32767&$:5SO`ufdEG/21/HFdcxIGB21'(VSihTV4365URdkZ[ %@742.)(HJ^eikxtqmeaKI++(*()))Y9768XWrmyxonVS53AB\y 33 3##yϙTT#PQyt 33##y׺ϙt7632&'&+"!!32767b&$:5SP^vfdEG/130dcyHGC21'%VSiiTU43X65URdjZ]%@742.)(HJ^amkmjhc++('+)))Y9767YWrLYOKnVS53AC[- 67,3'jT,q33276765!5!#"'&'&q o[HI"#ͥtv%27?@[^f qsDE-<!###"'&'&'727!32#'32767676765!#y #("("*$#$kWjl"!fDG+) #\2 $  "f {!!rKIX+*ZX #!*#I)!!#3!332+32767676765! jl"!fDG+) Y}!!rKIX+*ZX #!*#j&!#!5!!67632#4'&'.#"ǘPQsRBE02fDF23""Z[;?327654&'&'&+5327654'&+"'67632#"'&q%POS_a:/17:=NbaHGIJ_Qx 4ed{d\Y<;!!'(&$,')&|~/Q54UVGz%&}JHreFGTJ@hA@/-[YmRGF'( !1-DCFMLy 33##y둝ZPwyX!676730"'&'&=333##7#;EPB#ECCE#BQ1N&1둝*z Do9(&&(9oD p4ZPwy 33 ##yxϼsT$!###"'&'&'727З #&%) *$#$kWP#\2 #  "f {y 33 3##yϙTT!P\LyJ 3!3#!#ykP^\%M4'&'&'&'&#"3276767676%47676767632#"'&'&'&'&H 0.FCX^//!0.GFT^IK-- ! ,+C@ge{zbdBA-,,/?CefzxcbDA-+spOIC<9" P@?UTUrhKJA;9 '(;4HA<63$$9;JLL,! ,-A?hfzycdX  ,.@C{wBA-+ #>  /-HFT\-,! <  0-GCX^II/0 J 3 3 # #Jjc;˾^)'Jy0< %#5!3!3<˞#b"3##"'&'&'&53327676765sRBC1443CF25 P Zx!"BGhpEZKO7:"!"$9>IPSy%!3!;3Ş##y0%#5!3!;3a##($!#5!332+32767676765!o Ίjl"!fDG+) "!!rKIX%0ZX #!*#yK&!332767676765!332+gDG+' jjA@"!P %!*#V!!99KIX+*YXy"32767676765!332+gDG+' ΋jjA@"! %!*#V!!99KIX%0YXd?7327676767!5!&'&'&'&+"'67676767632#"'&'&'&d [ZkcST58X45STijSU %'11DGHxcd03.^GDu_PS5:$&%)\BA34TYkKOYLoZ[5678Z)$.+'(++chjqtsJGR.247},R3336767676762#"'&'&'&'&'#4'&'&'&'&#"3276767676}a *(;9]\XY<<'0 '):;onXY<<'%_*'B>MVACR -)KV@C)( GN5bleQN22./OP\rWedeiagKM`--NM]XoSN\܂mQGD;7#!()|VhNmmNH?=8@&'=:ULXSyP#"3#&'&54$;##Ǻ ('\Jdc2Ξ|)"(!&"nnPwjwB5"327654'&'254&#"'632#=#"&5476lHFGIj`HFIJ{fNL ~vB@;#Nڋ !537lmFFEcgCDFEcgCD761`#hm{!ΧkkZA326767654'&'&#"&#"67632 &'&5476767632"!nKIn!"A@bd@AP[i.1Tjde01`de01#":8JFO[NP2\JL=L756($.!/1ZZxZD>+,V43W-%  ^2!#!V2*P2 %3#5!#367!3#^LFlhdj^ q0V|abF 1!.#"32767#"'&'&54767632 pL<:<:LIEH3ijtac/012_a_QN23\65ON_QN76&(;7d:;MO|{~IJ.,LM\_c/!^~2!#5333##\\q:wUXaAJ??327654'&'&'&+5327654'&+"'67632#"'&aux>gKI)!,(/9GI3467D:-*e)PMbOIF/. %$'$T$#pqdef&6B76[0&' }/0HA-.24S64#"BAQ<542! 3/6^_==z2 33##z2",z!676730"'&'&=333##$7#;EPB#ECCE#BQ1N&,*z Do9(&&(9oD p4",y5 33 ##y0H0PkE}2!###"'&'&'727M #("("*$#$kZ 2|U2 $  "f {b42 33 3##bPO2`$$f03 3%'!#ff2)-ZF0476767632 &'&7326767654'&'&#"Z48QTjde01`de01"!nKIn!"A@bd@AvfhIM)*KL{LM~\JL=f^/.ONfA/2##MLtuOPPOutLM1,$ $\`enlebSQ10 "&*srstvttveF/&'&#"327676767#"'&'&547676767632<=E+'+ z 2)75=hj:;()68HJTsUV5)122M(%' LMTSRFH47=>`R2!!#!R92[J1 3 30#"'&'&'72?R=!*) ' ,$  k3^1n   f  dt %.&'6767054&'&5'476730Lim~[H2dqVoP`iKgꦂdS5Elכ] Vt޺P$5f1 !# # 33f:ȪHNy02 %#5!3!3c2[\2!3##"'&'&'&=3327676765$rSBC14fDE2724Zx!"BGhl_FL:;B"%8:MPS}3 )3;33Z[}/3%#5%3;33Z[[ 52&3#5!32+327676767654'&!zjl@$2+猌fDG+) 6!!,K?2/&ZXM@ #!*3k2*3#3320+327676767654'&!ԗ_jl@"3+茌gDG+' 622!!,L?2 &&YXM@ %!*1%3320+327>767654'&!jl@"3+茌cHKN 62!!,L?2 &&YXM@:%!+eF4'67632#"'&'&'&'732767!5!&'&#"5VUsTJH86)(;:jh=57)2 z +'+XGGZE=<)B`>=74HFRSTML '%(Mv_]x22ayQ.U33367676767632#"'&'&'&'&'#4'&'.'&#"3276767676aa **9;PTCB*) ,+>7`O:51V..?jK:OP85/+)**?7@<uK2 "'#&'&5476!3#`0dM.LM::!.IgeJb<'Cp}b'jr}tD!##5353!!67632#"'&'&'72=34'&'.#"?PQsRBE02#("("*$#$kffDF23"[;``HJI&'&'&'&'&547672&#" #"'&'7327654'&'&'&>'*2/""deR), 6Qt 112-+$lk\_%45[e::"'$#.1;KL,&)$%zNH&  !'/6AZYCEnC$$00U)" ?L#O'jD\TfMH.20A!320+##"'&'&'727327676767654'&!#jl@"3+!茞M #&%) *$#$kZ 1gDG+' 62!!,L?2 $(VX|U2 #  "f {u %!*X62.!#373320+327676767654'&!jl@"3+!gDG+' 6S2V!!,L?2 $(VXM@ %!*-!#534'&'.#"##5353!!67632fDF23"?PQsRBE02ZKO7;B"#:AFKX[;767654'&!jl@"3+茌cHKN 62!!,L?2 &&YXM@:%!+y"3 4'&'&'&'&+';2+# '+GDgΞ艋!"@AjkΞ#*!% XY0%WJK99!!TN"2676767632#"'&'&'&'#4'&#"3276& 52>f^/.ONfA/2##MLtuOPPOutLM1,$ $\`enlebSQ10 "&*srstvttv\!67632+&'0'&%!!#  0  e )   ^!67632+&'0'&!#!  0   g*   V2 !!!!##53\ *֞fo0 !!!##53!\?6276=4'&'.#"+!!>32+6gJIfDE27 rSBC14#JA@PAJI!_FL:;B"%8:MPSYZx!"BGhl >CE= ^2{Ln^^~2~q _aAJyby5yby5yby5yby5yJef03y3!!!+!#y ^f3 3%!!'!#ff2)׈U.yJgy2dieFdieFXjR2BZ3 3#BddBX<x?16#"'732767676=#"'&'&'&533276767653&$?`?LLn.&O^^~'W~y33 52>5#yx-(.hQU 0 /$ϼs?Na!&( %<'y5!52>5#33 /3.hQU 0 /$Ha*&( %<'k0PT$!7##"'&'&'727\З #&%) *$#$kWP#\2 #  "f {E*}2!7##"'&'&'727]M #("("*$#$kZ 2|U2 $  "f {yO%52>5!#3!3O-(.hQU 2'6)*k?Na!&( $;'^Pf83!52>5!#3%8-(.hQU 5%8',f?Na!&( &<'-2)yJ 3!3!#ypkP^f*03 3%7!#fDf2)-b%3#53#"'&'&'&53327676765G4sRBC1443CF25 P Zx!"BGhpEZKO7:"!"$9>IPS 2$3#53#"'&'&'&=3327676765$<1rSBC14fDE2724Zx!"BGhl_FL:;B"%8:MPSy 33 37#yaTT!P\Lb42 33 3#bPOj2`$$7,H.&Xjw'cxH"%-4632#"'&'&%4632#"'&'&!!#3#8&"28& )8&!8& P%  n&8*! '8!&8! '8!]Pjw"2X4632#"'&'&%4632#"'&'&"327654'&'254&#"'632#=#"&54768&!8& )8&"28& HlHFGIj`HFIJ{fNL ~vB@;#Nڋ !537lmN&8! '8!&8*! '8!FEcgCDFEcgCD761`#hm{!ΧkkSg!#!!!!!!53OFF{JT`Fx"327654'&'&67632!3267676767>7>767#"'&'&'&'&'.'#"'&'&5476326'&74'&#"'676767632!&'&#"h00"\6742<;!32>!4'&'&'&+"'67676767632#"'&'&'&'&5465 ҩrZL55STijSU %'11DGHxcd03.^GDu_PS5:$[!Ovlj\[5678Z)$.+'(++chjqtsJGR.24:%bF 0!3276767.#"'67632#"'&'&'&54&= FGoK<;>rNIFG4gju_`0112_aaOM42͑hi65PN_j'';7d:;LL{~IJ-,NK]_c!0'jb'jXLn'jD^^~'jX~q 'j_aA'j.q _aAJy !!33##8[둝jZPwz+ !!33##[X+j",y'j`z ,33##4632#"'&'&%4632#"'&'&z*8&"28& )8&!8& 2",N&8*! '8!&8! '8!\&2jf&Rj{\'<P47676767632#"'&'&'&'&%!3276767676%!&'&'&'&'&#"\,+C@ge{zbdBA-,,/?CefzxcbDA-+!0.GFT^IK-- ! @  0.FCX^// gehfdRO21./NLa]ltmbghbiIM00--NK_[lm4SOKJA;9 '(;OIC<9" P@?UTT+bF"/ #5"'&'&54767!.#"27676?!a_210/caac/012_# pL<:<:<FJI~{|OMMO|{~I`65ON65ONZ _QN7\'<Pas47676767632#"'&'&'&'&%!3276767676%!&'&'&'&'&#"4632#"'&'&%4632#"'&'&\,+C@ge{zbdBA-,,/?CefzxcbDA-+!0.GFT^IK-- ! @  0.FCX^// ,8&"28& )8&!8& gehfdRO21./NLa]ltmbghbiIM00--NK_[lm4SOKJA;9 '(;OIC<9" P@?UTT+B&8*! '8!&8! '8!b"/AR #5"'&'&54767!.#"27676?!4632#"'&'&%4632#"'&'&a_210/caac/012_# pL<:<:<8&!8& )8&"28& FJI~{|OMMO|{~I`65ON65ONZ _QN7&8! '8!&8*! '8!d?Qb7327676767!5!&'&'&'&+"'67676767632#"'&'&'&4632#"'&'&%4632#"'&'&d [ZkcST58X45STijSU %'11DGHxcd03.^GDu_PS5:$&U8&!8& )8&"28& %)\BA34TYkKOYLoZ[5678Z)$.+'(++chjqtsJGR.247&8! '8!&8*! '8!e4FW'67632#"'&'&'&'732767!5!&'&#"4632#"'&'&%4632#"'&'&5VUsTJH86)(;:jh=57)2 z +'+XGGZE=<O8&!8& )8&"28& )B`>=74HFRSTML '%(Mv_]x22&8! '8!&8*! '8!#!!3 3#"'&'&'727x[dd  &%) + ,$#$k3RjX #  "f MJ)#!!3 3#"'&'&'72?[j=!*) ' ,$  k3^)jn   f  'j=kJ'ju&kJ='b&jho'j\[^2{yK'js3k*<M3#3320+327676767654'&!4632#"'&'&%4632#"'&'&ԗ_jl@"3+茌gDG+' 6f8&!8& )8&"28& 22!!,L?2 &&YXM@ %!*&8! '8!&8*! '8!y='e%'eEy'w'I'G!84&'&'&#!!2>767#!!247632#"'&'&@<:QPc ax! --QPpmWySS21>E=F؆PN++iVliba98d\[E > F > 8O3#5+"'.547676763232767>54'&'&'&#"47632#"'&'&I>?OLCDf<21DE[l ().<13'(,'%52@0'(>E=FPn)*$$ҎsjcLJ**gKT5:!";<\ZIJ;8#!73RHE > F > y(&'I(&Gy')}' IU !3!3#!#476320#"'&'&ju>E>F~N^E >  E > 2!#36767>32##"47632#"'&'&#-$#"#:*532*(>E>E8"!n-+)788xE >E >ytJ&+t&ńK!!33 ##]Ctb:D g!! ##33]G-h5A 3!!47632#"'&'&c6=F>EۍF > E >  %3"'&5347632#"'&'&8vCB>E>Ei:9u\E >E >  !!3!!47632#"'&'&f\c6=F>E}ۍF > E >  $!!3"'&5347632#"'&'&B]zvCB>E>Ei:9u\E >E >  !!3!!]ucۍq %3"'&53!!8vCBVi:9uňy'h0'_P #33 3##47632#"'&'&ϚTT>E=FN[KE > F > I+B!#4'&#"#3>32>32#4&#"47632#"'&'&a**K4-/%$.?zNIHTJIVI4-/%$.=F>EML('n?l2cLo^mkr('n?xF > E > 47632#"'&'&33#29>9>Q䞒>7 > 8 uNYb047632#"'&'&#3632#4'&'"9>9>}P 77Q252-(> 8 >7 2A"%$'nJK+&96< 333#47632#"'&'&䞒>E=FuNYE > F > I2!#3632#4'&'"476320#"'&'&#}P 77Q252-(>E>F2A"%$'nJK+&96  E >  !!33#o]䞒uNYI !!#3632#4'&'"]+}P 77Q252-(2A"%$'nJK+&96<y'k3T'tS[23 4'&+ ##!2476320#"'&'&!bcSמmvegHJ(*a`v>E>EBCw35KOaml!vE >  E >qM0&#"#367676763247632#"'&'&DG/++!"!%!tY=F>E**(<:H|2&#7F > E > [ 6!!3 4'&+ ##!2476320#"'&'&])bcSמmvegHJ(*a`v>E>EBCw35KOaml!vE >  E >R74!!&#"#367676763247632#"'&'&R]LDG/++!"!%!tY=F>E7**(<:H|2&#7F > E > [ !!3 4'&+ ##!2])bcSמmvegHJ(*a`BCw35KOaml!vM&#"#3676767632!!DG/++!"!%!tY=}**(<:H|2&#7_- '6`H'3VL>?V7327>7654'&/$47676763 &'&#"&$47632#"'&'&LZZYnF<=Z^Zn#">?RS` %}2WVp<64*'.ϐNX/2%&BA\\jH>E=FP:9R56BaJG7lRKI674OW10$!`:S34%*,/:8ZYMO98##E > F > kSKD[&'&'&'&54767676732&#"# '7327676765447632#"'&'&k>F%'/,AEL:>:02 (%$(+dKD.*32PE!.$'=E=F# $#$,+/:84*((*6y #g3%($+'/03?>:-,6"!-{hF > F > X'7fP'Wb!!#!476320#"'&'&bE7">E>E$E >  E >q[,)#53533#;#"&547632#"'&'&uEEv=F>E,uzv9F > E > b !!!!#!a\E7"Î$q[,#53533#;#"&5!!uEEv,uzvT'C:D1='C&ZT'v:D1='v,ZT'j:D1'j$ZVp47632#"/&3 3#9>9>QeeA>7 > 8Y:?bD47632#"/&73276=#"'&'&'&533276767653#"':?:>i>26GoHH%DEOGFE64"!>?o2,+$ 64NJY> 8 >7TGJJH01 ;8VRizQS+&;9A^KM;8$"!!#36767>32##"\9-$#"#:*532*(8"!n-+)788+!5276767654'&/!"#47>Njm@X02L\\jB?>--^Ro%&*(-/:8[Wp#"()54DbHA.+' ~XLd'C<x?<'C\\~'!5!3"'&'&53dqAEP#<K%(V#"@!!3"&'&533"&'&53@dqtdqj" KJY#"! KJY#"Zw<'lIZw='@TJZw<'I'CZw<'@I'CZw='I'vZw<'@I'vZw'')Zw''@/H'H'@[&'C\|['C`|[&'v\|['v\|['&|['&|k='IJk;'@323276767#"'&'&'&'&#"1F% 8 " !1 !"" "$B  &   9"Q4632#"'&'&%4632#"'&'&67676323276767#"'&'.'&'&#"8&"28& )8&!8&  !#%#0%$/ 1 !"""$! *I&8*! '8!&8! '8!W-$ &   !vt:'0'CutN'-tt','v32#'&'&'&'&   u<&- )H8    [ #2 - $Kg$&+(0dL2%632'&'&7476%47>32#'&'&'&'&  <&- )H8    #2 - $Kg$&+(01y+F67>323276767#"'&'&'&'&#"4767632#'&'&'&'&1F% 8 " !1 !#! "$BD',@'H8    &   N $@, #Jh"+'+v' v &q v'Cl['j*[ v'v['j+^ Zt<'AI Zt<'@GI v<'[ v'E'j,[ BZ.&BZ'q=}'C\'v\&@<(9'%&'&547676324632#"'&'&%4632#"'&'&   l8&"28& )8&"28&   n&8*! '8!&8*! '8!P):%632'&'&74764632#"'&'&%4632#"&'&  8& 8&!)8& 8&"2   &8 '8"&8 '8*"<#"'%&'&54767632       7'Cb7tH&7t<'v67;'7t;'6v'C\'v['C\x5'v\t5&<%632#"'&'&5476L      dL;47>32#'&'&'&'&d<&- )H8   #2 - $Kg$&+(0v:!!v;Ȏv:!!v;Ȏ!!X!!R!!:!!ȎE2###222SD*_>6c4:NjDAMQDr'MHMa>'NJNq2R[>|Q * #!5!3!)uuU*!!#!5!!5!3!)v1ώ;eHi47632#"'&'&;oDTM nDTM gN/n,3M/n,3 2F kF\33"&54767632,@$ ->( @,(>-( \#3"&54767632!"&54767632,@$ ->( D,@% ->)@,(>-( @,&>,) \#5!"&54767632!"&54767632!"&54767632d,@$ ->( X,@$ ->( D,@% ->)@,(>-( @,(>-( @,&>,) D I47632#"'&'&MLm_GFMNk^GFGlKK:8[lKL::YsiE <\i2654'&#"32654'&#"#3476767632#"'&'&'&476767632#"'&'&'&2654'&#"476767632#"'&'&'&()xX+,=3Zl''A3/4#(()xX+,=3Z%$23<122&(0%&10>3/4#(uI()RHB**NyH()RGB**N M501&%$"#dB7.0%% %/1501&%"#21C7.0%& %/2I()RHB**NH501&%"#dB7.0%% %/1 si DE <\i2654'&#"32654'&#"#3476767632#"'&'&'&476767632#"'&'&'&2654'&#"476767632#"'&'&'&%2654'&#"476767632#"'&'&'&()xX+,=3Zl''A3/4#(()xX+,=3Z%$23<122&(0%&10>3/4#(()xX+,=3Z%$23<122&(0%&10>3/4#(uI()RHB**NyH()RGB**N M501&%$"#dB7.0%% %/1501&%"#21C7.0%& %/2I()RHB**NH501&%"#dB7.0%% %/1CI()RHB**NH501&%"#dB7.0%% %/1'476;2#"'&'& $ ,,'46;2#"'&'&%'476;2#"'&'&,  $( $ FD3##mD###g"3F#&'&546324632#"'&'&#&'&5476324632#"'&'&V)<&(@,(>-()')<@,' ,'(6%,@$ ->$ f)6&,@$ , $ 7F%4632#"'&'&? 4'&#"'67632#54632@,(>-( 4 MK~SHyzXLO|L%&= >2$ <&(^,@$ ->$  ,!&}EDZ|9oo^`aIK>..>S8(6%c%#"'&'5!2767cٲרn@@>>rJJt ZR ''!!''!!''!!TTTTTT6TTT/'7'7'77'd8RR88RRR88RR88R"m?#3)9$%4632#"'&'&%4632#"'&'&#54767676? 4'&#"'676326732#54767676? 4'&#"@,(>-(@,' ,' 74 MK~SHyzXL9,MENO>@%&&):$=1& 65 MK~C< &%&= >2$^,@$ ->$ ,@$ , $ +*)# .,!&}EDZ|9oo@/1MOJP9..>S+*&# .,!&}EDO`aIK>..>91CVi67032#54767676? 4'&#"#&'&5476324632#"'&'&%4632#"'&'&9MENO|L%):$=2%  65 MK~C<@)'(@,' ,'@,( ,(@^`aIP9..>S+*)# .,!&}ED)%,@$ , $ ,@$ , $ g 2EVi67032#54767676? 4'&#"4632#"'&'&#&'&5476324632#"'&'&~MENO>@%&&):$=1&  65 MK~C<@,' ,')')<@,' ,'@/1MOJP9..>S+*&# .,!&}ED1,@$ , $ f)6&,@$ , $ yu$<"&#27636767676767654'&'&'&"#!32 dP* &'#'"KZhŌywfc9:  /)5 L ;  "2')#u10NOb&-/)+ 3'#'&'&'&54%6;N! o y 6n->(*oL732#'37 !N Lo*(>-n6   Z ''!!`TTTZq#H,74767632#'&'&'&'&47632#"'&'&q(,@(H8  -&<@+'^ $@, #Jh"+'+- 2# +@$ >'%)%"'&5467632"&54767632#3A- 2# , ( ^,@$ , ( %ѐ -&< ,' @,' ,' D?3\+67>323276767#"'&'&'&'&#"?F% 8 " !1 !"" "$B  &   m?%72#"'&547676#"'&'&54632#"'&'&54632, $ - * >-&@,( >-&@,(  -( ,( .>" +@) Y.>" +@) m'9K2#"'&547676!2#"'&547676#"'&'&54632#"'&'&54632, $ - * , $ - * )>-&@,( >-&@,(  -( ,(  -( ,( .>" +@) Y.>" +@) m%8J\2#"'&5476762#"'&5476762#"'&547676#"&'&54632#"&'&54632!- 2# , ( - 2# , ( - 2# , ( ' -&<@+'  -&<@+'  -&< ,( d -&< ,' N -&< ,( - 2# +@( Y- 2# +@( d;+##"'&'&54632#"'&'&54632:@,&>,) >-(@,& ,@% ->)[.>" +@( %+':N2#"'&547676%2#"'&547676#"'&'&547632#"'&'&547632- # , ) - $ , '/@,& ,)  -( ,&  ,( -(  -& +( ,@$ , * ^- # , ' d<s%8#"'&'&547632#"'&'&547632#"'&'&547632;@,( ,' @,( ,' @,& -) ,@$ , ( Y,@$ , ( E,@# , +dm<+#5H#"'&'&54632#"&'&54632#"&'&54632#"'&'&54632:@,&>,)  -&<@+'  -&<@+'  -(@,& ,@% ->)- 2# +@( Y- 2# +@( E- " +@(0Q167>32#"'&'&54326767654'&'&#"B!!lBd~XcCA &0 % I;;HwHMqX\xLJwFJRR:>I('*('214D=E)'*+091@#73#{aDPB'767632!!5476767676?>?4&#"ʆ JIX&D !.   ( _ !. <&( #5O87:,-0 ,#406 '!"!5<.3S>7327654'&'&'&+5327654&+"'767632#"&'3 < 8&% JT"4"  9:H885##QRtHs+!(!!6($2 > >%%65A1)'&$-rIJXJA 3##5!335$^^WcW60H2'!!632#"'&/732654'.#"-    o7)&_CE>;PbFH "V2> >"N9} 9:\ &I?=*(9:Z%cJA.:0714'&'&#"3262#"'&'&54767676?3  +1  (3Bv_FI h8bBE  ("#-&B.9;Y .,0"#.;>S '*52l #!5lЧ:c%6I#"'&'&5476767&'&5463232654'.#"27654'&'&#"AA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$0O^= !?Lx#";;\/'& *>`~.(".%$3)@7 *-4:327654'&'&#""'&'&547676767632#  +2  !'2" u^GH  ,*.`ED  ("#, (" ::Z&$&<;V! " -F  533##5#53P4(!!P(@g!!!!@**C<lr&5476?3#'&]! ? &~#"9& <Doxgrlc7egcT7^3rh#767654'&/3%= !#$7% 9"# >r7[dd_ehkP7Zotqmon_B&!#3632#4'&'&'&#"Ԓ2D/*'   _$)%>@I1+! #+0Q1767>32#"'&'&54326767654'&'&#"B!!lBd~XcCA &0 % I;;HwHMqX\xLJwFJQQ:>I('*('214D=E)'*+091@#73#{aDPB7'767632!!5476767676?>?4&#"ʆ JIX&D !.   ( _ !. <&( #5O87:,-0 ,#406 '!"!5<.3S>7327654'&'&'&+5327654&+"'767632#"&'3 < 8&% JT"4"  9:H885##QRtH+!(!!6($2 > >%%65A1)'&$-rIJXJA %3##5!335$^^Wc W60H3%'!!632#"'&/732654'.#"-    o7)&_CE>;PbFH "V2> >"Z9} 9:\ &I?=*(9:Z%cJA.:0714'&'&#"3262#"'&'&54767676?3  +1  (3Bv_FI h8bBE J ("#-&B.9;Y!.,0"#.;>S '*52l #!5lЧ:c%6I#"'&'&5476767&'&5463232654'.#"27654'&'&#"AA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 *-4:7327654'&'&#""'&'&547676767632#  +2  !'2" u^GH  ,*.`ED  ("#, (" ::Z&$&<;V"" -F 7533##5#5?P447!!P4@s3!!!!@**C~7Zed_ehkP7Zotqmon_?  ,"327654&#"'&547632&'&#"'762#,(22( 44!!^@?ABZ;% + SKĂ$2"$0#$0 >>b_?@ o>t' 0 273&'&#"3276?#"&'&54767632!µ&   zDMr:8M:/16<$%!6";DZGFWUGE-+T50;#*%0/76767632#"'&'&543276767654'&'&": 31=Rt:;RR:; $  F0o8,*VGEGF----GIT==(#& &,7'(*N4G #'#373Gc_`_0.1 5#327676'&'&#"'767632#"'&'&'&5050=!&b&   =>CL:9;:K:/0HR$%"6";"#.-GITSID-,+*50:$D I47632#"'&'&MLm_GFMNk^GFGlKK:8[lKL::YD I47632#"'&'&MLm_GFMNk^GFGlKK:8[lKL::Y*)!&'&5476767632&#"!!!!!mFE/.EDQYB}JV*'%4,:MU,8u$ 39@#"'&'#7&'#&'&54767>?3273&'326?&#$T^`# )N4 37^'# %3M?w& Q+%* !d<<}567m!Qpl{ouTZ|2`;#6;3 *#Ckb@YJ#"'&'&5476767632&'&+"3676767632&#"2767؁^ilwolTR`,*RPnofiM.SP]]OQ9< '$65<"!%!tYBDG.,+! *ZFI.%C;=21cali<<;=sBB0.12TWqpkWYMI::##7|**)xEBDU3#535#53!!!!!!wwww..y؇S;؇d6/37632&'&#"!!!!!2?!76767#537#d k!d9'io~"7+P-y+;T  i6 q`>OF32673;2$++J- ͝j**L3-/%$.?zMI-0iHILKnEdML('n?l2cLE09kk#&)##!##535#533!33#)'!35!%35#wwwwwykwwU55yy؇SS؇HRnTel%#53533#303%276767654'&'&'&'&54767676;2&#"#!"'&32!#3 !Un.$)k>C'(.,BAO9>;02 ($$(+hJC.+32Qb;:yfcIG)(88؇,u ##+~E# #$%+)1=67)'(*6y #g3"'$,*.,8A<:-,6=;[42NLgop$ ^hz#"&'&'&'##!23276767654&'&'&'.5476767632&'&#"4'&'&'&+32767>^%'66JHBLDJ>=0؞m[h^SPb01C>P~I9(Z0289A&,')#T?T4H@?T4/BAB4;823!# =?@"H *&C2VFB>+*#"86FBGL?G57D)K;?)*.-G20pRCE01# oP9@ &$->N$$$fUG;6'$ *,9F$8" '%:9S54 j? 4 7!?#!'#!7###!##53'#53333333#3xNP-+2A.->19RP>0 A-WX&p]GGO)T8vciv.(330#53>32.#"!!!!3267#"&'#53&54'}q}M`2XQ<_,"i0E\>`<9[7&:K`3+ZJ MW+Da/!!!###53333!!ucwwLwfgzz+p!%%#5%55%!5!p755˞NN"E$mmmmwwww| +#324+32 3 !0IHF|MNFFW f1 +h<;77o`X &Gd3276767654'&'&'&#"2#"&'&'&54767676324'&'&'&'&'&#"'63>!!0.BA43'",+=;B5),=&V#,$:92Z55OOpm31/1FF_4*'B / -(9:<)%%-& 7<=45"! 4-C=<>?>..$'1585 &>6FMDUY2_c`PO21LB@[XgQVUAC** $ , >SERH;<)r',7!323#3#+##535#535!2&+4'&'!!676>'qFFq<~Ϟwwwwm_PLWPч    k:;Ws67mLL  s  ,8#5&'&'&'&54767676753&'6767#53+*CARQDG1410GDXU#DFT64\/'&~gXYDB/-+-EJ`a}l\_LJ64x5B_QO9B'&84GCM!#!##537!5!3!!3# '!2@@1up;+)䇇8Ȉo+n\!327676767#"'&'&'&54767#5367676767!5!654'&'&'&#"'6767676323#!n 8/0;<@E67-,') V]Y\CE++Du1,;.AH<()53;i5}/-/63D>P3X,B;$Dn'(#"032P68NOe &" =H!":@SY]_:;# "'&5!##533!33#3 B@@www:9u_66piLOju#5#"'#5&'#&'.'&'&54656767667632>32676767654%'$476767632&'&#"4#"37'54#"'54'&#"OlKOTTK4gG>T  $!T8$E<4,. "n#">?QRbkmG%}3UUq=63*),34hy]W0/-(?@-(+- QFGn&( =5H^!L  " $1)V0&Z\q"#,.492eoRKI68./e4OX00$#^:F9:%3,*'.,?Sg#"'&'&'&'&547676767632&'&+"32767;27654'&'&#"47632#"'&'&".-L_PQ76.8' 09;RO`=67&## xDCTFBG.1#(/luNIH{!&"'@4167KB208>4206))HDcxUTTGgEG-+,)'*))Z879=QXpmyzn~LB?^I (+L45)(?K55)'@"]+#"'&'&'&'732767654'&'4!5]c;6:jh<5;'. z )',X:.fj+YmUxML$ %(MvNp FZx>y+5!!327654'&'&#"47632#"'&'&33# v ('4<** ('4<**vLLn_GFLNl_GEf:71"!+,?2"!,+ClKK:8[lKL:9Z>P2y"3 4'&'&'&'&+';2+# '+GDgΞ艋!"@AjkΞ#*!% XY0%WJK99!!yP32676767654&+ ##;2\'( Sמcd"&$%,|wlmnnxw* 33##!###+sĉt_ bwM>7cP5K%&'&'&547676767632!!5676767654'&'&'&'&#"3!7 ?,+,+C@ge{zbdBA-,,-HK9;!  0.FCX^//!79EI^[lmlgehfdRO21./NLa]ltmbghbeK(@BRUORUspOIC<9" P@?UTUrhKJE9: 10+B327673#"'&'&54767632!"%4'&'&#"3!276 20FHOmacBmpk?7ه{ f  $!15>/R K R K &>DH7327654'&'&'&+5327654&+"'767632#"&'#73#'[ < 8&% JT"4"  9:H885##QRtH{a+!(!!6($2 > >%%65A1)'&$-rIJXJ 9A7H5B'767632!!5476767676?>?4&#"732654'&'&'&+5327654&+"'767632#"&''Ά JIX&D !.   ( _ &. <&( # < 9J JT"4"  9:H885##QRtHË5O87:,-0 ,#404!'!'!6<.+!(B6($2 > >%%65A1)'&$-rIJXJ]9A739=%'!!632#"'&/732654'.#"#73#'M    o7)&_CE>;PbFH "V2> >"W{aZ9} 9:\ &I?=*(9:Z%cJA.: 9A7L-Bvz'767632!!5476767676?>?4&#"'!!632#"'&/732654'.#"'҆ JIX&D !.   ( _ &. <&( #    o7)&_CE>;PbFH "V2> >"S5O87:,-0 ,#404!'!'!6<.j9} 9:\ &I?=*(9:Z%cJA.:]9A73->rv7327654'&'&'&+5327654&+"'767632#"&''!!632#"'&/732654'.#"'3 < 8&% JT"4"  9:H885##QRtH    o7)&_CE>;PbFH "V2> >"Ss+!(!!6($2 > >%%65A1)'&$-rIJXJ 9} 9:\ &I?=*(9:Z%cJA.:]9A7A- @D3##5!335'!!632#"'&/732654'.#"'$^^Wc7    o7)&_CE>;PbFH "V2> >"SW69} 9:\ &I?=*(9:Z%cJA.:]9A717;4'&'&#"3262#"'&'&54767676?3#73#'  +1  (3Bv_FI h8bBE {aJ ("#-&B.9;Y!.,0"#.;>S '*5$ 9A722Edh'!!632#"'&/732654'&'&#4'&'&#"3262#"'&'&54767676?3'6   n6)&`CE>;PaGH #U3> #  +1  (3Bv_FI h8bBE O9} 9:\ &GA=*(9:Z%cJA /g ("#-&B.9;Y!.,0"#.;>S '*5,9A7%6IOS#"'&'&5476767&'&5463232654'.#"27654'&'&#"#73#'AA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$s{a0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 * 9A75>du7327654'&'.+5327654'&+"'767632#"&'#"'&'&5476767&'&5463232654'.#"27654'&'&#"'5 < 8%& 0JT"! ;:H885##QRtHAA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$os+!(!!6($ > >%%65A/+)('*rIJXJ{0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 *r9A702Xi|'!!632#"'&/732654'.#"#"'&'&5476767&'&5463232654'.#"27654'&'&#"'-    o7)&_CE>;PbFH "V2> >"AA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$oN9} 9:\ &I?=*(9:Z%cJA.:{0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 *r9A72+<OS #!5#"'&'&5476767&'&5463232654'.#"27654'&'&#"'lЧAA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$o0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 *r9A7 #73#'{a 9A7733P\!3!3>PP !3!3!3>>PPP 3#33mGBPP{3#3)GBP{ !33#3U7GBPP{!3!33#3z>7GBPPP{!3!33#3z>7GBPPP 3 3 # # 3jc;˾^)'J'PJ 3 3 # #Jjc;˾^)'JJ!33 3 # #jc;˾P^)'JJ!3!33 3 # #6>jc;˾PP^)'Jy3!!yeݍd@#"'&'&'&'&547676767632&'&+"32767&$:5SO`ufdEG/21/HFdcxIGB21'(VSihTV4365URdkZ[ %@742.)(HJ^eikxtqmeaKI++(*()))Y9768XWrmyxonVS53AB\y)4'&'&'&'&'&+327676767#!!2 %*,2HIS~\[55''JIprDpqIK&'E=F?D8@(.j**PQfhdc78=>ehy 33 3##yϙTT!P\Ly54632#"'&'&3#y8&!8&!5&8! &8!yZ&*4632#"&'&3#4632#"'&'&3#8&"8&"28&!8&!5&8" &8*!5&8! &8!y&*<@4632#"'&'&3#4632#"&'&3#4632#"'&'&3#8&!8&!8&"8&"28&!8&!5&8! &8!5&8" &8*!5&8! &8!y54632#"'&'&3#y8&!8&!5&8! &8!R1!3 31nR4632#"'&'&3#!3 3B8&" 8&"i5&8' &8 1nRH%);?F4632#"&'&3#4632#"'&'&3#4632#"'&'&3#!3 38&"8&"28&"28&!8&" 8&"i5&8" &8*!5&8*! &8!5&8' &8 1nR#&*14632#"'&'&3#4632#"'&'&3#!3 3g8&"28&!8&" 8&"i5&8*! &8!5&8' &8 1ny !!# # 33 4632#"'&'&3#:Ȫ8&!8&!HN&8! &8!5f1 !# # 33f:ȪHN5!4632#"'&'&3+ # 338&!8&!:Ȫ5&8! &8!HN5&*64632#"&'&3#4632#"'&'&3+ # 338&"8&"28&!8&!:Ȫ5&8" &8*!5&8! &8!HN~ %3"&'&53dq KJY#"eF/&'&#"327676767#"'&'&547676767632<=E+'+ z 2)75=hj:;()68HJTsUV5)122M(%' LMTSRFH47=>`#23#5#"'&'.'&547>32327654'&"6"#2/BPEB.,@ ^f?15 &MLtuOPPOLLR*&"  75PTUne`\$ $,vttvtsrqN5!#4'&'.#"#3>7676767632>32#4'&'&'.#"V ,H5ژ ($0tJKm *B+#N1=37N.a1*! DEihs;/6+8$<g>.E_#!5#"&'&'&'&5476767676325!23276767654'&'&'&'&'&#&'&+"3276('qrD6FP`tDG/11/HFdcwIGB2 pq'([[55 %*,3FITn MSjhTU4585TRdlZDח88?*RGJ^ampsovmeaKI++ 5=>ʃj**PQfgE=?FD8@(.pQ3767YZomyxokYT43A0y)4'&'&'&'&'&+327676767#!!2 %*,2HIS~\[55''JIprDpqIK&'E=F?D8@(.j**PQfhdc78=>eh&'>O4'&'&'&'&'&+327676767#!!2;#"47>763!!"'.'&. %).3EIT\[54('qrDpq'(55[[TIF3,*% ('qpDrq'(E=F?D8>*/j**PNig88=>ʃhfQP**.(@8DF?=E>=P88ąd<73276767654'&'&'&+"'67676767632#"'&'&'&d [ZkcST5845STijSU %'11DGHxcd03.^GDu_PS5:$&%)\BA34TYkoxymoZ[5678Z)$.+'(++chjqtsJGR.247eF/'67632#"'&'&'&'732654&#"5VUsTJH86)(;:jh=57)2 z +'+E=<)B`>=74HFRSTML '%(Mõ22d@#"'&'&'&'&547676767632&'&+"32767&$:5SO`ufdEG/21/HFdcxIGB21'(VSihTV4365URdkZ[ %@742.)(HJ^eikxtqmeaKI++(*()))Y9768XWrmyxonVS53AB\BA 7%{eg,{f*hy)4'&'&'&'&'&+327676767#!!2 %*,2HIS~\[55''JIprDpqIK&'E=F?D8@(.j**PQfhdc78=>eh&'>O4'&'&'&'&'&+327676767#!!2;#"47>763!!"'.'&. %).3EIT\[54('qrDpq'(55[[TIF3,*% ('qpDrq'(E=F?D8>*/j**PNig88=>ʃhfQP**.(@8DF?=E>=P88ą01pt67>32#"'&'&54326767654'&'&#"7327654'&'&'&+5327654&+"'767632#"&'#3B!!lBd~XcCA &0 % . < 8&% JT"4"  9:H885##QRtHѐI;;HwHMqX\xLJwFJRR:>I('*('214D=E)'*+09+!(!!6($2 > >%%65A1)'&$-rIJXJ.x% !!x@& '#@&x!5!' R&@%37 (@x  !' 78@@@@ %7  ':@@@@4X4jn\tlZZn4X%''lZZnZn4X 77!ZnZn\4X !n\rn\ZjxXh! !3!!#H@@llx^jHxXh!' 7!#!5!3@@jjl HH%327632'&#"#&/,^^PMfaG7p@J,`^^^^L,OBp, 2N"$#"'763232?'8[`]/H@p6HafKP^^N1 ,pBO,L^x 37!!'# 8"@8@"@  '#75 :"@8@"@x #7!5!'3' R"@8@"@ %5'377 "@8@"@x< ! !73#$@@였Ȁx< 7#'3!' 7!Ȁ@@x 53#5! @@f@@  %3!53 '8@@@@@x 53#5! @@f@@  #5!#7 Z@@f@@xt 7!!7  'xddd@@v@@x^! %#Z@@&X&|!#' 7!&@@Zx^3! !ހ@@(|!' 7!3@@ڀ@x5!7 xT*@@Vx3! !@@(HB &'&'&'0#"767676303GJ U+d^R4l ˩ZWΡXZHMIO:\T_ZmlHB 6767670327'&'&'�#HWZ ƥl4R^d+U JIşlmZ_T\:OIMHZX4X !!!4jn\Z$jZ\n,x  !!3!5!' 3@DdF@0dȀZ`/3276767654'&'&'!#"'&'&5ghkl3+:)i5CXRO= 1G:;~ /36%ddrk/*A/`<7M98yz ,A@9?o0`/#"'&'&'&5476767'!'3276767650 ~;:G1 =ORXC5i):+3lkhg?9A, zy89M7<`/A*/krdd%63/x `!x@@ @x !f@ @ '#@@f@ #@Z@fx^5!'x@@x !5!f37h@@3fBx  !!!5!' x@&&@ ʀJ@ '#37 J@&&@x %!5!' !!R&@f@&x6 !!-!!->,:8.8 #%#j,:8.8x6  7!5! 7!5!:,:8.  3% 3:,:8.x 7!=!@f@@@x !=!'f@@@@ b '!!!!eh""nTZHHU!  #7#!#UnTZHH@lh"" b '%5!5%!5e""fZHHHHHU! 33!3ZHHeh""  '%5 '!!!!eeh""fZnTZHHH %!'!3#3a%QPRK327654'&'&#"#"&'&5476324'&'&/&#"'632 KLHpVV_]h:53:>FB|{ no+"(   548tE[%N$.1/uDDlm'rOM53F{sp$!5H=K&㙗HPć   !(^ih2VFy )5!!5!!5!g0^X&$7H47>76763273#"/#7&'&'&7&'&#"%3267>54'&'&^ dECFCGmY;_% JKtrld ]'P u '" 97BFB<9%#zm:*"Y}8>2,L8#/.OLf 420Z.(L<4x33%!xFE#n`Bx!# x>`B";#"'&'&57676;#"!!SRVresssseuSQSgf$-;;-&dgm<!&.#&57676?33#!!;#"'&'# x\ss`}AAS|COVrecd@;QS;-]EE+%_ &dg:^Bq 5! #!5!276767!5!&'&'&'&#:f?ssefvRSAk @>hfСƀ-$\I_?42n@!#!#nҞjPn@33!3nP@:y %5 5% %(lP0<D:!!DDȎIH(;#"/#"&57#"'&54?'&547632'46327632@ ') *' (( '* )' }q"*& *" (+om+( "* &3#!5!]ۯڡ3'uC&~DCC3276767654'&'&#"&'0'5#".54767676326763"30/BA/07:ST:7 A($&&$>54'&#"dbPr@AbVn+"kk NQ'0jk"+VbA@rPblxdFGo`ۼܚvu , uvi`oGFdx63h%!!!mh8O! #3߀OKPO3#3{!Py4'&'&'&#"#476763243?BIz\]"-gfg@? STSugeuty3#"'&'&53327676765졊ŀ-"]\zL?=54òsteguSTSA@gfT )%547676767032&'#"/7>54#;DB&(16]&D#;DB&(19]&DAOPF= $ j1AOPF= $ j1\-?#"'&'&5476767632"&54767632!"&54767632P, !+ !t,@$ ->( D,@% ->)3& $% $ @,(>-( @,&>,) ?3Z\&6767632276?#"'&/"?,.,- %">;-),) ,& -*.&Bb>&*.67>32276?#"'&/"!!!!E,X. %";CH(*#*L9 ,*+('%#>>;.)*)    ,& -# .&a?\/[676763203276767#"'&'.'&'&#"67>323276767#"'&'&'&'&#"?!#%#0%$/ 1 !"""$! *F% 8 " !1 !"" "$B-$ &   !  &   p7##537!5!33!!!̙ϐ NTBb !!!!!!B   Xm> 5 !!hZg[/uѴm> 5-5!5yZ[u:^Bq!"3!!"'&'&5476)Bfh>@>RTOyfess?f24~K{[^"-:^Bq5! #!5!2767654&'&'&#:f?ssefyOTR>@>hfСƀ-"^[{K~42_%!0#3!!"'#7&'&547673G`t`AJUsOKR#1i7oH5\F 'LgoZ  %Khb9)d%!5!"3!!"'&'&5476)Kji7oHIVrgst?%Khb9:$ghond7!!5! #!5!2767654'&'&#dK>hsUIHo7ijtnoĞ$:9bhK%^X'1>H47>767632#"'&'&'&67676767!%4&5&'&'&'&'!^ dECFCG% JKtrldeQP y''86;%&B=:$ E*+86<!B<9% 1eWVt)(<3uw?>**\Y}8 L89%$>20L/5L<=$#5 /.O*6^X%0;E47>767632#"'&'&'&77'32767'67654'&/&'&#"^ dECFCG% JKtrldeQP u # #6;:**\Y}8>2,C7La$$LZ.(L< G"^%!!5!3OP"RT4632#"'&'&RL51!# L5.#$ E7J* 5L+ RDTF47632#"'&'&R&(31!# L5.#$ 7%&* 4L+ f !547676767032&'g +23$'FЏ# 59- 0#"/7676= +22%)F 0# 79-9% 3 UagX97# 3aaeZ #3o(ک0~S 3!!%~:e'%3"'&'&5"'&'&53;&crADrADc K%'W#"%'W#"Ky!!!33#;#"'&5!#yuFF;32;3276767653#"'732767676=#"'&'&'&5# MLtuOPPOutLM#":8JFO[NP21 [i##2/AQEB.,@ ^fW5: fDE26&#A>JHQՖjh4,3%)QRqSBC14vttvtsrs bTQ75!"21<99Vv!*&"  75PTUne`\ _FL:;B"$:;KPSaUO96U{!76GY<=!"BFjl&7<)$f@+H#5353%3276767653#"'732767676=#"'&'&'&5%;#"'&5􎎗fDF23"&%>8RKMՖjg2.3%)PQsRBE02uFF;<ZKO7;B"#:AFKX`UT61!U{!76F[;34# ,i 4-V}xE4632#"'&'&#53476767632#"'&'&5654'4'&'&!#!#F8&" 8& ,(41& /)'8&   %ėҘK&8" '8 b6>34# TQG '8& 2$-V}cz0#5354767676320'&'&'&#"#!#,(41&<%!.   ':—Ԙ6>34# +  / 4-Vdx"<##53476767632&'&'&#"!#%632#"'&'&5476+(41&;J-m (—K    V6=45" (*i .G  }x#DK0#"3###53547676767673##!5!476767632&'&'&#"3%#'#3.',/2Ę,4&D@c`혘!+(41&;J-m ( &%"V.C4.6$V6=45" (*i .V}w9KW#!##5354767676767632#"'&'&5654'4'&'&!#4632#"'&'&%!47fҘ,E {&*/)'8&"  %ėx8&  8&"\'42,UV.C4.F5=%TQG '8' 1$-&8! '8!H &%"60}) 2!7#!##53547676767%'#h'42,Ҙ,(2O7Td  — &%"}UV.C4.*!6dSS   }x :T!47#!##5354767676767632&'&'&#"0!#%632#"'&'&5476h'42,Ҙ,E {<%"/m ' —O     &%"61VV.C4.G4=% ,i  1G  436767632#"'&'&543276767654'&'&#".-ACQxSP"''l|RS!ZA0&' ,+@0&) \ON+-_\g_xw_a^`iiXQj|"#;=DLBY]f>=#%;>FKL%1 !53#5!#3LٞMF'767632!!5476767676?>76?4&#"o_`s1-.(-# * '(T.(,+1 ! fC@865iGH #'87C(H$%'"%G?D/.3,$##  $(0Zf)(Njx2?7327654'.'&+5327654'&+"'67632#"'&j%ORPa`^:8?Nb`IGIK^Oz5edzd\[;: !'%)%+%+&|~z-O13RQH8:FxGFmaCERF=e>=--VUiRAC&# 1,@>F{|JIV/ 3##!;!]^ ~$ts#Voe23"'!!632#"&'7327654'&'&D   ^B[tv" j҇.T߄RQ PP    KT7ab=@ڊơa`,'pLKv54'&'&#"3276632#"&'&547676767673dQRrRTRQiUUFH@|}! ! :8YWf N!hCCZ\s!f??WVde%9NNL@>('Β/(;9=3"7&.*HT2 #!5ն2PT%L%27654'&'&#"327654'&'&#"2#"$'&547676767&'&5462bb]ZuDC_oGFAAewBCSKLDCqo" *,&)( q]]" mCA(oU21A@rQ10BC0m&KLj+%kj<;Ο2.LEB-/U+,ve2532654'&'&#"#"'&'&54767>7632# sRPjUVH@} '+fMKOvt " |"gw'eA@XYef/0>?A6;Rge+,7<7;5#84ZxB-7&/054763253#5#"32765&'&#"knf !537X@B`HF=?vF36!=YqtmWFϜ!ORFE`:LN!LZx='Ca~Zx;'v~Zx'bn~Zx'Z~Zx'~Zx'jb~ZB'*~Zx<'~Zx)&q~&&2@4'&#"'6763267632&'&#"327#"'&5"#"'&'7327656>F(?V!Jr?)VnLV=&J>*:9;^JVH<9AI_?=9>u %^6uG -5MN_XLM94"ϚTT>7 >7 %7J++$$H@bN[K*V47632#"'&'&327673#"'&'&'#4'&#"#3>32>32#4&#"9>:>y %^5uH +5NLaWML94"˘**K4-/%$.?zNIHTJIVI4-/%$.7>7 > 8 Q 7J++$$H@b+B!#4'&#"#3>32>32#4&#"327673#"'&'&'a**K4-/%$.?zNIHTJIVI4-/%$. %^5uH +5NLaWML94"ML('n?l2cLo^mkr('n?I 7J++HH@b3!#3632#4'&'"327673#"'&'&'#}P 77Q252-( $1/5uH-6aWML94"2A"%$'nJK+&96<I"5 o 1S=LT$$H@b[\43 4'&+ ##!2 327673#"'&'&'!bcSמmvegHJ(*a` %/.7uG -5MN_XLM94"BCw35KOaml!v\7n(R>J++$$H@b0&#"#3676767632327673#"'&'&'DG/++!"!%!tY %^5uH -6LMaWML94"**(<:H|2&#7 79>)9>9>$>7 > 8 >7 > 8>,$6#53533#;#"&547632#"/&%47632#"/&uEEv9>:>)9>9>,uzv->7 > 8 >7 > 8L>?Qc7327>7654'&/$47676763 &'&#"&$47632#"/&%47632#"/&LZZYnF<=Z^Zn#">?RS` %}2WVp<64*'.ϐNX/2%&BA\\j49>9>(:>9>P:9R56BaJG7lRKI674OW10$!`:S34%*,/:8ZYMO98##>7 > 8 >7 > 8kSKDVh&'&'&'&54767676732&#"# '7327676765447632#"/&%47632#"/&k>F%'/,AEL:>:02 (%$(+dKD.*32PE!.$'L:?:>)9>9># $#$,+/:84*((*6y #g3%($+'/03?>:-,6"!-{\>7 > 8 >7 > 8U /3!3#!#47632#"/&%47632#"/&jv9>9>(9>:>~N^>7 > 8 >7 > 8-?!#36767>32##"47632#"/&%47632#"/&#-$#"#:*532*(9>9>(9>:>8"!n-+)788l>7 > 8 >7 > 8U 3!3#!#!!j]~N^ -3!!327654'&'&#"47632#"'&'&c LW(OW(uoDSM oDTM ۍSN"& TN!+N/n.1N/n,3# 1%3"'&53327654'&'&#"47632#"'&'&8vCBLW(NV)tnDTM nDTM i:9u3SN ( TN#)M/n,3M/n,3  1!!3!!327654'&'&#"47632#"'&'&f\c LW(OW(uoDSM oDTM }ۍSN"& TN!+N/n.1N/n,3# !5!!3"'&53327654'&'&#"47632#"'&'&B]zvCBLW(NV)tnDTM nDTM i:9u3SN ( TN#)M/n,3M/n,3[0D3 4'&+ ##!2 327650'&'&#"47632#"'&'&!bcSמmvegHJ(*a`QLV)NV)tnDTM nDTM BCw35KOaml!vSN"&!TN#)M/n,3M/n,3M-A&#"#3676767632327654'&'&#"47632#"'&'&DG/++!"!%!tYlLW(OV)uoDSM oDTM **(<:H|2&#7SN"& TN!+N/n,3N/n,3[ 4H!!3 4'&+ ##!2 327650'&'&#"47632#"'&'&])bcSמmvegHJ(*a`QLV)NV)tnDTM nDTM BCw35KOaml!vSN"&!TN#)M/n,3M/n,371E!!&#"#3676767632327654'&'&#"47632#"'&'&R]LDG/++!"!%!tYlLW(OV)uoDSM oDTM 7**(<:H|2&#7SN"& TN!+N/n,3N/n,3TT1 732=3#"'&'&wk   f#("("*$#f  {1ϋ?42 $  e #!#3#3)#'#7'373 ! %! !D`\G~}D^]D}*S\888խ jJwE6 !!EED62^X +G!#3##3267>54'&'&'&'&#"47>767632#"'&'&'&LQ ''86;:**\[{8!#!#FP@b)7R"327654'&$'&'53254'&5476322654'&#"&%&#" '&547676^BC][CBAAֿGHzeehHy{^AA^^BC,_0yfffffHz}^^AAAA^]CB+zSjgffM%&^]CB^^AAr-zSlggggfL&'X67654'&'&#"32463227#"&5454&#"#"'&'&54767632254'&FL H'%#$L H(%$-޲llFb@|nbIJ%2t86>9q.1u68KG.rH'$#$KH$(%!KmnzVFvxnؿLM};HE@bj VAr,0v57=;p,( Hl5T7!!&'&'&547676767632!!5676767654'&'&'&'&'&#"3!7#H3-+C?hgyzD2<< ;,IK99!! .%(,HEV^IJ.1!!89E`)~YIn2LMgdRM32\P;qp&I)dL(@AAB2;1 bM28"!()>'mJM'9hM629: ">j=;53'5#"'&'5#"#'&+"#4'36763267632J>XX67.9@C< (WXr$YZB>::)_`J<((lzrr__rjn~~842mn NZ[[`_}tddQPx!5!##'!5!f dVVh1923632#"'#536&#"04'&'5267>327&'"h('jvJJFGv,==vf08$MGDCOP%+-(xNZ~ [_]^cRSihtnؿ`mnYX@h6$(S32263227632&#"#"'&#"#"'&"#'322632327632&#"#"'&#"#"'&#"#'hBr, n76rU**zl^?^3:S98;7SU78lV4@t*n7697U+)|l^?]1=U79:6TU7878S4 (FFFF$24LJNDFHFGb &FFFF"25LLMCFFGF`!5!37!!'/"Ҥ"- ~S'*PE3צ4Btb6 2bfh8HyOFP&#"3#6767654'&&'&'&'&'&5476767>;767676732#"' #"W&.x~:$8+($   " f?3-/462 DHA)7QPGTQP(.'Av ,~uHbA>B7Wp&  $*!"(%%#0;&(6-;OqrqP)P6F,^X&Hd7!!3254'&'&'&'&+';2+#3267>54'&'&'&'&#"47>767632#"'&'&'&_N  !NWWNV68  ()4NW ''86;:**\[{8=>3=> `=>3=> ` 0#''73\ xb$RT4632#"'&'&RL51!# L5.#$ E7J* 5L+  $'6630 \3x$b>#!5p=>3=> `>!5!3D=>p !54'&/76303kF'%22+ -95 #>IMT<2p2 p2>2p2!p >c(B77#"'&'&54767262;254/'7032767654'&'&#"1_[; qrjZrmA"Ds/[K "BGNnKH  rQLg%W Pm}i`5-,:嗗\O_gw63Wmm #}34#" jY-u78ׇ. (<`#s'&54767676323#;#"'&5#5354'&'"&#" #"'&'7327654'&'&'&'&'&'&'&'&547632/5@K !uFF;<``"3 *:6Qt$ !  112-+$lk\_%45[e::"'/&?*2/""dg^# **.*4 jY-u78ׇ*4"zNH&  !'/6AZYCEnC$$00U)"  $#.1;KM%#5553% @N++㯭 y  !5!5N2@jP+  <!#' i3h #55#nEy #55%5%50P=J}JJJBZ3 3#BddBX<"^ !!!5!!5^OPlB 73!#5!57!!5!!B z{{(pg<(   $   6 327$~~<..9cc..c҅(~~$c-k-.ӅPccd !!!!5!!Plzݍ:[.6 !''%8p2pp1 p4!O!!OJ,0'654/ 7FԮ . FDŽ5{{J9wOiElJA"p'}8@0Y[) )3!!!!!!#!5!5!5!5!5!ɘ``````˜b".   $  zRh"" zh"&-<'!2'67654!"ĞǮnmJۗkh5PSRIE898:#S %%RV Qhէ2/{d!&'&543267654&%ňB䡢ΐ]_:"˽(^_a|~;;4 #  WT 333# #T+P3J 3 3 # #Jjc;˾^)'J733Px"!#!x8Wr 7%5%/ S$!6ї5zuY '7s`Ũbki`ŨbkX!3!3BPPx !3!3!3۝CBPPP_"647632#"'&'&_ -&<@+'- 2# +@$ _"647632#"'&'&_ -&<@+'- 2# +@$ _"647632#"'&'&_ -&<@+'- 2# +@$ _"647632#"'&'&_ -&<@+'- 2# +@$ iq$&$7$9+$Y\$Z$$$$(5)*7.22$273$w7$7Xy9$ 9(9H:$:H<$B<D??qDYHWIDIQIRIWIXI\JMuMMPR[TMUH\Mu2RY29RY29RYl lm37+%  1x   @O  # Ah  5T! U km#|  4      J3      b & & "Created by Thatcher Ulrich (http://tulrich.com), Karoly Barta (bartakarcsi@gmail.com) and Michael Everson with FontForge (http://fontforge.sf.net) This font, including hint instructions, has been donated to the Public Domain. Do whatever you want with it. Created by Thatcher Ulrich (http://tulrich.com), Karoly Barta (bartakarcsi@gmail.com) and Michael Everson with FontForge (http://fontforge.sf.net) This font, including hint instructions, has been donated to the Public Domain. Do whatever you want with it. TuffyTuffyRegularRegularFontForge : Tuffy Regular : 14-6-2012FontForge : Tuffy Regular : 14-6-2012Tuffy RegularTuffy RegularVersion 001.280 Version 001.280 TuffyTuffyThatcher Ulrich, Karoly Barta and Michael EversonThatcher Ulrich, Karoly Barta and Michael Eversonhttp://tulrich.com http://tulrich.com http://tulrich.com http://tulrich.com Public Domain Public Domain All Typographic FeaturesFonctions typographiquesAlle typografischen MglichkeitenFunzioni TipograficheAlle typografische kenmerkenLigaturesLigaturesLigaturenLegatureLigaturenFractionsFractionsBreukenAll Type FeaturesToutes fonctions typographiquesAlle AuszeichnungsartenTutte le FunzioniAlle typekenmerkenCommon LigaturesLigatures UsuellesNormale LigaturenLegature pi ComuniGemeenschappelijke LigaturenNo FractionsPas de FractionsKein BrucheNessuna FrazioneGeen breukenDiagonal FractionsFractions en DiagonaleDiagonaler BruchFrazioni DiagonaliDiagonale breuken2  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~uni007F softhyphenuni00B5AmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflex Cdotaccent cdotaccentDcarondcaronDcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflex Gdotaccent gdotaccent Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonekIJij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflex Tcommaaccent tcommaaccentTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongsuni01E2uni01E3 Scommaaccent scommaaccentuni021Auni021Buni021Cuni021Duni0250uni0251uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0259uni025Auni025Buni025Cuni025Duni025Euni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni0268uni0269uni026Auni026Buni026Cuni026Duni026Euni026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276uni0277uni0278uni0279uni027Auni027Buni027Cuni027Duni027Euni027Funi0280uni0281uni0282uni0283uni0284uni0285uni0286uni0287uni0288uni0289uni028Auni028Buni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni0293uni0294uni0295uni0296uni0297uni0298uni0299uni029Auni029Buni029Cuni029Duni029Euni029Funi02A0uni02A1uni02A2uni02A3uni02A4uni02A5uni02A6uni02A7uni02A8uni02A9uni02AAuni02ABuni02ACuni02ADuni02AEuni02AF macronsub gravecomb acutecombuni0302 tildecombuni0304uni0306uni0307uni0308uni030Auni030Buni030Cuni0310 dotbelowcombuni0324uni0325uni0327uni0328 brevesubnospuni0331uni0370uni0371uni0376uni037Auni037Buni037Cuni037Duni037Etonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammaEpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsi IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdanuxiomicronrhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonosuni03CFuni03D0theta1Upsilon1Upsilonhooktonosuni03D4phi1omega1uni03D7uni03D8uni03D9uni03DAuni03DBuni03DCuni03DDuni03DEuni03DFuni03E0uni03E1uni03E2uni03E3uni03E4uni03E5uni03E6uni03E7uni03E8uni03E9uni03EAuni03EBuni03ECuni03EDuni03EEuni03EF kappascriptuni03F1uni03F2uni03F3uni03F4uni03F5uni03F6uni03F7uni03F8uni03F9uni03FAuni03FBuni03FCuni03FDuni03FEuni03FFuni0400 afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061uni040D afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097uni0450 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109uni045D afii10110 afii10193uni048Auni048Buni048Cuni048Duni048Euni048FGheupturncyrillicgheupturncyrillicGhestrokecyrillicghestrokecyrillicGhemiddlehookcyrillicghemiddlehookcyrillicZhedescendercyrilliczhedescendercyrillicZedescendercyrilliczedescendercyrillicKadescendercyrillickadescendercyrillicKaverticalstrokecyrillickaverticalstrokecyrillicKastrokecyrillickastrokecyrillicKabashkircyrillickabashkircyrillicEndescendercyrillicendescendercyrillic Enghecyrillic enghecyrillicPemiddlehookcyrillicpemiddlehookcyrillicHaabkhasiancyrillichaabkhasiancyrillicEsdescendercyrillicesdescendercyrillicTedescendercyrillictedescendercyrillicUstraightcyrillicustraightcyrillicUstraightstrokecyrillicustraightstrokecyrillicHadescendercyrillichadescendercyrillic Tetsecyrillic tetsecyrillicChedescendercyrillicchedescendercyrillicCheverticalstrokecyrilliccheverticalstrokecyrillic Shhacyrillic shhacyrillicCheabkhasiancyrilliccheabkhasiancyrillicChedescenderabkhasiancyrillicchedescenderabkhasiancyrillicpalochkacyrillicZhebrevecyrilliczhebrevecyrillicKahookcyrillickahookcyrillicuni04C5uni04C6Enhookcyrillicenhookcyrillicuni04C9uni04CAChekhakassiancyrillicchekhakassiancyrillicuni04CDuni04CEuni04CFAbrevecyrillicabrevecyrillicAdieresiscyrillicadieresiscyrillic Aiecyrillic aiecyrillicIebrevecyrilliciebrevecyrillic Schwacyrillic schwacyrillicSchwadieresiscyrillicschwadieresiscyrillicZhedieresiscyrilliczhedieresiscyrillicZedieresiscyrilliczedieresiscyrillicDzeabkhasiancyrillicdzeabkhasiancyrillicImacroncyrillicimacroncyrillicIdieresiscyrillicidieresiscyrillicOdieresiscyrillicodieresiscyrillicObarredcyrillicobarredcyrillicObarreddieresiscyrillicobarreddieresiscyrillicuni04ECuni04EDUmacroncyrillicumacroncyrillicUdieresiscyrillicudieresiscyrillicUhungarumlautcyrillicuhungarumlautcyrillicChedieresiscyrillicchedieresiscyrillicuni04F6uni04F7Yerudieresiscyrillicyerudieresiscyrillic Bdotaccent bdotaccent Ddotaccent ddotaccentuni1E0Cuni1E0Duni1E0Euni1E0F Fdotaccent fdotaccentuni1E24uni1E25uni1E2Auni1E2Buni1E34uni1E35uni1E36uni1E37uni1E38uni1E39uni1E3Auni1E3B Mdotaccent mdotaccentuni1E42uni1E43uni1E44uni1E45uni1E46uni1E47uni1E48uni1E49 Pdotaccent pdotaccentuni1E5Auni1E5Buni1E5Cuni1E5Duni1E5Euni1E5F Sdotaccent sdotaccentuni1E62uni1E63 Tdotaccent tdotaccentuni1E6Cuni1E6Duni1E6Euni1E6FWgravewgraveWacutewacute Wdieresis wdieresisuni1E8Euni1E8Funi1E96uni1E9EYgraveygraveuni1EFAuni1EFB alphalenis alphaasperalphalenisgravealphaaspergravealphalenisacutealphaasperacutealphalenistildealphaaspertilde Alphalenis AlphaasperAlphalenisgraveAlphaaspergraveAlphalenisacuteAlphaasperacuteAlphalenistildeAlphaaspertilde epsilonlenis epsilonasperepsilonlenisgraveepsilonaspergraveepsilonlenisacuteepsilonasperacute Epsilonlenis EpsilonasperEpsilonlenisgraveEpsilonaspergraveEpsilonlenisacuteEpsilonasperacuteetalenisetaasper etalenisgrave etaaspergrave etalenisacute etaasperacute etalenistilde etaaspertildeEtalenisEtaasper Etalenisgrave Etaaspergrave Etalenisacute Etaasperacute Etalenistilde Etaaspertilde iotalenis iotaasperiotalenisgraveiotaaspergraveiotalenisacuteiotaasperacuteiotalenistildeiotaaspertilde Iotalenis IotaasperIotalenisgraveIotaaspergraveIotalenisacuteIotaasperacuteIotalenistildeIotaaspertilde omicronlenis omicronasperomicronlenisgraveomicronaspergraveomicronlenisacuteomicronasperacute Omicronlenis OmicronasperOmicronlenisgraveOmicronaspergraveOmicronlenisacuteOmicronasperacute upsilonlenis upsilonasperupsilonlenisgraveupsilonaspergraveupsilonlenisacuteupsilonasperacuteupsilonlenistildeupsilonaspertilde UpsilonasperUpsilonaspergraveUpsilonasperacuteUpsilonaspertilde omegalenis omegaasperomegalenisgraveomegaaspergraveomegalenisacuteomegaasperacuteomegalenistildeomegaaspertilde Omegalenis OmegaasperOmegalenisgraveOmegaaspergraveOmegalenisacuteOmegaasperacuteOmegalenistildeOmegaaspertilde alphagrave alphaacute epsilongrave epsilonacuteetagraveetaacute iotagrave iotaacute omicrongrave omicronacute upsilongrave upsilonacute omegagrave omegaacutealphaiotasublenisalphaiotasubasperalphaiotasublenisgravealphaiotasubaspergravealphaiotasublenisacutealphaiotasubasperacutealphaiotasublenistildealphaiotasubaspertildeAlphaiotasublenisAlphaiotasubasperAlphaiotasublenisgraveAlphaiotasubaspergraveAlphaiotasublenisacuteAlphaiotasubasperacuteAlphaiotasublenistildeAlphaiotasubaspertildeetaiotasublenisetaiotasubasperetaiotasublenisgraveetaiotasubaspergraveetaiotasublenisacuteetaiotasubasperacuteetaiotasublenistildeetaiotasubaspertildeEtaiotasublenisEtaiotasubasperEtaiotasublenisgraveEtaiotasubaspergraveEtaiotasublenisacuteEtaiotasubasperacuteEtaiotasublenistildeEtaiotasubaspertildeomegaiotasublenisomegaiotasubasperomegaiotasublenisgraveomegaiotasubaspergraveomegaiotasublenisacuteomegaiotasubasperacuteomegaiotasublenistildeomegaiotasubaspertildeOmegaiotasublenisOmegaiotasubasperOmegaiotasublenisgraveOmegaiotasubaspergraveOmegaiotasublenisacuteOmegaiotasubasperacuteOmegaiotasublenistildeOmegaiotasubaspertilde alphabreve alphamacronalphaiotasubgrave alphaiotasubalphaiotasubacute alphatildealphaiotasubtilde Alphabreve Alphamacron Alphagrave Alphaacute Alphaiotasublenis iotasubscriptpsili perispomenidialytika_perispomenietaiotasubgrave etaiotasubetaiotasubacuteetatildeetaiotasubtilde Epsilongrave EpsilonacuteEtagraveEtaacute Etaiotasub psili_varia psili_oxiapsili_perispomeni iotabreve iotamacroniotadieresisgraveiotadieresisacute iotatildeiotadieresistilde Iotabreve Iotamacron Iotagrave Iotaacute dasia_varia dasia_oxiadasia_perispomeni upsilonbreve upsilonmacronupsilondieresisgraveupsilondieresisacuterholenisrhoasper upsilontildeupsilondieresistilde Upsilonbreve Upsilonmacron Upsilongrave UpsilonacuteRhoasperdialytika_variadialytika_oxiavariaomegaiotasubgrave omegaiotasubomegaiotasubacute omegatildeomegaiotasubtilde Omicrongrave Omicronacute Omegagrave Omegaacute Omegaiotasuboxiaasperemspacethreeperemspacefourperemspace thinspace hairspace hyphentwo hyphennobreak figuredash horizontalbaruni2016 quotereverseduni201Funi2023onedotenleadertwodotenleaderuni2027uni2031minutesecond exclamdbluni203Duni203Funi2042uni2043uni2047uni2048uni2049uni204Buni204Cuni204Duni204Euni204Funi2052uni2053uni2056uni2058uni2059uni205Auni205Buni205Duni205Euni2070uni2071uni2072uni2073 foursuperioruni2075uni2076uni2077uni2078uni2079uni207Auni207Buni207Cuni207Duni207Euni207Funi2080uni2081uni2082uni2083uni2084uni2085uni2086uni2087uni2088uni2089uni208Auni208Buni208Cuni208Duni208Euni2090uni2091uni2092uni2093uni2094uni2098uni2099uni20A0 colonmonetaryuni20A2lirauni20A5uni20A6pesetauni20A8uni20A9 afii57636dongEurouni20ADuni20AEuni20AFuni20B0uni20B1uni20B2uni20B3uni20B4uni20B5uni20B6uni20B7uni20B8uni20B9 centigradeIfraktur afii61352 weierstrassRfrakturuni2126 estimatedalephonethird twothirdsuni2155uni2156uni2157uni2158uni2159uni215A oneeighth threeeighths fiveeighths seveneighthsuni215Funi2160uni2161uni2162uni2163uni2164uni2165uni2166uni2167uni2168uni2169uni216Auni216Buni216Cuni216Duni216Euni216Funi2170uni2171uni2172uni2173uni2174uni2175uni2176uni2177uni2178uni2179uni217Auni217Buni217Cuni217Duni217Euni217Funi2180uni2181uni2182uni2183uni2184uni2185uni2186uni2187uni2188uni2189 arrowleftarrowup arrowright arrowdown arrowboth arrowupdnuni2196uni2197uni2198uni2199uni219Auni219Buni219Cuni219Duni219Euni219Funi21A0uni21A1uni21A2uni21A3uni21A4uni21A5uni21A6uni21A7 arrowupdnbseuni21B0uni21B1uni21B2uni21B3uni21B4carriagereturnuni21B6uni21B7uni21B8uni21B9uni21BAuni21BBuni21BCuni21BDuni21BEuni21BFuni21C0uni21C1uni21C2uni21C3uni21C4uni21C5uni21C6uni21C7uni21C8uni21C9uni21CAuni21CBuni21CC arrowdblleft arrowdblup arrowdblright arrowdbldown arrowdblboth universal existentialemptysetuni2206gradientelement notelementuni220Duni2210 asteriskmathuni221Buni221C proportionalangle logicaland logicalor intersectionunion thereforesimilar congruent equivalence propersubsetpropersuperset notsubset reflexsubsetreflexsuperset circlepluscirclemultiply perpendicularuni22C4dotmath integraltp integralbt angleleft anglerightuniA746uniA747forintbrevealtg_yt_yc_t f_icircumflex f_idieresisf_igravef_iacutef_f_icircumflex f_f_idieresis f_f_igrave f_f_iacuteuniE118uniE119uniE11AuniE11BuniE11CuniE11DuniE11EuniE11FuniE120uniE121aalt agravealt aacutealt abrevealt atildealtacircumflexalt adieresisalt aogonekaltaringalt amacronaltxaltuniEFA0uniEFA1uniEFA2uniEFA3uniEFA4uniEFA5uniEFA6uniEFA7uniEFA8uniEFA9uniEFAAuniEFABuniEFACuniEFADuniEFB0uniEFB1uniEFB2uniEFB3uniEFB4uniEFB5uniEFB6uniEFB7uniEFB8 j.dotlessuniF8E5uniF8E6uniF8E7uniF8E8uniF8E9uniF8EAuniF8EBuniF8ECuniF8EDuniF8EEuniF8EFuniF8F0uniF8F1uniF8F2uniF8F3uniF8F4uniF8F5uniF8F6uniF8F7uniF8F8bracketrighttpbracketrightexbracketrightbt bracerighttpuniF8FDuniF8FEuniF8FFlongs_ts_tu10900u10901u10902u10903u10904u10905u10906u10907u10908u10909u1090Au1090Bu1090Cu1090Du1090Eu1090Fu10910u10911u10912u10913u10914u10915u10916u10917u10918u10919u1091Au1091Bu1091Fu1091Eu1091Du1091CU~       !! #" >> ?? @@ CA ^^ __ `` ca gdkh qm srutvv zx {{}    ƀ   >>     $" 42 @? EA \F `]aa bb gc hhyi zz}| ~          @ AAaB bb cc dd   04 8 F~ JJ$WW&\\(??ij( D hh&??????~d DF II   ?R?S?T?U?Z??\?ÿ?^?ƿ?`?ɿnolmrspqɉo1pPySDL2-0.9.3/examples/__init__.py0000644000000000000000000000011312260256443013354 0ustar """Examples for PySDL2. This package contains the examples for sdl2. """ PySDL2-0.9.3/examples/colorpalettes.py0000644000000000000000000001673212312306263014505 0ustar """A simple example for filling rectangular areas.""" import sys import sdl2 import sdl2.ext import sdl2.ext.colorpalettes # This function will draw the passed palette colors onto the window surface. # The function does not require the window surface itself, any surface is fine, # since the window surface acquired in run() does not differ from any other # surface (not entirely true, but it offers and supports the same # functionality). def draw_palette(surface, palette): # Fill the entire surface with a black color. This is done by simply # passing a 0 value to the fill argument. We could also create a # Color(0, 0, 0) instance here, but this would be the same. sdl2.ext.fill(surface, 0) # Calculate the average width (roughly cut) to be used for each palette # value. When running the example, you will notice a black gap on the # right for some palettes. This s caused by the implicit cut behaviour # of the // operator. Since we can only operate pixel-wise, there are # no fractions to be used. width, height = surface.w, surface.h rw = width // len(palette) # Create the area to be filled with the palette values. we always start # at the top-left corner, use the calculated width and the entire height # of the window surface. As you will see below, we then only advance # horizontically by the calculated width to draw stripes. # Play around with different height values and start offsets to see what # happens rect = [0, 0, rw, height] # Loop over all colors and fill a portion of the surface with them. As # above, we use fill() to fill the surface with the palette color, but now # we provide an area (the third argument) to avoid filling the whole # surface. Instead, the provided area makes sure, that we only fill a # certain part. for color in palette: sdl2.ext.fill(surface, color, rect) rect[0] += rw def run(): # You know those from the helloworld.py example. # Initialize the video subsystem, create a window and make it visible. sdl2.ext.init() window = sdl2.ext.Window("Color Palettes", size=(800, 600)) window.show() # Explicitly acquire the window's surface to draw on. We used the # SpriteRenderSystem class in helloworld.py, which did the drawing magic # for us. Now we will do it ourselves, so we have to get a surface to draw # on. # # NOTE: if you intend to use textures or the SDL renderers, you must not # use the method. windowsurface = window.get_surface() # A simple mapping table for the builtin color palettes. We will use # the table to look up the color palette to draw an the title to set below. palettes = ( ("Mono Palette", sdl2.ext.colorpalettes.MONOPALETTE), ("2-bit Gray Palette", sdl2.ext.colorpalettes.GRAY2PALETTE), ("4-bit Gray Palette", sdl2.ext.colorpalettes.GRAY4PALETTE), ("8-bit Gray Palette", sdl2.ext.colorpalettes.GRAY8PALETTE), ("3-bit RGB Palette", sdl2.ext.colorpalettes.RGB3PALETTE), ("CGA Palette", sdl2.ext.colorpalettes.CGAPALETTE), ("EGA Palette", sdl2.ext.colorpalettes.EGAPALETTE), ("VGA Palette", sdl2.ext.colorpalettes.VGAPALETTE), ("Web Palette", sdl2.ext.colorpalettes.WEBPALETTE), ) # A storage variable for the palette we are currently on, so that we know # which palette to draw next. curindex = 0 # Since it is not that nice to have a black window right at the start of # the application, we will set the window's title to the first entry # of our mapping tables. Afterwards, we will draw the matching palette # to the window surface. window.title = palettes[0][0] draw_palette(windowsurface, palettes[0][1]) # The event loop. In helloworld.py we used the TestEventProcessor class, # since there was not much to do. Now however, we want to react on the # user input. Every time the user clicks around in our window, we want to # show the next palette. Once we reached the last palette within the # mapping table, we will start again with the first one. running = True while running: # This will check for any events that piled up since the last check. # If one or multiple events were found (such as a click, a mouse # movement, keyboard input, etc.), we will retrieve them. events = sdl2.ext.get_events() # In case there was no event, we do not need to do anything. This # might happen, if e.g. the user works with another application. Since # get_events() does not wait for an event to occur (that'd mean your # application blocks until there is an event), we have to handle # this. for event in events: # The received events can contain different information. There # might be mouse movements, clicks, keyboard hits and many more. # All of those carry different information. A mouse movement will # contain the mouse cursor position, while a keyoard hit will # contain the key that was pressed. Depending on that, we need to # handle the occured event in a different way, which is done here. # # In case of a special QUIT event, the user wants to quit the # application, just as you are used to closing an editor. # If the user wants to quit the application, we should let him do # so. This is done by breaking out of the while loop. if event.type == sdl2.SDL_QUIT: running = False break # We received a mouse button press event. As you can see from the # type, the user pressed the mouse button, but did not necesarily # release it. As such, it is not a typical click, but only 50% of # it, which is sufficient for our case here. if event.type == sdl2.SDL_MOUSEBUTTONDOWN: # If the user pressed the button, we want to draw the next # palette and update the window title accordingly. We do this # by increasing the storage variable and - in case it reached # the last entry, set it back to the first entry. curindex += 1 if curindex >= len(palettes): curindex = 0 window.title = palettes[curindex][0] draw_palette(windowsurface, palettes[curindex][1]) # If we found a single click (there might be many more) # we will break out of checking the rest of events. # Improved implementations could use the type= argument # for get_events() to filter specific events and # ignore anything else. break # Once the events were properly handled, we will refresh the window, # since it might have happened that the user moved the window around, # pressed a button or did something else. In all those cases, we want # the palettes to be shown, so we need to refresh the window. This will # cause the window internally to copy its surface information (those # we used to draw the palette on) to the screen, where the window # currently is placed on. # Comment this line out to see what happens! window.refresh() # As for helloworld.py, we have to call sdl2.ext.quit(), since we also # called sdl2.ext.init(). sdl2.ext.quit() return 0 if __name__ == "__main__": sys.exit(run()) PySDL2-0.9.3/examples/draw.py0000644000000000000000000000762712312250730012562 0ustar """2D drawing examples.""" import sys from random import randint import sdl2 import sdl2.ext # Draws random lines on the passed surface def draw_lines(surface, width, height): # Fill the whole surface with a black color. sdl2.ext.fill(surface, 0) for x in range(15): # Create a set of four random points for drawing the line. x1, x2 = randint(0, width), randint(0, width) y1, y2 = randint(0, height), randint(0, height) # Create a random color. color = sdl2.ext.Color(randint(0, 255), randint(0, 255), randint(0, 255)) # Draw the line with the specified color on the surface. # We also could create a set of points to be passed to the function # in the form # # line(surface, color, (x1, y1, x2, y2, x3, y3, x4, y4, ...)) # ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ # first line second line sdl2.ext.line(surface, color, (x1, y1, x2, y2)) # Draws random, filled rectangles on the passed surface def draw_rects(surface, width, height): # Fill the whole surface with a black color. sdl2.ext.fill(surface, 0) for k in range(15): # Create a set of four random points for the edges of the rectangle. x, y = randint(0, width), randint(0, height) w, h = randint(1, width // 2), randint(1, height // 2) # Create a random color. color = sdl2.ext.Color(randint(0, 255), randint(0, 255), randint(0, 255)) # Draw the filled rect with the specified color on the surface. # We also could create a set of points to be passed to the function # in the form # # fill(surface, color, ((x1, y1, x2, y2), (x3, y3, x4, y4), ...)) # ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ # first rect second rect sdl2.ext.fill(surface, color, (x, y, w, h)) def run(): # You know those from the helloworld.py example. # Initialize the video subsystem, create a window and make it visible. sdl2.ext.init() window = sdl2.ext.Window("2D drawing primitives", size=(800, 600)) window.show() # As in colorpalettes.py, explicitly acquire the window's surface to # draw on. windowsurface = window.get_surface() # We implement the functionality as it was done in colorpalettes.py and # utilise a mapping table to look up the function to be executed, together # with the arguments they should receive functions = ((draw_lines, (windowsurface, 800, 600)), (draw_rects, (windowsurface, 800, 600)) ) # A storage variable for the function we are currently on, so that we know # which function to execute next. curindex = 0 draw_lines(windowsurface, 800, 600) # The event loop is nearly the same as we used in colorpalettes.py. If you # do not know, what happens here, take a look at colorpalettes.py for a # detailled description. running = True while running: events = sdl2.ext.get_events() for event in events: if event.type == sdl2.SDL_QUIT: running = False break if event.type == sdl2.SDL_MOUSEBUTTONDOWN: curindex += 1 if curindex >= len(functions): curindex = 0 # In contrast to colorpalettes.py, our mapping table consists # of functions and their arguments. Thus, we get the currently # requested function and argument tuple and execute the # function with the arguments. func, args = functions[curindex] func(*args) break window.refresh() sdl2.ext.quit() return 0 if __name__ == "__main__": sys.exit(run()) PySDL2-0.9.3/examples/gfxdrawing.py0000644000000000000000000003557412312360014013764 0ustar """2D drawing examples utilising the SDL2_gfx functions.""" import sys import ctypes from random import randint import sdl2 import sdl2.sdlgfx import sdl2.ext # Draws random lines using the passed rendering context def draw_lines(context, width, height): # Reset the visible area with a black color. context.clear(0) # Split the visible area whalf = width // 2 - 2 hhalf = height // 2 - 2 lw = 5 x0, x1 = whalf, whalf y0, y1 = 0, height sdl2.sdlgfx.thickLineColor(context.renderer, x0, y0, x1, y1, lw, 0xFFFFFFFF) x0, x1 = 0, width y0, y1 = hhalf, hhalf sdl2.sdlgfx.thickLineColor(context.renderer, x0, y0, x1, y1, lw, 0xFFFFFFFF) for x in range(15): # In the first quadrant, draw normal lines color = randint(0, 0xFFFFFFFF) x0, x1 = randint(0, whalf), randint(0, whalf) y0, y1 = randint(0, hhalf), randint(0, hhalf) sdl2.sdlgfx.lineColor(context.renderer, x0, y0, x1, y1, color) # In the second quadrant, draw aa lines color = randint(0, 0xFFFFFFFF) x0, x1 = randint(whalf + lw, width), randint(whalf + lw, width) y0, y1 = randint(0, hhalf), randint(0, hhalf) sdl2.sdlgfx.aalineColor(context.renderer, x0, y0, x1, y1, color) # In the third quadrant, draw horizontal lines color = randint(0, 0xFFFFFFFF) x0, x1 = randint(0, whalf), randint(0, whalf) y0 = randint(hhalf + lw, height) sdl2.sdlgfx.hlineColor(context.renderer, x0, x1, y0, color) # In the fourth quadrant, draw vertical lines color = randint(0, 0xFFFFFFFF) x0 = randint(whalf + lw, width) y0, y1 = randint(hhalf + lw, height), randint(hhalf + lw, height) sdl2.sdlgfx.vlineColor(context.renderer, x0, y0, y1, color) # Draws random circles using the passed rendering context def draw_circles(context, width, height): # Reset the visible area with a black color. context.clear(0) # Split the visible area wthird = width // 3 - 1 lw = 3 sdl2.sdlgfx.thickLineColor(context.renderer, wthird, 0, wthird, height, lw, 0xFFFFFFFF) sdl2.sdlgfx.thickLineColor(context.renderer, (2 * wthird + lw), 0, (2 * wthird + lw), height, lw, 0xFFFFFFFF) for x in range(15): # In the first part, draw circles color = randint(0, 0xFFFFFFFF) x, y = randint(0, wthird), randint(0, height) r = randint(1, max(min(x, wthird - x), 2)) sdl2.sdlgfx.circleColor(context.renderer, x, y, r, color) # In the second part, draw aa circles color = randint(0, 0xFFFFFFFF) x, y = randint(0, wthird), randint(0, height) r = randint(1, max(min(x, wthird - x), 2)) sdl2.sdlgfx.aacircleColor(context.renderer, x + wthird + lw, y, r, color) # In the third part, draw filled circles color = randint(0, 0xFFFFFFFF) x, y = randint(0, wthird), randint(0, height) r = randint(1, max(min(x, wthird - x), 2)) sdl2.sdlgfx.filledCircleColor(context.renderer, x + 2 * (wthird + lw), y, r, color) # Draws random ellipsis using the passed rendering context def draw_ellipsis(context, width, height): # Reset the visible area with a black color. context.clear(0) # Split the visible area wthird = width // 3 - 1 eheight = height // 4 lw = 3 sdl2.sdlgfx.thickLineColor(context.renderer, wthird, 0, wthird, height, lw, 0xFFFFFFFF) sdl2.sdlgfx.thickLineColor(context.renderer, (2 * wthird + lw), 0, (2 * wthird + lw), height, lw, 0xFFFFFFFF) for x in range(15): # In the first part, draw ellipsis color = randint(0, 0xFFFFFFFF) x, y = randint(0, wthird), randint(0, height) rx, ry = randint(1, max(min(x, wthird - x), 2)), randint(0, eheight) sdl2.sdlgfx.ellipseColor(context.renderer, x, y, rx, ry, color) # In the second part, draw aa ellipsis color = randint(0, 0xFFFFFFFF) x, y = randint(0, wthird), randint(0, height) rx, ry = randint(1, max(min(x, wthird - x), 2)), randint(0, eheight) sdl2.sdlgfx.aaellipseColor(context.renderer, x + wthird + lw, y, rx, ry, color) # In the third part, draw filled ellipsis color = randint(0, 0xFFFFFFFF) x, y = randint(0, wthird), randint(0, height) rx, ry = randint(1, max(min(x, wthird - x), 2)), randint(0, eheight) sdl2.sdlgfx.filledEllipseColor(context.renderer, x + 2 * (wthird + lw), y, rx, ry, color) # Draws random rectangles using the passed rendering context def draw_rects(context, width, height): # Reset the visible area with a black color. context.clear(0) # Split the visible area whalf = width // 2 - 2 hhalf = height // 2 - 2 lw = 5 x0, x1 = whalf, whalf y0, y1 = 0, height sdl2.sdlgfx.thickLineColor(context.renderer, x0, y0, x1, y1, lw, 0xFFFFFFFF) x0, x1 = 0, width y0, y1 = hhalf, hhalf sdl2.sdlgfx.thickLineColor(context.renderer, x0, y0, x1, y1, lw, 0xFFFFFFFF) for x in range(15): # In the first quadrant, draw normal rectangles color = randint(0, 0xFFFFFFFF) x0, x1 = randint(0, whalf), randint(0, whalf) y0, y1 = randint(0, hhalf), randint(0, hhalf) sdl2.sdlgfx.rectangleColor(context.renderer, x0, y0, x1, y1, color) # In the second quadrant, draw rounded rectangles color = randint(0, 0xFFFFFFFF) x0, x1 = randint(whalf + lw, width), randint(whalf + lw, width) y0, y1 = randint(0, hhalf), randint(0, hhalf) r = randint(0, max(x1 - x0, x0 - x1)) sdl2.sdlgfx.roundedRectangleColor(context.renderer, x0, y0, x1, y1, r, color) # In the third quadrant, draw horizontal lines color = randint(0, 0xFFFFFFFF) x0, x1 = randint(0, whalf), randint(0, whalf) y0, y1 = randint(hhalf + lw, height), randint(hhalf + lw, height) sdl2.sdlgfx.boxColor(context.renderer, x0, y0, x1, y1, color) # In the fourth quadrant, draw vertical lines color = randint(0, 0xFFFFFFFF) x0, x1 = randint(whalf + lw, width), randint(whalf + lw, width) y0, y1 = randint(hhalf + lw, height), randint(hhalf + lw, height) r = randint(1, max(x1 - x0, x0 - x1)) sdl2.sdlgfx.roundedBoxColor(context.renderer, x0, y0, x1, y1, r, color) # Draws random triangles using the passed rendering context def draw_trigons(context, width, height): # Reset the visible area with a black color. context.clear(0) # Split the visible area wthird = width // 3 - 1 lw = 3 sdl2.sdlgfx.thickLineColor(context.renderer, wthird, 0, wthird, height, lw, 0xFFFFFFFF) sdl2.sdlgfx.thickLineColor(context.renderer, (2 * wthird + lw), 0, (2 * wthird + lw), height, lw, 0xFFFFFFFF) for x in range(15): # In the first part, draw triangles color = randint(0, 0xFFFFFFFF) x0, y0 = randint(0, wthird), randint(0, height) x1, y1 = randint(0, wthird), randint(0, height) x2, y2 = randint(0, wthird), randint(0, height) sdl2.sdlgfx.trigonColor(context.renderer, x0, y0, x1, y1, x2, y2, color) # In the second part, draw aa triangles color = randint(0, 0xFFFFFFFF) x0, y0 = randint(0, wthird) + wthird + lw, randint(0, height) x1, y1 = randint(0, wthird) + wthird + lw, randint(0, height) x2, y2 = randint(0, wthird) + wthird + lw, randint(0, height) sdl2.sdlgfx.aatrigonColor(context.renderer, x0, y0, x1, y1, x2, y2, color) # In the third part, draw filled triangles color = randint(0, 0xFFFFFFFF) x0, y0 = randint(0, wthird) + 2 * (wthird + lw), randint(0, height) x1, y1 = randint(0, wthird) + 2 * (wthird + lw), randint(0, height) x2, y2 = randint(0, wthird) + 2 * (wthird + lw), randint(0, height) sdl2.sdlgfx.filledTrigonColor(context.renderer, x0, y0, x1, y1, x2, y2, color) # Draws random polygons using the passed rendering context def draw_polygons(context, width, height): # Reset the visible area with a black color. context.clear(0) # Split the visible area wthird = width // 3 - 1 lw = 3 sdl2.sdlgfx.thickLineColor(context.renderer, wthird, 0, wthird, height, lw, 0xFFFFFFFF) sdl2.sdlgfx.thickLineColor(context.renderer, (2 * wthird + lw), 0, (2 * wthird + lw), height, lw, 0xFFFFFFFF) for x in range(5): # In the first part, draw polygons color = randint(0, 0xFFFFFFFF) ptcount = randint(3, 10) xlist, ylist = (sdl2.Sint16 * ptcount)(), (sdl2.Sint16 * ptcount)() for k in range(ptcount): xlist[k] = randint(0, wthird) ylist[k] = randint(0, height) xptr = ctypes.cast(xlist, ctypes.POINTER(sdl2.Sint16)) yptr = ctypes.cast(ylist, ctypes.POINTER(sdl2.Sint16)) sdl2.sdlgfx.polygonColor(context.renderer, xptr, yptr, ptcount, color) # In the second part, draw aa polygons color = randint(0, 0xFFFFFFFF) ptcount = randint(3, 10) xlist, ylist = (sdl2.Sint16 * ptcount)(), (sdl2.Sint16 * ptcount)() for k in range(ptcount): xlist[k] = randint(0, wthird) + wthird + lw ylist[k] = randint(0, height) xptr = ctypes.cast(xlist, ctypes.POINTER(sdl2.Sint16)) yptr = ctypes.cast(ylist, ctypes.POINTER(sdl2.Sint16)) sdl2.sdlgfx.aapolygonColor(context.renderer, xptr, yptr, ptcount, color) # In the third part, draw filled polygons color = randint(0, 0xFFFFFFFF) ptcount = randint(3, 10) xlist, ylist = (sdl2.Sint16 * ptcount)(), (sdl2.Sint16 * ptcount)() for k in range(ptcount): xlist[k] = randint(0, wthird) + 2 * (wthird + lw) ylist[k] = randint(0, height) xptr = ctypes.cast(xlist, ctypes.POINTER(sdl2.Sint16)) yptr = ctypes.cast(ylist, ctypes.POINTER(sdl2.Sint16)) sdl2.sdlgfx.filledPolygonColor(context.renderer, xptr, yptr, ptcount, color) # Draw random elements using the passed rendering context def draw_mixed(context, width, height): # Reset the visible area with a black color. context.clear(0) # Split the visible area whalf = width // 2 - 2 hhalf = height // 2 - 2 lw = 5 x0, x1 = whalf, whalf y0, y1 = 0, height sdl2.sdlgfx.thickLineColor(context.renderer, x0, y0, x1, y1, lw, 0xFFFFFFFF) x0, x1 = 0, width y0, y1 = hhalf, hhalf sdl2.sdlgfx.thickLineColor(context.renderer, x0, y0, x1, y1, lw, 0xFFFFFFFF) for x in range(15): # In the first quadrant, draw arcs color = randint(0, 0xFFFFFFFF) x0, y0 = randint(0, whalf), randint(0, hhalf) rad = randint(0, min(whalf - x0, hhalf - y0)) start, end = randint(0, 360), randint(0, 360) sdl2.sdlgfx.arcColor(context.renderer, x0, y0, rad, start, end, color) # In the second quadrant, draw bezier curves color = randint(0, 0xFFFFFFFF) ptcount = randint(3, 10) xlist, ylist = (sdl2.Sint16 * ptcount)(), (sdl2.Sint16 * ptcount)() for k in range(ptcount): xlist[k] = randint(whalf, width) ylist[k] = randint(0, hhalf) steps = randint(2, 10) xptr = ctypes.cast(xlist, ctypes.POINTER(sdl2.Sint16)) yptr = ctypes.cast(ylist, ctypes.POINTER(sdl2.Sint16)) sdl2.sdlgfx.bezierColor(context.renderer, xptr, yptr, ptcount, steps, color) # In the third quadrant, draw pies color = randint(0, 0xFFFFFFFF) x0, y0 = randint(0, whalf), randint(hhalf + lw, height) rad = randint(0, min(whalf - x0, y0 - (hhalf + lw))) start, end = randint(0, 360), randint(0, 360) sdl2.sdlgfx.pieColor(context.renderer, x0, y0, rad, start, end, color) # In the fourth quadrant, draw filled pies color = randint(0, 0xFFFFFFFF) x0, y0 = randint(whalf + lw, width), randint(hhalf + lw, height) rad = randint(0, min(x0 - (whalf + lw), y0 - (hhalf + lw))) start, end = randint(0, 360), randint(0, 360) sdl2.sdlgfx.filledPieColor(context.renderer, x0, y0, rad, start, end, color) def run(): # You know those from the helloworld.py example. # Initialize the video subsystem, create a window and make it visible. sdl2.ext.init() window = sdl2.ext.Window("sdlgfx drawing examples", size=(800, 600)) window.show() # Create a rendering context for the window. The sdlgfx module requires it. context = sdl2.ext.Renderer(window) # We implement the functionality as it was done in colorpalettes.py and # utilise a mapping table to look up the function to be executed, together # with the arguments they should receive functions = ((draw_lines, (context, 800, 600)), (draw_circles, (context, 800, 600)), (draw_ellipsis, (context, 800, 600)), (draw_rects, (context, 800, 600)), (draw_trigons, (context, 800, 600)), (draw_polygons, (context, 800, 600)), (draw_mixed, (context, 800, 600)) ) # A storage variable for the function we are currently on, so that we know # which function to execute next. curindex = 0 draw_lines(context, 800, 600) # The event loop is nearly the same as we used in colorpalettes.py. If you # do not know, what happens here, take a look at colorpalettes.py for a # detailed description. running = True while running: events = sdl2.ext.get_events() for event in events: if event.type == sdl2.SDL_QUIT: running = False break if event.type == sdl2.SDL_MOUSEBUTTONDOWN: curindex += 1 if curindex >= len(functions): curindex = 0 # In contrast to colorpalettes.py, our mapping table consists # of functions and their arguments. Thus, we get the currently # requested function and argument tuple and execute the # function with the arguments. func, args = functions[curindex] func(*args) break context.present() sdl2.ext.quit() return 0 if __name__ == "__main__": sys.exit(run()) PySDL2-0.9.3/examples/gui.py0000644000000000000000000001365212312306360012405 0ustar """User interface examples.""" import sys import sdl2 import sdl2.ext # Define some global color constants WHITE = sdl2.ext.Color(255, 255, 255) GREY = sdl2.ext.Color(200, 200, 200) RED = sdl2.ext.Color(255, 0, 0) GREEN = sdl2.ext.Color(0, 255, 0) # Create a resource, so we have easy access to the example images. RESOURCES = sdl2.ext.Resources(__file__, "resources") # A callback for the Button.motion event. def onmotion(button, event): print("Mouse moves over the button!") # A callback for the Button.click event. def onclick(button, event): print("Button was clicked!") # A callback for the TextEntry.input event. def oninput(entry, event): print("Input received with text '%s'" % event.text.text) print("Text on the entry now is '%s'" % entry.text) # A callback for the TextEntry.edit event. def onedit(entry, event): print("Edit received with text '%s', start '%d', length '%d'" % (event.text.text, event.text.start, event.text.length)) def oncheck(button, event): if button.checked: color = GREEN else: color = RED if button.factory.sprite_type == sdl2.ext.SOFTWARE: sdl2.ext.fill(button.surface, color) else: # SDL textures do not support color manipulation operation as easy # as software surface (since the texture is ideally stored somwhere # on the GPU memory in a GPU-specific layout [or not]). To circumvent # this, we create a temporary sprite (texture) and exchange the button # texture with it. tmpsprite = button.factory.from_color(color, button.size) button.texture, tmpsprite.texture = tmpsprite.texture, button.texture del tmpsprite def run(): # You know those from the helloworld.py example. # Initialize the video subsystem, create a window and make it visible. sdl2.ext.init() window = sdl2.ext.Window("UI Elements", size=(800, 600)) window.show() # Create a sprite factory that allows us to create visible 2D elements # easily. Depending on what the user chosses, we either create a factory # that supports hardware-accelerated sprites or software-based ones. # The hardware-accelerated SpriteFactory requres a rendering context # (or SDL_Renderer), which will create the underlying textures for us. if "-hardware" in sys.argv: print("Using hardware acceleration") renderer = sdl2.ext.Renderer(window) factory = sdl2.ext.SpriteFactory(sdl2.ext.TEXTURE, renderer=renderer) else: print("Using software rendering") factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE) # Create a UI factory, which will handle several defaults for # us. Also, the UIFactory can utilises software-based UI elements as # well as hardware-accelerated ones; this allows us to keep the UI # creation code clean. uifactory = sdl2.ext.UIFactory(factory) # Create a simple Button sprite, which reacts on mouse movements and # button presses and fill it with a white color. All UI elements # inherit directly from the TextureSprite (for TEXTURE) or SoftwareSprite # (for SOFTWARE), so everything you can do with those classes is also # possible for the UI elements. button = uifactory.from_image(sdl2.ext.BUTTON, RESOURCES.get_path("button.bmp")) button.position = 50, 50 # Create a TextEntry sprite, which reacts on keyboard presses and # text input. entry = uifactory.from_image(sdl2.ext.TEXTENTRY, RESOURCES.get_path("textentry.bmp")) entry.position = 50, 200 # Create a CheckButton sprite. The CheckButton is a specialised # Button, which can switch its state, identified by the 'checked' # attribute by clicking. checkbutton = uifactory.from_color(sdl2.ext.CHECKBUTTON, RED, size=(50, 50)) checkbutton.position = 200, 50 # Bind some actions to the button's event handlers. Whenever a click # (combination of a mouse button press and mouse button release), the # onclick() function will be called. # Whenever the mouse moves around in the area occupied by the button, the # onmotion() function will be called. # The event handlers receive the issuer of the event as first argument # (the button is the issuer of that event) and the SDL event data as second # argument for further processing, if necessary. button.click += onclick button.motion += onmotion # Bind some actions to the entry's event handlers. The TextEntry # receives input events, once it has been activated by a mouse # button press on its designated area. The UIProcessor class takes # care of this internally through its activate() method. If the # TextEntry is activated, SDL_TEXTINPUT events are enabled by the # relevant SDL2 functions, causing input events to occur, that are # handled by the TextEntry. entry.input += oninput entry.editing += onedit checkbutton.click += oncheck checkbutton.factory = factory # Since all gui elements are sprites, we can use the # SpriteRenderSystem class, we learned about in helloworld.py, to # draw them on the Window. spriterenderer = factory.create_sprite_render_system(window) # Create a new UIProcessor, which will handle the user input events # and pass them on to the relevant user interface elements. uiprocessor = sdl2.ext.UIProcessor() running = True while running: events = sdl2.ext.get_events() for event in events: if event.type == sdl2.SDL_QUIT: running = False break # Pass the SDL2 events to the UIProcessor, which takes care of # the user interface logic. uiprocessor.dispatch([button, checkbutton, entry], event) # Render all user interface elements on the window. spriterenderer.render((button, entry, checkbutton)) sdl2.ext.quit() return 0 if __name__ == "__main__": sys.exit(run()) PySDL2-0.9.3/examples/helloworld.py0000644000000000000000000000654312312306406013776 0ustar """The almighty Hello World! example""" # We'll use sys to properly exit with an error code. import sys import sdl2.ext # Create a resource container, so that we can easily access all # resource, we bundle with our application. We are using the current # file's location and define the "resources" subdirectory as the # location, in which we keep all data. RESOURCES = sdl2.ext.Resources(__file__, "resources") def run(): # Initialize the video system - this implicitly initializes some # necessary parts within the SDL2 DLL used by the video module. # # You SHOULD call this before using any video related methods or # classes. sdl2.ext.init() # Create a new window (like your browser window or editor window, # etc.) and give it a meaningful title and size. We definitely need # this, if we want to present something to the user. window = sdl2.ext.Window("Hello World!", size=(592, 460)) # By default, every Window is hidden, not shown on the screen right # after creation. Thus we need to tell it to be shown now. window.show() # Create a sprite factory that allows us to create visible 2D elements # easily. Depending on what the user chosses, we either create a factory # that supports hardware-accelerated sprites or software-based ones. # The hardware-accelerated SpriteFactory requres a rendering context # (or SDL_Renderer), which will create the underlying textures for us. if "-hardware" in sys.argv: print("Using hardware acceleration") renderer = sdl2.ext.Renderer(window) factory = sdl2.ext.SpriteFactory(sdl2.ext.TEXTURE, renderer=renderer) else: print("Using software rendering") factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE) # Creates a simple rendering system for the Window. The # SpriteRenderSystem can draw Sprite objects on the window. spriterenderer = factory.create_sprite_render_system(window) # Creates a new 2D pixel-based surface to be displayed, processed or # manipulated. We will use the one of the shipped example images # from the resource package to display. sprite = factory.from_image(RESOURCES.get_path("hello.bmp")) # Display the surface on the window. This will copy the contents # (pixels) of the surface to the window. The surface will be # displayed at surface.position on the window. Play around with the # surface.x and surface.y values or surface.position (which is just # surface.x and surface.y grouped as tuple)! spriterenderer.render(sprite) # Set up an example event loop processing system. This is a necessity, # so the application can exit correctly, mouse movements, etc. are # recognised and so on. The TestEventProcessor class is just for # testing purposes and does not do anything meaningful. Take a look # at its code to better understand how the event processing can be # done and customized! processor = sdl2.ext.TestEventProcessor() # Start the event processing. This will run in an endless loop, so # everything following after processor.run() will not be executed # before some quitting event is raised. processor.run(window) # We called video.init(), so we have to call video.quit() as well to # release the resources hold by the SDL DLL. sdl2.ext.quit() return 0 if __name__ == "__main__": sys.exit(run()) PySDL2-0.9.3/examples/opengl.py0000644000000000000000000000303412312251754013104 0ustar """OpenGL rendering simulation""" import sys import ctypes from OpenGL import GL, GLU import sdl2 def run(): if sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO) != 0: print(sdl2.SDL_GetError()) return -1 window = sdl2.SDL_CreateWindow(b"OpenGL demo", sdl2.SDL_WINDOWPOS_UNDEFINED, sdl2.SDL_WINDOWPOS_UNDEFINED, 800, 600, sdl2.SDL_WINDOW_OPENGL) if not window: print(sdl2.SDL_GetError()) return -1 context = sdl2.SDL_GL_CreateContext(window) GL.glMatrixMode(GL.GL_PROJECTION | GL.GL_MODELVIEW) GL.glLoadIdentity() GL.glOrtho(-400, 400, 300, -300, 0, 1) x = 0.0 y = 30.0 event = sdl2.SDL_Event() running = True while running: while sdl2.SDL_PollEvent(ctypes.byref(event)) != 0: if event.type == sdl2.SDL_QUIT: running = False GL.glClearColor(0, 0, 0, 1) GL.glClear(GL.GL_COLOR_BUFFER_BIT) GL.glRotatef(10.0, 0.0, 0.0, 1.0) GL.glBegin(GL.GL_TRIANGLES) GL.glColor3f(1.0, 0.0, 0.0) GL.glVertex2f(x, y + 90.0) GL.glColor3f(0.0, 1.0, 0.0) GL.glVertex2f(x + 90.0, y - 90.0) GL.glColor3f(0.0, 0.0, 1.0) GL.glVertex2f(x - 90.0, y - 90.0) GL.glEnd() sdl2.SDL_GL_SwapWindow(window) sdl2.SDL_Delay(10) sdl2.SDL_GL_DeleteContext(context) sdl2.SDL_DestroyWindow(window) sdl2.SDL_Quit() return 0 if __name__ == "__main__": sys.exit(run()) PySDL2-0.9.3/examples/particles.py0000644000000000000000000002327212312306474013614 0ustar """Particle simulation""" import sys import random import sdl2 import sdl2.ext import sdl2.ext.particles # Create a resource, so we have easy access to the example images. RESOURCES = sdl2.ext.Resources(__file__, "resources") # The Particle class offered by sdl2.ext.particles only contains the life # time information of the particle, which will be decreased by one each # time the particle engine processes it, as well as a x- and # y-coordinate. This is not enough for us, since we want them to have a # velocity as well to make moving them around easier. Also, each # particle can look different for us, so we also store some information # about the image to display on rendering in ptype. # # If particles run out of life, we want to remove them, since we do not # want to flood our world with unused entities. Thus, we store a # reference to the entity, the particle belongs to, too. This allows use # to remove them easily later on. class CParticle(sdl2.ext.particles.Particle): def __init__(self, entity, x, y, vx, vy, ptype, life): super(CParticle, self).__init__(x, y, life) self.entity = entity self.type = ptype self.vx = vx self.vy = vy # A simple Entity class, that contains the particle information. This # represents our living particle object. class EParticle(sdl2.ext.Entity): def __init__(self, world, x, y, vx, vy, ptype, life): self.cparticle = CParticle(self, x, y, vx, vy, ptype, life) # A callback function for creating new particles. It is needed by the # ParticleEngine and the requirements are explained below. def createparticles(world, deadones, count=None): if deadones is not None: count = len(deadones) # Create a replacement for each particle that died. The particle # will be created at the current mouse cursor position (explained # below) with a random velocity, life time, and image to be # displayed. for c in range(count): x = world.mousex y = world.mousey vx = random.random() * 3 - 1 vy = random.random() * 3 - 1 life = random.randint(20, 100) ptype = random.randint(0, 2) # 0-2 denote the image to be used # We do not need to assign the particle to a variable, since it # will be added to the World and we do not need to do perform # any post-creation operations. EParticle(world, x, y, vx, vy, ptype, life) # A callback function for updating particles. It is needed by the # ParticleEngine and the requirements are explained below. def updateparticles(world, particles): # For each existing, living particle, move it to a new location, # based on its velocity. for p in particles: p.x += p.vx p.y += p.vy # A callback function for deleting particles. It is needed by the # ParticleEngine and the requirements are explained below. def deleteparticles(world, deadones): # As written in the comment for the CParticle class, we will use the # stored entity reference of the dead particle components to delete # the dead particles from the world. world.delete_entities(p.entity for p in deadones) # Create a simple rendering system for particles. This is somewhat # similar to the TextureSprinteRenderSystem from sdl2.ext. Since we operate on # particles rather than sprites, we need to provide our own rendering logic. class ParticleRenderSystem(sdl2.ext.System): def __init__(self, renderer, images): # Create a new particle renderer. The surface argument will be # the targets surface to do the rendering on. images is a set of # images to be used for rendering the particles. super(ParticleRenderSystem, self).__init__() # Define, what component instances are processed by the # ParticleRenderer. self.componenttypes = (CParticle,) self.renderer = renderer self.images = images def process(self, world, components): # Processing code that will render all existing CParticle # components that currently exist in the world. We have a 1:1 # mapping between the created particle entities and associated # particle components; that said, we render all created # particles here. # We deal with quite a set of items, so we create some shortcuts # to save Python the time to look things up. # # The SDL_Rect is used for the blit operation below and is used # as destination position for rendering the particle. r = sdl2.SDL_Rect() # The SDL2 blit function to use. This will take an image # (SDL_Texture) as source and copies it on the target. dorender = sdl2.SDL_RenderCopy # And some more shortcuts. sdlrenderer = self.renderer.renderer images = self.images # Before rendering all particles, make sure the old ones are # removed from the window by filling it with a black color. self.renderer.clear(0x0) # Render all particles. for particle in components: # Set the correct destination position for the particle r.x = int(particle.x) r.y = int(particle.y) # Select the correct image for the particle. img = images[particle.type] r.w, r.h = img.size # Render (or blit) the particle by using the designated image. dorender(sdlrenderer, img.texture, None, r) self.renderer.present() def run(): # Create the environment, in which our particles will exist. world = sdl2.ext.World() # Set up the globally available information about the current mouse # position. We use that information to determine the emitter # location for new particles. world.mousex = 400 world.mousey = 300 # Create the particle engine. It is just a simple System that uses # callback functions to update a set of components. engine = sdl2.ext.particles.ParticleEngine() # Bind the callback functions to the particle engine. The engine # does the following on processing: # 1) reduce the life time of each particle by one # 2) create a list of particles, which's life time is 0 or below. # 3) call createfunc() with the world passed to process() and # the list of dead particles # 4) call updatefunc() with the world passed to process() and the # set of particles, which still are alive. # 5) call deletefunc() with the world passed to process() and the # list of dead particles. deletefunc() is respsonible for # removing the dead particles from the world. engine.createfunc = createparticles engine.updatefunc = updateparticles engine.deletefunc = deleteparticles world.add_system(engine) # We create all particles at once before starting the processing. # We also could create them in chunks to have a visually more # appealing effect, but let's keep it simple. createparticles(world, None, 300) # Initialize the video subsystem, create a window and make it visible. sdl2.ext.init() window = sdl2.ext.Window("Particles", size=(800, 600)) window.show() # Create a hardware-accelerated sprite factory. The sprite factory requires # a rendering context, which enables it to create the underlying textures # that serve as the visual parts for the sprites. renderer = sdl2.ext.Renderer(window) factory = sdl2.ext.SpriteFactory(sdl2.ext.TEXTURE, renderer=renderer) # Create a set of images to be used as particles on rendering. The # images are used by the ParticleRenderer created below. images = (factory.from_image(RESOURCES.get_path("circle.png")), factory.from_image(RESOURCES.get_path("square.png")), factory.from_image(RESOURCES.get_path("star.png")) ) # Center the mouse on the window. We use the SDL2 functions directly # here. Since the SDL2 functions do not know anything about the # sdl2.ext.Window class, we have to pass the window's SDL_Window to it. sdl2.SDL_WarpMouseInWindow(window.window, world.mousex, world.mousey) # Hide the mouse cursor, so it does not show up - just show the # particles. sdl2.SDL_ShowCursor(0) # Create the rendering system for the particles. This is somewhat # similar to the SoftSpriteRenderer, but since we only operate with # hundreds of particles (and not sprites with all their overhead), # we need an own rendering system. particlerenderer = ParticleRenderSystem(renderer, images) world.add_system(particlerenderer) # The almighty event loop. You already know several parts of it. running = True while running: for event in sdl2.ext.get_events(): if event.type == sdl2.SDL_QUIT: running = False break if event.type == sdl2.SDL_MOUSEMOTION: # Take care of the mouse motions here. Every time the # mouse is moved, we will make that information globally # available to our application environment by updating # the world attributes created earlier. world.mousex = event.motion.x world.mousey = event.motion.y # We updated the mouse coordinates once, ditch all the # other ones. Since world.process() might take several # milliseconds, new motion events can occur on the event # queue (10ths to 100ths!), and we do not want to handle # each of them. For this example, it is enough to handle # one per update cycle. sdl2.SDL_FlushEvent(sdl2.SDL_MOUSEMOTION) break world.process() sdl2.SDL_Delay(1) sdl2.ext.quit() return 0 if __name__ == "__main__": sys.exit(run()) PySDL2-0.9.3/examples/pixelaccess.py0000644000000000000000000001025312312252337014122 0ustar """Direct pixel access examples.""" import sys import sdl2 import sdl2.ext # Define black and white as global values, so we can access them throughout # the code. BLACK = sdl2.ext.Color(0, 0, 0) WHITE = sdl2.ext.Color(255, 255, 255) # This function will use a rectangular area and fill each second horizontal # line with a white color on the passed surface. def draw_horizontal_stripes(surface, x1, x2, y1, y2): # Fill the entire surface with a black color. In contrast to # colorpalettes.py we use a Color() value here, just to demonstrate that # it really works. sdl2.ext.fill(surface, BLACK) # Create a 2D view that allows us to directly access each individual pixel # of the surface. The PixelView class is quite slow, since it uses an non- # optimised read-write access to each individual pixel and offset. It # works on every platform, though. pixelview = sdl2.ext.PixelView(surface) # Loop over the area bounds, considering each fourth line and every column # on the 2D view. The PixelView uses a y-x alignment to access pixels. # This mkeans that the first accessible dimension of the PixelView denotes # the horizontal lines of an image, and the second the vertical lines. for y in range(y1, y2, 4): for x in range(x1, x2): # Change the color of each individual pixel. We can assign any # color-like value here, since the assignment method of the # PixelView will implicitly check and convert the value to a # matching color for its target surface. pixelview[y][x] = WHITE # Explicitly delete the PixelView. Some surface types need to be locked # in order to access their pixels directly. The PixelView will do that # implicitly at creation time. Once we are done with all necessary # operations, we need to unlock the surface, which will be done # automatically at the time the PixelView is garbage-collected. del pixelview # as draw_horizontal_stripes(), but vertical def draw_vertical_stripes(surface, x1, x2, y1, y2): sdl2.ext.fill(surface, BLACK) pixelview = sdl2.ext.PixelView(surface) for x in range(x1, x2, 4): for y in range(y1, y2): pixelview[y][x] = WHITE del pixelview def run(): # You know those from the helloworld.py example. # Initialize the video subsystem, create a window and make it visible. sdl2.ext.init() window = sdl2.ext.Window("Pixel Access", size=(800, 600)) window.show() # As in colorpalettes.py, explicitly acquire the window's surface to # draw on. windowsurface = window.get_surface() # We implement the functionality as it was done in colorpalettes.py and # utilise a mapping table to look up the function to be executed, together # with the arguments they should receive functions = ((draw_horizontal_stripes, (windowsurface, 300, 500, 200, 400)), (draw_vertical_stripes, (windowsurface, 300, 500, 200, 400)), ) # A storage variable for the function we are currently on, so that we know # which function to execute next. curindex = 0 draw_horizontal_stripes(windowsurface, 300, 500, 200, 400) # The event loop is nearly the same as we used in colorpalettes.py. If you # do not know, what happens here, take a look at colorpalettes.py for a # detailled description. running = True while running: events = sdl2.ext.get_events() for event in events: if event.type == sdl2.SDL_QUIT: running = False break if event.type == sdl2.SDL_MOUSEBUTTONDOWN: curindex += 1 if curindex >= len(functions): curindex = 0 # In contrast to colorpalettes.py, our mapping table consists # of functions and their arguments. Thus, we get the currently # requested function and argument tuple and execute the # function with the arguments. func, args = functions[curindex] func(*args) break window.refresh() sdl2.ext.quit() return 0 if __name__ == "__main__": sys.exit(run()) PySDL2-0.9.3/examples/pong.py0000644000000000000000000001717412312306605012571 0ustar """The Pong Game.""" import sys import sdl2 import sdl2.ext BLACK = sdl2.ext.Color(0, 0, 0) WHITE = sdl2.ext.Color(255, 255, 255) PADDLE_SPEED = 3 BALL_SPEED = 3 class CollisionSystem(sdl2.ext.Applicator): def __init__(self, minx, miny, maxx, maxy): super(CollisionSystem, self).__init__() self.componenttypes = Velocity, sdl2.ext.Sprite self.ball = None self.minx = minx self.miny = miny self.maxx = maxx self.maxy = maxy def _overlap(self, item): sprite = item[1] if sprite == self.ball.sprite: return False left, top, right, bottom = sprite.area bleft, btop, bright, bbottom = self.ball.sprite.area return (bleft < right and bright > left and btop < bottom and bbottom > top) def process(self, world, componentsets): collitems = [comp for comp in componentsets if self._overlap(comp)] if len(collitems) != 0: self.ball.velocity.vx = -self.ball.velocity.vx sprite = collitems[0][1] ballcentery = self.ball.sprite.y + self.ball.sprite.size[1] // 2 halfheight = sprite.size[1] // 2 stepsize = halfheight // 10 degrees = 0.7 paddlecentery = sprite.y + halfheight if ballcentery < paddlecentery: factor = (paddlecentery - ballcentery) // stepsize self.ball.velocity.vy = -int(round(factor * degrees)) elif ballcentery > paddlecentery: factor = (ballcentery - paddlecentery) // stepsize self.ball.velocity.vy = int(round(factor * degrees)) else: self.ball.velocity.vy = -self.ball.velocity.vy if (self.ball.sprite.y <= self.miny or self.ball.sprite.y + self.ball.sprite.size[1] >= self.maxy): self.ball.velocity.vy = -self.ball.velocity.vy if (self.ball.sprite.x <= self.minx or self.ball.sprite.x + self.ball.sprite.size[0] >= self.maxx): self.ball.velocity.vx = -self.ball.velocity.vx class MovementSystem(sdl2.ext.Applicator): def __init__(self, minx, miny, maxx, maxy): super(MovementSystem, self).__init__() self.componenttypes = Velocity, sdl2.ext.Sprite self.minx = minx self.miny = miny self.maxx = maxx self.maxy = maxy def process(self, world, componentsets): for velocity, sprite in componentsets: swidth, sheight = sprite.size sprite.x += velocity.vx sprite.y += velocity.vy sprite.x = max(self.minx, sprite.x) sprite.y = max(self.miny, sprite.y) pmaxx = sprite.x + swidth pmaxy = sprite.y + sheight if pmaxx > self.maxx: sprite.x = self.maxx - swidth if pmaxy > self.maxy: sprite.y = self.maxy - sheight class TrackingAIController(sdl2.ext.Applicator): def __init__(self, miny, maxy): super(TrackingAIController, self).__init__() self.componenttypes = PlayerData, Velocity, sdl2.ext.Sprite self.miny = miny self.maxy = maxy self.ball = None def process(self, world, componentsets): for pdata, vel, sprite in componentsets: if not pdata.ai: continue sheight = sprite.size[1] centery = sprite.y + sheight // 2 if self.ball.velocity.vx < 0: # ball is moving away from the AI if centery < self.maxy // 2 - PADDLE_SPEED: vel.vy = PADDLE_SPEED elif centery > self.maxy // 2 + PADDLE_SPEED: vel.vy = -PADDLE_SPEED else: vel.vy = 0 else: bcentery = self.ball.sprite.y + self.ball.sprite.size[1] // 2 if bcentery < centery: vel.vy = -PADDLE_SPEED elif bcentery > centery: vel.vy = PADDLE_SPEED else: vel.vy = 0 class SoftwareRenderSystem(sdl2.ext.SoftwareSpriteRenderSystem): def __init__(self, window): super(SoftwareRenderSystem, self).__init__(window) def render(self, components): sdl2.ext.fill(self.surface, BLACK) super(SoftwareRenderSystem, self).render(components) class TextureRenderSystem(sdl2.ext.TextureSpriteRenderSystem): def __init__(self, renderer): super(TextureRenderSystem, self).__init__(renderer) self.renderer = renderer def render(self, components): tmp = self.renderer.color self.renderer.color = BLACK self.renderer.clear() self.renderer.color = tmp super(TextureRenderSystem, self).render(components) class Velocity(object): def __init__(self): super(Velocity, self).__init__() self.vx = 0 self.vy = 0 class PlayerData(object): def __init__(self): super(PlayerData, self).__init__() self.ai = False self.points = 0 class Player(sdl2.ext.Entity): def __init__(self, world, sprite, posx=0, posy=0, ai=False): self.sprite = sprite self.sprite.position = posx, posy self.velocity = Velocity() self.playerdata = PlayerData() self.playerdata.ai = ai class Ball(sdl2.ext.Entity): def __init__(self, world, sprite, posx=0, posy=0): self.sprite = sprite self.sprite.position = posx, posy self.velocity = Velocity() def run(): sdl2.ext.init() window = sdl2.ext.Window("The Pong Game", size=(800, 600)) window.show() if "-hardware" in sys.argv: print("Using hardware acceleration") renderer = sdl2.ext.Renderer(window) factory = sdl2.ext.SpriteFactory(sdl2.ext.TEXTURE, renderer=renderer) else: print("Using software rendering") factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE) # Create the paddles - we want white ones. To keep it easy enough for us, # we create a set of surfaces that can be used for Texture- and # Software-based sprites. sp_paddle1 = factory.from_color(WHITE, size=(20, 100)) sp_paddle2 = factory.from_color(WHITE, size=(20, 100)) sp_ball = factory.from_color(WHITE, size=(20, 20)) world = sdl2.ext.World() movement = MovementSystem(0, 0, 800, 600) collision = CollisionSystem(0, 0, 800, 600) aicontroller = TrackingAIController(0, 600) if factory.sprite_type == sdl2.ext.SOFTWARE: spriterenderer = SoftwareRenderSystem(window) else: spriterenderer = TextureRenderSystem(renderer) world.add_system(aicontroller) world.add_system(movement) world.add_system(collision) world.add_system(spriterenderer) player1 = Player(world, sp_paddle1, 0, 250) player2 = Player(world, sp_paddle2, 780, 250, True) ball = Ball(world, sp_ball, 390, 290) ball.velocity.vx = -BALL_SPEED collision.ball = ball aicontroller.ball = ball running = True while running: for event in sdl2.ext.get_events(): if event.type == sdl2.SDL_QUIT: running = False break if event.type == sdl2.SDL_KEYDOWN: if event.key.keysym.sym == sdl2.SDLK_UP: player1.velocity.vy = -PADDLE_SPEED elif event.key.keysym.sym == sdl2.SDLK_DOWN: player1.velocity.vy = PADDLE_SPEED elif event.type == sdl2.SDL_KEYUP: if event.key.keysym.sym in (sdl2.SDLK_UP, sdl2.SDLK_DOWN): player1.velocity.vy = 0 sdl2.SDL_Delay(10) world.process() if __name__ == "__main__": sys.exit(run()) PySDL2-0.9.3/examples/sdl2hello.py0000644000000000000000000000214112312253103013474 0ustar """Simple example for using sdl2 directly.""" import os import sys import ctypes import sdl2 def run(): sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO) window = sdl2.SDL_CreateWindow(b"Hello World", sdl2.SDL_WINDOWPOS_CENTERED, sdl2.SDL_WINDOWPOS_CENTERED, 592, 460, sdl2.SDL_WINDOW_SHOWN) fname = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "hello.bmp") image = sdl2.SDL_LoadBMP(fname.encode("utf-8")) windowsurface = sdl2.SDL_GetWindowSurface(window) sdl2.SDL_BlitSurface(image, None, windowsurface, None) sdl2.SDL_UpdateWindowSurface(window) sdl2.SDL_FreeSurface(image) running = True event = sdl2.SDL_Event() while running: while sdl2.SDL_PollEvent(ctypes.byref(event)) != 0: if event.type == sdl2.SDL_QUIT: running = False break sdl2.SDL_Delay(10) sdl2.SDL_DestroyWindow(window) sdl2.SDL_Quit() return 0 if __name__ == "__main__": sys.exit(run()) PySDL2-0.9.3/sdl2/0000755000000000000000000000000012357043742010301 5ustar PySDL2-0.9.3/sdl2/ext/0000755000000000000000000000000012357043742011101 5ustar PySDL2-0.9.3/sdl2/ext/__init__.py0000644000000000000000000000106412270411445013204 0ustar """sdl2 extensions. This package provides easy access to the most common used video and graphics functionality of the SDL2 bindings. It enables you to easily create windows, display on them and to manipulate the shown graphics. """ from .algorithms import * from .array import * from .color import * from .resources import * from .events import * from .ebs import * from .common import * from .draw import * from .font import * from .gui import * from .image import * from .pixelaccess import * from .sprite import * from .surface import * from .window import * PySDL2-0.9.3/sdl2/ext/algorithms.py0000644000000000000000000000727112323417052013623 0ustar """Common algorithms.""" import sys __all__ = ["liangbarsky", "cohensutherland", "clipline", "point_on_line"] def cohensutherland(left, top, right, bottom, x1, y1, x2, y2): """Clips a line to a rectangular area. This implements the Cohen-Sutherland line clipping algorithm. left, top, right and bottom denote the clipping area, into which the line defined by x1, y1 (start point) and x2, y2 (end point) will be clipped. If the line does not intersect with the rectangular clipping area, four None values will be returned as tuple. Otherwise a tuple of the clipped line points will be returned in the form (cx1, cy1, cx2, cy2). """ LEFT, RIGHT, LOWER, UPPER = 1, 2, 4, 8 def _getclip(xa, ya): p = 0 if xa < left: p = LEFT elif xa > right: p = RIGHT if ya < top: p |= LOWER elif ya > bottom: p |= UPPER return p k1 = _getclip(x1, y1) k2 = _getclip(x2, y2) while (k1 | k2) != 0: if (k1 & k2) != 0: return None, None, None, None opt = k1 or k2 if opt & UPPER: x = x1 + (x2 - x1) * (1.0 * (bottom - y1)) / (y2 - y1) y = bottom elif opt & LOWER: x = x1 + (x2 - x1) * (1.0 * (top - y1)) / (y2 - y1) y = top elif opt & RIGHT: y = y1 + (y2 - y1) * (1.0 * (right - x1)) / (x2 - x1) x = right elif opt & LEFT: y = y1 + (y2 - y1) * (1.0 * (left - x1)) / (x2 - x1) x = left else: # this should not happen raise RuntimeError("invalid clipping state") if opt == k1: # x1, y1 = int(x), int(y) x1, y1 = x, y k1 = _getclip(x1, y1) else: # x2, y2 = int(x), int(y) x2, y2 = x, y k2 = _getclip(x2, y2) return x1, y1, x2, y2 def liangbarsky(left, top, right, bottom, x1, y1, x2, y2): """Clips a line to a rectangular area. This implements the Liang-Barsky line clipping algorithm. left, top, right and bottom denote the clipping area, into which the line defined by x1, y1 (start point) and x2, y2 (end point) will be clipped. If the line does not intersect with the rectangular clipping area, four None values will be returned as tuple. Otherwise a tuple of the clipped line points will be returned in the form (cx1, cy1, cx2, cy2). """ dx = x2 - x1 * 1.0 dy = y2 - y1 * 1.0 dt0, dt1 = 0.0, 1.0 xx1 = x1 yy1 = y1 checks = ((-dx, x1 - left), (dx, right - x1), (-dy, y1 - top), (dy, bottom - y1)) for p, q in checks: if p == 0 and q < 0: return None, None, None, None if p != 0: dt = q / (p * 1.0) if p < 0: if dt > dt1: return None, None, None, None dt0 = max(dt0, dt) else: if dt < dt0: return None, None, None, None dt1 = min(dt1, dt) if dt0 > 0: x1 += dt0 * dx y1 += dt0 * dy if dt1 < 1: x2 = xx1 + dt1 * dx y2 = yy1 + dt1 * dy return x1, y1, x2, y2 clipline = lambda l, t, r, b, x1, y1, x2, y2, method = liangbarsky: \ method(l, t, r, b, x1, y1, x2, y2) def point_on_line(p1, p2, point): """Checks, if point is on the line segment [p1, p2].""" x1, y1 = p1 x2, y2 = p2 px, py = point det = (py - y1) * (x2 - x1) - (px - x1) * (y2 - y1) if abs(det) > sys.float_info.epsilon: return False return (min(x1, x2) <= px <= max(x1, x2) and min(y1, y2) <= py <= max(y1, y2)) PySDL2-0.9.3/sdl2/ext/array.py0000644000000000000000000002550112260256443012571 0ustar """ Conversion routines for sequences. """ import ctypes __all__ = ["CTypesView", "to_ctypes", "to_list", "to_tuple", "create_array", "MemoryView"] # Hack around an import error using relative import paths in Python 2.7 _ARRAY = __import__("array") def to_tuple(dataseq): """Converts a ctypes array to a tuple.""" return tuple(dataseq) def to_list(dataseq): """Converts a ctypes array to a list.""" return list(dataseq) def to_ctypes(dataseq, dtype, mcount=0): """Converts an arbitrary sequence to a ctypes array of the specified type and returns the ctypes array and amount of items as two-value tuple. Raises a TypeError, if one or more elements in the passed sequence do not match the passed type. """ if mcount > 0: count = mcount else: count = len(dataseq) if isinstance(dataseq, CTypesView): itemsize = ctypes.sizeof(dtype) if itemsize == 1: dataseq = dataseq.to_bytes() elif itemsize == 2: dataseq = dataseq.to_uint16() elif itemsize == 4: dataseq = dataseq.to_uint32() elif itemsize == 8: dataseq = dataseq.to_uint64() else: raise TypeError("unsupported data type for the passed CTypesView") valset = (count * dtype)(*dataseq) return valset, count def create_array(obj, itemsize): """Creates an array.array based copy of the passed object. itemsize denotes the size in bytes for a single element within obj. """ if itemsize == 1: return _ARRAY.array("B", obj) elif itemsize == 2: return _ARRAY.array("H", obj) elif itemsize == 4: return _ARRAY.array("I", obj) elif itemsize == 8: return _ARRAY.array("d", obj) else: raise TypeError("unsupported data type") class CTypesView(object): """A proxy for byte-wise accessible data types to be used in ctypes bindings. """ def __init__(self, obj, itemsize=1, docopy=False, objsize=None): """Creates a new CTypesView for the passed object. Unless docopy is True, the CTypesView tries to let ctypes bindings and other callers access the object's contents directly. For certain types, such as the bytearray, the object must not be reassigned after being encapsuled and used in ctypes bindings, if the contents are not copied. """ self._obj = obj self._isshared = True self._view = None self._itemsize = itemsize self._create_view(itemsize, bool(docopy), objsize) def _create_view(self, itemsize, docopy, objsize): """Creates the view on the specified object.""" self._isshared = not docopy bsize = 0 if objsize is None: bsize = len(self._obj) * itemsize else: bsize = objsize * itemsize if docopy: self._obj = create_array(self._obj, itemsize) try: self._view = (ctypes.c_ubyte * bsize).from_buffer(self._obj) except AttributeError: # pypy ctypes arrays do not feature a from_buffer() method. self._isshared = False # in case we requested a copy earlier, we do not need to recreate # the array, since we have it already. In any other case, create # a byte array. if not docopy: # Try to determine the itemsize again for array # instances, just in case the user assumed it to work. if isinstance(self._obj, _ARRAY.array): itemsize = self._obj.itemsize bsize = len(self._obj) * itemsize self._obj = create_array(self._obj, itemsize) self._view = (ctypes.c_ubyte * bsize)(*bytearray(self._obj)) def __repr__(self): dtype = type(self._obj).__name__ bsize = self.bytesize return "CTypesView(type=%s, bytesize=%d, shared=%s)" % (dtype, bsize, self.is_shared) def __len__(self): """Returns the length of the underlying object in bytes.""" return self.bytesize def to_bytes(self): """Returns a byte representation of the underlying object.""" castval = ctypes.POINTER(ctypes.c_ubyte * self.bytesize) return ctypes.cast(self.view, castval).contents def to_uint16(self): """Returns a 16-bit unsigned integer array of the object data.""" castval = ctypes.POINTER(ctypes.c_ushort * (self.bytesize // 2)) return ctypes.cast(self.view, castval).contents def to_uint32(self): """Returns a 32-bit unsigned integer array of the object data.""" castval = ctypes.POINTER(ctypes.c_uint * (self.bytesize // 4)) return ctypes.cast(self.view, castval).contents def to_uint64(self): """Returns a 64-bit unsigned integer array of the object data.""" castval = ctypes.POINTER(ctypes.c_ulonglong * (self.bytesize // 8)) return ctypes.cast(self.view, castval).contents @property def bytesize(self): """The size in bytes of the underlying object.""" return ctypes.sizeof(self.view) @property def view(self): """The ctypes view of the object.""" return self._view @property def is_shared(self): """Indicates, if changes on the CTypesView data effect the underlying object directly. """ return self._isshared @property def object(self): """The underlying object.""" return self._obj class MemoryView(object): """Simple n-dimensional access to buffers. The MemoryView provides a read-write access to arbitrary data objects, which can be indexed. NOTE: The MemoryView is a pure Python-based implementation and makes heavy use of recursion for multi-dimensional access. If you aim for speed on accessing a n-dimensional object, you want to consider using a specialised library such as numpy. If you need n-dimensional access support, where such a library is not supported, or if you need to provide access to objects, which do not fulfill the requirements of that particular libray, MemoryView can act as solid fallback solution. """ def __init__(self, source, itemsize, strides, getfunc=None, setfunc=None, srcsize=None): """Creates a new MemoryView from a source. itemsize denotes the size of a single item. strides defines the dimensions and the length (n items * itemsize) for each dimension. getfunc and setfunc are optional parameters to provide specialised read and write access to the underlying source. srcsize can be used to provide the correct source size, if len(source) does not return the absolute size of the source object in all dimensions. """ self._source = source self._itemsize = itemsize self._strides = strides self._srcsize = srcsize or len(source) self._offset = 0 self._getfunc = getfunc or self._getbytes self._setfunc = setfunc or self._setbytes tsum = 1 for v in strides: tsum *= v if tsum > self._srcsize: raise ValueError("strides exceed the accesible source size") #if itemsize > strides[-1]: # raise ValueError("itemsize exceeds the accessible stride length") def _getbytes(self, start, end): """Gets the bytes within the range of start:end.""" return self._source[start:end] def _setbytes(self, start, end, value): """Gets the bytes within the range of start:end to the passed value. """ self._source[start:end] = value def __len__(self): """The length of the MemoryView over the current dimension (amount of items for the current dimension). """ return self.strides[0] def __repr__(self): retval = "[" slen = self.strides[0] for dim in range(slen - 1): retval += "%s, " % self[dim] retval += str(self[slen - 1]) retval += "]" return retval def __getitem__(self, index): """Returns the item at the specified index.""" if type(index) is slice: raise IndexError("slicing is not supported") else: if index >= len(self): raise IndexError("index '%d'is out of bounds for '%d'" % (index, len(self))) if self.ndim == 1: offset = self._offset + index * self.itemsize return self._getfunc(offset, offset + self.itemsize) else: advance = self.itemsize for b in self.strides[1:]: advance *= b offset = self._offset + advance * index view = MemoryView(self._source, self.itemsize, self.strides[1:], self._getfunc, self._setfunc, self._srcsize) view._offset = offset return view def __setitem__(self, index, value): """Sets the item at index to the specified value.""" if type(index) is slice: raise IndexError("slicing is not supported") else: if index >= len(self): raise IndexError("index '%d'is out of bounds for '%d'" % (index, len(self))) offset = self._offset + index * self.itemsize if self.ndim == 1: self._setfunc(offset, offset + self.itemsize, value) else: advance = self.itemsize for b in self.strides[1:]: advance *= b offset = self._offset + advance * index view = MemoryView(self._source, self.itemsize, self.strides[1:], self._getfunc, self._setfunc, self._srcsize) view._offset = offset if len(value) != len(view): raise ValueError("value does not match the view strides") for x in range(len(view)): view[x] = value[x] @property def size(self): """The size in bytes of the underlying source object.""" return self._srcsize @property def strides(self): """A tuple defining the length in bytes for accessing all elements in each dimension of the MemoryView. """ return self._strides @property def itemsize(self): """The size of a single item in bytes.""" return self._itemsize @property def ndim(self): """The number of dimensions of the MemoryView.""" return len(self.strides) @property def source(self): """The underlying data source.""" return self._source PySDL2-0.9.3/sdl2/ext/color.py0000644000000000000000000004044212323025462012565 0ustar """ color module for color creation and conversion operations. """ from math import floor from .compat import * __all__ = ["Color", "is_rgb_color", "is_rgba_color", "argb_to_color", "ARGB", "rgba_to_color", "RGBA", "string_to_color", "convert_to_color", "COLOR"] class Color(object): """A simple RGBA-based color implementation.""" def __init__(self, r=255, g=255, b=255, a=255): """Creates a Color with the specified RGBA values.""" if r < 0 or r > 255: raise ValueError("r must be in the range [0; 255]") if g < 0 or g > 255: raise ValueError("r must be in the range [0; 255]") if b < 0 or b > 255: raise ValueError("r must be in the range [0; 255]") if a < 0 or a > 255: raise ValueError("r must be in the range [0; 255]") self._r = int(r) self._g = int(g) self._b = int(b) self._a = int(a) def __repr__(self): return "Color(r=%d, g=%d, b=%d, a=%d)" % \ (self.r, self.g, self.b, self.a) def __copy__(self): return Color(self.r, self.g, self.b, self.a) def __eq__(self, color): return self.r == color.r and self.g == color.g and \ self.b == color.b and self.a == color.a def __ne__(self, color): return self.r != color.r or self.g != color.g or \ self.b != color.b or self.a != color.a def __int__(self): return (self.r << 24 | self.g << 16 | self.b << 8 | self.a) def __long__(self): return (self.r << 24 | self.g << 16 | self.b << 8 | self.a) def __float__(self): return (self.r << 24 | self.g << 16 | self.b << 8 | self.a) * 1.0 def __index__(self): return (self.r << 24 | self.g << 16 | self.b << 8 | self.a) def __oct__(self): val = (self.r << 24 | self.g << 16 | self.b << 8 | self.a) return oct(val) def __hex__(self): val = (self.r << 24 | self.g << 16 | self.b << 8 | self.a) return hex(val) def __invert__(self): vals = (255 - self.r, 255 - self.g, 255 - self.b, 255 - self.a) return Color(vals[0], vals[1], vals[2], vals[3]) def __mod__(self, color): vals = (self.r % color.r, self.g % color.g, self.b % color.b, self.a % color.a) return Color(vals[0], vals[1], vals[2], vals[3]) def __div__(self, color): vals = [0, 0, 0, 0] if color.r != 0: vals[0] = self.r / color.r if color.g != 0: vals[1] = self.g / color.g if color.b != 0: vals[2] = self.b / color.b if color.a != 0: vals[3] = self.a / color.a return Color(vals[0], vals[1], vals[2], vals[3]) def __truediv__(self, color): vals = [0, 0, 0, 0] if color.r != 0: vals[0] = self.r / color.r if color.g != 0: vals[1] = self.g / color.g if color.b != 0: vals[2] = self.b / color.b if color.a != 0: vals[3] = self.a / color.a return Color(vals[0], vals[1], vals[2], vals[3]) def __mul__(self, color): vals = (min(self.r * color.r, 255), min(self.g * color.g, 255), min(self.b * color.b, 255), min(self.a * color.a, 255)) return Color(vals[0], vals[1], vals[2], vals[3]) def __sub__(self, color): vals = (max(self.r - color.r, 0), max(self.g - color.g, 0), max(self.b - color.b, 0), max(self.a - color.a, 0)) return Color(vals[0], vals[1], vals[2], vals[3]) def __add__(self, color): vals = (min(self.r + color.r, 255), min(self.g + color.g, 255), min(self.b + color.b, 255), min(self.a + color.a, 255)) return Color(vals[0], vals[1], vals[2], vals[3]) def __len__(self): return 4 def __getitem__(self, index): return (self.r, self.g, self.b, self.a)[index] def __setitem__(self, index, val): tmp = [self.r, self.g, self.b, self.a] tmp[index] = val self.r = tmp[0] self.g = tmp[1] self.b = tmp[2] self.a = tmp[3] @property def r(self): """Gets or sets the red value of the Color.""" return self._r @r.setter def r(self, val): """Gets or sets the red value of the Color.""" if type(val) not in(int, long): raise TypeError("value must be an int") if val < 0 or val > 255: raise ValueError("The value must be in the range [0; 255]") self._r = val @property def g(self): """Gets or sets the green value of the Color.""" return self._g @g.setter def g(self, val): """Gets or sets the green value of the Color.""" if type(val) not in(int, long): raise TypeError("value must be an int") if val < 0 or val > 255: raise ValueError("The value must be in the range [0; 255]") self._g = val @property def b(self): """Gets or sets the blue value of the Color.""" return self._b @b.setter def b(self, val): """Gets or sets the blue value of the Color.""" if type(val) not in(int, long): raise TypeError("value must be an int") if val < 0 or val > 255: raise ValueError("The value must be in the range [0; 255]") self._b = val @property def a(self): """Gets or sets the alpha value of the Color.""" return self._a @a.setter def a(self, val): """Gets or sets the alpha value of the Color.""" if type(val) not in(int, long): raise TypeError("value must be an int") if val < 0 or val > 255: raise ValueError("The value must be in the range [0; 255]") self._a = val @property def hsva(self): """The Color as HSVA value.""" rn = self.r / 255.0 gn = self.g / 255.0 bn = self.b / 255.0 an = self.a / 255.0 maxv = max(rn, gn, bn) minv = min(rn, gn, bn) diff = maxv - minv h = 0 s = 0 v = maxv * 100.0 a = an * 100.0 if maxv == minv: return(h, s, v, a) s = 100.0 * (maxv - minv) / maxv if maxv == rn: h = (60 * (gn - bn) / diff) % 360.0 elif maxv == gn: h = (60 * (bn - rn) / diff) + 120.0 else: h = (60 * (rn - gn) / diff) + 240.0 if h < 0: h += 360.0 return (h, s, v, a) @hsva.setter def hsva(self, value): """The Color as HSVA value.""" h, s, v, a = value for x in (h, s, v, a): if type(x) not in(int, long, float): raise TypeError("HSVA values must be of type float") if not (0 <= s <= 100) or not (0 <= v <= 100) or \ not (0 <= a <= 100) or not (0 <= h <= 360): raise ValueError("invalid HSVA value") self.a = int((a / 100.0) * 255) s /= 100.0 v /= 100.0 hi = int(floor(h / 60.0)) f = (h / 60.0) - hi p = v * (1 - s) q = v * (1 - s * f) t = v * (1 - s * (1 - f)) if hi == 0: self.r = int(v * 255) self.g = int(t * 255) self.b = int(p * 255) elif hi == 1: self.r = int(q * 255) self.g = int(v * 255) self.b = int(p * 255) elif hi == 2: self.r = int(p * 255) self.g = int(v * 255) self.b = int(t * 255) elif hi == 3: self.r = int(p * 255) self.g = int(q * 255) self.b = int(v * 255) elif hi == 4: self.r = int(t * 255) self.g = int(p * 255) self.b = int(v * 255) elif hi == 5: self.r = int(v * 255) self.g = int(p * 255) self.b = int(q * 255) else: raise OverflowError("invalid HSVA value") @property def hsla(self): """The Color a HSLA value.""" rn = self.r / 255.0 gn = self.g / 255.0 bn = self.b / 255.0 an = self.a / 255.0 maxv = max(rn, gn, bn) minv = min(rn, gn, bn) diff = maxv - minv h = 0 s = 0 l = 50.0 * (maxv + minv) a = an * 100.0 if maxv == minv: return(h, s, l, a) if l <= 50.0: s = diff / (maxv + minv) * 100.0 else: s = diff / (2.0 - maxv - minv) * 100.0 if maxv == rn: h = (60 * (gn - bn) / diff) % 360.0 elif maxv == gn: h = (60 * (bn - rn) / diff) + 120.0 else: h = (60 * (rn - gn) / diff) + 240.0 if h < 0: h += 360.0 return (h, s, l, a) @hsla.setter def hsla(self, value): """The Color a HSLA value.""" h, s, l, a = value for x in (h, s, l, a): if type(x) not in (int, long, float): raise TypeError("HSLA values must be of type float") if not (0 <= s <= 100) or not (0 <= l <= 100) or \ not (0 <= a <= 100) or not (0 <= h <= 360): raise ValueError("invalid HSLA value") self.a = int((a / 100.0) * 255) s /= 100.0 l /= 100.0 if s == 0: self.r = int(l * 255) self.g = int(l * 255) self.b = int(l * 255) return q = 0 if l < 0.5: q = l * (1 + s) else: q = l + s - (l * s) p = 2 * l - q ht = h / 360.0 # r h = ht + (1.0 / 3.0) if h < 0: h += 1 elif h > 1: h -= 1 if h < (1.0 / 6.0): self.r = int((p + ((q - p) * 6 * h)) * 255) elif h < 0.5: self.r = int(q * 255) elif h < (2.0 / 3.0): self.r = int((p + ((q - p) * 6 * (2.0 / 3.0 - h))) * 255) else: self.r = int(p * 255) # g h = ht if h < 0: h += 1 elif h > 1: h -= 1 if h < (1.0 / 6.0): self.g = int((p + ((q - p) * 6 * h)) * 255) elif h < 0.5: self.g = int(q * 255) elif h < (2.0 / 3.0): self.g = int((p + ((q - p) * 6 * (2.0 / 3.0 - h))) * 255) else: self.g = int(p * 255) # b h = ht - (1.0 / 3.0) if h < 0: h += 1 elif h > 1: h -= 1 if h < (1.0 / 6.0): self.b = int((p + ((q - p) * 6 * h)) * 255) elif h < 0.5: self.b = int(q * 255) elif h < (2.0 / 3.0): self.b = int((p + ((q - p) * 6 * (2.0 / 3.0 - h))) * 255) else: self.b = int(p * 255) @property def i1i2i3(self): """The Color as I1I2I3 value.""" rn = self.r / 255.0 gn = self.g / 255.0 bn = self.b / 255.0 i1 = (rn + gn + bn) / 3.0 i2 = (rn - bn) / 2.0 i3 = (2 * gn - rn - bn) / 4.0 return(i1, i2, i3) @i1i2i3.setter def i1i2i3(self, value): """The Color as I1I2I3 value.""" i1, i2, i3 = value for x in (i1, i2, i3): if type(x) not in (int, long, float): raise TypeError("I1I2I3 values must be of type float") if not (0 <= i1 <= 1) or not (-0.5 <= i2 <= 0.5) or \ not (-0.5 <= i3 <= 0.5): raise ValueError("invalid I1I2I3 value") ab = i1 - i2 - 2 * i3 / 3.0 ar = 2 * i2 + ab ag = 3 * i1 - ar - ab self.r = int(ar * 255) self.g = int(ag * 255) self.b = int(ab * 255) @property def cmy(self): """The Color as CMY value.""" return (1.0 - self.r / 255.0, 1.0 - self.g / 255.0, 1.0 - self.b / 255.0) @cmy.setter def cmy(self, value): """The Color as CMY value.""" c, m, y = value if (c < 0 or c > 1) or (m < 0 or m > 1) or (y < 0 or y > 1): raise ValueError("invalid CMY value") self.r = int((1.0 - c) * 255) self.g = int((1.0 - m) * 255) self.b = int((1.0 - y) * 255) def normalize(self): """Returns the RGBA values in a normalized form with the range [0;1] as tuple. """ return (self.r / 255.0, self.g / 255.0, self.b / 255.0, self.a / 255.0) def is_rgb_color(v): """Checks, if the passed value is an item that could be converted to a RGB color. """ try: if hasattr(v, "r") and hasattr(v, "g") and hasattr(v, "b"): if 0 <= int(v.r) <= 255 and 0 <= int(v.g) <= 255 and \ 0 <= v.b <= 255: return True if len(v) >= 3: if 0 <= int(v[0]) <= 255 and 0 <= int(v[1]) <= 255 and \ 0 < int(v[2]) < 255: return True return False except (TypeError, ValueError): return False def is_rgba_color(v): """Checks, if the passed value is an item that could be converted to a RGBA color. """ rgb = is_rgb_color(v) if not rgb: return False try: if hasattr(v, "a") and 0 <= int(v.a) <= 255: return True if len(v) >= 4 and 0 <= int(v[3]) <= 255: return True return False except (TypeError, ValueError): return False def argb_to_color(v): """Converts an integer value to a Color, assuming the integer represents a 32-bit ARGB value. """ v = long(v) a = ((v & 0xFF000000) >> 24) r = ((v & 0x00FF0000) >> 16) g = ((v & 0x0000FF00) >> 8) b = ((v & 0x000000FF)) return Color(r, g, b, a) ARGB = argb_to_color def rgba_to_color(v): """Converts an integer value to a Color, assuming the integer represents a 32-bit RGBBA value. """ v = long(v) r = ((v & 0xFF000000) >> 24) g = ((v & 0x00FF0000) >> 16) b = ((v & 0x0000FF00) >> 8) a = ((v & 0x000000FF)) return Color(r, g, b, a) RGBA = rgba_to_color def string_to_color(s): """Converts a hex color string or color name to a Color value. Supported hex values are: #RGB #RGBA #RRGGBB #RRGGBBAA 0xRGB 0xRGBA 0xRRGGBB 0xRRGGBBAA """ if type(s) is not str: raise TypeError("s must be a string") if not(s.startswith("#") or s.startswith("0x")): raise ValueError("value is not Color-compatible") if s.startswith("#"): s = s[1:] else: s = s[2:] r, g, b, a = 255, 255, 255, 255 if len(s) in (3, 4): # A triple/quadruple in the form #ead == #eeaadd r = int(s[0], 16) << 4 | int(s[0], 16) g = int(s[1], 16) << 4 | int(s[1], 16) b = int(s[2], 16) << 4 | int(s[2], 16) if len(s) == 4: a = int(s[3], 16) << 4 | int(s[3], 16) elif len(s) in (6, 8): r = int(s[0], 16) << 4 | int(s[1], 16) g = int(s[2], 16) << 4 | int(s[3], 16) b = int(s[4], 16) << 4 | int(s[5], 16) if len(s) == 8: a = int(s[6], 16) << 4 | int(s[7], 16) else: raise ValueError("value is not Color-compatible") return Color(r, g, b, a) def convert_to_color(v): """Tries to convert the passed value to a Color object. If the color is an integer value, it is assumed to be in ARGB layout. """ if isinstance(v, Color): return v if type(v) is str: return string_to_color(v) if type(v) in (int, long): return argb_to_color(v) r, g, b, a = 0, 0, 0, 0 if hasattr(v, "r") and hasattr(v, "g") and hasattr(v, "b"): if 0 <= int(v.r) <= 255 and 0 <= int(v.g) <= 255 and \ 0 <= v.b <= 255: r = int(v.r) g = int(v.g) b = int(v.b) if hasattr(v, "a") and 0 <= int(v.a) <= 255: a = int(v.a) else: raise ValueError("value is not Color-compatible") return Color(r, g, b, a) try: length = len(v) except: raise ValueError("value is not Color-compatible") if length < 3: raise ValueError("value is not Color-compatible") if 0 <= int(v[0]) <= 255 and 0 <= int(v[1]) <= 255 and \ 0 <= int(v[2]) <= 255: r = int(v[0]) g = int(v[1]) b = int(v[2]) if length >= 4 and 0 <= int(v[3]) <= 255: a = int(v[3]) return Color(r, g, b, a) raise ValueError("value is not Color-compatible") COLOR = convert_to_color PySDL2-0.9.3/sdl2/ext/colorpalettes.py0000644000000000000000000003243212260256443014334 0ustar """ Various, indexed color palettes. Indexed color palettes. The following palettes are currently available: +--------------------+---------------------------------------------------+ | MONOPALETTE | 1-bit monochrome palette (black and white). | +--------------------+---------------------------------------------------+ | GRAY2PALETTE | 2-bit grayscale palette with black, white and two | | | shades of gray. | +--------------------+---------------------------------------------------+ | GRAY4PALETTE | 4-bit grayscale palette with black, white and | | | 14 shades shades of gray. | +--------------------+---------------------------------------------------+ | GRAY8PALETTE | 8-bit grayscale palette with black, white and | | | 254 shades shades of gray. | +--------------------+---------------------------------------------------+ | RGB3PALETTE | 3-bit RGB color palette with pure red, green and | | | blue and their complementary colors as well as | | | black and white. | +--------------------+---------------------------------------------------+ | CGAPALETTE | CGA color palette. | +--------------------+---------------------------------------------------+ | EGAPALETTE | EGA color palette. | +--------------------+---------------------------------------------------+ | VGAPALETTE | 8-bit VGA color palette. | +--------------------+---------------------------------------------------+ | WEBPALETTE | "Safe" web color palette with 225 colors. | +--------------------+---------------------------------------------------+ """ from .color import Color, ARGB __all__ = ["MONOPALETTE", "GRAY2PALETTE", "GRAY4PALETTE", "CGAPALETTE", "EGAPALETTE", "WEBPALETTE", "RGB3PALETTE", "VGAPALETTE"] def _create_8bpp_gray(): """Creates a 8 bit grayscale color palette.""" l = [] for x in range(0x00, 0xF1, 0x10): for y in range(0x00, 0x10, 0x01): l.append(Color(x | y, x | y, x | y)) return tuple(l) MONOPALETTE = (ARGB(0xFF000000), ARGB(0xFFFFFFFF),) GRAY2PALETTE = ( ARGB(0xFF000000), ARGB(0xFF555555), ARGB(0xFFAAAAAA), ARGB(0xFFFFFFFF), ) GRAY4PALETTE = ( ARGB(0xFF000000), ARGB(0xFF111111), ARGB(0xFF222222), ARGB(0xFF333333), ARGB(0xFF444444), ARGB(0xFF555555), ARGB(0xFF666666), ARGB(0xFF777777), ARGB(0xFF888888), ARGB(0xFF999999), ARGB(0xFFAAAAAA), ARGB(0xFFBBBBBB), ARGB(0xFFCCCCCC), ARGB(0xFFDDDDDD), ARGB(0xFFEEEEEE), ARGB(0xFFFFFFFF), ) GRAY8PALETTE = _create_8bpp_gray() CGAPALETTE = ( ARGB(0xFF000000), ARGB(0xFF0000AA), ARGB(0xFF00AA00), ARGB(0xFF00AAAA), ARGB(0xFFAA0000), ARGB(0xFFAA00AA), ARGB(0xFFAA5500), ARGB(0xFFAAAAAA), ARGB(0xFF555555), ARGB(0xFF5555FF), ARGB(0xFF55FF55), ARGB(0xFF55FFFF), ARGB(0xFFFF5555), ARGB(0xFFFF55FF), ARGB(0xFFFFFF55), ARGB(0xFFFFFFFF), ) EGAPALETTE = ( ARGB(0xFF000000), ARGB(0xFF0000AA), ARGB(0xFF00AA00), ARGB(0xFF00AAAA), ARGB(0xFFAA0000), ARGB(0xFFAA00AA), ARGB(0xFFAAAA00), ARGB(0xFFAAAAAA), ARGB(0xFF000055), ARGB(0xFF0000FF), ARGB(0xFF00AA55), ARGB(0xFF00AAFF), ARGB(0xFFAA0055), ARGB(0xFFAA00FF), ARGB(0xFFAAAA55), ARGB(0xFFAAAAFF), ARGB(0xFF005500), ARGB(0xFF0055AA), ARGB(0xFF00FF00), ARGB(0xFF00FFAA), ARGB(0xFFAA5500), ARGB(0xFFAA55AA), ARGB(0xFFAAFF00), ARGB(0xFFAAFFAA), ARGB(0xFF005555), ARGB(0xFF0055FF), ARGB(0xFF00FF55), ARGB(0xFF00FFFF), ARGB(0xFFAA5555), ARGB(0xFFAA55FF), ARGB(0xFFAAFF55), ARGB(0xFFAAFFFF), ARGB(0xFF550000), ARGB(0xFF5500AA), ARGB(0xFF55AA00), ARGB(0xFF55AAAA), ARGB(0xFFFF0000), ARGB(0xFFFF00AA), ARGB(0xFFFFAA00), ARGB(0xFFFFAAAA), ARGB(0xFF550055), ARGB(0xFF5500FF), ARGB(0xFF55AA55), ARGB(0xFF55AAFF), ARGB(0xFFFF0055), ARGB(0xFFFF00FF), ARGB(0xFFFFAA55), ARGB(0xFFFFAAFF), ARGB(0xFF555500), ARGB(0xFF5555AA), ARGB(0xFF55FF00), ARGB(0xFF55FFAA), ARGB(0xFFFF5500), ARGB(0xFFFF55AA), ARGB(0xFFFFFF00), ARGB(0xFFFFFFAA), ARGB(0xFF555555), ARGB(0xFF5555FF), ARGB(0xFF55FF55), ARGB(0xFF55FFFF), ARGB(0xFFFF5555), ARGB(0xFFFF55FF), ARGB(0xFFFFFF55), ARGB(0xFFFFFFFF), ) WEBPALETTE = ( ARGB(0xFFFFFFFF), ARGB(0xFFFFFFCC), ARGB(0xFFFFFF99), ARGB(0xFFFFFF66), ARGB(0xFFFFFF33), ARGB(0xFFFFFF00), ARGB(0xFFFFCCFF), ARGB(0xFFFFCCCC), ARGB(0xFFFFCC99), ARGB(0xFFFFCC66), ARGB(0xFFFFCC33), ARGB(0xFFFFCC00), ARGB(0xFFFF99FF), ARGB(0xFFFF99CC), ARGB(0xFFFF9999), ARGB(0xFFFF9966), ARGB(0xFFFF9933), ARGB(0xFFFF9900), ARGB(0xFFFF66FF), ARGB(0xFFFF66CC), ARGB(0xFFFF6699), ARGB(0xFFFF6666), ARGB(0xFFFF6633), ARGB(0xFFFF6600), ARGB(0xFFFF33FF), ARGB(0xFFFF33CC), ARGB(0xFFFF3399), ARGB(0xFFFF3366), ARGB(0xFFFF3333), ARGB(0xFFFF3300), ARGB(0xFFFF00FF), ARGB(0xFFFF00CC), ARGB(0xFFFF0099), ARGB(0xFFFF0066), ARGB(0xFFFF0033), ARGB(0xFFFF0000), ARGB(0xFFCCFFFF), ARGB(0xFFCCFFCC), ARGB(0xFFCCFF99), ARGB(0xFFCCFF66), ARGB(0xFFCCFF33), ARGB(0xFFCCFF00), ARGB(0xFFCCCCFF), ARGB(0xFFCCCCCC), ARGB(0xFFCCCC99), ARGB(0xFFCCCC66), ARGB(0xFFCCCC33), ARGB(0xFFCCCC00), ARGB(0xFFCC99FF), ARGB(0xFFCC99CC), ARGB(0xFFCC9999), ARGB(0xFFCC9966), ARGB(0xFFCC9933), ARGB(0xFFCC9900), ARGB(0xFFCC66FF), ARGB(0xFFCC66CC), ARGB(0xFFCC6699), ARGB(0xFFCC6666), ARGB(0xFFCC6633), ARGB(0xFFCC6600), ARGB(0xFFCC33FF), ARGB(0xFFCC33CC), ARGB(0xFFCC3399), ARGB(0xFFCC3366), ARGB(0xFFCC3333), ARGB(0xFFCC3300), ARGB(0xFFCC00FF), ARGB(0xFFCC00CC), ARGB(0xFFCC0099), ARGB(0xFFCC0066), ARGB(0xFFCC0033), ARGB(0xFFCC0000), ARGB(0xFF99FFFF), ARGB(0xFF99FFCC), ARGB(0xFF99FF99), ARGB(0xFF99FF66), ARGB(0xFF99FF33), ARGB(0xFF99FF00), ARGB(0xFF99CCFF), ARGB(0xFF99CCCC), ARGB(0xFF99CC99), ARGB(0xFF99CC66), ARGB(0xFF99CC33), ARGB(0xFF99CC00), ARGB(0xFF9999FF), ARGB(0xFF9999CC), ARGB(0xFF999999), ARGB(0xFF999966), ARGB(0xFF999933), ARGB(0xFF999900), ARGB(0xFF9966FF), ARGB(0xFF9966CC), ARGB(0xFF996699), ARGB(0xFF996666), ARGB(0xFF996633), ARGB(0xFF996600), ARGB(0xFF9933FF), ARGB(0xFF9933CC), ARGB(0xFF993399), ARGB(0xFF993366), ARGB(0xFF993333), ARGB(0xFF993300), ARGB(0xFF9900FF), ARGB(0xFF9900CC), ARGB(0xFF990099), ARGB(0xFF990066), ARGB(0xFF990033), ARGB(0xFF990000), ARGB(0xFF66FFFF), ARGB(0xFF66FFCC), ARGB(0xFF66FF99), ARGB(0xFF66FF66), ARGB(0xFF66FF33), ARGB(0xFF66FF00), ARGB(0xFF66CCFF), ARGB(0xFF66CCCC), ARGB(0xFF66CC99), ARGB(0xFF66CC66), ARGB(0xFF66CC33), ARGB(0xFF66CC00), ARGB(0xFF6699FF), ARGB(0xFF6699CC), ARGB(0xFF669999), ARGB(0xFF669966), ARGB(0xFF669933), ARGB(0xFF669900), ARGB(0xFF6666FF), ARGB(0xFF6666CC), ARGB(0xFF666699), ARGB(0xFF666666), ARGB(0xFF666633), ARGB(0xFF666600), ARGB(0xFF6633FF), ARGB(0xFF6633CC), ARGB(0xFF663399), ARGB(0xFF663366), ARGB(0xFF663333), ARGB(0xFF663300), ARGB(0xFF6600FF), ARGB(0xFF6600CC), ARGB(0xFF660099), ARGB(0xFF660066), ARGB(0xFF660033), ARGB(0xFF660000), ARGB(0xFF33FFFF), ARGB(0xFF33FFCC), ARGB(0xFF33FF99), ARGB(0xFF33FF66), ARGB(0xFF33FF33), ARGB(0xFF33FF00), ARGB(0xFF33CCFF), ARGB(0xFF33CCCC), ARGB(0xFF33CC99), ARGB(0xFF33CC66), ARGB(0xFF33CC33), ARGB(0xFF33CC00), ARGB(0xFF3399FF), ARGB(0xFF3399CC), ARGB(0xFF339999), ARGB(0xFF339966), ARGB(0xFF339933), ARGB(0xFF339900), ARGB(0xFF3366FF), ARGB(0xFF3366CC), ARGB(0xFF336699), ARGB(0xFF336666), ARGB(0xFF336633), ARGB(0xFF336600), ARGB(0xFF3333FF), ARGB(0xFF3333CC), ARGB(0xFF333399), ARGB(0xFF333366), ARGB(0xFF333333), ARGB(0xFF333300), ARGB(0xFF3300FF), ARGB(0xFF3300CC), ARGB(0xFF330099), ARGB(0xFF330066), ARGB(0xFF330033), ARGB(0xFF330000), ARGB(0xFF00FFFF), ARGB(0xFF00FFCC), ARGB(0xFF00FF99), ARGB(0xFF00FF66), ARGB(0xFF00FF33), ARGB(0xFF00FF00), ARGB(0xFF00CCFF), ARGB(0xFF00CCCC), ARGB(0xFF00CC99), ARGB(0xFF00CC66), ARGB(0xFF00CC33), ARGB(0xFF00CC00), ARGB(0xFF0099FF), ARGB(0xFF0099CC), ARGB(0xFF009999), ARGB(0xFF009966), ARGB(0xFF009933), ARGB(0xFF009900), ARGB(0xFF0066FF), ARGB(0xFF0066CC), ARGB(0xFF006699), ARGB(0xFF006666), ARGB(0xFF006633), ARGB(0xFF006600), ARGB(0xFF0033FF), ARGB(0xFF0033CC), ARGB(0xFF003399), ARGB(0xFF003366), ARGB(0xFF003333), ARGB(0xFF003300), ARGB(0xFF0000FF), ARGB(0xFF0000CC), ARGB(0xFF000099), ARGB(0xFF000066), ARGB(0xFF000033), ARGB(0xFF000000), ) RGB3PALETTE = ( ARGB(0xFF000000), ARGB(0xFF0000FF), ARGB(0xFF00FF00), ARGB(0xFF00FFFF), ARGB(0xFFFF0000), ARGB(0xFFFF00FF), ARGB(0xFFFFFF00), ARGB(0xFFFFFFFF), ) VGAPALETTE = ( ARGB(0xFF000000), ARGB(0xFF0000AA), ARGB(0xFF00AA00), ARGB(0xFF00AAAA), ARGB(0xFFAA0000), ARGB(0xFFAA00AA), ARGB(0xFFAA5500), ARGB(0xFFAAAAAA), ARGB(0xFF555555), ARGB(0xFF5555FF), ARGB(0xFF55FF55), ARGB(0xFF55FFFF), ARGB(0xFFFF5555), ARGB(0xFFFF55FF), ARGB(0xFFFFFF55), ARGB(0xFFFFFFFF), ARGB(0xFF000000), ARGB(0xFF101010), ARGB(0xFF202020), ARGB(0xFF353535), ARGB(0xFF454545), ARGB(0xFF555555), ARGB(0xFF656565), ARGB(0xFF757575), ARGB(0xFF8A8A8A), ARGB(0xFF9A9A9A), ARGB(0xFFAAAAAA), ARGB(0xFFBABABA), ARGB(0xFFCACACA), ARGB(0xFFDFDFDF), ARGB(0xFFEFEFEF), ARGB(0xFFFFFFFF), ARGB(0xFF0000FF), ARGB(0xFF4100FF), ARGB(0xFF8200FF), ARGB(0xFFBE00FF), ARGB(0xFFFF00FF), ARGB(0xFFFF00BE), ARGB(0xFFFF0082), ARGB(0xFFFF0041), ARGB(0xFFFF0000), ARGB(0xFFFF4100), ARGB(0xFFFF8200), ARGB(0xFFFFBE00), ARGB(0xFFFFFF00), ARGB(0xFFBEFF00), ARGB(0xFF82FF00), ARGB(0xFF41FF00), ARGB(0xFF00FF00), ARGB(0xFF00FF41), ARGB(0xFF00FF82), ARGB(0xFF00FFBE), ARGB(0xFF00FFFF), ARGB(0xFF00BEFF), ARGB(0xFF0082FF), ARGB(0xFF0041FF), ARGB(0xFF8282FF), ARGB(0xFF9E82FF), ARGB(0xFFBE82FF), ARGB(0xFFDF82FF), ARGB(0xFFFF82FF), ARGB(0xFFFF82DF), ARGB(0xFFFF82BE), ARGB(0xFFFF829E), ARGB(0xFFFF8282), ARGB(0xFFFF9E82), ARGB(0xFFFFBE82), ARGB(0xFFFFDF82), ARGB(0xFFFFFF82), ARGB(0xFFDFFF82), ARGB(0xFFBEFF82), ARGB(0xFF9EFF82), ARGB(0xFF82FF82), ARGB(0xFF82FF9E), ARGB(0xFF82FFBE), ARGB(0xFF82FFDF), ARGB(0xFF82FFFF), ARGB(0xFF82DFFF), ARGB(0xFF82BEFF), ARGB(0xFF829EFF), ARGB(0xFFBABAFF), ARGB(0xFFCABAFF), ARGB(0xFFDFBAFF), ARGB(0xFFEFBAFF), ARGB(0xFFFFBAFF), ARGB(0xFFFFBAEF), ARGB(0xFFFFBADF), ARGB(0xFFFFBACA), ARGB(0xFFFFBABA), ARGB(0xFFFFCABA), ARGB(0xFFFFDFBA), ARGB(0xFFFFEFBA), ARGB(0xFFFFFFBA), ARGB(0xFFEFFFBA), ARGB(0xFFDFFFBA), ARGB(0xFFCAFFBA), ARGB(0xFFBAFFBA), ARGB(0xFFBAFFCA), ARGB(0xFFBAFFDF), ARGB(0xFFBAFFEF), ARGB(0xFFBAFFFF), ARGB(0xFFBAEFFF), ARGB(0xFFBADFFF), ARGB(0xFFBACAFF), ARGB(0xFF000071), ARGB(0xFF1C0071), ARGB(0xFF390071), ARGB(0xFF550071), ARGB(0xFF710071), ARGB(0xFF710055), ARGB(0xFF710039), ARGB(0xFF71001C), ARGB(0xFF710000), ARGB(0xFF711C00), ARGB(0xFF713900), ARGB(0xFF715500), ARGB(0xFF717100), ARGB(0xFF557100), ARGB(0xFF397100), ARGB(0xFF1C7100), ARGB(0xFF007100), ARGB(0xFF00711C), ARGB(0xFF007139), ARGB(0xFF007155), ARGB(0xFF007171), ARGB(0xFF005571), ARGB(0xFF003971), ARGB(0xFF001C71), ARGB(0xFF393971), ARGB(0xFF453971), ARGB(0xFF553971), ARGB(0xFF613971), ARGB(0xFF713971), ARGB(0xFF713961), ARGB(0xFF713955), ARGB(0xFF713945), ARGB(0xFF713939), ARGB(0xFF714539), ARGB(0xFF715539), ARGB(0xFF716139), ARGB(0xFF717139), ARGB(0xFF617139), ARGB(0xFF557139), ARGB(0xFF457139), ARGB(0xFF397139), ARGB(0xFF397145), ARGB(0xFF397155), ARGB(0xFF397161), ARGB(0xFF397171), ARGB(0xFF396171), ARGB(0xFF395571), ARGB(0xFF394571), ARGB(0xFF515171), ARGB(0xFF595171), ARGB(0xFF615171), ARGB(0xFF695171), ARGB(0xFF715171), ARGB(0xFF715169), ARGB(0xFF715161), ARGB(0xFF715159), ARGB(0xFF715151), ARGB(0xFF715951), ARGB(0xFF716151), ARGB(0xFF716951), ARGB(0xFF717151), ARGB(0xFF697151), ARGB(0xFF617151), ARGB(0xFF597151), ARGB(0xFF517151), ARGB(0xFF517159), ARGB(0xFF517161), ARGB(0xFF517169), ARGB(0xFF517171), ARGB(0xFF516971), ARGB(0xFF516171), ARGB(0xFF515971), ARGB(0xFF000041), ARGB(0xFF100041), ARGB(0xFF200041), ARGB(0xFF310041), ARGB(0xFF410041), ARGB(0xFF410031), ARGB(0xFF410020), ARGB(0xFF410010), ARGB(0xFF410000), ARGB(0xFF411000), ARGB(0xFF412000), ARGB(0xFF413100), ARGB(0xFF414100), ARGB(0xFF314100), ARGB(0xFF204100), ARGB(0xFF104100), ARGB(0xFF004100), ARGB(0xFF004110), ARGB(0xFF004120), ARGB(0xFF004131), ARGB(0xFF004141), ARGB(0xFF003141), ARGB(0xFF002041), ARGB(0xFF001041), ARGB(0xFF202041), ARGB(0xFF282041), ARGB(0xFF312041), ARGB(0xFF392041), ARGB(0xFF412041), ARGB(0xFF412039), ARGB(0xFF412031), ARGB(0xFF412028), ARGB(0xFF412020), ARGB(0xFF412820), ARGB(0xFF413120), ARGB(0xFF413920), ARGB(0xFF414120), ARGB(0xFF394120), ARGB(0xFF314120), ARGB(0xFF284120), ARGB(0xFF204120), ARGB(0xFF204128), ARGB(0xFF204131), ARGB(0xFF204139), ARGB(0xFF204141), ARGB(0xFF203941), ARGB(0xFF203141), ARGB(0xFF202841), ARGB(0xFF2D2D41), ARGB(0xFF312D41), ARGB(0xFF352D41), ARGB(0xFF3D2D41), ARGB(0xFF412D41), ARGB(0xFF412D3D), ARGB(0xFF412D35), ARGB(0xFF412D31), ARGB(0xFF412D2D), ARGB(0xFF41312D), ARGB(0xFF41352D), ARGB(0xFF413D2D), ARGB(0xFF41412D), ARGB(0xFF3D412D), ARGB(0xFF35412D), ARGB(0xFF31412D), ARGB(0xFF2D412D), ARGB(0xFF2D4131), ARGB(0xFF2D4135), ARGB(0xFF2D413D), ARGB(0xFF2D4141), ARGB(0xFF2D3D41), ARGB(0xFF2D3541), ARGB(0xFF2D3141), ARGB(0xFF000000), ARGB(0xFF000000), ARGB(0xFF000000), ARGB(0xFF000000), ARGB(0xFF000000), ARGB(0xFF000000), ARGB(0xFF000000), ARGB(0xFF000000), ) PySDL2-0.9.3/sdl2/ext/common.py0000644000000000000000000000513512260256443012744 0ustar """SDL2 helper functions.""" import ctypes from .. import SDL_Init, SDL_Quit, SDL_QuitSubSystem, SDL_WasInit, \ SDL_INIT_VIDEO, error, events, timer _HASSDLTTF = True try: from .. import sdlttf except ImportError: _HASSDLTTF = False _HASSDLIMAGE = True try: from .. import sdlimage except ImportError: _HASSDLIMAGE = False __all__ = ["SDLError", "init", "quit", "get_events", "TestEventProcessor"] class SDLError(Exception): """A SDL2 specific exception class.""" def __init__(self, msg=None): """Creates a new SDLError instance with the specified message. If no msg is passed, it will try to get the current SDL2 error via sdl2.error.SDL_GetError(). """ super(SDLError, self).__init__() self.msg = msg if not msg: self.msg = error.SDL_GetError() def __str__(self): return repr(self.msg) def init(): """Initializes the SDL2 video subsystem. Raises a SDLError, if the SDL2 video subsystem could not be initialised. """ if SDL_Init(SDL_INIT_VIDEO) != 0: raise SDLError() def quit(): """Quits the SDL2 video subysystem. If no other subsystems are active, this will also call sdl2.SDL_Quit(), sdlttf.TTF_Quit() and sdlimage.IMG_Quit(). """ SDL_QuitSubSystem(SDL_INIT_VIDEO) if SDL_WasInit(0) != 0: if _HASSDLTTF and sdlttf.TTF_WasInit() == 1: sdlttf.TTF_Quit() if _HASSDLIMAGE: sdlimage.IMG_Quit() SDL_Quit() def get_events(): """Gets all SDL events that are currently on the event queue.""" events.SDL_PumpEvents() evlist = [] SDL_PeepEvents = events.SDL_PeepEvents op = events.SDL_GETEVENT first = events.SDL_FIRSTEVENT last = events.SDL_LASTEVENT while True: evarray = (events.SDL_Event * 10)() ptr = ctypes.cast(evarray, ctypes.POINTER(events.SDL_Event)) ret = SDL_PeepEvents(ptr, 10, op, first, last) if ret <= 0: break evlist += list(evarray)[:ret] if ret < 10: break return evlist class TestEventProcessor(object): """A simple event processor for testing purposes.""" def run(self, window): """Starts an event loop without actually processing any event.""" event = events.SDL_Event() running = True while running: ret = events.SDL_PollEvent(ctypes.byref(event), 1) if ret == 1: if event.type == events.SDL_QUIT: running = False break window.refresh() timer.SDL_Delay(10) PySDL2-0.9.3/sdl2/ext/compat.py0000644000000000000000000000630212260256443012734 0ustar """ Python compatibility helpers. """ import sys import collections import warnings __all__ = ["stringify", "byteify", "isiterable", "ISPYTHON2", "ISPYTHON3", "platform_is_64bit", "deprecated", "deprecation", "UnsupportedError", "ExperimentalWarning", "experimental", ] ISPYTHON2 = False ISPYTHON3 = False if sys.version_info[0] < 3: # Wrapper around bytes() and decode() for Python 2.x byteify = lambda x, enc: x.encode(enc) # Wrapper around str() for Python 2.x stringify = lambda x, enc: str(x) ISPYTHON2 = True else: __all__ += ["long", "unichr", "callable", "unicode"] byteify = bytes stringify = lambda x, enc: x.decode(enc) long = int unichr = chr callable = lambda x: isinstance(x, collections.Callable) ISPYTHON3 = True unicode = str isiterable = lambda x: isinstance(x, collections.Iterable) def platform_is_64bit(): """Checks, if the platform is a 64-bit machine.""" is64bit = sys.maxsize > 2 ** 32 if sys.platform == "cli": is64bit = sys.executable.endswith("ipy64.exe") return is64bit def deprecated(func): """A simple decorator to mark functions and methods as deprecated.""" def wrapper(*fargs, **kw): warnings.warn("%s is deprecated." % func.__name__, category=DeprecationWarning, stacklevel=2) return func(*fargs, **kw) wrapper.__name__ = func.__name__ wrapper.__doc__ = func.__doc__ wrapper.__dict__.update(func.__dict__) return wrapper def deprecation(message): """Prints a deprecation message.""" warnings.warn(message, category=DeprecationWarning, stacklevel=2) class UnsupportedError(Exception): """Indicates that a certain class, function or behaviour is not supported. """ def __init__(self, obj, msg=None): """Creates an UnsupportedError for the specified obj. If a message is passed in msg, it will be printed instead of the default message. """ super(UnsupportedError, self).__init__() self.obj = obj self.msg = msg def __str__(self): if self.msg is None: return "'%s' is not supported" % repr(self.obj) return repr(self.msg) class ExperimentalWarning(Warning): """Indicates that a certain class, function or behaviour is in an experimental state. """ def __init__(self, obj, msg=None): """Creates a ExperimentalWarning for the specified obj. If a message is passed in msg, it will be printed instead of the default message. """ super(ExperimentalWarning, self).__init__() self.obj = obj self.msg = msg def __str__(self): if self.msg is None: return "%s is in an experimental state." % repr(self.obj) return repr(self.msg) def experimental(func): """A simple decorator to mark functions and methods as experimental.""" def wrapper(*fargs, **kw): warnings.warn("%s" % func.__name__, category=ExperimentalWarning, stacklevel=2) return func(*fargs, **kw) wrapper.__name__ = func.__name__ wrapper.__doc__ = func.__doc__ wrapper.__dict__.update(func.__dict__) return wrapper PySDL2-0.9.3/sdl2/ext/draw.py0000644000000000000000000001262312260256443012411 0ustar """Drawing routines for software surfaces.""" import ctypes from .compat import isiterable, UnsupportedError from .array import to_ctypes from .color import convert_to_color from .. import surface, pixels, rect from .algorithms import clipline from .sprite import SoftwareSprite __all__ = ["prepare_color", "fill", "line"] def _get_target_surface(target): """Gets the SDL_surface from the passed target.""" if isinstance(target, surface.SDL_Surface): rtarget = target elif isinstance(target, SoftwareSprite): rtarget = target.surface else: raise TypeError("unsupported target type") return rtarget def prepare_color(color, target): """Prepares the passed color for the passed target.""" color = convert_to_color(color) pformat = None # Software surfaces if isinstance(target, pixels.SDL_PixelFormat): pformat = target elif isinstance(target, surface.SDL_Surface): pformat = target.format.contents elif isinstance(target, SoftwareSprite): pformat = target.surface.format.contents if pformat is None: raise TypeError("unsupported target type") if pformat.Amask != 0: # Target has an alpha mask return pixels.SDL_MapRGBA(pformat, color.r, color.g, color.b, color.a) return pixels.SDL_MapRGB(pformat, color.r, color.g, color.b) def fill(target, color, area=None): """Fills a certain rectangular area on the passed target with a color. If no area is provided, the entire target will be filled with the passed color. If an iterable item is provided as area (such as a list or tuple), it will be first checked, if the item denotes a single rectangular area (4 integer values) before assuming it to be a sequence of rectangular areas. """ color = prepare_color(color, target) rtarget = _get_target_surface(target) varea = None if area is not None and isiterable(area): # can be either a single rect or a list of rects) if len(area) == 4: # is it a rect? try: varea = rect.SDL_Rect(int(area[0]), int(area[1]), int(area[2]), int(area[3])) except: # No, not a rect, assume a seq of rects. pass if not varea: # len(area) == 4 AND varea set. varea = [] for r in area: varea.append(rect.SDL_Rect(r[0], r[1], r[2], r[3])) if varea is None or isinstance(varea, rect.SDL_Rect): surface.SDL_FillRect(rtarget, varea, color) else: varea, count = to_ctypes(varea, rect.SDL_Rect) varea = ctypes.cast(varea, ctypes.POINTER(rect.SDL_Rect)) surface.SDL_FillRects(rtarget, varea, count, color) def line(target, color, dline, width=1): """Draws one or multiple lines on the passed target. dline can be a sequence of four integers for a single line in the form (x1, y1, x2, y2) or a sequence of a multiple of 4 for drawing multiple lines at once, e.g. (x1, y1, x2, y2, x3, y3, x4, y4, ...). """ if width < 1: raise ValueError("width must be greater than 0") color = prepare_color(color, target) rtarget = _get_target_surface(target) # line: (x1, y1, x2, y2) OR (x1, y1, x2, y2, ...) if (len(dline) % 4) != 0: raise ValueError("line does not contain a valid set of points") pcount = len(dline) SDLRect = rect.SDL_Rect fillrect = surface.SDL_FillRect pitch = rtarget.pitch bpp = rtarget.format.contents.BytesPerPixel frac = pitch / bpp clip_rect = rtarget.clip_rect left, right = clip_rect.x, clip_rect.x + clip_rect.w - 1 top, bottom = clip_rect.y, clip_rect.y + clip_rect.h - 1 if bpp == 3: raise UnsupportedError(line, "24bpp are currently not supported") if bpp == 2: pxbuf = ctypes.cast(rtarget.pixels, ctypes.POINTER(ctypes.c_uint16)) elif bpp == 4: pxbuf = ctypes.cast(rtarget.pixels, ctypes.POINTER(ctypes.c_uint32)) else: pxbuf = rtarget.pixels # byte-wise access. for idx in range(0, pcount, 4): x1, y1, x2, y2 = dline[idx:idx + 4] if x1 == x2: # Vertical line yh = abs(y2 - y1) varea = SDLRect(x1 - width // 2, y1, width, yh) fillrect(rtarget, varea, color) continue if y1 == y2: # Horizontal line xw = abs(x2 - x1) varea = SDLRect(x1, y1 - width // 2, xw, width) fillrect(rtarget, varea, color) continue if width != 1: raise UnsupportedError(line, "width > 1 is not supported") if width == 1: # Bresenham x1, y1, x2, y2 = clipline(left, top, right, bottom, x1, y1, x2, y2) x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2) if x1 is None: # not to be drawn continue dx = abs(x2 - x1) dy = -abs(y2 - y1) err = dx + dy sx, sy = 1, 1 if x1 > x2: sx = -sx if y1 > y2: sy = -sy while True: pxbuf[int(y1 * frac + x1)] = color if x1 == x2 and y1 == y2: break e2 = err * 2 if e2 > dy: err += dy x1 += sx if e2 < dx: err += dx y1 += sy PySDL2-0.9.3/sdl2/ext/ebs.py0000644000000000000000000002452612323025462012225 0ustar """ A component-based entity system framework. ebs loosely follows a component oriented pattern to separate object instances, carried data and processing logic within applications or games. It uses a entity based approach, in which object instances are unique identifiers, while their data is managed within components, which are separately stored. For each individual component type a processing system will take care of all necessary updates for the World environment. """ import uuid import inspect from .compat import * __all__ = ["Entity", "World", "System", "Applicator"] class Entity(object): """A simple object entity. An entity is a specific object living in the application world. It does not carry any data or application logic, but merely acts as identifier label for data that is maintained in the application world itself. As such, it is an composition of components, which would not exist without the entity identifier. The entity itself is non-existent to the application world as long as it does not carry any data that can be processed by a system within the application world. """ def __new__(cls, world, *args, **kwargs): if not isinstance(world, World): raise TypeError("world must be a World") entity = object.__new__(cls) entity._id = uuid.uuid4() entity._world = world world.entities.add(entity) return entity def __repr__(self): return "Entity(id=%s)" % self._id def __hash__(self): return hash(self._id) def __getattr__(self, name): """Gets the component data related to the Entity.""" if name in ("_id", "_world"): return object.__getattr__(self, name) try: ctype = self._world._componenttypes[name] except KeyError: raise AttributeError("object '%r' has no attribute '%r'" % \ (self.__class__.__name__, name)) return self._world.components[ctype][self] def __setattr__(self, name, value): """Sets the component data related to the Entity.""" if name in ("_id", "_world"): object.__setattr__(self, name, value) else: # If the value is a compound component (e.g. a Button # inheriting from a Sprite), it needs to be added to all # supported component type instances. mro = inspect.getmro(value.__class__) if type in mro: stop = mro.index(type) else: stop = mro.index(object) mro = mro[0:stop] wctypes = self._world.componenttypes for clstype in mro: if clstype not in wctypes: self._world.add_componenttype(clstype) self._world.components[clstype][self] = value def __delattr__(self, name): """Deletes the component data related to the Entity.""" if name in ("_id", "_world"): raise AttributeError("'%s' cannot be deleted.", name) try: ctype = self._world._componenttypes[name] except KeyError: raise AttributeError("object '%s' has no attribute '%s'" % \ (self.__class__.__name__, name)) del self._world.components[ctype][self] def delete(self): """Removes the Entity from the world it belongs to.""" self.world.delete(self) @property def id(self): """The id of the Entity.""" return self._id @property def world(self): """The world the Entity resides in.""" return self._world class World(object): """A simple application world. An application world defines the combination of application data and processing logic and how the data will be processed. As such, it is a container object in which the application is defined. The application world maintains a set of entities and their related components as well as a set of systems that process the data of the entities. Each processing system within the application world only operates on a certain set of components, but not all components of an entity at once. The order in which data is processed depends on the order of the added systems. """ def __init__(self): """Creates a new World instance.""" self.entities = set() self._systems = [] self.components = {} self._componenttypes = {} def _system_is_valid(self, system): """Checks, if the passed object fulfills the requirements for being a processing system. """ return hasattr(system, "componenttypes") and \ isiterable(system.componenttypes) and \ hasattr(system, "process") and \ callable(system.process) def combined_components(self, comptypes): """A generator view on combined sets of component items.""" comps = self.components keysets = [set(comps[ctype]) for ctype in comptypes] valsets = [comps[ctype] for ctype in comptypes] entities = keysets[0].intersection(*keysets[1:]) for ekey in entities: yield tuple(component[ekey] for component in valsets) def add_componenttype(self, classtype): """Adds a supported component type to the World.""" if classtype in self._componenttypes.values(): return self.components[classtype] = {} self._componenttypes[classtype.__name__.lower()] = classtype def delete(self, entity): """Removes an Entity from the World, including all its data.""" for componentset in self.components.values(): componentset.pop(entity, None) self.entities.discard(entity) def delete_entities(self, entities): """Removes multiple entities from the World at once.""" eids = set(entities) if ISPYTHON2: for compkey, compset in self.components.viewitems(): keys = set(compset.viewkeys()) - eids self.components[compkey] = dict((k, compset[k]) for k in keys) else: for compkey, compset in self.components.items(): keys = set(compset.keys()) - eids self.components[compkey] = dict((k, compset[k]) for k in keys) self.entities -= set(entities) def get_components(self, componenttype): """Gets all existing components for a sepcific component type. If no components could be found for the passed component types, an empty list is returned. """ if componenttype in self.components: return self.components[componenttype].values() return [] def get_entities(self, component): """Gets the entities using the passed component. Note: this will not perform an identity check on the component but rely on its __eq__ implementation instead. """ compset = self.components.get(component.__class__, None) if compset is None: return [] return [e for e in compset if compset[e] == component] def add_system(self, system): """Adds a processing system to the world. The system will be added as last item in the processing order. Every object can be added as long as it contains * a 'componenttypes' attribute that is iterable and contains the class types to be processed * a 'process()' method, receiving two arguments, the world and components If the object contains a 'is_applicator' attribute that evaluates to True, the system will operate on combined sets of components. """ if not self._system_is_valid(system): raise ValueError("system must have componenttypes and a process method") for classtype in system.componenttypes: if classtype not in self.components: self.add_componenttype(classtype) self._systems.append(system) def insert_system(self, index, system): """Adds a processing system to the world. The system will be added at the specific position of the processing order. """ if not self._system_is_valid(system): raise ValueError("system must have componenttypes and a process method") for classtype in system.componenttypes: if classtype not in self.components: self.add_componenttype(classtype) self._systems.insert(index, system) def remove_system(self, system): """Removes a processing system from the world.""" self._systems.remove(system) def process(self): """Processes all components within their corresponding systems.""" components = self.components for system in self._systems: s_process = system.process if getattr(system, "is_applicator", False): comps = self.combined_components(system.componenttypes) s_process(self, comps) else: if ISPYTHON2: for ctype in system.componenttypes: s_process(self, components[ctype].viewvalues()) else: for ctype in system.componenttypes: s_process(self, components[ctype].values()) @property def systems(self): """Gets the systems bound to the world.""" return tuple(self._systems) @property def componenttypes(self): """Gets the supported component types of the world.""" return self._componenttypes.values() class System(object): """A processing system for component data. A processing system within an application world consumes the components of all entities, for which it was set up. At time of processing, the system does not know about any other component type that might be bound to any entity. Also, the processing system does not know about any specific entity, but only is aware of the data carried by all entities. """ def __init__(self): self.componenttypes = None def process(self, world, components): """Processes component items. This must be implemented by inheriting classes. """ raise NotImplementedError() class Applicator(System): """A processing system for combined data sets.""" def __init__(self): super(Applicator, self).__init__() self.is_applicator = True PySDL2-0.9.3/sdl2/ext/events.py0000644000000000000000000000564212260256443012763 0ustar """General purpose event handling routines""" from .compat import * __all__ = ["EventHandler", "MPEventHandler"] _HASMP = True try: from multiprocessing import Pool except ImportError: _HASMP = False class EventHandler(object): """A simple event handling class, which manages callbacks to be executed. """ def __init__(self, sender): self.callbacks = [] self.sender = sender def __call__(self, *args): """Executes all callbacks. Executes all connected callbacks in the order of addition, passing the sender of the EventHandler as first argument and the optional args as second, third, ... argument to them. """ return [callback(self.sender, *args) for callback in self.callbacks] def __iadd__(self, callback): """Adds a callback to the EventHandler.""" self.add(callback) return self def __isub__(self, callback): """Removes a callback from the EventHandler.""" self.remove(callback) return self def __len__(self): """Gets the amount of callbacks connected to the EventHandler.""" return len(self.callbacks) def __getitem__(self, index): return self.callbacks[index] def __setitem__(self, index, value): self.callbacks[index] = value def __delitem__(self, index): del self.callbacks[index] def add(self, callback): """Adds a callback to the EventHandler.""" if not callable(callback): raise TypeError("callback mus be callable") self.callbacks.append(callback) def remove(self, callback): """Removes a callback from the EventHandler.""" self.callbacks.remove(callback) def _mp_callback(args): # args = (function, sender, (args)) fargs = args[2] return args[0](args[1], *fargs) class MPEventHandler(EventHandler): """An asynchronous event handling class in which callbacks are executed in parallel. It is the responsibility of the caller code to ensure that every object used maintains a consistent state. The MPEventHandler class will not apply any locks, synchronous state changes or anything else to the arguments being used. Consider it a "fire-and-forget" event handling strategy """ def __init__(self, sender, maxprocs=None): if not _HASMP: raise UnsupportedError(MPEventHandler, "no multiprocessing support found") super(MPEventHandler, self).__init__(sender) self.maxprocs = maxprocs def __call__(self, *args): if self.maxprocs is not None: pool = Pool(processes=self.maxprocs) else: pool = Pool() psize = len(self.callbacks) pv = zip(self.callbacks, [self.sender] * psize, [args[:]] * psize) results = pool.map_async(_mp_callback, pv) pool.close() pool.join() return results PySDL2-0.9.3/sdl2/ext/font.py0000644000000000000000000002747312327135044012430 0ustar """Font and text rendering routines.""" import os from .. import surface, rect, pixels from .common import SDLError from .compat import * from .sprite import SoftwareSprite from .color import Color, convert_to_color _HASSDLTTF = True try: from .. import sdlttf except ImportError: _HASSDLTTF = False __all__ = ["BitmapFont", "FontManager"] class BitmapFont(object): """A bitmap graphics to character mapping. The BitmapFont class uses an image surface to find and render font character glyphs for text. It requires a mapping table, which denotes the characters available on the image. The mapping table is a list of strings, where each string reflects a 'line' of characters on the image. Each character within each line has the same size as specified by the size argument. A typical mapping table might look like [ '0123456789', 'ABCDEFGHIJ', 'KLMNOPQRST', 'UVWXYZ ', 'abcdefghij', 'klmnopqrst', 'uvwxyz ', ',;.:!?+-()' ] """ DEFAULTMAP = ["0123456789", "ABCDEFGHIJ", "KLMNOPQRST", "UVWXYZ ", "abcdefghij", "klmnopqrst", "uvwxyz ", ",;.:!?+-()" ] def __init__(self, imgsurface, size, mapping=None): """Creates a new BitmapFont instance from the passed image. Each character is expected to be of the same size (a 2-value tuple denoting the width and height) and to be in order of the passed mapping. """ if mapping is None: self.mapping = list(BitmapFont.DEFAULTMAP) else: self.mapping = mapping self.offsets = {} if isinstance(imgsurface, SoftwareSprite): self.surface = imgsurface.surface #elif isinstance(surface, sprite.Sprite): # TODO elif isinstance(imgsurface, surface.SDL_Surface): self.surface = imgsurface self.size = size[0], size[1] self._calculate_offsets() def _calculate_offsets(self): """Calculates the internal character offsets for each line.""" self.offsets = {} offsets = self.offsets x, y = 0, 0 w, h = self.size for line in self.mapping: x = 0 for c in line: offsets[c] = rect.SDL_Rect(x, y, w, h) x += w y += h def render(self, text, bpp=None): """Renders the passed text on a new Sprite and returns it.""" tw, th = 0, 0 w, h = self.size # TODO lines = text.split(os.linesep) for line in lines: tw = max(tw, sum([w for c in line])) th += h if bpp is None: bpp = self.surface.format.contents.BitsPerPixel sf = surface.SDL_CreateRGBSurface(0, tw, th, bpp, 0, 0, 0, 0) sf = sf.contents imgsurface = SoftwareSprite(sf, False) target = imgsurface.surface blit_surface = surface.SDL_BlitSurface fontsf = self.surface offsets = self.offsets dstr = rect.SDL_Rect(0, 0, 0, 0) y = 0 for line in lines: dstr.y = y x = 0 for c in line: dstr.x = x if c in offsets: blit_surface(fontsf, offsets[c], target, dstr) #elif c != ' ': # TODO: raise an exception for unknown char? x += w y += h return imgsurface def render_on(self, imgsurface, text, offset=(0, 0)): """Renders a text on the passed sprite, starting at a specific offset. The top-left start position of the text will be the passed offset and 4-value tuple with the changed area will be returned. """ w, h = self.size target = None if isinstance(imgsurface, SoftwareSprite): target = imgsurface.surface #elif isinstance(surface, sprite.Sprite): # TODO elif isinstance(imgsurface, surface.SDL_Surface): target = imgsurface else: raise TypeError("unsupported surface type") lines = text.split(os.linesep) blit_surface = surface.SDL_BlitSurface fontsf = self.surface offsets = self.offsets dstr = rect.SDL_Rect(0, 0, 0, 0) y = offset[1] for line in lines: dstr.y = y x = offset[0] for c in line: dstr.x = x if c in offsets: blit_surface(fontsf, offsets[c], target, dstr) #elif c != ' ': # TODO: raise an exception for unknown char? x += w y += h return (offset[0], offset[1], x + w, y + h) def contains(self, c): """Checks, whether a certain character exists in the font.""" return c == ' ' or c in self.offsets def can_render(self, text): """Checks, whether all characters in the passed text can be rendered. """ lines = text.split(os.linesep) for line in lines: for c in line: if c != ' ' and c not in self.offsets: return False return True class FontManager(object): """Manage fonts and rendering of text.""" def __init__(self, font_path, alias=None, size=16, color=Color(255, 255, 255), bg_color=Color(0, 0, 0)): """Initialize the FontManager One font path must be given to initialize the FontManager. The default_font will be set to this font. color and bg_color will give the FontManager a default color. size is the default font size in pixels. """ if not _HASSDLTTF: raise UnsupportedError(FontManager, "FontManager requires sdlttf support") if sdlttf.TTF_WasInit() == 0 and sdlttf.TTF_Init() != 0: raise SDLError() self.fonts = {} # fonts = {alias: {size:font_ptr}} self.aliases = {} # aliases = {alias:font_path} self._textcolor = pixels.SDL_Color(0, 0, 0) self._bgcolor = pixels.SDL_Color(255, 255, 255) self.color = color self.bg_color = bg_color self.size = size self._default_font = self.add(font_path, alias) def __del__(self): """Close all opened fonts.""" self.close() def close(self): """Close all opened fonts.""" for alias, fonts in self.fonts.items(): for size, font in fonts.items(): if font: sdlttf.TTF_CloseFont(font) self.fonts = {} self.aliases = {} def add(self, font_path, alias=None, size=None): """Add a font to the Font Manager. alias is by default the font name. But another name can be passed. Returns the font pointer stored in self.fonts. """ size = size or self.size if alias is None: # If no alias given, take the font name as alias basename = os.path.basename(font_path) alias = os.path.splitext(basename)[0] if alias in self.fonts: if size in self.fonts[alias] and self.fonts[alias]: # font with selected size already opened return else: self._change_font_size(alias, size) return else: if not os.path.isfile(font_path): raise IOError("Cannot find %s" % font_path) font = self._load_font(font_path, size) self.aliases[alias] = font_path self.fonts[alias] = {} self.fonts[alias][size] = font return font def _load_font(self, font_path, size): """Helper function to open the font. Raises an exception if something went wrong. """ font = sdlttf.TTF_OpenFont(byteify(font_path, "utf-8"), size) if font is None: raise SDLError() return font def _change_font_size(self, alias, size): """Loads an already opened font in another size.""" if alias not in self.fonts: raise KeyError("Font %s not loaded in FontManager" % alias) font = self._load_font(self.aliases[alias], size) self.fonts[alias][size] = font @property def color(self): """The text color to be used.""" return Color(self._textcolor.r, self._textcolor.g, self._textcolor.b, self._textcolor.a) @color.setter def color(self, value): """The text color to be used.""" c = convert_to_color(value) self._textcolor = pixels.SDL_Color(c.r, c.g, c.b, c.a) @property def bg_color(self): """The background color to be used.""" return Color(self._bgcolor.r, self._bgcolor.g, self._bgcolor.b, self._bgcolor.a) @bg_color.setter def bg_color(self, value): """The background color to be used.""" c = convert_to_color(value) self._bgcolor = pixels.SDL_Color(c.r, c.g, c.b, c.a) @property def default_font(self): """Returns the name of the current default_font.""" for alias in self.fonts: for size, font in self.fonts[alias].items(): if font == self._default_font: return alias @default_font.setter def default_font(self, value): """value must be a font alias Set the default_font to the given font name alias, provided it's loaded in the font manager. """ alias = value size = self.size if alias not in self.fonts: raise ValueError("Font %s not loaded in FontManager" % alias) # Check if size is already loaded, otherwise do it. if size not in self.fonts[alias]: self._change_font_size(alias, size) size = list(self.fonts[alias].keys())[0] self._default_font = self.fonts[alias][size] def render(self, text, alias=None, size=None, width=None, color=None, bg_color=None, **kwargs): """Renders text to a surface. This method uses the font designated by the alias or the default_font. A size can be passed even if the font was not loaded with this size. A width can be given for line wrapping. If no bg_color or color are given, it will default to the FontManager's bg_color and color. """ alias = alias or self.default_font size = size or self.size if bg_color is None: bg_color = self._bgcolor elif not isinstance(bg_color, pixels.SDL_Color): c = convert_to_color(bg_color) bg_color = pixels.SDL_Color(c.r, c.g, c.b, c.a) if color is None: color = self._textcolor elif not isinstance(color, pixels.SDL_Color): c = convert_to_color(color) color = pixels.SDL_Color(c.r, c.g, c.b, c.a) if len(self.fonts) == 0: raise TypeError("There are no fonts selected.") font = self._default_font if alias not in self.aliases: raise KeyError("Font %s not loaded" % font) elif size not in self.fonts[alias]: self._change_font_size(alias, size) font = self.fonts[alias][size] text = byteify(text, "utf-8") if width: sf = sdlttf.TTF_RenderUTF8_Blended_Wrapped(font, text, color, width) elif bg_color == pixels.SDL_Color(0, 0, 0): sf = sdlttf.TTF_RenderUTF8_Blended(font, text, color) else: sf = sdlttf.TTF_RenderUTF8_Shaded(font, text, color, bg_color) if not sf: raise SDLError(sdlttf.TTF_GetError()) return sf.contents PySDL2-0.9.3/sdl2/ext/gui.py0000644000000000000000000003243412321700063012230 0ustar """User interface elements.""" from .compat import isiterable, stringify from .ebs import System, World from .events import EventHandler from .sprite import Sprite from .. import events, mouse, keyboard, rect __all__ = ["RELEASED", "HOVERED", "PRESSED", "BUTTON", "CHECKBUTTON", "TEXTENTRY", "UIProcessor", "UIFactory" ] RELEASED = 0x0000 HOVERED = 0x0001 PRESSED = 0x0002 BUTTON = 0x0001 CHECKABLE = 0x0002 CHECKBUTTON = (CHECKABLE | BUTTON) TEXTENTRY = 0x0004 def _compose_button(obj): """Binds button attributes to the object, so it can be properly processed by the UIProcessor. Note: this is an internal helper method to avoid multiple inheritance and composition issues and should not be used by user code. """ obj.uitype = BUTTON obj.state = RELEASED obj.motion = EventHandler(obj) obj.pressed = EventHandler(obj) obj.released = EventHandler(obj) obj.click = EventHandler(obj) obj.events = { events.SDL_MOUSEMOTION: obj.motion, events.SDL_MOUSEBUTTONDOWN: obj.pressed, events.SDL_MOUSEBUTTONUP: obj.released } def _compose_checkbutton(obj): """Binds check button attributes to the object, so it can be properly processed by the UIProcessor. Note: this is an internal helper method to avoid multiple inheritance and composition issues and should not be used by user code. """ _compose_button(obj) obj.uitype = CHECKBUTTON obj.checked = False def _compose_textentry(obj): """Binds text entry attributes to the object, so it can be properly processed by the UIProcessor. Note: this is an internal helper method to avoid multiple inheritance and composition issues and should not be used by user code. """ obj.uitype = TEXTENTRY obj.text = "" obj.motion = EventHandler(obj) obj.pressed = EventHandler(obj) obj.released = EventHandler(obj) obj.keydown = EventHandler(obj) obj.keyup = EventHandler(obj) obj.input = EventHandler(obj) obj.editing = EventHandler(obj) obj.events = { events.SDL_MOUSEMOTION: obj.motion, events.SDL_MOUSEBUTTONDOWN: obj.pressed, events.SDL_MOUSEBUTTONUP: obj.released, events.SDL_TEXTEDITING: obj.editing, events.SDL_TEXTINPUT: obj.input, events.SDL_KEYDOWN: obj.keydown, events.SDL_KEYUP: obj.keyup } class UIFactory(object): """A simple UI factory for creating GUI elements for software- or texture-based rendering.""" def __init__(self, spritefactory, **kwargs): """Creates a new UIFactory. The additional kwargs will be stored internally and passed to the UI creation methods as arguments. Hence they can act as default arguments to be passed to each and every UI element to be created. """ self.spritefactory = spritefactory self.default_args = kwargs def from_image(self, uitype, fname): """Creates a new UI element from the passed image file.""" sprite = self.spritefactory.from_image(fname) if uitype == BUTTON: _compose_button(sprite) elif uitype == CHECKBUTTON: _compose_checkbutton(sprite) elif uitype == TEXTENTRY: _compose_textentry(sprite) else: del sprite raise ValueError("uitype must be a valid UI type identifier") return sprite def from_surface(self, uitype, surface, free=False): """Creates a new UI element from the passed SDL surface.""" sprite = self.spritefactory.from_surface(surface, free) if uitype == BUTTON: _compose_button(sprite) elif uitype == CHECKBUTTON: _compose_checkbutton(sprite) elif uitype == TEXTENTRY: _compose_textentry(sprite) else: del sprite raise ValueError("uitype must be a valid UI type identifier") return sprite def from_object(self, uitype, obj): """Creates a new UI element from an arbitrary object.""" sprite = self.spritefactory.from_object(obj) if uitype == BUTTON: _compose_button(sprite) elif uitype == CHECKBUTTON: _compose_checkbutton(sprite) elif uitype == TEXTENTRY: _compose_textentry(sprite) else: del sprite raise ValueError("uitype must be a valid UI type identifier") return sprite def from_color(self, uitype, color, size): """Creates a new UI element using a certain color.""" sprite = self.spritefactory.from_color(color, size) if uitype == BUTTON: _compose_button(sprite) elif uitype == CHECKBUTTON: _compose_checkbutton(sprite) elif uitype == TEXTENTRY: _compose_textentry(sprite) else: del sprite raise ValueError("uitype must be a valid UI type identifier") return sprite def create_button(self, **kwargs): """Creates a new Sprite that can react on mouse events.""" args = self.default_args.copy() args.update(kwargs) sprite = self.spritefactory.create_sprite(**args) _compose_button(sprite) return sprite def create_checkbutton(self, **kwargs): """Creates a new Sprite that can react on mouse events and retains its state.""" args = self.default_args.copy() args.update(kwargs) sprite = self.spritefactory.create_sprite(**args) _compose_checkbutton(sprite) return sprite def create_text_entry(self, **kwargs): """Creates a new Sprite that can react on text input.""" args = self.default_args.copy() args.update(kwargs) sprite = self.spritefactory.create_sprite(**args) _compose_textentry(sprite) return sprite def __repr__(self): return "UIFactory(spritefactory=%s, default_args=%s)" % \ (self.spritefactory, self.default_args) class UIProcessor(System): """A processing system for user interface elements and events.""" def __init__(self): """Creates a new UIProcessor.""" super(UIProcessor, self).__init__() self.componenttypes = (Sprite,) self._nextactive = None self._activecomponent = None self.handlers = { events.SDL_MOUSEMOTION: self.mousemotion, events.SDL_MOUSEBUTTONDOWN: self.mousedown, events.SDL_MOUSEBUTTONUP: self.mouseup, events.SDL_TEXTINPUT: self.textinput } def activate(self, component): """Activates a control to receive input.""" if self._activecomponent and self._activecomponent != component: self.deactivate(self._activecomponent) if (component.uitype & TEXTENTRY): area = rect.SDL_Rect(component.x, component.y, component.size[0], component.size[1]) keyboard.SDL_SetTextInputRect(area) keyboard.SDL_StartTextInput() self._activecomponent = component def deactivate(self, component): """Deactivates the currently active control.""" if component == self._activecomponent: if (self._activecomponent.uitype & TEXTENTRY): keyboard.SDL_StopTextInput() self._activecomponent = None def passevent(self, component, event): """Passes the event to a component without any additional checks or restrictions. """ component.events[event.type](event) def textinput(self, component, event): """Checks, if an active component is available and matches the passed component and passes the event on to that component.""" if self._activecomponent == component: if (component.uitype & TEXTENTRY): component.text += stringify(event.text.text, "utf-8") component.events[event.type](event) def mousemotion(self, component, event): """Checks, if the event's motion position is on the component and executes the component's event handlers on demand. If the motion event position is not within the area of the component, nothing will be done. In case the component is a Button, its state will be adjusted to reflect, if it is currently hovered or not. """ x1, y1, x2, y2 = component.area if event.motion.x >= x1 and event.motion.x < x2 and \ event.motion.y >= y1 and event.motion.y < y2: # Within the area of the component, raise the event on it. component.events[event.type](event) if (component.uitype & BUTTON): component.state |= HOVERED elif (component.uitype & BUTTON): # The mouse is not within the area of the button, reset the # state component.state &= ~HOVERED def mousedown(self, component, event): """Checks, if the event's button press position is on the component and executes the component's event handlers on demand. If the button press position is not within the area of the component, nothing will be done. In case the component is a Button, its state will be adjusted to reflect, if it is currently pressed or not. In case the component is a TextEntry and the pressed button is the primary mouse button, the component will be marked as the next control to activate for text input. """ x1, y1, x2, y2 = component.area if event.button.x >= x1 and event.button.x < x2 and \ event.button.y >= y1 and event.button.y < y2: # Within the area of the component, raise the event on it. component.events[event.type](event) if (component.uitype & BUTTON): component.state = PRESSED | HOVERED if (component.uitype & CHECKABLE): if event.button.button == mouse.SDL_BUTTON_LEFT: component.checked = not component.checked # Since we loop over all components, and might deactivate # some, store it temporarily for later activation. self._nextactive = component elif (component.uitype & BUTTON): component.state &= ~PRESSED def mouseup(self, component, event): """Checks, if the event's button release position is on the component and executes the component's event handlers on demand. If the button release position is not within the area of the component, nothing will be done. In case the component is a Button, its state will be adjusted to reflect, whether it is hovered or not. If the button release followed a button press on the same component and if the button is the primary button, the click() event handler is invoked, if the component is a Button. """ x1, y1, x2, y2 = component.area if event.button.x >= x1 and event.button.x < x2 and \ event.button.y >= y1 and event.button.y < y2: # Within the area of the component, raise the event on it. component.events[event.type](event) if (component.uitype & BUTTON): if (component.state & PRESSED) == PRESSED: # Was pressed already, now it is a click component.click(event) component.state = RELEASED | HOVERED elif (component.uitype & BUTTON): component.state &= ~HOVERED def dispatch(self, obj, event): """Passes an event to the given object. If obj is a World object, UI relevant components will receive the event, if they support the event type. If obj is a single object, obj.events MUST be a dictionary consisting of SDL event type identifiers and EventHandler instances bound to the object. obj also must have a 'uitype' attribute referring to the UI type of the object. If obj is an iterable, such as a list or set, every item within obj MUST feature an 'events' and 'uitype' attribute as described above. """ if event is None: return handler = self.handlers.get(event.type, self.passevent) if isinstance(obj, World): for ctype in self.componenttypes: items = obj.get_components(ctype) items = [(v, e) for v in items for e in (event,) if hasattr(v, "events") and hasattr(v, "uitype") \ and e.type in v.events] if len(items) > 0: arg1, arg2 = zip(*items) map(handler, arg1, arg2) elif isiterable(obj): items = [(v, e) for v in obj for e in (event,) if e.type in v.events] if len(items) > 0: for v, e in items: handler(v, e) elif event.type in obj.events: handler(obj, event) if self._nextactive is not None: self.activate(self._nextactive) self._nextactive = None def process(self, world, components): """The UIProcessor class does not implement the process() method by default. Instead it uses dispatch() to send events around to components. """ pass def __repr__(self): return "UIProcessor()" PySDL2-0.9.3/sdl2/ext/image.py0000644000000000000000000001270712326667501012545 0ustar """Image loaders.""" from .common import SDLError from .compat import UnsupportedError, byteify from .. import endian, surface, pixels _HASPIL = True try: from PIL import Image except ImportError: _HASPIL = False _HASSDLIMAGE = True try: from .. import sdlimage except ImportError: _HASSDLIMAGE = False __all__ = ["get_image_formats", "load_image"] def get_image_formats(): """Gets the formats supported in the default installation.""" if not _HASPIL and not _HASSDLIMAGE: return ("bmp", ) return ("bmp", "cur", "gif", "ico", "jpg", "lbm", "pbm", "pcx", "pgm", "png", "pnm", "ppm", "tga", "tif", "webp", "xcf", "xpm") def load_image(fname, enforce=None): """Creates a SDL_Surface from an image file. This function makes use of the Python Imaging Library, if it is available on the target execution environment. The function will try to load the file via sdl2 first. If the file could not be loaded, it will try to load it via sdl2.sdlimage and PIL. You can force the function to use only one of them, by passing the enforce as either "PIL" or "SDL". Note: This will call sdl2.sdlimage.init() implicitly with the default arguments, if the module is available and if sdl2.SDL_LoadBMP() failed to load the image. """ if enforce is not None and enforce not in ("PIL", "SDL"): raise ValueError("enforce must be either 'PIL' or 'SDL', if set") name = byteify(fname, "utf-8") if not _HASPIL and not _HASSDLIMAGE: imgsurface = surface.SDL_LoadBMP(name) if not imgsurface: raise UnsupportedError(load_image, "cannot use PIL or SDL for image loading") return imgsurface.contents if enforce == "PIL" and not _HASPIL: raise UnsupportedError(load_image, "cannot use PIL (not found)") if enforce == "SDL" and not _HASSDLIMAGE: imgsurface = surface.SDL_LoadBMP(name) if not imgsurface: raise UnsupportedError(load_image, "cannot use SDL_image (not found)") return imgsurface.contents imgsurface = None if enforce != "PIL" and _HASSDLIMAGE: sdlimage.IMG_Init(sdlimage.IMG_INIT_JPG | sdlimage.IMG_INIT_PNG | sdlimage.IMG_INIT_TIF | sdlimage.IMG_INIT_WEBP) imgsurface = sdlimage.IMG_Load(name) if not imgsurface: # An error occured - if we do not try PIL, break out now if not _HASPIL or enforce == "SDL": raise SDLError(sdlimage.IMG_GetError()) else: imgsurface = imgsurface.contents if enforce != "SDL" and _HASPIL and not imgsurface: image = Image.open(fname) mode = image.mode width, height = image.size rmask = gmask = bmask = amask = 0 if mode in ("1", "L", "P"): # 1 = B/W, 1 bit per byte # "L" = greyscale, 8-bit # "P" = palette-based, 8-bit pitch = width depth = 8 elif mode == "RGB": # 3x8-bit, 24bpp if endian.SDL_BYTEORDER == endian.SDL_LIL_ENDIAN: rmask = 0x0000FF gmask = 0x00FF00 bmask = 0xFF0000 else: rmask = 0xFF0000 gmask = 0x00FF00 bmask = 0x0000FF depth = 24 pitch = width * 3 elif mode in ("RGBA", "RGBX"): # RGBX: 4x8-bit, no alpha # RGBA: 4x8-bit, alpha if endian.SDL_BYTEORDER == endian.SDL_LIL_ENDIAN: rmask = 0x000000FF gmask = 0x0000FF00 bmask = 0x00FF0000 if mode == "RGBA": amask = 0xFF000000 else: rmask = 0xFF000000 gmask = 0x00FF0000 bmask = 0x0000FF00 if mode == "RGBA": amask = 0x000000FF depth = 32 pitch = width * 4 else: # We do not support CMYK or YCbCr for now raise TypeError("unsupported image format") pxbuf = image.tostring() imgsurface = surface.SDL_CreateRGBSurfaceFrom(pxbuf, width, height, depth, pitch, rmask, gmask, bmask, amask) if not imgsurface: raise SDLError() imgsurface = imgsurface.contents # the pixel buffer must not be freed for the lifetime of the surface imgsurface._pxbuf = pxbuf if mode == "P": # Create a SDL_Palette for the SDL_Surface def _chunk(seq, size): for x in range(0, len(seq), size): yield seq[x:x + size] rgbcolors = image.getpalette() sdlpalette = pixels.SDL_AllocPalette(len(rgbcolors) // 3) if not sdlpalette: raise SDLError() sdlpalette = sdlpalette.contents SDL_Color = pixels.SDL_Color for idx, (r, g, b) in enumerate(_chunk(rgbcolors, 3)): sdlpalette.colors[idx] = SDL_Color(r, g, b) ret = surface.SDL_SetSurfacePalette(imgsurface, sdlpalette) # This will decrease the refcount on the palette, so it gets # freed properly on releasing the SDL_Surface. pixels.SDL_FreePalette(sdlpalette) if ret != 0: raise SDLError() return imgsurface PySDL2-0.9.3/sdl2/ext/particles.py0000644000000000000000000001003412260256443013434 0ustar """ A simple particle engine implementation. """ from .compat import * from .ebs import System __all__ = ["Particle", "ParticleEngine"] class Particle(object): """A simple particle component type. The Particle component only contains information about a x- and y-coordinate and its current life time. The life time will be decreased by 1, everytime the particle is processed by the ParticleEngine. """ def __init__(self, x, y, life): """Creates a new Particle with a x-/y-position and life time.""" super(Particle, self).__init__() self.x = x self.y = y self.life = life @property def position(self): """The position of the Particle as tuple.""" return self.x, self.y @position.setter def position(self, value): """The position of the Particle as tuple.""" self.x = value[0] self.y = value[1] class ParticleEngine(System): """A simple particle processing system. The ParticleEngine takes care of creating, updating and deleting particles via callback functions. It only decreases the life of the particles by itself and marks them as dead, once the particle's life attribute has reached 0 or below. """ def __init__(self): """Creates a new ParticleEngine.""" super(ParticleEngine, self).__init__() self.componenttypes = (Particle,) self._createfunc = None self._deletefunc = None self._updatefunc = None def process(self, world, components): """Processes all particle components, decreasing their life by 1. Once the life of all particle components has been decreased properly and the particles considered dead (life <= 0) are identified, the creation, update and deletion callbacks are invoked. The creation callback takes the passed world as first and the list of dead particles as second argument. def particle_createfunc(world, list_of_dead_ones): ... Afterwards the still living particles are passed to the update callback, which also take the passed world as first and the living particles as set as second argument. def particle_updatefunc(world, set_of_living_ones): ... Finally, the dead particles need to be deleted in some way or another, which is done by the deletion callback, taking the passed world as first and the list of dead particles as second argument. def particle_deletefunc(world, list_of_dead_ones): ... """ deadones = [] dappend = deadones.append for p in components: p.life -= 1 if p.life <= 0: dappend(p) self.createfunc(world, deadones) self.updatefunc(world, set(components) - set(deadones)) self.deletefunc(world, deadones) @property def createfunc(self): """The function to be used for creating new particles.""" return self._createfunc @createfunc.setter def createfunc(self, value): """The function to be used for creating new particles.""" if not callable(value): raise TypeError("createfunc must be callable") self._createfunc = value @property def deletefunc(self): """The function to be used for deleting dead particles.""" return self._deletefunc @deletefunc.setter def deletefunc(self, value): """The function to be used for deletíng dead particles.""" if not callable(value): raise TypeError("deletefunc must be callable") self._deletefunc = value @property def updatefunc(self): """The function to be used for updating particles.""" return self._updatefunc @updatefunc.setter def updatefunc(self, value): """The function to be used for updating particles.""" if not callable(value): raise TypeError("updatefunc must be callable") self._updatefunc = value PySDL2-0.9.3/sdl2/ext/pixelaccess.py0000644000000000000000000001500112260256443013750 0ustar """Pixel-wise access routines.""" import ctypes from .compat import UnsupportedError, experimental from .array import MemoryView from ..surface import SDL_MUSTLOCK, SDL_LockSurface, SDL_UnlockSurface, \ SDL_Surface from ..stdinc import Uint8 from .sprite import SoftwareSprite from .draw import prepare_color __all__ = ["PixelView", "pixels2d", "pixels3d"] class PixelView(MemoryView): """2D memory view for Sprite and SDL_Surface pixel access. The PixelView uses a y/x-layout. Accessing view[N] will operate on the Nth row of the underlying surface. To access a specific column within that row, view[N][C] has to be used. NOTE: The PixelView is implemented on top of the MemoryView class. As such it makes heavy use of recursion to access rows and columns and can be considered as slow in contrast to optimised ndim-array solutions such as numpy. """ def __init__(self, source): """Creates a new PixelView from a Sprite or SDL_Surface. If necessary, the surface will be locked for accessing its pixel data. The lock will be removed once the PixelView is garbage-collected or deleted. """ if isinstance(source, SoftwareSprite): self._surface = source.surface # keep a reference, so the Sprite's not GC'd self._sprite = source elif isinstance(source, SDL_Surface): self._surface = source else: raise TypeError("source must be a Sprite or SDL_Surface") if SDL_MUSTLOCK(self._surface): SDL_LockSurface(self._surface) pxbuf = ctypes.cast(self._surface.pixels, ctypes.POINTER(Uint8)) itemsize = self._surface.format.contents.BytesPerPixel strides = (self._surface.h, self._surface.w) srcsize = self._surface.h * self._surface.pitch super(PixelView, self).__init__(pxbuf, itemsize, strides, getfunc=self._getitem, setfunc=self._setitem, srcsize=srcsize) def _getitem(self, start, end): if self.itemsize == 1: # byte-wise access return self.source[start:end] # move the pointer to the correct location src = ctypes.byref(self.source.contents, start) casttype = ctypes.c_ubyte if self.itemsize == 2: casttype = ctypes.c_ushort elif self.itemsize == 3: # TODO raise NotImplementedError("unsupported bpp") elif self.itemsize == 4: casttype = ctypes.c_uint return ctypes.cast(src, ctypes.POINTER(casttype)).contents.value def _setitem(self, start, end, value): target = None if self.itemsize == 1: target = ctypes.cast(self.source, ctypes.POINTER(ctypes.c_ubyte)) elif self.itemsize == 2: target = ctypes.cast(self.source, ctypes.POINTER(ctypes.c_ushort)) elif self.itemsize == 3: # TODO raise NotImplementedError("unsupported bpp") elif self.itemsize == 4: target = ctypes.cast(self.source, ctypes.POINTER(ctypes.c_uint)) value = prepare_color(value, self._surface) target[start // self.itemsize] = value def __del__(self): if self._surface is not None: if SDL_MUSTLOCK(self._surface): SDL_UnlockSurface(self._surface) _HASNUMPY = True try: import numpy class SurfaceArray(numpy.ndarray): """Wrapper class around numpy.ndarray. Used to keep track of the original source object for pixels2d() and pixels3d() to avoid the deletion of the source object. """ def __new__(cls, shape, dtype=float, buffer_=None, offset=0, strides=None, order=None, source=None, surface=None): sfarray = numpy.ndarray.__new__(cls, shape, dtype, buffer_, offset, strides, order) sfarray._source = source sfarray._surface = surface return sfarray def __array_finalize__(self, sfarray): if sfarray is None: return self._source = getattr(sfarray, '_source', None) self._surface = getattr(sfarray, '_surface', None) def __del__(self): if self._surface: if SDL_MUSTLOCK(self._surface): SDL_UnlockSurface(self._surface) except ImportError: _HASNUMPY = False @experimental def pixels2d(source): """Creates a 2D pixel array from the passed source.""" if not _HASNUMPY: raise UnsupportedError(pixels2d, "numpy module could not be loaded") if isinstance(source, SoftwareSprite): psurface = source.surface elif isinstance(source, SDL_Surface): psurface = source else: raise TypeError("source must be a Sprite or SDL_Surface") bpp = psurface.format.contents.BytesPerPixel if bpp < 1 or bpp > 4: raise ValueError("unsupported bpp") strides = (psurface.pitch, bpp) srcsize = psurface.h * psurface.pitch shape = psurface.h, psurface.w # surface.pitch // bpp dtypes = {1: numpy.uint8, 2: numpy.uint16, 3: numpy.uint32, 4: numpy.uint32 } if SDL_MUSTLOCK(psurface): SDL_LockSurface(psurface) pxbuf = ctypes.cast(psurface.pixels, ctypes.POINTER(ctypes.c_ubyte * srcsize)).contents return SurfaceArray(shape, dtypes[bpp], pxbuf, 0, strides, "C", source, psurface).transpose() @experimental def pixels3d(source): """Creates a 3D pixel array from the passed source. """ if not _HASNUMPY: raise UnsupportedError(pixels3d, "numpy module could not be loaded") if isinstance(source, SoftwareSprite): psurface = source.surface elif isinstance(source, SDL_Surface): psurface = source else: raise TypeError("source must be a Sprite or SDL_Surface") bpp = psurface.format.contents.BytesPerPixel if bpp < 1 or bpp > 4: raise ValueError("unsupported bpp") strides = (psurface.pitch, bpp, 1) srcsize = psurface.h * psurface.pitch shape = psurface.h, psurface.w, bpp if SDL_MUSTLOCK(psurface): SDL_LockSurface(psurface) pxbuf = ctypes.cast(psurface.pixels, ctypes.POINTER(ctypes.c_ubyte * srcsize)).contents return SurfaceArray(shape, numpy.uint8, pxbuf, 0, strides, "C", source, psurface).transpose(1, 0, 2) PySDL2-0.9.3/sdl2/ext/resources.py0000644000000000000000000002550612260256443013472 0ustar """ Resource management methods. """ import sys import os import re import zipfile import tarfile import io __all__ = ["open_zipfile", "open_tarfile", "open_url", "Resources"] # Python 3.x workarounds for the changed urllib modules. if sys.version_info[0] >= 3: import urllib.parse as urlparse import urllib.request as urllib2 else: import urlparse import urllib2 def open_zipfile(archive, filename, directory=None): """Opens and reads a certain file from a ZIP archive. Opens and reads a certain file from a ZIP archive. The result is returned as StringIO stream. filename can be a relative or absolute path within the ZIP archive. The optional directory argument can be used to supply a relative directory path, under which filename will be searched. If the filename could not be found, a KeyError will be raised. Raises a TypeError, if archive is not a valid ZIP archive. """ data = None opened = False if not isinstance(archive, zipfile.ZipFile): if not zipfile.is_zipfile(archive): raise TypeError("passed file does not seem to be a ZIP archive") else: archive = zipfile.ZipFile(archive, 'r') opened = True apath = filename if directory: apath = "%s/%s" % (directory, filename) try: dmpdata = archive.open(apath) data = io.BytesIO(dmpdata.read()) finally: if opened: archive.close() return data def open_tarfile(archive, filename, directory=None, ftype=None): """Opens and reads a certain file from a TAR archive. Opens and reads a certain file from a TAR archive. The result is returned as StringIO stream. filename can be a relative or absolute path within the TAR archive. The optional directory argument can be used to supply a relative directory path, under which filename will be searched. ftype is used to supply additional compression information, in case the system cannot determine the compression type itself, and can be either 'gz' for gzip compression or 'bz2' for bzip2 compression. Note: If ftype is supplied, the compression mode will be enforced for opening and reading. If the filename could not be found or an error occured on reading it, None will be returned. Raises a TypeError, if archive is not a valid TAR archive or if type is not a valid value of ('gz', 'bz2'). """ data = None opened = False mode = 'r' if ftype: if ftype not in ('gz', 'bz2'): raise TypeError("invalid TAR compression type") mode = "r:%s" % ftype if not isinstance(archive, tarfile.TarFile): if not tarfile.is_tarfile(archive): raise TypeError("passed file does not seem to be a TAR archive") else: archive = tarfile.open(archive, mode) opened = True apath = filename if directory: apath = "%s/%s" % (directory, filename) try: dmpdata = archive.extractfile(apath) data = io.BytesIO(dmpdata.read()) finally: if opened: archive.close() return data def open_url(filename, basepath=None): """Opens and reads a certain file from a web or remote location. Opens and reads a certain file from a web or remote location. This function utilizes the urllib2 module, which means that it is restricted to the types of remote locations supported by urllib2. basepath can be used to supply an additional location prefix. """ url = filename if basepath: url = urlparse.urljoin(basepath, filename) return urllib2.urlopen(url) class Resources(object): """The Resources class manages a set of file resources and eases accessing them by using relative paths, scanning archives automatically and so on. """ def __init__(self, path=None, subdir=None, excludepattern=None): """Creates a new resource container instance. If path is provided, the resource container will scan the path and add all found files to itself by invoking scan(path, subdir, excludepattern). """ self.files = {} if path: self.scan(path, subdir, excludepattern) def _scanzip(self, filename): """Scans the passed ZIP archive and indexes all the files contained by it. """ if not zipfile.is_zipfile(filename): raise TypeError("file '%s' is not a valid ZIP archive" % filename) archname = os.path.abspath(filename) zipf = zipfile.ZipFile(filename, 'r') for path in zipf.namelist(): fname = os.path.split(path)[1] if fname: self.files[fname] = (archname, 'zip', path) zipf.close() def _scantar(self, filename, ftype=None): """Scans the passed TAR archive and indexes all the files contained by it. """ if not tarfile.is_tarfile(filename): raise TypeError("file '%s' is not a valid TAR archive" % filename) mode = 'r' if ftype: if ftype not in ('gz', 'bz2'): raise TypeError("invalid TAR compression type") mode = "r:%s" % ftype archname = os.path.abspath(filename) archtype = 'tar' if ftype: archtype = 'tar%s' % ftype tar = tarfile.open(filename, mode) for path in tar.getnames(): fname = os.path.split(path)[1] self.files[fname] = (archname, archtype, path) tar.close() def add(self, filename): """Adds a file to the Resources container. Depending on the file type (determined by the file suffix or name), the file will be automatically scanned (if it is an archive) or checked for availability (if it is a stream/network resource). """ if not os.path.exists(filename): raise ValueError("invalid file path") if zipfile.is_zipfile(filename): self.add_archive(filename) elif tarfile.is_tarfile(filename): self.add_archive(filename, 'tar') else: self.add_file(filename) def add_file(self, filename): """Adds a file to the Resources container. This will only add the passed file and do not scan an archive or check a stream for availability. """ if not os.path.exists(filename): raise ValueError("invalid file path") abspath = os.path.abspath(filename) fname = os.path.split(abspath)[1] if not fname: raise ValueError("invalid file path") self.files[fname] = (None, None, abspath) def add_archive(self, filename, typehint='zip'): """Adds an archive file to the Resources container. This will scan the passed archive and add its contents to the list of available resources. """ if not os.path.exists(filename): raise ValueError("invalid file path") if typehint == 'zip': self._scanzip(filename) elif typehint == 'tar': self._scantar(filename) elif typehint == 'tarbz2': self._scantar(filename, 'bz2') elif typehint == 'targz': self._scantar(filename, 'gz') else: raise ValueError("unsupported archive type") def get(self, filename): """Gets a specific file from the Resources. Raises a KeyError, if filename could not be found. """ archive, ftype, pathname = self.files[filename] if archive: if ftype == 'zip': return open_zipfile(archive, pathname) elif ftype == 'tar': return open_tarfile(archive, pathname) elif ftype == 'tarbz2': return open_tarfile(archive, pathname, ftype='bz2') elif ftype == 'targz': return open_tarfile(archive, pathname, ftype='gz') else: raise ValueError("unsupported archive type") dmpdata = open(pathname, 'rb') data = io.BytesIO(dmpdata.read()) dmpdata.close() return data def get_filelike(self, filename): """Like get(), but tries to return the original file handle, if possible. If the passed filename is only available within an archive, a StringIO instance will be returned. Raises a KeyError, if filename could not be found. """ archive, ftype, pathname = self.files[filename] if archive: if ftype == 'zip': return open_zipfile(archive, pathname) elif ftype == 'tar': return open_tarfile(archive, pathname) elif ftype == 'tarbz2': return open_tarfile(archive, pathname, ftype='bz2') elif ftype == 'targz': return open_tarfile(archive, pathname, ftype='gz') else: raise ValueError("unsupported archive type") return open(pathname, 'rb') def get_path(self, filename): """Gets the path of the passed filename. If filename is only available within an archive, a string in the form 'filename@archivename' will be returned. Raises a KeyError, if filename could not be found. """ archive, ftype, pathname = self.files[filename] if archive: return '%s@%s' % (pathname, archive) return pathname def scan(self, path, subdir=None, excludepattern=None): """Scans a path and adds all found files to the Resources container. Scans a path and adds all found files to the Resources container. If a file is a supported (ZIP or TAR) archive, its contents will be indexed and added automatically. The method will consider the directory part (os.path.dirname) of the provided path as path to scan, if the path is not a directory. If subdir is provided, it will be appended to the path and used as starting point for adding files to the Resources container. excludepattern can be a regular expression to skip directories, which match the pattern. """ match = None if excludepattern: match = re.compile(excludepattern).match join = os.path.join add = self.add abspath = os.path.abspath(path) if not os.path.exists(abspath): raise ValueError("invalid path '%s'" % path) if not os.path.isdir(abspath): abspath = os.path.dirname(abspath) if subdir is not None: abspath = os.path.join(abspath, subdir) if not os.path.exists(abspath): raise ValueError("invalid path '%s'" % path) for (pdir, dirnames, filenames) in os.walk(abspath): if match and match(pdir) is not None: continue for fname in filenames: add(join(pdir, fname)) PySDL2-0.9.3/sdl2/ext/sprite.py0000644000000000000000000006412112326523661012764 0ustar """Sprite, texture and pixel surface routines.""" import abc from ctypes import byref, cast, POINTER, c_int, c_float from .common import SDLError from .compat import * from .color import convert_to_color from .ebs import System from .surface import subsurface from .window import Window from .image import load_image from .. import blendmode, surface, rect, video, pixels, render, rwops from ..stdinc import Uint8, Uint32 __all__ = ["Sprite", "SoftwareSprite", "TextureSprite", "SpriteFactory", "SoftwareSpriteRenderSystem", "SpriteRenderSystem", "TextureSpriteRenderSystem", "Renderer", "TEXTURE", "SOFTWARE"] TEXTURE = 0 SOFTWARE = 1 class Renderer(object): """SDL2-based renderer for windows and sprites.""" def __init__(self, target, index=-1, flags=render.SDL_RENDERER_ACCELERATED): """Creates a new Renderer for the given target. If target is a Window or SDL_Window, index and flags are passed to the relevant sdl.render.create_renderer() call. If target is a SoftwareSprite or SDL_Surface, the index and flags arguments are ignored. """ self.renderer = None self.rendertaget = None if isinstance(target, Window): self.renderer = render.SDL_CreateRenderer(target.window, index, flags) self.rendertarget = target.window elif isinstance(target, video.SDL_Window): self.renderer = render.SDL_CreateRenderer(target, index, flags) self.rendertarget = target elif isinstance(target, SoftwareSprite): self.renderer = render.SDL_CreateSoftwareRenderer(target.surface) self.rendertarget = target.surface elif isinstance(target, surface.SDL_Surface): self.renderer = render.SDL_CreateSoftwareRenderer(target) self.rendertarget = target else: raise TypeError("unsupported target type") def __del__(self): if self.renderer: render.SDL_DestroyRenderer(self.renderer) self.rendertarget = None @property def color(self): """The drawing color of the Renderer.""" r, g, b, a = Uint8(), Uint8(), Uint8(), Uint8() ret = render.SDL_GetRenderDrawColor(self.renderer, byref(r), byref(g), byref(b), byref(a)) if ret == -1: raise SDLError() return convert_to_color((r.value, g.value, b.value, a.value)) @color.setter def color(self, value): """The drawing color of the Renderer.""" c = convert_to_color(value) ret = render.SDL_SetRenderDrawColor(self.renderer, c.r, c.g, c.b, c.a) if ret == -1: raise SDLError() @property def blendmode(self): """The blend mode used for drawing operations (fill and line).""" mode = blendmode.SDL_BlendMode() ret = render.SDL_GetRenderDrawBlendMode(self.renderer, byref(mode)) if ret == -1: raise SDLError() return mode @blendmode.setter def blendmode(self, value): """The blend mode used for drawing operations (fill and line).""" ret = render.SDL_SetRenderDrawBlendMode(self.renderer, value) if ret == -1: raise SDLError() @property def scale(self): """The horizontal and vertical drawing scale.""" sx = c_float(0.0) sy = c_float(0.0) render.SDL_RenderGetScale(self.renderer, byref(sx), byref(sy)) return sx.value, sy.value @scale.setter def scale(self, value): """The horizontal and vertical drawing scale.""" ret = render.SDL_RenderGetScale(self.renderer, value[0], value[1]) if ret != 0: raise SDLError() def clear(self, color=None): """Clears the renderer with the currently set or passed color.""" if color is not None: tmp = self.color self.color = color ret = render.SDL_RenderClear(self.renderer) if color is not None: self.color = tmp if ret == -1: raise SDLError() def copy(self, src, srcrect=None, dstrect=None): """Copies (blits) the passed source to the target of the Renderer.""" SDL_Rect = rect.SDL_Rect if isinstance(src, TextureSprite): texture = src.texture elif isinstance(src, render.SDL_Texture): texture = src else: raise TypeError("src must be a TextureSprite or SDL_Texture") if srcrect is not None: x, y, w, h = srcrect srcrect = SDL_Rect(x, y, w, h) if dstrect is not None: x, y, w, h = dstrect dstrect = SDL_Rect(x, y, w, h) ret = render.SDL_RenderCopy(self.renderer, texture, srcrect, dstrect) if ret == -1: raise SDLError() def present(self): """Refreshes the target of the Renderer.""" render.SDL_RenderPresent(self.renderer) def draw_line(self, points, color=None): """Draws one or multiple lines on the renderer.""" # (x1, y1, x2, y2, ...) pcount = len(points) if (pcount % 4) != 0: raise ValueError("points does not contain a valid set of points") if pcount == 4: if color is not None: tmp = self.color self.color = color x1, y1, x2, y2 = points ret = render.SDL_RenderDrawLine(self.renderer, x1, y1, x2, y2) if color is not None: self.color = tmp if ret == -1: raise SDLError() else: x = 0 off = 0 count = pcount // 2 SDL_Point = rect.SDL_Point ptlist = (SDL_Point * count)() while x < pcount: ptlist[off] = SDL_Point(points[x], points[x + 1]) x += 2 off += 1 if color is not None: tmp = self.color self.color = color ptr = cast(ptlist, POINTER(SDL_Point)) ret = render.SDL_RenderDrawLines(self.renderer, ptr, count) if color is not None: self.color = tmp if ret == -1: raise SDLError() def draw_point(self, points, color=None): """Draws one or multiple points on the renderer.""" # (x1, y1, x2, y2, ...) pcount = len(points) if (pcount % 2) != 0: raise ValueError("points does not contain a valid set of points") if pcount == 2: if color is not None: tmp = self.color self.color = color ret = render.SDL_RenderDrawPoint(self.renderer, points[0], points[1]) if color is not None: self.color = tmp if ret == -1: raise SDLError() else: x = 0 off = 0 count = pcount // 2 SDL_Point = rect.SDL_Point ptlist = (SDL_Point * count)() while x < pcount: ptlist[off] = SDL_Point(points[x], points[x + 1]) x += 2 off += 1 if color is not None: tmp = self.color self.color = color ptr = cast(ptlist, POINTER(SDL_Point)) ret = render.SDL_RenderDrawPoints(self.renderer, ptr, count) if color is not None: self.color = tmp if ret == -1: raise SDLError() def draw_rect(self, rects, color=None): """Draws one or multiple rectangles on the renderer.""" SDL_Rect = rect.SDL_Rect # ((x, y, w, h), ...) if type(rects[0]) == int: # single rect if color is not None: tmp = self.color self.color = color x, y, w, h = rects ret = render.SDL_RenderDrawRect(self.renderer, SDL_Rect(x, y, w, h)) if color is not None: self.color = tmp if ret == -1: raise SDLError() else: x = 0 rlist = (SDL_Rect * len(rects))() for idx, r in enumerate(rects): rlist[idx] = SDL_Rect(r[0], r[1], r[2], r[3]) if color is not None: tmp = self.color self.color = color ptr = cast(rlist, POINTER(SDL_Rect)) ret = render.SDL_RenderDrawRects(self.renderer, ptr, len(rects)) if color is not None: self.color = tmp if ret == -1: raise SDLError() def fill(self, rects, color=None): """Fills one or multiple rectangular areas on the renderer.""" SDL_Rect = rect.SDL_Rect # ((x, y, w, h), ...) if type(rects[0]) == int: # single rect if color is not None: tmp = self.color self.color = color x, y, w, h = rects ret = render.SDL_RenderFillRect(self.renderer, SDL_Rect(x, y, w, h)) if color is not None: self.color = tmp if ret == -1: raise SDLError() else: x = 0 rlist = (SDL_Rect * len(rects))() for idx, r in enumerate(rects): rlist[idx] = SDL_Rect(r[0], r[1], r[2], r[3]) if color is not None: tmp = self.color self.color = color ptr = cast(rlist, POINTER(SDL_Rect)) ret = render.SDL_RenderFillRects(self.renderer, ptr, len(rects)) if color is not None: self.color = tmp if ret == -1: raise SDLError() class Sprite(object): """A simple 2D object.""" __metaclass__ = abc.ABCMeta def __init__(self): """Creates a new Sprite.""" super(Sprite, self).__init__() self.x = 0 self.y = 0 self.depth = 0 @property def position(self): """The top-left position of the Sprite as tuple.""" return self.x, self.y @position.setter def position(self, value): """The top-left position of the Sprite as tuple.""" self.x = value[0] self.y = value[1] @property @abc.abstractmethod def size(self): """The size of the Sprite as tuple.""" return @property def area(self): """The rectangular area occupied by the Sprite.""" w, h = self.size return (self.x, self.y, self.x + w, self.y + h) class SoftwareSprite(Sprite): """A simple, visible, pixel-based 2D object using software buffers.""" def __init__(self, imgsurface, free): """Creates a new SoftwareSprite.""" super(SoftwareSprite, self).__init__() self.free = free if not isinstance(imgsurface, surface.SDL_Surface): raise TypeError("surface must be a SDL_Surface") self.surface = imgsurface def __del__(self): """Releases the bound SDL_Surface, if it was created by the SoftwareSprite. """ imgsurface = getattr(self, "surface", None) if self.free and imgsurface is not None: surface.SDL_FreeSurface(imgsurface) self.surface = None @property def size(self): """The size of the SoftwareSprite as tuple.""" return self.surface.w, self.surface.h def subsprite(self, area): """Creates another SoftwareSprite from a part of the SoftwareSprite. The two sprites share pixel data, so if the parent sprite's surface is not managed by the sprite (free is False), you will need to keep it alive while the subsprite exists.""" ssurface = subsurface(self.surface, area) ssprite = SoftwareSprite(ssurface, True) # Keeps the parent surface alive until subsprite is freed if self.free: ssprite._parent = self return ssprite def __repr__(self): return "SoftwareSprite(size=%s, bpp=%d)" % \ (self.size, self.surface.format.contents.BitsPerPixel) class TextureSprite(Sprite): """A simple, visible, texture-based 2D object, using a renderer.""" def __init__(self, texture): """Creates a new TextureSprite.""" super(TextureSprite, self).__init__() self.texture = texture flags = Uint32() access = c_int() w = c_int() h = c_int() ret = render.SDL_QueryTexture(texture, byref(flags), byref(access), byref(w), byref(h)) if ret == -1: raise SDLError() self._size = w.value, h.value def __del__(self): """Releases the bound SDL_Texture.""" if self.texture is not None: render.SDL_DestroyTexture(self.texture) self.texture = None @property def size(self): """The size of the TextureSprite as tuple.""" return self._size def __repr__(self): flags = Uint32() access = c_int() w = c_int() h = c_int() ret = render.SDL_QueryTexture(self.texture, byref(flags), byref(access), byref(w), byref(h)) if ret == -1: raise SDLError() return "TextureSprite(format=%d, access=%d, size=%s)" % \ (flags.value, access.value, (w.value, h.value)) class SpriteFactory(object): """A factory class for creating Sprite components.""" def __init__(self, sprite_type=TEXTURE, **kwargs): """Creates a new SpriteFactory. The SpriteFactory can create TextureSprite or SoftwareSprite instances, depending on the sprite_type being passed to it, which can be SOFTWARE or TEXTURE. The additional kwargs are used as default arguments for creating sprites within the factory methods. """ if sprite_type == TEXTURE: if "renderer" not in kwargs: raise ValueError("you have to provide a renderer= argument") elif sprite_type != SOFTWARE: raise ValueError("stype must be TEXTURE or SOFTWARE") self._spritetype = sprite_type self.default_args = kwargs @property def sprite_type(self): """The sprite type created by the factory.""" return self._spritetype def __repr__(self): stype = "TEXTURE" if self.sprite_type == SOFTWARE: stype = "SOFTWARE" return "SpriteFactory(sprite_type=%s, default_args=%s)" % \ (stype, self.default_args) def create_sprite_render_system(self, *args, **kwargs): """Creates a new SpriteRenderSystem. For TEXTURE mode, the passed args and kwargs are ignored and the Renderer or SDL_Renderer passed to the SpriteFactory is used. """ if self.sprite_type == TEXTURE: return TextureSpriteRenderSystem(self.default_args["renderer"]) else: return SoftwareSpriteRenderSystem(*args, **kwargs) def from_image(self, fname): """Creates a Sprite from the passed image file.""" return self.from_surface(load_image(fname), True) def from_surface(self, tsurface, free=False): """Creates a Sprite from the passed SDL_Surface. If free is set to True, the passed surface will be freed automatically. """ if self.sprite_type == TEXTURE: renderer = self.default_args["renderer"] texture = render.SDL_CreateTextureFromSurface(renderer.renderer, tsurface) if not texture: raise SDLError() s = TextureSprite(texture.contents) if free: surface.SDL_FreeSurface(tsurface) elif self.sprite_type == SOFTWARE: s = SoftwareSprite(tsurface, free) return s def from_object(self, obj): """Creates a Sprite from an arbitrary object.""" if self.sprite_type == TEXTURE: rw = rwops.rw_from_object(obj) # TODO: support arbitrary objects. imgsurface = surface.SDL_LoadBMP_RW(rw, True) if not imgsurface: raise SDLError() s = self.from_surface(imgsurface.contents, True) elif self.sprite_type == SOFTWARE: rw = rwops.rw_from_object(obj) imgsurface = surface.SDL_LoadBMP_RW(rw, True) if not imgsurface: raise SDLError() s = SoftwareSprite(imgsurface.contents, True) return s def from_color(self, color, size, bpp=32, masks=None): """Creates a sprite with a certain color. """ color = convert_to_color(color) if masks: rmask, gmask, bmask, amask = masks else: rmask = gmask = bmask = amask = 0 sf = surface.SDL_CreateRGBSurface(0, size[0], size[1], bpp, rmask, gmask, bmask, amask) if not sf: raise SDLError() sf = sf.contents fmt = sf.format.contents if fmt.Amask != 0: # Target has an alpha mask c = pixels.SDL_MapRGBA(fmt, color.r, color.g, color.b, color.a) else: c = pixels.SDL_MapRGB(fmt, color.r, color.g, color.b) ret = surface.SDL_FillRect(sf, None, c) if ret == -1: raise SDLError() return self.from_surface(sf, True) def from_text(self, text, **kwargs): """Creates a Sprite from a string of text.""" args = self.default_args.copy() args.update(kwargs) fontmanager = args['fontmanager'] surface = fontmanager.render(text, **args) return self.from_surface(surface, free=True) def create_sprite(self, **kwargs): """Creates an empty Sprite. This will invoke create_software_sprite() or create_texture_sprite() with the passed arguments and the set default arguments. """ args = self.default_args.copy() args.update(kwargs) if self.sprite_type == TEXTURE: return self.create_texture_sprite(**args) else: return self.create_software_sprite(**args) def create_software_sprite(self, size, bpp=32, masks=None): """Creates a software sprite. A size tuple containing the width and height of the sprite and a bpp value, indicating the bits per pixel to be used, need to be provided. """ if masks: rmask, gmask, bmask, amask = masks else: rmask = gmask = bmask = amask = 0 imgsurface = surface.SDL_CreateRGBSurface(0, size[0], size[1], bpp, rmask, gmask, bmask, amask) if not imgsurface: raise SDLError() return SoftwareSprite(imgsurface.contents, True) def create_texture_sprite(self, renderer, size, pformat=pixels.SDL_PIXELFORMAT_RGBA8888, access=render.SDL_TEXTUREACCESS_STATIC): """Creates a texture sprite. A size tuple containing the width and height of the sprite needs to be provided. TextureSprite objects are assumed to be static by default, making it impossible to access their pixel buffer in favour for faster copy operations. If you need to update the pixel data frequently or want to use the texture as target for rendering operations, access can be set to the relevant SDL_TEXTUREACCESS_* flag. """ if isinstance(renderer, render.SDL_Renderer): sdlrenderer = renderer elif isinstance(renderer, Renderer): sdlrenderer = renderer.renderer else: raise TypeError("renderer must be a Renderer or SDL_Renderer") texture = render.SDL_CreateTexture(sdlrenderer, pformat, access, size[0], size[1]) if not texture: raise SDLError() return TextureSprite(texture.contents) class SpriteRenderSystem(System): """A rendering system for Sprite components. This is a base class for rendering systems capable of drawing and displaying Sprite-based objects. Inheriting classes need to implement the rendering capability by overriding the render() method. """ def __init__(self): super(SpriteRenderSystem, self).__init__() self.componenttypes = (Sprite,) self._sortfunc = lambda e: e.depth def render(self, sprites): """Renders the passed sprites. This is a no-op function and needs to be implemented by inheriting classes. """ pass def process(self, world, components): """Draws the passed SoftSprite objects on the Window's surface.""" self.render(sorted(components, key=self._sortfunc)) @property def sortfunc(self): """Sort function for the component processing order. The default sort order is based on the depth attribute of every sprite. Lower depth values will cause sprites to be drawn below sprites with higher depth values. """ return self._sortfunc @sortfunc.setter def sortfunc(self, value): """Sort function for the component processing order. The default sort order is based on the depth attribute of every sprite. Lower depth values will cause sprites to be drawn below sprites with higher depth values. """ if not callable(value): raise TypeError("sortfunc must be callable") self._sortfunc = value class SoftwareSpriteRenderSystem(SpriteRenderSystem): """A rendering system for SoftwareSprite components. The SoftwareSpriteRenderSystem class uses a Window as drawing device to display Sprite surfaces. It uses the Window's internal SDL surface as drawing context, so that GL operations, such as texture handling or using SDL renderers is not possible. """ def __init__(self, window): """Creates a new SoftwareSpriteRenderSystem for a specific Window.""" super(SoftwareSpriteRenderSystem, self).__init__() if isinstance(window, Window): self.window = window.window elif isinstance(window, video.SDL_Window): self.window = window else: raise TypeError("unsupported window type") surface = video.SDL_GetWindowSurface(self.window) if not surface: raise SDLError() self.surface = surface.contents self.componenttypes = (SoftwareSprite,) def render(self, sprites, x=None, y=None): """Draws the passed sprites (or sprite) on the Window's surface. x and y are optional arguments that can be used as relative drawing location for sprites. If set to None, the location information of the sprites are used. If set and sprites is an iterable, such as a list of SoftwareSprite objects, x and y are relative location values that will be added to each individual sprite's position. If sprites is a single SoftwareSprite, x and y denote the absolute position of the SoftwareSprite, if set. """ r = rect.SDL_Rect(0, 0, 0, 0) if isiterable(sprites): blit_surface = surface.SDL_BlitSurface imgsurface = self.surface x = x or 0 y = y or 0 for sp in sprites: r.x = x + sp.x r.y = y + sp.y blit_surface(sp.surface, None, imgsurface, r) else: r.x = sprites.x r.y = sprites.y if x is not None and y is not None: r.x = x r.y = y surface.SDL_BlitSurface(sprites.surface, None, self.surface, r) video.SDL_UpdateWindowSurface(self.window) class TextureSpriteRenderSystem(SpriteRenderSystem): """A rendering system for TextureSprite components. The TextureSpriteRenderSystem class uses a SDL_Renderer as drawing device to display TextureSprite objects. """ def __init__(self, target): """Creates a new TextureSpriteRenderSystem. target can be a Window, SDL_Window, Renderer or SDL_Renderer. If it is a Window or SDL_Window instance, a Renderer will be created to acquire the SDL_Renderer. """ super(TextureSpriteRenderSystem, self).__init__() if isinstance(target, (Window, video.SDL_Window)): # Create a Renderer for the window and use that one. target = Renderer(target) if isinstance(target, Renderer): self._renderer = target # Used to prevent GC sdlrenderer = target.renderer elif isinstance(target, render.SDL_Renderer): sdlrenderer = target else: raise TypeError("unsupported object type") self.sdlrenderer = sdlrenderer self.componenttypes = (TextureSprite,) def render(self, sprites, x=None, y=None): """Draws the passed sprites (or sprite). x and y are optional arguments that can be used as relative drawing location for sprites. If set to None, the location information of the sprites are used. If set and sprites is an iterable, such as a list of TextureSprite objects, x and y are relative location values that will be added to each individual sprite's position. If sprites is a single TextureSprite, x and y denote the absolute position of the TextureSprite, if set. """ r = rect.SDL_Rect(0, 0, 0, 0) if isiterable(sprites): rcopy = render.SDL_RenderCopy renderer = self.sdlrenderer x = x or 0 y = y or 0 for sp in sprites: r.x = x + sp.x r.y = y + sp.y r.w, r.h = sp.size if rcopy(renderer, sp.texture, None, r) == -1: raise SDLError() else: r.x = sprites.x r.y = sprites.y r.w, r.h = sprites.size if x is not None and y is not None: r.x = x r.y = y render.SDL_RenderCopy(self.sdlrenderer, sprites.texture, None, r) render.SDL_RenderPresent(self.sdlrenderer) PySDL2-0.9.3/sdl2/ext/surface.py0000644000000000000000000000144512327134741013104 0ustar """Surface manipulation.""" from ..surface import SDL_CreateRGBSurfaceFrom __all__ = ["subsurface"] def subsurface(surface, area): """Creates a surface from a part of another surface. The two surfaces share pixel data. The subsurface *must not* be used after its parent has been freed! """ surface_format = surface.format[0] subpixels = (surface.pixels + surface.pitch*area[1] + surface_format.BytesPerPixel*area[0]) return SDL_CreateRGBSurfaceFrom(subpixels, area[2], area[3], surface_format.BitsPerPixel, surface.pitch, surface_format.Rmask, surface_format.Gmask, surface_format.Bmask, surface_format.Amask)[0] PySDL2-0.9.3/sdl2/ext/window.py0000644000000000000000000000727312323025462012763 0ustar """Window routines to manage on-screen windows.""" from ctypes import c_int, byref from .compat import byteify, stringify from .common import SDLError from .. import video __all__ = ["Window"] class Window(object): """The Window class represents a visible on-screen object with an optional border and title text. It represents an area on the screen that can be accessed by the application for displaying graphics and receive and process user input. """ DEFAULTFLAGS = video.SDL_WINDOW_HIDDEN DEFAULTPOS = (video.SDL_WINDOWPOS_UNDEFINED, video.SDL_WINDOWPOS_UNDEFINED) def __init__(self, title, size, position=None, flags=None): """Creates a Window with a specific size and title. The position to show the Window at is undefined by default, letting the operating system or window manager pick the best location. The behaviour can be adjusted through the DEFAULTPOS class variable: Window.DEFAULTPOS = (10, 10) The created Window is hidden by default, which can be overriden at the time of creation by providing other SDL window flags through the flags parameter. The default flags for creating Window instances can be adjusted through the DEFAULTFLAGS class variable: Window.DEFAULTFLAGS = sdl2.video.SDL_WINDOW_SHOWN """ if position is None: position = self.DEFAULTPOS if flags is None: flags = self.DEFAULTFLAGS window = video.SDL_CreateWindow(byteify(title, "utf-8"), position[0], position[1], size[0], size[1], flags) if not window: raise SDLError() self.window = window.contents self._renderer = None # used by get_renderer() def __del__(self): """Releases the resources of the Window, implicitly destroying the underlying SDL2 window.""" if getattr(self, "window", None): video.SDL_DestroyWindow(self.window) self.window = None @property def title(self): """The title of the window.""" return stringify(video.SDL_GetWindowTitle(self.window), "utf-8") @title.setter def title(self, value): """The title of the window.""" video.SDL_SetWindowTitle(self.window, byteify(value, "utf-8")) @property def size(self): """The size of the window.""" w, h = c_int(), c_int() video.SDL_GetWindowSize(self.window, byref(w), byref(h)) return w.value, h.value def show(self): """Show the window on the display.""" video.SDL_ShowWindow(self.window) def hide(self): """Hides the window.""" video.SDL_HideWindow(self.window) def maximize(self): """Maximizes the window to the display's dimensions.""" video.SDL_MaximizeWindow(self.window) def minimize(self): """Minimizes the window to an iconified state in the system tray.""" video.SDL_MinimizeWindow(self.window) def refresh(self): """Refreshes the entire window surface. This only needs to be called, if a SDL_Surface was acquired via get_surface() and is used to display contents. """ video.SDL_UpdateWindowSurface(self.window) def get_surface(self): """Gets the SDL_Surface used by the Window to display 2D pixel data. Using this method will make the usage of GL operations, such as texture handling, or using SDL renderers impossible. """ sf = video.SDL_GetWindowSurface(self.window) if not sf: raise SDLError() return sf.contents PySDL2-0.9.3/sdl2/test/0000755000000000000000000000000012357043742011260 5ustar PySDL2-0.9.3/sdl2/test/resources/0000755000000000000000000000000012357043742013272 5ustar PySDL2-0.9.3/sdl2/test/resources/font.bmp0000644000000000000000000076150612260256443014754 0ustar BMF6(E666OOO𬬬XXX<<<ZZZ +++ SSSqqq000jjjLLLOOOMMM """---"""///MMM///NNN''''''JJJ jjj'''LLL---mmmjjjoooooo???]]]999 )))MMM '''JJJ$$$888444:::XXXBBBgggSSS000ooo???WWW777DDDAAA^^^lll>>>###!!!AAA+++!!!XXX999999EEEqqq```111qqqSSSJJJ777@@@  vvvSSS777999666yyy444LLL333VVV***999EEEVVV TTTcccddd!!!///~~~KKKxxx ,,,BBB:::VVVOOO$$$___]]] <<<KKK((([[[CCCbbbWWWEEEzzz)))OOO...DDD555444777 '''lll???GGGhhh///000wwwppp 444777333WWWRRRjjj ]]] BBB!!!ggg&&&(((222MMM:::HHHVVVRRR___RRRTTT UUUQQQooohhhRRRRRR ```ooo)))___ zzzQQQNNN---\\\xxx MMM AAA:::---YYY888VVVXXX)))((( DDDJJJ```ccc '''FFFLLLYYYqqq______```+++ ^^^^^^nnnYYY ***YYY777;;;aaa000 &&&TTT!!!sssGGGmmmfff!!!ȂXXX444 $$$YYYkkk@@@eee111 XXX<<< ...UUU{{{綶vvv'''@@@rrrhhhwwwOOO///qqq^^^ ۷]]]vvv"""oooFFF  >>>999 www888 )))fff|||"""111555###444---LLLXXX"""444222LLL777RRRUUULLLTTTuuuZZZeeeggg555<<<vvvyyy;;; }}}wwwyyyCCCvvvnnn&&&222 XXXkkkKKK777FFFsss===KKKyyyEEExxxsss555RRRWWW !!![[[OOO$$$___OOO'''xxx>>>###vvv뷷fff+++ 888---hhh---...DDD000yyywwwppp VVVJJJ(((***MMMTTT+++]]]+++uuu222MMM:::HHH000EEE```___RRR &&&)))WWWHHH222+++:::\\\xxxfffhhhߜwwwAAAkkk'''FFF///...666444XXX ***  ِLLL PPP+++aaa $$$  333YYYPPP '''@@@&&&&&&mmm///HHHZZZ"""]]]vvvXXXYYYyyyAAAYYY///555)))222KKK@@@'''III:::XXX iiikkk]]] <<<ooo222LLL777RRRnnn"""www888(((///!!!333WWW!!!___[[[bbbgggOOO%%%JJJ&&&vvvnnn&&&===QQQ666|||+++...ZZZtttRRR---VVVggg^^^hhhccc777FFF $$$^^^???NNNooo777'''UUUgggaaa ;;;aaa???cccmmm'''$$$iiiWWW !!![[[VVV^^^~~~000 +++cccnnnZZZ___"""QQQ킂TTT""" 888}}}SSS...---$$$}}}XXXlll{{{@@@FFFFFFfff)))UUU>>>BBBVVVKKK###qqq:::AAA<<<fffNNNQQQ333 ccc666III%%%ʀ+++%%%)))777$$$hhh///&&& ___EEE 888777)))+++{{{nnn"""666((('''---"""rrr___>>>cccccc---[[['''___???yyy]]]ooo```@@@HHH&&&444---888AAA(((aaaUUUfffXXXzzzaaahhh```ccc ---###,,,###---YYY    ;;;aaaȂXXX444   綶vvv&&&***,,,--- HHH222 ۸\\\^^^bbbggg;;;mmm%%% BBBPPP???DDD(((;;;{{{???444&&&sssiii]]],,,~~~KKKDDD$$$===pppHHH999uuuwwwxxxDDDEEESSS---::: :::<<<___]]]222EEE'''kkkKKK888qqqCCCsss555RRRKKK!!!gggCCC999񉉉777 iiiQQQ(((hhh󋋋999```CCCnnn'''%%%iii'''YYY lll'''***qqq777888tttUUULLLMMM;;;888ۂBBBHHHqqq777888tttHHHXXXoooJJJ 999 BBB---UUU555YYYaaaHHHXXX ]]]WWW +++nnn!!!lll ...kkk QQQGGGUUUWWW +++HHHDDDHHHQQQ xxx{{{[[[\\\}}}fffOOO HHH:::GGGQQQ(((%%%FFF /// FFFJJJAAA111eee,,,UUU555vvv===!!!222"""kkk;;;xxx"""{{{|||[[[ {{{~~~ZZZ999IIIeeejjj iiiwwwRRR}}}{{{|||DDDEEEWWW555iiiDDDEEE!!!""" AAA{{{\\\ ccc)))999rrr^^^!!!"""  iii888&&&EEEKKKDDDkkk...ooo111CCCOOOlll  XXX ,,,aaa ???111WWWhhh%%%:::BBB!!!@@@!!!^^^ ZZZNNN $$$ ))){{{dddmmm@@@xxxLLL  $$$ ggg000 )))ddd111<<< CCC///bbb::: 000999```yyy***111zzzNNNRRR{{{ &&&fffggg*** +++CCCkkk888kkkzzz:::DDD kkkwwwIII[[[ooo888^^^<<<$$$^^^444噙///TTT,,,999 ===HHHCCCppp+++666RRROOOHHHttt...NNNBBB;;;sssttt"""UUU!!! eeeccc}}}iiiAAATTTvvvSSSbbb```///??? """mmm%%%}}}UUUEEEOOO[[[EEE ###<<<bbbggg rrrPPPdddGGGKKK///qqqUUUWWW---LLLJJJqqq}}}'''mmmAAA---$$$000111555"""YYYiiiTTTfffbbb333JJJ111PPPօAAA HHH󀀀(((qqq___ۂBBBHHH߇EEE<<>>555222  GGGyyy!!! ~~~999JJJmmm{{{ vvv???AAAEEEiiiZZZ}}}kkkuuu{{{777VVV]]]cccBBBzzz &&&???UUU'''nnn !!! >>> CCC aaa}}}\\\nnnnnnAAACCCOOOlllSSSbbb```!!!DDD+++222PPP///ccc !!!@@@&&&AAAHHHSSSooo DDD  )))''' ---jjj򰰰nnn000ddd XXXCCCCCC### IIIKKK ]]]KKK888XXX  ***ڛ'''666 +++444DDD%%%zzz EEE  (((CCC333'''FFFڝ+++***--- ]]] gggDDDBBBSSSoooIIITTTrrr@@@''' ```FFFAAAMMM WWWJJJ000(((ccc YYYFFF $$$ [[[ooo RRRFFFAAA___QQQiiiCCC /// LLLAAAJJJCCC zzz%%%IIInnn)))444HHH FFF HHHhhhOOOjjjGGG!!!+++ @@@@@@ SSSJJJqqqDDD OOOJJJ]]] $$$ddd [[[OOO@@@ ;;;RRR NNNiiiEEESSSiii###{{{hhh 555III{{{===HHH---aaaقBBBHHH $$$OOOⅅAAAAAA%%%;;;uuu󠠠VVV((()))aaa&&&RRR훛WWW)))  !!!LLLzzz111 FFFIII\\\888aaa...xxxkkk ===444 ZZZ\\\fff&&&vvvXXX~~~@@@DDD???mmm###DDD999'''<<<III~~~III---ccc\\\777 ~~~RRR<<<555777qqqTTTNNN'''!!!666jjjKKKCCCccc{{{>>>ooo}}}tttBBB222zzzDDD+++mmmJJJ===&&& HHH333PPPSSS___OOO...{{{(((;;;###ȯLLL %%% OOOYYYLLL---OOOOOO000qqq $$$[[[OOO666+++~~~ppppppDDDWWWZZZ000<<<tttBBBUUU 444lll###___;;; RRRSSS AAA222oooqqq\\\222'''777XXX...!!!hhh777```+++RRRkkk  rrr444&&&sssiiiLLL;;; OOOkkkggg---___999444)))iiiUUU $$$VVVppp666 &&&[[[ @@@~~~ދJJJ  ***[[[===HHH |||333FFFccc%%% SSS[[[ ...{{{ 555555ZZZ ...ttt111JJJ;;; %%%dddDDD]]]... ttt///"""MMMFFF... UUU\\\yyy---GGG lllGGGJJJ<<>>PPP^^^)))(((NNN666WWWwww,,,wwwMMM;;; @@@kkkGGGccc&&&<<<YYY```&&&CCCYYY""" ttt%%%,,,bbb :::777---((( ~~~XXX333>>> |||))) nnntttfff|||(((666###888}}}ggg{{{"""gggWWW<<<555,,, ===ĐHHHtttnnnrrrooo999CCC888yyy!!!000;;;555...%%%AAAnnn PPP隚hhh,,,hhh oooyyyddd@@@ ,,, uuujjjoooIII>>>XXXQQQ333 &&&???PPP㡡...AAASSS000999WWW'''uuuwww FFF___ |||PPPDDD000Էbbb³&&&bbb```777ttt000777WWWKKKCCCdddeeeRRR:::{{{ggg999!!!{{{GGGhhhzzz;;;222 QQQggg???^^^JJJhhh111"""'''555333LLL...+++pppNNN::: ttt JJJfffrrrKKKCCC|||[[[eee999***~~~NNN444%%% cccbbbUUU666 444eeeaaa)))&&&$$$%%%...III:::HHH555hhh CCCyyy;;;'''xxx"""...dddBBBHHHQQQ %%%bbbuuu... TTT333kkk'''ppp+++  \\\󏏏===CCC{{{/// !!!aaaPySDL2-0.9.3/sdl2/test/resources/resources.tar.gz0000644000000000000000000000062012260256443016426 0ustar OO[O01aHL7M:X%%n#8q( nQ,r]NY'9D/WAMTOmKRL2 1J`nI+2B-e^&% xXxOdȴ[u cs5}^[T3z VW#Z,Hݏ ?;G[=_G?я~7煁~G?GAAA|(PySDL2-0.9.3/sdl2/test/resources/resources.zip0000644000000000000000000000135012260256443016024 0ustar PK L@ resources/UT OGOux PKL@Z&resources/rwopstest.txtUT OOux  @Ep`r:oy# op.yMv<`\6gyxYpH4lզ`ġ,qZb(\:Sg HMlDśr7II\⊢d :~PKL@7eIWFresources/surfacetest.bmpUT O{Oux su`7 b(f 07#0ÔI(`QGQG|/&heң?j?j?&PK L@ Aresources/UTOux PKL@Z&Dresources/rwopstest.txtUTOux PKL@7eIWFresources/surfacetest.bmpUTOux PK PySDL2-0.9.3/sdl2/test/resources/rwopstest.txt0000644000000000000000000000021612260256443016101 0ustar This is a test file for sdl2.rwops! DO NOT MODIFY ITS CONTENTS (NOT EVEN A BYTE), SINCE THE UNITTESTS ASSUME FIXED VALUES, RANGES AND SUCH! PySDL2-0.9.3/sdl2/test/resources/surfacetest.bmp0000644000000000000000000001006612260256443016322 0ustar BM66(    PySDL2-0.9.3/sdl2/test/resources/surfacetest.cur0000644000000000000000000000427612260256443016343 0ustar  ( @PySDL2-0.9.3/sdl2/test/resources/surfacetest.gif0000644000000000000000000000172312260256443016311 0ustar GIF89a !, (0(\Ç D!C%xB5cCD Y$ʔ"YRL(mY3N urPR$RVRjG& SMŠ t*رb^=ڭlѾmwܙmjk1۽x5wpݴ N|Xן>>pœF;PySDL2-0.9.3/sdl2/test/resources/surfacetest.ico0000644000000000000000000000427612260256443016324 0ustar  ( @PySDL2-0.9.3/sdl2/test/resources/surfacetest.jpg0000644000000000000000000000054612260256443016326 0ustar JFIFHHC   %# , #&')*)-0-(0%()(C   ((((((((((((((((((((((((((((((((((((((((((((((((((( " !ABDE ?:1LL&x ^me^ik4Z*m}E (:bMY3yyIх$Sk(dPySDL2-0.9.3/sdl2/test/resources/surfacetest.lbm0000755000000000000000000000607412260256443016325 0ustar FORM 4ILBMBMHD  CAMGBODY PySDL2-0.9.3/sdl2/test/resources/surfacetest.pbm0000644000000000000000000000024012260256443016313 0ustar P4 # Created by IrfanView 32 32 PySDL2-0.9.3/sdl2/test/resources/surfacetest.pcx0000644000000000000000000000124012260256443016330 0ustar HH PySDL2-0.9.3/sdl2/test/resources/surfacetest.pgm0000644000000000000000000000204412260256443016324 0ustar P5 # Created by IrfanView 32 32 255 MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMPySDL2-0.9.3/sdl2/test/resources/surfacetest.png0000644000000000000000000000021312260256443016321 0ustar PNG  IHDR  pHYs  =IDATx 0CѦtu=*ypmjlp乊$_HL[BP3IENDB`PySDL2-0.9.3/sdl2/test/resources/surfacetest.pnm0000644000000000000000000000601512260256443016335 0ustar P6 32 32 255 PySDL2-0.9.3/sdl2/test/resources/surfacetest.ppm0000644000000000000000000000604412260256443016341 0ustar P6 # Created by IrfanView 32 32 255 PySDL2-0.9.3/sdl2/test/resources/surfacetest.tga0000644000000000000000000000602212260256443016314 0ustar  PySDL2-0.9.3/sdl2/test/resources/surfacetest.tif0000644000000000000000000000634212260256443016330 0ustar II*    U   (1 HHIrfanViewPySDL2-0.9.3/sdl2/test/resources/surfacetest.webp0000644000000000000000000000015012260256443016472 0ustar RIFF`WEBPVP8 T* .i4Mr;X-sgP'h-Su ~ >?7>`PySDL2-0.9.3/sdl2/test/resources/surfacetest.xcf0000644000000000000000000000203612260256443016322 0ustar gimp xcf file BBgimp-image-grid(style solid) (fgcolor (color-rgba 0.000000 0.000000 0.000000 1.000000)) (bgcolor (color-rgba 1.000000 1.000000 1.000000 1.000000)) (xspacing 10.000000) (yspacing 10.000000) (spacing-unit inches) (xoffset 0.000000) (yoffset 0.000000) (offset-unit inches)   Background     2 F VPySDL2-0.9.3/sdl2/test/resources/surfacetest.xpm0000644000000000000000000000242312260256443016346 0ustar /* XPM */ static char * surfacetest_xpm[] = { "32 32 6 1", " c None", ". c #FF0000", "+ c #00FF00", "@ c #0000FF", "# c #FFFFFF", "$ c #000000", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@########", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$", "........++++++++@@@@@@@@$$$$$$$$"}; PySDL2-0.9.3/sdl2/test/resources/tuffy.copy.ttf0000644000000000000000000052044412260256443016125 0ustar FFTMW6[OS/2' `cmap% (l Jcvt e%feat@gaspglyf aP=<head6hhea T$hmtx+ˑrkern2Q0N4locaܷ%|maxp2x morx;gXname ]P ;postn^Z?propJ'GGJv_< 8x D 8e D @.A33f R PfEd = - Dhg5zhd~$)Z!~Ngbmg(pdppmfqpXpppophpqqKTBX\9X)HydyvyzySdytqyQyyy5\KyZ\My7-XyP(TJL-dr+~X&<TLIb}I((fI`f(xR^D5(xZZp}?5\5(P`TX?VJ1Z+L)mh;m^V1D3&<~yu1.b00/@@ R R R RlSxvyvyzzb 5\5\1f1f1fAl`yyL1\TT ^ ^ ^ ^TVblllxsRff&p&p$pwVx((x(@T@T@TdLdEdLdFyIbjvybvybvybvybvybSdISdISdISdIy*uuI{tqyz$yQwQyQyQyqQyyy$gnl5\f5\f5\f\fMyMyrMy 7-`7-`7-X7-`XfXfX4yxyxyxyxyyf(T^DLxL-dZ-dZ-dZ\^7-`Xf00jZZebbzb8essIR ((~(~p4=Xpnplibf70d:ppbb`Vff(22R^DRYZZZ$999e5\\ebf)7y`99ftff}"LBy%%&bL u?1A8byyygeeeq!LH_5:])NpHyKyxvy-dy5\y{yyn5\nKynXB_JrpNBZ(vpvZoRZi(vpdpZ(J(vR3Z(ZZZ(xv7JZ7_vZv7yopdT6 ~2Q5\Zd2ezyH([(v~N**Ky((s7-7-Zm4 2QZepdee1dyy dddJXJ8J?87-tq>EIyyE:HJ^JCJ\OJXLfqyyyxTyy5\yKydX_Jyby y(yKyd}yjZ\<^b^a(z(zyEbfZ(yeR(J0d5y(}}z 3eaubb(<^e`vH|X(y(z(J(yy(zKyKyJ\<^Jmg7c& /@"9T9Tg~y q>?Zd%dd01D3A0r02:-NF|Pj@<3jB01D3A0r02:-NF|Pj@<3T?T'Z*4B  u@Dd4*~nO$JA+)+L+9"yKyMyN1RH^L^3^A"2502X{D{\{Z{,JJ"JQydyyyyyyRHRRlRy555~e>y&dedBy&z0xxx4444xxxxxxxxxxxxxHH4xZoxxxxxJxxxxx U U HRvy^xxvvm|:nnz@DIb6OOyy\?B?Bhmhm|:|:p_pdpd^^"RR9fd99~zys:fe}}}d }}}}ppLppjpVpopvpTpTpvZZZZZZZZZZL&E(E("*wb>Lk*||www^N"xhtH^==R=d22cl}R`o vyB"4Bt-dNn4q,"O)"&#(TJx____,$ @, $z %(.1qv~_%+;IWcoEMWY[]}   ' 3 : = ? D I O S V [ ^ !!!!!!"!&!.!5!!!!""" " """" "+"4"<"E"H"a"e""""""#!#*%ʧG!Yh P #'.1pvz $*4@VZj HPY[]_    0 9 < ? B G K R V X ] p !!!!!!"!&!.!5!S!!!"""" """" "'"4"<"E"H"`"d""""""# #)%ʧFPha-WSPKJIHb\XVTRPONMLJIHFECB>;65-('&$"! pjc`5430/+)(" @9ߚ^$$e$\#.#    cBCEPK  #%'(..11pqvvz~_  $%"*+$4;&@I.VW8Zc:joDJPRSTVXn EtHMPWYY[[]]_}"58  A D  F  'M 0 3] 9 :a < =c ? ?e B Df G Ii K Ol R Sq V Vs X [t ] ^x p z   !!!!!!!!!!!"!"!&!&!.!.!5!5!S!!!!!!!0""5""6"" 8" " ="">""B""C" " H"'"+I"4"4N"<"<O"E"EP"H"HQ"`"aR"d"eT""V""Y""[""\""]""^# #!`#)#*b%%dFGegi!tPY~hh             !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abUrdeiWxpkvjRGsTUgw6@>Ml|cnCBQ9m}[IJQRMNd:habVyOS]qz!yDXXXX8\(4l <t\  H ` x l @p Ph@lX`$xLxt\(h DhxPh  "|"##|$ $`$%4%&L&'$'D'X(4(P(()*P*++++,,,-..///4/L/d/|///00,0D0\0t0001$1<1T1l11112|222223L4404H4`4x445566606H677D78x8888899|::0:H:`:x:;;,;D;\;t;;;;;<<<4d>|>>>>>? ?$?<?T?l??????@@,@D@AA,AABBB4BLBdB|BCCCDDDDEEE0EHEF0FHF`FFFGG(G@GXGpGH0HHHII,IDI\JKK,KDK\KtKKKKKLMlNNNOXOOPlPPQ Q$Q<QTQlQQQQQQRR,RDR\RtRRRRRSSSxST@U`V<WW(W8XXYZ Z[l\\]^_(_`xa,abcxceefghh|i,j jjkkl4lm0mntoXoppq\rTs0stt`tu(uvvxvwLxlxyz,{{D{||}@}h}}~~t`0hx\Dd< 4PXHXll $T(P|P4,x`$ @lHt $$$d`4Ld((X0LH d8xl@(8LX4p@ňżƸHȠɔtˤ̤ͼΌ\lP,Ҩph 88p$ܴݘݨݸ(d $TpH P@h88xP D08hx|Dp@pPTpttL\tH`x@p|l| ,<L\l ,<L\0`   $ 4 D T d t   d t  T    0   d 40pHH$<T(@P`L\ 8Phx     !"""""#X#$$ $h$% %t%&X&&&&'d($()$)*(*d**++,<,-..l../0001H112<2T2l22223,34`455 5l5566 6@6`6666677(7H7`777778808P8h888899909P9p9999:: :@:`:::::;;0;P;p;;;;<< <@<`<<<<<==(=H=h=====>>0>H>h>>>>?? ?@?`?????@@0@P@p@@@@AA A@A`AxAAAAABB B8BPBhBBBBBCC C@C`CCCCCDD0DPDpDDDDE EHEpEEEEFF0FPFpFFFFGG G@GXGxGGGGHH@HhHHHHHII,IDI\ItIIIIJ0JJKhL\L|LLLLMMM4MPMhMMMMMMNN,NLNdN|NNOXOPPQQ$QDQ\QtQQQQQRR,RSSTT T8TPThTTTTTU<UUUUUUUUUVV$V@VhV|VVVVVVWW8WWWXXY,Yp[]]l]^^@__````blcdeef$fXfglghijkklmxnn0noopq qDr rrss@sst@ttuvxvwLwx xyyyzzLz{ {|P|}$}h}~,~ Dt(<hdPp,htL LL`d@h(x\|DP p@$XXph 4\$P|XT0` <l,<4 ,LlT”TÔ@ĄdŜƀưǔX\Ʉɨʰ ̘̼pXϔ(8|Ѱ|X(\֠LtטTؤL$ܰ݀߸dd0LpT0H`P$pPP|PDpHplhldHpp @     X        t   L  Lx ,h8xDdU./<2<2/<2<23!%!!D $hUDgB #.546324632#"&'&#");'(=@,':?,':"!'77%-?1$,?0% ;&46;2#"&'4&%46;2#"&'&+'"+)"Dv$(v$( 5{!#!#!5!!5!3!3!!!\\Vii#RaaR{{e/8?3.' #5.'7.5467>54&ŁВ}#wKL'D%7$ ӴQ~fL- ;5O-S|k9ԝ]t7.54>32+'n_c[eaw|!Jg[ZL6RY(Ro_t3LLgiv4su]:Hy^P]; #u`lc46;2#"&'&+)"Dv$( ) &5473n{suTIUZ #654'3 tjyTJ]!y7#"'&54?"&5463'&547632763272#'#"'q+& 0*" (*om*( "*0 &+( (#)!)& (( &)!)#( (NB !3!!#!N34̍7Ɏ7g#>%'65"&'&54632>!8H':@,':^%M:?#*gK/% -?1$m3!!m[g>74632#"&'&g@,':?,':^-?1$,?0% T3#3͞d&4>32#"'&732>54'.#"dByo.mܓ."mPI&!kPL(ך|ڈ ڄxpms#73#F\Pm/'6$32!!4>7>54&#"'AxlP/*@:M3C *b`?u4PypG ?"=#-kdV7 GeY3bOO8>#,\ny/^\2*0%96F%q /?32654.+532654&+"'>32#"&q&S9_s=Nba_Py 5{euBN'&TM3}/RhIwK(}pdUI@i^mRM @]GX 3##!;!`^ }ts#V&"'!!632#"&'732654'.\!;1%$^B[# kч.T߄ ' KT7¤?>݉Ţ,'r)4'.#"326632#"&'&54>73oqiEI@! Bse /";N%gu!f~ɛ+3N~N͓*-:snDd Ho7 #!57նPh/@%2654'.#"32654'.#"2#"$'&54>7&'&546Fs`oewU# 3SQ) q" n&oVbqQa -n'l((w͠4,NY9V'0*32654'.#"#"&'&54>32#%qiI@! )PmQ 1A#fv"fɛ2->~pW3Γ,+:rr>mqH'  q#H&  T% 3 PdXBfbb!!!!B  \%# 3#eZ9&6#54>7>54&#"'>324632#"&'&=6(E,|RHV~K`6,@,':?,':-O7<#93(A'|Z|92`aG,W.-?1$,?0% )FV%# &54$32#"&'#"&'&5463232654'.#"32632654'.#"M^7`Ј6Tb-7x(,OzȎv R38f osc.[]uKZmqBTfWRP_]wC@K^89+54'.#32>54'.#"&'!2#2#!?FqK4S}F+ %HU˱vo? WHvK- *KcZ#!7KR,#^ud'!0C9#<9!4Ye:*#u5X^3$$"BWKL5!d)#".54>32.+"3267Lp_wȋa-.awLbN1hhi87#!!2*JcUi0ODOAs[4jTχpzy !!!!!!y0gy !!!!#y0\d-".54>32.#"32>5!5!#P-bwI:jgi99igFvP53#"&'&q o\Fͥ&45}ggGy 33 ##yxϼsy3!!yeݍy 33 3##yϙTT!P\Ly 333#y䝑wPZ\34'.#"32>%4>32#".'&H=^V]\==^U]\>&Z{yƆV'Z{xƆVvmStAPVokRq@MzUeΞc\ltmdʚ`Zkjy 3 4'.+';2+# ,SbΞ BՊΞ#)E?#-(WsB\94'.#"3267'764>32'#".'&PAaVde5=a[6{"Xg ([yb|b=U?ZLnd}b=rjVuAi{mdRvC)"teΞc?hVokRyu54&+ ##;2^R2Sמ3Ʀ"5LF(|wx- 9732654.'.54632.#"#"&-s,G>Y7S,=S73)ps..O8b0JaF@!ۋGWr)L::&+ 1:Ld<êHq|^)C5''& &;FYrBTX!!#!XD7##y3#"$'&5332>5-#zKe9g+rV?~ЇP3#3GBPT 333# #T+P3J 3 3 # #Jjc;˾^)'JLd3 3#LddBX<d!!!!Pliݍ#!!#3u`Z\!31 53#5!`@}5#'#35}VX5!XB獍<.#"'%&'&54767632       TbB )"32654&'254&#"'632#=#"&546ol`{h uEz"NۋgFcgcfm1`+"hm{1Χ">32#".'#&"320Fd>e\..\f>dF-蠠ts-GA#]poŤ`#@E-LlF.#"32>7#"&54>32xF+O6! z6qu(PmTr6)2c#60MZ~Vj=zaI 3#5#".54>3232654&"*we\..\e>dF0stRat`npš]#AG-pbF"!.#"3267#".>32 pLw<[e I }##5354>32.#"3;X`':M+m((9V325332654&"FsM[e<\h-Fd>RZ>.\e>dF0Lstck;Agt8Wu!-E@#@lXpš]#AG-p!#3>32#4.#"qɗ32>32#4.#"V+K3ژ/1L.tm+A+#HnrK/a1&/@$ihs;^dH<gN!#3>32#4.#"qɗ32#".732>54.#"f9kia_Ɍa BoJIoB 7ab7wʗUZyDDyZyuuTN">32#".'#&"320Fd>e\..\f>dF-蠠ts1-GA#]poŤ`#@E-"I? N *3"&=#".54>325332654&"4BEON0d[..\e>dF0Lst=5u͸?V-anpš]#AG-pN&#"#3>32P1>Y{5qR*xw1Yy`HJ:.54672&#" #"&'732654.+ȔQR0 6Pu")( ?"?%6!&ؗ&h\et&G? :Ab;-JG%zOG$  " .0="pCH`U(@-fP+#53533#;#"&5􎎗uFFx-uox13#5#"332>5qɗ=#"332>53L{MՖjg1^R2qɗ&67>7&#"327.'&'&'&Z@T! ,:F'+Z <.<"Y,'F:, (f}w"  P-M+>   " '@W} 33}R=532676=4>7&'&=4'&'.#"5@T! ,:F',Y <.?"Z+'F:, 'i|"  T+Q-9  " %R?3\&>3232>7#"."?%&&800:&-92 *% ?403,'-8 -, ,(  -- 0\I\#5476767676767>7>?>767>767>767654&#"'6763247632#"'&'&4'&'&'&'&#"3276767676%47676767632#"'&'&'&'&n $ lW;/12f VVvQEF,.- | 0.FCX^//!0.GFT^IK-- ! ,+C@ge{zbdBA-,,/?CefzxcbDA-+%cf       W` V(sNN@BYD42-  spOIC<9" P@?UTUrhKJA;9 '(;753&#"327#}k 8]`4cdZPkU~pPRZ< w,9L|M. W_Pz[!&S]jZ`4T''#5332.#"!!!>7!>7j^I: g ^.PF62 ; TBTktFdQ}N! s ' *?w-w132654'.#""'#53&'&547#536253#3# cAKi bALidPP+;yPPy&B>QjK>Qj779F$gQ{77{4B%hWJu!5!3 33!!!#!5!DX1Ϙ7D6ׇLZ#53鏏{z+h,;632#"&'7;26754"#"&'&54>32.+"4'.#";2& ];S Ga - " N[avFF^!Q% Ö0,Wd #pX 7:nxH\S{QL4!4632#"'&'&%4632#"'&'&#8&"28& )8&"28& &8*! '8!&8*! '8!)7(8#"&'&54632&"327%32654'.#"432#"&'&uCSJqyV[;N"L84!.sssu bC\GUy;R8& ,D%o'nŖ2)Ŗ+mm 2"3264'&#"'&547632&'&#"'7632#L0:0(:;Y;:<=V:+0AI\[=54'.#"4>32#".'&%32>54&5.+'32#'# Qlv;DtH Vpu5EtGu?gE& kʡ 3"/0]KRRq -dAR2,JuG$5aZ.(KzH&1^_ftR&߰96}U{8q "N:> ,a)!![)j1=32654'.#"4632#"&'& N4=S N4=Svm^m^3AW?3BXBktY ltY'HPDPB'767632!!5476767676?>?4&#"ʆ JIX&D !.   ( _ !. <&( #5O87:,-0 ,#406 '!"!5<.3S>7327654'&'&'&+5327654&+"'767632#"&'3 < 8&% JT"4"  9:H885##QRtHs+!(!!6($2 > >%%65A1)'&$-rIJXJ<.%632#"'&'&5476L      ufh%#332>53#5#".) $.N5%.u:+'" #J+6L8'@QQ&b9D$yu,23"3"&#.'&54>;0GM*$)A/%=^^A0 s  !!6O2!5!   ,7O1*)b`3neE'{uqJ>54'.'7u' @8*J  "  #8>H 81,1@#73#{a.(:-&327654'&'&#"47632#"'&'& ('4<** ('4<**vLLn_LNl_GF/1"!+,?2"!,+ClKKtYlKL:9Zb;^ #!#^"#"#0 %3##5!335#73##3v^^Wc{a) W6N0BHL%'767632!!5476767676?>?4&#"#73##3N JIX&D !.   ( _ !. <&( #g{a)5O87:,-0 ,#406 '!"!5<. /=GJN732654'&'&'&+5327654&+"'767632#"&'3##5!335#3/ < 9J JT"4"  9:H885##QRtH7^^Wc)s+!(B6($2 > >%%65A1)'&$-rIJXJW6}"{@&$C@&$vRq'A$ RJ'a$ R'j$ R'rf1$ Sg!#!!!!!!53OFF{JxX'z&y&(Cy&(vZ'A( 'j( 7&,CTH&, vhIf'A, 9'jZ, #53!2+324'.+!F}82⛝(,bhE^S5'a+1 \&2C\&2vfs'A2 fJ'a32 f'j2 lJ7,-c,`,9%#7&'&54>3273#"'32>54'&' &#"J|/6[xczaE55\wc5VoYZ=#OIXYZ<)FokRvD2EmtRsB;LzTtod`&O}Txdy&8Cy&8vw'A8 'j8 Ld&<v 2>54'&!3 ##/WlC.E7gc&;b@&(SX>!\]F>32!"'732>54'.+"5;2>54'&#" #67,DXQ'+^eNPj[ ( ?d_?&$*Y)JsO3!  +, 8cF:" ,GnA'h5{ $;`@o;xJ'%#CP7bzY Tb=&DCTb=&DvO^l&AD ^l'ayLD ^l'j^D ^lV'rD T`F`j"32654'.>32!32>7>7#".' #"&'&546326&74'&#"'>32!&'&#"i_"\mf:zd!aV!.'8m'@5$, %'3 ȘWR$ "AP'N& %'"0^t /:X/Zl1$h(Ob4_Y^} - IG]~+&7nk 9 %*% 7035,6+&'f  YsG9BmuV]vF'z F b=&HCzl=&H vcl&A5H l'jH /=3##"'%&'&54767632     11  ;=3#%632#"'&'&5476    11  s# 3##'#31^Vb%3#4632#"'&'&%4632#"'&'&8&"28& )8&"28& 1&8*! '8!&8*! '8!R>32654'.#"#"&'&54324'.''7&#"'6327 Iqg;h9C ݠ)G/30 h8cGY)J7`.2u׆%sjMo$!B&ҸHP$. !(^1dFm'aXQ f<&RCRf=&Rvp&A3R p'a/R p'jR w[#4632#"&'&4632#"&'&!!X@,':?,':@,':?,':[-?1$,?0% 3-?1$,?0% VJ 1 32>54'&'&#"7&'&54>3273#"'ATEj< ZASAh>! s7__1q9_c0DNNVD2?L{LWG+%YwZVKOZuQ\NNx=&XCe=&X*v&A1/X 'jX x?=&\v\,!#3>32#"./4'.#"326/DU4":[^.S6( fD5hU5Jr)54ȢXeZkA,+]Rp3232654&" '2(e*we\..\e>dF0st$#$ Q>& # Rat`npš]#AG-pj##53!2+324'&'&+! |ݝ2KL⚝(ts+ia˥_`F^SooR:327654'&"33##5#"'&'.'&547>32#53MLtuOPPOLL"#2/BPEB.,@ ^f?15 &vttvtsrq˅e*&"  75PTUne`\$ $,%y'q[(b)&qHy.&(b'|Hy'(b'DHy'(bF'HyB&b(b'HdB'*I?'Jd.&*I?'xJd'*I?'dJd?'*I?1'lgJyJB&O+B&K*3!33##!##53!!y88kOO3kf7^ff*!##5353!!67632#4'&'.#"ccPQsRBE02fDF23"[;323276767"'&'&'&'&#"F% # !1 !#B"$B1W  &   /'q,C(3#!![1(j.'S,&F|uq&,uq&LC&;,#13#1!%#"'&'&'&=33276767653٘3rRBE0/fDF23"Yg'ZOy'65"&'&547632%3!! '2(e$#$ Q>& #ݍ&'65"&'&5476323"&'&53 '2(dq$#$ Q>& #. KJY% y'y/'y8O ?37!!g}~eh ~}e?373"&'&5ldqmy  KJY#"y'v1:'vDQ y?'v1?N'BQyB&t1'Qg1'gQn6%276=4'&'.#"#367632#0#6gJIfD*b<`w1yqySBC14$HAAPA/JI!_FL:;B"9HKz\F0!"BGhl:DD< l?N3276=4'&'.#"#367632+6gJIfDF25 PQsRBE02#JA@PAJI!ZKO7;B"$9>IKX1[;CE= \'q2f,&qR\.&2f'R\&2f='jR\"=47676767632!!!!!!#"'&'&'&'&.'&#"327\,+C@ge{'<4_T^xcbDA-+ CX^//!0.GFTfAgehfdRO21'--NK_[lm/ P@?UTUrhKJA;9 'fvFJR2?&'&54767&#"476767632632!32767#"'#"'&'&%!.#" 977115Qc@A47STib^_QO214d::MJEF 4gju|_bef00t pKx<\JO:;#"".={>(#:;[_vychIM)*FF.-KJc 1_QO66&'<7d:;GGMN}~lyP'v5='vUy?P'65r?N' UyPB&5 'hU - 'vl6`H='v#V- B&6`J'V-] Zw732654'&'&'&'&'&'&/&'&'&'&'&'&'&547632&'&#"#"'&6767>54'&'&'7-s#$!*0>8!.+  zyyz(USqs * 5>!'2* $!DEmn|z? ' '(GWr)&+  #$%)+5baUVH98|^$   ($'%j6Z[**ba4 876767654'&'&'7C#'4/""deQ)/ 6P;: '( (  lk\_%44\dt"%!  ? -'$#.1;KL,&,$%z''H&    )ZYCEnC$$`U+"   "8& # -uoX!!!!#!5!!XD7YD#:[4+#53533#3#;#"'&5#53􎎗uFF;<u78gyF'8x'\Xy'qt8x'&q Xy.&8x'vXy'8x0'$Xy&8<'X*y'8f1'QXTB':D1'ZLdB&=<x?'\Ld&<jd'v=Z='v]]d'=Z'b]dB'=Z']5476767632&'&'&#"#,+1/(:'%,m ':1>34#")i 4- ##737676767632&/"3V11)-83A.().\(32@1VA@E50  ('&.\r!!!#!!!!!!53\EQGGWzJ^l7V_!!"327654'&'&6763 !32767#"'&'#"'&'&54762'4'&#"'67632!&'&#"]"|6m PX4= P-R- P`3DU+7D_ ]< "jHMU&;PeC .37",*}9B"## 3"cxDHGI.5)gCbD2:43pNJ <2.GgF I6H-  P'65"&'&54632732654.'.54632.#"#"&~!8H':@,':s,G>Y7S,=S73)ps..O8b0JaF@!ۋ%M:?#*gK/% -?1$Wr)L::&+ 1:Ld<êHq|^)C5''& &;FYrBT`HJQ'65"&'&54632.54672&#" #"&'732654.A!8H':@,':l+ȔQR0 6Pu")( ?"?%6!&ؗ&h\et&G?%M:?#*gK/% -?1$ :Ab;-JG%zOG$  " .0="pCH`U(@-X,$fP+%0 qF676767654'&'&'&#"57>54'&#"'6767632ucm^P/-;&M`_I:D M=<5bdw$"?8Z::!"%.?6&F)Vju0Cr8C$7674654'&'&'&#"5767654'&#"'6767632w& /-; #M`^HGI8FM=<5bdw$"?8Y;:!!&.06%L>6;&(@7  ~YXqd=. 76O)tRSRQmTNM.6 9K90 p\YjxB52654'&#""'&'32767#"&=3676767632pHGm`FGIJzhLL tD>=#Nڋ%!537hjmkߊdgDCEEdgCD653`#hm{"ghkjZxB-7&/054763253#5#"32765&'&#"knf !537X@B`HF=?vF36!=YqtmWFϜ!ORFE`:LN!LZxB-%#"'&'&'&'#36320&'&'&#"32765 w735!#fm=!63Fv?=GH_B?Yv 1FWmsˑL!NL`EFRN7G"'&55476767632#.#"67>7632#4'&#"3276wm##94NHM]LP20 \iB42>QEB., /-dMLtuOPPOutLMvqbTS62  "20>99Xt!'(%< 74LJPTTmecQO^8srstvttveF/'67632#"'&'&'&'732654&#"5VUsTJH86)(;:jh=57)2 z +'+E=<)B`>=74HFRSTML '%(Mõ22ZF<J&'&#"67672>32#"'&''67&'&5476767676323276=&'&#<=E5S.9M + 7"`[\72 TI327654'&"33?#"'&'&'&'&5#"'&'.'&547>32MLtuOPPOLLfk$#$*"("(#"#2/BPEB.,@ ^f?15 &vttvtsrql{ f"  $ 24?C*&"  75PTUne`\$ $,I327654'&"/"#5#"'&'.'&547>3247676767632MLtuOPPOLLkf"#2/BPEB.,@ ^f?15 &#("("*$#vttvtsrqf {*&"  75PTUne`\$ $,S?42 $  bF-.#"!546546767632#"'&'7327676rNIFG4gju_`0112_aaOM42͑hi65PN_j'';7d:;LL{~IJ-,NK]_c!0b`F'96327#"'&'&'&54&='&#"3276767654'&ju_rl# 012_aaOM42$9NIFn FGoK<;! ;LdF6 {~IJ-,NK]_c!005'1hi65PUR>_kJ=%#"&547676?&'&'&54767632.+";#"3267k+fee%;T(*- -3CINcMO)d`:A&H=;IH9/("+(IKg?xf==/1"7* &F33247676767632/" MLtuOPPOutLM#":8JFO[NP21 [i##2/AQEB.,@ ^f>25 &#&%) *$#$kfvttvtsrs bTQ75!"21<99Vv!*&"  75PTUne`\$ $,S?42 #  "f {s?N;K#"'&'&'&'3326=#"'&'.'&547>3253327654'&#"#":8JFO[NP21 [i##2/AQEB.,@ ^f>25 &LMLtuOPPOutLMbTQ75!"21<99Vv!*&"  75PTUne`\$ $,vttvtsrsICE"'&'&'&547676767632&'&#"32767676765!5!+hSV57%&03IHXvIH7e*1.PJ?<)&%&97L.61+ .(tA.0LObekOJKKN48""++UW:*(GAQP&ROR?A  )K.%o93=.6,('"(R102I0+&#"&"'&'.'&'&'&'&'&'&5476=673 3'&'32676750)(5      Rbw67    Y07 3C !1n,"X . B TE %276547#"&#&'&576733C8 $!  _ '*2 o'Oqor 1 !$3%U38i0F,#JN!3##"'&'&'&53327676765$rSBC14fDE27NP4Zx!"BGhl_FL:;B"%8:MPS~9!#5476767632#.#"67632#4'&'.#"#";5LHM^42\hOA PQsRBE02fDF23"1bTQ82 @42<99XtI;b[;46    f  {ZKO7;B"#:AFKX4632#"'&'&33###53y8&!8&!5&8! &8!:4V#533?#"'&'&'&'&5Sfk$#$* )%&${ f"  #!13@=2 3!53#5!7Y]]Sꎎ+.3276?#"';#"'&5/"56767632:%$<2 !""!uFF;<0$! *!#%#+.& u78 !X&1%3"&'&5#"'&'&=476736767'3dq$ -8!<ڗ)-mHS7W'%# KJY#"26P7/&_`;(:+(*(h33276767#"'&'&'&5:' m/"%<&14(,-4 i, #43>ntL 3%3"&'&53!5!#"'&'7327654'&'&'dqT$!/7&}~8%POS_`019 KJY#"9  C.BAHāLK/Q54UVJ;:&'N53323#5#"'&'#"&5332 ,H5ژ ($0tJKm *B+NN1=37N.&϶+! DEih;/6+8$<N63323#5#"'&'#"&5332 ,H5ژ ($0tJKm *B+NN1=37N.&5+! DEih;/6+8$<TNN!#4'&'.#"#3>7676767632>32#"'&'&'72=4'&'&'.#"V ,H5ژ ($0tJKm#&%) *$#$kf *B+#N1=37N.a1*! DEihs?42 #  "f {;/6+8$<g>IN5!#3>32#4'&'&'&#"+6726=sRBC1443CF25 $H?CP@f1Zx!"BGhl_FO7:"!"$9>IPS%A :ED; |!l?N6%330#"'&'&'&5054'&'.#"#367632IJgAPAAH#fDF25 PQsRBE02BB!IJ| 
ZKO7;B"$9>IKX1[;(#:;[_vychIM)*FF.-KJc 1_QO66&'<7d:;GGMN}~l7H$H%#"'&5476763!2#"'&'&'&"2767653367675&'&'&#a ! 3/7`112_a a_210`6/3 !Kx<?8!B& } &A!8?:X>=QSpR$<;^]wϵ[;<?32767653#5#"P1>X>=QSpR$<;^]w3[;<UF*?327676533?#"'&'&'&'&5#"P1>X>9fk  $*!"('#!QSpR$<7bQ{  f    64>\[;<N&#"#367632P1>X>=QSpR*<;^]wg[;<TO.&#"3?#"'&'&'&'&=367632P1>X><fk$#$* )%&#QToR+<:_W}{ f"  # 24?"Z;=V747676767632/"3!5"!*) !*$  kfxt?35   f  {V%3!534#'6767632xtxfk  $*!"('# {  f    65=bN'3276767>54&+ ##;2b@93 bpHG{=5 4[h@3'lQP'bN' 327654&'&'&'&#3+33bDC 35DG|FHpqpu54[4 5'OQlOP'4`THJe&'&'&'&'&547672&#" #"'3?#"'&'&'&'&='7327654'&'&'&>'*2/""deR), 6Qt  112-+$lkXfk$#$*"("(#45[e::"'$#.1;KL,&)$%zNH& !'/6AZY3{ f"  $ 24? C$$00U)" h,476767632&'&'&#"#"&'732765,+1/(:'%,m ':<+(41&;J-m (>34#")i 4-32:' m/"%<&14(,( m+N9(/1V<$,-4 i, #43>. i(*DjVh7H476767632&'&'&#"2632&##"'&'&'&5476767673276=,+1/(:'%,m ':# _p<+(41&;%U+; 5=>K*(vX=>34#")i 4-wHPS2D2#5!326767654'&/5!# &'&54767գ~ $A"!nKIn!"#9D~)1`de014!;[_v\JL=o% 26P &uE/ ,bt2& !5!#"'&'7327654'&'&'KT$!/7&}~8%POS_a035l9  C.BCFāLK/Q54UVH=:&($27F !5!&'#"'&'&5054767632654'&'&'327&'&#"HT$!/7&bCYHVNa(!!5- M9V4019OStWrr "'$l9  C.BAHtCb`gSbL"C: P65 -g IhJ;:&'42$ +*)# .,!&}EDZ|9oo^`aIP9..>96/&'&'&5467676324'&'&#" # &1=(:)%J@>OLXyy$$FER~KM 56 S>..9PIab1/oo9>=.-DE}&!,. #&*+94#"'&'732765/ &'&'&'&53= $2>(;(%L|OLX{y$$S|MM 47 T=-09OIb`^po:=>ZEE|&!--)*+ekF@&'&#"327676767#"'&'&'05<&454767676767632<=EZXRX+'+ z 2)75=hj:/ ()68HJTsUV5)122xt* `nvM(%' LMiD[JA;RFH47=>`\%M_4'&'&'&'&#"3276767676%47676767632#"'&'&'&'&%"'&547>32H 0.FCX^//!0.GFT^IK-- ! ,+C@ge{zbdBA-,,/?CefzxcbDA-+6776Z..,+spOIC<9" P@?UTUrhKJA;9 '(;L756($.!/1ZZxZD>+,V43W-%  eJ'J%#0#"&547676?&'&'&54767632;#"32767654'&#"h%;U(*- -3CINMSH86)(;:=;IH9/("+*fAT(&C3X[ZE=/L/1"7* "J346    f  {x7:('56PQf03) 9K4632#"'&&'#"'&'&'&'&=476763232=&'&#"8&&8&&Hg#("("*$#$5!!5- M9 Y'f); "'$5&8(&8o`^2 $  "/P0P65 PAK {F  47b1 373##3{jgh{RhybF3!!yKFG`?O327654'&"3"'&=#"'&'&'&547>32567676767632/"MLtuOPPOLLBFE4KIebPM.0^f?15 &#("("*$#$kfvttvtsrqV;;:͸w0.1/SV^elne`\$ $,$2 $  "f {}9;!5!54767676? 4'&#"'67632!!#? 74 MK~SHyzXLO|L%): >2$ _(C+*)# .,!&}EDZ|9oo^`aIP9..>S?9>#!5!5/&'&'&5467676324'&'&#" !=_ &1=$:)%J@>OLXyy$$FER~KM 56 ?((?S>..9PIab1/oo9>=.-DE}&!,. #&*+C;327654'&"3!5!!!+5#"'&'.'&547>32MLtuOPPOLL {"#2/BPEB.,@ ^f?15 &vttvtsrqt\*&"  75PTUne`\$ $,tY327654'&"3!#"'&'7327654'&'&/!#5#"'&'.'&547>32MLtuOPPOLL$!/7&}~8%POS_a035T/"#2/BPEB.,@ ^f?15 &vttvtsrq  C.BCFāLK/Q54UVH=:&(9[*&"  75PTUne`\$ $,lR^327654'&"3!5!3676767632!'7+5#"'&'.'&547>32!6=&'&#MLtuOPPOLL'e@'E9M -8!o% 26P2T!8\`4*&"  75PTUne`\$ $,53 ,bf+6T#5353!672&#" #!"'&52767654'&'&'&'&'&'&'&'&547#􎎗BTR), 6Qt  112-+$lkӕ;<A^:"'/&?*2/""_,&)$%zNH& !'/6AZY78q.i)"  $#.1;I8-pfhK@#535335476767632&'&'&#"#"&'732765#;#"'&5􎎗,+1/(:'%,m ':<+(41&;J-m (uFF;<>34#")i 4-32&'&#"67672632#"'&'#"'&53276505&'&#􎎗uF(P:(*48UrUW5<=EZ[7;E?G+ 8!32+67276=4'&'.#"#,+1/(:'%,m ':[rSBC14#JA@PAgJIfDE27V>34#")i 4-Zx!"BGhl >CE= |JI!_FL:;B"%8:MPSO337327654'&'&'&'&'&'&'&'&547672&#" #"'&'45[e::"'/>'*2/""deR), 6Qt  112-+$lk\P'+C$$00U)" $#.1;KL,&)$%zNH& !'/6AZYC9Y 33!!d\ B #333##333#Xrqs\Xrqs\z$ciz%ciyJ!#!#!#!#yўkўkvv%N@6767632#32767676=53#5#"'&'&'&=354#%$#$*"("(# fDF23"PQsRBE00f"  $ 24?09O7;B"#:AFKX`=+[;323276767#"'&'&'&'&#"?F% 8 " !1 !"" "$B  &   p+632#"'&'&54%632#"'&'&54$$;:!  :!  Ax"&54763#"'Q "! "8j632#"'&547&# !. GA/167676763223276?+"'&'&'&#"#1 $&(2 #",, 7  %/#&"AT t'  #! *F  8)q3276?3#"&'&'I Ll;23)6KMbX94"!s;:Z6M)*HH@b^b47632#"/&9>:>> 8 >7=d#47632#"/&%47632#"/&9>9>(:?:>> 8 >7> 8 >7)32765054'&'&#"47632#"'&'&LW(OW(uoFQN"oFRL"TN'! RN#(N/o.0L/o.0jQ$&h?&#5b^47632#"/&9>:>>7 > 8=^#47632#"/&%47632#"/&9>9>(:?:>>7 > 8 >7 > 8x})32765054'&'&#"47632#"'&'&LW(OW(uoFQN"oFRL"TN'! RN#)N/o.0M/o.0J654'&'7^4@DE$I8>G \U)J&'&'&54?^4?D3E$I8>H  \U)bt676730"'&'&=37#;EPB#ECCE#BQ1N&*z Do9(&&(9oD p4u!!]y3 30!0!#y^y32 30!0!#y2>y !##33Zwg>74632#"'&'&g@,' ,'^,@$ , $ eF/'67632#"'&'&'&'732654#"e5VUsTJH86)(;:jh=57)2 z +'+~`27H#`>=74HFRSTML '%(Mö)+eF/B&'&#"327676767#"'&'&5476767676324632#"'&'& 72`~İ+'+ z 2)75=hj:;()68HJTsUV5R@,( ,'H9+)M(%' LMTSRFH47=>`,@$ , $ eF'qRH)676#0#&'0'&47632#"'&'& 0   -&<@+'y)   - 2# +@$ w67632+&'0'&  0 )   Lv&jOH %!!#3#67632+&/&%    0 P)   _w6N4632#"'&'&_@,' ,',@$ , $ v &!!!!!!67632+&/&0g  0 )    &3!3#!#67632+&/&۞k  0  P^)   }3367632+&/&  0  P)   :%Mh4'&'&'&'&#"3276767676%47676767632#"'&'&'&'&67632+&/&H 0.FCX^//!0.GFT^IK-- ! ,+C@ge{zbdBA-,,/?CefzxcbDA-+"  0 spOIC<9" P@?UTUrhKJA;9 '(;4HA<63$$9;JLL,! ,-A?hfzycdX  ,.@C{wBA-+ #>  /-HFT\-,! <  0-GCX^II/0 J 3 3 # #Jjc;˾^)'Jp/367676767653#&'&'&'&'&5!0-H$,8*J.- ! ,/?CeEVJGbDA-+rhLJA;7!Q '=L<'fA\JL=;!"'#632767654'&#" 2327676767654'&'&+"1} g{|!%).')&+//25%%DY 4*\W[@A*#z)2"H (5*73|~$'RT-* :03!% #%54D)h'_<32#4'&'&'&#"sRBC1443CF25 1Zx!"BGhlW_FO7:"!"$9>IPSd'647>7632#"'&'&%!32767676%!&'&'&#"d!!x]\orr.76nnts/"IImO@A#% t!FGkNB@&( כ?>؋̭jiڂOd[dc89Z]hA`bab:9]bf=V233?#"'&'&'&'&5fk$#$* )%&$2{ f"  #!13@Z5 33 ##Z0H0PkJ 3'&#'67676303# Rl^3k$#$, + )%& Þ1 f"  # nvu2#%#3303276767653#5#"'&'&'& '4! ,=;u,<=J+lL8@)&#/(&b8#" R^!374# H86)(1wj74HFRST3tD%27630320#&'&#0#"547676767&'&'&54767#5!#;#"jG`B122vyZF1326767654'&'&#"47676763!# &'&"!nKIn!"A@bd@A48QTj 3 1`de01\JL=Lyo#\32767654'&#"327654'&'&+567>;"##"'&'&'4&46 4*\W[@A*#z))z#*A?\ZY* !1} g{|!%).')&&&)'.)% |{g ~XY1" 8<7632#"'&'&%!32767676%!&'&'&#"d!!x]\orr.76nnts/"IImO@A#% t!FGkNB@&( כ?>؋̭jiڂOd[dc89Z]hA`bab:9]bf=2 #&#'67676303 676767032/"5k$#$, +,J$$J,+ ,$#$k8& f"  08680  "f 6'>p&jJ~t )#&'&54767367654'&~zz/:voTpoSjTppQbؘ|~z֘z /DTpoS(RppQH$H%#"'&54767#5!2#"'&'&'&!"2767653367675&'&'&a ! 3/7`11!/a_210`6/3 !}Kx<?8!B& } &A!8?:<*$#{Q8JI~{#$*lZ_QO6*s$%(%$t)6OQ_ZNO56Qt3654'&'&'&'503;2#&'�#"'&'#( 3MHE!\.+'BI9uZKnyl{%N WRӁ<fM <#t#X5n\t*P47676767632#&'&'&'&'&%4'&'&'&'&#"3276767676\,+C@ge{zbdBA-,,/?CeKSO@bDA-+ 0.FCX^//!0.GFT^IK-- ! gehfdRO21./NLa]ltmbghbiIM0# t -NK_[lmlspOIC<9" P@?UTUrhKJA;9 '(;`y !!!!#y0\tA/"!!#"'&/5327676765#534767>321*+2G+, (67f  (4%L<9%%*+j  =BBMtJadBCB p32NPftK\`JLB [#C!5654/#'67670320!3?0#"'&'&'&'&50547[ CA"!%!  " CA"!%!  ":.%? %&3* d%? %&3* dv1 !'!5  \Ȏ0َ 02VQ'676767632#"'&'&'732767674654'&'#6767&/&'&'&#"#O34?do%IBa\\KI=:HgQT.,(H<@1kKn XMU// oX.iP9ktz[i2134$:=>TRiekRPa32&#"3276<##2/AfNO./^f>2-8ItLMMLtuOP#d*&" 01QSbelne`\+rsvttvTL!#"'&'&/"'67>323276=4'&'.#"#367632#"!i:S*$#$0!F%F%05O8ffDF23"PQsRBE02?42   " !  ,&+PZKO7;B"#:AFKX[;323276=4'3276?&'&#"3,1263BK@*7 SfJLx5i#"!i:S*$#$0!F%F%05O8fD#8> '.+*5;%)6.;Opt:= ,42=v?42   " !  ,&+P ;5 \A>C6W +v#- U#"'&'&5467>767676?6767676767654&#"'676323267 ;y|nmEEB #&2'!CC(* sqSU)yyyz  V)7F-.$ ȎsG`b**[\:b)'H  $^|89HVUab1/1"#2    )#,rW- B]#"'&'&5467>76767&'&=67632326736767676767654&#" ;y|nmEEB #& (NB)yyyz  V)7F-.$ ȎsI1OP0'* sqSUG`b**[\:b)'H"B VUab1/1"#2    )#,rW+WI1  $^|89A%!7!&/'>76763223767676?263632/X2G a 6W& 4 *B@@B* 4 &W6jf  w   >;;>   w  /A%!7!&/'>7676322376767673>3632/nF a 6W&0*B@@B*0&W6R|V&  w   >;;>   w  Z^326767654'&'&#"25/7+"67632 &'&=47676763237:32"!nKIn!"A@bd@A{  f   <64>gLK.1Tjde01`de01#":8JI<  S\JL=73'676767654'&'#.CV*&(.1:C/]35 6 S4RO #"'&';2A@db@A"!nIKn!"VOFJ8:"#10ed`10edjT1.i?42-v_[;::;[_v\JL=`TfMd'647>7632#"'&'&%!32767676%!&'&'&#"d!!x]\orr.76nnts/"IImO@A#% t!FGkNB@&( כ?>؋̭jiڂOd[dc89Z]hA`bab:9]bf=eF4&'&#"!!327676767#"'&'&547676767632<=EZGLGX+'+ z 2)75=hj:;()68HJTsUV5)122x]_vM(%' LMTSRFH47=>`eF4'67632#"'&'&'&'732767!5!&'&#"5VUsTJH86)(;:jh=57)2 z +'+XGLGZE=<)B`>=74HFRSTML '%(Mv_]x22#:!#3676767632#"'&'&/4'&'&#"3276$"#)(7Z[" -+LG`73034C543+,4DFIsCD3 deVgZNPIL64" ZUpBC67`SFGIqs#27676767654'&!3 ##/\GQGR17 "/E62B=YWQNi13>(&TB@.+ d@#"'&'&'&'&547676767632&'&+"32767&$:5SO`ufdEG/21/HFdcxIGB21'(VSihTV4365URdkZ[ %@742.)(HJ^eikxtqmeaKI++(*()))Y9768XWrmyxonVS53AB\y 33 3##yϙTT#PQyt 33##y׺ϙt7632&'&+"!!32767b&$:5SP^vfdEG/130dcyHGC21'%VSiiTU43X65URdjZ]%@742.)(HJ^amkmjhc++('+)))Y9767YWrLYOKnVS53AC[- 67,3'jT,q33276765!5!#"'&'&q o[HI"#ͥtv%27?@[^f qsDE-<!###"'&'&'727!32#'32767676765!#y #("("*$#$kWjl"!fDG+) #\2 $  "f {!!rKIX+*ZX #!*#I)!!#3!332+32767676765! jl"!fDG+) Y}!!rKIX+*ZX #!*#j&!#!5!!67632#4'&'.#"ǘPQsRBE02fDF23""Z[;?327654&'&'&+5327654'&+"'67632#"'&q%POS_a:/17:=NbaHGIJ_Qx 4ed{d\Y<;!!'(&$,')&|~/Q54UVGz%&}JHreFGTJ@hA@/-[YmRGF'( !1-DCFMLy 33##y둝ZPwyX!676730"'&'&=333##7#;EPB#ECCE#BQ1N&1둝*z Do9(&&(9oD p4ZPwy 33 ##yxϼsT$!###"'&'&'727З #&%) *$#$kWP#\2 #  "f {y 33 3##yϙTT!P\LyJ 3!3#!#ykP^\%M4'&'&'&'&#"3276767676%47676767632#"'&'&'&'&H 0.FCX^//!0.GFT^IK-- ! ,+C@ge{zbdBA-,,/?CefzxcbDA-+spOIC<9" P@?UTUrhKJA;9 '(;4HA<63$$9;JLL,! ,-A?hfzycdX  ,.@C{wBA-+ #>  /-HFT\-,! <  0-GCX^II/0 J 3 3 # #Jjc;˾^)'Jy0< %#5!3!3<˞#b"3##"'&'&'&53327676765sRBC1443CF25 P Zx!"BGhpEZKO7:"!"$9>IPSy%!3!;3Ş##y0%#5!3!;3a##($!#5!332+32767676765!o Ίjl"!fDG+) "!!rKIX%0ZX #!*#yK&!332767676765!332+gDG+' jjA@"!P %!*#V!!99KIX+*YXy"32767676765!332+gDG+' ΋jjA@"! %!*#V!!99KIX%0YXd?7327676767!5!&'&'&'&+"'67676767632#"'&'&'&d [ZkcST58X45STijSU %'11DGHxcd03.^GDu_PS5:$&%)\BA34TYkKOYLoZ[5678Z)$.+'(++chjqtsJGR.247},R3336767676762#"'&'&'&'&'#4'&'&'&'&#"3276767676}a *(;9]\XY<<'0 '):;onXY<<'%_*'B>MVACR -)KV@C)( GN5bleQN22./OP\rWedeiagKM`--NM]XoSN\܂mQGD;7#!()|VhNmmNH?=8@&'=:ULXSyP#"3#&'&54$;##Ǻ ('\Jdc2Ξ|)"(!&"nnPwjwB5"327654'&'254&#"'632#=#"&5476lHFGIj`HFIJ{fNL ~vB@;#Nڋ !537lmFFEcgCDFEcgCD761`#hm{!ΧkkZA326767654'&'&#"&#"67632 &'&5476767632"!nKIn!"A@bd@AP[i.1Tjde01`de01#":8JFO[NP2\JL=L756($.!/1ZZxZD>+,V43W-%  ^2!#!V2*P2 %3#5!#367!3#^LFlhdj^ q0V|abF 1!.#"32767#"'&'&54767632 pL<:<:LIEH3ijtac/012_a_QN23\65ON_QN76&(;7d:;MO|{~IJ.,LM\_c/!^~2!#5333##\\q:wUXaAJ??327654'&'&'&+5327654'&+"'67632#"'&aux>gKI)!,(/9GI3467D:-*e)PMbOIF/. %$'$T$#pqdef&6B76[0&' }/0HA-.24S64#"BAQ<542! 3/6^_==z2 33##z2",z!676730"'&'&=333##$7#;EPB#ECCE#BQ1N&,*z Do9(&&(9oD p4",y5 33 ##y0H0PkE}2!###"'&'&'727M #("("*$#$kZ 2|U2 $  "f {b42 33 3##bPO2`$$f03 3%'!#ff2)-ZF0476767632 &'&7326767654'&'&#"Z48QTjde01`de01"!nKIn!"A@bd@AvfhIM)*KL{LM~\JL=f^/.ONfA/2##MLtuOPPOutLM1,$ $\`enlebSQ10 "&*srstvttveF/&'&#"327676767#"'&'&547676767632<=E+'+ z 2)75=hj:;()68HJTsUV5)122M(%' LMTSRFH47=>`R2!!#!R92[J1 3 30#"'&'&'72?R=!*) ' ,$  k3^1n   f  dt %.&'6767054&'&5'476730Lim~[H2dqVoP`iKgꦂdS5Elכ] Vt޺P$5f1 !# # 33f:ȪHNy02 %#5!3!3c2[\2!3##"'&'&'&=3327676765$rSBC14fDE2724Zx!"BGhl_FL:;B"%8:MPS}3 )3;33Z[}/3%#5%3;33Z[[ 52&3#5!32+327676767654'&!zjl@$2+猌fDG+) 6!!,K?2/&ZXM@ #!*3k2*3#3320+327676767654'&!ԗ_jl@"3+茌gDG+' 622!!,L?2 &&YXM@ %!*1%3320+327>767654'&!jl@"3+茌cHKN 62!!,L?2 &&YXM@:%!+eF4'67632#"'&'&'&'732767!5!&'&#"5VUsTJH86)(;:jh=57)2 z +'+XGGZE=<)B`>=74HFRSTML '%(Mv_]x22ayQ.U33367676767632#"'&'&'&'&'#4'&'.'&#"3276767676aa **9;PTCB*) ,+>7`O:51V..?jK:OP85/+)**?7@<uK2 "'#&'&5476!3#`0dM.LM::!.IgeJb<'Cp}b'jr}tD!##5353!!67632#"'&'&'72=34'&'.#"?PQsRBE02#("("*$#$kffDF23"[;``HJI&'&'&'&'&547672&#" #"'&'7327654'&'&'&>'*2/""deR), 6Qt 112-+$lk\_%45[e::"'$#.1;KL,&)$%zNH&  !'/6AZYCEnC$$00U)" ?L#O'jD\TfMH.20A!320+##"'&'&'727327676767654'&!#jl@"3+!茞M #&%) *$#$kZ 1gDG+' 62!!,L?2 $(VX|U2 #  "f {u %!*X62.!#373320+327676767654'&!jl@"3+!gDG+' 6S2V!!,L?2 $(VXM@ %!*-!#534'&'.#"##5353!!67632fDF23"?PQsRBE02ZKO7;B"#:AFKX[;767654'&!jl@"3+茌cHKN 62!!,L?2 &&YXM@:%!+y"3 4'&'&'&'&+';2+# '+GDgΞ艋!"@AjkΞ#*!% XY0%WJK99!!TN"2676767632#"'&'&'&'#4'&#"3276& 52>f^/.ONfA/2##MLtuOPPOutLM1,$ $\`enlebSQ10 "&*srstvttv\!67632+&'0'&%!!#  0  e )   ^!67632+&'0'&!#!  0   g*   V2 !!!!##53\ *֞fo0 !!!##53!\?6276=4'&'.#"+!!>32+6gJIfDE27 rSBC14#JA@PAJI!_FL:;B"%8:MPSYZx!"BGhl >CE= ^2{Ln^^~2~q _aAJyby5yby5yby5yby5yJef03y3!!!+!#y ^f3 3%!!'!#ff2)׈U.yJgy2dieFdieFXjR2BZ3 3#BddBX<x?16#"'732767676=#"'&'&'&533276767653&$?`?LLn.&O^^~'W~y33 52>5#yx-(.hQU 0 /$ϼs?Na!&( %<'y5!52>5#33 /3.hQU 0 /$Ha*&( %<'k0PT$!7##"'&'&'727\З #&%) *$#$kWP#\2 #  "f {E*}2!7##"'&'&'727]M #("("*$#$kZ 2|U2 $  "f {yO%52>5!#3!3O-(.hQU 2'6)*k?Na!&( $;'^Pf83!52>5!#3%8-(.hQU 5%8',f?Na!&( &<'-2)yJ 3!3!#ypkP^f*03 3%7!#fDf2)-b%3#53#"'&'&'&53327676765G4sRBC1443CF25 P Zx!"BGhpEZKO7:"!"$9>IPS 2$3#53#"'&'&'&=3327676765$<1rSBC14fDE2724Zx!"BGhl_FL:;B"%8:MPSy 33 37#yaTT!P\Lb42 33 3#bPOj2`$$7,H.&Xjw'cxH"%-4632#"'&'&%4632#"'&'&!!#3#8&"28& )8&!8& P%  n&8*! '8!&8! '8!]Pjw"2X4632#"'&'&%4632#"'&'&"327654'&'254&#"'632#=#"&54768&!8& )8&"28& HlHFGIj`HFIJ{fNL ~vB@;#Nڋ !537lmN&8! '8!&8*! '8!FEcgCDFEcgCD761`#hm{!ΧkkSg!#!!!!!!53OFF{JT`Fx"327654'&'&67632!3267676767>7>767#"'&'&'&'&'.'#"'&'&5476326'&74'&#"'676767632!&'&#"h00"\6742<;!32>!4'&'&'&+"'67676767632#"'&'&'&'&5465 ҩrZL55STijSU %'11DGHxcd03.^GDu_PS5:$[!Ovlj\[5678Z)$.+'(++chjqtsJGR.24:%bF 0!3276767.#"'67632#"'&'&'&54&= FGoK<;>rNIFG4gju_`0112_aaOM42͑hi65PN_j'';7d:;LL{~IJ-,NK]_c!0'jb'jXLn'jD^^~'jX~q 'j_aA'j.q _aAJy !!33##8[둝jZPwz+ !!33##[X+j",y'j`z ,33##4632#"'&'&%4632#"'&'&z*8&"28& )8&!8& 2",N&8*! '8!&8! '8!\&2jf&Rj{\'<P47676767632#"'&'&'&'&%!3276767676%!&'&'&'&'&#"\,+C@ge{zbdBA-,,/?CefzxcbDA-+!0.GFT^IK-- ! @  0.FCX^// gehfdRO21./NLa]ltmbghbiIM00--NK_[lm4SOKJA;9 '(;OIC<9" P@?UTT+bF"/ #5"'&'&54767!.#"27676?!a_210/caac/012_# pL<:<:<FJI~{|OMMO|{~I`65ON65ONZ _QN7\'<Pas47676767632#"'&'&'&'&%!3276767676%!&'&'&'&'&#"4632#"'&'&%4632#"'&'&\,+C@ge{zbdBA-,,/?CefzxcbDA-+!0.GFT^IK-- ! @  0.FCX^// ,8&"28& )8&!8& gehfdRO21./NLa]ltmbghbiIM00--NK_[lm4SOKJA;9 '(;OIC<9" P@?UTT+B&8*! '8!&8! '8!b"/AR #5"'&'&54767!.#"27676?!4632#"'&'&%4632#"'&'&a_210/caac/012_# pL<:<:<8&!8& )8&"28& FJI~{|OMMO|{~I`65ON65ONZ _QN7&8! '8!&8*! '8!d?Qb7327676767!5!&'&'&'&+"'67676767632#"'&'&'&4632#"'&'&%4632#"'&'&d [ZkcST58X45STijSU %'11DGHxcd03.^GDu_PS5:$&U8&!8& )8&"28& %)\BA34TYkKOYLoZ[5678Z)$.+'(++chjqtsJGR.247&8! '8!&8*! '8!e4FW'67632#"'&'&'&'732767!5!&'&#"4632#"'&'&%4632#"'&'&5VUsTJH86)(;:jh=57)2 z +'+XGGZE=<O8&!8& )8&"28& )B`>=74HFRSTML '%(Mv_]x22&8! '8!&8*! '8!#!!3 3#"'&'&'727x[dd  &%) + ,$#$k3RjX #  "f MJ)#!!3 3#"'&'&'72?[j=!*) ' ,$  k3^)jn   f  'j=kJ'ju&kJ='b&jho'j\[^2{yK'js3k*<M3#3320+327676767654'&!4632#"'&'&%4632#"'&'&ԗ_jl@"3+茌gDG+' 6f8&!8& )8&"28& 22!!,L?2 &&YXM@ %!*&8! '8!&8*! '8!y='e%'eEy'w'I'G!84&'&'&#!!2>767#!!247632#"'&'&@<:QPc ax! --QPpmWySS21>E=F؆PN++iVliba98d\[E > F > 8O3#5+"'.547676763232767>54'&'&'&#"47632#"'&'&I>?OLCDf<21DE[l ().<13'(,'%52@0'(>E=FPn)*$$ҎsjcLJ**gKT5:!";<\ZIJ;8#!73RHE > F > y(&'I(&Gy')}' IU !3!3#!#476320#"'&'&ju>E>F~N^E >  E > 2!#36767>32##"47632#"'&'&#-$#"#:*532*(>E>E8"!n-+)788xE >E >ytJ&+t&ńK!!33 ##]Ctb:D g!! ##33]G-h5A 3!!47632#"'&'&c6=F>EۍF > E >  %3"'&5347632#"'&'&8vCB>E>Ei:9u\E >E >  !!3!!47632#"'&'&f\c6=F>E}ۍF > E >  $!!3"'&5347632#"'&'&B]zvCB>E>Ei:9u\E >E >  !!3!!]ucۍq %3"'&53!!8vCBVi:9uňy'h0'_P #33 3##47632#"'&'&ϚTT>E=FN[KE > F > I+B!#4'&#"#3>32>32#4&#"47632#"'&'&a**K4-/%$.?zNIHTJIVI4-/%$.=F>EML('n?l2cLo^mkr('n?xF > E > 47632#"'&'&33#29>9>Q䞒>7 > 8 uNYb047632#"'&'&#3632#4'&'"9>9>}P 77Q252-(> 8 >7 2A"%$'nJK+&96< 333#47632#"'&'&䞒>E=FuNYE > F > I2!#3632#4'&'"476320#"'&'&#}P 77Q252-(>E>F2A"%$'nJK+&96  E >  !!33#o]䞒uNYI !!#3632#4'&'"]+}P 77Q252-(2A"%$'nJK+&96<y'k3T'tS[23 4'&+ ##!2476320#"'&'&!bcSמmvegHJ(*a`v>E>EBCw35KOaml!vE >  E >qM0&#"#367676763247632#"'&'&DG/++!"!%!tY=F>E**(<:H|2&#7F > E > [ 6!!3 4'&+ ##!2476320#"'&'&])bcSמmvegHJ(*a`v>E>EBCw35KOaml!vE >  E >R74!!&#"#367676763247632#"'&'&R]LDG/++!"!%!tY=F>E7**(<:H|2&#7F > E > [ !!3 4'&+ ##!2])bcSמmvegHJ(*a`BCw35KOaml!vM&#"#3676767632!!DG/++!"!%!tY=}**(<:H|2&#7_- '6`H'3VL>?V7327>7654'&/$47676763 &'&#"&$47632#"'&'&LZZYnF<=Z^Zn#">?RS` %}2WVp<64*'.ϐNX/2%&BA\\jH>E=FP:9R56BaJG7lRKI674OW10$!`:S34%*,/:8ZYMO98##E > F > kSKD[&'&'&'&54767676732&#"# '7327676765447632#"'&'&k>F%'/,AEL:>:02 (%$(+dKD.*32PE!.$'=E=F# $#$,+/:84*((*6y #g3%($+'/03?>:-,6"!-{hF > F > X'7fP'Wb!!#!476320#"'&'&bE7">E>E$E >  E >q[,)#53533#;#"&547632#"'&'&uEEv=F>E,uzv9F > E > b !!!!#!a\E7"Î$q[,#53533#;#"&5!!uEEv,uzvT'C:D1='C&ZT'v:D1='v,ZT'j:D1'j$ZVp47632#"/&3 3#9>9>QeeA>7 > 8Y:?bD47632#"/&73276=#"'&'&'&533276767653#"':?:>i>26GoHH%DEOGFE64"!>?o2,+$ 64NJY> 8 >7TGJJH01 ;8VRizQS+&;9A^KM;8$"!!#36767>32##"\9-$#"#:*532*(8"!n-+)788+!5276767654'&/!"#47>Njm@X02L\\jB?>--^Ro%&*(-/:8[Wp#"()54DbHA.+' ~XLd'C<x?<'C\\~'!5!3"'&'&53dqAEP#<K%(V#"@!!3"&'&533"&'&53@dqtdqj" KJY#"! KJY#"Zw<'lIZw='@TJZw<'I'CZw<'@I'CZw='I'vZw<'@I'vZw'')Zw''@/H'H'@[&'C\|['C`|[&'v\|['v\|['&|['&|k='IJk;'@323276767#"'&'&'&'&#"1F% 8 " !1 !"" "$B  &   9"Q4632#"'&'&%4632#"'&'&67676323276767#"'&'.'&'&#"8&"28& )8&!8&  !#%#0%$/ 1 !"""$! *I&8*! '8!&8! '8!W-$ &   !vt:'0'CutN'-tt','v32#'&'&'&'&   u<&- )H8    [ #2 - $Kg$&+(0dL2%632'&'&7476%47>32#'&'&'&'&  <&- )H8    #2 - $Kg$&+(01y+F67>323276767#"'&'&'&'&#"4767632#'&'&'&'&1F% 8 " !1 !#! "$BD',@'H8    &   N $@, #Jh"+'+v' v &q v'Cl['j*[ v'v['j+^ Zt<'AI Zt<'@GI v<'[ v'E'j,[ BZ.&BZ'q=}'C\'v\&@<(9'%&'&547676324632#"'&'&%4632#"'&'&   l8&"28& )8&"28&   n&8*! '8!&8*! '8!P):%632'&'&74764632#"'&'&%4632#"&'&  8& 8&!)8& 8&"2   &8 '8"&8 '8*"<#"'%&'&54767632       7'Cb7tH&7t<'v67;'7t;'6v'C\'v['C\x5'v\t5&<%632#"'&'&5476L      dL;47>32#'&'&'&'&d<&- )H8   #2 - $Kg$&+(0v:!!v;Ȏv:!!v;Ȏ!!X!!R!!:!!ȎE2###222SD*_>6c4:NjDAMQDr'MHMa>'NJNq2R[>|Q * #!5!3!)uuU*!!#!5!!5!3!)v1ώ;eHi47632#"'&'&;oDTM nDTM gN/n,3M/n,3 2F kF\33"&54767632,@$ ->( @,(>-( \#3"&54767632!"&54767632,@$ ->( D,@% ->)@,(>-( @,&>,) \#5!"&54767632!"&54767632!"&54767632d,@$ ->( X,@$ ->( D,@% ->)@,(>-( @,(>-( @,&>,) D I47632#"'&'&MLm_GFMNk^GFGlKK:8[lKL::YsiE <\i2654'&#"32654'&#"#3476767632#"'&'&'&476767632#"'&'&'&2654'&#"476767632#"'&'&'&()xX+,=3Zl''A3/4#(()xX+,=3Z%$23<122&(0%&10>3/4#(uI()RHB**NyH()RGB**N M501&%$"#dB7.0%% %/1501&%"#21C7.0%& %/2I()RHB**NH501&%"#dB7.0%% %/1 si DE <\i2654'&#"32654'&#"#3476767632#"'&'&'&476767632#"'&'&'&2654'&#"476767632#"'&'&'&%2654'&#"476767632#"'&'&'&()xX+,=3Zl''A3/4#(()xX+,=3Z%$23<122&(0%&10>3/4#(()xX+,=3Z%$23<122&(0%&10>3/4#(uI()RHB**NyH()RGB**N M501&%$"#dB7.0%% %/1501&%"#21C7.0%& %/2I()RHB**NH501&%"#dB7.0%% %/1CI()RHB**NH501&%"#dB7.0%% %/1'476;2#"'&'& $ ,,'46;2#"'&'&%'476;2#"'&'&,  $( $ FD3##mD###g"3F#&'&546324632#"'&'&#&'&5476324632#"'&'&V)<&(@,(>-()')<@,' ,'(6%,@$ ->$ f)6&,@$ , $ 7F%4632#"'&'&? 4'&#"'67632#54632@,(>-( 4 MK~SHyzXLO|L%&= >2$ <&(^,@$ ->$  ,!&}EDZ|9oo^`aIK>..>S8(6%c%#"'&'5!2767cٲרn@@>>rJJt ZR ''!!''!!''!!TTTTTT6TTT/'7'7'77'd8RR88RRR88RR88R"m?#3)9$%4632#"'&'&%4632#"'&'&#54767676? 4'&#"'676326732#54767676? 4'&#"@,(>-(@,' ,' 74 MK~SHyzXL9,MENO>@%&&):$=1& 65 MK~C< &%&= >2$^,@$ ->$ ,@$ , $ +*)# .,!&}EDZ|9oo@/1MOJP9..>S+*&# .,!&}EDO`aIK>..>91CVi67032#54767676? 4'&#"#&'&5476324632#"'&'&%4632#"'&'&9MENO|L%):$=2%  65 MK~C<@)'(@,' ,'@,( ,(@^`aIP9..>S+*)# .,!&}ED)%,@$ , $ ,@$ , $ g 2EVi67032#54767676? 4'&#"4632#"'&'&#&'&5476324632#"'&'&~MENO>@%&&):$=1&  65 MK~C<@,' ,')')<@,' ,'@/1MOJP9..>S+*&# .,!&}ED1,@$ , $ f)6&,@$ , $ yu$<"&#27636767676767654'&'&'&"#!32 dP* &'#'"KZhŌywfc9:  /)5 L ;  "2')#u10NOb&-/)+ 3'#'&'&'&54%6;N! o y 6n->(*oL732#'37 !N Lo*(>-n6   Z ''!!`TTTZq#H,74767632#'&'&'&'&47632#"'&'&q(,@(H8  -&<@+'^ $@, #Jh"+'+- 2# +@$ >'%)%"'&5467632"&54767632#3A- 2# , ( ^,@$ , ( %ѐ -&< ,' @,' ,' D?3\+67>323276767#"'&'&'&'&#"?F% 8 " !1 !"" "$B  &   m?%72#"'&547676#"'&'&54632#"'&'&54632, $ - * >-&@,( >-&@,(  -( ,( .>" +@) Y.>" +@) m'9K2#"'&547676!2#"'&547676#"'&'&54632#"'&'&54632, $ - * , $ - * )>-&@,( >-&@,(  -( ,(  -( ,( .>" +@) Y.>" +@) m%8J\2#"'&5476762#"'&5476762#"'&547676#"&'&54632#"&'&54632!- 2# , ( - 2# , ( - 2# , ( ' -&<@+'  -&<@+'  -&< ,( d -&< ,' N -&< ,( - 2# +@( Y- 2# +@( d;+##"'&'&54632#"'&'&54632:@,&>,) >-(@,& ,@% ->)[.>" +@( %+':N2#"'&547676%2#"'&547676#"'&'&547632#"'&'&547632- # , ) - $ , '/@,& ,)  -( ,&  ,( -(  -& +( ,@$ , * ^- # , ' d<s%8#"'&'&547632#"'&'&547632#"'&'&547632;@,( ,' @,( ,' @,& -) ,@$ , ( Y,@$ , ( E,@# , +dm<+#5H#"'&'&54632#"&'&54632#"&'&54632#"'&'&54632:@,&>,)  -&<@+'  -&<@+'  -(@,& ,@% ->)- 2# +@( Y- 2# +@( E- " +@(0Q167>32#"'&'&54326767654'&'&#"B!!lBd~XcCA &0 % I;;HwHMqX\xLJwFJRR:>I('*('214D=E)'*+091@#73#{aDPB'767632!!5476767676?>?4&#"ʆ JIX&D !.   ( _ !. <&( #5O87:,-0 ,#406 '!"!5<.3S>7327654'&'&'&+5327654&+"'767632#"&'3 < 8&% JT"4"  9:H885##QRtHs+!(!!6($2 > >%%65A1)'&$-rIJXJA 3##5!335$^^WcW60H2'!!632#"'&/732654'.#"-    o7)&_CE>;PbFH "V2> >"N9} 9:\ &I?=*(9:Z%cJA.:0714'&'&#"3262#"'&'&54767676?3  +1  (3Bv_FI h8bBE  ("#-&B.9;Y .,0"#.;>S '*52l #!5lЧ:c%6I#"'&'&5476767&'&5463232654'.#"27654'&'&#"AA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$0O^= !?Lx#";;\/'& *>`~.(".%$3)@7 *-4:327654'&'&#""'&'&547676767632#  +2  !'2" u^GH  ,*.`ED  ("#, (" ::Z&$&<;V! " -F  533##5#53P4(!!P(@g!!!!@**C<lr&5476?3#'&]! ? &~#"9& <Doxgrlc7egcT7^3rh#767654'&/3%= !#$7% 9"# >r7[dd_ehkP7Zotqmon_B&!#3632#4'&'&'&#"Ԓ2D/*'   _$)%>@I1+! #+0Q1767>32#"'&'&54326767654'&'&#"B!!lBd~XcCA &0 % I;;HwHMqX\xLJwFJQQ:>I('*('214D=E)'*+091@#73#{aDPB7'767632!!5476767676?>?4&#"ʆ JIX&D !.   ( _ !. <&( #5O87:,-0 ,#406 '!"!5<.3S>7327654'&'&'&+5327654&+"'767632#"&'3 < 8&% JT"4"  9:H885##QRtH+!(!!6($2 > >%%65A1)'&$-rIJXJA %3##5!335$^^Wc W60H3%'!!632#"'&/732654'.#"-    o7)&_CE>;PbFH "V2> >"Z9} 9:\ &I?=*(9:Z%cJA.:0714'&'&#"3262#"'&'&54767676?3  +1  (3Bv_FI h8bBE J ("#-&B.9;Y!.,0"#.;>S '*52l #!5lЧ:c%6I#"'&'&5476767&'&5463232654'.#"27654'&'&#"AA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 *-4:7327654'&'&#""'&'&547676767632#  +2  !'2" u^GH  ,*.`ED  ("#, (" ::Z&$&<;V"" -F 7533##5#5?P447!!P4@s3!!!!@**C~7Zed_ehkP7Zotqmon_?  ,"327654&#"'&547632&'&#"'762#,(22( 44!!^@?ABZ;% + SKĂ$2"$0#$0 >>b_?@ o>t' 0 273&'&#"3276?#"&'&54767632!µ&   zDMr:8M:/16<$%!6";DZGFWUGE-+T50;#*%0/76767632#"'&'&543276767654'&'&": 31=Rt:;RR:; $  F0o8,*VGEGF----GIT==(#& &,7'(*N4G #'#373Gc_`_0.1 5#327676'&'&#"'767632#"'&'&'&5050=!&b&   =>CL:9;:K:/0HR$%"6";"#.-GITSID-,+*50:$D I47632#"'&'&MLm_GFMNk^GFGlKK:8[lKL::YD I47632#"'&'&MLm_GFMNk^GFGlKK:8[lKL::Y*)!&'&5476767632&#"!!!!!mFE/.EDQYB}JV*'%4,:MU,8u$ 39@#"'&'#7&'#&'&54767>?3273&'326?&#$T^`# )N4 37^'# %3M?w& Q+%* !d<<}567m!Qpl{ouTZ|2`;#6;3 *#Ckb@YJ#"'&'&5476767632&'&+"3676767632&#"2767؁^ilwolTR`,*RPnofiM.SP]]OQ9< '$65<"!%!tYBDG.,+! *ZFI.%C;=21cali<<;=sBB0.12TWqpkWYMI::##7|**)xEBDU3#535#53!!!!!!wwww..y؇S;؇d6/37632&'&#"!!!!!2?!76767#537#d k!d9'io~"7+P-y+;T  i6 q`>OF32673;2$++J- ͝j**L3-/%$.?zMI-0iHILKnEdML('n?l2cLE09kk#&)##!##535#533!33#)'!35!%35#wwwwwykwwU55yy؇SS؇HRnTel%#53533#303%276767654'&'&'&'&54767676;2&#"#!"'&32!#3 !Un.$)k>C'(.,BAO9>;02 ($$(+hJC.+32Qb;:yfcIG)(88؇,u ##+~E# #$%+)1=67)'(*6y #g3"'$,*.,8A<:-,6=;[42NLgop$ ^hz#"&'&'&'##!23276767654&'&'&'.5476767632&'&#"4'&'&'&+32767>^%'66JHBLDJ>=0؞m[h^SPb01C>P~I9(Z0289A&,')#T?T4H@?T4/BAB4;823!# =?@"H *&C2VFB>+*#"86FBGL?G57D)K;?)*.-G20pRCE01# oP9@ &$->N$$$fUG;6'$ *,9F$8" '%:9S54 j? 4 7!?#!'#!7###!##53'#53333333#3xNP-+2A.->19RP>0 A-WX&p]GGO)T8vciv.(330#53>32.#"!!!!3267#"&'#53&54'}q}M`2XQ<_,"i0E\>`<9[7&:K`3+ZJ MW+Da/!!!###53333!!ucwwLwfgzz+p!%%#5%55%!5!p755˞NN"E$mmmmwwww| +#324+32 3 !0IHF|MNFFW f1 +h<;77o`X &Gd3276767654'&'&'&#"2#"&'&'&54767676324'&'&'&'&'&#"'63>!!0.BA43'",+=;B5),=&V#,$:92Z55OOpm31/1FF_4*'B / -(9:<)%%-& 7<=45"! 4-C=<>?>..$'1585 &>6FMDUY2_c`PO21LB@[XgQVUAC** $ , >SERH;<)r',7!323#3#+##535#535!2&+4'&'!!676>'qFFq<~Ϟwwwwm_PLWPч    k:;Ws67mLL  s  ,8#5&'&'&'&54767676753&'6767#53+*CARQDG1410GDXU#DFT64\/'&~gXYDB/-+-EJ`a}l\_LJ64x5B_QO9B'&84GCM!#!##537!5!3!!3# '!2@@1up;+)䇇8Ȉo+n\!327676767#"'&'&'&54767#5367676767!5!654'&'&'&#"'6767676323#!n 8/0;<@E67-,') V]Y\CE++Du1,;.AH<()53;i5}/-/63D>P3X,B;$Dn'(#"032P68NOe &" =H!":@SY]_:;# "'&5!##533!33#3 B@@www:9u_66piLOju#5#"'#5&'#&'.'&'&54656767667632>32676767654%'$476767632&'&#"4#"37'54#"'54'&#"OlKOTTK4gG>T  $!T8$E<4,. "n#">?QRbkmG%}3UUq=63*),34hy]W0/-(?@-(+- QFGn&( =5H^!L  " $1)V0&Z\q"#,.492eoRKI68./e4OX00$#^:F9:%3,*'.,?Sg#"'&'&'&'&547676767632&'&+"32767;27654'&'&#"47632#"'&'&".-L_PQ76.8' 09;RO`=67&## xDCTFBG.1#(/luNIH{!&"'@4167KB208>4206))HDcxUTTGgEG-+,)'*))Z879=QXpmyzn~LB?^I (+L45)(?K55)'@"]+#"'&'&'&'732767654'&'4!5]c;6:jh<5;'. z )',X:.fj+YmUxML$ %(MvNp FZx>y+5!!327654'&'&#"47632#"'&'&33# v ('4<** ('4<**vLLn_GFLNl_GEf:71"!+,?2"!,+ClKK:8[lKL:9Z>P2y"3 4'&'&'&'&+';2+# '+GDgΞ艋!"@AjkΞ#*!% XY0%WJK99!!yP32676767654&+ ##;2\'( Sמcd"&$%,|wlmnnxw* 33##!###+sĉt_ bwM>7cP5K%&'&'&547676767632!!5676767654'&'&'&'&#"3!7 ?,+,+C@ge{zbdBA-,,-HK9;!  0.FCX^//!79EI^[lmlgehfdRO21./NLa]ltmbghbeK(@BRUORUspOIC<9" P@?UTUrhKJE9: 10+B327673#"'&'&54767632!"%4'&'&#"3!276 20FHOmacBmpk?7ه{ f  $!15>/R K R K &>DH7327654'&'&'&+5327654&+"'767632#"&'#73#'[ < 8&% JT"4"  9:H885##QRtH{a+!(!!6($2 > >%%65A1)'&$-rIJXJ 9A7H5B'767632!!5476767676?>?4&#"732654'&'&'&+5327654&+"'767632#"&''Ά JIX&D !.   ( _ &. <&( # < 9J JT"4"  9:H885##QRtHË5O87:,-0 ,#404!'!'!6<.+!(B6($2 > >%%65A1)'&$-rIJXJ]9A739=%'!!632#"'&/732654'.#"#73#'M    o7)&_CE>;PbFH "V2> >"W{aZ9} 9:\ &I?=*(9:Z%cJA.: 9A7L-Bvz'767632!!5476767676?>?4&#"'!!632#"'&/732654'.#"'҆ JIX&D !.   ( _ &. <&( #    o7)&_CE>;PbFH "V2> >"S5O87:,-0 ,#404!'!'!6<.j9} 9:\ &I?=*(9:Z%cJA.:]9A73->rv7327654'&'&'&+5327654&+"'767632#"&''!!632#"'&/732654'.#"'3 < 8&% JT"4"  9:H885##QRtH    o7)&_CE>;PbFH "V2> >"Ss+!(!!6($2 > >%%65A1)'&$-rIJXJ 9} 9:\ &I?=*(9:Z%cJA.:]9A7A- @D3##5!335'!!632#"'&/732654'.#"'$^^Wc7    o7)&_CE>;PbFH "V2> >"SW69} 9:\ &I?=*(9:Z%cJA.:]9A717;4'&'&#"3262#"'&'&54767676?3#73#'  +1  (3Bv_FI h8bBE {aJ ("#-&B.9;Y!.,0"#.;>S '*5$ 9A722Edh'!!632#"'&/732654'&'&#4'&'&#"3262#"'&'&54767676?3'6   n6)&`CE>;PaGH #U3> #  +1  (3Bv_FI h8bBE O9} 9:\ &GA=*(9:Z%cJA /g ("#-&B.9;Y!.,0"#.;>S '*5,9A7%6IOS#"'&'&5476767&'&5463232654'.#"27654'&'&#"#73#'AA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$s{a0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 * 9A75>du7327654'&'.+5327654'&+"'767632#"&'#"'&'&5476767&'&5463232654'.#"27654'&'&#"'5 < 8%& 0JT"! ;:H885##QRtHAA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$os+!(!!6($ > >%%65A/+)('*rIJXJ{0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 *r9A702Xi|'!!632#"'&/732654'.#"#"'&'&5476767&'&5463232654'.#"27654'&'&#"'-    o7)&_CE>;PbFH "V2> >"AA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$oN9} 9:\ &I?=*(9:Z%cJA.:{0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 *r9A72+<OS #!5#"'&'&5476767&'&5463232654'.#"27654'&'&#"'lЧAA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$o0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 *r9A7 #73#'{a 9A7733P\!3!3>PP !3!3!3>>PPP 3#33mGBPP{3#3)GBP{ !33#3U7GBPP{!3!33#3z>7GBPPP{!3!33#3z>7GBPPP 3 3 # # 3jc;˾^)'J'PJ 3 3 # #Jjc;˾^)'JJ!33 3 # #jc;˾P^)'JJ!3!33 3 # #6>jc;˾PP^)'Jy3!!yeݍd@#"'&'&'&'&547676767632&'&+"32767&$:5SO`ufdEG/21/HFdcxIGB21'(VSihTV4365URdkZ[ %@742.)(HJ^eikxtqmeaKI++(*()))Y9768XWrmyxonVS53AB\y)4'&'&'&'&'&+327676767#!!2 %*,2HIS~\[55''JIprDpqIK&'E=F?D8@(.j**PQfhdc78=>ehy 33 3##yϙTT!P\Ly54632#"'&'&3#y8&!8&!5&8! &8!yZ&*4632#"&'&3#4632#"'&'&3#8&"8&"28&!8&!5&8" &8*!5&8! &8!y&*<@4632#"'&'&3#4632#"&'&3#4632#"'&'&3#8&!8&!8&"8&"28&!8&!5&8! &8!5&8" &8*!5&8! &8!y54632#"'&'&3#y8&!8&!5&8! &8!R1!3 31nR4632#"'&'&3#!3 3B8&" 8&"i5&8' &8 1nRH%);?F4632#"&'&3#4632#"'&'&3#4632#"'&'&3#!3 38&"8&"28&"28&!8&" 8&"i5&8" &8*!5&8*! &8!5&8' &8 1nR#&*14632#"'&'&3#4632#"'&'&3#!3 3g8&"28&!8&" 8&"i5&8*! &8!5&8' &8 1ny !!# # 33 4632#"'&'&3#:Ȫ8&!8&!HN&8! &8!5f1 !# # 33f:ȪHN5!4632#"'&'&3+ # 338&!8&!:Ȫ5&8! &8!HN5&*64632#"&'&3#4632#"'&'&3+ # 338&"8&"28&!8&!:Ȫ5&8" &8*!5&8! &8!HN~ %3"&'&53dq KJY#"eF/&'&#"327676767#"'&'&547676767632<=E+'+ z 2)75=hj:;()68HJTsUV5)122M(%' LMTSRFH47=>`#23#5#"'&'.'&547>32327654'&"6"#2/BPEB.,@ ^f?15 &MLtuOPPOLLR*&"  75PTUne`\$ $,vttvtsrqN5!#4'&'.#"#3>7676767632>32#4'&'&'.#"V ,H5ژ ($0tJKm *B+#N1=37N.a1*! DEihs;/6+8$<g>.E_#!5#"&'&'&'&5476767676325!23276767654'&'&'&'&'&#&'&+"3276('qrD6FP`tDG/11/HFdcwIGB2 pq'([[55 %*,3FITn MSjhTU4585TRdlZDח88?*RGJ^ampsovmeaKI++ 5=>ʃj**PQfgE=?FD8@(.pQ3767YZomyxokYT43A0y)4'&'&'&'&'&+327676767#!!2 %*,2HIS~\[55''JIprDpqIK&'E=F?D8@(.j**PQfhdc78=>eh&'>O4'&'&'&'&'&+327676767#!!2;#"47>763!!"'.'&. %).3EIT\[54('qrDpq'(55[[TIF3,*% ('qpDrq'(E=F?D8>*/j**PNig88=>ʃhfQP**.(@8DF?=E>=P88ąd<73276767654'&'&'&+"'67676767632#"'&'&'&d [ZkcST5845STijSU %'11DGHxcd03.^GDu_PS5:$&%)\BA34TYkoxymoZ[5678Z)$.+'(++chjqtsJGR.247eF/'67632#"'&'&'&'732654&#"5VUsTJH86)(;:jh=57)2 z +'+E=<)B`>=74HFRSTML '%(Mõ22d@#"'&'&'&'&547676767632&'&+"32767&$:5SO`ufdEG/21/HFdcxIGB21'(VSihTV4365URdkZ[ %@742.)(HJ^eikxtqmeaKI++(*()))Y9768XWrmyxonVS53AB\BA 7%{eg,{f*hy)4'&'&'&'&'&+327676767#!!2 %*,2HIS~\[55''JIprDpqIK&'E=F?D8@(.j**PQfhdc78=>eh&'>O4'&'&'&'&'&+327676767#!!2;#"47>763!!"'.'&. %).3EIT\[54('qrDpq'(55[[TIF3,*% ('qpDrq'(E=F?D8>*/j**PNig88=>ʃhfQP**.(@8DF?=E>=P88ą01pt67>32#"'&'&54326767654'&'&#"7327654'&'&'&+5327654&+"'767632#"&'#3B!!lBd~XcCA &0 % . < 8&% JT"4"  9:H885##QRtHѐI;;HwHMqX\xLJwFJRR:>I('*('214D=E)'*+09+!(!!6($2 > >%%65A1)'&$-rIJXJ.x% !!x@& '#@&x!5!' R&@%37 (@x  !' 78@@@@ %7  ':@@@@4X4jn\tlZZn4X%''lZZnZn4X 77!ZnZn\4X !n\rn\ZjxXh! !3!!#H@@llx^jHxXh!' 7!#!5!3@@jjl HH%327632'&#"#&/,^^PMfaG7p@J,`^^^^L,OBp, 2N"$#"'763232?'8[`]/H@p6HafKP^^N1 ,pBO,L^x 37!!'# 8"@8@"@  '#75 :"@8@"@x #7!5!'3' R"@8@"@ %5'377 "@8@"@x< ! !73#$@@였Ȁx< 7#'3!' 7!Ȁ@@x 53#5! @@f@@  %3!53 '8@@@@@x 53#5! @@f@@  #5!#7 Z@@f@@xt 7!!7  'xddd@@v@@x^! %#Z@@&X&|!#' 7!&@@Zx^3! !ހ@@(|!' 7!3@@ڀ@x5!7 xT*@@Vx3! !@@(HB &'&'&'0#"767676303GJ U+d^R4l ˩ZWΡXZHMIO:\T_ZmlHB 6767670327'&'&'�#HWZ ƥl4R^d+U JIşlmZ_T\:OIMHZX4X !!!4jn\Z$jZ\n,x  !!3!5!' 3@DdF@0dȀZ`/3276767654'&'&'!#"'&'&5ghkl3+:)i5CXRO= 1G:;~ /36%ddrk/*A/`<7M98yz ,A@9?o0`/#"'&'&'&5476767'!'3276767650 ~;:G1 =ORXC5i):+3lkhg?9A, zy89M7<`/A*/krdd%63/x `!x@@ @x !f@ @ '#@@f@ #@Z@fx^5!'x@@x !5!f37h@@3fBx  !!!5!' x@&&@ ʀJ@ '#37 J@&&@x %!5!' !!R&@f@&x6 !!-!!->,:8.8 #%#j,:8.8x6  7!5! 7!5!:,:8.  3% 3:,:8.x 7!=!@f@@@x !=!'f@@@@ b '!!!!eh""nTZHHU!  #7#!#UnTZHH@lh"" b '%5!5%!5e""fZHHHHHU! 33!3ZHHeh""  '%5 '!!!!eeh""fZnTZHHH %!'!3#3a%QPRK327654'&'&#"#"&'&5476324'&'&/&#"'632 KLHpVV_]h:53:>FB|{ no+"(   548tE[%N$.1/uDDlm'rOM53F{sp$!5H=K&㙗HPć   !(^ih2VFy )5!!5!!5!g0^X&$7H47>76763273#"/#7&'&'&7&'&#"%3267>54'&'&^ dECFCGmY;_% JKtrld ]'P u '" 97BFB<9%#zm:*"Y}8>2,L8#/.OLf 420Z.(L<4x33%!xFE#n`Bx!# x>`B";#"'&'&57676;#"!!SRVresssseuSQSgf$-;;-&dgm<!&.#&57676?33#!!;#"'&'# x\ss`}AAS|COVrecd@;QS;-]EE+%_ &dg:^Bq 5! #!5!276767!5!&'&'&'&#:f?ssefvRSAk @>hfСƀ-$\I_?42n@!#!#nҞjPn@33!3nP@:y %5 5% %(lP0<D:!!DDȎIH(;#"/#"&57#"'&54?'&547632'46327632@ ') *' (( '* )' }q"*& *" (+om+( "* &3#!5!]ۯڡ3'uC&~DCC3276767654'&'&#"&'0'5#".54767676326763"30/BA/07:ST:7 A($&&$>54'&#"dbPr@AbVn+"kk NQ'0jk"+VbA@rPblxdFGo`ۼܚvu , uvi`oGFdx63h%!!!mh8O! #3߀OKPO3#3{!Py4'&'&'&#"#476763243?BIz\]"-gfg@? STSugeuty3#"'&'&53327676765졊ŀ-"]\zL?=54òsteguSTSA@gfT )%547676767032&'#"/7>54#;DB&(16]&D#;DB&(19]&DAOPF= $ j1AOPF= $ j1\-?#"'&'&5476767632"&54767632!"&54767632P, !+ !t,@$ ->( D,@% ->)3& $% $ @,(>-( @,&>,) ?3Z\&6767632276?#"'&/"?,.,- %">;-),) ,& -*.&Bb>&*.67>32276?#"'&/"!!!!E,X. %";CH(*#*L9 ,*+('%#>>;.)*)    ,& -# .&a?\/[676763203276767#"'&'.'&'&#"67>323276767#"'&'&'&'&#"?!#%#0%$/ 1 !"""$! *F% 8 " !1 !"" "$B-$ &   !  &   p7##537!5!33!!!̙ϐ NTBb !!!!!!B   Xm> 5 !!hZg[/uѴm> 5-5!5yZ[u:^Bq!"3!!"'&'&5476)Bfh>@>RTOyfess?f24~K{[^"-:^Bq5! #!5!2767654&'&'&#:f?ssefyOTR>@>hfСƀ-"^[{K~42_%!0#3!!"'#7&'&547673G`t`AJUsOKR#1i7oH5\F 'LgoZ  %Khb9)d%!5!"3!!"'&'&5476)Kji7oHIVrgst?%Khb9:$ghond7!!5! #!5!2767654'&'&#dK>hsUIHo7ijtnoĞ$:9bhK%^X'1>H47>767632#"'&'&'&67676767!%4&5&'&'&'&'!^ dECFCG% JKtrldeQP y''86;%&B=:$ E*+86<!B<9% 1eWVt)(<3uw?>**\Y}8 L89%$>20L/5L<=$#5 /.O*6^X%0;E47>767632#"'&'&'&77'32767'67654'&/&'&#"^ dECFCG% JKtrldeQP u # #6;:**\Y}8>2,C7La$$LZ.(L< G"^%!!5!3OP"RT4632#"'&'&RL51!# L5.#$ E7J* 5L+ RDTF47632#"'&'&R&(31!# L5.#$ 7%&* 4L+ f !547676767032&'g +23$'FЏ# 59- 0#"/7676= +22%)F 0# 79-9% 3 UagX97# 3aaeZ #3o(ک0~S 3!!%~:e'%3"'&'&5"'&'&53;&crADrADc K%'W#"%'W#"Ky!!!33#;#"'&5!#yuFF;32;3276767653#"'732767676=#"'&'&'&5# MLtuOPPOutLM#":8JFO[NP21 [i##2/AQEB.,@ ^fW5: fDE26&#A>JHQՖjh4,3%)QRqSBC14vttvtsrs bTQ75!"21<99Vv!*&"  75PTUne`\ _FL:;B"$:;KPSaUO96U{!76GY<=!"BFjl&7<)$f@+H#5353%3276767653#"'732767676=#"'&'&'&5%;#"'&5􎎗fDF23"&%>8RKMՖjg2.3%)PQsRBE02uFF;<ZKO7;B"#:AFKX`UT61!U{!76F[;34# ,i 4-V}xE4632#"'&'&#53476767632#"'&'&5654'4'&'&!#!#F8&" 8& ,(41& /)'8&   %ėҘK&8" '8 b6>34# TQG '8& 2$-V}cz0#5354767676320'&'&'&#"#!#,(41&<%!.   ':—Ԙ6>34# +  / 4-Vdx"<##53476767632&'&'&#"!#%632#"'&'&5476+(41&;J-m (—K    V6=45" (*i .G  }x#DK0#"3###53547676767673##!5!476767632&'&'&#"3%#'#3.',/2Ę,4&D@c`혘!+(41&;J-m ( &%"V.C4.6$V6=45" (*i .V}w9KW#!##5354767676767632#"'&'&5654'4'&'&!#4632#"'&'&%!47fҘ,E {&*/)'8&"  %ėx8&  8&"\'42,UV.C4.F5=%TQG '8' 1$-&8! '8!H &%"60}) 2!7#!##53547676767%'#h'42,Ҙ,(2O7Td  — &%"}UV.C4.*!6dSS   }x :T!47#!##5354767676767632&'&'&#"0!#%632#"'&'&5476h'42,Ҙ,E {<%"/m ' —O     &%"61VV.C4.G4=% ,i  1G  436767632#"'&'&543276767654'&'&#".-ACQxSP"''l|RS!ZA0&' ,+@0&) \ON+-_\g_xw_a^`iiXQj|"#;=DLBY]f>=#%;>FKL%1 !53#5!#3LٞMF'767632!!5476767676?>76?4&#"o_`s1-.(-# * '(T.(,+1 ! fC@865iGH #'87C(H$%'"%G?D/.3,$##  $(0Zf)(Njx2?7327654'.'&+5327654'&+"'67632#"'&j%ORPa`^:8?Nb`IGIK^Oz5edzd\[;: !'%)%+%+&|~z-O13RQH8:FxGFmaCERF=e>=--VUiRAC&# 1,@>F{|JIV/ 3##!;!]^ ~$ts#Voe23"'!!632#"&'7327654'&'&D   ^B[tv" j҇.T߄RQ PP    KT7ab=@ڊơa`,'pLKv54'&'&#"3276632#"&'&547676767673dQRrRTRQiUUFH@|}! ! :8YWf N!hCCZ\s!f??WVde%9NNL@>('Β/(;9=3"7&.*HT2 #!5ն2PT%L%27654'&'&#"327654'&'&#"2#"$'&547676767&'&5462bb]ZuDC_oGFAAewBCSKLDCqo" *,&)( q]]" mCA(oU21A@rQ10BC0m&KLj+%kj<;Ο2.LEB-/U+,ve2532654'&'&#"#"'&'&54767>7632# sRPjUVH@} '+fMKOvt " |"gw'eA@XYef/0>?A6;Rge+,7<7;5#84ZxB-7&/054763253#5#"32765&'&#"knf !537X@B`HF=?vF36!=YqtmWFϜ!ORFE`:LN!LZx='Ca~Zx;'v~Zx'bn~Zx'Z~Zx'~Zx'jb~ZB'*~Zx<'~Zx)&q~&&2@4'&#"'6763267632&'&#"327#"'&5"#"'&'7327656>F(?V!Jr?)VnLV=&J>*:9;^JVH<9AI_?=9>u %^6uG -5MN_XLM94"ϚTT>7 >7 %7J++$$H@bN[K*V47632#"'&'&327673#"'&'&'#4'&#"#3>32>32#4&#"9>:>y %^5uH +5NLaWML94"˘**K4-/%$.?zNIHTJIVI4-/%$.7>7 > 8 Q 7J++$$H@b+B!#4'&#"#3>32>32#4&#"327673#"'&'&'a**K4-/%$.?zNIHTJIVI4-/%$. %^5uH +5NLaWML94"ML('n?l2cLo^mkr('n?I 7J++HH@b3!#3632#4'&'"327673#"'&'&'#}P 77Q252-( $1/5uH-6aWML94"2A"%$'nJK+&96<I"5 o 1S=LT$$H@b[\43 4'&+ ##!2 327673#"'&'&'!bcSמmvegHJ(*a` %/.7uG -5MN_XLM94"BCw35KOaml!v\7n(R>J++$$H@b0&#"#3676767632327673#"'&'&'DG/++!"!%!tY %^5uH -6LMaWML94"**(<:H|2&#7 79>)9>9>$>7 > 8 >7 > 8>,$6#53533#;#"&547632#"/&%47632#"/&uEEv9>:>)9>9>,uzv->7 > 8 >7 > 8L>?Qc7327>7654'&/$47676763 &'&#"&$47632#"/&%47632#"/&LZZYnF<=Z^Zn#">?RS` %}2WVp<64*'.ϐNX/2%&BA\\j49>9>(:>9>P:9R56BaJG7lRKI674OW10$!`:S34%*,/:8ZYMO98##>7 > 8 >7 > 8kSKDVh&'&'&'&54767676732&#"# '7327676765447632#"/&%47632#"/&k>F%'/,AEL:>:02 (%$(+dKD.*32PE!.$'L:?:>)9>9># $#$,+/:84*((*6y #g3%($+'/03?>:-,6"!-{\>7 > 8 >7 > 8U /3!3#!#47632#"/&%47632#"/&jv9>9>(9>:>~N^>7 > 8 >7 > 8-?!#36767>32##"47632#"/&%47632#"/&#-$#"#:*532*(9>9>(9>:>8"!n-+)788l>7 > 8 >7 > 8U 3!3#!#!!j]~N^ -3!!327654'&'&#"47632#"'&'&c LW(OW(uoDSM oDTM ۍSN"& TN!+N/n.1N/n,3# 1%3"'&53327654'&'&#"47632#"'&'&8vCBLW(NV)tnDTM nDTM i:9u3SN ( TN#)M/n,3M/n,3  1!!3!!327654'&'&#"47632#"'&'&f\c LW(OW(uoDSM oDTM }ۍSN"& TN!+N/n.1N/n,3# !5!!3"'&53327654'&'&#"47632#"'&'&B]zvCBLW(NV)tnDTM nDTM i:9u3SN ( TN#)M/n,3M/n,3[0D3 4'&+ ##!2 327650'&'&#"47632#"'&'&!bcSמmvegHJ(*a`QLV)NV)tnDTM nDTM BCw35KOaml!vSN"&!TN#)M/n,3M/n,3M-A&#"#3676767632327654'&'&#"47632#"'&'&DG/++!"!%!tYlLW(OV)uoDSM oDTM **(<:H|2&#7SN"& TN!+N/n,3N/n,3[ 4H!!3 4'&+ ##!2 327650'&'&#"47632#"'&'&])bcSמmvegHJ(*a`QLV)NV)tnDTM nDTM BCw35KOaml!vSN"&!TN#)M/n,3M/n,371E!!&#"#3676767632327654'&'&#"47632#"'&'&R]LDG/++!"!%!tYlLW(OV)uoDSM oDTM 7**(<:H|2&#7SN"& TN!+N/n,3N/n,3TT1 732=3#"'&'&wk   f#("("*$#f  {1ϋ?42 $  e #!#3#3)#'#7'373 ! %! !D`\G~}D^]D}*S\888խ jJwE6 !!EED62^X +G!#3##3267>54'&'&'&'&#"47>767632#"'&'&'&LQ ''86;:**\[{8!#!#FP@b)7R"327654'&$'&'53254'&5476322654'&#"&%&#" '&547676^BC][CBAAֿGHzeehHy{^AA^^BC,_0yfffffHz}^^AAAA^]CB+zSjgffM%&^]CB^^AAr-zSlggggfL&'X67654'&'&#"32463227#"&5454&#"#"'&'&54767632254'&FL H'%#$L H(%$-޲llFb@|nbIJ%2t86>9q.1u68KG.rH'$#$KH$(%!KmnzVFvxnؿLM};HE@bj VAr,0v57=;p,( Hl5T7!!&'&'&547676767632!!5676767654'&'&'&'&'&#"3!7#H3-+C?hgyzD2<< ;,IK99!! .%(,HEV^IJ.1!!89E`)~YIn2LMgdRM32\P;qp&I)dL(@AAB2;1 bM28"!()>'mJM'9hM629: ">j=;53'5#"'&'5#"#'&+"#4'36763267632J>XX67.9@C< (WXr$YZB>::)_`J<((lzrr__rjn~~842mn NZ[[`_}tddQPx!5!##'!5!f dVVh1923632#"'#536&#"04'&'5267>327&'"h('jvJJFGv,==vf08$MGDCOP%+-(xNZ~ [_]^cRSihtnؿ`mnYX@h6$(S32263227632&#"#"'&#"#"'&"#'322632327632&#"#"'&#"#"'&#"#'hBr, n76rU**zl^?^3:S98;7SU78lV4@t*n7697U+)|l^?]1=U79:6TU7878S4 (FFFF$24LJNDFHFGb &FFFF"25LLMCFFGF`!5!37!!'/"Ҥ"- ~S'*PE3צ4Btb6 2bfh8HyOFP&#"3#6767654'&&'&'&'&'&5476767>;767676732#"' #"W&.x~:$8+($   " f?3-/462 DHA)7QPGTQP(.'Av ,~uHbA>B7Wp&  $*!"(%%#0;&(6-;OqrqP)P6F,^X&Hd7!!3254'&'&'&'&+';2+#3267>54'&'&'&'&#"47>767632#"'&'&'&_N  !NWWNV68  ()4NW ''86;:**\[{8=>3=> `=>3=> ` 0#''73\ xb$RT4632#"'&'&RL51!# L5.#$ E7J* 5L+  $'6630 \3x$b>#!5p=>3=> `>!5!3D=>p !54'&/76303kF'%22+ -95 #>IMT<2p2 p2>2p2!p >c(B77#"'&'&54767262;254/'7032767654'&'&#"1_[; qrjZrmA"Ds/[K "BGNnKH  rQLg%W Pm}i`5-,:嗗\O_gw63Wmm #}34#" jY-u78ׇ. (<`#s'&54767676323#;#"'&5#5354'&'"&#" #"'&'7327654'&'&'&'&'&'&'&'&547632/5@K !uFF;<``"3 *:6Qt$ !  112-+$lk\_%45[e::"'/&?*2/""dg^# **.*4 jY-u78ׇ*4"zNH&  !'/6AZYCEnC$$00U)"  $#.1;KM%#5553% @N++㯭 y  !5!5N2@jP+  <!#' i3h #55#nEy #55%5%50P=J}JJJBZ3 3#BddBX<"^ !!!5!!5^OPlB 73!#5!57!!5!!B z{{(pg<(   $   6 327$~~<..9cc..c҅(~~$c-k-.ӅPccd !!!!5!!Plzݍ:[.6 !''%8p2pp1 p4!O!!OJ,0'654/ 7FԮ . FDŽ5{{J9wOiElJA"p'}8@0Y[) )3!!!!!!#!5!5!5!5!5!ɘ``````˜b".   $  zRh"" zh"&-<'!2'67654!"ĞǮnmJۗkh5PSRIE898:#S %%RV Qhէ2/{d!&'&543267654&%ňB䡢ΐ]_:"˽(^_a|~;;4 #  WT 333# #T+P3J 3 3 # #Jjc;˾^)'J733Px"!#!x8Wr 7%5%/ S$!6ї5zuY '7s`Ũbki`ŨbkX!3!3BPPx !3!3!3۝CBPPP_"647632#"'&'&_ -&<@+'- 2# +@$ _"647632#"'&'&_ -&<@+'- 2# +@$ _"647632#"'&'&_ -&<@+'- 2# +@$ _"647632#"'&'&_ -&<@+'- 2# +@$ iq$&$7$9+$Y\$Z$$$$(5)*7.22$273$w7$7Xy9$ 9(9H:$:H<$B<D??qDYHWIDIQIRIWIXI\JMuMMPR[TMUH\Mu2RY29RY29RYl lm37+%  1x   @O  # Ah  5T! U km#|  4      J3      b & & "Created by Thatcher Ulrich (http://tulrich.com), Karoly Barta (bartakarcsi@gmail.com) and Michael Everson with FontForge (http://fontforge.sf.net) This font, including hint instructions, has been donated to the Public Domain. Do whatever you want with it. Created by Thatcher Ulrich (http://tulrich.com), Karoly Barta (bartakarcsi@gmail.com) and Michael Everson with FontForge (http://fontforge.sf.net) This font, including hint instructions, has been donated to the Public Domain. Do whatever you want with it. TuffyTuffyRegularRegularFontForge : Tuffy Regular : 14-6-2012FontForge : Tuffy Regular : 14-6-2012Tuffy RegularTuffy RegularVersion 001.280 Version 001.280 TuffyTuffyThatcher Ulrich, Karoly Barta and Michael EversonThatcher Ulrich, Karoly Barta and Michael Eversonhttp://tulrich.com http://tulrich.com http://tulrich.com http://tulrich.com Public Domain Public Domain All Typographic FeaturesFonctions typographiquesAlle typografischen MglichkeitenFunzioni TipograficheAlle typografische kenmerkenLigaturesLigaturesLigaturenLegatureLigaturenFractionsFractionsBreukenAll Type FeaturesToutes fonctions typographiquesAlle AuszeichnungsartenTutte le FunzioniAlle typekenmerkenCommon LigaturesLigatures UsuellesNormale LigaturenLegature pi ComuniGemeenschappelijke LigaturenNo FractionsPas de FractionsKein BrucheNessuna FrazioneGeen breukenDiagonal FractionsFractions en DiagonaleDiagonaler BruchFrazioni DiagonaliDiagonale breuken2  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~uni007F softhyphenuni00B5AmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflex Cdotaccent cdotaccentDcarondcaronDcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflex Gdotaccent gdotaccent Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonekIJij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflex Tcommaaccent tcommaaccentTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongsuni01E2uni01E3 Scommaaccent scommaaccentuni021Auni021Buni021Cuni021Duni0250uni0251uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0259uni025Auni025Buni025Cuni025Duni025Euni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni0268uni0269uni026Auni026Buni026Cuni026Duni026Euni026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276uni0277uni0278uni0279uni027Auni027Buni027Cuni027Duni027Euni027Funi0280uni0281uni0282uni0283uni0284uni0285uni0286uni0287uni0288uni0289uni028Auni028Buni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni0293uni0294uni0295uni0296uni0297uni0298uni0299uni029Auni029Buni029Cuni029Duni029Euni029Funi02A0uni02A1uni02A2uni02A3uni02A4uni02A5uni02A6uni02A7uni02A8uni02A9uni02AAuni02ABuni02ACuni02ADuni02AEuni02AF macronsub gravecomb acutecombuni0302 tildecombuni0304uni0306uni0307uni0308uni030Auni030Buni030Cuni0310 dotbelowcombuni0324uni0325uni0327uni0328 brevesubnospuni0331uni0370uni0371uni0376uni037Auni037Buni037Cuni037Duni037Etonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammaEpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsi IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdanuxiomicronrhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonosuni03CFuni03D0theta1Upsilon1Upsilonhooktonosuni03D4phi1omega1uni03D7uni03D8uni03D9uni03DAuni03DBuni03DCuni03DDuni03DEuni03DFuni03E0uni03E1uni03E2uni03E3uni03E4uni03E5uni03E6uni03E7uni03E8uni03E9uni03EAuni03EBuni03ECuni03EDuni03EEuni03EF kappascriptuni03F1uni03F2uni03F3uni03F4uni03F5uni03F6uni03F7uni03F8uni03F9uni03FAuni03FBuni03FCuni03FDuni03FEuni03FFuni0400 afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061uni040D afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097uni0450 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109uni045D afii10110 afii10193uni048Auni048Buni048Cuni048Duni048Euni048FGheupturncyrillicgheupturncyrillicGhestrokecyrillicghestrokecyrillicGhemiddlehookcyrillicghemiddlehookcyrillicZhedescendercyrilliczhedescendercyrillicZedescendercyrilliczedescendercyrillicKadescendercyrillickadescendercyrillicKaverticalstrokecyrillickaverticalstrokecyrillicKastrokecyrillickastrokecyrillicKabashkircyrillickabashkircyrillicEndescendercyrillicendescendercyrillic Enghecyrillic enghecyrillicPemiddlehookcyrillicpemiddlehookcyrillicHaabkhasiancyrillichaabkhasiancyrillicEsdescendercyrillicesdescendercyrillicTedescendercyrillictedescendercyrillicUstraightcyrillicustraightcyrillicUstraightstrokecyrillicustraightstrokecyrillicHadescendercyrillichadescendercyrillic Tetsecyrillic tetsecyrillicChedescendercyrillicchedescendercyrillicCheverticalstrokecyrilliccheverticalstrokecyrillic Shhacyrillic shhacyrillicCheabkhasiancyrilliccheabkhasiancyrillicChedescenderabkhasiancyrillicchedescenderabkhasiancyrillicpalochkacyrillicZhebrevecyrilliczhebrevecyrillicKahookcyrillickahookcyrillicuni04C5uni04C6Enhookcyrillicenhookcyrillicuni04C9uni04CAChekhakassiancyrillicchekhakassiancyrillicuni04CDuni04CEuni04CFAbrevecyrillicabrevecyrillicAdieresiscyrillicadieresiscyrillic Aiecyrillic aiecyrillicIebrevecyrilliciebrevecyrillic Schwacyrillic schwacyrillicSchwadieresiscyrillicschwadieresiscyrillicZhedieresiscyrilliczhedieresiscyrillicZedieresiscyrilliczedieresiscyrillicDzeabkhasiancyrillicdzeabkhasiancyrillicImacroncyrillicimacroncyrillicIdieresiscyrillicidieresiscyrillicOdieresiscyrillicodieresiscyrillicObarredcyrillicobarredcyrillicObarreddieresiscyrillicobarreddieresiscyrillicuni04ECuni04EDUmacroncyrillicumacroncyrillicUdieresiscyrillicudieresiscyrillicUhungarumlautcyrillicuhungarumlautcyrillicChedieresiscyrillicchedieresiscyrillicuni04F6uni04F7Yerudieresiscyrillicyerudieresiscyrillic Bdotaccent bdotaccent Ddotaccent ddotaccentuni1E0Cuni1E0Duni1E0Euni1E0F Fdotaccent fdotaccentuni1E24uni1E25uni1E2Auni1E2Buni1E34uni1E35uni1E36uni1E37uni1E38uni1E39uni1E3Auni1E3B Mdotaccent mdotaccentuni1E42uni1E43uni1E44uni1E45uni1E46uni1E47uni1E48uni1E49 Pdotaccent pdotaccentuni1E5Auni1E5Buni1E5Cuni1E5Duni1E5Euni1E5F Sdotaccent sdotaccentuni1E62uni1E63 Tdotaccent tdotaccentuni1E6Cuni1E6Duni1E6Euni1E6FWgravewgraveWacutewacute Wdieresis wdieresisuni1E8Euni1E8Funi1E96uni1E9EYgraveygraveuni1EFAuni1EFB alphalenis alphaasperalphalenisgravealphaaspergravealphalenisacutealphaasperacutealphalenistildealphaaspertilde Alphalenis AlphaasperAlphalenisgraveAlphaaspergraveAlphalenisacuteAlphaasperacuteAlphalenistildeAlphaaspertilde epsilonlenis epsilonasperepsilonlenisgraveepsilonaspergraveepsilonlenisacuteepsilonasperacute Epsilonlenis EpsilonasperEpsilonlenisgraveEpsilonaspergraveEpsilonlenisacuteEpsilonasperacuteetalenisetaasper etalenisgrave etaaspergrave etalenisacute etaasperacute etalenistilde etaaspertildeEtalenisEtaasper Etalenisgrave Etaaspergrave Etalenisacute Etaasperacute Etalenistilde Etaaspertilde iotalenis iotaasperiotalenisgraveiotaaspergraveiotalenisacuteiotaasperacuteiotalenistildeiotaaspertilde Iotalenis IotaasperIotalenisgraveIotaaspergraveIotalenisacuteIotaasperacuteIotalenistildeIotaaspertilde omicronlenis omicronasperomicronlenisgraveomicronaspergraveomicronlenisacuteomicronasperacute Omicronlenis OmicronasperOmicronlenisgraveOmicronaspergraveOmicronlenisacuteOmicronasperacute upsilonlenis upsilonasperupsilonlenisgraveupsilonaspergraveupsilonlenisacuteupsilonasperacuteupsilonlenistildeupsilonaspertilde UpsilonasperUpsilonaspergraveUpsilonasperacuteUpsilonaspertilde omegalenis omegaasperomegalenisgraveomegaaspergraveomegalenisacuteomegaasperacuteomegalenistildeomegaaspertilde Omegalenis OmegaasperOmegalenisgraveOmegaaspergraveOmegalenisacuteOmegaasperacuteOmegalenistildeOmegaaspertilde alphagrave alphaacute epsilongrave epsilonacuteetagraveetaacute iotagrave iotaacute omicrongrave omicronacute upsilongrave upsilonacute omegagrave omegaacutealphaiotasublenisalphaiotasubasperalphaiotasublenisgravealphaiotasubaspergravealphaiotasublenisacutealphaiotasubasperacutealphaiotasublenistildealphaiotasubaspertildeAlphaiotasublenisAlphaiotasubasperAlphaiotasublenisgraveAlphaiotasubaspergraveAlphaiotasublenisacuteAlphaiotasubasperacuteAlphaiotasublenistildeAlphaiotasubaspertildeetaiotasublenisetaiotasubasperetaiotasublenisgraveetaiotasubaspergraveetaiotasublenisacuteetaiotasubasperacuteetaiotasublenistildeetaiotasubaspertildeEtaiotasublenisEtaiotasubasperEtaiotasublenisgraveEtaiotasubaspergraveEtaiotasublenisacuteEtaiotasubasperacuteEtaiotasublenistildeEtaiotasubaspertildeomegaiotasublenisomegaiotasubasperomegaiotasublenisgraveomegaiotasubaspergraveomegaiotasublenisacuteomegaiotasubasperacuteomegaiotasublenistildeomegaiotasubaspertildeOmegaiotasublenisOmegaiotasubasperOmegaiotasublenisgraveOmegaiotasubaspergraveOmegaiotasublenisacuteOmegaiotasubasperacuteOmegaiotasublenistildeOmegaiotasubaspertilde alphabreve alphamacronalphaiotasubgrave alphaiotasubalphaiotasubacute alphatildealphaiotasubtilde Alphabreve Alphamacron Alphagrave Alphaacute Alphaiotasublenis iotasubscriptpsili perispomenidialytika_perispomenietaiotasubgrave etaiotasubetaiotasubacuteetatildeetaiotasubtilde Epsilongrave EpsilonacuteEtagraveEtaacute Etaiotasub psili_varia psili_oxiapsili_perispomeni iotabreve iotamacroniotadieresisgraveiotadieresisacute iotatildeiotadieresistilde Iotabreve Iotamacron Iotagrave Iotaacute dasia_varia dasia_oxiadasia_perispomeni upsilonbreve upsilonmacronupsilondieresisgraveupsilondieresisacuterholenisrhoasper upsilontildeupsilondieresistilde Upsilonbreve Upsilonmacron Upsilongrave UpsilonacuteRhoasperdialytika_variadialytika_oxiavariaomegaiotasubgrave omegaiotasubomegaiotasubacute omegatildeomegaiotasubtilde Omicrongrave Omicronacute Omegagrave Omegaacute Omegaiotasuboxiaasperemspacethreeperemspacefourperemspace thinspace hairspace hyphentwo hyphennobreak figuredash horizontalbaruni2016 quotereverseduni201Funi2023onedotenleadertwodotenleaderuni2027uni2031minutesecond exclamdbluni203Duni203Funi2042uni2043uni2047uni2048uni2049uni204Buni204Cuni204Duni204Euni204Funi2052uni2053uni2056uni2058uni2059uni205Auni205Buni205Duni205Euni2070uni2071uni2072uni2073 foursuperioruni2075uni2076uni2077uni2078uni2079uni207Auni207Buni207Cuni207Duni207Euni207Funi2080uni2081uni2082uni2083uni2084uni2085uni2086uni2087uni2088uni2089uni208Auni208Buni208Cuni208Duni208Euni2090uni2091uni2092uni2093uni2094uni2098uni2099uni20A0 colonmonetaryuni20A2lirauni20A5uni20A6pesetauni20A8uni20A9 afii57636dongEurouni20ADuni20AEuni20AFuni20B0uni20B1uni20B2uni20B3uni20B4uni20B5uni20B6uni20B7uni20B8uni20B9 centigradeIfraktur afii61352 weierstrassRfrakturuni2126 estimatedalephonethird twothirdsuni2155uni2156uni2157uni2158uni2159uni215A oneeighth threeeighths fiveeighths seveneighthsuni215Funi2160uni2161uni2162uni2163uni2164uni2165uni2166uni2167uni2168uni2169uni216Auni216Buni216Cuni216Duni216Euni216Funi2170uni2171uni2172uni2173uni2174uni2175uni2176uni2177uni2178uni2179uni217Auni217Buni217Cuni217Duni217Euni217Funi2180uni2181uni2182uni2183uni2184uni2185uni2186uni2187uni2188uni2189 arrowleftarrowup arrowright arrowdown arrowboth arrowupdnuni2196uni2197uni2198uni2199uni219Auni219Buni219Cuni219Duni219Euni219Funi21A0uni21A1uni21A2uni21A3uni21A4uni21A5uni21A6uni21A7 arrowupdnbseuni21B0uni21B1uni21B2uni21B3uni21B4carriagereturnuni21B6uni21B7uni21B8uni21B9uni21BAuni21BBuni21BCuni21BDuni21BEuni21BFuni21C0uni21C1uni21C2uni21C3uni21C4uni21C5uni21C6uni21C7uni21C8uni21C9uni21CAuni21CBuni21CC arrowdblleft arrowdblup arrowdblright arrowdbldown arrowdblboth universal existentialemptysetuni2206gradientelement notelementuni220Duni2210 asteriskmathuni221Buni221C proportionalangle logicaland logicalor intersectionunion thereforesimilar congruent equivalence propersubsetpropersuperset notsubset reflexsubsetreflexsuperset circlepluscirclemultiply perpendicularuni22C4dotmath integraltp integralbt angleleft anglerightuniA746uniA747forintbrevealtg_yt_yc_t f_icircumflex f_idieresisf_igravef_iacutef_f_icircumflex f_f_idieresis f_f_igrave f_f_iacuteuniE118uniE119uniE11AuniE11BuniE11CuniE11DuniE11EuniE11FuniE120uniE121aalt agravealt aacutealt abrevealt atildealtacircumflexalt adieresisalt aogonekaltaringalt amacronaltxaltuniEFA0uniEFA1uniEFA2uniEFA3uniEFA4uniEFA5uniEFA6uniEFA7uniEFA8uniEFA9uniEFAAuniEFABuniEFACuniEFADuniEFB0uniEFB1uniEFB2uniEFB3uniEFB4uniEFB5uniEFB6uniEFB7uniEFB8 j.dotlessuniF8E5uniF8E6uniF8E7uniF8E8uniF8E9uniF8EAuniF8EBuniF8ECuniF8EDuniF8EEuniF8EFuniF8F0uniF8F1uniF8F2uniF8F3uniF8F4uniF8F5uniF8F6uniF8F7uniF8F8bracketrighttpbracketrightexbracketrightbt bracerighttpuniF8FDuniF8FEuniF8FFlongs_ts_tu10900u10901u10902u10903u10904u10905u10906u10907u10908u10909u1090Au1090Bu1090Cu1090Du1090Eu1090Fu10910u10911u10912u10913u10914u10915u10916u10917u10918u10919u1091Au1091Bu1091Fu1091Eu1091Du1091CU~       !! #" >> ?? @@ CA ^^ __ `` ca gdkh qm srutvv zx {{}    ƀ   >>     $" 42 @? EA \F `]aa bb gc hhyi zz}| ~          @ AAaB bb cc dd   04 8 F~ JJ$WW&\\(??ij( D hh&??????~d DF II   ?R?S?T?U?Z??\?ÿ?^?ƿ?`?ɿnolmrspqɉo1pPySDL2-0.9.3/sdl2/test/resources/tuffy.ttf0000644000000000000000000052044412260256443015154 0ustar FFTMW6[OS/2' `cmap% (l Jcvt e%feat@gaspglyf aP=<head6hhea T$hmtx+ˑrkern2Q0N4locaܷ%|maxp2x morx;gXname ]P ;postn^Z?propJ'GGJv_< 8x D 8e D @.A33f R PfEd = - Dhg5zhd~$)Z!~Ngbmg(pdppmfqpXpppophpqqKTBX\9X)HydyvyzySdytqyQyyy5\KyZ\My7-XyP(TJL-dr+~X&<TLIb}I((fI`f(xR^D5(xZZp}?5\5(P`TX?VJ1Z+L)mh;m^V1D3&<~yu1.b00/@@ R R R RlSxvyvyzzb 5\5\1f1f1fAl`yyL1\TT ^ ^ ^ ^TVblllxsRff&p&p$pwVx((x(@T@T@TdLdEdLdFyIbjvybvybvybvybvybSdISdISdISdIy*uuI{tqyz$yQwQyQyQyqQyyy$gnl5\f5\f5\f\fMyMyrMy 7-`7-`7-X7-`XfXfX4yxyxyxyxyyf(T^DLxL-dZ-dZ-dZ\^7-`Xf00jZZebbzb8essIR ((~(~p4=Xpnplibf70d:ppbb`Vff(22R^DRYZZZ$999e5\\ebf)7y`99ftff}"LBy%%&bL u?1A8byyygeeeq!LH_5:])NpHyKyxvy-dy5\y{yyn5\nKynXB_JrpNBZ(vpvZoRZi(vpdpZ(J(vR3Z(ZZZ(xv7JZ7_vZv7yopdT6 ~2Q5\Zd2ezyH([(v~N**Ky((s7-7-Zm4 2QZepdee1dyy dddJXJ8J?87-tq>EIyyE:HJ^JCJ\OJXLfqyyyxTyy5\yKydX_Jyby y(yKyd}yjZ\<^b^a(z(zyEbfZ(yeR(J0d5y(}}z 3eaubb(<^e`vH|X(y(z(J(yy(zKyKyJ\<^Jmg7c& /@"9T9Tg~y q>?Zd%dd01D3A0r02:-NF|Pj@<3jB01D3A0r02:-NF|Pj@<3T?T'Z*4B  u@Dd4*~nO$JA+)+L+9"yKyMyN1RH^L^3^A"2502X{D{\{Z{,JJ"JQydyyyyyyRHRRlRy555~e>y&dedBy&z0xxx4444xxxxxxxxxxxxxHH4xZoxxxxxJxxxxx U U HRvy^xxvvm|:nnz@DIb6OOyy\?B?Bhmhm|:|:p_pdpd^^"RR9fd99~zys:fe}}}d }}}}ppLppjpVpopvpTpTpvZZZZZZZZZZL&E(E("*wb>Lk*||www^N"xhtH^==R=d22cl}R`o vyB"4Bt-dNn4q,"O)"&#(TJx____,$ @, $z %(.1qv~_%+;IWcoEMWY[]}   ' 3 : = ? D I O S V [ ^ !!!!!!"!&!.!5!!!!""" " """" "+"4"<"E"H"a"e""""""#!#*%ʧG!Yh P #'.1pvz $*4@VZj HPY[]_    0 9 < ? B G K R V X ] p !!!!!!"!&!.!5!S!!!"""" """" "'"4"<"E"H"`"d""""""# #)%ʧFPha-WSPKJIHb\XVTRPONMLJIHFECB>;65-('&$"! pjc`5430/+)(" @9ߚ^$$e$\#.#    cBCEPK  #%'(..11pqvvz~_  $%"*+$4;&@I.VW8Zc:joDJPRSTVXn EtHMPWYY[[]]_}"58  A D  F  'M 0 3] 9 :a < =c ? ?e B Df G Ii K Ol R Sq V Vs X [t ] ^x p z   !!!!!!!!!!!"!"!&!&!.!.!5!5!S!!!!!!!0""5""6"" 8" " ="">""B""C" " H"'"+I"4"4N"<"<O"E"EP"H"HQ"`"aR"d"eT""V""Y""[""\""]""^# #!`#)#*b%%dFGegi!tPY~hh             !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abUrdeiWxpkvjRGsTUgw6@>Ml|cnCBQ9m}[IJQRMNd:habVyOS]qz!yDXXXX8\(4l <t\  H ` x l @p Ph@lX`$xLxt\(h DhxPh  "|"##|$ $`$%4%&L&'$'D'X(4(P(()*P*++++,,,-..///4/L/d/|///00,0D0\0t0001$1<1T1l11112|222223L4404H4`4x445566606H677D78x8888899|::0:H:`:x:;;,;D;\;t;;;;;<<<4d>|>>>>>? ?$?<?T?l??????@@,@D@AA,AABBB4BLBdB|BCCCDDDDEEE0EHEF0FHF`FFFGG(G@GXGpGH0HHHII,IDI\JKK,KDK\KtKKKKKLMlNNNOXOOPlPPQ Q$Q<QTQlQQQQQQRR,RDR\RtRRRRRSSSxST@U`V<WW(W8XXYZ Z[l\\]^_(_`xa,abcxceefghh|i,j jjkkl4lm0mntoXoppq\rTs0stt`tu(uvvxvwLxlxyz,{{D{||}@}h}}~~t`0hx\Dd< 4PXHXll $T(P|P4,x`$ @lHt $$$d`4Ld((X0LH d8xl@(8LX4p@ňżƸHȠɔtˤ̤ͼΌ\lP,Ҩph 88p$ܴݘݨݸ(d $TpH P@h88xP D08hx|Dp@pPTpttL\tH`x@p|l| ,<L\l ,<L\0`   $ 4 D T d t   d t  T    0   d 40pHH$<T(@P`L\ 8Phx     !"""""#X#$$ $h$% %t%&X&&&&'d($()$)*(*d**++,<,-..l../0001H112<2T2l22223,34`455 5l5566 6@6`6666677(7H7`777778808P8h888899909P9p9999:: :@:`:::::;;0;P;p;;;;<< <@<`<<<<<==(=H=h=====>>0>H>h>>>>?? ?@?`?????@@0@P@p@@@@AA A@A`AxAAAAABB B8BPBhBBBBBCC C@C`CCCCCDD0DPDpDDDDE EHEpEEEEFF0FPFpFFFFGG G@GXGxGGGGHH@HhHHHHHII,IDI\ItIIIIJ0JJKhL\L|LLLLMMM4MPMhMMMMMMNN,NLNdN|NNOXOPPQQ$QDQ\QtQQQQQRR,RSSTT T8TPThTTTTTU<UUUUUUUUUVV$V@VhV|VVVVVVWW8WWWXXY,Yp[]]l]^^@__````blcdeef$fXfglghijkklmxnn0noopq qDr rrss@sst@ttuvxvwLwx xyyyzzLz{ {|P|}$}h}~,~ Dt(<hdPp,htL LL`d@h(x\|DP p@$XXph 4\$P|XT0` <l,<4 ,LlT”TÔ@ĄdŜƀưǔX\Ʉɨʰ ̘̼pXϔ(8|Ѱ|X(\֠LtטTؤL$ܰ݀߸dd0LpT0H`P$pPP|PDpHplhldHpp @     X        t   L  Lx ,h8xDdU./<2<2/<2<23!%!!D $hUDgB #.546324632#"&'&#");'(=@,':?,':"!'77%-?1$,?0% ;&46;2#"&'4&%46;2#"&'&+'"+)"Dv$(v$( 5{!#!#!5!!5!3!3!!!\\Vii#RaaR{{e/8?3.' #5.'7.5467>54&ŁВ}#wKL'D%7$ ӴQ~fL- ;5O-S|k9ԝ]t7.54>32+'n_c[eaw|!Jg[ZL6RY(Ro_t3LLgiv4su]:Hy^P]; #u`lc46;2#"&'&+)"Dv$( ) &5473n{suTIUZ #654'3 tjyTJ]!y7#"'&54?"&5463'&547632763272#'#"'q+& 0*" (*om*( "*0 &+( (#)!)& (( &)!)#( (NB !3!!#!N34̍7Ɏ7g#>%'65"&'&54632>!8H':@,':^%M:?#*gK/% -?1$m3!!m[g>74632#"&'&g@,':?,':^-?1$,?0% T3#3͞d&4>32#"'&732>54'.#"dByo.mܓ."mPI&!kPL(ך|ڈ ڄxpms#73#F\Pm/'6$32!!4>7>54&#"'AxlP/*@:M3C *b`?u4PypG ?"=#-kdV7 GeY3bOO8>#,\ny/^\2*0%96F%q /?32654.+532654&+"'>32#"&q&S9_s=Nba_Py 5{euBN'&TM3}/RhIwK(}pdUI@i^mRM @]GX 3##!;!`^ }ts#V&"'!!632#"&'732654'.\!;1%$^B[# kч.T߄ ' KT7¤?>݉Ţ,'r)4'.#"326632#"&'&54>73oqiEI@! Bse /";N%gu!f~ɛ+3N~N͓*-:snDd Ho7 #!57նPh/@%2654'.#"32654'.#"2#"$'&54>7&'&546Fs`oewU# 3SQ) q" n&oVbqQa -n'l((w͠4,NY9V'0*32654'.#"#"&'&54>32#%qiI@! )PmQ 1A#fv"fɛ2->~pW3Γ,+:rr>mqH'  q#H&  T% 3 PdXBfbb!!!!B  \%# 3#eZ9&6#54>7>54&#"'>324632#"&'&=6(E,|RHV~K`6,@,':?,':-O7<#93(A'|Z|92`aG,W.-?1$,?0% )FV%# &54$32#"&'#"&'&5463232654'.#"32632654'.#"M^7`Ј6Tb-7x(,OzȎv R38f osc.[]uKZmqBTfWRP_]wC@K^89+54'.#32>54'.#"&'!2#2#!?FqK4S}F+ %HU˱vo? WHvK- *KcZ#!7KR,#^ud'!0C9#<9!4Ye:*#u5X^3$$"BWKL5!d)#".54>32.+"3267Lp_wȋa-.awLbN1hhi87#!!2*JcUi0ODOAs[4jTχpzy !!!!!!y0gy !!!!#y0\d-".54>32.#"32>5!5!#P-bwI:jgi99igFvP53#"&'&q o\Fͥ&45}ggGy 33 ##yxϼsy3!!yeݍy 33 3##yϙTT!P\Ly 333#y䝑wPZ\34'.#"32>%4>32#".'&H=^V]\==^U]\>&Z{yƆV'Z{xƆVvmStAPVokRq@MzUeΞc\ltmdʚ`Zkjy 3 4'.+';2+# ,SbΞ BՊΞ#)E?#-(WsB\94'.#"3267'764>32'#".'&PAaVde5=a[6{"Xg ([yb|b=U?ZLnd}b=rjVuAi{mdRvC)"teΞc?hVokRyu54&+ ##;2^R2Sמ3Ʀ"5LF(|wx- 9732654.'.54632.#"#"&-s,G>Y7S,=S73)ps..O8b0JaF@!ۋGWr)L::&+ 1:Ld<êHq|^)C5''& &;FYrBTX!!#!XD7##y3#"$'&5332>5-#zKe9g+rV?~ЇP3#3GBPT 333# #T+P3J 3 3 # #Jjc;˾^)'JLd3 3#LddBX<d!!!!Pliݍ#!!#3u`Z\!31 53#5!`@}5#'#35}VX5!XB獍<.#"'%&'&54767632       TbB )"32654&'254&#"'632#=#"&546ol`{h uEz"NۋgFcgcfm1`+"hm{1Χ">32#".'#&"320Fd>e\..\f>dF-蠠ts-GA#]poŤ`#@E-LlF.#"32>7#"&54>32xF+O6! z6qu(PmTr6)2c#60MZ~Vj=zaI 3#5#".54>3232654&"*we\..\e>dF0stRat`npš]#AG-pbF"!.#"3267#".>32 pLw<[e I }##5354>32.#"3;X`':M+m((9V325332654&"FsM[e<\h-Fd>RZ>.\e>dF0Lstck;Agt8Wu!-E@#@lXpš]#AG-p!#3>32#4.#"qɗ32>32#4.#"V+K3ژ/1L.tm+A+#HnrK/a1&/@$ihs;^dH<gN!#3>32#4.#"qɗ32#".732>54.#"f9kia_Ɍa BoJIoB 7ab7wʗUZyDDyZyuuTN">32#".'#&"320Fd>e\..\f>dF-蠠ts1-GA#]poŤ`#@E-"I? N *3"&=#".54>325332654&"4BEON0d[..\e>dF0Lst=5u͸?V-anpš]#AG-pN&#"#3>32P1>Y{5qR*xw1Yy`HJ:.54672&#" #"&'732654.+ȔQR0 6Pu")( ?"?%6!&ؗ&h\et&G? :Ab;-JG%zOG$  " .0="pCH`U(@-fP+#53533#;#"&5􎎗uFFx-uox13#5#"332>5qɗ=#"332>53L{MՖjg1^R2qɗ&67>7&#"327.'&'&'&Z@T! ,:F'+Z <.<"Y,'F:, (f}w"  P-M+>   " '@W} 33}R=532676=4>7&'&=4'&'.#"5@T! ,:F',Y <.?"Z+'F:, 'i|"  T+Q-9  " %R?3\&>3232>7#"."?%&&800:&-92 *% ?403,'-8 -, ,(  -- 0\I\#5476767676767>7>?>767>767>767654&#"'6763247632#"'&'&4'&'&'&'&#"3276767676%47676767632#"'&'&'&'&n $ lW;/12f VVvQEF,.- | 0.FCX^//!0.GFT^IK-- ! ,+C@ge{zbdBA-,,/?CefzxcbDA-+%cf       W` V(sNN@BYD42-  spOIC<9" P@?UTUrhKJA;9 '(;753&#"327#}k 8]`4cdZPkU~pPRZ< w,9L|M. W_Pz[!&S]jZ`4T''#5332.#"!!!>7!>7j^I: g ^.PF62 ; TBTktFdQ}N! s ' *?w-w132654'.#""'#53&'&547#536253#3# cAKi bALidPP+;yPPy&B>QjK>Qj779F$gQ{77{4B%hWJu!5!3 33!!!#!5!DX1Ϙ7D6ׇLZ#53鏏{z+h,;632#"&'7;26754"#"&'&54>32.+"4'.#";2& ];S Ga - " N[avFF^!Q% Ö0,Wd #pX 7:nxH\S{QL4!4632#"'&'&%4632#"'&'&#8&"28& )8&"28& &8*! '8!&8*! '8!)7(8#"&'&54632&"327%32654'.#"432#"&'&uCSJqyV[;N"L84!.sssu bC\GUy;R8& ,D%o'nŖ2)Ŗ+mm 2"3264'&#"'&547632&'&#"'7632#L0:0(:;Y;:<=V:+0AI\[=54'.#"4>32#".'&%32>54&5.+'32#'# Qlv;DtH Vpu5EtGu?gE& kʡ 3"/0]KRRq -dAR2,JuG$5aZ.(KzH&1^_ftR&߰96}U{8q "N:> ,a)!![)j1=32654'.#"4632#"&'& N4=S N4=Svm^m^3AW?3BXBktY ltY'HPDPB'767632!!5476767676?>?4&#"ʆ JIX&D !.   ( _ !. <&( #5O87:,-0 ,#406 '!"!5<.3S>7327654'&'&'&+5327654&+"'767632#"&'3 < 8&% JT"4"  9:H885##QRtHs+!(!!6($2 > >%%65A1)'&$-rIJXJ<.%632#"'&'&5476L      ufh%#332>53#5#".) $.N5%.u:+'" #J+6L8'@QQ&b9D$yu,23"3"&#.'&54>;0GM*$)A/%=^^A0 s  !!6O2!5!   ,7O1*)b`3neE'{uqJ>54'.'7u' @8*J  "  #8>H 81,1@#73#{a.(:-&327654'&'&#"47632#"'&'& ('4<** ('4<**vLLn_LNl_GF/1"!+,?2"!,+ClKKtYlKL:9Zb;^ #!#^"#"#0 %3##5!335#73##3v^^Wc{a) W6N0BHL%'767632!!5476767676?>?4&#"#73##3N JIX&D !.   ( _ !. <&( #g{a)5O87:,-0 ,#406 '!"!5<. /=GJN732654'&'&'&+5327654&+"'767632#"&'3##5!335#3/ < 9J JT"4"  9:H885##QRtH7^^Wc)s+!(B6($2 > >%%65A1)'&$-rIJXJW6}"{@&$C@&$vRq'A$ RJ'a$ R'j$ R'rf1$ Sg!#!!!!!!53OFF{JxX'z&y&(Cy&(vZ'A( 'j( 7&,CTH&, vhIf'A, 9'jZ, #53!2+324'.+!F}82⛝(,bhE^S5'a+1 \&2C\&2vfs'A2 fJ'a32 f'j2 lJ7,-c,`,9%#7&'&54>3273#"'32>54'&' &#"J|/6[xczaE55\wc5VoYZ=#OIXYZ<)FokRvD2EmtRsB;LzTtod`&O}Txdy&8Cy&8vw'A8 'j8 Ld&<v 2>54'&!3 ##/WlC.E7gc&;b@&(SX>!\]F>32!"'732>54'.+"5;2>54'&#" #67,DXQ'+^eNPj[ ( ?d_?&$*Y)JsO3!  +, 8cF:" ,GnA'h5{ $;`@o;xJ'%#CP7bzY Tb=&DCTb=&DvO^l&AD ^l'ayLD ^l'j^D ^lV'rD T`F`j"32654'.>32!32>7>7#".' #"&'&546326&74'&#"'>32!&'&#"i_"\mf:zd!aV!.'8m'@5$, %'3 ȘWR$ "AP'N& %'"0^t /:X/Zl1$h(Ob4_Y^} - IG]~+&7nk 9 %*% 7035,6+&'f  YsG9BmuV]vF'z F b=&HCzl=&H vcl&A5H l'jH /=3##"'%&'&54767632     11  ;=3#%632#"'&'&5476    11  s# 3##'#31^Vb%3#4632#"'&'&%4632#"'&'&8&"28& )8&"28& 1&8*! '8!&8*! '8!R>32654'.#"#"&'&54324'.''7&#"'6327 Iqg;h9C ݠ)G/30 h8cGY)J7`.2u׆%sjMo$!B&ҸHP$. !(^1dFm'aXQ f<&RCRf=&Rvp&A3R p'a/R p'jR w[#4632#"&'&4632#"&'&!!X@,':?,':@,':?,':[-?1$,?0% 3-?1$,?0% VJ 1 32>54'&'&#"7&'&54>3273#"'ATEj< ZASAh>! s7__1q9_c0DNNVD2?L{LWG+%YwZVKOZuQ\NNx=&XCe=&X*v&A1/X 'jX x?=&\v\,!#3>32#"./4'.#"326/DU4":[^.S6( fD5hU5Jr)54ȢXeZkA,+]Rp3232654&" '2(e*we\..\e>dF0st$#$ Q>& # Rat`npš]#AG-pj##53!2+324'&'&+! |ݝ2KL⚝(ts+ia˥_`F^SooR:327654'&"33##5#"'&'.'&547>32#53MLtuOPPOLL"#2/BPEB.,@ ^f?15 &vttvtsrq˅e*&"  75PTUne`\$ $,%y'q[(b)&qHy.&(b'|Hy'(b'DHy'(bF'HyB&b(b'HdB'*I?'Jd.&*I?'xJd'*I?'dJd?'*I?1'lgJyJB&O+B&K*3!33##!##53!!y88kOO3kf7^ff*!##5353!!67632#4'&'.#"ccPQsRBE02fDF23"[;323276767"'&'&'&'&#"F% # !1 !#B"$B1W  &   /'q,C(3#!![1(j.'S,&F|uq&,uq&LC&;,#13#1!%#"'&'&'&=33276767653٘3rRBE0/fDF23"Yg'ZOy'65"&'&547632%3!! '2(e$#$ Q>& #ݍ&'65"&'&5476323"&'&53 '2(dq$#$ Q>& #. KJY% y'y/'y8O ?37!!g}~eh ~}e?373"&'&5ldqmy  KJY#"y'v1:'vDQ y?'v1?N'BQyB&t1'Qg1'gQn6%276=4'&'.#"#367632#0#6gJIfD*b<`w1yqySBC14$HAAPA/JI!_FL:;B"9HKz\F0!"BGhl:DD< l?N3276=4'&'.#"#367632+6gJIfDF25 PQsRBE02#JA@PAJI!ZKO7;B"$9>IKX1[;CE= \'q2f,&qR\.&2f'R\&2f='jR\"=47676767632!!!!!!#"'&'&'&'&.'&#"327\,+C@ge{'<4_T^xcbDA-+ CX^//!0.GFTfAgehfdRO21'--NK_[lm/ P@?UTUrhKJA;9 'fvFJR2?&'&54767&#"476767632632!32767#"'#"'&'&%!.#" 977115Qc@A47STib^_QO214d::MJEF 4gju|_bef00t pKx<\JO:;#"".={>(#:;[_vychIM)*FF.-KJc 1_QO66&'<7d:;GGMN}~lyP'v5='vUy?P'65r?N' UyPB&5 'hU - 'vl6`H='v#V- B&6`J'V-] Zw732654'&'&'&'&'&'&/&'&'&'&'&'&'&547632&'&#"#"'&6767>54'&'&'7-s#$!*0>8!.+  zyyz(USqs * 5>!'2* $!DEmn|z? ' '(GWr)&+  #$%)+5baUVH98|^$   ($'%j6Z[**ba4 876767654'&'&'7C#'4/""deQ)/ 6P;: '( (  lk\_%44\dt"%!  ? -'$#.1;KL,&,$%z''H&    )ZYCEnC$$`U+"   "8& # -uoX!!!!#!5!!XD7YD#:[4+#53533#3#;#"'&5#53􎎗uFF;<u78gyF'8x'\Xy'qt8x'&q Xy.&8x'vXy'8x0'$Xy&8<'X*y'8f1'QXTB':D1'ZLdB&=<x?'\Ld&<jd'v=Z='v]]d'=Z'b]dB'=Z']5476767632&'&'&#"#,+1/(:'%,m ':1>34#")i 4- ##737676767632&/"3V11)-83A.().\(32@1VA@E50  ('&.\r!!!#!!!!!!53\EQGGWzJ^l7V_!!"327654'&'&6763 !32767#"'&'#"'&'&54762'4'&#"'67632!&'&#"]"|6m PX4= P-R- P`3DU+7D_ ]< "jHMU&;PeC .37",*}9B"## 3"cxDHGI.5)gCbD2:43pNJ <2.GgF I6H-  P'65"&'&54632732654.'.54632.#"#"&~!8H':@,':s,G>Y7S,=S73)ps..O8b0JaF@!ۋ%M:?#*gK/% -?1$Wr)L::&+ 1:Ld<êHq|^)C5''& &;FYrBT`HJQ'65"&'&54632.54672&#" #"&'732654.A!8H':@,':l+ȔQR0 6Pu")( ?"?%6!&ؗ&h\et&G?%M:?#*gK/% -?1$ :Ab;-JG%zOG$  " .0="pCH`U(@-X,$fP+%0 qF676767654'&'&'&#"57>54'&#"'6767632ucm^P/-;&M`_I:D M=<5bdw$"?8Z::!"%.?6&F)Vju0Cr8C$7674654'&'&'&#"5767654'&#"'6767632w& /-; #M`^HGI8FM=<5bdw$"?8Y;:!!&.06%L>6;&(@7  ~YXqd=. 76O)tRSRQmTNM.6 9K90 p\YjxB52654'&#""'&'32767#"&=3676767632pHGm`FGIJzhLL tD>=#Nڋ%!537hjmkߊdgDCEEdgCD653`#hm{"ghkjZxB-7&/054763253#5#"32765&'&#"knf !537X@B`HF=?vF36!=YqtmWFϜ!ORFE`:LN!LZxB-%#"'&'&'&'#36320&'&'&#"32765 w735!#fm=!63Fv?=GH_B?Yv 1FWmsˑL!NL`EFRN7G"'&55476767632#.#"67>7632#4'&#"3276wm##94NHM]LP20 \iB42>QEB., /-dMLtuOPPOutLMvqbTS62  "20>99Xt!'(%< 74LJPTTmecQO^8srstvttveF/'67632#"'&'&'&'732654&#"5VUsTJH86)(;:jh=57)2 z +'+E=<)B`>=74HFRSTML '%(Mõ22ZF<J&'&#"67672>32#"'&''67&'&5476767676323276=&'&#<=E5S.9M + 7"`[\72 TI327654'&"33?#"'&'&'&'&5#"'&'.'&547>32MLtuOPPOLLfk$#$*"("(#"#2/BPEB.,@ ^f?15 &vttvtsrql{ f"  $ 24?C*&"  75PTUne`\$ $,I327654'&"/"#5#"'&'.'&547>3247676767632MLtuOPPOLLkf"#2/BPEB.,@ ^f?15 &#("("*$#vttvtsrqf {*&"  75PTUne`\$ $,S?42 $  bF-.#"!546546767632#"'&'7327676rNIFG4gju_`0112_aaOM42͑hi65PN_j'';7d:;LL{~IJ-,NK]_c!0b`F'96327#"'&'&'&54&='&#"3276767654'&ju_rl# 012_aaOM42$9NIFn FGoK<;! ;LdF6 {~IJ-,NK]_c!005'1hi65PUR>_kJ=%#"&547676?&'&'&54767632.+";#"3267k+fee%;T(*- -3CINcMO)d`:A&H=;IH9/("+(IKg?xf==/1"7* &F33247676767632/" MLtuOPPOutLM#":8JFO[NP21 [i##2/AQEB.,@ ^f>25 &#&%) *$#$kfvttvtsrs bTQ75!"21<99Vv!*&"  75PTUne`\$ $,S?42 #  "f {s?N;K#"'&'&'&'3326=#"'&'.'&547>3253327654'&#"#":8JFO[NP21 [i##2/AQEB.,@ ^f>25 &LMLtuOPPOutLMbTQ75!"21<99Vv!*&"  75PTUne`\$ $,vttvtsrsICE"'&'&'&547676767632&'&#"32767676765!5!+hSV57%&03IHXvIH7e*1.PJ?<)&%&97L.61+ .(tA.0LObekOJKKN48""++UW:*(GAQP&ROR?A  )K.%o93=.6,('"(R102I0+&#"&"'&'.'&'&'&'&'&'&5476=673 3'&'32676750)(5      Rbw67    Y07 3C !1n,"X . B TE %276547#"&#&'&576733C8 $!  _ '*2 o'Oqor 1 !$3%U38i0F,#JN!3##"'&'&'&53327676765$rSBC14fDE27NP4Zx!"BGhl_FL:;B"%8:MPS~9!#5476767632#.#"67632#4'&'.#"#";5LHM^42\hOA PQsRBE02fDF23"1bTQ82 @42<99XtI;b[;46    f  {ZKO7;B"#:AFKX4632#"'&'&33###53y8&!8&!5&8! &8!:4V#533?#"'&'&'&'&5Sfk$#$* )%&${ f"  #!13@=2 3!53#5!7Y]]Sꎎ+.3276?#"';#"'&5/"56767632:%$<2 !""!uFF;<0$! *!#%#+.& u78 !X&1%3"&'&5#"'&'&=476736767'3dq$ -8!<ڗ)-mHS7W'%# KJY#"26P7/&_`;(:+(*(h33276767#"'&'&'&5:' m/"%<&14(,-4 i, #43>ntL 3%3"&'&53!5!#"'&'7327654'&'&'dqT$!/7&}~8%POS_`019 KJY#"9  C.BAHāLK/Q54UVJ;:&'N53323#5#"'&'#"&5332 ,H5ژ ($0tJKm *B+NN1=37N.&϶+! DEih;/6+8$<N63323#5#"'&'#"&5332 ,H5ژ ($0tJKm *B+NN1=37N.&5+! DEih;/6+8$<TNN!#4'&'.#"#3>7676767632>32#"'&'&'72=4'&'&'.#"V ,H5ژ ($0tJKm#&%) *$#$kf *B+#N1=37N.a1*! DEihs?42 #  "f {;/6+8$<g>IN5!#3>32#4'&'&'&#"+6726=sRBC1443CF25 $H?CP@f1Zx!"BGhl_FO7:"!"$9>IPS%A :ED; |!l?N6%330#"'&'&'&5054'&'.#"#367632IJgAPAAH#fDF25 PQsRBE02BB!IJ| 
ZKO7;B"$9>IKX1[;(#:;[_vychIM)*FF.-KJc 1_QO66&'<7d:;GGMN}~l7H$H%#"'&5476763!2#"'&'&'&"2767653367675&'&'&#a ! 3/7`112_a a_210`6/3 !Kx<?8!B& } &A!8?:X>=QSpR$<;^]wϵ[;<?32767653#5#"P1>X>=QSpR$<;^]w3[;<UF*?327676533?#"'&'&'&'&5#"P1>X>9fk  $*!"('#!QSpR$<7bQ{  f    64>\[;<N&#"#367632P1>X>=QSpR*<;^]wg[;<TO.&#"3?#"'&'&'&'&=367632P1>X><fk$#$* )%&#QToR+<:_W}{ f"  # 24?"Z;=V747676767632/"3!5"!*) !*$  kfxt?35   f  {V%3!534#'6767632xtxfk  $*!"('# {  f    65=bN'3276767>54&+ ##;2b@93 bpHG{=5 4[h@3'lQP'bN' 327654&'&'&'&#3+33bDC 35DG|FHpqpu54[4 5'OQlOP'4`THJe&'&'&'&'&547672&#" #"'3?#"'&'&'&'&='7327654'&'&'&>'*2/""deR), 6Qt  112-+$lkXfk$#$*"("(#45[e::"'$#.1;KL,&)$%zNH& !'/6AZY3{ f"  $ 24? C$$00U)" h,476767632&'&'&#"#"&'732765,+1/(:'%,m ':<+(41&;J-m (>34#")i 4-32:' m/"%<&14(,( m+N9(/1V<$,-4 i, #43>. i(*DjVh7H476767632&'&'&#"2632&##"'&'&'&5476767673276=,+1/(:'%,m ':# _p<+(41&;%U+; 5=>K*(vX=>34#")i 4-wHPS2D2#5!326767654'&/5!# &'&54767գ~ $A"!nKIn!"#9D~)1`de014!;[_v\JL=o% 26P &uE/ ,bt2& !5!#"'&'7327654'&'&'KT$!/7&}~8%POS_a035l9  C.BCFāLK/Q54UVH=:&($27F !5!&'#"'&'&5054767632654'&'&'327&'&#"HT$!/7&bCYHVNa(!!5- M9V4019OStWrr "'$l9  C.BAHtCb`gSbL"C: P65 -g IhJ;:&'42$ +*)# .,!&}EDZ|9oo^`aIP9..>96/&'&'&5467676324'&'&#" # &1=(:)%J@>OLXyy$$FER~KM 56 S>..9PIab1/oo9>=.-DE}&!,. #&*+94#"'&'732765/ &'&'&'&53= $2>(;(%L|OLX{y$$S|MM 47 T=-09OIb`^po:=>ZEE|&!--)*+ekF@&'&#"327676767#"'&'&'05<&454767676767632<=EZXRX+'+ z 2)75=hj:/ ()68HJTsUV5)122xt* `nvM(%' LMiD[JA;RFH47=>`\%M_4'&'&'&'&#"3276767676%47676767632#"'&'&'&'&%"'&547>32H 0.FCX^//!0.GFT^IK-- ! ,+C@ge{zbdBA-,,/?CefzxcbDA-+6776Z..,+spOIC<9" P@?UTUrhKJA;9 '(;L756($.!/1ZZxZD>+,V43W-%  eJ'J%#0#"&547676?&'&'&54767632;#"32767654'&#"h%;U(*- -3CINMSH86)(;:=;IH9/("+*fAT(&C3X[ZE=/L/1"7* "J346    f  {x7:('56PQf03) 9K4632#"'&&'#"'&'&'&'&=476763232=&'&#"8&&8&&Hg#("("*$#$5!!5- M9 Y'f); "'$5&8(&8o`^2 $  "/P0P65 PAK {F  47b1 373##3{jgh{RhybF3!!yKFG`?O327654'&"3"'&=#"'&'&'&547>32567676767632/"MLtuOPPOLLBFE4KIebPM.0^f?15 &#("("*$#$kfvttvtsrqV;;:͸w0.1/SV^elne`\$ $,$2 $  "f {}9;!5!54767676? 4'&#"'67632!!#? 74 MK~SHyzXLO|L%): >2$ _(C+*)# .,!&}EDZ|9oo^`aIP9..>S?9>#!5!5/&'&'&5467676324'&'&#" !=_ &1=$:)%J@>OLXyy$$FER~KM 56 ?((?S>..9PIab1/oo9>=.-DE}&!,. #&*+C;327654'&"3!5!!!+5#"'&'.'&547>32MLtuOPPOLL {"#2/BPEB.,@ ^f?15 &vttvtsrqt\*&"  75PTUne`\$ $,tY327654'&"3!#"'&'7327654'&'&/!#5#"'&'.'&547>32MLtuOPPOLL$!/7&}~8%POS_a035T/"#2/BPEB.,@ ^f?15 &vttvtsrq  C.BCFāLK/Q54UVH=:&(9[*&"  75PTUne`\$ $,lR^327654'&"3!5!3676767632!'7+5#"'&'.'&547>32!6=&'&#MLtuOPPOLL'e@'E9M -8!o% 26P2T!8\`4*&"  75PTUne`\$ $,53 ,bf+6T#5353!672&#" #!"'&52767654'&'&'&'&'&'&'&'&547#􎎗BTR), 6Qt  112-+$lkӕ;<A^:"'/&?*2/""_,&)$%zNH& !'/6AZY78q.i)"  $#.1;I8-pfhK@#535335476767632&'&'&#"#"&'732765#;#"'&5􎎗,+1/(:'%,m ':<+(41&;J-m (uFF;<>34#")i 4-32&'&#"67672632#"'&'#"'&53276505&'&#􎎗uF(P:(*48UrUW5<=EZ[7;E?G+ 8!32+67276=4'&'.#"#,+1/(:'%,m ':[rSBC14#JA@PAgJIfDE27V>34#")i 4-Zx!"BGhl >CE= |JI!_FL:;B"%8:MPSO337327654'&'&'&'&'&'&'&'&547672&#" #"'&'45[e::"'/>'*2/""deR), 6Qt  112-+$lk\P'+C$$00U)" $#.1;KL,&)$%zNH& !'/6AZYC9Y 33!!d\ B #333##333#Xrqs\Xrqs\z$ciz%ciyJ!#!#!#!#yўkўkvv%N@6767632#32767676=53#5#"'&'&'&=354#%$#$*"("(# fDF23"PQsRBE00f"  $ 24?09O7;B"#:AFKX`=+[;323276767#"'&'&'&'&#"?F% 8 " !1 !"" "$B  &   p+632#"'&'&54%632#"'&'&54$$;:!  :!  Ax"&54763#"'Q "! "8j632#"'&547&# !. GA/167676763223276?+"'&'&'&#"#1 $&(2 #",, 7  %/#&"AT t'  #! *F  8)q3276?3#"&'&'I Ll;23)6KMbX94"!s;:Z6M)*HH@b^b47632#"/&9>:>> 8 >7=d#47632#"/&%47632#"/&9>9>(:?:>> 8 >7> 8 >7)32765054'&'&#"47632#"'&'&LW(OW(uoFQN"oFRL"TN'! RN#(N/o.0L/o.0jQ$&h?&#5b^47632#"/&9>:>>7 > 8=^#47632#"/&%47632#"/&9>9>(:?:>>7 > 8 >7 > 8x})32765054'&'&#"47632#"'&'&LW(OW(uoFQN"oFRL"TN'! RN#)N/o.0M/o.0J654'&'7^4@DE$I8>G \U)J&'&'&54?^4?D3E$I8>H  \U)bt676730"'&'&=37#;EPB#ECCE#BQ1N&*z Do9(&&(9oD p4u!!]y3 30!0!#y^y32 30!0!#y2>y !##33Zwg>74632#"'&'&g@,' ,'^,@$ , $ eF/'67632#"'&'&'&'732654#"e5VUsTJH86)(;:jh=57)2 z +'+~`27H#`>=74HFRSTML '%(Mö)+eF/B&'&#"327676767#"'&'&5476767676324632#"'&'& 72`~İ+'+ z 2)75=hj:;()68HJTsUV5R@,( ,'H9+)M(%' LMTSRFH47=>`,@$ , $ eF'qRH)676#0#&'0'&47632#"'&'& 0   -&<@+'y)   - 2# +@$ w67632+&'0'&  0 )   Lv&jOH %!!#3#67632+&/&%    0 P)   _w6N4632#"'&'&_@,' ,',@$ , $ v &!!!!!!67632+&/&0g  0 )    &3!3#!#67632+&/&۞k  0  P^)   }3367632+&/&  0  P)   :%Mh4'&'&'&'&#"3276767676%47676767632#"'&'&'&'&67632+&/&H 0.FCX^//!0.GFT^IK-- ! ,+C@ge{zbdBA-,,/?CefzxcbDA-+"  0 spOIC<9" P@?UTUrhKJA;9 '(;4HA<63$$9;JLL,! ,-A?hfzycdX  ,.@C{wBA-+ #>  /-HFT\-,! <  0-GCX^II/0 J 3 3 # #Jjc;˾^)'Jp/367676767653#&'&'&'&'&5!0-H$,8*J.- ! ,/?CeEVJGbDA-+rhLJA;7!Q '=L<'fA\JL=;!"'#632767654'&#" 2327676767654'&'&+"1} g{|!%).')&+//25%%DY 4*\W[@A*#z)2"H (5*73|~$'RT-* :03!% #%54D)h'_<32#4'&'&'&#"sRBC1443CF25 1Zx!"BGhlW_FO7:"!"$9>IPSd'647>7632#"'&'&%!32767676%!&'&'&#"d!!x]\orr.76nnts/"IImO@A#% t!FGkNB@&( כ?>؋̭jiڂOd[dc89Z]hA`bab:9]bf=V233?#"'&'&'&'&5fk$#$* )%&$2{ f"  #!13@Z5 33 ##Z0H0PkJ 3'&#'67676303# Rl^3k$#$, + )%& Þ1 f"  # nvu2#%#3303276767653#5#"'&'&'& '4! ,=;u,<=J+lL8@)&#/(&b8#" R^!374# H86)(1wj74HFRST3tD%27630320#&'&#0#"547676767&'&'&54767#5!#;#"jG`B122vyZF1326767654'&'&#"47676763!# &'&"!nKIn!"A@bd@A48QTj 3 1`de01\JL=Lyo#\32767654'&#"327654'&'&+567>;"##"'&'&'4&46 4*\W[@A*#z))z#*A?\ZY* !1} g{|!%).')&&&)'.)% |{g ~XY1" 8<7632#"'&'&%!32767676%!&'&'&#"d!!x]\orr.76nnts/"IImO@A#% t!FGkNB@&( כ?>؋̭jiڂOd[dc89Z]hA`bab:9]bf=2 #&#'67676303 676767032/"5k$#$, +,J$$J,+ ,$#$k8& f"  08680  "f 6'>p&jJ~t )#&'&54767367654'&~zz/:voTpoSjTppQbؘ|~z֘z /DTpoS(RppQH$H%#"'&54767#5!2#"'&'&'&!"2767653367675&'&'&a ! 3/7`11!/a_210`6/3 !}Kx<?8!B& } &A!8?:<*$#{Q8JI~{#$*lZ_QO6*s$%(%$t)6OQ_ZNO56Qt3654'&'&'&'503;2#&'�#"'&'#( 3MHE!\.+'BI9uZKnyl{%N WRӁ<fM <#t#X5n\t*P47676767632#&'&'&'&'&%4'&'&'&'&#"3276767676\,+C@ge{zbdBA-,,/?CeKSO@bDA-+ 0.FCX^//!0.GFT^IK-- ! gehfdRO21./NLa]ltmbghbiIM0# t -NK_[lmlspOIC<9" P@?UTUrhKJA;9 '(;`y !!!!#y0\tA/"!!#"'&/5327676765#534767>321*+2G+, (67f  (4%L<9%%*+j  =BBMtJadBCB p32NPftK\`JLB [#C!5654/#'67670320!3?0#"'&'&'&'&50547[ CA"!%!  " CA"!%!  ":.%? %&3* d%? %&3* dv1 !'!5  \Ȏ0َ 02VQ'676767632#"'&'&'732767674654'&'#6767&/&'&'&#"#O34?do%IBa\\KI=:HgQT.,(H<@1kKn XMU// oX.iP9ktz[i2134$:=>TRiekRPa32&#"3276<##2/AfNO./^f>2-8ItLMMLtuOP#d*&" 01QSbelne`\+rsvttvTL!#"'&'&/"'67>323276=4'&'.#"#367632#"!i:S*$#$0!F%F%05O8ffDF23"PQsRBE02?42   " !  ,&+PZKO7;B"#:AFKX[;323276=4'3276?&'&#"3,1263BK@*7 SfJLx5i#"!i:S*$#$0!F%F%05O8fD#8> '.+*5;%)6.;Opt:= ,42=v?42   " !  ,&+P ;5 \A>C6W +v#- U#"'&'&5467>767676?6767676767654&#"'676323267 ;y|nmEEB #&2'!CC(* sqSU)yyyz  V)7F-.$ ȎsG`b**[\:b)'H  $^|89HVUab1/1"#2    )#,rW- B]#"'&'&5467>76767&'&=67632326736767676767654&#" ;y|nmEEB #& (NB)yyyz  V)7F-.$ ȎsI1OP0'* sqSUG`b**[\:b)'H"B VUab1/1"#2    )#,rW+WI1  $^|89A%!7!&/'>76763223767676?263632/X2G a 6W& 4 *B@@B* 4 &W6jf  w   >;;>   w  /A%!7!&/'>7676322376767673>3632/nF a 6W&0*B@@B*0&W6R|V&  w   >;;>   w  Z^326767654'&'&#"25/7+"67632 &'&=47676763237:32"!nKIn!"A@bd@A{  f   <64>gLK.1Tjde01`de01#":8JI<  S\JL=73'676767654'&'#.CV*&(.1:C/]35 6 S4RO #"'&';2A@db@A"!nIKn!"VOFJ8:"#10ed`10edjT1.i?42-v_[;::;[_v\JL=`TfMd'647>7632#"'&'&%!32767676%!&'&'&#"d!!x]\orr.76nnts/"IImO@A#% t!FGkNB@&( כ?>؋̭jiڂOd[dc89Z]hA`bab:9]bf=eF4&'&#"!!327676767#"'&'&547676767632<=EZGLGX+'+ z 2)75=hj:;()68HJTsUV5)122x]_vM(%' LMTSRFH47=>`eF4'67632#"'&'&'&'732767!5!&'&#"5VUsTJH86)(;:jh=57)2 z +'+XGLGZE=<)B`>=74HFRSTML '%(Mv_]x22#:!#3676767632#"'&'&/4'&'&#"3276$"#)(7Z[" -+LG`73034C543+,4DFIsCD3 deVgZNPIL64" ZUpBC67`SFGIqs#27676767654'&!3 ##/\GQGR17 "/E62B=YWQNi13>(&TB@.+ d@#"'&'&'&'&547676767632&'&+"32767&$:5SO`ufdEG/21/HFdcxIGB21'(VSihTV4365URdkZ[ %@742.)(HJ^eikxtqmeaKI++(*()))Y9768XWrmyxonVS53AB\y 33 3##yϙTT#PQyt 33##y׺ϙt7632&'&+"!!32767b&$:5SP^vfdEG/130dcyHGC21'%VSiiTU43X65URdjZ]%@742.)(HJ^amkmjhc++('+)))Y9767YWrLYOKnVS53AC[- 67,3'jT,q33276765!5!#"'&'&q o[HI"#ͥtv%27?@[^f qsDE-<!###"'&'&'727!32#'32767676765!#y #("("*$#$kWjl"!fDG+) #\2 $  "f {!!rKIX+*ZX #!*#I)!!#3!332+32767676765! jl"!fDG+) Y}!!rKIX+*ZX #!*#j&!#!5!!67632#4'&'.#"ǘPQsRBE02fDF23""Z[;?327654&'&'&+5327654'&+"'67632#"'&q%POS_a:/17:=NbaHGIJ_Qx 4ed{d\Y<;!!'(&$,')&|~/Q54UVGz%&}JHreFGTJ@hA@/-[YmRGF'( !1-DCFMLy 33##y둝ZPwyX!676730"'&'&=333##7#;EPB#ECCE#BQ1N&1둝*z Do9(&&(9oD p4ZPwy 33 ##yxϼsT$!###"'&'&'727З #&%) *$#$kWP#\2 #  "f {y 33 3##yϙTT!P\LyJ 3!3#!#ykP^\%M4'&'&'&'&#"3276767676%47676767632#"'&'&'&'&H 0.FCX^//!0.GFT^IK-- ! ,+C@ge{zbdBA-,,/?CefzxcbDA-+spOIC<9" P@?UTUrhKJA;9 '(;4HA<63$$9;JLL,! ,-A?hfzycdX  ,.@C{wBA-+ #>  /-HFT\-,! <  0-GCX^II/0 J 3 3 # #Jjc;˾^)'Jy0< %#5!3!3<˞#b"3##"'&'&'&53327676765sRBC1443CF25 P Zx!"BGhpEZKO7:"!"$9>IPSy%!3!;3Ş##y0%#5!3!;3a##($!#5!332+32767676765!o Ίjl"!fDG+) "!!rKIX%0ZX #!*#yK&!332767676765!332+gDG+' jjA@"!P %!*#V!!99KIX+*YXy"32767676765!332+gDG+' ΋jjA@"! %!*#V!!99KIX%0YXd?7327676767!5!&'&'&'&+"'67676767632#"'&'&'&d [ZkcST58X45STijSU %'11DGHxcd03.^GDu_PS5:$&%)\BA34TYkKOYLoZ[5678Z)$.+'(++chjqtsJGR.247},R3336767676762#"'&'&'&'&'#4'&'&'&'&#"3276767676}a *(;9]\XY<<'0 '):;onXY<<'%_*'B>MVACR -)KV@C)( GN5bleQN22./OP\rWedeiagKM`--NM]XoSN\܂mQGD;7#!()|VhNmmNH?=8@&'=:ULXSyP#"3#&'&54$;##Ǻ ('\Jdc2Ξ|)"(!&"nnPwjwB5"327654'&'254&#"'632#=#"&5476lHFGIj`HFIJ{fNL ~vB@;#Nڋ !537lmFFEcgCDFEcgCD761`#hm{!ΧkkZA326767654'&'&#"&#"67632 &'&5476767632"!nKIn!"A@bd@AP[i.1Tjde01`de01#":8JFO[NP2\JL=L756($.!/1ZZxZD>+,V43W-%  ^2!#!V2*P2 %3#5!#367!3#^LFlhdj^ q0V|abF 1!.#"32767#"'&'&54767632 pL<:<:LIEH3ijtac/012_a_QN23\65ON_QN76&(;7d:;MO|{~IJ.,LM\_c/!^~2!#5333##\\q:wUXaAJ??327654'&'&'&+5327654'&+"'67632#"'&aux>gKI)!,(/9GI3467D:-*e)PMbOIF/. %$'$T$#pqdef&6B76[0&' }/0HA-.24S64#"BAQ<542! 3/6^_==z2 33##z2",z!676730"'&'&=333##$7#;EPB#ECCE#BQ1N&,*z Do9(&&(9oD p4",y5 33 ##y0H0PkE}2!###"'&'&'727M #("("*$#$kZ 2|U2 $  "f {b42 33 3##bPO2`$$f03 3%'!#ff2)-ZF0476767632 &'&7326767654'&'&#"Z48QTjde01`de01"!nKIn!"A@bd@AvfhIM)*KL{LM~\JL=f^/.ONfA/2##MLtuOPPOutLM1,$ $\`enlebSQ10 "&*srstvttveF/&'&#"327676767#"'&'&547676767632<=E+'+ z 2)75=hj:;()68HJTsUV5)122M(%' LMTSRFH47=>`R2!!#!R92[J1 3 30#"'&'&'72?R=!*) ' ,$  k3^1n   f  dt %.&'6767054&'&5'476730Lim~[H2dqVoP`iKgꦂdS5Elכ] Vt޺P$5f1 !# # 33f:ȪHNy02 %#5!3!3c2[\2!3##"'&'&'&=3327676765$rSBC14fDE2724Zx!"BGhl_FL:;B"%8:MPS}3 )3;33Z[}/3%#5%3;33Z[[ 52&3#5!32+327676767654'&!zjl@$2+猌fDG+) 6!!,K?2/&ZXM@ #!*3k2*3#3320+327676767654'&!ԗ_jl@"3+茌gDG+' 622!!,L?2 &&YXM@ %!*1%3320+327>767654'&!jl@"3+茌cHKN 62!!,L?2 &&YXM@:%!+eF4'67632#"'&'&'&'732767!5!&'&#"5VUsTJH86)(;:jh=57)2 z +'+XGGZE=<)B`>=74HFRSTML '%(Mv_]x22ayQ.U33367676767632#"'&'&'&'&'#4'&'.'&#"3276767676aa **9;PTCB*) ,+>7`O:51V..?jK:OP85/+)**?7@<uK2 "'#&'&5476!3#`0dM.LM::!.IgeJb<'Cp}b'jr}tD!##5353!!67632#"'&'&'72=34'&'.#"?PQsRBE02#("("*$#$kffDF23"[;``HJI&'&'&'&'&547672&#" #"'&'7327654'&'&'&>'*2/""deR), 6Qt 112-+$lk\_%45[e::"'$#.1;KL,&)$%zNH&  !'/6AZYCEnC$$00U)" ?L#O'jD\TfMH.20A!320+##"'&'&'727327676767654'&!#jl@"3+!茞M #&%) *$#$kZ 1gDG+' 62!!,L?2 $(VX|U2 #  "f {u %!*X62.!#373320+327676767654'&!jl@"3+!gDG+' 6S2V!!,L?2 $(VXM@ %!*-!#534'&'.#"##5353!!67632fDF23"?PQsRBE02ZKO7;B"#:AFKX[;767654'&!jl@"3+茌cHKN 62!!,L?2 &&YXM@:%!+y"3 4'&'&'&'&+';2+# '+GDgΞ艋!"@AjkΞ#*!% XY0%WJK99!!TN"2676767632#"'&'&'&'#4'&#"3276& 52>f^/.ONfA/2##MLtuOPPOutLM1,$ $\`enlebSQ10 "&*srstvttv\!67632+&'0'&%!!#  0  e )   ^!67632+&'0'&!#!  0   g*   V2 !!!!##53\ *֞fo0 !!!##53!\?6276=4'&'.#"+!!>32+6gJIfDE27 rSBC14#JA@PAJI!_FL:;B"%8:MPSYZx!"BGhl >CE= ^2{Ln^^~2~q _aAJyby5yby5yby5yby5yJef03y3!!!+!#y ^f3 3%!!'!#ff2)׈U.yJgy2dieFdieFXjR2BZ3 3#BddBX<x?16#"'732767676=#"'&'&'&533276767653&$?`?LLn.&O^^~'W~y33 52>5#yx-(.hQU 0 /$ϼs?Na!&( %<'y5!52>5#33 /3.hQU 0 /$Ha*&( %<'k0PT$!7##"'&'&'727\З #&%) *$#$kWP#\2 #  "f {E*}2!7##"'&'&'727]M #("("*$#$kZ 2|U2 $  "f {yO%52>5!#3!3O-(.hQU 2'6)*k?Na!&( $;'^Pf83!52>5!#3%8-(.hQU 5%8',f?Na!&( &<'-2)yJ 3!3!#ypkP^f*03 3%7!#fDf2)-b%3#53#"'&'&'&53327676765G4sRBC1443CF25 P Zx!"BGhpEZKO7:"!"$9>IPS 2$3#53#"'&'&'&=3327676765$<1rSBC14fDE2724Zx!"BGhl_FL:;B"%8:MPSy 33 37#yaTT!P\Lb42 33 3#bPOj2`$$7,H.&Xjw'cxH"%-4632#"'&'&%4632#"'&'&!!#3#8&"28& )8&!8& P%  n&8*! '8!&8! '8!]Pjw"2X4632#"'&'&%4632#"'&'&"327654'&'254&#"'632#=#"&54768&!8& )8&"28& HlHFGIj`HFIJ{fNL ~vB@;#Nڋ !537lmN&8! '8!&8*! '8!FEcgCDFEcgCD761`#hm{!ΧkkSg!#!!!!!!53OFF{JT`Fx"327654'&'&67632!3267676767>7>767#"'&'&'&'&'.'#"'&'&5476326'&74'&#"'676767632!&'&#"h00"\6742<;!32>!4'&'&'&+"'67676767632#"'&'&'&'&5465 ҩrZL55STijSU %'11DGHxcd03.^GDu_PS5:$[!Ovlj\[5678Z)$.+'(++chjqtsJGR.24:%bF 0!3276767.#"'67632#"'&'&'&54&= FGoK<;>rNIFG4gju_`0112_aaOM42͑hi65PN_j'';7d:;LL{~IJ-,NK]_c!0'jb'jXLn'jD^^~'jX~q 'j_aA'j.q _aAJy !!33##8[둝jZPwz+ !!33##[X+j",y'j`z ,33##4632#"'&'&%4632#"'&'&z*8&"28& )8&!8& 2",N&8*! '8!&8! '8!\&2jf&Rj{\'<P47676767632#"'&'&'&'&%!3276767676%!&'&'&'&'&#"\,+C@ge{zbdBA-,,/?CefzxcbDA-+!0.GFT^IK-- ! @  0.FCX^// gehfdRO21./NLa]ltmbghbiIM00--NK_[lm4SOKJA;9 '(;OIC<9" P@?UTT+bF"/ #5"'&'&54767!.#"27676?!a_210/caac/012_# pL<:<:<FJI~{|OMMO|{~I`65ON65ONZ _QN7\'<Pas47676767632#"'&'&'&'&%!3276767676%!&'&'&'&'&#"4632#"'&'&%4632#"'&'&\,+C@ge{zbdBA-,,/?CefzxcbDA-+!0.GFT^IK-- ! @  0.FCX^// ,8&"28& )8&!8& gehfdRO21./NLa]ltmbghbiIM00--NK_[lm4SOKJA;9 '(;OIC<9" P@?UTT+B&8*! '8!&8! '8!b"/AR #5"'&'&54767!.#"27676?!4632#"'&'&%4632#"'&'&a_210/caac/012_# pL<:<:<8&!8& )8&"28& FJI~{|OMMO|{~I`65ON65ONZ _QN7&8! '8!&8*! '8!d?Qb7327676767!5!&'&'&'&+"'67676767632#"'&'&'&4632#"'&'&%4632#"'&'&d [ZkcST58X45STijSU %'11DGHxcd03.^GDu_PS5:$&U8&!8& )8&"28& %)\BA34TYkKOYLoZ[5678Z)$.+'(++chjqtsJGR.247&8! '8!&8*! '8!e4FW'67632#"'&'&'&'732767!5!&'&#"4632#"'&'&%4632#"'&'&5VUsTJH86)(;:jh=57)2 z +'+XGGZE=<O8&!8& )8&"28& )B`>=74HFRSTML '%(Mv_]x22&8! '8!&8*! '8!#!!3 3#"'&'&'727x[dd  &%) + ,$#$k3RjX #  "f MJ)#!!3 3#"'&'&'72?[j=!*) ' ,$  k3^)jn   f  'j=kJ'ju&kJ='b&jho'j\[^2{yK'js3k*<M3#3320+327676767654'&!4632#"'&'&%4632#"'&'&ԗ_jl@"3+茌gDG+' 6f8&!8& )8&"28& 22!!,L?2 &&YXM@ %!*&8! '8!&8*! '8!y='e%'eEy'w'I'G!84&'&'&#!!2>767#!!247632#"'&'&@<:QPc ax! --QPpmWySS21>E=F؆PN++iVliba98d\[E > F > 8O3#5+"'.547676763232767>54'&'&'&#"47632#"'&'&I>?OLCDf<21DE[l ().<13'(,'%52@0'(>E=FPn)*$$ҎsjcLJ**gKT5:!";<\ZIJ;8#!73RHE > F > y(&'I(&Gy')}' IU !3!3#!#476320#"'&'&ju>E>F~N^E >  E > 2!#36767>32##"47632#"'&'&#-$#"#:*532*(>E>E8"!n-+)788xE >E >ytJ&+t&ńK!!33 ##]Ctb:D g!! ##33]G-h5A 3!!47632#"'&'&c6=F>EۍF > E >  %3"'&5347632#"'&'&8vCB>E>Ei:9u\E >E >  !!3!!47632#"'&'&f\c6=F>E}ۍF > E >  $!!3"'&5347632#"'&'&B]zvCB>E>Ei:9u\E >E >  !!3!!]ucۍq %3"'&53!!8vCBVi:9uňy'h0'_P #33 3##47632#"'&'&ϚTT>E=FN[KE > F > I+B!#4'&#"#3>32>32#4&#"47632#"'&'&a**K4-/%$.?zNIHTJIVI4-/%$.=F>EML('n?l2cLo^mkr('n?xF > E > 47632#"'&'&33#29>9>Q䞒>7 > 8 uNYb047632#"'&'&#3632#4'&'"9>9>}P 77Q252-(> 8 >7 2A"%$'nJK+&96< 333#47632#"'&'&䞒>E=FuNYE > F > I2!#3632#4'&'"476320#"'&'&#}P 77Q252-(>E>F2A"%$'nJK+&96  E >  !!33#o]䞒uNYI !!#3632#4'&'"]+}P 77Q252-(2A"%$'nJK+&96<y'k3T'tS[23 4'&+ ##!2476320#"'&'&!bcSמmvegHJ(*a`v>E>EBCw35KOaml!vE >  E >qM0&#"#367676763247632#"'&'&DG/++!"!%!tY=F>E**(<:H|2&#7F > E > [ 6!!3 4'&+ ##!2476320#"'&'&])bcSמmvegHJ(*a`v>E>EBCw35KOaml!vE >  E >R74!!&#"#367676763247632#"'&'&R]LDG/++!"!%!tY=F>E7**(<:H|2&#7F > E > [ !!3 4'&+ ##!2])bcSמmvegHJ(*a`BCw35KOaml!vM&#"#3676767632!!DG/++!"!%!tY=}**(<:H|2&#7_- '6`H'3VL>?V7327>7654'&/$47676763 &'&#"&$47632#"'&'&LZZYnF<=Z^Zn#">?RS` %}2WVp<64*'.ϐNX/2%&BA\\jH>E=FP:9R56BaJG7lRKI674OW10$!`:S34%*,/:8ZYMO98##E > F > kSKD[&'&'&'&54767676732&#"# '7327676765447632#"'&'&k>F%'/,AEL:>:02 (%$(+dKD.*32PE!.$'=E=F# $#$,+/:84*((*6y #g3%($+'/03?>:-,6"!-{hF > F > X'7fP'Wb!!#!476320#"'&'&bE7">E>E$E >  E >q[,)#53533#;#"&547632#"'&'&uEEv=F>E,uzv9F > E > b !!!!#!a\E7"Î$q[,#53533#;#"&5!!uEEv,uzvT'C:D1='C&ZT'v:D1='v,ZT'j:D1'j$ZVp47632#"/&3 3#9>9>QeeA>7 > 8Y:?bD47632#"/&73276=#"'&'&'&533276767653#"':?:>i>26GoHH%DEOGFE64"!>?o2,+$ 64NJY> 8 >7TGJJH01 ;8VRizQS+&;9A^KM;8$"!!#36767>32##"\9-$#"#:*532*(8"!n-+)788+!5276767654'&/!"#47>Njm@X02L\\jB?>--^Ro%&*(-/:8[Wp#"()54DbHA.+' ~XLd'C<x?<'C\\~'!5!3"'&'&53dqAEP#<K%(V#"@!!3"&'&533"&'&53@dqtdqj" KJY#"! KJY#"Zw<'lIZw='@TJZw<'I'CZw<'@I'CZw='I'vZw<'@I'vZw'')Zw''@/H'H'@[&'C\|['C`|[&'v\|['v\|['&|['&|k='IJk;'@323276767#"'&'&'&'&#"1F% 8 " !1 !"" "$B  &   9"Q4632#"'&'&%4632#"'&'&67676323276767#"'&'.'&'&#"8&"28& )8&!8&  !#%#0%$/ 1 !"""$! *I&8*! '8!&8! '8!W-$ &   !vt:'0'CutN'-tt','v32#'&'&'&'&   u<&- )H8    [ #2 - $Kg$&+(0dL2%632'&'&7476%47>32#'&'&'&'&  <&- )H8    #2 - $Kg$&+(01y+F67>323276767#"'&'&'&'&#"4767632#'&'&'&'&1F% 8 " !1 !#! "$BD',@'H8    &   N $@, #Jh"+'+v' v &q v'Cl['j*[ v'v['j+^ Zt<'AI Zt<'@GI v<'[ v'E'j,[ BZ.&BZ'q=}'C\'v\&@<(9'%&'&547676324632#"'&'&%4632#"'&'&   l8&"28& )8&"28&   n&8*! '8!&8*! '8!P):%632'&'&74764632#"'&'&%4632#"&'&  8& 8&!)8& 8&"2   &8 '8"&8 '8*"<#"'%&'&54767632       7'Cb7tH&7t<'v67;'7t;'6v'C\'v['C\x5'v\t5&<%632#"'&'&5476L      dL;47>32#'&'&'&'&d<&- )H8   #2 - $Kg$&+(0v:!!v;Ȏv:!!v;Ȏ!!X!!R!!:!!ȎE2###222SD*_>6c4:NjDAMQDr'MHMa>'NJNq2R[>|Q * #!5!3!)uuU*!!#!5!!5!3!)v1ώ;eHi47632#"'&'&;oDTM nDTM gN/n,3M/n,3 2F kF\33"&54767632,@$ ->( @,(>-( \#3"&54767632!"&54767632,@$ ->( D,@% ->)@,(>-( @,&>,) \#5!"&54767632!"&54767632!"&54767632d,@$ ->( X,@$ ->( D,@% ->)@,(>-( @,(>-( @,&>,) D I47632#"'&'&MLm_GFMNk^GFGlKK:8[lKL::YsiE <\i2654'&#"32654'&#"#3476767632#"'&'&'&476767632#"'&'&'&2654'&#"476767632#"'&'&'&()xX+,=3Zl''A3/4#(()xX+,=3Z%$23<122&(0%&10>3/4#(uI()RHB**NyH()RGB**N M501&%$"#dB7.0%% %/1501&%"#21C7.0%& %/2I()RHB**NH501&%"#dB7.0%% %/1 si DE <\i2654'&#"32654'&#"#3476767632#"'&'&'&476767632#"'&'&'&2654'&#"476767632#"'&'&'&%2654'&#"476767632#"'&'&'&()xX+,=3Zl''A3/4#(()xX+,=3Z%$23<122&(0%&10>3/4#(()xX+,=3Z%$23<122&(0%&10>3/4#(uI()RHB**NyH()RGB**N M501&%$"#dB7.0%% %/1501&%"#21C7.0%& %/2I()RHB**NH501&%"#dB7.0%% %/1CI()RHB**NH501&%"#dB7.0%% %/1'476;2#"'&'& $ ,,'46;2#"'&'&%'476;2#"'&'&,  $( $ FD3##mD###g"3F#&'&546324632#"'&'&#&'&5476324632#"'&'&V)<&(@,(>-()')<@,' ,'(6%,@$ ->$ f)6&,@$ , $ 7F%4632#"'&'&? 4'&#"'67632#54632@,(>-( 4 MK~SHyzXLO|L%&= >2$ <&(^,@$ ->$  ,!&}EDZ|9oo^`aIK>..>S8(6%c%#"'&'5!2767cٲרn@@>>rJJt ZR ''!!''!!''!!TTTTTT6TTT/'7'7'77'd8RR88RRR88RR88R"m?#3)9$%4632#"'&'&%4632#"'&'&#54767676? 4'&#"'676326732#54767676? 4'&#"@,(>-(@,' ,' 74 MK~SHyzXL9,MENO>@%&&):$=1& 65 MK~C< &%&= >2$^,@$ ->$ ,@$ , $ +*)# .,!&}EDZ|9oo@/1MOJP9..>S+*&# .,!&}EDO`aIK>..>91CVi67032#54767676? 4'&#"#&'&5476324632#"'&'&%4632#"'&'&9MENO|L%):$=2%  65 MK~C<@)'(@,' ,'@,( ,(@^`aIP9..>S+*)# .,!&}ED)%,@$ , $ ,@$ , $ g 2EVi67032#54767676? 4'&#"4632#"'&'&#&'&5476324632#"'&'&~MENO>@%&&):$=1&  65 MK~C<@,' ,')')<@,' ,'@/1MOJP9..>S+*&# .,!&}ED1,@$ , $ f)6&,@$ , $ yu$<"&#27636767676767654'&'&'&"#!32 dP* &'#'"KZhŌywfc9:  /)5 L ;  "2')#u10NOb&-/)+ 3'#'&'&'&54%6;N! o y 6n->(*oL732#'37 !N Lo*(>-n6   Z ''!!`TTTZq#H,74767632#'&'&'&'&47632#"'&'&q(,@(H8  -&<@+'^ $@, #Jh"+'+- 2# +@$ >'%)%"'&5467632"&54767632#3A- 2# , ( ^,@$ , ( %ѐ -&< ,' @,' ,' D?3\+67>323276767#"'&'&'&'&#"?F% 8 " !1 !"" "$B  &   m?%72#"'&547676#"'&'&54632#"'&'&54632, $ - * >-&@,( >-&@,(  -( ,( .>" +@) Y.>" +@) m'9K2#"'&547676!2#"'&547676#"'&'&54632#"'&'&54632, $ - * , $ - * )>-&@,( >-&@,(  -( ,(  -( ,( .>" +@) Y.>" +@) m%8J\2#"'&5476762#"'&5476762#"'&547676#"&'&54632#"&'&54632!- 2# , ( - 2# , ( - 2# , ( ' -&<@+'  -&<@+'  -&< ,( d -&< ,' N -&< ,( - 2# +@( Y- 2# +@( d;+##"'&'&54632#"'&'&54632:@,&>,) >-(@,& ,@% ->)[.>" +@( %+':N2#"'&547676%2#"'&547676#"'&'&547632#"'&'&547632- # , ) - $ , '/@,& ,)  -( ,&  ,( -(  -& +( ,@$ , * ^- # , ' d<s%8#"'&'&547632#"'&'&547632#"'&'&547632;@,( ,' @,( ,' @,& -) ,@$ , ( Y,@$ , ( E,@# , +dm<+#5H#"'&'&54632#"&'&54632#"&'&54632#"'&'&54632:@,&>,)  -&<@+'  -&<@+'  -(@,& ,@% ->)- 2# +@( Y- 2# +@( E- " +@(0Q167>32#"'&'&54326767654'&'&#"B!!lBd~XcCA &0 % I;;HwHMqX\xLJwFJRR:>I('*('214D=E)'*+091@#73#{aDPB'767632!!5476767676?>?4&#"ʆ JIX&D !.   ( _ !. <&( #5O87:,-0 ,#406 '!"!5<.3S>7327654'&'&'&+5327654&+"'767632#"&'3 < 8&% JT"4"  9:H885##QRtHs+!(!!6($2 > >%%65A1)'&$-rIJXJA 3##5!335$^^WcW60H2'!!632#"'&/732654'.#"-    o7)&_CE>;PbFH "V2> >"N9} 9:\ &I?=*(9:Z%cJA.:0714'&'&#"3262#"'&'&54767676?3  +1  (3Bv_FI h8bBE  ("#-&B.9;Y .,0"#.;>S '*52l #!5lЧ:c%6I#"'&'&5476767&'&5463232654'.#"27654'&'&#"AA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$0O^= !?Lx#";;\/'& *>`~.(".%$3)@7 *-4:327654'&'&#""'&'&547676767632#  +2  !'2" u^GH  ,*.`ED  ("#, (" ::Z&$&<;V! " -F  533##5#53P4(!!P(@g!!!!@**C<lr&5476?3#'&]! ? &~#"9& <Doxgrlc7egcT7^3rh#767654'&/3%= !#$7% 9"# >r7[dd_ehkP7Zotqmon_B&!#3632#4'&'&'&#"Ԓ2D/*'   _$)%>@I1+! #+0Q1767>32#"'&'&54326767654'&'&#"B!!lBd~XcCA &0 % I;;HwHMqX\xLJwFJQQ:>I('*('214D=E)'*+091@#73#{aDPB7'767632!!5476767676?>?4&#"ʆ JIX&D !.   ( _ !. <&( #5O87:,-0 ,#406 '!"!5<.3S>7327654'&'&'&+5327654&+"'767632#"&'3 < 8&% JT"4"  9:H885##QRtH+!(!!6($2 > >%%65A1)'&$-rIJXJA %3##5!335$^^Wc W60H3%'!!632#"'&/732654'.#"-    o7)&_CE>;PbFH "V2> >"Z9} 9:\ &I?=*(9:Z%cJA.:0714'&'&#"3262#"'&'&54767676?3  +1  (3Bv_FI h8bBE J ("#-&B.9;Y!.,0"#.;>S '*52l #!5lЧ:c%6I#"'&'&5476767&'&5463232654'.#"27654'&'&#"AA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 *-4:7327654'&'&#""'&'&547676767632#  +2  !'2" u^GH  ,*.`ED  ("#, (" ::Z&$&<;V"" -F 7533##5#5?P447!!P4@s3!!!!@**C~7Zed_ehkP7Zotqmon_?  ,"327654&#"'&547632&'&#"'762#,(22( 44!!^@?ABZ;% + SKĂ$2"$0#$0 >>b_?@ o>t' 0 273&'&#"3276?#"&'&54767632!µ&   zDMr:8M:/16<$%!6";DZGFWUGE-+T50;#*%0/76767632#"'&'&543276767654'&'&": 31=Rt:;RR:; $  F0o8,*VGEGF----GIT==(#& &,7'(*N4G #'#373Gc_`_0.1 5#327676'&'&#"'767632#"'&'&'&5050=!&b&   =>CL:9;:K:/0HR$%"6";"#.-GITSID-,+*50:$D I47632#"'&'&MLm_GFMNk^GFGlKK:8[lKL::YD I47632#"'&'&MLm_GFMNk^GFGlKK:8[lKL::Y*)!&'&5476767632&#"!!!!!mFE/.EDQYB}JV*'%4,:MU,8u$ 39@#"'&'#7&'#&'&54767>?3273&'326?&#$T^`# )N4 37^'# %3M?w& Q+%* !d<<}567m!Qpl{ouTZ|2`;#6;3 *#Ckb@YJ#"'&'&5476767632&'&+"3676767632&#"2767؁^ilwolTR`,*RPnofiM.SP]]OQ9< '$65<"!%!tYBDG.,+! *ZFI.%C;=21cali<<;=sBB0.12TWqpkWYMI::##7|**)xEBDU3#535#53!!!!!!wwww..y؇S;؇d6/37632&'&#"!!!!!2?!76767#537#d k!d9'io~"7+P-y+;T  i6 q`>OF32673;2$++J- ͝j**L3-/%$.?zMI-0iHILKnEdML('n?l2cLE09kk#&)##!##535#533!33#)'!35!%35#wwwwwykwwU55yy؇SS؇HRnTel%#53533#303%276767654'&'&'&'&54767676;2&#"#!"'&32!#3 !Un.$)k>C'(.,BAO9>;02 ($$(+hJC.+32Qb;:yfcIG)(88؇,u ##+~E# #$%+)1=67)'(*6y #g3"'$,*.,8A<:-,6=;[42NLgop$ ^hz#"&'&'&'##!23276767654&'&'&'.5476767632&'&#"4'&'&'&+32767>^%'66JHBLDJ>=0؞m[h^SPb01C>P~I9(Z0289A&,')#T?T4H@?T4/BAB4;823!# =?@"H *&C2VFB>+*#"86FBGL?G57D)K;?)*.-G20pRCE01# oP9@ &$->N$$$fUG;6'$ *,9F$8" '%:9S54 j? 4 7!?#!'#!7###!##53'#53333333#3xNP-+2A.->19RP>0 A-WX&p]GGO)T8vciv.(330#53>32.#"!!!!3267#"&'#53&54'}q}M`2XQ<_,"i0E\>`<9[7&:K`3+ZJ MW+Da/!!!###53333!!ucwwLwfgzz+p!%%#5%55%!5!p755˞NN"E$mmmmwwww| +#324+32 3 !0IHF|MNFFW f1 +h<;77o`X &Gd3276767654'&'&'&#"2#"&'&'&54767676324'&'&'&'&'&#"'63>!!0.BA43'",+=;B5),=&V#,$:92Z55OOpm31/1FF_4*'B / -(9:<)%%-& 7<=45"! 4-C=<>?>..$'1585 &>6FMDUY2_c`PO21LB@[XgQVUAC** $ , >SERH;<)r',7!323#3#+##535#535!2&+4'&'!!676>'qFFq<~Ϟwwwwm_PLWPч    k:;Ws67mLL  s  ,8#5&'&'&'&54767676753&'6767#53+*CARQDG1410GDXU#DFT64\/'&~gXYDB/-+-EJ`a}l\_LJ64x5B_QO9B'&84GCM!#!##537!5!3!!3# '!2@@1up;+)䇇8Ȉo+n\!327676767#"'&'&'&54767#5367676767!5!654'&'&'&#"'6767676323#!n 8/0;<@E67-,') V]Y\CE++Du1,;.AH<()53;i5}/-/63D>P3X,B;$Dn'(#"032P68NOe &" =H!":@SY]_:;# "'&5!##533!33#3 B@@www:9u_66piLOju#5#"'#5&'#&'.'&'&54656767667632>32676767654%'$476767632&'&#"4#"37'54#"'54'&#"OlKOTTK4gG>T  $!T8$E<4,. "n#">?QRbkmG%}3UUq=63*),34hy]W0/-(?@-(+- QFGn&( =5H^!L  " $1)V0&Z\q"#,.492eoRKI68./e4OX00$#^:F9:%3,*'.,?Sg#"'&'&'&'&547676767632&'&+"32767;27654'&'&#"47632#"'&'&".-L_PQ76.8' 09;RO`=67&## xDCTFBG.1#(/luNIH{!&"'@4167KB208>4206))HDcxUTTGgEG-+,)'*))Z879=QXpmyzn~LB?^I (+L45)(?K55)'@"]+#"'&'&'&'732767654'&'4!5]c;6:jh<5;'. z )',X:.fj+YmUxML$ %(MvNp FZx>y+5!!327654'&'&#"47632#"'&'&33# v ('4<** ('4<**vLLn_GFLNl_GEf:71"!+,?2"!,+ClKK:8[lKL:9Z>P2y"3 4'&'&'&'&+';2+# '+GDgΞ艋!"@AjkΞ#*!% XY0%WJK99!!yP32676767654&+ ##;2\'( Sמcd"&$%,|wlmnnxw* 33##!###+sĉt_ bwM>7cP5K%&'&'&547676767632!!5676767654'&'&'&'&#"3!7 ?,+,+C@ge{zbdBA-,,-HK9;!  0.FCX^//!79EI^[lmlgehfdRO21./NLa]ltmbghbeK(@BRUORUspOIC<9" P@?UTUrhKJE9: 10+B327673#"'&'&54767632!"%4'&'&#"3!276 20FHOmacBmpk?7ه{ f  $!15>/R K R K &>DH7327654'&'&'&+5327654&+"'767632#"&'#73#'[ < 8&% JT"4"  9:H885##QRtH{a+!(!!6($2 > >%%65A1)'&$-rIJXJ 9A7H5B'767632!!5476767676?>?4&#"732654'&'&'&+5327654&+"'767632#"&''Ά JIX&D !.   ( _ &. <&( # < 9J JT"4"  9:H885##QRtHË5O87:,-0 ,#404!'!'!6<.+!(B6($2 > >%%65A1)'&$-rIJXJ]9A739=%'!!632#"'&/732654'.#"#73#'M    o7)&_CE>;PbFH "V2> >"W{aZ9} 9:\ &I?=*(9:Z%cJA.: 9A7L-Bvz'767632!!5476767676?>?4&#"'!!632#"'&/732654'.#"'҆ JIX&D !.   ( _ &. <&( #    o7)&_CE>;PbFH "V2> >"S5O87:,-0 ,#404!'!'!6<.j9} 9:\ &I?=*(9:Z%cJA.:]9A73->rv7327654'&'&'&+5327654&+"'767632#"&''!!632#"'&/732654'.#"'3 < 8&% JT"4"  9:H885##QRtH    o7)&_CE>;PbFH "V2> >"Ss+!(!!6($2 > >%%65A1)'&$-rIJXJ 9} 9:\ &I?=*(9:Z%cJA.:]9A7A- @D3##5!335'!!632#"'&/732654'.#"'$^^Wc7    o7)&_CE>;PbFH "V2> >"SW69} 9:\ &I?=*(9:Z%cJA.:]9A717;4'&'&#"3262#"'&'&54767676?3#73#'  +1  (3Bv_FI h8bBE {aJ ("#-&B.9;Y!.,0"#.;>S '*5$ 9A722Edh'!!632#"'&/732654'&'&#4'&'&#"3262#"'&'&54767676?3'6   n6)&`CE>;PaGH #U3> #  +1  (3Bv_FI h8bBE O9} 9:\ &GA=*(9:Z%cJA /g ("#-&B.9;Y!.,0"#.;>S '*5,9A7%6IOS#"'&'&5476767&'&5463232654'.#"27654'&'&#"#73#'AA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$s{a0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 * 9A75>du7327654'&'.+5327654'&+"'767632#"&'#"'&'&5476767&'&5463232654'.#"27654'&'&#"'5 < 8%& 0JT"! ;:H885##QRtHAA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$os+!(!!6($ > >%%65A/+)('*rIJXJ{0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 *r9A702Xi|'!!632#"'&/732654'.#"#"'&'&5476767&'&5463232654'.#"27654'&'&#"'-    o7)&_CE>;PbFH "V2> >"AA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$oN9} 9:\ &I?=*(9:Z%cJA.:{0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 *r9A72+<OS #!5#"'&'&5476767&'&5463232654'.#"27654'&'&#"'lЧAA ! LA@JaLK-fY#)2.&-.Z5'& #%-9F "$o0O^= !?Lx#";;\/'& *=`~.(".%$3)@7 *r9A7 #73#'{a 9A7733P\!3!3>PP !3!3!3>>PPP 3#33mGBPP{3#3)GBP{ !33#3U7GBPP{!3!33#3z>7GBPPP{!3!33#3z>7GBPPP 3 3 # # 3jc;˾^)'J'PJ 3 3 # #Jjc;˾^)'JJ!33 3 # #jc;˾P^)'JJ!3!33 3 # #6>jc;˾PP^)'Jy3!!yeݍd@#"'&'&'&'&547676767632&'&+"32767&$:5SO`ufdEG/21/HFdcxIGB21'(VSihTV4365URdkZ[ %@742.)(HJ^eikxtqmeaKI++(*()))Y9768XWrmyxonVS53AB\y)4'&'&'&'&'&+327676767#!!2 %*,2HIS~\[55''JIprDpqIK&'E=F?D8@(.j**PQfhdc78=>ehy 33 3##yϙTT!P\Ly54632#"'&'&3#y8&!8&!5&8! &8!yZ&*4632#"&'&3#4632#"'&'&3#8&"8&"28&!8&!5&8" &8*!5&8! &8!y&*<@4632#"'&'&3#4632#"&'&3#4632#"'&'&3#8&!8&!8&"8&"28&!8&!5&8! &8!5&8" &8*!5&8! &8!y54632#"'&'&3#y8&!8&!5&8! &8!R1!3 31nR4632#"'&'&3#!3 3B8&" 8&"i5&8' &8 1nRH%);?F4632#"&'&3#4632#"'&'&3#4632#"'&'&3#!3 38&"8&"28&"28&!8&" 8&"i5&8" &8*!5&8*! &8!5&8' &8 1nR#&*14632#"'&'&3#4632#"'&'&3#!3 3g8&"28&!8&" 8&"i5&8*! &8!5&8' &8 1ny !!# # 33 4632#"'&'&3#:Ȫ8&!8&!HN&8! &8!5f1 !# # 33f:ȪHN5!4632#"'&'&3+ # 338&!8&!:Ȫ5&8! &8!HN5&*64632#"&'&3#4632#"'&'&3+ # 338&"8&"28&!8&!:Ȫ5&8" &8*!5&8! &8!HN~ %3"&'&53dq KJY#"eF/&'&#"327676767#"'&'&547676767632<=E+'+ z 2)75=hj:;()68HJTsUV5)122M(%' LMTSRFH47=>`#23#5#"'&'.'&547>32327654'&"6"#2/BPEB.,@ ^f?15 &MLtuOPPOLLR*&"  75PTUne`\$ $,vttvtsrqN5!#4'&'.#"#3>7676767632>32#4'&'&'.#"V ,H5ژ ($0tJKm *B+#N1=37N.a1*! DEihs;/6+8$<g>.E_#!5#"&'&'&'&5476767676325!23276767654'&'&'&'&'&#&'&+"3276('qrD6FP`tDG/11/HFdcwIGB2 pq'([[55 %*,3FITn MSjhTU4585TRdlZDח88?*RGJ^ampsovmeaKI++ 5=>ʃj**PQfgE=?FD8@(.pQ3767YZomyxokYT43A0y)4'&'&'&'&'&+327676767#!!2 %*,2HIS~\[55''JIprDpqIK&'E=F?D8@(.j**PQfhdc78=>eh&'>O4'&'&'&'&'&+327676767#!!2;#"47>763!!"'.'&. %).3EIT\[54('qrDpq'(55[[TIF3,*% ('qpDrq'(E=F?D8>*/j**PNig88=>ʃhfQP**.(@8DF?=E>=P88ąd<73276767654'&'&'&+"'67676767632#"'&'&'&d [ZkcST5845STijSU %'11DGHxcd03.^GDu_PS5:$&%)\BA34TYkoxymoZ[5678Z)$.+'(++chjqtsJGR.247eF/'67632#"'&'&'&'732654&#"5VUsTJH86)(;:jh=57)2 z +'+E=<)B`>=74HFRSTML '%(Mõ22d@#"'&'&'&'&547676767632&'&+"32767&$:5SO`ufdEG/21/HFdcxIGB21'(VSihTV4365URdkZ[ %@742.)(HJ^eikxtqmeaKI++(*()))Y9768XWrmyxonVS53AB\BA 7%{eg,{f*hy)4'&'&'&'&'&+327676767#!!2 %*,2HIS~\[55''JIprDpqIK&'E=F?D8@(.j**PQfhdc78=>eh&'>O4'&'&'&'&'&+327676767#!!2;#"47>763!!"'.'&. %).3EIT\[54('qrDpq'(55[[TIF3,*% ('qpDrq'(E=F?D8>*/j**PNig88=>ʃhfQP**.(@8DF?=E>=P88ą01pt67>32#"'&'&54326767654'&'&#"7327654'&'&'&+5327654&+"'767632#"&'#3B!!lBd~XcCA &0 % . < 8&% JT"4"  9:H885##QRtHѐI;;HwHMqX\xLJwFJRR:>I('*('214D=E)'*+09+!(!!6($2 > >%%65A1)'&$-rIJXJ.x% !!x@& '#@&x!5!' R&@%37 (@x  !' 78@@@@ %7  ':@@@@4X4jn\tlZZn4X%''lZZnZn4X 77!ZnZn\4X !n\rn\ZjxXh! !3!!#H@@llx^jHxXh!' 7!#!5!3@@jjl HH%327632'&#"#&/,^^PMfaG7p@J,`^^^^L,OBp, 2N"$#"'763232?'8[`]/H@p6HafKP^^N1 ,pBO,L^x 37!!'# 8"@8@"@  '#75 :"@8@"@x #7!5!'3' R"@8@"@ %5'377 "@8@"@x< ! !73#$@@였Ȁx< 7#'3!' 7!Ȁ@@x 53#5! @@f@@  %3!53 '8@@@@@x 53#5! @@f@@  #5!#7 Z@@f@@xt 7!!7  'xddd@@v@@x^! %#Z@@&X&|!#' 7!&@@Zx^3! !ހ@@(|!' 7!3@@ڀ@x5!7 xT*@@Vx3! !@@(HB &'&'&'0#"767676303GJ U+d^R4l ˩ZWΡXZHMIO:\T_ZmlHB 6767670327'&'&'�#HWZ ƥl4R^d+U JIşlmZ_T\:OIMHZX4X !!!4jn\Z$jZ\n,x  !!3!5!' 3@DdF@0dȀZ`/3276767654'&'&'!#"'&'&5ghkl3+:)i5CXRO= 1G:;~ /36%ddrk/*A/`<7M98yz ,A@9?o0`/#"'&'&'&5476767'!'3276767650 ~;:G1 =ORXC5i):+3lkhg?9A, zy89M7<`/A*/krdd%63/x `!x@@ @x !f@ @ '#@@f@ #@Z@fx^5!'x@@x !5!f37h@@3fBx  !!!5!' x@&&@ ʀJ@ '#37 J@&&@x %!5!' !!R&@f@&x6 !!-!!->,:8.8 #%#j,:8.8x6  7!5! 7!5!:,:8.  3% 3:,:8.x 7!=!@f@@@x !=!'f@@@@ b '!!!!eh""nTZHHU!  #7#!#UnTZHH@lh"" b '%5!5%!5e""fZHHHHHU! 33!3ZHHeh""  '%5 '!!!!eeh""fZnTZHHH %!'!3#3a%QPRK327654'&'&#"#"&'&5476324'&'&/&#"'632 KLHpVV_]h:53:>FB|{ no+"(   548tE[%N$.1/uDDlm'rOM53F{sp$!5H=K&㙗HPć   !(^ih2VFy )5!!5!!5!g0^X&$7H47>76763273#"/#7&'&'&7&'&#"%3267>54'&'&^ dECFCGmY;_% JKtrld ]'P u '" 97BFB<9%#zm:*"Y}8>2,L8#/.OLf 420Z.(L<4x33%!xFE#n`Bx!# x>`B";#"'&'&57676;#"!!SRVresssseuSQSgf$-;;-&dgm<!&.#&57676?33#!!;#"'&'# x\ss`}AAS|COVrecd@;QS;-]EE+%_ &dg:^Bq 5! #!5!276767!5!&'&'&'&#:f?ssefvRSAk @>hfСƀ-$\I_?42n@!#!#nҞjPn@33!3nP@:y %5 5% %(lP0<D:!!DDȎIH(;#"/#"&57#"'&54?'&547632'46327632@ ') *' (( '* )' }q"*& *" (+om+( "* &3#!5!]ۯڡ3'uC&~DCC3276767654'&'&#"&'0'5#".54767676326763"30/BA/07:ST:7 A($&&$>54'&#"dbPr@AbVn+"kk NQ'0jk"+VbA@rPblxdFGo`ۼܚvu , uvi`oGFdx63h%!!!mh8O! #3߀OKPO3#3{!Py4'&'&'&#"#476763243?BIz\]"-gfg@? STSugeuty3#"'&'&53327676765졊ŀ-"]\zL?=54òsteguSTSA@gfT )%547676767032&'#"/7>54#;DB&(16]&D#;DB&(19]&DAOPF= $ j1AOPF= $ j1\-?#"'&'&5476767632"&54767632!"&54767632P, !+ !t,@$ ->( D,@% ->)3& $% $ @,(>-( @,&>,) ?3Z\&6767632276?#"'&/"?,.,- %">;-),) ,& -*.&Bb>&*.67>32276?#"'&/"!!!!E,X. %";CH(*#*L9 ,*+('%#>>;.)*)    ,& -# .&a?\/[676763203276767#"'&'.'&'&#"67>323276767#"'&'&'&'&#"?!#%#0%$/ 1 !"""$! *F% 8 " !1 !"" "$B-$ &   !  &   p7##537!5!33!!!̙ϐ NTBb !!!!!!B   Xm> 5 !!hZg[/uѴm> 5-5!5yZ[u:^Bq!"3!!"'&'&5476)Bfh>@>RTOyfess?f24~K{[^"-:^Bq5! #!5!2767654&'&'&#:f?ssefyOTR>@>hfСƀ-"^[{K~42_%!0#3!!"'#7&'&547673G`t`AJUsOKR#1i7oH5\F 'LgoZ  %Khb9)d%!5!"3!!"'&'&5476)Kji7oHIVrgst?%Khb9:$ghond7!!5! #!5!2767654'&'&#dK>hsUIHo7ijtnoĞ$:9bhK%^X'1>H47>767632#"'&'&'&67676767!%4&5&'&'&'&'!^ dECFCG% JKtrldeQP y''86;%&B=:$ E*+86<!B<9% 1eWVt)(<3uw?>**\Y}8 L89%$>20L/5L<=$#5 /.O*6^X%0;E47>767632#"'&'&'&77'32767'67654'&/&'&#"^ dECFCG% JKtrldeQP u # #6;:**\Y}8>2,C7La$$LZ.(L< G"^%!!5!3OP"RT4632#"'&'&RL51!# L5.#$ E7J* 5L+ RDTF47632#"'&'&R&(31!# L5.#$ 7%&* 4L+ f !547676767032&'g +23$'FЏ# 59- 0#"/7676= +22%)F 0# 79-9% 3 UagX97# 3aaeZ #3o(ک0~S 3!!%~:e'%3"'&'&5"'&'&53;&crADrADc K%'W#"%'W#"Ky!!!33#;#"'&5!#yuFF;32;3276767653#"'732767676=#"'&'&'&5# MLtuOPPOutLM#":8JFO[NP21 [i##2/AQEB.,@ ^fW5: fDE26&#A>JHQՖjh4,3%)QRqSBC14vttvtsrs bTQ75!"21<99Vv!*&"  75PTUne`\ _FL:;B"$:;KPSaUO96U{!76GY<=!"BFjl&7<)$f@+H#5353%3276767653#"'732767676=#"'&'&'&5%;#"'&5􎎗fDF23"&%>8RKMՖjg2.3%)PQsRBE02uFF;<ZKO7;B"#:AFKX`UT61!U{!76F[;34# ,i 4-V}xE4632#"'&'&#53476767632#"'&'&5654'4'&'&!#!#F8&" 8& ,(41& /)'8&   %ėҘK&8" '8 b6>34# TQG '8& 2$-V}cz0#5354767676320'&'&'&#"#!#,(41&<%!.   ':—Ԙ6>34# +  / 4-Vdx"<##53476767632&'&'&#"!#%632#"'&'&5476+(41&;J-m (—K    V6=45" (*i .G  }x#DK0#"3###53547676767673##!5!476767632&'&'&#"3%#'#3.',/2Ę,4&D@c`혘!+(41&;J-m ( &%"V.C4.6$V6=45" (*i .V}w9KW#!##5354767676767632#"'&'&5654'4'&'&!#4632#"'&'&%!47fҘ,E {&*/)'8&"  %ėx8&  8&"\'42,UV.C4.F5=%TQG '8' 1$-&8! '8!H &%"60}) 2!7#!##53547676767%'#h'42,Ҙ,(2O7Td  — &%"}UV.C4.*!6dSS   }x :T!47#!##5354767676767632&'&'&#"0!#%632#"'&'&5476h'42,Ҙ,E {<%"/m ' —O     &%"61VV.C4.G4=% ,i  1G  436767632#"'&'&543276767654'&'&#".-ACQxSP"''l|RS!ZA0&' ,+@0&) \ON+-_\g_xw_a^`iiXQj|"#;=DLBY]f>=#%;>FKL%1 !53#5!#3LٞMF'767632!!5476767676?>76?4&#"o_`s1-.(-# * '(T.(,+1 ! fC@865iGH #'87C(H$%'"%G?D/.3,$##  $(0Zf)(Njx2?7327654'.'&+5327654'&+"'67632#"'&j%ORPa`^:8?Nb`IGIK^Oz5edzd\[;: !'%)%+%+&|~z-O13RQH8:FxGFmaCERF=e>=--VUiRAC&# 1,@>F{|JIV/ 3##!;!]^ ~$ts#Voe23"'!!632#"&'7327654'&'&D   ^B[tv" j҇.T߄RQ PP    KT7ab=@ڊơa`,'pLKv54'&'&#"3276632#"&'&547676767673dQRrRTRQiUUFH@|}! ! :8YWf N!hCCZ\s!f??WVde%9NNL@>('Β/(;9=3"7&.*HT2 #!5ն2PT%L%27654'&'&#"327654'&'&#"2#"$'&547676767&'&5462bb]ZuDC_oGFAAewBCSKLDCqo" *,&)( q]]" mCA(oU21A@rQ10BC0m&KLj+%kj<;Ο2.LEB-/U+,ve2532654'&'&#"#"'&'&54767>7632# sRPjUVH@} '+fMKOvt " |"gw'eA@XYef/0>?A6;Rge+,7<7;5#84ZxB-7&/054763253#5#"32765&'&#"knf !537X@B`HF=?vF36!=YqtmWFϜ!ORFE`:LN!LZx='Ca~Zx;'v~Zx'bn~Zx'Z~Zx'~Zx'jb~ZB'*~Zx<'~Zx)&q~&&2@4'&#"'6763267632&'&#"327#"'&5"#"'&'7327656>F(?V!Jr?)VnLV=&J>*:9;^JVH<9AI_?=9>u %^6uG -5MN_XLM94"ϚTT>7 >7 %7J++$$H@bN[K*V47632#"'&'&327673#"'&'&'#4'&#"#3>32>32#4&#"9>:>y %^5uH +5NLaWML94"˘**K4-/%$.?zNIHTJIVI4-/%$.7>7 > 8 Q 7J++$$H@b+B!#4'&#"#3>32>32#4&#"327673#"'&'&'a**K4-/%$.?zNIHTJIVI4-/%$. %^5uH +5NLaWML94"ML('n?l2cLo^mkr('n?I 7J++HH@b3!#3632#4'&'"327673#"'&'&'#}P 77Q252-( $1/5uH-6aWML94"2A"%$'nJK+&96<I"5 o 1S=LT$$H@b[\43 4'&+ ##!2 327673#"'&'&'!bcSמmvegHJ(*a` %/.7uG -5MN_XLM94"BCw35KOaml!v\7n(R>J++$$H@b0&#"#3676767632327673#"'&'&'DG/++!"!%!tY %^5uH -6LMaWML94"**(<:H|2&#7 79>)9>9>$>7 > 8 >7 > 8>,$6#53533#;#"&547632#"/&%47632#"/&uEEv9>:>)9>9>,uzv->7 > 8 >7 > 8L>?Qc7327>7654'&/$47676763 &'&#"&$47632#"/&%47632#"/&LZZYnF<=Z^Zn#">?RS` %}2WVp<64*'.ϐNX/2%&BA\\j49>9>(:>9>P:9R56BaJG7lRKI674OW10$!`:S34%*,/:8ZYMO98##>7 > 8 >7 > 8kSKDVh&'&'&'&54767676732&#"# '7327676765447632#"/&%47632#"/&k>F%'/,AEL:>:02 (%$(+dKD.*32PE!.$'L:?:>)9>9># $#$,+/:84*((*6y #g3%($+'/03?>:-,6"!-{\>7 > 8 >7 > 8U /3!3#!#47632#"/&%47632#"/&jv9>9>(9>:>~N^>7 > 8 >7 > 8-?!#36767>32##"47632#"/&%47632#"/&#-$#"#:*532*(9>9>(9>:>8"!n-+)788l>7 > 8 >7 > 8U 3!3#!#!!j]~N^ -3!!327654'&'&#"47632#"'&'&c LW(OW(uoDSM oDTM ۍSN"& TN!+N/n.1N/n,3# 1%3"'&53327654'&'&#"47632#"'&'&8vCBLW(NV)tnDTM nDTM i:9u3SN ( TN#)M/n,3M/n,3  1!!3!!327654'&'&#"47632#"'&'&f\c LW(OW(uoDSM oDTM }ۍSN"& TN!+N/n.1N/n,3# !5!!3"'&53327654'&'&#"47632#"'&'&B]zvCBLW(NV)tnDTM nDTM i:9u3SN ( TN#)M/n,3M/n,3[0D3 4'&+ ##!2 327650'&'&#"47632#"'&'&!bcSמmvegHJ(*a`QLV)NV)tnDTM nDTM BCw35KOaml!vSN"&!TN#)M/n,3M/n,3M-A&#"#3676767632327654'&'&#"47632#"'&'&DG/++!"!%!tYlLW(OV)uoDSM oDTM **(<:H|2&#7SN"& TN!+N/n,3N/n,3[ 4H!!3 4'&+ ##!2 327650'&'&#"47632#"'&'&])bcSמmvegHJ(*a`QLV)NV)tnDTM nDTM BCw35KOaml!vSN"&!TN#)M/n,3M/n,371E!!&#"#3676767632327654'&'&#"47632#"'&'&R]LDG/++!"!%!tYlLW(OV)uoDSM oDTM 7**(<:H|2&#7SN"& TN!+N/n,3N/n,3TT1 732=3#"'&'&wk   f#("("*$#f  {1ϋ?42 $  e #!#3#3)#'#7'373 ! %! !D`\G~}D^]D}*S\888խ jJwE6 !!EED62^X +G!#3##3267>54'&'&'&'&#"47>767632#"'&'&'&LQ ''86;:**\[{8!#!#FP@b)7R"327654'&$'&'53254'&5476322654'&#"&%&#" '&547676^BC][CBAAֿGHzeehHy{^AA^^BC,_0yfffffHz}^^AAAA^]CB+zSjgffM%&^]CB^^AAr-zSlggggfL&'X67654'&'&#"32463227#"&5454&#"#"'&'&54767632254'&FL H'%#$L H(%$-޲llFb@|nbIJ%2t86>9q.1u68KG.rH'$#$KH$(%!KmnzVFvxnؿLM};HE@bj VAr,0v57=;p,( Hl5T7!!&'&'&547676767632!!5676767654'&'&'&'&'&#"3!7#H3-+C?hgyzD2<< ;,IK99!! .%(,HEV^IJ.1!!89E`)~YIn2LMgdRM32\P;qp&I)dL(@AAB2;1 bM28"!()>'mJM'9hM629: ">j=;53'5#"'&'5#"#'&+"#4'36763267632J>XX67.9@C< (WXr$YZB>::)_`J<((lzrr__rjn~~842mn NZ[[`_}tddQPx!5!##'!5!f dVVh1923632#"'#536&#"04'&'5267>327&'"h('jvJJFGv,==vf08$MGDCOP%+-(xNZ~ [_]^cRSihtnؿ`mnYX@h6$(S32263227632&#"#"'&#"#"'&"#'322632327632&#"#"'&#"#"'&#"#'hBr, n76rU**zl^?^3:S98;7SU78lV4@t*n7697U+)|l^?]1=U79:6TU7878S4 (FFFF$24LJNDFHFGb &FFFF"25LLMCFFGF`!5!37!!'/"Ҥ"- ~S'*PE3צ4Btb6 2bfh8HyOFP&#"3#6767654'&&'&'&'&'&5476767>;767676732#"' #"W&.x~:$8+($   " f?3-/462 DHA)7QPGTQP(.'Av ,~uHbA>B7Wp&  $*!"(%%#0;&(6-;OqrqP)P6F,^X&Hd7!!3254'&'&'&'&+';2+#3267>54'&'&'&'&#"47>767632#"'&'&'&_N  !NWWNV68  ()4NW ''86;:**\[{8=>3=> `=>3=> ` 0#''73\ xb$RT4632#"'&'&RL51!# L5.#$ E7J* 5L+  $'6630 \3x$b>#!5p=>3=> `>!5!3D=>p !54'&/76303kF'%22+ -95 #>IMT<2p2 p2>2p2!p >c(B77#"'&'&54767262;254/'7032767654'&'&#"1_[; qrjZrmA"Ds/[K "BGNnKH  rQLg%W Pm}i`5-,:嗗\O_gw63Wmm #}34#" jY-u78ׇ. (<`#s'&54767676323#;#"'&5#5354'&'"&#" #"'&'7327654'&'&'&'&'&'&'&'&547632/5@K !uFF;<``"3 *:6Qt$ !  112-+$lk\_%45[e::"'/&?*2/""dg^# **.*4 jY-u78ׇ*4"zNH&  !'/6AZYCEnC$$00U)"  $#.1;KM%#5553% @N++㯭 y  !5!5N2@jP+  <!#' i3h #55#nEy #55%5%50P=J}JJJBZ3 3#BddBX<"^ !!!5!!5^OPlB 73!#5!57!!5!!B z{{(pg<(   $   6 327$~~<..9cc..c҅(~~$c-k-.ӅPccd !!!!5!!Plzݍ:[.6 !''%8p2pp1 p4!O!!OJ,0'654/ 7FԮ . FDŽ5{{J9wOiElJA"p'}8@0Y[) )3!!!!!!#!5!5!5!5!5!ɘ``````˜b".   $  zRh"" zh"&-<'!2'67654!"ĞǮnmJۗkh5PSRIE898:#S %%RV Qhէ2/{d!&'&543267654&%ňB䡢ΐ]_:"˽(^_a|~;;4 #  WT 333# #T+P3J 3 3 # #Jjc;˾^)'J733Px"!#!x8Wr 7%5%/ S$!6ї5zuY '7s`Ũbki`ŨbkX!3!3BPPx !3!3!3۝CBPPP_"647632#"'&'&_ -&<@+'- 2# +@$ _"647632#"'&'&_ -&<@+'- 2# +@$ _"647632#"'&'&_ -&<@+'- 2# +@$ _"647632#"'&'&_ -&<@+'- 2# +@$ iq$&$7$9+$Y\$Z$$$$(5)*7.22$273$w7$7Xy9$ 9(9H:$:H<$B<D??qDYHWIDIQIRIWIXI\JMuMMPR[TMUH\Mu2RY29RY29RYl lm37+%  1x   @O  # Ah  5T! U km#|  4      J3      b & & "Created by Thatcher Ulrich (http://tulrich.com), Karoly Barta (bartakarcsi@gmail.com) and Michael Everson with FontForge (http://fontforge.sf.net) This font, including hint instructions, has been donated to the Public Domain. Do whatever you want with it. Created by Thatcher Ulrich (http://tulrich.com), Karoly Barta (bartakarcsi@gmail.com) and Michael Everson with FontForge (http://fontforge.sf.net) This font, including hint instructions, has been donated to the Public Domain. Do whatever you want with it. TuffyTuffyRegularRegularFontForge : Tuffy Regular : 14-6-2012FontForge : Tuffy Regular : 14-6-2012Tuffy RegularTuffy RegularVersion 001.280 Version 001.280 TuffyTuffyThatcher Ulrich, Karoly Barta and Michael EversonThatcher Ulrich, Karoly Barta and Michael Eversonhttp://tulrich.com http://tulrich.com http://tulrich.com http://tulrich.com Public Domain Public Domain All Typographic FeaturesFonctions typographiquesAlle typografischen MglichkeitenFunzioni TipograficheAlle typografische kenmerkenLigaturesLigaturesLigaturenLegatureLigaturenFractionsFractionsBreukenAll Type FeaturesToutes fonctions typographiquesAlle AuszeichnungsartenTutte le FunzioniAlle typekenmerkenCommon LigaturesLigatures UsuellesNormale LigaturenLegature pi ComuniGemeenschappelijke LigaturenNo FractionsPas de FractionsKein BrucheNessuna FrazioneGeen breukenDiagonal FractionsFractions en DiagonaleDiagonaler BruchFrazioni DiagonaliDiagonale breuken2  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~uni007F softhyphenuni00B5AmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflex Cdotaccent cdotaccentDcarondcaronDcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflex Gdotaccent gdotaccent Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonekIJij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflex Tcommaaccent tcommaaccentTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongsuni01E2uni01E3 Scommaaccent scommaaccentuni021Auni021Buni021Cuni021Duni0250uni0251uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0259uni025Auni025Buni025Cuni025Duni025Euni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni0268uni0269uni026Auni026Buni026Cuni026Duni026Euni026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276uni0277uni0278uni0279uni027Auni027Buni027Cuni027Duni027Euni027Funi0280uni0281uni0282uni0283uni0284uni0285uni0286uni0287uni0288uni0289uni028Auni028Buni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni0293uni0294uni0295uni0296uni0297uni0298uni0299uni029Auni029Buni029Cuni029Duni029Euni029Funi02A0uni02A1uni02A2uni02A3uni02A4uni02A5uni02A6uni02A7uni02A8uni02A9uni02AAuni02ABuni02ACuni02ADuni02AEuni02AF macronsub gravecomb acutecombuni0302 tildecombuni0304uni0306uni0307uni0308uni030Auni030Buni030Cuni0310 dotbelowcombuni0324uni0325uni0327uni0328 brevesubnospuni0331uni0370uni0371uni0376uni037Auni037Buni037Cuni037Duni037Etonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammaEpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsi IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdanuxiomicronrhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonosuni03CFuni03D0theta1Upsilon1Upsilonhooktonosuni03D4phi1omega1uni03D7uni03D8uni03D9uni03DAuni03DBuni03DCuni03DDuni03DEuni03DFuni03E0uni03E1uni03E2uni03E3uni03E4uni03E5uni03E6uni03E7uni03E8uni03E9uni03EAuni03EBuni03ECuni03EDuni03EEuni03EF kappascriptuni03F1uni03F2uni03F3uni03F4uni03F5uni03F6uni03F7uni03F8uni03F9uni03FAuni03FBuni03FCuni03FDuni03FEuni03FFuni0400 afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061uni040D afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097uni0450 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109uni045D afii10110 afii10193uni048Auni048Buni048Cuni048Duni048Euni048FGheupturncyrillicgheupturncyrillicGhestrokecyrillicghestrokecyrillicGhemiddlehookcyrillicghemiddlehookcyrillicZhedescendercyrilliczhedescendercyrillicZedescendercyrilliczedescendercyrillicKadescendercyrillickadescendercyrillicKaverticalstrokecyrillickaverticalstrokecyrillicKastrokecyrillickastrokecyrillicKabashkircyrillickabashkircyrillicEndescendercyrillicendescendercyrillic Enghecyrillic enghecyrillicPemiddlehookcyrillicpemiddlehookcyrillicHaabkhasiancyrillichaabkhasiancyrillicEsdescendercyrillicesdescendercyrillicTedescendercyrillictedescendercyrillicUstraightcyrillicustraightcyrillicUstraightstrokecyrillicustraightstrokecyrillicHadescendercyrillichadescendercyrillic Tetsecyrillic tetsecyrillicChedescendercyrillicchedescendercyrillicCheverticalstrokecyrilliccheverticalstrokecyrillic Shhacyrillic shhacyrillicCheabkhasiancyrilliccheabkhasiancyrillicChedescenderabkhasiancyrillicchedescenderabkhasiancyrillicpalochkacyrillicZhebrevecyrilliczhebrevecyrillicKahookcyrillickahookcyrillicuni04C5uni04C6Enhookcyrillicenhookcyrillicuni04C9uni04CAChekhakassiancyrillicchekhakassiancyrillicuni04CDuni04CEuni04CFAbrevecyrillicabrevecyrillicAdieresiscyrillicadieresiscyrillic Aiecyrillic aiecyrillicIebrevecyrilliciebrevecyrillic Schwacyrillic schwacyrillicSchwadieresiscyrillicschwadieresiscyrillicZhedieresiscyrilliczhedieresiscyrillicZedieresiscyrilliczedieresiscyrillicDzeabkhasiancyrillicdzeabkhasiancyrillicImacroncyrillicimacroncyrillicIdieresiscyrillicidieresiscyrillicOdieresiscyrillicodieresiscyrillicObarredcyrillicobarredcyrillicObarreddieresiscyrillicobarreddieresiscyrillicuni04ECuni04EDUmacroncyrillicumacroncyrillicUdieresiscyrillicudieresiscyrillicUhungarumlautcyrillicuhungarumlautcyrillicChedieresiscyrillicchedieresiscyrillicuni04F6uni04F7Yerudieresiscyrillicyerudieresiscyrillic Bdotaccent bdotaccent Ddotaccent ddotaccentuni1E0Cuni1E0Duni1E0Euni1E0F Fdotaccent fdotaccentuni1E24uni1E25uni1E2Auni1E2Buni1E34uni1E35uni1E36uni1E37uni1E38uni1E39uni1E3Auni1E3B Mdotaccent mdotaccentuni1E42uni1E43uni1E44uni1E45uni1E46uni1E47uni1E48uni1E49 Pdotaccent pdotaccentuni1E5Auni1E5Buni1E5Cuni1E5Duni1E5Euni1E5F Sdotaccent sdotaccentuni1E62uni1E63 Tdotaccent tdotaccentuni1E6Cuni1E6Duni1E6Euni1E6FWgravewgraveWacutewacute Wdieresis wdieresisuni1E8Euni1E8Funi1E96uni1E9EYgraveygraveuni1EFAuni1EFB alphalenis alphaasperalphalenisgravealphaaspergravealphalenisacutealphaasperacutealphalenistildealphaaspertilde Alphalenis AlphaasperAlphalenisgraveAlphaaspergraveAlphalenisacuteAlphaasperacuteAlphalenistildeAlphaaspertilde epsilonlenis epsilonasperepsilonlenisgraveepsilonaspergraveepsilonlenisacuteepsilonasperacute Epsilonlenis EpsilonasperEpsilonlenisgraveEpsilonaspergraveEpsilonlenisacuteEpsilonasperacuteetalenisetaasper etalenisgrave etaaspergrave etalenisacute etaasperacute etalenistilde etaaspertildeEtalenisEtaasper Etalenisgrave Etaaspergrave Etalenisacute Etaasperacute Etalenistilde Etaaspertilde iotalenis iotaasperiotalenisgraveiotaaspergraveiotalenisacuteiotaasperacuteiotalenistildeiotaaspertilde Iotalenis IotaasperIotalenisgraveIotaaspergraveIotalenisacuteIotaasperacuteIotalenistildeIotaaspertilde omicronlenis omicronasperomicronlenisgraveomicronaspergraveomicronlenisacuteomicronasperacute Omicronlenis OmicronasperOmicronlenisgraveOmicronaspergraveOmicronlenisacuteOmicronasperacute upsilonlenis upsilonasperupsilonlenisgraveupsilonaspergraveupsilonlenisacuteupsilonasperacuteupsilonlenistildeupsilonaspertilde UpsilonasperUpsilonaspergraveUpsilonasperacuteUpsilonaspertilde omegalenis omegaasperomegalenisgraveomegaaspergraveomegalenisacuteomegaasperacuteomegalenistildeomegaaspertilde Omegalenis OmegaasperOmegalenisgraveOmegaaspergraveOmegalenisacuteOmegaasperacuteOmegalenistildeOmegaaspertilde alphagrave alphaacute epsilongrave epsilonacuteetagraveetaacute iotagrave iotaacute omicrongrave omicronacute upsilongrave upsilonacute omegagrave omegaacutealphaiotasublenisalphaiotasubasperalphaiotasublenisgravealphaiotasubaspergravealphaiotasublenisacutealphaiotasubasperacutealphaiotasublenistildealphaiotasubaspertildeAlphaiotasublenisAlphaiotasubasperAlphaiotasublenisgraveAlphaiotasubaspergraveAlphaiotasublenisacuteAlphaiotasubasperacuteAlphaiotasublenistildeAlphaiotasubaspertildeetaiotasublenisetaiotasubasperetaiotasublenisgraveetaiotasubaspergraveetaiotasublenisacuteetaiotasubasperacuteetaiotasublenistildeetaiotasubaspertildeEtaiotasublenisEtaiotasubasperEtaiotasublenisgraveEtaiotasubaspergraveEtaiotasublenisacuteEtaiotasubasperacuteEtaiotasublenistildeEtaiotasubaspertildeomegaiotasublenisomegaiotasubasperomegaiotasublenisgraveomegaiotasubaspergraveomegaiotasublenisacuteomegaiotasubasperacuteomegaiotasublenistildeomegaiotasubaspertildeOmegaiotasublenisOmegaiotasubasperOmegaiotasublenisgraveOmegaiotasubaspergraveOmegaiotasublenisacuteOmegaiotasubasperacuteOmegaiotasublenistildeOmegaiotasubaspertilde alphabreve alphamacronalphaiotasubgrave alphaiotasubalphaiotasubacute alphatildealphaiotasubtilde Alphabreve Alphamacron Alphagrave Alphaacute Alphaiotasublenis iotasubscriptpsili perispomenidialytika_perispomenietaiotasubgrave etaiotasubetaiotasubacuteetatildeetaiotasubtilde Epsilongrave EpsilonacuteEtagraveEtaacute Etaiotasub psili_varia psili_oxiapsili_perispomeni iotabreve iotamacroniotadieresisgraveiotadieresisacute iotatildeiotadieresistilde Iotabreve Iotamacron Iotagrave Iotaacute dasia_varia dasia_oxiadasia_perispomeni upsilonbreve upsilonmacronupsilondieresisgraveupsilondieresisacuterholenisrhoasper upsilontildeupsilondieresistilde Upsilonbreve Upsilonmacron Upsilongrave UpsilonacuteRhoasperdialytika_variadialytika_oxiavariaomegaiotasubgrave omegaiotasubomegaiotasubacute omegatildeomegaiotasubtilde Omicrongrave Omicronacute Omegagrave Omegaacute Omegaiotasuboxiaasperemspacethreeperemspacefourperemspace thinspace hairspace hyphentwo hyphennobreak figuredash horizontalbaruni2016 quotereverseduni201Funi2023onedotenleadertwodotenleaderuni2027uni2031minutesecond exclamdbluni203Duni203Funi2042uni2043uni2047uni2048uni2049uni204Buni204Cuni204Duni204Euni204Funi2052uni2053uni2056uni2058uni2059uni205Auni205Buni205Duni205Euni2070uni2071uni2072uni2073 foursuperioruni2075uni2076uni2077uni2078uni2079uni207Auni207Buni207Cuni207Duni207Euni207Funi2080uni2081uni2082uni2083uni2084uni2085uni2086uni2087uni2088uni2089uni208Auni208Buni208Cuni208Duni208Euni2090uni2091uni2092uni2093uni2094uni2098uni2099uni20A0 colonmonetaryuni20A2lirauni20A5uni20A6pesetauni20A8uni20A9 afii57636dongEurouni20ADuni20AEuni20AFuni20B0uni20B1uni20B2uni20B3uni20B4uni20B5uni20B6uni20B7uni20B8uni20B9 centigradeIfraktur afii61352 weierstrassRfrakturuni2126 estimatedalephonethird twothirdsuni2155uni2156uni2157uni2158uni2159uni215A oneeighth threeeighths fiveeighths seveneighthsuni215Funi2160uni2161uni2162uni2163uni2164uni2165uni2166uni2167uni2168uni2169uni216Auni216Buni216Cuni216Duni216Euni216Funi2170uni2171uni2172uni2173uni2174uni2175uni2176uni2177uni2178uni2179uni217Auni217Buni217Cuni217Duni217Euni217Funi2180uni2181uni2182uni2183uni2184uni2185uni2186uni2187uni2188uni2189 arrowleftarrowup arrowright arrowdown arrowboth arrowupdnuni2196uni2197uni2198uni2199uni219Auni219Buni219Cuni219Duni219Euni219Funi21A0uni21A1uni21A2uni21A3uni21A4uni21A5uni21A6uni21A7 arrowupdnbseuni21B0uni21B1uni21B2uni21B3uni21B4carriagereturnuni21B6uni21B7uni21B8uni21B9uni21BAuni21BBuni21BCuni21BDuni21BEuni21BFuni21C0uni21C1uni21C2uni21C3uni21C4uni21C5uni21C6uni21C7uni21C8uni21C9uni21CAuni21CBuni21CC arrowdblleft arrowdblup arrowdblright arrowdbldown arrowdblboth universal existentialemptysetuni2206gradientelement notelementuni220Duni2210 asteriskmathuni221Buni221C proportionalangle logicaland logicalor intersectionunion thereforesimilar congruent equivalence propersubsetpropersuperset notsubset reflexsubsetreflexsuperset circlepluscirclemultiply perpendicularuni22C4dotmath integraltp integralbt angleleft anglerightuniA746uniA747forintbrevealtg_yt_yc_t f_icircumflex f_idieresisf_igravef_iacutef_f_icircumflex f_f_idieresis f_f_igrave f_f_iacuteuniE118uniE119uniE11AuniE11BuniE11CuniE11DuniE11EuniE11FuniE120uniE121aalt agravealt aacutealt abrevealt atildealtacircumflexalt adieresisalt aogonekaltaringalt amacronaltxaltuniEFA0uniEFA1uniEFA2uniEFA3uniEFA4uniEFA5uniEFA6uniEFA7uniEFA8uniEFA9uniEFAAuniEFABuniEFACuniEFADuniEFB0uniEFB1uniEFB2uniEFB3uniEFB4uniEFB5uniEFB6uniEFB7uniEFB8 j.dotlessuniF8E5uniF8E6uniF8E7uniF8E8uniF8E9uniF8EAuniF8EBuniF8ECuniF8EDuniF8EEuniF8EFuniF8F0uniF8F1uniF8F2uniF8F3uniF8F4uniF8F5uniF8F6uniF8F7uniF8F8bracketrighttpbracketrightexbracketrightbt bracerighttpuniF8FDuniF8FEuniF8FFlongs_ts_tu10900u10901u10902u10903u10904u10905u10906u10907u10908u10909u1090Au1090Bu1090Cu1090Du1090Eu1090Fu10910u10911u10912u10913u10914u10915u10916u10917u10918u10919u1091Au1091Bu1091Fu1091Eu1091Du1091CU~       !! #" >> ?? @@ CA ^^ __ `` ca gdkh qm srutvv zx {{}    ƀ   >>     $" 42 @? EA \F `]aa bb gc hhyi zz}| ~          @ AAaB bb cc dd   04 8 F~ JJ$WW&\\(??ij( D hh&??????~d DF II   ?R?S?T?U?Z??\?ÿ?^?ƿ?`?ɿnolmrspqɉo1pPySDL2-0.9.3/sdl2/test/util/0000755000000000000000000000000012357043742012235 5ustar PySDL2-0.9.3/sdl2/test/util/__init__.py0000644000000000000000000000000012260256443014331 0ustar PySDL2-0.9.3/sdl2/test/util/runtests.py0000644000000000000000000002603112275100504014465 0ustar # # # # This file is placed under the public domain. # # import os import sys import imp import traceback import unittest import optparse import random import subprocess import time import inspect from . import support, testrunner if sys.version_info[0] >= 3: MAXINT = sys.maxsize else: MAXINT = sys.maxint LINEDELIM = "-" * 70 HEAVYDELIM = "=" * 70 # Excludes EXCLUDETAGS = ["interactive"] def printerror(): """Prints the last exception trace.""" print(traceback.format_exc()) def include_tag(option, opt, value, parser, *args, **kwargs): try: if args: EXCLUDETAGS.remove(args[0]) else: EXCLUDETAGS.remove(value) finally: pass def exclude_tag(option, opt, value, parser, *args, **kwargs): if value not in EXCLUDETAGS: EXCLUDETAGS.append(value) def list_tags(option, opt, value, parser, *args, **kwargs): alltags = [] testsuites = [] testdir, testfiles = gettestfiles(os.path.join (os.path.dirname(__file__), "..")) testloader = unittest.defaultTestLoader for test in testfiles: try: testmod = os.path.splitext(test)[0] fp, pathname, descr = imp.find_module(testmod, [testdir, ]) package = imp.load_module(testmod, fp, pathname, descr) try: testsuites.append(loadtests_frompkg(package, testloader)) except: printerror() except: pass for suite in testsuites: for test in suite: if hasattr(test, "__tags__"): tags = getattr(test, "__tags__") for tag in tags: if tag not in alltags: alltags.append(tag) print(alltags) sys.exit() def create_options(): """Create the accepatble options for the test runner.""" optparser = optparse.OptionParser() optparser.add_option("-f", "--filename", type="string", help="execute a single unit test file") optparser.add_option("-s", "--subprocess", action="store_true", default=False, help="run everything in an own subprocess " "(default: use a single process)") optparser.add_option("-t", "--timeout", type="int", default=70, help="Timout for subprocesses before being killed " "(default: 70s per file)") optparser.add_option("-v", "--verbose", action="store_true", default=False, help="be verbose and print anything instantly") optparser.add_option("-r", "--random", action="store_true", default=False, help="randomize the order of tests") optparser.add_option("-S", "--seed", type="int", help="seed the randomizer(useful to " "recreate earlier randomized test cases)") optparser.add_option("-i", "--interactive", action="callback", callback=include_tag, callback_args=("interactive",), help="also execute interactive tests") optparser.add_option("-e", "--exclude", action="callback", callback=exclude_tag, type="string", help="exclude test containing the tag") optparser.add_option("-l", "--listtags", action="callback", callback=list_tags, help="lists all available tags and exits") optparser.add_option("--logfile", type="string", help="save output to log file") optkeys = ["filename", "subprocess", "timeout", "random", "seed", "verbose" ] return optparser, optkeys def gettestfiles(testdir=None, randomizer=None): """Get all test files from the passed test directory. If none is passed, use the default sdl test directory. """ if not testdir: testdir = os.path.dirname(__file__) if testdir not in sys.path: sys.path.append(testdir) names = os.listdir(testdir) testfiles = [] for name in names: if name.endswith("_test" + os.extsep + "py"): testfiles.append(name) if randomizer: randomizer.shuffle(testfiles) else: testfiles.sort() return testdir, testfiles def loadtests_frompkg(package, loader): for x in dir(package): val = package.__dict__[x] if hasattr(val, "setUp") and hasattr(val, "tearDown"): # might be a test. return loader.loadTestsFromTestCase(val) def loadtests(package, test, testdir, writer, loader, options): """Loads a test.""" suites = [] try: testmod = os.path.splitext(test)[0] fp, pathname, descr = imp.find_module(testmod, [testdir, ]) package = imp.load_module("%s.%s" % (package, testmod), fp, pathname, descr) if options.verbose: writer.writeline("Loading tests from [%s] ..." % testmod) else: writer.writesame("Loading tests from [%s] ..." % testmod) try: suites.append(loadtests_frompkg(package, loader)) except: printerror() except: printerror() return suites def prepare_results(results): testcount = 0 errors = [] failures = [] skips = [] ok = 0 for res in results: testcount += res.testsRun ok += res.testsRun - len(res.errors) - len(res.failures) - \ len(res.skipped) errors.extend(res.errors) skips.extend(res.skipped) failures.extend(res.failures) return testcount, errors, failures, skips, ok def validate_args(options): if options.subprocess and options.filename: raise RuntimeError("-s cannot be used together with -f") def run(): optparser, optkeys = create_options() options, args = optparser.parse_args() validate_args(options) if options.logfile: openlog = open(options.logfile, 'wb') savedstd = sys.stderr, sys.stdout # copy stdout and stderr streams to log file sys.stderr = support.TeeOutput(sys.stderr, openlog) sys.stdout = support.TeeOutput(sys.stdout, openlog) writer = support.StreamOutput(sys.stdout) if options.verbose and not options.subprocess: writer.writeline(HEAVYDELIM) writer.writeline("-- Starting tests --") writer.writeline(HEAVYDELIM) randomizer = None if options.random: if options.seed is None: options.seed = random.randint(0, MAXINT) randomizer = random.Random(options.seed) loader = testrunner.TagTestLoader(EXCLUDETAGS, randomizer) testdir, testfiles = None, None if options.filename is not None: testdir = os.path.dirname(os.path.abspath(options.filename)) testfiles = [os.path.basename(options.filename), ] else: testdir, testfiles = gettestfiles(os.path.join (os.path.dirname(__file__), ".."), randomizer=randomizer) if options.subprocess: timeout = options.timeout gettime = time.time curmodule = "%s.%s" % (__package__, inspect.getmodulename(__file__)) for test in testfiles: writer.write("Executing tests from [%s]... " % test) procargs = [sys.executable, "-m", curmodule] procargs += ["-f", os.path.join(testdir, test)] proc = subprocess.Popen(procargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE) maxtime = gettime() + timeout retval = None while retval is None and gettime() < maxtime: retval = proc.poll() if retval is None: proc.kill() writer.writeline("execution timed out") elif retval != 0: writer.writeline("ERROR") writer.write(proc.stdout.read().decode("utf-8")) writer.writeline() else: writer.writeline("OK") if options.verbose: writer.write(proc.stdout.read().decode("utf-8")) writer.writeline() return 0 testsuites = [] package = __package__.rsplit(".", 1)[0] for test in testfiles: testsuites.extend(loadtests(package, test, testdir, writer, loader, options)) if not options.verbose: writer.writesame("Tests loaded") runner = testrunner.SimpleTestRunner(sys.stderr, options.verbose) results = [] timetaken = 0 if options.verbose: writer.writeline(HEAVYDELIM) writer.writeline("-- Executing tests --") writer.writeline(HEAVYDELIM) maxcount = 0 for suite in testsuites: maxcount += suite.countTestCases() class writerunning: def __init__(self, maxcount, verbose): self.curcount = 0 self.maxcount = maxcount self.verbose = verbose def __call__(self): self.curcount += 1 if not self.verbose: writer.writesame("Running tests [ %d / %d ] ..." % (self.curcount, self.maxcount)) runwrite = writerunning(maxcount, options.verbose) for suite in testsuites: result = runner.run(suite, runwrite) timetaken += result.duration results.append(result) writer.writeline() testcount, errors, failures, skips, ok = prepare_results(results) writer.writeline(HEAVYDELIM) writer.writeline("-- Statistics --") writer.writeline(HEAVYDELIM) writer.writeline("Python: %s" % sys.executable) writer.writeline("Options:") for key in optkeys: writer.writeline(" '%s' = '%s'" % (key, getattr(options, key))) writer.writeline(" 'excludetags' = '%s'" % EXCLUDETAGS) writer.writeline("Time taken: %.3f seconds" % timetaken) writer.writeline("Tests executed: %d " % testcount) writer.writeline("Tests OK: %d " % ok) writer.writeline("Tests SKIPPED: %d " % len(skips)) writer.writeline("Tests ERROR: %d " % len(errors)) writer.writeline("Tests FAILURE: %d " % len(failures)) if len(errors) > 0: writer.writeline("Errors:" + os.linesep) for err in errors: writer.writeline(LINEDELIM) writer.writeline("ERROR: %s" % err[0]) writer.writeline(HEAVYDELIM) writer.writeline(err[1]) if len(failures) > 0: writer.writeline("Failures:" + os.linesep) for fail in failures: writer.writeline(LINEDELIM) writer.writeline("FAILURE: %s" % fail[0]) writer.writeline(HEAVYDELIM) writer.writeline(fail[1]) if options.logfile: sys.stderr, sys.stdout = savedstd openlog.close() if len(errors) > 0 or len(failures) > 0: return 1 return 0 if __name__ == "__main__": sys.exit(run()) PySDL2-0.9.3/sdl2/test/util/support.py0000644000000000000000000000303612275100504014312 0ustar # # # # This file is placed under the public domain. # # """Utility functions for the tests.""" import os import sys PY3K = sys.version_info[0] == 3 class StreamOutput(object): def __init__(self, stream): self.stream = stream try: self.startoffset = self.stream.tell() except IOError: self.startoffset = 0 self.curoffset = 0 def writeline(self, data=None): if data: self.stream.write(data) self.stream.write(os.linesep) if data: self.curoffset = len(data) else: self.curoffset = 0 self.stream.flush() def write(self, data): self.stream.write(data) self.curoffset = len(data) self.stream.flush() def writesame(self, data): overhang = self.curoffset - len(data) if overhang > 0: self.stream.write("%s %s\r" % (data, " " * overhang)) else: self.stream.write("%s\r" % data) self.curoffset = len(data) self.stream.flush() class TeeOutput(object): def __init__(self, stream1, stream2): self.outputs = [stream1, stream2] # -- methods from sys.stdout / sys.stderr def write(self, data): for stream in self.outputs: if PY3K: if 'b' in stream.mode: data = data.encode('utf-8') stream.write(data) def tell(self): raise IOError def flush(self): for stream in self.outputs: stream.flush() # --/ sys.stdout PySDL2-0.9.3/sdl2/test/util/testrunner.py0000644000000000000000000000723712260256443015026 0ustar # # # # This file is placed under the public domain. # # import sys import os import unittest from unittest import TestResult, TestLoader import time class TagTestLoader(TestLoader): """A TestLoader which handles additional __tags__ attributes for test functions. """ def __init__(self, excludetags, randomizer=None): TestLoader.__init__(self) self.excludetags = excludetags self.randomizer = randomizer def getTestCaseNames(self, testCaseClass): """Gets only the tests, which are not within the tag exclusion. The method overrides the original TestLoader.getTestCaseNames() method, so we need to keep them in sync on updates. """ def isTestMethod(attrname, testCaseClass=testCaseClass, prefix=self.testMethodPrefix): if not attrname.startswith(prefix): return False if not hasattr(getattr(testCaseClass, attrname), "__call__"): return False if hasattr(getattr(testCaseClass, attrname), "__tags__"): # Tagged test method tags = getattr(getattr(testCaseClass, attrname), "__tags__") for t in tags: if t in self.excludetags: return False return True if hasattr(testCaseClass, "__tags__"): tags = getattr(testCaseClass, "__tags__") for t in tags: if t in self.excludetags: return [] testFnNames = list(filter(isTestMethod, dir(testCaseClass))) cmpkey = getattr(unittest, "_CmpToKey", None) or \ getattr(unittest, "CmpToKey", None) if self.randomizer: self.randomizer.shuffle(testFnNames) elif self.sortTestMethodsUsing: if cmpkey: testFnNames.sort(key=cmpkey(self.sortTestMethodsUsing)) else: testFnNames.sort() return testFnNames class SimpleTestResult(TestResult): """A simple TestResult class with output capabilities. """ def __init__(self, stream=sys.stderr, verbose=False, countcall=None): TestResult.__init__(self) self.stream = stream self.duration = 0 self.verbose = verbose self.countcall = countcall def addSkip(self, test, reason): TestResult.addSkip(self, test, reason) if self.verbose: self.stream.write("SKIPPED: %s [%s]%s" % (test, reason, os.linesep)) self.stream.flush() self.countcall() def addSuccess(self, test): TestResult.addSuccess(self, test) if self.verbose: self.stream.write("OK: %s%s" % (test, os.linesep)) self.stream.flush() self.countcall() def addError(self, test, err): TestResult.addError(self, test, err) if self.verbose: self.stream.write("ERROR: %s%s" % (test, os.linesep)) self.stream.flush() self.countcall() def addFailure(self, test, err): TestResult.addFailure(self, test, err) if self.verbose: self.stream.write("FAILED: %s%s" % (test, os.linesep)) self.stream.flush() self.countcall() class SimpleTestRunner(object): def __init__(self, stream=sys.stderr, verbose=False): self.stream = stream self.verbose = verbose def run(self, test, countcall): result = SimpleTestResult(self.stream, self.verbose, countcall) starttime = time.time() test(result) endtime = time.time() result.duration = endtime - starttime return result PySDL2-0.9.3/sdl2/test/util/testutils.py0000644000000000000000000000205612260256443014647 0ustar # # # # This file is placed under the public domain. # # import os try: getinput = raw_input except NameError: getinput = input def getanswer(question): answer = getinput("%s [y/n]: " % question) return answer.lower().strip() == 'y' def doprint(text): getinput("%s (press enter to continue) " % text) class interactive(object): """Simple interactive question decorator for unit test methods. """ def __init__(self, question=None): self.question = question def __call__(self, func): def wrapper(*fargs, **kw): if fargs and getattr(fargs[0], "__class__", None): instance = fargs[0] funcargs = fargs[1:] print(os.linesep) func(instance, *funcargs, **kw) if self.question: if not getanswer(self.question): instance.fail() wrapper.__name__ = func.__name__ wrapper.__dict__.update(func.__dict__) wrapper.__tags__ = ['interactive'] return wrapper PySDL2-0.9.3/sdl2/test/__init__.py0000644000000000000000000000033412260256443013366 0ustar """Unit tests SDL2. This package contains the unit tests for SDL2. You can execute the unit tests using python -c "import sdl.test; sdl.test.run()" """ import sys from .util.runtests import run __all__ = ["run"] PySDL2-0.9.3/sdl2/test/audio_test.py0000644000000000000000000003312012312245641013762 0ustar import os import sys import ctypes import unittest from .. import SDL_Init, SDL_Quit, SDL_InitSubSystem, SDL_QuitSubSystem, \ SDL_INIT_AUDIO from .. import audio class SDLAudioTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): SDL_Init(0) def audio_cb(userdata, audiobytes, length): pass self.audiocallback = audio.SDL_AudioCallback(audio_cb) def tearDown(self): SDL_Quit() def test_SDL_AUDIO_BITSIZE(self): self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_U8), 8) self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_S8), 8) self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_U16LSB), 16) self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_S16LSB), 16) self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_U16MSB), 16) self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_S16MSB), 16) self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_U16), 16) self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_S16), 16) self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_S32LSB), 32) self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_S32MSB), 32) self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_S32), 32) self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_F32LSB), 32) self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_F32MSB), 32) self.assertEqual(audio.SDL_AUDIO_BITSIZE(audio.AUDIO_F32), 32) def test_SDL_AUDIO_ISFLOAT(self): self.assertFalse(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_U8)) self.assertFalse(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_S8)) self.assertFalse(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_U16LSB)) self.assertFalse(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_S16LSB)) self.assertFalse(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_U16MSB)) self.assertFalse(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_S16MSB)) self.assertFalse(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_U16)) self.assertFalse(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_S16)) self.assertFalse(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_S32LSB)) self.assertFalse(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_S32MSB)) self.assertFalse(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_S32)) self.assertTrue(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_F32LSB)) self.assertTrue(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_F32MSB)) self.assertTrue(audio.SDL_AUDIO_ISFLOAT(audio.AUDIO_F32)) def test_SDL_AUDIO_ISBIGENDIAN(self): self.assertFalse(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_U8)) self.assertFalse(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_S8)) self.assertFalse(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_U16LSB)) self.assertFalse(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_S16LSB)) self.assertTrue(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_U16MSB)) self.assertTrue(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_S16MSB)) self.assertFalse(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_U16)) self.assertFalse(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_S16)) self.assertFalse(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_S32LSB)) self.assertTrue(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_S32MSB)) self.assertFalse(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_S32)) self.assertFalse(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_F32LSB)) self.assertTrue(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_F32MSB)) self.assertFalse(audio.SDL_AUDIO_ISBIGENDIAN(audio.AUDIO_F32)) def test_SDL_AUDIO_ISSIGNED(self): self.assertFalse(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_U8)) self.assertTrue(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_S8)) self.assertFalse(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_U16LSB)) self.assertTrue(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_S16LSB)) self.assertFalse(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_U16MSB)) self.assertTrue(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_S16MSB)) self.assertFalse(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_U16)) self.assertTrue(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_S16)) self.assertTrue(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_S32LSB)) self.assertTrue(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_S32MSB)) self.assertTrue(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_S32)) self.assertTrue(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_F32LSB)) self.assertTrue(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_F32MSB)) self.assertTrue(audio.SDL_AUDIO_ISSIGNED(audio.AUDIO_F32)) def test_SDL_AUDIO_ISINT(self): self.assertTrue(audio.SDL_AUDIO_ISINT(audio.AUDIO_U8)) self.assertTrue(audio.SDL_AUDIO_ISINT(audio.AUDIO_S8)) self.assertTrue(audio.SDL_AUDIO_ISINT(audio.AUDIO_U16LSB)) self.assertTrue(audio.SDL_AUDIO_ISINT(audio.AUDIO_S16LSB)) self.assertTrue(audio.SDL_AUDIO_ISINT(audio.AUDIO_U16MSB)) self.assertTrue(audio.SDL_AUDIO_ISINT(audio.AUDIO_S16MSB)) self.assertTrue(audio.SDL_AUDIO_ISINT(audio.AUDIO_U16)) self.assertTrue(audio.SDL_AUDIO_ISINT(audio.AUDIO_S16)) self.assertTrue(audio.SDL_AUDIO_ISINT(audio.AUDIO_S32LSB)) self.assertTrue(audio.SDL_AUDIO_ISINT(audio.AUDIO_S32MSB)) self.assertTrue(audio.SDL_AUDIO_ISINT(audio.AUDIO_S32)) self.assertFalse(audio.SDL_AUDIO_ISINT(audio.AUDIO_F32LSB)) self.assertFalse(audio.SDL_AUDIO_ISINT(audio.AUDIO_F32MSB)) self.assertFalse(audio.SDL_AUDIO_ISINT(audio.AUDIO_F32)) def test_SDL_AUDIO_ISLITTLEENDIAN(self): self.assertTrue(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_U8)) self.assertTrue(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_S8)) self.assertTrue(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_U16LSB)) self.assertTrue(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_S16LSB)) self.assertFalse(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_U16MSB)) self.assertFalse(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_S16MSB)) self.assertTrue(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_U16)) self.assertTrue(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_S16)) self.assertTrue(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_S32LSB)) self.assertFalse(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_S32MSB)) self.assertTrue(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_S32)) self.assertTrue(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_F32LSB)) self.assertFalse(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_F32MSB)) self.assertTrue(audio.SDL_AUDIO_ISLITTLEENDIAN(audio.AUDIO_F32)) def test_SDL_AUDIO_ISUNSIGNED(self): self.assertTrue(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_U8)) self.assertFalse(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_S8)) self.assertTrue(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_U16LSB)) self.assertFalse(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_S16LSB)) self.assertTrue(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_U16MSB)) self.assertFalse(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_S16MSB)) self.assertTrue(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_U16)) self.assertFalse(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_S16)) self.assertFalse(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_S32LSB)) self.assertFalse(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_S32MSB)) self.assertFalse(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_S32)) self.assertFalse(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_F32LSB)) self.assertFalse(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_F32MSB)) self.assertFalse(audio.SDL_AUDIO_ISUNSIGNED(audio.AUDIO_F32)) @unittest.skip("not implemented") def test_SDL_AudioSpec(self): pass @unittest.skip("not implemented") def test_SDL_AudioCVT(self): pass def test_SDL_GetNumAudioDrivers(self): count = audio.SDL_GetNumAudioDrivers() self.assertGreaterEqual(count, 1) def test_SDL_GetAudioDriver(self): founddummy = False drivercount = audio.SDL_GetNumAudioDrivers() for index in range(drivercount): drivername = audio.SDL_GetAudioDriver(index) self.assertIsInstance(drivername, (str, bytes)) if drivername == b"dummy": founddummy = True self.assertTrue(founddummy, "could not find dummy driver") # self.assertRaises(SDLError, audio.SDL_GetAudioDriver, -1) # self.assertRaises(SDLError, audio.get_audio_driver, # drivercount + 1) self.assertRaises((ctypes.ArgumentError, TypeError), audio.SDL_GetAudioDriver, "Test") self.assertRaises((ctypes.ArgumentError, TypeError), audio.SDL_GetAudioDriver, None) def test_SDL_GetCurrentAudioDriver(self): success = 0 for index in range(audio.SDL_GetNumAudioDrivers()): drivername = audio.SDL_GetAudioDriver(index) os.environ["SDL_AUDIODRIVER"] = drivername.decode("utf-8") # Certain drivers fail without bringing up the correct # return value, such as the esd, if it is not running. SDL_InitSubSystem(SDL_INIT_AUDIO) driver = audio.SDL_GetCurrentAudioDriver() # Do not handle wrong return values. if driver is not None: self.assertEqual(drivername, driver) success += 1 SDL_QuitSubSystem(SDL_INIT_AUDIO) self.assertGreaterEqual(success, 1, "Could not initialize any sound driver") @unittest.skip("SDL_AudioCallback is not retained in SDL_AudioSpec") def test_SDL_OpenAudio(self): os.environ["SDL_AUDIODRIVER"] = "dummy" SDL_InitSubSystem(SDL_INIT_AUDIO) reqspec = audio.SDL_AudioSpec(44100, audio.AUDIO_U16SYS, 2, 8192, self.audiocallback, None) spec = audio.SDL_AudioSpec(0, 0, 0, 0) ret = audio.SDL_OpenAudio(reqspec, ctypes.byref(spec)) self.assertEqual(ret, 0) self.assertEqual(spec.format, reqspec.format) self.assertEqual(spec.freq, reqspec.freq) self.assertEqual(spec.channels, reqspec.channels) audio.SDL_CloseAudio() SDL_QuitSubSystem(SDL_INIT_AUDIO) def test_SDL_GetNumAudioDevices(self): os.environ["SDL_AUDIODRIVER"] = "dummy" SDL_InitSubSystem(SDL_INIT_AUDIO) outnum = audio.SDL_GetNumAudioDevices(False) self.assertGreaterEqual(outnum, 1) innum = audio.SDL_GetNumAudioDevices(True) self.assertGreaterEqual(innum, 0) SDL_QuitSubSystem(SDL_INIT_AUDIO) def test_SDL_GetAudioDeviceName(self): os.environ["SDL_AUDIODRIVER"] = "dummy" SDL_InitSubSystem(SDL_INIT_AUDIO) outnum = audio.SDL_GetNumAudioDevices(False) for x in range(outnum): name = audio.SDL_GetAudioDeviceName(x, False) self.assertIsNotNone(name) innum = audio.SDL_GetNumAudioDevices(True) for x in range(innum): name = audio.SDL_GetAudioDeviceName(x, True) self.assertIsNotNone(name) # self.assertRaises(SDLError, audio.get_audio_device_name, -1) # self.assertRaises(SDLError, audio.get_audio_device_name, -1, True) SDL_QuitSubSystem(SDL_INIT_AUDIO) # self.assertRaises(SDLError, audio.get_audio_device_name, 0) # self.assertRaises(SDLError, audio.get_audio_device_name, 0, True) @unittest.skip("SDL_AudioCallback is not retained in SDL_AudioSpec") def test_SDL_OpenCloseAudioDevice(self): os.environ["SDL_AUDIODRIVER"] = "dummy" SDL_InitSubSystem(SDL_INIT_AUDIO) reqspec = audio.SDL_AudioSpec(44100, audio.AUDIO_U16SYS, 2, 8192, self.audiocallback, None) outnum = audio.SDL_GetNumAudioDevices(0) for x in range(outnum): spec = audio.SDL_AudioSpec() name = audio.SDL_GetAudioDeviceName(x, 0) self.assertIsNotNone(name) deviceid = audio.SDL_OpenAudioDevice(None, 0, reqspec, ctypes.byref(spec), 1) self.assertGreaterEqual(deviceid, 2) self.assertIsInstance(spec, audio.SDL_AudioSpec) self.assertEqual(spec.format, reqspec.format) self.assertEqual(spec.freq, reqspec.freq) self.assertEqual(spec.channels, reqspec.channels) audio.SDL_CloseAudioDevice(deviceid) SDL_QuitSubSystem(SDL_INIT_AUDIO) @unittest.skip("not implemented") def test_SDL_GetAudioStatus(self): pass @unittest.skip("not implemented") def test_SDL_GetAudioDeviceStatus(self): pass @unittest.skip("not implemented") def test_SDL_PausAudio(self): pass @unittest.skip("not implemented") def test_SDL_PauseAudioDevice(self): pass @unittest.skip("not implemented") def test_SDL_LoadWAV_RW(self): pass @unittest.skip("not implemented") def test_SDL_LoadWAV(self): pass @unittest.skip("not implemented") def test_SDL_FreeWAV(self): pass @unittest.skip("not implemented") def test_SDL_BuildAudioCVT(self): pass @unittest.skip("not implemented") def test_SDL_ConvertAudio(self): pass @unittest.skip("not implemented") def test_SDL_MixAudio(self): pass @unittest.skip("not implemented") def test_SDL_MixAudioFormat(self): pass @unittest.skip("not implemented") def test_SDL_LockUnlockAudio(self): pass @unittest.skip("not implemented") def test_SDL_LockUnlockAudioDevice(self): pass @unittest.skip("not implemented") def test_SDL_CloseAudio(self): pass if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/clipboard_test.py0000644000000000000000000000373412260256443014634 0ustar import sys import unittest from .. import SDL_Init, SDL_Quit, SDL_InitSubSystem, SDL_INIT_EVERYTHING from .. import clipboard from ..stdinc import SDL_TRUE from .util.testutils import interactive, doprint def is_win_or_mac(): return sys.platform in ("win32", "cygwin", "darwin", "cli") class SDLClipboardTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): SDL_Init(SDL_INIT_EVERYTHING) def tearDown(self): SDL_Quit() @unittest.skipIf(not is_win_or_mac(), "we would need a SDL window") @interactive() def test_SDL_HasClipboardText(self): doprint("Please put some text on the clipboard") self.assertEqual(clipboard.SDL_HasClipboardText(), SDL_TRUE) @unittest.skipIf(not is_win_or_mac(), "we would need a SDL window") @interactive("Does the shown value match the clipboard content?") def test_SDL_GetClipboardText(self): doprint("Please put some text on the clipboard") retval = clipboard.SDL_GetClipboardText() doprint("Clipboard content: '%s'" % retval) @unittest.skipIf(not is_win_or_mac(), "we would need a SDL window") def test_SDL_SetClipboardText(self): self.assertEquals(clipboard.SDL_SetClipboardText(b"Test content"), 0) retval = clipboard.SDL_GetClipboardText() self.assertEqual(retval, b"Test content") if sys.platform != "cli": # TODO: Check next IronPython version (>2.7.4) self.assertEquals(clipboard.SDL_SetClipboardText(b""), 0) retval = clipboard.SDL_GetClipboardText() self.assertEqual(retval, b"") self.assertEquals(clipboard.SDL_SetClipboardText(b"Test content"), 0) retval = clipboard.SDL_GetClipboardText() self.assertEqual(retval, b"Test content") self.assertEquals(clipboard.SDL_SetClipboardText(None), 0) retval = clipboard.SDL_GetClipboardText() self.assertEqual(retval, b"") if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/cpuinfo_test.py0000644000000000000000000000322012273410303014315 0ustar import sys import unittest from .. import cpuinfo _HASMP = True try: import multiprocessing except: _HASMP = False class SDLCPUInfoTest(unittest.TestCase): __tags__ = ["sdl"] def test_SDL_GetCPUCacheLineSize(self): ret = cpuinfo.SDL_GetCPUCacheLineSize() self.assertIsInstance(ret, int) def test_SDL_GetCPUCount(self): if _HASMP: self.assertEqual(multiprocessing.cpu_count(), cpuinfo.SDL_GetCPUCount()) else: self.assertGreaterEqual(cpuinfo.SDL_GetCPUCount(), 1) def test_SDL_Has3DNow(self): ret = cpuinfo.SDL_Has3DNow() self.assertIn(ret, (0, 1)) def test_SDL_HasAltiVec(self): ret = cpuinfo.SDL_HasAltiVec() self.assertIn(ret, (0, 1)) def test_SDL_HasMMX(self): ret = cpuinfo.SDL_HasMMX() self.assertIn(ret, (0, 1)) def test_SDL_HasRDTSC(self): ret = cpuinfo.SDL_HasRDTSC() self.assertIn(ret, (0, 1)) def test_SDL_HasSSE(self): ret = cpuinfo.SDL_HasSSE() self.assertIn(ret, (0, 1)) def test_SDL_HasSSE2(self): ret = cpuinfo.SDL_HasSSE2() self.assertIn(ret, (0, 1)) def test_SDL_HasSSE3(self): ret = cpuinfo.SDL_HasSSE3() self.assertIn(ret, (0, 1)) def test_SDL_HasSSE41(self): ret = cpuinfo.SDL_HasSSE41() self.assertIn(ret, (0, 1)) def test_SDL_HasSSE42(self): ret = cpuinfo.SDL_HasSSE42() self.assertIn(ret, (0, 1)) def test_SDL_HasAVX(self): ret = cpuinfo.SDL_HasAVX() self.assertIn(ret, (0, 1)) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/endian_test.py0000644000000000000000000001023412260256443014124 0ustar import sys import math import unittest from .. import endian class SDLEndianTest(unittest.TestCase): __tags__ = ["sdl"] def test_SDL_BYTEORDER(self): if sys.byteorder == "little": self.assertEqual(endian.SDL_BYTEORDER, endian.SDL_LIL_ENDIAN) else: self.assertEqual(endian.SDL_BYTEORDER, endian.SDL_BIG_ENDIAN) def test_SDL_Swap16(self): self.assertEqual(endian.SDL_Swap16(0xFF00), 0x00FF) self.assertEqual(endian.SDL_Swap16(0x0001), 0x0100) self.assertEqual(endian.SDL_Swap16(0x0032), 0x3200) self.assertEqual(endian.SDL_Swap16(0x0FF0), 0xF00F) self.assertEqual(endian.SDL_Swap16(0x00FF), 0xFF00) self.assertEqual(endian.SDL_Swap16(0x1234), 0x3412) if sys.byteorder == "little": self.assertEqual(endian.SDL_Swap16, endian.SDL_SwapBE16) self.assertNotEqual(endian.SDL_Swap16, endian.SDL_SwapLE16) else: self.assertNotEqual(endian.SDL_Swap16, endian.SDL_SwapBE16) self.assertEqual(endian.SDL_Swap16, endian.SDL_SwapLE16) def test_SDL_Swap32(self): self.assertEqual(endian.SDL_Swap32(0xFF000000), 0x000000FF) self.assertEqual(endian.SDL_Swap32(0x00FF0000), 0x0000FF00) self.assertEqual(endian.SDL_Swap32(0x0000FF00), 0x00FF0000) self.assertEqual(endian.SDL_Swap32(0x000000FF), 0xFF000000) self.assertEqual(endian.SDL_Swap32(0x12345678), 0x78563412) self.assertEqual(endian.SDL_Swap32(0xFF00FF00), 0x00FF00FF) if sys.byteorder == "little": self.assertEqual(endian.SDL_Swap32, endian.SDL_SwapBE32) self.assertNotEqual(endian.SDL_Swap32, endian.SDL_SwapLE32) else: self.assertNotEqual(endian.SDL_Swap32, endian.SDL_SwapBE32) self.assertEqual(endian.SDL_Swap32, endian.SDL_SwapLE32) def test_SDL_Swap64(self): self.assertEqual(endian.SDL_Swap64(0xFF00000000000000), 0x00000000000000FF) self.assertEqual(endian.SDL_Swap64(0x00FF000000000000), 0x000000000000FF00) self.assertEqual(endian.SDL_Swap64(0x0000FF0000000000), 0x0000000000FF0000) self.assertEqual(endian.SDL_Swap64(0x000000FF00000000), 0x00000000FF000000) self.assertEqual(endian.SDL_Swap64(0x00000000FF000000), 0x000000FF00000000) self.assertEqual(endian.SDL_Swap64(0x0000000000FF0000), 0x0000FF0000000000) self.assertEqual(endian.SDL_Swap64(0x000000000000FF00), 0x00FF000000000000) self.assertEqual(endian.SDL_Swap64(0x00000000000000FF), 0xFF00000000000000) self.assertEqual(endian.SDL_Swap64(0x0123456789ABCDEF), 0xEFCDAB8967452301) if sys.byteorder == "little": self.assertEqual(endian.SDL_Swap64, endian.SDL_SwapBE64) self.assertNotEqual(endian.SDL_Swap64, endian.SDL_SwapLE64) else: self.assertNotEqual(endian.SDL_Swap64, endian.SDL_SwapBE64) self.assertEqual(endian.SDL_Swap64, endian.SDL_SwapLE64) def test_SDL_SwapFloat(self): v = -100.0 while v < 101: p = endian.SDL_SwapFloat(v) self.assertNotEqual(p, v) self.assertEqual(endian.SDL_SwapFloat(p), v) v += 0.1 values = (sys.float_info.epsilon, sys.float_info.min, sys.float_info.max, - sys.float_info.min, math.pi, - math.pi ) for v in values: p = endian.SDL_SwapFloat(v) self.assertNotEqual(p, v) self.assertEqual(endian.SDL_SwapFloat(p), v) if sys.byteorder == "little": self.assertEqual(endian.SDL_SwapFloat, endian.SDL_SwapFloatBE) self.assertNotEqual(endian.SDL_SwapFloat, endian.SDL_SwapFloatLE) else: self.assertNotEqual(endian.SDL_SwapFloat, endian.SDL_SwapFloatBE) self.assertEqual(endian.SDL_SwapFloat, endian.SDL_SwapFloatLE) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/error_test.py0000644000000000000000000000173212260256443014022 0ustar import sys import unittest from .. import SDL_Init, SDL_Quit, error class SDLTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): SDL_Init(0) def tearDown(self): SDL_Quit() def test_SDL_ClearError(self): error.SDL_ClearError() self.assertEqual(error.SDL_GetError(), b"") def test_SDL_SetError(self): self.assertEqual(error.SDL_GetError(), b"") error.SDL_SetError(b"A Unit Test Error Message") self.assertEqual(error.SDL_GetError(), b"A Unit Test Error Message") error.SDL_ClearError() error.SDL_SetError(b"A Unit Test Error Message") self.assertEqual(error.SDL_GetError(), b"A Unit Test Error Message") self.assertEqual(error.SDL_GetError(), b"A Unit Test Error Message") error.SDL_ClearError() error.SDL_SetError(b"123456789") self.assertEqual(error.SDL_GetError(), b"123456789") if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/events_test.py0000644000000000000000000001457312260256443014204 0ustar import sys import unittest from ctypes import c_char_p, c_void_p, cast from .. import SDL_Init, SDL_Quit, SDL_QuitSubSystem, SDL_INIT_EVERYTHING from .. import events class SDLEventsTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): SDL_Init(SDL_INIT_EVERYTHING) def tearDown(self): SDL_QuitSubSystem(SDL_INIT_EVERYTHING) SDL_Quit() def test_SDL_WindowEvent(self): event = events.SDL_WindowEvent() self.assertIsInstance(event, events.SDL_WindowEvent) def test_SDL_KeyboardEvent(self): event = events.SDL_KeyboardEvent() self.assertIsInstance(event, events.SDL_KeyboardEvent) def test_SDL_TextEditingEvent(self): event = events.SDL_TextEditingEvent() self.assertIsInstance(event, events.SDL_TextEditingEvent) def test_SDL_TextInputEvent(self): event = events.SDL_TextInputEvent() self.assertIsInstance(event, events.SDL_TextInputEvent) def test_SDL_MouseMotionEvent(self): event = events.SDL_MouseMotionEvent() self.assertIsInstance(event, events.SDL_MouseMotionEvent) def test_SDL_MouseButtonEvent(self): event = events.SDL_MouseButtonEvent() self.assertIsInstance(event, events.SDL_MouseButtonEvent) def test_SDL_MouseWheelEvent(self): event = events.SDL_MouseWheelEvent() self.assertIsInstance(event, events.SDL_MouseWheelEvent) def test_SDL_JoyAxisEvent(self): event = events.SDL_JoyAxisEvent() self.assertIsInstance(event, events.SDL_JoyAxisEvent) def test_SDL_JoyBallEvent(self): event = events.SDL_JoyBallEvent() self.assertIsInstance(event, events.SDL_JoyBallEvent) def test_SDL_JoyHatEvent(self): event = events.SDL_JoyHatEvent() self.assertIsInstance(event, events.SDL_JoyHatEvent) def test_SDL_JoyButtonEvent(self): event = events.SDL_JoyButtonEvent() self.assertIsInstance(event, events.SDL_JoyButtonEvent) def test_SDL_TouchFingerEvent(self): event = events.SDL_TouchFingerEvent() self.assertIsInstance(event, events.SDL_TouchFingerEvent) def test_SDL_MultiGestureEvent(self): event = events.SDL_MultiGestureEvent() self.assertIsInstance(event, events.SDL_MultiGestureEvent) def test_SDL_DollarGestureEvent(self): event = events.SDL_DollarGestureEvent() self.assertIsInstance(event, events.SDL_DollarGestureEvent) def test_SDL_DropEvent(self): event = events.SDL_DropEvent() self.assertIsInstance(event, events.SDL_DropEvent) def test_SDL_QuitEvent(self): event = events.SDL_QuitEvent() self.assertIsInstance(event, events.SDL_QuitEvent) def test_SDL_UserEvent(self): event = events.SDL_UserEvent() self.assertIsInstance(event, events.SDL_UserEvent) def test_SDL_SysWMEvent(self): event = events.SDL_SysWMEvent() self.assertIsInstance(event, events.SDL_SysWMEvent) def test_SDL_Event(self): event = events.SDL_Event() self.assertIsInstance(event, events.SDL_Event) @unittest.skipIf(sys.platform == "cli", "IronPython's ctypes can't handle Union types correctly") def test_SDL_AddDelEventWatch(self): eventwatch = [] def watch(data, event): eventwatch.append((event.contents, data,)) return 0 efilter = events.SDL_EventFilter(watch) udata = c_char_p(b"Something random") events.SDL_AddEventWatch(efilter, cast(udata, c_void_p)) ev = events.SDL_Event() ev.type = events.SDL_USEREVENT ev.user = events.SDL_UserEvent() events.SDL_PushEvent(ev) self.assertEqual(len(eventwatch), 1) # TODO: x # self.assertEqual(eventwatch[0][1], udata) events.SDL_DelEventWatch(efilter, udata) ev = events.SDL_Event() events.SDL_PushEvent(ev) self.assertEqual(len(eventwatch), 1) # TODO: x # self.assertEqual(eventwatch[0][1], udata) @unittest.skipIf(sys.platform == "cli", "IronPython's ctypes can't handle Union types correctly") def test_SDL_EventState(self): pass # state = events.SDL_EventState(events.SDL_USEREVENT, events.SDL_QUERY) # self.assertEqual(state, events.SDL_ENABLE) # state = events.SDL_EventState(events.SDL_USEREVENT,events.SDL_IGNORE) # self.assertEqual(state, events.SDL_ENABLE) # state = events.SDL_EventState(events.SDL_USEREVENT, events.SDL_QUERY) # self.assertEqual(state, events.SDL_IGNORE) # state = events.SDL_EventState(events.SDL_USEREVENT,events.SDL_ENABLE) # self.assertEqual(state, events.SDL_IGNORE) # state = events.SDL_EventState(events.SDL_USEREVENT, events.SDL_QUERY) # self.assertEqual(state, events.SDL_ENABLE) # self.assertRaises(TypeError, events.SDL_EventState, None, None) # ev = events.SDL_Event() # ev.type = events.SDL_USEREVENT # ev.user = events.SDL_UserEvent() # events.SDL_PushEvent(ev) @unittest.skip("not implemented") def test_SDL_GetEventState(self): pass @unittest.skip("not implemented") def test_SDL_FilterEvents(self): pass @unittest.skip("not implemented") def test_SDL_FlushEvent(self): pass @unittest.skip("not implemented") def test_SDL_FlushEvents(self): pass @unittest.skip("not implemented") def test_SDL_GetSetEventFilter(self): pass @unittest.skip("not implemented") def test_SDL_HasEvent(self): pass @unittest.skip("not implemented") def test_SDL_HasEvents(self): pass @unittest.skip("not implemented") def test_SDL_PeepEvents(self): pass @unittest.skip("not implemented") def test_SDL_PollEvent(self): pass @unittest.skip("not implemented") def test_SDL_PumpEvents(self): pass @unittest.skip("not implemented") def test_SDL_PushEvent(self): pass @unittest.skip("not implemented") def test_SDL_RegisterEvents(self): pass @unittest.skip("not implemented") def test_SDL_WaitEvent(self): pass @unittest.skip("not implemented") def test_SDL_WaitEventTimeout(self): pass @unittest.skip("not implemented") def test_SDL_QuitRequested(self): pass if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/filesystem_test.py0000644000000000000000000000112712260256443015053 0ustar import os import sys import unittest from ctypes import cast, c_char_p, addressof from .. import filesystem, SDL_free class SDLFileSystemTest(unittest.TestCase): __tags__ = ["sdl"] def test_SDL_GetBasePath(self): execpath = os.path.dirname(sys.executable) + os.sep path = filesystem.SDL_GetBasePath() ppath = cast(path, c_char_p).value self.assertEqual(execpath, ppath.decode("utf-8")) SDL_free(path) @unittest.skip("not implemented") def test_SDL_GetPrefPath(self): pass if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/hints_test.py0000644000000000000000000000745112260256443014022 0ustar import sys import unittest from ctypes import cast, c_char_p from .. import SDL_Init, SDL_Quit, SDL_QuitSubSystem, SDL_INIT_EVERYTHING from .. import hints class SDLHintsTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): SDL_Init(SDL_INIT_EVERYTHING) def tearDown(self): SDL_QuitSubSystem(SDL_INIT_EVERYTHING) SDL_Quit() def test_SDL_ClearHints(self): self.assertEqual(hints.SDL_SetHint(b"TEST", b"32"), 1) self.assertEqual(hints.SDL_GetHint(b"TEST"), b"32") hints.SDL_ClearHints() self.assertEqual(hints.SDL_GetHint(b"TEST"), None) def test_SDL_GetHint(self): self.assertEqual(hints.SDL_SetHint(b"TEST", b"32"), 1) self.assertEqual(hints.SDL_GetHint(b"TEST"), b"32") self.assertEqual(hints.SDL_SetHint(hints.SDL_HINT_RENDER_DRIVER, b"dummy"), 1) self.assertEqual(hints.SDL_GetHint(hints.SDL_HINT_RENDER_DRIVER), b"dummy") def test_SDL_SetHint(self): self.assertEqual(hints.SDL_SetHint(b"TEST", b"32"), 1) self.assertEqual(hints.SDL_GetHint(b"TEST"), b"32") self.assertEqual(hints.SDL_SetHint(b"TEST", b"abcdef"), 1) self.assertEqual(hints.SDL_GetHint(b"TEST"), b"abcdef") if sys.platform != "cli": # TODO: Check on next IronPython version (>2.7.4) self.assertEqual(hints.SDL_SetHint(b"", b""), 1) self.assertEqual(hints.SDL_GetHint(b""), b"") def test_SDL_SetHintWithPriority(self): self.assertEqual(hints.SDL_SetHintWithPriority (b"TEST", b"32", hints.SDL_HINT_DEFAULT), 1) self.assertEqual(hints.SDL_GetHint(b"TEST"), b"32") self.assertEqual(hints.SDL_SetHintWithPriority (b"TEST", b"abcdef", hints.SDL_HINT_NORMAL), 1) self.assertEqual(hints.SDL_GetHint(b"TEST"), b"abcdef") if sys.platform != "cli": # TODO: Check on next IronPython version (>2.7.4) self.assertEqual(hints.SDL_SetHintWithPriority (b"", b"", hints.SDL_HINT_OVERRIDE), 1) self.assertEqual(hints.SDL_GetHint(b""), b"") # self.assertRaises(ValueError, hints.SDL_SetHintWithPriority, # "TEST", "123456789", 12) # self.assertRaises(ValueError, hints.SDL_SetHintWithPriority, # "TEST", "123456789", -78) # self.assertRaises(ValueError, hints.SDL_SetHintWithPriority, # "TEST", "123456789", None) # self.assertRaises(ValueError, hints.SDL_SetHintWithPriority, # "TEST", "123456789", "bananas") def test_SDL_AddDelHintCallback(self): calls = [] def callback(userdata, name, oldval, newval): data = cast(userdata, c_char_p) calls.append((data.value, name, oldval, newval)) hintcb = hints.SDL_HintCallback(callback) udata = c_char_p(b"banana") hints.SDL_AddHintCallback(hints.SDL_HINT_ALLOW_TOPMOST, hintcb, udata) # SDL_AddHintCallback invokes the callback once. self.assertEqual(len(calls), 1) self.assertEqual(calls[0], (b"banana", hints.SDL_HINT_ALLOW_TOPMOST, None, None)) hints.SDL_SetHint(hints.SDL_HINT_ALLOW_TOPMOST, b"true") self.assertEqual(len(calls), 2) self.assertEqual(calls[1], (b"banana", hints.SDL_HINT_ALLOW_TOPMOST, None, b"true")) hints.SDL_DelHintCallback(hints.SDL_HINT_ALLOW_TOPMOST, hintcb, udata) hints.SDL_SetHint(hints.SDL_HINT_ALLOW_TOPMOST, b"false") self.assertEqual(len(calls), 2) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/joystick_test.py0000644000000000000000000001407712260256443014536 0ustar import sys import unittest from .. import SDL_Init, SDL_Quit, SDL_QuitSubSystem, SDL_INIT_JOYSTICK from ..events import SDL_QUERY, SDL_ENABLE, SDL_IGNORE from .. import joystick class SDLJoystickTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): SDL_Init(SDL_INIT_JOYSTICK) self.jcount = joystick.SDL_NumJoysticks() def tearDown(self): SDL_QuitSubSystem(SDL_INIT_JOYSTICK) SDL_Quit() def test_SDL_NumJoysticks(self): retval = joystick.SDL_NumJoysticks() self.assertGreaterEqual(retval, 0) def test_SDL_JoystickNameForIndex(self): if self.jcount == 0: self.skipTest("no joysticks detected") for index in range(self.jcount): name = joystick.SDL_JoystickNameForIndex(index) self.assertIn(type(name), (str, bytes)) # self.assertRaises(sdl.SDLError, joystick.joystick_name, # self.jcount + 1) # self.assertRaises(sdl.SDLError, joystick.joystick_name, -10) # self.assertRaises(ValueError, joystick.joystick_name, "Test") # self.assertRaises(TypeError, joystick.joystick_name, None) def test_SDL_JoystickOpenClose(self): if self.jcount == 0: self.skipTest("no joysticks detected") for index in range(self.jcount): stick = joystick.SDL_JoystickOpen(index) self.assertIsInstance(stick.contents, joystick.SDL_Joystick) # self.assertTrue(joystick.joystick_opened(index)) joystick.SDL_JoystickClose(stick) # self.assertFalse(joystick.joystick_opened(index)) # self.assertRaises(sdl.SDLError, joystick.joystick_open, # self.jcount + 1) # self.assertRaises(sdl.SDLError, joystick.joystick_open, -10) # self.assertRaises(ValueError, joystick.joystick_open, "Test") # self.assertRaises(TypeError, joystick.joystick_open, None) def test_SDL_JoystickNumAxes(self): if self.jcount == 0: self.skipTest("no joysticks detected") for index in range(self.jcount): stick = joystick.SDL_JoystickOpen(index) self.assertIsInstance(stick.contents, joystick.SDL_Joystick) axes = joystick.SDL_JoystickNumAxes(stick) self.assertGreaterEqual(axes, 0) joystick.SDL_JoystickClose(stick) def test_SDL_JoystickNumBalls(self): if self.jcount == 0: self.skipTest("no joysticks detected") for index in range(self.jcount): stick = joystick.SDL_JoystickOpen(index) self.assertIsInstance(stick.contents, joystick.SDL_Joystick) balls = joystick.SDL_JoystickNumBalls(stick) self.assertGreaterEqual(balls, 0) joystick.SDL_JoystickClose(stick) def test_SDL_JoystickNumButtons(self): if self.jcount == 0: self.skipTest("no joysticks detected") for index in range(self.jcount): stick = joystick.SDL_JoystickOpen(index) self.assertIsInstance(stick.contents, joystick.SDL_Joystick) buttons = joystick.SDL_JoystickNumButtons(stick) self.assertGreaterEqual(buttons, 0) joystick.SDL_JoystickClose(stick) def test_SDL_JoystickNumHats(self): if self.jcount == 0: self.skipTest("no joysticks detected") for index in range(self.jcount): stick = joystick.SDL_JoystickOpen(index) self.assertIsInstance(stick.contents, joystick.SDL_Joystick) hats = joystick.SDL_JoystickNumHats(stick) self.assertGreaterEqual(hats, 0) joystick.SDL_JoystickClose(stick) def test_SDL_JoystickUpdate(self): if self.jcount == 0: self.skipTest("no joysticks detected") joystick.SDL_JoystickUpdate() def test_SDL_JoystickEventState(self): if self.jcount == 0: self.skipTest("no joysticks detected") for state in(SDL_IGNORE, SDL_ENABLE): news = joystick.SDL_JoystickEventState(state) self.assertEqual(news, state) query = joystick.SDL_JoystickEventState(SDL_QUERY) self.assertEqual(query, state) def test_SDL_JoystickGetAxis(self): if self.jcount == 0: self.skipTest("no joysticks detected") for index in range(self.jcount): stick = joystick.SDL_JoystickOpen(index) for axis in range(joystick.SDL_JoystickNumAxes(stick)): val = joystick.SDL_JoystickGetAxis(stick, axis) self.assertTrue(-32768 <= val <= 32767) joystick.SDL_JoystickClose(stick) def test_SDL_JoystickGetBall(self): if self.jcount == 0: self.skipTest("no joysticks detected") for index in range(self.jcount): stick = joystick.SDL_JoystickOpen(index) for ball in range(joystick.SDL_JoystickNumBalls(stick)): dx, dy = joystick.SDL_JoystickGetBall(stick, ball) self.assertIsInstance(dx, int) self.assertIsInstance(dy, int) # TODO joystick.SDL_JoystickClose(stick) def test_SDL_JoystickGetHat(self): if self.jcount == 0: self.skipTest("no joysticks detected") for index in range(self.jcount): stick = joystick.SDL_JoystickOpen(index) for hat in range(joystick.SDL_JoystickNumHats(stick)): val = joystick.SDL_JoystickGetHat(stick, hat) self.assertIsInstance(val, int) # TODO joystick.SDL_JoystickClose(stick) def test_SDL_JoystickGetButton(self): if self.jcount == 0: self.skipTest("no joysticks detected") for index in range(self.jcount): stick = joystick.SDL_JoystickOpen(index) for button in range(joystick.SDL_JoystickNumButtons(stick)): val = joystick.SDL_JoystickGetButton(stick, button) # TODO: x # self.assertIsInstance(val, bool) joystick.SDL_JoystickClose(stick) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/keyboard_test.py0000644000000000000000000001612612260256443014474 0ustar import sys import unittest from .. import SDL_Init, SDL_Quit, SDL_QuitSubSystem, SDL_INIT_VIDEO from .. import rect, keyboard, scancode, keycode, video from ctypes import c_int, cast, POINTER byteify = lambda x: x.encode("utf-8") class SDLKeyboardTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): SDL_Init(SDL_INIT_VIDEO) def tearDown(self): SDL_QuitSubSystem(SDL_INIT_VIDEO) SDL_Quit() def test_SDL_Keysym(self): keysym = keyboard.SDL_Keysym() self.assertEqual(keysym.scancode, 0) self.assertEqual(keysym.sym, 0) self.assertEqual(keysym.mod, 0) self.assertEqual(keysym.unicode, ord("\0")) # TODO keysym = keyboard.SDL_Keysym(1, 2, 3, ord("b")) self.assertEqual(keysym.scancode, 1) self.assertEqual(keysym.sym, 2) self.assertEqual(keysym.mod, 3) self.assertEqual(keysym.unicode, ord("b")) uval = "\u0220" if sys.version_info[0] < 3: uval = unichr(8224) keysym = keyboard.SDL_Keysym(17, 32, 88, ord(uval)) self.assertEqual(keysym.scancode, 17) self.assertEqual(keysym.sym, 32) self.assertEqual(keysym.mod, 88) self.assertEqual(keysym.unicode, ord(uval)) def test_SDL_GetKeyboardFocus(self): window = keyboard.SDL_GetKeyboardFocus() # TODO: x # self.assertEqual(window, None) rwin = video.SDL_CreateWindow(b"test", 10, 10, 10, 10, 0) window = keyboard.SDL_GetKeyboardFocus() if window: self.assertEqual(video.SDL_GetWindowID(window), video.SDL_GetWindowID(rwin)) video.SDL_DestroyWindow(rwin) window = keyboard.SDL_GetKeyboardFocus() # TODO: x # self.assertEqual(window, None) def test_SDL_GetKeyboardState(self): states = (c_int * scancode.SDL_NUM_SCANCODES)() keyboard.SDL_GetKeyboardState(cast(states, POINTER(c_int))) self.assertEqual(len(states), scancode.SDL_NUM_SCANCODES) # TODO: x # for state in states: # self.assertEqual(state, 0) def test_SDL_GetKeyFromName(self): for x in range(26): # a-z key = keyboard.SDL_GetKeyFromName(byteify(chr(x + 97))) self.assertEqual(key, x + 97) for x in range(10): key = keyboard.SDL_GetKeyFromName(("%d" % x).encode("utf-8")) self.assertEqual(key, 48 + x) val = keyboard.SDL_GetKeyFromName(byteify(repr(self))) self.assertEqual(val, keycode.SDLK_UNKNOWN) def test_SDL_GetKeyFromScancode(self): p = 0 for x in (scancode.SDL_SCANCODE_A, scancode.SDL_SCANCODE_B, scancode.SDL_SCANCODE_C): key = keyboard.SDL_GetKeyFromScancode(x) self.assertEqual(key, p + 97) p += 1 p = 0 for x in range(scancode.SDL_SCANCODE_1, scancode.SDL_SCANCODE_0): key = keyboard.SDL_GetKeyFromScancode(x) self.assertEqual(key, 49 + p) p += 1 # self.assertRaises(TypeError, keyboard.get_key_from_scancode, self) # self.assertRaises(ValueError, keyboard.get_key_from_scancode, "Test") # self.assertRaises(TypeError, keyboard.get_key_from_scancode, None) def test_SDL_GetKeyName(self): x = 65 # SDL maps everything against upper-case letters for key in range(ord('a'), ord('z')): ch = chr(x) name = keyboard.SDL_GetKeyName(key) self.assertEqual(name, byteify(ch)) x += 1 def test_SDL_GetSetModState(self): initial = keyboard.SDL_GetModState() for state in(keycode.KMOD_NUM | keycode.KMOD_CAPS | keycode.KMOD_MODE, keycode.KMOD_NUM | keycode.KMOD_CAPS, keycode.KMOD_CAPS): keyboard.SDL_SetModState(state) self.assertEqual(keyboard.SDL_GetModState(), state) state = keycode.KMOD_NUM keyboard.SDL_SetModState(state) self.assertEqual(keyboard.SDL_GetModState(), state) keyboard.SDL_SetModState(initial) self.assertEqual(keyboard.SDL_GetModState(), initial) def test_SDL_GetScancodeFromKey(self): codes = range(scancode.SDL_SCANCODE_1, scancode.SDL_SCANCODE_0) xoff = 0 for key in range(ord('1'), ord('0')): code = keyboard.SDL_GetScancodeFromKey(key) self.assertEqual(code, codes[xoff]) xoff += 1 key = keyboard.SDL_GetScancodeFromKey(477) self.assertEqual(key, scancode.SDL_SCANCODE_UNKNOWN) # self.assertRaises(TypeError, keyboard.get_scancode_from_key, None) # self.assertRaises(ValueError, keyboard.get_scancode_from_key, "Test") # self.assertRaises(TypeError, keyboard.get_scancode_from_key, self) @unittest.skipIf(sys.platform=="cli", "IronPython can't pass empty bytes() to ctypes") def test_SDL_GetScancodeFromName(self): codes = range(scancode.SDL_SCANCODE_A, scancode.SDL_SCANCODE_Z) xoff = 0 for key in range(ord('a'), ord('z')): ch = chr(key) code = keyboard.SDL_GetScancodeFromName(byteify(ch)) self.assertEqual(code, codes[xoff]) xoff += 1 key = keyboard.SDL_GetScancodeFromName(b"") self.assertEqual(key, scancode.SDL_SCANCODE_UNKNOWN) key = keyboard.SDL_GetScancodeFromName(None) self.assertEqual(key, scancode.SDL_SCANCODE_UNKNOWN) key = keyboard.SDL_GetScancodeFromName(b"Test") self.assertEqual(key, scancode.SDL_SCANCODE_UNKNOWN) key = keyboard.SDL_GetScancodeFromName(byteify(repr(self))) self.assertEqual(key, scancode.SDL_SCANCODE_UNKNOWN) def test_SDL_GetScancodeName(self): names = range(ord('A'), ord('Z')) xoff = 0 for code in range(scancode.SDL_SCANCODE_A, scancode.SDL_SCANCODE_Z): name = keyboard.SDL_GetScancodeName(code) self.assertEqual(name, byteify(chr(names[xoff]))) xoff += 1 name = keyboard.SDL_GetScancodeName(0) self.assertEqual(name, b"") # self.assertRaises(ValueError, keyboard.SDL_GetScancodeName, -22) # self.assertRaises(ValueError, keyboard.SDL_GetScancodeName, # scancode.SDL_NUM_SCANCODES) # self.assertRaises(TypeError, keyboard.get_scancode_from_key, None) # self.assertRaises(ValueError, keyboard.get_scancode_from_key, "Test") # self.assertRaises(TypeError, keyboard.get_scancode_from_key, self) def test_SDL_SetTextInputRect(self): # TODO: this test is a bit pointless coords = [(0, 0, 0, 0), (-10, -70, 3, 6), (10, 10, 10, 10)] for x, y, w, h in coords: r = rect.SDL_Rect(x, y, w, h) keyboard.SDL_SetTextInputRect(r) keyboard.SDL_SetTextInputRect(rect.SDL_Rect()) @unittest.skip("not implemented") def test_SDL_StartTextInput(self): keyboard.SDL_StartTextInput() @unittest.skip("not implemented") def test_SDL_StopTextInput(self): keyboard.SDL_StopTextInput() if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/log_test.py0000644000000000000000000003240612260256443013454 0ustar import sys import unittest import ctypes from .. import log @unittest.skipIf(sys.platform == "cli", "IronPython does not handle func pointers correctly") class SDLLogTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): self.logdata = [] def logfunc(userdata, category, priority, message): if userdata: userdata = ctypes.cast(userdata, ctypes.c_char_p).value self.logdata.append((userdata, category, priority, message,)) # bind to the TestCase, so we do not loose the reference. self.funcptr = log.SDL_LogOutputFunction(logfunc) log.SDL_LogSetOutputFunction(self.funcptr, None) log.SDL_LogSetAllPriority(log.SDL_LOG_PRIORITY_VERBOSE) def tearDown(self): log.SDL_LogSetOutputFunction(log.SDL_LogOutputFunction(), None) del self.funcptr def test_SDL_LogMessage(self): self.logdata = [] # reset the log log.SDL_LogMessage(log.SDL_LOG_CATEGORY_APPLICATION, log.SDL_LOG_PRIORITY_VERBOSE, b"test") self.assertEqual(self.logdata[0], (None, log.SDL_LOG_CATEGORY_APPLICATION, log.SDL_LOG_PRIORITY_VERBOSE, b"test")) log.SDL_LogMessage(log.SDL_LOG_CATEGORY_CUSTOM, log.SDL_LOG_PRIORITY_CRITICAL, b"test2") self.assertEqual(self.logdata[1], (None, log.SDL_LOG_CATEGORY_CUSTOM, log.SDL_LOG_PRIORITY_CRITICAL, b"test2")) #self.assertRaises(TypeError, log.SDL_LogMessage, None, None, None) #self.assertRaises(ValueError, log.SDL_LogMessage, 123, None, None) #self.assertRaises(ValueError, log.SDL_LogMessage, 123, 456, None) #self.assertRaises(ValueError, log.SDL_LogMessage, 123, 456, "Test") #self.assertRaises(TypeError, log.SDL_LogMessage, # log.SDL_LOG_CATEGORY_CUSTOM, None, None) #self.assertRaises(ValueError, log.SDL_LogMessage, # log.SDL_LOG_CATEGORY_CUSTOM, 123, None) #self.assertRaises(ValueError, log.SDL_LogMessage, # log.SDL_LOG_CATEGORY_CUSTOM, 123, "Test") def test_SDL_Log(self): self.logdata = [] # reset the log log.SDL_Log(b"test") self.assertEqual(self.logdata[0], (None, log.SDL_LOG_CATEGORY_APPLICATION, log.SDL_LOG_PRIORITY_INFO, b"test")) log.SDL_Log(b"abcdeghijk") self.assertEqual(self.logdata[1], (None, log.SDL_LOG_CATEGORY_APPLICATION, log.SDL_LOG_PRIORITY_INFO, b"abcdeghijk")) def test_SDL_LogCritical(self): self.logdata = [] # reset the log log.SDL_LogCritical(log.SDL_LOG_CATEGORY_APPLICATION, b"test") self.assertEqual(self.logdata[0], (None, log.SDL_LOG_CATEGORY_APPLICATION, log.SDL_LOG_PRIORITY_CRITICAL, b"test")) log.SDL_LogCritical(log.SDL_LOG_CATEGORY_SYSTEM, b"test") self.assertEqual(self.logdata[1], (None, log.SDL_LOG_CATEGORY_SYSTEM, log.SDL_LOG_PRIORITY_CRITICAL, b"test")) #self.assertRaises(TypeError, log.SDL_LogCritical, None, None) #self.assertRaises(ValueError, log.SDL_LogCritical, 123, None) #self.assertRaises(ValueError, log.SDL_LogCritical, 123, "Test") def test_SDL_LogDebug(self): self.logdata = [] # reset the log log.SDL_LogDebug(log.SDL_LOG_CATEGORY_APPLICATION, b"test") self.assertEqual(self.logdata[0], (None, log.SDL_LOG_CATEGORY_APPLICATION, log.SDL_LOG_PRIORITY_DEBUG, b"test")) log.SDL_LogDebug(log.SDL_LOG_CATEGORY_SYSTEM, b"test") self.assertEqual(self.logdata[1], (None, log.SDL_LOG_CATEGORY_SYSTEM, log.SDL_LOG_PRIORITY_DEBUG, b"test")) #self.assertRaises(TypeError, log.SDL_LogDebug, None, None) #self.assertRaises(ValueError, log.SDL_LogDebug, 123, None) #self.assertRaises(ValueError, log.SDL_LogDebug, 123, "Test") def test_SDL_LogError(self): self.logdata = [] # reset the log log.SDL_LogError(log.SDL_LOG_CATEGORY_APPLICATION, b"test") self.assertEqual(self.logdata[0], (None, log.SDL_LOG_CATEGORY_APPLICATION, log.SDL_LOG_PRIORITY_ERROR, b"test")) log.SDL_LogError(log.SDL_LOG_CATEGORY_SYSTEM, b"test") self.assertEqual(self.logdata[1], (None, log.SDL_LOG_CATEGORY_SYSTEM, log.SDL_LOG_PRIORITY_ERROR, b"test")) #self.assertRaises(TypeError, log.SDL_LogError, None, None) #self.assertRaises(ValueError, log.SDL_LogError, 123, None) #self.assertRaises(ValueError, log.SDL_LogError, 123, "Test") def test_SDL_LogInfo(self): self.logdata = [] # reset the log log.SDL_LogInfo(log.SDL_LOG_CATEGORY_APPLICATION, b"test") self.assertEqual(self.logdata[0], (None, log.SDL_LOG_CATEGORY_APPLICATION, log.SDL_LOG_PRIORITY_INFO, b"test")) log.SDL_LogInfo(log.SDL_LOG_CATEGORY_SYSTEM, b"test") self.assertEqual(self.logdata[1], (None, log.SDL_LOG_CATEGORY_SYSTEM, log.SDL_LOG_PRIORITY_INFO, b"test")) #self.assertRaises(TypeError, log.SDL_LogInfo, None, None) #self.assertRaises(ValueError, log.SDL_LogInfo, 123, None) #self.assertRaises(ValueError, log.SDL_LogInfo, 123, "Test") def test_SDL_LogVerbose(self): self.logdata = [] # reset the log log.SDL_LogVerbose(log.SDL_LOG_CATEGORY_APPLICATION, b"test") self.assertEqual(self.logdata[0], (None, log.SDL_LOG_CATEGORY_APPLICATION, log.SDL_LOG_PRIORITY_VERBOSE, b"test")) log.SDL_LogVerbose(log.SDL_LOG_CATEGORY_SYSTEM, b"test") self.assertEqual(self.logdata[1], (None, log.SDL_LOG_CATEGORY_SYSTEM, log.SDL_LOG_PRIORITY_VERBOSE, b"test")) #self.assertRaises(TypeError, log.SDL_LogVerbose, None, None) #self.assertRaises(ValueError, log.SDL_LogVerbose, 123, None) #self.assertRaises(ValueError, log.SDL_LogVerbose, 123, "Test") def test_SDL_LogWarn(self): self.logdata = [] # reset the log log.SDL_LogWarn(log.SDL_LOG_CATEGORY_APPLICATION, b"test") self.assertEqual(self.logdata[0], (None, log.SDL_LOG_CATEGORY_APPLICATION, log.SDL_LOG_PRIORITY_WARN, b"test")) log.SDL_LogWarn(log.SDL_LOG_CATEGORY_SYSTEM, b"test") self.assertEqual(self.logdata[1], (None, log.SDL_LOG_CATEGORY_SYSTEM, log.SDL_LOG_PRIORITY_WARN, b"test")) #self.assertRaises(TypeError, log.SDL_LogWarn, None, None) #self.assertRaises(ValueError, log.SDL_LogWarn, 123, None) #self.assertRaises(ValueError, log.SDL_LogWarn, 123, "Test") def test_SDL_LogSetAllPriority(self): self.assertEqual(log.SDL_LogGetPriority (log.SDL_LOG_CATEGORY_APPLICATION), log.SDL_LOG_PRIORITY_VERBOSE) self.assertEqual(log.SDL_LogGetPriority (log.SDL_LOG_CATEGORY_SYSTEM), log.SDL_LOG_PRIORITY_VERBOSE) log.SDL_LogSetAllPriority(log.SDL_LOG_PRIORITY_WARN) self.assertEqual(log.SDL_LogGetPriority (log.SDL_LOG_CATEGORY_APPLICATION), log.SDL_LOG_PRIORITY_WARN) self.assertEqual(log.SDL_LogGetPriority (log.SDL_LOG_CATEGORY_SYSTEM), log.SDL_LOG_PRIORITY_WARN) # self.assertRaises(ValueError, log.SDL_LogSetAllPriority, 123) # self.assertRaises(TypeError, log.SDL_LogSetAllPriority, None) # self.assertRaises(TypeError, log.SDL_LogSetAllPriority, "test") # Reset to the setUp() value, so other tests do not fail log.SDL_LogSetAllPriority(log.SDL_LOG_PRIORITY_VERBOSE) def test_SDL_LogGetSetPriority(self): self.assertEqual(log.SDL_LogGetPriority (log.SDL_LOG_CATEGORY_APPLICATION), log.SDL_LOG_PRIORITY_VERBOSE) self.assertEqual(log.SDL_LogGetPriority(log.SDL_LOG_CATEGORY_SYSTEM), log.SDL_LOG_PRIORITY_VERBOSE) self.assertEqual(log.SDL_LogGetPriority(log.SDL_LOG_CATEGORY_CUSTOM), log.SDL_LOG_PRIORITY_VERBOSE) log.SDL_LogSetPriority(log.SDL_LOG_CATEGORY_CUSTOM, log.SDL_LOG_PRIORITY_INFO) self.assertEqual(log.SDL_LogGetPriority (log.SDL_LOG_CATEGORY_APPLICATION), log.SDL_LOG_PRIORITY_VERBOSE) self.assertEqual(log.SDL_LogGetPriority(log.SDL_LOG_CATEGORY_SYSTEM), log.SDL_LOG_PRIORITY_VERBOSE) self.assertEqual(log.SDL_LogGetPriority(log.SDL_LOG_CATEGORY_CUSTOM), log.SDL_LOG_PRIORITY_INFO) log.SDL_LogSetPriority(log.SDL_LOG_CATEGORY_SYSTEM, log.SDL_LOG_PRIORITY_ERROR) self.assertEqual(log.SDL_LogGetPriority (log.SDL_LOG_CATEGORY_APPLICATION), log.SDL_LOG_PRIORITY_VERBOSE) self.assertEqual(log.SDL_LogGetPriority(log.SDL_LOG_CATEGORY_SYSTEM), log.SDL_LOG_PRIORITY_ERROR) self.assertEqual(log.SDL_LogGetPriority(log.SDL_LOG_CATEGORY_CUSTOM), log.SDL_LOG_PRIORITY_INFO) #self.assertRaises(TypeError, log.SDL_LogSetPriority, None, None) #self.assertRaises(TypeError, log.SDL_LogSetPriority, "Test", None) #self.assertRaises(ValueError, log.SDL_LogSetPriority, 123, None) #self.assertRaises(ValueError, log.SDL_LogSetPriority, 123, "Test") #self.assertRaises(TypeError, log.SDL_LogSetPriority, # log.SDL_LOG_CATEGORY_APPLICATION, None) #self.assertRaises(TypeError, log.SDL_LogSetPriority, # log.SDL_LOG_CATEGORY_APPLICATION, "Test") #self.assertRaises(ValueError, log.SDL_LogSetPriority, # log.SDL_LOG_CATEGORY_APPLICATION, 123) #self.assertRaises(TypeError, log.SDL_LogGetPriority, None) #self.assertRaises(TypeError, log.SDL_LogGetPriority, "Test") #self.assertRaises(ValueError, log.SDL_LogGetPriority, 123) def test_SDL_LogResetPriorities(self): # set in setUp() defpriority = log.SDL_LOG_PRIORITY_VERBOSE categories = ( log.SDL_LOG_CATEGORY_APPLICATION, log.SDL_LOG_CATEGORY_ERROR, log.SDL_LOG_CATEGORY_SYSTEM, log.SDL_LOG_CATEGORY_AUDIO, log.SDL_LOG_CATEGORY_VIDEO, log.SDL_LOG_CATEGORY_RENDER, log.SDL_LOG_CATEGORY_INPUT, log.SDL_LOG_CATEGORY_CUSTOM ) for cat in categories: priority = log.SDL_LogGetPriority(cat) self.assertEqual(priority, defpriority) log.SDL_LogResetPriorities() for cat in categories: priority = log.SDL_LogGetPriority(cat) self.assertNotEqual(priority, defpriority) log.SDL_LogSetAllPriority(log.SDL_LOG_PRIORITY_VERBOSE) def test_SDL_LogGetSetOutputFunction(self): logentries = [] def __log(userdata, category, priority, message): if userdata: userdata = ctypes.cast(userdata, ctypes.c_char_p).value logentries.append((userdata, category, priority, message,)) # setUp should have set our output function already. origfunc = log.SDL_LogOutputFunction() origdata = ctypes.c_void_p(0) log.SDL_LogGetOutputFunction(ctypes.byref(origfunc), ctypes.byref(origdata)) self.assertFalse(origdata) logcount = len(self.logdata) origfunc(None, 0, 0, b"test_log_get_set_output_function") self.assertEqual(len(self.logdata), logcount + 1) self.assertEqual(self.logdata[logcount][3], b"test_log_get_set_output_function") logptr = log.SDL_LogOutputFunction(__log) userdata = ctypes.c_char_p(b"Testobject") log.SDL_LogSetOutputFunction(logptr, userdata) ptr = log.SDL_LogOutputFunction() userdata = ctypes.c_void_p(0) log.SDL_LogGetOutputFunction(ctypes.byref(ptr), ctypes.byref(userdata)) userdata = ctypes.cast(userdata, ctypes.c_char_p) self.assertEqual(userdata.value, b"Testobject") log.SDL_Log(b"output test") self.assertEqual(logentries[0], (b"Testobject", log.SDL_LOG_CATEGORY_APPLICATION, log.SDL_LOG_PRIORITY_INFO, b"output test")) log.SDL_LogSetOutputFunction(origfunc, userdata) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/mouse_test.py0000644000000000000000000000202512356441513014015 0ustar import sys import unittest from .. import mouse @unittest.skip("not implemented") class SDLMouseTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): pass def tearDown(self): pass def test_SDL_GetMouseFocus(self): pass def test_SDL_GetMouseState(self): pass def test_SDL_GetRelativeMouseState(self): pass def test_SDL_WarpMouseInWindow(self): pass def test_SDL_GetSetRelativeMouseMode(self): pass def test_SDL_CreateFreeCursor(self): pass def test_SDL_CreateColorCursor(self): pass def test_SDL_CreateSystemCursor(self): pass def test_SDL_GetSetCursor(self): pass def test_SDL_GetDefaultCursor(self): pass def test_SDL_ShowCursor(self): pass def test_SDL_WarpMouseGlobal(self): pass def test_SDL_CaptureMouse(self): pass def test_SDL_GetGlobalMouseState(self): pass if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/pixels_test.py0000644000000000000000000006663612260256443014213 0ustar import sys import unittest import copy from ctypes import c_int, POINTER, byref, cast, ArgumentError from .. import SDL_Init, SDL_Quit, SDL_QuitSubSystem, SDL_INIT_EVERYTHING from .. import pixels from ..pixels import SDL_Color from ..stdinc import Uint8, Uint16, Uint32 class SDLPixelsTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): SDL_Init(SDL_INIT_EVERYTHING) def tearDown(self): SDL_QuitSubSystem(SDL_INIT_EVERYTHING) SDL_Quit() def test_SDL_FOURCC(self): self.assertRaises(TypeError, pixels.SDL_FOURCC, None, None, None, None) self.assertRaises(TypeError, pixels.SDL_FOURCC, "a", None, None, None) self.assertRaises(TypeError, pixels.SDL_FOURCC, None, "a", None, None) self.assertRaises(TypeError, pixels.SDL_FOURCC, None, None, "a", None) self.assertRaises(TypeError, pixels.SDL_FOURCC, None, None, None, "a") self.assertRaises(TypeError, pixels.SDL_FOURCC, "a", "a", None, None) self.assertRaises(TypeError, pixels.SDL_FOURCC, "a", "a", "a", None) self.assertRaises(TypeError, pixels.SDL_FOURCC, "a", "a", "a", 1) self.assertRaises(TypeError, pixels.SDL_FOURCC, "a", "a", 5, 1) self.assertRaises(TypeError, pixels.SDL_FOURCC, "a", 17, 5, 1) self.assertEqual(pixels.SDL_FOURCC("0", "0", "0", "0"), 0x30303030) self.assertEqual(pixels.SDL_FOURCC("1", "1", "1", "1"), 0x31313131) self.assertEqual(pixels.SDL_FOURCC("1", "2", "3", "4"), 0x34333231) self.assertEqual(pixels.SDL_FOURCC("4", "3", "2", "1"), 0x31323334) def test_SDL_DEFINE_PIXELFORMAT(self): fmt = pixels.SDL_DEFINE_PIXELFORMAT(pixels.SDL_PIXELTYPE_INDEX1, pixels.SDL_BITMAPORDER_4321, 0, 1, 0) self.assertEqual(fmt, pixels.SDL_PIXELFORMAT_INDEX1LSB) fmt = pixels.SDL_DEFINE_PIXELFORMAT(pixels.SDL_PIXELTYPE_PACKED16, pixels.SDL_PACKEDORDER_XRGB, pixels.SDL_PACKEDLAYOUT_4444, 12, 2) self.assertEqual(fmt, pixels.SDL_PIXELFORMAT_RGB444) fmt = pixels.SDL_DEFINE_PIXELFORMAT(pixels.SDL_PIXELTYPE_PACKED16, pixels.SDL_PACKEDORDER_ABGR, pixels.SDL_PACKEDLAYOUT_1555, 16, 2) self.assertEqual(fmt, pixels.SDL_PIXELFORMAT_ABGR1555) def test_SDL_PIXELTYPE(self): pixtype = pixels.SDL_PIXELTYPE self.assertEqual(pixtype(pixels.SDL_PIXELFORMAT_INDEX1LSB), pixels.SDL_PIXELTYPE_INDEX1) self.assertEqual(pixtype(pixels.SDL_PIXELFORMAT_INDEX1MSB), pixels.SDL_PIXELTYPE_INDEX1) self.assertEqual(pixtype(pixels.SDL_PIXELFORMAT_INDEX4LSB), pixels.SDL_PIXELTYPE_INDEX4) self.assertEqual(pixtype(pixels.SDL_PIXELFORMAT_ARGB8888), pixels.SDL_PIXELTYPE_PACKED32) def test_SDL_PIXELORDER(self): pixorder = pixels.SDL_PIXELORDER self.assertEqual(pixorder(pixels.SDL_PIXELFORMAT_INDEX1LSB), pixels.SDL_BITMAPORDER_4321) self.assertEqual(pixorder(pixels.SDL_PIXELFORMAT_INDEX1MSB), pixels.SDL_BITMAPORDER_1234) self.assertEqual(pixorder(pixels.SDL_PIXELFORMAT_INDEX4LSB), pixels.SDL_BITMAPORDER_4321) self.assertEqual(pixorder(pixels.SDL_PIXELFORMAT_ARGB8888), pixels.SDL_PACKEDORDER_ARGB) def test_SDL_PIXELLAYOUT(self): pixlayout = pixels.SDL_PIXELLAYOUT self.assertEqual(pixlayout(pixels.SDL_PIXELFORMAT_INDEX1LSB), pixels.SDL_PACKEDLAYOUT_NONE) self.assertEqual(pixlayout(pixels.SDL_PIXELFORMAT_RGB332), pixels.SDL_PACKEDLAYOUT_332) self.assertEqual(pixlayout(pixels.SDL_PIXELFORMAT_ARGB8888), pixels.SDL_PACKEDLAYOUT_8888) def test_SDL_BITSPERPIXEL(self): bitspp = pixels.SDL_BITSPERPIXEL self.assertEqual(bitspp(pixels.SDL_PIXELFORMAT_INDEX1LSB), 1) self.assertEqual(bitspp(pixels.SDL_PIXELFORMAT_INDEX4LSB), 4) self.assertEqual(bitspp(pixels.SDL_PIXELFORMAT_RGB332), 8) self.assertEqual(bitspp(pixels.SDL_PIXELFORMAT_ARGB8888), 32) # TODO: clarify # self.assertEqual(bitspp(pixels.SDL_PIXELFORMAT_YUY2), 85) # self.assertEqual(bitspp(pixels.SDL_PIXELFORMAT_IYUV), 89) # self.assertEqual(bitspp(pixels.SDL_PIXELFORMAT_UYVY), 89) def test_SDL_BYTESPERPIXEL(self): bytespp = pixels.SDL_BYTESPERPIXEL self.assertEqual(bytespp(pixels.SDL_PIXELFORMAT_INDEX1LSB), 0) self.assertEqual(bytespp(pixels.SDL_PIXELFORMAT_INDEX4LSB), 0) self.assertEqual(bytespp(pixels.SDL_PIXELFORMAT_RGB332), 1) self.assertEqual(bytespp(pixels.SDL_PIXELFORMAT_ARGB8888), 4) self.assertEqual(bytespp(pixels.SDL_PIXELFORMAT_YUY2), 2) self.assertEqual(bytespp(pixels.SDL_PIXELFORMAT_IYUV), 1) self.assertEqual(bytespp(pixels.SDL_PIXELFORMAT_UYVY), 2) def test_SDL_ISPIXELFORMAT_INDEXED(self): isindexed = pixels.SDL_ISPIXELFORMAT_INDEXED self.assertTrue(isindexed(pixels.SDL_PIXELFORMAT_INDEX1LSB)) self.assertTrue(isindexed(pixels.SDL_PIXELFORMAT_INDEX1MSB)) self.assertTrue(isindexed(pixels.SDL_PIXELFORMAT_INDEX4LSB)) self.assertTrue(isindexed(pixels.SDL_PIXELFORMAT_INDEX4MSB)) self.assertTrue(isindexed(pixels.SDL_PIXELFORMAT_INDEX8)) self.assertFalse(isindexed(pixels.SDL_PIXELFORMAT_RGB332)) self.assertFalse(isindexed(pixels.SDL_PIXELFORMAT_ARGB8888)) self.assertFalse(isindexed(pixels.SDL_PIXELFORMAT_YUY2)) def test_SDL_ISPIXELFORMAT_ALPHA(self): isalpha = pixels.SDL_ISPIXELFORMAT_ALPHA self.assertTrue(isalpha(pixels.SDL_PIXELFORMAT_ARGB8888)) self.assertTrue(isalpha(pixels.SDL_PIXELFORMAT_RGBA8888)) self.assertTrue(isalpha(pixels.SDL_PIXELFORMAT_RGBA4444)) self.assertTrue(isalpha(pixels.SDL_PIXELFORMAT_ABGR1555)) self.assertFalse(isalpha(pixels.SDL_PIXELFORMAT_INDEX1LSB)) self.assertFalse(isalpha(pixels.SDL_PIXELFORMAT_INDEX4MSB)) self.assertFalse(isalpha(pixels.SDL_PIXELFORMAT_RGB332)) self.assertFalse(isalpha(pixels.SDL_PIXELFORMAT_YUY2)) self.assertFalse(isalpha(pixels.SDL_PIXELFORMAT_RGBX8888)) def test_SDL_ISPIXELFORMAT_FOURCC(self): isfourcc = pixels.SDL_ISPIXELFORMAT_FOURCC self.assertTrue(isfourcc(pixels.SDL_PIXELFORMAT_YV12)) self.assertTrue(isfourcc(pixels.SDL_PIXELFORMAT_IYUV)) self.assertTrue(isfourcc(pixels.SDL_PIXELFORMAT_YUY2)) self.assertTrue(isfourcc(pixels.SDL_PIXELFORMAT_UYVY)) self.assertTrue(isfourcc(pixels.SDL_PIXELFORMAT_YVYU)) self.assertFalse(isfourcc(pixels.SDL_PIXELFORMAT_ARGB8888)) self.assertFalse(isfourcc(pixels.SDL_PIXELFORMAT_ARGB4444)) self.assertFalse(isfourcc(pixels.SDL_PIXELFORMAT_INDEX8)) def test_SDL_GetPixelFormatName(self): self.assertEqual(pixels.SDL_GetPixelFormatName (pixels.SDL_PIXELFORMAT_INDEX1LSB), b"SDL_PIXELFORMAT_INDEX1LSB") self.assertEqual(pixels.SDL_GetPixelFormatName (pixels.SDL_PIXELFORMAT_UNKNOWN), b"SDL_PIXELFORMAT_UNKNOWN") self.assertEqual(pixels.SDL_GetPixelFormatName (pixels.SDL_PIXELFORMAT_UYVY), b"SDL_PIXELFORMAT_UYVY") self.assertEqual(pixels.SDL_GetPixelFormatName(99999), b"SDL_PIXELFORMAT_UNKNOWN") def test_SDL_MasksToPixelFormatEnum(self): if sys.byteorder == "little": val = pixels.SDL_MasksToPixelFormatEnum(32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF) else: val = pixels.SDL_MasksToPixelFormatEnum(32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000) self.assertEqual(val, pixels.SDL_PIXELFORMAT_RGBA8888) if sys.byteorder == "little": val = pixels.SDL_MasksToPixelFormatEnum(32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0) else: val = pixels.SDL_MasksToPixelFormatEnum(32, 0, 0x000000FF, 0x0000FF00, 0x00FF0000) self.assertEqual(val, pixels.SDL_PIXELFORMAT_RGBX8888) val = pixels.SDL_MasksToPixelFormatEnum(1, 0, 0, 0, 0) self.assertEqual(val, pixels.SDL_PIXELFORMAT_INDEX1MSB) # not LSB val = pixels.SDL_MasksToPixelFormatEnum(17, 3, 6, 64, 255) self.assertEqual(val, pixels.SDL_PIXELFORMAT_UNKNOWN) val = pixels.SDL_MasksToPixelFormatEnum(0, 0, 0, 0, 0) self.assertEqual(val, pixels.SDL_PIXELFORMAT_UNKNOWN) def test_SDL_PixelFormatEnumToMasks(self): bpp = c_int() r, g, b, a = Uint32(), Uint32(), Uint32(), Uint32() pixels.SDL_PixelFormatEnumToMasks(pixels.SDL_PIXELFORMAT_INDEX1LSB, byref(bpp), byref(r), byref(g), byref(b), byref(a)) self.assertEqual((bpp.value, r.value, g.value, b.value, a.value), (1, 0, 0, 0, 0)) pixels.SDL_PixelFormatEnumToMasks(pixels.SDL_PIXELFORMAT_INDEX1MSB, byref(bpp), byref(r), byref(g), byref(b), byref(a)) self.assertEqual((bpp.value, r.value, g.value, b.value, a.value), (1, 0, 0, 0, 0)) pixels.SDL_PixelFormatEnumToMasks(pixels.SDL_PIXELFORMAT_RGBA8888, byref(bpp), byref(r), byref(g), byref(b), byref(a)) if sys.byteorder == "little": self.assertEqual((bpp.value, r.value, g.value, b.value, a.value), (32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF)) else: self.assertEqual((bpp.value, r.value, g.value, b.value, a.value), (32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000)) pixels.SDL_PixelFormatEnumToMasks(pixels.SDL_PIXELFORMAT_RGBX8888, byref(bpp), byref(r), byref(g), byref(b), byref(a)) if sys.byteorder == "little": self.assertEqual((bpp.value, r.value, g.value, b.value, a.value), (32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0)) else: self.assertEqual((bpp.value, r.value, g.value, b.value, a.value), (32, 0, 0x0000FF00, 0x00FF0000, 0xFF000000)) # self.assertRaises(sdl.SDLError, pixels.SDL_PixelFormatEnumToMasks, # 99999) pixels.SDL_PixelFormatEnumToMasks(0, byref(bpp), byref(r), byref(g), byref(b), byref(a)) self.assertEqual((bpp.value, r.value, g.value, b.value, a.value), (0, 0, 0, 0, 0)) pixels.SDL_PixelFormatEnumToMasks(pixels.SDL_PIXELFORMAT_UNKNOWN, byref(bpp), byref(r), byref(g), byref(b), byref(a)) self.assertEqual((bpp.value, r.value, g.value, b.value, a.value), (0, 0, 0, 0, 0)) def test_SDL_AllocFreeFormat(self): pformat = pixels.SDL_AllocFormat(pixels.SDL_PIXELFORMAT_RGBA8888) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) self.assertEqual(pformat.contents.format, pixels.SDL_PIXELFORMAT_RGBA8888) self.assertEqual(pformat.contents.BitsPerPixel, 32) self.assertEqual(pformat.contents.BytesPerPixel, 4) pixels.SDL_FreeFormat(pformat) pformat = pixels.SDL_AllocFormat(pixels.SDL_PIXELFORMAT_INDEX1LSB) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) self.assertEqual(pformat.contents.format, pixels.SDL_PIXELFORMAT_INDEX1LSB) self.assertEqual(pformat.contents.BitsPerPixel, 1) self.assertEqual(pformat.contents.BytesPerPixel, 1) pixels.SDL_FreeFormat(pformat) pformat = pixels.SDL_AllocFormat(pixels.SDL_PIXELFORMAT_INDEX4MSB) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) self.assertEqual(pformat.contents.format, pixels.SDL_PIXELFORMAT_INDEX4MSB) self.assertEqual(pformat.contents.BitsPerPixel, 4) self.assertEqual(pformat.contents.BytesPerPixel, 1) pixels.SDL_FreeFormat(pformat) # self.assertRaises(sdl.SDLError, pixels.SDL_AllocFormat, # pixels.SDL_PIXELFORMAT_UYVY) # self.assertRaises(sdl.SDLError, pixels.SDL_AllocFormat, # pixels.SDL_PIXELFORMAT_YUY2) def test_SDL_AllocFreePalette(self): self.assertRaises((ArgumentError, TypeError), pixels.SDL_AllocPalette, None) self.assertRaises((ArgumentError, TypeError), pixels.SDL_AllocPalette, "Test") # self.assertRaises(ValueError, pixels.SDL_AllocPalette, -5) palette = pixels.SDL_AllocPalette(10) self.assertIsInstance(palette.contents, pixels.SDL_Palette) self.assertEqual(palette.contents.ncolors, 10) colors = palette.contents.colors for x in range(palette.contents.ncolors): self.assertIsInstance(colors[x], SDL_Color) colors[3].r = 70 self.assertEqual(colors[3].r, 70) color = colors[4] self.assertEqual(colors[4].g, 255) self.assertEqual(color.g, 255) color.g = 33 self.assertEqual(color.g, 33) self.assertEqual(colors[4].g, 33) pixels.SDL_FreePalette(palette) def test_SDL_CalculateGammaRamp(self): # TODO: more tests self.assertRaises(TypeError, pixels.SDL_CalculateGammaRamp, None) self.assertRaises(TypeError, pixels.SDL_CalculateGammaRamp, "Test") self.assertRaises(TypeError, pixels.SDL_CalculateGammaRamp, 7) self.assertRaises(TypeError, pixels.SDL_CalculateGammaRamp, -0.00002) vals = (Uint16 * 256)() pixels.SDL_CalculateGammaRamp(0, cast(vals, POINTER(Uint16))) self.assertEqual(len(vals), 256) for x in vals: self.assertEqual(x, 0) vals = (Uint16 * 256)() pixels.SDL_CalculateGammaRamp(1, cast(vals, POINTER(Uint16))) self.assertEqual(len(vals), 256) p = 0 for x in vals: self.assertEqual(x, p) p += 257 vals = (Uint16 * 256)() pixels.SDL_CalculateGammaRamp(0.5, cast(vals, POINTER(Uint16))) self.assertEqual(len(vals), 256) p, step = 0, 1 for x in vals: if p == 33124: # dubios rounding correction - is this really correct? p = 33123 self.assertEqual(x, p) p = x + step step += 2 def test_SDL_GetRGB(self): # TODO: invalid parameters pformat = pixels.SDL_AllocFormat(pixels.SDL_PIXELFORMAT_RGBA8888) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) r, g, b = Uint8(), Uint8(), Uint8() pixels.SDL_GetRGB(0xFFAA8811, pformat, byref(r), byref(g), byref(b)) self.assertEqual((r.value, g.value, b.value), (0xFF, 0xAA, 0x88)) pixels.SDL_GetRGB(0x00000000, pformat, byref(r), byref(g), byref(b)) self.assertEqual((r.value, g.value, b.value), (0x00, 0x00, 0x00)) pixels.SDL_GetRGB(0xFFFFFFFF, pformat, byref(r), byref(g), byref(b)) self.assertEqual((r.value, g.value, b.value), (0xFF, 0xFF, 0xFF)) pixels.SDL_GetRGB(0x11223344, pformat, byref(r), byref(g), byref(b)) self.assertEqual((r.value, g.value, b.value), (0x11, 0x22, 0x33)) pixels.SDL_FreeFormat(pformat) fmts = (pixels.SDL_PIXELFORMAT_INDEX1LSB, pixels.SDL_PIXELFORMAT_INDEX1MSB) for fmt in fmts: pformat = pixels.SDL_AllocFormat(fmt) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) pixels.SDL_GetRGB(0x11223344, pformat, byref(r), byref(g), byref(b)) self.assertEqual((r.value, g.value, b.value), (0xFF, 0xFF, 0xFF)) pixels.SDL_GetRGB(0x00000000, pformat, byref(r), byref(g), byref(b)) # TODO: Seems to be always (0xFF, 0xFF, 0xFF)??? # self.assertEqual(rgb,(0x00, 0x00, 0x00)) pixels.SDL_FreeFormat(pformat) fmts = (pixels.SDL_PIXELFORMAT_INDEX4LSB, pixels.SDL_PIXELFORMAT_INDEX4MSB) for fmt in fmts: pformat = pixels.SDL_AllocFormat(fmt) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) # TODO pixels.SDL_FreeFormat(pformat) def test_SDL_GetRGBA(self): # TODO: invalid parameters pformat = pixels.SDL_AllocFormat(pixels.SDL_PIXELFORMAT_RGBA8888) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) r, g, b, a = Uint8(), Uint8(), Uint8(), Uint8() pixels.SDL_GetRGBA(0xFFAA8811, pformat, byref(r), byref(g), byref(b), byref(a)) self.assertEqual((r.value, g.value, b.value, a.value), (0xFF, 0xAA, 0x88, 0x11)) pixels.SDL_GetRGBA(0x00000000, pformat, byref(r), byref(g), byref(b), byref(a)) self.assertEqual((r.value, g.value, b.value, a.value), (0x00, 0x00, 0x00, 0x00)) pixels.SDL_GetRGBA(0xFFFFFFFF, pformat, byref(r), byref(g), byref(b), byref(a)) self.assertEqual((r.value, g.value, b.value, a.value), (0xFF, 0xFF, 0xFF, 0xFF)) pixels.SDL_GetRGBA(0x11223344, pformat, byref(r), byref(g), byref(b), byref(a)) self.assertEqual((r.value, g.value, b.value, a.value), (0x11, 0x22, 0x33, 0x44)) pixels.SDL_FreeFormat(pformat) fmts = (pixels.SDL_PIXELFORMAT_INDEX1LSB, pixels.SDL_PIXELFORMAT_INDEX1MSB) for fmt in fmts: pformat = pixels.SDL_AllocFormat(fmt) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) pixels.SDL_GetRGBA(0x11223344, pformat, byref(r), byref(g), byref(b), byref(a)) self.assertEqual((r.value, g.value, b.value, a.value), (0xFF, 0xFF, 0xFF, 0xFF)) pixels.SDL_GetRGBA(0x00000000, pformat, byref(r), byref(g), byref(b), byref(a)) # TODO: Seems to be always(0xFF, 0xFF, 0xFF) ??? # self.assertEqual(rgb,(0x00, 0x00, 0x00)) pixels.SDL_FreeFormat(pformat) fmts = (pixels.SDL_PIXELFORMAT_INDEX4LSB, pixels.SDL_PIXELFORMAT_INDEX4MSB) for fmt in fmts: pformat = pixels.SDL_AllocFormat(fmt) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) # TODO pixels.SDL_FreeFormat(pformat) @unittest.skipIf(sys.platform == "cli", "IronPython's ctypes can't handle long values correctly") def test_SDL_MapRGB(self): pformat = pixels.SDL_AllocFormat(pixels.SDL_PIXELFORMAT_RGBA8888) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) val = pixels.SDL_MapRGB(pformat, 0xFF, 0xAA, 0x88) self.assertEqual(val, 0xFFAA88FF) pixels.SDL_FreeFormat(pformat) pformat = pixels.SDL_AllocFormat(pixels.SDL_PIXELFORMAT_UNKNOWN) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) self.assertEqual(pformat.contents.format, pixels.SDL_PIXELFORMAT_UNKNOWN) val = pixels.SDL_MapRGB(pformat, 0xFF, 0xAA, 0x88) self.assertEqual(val, 0x0) pixels.SDL_FreeFormat(pformat) @unittest.skipIf(sys.platform == "cli", "IronPython's ctypes can't handle long values correctly") def test_SDL_MapRGBA(self): pformat = pixels.SDL_AllocFormat(pixels.SDL_PIXELFORMAT_RGBA8888) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) val = pixels.SDL_MapRGBA(pformat, 0xFF, 0xAA, 0x88, 0x11) self.assertEqual(val, 0xFFAA8811) pixels.SDL_FreeFormat(pformat) pformat = pixels.SDL_AllocFormat(pixels.SDL_PIXELFORMAT_UNKNOWN) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) self.assertEqual(pformat.contents.format, pixels.SDL_PIXELFORMAT_UNKNOWN) val = pixels.SDL_MapRGBA(pformat, 0xFF, 0xAA, 0x88, 0x11) self.assertEqual(val, 0x0) pixels.SDL_FreeFormat(pformat) def test_SDL_SetPaletteColors(self): colors = [] for v in range(20): colors.append(SDL_Color(v, v + 10, v + 20)) palette = pixels.SDL_AllocPalette(10) self.assertIsInstance(palette.contents, pixels.SDL_Palette) self.assertEqual(palette.contents.ncolors, 10) colors = palette.contents.colors for index in range(10): rgb = colors[index] self.assertEqual((rgb.r, rgb.g, rgb.b), (255, 255, 255)) pixels.SDL_SetPaletteColors(palette, colors, 0, 10) for index in range(10): rgb = palette.contents.colors[index] self.assertEqual(rgb, colors[index]) pixels.SDL_SetPaletteColors(palette, colors, 5, 1000) for index in range(10): rgb = palette.contents.colors[index] if index < 5: self.assertEqual(rgb, colors[index]) elif index > 5: self.assertEqual(rgb, colors[index - 5]) pixels.SDL_FreePalette(palette) def test_SDL_SetPixelFormatPalette(self): palette = pixels.SDL_AllocPalette(10) self.assertIsInstance(palette.contents, pixels.SDL_Palette) pformat = pixels.SDL_AllocFormat(pixels.SDL_PIXELFORMAT_RGBA8888) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) pixels.SDL_SetPixelFormatPalette(pformat, palette) # TODO: improve tests pixels.SDL_FreeFormat(pformat) pixels.SDL_FreePalette(palette) def test_SDL_PixelFormat(self): # test_alloc_SDL_FreeFormat() contains the real tests pformat = pixels.SDL_PixelFormat() self.assertIsInstance(pformat, pixels.SDL_PixelFormat) def test_SDL_Palette(self): # test_alloc_SDL_FreePalette() contains the real tests palette = pixels.SDL_Palette() self.assertIsInstance(palette, pixels.SDL_Palette) def test_SDL_Color(self): c1 = SDL_Color() self.assertEqual((c1.r, c1.g, c1.b, c1.a), (0xFF, 0xFF, 0xFF, 0xFF)) c1 = SDL_Color() c2 = SDL_Color() c3 = SDL_Color(0, 127, 255, 33) self.assertEqual(c1, c2) self.assertNotEqual(c1, c3) def test_SDL_Color__repr__(self): c1 = SDL_Color() self.assertEqual("SDL_Color(r=255, g=255, b=255, a=255)", repr(c1)) c2 = eval(repr(c1)) self.assertEqual(c2, c1) c3 = eval(repr(c2)) self.assertEqual(c3, c2) def test_SDL_Color__copy__(self): c = SDL_Color() c2 = copy.copy(c) self.assertEqual(c, c2) c = SDL_Color(10, 20, 30) c2 = copy.copy(c) self.assertEqual(c, c2) def test_SDL_Color__eq__(self): self.assertTrue(SDL_Color(255, 0, 0, 0) == SDL_Color(255, 0, 0, 0)) self.assertTrue(SDL_Color(0, 255, 0, 0) == SDL_Color(0, 255, 0, 0)) self.assertTrue(SDL_Color(0, 0, 255, 0) == SDL_Color(0, 0, 255, 0)) self.assertTrue(SDL_Color(0, 0, 0, 255) == SDL_Color(0, 0, 0, 255)) self.assertTrue(SDL_Color(0, 0, 0, 0) == SDL_Color(0, 0, 0, 0)) self.assertFalse(SDL_Color(0, 0, 0, 0) == SDL_Color(255, 0, 0, 0)) self.assertFalse(SDL_Color(0, 0, 0, 0) == SDL_Color(0, 255, 0, 0)) self.assertFalse(SDL_Color(0, 0, 0, 0) == SDL_Color(0, 0, 255, 0)) self.assertFalse(SDL_Color(0, 0, 0, 0) == SDL_Color(0, 0, 0, 255)) def test_SDL_Color__ne__(self): self.assertTrue(SDL_Color(0, 0, 0, 0) != SDL_Color(255, 0, 0, 0)) self.assertTrue(SDL_Color(0, 0, 0, 0) != SDL_Color(0, 255, 0, 0)) self.assertTrue(SDL_Color(0, 0, 0, 0) != SDL_Color(0, 0, 255, 0)) self.assertTrue(SDL_Color(0, 0, 0, 0) != SDL_Color(0, 0, 255, 0)) self.assertTrue(SDL_Color(0, 0, 0, 0) != SDL_Color(0, 0, 0, 255)) self.assertFalse(SDL_Color(255, 0, 0, 0) != SDL_Color(255, 0, 0, 0)) self.assertFalse(SDL_Color(0, 255, 0, 0) != SDL_Color(0, 255, 0, 0)) self.assertFalse(SDL_Color(0, 0, 255, 0) != SDL_Color(0, 0, 255, 0)) self.assertFalse(SDL_Color(0, 0, 0, 255) != SDL_Color(0, 0, 0, 255)) def test_SDL_Color_r(self): c1 = SDL_Color() def setr(color, val): color.r = val for x in range(0, 255): c1.r = x self.assertEqual(c1.r, x) # TODO # self.assertRaises(ValueError, setr, c1, -1) # self.assertRaises(ValueError, setr, c1, 256) self.assertRaises(TypeError, setr, c1, "Test") self.assertRaises(TypeError, setr, c1, None) def test_SDL_Color_g(self): c1 = SDL_Color() def setg(color, val): color.g = val for x in range(0, 255): c1.g = x self.assertEqual(c1.g, x) # TODO # self.assertRaises(ValueError, setg, c1, -1) # self.assertRaises(ValueError, setg, c1, 256) self.assertRaises(TypeError, setg, c1, "Test") self.assertRaises(TypeError, setg, c1, None) def test_SDL_Color_b(self): c1 = SDL_Color() def setb(color, val): color.b = val for x in range(0, 255): c1.b = x self.assertEqual(c1.b, x) # TODO # self.assertRaises(ValueError, setb, c1, -1) # self.assertRaises(ValueError, setb, c1, 256) self.assertRaises(TypeError, setb, c1, "Test") self.assertRaises(TypeError, setb, c1, None) def test_SDL_Color_a(self): c1 = SDL_Color() def seta(color, val): color.a = val for x in range(0, 255): c1.a = x self.assertEqual(c1.a, x) # TODO # self.assertRaises(ValueError, seta, c1, -1) # self.assertRaises(ValueError, seta, c1, 256) self.assertRaises(TypeError, seta, c1, "Test") self.assertRaises(TypeError, seta, c1, None) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/platform_test.py0000644000000000000000000000136112260256443014513 0ustar import sys import unittest from .. import platform class SDLPlatformTest(unittest.TestCase): __tags__ = ["sdl"] def test_SDL_GetPlatform(self): retval = platform.SDL_GetPlatform() if sys.platform in ("win32", "cygwin", "cli"): self.assertEqual(retval, b"Windows") elif sys.platform.startswith("linux"): self.assertEqual(retval, b"Linux") elif sys.platform.startswith("freebsd"): self.assertEqual(retval, b"FreeBSD") elif sys.platform.startswith("darwin"): self.assertEqual(retval, b"Mac OS X") # Do not check others atm, since we are unsure about what Python will # return here. if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/power_test.py0000644000000000000000000000220412260256443014020 0ustar import sys import os import unittest from ctypes import c_int, byref from .. import power from .util.testutils import interactive, doprint class SDLPowerTest(unittest.TestCase): __tags__ = ["sdl"] @interactive("Do the shown numbers match your power supply status?") def test_get_power_info(self): secs, percent = c_int(), c_int() retval = power.SDL_GetPowerInfo(byref(secs), byref(percent)) state = "Unknown" if retval == power.SDL_POWERSTATE_ON_BATTERY: state = "On battery" elif retval == power.SDL_POWERSTATE_NO_BATTERY: state = "No battery" elif retval == power.SDL_POWERSTATE_CHARGING: state = "Battery charging" elif retval == power.SDL_POWERSTATE_CHARGED: state = "Battery charged" output = "Power Status: %s" % state + os.linesep output += "Minutes left (-1 = undetermined): %d" % (secs.value / 60) output += os.linesep output += "Percent left (-1 = undetermined): %d" % percent.value output += os.linesep doprint(output) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/rect_test.py0000644000000000000000000004020112356441640013621 0ustar import sys import copy import unittest from ctypes import byref, c_int from .. import rect to_ctypes = lambda seq, dtype: (dtype * len(seq))(*seq) class SDLRectTest(unittest.TestCase): __tags__ = ["sdl"] def test_SDL_Point(self): pt = rect.SDL_Point() self.assertEqual((pt.x, pt.y), (0, 0)) for x in range(-100, 100): for y in range(-100, 100): pt = rect.SDL_Point(x, y) self.assertEqual((pt.x, pt.y), (x, y)) def test_SDL_Point_x(self): pt = rect.SDL_Point() def setx(point, val): point.x = val for x in range(-1000, 1000): pt.x = x self.assertEqual((pt.x, pt.y), (x, 0)) self.assertRaises(TypeError, setx, pt, 10.4) self.assertRaises(TypeError, setx, pt, "Test") self.assertRaises(TypeError, setx, pt, None) def test_SDL_Point_y(self): pt = rect.SDL_Point() def sety(point, val): point.y = val for x in range(-1000, 1000): pt.y = x self.assertEqual((pt.x, pt.y), (0, x)) self.assertRaises(TypeError, sety, pt, 10.4) self.assertRaises(TypeError, sety, pt, "Test") self.assertRaises(TypeError, sety, pt, None) def test_SDL_Point__repr__(self): pt = rect.SDL_Point() pt2 = eval("rect.%s" % repr(pt)) self.assertEqual(pt, pt2) self.assertEqual((pt.x, pt.y), (pt2.x, pt2.y)) pt = rect.SDL_Point(10, 12) pt2 = eval("rect.%s" % repr(pt)) self.assertEqual(pt, pt2) self.assertEqual((pt.x, pt.y), (pt2.x, pt2.y)) def test_SDL_Point__copy__(self): pt = rect.SDL_Point() pt2 = copy.copy(pt) self.assertEqual(pt, pt2) self.assertEqual((pt.x, pt.y), (pt2.x, pt2.y)) pt2.x = 7 pt2.y = 9 pt3 = copy.copy(pt2) self.assertNotEqual(pt, pt2) self.assertEqual(pt3, pt2) def test_SDL_Point__eq__(self): self.assertTrue(rect.SDL_Point() == rect.SDL_Point()) self.assertTrue(rect.SDL_Point(0, 0) == rect.SDL_Point(0, 0)) self.assertTrue(rect.SDL_Point(10, 0) == rect.SDL_Point(10, 0)) self.assertTrue(rect.SDL_Point(0, 10) == rect.SDL_Point(0, 10)) self.assertTrue(rect.SDL_Point(12, 10) == rect.SDL_Point(12, 10)) self.assertFalse(rect.SDL_Point(0, 0) == rect.SDL_Point(0, 1)) self.assertFalse(rect.SDL_Point(0, 0) == rect.SDL_Point(1, 0)) self.assertFalse(rect.SDL_Point(0, 0) == rect.SDL_Point(1, 1)) self.assertFalse(rect.SDL_Point(10, 10) == rect.SDL_Point(10, 0)) self.assertFalse(rect.SDL_Point(7, 10) == rect.SDL_Point(0, 10)) self.assertFalse(rect.SDL_Point(12, 10) == rect.SDL_Point(12, 11)) def test_SDL_Point__ne__(self): self.assertFalse(rect.SDL_Point() != rect.SDL_Point()) self.assertFalse(rect.SDL_Point(0, 0) != rect.SDL_Point(0, 0)) self.assertFalse(rect.SDL_Point(10, 0) != rect.SDL_Point(10, 0)) self.assertFalse(rect.SDL_Point(0, 10) != rect.SDL_Point(0, 10)) self.assertFalse(rect.SDL_Point(12, 10) != rect.SDL_Point(12, 10)) self.assertTrue(rect.SDL_Point(0, 0) != rect.SDL_Point(0, 1)) self.assertTrue(rect.SDL_Point(0, 0) != rect.SDL_Point(1, 0)) self.assertTrue(rect.SDL_Point(0, 0) != rect.SDL_Point(1, 1)) self.assertTrue(rect.SDL_Point(10, 10) != rect.SDL_Point(10, 0)) self.assertTrue(rect.SDL_Point(7, 10) != rect.SDL_Point(0, 10)) self.assertTrue(rect.SDL_Point(12, 10) != rect.SDL_Point(12, 11)) def test_SDL_Rect(self): rt = rect.SDL_Rect() self.assertEqual((rt.x, rt.y, rt.w, rt.h), (0, 0, 0, 0)) for x in range(-10, 10): for y in range(-10, 10): for w in range(-10, 10): for h in range(-10, 10): rt = rect.SDL_Rect(x, y, w, h) self.assertEqual((rt.x, rt.y, rt.w, rt.h), (x, y, w, h)) def test_SDL_Rect__repr__(self): rt = rect.SDL_Rect(1, 2, 3, 4) rt2 = eval("rect.%s" % repr(rt)) self.assertEqual((rt.x, rt.y, rt.w, rt.h), (rt2.x, rt2.y, rt2.w, rt2.h)) self.assertEqual(rt, rt2) def test_SDL_Rect__copy__(self): rt = rect.SDL_Rect() rt2 = copy.copy(rt) self.assertEqual(rt, rt2) self.assertEqual((rt.x, rt.y, rt.w, rt.h), (rt2.x, rt2.y, rt2.w, rt2.h)) rt2.x = 5 rt2.y = 33 rt2.w = 17 rt2.w = 212 rt3 = copy.copy(rt2) self.assertNotEqual(rt, rt2) self.assertEqual(rt3, rt2) def test_SDL_Rect__eq__(self): sdlr = rect.SDL_Rect self.assertTrue(sdlr() == sdlr()) self.assertTrue(sdlr(0, 0, 0, 0) == sdlr(0, 0, 0, 0)) self.assertTrue(sdlr(1, 2, 3, 4) == sdlr(1, 2, 3, 4)) self.assertTrue(sdlr(-1, -2, -3, -4) == sdlr(-1, -2, -3, -4)) self.assertTrue(sdlr(10, 0, 0, 0) == sdlr(10, 0, 0, 0)) self.assertTrue(sdlr(0, 10, 0, 0) == sdlr(0, 10, 0, 0)) self.assertTrue(sdlr(0, 0, 10, 0) == sdlr(0, 0, 10, 0)) self.assertTrue(sdlr(0, 0, 0, 10) == sdlr(0, 0, 0, 10)) self.assertTrue(sdlr(10, 10, 0, 0) == sdlr(10, 10, 0, 0)) self.assertTrue(sdlr(0, 10, 10, 0) == sdlr(0, 10, 10, 0)) self.assertTrue(sdlr(0, 0, 10, 10) == sdlr(0, 0, 10, 10)) self.assertTrue(sdlr(10, 0, 0, 10) == sdlr(10, 0, 0, 10)) self.assertTrue(sdlr(10, 10, 10, 0) == sdlr(10, 10, 10, 0)) self.assertTrue(sdlr(0, 10, 10, 10) == sdlr(0, 10, 10, 10)) self.assertFalse(sdlr() == sdlr(0, 0, 0, 1)) self.assertFalse(sdlr(10, 0, 0, 0) == sdlr(0, 0, 0, 0)) self.assertFalse(sdlr(10, 10, 0, 0) == sdlr(0, 10, 0, 0)) self.assertFalse(sdlr(10, 0, 10, 0) == sdlr(0, 0, 10, 0)) self.assertFalse(sdlr(10, 0, 0, 10) == sdlr(0, 0, 0, 10)) self.assertFalse(sdlr(1, 2, 3, 4) == sdlr(-1, -2, -3, -4)) def test_SDL_Rect__ne__(self): sdlr = rect.SDL_Rect self.assertTrue(sdlr() != sdlr(0, 0, 0, 1)) self.assertTrue(sdlr(10, 0, 0, 0) != sdlr(0, 0, 0, 0)) self.assertTrue(sdlr(10, 10, 0, 0) != sdlr(0, 10, 0, 0)) self.assertTrue(sdlr(10, 0, 10, 0) != sdlr(0, 0, 10, 0)) self.assertTrue(sdlr(10, 0, 0, 10) != sdlr(0, 0, 0, 10)) self.assertTrue(sdlr(1, 2, 3, 4) != sdlr(-1, -2, -3, -4)) self.assertFalse(sdlr() != sdlr()) self.assertFalse(sdlr(0, 0, 0, 0) != sdlr(0, 0, 0, 0)) self.assertFalse(sdlr(1, 2, 3, 4) != sdlr(1, 2, 3, 4)) self.assertFalse(sdlr(-1, -2, -3, -4) != sdlr(-1, -2, -3, -4)) self.assertFalse(sdlr(10, 0, 0, 0) != sdlr(10, 0, 0, 0)) self.assertFalse(sdlr(0, 10, 0, 0) != sdlr(0, 10, 0, 0)) self.assertFalse(sdlr(0, 0, 10, 0) != sdlr(0, 0, 10, 0)) self.assertFalse(sdlr(0, 0, 0, 10) != sdlr(0, 0, 0, 10)) self.assertFalse(sdlr(10, 10, 0, 0) != sdlr(10, 10, 0, 0)) self.assertFalse(sdlr(0, 10, 10, 0) != sdlr(0, 10, 10, 0)) self.assertFalse(sdlr(0, 0, 10, 10) != sdlr(0, 0, 10, 10)) self.assertFalse(sdlr(10, 0, 0, 10) != sdlr(10, 0, 0, 10)) self.assertFalse(sdlr(10, 10, 10, 0) != sdlr(10, 10, 10, 0)) self.assertFalse(sdlr(0, 10, 10, 10) != sdlr(0, 10, 10, 10)) def test_SDL_Rect_x(self): rt = rect.SDL_Rect() def setx(r, val): r.x = val for x in range(-1000, 1000): rt.x = x self.assertEqual((rt.x, rt.y, rt.w, rt.h), (x, 0, 0, 0)) self.assertRaises(TypeError, setx, rt, 10.4) self.assertRaises(TypeError, setx, rt, "Test") self.assertRaises(TypeError, setx, rt, None) def test_SDL_Rect_y(self): rt = rect.SDL_Rect() def sety(r, val): r.y = val for x in range(-1000, 1000): rt.y = x self.assertEqual((rt.x, rt.y, rt.w, rt.h), (0, x, 0, 0)) self.assertRaises(TypeError, sety, rt, 10.4) self.assertRaises(TypeError, sety, rt, "Test") self.assertRaises(TypeError, sety, rt, None) def test_SDL_Rect_w(self): rt = rect.SDL_Rect() def setw(r, val): r.w = val for x in range(-1000, 1000): rt.w = x self.assertEqual((rt.x, rt.y, rt.w, rt.h), (0, 0, x, 0)) self.assertRaises(TypeError, setw, rt, 10.4) self.assertRaises(TypeError, setw, rt, "Test") self.assertRaises(TypeError, setw, rt, None) def test_SDL_Rect_h(self): rt = rect.SDL_Rect() def seth(r, val): r.h = val for x in range(-1000, 1000): rt.h = x self.assertEqual((rt.x, rt.y, rt.w, rt.h), (0, 0, 0, x)) self.assertRaises(TypeError, seth, rt, 10.4) self.assertRaises(TypeError, seth, rt, "Test") self.assertRaises(TypeError, seth, rt, None) def test_SDL_RectEmpty(self): for w in range(-100, 100): for h in range(-100, 100): r = rect.SDL_Rect(0, 0, w, h) if w > 0 and h > 0: self.assertFalse(rect.SDL_RectEmpty(r)) else: self.assertTrue(rect.SDL_RectEmpty(r)) self.assertRaises(AttributeError, rect.SDL_RectEmpty, "Test") def test_SDL_RectEquals(self): r1 = rect.SDL_Rect(0, 0, 0, 0) r2 = rect.SDL_Rect(0, 0, 0, 0) self.assertTrue(rect.SDL_RectEquals(r1, r2)) self.assertEqual(r1, r2) r2 = rect.SDL_Rect(-1, 2, 0, 0) self.assertFalse(rect.SDL_RectEquals(r1, r2)) self.assertNotEqual(r1, r2) r2 = rect.SDL_Rect(0, 0, 1, 2) self.assertFalse(rect.SDL_RectEquals(r1, r2)) self.assertNotEqual(r1, r2) self.assertRaises(AttributeError, rect.SDL_RectEquals, "Test", r2) self.assertRaises(AttributeError, rect.SDL_RectEquals, r1, None) self.assertRaises(AttributeError, rect.SDL_RectEquals, r1, "Test") def test_SDL_UnionRect(self): r1 = rect.SDL_Rect(0, 0, 10, 10) r2 = rect.SDL_Rect(20, 20, 10, 10) r3 = rect.SDL_Rect() rect.SDL_UnionRect(r1, r2, byref(r3)) self.assertEqual((r3.x, r3.y, r3.w, r3.h), (0, 0, 30, 30)) r1 = rect.SDL_Rect(0, 0, 0, 0) r2 = rect.SDL_Rect(20, 20, 10, 10) rect.SDL_UnionRect(r1, r2, byref(r3)) self.assertEqual((r3.x, r3.y, r3.w, r3.h), (20, 20, 10, 10)) r1 = rect.SDL_Rect(-200, -4, 450, 33) r2 = rect.SDL_Rect(20, 20, 10, 10) rect.SDL_UnionRect(r1, r2, byref(r3)) self.assertEqual((r3.x, r3.y, r3.w, r3.h), (-200, -4, 450, 34)) r1 = rect.SDL_Rect(0, 0, 15, 16) r2 = rect.SDL_Rect(20, 20, 0, 0) rect.SDL_UnionRect(r1, r2, byref(r3)) self.assertEqual((r3.x, r3.y, r3.w, r3.h), (0, 0, 15, 16)) self.assertRaises((AttributeError, TypeError), rect.SDL_UnionRect, None, None) self.assertRaises((AttributeError, TypeError), rect.SDL_UnionRect, "Test", r2) self.assertRaises((AttributeError, TypeError), rect.SDL_UnionRect, r1, None) self.assertRaises((AttributeError, TypeError), rect.SDL_UnionRect, r1, "Test") def test_SDL_IntersectRectAndLine(self): r = rect.SDL_Rect() x1, y1, x2, y2 = c_int(-5), c_int(-5), c_int(5), c_int(5) ret = rect.SDL_IntersectRectAndLine(r, byref(x1), byref(y1), byref(x2), byref(y2)) self.assertFalse(ret) r = rect.SDL_Rect(0, 0, 2, 2) x1, y1, x2, y2 = c_int(-1), c_int(-1), c_int(3), c_int(3) ret = rect.SDL_IntersectRectAndLine(r, byref(x1), byref(y1), byref(x2), byref(y2)) self.assertTrue(ret) self.assertEqual((x1.value, y1.value, x2.value, y2.value), (0, 0, 1, 1)) r = rect.SDL_Rect(-4, -4, 14, 14) x1, y1, x2, y2 = c_int(8), c_int(22), c_int(8), c_int(33) ret = rect.SDL_IntersectRectAndLine(r, byref(x1), byref(y1), byref(x2), byref(y2)) self.assertFalse(ret) # TODO @unittest.skipIf(sys.platform=="cli", "IronPython does not convert arrays to POINTER objects") def test_SDL_EnclosePoints(self): pt1 = rect.SDL_Point(0, 0) pt2 = rect.SDL_Point(5, 7) clip = rect.SDL_Rect(0, 0, 10, 10) res = rect.SDL_Rect() ret = rect.SDL_EnclosePoints(to_ctypes([pt1, pt2], rect.SDL_Point), 2, byref(clip), byref(res)) self.assertTrue(ret) self.assertEqual(res, rect.SDL_Rect(0, 0, 6, 8)) clip = rect.SDL_Rect(-10, -10, 3, 3) ret = rect.SDL_EnclosePoints(to_ctypes([pt1, pt2], rect.SDL_Point), 2, byref(clip), byref(res)) self.assertFalse(ret) self.assertNotEqual(res, rect.SDL_Rect(0, 0, 0, 0)) ret = rect.SDL_EnclosePoints(to_ctypes([pt1, pt2], rect.SDL_Point), 2, None, byref(res)) self.assertTrue(ret) self.assertEqual(res, rect.SDL_Rect(0, 0, 6, 8)) ret = rect.SDL_EnclosePoints(None, 0, None, byref(res)) self.assertFalse(ret) self.assertNotEqual(res, rect.SDL_Rect()) self.assertRaises(TypeError, rect.SDL_EnclosePoints, None, None) if sys.platform != "cli": # IronPython can't handle this correctly self.assertRaises(TypeError, rect.SDL_EnclosePoints, "Test", None) self.assertRaises(TypeError, rect.SDL_EnclosePoints, (1, 2, 3), None) self.assertRaises(TypeError, rect.SDL_EnclosePoints, (None,), None) def test_SDL_HasIntersection(self): r1 = rect.SDL_Rect() r2 = rect.SDL_Rect() self.assertFalse(rect.SDL_HasIntersection(r1, r2)) r1 = rect.SDL_Rect(0, 0, -200, 200) r2 = rect.SDL_Rect(0, 0, -100, 200) self.assertFalse(rect.SDL_HasIntersection(r1, r2)) r1 = rect.SDL_Rect(0, 0, 10, 10) r2 = rect.SDL_Rect(-5, 5, 10, 2) self.assertTrue(rect.SDL_HasIntersection(r1, r2)) r1 = rect.SDL_Rect(0, 0, 10, 10) r2 = rect.SDL_Rect(-5, -5, 10, 2) self.assertFalse(rect.SDL_HasIntersection(r1, r2)) r1 = rect.SDL_Rect(0, 0, 10, 10) r2 = rect.SDL_Rect(-5, -5, 2, 10) self.assertFalse(rect.SDL_HasIntersection(r1, r2)) r1 = rect.SDL_Rect(0, 0, 10, 10) r2 = rect.SDL_Rect(-5, -5, 5, 5) self.assertFalse(rect.SDL_HasIntersection(r1, r2)) r1 = rect.SDL_Rect(0, 0, 10, 10) r2 = rect.SDL_Rect(-5, -5, 6, 6) self.assertTrue(rect.SDL_HasIntersection(r1, r2)) def test_SDL_IntersectRect(self): r1 = rect.SDL_Rect() r2 = rect.SDL_Rect() res = rect.SDL_Rect() ret = rect.SDL_IntersectRect(r1, r2, byref(res)) self.assertFalse(ret) r1 = rect.SDL_Rect(0, 0, -200, 200) r2 = rect.SDL_Rect(0, 0, -100, 200) ret = rect.SDL_IntersectRect(r1, r2, byref(res)) self.assertFalse(ret) r1 = rect.SDL_Rect(0, 0, 10, 10) r2 = rect.SDL_Rect(-5, 5, 10, 2) ret = rect.SDL_IntersectRect(r1, r2, byref(res)) self.assertTrue(ret) self.assertEqual(res, rect.SDL_Rect(0, 5, 5, 2)) r1 = rect.SDL_Rect(0, 0, 10, 10) r2 = rect.SDL_Rect(-5, -5, 10, 2) ret = rect.SDL_IntersectRect(r1, r2, byref(res)) self.assertFalse(ret) r1 = rect.SDL_Rect(0, 0, 10, 10) r2 = rect.SDL_Rect(-5, -5, 2, 10) ret = rect.SDL_IntersectRect(r1, r2, byref(res)) self.assertFalse(ret) r1 = rect.SDL_Rect(0, 0, 10, 10) r2 = rect.SDL_Rect(-5, -5, 5, 5) ret = rect.SDL_IntersectRect(r1, r2, byref(res)) self.assertFalse(ret) r1 = rect.SDL_Rect(0, 0, 10, 10) r2 = rect.SDL_Rect(-5, -5, 6, 6) ret = rect.SDL_IntersectRect(r1, r2, byref(res)) self.assertTrue(ret) self.assertEqual(res, rect.SDL_Rect(0, 0, 1, 1)) @unittest.skip("not implemented") def test_SDL_PointInRect(self): pass if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/render_test.py0000644000000000000000000007465712324671536014175 0ustar import sys import unittest from ctypes import byref, POINTER, c_int from .. import SDL_Init, SDL_Quit, SDL_INIT_EVERYTHING from ..stdinc import Uint8, Uint32, SDL_TRUE, SDL_FALSE from .. import render, video, surface, pixels, blendmode, rect from ..ext.pixelaccess import PixelView _ISPYPY = hasattr(sys, "pypy_version_info") if _ISPYPY: import gc # TODO: mostly positive tests, improve this! class SDLRenderTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): SDL_Init(SDL_INIT_EVERYTHING) def tearDown(self): SDL_Quit() def test_SDL_RendererInfo(self): info = render.SDL_RendererInfo() self.assertIsInstance(info, render.SDL_RendererInfo) def test_SDL_Renderer(self): val = render.SDL_Renderer() self.assertIsInstance(val, render.SDL_Renderer) def test_SDL_Texture(self): val = render.SDL_Texture() self.assertIsInstance(val, render.SDL_Texture) def test_SDL_GetNumRenderDrivers(self): val = render.SDL_GetNumRenderDrivers() self.assertGreaterEqual(val, 1) def test_SDL_GetRenderDriverInfo(self): success = False drivers = render.SDL_GetNumRenderDrivers() for x in range(drivers): info = render.SDL_RendererInfo() ret = render.SDL_GetRenderDriverInfo(x, byref(info)) self.assertEqual(ret, 0) # We must find at least one software renderer if info.name == b"software": success = True self.assertTrue(success, "failed on retrieving the driver information") # self.assertRaises((AttributeError, TypeError), # render.SDL_GetRenderDriverInfo, None) # self.assertRaises((AttributeError, TypeError), # render.SDL_GetRenderDriverInfo, "Test") # self.assertRaises((AttributeError, TypeError), # render.SDL_GetRenderDriverInfo, self) # #self.assertRaises(sdl.SDLError, render.SDL_GetRenderDriverInfo, -1) def test_SDL_CreateWindowAndRenderer(self): window = POINTER(video.SDL_Window)() renderer = POINTER(render.SDL_Renderer)() ret = render.SDL_CreateWindowAndRenderer \ (10, 10, video.SDL_WINDOW_HIDDEN, byref(window), byref(renderer)) self.assertEqual(ret, 0) render.SDL_DestroyRenderer(renderer) video.SDL_DestroyWindow(window) # TODO: the code below works, too - is that really expected from SDL? #window, renderer = render.SDL_CreateWindowAndRenderer \ # (-10, -10, video.SDL_WINDOW_HIDDEN) #self.assertIsInstance(window, video.SDL_Window) #self.assertIsInstance(renderer, render.SDL_Renderer) def test_SDL_CreateDestroyRenderer(self): for i in range(render.SDL_GetNumRenderDrivers()): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_SHOWN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer(window, i, render.SDL_RENDERER_ACCELERATED) self.assertTrue(renderer and renderer.contents, "could not create renderer for driver index %d" % i) self.assertIsInstance(renderer.contents, render.SDL_Renderer) render.SDL_DestroyRenderer(renderer) # TODO: using -1 as index for the call below leads to random # access violations on Win32 renderer = render.SDL_CreateRenderer(window, i, render.SDL_RENDERER_SOFTWARE) self.assertIsInstance(renderer.contents, render.SDL_Renderer) render.SDL_DestroyRenderer(renderer) video.SDL_DestroyWindow(window) def test_SDL_CreateSoftwareRenderer(self): sf = surface.SDL_CreateRGBSurface(0, 100, 100, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF) renderer = render.SDL_CreateSoftwareRenderer(sf) self.assertIsInstance(renderer.contents, render.SDL_Renderer) render.SDL_DestroyRenderer(renderer) surface.SDL_FreeSurface(sf) #self.assertRaises((AttributeError, TypeError), # render.SDL_CreateSoftwareRenderer, None) #self.assertRaises((AttributeError, TypeError), # render.SDL_CreateSoftwareRenderer, 1234) def test_SDL_GetRenderer(self): for i in range(render.SDL_GetNumRenderDrivers()): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_GetRenderer(window) self.assertFalse(renderer) renderer = render.SDL_CreateRenderer(window, i, render.SDL_RENDERER_SOFTWARE) self.assertTrue(renderer and renderer.contents, "could not create renderer for driver index %d" % i) ren = render.SDL_GetRenderer(window) self.assertIsInstance(ren.contents, render.SDL_Renderer) render.SDL_DestroyRenderer(renderer) self.assertFalse(render.SDL_GetRenderer(window)) video.SDL_DestroyWindow(window) self.assertFalse(render.SDL_GetRenderer(window)) #self.assertRaises((AttributeError, TypeError), # render.SDL_GetRenderer, None) #self.assertRaises((AttributeError, TypeError), # render.SDL_GetRenderer, "Test") def test_SDL_GetRendererInfo(self): for i in range(render.SDL_GetNumRenderDrivers()): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer(window, i, render.SDL_RENDERER_SOFTWARE) self.assertTrue(renderer and renderer.contents, "could not create renderer for driver index %d" % i) self.assertIsInstance(renderer.contents, render.SDL_Renderer) info = render.SDL_RendererInfo() ret = render.SDL_GetRendererInfo(renderer, byref(info)) self.assertEqual(ret, 0) render.SDL_DestroyRenderer(renderer) #self.assertRaises(sdl.SDLError, render.SDL_GetRendererInfo, # renderer) video.SDL_DestroyWindow(window) self.assertRaises((AttributeError, TypeError), render.SDL_GetRendererInfo, None) self.assertRaises((AttributeError, TypeError), render.SDL_GetRendererInfo, "Test") def test_SDL_CreateDestroyTexture(self): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer(window, -1, render.SDL_RENDERER_SOFTWARE) self.assertIsInstance(renderer.contents, render.SDL_Renderer) formats = (pixels.SDL_PIXELFORMAT_ARGB8888, pixels.SDL_PIXELFORMAT_RGB555, pixels.SDL_PIXELFORMAT_RGBA4444, pixels.SDL_PIXELFORMAT_RGBA8888, pixels.SDL_PIXELFORMAT_ARGB2101010, pixels.SDL_PIXELFORMAT_YUY2 ) access = (render.SDL_TEXTUREACCESS_STATIC, render.SDL_TEXTUREACCESS_STREAMING, render.SDL_TEXTUREACCESS_TARGET) for fmt in formats: for acc in access: for w in range(1, 300, 5): for h in range(1, 300, 5): tex = render.SDL_CreateTexture(renderer, fmt, acc, w, h) self.assertIsInstance(tex.contents, render.SDL_Texture) render.SDL_DestroyTexture(tex) if _ISPYPY and (w % 50) == 0: gc.collect() #self.assertRaises(sdl.SDLError, render.SDL_CreateTexture, renderer, # pixels.SDL_PIXELFORMAT_RGB555, 1, -10, 10) #self.assertRaises(sdl.SDLError, render.SDL_CreateTexture, renderer, # pixels.SDL_PIXELFORMAT_RGB555, 1, 10, -10) #self.assertRaises(sdl.SDLError, render.SDL_CreateTexture, renderer, # pixels.SDL_PIXELFORMAT_RGB555, 1, -10, -10) #self.assertRaises(ValueError, render.SDL_CreateTexture, renderer, # pixels.SDL_PIXELFORMAT_RGB555, -5, 10, 10) #self.assertRaises(ValueError, render.SDL_CreateTexture, renderer, # - 10, 1, 10, 10) #self.assertRaises((AttributeError, TypeError), # render.SDL_CreateTexture, None, # pixels.SDL_PIXELFORMAT_RGB555, 1, 10, 10) #self.assertRaises((AttributeError, TypeError), # render.SDL_CreateTexture, "Test", # pixels.SDL_PIXELFORMAT_RGB555, 1, 10, 10) #self.assertRaises(ValueError, render.SDL_CreateTexture, renderer, # "Test", 1, 10, 10) #self.assertRaises(ValueError, render.SDL_CreateTexture, renderer, # pixels.SDL_PIXELFORMAT_RGB555, None, 10, 10) #self.assertRaises(ValueError, render.SDL_CreateTexture, renderer, # pixels.SDL_PIXELFORMAT_RGB555, "Test", 10, 10) render.SDL_DestroyRenderer(renderer) #self.assertRaises(sdl.SDLError, render.SDL_CreateTexture, renderer, # pixels.SDL_PIXELFORMAT_RGB555, 1, 10, 10) video.SDL_DestroyWindow(window) def test_SDL_CreateTextureFromSurface(self): sf = surface.SDL_CreateRGBSurface(0, 100, 100, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF) self.assertIsInstance(sf.contents, surface.SDL_Surface) window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer(window, -1, render.SDL_RENDERER_SOFTWARE) self.assertIsInstance(renderer.contents, render.SDL_Renderer) tex = render.SDL_CreateTextureFromSurface(renderer, sf) self.assertIsInstance(tex.contents, render.SDL_Texture) def test_SDL_QueryTexture(self): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer(window, -1, render.SDL_RENDERER_SOFTWARE) self.assertIsInstance(renderer.contents, render.SDL_Renderer) formats = (pixels.SDL_PIXELFORMAT_ARGB8888, pixels.SDL_PIXELFORMAT_RGB555, pixels.SDL_PIXELFORMAT_RGBA4444, pixels.SDL_PIXELFORMAT_ARGB2101010, pixels.SDL_PIXELFORMAT_YUY2 ) access = (render.SDL_TEXTUREACCESS_STATIC, render.SDL_TEXTUREACCESS_STREAMING, render.SDL_TEXTUREACCESS_TARGET) for fmt in formats: for acc in access: for w in range(1, 300, 5): for h in range(1, 300, 5): tex = render.SDL_CreateTexture(renderer, fmt, acc, w, h) self.assertIsInstance(tex.contents, render.SDL_Texture) qf, qa, qw, qh = Uint32(), c_int(), c_int(), c_int() ret = render.SDL_QueryTexture(tex, byref(qf), byref(qa), byref(qw), byref(qh)) self.assertEqual(ret, 0) self.assertEqual(qf.value, fmt) self.assertEqual(qa.value, acc) self.assertEqual(qw.value, w) self.assertEqual(qh.value, h) render.SDL_DestroyTexture(tex) if _ISPYPY and (w % 50) == 0: gc.collect() render.SDL_DestroyRenderer(renderer) video.SDL_DestroyWindow(window) def test_SDL_GetSetTextureColorMod(self): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer(window, -1, render.SDL_RENDERER_SOFTWARE) self.assertIsInstance(renderer.contents, render.SDL_Renderer) tex = render.SDL_CreateTexture(renderer, pixels.SDL_PIXELFORMAT_ARGB8888, render.SDL_TEXTUREACCESS_STREAMING, 10, 10) self.assertIsInstance(tex.contents, render.SDL_Texture) colors = ((16, 22, 185), (32, 64, 128), (64, 32, 128), (64, 32, 255), (255, 32, 64), (255, 32, 128), (0, 0, 0), (255, 255, 255), (128, 128, 128), ) for r, g, b in colors: ret = render.SDL_SetTextureColorMod(tex, r, g, b) self.assertEqual(ret, 0) tr, tg, tb = Uint8(), Uint8(), Uint8() ret = render.SDL_GetTextureColorMod(tex, byref(tr), byref(tg), byref(tb)) self.assertEqual(ret, 0) self.assertEqual((tr.value, tg.value, tb.value), (r, g, b)) render.SDL_DestroyTexture(tex) #self.assertRaises(sdl.SDLError, render.SDL_SetTextureColorMod, tex, # 10, 20, 30) #self.assertRaises(sdl.SDLError, render.SDL_GetTextureColorMod, tex) render.SDL_DestroyRenderer(renderer) video.SDL_DestroyWindow(window) def test_SDL_GetSetTextureAlphaMod(self): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer(window, -1, render.SDL_RENDERER_SOFTWARE) self.assertIsInstance(renderer.contents, render.SDL_Renderer) tex = render.SDL_CreateTexture(renderer, pixels.SDL_PIXELFORMAT_ARGB8888, render.SDL_TEXTUREACCESS_STREAMING, 10, 10) self.assertIsInstance(tex.contents, render.SDL_Texture) for alpha in range(0, 255): ret = render.SDL_SetTextureAlphaMod(tex, alpha) self.assertEqual(ret, 0) talpha = Uint8() ret = render.SDL_GetTextureAlphaMod(tex, byref(talpha)) self.assertEqual(ret, 0) self.assertEqual(talpha.value, alpha) render.SDL_DestroyTexture(tex) #self.assertRaises(sdl.SDLError, render.SDL_SetTextureColorMod, tex, # 10, 20, 30) #self.assertRaises(sdl.SDLError, render.SDL_GetTextureColorMod, tex) render.SDL_DestroyRenderer(renderer) video.SDL_DestroyWindow(window) def test_SDL_GetSetTextureBlendMode(self): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer(window, -1, render.SDL_RENDERER_SOFTWARE) self.assertIsInstance(renderer.contents, render.SDL_Renderer) tex = render.SDL_CreateTexture(renderer, pixels.SDL_PIXELFORMAT_ARGB8888, render.SDL_TEXTUREACCESS_STREAMING, 10, 10) self.assertIsInstance(tex.contents, render.SDL_Texture) modes = (blendmode.SDL_BLENDMODE_NONE, blendmode.SDL_BLENDMODE_ADD, blendmode.SDL_BLENDMODE_BLEND, blendmode.SDL_BLENDMODE_MOD, ) for mode in modes: ret = render.SDL_SetTextureBlendMode(tex, mode) self.assertEqual(ret, 0) tmode = blendmode.SDL_BlendMode() ret = render.SDL_GetTextureBlendMode(tex, byref(tmode)) self.assertEqual(ret, 0) self.assertEqual(tmode.value, mode) render.SDL_DestroyTexture(tex) #self.assertRaises(sdl.SDLError, render.SDL_SetTextureBlendMode, tex, # modes[2]) #self.assertRaises(sdl.SDLError, render.SDL_GetTextureBlendMode, tex) render.SDL_DestroyRenderer(renderer) video.SDL_DestroyWindow(window) @unittest.skip("not implemented") def test_SDL_UpdateTexture(self): pass @unittest.skip("not implemented") def test_SDL_LockUnlockTexture(self): pass def test_SDL_RenderTargetSupported(self): for i in range(render.SDL_GetNumRenderDrivers()): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer\ (window, i, render.SDL_RENDERER_ACCELERATED) self.assertTrue(renderer and renderer.contents, "could not create renderer for driver index %d" % i) self.assertIsInstance(renderer.contents, render.SDL_Renderer) val = render.SDL_RenderTargetSupported(renderer) self.assertIn(val, (SDL_TRUE, SDL_FALSE)) render.SDL_DestroyRenderer(renderer) video.SDL_DestroyWindow(window) def test_SDL_GetSetRenderTarget(self): skipcount = 0 for i in range(render.SDL_GetNumRenderDrivers()): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer \ (window, i, render.SDL_RENDERER_ACCELERATED) self.assertTrue(renderer and renderer.contents, "could not create renderer for driver index %d" % i) self.assertIsInstance(renderer.contents, render.SDL_Renderer) supported = render.SDL_RenderTargetSupported(renderer) if not supported: skipcount += 1 render.SDL_DestroyRenderer(renderer) continue ret = render.SDL_SetRenderTarget(renderer, None) self.assertEqual(ret, 0) self.assertFalse(render.SDL_GetRenderTarget(renderer)) tex = render.SDL_CreateTexture(renderer, pixels.SDL_PIXELFORMAT_ARGB8888, render.SDL_TEXTUREACCESS_TARGET, 10, 10) ret = render.SDL_SetRenderTarget(renderer, tex) self.assertEqual(ret, 0) tgt = render.SDL_GetRenderTarget(renderer) self.assertIsInstance(tgt.contents, render.SDL_Texture) render.SDL_DestroyTexture(tex) # TODO: Check in the SDL codebase, why the code below does # not fail... # tex2 = render.SDL_CreateTexture(renderer, # pixels.SDL_PIXELFORMAT_ARGB8888, # render.SDL_TEXTUREACCESS_STREAMING, # 10, 10) # self.assertRaises(SDLError, render.SDL_SetRenderTarget, renderer, # tex2) # render.SDL_DestroyTexture(tex2) render.SDL_DestroyRenderer(renderer) video.SDL_DestroyWindow(window) if skipcount == render.SDL_GetNumRenderDrivers(): self.skipTest("None of the renderers supports render targets") def test_SDL_RenderGetSetViewport(self): rects = (rect.SDL_Rect(0, 0, 0, 0), rect.SDL_Rect(0, 0, 10, 10), rect.SDL_Rect(3, 3, 5, 5), rect.SDL_Rect(-5, -5, 10, 10), rect.SDL_Rect(10, 10, 10, 10), rect.SDL_Rect(0, 0, -10, -10), rect.SDL_Rect(-10, 0, 10, 10), rect.SDL_Rect(0, -10, 10, 10), rect.SDL_Rect(-10, -10, 10, 10), ) failcount = 0 port = rect.SDL_Rect() for i in range(render.SDL_GetNumRenderDrivers()): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN | video.SDL_WINDOW_BORDERLESS) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer \ (window, i, render.SDL_RENDERER_ACCELERATED) self.assertTrue(renderer and renderer.contents, "could not create renderer for driver index %d" % i) self.assertIsInstance(renderer.contents, render.SDL_Renderer) ret = render.SDL_RenderSetViewport(renderer, None) self.assertEqual(ret, 0) render.SDL_RenderGetViewport(renderer, byref(port)) self.assertEqual(port, rect.SDL_Rect(0, 0, 10, 10)) for r in rects: if r.w == r.h == 0: # http://bugzilla.libsdl.org/show_bug.cgi?id=1622 # OpenGL renderers cause a exception here. continue ret = render.SDL_RenderSetViewport(renderer, r) self.assertEqual(ret, 0) render.SDL_RenderGetViewport(renderer, byref(port)) if port != r: failcount += 1 render.SDL_DestroyRenderer(renderer) video.SDL_DestroyWindow(window) if failcount > 0: unittest.skip("""for some reason, even with correct values, this seems to fail on creating the second renderer of the window, if any""") def test_SDL_GetSetRenderDrawColor(self): for i in range(render.SDL_GetNumRenderDrivers()): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer \ (window, i, render.SDL_RENDERER_ACCELERATED|render.SDL_RENDERER_SOFTWARE) self.assertTrue(renderer and renderer.contents, "could not create renderer for driver index %d" % i) self.assertIsInstance(renderer.contents, render.SDL_Renderer) colors = ((16, 22, 185, 217), (32, 64, 128, 255), (64, 32, 128, 255), (64, 32, 255, 128), (255, 32, 64, 128), (255, 32, 128, 64), (0, 0, 0, 0), (255, 255, 255, 255), (128, 128, 128, 255), ) for r, g, b, a in colors: ret = render.SDL_SetRenderDrawColor(renderer, r, g, b, a) self.assertEqual(ret, 0) dr, dg, db, da = Uint8(), Uint8(), Uint8(), Uint8() ret = render.SDL_GetRenderDrawColor(renderer, byref(dr), byref(dg), byref(db), byref(da)) self.assertEqual(ret, 0) self.assertEqual((dr.value, dg.value, db.value, da.value), (r, g, b, a)) render.SDL_DestroyRenderer(renderer) #self.assertRaises(sdl.SDLError, render.SDL_SetRenderDrawColor, # renderer, 10, 20, 30, 40) #self.assertRaises(sdl.SDLError, render.SDL_GetRenderDrawColor, # renderer) video.SDL_DestroyWindow(window) def test_SDL_GetSetRenderDrawBlendMode(self): for i in range(render.SDL_GetNumRenderDrivers()): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer \ (window, i, render.SDL_RENDERER_ACCELERATED|render.SDL_RENDERER_SOFTWARE) self.assertTrue(renderer and renderer.contents, "could not create renderer for driver index %d" % i) self.assertIsInstance(renderer.contents, render.SDL_Renderer) modes = (blendmode.SDL_BLENDMODE_NONE, blendmode.SDL_BLENDMODE_ADD, blendmode.SDL_BLENDMODE_BLEND, blendmode.SDL_BLENDMODE_MOD, ) for mode in modes: ret = render.SDL_SetRenderDrawBlendMode(renderer, mode) bmode = blendmode.SDL_BlendMode() ret = render.SDL_GetRenderDrawBlendMode(renderer, byref(bmode)) self.assertEqual(ret, 0) self.assertEqual(bmode.value, mode) render.SDL_DestroyRenderer(renderer) #self.assertRaises(sdl.SDLError, render.SDL_SetRenderDrawBlendMode, # renderer, video.SDL_BLENDMODE_ADD) #self.assertRaises(sdl.SDLError, render.SDL_GetRenderDrawBlendMode, # renderer) video.SDL_DestroyWindow(window) def test_SDL_RenderClear(self): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) self.assertIsInstance(window.contents, video.SDL_Window) renderer = render.SDL_CreateRenderer(window, -1, render.SDL_RENDERER_ACCELERATED) self.assertIsInstance(renderer.contents, render.SDL_Renderer) ret = render.SDL_RenderClear(renderer) self.assertEqual(ret, 0) render.SDL_DestroyRenderer(renderer) #self.assertRaises(sdl.SDLError, render.SDL_RenderClear, renderer) # self.assertRaises((AttributeError, TypeError), # render.SDL_RenderClear, None) # self.assertRaises((AttributeError, TypeError), # render.SDL_RenderClear, "Test") # self.assertRaises((AttributeError, TypeError), # render.SDL_RenderClear, 123456) @unittest.skipIf(hasattr(sys, "pypy_version_info"), "PyPy's ctypes can't do byref(value, offset)") @unittest.skipIf(sys.platform=="cli", "IronPython can't cast values array values correctly") def test_SDL_RenderDrawPoint(self): points = ((-4, -3), (-4, 3), (4, -3), (0, 0), (1, 1), (10, 10), (99, 99), (4, 22), (57, 88), (45, 15), (100, 100) ) r, g, b, a = 0xAA, 0xBB, 0xCC, 0xDD w, h = 100, 100 sf = surface.SDL_CreateRGBSurface(0, w, h, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF) color = pixels.SDL_MapRGBA(sf.contents.format, r, g, b, a) renderer = render.SDL_CreateSoftwareRenderer(sf) self.assertIsInstance(renderer.contents, render.SDL_Renderer) ret = render.SDL_SetRenderDrawColor(renderer, r, g, b, a) self.assertEqual(ret, 0) for x, y in points: ret = render.SDL_RenderDrawPoint(renderer, x, y) self.assertEqual(ret, 0) render.SDL_RenderPresent(renderer) view = PixelView(sf.contents) for x, y in points: npx = max(x + 1, w) npy = max(y + 1, h) ppx = max(x - 1, 0) ppy = max(y - 1, 0) if x < 0 or x >= w or y < 0 or y >= h: continue self.assertEqual(hex(view[y][x]), hex(color)) if (npx, npy) not in points: self.assertNotEqual(hex(view[npy][npx]), hex(color)) if (ppx, ppy) not in points: self.assertNotEqual(hex(view[ppy][ppx]), hex(color)) render.SDL_DestroyRenderer(renderer) del view surface.SDL_FreeSurface(sf) @unittest.skip("not implemented") def test_SDL_RenderDrawPoints(self): pass @unittest.skip("not implemented") def test_SDL_RenderDrawLine(self): pass @unittest.skip("not implemented") def test_SDL_RenderDrawLines(self): pass @unittest.skip("not implemented") def test_SDL_RenderDrawRect(self): pass @unittest.skip("not implemented") def test_SDL_RenderDrawRects(self): pass @unittest.skip("not implemented") def test_SDL_RenderFillRect(self): pass @unittest.skip("not implemented") def test_SDL_RenderFillRects(self): pass @unittest.skip("not implemented") def test_SDL_RenderCopy(self): pass @unittest.skip("not implemented") def test_SDL_RenderReadPixels(self): pass @unittest.skip("not implemented") def test_SDL_RenderPresent(self): pass @unittest.skip("not implemented") def test_SDL_RenderGetSetScale(self): pass @unittest.skip("not implemented") def test_SDL_RenderGetSetLogicalSize(self): pass @unittest.skip("not implemented") def test_SDL_RenderGetSetClipRect(self): pass @unittest.skip("not implemented") def test_SDL_GetRendererOutputSize(self): pass @unittest.skip("not implemented") def test_SDL_RenderIsClipEnabled(self): pass if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/rwops_test.py0000644000000000000000000003512612323147121014037 0ustar import os import sys import ctypes import unittest from io import BytesIO from .. import rwops if sys.version_info[0] >= 3: byteify = bytes stringify = lambda x, enc: x.decode(enc) else: byteify = lambda x, enc: x.encode(enc) stringify = lambda x, enc: str(x) testfile = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "rwopstest.txt") # TODO: extended checks for r/w operations outside of buffer ranges, invalid # values, etc.! class SDLRWopsTest(unittest.TestCase): __tags__ = ["sdl"] def test_SDL_RWops(self): rw = rwops.SDL_RWops() self.assertIsInstance(rw, rwops.SDL_RWops) def test_SDL_RWFromFile(self): rw = rwops.SDL_RWFromFile(testfile.encode("utf-8"), b"r") self.assertIsInstance(rw.contents, rwops.SDL_RWops) # Read the first 36 bytes(sic!). It should be: # 'This is a test file for sdl2.rwops!' length = 36 buf = BytesIO() while length >= 2: # Reading in two bytes - we have plain text(1-byte encoding), so # we read in 2 characters at a time. This means that the first # character is always stored in the lo byte. ch = rwops.SDL_ReadLE16(rw) buf.write(byteify(chr(ch & 0x00FF), "utf-8")) buf.write(byteify(chr(ch >> 8), "utf-8")) length -= 2 self.assertEqual(stringify(buf.getvalue(), "utf-8"), "This is a test file for sdl2.rwops!") @unittest.skip("not implemented") def test_SDL_RWFromFP(self): pass @unittest.skip("not implemented") def test_SDL_RWFromMem(self): pass @unittest.skip("not implemented") def test_SDL_RWFromConstMem(self): pass def test_rw_from_object(self): buf = BytesIO() rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) for s in("Test", "Test", "Test", "Banana"): buf.write(byteify(s, "utf-8")) length = rwops.SDL_RWseek(rw, 0, rwops.RW_SEEK_END) rwops.SDL_RWseek(rw, 0, rwops.RW_SEEK_SET) self.assertEqual(len(buf.getvalue()), length) rwops.SDL_RWclose(rw) self.assertTrue(buf.closed) self.assertRaises(ValueError, buf.write, "Test") self.assertRaises(ValueError, buf.getvalue) def test_SDL_RWSeekTell(self): data = byteify("A Teststring of length 25", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) pos = rwops.SDL_RWseek(rw, 0, rwops.RW_SEEK_END) self.assertTrue(pos == buf.tell() == len(data)) pos = rwops.SDL_RWseek(rw, 0, rwops.RW_SEEK_SET) self.assertTrue(pos == buf.tell() == 0) pos = rwops.SDL_RWseek(rw, 15, rwops.RW_SEEK_CUR) self.assertTrue(pos == buf.tell() == 15) pos = rwops.SDL_RWseek(rw, -3, rwops.RW_SEEK_CUR) self.assertTrue(pos == buf.tell() == 12) pos = rwops.SDL_RWseek(rw, 7, rwops.RW_SEEK_CUR) self.assertTrue(pos == buf.tell() == 19) pos = rwops.SDL_RWseek(rw, -11, rwops.RW_SEEK_END) self.assertTrue(pos == buf.tell() == 14) pos = rwops.SDL_RWseek(rw, 8, rwops.RW_SEEK_SET) self.assertTrue(pos == buf.tell() == 8) pos = rwops.SDL_RWseek(rw, -2, rwops.RW_SEEK_SET) self.assertEqual(pos, -1) self.assertTrue(buf.tell() == 8) pos = rwops.SDL_RWseek(rw, 12, rwops.RW_SEEK_END) self.assertTrue(pos == buf.tell() == len(data) + 12) def test_SDL_RWread(self): data = byteify("A Teststring of length 25", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) readbuf = ctypes.create_string_buffer(2) read = rwops.SDL_RWread(rw, readbuf, 1, 2) self.assertEqual(read, 2) self.assertEqual(readbuf.raw, b"A ") readbuf = ctypes.create_string_buffer(10) read = rwops.SDL_RWread(rw, readbuf, 1, 10) self.assertEqual(read, 10) self.assertEqual(readbuf.raw, b"Teststring") def test_SDL_RWwrite(self): data = byteify("A Teststring of length 25", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) writebuf = ctypes.create_string_buffer(b"XQ") written = rwops.SDL_RWwrite(rw, writebuf, 1, 2) self.assertEqual(written, 2) self.assertEqual(buf.getvalue(), b"XQTeststring of length 25") writebuf = ctypes.create_string_buffer(b"banana") rwops.SDL_RWseek(rw, 14, rwops.RW_SEEK_CUR) written = rwops.SDL_RWwrite(rw, writebuf, 1, 6) self.assertEqual(written, 6) self.assertEqual(buf.getvalue(), b"XQTeststring of banana 25") def test_SDL_RWclose(self): data = byteify("A Teststring", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) self.assertEqual(buf.getvalue(), data) rwops.SDL_RWclose(rw) self.assertRaises(ValueError, buf.getvalue) @unittest.skip("not implemented") def test_SDL_AllocFreeRW(self): pass def test_SDL_ReadLE16(self): data = byteify("A Teststring", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) ch = rwops.SDL_ReadLE16(rw) self.assertEqual(chr(ch & 0x00FF), "A") self.assertEqual(chr(ch >> 8), " ") pos = rwops.SDL_RWseek(rw, 8, rwops.RW_SEEK_SET) self.assertEqual(pos, 8) ch = rwops.SDL_ReadLE16(rw) self.assertEqual(chr(ch & 0x00FF), "r") self.assertEqual(chr(ch >> 8), "i") def test_SDL_ReadBE16(self): data = byteify("A Teststring", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) ch = rwops.SDL_ReadBE16(rw) self.assertEqual(chr(ch & 0x00FF), " ") self.assertEqual(chr(ch >> 8), "A") pos = rwops.SDL_RWseek(rw, 8, rwops.RW_SEEK_SET) self.assertEqual(pos, 8) ch = rwops.SDL_ReadBE16(rw) self.assertEqual(chr(ch & 0x00FF), "i") self.assertEqual(chr(ch >> 8), "r") def test_SDL_ReadLE32(self): data = byteify("A Teststring", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) ch = rwops.SDL_ReadLE32(rw) self.assertEqual(chr(ch & 0x000000FF), "A") self.assertEqual(chr((ch & 0x0000FF00) >> 8), " ") self.assertEqual(chr((ch & 0x00FF0000) >> 16), "T") self.assertEqual(chr((ch & 0xFF000000) >> 24), "e") pos = rwops.SDL_RWseek(rw, 8, rwops.RW_SEEK_SET) self.assertEqual(pos, 8) ch = rwops.SDL_ReadLE32(rw) self.assertEqual(chr(ch & 0x000000FF), "r") self.assertEqual(chr((ch & 0x0000FF00) >> 8), "i") self.assertEqual(chr((ch & 0x00FF0000) >> 16), "n") self.assertEqual(chr((ch & 0xFF000000) >> 24), "g") def test_SDL_ReadBE32(self): data = byteify("A Teststring", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) ch = rwops.SDL_ReadBE32(rw) self.assertEqual(chr(ch & 0x000000FF), "e") self.assertEqual(chr((ch & 0x0000FF00) >> 8), "T") self.assertEqual(chr((ch & 0x00FF0000) >> 16), " ") self.assertEqual(chr((ch & 0xFF000000) >> 24), "A") pos = rwops.SDL_RWseek(rw, 8, rwops.RW_SEEK_SET) self.assertEqual(pos, 8) ch = rwops.SDL_ReadBE32(rw) self.assertEqual(chr(ch & 0x000000FF), "g") self.assertEqual(chr((ch & 0x0000FF00) >> 8), "n") self.assertEqual(chr((ch & 0x00FF0000) >> 16), "i") self.assertEqual(chr((ch & 0xFF000000) >> 24), "r") def test_SDL_ReadLE64(self): data = byteify("A Teststring 64b", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) ch = rwops.SDL_ReadLE64(rw) self.assertEqual(chr(ch & 0x00000000000000FF), "A") self.assertEqual(chr((ch & 0x000000000000FF00) >> 8), " ") self.assertEqual(chr((ch & 0x0000000000FF0000) >> 16), "T") self.assertEqual(chr((ch & 0x00000000FF000000) >> 24), "e") self.assertEqual(chr((ch & 0x000000FF00000000) >> 32), "s") self.assertEqual(chr((ch & 0x0000FF0000000000) >> 40), "t") self.assertEqual(chr((ch & 0x00FF000000000000) >> 48), "s") self.assertEqual(chr((ch & 0xFF00000000000000) >> 56), "t") pos = rwops.SDL_RWseek(rw, 8, rwops.RW_SEEK_SET) self.assertEqual(pos, 8) ch = rwops.SDL_ReadLE64(rw) self.assertEqual(chr(ch & 0x00000000000000FF), "r") self.assertEqual(chr((ch & 0x000000000000FF00) >> 8), "i") self.assertEqual(chr((ch & 0x0000000000FF0000) >> 16), "n") self.assertEqual(chr((ch & 0x00000000FF000000) >> 24), "g") self.assertEqual(chr((ch & 0x000000FF00000000) >> 32), " ") self.assertEqual(chr((ch & 0x0000FF0000000000) >> 40), "6") self.assertEqual(chr((ch & 0x00FF000000000000) >> 48), "4") self.assertEqual(chr((ch & 0xFF00000000000000) >> 56), "b") def test_SDL_ReadBE64(self): data = byteify("A Teststring 64b", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) ch = rwops.SDL_ReadBE64(rw) self.assertEqual(chr(ch & 0x00000000000000FF), "t") self.assertEqual(chr((ch & 0x000000000000FF00) >> 8), "s") self.assertEqual(chr((ch & 0x0000000000FF0000) >> 16), "t") self.assertEqual(chr((ch & 0x00000000FF000000) >> 24), "s") self.assertEqual(chr((ch & 0x000000FF00000000) >> 32), "e") self.assertEqual(chr((ch & 0x0000FF0000000000) >> 40), "T") self.assertEqual(chr((ch & 0x00FF000000000000) >> 48), " ") self.assertEqual(chr((ch & 0xFF00000000000000) >> 56), "A") pos = rwops.SDL_RWseek(rw, 8, rwops.RW_SEEK_SET) self.assertEqual(pos, 8) ch = rwops.SDL_ReadBE64(rw) self.assertEqual(chr(ch & 0x00000000000000FF), "b") self.assertEqual(chr((ch & 0x000000000000FF00) >> 8), "4") self.assertEqual(chr((ch & 0x0000000000FF0000) >> 16), "6") self.assertEqual(chr((ch & 0x00000000FF000000) >> 24), " ") self.assertEqual(chr((ch & 0x000000FF00000000) >> 32), "g") self.assertEqual(chr((ch & 0x0000FF0000000000) >> 40), "n") self.assertEqual(chr((ch & 0x00FF000000000000) >> 48), "i") self.assertEqual(chr((ch & 0xFF00000000000000) >> 56), "r") def test_SDL_WriteLE16(self): data = byteify("A Teststring", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) value = ((ord("q") << 8) | (ord("%"))) rwops.SDL_WriteLE16(rw, value) self.assertEqual(stringify(buf.getvalue(), "utf-8"), "%qTeststring") rwops.SDL_RWseek(rw, 6, rwops.RW_SEEK_SET) rwops.SDL_WriteLE16(rw, value) self.assertEqual(stringify(buf.getvalue(), "utf-8"), "%qTest%qring") def test_SDL_WriteBE16(self): data = byteify("A Teststring", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) value = ((ord("q") << 8) | (ord("%"))) rwops.SDL_WriteBE16(rw, value) self.assertEqual(stringify(buf.getvalue(), "utf-8"), "q%Teststring") rwops.SDL_RWseek(rw, 6, rwops.RW_SEEK_SET) rwops.SDL_WriteBE16(rw, value) self.assertEqual(stringify(buf.getvalue(), "utf-8"), "q%Testq%ring") def test_SDL_WriteLE32(self): data = byteify("A Teststring", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) value = ((ord("a") << 24) | (ord("c") << 16) | (ord("f") << 8) | (ord("z")) ) rwops.SDL_WriteLE32(rw, value) self.assertEqual(stringify(buf.getvalue(), "utf-8"), "zfcaststring") rwops.SDL_RWseek(rw, 6, rwops.RW_SEEK_SET) rwops.SDL_WriteLE32(rw, value) self.assertEqual(stringify(buf.getvalue(), "utf-8"), "zfcastzfcang") def test_SDL_WriteBE32(self): data = byteify("A Teststring", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) value = ((ord("a") << 24) | (ord("c") << 16) | (ord("f") << 8) | (ord("z")) ) rwops.SDL_WriteBE32(rw, value) self.assertEqual(stringify(buf.getvalue(), "utf-8"), "acfzststring") rwops.SDL_RWseek(rw, 6, rwops.RW_SEEK_SET) rwops.SDL_WriteBE32(rw, value) self.assertEqual(stringify(buf.getvalue(), "utf-8"), "acfzstacfzng") def test_SDL_WriteLE64(self): data = byteify("A Teststring", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) value = ((ord("q") << 56) | (ord("w") << 48) | (ord("b") << 40) | (ord("k") << 32) | (ord("a") << 24) | (ord("c") << 16) | (ord("f") << 8) | (ord("z")) ) rwops.SDL_WriteLE64(rw, value) self.assertEqual(stringify(buf.getvalue(), "utf-8"), "zfcakbwqring") rwops.SDL_RWseek(rw, 4, rwops.RW_SEEK_SET) rwops.SDL_WriteLE64(rw, value) self.assertEqual(stringify(buf.getvalue(), "utf-8"), "zfcazfcakbwq") def test_SDL_WriteBE64(self): data = byteify("A Teststring", "utf-8") buf = BytesIO(data) rw = rwops.rw_from_object(buf) self.assertIsInstance(rw, rwops.SDL_RWops) value = ((ord("q") << 56) | (ord("w") << 48) | (ord("b") << 40) | (ord("k") << 32) | (ord("a") << 24) | (ord("c") << 16) | (ord("f") << 8) | (ord("z")) ) rwops.SDL_WriteBE64(rw, value) self.assertEqual(stringify(buf.getvalue(), "utf-8"), "qwbkacfzring") rwops.SDL_RWseek(rw, 4, rwops.RW_SEEK_SET) rwops.SDL_WriteBE64(rw, value) self.assertEqual(stringify(buf.getvalue(), "utf-8"), "qwbkqwbkacfz") if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_algorithms_test.py0000644000000000000000000000075512352466501016513 0ustar import sys import unittest from ..ext import algorithms class SDL2ExtAlgorithmsTest(unittest.TestCase): __tags__ = ["sdl2ext"] @unittest.skip("not implemented") def test_cohensutherland(self): pass @unittest.skip("not implemented") def test_liangbarsky(self): pass @unittest.skip("not implemented") def test_clipline(self): pass def test_point_on_line(self): pass if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_array_test.py0000644000000000000000000003270012260256443015453 0ustar import sys import array import ctypes import struct import unittest from ..ext import array as sdlextarray singlebyteseq = [x for x in range(0x100)] doublebyteseq = [x for x in range(0x10000)] quadbyteseq = [0x00000000, 0x000000FF, 0x0000FF00, 0x0000FFFF, 0x00FF0000, 0x00FF00FF, 0x00FFFF00, 0x00FFFFFF, 0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFFFF0000, 0xFFFF00FF, 0xFFFFFF00, 0xFFFFFFFF ] singlebytebuf = array.array("B", singlebyteseq) doublebytebuf = array.array("H", doublebyteseq) quadbytebuf = array.array("I", quadbyteseq) USHORT_SIZE = struct.calcsize("H") UINT_SIZE = struct.calcsize("I") UBYTE_SIZE = struct.calcsize("B") def create_16b(seq, offset): if sys.byteorder == 'little': return (seq[offset] | seq[offset + 1] << 8) else: return (seq[offset] << 8 | seq[offset + 1]) def create_32b(seq, size, offset): if sys.byteorder == 'little': if size == 1: return (seq[offset] | seq[offset + 1] << 8 | seq[offset + 2] << 16 | seq[offset + 3] << 24) elif size == 2: return (seq[offset] | seq[offset + 1] << 16) else: if size == 1: return (seq[offset] << 24 | seq[offset + 1] << 16 | seq[offset + 2] << 8 | seq[offset + 3]) elif size == 2: return (seq[offset] << 16 | seq[offset + 1]) def create_64b(seq, size, offset): if sys.byteorder == 'little': if size == 1: return (seq[offset] | seq[offset + 1] << 8 | seq[offset + 2] << 16 | seq[offset + 3] << 24 | seq[offset + 4] << 32 | seq[offset + 5] << 40 | seq[offset + 6] << 48 | seq[offset + 7] << 56) elif size == 2: return (seq[offset] | seq[offset + 1] << 16 | seq[offset + 2] << 32 | seq[offset + 3] << 48) elif size == 4: return (seq[offset] | seq[offset + 1] << 32) else: if size == 1: return (seq[offset] << 56 | seq[offset + 1] << 48 | seq[offset + 2] << 40 | seq[offset + 3] << 32 | seq[offset + 4] << 24 | seq[offset + 5] << 16 | seq[offset + 6] << 8 | seq[offset + 7]) elif size == 2: return (seq[offset] << 48 | seq[offset + 1] << 32 | seq[offset + 2] << 16 | seq[offset + 3]) elif size == 4: return (seq[offset] << 32 | seq[offset]) def lobyte16(val): return val & 0x00FF def hibyte16(val): return val >> 8 & 0x00FF def lobytes32(val): return val & 0x0000FFFF def hibytes32(val): return val >> 16 & 0x0000FFFF def ltrbyte32(val, pos): if sys.byteorder == 'little': if pos == 0: return val & 0x000000FF elif pos == 1: return (val & 0x0000FF00) >> 8 elif pos == 2: return (val & 0x00FF0000) >> 16 elif pos == 3: return (val & 0xFF000000) >> 24 else: raise IndexError("invalid position") else: if pos == 3: return (val & 0x000000FF) elif pos == 2: return (val & 0x0000FF00) >> 8 elif pos == 1: return (val & 0x00FF0000) >> 16 elif pos == 0: return (val & 0xFF000000) >> 24 else: raise IndexError("invalid position") class SDL2ExtArrayTest(unittest.TestCase): __tags__ = ["sdl2ext"] def test_to_ctypes(self): for seq, dtype in ((singlebyteseq, ctypes.c_ubyte), (singlebytebuf, ctypes.c_ubyte), (doublebyteseq, ctypes.c_ushort), (doublebytebuf, ctypes.c_ushort), (quadbyteseq, ctypes.c_uint), (quadbytebuf, ctypes.c_uint)): bytebuf, size = sdlextarray.to_ctypes(seq, dtype) self.assertEqual(size, len(seq)) for index, x in enumerate(bytebuf): self.assertEqual(x, seq[index]) def test_CTypesView__singlebytes(self): buf1 = sdlextarray.CTypesView(singlebyteseq, docopy=True) buf2 = sdlextarray.CTypesView(singlebytebuf, docopy=False) for singlebytes, shared in ((buf1, False), (buf2, True)): self.assertIsInstance(singlebytes, sdlextarray.CTypesView) # Pypy 1.8.0 does not support ctypes.from_buffer(), hence we # never will receive a shared one if hasattr(sys, "pypy_version_info"): shared = False self.assertEqual(singlebytes.is_shared, shared) self.assertEqual(singlebytes.bytesize, len(singlebyteseq)) for index, val in enumerate(singlebytes.to_bytes()): self.assertEqual(val, singlebyteseq[index]) offset = 0 for val in singlebytes.to_uint16(): seqval = create_16b(singlebyteseq, offset) self.assertEqual(val, seqval) offset += 2 offset = 0 for val in singlebytes.to_uint32(): seqval = create_32b(singlebyteseq, 1, offset) self.assertEqual(val, seqval) offset += 4 offset = 0 for val in singlebytes.to_uint64(): seqval = create_64b(singlebyteseq, 1, offset) self.assertEqual(val, seqval) offset += 8 def test_CTypesView__doublebytes(self): buf1 = sdlextarray.CTypesView(doublebyteseq, USHORT_SIZE, docopy=True) buf2 = sdlextarray.CTypesView(doublebytebuf, USHORT_SIZE, docopy=False) for singlebytes, shared in ((buf1, False), (buf2, True)): self.assertIsInstance(singlebytes, sdlextarray.CTypesView) # Pypy 1.8.0 does not support ctypes.from_buffer(), hence we # never will receive a shared one if hasattr(sys, "pypy_version_info"): shared = False self.assertEqual(singlebytes.is_shared, shared) self.assertEqual(singlebytes.bytesize, len(doublebyteseq) * 2) offset = 0 cnt = 0 for val in singlebytes.to_bytes(): if cnt > 0: self.assertEqual(val, hibyte16(doublebyteseq[offset])) cnt = 0 offset += 1 else: self.assertEqual(val, lobyte16(doublebyteseq[offset])) cnt += 1 offset = 0 for val in singlebytes.to_uint16(): self.assertEqual(val, doublebyteseq[offset]) offset += 1 offset = 0 for val in singlebytes.to_uint32(): seqval = create_32b(doublebyteseq, 2, offset) self.assertEqual(val, seqval) offset += 2 offset = 0 for val in singlebytes.to_uint64(): seqval = create_64b(doublebyteseq, 2, offset) self.assertEqual(val, seqval) offset += 4 def test_CTypesView__quadbytes(self): buf1 = sdlextarray.CTypesView(quadbyteseq, UINT_SIZE, docopy=True) buf2 = sdlextarray.CTypesView(quadbytebuf, UINT_SIZE, docopy=False) for singlebytes, shared in ((buf1, False), (buf2, True)): self.assertIsInstance(singlebytes, sdlextarray.CTypesView) # Pypy 1.8.0 does not support ctypes.from_buffer(), hence we # never will receive a shared one if hasattr(sys, "pypy_version_info"): shared = False self.assertEqual(singlebytes.is_shared, shared) self.assertEqual(singlebytes.bytesize, len(quadbyteseq) * 4) offset = 0 cnt = 0 for val in singlebytes.to_bytes(): self.assertEqual(val, ltrbyte32(quadbyteseq[offset], cnt)) if cnt == 3: offset += 1 cnt = 0 else: cnt += 1 cnt = 0 offset = 0 for val in singlebytes.to_uint16(): if cnt > 0: self.assertEqual(val, hibytes32(quadbyteseq[offset])) cnt = 0 offset += 1 else: self.assertEqual(val, lobytes32(quadbyteseq[offset])) cnt += 1 offset = 0 for val in singlebytes.to_uint32(): self.assertEqual(val, quadbyteseq[offset]) offset += 1 offset = 0 for val in singlebytes.to_uint64(): seqval = create_64b(quadbyteseq, 4, offset) self.assertEqual(val, seqval) offset += 2 def test_CTypesView__repr__(self): seqs = ((singlebyteseq, UBYTE_SIZE, 1, False), (doublebyteseq, USHORT_SIZE, 2, False), (quadbyteseq, UINT_SIZE, 4, False), (singlebytebuf, UBYTE_SIZE, 1, True), (doublebytebuf, USHORT_SIZE, 2, True), (quadbytebuf, UINT_SIZE, 4, True), ) for seq, size, factor, shared in seqs: buf = sdlextarray.CTypesView(seq, size, not shared) otype = type(seq).__name__ if not shared: otype = 'array' # Pypy 1.8.0 does not support ctypes.from_buffer(), hence we # never will receive a shared one if hasattr(sys, "pypy_version_info"): shared = False text = "CTypesView(type=%s, bytesize=%d, shared=%s)" % \ (otype, len(seq) * factor, shared) self.assertEqual(text, repr(buf)) def test_MemoryView(self): self.assertRaises(TypeError, sdlextarray.MemoryView, 5, 1, (1,)) self.assertRaises(TypeError, sdlextarray.MemoryView, None, 1, (1,)) source = "Example buffer" view = sdlextarray.MemoryView(source, 1, (len(source),)) for index, val in enumerate(view): self.assertEqual(val, source[index]) view = sdlextarray.MemoryView(source, 1, (2, 7)) word1 = view[0] # "Example" word2 = view[1] # " buffer" self.assertEqual(len(view), 2) self.assertEqual(len(word1), 7) self.assertEqual(len(word2), 7) for index, val in enumerate(word1): self.assertEqual(val, source[index]) for index, val in enumerate(word2): self.assertEqual(val, source[index + 7]) # TODO: more tests def test_MemoryView_ndim_strides(self): source = "Example buffer" view = sdlextarray.MemoryView(source, 1, (len(source),)) self.assertEqual(view.ndim, 1) self.assertEqual(view.strides, (len(source),)) view = sdlextarray.MemoryView(source, 1, (2, 7)) self.assertEqual(view.ndim, 2) self.assertEqual(view.strides, (2, 7)) view = sdlextarray.MemoryView(source, 1, (7, 2)) self.assertEqual(view.ndim, 2) self.assertEqual(view.strides, (7, 2)) view = sdlextarray.MemoryView(source, 1, (2, 2, 2)) self.assertEqual(view.ndim, 3) self.assertEqual(view.strides, (2, 2, 2)) def test_MemoryView_itemsize(self): source = "Example buffer" view = sdlextarray.MemoryView(source, 1, (len(source),)) self.assertEqual(view.itemsize, 1) view = sdlextarray.MemoryView(source, 7, (1, 7)) self.assertEqual(view.itemsize, 7) def test_MemoryView_size(self): source = "Example buffer" view = sdlextarray.MemoryView(source, 1, (len(source),)) self.assertEqual(view.size, len(source)) view = sdlextarray.MemoryView(source, 7, (1, 7)) self.assertEqual(view.size, len(source)) def test_MemoryView_source(self): source = "Example buffer" view = sdlextarray.MemoryView(source, 1, (len(source),)) self.assertEqual(view.source, source) def test_to_tuple(self): ar = (ctypes.c_int * 20)() for i in range(20): ar[i] = i vtuple = sdlextarray.to_tuple(ar) self.assertIsInstance(vtuple, tuple) for index, value in enumerate(vtuple): self.assertEqual(value, ar[index]) def test_to_list(self): ar = (ctypes.c_int * 20)() for i in range(20): ar[i] = i vlist = sdlextarray.to_list(ar) self.assertIsInstance(vlist, list) for index, value in enumerate(vlist): self.assertEqual(value, ar[index]) def test_create_array(self): barr = bytes(bytearray(singlebyteseq)) for i in (1, 2, 4, 8): parr = sdlextarray.create_array(barr, i) self.assertIsInstance(parr, array.array) if i == 1: self.assertEqual(parr[0], 0x0) elif i == 2: self.assertEqual(parr[0], 0x0100) elif i == 4: self.assertEqual(parr[0], 0x03020100) for i in (0, 3, 5, 6, 7, 9, 10, 12, "test", self): self.assertRaises(TypeError, sdlextarray.create_array, barr, i) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_color_test.py0000644000000000000000000006542012260256443015460 0ustar import sys import unittest import copy from ..ext import color from ..ext.color import Color from ..ext.compat import * combs = [0, 1, 2, 4, 8, 16, 32, 62, 63, 64, 126, 127, 128, 255] all_combos = [(r, g, b, a) for r in combs for g in combs for b in combs for a in combs] def color_combos(): for x in all_combos: yield Color(*x) def hex_combos(): for r, g, b, a in all_combos: yield "0x%.2x%.2x%.2x%.2x" % (r, g, b, a) def hash_combos(): for r, g, b, a in all_combos: yield "#%.2x%.2x%.2x%.2x" % (r, g, b, a) def rgba_combos(): for r, g, b, a in all_combos: yield (r << 24 | g << 16 | b << 8 | a) def argb_combos(): for r, g, b, a in all_combos: yield (a << 24 | r << 16 | g << 8 | b) def _assignr(x, y): x.r = y def _assigng(x, y): x.g = y def _assignb(x, y): x.b = y def _assigna(x, y): x.a = y def _assign_item(x, p, y): x[p] = y class SDL2ExtColorTest(unittest.TestCase): __tags__ = ["sdl2ext"] def test_Color(self): c = Color(10, 20, 30, 40) self.assertEqual(c.r, 10) self.assertEqual(c.g, 20) self.assertEqual(c.b, 30) self.assertEqual(c.a, 40) self.assertRaises(ValueError, Color, 257, 10, 105, 44) self.assertRaises(ValueError, Color, 10, 257, 105, 44) self.assertRaises(ValueError, Color, 10, 105, 257, 44) self.assertRaises(ValueError, Color, 10, 105, 44, 257) def test_Color__copy__(self): copy_copy = copy.copy assertEqual = self.assertEqual assertNotEqual = self.assertNotEqual for c in color_combos(): c2 = copy_copy(c) assertEqual(c, c2) c2 = ~c2 assertNotEqual(c, c2) def test_Color__eq__(self): self.assertTrue(Color(255, 0, 0, 0) == Color(255, 0, 0, 0)) self.assertTrue(Color(0, 255, 0, 0) == Color(0, 255, 0, 0)) self.assertTrue(Color(0, 0, 255, 0) == Color(0, 0, 255, 0)) self.assertTrue(Color(0, 0, 0, 255) == Color(0, 0, 0, 255)) self.assertFalse(Color(0, 0, 0, 0) == Color(255, 0, 0, 0)) self.assertFalse(Color(0, 0, 0, 0) == Color(0, 255, 0, 0)) self.assertFalse(Color(0, 0, 0, 0) == Color(0, 0, 255, 0)) self.assertFalse(Color(0, 0, 0, 0) == Color(0, 0, 0, 255)) self.assertTrue(tuple(Color(255, 0, 0, 0)) == (255, 0, 0, 0)) self.assertTrue(tuple(Color(0, 255, 0, 0)) == (0, 255, 0, 0)) self.assertTrue(tuple(Color(0, 0, 255, 0)) == (0, 0, 255, 0)) self.assertTrue(tuple(Color(0, 0, 0, 255)) == (0, 0, 0, 255)) self.assertFalse(tuple(Color(0, 0, 0, 0)) == (255, 0, 0, 0)) self.assertFalse(tuple(Color(0, 0, 0, 0)) == (0, 255, 0, 0)) self.assertFalse(tuple(Color(0, 0, 0, 0)) == (0, 0, 255, 0)) self.assertFalse(tuple(Color(0, 0, 0, 0)) == (0, 0, 0, 255)) self.assertTrue(int(Color(255, 0, 0, 0)) == 0xff000000) self.assertTrue(int(Color(0, 255, 0, 0)) == 0x00ff0000) self.assertTrue(int(Color(0, 0, 255, 0)) == 0x0000ff00) self.assertTrue(int(Color(0, 0, 0, 255)) == 0x000000ff) self.assertFalse(int(Color(0, 0, 0, 0)) == 0xff000000) self.assertFalse(int(Color(0, 0, 0, 0)) == 0x00ff0000) self.assertFalse(int(Color(0, 0, 0, 0)) == 0x0000ff00) self.assertFalse(int(Color(0, 0, 0, 0)) == 0x000000ff) def test_Color__ne__(self): self.assertTrue(Color(0, 0, 0, 0) != Color(255, 0, 0, 0)) self.assertTrue(Color(0, 0, 0, 0) != Color(0, 255, 0, 0)) self.assertTrue(Color(0, 0, 0, 0) != Color(0, 0, 255, 0)) self.assertTrue(Color(0, 0, 0, 0) != Color(0, 0, 0, 255)) self.assertFalse(Color(255, 0, 0, 0) != Color(255, 0, 0, 0)) self.assertFalse(Color(0, 255, 0, 0) != Color(0, 255, 0, 0)) self.assertFalse(Color(0, 0, 255, 0) != Color(0, 0, 255, 0)) self.assertFalse(Color(0, 0, 0, 255) != Color(0, 0, 0, 255)) self.assertTrue(tuple(Color(0, 0, 0, 0)) != (255, 0, 0, 0)) self.assertTrue(tuple(Color(0, 0, 0, 0)) != (0, 255, 0, 0)) self.assertTrue(tuple(Color(0, 0, 0, 0)) != (0, 0, 255, 0)) self.assertTrue(tuple(Color(0, 0, 0, 0)) != (0, 0, 0, 255)) self.assertFalse(tuple(Color(255, 0, 0, 0)) != (255, 0, 0, 0)) self.assertFalse(tuple(Color(0, 255, 0, 0)) != (0, 255, 0, 0)) self.assertFalse(tuple(Color(0, 0, 255, 0)) != (0, 0, 255, 0)) self.assertFalse(tuple(Color(0, 0, 0, 255)) != (0, 0, 0, 255)) self.assertTrue(int(Color(0, 0, 0, 0)) != 0xff000000) self.assertTrue(int(Color(0, 0, 0, 0)) != 0x00ff0000) self.assertTrue(int(Color(0, 0, 0, 0)) != 0x0000ff00) self.assertTrue(int(Color(0, 0, 0, 0)) != 0x000000ff) self.assertFalse(int(Color(255, 0, 0, 0)) != 0xff000000) self.assertFalse(int(Color(0, 255, 0, 0)) != 0x00ff0000) self.assertFalse(int(Color(0, 0, 255, 0)) != 0x0000ff00) self.assertFalse(int(Color(0, 0, 0, 255)) != 0x000000ff) def test_Color__repr__(self): c = Color(68, 38, 26, 69) c1 = eval(repr(c)) self.assertEqual(c, c1) def test_Color__int__(self): c = Color(0x00, 0xCC, 0x00, 0xCC) self.assertEqual(c.r, 0x00) self.assertEqual(c.g, 0xCC) self.assertEqual(c.b, 0x00) self.assertEqual(c.a, 0xCC) self.assertEqual(int(c), int(0x00CC00CC)) c = Color(0x72, 0x75, 0x92, 0x33) self.assertEqual(c.r, 0x72) self.assertEqual(c.g, 0x75) self.assertEqual(c.b, 0x92) self.assertEqual(c.a, 0x33) self.assertEqual(int(c), int(0x72759233)) def test_Color__long__(self): c = Color(0x00, 0xCC, 0x00, 0xCC) self.assertEqual(c.r, 0x00) self.assertEqual(c.g, 0xCC) self.assertEqual(c.b, 0x00) self.assertEqual(c.a, 0xCC) self.assertEqual(long(c), long(0x00CC00CC)) c = Color(0x72, 0x75, 0x92, 0x33) self.assertEqual(c.r, 0x72) self.assertEqual(c.g, 0x75) self.assertEqual(c.b, 0x92) self.assertEqual(c.a, 0x33) self.assertEqual(long(c), long(0x72759233)) def test_Color__float__(self): c = Color(0x00, 0xCC, 0x00, 0xCC) self.assertEqual(c.r, 0x00) self.assertEqual(c.g, 0xCC) self.assertEqual(c.b, 0x00) self.assertEqual(c.a, 0xCC) self.assertEqual(float(c), float(0x00CC00CC)) c = Color(0x72, 0x75, 0x92, 0x33) self.assertEqual(c.r, 0x72) self.assertEqual(c.g, 0x75) self.assertEqual(c.b, 0x92) self.assertEqual(c.a, 0x33) self.assertEqual(float(c), float(0x72759233)) def test_Color__oct__(self): c = Color(0x00, 0xCC, 0x00, 0xCC) self.assertEqual(c.r, 0x00) self.assertEqual(c.g, 0xCC) self.assertEqual(c.b, 0x00) self.assertEqual(c.a, 0xCC) self.assertEqual(oct(c), oct(0x00CC00CC)) c = Color(0x72, 0x75, 0x92, 0x33) self.assertEqual(c.r, 0x72) self.assertEqual(c.g, 0x75) self.assertEqual(c.b, 0x92) self.assertEqual(c.a, 0x33) self.assertEqual(oct(c), oct(0x72759233)) def test_Color__hex__(self): c = Color(0x00, 0xCC, 0x00, 0xCC) self.assertEqual(c.r, 0x00) self.assertEqual(c.g, 0xCC) self.assertEqual(c.b, 0x00) self.assertEqual(c.a, 0xCC) self.assertEqual(hex(c), hex(0x00CC00CC)) c = Color(0x72, 0x75, 0x92, 0x33) self.assertEqual(c.r, 0x72) self.assertEqual(c.g, 0x75) self.assertEqual(c.b, 0x92) self.assertEqual(c.a, 0x33) self.assertEqual(hex(c), hex(0x72759233)) def test_Color__invert__(self): self.assertEqual(~Color(), Color(0, 0, 0, 0)) self.assertEqual(~Color(0, 0, 0, 0), Color(255, 255, 255, 255)) self.assertEqual(~Color(255, 0, 0, 0), Color(0, 255, 255, 255)) self.assertEqual(~Color(0, 255, 0, 0), Color(255, 0, 255, 255)) self.assertEqual(~Color(0, 0, 255, 0), Color(255, 255, 0, 255)) self.assertEqual(~Color(0, 0, 0, 255), Color(255, 255, 255, 0)) self.assertEqual(~Color(127, 127, 127, 0), Color(128, 128, 128, 255)) self.assertEqual(~Color(1, 2, 3, 4), Color(254, 253, 252, 251)) self.assertEqual(~Color(127, 127, 127, 0), Color(128, 128, 128, 255)) def test_Color__mod__(self): c1 = Color() self.assertEqual(c1.r, 255) self.assertEqual(c1.g, 255) self.assertEqual(c1.b, 255) self.assertEqual(c1.a, 255) c2 = Color(2, 4, 8, 16) self.assertEqual(c2.r, 2) self.assertEqual(c2.g, 4) self.assertEqual(c2.b, 8) self.assertEqual(c2.a, 16) c3 = c1 % c2 self.assertEqual(c3.r, 1) self.assertEqual(c3.g, 3) self.assertEqual(c3.b, 7) self.assertEqual(c3.a, 15) def test_Color__div__(self): c1 = Color(128, 128, 128, 128) self.assertEqual(c1.r, 128) self.assertEqual(c1.g, 128) self.assertEqual(c1.b, 128) self.assertEqual(c1.a, 128) c2 = Color(2, 4, 8, 16) self.assertEqual(c2.r, 2) self.assertEqual(c2.g, 4) self.assertEqual(c2.b, 8) self.assertEqual(c2.a, 16) c3 = c1 / c2 self.assertEqual(c3.r, 64) self.assertEqual(c3.g, 32) self.assertEqual(c3.b, 16) self.assertEqual(c3.a, 8) c3 = c3 / c2 self.assertEqual(c3.r, 32) self.assertEqual(c3.g, 8) self.assertEqual(c3.b, 2) self.assertEqual(c3.a, 0) def test_Color__mul__(self): c1 = Color(1, 1, 1, 1) self.assertEqual(c1.r, 1) self.assertEqual(c1.g, 1) self.assertEqual(c1.b, 1) self.assertEqual(c1.a, 1) c2 = Color(2, 5, 3, 22) self.assertEqual(c2.r, 2) self.assertEqual(c2.g, 5) self.assertEqual(c2.b, 3) self.assertEqual(c2.a, 22) c3 = c1 * c2 self.assertEqual(c3.r, 2) self.assertEqual(c3.g, 5) self.assertEqual(c3.b, 3) self.assertEqual(c3.a, 22) c3 = c3 * c2 self.assertEqual(c3.r, 4) self.assertEqual(c3.g, 25) self.assertEqual(c3.b, 9) self.assertEqual(c3.a, 255) def test_Color__sub__(self): c1 = Color(255, 255, 255, 255) self.assertEqual(c1.r, 255) self.assertEqual(c1.g, 255) self.assertEqual(c1.b, 255) self.assertEqual(c1.a, 255) c2 = Color(20, 33, 82, 193) self.assertEqual(c2.r, 20) self.assertEqual(c2.g, 33) self.assertEqual(c2.b, 82) self.assertEqual(c2.a, 193) c3 = c1 - c2 self.assertEqual(c3.r, 235) self.assertEqual(c3.g, 222) self.assertEqual(c3.b, 173) self.assertEqual(c3.a, 62) c3 = c3 - c2 self.assertEqual(c3.r, 215) self.assertEqual(c3.g, 189) self.assertEqual(c3.b, 91) self.assertEqual(c3.a, 0) def test_Color__add__(self): c1 = Color(0, 0, 0, 0) self.assertEqual(c1.r, 0) self.assertEqual(c1.g, 0) self.assertEqual(c1.b, 0) self.assertEqual(c1.a, 0) c2 = Color(20, 33, 82, 193) self.assertEqual(c2.r, 20) self.assertEqual(c2.g, 33) self.assertEqual(c2.b, 82) self.assertEqual(c2.a, 193) c3 = c1 + c2 self.assertEqual(c3.r, 20) self.assertEqual(c3.g, 33) self.assertEqual(c3.b, 82) self.assertEqual(c3.a, 193) c3 = c3 + c2 self.assertEqual(c3.r, 40) self.assertEqual(c3.g, 66) self.assertEqual(c3.b, 164) self.assertEqual(c3.a, 255) def test_Color__len__(self): c = Color(204, 38, 194, 55) self.assertEqual(len(c), 4) self.assertEqual(len(Color()), 4) self.assertEqual(len(Color(2)), 4) def test_Color__getitem__(self): c = Color(204, 38, 194, 55) self.assertEqual(c[0], 204) self.assertEqual(c[1], 38) self.assertEqual(c[2], 194) self.assertEqual(c[3], 55) def test_Color__setitem(self): c = Color(204, 38, 194, 55) self.assertEqual(c[0], 204) self.assertEqual(c[1], 38) self.assertEqual(c[2], 194) self.assertEqual(c[3], 55) c[0] = 33 self.assertEqual(c[0], 33) c[1] = 48 self.assertEqual(c[1], 48) c[2] = 173 self.assertEqual(c[2], 173) c[3] = 213 self.assertEqual(c[3], 213) # Now try some 'invalid' ones self.assertRaises(ValueError, _assign_item, c, 1, -83) self.assertEqual(c[1], 48) self.assertRaises(TypeError, _assign_item, c, 2, "Hello") self.assertEqual(c[2], 173) def test_Color_r(self): c = Color(100, 100, 100) self.assertEqual(c.r, 100) c = Color(100, 100, 100, 100) self.assertEqual(c.r, 100) c = Color(100, 100, 100) self.assertEqual(c.r, 100) c.r = 200 self.assertEqual(c.r, 200) c.r += 22 self.assertEqual(c.r, 222) def test_Color_g(self): c = Color(100, 100, 100) self.assertEqual(c.g, 100) c = Color(100, 100, 100, 100) self.assertEqual(c.g, 100) c = Color(100, 100, 100) self.assertEqual(c.g, 100) c.g = 200 self.assertEqual(c.g, 200) c.g += 22 self.assertEqual(c.g, 222) def test_Color_b(self): c = Color(100, 100, 100) self.assertEqual(c.b, 100) c = Color(100, 100, 100, 100) self.assertEqual(c.b, 100) c = Color(100, 100, 100) self.assertEqual(c.b, 100) c.b = 200 self.assertEqual(c.b, 200) c.b += 22 self.assertEqual(c.b, 222) def test_Color_a(self): c = Color(100, 100, 100) self.assertEqual(c.a, 255) c = Color(100, 100, 100, 100) self.assertEqual(c.a, 100) c = Color(100, 100, 100) self.assertEqual(c.a, 255) c.a = 200 self.assertEqual(c.a, 200) c.a += 22 self.assertEqual(c.a, 222) def test_Color_rgba(self): c = Color(0) self.assertEqual(c.r, 0) self.assertEqual(c.g, 255) self.assertEqual(c.b, 255) self.assertEqual(c.a, 255) # Test simple assignments c.r = 123 self.assertEqual(c.r, 123) self.assertRaises(ValueError, _assignr, c, 537) self.assertEqual(c.r, 123) self.assertRaises(ValueError, _assignr, c, -3) self.assertEqual(c.r, 123) self.assertEqual(c.g, 255) self.assertEqual(c.b, 255) self.assertEqual(c.a, 255) c.g = 55 self.assertEqual(c.g, 55) self.assertRaises(ValueError, _assigng, c, 348) self.assertEqual(c.g, 55) self.assertRaises(ValueError, _assigng, c, -44) self.assertEqual(c.g, 55) self.assertEqual(c.r, 123) self.assertEqual(c.b, 255) self.assertEqual(c.a, 255) c.b = 77 self.assertEqual(c.b, 77) self.assertRaises(ValueError, _assignb, c, 256) self.assertEqual(c.b, 77) self.assertRaises(ValueError, _assignb, c, -12) self.assertEqual(c.b, 77) self.assertEqual(c.r, 123) self.assertEqual(c.g, 55) self.assertEqual(c.a, 255) c.a = 251 self.assertEqual(c.a, 251) self.assertRaises(ValueError, _assigna, c, 312) self.assertEqual(c.a, 251) self.assertRaises(ValueError, _assigna, c, -10) self.assertEqual(c.a, 251) self.assertEqual(c.r, 123) self.assertEqual(c.g, 55) self.assertEqual(c.b, 77) def test_Color_hsva(self): assertTrue = self.assertTrue assertEqual = self.assertEqual for c in color_combos(): h, s, v, a = c.hsva assertTrue(0 <= h <= 360) assertTrue(0 <= s <= 100) assertTrue(0 <= v <= 100) assertTrue(0 <= a <= 100) for cx in [(0, 0, 0, 0), (255, 255, 255, 255)]: c2 = Color(*cx) assertEqual(tuple(c2), cx) c2.hsva = c.hsva assertTrue(abs(c2.r - c.r) <= 1, "Failed for color '%s' and cx '%s': %s" % (c, cx, c2)) assertTrue(abs(c2.g - c.g) <= 1, "Failed for color '%s' and cx '%s': %s" % (c, cx, c2)) assertTrue(abs(c2.b - c.b) <= 1, "Failed for color '%s' and cx '%s': %s" % (c, cx, c2)) assertTrue(abs(c2.a - c.a) <= 1, "Failed for color '%s' and cx '%s': %s" % (c, cx, c2)) def test_Color_hsla(self): assertTrue = self.assertTrue assertEqual = self.assertEqual for c in color_combos(): h, s, l, a = c.hsla assertTrue(0 <= h <= 360) assertTrue(0 <= s <= 100) assertTrue(0 <= l <= 100) assertTrue(0 <= a <= 100) for cx in [(0, 0, 0, 0), (255, 255, 255, 255)]: c2 = Color(*cx) assertEqual(tuple(c2), cx) c2.hsla = c.hsla assertTrue(abs(c2.r - c.r) <= 1, "Failed for color '%s' and cx '%s': %s" % (c, cx, c2)) assertTrue(abs(c2.g - c.g) <= 1, "Failed for color '%s' and cx '%s': %s" % (c, cx, c2)) assertTrue(abs(c2.b - c.b) <= 1, "Failed for color '%s' and cx '%s': %s" % (c, cx, c2)) assertTrue(abs(c2.a - c.a) <= 1, "Failed for color '%s' and cx '%s': %s" % (c, cx, c2)) def test_Color_i1i2i3(self): assertTrue = self.assertTrue assertEqual = self.assertEqual for c in color_combos(): i1, i2, i3 = c.i1i2i3 assertTrue(0 <= i1 <= 1) assertTrue(-0.5 <= i2 <= 0.5) assertTrue(-0.5 <= i3 <= 0.5) for cx in [(0, 0, 0, 0), (255, 255, 255, 255)]: c2 = Color(*cx) assertEqual(tuple(c2), cx) c2.i1i2i3 = c.i1i2i3 # I1I2I3 ignores the alpha channel, thus we won't check it assertTrue(abs(c2.r - c.r) <= 1, "Failed for color '%s' and cx '%s': %s" % (c, cx, c2)) assertTrue(abs(c2.g - c.g) <= 1, "Failed for color '%s' and cx '%s': %s" % (c, cx, c2)) assertTrue(abs(c2.b - c.b) <= 1, "Failed for color '%s' and cx '%s': %s" % (c, cx, c2)) def test_Color_cmy(self): assertTrue = self.assertTrue assertEqual = self.assertEqual for val in color_combos(): c, m, y = val.cmy assertTrue(0 <= c <= 1) assertTrue(0 <= m <= 1) assertTrue(0 <= y <= 1) for cx in [(0, 0, 0, 0), (255, 255, 255, 255)]: c2 = Color(*cx) assertEqual(tuple(c2), cx) c2.cmy = val.cmy # CMY ignores the alpha channel, thus we won't check it assertTrue(abs(c2.r - val.r) <= 1, "Failed for color '%s' and cx '%s': %s" % (val, cx, c2)) assertTrue(abs(c2.g - val.g) <= 1, "Failed for color '%s' and cx '%s': %s" % (val, cx, c2)) assertTrue(abs(c2.b - val.b) <= 1, "Failed for color '%s' and cx '%s': %s" % (val, cx, c2)) def test_Color_normalize(self): c = Color(204, 38, 194, 55) self.assertEqual(c.r, 204) self.assertEqual(c.g, 38) self.assertEqual(c.b, 194) self.assertEqual(c.a, 55) t = c.normalize() self.assertAlmostEquals(t[0], 0.800000, places=5) self.assertAlmostEquals(t[1], 0.149016, places=5) self.assertAlmostEquals(t[2], 0.760784, places=5) self.assertAlmostEquals(t[3], 0.215686, places=5) c = Color(255, 255, 255, 255) self.assertEqual(c.normalize(), (1.0, 1.0, 1.0, 1.0)) c = Color(0, 0, 0, 0) self.assertEqual(c.normalize(), (0.0, 0.0, 0.0, 0.0)) c = Color(128, 128, 128, 128) t = c.normalize() for v in t: self.assertAlmostEquals(v, 0.5, places=2) c = Color(128, 255, 0, 52) t = c.normalize() self.assertAlmostEquals(t[0], 0.5, places=2) self.assertEqual(t[1], 1.0) self.assertEqual(t[2], 0.0) # 52 / 255 ~= .20 self.assertAlmostEquals(t[3], 0.2, places=2) def test_is_rgb_color(self): assertTrue = self.assertTrue assertFalse = self.assertFalse for v in color_combos(): assertTrue(color.is_rgba_color(v)) for v in rgba_combos(): assertFalse(color.is_rgba_color(v)) for v in argb_combos(): assertFalse(color.is_rgba_color(v)) for v in hex_combos(): assertFalse(color.is_rgba_color(v)) for v in hash_combos(): assertFalse(color.is_rgba_color(v)) def test_is_rgba_color(self): assertTrue = self.assertTrue assertFalse = self.assertFalse for v in color_combos(): assertTrue(color.is_rgba_color(v)) for v in rgba_combos(): assertFalse(color.is_rgba_color(v)) for v in argb_combos(): assertFalse(color.is_rgba_color(v)) for v in hex_combos(): assertFalse(color.is_rgba_color(v)) for v in hash_combos(): assertFalse(color.is_rgba_color(v)) def test_rgba_argb_to_color(self): self.assertEqual(color.RGBA, color.rgba_to_color) self.assertEqual(color.ARGB, color.argb_to_color) assertEqual = self.assertEqual assertNotEqual = self.assertNotEqual cvals = list(color_combos()) for index, val in enumerate(rgba_combos()): c = cvals[index] if c.r == c.g == c.b == c.a: assertEqual(color.RGBA(val), c) assertEqual(color.ARGB(val), c) continue assertEqual(color.RGBA(val), c, "Failed for '%s'" % val) assertNotEqual(color.ARGB(val), c, "Failed for '0x%.8x'" % val) for index, val in enumerate(argb_combos()): c = cvals[index] if c.r == c.g == c.b == c.a: assertEqual(color.RGBA(val), c) assertEqual(color.ARGB(val), c) continue assertEqual(color.ARGB(val), c, "Failed for '%s'" % val) assertNotEqual(color.RGBA(val), c, "Failed for '0x%.8x'" % val) def test_string_to_color(self): assertEqual = self.assertEqual assertRaises = self.assertRaises for method in(color.string_to_color, color.convert_to_color, color.COLOR): assertEqual(method('#00000000').r, 0x00) assertEqual(method('#10000000').r, 0x10) assertEqual(method('#20000000').r, 0x20) assertEqual(method('#30000000').r, 0x30) assertEqual(method('#40000000').r, 0x40) assertEqual(method('#50000000').r, 0x50) assertEqual(method('#60000000').r, 0x60) assertEqual(method('#70000000').r, 0x70) assertEqual(method('#80000000').r, 0x80) assertEqual(method('#90000000').r, 0x90) assertEqual(method('#A0000000').r, 0xA0) assertEqual(method('#B0000000').r, 0xB0) assertEqual(method('#C0000000').r, 0xC0) assertEqual(method('#D0000000').r, 0xD0) assertEqual(method('#E0000000').r, 0xE0) assertEqual(method('#F0000000').r, 0xF0) assertEqual(method('#01000000').r, 0x01) assertEqual(method('#02000000').r, 0x02) assertEqual(method('#03000000').r, 0x03) assertEqual(method('#04000000').r, 0x04) assertEqual(method('#05000000').r, 0x05) assertEqual(method('#06000000').r, 0x06) assertEqual(method('#07000000').r, 0x07) assertEqual(method('#08000000').r, 0x08) assertEqual(method('#09000000').r, 0x09) assertEqual(method('#0A000000').r, 0x0A) assertEqual(method('#0B000000').r, 0x0B) assertEqual(method('#0C000000').r, 0x0C) assertEqual(method('#0D000000').r, 0x0D) assertEqual(method('#0E000000').r, 0x0E) assertEqual(method('#0F000000').r, 0x0F) assertRaises(ValueError, method, "0x12345") assertRaises(ValueError, method, "0x1234567") assertRaises(ValueError, method, "#123456789") assertRaises(ValueError, method, "#12345") assertRaises(ValueError, method, "#1234567") assertRaises(ValueError, method, "#123456789") assertRaises(ValueError, method, "# f000000") assertRaises(ValueError, method, "#f 000000") assertRaises(ValueError, method, "#-f000000") assertRaises(ValueError, method, "-#f000000") assertRaises(ValueError, method, "0x f000000") assertRaises(ValueError, method, "0xf 000000") assertRaises(ValueError, method, "0x-f000000") assertRaises(ValueError, method, "-0xf000000") assertRaises(ValueError, method, "#cc00qq") assertRaises(ValueError, method, "0xcc00qq") assertRaises(ValueError, method, "09abcdef") assertRaises(ValueError, method, "09abcde") assertRaises(ValueError, method, "quarky") cvals = list(color_combos()) for index, val in enumerate(hex_combos()): assertEqual(method(val), cvals[index], "Failed for '%s'" % val) for index, val in enumerate(hash_combos()): assertEqual(method(val), cvals[index], "Failed for '%s'" % val) self.assertRaises(TypeError, color.string_to_color, 0xff000000) self.assertRaises(TypeError, color.string_to_color, Color()) def test_convert_to_color(self): self.assertEqual(color.COLOR, color.convert_to_color) cvals = list(color_combos()) assertEqual = self.assertEqual for index, val in enumerate(hex_combos()): assertEqual(color.COLOR(val), cvals[index], "Failed for '%s'" % val) for index, val in enumerate(hash_combos()): assertEqual(color.COLOR(val), cvals[index], "Failed for '%s'" % val) for index, val in enumerate(hex_combos()): assertEqual(color.COLOR(val), cvals[index], "Failed for '%s'" % val) for index, val in enumerate(argb_combos()): assertEqual(color.COLOR(val), cvals[index], "Failed for '0x%.8x'" % val) for index, val in enumerate(color_combos()): assertEqual(color.COLOR(val), cvals[index], "Failed for '%s'" % val) self.assertRaises(ValueError, color.convert_to_color, self) self.assertRaises(ValueError, color.convert_to_color, "Test") if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_draw_test.py0000644000000000000000000000570712260256443015301 0ustar import sys import unittest from ..ext.color import Color, COLOR from .. import ext as sdl2ext class SDL2ExtDrawTest(unittest.TestCase): __tags__ = ["sdl", "sdl2ext"] def setUp(self): sdl2ext.init() def tearDown(self): sdl2ext.quit() @unittest.skipIf(hasattr(sys, "pypy_version_info"), "PyPy's ctypes can't do byref(value, offset)") @unittest.skipIf(sys.platform=="cli", "IronPython can't cast correctly") def test_fill(self): # TODO: add exceptions and more bounding tests. rects = ((0, 0, 3, 2), (2, 3, 4, 2), (5, -1, 2, 2), (1, 7, 4, 8) ) factory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE) sprite = factory.create_sprite(size=(10, 10), bpp=32) view = sdl2ext.PixelView(sprite) for rect in rects: sdl2ext.fill(sprite, 0) colorval = sdl2ext.prepare_color(0xAABBCCDD, sprite) sdl2ext.fill(sprite, 0xAABBCCDD, rect) for y, row in enumerate(view): for x, col in enumerate(row): if y >= rect[1] and y < (rect[1] + rect[3]): if x >= rect[0] and x < (rect[0] + rect[2]): self.assertEqual(col, colorval, "color mismatch at (x, y)") else: self.assertEqual(col, 0, "color mismatch at (x, y)") else: self.assertEqual(col, 0, "color mismatch at (x, y)") @unittest.skipIf(sys.platform=="cli", "IronPython does not convert int values correctly") def test_prepare_color(self): rcolors = (Color(0, 0, 0, 0), Color(255, 255, 255, 255), Color(8, 55, 110, 220), ) icolors = (0x00000000, 0xFFFFFFFF, 0xAABBCCDD, ) scolors = ("#000", "#FFF", "#AABBCCDD", ) factory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE) sprite = factory.create_sprite(size=(10, 10), bpp=32, masks=(0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF)) for color in rcolors: c = sdl2ext.prepare_color(color, sprite) self.assertEqual(c, int(color)) for color in icolors: c = sdl2ext.prepare_color(color, sprite) cc = COLOR(color) self.assertEqual(c, int(cc)) for color in scolors: c = sdl2ext.prepare_color(color, sprite) cc = COLOR(color) self.assertEqual(c, int(cc)) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_ebs_test.py0000644000000000000000000002211512260256443015105 0ustar import sys import unittest from ..ext.ebs import Entity, System, Applicator, World class Position(object): def __init__(self, x=0, y=0): self.x = x self.y = y def __eq__(self, other): return self.x == other.x and self.y == other.y class Movement(object): def __init__(self, vx=0, vy=0): self.vx = vx self.vy = vy class PositionEntity(Entity): def __init__(self, world, x=0, y=0): self.position = Position(x, y) class MovingEntity(Entity): def __init__(self, world, x=0, y=0, vx=0, vy=0): self.position = Position(x, y) self.movement = Movement(vx, vy) class PosEntity(Entity): def __init__(self, world, x=0, y=0): self.pos = Position(x, y) class PositionSystem(System): def __init__(self): super(PositionSystem, self).__init__() self.componenttypes = (Position,) def process(self, world, components): for c in components: c.x += 1 c.y += 1 class MovementApplicator(Applicator): def __init__(self): super(MovementApplicator, self).__init__() self.componenttypes = (Position, Movement) def process(self, world, componentsets): for p, m in componentsets: p.x += m.vx p.y += m.vy class SDL2ExtEBSTest(unittest.TestCase): __tags__ = ["ebs", "sdl2ext"] def test_Entity(self): world = World() world.add_system(PositionSystem()) e = Entity(world) e2 = Entity(world) self.assertIsInstance(e, Entity) self.assertIsInstance(e2, Entity) self.assertNotEqual(e, e2) p = PositionEntity(world) self.assertIsInstance(p, PositionEntity) self.assertIsInstance(p, Entity) def test_Entity_id(self): world = World() ent1 = Entity(world) ent2 = Entity(world) self.assertNotEqual(ent1.id, ent2.id) def test_Entity_world(self): world = World() world2 = World() ent1 = Entity(world) ent2 = Entity(world2) self.assertEqual(ent1.world, world) self.assertNotEqual(ent1.world, world2) self.assertEqual(ent2.world, world2) self.assertNotEqual(ent2.world, world) self.assertNotEqual(ent1.world, ent2.world) def test_Entity_delete(self): w = World() e1 = Entity(w) e2 = Entity(w) self.assertEqual(len(w.entities), 2) e1.delete() self.assertEqual(len(w.entities), 1) e2.delete() self.assertEqual(len(w.entities), 0) # The next two should have no effect e1.delete() e2.delete() def test_Entity__inheritance(self): world = World() pos1 = PositionEntity(world) pos2 = PositionEntity(world, 10, 10) for p in (pos1, pos2): self.assertIsInstance(p, PositionEntity) self.assertIsInstance(p, Entity) self.assertIsInstance(p.position, Position) def test_Entity__access(self): world = World() pos1 = PositionEntity(world) pos2 = PosEntity(world) pos1.position.x = 10 # components are _always_ identified by a lower-case class name. def sx(p, v): p.pos.x = v self.assertRaises(AttributeError, sx, pos2, 10) def test_World(self): w = World() self.assertIsInstance(w, World) def test_World_add_remove_system(self): world = World() self.assertIsInstance(world, World) class SimpleSystem(object): def __init__(self): self.componenttypes = (Position,) def process(self, world, components): pass for method in (world.add_system, world.remove_system): for val in (None, "Test", Position, Entity(world)): self.assertRaises(ValueError, method, val) psystem = SimpleSystem() world.add_system(psystem) self.assertTrue(len(world.systems) != 0) self.assertTrue(psystem in world.systems) world.remove_system(psystem) self.assertTrue(len(world.systems) == 0) self.assertTrue(psystem not in world.systems) psystem = PositionSystem() world.add_system(psystem) self.assertTrue(len(world.systems) != 0) self.assertTrue(psystem in world.systems) entity = PositionEntity(world) self.assertIsInstance(entity.position, Position) world.remove_system(psystem) self.assertTrue(len(world.systems) == 0) self.assertTrue(psystem not in world.systems) # The data must stay intact in the world, even if the processing # system has been removed. self.assertIsInstance(entity.position, Position) def test_World_entities(self): w = World() self.assertEqual(len(w.entities), 0) for x in range(100): Entity(w) self.assertEqual(len(w.entities), 100) def test_World_delete(self): w = World() e1 = Entity(w) e2 = Entity(w) self.assertEqual(len(w.entities), 2) w.delete(e1) self.assertEqual(len(w.entities), 1) w.delete(e2) self.assertEqual(len(w.entities), 0) # The next two should have no effect w.delete(e1) w.delete(e2) def test_World_delete_entities(self): w = World() e1 = Entity(w) e2 = Entity(w) self.assertEqual(len(w.entities), 2) w.delete_entities((e1, e2)) self.assertEqual(len(w.entities), 0) # The next should have no effect w.delete_entities((e1, e2)) def test_World_get_entities(self): w = World() e1 = PositionEntity(w, 1, 1) e2 = PositionEntity(w, 1, 2) self.assertEqual(len(w.get_entities(e1.position)), 1) e2.position.y = 1 self.assertEqual(len(w.get_entities(e1.position)), 2) def test_System(self): world = World() self.assertRaises(ValueError, world.add_system, None) self.assertRaises(ValueError, world.add_system, 1234) self.assertRaises(ValueError, world.add_system, "Test") class ErrornousSystem(System): def __init__(self): super(ErrornousSystem, self).__init__() esystem = ErrornousSystem() # No component types defined. self.assertRaises(ValueError, world.add_system, esystem) self.assertEqual(len(world.systems), 0) psystem = PositionSystem() world.add_system(psystem) self.assertTrue(psystem in world.systems) def test_System_process(self): world = World() class ErrornousSystem(System): def __init__(self): super(ErrornousSystem, self).__init__() self.componenttypes = (Position,) esystem = ErrornousSystem() world.add_system(esystem) for x in range(10): PositionEntity(world) self.assertTrue(esystem in world.systems) self.assertRaises(NotImplementedError, world.process) world2 = World() psystem = PositionSystem() world2.add_system(psystem) for x in range(10): PositionEntity(world2) self.assertTrue(psystem in world2.systems) world2.process() for c in world2.components[Position].values(): self.assertEqual(c.x, 1) self.assertEqual(c.y, 1) world2.process() for c in world2.components[Position].values(): self.assertEqual(c.x, 2) self.assertEqual(c.y, 2) def test_Applicator(self): world = World() class ErrornousApplicator(Applicator): def __init__(self): super(ErrornousApplicator, self).__init__() eapplicator = ErrornousApplicator() # No component types defined. self.assertRaises(ValueError, world.add_system, eapplicator) self.assertEqual(len(world.systems), 0) mapplicator = MovementApplicator() world.add_system(mapplicator) self.assertTrue(mapplicator in world.systems) def test_Applicator_process(self): world = World() class ErrornousApplicator(Applicator): def __init__(self): super(ErrornousApplicator, self).__init__() self.componenttypes = (Position, Movement) eapplicator = ErrornousApplicator() world.add_system(eapplicator) for x in range(10): MovingEntity(world) self.assertTrue(eapplicator in world.systems) self.assertRaises(NotImplementedError, world.process) world2 = World() mapplicator = MovementApplicator() world2.add_system(mapplicator) for x in range(10): MovingEntity(world2, vx=1, vy=1) self.assertTrue(mapplicator in world2.systems) world2.process() for c in world2.components[Position].values(): self.assertEqual(c.x, 1) self.assertEqual(c.y, 1) world2.process() for c in world2.components[Position].values(): self.assertEqual(c.x, 2) self.assertEqual(c.y, 2) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_events_test.py0000644000000000000000000001436712260256443015652 0ustar import sys import unittest try: import multiprocessing _HASMP = True except ImportError: _HASMP = False from ..ext import events def mp_do_nothing(sender, *args): # Does nothing pass class SDL2ExtEventsTest(unittest.TestCase): __tags__ = ["sdl2ext"] def test_EventHandler(self): self.assertRaises(TypeError, events.EventHandler) self.assertIsInstance(events.EventHandler(None), events.EventHandler) self.assertIsInstance(events.EventHandler(132), events.EventHandler) self.assertIsInstance(events.EventHandler("Test"), events.EventHandler) ev = events.EventHandler(None) self.assertEqual(ev.sender, None) ev = events.EventHandler("Test") self.assertEqual(ev.sender, "Test") self.assertEqual(len(ev), 0) self.assertEqual(len(ev.callbacks), 0) def test_EventHandler_add__iadd__(self): ev = events.EventHandler(None) def doadd(ev, cb): ev += cb def callback(): pass self.assertRaises(TypeError, doadd, ev, None) self.assertRaises(TypeError, doadd, ev, "Test") self.assertRaises(TypeError, doadd, ev, 1234) self.assertEqual(len(ev), 0) ev += callback self.assertEqual(len(ev), 1) for x in range(4): ev += callback self.assertEqual(len(ev), 5) self.assertRaises(TypeError, ev.add, None) self.assertRaises(TypeError, ev.add, "Test") self.assertRaises(TypeError, ev.add, 1234) self.assertEqual(len(ev), 5) ev.add(callback) self.assertEqual(len(ev), 6) for x in range(4): ev.add(callback) self.assertEqual(len(ev), 10) def test_EventHandler_remove__isub__(self): ev = events.EventHandler(None) def doremove(ev, cb): ev -= cb def callback(): pass for x in range(10): ev += callback self.assertEqual(len(ev), 10) self.assertRaises(TypeError, ev.remove) for invval in ("Test", None, 1234, self.assertEqual): self.assertRaises(ValueError, ev.remove, invval) self.assertRaises(ValueError, doremove, ev, invval) self.assertEqual(len(ev), 10) ev.remove(callback) self.assertEqual(len(ev), 9) ev -= callback self.assertEqual(len(ev), 8) for x in range(3): ev.remove(callback) ev -= callback self.assertEqual(len(ev), 2) def test_EventHandler__call__(self): ev = events.EventHandler("Test") testsum = [] def callback(sender, sumval): self.assertEqual(sender, "Test") sumval.append(1) for x in range(10): ev += callback self.assertEqual(len(ev), 10) results = ev(testsum) self.assertEqual(len(testsum), 10) for v in testsum: self.assertEqual(v, 1) self.assertEqual(len(results), 10) for v in results: self.assertIsNone(v) @unittest.skipIf(not _HASMP, "multiprocessing is not supported") def test_MPEventHandler(self): self.assertRaises(TypeError, events.MPEventHandler) self.assertIsInstance(events.MPEventHandler(None), events.MPEventHandler) self.assertIsInstance(events.MPEventHandler(132), events.MPEventHandler) self.assertIsInstance(events.MPEventHandler("Test"), events.MPEventHandler) ev = events.MPEventHandler(None) self.assertEqual(ev.sender, None) ev = events.MPEventHandler("Test") self.assertEqual(ev.sender, "Test") self.assertEqual(len(ev), 0) self.assertEqual(len(ev.callbacks), 0) @unittest.skipIf(not _HASMP, "multiprocessing is not supported") def test_MPEventHandler_add__iadd__(self): ev = events.MPEventHandler(None) def doadd(ev, cb): ev += cb def callback(): pass self.assertRaises(TypeError, doadd, ev, None) self.assertRaises(TypeError, doadd, ev, "Test") self.assertRaises(TypeError, doadd, ev, 1234) self.assertEqual(len(ev), 0) ev += callback self.assertEqual(len(ev), 1) for x in range(4): ev += callback self.assertEqual(len(ev), 5) self.assertRaises(TypeError, ev.add, None) self.assertRaises(TypeError, ev.add, "Test") self.assertRaises(TypeError, ev.add, 1234) self.assertEqual(len(ev), 5) ev.add(callback) self.assertEqual(len(ev), 6) for x in range(4): ev.add(callback) self.assertEqual(len(ev), 10) @unittest.skipIf(not _HASMP, "multiprocessing is not supported") def test_MPEventHandler_remove__isub__(self): ev = events.MPEventHandler(None) def doremove(ev, cb): ev -= cb def callback(): pass for x in range(10): ev += callback self.assertEqual(len(ev), 10) self.assertRaises(TypeError, ev.remove) for invval in ("Test", None, 1234, self.assertEqual): self.assertRaises(ValueError, ev.remove, invval) self.assertRaises(ValueError, doremove, ev, invval) self.assertEqual(len(ev), 10) ev.remove(callback) self.assertEqual(len(ev), 9) ev -= callback self.assertEqual(len(ev), 8) for x in range(3): ev.remove(callback) ev -= callback self.assertEqual(len(ev), 2) @unittest.skipIf(not _HASMP, "multiprocessing is not supported") @unittest.skipIf(sys.platform == "win32", "relative import will create a fork bomb") def test_MPEventHandler__call__(self): ev = events.MPEventHandler("Test") for x in range(10): ev += mp_do_nothing self.assertEqual(len(ev), 10) results = ev().get(timeout=1) self.assertEqual(len(results), 10) for v in results: self.assertIsNone(v) results = ev("Test", 1234, "MoreArgs").get(timeout=1) self.assertEqual(len(results), 10) for v in results: self.assertIsNone(v) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_font_test.py0000644000000000000000000001262512260256443015307 0ustar # coding=utf-8 import sys import unittest from .. import ext as sdl2ext from ..ext.compat import byteify from .. import surface, sdlttf RESOURCES = sdl2ext.Resources(__file__, "resources") FONTMAP = ["0123456789", "ABCDEFGHIJ", "KLMNOPQRST", "UVWXYZ ", "abcdefghij", "klmnopqrst", "uvwxyz ", ",;.:!?-+()" ] class SDL2ExtFontTest(unittest.TestCase): __tags__ = ["sdl", "sdl2ext"] def setUp(self): sdl2ext.init() def tearDown(self): sdl2ext.quit() def test_BitmapFont(self): sf = surface.SDL_LoadBMP(byteify(RESOURCES.get_path("font.bmp"), "utf-8")) self.assertIsInstance(sf.contents, surface.SDL_Surface) font = sdl2ext.BitmapFont(sf, (32, 32), FONTMAP) self.assertIsInstance(font, sdl2ext.BitmapFont) sprite = sdl2ext.SoftwareSprite(sf.contents, True) self.assertIsInstance(sprite, sdl2ext.SoftwareSprite) font = sdl2ext.BitmapFont(sprite, (32, 32), FONTMAP) self.assertIsInstance(font, sdl2ext.BitmapFont) @unittest.skip("not implemented") def test_BitmapFont_render(self): pass @unittest.skip("not implemented") def test_BitmapFont_render_on(self): pass def test_BitmapFont_contains(self): sf = surface.SDL_LoadBMP(byteify(RESOURCES.get_path("font.bmp"), "utf-8")) self.assertIsInstance(sf.contents, surface.SDL_Surface) font = sdl2ext.BitmapFont(sf, (32, 32), FONTMAP) self.assertIsInstance(font, sdl2ext.BitmapFont) for ch in "abcde12345.-,+": self.assertTrue(font.contains(ch)) for ch in "äöüß": self.assertFalse(font.contains(ch)) def test_BitmapFont_can_render(self): sf = surface.SDL_LoadBMP(byteify(RESOURCES.get_path("font.bmp"), "utf-8")) self.assertIsInstance(sf.contents, surface.SDL_Surface) font = sdl2ext.BitmapFont(sf, (32, 32), FONTMAP) self.assertIsInstance(font, sdl2ext.BitmapFont) self.assertTrue(font.can_render("text")) self.assertTrue(font.can_render("473285435hfsjadfhriuewtrhefd")) self.assertFalse(font.can_render("testä")) def test_FontManager(self): fm = sdl2ext.FontManager(RESOURCES.get_path("tuffy.ttf"), bg_color=(100, 0, 0)) self.assertIsInstance(fm, sdl2ext.FontManager) self.assertEqual(fm.default_font, "tuffy") self.assertEqual(fm.size, 16) self.assertEqual(fm.bg_color, sdl2ext.Color(100, 0, 0, 0)) def test_FontManager_default_font(self): fm = sdl2ext.FontManager(RESOURCES.get_path("tuffy.ttf")) self.assertEqual(fm.default_font, "tuffy") self.assertEqual(fm.size, 16) with self.assertRaises(ValueError): fm.default_font = "Inexistent Alias" fm.add(RESOURCES.get_path("tuffy.copy.ttf"), size = 10) fm.default_font = "tuffy.copy" fm.size = 10 self.assertEqual(fm.default_font, "tuffy.copy") self.assertEqual(fm.size, 10) fm.default_font = "tuffy.copy" fm.size = 16 self.assertEqual(fm.default_font, "tuffy.copy") self.assertEqual(fm.size, 16) def test_FontManager_add(self): fm = sdl2ext.FontManager(RESOURCES.get_path("tuffy.ttf")) self.assertIn("tuffy", fm.aliases) self.assertIn("tuffy", fm.fonts) self.assertIn(16, fm.fonts["tuffy"]) self.assertIsInstance(fm.fonts["tuffy"][16].contents, sdlttf.TTF_Font) # Do some metrics tests font = fm.fonts["tuffy"][16] self.assertEqual(16, sdlttf.TTF_FontAscent(font)) fm.add(RESOURCES.get_path("tuffy.ttf"), size=12) font = fm.fonts["tuffy"][12] self.assertEqual(12, sdlttf.TTF_FontAscent(font)) self.assertRaises(IOError, fm.add, "inexistent.ttf") # I don't find a scenario raising a TTF_Error. # self.assertRaises(sdl2ext.SDLError, fm.add, "resources/tuffy.ttf", # size=-1) # Close the font manager and add a new font fm.close() fm.add(RESOURCES.get_path("tuffy.ttf"), size=12) self.assertIsInstance(fm.fonts["tuffy"][12].contents, sdlttf.TTF_Font) def test_FontManager_close(self): fm = sdl2ext.FontManager(RESOURCES.get_path("tuffy.ttf")) fm.add(RESOURCES.get_path("tuffy.ttf"), size=20) fm.add(RESOURCES.get_path("tuffy.ttf"), alias="Foo", size=10) fm.close() self.assertEqual(fm.fonts, {}) # How to make sure TTF_CloseFont was called on each loaded font? def test_FontManager_render(self): fm = sdl2ext.FontManager(RESOURCES.get_path("tuffy.ttf")) text_surf = fm.render("text") self.assertIsInstance(text_surf, surface.SDL_Surface) self.assertTrue(text_surf.w > 1) text_surf = fm.render("text", size=10) self.assertIsInstance(text_surf, surface.SDL_Surface) text_surf = fm.render(""" text long enough to have it wrapped at 100 px width.""", size=20, width=100) self.assertIsInstance(text_surf, surface.SDL_Surface) self.assertTrue(text_surf.w > 1) self.assertTrue(text_surf.w == 100) self.assertRaises(KeyError, fm.render, "text", alias="inexistent") if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_gui_test.py0000644000000000000000000000345512260256443015126 0ustar import sys import unittest from .. import ext as sdl2ext class SDL2ExtGUITest(unittest.TestCase): __tags__ = ["sdl", "sdl2ext"] def setUp(self): sdl2ext.init() def tearDown(self): sdl2ext.quit() @unittest.skip("not implemented") def test_UIFactory(self): pass @unittest.skip("not implemented") def test_UIFactory_create_button(self): pass @unittest.skip("not implemented") def test_UIFactory_create_checkbutton(self): pass @unittest.skip("not implemented") def test_UIFactory_create_text_entry(self): pass @unittest.skip("not implemented") def test_Button(self): pass @unittest.skip("not implemented") def test_CheckButton(self): pass @unittest.skip("not implemented") def test_TextEntry(self): pass @unittest.skip("not implemented") def test_UIProcessor(self): pass @unittest.skip("not implemented") def test_UIProcessor_activate(self): pass @unittest.skip("not implemented") def test_UIProcessor_deactivate(self): pass @unittest.skip("not implemented") def test_UIProcessor_dispatch(self): pass @unittest.skip("not implemented") def test_UIProcessor_mousedown(self): pass @unittest.skip("not implemented") def test_UIProcessor_mouseup(self): pass @unittest.skip("not implemented") def test_UIProcessor_mousemotion(self): pass @unittest.skip("not implemented") def test_UIProcessor_passevent(self): pass @unittest.skip("not implemented") def test_UIProcessor_process(self): pass @unittest.skip("not implemented") def test_UIProcessor_textinput(self): pass if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_image_test.py0000644000000000000000000000353112260256443015417 0ustar import sys import unittest from .. import ext as sdl2ext from .. import surface RESOURCES = sdl2ext.Resources(__file__, "resources") formats = [ # Do not use bmp - it's contained in resources.zip "cur", "gif", "ico", "jpg", "lbm", "pbm", "pcx", "pgm", "png", "pnm", "ppm", "tga", "tif", "webp", "xcf", "xpm", # "xv", ] class SDL2ExtImageTest(unittest.TestCase): __tags__ = ["sdl", "sdl2ext"] def setUp(self): sdl2ext.init() def tearDown(self): sdl2ext.quit() def test_get_image_formats(self): self.assertIsInstance(sdl2ext.get_image_formats(), tuple) supformats = sdl2ext.get_image_formats() for fmt in formats: self.assertTrue(fmt in supformats) def test_load_image(self): # TODO: add image comparision to check, if it actually does the # right thing (SDL2 BMP loaded image?) # Add argument tests try: import PIL _HASPIL = True except ImportError: _HASPIL = False fname = "surfacetest.%s" for fmt in formats: filename = RESOURCES.get_path(fname % fmt) sf = sdl2ext.load_image(filename) self.assertIsInstance(sf, surface.SDL_Surface) # Force only PIL if _HASPIL and fmt not in ("webp", "xcf", "lbm"): sf = sdl2ext.load_image(filename, enforce="PIL") self.assertIsInstance(sf, surface.SDL_Surface) # Force only mule.sdlimage sf = sdl2ext.load_image(filename, enforce="SDL") self.assertIsInstance(sf, surface.SDL_Surface) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_particles_test.py0000644000000000000000000001020012260256443016312 0ustar import sys import unittest from ..ext import particles class SDL2ExtParticlesTest(unittest.TestCase): __tags__ = ["sdl2ext"] def test_Particle(self): p = particles.Particle(0, 0, 0) self.assertIsInstance(p, particles.Particle) self.assertTrue(p.x == p.y == p.life == 0) p = particles.Particle(1, 2, 3) self.assertIsInstance(p, particles.Particle) self.assertEqual(p.x, 1) self.assertEqual(p.y, 2) self.assertEqual(p.life, 3) def test_Particle_xy_position(self): for x in range(-100, 100): for y in range(-100, 100): p = particles.Particle(x, y, 1) self.assertEqual(p.position, (x, y)) self.assertEqual(p.x, x) self.assertEqual(p.y, y) p.position = x + 1, y + 1 self.assertEqual(p.position, (x + 1, y + 1)) self.assertEqual(p.x, x + 1) self.assertEqual(p.y, y + 1) p.x = x self.assertEqual(p.position, (x, y + 1)) self.assertEqual(p.x, x) self.assertEqual(p.y, y + 1) p.y = y self.assertEqual(p.position, (x, y)) self.assertEqual(p.x, x) self.assertEqual(p.y, y) def test_Particle_life(self): for life in range(-100, 100): p = particles.Particle(0, 0, life) self.assertEqual(p.life, life) def test_ParticleEngine(self): engine = particles.ParticleEngine() self.assertIsInstance(engine, particles.ParticleEngine) self.assertTrue(particles.Particle in engine.componenttypes) self.assertIsNone(engine.createfunc) self.assertIsNone(engine.deletefunc) self.assertIsNone(engine.updatefunc) def test_ParticleEngine_createfunc(self): def func(w, c): pass engine = particles.ParticleEngine() self.assertIsNone(engine.createfunc) engine.createfunc = func self.assertEqual(engine.createfunc, func) def setf(x, f): x.createfunc = f self.assertRaises(TypeError, setf, engine, None) self.assertRaises(TypeError, setf, engine, "Test") self.assertRaises(TypeError, setf, engine, 1234) def test_ParticleEngine_deletefunc(self): def func(w, c): pass engine = particles.ParticleEngine() self.assertIsNone(engine.deletefunc) engine.deletefunc = func self.assertEqual(engine.deletefunc, func) def setf(x, f): x.deletefunc = f self.assertRaises(TypeError, setf, engine, None) self.assertRaises(TypeError, setf, engine, "Test") self.assertRaises(TypeError, setf, engine, 1234) def test_ParticleEngine_updatefunc(self): def func(w, c): pass engine = particles.ParticleEngine() self.assertIsNone(engine.updatefunc) engine.updatefunc = func self.assertEqual(engine.updatefunc, func) def setf(x, f): x.updatefunc = f self.assertRaises(TypeError, setf, engine, None) self.assertRaises(TypeError, setf, engine, "Test") self.assertRaises(TypeError, setf, engine, 1234) def test_ParticleEngine_process(self): def cfunc(w, c): self.assertEqual(len(c), w["runs"]) for p in c: self.assertLessEqual(p.life, 0) def ufunc(w, c): self.assertEqual(len(c), 100 - w["runs"]) for p in c: self.assertGreaterEqual(p.life, 1) def dfunc(w, c): self.assertEqual(len(c), w["runs"]) for p in c: self.assertLessEqual(p.life, 0) plist = [] for x in range(2, 102): plist.append(particles.Particle(x, x, x - 1)) engine = particles.ParticleEngine() engine.createfunc = cfunc engine.updatefunc = ufunc engine.deletefunc = dfunc world = {"runs": 1} engine.process(world, plist) world["runs"] = 2 engine.process(world, plist) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_pixelaccess_test.py0000644000000000000000000000512012260256443016634 0ustar import sys import unittest from .. import ext as sdl2ext try: import numpy _HASNUMPY = True except: _HASNUMPY = False class SDL2ExtPixelAccessTest(unittest.TestCase): __tags__ = ["sdl", "sdl2ext"] def setUp(self): sdl2ext.init() def tearDown(self): sdl2ext.quit() @unittest.skipIf(hasattr(sys, "pypy_version_info"), "PyPy's ctypes can't do byref(value, offset)") @unittest.skipIf(sys.platform=="cli", "IronPython can't cast correctly") def test_PixelView(self): factory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE) sprite = factory.create_sprite(size=(10, 10), bpp=32) view = sdl2ext.PixelView(sprite) view[1] = (0xAABBCCDD,) * 10 rcolor = sdl2ext.prepare_color(0xAABBCCDD, sprite) for index, row in enumerate(view): if index == 1: for col in row: self.assertEqual(col, rcolor) else: for col in row: self.assertEqual(col, 0x0) @unittest.skip("not implemented") @unittest.skipIf(not _HASNUMPY, "numpy module is not supported") def test_pixels2d(self): factory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE) sprite = factory.create_sprite(size=(5, 10), bpp=32, masks=(0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF)) sdl2ext.fill(sprite, 0x01, (2, 2, 2, 2)) nparray = sdl2ext.pixels2d(sprite) @unittest.skipIf(not _HASNUMPY, "numpy module is not supported") def test_pixels3d(self): factory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE) sprite = factory.create_sprite(size=(5, 10), bpp=32, masks=(0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF)) sdl2ext.fill(sprite, 0xAABBCCDD, (1, 2, 3, 4)) nparray = sdl2ext.pixels3d(sprite) for x in range(1, 4): for y in range(2, 6): self.assertTrue(numpy.all([nparray[x, y], [0xAA, 0xBB, 0xCC, 0xDD]])) self.assertFalse(numpy.all([nparray[0, 0], [0xAA, 0xBB, 0xCC, 0xDD]])) self.assertFalse(numpy.all([nparray[1, 0], [0xAA, 0xBB, 0xCC, 0xDD]])) self.assertFalse(numpy.all([nparray[0, 1], [0xAA, 0xBB, 0xCC, 0xDD]])) self.assertFalse(numpy.all([nparray[3, 6], [0xAA, 0xBB, 0xCC, 0xDD]])) self.assertFalse(numpy.all([nparray[4, 6], [0xAA, 0xBB, 0xCC, 0xDD]])) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_resources_test.py0000644000000000000000000002336212260256443016353 0ustar import os import sys import unittest import urllib if sys.version_info[0] < 3: import urllib2 else: import urllib.request as urllib2 from ..ext import resources class SDL2ExtResourcesTest(unittest.TestCase): __tags__ = ["sdl2ext"] def test_open_zipfile(self): fpath = os.path.join(os.path.dirname(__file__), "resources") zfile = os.path.join(fpath, "resources.zip") # resources.zip is a packed version of resources/, which at # least contains # # resources/rwopstest.txt # resources/surfacetest.bmp resfile = resources.open_zipfile(zfile, "rwopstest.txt", "resources") self.assertIsNotNone(resfile) resfile = resources.open_zipfile(zfile, "resources/rwopstest.txt") self.assertIsNotNone(resfile) self.assertRaises(KeyError, resources.open_zipfile, zfile, "invalid") self.assertRaises(KeyError, resources.open_zipfile, zfile, None) self.assertRaises(KeyError, resources.open_zipfile, zfile, "rwopstest.txt", "data") self.assertRaises(KeyError, resources.open_zipfile, zfile, "rwopstest.txt", 1234) self.assertRaises(KeyError, resources.open_zipfile, zfile, None, None) self.assertRaises(TypeError, resources.open_zipfile, None, "rwopstest.txt") self.assertRaises(TypeError, resources.open_zipfile, None, None) self.assertRaises(TypeError, resources.open_zipfile, None, "rwopstest.txt", "resources") def test_open_tarfile(self): fpath = os.path.join(os.path.dirname(__file__), "resources") tfile = os.path.join(fpath, "resources.tar.gz") # resources.tar.gz is a packed version of resources/, which at # least contains # # resources/rwopstest.txt # resources/surfacetest.bmp resfile = resources.open_tarfile(tfile, "rwopstest.txt", "resources") self.assertIsNotNone(resfile) resfile = resources.open_tarfile(tfile, "resources/rwopstest.txt") self.assertIsNotNone(resfile) # TODO: refine the error handling in open_tarfile() self.assertRaises(KeyError, resources.open_tarfile, tfile, "invalid") self.assertRaises(AttributeError, resources.open_tarfile, tfile, None) self.assertRaises(KeyError, resources.open_tarfile, tfile, "rwopstest.txt", "data") self.assertRaises(KeyError, resources.open_tarfile, tfile, "rwopstest.txt", 1234) self.assertRaises(AttributeError, resources.open_tarfile, tfile, None, None) self.assertRaises(ValueError, resources.open_tarfile, None, "rwopstest.txt") self.assertRaises(ValueError, resources.open_tarfile, None, None) self.assertRaises(ValueError, resources.open_tarfile, None, "rwopstest.txt", "resources") def test_open_url(self): if sys.version_info[0] < 3: p2url = urllib.pathname2url else: p2url = urllib2.pathname2url fpath = os.path.join(os.path.dirname(__file__), "resources") fpath = os.path.abspath(fpath) tfile = os.path.join(fpath, "rwopstest.txt") urlpath = "file:%s" % p2url(tfile) resfile = resources.open_url(urlpath) self.assertIsNotNone(resfile) tfile = os.path.join(fpath, "invalid") urlpath = "file:%s" % p2url(tfile) self.assertRaises(urllib2.URLError, resources.open_url, urlpath) @unittest.skipIf(sys.platform=="cli", "IronPython's tarfile module is broken") def test_Resources(self): self.assertRaises(ValueError, resources.Resources, "invalid") res = resources.Resources() self.assertIsInstance(res, resources.Resources) self.assertRaises(KeyError, res.get, "surfacetest.bmp") fpath = os.path.join(os.path.dirname(__file__), "resources") res = resources.Resources(fpath) self.assertIsNotNone(res.get("rwopstest.txt")) self.assertIsNotNone(res.get("surfacetest.bmp")) res2 = resources.Resources(__file__) self.assertIsNotNone(res2.get("rwopstest.txt")) self.assertIsNotNone(res2.get("surfacetest.bmp")) res3 = resources.Resources(__file__, "resources") self.assertIsNotNone(res3.get("rwopstest.txt")) self.assertIsNotNone(res3.get("surfacetest.bmp")) @unittest.skipIf(sys.platform=="cli", "IronPython's tarfile module is broken") def test_Resources_add(self): fpath = os.path.join(os.path.dirname(__file__), "resources") sfile = os.path.join(fpath, "surfacetest.bmp") zfile = os.path.join(fpath, "resources.zip") res = resources.Resources() res.add(sfile) self.assertRaises(KeyError, res.get, "rwopstest.txt") self.assertIsNotNone(res.get("surfacetest.bmp")) res.add(zfile) self.assertIsNotNone(res.get("rwopstest.txt")) self.assertIsNotNone(res.get("surfacetest.bmp")) self.assertRaises(TypeError, res.add, None) self.assertRaises(ValueError, res.add, "invalid_name.txt") def test_Resources_add_file(self): fpath = os.path.join(os.path.dirname(__file__), "resources") sfile = os.path.join(fpath, "surfacetest.bmp") zfile = os.path.join(fpath, "resources.zip") res = resources.Resources() res.add_file(sfile) res.add_file(zfile) self.assertRaises(KeyError, res.get, "rwopstest.txt") self.assertIsNotNone(res.get("surfacetest.bmp")) self.assertIsNotNone(res.get("resources.zip")) self.assertRaises(TypeError, res.add_file, None) self.assertRaises(ValueError, res.add_file, "invalid_name.txt") def test_Resources_add_archive(self): fpath = os.path.join(os.path.dirname(__file__), "resources") zfile = os.path.join(fpath, "resources.zip") tfile = os.path.join(fpath, "resources.tar.gz") res = resources.Resources() res.add_archive(zfile) self.assertIsNotNone(res.get("surfacetest.bmp")) self.assertIsNotNone(res.get("rwopstest.txt")) self.assertRaises(KeyError, res.get, "resources.zip") self.assertRaises(TypeError, res.add_archive, None) self.assertRaises(ValueError, res.add_archive, "invalid_name.txt") res = resources.Resources() res.add_archive(tfile, typehint="targz") self.assertIsNotNone(res.get("surfacetest.bmp")) self.assertIsNotNone(res.get("rwopstest.txt")) self.assertRaises(KeyError, res.get, "resources.tar.gz") @unittest.skipIf(sys.platform=="cli", "IronPython's tarfile module is broken") def test_Resources_get(self): fpath = os.path.join(os.path.dirname(__file__), "resources") for path in (fpath, None): res = resources.Resources(path) self.assertRaises(KeyError, res.get, "invalid_file.txt") self.assertRaises(KeyError, res.get, None) self.assertRaises(KeyError, res.get, 123456) if path is None: self.assertRaises(KeyError, res.get, "surfacetest.bmp") self.assertRaises(KeyError, res.get, "rwopstest.txt") else: self.assertIsNotNone(res.get("surfacetest.bmp")) self.assertIsNotNone(res.get("rwopstest.txt")) @unittest.skipIf(sys.platform=="cli", "IronPython's tarfile module is broken") def test_Resources_get_filelike(self): fpath = os.path.join(os.path.dirname(__file__), "resources") zfile = os.path.join(fpath, "resources.zip") pfile = os.path.join(fpath, "rwopstest.txt") res = resources.Resources() res.add(zfile) v1 = res.get_filelike("rwopstest.txt") v2 = res.get_filelike("surfacetest.bmp") self.assertEqual(type(v1), type(v2)) res.add(pfile) v1 = res.get_filelike("rwopstest.txt") v2 = res.get_filelike("surfacetest.bmp") self.assertNotEqual(type(v1), type(v2)) self.assertRaises(KeyError, res.get_filelike, None) self.assertRaises(KeyError, res.get_filelike, "invalid") self.assertRaises(KeyError, res.get_filelike, 1234) @unittest.skipIf(sys.platform=="cli", "IronPython's tarfile module is broken") def test_Resources_get_path(self): fpath = os.path.join(os.path.dirname(__file__), "resources") zfile = os.path.join(fpath, "resources.zip") pfile = os.path.join(fpath, "rwopstest.txt") res = resources.Resources() res.add(zfile) res.add(pfile) zpath = res.get_path("surfacetest.bmp") self.assertTrue(zpath.find("surfacetest.bmp@") != -1) self.assertNotEqual(zpath, zfile) ppath = res.get_path("rwopstest.txt") self.assertTrue(ppath.find("rwopstest.txt") != -1) self.assertRaises(KeyError, res.get_path, None) self.assertRaises(KeyError, res.get_path, "invalid") self.assertRaises(KeyError, res.get_path, 1234) @unittest.skipIf(sys.platform=="cli", "IronPython's tarfile module is broken") def test_Resources_scan(self): fpath = os.path.join(os.path.dirname(__file__)) res = resources.Resources() res.scan(fpath) self.assertIsNotNone(res.get("rwopstest.txt")) self.assertIsNotNone(res.get("surfacetest.bmp")) self.assertRaises(ValueError, res.scan, "invalid") self.assertRaises(ValueError, res.scan, fpath, "invalid") self.assertRaises(Exception, res.scan, 12345) res = resources.Resources() res.scan(fpath, "resources") self.assertIsNotNone(res.get("rwopstest.txt")) self.assertIsNotNone(res.get("surfacetest.bmp")) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_sprite_test.py0000644000000000000000000007044612354202052015643 0ustar import sys import unittest from ctypes import ArgumentError, POINTER, byref from ..ext.resources import Resources from .. import ext as sdl2ext from ..surface import SDL_Surface, SDL_CreateRGBSurface, SDL_FreeSurface from sdl2.video import SDL_Window, SDL_WINDOW_HIDDEN, SDL_DestroyWindow from sdl2.render import SDL_Renderer, SDL_CreateWindowAndRenderer, \ SDL_DestroyRenderer, SDL_CreateTexture, SDL_Texture, \ SDL_TEXTUREACCESS_STATIC, SDL_TEXTUREACCESS_STREAMING, \ SDL_TEXTUREACCESS_TARGET _ISPYPY = hasattr(sys, "pypy_version_info") RESOURCES = Resources(__file__, "resources") class MSprite(sdl2ext.Sprite): def __init__(self, w=0, h=0): super(MSprite, self).__init__() self._size = w, h @property def size(self): return self._size class SDL2ExtSpriteTest(unittest.TestCase): __tags__ = ["sdl", "sdl2ext"] def setUp(self): sdl2ext.init() def tearDown(self): sdl2ext.quit() def check_pixels(self, view, w, h, sprite, c1, c2, cx=0, cy=0): msg = "color mismatch at %d,%d: %d not in %s" cx = cx + sprite.x cy = cy + sprite.y cw, ch = sprite.size cmy = cy + ch cmx = cx + cw for y in range(w): for x in range(h): if cy <= y < cmy and cx <= x < cmx: self.assertEqual(view[y][x], c1, msg % (x, y, view[y][x], c1)) else: self.assertTrue(view[y][x] in c2, msg % (x, y, view[y][x], c2)) def check_areas(self, view, w, h, rects, c1, c2): def _inarea(x, y, rs): for r in rs: if (x >= r[0] and x < (r[0] + r[2]) and y >= r[1] and y < (r[1] + r[3])): return True return False msg = "color mismatch at %d,%d: %d not in %s" for y in range(w): for x in range(h): if _inarea(x, y, rects): self.assertEqual(view[y][x], c1, msg % (x, y, view[y][x], c1)) else: self.assertTrue(view[y][x] in c2, msg % (x, y, view[y][x], c2)) def check_lines(self, view, w, h, points, c1, c2): def _online(x, y, pts): for p1, p2 in pts: if sdl2ext.point_on_line(p1, p2, (x, y)): return True return False msg = "color mismatch at %d,%d: %d not in %s" for y in range(w): for x in range(h): if _online(x, y, points): self.assertEqual(view[y][x], c1, msg % (x, y, view[y][x], c1)) else: self.assertTrue(view[y][x] in c2, msg % (x, y, view[y][x], c2)) def test_SpriteFactory(self): factory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE) self.assertIsInstance(factory, sdl2ext.SpriteFactory) self.assertEqual(factory.default_args, {}) factory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE, bananas="tasty") self.assertIsInstance(factory, sdl2ext.SpriteFactory) self.assertEqual(factory.default_args, {"bananas": "tasty"}) window = sdl2ext.Window("Test", size=(1, 1)) renderer = sdl2ext.Renderer(window) factory = sdl2ext.SpriteFactory(sdl2ext.TEXTURE, renderer=renderer) self.assertIsInstance(factory, sdl2ext.SpriteFactory) factory = sdl2ext.SpriteFactory(sdl2ext.TEXTURE, renderer=renderer) self.assertIsInstance(factory, sdl2ext.SpriteFactory) self.assertEqual(factory.default_args, {"renderer": renderer}) self.assertRaises(ValueError, sdl2ext.SpriteFactory, "Test") self.assertRaises(ValueError, sdl2ext.SpriteFactory, -456) self.assertRaises(ValueError, sdl2ext.SpriteFactory, 123) self.assertRaises(ValueError, sdl2ext.SpriteFactory, sdl2ext.TEXTURE) def test_SpriteFactory_create_sprite(self): window = sdl2ext.Window("Test", size=(1, 1)) renderer = sdl2ext.Renderer(window) tfactory = sdl2ext.SpriteFactory(sdl2ext.TEXTURE, renderer=renderer) sfactory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE) for w in range(0, 100): for h in range(0, 100): for bpp in (1, 4, 8, 12, 15, 16, 24, 32): sprite = sfactory.create_sprite(size=(w, h), bpp=bpp) self.assertIsInstance(sprite, sdl2ext.SoftwareSprite) if w == 0 or h == 0: self.assertRaises(sdl2ext.SDLError, tfactory.create_sprite, size=(w, h)) continue sprite = tfactory.create_sprite(size=(w, h)) self.assertIsInstance(sprite, sdl2ext.TextureSprite) def test_SpriteFactory_create_software_sprite(self): factory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE) for w in range(0, 100): for h in range(0, 100): for bpp in (1, 4, 8, 12, 15, 16, 24, 32): sprite = factory.create_software_sprite((w, h), bpp) self.assertIsInstance(sprite, sdl2ext.SoftwareSprite) #self.assertRaises(ValueError, factory.create_software_sprite, (-1,-1)) #self.assertRaises(ValueError, factory.create_software_sprite, (-10,5)) #self.assertRaises(ValueError, factory.create_software_sprite, (10,-5)) self.assertRaises(TypeError, factory.create_software_sprite, size=None) self.assertRaises(sdl2ext.SDLError, factory.create_software_sprite, size=(10, 10), bpp=-1) self.assertRaises(TypeError, factory.create_software_sprite, masks=5) self.assertRaises((ArgumentError, TypeError), factory.create_software_sprite, size=(10, 10), masks=(None, None, None, None)) self.assertRaises((ArgumentError, TypeError), factory.create_software_sprite, size=(10, 10), masks=("Test", 1, 2, 3)) def test_SpriteFactory_create_texture_sprite(self): window = sdl2ext.Window("Test", size=(1, 1)) renderer = sdl2ext.Renderer(window) factory = sdl2ext.SpriteFactory(sdl2ext.TEXTURE, renderer=renderer) for w in range(1, 100): for h in range(1, 100): sprite = factory.create_texture_sprite(renderer, size=(w, h)) self.assertIsInstance(sprite, sdl2ext.TextureSprite) # Test different access flags for flag in (SDL_TEXTUREACCESS_STATIC, SDL_TEXTUREACCESS_STREAMING, SDL_TEXTUREACCESS_TARGET, 22): sprite = factory.create_texture_sprite(renderer, size=(64, 64), access=flag) self.assertIsInstance(sprite, sdl2ext.TextureSprite) def test_SpriteFactory_from_image(self): window = sdl2ext.Window("Test", size=(1, 1)) renderer = sdl2ext.Renderer(window) tfactory = sdl2ext.SpriteFactory(sdl2ext.TEXTURE, renderer=renderer) sfactory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE) for suffix in ("tif", "png", "jpg"): imgname = RESOURCES.get_path("surfacetest.%s" % suffix) tsprite = tfactory.from_image(imgname) self.assertIsInstance(tsprite, sdl2ext.TextureSprite) ssprite = sfactory.from_image(imgname) self.assertIsInstance(ssprite, sdl2ext.SoftwareSprite) for factory in (tfactory, sfactory): self.assertRaises((AttributeError, TypeError, sdl2ext.SDLError), factory.from_image, None) #self.assertRaises((IOError, SDLError), # factory.from_image, "banana") self.assertRaises((AttributeError, IOError, sdl2ext.SDLError), factory.from_image, 12345) @unittest.skip("not implemented") def test_SpriteFactory_from_object(self): window = sdl2ext.Window("Test", size=(1, 1)) renderer = sdl2ext.Renderer(window) tfactory = sdl2ext.SpriteFactory(sdl2ext.TEXTURE, renderer=renderer) sfactory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE) def test_SpriteFactory_from_surface(self): window = sdl2ext.Window("Test", size=(1, 1)) renderer = sdl2ext.Renderer(window) tfactory = sdl2ext.SpriteFactory(sdl2ext.TEXTURE, renderer=renderer) sfactory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE) sf = SDL_CreateRGBSurface(0, 10, 10, 32, 0, 0, 0, 0) tsprite = tfactory.from_surface(sf.contents) self.assertIsInstance(tsprite, sdl2ext.TextureSprite) ssprite = sfactory.from_surface(sf.contents) self.assertIsInstance(ssprite, sdl2ext.SoftwareSprite) SDL_FreeSurface(sf) for factory in (tfactory, sfactory): self.assertRaises((sdl2ext.SDLError, AttributeError, ArgumentError, TypeError), factory.from_surface, None) self.assertRaises((AttributeError, ArgumentError, TypeError), factory.from_surface, "test") # TODO: crashes pypy 2.0 #self.assertRaises((AttributeError, ArgumentError, TypeError), # factory.from_surface, 1234) def test_SpriteFactory_from_text(self): sfactory = sdl2ext.SpriteFactory(sdl2ext.SOFTWARE) fm = sdl2ext.FontManager(RESOURCES.get_path("tuffy.ttf")) # No Fontmanager passed self.assertRaises(KeyError, sfactory.from_text, "Test") # Passing various keywords arguments sprite = sfactory.from_text("Test", fontmanager = fm) self.assertIsInstance(sprite, sdl2ext.SoftwareSprite) sprite = sfactory.from_text("Test", fontmanager = fm, alias="tuffy") self.assertIsInstance(sprite, sdl2ext.SoftwareSprite) # Get text from a texture sprite factory window = sdl2ext.Window("Test", size=(1, 1)) renderer = sdl2ext.Renderer(window) tfactory = sdl2ext.SpriteFactory(sdl2ext.TEXTURE, renderer=renderer, fontmanager=fm) sprite = tfactory.from_text("Test", alias="tuffy") self.assertIsInstance(sprite, sdl2ext.TextureSprite) def test_SpriteRenderSystem(self): renderer = sdl2ext.SpriteRenderSystem() self.assertIsInstance(renderer, sdl2ext.SpriteRenderSystem) self.assertIsNotNone(renderer.sortfunc) self.assertTrue(sdl2ext.Sprite in renderer.componenttypes) def test_SpriteRenderSystem_sortfunc(self): def func(p): pass renderer = sdl2ext.SpriteRenderSystem() self.assertIsNotNone(renderer.sortfunc) renderer.sortfunc = func self.assertEqual(renderer.sortfunc, func) def setf(x, f): x.sortfunc = f self.assertRaises(TypeError, setf, renderer, None) self.assertRaises(TypeError, setf, renderer, "Test") self.assertRaises(TypeError, setf, renderer, 1234) @unittest.skip("not implemented") def test_SpriteRenderSystem_render(self): pass @unittest.skip("not implemented") def test_SpriteRenderSystem_process(self): pass def test_SoftwareSpriteRenderSystem(self): self.assertRaises(TypeError, sdl2ext.SoftwareSpriteRenderSystem) self.assertRaises(TypeError, sdl2ext.SoftwareSpriteRenderSystem, None) self.assertRaises(TypeError, sdl2ext.SoftwareSpriteRenderSystem, "Test") self.assertRaises(TypeError, sdl2ext.SoftwareSpriteRenderSystem, 12345) window = sdl2ext.Window("Test", size=(1, 1)) renderer = sdl2ext.SoftwareSpriteRenderSystem(window) self.assertIsInstance(renderer, sdl2ext.SpriteRenderSystem) self.assertEqual(renderer.window, window.window) self.assertIsInstance(renderer.surface, SDL_Surface) renderer = sdl2ext.SoftwareSpriteRenderSystem(window.window) self.assertIsInstance(renderer, sdl2ext.SpriteRenderSystem) self.assertEqual(renderer.window, window.window) self.assertIsInstance(renderer.surface, SDL_Surface) self.assertIsNotNone(renderer.sortfunc) self.assertFalse(sdl2ext.Sprite in renderer.componenttypes) self.assertTrue(sdl2ext.SoftwareSprite in renderer.componenttypes) @unittest.skipIf(_ISPYPY, "PyPy's ctypes can't do byref(value, offset)") def test_SoftwareSpriteRenderSystem_render(self): sf1 = SDL_CreateRGBSurface(0, 12, 7, 32, 0, 0, 0, 0) sp1 = sdl2ext.SoftwareSprite(sf1.contents, True) sdl2ext.fill(sp1, 0xFF0000) sf2 = SDL_CreateRGBSurface(0, 3, 9, 32, 0, 0, 0, 0) sp2 = sdl2ext.SoftwareSprite(sf2.contents, True) sdl2ext.fill(sp2, 0x00FF00) sprites = [sp1, sp2] window = sdl2ext.Window("Test", size=(20, 20)) renderer = sdl2ext.SoftwareSpriteRenderSystem(window) self.assertIsInstance(renderer, sdl2ext.SpriteRenderSystem) self.assertRaises(AttributeError, renderer.render, None, None, None) self.assertRaises(AttributeError, renderer.render, [None, None], None, None) for x, y in ((0, 0), (3, 3), (20, 20), (1, 12), (5, 6)): sp1.position = x, y renderer.render(sp1) view = sdl2ext.PixelView(renderer.surface) self.check_pixels(view, 20, 20, sp1, 0xFF0000, (0x0,)) del view sdl2ext.fill(renderer.surface, 0x0) sp1.position = 0, 0 sp2.position = 14, 1 renderer.render(sprites) view = sdl2ext.PixelView(renderer.surface) self.check_pixels(view, 20, 20, sp1, 0xFF0000, (0x0, 0x00FF00)) self.check_pixels(view, 20, 20, sp2, 0x00FF00, (0x0, 0xFF0000)) del view sdl2ext.fill(renderer.surface, 0x0) renderer.render(sprites, 1, 2) view = sdl2ext.PixelView(renderer.surface) self.check_pixels(view, 20, 20, sp1, 0xFF0000, (0x0, 0x00FF00), 1, 2) self.check_pixels(view, 20, 20, sp2, 0x00FF00, (0x0, 0xFF0000), 1, 2) del view @unittest.skipIf(_ISPYPY, "PyPy's ctypes can't do byref(value, offset)") def test_SoftwareSpriteRenderSystem_process(self): sf1 = SDL_CreateRGBSurface(0, 5, 10, 32, 0, 0, 0, 0) sp1 = sdl2ext.SoftwareSprite(sf1.contents, True) sp1.depth = 0 sdl2ext.fill(sp1, 0xFF0000) sf2 = SDL_CreateRGBSurface(0, 5, 10, 32, 0, 0, 0, 0) sp2 = sdl2ext.SoftwareSprite(sf2.contents, True) sp2.depth = 99 sdl2ext.fill(sp2, 0x00FF00) sprites = [sp1, sp2] window = sdl2ext.Window("Test", size=(20, 20)) renderer = sdl2ext.SoftwareSpriteRenderSystem(window) renderer.process("fakeworld", sprites) view = sdl2ext.PixelView(renderer.surface) # Only sp2 wins, since its depth is higher self.check_pixels(view, 20, 20, sp1, 0x00FF00, (0x0,)) self.check_pixels(view, 20, 20, sp2, 0x00FF00, (0x0,)) del view self.assertRaises(TypeError, renderer.process, None, None) @unittest.skip("not implemented") def test_TextureSpriteRenderSystem(self): pass @unittest.skip("not implemented") def test_TextureSpriteRenderSystem_render(self): pass @unittest.skip("not implemented") def test_TextureSpriteRenderSystem_process(self): pass def test_Sprite(self): sprite = MSprite() self.assertIsInstance(sprite, MSprite) self.assertIsInstance(sprite, sdl2ext.Sprite) def test_Sprite_position_xy(self): sprite = MSprite() positions = [(x, y) for x in range(-50, 50) for y in range(-50, 50)] for x, y in positions: sprite.position = x, y self.assertEqual(sprite.position, (x, y)) sprite.x = x + 1 sprite.y = y + 1 self.assertEqual(sprite.position, (x + 1, y + 1)) def test_Sprite_area(self): for w in range(0, 200): for h in range(0, 200): sprite = MSprite(w, h) self.assertEqual(sprite.size, (w, h)) self.assertEqual(sprite.area, (0, 0, w, h)) sprite.position = w, h self.assertEqual(sprite.area, (w, h, 2 * w, 2 * h)) def test_SoftwareSprite(self): self.assertRaises(TypeError, sdl2ext.SoftwareSprite, None, None) self.assertRaises(TypeError, sdl2ext.SoftwareSprite, None, True) self.assertRaises(TypeError, sdl2ext.SoftwareSprite, None, False) sf = SDL_CreateRGBSurface(0, 10, 10, 32, 0, 0, 0, 0) sprite = sdl2ext.SoftwareSprite(sf.contents, False) # TODO: the following assert fails... # self.assertEqual(sprite.surface, sf.contents) self.assertFalse(sprite.free) sprite = sdl2ext.SoftwareSprite(sf.contents, True) # TODO: the following assert fails... # self.assertEqual(sprite.surface, sf.contents) self.assertTrue(sprite.free) def test_SoftwareSprite_repr(self): sf = SDL_CreateRGBSurface(0, 10, 10, 32, 0, 0, 0, 0) sprite = sdl2ext.SoftwareSprite(sf.contents, True) self.assertEqual(repr(sprite), "SoftwareSprite(size=(10, 10), bpp=32)") def test_SoftwareSprite_position_xy(self): sf = SDL_CreateRGBSurface(0, 10, 10, 32, 0, 0, 0, 0) sprite = sdl2ext.SoftwareSprite(sf.contents, True) self.assertIsInstance(sprite, sdl2ext.SoftwareSprite) self.assertEqual(sprite.position, (0, 0)) positions = [(x, y) for x in range(-50, 50) for y in range(-50, 50)] for x, y in positions: sprite.position = x, y self.assertEqual(sprite.position, (x, y)) sprite.x = x + 1 sprite.y = y + 1 self.assertEqual(sprite.position, (x + 1, y + 1)) def test_SoftwareSprite_size(self): for w in range(0, 200): for h in range(0, 200): sf = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0) sprite = sdl2ext.SoftwareSprite(sf.contents, True) self.assertIsInstance(sprite, sdl2ext.SoftwareSprite) self.assertEqual(sprite.size, (w, h)) def test_SoftwareSprite_area(self): sf = SDL_CreateRGBSurface(0, 10, 10, 32, 0, 0, 0, 0) sprite = sdl2ext.SoftwareSprite(sf.contents, True) self.assertEqual(sprite.area, (0, 0, 10, 10)) def setarea(s, v): s.area = v self.assertRaises(AttributeError, setarea, sprite, (1, 2, 3, 4)) sprite.position = 7, 3 self.assertEqual(sprite.area, (7, 3, 17, 13)) sprite.position = -22, 99 self.assertEqual(sprite.area, (-22, 99, -12, 109)) def test_TextureSprite(self): window = POINTER(SDL_Window)() renderer = POINTER(SDL_Renderer)() SDL_CreateWindowAndRenderer(10, 10, SDL_WINDOW_HIDDEN, byref(window), byref(renderer)) tex = SDL_CreateTexture(renderer, 0, 0, 10, 10) self.assertIsInstance(tex.contents, SDL_Texture) sprite = sdl2ext.TextureSprite(tex.contents) self.assertIsInstance(sprite, sdl2ext.TextureSprite) SDL_DestroyRenderer(renderer) SDL_DestroyWindow(window) def test_TextureSprite_position_xy(self): window = POINTER(SDL_Window)() renderer = POINTER(SDL_Renderer)() SDL_CreateWindowAndRenderer(10, 10, SDL_WINDOW_HIDDEN, byref(window), byref(renderer)) tex = SDL_CreateTexture(renderer, 0, 0, 10, 10) self.assertIsInstance(tex.contents, SDL_Texture) sprite = sdl2ext.TextureSprite(tex.contents) self.assertIsInstance(sprite, sdl2ext.TextureSprite) self.assertEqual(sprite.position, (0, 0)) positions = [(x, y) for x in range(-50, 50) for y in range(-50, 50)] for x, y in positions: sprite.position = x, y self.assertEqual(sprite.position, (x, y)) sprite.x = x + 1 sprite.y = y + 1 self.assertEqual(sprite.position, (x + 1, y + 1)) SDL_DestroyRenderer(renderer) SDL_DestroyWindow(window) def test_TextureSprite_size(self): window = POINTER(SDL_Window)() renderer = POINTER(SDL_Renderer)() SDL_CreateWindowAndRenderer(10, 10, SDL_WINDOW_HIDDEN, byref(window), byref(renderer)) for w in range(1, 200): for h in range(1, 200): tex = SDL_CreateTexture(renderer, 0, 0, w, h) self.assertIsInstance(tex.contents, SDL_Texture) sprite = sdl2ext.TextureSprite(tex.contents) self.assertIsInstance(sprite, sdl2ext.TextureSprite) self.assertEqual(sprite.size, (w, h)) del sprite SDL_DestroyRenderer(renderer) SDL_DestroyWindow(window) def test_TextureSprite_area(self): window = POINTER(SDL_Window)() renderer = POINTER(SDL_Renderer)() SDL_CreateWindowAndRenderer(10, 10, SDL_WINDOW_HIDDEN, byref(window), byref(renderer)) tex = SDL_CreateTexture(renderer, 0, 0, 10, 20) self.assertIsInstance(tex.contents, SDL_Texture) sprite = sdl2ext.TextureSprite(tex.contents) self.assertIsInstance(sprite, sdl2ext.TextureSprite) self.assertEqual(sprite.area, (0, 0, 10, 20)) def setarea(s, v): s.area = v self.assertRaises(AttributeError, setarea, sprite, (1, 2, 3, 4)) sprite.position = 7, 3 self.assertEqual(sprite.area, (7, 3, 17, 23)) sprite.position = -22, 99 self.assertEqual(sprite.area, (-22, 99, -12, 119)) SDL_DestroyRenderer(renderer) SDL_DestroyWindow(window) def test_Renderer(self): sf = SDL_CreateRGBSurface(0, 10, 10, 32, 0, 0, 0, 0).contents renderer = sdl2ext.Renderer(sf) self.assertEqual(renderer.rendertarget, sf) self.assertIsInstance(renderer.renderer.contents, SDL_Renderer) del renderer sprite = sdl2ext.SoftwareSprite(sf, True) renderer = sdl2ext.Renderer(sprite) self.assertEqual(renderer.rendertarget, sprite.surface) self.assertEqual(renderer.rendertarget, sf) self.assertIsInstance(renderer.renderer.contents, SDL_Renderer) del renderer window = sdl2ext.Window("Test", size=(1, 1)) renderer = sdl2ext.Renderer(window) self.assertEqual(renderer.rendertarget, window.window) self.assertIsInstance(renderer.renderer.contents, SDL_Renderer) del renderer sdlwindow = window.window renderer = sdl2ext.Renderer(sdlwindow) self.assertEqual(renderer.rendertarget, sdlwindow) self.assertEqual(renderer.rendertarget, window.window) self.assertIsInstance(renderer.renderer.contents, SDL_Renderer) del renderer del window self.assertRaises(TypeError, sdl2ext.Renderer, None) self.assertRaises(TypeError, sdl2ext.Renderer, 1234) self.assertRaises(TypeError, sdl2ext.Renderer, "test") def test_Renderer_color(self): sf = SDL_CreateRGBSurface(0, 10, 10, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF) renderer = sdl2ext.Renderer(sf.contents) self.assertIsInstance(renderer.color, sdl2ext.Color) self.assertEqual(renderer.color, sdl2ext.Color(0, 0, 0 ,0)) renderer.color = 0x00FF0000 self.assertEqual(renderer.color, sdl2ext.Color(0xFF, 0, 0, 0)) renderer.clear() view = sdl2ext.PixelView(sf.contents) self.check_areas(view, 10, 10, [[0, 0, 10, 10]], 0xFF000000, (0x0,)) del view renderer.color = 0xAABBCCDD self.assertEqual(renderer.color, sdl2ext.Color(0xBB, 0xCC, 0xDD, 0xAA)) renderer.clear() view = sdl2ext.PixelView(sf.contents) self.check_areas(view, 10, 10, [[0, 0, 10, 10]], 0xBBCCDDAA, (0x0,)) del view del renderer SDL_FreeSurface(sf) @unittest.skip("not implemented") def test_Renderer_blendmode(self): pass def test_Renderer_clear(self): sf = SDL_CreateRGBSurface(0, 10, 10, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF) renderer = sdl2ext.Renderer(sf.contents) self.assertIsInstance(renderer.color, sdl2ext.Color) self.assertEqual(renderer.color, sdl2ext.Color(0, 0, 0 ,0)) renderer.color = 0x00FF0000 self.assertEqual(renderer.color, sdl2ext.Color(0xFF, 0, 0, 0)) renderer.clear() view = sdl2ext.PixelView(sf.contents) self.check_areas(view, 10, 10, [[0, 0, 10, 10]], 0xFF000000, (0x0,)) del view renderer.clear(0xAABBCCDD) self.assertEqual(renderer.color, sdl2ext.Color(0xFF, 0, 0, 0)) view = sdl2ext.PixelView(sf.contents) self.check_areas(view, 10, 10, [[0, 0, 10, 10]], 0xBBCCDDAA, (0x0,)) del view del renderer SDL_FreeSurface(sf) @unittest.skipIf(_ISPYPY, "PyPy's ctypes can't do byref(value, offset)") def test_Renderer_copy(self): surface = SDL_CreateRGBSurface(0, 128, 128, 32, 0, 0, 0, 0).contents sdl2ext.fill(surface, 0x0) renderer = sdl2ext.Renderer(surface) factory = sdl2ext.SpriteFactory(sdl2ext.TEXTURE, renderer=renderer) w, h = 32, 32 sp = factory.from_color(0xFF0000, (w, h)) sp.x, sp.y = 40, 50 renderer.copy(sp, (0, 0, w, h), (sp.x, sp.y, w, h)) view = sdl2ext.PixelView(surface) self.check_pixels(view, 128, 128, sp, 0xFF0000, (0x0,)) del view @unittest.skipIf(_ISPYPY, "PyPy's ctypes can't do byref(value, offset)") def test_Renderer_draw_line(self): surface = SDL_CreateRGBSurface(0, 128, 128, 32, 0, 0, 0, 0).contents sdl2ext.fill(surface, 0x0) renderer = sdl2ext.Renderer(surface) renderer.draw_line((20, 10, 20, 86), 0x0000FF) view = sdl2ext.PixelView(surface) self.check_lines(view, 128, 128, [((20, 10), (20, 86))], 0x0000FF, (0x0,)) del view @unittest.skip("not implemented") def test_Renderer_draw_point(self): pass @unittest.skipIf(_ISPYPY, "PyPy's ctypes can't do byref(value, offset)") def test_Renderer_draw_rect(self): surface = SDL_CreateRGBSurface(0, 128, 128, 32, 0, 0, 0, 0).contents sdl2ext.fill(surface, 0x0) renderer = sdl2ext.Renderer(surface) renderer.draw_rect((40, 50, 32, 32), 0x0000FF) view = sdl2ext.PixelView(surface) self.check_lines(view, 128, 128, [((40, 50), (71, 50)), ((40, 50), (40, 81)), ((40, 81), (71, 81)), ((71, 50), (71, 81))], 0x0000FF, (0x0,)) del view sdl2ext.fill(surface, 0x0) renderer.draw_rect([(5, 5, 10, 10), (20, 15, 8, 10)], 0x0000FF) view = sdl2ext.PixelView(surface) self.check_lines(view, 128, 128, [((5, 5), (14, 5)), ((5, 5), (5, 14)), ((5, 14), (14, 14)), ((14, 5), (14, 14)), ((20, 15), (27, 15)), ((20, 15), (20, 24)), ((20, 24), (27, 24)), ((27, 15), (27, 24))], 0x0000FF, (0x0,)) del view @unittest.skipIf(_ISPYPY, "PyPy's ctypes can't do byref(value, offset)") def test_Renderer_fill(self): surface = SDL_CreateRGBSurface(0, 128, 128, 32, 0, 0, 0, 0).contents sdl2ext.fill(surface, 0x0) renderer = sdl2ext.Renderer(surface) factory = sdl2ext.SpriteFactory(sdl2ext.TEXTURE, renderer=renderer) w, h = 32, 32 sp = factory.from_color(0xFF0000, (w, h)) sp.x, sp.y = 40, 50 renderer.fill((sp.x, sp.y, w, h), 0x0000FF) view = sdl2ext.PixelView(surface) self.check_pixels(view, 128, 128, sp, 0x0000FF, (0x0,)) del view sdl2ext.fill(surface, 0x0) renderer.fill([(5, 5, 10, 10), (20, 15, 8, 10)], 0x0000FF) view = sdl2ext.PixelView(surface) self.check_areas(view, 128, 128, [(5, 5, 10, 10), (20, 15, 8, 10)], 0x0000FF, (0x0,)) del view if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_test.py0000644000000000000000000000323212260256443014253 0ustar import sys import unittest from .. import ext as sdl2ext from .. import SDL_WasInit, SDL_INIT_VIDEO, SDL_FlushEvent, SDL_USEREVENT, \ SDL_FIRSTEVENT, SDL_LASTEVENT, SDL_Event, SDL_UserEvent, SDL_PushEvent class SDL2ExtTest(unittest.TestCase): __tags__ = ["sdl", "sdl2ext"] def test_init_quit(self): sdl2ext.init() self.assertEqual(SDL_WasInit(SDL_INIT_VIDEO), SDL_INIT_VIDEO) sdl2ext.quit() self.assertNotEqual(SDL_WasInit(SDL_INIT_VIDEO), SDL_INIT_VIDEO) sdl2ext.init() sdl2ext.init() sdl2ext.init() self.assertEqual(SDL_WasInit(SDL_INIT_VIDEO), SDL_INIT_VIDEO) sdl2ext.quit() self.assertNotEqual(SDL_WasInit(SDL_INIT_VIDEO), SDL_INIT_VIDEO) sdl2ext.quit() sdl2ext.quit() sdl2ext.quit() self.assertNotEqual(SDL_WasInit(SDL_INIT_VIDEO), SDL_INIT_VIDEO) @unittest.skip("not implemented") def test_get_events(self): pass def test_get_events_issue_6(self): sdl2ext.init() SDL_FlushEvent(SDL_FIRSTEVENT, SDL_LASTEVENT) for x in range(12): event = SDL_Event() event.type = SDL_USEREVENT + x event.user = SDL_UserEvent(type=event.type, timestamp=0, windowID=0, code=0) SDL_PushEvent(event) results = sdl2ext.get_events() for idx, r in enumerate(results): self.assertEqual(idx, r.type - SDL_USEREVENT) def test_TestEventProcessor(self): proc = sdl2ext.TestEventProcessor() self.assertIsInstance(proc, sdl2ext.TestEventProcessor) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl2ext_window_test.py0000644000000000000000000000633312260256443015647 0ustar import sys import unittest from .. import ext as sdl2ext from .. import surface, video from .util.testutils import interactive, doprint class SDL2ExtWindowTest(unittest.TestCase): __tags__ = ["sdl", "sdl2ext"] def setUp(self): sdl2ext.init() def tearDown(self): sdl2ext.quit() def test_Window(self): flags = video.SDL_WINDOW_BORDERLESS sizes = ((1, 1), (10, 10), (10, 20), (200, 17), (640, 480), (800, 600)) for w, h in sizes: window = sdl2ext.Window("Window", size=(w, h), flags=flags) self.assertEqual(window.size, (w, h)) #self.assertRaises(TypeError, video.Window, None, None, None, None) #self.assertRaises(TypeError, video.Window, None, None, None) #self.assertRaises(TypeError, video.Window, None, None) self.assertRaises(TypeError, sdl2ext.Window, "Test", None, None, None) self.assertRaises(TypeError, sdl2ext.Window, "Test", None, None) self.assertRaises(TypeError, sdl2ext.Window, "Test", None) def test_Window_title(self): window = sdl2ext.Window("Window", size=(10, 10)) self.assertEqual(window.title, "Window") window.title = "Test1234" self.assertEqual(window.title, "Test1234") #window.title = None #self.assertEqual(window.title, "None") #window.title = 1234 #self.assertEqual(window.title, "1234") @interactive("Was the window shown?") def test_Window_show(self): window = sdl2ext.Window("Test Show Window", size=(200, 200)) window.show() doprint("""Please check, if a window with the title 'Test Show Window' is shown""") @interactive("Did the window vanish from your sight and pop up again?") def test_Window_hide(self): window = sdl2ext.Window("Test Hide Window", size=(200, 200)) window.show() doprint("""Please check, if a window with the title 'Test Hide Window' is shown""") window.hide() doprint("Please check, that the window is not shown anymore") window.show() doprint("Please check, if the window is shown again") @interactive("Was the window maximized?") def test_Window_maximize(self): window = sdl2ext.Window("Test Maximize Window", size=(200, 200), flags=video.SDL_WINDOW_RESIZABLE) window.show() doprint("""Please check, that a window with the title 'Test Maximize Window' is shown""") window.maximize() doprint("Please check, if the window was maximized properly") @interactive("Was the window minimized?") def test_Window_minimize(self): window = sdl2ext.Window("Test Minimize Window", size=(200, 200)) window.show() doprint("""Please check, that a window with the title 'Test Minimize Window' is shown""") window.minimize() doprint("Please check, if the window was minimized properly") @unittest.skip("not implemented") def test_Window_refresh(self): pass def test_Window_get_surface(self): window = sdl2ext.Window("Surface", size=(200, 200)) sf = window.get_surface() self.assertIsInstance(sf, surface.SDL_Surface) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdl_test.py0000644000000000000000000000357012260256443013455 0ustar import sys import unittest from .. import SDL_Init, SDL_WasInit, SDL_InitSubSystem, SDL_QuitSubSystem, \ SDL_Quit, SDL_INIT_AUDIO, SDL_INIT_EVERYTHING, SDL_INIT_GAMECONTROLLER, \ SDL_INIT_HAPTIC, SDL_INIT_JOYSTICK, SDL_INIT_NOPARACHUTE, SDL_INIT_TIMER, \ SDL_INIT_VIDEO, SDL_GetError class SDLTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): SDL_Init(0) def tearDown(self): SDL_Quit() def test_SDL_INIT_TIMER(self): ret = SDL_Init(SDL_INIT_TIMER) self.assertEqual(ret, 0, SDL_GetError()) ret = SDL_WasInit(SDL_INIT_TIMER) self.assertEqual(ret, SDL_INIT_TIMER) SDL_QuitSubSystem(SDL_INIT_TIMER) def test_SDL_INIT_AUDIO(self): ret = SDL_Init(SDL_INIT_AUDIO) self.assertEqual(ret, 0, SDL_GetError()) ret = SDL_WasInit(SDL_INIT_AUDIO) self.assertEqual(ret, SDL_INIT_AUDIO) SDL_QuitSubSystem(SDL_INIT_AUDIO) def test_SDL_INIT_VIDEO(self): ret = SDL_Init(SDL_INIT_VIDEO) self.assertEqual(ret, 0, SDL_GetError()) ret = SDL_WasInit(SDL_INIT_VIDEO) self.assertEqual(ret, SDL_INIT_VIDEO) SDL_QuitSubSystem(SDL_INIT_VIDEO) def test_SDL_INIT_JOYSTICK(self): ret = SDL_Init(SDL_INIT_JOYSTICK) self.assertEqual(ret, 0, SDL_GetError()) ret = SDL_WasInit(SDL_INIT_JOYSTICK) self.assertEqual(ret, SDL_INIT_JOYSTICK) SDL_QuitSubSystem(SDL_INIT_JOYSTICK) @unittest.skipIf(sys.platform.startswith("freebsd"), "FreeBSD des not support haptic input yet") def test_SDL_INIT_HAPTIC(self): ret = SDL_Init(SDL_INIT_HAPTIC) self.assertEqual(ret, 0, SDL_GetError()) ret = SDL_WasInit(SDL_INIT_HAPTIC) self.assertEqual(ret, SDL_INIT_HAPTIC) SDL_QuitSubSystem(SDL_INIT_HAPTIC) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdlgfx_test.py0000644000000000000000000001471312260256443014163 0ustar import os import sys import unittest from .. import SDL_Init, SDL_Quit, sdlgfx class SDLTTFTest(unittest.TestCase): __tags__ = ["sdl", "sdlgfx"] def setUp(self): SDL_Init(0) def tearDown(self): SDL_Quit() @unittest.skip("not implemented") def test_FPSManager(self): pass @unittest.skip("not implemented") def test_SDL_initFramerate(self): pass @unittest.skip("not implemented") def test_SDL_getFramerate(self): pass @unittest.skip("not implemented") def test_SDL_setFramerate(self): pass @unittest.skip("not implemented") def test_SDL_getFramecount(self): pass @unittest.skip("not implemented") def test_SDL_framerateDelay(self): pass @unittest.skip("not implemented") def test_pixelColor(self): pass @unittest.skip("not implemented") def test_pixelRGBA(self): pass @unittest.skip("not implemented") def test_hlineColor(self): pass @unittest.skip("not implemented") def test_hlineRGBA(self): pass @unittest.skip("not implemented") def test_vlineColor(self): pass @unittest.skip("not implemented") def test_vlineRGBA(self): pass @unittest.skip("not implemented") def test_rectangleColor(self): pass @unittest.skip("not implemented") def test_rectangleRGBA(self): pass @unittest.skip("not implemented") def test_roundedRectangleColor(self): pass @unittest.skip("not implemented") def test_roundedRectangleRGBA(self): pass @unittest.skip("not implemented") def test_boxColor(self): pass @unittest.skip("not implemented") def test_boxRGBA(self): pass @unittest.skip("not implemented") def test_roundedBoxColor(self): pass @unittest.skip("not implemented") def test_roundedBoxRGBA(self): pass @unittest.skip("not implemented") def test_lineColor(self): pass @unittest.skip("not implemented") def test_lineRGBA(self): pass @unittest.skip("not implemented") def test_aalineColor(self): pass @unittest.skip("not implemented") def test_aalineRGBA(self): pass @unittest.skip("not implemented") def test_thickLineColor(self): pass @unittest.skip("not implemented") def test_thickLineRGBA(self): pass @unittest.skip("not implemented") def test_circleColor(self): pass @unittest.skip("not implemented") def test_circleRGBA(self): pass @unittest.skip("not implemented") def test_arcColor(self): pass @unittest.skip("not implemented") def test_arcRGBA(self): pass @unittest.skip("not implemented") def test_aacircleColor(self): pass @unittest.skip("not implemented") def test_aacircleRGBA(self): pass @unittest.skip("not implemented") def test_filledCircleColor(self): pass @unittest.skip("not implemented") def test_filledCircleRGBA(self): pass @unittest.skip("not implemented") def test_ellipseColor(self): pass @unittest.skip("not implemented") def test_ellipseRGBA(self): pass @unittest.skip("not implemented") def test_aaellipseColor(self): pass @unittest.skip("not implemented") def test_aaellipseRGBA(self): pass @unittest.skip("not implemented") def test_filledEllipseColor(self): pass @unittest.skip("not implemented") def test_filledEllipseRGBA(self): pass @unittest.skip("not implemented") def test_pieColor(self): pass @unittest.skip("not implemented") def test_pieRGBA(self): pass @unittest.skip("not implemented") def test_filledPieColor(self): pass @unittest.skip("not implemented") def test_filledPieRGBA(self): pass @unittest.skip("not implemented") def test_trigonColor(self): pass @unittest.skip("not implemented") def test_trigonRGBA(self): pass @unittest.skip("not implemented") def test_aatrigonColor(self): pass @unittest.skip("not implemented") def test_aatrigonRGBA(self): pass @unittest.skip("not implemented") def test_filledTrigonColor(self): pass @unittest.skip("not implemented") def test_filledTrigonRGBA(self): pass @unittest.skip("not implemented") def test_polygonColor(self): pass @unittest.skip("not implemented") def test_polygonRGBA(self): pass @unittest.skip("not implemented") def test_aapolygonColor(self): pass @unittest.skip("not implemented") def test_aapolygonRGBA(self): pass @unittest.skip("not implemented") def test_filledPolygonColor(self): pass @unittest.skip("not implemented") def test_filledPolygonRGBA(self): pass @unittest.skip("not implemented") def test_texturedPolygon(self): pass @unittest.skip("not implemented") def test_bezierColor(self): pass @unittest.skip("not implemented") def test_bezierRGBA(self): pass @unittest.skip("not implemented") def test_gfxPrimitivesSetFont(self): pass @unittest.skip("not implemented") def test_gfxPrimitivesSetFontRotation(self): pass @unittest.skip("not implemented") def test_characterColor(self): pass @unittest.skip("not implemented") def test_characterRGBA(self): pass @unittest.skip("not implemented") def test_stringColor(self): pass @unittest.skip("not implemented") def test_stringRGBA(self): pass @unittest.skip("not implemented") def test_rotozoomSurface(self): pass @unittest.skip("not implemented") def test_rotozoomSurfaceXY(self): pass @unittest.skip("not implemented") def test_rotozoomSurfaceSize(self): pass @unittest.skip("not implemented") def test_rotozoomSurfaceSizeXY(self): pass @unittest.skip("not implemented") def test_zoomSurface(self): pass @unittest.skip("not implemented") def test_zoomSurfaceSize(self): pass @unittest.skip("not implemented") def test_shrinkSurface(self): pass @unittest.skip("not implemented") def test_rotateSurface90Degrees(self): pass if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdlimage_test.py0000644000000000000000000005312612260256443014462 0ustar import os import sys import ctypes import unittest from .. import SDL_Init, SDL_Quit, version, surface, rwops, render from .. import sdlimage formats = ["bmp", "cur", "gif", "ico", "jpg", "lbm", "pbm", "pcx", "pgm", "png", "pnm", "ppm", "tga", "tif", "webp", "xcf", "xpm", #"xv", ] class SDLImageTest(unittest.TestCase): __tags__ = ["sdl", "sdlimage"] def setUp(self): SDL_Init(0) sdlimage.IMG_Init(sdlimage.IMG_INIT_JPG | sdlimage.IMG_INIT_PNG | sdlimage.IMG_INIT_TIF | sdlimage.IMG_INIT_WEBP) def tearDown(self): SDL_Quit() sdlimage.IMG_Quit() @unittest.skip("not implemented") def test_IMG_InitQuit(self): pass def test_IMG_Linked_Version(self): v = sdlimage.IMG_Linked_Version() self.assertIsInstance(v.contents, version.SDL_version) self.assertEqual(v.contents.major, 2) self.assertEqual(v.contents.minor, 0) self.assertGreaterEqual(v.contents.patch, 0) def test_IMG_Load(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) sf = sdlimage.IMG_Load(filename.encode("utf-8")) self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_Load_RW(self): fname = "surfacetest.%s" for fmt in formats: if fmt == "tga": # SDL_image does not support loading TGA via IMG_Load_RW() continue filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") sf = sdlimage.IMG_Load_RW(rwops.rw_from_object(fp), False) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) def test_IMG_LoadTexture(self): sf = surface.SDL_CreateRGBSurface(0, 10, 10, 32, 0, 0, 0, 0) rd = render.SDL_CreateSoftwareRenderer(sf) fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) tex = sdlimage.IMG_LoadTexture(rd, filename.encode("utf-8")) self.assertIsInstance(tex.contents, render.SDL_Texture) render.SDL_DestroyTexture(tex) #self.assertRaises(sdl.SDLError, sdlimage.load_texture, rd, # RESOURCES.get_path("rwopstest.txt")) #self.assertRaises(sdl.SDLError, sdlimage.load_texture, rd, None) #self.assertRaises(sdl.SDLError, sdlimage.load_texture, rd, 1234) #self.assertRaises((AttributeError, TypeError), # sdlimage.load_texture, None, # RESOURCES.get_path("surfacetest.bmp")) #self.assertRaises((AttributeError, TypeError), # sdlimage.load_texture, "Test", # RESOURCES.get_path("surfacetest.bmp")) #self.assertRaises((AttributeError, TypeError), # sdlimage.load_texture, 1234, # RESOURCES.get_path("surfacetest.bmp")) render.SDL_DestroyRenderer(rd) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadTexture_RW(self): sf = surface.SDL_CreateRGBSurface(0, 10, 10, 32, 0, 0, 0, 0) rd = render.SDL_CreateSoftwareRenderer(sf) fname = "surfacetest.%s" for fmt in formats: if fmt == "tga": # SDL_image does not support loading TGA via # IMG_LoadTexture_RW() continue filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") tex = sdlimage.IMG_LoadTexture_RW(rd, rwops.rw_from_object(fp), 0) fp.close() self.assertIsInstance(tex.contents, render.SDL_Texture) render.SDL_DestroyTexture(tex) render.SDL_DestroyRenderer(rd) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadTextureTyped_RW(self): sf = surface.SDL_CreateRGBSurface(0, 10, 10, 32, 0, 0, 0, 0) rd = render.SDL_CreateSoftwareRenderer(sf) fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") fmtx = fmt.upper().encode("utf-8") rw = rwops.rw_from_object(fp) tex = sdlimage.IMG_LoadTextureTyped_RW(rd, rw, 0, fmtx) fp.close() self.assertIsInstance(tex.contents, render.SDL_Texture) render.SDL_DestroyTexture(tex) render.SDL_DestroyRenderer(rd) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadTyped_RW(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") sf = sdlimage.IMG_LoadTyped_RW(rwops.rw_from_object(fp), False, fmt.upper().encode("utf-8")) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadBMP_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.bmp"), "rb") sf = sdlimage.IMG_LoadBMP_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadCUR_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.cur"), "rb") sf = sdlimage.IMG_LoadCUR_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) pass @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadGIF_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.gif"), "rb") sf = sdlimage.IMG_LoadGIF_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadICO_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.ico"), "rb") sf = sdlimage.IMG_LoadICO_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadJPG_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.jpg"), "rb") sf = sdlimage.IMG_LoadJPG_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadLBM_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.lbm"), "rb") sf = sdlimage.IMG_LoadLBM_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadPCX_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.pcx"), "rb") sf = sdlimage.IMG_LoadPCX_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadPNG_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.png"), "rb") sf = sdlimage.IMG_LoadPNG_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadPNM_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.pnm"), "rb") sf = sdlimage.IMG_LoadPNM_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadTGA_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.tga"), "rb") sf = sdlimage.IMG_LoadTGA_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadTIF_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.tif"), "rb") sf = sdlimage.IMG_LoadTIF_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadWEBP_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.webp"), "rb") sf = sdlimage.IMG_LoadWEBP_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadXCF_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.xcf"), "rb") sf = sdlimage.IMG_LoadXCF_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_LoadXPM_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.xpm"), "rb") sf = sdlimage.IMG_LoadXPM_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skip("not implemented") def test_IMG_LoadXV_RW(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.xv"), "rb") sf = sdlimage.IMG_LoadXV_RW(rwops.rw_from_object(fp)) fp.close() self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_isBMP(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt == "bmp": self.assertTrue(sdlimage.IMG_isBMP(imgrw)) else: self.assertFalse(sdlimage.IMG_isBMP(imgrw)) fp.close() @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_isCUR(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt == "cur": self.assertTrue(sdlimage.IMG_isCUR(imgrw)) else: self.assertFalse(sdlimage.IMG_isCUR(imgrw)) fp.close() @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_isGIF(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt == "gif": self.assertTrue(sdlimage.IMG_isGIF(imgrw)) else: self.assertFalse(sdlimage.IMG_isGIF(imgrw)) fp.close() @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_isICO(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt == "ico": self.assertTrue(sdlimage.IMG_isICO(imgrw)) else: self.assertFalse(sdlimage.IMG_isICO(imgrw)) fp.close() @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_isJPG(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt == "jpg": self.assertTrue(sdlimage.IMG_isJPG(imgrw)) else: self.assertFalse(sdlimage.IMG_isJPG(imgrw)) fp.close() @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_isLBM(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt == "lbm": self.assertTrue(sdlimage.IMG_isLBM(imgrw)) else: self.assertFalse(sdlimage.IMG_isLBM(imgrw)) fp.close() @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_isPCX(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt == "pcx": self.assertTrue(sdlimage.IMG_isPCX(imgrw)) else: self.assertFalse(sdlimage.IMG_isPCX(imgrw)) fp.close() @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_isPNG(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt == "png": self.assertTrue(sdlimage.IMG_isPNG(imgrw)) else: self.assertFalse(sdlimage.IMG_isPNG(imgrw)) fp.close() @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_isPNM(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt in ("pnm", "pbm", "ppm", "pgm"): self.assertTrue(sdlimage.IMG_isPNM(imgrw)) else: self.assertFalse(sdlimage.IMG_isPNM(imgrw)) fp.close() @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_isTIF(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt == "tif": self.assertTrue(sdlimage.IMG_isTIF(imgrw)) else: self.assertFalse(sdlimage.IMG_isTIF(imgrw)) fp.close() @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_isWEBP(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt == "webp": self.assertTrue(sdlimage.IMG_isWEBP(imgrw)) else: self.assertFalse(sdlimage.IMG_isWEBP(imgrw)) fp.close() @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_isXCF(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt == "xcf": self.assertTrue(sdlimage.IMG_isXCF(imgrw)) else: self.assertFalse(sdlimage.IMG_isXCF(imgrw)) fp.close() @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_IMG_isXPM(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt == "xpm": self.assertTrue(sdlimage.IMG_isXPM(imgrw)) else: self.assertFalse(sdlimage.IMG_isXPM(imgrw)) fp.close() @unittest.skip("not implemented") def test_IMG_isXV(self): fname = "surfacetest.%s" for fmt in formats: filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", fname % fmt) fp = open(filename, "rb") imgrw = rwops.rw_from_object(fp) if fmt == "xv": self.assertTrue(sdlimage.IMG_isXV(imgrw)) else: self.assertFalse(sdlimage.IMG_isXV(imgrw)) fp.close() @unittest.skipIf(hasattr(sys, "pypy_version_info"), "PyPy's ctypes fails to pass a correct string array") @unittest.skipIf(sys.platform=="cli", "IronPython can't handle byte() objects") def test_IMG_ReadXPMFromArray(self): fp = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "surfacetest.xpm"), "rb") xpm = b"" fp.readline() # /* XPM */ fp.readline() # static char * surfacetest_xpm[] = { lbuf = fp.readlines() fp.close() for line in lbuf: if line.endswith(b"};"): xpm += line[1:-4] else: xpm += line[1:-3] pxpm = ctypes.c_char_p(xpm) sf = sdlimage.IMG_ReadXPMFromArray(ctypes.byref(pxpm)) self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) @unittest.skip("not implemented") def test_IMG_SavePNG(self): pass @unittest.skip("not implemented") def test_IMG_SavePNG_RW(self): pass if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdlmixer_test.py0000644000000000000000000000117012260256443014514 0ustar import os import sys import unittest import ctypes from .. import SDL_Init, SDL_Quit, sdlmixer, rwops, version class SDLMixerTest(unittest.TestCase): __tags__ = ["sdl", "sdlmixer"] def setUp(self): sdlmixer.Mix_Init(0) def tearDown(self): sdlmixer.Mix_Quit() def test_Mix_Linked_Version(self): v = sdlmixer.Mix_Linked_Version() self.assertIsInstance(v.contents, version.SDL_version) self.assertEqual(v.contents.major, 2) self.assertEqual(v.contents.minor, 0) self.assertEqual(v.contents.patch, 0) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/sdlttf_test.py0000644000000000000000000003503412260256443014173 0ustar import os import sys import unittest from .. import SDL_Init, SDL_Quit, sdlttf, rwops fontfile = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "tuffy.ttf").encode("utf-8") class SDLTTFTest(unittest.TestCase): __tags__ = ["sdl", "sdlttf"] def setUp(self): SDL_Init(0) sdlttf.TTF_Init() def tearDown(self): SDL_Quit() sdlttf.TTF_Quit() def test_TTF_Font(self): font = sdlttf.TTF_Font() self.assertIsInstance(font, sdlttf.TTF_Font) def test_TTF_InitQuit(self): sdlttf.TTF_Init() sdlttf.TTF_Init() sdlttf.TTF_Init() sdlttf.TTF_Quit() sdlttf.TTF_Quit() sdlttf.TTF_Init() def test_TTF_OpenCloseFont(self): for x in range(-10, 15): font = sdlttf.TTF_OpenFont(fontfile, x) self.assertIsInstance(font.contents, sdlttf.TTF_Font) sdlttf.TTF_CloseFont(font) #self.assertRaises(TypeError, sdlttf.open_font, None, None) #self.assertRaises(TypeError, sdlttf.open_font, filename, None) #self.assertRaises(ValueError, sdlttf.open_font, filename, "abcd") #self.assertRaises(ValueError, sdlttf.open_font, None, "abcd") #self.assertRaises(sdl.SDLError, sdlttf.open_font, "test", 10) def test_TTF_OpenFontIndex(self): for x in range(-10, 15): font = sdlttf.TTF_OpenFontIndex(fontfile, x, 0) self.assertIsInstance(font.contents, sdlttf.TTF_Font) sdlttf.TTF_CloseFont(font) #self.assertRaises(TypeError, sdlttf.open_font_index, None, None, None) #self.assertRaises(TypeError, sdlttf.open_font_index, filename, None, # None) #self.assertRaises(TypeError, sdlttf.open_font_index, filename, 10, # None) #self.assertRaises(TypeError, sdlttf.open_font_index, filename, None,0) #self.assertRaises(TypeError, sdlttf.open_font_index, filename, None,0) #self.assertRaises(ValueError, sdlttf.open_font_index, filename, 10,-2) #self.assertRaises(sdl.SDLError, sdlttf.open_font_index, "test", 10, 0) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_TTF_OpenFontRW(self): fp = open(fontfile, "rb") fontrw = rwops.rw_from_object(fp) for x in range(-10, 15): fp.seek(0) font = sdlttf.TTF_OpenFontRW(fontrw, 0, x) self.assertIsInstance(font.contents, sdlttf.TTF_Font) sdlttf.TTF_CloseFont(font) fp.close() #self.assertRaises(TypeError, sdlttf.open_font_rw, None, False, None) #self.assertRaises((AttributeError, TypeError), # sdlttf.open_font_rw, None, False, 10) #self.assertRaises(TypeError, sdlttf.open_font_rw, fontrw, False, None) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_TTF_OpenFontIndexRW(self): fp = open(fontfile, "rb") fontrw = rwops.rw_from_object(fp) for x in range(-10, 15): fp.seek(0) font = sdlttf.TTF_OpenFontIndexRW(fontrw, 0, x, 0) self.assertIsInstance(font.contents, sdlttf.TTF_Font) sdlttf.TTF_CloseFont(font) fp.close() #self.assertRaises(TypeError, sdlttf.open_font_index_rw, None, False, # None, None) #self.assertRaises(TypeError, sdlttf.open_font_index_rw, None, False, # 10, None) #self.assertRaises(TypeError, sdlttf.open_font_index_rw, None, False, # None, 0) #self.assertRaises(TypeError, sdlttf.open_font_index_rw, fontrw, False, # None, 0) #self.assertRaises(TypeError, sdlttf.open_font_index_rw, fontrw, False, # 10, None) def test_TTF_GetSetFontStyle(self): font = sdlttf.TTF_OpenFont(fontfile, 10) self.assertIsInstance(font.contents, sdlttf.TTF_Font) self.assertEqual(sdlttf.TTF_GetFontStyle(font), sdlttf.TTF_STYLE_NORMAL) sdlttf.TTF_SetFontStyle(font, sdlttf.TTF_STYLE_BOLD) self.assertEqual(sdlttf.TTF_GetFontStyle(font), sdlttf.TTF_STYLE_BOLD) sdlttf.TTF_SetFontStyle(font, sdlttf.TTF_STYLE_BOLD | sdlttf.TTF_STYLE_ITALIC) self.assertEqual(sdlttf.TTF_GetFontStyle(font), sdlttf.TTF_STYLE_BOLD | sdlttf.TTF_STYLE_ITALIC) sdlttf.TTF_SetFontStyle(font, sdlttf.TTF_STYLE_BOLD | sdlttf.TTF_STYLE_UNDERLINE) #self.assertRaises((AttributeError, TypeError), # sdlttf.get_font_style, None) #self.assertRaises((AttributeError, TypeError), # sdlttf.get_font_style, "test") #self.assertRaises((AttributeError, TypeError), # sdlttf.get_font_style, 1234) #self.assertRaises(ArgumentError, sdlttf.set_font_style, font, None) #self.assertRaises((AttributeError, TypeError), # sdlttf.set_font_style, "test", None) #self.assertRaises((AttributeError, TypeError), # sdlttf.set_font_style, 1234, None) #self.assertRaises((AttributeError, TypeError), # sdlttf.set_font_style, "test", 3) #self.assertRaises((AttributeError, TypeError), # sdlttf.set_font_style, 1234, 4) #self.assertRaises(ArgumentError, sdlttf.set_font_style, font, "test") sdlttf.TTF_CloseFont(font) def test_TTF_GetSetFontOutline(self): font = sdlttf.TTF_OpenFont(fontfile, 10) self.assertEqual(sdlttf.TTF_GetFontOutline(font), 0) for x in range(-10, 10): sdlttf.TTF_SetFontOutline(font, x) self.assertEqual(sdlttf.TTF_GetFontOutline(font), x) #self.assertRaises(TypeError, sdlttf.set_font_outline, None, None) #self.assertRaises(TypeError, sdlttf.set_font_outline, font, None) #self.assertRaises(ValueError, sdlttf.set_font_outline, font, "test") #self.assertRaises(ValueError, sdlttf.set_font_outline, None, "test") #self.assertRaises((AttributeError, TypeError), # sdlttf.set_font_outline, None, 123) #self.assertRaises((AttributeError, TypeError), # sdlttf.get_font_outline, None) #self.assertRaises((AttributeError, TypeError), # sdlttf.get_font_outline, None) sdlttf.TTF_CloseFont(font) def test_TTF_GetSetFontHinting(self): font = sdlttf.TTF_OpenFont(fontfile, 10) self.assertEqual(sdlttf.TTF_GetFontHinting(font), sdlttf.TTF_HINTING_NORMAL) for hint in (sdlttf.TTF_HINTING_NORMAL, sdlttf.TTF_HINTING_LIGHT, sdlttf.TTF_HINTING_MONO, sdlttf.TTF_HINTING_NONE): sdlttf.TTF_SetFontHinting(font, hint) self.assertEqual(sdlttf.TTF_GetFontHinting(font), hint) # self.assertRaises((AttributeError, TypeError), # sdlttf.set_font_hinting, None, None) # self.assertRaises(ArgumentError, sdlttf.set_font_hinting, font, None) # self.assertRaises((AttributeError, TypeError), # sdlttf.set_font_hinting, None, 1) # self.assertRaises(ArgumentError, sdlttf.set_font_hinting, font,"test") # self.assertRaises((AttributeError, TypeError), # sdlttf.set_font_hinting, None, "test") # self.assertRaises((AttributeError, TypeError), # sdlttf.get_font_hinting, None) sdlttf.TTF_CloseFont(font) def test_TTF_FontHeight(self): last = cur = 0 for ptsize in range(-10, 10): font = sdlttf.TTF_OpenFont(fontfile, ptsize) cur = sdlttf.TTF_FontHeight(font) self.assertGreaterEqual(cur, last) last = cur sdlttf.TTF_CloseFont(font) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_height, None) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_height, 1234) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_height, "test") def test_TTF_FontAscent(self): last = cur = 0 for ptsize in range(-10, 10): font = sdlttf.TTF_OpenFont(fontfile, ptsize) cur = sdlttf.TTF_FontAscent(font) self.assertGreaterEqual(cur, last) last = cur sdlttf.TTF_CloseFont(font) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_ascent, None) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_ascent, 1234) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_ascent, "test") def test_TTF_FontDescent(self): last = cur = 0 for ptsize in range(-10, 10): font = sdlttf.TTF_OpenFont(fontfile, ptsize) cur = sdlttf.TTF_FontDescent(font) self.assertLessEqual(cur, last) last = cur sdlttf.TTF_CloseFont(font) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_descent, None) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_descent, 1234) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_descent, "test") def test_TTF_FontLineSkip(self): last = cur = 0 for ptsize in range(-10, 10): font = sdlttf.TTF_OpenFont(fontfile, ptsize) cur = sdlttf.TTF_FontLineSkip(font) self.assertGreaterEqual(cur, last) last = cur sdlttf.TTF_CloseFont(font) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_line_skip, None) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_line_skip, 1234) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_line_skip, "test") def test_TTF_GetSetFontKerning(self): font = sdlttf.TTF_OpenFont(fontfile, 10) self.assertEqual(sdlttf.TTF_GetFontKerning(font), 1) sdlttf.TTF_SetFontKerning(font, 0) self.assertEqual(sdlttf.TTF_GetFontKerning(font), 0) sdlttf.TTF_SetFontKerning(font, 1) self.assertEqual(sdlttf.TTF_GetFontKerning(font), 1) sdlttf.TTF_SetFontKerning(font, 0) self.assertEqual(sdlttf.TTF_GetFontKerning(font), 0) # self.assertRaises((AttributeError, TypeError), # sdlttf.get_font_kerning, None) # self.assertRaises((AttributeError, TypeError), # sdlttf.get_font_kerning, "test") # self.assertRaises((AttributeError, TypeError), # sdlttf.get_font_kerning, 1234) # self.assertRaises((AttributeError, TypeError), # sdlttf.set_font_kerning, None, None) # self.assertRaises((AttributeError, TypeError), # sdlttf.set_font_kerning, "test", "test") # self.assertRaises((AttributeError, TypeError), # sdlttf.set_font_kerning, 1234, None) sdlttf.TTF_CloseFont(font) def test_TTF_FontFaces(self): font = sdlttf.TTF_OpenFont(fontfile, 10) self.assertGreaterEqual(sdlttf.TTF_FontFaces(font), 1) # self.assertRaises((AttributeError, TypeError), sdlttf.font_faces,None) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_faces, "test") # self.assertRaises((AttributeError, TypeError), sdlttf.font_faces,1234) sdlttf.TTF_CloseFont(font) def test_TTF_FontFaceIsFixedWidth(self): font = sdlttf.TTF_OpenFont(fontfile, 10) self.assertFalse(sdlttf.TTF_FontFaceIsFixedWidth(font)) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_face_is_fixed_width, None) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_face_is_fixed_width, "test") # self.assertRaises((AttributeError, TypeError), # sdlttf.font_face_is_fixed_width, 1234) sdlttf.TTF_CloseFont(font) def test_TTF_FontFaceFamilyName(self): font = sdlttf.TTF_OpenFont(fontfile, 10) self.assertEqual(sdlttf.TTF_FontFaceFamilyName(font), b"Tuffy") # self.assertRaises((AttributeError, TypeError), # sdlttf.font_face_family_name, None) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_face_family_name, "test") # self.assertRaises((AttributeError, TypeError), # sdlttf.font_face_family_name, 1234) sdlttf.TTF_CloseFont(font) def test_TTF_FontFaceStyleName(self): font = sdlttf.TTF_OpenFont(fontfile, 10) self.assertEqual(sdlttf.TTF_FontFaceStyleName(font), b"Regular") # self.assertRaises((AttributeError, TypeError), # sdlttf.font_face_style_name, None) # self.assertRaises((AttributeError, TypeError), # sdlttf.font_face_style_name, "test") # self.assertRaises((AttributeError, TypeError), # sdlttf.font_face_style_name, 1234) sdlttf.TTF_CloseFont(font) def test_TTF_GlyphIsProvided(self): font = sdlttf.TTF_OpenFont(fontfile, 10) self.assertIsInstance(font.contents, sdlttf.TTF_Font) for ch in range(32, 127): self.assertTrue(sdlttf.TTF_GlyphIsProvided(font, ch)) self.assertFalse(sdlttf.TTF_GlyphIsProvided(font, 0)) self.assertFalse(sdlttf.TTF_GlyphIsProvided(font, 0x0ff9)) # self.assertRaises((AttributeError, TypeError), # sdlttf.glyph_is_provided, None, None) # self.assertRaises((AttributeError, TypeError), # sdlttf.glyph_is_provided, "test", None) # self.assertRaises((AttributeError, TypeError), # sdlttf.glyph_is_provided, "test", 1234) # self.assertRaises((ArgumentError, TypeError), # sdlttf.glyph_is_provided, font, None) # self.assertRaises((AttributeError, TypeError), # sdlttf.glyph_is_provided, font, "test") @unittest.skip("not implemented") def test_TTF_GlyphMetrics(self): pass if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/shape_test.py0000644000000000000000000001052512260256443013771 0ustar import sys import unittest import ctypes from .. import SDL_Init, SDL_Quit, SDL_QuitSubSystem, SDL_INIT_EVERYTHING from .. import video, shape, surface class SDLShapeTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): SDL_Init(SDL_INIT_EVERYTHING) def tearDown(self): SDL_QuitSubSystem(SDL_INIT_EVERYTHING) SDL_Quit() def test_SDL_CreateShapedWindow(self): flags = (video.SDL_WINDOW_HIDDEN,) for flag in flags: window = shape.SDL_CreateShapedWindow(b"Test", 10, 10, 10, 10, flag) self.assertIsInstance(window.contents, video.SDL_Window) video.SDL_DestroyWindow(window) def test_SDL_IsShapedWindow(self): flags = (video.SDL_WINDOW_HIDDEN,) for flag in flags: window = shape.SDL_CreateShapedWindow(b"Test", 10, 10, 10, 10, flag) self.assertIsInstance(window.contents, video.SDL_Window) val = shape.SDL_IsShapedWindow(window) self.assertTrue(val) video.SDL_DestroyWindow(window) window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, flag) self.assertIsInstance(window.contents, video.SDL_Window) val = shape.SDL_IsShapedWindow(window) self.assertFalse(val) video.SDL_DestroyWindow(window) @unittest.skipIf(sys.platform=="cli", "IronPython can't create Union types") def test_SDL_SetWindowShape(self): sf = surface.SDL_CreateRGBSurface(0, 10, 10, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF) mode = shape.SDL_WindowShapeMode() mode.mode = shape.ShapeModeDefault mode.parameters = shape.SDL_WindowShapeParams() mode.parameters.binarizationCutoff = 1 flags = (video.SDL_WINDOW_HIDDEN,) for flag in flags: # TODO: find out, how shaping is supposed to work :-) # window = shape.SDL_CreateShapedWindow(b"Test", 10, 10, 10, 10, # flag) # self.assertIsInstance(window, video.SDL_Window) # self.assertTrue(shape.SDL_IsShapedWindow(window)) # self.assertRaises(TypeError, shape.SDL_SetWindowShape, # None, None, None) # self.assertRaises(TypeError, shape.SDL_SetWindowShape, # window, None, None) # self.assertRaises(TypeError, shape.SDL_SetWindowShape, # window, sf, None) # self.assertRaises(TypeError, shape.SDL_SetWindowShape, # "Test", sf, mode) # self.assertRaises(TypeError, shape.SDL_SetWindowShape, # window, 12345, mode) # self.assertRaises(TypeError, shape.SDL_SetWindowShape, # window, sf, "Test") # shape.SDL_SetWindowShape(window, sf, mode) # wmode = shape.SDL_GetShapedWindowMode(window) # self.assertEqual(wmode.mode, mode.mode) # self.assertEqual(wmode.parameters.binarizationCutoff, # mode.parameters.binarizationCutoff) # video.SDL_DestroyWindow(window) window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, flag) self.assertIsInstance(window.contents, video.SDL_Window) #self.assertRaises(sdl.SDLError, shape.SDL_SetWindowShape, # window, sf, mode) video.SDL_DestroyWindow(window) surface.SDL_FreeSurface(sf) def test_SDL_GetShapedWindowMode(self): flags = (video.SDL_WINDOW_HIDDEN,) for flag in flags: window = shape.SDL_CreateShapedWindow(b"Test", 10, 10, 10, 10, flag) self.assertIsInstance(window.contents, video.SDL_Window) mode = shape.SDL_WindowShapeMode() ret = shape.SDL_GetShapedWindowMode(window, ctypes.byref(mode)) self.assertEqual(ret, 0) video.SDL_DestroyWindow(window) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/surface_test.py0000644000000000000000000007600512260256443014326 0ustar import os import sys import array import unittest from ctypes import c_int, byref, cast, POINTER, c_void_p from ..ext import CTypesView from .. import SDL_Init, SDL_Quit, SDL_INIT_EVERYTHING from ..stdinc import Uint8, Uint32, SDL_TRUE, SDL_FALSE from .. import blendmode, pixels, rect, surface, rwops, error to_ctypes = lambda seq, dtype: (dtype * len(seq))(*seq) alldepths = (1, 4, 8, 12, 15, 16, 24, 32) indexdepths = (1, 4, 8) rgbdepths = (8, 12, 15, 16) rgbadepths = (16, 24, 32) rgba_pixelations_16x16 = ( # 32-bit 16x16 RGBA surface ([x << 24 for x in range(16 * 16)], 32, 16, (0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF), pixels.SDL_PIXELFORMAT_RGBA8888), # 16-bit 16x16 RGBA surface ([x << 8 for x in range(16 * 16)], 16, 16, (0xF000, 0x0F00, 0x00F0, 0x000F), pixels.SDL_PIXELFORMAT_RGB444), ) blitsizes = ((2, 2), (5, 5), (10, 10), (20, 20), (2, 4), (5, 3), (8, 12), (27, 9), ) blitpositions = ( rect.SDL_Rect(0, 0), rect.SDL_Rect(4, 4), rect.SDL_Rect(10, 10), rect.SDL_Rect(15, 15), rect.SDL_Rect(-2, 1), rect.SDL_Rect(3, -4), rect.SDL_Rect(0, 3), rect.SDL_Rect(4, 0), rect.SDL_Rect(12, 6), rect.SDL_Rect(13, 22), ) # TODO: mostly covers positive tests right now - fix this! class SDLSurfaceTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): self.testfile = os.path.join(os.path.dirname (os.path.abspath(__file__)), "resources", "surfacetest.bmp") SDL_Init(SDL_INIT_EVERYTHING) def tearDown(self): SDL_Quit() def test_SDL_Surface(self): sf = surface.SDL_Surface() self.assertIsInstance(sf, surface.SDL_Surface) # TODO: property checks @unittest.skipIf(sys.platform=="cli", "IronPython crashes for unknown reasons") def test_SDL_ConvertPixels(self): for buf, bpp, pitch, masks, fmt in rgba_pixelations_16x16: bytecount = bpp // 8 arflag = None if bpp == 32: arflag = "I" elif bpp == 16: arflag = "H" src = CTypesView(array.array(arflag, buf), bytecount) srcp = cast(src.to_bytes(), POINTER(Uint8)) dst = (Uint8 * len(src))() dstp = cast(dst, POINTER(Uint8)) ret = surface.SDL_ConvertPixels(16, 16, fmt, srcp, 16 * bytecount, fmt, dstp, 16 * bytecount) self.assertEqual(ret, 0) for index, val in enumerate(dst): self.assertEqual(val, src.view[index]) @unittest.skipIf(sys.platform=="cli", "IronPython crashes for unknown reasons") def test_SDL_ConvertSurface(self): for idx in pixels.ALL_PIXELFORMATS: if pixels.SDL_ISPIXELFORMAT_FOURCC(idx): continue pfmt = pixels.SDL_AllocFormat(idx) for fmt in pixels.ALL_PIXELFORMATS: if pixels.SDL_ISPIXELFORMAT_FOURCC(fmt): continue bpp = c_int() rmask, gmask, bmask, amask = Uint32(), Uint32(), Uint32(), Uint32() ret = pixels.SDL_PixelFormatEnumToMasks(fmt, byref(bpp), byref(rmask), byref(gmask), byref(bmask), byref(amask)) self.assertEqual(ret, SDL_TRUE) sf = surface.SDL_CreateRGBSurface(0, 10, 20, bpp, rmask, gmask, bmask, amask) self.assertIsInstance(sf.contents, surface.SDL_Surface) csf = surface.SDL_ConvertSurface(sf, pfmt, 0) self.assertTrue(csf, error.SDL_GetError()) self.assertIsInstance(csf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) surface.SDL_FreeSurface(csf) pixels.SDL_FreeFormat(pfmt) ####################################################################### # sf = surface.create_rgb_surface(10, 10, 32, 0, 0, 0) # self.assertRaises((AttributeError, TypeError), # surface.convert_surface, None, None, None) # self.assertRaises((AttributeError, TypeError), # surface.convert_surface, sf, None, None) # self.assertRaises((AttributeError, TypeError), # surface.convert_surface, sf, "Test", 0) # self.assertRaises((AttributeError, TypeError), # surface.convert_surface, sf, 12345, 0) # self.assertRaises((AttributeError, TypeError), # surface.convert_surface, None, pfmt, 0) # self.assertRaises((AttributeError, TypeError), # surface.convert_surface, "Test", pfmt, 0) # self.assertRaises((AttributeError, TypeError), # surface.convert_surface, 12345, pfmt, 0) # surface.free_surface(sf) ####################################################################### @unittest.skipIf(sys.platform=="cli", "IronPython crashes for unknown reasons") def test_SDL_ConvertSurfaceFormat(self): for pfmt in pixels.ALL_PIXELFORMATS: if pixels.SDL_ISPIXELFORMAT_FOURCC(pfmt): continue for fmt in pixels.ALL_PIXELFORMATS: if pixels.SDL_ISPIXELFORMAT_FOURCC(fmt): continue bpp = c_int() rmask, gmask, bmask, amask = Uint32(), Uint32(), Uint32(), Uint32() ret = pixels.SDL_PixelFormatEnumToMasks(fmt, byref(bpp), byref(rmask), byref(gmask), byref(bmask), byref(amask)) self.assertEqual(ret, SDL_TRUE) sf = surface.SDL_CreateRGBSurface(0, 10, 20, bpp, rmask, gmask, bmask, amask) self.assertIsInstance(sf.contents, surface.SDL_Surface) csf = surface.SDL_ConvertSurfaceFormat(sf, pfmt, 0) self.assertTrue(csf, error.SDL_GetError()) self.assertIsInstance(csf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) surface.SDL_FreeSurface(csf) @unittest.skipIf(sys.platform=="cli", "IronPython crashes for unknown reasons") def test_SDL_CreateRGBSurface(self): for w in range(1, 100, 5): for h in range(1, 100, 5): for bpp in alldepths: sf = surface.SDL_CreateRGBSurface(0, w, h, bpp, 0, 0, 0, 0) self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) bpp = c_int() rmask, gmask, bmask, amask = Uint32(), Uint32(), Uint32(), Uint32() for fmt in pixels.ALL_PIXELFORMATS: if pixels.SDL_ISPIXELFORMAT_FOURCC(fmt): continue for w in range(1, 100, 5): for h in range(1, 100, 5): ret = pixels.SDL_PixelFormatEnumToMasks(fmt, byref(bpp), byref(rmask), byref(gmask), byref(bmask), byref(amask)) self.assertEqual(ret, SDL_TRUE) sf = surface.SDL_CreateRGBSurface(0, 10, 20, bpp, rmask, gmask, bmask, amask) self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) # Broken ones # sizes = [(0, 0), (65536, 65536)] # for (w, h) in sizes: # for bpp in alldepths: # print w, h, bpp # sf = surface.create_rgb_surface(w, h, bpp) # self.assertIsInstance(sf, surface.SDL_Surface) # surface.free_surface(sf) # TODO: raises a SDL Out of memory error, but 65536 works?! # # sf = surface.create_rgb_surface(65535, 65535, 32) # self.assertIsInstance(sf, surface.SDL_Surface) #self.assertRaises(sdl.SDLError, surface.create_rgb_surface, 1, 1, 66) #self.assertRaises(sdl.SDLError, surface.create_rgb_surface, 1, 1, 0) #self.assertRaises(sdl.SDLError, surface.create_rgb_surface, 1, 1, 8, # 0xf0, 0x0f, 0x01, 0x02) #self.assertRaises(sdl.SDLError, surface.create_rgb_surface, 1, 1, 16, # 0xf0, 0x0f, 0x01, 0x02) #self.assertRaises(sdl.SDLError, surface.create_rgb_surface, 1, 1, 24, # 0xf0, 0x0f, 0x01, 0x02) #self.assertRaises(sdl.SDLError, surface.create_rgb_surface, 1, 1, 32, # 0xf0, 0x0f, 0x01, 0x02) @unittest.skipIf(sys.platform=="cli", "IronPython crashes for unknown reasons") def test_SDL_CreateRGBSurfaceFrom(self): for buf, bpp, pitch, masks, fmt in rgba_pixelations_16x16: if bpp == 32: arflag = "I" elif bpp == 16: arflag = "H" bytebuf = CTypesView(array.array(arflag, buf)) bufptr = cast(bytebuf.to_bytes(), POINTER(Uint8)) sf = surface.SDL_CreateRGBSurfaceFrom(bufptr, 16, 16, bpp, pitch, masks[0], masks[1], masks[2], masks[3]) self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_FreeSurface(sf) def test_SDL_FillRect(self): rectlist = (rect.SDL_Rect(0, 0, 0, 0), rect.SDL_Rect(0, 0, 10, 10), rect.SDL_Rect(0, 0, -10, 10), rect.SDL_Rect(0, 0, -10, -10), rect.SDL_Rect(-10, -10, 10, 10), rect.SDL_Rect(10, -10, 10, 10), rect.SDL_Rect(10, 10, 10, 10), ) bpp = c_int() rmask, gmask, bmask, amask = Uint32(), Uint32(), Uint32(), Uint32() for fmt in pixels.ALL_PIXELFORMATS: if pixels.SDL_ISPIXELFORMAT_FOURCC(fmt): continue if pixels.SDL_BITSPERPIXEL(fmt) < 8: continue # Skip < 8bpp, SDL_FillRect does not work on those ret = pixels.SDL_PixelFormatEnumToMasks(fmt, byref(bpp), byref(rmask), byref(gmask), byref(bmask), byref(amask)) self.assertEqual(ret, SDL_TRUE) for w in range(1, 100, 5): for h in range(1, 100, 5): sf = surface.SDL_CreateRGBSurface(0, w, h, bpp, rmask, gmask, bmask, amask) for r in rectlist: # TODO: check for changed pixels ret = surface.SDL_FillRect(sf, r, 0xff00ff00) self.assertEqual(ret, 0) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle array to POINTER conversions") def test_SDL_FillRects(self): rectlist = to_ctypes([rect.SDL_Rect(0, 0, 0, 0), rect.SDL_Rect(0, 0, 10, 10), rect.SDL_Rect(0, 0, -10, 10), rect.SDL_Rect(0, 0, -10, -10), rect.SDL_Rect(-10, -10, 10, 10), rect.SDL_Rect(10, -10, 10, 10), rect.SDL_Rect(10, 10, 10, 10)], rect.SDL_Rect) bpp = c_int() rmask, gmask, bmask, amask = Uint32(), Uint32(), Uint32(), Uint32() for fmt in pixels.ALL_PIXELFORMATS: if pixels.SDL_ISPIXELFORMAT_FOURCC(fmt): continue if pixels.SDL_BITSPERPIXEL(fmt) < 8: continue # Skip < 8bpp, SDL_FillRect does not work on those ret = pixels.SDL_PixelFormatEnumToMasks(fmt, byref(bpp), byref(rmask), byref(gmask), byref(bmask), byref(amask)) self.assertEqual(ret, SDL_TRUE) for w in range(1, 100, 5): for h in range(1, 100, 5): sf = surface.SDL_CreateRGBSurface(0, w, h, bpp, rmask, gmask, bmask, amask) # TODO: check for changed pixels surface.SDL_FillRects(sf, rectlist, 7, 0xff00ff00) surface.SDL_FreeSurface(sf) def test_SDL_FreeSurface(self): # self.assertRaises((AttributeError, TypeError), # surface.SDL_FreeSurface, None) # self.assertRaises((AttributeError, TypeError), # surface.free_surface, "Test") # self.assertRaises((AttributeError, TypeError), # surface.free_surface, 5) formats = (pixels.SDL_PIXELFORMAT_INDEX1LSB, pixels.SDL_PIXELFORMAT_RGB332, pixels.SDL_PIXELFORMAT_RGBA4444, pixels.SDL_PIXELFORMAT_BGR888, pixels.SDL_PIXELFORMAT_ARGB8888, pixels.SDL_PIXELFORMAT_ARGB2101010 ) bpp = c_int() rmask, gmask, bmask, amask = Uint32(), Uint32(), Uint32(), Uint32() for fmt in formats: ret = pixels.SDL_PixelFormatEnumToMasks(fmt, byref(bpp), byref(rmask), byref(gmask), byref(bmask), byref(amask)) self.assertEqual(ret, SDL_TRUE) sf = surface.SDL_CreateRGBSurface(0, 5, 5, bpp, rmask, gmask, bmask, amask) surface.SDL_FreeSurface(sf) def test_SDL_GetSetClipRect(self): rectlist = ((rect.SDL_Rect(0, 0, 0, 0), SDL_FALSE, True), (rect.SDL_Rect(2, 2, 0, 0), SDL_FALSE, False), (rect.SDL_Rect(2, 2, 5, 1), SDL_TRUE, True), (rect.SDL_Rect(6, 5, 10, 3), SDL_TRUE, False), (rect.SDL_Rect(0, 0, 10, 10), SDL_TRUE, True), (rect.SDL_Rect(0, 0, -10, 10), SDL_FALSE, False), (rect.SDL_Rect(0, 0, -10, -10), SDL_FALSE, False), (rect.SDL_Rect(-10, -10, 10, 10), SDL_FALSE, False), (rect.SDL_Rect(10, -10, 10, 10), SDL_FALSE, False), (rect.SDL_Rect(10, 10, 10, 10), SDL_TRUE, False) ) clip = rect.SDL_Rect() sf = surface.SDL_CreateRGBSurface(0, 15, 15, 32, 0, 0, 0, 0) self.assertIsInstance(sf.contents, surface.SDL_Surface) surface.SDL_GetClipRect(sf, byref(clip)) self.assertEqual(clip, rect.SDL_Rect(0, 0, 15, 15)) for r, clipsetval, cmpval in rectlist: retval = surface.SDL_SetClipRect(sf, r) surface.SDL_GetClipRect(sf, byref(clip)) self.assertEqual(retval, clipsetval, "retval: Could not set clip rect %s" % r) self.assertEqual(clip == r, cmpval, "clip: Could not set clip rect %s" % r) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle int type conversions") def test_SDL_GetSetColorKey(self): colorkeys = ((0, 0, 0), (32, 64, 128), (10, 20, 30), (1, 2, 4), (255, 255, 255), (128, 128, 128), (127, 127, 127), ) bpp = c_int() rmask, gmask, bmask, amask = Uint32(), Uint32(), Uint32(), Uint32() for fmt in pixels.ALL_PIXELFORMATS: if pixels.SDL_ISPIXELFORMAT_FOURCC(fmt): continue pformat = pixels.SDL_AllocFormat(fmt) self.assertIsInstance(pformat.contents, pixels.SDL_PixelFormat) ret = pixels.SDL_PixelFormatEnumToMasks(fmt, byref(bpp), byref(rmask), byref(gmask), byref(bmask), byref(amask)) self.assertEqual(ret, SDL_TRUE) sf = surface.SDL_CreateRGBSurface(0, 10, 10, bpp, rmask, gmask, bmask, amask) for r, g, b in colorkeys: key = pixels.SDL_MapRGB(pformat, r, g, b) surface.SDL_SetColorKey(sf, 1, key) skey = Uint32() ret = surface.SDL_GetColorKey(sf, byref(skey)) self.assertEqual(ret, 0) self.assertEqual(skey.value, key, "Could not set color key (%d, %d, %d)" % (r, g, b)) pixels.SDL_FreeFormat(pformat) surface.SDL_FreeSurface(sf) def test_SDL_GetSetSurfaceAlphaMod(self): bpp = c_int() rmask, gmask, bmask, amask = Uint32(), Uint32(), Uint32(), Uint32() for fmt in pixels.ALL_PIXELFORMATS: if pixels.SDL_ISPIXELFORMAT_FOURCC(fmt): continue ret = pixels.SDL_PixelFormatEnumToMasks(fmt, byref(bpp), byref(rmask), byref(gmask), byref(bmask), byref(amask)) self.assertEqual(ret, SDL_TRUE) sf = surface.SDL_CreateRGBSurface(0, 10, 10, bpp, rmask, gmask, bmask, amask) salpha = Uint8() ret = surface.SDL_GetSurfaceAlphaMod(sf, byref(salpha)) self.assertEqual(ret, 0) self.assertEqual(salpha.value, 255) for alpha in range(0, 255): ret = surface.SDL_SetSurfaceAlphaMod(sf, alpha) self.assertEqual(ret, 0) ret = surface.SDL_GetSurfaceAlphaMod(sf, byref(salpha)) self.assertEqual(ret, 0) self.assertEqual(salpha.value, alpha) surface.SDL_FreeSurface(sf) def test_SDL_GetSetSurfaceBlendMode(self): modes = (blendmode.SDL_BLENDMODE_NONE, blendmode.SDL_BLENDMODE_BLEND, blendmode.SDL_BLENDMODE_ADD, blendmode.SDL_BLENDMODE_MOD ) bpp = c_int() rmask, gmask, bmask, amask = Uint32(), Uint32(), Uint32(), Uint32() for fmt in pixels.ALL_PIXELFORMATS: if pixels.SDL_ISPIXELFORMAT_FOURCC(fmt): continue ret = pixels.SDL_PixelFormatEnumToMasks(fmt, byref(bpp), byref(rmask), byref(gmask), byref(bmask), byref(amask)) self.assertEqual(ret, SDL_TRUE) sf = surface.SDL_CreateRGBSurface(0, 10, 10, bpp, rmask, gmask, bmask, amask) for mode in modes: smode = blendmode.SDL_BlendMode() ret = surface.SDL_SetSurfaceBlendMode(sf, mode) self.assertEqual(ret, 0) surface.SDL_GetSurfaceBlendMode(sf, byref(smode)) self.assertEqual(smode.value, mode) surface.SDL_FreeSurface(sf) def test_SDL_GetSetSurfaceColorMod(self): colormods = ((0, 0, 0), (32, 64, 128), (10, 20, 30), (1, 2, 4), (255, 255, 255), (128, 128, 128), (127, 127, 127), ) bpp = c_int() rmask, gmask, bmask, amask = Uint32(), Uint32(), Uint32(), Uint32() for fmt in pixels.ALL_PIXELFORMATS: if pixels.SDL_ISPIXELFORMAT_FOURCC(fmt): continue ret = pixels.SDL_PixelFormatEnumToMasks(fmt, byref(bpp), byref(rmask), byref(gmask), byref(bmask), byref(amask)) self.assertEqual(ret, SDL_TRUE) sf = surface.SDL_CreateRGBSurface(0, 10, 10, bpp, rmask, gmask, bmask, amask) for r, g, b in colormods: sr, sg, sb = Uint8(), Uint8(), Uint8() surface.SDL_SetSurfaceColorMod(sf, r, g, b) ret = surface.SDL_GetSurfaceColorMod(sf, byref(sr), byref(sg), byref(sb)) self.assertEqual(ret, 0) self.assertEqual((sr.value, sg.value, sb.value), (r, g, b)) surface.SDL_FreeSurface(sf) def test_SDL_LockUnlockMUSTLOCKSurface(self): bpp = c_int() rmask, gmask, bmask, amask = Uint32(), Uint32(), Uint32(), Uint32() for fmt in pixels.ALL_PIXELFORMATS: if pixels.SDL_ISPIXELFORMAT_FOURCC(fmt): continue ret = pixels.SDL_PixelFormatEnumToMasks(fmt, byref(bpp), byref(rmask), byref(gmask), byref(bmask), byref(amask)) self.assertEqual(ret, SDL_TRUE) sf = surface.SDL_CreateRGBSurface(0, 10, 10, bpp, rmask, gmask, bmask, amask) # TODO: locking seems to be only necessary for RLE surfaces... if surface.SDL_MUSTLOCK(sf.contents): self.assertFalse(sf.contents.locked) surface.SDL_LockSurface(sf) self.assertTrue(sf.contents.locked) surface.SDL_LockSurface(sf) self.assertTrue(sf.contents.locked) surface.SDL_LockSurface(sf) self.assertTrue(sf.contents.locked) surface.SDL_LockSurface(sf) self.assertTrue(sf.contents.locked) surface.SDL_LockSurface(sf) self.assertTrue(sf.contents.locked) surface.SDL_UnlockSurface(sf) self.assertFalse(sf.contents.locked) surface.SDL_FreeSurface(sf) @unittest.skipIf(sys.platform=="cli", "IronPython can't handle array to POINTER conversions") def test_SDL_LowerBlit(self): bpp = 32 w, h = 10, 10 # no alpha to prevent blending masks = (0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000) dest = surface.SDL_CreateRGBSurface(0, w, h, bpp, masks[0], masks[1], masks[2], masks[3]) pixelsize = h * dest.contents.pitch rowlen = dest.contents.pitch // 4 sources = [] for width, height in blitsizes: src = surface.SDL_CreateRGBSurface(0, width, height, bpp, masks[0], masks[1], masks[2], masks[3]) surface.SDL_FillRect(src, None, 0xFFFFFFFF) # fill with white sources.append(src) for src in sources: for pos in blitpositions: drect = pos.__copy__() surface.SDL_FillRect(dest, None, 0x0) # fill with black surface.SDL_LowerBlit(src, src.contents.clip_rect, dest, drect) buf = cast(dest.contents.pixels, POINTER(Uint8 * pixelsize)) pbuf = CTypesView(buf.contents, itemsize=1, objsize=pixelsize) iview = pbuf.to_uint32() pw = drect.x + drect.w ph = drect.y + drect.h for y in range(dest.contents.h): for x in range(dest.contents.w): col = iview[y * rowlen + x] if y >= drect.y and y < ph and \ x >= drect.x and x < pw: self.assertEqual(col, 0xFFFFFFFF, msg="""color mismatch at %d,%d for %s: %d != %d""" % (y, x, pos, col, 0xFFFFFFFF)) else: self.assertEqual(col, 0x0, msg="""color mismatch at %d,%d for %s: %d != %d""" % (y, x, pos, col, 0x0)) while len(sources) > 0: sf = sources.pop() surface.SDL_FreeSurface(sf) surface.SDL_FreeSurface(dest) @unittest.skip("not implemented") def test_SDL_LowerBlitScaled(self): pass @unittest.skipIf(sys.platform=="cli", "IronPython can't handle array to POINTER conversions") def test_SDL_UpperBlit(self): bpp = 32 w, h = 10, 10 # no alpha to prevent blending masks = (0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000) dest = surface.SDL_CreateRGBSurface(0, w, h, bpp, masks[0], masks[1], masks[2], masks[3]) pixelsize = h * dest.contents.pitch rowlen = dest.contents.pitch // 4 sources = [] for width, height in blitsizes: src = surface.SDL_CreateRGBSurface(0, width, height, bpp, masks[0], masks[1], masks[2], masks[3]) surface.SDL_FillRect(src, None, 0xFFFFFFFF) # fill with white sources.append(src) for src in sources: for pos in blitpositions: drect = pos.__copy__() surface.SDL_FillRect(dest, None, 0x0) # fill with black surface.SDL_UpperBlit(src, None, dest, drect) buf = cast(dest.contents.pixels, POINTER(Uint8 * pixelsize)) pbuf = CTypesView(buf.contents, itemsize=1, objsize=pixelsize) iview = pbuf.to_uint32() pw = drect.x + drect.w ph = drect.y + drect.h for y in range(dest.contents.h): for x in range(dest.contents.w): col = iview[y * rowlen + x] if y >= drect.y and y < ph and \ x >= drect.x and x < pw: self.assertEqual(col, 0xFFFFFFFF, msg="""color mismatch at %d,%d for %s: %d != %d""" % (x, y, pos, col, 0xFFFFFFFF)) else: self.assertEqual(col, 0x0, msg="""color mismatch at %d,%d for %s: %d != %d""" % (x, y, pos, col, 0x0)) while len(sources) > 0: sf = sources.pop() surface.SDL_FreeSurface(sf) surface.SDL_FreeSurface(dest) @unittest.skipIf(sys.platform=="cli", "IronPython can't cast correctly") def test_SDL_BlitSurface(self): bpp = 32 w, h = 10, 10 # no alpha to prevent blending masks = (0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000) dest = surface.SDL_CreateRGBSurface(0, w, h, bpp, masks[0], masks[1], masks[2], masks[3]) pixelsize = h * dest.contents.pitch rowlen = dest.contents.pitch // 4 sources = [] for width, height in blitsizes: src = surface.SDL_CreateRGBSurface(0, width, height, bpp, masks[0], masks[1], masks[2], masks[3]) surface.SDL_FillRect(src, None, 0xFFFFFFFF) # fill with white sources.append(src) for src in sources: for pos in blitpositions: drect = pos.__copy__() surface.SDL_FillRect(dest, None, 0x0) # fill with black surface.SDL_BlitSurface(src, None, dest, drect) buf = cast(dest.contents.pixels, POINTER(Uint8 * pixelsize)) pbuf = CTypesView(buf.contents, itemsize=1, objsize=pixelsize) iview = pbuf.to_uint32() pw = drect.x + drect.w ph = drect.y + drect.h for y in range(dest.contents.h): for x in range(dest.contents.w): col = iview[y * rowlen + x] if y >= drect.y and y < ph and \ x >= drect.x and x < pw: self.assertEqual(col, 0xFFFFFFFF, msg="""color mismatch at %d,%d for %s: %d != %d""" % (y, x, pos, col, 0xFFFFFFFF)) else: self.assertEqual(col, 0x0, msg="""color mismatch at %d,%d for %s: %d != %d""" % (y, x, pos, col, 0x0)) while len(sources) > 0: sf = sources.pop() surface.SDL_FreeSurface(sf) surface.SDL_FreeSurface(dest) @unittest.skip("not implemented") def test_SDL_UpperBlitScaled(self): pass @unittest.skip("not implemented") def test_SDL_SoftStretch(self): pass def test_SDL_SetSurfacePalette(self): invpalette = pixels.SDL_AllocPalette(10) palette = pixels.SDL_AllocPalette(1 << 16) sf = surface.SDL_CreateRGBSurface(0, 10, 10, 16, 0, 0, 0, 0) # self.assertRaises((AttributeError, TypeError), # surface.set_surface_palette, None, None) # self.assertRaises((AttributeError, TypeError), # surface.set_surface_palette, None, palette) self.assertFalse(sf.contents.format.contents.palette) surface.SDL_SetSurfacePalette(sf, palette) self.assertIsNotNone(sf.contents.format.contents.palette.contents) # self.assertRaises(sdl.SDLError, surface.set_surface_palette, sf, # invpalette) self.assertIsNotNone(sf.contents.format.contents.palette.contents) surface.SDL_SetSurfacePalette(sf, None) self.assertFalse(sf.contents.format.contents.palette) surface.SDL_FreeSurface(sf) pixels.SDL_FreePalette(invpalette) pixels.SDL_FreePalette(palette) @unittest.skip("not implemented") def test_SDL_SetSurfaceRLE(self): pass @unittest.skipIf(sys.platform=="cli", "IronPython can't handle RW objects") def test_SDL_LoadBMP_RW(self): fp = open(self.testfile, "rb") imgrw = rwops.rw_from_object(fp) imgsurface = surface.SDL_LoadBMP_RW(imgrw, 0) self.assertIsInstance(imgsurface.contents, surface.SDL_Surface) surface.SDL_FreeSurface(imgsurface) imgrw.close(imgrw) # self.assertRaises(TypeError, surface.load_bmp_rw, "Test") # self.assertRaises(TypeError, surface.load_bmp_rw, None) # self.assertRaises(TypeError, surface.load_bmp_rw, 1234) def test_SDL_LoadBMP(self): imgsurface = surface.SDL_LoadBMP(self.testfile.encode("utf-8")) self.assertIsInstance(imgsurface.contents, surface.SDL_Surface) surface.SDL_FreeSurface(imgsurface) # self.assertRaises(sdl.SDLError, surface.load_bmp, "invalid path") # self.assertRaises(sdl.SDLError, surface.load_bmp, None) # self.assertRaises(sdl.SDLError, surface.load_bmp, 1234) @unittest.skip("not implemented") def test_SDL_SaveBMP_RW(self): pass @unittest.skip("not implemented") def test_SDL_SaveBMP(self): pass if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/syswm_test.py0000644000000000000000000000254612260256443014057 0ustar import sys import unittest import ctypes from ..stdinc import SDL_TRUE from .. import video, syswm, version class SDLSysWMTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): video.SDL_VideoInit(None) def tearDown(self): video.SDL_VideoQuit() def test_SDL_GetWindowWMInfo(self): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, video.SDL_WINDOW_HIDDEN) wminfo = syswm.SDL_SysWMinfo() version.SDL_VERSION(wminfo.version) ret = syswm.SDL_GetWindowWMInfo(window, ctypes.byref(wminfo)) self.assertEqual(ret, SDL_TRUE) if sys.platform in ("win32", "cygwin", "cli"): self.assertEqual(wminfo.subsystem, syswm.SDL_SYSWM_WINDOWS) elif sys.platform.startswith("linux"): self.assertIn(wminfo.subsystem, (syswm.SDL_SYSWM_X11, syswm.SDL_SYSWM_DIRECTFB)) elif sys.platform.startswith("freebsd"): self.assertIn(wminfo.subsystem, (syswm.SDL_SYSWM_X11, syswm.SDL_SYSWM_DIRECTFB)) elif sys.platform.startswith("darwin"): self.assertEqual(wminfo.subsystem, syswm.SDL_SYSWM_COCOA) video.SDL_DestroyWindow(window) # TODO: not sure, what to test here specifically if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/timer_test.py0000644000000000000000000000561312356442655014023 0ustar import sys import time import unittest from .. import SDL_Init, SDL_Quit, SDL_QuitSubSystem, SDL_INIT_TIMER from .. import timer if sys.version_info[0] >= 3: long = int calls = [] class SDLTimerTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): SDL_Init(SDL_INIT_TIMER) def tearDown(self): SDL_QuitSubSystem(SDL_INIT_TIMER) SDL_Quit() def test_SDL_GetTicks(self): ticks = timer.SDL_GetTicks() time.sleep(1) ticks2 = timer.SDL_GetTicks() time.sleep(1) ticks3 = timer.SDL_GetTicks() # Add some latency, since the final numbers can heavily depend # on the system's context switching behaviour, load, etc., etc., # etc. self.assertTrue(abs(ticks2 - 1000 - ticks) <= 3, "1: %f is not <= 3 for %f and %f" % (abs(ticks2 - 1000 - ticks), ticks2, ticks)) self.assertTrue(abs(ticks3 - 1000 - ticks2) <= 3, "2: %f is not <= 3 for %f and %f" % (abs(ticks3 - 1000 - ticks2), ticks3, ticks2)) self.assertTrue(abs(ticks3 - 2000 - ticks) <= 3, "3: %f is not <= 3 for %f and %f" % (abs(ticks3 - 2000 - ticks2), ticks3, ticks)) def test_SDL_GetPerformanceCounter(self): perf = timer.SDL_GetPerformanceCounter() self.assertTrue(type(perf) in (int, long)) def test_SDL_GetPerformanceFrequency(self): freq = timer.SDL_GetPerformanceFrequency() self.assertTrue(type(freq) in (int, long)) def test_SDL_Delay(self): for wait in range(5, 200, 5): start = time.time() * 1000 timer.SDL_Delay(wait) end = time.time() * 1000 sm = (end - start) self.assertTrue(abs(wait - sm) <= 3, "%f is not <= 3 for %f and %f" % (abs(wait - sm), wait, sm)) @unittest.skipIf(hasattr(sys, "pypy_version_info"), "PyPy can't access other variables properly from a separate thread") def test_SDL_AddRemoveTimer(self): calls = [] def timerfunc(interval, param): calls.append(param) return interval callback = timer.SDL_TimerCallback(timerfunc) timerid = timer.SDL_AddTimer(100, callback, "Test") start = timer.SDL_GetTicks() end = long(start) while (end - start) < 1100: # One second wait end = timer.SDL_GetTicks() # check for <=11, since it can happen that a last call is still # executing self.assertLessEqual(len(calls), 11) timer.SDL_RemoveTimer(timerid) self.assertLessEqual(len(calls), 11) timer.SDL_RemoveTimer(timerid) # Wait a bit, so the last executing handlers can finish timer.SDL_Delay(10) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/version_test.py0000644000000000000000000000317312312254160014347 0ustar import sys import ctypes import unittest from .. import version class SDLVersionTest(unittest.TestCase): __tags__ = ["sdl"] def test_SDL_version(self): v = version.SDL_version(0, 0, 0) self.assertEqual(v.major, 0) self.assertEqual(v.minor, 0) self.assertEqual(v.patch, 0) def test_SDL_GetVersion(self): v = version.SDL_version() version.SDL_GetVersion(ctypes.byref(v)) self.assertEqual(type(v), version.SDL_version) self.assertEqual(v.major, 2) self.assertEqual(v.minor, 0) self.assertEqual(v.patch, 3) def test_SDL_VERSIONNUM(self): self.assertEqual(version.SDL_VERSIONNUM(1, 2, 3), 1203) self.assertEqual(version.SDL_VERSIONNUM(4, 5, 6), 4506) self.assertEqual(version.SDL_VERSIONNUM(2, 0, 0), 2000) self.assertEqual(version.SDL_VERSIONNUM(17, 42, 3), 21203) def test_SDL_VERSION_ATLEAST(self): self.assertTrue(version.SDL_VERSION_ATLEAST(1, 2, 3)) self.assertTrue(version.SDL_VERSION_ATLEAST(2, 0, 0)) self.assertTrue(version.SDL_VERSION_ATLEAST(2, 0, 1)) self.assertFalse(version.SDL_VERSION_ATLEAST(2, 0, 100)) def test_SDL_GetRevision(self): self.assertEqual(version.SDL_GetRevision()[0:3], b"hg-") def test_SDL_GetRevisionNumber(self): if sys.platform in ("win32", "cli"): # HG tip on Win32 does not set any revision number self.assertGreaterEqual(version.SDL_GetRevisionNumber(), 0) else: self.assertGreaterEqual(version.SDL_GetRevisionNumber(), 7000) if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/test/video_test.py0000644000000000000000000011023012356441627013777 0ustar import sys from ctypes.util import find_library from ctypes import c_int, byref, cast, POINTER, py_object import unittest from .util.testutils import interactive, doprint from ..stdinc import SDL_FALSE, SDL_TRUE from .. import video, rect, surface if sys.version_info[0] >= 3: long = int to_ctypes = lambda seq, dtype: (dtype * len(seq))(*seq) def has_opengl_lib(): for libname in("gl", "opengl", "opengl32"): path = find_library(libname) if path is not None: return True def get_opengl_path(): for libname in("gl", "opengl", "opengl32"): path = find_library(libname) if path is not None: return path # TODO: mostly covers positive tests right now - fix this! class SDLVideoTest(unittest.TestCase): __tags__ = ["sdl"] def setUp(self): video.SDL_VideoInit(None) def tearDown(self): video.SDL_VideoQuit() def test_SDL_WINDOWPOS_UNDEFINED_DISPLAY(self): for x in range(0xFFFF): self.assertEqual(video.SDL_WINDOWPOS_UNDEFINED_MASK | x, video.SDL_WINDOWPOS_UNDEFINED_DISPLAY(x)) self.assertEqual((video.SDL_WINDOWPOS_UNDEFINED_DISPLAY(x) & video.SDL_WINDOWPOS_UNDEFINED_MASK), video.SDL_WINDOWPOS_UNDEFINED_MASK) self.assertTrue(video.SDL_WINDOWPOS_UNDEFINED_DISPLAY(x) != video.SDL_WINDOWPOS_CENTERED_DISPLAY(x)) def test_SDL_WINDOWPOS_ISUNDEFINED(self): self.assertTrue(video.SDL_WINDOWPOS_ISUNDEFINED (video.SDL_WINDOWPOS_UNDEFINED)) self.assertFalse(video.SDL_WINDOWPOS_ISUNDEFINED (video.SDL_WINDOWPOS_CENTERED)) for x in range(0xFFFF): self.assertTrue(video.SDL_WINDOWPOS_ISUNDEFINED (video.SDL_WINDOWPOS_UNDEFINED_DISPLAY(x))) def test_SDL_WINDOWPOS_CENTERED_DISPLAY(self): for x in range(0xFFFF): self.assertEqual(video.SDL_WINDOWPOS_CENTERED_MASK | x, video.SDL_WINDOWPOS_CENTERED_DISPLAY(x)) self.assertEqual((video.SDL_WINDOWPOS_CENTERED_DISPLAY(x) & video.SDL_WINDOWPOS_CENTERED_MASK), video.SDL_WINDOWPOS_CENTERED_MASK) self.assertTrue(video.SDL_WINDOWPOS_CENTERED_DISPLAY(x) != video.SDL_WINDOWPOS_UNDEFINED_DISPLAY(x)) def test_SDL_WINDOWPOS_ISCENTERED(self): self.assertTrue(video.SDL_WINDOWPOS_ISCENTERED (video.SDL_WINDOWPOS_CENTERED)) self.assertFalse(video.SDL_WINDOWPOS_ISCENTERED (video.SDL_WINDOWPOS_UNDEFINED)) for x in range(0xFFFF): self.assertTrue(video.SDL_WINDOWPOS_ISCENTERED (video.SDL_WINDOWPOS_CENTERED_DISPLAY(x))) def test_SDL_DisplayMode(self): mode = video.SDL_DisplayMode() self.assertIsInstance(mode, video.SDL_DisplayMode) for fmt in range(0, 10): for w in range(0, 20): for h in range(0, 30): for r in range(0, 40): mode = video.SDL_DisplayMode(fmt, w, h, r) self.assertIsInstance(mode, video.SDL_DisplayMode) self.assertEqual(mode.format, fmt) self.assertEqual(mode.w, w) self.assertEqual(mode.h, h) self.assertEqual(mode.refresh_rate, r) self.assertRaises(TypeError, video.SDL_DisplayMode, "Test") self.assertRaises(TypeError, video.SDL_DisplayMode, "Test", 10, 10, 10) self.assertRaises(TypeError, video.SDL_DisplayMode, 10, "Test", 10, 10) self.assertRaises(TypeError, video.SDL_DisplayMode, 10, 10, "Test", 10) self.assertRaises(TypeError, video.SDL_DisplayMode, 10, 10, 10, "Test") self.assertRaises(TypeError, video.SDL_DisplayMode, None) self.assertRaises(TypeError, video.SDL_DisplayMode, None, 10, 10, 10) self.assertRaises(TypeError, video.SDL_DisplayMode, 10, None, 10, 10) self.assertRaises(TypeError, video.SDL_DisplayMode, 10, 10, None, 10) self.assertRaises(TypeError, video.SDL_DisplayMode, 10, 10, 10, None) def test_SDL_DisplayMode__eq__(self): DMode = video.SDL_DisplayMode self.assertTrue(DMode() == DMode()) self.assertTrue(DMode(10, 0, 0, 0) == DMode(10, 0, 0, 0)) self.assertTrue(DMode(10, 10, 0, 0) == DMode(10, 10, 0, 0)) self.assertTrue(DMode(10, 10, 10, 0) == DMode(10, 10, 10, 0)) self.assertTrue(DMode(10, 10, 10, 10) == DMode(10, 10, 10, 10)) self.assertTrue(DMode(0, 10, 0, 0) == DMode(0, 10, 0, 0)) self.assertTrue(DMode(0, 0, 10, 0) == DMode(0, 0, 10, 0)) self.assertTrue(DMode(0, 0, 0, 10) == DMode(0, 0, 0, 10)) self.assertFalse(DMode() == DMode(10, 0, 0, 0)) self.assertFalse(DMode(10, 0, 0, 0) == DMode(0, 0, 0, 0)) self.assertFalse(DMode(10, 0, 0, 0) == DMode(0, 10, 0, 0)) self.assertFalse(DMode(10, 0, 0, 0) == DMode(0, 0, 10, 0)) self.assertFalse(DMode(10, 0, 0, 0) == DMode(0, 0, 0, 10)) def test_SDL_DisplayMode__ne__(self): DMode = video.SDL_DisplayMode self.assertFalse(DMode() != DMode()) self.assertFalse(DMode(10, 0, 0, 0) != DMode(10, 0, 0, 0)) self.assertFalse(DMode(10, 10, 0, 0) != DMode(10, 10, 0, 0)) self.assertFalse(DMode(10, 10, 10, 0) != DMode(10, 10, 10, 0)) self.assertFalse(DMode(10, 10, 10, 10) != DMode(10, 10, 10, 10)) self.assertFalse(DMode(0, 10, 0, 0) != DMode(0, 10, 0, 0)) self.assertFalse(DMode(0, 0, 10, 0) != DMode(0, 0, 10, 0)) self.assertFalse(DMode(0, 0, 0, 10) != DMode(0, 0, 0, 10)) self.assertTrue(DMode() != DMode(10, 0, 0, 0)) self.assertTrue(DMode(10, 0, 0, 0) != DMode(0, 0, 0, 0)) self.assertTrue(DMode(10, 0, 0, 0) != DMode(0, 10, 0, 0)) self.assertTrue(DMode(10, 0, 0, 0) != DMode(0, 0, 10, 0)) self.assertTrue(DMode(10, 0, 0, 0) != DMode(0, 0, 0, 10)) def test_SDL_Window(self): window = video.SDL_Window() self.assertIsInstance(window, video.SDL_Window) def test_SDL_GetNumVideoDrivers(self): numdrivers = video.SDL_GetNumVideoDrivers() self.assertGreaterEqual(numdrivers, 1) def test_SDL_GetVideoDriver(self): numdrivers = video.SDL_GetNumVideoDrivers() for i in range(numdrivers): name = video.SDL_GetVideoDriver(i) self.assertIn(type(name), (str, bytes)) def test_SDL_GetCurrentVideoDriver(self): curdriver = video.SDL_GetCurrentVideoDriver() found = False numdrivers = video.SDL_GetNumVideoDrivers() for i in range(numdrivers): name = video.SDL_GetVideoDriver(i) if name == curdriver: found = True break self.assertTrue(found, "Current video driver not found") def test_SDL_GetNumVideoDisplays(self): numdisplays = video.SDL_GetNumVideoDisplays() self.assertGreaterEqual(numdisplays, 1) def test_SDL_GetNumDisplayModes(self): numdisplays = video.SDL_GetNumVideoDisplays() for index in range(numdisplays): modes = video.SDL_GetNumDisplayModes(index) self.assertGreaterEqual(modes, 1) def test_SDL_GetDisplayMode(self): numdisplays = video.SDL_GetNumVideoDisplays() for index in range(numdisplays): modes = video.SDL_GetNumDisplayModes(index) for mode in range(modes): dmode = video.SDL_DisplayMode() ret = video.SDL_GetDisplayMode(index, mode, byref(dmode)) self.assertEqual(ret, 0) def test_SDL_GetCurrentDisplayMode(self): numdisplays = video.SDL_GetNumVideoDisplays() for index in range(numdisplays): dmode = video.SDL_DisplayMode() ret = video.SDL_GetCurrentDisplayMode(index, byref(dmode)) self.assertEqual(ret, 0) def test_SDL_GetDesktopDisplayMode(self): numdisplays = video.SDL_GetNumVideoDisplays() for index in range(numdisplays): dmode = video.SDL_DisplayMode() ret = video.SDL_GetDesktopDisplayMode(index, byref(dmode)) self.assertEqual(ret, 0) def test_SDL_GetClosestDisplayMode(self): numdisplays = video.SDL_GetNumVideoDisplays() for index in range(numdisplays): modes = video.SDL_GetNumDisplayModes(index) dmode = video.SDL_DisplayMode() for mode in range(modes): ret = video.SDL_GetDisplayMode(index, mode, byref(dmode)) #self.assertIsInstance(dmode.contents, video.SDL_DisplayMode) self.assertEqual(ret, 0) cmode = video.SDL_DisplayMode(dmode.format, dmode.w - 1, dmode.h - 1, dmode.refresh_rate) closest = video.SDL_DisplayMode() video.SDL_GetClosestDisplayMode(index, cmode, byref(closest)) self.assertEqual(closest, dmode) def test_SDL_VideoInit(self): video.SDL_VideoInit(None) video.SDL_VideoInit(None) video.SDL_VideoInit(None) video.SDL_VideoQuit(None) video.SDL_VideoInit(None) def test_SDL_VideoQuit(self): video.SDL_VideoQuit() video.SDL_VideoQuit() video.SDL_VideoQuit() video.SDL_VideoInit(None) def test_SDL_GetDisplayBounds(self): numdisplays = video.SDL_GetNumVideoDisplays() for index in range(numdisplays): bounds = rect.SDL_Rect() ret = video.SDL_GetDisplayBounds(index, byref(bounds)) self.assertEqual(ret, 0) self.assertFalse(rect.SDL_RectEmpty(bounds)) def test_screensaver(self): initial = video.SDL_IsScreenSaverEnabled() self.assertIn(initial, (SDL_FALSE, SDL_TRUE)) video.SDL_EnableScreenSaver() self.assertEqual(video.SDL_IsScreenSaverEnabled(), SDL_TRUE) video.SDL_EnableScreenSaver() self.assertEqual(video.SDL_IsScreenSaverEnabled(), SDL_TRUE) video.SDL_DisableScreenSaver() self.assertEqual(video.SDL_IsScreenSaverEnabled(), SDL_FALSE) video.SDL_DisableScreenSaver() self.assertEqual(video.SDL_IsScreenSaverEnabled(), SDL_FALSE) video.SDL_EnableScreenSaver() self.assertEqual(video.SDL_IsScreenSaverEnabled(), SDL_TRUE) video.SDL_DisableScreenSaver() self.assertEqual(video.SDL_IsScreenSaverEnabled(), SDL_FALSE) if initial == SDL_TRUE: video.SDL_EnableScreenSaver() else: video.SDL_DisableScreenSaver() def test_SDL_CreateWindow(self): # Borderless to ensure that the size check works flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN) for flag in flags: window = video.SDL_CreateWindow(b"Test", 10, 11, 12, 13, flag) self.assertIsInstance(window.contents, video.SDL_Window) px, py = c_int(), c_int() video.SDL_GetWindowPosition(window, byref(px), byref(py)) self.assertEqual((px.value, py.value), (10, 11)) video.SDL_GetWindowSize(window, byref(px), byref(py)) self.assertEqual((px.value, py.value), (12, 13)) self.assertEqual(video.SDL_GetWindowFlags(window) & flag, flag) self.assertEqual(video.SDL_GetWindowTitle(window), b"Test") video.SDL_DestroyWindow(window) # TODO def test_SDL_DestroyWindow(self): flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN) for flag in flags: window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, flag) # TODO: how to check for this in a meaningful way? video.SDL_DestroyWindow(window) @unittest.skip("not implemented") def test_SDL_CreateWindowFrom(self): pass def test_SDL_GetWindowDisplayIndex(self): numdisplays = video.SDL_GetNumVideoDisplays() flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN) for flag in flags: window = video.SDL_CreateWindow(b"Test", 10, 11, 12, 13, flag) self.assertIsInstance(window.contents, video.SDL_Window) px, py = c_int(), c_int() video.SDL_GetWindowPosition(window, byref(px), byref(py)) self.assertEqual((px.value, py.value), (10, 11)) video.SDL_GetWindowSize(window, byref(px), byref(py)) self.assertEqual((px.value, py.value), (12, 13)) self.assertEqual(video.SDL_GetWindowFlags(window) & flag, flag) self.assertEqual(video.SDL_GetWindowTitle(window), b"Test") dindex = video.SDL_GetWindowDisplayIndex(window) self.assertTrue(0 <= dindex <= numdisplays, "Invalid display index") video.SDL_DestroyWindow(window) #self.assertRaises(sdl.SDLError, video.SDL_GetWindowDisplay, # window) def test_SDL_GetWindowDisplayMode(self): flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN) for flag in flags: window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, flag) dmode = video.SDL_DisplayMode() ret = video.SDL_GetWindowDisplayMode(window, byref(dmode)) self.assertEqual(ret, 0) video.SDL_DestroyWindow(window) #self.assertRaises(sdl.SDLError, video.SDL_GetWindowDisplayMode, # window) def test_SDL_SetWindowDisplayMode(self): flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN) for flag in flags: window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, flag) dindex = video.SDL_GetWindowDisplayIndex(window) dmode = video.SDL_DisplayMode() ret = video.SDL_GetCurrentDisplayMode(dindex, byref(dmode)) self.assertEqual(ret, 0) video.SDL_SetWindowDisplayMode(window, dmode) wmode = video.SDL_DisplayMode() ret = video.SDL_GetWindowDisplayMode(window, byref(wmode)) self.assertEqual(ret, 0) # TODO: refresh rates differ #self.assertEqual(dmode, wmode) video.SDL_DestroyWindow(window) #self.assertRaises(sdl.SDLError, video.SDL_SetWindowDisplayMode, # window, dmode) def test_SDL_GetWindowPixelFormat(self): flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN) for flag in flags: window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, flag) fmt = video.SDL_GetWindowPixelFormat(window) self.assertTrue(type(fmt) in(int, long)) video.SDL_DestroyWindow(window) #self.assertRaises(sdl.SDLError, video.SDL_GetWindowPixelFormat, # window) def test_SDL_GetWindowID(self): flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN) for flag in flags: window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, flag) self.assertGreaterEqual(video.SDL_GetWindowID(window), 0) video.SDL_DestroyWindow(window) #self.assertRaises(sdl.SDLError, video.SDL_GetWindowID, window) def test_SDL_GetWindowFromID(self): flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN) for flag in flags: window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, flag) window2 = video.SDL_GetWindowFromID(video.SDL_GetWindowID(window)) self.assertEqual(video.SDL_GetWindowID(window), video.SDL_GetWindowID(window2)) self.assertEqual(video.SDL_GetWindowTitle(window), video.SDL_GetWindowTitle(window2)) px1, py1, px2, py2 = c_int(), c_int(), c_int(), c_int() video.SDL_GetWindowPosition(window, byref(px1), byref(px2)) video.SDL_GetWindowPosition(window2, byref(px2), byref(px2)) self.assertEqual((px1.value, py1.value), (px2.value, py2.value)) video.SDL_GetWindowSize(window, byref(px1), byref(px2)) video.SDL_GetWindowSize(window2, byref(px2), byref(px2)) self.assertEqual((px1.value, py1.value), (px2.value, py2.value)) def test_SDL_GetWindowFlags(self): flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN, video.SDL_WINDOW_RESIZABLE) for flag in flags: window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, flag) wflags = video.SDL_GetWindowFlags(window) self.assertEqual((wflags & flag), flag) def test_SDL_GetSetWindowTitle(self): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, 0) self.assertEqual(video.SDL_GetWindowTitle(window), b"Test") video.SDL_SetWindowTitle(window, b"Hello there") self.assertEqual(video.SDL_GetWindowTitle(window), b"Hello there") video.SDL_DestroyWindow(window) #self.assertRaises(sdl.SDLError, video.SDL_GetWindowTitle, window) def test_SDL_SetWindowIcon(self): sf = surface.SDL_CreateRGBSurface(0, 16, 16, 16, 0xF000, 0x0F00, 0x00F0, 0x000F) self.assertIsInstance(sf.contents, surface.SDL_Surface) window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, 0) video.SDL_SetWindowIcon(window, sf) #self.assertRaises((AttributeError, TypeError), # video.SDL_SetWindowIcon, None, None) #self.assertRaises((AttributeError, TypeError), # video.SDL_SetWindowIcon, window, None) #self.assertRaises((AttributeError, TypeError), # video.SDL_SetWindowIcon, None, sf) ##self.assertRaises((AttributeError, TypeError), # video.SDL_SetWindowIcon, window, "Test") #self.assertRaises((AttributeError, TypeError), # video.SDL_SetWindowIcon, window, 123456) @unittest.skipIf(hasattr(sys, "pypy_version_info"), "PyPy can't create proper py_object() values") def test_SDL_GetSetWindowData(self): #TODO: fix this window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, 0) self.assertIsInstance(window.contents, video.SDL_Window) values = {b"text": py_object("Teststring"), b"object": py_object(self), b"list": py_object([1, 2, 3, 4]), b"tuple": py_object(("a", 1, self)) } for k, v in values.items(): retval = video.SDL_GetWindowData(window, k) self.assertFalse(retval) video.SDL_SetWindowData(window, k, v) retval = video.SDL_GetWindowData(window, k) self.assertEqual(retval.contents.value, v.value) video.SDL_DestroyWindow(window) def test_SDL_GetSetWindowPosition(self): window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, 0) px, py = c_int(), c_int() video.SDL_GetWindowPosition(window, byref(px), byref(py)) self.assertEqual((px.value, py.value), (10, 10)) video.SDL_SetWindowPosition(window, 0, 0) video.SDL_GetWindowPosition(window, byref(px), byref(py)) self.assertEqual((px.value, py.value), (0, 0)) video.SDL_SetWindowPosition(window, 600, 900) video.SDL_GetWindowPosition(window, byref(px), byref(py)) self.assertEqual((px.value, py.value), (600, 900)) video.SDL_SetWindowPosition(window, -200, -10) video.SDL_GetWindowPosition(window, byref(px), byref(py)) self.assertEqual((px.value, py.value), (-200, -10)) video.SDL_DestroyWindow(window) def test_SDL_GetSetWindowSize(self): flags = video.SDL_WINDOW_BORDERLESS window = video.SDL_CreateWindow(b"Test", 10, 10, 10, 10, flags) sx, sy = c_int(), c_int() video.SDL_GetWindowSize(window, byref(sx), byref(sy)) self.assertEqual((sx.value, sy.value), (10, 10)) video.SDL_SetWindowSize(window, 1, 1) video.SDL_GetWindowSize(window, byref(sx), byref(sy)) self.assertEqual((sx.value, sy.value), (1, 1)) video.SDL_SetWindowSize(window, 600, 900) video.SDL_GetWindowSize(window, byref(sx), byref(sy)) self.assertEqual((sx.value, sy.value), (600, 900)) video.SDL_SetWindowSize(window, -200, -10) video.SDL_GetWindowSize(window, byref(sx), byref(sy)) self.assertEqual((sx.value, sy.value), (600, 900)) video.SDL_DestroyWindow(window) @interactive("Was the window shown?") def test_SDL_ShowWindow(self): window = video.SDL_CreateWindow(b"test_SDL_ShowWindow", 200, 200, 200, 200, 0) video.SDL_ShowWindow(window) doprint("""Please check, if a window with the title 'test_SDL_ShowWindow' is shown""") video.SDL_DestroyWindow(window) @interactive("Did the window vanish from your sight and pop up again?") def test_SDL_HideWindow(self): window = video.SDL_CreateWindow(b"test_SDL_HideWindow", 200, 200, 200, 200, 0) video.SDL_ShowWindow(window) doprint("""Please check, if a window with the title 'test_SDL_HideWindow' is shown""") video.SDL_HideWindow(window) doprint("Please check, that the window is not shown anymore") video.SDL_ShowWindow(window) doprint("Please check, if the window is shown again") video.SDL_DestroyWindow(window) @interactive("Did the window raise properly?") def test_SDL_RaiseWindow(self): window = video.SDL_CreateWindow(b"test_SDL_RaiseWindow", 200, 200, 200, 200, 0) video.SDL_ShowWindow(window) doprint("""Please check, that a window with the title 'test_SDL_RaiseWindow' is shown""") doprint("Move another window on top of the window, so it is hidden") video.SDL_RaiseWindow(window) doprint("The window should be raised to the foreground now") video.SDL_DestroyWindow(window) @interactive("Was the window maximized?") def test_SDL_MaximizeWindow(self): window = video.SDL_CreateWindow(b"test_SDL_MaximizeWindow", 200, 200, 200, 200, video.SDL_WINDOW_RESIZABLE) video.SDL_ShowWindow(window) doprint("""Please check, that a window with the title 'test_SDL_MaximizeWindow' is shown""") video.SDL_MaximizeWindow(window) doprint("Please check, if the window was maximized properly") video.SDL_DestroyWindow(window) @interactive("Was the window minimized?") def test_SDL_MinimizeWindow(self): window = video.SDL_CreateWindow(b"test_SDL_MinimizeWindow", 200, 200, 200, 200, 0) video.SDL_ShowWindow(window) doprint("""Please check, that a window with the title 'test_SDL_MinimizeWindow' is shown""") video.SDL_MinimizeWindow(window) doprint("Please check, if the window was minimized properly") video.SDL_DestroyWindow(window) @interactive("Was the window maximized and restored properly?") def test_SDL_RestoreWindow(self): window = video.SDL_CreateWindow(b"test_SDL_RestoreWindow", 200, 200, 200, 200, video.SDL_WINDOW_RESIZABLE) video.SDL_ShowWindow(window) doprint("""Please check, that a window with the title 'test_SDL_RestoreWindow' is shown""") video.SDL_MaximizeWindow(window) doprint("Please check, if the window was maximized properly") video.SDL_RestoreWindow(window) doprint("Please check, if the window was restored properly") video.SDL_DestroyWindow(window) def test_SDL_SetWindowFullscreen(self): # TODO: HIDDEN avoids flickering, but is this really a sufficient test? flags = (video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN, video.SDL_WINDOW_RESIZABLE | video.SDL_WINDOW_MINIMIZED | video.SDL_WINDOW_HIDDEN) for flag in flags: window = video.SDL_CreateWindow(b"Test", 0, 0, 1024, 768, flag) video.SDL_SetWindowFullscreen(window, True) flags = video.SDL_GetWindowFlags(window) self.assertEqual(flags & video.SDL_WINDOW_FULLSCREEN, video.SDL_WINDOW_FULLSCREEN) video.SDL_SetWindowFullscreen(window, False) flags = video.SDL_GetWindowFlags(window) self.assertNotEqual(flags & video.SDL_WINDOW_FULLSCREEN, video.SDL_WINDOW_FULLSCREEN) video.SDL_DestroyWindow(window) def test_SDL_GetWindowSurface(self): flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN, video.SDL_WINDOW_RESIZABLE | video.SDL_WINDOW_MINIMIZED) for flag in flags: window = video.SDL_CreateWindow(b"Test", 200, 200, 200, 200, flag) sf = video.SDL_GetWindowSurface(window) self.assertIsInstance(sf.contents, surface.SDL_Surface) video.SDL_DestroyWindow(window) #self.assertRaises(sdl.SDLError, video.SDL_GetWindowSurface, # window) def test_SDL_UpdateWindowSurface(self): flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN, video.SDL_WINDOW_RESIZABLE | video.SDL_WINDOW_MINIMIZED) for flag in flags: window = video.SDL_CreateWindow(b"Test", 200, 200, 200, 200, flag) video.SDL_UpdateWindowSurface(window) video.SDL_DestroyWindow(window) def test_SDL_UpdateWindowSurfaceRects(self): rectlist = (rect.SDL_Rect * 4)(rect.SDL_Rect(), rect.SDL_Rect(10, 10, 10, 10), rect.SDL_Rect(0, 0, 5, 4), rect.SDL_Rect(-5, -5, 6, 2)) rptr = cast(rectlist, POINTER(rect.SDL_Rect)) flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN, video.SDL_WINDOW_RESIZABLE | video.SDL_WINDOW_MINIMIZED) for flag in flags: window = video.SDL_CreateWindow(b"Test", 200, 200, 200, 200, flag) #self.assertRaises(sdl.SDLError, # video.SDL_UpdateWindowSurfaceRects, # window, rectlist) sf = surface.SDL_Surface() video.SDL_GetWindowSurface(window, byref(sf)) ret = video.SDL_UpdateWindowSurfaceRects(window, rptr, 4) self.assertEqual(ret, 0) video.SDL_DestroyWindow(window) def test_SDL_GetSetWindowGrab(self): flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN, video.SDL_WINDOW_RESIZABLE | video.SDL_WINDOW_MINIMIZED) for flag in flags: window = video.SDL_CreateWindow(b"Test", 200, 200, 200, 200, flag) self.assertFalse(video.SDL_GetWindowGrab(window)) video.SDL_SetWindowGrab(window, SDL_TRUE) self.assertEqual(video.SDL_GetWindowGrab(window), SDL_TRUE) video.SDL_SetWindowGrab(window, SDL_FALSE) self.assertEqual(video.SDL_GetWindowGrab(window), SDL_FALSE) def test_SDL_GetSetWindowBrightness(self): flags = (video.SDL_WINDOW_BORDERLESS, video.SDL_WINDOW_BORDERLESS | video.SDL_WINDOW_HIDDEN, video.SDL_WINDOW_RESIZABLE | video.SDL_WINDOW_MINIMIZED) for flag in flags: window = video.SDL_CreateWindow(b"Test", 200, 200, 200, 200, flag) orig = video.SDL_GetWindowBrightness(window) self.assertIsInstance(orig, float) # Go from 0.0, 0.1 ... to 3.0 gammas = (x * 0.1 for x in range(0, 20)) count = 0 for b in gammas: ret = video.SDL_SetWindowBrightness(window, b) if ret == 0: val = video.SDL_GetWindowBrightness(window) self.assertAlmostEqual(val, b) count += 1 # At least one gamma(1.0) must have worked. self.assertTrue(count > 0) @unittest.skip("not implemented") def test_SDL_SetWindowGammaRamp(self): pass @unittest.skip("not implemented") def test_SDL_GetWindowGammaRamp(self): pass @unittest.skip("not implemented") def test_SDL_SetWindowHitTest(self): pass def test_SDL_GL_LoadUnloadLibrary(self): # Try the default library self.assertEquals(video.SDL_GL_LoadLibrary(None), 0) video.SDL_GL_UnloadLibrary() if has_opengl_lib(): fpath = get_opengl_path().encode("utf-8") self.assertEqual(video.SDL_GL_LoadLibrary(fpath), 0) video.SDL_GL_UnloadLibrary() #self.assertRaises(sdl.SDLError, video.SDL_GL_LoadLibrary, "Test") #self.assertRaises(sdl.SDLError, video.SDL_GL_LoadLibrary, False) #self.assertRaises(sdl.SDLError, video.SDL_GL_LoadLibrary, 0) def test_SDL_GL_GetProcAddress(self): procaddr = video.SDL_GL_GetProcAddress(b"glGetString") self.assertIsNone(procaddr) self.assertEquals(video.SDL_GL_LoadLibrary(None), 0) # Behaviour is undefined as long as there is no window and context. window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10, video.SDL_WINDOW_OPENGL) ctx = video.SDL_GL_CreateContext(window) procaddr = video.SDL_GL_GetProcAddress(b"glGetString") self.assertTrue(procaddr is not None and int(procaddr) != 0) video.SDL_GL_DeleteContext(ctx) video.SDL_DestroyWindow(window) video.SDL_GL_UnloadLibrary() procaddr = video.SDL_GL_GetProcAddress(b"glGetString") self.assertIsNone(procaddr) def test_SDL_GL_ExtensionSupported(self): self.assertFalse(video.SDL_GL_ExtensionSupported(b"GL_EXT_bgra")) self.assertEquals(video.SDL_GL_LoadLibrary(None), 0) window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10, video.SDL_WINDOW_OPENGL) ctx = video.SDL_GL_CreateContext(window) self.assertTrue(video.SDL_GL_ExtensionSupported(b"GL_EXT_bgra")) video.SDL_GL_DeleteContext(ctx) video.SDL_DestroyWindow(window) video.SDL_GL_UnloadLibrary() self.assertFalse(video.SDL_GL_ExtensionSupported(b"GL_EXT_bgra")) def test_SDL_GL_GetSetAttribute(self): #self.assertRaises(sdl.SDLError, video.SDL_GL_GetAttribute, # video.SDL_GL_DEPTH_SIZE) #self.assertRaises(sdl.SDLError, video.SDL_GL_SetAttribute, # 1455, 24) self.assertEquals(video.SDL_GL_LoadLibrary(None), 0) window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10, video.SDL_WINDOW_OPENGL) ctx = video.SDL_GL_CreateContext(window) depth = c_int() video.SDL_GL_GetAttribute(video.SDL_GL_DEPTH_SIZE, byref(depth)) video.SDL_GL_DeleteContext(ctx) video.SDL_DestroyWindow(window) newdepth = 24 if depth == 8: newdepth = 16 elif depth == 16: newdepth = 24 elif depth == 24: newdepth = 16 video.SDL_GL_SetAttribute(video.SDL_GL_DEPTH_SIZE, newdepth) window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10, video.SDL_WINDOW_OPENGL) ctx = video.SDL_GL_CreateContext(window) val = c_int() video.SDL_GL_GetAttribute(video.SDL_GL_DEPTH_SIZE, byref(val)) self.assertNotEqual(depth, val) self.assertEqual(val.value, newdepth) video.SDL_GL_DeleteContext(ctx) video.SDL_DestroyWindow(window) video.SDL_GL_UnloadLibrary() def test_SDL_GL_CreateDeleteContext(self): #self.assertRaises((AttributeError, TypeError), # video.SDL_GL_CreateContext, None) #self.assertRaises((AttributeError, TypeError), # video.SDL_GL_CreateContext, "Test") #self.assertRaises((AttributeError, TypeError), # video.SDL_GL_CreateContext, 1234) window = video.SDL_CreateWindow(b"No OpenGL", 10, 10, 10, 10, video.SDL_WINDOW_BORDERLESS) #self.assertRaises(sdl.SDLError, video.SDL_GL_CreateContext, window) video.SDL_DestroyWindow(window) self.assertEquals(video.SDL_GL_LoadLibrary(None), 0) window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10, video.SDL_WINDOW_OPENGL) ctx = video.SDL_GL_CreateContext(window) video.SDL_GL_DeleteContext(ctx) video.SDL_DestroyWindow(window) window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10, video.SDL_WINDOW_OPENGL) ctx = video.SDL_GL_CreateContext(window) video.SDL_DestroyWindow(window) video.SDL_GL_DeleteContext(ctx) video.SDL_GL_UnloadLibrary() def test_SDL_GL_MakeCurrent(self): self.assertEquals(video.SDL_GL_LoadLibrary(None), 0) #self.assertRaises((AttributeError, TypeError), # video.SDL_GL_MakeCurrent, None, None) window = video.SDL_CreateWindow(b"No OpenGL", 10, 10, 10, 10, video.SDL_WINDOW_BORDERLESS) #self.assertRaises(sdl.SDLError, video.SDL_GL_CreateContext, window) video.SDL_DestroyWindow(window) #self.assertRaises((AttributeError, TypeError), # video.SDL_GL_MakeCurrent, None, None) video.SDL_GL_UnloadLibrary() def test_SDL_GL_GetSetSwapInterval(self): #self.assertRaises(ValueError, video.SDL_GL_SetSwapInterval, None) #self.assertRaises(ValueError, video.SDL_GL_SetSwapInterval, "Test") #self.assertRaises(ValueError, video.SDL_GL_SetSwapInterval, 1234) # No current OpenGL context yet. # Might crash on certain platforms, since the internal state of # SDL2 does not support calling GL functions without having a # GL library loaded. # self.assertRaises(sdl.SDLError, video.SDL_GL_SetSwapInterval, 1) # self.assertRaises(sdl.SDLError, video.SDL_GL_SetSwapInterval, 0) self.assertEquals(video.SDL_GL_LoadLibrary(None), 0) window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10, video.SDL_WINDOW_OPENGL) ctx = video.SDL_GL_CreateContext(window) video.SDL_GL_MakeCurrent(window, ctx) video.SDL_GL_SetSwapInterval(0) self.assertEqual(video.SDL_GL_GetSwapInterval(), 0) video.SDL_GL_SetSwapInterval(1) self.assertEqual(video.SDL_GL_GetSwapInterval(), 1) video.SDL_GL_DeleteContext(ctx) video.SDL_DestroyWindow(window) video.SDL_GL_UnloadLibrary() def test_SDL_GL_SwapWindow(self): self.assertEquals(video.SDL_GL_LoadLibrary(None), 0) window = video.SDL_CreateWindow(b"OpenGL", 10, 10, 10, 10, video.SDL_WINDOW_OPENGL) ctx = video.SDL_GL_CreateContext(window) video.SDL_GL_MakeCurrent(window, ctx) video.SDL_GL_SwapWindow(window) video.SDL_GL_SwapWindow(window) video.SDL_GL_SwapWindow(window) video.SDL_GL_SwapWindow(window) video.SDL_GL_DeleteContext(ctx) video.SDL_DestroyWindow(window) video.SDL_GL_UnloadLibrary() @unittest.skip("not implemented") def test_SDL_GL_ResetAttributes(self): pass if __name__ == '__main__': sys.exit(unittest.main()) PySDL2-0.9.3/sdl2/__init__.py0000644000000000000000000000327512354723645012425 0ustar """SDL2 wrapper package""" from .dll import get_dll_file, _bind from ctypes import c_int as _cint from .audio import * from .blendmode import * from .clipboard import * from .cpuinfo import * from .endian import * from .error import * from .events import * from .filesystem import * from .gamecontroller import * from .gesture import * from .haptic import * from .hints import * from .joystick import * from .keyboard import * from .loadso import * from .log import * from .messagebox import * from .mouse import * from .pixels import * from .platform import * from .power import * from .rect import * from .render import * from .rwops import * from .shape import * from .stdinc import * from .surface import * from .syswm import * from .timer import * from .touch import * from .version import * from .video import * from .keycode import * from .scancode import * # At least Win32 platforms need this now. _SDL_SetMainReady = _bind("SDL_SetMainReady") _SDL_SetMainReady() SDL_INIT_TIMER = 0x00000001 SDL_INIT_AUDIO = 0x00000010 SDL_INIT_VIDEO = 0x00000020 SDL_INIT_JOYSTICK = 0x00000200 SDL_INIT_HAPTIC = 0x00001000 SDL_INIT_GAMECONTROLLER = 0x00002000 SDL_INIT_EVENTS = 0x00004000 SDL_INIT_NOPARACHUTE = 0x00100000 SDL_INIT_EVERYTHING = (SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER) SDL_Init = _bind("SDL_Init", [Uint32], _cint) SDL_InitSubSystem = _bind("SDL_InitSubSystem", [Uint32], _cint) SDL_QuitSubSystem = _bind("SDL_QuitSubSystem", [Uint32]) SDL_WasInit = _bind("SDL_WasInit", [Uint32], Uint32) SDL_Quit = _bind("SDL_Quit") __version__ = "0.9.3" version_info = (0, 9, 3, "") PySDL2-0.9.3/sdl2/audio.py0000644000000000000000000001740012312245641011747 0ustar import sys from ctypes import Structure, c_int, c_char_p, c_double, c_void_p, CFUNCTYPE, \ POINTER from .dll import _bind from .endian import SDL_BYTEORDER, SDL_LIL_ENDIAN from .stdinc import Uint8, Uint16, Uint32 from .rwops import SDL_RWops, SDL_RWFromFile __all__ = ["SDL_AudioFormat", "SDL_AUDIO_MASK_BITSIZE", "SDL_AUDIO_MASK_DATATYPE", "SDL_AUDIO_MASK_ENDIAN", "SDL_AUDIO_MASK_SIGNED", "SDL_AUDIO_BITSIZE", "SDL_AUDIO_ISFLOAT", "SDL_AUDIO_ISBIGENDIAN", "SDL_AUDIO_ISSIGNED", "SDL_AUDIO_ISINT", "SDL_AUDIO_ISLITTLEENDIAN", "SDL_AUDIO_ISUNSIGNED", "AUDIO_U8", "AUDIO_S8", "AUDIO_U16LSB", "AUDIO_S16LSB", "AUDIO_U16MSB", "AUDIO_S16MSB", "AUDIO_U16", "AUDIO_S16", "AUDIO_S32LSB", "AUDIO_S32MSB", "AUDIO_S32", "AUDIO_F32LSB", "AUDIO_S32MSB", "AUDIO_F32", "AUDIO_U16SYS", "AUDIO_S16SYS", "AUDIO_S32SYS", "AUDIO_FORMATS", "AUDIO_F32SYS", "SDL_AUDIO_ALLOW_FREQUENCY_CHANGE", "SDL_AUDIO_ALLOW_FORMAT_CHANGE", "SDL_AUDIO_ALLOW_CHANNELS_CHANGE", "SDL_AUDIO_ALLOW_ANY_CHANGE", "SDL_AudioCallback", "SDL_AudioSpec", "SDL_AudioCVT", "SDL_AudioFilter", "SDL_GetNumAudioDrivers", "SDL_GetAudioDriver", "SDL_AudioInit", "SDL_AudioQuit", "SDL_GetCurrentAudioDriver", "SDL_OpenAudio", "SDL_AudioDeviceID", "SDL_GetNumAudioDevices", "SDL_GetAudioDeviceName", "SDL_OpenAudioDevice", "SDL_AUDIO_STOPPED", "SDL_AUDIO_PLAYING", "SDL_AUDIO_PAUSED", "SDL_AudioStatus", "SDL_GetAudioStatus", "SDL_GetAudioDeviceStatus", "SDL_PauseAudio", "SDL_PauseAudioDevice", "SDL_LoadWAV_RW", "SDL_LoadWAV", "SDL_FreeWAV", "SDL_BuildAudioCVT", "SDL_ConvertAudio", "SDL_MIX_MAXVOLUME", "SDL_MixAudio", "SDL_MixAudioFormat", "SDL_LockAudio", "SDL_LockAudioDevice", "SDL_UnlockAudio", "SDL_UnlockAudioDevice", "SDL_CloseAudio", "SDL_CloseAudioDevice" ] SDL_AudioFormat = Uint16 SDL_AUDIO_MASK_BITSIZE = 0xFF SDL_AUDIO_MASK_DATATYPE = 1 << 8 SDL_AUDIO_MASK_ENDIAN = 1 << 12 SDL_AUDIO_MASK_SIGNED = 1 << 15 SDL_AUDIO_BITSIZE = lambda x: (x & SDL_AUDIO_MASK_BITSIZE) SDL_AUDIO_ISFLOAT = lambda x: (x & SDL_AUDIO_MASK_DATATYPE) SDL_AUDIO_ISBIGENDIAN = lambda x: (x & SDL_AUDIO_MASK_ENDIAN) SDL_AUDIO_ISSIGNED = lambda x: (x & SDL_AUDIO_MASK_SIGNED) SDL_AUDIO_ISINT = lambda x: (not SDL_AUDIO_ISFLOAT(x)) SDL_AUDIO_ISLITTLEENDIAN = lambda x: (not SDL_AUDIO_ISBIGENDIAN(x)) SDL_AUDIO_ISUNSIGNED = lambda x: (not SDL_AUDIO_ISSIGNED(x)) AUDIO_U8 = 0x0008 AUDIO_S8 = 0x8008 AUDIO_U16LSB = 0x0010 AUDIO_S16LSB = 0x8010 AUDIO_U16MSB = 0x1010 AUDIO_S16MSB = 0x9010 AUDIO_U16 = AUDIO_U16LSB AUDIO_S16 = AUDIO_S16LSB AUDIO_S32LSB = 0x8020 AUDIO_S32MSB = 0x9020 AUDIO_S32 = AUDIO_S32LSB AUDIO_F32LSB = 0x8120 AUDIO_F32MSB = 0x9120 AUDIO_F32 = AUDIO_F32LSB # All of the audio formats should be in this set which is provided as a # convenience to the end user for purposes of iteration and validation. # (is the provided audio format in the supported set?) AUDIO_FORMATS = set([AUDIO_U8, AUDIO_S8, AUDIO_U16LSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_S16MSB, AUDIO_U16, AUDIO_S16, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S32, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_F32]) if SDL_BYTEORDER == SDL_LIL_ENDIAN: AUDIO_U16SYS = AUDIO_U16LSB AUDIO_S16SYS = AUDIO_S16LSB AUDIO_S32SYS = AUDIO_S32LSB AUDIO_F32SYS = AUDIO_F32LSB else: AUDIO_U16SYS = AUDIO_U16MSB AUDIO_S16SYS = AUDIO_S16MSB AUDIO_S32SYS = AUDIO_S32MSB AUDIO_F32SYS = AUDIO_F32MSB SDL_AUDIO_ALLOW_FREQUENCY_CHANGE = 0x00000001 SDL_AUDIO_ALLOW_FORMAT_CHANGE = 0x00000002 SDL_AUDIO_ALLOW_CHANNELS_CHANGE = 0x00000004 SDL_AUDIO_ALLOW_ANY_CHANGE = (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_FORMAT_CHANGE | SDL_AUDIO_ALLOW_CHANNELS_CHANGE) SDL_AudioCallback = CFUNCTYPE(None, c_void_p, POINTER(Uint8), c_int) class SDL_AudioSpec(Structure): _fields_ = [("freq", c_int), ("format", SDL_AudioFormat), ("channels", Uint8), ("silence", Uint8), ("samples", Uint16), ("padding", Uint16), ("size", Uint32), ("callback", SDL_AudioCallback), ("userdata", c_void_p) ] def __init__(self, freq, aformat, channels, samples, callback=SDL_AudioCallback(), userdata=c_void_p(0)): super(SDL_AudioSpec, self).__init__() self.freq = freq self.format = aformat self.channels = channels self.samples = samples self.callback = callback self.userdata = userdata class SDL_AudioCVT(Structure): pass SDL_AudioFilter = CFUNCTYPE(POINTER(SDL_AudioCVT), SDL_AudioFormat) # HACK: hack for an IronPython 2.7.2.1+ issue: # ptrarray = (CFUNCTYPE() * int) # is not supported properly if sys.platform == "cli": _X_SDL_AudioFilter = POINTER(SDL_AudioFilter) else: _X_SDL_AudioFilter = SDL_AudioFilter SDL_AudioCVT._fields_ = [("needed", c_int), ("src_format", SDL_AudioFormat), ("dst_format", SDL_AudioFormat), ("rate_incr", c_double), ("buf", POINTER(Uint8)), ("len", c_int), ("len_cvt", c_int), ("len_mult", c_int), ("len_ratio", c_double), ("filters", (_X_SDL_AudioFilter * 10)), ("filter_index", c_int) ] SDL_GetNumAudioDrivers = _bind("SDL_GetNumAudioDrivers", None, c_int) SDL_GetAudioDriver = _bind("SDL_GetAudioDriver", [c_int], c_char_p) SDL_AudioInit = _bind("SDL_AudioInit", [c_char_p], c_int) SDL_AudioQuit = _bind("SDL_AudioQuit") SDL_GetCurrentAudioDriver = _bind("SDL_GetCurrentAudioDriver", None, c_char_p) SDL_OpenAudio = _bind("SDL_OpenAudio", [POINTER(SDL_AudioSpec), POINTER(SDL_AudioSpec)], c_int) SDL_AudioDeviceID = Uint32 SDL_GetNumAudioDevices = _bind("SDL_GetNumAudioDevices", [c_int], c_int) SDL_GetAudioDeviceName = _bind("SDL_GetAudioDeviceName", [c_int, c_int], c_char_p) SDL_OpenAudioDevice = _bind("SDL_OpenAudioDevice", [c_char_p, c_int, POINTER(SDL_AudioSpec), POINTER(SDL_AudioSpec), c_int], SDL_AudioDeviceID) SDL_AUDIO_STOPPED = 0 SDL_AUDIO_PLAYING = 1 SDL_AUDIO_PAUSED = 2 SDL_AudioStatus = c_int SDL_GetAudioStatus = _bind("SDL_GetAudioStatus", None, SDL_AudioStatus) SDL_GetAudioDeviceStatus = _bind("SDL_GetAudioDeviceStatus", [SDL_AudioDeviceID], SDL_AudioStatus) SDL_PauseAudio = _bind("SDL_PauseAudio", [c_int]) SDL_PauseAudioDevice = _bind("SDL_PauseAudioDevice", [SDL_AudioDeviceID, c_int]) SDL_LoadWAV_RW = _bind("SDL_LoadWAV_RW", [POINTER(SDL_RWops), c_int, POINTER(SDL_AudioSpec), POINTER(POINTER(Uint8)), POINTER(Uint32)], POINTER(SDL_AudioSpec)) SDL_LoadWAV = lambda f, s, ab, al: SDL_LoadWAV_RW(SDL_RWFromFile(f, b"rb"), 1, s, ab , al) SDL_FreeWAV = _bind("SDL_FreeWAV", [POINTER(Uint8)]) SDL_BuildAudioCVT = _bind("SDL_BuildAudioCVT", [POINTER(SDL_AudioCVT), SDL_AudioFormat, Uint8, c_int, SDL_AudioFormat, Uint8, c_int], c_int) SDL_ConvertAudio = _bind("SDL_ConvertAudio", [POINTER(SDL_AudioCVT)], c_int) SDL_MIX_MAXVOLUME = 128 SDL_MixAudio = _bind("SDL_MixAudio", [POINTER(Uint8), POINTER(Uint8), Uint32, c_int]) SDL_MixAudioFormat = _bind("SDL_MixAudioFormat", [POINTER(Uint8), POINTER(Uint8), SDL_AudioFormat, Uint32, c_int]) SDL_LockAudio = _bind("SDL_LockAudio") SDL_LockAudioDevice = _bind("SDL_LockAudioDevice", [SDL_AudioDeviceID]) SDL_UnlockAudio = _bind("SDL_UnlockAudio") SDL_UnlockAudioDevice = _bind("SDL_UnlockAudioDevice", [SDL_AudioDeviceID]) SDL_CloseAudio = _bind("SDL_CloseAudio") SDL_CloseAudioDevice = _bind("SDL_CloseAudioDevice", [SDL_AudioDeviceID]) PySDL2-0.9.3/sdl2/blendmode.py0000644000000000000000000000047212260256443012604 0ustar from ctypes import c_int __all__ = ["SDL_BLENDMODE_NONE", "SDL_BLENDMODE_BLEND", "SDL_BLENDMODE_ADD", "SDL_BLENDMODE_MOD", "SDL_BlendMode" ] SDL_BLENDMODE_NONE = 0x00000000 SDL_BLENDMODE_BLEND = 0x00000001 SDL_BLENDMODE_ADD = 0x00000002 SDL_BLENDMODE_MOD = 0x00000004 SDL_BlendMode = c_int PySDL2-0.9.3/sdl2/clipboard.py0000644000000000000000000000061112260256443012605 0ustar from ctypes import c_char_p, c_int from .dll import _bind from .stdinc import SDL_bool __all__ = ["SDL_SetClipboardText", "SDL_GetClipboardText", "SDL_HasClipboardText"] SDL_SetClipboardText = _bind("SDL_SetClipboardText", [c_char_p], c_int) SDL_GetClipboardText = _bind("SDL_GetClipboardText", None, c_char_p) SDL_HasClipboardText = _bind("SDL_HasClipboardText", None, SDL_bool) PySDL2-0.9.3/sdl2/cpuinfo.py0000644000000000000000000000216112317473343012316 0ustar from ctypes import c_int from .dll import _bind, nullfunc from .stdinc import SDL_bool __all__ = ["SDL_CACHELINE_SIZE", "SDL_GetCPUCount", "SDL_GetCPUCacheLineSize", "SDL_HasRDTSC", "SDL_HasAltiVec", "SDL_HasMMX", "SDL_Has3DNow", "SDL_HasSSE", "SDL_HasSSE2", "SDL_HasSSE3", "SDL_HasSSE41", "SDL_HasSSE42", "SDL_GetSystemRAM", "SDL_HasAVX" ] SDL_CACHELINE_SIZE = 128 SDL_GetCPUCount = _bind("SDL_GetCPUCount", None, c_int) SDL_GetCPUCacheLineSize = _bind("SDL_GetCPUCacheLineSize", None, c_int) SDL_HasRDTSC = _bind("SDL_HasRDTSC", None, SDL_bool) SDL_HasAltiVec = _bind("SDL_HasAltiVec", None, SDL_bool) SDL_HasMMX = _bind("SDL_HasMMX", None, SDL_bool) SDL_Has3DNow = _bind("SDL_Has3DNow", None, SDL_bool) SDL_HasSSE = _bind("SDL_HasSSE", None, SDL_bool) SDL_HasSSE2 = _bind("SDL_HasSSE2", None, SDL_bool) SDL_HasSSE3 = _bind("SDL_HasSSE3", None, SDL_bool) SDL_HasSSE41 = _bind("SDL_HasSSE41", None, SDL_bool) SDL_HasSSE42 = _bind("SDL_HasSSE42", None, SDL_bool) SDL_GetSystemRAM = _bind("SDL_GetSystemRAM", None, c_int, nullfunc) SDL_HasAVX = _bind("SDL_HasAVX", None, SDL_bool, nullfunc) PySDL2-0.9.3/sdl2/dll.py0000644000000000000000000001000412342312005011402 0ustar """DLL wrapper""" import os import sys import warnings from ctypes import CDLL from ctypes.util import find_library __all__ = ["DLL", "nullfunc"] def _findlib(libnames, path=None): """.""" platform = sys.platform if platform in ("win32", "cli"): pattern = "%s.dll" elif platform == "darwin": pattern = "lib%s.dylib" else: pattern = "lib%s.so" searchfor = libnames if type(libnames) is dict: # different library names for the platforms if platform == "cli" and platform not in libnames: # if not explicitly specified, use the Win32 libs for IronPython platform = "win32" if platform not in libnames: platform = "DEFAULT" searchfor = libnames[platform] results = [] if path: for libname in searchfor: for subpath in str.split(path, os.pathsep): dllfile = os.path.join(subpath, pattern % libname) if os.path.exists(dllfile): results.append(dllfile) for libname in searchfor: dllfile = find_library(libname) if dllfile: results.append(dllfile) return results class DLL(object): """Function wrapper around the different DLL functions. Do not use or instantiate this one directly from your user code. """ def __init__(self, libinfo, libnames, path=None): self._dll = None foundlibs = _findlib(libnames, path) dllmsg = "PYSDL2_DLL_PATH: %s" % (os.getenv("PYSDL2_DLL_PATH") or "unset") if len(foundlibs) == 0: raise RuntimeError("could not find any library for %s (%s)" % (libinfo, dllmsg)) for libfile in foundlibs: try: self._dll = CDLL(libfile) self._libfile = libfile break except Exception as exc: # Could not load it, silently ignore that issue and move # to the next one. warnings.warn(repr(exc), ImportWarning) if self._dll is None: raise RuntimeError("found %s, but it's not usable for the library %s" % (foundlibs, libinfo)) if path is not None and sys.platform in ("win32", "cli") and \ path in self._libfile: os.environ["PATH"] = "%s;%s" % (path, os.environ["PATH"]) def bind_function(self, funcname, args=None, returns=None, optfunc=None): """Binds the passed argument and return value types to the specified function.""" func = getattr(self._dll, funcname, None) warnings.warn\ ("function '%s' not found in %r, using replacement" % (funcname, self._dll), ImportWarning) if not func: if optfunc: warnings.warn\ ("function '%s' not found in %r, using replacement" % (funcname, self._dll), ImportWarning) func = _nonexistent(funcname, optfunc) else: raise ValueError("could not find function '%s' in %r" % (funcname, self._dll)) func.argtypes = args func.restype = returns return func @property def libfile(self): """Gets the filename of the loaded library.""" return self._libfile def _nonexistent(funcname, func): """A simple wrapper to mark functions and methods as nonexistent.""" def wrapper(*fargs, **kw): warnings.warn("%s does not exist" % funcname, category=RuntimeWarning, stacklevel=2) return func(*fargs, **kw) wrapper.__name__ = func.__name__ return wrapper def nullfunc(*args): """A simple no-op function to be used as dll replacement.""" return try: dll = DLL("SDL2", ["SDL2", "SDL2-2.0"], os.getenv("PYSDL2_DLL_PATH")) except RuntimeError as exc: raise ImportError(exc) def get_dll_file(): """Gets the file name of the loaded SDL2 library.""" return dll.libfile _bind = dll.bind_function PySDL2-0.9.3/sdl2/endian.py0000644000000000000000000000270012260256443012105 0ustar import sys import array __all__ = ["SDL_LIL_ENDIAN", "SDL_BIG_ENDIAN", "SDL_BYTEORDER", "SDL_Swap16", "SDL_Swap32", "SDL_Swap64", "SDL_SwapFloat", "SDL_SwapLE16", "SDL_SwapLE32", "SDL_SwapLE64", "SDL_SwapFloatLE", "SDL_SwapBE16", "SDL_SwapBE32", "SDL_SwapBE64", "SDL_SwapFloatBE" ] SDL_LIL_ENDIAN = 1234 SDL_BIG_ENDIAN = 4321 if sys.byteorder == "little": SDL_BYTEORDER = SDL_LIL_ENDIAN else: SDL_BYTEORDER = SDL_BIG_ENDIAN SDL_Swap16 = lambda x: ((x << 8 & 0xFF00) | (x >> 8 & 0x00FF)) SDL_Swap32 = lambda x: (((x << 24) & 0xFF000000) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | ((x >> 24) & 0x000000FF)) SDL_Swap64 = lambda x: ((SDL_Swap32(x & 0xFFFFFFFF) << 32) | (SDL_Swap32(x >> 32 & 0xFFFFFFFF))) def SDL_SwapFloat(x): ar = array.array("d", (x,)) ar.byteswap() return ar[0] def _nop(x): return x if SDL_BYTEORDER == SDL_LIL_ENDIAN: SDL_SwapLE16 = _nop SDL_SwapLE32 = _nop SDL_SwapLE64 = _nop SDL_SwapFloatLE = _nop SDL_SwapBE16 = SDL_Swap16 SDL_SwapBE32 = SDL_Swap32 SDL_SwapBE64 = SDL_Swap64 SDL_SwapFloatBE = SDL_SwapFloat else: SDL_SwapLE16 = SDL_Swap16 SDL_SwapLE32 = SDL_Swap32 SDL_SwapLE64 = SDL_Swap64 SDL_SwapFloatLE = SDL_SwapFloat SDL_SwapBE16 = _nop SDL_SwapBE32 = _nop SDL_SwapBE64 = _nop SDL_SwapFloatBE = _nop PySDL2-0.9.3/sdl2/error.py0000644000000000000000000000150612260256443012003 0ustar from ctypes import c_char_p, c_int from .dll import _bind __all__ = ["SDL_SetError", "SDL_GetError", "SDL_ClearError", "SDL_ENOMEM", "SDL_EFREAD", "SDL_EFWRITE", "SDL_EFSEEK", "SDL_UNSUPPORTED", "SDL_LASTERROR", "SDL_errorcode", "SDL_Error", "SDL_OutOfMemory", "SDL_Unsupported", "SDL_InvalidParamError" ] SDL_SetError = _bind("SDL_SetError", [c_char_p], c_int) SDL_GetError = _bind("SDL_GetError", None, c_char_p) SDL_ClearError = _bind("SDL_ClearError") SDL_ENOMEM = 0 SDL_EFREAD = 1 SDL_EFWRITE = 2 SDL_EFSEEK = 3 SDL_UNSUPPORTED = 4 SDL_LASTERROR = 5 SDL_errorcode = c_int SDL_Error = _bind("SDL_Error", [c_int], c_int) SDL_OutOfMemory = SDL_Error(SDL_ENOMEM) SDL_Unsupported = SDL_Error(SDL_UNSUPPORTED) SDL_InvalidParamError = lambda x: SDL_SetError("Parameter '%s' is invalid" % (x)) PySDL2-0.9.3/sdl2/events.py0000644000000000000000000003270612313765350012165 0ustar from ctypes import c_char, c_char_p, c_float, c_void_p, c_int, Structure, \ Union, CFUNCTYPE, POINTER from .dll import _bind from .stdinc import Sint16, Sint32, Uint8, Uint16, Uint32, SDL_bool from .keyboard import SDL_Keysym from .joystick import SDL_JoystickID from .touch import SDL_FingerID, SDL_TouchID from .gesture import SDL_GestureID __all__ = ["SDL_FIRSTEVENT", "SDL_QUIT", "SDL_APP_TERMINATING", "SDL_APP_LOWMEMORY", "SDL_APP_WILLENTERBACKGROUND", "SDL_APP_DIDENTERBACKGROUND", "SDL_APP_WILLENTERFOREGROUND", "SDL_APP_DIDENTERFOREGROUND", "SDL_WINDOWEVENT", "SDL_SYSWMEVENT", "SDL_KEYDOWN", "SDL_KEYUP", "SDL_TEXTEDITING", "SDL_TEXTINPUT", "SDL_MOUSEMOTION", "SDL_MOUSEBUTTONDOWN", "SDL_MOUSEBUTTONUP", "SDL_MOUSEWHEEL", "SDL_JOYAXISMOTION", "SDL_JOYBALLMOTION", "SDL_JOYHATMOTION", "SDL_JOYBUTTONDOWN", "SDL_JOYBUTTONUP", "SDL_JOYDEVICEADDED", "SDL_JOYDEVICEREMOVED", "SDL_CONTROLLERAXISMOTION", "SDL_CONTROLLERBUTTONDOWN", "SDL_CONTROLLERBUTTONUP", "SDL_CONTROLLERDEVICEADDED", "SDL_CONTROLLERDEVICEREMOVED", "SDL_CONTROLLERDEVICEREMAPPED", "SDL_FINGERDOWN", "SDL_FINGERUP", "SDL_FINGERMOTION", "SDL_DOLLARGESTURE", "SDL_DOLLARRECORD", "SDL_MULTIGESTURE", "SDL_CLIPBOARDUPDATE", "SDL_DROPFILE", "SDL_RENDER_TARGETS_RESET", "SDL_RENDER_DEVICE_RESET", "SDL_USEREVENT", "SDL_LASTEVENT", "SDL_EventType","SDL_GenericEvent", "SDL_WindowEvent", "SDL_KeyboardEvent", "SDL_TEXTEDITINGEVENT_TEXT_SIZE", "SDL_TextEditingEvent", "SDL_TEXTINPUTEVENT_TEXT_SIZE", "SDL_TextInputEvent", "SDL_MouseMotionEvent", "SDL_MouseButtonEvent", "SDL_MouseWheelEvent", "SDL_JoyAxisEvent", "SDL_JoyBallEvent", "SDL_JoyHatEvent", "SDL_JoyButtonEvent", "SDL_JoyDeviceEvent", "SDL_ControllerAxisEvent", "SDL_ControllerButtonEvent", "SDL_ControllerDeviceEvent", "SDL_TouchFingerEvent", "SDL_MultiGestureEvent", "SDL_DollarGestureEvent", "SDL_DropEvent", "SDL_QuitEvent", "SDL_UserEvent", "SDL_SysWMmsg", "SDL_SysWMEvent", "SDL_Event", "SDL_PumpEvents", "SDL_ADDEVENT", "SDL_PEEKEVENT", "SDL_GETEVENT", "SDL_eventaction", "SDL_PeepEvents", "SDL_HasEvent", "SDL_HasEvents", "SDL_FlushEvent", "SDL_FlushEvents", "SDL_PollEvent", "SDL_WaitEvent", "SDL_WaitEventTimeout", "SDL_PushEvent", "SDL_EventFilter", "SDL_SetEventFilter", "SDL_GetEventFilter", "SDL_AddEventWatch", "SDL_DelEventWatch", "SDL_FilterEvents", "SDL_QUERY", "SDL_IGNORE", "SDL_DISABLE", "SDL_ENABLE", "SDL_EventState", "SDL_GetEventState", "SDL_RegisterEvents", "SDL_QuitRequested" ] SDL_FIRSTEVENT = 0 SDL_QUIT = 0x100 SDL_APP_TERMINATING = 0x101 SDL_APP_LOWMEMORY = 0x102 SDL_APP_WILLENTERBACKGROUND = 0x103 SDL_APP_DIDENTERBACKGROUND = 0x104 SDL_APP_WILLENTERFOREGROUND = 0x105 SDL_APP_DIDENTERFOREGROUND = 0x106 SDL_WINDOWEVENT = 0x200 SDL_SYSWMEVENT = 0x201 SDL_KEYDOWN = 0x300 SDL_KEYUP = 0x301 SDL_TEXTEDITING = 0x302 SDL_TEXTINPUT = 0x303 SDL_MOUSEMOTION = 0x400 SDL_MOUSEBUTTONDOWN = 0x401 SDL_MOUSEBUTTONUP = 0x402 SDL_MOUSEWHEEL = 0x403 SDL_JOYAXISMOTION = 0x600 SDL_JOYBALLMOTION = 0x601 SDL_JOYHATMOTION = 0x602 SDL_JOYBUTTONDOWN = 0x603 SDL_JOYBUTTONUP = 0x604 SDL_JOYDEVICEADDED = 0x605 SDL_JOYDEVICEREMOVED = 0x606 SDL_CONTROLLERAXISMOTION = 0x650 SDL_CONTROLLERBUTTONDOWN = 0x651 SDL_CONTROLLERBUTTONUP = 0x652 SDL_CONTROLLERDEVICEADDED = 0x653 SDL_CONTROLLERDEVICEREMOVED = 0x654 SDL_CONTROLLERDEVICEREMAPPED = 0x655 SDL_FINGERDOWN = 0x700 SDL_FINGERUP = 0x701 SDL_FINGERMOTION = 0x702 SDL_DOLLARGESTURE = 0x800 SDL_DOLLARRECORD = 0x801 SDL_MULTIGESTURE = 0x802 SDL_CLIPBOARDUPDATE = 0x900 SDL_DROPFILE = 0x1000 SDL_RENDER_TARGETS_RESET = 0x2000 SDL_RENDER_DEVICE_RESET = 0x2001 SDL_USEREVENT = 0x8000 SDL_LASTEVENT = 0xFFFF SDL_EventType = c_int class SDL_GenericEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32)] class SDL_WindowEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("windowID", Uint32), ("event", Uint8), ("padding1", Uint8), ("padding2", Uint8), ("padding3", Uint8), ("data1", Sint32), ("data2", Sint32) ] class SDL_KeyboardEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("windowID", Uint32), ("state", Uint8), ("repeat", Uint8), ("padding2", Uint8), ("padding3", Uint8), ("keysym", SDL_Keysym) ] SDL_TEXTEDITINGEVENT_TEXT_SIZE = 32 class SDL_TextEditingEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("windowID", Uint32), ("text", (c_char * SDL_TEXTEDITINGEVENT_TEXT_SIZE)), ("start", Sint32), ("length", Sint32) ] SDL_TEXTINPUTEVENT_TEXT_SIZE = 32 class SDL_TextInputEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("windowID", Uint32), ("text", (c_char * SDL_TEXTINPUTEVENT_TEXT_SIZE)) ] class SDL_MouseMotionEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("windowID", Uint32), ("which", Uint32), ("state", Uint32), ("x", Sint32), ("y", Sint32), ("xrel", Sint32), ("yrel", Sint32) ] class SDL_MouseButtonEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("windowID", Uint32), ("which", Uint32), ("button", Uint8), ("state", Uint8), ("clicks", Uint8), ("padding1", Uint8), ("x", Sint32), ("y", Sint32) ] class SDL_MouseWheelEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("windowID", Uint32), ("which", Uint32), ("x", Sint32), ("y", Sint32) ] class SDL_JoyAxisEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("which", SDL_JoystickID), ("axis", Uint8), ("padding1", Uint8), ("padding2", Uint8), ("padding3", Uint8), ("value", Sint16), ("padding4", Uint16) ] class SDL_JoyBallEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("which", SDL_JoystickID), ("ball", Uint8), ("padding1", Uint8), ("padding2", Uint8), ("padding3", Uint8), ("xrel", Sint16), ("yrel", Sint16) ] class SDL_JoyHatEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("which", SDL_JoystickID), ("hat", Uint8), ("value", Uint8), ("padding1", Uint8), ("padding2", Uint8) ] class SDL_JoyButtonEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("which", SDL_JoystickID), ("button", Uint8), ("state", Uint8), ("padding1", Uint8), ("padding2", Uint8) ] class SDL_JoyDeviceEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("which", Sint32) ] class SDL_ControllerAxisEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("which", SDL_JoystickID), ("axis", Uint8), ("padding1", Uint8), ("padding2", Uint8), ("padding3", Uint8), ("value", Sint16), ("padding4", Uint16) ] class SDL_ControllerButtonEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("which", SDL_JoystickID), ("button", Uint8), ("state", Uint8), ("padding1", Uint8), ("padding2", Uint8) ] class SDL_ControllerDeviceEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("which", Sint32) ] class SDL_TouchFingerEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("touchId", SDL_TouchID), ("fingerId", SDL_FingerID), ("x", c_float), ("y", c_float), ("dx", c_float), ("dy", c_float), ("pressure", c_float) ] class SDL_MultiGestureEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("touchId", SDL_TouchID), ("dTheta", c_float), ("dDist", c_float), ("x", c_float), ("y", c_float), ("numFingers", Uint16), ("padding", Uint16) ] class SDL_DollarGestureEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("touchId", SDL_TouchID), ("gestureId", SDL_GestureID), ("numFingers", Uint32), ("error", c_float), ("x", c_float), ("y", c_float) ] class SDL_DropEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("file", c_char_p) ] class SDL_QuitEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32) ] class SDL_OSEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32) ] class SDL_UserEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("windowID", Uint32), ("code", Sint32), ("data1", c_void_p), ("data2", c_void_p) ] # TODO class SDL_SysWMmsg(Structure): pass class SDL_SysWMEvent(Structure): _fields_ = [("type", Uint32), ("timestamp", Uint32), ("msg", POINTER(SDL_SysWMmsg)) ] class SDL_Event(Union): _fields_ = [("type", Uint32), ("generic", SDL_GenericEvent), ("window", SDL_WindowEvent), ("key", SDL_KeyboardEvent), ("edit", SDL_TextEditingEvent), ("text", SDL_TextInputEvent), ("motion", SDL_MouseMotionEvent), ("button", SDL_MouseButtonEvent), ("wheel", SDL_MouseWheelEvent), ("jaxis", SDL_JoyAxisEvent), ("jball", SDL_JoyBallEvent), ("jhat", SDL_JoyHatEvent), ("jbutton", SDL_JoyButtonEvent), ("jdevice", SDL_JoyDeviceEvent), ("caxis", SDL_ControllerAxisEvent), ("cbutton", SDL_ControllerButtonEvent), ("cdevice", SDL_ControllerDeviceEvent), ("quit", SDL_QuitEvent), ("user", SDL_UserEvent), ("syswm", SDL_SysWMEvent), ("tfinger", SDL_TouchFingerEvent), ("mgesture", SDL_MultiGestureEvent), ("dgesture", SDL_DollarGestureEvent), ("drop", SDL_DropEvent), ("padding", (Uint8 * 56)), ] SDL_PumpEvents = _bind("SDL_PumpEvents") SDL_ADDEVENT = 0 SDL_PEEKEVENT = 1 SDL_GETEVENT = 2 SDL_eventaction = c_int SDL_PeepEvents = _bind("SDL_PeepEvents", [POINTER(SDL_Event), c_int, SDL_eventaction, Uint32, Uint32], c_int) SDL_HasEvent = _bind("SDL_HasEvent", [Uint32], SDL_bool) SDL_HasEvents = _bind("SDL_HasEvents", [Uint32, Uint32], SDL_bool) SDL_FlushEvent = _bind("SDL_FlushEvent", [Uint32]) SDL_FlushEvents = _bind("SDL_FlushEvents", [Uint32, Uint32]) SDL_PollEvent = _bind("SDL_PollEvent", [POINTER(SDL_Event)], c_int) SDL_WaitEvent = _bind("SDL_WaitEvent", [POINTER(SDL_Event)], c_int) SDL_WaitEventTimeout = _bind("SDL_WaitEventTimeout", [POINTER(SDL_Event), c_int], c_int) SDL_PushEvent = _bind("SDL_PushEvent", [POINTER(SDL_Event)], c_int) SDL_EventFilter = CFUNCTYPE(c_int, c_void_p, POINTER(SDL_Event)) SDL_SetEventFilter = _bind("SDL_SetEventFilter", [SDL_EventFilter, c_void_p]) SDL_GetEventFilter = _bind("SDL_GetEventFilter", [POINTER(SDL_EventFilter), POINTER(c_void_p)], SDL_bool) SDL_AddEventWatch = _bind("SDL_AddEventWatch", [SDL_EventFilter, c_void_p]) SDL_DelEventWatch = _bind("SDL_DelEventWatch", [SDL_EventFilter, c_void_p]) SDL_FilterEvents = _bind("SDL_FilterEvents", [SDL_EventFilter, c_void_p]) SDL_QUERY = -1 SDL_IGNORE = 0 SDL_DISABLE = 0 SDL_ENABLE = 1 SDL_EventState = _bind("SDL_EventState", [Uint32, c_int], Uint8) SDL_GetEventState = lambda t: SDL_EventState(t, SDL_QUERY) SDL_RegisterEvents = _bind("SDL_RegisterEvents", [c_int], Uint32) # SDL_quit.h def SDL_QuitRequested(): SDL_PumpEvents() return SDL_PeepEvents(None, 0, SDL_PEEKEVENT, SDL_QUIT, SDL_QUIT) > 0 PySDL2-0.9.3/sdl2/filesystem.py0000644000000000000000000000056412260256443013041 0ustar from ctypes import c_char, c_char_p, POINTER from .dll import _bind, nullfunc __all__ = ["SDL_GetBasePath", "SDL_GetPrefPath"] # The filesystem API came in after the 2.0 release SDL_GetBasePath = _bind("SDL_GetBasePath", None, POINTER(c_char), nullfunc) SDL_GetPrefPath = _bind("SDL_GetPrefPath", [c_char_p, c_char_p], POINTER(c_char), nullfunc) PySDL2-0.9.3/sdl2/gamecontroller.py0000644000000000000000000001415112323544617013672 0ustar from ctypes import Structure, Union, c_int, c_char_p, POINTER from .dll import _bind, nullfunc from .stdinc import SDL_bool, Sint16, Uint8 from .joystick import SDL_JoystickGUID, SDL_Joystick from .rwops import SDL_RWops, SDL_RWFromFile __all__ = ["SDL_GameController", "SDL_CONTROLLER_BINDTYPE_NONE", "SDL_CONTROLLER_BINDTYPE_BUTTON", "SDL_CONTROLLER_BINDTYPE_AXIS", "SDL_CONTROLLER_BINDTYPE_HAT", "SDL_GameControllerBindType", "SDL_GameControllerButtonBind", "SDL_GameControllerAddMapping", "SDL_GameControllerMappingForGUID", "SDL_GameControllerMapping", "SDL_IsGameController", "SDL_GameControllerNameForIndex", "SDL_GameControllerOpen", "SDL_GameControllerName", "SDL_GameControllerGetAttached", "SDL_GameControllerGetJoystick", "SDL_GameControllerEventState", "SDL_GameControllerUpdate", "SDL_CONTROLLER_AXIS_INVALID", "SDL_CONTROLLER_AXIS_LEFTX", "SDL_CONTROLLER_AXIS_LEFTY", "SDL_CONTROLLER_AXIS_RIGHTX", "SDL_CONTROLLER_AXIS_RIGHTY", "SDL_CONTROLLER_AXIS_TRIGGERLEFT", "SDL_CONTROLLER_AXIS_TRIGGERRIGHT", "SDL_CONTROLLER_AXIS_MAX", "SDL_GameControllerAxis", "SDL_GameControllerGetAxisFromString", "SDL_GameControllerGetStringForAxis", "SDL_GameControllerGetBindForAxis", "SDL_GameControllerGetAxis", "SDL_CONTROLLER_BUTTON_INVALID", "SDL_CONTROLLER_BUTTON_A", "SDL_CONTROLLER_BUTTON_B", "SDL_CONTROLLER_BUTTON_X", "SDL_CONTROLLER_BUTTON_Y", "SDL_CONTROLLER_BUTTON_BACK", "SDL_CONTROLLER_BUTTON_GUIDE", "SDL_CONTROLLER_BUTTON_START", "SDL_CONTROLLER_BUTTON_LEFTSTICK", "SDL_CONTROLLER_BUTTON_RIGHTSTICK", "SDL_CONTROLLER_BUTTON_LEFTSHOULDER", "SDL_CONTROLLER_BUTTON_RIGHTSHOULDER", "SDL_CONTROLLER_BUTTON_DPAD_UP", "SDL_CONTROLLER_BUTTON_DPAD_DOWN", "SDL_CONTROLLER_BUTTON_DPAD_LEFT", "SDL_CONTROLLER_BUTTON_DPAD_RIGHT", "SDL_CONTROLLER_BUTTON_MAX", "SDL_GameControllerButton", "SDL_GameControllerGetButtonFromString", "SDL_GameControllerGetStringForButton", "SDL_GameControllerGetBindForButton", "SDL_GameControllerGetButton", "SDL_GameControllerClose", "SDL_GameControllerAddMappingsFromFile", "SDL_GameControllerAddMappingsFromRW" ] class SDL_GameController(Structure): pass SDL_CONTROLLER_BINDTYPE_NONE = 0 SDL_CONTROLLER_BINDTYPE_BUTTON = 1 SDL_CONTROLLER_BINDTYPE_AXIS = 2 SDL_CONTROLLER_BINDTYPE_HAT = 3 SDL_GameControllerBindType = c_int class _gchat(Structure): _fields_ = [("hat", c_int), ("hat_mask", c_int)] class _gcvalue(Union): _fields_ = [("button", c_int), ("axis", c_int), ("hat", _gchat)] class SDL_GameControllerButtonBind(Structure): _fields_ = [("bindType", SDL_GameControllerBindType), ("value", _gcvalue)] SDL_GameControllerAddMapping = _bind("SDL_GameControllerAddMapping", [c_char_p], c_int) SDL_GameControllerMappingForGUID = _bind("SDL_GameControllerMappingForGUID", [SDL_JoystickGUID], c_char_p) SDL_GameControllerMapping = _bind("SDL_GameControllerMapping", [POINTER(SDL_GameController)], c_char_p) SDL_IsGameController = _bind("SDL_IsGameController", [c_int], SDL_bool) SDL_GameControllerNameForIndex = _bind("SDL_GameControllerNameForIndex", [c_int], c_char_p) SDL_GameControllerOpen = _bind("SDL_GameControllerOpen", [c_int], POINTER(SDL_GameController)) SDL_GameControllerName = _bind("SDL_GameControllerName", [POINTER(SDL_GameController)], c_char_p) SDL_GameControllerGetAttached = _bind("SDL_GameControllerGetAttached", [POINTER(SDL_GameController)], SDL_bool) SDL_GameControllerGetJoystick = _bind("SDL_GameControllerGetJoystick", [POINTER(SDL_GameController)], POINTER(SDL_Joystick)) SDL_GameControllerEventState = _bind("SDL_GameControllerEventState", [c_int], c_int) SDL_GameControllerUpdate = _bind("SDL_GameControllerUpdate") SDL_CONTROLLER_AXIS_INVALID = -1 SDL_CONTROLLER_AXIS_LEFTX = 0 SDL_CONTROLLER_AXIS_LEFTY = 1 SDL_CONTROLLER_AXIS_RIGHTX = 2 SDL_CONTROLLER_AXIS_RIGHTY = 3 SDL_CONTROLLER_AXIS_TRIGGERLEFT = 4 SDL_CONTROLLER_AXIS_TRIGGERRIGHT = 5 SDL_CONTROLLER_AXIS_MAX = 6 SDL_GameControllerAxis = c_int SDL_GameControllerGetAxisFromString = _bind("SDL_GameControllerGetAxisFromString", [c_char_p], SDL_GameControllerAxis) SDL_GameControllerGetStringForAxis = _bind("SDL_GameControllerGetStringForAxis", [SDL_GameControllerAxis], c_char_p) SDL_GameControllerGetBindForAxis = _bind("SDL_GameControllerGetBindForAxis", [POINTER(SDL_GameController), SDL_GameControllerAxis], SDL_GameControllerButtonBind) SDL_GameControllerGetAxis = _bind("SDL_GameControllerGetAxis", [POINTER(SDL_GameController), SDL_GameControllerAxis], Sint16) SDL_CONTROLLER_BUTTON_INVALID = -1 SDL_CONTROLLER_BUTTON_A = 0 SDL_CONTROLLER_BUTTON_B = 1 SDL_CONTROLLER_BUTTON_X = 2 SDL_CONTROLLER_BUTTON_Y = 3 SDL_CONTROLLER_BUTTON_BACK = 4 SDL_CONTROLLER_BUTTON_GUIDE = 5 SDL_CONTROLLER_BUTTON_START = 6 SDL_CONTROLLER_BUTTON_LEFTSTICK = 7 SDL_CONTROLLER_BUTTON_RIGHTSTICK = 8 SDL_CONTROLLER_BUTTON_LEFTSHOULDER = 9 SDL_CONTROLLER_BUTTON_RIGHTSHOULDER = 10 SDL_CONTROLLER_BUTTON_DPAD_UP = 11 SDL_CONTROLLER_BUTTON_DPAD_DOWN = 12 SDL_CONTROLLER_BUTTON_DPAD_LEFT = 13 SDL_CONTROLLER_BUTTON_DPAD_RIGHT = 14 SDL_CONTROLLER_BUTTON_MAX = 15 SDL_GameControllerButton = c_int SDL_GameControllerGetButtonFromString = _bind("SDL_GameControllerGetButtonFromString", [c_char_p], SDL_GameControllerButton) SDL_GameControllerGetStringForButton = _bind("SDL_GameControllerGetStringForButton", [SDL_GameControllerButton], c_char_p) SDL_GameControllerGetBindForButton = _bind("SDL_GameControllerGetBindForButton", [POINTER(SDL_GameController), SDL_GameControllerButton], SDL_GameControllerButtonBind) SDL_GameControllerGetButton = _bind("SDL_GameControllerGetButton", [POINTER(SDL_GameController), SDL_GameControllerButton], Uint8) SDL_GameControllerClose = _bind("SDL_GameControllerClose", [POINTER(SDL_GameController)]) SDL_GameControllerAddMappingsFromRW = _bind("SDL_GameControllerAddMappingsFromRW", [POINTER(SDL_RWops), c_int], c_int, nullfunc) SDL_GameControllerAddMappingsFromFile = lambda fname: SDL_GameControllerAddMappingsFromRW(SDL_RWFromFile(fname, b"rb"), 1) PySDL2-0.9.3/sdl2/gesture.py0000644000000000000000000000126112260256443012326 0ustar from ctypes import c_int, POINTER from .dll import _bind from .stdinc import Sint64 from .touch import SDL_TouchID from .rwops import SDL_RWops __all__ = ["SDL_GestureID", "SDL_RecordGesture", "SDL_SaveAllDollarTemplates", "SDL_SaveDollarTemplate", "SDL_LoadDollarTemplates" ] SDL_GestureID = Sint64 SDL_RecordGesture = _bind("SDL_RecordGesture", [SDL_TouchID], c_int) SDL_SaveAllDollarTemplates = _bind("SDL_SaveAllDollarTemplates", [POINTER(SDL_RWops)], c_int) SDL_SaveDollarTemplate = _bind("SDL_SaveDollarTemplate", [SDL_GestureID, POINTER(SDL_RWops)], c_int) SDL_LoadDollarTemplates = _bind("SDL_LoadDollarTemplates", [SDL_TouchID, POINTER(SDL_RWops)], c_int) PySDL2-0.9.3/sdl2/haptic.py0000644000000000000000000002055212260256443012124 0ustar from ctypes import Structure, Union, POINTER, c_int, c_uint, c_float, c_char_p from .dll import _bind from .stdinc import Uint8, Uint16, Uint32, Sint16, Sint32 from .joystick import SDL_Joystick __all__ = ["SDL_Haptic", "SDL_HAPTIC_CONSTANT", "SDL_HAPTIC_SINE", "SDL_HAPTIC_LEFTRIGHT", "SDL_HAPTIC_TRIANGLE", "SDL_HAPTIC_SAWTOOTHUP", "SDL_HAPTIC_SAWTOOTHDOWN", "SDL_HAPTIC_RAMP", "SDL_HAPTIC_SPRING", "SDL_HAPTIC_DAMPER", "SDL_HAPTIC_INERTIA", "SDL_HAPTIC_FRICTION", "SDL_HAPTIC_CUSTOM", "SDL_HAPTIC_GAIN", "SDL_HAPTIC_AUTOCENTER", "SDL_HAPTIC_STATUS", "SDL_HAPTIC_PAUSE", "SDL_HAPTIC_POLAR", "SDL_HAPTIC_CARTESIAN", "SDL_HAPTIC_SPHERICAL", "SDL_HAPTIC_INFINITY", "SDL_HapticDirection", "SDL_HapticConstant", "SDL_HapticPeriodic", "SDL_HapticCondition", "SDL_HapticRamp", "SDL_HapticCustom", "SDL_HapticLeftRight", "SDL_HapticEffect", "SDL_NumHaptics", "SDL_HapticName", "SDL_HapticOpen", "SDL_HapticOpened", "SDL_HapticIndex", "SDL_MouseIsHaptic", "SDL_HapticOpenFromMouse", "SDL_JoystickIsHaptic", "SDL_HapticOpenFromJoystick", "SDL_HapticClose", "SDL_HapticNumEffects", "SDL_HapticNumEffectsPlaying", "SDL_HapticQuery", "SDL_HapticNumAxes", "SDL_HapticEffectSupported", "SDL_HapticNewEffect", "SDL_HapticUpdateEffect", "SDL_HapticRunEffect", "SDL_HapticStopEffect", "SDL_HapticDestroyEffect", "SDL_HapticGetEffectStatus", "SDL_HapticSetGain", "SDL_HapticSetAutocenter", "SDL_HapticPause", "SDL_HapticUnpause", "SDL_HapticStopAll", "SDL_HapticRumbleSupported", "SDL_HapticRumbleInit", "SDL_HapticRumblePlay", "SDL_HapticRumbleStop" ] class SDL_Haptic(Structure): pass SDL_HAPTIC_CONSTANT = 1 << 0 SDL_HAPTIC_SINE = 1 << 1 SDL_HAPTIC_LEFTRIGHT = 1 << 2 SDL_HAPTIC_TRIANGLE = 1 << 3 SDL_HAPTIC_SAWTOOTHUP = 1 << 4 SDL_HAPTIC_SAWTOOTHDOWN = 1 << 5 SDL_HAPTIC_RAMP = 1 << 6 SDL_HAPTIC_SPRING = 1 << 7 SDL_HAPTIC_DAMPER = 1 << 8 SDL_HAPTIC_INERTIA = 1 << 9 SDL_HAPTIC_FRICTION = 1 << 10 SDL_HAPTIC_CUSTOM = 1 << 11 SDL_HAPTIC_GAIN = 1 << 12 SDL_HAPTIC_AUTOCENTER = 1 << 13 SDL_HAPTIC_STATUS = 1 << 14 SDL_HAPTIC_PAUSE = 1 << 15 SDL_HAPTIC_POLAR = 0 SDL_HAPTIC_CARTESIAN = 1 SDL_HAPTIC_SPHERICAL = 2 SDL_HAPTIC_INFINITY = 4294967295 class SDL_HapticDirection(Structure): _fields_ = [("type", Uint8), ("dir", (Sint32 * 3))] class SDL_HapticConstant(Structure): _fields_ = [("type", Uint16), ("direction", SDL_HapticDirection), ("length", Uint32), ("delay", Uint16), ("button", Uint16), ("interval", Uint16), ("level", Sint16), ("attack_length", Uint16), ("attack_level", Uint16), ("fade_length", Uint16), ("fade_level", Uint16), ] class SDL_HapticPeriodic(Structure): _fields_ = [("type", Uint16), ("direction", SDL_HapticDirection), ("length", Uint32), ("delay", Uint16), ("button", Uint16), ("interval", Uint16), ("period", Uint16), ("magnitude", Sint16), ("offset", Sint16), ("phase", Uint16), ("attack_length", Uint16), ("attack_level", Uint16), ("fade_length", Uint16), ("fade_level", Uint16), ] class SDL_HapticCondition(Structure): """A conditionally running effect.""" _fields_ = [("type", Uint16), ("direction", SDL_HapticDirection), ("length", Uint32), ("delay", Uint16), ("button", Uint16), ("interval", Uint16), ("right_sat", (Uint16 * 3)), ("left_sat", (Uint16 * 3)), ("right_coeff", (Sint16 * 3)), ("left_coeff", (Sint16 * 3)), ("deadband", (Uint16 * 3)), ("center", (Sint16 * 3)), ] class SDL_HapticRamp(Structure): """A ramp-like effect.""" _fields_ = [("type", Uint16), ("direction", SDL_HapticDirection), ("length", Uint32), ("delay", Uint16), ("button", Uint16), ("interval", Uint16), ("start", Sint16), ("end", Sint16), ("attack_length", Uint16), ("attack_level", Uint16), ("fade_length", Uint16), ("fade_level", Uint16), ] class SDL_HapticLeftRight(Structure): """A left-right effect.""" _fields_ = [("type", Uint16), ("length", Uint32), ("large_magnitude", Uint16), ("small_magnitude", Uint16) ] class SDL_HapticCustom(Structure): """A custom effect.""" _fields_ = [("type", Uint16), ("direction", SDL_HapticDirection), ("length", Uint32), ("delay", Uint16), ("button", Uint16), ("interval", Uint16), ("channels", Uint8), ("period", Uint16), ("samples", Uint16), ("data", POINTER(Uint16)), ("attack_length", Uint16), ("attack_level", Uint16), ("fade_length", Uint16), ("fade_level", Uint16), ] class SDL_HapticEffect(Union): """A generic haptic effect, containing the concrete haptic effect.""" _fields_ = [("type", Uint16), ("constant", SDL_HapticConstant), ("periodic", SDL_HapticPeriodic), ("condition", SDL_HapticCondition), ("ramp", SDL_HapticRamp), ("custom", SDL_HapticCustom), ] SDL_NumHaptics = _bind("SDL_NumHaptics", None, c_int) SDL_HapticName = _bind("SDL_HapticName", [c_int], c_char_p) SDL_HapticOpen = _bind("SDL_HapticOpen", [c_int], POINTER(SDL_Haptic)) SDL_HapticOpened = _bind("SDL_HapticOpened", [c_int], c_int) SDL_HapticIndex = _bind("SDL_HapticIndex", [POINTER(SDL_Haptic)], c_int) SDL_MouseIsHaptic = _bind("SDL_MouseIsHaptic", None, c_int) SDL_HapticOpenFromMouse = _bind("SDL_HapticOpenFromMouse", None, POINTER(SDL_Haptic)) SDL_JoystickIsHaptic = _bind("SDL_JoystickIsHaptic", [POINTER(SDL_Joystick)], c_int) SDL_HapticOpenFromJoystick = _bind("SDL_HapticOpenFromJoystick", [POINTER(SDL_Joystick)], POINTER(SDL_Haptic)) SDL_HapticClose = _bind("SDL_HapticClose", [POINTER(SDL_Haptic)]) SDL_HapticNumEffects = _bind("SDL_HapticNumEffects", [POINTER(SDL_Haptic)], c_int) SDL_HapticNumEffectsPlaying = _bind("SDL_HapticNumEffectsPlaying", [POINTER(SDL_Haptic)], c_int) SDL_HapticQuery = _bind("SDL_HapticQuery", [POINTER(SDL_Haptic)], c_uint) SDL_HapticNumAxes = _bind("SDL_HapticNumAxes", [POINTER(SDL_Haptic)], c_int) SDL_HapticEffectSupported = _bind("SDL_HapticEffectSupported", [POINTER(SDL_Haptic), POINTER(SDL_HapticEffect)], c_int) SDL_HapticNewEffect = _bind("SDL_HapticNewEffect", [POINTER(SDL_Haptic), POINTER(SDL_HapticEffect)], c_int) SDL_HapticUpdateEffect = _bind("SDL_HapticUpdateEffect", [POINTER(SDL_Haptic), c_int, POINTER(SDL_HapticEffect)], c_int) SDL_HapticRunEffect = _bind("SDL_HapticRunEffect", [POINTER(SDL_Haptic), c_int, Uint32], c_int) SDL_HapticStopEffect = _bind("SDL_HapticStopEffect", [POINTER(SDL_Haptic), c_int], c_int) SDL_HapticDestroyEffect = _bind("SDL_HapticDestroyEffect", [POINTER(SDL_Haptic), c_int]) SDL_HapticGetEffectStatus = _bind("SDL_HapticGetEffectStatus", [POINTER(SDL_Haptic), c_int], c_int) SDL_HapticSetGain = _bind("SDL_HapticSetGain", [POINTER(SDL_Haptic), c_int], c_int) SDL_HapticSetAutocenter = _bind("SDL_HapticSetAutocenter", [POINTER(SDL_Haptic), c_int], c_int) SDL_HapticPause = _bind("SDL_HapticPause", [POINTER(SDL_Haptic)], c_int) SDL_HapticUnpause = _bind("SDL_HapticUnpause", [POINTER(SDL_Haptic)], c_int) SDL_HapticStopAll = _bind("SDL_HapticStopAll", [POINTER(SDL_Haptic)], c_int) SDL_HapticRumbleSupported = _bind("SDL_HapticRumbleSupported", [POINTER(SDL_Haptic)], c_int) SDL_HapticRumbleInit = _bind("SDL_HapticRumbleInit", [POINTER(SDL_Haptic)], c_int) SDL_HapticRumblePlay = _bind("SDL_HapticRumblePlay", [POINTER(SDL_Haptic), c_float, Uint32], c_int) SDL_HapticRumbleStop = _bind("SDL_HapticRumbleStop", [POINTER(SDL_Haptic)], c_int) PySDL2-0.9.3/sdl2/hints.py0000644000000000000000000001143712356436516012012 0ustar from ctypes import CFUNCTYPE, c_int, c_char_p, c_void_p from .dll import _bind from .stdinc import SDL_bool __all__ = ["SDL_HINT_FRAMEBUFFER_ACCELERATION", "SDL_HINT_RENDER_DRIVER", "SDL_HINT_RENDER_OPENGL_SHADERS", "SDL_HINT_RENDER_SCALE_QUALITY", "SDL_HINT_RENDER_VSYNC", "SDL_HINT_VIDEO_X11_XVIDMODE", "SDL_HINT_VIDEO_X11_XINERAMA", "SDL_HINT_VIDEO_X11_XRANDR", "SDL_HINT_GRAB_KEYBOARD", "SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS", "SDL_HINT_IDLE_TIMER_DISABLED", "SDL_HINT_ORIENTATIONS", "SDL_HINT_XINPUT_ENABLED", "SDL_HINT_GAMECONTROLLERCONFIG", "SDL_HINT_ALLOW_TOPMOST", "SDL_HINT_DEFAULT", "SDL_HINT_NORMAL", "SDL_HINT_OVERRIDE", "SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS", "SDL_HINT_VIDEO_HIGHDPI_DISABLED", "SDL_HINT_ACCELEROMETER_AS_JOYSTICK", "SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK", "SDL_HINT_RENDER_DIRECT3D_THREADSAFE", "SDL_HINT_VIDEO_FULLSCREEN_SPACES", "SDL_HINT_MOUSE_RELATIVE_MODE_WARP", "SDL_HINT_VIDEO_WIN_D3DCOMPILER", "SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT", "SDL_HINT_VIDEO_ALLOW_SCREENSAVER", "SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES", "SDL_HINT_RENDER_DIRECT3D11_DEBUG", "SDL_HINT_WINRT_PRIVACY_POLICY_URL", "SDL_HINT_WINRT_PRIVACY_POLICY_LABEL", "SDL_HINT_WINRT_HANDLE_BACK_BUTTON", "SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN", "SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP", "SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION", "SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION", "SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING", "SDL_HintPriority", "SDL_SetHintWithPriority", "SDL_SetHint", "SDL_GetHint", "SDL_ClearHints" ] SDL_HINT_FRAMEBUFFER_ACCELERATION = b"SDL_FRAMEBUFFER_ACCELERATION" SDL_HINT_RENDER_DRIVER = b"SDL_RENDER_DRIVER" SDL_HINT_RENDER_OPENGL_SHADERS = b"SDL_RENDER_OPENGL_SHADERS" SDL_HINT_RENDER_SCALE_QUALITY = b"SDL_RENDER_SCALE_QUALITY" SDL_HINT_RENDER_VSYNC = b"SDL_RENDER_VSYNC" SDL_HINT_VIDEO_X11_XVIDMODE = b"SDL_VIDEO_X11_XVIDMODE" SDL_HINT_VIDEO_X11_XINERAMA = b"SDL_VIDEO_X11_XINERAMA" SDL_HINT_VIDEO_X11_XRANDR = b"SDL_VIDEO_X11_XRANDR" SDL_HINT_GRAB_KEYBOARD = b"SDL_GRAB_KEYBOARD" SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS = b"SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS" SDL_HINT_VIDEO_FULLSCREEN_SPACES = b"SDL_VIDEO_FULLSCREEN_SPACES" SDL_HINT_IDLE_TIMER_DISABLED = b"SDL_IOS_IDLE_TIMER_DISABLED" SDL_HINT_ORIENTATIONS = b"SDL_IOS_ORIENTATIONS" SDL_HINT_ACCELEROMETER_AS_JOYSTICK = b"SDL_ACCELEROMETER_AS_JOYSTICK" SDL_HINT_XINPUT_ENABLED = b"SDL_XINPUT_ENABLED" SDL_HINT_GAMECONTROLLERCONFIG = b"SDL_GAMECONTROLLERCONFIG" SDL_HINT_ALLOW_TOPMOST = b"SDL_ALLOW_TOPMOST" SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS = b"SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS" SDL_HINT_TIMER_RESOLUTION = b"SDL_TIMER_RESOLUTION" SDL_HINT_VIDEO_HIGHDPI_DISABLED = b"SDL_VIDEO_HIGHDPI_DISABLED" SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK = b"SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK" SDL_HINT_RENDER_DIRECT3D_THREADSAFE = b"SDL_RENDER_DIRECT3D_THREADSAFE" SDL_HINT_MOUSE_RELATIVE_MODE_WARP = b"SDL_MOUSE_RELATIVE_MODE_WARP" SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT = b"SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT" SDL_HINT_VIDEO_ALLOW_SCREENSAVER = b"SDL_VIDEO_ALLOW_SCREENSAVER" SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES = b"SDL_VIDEO_MAC_FULLSCREEN_SPACES" SDL_HINT_VIDEO_WIN_D3DCOMPILER = b"SDL_VIDEO_WIN_D3DCOMPILER" SDL_HINT_RENDER_DIRECT3D11_DEBUG = b"SDL_RENDER_DIRECT3D11_DEBUG" SDL_HINT_WINRT_PRIVACY_POLICY_URL = b"SDL_WINRT_PRIVACY_POLICY_URL" SDL_HINT_WINRT_PRIVACY_POLICY_LABEL = b"SDL_WINRT_PRIVACY_POLICY_LABEL" SDL_HINT_WINRT_HANDLE_BACK_BUTTON = b"SDL_WINRT_HANDLE_BACK_BUTTON" SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN = b"SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN" SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP = b"SDL_WINDOWS_ENABLE_MESSAGELOOP" SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION = b"SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION" SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION = b"SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION" SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING = b"SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING" SDL_HINT_DEFAULT = 0 SDL_HINT_NORMAL = 1 SDL_HINT_OVERRIDE = 2 SDL_HintPriority = c_int SDL_SetHintWithPriority = _bind("SDL_SetHintWithPriority", [c_char_p, c_char_p, SDL_HintPriority], SDL_bool) SDL_SetHint = _bind("SDL_SetHint", [c_char_p, c_char_p], SDL_bool) SDL_GetHint = _bind("SDL_GetHint", [c_char_p], c_char_p) SDL_ClearHints = _bind("SDL_ClearHints") SDL_HintCallback = CFUNCTYPE(None, c_void_p, c_char_p, c_char_p, c_char_p) SDL_AddHintCallback = _bind("SDL_AddHintCallback", [c_char_p, SDL_HintCallback, c_void_p]) SDL_DelHintCallback = _bind("SDL_DelHintCallback",[c_char_p, SDL_HintCallback, c_void_p]) PySDL2-0.9.3/sdl2/joystick.py0000644000000000000000000000625512260256443012517 0ustar from ctypes import Structure, c_int, c_char_p, POINTER from .dll import _bind from .stdinc import Sint16, Sint32, Uint8, SDL_bool __all__ = ["SDL_Joystick", "SDL_JoystickGUID", "SDL_JoystickID", "SDL_NumJoysticks", "SDL_JoystickNameForIndex", "SDL_JoystickOpen", "SDL_JoystickName", "SDL_JoystickGetDeviceGUID", "SDL_JoystickGetGUID", "SDL_JoystickGetGUIDString", "SDL_JoystickGetGUIDFromString", "SDL_JoystickGetAttached", "SDL_JoystickInstanceID", "SDL_JoystickNumAxes", "SDL_JoystickNumBalls", "SDL_JoystickNumHats", "SDL_JoystickNumButtons", "SDL_JoystickUpdate", "SDL_JoystickEventState", "SDL_JoystickGetAxis", "SDL_HAT_CENTERED", "SDL_HAT_UP", "SDL_HAT_RIGHT", "SDL_HAT_DOWN", "SDL_HAT_LEFT", "SDL_HAT_RIGHTUP", "SDL_HAT_RIGHTDOWN", "SDL_HAT_LEFTUP", "SDL_HAT_LEFTDOWN", "SDL_JoystickGetHat", "SDL_JoystickGetBall", "SDL_JoystickGetButton", "SDL_JoystickClose" ] class SDL_Joystick(Structure): pass class SDL_JoystickGUID(Structure): _fields_ = [("data", (Uint8 * 16))] SDL_JoystickID = Sint32 SDL_NumJoysticks = _bind("SDL_NumJoysticks", None, c_int) SDL_JoystickNameForIndex = _bind("SDL_JoystickNameForIndex", [c_int], c_char_p) SDL_JoystickOpen = _bind("SDL_JoystickOpen", [c_int], POINTER(SDL_Joystick)) SDL_JoystickName = _bind("SDL_JoystickName", [POINTER(SDL_Joystick)], c_char_p) SDL_JoystickGetDeviceGUID = _bind("SDL_JoystickGetDeviceGUID", [c_int], SDL_JoystickGUID) SDL_JoystickGetGUID = _bind("SDL_JoystickGetGUID", [POINTER(SDL_Joystick)], SDL_JoystickGUID) SDL_JoystickGetGUIDString = _bind("SDL_JoystickGetGUIDString", [SDL_JoystickGUID, c_char_p, c_int]) SDL_JoystickGetGUIDFromString = _bind("SDL_JoystickGetGUIDFromString", [c_char_p], SDL_JoystickGUID) SDL_JoystickGetAttached = _bind("SDL_JoystickGetAttached", [POINTER(SDL_Joystick)], SDL_bool) SDL_JoystickInstanceID = _bind("SDL_JoystickInstanceID", [POINTER(SDL_Joystick)], SDL_JoystickID) SDL_JoystickNumAxes = _bind("SDL_JoystickNumAxes", [POINTER(SDL_Joystick)], c_int) SDL_JoystickNumBalls = _bind("SDL_JoystickNumBalls", [POINTER(SDL_Joystick)], c_int) SDL_JoystickNumHats = _bind("SDL_JoystickNumHats", [POINTER(SDL_Joystick)], c_int) SDL_JoystickNumButtons = _bind("SDL_JoystickNumButtons", [POINTER(SDL_Joystick)], c_int) SDL_JoystickUpdate = _bind("SDL_JoystickUpdate") SDL_JoystickEventState = _bind("SDL_JoystickEventState", [c_int], c_int) SDL_JoystickGetAxis = _bind("SDL_JoystickGetAxis", [POINTER(SDL_Joystick), c_int], Sint16) SDL_HAT_CENTERED = 0x00 SDL_HAT_UP = 0x01 SDL_HAT_RIGHT = 0x02 SDL_HAT_DOWN = 0x04 SDL_HAT_LEFT = 0x08 SDL_HAT_RIGHTUP = SDL_HAT_RIGHT | SDL_HAT_UP SDL_HAT_RIGHTDOWN = SDL_HAT_RIGHT | SDL_HAT_DOWN SDL_HAT_LEFTUP = SDL_HAT_LEFT | SDL_HAT_UP SDL_HAT_LEFTDOWN = SDL_HAT_LEFT | SDL_HAT_DOWN SDL_JoystickGetHat = _bind("SDL_JoystickGetHat", [POINTER(SDL_Joystick), c_int], Uint8) SDL_JoystickGetBall = _bind("SDL_JoystickGetBall", [POINTER(SDL_Joystick), c_int, POINTER(c_int), POINTER(c_int)], c_int) SDL_JoystickGetButton = _bind("SDL_JoystickGetButton", [POINTER(SDL_Joystick), c_int], Uint8) SDL_JoystickClose = _bind("SDL_JoystickClose", [POINTER(SDL_Joystick)]) PySDL2-0.9.3/sdl2/keyboard.py0000644000000000000000000000412512260256443012452 0ustar from ctypes import Structure, c_int, c_char_p, POINTER from .dll import _bind from .stdinc import Uint8, Uint16, Uint32, SDL_bool from .keycode import SDL_Keycode, SDL_Keymod from .scancode import SDL_Scancode from .rect import SDL_Rect from .video import SDL_Window __all__ = ["SDL_Keysym", "SDL_GetKeyboardFocus", "SDL_GetKeyboardState", "SDL_GetModState", "SDL_SetModState", "SDL_GetKeyFromScancode", "SDL_GetScancodeFromKey", "SDL_GetScancodeName", "SDL_GetScancodeFromName", "SDL_GetKeyName", "SDL_GetKeyFromName", "SDL_StartTextInput", "SDL_IsTextInputActive", "SDL_StopTextInput", "SDL_SetTextInputRect", "SDL_HasScreenKeyboardSupport", "SDL_IsScreenKeyboardShown" ] class SDL_Keysym(Structure): _fields_ = [("scancode", SDL_Scancode), ("sym", SDL_Keycode), ("mod", Uint16), ("unicode", Uint32) ] SDL_GetKeyboardFocus = _bind("SDL_GetKeyboardFocus", None, POINTER(SDL_Window)) SDL_GetKeyboardState = _bind("SDL_GetKeyboardState", [POINTER(c_int)], POINTER(Uint8)) SDL_GetModState = _bind("SDL_GetModState", None, SDL_Keymod) SDL_SetModState = _bind("SDL_SetModState", [SDL_Keymod]) SDL_GetKeyFromScancode = _bind("SDL_GetKeyFromScancode", [SDL_Scancode], SDL_Keycode) SDL_GetScancodeFromKey = _bind("SDL_GetScancodeFromKey", [SDL_Keycode], SDL_Scancode) SDL_GetScancodeName = _bind("SDL_GetScancodeName", [SDL_Scancode], c_char_p) SDL_GetScancodeFromName = _bind("SDL_GetScancodeFromName", [c_char_p], SDL_Scancode) SDL_GetKeyName = _bind("SDL_GetKeyName", [SDL_Keycode], c_char_p) SDL_GetKeyFromName = _bind("SDL_GetKeyFromName", [c_char_p], SDL_Keycode) SDL_StartTextInput = _bind("SDL_StartTextInput") SDL_IsTextInputActive = _bind("SDL_IsTextInputActive", None, SDL_bool) SDL_StopTextInput = _bind("SDL_StopTextInput") SDL_SetTextInputRect = _bind("SDL_SetTextInputRect", [POINTER(SDL_Rect)]) SDL_HasScreenKeyboardSupport = _bind("SDL_HasScreenKeyboardSupport", None, SDL_bool) SDL_IsScreenKeyboardShown = _bind("SDL_IsScreenKeyboardShown", [POINTER(SDL_Window)], SDL_bool) PySDL2-0.9.3/sdl2/keycode.py0000644000000000000000000002761212260256443012303 0ustar from .stdinc import Sint32 from .scancode import * SDL_Keycode = Sint32 SDLK_SCANCODE_MASK = 1 << 30 SDL_SCANCODE_TO_KEYCODE = lambda x: (x | SDLK_SCANCODE_MASK) SDL_Keymod = c_int KMOD_NONE = 0x0000 KMOD_LSHIFT = 0x0001 KMOD_RSHIFT = 0x0002 KMOD_LCTRL = 0x0040 KMOD_RCTRL = 0x0080 KMOD_LALT = 0x0100 KMOD_RALT = 0x0200 KMOD_LGUI = 0x0400 KMOD_RGUI = 0x0800 KMOD_NUM = 0x1000 KMOD_CAPS = 0x2000 KMOD_MODE = 0x4000 KMOD_RESERVED = 0x8000 KMOD_CTRL = KMOD_LCTRL | KMOD_RCTRL KMOD_SHIFT = KMOD_LSHIFT | KMOD_RSHIFT KMOD_ALT = KMOD_LALT | KMOD_RALT KMOD_GUI = KMOD_LGUI | KMOD_RGUI SDLK_UNKNOWN = 0 SDLK_RETURN = ord('\r') SDLK_ESCAPE = ord('\033') SDLK_BACKSPACE = ord('\b') SDLK_TAB = ord('\t') SDLK_SPACE = ord(' ') SDLK_EXCLAIM = ord('!') SDLK_QUOTEDBL = ord('"') SDLK_HASH = ord('#') SDLK_PERCENT = ord('%') SDLK_DOLLAR = ord('$') SDLK_AMPERSAND = ord('&') SDLK_QUOTE = ord('\'') SDLK_LEFTPAREN = ord('(') SDLK_RIGHTPAREN = ord(')') SDLK_ASTERISK = ord('*') SDLK_PLUS = ord('+') SDLK_COMMA = ord(',') SDLK_MINUS = ord('-') SDLK_PERIOD = ord('.') SDLK_SLASH = ord('/') SDLK_0 = ord('0') SDLK_1 = ord('1') SDLK_2 = ord('2') SDLK_3 = ord('3') SDLK_4 = ord('4') SDLK_5 = ord('5') SDLK_6 = ord('6') SDLK_7 = ord('7') SDLK_8 = ord('8') SDLK_9 = ord('9') SDLK_COLON = ord(':') SDLK_SEMICOLON = ord(';') SDLK_LESS = ord('<') SDLK_EQUALS = ord('=') SDLK_GREATER = ord('>') SDLK_QUESTION = ord('?') SDLK_AT = ord('@') SDLK_LEFTBRACKET = ord('[') SDLK_BACKSLASH = ord('\\') SDLK_RIGHTBRACKET = ord(']') SDLK_CARET = ord('^') SDLK_UNDERSCORE = ord('_') SDLK_BACKQUOTE = ord('`') SDLK_a = ord('a') SDLK_b = ord('b') SDLK_c = ord('c') SDLK_d = ord('d') SDLK_e = ord('e') SDLK_f = ord('f') SDLK_g = ord('g') SDLK_h = ord('h') SDLK_i = ord('i') SDLK_j = ord('j') SDLK_k = ord('k') SDLK_l = ord('l') SDLK_m = ord('m') SDLK_n = ord('n') SDLK_o = ord('o') SDLK_p = ord('p') SDLK_q = ord('q') SDLK_r = ord('r') SDLK_s = ord('s') SDLK_t = ord('t') SDLK_u = ord('u') SDLK_v = ord('v') SDLK_w = ord('w') SDLK_x = ord('x') SDLK_y = ord('y') SDLK_z = ord('z') SDLK_CAPSLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CAPSLOCK) SDLK_F1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F1) SDLK_F2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F2) SDLK_F3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F3) SDLK_F4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F4) SDLK_F5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F5) SDLK_F6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F6) SDLK_F7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F7) SDLK_F8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F8) SDLK_F9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F9) SDLK_F10 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F10) SDLK_F11 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F11) SDLK_F12 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F12) SDLK_PRINTSCREEN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRINTSCREEN) SDLK_SCROLLLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SCROLLLOCK) SDLK_PAUSE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAUSE) SDLK_INSERT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_INSERT) SDLK_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HOME) SDLK_PAGEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEUP) SDLK_DELETE = ord('\177') SDLK_END = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_END) SDLK_PAGEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEDOWN) SDLK_RIGHT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RIGHT) SDLK_LEFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LEFT) SDLK_DOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DOWN) SDLK_UP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UP) SDLK_NUMLOCKCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_NUMLOCKCLEAR) SDLK_KP_DIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DIVIDE) SDLK_KP_MULTIPLY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MULTIPLY) SDLK_KP_MINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MINUS) SDLK_KP_PLUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUS) SDLK_KP_ENTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_ENTER) SDLK_KP_1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_1) SDLK_KP_2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_2) SDLK_KP_3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_3) SDLK_KP_4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_4) SDLK_KP_5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_5) SDLK_KP_6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_6) SDLK_KP_7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_7) SDLK_KP_8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_8) SDLK_KP_9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_9) SDLK_KP_0 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_0) SDLK_KP_PERIOD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERIOD) SDLK_APPLICATION = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APPLICATION) SDLK_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_POWER) SDLK_KP_EQUALS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALS) SDLK_F13 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F13) SDLK_F14 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F14) SDLK_F15 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F15) SDLK_F16 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F16) SDLK_F17 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F17) SDLK_F18 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F18) SDLK_F19 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F19) SDLK_F20 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F20) SDLK_F21 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F21) SDLK_F22 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F22) SDLK_F23 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F23) SDLK_F24 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F24) SDLK_EXECUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXECUTE) SDLK_HELP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HELP) SDLK_MENU = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MENU) SDLK_SELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SELECT) SDLK_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_STOP) SDLK_AGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AGAIN) SDLK_UNDO = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UNDO) SDLK_CUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CUT) SDLK_COPY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COPY) SDLK_PASTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PASTE) SDLK_FIND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_FIND) SDLK_MUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MUTE) SDLK_VOLUMEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEUP) SDLK_VOLUMEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEDOWN) SDLK_KP_COMMA = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COMMA) SDLK_KP_EQUALSAS400 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALSAS400) SDLK_ALTERASE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ALTERASE) SDLK_SYSREQ = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SYSREQ) SDLK_CANCEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CANCEL) SDLK_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEAR) SDLK_PRIOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRIOR) SDLK_RETURN2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RETURN2) SDLK_SEPARATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SEPARATOR) SDLK_OUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OUT) SDLK_OPER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OPER) SDLK_CLEARAGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEARAGAIN) SDLK_CRSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CRSEL) SDLK_EXSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXSEL) SDLK_KP_00 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_00) SDLK_KP_000 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_000) SDLK_THOUSANDSSEPARATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_THOUSANDSSEPARATOR) SDLK_DECIMALSEPARATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DECIMALSEPARATOR) SDLK_CURRENCYUNIT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYUNIT) SDLK_CURRENCYSUBUNIT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYSUBUNIT) SDLK_KP_LEFTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTPAREN) SDLK_KP_RIGHTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTPAREN) SDLK_KP_LEFTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTBRACE) SDLK_KP_RIGHTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTBRACE) SDLK_KP_TAB = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_TAB) SDLK_KP_BACKSPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BACKSPACE) SDLK_KP_A = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_A) SDLK_KP_B = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_B) SDLK_KP_C = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_C) SDLK_KP_D = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_D) SDLK_KP_E = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_E) SDLK_KP_F = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_F) SDLK_KP_XOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_XOR) SDLK_KP_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_POWER) SDLK_KP_PERCENT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERCENT) SDLK_KP_LESS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LESS) SDLK_KP_GREATER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_GREATER) SDLK_KP_AMPERSAND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AMPERSAND) SDLK_KP_DBLAMPERSAND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLAMPERSAND) SDLK_KP_VERTICALBAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_VERTICALBAR) SDLK_KP_DBLVERTICALBAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLVERTICALBAR) SDLK_KP_COLON = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COLON) SDLK_KP_HASH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HASH) SDLK_KP_SPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_SPACE) SDLK_KP_AT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AT) SDLK_KP_EXCLAM = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EXCLAM) SDLK_KP_MEMSTORE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSTORE) SDLK_KP_MEMRECALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMRECALL) SDLK_KP_MEMCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMCLEAR) SDLK_KP_MEMADD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMADD) SDLK_KP_MEMSUBTRACT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSUBTRACT) SDLK_KP_MEMMULTIPLY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMMULTIPLY) SDLK_KP_MEMDIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMDIVIDE) SDLK_KP_PLUSMINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUSMINUS) SDLK_KP_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEAR) SDLK_KP_CLEARENTRY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEARENTRY) SDLK_KP_BINARY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BINARY) SDLK_KP_OCTAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_OCTAL) SDLK_KP_DECIMAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DECIMAL) SDLK_KP_HEXADECIMAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HEXADECIMAL) SDLK_LCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LCTRL) SDLK_LSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LSHIFT) SDLK_LALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LALT) SDLK_LGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LGUI) SDLK_RCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RCTRL) SDLK_RSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RSHIFT) SDLK_RALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RALT) SDLK_RGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RGUI) SDLK_MODE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MODE) SDLK_AUDIONEXT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIONEXT) SDLK_AUDIOPREV = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPREV) SDLK_AUDIOSTOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOSTOP) SDLK_AUDIOPLAY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPLAY) SDLK_AUDIOMUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOMUTE) SDLK_MEDIASELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIASELECT) SDLK_WWW = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_WWW) SDLK_MAIL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MAIL) SDLK_CALCULATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALCULATOR) SDLK_COMPUTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COMPUTER) SDLK_AC_SEARCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_SEARCH) SDLK_AC_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_HOME) SDLK_AC_BACK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BACK) SDLK_AC_FORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_FORWARD) SDLK_AC_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_STOP) SDLK_AC_REFRESH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_REFRESH) SDLK_AC_BOOKMARKS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BOOKMARKS) SDLK_BRIGHTNESSDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSDOWN) SDLK_BRIGHTNESSUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSUP) SDLK_DISPLAYSWITCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DISPLAYSWITCH) SDLK_KBDILLUMTOGGLE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMTOGGLE) SDLK_KBDILLUMDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMDOWN) SDLK_KBDILLUMUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMUP) SDLK_EJECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EJECT) SDLK_SLEEP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SLEEP) PySDL2-0.9.3/sdl2/loadso.py0000644000000000000000000000051112277225122012124 0ustar from ctypes import c_char_p, c_void_p from .dll import _bind __all__ = ["SDL_LoadObject", "SDL_LoadFunction", "SDL_UnloadObject"] SDL_LoadObject = _bind("SDL_LoadObject", [c_char_p], c_void_p) SDL_LoadFunction = _bind("SDL_LoadFunction", [c_void_p, c_char_p], c_void_p) SDL_UnloadObject = _bind("SDL_UnloadObject", [c_void_p]) PySDL2-0.9.3/sdl2/log.py0000644000000000000000000000641212260256443011434 0ustar from ctypes import c_int, c_char_p, c_void_p, CFUNCTYPE, POINTER, py_object from .dll import _bind __all__ = ["SDL_MAX_LOG_MESSAGE", "SDL_LOG_CATEGORY_APPLICATION", "SDL_LOG_CATEGORY_ERROR", "SDL_LOG_CATEGORY_ASSERT", "SDL_LOG_CATEGORY_SYSTEM", "SDL_LOG_CATEGORY_AUDIO", "SDL_LOG_CATEGORY_VIDEO", "SDL_LOG_CATEGORY_RENDER", "SDL_LOG_CATEGORY_INPUT", "SDL_LOG_CATEGORY_TEST", "SDL_LOG_CATEGORY_RESERVED1", "SDL_LOG_CATEGORY_RESERVED2", "SDL_LOG_CATEGORY_RESERVED3", "SDL_LOG_CATEGORY_RESERVED4", "SDL_LOG_CATEGORY_RESERVED5", "SDL_LOG_CATEGORY_RESERVED6", "SDL_LOG_CATEGORY_RESERVED7", "SDL_LOG_CATEGORY_RESERVED8", "SDL_LOG_CATEGORY_RESERVED9", "SDL_LOG_CATEGORY_RESERVED10", "SDL_LOG_CATEGORY_CUSTOM", "SDL_LOG_PRIORITY_VERBOSE", "SDL_LOG_PRIORITY_DEBUG", "SDL_LOG_PRIORITY_INFO", "SDL_LOG_PRIORITY_WARN", "SDL_LOG_PRIORITY_ERROR", "SDL_LOG_PRIORITY_CRITICAL", "SDL_NUM_LOG_PRIORITIES", "SDL_LogPriority", "SDL_LogSetAllPriority", "SDL_LogSetPriority", "SDL_LogGetPriority", "SDL_LogResetPriorities", "SDL_Log", "SDL_LogVerbose", "SDL_LogDebug", "SDL_LogInfo", "SDL_LogWarn", "SDL_LogError", "SDL_LogCritical", "SDL_LogMessage", "SDL_LogOutputFunction", "SDL_LogGetOutputFunction", "SDL_LogSetOutputFunction" ] SDL_MAX_LOG_MESSAGE = 4096 SDL_LOG_CATEGORY_APPLICATION = 0 SDL_LOG_CATEGORY_ERROR = 1 SDL_LOG_CATEGORY_ASSERT = 2 SDL_LOG_CATEGORY_SYSTEM = 3 SDL_LOG_CATEGORY_AUDIO = 4 SDL_LOG_CATEGORY_VIDEO = 5 SDL_LOG_CATEGORY_RENDER = 6 SDL_LOG_CATEGORY_INPUT = 7 SDL_LOG_CATEGORY_TEST = 8 SDL_LOG_CATEGORY_RESERVED1 = 9 SDL_LOG_CATEGORY_RESERVED2 = 10 SDL_LOG_CATEGORY_RESERVED3 = 11 SDL_LOG_CATEGORY_RESERVED4 = 12 SDL_LOG_CATEGORY_RESERVED5 = 13 SDL_LOG_CATEGORY_RESERVED6 = 14 SDL_LOG_CATEGORY_RESERVED7 = 15 SDL_LOG_CATEGORY_RESERVED8 = 16 SDL_LOG_CATEGORY_RESERVED9 = 17 SDL_LOG_CATEGORY_RESERVED10 = 18 SDL_LOG_CATEGORY_CUSTOM = 19 SDL_LOG_PRIORITY_VERBOSE = 1 SDL_LOG_PRIORITY_DEBUG = 2 SDL_LOG_PRIORITY_INFO = 3 SDL_LOG_PRIORITY_WARN = 4 SDL_LOG_PRIORITY_ERROR = 5 SDL_LOG_PRIORITY_CRITICAL = 6 SDL_NUM_LOG_PRIORITIES = 7 SDL_LogPriority = c_int SDL_LogSetAllPriority = _bind("SDL_LogSetAllPriority", [SDL_LogPriority]) SDL_LogSetPriority = _bind("SDL_LogSetPriority", [c_int, SDL_LogPriority]) SDL_LogGetPriority = _bind("SDL_LogGetPriority", [c_int], SDL_LogPriority) SDL_LogResetPriorities = _bind("SDL_LogResetPriorities") SDL_Log = _bind("SDL_Log", [c_char_p]) SDL_LogVerbose = _bind("SDL_LogVerbose", [c_int, c_char_p]) SDL_LogDebug = _bind("SDL_LogDebug", [c_int, c_char_p]) SDL_LogInfo = _bind("SDL_LogInfo", [c_int, c_char_p]) SDL_LogWarn = _bind("SDL_LogWarn", [c_int, c_char_p]) SDL_LogError = _bind("SDL_LogError", [c_int, c_char_p]) SDL_LogCritical = _bind("SDL_LogCritical", [c_int, c_char_p]) SDL_LogMessage = _bind("SDL_LogMessage", [c_int, SDL_LogPriority, c_char_p]) # TODO: do we want SDL_LogMessageV? SDL_LogOutputFunction = CFUNCTYPE(None, c_void_p, c_int, SDL_LogPriority, c_char_p) SDL_LogGetOutputFunction = _bind("SDL_LogGetOutputFunction", [POINTER(SDL_LogOutputFunction), c_void_p]) SDL_LogSetOutputFunction = _bind("SDL_LogSetOutputFunction", [SDL_LogOutputFunction, c_void_p]) PySDL2-0.9.3/sdl2/messagebox.py0000644000000000000000000000450612260256443013012 0ustar from ctypes import Structure, c_int, c_char_p, POINTER from .dll import _bind from .stdinc import Uint8, Uint32 from .video import SDL_Window __all__ = ["SDL_MESSAGEBOX_ERROR", "SDL_MESSAGEBOX_WARNING", "SDL_MESSAGEBOX_INFORMATION", "SDL_MessageBoxFlags", "SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT", "SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT", "SDL_MessageBoxButtonFlags", "SDL_MessageBoxButtonData", "SDL_MessageBoxColor", "SDL_MESSAGEBOX_COLOR_BACKGROUND", "SDL_MESSAGEBOX_COLOR_TEXT", "SDL_MESSAGEBOX_COLOR_BUTTON_BORDER", "SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND", "SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED", "SDL_MESSAGEBOX_COLOR_MAX", "SDL_MessageBoxColorType", "SDL_MessageBoxColorScheme", "SDL_MessageBoxData", "SDL_ShowMessageBox", "SDL_ShowSimpleMessageBox" ] SDL_MESSAGEBOX_ERROR = 0x00000010 SDL_MESSAGEBOX_WARNING = 0x00000020 SDL_MESSAGEBOX_INFORMATION = 0x00000040 SDL_MessageBoxFlags = c_int SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT = 0x00000001 SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT = 0x00000002 SDL_MessageBoxButtonFlags = c_int class SDL_MessageBoxButtonData(Structure): _fields_ = [("flags", Uint32), ("buttonid", c_int), ("text", c_char_p)] class SDL_MessageBoxColor(Structure): _fields_ = [("r", Uint8), ("g", Uint8), ("b", Uint8)] SDL_MESSAGEBOX_COLOR_BACKGROUND = 0 SDL_MESSAGEBOX_COLOR_TEXT = 1 SDL_MESSAGEBOX_COLOR_BUTTON_BORDER = 2 SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND = 3 SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED = 4 SDL_MESSAGEBOX_COLOR_MAX = 5 SDL_MessageBoxColorType = c_int class SDL_MessageBoxColorScheme(Structure): _fields_ = [("colors", (SDL_MessageBoxColor * SDL_MESSAGEBOX_COLOR_MAX))] class SDL_MessageBoxData(Structure): _fields_ = [("flags", Uint32), ("window", POINTER(SDL_Window)), ("title", c_char_p), ("message", c_char_p), ("numbuttons", c_int), ("buttons", POINTER(SDL_MessageBoxButtonData)), ("colorScheme", POINTER(SDL_MessageBoxColorScheme)) ] SDL_ShowMessageBox = _bind("SDL_ShowMessageBox", [POINTER(SDL_MessageBoxData), POINTER(c_int)], c_int) SDL_ShowSimpleMessageBox = _bind("SDL_ShowSimpleMessageBox", [Uint32, c_char_p, c_char_p, POINTER(SDL_Window)], c_int) PySDL2-0.9.3/sdl2/mouse.py0000644000000000000000000000713012356441272012003 0ustar from ctypes import Structure, POINTER, c_int from .dll import _bind, nullfunc from .stdinc import Uint8, Uint32, SDL_bool from .video import SDL_Window from .surface import SDL_Surface __all__ = ["SDL_Cursor", "SDL_SYSTEM_CURSOR_ARROW", "SDL_SYSTEM_CURSOR_IBEAM", "SDL_SYSTEM_CURSOR_WAIT", "SDL_SYSTEM_CURSOR_CROSSHAIR", "SDL_SYSTEM_CURSOR_WAITARROW", "SDL_SYSTEM_CURSOR_SIZENWSE", "SDL_SYSTEM_CURSOR_SIZENESW", "SDL_SYSTEM_CURSOR_SIZEWE", "SDL_SYSTEM_CURSOR_SIZENS", "SDL_SYSTEM_CURSOR_SIZEALL", "SDL_SYSTEM_CURSOR_NO", "SDL_SYSTEM_CURSOR_HAND", "SDL_NUM_SYSTEM_CURSORS", "SDL_SystemCursor", "SDL_GetMouseFocus", "SDL_GetMouseState", "SDL_GetRelativeMouseState", "SDL_WarpMouseInWindow", "SDL_SetRelativeMouseMode", "SDL_GetRelativeMouseMode", "SDL_CreateCursor", "SDL_CreateColorCursor", "SDL_CreateSystemCursor", "SDL_SetCursor", "SDL_GetCursor", "SDL_GetDefaultCursor", "SDL_FreeCursor", "SDL_ShowCursor", "SDL_BUTTON", "SDL_BUTTON_LEFT", "SDL_BUTTON_MIDDLE", "SDL_BUTTON_RIGHT", "SDL_BUTTON_X1", "SDL_BUTTON_X2", "SDL_BUTTON_LMASK", "SDL_BUTTON_MMASK", "SDL_BUTTON_RMASK", "SDL_BUTTON_X1MASK", "SDL_BUTTON_X2MASK", "SDL_WarpMouseGlobal", "SDL_CaptureMouse", "SDL_GetGlobalMouseState" ] class SDL_Cursor(Structure): pass SDL_SYSTEM_CURSOR_ARROW = 0 SDL_SYSTEM_CURSOR_IBEAM = 1 SDL_SYSTEM_CURSOR_WAIT = 2 SDL_SYSTEM_CURSOR_CROSSHAIR = 3 SDL_SYSTEM_CURSOR_WAITARROW = 4 SDL_SYSTEM_CURSOR_SIZENWSE = 5 SDL_SYSTEM_CURSOR_SIZENESW = 6 SDL_SYSTEM_CURSOR_SIZEWE = 7 SDL_SYSTEM_CURSOR_SIZENS = 8 SDL_SYSTEM_CURSOR_SIZEALL = 9 SDL_SYSTEM_CURSOR_NO = 10 SDL_SYSTEM_CURSOR_HAND = 11 SDL_NUM_SYSTEM_CURSORS = 12 SDL_SystemCursor = c_int SDL_GetMouseFocus = _bind("SDL_GetMouseFocus", None, POINTER(SDL_Window)) SDL_GetMouseState = _bind("SDL_GetMouseState", [POINTER(c_int), POINTER(c_int)], Uint32) SDL_GetRelativeMouseState = _bind("SDL_GetRelativeMouseState", [POINTER(c_int), POINTER(c_int)], Uint32) SDL_WarpMouseInWindow = _bind("SDL_WarpMouseInWindow", [POINTER(SDL_Window), c_int, c_int]) SDL_SetRelativeMouseMode = _bind("SDL_SetRelativeMouseMode", [SDL_bool], c_int) SDL_GetRelativeMouseMode = _bind("SDL_GetRelativeMouseMode", None, SDL_bool) SDL_CreateCursor = _bind("SDL_CreateCursor", [POINTER(Uint8), POINTER(Uint8), c_int, c_int, c_int, c_int], POINTER(SDL_Cursor)) SDL_CreateColorCursor = _bind("SDL_CreateColorCursor", [POINTER(SDL_Surface), c_int, c_int], POINTER(SDL_Cursor)) SDL_CreateSystemCursor = _bind("SDL_CreateSystemCursor", [SDL_SystemCursor], POINTER(SDL_Cursor)) SDL_SetCursor = _bind("SDL_SetCursor", [POINTER(SDL_Cursor)]) SDL_GetCursor = _bind("SDL_GetCursor", None, POINTER(SDL_Cursor)) SDL_GetDefaultCursor = _bind("SDL_GetDefaultCursor", None, POINTER(SDL_Cursor)) SDL_FreeCursor = _bind("SDL_FreeCursor", [POINTER(SDL_Cursor)]) SDL_ShowCursor = _bind("SDL_ShowCursor", [c_int], c_int) SDL_WarpMouseGlobal = _bind("SDL_WarpMouseGlobal", [c_int, c_int], optfunc=nullfunc) SDL_CaptureMouse = _bind("SDL_CaptureMouse", [SDL_bool], c_int, optfunc=nullfunc) SDL_GetGlobalMouseState = _bind("SDL_GetGlobalMouseState", [POINTER(c_int), POINTER(c_int)], Uint32, optfunc=nullfunc) SDL_BUTTON = lambda X: (1 << ((X) - 1)) SDL_BUTTON_LEFT = 1 SDL_BUTTON_MIDDLE = 2 SDL_BUTTON_RIGHT = 3 SDL_BUTTON_X1 = 4 SDL_BUTTON_X2 = 5 SDL_BUTTON_LMASK = SDL_BUTTON(SDL_BUTTON_LEFT) SDL_BUTTON_MMASK = SDL_BUTTON(SDL_BUTTON_MIDDLE) SDL_BUTTON_RMASK = SDL_BUTTON(SDL_BUTTON_RIGHT) SDL_BUTTON_X1MASK = SDL_BUTTON(SDL_BUTTON_X1) SDL_BUTTON_X2MASK = SDL_BUTTON(SDL_BUTTON_X2) PySDL2-0.9.3/sdl2/pixels.py0000644000000000000000000003315512260256443012163 0ustar from ctypes import Structure, POINTER, c_int, c_char_p, c_float from .dll import _bind from .stdinc import Uint8, Uint16, Uint32, SDL_bool SDL_ALPHA_OPAQUE = 255 SDL_ALPHA_TRANSPARENT = 0 SDL_PIXELTYPE_UNKNOWN = 0 SDL_PIXELTYPE_INDEX1 = 1 SDL_PIXELTYPE_INDEX4 = 2 SDL_PIXELTYPE_INDEX8 = 3 SDL_PIXELTYPE_PACKED8 = 4 SDL_PIXELTYPE_PACKED16 = 5 SDL_PIXELTYPE_PACKED32 = 6 SDL_PIXELTYPE_ARRAYU8 = 7 SDL_PIXELTYPE_ARRAYU16 = 8 SDL_PIXELTYPE_ARRAYU32 = 9 SDL_PIXELTYPE_ARRAYF16 = 10 SDL_PIXELTYPE_ARRAYF32 = 11 SDL_BITMAPORDER_NONE = 0 SDL_BITMAPORDER_4321 = 1 SDL_BITMAPORDER_1234 = 2 SDL_PACKEDORDER_NONE = 0 SDL_PACKEDORDER_XRGB = 1 SDL_PACKEDORDER_RGBX = 2 SDL_PACKEDORDER_ARGB = 3 SDL_PACKEDORDER_RGBA = 4 SDL_PACKEDORDER_XBGR = 5 SDL_PACKEDORDER_BGRX = 6 SDL_PACKEDORDER_ABGR = 7 SDL_PACKEDORDER_BGRA = 8 SDL_ARRAYORDER_NONE = 0 SDL_ARRAYORDER_RGB = 1 SDL_ARRAYORDER_RGBA = 2 SDL_ARRAYORDER_ARGB = 3 SDL_ARRAYORDER_BGR = 4 SDL_ARRAYORDER_BGRA = 5 SDL_ARRAYORDER_ABGR = 6 SDL_PACKEDLAYOUT_NONE = 0 SDL_PACKEDLAYOUT_332 = 1 SDL_PACKEDLAYOUT_4444 = 2 SDL_PACKEDLAYOUT_1555 = 3 SDL_PACKEDLAYOUT_5551 = 4 SDL_PACKEDLAYOUT_565 = 5 SDL_PACKEDLAYOUT_8888 = 6 SDL_PACKEDLAYOUT_2101010 = 7 SDL_PACKEDLAYOUT_1010102 = 8 SDL_FOURCC = lambda a, b, c, d: (ord(a) << 0) | (ord(b) << 8) | (ord(c) << 16) | (ord(d) << 24) SDL_DEFINE_PIXELFOURCC = SDL_FOURCC SDL_DEFINE_PIXELFORMAT = lambda ptype, order, layout, bits, pbytes: ((1 << 28) | ((ptype) << 24) | ((order) << 20) | ((layout) << 16) | ((bits) << 8) | ((pbytes) << 0)) SDL_PIXELFLAG = lambda X: (((X) >> 28) & 0x0F) SDL_PIXELTYPE = lambda X: (((X) >> 24) & 0x0F) SDL_PIXELORDER = lambda X: (((X) >> 20) & 0x0F) SDL_PIXELLAYOUT = lambda X: (((X) >> 16) & 0x0F) SDL_BITSPERPIXEL = lambda X: (((X) >> 8) & 0xFF) def SDL_BYTESPERPIXEL(x): valid = (SDL_PIXELFORMAT_YUY2, SDL_PIXELFORMAT_UYVY, SDL_PIXELFORMAT_YVYU) if SDL_ISPIXELFORMAT_FOURCC(x): if x in valid: return 2 else: return 1 else: return(((x) >> 0) & 0xFF) def SDL_ISPIXELFORMAT_INDEXED(pformat): """Checks, if the passed format value is an indexed format.""" return ((not SDL_ISPIXELFORMAT_FOURCC(pformat)) and ((SDL_PIXELTYPE(pformat) == SDL_PIXELTYPE_INDEX1) or (SDL_PIXELTYPE(pformat) == SDL_PIXELTYPE_INDEX4) or (SDL_PIXELTYPE(pformat) == SDL_PIXELTYPE_INDEX8))) def SDL_ISPIXELFORMAT_ALPHA(pformat): """Checks, if the passed format value is an alpha channel supporting format. """ return ((not SDL_ISPIXELFORMAT_FOURCC(pformat)) and ((SDL_PIXELORDER(pformat) == SDL_PACKEDORDER_ARGB) or (SDL_PIXELORDER(pformat) == SDL_PACKEDORDER_RGBA) or (SDL_PIXELORDER(pformat) == SDL_PACKEDORDER_ABGR) or (SDL_PIXELORDER(pformat) == SDL_PACKEDORDER_BGRA))) SDL_ISPIXELFORMAT_FOURCC = lambda fmt: ((fmt) and (SDL_PIXELFLAG(fmt) != 1)) SDL_PIXELFORMAT_UNKNOWN = 0 SDL_PIXELFORMAT_INDEX1LSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_4321, 0, 1, 0) SDL_PIXELFORMAT_INDEX1MSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_1234, 0, 1, 0) SDL_PIXELFORMAT_INDEX4LSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_4321, 0, 4, 0) SDL_PIXELFORMAT_INDEX4MSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_1234, 0, 4, 0) SDL_PIXELFORMAT_INDEX8 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX8, 0, 0, 8, 1) SDL_PIXELFORMAT_RGB332 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED8, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_332, 8, 1) SDL_PIXELFORMAT_RGB444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_4444, 12, 2) SDL_PIXELFORMAT_RGB555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_1555, 15, 2) SDL_PIXELFORMAT_BGR555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, SDL_PACKEDLAYOUT_1555, 15, 2) SDL_PIXELFORMAT_ARGB4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_4444, 16, 2) SDL_PIXELFORMAT_RGBA4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, SDL_PACKEDLAYOUT_4444, 16, 2) SDL_PIXELFORMAT_ABGR4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, SDL_PACKEDLAYOUT_4444, 16, 2) SDL_PIXELFORMAT_BGRA4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, SDL_PACKEDLAYOUT_4444, 16, 2) SDL_PIXELFORMAT_ARGB1555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_1555, 16, 2) SDL_PIXELFORMAT_RGBA5551 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, SDL_PACKEDLAYOUT_5551, 16, 2) SDL_PIXELFORMAT_ABGR1555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, SDL_PACKEDLAYOUT_1555, 16, 2) SDL_PIXELFORMAT_BGRA5551 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, SDL_PACKEDLAYOUT_5551, 16, 2) SDL_PIXELFORMAT_RGB565 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_565, 16, 2) SDL_PIXELFORMAT_BGR565 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, SDL_PACKEDLAYOUT_565, 16, 2) SDL_PIXELFORMAT_RGB24 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_RGB, 0, 24, 3) SDL_PIXELFORMAT_BGR24 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_BGR, 0, 24, 3) SDL_PIXELFORMAT_RGB888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_8888, 24, 4) SDL_PIXELFORMAT_RGBX8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBX, SDL_PACKEDLAYOUT_8888, 24, 4) SDL_PIXELFORMAT_BGR888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XBGR, SDL_PACKEDLAYOUT_8888, 24, 4) SDL_PIXELFORMAT_BGRX8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRX, SDL_PACKEDLAYOUT_8888, 24, 4) SDL_PIXELFORMAT_ARGB8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_8888, 32, 4) SDL_PIXELFORMAT_RGBA8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBA, SDL_PACKEDLAYOUT_8888, 32, 4) SDL_PIXELFORMAT_ABGR8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ABGR, SDL_PACKEDLAYOUT_8888, 32, 4) SDL_PIXELFORMAT_BGRA8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRA, SDL_PACKEDLAYOUT_8888, 32, 4) SDL_PIXELFORMAT_ARGB2101010 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_2101010, 32, 4) SDL_PIXELFORMAT_YV12 = SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2') SDL_PIXELFORMAT_IYUV = SDL_DEFINE_PIXELFOURCC('I', 'Y', 'U', 'V') SDL_PIXELFORMAT_YUY2 = SDL_DEFINE_PIXELFOURCC('Y', 'U', 'Y', '2') SDL_PIXELFORMAT_UYVY = SDL_DEFINE_PIXELFOURCC('U', 'Y', 'V', 'Y') SDL_PIXELFORMAT_YVYU = SDL_DEFINE_PIXELFOURCC('Y', 'V', 'Y', 'U') ALL_PIXELFORMATS = ( SDL_PIXELFORMAT_INDEX1LSB, SDL_PIXELFORMAT_INDEX1MSB, SDL_PIXELFORMAT_INDEX4LSB, SDL_PIXELFORMAT_INDEX4MSB, SDL_PIXELFORMAT_INDEX8, SDL_PIXELFORMAT_RGB332, SDL_PIXELFORMAT_RGB444, SDL_PIXELFORMAT_RGB555, SDL_PIXELFORMAT_BGR555, SDL_PIXELFORMAT_ARGB4444, SDL_PIXELFORMAT_RGBA4444, SDL_PIXELFORMAT_ABGR4444, SDL_PIXELFORMAT_BGRA4444, SDL_PIXELFORMAT_ARGB1555, SDL_PIXELFORMAT_RGBA5551, SDL_PIXELFORMAT_ABGR1555, SDL_PIXELFORMAT_BGRA5551, SDL_PIXELFORMAT_RGB565, SDL_PIXELFORMAT_BGR565, SDL_PIXELFORMAT_RGB24, SDL_PIXELFORMAT_BGR24, SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_RGBX8888, SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_BGRX8888, SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_ARGB2101010, SDL_PIXELFORMAT_YV12, SDL_PIXELFORMAT_IYUV, SDL_PIXELFORMAT_YUY2, SDL_PIXELFORMAT_UYVY, SDL_PIXELFORMAT_YVYU, ) class SDL_Color(Structure): _fields_ = [("r", Uint8), ("g", Uint8), ("b", Uint8), ("a", Uint8), ] def __init__(self, r=255, g=255, b=255, a=255): super(SDL_Color, self).__init__() self.r = r self.g = g self.b = b self.a = a def __repr__(self): return "SDL_Color(r=%d, g=%d, b=%d, a=%d)" % (self.r, self.g, self.b, self.a) def __copy__(self): return SDL_Color(self.r, self.g, self.b, self.a) def __deepcopy__(self, memo): return SDL_Color(self.r, self.g, self.b, self.a) def __eq__(self, color): return self.r == color.r and self.g == color.g and \ self.b == color.b and self.a == color.a def __ne__(self, color): return self.r != color.r or self.g != color.g or self.b != color.b or \ self.a != color.a SDL_Colour = SDL_Color class SDL_Palette(Structure): _fields_ = [("ncolors", c_int), ("colors", POINTER(SDL_Color)), ("version", Uint32), ("refcount", c_int)] class SDL_PixelFormat(Structure): pass SDL_PixelFormat._fields_ = \ [("format", Uint32), ("palette", POINTER(SDL_Palette)), ("BitsPerPixel", Uint8), ("BytesPerPixel", Uint8), ("padding", Uint8 * 2), ("Rmask", Uint32), ("Gmask", Uint32), ("Bmask", Uint32), ("Amask", Uint32), ("Rloss", Uint8), ("Gloss", Uint8), ("Bloss", Uint8), ("Aloss", Uint8), ("Rshift", Uint8), ("Gshift", Uint8), ("Bshift", Uint8), ("Ashift", Uint8), ("refcount", c_int), ("next", POINTER(SDL_PixelFormat))] SDL_GetPixelFormatName = _bind("SDL_GetPixelFormatName", [Uint32], c_char_p) SDL_PixelFormatEnumToMasks = _bind("SDL_PixelFormatEnumToMasks", [Uint32, POINTER(c_int), POINTER(Uint32), POINTER(Uint32), POINTER(Uint32), POINTER(Uint32)], SDL_bool) SDL_MasksToPixelFormatEnum = _bind("SDL_MasksToPixelFormatEnum", [c_int, Uint32, Uint32, Uint32, Uint32], Uint32) SDL_AllocFormat = _bind("SDL_AllocFormat", [Uint32], POINTER(SDL_PixelFormat)) SDL_FreeFormat = _bind("SDL_FreeFormat", [POINTER(SDL_PixelFormat)]) SDL_AllocPalette = _bind("SDL_AllocPalette", [c_int], POINTER(SDL_Palette)) SDL_SetPixelFormatPalette = _bind("SDL_SetPixelFormatPalette", [POINTER(SDL_PixelFormat), POINTER(SDL_Palette)], c_int) SDL_SetPaletteColors = _bind("SDL_SetPaletteColors", [POINTER(SDL_Palette), POINTER(SDL_Color), c_int, c_int], c_int) SDL_FreePalette = _bind("SDL_FreePalette", [POINTER(SDL_Palette)]) SDL_MapRGB = _bind("SDL_MapRGB", [POINTER(SDL_PixelFormat), Uint8, Uint8, Uint8], Uint32) SDL_MapRGBA = _bind("SDL_MapRGBA", [POINTER(SDL_PixelFormat), Uint8, Uint8, Uint8, Uint8], Uint32) SDL_GetRGB = _bind("SDL_GetRGB", [Uint32, POINTER(SDL_PixelFormat), POINTER(Uint8), POINTER(Uint8), POINTER(Uint8)]) SDL_GetRGBA = _bind("SDL_GetRGBA", [Uint32, POINTER(SDL_PixelFormat), POINTER(Uint8), POINTER(Uint8), POINTER(Uint8), POINTER(Uint8)]) SDL_CalculateGammaRamp = _bind("SDL_CalculateGammaRamp", [c_float, POINTER(Uint16)]) PySDL2-0.9.3/sdl2/platform.py0000644000000000000000000000021612260256443012473 0ustar from ctypes import c_char_p from .dll import _bind __all__ = ["SDL_GetPlatform"] SDL_GetPlatform = _bind("SDL_GetPlatform", None, c_char_p) PySDL2-0.9.3/sdl2/power.py0000644000000000000000000000104312260256443012002 0ustar from ctypes import POINTER, c_int from .dll import _bind __all__ = ["SDL_PowerState", "SDL_POWERSTATE_UNKNOWN", "SDL_POWERSTATE_ON_BATTERY", "SDL_POWERSTATE_NO_BATTERY", "SDL_POWERSTATE_CHARGING", "SDL_POWERSTATE_CHARGED", "SDL_GetPowerInfo" ] SDL_PowerState = c_int SDL_POWERSTATE_UNKNOWN = 0 SDL_POWERSTATE_ON_BATTERY = 1 SDL_POWERSTATE_NO_BATTERY = 2 SDL_POWERSTATE_CHARGING = 3 SDL_POWERSTATE_CHARGED = 4 SDL_GetPowerInfo = _bind("SDL_GetPowerInfo", [POINTER(c_int), POINTER(c_int)], SDL_PowerState) PySDL2-0.9.3/sdl2/rect.py0000644000000000000000000000522212356441667011620 0ustar from ctypes import Structure, c_int, POINTER from .dll import _bind from .stdinc import SDL_bool __all__ = ["SDL_Point", "SDL_Rect", "SDL_RectEmpty", "SDL_RectEquals", "SDL_HasIntersection", "SDL_IntersectRect", "SDL_UnionRect", "SDL_EnclosePoints", "SDL_IntersectRectAndLine", "SDL_PointInRect" ] class SDL_Point(Structure): _fields_ = [("x", c_int), ("y", c_int)] def __init__(self, x=0, y=0): super(SDL_Point, self).__init__() self.x = x self.y = y def __repr__(self): return "SDL_Point(x=%d, y=%d)" % (self.x, self.y) def __copy__(self): return SDL_Point(self.x, self.y) def __deepcopy__(self, memo): return SDL_Point(self.x, self.y) def __eq__(self, pt): return self.x == pt.x and self.y == pt.y def __ne__(self, pt): return self.x != pt.x or self.y != pt.y class SDL_Rect(Structure): _fields_ = [("x", c_int), ("y", c_int), ("w", c_int), ("h", c_int)] def __init__(self, x=0, y=0, w=0, h=0): super(SDL_Rect, self).__init__() self.x = x self.y = y self.w = w self.h = h def __repr__(self): return "SDL_Rect(x=%d, y=%d, w=%d, h=%d)" % (self.x, self.y, self.w, self.h) def __copy__(self): return SDL_Rect(self.x, self.y, self.w, self.h) def __deepcopy__(self, memo): return SDL_Rect(self.x, self.y, self.w, self.h) def __eq__(self, rt): return self.x == rt.x and self.y == rt.y and \ self.w == rt.w and self.h == rt.h def __ne__(self, rt): return self.x != rt.x or self.y != rt.y or \ self.w != rt.w or self.h != rt.h SDL_RectEmpty = lambda x: ((not x) or (x.w <= 0) or (x.h <= 0)) SDL_RectEquals = lambda a, b: ((a.x == b.x) and (a.y == b.y) and (a.w == b.w) and (a.h == b.h)) SDL_PointInRect = lambda p, r: ((p.x >= r.x) and (p.x < (r.x + r.w)) and (p.y >= r.y) and (p.y < (r.y + r.h))) SDL_HasIntersection = _bind("SDL_HasIntersection", [POINTER(SDL_Rect), POINTER(SDL_Rect)], SDL_bool) SDL_IntersectRect = _bind("SDL_IntersectRect", [POINTER(SDL_Rect), POINTER(SDL_Rect), POINTER(SDL_Rect)], SDL_bool) SDL_UnionRect = _bind("SDL_UnionRect", [POINTER(SDL_Rect), POINTER(SDL_Rect), POINTER(SDL_Rect)]) SDL_EnclosePoints = _bind("SDL_EnclosePoints", [POINTER(SDL_Point), c_int, POINTER(SDL_Rect), POINTER(SDL_Rect)], SDL_bool) SDL_IntersectRectAndLine = _bind("SDL_IntersectRectAndLine", [POINTER(SDL_Rect), POINTER(c_int), POINTER(c_int), POINTER(c_int), POINTER(c_int)], SDL_bool) PySDL2-0.9.3/sdl2/render.py0000644000000000000000000002222012324671431012124 0ustar from ctypes import Structure, POINTER, c_int, c_char_p, c_void_p, c_float, \ c_double from .dll import _bind, nullfunc from .stdinc import Uint8, Uint32, SDL_bool from .blendmode import SDL_BlendMode from .rect import SDL_Point, SDL_Rect from .surface import SDL_Surface from .video import SDL_Window __all__ = ["SDL_RendererFlags", "SDL_RENDERER_SOFTWARE", "SDL_RENDERER_ACCELERATED", "SDL_RENDERER_PRESENTVSYNC", "SDL_RENDERER_TARGETTEXTURE", "SDL_RendererInfo", "SDL_TextureAccess", "SDL_TEXTUREACCESS_STATIC", "SDL_TEXTUREACCESS_STREAMING", "SDL_TEXTUREACCESS_TARGET", "SDL_TextureModulate", "SDL_TEXTUREMODULATE_NONE", "SDL_TEXTUREMODULATE_COLOR", "SDL_TEXTUREMODULATE_ALPHA", "SDL_RendererFlip", "SDL_FLIP_NONE", "SDL_FLIP_HORIZONTAL", "SDL_FLIP_VERTICAL", "SDL_Renderer", "SDL_Texture", "SDL_GetNumRenderDrivers", "SDL_GetRenderDriverInfo", "SDL_CreateWindowAndRenderer", "SDL_CreateRenderer", "SDL_CreateSoftwareRenderer", "SDL_GetRenderer", "SDL_GetRendererInfo", "SDL_CreateTexture", "SDL_CreateTextureFromSurface", "SDL_QueryTexture", "SDL_SetTextureColorMod", "SDL_GetTextureColorMod", "SDL_SetTextureAlphaMod", "SDL_GetTextureAlphaMod", "SDL_SetTextureBlendMode", "SDL_GetTextureBlendMode", "SDL_UpdateTexture", "SDL_LockTexture", "SDL_UnlockTexture", "SDL_RenderTargetSupported", "SDL_SetRenderTarget", "SDL_GetRenderTarget", "SDL_RenderSetLogicalSize", "SDL_RenderGetLogicalSize", "SDL_RenderSetViewport", "SDL_RenderGetClipRect", "SDL_RenderSetClipRect", "SDL_RenderGetViewport", "SDL_RenderSetScale", "SDL_RenderGetScale", "SDL_SetRenderDrawColor", "SDL_GetRenderDrawColor", "SDL_SetRenderDrawBlendMode", "SDL_GetRenderDrawBlendMode", "SDL_RenderClear", "SDL_RenderDrawPoint", "SDL_RenderDrawPoints", "SDL_RenderDrawLine", "SDL_RenderDrawLines", "SDL_RenderDrawRect", "SDL_RenderDrawRects", "SDL_RenderFillRect", "SDL_RenderFillRects", "SDL_RenderCopy", "SDL_RenderCopyEx", "SDL_RenderReadPixels", "SDL_RenderPresent", "SDL_DestroyTexture", "SDL_DestroyRenderer", "SDL_UpdateYUVTexture", "SDL_GL_BindTexture", "SDL_GL_UnbindTexture", "SDL_GetRendererOutputSize" ] SDL_RendererFlags = c_int SDL_RENDERER_SOFTWARE = 0x00000001 SDL_RENDERER_ACCELERATED = 0x00000002 SDL_RENDERER_PRESENTVSYNC = 0x00000004 SDL_RENDERER_TARGETTEXTURE = 0x00000008 class SDL_RendererInfo(Structure): _fields_ = [("name", c_char_p), ("flags", Uint32), ("num_texture_formats", Uint32), ("texture_formats", Uint32 * 16), ("max_texture_width", c_int), ("max_texture_height", c_int)] SDL_TextureAccess = c_int SDL_TEXTUREACCESS_STATIC = 0 SDL_TEXTUREACCESS_STREAMING = 1 SDL_TEXTUREACCESS_TARGET = 2 SDL_TextureModulate = c_int SDL_TEXTUREMODULATE_NONE = 0x00000000 SDL_TEXTUREMODULATE_COLOR = 0x00000001 SDL_TEXTUREMODULATE_ALPHA = 0x00000002 SDL_RendererFlip = c_int SDL_FLIP_NONE = 0x00000000 SDL_FLIP_HORIZONTAL = 0x00000001 SDL_FLIP_VERTICAL = 0x00000002 class SDL_Renderer(Structure): pass class SDL_Texture(Structure): pass SDL_GetNumRenderDrivers = _bind("SDL_GetNumRenderDrivers", None, c_int) SDL_GetRenderDriverInfo = _bind("SDL_GetRenderDriverInfo", [c_int, POINTER(SDL_RendererInfo)], c_int) SDL_CreateWindowAndRenderer = _bind("SDL_CreateWindowAndRenderer", [c_int, c_int, Uint32, POINTER(POINTER(SDL_Window)), POINTER(POINTER(SDL_Renderer))], c_int) SDL_CreateRenderer = _bind("SDL_CreateRenderer", [POINTER(SDL_Window), c_int, Uint32], POINTER(SDL_Renderer)) SDL_CreateSoftwareRenderer = _bind("SDL_CreateSoftwareRenderer", [POINTER(SDL_Surface)], POINTER(SDL_Renderer)) SDL_GetRenderer = _bind("SDL_GetRenderer", [POINTER(SDL_Window)], POINTER(SDL_Renderer)) SDL_GetRendererInfo = _bind("SDL_GetRendererInfo", [POINTER(SDL_Renderer), POINTER(SDL_RendererInfo)], c_int) SDL_GetRendererOutputSize = _bind("SDL_GetRendererOutputSize", [POINTER(SDL_Renderer), POINTER(c_int), POINTER(c_int)], c_int) SDL_CreateTexture = _bind("SDL_CreateTexture", [POINTER(SDL_Renderer), Uint32, c_int, c_int, c_int], POINTER(SDL_Texture)) SDL_CreateTextureFromSurface = _bind("SDL_CreateTextureFromSurface", [POINTER(SDL_Renderer), POINTER(SDL_Surface)], POINTER(SDL_Texture)) SDL_QueryTexture = _bind("SDL_QueryTexture", [POINTER(SDL_Texture), POINTER(Uint32), POINTER(c_int), POINTER(c_int), POINTER(c_int)], c_int) SDL_SetTextureColorMod = _bind("SDL_SetTextureColorMod", [POINTER(SDL_Texture), Uint8, Uint8, Uint8], c_int) SDL_GetTextureColorMod = _bind("SDL_GetTextureColorMod", [POINTER(SDL_Texture), POINTER(Uint8), POINTER(Uint8), POINTER(Uint8)], c_int) SDL_SetTextureAlphaMod = _bind("SDL_SetTextureAlphaMod", [POINTER(SDL_Texture), Uint8], c_int) SDL_GetTextureAlphaMod = _bind("SDL_GetTextureAlphaMod", [POINTER(SDL_Texture), POINTER(Uint8)], c_int) SDL_SetTextureBlendMode = _bind("SDL_SetTextureBlendMode", [POINTER(SDL_Texture), SDL_BlendMode], c_int) SDL_GetTextureBlendMode = _bind("SDL_GetTextureBlendMode", [POINTER(SDL_Texture), POINTER(SDL_BlendMode)], c_int) SDL_UpdateTexture = _bind("SDL_UpdateTexture", [POINTER(SDL_Texture), POINTER(SDL_Rect), c_void_p, c_int], c_int) SDL_LockTexture = _bind("SDL_LockTexture", [POINTER(SDL_Texture), POINTER(SDL_Rect), POINTER(c_void_p), POINTER(c_int)], c_int) SDL_UnlockTexture = _bind("SDL_UnlockTexture", [POINTER(SDL_Texture)]) SDL_RenderTargetSupported = _bind("SDL_RenderTargetSupported", [POINTER(SDL_Renderer)], SDL_bool) SDL_SetRenderTarget = _bind("SDL_SetRenderTarget", [POINTER(SDL_Renderer), POINTER(SDL_Texture)], c_int) SDL_GetRenderTarget = _bind("SDL_GetRenderTarget", [POINTER(SDL_Renderer)], POINTER(SDL_Texture)) SDL_RenderSetLogicalSize = _bind("SDL_RenderSetLogicalSize", [POINTER(SDL_Renderer), c_int, c_int], c_int) SDL_RenderGetLogicalSize = _bind("SDL_RenderGetLogicalSize", [POINTER(SDL_Renderer), POINTER(c_int), POINTER(c_int)]) SDL_RenderSetViewport = _bind("SDL_RenderSetViewport", [POINTER(SDL_Renderer), POINTER(SDL_Rect)], c_int) SDL_RenderGetViewport = _bind("SDL_RenderGetViewport", [POINTER(SDL_Renderer), POINTER(SDL_Rect)]) SDL_RenderGetClipRect = _bind("SDL_RenderGetClipRect", [POINTER(SDL_Renderer), POINTER(SDL_Rect)]) SDL_RenderSetClipRect = _bind("SDL_RenderSetClipRect", [POINTER(SDL_Renderer), POINTER(SDL_Rect)], c_int) SDL_RenderIsClipEnabled = _bind("SDL_RenderIsClipEnabled", [POINTER(SDL_Renderer)], SDL_bool, nullfunc) SDL_RenderSetScale = _bind("SDL_RenderSetScale", [POINTER(SDL_Renderer), c_float, c_float], c_int) SDL_RenderGetScale = _bind("SDL_RenderGetScale", [POINTER(SDL_Renderer), POINTER(c_float), POINTER(c_float)]) SDL_SetRenderDrawColor = _bind("SDL_SetRenderDrawColor", [POINTER(SDL_Renderer), Uint8, Uint8, Uint8, Uint8], c_int) SDL_GetRenderDrawColor = _bind("SDL_GetRenderDrawColor", [POINTER(SDL_Renderer), POINTER(Uint8), POINTER(Uint8), POINTER(Uint8), POINTER(Uint8)], c_int) SDL_SetRenderDrawBlendMode = _bind("SDL_SetRenderDrawBlendMode", [POINTER(SDL_Renderer), SDL_BlendMode], c_int) SDL_GetRenderDrawBlendMode = _bind("SDL_GetRenderDrawBlendMode", [POINTER(SDL_Renderer), POINTER(SDL_BlendMode)], c_int) SDL_RenderClear = _bind("SDL_RenderClear", [POINTER(SDL_Renderer)], c_int) SDL_RenderDrawPoint = _bind("SDL_RenderDrawPoint", [POINTER(SDL_Renderer), c_int, c_int], c_int) SDL_RenderDrawPoints = _bind("SDL_RenderDrawPoints", [POINTER(SDL_Renderer), POINTER(SDL_Point), c_int], c_int) SDL_RenderDrawLine = _bind("SDL_RenderDrawLine", [POINTER(SDL_Renderer), c_int, c_int, c_int, c_int], c_int) SDL_RenderDrawLines = _bind("SDL_RenderDrawLines", [POINTER(SDL_Renderer), POINTER(SDL_Point), c_int], c_int) SDL_RenderDrawRect = _bind("SDL_RenderDrawRect", [POINTER(SDL_Renderer), POINTER(SDL_Rect)], c_int) SDL_RenderDrawRects = _bind("SDL_RenderDrawRects", [POINTER(SDL_Renderer), POINTER(SDL_Rect), c_int], c_int) SDL_RenderFillRect = _bind("SDL_RenderFillRect", [POINTER(SDL_Renderer), POINTER(SDL_Rect)], c_int) SDL_RenderFillRects = _bind("SDL_RenderFillRects", [POINTER(SDL_Renderer), POINTER(SDL_Rect), c_int], c_int) SDL_RenderCopy = _bind("SDL_RenderCopy", [POINTER(SDL_Renderer), POINTER(SDL_Texture), POINTER(SDL_Rect), POINTER(SDL_Rect)], c_int) SDL_RenderCopyEx = _bind("SDL_RenderCopyEx", [POINTER(SDL_Renderer), POINTER(SDL_Texture), POINTER(SDL_Rect), POINTER(SDL_Rect), c_double, POINTER(SDL_Point), SDL_RendererFlip], c_int) SDL_RenderReadPixels = _bind("SDL_RenderReadPixels", [POINTER(SDL_Renderer), POINTER(SDL_Rect), Uint32, c_void_p, c_int], c_int) SDL_RenderPresent = _bind("SDL_RenderPresent", [POINTER(SDL_Renderer)]) SDL_DestroyTexture = _bind("SDL_DestroyTexture", [POINTER(SDL_Texture)]) SDL_DestroyRenderer = _bind("SDL_DestroyRenderer", [POINTER(SDL_Renderer)]) SDL_GL_BindTexture = _bind("SDL_GL_BindTexture", [POINTER(SDL_Texture), POINTER(c_float), POINTER(c_float)], c_int) SDL_GL_UnbindTexture = _bind("SDL_GL_UnbindTexture", [POINTER(SDL_Texture)], c_int) SDL_UpdateYUVTexture = _bind("SDL_UpdateYUVTexture", [POINTER(SDL_Texture), POINTER(SDL_Rect), POINTER(Uint8), c_int, POINTER(Uint8), c_int, POINTER(Uint8), c_int], c_int, nullfunc) PySDL2-0.9.3/sdl2/rwops.py0000644000000000000000000001723012345520161012020 0ustar import sys from ctypes import Structure, POINTER, CFUNCTYPE, c_int, c_size_t, c_void_p, \ c_char_p, memmove, string_at from .dll import _bind from .stdinc import Sint64, Uint8, Uint16, Uint32, Uint64, SDL_bool __all__ = ["SDL_RWOPS_UNKNOWN", "SDL_RWOPS_WINFILE", "SDL_RWOPS_STDFILE", "SDL_RWOPS_JNIFILE", "SDL_RWOPS_MEMORY", "SDL_RWOPS_MEMORY_RO", "SDL_RWops", "SDL_RWFromFile", "SDL_RWFromFP", "SDL_RWFromMem", "SDL_RWFromConstMem", "SDL_AllocRW", "SDL_FreeRW", "RW_SEEK_SET", "RW_SEEK_CUR", "RW_SEEK_END", "SDL_RWsize", "SDL_RWseek", "SDL_RWtell", "SDL_RWread", "SDL_RWwrite", "SDL_RWclose", "SDL_ReadU8", "SDL_ReadLE16", "SDL_ReadBE16", "SDL_ReadLE32", "SDL_ReadBE32", "SDL_ReadLE64", "SDL_ReadBE64", "SDL_WriteU8", "SDL_WriteLE16", "SDL_WriteBE16", "SDL_WriteLE32", "SDL_WriteBE32", "SDL_WriteLE64", "SDL_WriteBE64", "rw_from_object" ] SDL_RWOPS_UNKNOWN = 0 SDL_RWOPS_WINFILE = 1 SDL_RWOPS_STDFILE = 2 SDL_RWOPS_JNIFILE = 3 SDL_RWOPS_MEMORY = 4 SDL_RWOPS_MEMORY_RO = 5 class SDL_RWops(Structure): pass _sdlsize = CFUNCTYPE(Sint64, POINTER(SDL_RWops)) _sdlseek = CFUNCTYPE(Sint64, POINTER(SDL_RWops), Sint64, c_int) _sdlread = CFUNCTYPE(c_size_t, POINTER(SDL_RWops), c_void_p, c_size_t, c_size_t) _sdlwrite = CFUNCTYPE(c_size_t, POINTER(SDL_RWops), c_void_p, c_size_t, c_size_t) _sdlclose = CFUNCTYPE(c_int, POINTER(SDL_RWops)) SDL_RWops._fields_ = [("size", _sdlsize), ("seek", _sdlseek), ("read", _sdlread), ("write", _sdlwrite), ("close", _sdlclose), ("type", Uint32), # TODO: Union hidden ] SDL_RWFromFile = _bind("SDL_RWFromFile", [c_char_p, c_char_p], POINTER(SDL_RWops)) SDL_RWFromFP = _bind("SDL_RWFromFP", [c_void_p, SDL_bool], POINTER(SDL_RWops)) SDL_RWFromMem = _bind("SDL_RWFromMem", [c_void_p, c_int], POINTER(SDL_RWops)) SDL_RWFromConstMem = _bind("SDL_RWFromConstMem", [c_void_p, c_int], POINTER(SDL_RWops)) SDL_AllocRW = _bind("SDL_AllocRW", None, POINTER(SDL_RWops)) SDL_FreeRW = _bind("SDL_FreeRW", [POINTER(SDL_RWops)]) RW_SEEK_SET = 0 RW_SEEK_CUR = 1 RW_SEEK_END = 2 SDL_RWsize = lambda ctx: ctx.size(ctx) SDL_RWseek = lambda ctx, offset, whence: ctx.seek(ctx, offset, whence) SDL_RWtell = lambda ctx: ctx.seek(ctx, 0, RW_SEEK_CUR) SDL_RWread = lambda ctx, ptr, size, n: ctx.read(ctx, ptr, size, n) SDL_RWwrite = lambda ctx, ptr, size, n: ctx.write(ctx, ptr, size, n) SDL_RWclose = lambda ctx: ctx.close(ctx) SDL_ReadU8 = _bind("SDL_ReadU8", [POINTER(SDL_RWops)], Uint8) SDL_ReadLE16 = _bind("SDL_ReadLE16", [POINTER(SDL_RWops)], Uint16) SDL_ReadBE16 = _bind("SDL_ReadBE16", [POINTER(SDL_RWops)], Uint16) SDL_ReadLE32 = _bind("SDL_ReadLE32", [POINTER(SDL_RWops)], Uint32) SDL_ReadBE32 = _bind("SDL_ReadBE32", [POINTER(SDL_RWops)], Uint32) SDL_ReadLE64 = _bind("SDL_ReadLE64", [POINTER(SDL_RWops)], Uint64) SDL_ReadBE64 = _bind("SDL_ReadBE64", [POINTER(SDL_RWops)], Uint64) SDL_WriteU8 = _bind("SDL_WriteU8", [POINTER(SDL_RWops), Uint8], c_size_t) SDL_WriteLE16 = _bind("SDL_WriteLE16", [POINTER(SDL_RWops), Uint16], c_size_t) SDL_WriteBE16 = _bind("SDL_WriteBE16", [POINTER(SDL_RWops), Uint16], c_size_t) SDL_WriteLE32 = _bind("SDL_WriteLE32", [POINTER(SDL_RWops), Uint32], c_size_t) SDL_WriteBE32 = _bind("SDL_WriteBE32", [POINTER(SDL_RWops), Uint32], c_size_t) SDL_WriteLE64 = _bind("SDL_WriteLE64", [POINTER(SDL_RWops), Uint64], c_size_t) SDL_WriteBE64 = _bind("SDL_WriteBE64", [POINTER(SDL_RWops), Uint64], c_size_t) if sys.version_info[0] >= 3: import collections callable = lambda x: isinstance(x, collections.Callable) def rw_from_object(obj): """Creats a SDL_RWops from any Python object. The Python object must at least support the following methods: read(length) -> data length is the size in bytes to be read. A call to len(data) must return the correct amount of bytes for the data, so that len(data) / [size in bytes for a single element from data] returns the amount of elements. Must raise an error on failure. seek(offset, whence) -> int offset denotes the offset to move the read/write pointer of the object to. whence indicates the movement behaviour and can be one of the following values: RW_SEEK_SET - move to offset from the start of the file RW_SEEK_CUR - move by offset from the relative location RW_SEEK_END - move to offset from the end of the file If it could not move read/write pointer to the desired location, an error must be raised. tell() -> int Must return the current offset. This method must only be provided, if seek() does not return any value. close() -> None Closes the object(or its internal data access methods). Must raise an error on failure. write(data) -> None Writes the passed data(which is a string of bytes) to the object. Must raise an error on failure. Note: The write() method is optional and only necessary, if the passed object should be able to write data. The returned SDL_RWops is a pure Python object and must not be freed via free_rw(). """ if not hasattr(obj, "read"): raise TypeError("obj must have a read(len) -> data method") if not hasattr(obj, "seek") or not callable(obj.seek): raise TypeError("obj must have a seek(offset, whence) method") if not hasattr(obj, "close") or not callable(obj.close): raise TypeError("obj must have a close() -> int method") rwops = SDL_RWops() def _rwsize(context): try: if hasattr(obj, "size"): if callable(obj.size): return obj.size() else: return obj.size else: cur = obj.seek(0, RW_SEEK_CUR) length = obj.seek(0, RW_SEEK_END) obj.seek(cur, RW_SEEK_CUR) return length except Exception: #print(e) return -1 rwops.size = _sdlsize(_rwsize) def _rwseek(context, offset, whence): try: retval = obj.seek(offset, whence) if retval is None: retval = obj.tell() return retval except Exception: #print(e) return -1 rwops.seek = _sdlseek(_rwseek) def _rwread(context, ptr, size, maxnum): try: data = obj.read(size * maxnum) num = len(data) memmove(ptr, data, num) return num // size except Exception: #print(e) return 0 rwops.read = _sdlread(_rwread) def _rwclose(context): try: retval = obj.close() if retval is None: # No return value; we assume that everything is okay. return 0 return retval except Exception: #print(e) return -1 rwops.close = _sdlclose(_rwclose) def _rwwrite(context, ptr, size, num): try: # string_at feels wrong, since we access a raw byte buffer... retval = obj.write(string_at(ptr, size * num)) if retval is None: # No return value; we assume that everything is okay. return num return retval except Exception: #print(e) return 0 if hasattr(obj, "write") and callable(obj.write): rwops.write = _sdlwrite(_rwwrite) else: rwops.write = _sdlwrite() return rwops PySDL2-0.9.3/sdl2/scancode.py0000644000000000000000000001422012260256443012426 0ustar from ctypes import c_int SDL_Scancode = c_int SDL_SCANCODE_UNKNOWN = 0 SDL_SCANCODE_A = 4 SDL_SCANCODE_B = 5 SDL_SCANCODE_C = 6 SDL_SCANCODE_D = 7 SDL_SCANCODE_E = 8 SDL_SCANCODE_F = 9 SDL_SCANCODE_G = 10 SDL_SCANCODE_H = 11 SDL_SCANCODE_I = 12 SDL_SCANCODE_J = 13 SDL_SCANCODE_K = 14 SDL_SCANCODE_L = 15 SDL_SCANCODE_M = 16 SDL_SCANCODE_N = 17 SDL_SCANCODE_O = 18 SDL_SCANCODE_P = 19 SDL_SCANCODE_Q = 20 SDL_SCANCODE_R = 21 SDL_SCANCODE_S = 22 SDL_SCANCODE_T = 23 SDL_SCANCODE_U = 24 SDL_SCANCODE_V = 25 SDL_SCANCODE_W = 26 SDL_SCANCODE_X = 27 SDL_SCANCODE_Y = 28 SDL_SCANCODE_Z = 29 SDL_SCANCODE_1 = 30 SDL_SCANCODE_2 = 31 SDL_SCANCODE_3 = 32 SDL_SCANCODE_4 = 33 SDL_SCANCODE_5 = 34 SDL_SCANCODE_6 = 35 SDL_SCANCODE_7 = 36 SDL_SCANCODE_8 = 37 SDL_SCANCODE_9 = 38 SDL_SCANCODE_0 = 39 SDL_SCANCODE_RETURN = 40 SDL_SCANCODE_ESCAPE = 41 SDL_SCANCODE_BACKSPACE = 42 SDL_SCANCODE_TAB = 43 SDL_SCANCODE_SPACE = 44 SDL_SCANCODE_MINUS = 45 SDL_SCANCODE_EQUALS = 46 SDL_SCANCODE_LEFTBRACKET = 47 SDL_SCANCODE_RIGHTBRACKET = 48 SDL_SCANCODE_BACKSLASH = 49 SDL_SCANCODE_NONUSHASH = 50 SDL_SCANCODE_SEMICOLON = 51 SDL_SCANCODE_APOSTROPHE = 52 SDL_SCANCODE_GRAVE = 53 SDL_SCANCODE_COMMA = 54 SDL_SCANCODE_PERIOD = 55 SDL_SCANCODE_SLASH = 56 SDL_SCANCODE_CAPSLOCK = 57 SDL_SCANCODE_F1 = 58 SDL_SCANCODE_F2 = 59 SDL_SCANCODE_F3 = 60 SDL_SCANCODE_F4 = 61 SDL_SCANCODE_F5 = 62 SDL_SCANCODE_F6 = 63 SDL_SCANCODE_F7 = 64 SDL_SCANCODE_F8 = 65 SDL_SCANCODE_F9 = 66 SDL_SCANCODE_F10 = 67 SDL_SCANCODE_F11 = 68 SDL_SCANCODE_F12 = 69 SDL_SCANCODE_PRINTSCREEN = 70 SDL_SCANCODE_SCROLLLOCK = 71 SDL_SCANCODE_PAUSE = 72 SDL_SCANCODE_INSERT = 73 SDL_SCANCODE_HOME = 74 SDL_SCANCODE_PAGEUP = 75 SDL_SCANCODE_DELETE = 76 SDL_SCANCODE_END = 77 SDL_SCANCODE_PAGEDOWN = 78 SDL_SCANCODE_RIGHT = 79 SDL_SCANCODE_LEFT = 80 SDL_SCANCODE_DOWN = 81 SDL_SCANCODE_UP = 82 SDL_SCANCODE_NUMLOCKCLEAR = 83 SDL_SCANCODE_KP_DIVIDE = 84 SDL_SCANCODE_KP_MULTIPLY = 85 SDL_SCANCODE_KP_MINUS = 86 SDL_SCANCODE_KP_PLUS = 87 SDL_SCANCODE_KP_ENTER = 88 SDL_SCANCODE_KP_1 = 89 SDL_SCANCODE_KP_2 = 90 SDL_SCANCODE_KP_3 = 91 SDL_SCANCODE_KP_4 = 92 SDL_SCANCODE_KP_5 = 93 SDL_SCANCODE_KP_6 = 94 SDL_SCANCODE_KP_7 = 95 SDL_SCANCODE_KP_8 = 96 SDL_SCANCODE_KP_9 = 97 SDL_SCANCODE_KP_0 = 98 SDL_SCANCODE_KP_PERIOD = 99 SDL_SCANCODE_NONUSBACKSLASH = 100 SDL_SCANCODE_APPLICATION = 101 SDL_SCANCODE_POWER = 102 SDL_SCANCODE_KP_EQUALS = 103 SDL_SCANCODE_F13 = 104 SDL_SCANCODE_F14 = 105 SDL_SCANCODE_F15 = 106 SDL_SCANCODE_F16 = 107 SDL_SCANCODE_F17 = 108 SDL_SCANCODE_F18 = 109 SDL_SCANCODE_F19 = 110 SDL_SCANCODE_F20 = 111 SDL_SCANCODE_F21 = 112 SDL_SCANCODE_F22 = 113 SDL_SCANCODE_F23 = 114 SDL_SCANCODE_F24 = 115 SDL_SCANCODE_EXECUTE = 116 SDL_SCANCODE_HELP = 117 SDL_SCANCODE_MENU = 118 SDL_SCANCODE_SELECT = 119 SDL_SCANCODE_STOP = 120 SDL_SCANCODE_AGAIN = 121 SDL_SCANCODE_UNDO = 122 SDL_SCANCODE_CUT = 123 SDL_SCANCODE_COPY = 124 SDL_SCANCODE_PASTE = 125 SDL_SCANCODE_FIND = 126 SDL_SCANCODE_MUTE = 127 SDL_SCANCODE_VOLUMEUP = 128 SDL_SCANCODE_VOLUMEDOWN = 129 SDL_SCANCODE_KP_COMMA = 133 SDL_SCANCODE_KP_EQUALSAS400 = 134 SDL_SCANCODE_INTERNATIONAL1 = 135 SDL_SCANCODE_INTERNATIONAL2 = 136 SDL_SCANCODE_INTERNATIONAL3 = 137 SDL_SCANCODE_INTERNATIONAL4 = 138 SDL_SCANCODE_INTERNATIONAL5 = 139 SDL_SCANCODE_INTERNATIONAL6 = 140 SDL_SCANCODE_INTERNATIONAL7 = 141 SDL_SCANCODE_INTERNATIONAL8 = 142 SDL_SCANCODE_INTERNATIONAL9 = 143 SDL_SCANCODE_LANG1 = 144 SDL_SCANCODE_LANG2 = 145 SDL_SCANCODE_LANG3 = 146 SDL_SCANCODE_LANG4 = 147 SDL_SCANCODE_LANG5 = 148 SDL_SCANCODE_LANG6 = 149 SDL_SCANCODE_LANG7 = 150 SDL_SCANCODE_LANG8 = 151 SDL_SCANCODE_LANG9 = 152 SDL_SCANCODE_ALTERASE = 153 SDL_SCANCODE_SYSREQ = 154 SDL_SCANCODE_CANCEL = 155 SDL_SCANCODE_CLEAR = 156 SDL_SCANCODE_PRIOR = 157 SDL_SCANCODE_RETURN2 = 158 SDL_SCANCODE_SEPARATOR = 159 SDL_SCANCODE_OUT = 160 SDL_SCANCODE_OPER = 161 SDL_SCANCODE_CLEARAGAIN = 162 SDL_SCANCODE_CRSEL = 163 SDL_SCANCODE_EXSEL = 164 SDL_SCANCODE_KP_00 = 176 SDL_SCANCODE_KP_000 = 177 SDL_SCANCODE_THOUSANDSSEPARATOR = 178 SDL_SCANCODE_DECIMALSEPARATOR = 179 SDL_SCANCODE_CURRENCYUNIT = 180 SDL_SCANCODE_CURRENCYSUBUNIT = 181 SDL_SCANCODE_KP_LEFTPAREN = 182 SDL_SCANCODE_KP_RIGHTPAREN = 183 SDL_SCANCODE_KP_LEFTBRACE = 184 SDL_SCANCODE_KP_RIGHTBRACE = 185 SDL_SCANCODE_KP_TAB = 186 SDL_SCANCODE_KP_BACKSPACE = 187 SDL_SCANCODE_KP_A = 188 SDL_SCANCODE_KP_B = 189 SDL_SCANCODE_KP_C = 190 SDL_SCANCODE_KP_D = 191 SDL_SCANCODE_KP_E = 192 SDL_SCANCODE_KP_F = 193 SDL_SCANCODE_KP_XOR = 194 SDL_SCANCODE_KP_POWER = 195 SDL_SCANCODE_KP_PERCENT = 196 SDL_SCANCODE_KP_LESS = 197 SDL_SCANCODE_KP_GREATER = 198 SDL_SCANCODE_KP_AMPERSAND = 199 SDL_SCANCODE_KP_DBLAMPERSAND = 200 SDL_SCANCODE_KP_VERTICALBAR = 201 SDL_SCANCODE_KP_DBLVERTICALBAR = 202 SDL_SCANCODE_KP_COLON = 203 SDL_SCANCODE_KP_HASH = 204 SDL_SCANCODE_KP_SPACE = 205 SDL_SCANCODE_KP_AT = 206 SDL_SCANCODE_KP_EXCLAM = 207 SDL_SCANCODE_KP_MEMSTORE = 208 SDL_SCANCODE_KP_MEMRECALL = 209 SDL_SCANCODE_KP_MEMCLEAR = 210 SDL_SCANCODE_KP_MEMADD = 211 SDL_SCANCODE_KP_MEMSUBTRACT = 212 SDL_SCANCODE_KP_MEMMULTIPLY = 213 SDL_SCANCODE_KP_MEMDIVIDE = 214 SDL_SCANCODE_KP_PLUSMINUS = 215 SDL_SCANCODE_KP_CLEAR = 216 SDL_SCANCODE_KP_CLEARENTRY = 217 SDL_SCANCODE_KP_BINARY = 218 SDL_SCANCODE_KP_OCTAL = 219 SDL_SCANCODE_KP_DECIMAL = 220 SDL_SCANCODE_KP_HEXADECIMAL = 221 SDL_SCANCODE_LCTRL = 224 SDL_SCANCODE_LSHIFT = 225 SDL_SCANCODE_LALT = 226 SDL_SCANCODE_LGUI = 227 SDL_SCANCODE_RCTRL = 228 SDL_SCANCODE_RSHIFT = 229 SDL_SCANCODE_RALT = 230 SDL_SCANCODE_RGUI = 231 SDL_SCANCODE_MODE = 257 SDL_SCANCODE_AUDIONEXT = 258 SDL_SCANCODE_AUDIOPREV = 259 SDL_SCANCODE_AUDIOSTOP = 260 SDL_SCANCODE_AUDIOPLAY = 261 SDL_SCANCODE_AUDIOMUTE = 262 SDL_SCANCODE_MEDIASELECT = 263 SDL_SCANCODE_WWW = 264 SDL_SCANCODE_MAIL = 265 SDL_SCANCODE_CALCULATOR = 266 SDL_SCANCODE_COMPUTER = 267 SDL_SCANCODE_AC_SEARCH = 268 SDL_SCANCODE_AC_HOME = 269 SDL_SCANCODE_AC_BACK = 270 SDL_SCANCODE_AC_FORWARD = 271 SDL_SCANCODE_AC_STOP = 272 SDL_SCANCODE_AC_REFRESH = 273 SDL_SCANCODE_AC_BOOKMARKS = 274 SDL_SCANCODE_BRIGHTNESSDOWN = 275 SDL_SCANCODE_BRIGHTNESSUP = 276 SDL_SCANCODE_DISPLAYSWITCH = 277 SDL_SCANCODE_KBDILLUMTOGGLE = 278 SDL_SCANCODE_KBDILLUMDOWN = 279 SDL_SCANCODE_KBDILLUMUP = 280 SDL_SCANCODE_EJECT = 281 SDL_SCANCODE_SLEEP = 282 SDL_NUM_SCANCODES = 512 PySDL2-0.9.3/sdl2/sdlgfx.py0000644000000000000000000002563112323025462012141 0ustar import os from ctypes import Structure, POINTER, c_int, c_float, c_void_p, c_char, \ c_char_p, c_double from .dll import DLL from .stdinc import Uint8, Uint32, Sint16 from .render import SDL_Renderer from .surface import SDL_Surface __all__ = ["get_dll_file", "FPS_UPPER_LIMIT", "FPS_LOWER_LIMIT", "FPS_DEFAULT", "FPSManager", "SDL_initFramerate", "SDL_getFramerate", "SDL_setFramerate", "SDL_getFramecount", "SDL_framerateDelay", "SDL2_GFXPRIMITIVES_MAJOR", "SDL2_GFXPRIMITIVES_MAJOR", "SDL2_GFXPRIMITIVES_MICRO", "pixelColor", "pixelRGBA", "hlineColor", "hlineRGBA", "vlineColor", "vlineRGBA", "rectangleColor", "rectangleRGBA", "roundedRectangleColor", "roundedRectangleRGBA", "boxColor", "boxRGBA", "roundedBoxColor", "roundedBoxRGBA", "lineColor", "lineRGBA", "aalineColor", "aalineRGBA", "thickLineColor", "thickLineRGBA", "circleColor", "circleRGBA", "arcColor", "arcRGBA", "aacircleColor", "aacircleRGBA", "filledCircleColor", "filledCircleRGBA", "ellipseColor", "ellipseRGBA", "aaellipseColor", "aaellipseRGBA", "filledEllipseColor", "filledEllipseRGBA", "pieColor", "pieRGBA", "filledPieColor", "filledPieRGBA", "trigonColor", "trigonRGBA", "aatrigonColor", "aatrigonRGBA", "filledTrigonColor", "filledTrigonRGBA", "polygonColor", "polygonRGBA", "aapolygonColor", "aapolygonRGBA", "filledPolygonColor", "filledPolygonRGBA", "texturedPolygon", "bezierColor", "bezierRGBA", "gfxPrimitivesSetFont", "gfxPrimitivesSetFontRotation", "characterColor", "characterRGBA", "stringColor", "stringRGBA", "SMOOTHING_OFF", "SMOOTHING_ON", "rotozoomSurface", "rotozoomSurfaceXY", "rotozoomSurfaceSize", "rotozoomSurfaceSizeXY", "zoomSurface", "zoomSurfaceSize", "shrinkSurface", "rotateSurface90Degrees" ] try: dll = DLL("SDL2_gfx", ["SDL2_gfx", "SDL2_gfx-1.0"], os.getenv("PYSDL2_DLL_PATH")) except RuntimeError as exc: raise ImportError(exc) def get_dll_file(): """Gets the file name of the loaded SDL2_gfx library.""" return dll.libfile _bind = dll.bind_function FPS_UPPER_LIMIT = 200 FPS_LOWER_LIMIT = 1 FPS_DEFAULT = 30 class FPSManager(Structure): _fields_ = [("framecount", Uint32), ("rateticks", c_float), ("baseticks", Uint32), ("lastticks", Uint32), ("rate", Uint32) ] SDL_initFramerate = _bind("SDL_initFramerate", [POINTER(FPSManager)]) SDL_setFramerate = _bind("SDL_setFramerate", [POINTER(FPSManager), Uint32], c_int) SDL_getFramerate = _bind("SDL_getFramerate", [POINTER(FPSManager)], c_int) SDL_getFramecount = _bind("SDL_getFramecount", [POINTER(FPSManager)], Uint32) SDL_framerateDelay = _bind("SDL_framerateDelay", [POINTER(FPSManager)], Uint32) SDL2_GFXPRIMITIVES_MAJOR = 1 SDL2_GFXPRIMITIVES_MINOR = 0 SDL2_GFXPRIMITIVES_MICRO = 0 pixelColor = _bind("pixelColor", [POINTER(SDL_Renderer), Sint16, Sint16, Uint32], c_int) pixelRGBA = _bind("pixelRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) hlineColor = _bind("hlineColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint32], c_int) hlineRGBA = _bind("hlineRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) vlineColor = _bind("vlineColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint32], c_int) vlineRGBA = _bind("vlineRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) rectangleColor = _bind("rectangleColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int) rectangleRGBA = _bind("rectangleRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) roundedRectangleColor = _bind("roundedRectangleColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int) roundedRectangleRGBA = _bind("roundedRectangleRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) boxColor = _bind("boxColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int) boxRGBA = _bind("boxRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) roundedBoxColor = _bind("roundedBoxColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int) roundedBoxRGBA = _bind("roundedBoxRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) lineColor = _bind("lineColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int) lineRGBA = _bind("lineRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) aalineColor = _bind("aalineColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int) aalineRGBA = _bind("aalineRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) thickLineColor = _bind("thickLineColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint32], c_int) thickLineRGBA = _bind("thickLineRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8, Uint8], c_int) circleColor = _bind("circleColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint32], c_int) circleRGBA = _bind("circleRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) arcColor = _bind("arcColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int) arcRGBA = _bind("arcRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) aacircleColor = _bind("aacircleColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint32], c_int) aacircleRGBA = _bind("aacircleRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) filledCircleColor = _bind("filledCircleColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint32], c_int) filledCircleRGBA = _bind("filledCircleRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) ellipseColor = _bind("ellipseColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int) ellipseRGBA = _bind("ellipseRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) aaellipseColor = _bind("aaellipseColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int) aaellipseRGBA = _bind("aaellipseRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) filledEllipseColor = _bind("filledEllipseColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint32], c_int) filledEllipseRGBA = _bind("filledEllipseRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) pieColor = _bind("pieColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int) pieRGBA = _bind("pieRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) filledPieColor = _bind("filledPieColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int) filledPieRGBA = _bind("filledPieRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) trigonColor = _bind("trigonColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int) trigonRGBA = _bind("trigonRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) aatrigonColor = _bind("aatrigonColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int) aatrigonRGBA = _bind("aatrigonRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) filledTrigonColor = _bind("filledTrigonColor", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Sint16, Uint32], c_int) filledTrigonRGBA = _bind("filledTrigonRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, Sint16, Sint16, Sint16, Sint16, Uint8, Uint8, Uint8, Uint8], c_int) polygonColor = _bind("polygonColor", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, Uint32], c_int) polygonRGBA = _bind("polygonRGBA", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, Uint8, Uint8, Uint8, Uint8], c_int) aapolygonColor = _bind("aapolygonColor", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, Uint32], c_int) aapolygonRGBA = _bind("aapolygonRGBA", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, Uint8, Uint8, Uint8, Uint8], c_int) filledPolygonColor = _bind("filledPolygonColor", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, Uint32], c_int) filledPolygonRGBA = _bind("filledPolygonRGBA", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, Uint8, Uint8, Uint8, Uint8], c_int) texturedPolygon = _bind("texturedPolygon", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, POINTER(SDL_Surface), c_int, c_int], c_int) bezierColor = _bind("bezierColor", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, c_int, Uint32], c_int) bezierRGBA = _bind("bezierRGBA", [POINTER(SDL_Renderer), POINTER(Sint16), POINTER(Sint16), c_int, c_int, Uint8, Uint8, Uint8, Uint8], c_int) gfxPrimitivesSetFont = _bind("gfxPrimitivesSetFont", [c_void_p, Uint32, Uint32]) gfxPrimitivesSetFontRotation = _bind("gfxPrimitivesSetFontRotation", [Uint32]) characterColor = _bind("characterColor", [POINTER(SDL_Renderer), Sint16, Sint16, c_char, Uint32], c_int) characterRGBA = _bind("characterRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, c_char, Uint8, Uint8, Uint8, Uint8], c_int) stringColor = _bind("stringColor", [POINTER(SDL_Renderer), Sint16, Sint16, c_char_p, Uint32], c_int) stringRGBA = _bind("stringRGBA", [POINTER(SDL_Renderer), Sint16, Sint16, c_char_p, Uint8, Uint8, Uint8, Uint8], c_int) SMOOTHING_OFF = 0 SMOOTHING_ON = 1 rotozoomSurface = _bind("rotozoomSurface", [POINTER(SDL_Surface), c_double, c_double, c_int], POINTER(SDL_Surface)) rotozoomSurfaceXY = _bind("rotozoomSurfaceXY", [POINTER(SDL_Surface), c_double, c_double, c_double, c_int], POINTER(SDL_Surface)) rotozoomSurfaceSize = _bind("rotozoomSurfaceSize", [c_int, c_int, c_double, c_double, POINTER(c_int), POINTER(c_int)]) rotozoomSurfaceSizeXY = _bind("rotozoomSurfaceSizeXY", [c_int, c_int, c_double, c_double, c_double, POINTER(c_int), POINTER(c_int)]) zoomSurface = _bind("zoomSurface", [POINTER(SDL_Surface), c_double, c_double, c_int], POINTER(SDL_Surface)) zoomSurfaceSize = _bind("zoomSurfaceSize", [c_int, c_int, c_double, c_double, POINTER(c_int), POINTER(c_int)]) shrinkSurface = _bind("shrinkSurface", [POINTER(SDL_Surface), c_int, c_int], POINTER(SDL_Surface)) rotateSurface90Degrees = _bind("rotateSurface90Degrees", [POINTER(SDL_Surface), c_int], POINTER(SDL_Surface)) PySDL2-0.9.3/sdl2/sdlimage.py0000644000000000000000000001211412323025462012427 0ustar import os from ctypes import POINTER, c_int, c_char_p from .dll import DLL from .version import SDL_version from .surface import SDL_Surface from .rwops import SDL_RWops from .render import SDL_Texture, SDL_Renderer from .error import SDL_SetError, SDL_GetError __all__ = ["SDL_IMAGE_MAJOR_VERSION", "SDL_IMAGE_MINOR_VERSION", \ "SDL_IMAGE_PATCHLEVEL", "SDL_IMAGE_VERSION", "IMG_Linked_Version", "IMG_InitFlags", "IMG_INIT_JPG", "IMG_INIT_PNG", "IMG_INIT_TIF", "IMG_INIT_WEBP", "IMG_Init", "IMG_Quit", "IMG_LoadTyped_RW", "IMG_Load", "IMG_Load_RW", "IMG_LoadTexture", "IMG_LoadTexture_RW", "IMG_LoadTextureTyped_RW", "IMG_isICO", "IMG_isCUR", "IMG_isBMP", "IMG_isGIF", "IMG_isJPG", "IMG_isLBM", "IMG_isPNG", "IMG_isPNM", "IMG_isPCX", "IMG_isTIF", "IMG_isXCF", "IMG_isXV", "IMG_isWEBP", "IMG_LoadBMP_RW", "IMG_LoadCUR_RW", "IMG_LoadCUR_RW", "IMG_LoadGIF_RW", "IMG_LoadICO_RW", "IMG_LoadJPG_RW", "IMG_LoadLBM_RW", "IMG_LoadPCX_RW", "IMG_LoadPNM_RW", "IMG_LoadPNG_RW", "IMG_LoadTGA_RW", "IMG_LoadTIF_RW", "IMG_LoadXCF_RW", "IMG_LoadWEBP_RW", "IMG_LoadXPM_RW", "IMG_LoadXV_RW", "IMG_ReadXPMFromArray", "IMG_GetError", "IMG_SetError", "get_dll_file" ] try: dll = DLL("SDL2_image", ["SDL2_image", "SDL2_image-2.0"], os.getenv("PYSDL2_DLL_PATH")) except RuntimeError as exc: raise ImportError(exc) def get_dll_file(): """Gets the file name of the loaded SDL2_image library.""" return dll.libfile _bind = dll.bind_function SDL_IMAGE_MAJOR_VERSION = 2 SDL_IMAGE_MINOR_VERSION = 0 SDL_IMAGE_PATCHLEVEL = 0 def SDL_IMAGE_VERSION(x): x.major = SDL_IMAGE_MAJOR_VERSION x.minor = SDL_IMAGE_MINOR_VERSION x.patch = SDL_IMAGE_PATCHLEVEL IMG_Linked_Version = _bind("IMG_Linked_Version", None, POINTER(SDL_version)) IMG_InitFlags = c_int IMG_INIT_JPG = 0x00000001 IMG_INIT_PNG = 0x00000002 IMG_INIT_TIF = 0x00000004 IMG_INIT_WEBP = 0x00000008 IMG_Init = _bind("IMG_Init", [c_int], c_int) IMG_Quit = _bind("IMG_Quit") IMG_LoadTyped_RW = _bind("IMG_LoadTyped_RW", [POINTER(SDL_RWops), c_int, c_char_p], POINTER(SDL_Surface)) IMG_Load = _bind("IMG_Load", [c_char_p], POINTER(SDL_Surface)) IMG_Load_RW = _bind("IMG_Load_RW", [POINTER(SDL_RWops), c_int], POINTER(SDL_Surface)) IMG_LoadTexture = _bind("IMG_LoadTexture", [POINTER(SDL_Renderer), c_char_p], POINTER(SDL_Texture)) IMG_LoadTexture_RW = _bind("IMG_LoadTexture_RW", [POINTER(SDL_Renderer), POINTER(SDL_RWops), c_int], POINTER(SDL_Texture)) IMG_LoadTextureTyped_RW = _bind("IMG_LoadTextureTyped_RW", [POINTER(SDL_Renderer), POINTER(SDL_RWops), c_int, c_char_p], POINTER(SDL_Texture)) IMG_isICO = _bind("IMG_isICO", [POINTER(SDL_RWops)], c_int) IMG_isCUR = _bind("IMG_isCUR", [POINTER(SDL_RWops)], c_int) IMG_isBMP = _bind("IMG_isBMP", [POINTER(SDL_RWops)], c_int) IMG_isGIF = _bind("IMG_isGIF", [POINTER(SDL_RWops)], c_int) IMG_isJPG = _bind("IMG_isJPG", [POINTER(SDL_RWops)], c_int) IMG_isLBM = _bind("IMG_isLBM", [POINTER(SDL_RWops)], c_int) IMG_isPCX = _bind("IMG_isPCX", [POINTER(SDL_RWops)], c_int) IMG_isPNG = _bind("IMG_isPNG", [POINTER(SDL_RWops)], c_int) IMG_isPNM = _bind("IMG_isPNM", [POINTER(SDL_RWops)], c_int) IMG_isTIF = _bind("IMG_isTIF", [POINTER(SDL_RWops)], c_int) IMG_isXCF = _bind("IMG_isXCF", [POINTER(SDL_RWops)], c_int) IMG_isXPM = _bind("IMG_isXPM", [POINTER(SDL_RWops)], c_int) IMG_isXV = _bind("IMG_isXV", [POINTER(SDL_RWops)], c_int) IMG_isWEBP = _bind("IMG_isWEBP", [POINTER(SDL_RWops)], c_int) IMG_LoadICO_RW = _bind("IMG_LoadICO_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadCUR_RW = _bind("IMG_LoadCUR_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadBMP_RW = _bind("IMG_LoadBMP_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadGIF_RW = _bind("IMG_LoadGIF_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadJPG_RW = _bind("IMG_LoadJPG_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadLBM_RW = _bind("IMG_LoadLBM_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadPCX_RW = _bind("IMG_LoadPCX_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadPNG_RW = _bind("IMG_LoadPNG_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadPNM_RW = _bind("IMG_LoadPNM_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadTGA_RW = _bind("IMG_LoadTGA_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadTIF_RW = _bind("IMG_LoadTIF_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadXCF_RW = _bind("IMG_LoadXCF_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadXPM_RW = _bind("IMG_LoadXPM_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadXV_RW = _bind("IMG_LoadXV_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_LoadWEBP_RW = _bind("IMG_LoadWEBP_RW", [POINTER(SDL_RWops)], POINTER(SDL_Surface)) IMG_ReadXPMFromArray = _bind("IMG_ReadXPMFromArray", [POINTER(c_char_p)], POINTER(SDL_Surface)) IMG_SavePNG = _bind("IMG_SavePNG", [POINTER(SDL_Surface), c_char_p], c_int) IMG_SavePNG_RW = _bind("IMG_SavePNG_RW", [POINTER(SDL_Surface), POINTER(SDL_RWops), c_int], c_int) IMG_SetError = SDL_SetError IMG_GetError = SDL_GetError PySDL2-0.9.3/sdl2/sdlmixer.py0000644000000000000000000002416412323025462012501 0ustar import os from ctypes import Structure, POINTER, CFUNCTYPE, c_int, c_char_p, c_void_p, \ c_double from .dll import DLL from .version import SDL_version from .audio import AUDIO_S16LSB, AUDIO_S16MSB from .stdinc import Uint8, Uint16, Uint32, Sint16 from .endian import SDL_LIL_ENDIAN, SDL_BYTEORDER from .rwops import SDL_RWops, SDL_RWFromFile from .error import SDL_SetError, SDL_GetError __all__ = ["get_dll_file", "SDL_MIXER_MAJOR_VERSION", "SDL_MIXER_MINOR_VERSION", "SDL_MIXER_PATCHLEVEL", "SDL_MIXER_VERSION", "MIX_MAJOR_VERSION", "MIX_MINOR_VERSION", "MIX_PATCHLEVEL", "MIX_VERSION", "Mix_Linked_Version", "MIX_InitFlags", "MIX_INIT_FLAC", "MIX_INIT_MOD", "MIX_INIT_MP3", "MIX_INIT_OGG", "MIX_INIT_FLUIDSYNTH", "Mix_Init", "Mix_Quit", "MIX_CHANNELS", "MIX_DEFAULT_FREQUENCY" , "MIX_DEFAULT_FORMAT", "MIX_DEFAULT_CHANNELS", "MIX_MAX_VOLUME", "Mix_Chunk", "Mix_Fading", "MIX_NO_FADING", "MIX_FADING_OUT", "MIX_FADING_IN", "Mix_MusicType", "MUS_NONE", "MUS_CMD", "MUS_WAV", "MUS_MOD", "MUS_MID", "MUS_OGG", "MUS_MP3", "MUS_MP3_MAD", "MUS_FLAC", "MUS_MODPLUG", "Mix_Music", "Mix_OpenAudio", "Mix_AllocateChannels", "Mix_QuerySpec", "Mix_LoadWAV_RW", "Mix_LoadWAV", "Mix_LoadMUS", "Mix_LoadMUS_RW", "Mix_LoadMUSType_RW", "Mix_QuickLoad_WAV", "Mix_QuickLoad_RAW", "Mix_FreeChunk", "Mix_FreeMusic", "Mix_GetNumChunkDecoders", "Mix_GetChunkDecoder", "Mix_GetNumMusicDecoders", "Mix_GetMusicDecoder", "Mix_GetMusicType", "mix_func", "Mix_SetPostMix", "Mix_HookMusic", "music_finished", "Mix_HookMusicFinished", "Mix_GetMusicHookData", "channel_finished", "Mix_ChannelFinished", "MIX_CHANNEL_POST", "Mix_EffectFunc_t", "Mix_EffectDone_t", "Mix_RegisterEffect", "Mix_UnregisterEffect", "Mix_UnregisterAllEffects", "MIX_EFFECTSMAXSPEED", "Mix_SetPanning", "Mix_SetPosition", "Mix_SetDistance", "Mix_SetReverseStereo", "Mix_ReserveChannels", "Mix_GroupChannel", "Mix_GroupChannels", "Mix_GroupAvailable", "Mix_GroupCount", "Mix_GroupOldest", "Mix_GroupNewer", "Mix_PlayChannel", "Mix_PlayChannelTimed", "Mix_PlayMusic", "Mix_FadeInMusic", "Mix_FadeInMusicPos", "Mix_FadeInChannel", "Mix_FadeInChannelTimed", "Mix_Volume", "Mix_VolumeChunk", "Mix_VolumeMusic", "Mix_HaltChannel", "Mix_HaltGroup", "Mix_HaltMusic", "Mix_ExpireChannel", "Mix_FadeOutChannel", "Mix_FadeOutGroup", "Mix_FadeOutMusic", "Mix_FadingMusic", "Mix_FadingChannel", "Mix_Pause", "Mix_Resume", "Mix_Paused", "Mix_PauseMusic", "Mix_ResumeMusic", "Mix_RewindMusic", "Mix_PausedMusic", "Mix_SetMusicPosition", "Mix_Playing", "Mix_PlayingMusic", "Mix_SetMusicCMD", "Mix_SetSynchroValue", "Mix_GetSynchroValue", "Mix_SetSoundFonts", "Mix_GetSoundFonts", "soundfont_function", "Mix_EachSoundFont", "Mix_GetChunk", "Mix_CloseAudio", "Mix_SetError", "Mix_GetError" ] try: dll = DLL("SDL2_mixer", ["SDL2_mixer", "SDL2_mixer-2.0"], os.getenv("PYSDL2_DLL_PATH")) except RuntimeError as exc: raise ImportError(exc) def get_dll_file(): """Gets the file name of the loaded SDL2_mixer library.""" return dll.libfile _bind = dll.bind_function SDL_MIXER_MAJOR_VERSION = 2 SDL_MIXER_MINOR_VERSION = 0 SDL_MIXER_PATCHLEVEL = 0 def SDL_MIXER_VERSION(x): x.major = SDL_MIXER_MAJOR_VERSION x.minor = SDL_MIXER_MINOR_VERSION x.patch = SDL_MIXER_PATCHLEVEL MIX_MAJOR_VERSION = SDL_MIXER_MAJOR_VERSION MIX_MINOR_VERSION = SDL_MIXER_MINOR_VERSION MIX_PATCHLEVEL = SDL_MIXER_PATCHLEVEL MIX_VERSION = SDL_MIXER_VERSION Mix_Linked_Version = _bind("Mix_Linked_Version", None, POINTER(SDL_version)) MIX_InitFlags = c_int MIX_INIT_FLAC = 0x00000001 MIX_INIT_MOD = 0x00000002 MIX_INIT_MP3 = 0x00000004 MIX_INIT_OGG = 0x00000008 MIX_INIT_FLUIDSYNTH = 0x00000010 Mix_Init = _bind("Mix_Init", [c_int], c_int) Mix_Quit = _bind("Mix_Quit") MIX_CHANNELS = 8 MIX_DEFAULT_FREQUENCY = 22050 if SDL_BYTEORDER == SDL_LIL_ENDIAN: MIX_DEFAULT_FORMAT = AUDIO_S16LSB else: MIX_DEFAULT_FORMAT = AUDIO_S16MSB MIX_DEFAULT_CHANNELS = 2 MIX_MAX_VOLUME = 128 class Mix_Chunk(Structure): _fields_ = [("allocated", c_int), ("abuf", POINTER(Uint8)), ("alen", Uint32), ("volume", Uint8)] Mix_Fading = c_int MIX_NO_FADING = 0 MIX_FADING_OUT = 1 MIX_FADING_IN = 2 Mix_MusicType = c_int MUS_NONE = 0 MUS_CMD = 1 MUS_WAV = 2 MUS_MOD = 3 MUS_MID = 4 MUS_OGG = 5 MUS_MP3 = 6 MUS_MP3_MAD = 7 MUS_FLAC = 8 MUS_MODPLUG = 9 class Mix_Music(Structure): pass Mix_OpenAudio = _bind("Mix_OpenAudio", [c_int, Uint16, c_int, c_int], c_int) Mix_AllocateChannels = _bind("Mix_AllocateChannels", [c_int], c_int) Mix_QuerySpec = _bind("Mix_QuerySpec", [POINTER(c_int), POINTER(Uint16), POINTER(c_int)], c_int) Mix_LoadWAV_RW = _bind("Mix_LoadWAV_RW", [POINTER(SDL_RWops), c_int], POINTER(Mix_Chunk)) Mix_LoadWAV = lambda fname: Mix_LoadWAV_RW(SDL_RWFromFile(fname, b"rb"), 1) Mix_LoadMUS = _bind("Mix_LoadMUS", [c_char_p], POINTER(Mix_Music)) Mix_LoadMUS_RW = _bind("Mix_LoadMUS_RW", [POINTER(SDL_RWops)], POINTER(Mix_Music)) Mix_LoadMUSType_RW = _bind("Mix_LoadMUSType_RW", [POINTER(SDL_RWops), Mix_MusicType, c_int], POINTER(Mix_Music)) Mix_QuickLoad_WAV = _bind("Mix_QuickLoad_WAV", [POINTER(Uint8)], POINTER(Mix_Chunk)) Mix_QuickLoad_RAW = _bind("Mix_QuickLoad_RAW", [POINTER(Uint8), Uint32], POINTER(Mix_Chunk)) Mix_FreeChunk = _bind("Mix_FreeChunk", [POINTER(Mix_Chunk)]) Mix_FreeMusic = _bind("Mix_FreeMusic", [POINTER(Mix_Music)]) Mix_GetNumChunkDecoders = _bind("Mix_GetNumChunkDecoders", None, c_int) Mix_GetChunkDecoder = _bind("Mix_GetChunkDecoder", [c_int], c_char_p) Mix_GetNumMusicDecoders = _bind("Mix_GetNumMusicDecoders", None, c_int) Mix_GetMusicDecoder = _bind("Mix_GetMusicDecoder", [c_int], c_char_p) Mix_GetMusicType = _bind("Mix_GetMusicType", [POINTER(Mix_Music)], Mix_MusicType) mix_func = CFUNCTYPE(None, c_void_p, POINTER(Uint8), c_int) Mix_SetPostMix = _bind("Mix_SetPostMix", [mix_func, c_void_p]) Mix_HookMusic = _bind("Mix_HookMusic", [mix_func, c_void_p]) music_finished = CFUNCTYPE(None) Mix_HookMusicFinished = _bind("Mix_HookMusicFinished", [music_finished]) Mix_GetMusicHookData = _bind("Mix_GetMusicHookData", None, c_void_p) channel_finished = CFUNCTYPE(None, c_int) Mix_ChannelFinished = _bind("Mix_ChannelFinished", [channel_finished]) MIX_CHANNEL_POST = -2 Mix_EffectFunc_t = CFUNCTYPE(None, c_int, c_void_p, c_int, c_void_p) Mix_EffectDone_t = CFUNCTYPE(None, c_int, c_void_p) Mix_RegisterEffect = _bind("Mix_RegisterEffect", [c_int, Mix_EffectFunc_t, Mix_EffectDone_t, c_void_p], c_int) Mix_UnregisterEffect = _bind("Mix_UnregisterEffect", [c_int, Mix_EffectFunc_t], c_int) Mix_UnregisterAllEffects = _bind("Mix_UnregisterAllEffects", [c_int]) MIX_EFFECTSMAXSPEED = "MIX_EFFECTSMAXSPEED" Mix_SetPanning = _bind("Mix_SetPanning", [c_int, Uint8, Uint8], c_int) Mix_SetPosition = _bind("Mix_SetPosition", [c_int, Sint16, Uint8], c_int) Mix_SetDistance = _bind("Mix_SetDistance", [c_int, Uint8]) Mix_SetReverseStereo = _bind("Mix_SetReverseStereo", [c_int, c_int], c_int) Mix_ReserveChannels = _bind("Mix_ReserveChannels", [c_int], c_int) Mix_GroupChannel = _bind("Mix_GroupChannel", [c_int, c_int], c_int) Mix_GroupChannels = _bind("Mix_GroupChannels", [c_int, c_int, c_int], c_int) Mix_GroupAvailable = _bind("Mix_GroupAvailable", [c_int], c_int) Mix_GroupCount = _bind("Mix_GroupCount", [c_int], c_int) Mix_GroupOldest = _bind("Mix_GroupOldest", [c_int], c_int) Mix_GroupNewer = _bind("Mix_GroupNewer", [c_int], c_int) Mix_PlayChannel = lambda channel, chunk, loops: Mix_PlayChannelTimed(channel, chunk, loops, -1) Mix_PlayChannelTimed = _bind("Mix_PlayChannelTimed", [c_int, POINTER(Mix_Chunk), c_int, c_int], c_int) Mix_PlayMusic = _bind("Mix_PlayMusic", [POINTER(Mix_Music), c_int], c_int) Mix_FadeInMusic = _bind("Mix_FadeInMusic", [POINTER(Mix_Music), c_int, c_int], c_int) Mix_FadeInMusicPos = _bind("Mix_FadeInMusicPos", [POINTER(Mix_Music), c_int, c_int, c_double], c_int) Mix_FadeInChannel = lambda channel, chunk, loops, ms: Mix_FadeInChannelTimed(channel, chunk, loops, ms, -1) Mix_FadeInChannelTimed = _bind("Mix_FadeInChannelTimed", [c_int, POINTER(Mix_Chunk), c_int, c_int, c_int], c_int) Mix_Volume = _bind("Mix_Volume", [c_int, c_int], c_int) Mix_VolumeChunk = _bind("Mix_VolumeChunk", [POINTER(Mix_Chunk), c_int], c_int) Mix_VolumeMusic = _bind("Mix_VolumeMusic", [c_int], c_int) Mix_HaltChannel = _bind("Mix_HaltChannel", [c_int], c_int) Mix_HaltGroup = _bind("Mix_HaltGroup", [c_int], c_int) Mix_HaltMusic = _bind("Mix_HaltMusic", None, c_int) Mix_ExpireChannel = _bind("Mix_ExpireChannel", [c_int, c_int], c_int) Mix_FadeOutChannel = _bind("Mix_FadeOutChannel", [c_int, c_int], c_int) Mix_FadeOutGroup = _bind("Mix_FadeOutGroup", [c_int, c_int], c_int) Mix_FadeOutMusic = _bind("Mix_FadeOutMusic", [c_int], c_int) Mix_FadingMusic = _bind("Mix_FadingMusic", None, Mix_Fading) Mix_FadingChannel = _bind("Mix_FadingChannel", [c_int], Mix_Fading) Mix_Pause = _bind("Mix_Pause", [c_int]) Mix_Resume = _bind("Mix_Resume", [c_int]) Mix_Paused = _bind("Mix_Paused", [c_int], c_int) Mix_PauseMusic = _bind("Mix_PauseMusic") Mix_ResumeMusic = _bind("Mix_ResumeMusic") Mix_RewindMusic = _bind("Mix_RewindMusic") Mix_PausedMusic = _bind("Mix_PauseMusic", None, c_int) Mix_SetMusicPosition = _bind("Mix_SetMusicPosition", [c_double], c_int) Mix_Playing = _bind("Mix_Playing", [c_int], c_int) Mix_PlayingMusic = _bind("Mix_PlayingMusic", None, c_int) Mix_SetMusicCMD = _bind("Mix_SetMusicCMD", [c_char_p], c_int) Mix_SetSynchroValue = _bind("Mix_SetSynchroValue", [c_int], c_int) Mix_GetSynchroValue = _bind("Mix_GetSynchroValue", None, c_int) Mix_SetSoundFonts = _bind("Mix_SetSoundFonts", [c_char_p], c_int) Mix_GetSoundFonts = _bind("Mix_GetSoundFonts", None, c_char_p) soundfont_function = CFUNCTYPE(c_int, c_char_p, c_void_p) Mix_EachSoundFont = _bind("Mix_EachSoundFont", [soundfont_function, c_void_p], c_int) Mix_GetChunk = _bind("Mix_GetChunk", [c_int], POINTER(Mix_Chunk)) Mix_CloseAudio = _bind("Mix_CloseAudio") Mix_SetError = SDL_SetError Mix_GetError = SDL_GetError PySDL2-0.9.3/sdl2/sdlttf.py0000644000000000000000000001726712323025462012160 0ustar import os from ctypes import Structure, POINTER, c_int, c_long, c_char_p from .dll import DLL from .version import SDL_version from .rwops import SDL_RWops from .stdinc import Uint16, Uint32 from .pixels import SDL_Color from .surface import SDL_Surface from .error import SDL_GetError, SDL_SetError __all__ = ["get_dll_file", "SDL_TTF_MAJOR_VERSION", "SDL_TTF_MINOR_VERSION", "SDL_TTF_PATCHLEVEL", "SDL_TTF_VERSION", "TTF_MAJOR_VERSION", "TTF_MINOR_VERSION", "TTF_PATCHLEVEL", "TTF_VERSION", "TTF_Linked_Version", "UNICODE_BOM_NATIVE", "UNICODE_BOM_SWAPPED", "TTF_ByteSwappedUNICODE", "TTF_Font", "TTF_Init", "TTF_OpenFont", "TTF_OpenFontIndex", "TTF_OpenFontRW", "TTF_OpenFontIndexRW", "TTF_STYLE_NORMAL", "TTF_STYLE_BOLD", "TTF_STYLE_ITALIC", "TTF_STYLE_UNDERLINE", "TTF_STYLE_STRIKETHROUGH", "TTF_GetFontStyle", "TTF_SetFontStyle", "TTF_GetFontOutline", "TTF_SetFontOutline", "TTF_HINTING_NORMAL", "TTF_HINTING_LIGHT", "TTF_HINTING_MONO", "TTF_HINTING_NONE", "TTF_GetFontHinting", "TTF_SetFontHinting", "TTF_FontHeight", "TTF_FontAscent", "TTF_FontDescent", "TTF_FontLineSkip", "TTF_GetFontKerning", "TTF_SetFontKerning", "TTF_FontFaces", "TTF_FontFaceIsFixedWidth", "TTF_FontFaceFamilyName", "TTF_FontFaceStyleName", "TTF_GlyphIsProvided", "TTF_GlyphMetrics", "TTF_SizeText", "TTF_SizeUTF8", "TTF_SizeUNICODE", "TTF_RenderText_Solid", "TTF_RenderUTF8_Solid", "TTF_RenderUNICODE_Solid", "TTF_RenderGlyph_Solid", "TTF_RenderText_Shaded", "TTF_RenderUTF8_Shaded", "TTF_RenderUNICODE_Shaded", "TTF_RenderGlyph_Shaded", "TTF_RenderText_Blended", "TTF_RenderUTF8_Blended", "TTF_RenderUNICODE_Blended", "TTF_RenderText_Blended_Wrapped", "TTF_RenderUTF8_Blended_Wrapped", "TTF_RenderUNICODE_Blended_Wrapped", "TTF_RenderGlyph_Blended", "TTF_RenderText", "TTF_RenderUTF", "TTF_RenderUNICODE", "TTF_CloseFont", "TTF_Quit", "TTF_WasInit", "TTF_GetFontKerningSize", "TTF_SetError", "TTF_GetError" ] try: dll = DLL("SDL2_ttf", ["SDL2_ttf", "SDL2_ttf-2.0"], os.getenv("PYSDL2_DLL_PATH")) except RuntimeError as exc: raise ImportError(exc) def get_dll_file(): """Gets the file name of the loaded SDL2_ttf library.""" return dll.libfile _bind = dll.bind_function SDL_TTF_MAJOR_VERSION = 2 SDL_TTF_MINOR_VERSION = 0 SDL_TTF_PATCHLEVEL = 12 def SDL_TTF_VERSION(x): x.major = SDL_TTF_MAJOR_VERSION x.minor = SDL_TTF_MINOR_VERSION x.patch = SDL_TTF_PATCHLEVEL TTF_MAJOR_VERSION = SDL_TTF_MAJOR_VERSION TTF_MINOR_VERSION = SDL_TTF_MINOR_VERSION TTF_PATCHLEVEL = SDL_TTF_PATCHLEVEL TTF_VERSION = SDL_TTF_VERSION TTF_Linked_Version = _bind("TTF_Linked_Version", None, POINTER(SDL_version)) UNICODE_BOM_NATIVE = 0xFEFF UNICODE_BOM_SWAPPED = 0xFFFE TTF_ByteSwappedUNICODE = _bind("TTF_ByteSwappedUNICODE", [c_int]) class TTF_Font(Structure): pass TTF_Init = _bind("TTF_Init", None, c_int) TTF_OpenFont = _bind("TTF_OpenFont", [c_char_p, c_int], POINTER(TTF_Font)) TTF_OpenFontIndex = _bind("TTF_OpenFontIndex", [c_char_p, c_int, c_long], POINTER(TTF_Font)) TTF_OpenFontRW = _bind("TTF_OpenFontRW", [POINTER(SDL_RWops), c_int, c_int], POINTER(TTF_Font)) TTF_OpenFontIndexRW = _bind("TTF_OpenFontIndexRW", [POINTER(SDL_RWops), c_int, c_int, c_long], POINTER(TTF_Font)) TTF_STYLE_NORMAL = 0x00 TTF_STYLE_BOLD = 0x01 TTF_STYLE_ITALIC = 0x02 TTF_STYLE_UNDERLINE = 0x04 TTF_STYLE_STRIKETHROUGH = 0x08 TTF_GetFontStyle = _bind("TTF_GetFontStyle", [POINTER(TTF_Font)], c_int) TTF_SetFontStyle = _bind("TTF_SetFontStyle", [POINTER(TTF_Font), c_int]) TTF_GetFontOutline = _bind("TTF_GetFontOutline", [POINTER(TTF_Font)], c_int) TTF_SetFontOutline = _bind("TTF_SetFontOutline", [POINTER(TTF_Font), c_int]) TTF_HINTING_NORMAL = 0 TTF_HINTING_LIGHT = 1 TTF_HINTING_MONO = 2 TTF_HINTING_NONE = 3 TTF_GetFontHinting = _bind("TTF_GetFontHinting", [POINTER(TTF_Font)], c_int) TTF_SetFontHinting = _bind("TTF_SetFontHinting", [POINTER(TTF_Font), c_int]) TTF_FontHeight = _bind("TTF_FontHeight", [POINTER(TTF_Font)], c_int) TTF_FontAscent = _bind("TTF_FontAscent", [POINTER(TTF_Font)], c_int) TTF_FontDescent = _bind("TTF_FontDescent", [POINTER(TTF_Font)], c_int) TTF_FontLineSkip = _bind("TTF_FontLineSkip", [POINTER(TTF_Font)], c_int) TTF_GetFontKerning = _bind("TTF_GetFontKerning", [POINTER(TTF_Font)], c_int) TTF_SetFontKerning = _bind("TTF_SetFontKerning", [POINTER(TTF_Font), c_int]) TTF_FontFaces = _bind("TTF_FontFaces", [POINTER(TTF_Font)], c_long) TTF_FontFaceIsFixedWidth = _bind("TTF_FontFaceIsFixedWidth", [POINTER(TTF_Font)], c_int) TTF_FontFaceFamilyName = _bind("TTF_FontFaceFamilyName", [POINTER(TTF_Font)], c_char_p) TTF_FontFaceStyleName = _bind("TTF_FontFaceStyleName", [POINTER(TTF_Font)], c_char_p) TTF_GlyphIsProvided = _bind("TTF_GlyphIsProvided", [POINTER(TTF_Font), Uint16], c_int) TTF_GlyphMetrics = _bind("TTF_GlyphMetrics", [POINTER(TTF_Font), Uint16, POINTER(c_int), POINTER(c_int), POINTER(c_int), POINTER(c_int), POINTER(c_int)], c_int) TTF_SizeText = _bind("TTF_SizeText", [POINTER(TTF_Font), c_char_p, POINTER(c_int), POINTER(c_int)], c_int) TTF_SizeUTF8 = _bind("TTF_SizeUTF8", [POINTER(TTF_Font), c_char_p, POINTER(c_int), POINTER(c_int)], c_int) TTF_SizeUNICODE = _bind("TTF_SizeUNICODE", [POINTER(TTF_Font), POINTER(Uint16), POINTER(c_int), POINTER(c_int)], c_int) TTF_RenderText_Solid = _bind("TTF_RenderText_Solid", [POINTER(TTF_Font), c_char_p, SDL_Color], POINTER(SDL_Surface)) TTF_RenderUTF8_Solid = _bind("TTF_RenderUTF8_Solid", [POINTER(TTF_Font), c_char_p, SDL_Color], POINTER(SDL_Surface)) TTF_RenderUNICODE_Solid = _bind("TTF_RenderUNICODE_Solid", [POINTER(TTF_Font), POINTER(Uint16), SDL_Color], POINTER(SDL_Surface)) TTF_RenderGlyph_Solid = _bind("TTF_RenderGlyph_Solid", [POINTER(TTF_Font), Uint16, SDL_Color], POINTER(SDL_Surface)) TTF_RenderText_Shaded = _bind("TTF_RenderText_Shaded", [POINTER(TTF_Font), c_char_p, SDL_Color, SDL_Color], POINTER(SDL_Surface)) TTF_RenderUTF8_Shaded = _bind("TTF_RenderUTF8_Shaded", [POINTER(TTF_Font), c_char_p, SDL_Color, SDL_Color], POINTER(SDL_Surface)) TTF_RenderUNICODE_Shaded = _bind("TTF_RenderUNICODE_Shaded", [POINTER(TTF_Font), POINTER(Uint16), SDL_Color, SDL_Color], POINTER(SDL_Surface)) TTF_RenderGlyph_Shaded = _bind("TTF_RenderGlyph_Shaded", [POINTER(TTF_Font), Uint16, SDL_Color, SDL_Color], POINTER(SDL_Surface)) TTF_RenderText_Blended = _bind("TTF_RenderText_Blended", [POINTER(TTF_Font), c_char_p, SDL_Color], POINTER(SDL_Surface)) TTF_RenderUTF8_Blended = _bind("TTF_RenderUTF8_Blended", [POINTER(TTF_Font), c_char_p, SDL_Color], POINTER(SDL_Surface)) TTF_RenderUNICODE_Blended = _bind("TTF_RenderUNICODE_Blended", [POINTER(TTF_Font), POINTER(Uint16), SDL_Color], POINTER(SDL_Surface)) TTF_RenderText_Blended_Wrapped = _bind("TTF_RenderText_Blended_Wrapped", [POINTER(TTF_Font), c_char_p, SDL_Color, Uint32], POINTER(SDL_Surface)) TTF_RenderUTF8_Blended_Wrapped = _bind("TTF_RenderUTF8_Blended_Wrapped", [POINTER(TTF_Font), c_char_p, SDL_Color, Uint32], POINTER(SDL_Surface)) TTF_RenderUNICODE_Blended_Wrapped = _bind("TTF_RenderUNICODE_Blended_Wrapped", [POINTER(TTF_Font), POINTER(Uint16), SDL_Color, Uint32], POINTER(SDL_Surface)) TTF_RenderGlyph_Blended = _bind("TTF_RenderGlyph_Blended", [POINTER(TTF_Font), Uint16, SDL_Color], POINTER(SDL_Surface)) TTF_RenderText = TTF_RenderText_Shaded TTF_RenderUTF = TTF_RenderUTF8_Shaded TTF_RenderUNICODE = TTF_RenderUNICODE_Shaded TTF_CloseFont = _bind("TTF_CloseFont", [POINTER(TTF_Font)]) TTF_Quit = _bind("TTF_Quit") TTF_WasInit = _bind("TTF_WasInit", None, c_int) TTF_GetFontKerningSize = _bind("TTF_GetFontKerningSize", [POINTER(TTF_Font), c_int, c_int], c_int) TTF_SetError = SDL_SetError TTF_GetError = SDL_GetError PySDL2-0.9.3/sdl2/shape.py0000644000000000000000000000341412260256443011752 0ustar from ctypes import Union, Structure, POINTER, c_char_p, c_uint, c_int from .dll import _bind from .stdinc import Uint8, Uint32, SDL_bool from .pixels import SDL_Color from .surface import SDL_Surface from .video import SDL_Window __all__ = ["SDL_NONSHAPEABLE_WINDOW", "SDL_INVALID_SHAPE_ARGUMENT", "SDL_WINDOW_LACKS_SHAPE", "SDL_CreateShapedWindow", "SDL_IsShapedWindow", "WindowShapeMode", "ShapeModeDefault", "ShapeModeBinarizeAlpha", "ShapeModeReverseBinarizeAlpha", "ShapeModeColorKey", "SDL_SHAPEMODEALPHA", "SDL_WindowShapeParams", "SDL_WindowShapeMode", "SDL_SetWindowShape", "SDL_GetShapedWindowMode" ] SDL_NONSHAPEABLE_WINDOW = -1 SDL_INVALID_SHAPE_ARGUMENT = -2 SDL_WINDOW_LACKS_SHAPE = -3 SDL_CreateShapedWindow = _bind("SDL_CreateShapedWindow", [c_char_p, c_uint, c_uint, c_uint, c_uint, Uint32], POINTER(SDL_Window)) SDL_IsShapedWindow = _bind("SDL_IsShapedWindow", [POINTER(SDL_Window)], SDL_bool) WindowShapeMode = c_int ShapeModeDefault = 0 ShapeModeBinarizeAlpha = 1 ShapeModeReverseBinarizeAlpha = 2 ShapeModeColorKey = 3 SDL_SHAPEMODEALPHA = lambda mode: (mode == ShapeModeDefault or mode == ShapeModeBinarizeAlpha or mode == ShapeModeReverseBinarizeAlpha) class SDL_WindowShapeParams(Union): _fields_ = [("binarizationCutoff", Uint8), ("colorKey", SDL_Color) ] class SDL_WindowShapeMode(Structure): _fields_ = [("mode", WindowShapeMode), ("parameters", SDL_WindowShapeParams) ] SDL_SetWindowShape = _bind("SDL_SetWindowShape", [POINTER(SDL_Window), POINTER(SDL_Surface), POINTER(SDL_WindowShapeMode)], c_int) SDL_GetShapedWindowMode = _bind("SDL_GetShapedWindowMode", [POINTER(SDL_Window), POINTER(SDL_WindowShapeMode)], c_int) PySDL2-0.9.3/sdl2/stdinc.py0000644000000000000000000000236512260256443012142 0ustar import sys from .dll import _bind from ctypes import c_int, c_int8, c_uint8, c_int16, c_uint16, c_int32, \ c_uint32, c_int64, c_uint64, cdll, c_size_t, c_void_p, c_char_p from ctypes.util import find_library __all__ = ["SDL_FALSE", "SDL_TRUE", "SDL_bool", "Sint8", "Uint8", "Sint16", "Uint16", "Sint32", "Uint32", "Sint64", "Uint64", "SDL_malloc", "SDL_calloc", "SDL_realloc", "SDL_free", "SDL_getenv", "SDL_setenv", "SDL_abs", "SDL_min", "SDL_max", "SDL_memset", "SDL_memcpy" ] SDL_FALSE = 0 SDL_TRUE = 1 SDL_bool = c_int Sint8 = c_int8 Uint8 = c_uint8 Sint16 = c_int16 Uint16 = c_uint16 Sint32 = c_int32 Uint32 = c_uint32 Sint64 = c_int64 Uint64 = c_uint64 SDL_malloc = _bind("SDL_malloc", [c_size_t], c_void_p) SDL_calloc = _bind("SDL_calloc", [c_size_t, c_size_t], c_void_p) SDL_realloc = _bind("SDL_realloc", [c_void_p, c_size_t], c_void_p) SDL_free = _bind("SDL_free", [c_void_p], None) SDL_getenv = _bind("SDL_getenv", [c_char_p], c_char_p) SDL_setenv = _bind("SDL_setenv", [c_char_p, c_char_p, c_int], c_int) SDL_abs = abs SDL_min = min SDL_max = max SDL_memset = _bind("SDL_memset", [c_void_p, c_int, c_size_t], c_void_p) SDL_memcpy = _bind("SDL_memcpy", [c_void_p, c_void_p, c_size_t], c_void_p) PySDL2-0.9.3/sdl2/surface.py0000644000000000000000000001255512327134762012313 0ustar from ctypes import CFUNCTYPE, Structure, POINTER, c_int, c_void_p from .dll import _bind from .stdinc import Uint8, Uint32, SDL_bool from .blendmode import SDL_BlendMode from .rect import SDL_Rect from .pixels import SDL_PixelFormat, SDL_Palette from .rwops import SDL_RWops, SDL_RWFromFile __all__ = ["SDL_SWSURFACE", "SDL_PREALLOC", "SDL_RLEACCEL", "SDL_DONTFREE", "SDL_MUSTLOCK", "SDL_BlitMap", "SDL_Surface", "SDL_Blit", "SDL_CreateRGBSurface", "SDL_CreateRGBSurfaceFrom", "SDL_FreeSurface", "SDL_SetSurfacePalette", "SDL_LockSurface", "SDL_UnlockSurface", "SDL_LoadBMP_RW", "SDL_LoadBMP", "SDL_SaveBMP_RW", "SDL_SaveBMP", "SDL_SetSurfaceRLE", "SDL_SetColorKey", "SDL_GetColorKey", "SDL_SetSurfaceColorMod", "SDL_GetSurfaceColorMod", "SDL_SetSurfaceAlphaMod", "SDL_GetSurfaceAlphaMod", "SDL_SetSurfaceBlendMode", "SDL_GetSurfaceBlendMode", "SDL_SetClipRect", "SDL_GetClipRect", "SDL_ConvertSurface", "SDL_ConvertSurfaceFormat", "SDL_ConvertPixels", "SDL_FillRect", "SDL_FillRects", "SDL_UpperBlit", "SDL_BlitSurface", "SDL_LowerBlit", "SDL_SoftStretch", "SDL_UpperBlitScaled", "SDL_BlitScaled", "SDL_LowerBlitScaled" ] SDL_SWSURFACE = 0 SDL_PREALLOC = 0x00000001 SDL_RLEACCEL = 0x00000002 SDL_DONTFREE = 0x00000004 SDL_MUSTLOCK = lambda s: ((s.flags & SDL_RLEACCEL) != 0) class SDL_BlitMap(Structure): pass class SDL_Surface(Structure): _fields_ = [("flags", Uint32), ("format", POINTER(SDL_PixelFormat)), ("w", c_int), ("h", c_int), ("pitch", c_int), ("pixels", c_void_p), ("userdata", c_void_p), ("locked", c_int), ("lock_data", c_void_p), ("clip_rect", SDL_Rect), ("map", POINTER(SDL_BlitMap)), ("refcount", c_int) ] SDL_Blit = CFUNCTYPE(c_int, POINTER(SDL_Surface), POINTER(SDL_Rect), POINTER(SDL_Surface), POINTER(SDL_Rect)) SDL_CreateRGBSurface = _bind("SDL_CreateRGBSurface", [Uint32, c_int, c_int, c_int, Uint32, Uint32, Uint32, Uint32], POINTER(SDL_Surface)) SDL_CreateRGBSurfaceFrom = _bind("SDL_CreateRGBSurfaceFrom", [c_void_p, c_int, c_int, c_int, c_int, Uint32, Uint32, Uint32, Uint32], POINTER(SDL_Surface)) SDL_FreeSurface = _bind("SDL_FreeSurface", [POINTER(SDL_Surface)]) SDL_SetSurfacePalette = _bind("SDL_SetSurfacePalette", [POINTER(SDL_Surface), POINTER(SDL_Palette)], c_int) SDL_LockSurface = _bind("SDL_LockSurface", [POINTER(SDL_Surface)], c_int) SDL_UnlockSurface = _bind("SDL_UnlockSurface", [POINTER(SDL_Surface)]) SDL_LoadBMP_RW = _bind("SDL_LoadBMP_RW", [POINTER(SDL_RWops), c_int], POINTER(SDL_Surface)) SDL_LoadBMP = lambda fname: SDL_LoadBMP_RW(SDL_RWFromFile(fname, b"rb"), 1) SDL_SaveBMP_RW = _bind("SDL_SaveBMP_RW", [POINTER(SDL_Surface), POINTER(SDL_RWops), c_int], c_int) SDL_SaveBMP = lambda surface, fname: SDL_SaveBMP_RW(surface, SDL_RWFromFile(fname, b"wb"), 1) SDL_SetSurfaceRLE = _bind("SDL_SetSurfaceRLE", [POINTER(SDL_Surface), c_int], c_int) SDL_SetColorKey = _bind("SDL_SetColorKey", [POINTER(SDL_Surface), c_int, Uint32], c_int) SDL_GetColorKey = _bind("SDL_GetColorKey", [POINTER(SDL_Surface), POINTER(Uint32)], c_int) SDL_SetSurfaceColorMod = _bind("SDL_SetSurfaceColorMod", [POINTER(SDL_Surface), Uint8, Uint8, Uint8], c_int) SDL_GetSurfaceColorMod = _bind("SDL_GetSurfaceColorMod", [POINTER(SDL_Surface), POINTER(Uint8), POINTER(Uint8), POINTER(Uint8)], c_int) SDL_SetSurfaceAlphaMod = _bind("SDL_SetSurfaceAlphaMod", [POINTER(SDL_Surface), Uint8], c_int) SDL_GetSurfaceAlphaMod = _bind("SDL_GetSurfaceAlphaMod", [POINTER(SDL_Surface), POINTER(Uint8)], c_int) SDL_SetSurfaceBlendMode = _bind("SDL_SetSurfaceBlendMode", [POINTER(SDL_Surface), SDL_BlendMode], c_int) SDL_GetSurfaceBlendMode = _bind("SDL_GetSurfaceBlendMode", [POINTER(SDL_Surface), POINTER(SDL_BlendMode)], c_int) SDL_SetClipRect = _bind("SDL_SetClipRect", [POINTER(SDL_Surface), POINTER(SDL_Rect)], SDL_bool) SDL_GetClipRect = _bind("SDL_GetClipRect", [POINTER(SDL_Surface), POINTER(SDL_Rect)]) SDL_ConvertSurface = _bind("SDL_ConvertSurface", [POINTER(SDL_Surface), POINTER(SDL_PixelFormat), Uint32], POINTER(SDL_Surface)) SDL_ConvertSurfaceFormat = _bind("SDL_ConvertSurfaceFormat", [POINTER(SDL_Surface), Uint32, Uint32], POINTER(SDL_Surface)) SDL_ConvertPixels = _bind("SDL_ConvertPixels", [c_int, c_int, Uint32, c_void_p, c_int, Uint32, c_void_p, c_int], c_int) SDL_FillRect = _bind("SDL_FillRect", [POINTER(SDL_Surface), POINTER(SDL_Rect), Uint32], c_int) SDL_FillRects = _bind("SDL_FillRects", [POINTER(SDL_Surface), POINTER(SDL_Rect), c_int, Uint32], c_int) SDL_UpperBlit = _bind("SDL_UpperBlit", [POINTER(SDL_Surface), POINTER(SDL_Rect), POINTER(SDL_Surface), POINTER(SDL_Rect)], c_int) SDL_BlitSurface = SDL_UpperBlit SDL_LowerBlit = _bind("SDL_LowerBlit", [POINTER(SDL_Surface), POINTER(SDL_Rect), POINTER(SDL_Surface), POINTER(SDL_Rect)], c_int) SDL_SoftStretch = _bind("SDL_SoftStretch", [POINTER(SDL_Surface), POINTER(SDL_Rect), POINTER(SDL_Surface), POINTER(SDL_Rect)], c_int) SDL_UpperBlitScaled = _bind("SDL_UpperBlitScaled", [POINTER(SDL_Surface), POINTER(SDL_Rect), POINTER(SDL_Surface), POINTER(SDL_Rect)], c_int) SDL_BlitScaled = SDL_UpperBlitScaled SDL_LowerBlitScaled = _bind("SDL_LowerBlitScaled", [POINTER(SDL_Surface), POINTER(SDL_Rect), POINTER(SDL_Surface), POINTER(SDL_Rect)], c_int) PySDL2-0.9.3/sdl2/syswm.py0000644000000000000000000000742612345025602012036 0ustar from ctypes import Union, Structure, c_int, c_void_p, c_long, c_ulong, \ c_longlong, c_ulonglong, c_uint, sizeof, POINTER from .dll import _bind from .stdinc import SDL_bool from .version import SDL_version from .video import SDL_Window __all__ = ["SDL_SYSWM_TYPE", "SDL_SYSWM_UNKNOWN", "SDL_SYSWM_WINDOWS", "SDL_SYSWM_X11", "SDL_SYSWM_DIRECTFB", "SDL_SYSWM_COCOA", "SDL_SYSWM_UIKIT", "SDL_SYSWM_WAYLAND", "SDL_SYSWM_MIR", "SDL_SYSWM_WINRT", "SDL_SYSWM_ANDROID", "SDL_SysWMmsg", "SDL_SysWMinfo", "SDL_GetWindowWMInfo" ] SDL_SYSWM_TYPE = c_int SDL_SYSWM_UNKNOWN = 0 SDL_SYSWM_WINDOWS = 1 SDL_SYSWM_X11 = 2 SDL_SYSWM_DIRECTFB = 3 SDL_SYSWM_COCOA = 4 SDL_SYSWM_UIKIT = 5 SDL_SYSWM_WAYLAND = 6 SDL_SYSWM_MIR = 7 SDL_SYSWM_WINRT = 8 SDL_SYSWM_ANDROID = 9 # FIXME: Hack around the ctypes "_type_ 'v' not supported" bug - remove # once this has been fixed properly in Python 2.7+ HWND = c_void_p UINT = c_uint if sizeof(c_long) == sizeof(c_void_p): WPARAM = c_ulong LPARAM = c_long elif sizeof(c_longlong) == sizeof(c_void_p): WPARAM = c_ulonglong LPARAM = c_longlong # FIXME: end class _winmsg(Structure): _fields_ = [("hwnd", HWND), ("msg", UINT), ("wParam", WPARAM), ("lParam", LPARAM), ] class _x11msg(Structure): _fields_ = [("event", c_void_p)] class _dfbmsg(Structure): _fields_ = [("event", c_void_p)] class _cocoamsg(Structure): pass class _uikitmsg(Structure): pass class _msg(Union): _fields_ = [("win", _winmsg), ("x11", _x11msg), ("dfb", _dfbmsg), ("cocoa", _cocoamsg), ("uikit", _uikitmsg), ("dummy", c_int) ] class SDL_SysWMmsg(Structure): _fields_ = [("version", SDL_version), ("subsystem", SDL_SYSWM_TYPE), ("msg", _msg) ] class _wininfo(Structure): _fields_ = [("window", HWND)] class _x11info(Structure): """Window information for X11.""" _fields_ = [("display", c_void_p), ("window", c_ulong)] class _dfbinfo(Structure): """Window information for DirectFB.""" _fields_ = [("dfb", c_void_p), ("window", c_void_p), ("surface", c_void_p)] class _cocoainfo(Structure): """Window information for MacOS X.""" _fields_ = [("window", c_void_p)] class _uikitinfo(Structure): """Window information for iOS.""" _fields_ = [("window", c_void_p)] class _wl(Structure): """Window information for Wayland.""" _fields_ = [("display", c_void_p), ("surface", c_void_p), ("shell_surface", c_void_p)] class _mir(Structure): """Window information for Mir.""" _fields_ = [("connection", c_void_p), ("surface", c_void_p)] class _android(Structure): """Window information for Android.""" _fields_ = [("window", c_void_p), ("surface", c_void_p)] class _info(Union): """The platform-specific information of a window.""" _fields_ = [("win", _wininfo), ("x11", _x11info), ("dfb", _dfbinfo), ("cocoa", _cocoainfo), ("uikit", _uikitinfo), ("wl", _wl), ("mir", _mir), ("android", _android), ("dummy", c_int) ] class SDL_SysWMinfo(Structure): """System-specific window manager information. This holds the low-level information about the window. """ _fields_ = [("version", SDL_version), ("subsystem", SDL_SYSWM_TYPE), ("info", _info) ] SDL_GetWindowWMInfo = _bind("SDL_GetWindowWMInfo", [POINTER(SDL_Window), POINTER(SDL_SysWMinfo)], SDL_bool) PySDL2-0.9.3/sdl2/timer.py0000644000000000000000000000153412260256443011773 0ustar from ctypes import CFUNCTYPE, c_void_p, c_int from .dll import _bind from .stdinc import Uint32, Uint64, SDL_bool __all__ = ["SDL_GetTicks", "SDL_GetPerformanceCounter", "SDL_GetPerformanceFrequency", "SDL_Delay", "SDL_TimerCallback", "SDL_TimerID", "SDL_AddTimer", "SDL_RemoveTimer" ] SDL_GetTicks = _bind("SDL_GetTicks", None, Uint32) SDL_GetPerformanceCounter = _bind("SDL_GetPerformanceCounter", None, Uint64) SDL_GetPerformanceFrequency = _bind("SDL_GetPerformanceFrequency", None, Uint64) SDL_Delay = _bind("SDL_Delay", [Uint32]) SDL_TimerCallback = CFUNCTYPE(Uint32, Uint32, c_void_p) SDL_TimerID = c_int SDL_AddTimer = _bind("SDL_AddTimer", [Uint32, SDL_TimerCallback, c_void_p], SDL_TimerID) SDL_RemoveTimer = _bind("SDL_RemoveTimer", [SDL_TimerID], SDL_bool) def SDL_TICKS_PASSED(A, B): return (B - A) <= 0 PySDL2-0.9.3/sdl2/touch.py0000644000000000000000000000155112260256443011774 0ustar from ctypes import Structure, POINTER, c_float, c_int from .dll import _bind from .stdinc import Sint64 __all__ = ["SDL_TouchID", "SDL_FingerID", "SDL_Finger", "SDL_GetNumTouchDevices", "SDL_GetTouchDevice", "SDL_GetNumTouchFingers", "SDL_GetTouchFinger" ] SDL_TouchID = Sint64 SDL_FingerID = Sint64 class SDL_Finger(Structure): _fields_ = [("id", SDL_FingerID), ("x", c_float), ("y", c_float), ("pressure", c_float) ] # TODO: #define SDL_TOUCH_MOUSEID ((Uint32)-1) SDL_GetNumTouchDevices = _bind("SDL_GetNumTouchDevices", None, c_int) SDL_GetTouchDevice = _bind("SDL_GetTouchDevice", [c_int], SDL_TouchID) SDL_GetNumTouchFingers = _bind("SDL_GetNumTouchFingers", [SDL_TouchID], c_int) SDL_GetTouchFinger = _bind("SDL_GetTouchFinger", [SDL_TouchID, c_int], POINTER(SDL_Finger)) PySDL2-0.9.3/sdl2/version.py0000644000000000000000000000215712313517063012337 0ustar from ctypes import Structure, POINTER, c_char_p, c_int from .dll import _bind from .stdinc import Uint8 __all__ = ["SDL_version", "SDL_MAJOR_VERSION", "SDL_MINOR_VERSION", "SDL_PATCHLEVEL", "SDL_VERSION", "SDL_VERSIONNUM", "SDL_COMPILEDVERSION", "SDL_VERSION_ATLEAST", "SDL_GetVersion", "SDL_GetRevision", "SDL_GetRevisionNumber" ] class SDL_version(Structure): _fields_ = [("major", Uint8), ("minor", Uint8), ("patch", Uint8), ] SDL_MAJOR_VERSION = 2 SDL_MINOR_VERSION = 0 SDL_PATCHLEVEL = 3 def SDL_VERSION(x): x.major = SDL_MAJOR_VERSION x.minor = SDL_MINOR_VERSION x.patch = SDL_PATCHLEVEL SDL_VERSIONNUM = lambda x, y, z: (x * 1000 + y * 100 + z) SDL_COMPILEDVERSION = SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) SDL_VERSION_ATLEAST = lambda x, y, z: (SDL_COMPILEDVERSION >= SDL_VERSIONNUM(x, y, z)) SDL_GetVersion = _bind("SDL_GetVersion", [POINTER(SDL_version)]) SDL_GetRevision = _bind("SDL_GetRevision", None, c_char_p) SDL_GetRevisionNumber = _bind("SDL_GetRevisionNumber", None, c_int) PySDL2-0.9.3/sdl2/video.py0000644000000000000000000003607512356441756012002 0ustar from ctypes import Structure, POINTER, c_int, c_void_p, c_char_p, c_float, \ py_object, CFUNCTYPE from .dll import _bind, nullfunc from .stdinc import Uint16, Uint32, SDL_bool from .rect import SDL_Point, SDL_Rect from .surface import SDL_Surface __all__ = ["SDL_DisplayMode", "SDL_Window", "SDL_WindowFlags", "SDL_WINDOW_FULLSCREEN", "SDL_WINDOW_OPENGL", "SDL_WINDOW_SHOWN", "SDL_WINDOW_HIDDEN", "SDL_WINDOW_BORDERLESS", "SDL_WINDOW_RESIZABLE", "SDL_WINDOW_MINIMIZED", "SDL_WINDOW_MAXIMIZED", "SDL_WINDOW_INPUT_GRABBED", "SDL_WINDOW_INPUT_FOCUS", "SDL_WINDOW_MOUSE_FOCUS", "SDL_WINDOW_FULLSCREEN_DESKTOP", "SDL_WINDOW_FOREIGN", "SDL_WINDOW_ALLOW_HIGHDPI", "SDL_WINDOW_MOUSE_CAPTURE", "SDL_WINDOWPOS_UNDEFINED_MASK", "SDL_WINDOWPOS_UNDEFINED_DISPLAY", "SDL_WINDOWPOS_UNDEFINED", "SDL_WINDOWPOS_ISUNDEFINED", "SDL_WINDOWPOS_CENTERED_MASK", "SDL_WINDOWPOS_CENTERED_DISPLAY", "SDL_WINDOWPOS_CENTERED", "SDL_WINDOWPOS_ISCENTERED", "SDL_WindowEventID", "SDL_WINDOWEVENT_NONE", "SDL_WINDOWEVENT_SHOWN", "SDL_WINDOWEVENT_HIDDEN", "SDL_WINDOWEVENT_EXPOSED", "SDL_WINDOWEVENT_MOVED", "SDL_WINDOWEVENT_RESIZED", "SDL_WINDOWEVENT_SIZE_CHANGED", "SDL_WINDOWEVENT_MINIMIZED", "SDL_WINDOWEVENT_MAXIMIZED", "SDL_WINDOWEVENT_RESTORED", "SDL_WINDOWEVENT_ENTER", "SDL_WINDOWEVENT_LEAVE", "SDL_WINDOWEVENT_FOCUS_GAINED", "SDL_WINDOWEVENT_FOCUS_LOST", "SDL_WINDOWEVENT_CLOSE", "SDL_GLContext", "SDL_GLattr", "SDL_GL_RED_SIZE", "SDL_GL_GREEN_SIZE", "SDL_GL_BLUE_SIZE", "SDL_GL_ALPHA_SIZE", "SDL_GL_BUFFER_SIZE", "SDL_GL_DOUBLEBUFFER", "SDL_GL_DEPTH_SIZE", "SDL_GL_STENCIL_SIZE", "SDL_GL_ACCUM_RED_SIZE", "SDL_GL_ACCUM_GREEN_SIZE", "SDL_GL_ACCUM_BLUE_SIZE", "SDL_GL_ACCUM_ALPHA_SIZE", "SDL_GL_STEREO", "SDL_GL_MULTISAMPLEBUFFERS", "SDL_GL_MULTISAMPLESAMPLES", "SDL_GL_ACCELERATED_VISUAL", "SDL_GL_RETAINED_BACKING", "SDL_GL_CONTEXT_MAJOR_VERSION", "SDL_GL_CONTEXT_MINOR_VERSION", "SDL_GL_CONTEXT_EGL", "SDL_GL_CONTEXT_FLAGS", "SDL_GL_CONTEXT_PROFILE_MASK", "SDL_GL_SHARE_WITH_CURRENT_CONTEXT", "SDL_GL_FRAMEBUFFER_SRGB_CAPABLE", "SDL_GLprofile", "SDL_GL_CONTEXT_PROFILE_CORE", "SDL_GL_CONTEXT_PROFILE_COMPATIBILITY", "SDL_GL_CONTEXT_PROFILE_ES", "SDL_GLcontextFlag", "SDL_GL_CONTEXT_DEBUG_FLAG", "SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG", "SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG", "SDL_GL_CONTEXT_RESET_ISOLATION_FLAG", "SDL_GetNumVideoDrivers", "SDL_GetVideoDriver", "SDL_VideoInit", "SDL_VideoQuit", "SDL_GetCurrentVideoDriver", "SDL_GetNumVideoDisplays", "SDL_GetDisplayName", "SDL_GetDisplayBounds", "SDL_GetNumDisplayModes", "SDL_GetDisplayMode", "SDL_GetDesktopDisplayMode", "SDL_GetCurrentDisplayMode", "SDL_GetClosestDisplayMode", "SDL_GetWindowDisplayIndex", "SDL_SetWindowDisplayMode", "SDL_GetWindowDisplayMode", "SDL_GetWindowPixelFormat", "SDL_CreateWindow", "SDL_CreateWindowFrom", "SDL_GetWindowID", "SDL_GetWindowFromID", "SDL_GetWindowFlags", "SDL_SetWindowTitle", "SDL_GetWindowTitle", "SDL_SetWindowIcon", "SDL_SetWindowData", "SDL_GetWindowData", "SDL_SetWindowPosition", "SDL_GetWindowPosition", "SDL_SetWindowSize", "SDL_GetWindowSize", "SDL_SetWindowMinimumSize", "SDL_GetWindowMinimumSize", "SDL_SetWindowMaximumSize", "SDL_GetWindowMaximumSize", "SDL_SetWindowBordered", "SDL_ShowWindow", "SDL_HideWindow", "SDL_RaiseWindow", "SDL_MaximizeWindow", "SDL_MinimizeWindow", "SDL_RestoreWindow", "SDL_SetWindowFullscreen", "SDL_GetWindowSurface", "SDL_UpdateWindowSurface", "SDL_UpdateWindowSurfaceRects", "SDL_SetWindowGrab", "SDL_GetWindowGrab", "SDL_SetWindowBrightness", "SDL_GetWindowBrightness", "SDL_SetWindowGammaRamp", "SDL_GetWindowGammaRamp", "SDL_DestroyWindow", "SDL_DisableScreenSaver", "SDL_IsScreenSaverEnabled", "SDL_EnableScreenSaver", "SDL_HITTEST_NORMAL", "SDL_HITTEST_DRAGGABLE", "SDL_HITTEST_RESIZE_TOPLEFT", "SDL_HITTEST_RESIZE_TOP", "SDL_HITTEST_RESIZE_TOPRIGHT", "SDL_HITTEST_RESIZE_RIGHT", "SDL_HITTEST_RESIZE_BOTTOMRIGHT", "SDL_HITTEST_RESIZE_BOTTOM", "SDL_HITTEST_RESIZE_BOTTOMLEFT", "SDL_HITTEST_RESIZE_LEFT", "SDL_HitTestResult", "SDL_HitTest", "SDL_SetWindowHitTest", "SDL_GL_LoadLibrary", "SDL_GL_GetProcAddress", "SDL_GL_UnloadLibrary", "SDL_GL_ExtensionSupported", "SDL_GL_SetAttribute", "SDL_GL_GetAttribute", "SDL_GL_CreateContext", "SDL_GL_MakeCurrent", "SDL_GL_SetSwapInterval", "SDL_GL_GetSwapInterval", "SDL_GL_SwapWindow", "SDL_GL_DeleteContext", "SDL_GL_ResetAttributes" ] class SDL_DisplayMode(Structure): _fields_ = [("format", Uint32), ("w", c_int), ("h", c_int), ("refresh_rate", c_int), ("driverdata", c_void_p) ] def __init__(self, format_=0, w=0, h=0, refresh_rate=0): super(SDL_DisplayMode, self).__init__() self.format = format_ self.w = w self.h = h self.refresh_rate = refresh_rate def __repr__(self): return "SDL_DisplayMode(format=%d, w=%d, h=%d, refresh_rate=%d)" % \ (self.format, self.w, self.h, self.refresh_rate) def __eq__(self, mode): return self.format == mode.format and self.w == mode.w and \ self.h == mode.h and self.refresh_rate == mode.refresh_rate def __ne__(self, mode): return self.format != mode.format or self.w != mode.w or \ self.h != mode.h or self.refresh_rate != mode.refresh_rate class SDL_Window(Structure): pass SDL_WindowFlags = c_int SDL_WINDOW_FULLSCREEN = 0x00000001 SDL_WINDOW_OPENGL = 0x00000002 SDL_WINDOW_SHOWN = 0x00000004 SDL_WINDOW_HIDDEN = 0x00000008 SDL_WINDOW_BORDERLESS = 0x00000010 SDL_WINDOW_RESIZABLE = 0x00000020 SDL_WINDOW_MINIMIZED = 0x00000040 SDL_WINDOW_MAXIMIZED = 0x00000080 SDL_WINDOW_INPUT_GRABBED = 0x00000100 SDL_WINDOW_INPUT_FOCUS = 0x00000200 SDL_WINDOW_MOUSE_FOCUS = 0x00000400 SDL_WINDOW_FULLSCREEN_DESKTOP = (SDL_WINDOW_FULLSCREEN | 0x00001000) SDL_WINDOW_FOREIGN = 0x00000800 SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000 SDL_WINDOW_MOUSE_CAPTURE = 0x00004000 SDL_WINDOWPOS_UNDEFINED_MASK = 0x1FFF0000 SDL_WINDOWPOS_UNDEFINED_DISPLAY = lambda x: (SDL_WINDOWPOS_UNDEFINED_MASK | x) SDL_WINDOWPOS_UNDEFINED = SDL_WINDOWPOS_UNDEFINED_DISPLAY(0) SDL_WINDOWPOS_ISUNDEFINED = lambda x: ((x & 0xFFFF0000) == SDL_WINDOWPOS_UNDEFINED_MASK) SDL_WINDOWPOS_CENTERED_MASK = 0x2FFF0000 SDL_WINDOWPOS_CENTERED_DISPLAY = lambda x: (SDL_WINDOWPOS_CENTERED_MASK | x) SDL_WINDOWPOS_CENTERED = SDL_WINDOWPOS_CENTERED_DISPLAY(0) SDL_WINDOWPOS_ISCENTERED = lambda x: ((x & 0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK) SDL_WindowEventID = c_int SDL_WINDOWEVENT_NONE = 0 SDL_WINDOWEVENT_SHOWN = 1 SDL_WINDOWEVENT_HIDDEN = 2 SDL_WINDOWEVENT_EXPOSED = 3 SDL_WINDOWEVENT_MOVED = 4 SDL_WINDOWEVENT_RESIZED = 5 SDL_WINDOWEVENT_SIZE_CHANGED = 6 SDL_WINDOWEVENT_MINIMIZED = 7 SDL_WINDOWEVENT_MAXIMIZED = 8 SDL_WINDOWEVENT_RESTORED = 9 SDL_WINDOWEVENT_ENTER = 10 SDL_WINDOWEVENT_LEAVE = 11 SDL_WINDOWEVENT_FOCUS_GAINED = 12 SDL_WINDOWEVENT_FOCUS_LOST = 13 SDL_WINDOWEVENT_CLOSE = 14 SDL_GLContext = c_void_p SDL_GLattr = c_int SDL_GL_RED_SIZE = 0 SDL_GL_GREEN_SIZE = 1 SDL_GL_BLUE_SIZE = 2 SDL_GL_ALPHA_SIZE = 3 SDL_GL_BUFFER_SIZE = 4 SDL_GL_DOUBLEBUFFER = 5 SDL_GL_DEPTH_SIZE = 6 SDL_GL_STENCIL_SIZE = 7 SDL_GL_ACCUM_RED_SIZE = 8 SDL_GL_ACCUM_GREEN_SIZE = 9 SDL_GL_ACCUM_BLUE_SIZE = 10 SDL_GL_ACCUM_ALPHA_SIZE = 11 SDL_GL_STEREO = 12 SDL_GL_MULTISAMPLEBUFFERS = 13 SDL_GL_MULTISAMPLESAMPLES = 14 SDL_GL_ACCELERATED_VISUAL = 15 SDL_GL_RETAINED_BACKING = 16 SDL_GL_CONTEXT_MAJOR_VERSION = 17 SDL_GL_CONTEXT_MINOR_VERSION = 18 SDL_GL_CONTEXT_EGL = 19 SDL_GL_CONTEXT_FLAGS = 20 SDL_GL_CONTEXT_PROFILE_MASK = 21 SDL_GL_SHARE_WITH_CURRENT_CONTEXT = 22 SDL_GL_FRAMEBUFFER_SRGB_CAPABLE = 23 SDL_GLprofile = c_int SDL_GL_CONTEXT_PROFILE_CORE = 0x0001 SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002 SDL_GL_CONTEXT_PROFILE_ES = 0x0004 SDL_GLcontextFlag = c_int SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001 SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002 SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004 SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008 SDL_HitTestResult = c_int SDL_HITTEST_NORMAL = 0 SDL_HITTEST_DRAGGABLE = 1 SDL_HITTEST_RESIZE_TOPLEFT = 2 SDL_HITTEST_RESIZE_TOP = 3 SDL_HITTEST_RESIZE_TOPRIGHT = 4 SDL_HITTEST_RESIZE_RIGHT = 5 SDL_HITTEST_RESIZE_BOTTOMRIGHT = 6 SDL_HITTEST_RESIZE_BOTTOM = 7 SDL_HITTEST_RESIZE_BOTTOMLEFT = 8 SDL_HITTEST_RESIZE_LEFT = 9 SDL_HitTest = CFUNCTYPE(SDL_HitTestResult, POINTER(SDL_Window), POINTER(SDL_Point), c_void_p) SDL_GetNumVideoDrivers = _bind("SDL_GetNumVideoDrivers", None, c_int) SDL_GetVideoDriver = _bind("SDL_GetVideoDriver", [c_int], c_char_p) SDL_VideoInit = _bind("SDL_VideoInit", [c_char_p], c_int) SDL_VideoQuit = _bind("SDL_VideoQuit") SDL_GetCurrentVideoDriver = _bind("SDL_GetCurrentVideoDriver", None, c_char_p) SDL_GetNumVideoDisplays = _bind("SDL_GetNumVideoDisplays", None, c_int) SDL_GetDisplayName = _bind("SDL_GetDisplayName", [c_int], c_char_p) SDL_GetDisplayBounds = _bind("SDL_GetDisplayBounds", [c_int, POINTER(SDL_Rect)], c_int) SDL_GetNumDisplayModes = _bind("SDL_GetNumDisplayModes", [c_int], c_int) SDL_GetDisplayMode = _bind("SDL_GetDisplayMode", [c_int, c_int, POINTER(SDL_DisplayMode)], c_int) SDL_GetDesktopDisplayMode = _bind("SDL_GetDesktopDisplayMode", [c_int, POINTER(SDL_DisplayMode)], c_int) SDL_GetCurrentDisplayMode = _bind("SDL_GetCurrentDisplayMode", [c_int, POINTER(SDL_DisplayMode)], c_int) SDL_GetClosestDisplayMode = _bind("SDL_GetClosestDisplayMode", [c_int, POINTER(SDL_DisplayMode), POINTER(SDL_DisplayMode)], POINTER(SDL_DisplayMode)) SDL_GetWindowDisplayIndex = _bind("SDL_GetWindowDisplayIndex", [POINTER(SDL_Window)], c_int) SDL_SetWindowDisplayMode = _bind("SDL_SetWindowDisplayMode", [POINTER(SDL_Window), POINTER(SDL_DisplayMode)], c_int) SDL_GetWindowDisplayMode = _bind("SDL_GetWindowDisplayMode", [POINTER(SDL_Window), POINTER(SDL_DisplayMode)], c_int) SDL_GetWindowPixelFormat = _bind("SDL_GetWindowPixelFormat", [POINTER(SDL_Window)], Uint32) SDL_CreateWindow = _bind("SDL_CreateWindow", [c_char_p, c_int, c_int, c_int, c_int, Uint32], POINTER(SDL_Window)) SDL_CreateWindowFrom = _bind("SDL_CreateWindowFrom", [c_void_p], POINTER(SDL_Window)) SDL_GetWindowID = _bind("SDL_GetWindowID", [POINTER(SDL_Window)], Uint32) SDL_GetWindowFromID = _bind("SDL_GetWindowFromID", [Uint32], POINTER(SDL_Window)) SDL_GetWindowFlags = _bind("SDL_GetWindowFlags", [POINTER(SDL_Window)], Uint32) SDL_SetWindowTitle = _bind("SDL_SetWindowTitle", [POINTER(SDL_Window), c_char_p]) SDL_GetWindowTitle = _bind("SDL_GetWindowTitle", [POINTER(SDL_Window)], c_char_p) SDL_SetWindowIcon = _bind("SDL_SetWindowIcon", [POINTER(SDL_Window), POINTER(SDL_Surface)]) SDL_SetWindowData = _bind("SDL_SetWindowData", [POINTER(SDL_Window), c_char_p, POINTER(py_object)], POINTER(py_object)) SDL_GetWindowData = _bind("SDL_GetWindowData", [POINTER(SDL_Window), c_char_p], POINTER(py_object)) SDL_SetWindowPosition = _bind("SDL_SetWindowPosition", [POINTER(SDL_Window), c_int, c_int]) SDL_GetWindowPosition = _bind("SDL_GetWindowPosition", [POINTER(SDL_Window), POINTER(c_int), POINTER(c_int)]) SDL_SetWindowSize = _bind("SDL_SetWindowSize", [POINTER(SDL_Window), c_int, c_int]) SDL_GetWindowSize = _bind("SDL_GetWindowSize", [POINTER(SDL_Window), POINTER(c_int), POINTER(c_int)]) SDL_SetWindowMinimumSize = _bind("SDL_SetWindowMinimumSize", [POINTER(SDL_Window), c_int, c_int]) SDL_GetWindowMinimumSize = _bind("SDL_GetWindowMinimumSize", [POINTER(SDL_Window), POINTER(c_int), POINTER(c_int)]) SDL_SetWindowMaximumSize = _bind("SDL_SetWindowMaximumSize", [POINTER(SDL_Window), c_int, c_int]) SDL_GetWindowMaximumSize = _bind("SDL_GetWindowMaximumSize", [POINTER(SDL_Window), POINTER(c_int), POINTER(c_int)]) SDL_SetWindowBordered = _bind("SDL_SetWindowBordered", [POINTER(SDL_Window), SDL_bool]) SDL_ShowWindow = _bind("SDL_ShowWindow", [POINTER(SDL_Window)]) SDL_HideWindow = _bind("SDL_HideWindow", [POINTER(SDL_Window)]) SDL_RaiseWindow = _bind("SDL_RaiseWindow", [POINTER(SDL_Window)]) SDL_MaximizeWindow = _bind("SDL_MaximizeWindow", [POINTER(SDL_Window)]) SDL_MinimizeWindow = _bind("SDL_MinimizeWindow", [POINTER(SDL_Window)]) SDL_RestoreWindow = _bind("SDL_RestoreWindow", [POINTER(SDL_Window)]) SDL_SetWindowFullscreen = _bind("SDL_SetWindowFullscreen", [POINTER(SDL_Window), Uint32], c_int) SDL_GetWindowSurface = _bind("SDL_GetWindowSurface", [POINTER(SDL_Window)], POINTER(SDL_Surface)) SDL_UpdateWindowSurface = _bind("SDL_UpdateWindowSurface", [POINTER(SDL_Window)], c_int) SDL_UpdateWindowSurfaceRects = _bind("SDL_UpdateWindowSurfaceRects", [POINTER(SDL_Window), POINTER(SDL_Rect), c_int], c_int) SDL_SetWindowGrab = _bind("SDL_SetWindowGrab", [POINTER(SDL_Window), SDL_bool]) SDL_GetWindowGrab = _bind("SDL_GetWindowGrab", [POINTER(SDL_Window)], SDL_bool) SDL_SetWindowBrightness = _bind("SDL_SetWindowBrightness", [POINTER(SDL_Window), c_float], c_int) SDL_GetWindowBrightness = _bind("SDL_GetWindowBrightness", [POINTER(SDL_Window)], c_float) SDL_SetWindowGammaRamp = _bind("SDL_SetWindowGammaRamp", [POINTER(SDL_Window), POINTER(Uint16), POINTER(Uint16), POINTER(Uint16)], c_int) SDL_GetWindowGammaRamp = _bind("SDL_GetWindowGammaRamp", [POINTER(SDL_Window), POINTER(Uint16), POINTER(Uint16), POINTER(Uint16)], c_int) SDL_DestroyWindow = _bind("SDL_DestroyWindow", [POINTER(SDL_Window)]) SDL_IsScreenSaverEnabled = _bind("SDL_IsScreenSaverEnabled", None, SDL_bool) SDL_EnableScreenSaver = _bind("SDL_EnableScreenSaver") SDL_DisableScreenSaver = _bind("SDL_DisableScreenSaver") SDL_SetWindowHitTest = _bind("SDL_SetWindowHitTest", [POINTER(SDL_Window), SDL_HitTest, c_void_p], c_int, optfunc=nullfunc) SDL_GL_LoadLibrary = _bind("SDL_GL_LoadLibrary", [c_char_p], c_int) SDL_GL_GetProcAddress = _bind("SDL_GL_GetProcAddress", [c_char_p], c_void_p) SDL_GL_UnloadLibrary = _bind("SDL_GL_UnloadLibrary") SDL_GL_ExtensionSupported = _bind("SDL_GL_ExtensionSupported", [c_char_p], SDL_bool) SDL_GL_SetAttribute = _bind("SDL_GL_SetAttribute", [SDL_GLattr, c_int], c_int) SDL_GL_GetAttribute = _bind("SDL_GL_GetAttribute", [SDL_GLattr, POINTER(c_int)], c_int) SDL_GL_CreateContext = _bind("SDL_GL_CreateContext", [POINTER(SDL_Window)], SDL_GLContext) SDL_GL_MakeCurrent = _bind("SDL_GL_MakeCurrent", [POINTER(SDL_Window), SDL_GLContext], c_int) SDL_GL_SetSwapInterval = _bind("SDL_GL_SetSwapInterval", [c_int], c_int) SDL_GL_GetSwapInterval = _bind("SDL_GL_GetSwapInterval", None, c_int) SDL_GL_SwapWindow = _bind("SDL_GL_SwapWindow", [POINTER(SDL_Window)]) SDL_GL_DeleteContext = _bind("SDL_GL_DeleteContext", [SDL_GLContext]) SDL_GL_GetDrawableSize = _bind("SDL_GL_GetDrawableSize", [POINTER(SDL_Window), POINTER(c_int), POINTER(c_int)], optfunc=nullfunc) SDL_GL_ResetAttributes = _bind("SDL_GL_ResetAttributes", optfunc=nullfunc) PySDL2-0.9.3/util/0000755000000000000000000000000012357043742010412 5ustar PySDL2-0.9.3/util/valgrind.sh0000755000000000000000000000153712260256443012562 0ustar #!/bin/sh # Path to the debug version of python : ${PYDEBUG:="/opt/python-debug/bin/python"} # Valgrind checker application and the default arguments to use. : ${VALGRIND:="valgrind"} : ${VALGRINDARGS:="--tool=memcheck --leak-check=summary"} : ${PYTHONPATH:="`dirname $0`/../"} usage() { echo "usage: `basename $0` [-f|-r|-s] module ..." } while getopts frs arg; do case $arg in f) DEFARGS="--tool=memcheck --leak-check=full" ;; r) DEFARGS="--tool=memcheck --leak-check=full --show-reachable=yes" ;; s) DEFARGS="--tool=memcheck --leak-check=summary" ;; \? | h) usage exit 2 esac done shift $(expr $OPTIND - 1) if [ $# -eq 0 ]; then usage exit 1 fi for f in $@; do $VALGRIND $DEFARGS $PYDEBUG -B -m $f done PySDL2-0.9.3/AUTHORS.txt0000644000000000000000000000077512354723733011336 0ustar This software packages was created and is maintained and improved by * Marcus von Appen with contributions from * Steven Johnson * Marcel Rodrigues * Dan Gillett Thanks to everyone else for their assistance, support, fixes and improvements: Sven Eckelmann, Marcel Rodrigues, Michael McCandless, Andreas Schiefer, Franz Schrober, Roger Flores, otus, Mihail Latyshov, Todd Rovito, Bil Bas, Dan McCombs, William Manire, Radomir Dopieralski, Joe Polak, Jordan F, DR0ID, Filip M. Nowak PySDL2-0.9.3/COPYING.txt0000644000000000000000000000002412260256443011277 0ustar See doc/copying.rst PySDL2-0.9.3/Makefile0000644000000000000000000000400112323150065011056 0ustar PYTHON ?= python top_srcdir := `pwd` PYTHONPATH ?= $(top_srcdir) SUBDIRS = \ $(top_srcdir)/sdl2 \ $(top_srcdir)/sdl2/ext \ $(top_srcdir)/sdl2/test \ $(top_srcdir)/sdl2/test/resources \ $(top_srcdir)/sdl2/test/util \ $(top_srcdir)/doc \ $(top_srcdir)/doc/tutorial \ $(top_srcdir)/doc/modules \ $(top_srcdir)/examples INTERPRETERS = python2.7 python3.2 python3.3 python3.4 pypy all: clean build dist: clean docs @echo "Creating dist..." @$(PYTHON) setup.py sdist --format gztar @$(PYTHON) setup.py sdist --format zip bdist: clean docs @echo "Creating bdist..." @$(PYTHON) setup.py bdist build: @echo "Running build" @$(PYTHON) setup.py build @echo "Build finished, invoke 'make install' to install." install: @echo "Installing..." @$(PYTHON) setup.py install clean: @echo "Cleaning up in $(top_srcdir)/ ..." @rm -f *.cache *.core *~ MANIFEST *.pyc *.orig *.rej @rm -rf __pycache__ @rm -rf build dist doc/html @for dir in $(SUBDIRS); do \ echo "Cleaning up in $$dir ..."; \ if test -f $$dir/Makefile; then \ make -C $$dir clean; \ fi; \ cd $$dir && rm -f *.cache *.core *~ MANIFEST *.pyc *.orig *.rej; \ done docs: @echo "Creating docs package" @rm -rf doc/html @cd doc && PYTHONPATH=$(PYTHONPATH) make html @mv doc/_build/html doc/html @rm -rf doc/_build @cd doc && make clean release: dist runtest: @PYTHONPATH=$(PYTHONPATH) $(PYTHON) -B -m sdl2.test.util.runtests testall: @for interp in $(INTERPRETERS); do \ PYTHONPATH=$(PYTHONPATH) $$interp -B -m sdl2.test.util.runtests || true; \ done # Do not run these in production environments! They are for testing # purposes only! buildall: clean @for interp in $(INTERPRETERS); do \ $$interp setup.py build; \ done installall: @for interp in $(INTERPRETERS); do \ $$interp setup.py install; \ done testpackage: @for interp in $(INTERPRETERS); do \ $$interp -c "import sdl2.test; sdl2.test.run()" || true \ done purge_installs: @for interp in $(INTERPRETERS); do \ rm -rf /usr/local/lib/$$interp/site-packages/sdl2*; \ done PySDL2-0.9.3/README.txt0000644000000000000000000000155412313774567011150 0ustar About PySDL2 ============ PySDL2 is a wrapper around the SDL2 library and as such similar to the discontinued PySDL project. In contrast to PySDL, it has no licensing restrictions, nor does it rely on C code, but uses ctypes instead. Installation ============ PySDL2 is easy to install and integrate within your own projects. Just follow Python's standard procedure of installing packages or look for a prebuilt package for your operating system or distribution. Documentation ============= If you just started with SDL and PySDL2, it is strongly recommended that you read through the tutorial of the documentation to learn the basics. You can find the documentation at *doc/html* or online at http://pysdl2.readthedocs.org. License ======= This library is given to the public domain. There are no licensing restrictions. Please see *doc/copying.rst* for further details. PySDL2-0.9.3/make.bat0000644000000000000000000001050012312631602011023 0ustar @SETLOCAL @REM Set the PYTHON path variable to your python command, like C:\Python33\python.exe @IF "%PYTHON%" == "" echo Warning: PYTHON environment path not set. @IF "%DLLPATH_X86%" == "" SET DLLPATH_X86=%CD%\..\dlls\32bit @IF "%DLLPATH_X64%" == "" SET DLLPATH_X64=%CD%\..\dlls\64bit @IF "%PYTHONPATH%" == "" SET PYTHONPATH=%CHDIR% @IF "%PYTHON27_X86%" == "" SET PYTHON27_X86=c:\Python27-x86\python.exe @IF "%PYTHON27_X64%" == "" SET PYTHON27_X64=c:\Python27-x64\python.exe @IF "%PYTHON32_X86%" == "" SET PYTHON32_X86=c:\Python32-x86\python.exe @IF "%PYTHON32_X64%" == "" SET PYTHON32_X64=c:\Python32-x64\python.exe @IF "%PYTHON33_X86%" == "" SET PYTHON33_X86=c:\Python33-x86\python.exe @IF "%PYTHON33_X64%" == "" SET PYTHON33_X64=c:\Python33-x64\python.exe @IF "%PYTHON34_X86%" == "" SET PYTHON34_X86=c:\Python34-x86\python.exe @IF "%PYTHON34_X64%" == "" SET PYTHON34_X64=c:\Python34-x64\python.exe @IF "%PYTHON%" == "" SET PYTHON=%PYTHON27_X64% @IF "%PYPY18%" == "" SET PYPY18=c:\pypy-1.8\pypy.exe @IF "%PYPY19%" == "" SET PYPY19=c:\pypy-1.9\pypy.exe @IF "%PYPY20%" == "" SET PYPY20=c:\pypy-2.0\pypy.exe @IF "%PYPY21%" == "" SET PYPY21=c:\pypy-2.1\pypy.exe @IF "%PYPY22%" == "" SET PYPY22=c:\pypy-2.2\pypy.exe @IF "%IRONPYTHON27_X86%" == "" SET IRONPYTHON27_X86=c:\IronPython-2.7.4\ipy.exe @IF "%IRONPYTHON27_X64%" == "" SET IRONPYTHON27_X64=c:\IronPython-2.7.4\ipy64.exe @SET INTERP_X64=%PYTHON27_X64%;%PYTHON32_X64%;%PYTHON33_X64%;%PYTHON34_X64%;^ %IRONPYTHON27_X64% @SET INTERP_X86=%PYTHON27_X86%;%PYTHON32_X86%;%PYTHON33_X86%;%PYTHON34_X86%;^ %PYPY18%;%PYPY19%;%PYPY20%;%PYPY21%;%PYPY22%;%IRONPYTHON27_X86% @SET INTERPRETERS=%INTERP_X86%;%INTERP_X64% @IF "%~1" == "" GOTO :all @GOTO :%~1 :all @CALL :clean @CALL :build @GOTO :eof :dist @ECHO Creating dist... @CALL :clean @CALL :docs @%PYTHON% setup.py sdist --format gztar @%PYTHON% setup.py sdist --format zip @GOTO :eof :bdist @CALL :clean @CALL :docs @ECHO Creating bdist... @FOR %%A in (%INTERPRETERS%) do %%A setup.py bdist --format=msi @GOTO :eof :build @ECHO Running build @%PYTHON% setup.py build @ECHO Build finished, invoke 'make install' to install. @GOTO :eof :install @ECHO Installing... @%PYTHON% setup.py install @GOTO :eof :clean @RMDIR /S /Q build @RMDIR /S /Q dist @FOR /d /r . %%d in (__pycache__) do @IF EXIST "%%d" RMDIR /S /Q "%%d" @DEL /S /Q MANIFEST @DEL /S /Q *.pyc @GOTO :eof :docs @IF "%SPHINXBUILD%" == "" SET SPHINXBUILD=C:\Python27-x64\Scripts\sphinx-build.exe @ECHO Creating docs package @RMDIR /S /Q doc\html @CD doc @CALL make html @MOVE /Y _build\html html @RMDIR /S /Q _build @CALL make clean @CD .. @GOTO :eof :release @CALL :dist @GOTO :eof :testall @FOR /F "tokens=1 delims=" %%A in ('CHDIR') do @SET PYTHONPATH=%%A && @SET IRONPYTHONPATH=%%A @SET PYSDL2_DLL_PATH=%DLLPATH_X86% @FOR %%A in (%INTERP_X86%) do @%%A -B -m sdl2.test.util.runtests @SET PYSDL2_DLL_PATH=%DLLPATH_X64% @FOR %%A in (%INTERP_X64%) do @%%A -B -m sdl2.test.util.runtests @GOTO :eof @REM Do not run these in production environments. They are for testing purposes @REM only! :buildall @FOR %%A in (%INTERPRETERS%) do @CALL :clean & @%%A setup.py build @CALL :clean @GOTO :eof :installall @FOR %%A in (%INTERPRETERS%) do @CALL :clean & @%%A setup.py install @CALL :clean @GOTO :eof :testall2 @SET PYSDL2_DLL_PATH=%DLLPATH_X86% @FOR %%A in (%INTERP_X86%) do @%%A -B -c "import sdl2.test; sdl2.test.run()" @SET PYSDL2_DLL_PATH=%DLLPATH_X64% @FOR %%A in (%INTERP_X64%) do @%%A -B -c "import sdl2.test; sdl2.test.run()" @GOTO :eof :purge_installs @echo Deleting data... @RMDIR /S /Q C:\Python27-x86\Lib\site-packages\sdl2 @RMDIR /S /Q C:\Python27-x64\Lib\site-packages\sdl2 @RMDIR /S /Q C:\Python32-x86\Lib\site-packages\sdl2 @RMDIR /S /Q C:\Python32-x64\Lib\site-packages\sdl2 @RMDIR /S /Q C:\Python33-x86\Lib\site-packages\sdl2 @RMDIR /S /Q C:\Python33-x64\Lib\site-packages\sdl2 @RMDIR /S /Q C:\Python34-x86\Lib\site-packages\sdl2 @RMDIR /S /Q C:\Python34-x64\Lib\site-packages\sdl2 @RMDIR /S /Q C:\pypy-1.8\site-packages\sdl2 @RMDIR /S /Q C:\pypy-1.9\site-packages\sdl2 @RMDIR /S /Q C:\pypy-2.0\site-packages\sdl2 @RMDIR /S /Q C:\pypy-2.1\site-packages\sdl2 @RMDIR /S /Q C:\pypy-2.2\site-packages\sdl2 @RMDIR /S /Q C:\IronPython-2.7.4\Lib\site-packages\sdl2 @echo done @GOTO :eof @ENDLOCAL PySDL2-0.9.3/setup.py0000644000000000000000000000435212354723627011157 0ustar #!/usr/bin/env python import os import sys from distutils.core import setup VERSION = "0.9.3" if __name__ == "__main__": if "--format=msi" in sys.argv or "bdist_msi" in sys.argv: # hack the version name to a format msi doesn't have trouble with VERSION = VERSION.replace("-alpha", "a") VERSION = VERSION.replace("-beta", "b") VERSION = VERSION.replace("-rc", "r") fname = os.path.join(os.path.dirname(os.path.abspath(__file__)), "README.txt") readme = open(fname, "r") long_desc = readme.read() readme.close() setupdata = { "name": "PySDL2", "version": VERSION, "description": "Python SDL2 bindings", "long_description": long_desc, "author": "Marcus von Appen", "author_email": "marcus@sysfault.org", "license": "Public Domain / zlib", "url": "http://bitbucket.org/marcusva/py-sdl2", "download_url": "http://bitbucket.org/marcusva/py-sdl2/downloads", "package_dir": {"sdl2.examples": "examples"}, "package_data": {"sdl2.test": ["resources/*.*"], "sdl2.examples": ["resources/*.*"]}, "packages": ["sdl2", "sdl2.ext", "sdl2.test", "sdl2.test.util", "sdl2.examples" ], "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: Public Domain", "License :: OSI Approved :: zlib/libpng License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: IronPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries :: Python Modules", ], } setup(**setupdata) PySDL2-0.9.3/PKG-INFO0000644000000000000000000000420612357043742010534 0ustar Metadata-Version: 1.1 Name: PySDL2 Version: 0.9.3 Summary: Python SDL2 bindings Home-page: http://bitbucket.org/marcusva/py-sdl2 Author: Marcus von Appen Author-email: marcus@sysfault.org License: Public Domain / zlib Download-URL: http://bitbucket.org/marcusva/py-sdl2/downloads Description: About PySDL2 ============ PySDL2 is a wrapper around the SDL2 library and as such similar to the discontinued PySDL project. In contrast to PySDL, it has no licensing restrictions, nor does it rely on C code, but uses ctypes instead. Installation ============ PySDL2 is easy to install and integrate within your own projects. Just follow Python's standard procedure of installing packages or look for a prebuilt package for your operating system or distribution. Documentation ============= If you just started with SDL and PySDL2, it is strongly recommended that you read through the tutorial of the documentation to learn the basics. You can find the documentation at *doc/html* or online at http://pysdl2.readthedocs.org. License ======= This library is given to the public domain. There are no licensing restrictions. Please see *doc/copying.rst* for further details. Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: License :: Public Domain Classifier: License :: OSI Approved :: zlib/libpng License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: IronPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development :: Libraries :: Python Modules