pyglet 2.1.13__py3-none-any.whl → 3.0.dev1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. pyglet/__init__.py +67 -61
  2. pyglet/__init__.pyi +15 -8
  3. pyglet/app/__init__.py +22 -13
  4. pyglet/app/async_app.py +212 -0
  5. pyglet/app/base.py +2 -1
  6. pyglet/app/{xlib.py → linux.py} +3 -3
  7. pyglet/config/__init__.py +101 -0
  8. pyglet/config/gl/__init__.py +30 -0
  9. pyglet/config/gl/egl.py +120 -0
  10. pyglet/config/gl/macos.py +262 -0
  11. pyglet/config/gl/windows.py +267 -0
  12. pyglet/config/gl/x11.py +142 -0
  13. pyglet/customtypes.py +43 -2
  14. pyglet/display/__init__.py +8 -6
  15. pyglet/display/base.py +3 -63
  16. pyglet/display/cocoa.py +12 -17
  17. pyglet/display/emscripten.py +39 -0
  18. pyglet/display/headless.py +23 -30
  19. pyglet/display/wayland.py +157 -0
  20. pyglet/display/win32.py +5 -21
  21. pyglet/display/xlib.py +19 -27
  22. pyglet/display/xlib_vidmoderestore.py +2 -2
  23. pyglet/enums.py +183 -0
  24. pyglet/event.py +0 -1
  25. pyglet/experimental/geoshader_sprite.py +15 -13
  26. pyglet/experimental/hidraw.py +6 -15
  27. pyglet/experimental/multitexture_sprite.py +31 -19
  28. pyglet/experimental/particles.py +13 -35
  29. pyglet/font/__init__.py +251 -85
  30. pyglet/font/base.py +116 -61
  31. pyglet/font/dwrite/__init__.py +349 -204
  32. pyglet/font/dwrite/dwrite_lib.py +27 -5
  33. pyglet/font/fontconfig.py +14 -6
  34. pyglet/font/freetype.py +138 -87
  35. pyglet/font/freetype_lib.py +19 -0
  36. pyglet/font/group.py +179 -0
  37. pyglet/font/harfbuzz/__init__.py +3 -3
  38. pyglet/font/pyodide_js.py +310 -0
  39. pyglet/font/quartz.py +319 -126
  40. pyglet/font/ttf.py +45 -3
  41. pyglet/font/user.py +14 -19
  42. pyglet/font/win32.py +45 -21
  43. pyglet/graphics/__init__.py +8 -787
  44. pyglet/graphics/allocation.py +115 -1
  45. pyglet/graphics/api/__init__.py +77 -0
  46. pyglet/graphics/api/base.py +299 -0
  47. pyglet/graphics/api/gl/__init__.py +58 -0
  48. pyglet/graphics/api/gl/base.py +24 -0
  49. pyglet/graphics/{vertexbuffer.py → api/gl/buffer.py} +104 -159
  50. pyglet/graphics/api/gl/cocoa/context.py +76 -0
  51. pyglet/graphics/api/gl/context.py +391 -0
  52. pyglet/graphics/api/gl/default_shaders.py +0 -0
  53. pyglet/graphics/api/gl/draw.py +627 -0
  54. pyglet/graphics/api/gl/egl/__init__.py +0 -0
  55. pyglet/graphics/api/gl/egl/context.py +92 -0
  56. pyglet/graphics/api/gl/enums.py +76 -0
  57. pyglet/graphics/api/gl/framebuffer.py +315 -0
  58. pyglet/graphics/api/gl/gl.py +5463 -0
  59. pyglet/graphics/api/gl/gl_info.py +188 -0
  60. pyglet/graphics/api/gl/global_opengl.py +226 -0
  61. pyglet/{gl → graphics/api/gl}/lib.py +34 -18
  62. pyglet/graphics/api/gl/shader.py +1476 -0
  63. pyglet/graphics/api/gl/shapes.py +55 -0
  64. pyglet/graphics/api/gl/sprite.py +102 -0
  65. pyglet/graphics/api/gl/state.py +219 -0
  66. pyglet/graphics/api/gl/text.py +190 -0
  67. pyglet/graphics/api/gl/texture.py +1526 -0
  68. pyglet/graphics/{vertexarray.py → api/gl/vertexarray.py} +11 -13
  69. pyglet/graphics/api/gl/vertexdomain.py +751 -0
  70. pyglet/graphics/api/gl/win32/__init__.py +0 -0
  71. pyglet/graphics/api/gl/win32/context.py +108 -0
  72. pyglet/graphics/api/gl/win32/wgl_info.py +24 -0
  73. pyglet/graphics/api/gl/xlib/__init__.py +0 -0
  74. pyglet/graphics/api/gl/xlib/context.py +174 -0
  75. pyglet/{gl → graphics/api/gl/xlib}/glx_info.py +26 -31
  76. pyglet/graphics/api/gl1/__init__.py +0 -0
  77. pyglet/{gl → graphics/api/gl1}/gl_compat.py +3 -2
  78. pyglet/graphics/api/gl2/__init__.py +0 -0
  79. pyglet/graphics/api/gl2/buffer.py +320 -0
  80. pyglet/graphics/api/gl2/draw.py +600 -0
  81. pyglet/graphics/api/gl2/global_opengl.py +122 -0
  82. pyglet/graphics/api/gl2/shader.py +200 -0
  83. pyglet/graphics/api/gl2/shapes.py +51 -0
  84. pyglet/graphics/api/gl2/sprite.py +79 -0
  85. pyglet/graphics/api/gl2/text.py +175 -0
  86. pyglet/graphics/api/gl2/vertexdomain.py +364 -0
  87. pyglet/graphics/api/webgl/__init__.py +233 -0
  88. pyglet/graphics/api/webgl/buffer.py +302 -0
  89. pyglet/graphics/api/webgl/context.py +234 -0
  90. pyglet/graphics/api/webgl/draw.py +590 -0
  91. pyglet/graphics/api/webgl/enums.py +76 -0
  92. pyglet/graphics/api/webgl/framebuffer.py +360 -0
  93. pyglet/graphics/api/webgl/gl.py +1537 -0
  94. pyglet/graphics/api/webgl/gl_info.py +130 -0
  95. pyglet/graphics/api/webgl/shader.py +1346 -0
  96. pyglet/graphics/api/webgl/shapes.py +92 -0
  97. pyglet/graphics/api/webgl/sprite.py +102 -0
  98. pyglet/graphics/api/webgl/state.py +227 -0
  99. pyglet/graphics/api/webgl/text.py +187 -0
  100. pyglet/graphics/api/webgl/texture.py +1227 -0
  101. pyglet/graphics/api/webgl/vertexarray.py +54 -0
  102. pyglet/graphics/api/webgl/vertexdomain.py +616 -0
  103. pyglet/graphics/api/webgl/webgl_js.pyi +307 -0
  104. pyglet/{image → graphics}/atlas.py +33 -32
  105. pyglet/graphics/base.py +10 -0
  106. pyglet/graphics/buffer.py +245 -0
  107. pyglet/graphics/draw.py +578 -0
  108. pyglet/graphics/framebuffer.py +26 -0
  109. pyglet/graphics/instance.py +178 -69
  110. pyglet/graphics/shader.py +267 -1553
  111. pyglet/graphics/state.py +83 -0
  112. pyglet/graphics/texture.py +703 -0
  113. pyglet/graphics/vertexdomain.py +695 -538
  114. pyglet/gui/ninepatch.py +10 -10
  115. pyglet/gui/widgets.py +120 -10
  116. pyglet/image/__init__.py +20 -1973
  117. pyglet/image/animation.py +12 -12
  118. pyglet/image/base.py +730 -0
  119. pyglet/image/codecs/__init__.py +9 -0
  120. pyglet/image/codecs/bmp.py +53 -30
  121. pyglet/image/codecs/dds.py +53 -31
  122. pyglet/image/codecs/gdiplus.py +38 -14
  123. pyglet/image/codecs/gdkpixbuf2.py +0 -2
  124. pyglet/image/codecs/js_image.py +99 -0
  125. pyglet/image/codecs/ktx2.py +161 -0
  126. pyglet/image/codecs/pil.py +1 -1
  127. pyglet/image/codecs/png.py +1 -1
  128. pyglet/image/codecs/wic.py +11 -2
  129. pyglet/info.py +26 -24
  130. pyglet/input/__init__.py +8 -0
  131. pyglet/input/base.py +163 -105
  132. pyglet/input/controller.py +13 -19
  133. pyglet/input/controller_db.py +39 -24
  134. pyglet/input/emscripten/__init__.py +18 -0
  135. pyglet/input/emscripten/gamepad_js.py +397 -0
  136. pyglet/input/linux/__init__.py +11 -5
  137. pyglet/input/linux/evdev.py +10 -11
  138. pyglet/input/linux/x11_xinput.py +2 -2
  139. pyglet/input/linux/x11_xinput_tablet.py +1 -1
  140. pyglet/input/macos/__init__.py +7 -2
  141. pyglet/input/macos/darwin_gc.py +559 -0
  142. pyglet/input/win32/__init__.py +1 -1
  143. pyglet/input/win32/directinput.py +34 -29
  144. pyglet/input/win32/xinput.py +11 -61
  145. pyglet/lib.py +3 -3
  146. pyglet/libs/__init__.py +1 -1
  147. pyglet/{gl → libs/darwin}/agl.py +1 -1
  148. pyglet/libs/darwin/cocoapy/__init__.py +2 -2
  149. pyglet/libs/darwin/cocoapy/cocoahelpers.py +181 -0
  150. pyglet/libs/darwin/cocoapy/cocoalibs.py +31 -0
  151. pyglet/libs/darwin/cocoapy/cocoatypes.py +27 -0
  152. pyglet/libs/darwin/cocoapy/runtime.py +81 -45
  153. pyglet/libs/darwin/coreaudio.py +4 -4
  154. pyglet/{gl → libs/darwin}/lib_agl.py +9 -8
  155. pyglet/libs/darwin/quartzkey.py +1 -3
  156. pyglet/libs/egl/__init__.py +2 -0
  157. pyglet/libs/egl/egl_lib.py +576 -0
  158. pyglet/libs/egl/eglext.py +51 -5
  159. pyglet/libs/linux/__init__.py +0 -0
  160. pyglet/libs/linux/egl/__init__.py +0 -0
  161. pyglet/libs/linux/egl/eglext.py +22 -0
  162. pyglet/libs/linux/glx/__init__.py +0 -0
  163. pyglet/{gl → libs/linux/glx}/glx.py +13 -14
  164. pyglet/{gl → libs/linux/glx}/glxext_arb.py +408 -192
  165. pyglet/{gl → libs/linux/glx}/glxext_mesa.py +1 -1
  166. pyglet/{gl → libs/linux/glx}/glxext_nv.py +345 -164
  167. pyglet/{gl → libs/linux/glx}/lib_glx.py +3 -2
  168. pyglet/libs/linux/wayland/__init__.py +0 -0
  169. pyglet/libs/linux/wayland/client.py +1068 -0
  170. pyglet/libs/linux/wayland/lib_wayland.py +207 -0
  171. pyglet/libs/linux/wayland/wayland_egl.py +38 -0
  172. pyglet/libs/{wayland → linux/wayland}/xkbcommon.py +26 -0
  173. pyglet/libs/{x11 → linux/x11}/xf86vmode.py +4 -4
  174. pyglet/libs/{x11 → linux/x11}/xinerama.py +2 -2
  175. pyglet/libs/{x11 → linux/x11}/xinput.py +10 -10
  176. pyglet/libs/linux/x11/xrandr.py +0 -0
  177. pyglet/libs/{x11 → linux/x11}/xrender.py +1 -1
  178. pyglet/libs/shared/__init__.py +0 -0
  179. pyglet/libs/shared/spirv/__init__.py +0 -0
  180. pyglet/libs/shared/spirv/lib_shaderc.py +85 -0
  181. pyglet/libs/shared/spirv/lib_spirv_cross.py +126 -0
  182. pyglet/libs/win32/__init__.py +28 -8
  183. pyglet/libs/win32/constants.py +59 -48
  184. pyglet/libs/win32/context_managers.py +20 -3
  185. pyglet/libs/win32/dinput.py +105 -88
  186. pyglet/{gl → libs/win32}/lib_wgl.py +52 -26
  187. pyglet/libs/win32/types.py +58 -23
  188. pyglet/{gl → libs/win32}/wgl.py +32 -25
  189. pyglet/{gl → libs/win32}/wglext_arb.py +364 -2
  190. pyglet/media/__init__.py +9 -10
  191. pyglet/media/codecs/__init__.py +12 -1
  192. pyglet/media/codecs/base.py +99 -96
  193. pyglet/media/codecs/ffmpeg.py +2 -2
  194. pyglet/media/codecs/ffmpeg_lib/libavformat.py +3 -8
  195. pyglet/media/codecs/webaudio_pyodide.py +111 -0
  196. pyglet/media/drivers/__init__.py +9 -4
  197. pyglet/media/drivers/base.py +4 -4
  198. pyglet/media/drivers/openal/__init__.py +1 -1
  199. pyglet/media/drivers/openal/adaptation.py +3 -3
  200. pyglet/media/drivers/pulse/__init__.py +1 -1
  201. pyglet/media/drivers/pulse/adaptation.py +3 -3
  202. pyglet/media/drivers/pyodide_js/__init__.py +8 -0
  203. pyglet/media/drivers/pyodide_js/adaptation.py +288 -0
  204. pyglet/media/drivers/xaudio2/adaptation.py +3 -3
  205. pyglet/media/player.py +276 -193
  206. pyglet/media/player_worker_thread.py +1 -1
  207. pyglet/model/__init__.py +39 -29
  208. pyglet/model/codecs/base.py +4 -4
  209. pyglet/model/codecs/gltf.py +3 -3
  210. pyglet/model/codecs/obj.py +71 -43
  211. pyglet/resource.py +129 -78
  212. pyglet/shapes.py +154 -194
  213. pyglet/sprite.py +47 -164
  214. pyglet/text/__init__.py +44 -54
  215. pyglet/text/caret.py +12 -7
  216. pyglet/text/document.py +19 -17
  217. pyglet/text/formats/html.py +2 -2
  218. pyglet/text/formats/structured.py +10 -40
  219. pyglet/text/layout/__init__.py +20 -13
  220. pyglet/text/layout/base.py +176 -287
  221. pyglet/text/layout/incremental.py +9 -10
  222. pyglet/text/layout/scrolling.py +7 -95
  223. pyglet/window/__init__.py +183 -172
  224. pyglet/window/cocoa/__init__.py +62 -51
  225. pyglet/window/cocoa/pyglet_delegate.py +2 -25
  226. pyglet/window/cocoa/pyglet_view.py +9 -8
  227. pyglet/window/dialog/__init__.py +184 -0
  228. pyglet/window/dialog/base.py +99 -0
  229. pyglet/window/dialog/darwin.py +121 -0
  230. pyglet/window/dialog/linux.py +72 -0
  231. pyglet/window/dialog/windows.py +194 -0
  232. pyglet/window/emscripten/__init__.py +779 -0
  233. pyglet/window/headless/__init__.py +44 -28
  234. pyglet/window/key.py +2 -0
  235. pyglet/window/mouse.py +2 -2
  236. pyglet/window/wayland/__init__.py +377 -0
  237. pyglet/window/win32/__init__.py +101 -46
  238. pyglet/window/xlib/__init__.py +104 -66
  239. {pyglet-2.1.13.dist-info → pyglet-3.0.dev1.dist-info}/METADATA +2 -3
  240. pyglet-3.0.dev1.dist-info/RECORD +322 -0
  241. {pyglet-2.1.13.dist-info → pyglet-3.0.dev1.dist-info}/WHEEL +1 -1
  242. pyglet/gl/__init__.py +0 -208
  243. pyglet/gl/base.py +0 -499
  244. pyglet/gl/cocoa.py +0 -309
  245. pyglet/gl/gl.py +0 -4625
  246. pyglet/gl/gl.pyi +0 -2320
  247. pyglet/gl/gl_compat.pyi +0 -3097
  248. pyglet/gl/gl_info.py +0 -190
  249. pyglet/gl/headless.py +0 -166
  250. pyglet/gl/wgl_info.py +0 -36
  251. pyglet/gl/wglext_nv.py +0 -1096
  252. pyglet/gl/win32.py +0 -268
  253. pyglet/gl/xlib.py +0 -295
  254. pyglet/image/buffer.py +0 -274
  255. pyglet/image/codecs/s3tc.py +0 -354
  256. pyglet/libs/x11/xrandr.py +0 -166
  257. pyglet-2.1.13.dist-info/RECORD +0 -234
  258. /pyglet/{libs/wayland → graphics/api/gl/cocoa}/__init__.py +0 -0
  259. /pyglet/libs/{egl → linux/egl}/egl.py +0 -0
  260. /pyglet/libs/{egl → linux/egl}/lib.py +0 -0
  261. /pyglet/libs/{ioctl.py → linux/ioctl.py} +0 -0
  262. /pyglet/libs/{wayland → linux/wayland}/gbm.py +0 -0
  263. /pyglet/libs/{x11 → linux/x11}/__init__.py +0 -0
  264. /pyglet/libs/{x11 → linux/x11}/cursorfont.py +0 -0
  265. /pyglet/libs/{x11 → linux/x11}/xlib.py +0 -0
  266. /pyglet/libs/{x11 → linux/x11}/xsync.py +0 -0
  267. {pyglet-2.1.13.dist-info/licenses → pyglet-3.0.dev1.dist-info}/LICENSE +0 -0
