pyglet 2.1.3__py3-none-any.whl → 2.1.4__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 (61) hide show
  1. pyglet/__init__.py +21 -9
  2. pyglet/__init__.pyi +3 -1
  3. pyglet/app/cocoa.py +6 -3
  4. pyglet/display/win32.py +14 -15
  5. pyglet/display/xlib_vidmoderestore.py +1 -1
  6. pyglet/extlibs/earcut.py +2 -2
  7. pyglet/font/__init__.py +3 -3
  8. pyglet/font/base.py +118 -51
  9. pyglet/font/dwrite/__init__.py +1381 -0
  10. pyglet/font/dwrite/d2d1_lib.py +637 -0
  11. pyglet/font/dwrite/d2d1_types_lib.py +60 -0
  12. pyglet/font/dwrite/dwrite_lib.py +1577 -0
  13. pyglet/font/fontconfig.py +79 -16
  14. pyglet/font/freetype.py +252 -77
  15. pyglet/font/freetype_lib.py +234 -125
  16. pyglet/font/harfbuzz/__init__.py +275 -0
  17. pyglet/font/harfbuzz/harfbuzz_lib.py +212 -0
  18. pyglet/font/quartz.py +432 -112
  19. pyglet/font/user.py +18 -11
  20. pyglet/font/win32.py +9 -1
  21. pyglet/gl/wgl.py +94 -87
  22. pyglet/gl/wglext_arb.py +472 -218
  23. pyglet/gl/wglext_nv.py +410 -188
  24. pyglet/gui/widgets.py +6 -1
  25. pyglet/image/codecs/bmp.py +3 -5
  26. pyglet/image/codecs/gdiplus.py +28 -9
  27. pyglet/image/codecs/wic.py +198 -489
  28. pyglet/image/codecs/wincodec_lib.py +413 -0
  29. pyglet/input/base.py +3 -2
  30. pyglet/input/macos/darwin_hid.py +28 -2
  31. pyglet/input/win32/directinput.py +2 -1
  32. pyglet/input/win32/xinput.py +10 -9
  33. pyglet/lib.py +14 -2
  34. pyglet/libs/darwin/cocoapy/cocoalibs.py +74 -3
  35. pyglet/libs/darwin/coreaudio.py +0 -2
  36. pyglet/libs/win32/__init__.py +4 -2
  37. pyglet/libs/win32/com.py +65 -12
  38. pyglet/libs/win32/constants.py +1 -0
  39. pyglet/libs/win32/dinput.py +1 -9
  40. pyglet/libs/win32/types.py +72 -8
  41. pyglet/media/codecs/coreaudio.py +1 -0
  42. pyglet/media/codecs/wmf.py +93 -72
  43. pyglet/media/devices/win32.py +5 -4
  44. pyglet/media/drivers/directsound/lib_dsound.py +4 -4
  45. pyglet/media/drivers/xaudio2/interface.py +21 -17
  46. pyglet/media/drivers/xaudio2/lib_xaudio2.py +42 -25
  47. pyglet/shapes.py +1 -1
  48. pyglet/text/document.py +7 -53
  49. pyglet/text/formats/attributed.py +3 -1
  50. pyglet/text/formats/plaintext.py +1 -1
  51. pyglet/text/formats/structured.py +1 -1
  52. pyglet/text/layout/base.py +76 -68
  53. pyglet/text/layout/incremental.py +38 -8
  54. pyglet/text/layout/scrolling.py +1 -1
  55. pyglet/text/runlist.py +2 -114
  56. pyglet/window/win32/__init__.py +1 -3
  57. {pyglet-2.1.3.dist-info → pyglet-2.1.4.dist-info}/METADATA +1 -1
  58. {pyglet-2.1.3.dist-info → pyglet-2.1.4.dist-info}/RECORD +60 -54
  59. pyglet/font/directwrite.py +0 -2798
  60. {pyglet-2.1.3.dist-info → pyglet-2.1.4.dist-info}/LICENSE +0 -0
  61. {pyglet-2.1.3.dist-info → pyglet-2.1.4.dist-info}/WHEEL +0 -0
pyglet/font/fontconfig.py CHANGED
@@ -2,7 +2,7 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  from collections import OrderedDict
5
- from ctypes import CDLL, Structure, Union, byref, c_char_p, c_double, c_int, c_uint, c_void_p
5
+ from ctypes import CDLL, Structure, Union, byref, c_char_p, c_double, c_int, c_uint, c_void_p, POINTER
6
6
  from typing import TYPE_CHECKING
7
7
 
8
8
  from pyglet.font.base import FontException
@@ -28,6 +28,7 @@ FC_SLANT = asbytes("slant")
28
28
  FC_WEIGHT = asbytes("weight")
29
29
  FC_FT_FACE = asbytes("ftface")
30
30
  FC_FILE = asbytes("file")
31
+ FC_WIDTH = asbytes("width")
31
32
 
32
33
  FC_WEIGHT_THIN = 10
33
34
  FC_WEIGHT_EXTRALIGHT = 40
