pyglet 2.1.12__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 +4 -17
  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 +27 -5
  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 +147 -177
  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.12.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.12.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.12.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.12.dist-info/licenses → pyglet-3.0.dev1.dist-info}/LICENSE +0 -0
@@ -14,26 +14,14 @@ from typing import (
14
14
  )
15
15
 
16
16
  import pyglet
17
+
17
18
  from pyglet import graphics
18
- from pyglet.font.base import GlyphPosition
19
- from pyglet.gl import (
20
- GL_BLEND,
21
- GL_DEPTH_ATTACHMENT,
22
- GL_DEPTH_COMPONENT,
23
- GL_LINES,
24
- GL_NEAREST,
25
- GL_ONE_MINUS_SRC_ALPHA,
26
- GL_SRC_ALPHA,
27
- GL_TEXTURE0,
28
- GL_TRIANGLES,
29
- glActiveTexture,
30
- glBindTexture,
31
- glBlendFunc,
32
- glDisable,
33
- glEnable,
34
- )
35
- from pyglet.graphics import Group
19
+ from pyglet.enums import BlendFactor
20
+ from pyglet.graphics import GeometryMode, Group, ShaderProgram
21
+ from pyglet.graphics.draw import Group
22
+ from pyglet.graphics.texture import TextureBase
36
23
  from pyglet.text import runlist
24
+ from pyglet.font.base import GlyphPosition
37
25
 
38
26
  if TYPE_CHECKING:
39
27
  from pyglet.customtypes import AnchorX, AnchorY, ContentVAlign, HorizontalAlign
@@ -41,161 +29,135 @@ if TYPE_CHECKING:
41
29
  from pyglet.graphics import Batch
42
30
  from pyglet.graphics.shader import ShaderProgram
43
31
  from pyglet.graphics.vertexdomain import VertexList
44
- from pyglet.image import Texture
32
+ from pyglet.graphics import Texture
45
33
  from pyglet.text.document import AbstractDocument, InlineElement
46
34
  from pyglet.text.runlist import AbstractRunIterator, RunIterator
47
35
 
48
36
  _is_pyglet_doc_run = hasattr(sys, "is_pyglet_doc_run") and sys.is_pyglet_doc_run
49
37
 