pyglet/sprite.py CHANGED
@@ -67,125 +67,37 @@ sprites within batches.
67
67
  from __future__ import annotations
68
68
 
69
69
  import sys
70
- import warnings
71
- from typing import TYPE_CHECKING, ClassVar, Literal
70
+ from typing import TYPE_CHECKING
72
71
 
73
72
  import pyglet
74
- from pyglet import clock, event, graphics, image
75
- from pyglet.gl import (
76
- GL_BLEND,
77
- GL_ONE_MINUS_SRC_ALPHA,
78
- GL_SRC_ALPHA,
79
- GL_TEXTURE0,
80
- GL_TRIANGLES,
81
- glActiveTexture,
82
- glBindTexture,
83
- glBlendFunc,
84
- glDisable,
85
- glEnable,
86
- )
87
-
88
- _is_pyglet_doc_run = hasattr(sys, "is_pyglet_doc_run") and sys.is_pyglet_doc_run
73
+ from pyglet import event, clock
89
74
 
90
75
  if TYPE_CHECKING:
91
- from pyglet.graphics import Batch, Group
92
- from pyglet.graphics.shader import ShaderProgram
93
- from pyglet.image import AbstractImage, Animation, Texture
94
-
95
- vertex_source: str = """#version 150 core
96
- in vec3 translate;
97
- in vec4 colors;
98
- in vec3 tex_coords;
99
- in vec2 scale;
100
- in vec3 position;
101
- in float rotation;
102
-
103
- out vec4 vertex_colors;
104
- out vec3 texture_coords;
105
-
106
- uniform WindowBlock
107
- {
108
- mat4 projection;
109
- mat4 view;
110
- } window;
111
-
112
- mat4 m_scale = mat4(1.0);
113
- mat4 m_rotation = mat4(1.0);
114
- mat4 m_translate = mat4(1.0);
115
-
116
- void main()
117
- {
118
- m_scale[0][0] = scale.x;
119
- m_scale[1][1] = scale.y;
120
- m_translate[3][0] = translate.x;
121
- m_translate[3][1] = translate.y;
122
- m_translate[3][2] = translate.z;
123
- m_rotation[0][0] = cos(-radians(rotation));
124
- m_rotation[0][1] = sin(-radians(rotation));
125
- m_rotation[1][0] = -sin(-radians(rotation));
126
- m_rotation[1][1] = cos(-radians(rotation));
127
-
128
- gl_Position = window.projection * window.view * m_translate * m_rotation * m_scale * vec4(position, 1.0);
129
-
130
- vertex_colors = colors;
131
- texture_coords = tex_coords;
132
- }
133
- """
134
-
135
- fragment_source: str = """#version 150 core
136
- in vec4 vertex_colors;
137
- in vec3 texture_coords;
138
- out vec4 final_colors;
139
-
140
- uniform sampler2D sprite_texture;
141
-
142
- void main()
143
- {
144
- final_colors = texture(sprite_texture, texture_coords.xy) * vertex_colors;
145
- }
146
- """
147
-
148
- fragment_array_source: str = """#version 150 core
149
- in vec4 vertex_colors;
150
- in vec3 texture_coords;
151
- out vec4 final_colors;
152
-
153
- uniform sampler2DArray sprite_texture;
154
-
155
- void main()
156
- {
157
- final_colors = texture(sprite_texture, texture_coords) * vertex_colors;
158
- }
159
- """
160
-
161
-
162
- def get_default_shader() -> ShaderProgram:
163
- """Create and return the default sprite shader.
76
+ from typing import ClassVar, Literal
77
+ from pyglet.graphics.texture import TextureBase
164
78
 
165
- This method allows the module to be imported without an OpenGL Context.
166
- """
167
- return pyglet.gl.current_context.create_program((vertex_source, 'vertex'),
168
- (fragment_source, 'fragment'))
79
+ from pyglet.graphics import Group, Batch, ShaderProgram, GeometryMode
80
+ from pyglet.enums import BlendFactor
81
+ from pyglet.image.base import Animation
82
+ from pyglet.graphics.texture import TextureArrayRegion
169
83
 