@@ -49,11 +50,10 @@ FC_WEIGHT_HEAVY = FC_WEIGHT_BLACK
49
50
  FC_WEIGHT_EXTRABLACK = 215
50
51
  FC_WEIGHT_ULTRABLACK = FC_WEIGHT_EXTRABLACK
51
52
 
52
-
53
53
  name_to_weight = {
54
- True: FC_WEIGHT_BOLD, # Temporary alias for attributed text
55
- False: FC_WEIGHT_NORMAL, # Temporary alias for attributed text
56
- None: FC_WEIGHT_NORMAL, # Temporary alias for attributed text
54
+ True: FC_WEIGHT_BOLD, # Temporary alias for attributed text
55
+ False: FC_WEIGHT_NORMAL, # Temporary alias for attributed text
56
+ None: FC_WEIGHT_NORMAL, # Temporary alias for attributed text
57
57
  "thin": FC_WEIGHT_THIN,
58
58
  "extralight": FC_WEIGHT_EXTRALIGHT,
59
59
  "ultralight": FC_WEIGHT_ULTRALIGHT,
@@ -73,6 +73,7 @@ name_to_weight = {
73
73
  }
74
74
 
75
75
  weight_to_name = {
76
+ None: 'normal',
76
77
  0: 'thin',
77
78
  40: 'extralight',
78
79
  50: 'light',
@@ -87,8 +88,50 @@ weight_to_name = {
87
88
  }
88
89
 
89
90
 
91
+ FC_WIDTH_ULTRACONDENSED = 50
92
+ FC_WIDTH_EXTRACONDENSED = 63
93
+ FC_WIDTH_CONDENSED = 75
94
+ FC_WIDTH_SEMICONDENSED = 87
95
+ FC_WIDTH_NORMAL = 100
96
+ FC_WIDTH_SEMIEXPANDED = 113
97
+ FC_WIDTH_EXPANDED = 125
98
+ FC_WIDTH_EXTRAEXPANDED = 150
99
+ FC_WIDTH_ULTRAEXPANDED = 200
100
+
101
+
102
+ name_to_stretch = {
103
+ None: FC_WIDTH_NORMAL,
104
+ False: FC_WIDTH_NORMAL,
105
+ "undefined": FC_WIDTH_NORMAL,
106
+ "ultracondensed": FC_WIDTH_ULTRACONDENSED,
107
+ "extracondensed": FC_WIDTH_EXTRACONDENSED,
108
+ "condensed": FC_WIDTH_CONDENSED,
109
+ "semicondensed": FC_WIDTH_SEMICONDENSED,
110
+ "normal": FC_WIDTH_NORMAL,
111
+ "medium": FC_WIDTH_NORMAL,
112
+ "semiexpanded": FC_WIDTH_SEMIEXPANDED,
113
+ "expanded": FC_WIDTH_EXPANDED,
114
+ "extraexpanded": FC_WIDTH_EXTRAEXPANDED,
115
+ "ultraexpanded": FC_WIDTH_ULTRAEXPANDED,
116
+ }
117
+
118
+ stretch_to_name = {
119
+ None: "normal",
120
+ False: "normal",
121
+ FC_WIDTH_ULTRACONDENSED : "ultracondensed",
122
+ FC_WIDTH_EXTRACONDENSED: "extracondensed",
123
+ FC_WIDTH_CONDENSED: "condensed",
124
+ FC_WIDTH_SEMICONDENSED: "semicondensed",
125
+ FC_WIDTH_NORMAL: "normal",
126
+ FC_WIDTH_SEMIEXPANDED: "semiexpanded",
127
+ FC_WIDTH_EXPANDED: "expanded",
128
+ FC_WIDTH_EXTRAEXPANDED: "extraexpanded",
129
+ FC_WIDTH_ULTRAEXPANDED: "narrow",
130
+ }
131
+
90
132
  FC_SLANT_ROMAN = 0
91
133
  FC_SLANT_ITALIC = 100
134
+ FC_SLANT_OBLIQUE = 110
92
135
 
93
136
  (FcTypeVoid,
94
137
  FcTypeInteger,
@@ -131,7 +174,7 @@ class FcValue(Structure):
131
174
 
132
175
 
133
176
  class FontConfig:
134
- _search_cache: OrderedDict[tuple[str, float, str, bool], FontConfigSearchResult]
177
+ _search_cache: OrderedDict[tuple[str, float, str, bool, str], FontConfigSearchResult]
135
178
  _fontconfig: CDLL | None
136
179
 
137
180
  def __init__(self) -> None:
@@ -151,8 +194,14 @@ class FontConfig:
151
194
  def create_search_pattern(self) -> FontConfigSearchPattern:
152
195
  return FontConfigSearchPattern(self._fontconfig)
153
196
 
154
- def find_font(self, name: str, size: float = 12, weight: str = "normal", italic: bool = False) -> FontConfigSearchResult:
155
- if result := self._get_from_search_cache(name, size, weight, italic):
197
+ def style_from_face(self, font_face: FT_Face):
198
+ pattern = self._fontconfig.FcFreeTypeQueryFace(font_face, None, 0, None)
199
+ result = FontConfigSearchResult(self._fontconfig, pattern)
200
+ return result.weight, result.italic, result.stretch
201
+
202
+ def find_font(self, name: str, size: float = 12, weight: str = "normal",
203
+ italic: bool = False, stretch: str = "normal") -> FontConfigSearchResult:
204
+ if result := self._get_from_search_cache(name, size, weight, italic, stretch):
156
205
  return result
157
206
 
158
207
  search_pattern = self.create_search_pattern()
@@ -160,6 +209,7 @@ class FontConfig:
160
209
  search_pattern.size = size
161
210
  search_pattern.weight = weight
162
211
  search_pattern.italic = italic
212
+ search_pattern.stretch = stretch
163
213
 
164
214
  result = search_pattern.match()
165
215
  self._add_to_search_cache(search_pattern, result)
@@ -183,12 +233,14 @@ class FontConfig:
183
233
  self._search_cache[(search_pattern.name,
184
234
  search_pattern.size,
185
235
  search_pattern.weight,
186
- search_pattern.italic)] = result_pattern
236
+ search_pattern.italic,
237
+ search_pattern.stretch)] = result_pattern
187
238
  if len(self._search_cache) > self._cache_size:
188
239
  self._search_cache.popitem(last=False)[1].dispose()
189
240
 
190
- def _get_from_search_cache(self, name: str, size: float, weight: str, italic: bool) -> FontConfigSearchResult | None:
191
- result = self._search_cache.get((name, size, weight, italic), None)
241
+ def _get_from_search_cache(self, name: str, size: float, weight: str,
242
+ italic: bool, stretch: str) -> FontConfigSearchResult | None:
243
+ result = self._search_cache.get((name, size, weight, italic, stretch), None)
192
244
 
193
245
  if result and result.is_valid:
194
246
  return result
@@ -216,6 +268,9 @@ class FontConfig:
216
268
  fontconfig.FcPatternGetFTFace.argtypes = [c_void_p, c_char_p, c_int, c_void_p]
217
269
  fontconfig.FcPatternGet.argtypes = [c_void_p, c_char_p, c_int, c_void_p]
218
270
 
271
+ fontconfig.FcFreeTypeQueryFace.argtypes = [c_void_p, c_char_p, c_int, POINTER(c_int)]
272
+ fontconfig.FcFreeTypeQueryFace.restype = c_void_p
273
+
219
274
  return fontconfig
220
275
 
221
276
 
@@ -255,7 +310,7 @@ class FontConfigPattern:
255
310
 
256
311
  self._fontconfig.FcPatternAddString(self._pattern, name, asbytes(value))
257
312
 
258
- def _set_double(self, name: bytes, value: int) -> None:
313
+ def _set_double(self, name: bytes, value: float) -> None:
259
314
  assert self._pattern
260
315
  assert name
261
316
  assert self._fontconfig
@@ -321,18 +376,20 @@ class FontConfigPattern:
321
376
 
322
377
 
323
378
  class FontConfigSearchPattern(FontConfigPattern):
324
- size: int | None
379
+ size: float | None
325
380
  italic: bool
326
381
  weight: str
327
382
  name: str | None
383
+ stretch: str
328
384
 
329
- def __init__(self, fontconfig: CDLL) -> None:
330
- super().__init__(fontconfig)
385
+ def __init__(self, fontconfig: CDLL, pattern: c_void_p | None = None) -> None:
386
+ super().__init__(fontconfig, pattern)
331
387
 
332
388
  self.name = None
333
389
  self.weight = "normal"
334
390
  self.italic = False
335
391
  self.size = None
392
+ self.stretch = 'normal'
336
393
 
337
394
  def match(self) -> FontConfigSearchResult | None:
338
395
  self._prepare_search_pattern()
@@ -344,11 +401,13 @@ class FontConfigSearchPattern(FontConfigPattern):
344
401
  return None
345
402
 
346
403
  def _prepare_search_pattern(self) -> None:
347
- self._create()
404
+ if self._pattern is None:
405
+ self._create()
348
406
  self._set_string(FC_FAMILY, self.name)
349
407
  self._set_double(FC_SIZE, self.size)
350
408
  self._set_double(FC_WEIGHT, name_to_weight[self.weight])
351
409
  self._set_integer(FC_SLANT, self._italic_to_slant(self.italic))
410
+ self._set_integer(FC_WIDTH, name_to_stretch[self.stretch])
352
411
 
353
412
  self._substitute_defaults()
354
413
 
@@ -399,6 +458,10 @@ class FontConfigSearchResult(FontConfigPattern):
399
458
  def face(self) -> FT_Face:
400
459
  return self._get_face(FC_FT_FACE)
401
460
 
461
+ @property
462
+ def stretch(self) -> str:
463
+ return stretch_to_name[self._get_integer(FC_WIDTH)]
464
+
402
465
  @property
403
466
  def file(self) -> str:
404
467
  return self._get_string(FC_FILE)