50
- layout_vertex_source = """#version 330 core
51
- in vec3 position;
52
- in vec4 colors;
53
- in vec3 tex_coords;
54
- in vec3 translation;
55
- in vec3 view_translation;
56
- in vec2 anchor;
57
- in float rotation;
58
- in float visible;
59
-
60
- out vec4 text_colors;
61
- out vec2 texture_coords;
62
- out vec4 vert_position;
63
-
64
- uniform WindowBlock
65
- {
66
- mat4 projection;
67
- mat4 view;
68
- } window;
69
-
70
- void main()
71
- {
72
- mat4 m_rotation = mat4(1.0);
73
- vec3 v_anchor = vec3(anchor.x, anchor.y, 0);
74
- mat4 m_anchor = mat4(1.0);
75
- mat4 m_translate = mat4(1.0);
76
-
77
- m_translate[3][0] = translation.x;
78
- m_translate[3][1] = translation.y;
79
- m_translate[3][2] = translation.z;
80
-
81
- m_rotation[0][0] = cos(-radians(rotation));
82
- m_rotation[0][1] = sin(-radians(rotation));
83
- m_rotation[1][0] = -sin(-radians(rotation));
84
- m_rotation[1][1] = cos(-radians(rotation));
85
-
86
- gl_Position = window.projection * window.view * m_translate * m_anchor * m_rotation * vec4(position + view_translation + v_anchor, 1.0) * visible;
87
-
88
- vert_position = vec4(position + translation + view_translation + v_anchor, 1.0);
89
- text_colors = colors;
90
- texture_coords = tex_coords.xy;
91
- }
92
- """ # noqa: E501
93
- layout_fragment_source = """#version 330 core
94
- in vec4 text_colors;
95
- in vec2 texture_coords;
96
- in vec4 vert_position;
97
-
98
- out vec4 final_colors;
99
-
100
- uniform sampler2D text;
101
- uniform bool scissor;
102
- uniform vec4 scissor_area;
103
-
104
- void main()
105
- {
106
- final_colors = texture(text, texture_coords) * text_colors;
107
- if (scissor == true) {
108
- if (vert_position.x < scissor_area[0]) discard; // left
109
- if (vert_position.y < scissor_area[1]) discard; // bottom
110
- if (vert_position.x > scissor_area[0] + scissor_area[2]) discard; // right
111
- if (vert_position.y > scissor_area[1] + scissor_area[3]) discard; // top
112
- }
113
- }
114
- """
115
- layout_fragment_image_source = """#version 330 core
116
- in vec4 text_colors;
117
- in vec2 texture_coords;
118
- in vec4 vert_position;
119
-
120
- uniform sampler2D image_texture;
121
-
122
- out vec4 final_colors;
123
-
124
- uniform sampler2D text;
125
- uniform bool scissor;
126
- uniform vec4 scissor_area;
127
-
128
- void main()
129
- {
130
- final_colors = texture(image_texture, texture_coords.xy);
131
- if (scissor == true) {
132
- if (vert_position.x < scissor_area[0]) discard; // left
133
- if (vert_position.y < scissor_area[1]) discard; // bottom
134
- if (vert_position.x > scissor_area[0] + scissor_area[2]) discard; // right
135
- if (vert_position.y > scissor_area[1] + scissor_area[3]) discard; // top
38
+ if pyglet.options.backend in ("opengl", "gles3"):
39
+ from pyglet.graphics.api.gl.text import (
40
+ get_default_decoration_shader,
41
+ get_default_image_layout_shader,
42
+ get_default_layout_shader,
43
+ )
44
+ elif pyglet.options.backend in ("gl2", "gles2"):
45
+ from pyglet.graphics.api.gl2.text import (
46
+ get_default_decoration_shader,
47
+ get_default_image_layout_shader,
48
+ get_default_layout_shader,
49
+ )
50
+ elif pyglet.options.backend == "webgl":
51
+ from pyglet.graphics.api.webgl.text import (
52
+ get_default_decoration_shader,
53
+ get_default_image_layout_shader, # noqa: F401
54
+ get_default_layout_shader,
55
+ )
56
+ elif pyglet.options.backend == "vulkan":
57
+ from pyglet.graphics.api.vulkan.text import (
58
+ get_default_decoration_shader,
59
+ get_default_layout_shader,
60
+ )
61
+
62
+
63
+ class TextLayoutGroup(Group):
64
+ """Create a text layout rendering group.
65
+
66
+ The group is created internally when a :py:class:`~pyglet.text.Label`
67
+ is created; applications usually do not need to explicitly create it.
68
+ """
69
+
70
+ def __init__(self, texture: TextureBase, program: ShaderProgram, order: int = 1, # noqa: D107
71
+ parent: Group | None = None) -> None:
72
+ super().__init__(order=order, parent=parent)
73
+ self.uniforms = {"scissor": False}
74
+ self.texture = texture
75
+ self.set_shader_program(program)
76
+ self.set_blend(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA)
77
+ self.set_texture(texture, 0)
78
+ self.set_shader_uniforms(program, self.uniforms)
79
+
80
+ def __repr__(self) -> str:
81
+ return f"{self.__class__.__name__}({self.texture})"
82
+
83
+
84
+ class TextDecorationGroup(Group):
85
+ """Create a text decoration rendering group.
86
+
87
+ The group is created internally when a :py:class:`~pyglet.text.Label`
88
+ is created; applications usually do not need to explicitly create it.
89
+ """
90
+
91
+ def __init__(self, program: ShaderProgram, order: int = 0, # noqa: D107
92
+ parent: Group | None = None) -> None:
93
+ super().__init__(order=order, parent=parent)
94
+ self.uniforms = {"scissor": False}
95
+ self.set_shader_program(program)
96
+ self.set_blend(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA)
97
+ self.set_shader_uniforms(program, self.uniforms)
98
+
99
+
100
+ class ScrollableTextLayoutGroup(Group):
101
+ """Default rendering group for :py:class:`~pyglet.text.layout.ScrollableTextLayout`.
102
+
103
+ The group maintains internal state for specifying the viewable
104
+ area, and for scrolling. Because the group has internal state
105
+ specific to the text layout, the group is never shared.
106
+ """
107
+ scissor_area: ClassVar[tuple[int, int, int, int]] = 0, 0, 0, 0
108
+
109
+ def __init__(self, texture: TextureBase, program: ShaderProgram, order: int = 1, # noqa: D107
110
+ parent: Group | None = None) -> None:
111
+
112
+ super().__init__(order=order, parent=parent)
113
+ self.texture = texture
114
+ self.uniforms = {
115
+ "scissor": True,
116
+ "scissor_area": self.scissor_area,
136
117
  }
137
- }
138
- """
139
- decoration_vertex_source = """#version 330 core
140
- in vec3 position;
141
- in vec4 colors;
142
- in vec3 translation;
143
- in vec3 view_translation;
144
- in vec2 anchor;
145
- in float rotation;
146
- in float visible;
147
-
148
- out vec4 vert_colors;
149
- out vec4 vert_position;
150
-
151
- uniform WindowBlock
152
- {
153
- mat4 projection;
154
- mat4 view;
155
- } window;
156
-
157
- void main()
158
- {
159
- mat4 m_rotation = mat4(1.0);
160
- vec3 v_anchor = vec3(anchor.x, anchor.y, 0);
161
- mat4 m_anchor = mat4(1.0);
162
- mat4 m_translate = mat4(1.0);
163
-
164
- m_translate[3][0] = translation.x;
165
- m_translate[3][1] = translation.y;
166
- m_translate[3][2] = translation.z;
167
-
168
- m_rotation[0][0] = cos(-radians(rotation));
169
- m_rotation[0][1] = sin(-radians(rotation));
170
- m_rotation[1][0] = -sin(-radians(rotation));
171
- m_rotation[1][1] = cos(-radians(rotation));
172
-
173
- gl_Position = window.projection * window.view * m_translate * m_anchor * m_rotation * vec4(position + view_translation + v_anchor, 1.0) * visible;
174
-
175
- vert_position = vec4(position + translation + view_translation + v_anchor, 1.0);
176
- vert_colors = colors;
177
- }
178
- """ # noqa: E501
179
- decoration_fragment_source = """#version 330 core
180
- in vec4 vert_colors;
181
- in vec4 vert_position;
182
-
183
- out vec4 final_colors;
184
-
185
- uniform bool scissor;
186
- uniform vec4 scissor_area;
187
-
188
- void main()
189
- {
190
- final_colors = vert_colors;
191
- if (scissor == true) {
192
- if (vert_position.x < scissor_area[0]) discard; // left
193
- if (vert_position.y < scissor_area[1]) discard; // bottom
194
- if (vert_position.x > scissor_area[0] + scissor_area[2]) discard; // right
195
- if (vert_position.y > scissor_area[1] + scissor_area[3]) discard; // top
118
+ self.set_shader_program(program)
119
+ self.set_blend(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA)
120
+ self.set_texture(texture, 0)
121
+ self.set_shader_uniforms(program, self.uniforms)
122
+
123
+ def __repr__(self) -> str:
124
+ return f"{self.__class__.__name__}({self.texture})"
125
+
126
+ def __eq__(self, other: object) -> bool:
127
+ return self is other
128
+
129
+ def __hash__(self) -> int:
130
+ return id(self)
131
+
132
+
133
+ class ScrollableTextDecorationGroup(Group):
134
+ """Create a text decoration rendering group.
135
+
136
+ The group is created internally when a :py:class:`~pyglet.text.Label`
137
+ is created; applications usually do not need to explicitly create it.
138
+ """
139
+
140
+ scissor_area: ClassVar[tuple[int, int, int, int]] = 0, 0, 0, 0
141
+
142
+ def __init__(self, program: ShaderProgram, order: int = 0, parent: Group | None = None) -> None: # noqa: D107
143
+ super().__init__(order=order, parent=parent)
144
+ self.program = program
145
+ self.set_shader_program(program)
146
+ self.set_blend(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA)
147
+ self.uniforms = {
148
+ "scissor": True,
149
+ "scissor_area": self.scissor_area,
196
150
  }
197
- }
198
- """
151
+ self.set_shader_uniforms(program, self.uniforms)
152
+
153
+ def __repr__(self) -> str:
154
+ return f"{self.__class__.__name__}(scissor={self.scissor_area})"
155
+
156
+ def __eq__(self, other: object) -> bool:
157
+ return self is other
158
+
159
+ def __hash__(self) -> int:
160
+ return id(self)
199
161
 