170
84
 
171
- def get_default_array_shader() -> ShaderProgram:
172
- """Create and return the default array sprite shader.
85
+ if pyglet.options.backend in ("opengl", "gles3"):
86
+ from pyglet.graphics.api.gl.sprite import get_default_array_shader, get_default_shader
87
+ elif pyglet.options.backend in ("gl2", "gles2"):
88
+ from pyglet.graphics.api.gl2.sprite import get_default_array_shader, get_default_shader
89
+ elif pyglet.options.backend == "webgl":
90
+ from pyglet.graphics.api.webgl.sprite import get_default_array_shader, get_default_shader
91
+ elif pyglet.options.backend == "vulkan":
92
+ from pyglet.graphics.api.vulkan.sprite import get_default_array_shader, get_default_shader, SpriteGroup
173
93
 
174
- This method allows the module to be imported without an OpenGL Context.
175
- """
176
- return pyglet.gl.current_context.create_program((vertex_source, 'vertex'),
177
- (fragment_array_source, 'fragment'))
94
+ _is_pyglet_doc_run = hasattr(sys, "is_pyglet_doc_run") and sys.is_pyglet_doc_run
178
95
 
179
96
 
180
- class SpriteGroup(graphics.Group):
181
- """Shared Sprite rendering Group.
97
+ class SpriteGroup(Group):
98
+ """Shared Sprite rendering Group."""
182
99
 
183
- The Group defines custom ``__eq__`` and ``__hash__`` methods, and so will
184
- be automatically coalesced with other Sprite Groups sharing the same parent
185
- Group, Texture and blend parameters.
186
- """
187
-
188
- def __init__(self, texture: Texture, blend_src: int, blend_dest: int,
100
+ def __init__(self, texture: TextureBase, blend_src: BlendFactor, blend_dest: BlendFactor,
189
101
  program: ShaderProgram, parent: Group | None = None) -> None:
190
102
  """Create a sprite group.
191
103
 
@@ -196,11 +108,9 @@ class SpriteGroup(graphics.Group):
196
108
  texture:
197
109
  The (top-level) texture containing the sprite image.
198
110
  blend_src:
199
- OpenGL blend source mode; for example,
200
- ``GL_SRC_ALPHA``.
111
+ Blend factor source mode; for example: ``SRC_ALPHA``.
201
112
  blend_dest:
202
- OpenGL blend destination mode; for example,
203
- ``GL_ONE_MINUS_SRC_ALPHA``.
113
+ Blend factor source mode; for example: ``_ONE_MINUS_SRC_ALPHA``.
204
114
  program:
205
115
  A custom ShaderProgram.
206
116
  parent:
@@ -208,39 +118,9 @@ class SpriteGroup(graphics.Group):
208
118
  """
209
119
  super().__init__(parent=parent)
210
120
  self.texture = texture
211
- self.blend_src = blend_src
212
- self.blend_dest = blend_dest
213
- self.program = program
214
-
215
- def set_state(self) -> None:
216
- self.program.use()
217
-
218
- glActiveTexture(GL_TEXTURE0)
219
- glBindTexture(self.texture.target, self.texture.id)
220
-
221
- glEnable(GL_BLEND)
222
- glBlendFunc(self.blend_src, self.blend_dest)
223
-
224
- def unset_state(self) -> None:
225
- glDisable(GL_BLEND)
226
- self.program.stop()
227
-
228
- def __repr__(self) -> str:
229
- return f"{self.__class__.__name__}({self.texture})"
230
-
231
- def __eq__(self, other: SpriteGroup) -> bool:
232
- return (other.__class__ is self.__class__ and
233
- self.program is other.program and
234
- self.parent == other.parent and
235
- self.texture.target == other.texture.target and
236
- self.texture.id == other.texture.id and
237
- self.blend_src == other.blend_src and
238
- self.blend_dest == other.blend_dest)
239
-
240
- def __hash__(self) -> int:
241
- return hash((self.program, self.parent,
242
- self.texture.id, self.texture.target,
243
- self.blend_src, self.blend_dest))
121
+ self.set_shader_program(program)
122
+ self.set_blend(blend_src, blend_dest)
123
+ self.set_texture(self.texture, 0)
244
124
 
245
125
 
246
126
  class Sprite(event.EventDispatcher):
@@ -265,10 +145,10 @@ class Sprite(event.EventDispatcher):
265
145
  group_class: ClassVar[type[SpriteGroup | Group]] = SpriteGroup
266
146
 
267
147
  def __init__(self,
268
- img: AbstractImage | Animation,
148
+ img: TextureBase | Animation,
269
149
  x: float = 0, y: float = 0, z: float = 0,
270
- blend_src: int = GL_SRC_ALPHA,
271
- blend_dest: int = GL_ONE_MINUS_SRC_ALPHA,
150
+ blend_src: BlendFactor = BlendFactor.SRC_ALPHA,
151
+ blend_dest: BlendFactor = BlendFactor.ONE_MINUS_SRC_ALPHA,
272
152
  batch: Batch | None = None,
273
153
  group: Group | None = None,
274
154
  subpixel: bool = False,
@@ -308,7 +188,7 @@ class Sprite(event.EventDispatcher):
308
188
  self._y = y
309
189
  self._z = z
310
190
 
311
- if isinstance(img, image.Animation):
191
+ if isinstance(img, Animation):
312
192
  self._animation = img
313
193
  self._texture = img.frames[0].image.get_texture()
314
194
  self._next_dt = img.frames[0].duration
@@ -318,7 +198,7 @@ class Sprite(event.EventDispatcher):
318
198
  self._texture = img.get_texture()
319
199
 
320
200
  if not program:
321
- if isinstance(img, image.TextureArrayRegion):
201
+ if isinstance(img, TextureArrayRegion):
322
202
  program = get_default_array_shader()
323
203
  else:
324
204
  program = get_default_shader()
@@ -368,14 +248,14 @@ class Sprite(event.EventDispatcher):
368
248
 
369
249
  if frame.duration is not None:
370
250
  duration = frame.duration - (self._next_dt - dt)
371
- duration = min(max(0, duration), frame.duration)
251
+ duration = min(max(0.0, duration), frame.duration)
372
252
  clock.schedule_once(self._animate, duration)
373
253
  self._next_dt = duration
374
254
  else:
375
255
  self.dispatch_event('on_animation_end')
376
256
 
377
257
  @property
378
- def blend_mode(self) -> tuple[int, int]:
258
+ def blend_mode(self) -> tuple[BlendFactor, BlendFactor]:
379
259
  """The current blend mode applied to this sprite.
380
260
 
381
261
  .. note:: Changing this can be an expensive operation as it involves a group creation and transfer.
@@ -393,7 +273,7 @@ class Sprite(event.EventDispatcher):
393
273
 
394
274
  self._group = self.get_sprite_group()
395
275
  if self._batch is not None:
396
- self._batch.migrate(self._vertex_list, GL_TRIANGLES, self._group, self._batch)
276
+ self._batch.migrate(self._vertex_list, GeometryMode.TRIANGLES, self._group, self._batch)
397
277
 
398
278
  @property
399
279
  def program(self) -> ShaderProgram:
@@ -411,7 +291,7 @@ class Sprite(event.EventDispatcher):
411
291
  self._group = self.get_sprite_group()
412
292
 
413
293
  if (self._batch and
414
- self._batch.update_shader(self._vertex_list, GL_TRIANGLES, self._group, program)):
294
+ self._batch.update_shader(self._vertex_list, GeometryMode.TRIANGLES, self._group, program)):
415
295
  # Exit early if changing domain is not needed.
416
296
  return
417
297
 
@@ -436,7 +316,7 @@ class Sprite(event.EventDispatcher):
436
316
  return
437
317
 
438
318
  if batch is not None and self._batch is not None:
439
- self._batch.migrate(self._vertex_list, GL_TRIANGLES, self._group, batch)
319
+ self._batch.migrate(self._vertex_list, GeometryMode.TRIANGLES, self._group, batch)
440
320
  self._batch = batch
441
321
  else:
442
322
  self._vertex_list.delete()
@@ -460,10 +340,10 @@ class Sprite(event.EventDispatcher):
460
340
  self._user_group = group
461
341
  self._group = self.get_sprite_group()
462
342
  if self._batch is not None:
463
- self._batch.migrate(self._vertex_list, GL_TRIANGLES, self._group, self._batch)
343
+ self._batch.migrate(self._vertex_list, GeometryMode.TRIANGLES, self._group, self._batch)
464
344
 
465
345
  @property
466
- def image(self) -> AbstractImage | Animation:
346
+ def image(self) -> TextureBase | Animation:
467
347
  """The Sprite's Image or Animation to display.
468
348
 
469
349
  .. note:: Changing this can be an expensive operation if the texture is not part of the same texture or atlas.
@@ -473,12 +353,12 @@ class Sprite(event.EventDispatcher):
473
353
  return self._texture
474
354
 
475
355
  @image.setter
476
- def image(self, img: AbstractImage | Animation) -> None:
356
+ def image(self, img: TextureBase | Animation) -> None:
477
357
  if self._animation is not None:
478
358
  clock.unschedule(self._animate)
479
359
  self._animation = None
480
360
 
481
- if isinstance(img, image.Animation):
361
+ if isinstance(img, Animation):
482
362
  self._animation = img
483
363
  self._frame_index = 0
484
364
  self._set_texture(img.frames[0].image.get_texture())
@@ -489,19 +369,20 @@ class Sprite(event.EventDispatcher):
489
369
  self._set_texture(img.get_texture())
490
370
  self._update_position()
491
371
 
492
- def _set_texture(self, texture: Texture) -> None:
372
+ def _set_texture(self, texture: TextureBase) -> None:
493
373
  if texture.id is not self._texture.id:
494
374
  self._vertex_list.delete()
495
375
  self._texture = texture
496
376
  self._group = self.get_sprite_group()
497
377
  self._create_vertex_list()
378
+ print("CREATE VERTEX LIST")
498
379
  else:
499
380
  self._vertex_list.tex_coords[:] = texture.tex_coords
500
381
  self._texture = texture
501
382
 
502
383
  def _create_vertex_list(self) -> None:
503
384
  self._vertex_list = self.program.vertex_list_indexed(
504
- 4, GL_TRIANGLES, [0, 1, 2, 0, 2, 3], self._batch, self._group,
385
+ 4, GeometryMode.TRIANGLES, [0, 1, 2, 0, 2, 3], self._batch, self._group,
505
386
  position=('f', self._get_vertices()),
506
387
  colors=('Bn', self._rgba * 4),
507
388
  translate=('f', (self._x, self._y, self._z) * 4),
@@ -844,9 +725,10 @@ class Sprite(event.EventDispatcher):
844
725
  See the module documentation for hints on drawing multiple sprites
845
726
  efficiently.
846
727
  """
847
- self._group.set_state_recursive()
848
- self._vertex_list.draw(GL_TRIANGLES)
849
- self._group.unset_state_recursive()
728
+ ctx = pyglet.graphics.api.core.current_context
729
+ self._group.set_state_recursive(ctx)
730
+ self._vertex_list.draw(GeometryMode.TRIANGLES)
731
+ self._group.unset_state_recursive(ctx)
850
732
 
851
733
  if _is_pyglet_doc_run:
852
734
  # Events
@@ -863,3 +745,4 @@ class Sprite(event.EventDispatcher):
863
745
 
864
746
 
865
747
  Sprite.register_event_type('on_animation_end')
748
+
pyglet/text/__init__.py CHANGED
@@ -38,12 +38,12 @@ creating scrollable layouts.
38
38
  from __future__ import annotations
39
39
 
40
40
  from abc import abstractmethod
41
- from enum import Enum
42
41
  from os.path import dirname as _dirname
43
42
  from os.path import splitext as _splitext
44
43
  from typing import TYPE_CHECKING, Any, BinaryIO, Literal
45
44
 
46
45
  import pyglet
46
+ from pyglet.font import base
47
47
 
48
48
  from pyglet.text import caret, document, layout # noqa: F401
49
49
 
@@ -79,48 +79,6 @@ class DocumentDecoder:
79
79
  SupportedMimeTypes = Literal["text/plain", "text/html", "text/vnd.pyglet-attributed"]
80
80
 
81
81
 
82
- class Weight(str, Enum):
83
- """An :py:class:`~enum.Enum` of known cross-platform font weight strings.
84
-
85
- Each value is both an :py:class:`~enum.Enum` and a :py:class:`str`.
86
- This is not a built-in Python :py:class:`~enum.StrEnum` to ensure
87
- compatibility with Python < 3.11.
88
-
89
- .. important:: Fonts will use the closest match if they lack a weight!
90
-
91
- The values of this enum imitate the string names for font weights
92
- as used in CSS and the OpenType specification. Numerical font weights
93
- are not supported because:
94
-
95
- * Integer font weight support and behavior varies by back-end
96
- * Some font renderers do not support or round :py:class:`float` values
97
- * Some font renderers lack support for variable-width fonts
98
-
99
- Additional weight strings may be supported by certain font-rendering
100
- back-ends. To learn more, please see your platform's API documentation
101
- and the following:
102
-
103
- #. `The MDN article on CSS font weights <https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight>`_
104
- #. `The OpenType specification <https://learn.microsoft.com/en-us/typography/opentype/spec/os2#usweightclass>`_
105
-
106
- """
107
-
108
- THIN = 'thin'
109
- EXTRALIGHT = 'extralight'
110
- LIGHT = 'light'
111
- NORMAL = 'normal'
112
- """The default weight for a font."""
113
- MEDIUM = 'medium'
114
- SEMIBOLD = 'semibold'
115
- BOLD = 'bold'
116
- """The default **bold** style for a font."""
117
- EXTRABOLD = 'extrabold'
118
- ULTRABOLD = 'ultrabold'
119
-
120
- def __str__(self) -> str:
121
- return self.value
122
-
123
-
124
82
  def get_decoder(filename: str | None, mimetype: SupportedMimeTypes | None = None) -> DocumentDecoder:
125
83
  """Get a document decoder for the given filename and MIME type.
126
84
 
@@ -239,6 +197,7 @@ class DocumentLabel(layout.TextLayout):
239
197
  multiline: bool = False, dpi: int | None = None,
240
198
  batch: Batch | None = None, group: Group | None = None,
241
199
  program: ShaderProgram | None = None,
200
+ shaping: bool = True,
242
201
  init_document: bool = True,
243
202
  ) -> None:
244
203
  """Create a label for a given document.
@@ -268,13 +227,16 @@ class DocumentLabel(layout.TextLayout):
268
227
  batch: Optional graphics batch to add the label to.
269
228
  group: Optional graphics group to use.
270
229
  program: Optional graphics shader to use. Will affect all glyphs.
230
+ shaping:
231
+ If the text should use proper positioning and typography according to the font and global
232
+ ``pyglet.options.text_shaping`` option. If ``False``, metrics will instead be tied to the glyph sizes.
271
233
  init_document:
272
234
  If ``True``, the document will be initialized. If you
273
235
  are passing an already-initialized document, then you can
274
236
  avoid duplicating work by setting this to ``False``.
275
237
  """
276
238
  super().__init__(document, x, y, z, width, height, anchor_x, anchor_y, rotation,
277
- multiline, dpi, batch, group, program, init_document=init_document)
239
+ multiline, dpi, batch, group, program, shaping=shaping, init_document=init_document)
278
240
 
279
241
  @property
280
242
  def text(self) -> str:
@@ -318,17 +280,40 @@ class DocumentLabel(layout.TextLayout):
318
280
  self.color = list(map(int, (*self.color[:3], alpha)))
319
281
 
320
282
  @property
321
- def font_name(self) -> str | list[str]:
322
- """Font family name.
283
+ def font_name(self) -> str:
284
+ """The current font family name.
285
+
286
+ The value is read from the beginning of this document.
323
287
 
324
288
  The font name, as passed to :py:func:`pyglet.font.load`. A list of names can
325
289
  optionally be given: the first matching font will be used.
326
290
  """
327
- return self.document.get_style("font_name")
291
+ return self.document.get_font(0).name
328
292
 
329
293
  @font_name.setter
330
294
  def font_name(self, font_name: str | list[str]) -> None:
331
- self.document.set_style(0, len(self.document.text), {"font_name": font_name})
295
+ resolved_font_name = pyglet.font.manager.get_resolved_name(font_name)
296
+ self.document.set_style(0, len(self.document.text), {"font_name": resolved_font_name})
297
+
298
+ @property
299
+ def font(self) -> base.Font:
300
+ """The current font object used at the beginning of the text.
301
+
302
+ Setting this property will change the font for the entire document.
303
+
304
+ .. versionadded:: 3.0
305
+ """
306
+ return self.document.get_font(0)
307
+
308
+ @font.setter
309
+ def font(self, font: base.Font) -> None:
310
+ self.document.set_style(0, len(self.document.text), {
311
+ "font_name": font.name,
312
+ "font_size": font.size,
313
+ "weight": font.weight,
314
+ "italic": font.style,
315
+ "stretch": font.stretch,
316
+ })
332
317
 
333
318
  @property
334
319
  def font_size(self) -> float:
@@ -399,9 +384,10 @@ class Label(DocumentLabel):
399
384
  anchor_x: AnchorX = "left", anchor_y: AnchorY = "baseline", rotation: float = 0.0,
400
385
  multiline: bool = False, dpi: int | None = None,
401
386
  font_name: str | None = None, font_size: float | None = None,
402
- weight: str = "normal", italic: bool | str = False, stretch: bool | str = False,
387
+ weight: str = "normal", style: str = "normal", stretch: str = "normal",
403
388
  color: tuple[int, int, int, int] | tuple[int, int, int] = (255, 255, 255, 255),
404
389
  align: HorizontalAlign = "left",
390
+ shaping: bool = True,
405
391
  batch: Batch | None = None, group: Group | None = None,
406
392
  program: ShaderProgram | None = None,
407
393
  ) -> None:
@@ -441,12 +427,13 @@ class Label(DocumentLabel):
441
427
  font_size:
442
428
  Font size, in points.
443
429
  weight:
444
- The 'weight' of the font (boldness). See the :py:class:`~Weight`
430
+ The 'weight' of the font (boldness). See the :py:class:`~pyglet.enums.Weight`
445
431
  enum for valid cross-platform weight names.
446
- italic:
447
- Italic font style.
432
+ style:
433
+ Italic font style. See the :py:class:`~pyglet.enums.Style` enum for valid cross-platform style names.
448
434
  stretch:
449
- Stretch font style.
435
+ Stretch font style. See the :py:class:`~pyglet.enums.Stretch` enum for valid cross-platform
436
+ style names.
450
437
  color:
451
438
  Font color as RGBA or RGB components, each within
452
439
  ``0 <= component <= 255``.
@@ -454,6 +441,9 @@ class Label(DocumentLabel):
454
441
  Horizontal alignment of text on a line, only applies if
455
442
  a width is supplied. One of ``"left"``, ``"center"``
456
443
  or ``"right"``.
444
+ shaping:
445
+ If the text should use proper positioning and typography according to the font and global
446
+ ``pyglet.options.text_shaping`` option. If ``False``, metrics will instead be tied to the glyph sizes.
457
447
  batch:
458
448
  Optional graphics batch to add the label to.
459
449
  group:
@@ -472,7 +462,7 @@ class Label(DocumentLabel):
472
462
  "font_name": font_name,
473
463
  "font_size": font_size,
474
464
  "weight": weight,
475
- "italic": italic,
465
+ "style": style,
476
466
  "stretch": stretch,
477
467
  "color": rgba,
478
468
  "align": align,
pyglet/text/caret.py CHANGED
@@ -19,6 +19,7 @@ from typing import TYPE_CHECKING, Any, Pattern
19
19
  from pyglet import clock, event
20
20
  from pyglet.window import key
21
21
  from pyglet.event import EventDispatcher
22
+ from pyglet.graphics import GeometryMode
22
23
 
23
24
  if TYPE_CHECKING:
24
25
  from pyglet.graphics import Batch
@@ -91,7 +92,6 @@ class Caret(EventDispatcher):
91
92
  `window` : `~pyglet.window.Window`
92
93
  For the clipboard feature to work, a window object is needed to be passed in to access and set clipboard content.
93
94
  """
94
- from pyglet import gl
95
95
  self._layout = layout
96
96
 
97
97
  self._custom_batch = batch is not None
@@ -106,9 +106,15 @@ class Caret(EventDispatcher):
106
106
 
107
107
  colors = r, g, b, self._visible_alpha, r, g, b, self._visible_alpha
108
108
 
109
- self._list = self._group.program.vertex_list(2, gl.GL_LINES, self._batch, self._group,
110
- colors=("Bn", colors),
111
- visible=("f", (1, 1)))
109
+ self._list = self._group.program.vertex_list(2, GeometryMode.LINES, self._batch, self._group,
110
+ position=('f', (0, 0, 0) * 2),
111
+ translation=('f', (0, 0, 0) * 2),
112
+ view_translation=('f', (0, 0, 0) * 2),
113
+ anchor=('f', (0, 0) * 2),
114
+ rotation=('f', (0, 0)),
115
+ visible=('f', (1, 1)),
116
+ colors=("Bn", colors))
117
+
112
118
  self._ideal_x = None
113
119
  self._ideal_line = None
114
120
  self._next_attributes = {}
@@ -124,14 +130,13 @@ class Caret(EventDispatcher):
124
130
 
125
131
  @layout.setter
126
132
  def layout(self, layout: IncrementalTextLayout) -> None:
127
- if self._layout == layout and self._group == layout.group:
133
+ if self._layout == layout and self._group == layout.foreground_decoration_group:
128
134
  return
129
135
 
130
- from pyglet.gl import GL_LINES
131
136
  self._layout = layout
132
137
  batch = self._batch if self._custom_batch else layout.batch
133
138
  self._group = layout.foreground_decoration_group
134
- self._batch.migrate(self._list, GL_LINES, self._group, batch)
139
+ self._batch.migrate(self._list, GeometryMode.LINES, self._group, batch)
135
140
 
136
141
  def delete(self) -> None:
137
142
  """Remove the caret from its batch.
pyglet/text/document.py CHANGED
@@ -14,18 +14,18 @@ example::
14
14
  0 5 10 15 20
15
15
  The cat sat on the mat.
16
16
  +++++++ +++++++ "weight"
17
- ++++++ "italic"
17
+ ++++++ "style"
18
18
 
19
19
  If this example were to be rendered, "The cat" and "the mat" would have a weight
20
20
  set ("bold", "thin", etc.), and "on the" would be in italics. Note that the second
21
21
  "the" is both weighted and italic.
22
22
 
23
23
  The document styles recorded for this example would be a specific ``"weight"`` over
24
- ranges (0-7) & (15-22) and ``"italic"`` over range (12-18). Overlapping styles are
24
+ ranges (0-7) & (15-22) and ``"style"`` over range (12-18). Overlapping document styles are
25
25
  permitted; unlike HTML and other structured markup, the ranges need not be nested.
26
26
 
27
27
  The document has no knowledge of the semantics of ``"weight"`` names or
28
- ``"italic"``, it stores only the style names. The pyglet layout classes give
28
+ ``"style"`` names, it stores only the document style key names. The pyglet layout classes give
29
29
  meaning to these style names in the way they are rendered; but you are also free
30
30
  to invent your own style names (which will be ignored by the layout classes).
31
31
  This can be useful to tag areas of interest in a document, or maintain
@@ -71,9 +71,11 @@ The following character style attribute names are recognised by pyglet:
71
71
  ``font_size``
72
72
  Font size, in points.
73
73
  ``weight``
74
- String.
75
- ``italic``
76
- Boolean.
74
+ String or :py:class:`~pyglet.enums.Weight`.
75
+ ``style``
76
+ String or :py:class:`~pyglet.enums.Style`.
77
+ ``stretch``
78
+ String or :py:class:`~pyglet.enums.Stretch`.
77
79
  ``underline``
78
80
  4-tuple of ints in range (0, 255) giving RGBA underline color, or None
79
81
  (default) for no underline.
@@ -337,7 +339,7 @@ class AbstractDocument(event.EventDispatcher):
337
339
  """Get a style iterator over the `pyglet.font.Font` instances used in the document.
338
340
 
339
341
  The font instances are created on-demand by inspection of the
340
- ``font_name``, ``font_size``, ``weight`` and ``italic`` style
342
+ ``font_name``, ``font_size``, ``weight`` and ``style`` document style
341
343
  attributes.
342
344
 
343
345
  Args:
@@ -571,9 +573,9 @@ class UnformattedDocument(AbstractDocument):
571
573
  font_name = self.styles.get("font_name")
572
574
  font_size = self.styles.get("font_size")
573
575
  weight = self.styles.get("weight", "normal")
574
- italic = self.styles.get("italic", False)
575
- stretch = self.styles.get("stretch", False)
576
- return font.load(font_name, font_size, weight=weight, italic=italic, stretch=stretch, dpi=dpi)
576
+ style = self.styles.get("style", "normal")
577
+ stretch = self.styles.get("stretch", "normal")
578
+ return font.load(font_name, font_size, weight=weight, style=style, stretch=stretch, dpi=dpi)
577
579
 
578
580
  def get_element_runs(self) -> runlist.ConstRunIterator:
579
581
  return runlist.ConstRunIterator(len(self._text), None)
@@ -616,7 +618,7 @@ class FormattedDocument(AbstractDocument):
616
618
  self.get_style_runs("font_name"),
617
619
  self.get_style_runs("font_size"),
618
620
  self.get_style_runs("weight"),
619
- self.get_style_runs("italic"),
621
+ self.get_style_runs("style"),
620
622
  self.get_style_runs("stretch"),
621
623
  dpi)