200
162
 
201
163
  class _LayoutVertexList(Protocol):
@@ -212,24 +174,6 @@ class _LayoutVertexList(Protocol):
212
174
  def delete(self) -> None: ...
213
175
 
214
176
 
215
- def get_default_layout_shader() -> ShaderProgram:
216
- """The default shader used for all glyphs in the layout."""
217
- return pyglet.gl.current_context.create_program((layout_vertex_source, "vertex"),
218
- (layout_fragment_source, "fragment"))
219
-
220
-
221
- def get_default_image_layout_shader() -> ShaderProgram:
222
- """The default shader used for an InlineElement image. Used for HTML Labels that insert images via <img> tag."""
223
- return pyglet.gl.current_context.create_program((layout_vertex_source, "vertex"),
224
- (layout_fragment_image_source, "fragment"))
225
-
226
-
227
- def get_default_decoration_shader() -> ShaderProgram:
228
- """The default shader for underline and background decoration effects in the layout."""
229
- return pyglet.gl.current_context.create_program((decoration_vertex_source, "vertex"),
230
- (decoration_fragment_source, "fragment"))
231
-
232
-
233
177
  _distance_re: Pattern[str] = re.compile(r"([-0-9.]+)([a-zA-Z]+)")
234
178
 
235
179
 
@@ -496,10 +440,12 @@ class _GlyphBox(_AbstractBox):
496
440
 
497
441
  t_position = (x, y, z)
498
442
 
499
- vertex_list = layout.program.vertex_list_indexed(n_glyphs * 4, GL_TRIANGLES, indices, layout.batch, group,
443
+ vertex_list = layout.program.vertex_list_indexed(n_glyphs * 4, GeometryMode.TRIANGLES, indices, layout.batch,
444
+ group,
500
445
  position=("f", vertices),
501
446
  translation=("f", t_position * 4 * n_glyphs),
502
447
  colors=("Bn", colors),
448
+ view_translation=('f', ((0, 0, 0) * 4 * n_glyphs)),
503
449
  tex_coords=("f", tex_coords),
504
450
  rotation=("f", ((rotation,) * 4) * n_glyphs),
505
451
  visible=("f", ((visible,) * 4) * n_glyphs),
@@ -548,10 +494,12 @@ class _GlyphBox(_AbstractBox):
548
494
  bg_count = len(background_vertices) // 3
549
495
  background_indices = [(0, 1, 2, 0, 2, 3)[i % 6] for i in range(bg_count * 3)]
550
496
  decoration_program = get_default_decoration_shader()
551
- background_list = decoration_program.vertex_list_indexed(bg_count, GL_TRIANGLES, background_indices,
497
+ background_list = decoration_program.vertex_list_indexed(bg_count, GeometryMode.TRIANGLES,
498
+ background_indices,
552
499
  layout.batch, layout.background_decoration_group,
553
500
  position=("f", background_vertices),
554
501
  translation=("f", t_position * bg_count),
502
+ view_translation=('f', (0, 0, 0) * bg_count),
555
503
  colors=("Bn", background_colors),
556
504
  rotation=("f", (rotation,) * bg_count),
557
505
  visible=("f", (visible,) * bg_count),
@@ -561,10 +509,11 @@ class _GlyphBox(_AbstractBox):
561
509
  if underline_vertices:
562
510
  ul_count = len(underline_vertices) // 3
563
511
  decoration_program = get_default_decoration_shader()
564
- underline_list = decoration_program.vertex_list(ul_count, GL_LINES,
512
+ underline_list = decoration_program.vertex_list(ul_count, GeometryMode.LINES,
565
513
  layout.batch, layout.foreground_decoration_group,
566
514
  position=("f", underline_vertices),
567
515
  translation=("f", t_position * ul_count),
516
+ view_translation=('f', (0, 0, 0) * ul_count),
568
517
  colors=("Bn", underline_colors),
569
518
  rotation=("f", (rotation,) * ul_count),
570
519
  visible=("f", (visible,) * ul_count),
@@ -603,7 +552,7 @@ class _GlyphBox(_AbstractBox):
603
552
  def update_rotation(self, rotation: float) -> None:
604
553
  rot = (rotation,)
605
554
  for _vertex_list in self.vertex_lists:
606
- _vertex_list.rotation[:] = rot * _vertex_list.count
555
+ _vertex_list.rotation[:] = (rot * _vertex_list.count)
607
556
 
608
557
  def update_visibility(self, visible: bool) -> None:
609
558
  visible_tuple = (visible,)
@@ -657,7 +606,7 @@ class _InlineElementBox(_AbstractBox):
657
606
  # Determines if the box is visible.
658
607
  self.placed = False
659
608
 
660
- def place(self, layout: TextLayout, i: int, x: float, y: float, z: float, line_x: float, line_y: float, # noqa: ARG002
609
+ def place(self, layout: TextLayout, i: int, x: float, y: float, z: float, line_x: float, line_y: float,
661
610
  rotation: float, visible: bool, anchor_x: float, anchor_y: float,
662
611
  context: _LayoutContext) -> None: # noqa: ARG002
663
612
  self.element.place(layout, x, y, z, line_x, line_y, rotation, visible, anchor_x, anchor_y)
@@ -751,75 +700,11 @@ class _InvalidRange:
751
700
  return self.end > self.start
752
701
 
753
702
 
754
- class TextLayoutGroup(graphics.Group):
755
- """Create a text layout rendering group.
756
-
757
- The group is created internally when a :py:class:`~pyglet.text.Label`
758
- is created; applications usually do not need to explicitly create it.
759
- """
760
-
761
- def __init__(self, texture: Texture, program: ShaderProgram, order: int = 1, # noqa: D107
762
- parent: graphics.Group | None = None) -> None:
763
- super().__init__(order=order, parent=parent)
764
- self.texture = texture
765
- self.program = program
766
-
767
- def set_state(self) -> None:
768
- self.program.use()
769
- self.program["scissor"] = False
770
-
771
- glActiveTexture(GL_TEXTURE0)
772
- glBindTexture(self.texture.target, self.texture.id)
773
-
774
- glEnable(GL_BLEND)
775
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
776
-
777
- def unset_state(self) -> None:
778
- glDisable(GL_BLEND)
779
- self.program.stop()
780
-
781
- def __repr__(self) -> str:
782
- return f"{self.__class__.__name__}({self.texture})"
783
-
784
- def __eq__(self, other: object) -> bool:
785
- return (other.__class__ is self.__class__ and
786
- self.parent is other.parent and
787
- self.program.id is other.program.id and
788
- self.order == other.order and
789
- self.texture.target == other.texture.target and
790
- self.texture.id == other.texture.id)
791
-
792
- def __hash__(self) -> int:
793
- return hash((id(self.parent), self.program.id, self.order, self.texture.target, self.texture.id))
794
-
795
-
796
- class TextDecorationGroup(Group):
797
- """Create a text decoration rendering group.
798
-
799
- The group is created internally when a :py:class:`~pyglet.text.Label`
800
- is created; applications usually do not need to explicitly create it.
801
- """
802
-
803
- def __init__(self, program: ShaderProgram, order: int = 0, # noqa: D107
804
- parent: graphics.Group | None = None) -> None:
805
- super().__init__(order=order, parent=parent)
806
- self.program = program
807
-
808
- def set_state(self) -> None:
809
- self.program.use()
810
- self.program["scissor"] = False
811
-
812
- glEnable(GL_BLEND)
813
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
814
-
815
- def unset_state(self) -> None:
816
- glDisable(GL_BLEND)
817
- self.program.stop()
818
-
819
703
 
820
704
  # Just have one object for empty positions in layout. It won't be modified.
821
705
  _empty_pos = GlyphPosition(0, 0, 0, 0)
822
706
 
707
+
823
708
  class TextLayout:
824
709
  """Lay out and display documents.
825
710
 
@@ -873,7 +758,7 @@ class TextLayout:
873
758
  anchor_x: AnchorX = 'left', anchor_y: AnchorY = 'bottom', rotation: float = 0,
874
759
  multiline: bool = False, dpi: float | None = None, batch: Batch | None = None,
875
760
  group: graphics.Group | None = None, program: ShaderProgram | None = None,
876
- wrap_lines: bool = True, init_document: bool = True) -> None:
761
+ wrap_lines: bool = True, shaping: bool = True, init_document: bool = True) -> None:
877
762
  """Create a text layout.
878
763
 
879
764
  Args:
@@ -913,6 +798,9 @@ class TextLayout:
913
798
  Optional graphics shader to use. Will affect all glyphs in the layout.
914
799
  wrap_lines:
915
800
  If True and `multiline` is True, the text is word-wrapped using the specified width.
801
+ shaping:
802
+ If the text should use proper positioning and typography according to the font and global
803
+ ``pyglet.options.text_shaping`` option. If ``False``, metrics will instead be tied to the glyph sizes.
916
804
  init_document:
917
805
  If True the document will be initialized. If subclassing then
918
806
  you may want to avoid duplicate initializations by changing to False.
@@ -927,6 +815,7 @@ class TextLayout:
927
815
  self._rotation = rotation
928
816
  self._multiline = multiline
929
817
  self._dpi = dpi or 96
818
+ self._shaping = shaping
930
819
 
931
820
  self._content_width = 0
932
821
  self._content_height = 0
@@ -939,7 +828,6 @@ class TextLayout:
939
828
  # Boxes are all existing _AbstractBoxes, these are used to gather line information.
940
829
  # Note that this is only relevant to layouts that do not store directly on lines.
941
830
  self._boxes = []
942
- self._lines = []
943
831
 
944
832
  #: :meta private:
945
833
  self.group_cache = {}
@@ -947,7 +835,8 @@ class TextLayout:
947
835
  self._initialize_groups()
948
836
 
949
837
  if batch is None:
950
- batch = graphics.Batch()
838
+ batch = pyglet.graphics.Batch()
839
+ # Create a batch as some text elements may require being drawn together.
951
840
  self._own_batch = True
952
841
  self._batch = batch
953
842
 
@@ -1022,7 +911,7 @@ class TextLayout:
1022
911
  return
1023
912
 
1024
913
  if batch is None:
1025
- self._batch = graphics.Batch()
914
+ self._batch = pyglet.graphics.Batch()
1026
915
  self._own_batch = True
1027
916
  self._update()
1028
917
  elif batch is not None:
@@ -1140,11 +1029,10 @@ class TextLayout:
1140
1029
 
1141
1030
  anchor_y = self._get_top_anchor()
1142
1031
 
1143
- for line in self._lines:
1144
- acc_anchor_x = self._anchor_left
1145
- for box in line.boxes:
1146
- box.update_anchor(acc_anchor_x, anchor_y)
1147
- acc_anchor_x += box.advance
1032
+ acc_anchor_x = self._anchor_left
1033
+ for box in self._boxes:
1034
+ box.update_anchor(acc_anchor_x, anchor_y)
1035
+ acc_anchor_x += box.advance
1148
1036
 
1149
1037
  @property
1150
1038
  def visible(self) -> bool:
@@ -1391,7 +1279,7 @@ class TextLayout:
1391
1279
  self._vertex_lists.clear()
1392
1280
  self._boxes.clear()
1393
1281
 
1394
- def get_as_texture(self, min_filter: int=GL_NEAREST, mag_filter: int=GL_NEAREST) -> Texture:
1282
+ def get_as_texture(self) -> Texture:
1395
1283
  """Utilizes a :py:class:`~pyglet.image.framebuffer.Framebuffer` to draw the current layout into a texture.
1396
1284
 
1397
1285
  .. warning:: Usage is recommended only if you understand how texture generation affects your application.
@@ -1404,22 +1292,23 @@ class TextLayout:
1404
1292
 
1405
1293
  .. versionadded:: 2.0.11
1406
1294
  """
1407
- framebuffer = pyglet.image.Framebuffer()
1408
- temp_pos = self.position
1409
- width = int(round(self._content_width))
1410
- height = int(round(self._content_height))
1411
- texture = pyglet.image.Texture.create(width, height, min_filter=min_filter, mag_filter=mag_filter)
1412
- depth_buffer = pyglet.image.buffer.Renderbuffer(width, height, GL_DEPTH_COMPONENT)
1413
- framebuffer.attach_texture(texture)
1414
- framebuffer.attach_renderbuffer(depth_buffer, attachment=GL_DEPTH_ATTACHMENT)
1415
-
1416
- self.position = (0 - self._anchor_left, 0 - self._anchor_bottom, 0)
1417
- framebuffer.bind()
1418
- self.draw()
1419
- framebuffer.unbind()
1420
-
1421
- self.position = temp_pos
1422
- return texture
1295
+ raise NotImplementedError
1296
+ # framebuffer = pyglet.image.Framebuffer()
1297
+ # temp_pos = self.position
1298
+ # width = int(round(self._content_width))
1299
+ # height = int(round(self._content_height))
1300
+ # texture = pyglet.graphics.Texture.create(width, height, texture_desc)
1301
+ # depth_buffer = pyglet.image.buffer.Renderbuffer(width, height, GL_DEPTH_COMPONENT)
1302
+ # framebuffer.attach_texture(texture)
1303
+ # framebuffer.attach_renderbuffer(depth_buffer, attachment=GL_DEPTH_ATTACHMENT)
1304
+ #
1305
+ # self.position = (0 - self._anchor_left, 0 - self._anchor_bottom, 0)
1306
+ # framebuffer.bind()
1307
+ # self.draw()
1308
+ # framebuffer.unbind()
1309
+ #
1310
+ # self.position = temp_pos
1311
+ # return texture
1423
1312
 
1424
1313
  def draw(self) -> None:
1425
1314
  """Draw this text layout.
@@ -1455,8 +1344,7 @@ class TextLayout:
1455
1344
 
1456
1345
  self._vertex_lists.clear()
1457
1346
  self._boxes.clear()
1458
- self._lines.clear()
1459
- self.group_cache.clear()
1347
+ #self.group_cache.clear()
1460
1348
 
1461
1349
  if not self._document or not self._document.text:
1462
1350
  self._ascent = 0
@@ -1465,9 +1353,9 @@ class TextLayout:
1465
1353
  self._anchor_bottom = 0
1466
1354
  return
1467
1355
 
1468
- self._lines = self._get_lines()
1469
- self._ascent = self._lines[0].ascent
1470
- self._descent = self._lines[0].descent
1356
+ lines = self._get_lines()
1357
+ self._ascent = lines[0].ascent
1358
+ self._descent = lines[0].descent
1471
1359
 
1472
1360
  colors_iter = self._document.get_style_runs("color")
1473
1361
 
@@ -1479,7 +1367,7 @@ class TextLayout:
1479
1367
 
1480
1368
  context = _StaticLayoutContext(self, self._document, colors_iter, background_iter)
1481
1369
 
1482
- for line in self._lines:
1370
+ for line in lines:
1483
1371
  self._boxes.extend(line.boxes)
1484
1372
  self._create_vertex_lists(line.x, line.y, self._anchor_left, anchor_top, line.start, line.boxes, context)
1485
1373
 
@@ -1633,7 +1521,7 @@ class TextLayout:
1633
1521
  glyphs.append(_InlineElementBox(element))
1634
1522
  offsets.append(_empty_pos)
1635
1523
  else:
1636
- char_glyphs, char_offsets = font.get_glyphs(text[start:end])
1524
+ char_glyphs, char_offsets = font.get_glyphs(text[start:end], self._shaping)
1637
1525
  glyphs.extend(char_glyphs)
1638
1526
  offsets.extend(char_offsets)
1639
1527
 
@@ -2009,3 +1897,4 @@ class TextLayout:
2009
1897
  def get_line_count(self) -> int:
2010
1898
  """Get the number of lines in the text layout."""
2011
1899
  return self._line_count
1900
+