622
624
 
@@ -670,21 +672,21 @@ class _ElementIterator(runlist.RunIterator):
670
672
  class _FontStyleRunsRangeIterator(runlist.RunIterator):
671
673
  # XXX subclass runlist
672
674
  def __init__(self, font_names: runlist.RunIterator, font_sizes: runlist.RunIterator, weights: runlist.RunIterator,
673
- italics: runlist.RunIterator, stretch: runlist.RunIterator, dpi: int | None) -> None:
674
- self.zip_iter = runlist.ZipRunIterator((font_names, font_sizes, weights, italics, stretch))
675
+ italic_styles: runlist.RunIterator, stretch: runlist.RunIterator, dpi: int | None) -> None:
676
+ self.zip_iter = runlist.ZipRunIterator((font_names, font_sizes, weights, italic_styles, stretch))
675
677
  self.dpi = dpi
676
678
 
677
679
  def ranges(self, start: int, end: int) -> Generator[tuple[int, int, Font], None, None]:
678
680
  from pyglet import font
679
681
  for start_, end_, styles in self.zip_iter.ranges(start, end):
680
- font_name, font_size, weight, italic, stretch = styles
681
- ft = font.load(font_name, font_size, weight=weight or "normal", italic=bool(italic), stretch=stretch or False, dpi=self.dpi)
682
+ font_name, font_size, weight, italic_style, stretch = styles
683
+ ft = font.load(font_name, font_size, weight=weight, style=italic_style, stretch=stretch, dpi=self.dpi)
682
684
  yield start_, end_, ft
683
685
 
684
686
  def __getitem__(self, index: int) -> Font:
685
687
  from pyglet import font
686
- font_name, font_size, weight, italic, stretch = self.zip_iter[index]
687
- return font.load(font_name, font_size, weight=weight or "normal", italic=bool(italic), stretch=stretch or False, dpi=self.dpi)
688
+ font_name, font_size, weight, italic_style, stretch = self.zip_iter[index]
689
+ return font.load(font_name, font_size, weight=weight, style=italic_style, stretch=stretch, dpi=self.dpi)
688
690
 
689
691
 
690
692
  class _NoStyleRangeIterator(runlist.RunIterator):